Fix UI7 Scrolling
Add Installer
Add Scissor to Draw2 (beta)
Fix IDB for Net code
This commit is contained in:
tobid7 2024-05-24 15:51:39 +02:00
parent 6d7781b209
commit 14368abae7
12 changed files with 306 additions and 66 deletions

View File

@ -11,7 +11,7 @@ RENDERD7_SRC := RenderD7/source RenderD7/external
RENDERD7_INC := RenderD7/include
# Libraries used for RenderD7
# if you already use -lm, -lctru etc place a # before -lm
RENDERD7_LIBS := -lcurl -lm -lcitro2dd -lcitro3d -lctru
RENDERD7_LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lz -lm -lcitro2dd -lcitro3d -lctru
RENDERD7_FLAGS := -DRENDERD7_MEMTRACK=1
```
Now you need to add it to your sources and includes

View File

@ -24,6 +24,7 @@
#include <renderd7/FileSystem.hpp>
#include <renderd7/Hid.hpp>
#include <renderd7/Image.hpp>
#include <renderd7/Installer.hpp>
#include <renderd7/Message.hpp>
#include <renderd7/Net.hpp>
#include <renderd7/Overlays.hpp>

View File

@ -52,6 +52,8 @@ void TextFont(Font::Ref fnt);
void TextFontRestore();
void TextDefaultFont();
namespace Draw2 {
void Scissor(R7Vec2 pos, R7Vec2 size);
void ScissorReset();
void Rect(R7Vec2 pos, R7Vec2 size, unsigned int color, int t = 1);
void RectFilled(R7Vec2 pos, R7Vec2 size, Color4 colors);
void RectFilledSolid(R7Vec2 pos, R7Vec2 size, unsigned int color);

View File

@ -0,0 +1,25 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
namespace RenderD7 {
Result InstallCia(const std::string& path, bool self);
}

View File

@ -75,6 +75,7 @@ extern bool rd7i_idb_running;
extern bool rd7i_graphics_on;
extern bool rd7i_amdt;
extern void* rd7i_soc_buf;
extern bool rd7i_is_am_init;
RenderD7::Net::Error rd7i_soc_init();
void rd7i_soc_deinit();

View File

@ -74,7 +74,7 @@ RENDERD7_SRC := ../source ../external
RENDERD7_INC := ../include
# Libraries used for RenderD7
# if you already use -lm, -lctru etc place a # before -lm
RENDERD7_LIBS := -lcurl -lm -lcitro2dd -lcitro3d -lctru
RENDERD7_LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lz -lm -lcitro2dd -lcitro3d -lctru
RENDERD7_FLAGS := -DRENDERD7_MEMTRACK=1
TARGET := rd7tf
BUILD := build

View File

@ -150,6 +150,12 @@ std::string TextShort(const std::string &in, int max_len) {
}
namespace Draw2 {
void Scissor(R7Vec2 pos, R7Vec2 size) {
// TODO: Seems not correct yet
C3D_SetScissor(GPU_SCISSOR_NORMAL, pos.y, pos.x, size.y - pos.y,
pos.x + size.x);
}
void ScissorReset() { C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); }
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);

161
source/Installer.cpp Normal file
View File

@ -0,0 +1,161 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*/
#include <3ds.h>
#include <renderd7/Installer.hpp>
#include <renderd7/internal_db.hpp>
namespace RenderD7 {
Result DeletePrevious(u64 id, FS_MediaType mt) {
if (!rd7i_is_am_init) return -1;
u32 num_titles = 0;
Result ret = AM_GetTitleCount(mt, &num_titles);
if (R_FAILED(ret)) {
return ret;
}
u32 read_titles = 0;
auto ids = new u64[num_titles];
ret = AM_GetTitleList(&read_titles, mt, num_titles, ids);
if (R_FAILED(ret)) {
delete[] ids;
return ret;
}
for (u32 i = 0; i < read_titles; i++) {
if (ids[i] == id) {
ret = AM_DeleteAppTitle(mt, id);
break;
}
}
delete[] ids;
if (R_FAILED(ret)) {
return ret;
}
return 0;
}
FS_MediaType GetTitleDest(u64 id) {
u16 platform = (u16)((id >> 48) & 0xFFFF);
u16 category = (u16)((id >> 32) & 0xFFFF);
u8 variation = (u8)(id & 0xFF);
/* DSiWare 3DS DSiWare, System, DLP
* Application System Title */
return platform == 0x0003 || (platform == 0x0004 &&
((category & 0x8011) != 0 ||
(category == 0x0000 && variation == 0x02)))
? MEDIATYPE_NAND
: MEDIATYPE_SD;
}
/* Variables. */
u64 rd7i_install_size = 0, rd7i_install_offset = 0;
Result InstallCia(const std::string& path, bool self) {
if (!rd7i_is_am_init) return -1;
u32 bytes_read = 0, bytes_written;
rd7i_install_size = 0, rd7i_install_offset = 0;
u64 size = 0;
Handle cia, file;
AM_TitleEntry info;
Result ret = 0;
FS_MediaType media = MEDIATYPE_SD;
std::string pth;
if (path[0] == '/') {
pth = path;
} else if (path.substr(0, 5) == "sdmc:") {
pth = path.substr(5);
} else {
return -1;
}
ret = FSUSER_OpenFileDirectly(&file, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""),
fsMakePath(PATH_ASCII, pth.c_str()),
FS_OPEN_READ, 0);
if (R_FAILED(ret)) {
return ret;
}
ret = AM_GetCiaFileInfo(media, &info, file);
if (R_FAILED(ret)) {
return ret;
}
media = GetTitleDest(info.titleID);
if (!self) {
ret = DeletePrevious(info.titleID, media);
if (R_FAILED(ret)) return ret;
}
ret = FSFILE_GetSize(file, &size);
if (R_FAILED(ret)) {
return ret;
}
ret = AM_StartCiaInstall(media, &cia);
if (R_FAILED(ret)) {
return ret;
}
u32 toRead = 0x200000;
u8* buf = new u8[toRead];
if (buf == nullptr) {
return -1;
}
rd7i_install_size = size;
do {
FSFILE_Read(file, &bytes_read, rd7i_install_offset, buf, toRead);
FSFILE_Write(cia, &bytes_written, rd7i_install_offset, buf, toRead,
FS_WRITE_FLUSH);
rd7i_install_offset += bytes_read;
} while (rd7i_install_offset < rd7i_install_size);
delete[] buf;
ret = AM_FinishCiaInstall(cia);
if (R_FAILED(ret)) {
return ret;
}
ret = FSFILE_Close(file);
if (R_FAILED(ret)) {
return ret;
}
if (self) {
aptSetChainloaderToSelf();
}
return 0;
}
} // namespace RenderD7

View File

@ -32,7 +32,7 @@
static RenderD7::Net::Error rd7i_check_wifi() {
// if (rd7i_is_citra) return 0;
int s = osGetWifiStrength();
return (s == 0);
return (s == 0 ? RenderD7::Net::Error_NoWifi : 0);
}
static size_t rd7i_handle_data(char* ptr, size_t size, size_t nmemb,
@ -103,19 +103,10 @@ Error Download(const std::string& url, std::string& data) {
if (rd7i_curl_is_busy) return Error_Busy;
Error ret = rd7i_check_wifi();
if (ret != 0) {
if (ret == 1) {
return Error_NoWifi;
} else {
return ret;
}
return ret;
}
rd7i_curl_is_busy = true;
rd7i_net_dl_spec.Reset();
ret = rd7i_soc_init();
if (ret) {
rd7i_curl_is_busy = false;
return ret;
}
auto hnd = curl_easy_init();
rd7i_setup_curl_context(hnd, url, &data, true);
@ -125,13 +116,11 @@ Error Download(const std::string& url, std::string& data) {
if (curl_res != CURLE_OK) {
data.clear();
rd7i_soc_deinit();
rd7i_curl_is_busy = false;
return ((static_cast<Error>(curl_res) << 32) |
static_cast<Error>(Error_Curl));
}
rd7i_soc_deinit();
rd7i_curl_is_busy = false;
return 0;
}
@ -140,20 +129,10 @@ Error Download2File(const std::string& url, const std::string& path) {
if (rd7i_curl_is_busy) return Error_Busy;
Error ret = rd7i_check_wifi();
if (ret != 0) {
if (ret == 1) {
return Error_NoWifi;
} else {
return ret;
}
return ret;
}
rd7i_curl_is_busy = true;
rd7i_net_dl_spec.Reset();
ret = rd7i_soc_init();
if (ret) {
rd7i_curl_is_busy = false;
return ret;
}
// std::filesystem::create_directories(
// std::filesystem::path(path).remove_filename());
std::ofstream file(path, std::ios::binary);
@ -171,7 +150,6 @@ Error Download2File(const std::string& url, const std::string& path) {
file.close();
if (curl_res != CURLE_OK) {
rd7i_soc_deinit();
if (RenderD7::FS::FileExist(path)) {
std::filesystem::remove(path);
}
@ -180,7 +158,6 @@ Error Download2File(const std::string& url, const std::string& path) {
static_cast<Error>(Error_Curl));
}
rd7i_soc_deinit();
rd7i_curl_is_busy = false;
return 0;
}
@ -190,11 +167,7 @@ Error GitDownloadRelease(const std::string& url, const std::string& asset_name,
if (rd7i_apir_is_busy) return Error_Busy;
Error ret = rd7i_check_wifi();
if (ret != 0) {
if (ret == 1) {
return Error_NoWifi;
} else {
return ret;
}
return ret;
}
rd7i_apir_is_busy = true;
std::regex parse("github\\.com\\/(.+)\\/(.+)");
@ -253,11 +226,7 @@ Error JsonApiRequest(const std::string& api_url, nlohmann::json& res) {
if (rd7i_apir_is_busy) return Error_Busy;
Error ret = rd7i_check_wifi();
if (ret != 0) {
if (ret == 1) {
return Error_NoWifi;
} else {
return ret;
}
return ret;
}
rd7i_apir_is_busy = true;

View File

@ -296,12 +296,20 @@ bool Button(const std::string &label, R7Vec2 size) {
}
RD7Color btn = RD7Color_Button;
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, size), 1));
UI7CtxCursorMove(size);
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return false;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 ||
(pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return false;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, size), 1));
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, size)) {
@ -318,6 +326,7 @@ bool Button(const std::string &label, R7Vec2 size) {
RenderD7::TextColorByBg(btn);
RenderD7::Draw2::Text(pos, label);
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::Draw2::ScissorReset();
return ret;
}
@ -330,12 +339,18 @@ void Checkbox(const std::string &label, bool &c) {
RD7Color bg = RD7Color_FrameBg;
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
UI7CtxCursorMove(inp);
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 ||
(pos.y + cbs.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, inp)) {
@ -355,39 +370,55 @@ void Checkbox(const std::string &label, bool &c) {
RenderD7::Draw2::Text(pos + R7Vec2(cbs.x + 5, 1), label);
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, cbs + R7Vec2(txtdim.x + 5, 0)), 1));
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, cbs), 2));
RenderD7::Draw2::ScissorReset();
}
void Label(const std::string &label, RD7TextFlags flags) {
if (!UI7CtxValidate()) return;
R7Vec2 textdim = RenderD7::GetTextDimensions(label);
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
// Remove some y offset cause texts have some offset
UI7CtxCursorMove(textdim - R7Vec2(0, 4));
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 ||
(pos.y + textdim.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
float tbh = RenderD7::TextGetSize() * 40;
if (flags & RD7TextFlags_AlignRight) {
UI7CtxRegObj(UI7OBJ(R7Vec4(pos - R7Vec2(textdim.x, 0), textdim), 1));
} else {
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, textdim), 1));
}
RenderD7::TextColorByBg(
(pos.y + textdim.y < tbh ? RD7Color_Header : RD7Color_Background));
RenderD7::Draw2::Text(pos, label, flags);
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::Draw2::ScissorReset();
}
void Progressbar(float value) {
if (!UI7CtxValidate()) return;
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
R7Vec2 size = R7Vec2((rd7i_current_screen ? 400 : 320) - (pos.x * 2), 20);
UI7CtxCursorMove(size);
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 ||
(pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
RenderD7::Draw2::RFS(pos, size, RenderD7::StyleColor(RD7Color_FrameBg));
RenderD7::Draw2::RFS(pos + R7Vec2(2, 2), size - R7Vec2(4, 4),
@ -396,19 +427,28 @@ void Progressbar(float value) {
RenderD7::Draw2::RFS(pos + R7Vec2(2, 2),
R7Vec2((size.x - 4) * value, size.y - 4),
RenderD7::StyleColor(RD7Color_Progressbar));
RenderD7::Draw2::ScissorReset();
}
void Image(RenderD7::Image *img) {
if (!UI7CtxValidate()) return;
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
UI7CtxCursorMove(R7Vec2(img->get_size().x, img->get_size().y));
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 || (pos.y + img->get_size().y < ui7_ctx->cm->tbh - 5 &&
pb.y > ui7_ctx->cm->tbh))
return;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
UI7CtxRegObj(UI7OBJ(R7Vec4(pos, img->get_size()), 1));
RenderD7::Draw2::Image(img, pos);
RenderD7::Draw2::ScissorReset();
}
void BrowserList(const std::vector<std::string> &entrys, int &selection,
@ -477,11 +517,17 @@ void InputText(const std::string &label, std::string &text,
RD7KeyboardState kbd_state; // tmp (goes out of scope)
R7Vec2 pos = GetCursorPos();
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
UI7CtxCursorMove(inp);
if (pos.y > 240 || (pos.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
if (ui7_ctx->cm->enable_scrolling) {
R7Vec2 pb = pos;
pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset);
if (pos.y > 240 ||
(pos.y + cbs.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh))
return;
RenderD7::Draw2::Scissor(R7Vec2(0, ui7_ctx->cm->tbh),
R7Vec2(rd7i_current_screen ? 400 : 320, 240));
}
if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) &&
InBox(RenderD7::Hid::GetLastTouchPosition(), pos, inp)) {
@ -498,11 +544,13 @@ void InputText(const std::string &label, std::string &text,
RenderD7::Draw2::Text(pos + R7Vec2(5, 1), (text != "" ? text : hint));
RenderD7::UndoColorEdit(RD7Color_Text);
RenderD7::Draw2::Text(pos + R7Vec2(cbs.x + 5, 1), id->Title());
RenderD7::Draw2::ScissorReset();
}
bool BeginMenu(const std::string &title, R7Vec2 size, UI7MenuFlags flags) {
if (!UI7CtxValidate()) return false;
if (UI7CtxInMenu()) return false;
RenderD7::Draw2::ScissorReset();
auto id = UI7CtxNewID(title);
auto ret = UI7CtxBeginMenu(title);
if (!ret) return ret;
@ -564,7 +612,10 @@ bool BeginMenu(const std::string &title, R7Vec2 size, UI7MenuFlags flags) {
return ret;
}
void EndMenu() { UI7CtxEndMenu(); }
void EndMenu() {
RenderD7::Draw2::ScissorReset();
UI7CtxEndMenu();
}
void Grid(const std::string &name, const R7Vec2 &size, const R7Vec2 &entry_size,
void (*display_func)(void *, R7Vec2), void **data_array,

View File

@ -73,6 +73,7 @@ bool rd7i_graphics_on = false;
float rd7_draw2_tsm = 1.2f;
bool rd7i_amdt = false;
void *rd7i_soc_buf = nullptr;
bool rd7i_is_am_init = false;
/// Global ///
// Outdated HidApi (HidV2Patched)
@ -238,11 +239,10 @@ static bool rd7i_idb_fp = false;
void KillIdbServer() {
rd7i_idb_fp = true;
rd7i_idb_server.join(100);
rd7i_soc_deinit();
}
void ServerThread(RenderD7::Parameter param) {
if (rd7i_soc_init()) return;
if (rd7i_soc_buf == nullptr) return;
rd7i_idb_running = true;
rd7i_idb_fp = false;
atexit(KillIdbServer);

View File

@ -352,6 +352,18 @@ Result RenderD7::Init::Main(std::string app_name) {
atexit(aptExit);
romfsInit();
auto ret = rd7i_soc_init();
if (ret) {
RenderD7::PushMessage("RenderD7", "Failed to\nInit Soc!");
} else {
atexit(rd7i_soc_deinit);
}
if (R_SUCCEEDED(amInit())) {
atexit(amExit);
rd7i_is_am_init = true;
}
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
atexit(C3D_Fini);
C2D_Init((size_t)rd7_max_objects);
@ -388,6 +400,18 @@ Result RenderD7::Init::Minimal(std::string app_name) {
atexit(gfxExit);
romfsInit();
auto ret = rd7i_soc_init();
if (ret) {
RenderD7::PushMessage("RenderD7", "Failed to\nInit Soc!");
} else {
atexit(rd7i_soc_deinit);
}
if (R_SUCCEEDED(amInit())) {
atexit(amExit);
rd7i_is_am_init = true;
}
osSetSpeedupEnable(true);
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
atexit(C3D_Fini);