RenderD7 is now LibRenderD7

This commit is contained in:
2022-07-24 00:55:18 +02:00
parent 3c7c12ef39
commit 6af08275e9
37 changed files with 553 additions and 98 deletions
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <renderd7/bmp.hpp>
#include <renderd7/renderd7.hpp>
+23
View File
@@ -0,0 +1,23 @@
#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
};
}
+82
View File
@@ -0,0 +1,82 @@
namespace rnd7 {
class Time {
public:
Time();
float asSeconds() const;
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);
}
+717
View File
@@ -0,0 +1,717 @@
#pragma once
#include <fstream>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <iterator>
#include <sstream>
using namespace std;
#pragma pack(push, 1)
struct BMPFileHeader {
uint16_t file_type{ 0x4D42 }; // File type always BM which is 0x4D42 (stored as hex uint16_t in little endian)
uint32_t file_size{ 0 }; // Size of the file (in bytes)
uint16_t reserved1{ 0 }; // Reserved, always 0
uint16_t reserved2{ 0 }; // Reserved, always 0
uint32_t offset_data{ 0 }; // Start position of pixel data (bytes from the beginning of the file)
};
struct BMPInfoHeader {
uint32_t size{ 0 }; // Size of this header (in bytes)
int32_t width{ 0 }; // width of bitmap in pixels
int32_t height{ 0 }; // height of bitmap in pixels
// (if positive, bottom-up, with origin in lower left corner)
// (if negative, top-down, with origin in upper left corner)
uint16_t planes{ 1 }; // No. of planes for the target device, this is always 1
uint16_t bit_count{ 0 }; // No. of bits per pixel
uint32_t compression{ 0 }; // 0 or 3 - uncompressed. THIS PROGRAM CONSIDERS ONLY UNCOMPRESSED BMP images
uint32_t size_image{ 0 }; // 0 - for uncompressed images
int32_t x_pixels_per_meter{ 0 };
int32_t y_pixels_per_meter{ 0 };
uint32_t colors_used{ 0 }; // No. color indexes in the color table. Use 0 for the max number of colors allowed by bit_count
uint32_t colors_important{ 0 }; // No. of colors used for displaying the bitmap. If 0 all colors are required
};
struct BMPColorHeader {
uint32_t red_mask{ 0x00ff0000 }; // Bit mask for the red channel
uint32_t green_mask{ 0x0000ff00 }; // Bit mask for the green channel
uint32_t blue_mask{ 0x000000ff }; // Bit mask for the blue channel
uint32_t alpha_mask{ 0xff000000 }; // Bit mask for the alpha channel
uint32_t color_space_type{ 0x73524742 }; // Default "sRGB" (0x73524742)
uint32_t unused[16]{ 0 }; // Unused data for sRGB color space
};
#pragma pack(pop)
struct BMP {
BMPFileHeader file_header;
BMPInfoHeader bmp_info_header;
BMPColorHeader bmp_color_header;
std::vector<uint8_t> data;
BMP(const char *fname) {
read(fname);
}
int read(const char *fname) {
std::ifstream inp{ fname, std::ios_base::binary };
if (inp) {
inp.read((char*)&file_header, sizeof(file_header));
if(file_header.file_type != 0x4D42) {
return 50;//throw std::runtime_error("Error! Unrecognized file format.");
}
inp.read((char*)&bmp_info_header, sizeof(bmp_info_header));
// The BMPColorHeader is used only for transparent images
if(bmp_info_header.bit_count == 32) {
// Check if the file has bit mask color information
if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) {
inp.read((char*)&bmp_color_header, sizeof(bmp_color_header));
// Check if the pixel data is stored as BGRA and if the color space type is sRGB
check_color_header(bmp_color_header);
} else {
//std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n";
return 51;//throw std::runtime_error("Error! Unrecognized file format.");
}
}
// Jump to the pixel data location
inp.seekg(file_header.offset_data, inp.beg);
// Adjust the header fields for output.
// Some editors will put extra info in the image file, we only save the headers and the data.
if(bmp_info_header.bit_count == 32) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
} else {
bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
}
file_header.file_size = file_header.offset_data;
if (bmp_info_header.height < 0) {
return 52;//throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!");
}
data.resize(bmp_info_header.width * bmp_info_header.height * bmp_info_header.bit_count / 8);
// Here we check if we need to take into account row padding
if (bmp_info_header.width % 4 == 0) {
inp.read((char*)data.data(), data.size());
file_header.file_size += static_cast<uint32_t>(data.size());
}
else {
row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8;
uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < bmp_info_header.height; ++y) {
inp.read((char*)(data.data() + row_stride * y), row_stride);
inp.read((char*)padding_row.data(), padding_row.size());
}
file_header.file_size += static_cast<uint32_t>(data.size()) + bmp_info_header.height * static_cast<uint32_t>(padding_row.size());
}
}
else {
return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname));
}
return 0;
}
int read_mem(std::vector<unsigned char> buffer) {
std::stringstream inp;
std::copy(buffer.begin(), buffer.end(),std::ostream_iterator<unsigned char>(inp,"\n"));
if (inp) {
inp.read((char*)&file_header, sizeof(file_header));
if(file_header.file_type != 0x4D42) {
return 50;//throw std::runtime_error("Error! Unrecognized file format.");
}
inp.read((char*)&bmp_info_header, sizeof(bmp_info_header));
// The BMPColorHeader is used only for transparent images
if(bmp_info_header.bit_count == 32) {
// Check if the file has bit mask color information
if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) {
inp.read((char*)&bmp_color_header, sizeof(bmp_color_header));
// Check if the pixel data is stored as BGRA and if the color space type is sRGB
check_color_header(bmp_color_header);
} else {
//std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n";
return 51;//throw std::runtime_error("Error! Unrecognized file format.");
}
}
// Jump to the pixel data location
inp.seekg(file_header.offset_data, inp.beg);
// Adjust the header fields for output.
// Some editors will put extra info in the image file, we only save the headers and the data.
if(bmp_info_header.bit_count == 32) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
} else {
bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
}
file_header.file_size = file_header.offset_data;
if (bmp_info_header.height < 0) {
return 52;//throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!");
}
data.resize(bmp_info_header.width * bmp_info_header.height * bmp_info_header.bit_count / 8);
// Here we check if we need to take into account row padding
if (bmp_info_header.width % 4 == 0) {
inp.read((char*)data.data(), data.size());
file_header.file_size += static_cast<uint32_t>(data.size());
}
else {
row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8;
uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < bmp_info_header.height; ++y) {
inp.read((char*)(data.data() + row_stride * y), row_stride);
inp.read((char*)padding_row.data(), padding_row.size());
}
file_header.file_size += static_cast<uint32_t>(data.size()) + bmp_info_header.height * static_cast<uint32_t>(padding_row.size());
}
}
else {
return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname));
}
return 0;
}
BMP(int32_t width, int32_t height, bool has_alpha = true) {
if (width <= 0 || height <= 0) {
width = 1;
height = 1;
}
bmp_info_header.width = width;
bmp_info_header.height = height;
if (has_alpha) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
bmp_info_header.bit_count = 32;
bmp_info_header.compression = 3;
row_stride = width * 4;
data.resize(row_stride * height);
file_header.file_size = file_header.offset_data + data.size();
}
else {
bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
bmp_info_header.bit_count = 24;
bmp_info_header.compression = 0;
row_stride = width * 3;
data.resize(row_stride * height);
uint32_t new_stride = make_stride_aligned(4);
file_header.file_size = file_header.offset_data + static_cast<uint32_t>(data.size()) + bmp_info_header.height * (new_stride - row_stride);
}
}
unsigned write(const char *fname) {
std::ofstream of{ fname, std::ios_base::binary };
if (of) {
if (bmp_info_header.bit_count == 32) {
write_headers_and_data(of);
}
else if (bmp_info_header.bit_count == 24) {
if (bmp_info_header.width % 4 == 0) {
write_headers_and_data(of);
}
else {
uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride);
write_headers(of);
for (int y = 0; y < bmp_info_header.height; ++y) {
of.write((const char*)(data.data() + row_stride * y), row_stride);
of.write((const char*)padding_row.data(), padding_row.size());
}
}
}
else {
return 54;//throw std::runtime_error("The program can treat only 24 or 32 bits per pixel BMP files");
}
}
else {
return 55;//throw std::runtime_error("Unable to open the output image file.");
}
return 0;
}
std::vector<unsigned char> DATA() {
std::stringstream ss;
if (ss) {
if (bmp_info_header.bit_count == 32) {
write_headers_and_datass(ss);
}
else if (bmp_info_header.bit_count == 24) {
if (bmp_info_header.width % 4 == 0) {
write_headers_and_datass(ss);
}
else {
uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride);
write_headersss(ss);
for (int y = 0; y < bmp_info_header.height; ++y) {
ss.write((const char*)(data.data() + row_stride * y), row_stride);
ss.write((const char*)padding_row.data(), padding_row.size());
}
}
}
else {
}
}
else {
}
std::string test11 = ss.str();
std::vector<unsigned char> test12(test11.begin(), test11.end());
return test12;
}
unsigned fill_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint8_t B, uint8_t G, uint8_t R, uint8_t A) {
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
return 59;
}
uint32_t channels = bmp_info_header.bit_count / 8;
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
data[channels * (y * bmp_info_header.width + x) + 0] = B;
data[channels * (y * bmp_info_header.width + x) + 1] = G;
data[channels * (y * bmp_info_header.width + x) + 2] = R;
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
return 0;
}
void fill_region_df(uint32_t x1, uint32_t y1, uint32_t w, uint32_t h, uint8_t B, uint8_t G, uint8_t R, uint8_t A) {
int x0 = x1;
int y0 = this->bmp_info_header.height - y1 - h;
uint32_t channels = bmp_info_header.bit_count / 8;
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
if ((x + w < (uint32_t)bmp_info_header.width) || this->bmp_info_header.height - y - h > 0) {
data[channels * (y * bmp_info_header.width + x) + 0] = B;
data[channels * (y * bmp_info_header.width + x) + 1] = G;
data[channels * (y * bmp_info_header.width + x) + 2] = R;
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
}
void manipulate_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint8_t A) {
int choice, choice2, intensity;
cout << "What color do you want to change? " << endl;
cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl;
cin >> choice;
cout << "To what color do you want to change it too?" << endl;
cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl;
cin >> choice2;
cout << "Enter the intensity of the color. (From 0 to 255) " << endl;
cin >> intensity;
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
return;//throw std::runtime_error("The region does not fit in the image!");
}
uint32_t channels = bmp_info_header.bit_count / 8;
if (choice==1 && choice2==1)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make blue thing blue
if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
//data[channels * (y * bmp_info_header.width + x) + 0] = B;
//data[channels * (y * bmp_info_header.width + x) + 1] = G;
//data[channels * (y * bmp_info_header.width + x) + 2] = R;
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 1 && choice2==2)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make blue thing green
if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 1 && choice2==3)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make blue thing red
if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 2 && choice2==1)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make green thing blue
if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 2 && choice2==2)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make green thing green
if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 2 && choice2==3)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make green thing red
if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 3 && choice2==1)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make red thing blue
if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 3 && choice2==2)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make red thing green
if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
if (choice == 3 && choice2==3)
{
for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl;
//Make red thing blue
if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255)
{
data[channels * (y * bmp_info_header.width + x) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
}
if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A;
}
}
}
}
}
int OrganizeAverageRed()
{
int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[bmp_info_header.height][bmp_info_header.width];;
int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width;
float intensity=0;
float sum=0;
uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << endl;
for (int y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl;
//Read red
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2];
}
}
for(int y=0; y<bmp_info_header.height; y++)
{
for(int x=0; x<bmp_info_header.width; x++)
{
sum=ColorRed[y][x]+sum-((ColorBlue[y][x])/2+(ColorGreen[y][x])/2);
}
}
intensity=sum/pixels;
cout << intensity << endl;
return intensity;
}
int OrganizeAverageGreen()
{
int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[bmp_info_header.height][bmp_info_header.width];;
int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width;
float intensity=0;
float sum=0;
uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << endl;
for (int y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl;
//Read Green
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2];
}
}
for(int y=0; y<bmp_info_header.height; y++)
{
for(int x=0; x<bmp_info_header.width; x++)
{
sum=ColorGreen[y][x]+sum-((ColorBlue[y][x])/2+(ColorRed[y][x])/2);
}
}
intensity=sum/pixels;
cout << intensity << endl;
return intensity;
}
int OrganizeAverageBlue()
{
int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[bmp_info_header.height][bmp_info_header.width];;
int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width;
float intensity=0;
float sum=0;
uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << endl;
for (int y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl;
//Read Blue
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2];
}
}
for(int y=0; y<bmp_info_header.height; y++)
{
for(int x=0; x<bmp_info_header.width; x++)
{
sum=ColorBlue[y][x]+sum-((ColorGreen[y][x])/2+(ColorRed[y][x])/2);
}
}
intensity=sum/pixels;
cout << intensity << endl;
return intensity;
}
unsigned set_pixel(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) {
if (x0 >= (uint32_t)bmp_info_header.width || y0 >= (uint32_t)bmp_info_header.height || x0 < 0 || y0 < 0) {
return 59;//throw std::runtime_error("The point is outside the image boundaries!");
}
uint32_t channels = bmp_info_header.bit_count / 8;
data[channels * (y0 * bmp_info_header.width + x0) + 0] = B;
data[channels * (y0 * bmp_info_header.width + x0) + 1] = G;
data[channels * (y0 * bmp_info_header.width + x0) + 2] = R;
if (channels == 4) {
data[channels * (y0 * bmp_info_header.width + x0) + 3] = A;
}
return 0;
}
void set_pixel_df(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) {
uint32_t y1 = this->bmp_info_header.height - y0;
if (x0 >= (uint32_t)bmp_info_header.width || y1 <= (uint32_t)bmp_info_header.width || x0 < 0 || y0 > 0) {
return;//throw std::runtime_error("The point is outside the image boundaries!");
}
uint32_t channels = bmp_info_header.bit_count / 8;
data[channels * (y0 * bmp_info_header.width + x0) + 0] = B;
data[channels * (y0 * bmp_info_header.width + x0) + 1] = G;
data[channels * (y0 * bmp_info_header.width + x0) + 2] = R;
if (channels == 4) {
data[channels * (y0 * bmp_info_header.width + x0) + 3] = A;
}
}
unsigned draw_rectangle(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h,
uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) {
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
return 59;//throw std::runtime_error("The rectangle does not fit in the image!");
}
fill_region(x0, y0, w, line_w, B, G, R, A); // top line
fill_region(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line
fill_region((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // right line
fill_region(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line
return 0;
}
void draw_rectangle_df(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h,
uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) {
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
return;//throw std::runtime_error("The rectangle does not fit in the image!");
}
fill_region_df(x0, y0, w, line_w, B, G, R, A); // top line
fill_region_df(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line
fill_region_df((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // right line
fill_region_df(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line
}
private:
uint32_t row_stride{ 0 };
void write_headers(std::ofstream &of) {
of.write((const char*)&file_header, sizeof(file_header));
of.write((const char*)&bmp_info_header, sizeof(bmp_info_header));
if(bmp_info_header.bit_count == 32) {
of.write((const char*)&bmp_color_header, sizeof(bmp_color_header));
}
}
void write_headers_and_data(std::ofstream &of) {
write_headers(of);
of.write((const char*)data.data(), data.size());
}
void write_headersss(std::stringstream &of) {
of.write((const char*)&file_header, sizeof(file_header));
of.write((const char*)&bmp_info_header, sizeof(bmp_info_header));
if(bmp_info_header.bit_count == 32) {
of.write((const char*)&bmp_color_header, sizeof(bmp_color_header));
}
}
void write_headers_and_datass(std::stringstream &of) {
write_headersss(of);
of.write((const char*)data.data(), data.size());
}
// Add 1 to the row_stride until it is divisible with align_stride
uint32_t make_stride_aligned(uint32_t align_stride) {
uint32_t new_stride = row_stride;
while (new_stride % align_stride != 0) {
new_stride++;
}
return new_stride;
}
// Check if the pixel data is stored as BGRA and if the color space type is sRGB
void check_color_header(BMPColorHeader &bmp_color_header) {
BMPColorHeader expected_color_header;
if(expected_color_header.red_mask != bmp_color_header.red_mask ||
expected_color_header.blue_mask != bmp_color_header.blue_mask ||
expected_color_header.green_mask != bmp_color_header.green_mask ||
expected_color_header.alpha_mask != bmp_color_header.alpha_mask) {
return;//throw std::runtime_error("Unexpected color mask format! The program expects the pixel data to be in the BGRA format");
}
if(expected_color_header.color_space_type != bmp_color_header.color_space_type) {
return;//throw std::runtime_error("Unexpected color space type! The program expects sRGB values");
}
}
};
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <renderd7/external/lodepng.h>
#include <iostream>
namespace BitmapConverter{
//returns 0 if all went ok, non-0 if error
//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel
unsigned decodeBMP(std::vector<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> ConvertData(std::vector<unsigned char> data);
}
+29
View File
@@ -0,0 +1,29 @@
#include <3ds.h>
extern FS_Archive archive, sdmc_archive, nand_archive;
Result FS_OpenArchive(FS_Archive *archive, FS_ArchiveID id);
Result FS_CloseArchive(FS_Archive archive);
Result FS_OpenDir(Handle *handle, FS_Archive archive, const char *path);
Result FS_OpenFile(Handle *handle, FS_Archive archive, const char *path, u32 flags, u32 attributes);
Result FS_MakeDir(FS_Archive archive, const char *path);
Result FS_CreateFile(FS_Archive archive, const char *path, u64 size);
Result FS_RecursiveMakeDir(FS_Archive archive, const char *path);
bool FS_FileExists(FS_Archive archive, const char *path);
bool FS_DirExists(FS_Archive archive, const char *path);
Result FS_GetFileSize(FS_Archive archive, const char *path, u64 *size);
u64 FS_GetFreeStorage(FS_SystemMediaType media_type);
u64 FS_GetTotalStorage(FS_SystemMediaType media_type);
u64 FS_GetUsedStorage(FS_SystemMediaType media_type);
Result FS_RemoveFile(FS_Archive archive, const char *path);
Result FS_RemoveDir(FS_Archive archive, const char *path);
Result FS_RemoveDirRecursive(FS_Archive archive, const char *path);
Result FS_RenameFile(FS_Archive archive, const char *old_filename, const char *new_filename);
Result FS_RenameDir(FS_Archive archive, const char *old_dirname, const char *new_dirname);
Result FS_Read(FS_Archive archive, const char *path, u64 size, void *buf);
Result FS_Write(FS_Archive archive, const char *path, const void *buf, u32 size);
char *FS_GetFileTimestamp(const char *path);
Result makeDirs(const char * path);
Result openFile(Handle* fileHandle, const char * path, bool write);
+25447
View File
File diff suppressed because it is too large Load Diff
+250
View File
@@ -0,0 +1,250 @@
/*
* Copyright 2006 Richard Wilson <richard.wilson@netsurf-browser.org>
* Copyright 2008 Sean Fox <dyntryx@gmail.com>
*
* This file is part of NetSurf's libnsbmp, http://www.netsurf-browser.org/
* Licenced under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
*/
/**
* \file
* Bitmap file decoding interface.
*/
#ifndef libnsbmp_h_
#define libnsbmp_h_
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/* bmp flags */
#define BMP_NEW 0
/** image is opaque (as opposed to having an alpha mask) */
#define BMP_OPAQUE (1 << 0)
/** memory should be wiped */
#define BMP_CLEAR_MEMORY (1 << 1)
/**
* error return values
*/
typedef enum {
BMP_OK = 0,
BMP_INSUFFICIENT_MEMORY = 1,
BMP_INSUFFICIENT_DATA = 2,
BMP_DATA_ERROR = 3
} bmp_result;
/**
* encoding types
*/
typedef enum {
BMP_ENCODING_RGB = 0,
BMP_ENCODING_RLE8 = 1,
BMP_ENCODING_RLE4 = 2,
BMP_ENCODING_BITFIELDS = 3
} bmp_encoding;
/* API for Bitmap callbacks */
typedef void* (*bmp_bitmap_cb_create)(int width, int height, unsigned int state);
typedef void (*bmp_bitmap_cb_destroy)(void *bitmap);
typedef unsigned char* (*bmp_bitmap_cb_get_buffer)(void *bitmap);
typedef size_t (*bmp_bitmap_cb_get_bpp)(void *bitmap);
/**
* The Bitmap callbacks function table
*/
typedef struct bmp_bitmap_callback_vt_s {
/** Callback to allocate bitmap storage. */
bmp_bitmap_cb_create bitmap_create;
/** Called to free bitmap storage. */
bmp_bitmap_cb_destroy bitmap_destroy;
/** Return a pointer to the pixel data in a bitmap. */
bmp_bitmap_cb_get_buffer bitmap_get_buffer;
/** Find the width of a pixel row in bytes. */
bmp_bitmap_cb_get_bpp bitmap_get_bpp;
} bmp_bitmap_callback_vt;
/**
* bitmap image
*/
typedef struct bmp_image {
/** callbacks for bitmap functions */
bmp_bitmap_callback_vt bitmap_callbacks;
/** pointer to BMP data */
uint8_t *bmp_data;
/** width of BMP (valid after _analyse) */
uint32_t width;
/** heigth of BMP (valid after _analyse) */
uint32_t height;
/** whether the image has been decoded */
bool decoded;
/** decoded image */
void *bitmap;
/* Internal members are listed below */
/** total number of bytes of BMP data available */
uint32_t buffer_size;
/** pixel encoding type */
bmp_encoding encoding;
/** offset of bitmap data */
uint32_t bitmap_offset;
/** bits per pixel */
uint16_t bpp;
/** number of colours */
uint32_t colours;
/** colour table */
uint32_t *colour_table;
/** whether to use bmp's limited transparency */
bool limited_trans;
/** colour to display for "transparent" pixels when using limited
* transparency
*/
uint32_t trans_colour;
/** scanlines are top to bottom */
bool reversed;
/** image is part of an ICO, mask follows */
bool ico;
/** true if the bitmap does not contain an alpha channel */
bool opaque;
/** four bitwise mask */
uint32_t mask[4];
/** four bitwise shifts */
int32_t shift[4];
/** colour representing "transparency" in the bitmap */
uint32_t transparent_index;
} bmp_image;
typedef struct ico_image {
bmp_image bmp;
struct ico_image *next;
} ico_image;
/**
* icon image collection
*/
typedef struct ico_collection {
/** callbacks for bitmap functions */
bmp_bitmap_callback_vt bitmap_callbacks;
/** width of largest BMP */
uint16_t width;
/** heigth of largest BMP */
uint16_t height;
/* Internal members are listed below */
/** pointer to ICO data */
uint8_t *ico_data;
/** total number of bytes of ICO data available */
uint32_t buffer_size;
/** root of linked list of images */
ico_image *first;
} ico_collection;
/**
* Initialises bitmap ready for analysing the bitmap.
*
* \param bmp The Bitmap to initialise
* \param callbacks The callbacks the library will call on operations.
* \return BMP_OK on success or appropriate error code.
*/
bmp_result bmp_create(bmp_image *bmp, bmp_bitmap_callback_vt *callbacks);
/**
* Initialises icon ready for analysing the icon
*
* \param bmp The Bitmap to initialise
* \param callbacks The callbacks the library will call on operations.
* \return BMP_OK on success or appropriate error code.
*/
bmp_result ico_collection_create(ico_collection *ico,
bmp_bitmap_callback_vt *callbacks);
/**
* Analyse a BMP prior to decoding.
*
* This will scan the data provided and perform checks to ensure the data is a
* valid BMP and prepare the bitmap image structure ready for decode.
*
* This function must be called and resturn BMP_OK before bmp_decode() as it
* prepares the bmp internal state for the decode process.
*
* \param bmp the BMP image to analyse.
* \param size The size of data in cdata.
* \param data The bitmap source data.
* \return BMP_OK on success or error code on faliure.
*/
bmp_result bmp_analyse(bmp_image *bmp, size_t size, uint8_t *data);
/**
* Analyse an ICO prior to decoding.
*
* This function will scan the data provided and perform checks to ensure the
* data is a valid ICO.
*
* This function must be called before ico_find().
*
* \param ico the ICO image to analyse
* \param size The size of data in cdata.
* \param data The bitmap source data.
* \return BMP_OK on success
*/
bmp_result ico_analyse(ico_collection *ico, size_t size, uint8_t *data);
/**
* Decode a BMP
*
* This function decodes the BMP data such that bmp->bitmap is a valid
* image. The state of bmp->decoded is set to TRUE on exit such that it
* can easily be identified which BMPs are in a fully decoded state.
*
* \param bmp the BMP image to decode
* \return BMP_OK on success
*/
bmp_result bmp_decode(bmp_image *bmp);
/**
* Decode a BMP using "limited transparency"
*
* Bitmaps do not have native transparency support. However, there is a
* "trick" that is used in some instances in which the first pixel of the
* bitmap becomes the "transparency index". The decoding application can
* replace this index with whatever background colour it chooses to
* create the illusion of transparency.
*
* When to use transparency is at the discretion of the decoding
* application.
*
* \param bmp the BMP image to decode
* \param colour the colour to use as "transparent"
* \return BMP_OK on success
*/
bmp_result bmp_decode_trans(bmp_image *bmp, uint32_t transparent_colour);
/**
* Finds the closest BMP within an ICO collection
*
* This function finds the BMP with dimensions as close to a specified set
* as possible from the images in the collection.
*
* \param ico the ICO collection to examine
* \param width the preferred width (0 to use ICO header width)
* \param height the preferred height (0 to use ICO header height)
*/
bmp_image *ico_find(ico_collection *ico, uint16_t width, uint16_t height);
/**
* Finalise a BMP prior to destruction.
*
* \param bmp the BMP image to finalise.
*/
void bmp_finalise(bmp_image *bmp);
/**
* Finalise an ICO prior to destruction.
*
* \param ico the ICO image to finalise,
*/
void ico_finalise(ico_collection *ico);
#endif
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
* Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
* Licenced under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
*/
#include <stdio.h>
#ifndef _LIBNSBMP_LOG_H_
#define _LIBNSBMP_LOG_H_
#ifdef NDEBUG
# define LOG(x) ((void) 0)
#else
# ifdef __GNUC__
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
# elif defined(__CC_NORCROFT)
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
# else
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
# endif
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+679
View File
@@ -0,0 +1,679 @@
#ifndef INI_INI_H_
#define INI_INI_H_
#include <string>
#include <sstream>
#include <algorithm>
#include <utility>
#include <unordered_map>
#include <vector>
#include <memory>
#include <fstream>
#include <sys/stat.h>
#include <cctype>
namespace INI
{
namespace INIStringUtil
{
const char* const whitespaceDelimiters = " \t\n\r\f\v";
inline void trim(std::string& str)
{
str.erase(str.find_last_not_of(whitespaceDelimiters) + 1);
str.erase(0, str.find_first_not_of(whitespaceDelimiters));
}
#ifndef INI_CASE_SENSITIVE
inline void toLower(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), [](const char c) {
return static_cast<const char>(std::tolower(c));
});
}
#endif
inline void replace(std::string& str, std::string const& a, std::string const& b)
{
if (!a.empty())
{
std::size_t pos = 0;
while ((pos = str.find(a, pos)) != std::string::npos)
{
str.replace(pos, a.size(), b);
pos += b.size();
}
}
}
#ifdef _WIN32
const char* const endl = "\r\n";
#else
const char* const endl = "\n";
#endif
};
template<typename T>
class INIMap
{
private:
using T_DataIndexMap = std::unordered_map<std::string, std::size_t>;
using T_DataItem = std::pair<std::string, T>;
using T_DataContainer = std::vector<T_DataItem>;
using T_MultiArgs = typename std::vector<std::pair<std::string, T>>;
T_DataIndexMap dataIndexMap;
T_DataContainer data;
inline std::size_t setEmpty(std::string& key)
{
std::size_t index = data.size();
dataIndexMap[key] = index;
data.emplace_back(key, T());
return index;
}
public:
using const_iterator = typename T_DataContainer::const_iterator;
INIMap() { }
INIMap(INIMap const& other)
{
std::size_t data_size = other.data.size();
for (std::size_t i = 0; i < data_size; ++i)
{
auto const& key = other.data[i].first;
auto const& obj = other.data[i].second;
data.emplace_back(key, obj);
}
dataIndexMap = T_DataIndexMap(other.dataIndexMap);
}
T& operator[](std::string key)
{
INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
bool hasIt = (it != dataIndexMap.end());
std::size_t index = (hasIt) ? it->second : setEmpty(key);
return data[index].second;
}
T get(std::string key) const
{
INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it == dataIndexMap.end())
{
return T();
}
return T(data[it->second].second);
}
bool has(std::string key) const
{
INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
return (dataIndexMap.count(key) == 1);
}
void set(std::string key, T obj)
{
INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end())
{
data[it->second].second = obj;
}
else
{
dataIndexMap[key] = data.size();
data.emplace_back(key, obj);
}
}
void set(T_MultiArgs const& multiArgs)
{
for (auto const& it : multiArgs)
{
auto const& key = it.first;
auto const& obj = it.second;
set(key, obj);
}
}
bool remove(std::string key)
{
INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end())
{
std::size_t index = it->second;
data.erase(data.begin() + index);
dataIndexMap.erase(it);
for (auto& it2 : dataIndexMap)
{
auto& vi = it2.second;
if (vi > index)
{
vi--;
}
}
return true;
}
return false;
}
void clear()
{
data.clear();
dataIndexMap.clear();
}
std::size_t size() const
{
return data.size();
}
const_iterator begin() const { return data.begin(); }
const_iterator end() const { return data.end(); }
};
using INIStructure = INIMap<INIMap<std::string>>;
namespace INIParser
{
using T_ParseValues = std::pair<std::string, std::string>;
enum class PDataType : char
{
PDATA_NONE,
PDATA_COMMENT,
PDATA_SECTION,
PDATA_KEYVALUE,
PDATA_UNKNOWN
};
inline PDataType parseLine(std::string line, T_ParseValues& parseData)
{
parseData.first.clear();
parseData.second.clear();
INIStringUtil::trim(line);
if (line.empty())
{
return PDataType::PDATA_NONE;
}
char firstCharacter = line[0];
if (firstCharacter == ';')
{
return PDataType::PDATA_COMMENT;
}
if (firstCharacter == '[')
{
auto commentAt = line.find_first_of(';');
if (commentAt != std::string::npos)
{
line = line.substr(0, commentAt);
}
auto closingBracketAt = line.find_last_of(']');
if (closingBracketAt != std::string::npos)
{
auto section = line.substr(1, closingBracketAt - 1);
INIStringUtil::trim(section);
parseData.first = section;
return PDataType::PDATA_SECTION;
}
}
auto lineNorm = line;
INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('=');
if (equalsAt != std::string::npos)
{
auto key = line.substr(0, equalsAt);
INIStringUtil::trim(key);
INIStringUtil::replace(key, "\\=", "=");
auto value = line.substr(equalsAt + 1);
INIStringUtil::trim(value);
parseData.first = key;
parseData.second = value;
return PDataType::PDATA_KEYVALUE;
}
return PDataType::PDATA_UNKNOWN;
}
};
class INIReader
{
public:
using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>;
private:
std::ifstream fileReadStream;
T_LineDataPtr lineData;
T_LineData readFile()
{
std::string fileContents;
fileReadStream.seekg(0, std::ios::end);
fileContents.resize(fileReadStream.tellg());
fileReadStream.seekg(0, std::ios::beg);
std::size_t fileSize = fileContents.size();
fileReadStream.read(&fileContents[0], fileSize);
fileReadStream.close();
T_LineData output;
if (fileSize == 0)
{
return output;
}
std::string buffer;
buffer.reserve(50);
for (std::size_t i = 0; i < fileSize; ++i)
{
char& c = fileContents[i];
if (c == '\n')
{
output.emplace_back(buffer);
buffer.clear();
continue;
}
if (c != '\0' && c != '\r')
{
buffer += c;
}
}
output.emplace_back(buffer);
return output;
}
public:
INIReader(std::string const& filename, bool keepLineData = false)
{
fileReadStream.open(filename, std::ios::in | std::ios::binary);
if (keepLineData)
{
lineData = std::make_shared<T_LineData>();
}
}
~INIReader() { }
bool operator>>(INIStructure& data)
{
if (!fileReadStream.is_open())
{
return false;
}
T_LineData fileLines = readFile();
std::string section;
bool inSection = false;
INIParser::T_ParseValues parseData;
for (auto const& line : fileLines)
{
auto parseResult = INIParser::parseLine(line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION)
{
inSection = true;
data[section = parseData.first];
}
else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE)
{
auto const& key = parseData.first;
auto const& value = parseData.second;
data[section][key] = value;
}
if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN)
{
if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection)
{
continue;
}
lineData->emplace_back(line);
}
}
return true;
}
T_LineDataPtr getLines()
{
return lineData;
}
};
class INIGenerator
{
private:
std::ofstream fileWriteStream;
public:
bool prettyPrint = false;
INIGenerator(std::string const& filename)
{
fileWriteStream.open(filename, std::ios::out | std::ios::binary);
}
~INIGenerator() { }
bool operator<<(INIStructure const& data)
{
if (!fileWriteStream.is_open())
{
return false;
}
if (!data.size())
{
return true;
}
auto it = data.begin();
for (;;)
{
auto const& section = it->first;
auto const& collection = it->second;
fileWriteStream
<< "["
<< section
<< "]";
if (collection.size())
{
fileWriteStream << INIStringUtil::endl;
auto it2 = collection.begin();
for (;;)
{
auto key = it2->first;
INIStringUtil::replace(key, "=", "\\=");
auto value = it2->second;
INIStringUtil::trim(value);
fileWriteStream
<< key
<< ((prettyPrint) ? " = " : "=")
<< value;
if (++it2 == collection.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
}
}
if (++it == data.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
if (prettyPrint)
{
fileWriteStream << INIStringUtil::endl;
}
}
return true;
}
};
class INIWriter
{
private:
using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>;
std::string filename;
T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original)
{
T_LineData output;
INIParser::T_ParseValues parseData;
std::string sectionCurrent;
bool parsingSection = false;
bool continueToNextSection = false;
bool discardNextEmpty = false;
bool writeNewKeys = false;
std::size_t lastKeyLine = 0;
for (auto line = lineData->begin(); line != lineData->end(); ++line)
{
if (!writeNewKeys)
{
auto parseResult = INIParser::parseLine(*line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION)
{
if (parsingSection)
{
writeNewKeys = true;
parsingSection = false;
--line;
continue;
}
sectionCurrent = parseData.first;
if (data.has(sectionCurrent))
{
parsingSection = true;
continueToNextSection = false;
discardNextEmpty = false;
output.emplace_back(*line);
lastKeyLine = output.size();
}
else
{
continueToNextSection = true;
discardNextEmpty = true;
continue;
}
}
else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE)
{
if (continueToNextSection)
{
continue;
}
if (data.has(sectionCurrent))
{
auto& collection = data[sectionCurrent];
auto const& key = parseData.first;
auto const& value = parseData.second;
if (collection.has(key))
{
auto outputValue = collection[key];
if (value == outputValue)
{
output.emplace_back(*line);
}
else
{
INIStringUtil::trim(outputValue);
auto lineNorm = *line;
INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('=');
auto valueAt = lineNorm.find_first_not_of(
INIStringUtil::whitespaceDelimiters,
equalsAt + 1
);
std::string outputLine = line->substr(0, valueAt);
if (prettyPrint && equalsAt + 1 == valueAt)
{
outputLine += " ";
}
outputLine += outputValue;
output.emplace_back(outputLine);
}
lastKeyLine = output.size();
}
}
}
else
{
if (discardNextEmpty && line->empty())
{
discardNextEmpty = false;
}
else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN)
{
output.emplace_back(*line);
}
}
}
if (writeNewKeys || std::next(line) == lineData->end())
{
T_LineData linesToAdd;
if (data.has(sectionCurrent) && original.has(sectionCurrent))
{
auto const& collection = data[sectionCurrent];
auto const& collectionOriginal = original[sectionCurrent];
for (auto const& it : collection)
{
auto key = it.first;
if (collectionOriginal.has(key))
{
continue;
}
auto value = it.second;
INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value);
linesToAdd.emplace_back(
key + ((prettyPrint) ? " = " : "=") + value
);
}
}
if (!linesToAdd.empty())
{
output.insert(
output.begin() + lastKeyLine,
linesToAdd.begin(),
linesToAdd.end()
);
}
if (writeNewKeys)
{
writeNewKeys = false;
--line;
}
}
}
for (auto const& it : data)
{
auto const& section = it.first;
if (original.has(section))
{
continue;
}
if (prettyPrint && output.size() > 0 && !output.back().empty())
{
output.emplace_back();
}
output.emplace_back("[" + section + "]");
auto const& collection = it.second;
for (auto const& it2 : collection)
{
auto key = it2.first;
auto value = it2.second;
INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value);
output.emplace_back(
key + ((prettyPrint) ? " = " : "=") + value
);
}
}
return output;
}
public:
bool prettyPrint = false;
INIWriter(std::string const& filename)
: filename(filename)
{
}
~INIWriter() { }
bool operator<<(INIStructure& data)
{
struct stat buf;
bool fileExists = (stat(filename.c_str(), &buf) == 0);
if (!fileExists)
{
INIGenerator generator(filename);
generator.prettyPrint = prettyPrint;
return generator << data;
}
INIStructure originalData;
T_LineDataPtr lineData;
bool readSuccess = false;
{
INIReader reader(filename, true);
if ((readSuccess = reader >> originalData))
{
lineData = reader.getLines();
}
}
if (!readSuccess)
{
return false;
}
T_LineData output = getLazyOutput(lineData, data, originalData);
std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary);
if (fileWriteStream.is_open())
{
if (output.size())
{
auto line = output.begin();
for (;;)
{
fileWriteStream << *line;
if (++line == output.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
}
}
return true;
}
return false;
}
};
class INIFile
{
private:
std::string filename;
public:
INIFile(std::string const& filename)
: filename(filename)
{ }
~INIFile() { }
bool read(INIStructure& data) const
{
if (data.size())
{
data.clear();
}
if (filename.empty())
{
return false;
}
INIReader reader(filename);
return reader >> data;
}
bool generate(INIStructure const& data, bool pretty = false) const
{
if (filename.empty())
{
return false;
}
INIGenerator generator(filename);
generator.prettyPrint = pretty;
return generator << data;
}
bool write(INIStructure& data, bool pretty = false) const
{
if (filename.empty())
{
return false;
}
INIWriter writer(filename);
writer.prettyPrint = pretty;
return writer << data;
}
};
}
#endif
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <string>
#include <renderd7/external/json.hpp>
/// RenderD7::Lang
namespace RenderD7::Lang
{
/// Get the 3ds System Language
std::string getSys();
/// Get a translated string
/// \param key The Key so the code can find your string
std::string get(const std::string &key);
/// Load the lang file from dir structure en/app.json for sample
/// \param lang the folder name en, fr, de ... . I prefer geSys()
void load(const std::string &lang);
} /// RenderD7::Lang
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <fstream>
#include <stdarg.h>
#include <string>
#include <time.h>
#include <unistd.h>
/** Log Class */
class Log
{
public:
/** Construct */
Log();
/** Deconstruct */
~Log();
/// Init the log file
/// \param filename name for the file
void Init(const char *filename);
/// Write Text to logfile
/// \param debug_text your text
void Write(std::string debug_text);
/// Get the date
std::string logDate(void);
/// Format to logstyle
/// \param fmt_str the formatted style
std::string format(const std::string& fmt_str, ...);
private:
/// \param filename the name of the logfile
std::string filename;
};
+112
View File
@@ -0,0 +1,112 @@
#pragma once
#include <tuple>
namespace RenderD7{
class Parameter
{
private:
using id = size_t;
template<typename T>
struct type { static void id() { } };
template<typename T>
static id type_id() { return reinterpret_cast<id>(&type<T>::id); }
template<typename T>
using decay = typename std::decay<T>::type;
template<typename T>
using none = typename std::enable_if<!std::is_same<Parameter, T>::value>::type;
struct base
{
virtual ~base() { }
virtual bool is(id) const = 0;
virtual base *copy() const = 0;
} *p = nullptr;
template<typename T>
struct data : base, std::tuple<T>
{
using std::tuple<T>::tuple;
T &get() & { return std::get<0>(*this); }
T const &get() const& { return std::get<0>(*this); }
bool is(id i) const override { return i == type_id<T>(); }
base *copy() const override { return new data{get()}; }
};
template<typename T>
T &stat() { return static_cast<data<T>&>(*p).get(); }
template<typename T>
T const &stat() const { return static_cast<data<T> const&>(*p).get(); }
template<typename T>
T &dyn() { return dynamic_cast<data<T>&>(*p).get(); }
template<typename T>
T const &dyn() const { return dynamic_cast<data<T> const&>(*p).get(); }
public:
/**
* @brief Default constructor
*/
Parameter() { }
/**
* @brief Destructs the Parameter
*/
~Parameter() { delete p; }
/**
* @brief Copy constructor
* @param s The Parameter to copy
*/
Parameter(Parameter &&s) : p{s.p} { s.p = nullptr; }
/**
* @brief Const copy constructor
* @param s The Parameter to copy
*/
Parameter(Parameter const &s) : p{s.p->copy()} { }
/**
* @brief Initializes the Parameter with the given value
* @param x The value to initialize the Parameter with
*/
template<typename T, typename U = decay<T>, typename = none<U>>
Parameter(T &&x) : p{new data<U>{std::forward<T>(x)}} { }
/**
* @brief Overloads the assignment operator
* @param s The value to set the Parameter to
*/
Parameter &operator=(Parameter s) { swap(*this, s); return *this; }
friend void swap(Parameter &s, Parameter &r) { std::swap(s.p, r.p); }
/**
* @brief Clears the Parameter
*/
void clear() { delete p; p = nullptr; }
/**
* @brief Checks whether the Parameter is the given type
* @tparam T The type to check
* @return Whether the Parameter has the given type or not
*/
template<typename T>
bool is() const { return p ? p->is(type_id<T>()) : false; }
/**
* @brief Returns the value of the Parameter
* @tparam T The type of the Parameter
* @return The value of the Parameter
* @warning If the type of the Parameter doesn't match the type of it's stored value, it will result in undefined behaviour.
*/
template<typename T> T &get() & { return stat<T>(); }
};
}
+448
View File
@@ -0,0 +1,448 @@
#pragma once
#include <3ds.h>
#include <citro2d.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 <random>
#include <sys/stat.h>
#include <algorithm>
#include <iostream>
#include <filesystem>
#include <locale>
#include <time.h>
#include <codecvt>
#include <renderd7/external/lodepng.h>
#include <renderd7/lang.hpp>
#include <renderd7/parameter.hpp>
#include <renderd7/thread.hpp>
#include <renderd7/ini.hpp>
#include <renderd7/stringtool.hpp>
#include <renderd7/Clock.hpp>
#include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp>
extern "C"
{
#include <renderd7/external/fs.h>
}
#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 DEFAULT_CENTER 0.5f
extern C3D_RenderTarget* Top;
extern C3D_RenderTarget* TopRight;
extern C3D_RenderTarget* Bottom;
extern u32 d7_hDown;
extern u32 d7_hHeld;
extern u32 d7_hUp;
extern touchPosition d7_touch;
extern std::string dspststus;
/// RenderD7
namespace RenderD7
{
float GetDeltaTime();
enum kbd{
SWKBD,
BKBD
};
enum kbd_type
{
NUMPAD,
STANDARD
};
struct TObject
{
int x; //Position X
int y; //Position Y
int w; //Button Width
int h; //Button Height
std::string text = ""; //Text
float correctx = 0; //Correct X Position
float correcty = 0; //Correct Y Position
float txtsize = 0.7f; //Set Text Size
};
/// 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();
/// 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;
};
/// 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;
virtual ~Scene() {}
virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0;
virtual void Draw() const = 0;
//virtual void Ovl() const = 0;
static void Load(std::unique_ptr<Scene> scene, bool fade = false);
static void Back();
static void doDraw();
static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch);
//static void HandleOvl();
};
class RSettings : public RenderD7::Scene
{
private:
enum RState {
RSETTINGS,
RINFO
};
RenderD7::RSettings::RState m_state = RenderD7::RSettings::RState::RSETTINGS;
std::string rd7srstate = "false";
std::string csvstate = "false";
std::string mtovlstate = "false";
std::string fpsstate = "60";
std::string mtscreenstate = "Top";
std::string mttxtcolstate = "#ffffff";
std::string mtcola = "255";
std::string mttxtcola = "255";
std::vector<RenderD7::TObject> buttons =
{
{20, 35, 120, 35, "RD7SR", -11, 10},
{20, 85, 120, 35, "MT_CSV", -15, 9},
{20, 135, 120, 35, "MT_OVL", -19, 10},
{20, 185, 120, 35, "FPS", 6, 10},
{180, 35, 120, 35, "MTSCREEN", -29, 10},
{180, 85, 120, 35, "DSPERR", -13, 10},
{180, 135, 120, 35, "INFO", 2, 10},
{180, 185, 120, 35, "", -13, 10}
};
public:
RSettings();
void Draw(void) const override;
~RSettings();
void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) override;
};
void LoadSettings();
class 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;
};
class DSP_NF : public RenderD7::Ovl
{
public:
DSP_NF();
void Draw(void) const override;
void Logic() override;
private:
int msgposy = 240;
int delay = 0;
};
class Toast : public RenderD7::Ovl
{
public:
Toast(std::string head, std::string msg);
void Draw(void) const override;
void Logic() override;
private:
std::string head, msg;
int msgposy = 240;
int delay = 0;
};
void AddOvl(std::unique_ptr<RenderD7::Ovl> scene);
namespace Color
{
struct rgba
{
u8 r, g, b, a;
};
class RGBA{
public:
RGBA(u8 r, u8 g, u8 b, u8 a) : m_r(r),m_g(g),m_b(b),m_a(a){}
u32 toRGBA() const {return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a;}
u8 m_r, m_g ,m_b, m_a;
};
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 path;
bool isDir;
};
namespace FS
{
bool FileExist(const std::string& path);
}
bool IsNdspInit();
void SetupLog(void);
std::string GetFramerate();
bool MainLoop();
void ExitApp();
void ClearTextBufs(void);
std::string Kbd(int lenght, SwkbdType tp);
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
{
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;
};
struct TLBtn
{
int x; //Position X
int y; //Position Y
int w; //Button Width
int h; //Button Height
};
struct ScrollList1
{
std::string Text = "";
};
struct ScrollList2
{
float x;
float y;
float w;
float h;
std::string Text = "";
};
/*enum ListType
{
ONE,
TWO
};*/
void DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t);
void DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color, u32 txtcolor, 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
{
float x, y, s;
bool is_chexked = false;
u32 outcol, incol, chcol;
};
void DrawCheckbox(Checkbox box);
std::string FormatString(std::string fmt_str, ...);
std::string GetTimeStr(void);
class Console
{
public:
Console();
Console(int x, int y, int w, int h, u8 a = 255);
Console(int x, int y, int w, int h, RenderD7::Color::rgba col);
Console(int x, int y, int w, int h, std::string name, RenderD7::Color::rgba col = {255, 255, 255, 255}, RenderD7::Color::rgba barcol = {0, 0, 0, 255}, RenderD7::Color::rgba outlinecol = {222, 222, 222, 255});
void On(C3D_RenderTarget *t_cscreen);
bool Update();
~Console();
private:
std::vector<std::string> m_lines;
int x, y, w, h;
std::string m_name = "";
C3D_RenderTarget *cscreen;
bool m_nconsole = false;
bool m_mconsole = false;
RenderD7::Color::rgba color = {255, 255, 255, 255};
RenderD7::Color::rgba outlinecol = {222, 222, 222, 255};
RenderD7::Color::rgba barcolor = {0, 0, 0, 255};
};
bool NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions);
void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions);
void GetDirContents(std::vector<RenderD7::DirContent> &dircontent);
class BitmapPrinter
{
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
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <3ds.h>
#include <string>
/** Sound Class */
class sound {
public:
/// \brief Construct new Soundeffect
/// \param path Path to the .wav file
/// \param channel the channel 1-23
/// \param toloop true:loop the sound, false: don't loop
sound(const std::string& path, int channel = 1, bool toloop = false);
/** deconstruct the sound */
~sound();
/** play the sound */
void play();
/** stop the sound */
void stop();
private:
/// \param dataSize the Size of the filedata
u32 dataSize;
ndspWaveBuf waveBuf;
u8* data = NULL;
int chnl;
};
+11
View File
@@ -0,0 +1,11 @@
template<class T>
T GetFileName(T const & path, T const & delims = "/\\")
{
return path.substr(path.find_last_of(delims) + 1);
}
template<class T>
T remove_ext(T const & filename)
{
typename T::size_type const p(filename.find_last_of('.'));
return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
}
+119
View File
@@ -0,0 +1,119 @@
#pragma once
#include <3ds.h>
#include <atomic>
#include <functional>
#include <string>
#include <renderd7/parameter.hpp>
using CTRU_Thread = Thread;
#define THREAD_STACK_SIZE 0x1000
namespace RenderD7 {
namespace Threads
{
inline bool threadrunning = false;
struct Thread
{
Handle handle;
void (*ep)(void);
bool finished;
void* stacktop;
};
bool Create();
bool Join();
void Exit();
}
class Thread {
public:
/**
* @brief Default constructor
* @note This should only be called when calling m3d::Thread::initialize() before calling m3d::Thread::start()
*/
Thread();
/**
* @brief Constructs the thread
* @param t_function The thread function
* @param t_parameter The parameter to pass to the function
* @param t_autostart Whether the thread should start instantly
* @param t_detached Whether the thread starts detached or not
* @param t_stackSize The stacksize allocated for the thread in bytes (rounded to multiples of 8 bytes)
* @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter
* @warning If the thread priority is lower than the priority of the calling thread, the thread will never get executed. Use m3d::Thread::getCurrentPriority() to get the priority of the current thread
*/
Thread(std::function<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
*/
virtual ~Thread();
/**
* @brief Initializes the thread
* @param t_function The thread function
* @param t_parameter The parameter to pass to the function
* @param t_autostart Whether the thread should start instantly
* @param t_detached Whether the thread starts detached or not
* @param t_stackSize The stacksize allocated for the thread in bytes (rounded to multiples of 8 bytes)
* @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter
* @warning If the thread priority is lower than the priority of the calling thread, the thread will never get executed. Use m3d::Thread::getCurrentPriority() to get the priority of the current thread
*/
void initialize(std::function<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
* @param t_stackSize The allocated space in bytes (rounded to multiples of 8 bytes)
*/
void setStackSize(unsigned long long int t_stackSize);
/**
* @brief Starts the thread. To restart it, call Thread::join() before
* @param t_detached Whether the thread should start detached or not
*/
void start(bool t_detached = false);
/**
* @brief Detaches the thread
*/
void kill();
/**
* @brief Waits for the thread to finish
* @param t_timeout The timeout in nanoseconds. Leave it for no timeout
*/
void join(long long unsigned int t_timeout = U64_MAX);
bool isRunning();
/**
* @brief Puts the thread to sleep
*
* This is needed if you have multiple threads running at the same time. It doesn't affect the execution-time of the thread, it just makes it possible for the other threads to get their chance to shine.
*/
static void sleep();
/**
* @brief Sleeps for the given time
* @param t_milliseconds The time to sleep in milliseconds
*/
static void sleep(int t_milliseconds);
private:
struct ThreadData {
RenderD7::Parameter m_parameter;
std::function<void(RenderD7::Parameter)> m_function;
std::atomic<bool>* m_running;
};
static void threadFunction(void* t_arg);
/* data */
int m_priority, m_stackSize;
bool m_started;
std::atomic<bool> m_running;
RenderD7::Thread::ThreadData m_data;
CTRU_Thread m_thread;
};
}
+17
View File
@@ -0,0 +1,17 @@
#include <renderd7/Clock.hpp>
namespace rnd7{
enum class TweenType : int {Position = 1, Color, Alpha};
enum class TweenLoop : int {None = 1, Loop = 2,};
enum class TweenDirection : int {Current, Forward, Backward};
enum class TweenState : int {Playing = 1, Stopped};
class Tween
{
public:
Tween(float from, float to, float duration, TweenLoop loop, TweenState state);
};
}