split screen mode for fs. fix game dump. scrolling text for fs, progress, menu base. display icon when dumping.
This commit is contained in:
@@ -87,11 +87,19 @@ auto ProgressBox::Draw(NVGcontext* vg, Theme* theme) -> void {
|
||||
const auto offset = m_offset;
|
||||
const auto speed = m_speed;
|
||||
const auto last_offset = m_last_offset;
|
||||
auto image = m_image;
|
||||
|
||||
if (m_is_image_pending) {
|
||||
FreeImage();
|
||||
image = m_image = m_image_pending;
|
||||
m_image_pending = 0;
|
||||
m_is_image_pending = false;
|
||||
}
|
||||
mutexUnlock(&m_mutex);
|
||||
|
||||
if (!image_data.empty()) {
|
||||
FreeImage();
|
||||
m_image = nvgCreateImageMem(vg, 0, image_data.data(), image_data.size());
|
||||
image = m_image = nvgCreateImageMem(vg, 0, image_data.data(), image_data.size());
|
||||
m_own_image = true;
|
||||
}
|
||||
|
||||
@@ -108,8 +116,8 @@ auto ProgressBox::Draw(NVGcontext* vg, Theme* theme) -> void {
|
||||
nvgSave(vg);
|
||||
nvgIntersectScissor(vg, GetX(), GetY(), GetW(), GetH());
|
||||
|
||||
if (m_image) {
|
||||
gfx::drawImage(vg, GetX() + 30, GetY() + 30, 128, 128, m_image, 5);
|
||||
if (image) {
|
||||
gfx::drawImage(vg, GetX() + 25, GetY() + 25, 120, 120, image, 5);
|
||||
}
|
||||
|
||||
// shapes.
|
||||
@@ -152,9 +160,21 @@ auto ProgressBox::Draw(NVGcontext* vg, Theme* theme) -> void {
|
||||
}
|
||||
|
||||
gfx::drawTextArgs(vg, center_x, m_pos.y + 40, 24, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), m_action.c_str());
|
||||
gfx::drawTextArgs(vg, center_x, m_pos.y + 100, 22, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), title.c_str());
|
||||
|
||||
const auto draw_text = [&](ScrollingText& scroll, const std::string& txt, float y, float size, float pad, ThemeEntryID id){
|
||||
float bounds[4];
|
||||
nvgFontSize(vg, size);
|
||||
gfx::textBounds(vg, 0, 0, bounds, txt.c_str());
|
||||
|
||||
const auto min_x = GetX() + pad;
|
||||
const auto title_x = std::max(min_x, center_x - (bounds[2] - bounds[0]) / 2);
|
||||
|
||||
scroll.Draw(vg, true, title_x, y, GetW() - pad * 2, size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->GetColour(id), txt.c_str());
|
||||
};
|
||||
|
||||
draw_text(m_scroll_title, title, m_pos.y + 100, 22, 160, ThemeEntryID_TEXT);
|
||||
if (!transfer.empty()) {
|
||||
gfx::drawTextArgs(vg, center_x, m_pos.y + 150, 18, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT_INFO), "%s", transfer.c_str());
|
||||
draw_text(m_scroll_transfer, transfer, m_pos.y + 160, 18, 30, ThemeEntryID_TEXT_INFO);
|
||||
}
|
||||
|
||||
nvgRestore(vg);
|
||||
@@ -189,6 +209,14 @@ auto ProgressBox::UpdateTransfer(s64 offset, s64 size) -> ProgressBox& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto ProgressBox::SetImage(int image) -> ProgressBox& {
|
||||
mutexLock(&m_mutex);
|
||||
m_image_pending = image;
|
||||
m_is_image_pending = true;
|
||||
mutexUnlock(&m_mutex);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto ProgressBox::SetImageData(std::vector<u8>& data) -> ProgressBox& {
|
||||
mutexLock(&m_mutex);
|
||||
std::swap(m_image_data, data);
|
||||
@@ -219,24 +247,24 @@ auto ProgressBox::ShouldExitResult() -> Result {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
auto ProgressBox::CopyFile(fs::Fs* fs, const fs::FsPath& src_path, const fs::FsPath& dst_path) -> Result {
|
||||
auto ProgressBox::CopyFile(fs::Fs* fs_src, fs::Fs* fs_dst, const fs::FsPath& src_path, const fs::FsPath& dst_path) -> Result {
|
||||
fs::File src_file;
|
||||
R_TRY(fs->OpenFile(src_path, FsOpenMode_Read, &src_file));
|
||||
ON_SCOPE_EXIT(fs->FileClose(&src_file));
|
||||
R_TRY(fs_src->OpenFile(src_path, FsOpenMode_Read, &src_file));
|
||||
ON_SCOPE_EXIT(fs_src->FileClose(&src_file));
|
||||
|
||||
s64 src_size;
|
||||
R_TRY(fs->FileGetSize(&src_file, &src_size));
|
||||
R_TRY(fs_src->FileGetSize(&src_file, &src_size));
|
||||
|
||||
// this can fail if it already exists so we ignore the result.
|
||||
// if the file actually failed to be created, the result is implicitly
|
||||
// handled when we try and open it for writing.
|
||||
fs->CreateFile(dst_path, src_size, 0);
|
||||
fs_dst->CreateFile(dst_path, src_size, 0);
|
||||
|
||||
fs::File dst_file;
|
||||
R_TRY(fs->OpenFile(dst_path, FsOpenMode_Write, &dst_file));
|
||||
ON_SCOPE_EXIT(fs->FileClose(&dst_file));
|
||||
R_TRY(fs_dst->OpenFile(dst_path, FsOpenMode_Write, &dst_file));
|
||||
ON_SCOPE_EXIT(fs_dst->FileClose(&dst_file));
|
||||
|
||||
R_TRY(fs->FileSetSize(&dst_file, src_size));
|
||||
R_TRY(fs_dst->FileSetSize(&dst_file, src_size));
|
||||
|
||||
s64 offset{};
|
||||
std::vector<u8> buf(1024*1024*4); // 4MiB
|
||||
@@ -245,10 +273,10 @@ auto ProgressBox::CopyFile(fs::Fs* fs, const fs::FsPath& src_path, const fs::FsP
|
||||
R_TRY(ShouldExitResult());
|
||||
|
||||
u64 bytes_read;
|
||||
R_TRY(fs->FileRead(&src_file, offset, buf.data(), buf.size(), 0, &bytes_read));
|
||||
R_TRY(fs_src->FileRead(&src_file, offset, buf.data(), buf.size(), 0, &bytes_read));
|
||||
Yield();
|
||||
|
||||
R_TRY(fs->FileWrite(&dst_file, offset, buf.data(), bytes_read, FsWriteOption_None));
|
||||
R_TRY(fs_dst->FileWrite(&dst_file, offset, buf.data(), bytes_read, FsWriteOption_None));
|
||||
Yield();
|
||||
|
||||
UpdateTransfer(offset, src_size);
|
||||
@@ -258,6 +286,10 @@ auto ProgressBox::CopyFile(fs::Fs* fs, const fs::FsPath& src_path, const fs::FsP
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
auto ProgressBox::CopyFile(fs::Fs* fs, const fs::FsPath& src_path, const fs::FsPath& dst_path) -> Result {
|
||||
return CopyFile(fs, fs, src_path, dst_path);
|
||||
}
|
||||
|
||||
auto ProgressBox::CopyFile(const fs::FsPath& src_path, const fs::FsPath& dst_path) -> Result {
|
||||
fs::FsNativeSd fs;
|
||||
R_TRY(fs.GetFsOpenResult());
|
||||
|
||||
Reference in New Issue
Block a user