mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-04-25 16:15:11 -05:00
Minor work: Block home menu and exiting from tasks.
This commit is contained in:
parent
24e73971ff
commit
95cc75c41d
|
|
@ -5,7 +5,7 @@
|
|||
class AppState
|
||||
{
|
||||
public:
|
||||
AppState(void) = default;
|
||||
AppState(bool IsClosable = true) : m_IsClosable(IsClosable) {};
|
||||
virtual ~AppState() {};
|
||||
|
||||
virtual void Update(void) = 0;
|
||||
|
|
@ -23,16 +23,19 @@ class AppState
|
|||
return m_IsActive;
|
||||
}
|
||||
|
||||
// Deactivates state and allows JKSV to kill it.
|
||||
void Deactivate(void)
|
||||
{
|
||||
m_IsActive = false;
|
||||
}
|
||||
|
||||
// Tells state it has the current focus of the app.
|
||||
void GiveFocus(void)
|
||||
{
|
||||
m_HasFocus = true;
|
||||
}
|
||||
|
||||
// Takes focus away from the state.
|
||||
void TakeFocus(void)
|
||||
{
|
||||
m_HasFocus = false;
|
||||
|
|
@ -44,9 +47,17 @@ class AppState
|
|||
return m_HasFocus;
|
||||
}
|
||||
|
||||
// Returns whether or not state is closable with +.
|
||||
bool IsClosable(void) const
|
||||
{
|
||||
return m_IsClosable;
|
||||
}
|
||||
|
||||
private:
|
||||
// Whether state is still active or can be purged.
|
||||
bool m_IsActive = true;
|
||||
// Whether or not state has focus
|
||||
bool m_HasFocus = false;
|
||||
// Whether or not state should allow exiting JKSV
|
||||
bool m_IsClosable = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,39 +6,71 @@
|
|||
#include "Input.hpp"
|
||||
#include "JKSV.hpp"
|
||||
#include "SDL.hpp"
|
||||
#include "Strings.hpp"
|
||||
#include "System/Task.hpp"
|
||||
#include "UI/RenderFunctions.hpp"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <switch.h>
|
||||
#include <tuple>
|
||||
|
||||
// To do: I didn't want to accomplish this with structs, but templating it was holding me up too much.
|
||||
struct ConfirmStruct
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TaskType, typename StateType>
|
||||
template <typename TaskType, typename StateType, typename StructType>
|
||||
class ConfirmState : public AppState
|
||||
{
|
||||
public:
|
||||
// All functions using confirmation must follow this signature. The struct must be cast to the intended type for now.
|
||||
using TaskFunction = void (*)(TaskType *, std::shared_ptr<ConfirmStruct>);
|
||||
// All functions using confirmation must follow this signature.
|
||||
using TaskFunction = void (*)(TaskType *, std::shared_ptr<StructType>);
|
||||
// Constructor
|
||||
ConfirmState(std::string_view QueryString, bool HoldRequired, TaskFunction Function, std::shared_ptr<ConfirmStruct> DataStruct)
|
||||
: m_QueryString(QueryString.data()), m_Hold(HoldRequired), m_Function(Function), m_DataStruct(DataStruct) {};
|
||||
ConfirmState(std::string_view QueryString, bool HoldRequired, TaskFunction Function, std::shared_ptr<StructType> DataStruct)
|
||||
: AppState(false), m_QueryString(QueryString.data()), m_YesString(Strings::GetByName(Strings::Names::YesNo, 0)),
|
||||
m_Hold(HoldRequired), m_Function(Function), m_DataStruct(DataStruct)
|
||||
{
|
||||
appletBeginBlockingHomeButton(0);
|
||||
}
|
||||
|
||||
~ConfirmState() {};
|
||||
~ConfirmState()
|
||||
{
|
||||
appletEndBlockingHomeButton();
|
||||
}
|
||||
|
||||
void Update(void)
|
||||
{
|
||||
if (Input::ButtonPressed(HidNpadButton_A))
|
||||
if (Input::ButtonPressed(HidNpadButton_A) && !m_Hold)
|
||||
{
|
||||
AppState::Deactivate();
|
||||
JKSV::PushState(std::make_shared<StateType>(m_Function, m_DataStruct));
|
||||
}
|
||||
else if (Input::ButtonPressed(HidNpadButton_A) && m_Hold)
|
||||
{
|
||||
// Get the starting tick count and change the Yes string to the first holding string.
|
||||
m_StartingTickCount = SDL_GetTicks64();
|
||||
m_YesString = Strings::GetByName(Strings::Names::HoldingStrings, 0);
|
||||
}
|
||||
else if (Input::ButtonHeld(HidNpadButton_A) && m_Hold)
|
||||
{
|
||||
uint64_t TickCount = SDL_GetTicks64() - m_StartingTickCount;
|
||||
|
||||
// If the TickCount is >= 3 seconds, confirmed. Else, just change the string so we can see we're not holding for nothing?
|
||||
if (TickCount >= 3000)
|
||||
{
|
||||
AppState::Deactivate();
|
||||
JKSV::PushState(std::make_shared<StateType>(m_Function, m_DataStruct));
|
||||
}
|
||||
else if (TickCount >= 2000)
|
||||
{
|
||||
m_YesString = Strings::GetByName(Strings::Names::HoldingStrings, 2);
|
||||
}
|
||||
else if (TickCount >= 1000)
|
||||
{
|
||||
m_YesString = Strings::GetByName(Strings::Names::HoldingStrings, 1);
|
||||
}
|
||||
}
|
||||
else if (Input::ButtonReleased(HidNpadButton_A))
|
||||
{
|
||||
m_YesString = Strings::GetByName(Strings::Names::YesNo, 0);
|
||||
}
|
||||
else if (Input::ButtonPressed(HidNpadButton_B))
|
||||
{
|
||||
// Just deactivate and don't do anything.
|
||||
AppState::Deactivate();
|
||||
}
|
||||
}
|
||||
|
|
@ -54,15 +86,23 @@ class ConfirmState : public AppState
|
|||
// Fake buttons. Maybe real later.
|
||||
SDL::RenderLine(NULL, 280, 454, 999, 454, Colors::White);
|
||||
SDL::RenderLine(NULL, 640, 454, 640, 517, Colors::White);
|
||||
// To do: Position this better. Currently brought over from old code.
|
||||
int YesX = 458 - SDL::Text::GetWidth(22, m_YesString.c_str());
|
||||
SDL::Text::Render(NULL, YesX, 478, 22, SDL::Text::NO_TEXT_WRAP, Colors::White, m_YesString.c_str());
|
||||
SDL::Text::Render(NULL, 782, 478, 22, SDL::Text::NO_TEXT_WRAP, Colors::White, Strings::GetByName(Strings::Names::YesNo, 1));
|
||||
}
|
||||
|
||||
private:
|
||||
// Query string
|
||||
std::string m_QueryString;
|
||||
// Yes string.
|
||||
std::string m_YesString;
|
||||
// Whether or not holding is required to confirm.
|
||||
bool m_Hold;
|
||||
// For tick counting/holding
|
||||
uint64_t m_StartingTickCount = 0;
|
||||
// Function
|
||||
TaskFunction m_Function;
|
||||
// Shared ptr to data to send to confirmation function.
|
||||
std::shared_ptr<ConfirmStruct> m_DataStruct;
|
||||
std::shared_ptr<StructType> m_DataStruct;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,14 +2,22 @@
|
|||
#include "AppStates/AppState.hpp"
|
||||
#include "System/ProgressTask.hpp"
|
||||
#include <string>
|
||||
#include <switch.h>
|
||||
|
||||
class ProgressState : public AppState
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
ProgressState(void (*Function)(System::ProgressTask *, Args...), Args... Arguments)
|
||||
: m_Task(Function, std::forward<Args>(Arguments)...){};
|
||||
~ProgressState() {};
|
||||
: AppState(false), m_Task(Function, std::forward<Args>(Arguments)...)
|
||||
{
|
||||
appletBeginBlockingHomeButton(0);
|
||||
}
|
||||
|
||||
~ProgressState()
|
||||
{
|
||||
appletEndBlockingHomeButton();
|
||||
}
|
||||
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,10 @@ class SaveCreateState : public AppState
|
|||
// Pointer to user and title select
|
||||
Data::User *m_User;
|
||||
TitleSelectCommon *m_TitleSelect;
|
||||
// Menu
|
||||
UI::Menu m_SaveMenu;
|
||||
// Vector of pointers to save info we're using
|
||||
std::vector<Data::TitleInfo *> m_TitleInfoVector;
|
||||
// All instances shared these so they're static.
|
||||
// All instances shared this so they're static.
|
||||
static inline std::unique_ptr<UI::SlideOutPanel> m_SlidePanel = nullptr;
|
||||
static inline std::unique_ptr<UI::Menu> m_SaveDataMenu = nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
#pragma once
|
||||
#include "AppStates/AppState.hpp"
|
||||
#include "System/Task.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
class TaskState : public AppState
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
TaskState(void (*Function)(System::Task *, Args...), Args... Arguments) : m_Task(Function, std::forward<Args>(Arguments)...){};
|
||||
~TaskState() {};
|
||||
TaskState(void (*Function)(System::Task *, Args...), Args... Arguments)
|
||||
: AppState(false), m_Task(Function, std::forward<Args>(Arguments)...)
|
||||
{
|
||||
appletBeginBlockingHomeButton(0);
|
||||
}
|
||||
|
||||
~TaskState()
|
||||
{
|
||||
appletEndBlockingHomeButton();
|
||||
}
|
||||
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Strings
|
|||
static constexpr std::string_view MainMenuNames = "MainMenuNames";
|
||||
static constexpr std::string_view SettingsMenu = "SettingsMenu";
|
||||
static constexpr std::string_view ExtrasMenu = "ExtrasMenu";
|
||||
static constexpr std::string_view YesNo = "YesNo";
|
||||
static constexpr std::string_view HoldingStrings = "HoldingStrings";
|
||||
static constexpr std::string_view OnOff = "OnOff";
|
||||
static constexpr std::string_view BackupMenu = "BackupMenu";
|
||||
static constexpr std::string_view CopyingFiles = "CopyingFiles";
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@
|
|||
"Terminate Process",
|
||||
"Mount System Save"
|
||||
],
|
||||
"YesNo": [
|
||||
"Yes [A]",
|
||||
"No [B]"
|
||||
],
|
||||
"HoldingStrings": [
|
||||
"Hold [A]",
|
||||
"Keep Holding [A]",
|
||||
"Almost There! [A]"
|
||||
],
|
||||
"OnOff": [
|
||||
"Off",
|
||||
">On>"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include <cstring>
|
||||
|
||||
// This struct is used to pass data to Restore, Delete, and upload.
|
||||
struct TargetStruct : ConfirmStruct
|
||||
struct TargetStruct
|
||||
{
|
||||
FsLib::Path TargetPath;
|
||||
uint64_t JournalSize = 0;
|
||||
|
|
@ -44,7 +44,7 @@ static void CreateNewBackup(System::ProgressTask *Task, FsLib::Path DestinationP
|
|||
Task->Finished();
|
||||
}
|
||||
|
||||
static void RestoreBackup(System::ProgressTask *Task, std::shared_ptr<ConfirmStruct> DataStruct)
|
||||
static void RestoreBackup(System::ProgressTask *Task, std::shared_ptr<TargetStruct> DataStruct)
|
||||
{
|
||||
// Wipe the save root first.
|
||||
if (!FsLib::DeleteDirectoryRecursively(FS::DEFAULT_SAVE_PATH))
|
||||
|
|
@ -54,50 +54,45 @@ static void RestoreBackup(System::ProgressTask *Task, std::shared_ptr<ConfirmStr
|
|||
return;
|
||||
}
|
||||
|
||||
// Cast struct to what we really need.
|
||||
std::shared_ptr<TargetStruct> Data = std::static_pointer_cast<TargetStruct>(DataStruct);
|
||||
|
||||
if (FsLib::DirectoryExists(Data->TargetPath))
|
||||
if (FsLib::DirectoryExists(DataStruct->TargetPath))
|
||||
{
|
||||
FS::CopyDirectory(Data->TargetPath, FS::DEFAULT_SAVE_PATH, Data->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
FS::CopyDirectory(DataStruct->TargetPath, FS::DEFAULT_SAVE_PATH, DataStruct->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
}
|
||||
else if (std::strstr(Data->TargetPath.CString(), ".zip") != NULL)
|
||||
else if (std::strstr(DataStruct->TargetPath.CString(), ".zip") != NULL)
|
||||
{
|
||||
unzFile TargetZip = unzOpen64(Data->TargetPath.CString());
|
||||
unzFile TargetZip = unzOpen64(DataStruct->TargetPath.CString());
|
||||
if (!TargetZip)
|
||||
{
|
||||
Logger::Log("Error opening zip for reading.");
|
||||
Task->Finished();
|
||||
return;
|
||||
}
|
||||
FS::CopyZipToDirectory(TargetZip, FS::DEFAULT_SAVE_PATH, Data->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
FS::CopyZipToDirectory(TargetZip, FS::DEFAULT_SAVE_PATH, DataStruct->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
unzClose(TargetZip);
|
||||
}
|
||||
else
|
||||
{
|
||||
FS::CopyFile(Data->TargetPath, FS::DEFAULT_SAVE_PATH, Data->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
FS::CopyFile(DataStruct->TargetPath, FS::DEFAULT_SAVE_PATH, DataStruct->JournalSize, FS::DEFAULT_SAVE_MOUNT, Task);
|
||||
}
|
||||
Task->Finished();
|
||||
}
|
||||
|
||||
static void DeleteBackup(System::Task *Task, std::shared_ptr<ConfirmStruct> DataStruct)
|
||||
static void DeleteBackup(System::Task *Task, std::shared_ptr<TargetStruct> DataStruct)
|
||||
{
|
||||
std::shared_ptr<TargetStruct> Data = std::static_pointer_cast<TargetStruct>(DataStruct);
|
||||
|
||||
if (Task)
|
||||
{
|
||||
Task->SetStatus(Strings::GetByName(Strings::Names::DeletingFiles, 0), Data->TargetPath.CString());
|
||||
Task->SetStatus(Strings::GetByName(Strings::Names::DeletingFiles, 0), DataStruct->TargetPath.CString());
|
||||
}
|
||||
|
||||
if (FsLib::DirectoryExists(Data->TargetPath) && !FsLib::DeleteDirectoryRecursively(Data->TargetPath))
|
||||
if (FsLib::DirectoryExists(DataStruct->TargetPath) && !FsLib::DeleteDirectoryRecursively(DataStruct->TargetPath))
|
||||
{
|
||||
Logger::Log("Error deleting folder backup: %s", FsLib::GetErrorString());
|
||||
}
|
||||
else if (!FsLib::DeleteFile(Data->TargetPath))
|
||||
else if (!FsLib::DeleteFile(DataStruct->TargetPath))
|
||||
{
|
||||
Logger::Log("Error deleting backup: %s", FsLib::GetErrorString());
|
||||
}
|
||||
Data->CreatingState->RefreshListing();
|
||||
DataStruct->CreatingState->RefreshListing();
|
||||
Task->Finished();
|
||||
}
|
||||
|
||||
|
|
@ -163,14 +158,18 @@ void BackupMenuState::Update(void)
|
|||
{
|
||||
int Selected = m_BackupMenu->GetSelected() - 1;
|
||||
|
||||
std::shared_ptr<ConfirmStruct> DataStruct = std::make_shared<TargetStruct>();
|
||||
std::static_pointer_cast<TargetStruct>(DataStruct)->TargetPath = m_DirectoryPath / m_DirectoryListing[Selected];
|
||||
std::static_pointer_cast<TargetStruct>(DataStruct)->JournalSize = m_TitleInfo->GetJournalSize(m_SaveType);
|
||||
std::shared_ptr<TargetStruct> DataStruct(new TargetStruct);
|
||||
DataStruct->TargetPath = m_DirectoryPath / m_DirectoryListing[Selected];
|
||||
DataStruct->JournalSize = m_TitleInfo->GetJournalSize(m_SaveType);
|
||||
|
||||
std::string QueryString =
|
||||
StringUtil::GetFormattedString(Strings::GetByName(Strings::Names::BackupMenuConfirmations, 0), m_DirectoryListing[Selected]);
|
||||
|
||||
JKSV::PushState(std::make_shared<ConfirmState<System::ProgressTask, ProgressState>>(QueryString, false, RestoreBackup, DataStruct));
|
||||
JKSV::PushState(std::make_shared<ConfirmState<System::ProgressTask, ProgressState, TargetStruct>>(
|
||||
QueryString,
|
||||
Config::GetByKey(Config::Keys::HoldForRestoration),
|
||||
RestoreBackup,
|
||||
DataStruct));
|
||||
}
|
||||
else if (Input::ButtonPressed(HidNpadButton_X) && m_BackupMenu->GetSelected() > 0)
|
||||
{
|
||||
|
|
@ -178,16 +177,19 @@ void BackupMenuState::Update(void)
|
|||
int Selected = m_BackupMenu->GetSelected() - 1;
|
||||
|
||||
// Create struct to pass.
|
||||
std::shared_ptr<ConfirmStruct> DataStruct = std::make_shared<TargetStruct>();
|
||||
std::static_pointer_cast<TargetStruct>(DataStruct)->TargetPath = m_DirectoryPath / m_DirectoryListing[Selected];
|
||||
std::static_pointer_cast<TargetStruct>(DataStruct)->CreatingState = this;
|
||||
std::shared_ptr<TargetStruct> DataStruct(new TargetStruct);
|
||||
DataStruct->TargetPath = m_DirectoryPath / m_DirectoryListing[Selected];
|
||||
DataStruct->CreatingState = this;
|
||||
|
||||
// Get the string.
|
||||
std::string QueryString =
|
||||
StringUtil::GetFormattedString(Strings::GetByName(Strings::Names::BackupMenuConfirmations, 1), m_DirectoryListing[Selected]);
|
||||
|
||||
// Create/push new state.
|
||||
JKSV::PushState(std::make_shared<ConfirmState<System::Task, TaskState>>(QueryString, false, DeleteBackup, DataStruct));
|
||||
JKSV::PushState(std::make_shared<ConfirmState<System::Task, TaskState, TargetStruct>>(QueryString,
|
||||
Config::GetByKey(Config::Keys::HoldForDeletion),
|
||||
DeleteBackup,
|
||||
DataStruct));
|
||||
}
|
||||
else if (Input::ButtonPressed(HidNpadButton_B))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,18 +79,16 @@ static void CreateSaveDataFor(System::Task *Task, Data::User *TargetUser, Data::
|
|||
Task->Finished();
|
||||
}
|
||||
|
||||
SaveCreateState::SaveCreateState(Data::User *TargetUser, TitleSelectCommon *TitleSelect) : m_User(TargetUser), m_TitleSelect(TitleSelect)
|
||||
SaveCreateState::SaveCreateState(Data::User *TargetUser, TitleSelectCommon *TitleSelect)
|
||||
: m_User(TargetUser), m_TitleSelect(TitleSelect), m_SaveMenu(8, 8, 624, 22, 720)
|
||||
{
|
||||
// If these aren't null, just return since they're already initialized.
|
||||
if (m_SlidePanel && m_SaveDataMenu)
|
||||
// If the panel is null, create it.
|
||||
if (!m_SlidePanel)
|
||||
{
|
||||
return;
|
||||
// Create panel and menu.
|
||||
m_SlidePanel = std::make_unique<UI::SlideOutPanel>(640, UI::SlideOutPanel::Side::Right);
|
||||
}
|
||||
|
||||
// Create panel and menu.
|
||||
m_SlidePanel = std::make_unique<UI::SlideOutPanel>(640, UI::SlideOutPanel::Side::Right);
|
||||
m_SaveDataMenu = std::make_unique<UI::Menu>(8, 8, 624, 22, 720);
|
||||
|
||||
// Get title info vector and copy titles to menu.
|
||||
Data::GetTitleInfoByType(FsSaveDataType_Account, m_TitleInfoVector);
|
||||
|
||||
|
|
@ -99,26 +97,35 @@ SaveCreateState::SaveCreateState(Data::User *TargetUser, TitleSelectCommon *Titl
|
|||
|
||||
for (size_t i = 0; i < m_TitleInfoVector.size(); i++)
|
||||
{
|
||||
m_SaveDataMenu->AddOption(m_TitleInfoVector.at(i)->GetTitle());
|
||||
m_SaveMenu.AddOption(m_TitleInfoVector.at(i)->GetTitle());
|
||||
}
|
||||
}
|
||||
|
||||
void SaveCreateState::Update(void)
|
||||
{
|
||||
m_SlidePanel->Update(AppState::HasFocus());
|
||||
m_SaveDataMenu->Update(AppState::HasFocus());
|
||||
m_SaveMenu.Update(AppState::HasFocus());
|
||||
|
||||
if (Input::ButtonPressed(HidNpadButton_A))
|
||||
{
|
||||
Data::TitleInfo *TargetTitle = m_TitleInfoVector.at(m_SaveDataMenu->GetSelected());
|
||||
Data::TitleInfo *TargetTitle = m_TitleInfoVector.at(m_SaveMenu.GetSelected());
|
||||
JKSV::PushState(std::make_shared<TaskState>(CreateSaveDataFor, m_User, TargetTitle));
|
||||
}
|
||||
else if (Input::ButtonPressed(HidNpadButton_B))
|
||||
{
|
||||
m_SlidePanel->Close();
|
||||
}
|
||||
else if (m_SlidePanel->IsClosed())
|
||||
{
|
||||
m_SlidePanel->Reset();
|
||||
AppState::Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveCreateState::Render(void)
|
||||
{
|
||||
// Clear slide target, render menu, render slide to frame buffer.
|
||||
m_SlidePanel->ClearTarget();
|
||||
m_SaveDataMenu->Render(m_SlidePanel->Get(), AppState::HasFocus());
|
||||
m_SaveMenu.Render(m_SlidePanel->Get(), AppState::HasFocus());
|
||||
m_SlidePanel->Render(NULL, AppState::HasFocus());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ void JKSV::Update(void)
|
|||
{
|
||||
Input::Update();
|
||||
|
||||
if (Input::ButtonPressed(HidNpadButton_Plus))
|
||||
if (Input::ButtonPressed(HidNpadButton_Plus) && !m_StateVector.empty() && m_StateVector.back()->IsClosable())
|
||||
{
|
||||
m_IsRunning = false;
|
||||
}
|
||||
|
|
@ -165,7 +165,10 @@ void JKSV::Render(void)
|
|||
Strings::GetByName(Strings::Names::TranslationInfo, 0),
|
||||
Strings::GetByName(Strings::Names::TranslationInfo, 1));
|
||||
}
|
||||
// Build date
|
||||
SDL::Text::Render(NULL, 8, 700, 14, SDL::Text::NO_TEXT_WRAP, Colors::White, "v. %02d.%02d.%04d", BUILD_MON, BUILD_DAY, BUILD_YEAR);
|
||||
|
||||
// State render loop.
|
||||
if (!m_StateVector.empty())
|
||||
{
|
||||
for (auto &CurrentState : m_StateVector)
|
||||
|
|
@ -174,8 +177,6 @@ void JKSV::Render(void)
|
|||
}
|
||||
}
|
||||
|
||||
SDL::Text::Render(NULL, 8, 700, 14, SDL::Text::NO_TEXT_WRAP, Colors::White, "v. %02d.%02d.%04d", BUILD_MON, BUILD_DAY, BUILD_YEAR);
|
||||
|
||||
SDL::FrameEnd();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
int main(void)
|
||||
{
|
||||
JKSV Jksv{};
|
||||
while (Jksv.IsRunning())
|
||||
while (appletMainLoop() && Jksv.IsRunning())
|
||||
{
|
||||
Jksv.Update();
|
||||
Jksv.Render();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user