0.9.5 preview1
This commit is contained in:
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
262
source/Color.cpp
262
source/Color.cpp
@ -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();
|
||||
}
|
216
source/Draw.cpp
216
source/Draw.cpp
@ -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
239
source/DrawV2.cpp
Normal 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
44
source/Error.cpp
Normal 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
|
@ -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;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
#include <renderd7/FunctionTrace.hpp>
|
||||
|
||||
#include <renderd7/FunctionTrace.hpp>
|
||||
|
||||
std::map<std::string, RenderD7::Ftrace::FTRes> RenderD7::Ftrace::rd7_traces;
|
@ -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
110
source/Hid.cpp
Normal 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] = ∈ }
|
||||
void setKheld(uint32_t &in) { actions[Hid::Held] = ∈ }
|
||||
void setKup(uint32_t &in) { actions[Hid::Up] = ∈ }
|
||||
void setKrepeat(uint32_t &in) { actions[Hid::DownRepeat] = ∈ }
|
||||
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
|
506
source/Image.cpp
506
source/Image.cpp
@ -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
|
@ -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
98
source/Message.cpp
Normal 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
|
@ -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;
|
||||
}
|
@ -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
448
source/Overlays.cpp
Normal 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
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
@ -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
|
@ -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));
|
||||
}
|
||||
}
|
@ -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
31
source/Timer.cpp
Normal 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
|
@ -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
489
source/UI7.cpp
Normal 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
|
@ -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
256
source/internal_db.cpp
Normal 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);
|
||||
}
|
191
source/lang.cpp
191
source/lang.cpp
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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
119
source/nimg.cpp
Normal 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
83
source/nimg_engine.cpp
Normal 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
|
1268
source/renderd7.cpp
1268
source/renderd7.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -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
|
||||
|
Reference in New Issue
Block a user