0.9.5 preview1

This commit is contained in:
2024-02-19 19:20:37 +01:00
parent a671631dde
commit 168614d579
132 changed files with 49337 additions and 63128 deletions

View File

@ -1,475 +0,0 @@
#include <renderd7/BitmapPrinter.hpp>
#include <renderd7/ToastsV2.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::PushMessage(RenderD7::Message(
"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::PushMessage(RenderD7::Message(
"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::PushMessage(RenderD7::Message(
"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::PushMessage(RenderD7::Message(
"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::PushMessage(
RenderD7::Message("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;
}
void RenderD7::BitmapPrinter::DrawBitmap(int x, int y, BMP map) {
for (int i = 0; i < map.bmp_info_header.width; i++) {
for (int j = 0; j < map.bmp_info_header.height; j++) {
bitmap.set_pixel(
x + i, (bitmap.bmp_info_header.height - 1) - (y + j),
UNPACK_BGRA(map.get_pixel(i, (map.bmp_info_header.height - 1) - j)));
}
}
}

View File

@ -1,46 +1,218 @@
#include <map>
#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);
// }
// Lookup-Table für Hex-to-Dez-Konvertierung
static const std::map<char, int> HEX_TO_DEC = {
{'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5},
{'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11},
{'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'A', 10}, {'B', 11},
{'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
uint32_t RenderD7::Color::Hex(const std::string &color, uint8_t a) {
if (color.length() < 7 ||
std::find_if(color.begin() + 1, color.end(),
[](char c) { return !std::isxdigit(c); }) != color.end()) {
return RenderD7::Color::Hex("#000000", 0);
}
int r = HEX_TO_DEC.at(color[1]) * 16 + HEX_TO_DEC.at(color[2]);
int g = HEX_TO_DEC.at(color[3]) * 16 + HEX_TO_DEC.at(color[4]);
int b = HEX_TO_DEC.at(color[5]) * 16 + HEX_TO_DEC.at(color[6]);
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();
#include <filesystem>
#include <fstream>
#include <map>
#include <renderd7/Color.hpp>
#include <renderd7/external/json.hpp>
#include <renderd7/internal_db.hpp>
// This is btw the default theme setup
// RenderD7 StyleColor Api
// not const cause const = error lol
std::map<RD7Color, unsigned int> rd7i_color_map = {
{RD7Color_Text, RGBA8(0, 0, 0, 255)},
{RD7Color_Text2, RGBA8(255, 255, 255, 255)}, // For Background change or so
{RD7Color_TextDisabled, RGBA8(170, 170, 170, 255)},
{RD7Color_Background, RGBA8(238, 238, 238, 255)},
{RD7Color_Header, RGBA8(17, 17, 17, 255)},
{RD7Color_Selector, RGBA8(34, 34, 34, 255)},
{RD7Color_SelectorFade, RGBA8(90, 90, 90, 255)},
{RD7Color_List0, RGBA8(204, 204, 204, 255)}, // List0 = % 2
{RD7Color_List1, RGBA8(187, 187, 187, 255)},
{RD7Color_MessageBackground, RGBA8(51, 51, 51, 255)},
{RD7Color_Button, RGBA8(17, 17, 17, 255)},
{RD7Color_ButtonHovered, RGBA8(34, 34, 34, 255)},
{RD7Color_ButtonDisabled, RGBA8(8, 8, 8, 255)},
{RD7Color_ButtonActive, RGBA8(42, 42, 42, 255)},
{RD7Color_Checkmark, RGBA8(42, 42, 42, 255)},
{RD7Color_FrameBg, RGBA8(85, 85, 85, 255)},
{RD7Color_FrameBgHovered, RGBA8(119, 119, 119, 255)},
{RD7Color_Progressbar, RGBA8(0, 255, 0, 255)},
};
std::map<RD7Color, unsigned int> rd7i_color_swap_map;
unsigned int RenderD7::StyleColor(RD7Color color) {
if (rd7i_color_swap_map.find(color) != rd7i_color_swap_map.end())
return rd7i_color_swap_map[color];
else if (rd7i_color_map.find(color) != rd7i_color_map.end())
return rd7i_color_map[color];
return RGBA8(0, 0, 0, 0);
}
void RenderD7::ColorNew(RD7Color color, unsigned int new_color) {
// Dont edit before Init
if (!rd7i_running) return;
rd7i_color_map[color] = new_color;
}
void RenderD7::RedirectColor(RD7Color to, RD7Color from) {
// As you see at the code Redirect doesnt redirect xd
// Just named cause it feels like redirecting
// Oh and if the color is edit you redirect to it is
// grabs that redirected lol
rd7i_color_swap_map[to] = StyleColor(from);
}
void RenderD7::CustomizeColor(RD7Color color, unsigned int custom) {
rd7i_color_swap_map[color] = custom;
}
void RenderD7::TextColorByBg(RD7Color background) {
UndoColorEdit(RD7Color_Text); // To be sure
rd7i_color_swap_map[RD7Color_Text] = StyleColor(
Color::RGBA(background).is_light() ? RD7Color_Text : RD7Color_Text2);
}
void RenderD7::UndoColorEdit(RD7Color color) {
if (rd7i_color_swap_map.find(color) == rd7i_color_swap_map.end()) return;
rd7i_color_swap_map.erase(color);
}
void RenderD7::UndoAllColorEdits() { rd7i_color_swap_map.clear(); }
void rd7i_swap32(unsigned int& c) {
c = ((c & 0xFF) << 24) | ((c & 0xFF00) << 8) | ((c & 0xFF0000) >> 8) |
((c & 0xFF000000) >> 24);
}
std::string rd7i_mk2hex(unsigned int c32) {
rd7i_swap32(c32);
std::stringstream ss;
ss << "#";
ss << std::hex << std::setw(8) << std::setfill('0') << c32;
return ss.str();
}
// Standart Color Converter
static const std::map<char, int> HEX_TO_DEC = {
{'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5},
{'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11},
{'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'A', 10}, {'B', 11},
{'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
unsigned int rd7i_special_color_hex(const std::string& hex) {
if (hex.length() < 9 || std::find_if(hex.begin() + 1, hex.end(), [](char c) {
return !std::isxdigit(c);
}) != hex.end()) {
return rd7i_special_color_hex("#00000000");
}
int r = HEX_TO_DEC.at(hex[1]) * 16 + HEX_TO_DEC.at(hex[2]);
int g = HEX_TO_DEC.at(hex[3]) * 16 + HEX_TO_DEC.at(hex[4]);
int b = HEX_TO_DEC.at(hex[5]) * 16 + HEX_TO_DEC.at(hex[6]);
int a = HEX_TO_DEC.at(hex[7]) * 16 + HEX_TO_DEC.at(hex[8]);
return RGBA8(r, g, b, a);
}
void RenderD7::ThemeLoad(const std::string& path) {
std::ifstream file(path);
if (!file.is_open()) {
return;
}
nlohmann::json js;
file >> js;
// clang-format off
if(THEMEVER != js["version"]) {
file.close();
return;
}
rd7i_color_map[RD7Color_Text] =rd7i_special_color_hex(js["RD7Color_Text"].get<std::string>());
rd7i_color_map[RD7Color_Text2] =rd7i_special_color_hex(js["RD7Color_Text2"].get<std::string>());
rd7i_color_map[RD7Color_TextDisabled] =rd7i_special_color_hex(js["RD7Color_TextDisabled"].get<std::string>());
rd7i_color_map[RD7Color_Background] =rd7i_special_color_hex(js["RD7Color_Background"].get<std::string>());
rd7i_color_map[RD7Color_Header] =rd7i_special_color_hex(js["RD7Color_Header"].get<std::string>());
rd7i_color_map[RD7Color_Selector] =rd7i_special_color_hex(js["RD7Color_Selector"].get<std::string>());
rd7i_color_map[RD7Color_SelectorFade] =rd7i_special_color_hex(js["RD7Color_SelectorFade"].get<std::string>());
rd7i_color_map[RD7Color_List0] =rd7i_special_color_hex(js["RD7Color_List0"].get<std::string>());
rd7i_color_map[RD7Color_List1] =rd7i_special_color_hex(js["RD7Color_List1"].get<std::string>());
rd7i_color_map[RD7Color_MessageBackground] = rd7i_special_color_hex(js["RD7Color_MessageBackground"].get<std::string>());
rd7i_color_map[RD7Color_Button] =rd7i_special_color_hex(js["RD7Color_Button"].get<std::string>());
rd7i_color_map[RD7Color_ButtonHovered] =rd7i_special_color_hex(js["RD7Color_ButtonHovered"].get<std::string>());
rd7i_color_map[RD7Color_ButtonDisabled] =rd7i_special_color_hex(js["RD7Color_ButtonDisabled"].get<std::string>());
rd7i_color_map[RD7Color_ButtonActive] =rd7i_special_color_hex(js["RD7Color_ButtonActive"].get<std::string>());
rd7i_color_map[RD7Color_Checkmark] =rd7i_special_color_hex(js["RD7Color_Checkmark"].get<std::string>());
rd7i_color_map[RD7Color_FrameBg] =rd7i_special_color_hex(js["RD7Color_FrameBg"].get<std::string>());
rd7i_color_map[RD7Color_FrameBgHovered] =rd7i_special_color_hex(js["RD7Color_FrameBgHovered"].get<std::string>());
rd7i_color_map[RD7Color_Progressbar] =rd7i_special_color_hex(js["RD7Color_Progressbar"].get<std::string>());
// clang-format on
file.close();
}
void RenderD7::ThemeSave(const std::string& path) {
if (std::filesystem::path(path).filename().string() == "renderd7.theme") {
if (!rd7i_amdt) {
return;
}
}
std::ofstream file(path);
if (!file.is_open()) {
return;
}
nlohmann::json js;
// clang-format off
js["version"] = THEMEVER;
js["RD7Color_Text"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Text]);
js["RD7Color_Text2"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Text2]);
js["RD7Color_TextDisabled"] = rd7i_mk2hex(rd7i_color_map[RD7Color_TextDisabled]);
js["RD7Color_Background"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Background]);
js["RD7Color_Header"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Header]);
js["RD7Color_Selector"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Selector]);
js["RD7Color_SelectorFade"] = rd7i_mk2hex(rd7i_color_map[RD7Color_SelectorFade]);
js["RD7Color_List0"] = rd7i_mk2hex(rd7i_color_map[RD7Color_List0]);
js["RD7Color_List1"] = rd7i_mk2hex(rd7i_color_map[RD7Color_List1]);
js["RD7Color_MessageBackground"] = rd7i_mk2hex(rd7i_color_map[RD7Color_MessageBackground]);
js["RD7Color_Button"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Button]);
js["RD7Color_ButtonHovered"] = rd7i_mk2hex(rd7i_color_map[RD7Color_ButtonHovered]);
js["RD7Color_ButtonDisabled"] = rd7i_mk2hex(rd7i_color_map[RD7Color_ButtonDisabled]);
js["RD7Color_ButtonActive"] = rd7i_mk2hex(rd7i_color_map[RD7Color_ButtonActive]);
js["RD7Color_Checkmark"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Checkmark]);
js["RD7Color_FrameBg"] = rd7i_mk2hex(rd7i_color_map[RD7Color_FrameBg]);
js["RD7Color_FrameBgHovered"] = rd7i_mk2hex(rd7i_color_map[RD7Color_FrameBgHovered]);
js["RD7Color_Progressbar"] = rd7i_mk2hex(rd7i_color_map[RD7Color_Progressbar]);
// clang-format on
file << js.dump(4);
file.close();
}
void RenderD7::ThemeDefault() {
rd7i_color_map[RD7Color_Text] = RGBA8(0, 0, 0, 255);
rd7i_color_map[RD7Color_Text2] = RGBA8(255, 255, 255, 255);
rd7i_color_map[RD7Color_TextDisabled] = RGBA8(170, 170, 170, 255);
rd7i_color_map[RD7Color_Background] = RGBA8(238, 238, 238, 255);
rd7i_color_map[RD7Color_Header] = RGBA8(17, 17, 17, 255);
rd7i_color_map[RD7Color_Selector] = RGBA8(34, 34, 34, 255);
rd7i_color_map[RD7Color_SelectorFade] = RGBA8(90, 90, 90, 255);
rd7i_color_map[RD7Color_List0] = RGBA8(204, 204, 204, 255);
rd7i_color_map[RD7Color_List1] = RGBA8(187, 187, 187, 255);
rd7i_color_map[RD7Color_MessageBackground] = RGBA8(51, 51, 51, 255);
rd7i_color_map[RD7Color_Button] = RGBA8(17, 17, 17, 255);
rd7i_color_map[RD7Color_ButtonHovered] = RGBA8(34, 34, 34, 255);
rd7i_color_map[RD7Color_ButtonDisabled] = RGBA8(8, 8, 8, 255);
rd7i_color_map[RD7Color_ButtonActive] = RGBA8(42, 42, 42, 255);
rd7i_color_map[RD7Color_Checkmark] = RGBA8(42, 42, 42, 255);
rd7i_color_map[RD7Color_FrameBg] = RGBA8(85, 85, 85, 255);
rd7i_color_map[RD7Color_FrameBgHovered] = RGBA8(119, 119, 119, 255);
rd7i_color_map[RD7Color_Progressbar] = RGBA8(0, 255, 0, 255);
}
uint32_t RenderD7::Color::Hex(const std::string& color, uint8_t a) {
if (color.length() < 7 ||
std::find_if(color.begin() + 1, color.end(),
[](char c) { return !std::isxdigit(c); }) != color.end()) {
return RenderD7::Color::Hex("#000000", 0);
}
int r = HEX_TO_DEC.at(color[1]) * 16 + HEX_TO_DEC.at(color[2]);
int g = HEX_TO_DEC.at(color[3]) * 16 + HEX_TO_DEC.at(color[4]);
int b = HEX_TO_DEC.at(color[5]) * 16 + HEX_TO_DEC.at(color[6]);
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();
}

View File

@ -1,216 +0,0 @@
#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;
}

239
source/DrawV2.cpp Normal file
View File

@ -0,0 +1,239 @@
#include <citro2d.h>
#include <algorithm>
#include <renderd7/DrawV2.hpp>
#include <renderd7/global_db.hpp>
#include <renderd7/internal_db.hpp>
const float rd7i_d7_dts = 0.5f;
float rd7i_d2_txt_size = rd7i_d7_dts;
C2D_Font rd7i_d2_fnt = nullptr;
R7Vec2 rd7i_d7_mwh = R7Vec2(0, 0);
std::map<std::string, float> rd7i_d2_ts;
std::map<std::string, int> rd7i_d2_mln;
bool rd7i_txt_init = false;
std::string GetShortedText(const std::string &in, int maxlen) {
auto textdim = RenderD7::GetTextDimensions(in);
if (textdim.x < (float)maxlen) return in;
std::string ft = "";
std::string worker = in;
if (in.find_last_of('.') != in.npos) {
ft = in.substr(in.find_last_of('.'));
worker = in.substr(0, in.find_last_of('.'));
}
maxlen -= RenderD7::GetTextDimensions(ft).x -
RenderD7::GetTextDimensions("(...)").x;
float len_mod = (float)maxlen / textdim.x;
int pos = (in.length() * len_mod) / rd7_draw2_tsm;
std::string out;
out = in.substr(0, pos);
for (size_t i = pos; i < worker.length(); i++) {
out += worker[i];
if (RenderD7::GetTextDimensions(out + "(...)" + ft).x > (float)maxlen) {
out += "(...)";
out += ft;
return out;
}
}
return ""; // Impossible to reach
}
std::string WrapText(const std ::string &in, int maxlen) {
std::string out;
std::string line;
int line_x = 0;
std::istringstream istream(in);
std::string temp;
while (istream >> temp) {
R7Vec2 dim = RenderD7::GetTextDimensions(line + temp);
if (line_x + dim.x <= maxlen) {
line += temp + ' ';
line_x += dim.x;
} else {
out += line + '\n';
line = temp + ' ';
line_x = dim.x;
}
}
out += line;
return out;
}
bool RD7I_FNT_VALID() {
if (rd7i_d2_fnt != nullptr && !rd7i_txt_init) {
rd7i_txt_init = true;
}
if (!rd7i_txt_init) {
if (rd7i_base_font != nullptr) {
rd7i_d2_fnt = rd7i_base_font;
rd7i_txt_init = true;
return true;
}
}
if (rd7i_d2_fnt != nullptr) {
return true;
} else {
rd7i_d2_fnt = rd7i_base_font;
return true;
}
// Schould never be reached
return false;
}
namespace RenderD7 {
R7Vec2 GetTextDimensions(const std::string &text) {
C2D_TextBufClear(rd7i_d2_dimbuf);
float w = 0, h = 0;
if (!RD7I_FNT_VALID()) return R7Vec2(w, h);
C2D_Text c2dtext;
C2D_TextFontParse(&c2dtext, rd7i_d2_fnt, rd7i_d2_dimbuf, text.c_str());
C2D_TextGetDimensions(&c2dtext, rd7i_d2_txt_size, rd7i_d2_txt_size, &w, &h);
return R7Vec2(w, h);
}
void CustomTextSize(float size) { rd7i_d2_txt_size = size; }
void TextDefaultSize() { rd7i_d2_txt_size = rd7i_d7_dts; }
void TextMaxBox(R7Vec2 size) { rd7i_d7_mwh = size; }
void TextDefaultBox() { rd7i_d7_mwh = R7Vec2(0, 0); }
void TextFont(Font fnt) { rd7i_d2_fnt = fnt.ptr(); }
void TextDefaultFont() { rd7i_d2_fnt = rd7i_base_font; }
std::string TextShort(const std::string &in, int max_len) {
return GetShortedText(in, max_len);
}
namespace Draw2 {
void Rect(R7Vec2 pos, R7Vec2 size, unsigned int color, int t) {
// 4 DrawLine Calls Lol
C2D_DrawLine(pos.x, pos.y, color, pos.x + size.x, pos.y, color, t, 1.f);
C2D_DrawLine(pos.x, pos.y, color, pos.x, pos.y + size.y, color, t, 1.f);
C2D_DrawLine(pos.x + size.x, pos.y, color, pos.x + size.x, pos.y + size.y,
color, t, 1.f);
C2D_DrawLine(pos.x, pos.y + size.y, color, pos.x + size.x, pos.y + size.y,
color, t, 1.f);
}
void RectFilled(R7Vec2 pos, R7Vec2 size, Color4 colors) {
C2D_DrawRectangle(pos.x, pos.y, 0.5f, size.x, size.y, colors.color0,
colors.color1, colors.color2, colors.color3);
}
void RectFilledSolid(R7Vec2 pos, R7Vec2 size, unsigned int color) {
C2D_DrawRectSolid(pos.x, pos.y, 0.5f, size.x, size.y, color);
}
void Line(R7Vec2 pos0, R7Vec2 pos1, unsigned int color, int t) {
C2D_DrawLine(pos0.x, pos0.y, color, pos1.x, pos1.y, color, t, 1.f);
}
void Triangle(R7Vec2 pos0, R7Vec2 pos1, R7Vec2 pos2, Color3 colors) {
C2D_DrawTriangle(pos0.x, pos0.y, colors.color0, pos1.x, pos1.y, colors.color1,
pos2.x, pos2.y, colors.color2, 0.5f);
}
void TriangleSolid(R7Vec2 pos0, R7Vec2 pos1, R7Vec2 pos2, unsigned int color) {
C2D_DrawTriangle(pos0.x, pos0.y, color, pos1.x, pos1.y, color, pos2.x, pos2.y,
color, 0.5f);
}
void TriangleLined(R7Vec2 pos0, R7Vec2 pos1, R7Vec2 pos2, unsigned int color,
int t) {
// 3 Line Cqalls lol more efficient than Rect
C2D_DrawLine(pos0.x, pos0.y, color, pos1.x, pos1.y, color, t, 1.f);
C2D_DrawLine(pos0.x, pos0.y, color, pos2.x, pos2.y, color, t, 1.f);
C2D_DrawLine(pos1.x, pos1.y, color, pos2.x, pos2.y, color, t, 1.f);
}
void Text(R7Vec2 pos, const std::string &text, RD7TextFlags flags) {
// The Start of the C2D Text Hell
if (!RD7I_FNT_VALID()) return;
// little patch for a freeze
if (text.length() < 1) return;
// Variables
bool updated_mwh = false;
if (rd7i_d7_mwh.x == 0.0f) {
rd7i_d7_mwh.x = rd7i_current_screen ? 400 : 320;
updated_mwh = true;
}
if (rd7i_d7_mwh.y == 0.0f) {
rd7i_d7_mwh.y = 240;
updated_mwh = true;
}
std::string edit_text = text;
if (edit_text.substr(text.length() - 1) != "\n")
edit_text.append("\n"); // Add \n to end if not exist
int line = 0;
if (flags & RD7TextFlags_Wrap)
edit_text = WrapText(text, rd7i_d7_mwh.x - pos.x);
while (edit_text.find('\n') != edit_text.npos) {
std::string current_line = edit_text.substr(0, edit_text.find('\n'));
if (flags & RD7TextFlags_Short)
current_line = GetShortedText(current_line, rd7i_d7_mwh.x - pos.x);
R7Vec2 newpos = pos;
// Check Flags
R7Vec2 dim = GetTextDimensions(current_line);
if (flags & RD7TextFlags_AlignRight)
newpos.x = newpos.x - GetTextDimensions(current_line).x;
if (flags & RD7TextFlags_AlignMid) // Offset by inpos
newpos.x = (rd7i_d7_mwh.x * 0.5) - (dim.x * 0.5) + pos.x;
if (flags & RD7TextFlags_Scroll) { // Scroll Text
if (newpos.x + dim.x > rd7i_d7_mwh.x - newpos.x - 10) {
if (rd7i_d2_ts.find(current_line) == rd7i_d2_ts.end())
rd7i_d2_ts[current_line] = 0;
if (rd7i_d2_mln.find(current_line) == rd7i_d2_mln.end())
rd7i_d2_mln[current_line] =
GetShortedText(current_line, rd7i_d7_mwh.x - newpos.x).length();
rd7i_d2_ts[current_line] += rd7i_dtm * 6;
if ((int)rd7i_d2_ts[current_line] >= (int)current_line.length()) {
rd7i_d2_ts[current_line] = 0.0f;
}
std::string bcl = current_line;
current_line = current_line.substr((int)rd7i_d2_ts[current_line],
rd7i_d2_mln[current_line]);
if (newpos.x + GetTextDimensions(current_line).x <
rd7i_d7_mwh.x - newpos.x)
current_line +=
"|" + bcl.substr(0, rd7i_d2_ts[bcl] - (int)current_line.length());
}
}
if (rd7_debugging) {
RenderD7::Draw2::Rect(newpos, dim, RenderD7::Color::Hex("#ff0000"));
}
C2D_Text c2dtext;
C2D_TextFontParse(&c2dtext, rd7i_d2_fnt, rd7i_text_buffer,
current_line.c_str());
C2D_TextOptimize(&c2dtext);
if (flags & RD7TextFlags_Shaddow) // performance Killer xd
C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x + 1 + (dim.y * line),
newpos.y + 1, 0.5, rd7i_d2_txt_size, rd7i_d2_txt_size,
RenderD7::StyleColor(RD7Color_TextDisabled));
C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x, newpos.y + (dim.y * line),
0.5, rd7i_d2_txt_size, rd7i_d2_txt_size,
RenderD7::StyleColor(RD7Color_Text));
edit_text = edit_text.substr(edit_text.find('\n') + 1);
line++;
}
if (updated_mwh) rd7i_d7_mwh = R7Vec2(0, 0);
}
void Image(RenderD7::Image *img, const R7Vec2 &pos, const R7Vec2 &scale) {
if (img->loaded())
C2D_DrawImageAt(img->get(), pos.x, pos.y, 0.5f, nullptr, scale.x, scale.y);
}
} // namespace Draw2
} // namespace RenderD7

44
source/Error.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <3ds.h>
#include <renderd7/Error.hpp>
#include <renderd7/UI7.hpp>
#include <renderd7/internal_db.hpp>
#include <renderd7/renderd7.hpp>
namespace RenderD7 {
void Error(const std::string& msg) {
if (rd7i_graphics_on) {
C3D_FrameEnd(0);
while (aptMainLoop()) {
hidScanInput();
if (hidKeysDown() & KEY_START) break;
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
RenderD7::ClearTextBufs();
C2D_TargetClear(Top, 0x00000000);
C2D_TargetClear(Bottom, 0x00000000);
RenderD7::OnScreen(Top);
if (UI7::BeginMenu("RenderD7 - Error Manager", R7Vec2(),
UI7MenuFlags_TitleMid)) {
UI7::Label(msg, RD7TextFlags_Wrap);
UI7::Label("Press Start to Exit!");
UI7::EndMenu();
}
RenderD7::OnScreen(Bottom);
C3D_FrameEnd(0);
}
exit(0);
} else {
gfxInitDefault();
consoleInit(GFX_TOP, NULL);
printf("RENDERD7 - ERROR MANAGER\n\n%s\n", msg.c_str());
printf("Press Start to Exit\n");
while (aptMainLoop()) {
hidScanInput();
if (hidKeysDown() & KEY_START) break;
gfxSwapBuffers();
}
gfxExit();
exit(0);
}
}
} // namespace RenderD7

View File

@ -1,19 +1,73 @@
#include <3ds.h>
#include <cstring>
#include <renderd7/FileSystem.hpp>
// Debugging
#include <memory>
#include <renderd7/stringtool.hpp>
#include <filesystem>
std::vector<RenderD7::FileSystem::Entry>
RenderD7::FileSystem::GetDirContent(std::string path) {
std::vector<RenderD7::FileSystem::Entry> res;
for (const auto &entry :
std::filesystem::directory_iterator(std::filesystem::path(path))) {
res.push_back({entry.path().string(), GetFileName(entry.path().string()),
entry.is_directory()});
}
return res;
#include <3ds.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <renderd7/FileSystem.hpp>
// Debugging
#include <algorithm>
#include <filesystem>
#include <memory>
#include <renderd7/stringtool.hpp>
bool ___dir__predicate__(const RenderD7::FileSystem::Entry &lhs,
const RenderD7::FileSystem::Entry &rhs) {
if (!lhs.dir && rhs.dir) return false;
if (lhs.dir && !rhs.dir) return true;
std::string a = lhs.name;
std::string b = rhs.name;
std::transform(a.begin(), a.end(), a.begin(),
[](int i) { return std::tolower(i); });
std::transform(b.begin(), b.end(), b.begin(),
[](int i) { return std::tolower(i); });
return a.compare(b) < 0;
}
std::string RenderD7::FileSystem::GetParentPath(std::string path,
std::string mount_point) {
std::string tcl = path;
if (path.substr(path.length() - 1, 1) != "/") {
tcl += "/";
}
std::string res;
if (std::filesystem::exists(
std::filesystem::path(tcl).parent_path().parent_path()))
res = std::filesystem::path(tcl).parent_path().parent_path().string();
if (res.length() > mount_point.length()) {
return res;
}
return mount_point;
}
std::vector<RenderD7::FileSystem::Entry> RenderD7::FileSystem::GetDirContent(
std::string path) {
std::vector<RenderD7::FileSystem::Entry> res;
for (const auto &entry :
std::filesystem::directory_iterator(std::filesystem::path(path))) {
res.push_back({entry.path().string(), GetFileName(entry.path().string()),
entry.is_directory()});
}
return res;
}
std::vector<RenderD7::FileSystem::Entry>
RenderD7::FileSystem::GetDirContentsExt(
std::string &path, const std::vector<std::string> &extensions) {
std::vector<RenderD7::FileSystem::Entry> res;
for (auto const &it :
std::filesystem::directory_iterator(std::filesystem::path(path))) {
RenderD7::FileSystem::Entry temp;
std::string fn = it.path().string();
temp.name = GetFileName(fn);
temp.path = it.path().string().c_str();
temp.dir = it.is_directory();
if (NameIsEndingWith(GetFileName(it.path().string()), extensions) ||
it.is_directory()) {
res.push_back(temp);
}
}
std::sort(res.begin(), res.end(), ___dir__predicate__);
return res;
}

View File

@ -1,3 +1,3 @@
#include <renderd7/FunctionTrace.hpp>
#include <renderd7/FunctionTrace.hpp>
std::map<std::string, RenderD7::Ftrace::FTRes> RenderD7::Ftrace::rd7_traces;

View File

@ -1,46 +1,46 @@
#include <renderd7/Hardware.hpp>
#include <renderd7/Security.hpp>
// Os Specific includes
#include <3ds.h>
// RenderD7 Security
extern bool isndspinit;
void RenderD7::Hardware::Initialisize() {
rd7_security->SafeInit(mcuHwcInit, &mcuHwcExit);
rd7_security->SafeInit(ptmuInit, &ptmuExit);
}
bool RenderD7::Hardware::IsHeadphones() {
if (isndspinit) {
bool inserted;
DSP_GetHeadphoneStatus(&inserted);
return inserted;
} else
return false;
}
bool RenderD7::Hardware::IsCharging() {
uint8_t var;
PTMU_GetBatteryChargeState(&var);
// Some Security Stuff
if (var < 0x00 && var > 0x01) {
return false;
}
return (var == 0x01 ? true : false);
}
float RenderD7::Hardware::GetBatteryPercentage() {
uint8_t percentLevel;
PTMU_GetBatteryLevel(&percentLevel);
return (float)percentLevel / 100;
}
float RenderD7::Hardware::Get3dSliderLevel() { return osGet3DSliderState(); }
float RenderD7::Hardware::GetSoundSliderLevel() {
uint8_t percentLevel;
MCUHWC_GetSoundSliderLevel(&percentLevel);
return (float)percentLevel / 100;
#include <renderd7/Hardware.hpp>
#include <renderd7/Security.hpp>
// Os Specific includes
#include <3ds.h>
// RenderD7 Security
extern bool isndspinit;
void RenderD7::Hardware::Initialisize() {
rd7_security->SafeInit(mcuHwcInit, &mcuHwcExit);
rd7_security->SafeInit(ptmuInit, &ptmuExit);
}
bool RenderD7::Hardware::IsHeadphones() {
if (isndspinit) {
bool inserted;
DSP_GetHeadphoneStatus(&inserted);
return inserted;
} else
return false;
}
bool RenderD7::Hardware::IsCharging() {
uint8_t var;
PTMU_GetBatteryChargeState(&var);
// Some Security Stuff
if (var < 0x00 && var > 0x01) {
return false;
}
return (var == 0x01 ? true : false);
}
float RenderD7::Hardware::GetBatteryPercentage() {
uint8_t percentLevel;
PTMU_GetBatteryLevel(&percentLevel);
return (float)percentLevel / 100;
}
float RenderD7::Hardware::Get3dSliderLevel() { return osGet3DSliderState(); }
float RenderD7::Hardware::GetSoundSliderLevel() {
uint8_t percentLevel;
MCUHWC_GetSoundSliderLevel(&percentLevel);
return (float)percentLevel / 100;
}

110
source/Hid.cpp Normal file
View File

@ -0,0 +1,110 @@
#include <map>
#include <renderd7/Hid.hpp>
namespace RenderD7 {
class HidApi {
public:
HidApi() {}
~HidApi() {}
void setKdown(uint32_t &in) { actions[Hid::Down] = &in; }
void setKheld(uint32_t &in) { actions[Hid::Held] = &in; }
void setKup(uint32_t &in) { actions[Hid::Up] = &in; }
void setKrepeat(uint32_t &in) { actions[Hid::DownRepeat] = &in; }
void setTouchCoords(R7Vec2 &touch_coords) { touch_pos = &touch_coords; }
void setJS1Movement(R7Vec2 &mvmt) { js1_mv = &mvmt; }
void setJS2Movement(R7Vec2 &mvmt) { js2_mv = &mvmt; }
void bindKey(const std::string &event, uint32_t key) {
key_bindings[event] = key; // Overrides if existing
}
void lock(bool lock) { locked = lock; }
void clear() {
// Clears Functionality for 1 Frame
last_touch_pos = R7Vec2();
touch_pos[0] = R7Vec2();
backups[Hid::Down] = 0;
backups[Hid::Held] = 0;
backups[Hid::Up] = 0;
backups[Hid::DownRepeat] = 0;
}
bool isEvent(const std::string &event, Hid::Actions action) {
if (locked) return false;
if (key_bindings.find(event) == key_bindings.end())
return false; // Unknown Event
if (backups.find(action) == backups.end())
return false; // What? NOT Alowed acrion
if (backups[action] & key_bindings[event])
return true; // Action contains key as flag
return false; // Nothing to do
}
R7Vec2 getTouchPos() { return touch_pos[0]; }
R7Vec2 getLastTouchPos() { return last_touch_pos; }
void update() {
last_touch_pos = touch_pos[0];
for (const auto &it : actions) {
backups[it.first] = it.second[0];
}
if (locked) {
actions[Hid::Down][0] = 0;
actions[Hid::Held][0] = 0;
actions[Hid::Up][0] = 0;
actions[Hid::DownRepeat][0] = 0;
}
}
private:
std::map<Hid::Actions, uint32_t *> actions;
std::map<Hid::Actions, uint32_t> backups;
R7Vec2 *touch_pos = nullptr;
R7Vec2 *js1_mv = nullptr;
R7Vec2 *js2_mv = nullptr;
R7Vec2 last_touch_pos;
std::map<std::string, uint32_t> key_bindings;
bool locked = false;
};
static HidApi hid_handler;
namespace Hid {
// Register Functions
// Register Current state values
void RegKeyDown(uint32_t &key_down) { hid_handler.setKdown(key_down); }
void RegKeyHeld(uint32_t &key_held) { hid_handler.setKheld(key_held); }
void RegKeyUp(uint32_t &key_up) { hid_handler.setKup(key_up); }
void RegKeyRepeat(uint32_t &repeat) { hid_handler.setKrepeat(repeat); }
void RegTouchCoords(R7Vec2 &touch_pos) {
hid_handler.setTouchCoords(touch_pos);
}
void RegAnalog1Movement(R7Vec2 &movement) {
hid_handler.setJS1Movement(movement);
}
void RegAnalog2Movement(R7Vec2 &movement) {
hid_handler.setJS2Movement(movement);
}
// Register Keys
void RegKeyEvent(const std::string &event, uint32_t key) {
hid_handler.bindKey(event, key);
}
bool IsEvent(const std::string &event, Actions action) {
return hid_handler.isEvent(event, action);
}
R7Vec2 GetTouchPosition() { return hid_handler.getTouchPos(); }
R7Vec2 GetLastTouchPosition() { return hid_handler.getLastTouchPos(); }
void Update() { hid_handler.update(); }
void Lock() { hid_handler.lock(true); }
void Unlock() { hid_handler.lock(false); }
void Clear() { hid_handler.clear(); }
} // namespace Hid
} // namespace RenderD7

View File

@ -1,338 +1,168 @@
#include <renderd7/Image.hpp>
#include <renderd7/ToastsV2.hpp>
#include <renderd7/external/stb_image.h>
extern bool usedbgmsg;
void convert24to32(unsigned char *inputImage, int width, int height,
unsigned char *outputImage) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int i = (y * width + x) * 3; // index of current pixel in input image
int j = (y * width + x) * 4; // index of current pixel in output image
outputImage[j] = inputImage[i]; // copy red channel
outputImage[j + 1] = inputImage[i + 1]; // copy green channel
outputImage[j + 2] = inputImage[i + 2]; // copy blue channel
outputImage[j + 3] = 255; // set alpha channel to 255 (fully opaque)
}
}
}
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;
}
static void OLD_C3DTexToC2DImage(C3D_Tex *tex, Tex3DS_SubTexture *subtex,
u8 *buf, u32 size, u32 width, u32 height,
GPU_TEXCOLOR format) {
// RGBA -> ABGR
for (u32 row = 0; row < width; row++) {
for (u32 col = 0; col < height; col++) {
u32 z = (row + col * width) * 4;
u8 r = *(u8 *)(buf + z);
u8 g = *(u8 *)(buf + z + 1);
u8 b = *(u8 *)(buf + z + 2);
u8 a = *(u8 *)(buf + z + 3);
*(buf + z) = a;
*(buf + z + 1) = b;
*(buf + z + 2) = g;
*(buf + z + 3) = r;
}
}
u32 w_pow2 = GetNextPowerOf2(width);
u32 h_pow2 = GetNextPowerOf2(height);
subtex->width = (u16)width;
subtex->height = (u16)height;
subtex->left = 0.0f;
subtex->top = 1.0f;
subtex->right = (width / (float)w_pow2);
subtex->bottom = 1.0 - (height / (float)h_pow2);
C3D_TexInit(tex, (u16)w_pow2, (u16)h_pow2, format);
C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
u32 pixel_size = (size / width / height);
memset(tex->data, 0, tex->size);
for (u32 x = 0; x < width; x++) {
for (u32 y = 0; y < height; y++) {
u32 dst_pos = ((((y >> 3) * (w_pow2 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
pixel_size;
u32 src_pos = (y * width + x) * pixel_size;
memcpy(&((u8 *)tex->data)[dst_pos], &((u8 *)buf)[src_pos], pixel_size);
}
}
C3D_TexFlush(tex);
tex->border = 0x00000000;
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
linearFree(buf);
}
bool IMG_LoadImageFile(C2D_Image *texture, const char *path) {
stbi_uc *image = NULL;
int width = 0, height = 0;
int nc;
image = stbi_load(path, &width, &height, &nc, 4);
if (width > 1024 || height > 1024) {
stbi_image_free(image);
return false;
}
C3D_Tex *tex = new C3D_Tex;
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture;
OLD_C3DTexToC2DImage(tex, subtex, image, (u32)(width * height * 4),
(u32)width, (u32)height, GPU_RGBA8);
texture->tex = tex;
texture->subtex = subtex;
stbi_image_free(image);
return true;
}
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 =
C3DTexToC2DImage(&this->img, bitmap.bmp_info_header.width,
bitmap.bmp_info_header.height, bitmap.data.data());
if (error == 0) {
this->loadet = true;
}
if (error) {
std::cout << "BMP decoding error " << error << std::endl;
RenderD7::PushMessage(
RenderD7::Message("Bmp - Error", "Code: " + std::to_string(error)));
}
}
namespace RenderD7 {
void Image::LoadJpg(std::string path) {
if (usedbgmsg) {
// RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top);
}
if (loadet) {
C3D_TexDelete(this->img.tex);
loadet = false;
}
IMG_LoadImageFile(&this->img, path.c_str());
loadet = true;
}
void Image::LoadPixels(int w, int h, int bpp, void *buffer) {
if (loadet) {
C3D_TexDelete(this->img.tex);
loadet = false;
}
unsigned width, height;
width = w;
height = h;
uint8_t *ImageBuffer = new uint8_t[w * h * 4];
if (bpp == 3)
convert24to32((uint8_t *)buffer, width, height, ImageBuffer);
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[srcPos + 3];
((uint8_t *)img.tex->data)[dstPos + 1] = ImageBuffer[srcPos + 2];
((uint8_t *)img.tex->data)[dstPos + 2] = ImageBuffer[srcPos + 1];
((uint8_t *)img.tex->data)[dstPos + 3] = ImageBuffer[srcPos + 0];
}
}
delete[] ImageBuffer;
loadet = true;
}
} // namespace RenderD7
#include <renderd7/external/stb_image.h>
#include <renderd7/Image.hpp>
#include <vector>
static u32 __rd7i_gp2o__(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 void __rd7i_r24r32(std::vector<uint8_t> &out,
const std::vector<uint8_t> &in, const int &w,
const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 3;
int dst = (y * w + x) * 4;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
out[dst + 3] = 255;
}
}
}
static void __rd7i_c3dc2d__(C3D_Tex *tex, Tex3DS_SubTexture *subtex, u8 *buf,
u32 size, u32 width, u32 height) {
// RGBA -> ABGR
for (u32 row = 0; row < width; row++) {
for (u32 col = 0; col < height; col++) {
u32 z = (row + col * width) * 4;
u8 r = *(u8 *)(buf + z);
u8 g = *(u8 *)(buf + z + 1);
u8 b = *(u8 *)(buf + z + 2);
u8 a = *(u8 *)(buf + z + 3);
*(buf + z) = a;
*(buf + z + 1) = b;
*(buf + z + 2) = g;
*(buf + z + 3) = r;
}
}
u32 w_pow2 = __rd7i_gp2o__(width);
u32 h_pow2 = __rd7i_gp2o__(height);
subtex->width = (u16)width;
subtex->height = (u16)height;
subtex->left = 0.0f;
subtex->top = 1.0f;
subtex->right = (width / (float)w_pow2);
subtex->bottom = 1.0 - (height / (float)h_pow2);
C3D_TexInit(tex, (u16)w_pow2, (u16)h_pow2, GPU_RGBA8);
C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
u32 pixel_size = (size / width / height);
memset(tex->data, 0, tex->size);
for (u32 x = 0; x < width; x++) {
for (u32 y = 0; y < height; y++) {
u32 dst_pos = ((((y >> 3) * (w_pow2 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
pixel_size;
u32 src_pos = (y * width + x) * pixel_size;
memcpy(&((u8 *)tex->data)[dst_pos], &((u8 *)buf)[src_pos], pixel_size);
}
}
C3D_TexFlush(tex);
tex->border = 0x00000000;
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
// linearFree(buf);
}
namespace RenderD7 {
Image::Image() {
img.tex = nullptr;
img.subtex = nullptr;
}
Image::~Image() { safe_del(); }
void Image::load(const std::string &path) {
// Make sure to cleanup
safe_del();
ld = false;
// Setup Func and Load Data
int w, h, c = 0;
uint8_t *image = stbi_load(path.c_str(), &w, &h, &c, 4);
if (image == nullptr) {
return;
}
// Size/Fmt Check
if (w > 1024 || h > 1024) {
// Reason: Image to Large
stbi_image_free(image);
return;
}
std::vector<uint8_t> wimg(w * h * 4);
if (c == 3) {
stbi_image_free(image);
image = stbi_load(path.c_str(), &w, &h, &c, 3);
__rd7i_r24r32(wimg, std::vector<uint8_t>(image, image + (w * h * 3)), w, h);
} else {
// Maybe find a better solution later
for (size_t i = 0; i < wimg.size(); i++) {
wimg[i] = image[i];
}
}
stbi_image_free(image);
// Create C2D_Image
C3D_Tex *tex = new C3D_Tex;
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture;
__rd7i_c3dc2d__(tex, subtex, wimg.data(), (u32)(w * h * 4), (u32)w, (u32)h);
img.tex = tex;
img.subtex = subtex;
ld = true;
}
void Image::from_nimg(const nimg &image) {
// Make sure to cleanup
safe_del();
ld = false;
if (image.width > 1024 || image.height > 1024) return;
C3D_Tex *tex = new C3D_Tex;
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture;
__rd7i_c3dc2d__(tex, subtex, (u8 *)image.pixel_buffer.data(),
(u32)image.pixel_buffer.size(), (u32)image.width,
(u32)image.height);
img.tex = tex;
img.subtex = subtex;
ld = true;
}
C2D_Image Image::get() { return img; }
C2D_Image &Image::get_ref() { return img; }
void Image::set(const C2D_Image &i) {
safe_del();
img = i;
}
R7Vec2 Image::get_size() {
if (!img.subtex) return R7Vec2(0, 0);
return R7Vec2(img.subtex->width, img.subtex->height);
}
void Image::safe_del() {
if (img.subtex != nullptr) delete img.subtex;
if (img.tex != nullptr) delete img.tex;
}
bool Image::loaded() { return ld; }
} // namespace RenderD7

View File

@ -1,60 +1,54 @@
#include <map>
#include <renderd7/Memory.hpp>
static RenderD7::Memory::memory_metrics metrics;
bool rd7_enable_memtrack;
void *operator new(size_t size) {
void *ptr = malloc(size);
if (rd7_enable_memtrack)
metrics.t_TotalAllocated += size;
return ptr;
}
void operator delete(void *memory, size_t size) {
if (rd7_enable_memtrack)
metrics.t_TotalFreed += size;
free(memory);
}
int allocations = 0;
int total_size = 0;
std::map<void *, size_t> sizes;
void *operator new[](size_t size) {
if (rd7_enable_memtrack)
allocations++;
if (rd7_enable_memtrack)
total_size += size;
void *ptr = malloc(size);
if (rd7_enable_memtrack)
sizes[ptr] = size;
if (rd7_enable_memtrack)
metrics.t_TotalAllocated += size;
return ptr;
}
void operator delete[](void *ptr) {
if (rd7_enable_memtrack)
allocations--;
if (rd7_enable_memtrack)
total_size -= sizes[ptr];
if (rd7_enable_memtrack)
metrics.t_TotalFreed += sizes[ptr];
if (rd7_enable_memtrack)
sizes.erase(ptr);
free(ptr);
}
namespace RenderD7 {
namespace Memory {
size_t GetTotalAllocated() { return metrics.t_TotalAllocated; }
size_t GetTotalFreed() { return metrics.t_TotalFreed; }
size_t GetCurrent() { return metrics.t_CurrentlyAllocated(); }
} // namespace Memory
} // namespace RenderD7
#include <cstdlib>
#include <map>
#include <renderd7/Memory.hpp>
static RenderD7::Memory::memory_metrics metrics;
bool rd7_enable_memtrack;
#ifdef RENDERD7_MEMTRACK
void *operator new(size_t size) {
void *ptr = malloc(size);
if (rd7_enable_memtrack) metrics.t_TotalAllocated += size;
return ptr;
}
void operator delete(void *memory, size_t size) {
if (rd7_enable_memtrack) metrics.t_TotalFreed += size;
free(memory);
}
int allocations = 0;
int total_size = 0;
std::map<void *, size_t> sizes;
void *operator new[](size_t size) {
if (rd7_enable_memtrack) allocations++;
if (rd7_enable_memtrack) total_size += size;
void *ptr = malloc(size);
if (rd7_enable_memtrack) sizes[ptr] = size;
if (rd7_enable_memtrack) metrics.t_TotalAllocated += size;
return ptr;
}
void operator delete[](void *ptr) {
if (rd7_enable_memtrack) allocations--;
if (rd7_enable_memtrack) total_size -= sizes[ptr];
if (rd7_enable_memtrack) metrics.t_TotalFreed += sizes[ptr];
if (rd7_enable_memtrack) sizes.erase(ptr);
free(ptr);
}
#endif
namespace RenderD7 {
namespace Memory {
size_t GetTotalAllocated() { return metrics.t_TotalAllocated; }
size_t GetTotalFreed() { return metrics.t_TotalFreed; }
size_t GetCurrent() { return metrics.t_CurrentlyAllocated(); }
} // namespace Memory
} // namespace RenderD7

98
source/Message.cpp Normal file
View File

@ -0,0 +1,98 @@
#include <algorithm>
#include <memory>
#include <renderd7/Color.hpp>
#include <renderd7/DrawV2.hpp> // Update to Draw2
#include <renderd7/Message.hpp>
#include <renderd7/Screen.hpp>
#include <vector>
extern bool rd7_debugging;
static std::vector<std::shared_ptr<RenderD7::Message>> msg_lst;
static int fade_outs = 200; // Start of fadeout
static int idles = 60; // start of Idle
static int anim_len = 300; // Full Length of Animation
R7Vec2 MakePos(int frame, int entry) {
float fol = anim_len - fade_outs;
if (frame > fade_outs)
return R7Vec2(5, 240 - ((entry + 1) * 55) - 5 +
(float)((frame - fade_outs) / fol) * -20);
if (frame > idles) return R7Vec2(5, 240 - ((entry + 1) * 55) - 5);
return R7Vec2(-150 + ((float)(frame / (float)idles) * 155),
240 - ((entry + 1) * 55) - 5);
}
namespace RenderD7 {
float GetDeltaTime(); // Extern from renderd7.cpp
void ProcessMessages() {
// Draw in ovl mode
RenderD7::OnScreen(Top);
float fol = anim_len - fade_outs;
std::reverse(msg_lst.begin(), msg_lst.end());
for (size_t i = 0; i < msg_lst.size(); i++) {
R7Vec2 pos = MakePos(msg_lst[i]->animationframe, i);
if ((pos.y + 150) < 0) {
// Dont Render Out of Screen
// And as thay aren't relevant anymore
// Thay get deleted!
msg_lst.erase(msg_lst.begin() + i);
} else {
int new_alpha = 200;
if (msg_lst[i]->animationframe > fade_outs) {
new_alpha =
200 - (float(msg_lst[i]->animationframe - fade_outs) / fol) * 200;
}
// Wtf is this function lol
RenderD7::CustomizeColor(RD7Color_MessageBackground,
RenderD7::Color::RGBA(RD7Color_MessageBackground)
.changeA(new_alpha)
.toRGBA());
RenderD7::CustomizeColor(
RD7Color_Text,
RenderD7::Color::RGBA(RD7Color_Text2).changeA(new_alpha).toRGBA());
RenderD7::Draw2::RFS(pos, R7Vec2(150, 50),
RenderD7::StyleColor(RD7Color_MessageBackground));
RenderD7::Draw2::Text(pos + R7Vec2(5, 1), msg_lst[i]->title);
RenderD7::Draw2::Text(pos + R7Vec2(5, 17), msg_lst[i]->message);
if (rd7_debugging)
RenderD7::Draw2::Text(pos + R7Vec2(155, 1),
std::to_string(msg_lst[i]->animationframe));
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::UndoColorEdit(RD7Color_MessageBackground);
// Why Frameadd? because Message uses int as frame and
// It seems that lower 0.5 will be rounded to 0
// Why not replace int with float ?
// cause of buggy positions (seen in Flappy Bird 3ds for example)
float frameadd = 60.f * RenderD7::GetDeltaTime();
// 60fps animation * delta to not slowdown
// Oh and fix for Startup lol
// Todo: Only do this on AppStart
if (msg_lst[i]->animationframe == 0) {
msg_lst[i]->animationframe += 1;
} else {
msg_lst[i]->animationframe += (frameadd < 1.f ? 1.f : frameadd);
}
if (msg_lst[i]->animationframe > anim_len) {
msg_lst.erase(msg_lst.begin() + i);
}
}
}
// ReReverse ?? lol
// Cause otherwise the Toasts will swap
std::reverse(msg_lst.begin(), msg_lst.end());
}
void PushMessage(const Message &msg) {
msg_lst.push_back(std::make_shared<RenderD7::Message>(msg));
}
void SetMessageIdleStartFrame(int frame) { idles = frame; }
void SetMessageTotalAnimationFrames(int total_frames) {
anim_len = total_frames;
}
void SetMessageFadeOutStartFrame(int frame) { fade_outs = frame; }
} // namespace RenderD7

View File

@ -1,71 +0,0 @@
#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>
#include <fstream>
RenderD7::NFontApi::NFontApi() {}
RenderD7::NFontApi::~NFontApi() {}
void RenderD7::NFontApi::LoadTTF(std::string path) {
/////READ FILE
unsigned char *buffer;
long size = 0;
std::fstream ttf__(path, std::ios::in | std::ios::binary);
if(!ttf__.is_open()) {
return; // Add Error Handler in future
}
ttf__.seekg(0, std::ios::end);
size = ttf__.tellg();
ttf__.seekg(0, std::ios::beg);
buffer = (unsigned char *)malloc(size);
ttf__.read(reinterpret_cast<char*>(buffer), size);
ttf__.close();
/////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;
}

View File

@ -1,11 +0,0 @@
#include <renderd7/FunctionTrace.hpp>
#include <renderd7/Ovarlays.hpp>
#include <renderd7/renderd7.hpp>
namespace RenderD7 {
Ovl_Ftrace::Ovl_Ftrace() {}
void Ovl_Ftrace::Draw(void) const { RenderD7::OnScreen(Top); }
void Ovl_Ftrace::Logic() {}
} // namespace RenderD7

448
source/Overlays.cpp Normal file
View File

@ -0,0 +1,448 @@
#include <renderd7/DrawV2.hpp>
#include <renderd7/FunctionTrace.hpp>
#include <renderd7/Hid.hpp>
#include <renderd7/Overlays.hpp>
#include <renderd7/internal_db.hpp>
#include <renderd7/renderd7.hpp>
///////////////////////////////
struct Key {
std::string disp;
R7Vec2 pos;
R7Vec2 size;
// 0 = default key
// 1 = Shift
// 2 = Backsp
// 3 = Enter
// 4 = Cancel
// 5 = Confirm
// 6 = Tab
// 7 = Caps
// 8 = Space
int action = 0;
};
std::vector<Key> keyboard_layout = {
// 1st row
{"`", R7Vec2(5, 137), R7Vec2(18, 18), 0},
{"1", R7Vec2(25, 137), R7Vec2(18, 18), 0},
{"2", R7Vec2(45, 137), R7Vec2(18, 18), 0},
{"3", R7Vec2(65, 137), R7Vec2(18, 18), 0},
{"4", R7Vec2(85, 137), R7Vec2(18, 18), 0},
{"5", R7Vec2(105, 137), R7Vec2(18, 18), 0},
{"6", R7Vec2(125, 137), R7Vec2(18, 18), 0},
{"7", R7Vec2(145, 137), R7Vec2(18, 18), 0},
{"8", R7Vec2(165, 137), R7Vec2(18, 18), 0},
{"9", R7Vec2(185, 137), R7Vec2(18, 18), 0},
{"0", R7Vec2(205, 137), R7Vec2(18, 18), 0},
{"-", R7Vec2(225, 137), R7Vec2(18, 18), 0},
{"=", R7Vec2(245, 137), R7Vec2(18, 18), 0},
{"Bksp", R7Vec2(265, 137), R7Vec2(50, 18), 2},
// 2nd row
{"Tab", R7Vec2(5, 157), R7Vec2(40, 18), 6},
{"q", R7Vec2(47, 157), R7Vec2(18, 18), 0},
{"w", R7Vec2(67, 157), R7Vec2(18, 18), 0},
{"e", R7Vec2(87, 157), R7Vec2(18, 18), 0},
{"r", R7Vec2(107, 157), R7Vec2(18, 18), 0},
{"t", R7Vec2(127, 157), R7Vec2(18, 18), 0},
{"y", R7Vec2(147, 157), R7Vec2(18, 18), 0},
{"u", R7Vec2(167, 157), R7Vec2(18, 18), 0},
{"i", R7Vec2(187, 157), R7Vec2(18, 18), 0},
{"o", R7Vec2(207, 157), R7Vec2(18, 18), 0},
{"p", R7Vec2(227, 157), R7Vec2(18, 18), 0},
{"[", R7Vec2(247, 157), R7Vec2(18, 18), 0},
{"]", R7Vec2(267, 157), R7Vec2(18, 18), 0},
{"\\", R7Vec2(287, 157), R7Vec2(28, 18), 0},
// 3rd row
{"Caps", R7Vec2(5, 177), R7Vec2(50, 18), 7},
{"a", R7Vec2(57, 177), R7Vec2(18, 18), 0},
{"s", R7Vec2(77, 177), R7Vec2(18, 18), 0},
{"d", R7Vec2(97, 177), R7Vec2(18, 18), 0},
{"f", R7Vec2(117, 177), R7Vec2(18, 18), 0},
{"g", R7Vec2(137, 177), R7Vec2(18, 18), 0},
{"h", R7Vec2(157, 177), R7Vec2(18, 18), 0},
{"j", R7Vec2(177, 177), R7Vec2(18, 18), 0},
{"k", R7Vec2(197, 177), R7Vec2(18, 18), 0},
{"l", R7Vec2(217, 177), R7Vec2(18, 18), 0},
{";", R7Vec2(237, 177), R7Vec2(18, 18), 0},
{"'", R7Vec2(257, 177), R7Vec2(18, 18), 0},
{"Enter", R7Vec2(277, 177), R7Vec2(38, 18), 3},
// 4th row
{"Shift", R7Vec2(5, 197), R7Vec2(60, 18), 1},
{"z", R7Vec2(67, 197), R7Vec2(18, 18), 0},
{"x", R7Vec2(87, 197), R7Vec2(18, 18), 0},
{"c", R7Vec2(107, 197), R7Vec2(18, 18), 0},
{"v", R7Vec2(127, 197), R7Vec2(18, 18), 0},
{"b", R7Vec2(147, 197), R7Vec2(18, 18), 0},
{"n", R7Vec2(167, 197), R7Vec2(18, 18), 0},
{"m", R7Vec2(187, 197), R7Vec2(18, 18), 0},
{",", R7Vec2(207, 197), R7Vec2(18, 18), 0},
{".", R7Vec2(227, 197), R7Vec2(18, 18), 0},
{"/", R7Vec2(247, 197), R7Vec2(18, 18), 0},
{"Shift", R7Vec2(267, 197), R7Vec2(48, 18), 1},
// 5th row
{"Cancel", R7Vec2(5, 217), R7Vec2(70, 18), 4},
{"(X)", R7Vec2(77, 217), R7Vec2(23, 18), 10},
{"Space", R7Vec2(102, 217), R7Vec2(108, 18), 8},
{"(!)", R7Vec2(212, 217), R7Vec2(23, 18), 10},
{"Confirm", R7Vec2(237, 217), R7Vec2(78, 18), 5},
/*{"←", R7Vec2(237, 217), R7Vec2(18, 18)},
{"→", R7Vec2(257, 217), R7Vec2(18, 18)},
{"↓", R7Vec2(277, 217), R7Vec2(18, 18)},
{"↑", R7Vec2(297, 217), R7Vec2(18, 18)},*/
};
std::vector<Key> keyboard_layout_caps = {
// 1st row
{"`", R7Vec2(5, 137), R7Vec2(18, 18), 0},
{"1", R7Vec2(25, 137), R7Vec2(18, 18), 0},
{"2", R7Vec2(45, 137), R7Vec2(18, 18), 0},
{"3", R7Vec2(65, 137), R7Vec2(18, 18), 0},
{"4", R7Vec2(85, 137), R7Vec2(18, 18), 0},
{"5", R7Vec2(105, 137), R7Vec2(18, 18), 0},
{"6", R7Vec2(125, 137), R7Vec2(18, 18), 0},
{"7", R7Vec2(145, 137), R7Vec2(18, 18), 0},
{"8", R7Vec2(165, 137), R7Vec2(18, 18), 0},
{"9", R7Vec2(185, 137), R7Vec2(18, 18), 0},
{"0", R7Vec2(205, 137), R7Vec2(18, 18), 0},
{"-", R7Vec2(225, 137), R7Vec2(18, 18), 0},
{"=", R7Vec2(245, 137), R7Vec2(18, 18), 0},
{"Bksp", R7Vec2(265, 137), R7Vec2(50, 18), 2},
// 2nd row
{"Tab", R7Vec2(5, 157), R7Vec2(40, 18), 6},
{"Q", R7Vec2(47, 157), R7Vec2(18, 18), 0},
{"W", R7Vec2(67, 157), R7Vec2(18, 18), 0},
{"E", R7Vec2(87, 157), R7Vec2(18, 18), 0},
{"R", R7Vec2(107, 157), R7Vec2(18, 18), 0},
{"T", R7Vec2(127, 157), R7Vec2(18, 18), 0},
{"Y", R7Vec2(147, 157), R7Vec2(18, 18), 0},
{"U", R7Vec2(167, 157), R7Vec2(18, 18), 0},
{"I", R7Vec2(187, 157), R7Vec2(18, 18), 0},
{"O", R7Vec2(207, 157), R7Vec2(18, 18), 0},
{"P", R7Vec2(227, 157), R7Vec2(18, 18), 0},
{"[", R7Vec2(247, 157), R7Vec2(18, 18), 0},
{"]", R7Vec2(267, 157), R7Vec2(18, 18), 0},
{"\\", R7Vec2(287, 157), R7Vec2(28, 18), 0},
// 3rd row
{"Caps", R7Vec2(5, 177), R7Vec2(50, 18), 7},
{"A", R7Vec2(57, 177), R7Vec2(18, 18), 0},
{"S", R7Vec2(77, 177), R7Vec2(18, 18), 0},
{"D", R7Vec2(97, 177), R7Vec2(18, 18), 0},
{"F", R7Vec2(117, 177), R7Vec2(18, 18), 0},
{"G", R7Vec2(137, 177), R7Vec2(18, 18), 0},
{"H", R7Vec2(157, 177), R7Vec2(18, 18), 0},
{"J", R7Vec2(177, 177), R7Vec2(18, 18), 0},
{"K", R7Vec2(197, 177), R7Vec2(18, 18), 0},
{"L", R7Vec2(217, 177), R7Vec2(18, 18), 0},
{";", R7Vec2(237, 177), R7Vec2(18, 18), 0},
{"'", R7Vec2(257, 177), R7Vec2(18, 18), 0},
{"Enter", R7Vec2(277, 177), R7Vec2(38, 18), 3},
// 4th row
{"Shift", R7Vec2(5, 197), R7Vec2(60, 18), 1},
{"Z", R7Vec2(67, 197), R7Vec2(18, 18), 0},
{"X", R7Vec2(87, 197), R7Vec2(18, 18), 0},
{"C", R7Vec2(107, 197), R7Vec2(18, 18), 0},
{"V", R7Vec2(127, 197), R7Vec2(18, 18), 0},
{"B", R7Vec2(147, 197), R7Vec2(18, 18), 0},
{"N", R7Vec2(167, 197), R7Vec2(18, 18), 0},
{"M", R7Vec2(187, 197), R7Vec2(18, 18), 0},
{",", R7Vec2(207, 197), R7Vec2(18, 18), 0},
{".", R7Vec2(227, 197), R7Vec2(18, 18), 0},
{"/", R7Vec2(247, 197), R7Vec2(18, 18), 0},
{"Shift", R7Vec2(267, 197), R7Vec2(48, 18), 1},
// 5th row
{"Cancel", R7Vec2(5, 217), R7Vec2(70, 18), 4},
{"(X)", R7Vec2(77, 217), R7Vec2(23, 18), 10},
{"Space", R7Vec2(102, 217), R7Vec2(108, 18), 8},
{"(!)", R7Vec2(212, 217), R7Vec2(23, 18), 10},
{"Confirm", R7Vec2(237, 217), R7Vec2(78, 18), 5},
/*{"←", R7Vec2(237, 217), R7Vec2(18, 18)},
{"→", R7Vec2(257, 217), R7Vec2(18, 18)},
{"↑", R7Vec2(277, 217), R7Vec2(18, 18)},
{"↓", R7Vec2(297, 217), R7Vec2(18, 18)},*/
};
std::vector<Key> keyboard_layout_shift = {
// 1st row
{"~", R7Vec2(5, 137), R7Vec2(18, 18), 0},
{"!", R7Vec2(25, 137), R7Vec2(18, 18), 0},
{"@", R7Vec2(45, 137), R7Vec2(18, 18), 0},
{"#", R7Vec2(65, 137), R7Vec2(18, 18), 0},
{"$", R7Vec2(85, 137), R7Vec2(18, 18), 0},
{"%", R7Vec2(105, 137), R7Vec2(18, 18), 0},
{"^", R7Vec2(125, 137), R7Vec2(18, 18), 0},
{"&", R7Vec2(145, 137), R7Vec2(18, 18), 0},
{"*", R7Vec2(165, 137), R7Vec2(18, 18), 0},
{"(", R7Vec2(185, 137), R7Vec2(18, 18), 0},
{")", R7Vec2(205, 137), R7Vec2(18, 18), 0},
{"_", R7Vec2(225, 137), R7Vec2(18, 18), 0},
{"+", R7Vec2(245, 137), R7Vec2(18, 18), 0},
{"Bksp", R7Vec2(265, 137), R7Vec2(50, 18), 2},
// 2nd row
{"Tab", R7Vec2(5, 157), R7Vec2(40, 18), 6},
{"Q", R7Vec2(47, 157), R7Vec2(18, 18), 0},
{"W", R7Vec2(67, 157), R7Vec2(18, 18), 0},
{"E", R7Vec2(87, 157), R7Vec2(18, 18), 0},
{"R", R7Vec2(107, 157), R7Vec2(18, 18), 0},
{"T", R7Vec2(127, 157), R7Vec2(18, 18), 0},
{"Y", R7Vec2(147, 157), R7Vec2(18, 18), 0},
{"U", R7Vec2(167, 157), R7Vec2(18, 18), 0},
{"I", R7Vec2(187, 157), R7Vec2(18, 18), 0},
{"O", R7Vec2(207, 157), R7Vec2(18, 18), 0},
{"P", R7Vec2(227, 157), R7Vec2(18, 18), 0},
{"{", R7Vec2(247, 157), R7Vec2(18, 18), 0},
{"}", R7Vec2(267, 157), R7Vec2(18, 18), 0},
{"|", R7Vec2(287, 157), R7Vec2(28, 18), 0},
// 3rd row
{"Caps", R7Vec2(5, 177), R7Vec2(50, 18), 7},
{"A", R7Vec2(57, 177), R7Vec2(18, 18), 0},
{"S", R7Vec2(77, 177), R7Vec2(18, 18), 0},
{"D", R7Vec2(97, 177), R7Vec2(18, 18), 0},
{"F", R7Vec2(117, 177), R7Vec2(18, 18), 0},
{"G", R7Vec2(137, 177), R7Vec2(18, 18), 0},
{"H", R7Vec2(157, 177), R7Vec2(18, 18), 0},
{"J", R7Vec2(177, 177), R7Vec2(18, 18), 0},
{"K", R7Vec2(197, 177), R7Vec2(18, 18), 0},
{"L", R7Vec2(217, 177), R7Vec2(18, 18), 0},
{":", R7Vec2(237, 177), R7Vec2(18, 18), 0},
{"\"", R7Vec2(257, 177), R7Vec2(18, 18), 0},
{"Enter", R7Vec2(277, 177), R7Vec2(38, 18), 3},
// 4th row
{"Shift", R7Vec2(5, 197), R7Vec2(60, 18), 1},
{"Z", R7Vec2(67, 197), R7Vec2(18, 18), 0},
{"X", R7Vec2(87, 197), R7Vec2(18, 18), 0},
{"C", R7Vec2(107, 197), R7Vec2(18, 18), 0},
{"V", R7Vec2(127, 197), R7Vec2(18, 18), 0},
{"B", R7Vec2(147, 197), R7Vec2(18, 18), 0},
{"N", R7Vec2(167, 197), R7Vec2(18, 18), 0},
{"M", R7Vec2(187, 197), R7Vec2(18, 18), 0},
{"<", R7Vec2(207, 197), R7Vec2(18, 18), 0},
{">", R7Vec2(227, 197), R7Vec2(18, 18), 0},
{"?", R7Vec2(247, 197), R7Vec2(18, 18), 0},
{"Shift", R7Vec2(267, 197), R7Vec2(48, 18), 1},
// 5th row
{"Cancel", R7Vec2(5, 217), R7Vec2(70, 18), 4},
{"(X)", R7Vec2(77, 217), R7Vec2(23, 18), 10},
{"Space", R7Vec2(102, 217), R7Vec2(108, 18), 8},
{"(!)", R7Vec2(212, 217), R7Vec2(23, 18), 10},
{"Confirm", R7Vec2(237, 217), R7Vec2(78, 18), 5},
/*{"←", R7Vec2(237, 217), R7Vec2(18, 18)},
{"→", R7Vec2(257, 217), R7Vec2(18, 18)},
{"↑", R7Vec2(277, 217), R7Vec2(18, 18)},
{"↓", R7Vec2(297, 217), R7Vec2(18, 18)},*/
};
// From UI7
bool UI7_InBox(R7Vec2 inpos, R7Vec2 boxpos, R7Vec2 boxsize) {
if ((inpos.x > boxpos.x) && (inpos.y > boxpos.y) &&
(inpos.x < boxpos.x + boxsize.x) && (inpos.y < boxpos.y + boxsize.y))
return true;
return false;
}
namespace RenderD7 {
Ovl_Ftrace::Ovl_Ftrace(bool* is_enabled) { i_is_enabled = is_enabled; }
void Ovl_Ftrace::Draw(void) const {
RenderD7::OnScreen(Top);
RenderD7::Draw2::RFS(R7Vec2(0, 0), R7Vec2(400, 20),
RenderD7::StyleColor(RD7Color_Background));
std::vector<RenderD7::Ftrace::FTRes> dt;
for (auto const& it : RenderD7::Ftrace::rd7_traces)
if (it.second.is_ovl && dt.size() < 10) dt.push_back(it.second);
for (size_t i = 0; i < (dt.size() < 10 ? dt.size() : 10); i++) {
RenderD7::Draw2::Text(R7Vec2(5, 30 + i * 15), dt[i].func_name);
RenderD7::Draw2::Text(R7Vec2(295, 30 + i * 15),
RenderD7::MsTimeFmt(dt[i].time_of));
}
}
void Ovl_Ftrace::Logic() {
if (!i_is_enabled[0]) this->Kill();
}
Ovl_Metrik::Ovl_Metrik(bool* is_enabled, bool* screen, uint32_t* mt_color,
uint32_t* txt_color, float* txt_size) {
i_is_enabled = is_enabled;
i_screen = screen;
i_mt_color = mt_color;
i_txt_color = txt_color;
i_txt_size = txt_size;
}
void Ovl_Metrik::Draw(void) const {
if (i_screen[0]) {
RenderD7::OnScreen(Bottom);
} else {
RenderD7::OnScreen(Top);
}
std::string info =
"RenderD7 " + std::string(RENDERD7VSTRING) + " Debug Overlay";
float dim_y = RenderD7::GetTextDimensions(info).y;
float infoy = 240 - dim_y;
mt_fps = "FPS: " + RenderD7::GetFramerate();
if (rd7i_idb_running) mt_fps += " IDB -> ON";
mt_cpu = "CPU: " +
std::to_string(C3D_GetProcessingTime() * (RenderD7::GetFps() / 10))
.substr(0, 4) +
"%/" + std::to_string(C3D_GetProcessingTime()).substr(0, 4) + "ms";
mt_gpu = "GPU: " +
std::to_string(C3D_GetDrawingTime() * (RenderD7::GetFps() / 10))
.substr(0, 4) +
"%/" + std::to_string(C3D_GetDrawingTime()).substr(0, 4) + "ms";
mt_cmd =
"CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) +
"%";
mt_lfr = "Linear: " + RenderD7::FormatBytes(linearSpaceFree());
mt_tbs =
"TextBuf: " + std::to_string(C2D_TextBufGetNumGlyphs(rd7i_text_buffer)) +
"/4096";
RenderD7::Draw2::RFS(R7Vec2(0, 0), RenderD7::GetTextDimensions(mt_fps),
i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, 50), RenderD7::GetTextDimensions(mt_cpu),
i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, 50 + dim_y * 1),
RenderD7::GetTextDimensions(mt_gpu), i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, 50 + dim_y * 2),
RenderD7::GetTextDimensions(mt_cmd), i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, 50 + dim_y * 3),
RenderD7::GetTextDimensions(mt_lfr), i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, 50 + dim_y * 4),
RenderD7::GetTextDimensions(mt_tbs), i_mt_color[0]);
RenderD7::Draw2::RFS(R7Vec2(0, infoy), RenderD7::GetTextDimensions(info),
i_mt_color[0]);
RenderD7::CustomizeColor(RD7Color_Text, i_txt_color[0]);
RenderD7::Draw2::Text(R7Vec2(0, 0), mt_fps);
RenderD7::Draw2::Text(R7Vec2(0, 50), mt_cpu);
RenderD7::Draw2::Text(R7Vec2(0, 50 + dim_y * 1), mt_gpu);
RenderD7::Draw2::Text(R7Vec2(0, 50 + dim_y * 2), mt_cmd);
RenderD7::Draw2::Text(R7Vec2(0, 50 + dim_y * 3), mt_lfr);
RenderD7::Draw2::Text(R7Vec2(0, 50 + dim_y * 4), mt_tbs);
RenderD7::Draw2::Text(R7Vec2(0, infoy), info);
RenderD7::UndoColorEdit(RD7Color_Text);
// Force Bottom (Debug Touchpos)
RenderD7::OnScreen(Bottom);
if (Hid::IsEvent("touch", Hid::Held)) {
RenderD7::Draw2::Line(R7Vec2(Hid::GetTouchPosition().x, 0),
R7Vec2(Hid::GetTouchPosition().x, 240),
RenderD7::Color::Hex("#ff0000"));
RenderD7::Draw2::Line(R7Vec2(0, Hid::GetTouchPosition().y),
R7Vec2(320, Hid::GetTouchPosition().y),
RenderD7::Color::Hex("#ff0000"));
}
}
void Ovl_Metrik::Logic() {
if (!i_is_enabled[0]) this->Kill();
}
Ovl_Keyboard::Ovl_Keyboard(std::string& ref, const std::string& hint,
RD7Keyboard type) {
// Blocks All Input outside of Keyboard
// Doesnt work for Hidkeys down etc
RenderD7::Hid::Lock();
typed_text = &ref;
str_bak = ref;
ft3 = 0;
}
Ovl_Keyboard::~Ovl_Keyboard() {
// And Unlock when closing Keyboard lol
RenderD7::Hid::Unlock();
}
void Ovl_Keyboard::Draw(void) const {
if (ft3 > 5) RenderD7::Hid::Unlock();
auto key_table = keyboard_layout;
if (mode == 1)
key_table = keyboard_layout_caps;
else if (mode == 2)
key_table = keyboard_layout_shift;
RenderD7::OnScreen(Top);
RenderD7::Draw2::RFS(
R7Vec2(0, 0), R7Vec2(400, 240),
RenderD7::Color::RGBA(RD7Color_FrameBg).changeA(150).toRGBA());
RenderD7::OnScreen(Bottom);
RenderD7::Draw2::RFS(
R7Vec2(0, 0), R7Vec2(320, 112),
RenderD7::Color::RGBA(RD7Color_FrameBg).changeA(150).toRGBA());
RenderD7::Draw2::RFS(R7Vec2(0, 112), R7Vec2(320, 128),
RenderD7::StyleColor(RD7Color_FrameBg));
RenderD7::Draw2::RFS(R7Vec2(0, 112), R7Vec2(320, 20),
RenderD7::StyleColor(RD7Color_Header));
RenderD7::TextColorByBg(RD7Color_Header);
RenderD7::Draw2::Text(R7Vec2(5, 114), "> " + *typed_text);
RenderD7::UndoColorEdit(RD7Color_Text);
for (auto const& it : key_table) {
R7Vec2 txtdim = RenderD7::GetTextDimensions(it.disp);
R7Vec2 txtpos = R7Vec2(it.pos.x + it.size.x * 0.5 - txtdim.x * 0.5,
it.pos.y + it.size.y * 0.5 - txtdim.y * 0.5);
RD7Color btn = RD7Color_Button;
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
UI7_InBox(RenderD7::Hid::GetLastTouchPosition(), it.pos, it.size)) {
if (mode == 2) // Request Disable Shift
shared_data[0x02] = 1;
if (it.action == 0)
shared_data[0x01] = it.disp[0];
else if (it.action == 1)
shared_data[0x02] = 1;
else if (it.action == 2)
shared_data[0x03] = 1;
else if (it.action == 3)
shared_data[0x04] = 1;
else if (it.action == 4)
shared_data[0x05] = 1;
else if (it.action == 5)
shared_data[0x06] = 1;
else if (it.action == 6)
shared_data[0x07] = 1;
else if (it.action == 7)
shared_data[0x08] = 1;
else if (it.action == 8)
shared_data[0x09] = 1;
} else if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Held) &&
UI7_InBox(RenderD7::Hid::GetTouchPosition(), it.pos, it.size)) {
btn = RD7Color_ButtonHovered;
}
RenderD7::Draw2::RFS(it.pos, it.size, RenderD7::StyleColor(btn));
RenderD7::TextColorByBg(btn);
RenderD7::Draw2::Text(txtpos, it.disp);
RenderD7::UndoColorEdit(RD7Color_Text);
}
if (ft3 > 5) RenderD7::Hid::Lock();
}
void Ovl_Keyboard::Logic() {
ft3++;
for (const auto& it : shared_data) {
if (it.first == 0x01) {
typed_text->push_back(it.second);
} else if (it.first == 0x02) {
// Shift
mode = (mode == 2) ? 0 : 2;
} else if (it.first == 0x03) {
if (typed_text->length() >= 1)
typed_text->erase(typed_text->begin() + typed_text->length() - 1);
} else if (it.first == 0x04) {
// Enter
} else if (it.first == 0x05) {
*typed_text = str_bak;
this->Kill();
} else if (it.first == 0x06) {
this->Kill();
} else if (it.first == 0x07) {
// this->typed_text += '\t'; // Tab
} else if (it.first == 0x08) {
// Caps
mode = (mode == 1) ? 0 : 1;
} else if (it.first == 0x09) {
typed_text->append(" "); // Space
}
}
shared_data.clear();
}
} // namespace RenderD7

