renderd7/renderd7.cpp

1371 lines
42 KiB
C++
Raw Normal View History

2021-07-23 15:58:16 +02:00
#include "renderd7.hpp"
#include "log.hpp"
#include <regex>
#define RGBA8(r, g, b, a) ((((r) & 0xFF) << 0) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16) | (((a) & 0xFF) << 24))
#define D7_NOTHING C2D_Color32(0, 0, 0, 0)
2022-04-22 14:27:10 +02:00
#define CFGVER "2"
2021-07-23 15:58:16 +02:00
Log renderd7log;
float animtime;
bool isndspinit = false;
bool running = true;
std::stack<std::unique_ptr<RenderD7::Scene>> RenderD7::Scene::scenes;
2022-04-16 23:11:12 +02:00
std::stack<std::unique_ptr<RenderD7::Ovl>> overlays;
2021-07-23 15:58:16 +02:00
bool usedbgmsg = false;
std::string dspststus = "Not Initialisized!";
2021-12-04 01:05:41 +01:00
int cobj___;
int maxobj__;
2021-12-05 23:46:00 +01:00
2021-07-23 15:58:16 +02:00
//INI::INIFile cfgfile;
std::unique_ptr<INI::INIFile> cfgfile = nullptr;
INI::INIStructure cfgstruct;
2022-04-22 10:43:34 +02:00
std::string cfgpath;
2021-07-23 15:58:16 +02:00
2022-04-11 17:00:10 +02:00
// RD7 SuperReselution
bool rd7_superreselution;
u8 consoleModel = 0;
u8 sysRegion = CFG_REGION_USA;
2022-04-16 22:15:15 +02:00
bool is_citra = false;
2022-04-11 17:00:10 +02:00
//---------------------------------------
2022-04-25 17:29:40 +02:00
bool rd7settings = false;
2022-04-11 17:00:10 +02:00
2021-11-27 11:57:40 +01:00
std::string D_app_name;
2021-07-23 15:58:16 +02:00
u32 d7_hDown;
u32 d7_hHeld;
u32 d7_hUp;
touchPosition d7_touch;
C2D_TextBuf TextBuf;
C2D_Font Font;
// Fps Calc
static float current_fps = 0.0f;
static unsigned int frames = 0;
static u64 last_time = 0;
float d11framerate = 0;
//-----------------
//Metrik-------------------------------------
u32 mt_color;
2021-11-28 05:37:58 +01:00
u32 mt_txtcolor;
2021-12-05 23:46:00 +01:00
2022-04-22 14:27:10 +02:00
std::string mt_fps;
std::string mt_cpu;
std::string mt_gpu;
std::string mt_cmd;
2022-04-17 17:34:48 +02:00
bool shouldbe_disabled = false;
2021-11-28 12:09:07 +01:00
int mt_screen;
2021-12-05 23:46:00 +01:00
//int mt_width = mt_screen ? 320 : 400;
2021-11-28 05:37:58 +01:00
float mt_txtSize;
2021-11-28 15:03:00 +01:00
bool metrikd = false;
2022-04-16 17:45:20 +02:00
//double mt_fpsgraph[320];
2022-04-17 22:23:47 +02:00
std::vector<int> mt_fpsgraph(320);
2022-04-22 14:27:10 +02:00
//Metrik-CSV
2022-04-22 17:11:30 +02:00
std::string csvpc;
2022-04-22 14:27:10 +02:00
bool mt_dumpcsv = false; //Logs the Fps and stuff to csv. It saves every second to not loose performence.
bool mt_csvloop = false; //Saves In Every Frame but slows down performens. mt_dumpcsv must be enabled.
std::ofstream mt_csv;
std::string mt_cname;
2021-07-23 15:58:16 +02:00
//-------------------------------------------
bool currentScreen = false;
2021-11-28 15:03:00 +01:00
2021-07-23 15:58:16 +02:00
C3D_RenderTarget* Top;
C3D_RenderTarget* TopRight;
C3D_RenderTarget* Bottom;
#define DSEVENBLACK C2D_Color32(0, 0 ,0, 255)
#define DSEVENWHITE C2D_Color32(255, 255, 255, 255)
2022-04-11 17:00:10 +02:00
2022-04-22 14:51:29 +02:00
std::string _FMT_(const 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());
}
2022-04-22 14:27:10 +02:00
std::string Date(void)
{
time_t unixTime;
struct tm timeStruct;
time(&unixTime);
localtime_r(&unixTime, &timeStruct);
2022-04-23 01:14:49 +02:00
return _FMT_("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday,
2022-04-22 14:27:10 +02:00
timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec);
}
2022-04-11 17:00:10 +02:00
void screenoff()
{
gspLcdInit();\
GSPLCD_PowerOffBacklight(GSPLCD_SCREEN_BOTH);\
gspLcdExit();
}
void screenon()
{
gspLcdInit();\
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH);\
gspLcdExit();
}
2021-07-23 15:58:16 +02:00
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation()
{
renderd7log.Write("SpriteSheetAnimation createt!");
}
RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation()
{
//
}
bool RenderD7::DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX, float scaleY)
{
if (sheet->spritesheet != nullptr)
{
if (C2D_SpriteSheetCount(sheet->spritesheet) >= index)
{
return C2D_DrawImageAt(C2D_SpriteSheetGetImage(sheet->spritesheet, index), x, y, 0.5f, nullptr, scaleX, scaleY);
}
}
return false;
}
void RenderD7::Init::NdspFirm(bool useit)
{
if (useit)
{
if ( access( "sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 )
{
ndspInit();
isndspinit = true;
dspststus = "Initialisized success!";
}
else
{
dspststus = "Not found: dspfirm.cdc";
renderd7log.Write("RenderD7: SoundEngine Error! ndspfirm not found!");
}
}
}
void RenderD7::Exit::NdspFirm()
{
if (isndspinit)
{
ndspExit();
}
}
void RenderD7::Msg::Display(std::string titletxt, std::string subtext, C3D_RenderTarget *target)
{
2022-04-17 17:34:48 +02:00
shouldbe_disabled = true;
2021-07-23 15:58:16 +02:00
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, DSEVENBLACK);
C2D_TargetClear(Bottom, DSEVENBLACK);
RenderD7::ClearTextBufs();
RenderD7::OnScreen(Top);
RenderD7::DrawRect(0, 0, 400, 240, RenderD7::Color::Hex("#111111"));
RenderD7::OnScreen(Bottom);
RenderD7::DrawRect(0, 0, 320, 240, RenderD7::Color::Hex("#111111"));
RenderD7::OnScreen(target);
RenderD7::DrawRect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200));
RenderD7::DrawText(5, 2, 0.7f, DSEVENWHITE, titletxt);
RenderD7::DrawText(5, 30, 0.6f, DSEVENWHITE, subtext);
2022-04-17 23:00:37 +02:00
C3D_FrameEnd(0);
shouldbe_disabled = false;
2021-07-23 15:58:16 +02:00
}
void RenderD7::Msg::DisplayWithProgress(std::string titletext, std::string subtext, float current, float total, u32 prgbarcolor)
{
2022-04-17 17:34:48 +02:00
shouldbe_disabled = true;
2021-07-23 15:58:16 +02:00
RenderD7::ClearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, DSEVENBLACK);
C2D_TargetClear(Bottom, DSEVENBLACK);
char str[256];
snprintf(str, sizeof(str), "(%.2f%%)", ((float)current/(float)total) * 100.0f);
RenderD7::OnScreen(Top);
RenderD7::DrawRect(0, 0, 400, 240, RenderD7::Color::Hex("#111111"));
RenderD7::DrawRect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200));
RenderD7::DrawText(5, 2, 0.7f, DSEVENWHITE, titletext);
RenderD7::DrawText(5, 30, 0.6f, DSEVENWHITE, subtext);
RenderD7::DrawRect(30, 120, 342, 30, RenderD7::Color::Hex("#333333"));
RenderD7::DrawRect(31, 121, (int)(((float)current / (float)total) * 338.0f), 28, prgbarcolor);
RenderD7::DrawTextCentered(5, 124, 0.7f, RenderD7::Color::Hex("#111111"), str, 390);
RenderD7::OnScreen(Bottom);
RenderD7::DrawRect(0, 0, 320, 240, RenderD7::Color::Hex("#111111"));
2022-04-17 23:00:37 +02:00
C3D_FrameEnd(0);
shouldbe_disabled = false;
2021-07-23 15:58:16 +02:00
}
void RenderD7::SetupLog()
{
renderd7log.Init("sdmc:/RenderD7.log");
2021-07-23 15:58:16 +02:00
}
void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish)
{
D_totaltime = frame_begin;
renderd7log.Write("frame_begin success");
this->images = imagecount;
renderd7log.Write("imagecount success");
this->sheet = sheet;
renderd7log.Write("sheet success");
this->time = frame_finish;
renderd7log.Write("frame_finish success");
RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage);
}
void RenderD7::SpriteSheetAnimation::Play(float timespeed)
{
D_totaltime += timespeed;
if (D_totaltime >= time)
{
D_totaltime -= time;
imgs++;
if (imgs == images)
{
imgs = 0;
}
}
RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs);
//RenderD7::SpriteSheetAnimation::Draw();
}
2022-04-10 13:13:45 +02:00
void RenderD7::Error::DisplayError(std::string toptext, std::string errortext, int timesec)
2021-07-23 15:58:16 +02:00
{
2022-04-17 17:34:48 +02:00
shouldbe_disabled = true;
2021-07-23 15:58:16 +02:00
RenderD7::ClearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, DSEVENBLACK);
C2D_TargetClear(Bottom, DSEVENBLACK);
RenderD7::OnScreen(Top);
2022-04-10 13:13:45 +02:00
RenderD7::DrawText(0, 0, 0.7f, DSEVENWHITE, toptext);
RenderD7::DrawText(0, 30, 0.6f, DSEVENWHITE, errortext);
2022-04-17 23:00:37 +02:00
C3D_FrameEnd(0);
2022-04-10 13:13:45 +02:00
for (int i = 0; i < 60*timesec; i++) {
RenderD7::DrawRect(0, 236, (int)(((float)i / (float)60*timesec) * 400.0f), 4, RenderD7::Color::Hex("#00ff00"));
2021-07-23 15:58:16 +02:00
gspWaitForVBlank();
}
2022-04-17 23:00:37 +02:00
shouldbe_disabled = false;
2021-07-23 15:58:16 +02:00
}
void RenderD7::Error::DisplayFatalError(std::string toptext, std::string errortext)
{
2022-04-17 17:34:48 +02:00
shouldbe_disabled = true;
2021-07-23 15:58:16 +02:00
bool error___ = true;
RenderD7::ClearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, DSEVENBLACK);
C2D_TargetClear(Bottom, DSEVENBLACK);
RenderD7::OnScreen(Top);
RenderD7::DrawTextCentered(0, 0, 0.7f, DSEVENWHITE, toptext, 400);
RenderD7::DrawTextCentered(0, 100, 0.6f, DSEVENWHITE, errortext, 400);
RenderD7::DrawTextCentered(0, 200, 0.6f, DSEVENWHITE, "Press Start to Exit!", 400);
2022-04-17 23:00:37 +02:00
C3D_FrameEnd(0);
2021-07-23 15:58:16 +02:00
while (error___)
{
if(d7_hDown & KEY_START)
{
RenderD7::ExitApp();
}
2022-04-17 23:00:37 +02:00
}
shouldbe_disabled = false;
2021-07-23 15:58:16 +02:00
}
u32 RenderD7::Color::Hex(const std::string color, u8 a)
{
if (color.length() < 7 || std::regex_search(color.substr(1), std::regex("[^0-9A-Fa-f]"))) { // invalid color.
return D7_NOTHING;
}
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);
}
2022-04-22 20:27:27 +02:00
std::string RenderD7::Color::RGB2Hex(int r, int g, int b)
2022-04-22 20:20:11 +02:00
{
std::stringstream ss;
ss << "#";
ss << std::hex << (r << 16 | g << 8 | b );
return ss.str();
}
2021-07-23 15:58:16 +02:00
void RenderD7::Scene::doDraw() {
if(!RenderD7::Scene::scenes.empty())
RenderD7::Scene::scenes.top()->Draw();
}
void RenderD7::Scene::doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) {
if(!RenderD7::Scene::scenes.empty())
RenderD7::Scene::scenes.top()->Logic(hDown, hHeld, hUp, touch);
}
void RenderD7::Scene::Load(std::unique_ptr<Scene> scene)
{
Scene::scenes.push(std::move(scene));
}
void RenderD7::Scene::Back() {
if(RenderD7::Scene::scenes.size() > 0)
RenderD7::Scene::scenes.pop();
}
void RenderD7::OnScreen(C3D_RenderTarget *target)
{
C2D_SceneBegin(target);
2022-04-13 12:50:22 +02:00
currentScreen = (target == Top || target == TopRight) ? 1 : 0;
2021-07-23 15:58:16 +02:00
}
void frameloop()
{
frames++;
u64 delta_time = osGetTime() - last_time;
if (delta_time >= 1000) {
current_fps = frames/(delta_time/1000.0f)+1;
frames = 0;
last_time = osGetTime();
}
d11framerate = current_fps;
2022-04-17 22:23:47 +02:00
//for (int i = 0; i < 320; i++) mt_fpsgraph[i] = current_fps;
2021-07-23 15:58:16 +02:00
}
float getframerate()
{
return d11framerate;
}
std::string RenderD7::GetFramerate()
{
return (std::to_string((int)d11framerate).substr(0, 2));
}
bool RenderD7::MainLoop()
{
if (!aptMainLoop()) return false;
hidScanInput();
d7_hDown = hidKeysDown();
d7_hUp = hidKeysUp();
d7_hHeld = hidKeysHeld();
hidTouchRead(&d7_touch);
RenderD7::ClearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
frameloop();
2022-04-17 22:23:47 +02:00
RenderD7::Scene::doDraw();
RenderD7::Scene::doLogic(d7_hDown, d7_hHeld, d7_hUp, d7_touch);
2022-04-17 17:34:48 +02:00
2021-07-23 15:58:16 +02:00
return running;
}
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);
}
RenderD7::Sprite::Sprite()
{
//
}
RenderD7::Sprite::~Sprite()
{
//
}
void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index)
{
C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index);
}
bool RenderD7::Sprite::Draw()
{
return C2D_DrawSprite(&this->sprite);
}
void RenderD7::Sprite::SetCenter(float x, float y)
{
C2D_SpriteSetCenter(&this->sprite, x, y);
}
void RenderD7::Sprite::SetPos(float x, float y)
{
C2D_SpriteSetPos(&this->sprite, x, y);
}
void RenderD7::Sprite::SetRotation(float rotation)
{
C2D_SpriteSetRotation(&this->sprite, rotation);
}
void RenderD7::Sprite::Rotate(float speed)
{
C2D_SpriteRotateDegrees(&this->sprite, speed);
}
float RenderD7::Sprite::getHeigh()
{
return this->sprite.params.pos.h;
}
float RenderD7::Sprite::getWidth()
{
return this->sprite.params.pos.w;
}
float RenderD7::Sprite::getPosX()
{
return this->sprite.params.pos.x;
}
float RenderD7::Sprite::getPosY()
{
return this->sprite.params.pos.y;
}
void RenderD7::Sprite::FromImage(RenderD7::Image *img)
{
C2D_SpriteFromImage(&this->sprite, img->img);
}
void RenderD7::Sprite::SetScale(float x, float y)
{
C2D_SpriteScale(&this->sprite, x, y);
}
void RenderD7::ClearTextBufs(void)
{
C2D_TextBufClear(TextBuf);
}
bool RenderD7::DrawRect(float x, float y, float w, float h, u32 color)
{
return C2D_DrawRectSolid(x, y, 0.5f, w, h, color);
}
2021-08-01 12:58:56 +02:00
bool RenderD7::DrawPx(float x, float y, u32 color)
{
return C2D_DrawRectSolid(x, y, 0.5f, 1, 1, color);
}
2021-07-23 15:58:16 +02:00
void RenderD7::DrawTextCentered(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::GetTextHeight(size, " ", fnt);
} else {
lineHeight = RenderD7::GetTextHeight(size, " ");
}
int line = 0;
while(Text.find('\n') != Text.npos) {
if (maxWidth == 0) {
// Do the widthScale.
if (fnt != nullptr) {
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt);
} else {
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')));
}
} else {
// Do the widthScale 2.
if (fnt != nullptr) {
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt));
} else {
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
}
}
if (fnt != nullptr) {
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt);
} else {
RenderD7::DrawText((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::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt);
} else {
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')));
}
} else {
// And again.
if (fnt != nullptr) {
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt));
} else {
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
}
}
if (fnt != nullptr) {
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt);
} else {
RenderD7::DrawText((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::DrawText(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::GetTextHeight(size, Text, fnt)));
} else {
heightScale = std::min(size, size*(maxHeight/RenderD7::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::GetTextWidth(size, Text, fnt))), heightScale, color);
} else {
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::GetTextWidth(size, Text))), heightScale, color);
}
}
}
void RenderD7::DrawTextLeft(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt)
{
RenderD7::DrawText(x - RenderD7::GetTextWidth(size, Text, fnt), y, size, color, Text, maxWidth, maxHeight, fnt);
}
// Get String or Text Width.
float RenderD7::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::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::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::loadFont(C2D_Font &fnt, const char* Path) {
fnt = C2D_FontLoad(Path); // Only load if found.
return 0;
}
// Unload a Font.
Result RenderD7::unloadFont(C2D_Font &fnt) {
if (fnt != nullptr) {
C2D_FontFree(fnt); // Make sure to only unload if not nullptr.
}
return 0;
}
bool RenderD7::DrawCircle(float x, float y, float radius, u32 color)
{
return C2D_DrawCircleSolid(x, y, 0.5f, radius, color);
}
void MetrikThread(RenderD7::Parameter param) {
while (true) {
RenderD7::DrawMetrikOvl();
RenderD7::Thread::sleep(1000 * 1); // wait; also, this is needed to allow for concurrency (refer to the documentation for m3d::Thread::sleep())
}
}
2021-11-27 11:57:40 +01:00
Result RenderD7::Init::Main(std::string app_name)
2021-07-23 15:58:16 +02:00
{
gfxInitDefault();
2022-04-11 17:00:10 +02:00
Result res = cfguInit();
if (R_SUCCEEDED(res)) {
CFGU_SecureInfoGetRegion(&sysRegion);
CFGU_GetSystemModel(&consoleModel);
cfguExit();
}
if (rd7_superreselution)
{
gfxSetWide(consoleModel != 3);
}
2021-07-23 15:58:16 +02:00
aptInit();
romfsInit();
cfguInit();
2021-12-04 01:05:41 +01:00
if (cobj___){maxobj__ = cobj___;}
if (!cobj___){maxobj__ = C2D_DEFAULT_MAX_OBJECTS;}
2021-11-27 12:05:43 +01:00
D_app_name = app_name;
2022-04-22 10:43:34 +02:00
cfgpath = "sdmc:/RenderD7/Apps/";
2021-11-27 11:57:40 +01:00
cfgpath += D_app_name;
2022-04-22 17:04:37 +02:00
csvpc = "sdmc:/RenderD7/Apps/";
csvpc += D_app_name;
csvpc += "/mt";
2021-07-23 15:58:16 +02:00
mkdir("sdmc:/RenderD7/", 0777);
2022-04-11 09:50:47 +02:00
mkdir("sdmc:/RenderD7/Apps", 0777);
mkdir(cfgpath.c_str(), 0777);
2022-04-22 17:04:37 +02:00
mkdir(csvpc.c_str(), 0777);
2022-04-11 09:50:47 +02:00
bool renew = false;
if (FS::FileExist(cfgpath + "/config.ini"))
{
cfgfile = std::make_unique<INI::INIFile>(cfgpath + "/config.ini");
cfgfile->read(cfgstruct);
2022-04-11 09:59:25 +02:00
std::string version = cfgstruct["info"]["version"];
2022-04-11 09:53:36 +02:00
if (version != CFGVER) renew = true;
2022-04-11 09:50:47 +02:00
}
if (!FS::FileExist(cfgpath + "/config.ini") || renew)
2021-07-23 15:58:16 +02:00
{
2021-11-27 12:11:05 +01:00
cfgfile = std::make_unique<INI::INIFile>(cfgpath+ "/config.ini");
2021-07-23 15:58:16 +02:00
cfgfile->read(cfgstruct);
cfgstruct["info"]["version"] = CFGVER;
cfgstruct["info"]["renderd7ver"] = RENDERD7VSTRING;
cfgstruct["settings"]["doscreentimeout"] = "0";
cfgstruct["settings"]["forcetimeoutLB"] = "1";
cfgstruct["settings"]["forceFrameRate"] = "60";
cfgstruct["settings"]["super-reselution"] = "0";
cfgstruct["metrik-settings"]["enableoverlay"] = "0";
cfgstruct["metrik-settings"]["Screen"] = "0";
2021-11-28 05:37:58 +01:00
cfgstruct["metrik-settings"]["txtColor"] = "#ffffff";
cfgstruct["metrik-settings"]["txtColorA"] = "255";
2022-04-10 00:59:30 +02:00
cfgstruct["metrik-settings"]["ColorA"] = "255";
cfgstruct["metrik-settings"]["Color"] = "#000000";
cfgstruct["metrik-settings"]["txtSize"] = "0.7f";
2022-04-22 14:27:10 +02:00
cfgstruct["metrik-settings"]["dumpcsv"] = "0";
cfgstruct["metrik-settings"]["dumpcsvloop"] = "0";
2021-07-23 15:58:16 +02:00
cfgfile->write(cfgstruct);
}
2021-11-27 12:11:05 +01:00
cfgfile = std::make_unique<INI::INIFile>(cfgpath+ "/config.ini");
2021-07-23 15:58:16 +02:00
cfgfile->read(cfgstruct);
std::string Fps = cfgstruct["settings"]["forceFrameRate"];
C3D_FrameRate(RenderD7::Convert::StringtoFloat(Fps));
metrikd = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["enableoverlay"]));
2021-11-28 05:37:58 +01:00
mt_txtcolor = RenderD7::Color::Hex(cfgstruct["metrik-settings"]["txtColor"], (u8)RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["txtColorA"]));
2022-04-10 00:59:30 +02:00
mt_color = RenderD7::Color::Hex(cfgstruct["metrik-settings"]["Color"], (u8)RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["ColorA"]));
mt_txtSize = RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["txtSize"]);
mt_screen = RenderD7::Convert::StringtoInt(cfgstruct["metrik-settings"]["Screen"]);
2022-04-11 17:00:10 +02:00
rd7_superreselution = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["settings"]["super-reselution"]));
2022-04-22 14:27:10 +02:00
mt_dumpcsv = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["dumpcsv"]));
mt_csvloop = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["dumpcsvloop"]));
2022-04-16 22:15:15 +02:00
//Check if citra
s64 citracheck = 0;
svcGetSystemInfo(&citracheck, 0x20000, 0);
is_citra = citracheck ? true : false;
//Speedup
2022-04-11 17:00:10 +02:00
osSetSpeedupEnable(true);
2022-04-16 22:15:15 +02:00
if (!is_citra && rd7_superreselution)
2022-04-13 01:38:39 +02:00
{
if (consoleModel != 3) gfxSetWide(true);
}
2022-04-23 01:14:49 +02:00
//consoleInit(GFX_BOTTOM, NULL);
2022-04-22 14:27:10 +02:00
if (mt_dumpcsv)
{
2022-04-22 21:03:58 +02:00
mt_cname = csvpc;
mt_cname += "/";
mt_cname += Date();
mt_cname += ".csv";
2022-04-23 01:00:19 +02:00
2022-04-23 01:14:49 +02:00
FILE* logfile = fopen((mt_cname.c_str()), "w");
fclose(logfile);
2022-04-22 17:41:48 +02:00
mt_csv.open((mt_cname), std::ofstream::app);
2022-04-22 14:27:10 +02:00
mt_csv << "FPS,CPU,GPU,CMD\n";
mt_csv.close();
}
2022-04-16 23:11:12 +02:00
RenderD7::AddOvl(std::make_unique<RenderD7::DSP_NF>());
2022-04-10 00:59:30 +02:00
2021-07-23 15:58:16 +02:00
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
2021-12-04 01:05:41 +01:00
C2D_Init(size_t(maxobj__));
2021-07-23 15:58:16 +02:00
C2D_Prepare();
Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT);
TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT);
Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
TextBuf = C2D_TextBufNew(4096);
Font = C2D_FontLoadSystem(CFG_REGION_USA);
2022-04-13 01:38:39 +02:00
2022-04-16 22:15:15 +02:00
//RenderD7::Msg::Display("RenderD7", "RenderD7 init success!\nWaiting for MainLoop!", Top);
2021-07-23 15:58:16 +02:00
return 0;
}
2022-04-11 17:00:10 +02:00
2022-04-13 01:38:39 +02:00
Result RenderD7::Init::Reload()
{
C2D_TextBufDelete(TextBuf);
C2D_Fini();
C3D_Fini();
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
C2D_Init(size_t(maxobj__));
C2D_Prepare();
Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT);
TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT);
Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
TextBuf = C2D_TextBufNew(4096);
Font = C2D_FontLoadSystem(CFG_REGION_USA);
return 0;
}
2022-04-11 17:00:10 +02:00
void RenderD7::ToggleRD7SR()
{
2022-04-11 17:08:50 +02:00
// Display black screen
2022-04-11 17:00:10 +02:00
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
2022-04-11 17:08:50 +02:00
C2D_TargetClear(Top, RenderD7::Color::Hex("#000000"));
RenderD7::OnScreen(Top);
2022-04-11 17:00:10 +02:00
C3D_FrameEnd(0);
// Toggle 400px/800px mode
2022-04-22 20:37:59 +02:00
gfxSetWide(gfxIsWide() ? false : true);
2022-04-25 17:06:35 +02:00
rd7_superreselution = gfxIsWide();
2022-04-13 01:38:39 +02:00
RenderD7::Init::Reload();
2022-04-11 17:00:10 +02:00
}
bool RenderD7::IsRD7SR()
{
return gfxIsWide();
}
2021-07-23 15:58:16 +02:00
void RenderD7::Exit::Main()
{
cfgfile->write(cfgstruct);
if (RenderD7::Threads::threadrunning) RenderD7::Threads::Exit();
C2D_TextBufDelete(TextBuf);
C2D_Fini();
C3D_Fini();
aptExit();
2022-04-11 09:50:47 +02:00
gfxExit();
2021-07-23 15:58:16 +02:00
romfsExit();
cfguExit();
2022-04-11 09:50:47 +02:00
romfsExit();
2021-07-23 15:58:16 +02:00
}
void RenderD7::DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color, u32 txtcolor, int selection, u32 selbgcolor, u32 selcolor)
{
for(int i = 0; i < (int)tobjects.size(); i++)
{
if (selection == i)
{
RenderD7::DrawRect(tobjects[i].x - 2, tobjects[i].y - 2, tobjects[i].w + 4, tobjects[i].h + 4, selbgcolor);
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, color);
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, selcolor);
RenderD7::DrawText(tobjects[i].x + (tobjects[i].w/2) - RenderD7::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text);
}
else
{
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y - 1, tobjects[i].w, tobjects[i].h, color);
RenderD7::DrawText(tobjects[i].x + (tobjects[i].w/2) - RenderD7::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text);
}
}
}
2021-08-14 10:08:54 +02:00
void RenderD7::DrawTLBtns(std::vector<RenderD7::TLBtn> btns, u32 color, int selection, u32 selbgcolor, u32 selcolor)
{
2021-08-14 10:51:20 +02:00
for(int i = 0; i < (int)btns.size(); i++)
2021-08-14 10:08:54 +02:00
{
if (selection == i)
{
RenderD7::DrawRect(btns[i].x - 2, btns[i].y - 2, btns[i].w + 4, btns[i].h + 4, selbgcolor);
RenderD7::DrawRect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, color);
RenderD7::DrawRect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, selcolor);
}
else
{
RenderD7::DrawRect(btns[i].x, btns[i].y - 1, btns[i].w, btns[i].h, color);
}
}
}
2021-07-23 15:58:16 +02:00
void RenderD7::ExitApp()
{
2022-04-25 17:29:40 +02:00
if (!rd7settings) running = false;
2021-07-23 15:58:16 +02:00
}
bool RenderD7::touchTObj(touchPosition touch, RenderD7::TObject button)
{
if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true;
else return false;
}
2022-04-08 13:45:10 +02:00
int RenderD7::GetRandomInt(int b, int e)
{
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(b, e);
int r = distribution(generator);
return r;
}
2021-07-23 15:58:16 +02:00
void RenderD7::DrawSTObject(std::vector<RenderD7::TObject> tobject, int tobjectindex, u32 color, u32 txtcolor)
{
RenderD7::DrawRect(tobject[tobjectindex].x, tobject[tobjectindex].y, tobject[tobjectindex].w, tobject[tobjectindex].h, color);
RenderD7::DrawText(tobject[tobjectindex].x + (tobject[tobjectindex].w/2) - RenderD7::GetTextHeight(tobject[tobjectindex].txtsize , tobject[tobjectindex].text) + tobject[tobjectindex].correctx, tobject[tobjectindex].y + (tobject[tobjectindex].h/2) - RenderD7::GetTextHeight(tobject[tobjectindex].txtsize, tobject[tobjectindex].text) + tobject[tobjectindex].correcty, tobject[tobjectindex].txtsize, txtcolor, tobject[tobjectindex].text);
}
bool RenderD7::NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions) {
if (name.substr(0, 2) == "._") return false;
if (name.size() == 0) return false;
if (extensions.size() == 0) return true;
for(int i = 0; i < (int)extensions.size(); i++) {
const std::string ext = extensions.at(i);
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true;
}
return false;
}
bool dirEntryPredicate(const RenderD7::DirContent &lhs, const RenderD7::DirContent &rhs) {
if (!lhs.isDir && rhs.isDir) return false;
if (lhs.isDir && !rhs.isDir) return true;
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
}
void RenderD7::GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions) {
struct stat st;
dircontent.clear();
DIR *pdir = opendir(".");
if (pdir != nullptr) {
while(true) {
RenderD7::DirContent dirEntry;
struct dirent *pent = readdir(pdir);
if (pent == NULL) break;
stat(pent->d_name, &st);
dirEntry.name = pent->d_name;
dirEntry.isDir = (st.st_mode & S_IFDIR) ? true : false;
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDir || RenderD7::NameIsEndingWith(dirEntry.name, extensions))) {
dircontent.push_back(dirEntry);
}
}
closedir(pdir);
}
sort(dircontent.begin(), dircontent.end(), dirEntryPredicate);
}
void RenderD7::GetDirContents(std::vector<RenderD7::DirContent> &dircontent) {
RenderD7::GetDirContentsExt(dircontent, {});
}
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);
}
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;
}
void RenderD7::Image::LoadPFromBuffer(const std::vector<u8> &buffer)
{
std::vector<u8> ImageBuffer;
if (loadet)
{
C3D_TexDelete(this->img.tex);
}
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];
}
}
}
2022-04-23 14:54:10 +02:00
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++) {
2022-04-23 14:56:32 +02:00
u32 z = (row + col * subtex->width) * 4;
2022-04-23 14:54:10 +02:00
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++) {
2022-04-23 14:56:32 +02:00
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);
2022-04-23 14:54:10 +02:00
}
}
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;
}
2022-04-23 13:58:48 +02:00
void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index)
{
}
2021-07-23 15:58:16 +02:00
bool RenderD7::DrawImage(C2D_Image img, float x, float y, float scaleX, float scaleY)
{
return C2D_DrawImageAt(img, x, y, 0.5f, nullptr, scaleX, scaleY);
}
bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY)
{
return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY);
}
bool RenderD7::FS::FileExist(const std::string& path)
{
FILE *test = fopen(path.c_str(), "r");
if(test != NULL)
{
fclose(test);
return true;
}
return false;
}
bool RenderD7::IsNdspInit()
{
if (isndspinit)
{
return true;
}
else
{
return false;
}
}
void RenderD7::DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t)
{
RenderD7::OnScreen(t);
RenderD7::DrawRect(0, 0, 400, 240, RenderD7::Color::Hex("#dddddd"));
RenderD7::DrawText(0, 0, 0.8f, RenderD7::Color::Hex("#ffffff"), l.Text);
}
2022-04-17 22:23:47 +02:00
2021-07-23 15:58:16 +02:00
void RenderD7::DrawMetrikOvl()
{
2022-04-10 00:59:30 +02:00
switch (mt_screen)
{
case 0:
RenderD7::OnScreen(Top);
break;
case 1:
RenderD7::OnScreen(Bottom);
break;
default:
RenderD7::OnScreen(Bottom);
break;
}
2022-04-17 22:49:54 +02:00
std::string __C = RENDERD7VSTRING;
std::string info = "RenderD7 " + __C + " Debug Overlay";
float infoy = 240 - RenderD7::GetTextHeight(mt_txtSize, info);
2022-04-22 14:27:10 +02:00
mt_fps = "FPS: " + RenderD7::GetFramerate();
mt_cpu = "CPU: " + std::to_string(C3D_GetProcessingTime()*6.0f).substr(0, 4) + "%/" + std::to_string(C3D_GetProcessingTime()).substr(0, 4) + "ms";
mt_gpu = "GPU: " + std::to_string(C3D_GetDrawingTime()*6.0f).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) + "%/" + std::to_string(C3D_GetCmdBufUsage()).substr(0, 4) + "ms";
2022-04-22 14:48:20 +02:00
RenderD7::DrawRect(0, 0, RenderD7::GetTextWidth(mt_txtSize, mt_fps), RenderD7::GetTextHeight(mt_txtSize, mt_fps), mt_color);
RenderD7::DrawRect(0, 50, RenderD7::GetTextWidth(mt_txtSize, mt_cpu), RenderD7::GetTextHeight(mt_txtSize, mt_cpu), mt_color);
RenderD7::DrawRect(0, 70, RenderD7::GetTextWidth(mt_txtSize, mt_gpu), RenderD7::GetTextHeight(mt_txtSize, mt_gpu), mt_color);
RenderD7::DrawRect(0, 90, RenderD7::GetTextWidth(mt_txtSize, mt_cmd), RenderD7::GetTextHeight(mt_txtSize, mt_cmd), mt_color);
2022-04-17 22:49:54 +02:00
RenderD7::DrawRect(0, infoy, RenderD7::GetTextWidth(mt_txtSize, info), RenderD7::GetTextHeight(mt_txtSize, info), mt_color);
2022-04-22 14:48:20 +02:00
RenderD7::DrawText(0, 0, mt_txtSize, mt_txtcolor, mt_fps);
RenderD7::DrawText(0, 50, mt_txtSize, mt_txtcolor, mt_cpu);
RenderD7::DrawText(0, 70, mt_txtSize, mt_txtcolor, mt_gpu);
RenderD7::DrawText(0, 90, mt_txtSize, mt_txtcolor, mt_cmd);
2022-04-17 22:49:54 +02:00
RenderD7::DrawText(0, infoy, mt_txtSize, mt_txtcolor, info);
2022-04-17 22:23:47 +02:00
/*for (int z = 0; z < (int)mt_fpsgraph.size(); z++)
2022-04-10 00:59:30 +02:00
{
2022-04-17 22:23:47 +02:00
//mt_fpsgraph[z] = (int)d11framerate;
C2D_DrawLine(z, 239 - mt_fpsgraph[z], mt_txtcolor, z + 1, 239 - mt_fpsgraph[z + 1], mt_txtcolor, 1, 1);
}*/
2021-07-23 15:58:16 +02:00
}
2021-11-21 21:40:08 +01:00
2021-12-26 10:51:04 +01:00
bool RenderD7::DrawNFRect(float p1x, float p1y, float w, float h, u32 color, float scale)
2021-12-24 03:42:13 +01:00
{
2021-12-26 13:15:33 +01:00
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);
2021-12-24 03:42:13 +01:00
return true;
}
2022-04-16 23:11:12 +02:00
RenderD7::DSP_NF::DSP_NF()
{
}
void RenderD7::DSP_NF::Draw(void) const
{
RenderD7::OnScreen(Top);
RenderD7::DrawRect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111"));
RenderD7::DrawRect(0, 0, 20, 20, RenderD7::Color::Hex("#cccccc"));
}
void RenderD7::DSP_NF::Logic()
{
for (int i = 0; i < 10*60; i++)
{
msgposy--;
if (msgposy < 240 - 70)
{
msgposy = 240 - 70;
}
}
this->Kill();
}
void OvlHandler()
{
//for (int i = 0; i < (int)overlays.size(); i++)
//{
/*if (!overlays[i].IsKilled())
{
overlays[i].Draw();
overlays[i].Logic();
}
if (overlays[i].IsKilled())
{
overlays.erase(overlays.begin() + i);
}*/
if (!overlays.empty())
{
overlays.top()->Draw();
}
if (!overlays.empty())
{
overlays.top()->Logic();
}
if (!overlays.empty())
{
if (overlays.top()->IsKilled()) overlays.pop();
}
//}
}
2022-04-22 14:27:10 +02:00
int lp = 0;
2022-04-10 00:41:16 +02:00
void RenderD7::FrameEnd()
{
2022-04-17 23:00:37 +02:00
if (metrikd && !shouldbe_disabled)RenderD7::DrawMetrikOvl();
//OvlHandler();
2022-04-22 10:24:41 +02:00
/*if (d7_hHeld & KEY_R && d7_hDown & KEY_SELECT)
2022-04-10 10:13:22 +02:00
{
RenderD7::LoadSettings();
2022-04-22 10:24:41 +02:00
}*/
2022-04-22 14:27:10 +02:00
if (mt_dumpcsv && lp == 60)
{
std::string _mt_fps = RenderD7::GetFramerate();
std::string _mt_cpu = std::to_string(C3D_GetProcessingTime()).substr(0, 4);
std::string _mt_gpu = std::to_string(C3D_GetDrawingTime()).substr(0, 4);
std::string _mt_cmd = std::to_string(C3D_GetCmdBufUsage()).substr(0, 4);
2022-04-22 17:41:48 +02:00
mt_csv.open((mt_cname), std::ofstream::app);
2022-04-22 14:27:10 +02:00
std::string fmt_ = _mt_fps + "," + _mt_cpu + "," + _mt_gpu + "," + _mt_cmd + "\n";
mt_csv << fmt_;
mt_csv.close();
lp = 0;
}
lp++;
2022-04-10 10:13:22 +02:00
2022-04-10 00:41:16 +02:00
C3D_FrameEnd(0);
}
2022-04-10 09:55:05 +02:00
RenderD7::RSettings::RSettings()
{
2022-04-22 10:24:41 +02:00
cfgfile = std::make_unique<INI::INIFile>(cfgpath+ "/config.ini");
cfgfile->read(cfgstruct);
2022-04-25 17:29:40 +02:00
rd7settings = true;
2022-04-10 09:55:05 +02:00
}
2022-04-10 10:08:06 +02:00
RenderD7::RSettings::~RSettings()
2022-04-10 09:55:05 +02:00
{
2022-04-22 10:24:41 +02:00
cfgfile->write(cfgstruct);
2022-04-10 09:55:05 +02:00
}
void RenderD7::RSettings::Draw(void) const
{
2022-04-10 10:19:58 +02:00
RenderD7::OnScreen(Top);
2022-04-13 01:38:39 +02:00
RenderD7::DrawRect(0, 0, 400, 21, RenderD7::Color::Hex("#111111"));
RenderD7::DrawRect(0, 21, 400, 220, RenderD7::Color::Hex("#eeeeee"));
2022-04-10 15:00:06 +02:00
RenderD7::DrawText(0, 0, 0.7f, DSEVENWHITE, "RenderD7->Settings");
2022-04-23 01:47:51 +02:00
RenderD7::DrawTextLeft(400, 0, 0.7f, RenderD7::Color::Hex("#ffffff"), RENDERD7VSTRING);
2022-04-22 14:27:10 +02:00
RenderD7::DrawText(0, 30, 0.7f, DSEVENBLACK, "RD7SR: " + rd7srstate);
RenderD7::DrawText(0, 50, 0.7f, DSEVENBLACK, "Metrik to Csv: " + csvstate);
2022-04-25 17:06:35 +02:00
RenderD7::DrawText(0, 70, 0.7f, DSEVENBLACK, "Metrik Overlay: " + mtovlstate);
2022-04-23 01:47:51 +02:00
RenderD7::DrawText(0, 90, 0.7f, DSEVENBLACK, "Force FPS: " + fpsstate);
2022-04-25 17:14:47 +02:00
RenderD7::DrawText(0, 110, 0.7f, DSEVENBLACK, "Metrik Screen: " + mtscreenstate);
/*RenderD7::DrawText(0, 130, 0.7f, DSEVENBLACK, "Metrik Text RGB: " + mttxtcolstate);
2022-04-23 01:47:51 +02:00
RenderD7::DrawText(0, 150, 0.7f, DSEVENBLACK, "Metrik Alpha: " + mtcola);
2022-04-25 17:14:47 +02:00
RenderD7::DrawText(0, 170, 0.7f, DSEVENBLACK, "Metrik Text Alpha: " + mttxtcola);*/
2022-04-13 01:38:39 +02:00
RenderD7::OnScreen(Bottom);
2022-04-23 01:47:51 +02:00
std::string verc = "Config Version: ";
verc += CFGVER;
2022-04-13 01:38:39 +02:00
RenderD7::DrawRect(0, 0, 320, 240, RenderD7::Color::Hex("#eeeeee"));
2022-04-23 01:47:51 +02:00
RenderD7::DrawText(0, 0, 0.7f, RenderD7::Color::Hex("#111111"), verc);
2022-04-13 01:38:39 +02:00
RenderD7::DrawTObjects(buttons, RenderD7::Color::Hex("#111111"), RenderD7::Color::Hex("#eeeeee"));
2022-04-10 09:55:05 +02:00
}
2022-04-23 01:47:51 +02:00
std::string Kbd(int lenght, SwkbdType tp)
{
RenderD7::FrameEnd();
SwkbdState state;
char temp[lenght + 1] = { 0 };
2022-04-23 14:46:07 +02:00
2022-04-23 01:47:51 +02:00
swkbdInit(&state, SwkbdType::SWKBD_TYPE_NUMPAD, 2, lenght);
2022-04-23 14:46:07 +02:00
swkbdSetValidation(&state, SWKBD_NOTBLANK_NOTEMPTY, SWKBD_FILTER_PROFANITY, 0);
2022-04-23 01:47:51 +02:00
SwkbdButton ret = swkbdInputText(&state, temp, sizeof(temp));
2022-04-23 14:49:49 +02:00
temp[lenght] = '\0';
2022-04-23 01:47:51 +02:00
return (ret == SWKBD_BUTTON_CONFIRM ? temp : "60");
}
2022-04-10 10:08:06 +02:00
void RenderD7::RSettings::Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch)
2022-04-10 09:55:05 +02:00
{
2022-04-16 11:24:15 +02:00
rd7srstate = rd7_superreselution ? "true" : "false";
2022-04-22 14:27:10 +02:00
csvstate = mt_dumpcsv ? "true" : "false";
2022-04-25 17:06:35 +02:00
mtovlstate = metrikd ? "true" : "false";
2022-04-25 17:14:47 +02:00
fpsstate = cfgstruct["settings"]["forceFrameRate"];
2022-04-25 18:30:33 +02:00
mtscreenstate = mt_screen ? "Bottom" : "Top";
2022-04-25 19:24:24 +02:00
if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[0]) && !metrikd)
2022-04-16 11:24:15 +02:00
{
RenderD7::ToggleRD7SR();
2022-04-25 17:14:47 +02:00
cfgstruct["settings"]["super-reselution"] = rd7_superreselution ? "1" : "0";
2022-04-16 11:24:15 +02:00
}
2022-04-22 20:37:59 +02:00
if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[1]))
2022-04-22 14:27:10 +02:00
{
mt_dumpcsv = mt_dumpcsv ? false : true;
2022-04-23 01:14:49 +02:00
cfgstruct["metrik-settings"]["dumpcsv"] = mt_dumpcsv ? "1" : "0";
2022-04-22 14:27:10 +02:00
if (mt_dumpcsv)
{
2022-04-22 21:03:58 +02:00
mt_cname = csvpc;
mt_cname += "/";
mt_cname += Date();
mt_cname += ".csv";
2022-04-22 14:27:10 +02:00
FILE* logfile = fopen((mt_cname.c_str()), "w");
fclose(logfile);
2022-04-22 20:20:11 +02:00
mt_csv.open((mt_cname), std::ofstream::app);
2022-04-22 14:27:10 +02:00
mt_csv << "FPS,CPU,GPU,CMD\n";
mt_csv.close();
}
}
2022-04-22 20:37:59 +02:00
if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[2]))
2022-04-22 14:27:10 +02:00
{
2022-04-25 17:06:35 +02:00
metrikd = metrikd ? false : true;
2022-04-25 19:29:57 +02:00
cfgstruct["metrik-settings"]["enableoverlay"] = metrikd ? "1" : "0";
2022-04-22 14:27:10 +02:00
}
2022-04-25 19:24:24 +02:00
if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[3]) && !metrikd)
2022-04-23 01:47:51 +02:00
{
cfgstruct["settings"]["forceFrameRate"] = Kbd(2, SWKBD_TYPE_NUMPAD);
}
2022-04-25 17:29:40 +02:00
if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[4]))
{
mt_screen = mt_screen ? 0 : 1;
2022-04-25 18:30:33 +02:00
cfgstruct["metrik-settings"]["screen"] = mt_screen ? "1" : "0";
2022-04-25 17:29:40 +02:00
}
2022-04-10 15:12:04 +02:00
if (d7_hDown & KEY_B)
2022-04-10 09:55:05 +02:00
{
2022-04-22 10:24:41 +02:00
cfgfile->write(cfgstruct);
2022-04-25 17:29:40 +02:00
rd7settings = false;
2022-04-10 09:55:05 +02:00
RenderD7::Scene::Back();
}
}
2022-04-10 10:19:58 +02:00
void RenderD7::LoadSettings(){
2022-04-10 10:09:43 +02:00
RenderD7::Scene::Load(std::make_unique<RenderD7::RSettings>());
}
2022-04-16 23:11:12 +02:00
void RenderD7::AddOvl(std::unique_ptr<RenderD7::Ovl> overlay)
2022-04-10 00:59:30 +02:00
{
2022-04-16 23:11:12 +02:00
overlays.push(std::move(overlay));
}
2022-04-10 01:17:34 +02:00
2022-04-23 01:00:19 +02:00
RenderD7::Console::Console()
2021-11-27 11:23:44 +01:00
{
2021-11-27 11:34:32 +01:00
this->x = 0;
this->y = 0;
this->w = 320;
this->h = 240;
this->color = {0, 0, 0, 255};
2021-11-27 11:23:44 +01:00
}
RenderD7::Console::Console(int x, int y, int w, int h, u8 a)
2021-11-21 21:40:08 +01:00
{
2021-11-27 11:34:32 +01:00
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->color = {0, 0, 0, a};
2021-11-21 21:40:08 +01:00
}
2022-04-10 01:13:16 +02:00
RenderD7::Console::Console(int x, int y, int w, int h, RenderD7::Color::rgba col)
2021-11-21 21:40:08 +01:00
{
2021-11-27 11:34:32 +01:00
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->color = col;
2021-11-21 21:40:08 +01:00
}
2022-04-10 01:13:16 +02:00
RenderD7::Console::Console(int x, int y, int w, int h, std::string name, RenderD7::Color::rgba col, RenderD7::Color::rgba barcol, RenderD7::Color::rgba outlinecol)
2021-11-21 21:40:08 +01:00
{
2021-11-27 11:34:32 +01:00
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->color = col;
this->outlinecol = outlinecol;
this->barcolor = barcol;
this->m_name = name;
2021-11-21 21:40:08 +01:00
}
RenderD7::Console::~Console()
{
}
void RenderD7::Console::On(C3D_RenderTarget *t_cscreen)
{
this->cscreen = t_cscreen;
}
2022-04-10 01:09:46 +02:00
bool RenderD7::Console::Update()
2021-11-21 21:40:08 +01:00
{
2021-11-27 11:34:32 +01:00
bool dr_sc = true;
return dr_sc;
2021-11-21 21:40:08 +01:00
}
2022-04-23 01:00:19 +02:00
2022-04-18 14:41:51 +02:00
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 = time(NULL);
struct tm* timeStruct = gmtime((const time_t*)&unixTime);
return RenderD7::FormatString("%02i:%02i:%02i", timeStruct->tm_hour, timeStruct->tm_min, timeStruct->tm_sec);
}