/** * This file is part of RenderD7 * Copyright (C) 2021-2024 NPI-D7, tobid7 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include namespace RenderD7 { R2Base::R2Base() { this->font = Font::New(); } void R2Base::SetFont(Font::Ref fnt) { if (!fnt) return; this->font = fnt; } Font::Ref R2Base::GetFont() { return this->font; } void R2Base::DefaultFont() { this->font->Unload(); } void R2Base::DrawNextLined() { this->next_lined = true; } void R2Base::OnScreen(R2Screen screen) { if (screen < 0 || screen > R2Screen_Top) return; this->current_screen = screen; } void R2Base::SetTextSize(float szs) { text_size = szs; } void R2Base::DefaultTextSize() { text_size = default_text_size; } float R2Base::GetTextSize() { return text_size; } R2Screen R2Base::GetCurrentScreen() { return current_screen; } R7Vec2 R2Base::GetTextDimensions(const std::string& text) { C2D_TextBufClear(rd7i_d2_dimbuf); float w = 0, h = 0; C2D_Text c2dtext; C2D_TextFontParse(&c2dtext, font->Ptr(), rd7i_d2_dimbuf, text.c_str()); C2D_TextGetDimensions(&c2dtext, this->text_size, this->text_size, &w, &h); return R7Vec2(w, h); } // Main Processing of Draw Calls void R2Base::Process() { for (auto& it : this->commands) { if (it.type <= 0 || it.type > 3) { // Skip continue; } C2D_SceneBegin(it.Screen ? rd7_top : rd7_bottom); if (it.type == 1) { // Rect if (it.lined) { C2D_DrawLine(it.pos.x, it.pos.y, it.clr, it.pos.x + it.pszs.x, it.pos.y, it.clr, 1.f, 0.5f); C2D_DrawLine(it.pos.x, it.pos.y, it.clr, it.pos.x, it.pos.y + it.pszs.y, it.clr, 1.f, 0.5f); C2D_DrawLine(it.pos.x + it.pszs.x, it.pos.y, it.clr, it.pos.x + it.pszs.x, it.pos.y + it.pszs.y, it.clr, 1.f, 0.5f); C2D_DrawLine(it.pos.x, it.pos.y + it.pszs.y, it.clr, it.pos.x + it.pszs.x, it.pos.y + it.pszs.y, it.clr, 1.f, 0.5f); } else { C2D_DrawRectSolid(it.pos.x, it.pos.y, 0.5, it.pszs.x, it.pszs.y, it.clr); } } else if (it.type == 2) { // Triangle if (it.lined) { C2D_DrawLine(it.pos.x, it.pos.y, it.clr, it.pszs.x, it.pszs.y, it.clr, 1, 0.5f); C2D_DrawLine(it.pos.x, it.pos.y, it.clr, it.ap.x, it.ap.y, it.clr, 1, 0.5f); C2D_DrawLine(it.pszs.x, it.pszs.y, it.clr, it.ap.x, it.ap.y, it.clr, 1, 0.5f); } else { C2D_DrawTriangle(it.pos.x, it.pos.y, it.clr, it.pszs.x, it.pszs.y, it.clr, it.ap.x, it.ap.y, it.clr, 0.5); } } else if (it.type == 3) { // Text // little patch for a freeze if (it.text.length() < 1) continue; if (it.pszs.x == 0.0f) { it.pszs.x = it.Screen == R2Screen_Top ? 400 : 320; } if (it.pszs.y == 0.0f) { it.pszs.y = 240; } std::string edit_text = it.text; if (edit_text.substr(it.text.length() - 1) != "\n") edit_text.append("\n"); // Add \n to end if not exist int line = 0; // if (it.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 (it.flags & RD7TextFlags_Short) // current_line = GetShortedText(current_line, it.pszs.x - it.pos.x); R7Vec2 newpos = it.pos; // Check Flags R7Vec2 dim = this->GetTextDimensions(current_line); if (it.flags & RD7TextFlags_AlignRight) newpos.x = newpos.x - dim.x; if (it.flags & RD7TextFlags_AlignMid) // Offset by inpos newpos.x = (it.pszs.x * 0.5) - (dim.x * 0.5) + it.pos.x; if (it.flags & RD7TextFlags_Scroll) { // Scroll Text // Look into Old Draw2 Code // TODO: Create Code for this } if (rd7_debugging) { this->DrawNextLined(); this->AddRect(newpos, dim, 0xff0000ff); } C2D_Text c2dtext; C2D_TextFontParse(&c2dtext, font->Ptr(), rd7i_text_buffer, current_line.c_str()); C2D_TextOptimize(&c2dtext); if (it.flags & RD7TextFlags_Shaddow) // performance Killer xd C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x + 1 + (dim.y * line), newpos.y + 1, 0.5, this->text_size, this->text_size, RenderD7::ThemeActive()->Get(RD7Color_TextDisabled)); C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x, newpos.y + (dim.y * line), 0.5, this->text_size, this->text_size, it.clr); edit_text = edit_text.substr(edit_text.find('\n') + 1); line++; } } } this->commands.clear(); } void R2Base::AddRect(R7Vec2 pos, R7Vec2 size, RD7Color clr) { R2Cmd cmd; cmd.pos = pos; cmd.pszs = size; cmd.clr = RenderD7::ThemeActive()->Get(clr); cmd.type = 1; // Rect // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } void R2Base::AddRect(R7Vec2 pos, R7Vec2 size, unsigned int clr) { R2Cmd cmd; cmd.pos = pos; cmd.pszs = size; cmd.clr = clr; cmd.type = 1; // Rect // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } void R2Base::AddTriangle(R7Vec2 pos0, R7Vec2 pos1, R7Vec2 pos2, RD7Color clr) { R2Cmd cmd; cmd.pos = pos0; cmd.pszs = pos1; cmd.ap = pos2; cmd.clr = RenderD7::ThemeActive()->Get(clr); cmd.type = 2; // Triangle // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } void R2Base::AddTriangle(R7Vec2 pos0, R7Vec2 pos1, R7Vec2 pos2, unsigned int clr) { R2Cmd cmd; cmd.pos = pos0; cmd.pszs = pos1; cmd.ap = pos2; cmd.clr = clr; cmd.type = 2; // Triangle // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } void R2Base::AddText(R7Vec2 pos, const std::string& text, RD7Color clr, RD7TextFlags flags, R7Vec2 tmb) { R2Cmd cmd; cmd.pos = pos; cmd.pszs = tmb; cmd.clr = RenderD7::ThemeActive()->Get(clr); cmd.flags = flags; cmd.text = text; cmd.type = 3; // Text // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } void R2Base::AddText(R7Vec2 pos, const std::string& text, unsigned int clr, RD7TextFlags flags, R7Vec2 tmb) { R2Cmd cmd; cmd.pos = pos; cmd.pszs = tmb; cmd.clr = clr; cmd.flags = flags; cmd.text = text; cmd.type = 3; // Text // Just assign current screen as bottom is 0 (false) // and Top and TopRight are !0 (true) cmd.Screen = current_screen; if (this->next_lined) { cmd.lined = true; this->next_lined = false; } this->commands.push_back(cmd); } } // namespace RenderD7