View File

@ -1,422 +1,461 @@
#include <map>
#include <renderd7/ResultDecoder.hpp>
#include <sstream>
static std::map<int, std::string> modules = {
{0, "common"},
{1, "kernel"},
{2, "util"},
{3, "file server"},
{4, "loader server"},
{5, "tcb"},
{6, "os"},
{7, "dbg"},
{8, "dmnt"},
{9, "pdn"},
{10, "gsp"},
{11, "i2c"},
{12, "gpio"},
{13, "dd"},
{14, "codec"},
{15, "spi"},
{16, "pxi"},
{17, "fs"},
{18, "di"},
{19, "hid"},
{20, "cam"},
{21, "pi"},
{22, "pm"},
{23, "pm_low"},
{24, "fsi"},
{25, "srv"},
{26, "ndm"},
{27, "nwm"},
{28, "soc"},
{29, "ldr"},
{30, "acc"},
{31, "romfs"},
{32, "am"},
{33, "hio"},
{34, "updater"},
{35, "mic"},
{36, "fnd"},
{37, "mp"},
{38, "mpwl"},
{39, "ac"},
{40, "http"},
{41, "dsp"},
{42, "snd"},
{43, "dlp"},
{44, "hio_low"},
{45, "csnd"},
{46, "ssl"},
{47, "am_low"},
{48, "nex"},
{49, "friends"},
{50, "rdt"},
{51, "applet"},
{52, "nim"},
{53, "ptm"},
{54, "midi"},
{55, "mc"},
{56, "swc"},
{57, "fatfs"},
{58, "ngc"},
{59, "card"},
{60, "cardnor"},
{61, "sdmc"},
{62, "boss"},
{63, "dbm"},
{64, "config"},
{65, "ps"},
{66, "cec"},
{67, "ir"},
{68, "uds"},
{69, "pl"},
{70, "cup"},
{71, "gyroscope"},
{72, "mcu"},
{73, "ns"},
{74, "news"},
{75, "ro"},
{76, "gd"},
{77, "card spi"},
{78, "ec"},
{79, "web browser"},
{80, "test"},
{81, "enc"},
{82, "pia"},
{83, "act"},
{84, "vctl"},
{85, "olv"},
{86, "neia"},
{87, "npns"},
{90, "avd"},
{91, "l2b"},
{92, "mvd"},
{93, "nfc"},
{94, "uart"},
{95, "spm"},
{96, "qtm"},
{97, "nfp"},
{254, "application"},
};
static std::map<int, std::string> levels = {
{0, "Success"}, {1, "Info"}, {25, "Status"},
{26, "Temporary"}, {27, "Permanent"}, {28, "Usage"},
{29, "Reinitialize"}, {30, "Reset"}, {31, "Fatal"},
};
static std::map<int, std::string> summaries = {
{0, "Success"},
{1, "Nothing happened"},
{2, "Would block"},
{3, "Out of resource"},
{4, "Not found"},
{5, "Invalid state"},
{6, "Not supported"},
{7, "Invalid argument"},
{8, "Wrong argument"},
{9, "Canceled"},
{10, "Status changed"},
{11, "Internal"},
{63, "Invalid result value"},
};
static std::map<int, std::string> desccommon = {
{0, "Success"},
{1000, "Invalid selection"},
{1001, "Too large"},
{1002, "Not authorized"},
{1003, "Already done"},
{1004, "Invalid size"},
{1005, "Invalid enum value"},
{1006, "Invalid combination"},
{1007, "No data"},
{1008, "Busy"},
{1009, "Misaligned address"},
{1010, "Misaligned size"},
{1011, "Out of memory"},
{1012, "Not implemented"},
{1013, "Invalid address"},
{1014, "Invalid pointer"},
{1015, "Invalid handle"},
{1016, "Not initialized"},
{1017, "Already initialized"},
{1018, "Not found"},
{1019, "Cancel requested"},
{1020, "Already exists"},
{1021, "Out of range"},
{1022, "Timeout"},
{1023, "Invalid result value"},
};
static std::map<int, std::string> desckernel = {
{2, "Invalid memory permissions."},
};
static std::map<int, std::string> descos = {
{10, "Not enough memory."},
{26, "Session closed by remote."},
{47, "Invalid command header."},
};
// Need to Fix The Range based Values
static std::map<int, std::string> descfs = {
{101, "Archive not mounted or mount-point not found."},
{120, "Title or object not found."},
{141, "Gamecard not inserted."},
{230, "Invalid open flags or permissions."},
{391, "NCCH hash check failed."},
{302, "RSA or AES-MAC verification failed."},
{395, "RomFS or Savedata hash check failed."},
{630, "Command not allowed, or missing permissions."},
{702, "Invalid path."},
{761, "Incorrect ExeFS read size."},
{100, "[Media] not found."},
{180, "Exists already."},
{200, "Not enough space."},
{220, "Invalidated archive."},
{230, "Unacceptable or write protected."},
{340, "0x01"},
{360, "Bad format."},
{390, "Verification failure."},
{400, "0x01"},
{600, "Out of resources."},
{630, "Access denied."},
{661, "0x01"},
{700, "Invalid argument."},
{730, "Not initialized."},
{750, "Already initialized."},
{760, "Not supported."},
{780, "0x01"},
};
static std::map<int, std::string> descsrv = {
{5, "Invalid string length (service name length is zero or longer than 8 "
"chars)."},
{6, "Access to service denied (requested a service the application does "
"not have access to)."},
{7, "String size does not match contents (service name contains unexpected "
"null byte)."},
};
static std::map<int, std::string> descnwm = {
{2, "This error usually indicates the wifi chipset in the console is dying "
"or dead."},
};
static std::map<int, std::string> descam = {
{4, "Invalid ticket version."},
{32, "Empty CIA."},
{37, "Invalid NCCH."},
{39, "Invalid title version."},
{43, "Database doesn\"t exist, or it failed to open."},
{44, "Trying to uninstall system-app."},
{106, "Invalid signature/CIA. Usually happens when developer UNITINFO is "
"enabled in Luma3DS."},
{393, "Invalid database."},
};
static std::map<int, std::string> deschttp = {
{105, "Request timed out."},
};
static std::map<int, std::string> descnim = {
{1, "Invalid string IPC paramater (non null terminated at its indicated "
"length)."},
{12, "Invalid country code returned by CFG module reading config save "
"0xB0000."},
{13, "Zero string length console serial number or '000000000000000' "
"returned by CFG's SecureInfoGetSerialNo."},
{18, "General data reading error of NIM's .dat files from its system save, "
"bad data or bad data lengths."},
{22, "General invalid data or length of data returned from nintendo "
"servers. (Only applicable for some operations)"},
{25, "IntegrityVerificationSeed is waiting on servers to be synced into "
"console. Can't processed with online services without sync being "
"completed first over IPC request."},
{26, "Unavailable/unaccessable IntegrityVerificationSeed on Nintendo "
"servers. May happen if NIM is told to import "
"IntegrityVerificationSeed from servers at any time other than after "
"the successful System Transfer reboot."},
{27, "Invalid country language code returned by CFG module reading config "
"save 0xA0002."},
{37, "Service is in Standby Mode. (eShop ban? General service is down? "
"This caused by a server response flag on account information. "
"Account is not referring to NNID.)"},
{39, "HTTP Status non 200. (Only applicable for some operations)"},
{40, "General XML read/write error while processing Auto Delivery XMLs."},
{41, "General XML read/write error while processing Auto Delivery XMLs. "
"(Stubbed virtual call was called)"},
{58,
"Invalid NPNS token returned by CFG module reading config save 0xF0006."},
{67, "HTTP Status 404 while trying to download a game's seed."},
{68, "HTTP Status 503 while trying to download a game's seed."},
};
static std::map<int, std::string> descmvd = {
{271, "Invalid configuration."},
};
static std::map<int, std::string> descqtm = {
{8, "Camera is already in use or busy."},
};
// Need to Fix The Range based Values
static std::map<int, std::string> descapplication = {
{0, "The application raised an error. Please consult the application's "
"source code or ask the author for assistance with it."},
{1024, "0x01"},
};
namespace RenderD7 {
void ResultDecoder::Load(Result rescode) { this->m_rescode = rescode; }
void ResultDecoder::Load(std::string rescode) {
std::stringstream ss;
ss << rescode;
ss >> std::hex >> this->m_rescode;
}
std::string RenderD7::ResultDecoder::GetCode() {
std::stringstream ss;
ss << std::hex << m_rescode;
std::string reshex(ss.str());
return reshex;
}
std::string ResultDecoder::GetLevel() {
std::string res = levels.at(this->GetLevelInt()) + " (" +
std::to_string(this->GetLevelInt()) + ")";
return res;
}
int ResultDecoder::GetLevelInt() { return R_LEVEL(m_rescode); }
std::string ResultDecoder::GetModule() {
std::string res = modules.at(this->GetModuleInt()) + " (" +
std::to_string(this->GetModuleInt()) + ")";
return res;
}
int ResultDecoder::GetModuleInt() { return R_MODULE(m_rescode); }
std::string ResultDecoder::GetDescription() {
std::string res = "Desc Not Implemented!";
switch (this->GetModuleInt()) {
case 0:
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
break;
case 1:
if ((desckernel.find(this->GetDescriptionInt()) == desckernel.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = desckernel.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 6:
if ((descos.find(this->GetDescriptionInt()) == descos.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descos.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 17:
if ((descfs.find(this->GetDescriptionInt()) == descfs.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descfs.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 25:
if ((descsrv.find(this->GetDescriptionInt()) == descsrv.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descsrv.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 27:
if ((descnwm.find(this->GetDescriptionInt()) == descnwm.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descnwm.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 32:
if ((descam.find(this->GetDescriptionInt()) == descam.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descam.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 40:
if ((deschttp.find(this->GetDescriptionInt()) == deschttp.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = deschttp.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 52:
if ((descnim.find(this->GetDescriptionInt()) == descnim.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descnim.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 92:
if ((descmvd.find(this->GetDescriptionInt()) == descmvd.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descmvd.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 96:
if ((descqtm.find(this->GetDescriptionInt()) == descqtm.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descqtm.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 254:
if ((descapplication.find(this->GetDescriptionInt()) ==
descapplication.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descapplication.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
default:
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
break;
}
return res;
}
int ResultDecoder::GetDescriptionInt() { return R_DESCRIPTION(m_rescode); }
std::string ResultDecoder::GetSummary() {
std::string res = summaries.at(this->GetSummaryInt()) + " (" +
std::to_string(this->GetSummaryInt()) + ")";
return res;
}
int ResultDecoder::GetSummaryInt() { return R_SUMMARY(m_rescode); }
} // namespace RenderD7
#include <filesystem>
#include <fstream>
#include <map>
#include <renderd7/ResultDecoder.hpp>
#include <sstream>
extern std::string D_app_name;
static std::map<int, std::string> modules = {
{0, "common"},
{1, "kernel"},
{2, "util"},
{3, "file server"},
{4, "loader server"},
{5, "tcb"},
{6, "os"},
{7, "dbg"},
{8, "dmnt"},
{9, "pdn"},
{10, "gsp"},
{11, "i2c"},
{12, "gpio"},
{13, "dd"},
{14, "codec"},
{15, "spi"},
{16, "pxi"},
{17, "fs"},
{18, "di"},
{19, "hid"},
{20, "cam"},
{21, "pi"},
{22, "pm"},
{23, "pm_low"},
{24, "fsi"},
{25, "srv"},
{26, "ndm"},
{27, "nwm"},
{28, "soc"},
{29, "ldr"},
{30, "acc"},
{31, "romfs"},
{32, "am"},
{33, "hio"},
{34, "updater"},
{35, "mic"},
{36, "fnd"},
{37, "mp"},
{38, "mpwl"},
{39, "ac"},
{40, "http"},
{41, "dsp"},
{42, "snd"},
{43, "dlp"},
{44, "hio_low"},
{45, "csnd"},
{46, "ssl"},
{47, "am_low"},
{48, "nex"},
{49, "friends"},
{50, "rdt"},
{51, "applet"},
{52, "nim"},
{53, "ptm"},
{54, "midi"},
{55, "mc"},
{56, "swc"},
{57, "fatfs"},
{58, "ngc"},
{59, "card"},
{60, "cardnor"},
{61, "sdmc"},
{62, "boss"},
{63, "dbm"},
{64, "config"},
{65, "ps"},
{66, "cec"},
{67, "ir"},
{68, "uds"},
{69, "pl"},
{70, "cup"},
{71, "gyroscope"},
{72, "mcu"},
{73, "ns"},
{74, "news"},
{75, "ro"},
{76, "gd"},
{77, "card spi"},
{78, "ec"},
{79, "web browser"},
{80, "test"},
{81, "enc"},
{82, "pia"},
{83, "act"},
{84, "vctl"},
{85, "olv"},
{86, "neia"},
{87, "npns"},
{90, "avd"},
{91, "l2b"},
{92, "mvd"},
{93, "nfc"},
{94, "uart"},
{95, "spm"},
{96, "qtm"},
{97, "nfp"},
{254, "application"},
};
static std::map<int, std::string> levels = {
{0, "Success"}, {1, "Info"}, {25, "Status"},
{26, "Temporary"}, {27, "Permanent"}, {28, "Usage"},
{29, "Reinitialize"}, {30, "Reset"}, {31, "Fatal"},
};
static std::map<int, std::string> summaries = {
{0, "Success"},
{1, "Nothing happened"},
{2, "Would block"},
{3, "Out of resource"},
{4, "Not found"},
{5, "Invalid state"},
{6, "Not supported"},
{7, "Invalid argument"},
{8, "Wrong argument"},
{9, "Canceled"},
{10, "Status changed"},
{11, "Internal"},
{63, "Invalid result value"},
};
static std::map<int, std::string> desccommon = {
{0, "Success"},
{1000, "Invalid selection"},
{1001, "Too large"},
{1002, "Not authorized"},
{1003, "Already done"},
{1004, "Invalid size"},
{1005, "Invalid enum value"},
{1006, "Invalid combination"},
{1007, "No data"},
{1008, "Busy"},
{1009, "Misaligned address"},
{1010, "Misaligned size"},
{1011, "Out of memory"},
{1012, "Not implemented"},
{1013, "Invalid address"},
{1014, "Invalid pointer"},
{1015, "Invalid handle"},
{1016, "Not initialized"},
{1017, "Already initialized"},
{1018, "Not found"},
{1019, "Cancel requested"},
{1020, "Already exists"},
{1021, "Out of range"},
{1022, "Timeout"},
{1023, "Invalid result value"},
};
static std::map<int, std::string> desckernel = {
{2, "Invalid memory permissions."},
};
static std::map<int, std::string> descos = {
{10, "Not enough memory."},
{26, "Session closed by remote."},
{47, "Invalid command header."},
};
// Need to Fix The Range based Values
static std::map<int, std::string> descfs = {
{101, "Archive not mounted or mount-point not found."},
{120, "Title or object not found."},
{141, "Gamecard not inserted."},
{230, "Invalid open flags or permissions."},
{391, "NCCH hash check failed."},
{302, "RSA or AES-MAC verification failed."},
{395, "RomFS or Savedata hash check failed."},
{630, "Command not allowed, or missing permissions."},
{702, "Invalid path."},
{761, "Incorrect ExeFS read size."},
{100, "[Media] not found."},
{180, "Exists already."},
{200, "Not enough space."},
{220, "Invalidated archive."},
{230, "Unacceptable or write protected."},
{340, "0x01"},
{360, "Bad format."},
{390, "Verification failure."},
{400, "0x01"},
{600, "Out of resources."},
{630, "Access denied."},
{661, "0x01"},
{700, "Invalid argument."},
{730, "Not initialized."},
{750, "Already initialized."},
{760, "Not supported."},
{780, "0x01"},
};
static std::map<int, std::string> descsrv = {
{5,
"Invalid string length (service name length is zero or longer than 8 "
"chars)."},
{6,
"Access to service denied (requested a service the application does "
"not have access to)."},
{7,
"String size does not match contents (service name contains unexpected "
"null byte)."},
};
static std::map<int, std::string> descnwm = {
{2,
"This error usually indicates the wifi chipset in the console is dying "
"or dead."},
};
static std::map<int, std::string> descam = {
{4, "Invalid ticket version."},
{32, "Empty CIA."},
{37, "Invalid NCCH."},
{39, "Invalid title version."},
{43, "Database doesn\"t exist, or it failed to open."},
{44, "Trying to uninstall system-app."},
{106,
"Invalid signature/CIA. Usually happens when developer UNITINFO is "
"enabled in Luma3DS."},
{393, "Invalid database."},
};
static std::map<int, std::string> deschttp = {
{105, "Request timed out."},
};
static std::map<int, std::string> descnim = {
{1,
"Invalid string IPC paramater (non null terminated at its indicated "
"length)."},
{12,
"Invalid country code returned by CFG module reading config save "
"0xB0000."},
{13,
"Zero string length console serial number or '000000000000000' "
"returned by CFG's SecureInfoGetSerialNo."},
{18,
"General data reading error of NIM's .dat files from its system save, "
"bad data or bad data lengths."},
{22,
"General invalid data or length of data returned from nintendo "
"servers. (Only applicable for some operations)"},
{25,
"IntegrityVerificationSeed is waiting on servers to be synced into "
"console. Can't processed with online services without sync being "
"completed first over IPC request."},
{26,
"Unavailable/unaccessable IntegrityVerificationSeed on Nintendo "
"servers. May happen if NIM is told to import "
"IntegrityVerificationSeed from servers at any time other than after "
"the successful System Transfer reboot."},
{27,
"Invalid country language code returned by CFG module reading config "
"save 0xA0002."},
{37,
"Service is in Standby Mode. (eShop ban? General service is down? "
"This caused by a server response flag on account information. "
"Account is not referring to NNID.)"},
{39, "HTTP Status non 200. (Only applicable for some operations)"},
{40, "General XML read/write error while processing Auto Delivery XMLs."},
{41,
"General XML read/write error while processing Auto Delivery XMLs. "
"(Stubbed virtual call was called)"},
{58,
"Invalid NPNS token returned by CFG module reading config save 0xF0006."},
{67, "HTTP Status 404 while trying to download a game's seed."},
{68, "HTTP Status 503 while trying to download a game's seed."},
};
static std::map<int, std::string> descmvd = {
{271, "Invalid configuration."},
};
static std::map<int, std::string> descqtm = {
{8, "Camera is already in use or busy."},
};
// Need to Fix The Range based Values
static std::map<int, std::string> descapplication = {
{0,
"The application raised an error. Please consult the application's "
"source code or ask the author for assistance with it."},
{1024, "0x01"},
};
namespace RenderD7 {
void ResultDecoder::Load(Result rescode) { this->m_rescode = rescode; }
void ResultDecoder::Load(std::string rescode) {
std::stringstream ss;
ss << rescode;
ss >> std::hex >> this->m_rescode;
}
std::string RenderD7::ResultDecoder::GetCode() {
std::stringstream ss;
ss << std::hex << m_rescode;
std::string reshex(ss.str());
return reshex;
}
std::string ResultDecoder::GetLevel() {
std::string res = levels.at(this->GetLevelInt()) + " (" +
std::to_string(this->GetLevelInt()) + ")";
return res;
}
int ResultDecoder::GetLevelInt() { return R_LEVEL(m_rescode); }
std::string ResultDecoder::GetModule() {
std::string res = modules.at(this->GetModuleInt()) + " (" +
std::to_string(this->GetModuleInt()) + ")";
return res;
}
int ResultDecoder::GetModuleInt() { return R_MODULE(m_rescode); }
std::string ResultDecoder::GetDescription() {
std::string res = "Desc Not Implemented!";
switch (this->GetModuleInt()) {
case 0:
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
break;
case 1:
if ((desckernel.find(this->GetDescriptionInt()) == desckernel.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = desckernel.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 6:
if ((descos.find(this->GetDescriptionInt()) == descos.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descos.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 17:
if ((descfs.find(this->GetDescriptionInt()) == descfs.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descfs.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 25:
if ((descsrv.find(this->GetDescriptionInt()) == descsrv.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descsrv.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 27:
if ((descnwm.find(this->GetDescriptionInt()) == descnwm.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descnwm.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 32:
if ((descam.find(this->GetDescriptionInt()) == descam.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descam.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 40:
if ((deschttp.find(this->GetDescriptionInt()) == deschttp.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = deschttp.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 52:
if ((descnim.find(this->GetDescriptionInt()) == descnim.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descnim.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 92:
if ((descmvd.find(this->GetDescriptionInt()) == descmvd.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descmvd.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 96:
if ((descqtm.find(this->GetDescriptionInt()) == descqtm.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descqtm.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
case 254:
if ((descapplication.find(this->GetDescriptionInt()) ==
descapplication.end())) {
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
} else {
res = descapplication.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
}
break;
default:
res = desccommon.at(this->GetDescriptionInt()) + " (" +
std::to_string(this->GetDescriptionInt()) + ")";
break;
}
return res;
}
int ResultDecoder::GetDescriptionInt() { return R_DESCRIPTION(m_rescode); }
std::string ResultDecoder::GetSummary() {
std::string res = summaries.at(this->GetSummaryInt()) + " (" +
std::to_string(this->GetSummaryInt()) + ")";
return res;
}
void RenderD7::ResultDecoder::WriteLog() {
std::string out_path = "sdmc:/RenderD7/Apps/" + D_app_name + "/resdec/";
std::filesystem::create_directories(out_path);
out_path += "/err_result_" + std::to_string(time(0)) + ".log";
std::ofstream out(out_path, std::ios::app);
out << "+-------------------\n";
out << "| Error: " << GetCode() << "\n";
out << "+-------------------\n";
out << "| Module: " << GetModule() << "\n";
out << "+-------------------\n";
out << "| Level: " << GetLevel() << "\n";
out << "+-------------------\n";
out << "| Summary: " << GetSummary() << "\n";
out << "+-------------------\n";
out << "| Description: " << GetDescription() << "\n";
out << "+-------------------\n";
out.close();
}
int ResultDecoder::GetSummaryInt() { return R_SUMMARY(m_rescode); }
} // namespace RenderD7

View File

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

View File

@ -1,61 +1,51 @@
#include <renderd7/Security.hpp>
#include <3ds.h>
#include <stdio.h>
#include <stdlib.h>
RenderD7::Security *rd7_security;
extern bool running;
bool *running_addr = NULL;
struct SecurityReport {
uint32_t addr;
std::string initialisized_at;
bool success;
};
std::vector<SecurityReport> rd7_security_reports;
RenderD7::Security::Level RenderD7::Security::GetLevel() {
return RenderD7::Security::Level::FULL;
}
void RenderD7::Security::SetLevel(RenderD7::Security::Level level) {}
void RenderD7::Security::Report(uint32_t addr, void *result_ptr) {
// Create Report
}
namespace RenderD7 {
Security::Security() { running_addr = &running; }
Security::~Security() { *running_addr = false; }
void Security::SafeExit(void (*exit_func)()) { atexit(exit_func); }
void Security::SafeInit(void (*init_func)(), void (*exit_func)()) {
init_func();
atexit(exit_func);
}
void Security::SafeInit(Result (*init_func)(), void (*exit_func)()) {
init_func();
atexit(exit_func);
}
void Security::SafeInit(void (*init_func)(), Result (*exit_func)()) {
init_func();
atexit(reinterpret_cast<void (*)()>(exit_func));
}
void Security::SafeInit(Result (*init_func)(), Result (*exit_func)()) {
init_func();
atexit(reinterpret_cast<void (*)()>(exit_func));
}
} // namespace RenderD7
namespace RenderD7 {
namespace Init {
void Security() {
rd7_security = new RenderD7::Security(); // Load and Init the Security System
}
} // namespace Init
} // namespace RenderD7
#include <3ds.h>
#include <stdio.h>
#include <stdlib.h>
#include <renderd7/Security.hpp>
#include <renderd7/internal_db.hpp>
RenderD7::Security *rd7_security;
bool *running_addr = NULL;
RenderD7::Security::Level rd7i_slvl = RenderD7::Security::Level::NONE;
RenderD7::Security::Level RenderD7::Security::GetLevel() { return rd7i_slvl; }
void RenderD7::Security::SetLevel(RenderD7::Security::Level level) {
rd7i_slvl = level;
}
namespace RenderD7 {
Security::Security() { running_addr = &rd7i_running; }
Security::~Security() { *running_addr = false; }
void Security::SafeExit(void (*exit_func)()) { atexit(exit_func); }
void Security::SafeInit(void (*init_func)(), void (*exit_func)()) {
init_func();
atexit(exit_func);
}
void Security::SafeInit(Result (*init_func)(), void (*exit_func)()) {
init_func();
atexit(exit_func);
}
void Security::SafeInit(void (*init_func)(), Result (*exit_func)()) {
init_func();
atexit(reinterpret_cast<void (*)()>(exit_func));
}
void Security::SafeInit(Result (*init_func)(), Result (*exit_func)()) {
init_func();
atexit(reinterpret_cast<void (*)()>(exit_func));
}
} // namespace RenderD7
namespace RenderD7 {
namespace Init {
void Security() {
rd7_security = new RenderD7::Security(); // Load and Init the Security System
}
} // namespace Init
} // namespace RenderD7

View File

@ -1,15 +1,11 @@
#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); }
#include <renderd7/Sheet.hpp>
Result RenderD7::Sheet::Load(const std::string& path) {
this->spritesheet = C2D_SpriteSheetLoad(path.c_str());
return 0;
}
void RenderD7::Sheet::Free() {
C2D_SpriteSheetFree(this->spritesheet);
this->spritesheet = nullptr;
}

View File

@ -1,36 +1,34 @@
#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::getHeight() { 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);
#include <renderd7/Sprite.hpp>
void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index) {
C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index);
}
bool RenderD7::Sprite::Draw() {
// Patch Depth before draw
sprite.params.depth = 0.5;
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::getHeight() { 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->get());
}
void RenderD7::Sprite::SetScale(float x, float y) {
C2D_SpriteScale(&this->sprite, x, y);
}

View File

@ -1,38 +1,38 @@
#include <renderd7/SpriteAnimation.hpp>
#include <renderd7/log.hpp>
extern Log renderd7log;
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() {
//
}
RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation() {
//
}
void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet,
size_t imagecount, size_t startimage,
float frame_begin,
float frame_finish) {
D_totaltime = frame_begin;
this->images = imagecount;
this->sheet = sheet;
this->time = frame_finish;
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();
#include <renderd7/SpriteAnimation.hpp>
#include <renderd7/log.hpp>
extern Log renderd7log;
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() {
//
}
RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation() {
//
}
void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet,
size_t imagecount, size_t startimage,
float frame_begin,
float frame_finish) {
D_totaltime = frame_begin;
this->images = imagecount;
this->sheet = sheet;
this->time = frame_finish;
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,24 +1,24 @@
#include <iostream>
#include <renderd7/StealConsole.hpp>
namespace RenderD7 {
StealConsole::StealConsole() {
std::streambuf *old = std::cout.rdbuf(this->stolen_stdout.rdbuf());
if (old) {
// To prevent from unused error
}
}
StealConsole::~StealConsole() {
// Do Nothing Here
}
std::string StealConsole::GetStdout() {
if (this->stolen_stdout.str().length() < 400) {
return this->stolen_stdout.str();
} else {
return this->stolen_stdout.str().substr(stolen_stdout.str().length() - 400);
}
return "";
}
} // namespace RenderD7
#include <iostream>
#include <renderd7/StealConsole.hpp>
namespace RenderD7 {
StealConsole::StealConsole() {
std::streambuf *old = std::cout.rdbuf(this->stolen_stdout.rdbuf());
if (old) {
// To prevent from unused error
}
}
StealConsole::~StealConsole() {
// Do Nothing Here
}
std::string StealConsole::GetStdout() {
if (this->stolen_stdout.str().length() < 400) {
return this->stolen_stdout.str();
} else {
return this->stolen_stdout.str().substr(stolen_stdout.str().length() - 400);
}
return "";
}
} // namespace RenderD7

View File

@ -1,22 +1,22 @@
#include <renderd7/Tasks.hpp>
#include <3ds.h>
#include <stdio.h>
#include <string.h>
static std::vector<Thread> threads;
void RenderD7::Tasks::create(ThreadFunc entrypoint) {
s32 prio = 0;
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
Thread thread = threadCreate((ThreadFunc)entrypoint, NULL, 64 * 1024,
prio - 1, -2, false);
threads.push_back(thread);
}
void RenderD7::Tasks::destroy(void) {
for (u32 i = 0; i < threads.size(); i++) {
threadJoin(threads.at(i), U64_MAX);
threadFree(threads.at(i));
}
#include <3ds.h>
#include <stdio.h>
#include <string.h>
#include <renderd7/Tasks.hpp>
static std::vector<Thread> threads;
void RenderD7::Tasks::create(ThreadFunc entrypoint) {
s32 prio = 0;
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
Thread thread = threadCreate((ThreadFunc)entrypoint, NULL, 64 * 1024,
prio - 1, -2, false);
threads.push_back(thread);
}
void RenderD7::Tasks::destroy(void) {
for (u32 i = 0; i < threads.size(); i++) {
threadJoin(threads.at(i), U64_MAX);
threadFree(threads.at(i));
}
}

View File

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

31
source/Timer.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <renderd7/Timer.hpp>
// Ticks per MSEC
#define TPMS 268111.856
namespace RenderD7 {
Timer::Timer(bool autostart) {
if (autostart) is_running = true;
last = svcGetSystemTick();
current = last;
}
void Timer::reset() {
last = svcGetSystemTick();
current = last;
}
void Timer::tick() {
if (is_running) current = svcGetSystemTick();
}
void Timer::pause() { is_running = false; }
void Timer::resume() { is_running = true; }
bool Timer::running() { return is_running; }
float Timer::get() { return (float)((current - last) / TPMS); }
float Timer::get_live() { return (float)((svcGetSystemTick() - last) / TPMS); }
} // namespace RenderD7

View File

@ -1,93 +0,0 @@
#include <renderd7/Color.hpp>
#include <renderd7/Draw.hpp>
#include <renderd7/Screen.hpp>
#include <renderd7/ToastsV2.hpp>
#include <algorithm>
#include <memory>
#include <vector>
extern bool rd7_debugging;
std::vector<std::shared_ptr<RenderD7::Message>> msg_lst;
int fade_outs = 200; // Start of fadeout
int idles = 60; // start of Idle
int anim_len = 300; // Full Length of Animation
std::pair<int, int> MakePos(int frame, int entry) {
float fol = anim_len - fade_outs;
if (frame > fade_outs)
return std::make_pair(5, 240 - ((entry + 1) * 55) - 5 +
(float)((frame - fade_outs) / fol) * -20);
if (frame > idles)
return std::make_pair(5, 240 - ((entry + 1) * 55) - 5);
return std::make_pair(-150 + ((float)(frame / (float)idles) * 155),
240 - ((entry + 1) * 55) - 5);
}
namespace RenderD7 {
float GetDeltaTime(); // Extern from renderd7.cpp
void ProcessMessages() {
// Draw in ovl mode
RenderD7::OnScreen(Top);
float fol = anim_len - fade_outs;
std::reverse(msg_lst.begin(), msg_lst.end());
for (size_t i = 0; i < msg_lst.size(); i++) {
std::pair<int, int> pos = MakePos(msg_lst[i]->animationframe, i);
if ((pos.second + 150) < 0) {
// Dont Render Out of Screen
// And as thay aren't relevant anymore
// Thay get deleted!
msg_lst.erase(msg_lst.begin() + i);
} else {
int new_alpha = 200;
if (msg_lst[i]->animationframe > fade_outs) {
new_alpha =
200 - (float(msg_lst[i]->animationframe - fade_outs) / fol) * 200;
}
u32 txtcol = RenderD7::Color::Hex("#ffffff", new_alpha);
RenderD7::Draw::Rect(pos.first, pos.second, 150, 50,
RenderD7::Color::Hex("#333333", new_alpha));
RenderD7::Draw::Text(pos.first + 5, pos.second + 1, 0.4f, txtcol,
msg_lst[i]->title);
RenderD7::Draw::Text(pos.first + 5, pos.second + 17, 0.4f, txtcol,
msg_lst[i]->message);
if (rd7_debugging)
RenderD7::Draw::Text(pos.first + 160, pos.second + 1, 0.5f,
RenderD7::Color::Hex("#000000"),
std::to_string(msg_lst[i]->animationframe));
// Why Frameadd? because Message uses int as frame and
// It seems that lower 0.5 will be rounded to 0
// Why not replace int with float ?
// cause of buggy positions (seen in Flappy Bird 3ds for example)
float frameadd = 60.f * RenderD7::GetDeltaTime();
// 60fps animation * delta to not slowdown
// Oh and fix for Startup lol
// Todo: Only do this on AppStart
if (msg_lst[i]->animationframe == 0) {
msg_lst[i]->animationframe += 1;
} else {
msg_lst[i]->animationframe += (frameadd < 1.f ? 1.f : frameadd);
}
if (msg_lst[i]->animationframe > anim_len) {
msg_lst.erase(msg_lst.begin() + i);
}
}
}
// ReReverse ?? lol
// Cause otherwise the Toasts will swap
std::reverse(msg_lst.begin(), msg_lst.end());
}
void PushMessage(const Message &msg) {
msg_lst.push_back(std::make_shared<RenderD7::Message>(msg));
}
void SetIdleStartFrame(int frame) { idles = frame; }
void SetTotalAnimationFrames(int total_frames) { anim_len = total_frames; }
void SetFadeOutStartFrame(int frame) { fade_outs = frame; }
} // namespace RenderD7

489
source/UI7.cpp Normal file
View File

@ -0,0 +1,489 @@
#include <ctime>
#include <renderd7/Color.hpp>
#include <renderd7/DrawV2.hpp>
#include <renderd7/Hid.hpp>
#include <renderd7/Overlays.hpp>
#include <renderd7/UI7.hpp>
#include <renderd7/internal_db.hpp>
#include <unordered_map>
// As the 3ds doesn't support std::chrono
#ifdef __3DS__
/// @brief 3ds System Ticks per milli second
/// Already defined in FTrace ik but
/// I Want to make UI7 and Draw2 more
/// Independent of the main RenderD7 api
#define TICKS_PER_MSEC 268111.856
#include <3ds.h>
#define __get_time() svcGetSystemTick() / TICKS_PER_MSEC
#else
#include <chrono>
#define __get_time() \
std::chrono::duration_cast<std::chrono::milliseconds>( \
std::chrono::system_clock().now().time_since_epoch()) \
.count()
#endif
// Basement structs enums etc
struct UI7ID {
UI7ID(const std::string &id) {
real_id = id;
title = id;
if (id.substr(0, 2) == "##") {
title = "";
has_title = false;
}
// Ensure the id is lowercase
std::transform(real_id.begin(), real_id.end(), real_id.begin(),
[](unsigned char c) { return std::tolower(c); });
lt = time(0);
}
UI7ID() {
title = "";
real_id = "";
has_title = false;
lt = time(0);
}
std::string Title() {
lt = time(0);
return title;
}
std::string ID() {
lt = time(0);
return real_id;
}
bool operator==(const UI7ID &in) { return (real_id == in.real_id); }
bool operator!=(const UI7ID &in) { return !(*this == in); }
std::string title;
std::string real_id;
bool has_title;
int lt;
};
struct UI7_Ctx {
UI7_Ctx() {
delta = 0.0f;
time = 0.0f;
is_activated = false;
_last = 0;
cursor = R7Vec2();
slc = R7Vec2();
cbackup = R7Vec2();
in_menu = false;
current_menu = UI7ID("");
}
float delta;
float time;
bool is_activated;
unsigned long long _last;
R7Vec2 cursor;
R7Vec2 cbackup;
R7Vec2 slc;
bool in_menu;
UI7ID current_menu;
std::map<std::string, R7Vec2> grid_mapping;
std::unordered_map<std::string, UI7ID *> ids;
};
UI7_Ctx *ui7_ctx;
bool UI7CtxValidate() {
if (ui7_ctx == nullptr) return false;
if (!ui7_ctx->is_activated) return false;
return true;
}
bool UI7CtxInMenu() {
if (!UI7CtxValidate()) return false;
return ui7_ctx->in_menu;
}
bool UI7CtxBeginMenu(const std::string &lb) {
if (!UI7CtxValidate()) return false;
if (UI7CtxInMenu()) return false;
ui7_ctx->current_menu = UI7ID(lb);
ui7_ctx->in_menu = true;
return true;
}
void UI7CtxEndMenu() {
if (!UI7CtxValidate()) return;
if (!UI7CtxInMenu()) return;
ui7_ctx->current_menu = UI7ID("");
ui7_ctx->in_menu = false;
}
void UI7CtxCursorMove(R7Vec2 size) {
if (!UI7CtxValidate()) return;
if (!UI7CtxInMenu()) return;
ui7_ctx->slc = ui7_ctx->cursor + R7Vec2(5, 0);
ui7_ctx->cursor.x = 5;
ui7_ctx->cursor += R7Vec2(0, size.y + 5);
ui7_ctx->slc += R7Vec2(size.x, 0);
}
UI7ID *UI7CtxNewID(const std::string &i) {
std::string t = i;
std::transform(t.begin(), t.end(), t.begin(),
[](unsigned char c) { return std::tolower(c); });
if (ui7_ctx->ids.find(t) != ui7_ctx->ids.end()) {
return ui7_ctx->ids[t];
}
auto id = new UI7ID(i);
ui7_ctx->ids[id->real_id] = id;
return id;
}
void UI7CtxClearIDs() {
for (auto it = ui7_ctx->ids.begin(); it != ui7_ctx->ids.end();) {
if (it->second == nullptr) {
++it;
continue;
}
if (time(0) - it->second->lt > 5) {
delete it->second;
it = ui7_ctx->ids.erase(it);
continue;
}
++it;
}
}
int rd7i_ui7_ids_active() {
if (!UI7CtxValidate()) return 0;
return ui7_ctx->ids.size();
}
namespace UI7 {
bool InBox(R7Vec2 inpos, R7Vec2 boxpos, R7Vec2 boxsize) {
if ((inpos.x > boxpos.x) && (inpos.y > boxpos.y) &&
(inpos.x < boxpos.x + boxsize.x) && (inpos.y < boxpos.y + boxsize.y))
return true;
return false;
}
void Init() {
// If Context is valid it makes no sense to reinit lol
if (UI7CtxValidate()) return;
ui7_ctx = new UI7_Ctx;
ui7_ctx->delta = 0.0f;
ui7_ctx->time = 0.0f;
ui7_ctx->cursor = R7Vec2(0, 0);
ui7_ctx->is_activated = true;
}
void Deinit() {
// Dont deinit something not initialized
// Please dont count how often init... was
// written wront by me :(
if (!UI7CtxValidate()) return;
ui7_ctx->is_activated = false;
delete ui7_ctx;
}
void Update() {
// Dont do anithing without ctx;
if (!UI7CtxValidate()) return;
unsigned long long current = __get_time();
ui7_ctx->delta = (float)((float)current - (float)ui7_ctx->_last) / 1000.f;
ui7_ctx->_last = current;
ui7_ctx->time += ui7_ctx->delta;
ui7_ctx->cursor = R7Vec2();
UI7CtxClearIDs();
}
float GetTime() {
if (!UI7CtxValidate()) return 0;
return ui7_ctx->time;
}
float GetDeltaTime() {
if (!UI7CtxValidate()) return 0;
return ui7_ctx->delta;
}
bool Button(const std::string &label, R7Vec2 size) {
bool ret = false;
if (!UI7CtxValidate()) return ret;
R7Vec2 textdim = RenderD7::GetTextDimensions(label);
if (size.x == 0) {
size.x = textdim.x + 8;
}
if (size.y == 0) {
size.y = textdim.y + 4;
}
RD7Color btn = RD7Color_Button;
R7Vec2 pos = GetCursorPos();
UI7CtxCursorMove(size);
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, size)) {
btn = RD7Color_ButtonActive;
ret = true;
} else if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Held) &&
InBox(RenderD7::Hid::GetTouchPosition(), pos, size)) {
btn = RD7Color_ButtonHovered;
}
RenderD7::Draw2::RFS(pos, size, RenderD7::StyleColor(btn));
pos = R7Vec2(pos.x + size.x * 0.5f - textdim.x * 0.5,
pos.y + size.y * 0.5f - textdim.y * 0.5);
RenderD7::TextColorByBg(btn);
RenderD7::Draw2::Text(pos, label);
RenderD7::UndoColorEdit(RD7Color_Text);
return ret;
}
void Checkbox(const std::string &label, bool &c) {
if (!UI7CtxValidate()) return;
R7Vec2 cbs = R7Vec2(18, 18);
R7Vec2 txtdim = RenderD7::GetTextDimensions(label);
R7Vec2 inp = cbs + R7Vec2(txtdim.x + 5, 0);
RD7Color bg = RD7Color_FrameBg;
R7Vec2 pos = GetCursorPos();
UI7CtxCursorMove(inp);
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, inp)) {
bg = RD7Color_FrameBgHovered;
c = !c;
} else if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Held) &&
InBox(RenderD7::Hid::GetTouchPosition(), pos, inp)) {
bg = RD7Color_FrameBgHovered;
}
RenderD7::Draw2::RFS(pos, cbs, RenderD7::StyleColor(bg));
if (c == true) {
RenderD7::Draw2::RFS(pos + R7Vec2(2, 2), cbs - R7Vec2(4, 4),
RenderD7::StyleColor(RD7Color_Checkmark));
}
RenderD7::Draw2::Text(pos + R7Vec2(cbs.x + 5, 1), label);
}
void Label(const std::string &label, RD7TextFlags flags) {
if (!UI7CtxValidate()) return;
R7Vec2 textdim = RenderD7::GetTextDimensions(label);
R7Vec2 pos = GetCursorPos();
// Remove some y offset cause texts have some offset
UI7CtxCursorMove(textdim - R7Vec2(0, 4));
RenderD7::TextColorByBg(
(pos.y + textdim.y < 20 ? RD7Color_Header : RD7Color_Background));
RenderD7::Draw2::Text(pos, label, flags);
RenderD7::UndoColorEdit(RD7Color_Text);
}
void Progressbar(float value) {
if (!UI7CtxValidate()) return;
R7Vec2 pos = GetCursorPos();
R7Vec2 size = R7Vec2((rd7i_current_screen ? 400 : 320) - (pos.x * 2), 20);
UI7CtxCursorMove(size);
RenderD7::Draw2::RFS(pos, size, RenderD7::StyleColor(RD7Color_FrameBg));
RenderD7::Draw2::RFS(pos + R7Vec2(2, 2), size - R7Vec2(4, 4),
RenderD7::StyleColor(RD7Color_FrameBgHovered));
if (!(value != value) && !(value < 0.0) && !(value > 1.0))
RenderD7::Draw2::RFS(pos + R7Vec2(2, 2),
R7Vec2((size.x - 4) * value, size.y - 4),
RenderD7::StyleColor(RD7Color_Progressbar));
}
void Image(RenderD7::Image *img) {
if (!UI7CtxValidate()) return;
R7Vec2 pos = GetCursorPos();
UI7CtxCursorMove(R7Vec2(img->get_size().x, img->get_size().y));
RenderD7::Draw2::Image(img, pos);
}
void BrowserList(const std::vector<std::string> &entrys, int &selection,
RD7TextFlags txtflags, R7Vec2 size, int max_entrys) {
if (!UI7CtxValidate()) return;
if (selection < 0) return;
R7Vec2 pos = GetCursorPos();
if (pos.y + 15 * max_entrys > 230) max_entrys = (int)((230 - pos.y) / 15);
if (size.x == 0) size.x = (rd7i_current_screen ? 400 : 320) - (pos.x * 2);
if (size.y == 0) size.y = (max_entrys * 15);
UI7CtxCursorMove(size);
for (int i = 0; i < max_entrys; i++) {
RenderD7::Draw2::RFS(
pos + R7Vec2(0, 15 * i), R7Vec2(size.x, 15),
RenderD7::StyleColor((i % 2) == 0 ? RD7Color_List0 : RD7Color_List1));
}
for (size_t i = 0;
i < ((entrys.size() < (size_t)max_entrys) ? entrys.size()
: (size_t)max_entrys);
i++) {
int selindex = (selection < max_entrys ? selection : (max_entrys - 1));
int list_index =
(selection < max_entrys ? i : (i + selection - (max_entrys - 1)));
if (i == (size_t)selindex) {
RenderD7::Draw2::RectFilled(
pos + R7Vec2(0, 15 * i), R7Vec2(size.x, 15),
{RenderD7::StyleColor(RD7Color_Selector),
RenderD7::Color::RGBA(RD7Color_Selector)
.fade_to(RD7Color_SelectorFade, std::sin(RenderD7::GetTime()))
.toRGBA(),
RenderD7::StyleColor(RD7Color_Selector),
RenderD7::Color::RGBA(RD7Color_Selector)
.fade_to(RD7Color_SelectorFade, std::sin(RenderD7::GetTime()))
.toRGBA()});
RenderD7::TextColorByBg(RD7Color_Selector);
RenderD7::TextMaxBox(R7Vec2(size.x, 0));
RenderD7::Draw2::Text(pos + R7Vec2(5, 15 * i), entrys[list_index],
txtflags | RD7TextFlags_Short);
RenderD7::TextDefaultBox();
RenderD7::UndoColorEdit(RD7Color_Text);
} else {
RenderD7::Ftrace::Beg("app", "short_algo");
RenderD7::TextColorByBg(RD7Color_List0);
RenderD7::TextMaxBox(R7Vec2(size.x, 0));
RenderD7::Draw2::Text(pos + R7Vec2(5, 15 * i), entrys[list_index],
txtflags | RD7TextFlags_Short);
RenderD7::TextDefaultBox();
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::Ftrace::End("app", "short_algo");
}
}
}
void InputText(const std::string &label, std::string &text,
const std::string &hint) {
if (!UI7CtxValidate()) return;
R7Vec2 cbs = R7Vec2(144, 18);
R7Vec2 txtdim = RenderD7::GetTextDimensions(label);
R7Vec2 inp = cbs + R7Vec2(txtdim.x + 5, 0);
RD7Color bg = RD7Color_FrameBg;
auto id = UI7CtxNewID(label);
R7Vec2 pos = GetCursorPos();
UI7CtxCursorMove(inp);
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, inp)) {
bg = RD7Color_FrameBgHovered;
RenderD7::AddOvl(std::make_unique<RenderD7::Ovl_Keyboard>(text, hint));
} else if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Held) &&
InBox(RenderD7::Hid::GetTouchPosition(), pos, inp)) {
bg = RD7Color_FrameBgHovered;
}
RenderD7::Draw2::RFS(pos, cbs, RenderD7::StyleColor(bg));
RenderD7::TextColorByBg(bg);
RenderD7::Draw2::Text(pos + R7Vec2(5, 1), (text != "" ? text : hint));
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::Draw2::Text(pos + R7Vec2(cbs.x + 5, 1), id->Title());
}
bool BeginMenu(const std::string &title, R7Vec2 size, UI7MenuFlags flags) {
if (!UI7CtxValidate()) return false;
auto id = UI7CtxNewID(title);
bool titlebar = true;
if (size.x == 0) {
size.x = rd7i_current_screen ? 400 : 320;
}
if (size.y == 0) {
size.y = 240;
}
RD7TextFlags txtflags = 0;
if (flags & UI7MenuFlags_NoTitlebar) titlebar = false;
if (flags & UI7MenuFlags_TitleMid) txtflags = RD7TextFlags_AlignMid;
RenderD7::Draw2::RFS(R7Vec2(0, 0), size,
RenderD7::StyleColor(RD7Color_Background));
if (titlebar) {
RenderD7::Draw2::RFS(R7Vec2(0, 0), R7Vec2(size.x, 20),
RenderD7::StyleColor(RD7Color_Header));
RenderD7::TextColorByBg(RD7Color_Header);
RenderD7::Draw2::Text(R7Vec2(5, 2), id->title, txtflags);
RenderD7::UndoColorEdit(RD7Color_Text);
}
SetCursorPos(R7Vec2(5, 25));
return UI7CtxBeginMenu(title);
}
void EndMenu() { UI7CtxEndMenu(); }
void Grid(const std::string &name, const R7Vec2 &size,
R7Vec2 (*display_func)(void *, R7Vec2), void **data_array,
size_t num_entrys) {
if (!UI7CtxValidate()) return;
if (num_entrys <= 0) return;
if (data_array == nullptr) return;
if (ui7_ctx->grid_mapping.find(UI7ID(name).real_id) ==
ui7_ctx->grid_mapping.end())
ui7_ctx->grid_mapping[UI7ID(name).real_id] =
R7Vec2(); // Register id not exist
R7Vec2 pos = GetCursorPos();
R7Vec2 cpos(pos);
// Debug Grid
RenderD7::Draw2::Rect(pos, size, RenderD7::Color::Hex("#ff0000"), 1);
// Y-Offset
int yoff = 0;
pos += ui7_ctx->grid_mapping[UI7ID(name).real_id];
for (size_t i = 0; i < num_entrys; i++) {
R7Vec2 szs = display_func(data_array[i], pos);
RenderD7::Draw2::Text(pos + R7Vec2(4, 4), std::to_string(i));
if (pos.x + (szs.x * 2) > (cpos.x + size.x) &&
pos.y + szs.y > cpos.y + size.y) {
if (ui7_ctx->grid_mapping[UI7ID(name).real_id].y == 0)
ui7_ctx->grid_mapping[UI7ID(name).real_id].y =
(cpos.y + size.y) / 2 - ((yoff + 1) * (szs.y + 4)) / 2;
break;
} else if (pos.x + (szs.x * 2) > (cpos.x + size.x)) {
if (ui7_ctx->grid_mapping[UI7ID(name).real_id].x == 0)
ui7_ctx->grid_mapping[UI7ID(name).real_id].x =
(cpos.x + size.x) / 2 - ((i + 1) * (szs.x + 4)) / 2;
pos = R7Vec2(5 + ui7_ctx->grid_mapping[UI7ID(name).real_id].x,
pos.y + szs.y + 4);
yoff++;
} else {
pos += R7Vec2(szs.x + 4, 0);
}
}
UI7CtxCursorMove(size);
}
bool BeginTree(const std::string& text) {
return false;
}
void EndTree() {
}
R7Vec2 GetCursorPos() {
if (!UI7CtxValidate()) return R7Vec2();
return ui7_ctx->cursor;
}
void SetCursorPos(R7Vec2 cp) {
if (!UI7CtxValidate()) return;
ui7_ctx->cbackup = ui7_ctx->cursor;
ui7_ctx->cursor = cp;
}
void RestoreCursor() {
if (!UI7CtxValidate()) return;
ui7_ctx->cursor = ui7_ctx->cbackup;
}
void SameLine() {
if (!UI7CtxValidate()) return;
ui7_ctx->cursor = ui7_ctx->slc;
}
} // namespace UI7

View File

@ -1,110 +0,0 @@
#include <renderd7/bmpconverter.hpp>
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) {
static const unsigned MINHEADER = 54; // minimum BMP header size
if (bmp.size() < MINHEADER)
return -1;
if (bmp[0] != 'B' || bmp[1] != 'M')
return 1; // It's not a BMP file if it doesn't start with marker 'BM'
unsigned pixeloffset = bmp[10] + 256 * bmp[11]; // where the pixel data starts
// read width and height from BMP header
w = bmp[18] + bmp[19] * 256;
h = bmp[22] + bmp[23] * 256;
// read number of channels from BMP header
if (bmp[28] != 24 && bmp[28] != 32)
return 2; // only 24-bit and 32-bit BMPs are supported.
unsigned numChannels = bmp[28] / 8;
// The amount of scanline bytes is width of image times channels, with extra
// bytes added if needed to make it a multiple of 4 bytes.
unsigned scanlineBytes = w * numChannels;
if (scanlineBytes % 4 != 0)
scanlineBytes = (scanlineBytes / 4) * 4 + 4;
unsigned dataSize = scanlineBytes * h;
if (bmp.size() < dataSize + pixeloffset)
return 3; // BMP file too small to contain all pixels
image.resize(w * h * 4);
/*
There are 3 differences between BMP and the raw image buffer for LodePNG:
-it's upside down
-it's in BGR instead of RGB format (or BRGA instead of RGBA)
-each scanline has padding bytes to make it a multiple of 4 if needed
The 2D for loop below does all these 3 conversions at once.
*/
for (unsigned y = 0; y < h; y++)
for (unsigned x = 0; x < w; x++) {
// pixel start byte position in the BMP
unsigned bmpos =
pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x;
// pixel start byte position in the new raw image
unsigned newpos = 4 * y * w + 4 * x;
if (numChannels == 3) {
image[newpos + 0] = bmp[bmpos + 2]; // R
image[newpos + 1] = bmp[bmpos + 1]; // G
image[newpos + 2] = bmp[bmpos + 0]; // B
image[newpos + 3] = 255; // A
} else {
image[newpos + 0] = bmp[bmpos + 2]; // R
image[newpos + 1] = bmp[bmpos + 1]; // G
image[newpos + 2] = bmp[bmpos + 0]; // B
image[newpos + 3] = bmp[bmpos + 3]; // A
}
}
return 0;
}
std::vector<unsigned char> ConvertFile(std::string filename) {
std::vector<unsigned char> bmp;
lodepng::load_file(bmp, filename);
std::vector<unsigned char> image;
unsigned w, h;
unsigned error = BitmapConverter::decodeBMP(image, w, h, bmp);
if (error) {
std::cout << "BMP decoding error " << error << std::endl;
}
std::vector<unsigned char> png;
error = lodepng::encode(png, image, w, h);
if (error) {
std::cout << "PNG encoding error " << error << ": "
<< lodepng_error_text(error) << std::endl;
}
return png;
}
std::vector<unsigned char> ConvertData(std::vector<unsigned char> data) {
std::vector<unsigned char> image;
unsigned w, h;
unsigned error = BitmapConverter::decodeBMP(image, w, h, data);
if (error) {
std::cout << "BMP decoding error " << error << std::endl;
}
std::vector<unsigned char> png;
error = lodepng::encode(png, image, w, h);
if (error) {
std::cout << "PNG encoding error " << error << ": "
<< lodepng_error_text(error) << std::endl;
}
return png;
}
} // namespace BitmapConverter

256
source/internal_db.cpp Normal file
View File

@ -0,0 +1,256 @@
#include <arpa/inet.h>
#include <errno.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <filesystem>
#include <renderd7/FileSystem.hpp>
#include <renderd7/external/json.hpp>
#include <renderd7/renderd7.hpp>
/// Base ///
static RenderD7::Thread rd7i_idb_server; // Protected
std::string rd7i_app_name;
std::string rd7i_config_path;
nlohmann::json rd7i_config;
u8 rd7i_console_model = 0;
u8 rd7i_system_region = CFG_REGION_USA;
bool rd7i_is_citra = false;
bool rd7i_settings = false;
R7Vec2 rd7i_hid_touch_pos;
C2D_TextBuf rd7i_text_buffer;
C2D_Font rd7i_base_font;
C2D_TextBuf rd7i_d2_dimbuf;
bool rd7i_is_ndsp = false;
bool rd7i_running = false;
std::stack<std::unique_ptr<RenderD7::Scene>> RenderD7::Scene::scenes;
std::unique_ptr<RenderD7::Scene> rd7i_fade_scene;
std::vector<std::unique_ptr<RenderD7::Ovl>> rd7i_overlays;
unsigned int rd7i_frames = 0;
u64 rd7i_last_time = 0;
float rd7i_framerate = 0.0f;
u32 rd7i_mt_color = 0xaa000000;
u32 rd7i_mt_txtcolor = 0xbbffffff;
bool rd7i_mt_screen;
float rd7i_mt_txtSize;
bool rd7i_metrikd = false;
bool rd7i_ftraced = false;
bool rd7i_current_screen = false;
u64 rd7i_delta_time;
u64 rd7i_last_tm;
float rd7i_dtm;
float rd7i_time;
bool rd7i_fadeout = false, rd7i_fadein = false, rd7i_fadeout2 = false,
rd7i_fadein2 = false;
int rd7i_fadealpha = 0;
int rd7i_fadecolor = 0;
bool rd7i_wait_fade = false;
bool rd7i_fade_exit = false;
bool rd7i_fade_scene_wait = false;
bool rd7i_idb_running = false;
bool rd7i_graphics_on = false;
float rd7_draw2_tsm = 1.2f;
bool rd7i_amdt = false;
/// Global ///
// Outdated HidApi (HidV2Patched)
u32 d7_hDown;
u32 d7_hHeld;
u32 d7_hUp;
u32 d7_hRepeat; // Inofficial lol
touchPosition d7_touch;
// Outdated Screens
C3D_RenderTarget *Top;
C3D_RenderTarget *TopRight;
C3D_RenderTarget *Bottom;
// Modern Global Api
int rd7_max_objects = C2D_DEFAULT_MAX_OBJECTS;
bool rd7_do_splash = false;
bool rd7_enable_scene_system = true;
bool rd7_debugging = false;
C3D_RenderTarget *rd7_top;
C3D_RenderTarget *rd7_top_right;
C3D_RenderTarget *rd7_bottom;
class Logger {
public:
Logger() = default;
virtual ~Logger() = default;
static void log(const std::string &prefix, const std::string &message) {
std::cout << "[" << prefix << "]: " << message << std::endl;
}
};
#define rd7_err(x) Logger::log("ERROR", x)
#define rd7_wrn(x) Logger::log("WARNING", x)
class tcp_server {
public:
tcp_server(const std::string &ip, int port) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
rd7_err("Unable to create socket!");
return;
}
server.sin_family = AF_INET;
server.sin_port = port;
server.sin_addr.s_addr = inet_addr(ip.c_str());
e = bind(sockfd, (struct sockaddr *)&server, sizeof(server));
if (e == -1) {
rd7_err("Unable to bind!");
return;
}
e = listen(sockfd, 10);
if (e == 0) {
printf("[+]Listening...\n");
} else {
rd7_err("Error in Binding");
return;
}
addr_size = sizeof(new_addr);
new_sock = accept(sockfd, (struct sockaddr *)&new_addr, &addr_size);
std::cout << "Connected" << std::endl;
}
~tcp_server() {
// Nothing here
}
bool reconnect() {
close(new_sock);
new_sock = accept(sockfd, (struct sockaddr *)&new_addr, &addr_size);
return true;
}
size_t snd(void *ptr, size_t size) { return send(new_sock, ptr, size, 0); }
size_t rec(void *ptr, size_t size) { return recv(new_sock, ptr, size, 0); }
private:
int e, sockfd, new_sock;
struct sockaddr_in server, new_addr;
socklen_t addr_size;
};
#define stupid(x) &x, sizeof(x)
#define rd7i_reacttion(x) \
({ \
int code = x; \
server.snd(stupid(code)); \
})
struct pak32 {
pak32() {}
pak32(const std::string &n0, float n1, unsigned char n2, unsigned char n3,
bool n4, bool n5, bool n6, float n7, float n8, float n9, float n10,
unsigned int n11, unsigned int n12, unsigned int n13,
unsigned int n14) {
magic = 0x44772277;
for (int i = 0; i < 64; i++) app_name[i] = (char)0;
int l = n0.length();
if (l > 64) l = 64;
for (int i = 0; i < l; i++) app_name[i] = n0[i];
framerate = n1;
console_model = n2;
system_region = n3;
is_citra = n4;
ndsp_support = n5;
in_settings = n6;
deltatime = n7;
rtime = n8;
cpu = n9;
gpu = n10;
mem_alloc = n11;
mem_dalloc = n12;
mem_ialloc = n13;
tbs = n14;
}
uint32_t magic;
char app_name[64];
float framerate;
unsigned char console_model;
unsigned char system_region;
bool is_citra;
bool ndsp_support;
bool in_settings;
float deltatime;
float rtime;
float cpu;
float gpu;
unsigned int mem_alloc;
unsigned int mem_dalloc;
unsigned int mem_ialloc;
unsigned int tbs;
};
#define SOC_ALIGN 0x1000
#define SOC_BUFFERSIZE 0x100000
static u32 *SOC_buffer = NULL;
static bool rd7i_idb_fp = false;
void KillIdbServer() {
rd7i_idb_fp = true;
socExit();
}
void ServerThread(RenderD7::Parameter param) {
Result ret;
SOC_buffer = (u32 *)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
if (SOC_buffer == NULL) {
return;
}
// Now intialise soc:u service
if ((ret = socInit(SOC_buffer, SOC_BUFFERSIZE)) != 0) {
return;
}
rd7i_idb_running = true;
rd7_security->SafeExit(KillIdbServer);
tcp_server server("0.0.0.0", 4727);
int cmd = 0;
while (true && !rd7i_idb_fp) {
size_t r = server.rec(&cmd, sizeof(int));
if (r == 0) {
server.reconnect();
}
if (cmd == 1) {
rd7i_reacttion(1);
auto pak = pak32(
rd7i_app_name, rd7i_framerate, rd7i_console_model, rd7i_system_region,
rd7i_is_citra, rd7i_is_ndsp, rd7i_settings, rd7i_dtm, rd7i_time,
C3D_GetProcessingTime(), C3D_GetDrawingTime(),
RenderD7::Memory::GetTotalAllocated(),
RenderD7::Memory::GetTotalFreed(), RenderD7::Memory::GetCurrent(),
C2D_TextBufGetNumGlyphs(rd7i_text_buffer));
server.snd(stupid(pak));
} else if (cmd == 2) {
rd7i_reacttion(2);
std::vector<RenderD7::FileSystem::Entry> el =
RenderD7::FileSystem::GetDirContent("sdmc:/");
size_t buf = el.size() * sizeof(RenderD7::FileSystem::Entry);
server.snd(stupid(buf));
server.snd(el.data(), buf);
} else if (cmd == 3) {
rd7i_reacttion(3);
RenderD7::ExitApp();
} else {
rd7i_reacttion(1234);
}
}
rd7i_idb_running = false;
}
void IdbServer() {
rd7i_idb_server.initialize(ServerThread);
rd7i_idb_server.start(true);
}

View File

@ -1,98 +1,95 @@
#include <3ds.h>
#include <renderd7/lang.hpp>
#include <fstream>
#include <filesystem>
static nlohmann::json appJson;
std::string RenderD7::Lang::getSys() {
u8 language = 1;
CFGU_GetSystemLanguage(&language);
switch (language) {
case 0:
return "jp"; // Japanese
break;
case 1:
return "en"; // English
break;
case 2:
return "fr"; // French
break;
case 3:
return "de"; // German
break;
case 4:
return "it"; // Italian
break;
case 5:
return "es"; // Spanish
break;
case 6:
return "zh-CN"; // Chinese (Simplified)
break;
// case 7:
// return "ko"; // Korean
// break;
// case 8:
// return "nl"; // Dutch
// break;
case 9:
return "pt"; // Portuguese
break;
case 10:
return "ru"; // Russian
break;
case 11:
return "zh-TW"; // Chinese (Traditional)
break;
default:
return "en"; // Fall back to English if missing
break;
}
}
std::string RenderD7::Lang::get(const std::string &key) {
if (!appJson.contains(key))
return key;
return appJson.at(key).get<std::string>();
}
void RenderD7::Lang::load(const std::string &lang) {
std::fstream values;
if(std::filesystem::is_character_file("romfs:/lang/" + lang + "/app.json")) {
values.open("romfs:/lang/" + lang + "/app.json", std::ios::in);
if(values.is_open()) {
appJson = nlohmann::json::parse(values);
}
values.close();
if(appJson.is_discarded()) {
appJson = {};
}
return;
} else {
values.open("romfs:/lang/en/app.json", std::ios::in);
if(values.is_open()) {
appJson = nlohmann::json::parse(values);
}
values.close();
if(appJson.is_discarded()) {
appJson = {};
}
return;
}
#include <3ds.h>
#include <filesystem>
#include <fstream>
#include <renderd7/lang.hpp>
static nlohmann::json appJson;
std::string RenderD7::Lang::getSys() {
u8 language = 1;
CFGU_GetSystemLanguage(&language);
switch (language) {
case 0:
return "jp"; // Japanese
break;
case 1:
return "en"; // English
break;
case 2:
return "fr"; // French
break;
case 3:
return "de"; // German
break;
case 4:
return "it"; // Italian
break;
case 5:
return "es"; // Spanish
break;
case 6:
return "zh-CN"; // Chinese (Simplified)
break;
// case 7:
// return "ko"; // Korean
// break;
// case 8:
// return "nl"; // Dutch
// break;
case 9:
return "pt"; // Portuguese
break;
case 10:
return "ru"; // Russian
break;
case 11:
return "zh-TW"; // Chinese (Traditional)
break;
default:
return "en"; // Fall back to English if missing
break;
}
}
std::string RenderD7::Lang::get(const std::string &key) {
if (!appJson.contains(key)) return key;
return appJson.at(key).get<std::string>();
}
void RenderD7::Lang::load(const std::string &lang) {
std::fstream values;
if (std::filesystem::is_character_file("romfs:/lang/" + lang + "/app.json")) {
values.open("romfs:/lang/" + lang + "/app.json", std::ios::in);
if (values.is_open()) {
appJson = nlohmann::json::parse(values);
}
values.close();
if (appJson.is_discarded()) {
appJson = {};
}
return;
} else {
values.open("romfs:/lang/en/app.json", std::ios::in);
if (values.is_open()) {
appJson = nlohmann::json::parse(values);
}
values.close();
if (appJson.is_discarded()) {
appJson = {};
}
return;
}
}

View File

@ -1,34 +0,0 @@
; Project Li7
; Copyright (C) 2023 NPI-D7
; Projection Matrix
.fvec projection[4]
; Constants
.constf constants(1.0, 0.0, 0.00392156862745, 0.0)
; Outputs
.out outPos position
.out outUv texcoord0
.out outColor color
; Inputs
.alias inPos v0
.alias inUv v1
.alias inColor v2
.proc main
mov r0.xy, inPos.xy
mov r0.zw, constants.yx
dp4 outPos.x, projection[0], r0
dp4 outPos.y, projection[1], r0
dp4 outPos.z, projection[2], r0
dp4 outPos.w, projection[3], r0
mov outUv, inUv
; Convert from u32 to float
mul r1, constants.zzzz, inColor
mov outColor, r1
end
.end

View File

@ -1,7 +1,7 @@
#include <renderd7/log.hpp>
#include <fstream>
#include <filesystem>
#include <fstream>
#include <memory>
#include <renderd7/log.hpp>
std::string Log::format(const std::string &fmt_str, ...) {
va_list ap;
@ -30,7 +30,7 @@ void Log::Init(const char *filename) {
std::string fn = filename;
std::string name = fn + ".txt";
this->filename = name;
if(std::filesystem::exists(name)) {
if (std::filesystem::exists(name)) {
// Do nothing
} else {
std::fstream f(name, std::ios::out);

119
source/nimg.cpp Normal file
View File

@ -0,0 +1,119 @@
#include <filesystem>
#include <fstream>
#include <map>
#include <renderd7/nimg.hpp>
#include <sstream>
// Use an Npi simplifier cause I am lazy
#define reca_cc(x) reinterpret_cast<const char*>(x)
#define reca_c(x) reinterpret_cast<char*>(x)
#define pak32(q, w, e, r) \
((((q)&0xff) << 0) | (((w)&0xff) << 8) | (((e)&0xff) << 16) | \
(((r)&0xff) << 24))
// Stupid RLE Algorithm
void npi_compress(std::vector<unsigned char>& ret,
const std::vector<unsigned char>& in) {
unsigned char counter = 1;
unsigned char tmp = in[0];
for (size_t i = 1; i < in.size(); ++i) {
if (tmp == in[i]) {
counter++;
} else {
ret.push_back(counter);
ret.push_back(tmp);
counter = 1;
tmp = in[i];
}
if (counter == 255) {
ret.push_back(counter);
ret.push_back(tmp);
counter = 0;
}
}
if (counter > 0) {
ret.push_back(counter);
ret.push_back(tmp);
}
}
void npi_decompress(std::vector<unsigned char>& ret,
const std::vector<unsigned char>& in) {
// Size is sus
if ((in.size() % 2) != 0) return;
for (size_t i = 0; i < in.size(); i += 2) {
int count = in[i];
int value = in[i + 1];
for (int c = 0; c < count; c++) {
ret.push_back(value);
}
}
}
namespace RenderD7 {
nimg NIMG_Load(std::string path) {
nimg res;
std::ifstream fin(path, std::ios::in | std::ios::binary);
// Check magic
fin.read(reca_c(&res.magic), sizeof(uint32_t));
if (res.magic != NPI_NIMG_) {
std::cout << path << " is invalid!" << std::endl;
return res;
}
// Read Information
fin.read(reca_c(&res.width), sizeof(int));
fin.read(reca_c(&res.height), sizeof(int));
fin.read(reca_c(&res.format), sizeof(int));
fin.read(reca_c(&res.compression), sizeof(int));
// Read Pixeldata
if (res.compression == 1) {
std::vector<unsigned char> tb;
int pb_size = 0;
fin.read(reca_c(&pb_size), sizeof(int));
tb.resize(pb_size);
fin.read(reca_c(tb.data()), pb_size);
npi_decompress(res.pixel_buffer, tb);
} else {
int pb_size = 0;
fin.read(reca_c(&pb_size), sizeof(int));
res.pixel_buffer.resize(pb_size);
fin.read(reca_c(res.pixel_buffer.data()), pb_size);
}
// Close stream
fin.close();
// Return the loadet imaeg
return res;
}
nimg NIMG_LoadFromMem(unsigned char* buffer, size_t bf_size) { return nimg(); }
void NIMG_Save(nimg image, std::string path) {
std::ofstream fout(path);
// Write Magic
fout.write(reca_cc(&image.magic), sizeof(uint32_t));
// Write Information
fout.write(reca_cc(&image.width), sizeof(int));
fout.write(reca_cc(&image.height), sizeof(int));
fout.write(reca_cc(&image.format), sizeof(int));
fout.write(reca_cc(&image.compression), sizeof(int));
std::vector<unsigned char> test;
// Write pixels
if (image.compression == 1) {
std::vector<unsigned char> tb;
npi_compress(tb, image.pixel_buffer);
int buf_szs = tb.size();
fout.write(reca_cc(&buf_szs), sizeof(int)); // buf_size
fout.write(reca_cc(tb.data()),
tb.size()); // buffer
} else {
int buf_szs = image.pixel_buffer.size();
fout.write(reca_cc(&buf_szs), sizeof(int)); // buf_size
fout.write(reca_cc(image.pixel_buffer.data()),
image.pixel_buffer.size()); // buffer
}
// Close stream
fout.close();
}
} // namespace RenderD7

83
source/nimg_engine.cpp Normal file
View File

@ -0,0 +1,83 @@
#include <renderd7/external/stb_image.h>
#include <renderd7/Color.hpp>
#include <renderd7/nimg_engine.hpp>
namespace RenderD7 {
NIMG_Engine::NIMG_Engine(int w, int h) { image = RenderD7::nimg(w, h); }
NIMG_Engine::NIMG_Engine() { image = RenderD7::nimg(1, 1); }
NIMG_Engine::~NIMG_Engine() {
// Do nothing
}
void NIMG_Engine::load_file(const std::string& path) {
int w, h, c;
uint8_t* dat = stbi_load(path.c_str(), &w, &h, &c, 4);
image = nimg(w, h);
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * 4;
image.pixel_buffer[pos + 0] = dat[pos + 0];
image.pixel_buffer[pos + 1] = dat[pos + 1];
image.pixel_buffer[pos + 2] = dat[pos + 2];
image.pixel_buffer[pos + 3] = dat[pos + 3];
}
}
stbi_image_free(dat);
}
void NIMG_Engine::load_nimg(const std::string& path) {
image = RenderD7::NIMG_Load(path);
}
void NIMG_Engine::draw_pixel(int x, int y, unsigned int color) {
if (x > image.width || x < 0 || y > image.height || y < 0) return;
RenderD7::Color::RGBA splitter(color);
image.pixel_buffer[((y * image.width + x) * 4) + 0] = splitter.m_r;
image.pixel_buffer[((y * image.width + x) * 4) + 1] = splitter.m_g;
image.pixel_buffer[((y * image.width + x) * 4) + 2] = splitter.m_b;
image.pixel_buffer[((y * image.width + x) * 4) + 3] = splitter.m_a;
}
void NIMG_Engine::draw_rect(int x, int y, int w, int h, unsigned int color,
int t) {}
void NIMG_Engine::draw_rect_solid(int x, int y, int w, int h,
unsigned int color) {
for (int ix = x; ix < x + w; ix++) {
for (int iy = y; iy < y + h; iy++) {
draw_pixel(ix, iy, color);
}
}
}
void NIMG_Engine::flip(bool h, bool v) {
const nimg _bak = image;
if (h) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = ((image.height - 1 - y) * image.width + x) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 3];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 0];
}
}
}
if (v) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = (y * image.width + (image.width - 1 - x)) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 3];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 0];
}
}
}
}
} // namespace RenderD7

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,33 +1,31 @@
#include <renderd7/sound.hpp>
#include <fstream>
#include <string>
#include <cstring>
extern bool isndspinit;
#include <fstream>
#include <renderd7/internal_db.hpp>
#include <renderd7/sound.hpp>
#include <string>
using std::string;
// Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/
typedef struct _WavHeader {
char magic[4]; // "RIFF"
u32 totallength; // Total file length, minus 8.
char wavefmt[8]; // Should be "WAVEfmt "
u32 format; // 16 for PCM format
u16 pcm; // 1 for PCM format
u16 channels; // Channels
u32 frequency; // Sampling frequency
char magic[4]; // "RIFF"
u32 totallength; // Total file length, minus 8.
char wavefmt[8]; // Should be "WAVEfmt "
u32 format; // 16 for PCM format
u16 pcm; // 1 for PCM format
u16 channels; // Channels
u32 frequency; // Sampling frequency
u32 bytes_per_second;
u16 bytes_by_capture;
u16 bits_per_sample;
char data[4]; // "data"
char data[4]; // "data"
u32 bytes_in_data;
} WavHeader;
static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes.");
sound::sound(const string &path, int channel, bool toloop) {
if (isndspinit) {
if (rd7i_is_ndsp) {
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetOutputCount(2); // Num of buffers
ndspSetOutputCount(2); // Num of buffers
// Reading wav file
std::fstream fp(path, std::ios::in | std::ios::binary);
@ -38,7 +36,7 @@ sound::sound(const string &path, int channel, bool toloop) {
}
WavHeader wavHeader;
fp.read(reinterpret_cast<char*>(&wavHeader), sizeof(WavHeader));
fp.read(reinterpret_cast<char *>(&wavHeader), sizeof(WavHeader));
size_t read = fp.tellg();
if (read != sizeof(wavHeader)) {
// Short read.
@ -73,9 +71,9 @@ sound::sound(const string &path, int channel, bool toloop) {
// Allocating and reading samples
data = static_cast<u8 *>(linearAlloc(dataSize));
fp.seekg(44, std::ios::beg);
fp.read(reinterpret_cast<char*>(data), dataSize);
fp.read(reinterpret_cast<char *>(data), dataSize);
fp.close();
dataSize /= 2; // FIXME: 16-bit or stereo?
dataSize /= 2; // FIXME: 16-bit or stereo?
// Find the right format
u16 ndspFormat;
@ -104,7 +102,7 @@ sound::sound(const string &path, int channel, bool toloop) {
}
sound::~sound() {
if (isndspinit) {
if (rd7i_is_ndsp) {
waveBuf.data_vaddr = 0;
waveBuf.nsamples = 0;
waveBuf.looping = false;
@ -118,18 +116,16 @@ sound::~sound() {
}
void sound::play() {
if (isndspinit) {
if (!data)
return;
if (rd7i_is_ndsp) {
if (!data) return;
DSP_FlushDataCache(data, dataSize);
ndspChnWaveBufAdd(chnl, &waveBuf);
}
}
void sound::stop() {
if (isndspinit) {
if (!data)
return;
if (rd7i_is_ndsp) {
if (!data) return;
ndspChnWaveBufClear(chnl);
}
}

View File

@ -1,2 +1,6 @@
#define STB_IMAGE_IMPLEMENTATION
#include <renderd7/external/stb_image.h>
#define STB_IMAGE_IMPLEMENTATION
#include <renderd7/external/stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <renderd7/external/stb_image_write.h>
#define STB_TRUETYPE_IMPLEMENTATION
#include <renderd7/external/stb_truetype.h>

View File

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