Codebase of 0.9.5 26.06.2024 found on my OneDrive
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)));
|
||||
}
|
||||
}
|
||||
}
|
138
source/Color.cpp
138
source/Color.cpp
@ -1,46 +1,94 @@
|
||||
#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 <map>
|
||||
#include <renderd7/Color.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) {
|
||||
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(); }
|
||||
|
||||
// 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}};
|
||||
|
||||
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;
|
||||
}
|
237
source/DrawV2.cpp
Normal file
237
source/DrawV2.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
#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(C2D_Font fnt) { rd7i_d2_fnt = fnt; }
|
||||
|
||||
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;
|
||||
// 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 <renderd7/Error.hpp>
|
||||
|
||||
#include <3ds.h>
|
||||
#include <renderd7/renderd7.hpp>
|
||||
#include <renderd7/internal_db.hpp>
|
||||
#include <renderd7/UI7.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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +1,70 @@
|
||||
#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 <cstring>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <renderd7/FileSystem.hpp>
|
||||
// Debugging
|
||||
#include <memory>
|
||||
#include <renderd7/stringtool.hpp>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
|
||||
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;
|
||||
|
||||
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 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;
|
||||
}
|
111
source/Hid.cpp
Normal file
111
source/Hid.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#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,61 @@
|
||||
#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
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
#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
|
@ -1,93 +1,99 @@
|
||||
#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; }
|
||||
#include <renderd7/Color.hpp>
|
||||
#include <renderd7/DrawV2.hpp> // Update to Draw2
|
||||
#include <renderd7/Screen.hpp>
|
||||
#include <renderd7/Message.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
|
||||
|
||||
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
|
451
source/Overlays.cpp
Normal file
451
source/Overlays.cpp
Normal file
@ -0,0 +1,451 @@
|
||||
#include <renderd7/DrawV2.hpp>
|
||||
#include <renderd7/FunctionTrace.hpp>
|
||||
#include <renderd7/Hid.hpp>
|
||||
#include <renderd7/Overlays.hpp>
|
||||
#include <renderd7/renderd7.hpp>
|
||||
#include <renderd7/internal_db.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 StolenInBox(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) &&
|
||||
StolenInBox(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) &&
|
||||
StolenInBox(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,445 @@
|
||||
#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); }
|
||||
#include <map>
|
||||
#include <renderd7/ResultDecoder.hpp>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
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,61 @@
|
||||
#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
|
||||
#include <renderd7/Security.hpp>
|
||||
|
||||
#include <3ds.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <renderd7/internal_db.hpp>
|
||||
|
||||
RenderD7::Security *rd7_security;
|
||||
|
||||
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 = &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,15 @@
|
||||
#include <renderd7/Sheet.hpp>
|
||||
|
||||
RenderD7::Sheet::Sheet() {
|
||||
//
|
||||
}
|
||||
RenderD7::Sheet::~Sheet() {
|
||||
//
|
||||
}
|
||||
|
||||
Result RenderD7::Sheet::Load(const char *path) {
|
||||
this->spritesheet = C2D_SpriteSheetLoad(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RenderD7::Sheet::Free() { C2D_SpriteSheetFree(this->spritesheet); }
|
||||
#include <renderd7/Sheet.hpp>
|
||||
|
||||
RenderD7::Sheet::Sheet() {
|
||||
//
|
||||
}
|
||||
RenderD7::Sheet::~Sheet() {
|
||||
//
|
||||
}
|
||||
|
||||
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); }
|
||||
|
@ -1,36 +1,40 @@
|
||||
#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>
|
||||
|
||||
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() {
|
||||
// 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 "";
|
||||
}
|
||||
#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 <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));
|
||||
}
|
||||
}
|
@ -1,30 +1,30 @@
|
||||
#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 <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);
|
||||
}
|
||||
|
43
source/Timer.cpp
Normal file
43
source/Timer.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#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);
|
||||
}
|
||||
}
|
423
source/UI7.cpp
Normal file
423
source/UI7.cpp
Normal file
@ -0,0 +1,423 @@
|
||||
#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>
|
||||
|
||||
// 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;
|
||||
// Ensure the id is lowercase
|
||||
std::transform(real_id.begin(), real_id.end(), real_id.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
}
|
||||
UI7ID() {
|
||||
title = "";
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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), label);
|
||||
}
|
||||
|
||||
bool BeginMenu(const std::string &title, R7Vec2 size, UI7MenuFlags flags) {
|
||||
if (!UI7CtxValidate()) return false;
|
||||
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), 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);
|
||||
}
|
||||
|
||||
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
|
7737
source/external/lodepng.cpp
vendored
Normal file
7737
source/external/lodepng.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
262
source/internal_db.cpp
Normal file
262
source/internal_db.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
#include <renderd7/renderd7.hpp>
|
||||
#include <renderd7/external/json.hpp>
|
||||
#include <renderd7/FileSystem.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/// 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 = true;
|
||||
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;
|
||||
|
||||
/// 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);
|
||||
}
|
192
source/lang.cpp
192
source/lang.cpp
@ -1,98 +1,96 @@
|
||||
#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 <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;
|
||||
}
|
||||
}
|
@ -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
|
133
source/music/Mp3.cpp
Normal file
133
source/music/Mp3.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
#include <renderd7/music/Mp3.hpp>
|
||||
|
||||
#ifdef RENDERD7_MUSICDEC
|
||||
// MP3 ID3V1
|
||||
std::string rd7i_id3v1_to_string(const std::string& in) {
|
||||
std::string ret = "";
|
||||
if(in.length() < 31) ret = in;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// For MP3 ID3V2 tags
|
||||
// Split up a number of lines separated by \n, \r, both or just zero byte
|
||||
// and print out each line with specified prefix.
|
||||
std::string rd7i_id3v2_to_string(const std::string& prefix, mpg123_string* inlines) {
|
||||
size_t i;
|
||||
int hadcr = 0, hadlf = 0;
|
||||
std::string lines;
|
||||
std::string line;
|
||||
size_t len = 0;
|
||||
|
||||
if(inlines == nullptr) return "";
|
||||
|
||||
if (inlines->fill > 0) {
|
||||
lines = inlines->p;
|
||||
len = inlines->fill;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
line = lines;
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (lines[i] == '\n' || lines[i] == '\r' || lines[i] == 0) {
|
||||
char save = lines[i];
|
||||
if (save == '\n') {
|
||||
++hadlf;
|
||||
}
|
||||
if (save == '\r') {
|
||||
++hadcr;
|
||||
}
|
||||
if ((hadcr || hadlf) && (hadlf % 2 == 0) && (hadcr % 2 == 0)) {
|
||||
line = "";
|
||||
}
|
||||
|
||||
if (!line.empty()) {
|
||||
lines[i] = 0;
|
||||
std::string result;
|
||||
result = prefix + line;
|
||||
line = "";
|
||||
lines[i] = save;
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
hadlf = hadcr = 0;
|
||||
if (line.empty()) {
|
||||
line = lines.substr(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
namespace RenderD7 {
|
||||
int Mp3Decoder::_init(const std::string &path, MusicMeta& meta) {
|
||||
int ret = 0;
|
||||
int encoding = 0;
|
||||
if ((ret = mpg123_init() != MPG123_OK)) return ret;
|
||||
if ((hnd = mpg123_new(NULL, &ret)) == NULL) {
|
||||
printf("[MPG123]: ERR -> %s\n", mpg123_plain_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
if (mpg123_open(hnd, path.c_str()) != MPG123_OK ||
|
||||
mpg123_getformat(hnd, &rate, &channels, &encoding) != MPG123_OK) {
|
||||
printf("[MPG123]: ERR -> %s\n", mpg123_strerror(hnd));
|
||||
return -1;
|
||||
}
|
||||
|
||||
mpg123_id3v1* v1;
|
||||
mpg123_id3v2* v2;
|
||||
mpg123_seek(hnd, 0, SEEK_SET);
|
||||
if(mpg123_meta_check(hnd) & MPG123_ID3 && mpg123_id3(hnd, &v1, &v2) == MPG123_OK) {
|
||||
if(v1 != nullptr) {
|
||||
///// POSSIBLE CRASH /////
|
||||
//meta.title(rd7i_id3v1_to_string(v1->title));
|
||||
//meta.album(rd7i_id3v1_to_string(v1->album));
|
||||
//meta.artist(rd7i_id3v1_to_string(v1->artist));
|
||||
//meta.year(rd7i_id3v1_to_string(v1->year));
|
||||
meta.mdt("mpg123_id3v1");
|
||||
}
|
||||
if(v2 != nullptr) {
|
||||
meta.title(rd7i_id3v2_to_string("", v2->title));
|
||||
meta.album(rd7i_id3v2_to_string("", v2->album));
|
||||
meta.artist(rd7i_id3v2_to_string("", v2->artist));
|
||||
meta.year(rd7i_id3v2_to_string("", v2->year));
|
||||
meta.mdt("mpg123_id3v2");
|
||||
}
|
||||
}
|
||||
|
||||
mpg123_format_none(hnd);
|
||||
mpg123_format(hnd, rate, channels, encoding);
|
||||
buf_size = mpg123_outblock(hnd) * 16;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int Mp3Decoder::_getSampleRate() { return rate; }
|
||||
|
||||
unsigned char Mp3Decoder::_getChannels(){return channels; }
|
||||
|
||||
size_t Mp3Decoder::_getBufSize() {
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
unsigned long long Mp3Decoder::_decode(signed short*buf_addr) {
|
||||
size_t done = 0;
|
||||
mpg123_read(hnd, buf_addr, buf_size, &done);
|
||||
return done / (sizeof(int16_t));
|
||||
}
|
||||
|
||||
void Mp3Decoder::_deinit() {
|
||||
mpg123_close(hnd);
|
||||
mpg123_delete(hnd);
|
||||
mpg123_exit();
|
||||
}
|
||||
|
||||
size_t Mp3Decoder::_getFileSamples() {
|
||||
off_t len = mpg123_length(hnd);
|
||||
if (len != MPG123_ERR) return len * (size_t)channels;
|
||||
return -1; // Not Exist
|
||||
}
|
||||
|
||||
} // namespace RenderD7
|
||||
|
||||
#endif
|
279
source/music/Music.cpp
Normal file
279
source/music/Music.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#ifdef RENDERD7_MUSICDEC
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <renderd7/Message.hpp>
|
||||
#include <renderd7/music/Mp3.hpp>
|
||||
#include <renderd7/music/Music.hpp>
|
||||
#include <renderd7/music/Vorbis.hpp>
|
||||
#include <renderd7/thread.hpp>
|
||||
|
||||
extern bool isndspinit;
|
||||
|
||||
struct PlayerData {
|
||||
RenderD7::MusicMeta meta;
|
||||
size_t samples_total = 0;
|
||||
size_t samples_played = 0;
|
||||
size_t samples_per_sec = 0;
|
||||
|
||||
// Song Info
|
||||
std::string file = "";
|
||||
|
||||
signed short *buf1 = NULL;
|
||||
signed short *buf2 = NULL;
|
||||
ndspWaveBuf waveBuf[2] = {0};
|
||||
bool last_buf = false;
|
||||
int ret = -1;
|
||||
bool done = false;
|
||||
bool playing = false;
|
||||
|
||||
bool stop = false;
|
||||
};
|
||||
|
||||
int rd7i_player_channel = 8;
|
||||
PlayerData rd7i_mp_internal_data;
|
||||
RenderD7::Thread rd7i_mph;
|
||||
|
||||
void rd7i_player_init() {
|
||||
rd7i_mp_internal_data.samples_total = 0;
|
||||
rd7i_mp_internal_data.samples_played = 0;
|
||||
rd7i_mp_internal_data.samples_per_sec = 0;
|
||||
rd7i_mp_internal_data.buf1 = NULL;
|
||||
rd7i_mp_internal_data.buf2 = NULL;
|
||||
rd7i_mp_internal_data.last_buf = false;
|
||||
rd7i_mp_internal_data.ret = -1;
|
||||
rd7i_mp_internal_data.stop = false;
|
||||
rd7i_mp_internal_data.done = false;
|
||||
rd7i_mp_internal_data.playing = true;
|
||||
rd7i_mp_internal_data.file = "";
|
||||
}
|
||||
|
||||
// Non Public Check funcs
|
||||
extern int rd7i_check_vorbis(const std::string &path);
|
||||
extern int rd7i_check_flac(const std::string &path);
|
||||
|
||||
namespace RenderD7 {
|
||||
MusicDecoder *MusicDecoder::decoder = nullptr;
|
||||
|
||||
void MusicDecoder::LoadFile(const std::string &path) {
|
||||
rd7i_mp_internal_data.meta = MusicMeta(); // AutoClean
|
||||
std::fstream f(path, std::ios::in | std::ios::binary);
|
||||
if (!f.is_open()) return;
|
||||
if (!f.good()) return;
|
||||
// File Signature
|
||||
unsigned int sig;
|
||||
f.read(reinterpret_cast<char *>(&sig), sizeof(unsigned int));
|
||||
if (f.tellg() != 4) {
|
||||
f.close();
|
||||
return;
|
||||
}
|
||||
f.close();
|
||||
switch (sig) {
|
||||
// "OGG Collection"
|
||||
case 0x5367674F:
|
||||
if (rd7i_check_vorbis(path) == 0) {
|
||||
decoder = new VorbisDecoder();
|
||||
if (init(path, rd7i_mp_internal_data.meta)) {
|
||||
MusicDecoder::CleanUp();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
return; // Err
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((sig << 16) == 0xFBFF0000 || (sig << 16) == 0xFAFF0000 ||
|
||||
(sig << 8) == 0x33444900) {
|
||||
decoder = new Mp3Decoder();
|
||||
if (init(path, rd7i_mp_internal_data.meta)) {
|
||||
RenderD7::PushMessage(
|
||||
RenderD7::Message("Music Player", "Failed to load MP3"));
|
||||
MusicDecoder::CleanUp();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MusicDecoder::CleanUp() {
|
||||
if (decoder != nullptr) delete decoder;
|
||||
decoder = nullptr;
|
||||
}
|
||||
|
||||
static void rd7i_player_cleaner() {
|
||||
MusicDecoder::deinit();
|
||||
MusicDecoder::CleanUp();
|
||||
ndspChnWaveBufClear(rd7i_player_channel);
|
||||
linearFree(rd7i_mp_internal_data.buf1);
|
||||
linearFree(rd7i_mp_internal_data.buf2);
|
||||
rd7i_mp_internal_data.ret = -1;
|
||||
// Also clean ret data
|
||||
rd7i_mp_internal_data.samples_per_sec = 0;
|
||||
rd7i_mp_internal_data.samples_total = 0;
|
||||
rd7i_mp_internal_data.samples_played = 0;
|
||||
rd7i_mp_internal_data.file = "";
|
||||
}
|
||||
|
||||
static void rd7i_mplayer(RenderD7::Parameter param) {
|
||||
MusicDecoder::LoadFile(param.get<std::string>());
|
||||
if (MusicDecoder::decoder == nullptr) return;
|
||||
|
||||
rd7i_mp_internal_data.samples_total = 0;
|
||||
rd7i_mp_internal_data.samples_played = 0;
|
||||
rd7i_mp_internal_data.samples_per_sec = 0;
|
||||
rd7i_mp_internal_data.buf1 = NULL;
|
||||
rd7i_mp_internal_data.buf2 = NULL;
|
||||
rd7i_mp_internal_data.last_buf = false;
|
||||
rd7i_mp_internal_data.ret = -1;
|
||||
rd7i_mp_internal_data.stop = false;
|
||||
rd7i_mp_internal_data.done = false;
|
||||
rd7i_mp_internal_data.playing = true;
|
||||
rd7i_mp_internal_data.file = "";
|
||||
|
||||
if (MusicDecoder::getFileSamples() != (size_t)-1)
|
||||
rd7i_mp_internal_data.samples_total = MusicDecoder::getFileSamples();
|
||||
|
||||
rd7i_mp_internal_data.samples_per_sec =
|
||||
MusicDecoder::getSampleRate() * MusicDecoder::getChannels();
|
||||
rd7i_mp_internal_data.buf1 = (signed short *)linearAlloc(
|
||||
MusicDecoder::getBufSize() * sizeof(signed short));
|
||||
rd7i_mp_internal_data.buf2 = (signed short *)linearAlloc(
|
||||
MusicDecoder::getBufSize() * sizeof(signed short));
|
||||
rd7i_mp_internal_data.file = param.get<std::string>();
|
||||
|
||||
ndspChnReset(rd7i_player_channel);
|
||||
ndspChnWaveBufClear(rd7i_player_channel);
|
||||
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
|
||||
ndspChnSetInterp(rd7i_player_channel, NDSP_INTERP_POLYPHASE);
|
||||
ndspChnSetRate(rd7i_player_channel, MusicDecoder::getSampleRate());
|
||||
ndspChnSetFormat(rd7i_player_channel, MusicDecoder::getChannels() == 2
|
||||
? NDSP_FORMAT_STEREO_PCM16
|
||||
: NDSP_FORMAT_MONO_PCM16);
|
||||
|
||||
memset(rd7i_mp_internal_data.waveBuf, 0,
|
||||
sizeof(rd7i_mp_internal_data.waveBuf));
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples =
|
||||
MusicDecoder::decode(&rd7i_mp_internal_data.buf1[0]) /
|
||||
MusicDecoder::getChannels();
|
||||
rd7i_mp_internal_data.waveBuf[0].data_vaddr = &rd7i_mp_internal_data.buf1[0];
|
||||
ndspChnWaveBufAdd(rd7i_player_channel, &rd7i_mp_internal_data.waveBuf[0]);
|
||||
|
||||
rd7i_mp_internal_data.waveBuf[1].nsamples =
|
||||
MusicDecoder::decode(&rd7i_mp_internal_data.buf2[0]) /
|
||||
MusicDecoder::getChannels();
|
||||
rd7i_mp_internal_data.waveBuf[1].data_vaddr = &rd7i_mp_internal_data.buf2[0];
|
||||
ndspChnWaveBufAdd(rd7i_player_channel, &rd7i_mp_internal_data.waveBuf[1]);
|
||||
|
||||
// Wait for music to start playing
|
||||
while (ndspChnIsPlaying(rd7i_player_channel) == false) {
|
||||
// Waiting
|
||||
}
|
||||
|
||||
while (rd7i_mp_internal_data.stop == false) {
|
||||
svcSleepThread(100 * 1000);
|
||||
if (rd7i_mp_internal_data.last_buf == true &&
|
||||
rd7i_mp_internal_data.waveBuf[0].status == NDSP_WBUF_DONE &&
|
||||
rd7i_mp_internal_data.waveBuf[1].status == NDSP_WBUF_DONE)
|
||||
break;
|
||||
|
||||
if (ndspChnIsPaused(rd7i_player_channel) == true ||
|
||||
rd7i_mp_internal_data.last_buf == true)
|
||||
continue;
|
||||
|
||||
if (rd7i_mp_internal_data.waveBuf[0].status == NDSP_WBUF_DONE) {
|
||||
size_t read = MusicDecoder::decode(&rd7i_mp_internal_data.buf1[0]);
|
||||
/* The previous block of samples have finished playing,
|
||||
* so accumulate them here. */
|
||||
rd7i_mp_internal_data.samples_played +=
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples *
|
||||
MusicDecoder::getChannels();
|
||||
|
||||
if (read <= 0) {
|
||||
rd7i_mp_internal_data.last_buf = true;
|
||||
continue;
|
||||
} else if (read < MusicDecoder::getBufSize())
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples =
|
||||
read / MusicDecoder::getChannels();
|
||||
|
||||
ndspChnWaveBufAdd(rd7i_player_channel, &rd7i_mp_internal_data.waveBuf[0]);
|
||||
}
|
||||
|
||||
if (rd7i_mp_internal_data.waveBuf[1].status == NDSP_WBUF_DONE) {
|
||||
size_t read = MusicDecoder::decode(&rd7i_mp_internal_data.buf2[0]);
|
||||
rd7i_mp_internal_data.samples_played +=
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples *
|
||||
MusicDecoder::getChannels();
|
||||
|
||||
if (read <= 0) {
|
||||
rd7i_mp_internal_data.last_buf = true;
|
||||
continue;
|
||||
} else if (read < MusicDecoder::getBufSize())
|
||||
rd7i_mp_internal_data.waveBuf[1].nsamples =
|
||||
read / MusicDecoder::getChannels();
|
||||
|
||||
ndspChnWaveBufAdd(rd7i_player_channel, &rd7i_mp_internal_data.waveBuf[1]);
|
||||
}
|
||||
|
||||
DSP_FlushDataCache(rd7i_mp_internal_data.buf1,
|
||||
MusicDecoder::getBufSize() * sizeof(int16_t));
|
||||
DSP_FlushDataCache(rd7i_mp_internal_data.buf2,
|
||||
MusicDecoder::getBufSize() * sizeof(int16_t));
|
||||
}
|
||||
rd7i_mp_internal_data.samples_played +=
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples * MusicDecoder::getChannels();
|
||||
rd7i_mp_internal_data.samples_played +=
|
||||
rd7i_mp_internal_data.waveBuf[0].nsamples * MusicDecoder::getChannels();
|
||||
rd7i_player_cleaner();
|
||||
rd7i_mp_internal_data.playing = false;
|
||||
rd7i_mp_internal_data.done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void MusicPlayer::PlayFile(const std::string &path) {
|
||||
if (MusicPlayer::IsRunning()) {
|
||||
rd7i_mp_internal_data.stop = true;
|
||||
}
|
||||
while (rd7i_mp_internal_data.playing) {
|
||||
}
|
||||
RenderD7::Thread::sleep(100);
|
||||
rd7i_mph.initialize(rd7i_mplayer, path);
|
||||
rd7i_mph.start(true);
|
||||
}
|
||||
|
||||
void MusicPlayer::Play() {
|
||||
if (!rd7i_mp_internal_data.playing) {
|
||||
ndspChnSetPaused(rd7i_player_channel, false);
|
||||
rd7i_mp_internal_data.playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayer::Pause() {
|
||||
if (rd7i_mp_internal_data.playing) {
|
||||
ndspChnSetPaused(rd7i_player_channel, true);
|
||||
rd7i_mp_internal_data.playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayer::Stop() { rd7i_mp_internal_data.stop = true; }
|
||||
|
||||
bool MusicPlayer::IsPlaying() { return rd7i_mp_internal_data.playing; }
|
||||
|
||||
bool MusicPlayer::IsRunning() { return rd7i_mph.isRunning(); }
|
||||
|
||||
int MusicPlayer::PosCurrent() { return rd7i_mp_internal_data.samples_played; }
|
||||
|
||||
int MusicPlayer::Total() { return rd7i_mp_internal_data.samples_total; }
|
||||
|
||||
int MusicPlayer::SampleRate() { return rd7i_mp_internal_data.samples_per_sec; }
|
||||
|
||||
MusicMeta MusicPlayer::GetMeta() { return rd7i_mp_internal_data.meta; }
|
||||
|
||||
} // namespace RenderD7
|
||||
|
||||
#endif
|
74
source/music/Vorbis.cpp
Normal file
74
source/music/Vorbis.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <renderd7/music/Vorbis.hpp>
|
||||
|
||||
#ifdef RENDERD7_MUSICDEC
|
||||
|
||||
int rd7i_check_vorbis(const std::string &path) {
|
||||
// As always forced by libvorbis to not use fstream :(
|
||||
FILE *ft = fopen(path.c_str(), "r");
|
||||
OggVorbis_File testvf;
|
||||
int err;
|
||||
|
||||
if (ft == NULL) return -1;
|
||||
|
||||
err = ov_test(ft, &testvf, NULL, 0);
|
||||
|
||||
ov_clear(&testvf);
|
||||
fclose(ft);
|
||||
return err;
|
||||
}
|
||||
|
||||
namespace RenderD7 {
|
||||
int VorbisDecoder::_init(const std::string &path, MusicMeta& meta) {
|
||||
meta.path(path);
|
||||
if(path.find_last_of('/') != path.npos)
|
||||
meta.name(path.substr(path.find_last_of('/')));
|
||||
else
|
||||
meta.name(path);
|
||||
int ret = -1;
|
||||
if ((f = fopen(path.c_str(), "rb")) == NULL) return ret;
|
||||
if (ov_open(f, &vorbis_file, NULL, 0) < 0) return ret;
|
||||
if ((vi = ov_info(&vorbis_file, -1)) == NULL) return ret;
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int VorbisDecoder::_getSampleRate() { return vi->rate; }
|
||||
|
||||
unsigned char VorbisDecoder::_getChannels() { return vi->channels; }
|
||||
|
||||
size_t VorbisDecoder::_getBufSize() { return buf_size; }
|
||||
|
||||
unsigned long long VorbisDecoder::_decode(signed short*buf_addr) {
|
||||
uint64_t samples_read = 0;
|
||||
int samples2read = buf_size;
|
||||
char *buf = reinterpret_cast<char *>(buf_addr);
|
||||
|
||||
while (samples2read > 0) {
|
||||
int cur_section;
|
||||
int samples_just_read =
|
||||
ov_read(&vorbis_file, buf, samples2read > 4096 ? 4096 : samples2read,
|
||||
&cur_section);
|
||||
if (samples_just_read < 0)
|
||||
return samples_just_read;
|
||||
else if (samples_just_read == 0)
|
||||
break; // End of File
|
||||
samples_read += samples_just_read;
|
||||
samples2read -= samples_just_read;
|
||||
buf += samples_just_read;
|
||||
}
|
||||
// Aka / sizeof(int16_t)
|
||||
return samples_read / sizeof(signed short);
|
||||
}
|
||||
|
||||
void VorbisDecoder::_deinit() {
|
||||
ov_clear(&vorbis_file);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
size_t VorbisDecoder::_getFileSamples() {
|
||||
return ov_pcm_total(&vorbis_file, -1)*vi->channels;
|
||||
}
|
||||
|
||||
} // namespace RenderD7
|
||||
|
||||
#endif
|
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
|
1331
source/renderd7.cpp
1331
source/renderd7.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
extern bool isndspinit;
|
||||
#include <renderd7/internal_db.hpp>
|
||||
using std::string;
|
||||
|
||||
// Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/
|
||||
@ -25,7 +25,7 @@ typedef struct _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
|
||||
|
||||
@ -104,7 +104,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,7 +118,7 @@ sound::~sound() {
|
||||
}
|
||||
|
||||
void sound::play() {
|
||||
if (isndspinit) {
|
||||
if (rd7i_is_ndsp) {
|
||||
if (!data)
|
||||
return;
|
||||
DSP_FlushDataCache(data, dataSize);
|
||||
@ -127,7 +127,7 @@ void sound::play() {
|
||||
}
|
||||
|
||||
void sound::stop() {
|
||||
if (isndspinit) {
|
||||
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,78 @@
|
||||
#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