Changed Some More Stuff To DarkStore & Removed All Translations For Now

This commit is contained in:
Dark98
2021-06-18 06:58:54 +01:00
committed by dark98
parent fa3ce2acc8
commit eba72e5cb3
117 changed files with 52444 additions and 54800 deletions
+105 -105
View File
@@ -1,106 +1,106 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "gfx.hpp"
/*
Déssinez la base de l'écran supèrieur.
*/
void GFX::DrawTop(void) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
}
/*
Déssinez la base de l'écran infèrieur.
*/
void GFX::DrawBottom() {
Gui::ScreenDraw(Bottom);
Gui::Draw_Rect(0, 0, 320, 240, BG_COLOR);
}
/*
Dessinez la boîte.
float xPos: La position X où dessiner la boîte.
float yPos: La position Y où dessiner la boîte.
float width: La largeur du bouton.
float height: La hauteur du bouton.
bool selected: Si sélectionné ou non.
uint32_t clr: (Facultatif) La couleur de lintérieur de la boîte.
*/
void GFX::DrawBox(float xPos, float yPos, float width, float height, bool selected, uint32_t clr) {
Gui::Draw_Rect(xPos, yPos, width, height, BOX_INSIDE_COLOR); // Dessinez le BG du milieu.
if (selected) {
static constexpr int depth = 2;
Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, BOX_SELECTED_COLOR); // Haut.
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Gauche.
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Droite.
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, BOX_SELECTED_COLOR); // Bas.
}
}
extern C2D_SpriteSheet sprites;
/*
Dessinez un Sprite des sprites SpriteSheet.
int img: L'index d'image.
int x: la position X où dessiner.
int y: la position Y où dessiner.
float ScaleX: (Facultatif) L'échelle X du Sprite. (1 par défaut)
float ScaleY: (Facultatif) L'échelle Y du Sprite. (1 par défaut)
*/
void GFX::DrawSprite(int img, int x, int y, float ScaleX, float ScaleY) {
Gui::DrawSprite(sprites, img, x, y, ScaleX, ScaleY);
}
/*
Dessinez la case à cocher.
float xPos: La position X où dessiner la boîte.
float yPos: La position Y où dessiner la boîte.
booléen sélectionné: si coché ou non.
*/
void GFX::DrawCheckbox(float xPos, float yPos, bool selected) {
GFX::DrawSprite((selected ? sprites_checked_idx : sprites_unchecked_idx), xPos, yPos);
}
/*
Dessinez la boîte à bascule.
float xPos: La position X où dessiner la bascule.
float yPos: La position Y où dessiner la bascule.
bool toggled: Si basculé ou non.
*/
void GFX::DrawToggle(float xPos, float yPos, bool toggled) {
GFX::DrawSprite((toggled ? sprites_toggle_on_idx : sprites_toggle_off_idx), xPos, yPos);
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "gfx.hpp"
/*
Déssinez la base de l'écran supèrieur.
*/
void GFX::DrawTop(void) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
}
/*
Déssinez la base de l'écran infèrieur.
*/
void GFX::DrawBottom() {
Gui::ScreenDraw(Bottom);
Gui::Draw_Rect(0, 0, 320, 240, BG_COLOR);
}
/*
Dessinez la boîte.
float xPos: La position X où dessiner la boîte.
float yPos: La position Y où dessiner la boîte.
float width: La largeur du bouton.
float height: La hauteur du bouton.
bool selected: Si sélectionné ou non.
uint32_t clr: (Facultatif) La couleur de lintérieur de la boîte.
*/
void GFX::DrawBox(float xPos, float yPos, float width, float height, bool selected, uint32_t clr) {
Gui::Draw_Rect(xPos, yPos, width, height, BOX_INSIDE_COLOR); // Dessinez le BG du milieu.
if (selected) {
static constexpr int depth = 2;
Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, BOX_SELECTED_COLOR); // Haut.
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Gauche.
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, BOX_SELECTED_COLOR); // Droite.
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, BOX_SELECTED_COLOR); // Bas.
}
}
extern C2D_SpriteSheet sprites;
/*
Dessinez un Sprite des sprites SpriteSheet.
int img: L'index d'image.
int x: la position X où dessiner.
int y: la position Y où dessiner.
float ScaleX: (Facultatif) L'échelle X du Sprite. (1 par défaut)
float ScaleY: (Facultatif) L'échelle Y du Sprite. (1 par défaut)
*/
void GFX::DrawSprite(int img, int x, int y, float ScaleX, float ScaleY) {
Gui::DrawSprite(sprites, img, x, y, ScaleX, ScaleY);
}
/*
Dessinez la case à cocher.
float xPos: La position X où dessiner la boîte.
float yPos: La position Y où dessiner la boîte.
booléen sélectionné: si coché ou non.
*/
void GFX::DrawCheckbox(float xPos, float yPos, bool selected) {
GFX::DrawSprite((selected ? sprites_checked_idx : sprites_unchecked_idx), xPos, yPos);
}
/*
Dessinez la boîte à bascule.
float xPos: La position X où dessiner la bascule.
float yPos: La position Y où dessiner la bascule.
bool toggled: Si basculé ou non.
*/
void GFX::DrawToggle(float xPos, float yPos, bool toggled) {
GFX::DrawSprite((toggled ? sprites_toggle_on_idx : sprites_toggle_off_idx), xPos, yPos);
}
+122 -122
View File
@@ -1,123 +1,123 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "msg.hpp"
/*
Affiche juste un message jusquau prochain cadre de dessin.
const std::string &Text : Le message, qui doit être affiché.
*/
void Msg::DisplayMsg(const std::string &Text) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, Text)) / 2, 0.6f, TEXT_COLOR, Text, 395, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
}
/*
Affiche un message davertissement pendant 3 secondes.
const std::string &Text : Le message, qui doit être affiché.
*/
void Msg::DisplayWarnMsg(const std::string &Text) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.6f, TEXT_COLOR, Text, 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 60 * 3; i++) {
gspWaitForVBlank();
}
}
/*
Afficher un message qui doit être confirmé par A/B.
const std::string &promptMsg : Le message, qui doit être affiché.
*/
bool Msg::promptMsg(const std::string &promptMsg) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, promptMsg)) / 2, 0.6f, TEXT_COLOR, promptMsg, 395, 0, font);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CONFIRM_OR_CANCEL"), 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 3; i++) gspWaitForVBlank();
hidScanInput();
while(1) {
hidScanInput();
if (hidKeysDown() & KEY_A) return true;
else if (hidKeysDown() & KEY_B) return false;
}
}
/*
Afficher un message, qui peut être "confirmé" avec nimporte quelle clé.
const std::string &msg : Le message qui doit être affiché.
*/
void Msg::waitMsg(const std::string &msg) {
bool doOut = false;
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, msg)) / 2, 0.6f, TEXT_COLOR, msg, 395, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("KEY_CONTINUE"), 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 3; i++) gspWaitForVBlank();
hidScanInput();
while(!doOut) {
hidScanInput();
if (hidKeysDown()) doOut = !doOut;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "msg.hpp"
/*
Affiche juste un message jusquau prochain cadre de dessin.
const std::string &Text : Le message, qui doit être affiché.
*/
void Msg::DisplayMsg(const std::string &Text) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, Text)) / 2, 0.6f, TEXT_COLOR, Text, 395, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
}
/*
Affiche un message davertissement pendant 3 secondes.
const std::string &Text : Le message, qui doit être affiché.
*/
void Msg::DisplayWarnMsg(const std::string &Text) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.6f, TEXT_COLOR, Text, 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 60 * 3; i++) {
gspWaitForVBlank();
}
}
/*
Afficher un message qui doit être confirmé par A/B.
const std::string &promptMsg : Le message, qui doit être affiché.
*/
bool Msg::promptMsg(const std::string &promptMsg) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, promptMsg)) / 2, 0.6f, TEXT_COLOR, promptMsg, 395, 0, font);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CONFIRM_OR_CANCEL"), 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 3; i++) gspWaitForVBlank();
hidScanInput();
while(1) {
hidScanInput();
if (hidKeysDown() & KEY_A) return true;
else if (hidKeysDown() & KEY_B) return false;
}
}
/*
Afficher un message, qui peut être "confirmé" avec nimporte quelle clé.
const std::string &msg : Le message qui doit être affiché.
*/
void Msg::waitMsg(const std::string &msg) {
bool doOut = false;
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, (240 - Gui::GetStringHeight(0.6f, msg)) / 2, 0.6f, TEXT_COLOR, msg, 395, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("KEY_CONTINUE"), 390, 0, font);
GFX::DrawBottom();
C3D_FrameEnd(0);
for (int i = 0; i < 3; i++) gspWaitForVBlank();
hidScanInput();
while(!doOut) {
hidScanInput();
if (hidKeysDown()) doOut = !doOut;
}
}
+220 -220
View File
@@ -1,220 +1,220 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "download.hpp"
#include "init.hpp"
#include "mainScreen.hpp"
#include "queueSystem.hpp"
#include "sound.hpp"
#include <dirent.h>
#include <unistd.h>
bool exiting = false, is3DSX = false, needUnloadFont = false;
C2D_SpriteSheet sprites;
int fadeAlpha = 0;
u32 old_time_limit;
std::unique_ptr<Sound> Music = nullptr;
bool dspfirmFound = false;
/*
Set, si 3DSX ou CIA.
*/
static void getCurrentUsage(){
u64 id;
APT_GetProgramID(&id);
is3DSX = (id != 0x0004000007392600);
}
/*
Init Music.
*/
static void InitMusic() {
if (access("sdmc:/3ds/dspfirm.cdc", F_OK) == 0) { // Ensure dspfirm dump exist.
if (access("romfs:/song/music.wav", F_OK) == 0) { // Ensure music.wav exist.
dspfirmFound = true;
ndspInit();
Music = std::make_unique<Sound>("romfs:/song/music.wav");
Music->play();
}
}
}
/*
Exit Music.
*/
static void ExitMusic() {
if (dspfirmFound) {
Music->stop();
Music = nullptr;
ndspExit();
}
}
/*
If button Position pressed -> Do something.
touchPosition touch: The TouchPosition variable.
Structs::ButtonPos button: The Button Struct.
*/
bool touching(touchPosition touch, Structs::ButtonPos button) {
if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true;
return false;
}
/*
Chargez la police personnalisée et utilisez-la à la place de SysFont, si elle est trouvée.
*/
void Init::LoadFont() {
if (config->customfont()) {
if (!needUnloadFont) {
if (access("sdmc:/3ds/DarkStore/font.bcfnt", F_OK) == 0) {
Gui::loadFont(font, "sdmc:/3ds/DarkStore/font.bcfnt");
needUnloadFont = true;
}
}
}
}
/*
Déchargez la police personnalisée et revenez à SysFont.
*/
void Init::UnloadFont() {
if (needUnloadFont) {
Gui::unloadFont(font);
font = nullptr;
needUnloadFont = false;
}
}
/*
Initialiser DarkStore.
*/
Result Init::Initialize() {
gfxInitDefault();
romfsInit();
Gui::init();
cfguInit();
amInit();
acInit();
APT_GetAppCpuTimeLimit(&old_time_limit);
APT_SetAppCpuTimeLimit(30); // Nécessaire pour que le scanner QR fonctionne.
getCurrentUsage();
aptSetSleepAllowed(false);
hidSetRepeatParameters(20, 8);
/* Créer des répertoires, sil manque. */
mkdir("sdmc:/3ds", 0777);
mkdir("sdmc:/3ds/DarkStore", 0777);
mkdir("sdmc:/3ds/DarkStore/stores", 0777);
mkdir("sdmc:/3ds/DarkStore/shortcuts", 0777);
config = std::make_unique<Config>();
Lang::load(config->language());
Gui::loadSheet("romfs:/gfx/sprites.t3x", sprites);
LoadFont();
osSetSpeedupEnable(true); // Activer laccélération pour les utilisateurs de new3DS.
/* Check here for updates. */
if (config->updatecheck()) UpdateAction();
if (exiting) return -1; // En cas de succès de la mise à jour.
Gui::setScreen(std::make_unique<MainScreen>(), false, false);
InitMusic();
/* Initialize Queue System LightLock. */
LightLock_Init(&QueueSystem::lock);
return 0;
}
/*
MainLoop de DarkStore.
*/
Result Init::MainLoop() {
bool fullExit = false;
if (Initialize() == -1) fullExit = true;
/* Boucle tant que le statut nest pas fullExit. */
while (aptMainLoop() && !fullExit) {
hidScanInput();
hHeld = hidKeysHeld();
hDown = hidKeysDown();
hRepeat = hidKeysDownRepeat();
hidTouchRead(&touch);
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
Gui::DrawScreen(false);
if (!exiting) Gui::ScreenLogic(hDown, hHeld, touch, true, false);
C3D_FrameEnd(0);
if (exiting) {
if (hDown & KEY_START) fullExit = true; // En option, plus vite.
if (fadeAlpha < 255) {
fadeAlpha += 4;
if (fadeAlpha >= 255) fullExit = true;
}
}
}
/* Quitter tous les services et quitter lapplication. */
Exit();
return 0;
}
/*
Fermer DarkStore.
*/
Result Init::Exit() {
Gui::exit();
Gui::unloadSheet(sprites);
UnloadFont();
ExitMusic();
gfxExit();
cfguExit();
config->save();
acExit();
amExit();
if (old_time_limit != UINT32_MAX) APT_SetAppCpuTimeLimit(old_time_limit); // Rétablir lancienne limite.
aptSetSleepAllowed(true);
romfsExit();
return 0;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "download.hpp"
#include "init.hpp"
#include "mainScreen.hpp"
#include "queueSystem.hpp"
#include "sound.hpp"
#include <dirent.h>
#include <unistd.h>
bool exiting = false, is3DSX = false, needUnloadFont = false;
C2D_SpriteSheet sprites;
int fadeAlpha = 0;
u32 old_time_limit;
std::unique_ptr<Sound> Music = nullptr;
bool dspfirmFound = false;
/*
Set, si 3DSX ou CIA.
*/
static void getCurrentUsage(){
u64 id;
APT_GetProgramID(&id);
is3DSX = (id != 0x0004000007392600);
}
/*
Init Music.
*/
static void InitMusic() {
if (access("sdmc:/3ds/dspfirm.cdc", F_OK) == 0) { // Ensure dspfirm dump exist.
if (access("romfs:/song/music.wav", F_OK) == 0) { // Ensure music.wav exist.
dspfirmFound = true;
ndspInit();
Music = std::make_unique<Sound>("romfs:/song/music.wav");
Music->play();
}
}
}
/*
Exit Music.
*/
static void ExitMusic() {
if (dspfirmFound) {
Music->stop();
Music = nullptr;
ndspExit();
}
}
/*
If button Position pressed -> Do something.
touchPosition touch: The TouchPosition variable.
Structs::ButtonPos button: The Button Struct.
*/
bool touching(touchPosition touch, Structs::ButtonPos button) {
if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true;
return false;
}
/*
Chargez la police personnalisée et utilisez-la à la place de SysFont, si elle est trouvée.
*/
void Init::LoadFont() {
if (config->customfont()) {
if (!needUnloadFont) {
if (access("sdmc:/3ds/DarkStore/font.bcfnt", F_OK) == 0) {
Gui::loadFont(font, "sdmc:/3ds/DarkStore/font.bcfnt");
needUnloadFont = true;
}
}
}
}
/*
Déchargez la police personnalisée et revenez à SysFont.
*/
void Init::UnloadFont() {
if (needUnloadFont) {
Gui::unloadFont(font);
font = nullptr;
needUnloadFont = false;
}
}
/*
Initialiser DarkStore.
*/
Result Init::Initialize() {
gfxInitDefault();
romfsInit();
Gui::init();
cfguInit();
amInit();
acInit();
APT_GetAppCpuTimeLimit(&old_time_limit);
APT_SetAppCpuTimeLimit(30); // Nécessaire pour que le scanner QR fonctionne.
getCurrentUsage();
aptSetSleepAllowed(false);
hidSetRepeatParameters(20, 8);
/* Créer des répertoires, sil manque. */
mkdir("sdmc:/3ds", 0777);
mkdir("sdmc:/3ds/DarkStore", 0777);
mkdir("sdmc:/3ds/DarkStore/stores", 0777);
mkdir("sdmc:/3ds/DarkStore/shortcuts", 0777);
config = std::make_unique<Config>();
Lang::load(config->language());
Gui::loadSheet("romfs:/gfx/sprites.t3x", sprites);
LoadFont();
osSetSpeedupEnable(true); // Activer laccélération pour les utilisateurs de new3DS.
/* Check here for updates. */
if (config->updatecheck()) UpdateAction();
if (exiting) return -1; // En cas de succès de la mise à jour.
Gui::setScreen(std::make_unique<MainScreen>(), false, false);
InitMusic();
/* Initialize Queue System LightLock. */
LightLock_Init(&QueueSystem::lock);
return 0;
}
/*
MainLoop de DarkStore.
*/
Result Init::MainLoop() {
bool fullExit = false;
if (Initialize() == -1) fullExit = true;
/* Boucle tant que le statut nest pas fullExit. */
while (aptMainLoop() && !fullExit) {
hidScanInput();
hHeld = hidKeysHeld();
hDown = hidKeysDown();
hRepeat = hidKeysDownRepeat();
hidTouchRead(&touch);
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
Gui::DrawScreen(false);
if (!exiting) Gui::ScreenLogic(hDown, hHeld, touch, true, false);
C3D_FrameEnd(0);
if (exiting) {
if (hDown & KEY_START) fullExit = true; // En option, plus vite.
if (fadeAlpha < 255) {
fadeAlpha += 4;
if (fadeAlpha >= 255) fullExit = true;
}
}
}
/* Quitter tous les services et quitter lapplication. */
Exit();
return 0;
}
/*
Fermer DarkStore.
*/
Result Init::Exit() {
Gui::exit();
Gui::unloadSheet(sprites);
UnloadFont();
ExitMusic();
gfxExit();
cfguExit();
config->save();
acExit();
amExit();
if (old_time_limit != UINT32_MAX) APT_SetAppCpuTimeLimit(old_time_limit); // Rétablir lancienne limite.
aptSetSleepAllowed(true);
romfsExit();
return 0;
}
+67 -67
View File
@@ -1,68 +1,68 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "gfx.hpp"
#include "keyboard.hpp"
#include "screenCommon.hpp"
static std::vector<SwkbdDictWord> words;
/*
Retourne une chaîne du clavier.
uint maxLongueur : La longueur maximale.
const std::string &Text : Const Référence au texte.
const std::vectorstd::unique_ptrStoreEntry>> &entries : Const Référence de toutes les entrées pour les mots à suggérer.
*/
std::string Input::setkbdString(uint maxLength, const std::string &Text, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
C3D_FrameEnd(0); // Nécessaire pour que le système ne gèle pas.
SwkbdState state;
swkbdInit(&state, SWKBD_TYPE_NORMAL, 2, maxLength);
char temp[maxLength + 1] = { 0 };
swkbdSetHintText(&state, Text.c_str());
swkbdSetValidation(&state, SWKBD_NOTBLANK_NOTEMPTY, SWKBD_FILTER_PROFANITY, 0);
if (entries.size()) {
words.clear();
words.resize(entries.size());
for (uint i = 0; i < entries.size(); i++) {
/* Vérification pour non nullptr. */
if (entries[i]) swkbdSetDictWord(&words[i], StringUtils::lower_case(entries[i]->GetTitle()).c_str(), entries[i]->GetTitle().c_str());
else swkbdSetDictWord(&words[i], "", "");
}
if (words.size() > 0) {
swkbdSetDictionary(&state, words.data(), entries.size());
swkbdSetFeatures(&state, SWKBD_PREDICTIVE_INPUT);
}
}
SwkbdButton ret = swkbdInputText(&state, temp, sizeof(temp));
temp[maxLength] = '\0';
return (ret == SWKBD_BUTTON_CONFIRM ? temp : "");
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "gfx.hpp"
#include "keyboard.hpp"
#include "screenCommon.hpp"
static std::vector<SwkbdDictWord> words;
/*
Retourne une chaîne du clavier.
uint maxLongueur : La longueur maximale.
const std::string &Text : Const Référence au texte.
const std::vectorstd::unique_ptrStoreEntry>> &entries : Const Référence de toutes les entrées pour les mots à suggérer.
*/
std::string Input::setkbdString(uint maxLength, const std::string &Text, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
C3D_FrameEnd(0); // Nécessaire pour que le système ne gèle pas.
SwkbdState state;
swkbdInit(&state, SWKBD_TYPE_NORMAL, 2, maxLength);
char temp[maxLength + 1] = { 0 };
swkbdSetHintText(&state, Text.c_str());
swkbdSetValidation(&state, SWKBD_NOTBLANK_NOTEMPTY, SWKBD_FILTER_PROFANITY, 0);
if (entries.size()) {
words.clear();
words.resize(entries.size());
for (uint i = 0; i < entries.size(); i++) {
/* Vérification pour non nullptr. */
if (entries[i]) swkbdSetDictWord(&words[i], StringUtils::lower_case(entries[i]->GetTitle()).c_str(), entries[i]->GetTitle().c_str());
else swkbdSetDictWord(&words[i], "", "");
}
if (words.size() > 0) {
swkbdSetDictionary(&state, words.data(), entries.size());
swkbdSetFeatures(&state, SWKBD_PREDICTIVE_INPUT);
}
}
SwkbdButton ret = swkbdInputText(&state, temp, sizeof(temp));
temp[maxLength] = '\0';
return (ret == SWKBD_BUTTON_CONFIRM ? temp : "");
}
+93 -93
View File
@@ -1,93 +1,93 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "argumentParser.hpp"
#include "common.hpp"
#include "init.hpp"
#include <dirent.h>
#include <string>
#define ARG_AMOUNT 4 // Dans le cas où plus dargs, modifiez ceci. Il doit être le montant ARG + 1, en raison de 3DSX Path.
std::string _3dsxPath = "";
/*
ARG Init.
*/
static void InitForARG() {
gfxInitDefault();
romfsInit();
cfguInit();
Gui::init();
amInit();
acInit();
/* Créer des répertoires, sil manque. */
mkdir("sdmc:/3ds", 0777);
mkdir("sdmc:/3ds/DarkStore", 0777);
mkdir("sdmc:/3ds/DarkStore/stores", 0777);
mkdir("sdmc:/3ds/DarkStore/shortcuts", 0777);
config = std::make_unique<Config>();
Lang::load(config->language());
Init::LoadFont();
osSetSpeedupEnable(true); // Activer laccélération pour les utilisateurs de new3DS.
}
/*
ARG Exit.
*/
static Result ExitForARG() {
Gui::exit();
Init::UnloadFont();
gfxExit();
cfguExit();
acExit();
amExit();
romfsExit();
return 0;
}
int main(int argc, char *argv[]) {
if (argc > 0) _3dsxPath = argv[0];
/* 4 --> Mode argument. */
if (argc == ARG_AMOUNT) {
InitForARG();
const std::string file = argv[1];
const std::string entry = argv[2];
int dlIndex = atoi(argv[3]);
std::unique_ptr<ArgumentParser> arg = std::make_unique<ArgumentParser>(file, entry, dlIndex);
if (arg->GetValid()) arg->Execute(); // Exécuter, si valide.
else Msg::waitMsg(Lang::get("ARGUMENT_INVALID"));
return ExitForARG();
}
return Init::MainLoop();
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "argumentParser.hpp"
#include "common.hpp"
#include "init.hpp"
#include <dirent.h>
#include <string>
#define ARG_AMOUNT 4 // Dans le cas où plus dargs, modifiez ceci. Il doit être le montant ARG + 1, en raison de 3DSX Path.
std::string _3dsxPath = "";
/*
ARG Init.
*/
static void InitForARG() {
gfxInitDefault();
romfsInit();
cfguInit();
Gui::init();
amInit();
acInit();
/* Créer des répertoires, sil manque. */
mkdir("sdmc:/3ds", 0777);
mkdir("sdmc:/3ds/DarkStore", 0777);
mkdir("sdmc:/3ds/DarkStore/stores", 0777);
mkdir("sdmc:/3ds/DarkStore/shortcuts", 0777);
config = std::make_unique<Config>();
Lang::load(config->language());
Init::LoadFont();
osSetSpeedupEnable(true); // Activer laccélération pour les utilisateurs de new3DS.
}
/*
ARG Exit.
*/
static Result ExitForARG() {
Gui::exit();
Init::UnloadFont();
gfxExit();
cfguExit();
acExit();
amExit();
romfsExit();
return 0;
}
int main(int argc, char *argv[]) {
if (argc > 0) _3dsxPath = argv[0];
/* 4 --> Mode argument. */
if (argc == ARG_AMOUNT) {
InitForARG();
const std::string file = argv[1];
const std::string entry = argv[2];
int dlIndex = atoi(argv[3]);
std::unique_ptr<ArgumentParser> arg = std::make_unique<ArgumentParser>(file, entry, dlIndex);
if (arg->GetValid()) arg->Execute(); // Exécuter, si valide.
else Msg::waitMsg(Lang::get("ARGUMENT_INVALID"));
return ExitForARG();
}
return Init::MainLoop();
}
+254 -254
View File
@@ -1,255 +1,255 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "queueSystem.hpp"
#include "scriptUtils.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
#include <fstream>
#define DOWNLOAD_ENTRIES 7
extern std::string _3dsxPath;
extern bool is3DSX;
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> downloadBoxes = {
{ 46, 32, 270, 22 },
{ 46, 62, 270, 22 },
{ 46, 92, 270, 22 },
{ 46, 122, 270, 22 },
{ 46, 152, 270, 22 },
{ 46, 182, 270, 22 },
{ 46, 212, 270, 22 },
{ 42, 216, 24, 24 }
};
/*
With this, we can create a shortcut. ;P
const std::string &entryName: The name of the Entry. AKA: The Title Name.
int index: The Download index.
const std::string &EshopName: The name of the eShop filename.
const std::string &author: The author of the app.
*/
static bool CreateShortcut(const std::string &entryName, int index, const std::string &EshopName, const std::string &author) {
std::string sName = Input::setkbdString(30, Lang::get("ENTER_SHORTCUT_FILENAME"), {});
if (sName == "") return false; // Just cancel.
std::ofstream out(config->shortcut() + "/" + sName + ".xml", std::ios::binary);
out << "<shortcut>" << std::endl;
/* Executable. */
const std::string executable = _3dsxPath.substr(5, _3dsxPath.size()); // It must be '/3ds/...'.
out << " <executable>" << executable << "</executable>" << std::endl;
/* Arguments. */
out << " <arg>\"" << EshopName << "\" \"" << entryName << "\" \"" << std::to_string(index) << "\"" << "</arg>" << std::endl;
/* Title. */
const std::string title = Input::setkbdString(30, Lang::get("ENTER_TITLE_SHORTCUT"), {});
if (title != "") out << " <name>" << title << "</name>" << std::endl;
else out << " <name>" << entryName << "</name>" << std::endl;
/* Description. */
const std::string desc = Input::setkbdString(50, Lang::get("ENTER_DESC_SHORTCUT"), {});
if (desc != "") out << " <description>" << desc << "</description>" << std::endl;
else out << " <description>" << entryName << "</description>" << std::endl;
/* Author and end. */
out << " <author>" << author << "</author>" << std::endl;
out << "</shortcut>" << std::endl;
out.close();
return true;
}
/*
Draw the Download Entries part.
const std::unique_ptr<Store> &store: Const Reference to the Store class.
const std::vector<std::string> &entries: Const Reference to the download list as a vector of strings.
bool fetch: if fetching or not.
const std::unique_ptr<StoreEntry> &entry: Const Reference to the StoreEntry.
const std::vector<std::string> &sizes: Const Reference to the download sizes as a vector of strings.
*/
void StoreUtils::DrawDownList(const std::unique_ptr<Store> &store, const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes) {
/* For the Top Screen. */
if (store && store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
Gui::Draw_Rect(0, 174, 400, 66, BOX_INSIDE_COLOR);
const C2D_Image tempImg = entry->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
C2D_DrawImageAt(tempImg, 9 + offsetW, 174 + 9 + offsetH, 0.5);
Gui::DrawString(70, 174 + 15, 0.45f, TEXT_COLOR, entries[store->GetDownloadIndex()], 310, 0, font);
if (!sizes.empty()) {
if (sizes[store->GetDownloadIndex()] != "") {
Gui::DrawString(70, 174 + 30, 0.45f, TEXT_COLOR, Lang::get("SIZE") + ": " + sizes[store->GetDownloadIndex()], 310, 0, font);
}
}
}
}
GFX::DrawBottom();
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, Lang::get("AVAILABLE_DOWNLOADS"), 273, 0, font);
if (store && store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
for (int i = 0; i < DOWNLOAD_ENTRIES && i < (int)entries.size(); i++) {
if (store->GetDownloadIndex() == i + store->GetDownloadSIndex()) GFX::DrawBox(downloadBoxes[i].x, downloadBoxes[i].y, downloadBoxes[i].w, downloadBoxes[i].h, false);
Gui::DrawStringCentered(46 - 160 + (270 / 2), downloadBoxes[i].y + 4, 0.45f, TEXT_COLOR, entries[(i + store->GetDownloadSIndex())], 268, 0, font);
}
if (is3DSX) GFX::DrawSprite(sprites_shortcut_idx, downloadBoxes[6].x, downloadBoxes[6].y);
} else { // If no downloads available..
Gui::DrawStringCentered(46 - 160 + (270 / 2), downloadBoxes[0].y + 4, 0.5f, TEXT_COLOR, Lang::get("NO_DOWNLOADS_AVAILABLE"), 263, 0, font);
}
}
}
/*
Adding to Queue.. with checks!
*/
void AddToQueue(int index, const std::string &entry, const std::unique_ptr<Store> &store) {
if (!store) return;
/* Check first for proper JSON. */
if (!store->GetJson().contains("storeContent")) return;
if ((int)store->GetJson()["storeContent"].size() < index) return;
if (!store->GetJson()["storeContent"][index].contains(entry)) return;
nlohmann::json Script = nullptr;
/* Detect if array or new object thing. Else return Syntax error. :P */
if (store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::array) {
Script = store->GetJson()["storeContent"][index][entry];
} else if (store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::object) {
if (store->GetJson()["storeContent"][index][entry].contains("script") && store->GetJson()["storeContent"][index][entry]["script"].is_array()) {
Script = store->GetJson()["storeContent"][index][entry]["script"];
} else {
return;
}
}
QueueSystem::AddToQueue(Script, store->GetIconEntry(index), entry); // Here we add this to the Queue at the end.
}
/*
This is the Download List handle.
Here you can..
- Scroll through the download list, if any available.
- Execute an Entry of the download list.
- Return back to EntryInfo through `B`.
const std::unique_ptr<Store> &store: Const Reference to the Store class, since we do not modify anything in it.
const std::unique_ptr<StoreEntry> &entry: Const Reference to the current StoreEntry, since we do not modify anything in it.
const std::vector<std::string> &entries: Const Reference to the download list, since we do not modify anything in it.
int &currentMenu: Reference to the StoreMode / Menu, so we can switch back to EntryInfo with `B`.
std::unique_ptr<Meta> &meta: Reference to the Meta, to apply the updates stuff.
const int &lastMode: Const Reference to the last mode.
int &smallDelay: Reference to the small delay. This helps to not directly press A.
*/
void StoreUtils::DownloadHandle(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int &currentMenu, std::unique_ptr<Meta> &meta, const int &lastMode, int &smallDelay) {
if (store && entry) { // Ensure, store & entry is not a nullptr.
if (smallDelay > 0) {
smallDelay--;
}
if ((hDown & KEY_Y) || (hDown & KEY_START) || (hDown & KEY_TOUCH && touching(touch, downloadBoxes[6]))) {
if (is3DSX) { // Only allow if 3DSX.
if (entries.size() <= 0) return; // Smaller than 0 -> No No.
if (Msg::promptMsg(Lang::get("CREATE_SHORTCUT"))) {
if (CreateShortcut(entry->GetTitle(), store->GetDownloadIndex(), store->GetFileName(), entry->GetAuthor())) {
Msg::waitMsg(Lang::get("SHORTCUT_CREATED"));
}
}
}
}
if (hRepeat & KEY_DOWN) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() < (int)entries.size() - 1) store->SetDownloadIndex(store->GetDownloadIndex() + 1);
else store->SetDownloadIndex(0);
}
if (hRepeat & KEY_UP) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() > 0) store->SetDownloadIndex(store->GetDownloadIndex() - 1);
else store->SetDownloadIndex(entries.size() - 1);
}
if (hRepeat & KEY_RIGHT) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() + DOWNLOAD_ENTRIES < (int)entries.size()-1) store->SetDownloadIndex(store->GetDownloadIndex() + DOWNLOAD_ENTRIES);
else store->SetDownloadIndex(entries.size()-1);
}
if (hRepeat & KEY_LEFT) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() - DOWNLOAD_ENTRIES > 0) store->SetDownloadIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES);
else store->SetDownloadIndex(0);
}
if (smallDelay == 0 && hDown & KEY_TOUCH) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
for (int i = 0; i < DOWNLOAD_ENTRIES; i++) {
if (touching(touch, downloadBoxes[i])) {
if (i + store->GetDownloadSIndex() < (int)entries.size()) {
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[i + store->GetDownloadSIndex()])) {
AddToQueue(entry->GetEntryIndex(), entries[i + store->GetDownloadSIndex()], store);
}
}
}
}
}
if (smallDelay == 0 && hDown & KEY_A) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[store->GetDownloadIndex()])) {
AddToQueue(entry->GetEntryIndex(), entries[store->GetDownloadIndex()], store);
}
}
if (hDown & KEY_B) currentMenu = lastMode; // Go back to EntryInfo.
/* Scroll Handle. */
if (store->GetDownloadIndex() < store->GetDownloadSIndex()) store->SetDownloadSIndex(store->GetDownloadIndex());
else if (store->GetDownloadIndex() > store->GetDownloadSIndex() + DOWNLOAD_ENTRIES - 1) store->SetDownloadSIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES + 1);
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "queueSystem.hpp"
#include "scriptUtils.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
#include <fstream>
#define DOWNLOAD_ENTRIES 7
extern std::string _3dsxPath;
extern bool is3DSX;
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> downloadBoxes = {
{ 46, 32, 270, 22 },
{ 46, 62, 270, 22 },
{ 46, 92, 270, 22 },
{ 46, 122, 270, 22 },
{ 46, 152, 270, 22 },
{ 46, 182, 270, 22 },
{ 46, 212, 270, 22 },
{ 42, 216, 24, 24 }
};
/*
With this, we can create a shortcut. ;P
const std::string &entryName: The name of the Entry. AKA: The Title Name.
int index: The Download index.
const std::string &EshopName: The name of the eShop filename.
const std::string &author: The author of the app.
*/
static bool CreateShortcut(const std::string &entryName, int index, const std::string &EshopName, const std::string &author) {
std::string sName = Input::setkbdString(30, Lang::get("ENTER_SHORTCUT_FILENAME"), {});
if (sName == "") return false; // Just cancel.
std::ofstream out(config->shortcut() + "/" + sName + ".xml", std::ios::binary);
out << "<shortcut>" << std::endl;
/* Executable. */
const std::string executable = _3dsxPath.substr(5, _3dsxPath.size()); // It must be '/3ds/...'.
out << " <executable>" << executable << "</executable>" << std::endl;
/* Arguments. */
out << " <arg>\"" << EshopName << "\" \"" << entryName << "\" \"" << std::to_string(index) << "\"" << "</arg>" << std::endl;
/* Title. */
const std::string title = Input::setkbdString(30, Lang::get("ENTER_TITLE_SHORTCUT"), {});
if (title != "") out << " <name>" << title << "</name>" << std::endl;
else out << " <name>" << entryName << "</name>" << std::endl;
/* Description. */
const std::string desc = Input::setkbdString(50, Lang::get("ENTER_DESC_SHORTCUT"), {});
if (desc != "") out << " <description>" << desc << "</description>" << std::endl;
else out << " <description>" << entryName << "</description>" << std::endl;
/* Author and end. */
out << " <author>" << author << "</author>" << std::endl;
out << "</shortcut>" << std::endl;
out.close();
return true;
}
/*
Draw the Download Entries part.
const std::unique_ptr<Store> &store: Const Reference to the Store class.
const std::vector<std::string> &entries: Const Reference to the download list as a vector of strings.
bool fetch: if fetching or not.
const std::unique_ptr<StoreEntry> &entry: Const Reference to the StoreEntry.
const std::vector<std::string> &sizes: Const Reference to the download sizes as a vector of strings.
*/
void StoreUtils::DrawDownList(const std::unique_ptr<Store> &store, const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes) {
/* For the Top Screen. */
if (store && store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
Gui::Draw_Rect(0, 174, 400, 66, BOX_INSIDE_COLOR);
const C2D_Image tempImg = entry->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
C2D_DrawImageAt(tempImg, 9 + offsetW, 174 + 9 + offsetH, 0.5);
Gui::DrawString(70, 174 + 15, 0.45f, TEXT_COLOR, entries[store->GetDownloadIndex()], 310, 0, font);
if (!sizes.empty()) {
if (sizes[store->GetDownloadIndex()] != "") {
Gui::DrawString(70, 174 + 30, 0.45f, TEXT_COLOR, Lang::get("SIZE") + ": " + sizes[store->GetDownloadIndex()], 310, 0, font);
}
}
}
}
GFX::DrawBottom();
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, Lang::get("AVAILABLE_DOWNLOADS"), 273, 0, font);
if (store && store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
for (int i = 0; i < DOWNLOAD_ENTRIES && i < (int)entries.size(); i++) {
if (store->GetDownloadIndex() == i + store->GetDownloadSIndex()) GFX::DrawBox(downloadBoxes[i].x, downloadBoxes[i].y, downloadBoxes[i].w, downloadBoxes[i].h, false);
Gui::DrawStringCentered(46 - 160 + (270 / 2), downloadBoxes[i].y + 4, 0.45f, TEXT_COLOR, entries[(i + store->GetDownloadSIndex())], 268, 0, font);
}
if (is3DSX) GFX::DrawSprite(sprites_shortcut_idx, downloadBoxes[6].x, downloadBoxes[6].y);
} else { // If no downloads available..
Gui::DrawStringCentered(46 - 160 + (270 / 2), downloadBoxes[0].y + 4, 0.5f, TEXT_COLOR, Lang::get("NO_DOWNLOADS_AVAILABLE"), 263, 0, font);
}
}
}
/*
Adding to Queue.. with checks!
*/
void AddToQueue(int index, const std::string &entry, const std::unique_ptr<Store> &store) {
if (!store) return;
/* Check first for proper JSON. */
if (!store->GetJson().contains("storeContent")) return;
if ((int)store->GetJson()["storeContent"].size() < index) return;
if (!store->GetJson()["storeContent"][index].contains(entry)) return;
nlohmann::json Script = nullptr;
/* Detect if array or new object thing. Else return Syntax error. :P */
if (store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::array) {
Script = store->GetJson()["storeContent"][index][entry];
} else if (store->GetJson()["storeContent"][index][entry].type() == nlohmann::json::value_t::object) {
if (store->GetJson()["storeContent"][index][entry].contains("script") && store->GetJson()["storeContent"][index][entry]["script"].is_array()) {
Script = store->GetJson()["storeContent"][index][entry]["script"];
} else {
return;
}
}
QueueSystem::AddToQueue(Script, store->GetIconEntry(index), entry); // Here we add this to the Queue at the end.
}
/*
This is the Download List handle.
Here you can..
- Scroll through the download list, if any available.
- Execute an Entry of the download list.
- Return back to EntryInfo through `B`.
const std::unique_ptr<Store> &store: Const Reference to the Store class, since we do not modify anything in it.
const std::unique_ptr<StoreEntry> &entry: Const Reference to the current StoreEntry, since we do not modify anything in it.
const std::vector<std::string> &entries: Const Reference to the download list, since we do not modify anything in it.
int &currentMenu: Reference to the StoreMode / Menu, so we can switch back to EntryInfo with `B`.
std::unique_ptr<Meta> &meta: Reference to the Meta, to apply the updates stuff.
const int &lastMode: Const Reference to the last mode.
int &smallDelay: Reference to the small delay. This helps to not directly press A.
*/
void StoreUtils::DownloadHandle(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &entries, int &currentMenu, std::unique_ptr<Meta> &meta, const int &lastMode, int &smallDelay) {
if (store && entry) { // Ensure, store & entry is not a nullptr.
if (smallDelay > 0) {
smallDelay--;
}
if ((hDown & KEY_Y) || (hDown & KEY_START) || (hDown & KEY_TOUCH && touching(touch, downloadBoxes[6]))) {
if (is3DSX) { // Only allow if 3DSX.
if (entries.size() <= 0) return; // Smaller than 0 -> No No.
if (Msg::promptMsg(Lang::get("CREATE_SHORTCUT"))) {
if (CreateShortcut(entry->GetTitle(), store->GetDownloadIndex(), store->GetFileName(), entry->GetAuthor())) {
Msg::waitMsg(Lang::get("SHORTCUT_CREATED"));
}
}
}
}
if (hRepeat & KEY_DOWN) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() < (int)entries.size() - 1) store->SetDownloadIndex(store->GetDownloadIndex() + 1);
else store->SetDownloadIndex(0);
}
if (hRepeat & KEY_UP) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() > 0) store->SetDownloadIndex(store->GetDownloadIndex() - 1);
else store->SetDownloadIndex(entries.size() - 1);
}
if (hRepeat & KEY_RIGHT) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() + DOWNLOAD_ENTRIES < (int)entries.size()-1) store->SetDownloadIndex(store->GetDownloadIndex() + DOWNLOAD_ENTRIES);
else store->SetDownloadIndex(entries.size()-1);
}
if (hRepeat & KEY_LEFT) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (store->GetDownloadIndex() - DOWNLOAD_ENTRIES > 0) store->SetDownloadIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES);
else store->SetDownloadIndex(0);
}
if (smallDelay == 0 && hDown & KEY_TOUCH) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
for (int i = 0; i < DOWNLOAD_ENTRIES; i++) {
if (touching(touch, downloadBoxes[i])) {
if (i + store->GetDownloadSIndex() < (int)entries.size()) {
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[i + store->GetDownloadSIndex()])) {
AddToQueue(entry->GetEntryIndex(), entries[i + store->GetDownloadSIndex()], store);
}
}
}
}
}
if (smallDelay == 0 && hDown & KEY_A) {
if (entries.size() <= 0) return; // Smaller *than* 0 -> Invalid.
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + entries[store->GetDownloadIndex()])) {
AddToQueue(entry->GetEntryIndex(), entries[store->GetDownloadIndex()], store);
}
}
if (hDown & KEY_B) currentMenu = lastMode; // Go back to EntryInfo.
/* Scroll Handle. */
if (store->GetDownloadIndex() < store->GetDownloadSIndex()) store->SetDownloadSIndex(store->GetDownloadIndex());
else if (store->GetDownloadIndex() > store->GetDownloadSIndex() + DOWNLOAD_ENTRIES - 1) store->SetDownloadSIndex(store->GetDownloadIndex() - DOWNLOAD_ENTRIES + 1);
}
}
+88 -88
View File
@@ -1,89 +1,89 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const Structs::ButtonPos btn = { 45, 215, 24, 24 };
static const Structs::ButtonPos sshot = { 75, 215, 24, 24 };
static const Structs::ButtonPos notes = { 105, 215, 24, 24 };
extern bool checkWifiStatus();
/*
Dessinez la partie Entry Info.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::unique_ptr<StoreEntry> &entry : Const Référence au StoreEntry actuel.
*/
void StoreUtils::DrawEntryInfo(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry) {
if (store && entry) { // Assurez-vous que lenregistrement et la saisie ne sont pas un nullptr.
Gui::Draw_Rect(40, 0, 280, 36, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 36, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 0, 0.6, TEXT_COLOR, entry->GetTitle(), 273, 0, font);
Gui::DrawStringCentered(17, 20, 0.4, TEXT_COLOR, entry->GetAuthor(), 273, 0, font);
Gui::DrawStringCentered(17, 50, 0.4, TEXT_COLOR, entry->GetDescription(), 248, 0, font, C2D_WordWrap);
Gui::DrawString(61, 130, 0.45, TEXT_COLOR, Lang::get("VERSION") + ": " + entry->GetVersion(), 248, 0, font);
Gui::DrawString(61, 145, 0.45, TEXT_COLOR, Lang::get("CATEGORY") + ": " + entry->GetCategory(), 248, 0, font);
Gui::DrawString(61, 160, 0.45, TEXT_COLOR, Lang::get("CONSOLE") + ": " + entry->GetConsole(), 248, 0, font);
Gui::DrawString(61, 175, 0.45, TEXT_COLOR, Lang::get("SIZE") + ": " + entry->GetSize(), 248, 0, font);
Gui::DrawString(61, 195, 0.45, TEXT_COLOR, entry->GetAdditionalcontent(), 248, 0, font);
GFX::DrawBox(btn.x, btn.y, btn.w, btn.h, false);
if (!entry->GetScreenshots().empty()) GFX::DrawSprite(sprites_screenshot_idx, sshot.x, sshot.y);
if (entry->GetReleaseNotes() != "") GFX::DrawSprite(sprites_notes_idx, notes.x, notes.y);
Gui::DrawString(btn.x + 5, btn.y + 2, 0.6f, TEXT_COLOR, "", 0, 0, font);
}
}
/*
La poignée EntryInfo.
Ici vous pouvez..
- Accédez à la liste de téléchargement en appuyant sur « A ».
- Montrez le MarkMenu avec START.
bool &showMark : Référence à showMark.. pour afficher le menu mark.
bool &fetch : Référence à fetch, pour que nous sachions, si nous avons besoin de fetch,
quand nous accédons à la liste de téléchargement.
*/
void StoreUtils::EntryHandle(bool &showMark, bool &fetch, bool &sFetch, int &mode, const std::unique_ptr<StoreEntry> &entry) {
if (entry) {
if ((hDown & KEY_START) || (hDown & KEY_TOUCH && touching(touch, btn))) showMark = true;
if ((hDown & KEY_Y) || (hDown & KEY_TOUCH && touching(touch, sshot))) {
if (!entry->GetScreenshots().empty()) {
if (checkWifiStatus()) {
sFetch = true;
mode = 6;
}
}
}
if ((hDown & KEY_X) || (hDown & KEY_TOUCH && touching(touch, notes))) {
if (entry->GetReleaseNotes() != "") mode = 7;
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const Structs::ButtonPos btn = { 45, 215, 24, 24 };
static const Structs::ButtonPos sshot = { 75, 215, 24, 24 };
static const Structs::ButtonPos notes = { 105, 215, 24, 24 };
extern bool checkWifiStatus();
/*
Dessinez la partie Entry Info.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::unique_ptr<StoreEntry> &entry : Const Référence au StoreEntry actuel.
*/
void StoreUtils::DrawEntryInfo(const std::unique_ptr<Store> &store, const std::unique_ptr<StoreEntry> &entry) {
if (store && entry) { // Assurez-vous que lenregistrement et la saisie ne sont pas un nullptr.
Gui::Draw_Rect(40, 0, 280, 36, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 36, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 0, 0.6, TEXT_COLOR, entry->GetTitle(), 273, 0, font);
Gui::DrawStringCentered(17, 20, 0.4, TEXT_COLOR, entry->GetAuthor(), 273, 0, font);
Gui::DrawStringCentered(17, 50, 0.4, TEXT_COLOR, entry->GetDescription(), 248, 0, font, C2D_WordWrap);
Gui::DrawString(61, 130, 0.45, TEXT_COLOR, Lang::get("VERSION") + ": " + entry->GetVersion(), 248, 0, font);
Gui::DrawString(61, 145, 0.45, TEXT_COLOR, Lang::get("CATEGORY") + ": " + entry->GetCategory(), 248, 0, font);
Gui::DrawString(61, 160, 0.45, TEXT_COLOR, Lang::get("CONSOLE") + ": " + entry->GetConsole(), 248, 0, font);
Gui::DrawString(61, 175, 0.45, TEXT_COLOR, Lang::get("SIZE") + ": " + entry->GetSize(), 248, 0, font);
Gui::DrawString(61, 195, 0.45, TEXT_COLOR, entry->GetAdditionalcontent(), 248, 0, font);
GFX::DrawBox(btn.x, btn.y, btn.w, btn.h, false);
if (!entry->GetScreenshots().empty()) GFX::DrawSprite(sprites_screenshot_idx, sshot.x, sshot.y);
if (entry->GetReleaseNotes() != "") GFX::DrawSprite(sprites_notes_idx, notes.x, notes.y);
Gui::DrawString(btn.x + 5, btn.y + 2, 0.6f, TEXT_COLOR, "", 0, 0, font);
}
}
/*
La poignée EntryInfo.
Ici vous pouvez..
- Accédez à la liste de téléchargement en appuyant sur « A ».
- Montrez le MarkMenu avec START.
bool &showMark : Référence à showMark.. pour afficher le menu mark.
bool &fetch : Référence à fetch, pour que nous sachions, si nous avons besoin de fetch,
quand nous accédons à la liste de téléchargement.
*/
void StoreUtils::EntryHandle(bool &showMark, bool &fetch, bool &sFetch, int &mode, const std::unique_ptr<StoreEntry> &entry) {
if (entry) {
if ((hDown & KEY_START) || (hDown & KEY_TOUCH && touching(touch, btn))) showMark = true;
if ((hDown & KEY_Y) || (hDown & KEY_TOUCH && touching(touch, sshot))) {
if (!entry->GetScreenshots().empty()) {
if (checkWifiStatus()) {
sFetch = true;
mode = 6;
}
}
}
if ((hDown & KEY_X) || (hDown & KEY_TOUCH && touching(touch, notes))) {
if (entry->GetReleaseNotes() != "") mode = 7;
}
}
}
+175 -175
View File
@@ -1,176 +1,176 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
static const std::vector<Structs::ButtonPos> GridBoxes = {
{ 25, 45, 50, 50 },
{ 100, 45, 50, 50 },
{ 175, 45, 50, 50 },
{ 250, 45, 50, 50 },
{ 325, 45, 50, 50 },
{ 25, 105, 50, 50 },
{ 100, 105, 50, 50 },
{ 175, 105, 50, 50 },
{ 250, 105, 50, 50 },
{ 325, 105, 50, 50 },
{ 25, 165, 50, 50 },
{ 100, 165, 50, 50 },
{ 175, 165, 50, 50 },
{ 250, 165, 50, 50 },
{ 325, 165, 50, 50 }
};
/*
Dessinez la grille supérieure.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::vector<std::unique_ptr<StoreEntry>> &entries : Const Référence à StoreEntries.
*/
void StoreUtils::DrawGrid(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (config->usebg() && store->customBG()) {
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
for (int i = 0, i2 = 0 + (store->GetScreenIndx() * 5); i2 < 15 + (store->GetScreenIndx() * 5) && i2 < (int)entries.size(); i2++, i++) {
/* Boxes. */
if (i == store->GetBox()) GFX::DrawBox(GridBoxes[i].x, GridBoxes[i].y, 50, 50, true);
/* Assurez-vous que les entrées sont plus grandes que lindex. */
if ((int)entries.size() > i2) {
if (entries[i2]) { // Assurez-vous que lentrée nest pas nullptr.
const C2D_Image tempImg = entries[i2]->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Centre W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Centre H.
C2D_DrawImageAt(tempImg, GridBoxes[i].x + 1 + offsetW, GridBoxes[i].y + 1 + offsetH, 0.5);
/* Mettre à jour la marque disponible. */
if (entries[i2]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, GridBoxes[i].x + 32, GridBoxes[i].y + 32);
}
}
}
}
}
/*
Poignée logique de grille supérieure.
Ici vous pouvez..
- Faire défiler la grille à laide du pavé en D.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence à StoreEntries.
const int &currentMode : Référence au mode actuel.
int &lastMode : Référence au dernier mode.
bool &fetch : Référence à fetch.
int &smallDelay : Référence au petit délai.
*/
void StoreUtils::GridLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int &currentMode, int &lastMode, bool &fetch, int &smallDelay) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (hRepeat & KEY_DOWN) {
if (store->GetBox() > 9) {
if (store->GetEntry() + 5 < (int)entries.size() - 1) {
store->SetEntry(store->GetEntry() + 5);
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
} else {
if (store->GetEntry() < (int)entries.size() - 1) {
store->SetEntry(entries.size() - 1);
store->SetBox(10 + (store->GetEntry() % 5));
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
}
}
} else {
if (store->GetEntry() + 5 < (int)entries.size()) {
store->SetBox(store->GetBox() + 5);
store->SetEntry(store->GetEntry() + 5);
}
}
}
if (hRepeat & KEY_RIGHT) {
if (store->GetEntry() < (int)entries.size() - 1) {
if (store->GetBox() < 14) {
store->SetBox(store->GetBox() + 1);
store->SetEntry(store->GetEntry() + 1);
} else {
store->SetBox(10);
store->SetEntry(store->GetEntry() + 1);
store->SetScreenIndx((store->GetEntry() / 5) - 2);
}
}
}
if (hRepeat & KEY_LEFT) {
if (store->GetEntry() > 0) {
if (store->GetBox() > 0) {
store->SetBox(store->GetBox() - 1);
store->SetEntry(store->GetEntry() - 1);
} else {
store->SetBox(4);
store->SetEntry(store->GetEntry() - 1);
store->SetScreenIndx((store->GetEntry() / 5));
}
}
}
if (hRepeat & KEY_UP) {
if (store->GetBox() < 5) {
if (store->GetEntry() > 4) {
store->SetEntry(store->GetEntry() - 5);
store->SetScreenIndx((store->GetEntry() / 5));
}
} else {
store->SetBox(store->GetBox() - 5);
store->SetEntry(store->GetEntry() - 5);
}
}
if (hDown & KEY_A) {
fetch = true;
smallDelay = 5;
lastMode = currentMode;
currentMode = 1;
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
static const std::vector<Structs::ButtonPos> GridBoxes = {
{ 25, 45, 50, 50 },
{ 100, 45, 50, 50 },
{ 175, 45, 50, 50 },
{ 250, 45, 50, 50 },
{ 325, 45, 50, 50 },
{ 25, 105, 50, 50 },
{ 100, 105, 50, 50 },
{ 175, 105, 50, 50 },
{ 250, 105, 50, 50 },
{ 325, 105, 50, 50 },
{ 25, 165, 50, 50 },
{ 100, 165, 50, 50 },
{ 175, 165, 50, 50 },
{ 250, 165, 50, 50 },
{ 325, 165, 50, 50 }
};
/*
Dessinez la grille supérieure.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::vector<std::unique_ptr<StoreEntry>> &entries : Const Référence à StoreEntries.
*/
void StoreUtils::DrawGrid(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (config->usebg() && store->customBG()) {
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
for (int i = 0, i2 = 0 + (store->GetScreenIndx() * 5); i2 < 15 + (store->GetScreenIndx() * 5) && i2 < (int)entries.size(); i2++, i++) {
/* Boxes. */
if (i == store->GetBox()) GFX::DrawBox(GridBoxes[i].x, GridBoxes[i].y, 50, 50, true);
/* Assurez-vous que les entrées sont plus grandes que lindex. */
if ((int)entries.size() > i2) {
if (entries[i2]) { // Assurez-vous que lentrée nest pas nullptr.
const C2D_Image tempImg = entries[i2]->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Centre W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Centre H.
C2D_DrawImageAt(tempImg, GridBoxes[i].x + 1 + offsetW, GridBoxes[i].y + 1 + offsetH, 0.5);
/* Mettre à jour la marque disponible. */
if (entries[i2]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, GridBoxes[i].x + 32, GridBoxes[i].y + 32);
}
}
}
}
}
/*
Poignée logique de grille supérieure.
Ici vous pouvez..
- Faire défiler la grille à laide du pavé en D.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence à StoreEntries.
const int &currentMode : Référence au mode actuel.
int &lastMode : Référence au dernier mode.
bool &fetch : Référence à fetch.
int &smallDelay : Référence au petit délai.
*/
void StoreUtils::GridLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int &currentMode, int &lastMode, bool &fetch, int &smallDelay) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (hRepeat & KEY_DOWN) {
if (store->GetBox() > 9) {
if (store->GetEntry() + 5 < (int)entries.size() - 1) {
store->SetEntry(store->GetEntry() + 5);
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
} else {
if (store->GetEntry() < (int)entries.size() - 1) {
store->SetEntry(entries.size() - 1);
store->SetBox(10 + (store->GetEntry() % 5));
if (entries.size() > 15) store->SetScreenIndx((store->GetEntry() / 5) - 2);
}
}
} else {
if (store->GetEntry() + 5 < (int)entries.size()) {
store->SetBox(store->GetBox() + 5);
store->SetEntry(store->GetEntry() + 5);
}
}
}
if (hRepeat & KEY_RIGHT) {
if (store->GetEntry() < (int)entries.size() - 1) {
if (store->GetBox() < 14) {
store->SetBox(store->GetBox() + 1);
store->SetEntry(store->GetEntry() + 1);
} else {
store->SetBox(10);
store->SetEntry(store->GetEntry() + 1);
store->SetScreenIndx((store->GetEntry() / 5) - 2);
}
}
}
if (hRepeat & KEY_LEFT) {
if (store->GetEntry() > 0) {
if (store->GetBox() > 0) {
store->SetBox(store->GetBox() - 1);
store->SetEntry(store->GetEntry() - 1);
} else {
store->SetBox(4);
store->SetEntry(store->GetEntry() - 1);
store->SetScreenIndx((store->GetEntry() / 5));
}
}
}
if (hRepeat & KEY_UP) {
if (store->GetBox() < 5) {
if (store->GetEntry() > 4) {
store->SetEntry(store->GetEntry() - 5);
store->SetScreenIndx((store->GetEntry() / 5));
}
} else {
store->SetBox(store->GetBox() - 5);
store->SetEntry(store->GetEntry() - 5);
}
}
if (hDown & KEY_A) {
fetch = true;
smallDelay = 5;
lastMode = currentMode;
currentMode = 1;
}
}
}
+121 -121
View File
@@ -1,122 +1,122 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
static const std::vector<Structs::ButtonPos> StoreBoxesList = {
{ 20, 45, 360, 50 },
{ 20, 105, 360, 50 },
{ 20, 165, 360, 50 }
};
/*
Dessinez la liste du haut.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::vector<std::unique_ptr<StoreEntry>> &entries : Const Référence à StoreEntries.
*/
void StoreUtils::DrawList(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (config->usebg() && store->customBG()) {
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
if (entries.size() > 0) {
for (int i = 0; i < 3 && i < (int)entries.size(); i++) {
if (i + store->GetScreenIndx() == store->GetEntry()) {
GFX::DrawBox(StoreBoxesList[i].x, StoreBoxesList[i].y, StoreBoxesList[i].w, StoreBoxesList[i].h, false);
}
/* Assurez-vous que les entrées sont plus grandes que lindex. */
if ((int)entries.size() > i + store->GetScreenIndx()) {
if (entries[i + store->GetScreenIndx()]) { // Assurez-vous que lentrée nest pas nulle.
const C2D_Image tempImg = entries[i + store->GetScreenIndx()]->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Centre W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Centre H.
C2D_DrawImageAt(tempImg, StoreBoxesList[i].x + 1 + offsetW, StoreBoxesList[i].y + 1 + offsetH, 0.5);
}
if (entries[i + store->GetScreenIndx()]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, StoreBoxesList[i].x + 32, StoreBoxesList[i].y + 32);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetTitle(), 300, 0, font);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
}
}
}
}
}
/*
Poignée logique de liste supérieure.
Ici vous pouvez..
- Faites défiler la grille avec le pavé en D vers le haut/vers le bas et sautez 3 entrées avec la gauche/droite.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence à StoreEntries.
int &currentMode : Const Référence au mode actuel.
int &lastMode : Référence au dernier mode.
bool &fetch : Référence à fetch.
int &smallDelay : Référence au petit délai.
*/
void StoreUtils::ListLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int &currentMode, int &lastMode, bool &fetch, int &smallDelay) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (hRepeat & KEY_DOWN) {
if (store->GetEntry() < (int)entries.size() - 1) store->SetEntry(store->GetEntry() + 1);
else store->SetEntry(0);
}
if (hRepeat & KEY_RIGHT) {
if (store->GetEntry() < (int)entries.size() - 3) store->SetEntry(store->GetEntry() + 3);
else store->SetEntry(entries.size() - 1);
}
if (hRepeat & KEY_LEFT) {
if (store->GetEntry() - 2 > 0) store->SetEntry(store->GetEntry() - 3);
else store->SetEntry(0);
}
if (hRepeat & KEY_UP) {
if (store->GetEntry() > 0) store->SetEntry(store->GetEntry() - 1);
else store->SetEntry(entries.size() - 1);
}
if (hDown & KEY_A) {
fetch = true;
smallDelay = 5;
lastMode = currentMode;
currentMode = 1;
}
/* Scroll Logic. */
if (store->GetEntry() < store->GetScreenIndx()) store->SetScreenIndx(store->GetEntry());
else if (store->GetEntry() > store->GetScreenIndx() + 3 - 1) store->SetScreenIndx(store->GetEntry() - 3 + 1);
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
static const std::vector<Structs::ButtonPos> StoreBoxesList = {
{ 20, 45, 360, 50 },
{ 20, 105, 360, 50 },
{ 20, 165, 360, 50 }
};
/*
Dessinez la liste du haut.
const std::unique_ptr<Store> &store : Const Référence à la classe Store.
const std::vector<std::unique_ptr<StoreEntry>> &entries : Const Référence à StoreEntries.
*/
void StoreUtils::DrawList(const std::unique_ptr<Store> &store, const std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (config->usebg() && store->customBG()) {
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
if (entries.size() > 0) {
for (int i = 0; i < 3 && i < (int)entries.size(); i++) {
if (i + store->GetScreenIndx() == store->GetEntry()) {
GFX::DrawBox(StoreBoxesList[i].x, StoreBoxesList[i].y, StoreBoxesList[i].w, StoreBoxesList[i].h, false);
}
/* Assurez-vous que les entrées sont plus grandes que lindex. */
if ((int)entries.size() > i + store->GetScreenIndx()) {
if (entries[i + store->GetScreenIndx()]) { // Assurez-vous que lentrée nest pas nulle.
const C2D_Image tempImg = entries[i + store->GetScreenIndx()]->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Centre W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Centre H.
C2D_DrawImageAt(tempImg, StoreBoxesList[i].x + 1 + offsetW, StoreBoxesList[i].y + 1 + offsetH, 0.5);
}
if (entries[i + store->GetScreenIndx()]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, StoreBoxesList[i].x + 32, StoreBoxesList[i].y + 32);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetTitle(), 300, 0, font);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24, 0.6f, TEXT_COLOR, entries[i + store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
}
}
}
}
}
/*
Poignée logique de liste supérieure.
Ici vous pouvez..
- Faites défiler la grille avec le pavé en D vers le haut/vers le bas et sautez 3 entrées avec la gauche/droite.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence à StoreEntries.
int &currentMode : Const Référence au mode actuel.
int &lastMode : Référence au dernier mode.
bool &fetch : Référence à fetch.
int &smallDelay : Référence au petit délai.
*/
void StoreUtils::ListLogic(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, int &currentMode, int &lastMode, bool &fetch, int &smallDelay) {
if (store) { // Assurez-vous que le magasin nest pas un nullptr.
if (hRepeat & KEY_DOWN) {
if (store->GetEntry() < (int)entries.size() - 1) store->SetEntry(store->GetEntry() + 1);
else store->SetEntry(0);
}
if (hRepeat & KEY_RIGHT) {
if (store->GetEntry() < (int)entries.size() - 3) store->SetEntry(store->GetEntry() + 3);
else store->SetEntry(entries.size() - 1);
}
if (hRepeat & KEY_LEFT) {
if (store->GetEntry() - 2 > 0) store->SetEntry(store->GetEntry() - 3);
else store->SetEntry(0);
}
if (hRepeat & KEY_UP) {
if (store->GetEntry() > 0) store->SetEntry(store->GetEntry() - 1);
else store->SetEntry(entries.size() - 1);
}
if (hDown & KEY_A) {
fetch = true;
smallDelay = 5;
lastMode = currentMode;
currentMode = 1;
}
/* Scroll Logic. */
if (store->GetEntry() < store->GetScreenIndx()) store->SetScreenIndx(store->GetEntry());
else if (store->GetEntry() > store->GetScreenIndx() + 3 - 1) store->SetScreenIndx(store->GetEntry() - 3 + 1);
}
}
+125 -125
View File
@@ -1,126 +1,126 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> markBox = {
{ 10, 94, 52, 52 },
{ 72, 94, 52, 52 },
{ 134, 94, 52, 52 },
{ 196, 94, 52, 52 },
{ 258, 94, 52, 52 },
{ 45, 215, 24, 24 }
};
/*
Dessinez la partie Marquage.
int marks : Les drapeaux de marque actifs.
*/
void StoreUtils::DisplayMarkBox(int marks) {
Gui::Draw_Rect(0, 0, 320, 240, DIM_COLOR); // Assombrir.
Gui::Draw_Rect(markBox[0].x, markBox[0].y, markBox[0].w, markBox[0].h, (marks & favoriteMarks::STAR ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[1].x, markBox[1].y, markBox[1].w, markBox[1].h, (marks & favoriteMarks::HEART ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[2].x, markBox[2].y, markBox[2].w, markBox[2].h, (marks & favoriteMarks::DIAMOND ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[3].x, markBox[3].y, markBox[3].w, markBox[3].h, (marks & favoriteMarks::CLUBS ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[4].x, markBox[4].y, markBox[4].w, markBox[4].h, (marks & favoriteMarks::SPADE ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::DrawString(markBox[0].x + 15, markBox[0].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[1].x + 15, markBox[1].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[2].x + 15, markBox[2].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[3].x + 15, markBox[3].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[4].x + 15, markBox[4].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
GFX::DrawBox(markBox[5].x, markBox[5].y, markBox[5].w, markBox[5].h, false);
Gui::DrawString(markBox[5].x + 5, markBox[5].y + 2, 0.6f, TEXT_COLOR, "", 0, 0, font);
}
/*
Sélectionner la poignée de menu.
Ici vous pouvez..
- Cochez lapplication sélectionnée.
- Retournez à EntryInfo avec `B`.
std::unique_ptrStoreEntry> &entry : Référence au StoreEntry actuel.
const std::unique_ptrStore> &store : Const Référence au Store, puisque nous ny modifions rien.
bool &showMark : Référence à showMark, pour que nous sachions si nous devrions rester ici ou non.
std::unique_ptrMeta> &meta : Référence à la classe Meta.
*/
void StoreUtils::MarkHandle(std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store, bool &showMark, std::unique_ptr<Meta> &meta) {
hidScanInput();
touchPosition t;
hidTouchRead(&t);
if (meta && entry && store) {
if (hidKeysDown() & KEY_TOUCH) {
/* Etoiles. */
if (touching(t, markBox[0])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::STAR);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Coeur. */
} else if (touching(t, markBox[1])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::HEART);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Diamand. */
} else if (touching(t, markBox[2])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::DIAMOND);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Clubs. */
} else if (touching(t, markBox[3])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::CLUBS);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Spade. */
} else if (touching(t, markBox[4])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::SPADE);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
}
}
}
if ((hidKeysDown() & KEY_B || hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_TOUCH && touching(t, markBox[5]))) showMark = false; // Return back to screen.
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> markBox = {
{ 10, 94, 52, 52 },
{ 72, 94, 52, 52 },
{ 134, 94, 52, 52 },
{ 196, 94, 52, 52 },
{ 258, 94, 52, 52 },
{ 45, 215, 24, 24 }
};
/*
Dessinez la partie Marquage.
int marks : Les drapeaux de marque actifs.
*/
void StoreUtils::DisplayMarkBox(int marks) {
Gui::Draw_Rect(0, 0, 320, 240, DIM_COLOR); // Assombrir.
Gui::Draw_Rect(markBox[0].x, markBox[0].y, markBox[0].w, markBox[0].h, (marks & favoriteMarks::STAR ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[1].x, markBox[1].y, markBox[1].w, markBox[1].h, (marks & favoriteMarks::HEART ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[2].x, markBox[2].y, markBox[2].w, markBox[2].h, (marks & favoriteMarks::DIAMOND ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[3].x, markBox[3].y, markBox[3].w, markBox[3].h, (marks & favoriteMarks::CLUBS ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(markBox[4].x, markBox[4].y, markBox[4].w, markBox[4].h, (marks & favoriteMarks::SPADE ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::DrawString(markBox[0].x + 15, markBox[0].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[1].x + 15, markBox[1].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[2].x + 15, markBox[2].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[3].x + 15, markBox[3].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(markBox[4].x + 15, markBox[4].y + 11, 0.9, TEXT_COLOR, "", 0, 0, font);
GFX::DrawBox(markBox[5].x, markBox[5].y, markBox[5].w, markBox[5].h, false);
Gui::DrawString(markBox[5].x + 5, markBox[5].y + 2, 0.6f, TEXT_COLOR, "", 0, 0, font);
}
/*
Sélectionner la poignée de menu.
Ici vous pouvez..
- Cochez lapplication sélectionnée.
- Retournez à EntryInfo avec `B`.
std::unique_ptrStoreEntry> &entry : Référence au StoreEntry actuel.
const std::unique_ptrStore> &store : Const Référence au Store, puisque nous ny modifions rien.
bool &showMark : Référence à showMark, pour que nous sachions si nous devrions rester ici ou non.
std::unique_ptrMeta> &meta : Référence à la classe Meta.
*/
void StoreUtils::MarkHandle(std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store, bool &showMark, std::unique_ptr<Meta> &meta) {
hidScanInput();
touchPosition t;
hidTouchRead(&t);
if (meta && entry && store) {
if (hidKeysDown() & KEY_TOUCH) {
/* Etoiles. */
if (touching(t, markBox[0])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::STAR);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Coeur. */
} else if (touching(t, markBox[1])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::HEART);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Diamand. */
} else if (touching(t, markBox[2])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::DIAMOND);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Clubs. */
} else if (touching(t, markBox[3])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::CLUBS);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
/* Spade. */
} else if (touching(t, markBox[4])) {
meta->SetMarks(store->GetEshopTitle(), entry->GetTitle(),
meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()) ^ favoriteMarks::SPADE);
entry->SetMark(meta->GetMarks(store->GetEshopTitle(), entry->GetTitle()));
}
}
}
if ((hidKeysDown() & KEY_B || hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_TOUCH && touching(t, markBox[5]))) showMark = false; // Return back to screen.
}
+134 -134
View File
@@ -1,135 +1,135 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "fileBrowse.hpp"
#include "meta.hpp"
#include <unistd.h>
/*
Le Constructeur de la Meta.
Inclut la création de fichier MetaData, si elle nexiste pas.
*/
Meta::Meta() {
if (access(_META_PATH, F_OK) != 0) {
FILE *temp = fopen(_META_PATH, "w");
char tmp[2] = { '{', '}' };
fwrite(tmp, sizeof(tmp), 1, temp);
fclose(temp);
}
FILE *temp = fopen(_META_PATH, "rt");
this->metadataJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (config->metadata()) this->ImportMetadata();
}
/*
Importez les anciennes métadonnées du fichier 'updates.json'.
*/
void Meta::ImportMetadata() {
if (access("sdmc:/3ds/DarkStore/updates.json", F_OK) != 0) {
config->metadata(false);
return; // Introuvables.
}
Msg::DisplayMsg(Lang::get("FETCHING_METADATA"));
FILE *old = fopen("sdmc:/3ds/DarkStore/updates.json", "r");
nlohmann::json oldJson = nlohmann::json::parse(old, nullptr, false);
fclose(old);
std::vector<EshopInfo> info = GetEshopInfo(_STORE_PATH); // Va chercher eShop.
for (int i = 0; i < (int)info.size(); i++) {
if (info[i].Title != "" && oldJson.contains(info[i].FileName)) {
for(auto it = oldJson[info[i].FileName].begin(); it != oldJson[info[i].FileName].end(); ++it) {
this->SetUpdated(info[i].Title, it.key().c_str(), it.value().get<std::string>());
}
}
}
config->metadata(false);
}
/*
Obtenir la dernière mise à jour.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
*/
std::string Meta::GetUpdated(const std::string &EshopName, const std::string &entry) const {
if (!this->metadataJson.contains(EshopName)) return ""; // Le nom de l'eShop nexiste pas.
if (!this->metadataJson[EshopName].contains(entry)) return ""; // L'entrée n'existe pas.
if (!this->metadataJson[EshopName][entry].contains("updated")) return ""; // Les mises à jour n'existe pas.
if (this->metadataJson[EshopName][entry]["updated"].is_string()) return this->metadataJson[EshopName][entry]["updated"];
return "";
}
/*
Prends les marques.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
*/
int Meta::GetMarks(const std::string &EshopName, const std::string &entry) const {
int temp = 0;
if (!this->metadataJson.contains(EshopName)) return temp; // Le nom de l'eShop nexiste pas.
if (!this->metadataJson[EshopName].contains(entry)) return temp; // L'entrée n'existe pas.
if (!this->metadataJson[EshopName][entry].contains("marks")) return temp; // Les marques n'existe pas.
if (this->metadataJson[EshopName][entry]["marks"].is_number()) return this->metadataJson[EshopName][entry]["marks"];
return temp;
}
/*
Retourner, si la mise à jour est disponible.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
const std::string &updated : Compare pour la mise à jour.
*/
bool Meta::UpdateAvailable(const std::string &EshopName, const std::string &entry, const std::string &updated) const {
if (this->GetUpdated(EshopName, entry) != "" && updated != "") {
return strcasecmp(updated.c_str(), this->GetUpdated(EshopName, entry).c_str()) > 0;
}
return false;
}
/*
Lappel de sauvegarde.
Ecrire au fichier.. appelé sur destructor.
*/
void Meta::SaveCall() {
FILE *file = fopen(_META_PATH, "wb");
const std::string dump = this->metadataJson.dump(1, '\t');
fwrite(dump.c_str(), 1, dump.size(), file);
fclose(file);
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "fileBrowse.hpp"
#include "meta.hpp"
#include <unistd.h>
/*
Le Constructeur de la Meta.
Inclut la création de fichier MetaData, si elle nexiste pas.
*/
Meta::Meta() {
if (access(_META_PATH, F_OK) != 0) {
FILE *temp = fopen(_META_PATH, "w");
char tmp[2] = { '{', '}' };
fwrite(tmp, sizeof(tmp), 1, temp);
fclose(temp);
}
FILE *temp = fopen(_META_PATH, "rt");
this->metadataJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (config->metadata()) this->ImportMetadata();
}
/*
Importez les anciennes métadonnées du fichier 'updates.json'.
*/
void Meta::ImportMetadata() {
if (access("sdmc:/3ds/DarkStore/updates.json", F_OK) != 0) {
config->metadata(false);
return; // Introuvables.
}
Msg::DisplayMsg(Lang::get("FETCHING_METADATA"));
FILE *old = fopen("sdmc:/3ds/DarkStore/updates.json", "r");
nlohmann::json oldJson = nlohmann::json::parse(old, nullptr, false);
fclose(old);
std::vector<EshopInfo> info = GetEshopInfo(_STORE_PATH); // Va chercher eShop.
for (int i = 0; i < (int)info.size(); i++) {
if (info[i].Title != "" && oldJson.contains(info[i].FileName)) {
for(auto it = oldJson[info[i].FileName].begin(); it != oldJson[info[i].FileName].end(); ++it) {
this->SetUpdated(info[i].Title, it.key().c_str(), it.value().get<std::string>());
}
}
}
config->metadata(false);
}
/*
Obtenir la dernière mise à jour.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
*/
std::string Meta::GetUpdated(const std::string &EshopName, const std::string &entry) const {
if (!this->metadataJson.contains(EshopName)) return ""; // Le nom de l'eShop nexiste pas.
if (!this->metadataJson[EshopName].contains(entry)) return ""; // L'entrée n'existe pas.
if (!this->metadataJson[EshopName][entry].contains("updated")) return ""; // Les mises à jour n'existe pas.
if (this->metadataJson[EshopName][entry]["updated"].is_string()) return this->metadataJson[EshopName][entry]["updated"];
return "";
}
/*
Prends les marques.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
*/
int Meta::GetMarks(const std::string &EshopName, const std::string &entry) const {
int temp = 0;
if (!this->metadataJson.contains(EshopName)) return temp; // Le nom de l'eShop nexiste pas.
if (!this->metadataJson[EshopName].contains(entry)) return temp; // L'entrée n'existe pas.
if (!this->metadataJson[EshopName][entry].contains("marks")) return temp; // Les marques n'existe pas.
if (this->metadataJson[EshopName][entry]["marks"].is_number()) return this->metadataJson[EshopName][entry]["marks"];
return temp;
}
/*
Retourner, si la mise à jour est disponible.
const std::string &EshopName : Le nom eShop.
const std::string &entry : Le nom de lentrée.
const std::string &updated : Compare pour la mise à jour.
*/
bool Meta::UpdateAvailable(const std::string &EshopName, const std::string &entry, const std::string &updated) const {
if (this->GetUpdated(EshopName, entry) != "" && updated != "") {
return strcasecmp(updated.c_str(), this->GetUpdated(EshopName, entry).c_str()) > 0;
}
return false;
}
/*
Lappel de sauvegarde.
Ecrire au fichier.. appelé sur destructor.
*/
void Meta::SaveCall() {
FILE *file = fopen(_META_PATH, "wb");
const std::string dump = this->metadataJson.dump(1, '\t');
fwrite(dump.c_str(), 1, dump.size(), file);
fclose(file);
}
+134 -134
View File
@@ -1,135 +1,135 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "queueSystem.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
#include <curl/curl.h>
extern u32 extractSize, writeOffset;
extern u32 installSize, installOffset;
extern u32 copyOffset, copySize;
extern curl_off_t downloadTotal;
extern curl_off_t downloadNow;
#define QUEUE_ENTRIES 2 // 2 Entries per screen or so.
extern bool touching(touchPosition touch, Structs::ButtonPos button);
/* TODO: Rework positions + sizes.. */
static const std::vector<Structs::ButtonPos> QueueBoxes = {
{ 46, 32, 266, 80 },
{ 46, 132, 266, 80 }
};
extern std::deque<std::unique_ptr<Queue>> queueEntries;
void DrawStatus(QueueStatus s) {
char str[256];
/* String Handle. */
switch(s) {
case QueueStatus::None:
case QueueStatus::Failed:
case QueueStatus::Done:
break;
case QueueStatus::Downloading:
if (downloadTotal < 1.0f) downloadTotal = 1.0f;
if (downloadTotal < downloadNow) downloadTotal = downloadNow;
snprintf(str, sizeof(str), "Downloading... %s / %s (%.2f%%)",
StringUtils::formatBytes(downloadNow).c_str(),
StringUtils::formatBytes(downloadTotal).c_str(),
((float)downloadNow/(float)downloadTotal) * 100.0f);
break;
case QueueStatus::Extracting:
snprintf(str, sizeof(str), "Extracting... %s / %s (%.2f%%)",
StringUtils::formatBytes(writeOffset).c_str(),
StringUtils::formatBytes(extractSize).c_str(),
((float)writeOffset/(float)extractSize) * 100.0f);
break;
case QueueStatus::Installing:
snprintf(str, sizeof(str), "Installing... %s / %s (%.2f%%)",
StringUtils::formatBytes(installOffset).c_str(),
StringUtils::formatBytes(installSize).c_str(),
((float)installOffset/(float)installSize) * 100.0f);
break;
}
/* Draw Handle. */
switch(s) {
case QueueStatus::None:
case QueueStatus::Failed:
case QueueStatus::Done:
break;
case QueueStatus::Downloading:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)downloadNow / (float)downloadTotal) * 180.0f), 28, WHITE);
break;
case QueueStatus::Extracting:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)writeOffset / (float)extractSize) * 180.0f), 28, WHITE);
break;
case QueueStatus::Installing:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)installOffset / (float)installSize) * 180.0f), 28, WHITE);
break;
}
}
void StoreUtils::DrawQueueMenu(const int queueIndex) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, "Queue System", 273, 0, font);
LightLock_Lock(&QueueSystem::lock);
if (!queueEntries.empty()) {
GFX::DrawBox(QueueBoxes[0].x, QueueBoxes[0].y, QueueBoxes[0].w, QueueBoxes[0].h, false);
C2D_DrawImageAt(queueEntries[0]->icn, QueueBoxes[0].x + 5, QueueBoxes[0].y + 21, 0.5f);
DrawStatus(queueEntries[0]->status);
}
LightLock_Unlock(&QueueSystem::lock);
}
void StoreUtils::QueueMenuHandle(int &queueIndex) {
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "queueSystem.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
#include <curl/curl.h>
extern u32 extractSize, writeOffset;
extern u32 installSize, installOffset;
extern u32 copyOffset, copySize;
extern curl_off_t downloadTotal;
extern curl_off_t downloadNow;
#define QUEUE_ENTRIES 2 // 2 Entries per screen or so.
extern bool touching(touchPosition touch, Structs::ButtonPos button);
/* TODO: Rework positions + sizes.. */
static const std::vector<Structs::ButtonPos> QueueBoxes = {
{ 46, 32, 266, 80 },
{ 46, 132, 266, 80 }
};
extern std::deque<std::unique_ptr<Queue>> queueEntries;
void DrawStatus(QueueStatus s) {
char str[256];
/* String Handle. */
switch(s) {
case QueueStatus::None:
case QueueStatus::Failed:
case QueueStatus::Done:
break;
case QueueStatus::Downloading:
if (downloadTotal < 1.0f) downloadTotal = 1.0f;
if (downloadTotal < downloadNow) downloadTotal = downloadNow;
snprintf(str, sizeof(str), "Downloading... %s / %s (%.2f%%)",
StringUtils::formatBytes(downloadNow).c_str(),
StringUtils::formatBytes(downloadTotal).c_str(),
((float)downloadNow/(float)downloadTotal) * 100.0f);
break;
case QueueStatus::Extracting:
snprintf(str, sizeof(str), "Extracting... %s / %s (%.2f%%)",
StringUtils::formatBytes(writeOffset).c_str(),
StringUtils::formatBytes(extractSize).c_str(),
((float)writeOffset/(float)extractSize) * 100.0f);
break;
case QueueStatus::Installing:
snprintf(str, sizeof(str), "Installing... %s / %s (%.2f%%)",
StringUtils::formatBytes(installOffset).c_str(),
StringUtils::formatBytes(installSize).c_str(),
((float)installOffset/(float)installSize) * 100.0f);
break;
}
/* Draw Handle. */
switch(s) {
case QueueStatus::None:
case QueueStatus::Failed:
case QueueStatus::Done:
break;
case QueueStatus::Downloading:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)downloadNow / (float)downloadTotal) * 180.0f), 28, WHITE);
break;
case QueueStatus::Extracting:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)writeOffset / (float)extractSize) * 180.0f), 28, WHITE);
break;
case QueueStatus::Installing:
Gui::DrawString(QueueBoxes[0].x + 10, QueueBoxes[0].y + 5, 0.4f, TEXT_COLOR, str, 250, 0, font);
Gui::Draw_Rect(QueueBoxes[0].x + 60, QueueBoxes[0].y + 25, 180, 30, BLACK);
Gui::Draw_Rect(QueueBoxes[0].x + 60 + 1, QueueBoxes[0].y + 25 + 1, (int)(((float)installOffset / (float)installSize) * 180.0f), 28, WHITE);
break;
}
}
void StoreUtils::DrawQueueMenu(const int queueIndex) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, "Queue System", 273, 0, font);
LightLock_Lock(&QueueSystem::lock);
if (!queueEntries.empty()) {
GFX::DrawBox(QueueBoxes[0].x, QueueBoxes[0].y, QueueBoxes[0].w, QueueBoxes[0].h, false);
C2D_DrawImageAt(queueEntries[0]->icn, QueueBoxes[0].x + 5, QueueBoxes[0].y + 21, 0.5f);
DrawStatus(queueEntries[0]->status);
}
LightLock_Unlock(&QueueSystem::lock);
}
void StoreUtils::QueueMenuHandle(int &queueIndex) {
}
+117 -117
View File
@@ -1,118 +1,118 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "storeUtils.hpp"
void StoreUtils::DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store) {
if (entry && store) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, entry->GetReleaseNotes(), 390, 0, font, C2D_WordWrap);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, entry->GetTitle(), 390, 0, font);
} else {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
}
/*
As the name says: Release notes logic.
int &scrollIndex: The scroll index for the Release Notes text.
int &storeMode: The store mode to properly return back.
*/
void StoreUtils::ReleaseNotesLogic(int &scrollIndex, int &storeMode) {
if (hRepeat & KEY_DOWN) scrollIndex += Gui::GetStringHeight(0.5f, "", font);
if (hRepeat & KEY_UP) {
if (scrollIndex > 0) scrollIndex -= Gui::GetStringHeight(0.5f, "", font);
}
if (hDown & KEY_B) {
scrollIndex = 0;
storeMode = 0;
}
}
/*
I place it temporarely here for now.
Display Release changelog for DarkStore.
*/
void DisplayChangelog() {
if (config->changelog()) {
config->changelog(false);
bool confirmed = false;
const std::string notes = GetChangelog();
if (notes == "") return;
int scrollIndex = 0;
while(!confirmed) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, notes, 390, 0, font, C2D_WordWrap);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "DarkStore", 390, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 217, 0.7f, TEXT_COLOR, C_V, 390, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, BAR_OUTL_COLOR);
C3D_FrameEnd(0);
hidScanInput();
touchPosition t;
touchRead(&t);
u32 repeat = hidKeysDownRepeat();
u32 down = hidKeysDown();
/* Scroll Logic. */
if (repeat & KEY_DOWN) scrollIndex += Gui::GetStringHeight(0.5f, "", font);
if (repeat & KEY_UP) {
if (scrollIndex > 0) scrollIndex -= Gui::GetStringHeight(0.5f, "", font);
}
if ((down & KEY_A) || (down & KEY_B) || (down & KEY_START) || (down & KEY_TOUCH)) confirmed = true;
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "storeUtils.hpp"
void StoreUtils::DrawReleaseNotes(const int &scrollIndex, const std::unique_ptr<StoreEntry> &entry, const std::unique_ptr<Store> &store) {
if (entry && store) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, entry->GetReleaseNotes(), 390, 0, font, C2D_WordWrap);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, entry->GetTitle(), 390, 0, font);
} else {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
}
}
/*
As the name says: Release notes logic.
int &scrollIndex: The scroll index for the Release Notes text.
int &storeMode: The store mode to properly return back.
*/
void StoreUtils::ReleaseNotesLogic(int &scrollIndex, int &storeMode) {
if (hRepeat & KEY_DOWN) scrollIndex += Gui::GetStringHeight(0.5f, "", font);
if (hRepeat & KEY_UP) {
if (scrollIndex > 0) scrollIndex -= Gui::GetStringHeight(0.5f, "", font);
}
if (hDown & KEY_B) {
scrollIndex = 0;
storeMode = 0;
}
}
/*
I place it temporarely here for now.
Display Release changelog for DarkStore.
*/
void DisplayChangelog() {
if (config->changelog()) {
config->changelog(false);
bool confirmed = false;
const std::string notes = GetChangelog();
if (notes == "") return;
int scrollIndex = 0;
while(!confirmed) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 26, 400, 214, BG_COLOR);
Gui::DrawString(5, 25 - scrollIndex, 0.5f, TEXT_COLOR, notes, 390, 0, font, C2D_WordWrap);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "DarkStore", 390, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 217, 0.7f, TEXT_COLOR, C_V, 390, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, BAR_OUTL_COLOR);
C3D_FrameEnd(0);
hidScanInput();
touchPosition t;
touchRead(&t);
u32 repeat = hidKeysDownRepeat();
u32 down = hidKeysDown();
/* Scroll Logic. */
if (repeat & KEY_DOWN) scrollIndex += Gui::GetStringHeight(0.5f, "", font);
if (repeat & KEY_UP) {
if (scrollIndex > 0) scrollIndex -= Gui::GetStringHeight(0.5f, "", font);
}
if ((down & KEY_A) || (down & KEY_B) || (down & KEY_START) || (down & KEY_TOUCH)) confirmed = true;
}
}
}
+150 -150
View File
@@ -1,151 +1,151 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
extern bool checkWifiStatus();
/*
Draw the Screenshot menu.
const C2D_Image &img: The C2D_Image of the screenshot.
const int sIndex: The Screenshot index.
const bool sFetch: If fetching screenshots or not.
const int screenshotSize: The screenshot amount.
const std::string &name: The name of the screenshot.
const int zoom: The zoom level, zoom out, 1x scale, or zoom in.
const bool canDisplay: If can display, or not.
*/
void StoreUtils::DrawScreenshotMenu(const C2D_Image &img, const int sIndex, const bool sFetch, const int screenshotSize, const std::string &name, const int zoom, const bool canDisplay) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 240, BG_COLOR);
if (!canDisplay) {
GFX::DrawBottom();
if (screenshotSize > 0) { // if texture is nullptr AND screenshot size is larger than 0.
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("SCREENSHOT_COULD_NOT_LOAD"), 310);
} else {
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
}
return;
}
if (!sFetch) { // Only, if not fetch. This avoids a small flicker of the old screenshot on entries without screenshots.
if (screenshotSize > 0) {
float scale = 1.0f;
if (zoom == 0) {
scale = std::min(1.0f, std::min(400.0f / img.subtex->width, 240.0f / img.subtex->height));
if (img.tex) C2D_DrawImageAt(img, (400 - img.subtex->width * scale) / 2, (240 - img.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
} else {
// Create new C2D_Image with smaller subtex
C2D_Image top = img;
if (img.subtex->height > 240)
top.subtex = new Tex3DS_SubTexture({img.subtex->width, (u16)(img.subtex->height / 2), img.subtex->left, img.subtex->top, img.subtex->right, 1.0f - (img.subtex->height / 2 / 512.0f)});
// If zoom == 2, then zoom in to fit the screen
if (zoom == 2)
scale = std::min(400.0f / top.subtex->width, 240.0f / top.subtex->height);
if (top.tex) C2D_DrawImageAt(top, (400 - top.subtex->width * scale) / 2, (240 - top.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
// Only delete if new
if (top.subtex->height > 240)
delete top.subtex;
}
GFX::DrawBottom();
/* Bottom. */
if (zoom > 0 && img.subtex->height * scale > 240) {
C2D_Image bottom = img;
bottom.subtex = new Tex3DS_SubTexture({img.subtex->width, (u16)(img.subtex->height / 2), img.subtex->left, img.subtex->bottom + (img.subtex->height / 2 / 512.0f), img.subtex->right, img.subtex->bottom});
if (bottom.tex) C2D_DrawImageAt(bottom, (320 - bottom.subtex->width * scale) / 2, (240 - bottom.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
delete bottom.subtex;
} else {
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("SCREENSHOT_INSTRUCTIONS"), 310, 0, font);
char screenshots[0x100];
snprintf(screenshots, sizeof(screenshots), Lang::get("SCREENSHOT").c_str(), sIndex + 1, screenshotSize);
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, screenshots, 310, 0, font);
Gui::DrawStringCentered(0, 40, 0.6f, WHITE, name, 310, 0, font);
}
} else {
GFX::DrawBottom();
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
}
}
}
/*
Screenshot Menu handle.
C2D_Image &img: The C2D_Image of the screenshot.
int &sIndex: The Screenshot index.
bool &sFetch: If fetching screenshots or not.
const int screenshotSize: The screenshot amount.
int &zoom: The zoom level, zoom out, 1x scale, or zoom in.
bool &canDisplay: If can display or not.
*/
void StoreUtils::ScreenshotMenu(C2D_Image &img, int &sIndex, bool &sFetch, int &storeMode, const int screenshotSize, int &zoom, bool &canDisplay) {
if (hDown & KEY_B) {
canDisplay = false;
zoom = 0;
sIndex = 0;
storeMode = 0; // Go back to EntryInfo.
}
if ((hDown & KEY_RIGHT) || (hDown & KEY_R)) {
if (checkWifiStatus()) {
if (sIndex < screenshotSize - 1) {
sIndex++;
sFetch = true;
}
}
}
if (hDown & KEY_DOWN && zoom > 0) zoom--;
if (hDown & KEY_UP && zoom < 2) zoom++;
if ((hDown & KEY_LEFT) || (hDown & KEY_L)) {
if (checkWifiStatus()) {
if (sIndex > 0) {
sIndex--;
sFetch = true;
}
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
extern bool checkWifiStatus();
/*
Draw the Screenshot menu.
const C2D_Image &img: The C2D_Image of the screenshot.
const int sIndex: The Screenshot index.
const bool sFetch: If fetching screenshots or not.
const int screenshotSize: The screenshot amount.
const std::string &name: The name of the screenshot.
const int zoom: The zoom level, zoom out, 1x scale, or zoom in.
const bool canDisplay: If can display, or not.
*/
void StoreUtils::DrawScreenshotMenu(const C2D_Image &img, const int sIndex, const bool sFetch, const int screenshotSize, const std::string &name, const int zoom, const bool canDisplay) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 240, BG_COLOR);
if (!canDisplay) {
GFX::DrawBottom();
if (screenshotSize > 0) { // if texture is nullptr AND screenshot size is larger than 0.
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("SCREENSHOT_COULD_NOT_LOAD"), 310);
} else {
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
}
return;
}
if (!sFetch) { // Only, if not fetch. This avoids a small flicker of the old screenshot on entries without screenshots.
if (screenshotSize > 0) {
float scale = 1.0f;
if (zoom == 0) {
scale = std::min(1.0f, std::min(400.0f / img.subtex->width, 240.0f / img.subtex->height));
if (img.tex) C2D_DrawImageAt(img, (400 - img.subtex->width * scale) / 2, (240 - img.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
} else {
// Create new C2D_Image with smaller subtex
C2D_Image top = img;
if (img.subtex->height > 240)
top.subtex = new Tex3DS_SubTexture({img.subtex->width, (u16)(img.subtex->height / 2), img.subtex->left, img.subtex->top, img.subtex->right, 1.0f - (img.subtex->height / 2 / 512.0f)});
// If zoom == 2, then zoom in to fit the screen
if (zoom == 2)
scale = std::min(400.0f / top.subtex->width, 240.0f / top.subtex->height);
if (top.tex) C2D_DrawImageAt(top, (400 - top.subtex->width * scale) / 2, (240 - top.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
// Only delete if new
if (top.subtex->height > 240)
delete top.subtex;
}
GFX::DrawBottom();
/* Bottom. */
if (zoom > 0 && img.subtex->height * scale > 240) {
C2D_Image bottom = img;
bottom.subtex = new Tex3DS_SubTexture({img.subtex->width, (u16)(img.subtex->height / 2), img.subtex->left, img.subtex->bottom + (img.subtex->height / 2 / 512.0f), img.subtex->right, img.subtex->bottom});
if (bottom.tex) C2D_DrawImageAt(bottom, (320 - bottom.subtex->width * scale) / 2, (240 - bottom.subtex->height * scale) / 2, 0.5f, nullptr, scale, scale);
delete bottom.subtex;
} else {
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("SCREENSHOT_INSTRUCTIONS"), 310, 0, font);
char screenshots[0x100];
snprintf(screenshots, sizeof(screenshots), Lang::get("SCREENSHOT").c_str(), sIndex + 1, screenshotSize);
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, screenshots, 310, 0, font);
Gui::DrawStringCentered(0, 40, 0.6f, WHITE, name, 310, 0, font);
}
} else {
GFX::DrawBottom();
Gui::DrawStringCentered(0, 2, 0.6f, WHITE, Lang::get("NO_SCREENSHOTS_AVAILABLE"), 310);
}
}
}
/*
Screenshot Menu handle.
C2D_Image &img: The C2D_Image of the screenshot.
int &sIndex: The Screenshot index.
bool &sFetch: If fetching screenshots or not.
const int screenshotSize: The screenshot amount.
int &zoom: The zoom level, zoom out, 1x scale, or zoom in.
bool &canDisplay: If can display or not.
*/
void StoreUtils::ScreenshotMenu(C2D_Image &img, int &sIndex, bool &sFetch, int &storeMode, const int screenshotSize, int &zoom, bool &canDisplay) {
if (hDown & KEY_B) {
canDisplay = false;
zoom = 0;
sIndex = 0;
storeMode = 0; // Go back to EntryInfo.
}
if ((hDown & KEY_RIGHT) || (hDown & KEY_R)) {
if (checkWifiStatus()) {
if (sIndex < screenshotSize - 1) {
sIndex++;
sFetch = true;
}
}
}
if (hDown & KEY_DOWN && zoom > 0) zoom--;
if (hDown & KEY_UP && zoom < 2) zoom++;
if ((hDown & KEY_LEFT) || (hDown & KEY_L)) {
if (checkWifiStatus()) {
if (sIndex > 0) {
sIndex--;
sFetch = true;
}
}
}
}
+203 -203
View File
@@ -1,204 +1,204 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> SearchMenu = {
{ 51, 45, 262, 30 }, // Search bar.
/* Inclure. */
{ 85, 109, 50, 10 },
{ 85, 125, 50, 10 },
{ 167, 109, 50, 10 },
{ 167, 125, 50, 10 },
/* Filtrer. */
{ 82, 195, 30, 30 },
{ 117, 195, 30, 30 },
{ 152, 195, 30, 30 },
{ 187, 195, 30, 30 },
{ 222, 195, 30, 30 },
{ 257, 195, 30, 30 }
};
/*
Dessinez le menu Recherche + Filtre.
const std::vectorbool> &searchIncludes : Const Référence à la searchIncludes.
const std::string &searchResult : Const Référence à searchResult.
int marks : Les drapeaux de marque de filtre.
bool updateFilter : Le filtre de mise à jour.
*/
void StoreUtils::DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(21, 2, 0.6, TEXT_COLOR, Lang::get("SEARCH_FILTERS"), 269, 0, font);
Gui::Draw_Rect(50, 44, 264, SearchMenu[0].h + 2, SEARCH_BAR_OUTL_COLOR);
Gui::Draw_Rect(SearchMenu[0].x, SearchMenu[0].y, SearchMenu[0].w, SearchMenu[0].h, SEARCH_BAR_COLOR);
Gui::DrawStringCentered(24, 50, 0.6, TEXT_COLOR, searchResult, 265, 0, font);
/* Checkboxes. */
for (int i = 0; i < 4; i++) {
GFX::DrawCheckbox(SearchMenu[i + 1].x, SearchMenu[i + 1].y, searchIncludes[i]);
}
Gui::DrawString(84, 85, 0.5, TEXT_COLOR, Lang::get("INCLUDE_IN_RESULTS"), 265, 0, font);
Gui::DrawString(SearchMenu[1].x + 18, SearchMenu[1].y + 1, 0.4, TEXT_COLOR, Lang::get("TITLE"), 90, 0, font);
Gui::DrawString(SearchMenu[2].x + 18, SearchMenu[2].y + 1, 0.4, TEXT_COLOR, Lang::get("AUTHOR"), 90, 0, font);
Gui::DrawString(SearchMenu[3].x + 18, SearchMenu[3].y + 1, 0.4, TEXT_COLOR, Lang::get("CATEGORY"), 90, 0, font);
Gui::DrawString(SearchMenu[4].x + 18, SearchMenu[4].y + 1, 0.4, TEXT_COLOR, Lang::get("CONSOLE"), 90, 0, font);
/* Filtrer. */
Gui::DrawString(84, 175, 0.5f, TEXT_COLOR, Lang::get("FILTER_TO"), 265, 0, font);
Gui::Draw_Rect(SearchMenu[5].x, SearchMenu[5].y, SearchMenu[5].w, SearchMenu[5].h, (marks & favoriteMarks::STAR ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[6].x, SearchMenu[6].y, SearchMenu[6].w, SearchMenu[6].h, (marks & favoriteMarks::HEART ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[7].x, SearchMenu[7].y, SearchMenu[7].w, SearchMenu[7].h, (marks & favoriteMarks::DIAMOND ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[8].x, SearchMenu[8].y, SearchMenu[8].w, SearchMenu[8].h, (marks & favoriteMarks::CLUBS ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[9].x, SearchMenu[9].y, SearchMenu[9].w, SearchMenu[9].h, (marks & favoriteMarks::SPADE ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[10].x, SearchMenu[10].y, SearchMenu[10].w, SearchMenu[10].h, (updateFilter ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::DrawString(SearchMenu[5].x + 9, SearchMenu[5].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[6].x + 9, SearchMenu[6].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[7].x + 9, SearchMenu[7].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[8].x + 9, SearchMenu[8].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[9].x + 9, SearchMenu[9].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
GFX::DrawSprite(sprites_update_filter_idx, SearchMenu[10].x + 8, SearchMenu[10].y + 8);
}
/*
Rechercher + Filter Handle.
Ici vous pouvez..
- Filtrez les marques dans vos applications.
- Rechercher dans eShop.
- Inclure des éléments dans la recherche.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées du magasin.
std::vectorbool> &searchIncludes : Référence aux InclusionsRecherche.
std::unique_ptrMeta> &meta : Référence à la classe Meta.
std::string &searchResult : Référence à searchResult.
int &marks : Référence aux drapeaux de marque.
bool &updateFilter : référence au filtre de mise à jour.
*/
void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::vector<bool> &searchIncludes, std::unique_ptr<Meta> &meta, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype) {
/* Checkboxes. */
if (hDown & KEY_TOUCH) {
bool didTouch = false;
/* Inclures. */
for (int i = 0; i < 4; i++) {
if (touching(touch, SearchMenu[i + 1])) {
searchIncludes[i] = !searchIncludes[i];
didTouch = true;
break;
}
}
/* Barres de Recherche. */
if (!didTouch) {
if (touching(touch, SearchMenu[0])) {
if (store) {
searchResult = Input::setkbdString(20, Lang::get("ENTER_SEARCH"), {});
didTouch = true;
} else {
searchResult = Input::setkbdString(20, Lang::get("ENTER_SEARCH"), {});
didTouch = true;
}
}
}
/* Filtrer. */
if (!didTouch) {
if (touching(touch, SearchMenu[5])) {
marks = marks ^ favoriteMarks::STAR;
didTouch = true;
} else if (touching(touch, SearchMenu[6])) {
marks = marks ^ favoriteMarks::HEART;
didTouch = true;
} else if (touching(touch, SearchMenu[7])) {
marks = marks ^ favoriteMarks::DIAMOND;
didTouch = true;
} else if (touching(touch, SearchMenu[8])) {
marks = marks ^ favoriteMarks::CLUBS;
didTouch = true;
} else if (touching(touch, SearchMenu[9])) {
marks = marks ^ favoriteMarks::SPADE;
didTouch = true;
} else if (touching(touch, SearchMenu[10])) {
updateFilter = !updateFilter;
didTouch = true;
}
}
if (didTouch) {
if (store && store->GetValid()) { // Ne cherchez que si cest valide.
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::search(entries, searchResult, searchIncludes[0], searchIncludes[1], searchIncludes[2], searchIncludes[3], marks, updateFilter);
store->SetScreenIndx(0);
store->SetEntry(0);
store->SetBox(0);
StoreUtils::SortEntries(ascending, sorttype, entries);
}
}
}
/* Réinitialiser tout. */
if (hDown & KEY_X) {
marks = 0;
updateFilter = false;
for(uint i = 0; i < searchIncludes.size(); i++) searchIncludes[i] = false;
searchResult = "";
if (store && store->GetValid()) {
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(ascending, sorttype, entries);
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> SearchMenu = {
{ 51, 45, 262, 30 }, // Search bar.
/* Inclure. */
{ 85, 109, 50, 10 },
{ 85, 125, 50, 10 },
{ 167, 109, 50, 10 },
{ 167, 125, 50, 10 },
/* Filtrer. */
{ 82, 195, 30, 30 },
{ 117, 195, 30, 30 },
{ 152, 195, 30, 30 },
{ 187, 195, 30, 30 },
{ 222, 195, 30, 30 },
{ 257, 195, 30, 30 }
};
/*
Dessinez le menu Recherche + Filtre.
const std::vectorbool> &searchIncludes : Const Référence à la searchIncludes.
const std::string &searchResult : Const Référence à searchResult.
int marks : Les drapeaux de marque de filtre.
bool updateFilter : Le filtre de mise à jour.
*/
void StoreUtils::DrawSearchMenu(const std::vector<bool> &searchIncludes, const std::string &searchResult, int marks, bool updateFilter) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(21, 2, 0.6, TEXT_COLOR, Lang::get("SEARCH_FILTERS"), 269, 0, font);
Gui::Draw_Rect(50, 44, 264, SearchMenu[0].h + 2, SEARCH_BAR_OUTL_COLOR);
Gui::Draw_Rect(SearchMenu[0].x, SearchMenu[0].y, SearchMenu[0].w, SearchMenu[0].h, SEARCH_BAR_COLOR);
Gui::DrawStringCentered(24, 50, 0.6, TEXT_COLOR, searchResult, 265, 0, font);
/* Checkboxes. */
for (int i = 0; i < 4; i++) {
GFX::DrawCheckbox(SearchMenu[i + 1].x, SearchMenu[i + 1].y, searchIncludes[i]);
}
Gui::DrawString(84, 85, 0.5, TEXT_COLOR, Lang::get("INCLUDE_IN_RESULTS"), 265, 0, font);
Gui::DrawString(SearchMenu[1].x + 18, SearchMenu[1].y + 1, 0.4, TEXT_COLOR, Lang::get("TITLE"), 90, 0, font);
Gui::DrawString(SearchMenu[2].x + 18, SearchMenu[2].y + 1, 0.4, TEXT_COLOR, Lang::get("AUTHOR"), 90, 0, font);
Gui::DrawString(SearchMenu[3].x + 18, SearchMenu[3].y + 1, 0.4, TEXT_COLOR, Lang::get("CATEGORY"), 90, 0, font);
Gui::DrawString(SearchMenu[4].x + 18, SearchMenu[4].y + 1, 0.4, TEXT_COLOR, Lang::get("CONSOLE"), 90, 0, font);
/* Filtrer. */
Gui::DrawString(84, 175, 0.5f, TEXT_COLOR, Lang::get("FILTER_TO"), 265, 0, font);
Gui::Draw_Rect(SearchMenu[5].x, SearchMenu[5].y, SearchMenu[5].w, SearchMenu[5].h, (marks & favoriteMarks::STAR ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[6].x, SearchMenu[6].y, SearchMenu[6].w, SearchMenu[6].h, (marks & favoriteMarks::HEART ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[7].x, SearchMenu[7].y, SearchMenu[7].w, SearchMenu[7].h, (marks & favoriteMarks::DIAMOND ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[8].x, SearchMenu[8].y, SearchMenu[8].w, SearchMenu[8].h, (marks & favoriteMarks::CLUBS ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[9].x, SearchMenu[9].y, SearchMenu[9].w, SearchMenu[9].h, (marks & favoriteMarks::SPADE ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::Draw_Rect(SearchMenu[10].x, SearchMenu[10].y, SearchMenu[10].w, SearchMenu[10].h, (updateFilter ?
SIDEBAR_UNSELECTED_COLOR : BOX_INSIDE_COLOR));
Gui::DrawString(SearchMenu[5].x + 9, SearchMenu[5].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[6].x + 9, SearchMenu[6].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[7].x + 9, SearchMenu[7].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[8].x + 9, SearchMenu[8].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
Gui::DrawString(SearchMenu[9].x + 9, SearchMenu[9].y + 7, 0.5f, TEXT_COLOR, "", 0, 0, font);
GFX::DrawSprite(sprites_update_filter_idx, SearchMenu[10].x + 8, SearchMenu[10].y + 8);
}
/*
Rechercher + Filter Handle.
Ici vous pouvez..
- Filtrez les marques dans vos applications.
- Rechercher dans eShop.
- Inclure des éléments dans la recherche.
std::unique_ptrStore> &store : Référence à la classe Store.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées du magasin.
std::vectorbool> &searchIncludes : Référence aux InclusionsRecherche.
std::unique_ptrMeta> &meta : Référence à la classe Meta.
std::string &searchResult : Référence à searchResult.
int &marks : Référence aux drapeaux de marque.
bool &updateFilter : référence au filtre de mise à jour.
*/
void StoreUtils::SearchHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::vector<bool> &searchIncludes, std::unique_ptr<Meta> &meta, std::string &searchResult, int &marks, bool &updateFilter, bool ascending, SortType sorttype) {
/* Checkboxes. */
if (hDown & KEY_TOUCH) {
bool didTouch = false;
/* Inclures. */
for (int i = 0; i < 4; i++) {
if (touching(touch, SearchMenu[i + 1])) {
searchIncludes[i] = !searchIncludes[i];
didTouch = true;
break;
}
}
/* Barres de Recherche. */
if (!didTouch) {
if (touching(touch, SearchMenu[0])) {
if (store) {
searchResult = Input::setkbdString(20, Lang::get("ENTER_SEARCH"), {});
didTouch = true;
} else {
searchResult = Input::setkbdString(20, Lang::get("ENTER_SEARCH"), {});
didTouch = true;
}
}
}
/* Filtrer. */
if (!didTouch) {
if (touching(touch, SearchMenu[5])) {
marks = marks ^ favoriteMarks::STAR;
didTouch = true;
} else if (touching(touch, SearchMenu[6])) {
marks = marks ^ favoriteMarks::HEART;
didTouch = true;
} else if (touching(touch, SearchMenu[7])) {
marks = marks ^ favoriteMarks::DIAMOND;
didTouch = true;
} else if (touching(touch, SearchMenu[8])) {
marks = marks ^ favoriteMarks::CLUBS;
didTouch = true;
} else if (touching(touch, SearchMenu[9])) {
marks = marks ^ favoriteMarks::SPADE;
didTouch = true;
} else if (touching(touch, SearchMenu[10])) {
updateFilter = !updateFilter;
didTouch = true;
}
}
if (didTouch) {
if (store && store->GetValid()) { // Ne cherchez que si cest valide.
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::search(entries, searchResult, searchIncludes[0], searchIncludes[1], searchIncludes[2], searchIncludes[3], marks, updateFilter);
store->SetScreenIndx(0);
store->SetEntry(0);
store->SetBox(0);
StoreUtils::SortEntries(ascending, sorttype, entries);
}
}
}
/* Réinitialiser tout. */
if (hDown & KEY_X) {
marks = 0;
updateFilter = false;
for(uint i = 0; i < searchIncludes.size(); i++) searchIncludes[i] = false;
searchResult = "";
if (store && store->GetValid()) {
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(ascending, sorttype, entries);
}
}
}
+611 -611
View File
File diff suppressed because it is too large Load Diff
+101 -101
View File
@@ -1,102 +1,102 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "animation.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> sidePos = {
{ 0, 0, 40, 40 },
{ 0, 40, 40, 40 },
{ 0, 80, 40, 40 },
{ 0, 120, 40, 40 },
{ 0, 160, 40, 40 },
{ 0, 200, 40, 40 }
};
/*
Dessinez la partie Menu latéral.
int currentMenu : Le Mode Store / Menu courant.
*/
void StoreUtils::DrawSideMenu(int currentMenu) {
for (int i = 0; i < 6; i++) {
if (i == currentMenu) {
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_SELECTED_COLOR);
} else {
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_UNSELECTED_COLOR);
}
}
GFX::DrawSprite(sprites_info_idx, sidePos[0].x, sidePos[0].y);
GFX::DrawSprite(sprites_download_idx, sidePos[1].x, sidePos[1].y);
Animation::DrawQueue(sidePos[2].x, sidePos[2].y);
GFX::DrawSprite(sprites_search_idx, sidePos[3].x, sidePos[3].y);
GFX::DrawSprite(sprites_sort_idx, sidePos[4].x, sidePos[4].y);
GFX::DrawSprite(sprites_settings_idx, sidePos[5].x, sidePos[5].y);
Gui::Draw_Rect(40, 0, 1, 240, BAR_OUTL_COLOR);
}
/*
Poignée de menu latéral.
Ici vous pouvez..
- Basculer entre les menus à travers la barre latérale.
int tMenu : Référence au Mode Store / Menu.
bool &fetch : Référence de la variable download fetch.. donc nous savons, si nous avons besoin de récupérer les entrées de téléchargement.
int &lastMenu : Référence au dernier menu.
*/
void StoreUtils::SideMenuHandle(int &currentMenu, bool &fetch, int &lastMenu) {
Animation::QueueAnimHandle();
if (hDown & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(touch, sidePos[i])) {
lastMenu = currentMenu;
if (i == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu = i;
break;
}
}
}
if (hRepeat & KEY_R) {
if (currentMenu < 5) {
lastMenu = currentMenu;
if (currentMenu + 1 == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu++;
}
}
if (hRepeat & KEY_L) {
if (currentMenu > 0) {
lastMenu = currentMenu;
if (currentMenu - 1 == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu--;
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "animation.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> sidePos = {
{ 0, 0, 40, 40 },
{ 0, 40, 40, 40 },
{ 0, 80, 40, 40 },
{ 0, 120, 40, 40 },
{ 0, 160, 40, 40 },
{ 0, 200, 40, 40 }
};
/*
Dessinez la partie Menu latéral.
int currentMenu : Le Mode Store / Menu courant.
*/
void StoreUtils::DrawSideMenu(int currentMenu) {
for (int i = 0; i < 6; i++) {
if (i == currentMenu) {
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_SELECTED_COLOR);
} else {
Gui::Draw_Rect(sidePos[i].x, sidePos[i].y, sidePos[i].w, sidePos[i].h, SIDEBAR_UNSELECTED_COLOR);
}
}
GFX::DrawSprite(sprites_info_idx, sidePos[0].x, sidePos[0].y);
GFX::DrawSprite(sprites_download_idx, sidePos[1].x, sidePos[1].y);
Animation::DrawQueue(sidePos[2].x, sidePos[2].y);
GFX::DrawSprite(sprites_search_idx, sidePos[3].x, sidePos[3].y);
GFX::DrawSprite(sprites_sort_idx, sidePos[4].x, sidePos[4].y);
GFX::DrawSprite(sprites_settings_idx, sidePos[5].x, sidePos[5].y);
Gui::Draw_Rect(40, 0, 1, 240, BAR_OUTL_COLOR);
}
/*
Poignée de menu latéral.
Ici vous pouvez..
- Basculer entre les menus à travers la barre latérale.
int tMenu : Référence au Mode Store / Menu.
bool &fetch : Référence de la variable download fetch.. donc nous savons, si nous avons besoin de récupérer les entrées de téléchargement.
int &lastMenu : Référence au dernier menu.
*/
void StoreUtils::SideMenuHandle(int &currentMenu, bool &fetch, int &lastMenu) {
Animation::QueueAnimHandle();
if (hDown & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(touch, sidePos[i])) {
lastMenu = currentMenu;
if (i == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu = i;
break;
}
}
}
if (hRepeat & KEY_R) {
if (currentMenu < 5) {
lastMenu = currentMenu;
if (currentMenu + 1 == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu++;
}
}
if (hRepeat & KEY_L) {
if (currentMenu > 0) {
lastMenu = currentMenu;
if (currentMenu - 1 == 1) fetch = true; // Récupérez la liste des téléchargements, si 1.
currentMenu--;
}
}
}
+156 -156
View File
@@ -1,157 +1,157 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> buttons = {
{ 71, 60, 104, 16 },
{ 71, 80, 104, 16 },
{ 71, 100, 104, 16 },
{ 201, 60, 104, 16 },
{ 201, 80, 104, 16 },
{ 71, 170, 104, 16 },
{ 71, 190, 104, 16 }
};
static void DrawCheck(int pos, bool v) {
GFX::DrawSprite((v ? sprites_sort_checked_idx : sprites_sort_unchecked_idx), buttons[pos].x + 1, buttons[pos].y);
}
/*
Return SortType as an uint8_t.
SortType st: The SortType variable.
*/
static const uint8_t GetType(SortType st) {
switch(st) {
case SortType::TITLE:
return 0;
case SortType::AUTHOR:
return 1;
case SortType::LAST_UPDATED:
return 2;
}
return 1;
}
/*
Draw the Sort Menu.
bool asc: The Ascending variable.
SortType st: The SortType variable.
*/
void StoreUtils::DrawSorting(bool asc, SortType st) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, Lang::get("SORTING"), 273, 0, font);
/* Sort By. */
Gui::DrawString(buttons[0].x + 1, buttons[0].y - 20, 0.6f, TEXT_COLOR, Lang::get("SORT_BY"), 90, 0, font);
for (int i = 0; i < 3; i++) {
DrawCheck(i, i == GetType(st));
}
Gui::DrawString(buttons[0].x + 21, buttons[0].y + 2, 0.4f, TEXT_COLOR, Lang::get("TITLE"), 80, 0, font);
Gui::DrawString(buttons[1].x + 21, buttons[1].y + 2, 0.4f, TEXT_COLOR, Lang::get("AUTHOR"), 80, 0, font);
Gui::DrawString(buttons[2].x + 21, buttons[2].y + 2, 0.4f, TEXT_COLOR, Lang::get("LAST_UPDATED"), 80, 0, font);
/* Direction. */
Gui::DrawString(buttons[3].x + 1, buttons[3].y - 20, 0.6f, TEXT_COLOR, Lang::get("DIRECTION"), 80, 0, font);
DrawCheck(3, asc);
DrawCheck(4, !asc);
Gui::DrawString(buttons[3].x + 21, buttons[3].y + 2, 0.4f, TEXT_COLOR, Lang::get("ASCENDING"), 80, 0, font);
Gui::DrawString(buttons[4].x + 21, buttons[4].y + 2, 0.4f, TEXT_COLOR, Lang::get("DESCENDING"), 80, 0, font);
/* Top Style. */
Gui::DrawString(buttons[5].x + 1, buttons[5].y - 20, 0.6f, TEXT_COLOR, Lang::get("TOP_STYLE"), 90, 0, font);
DrawCheck(5, config->list());
DrawCheck(6, !config->list());
Gui::DrawString(buttons[5].x + 21, buttons[5].y + 2, 0.4f, TEXT_COLOR, Lang::get("LIST"), 90, 0, font);
Gui::DrawString(buttons[6].x + 21, buttons[6].y + 2, 0.4f, TEXT_COLOR, Lang::get("GRID"), 90, 0, font);
}
/*
Sort Handle.
Here you can..
- Sort your Entries to..
- Title (Ascending / Descending).
- Author (Ascending / Descending).
- Last Updated Date (Ascending / Descending).
- Change the Top Style.
std::unique_ptr<Store> &store: Reference to the Store class.
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
bool &asc: Reference to the Ascending variable.
SortType &st: Reference to the SortType.
*/
void StoreUtils::SortHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, bool &asc, SortType &st) {
if (store && store->GetValid() && entries.size() > 0) { // Ensure, this is valid and more than 0 entries exist.
if (hDown & KEY_TOUCH) {
/* SortType Part. */
if (touching(touch, buttons[0])) {
st = SortType::TITLE;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[1])) {
st = SortType::AUTHOR;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[2])) {
st = SortType::LAST_UPDATED;
StoreUtils::SortEntries(asc, st, entries);
/* Ascending | Descending Part. */
} else if (touching(touch, buttons[3])) {
asc = true;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[4])) {
asc = false;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[5])) {
if (config->list()) return;
config->list(true);
store->SetEntry(0);
store->SetScreenIndx(0);
store->SetBox(0);
} else if (touching(touch, buttons[6])) {
if (!config->list()) return;
config->list(false);
store->SetEntry(0);
store->SetScreenIndx(0);
store->SetBox(0);
}
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "keyboard.hpp"
#include "storeUtils.hpp"
#include "structs.hpp"
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> buttons = {
{ 71, 60, 104, 16 },
{ 71, 80, 104, 16 },
{ 71, 100, 104, 16 },
{ 201, 60, 104, 16 },
{ 201, 80, 104, 16 },
{ 71, 170, 104, 16 },
{ 71, 190, 104, 16 }
};
static void DrawCheck(int pos, bool v) {
GFX::DrawSprite((v ? sprites_sort_checked_idx : sprites_sort_unchecked_idx), buttons[pos].x + 1, buttons[pos].y);
}
/*
Return SortType as an uint8_t.
SortType st: The SortType variable.
*/
static const uint8_t GetType(SortType st) {
switch(st) {
case SortType::TITLE:
return 0;
case SortType::AUTHOR:
return 1;
case SortType::LAST_UPDATED:
return 2;
}
return 1;
}
/*
Draw the Sort Menu.
bool asc: The Ascending variable.
SortType st: The SortType variable.
*/
void StoreUtils::DrawSorting(bool asc, SortType st) {
Gui::Draw_Rect(40, 0, 280, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(40, 25, 280, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(17, 2, 0.6, TEXT_COLOR, Lang::get("SORTING"), 273, 0, font);
/* Sort By. */
Gui::DrawString(buttons[0].x + 1, buttons[0].y - 20, 0.6f, TEXT_COLOR, Lang::get("SORT_BY"), 90, 0, font);
for (int i = 0; i < 3; i++) {
DrawCheck(i, i == GetType(st));
}
Gui::DrawString(buttons[0].x + 21, buttons[0].y + 2, 0.4f, TEXT_COLOR, Lang::get("TITLE"), 80, 0, font);
Gui::DrawString(buttons[1].x + 21, buttons[1].y + 2, 0.4f, TEXT_COLOR, Lang::get("AUTHOR"), 80, 0, font);
Gui::DrawString(buttons[2].x + 21, buttons[2].y + 2, 0.4f, TEXT_COLOR, Lang::get("LAST_UPDATED"), 80, 0, font);
/* Direction. */
Gui::DrawString(buttons[3].x + 1, buttons[3].y - 20, 0.6f, TEXT_COLOR, Lang::get("DIRECTION"), 80, 0, font);
DrawCheck(3, asc);
DrawCheck(4, !asc);
Gui::DrawString(buttons[3].x + 21, buttons[3].y + 2, 0.4f, TEXT_COLOR, Lang::get("ASCENDING"), 80, 0, font);
Gui::DrawString(buttons[4].x + 21, buttons[4].y + 2, 0.4f, TEXT_COLOR, Lang::get("DESCENDING"), 80, 0, font);
/* Top Style. */
Gui::DrawString(buttons[5].x + 1, buttons[5].y - 20, 0.6f, TEXT_COLOR, Lang::get("TOP_STYLE"), 90, 0, font);
DrawCheck(5, config->list());
DrawCheck(6, !config->list());
Gui::DrawString(buttons[5].x + 21, buttons[5].y + 2, 0.4f, TEXT_COLOR, Lang::get("LIST"), 90, 0, font);
Gui::DrawString(buttons[6].x + 21, buttons[6].y + 2, 0.4f, TEXT_COLOR, Lang::get("GRID"), 90, 0, font);
}
/*
Sort Handle.
Here you can..
- Sort your Entries to..
- Title (Ascending / Descending).
- Author (Ascending / Descending).
- Last Updated Date (Ascending / Descending).
- Change the Top Style.
std::unique_ptr<Store> &store: Reference to the Store class.
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the StoreEntries.
bool &asc: Reference to the Ascending variable.
SortType &st: Reference to the SortType.
*/
void StoreUtils::SortHandle(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, bool &asc, SortType &st) {
if (store && store->GetValid() && entries.size() > 0) { // Ensure, this is valid and more than 0 entries exist.
if (hDown & KEY_TOUCH) {
/* SortType Part. */
if (touching(touch, buttons[0])) {
st = SortType::TITLE;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[1])) {
st = SortType::AUTHOR;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[2])) {
st = SortType::LAST_UPDATED;
StoreUtils::SortEntries(asc, st, entries);
/* Ascending | Descending Part. */
} else if (touching(touch, buttons[3])) {
asc = true;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[4])) {
asc = false;
StoreUtils::SortEntries(asc, st, entries);
} else if (touching(touch, buttons[5])) {
if (config->list()) return;
config->list(true);
store->SetEntry(0);
store->SetScreenIndx(0);
store->SetBox(0);
} else if (touching(touch, buttons[6])) {
if (!config->list()) return;
config->list(false);
store->SetEntry(0);
store->SetScreenIndx(0);
store->SetBox(0);
}
}
}
}
+64 -64
View File
@@ -1,65 +1,65 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "overlay.hpp"
/*
Montrez les crédits.
*/
void Overlays::ShowCredits() {
bool doOut = false;
while(!doOut) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
GFX::DrawSprite(sprites_DarkStore_idx, 240, 30);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "DarkStore - " + Lang::get("CREDITS"), 395, 0, font);
Gui::DrawString(10, 30, 0.5f, TEXT_COLOR, "- DarkStore Team", 0, 0, font);
Gui::DrawString(10, 50, 0.5f, TEXT_COLOR, "- " + Lang::get("FILES_HOSTING_ANONYKU"), 0, 0, font);
Gui::DrawString(10, 70, 0.5f, TEXT_COLOR, "- " + Lang::get("CITRA_BIGN_ICON"), 0, 0, font);
Gui::DrawString(10, 90, 0.5f, TEXT_COLOR, "- https://hshop.erista.me/", 0, 0, font);
Gui::DrawString(10, 110, 0.5f, TEXT_COLOR, "- https://icons8.com/", 0, 0, font);
Gui::DrawString(10, 130, 0.5f, TEXT_COLOR, "- Dhalian. : Images", 0, 0, font);
Gui::DrawString(10, 150, 0.5f, TEXT_COLOR, Lang::get("CONTRIBUTOR_TRANSLATORS"), 210, 0, font);
Gui::DrawString(10, 197, 0.5f, TEXT_COLOR, Lang::get("WEBSITE"), 390, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CURRENT_VERSION") + std::string(V_STRING), 390, 0, font);
GFX::DrawBottom();
GFX::DrawSprite(sprites_DarkStore_core_idx, 0, 0);
C3D_FrameEnd(0);
hidScanInput();
if ((hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_A)) doOut = true;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "overlay.hpp"
/*
Montrez les crédits.
*/
void Overlays::ShowCredits() {
bool doOut = false;
while(!doOut) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
GFX::DrawSprite(sprites_DarkStore_idx, 240, 30);
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, "DarkStore - " + Lang::get("CREDITS"), 395, 0, font);
Gui::DrawString(10, 30, 0.5f, TEXT_COLOR, "- DarkStore Team", 0, 0, font);
Gui::DrawString(10, 50, 0.5f, TEXT_COLOR, "- " + Lang::get("FILES_HOSTING_ANONYKU"), 0, 0, font);
Gui::DrawString(10, 70, 0.5f, TEXT_COLOR, "- " + Lang::get("CITRA_BIGN_ICON"), 0, 0, font);
Gui::DrawString(10, 90, 0.5f, TEXT_COLOR, "- https://hshop.erista.me/", 0, 0, font);
Gui::DrawString(10, 110, 0.5f, TEXT_COLOR, "- https://icons8.com/", 0, 0, font);
Gui::DrawString(10, 130, 0.5f, TEXT_COLOR, "- Dhalian. : Images", 0, 0, font);
Gui::DrawString(10, 150, 0.5f, TEXT_COLOR, Lang::get("CONTRIBUTOR_TRANSLATORS"), 210, 0, font);
Gui::DrawString(10, 197, 0.5f, TEXT_COLOR, Lang::get("WEBSITE"), 390, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 218, 0.6f, TEXT_COLOR, Lang::get("CURRENT_VERSION") + std::string(V_STRING), 390, 0, font);
GFX::DrawBottom();
GFX::DrawSprite(sprites_DarkStore_core_idx, 0, 0);
C3D_FrameEnd(0);
hidScanInput();
if ((hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_A)) doOut = true;
}
}
+197 -197
View File
@@ -1,198 +1,198 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "fileBrowse.hpp"
#include "overlay.hpp"
#include <unistd.h>
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 6, 300, 22 },
{ 10, 36, 300, 22 },
{ 10, 66, 300, 22 },
{ 10, 96, 300, 22 },
{ 10, 126, 300, 22 },
{ 10, 156, 300, 22 },
{ 10, 186, 300, 22 }
};
/*
Sélectionnez un répertoire.
*/
std::string Overlays::SelectDir(const std::string &oldDir, const std::string &msg, const std::unique_ptr<Store> &store) {
std::string currentPath = oldDir;
bool dirChanged = false;
int selection = 0, sPos = 0;
std::vector<DirEntry> dirContents;
dirContents.clear();
/* Juste pour s'assurer. */
if (access((oldDir + std::string("/")).c_str(), F_OK) == 0) {
chdir((oldDir + std::string("/")).c_str());
} else {
currentPath = "sdmc:/";
chdir("sdmc:/");
}
std::vector<DirEntry> dirContentsTemp;
getDirectoryContents(dirContentsTemp, {"/"});
for(uint i = 0; i < dirContentsTemp.size(); i++) {
dirContents.push_back(dirContentsTemp[i]);
}
while(1) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (store && config->usebg() && store->customBG()) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
GFX::DrawTop();
}
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, msg, 380, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 217, 0.6f, TEXT_COLOR, currentPath, 390, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("START_SELECT"), 310, 0, font);
if (dirContents.size() > 0) {
for(int i = 0; i < 7 && i < (int)dirContents.size(); i++) {
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, dirContents[sPos + i].name, 295, 0, font);
}
}
C3D_FrameEnd(0);
if (dirChanged) {
dirChanged = false;
selection = 0;
sPos = 0;
dirContents.clear();
std::vector<DirEntry> dirContentsTemp;
getDirectoryContents(dirContentsTemp, {"/"});
for(uint i = 0; i < dirContentsTemp.size(); i++) {
dirContents.push_back(dirContentsTemp[i]);
}
}
hidScanInput();
touchPosition touch;
hidTouchRead(&touch);
u32 hRepeat = hidKeysDownRepeat();
if (dirContents.size() > 0) {
if (hRepeat & KEY_DOWN) {
if (selection < (int)dirContents.size() - 1) selection++;
else selection = 0;
}
if (hRepeat & KEY_UP) {
if (selection > 0) selection--;
else selection = dirContents.size() - 1;
}
if (hRepeat & KEY_RIGHT) {
if (selection + 7 < (int)dirContents.size()-1) selection += 7;
else selection = dirContents.size()-1;
}
if (hRepeat & KEY_LEFT) {
if (selection - 7 > 0) selection -= 7;
else selection = 0;
}
if (hidKeysDown() & KEY_A) {
if (dirContents[selection].isDirectory) {
chdir(dirContents[selection].name.c_str());
char path[PATH_MAX];
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
}
}
if (hidKeysDown() & KEY_TOUCH) {
for (int i = 0; i < 7; i++) {
if (touching(touch, mainButtons[i])) {
if (i + sPos < (int)dirContents.size()) {
if (dirContents[i + sPos].isDirectory) {
chdir(dirContents[i + sPos].name.c_str());
char path[PATH_MAX];
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
break;
}
}
}
}
}
if (selection < sPos) sPos = selection;
else if (selection > sPos + 7 - 1) sPos = selection - 7 + 1;
}
if ((hidKeysDown() & KEY_X) || (hidKeysDown() & KEY_START)) {
if (currentPath.size() > 0 && currentPath.back() == '/') currentPath.pop_back(); // Pop back le "/".
return currentPath;
}
if (hidKeysDown() & KEY_B) {
char path[PATH_MAX];
getcwd(path, PATH_MAX);
if (strcmp(path, "sdmc:/") == 0 || strcmp(path, "/") == 0) return "";
else {
chdir("..");
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
}
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "fileBrowse.hpp"
#include "overlay.hpp"
#include <unistd.h>
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 6, 300, 22 },
{ 10, 36, 300, 22 },
{ 10, 66, 300, 22 },
{ 10, 96, 300, 22 },
{ 10, 126, 300, 22 },
{ 10, 156, 300, 22 },
{ 10, 186, 300, 22 }
};
/*
Sélectionnez un répertoire.
*/
std::string Overlays::SelectDir(const std::string &oldDir, const std::string &msg, const std::unique_ptr<Store> &store) {
std::string currentPath = oldDir;
bool dirChanged = false;
int selection = 0, sPos = 0;
std::vector<DirEntry> dirContents;
dirContents.clear();
/* Juste pour s'assurer. */
if (access((oldDir + std::string("/")).c_str(), F_OK) == 0) {
chdir((oldDir + std::string("/")).c_str());
} else {
currentPath = "sdmc:/";
chdir("sdmc:/");
}
std::vector<DirEntry> dirContentsTemp;
getDirectoryContents(dirContentsTemp, {"/"});
for(uint i = 0; i < dirContentsTemp.size(); i++) {
dirContents.push_back(dirContentsTemp[i]);
}
while(1) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (store && config->usebg() && store->customBG()) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
GFX::DrawTop();
}
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, msg, 380, 0, font);
Gui::Draw_Rect(0, 215, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 400, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 217, 0.6f, TEXT_COLOR, currentPath, 390, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 215, 320, 25, BAR_COLOR);
Gui::Draw_Rect(0, 214, 320, 1, BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 220, 0.5f, TEXT_COLOR, Lang::get("START_SELECT"), 310, 0, font);
if (dirContents.size() > 0) {
for(int i = 0; i < 7 && i < (int)dirContents.size(); i++) {
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, dirContents[sPos + i].name, 295, 0, font);
}
}
C3D_FrameEnd(0);
if (dirChanged) {
dirChanged = false;
selection = 0;
sPos = 0;
dirContents.clear();
std::vector<DirEntry> dirContentsTemp;
getDirectoryContents(dirContentsTemp, {"/"});
for(uint i = 0; i < dirContentsTemp.size(); i++) {
dirContents.push_back(dirContentsTemp[i]);
}
}
hidScanInput();
touchPosition touch;
hidTouchRead(&touch);
u32 hRepeat = hidKeysDownRepeat();
if (dirContents.size() > 0) {
if (hRepeat & KEY_DOWN) {
if (selection < (int)dirContents.size() - 1) selection++;
else selection = 0;
}
if (hRepeat & KEY_UP) {
if (selection > 0) selection--;
else selection = dirContents.size() - 1;
}
if (hRepeat & KEY_RIGHT) {
if (selection + 7 < (int)dirContents.size()-1) selection += 7;
else selection = dirContents.size()-1;
}
if (hRepeat & KEY_LEFT) {
if (selection - 7 > 0) selection -= 7;
else selection = 0;
}
if (hidKeysDown() & KEY_A) {
if (dirContents[selection].isDirectory) {
chdir(dirContents[selection].name.c_str());
char path[PATH_MAX];
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
}
}
if (hidKeysDown() & KEY_TOUCH) {
for (int i = 0; i < 7; i++) {
if (touching(touch, mainButtons[i])) {
if (i + sPos < (int)dirContents.size()) {
if (dirContents[i + sPos].isDirectory) {
chdir(dirContents[i + sPos].name.c_str());
char path[PATH_MAX];
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
break;
}
}
}
}
}
if (selection < sPos) sPos = selection;
else if (selection > sPos + 7 - 1) sPos = selection - 7 + 1;
}
if ((hidKeysDown() & KEY_X) || (hidKeysDown() & KEY_START)) {
if (currentPath.size() > 0 && currentPath.back() == '/') currentPath.pop_back(); // Pop back le "/".
return currentPath;
}
if (hidKeysDown() & KEY_B) {
char path[PATH_MAX];
getcwd(path, PATH_MAX);
if (strcmp(path, "sdmc:/") == 0 || strcmp(path, "/") == 0) return "";
else {
chdir("..");
getcwd(path, PATH_MAX);
currentPath = path;
dirChanged = true;
}
}
}
}
+385 -385
View File
@@ -1,386 +1,386 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "fileBrowse.hpp"
#include "files.hpp"
#include "keyboard.hpp"
#include "overlay.hpp"
#include "qrcode.hpp"
#include "scriptUtils.hpp"
#include "storeUtils.hpp"
#include <unistd.h>
extern bool checkWifiStatus();
extern void notConnectedMsg();
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 34, 300, 22 },
{ 10, 64, 300, 22 },
{ 10, 94, 300, 22 },
{ 10, 124, 300, 22 },
{ 10, 154, 300, 22 },
{ 10, 184, 300, 22 },
{ 112, 215, 16, 16 }, // Delete.
{ 154, 215, 16, 16 }, // Update.
{ 200, 215, 16, 16 }, // Add.
{ 4, 0, 24, 24 } // Back.
};
/*
Supprimez un Shop.. y compris les Spritesheets, le cas échéant.
const std::string &file : Le fichier de eShop.
*/
static void DeleteStore(const std::string &file) {
FILE *temp = fopen((std::string(_STORE_PATH) + file).c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
/* Vérifiez, si Spritesheet existe sur eShop. */
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
/* Parce que cest un tableau, supprimez tous les Spritesheets qui existent. */
for (int i = 0; i < (int)sht.size(); i++) {
if (sht[i] != "") {
if (!(StringUtils::lower_case(sht[i]).find(StringUtils::lower_case("/")) != std::string::npos)) {
if (access((std::string(_STORE_PATH) + sht[i]).c_str(), F_OK) == 0) {
deleteFile((std::string(_STORE_PATH) + sht[i]).c_str());
}
}
}
}
/* Sinon, si cest juste une chaîne.. vérifier et supprimer simplement Spritesheet. */
} else if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheet"];
if (fl != "") {
if (!(StringUtils::lower_case(fl).find(StringUtils::lower_case("/")) != std::string::npos)) {
if (access((std::string(_STORE_PATH) + fl).c_str(), F_OK) == 0) {
deleteFile((std::string(_STORE_PATH) + fl).c_str());
}
}
}
}
deleteFile((std::string(_STORE_PATH) + file).c_str()); // Supprimez maintenant l'eShop.
}
/*
Download a Store.. including the SpriteSheets, if found.
*/
static bool DownloadStore() {
bool doSheet = false;
std::string file = "";
const std::string URL = QR_Scanner::StoreHandle();
if (URL != "") doSheet = DownloadEshop(URL, -1, file, true);
if (doSheet) {
FILE *temp = fopen(file.c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (doSheet) {
if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> locs = storeJson["storeInfo"]["sheetURL"].get<std::vector<std::string>>();
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
if (locs.size() == sht.size()) {
for (int i = 0; i < (int)sht.size(); i++) {
if (!(sht[i].find("/") != std::string::npos)) {
char msg[150];
snprintf(msg, sizeof(msg), Lang::get("DOWNLOADING_SPRITE_SHEET2").c_str(), i + 1, sht.size());
Msg::DisplayMsg(msg);
DownloadSpriteSheet(locs[i], sht[i]);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
} else if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_string()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheetURL"];
const std::string fl2 = storeJson["storeInfo"]["sheet"];
if (!(fl2.find("/") != std::string::npos)) {
Msg::DisplayMsg(Lang::get("DOWNLOADING_SPRITE_SHEET"));
DownloadSpriteSheet(fl, fl2);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
}
hidScanInput(); // Re-Scan.
return doSheet;
}
static bool UpdateStore(const std::string &URL) {
bool doSheet = false;
std::string file = "";
if (URL != "") doSheet = DownloadEshop(URL, -1, file, false);
if (doSheet) {
FILE *temp = fopen(file.c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (doSheet) {
if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> locs = storeJson["storeInfo"]["sheetURL"].get<std::vector<std::string>>();
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
if (locs.size() == sht.size()) {
for (int i = 0; i < (int)sht.size(); i++) {
if (!(sht[i].find("/") != std::string::npos)) {
char msg[150];
snprintf(msg, sizeof(msg), Lang::get("DOWNLOADING_SPRITE_SHEET2").c_str(), i + 1, sht.size());
Msg::DisplayMsg(msg);
DownloadSpriteSheet(locs[i], sht[i]);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
} else if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_string()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheetURL"];
const std::string fl2 = storeJson["storeInfo"]["sheet"];
if (!(fl2.find("/") != std::string::npos)) {
Msg::DisplayMsg(Lang::get("DOWNLOADING_SPRITE_SHEET"));
DownloadSpriteSheet(fl, fl2);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
}
return doSheet;
}
/*
This is the eShop Manage Handle.
Here you can..
- Delete a eShop.
- Download / Add a eShop.
- Check for Updates for a eShop.
- Switch the eShop.
std::unique_ptr<Store> &store: Reference to the Store class.
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the Store Entries.
std::unique_ptr<Meta> &meta: Reference to the Meta class.
*/
void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta) {
bool doOut = false;
int selection = 0, sPos = 0;
std::vector<EshopInfo> info = GetEshopInfo(_STORE_PATH);
while(!doOut) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (store && config->usebg() && store->customBG()) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
GFX::DrawTop();
}
if (info.size() > 0) {
if (info[selection].StoreSize != -1) {
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, info[selection].Title, 390, 0, font);
Gui::DrawStringCentered(0, 30, 0.6f, TEXT_COLOR, info[selection].Author, 380, 0, font);
Gui::DrawStringCentered(0, 70, 0.5f, TEXT_COLOR, info[selection].Description, 380, 130, font, C2D_WordWrap);
} else {
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_ESHOP"), 390, 0, font);
}
Gui::DrawString(10, 200, 0.4, TEXT_COLOR, "- " + Lang::get("ENTRIES") + ": " + std::to_string(info[selection].StoreSize), 150, 0, font);
Gui::DrawString(10, 210, 0.4, TEXT_COLOR, "- " + Lang::get("VERSION") + ": " + std::to_string(info[selection].Version), 150, 0, font);
Gui::DrawString(10, 220, 0.4, TEXT_COLOR, "- " + Lang::get("REVISION") + ": " + std::to_string(info[selection].Revision), 150, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
GFX::DrawSprite(sprites_arrow_idx, mainButtons[9].x, mainButtons[9].y);
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("SELECT_ESHOP_2"), 310, 0, font);
for(int i = 0; i < 6 && i < (int)info.size(); i++) {
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, info[sPos + i].FileName, 295, 0, font);
}
}
if (info.size() <= 0) GFX::DrawBottom(); // Otherwise we'd draw on top.
GFX::DrawSprite(sprites_delete_idx, mainButtons[6].x, mainButtons[6].y);
GFX::DrawSprite(sprites_update_idx, mainButtons[7].x, mainButtons[7].y);
GFX::DrawSprite(sprites_add_idx, mainButtons[8].x, mainButtons[8].y);
C3D_FrameEnd(0);
hidScanInput();
touchPosition touch;
hidTouchRead(&touch);
u32 hRepeat = hidKeysDownRepeat();
if (info.size() > 0) {
if (hRepeat & KEY_DOWN) {
if (selection < (int)info.size() - 1) selection++;
else selection = 0;
}
if (hRepeat & KEY_UP) {
if (selection > 0) selection--;
else selection = info.size() - 1;
}
if (hRepeat & KEY_RIGHT) {
if (selection + 6 < (int)info.size() - 1) selection += 6;
else selection = info.size() - 1;
}
if (hRepeat & KEY_LEFT) {
if (selection - 6 > 0) selection -= 6;
else selection = 0;
}
if (hidKeysDown() & KEY_A) {
if (info[selection].File != "") { // Ensure to check for this.
if (!(info[selection].File.find("/") != std::string::npos)) {
/* Load selected one. */
if (info[selection].Version == -1) Msg::waitMsg(Lang::get("ESHOP_INVALID_ERROR"));
else if (info[selection].Version < 3) Msg::waitMsg(Lang::get("ESHOP_TOO_OLD"));
else if (info[selection].Version > _ESHOP_VERSION) Msg::waitMsg(Lang::get("ESHOP_TOO_NEW"));
else {
config->lastStore(info[selection].FileName);
store = std::make_unique<Store>(_STORE_PATH + info[selection].FileName, info[selection].FileName);
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
doOut = true;
}
} else {
Msg::waitMsg(Lang::get("FILE_SLASH"));
}
}
}
if (hidKeysDown() & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(touch, mainButtons[i])) {
if (i + sPos < (int)info.size() && info[i + sPos].File != "") { // Ensure to check for this.
if (!(info[i + sPos].File.find("/") != std::string::npos)) {
if (info[i + sPos].Version == -1) Msg::waitMsg(Lang::get("ESHOP_INVALID_ERROR"));
else if (info[i + sPos].Version < 3) Msg::waitMsg(Lang::get("ESHOP_TOO_OLD"));
else if (info[i + sPos].Version > _ESHOP_VERSION) Msg::waitMsg(Lang::get("ESHOP_TOO_NEW"));
else {
config->lastStore(info[i + sPos].FileName);
store = std::make_unique<Store>(_STORE_PATH + info[i + sPos].FileName, info[i + sPos].FileName);
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
doOut = true;
}
} else {
Msg::waitMsg(Lang::get("FILE_SLASH"));
}
}
}
}
}
/* Supprimer l'eShop */
if ((hidKeysDown() & KEY_X) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[6]))) {
if (info[selection].FileName != "") {
DeleteStore(info[selection].FileName);
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
}
/* Télécharger le dernier eShop */
if ((hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[7]))) {
if (checkWifiStatus()) {
if (info[selection].URL != "") {
if (UpdateStore(info[selection].URL)) {
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
}
} else {
notConnectedMsg();
}
}
if (selection < sPos) sPos = selection;
else if (selection > sPos + 6 - 1) sPos = selection - 6 + 1;
}
/* Téléchargement de l'eShop depuis URL. */
if ((hidKeysDown() & KEY_Y) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[8]))) {
if (checkWifiStatus()) {
if (DownloadStore()) {
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
} else {
notConnectedMsg();
}
}
/* Go out of the menu. */
if ((hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[9]))) doOut = true;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "fileBrowse.hpp"
#include "files.hpp"
#include "keyboard.hpp"
#include "overlay.hpp"
#include "qrcode.hpp"
#include "scriptUtils.hpp"
#include "storeUtils.hpp"
#include <unistd.h>
extern bool checkWifiStatus();
extern void notConnectedMsg();
extern bool touching(touchPosition touch, Structs::ButtonPos button);
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 34, 300, 22 },
{ 10, 64, 300, 22 },
{ 10, 94, 300, 22 },
{ 10, 124, 300, 22 },
{ 10, 154, 300, 22 },
{ 10, 184, 300, 22 },
{ 112, 215, 16, 16 }, // Delete.
{ 154, 215, 16, 16 }, // Update.
{ 200, 215, 16, 16 }, // Add.
{ 4, 0, 24, 24 } // Back.
};
/*
Supprimez un Shop.. y compris les Spritesheets, le cas échéant.
const std::string &file : Le fichier de eShop.
*/
static void DeleteStore(const std::string &file) {
FILE *temp = fopen((std::string(_STORE_PATH) + file).c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
/* Vérifiez, si Spritesheet existe sur eShop. */
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
/* Parce que cest un tableau, supprimez tous les Spritesheets qui existent. */
for (int i = 0; i < (int)sht.size(); i++) {
if (sht[i] != "") {
if (!(StringUtils::lower_case(sht[i]).find(StringUtils::lower_case("/")) != std::string::npos)) {
if (access((std::string(_STORE_PATH) + sht[i]).c_str(), F_OK) == 0) {
deleteFile((std::string(_STORE_PATH) + sht[i]).c_str());
}
}
}
}
/* Sinon, si cest juste une chaîne.. vérifier et supprimer simplement Spritesheet. */
} else if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheet"];
if (fl != "") {
if (!(StringUtils::lower_case(fl).find(StringUtils::lower_case("/")) != std::string::npos)) {
if (access((std::string(_STORE_PATH) + fl).c_str(), F_OK) == 0) {
deleteFile((std::string(_STORE_PATH) + fl).c_str());
}
}
}
}
deleteFile((std::string(_STORE_PATH) + file).c_str()); // Supprimez maintenant l'eShop.
}
/*
Download a Store.. including the SpriteSheets, if found.
*/
static bool DownloadStore() {
bool doSheet = false;
std::string file = "";
const std::string URL = QR_Scanner::StoreHandle();
if (URL != "") doSheet = DownloadEshop(URL, -1, file, true);
if (doSheet) {
FILE *temp = fopen(file.c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (doSheet) {
if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> locs = storeJson["storeInfo"]["sheetURL"].get<std::vector<std::string>>();
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
if (locs.size() == sht.size()) {
for (int i = 0; i < (int)sht.size(); i++) {
if (!(sht[i].find("/") != std::string::npos)) {
char msg[150];
snprintf(msg, sizeof(msg), Lang::get("DOWNLOADING_SPRITE_SHEET2").c_str(), i + 1, sht.size());
Msg::DisplayMsg(msg);
DownloadSpriteSheet(locs[i], sht[i]);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
} else if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_string()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheetURL"];
const std::string fl2 = storeJson["storeInfo"]["sheet"];
if (!(fl2.find("/") != std::string::npos)) {
Msg::DisplayMsg(Lang::get("DOWNLOADING_SPRITE_SHEET"));
DownloadSpriteSheet(fl, fl2);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
}
hidScanInput(); // Re-Scan.
return doSheet;
}
static bool UpdateStore(const std::string &URL) {
bool doSheet = false;
std::string file = "";
if (URL != "") doSheet = DownloadEshop(URL, -1, file, false);
if (doSheet) {
FILE *temp = fopen(file.c_str(), "rt");
nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (doSheet) {
if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) {
const std::vector<std::string> locs = storeJson["storeInfo"]["sheetURL"].get<std::vector<std::string>>();
const std::vector<std::string> sht = storeJson["storeInfo"]["sheet"].get<std::vector<std::string>>();
if (locs.size() == sht.size()) {
for (int i = 0; i < (int)sht.size(); i++) {
if (!(sht[i].find("/") != std::string::npos)) {
char msg[150];
snprintf(msg, sizeof(msg), Lang::get("DOWNLOADING_SPRITE_SHEET2").c_str(), i + 1, sht.size());
Msg::DisplayMsg(msg);
DownloadSpriteSheet(locs[i], sht[i]);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
} else if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_string()) {
if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_string()) {
const std::string fl = storeJson["storeInfo"]["sheetURL"];
const std::string fl2 = storeJson["storeInfo"]["sheet"];
if (!(fl2.find("/") != std::string::npos)) {
Msg::DisplayMsg(Lang::get("DOWNLOADING_SPRITE_SHEET"));
DownloadSpriteSheet(fl, fl2);
} else {
Msg::waitMsg(Lang::get("SHEET_SLASH"));
}
}
}
}
}
return doSheet;
}
/*
This is the eShop Manage Handle.
Here you can..
- Delete a eShop.
- Download / Add a eShop.
- Check for Updates for a eShop.
- Switch the eShop.
std::unique_ptr<Store> &store: Reference to the Store class.
std::vector<std::unique_ptr<StoreEntry>> &entries: Reference to the Store Entries.
std::unique_ptr<Meta> &meta: Reference to the Meta class.
*/
void Overlays::SelectStore(std::unique_ptr<Store> &store, std::vector<std::unique_ptr<StoreEntry>> &entries, std::unique_ptr<Meta> &meta) {
bool doOut = false;
int selection = 0, sPos = 0;
std::vector<EshopInfo> info = GetEshopInfo(_STORE_PATH);
while(!doOut) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (store && config->usebg() && store->customBG()) {
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
C2D_DrawImageAt(store->GetStoreImg(), 0, 26, 0.5f, nullptr);
} else {
GFX::DrawTop();
}
if (info.size() > 0) {
if (info[selection].StoreSize != -1) {
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, info[selection].Title, 390, 0, font);
Gui::DrawStringCentered(0, 30, 0.6f, TEXT_COLOR, info[selection].Author, 380, 0, font);
Gui::DrawStringCentered(0, 70, 0.5f, TEXT_COLOR, info[selection].Description, 380, 130, font, C2D_WordWrap);
} else {
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_ESHOP"), 390, 0, font);
}
Gui::DrawString(10, 200, 0.4, TEXT_COLOR, "- " + Lang::get("ENTRIES") + ": " + std::to_string(info[selection].StoreSize), 150, 0, font);
Gui::DrawString(10, 210, 0.4, TEXT_COLOR, "- " + Lang::get("VERSION") + ": " + std::to_string(info[selection].Version), 150, 0, font);
Gui::DrawString(10, 220, 0.4, TEXT_COLOR, "- " + Lang::get("REVISION") + ": " + std::to_string(info[selection].Revision), 150, 0, font);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
GFX::DrawSprite(sprites_arrow_idx, mainButtons[9].x, mainButtons[9].y);
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("SELECT_ESHOP_2"), 310, 0, font);
for(int i = 0; i < 6 && i < (int)info.size(); i++) {
if (sPos + i == selection) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, info[sPos + i].FileName, 295, 0, font);
}
}
if (info.size() <= 0) GFX::DrawBottom(); // Otherwise we'd draw on top.
GFX::DrawSprite(sprites_delete_idx, mainButtons[6].x, mainButtons[6].y);
GFX::DrawSprite(sprites_update_idx, mainButtons[7].x, mainButtons[7].y);
GFX::DrawSprite(sprites_add_idx, mainButtons[8].x, mainButtons[8].y);
C3D_FrameEnd(0);
hidScanInput();
touchPosition touch;
hidTouchRead(&touch);
u32 hRepeat = hidKeysDownRepeat();
if (info.size() > 0) {
if (hRepeat & KEY_DOWN) {
if (selection < (int)info.size() - 1) selection++;
else selection = 0;
}
if (hRepeat & KEY_UP) {
if (selection > 0) selection--;
else selection = info.size() - 1;
}
if (hRepeat & KEY_RIGHT) {
if (selection + 6 < (int)info.size() - 1) selection += 6;
else selection = info.size() - 1;
}
if (hRepeat & KEY_LEFT) {
if (selection - 6 > 0) selection -= 6;
else selection = 0;
}
if (hidKeysDown() & KEY_A) {
if (info[selection].File != "") { // Ensure to check for this.
if (!(info[selection].File.find("/") != std::string::npos)) {
/* Load selected one. */
if (info[selection].Version == -1) Msg::waitMsg(Lang::get("ESHOP_INVALID_ERROR"));
else if (info[selection].Version < 3) Msg::waitMsg(Lang::get("ESHOP_TOO_OLD"));
else if (info[selection].Version > _ESHOP_VERSION) Msg::waitMsg(Lang::get("ESHOP_TOO_NEW"));
else {
config->lastStore(info[selection].FileName);
store = std::make_unique<Store>(_STORE_PATH + info[selection].FileName, info[selection].FileName);
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
doOut = true;
}
} else {
Msg::waitMsg(Lang::get("FILE_SLASH"));
}
}
}
if (hidKeysDown() & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(touch, mainButtons[i])) {
if (i + sPos < (int)info.size() && info[i + sPos].File != "") { // Ensure to check for this.
if (!(info[i + sPos].File.find("/") != std::string::npos)) {
if (info[i + sPos].Version == -1) Msg::waitMsg(Lang::get("ESHOP_INVALID_ERROR"));
else if (info[i + sPos].Version < 3) Msg::waitMsg(Lang::get("ESHOP_TOO_OLD"));
else if (info[i + sPos].Version > _ESHOP_VERSION) Msg::waitMsg(Lang::get("ESHOP_TOO_NEW"));
else {
config->lastStore(info[i + sPos].FileName);
store = std::make_unique<Store>(_STORE_PATH + info[i + sPos].FileName, info[i + sPos].FileName);
StoreUtils::ResetAll(store, meta, entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, entries);
doOut = true;
}
} else {
Msg::waitMsg(Lang::get("FILE_SLASH"));
}
}
}
}
}
/* Supprimer l'eShop */
if ((hidKeysDown() & KEY_X) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[6]))) {
if (info[selection].FileName != "") {
DeleteStore(info[selection].FileName);
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
}
/* Télécharger le dernier eShop */
if ((hidKeysDown() & KEY_START) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[7]))) {
if (checkWifiStatus()) {
if (info[selection].URL != "") {
if (UpdateStore(info[selection].URL)) {
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
}
} else {
notConnectedMsg();
}
}
if (selection < sPos) sPos = selection;
else if (selection > sPos + 6 - 1) sPos = selection - 6 + 1;
}
/* Téléchargement de l'eShop depuis URL. */
if ((hidKeysDown() & KEY_Y) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[8]))) {
if (checkWifiStatus()) {
if (DownloadStore()) {
selection = 0;
info = GetEshopInfo(_STORE_PATH);
}
} else {
notConnectedMsg();
}
}
/* Go out of the menu. */
if ((hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_TOUCH && touching(touch, mainButtons[9]))) doOut = true;
}
}
+942 -942
View File
File diff suppressed because it is too large Load Diff
+1292 -1292
View File
File diff suppressed because it is too large Load Diff
+450 -450
View File
@@ -1,451 +1,451 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/*
* This file is part of PKSM
* Copyright (C) 2016-2020 Bernardo Giordano, Admiral Fish, piepie62
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "download.hpp"
#include "keyboard.hpp"
#include "qrcode.hpp"
#include <cstring>
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 34, 300, 22 },
{ 10, 64, 300, 22 },
{ 10, 94, 300, 22 },
{ 10, 124, 300, 22 },
{ 10, 154, 300, 22 },
{ 10, 184, 300, 22 },
{ 5, 215, 24, 24 }, // QR Code / List.
{ 35, 215, 24, 24 }, // Keyboard.
{ 4, 0, 24, 24 } // Back.
};
extern bool touching(touchPosition touch, Structs::ButtonPos button);
/*
Initialize everything needed for the camera.
*/
QRCode::QRCode() {
this->image.tex = new C3D_Tex;
this->image.subtex = &this->subtex;
this->qrData = quirc_new();
std::fill(this->cameraBuffer.begin(), this->cameraBuffer.end(), 0);
C3D_TexInit(this->image.tex, 512, 256, GPU_RGB565);
C3D_TexSetFilter(this->image.tex, GPU_LINEAR, GPU_LINEAR);
this->image.tex->border = 0xFFFFFFFF;
C3D_TexSetWrap(this->image.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
LightLock_Init(&this->bufferLock);
LightLock_Init(&this->imageLock);
svcCreateEvent(&this->exitEvent, RESET_STICKY);
quirc_resize(this->qrData, 400, 240);
if (checkWifiStatus()) this->stores = FetchStores(); // Fetching Stores here.
if (this->stores.size() > 0) this->displayList = true;
}
/*
Destroy everything.
*/
QRCode::~QRCode() {
C3D_TexDelete(this->image.tex);
delete this->image.tex;
quirc_destroy(this->qrData);
svcCloseHandle(this->exitEvent);
}
/*
mem copy the captured Image to the buffer, used for drawing.
*/
void QRCode::buffToImage() {
LightLock_Lock(&this->bufferLock);
for (u32 x = 0; x < 400; x++) {
for (u32 y = 0; y < 240; 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))) * 2;
const u32 srcPos = (y * 400 + x) * 2;
memcpy(((u8 *)this->image.tex->data) + dstPos, ((u8 *)this->cameraBuffer.data()) + srcPos, 2);
}
}
LightLock_Unlock(&this->bufferLock);
}
/*
Finish and unlock everything.
*/
void QRCode::finish() {
svcSignalEvent(this->exitEvent);
while (!this->done()) svcSleepThread(1000000);
LightLock_Lock(&this->bufferLock);
LightLock_Unlock(&this->bufferLock);
LightLock_Lock(&this->imageLock);
LightLock_Unlock(&this->imageLock);
}
/*
The Draw Thread of the Camera.
*/
void QRCode::drawThread() {
LightLock_Lock(&this->imageLock);
/* If we aren't done.. do the draw to scan. */
while (!this->done()) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (!this->displayList) {
this->buffToImage(); // Fetch image.
Gui::ScreenDraw(Top);
C2D_DrawImageAt(this->image, 0, 0, 0.5, nullptr, 1.0f, 1.0f);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
} else {
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.7, TEXT_COLOR, Lang::get("STORE_INFO"), 390, 0, font);
if (this->stores.size() > 0) {
Gui::DrawStringCentered(0, 30, 0.7f, TEXT_COLOR, this->stores[this->selectedStore].Title, 390, 0, font);
Gui::DrawStringCentered(0, 50, 0.6f, TEXT_COLOR, this->stores[this->selectedStore].Author, 380, 0, font);
Gui::DrawStringCentered(0, 90, 0.5f, TEXT_COLOR, this->stores[this->selectedStore].Description, 380, 130, font, C2D_WordWrap);
}
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("RECOMMENDED_ESHOP"), 310, 0, font);
for(int i = 0; i < 6 && i < (int)this->stores.size(); i++) {
if (this->sPos + i == this->selectedStore) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, this->stores[this->sPos + i].Title, 295, 0, font);
}
}
GFX::DrawSprite((this->displayList ? sprites_qr_code_idx : sprites_list_idx), mainButtons[6].x, mainButtons[6].y);
if (this->displayList) GFX::DrawSprite(sprites_keyboard_idx, mainButtons[7].x, mainButtons[7].y);
GFX::DrawSprite(sprites_arrow_idx, mainButtons[8].x, mainButtons[8].y);
C3D_FrameEnd(0);
}
LightLock_Unlock(&this->imageLock);
}
/*
The Capture Thread of the camera.
*/
void QRCode::captureThread() {
Handle events[3] = { 0 };
events[0] = exitEvent;
u32 transferUnit;
u16 *buffer = new u16[400 * 240];
camInit();
CAMU_SetSize(SELECT_OUT1, SIZE_CTR_TOP_LCD, CONTEXT_A);
CAMU_SetOutputFormat(SELECT_OUT1, OUTPUT_RGB_565, CONTEXT_A);
CAMU_SetFrameRate(SELECT_OUT1, FRAME_RATE_30);
CAMU_SetNoiseFilter(SELECT_OUT1, true);
CAMU_SetAutoExposure(SELECT_OUT1, true);
CAMU_SetAutoWhiteBalance(SELECT_OUT1, true);
CAMU_SetPhotoMode(SELECT_OUT1, PHOTO_MODE_LETTER);
/* No clue if this is actually effective or if it's just a placebo effect, but it seems to help? */
CAMU_SetSharpness(SELECT_OUT1, 127);
CAMU_Activate(SELECT_OUT1);
CAMU_GetBufferErrorInterruptEvent(&events[2], PORT_CAM1);
CAMU_SetTrimming(PORT_CAM1, false);
CAMU_GetMaxBytes(&transferUnit, 400, 240);
CAMU_SetTransferBytes(PORT_CAM1, transferUnit, 400, 240);
CAMU_ClearBuffer(PORT_CAM1);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), (s16)transferUnit);
CAMU_StartCapture(PORT_CAM1);
bool cancel = false;
while (!cancel) {
s32 index = 0;
svcWaitSynchronizationN(&index, events, 3, false, U64_MAX);
switch (index) {
case 0:
cancel = true;
break;
case 1:
svcCloseHandle(events[1]);
events[1] = 0;
LightLock_Lock(&this->bufferLock);
memcpy(this->cameraBuffer.data(), buffer, 400 * 240 * sizeof(u16));
GSPGPU_FlushDataCache(this->cameraBuffer.data(), 400 * 240 * sizeof(u16));
LightLock_Unlock(&this->bufferLock);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), transferUnit);
break;
case 2:
svcCloseHandle(events[1]);
events[1] = 0;
CAMU_ClearBuffer(PORT_CAM1);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), transferUnit);
CAMU_StartCapture(PORT_CAM1);
break;
default:
break;
}
}
CAMU_StopCapture(PORT_CAM1);
bool busy = false;
while (R_SUCCEEDED(CAMU_IsBusy(&busy, PORT_CAM1)) && busy) svcSleepThread(1000000);
CAMU_ClearBuffer(PORT_CAM1);
CAMU_Activate(SELECT_NONE);
camExit();
delete[] buffer;
for (int i = 1; i < 3; i++) {
if (events[i] != 0) {
svcCloseHandle(events[i]);
events[i] = 0;
}
}
this->finished = true;
}
/*
These are just Helpers.. because Threads.
*/
void drawHelper(void *arg) {
QRCode *qrData = (QRCode *)arg;
qrData->drawThread();
}
void captureHelper(void *arg) {
QRCode *qrData = (QRCode *)arg;
qrData->captureThread();
}
/*
Handle the capture.
*/
void QRCode::handler(std::string &result) {
hidScanInput();
touchPosition t;
hidTouchRead(&t);
u32 keyDown = hidKeysDown();
u32 keyRepeat = hidKeysDownRepeat();
if ((keyDown & KEY_B) || (keyDown & KEY_TOUCH && touching(t, mainButtons[8]))) {
result = "";
this->finished = true;
this->finish();
return;
}
/* Keyboard. */
if (keyDown & KEY_TOUCH && touching(t, mainButtons[7])) {
if (this->displayList) {
const std::string temp = Input::setkbdString(150, Lang::get("ENTER_URL"), { });
if (temp != "") {
result = temp;
this->finished = true;
this->finish();
return;
}
}
}
if (this->displayList) {
gspWaitForVBlank();
if ((keyDown & KEY_SELECT) || (keyDown & KEY_TOUCH && touching(t, mainButtons[6]))) {
keyDown = 0;
this->displayList = false;
}
if (this->stores.size() > 0) {
if (keyRepeat & KEY_DOWN) {
if (this->selectedStore < (int)this->stores.size() - 1) this->selectedStore++;
else this->selectedStore = 0;
}
if (keyRepeat & KEY_UP) {
if (this->selectedStore > 0) this->selectedStore--;
else this->selectedStore = (int)this->stores.size() - 1;
}
if (keyDown & KEY_A) {
result = this->stores[this->selectedStore].URL;
this->finished = true;
this->finish();
return;
}
if (keyDown & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(t, mainButtons[i])) {
if (i + this->sPos < (int)this->stores.size()) {
result = this->stores[i + this->sPos].URL;
this->finished = true;
this->finish();
return;
}
}
}
}
}
} else {
if (this->stores.size() > 0) {
if ((keyDown & KEY_SELECT) || (keyDown & KEY_TOUCH && touching(t, mainButtons[6]))) {
keyDown = 0;
this->displayList = true;
}
}
if (!this->capturing) {
/* create camera capture thread. */
if (threadCreate((ThreadFunc)&captureHelper, this, 0x10000, 0x1A, 1, true) != NULL) this->capturing = true;
else {
this->finish();
return;
}
}
if (this->done()) return;
int w, h;
u8 *image = (u8 *)quirc_begin(this->qrData, &w, &h);
LightLock_Lock(&bufferLock);
for (ssize_t x = 0; x < w; x++) {
for (ssize_t y = 0; y < h; y++) {
u16 px = this->cameraBuffer[y * 400 + x];
image[y * w + x] = (u8)(((((px >> 11) & 0x1F) << 3) + (((px >> 5) & 0x3F) << 2) + ((px & 0x1F) << 3)) / 3);
}
}
LightLock_Unlock(&this->bufferLock);
quirc_end(this->qrData);
if (quirc_count(this->qrData) > 0) {
struct quirc_code code;
struct quirc_data scan_data;
quirc_extract(this->qrData, 0, &code);
if (!quirc_decode(&code, &scan_data)) {
this->finish();
this->out.resize(scan_data.payload_len);
std::copy(scan_data.payload, scan_data.payload + scan_data.payload_len, this->out.begin());
/* From scanned stuff. */
if (this->out.empty()) result = "";
/* If Terminator, do -1. */
if (this->out.back() == '\0') result = std::string((char *)this->out.data(), this->out.size() - 1);
else result = std::string((char *)this->out.data(), this->out.size());
}
}
if (this->selectedStore < this->sPos) this->sPos = this->selectedStore;
else if (this->selectedStore > this->sPos + 6 - 1) this->sPos = this->selectedStore - 6 + 1;
}
}
/*
The Store Add QR Code handle and such.
*/
std::string QR_Scanner::StoreHandle() {
std::string result = "";
std::unique_ptr<QRCode> qrData = std::make_unique<QRCode>();
aptSetHomeAllowed(false); // Block the Home key.
threadCreate((ThreadFunc)&drawHelper, qrData.get(), 0x10000, 0x1A, 1, true);
while (!qrData->done()) qrData->handler(result); // Handle.
aptSetHomeAllowed(true); // Re-Allow it.
return result;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/*
* This file is part of PKSM
* Copyright (C) 2016-2020 Bernardo Giordano, Admiral Fish, piepie62
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "download.hpp"
#include "keyboard.hpp"
#include "qrcode.hpp"
#include <cstring>
static const std::vector<Structs::ButtonPos> mainButtons = {
{ 10, 34, 300, 22 },
{ 10, 64, 300, 22 },
{ 10, 94, 300, 22 },
{ 10, 124, 300, 22 },
{ 10, 154, 300, 22 },
{ 10, 184, 300, 22 },
{ 5, 215, 24, 24 }, // QR Code / List.
{ 35, 215, 24, 24 }, // Keyboard.
{ 4, 0, 24, 24 } // Back.
};
extern bool touching(touchPosition touch, Structs::ButtonPos button);
/*
Initialize everything needed for the camera.
*/
QRCode::QRCode() {
this->image.tex = new C3D_Tex;
this->image.subtex = &this->subtex;
this->qrData = quirc_new();
std::fill(this->cameraBuffer.begin(), this->cameraBuffer.end(), 0);
C3D_TexInit(this->image.tex, 512, 256, GPU_RGB565);
C3D_TexSetFilter(this->image.tex, GPU_LINEAR, GPU_LINEAR);
this->image.tex->border = 0xFFFFFFFF;
C3D_TexSetWrap(this->image.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
LightLock_Init(&this->bufferLock);
LightLock_Init(&this->imageLock);
svcCreateEvent(&this->exitEvent, RESET_STICKY);
quirc_resize(this->qrData, 400, 240);
if (checkWifiStatus()) this->stores = FetchStores(); // Fetching Stores here.
if (this->stores.size() > 0) this->displayList = true;
}
/*
Destroy everything.
*/
QRCode::~QRCode() {
C3D_TexDelete(this->image.tex);
delete this->image.tex;
quirc_destroy(this->qrData);
svcCloseHandle(this->exitEvent);
}
/*
mem copy the captured Image to the buffer, used for drawing.
*/
void QRCode::buffToImage() {
LightLock_Lock(&this->bufferLock);
for (u32 x = 0; x < 400; x++) {
for (u32 y = 0; y < 240; 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))) * 2;
const u32 srcPos = (y * 400 + x) * 2;
memcpy(((u8 *)this->image.tex->data) + dstPos, ((u8 *)this->cameraBuffer.data()) + srcPos, 2);
}
}
LightLock_Unlock(&this->bufferLock);
}
/*
Finish and unlock everything.
*/
void QRCode::finish() {
svcSignalEvent(this->exitEvent);
while (!this->done()) svcSleepThread(1000000);
LightLock_Lock(&this->bufferLock);
LightLock_Unlock(&this->bufferLock);
LightLock_Lock(&this->imageLock);
LightLock_Unlock(&this->imageLock);
}
/*
The Draw Thread of the Camera.
*/
void QRCode::drawThread() {
LightLock_Lock(&this->imageLock);
/* If we aren't done.. do the draw to scan. */
while (!this->done()) {
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
if (!this->displayList) {
this->buffToImage(); // Fetch image.
Gui::ScreenDraw(Top);
C2D_DrawImageAt(this->image, 0, 0, 0.5, nullptr, 1.0f, 1.0f);
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
} else {
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.7, TEXT_COLOR, Lang::get("STORE_INFO"), 390, 0, font);
if (this->stores.size() > 0) {
Gui::DrawStringCentered(0, 30, 0.7f, TEXT_COLOR, this->stores[this->selectedStore].Title, 390, 0, font);
Gui::DrawStringCentered(0, 50, 0.6f, TEXT_COLOR, this->stores[this->selectedStore].Author, 380, 0, font);
Gui::DrawStringCentered(0, 90, 0.5f, TEXT_COLOR, this->stores[this->selectedStore].Description, 380, 130, font, C2D_WordWrap);
}
GFX::DrawBottom();
Gui::Draw_Rect(0, 0, 320, 25, ENTRY_BAR_COLOR);
Gui::Draw_Rect(0, 25, 320, 1, ENTRY_BAR_OUTL_COLOR);
Gui::DrawStringCentered(0, 2, 0.6, TEXT_COLOR, Lang::get("RECOMMENDED_ESHOP"), 310, 0, font);
for(int i = 0; i < 6 && i < (int)this->stores.size(); i++) {
if (this->sPos + i == this->selectedStore) GFX::DrawBox(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, false);
Gui::DrawStringCentered(10 - 160 + (300 / 2), mainButtons[i].y + 4, 0.45f, TEXT_COLOR, this->stores[this->sPos + i].Title, 295, 0, font);
}
}
GFX::DrawSprite((this->displayList ? sprites_qr_code_idx : sprites_list_idx), mainButtons[6].x, mainButtons[6].y);
if (this->displayList) GFX::DrawSprite(sprites_keyboard_idx, mainButtons[7].x, mainButtons[7].y);
GFX::DrawSprite(sprites_arrow_idx, mainButtons[8].x, mainButtons[8].y);
C3D_FrameEnd(0);
}
LightLock_Unlock(&this->imageLock);
}
/*
The Capture Thread of the camera.
*/
void QRCode::captureThread() {
Handle events[3] = { 0 };
events[0] = exitEvent;
u32 transferUnit;
u16 *buffer = new u16[400 * 240];
camInit();
CAMU_SetSize(SELECT_OUT1, SIZE_CTR_TOP_LCD, CONTEXT_A);
CAMU_SetOutputFormat(SELECT_OUT1, OUTPUT_RGB_565, CONTEXT_A);
CAMU_SetFrameRate(SELECT_OUT1, FRAME_RATE_30);
CAMU_SetNoiseFilter(SELECT_OUT1, true);
CAMU_SetAutoExposure(SELECT_OUT1, true);
CAMU_SetAutoWhiteBalance(SELECT_OUT1, true);
CAMU_SetPhotoMode(SELECT_OUT1, PHOTO_MODE_LETTER);
/* No clue if this is actually effective or if it's just a placebo effect, but it seems to help? */
CAMU_SetSharpness(SELECT_OUT1, 127);
CAMU_Activate(SELECT_OUT1);
CAMU_GetBufferErrorInterruptEvent(&events[2], PORT_CAM1);
CAMU_SetTrimming(PORT_CAM1, false);
CAMU_GetMaxBytes(&transferUnit, 400, 240);
CAMU_SetTransferBytes(PORT_CAM1, transferUnit, 400, 240);
CAMU_ClearBuffer(PORT_CAM1);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), (s16)transferUnit);
CAMU_StartCapture(PORT_CAM1);
bool cancel = false;
while (!cancel) {
s32 index = 0;
svcWaitSynchronizationN(&index, events, 3, false, U64_MAX);
switch (index) {
case 0:
cancel = true;
break;
case 1:
svcCloseHandle(events[1]);
events[1] = 0;
LightLock_Lock(&this->bufferLock);
memcpy(this->cameraBuffer.data(), buffer, 400 * 240 * sizeof(u16));
GSPGPU_FlushDataCache(this->cameraBuffer.data(), 400 * 240 * sizeof(u16));
LightLock_Unlock(&this->bufferLock);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), transferUnit);
break;
case 2:
svcCloseHandle(events[1]);
events[1] = 0;
CAMU_ClearBuffer(PORT_CAM1);
CAMU_SetReceiving(&events[1], buffer, PORT_CAM1, 400 * 240 * sizeof(u16), transferUnit);
CAMU_StartCapture(PORT_CAM1);
break;
default:
break;
}
}
CAMU_StopCapture(PORT_CAM1);
bool busy = false;
while (R_SUCCEEDED(CAMU_IsBusy(&busy, PORT_CAM1)) && busy) svcSleepThread(1000000);
CAMU_ClearBuffer(PORT_CAM1);
CAMU_Activate(SELECT_NONE);
camExit();
delete[] buffer;
for (int i = 1; i < 3; i++) {
if (events[i] != 0) {
svcCloseHandle(events[i]);
events[i] = 0;
}
}
this->finished = true;
}
/*
These are just Helpers.. because Threads.
*/
void drawHelper(void *arg) {
QRCode *qrData = (QRCode *)arg;
qrData->drawThread();
}
void captureHelper(void *arg) {
QRCode *qrData = (QRCode *)arg;
qrData->captureThread();
}
/*
Handle the capture.
*/
void QRCode::handler(std::string &result) {
hidScanInput();
touchPosition t;
hidTouchRead(&t);
u32 keyDown = hidKeysDown();
u32 keyRepeat = hidKeysDownRepeat();
if ((keyDown & KEY_B) || (keyDown & KEY_TOUCH && touching(t, mainButtons[8]))) {
result = "";
this->finished = true;
this->finish();
return;
}
/* Keyboard. */
if (keyDown & KEY_TOUCH && touching(t, mainButtons[7])) {
if (this->displayList) {
const std::string temp = Input::setkbdString(150, Lang::get("ENTER_URL"), { });
if (temp != "") {
result = temp;
this->finished = true;
this->finish();
return;
}
}
}
if (this->displayList) {
gspWaitForVBlank();
if ((keyDown & KEY_SELECT) || (keyDown & KEY_TOUCH && touching(t, mainButtons[6]))) {
keyDown = 0;
this->displayList = false;
}
if (this->stores.size() > 0) {
if (keyRepeat & KEY_DOWN) {
if (this->selectedStore < (int)this->stores.size() - 1) this->selectedStore++;
else this->selectedStore = 0;
}
if (keyRepeat & KEY_UP) {
if (this->selectedStore > 0) this->selectedStore--;
else this->selectedStore = (int)this->stores.size() - 1;
}
if (keyDown & KEY_A) {
result = this->stores[this->selectedStore].URL;
this->finished = true;
this->finish();
return;
}
if (keyDown & KEY_TOUCH) {
for (int i = 0; i < 6; i++) {
if (touching(t, mainButtons[i])) {
if (i + this->sPos < (int)this->stores.size()) {
result = this->stores[i + this->sPos].URL;
this->finished = true;
this->finish();
return;
}
}
}
}
}
} else {
if (this->stores.size() > 0) {
if ((keyDown & KEY_SELECT) || (keyDown & KEY_TOUCH && touching(t, mainButtons[6]))) {
keyDown = 0;
this->displayList = true;
}
}
if (!this->capturing) {
/* create camera capture thread. */
if (threadCreate((ThreadFunc)&captureHelper, this, 0x10000, 0x1A, 1, true) != NULL) this->capturing = true;
else {
this->finish();
return;
}
}
if (this->done()) return;
int w, h;
u8 *image = (u8 *)quirc_begin(this->qrData, &w, &h);
LightLock_Lock(&bufferLock);
for (ssize_t x = 0; x < w; x++) {
for (ssize_t y = 0; y < h; y++) {
u16 px = this->cameraBuffer[y * 400 + x];
image[y * w + x] = (u8)(((((px >> 11) & 0x1F) << 3) + (((px >> 5) & 0x3F) << 2) + ((px & 0x1F) << 3)) / 3);
}
}
LightLock_Unlock(&this->bufferLock);
quirc_end(this->qrData);
if (quirc_count(this->qrData) > 0) {
struct quirc_code code;
struct quirc_data scan_data;
quirc_extract(this->qrData, 0, &code);
if (!quirc_decode(&code, &scan_data)) {
this->finish();
this->out.resize(scan_data.payload_len);
std::copy(scan_data.payload, scan_data.payload + scan_data.payload_len, this->out.begin());
/* From scanned stuff. */
if (this->out.empty()) result = "";
/* If Terminator, do -1. */
if (this->out.back() == '\0') result = std::string((char *)this->out.data(), this->out.size() - 1);
else result = std::string((char *)this->out.data(), this->out.size());
}
}
if (this->selectedStore < this->sPos) this->sPos = this->selectedStore;
else if (this->selectedStore > this->sPos + 6 - 1) this->sPos = this->selectedStore - 6 + 1;
}
}
/*
The Store Add QR Code handle and such.
*/
std::string QR_Scanner::StoreHandle() {
std::string result = "";
std::unique_ptr<QRCode> qrData = std::make_unique<QRCode>();
aptSetHomeAllowed(false); // Block the Home key.
threadCreate((ThreadFunc)&drawHelper, qrData.get(), 0x10000, 0x1A, 1, true);
while (!qrData->done()) qrData->handler(result); // Handle.
aptSetHomeAllowed(true); // Re-Allow it.
return result;
}
+100 -100
View File
@@ -1,101 +1,101 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "quirc_internal.hpp"
const char *quirc_version(void) { return "1.0"; }
struct quirc *quirc_new(void) {
struct quirc *q = (quirc *)malloc(sizeof(*q));
if (!q) return NULL;
memset(q, 0, sizeof(*q));
return q;
}
void quirc_destroy(struct quirc *q) {
if (q->image) free(q->image);
if (sizeof(*q->image) != sizeof(*q->pixels)) free(q->pixels);
free(q);
}
int quirc_resize(struct quirc *q, int w, int h) {
uint8_t *new_image = (uint8_t *)realloc(q->image, w * h);
if (!new_image) return -1;
if (sizeof(*q->image) != sizeof(*q->pixels)) {
size_t new_size = w * h * sizeof(quirc_pixel_t);
quirc_pixel_t *new_pixels = (quirc_pixel_t *)realloc(q->pixels, new_size);
if (!new_pixels) return -1;
q->pixels = new_pixels;
}
q->image = new_image;
q->w = w;
q->h = h;
return 0;
}
int quirc_count(const struct quirc *q) { return q->num_grids; }
static const char *const error_table[] = {
[QUIRC_SUCCESS] = "Success",
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"
};
const char *quirc_strerror(quirc_decode_error_t err) {
if (err < sizeof(error_table) / sizeof(error_table[0])) return error_table[err];
return "Unknown error";
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "quirc_internal.hpp"
const char *quirc_version(void) { return "1.0"; }
struct quirc *quirc_new(void) {
struct quirc *q = (quirc *)malloc(sizeof(*q));
if (!q) return NULL;
memset(q, 0, sizeof(*q));
return q;
}
void quirc_destroy(struct quirc *q) {
if (q->image) free(q->image);
if (sizeof(*q->image) != sizeof(*q->pixels)) free(q->pixels);
free(q);
}
int quirc_resize(struct quirc *q, int w, int h) {
uint8_t *new_image = (uint8_t *)realloc(q->image, w * h);
if (!new_image) return -1;
if (sizeof(*q->image) != sizeof(*q->pixels)) {
size_t new_size = w * h * sizeof(quirc_pixel_t);
quirc_pixel_t *new_pixels = (quirc_pixel_t *)realloc(q->pixels, new_size);
if (!new_pixels) return -1;
q->pixels = new_pixels;
}
q->image = new_image;
q->w = w;
q->h = h;
return 0;
}
int quirc_count(const struct quirc *q) { return q->num_grids; }
static const char *const error_table[] = {
[QUIRC_SUCCESS] = "Success",
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"
};
const char *quirc_strerror(quirc_decode_error_t err) {
if (err < sizeof(error_table) / sizeof(error_table[0])) return error_table[err];
return "Unknown error";
}
+447 -447
View File
@@ -1,447 +1,447 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "quirc_internal.hpp"
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
{0},
{ /* Version 1 */
.data_bytes = 26,
.apat = {0},
.ecc = {
{.bs = 26, .dw = 16, .ce = 4},
{.bs = 26, .dw = 19, .ce = 2},
{.bs = 26, .dw = 9, .ce = 8},
{.bs = 26, .dw = 13, .ce = 6}
}
},
{ /* Version 2 */
.data_bytes = 44,
.apat = {6, 18, 0},
.ecc = {
{.bs = 44, .dw = 28, .ce = 8},
{.bs = 44, .dw = 34, .ce = 4},
{.bs = 44, .dw = 16, .ce = 14},
{.bs = 44, .dw = 22, .ce = 11}
}
},
{ /* Version 3 */
.data_bytes = 70,
.apat = {6, 22, 0},
.ecc = {
{.bs = 70, .dw = 44, .ce = 13},
{.bs = 70, .dw = 55, .ce = 7},
{.bs = 35, .dw = 13, .ce = 11},
{.bs = 35, .dw = 17, .ce = 9}
}
},
{ /* Version 4 */
.data_bytes = 100,
.apat = {6, 26, 0},
.ecc = {
{.bs = 50, .dw = 32, .ce = 9},
{.bs = 100, .dw = 80, .ce = 10},
{.bs = 25, .dw = 9, .ce = 8},
{.bs = 50, .dw = 24, .ce = 13}
}
},
{ /* Version 5 */
.data_bytes = 134,
.apat = {6, 30, 0},
.ecc = {
{.bs = 67, .dw = 43, .ce = 12},
{.bs = 134, .dw = 108, .ce = 13},
{.bs = 33, .dw = 11, .ce = 11},
{.bs = 33, .dw = 15, .ce = 9}
}
},
{ /* Version 6 */
.data_bytes = 172,
.apat = {6, 34, 0},
.ecc = {
{.bs = 43, .dw = 27, .ce = 8},
{.bs = 86, .dw = 68, .ce = 9},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 7 */
.data_bytes = 196,
.apat = {6, 22, 38, 0},
.ecc = {
{.bs = 49, .dw = 31, .ce = 9},
{.bs = 98, .dw = 78, .ce = 10},
{.bs = 39, .dw = 13, .ce = 13},
{.bs = 32, .dw = 14, .ce = 9}
}
},
{ /* Version 8 */
.data_bytes = 242,
.apat = {6, 24, 42, 0},
.ecc = {
{.bs = 60, .dw = 38, .ce = 11},
{.bs = 121, .dw = 97, .ce = 12},
{.bs = 40, .dw = 14, .ce = 13},
{.bs = 40, .dw = 18, .ce = 11}
}
},
{ /* Version 9 */
.data_bytes = 292,
.apat = {6, 26, 46, 0},
.ecc = {
{.bs = 58, .dw = 36, .ce = 11},
{.bs = 146, .dw = 116, .ce = 15},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 36, .dw = 16, .ce = 10}
}
},
{ /* Version 10 */
.data_bytes = 346,
.apat = {6, 28, 50, 0},
.ecc = {
{.bs = 69, .dw = 43, .ce = 13},
{.bs = 86, .dw = 68, .ce = 9},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 11 */
.data_bytes = 404,
.apat = {6, 30, 54, 0},
.ecc = {
{.bs = 80, .dw = 50, .ce = 15},
{.bs = 101, .dw = 81, .ce = 10},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 12 */
.data_bytes = 466,
.apat = {6, 32, 58, 0},
.ecc = {
{.bs = 58, .dw = 36, .ce = 11},
{.bs = 116, .dw = 92, .ce = 12},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 46, .dw = 20, .ce = 14}
}
},
{ /* Version 13 */
.data_bytes = 532,
.apat = {6, 34, 62, 0},
.ecc = {
{.bs = 59, .dw = 37, .ce = 11},
{.bs = 133, .dw = 107, .ce = 13},
{.bs = 33, .dw = 11, .ce = 11},
{.bs = 44, .dw = 20, .ce = 12}
}
},
{ /* Version 14 */
.data_bytes = 581,
.apat = {6, 26, 46, 66, 0},
.ecc = {
{.bs = 65, .dw = 41, .ce = 12},
{.bs = 109, .dw = 87, .ce = 11},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 15 */
.data_bytes = 655,
.apat = {6, 26, 48, 70, 0},
.ecc = {
{.bs = 65, .dw = 41, .ce = 12},
{.bs = 109, .dw = 87, .ce = 11},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 16 */
.data_bytes = 733,
.apat = {6, 26, 50, 74, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 122, .dw = 98, .ce = 12},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 17 */
.data_bytes = 815,
.apat = {6, 30, 54, 78, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 135, .dw = 107, .ce = 14},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 18 */
.data_bytes = 901,
.apat = {6, 30, 56, 82, 0},
.ecc = {
{.bs = 69, .dw = 43, .ce = 13},
{.bs = 150, .dw = 120, .ce = 15},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 19 */
.data_bytes = 991,
.apat = {6, 30, 58, 86, 0},
.ecc = {
{.bs = 70, .dw = 44, .ce = 13},
{.bs = 141, .dw = 113, .ce = 14},
{.bs = 39, .dw = 13, .ce = 13},
{.bs = 47, .dw = 21, .ce = 13}
}
},
{ /* Version 20 */
.data_bytes = 1085,
.apat = {6, 34, 62, 90, 0},
.ecc = {
{.bs = 67, .dw = 41, .ce = 13},
{.bs = 135, .dw = 107, .ce = 14},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 21 */
.data_bytes = 1156,
.apat = {6, 28, 50, 72, 92, 0},
.ecc = {
{.bs = 68, .dw = 42, .ce = 13},
{.bs = 144, .dw = 116, .ce = 14},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 22 */
.data_bytes = 1258,
.apat = {6, 26, 50, 74, 98, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 139, .dw = 111, .ce = 14},
{.bs = 37, .dw = 13, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 23 */
.data_bytes = 1364,
.apat = {6, 30, 54, 78, 102, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 24 */
.data_bytes = 1474,
.apat = {6, 28, 54, 80, 106, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 25 */
.data_bytes = 1588,
.apat = {6, 32, 58, 84, 110, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 132, .dw = 106, .ce = 13},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 26 */
.data_bytes = 1706,
.apat = {6, 30, 58, 86, 114, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 142, .dw = 114, .ce = 14},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 27 */
.data_bytes = 1828,
.apat = {6, 34, 62, 90, 118, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 53, .dw = 23, .ce = 15}
}
},
{ /* Version 28 */
.data_bytes = 1921,
.apat = {6, 26, 50, 74, 98, 122, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 29 */
.data_bytes = 2051,
.apat = {6, 30, 54, 78, 102, 126, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 146, .dw = 116, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 73, .dw = 45, .ce = 14}
}
},
{ /* Version 30 */
.data_bytes = 2185,
.apat = {6, 26, 52, 78, 104, 130, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 31 */
.data_bytes = 2323,
.apat = {6, 30, 56, 82, 108, 134, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 32 */
.data_bytes = 2465,
.apat = {6, 34, 60, 86, 112, 138, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 33 */
.data_bytes = 2611,
.apat = {6, 30, 58, 96, 114, 142, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 34 */
.data_bytes = 2761,
.apat = {6, 34, 62, 90, 118, 146, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 35 */
.data_bytes = 2876,
.apat = {6, 30, 54, 78, 102, 126, 150},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 36 */
.data_bytes = 3034,
.apat = {6, 24, 50, 76, 102, 128, 154},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 37 */
.data_bytes = 3196,
.apat = {6, 28, 54, 80, 106, 132, 158},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 38 */
.data_bytes = 3362,
.apat = {6, 32, 58, 84, 110, 136, 162},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 39 */
.data_bytes = 3532,
.apat = {6, 26, 54, 82, 110, 138, 166},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 40 */
.data_bytes = 3706,
.apat = {6, 30, 58, 86, 114, 142, 170},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 148, .dw = 118, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
}
};
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "quirc_internal.hpp"
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
{0},
{ /* Version 1 */
.data_bytes = 26,
.apat = {0},
.ecc = {
{.bs = 26, .dw = 16, .ce = 4},
{.bs = 26, .dw = 19, .ce = 2},
{.bs = 26, .dw = 9, .ce = 8},
{.bs = 26, .dw = 13, .ce = 6}
}
},
{ /* Version 2 */
.data_bytes = 44,
.apat = {6, 18, 0},
.ecc = {
{.bs = 44, .dw = 28, .ce = 8},
{.bs = 44, .dw = 34, .ce = 4},
{.bs = 44, .dw = 16, .ce = 14},
{.bs = 44, .dw = 22, .ce = 11}
}
},
{ /* Version 3 */
.data_bytes = 70,
.apat = {6, 22, 0},
.ecc = {
{.bs = 70, .dw = 44, .ce = 13},
{.bs = 70, .dw = 55, .ce = 7},
{.bs = 35, .dw = 13, .ce = 11},
{.bs = 35, .dw = 17, .ce = 9}
}
},
{ /* Version 4 */
.data_bytes = 100,
.apat = {6, 26, 0},
.ecc = {
{.bs = 50, .dw = 32, .ce = 9},
{.bs = 100, .dw = 80, .ce = 10},
{.bs = 25, .dw = 9, .ce = 8},
{.bs = 50, .dw = 24, .ce = 13}
}
},
{ /* Version 5 */
.data_bytes = 134,
.apat = {6, 30, 0},
.ecc = {
{.bs = 67, .dw = 43, .ce = 12},
{.bs = 134, .dw = 108, .ce = 13},
{.bs = 33, .dw = 11, .ce = 11},
{.bs = 33, .dw = 15, .ce = 9}
}
},
{ /* Version 6 */
.data_bytes = 172,
.apat = {6, 34, 0},
.ecc = {
{.bs = 43, .dw = 27, .ce = 8},
{.bs = 86, .dw = 68, .ce = 9},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 7 */
.data_bytes = 196,
.apat = {6, 22, 38, 0},
.ecc = {
{.bs = 49, .dw = 31, .ce = 9},
{.bs = 98, .dw = 78, .ce = 10},
{.bs = 39, .dw = 13, .ce = 13},
{.bs = 32, .dw = 14, .ce = 9}
}
},
{ /* Version 8 */
.data_bytes = 242,
.apat = {6, 24, 42, 0},
.ecc = {
{.bs = 60, .dw = 38, .ce = 11},
{.bs = 121, .dw = 97, .ce = 12},
{.bs = 40, .dw = 14, .ce = 13},
{.bs = 40, .dw = 18, .ce = 11}
}
},
{ /* Version 9 */
.data_bytes = 292,
.apat = {6, 26, 46, 0},
.ecc = {
{.bs = 58, .dw = 36, .ce = 11},
{.bs = 146, .dw = 116, .ce = 15},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 36, .dw = 16, .ce = 10}
}
},
{ /* Version 10 */
.data_bytes = 346,
.apat = {6, 28, 50, 0},
.ecc = {
{.bs = 69, .dw = 43, .ce = 13},
{.bs = 86, .dw = 68, .ce = 9},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 11 */
.data_bytes = 404,
.apat = {6, 30, 54, 0},
.ecc = {
{.bs = 80, .dw = 50, .ce = 15},
{.bs = 101, .dw = 81, .ce = 10},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 12 */
.data_bytes = 466,
.apat = {6, 32, 58, 0},
.ecc = {
{.bs = 58, .dw = 36, .ce = 11},
{.bs = 116, .dw = 92, .ce = 12},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 46, .dw = 20, .ce = 14}
}
},
{ /* Version 13 */
.data_bytes = 532,
.apat = {6, 34, 62, 0},
.ecc = {
{.bs = 59, .dw = 37, .ce = 11},
{.bs = 133, .dw = 107, .ce = 13},
{.bs = 33, .dw = 11, .ce = 11},
{.bs = 44, .dw = 20, .ce = 12}
}
},
{ /* Version 14 */
.data_bytes = 581,
.apat = {6, 26, 46, 66, 0},
.ecc = {
{.bs = 65, .dw = 41, .ce = 12},
{.bs = 109, .dw = 87, .ce = 11},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 15 */
.data_bytes = 655,
.apat = {6, 26, 48, 70, 0},
.ecc = {
{.bs = 65, .dw = 41, .ce = 12},
{.bs = 109, .dw = 87, .ce = 11},
{.bs = 36, .dw = 12, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 16 */
.data_bytes = 733,
.apat = {6, 26, 50, 74, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 122, .dw = 98, .ce = 12},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 43, .dw = 19, .ce = 12}
}
},
{ /* Version 17 */
.data_bytes = 815,
.apat = {6, 30, 54, 78, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 135, .dw = 107, .ce = 14},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 18 */
.data_bytes = 901,
.apat = {6, 30, 56, 82, 0},
.ecc = {
{.bs = 69, .dw = 43, .ce = 13},
{.bs = 150, .dw = 120, .ce = 15},
{.bs = 42, .dw = 14, .ce = 14},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 19 */
.data_bytes = 991,
.apat = {6, 30, 58, 86, 0},
.ecc = {
{.bs = 70, .dw = 44, .ce = 13},
{.bs = 141, .dw = 113, .ce = 14},
{.bs = 39, .dw = 13, .ce = 13},
{.bs = 47, .dw = 21, .ce = 13}
}
},
{ /* Version 20 */
.data_bytes = 1085,
.apat = {6, 34, 62, 90, 0},
.ecc = {
{.bs = 67, .dw = 41, .ce = 13},
{.bs = 135, .dw = 107, .ce = 14},
{.bs = 43, .dw = 15, .ce = 14},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 21 */
.data_bytes = 1156,
.apat = {6, 28, 50, 72, 92, 0},
.ecc = {
{.bs = 68, .dw = 42, .ce = 13},
{.bs = 144, .dw = 116, .ce = 14},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 22 */
.data_bytes = 1258,
.apat = {6, 26, 50, 74, 98, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 139, .dw = 111, .ce = 14},
{.bs = 37, .dw = 13, .ce = 12},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 23 */
.data_bytes = 1364,
.apat = {6, 30, 54, 78, 102, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 24 */
.data_bytes = 1474,
.apat = {6, 28, 54, 80, 106, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 25 */
.data_bytes = 1588,
.apat = {6, 32, 58, 84, 110, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 132, .dw = 106, .ce = 13},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 26 */
.data_bytes = 1706,
.apat = {6, 30, 58, 86, 114, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 142, .dw = 114, .ce = 14},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 50, .dw = 22, .ce = 14}
}
},
{ /* Version 27 */
.data_bytes = 1828,
.apat = {6, 34, 62, 90, 118, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 53, .dw = 23, .ce = 15}
}
},
{ /* Version 28 */
.data_bytes = 1921,
.apat = {6, 26, 50, 74, 98, 122, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 29 */
.data_bytes = 2051,
.apat = {6, 30, 54, 78, 102, 126, 0},
.ecc = {
{.bs = 73, .dw = 45, .ce = 14},
{.bs = 146, .dw = 116, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 73, .dw = 45, .ce = 14}
}
},
{ /* Version 30 */
.data_bytes = 2185,
.apat = {6, 26, 52, 78, 104, 130, 0},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 31 */
.data_bytes = 2323,
.apat = {6, 30, 56, 82, 108, 134, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 32 */
.data_bytes = 2465,
.apat = {6, 34, 60, 86, 112, 138, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 33 */
.data_bytes = 2611,
.apat = {6, 30, 58, 96, 114, 142, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 34 */
.data_bytes = 2761,
.apat = {6, 34, 62, 90, 118, 146, 0},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 145, .dw = 115, .ce = 15},
{.bs = 46, .dw = 16, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 35 */
.data_bytes = 2876,
.apat = {6, 30, 54, 78, 102, 126, 150},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 36 */
.data_bytes = 3034,
.apat = {6, 24, 50, 76, 102, 128, 154},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 151, .dw = 121, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 37 */
.data_bytes = 3196,
.apat = {6, 28, 54, 80, 106, 132, 158},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 38 */
.data_bytes = 3362,
.apat = {6, 32, 58, 84, 110, 136, 162},
.ecc = {
{.bs = 74, .dw = 46, .ce = 14},
{.bs = 152, .dw = 122, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 39 */
.data_bytes = 3532,
.apat = {6, 26, 54, 82, 110, 138, 166},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 147, .dw = 117, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
},
{ /* Version 40 */
.data_bytes = 3706,
.apat = {6, 30, 58, 86, 114, 142, 170},
.ecc = {
{.bs = 75, .dw = 47, .ce = 14},
{.bs = 148, .dw = 118, .ce = 15},
{.bs = 45, .dw = 15, .ce = 15},
{.bs = 54, .dw = 24, .ce = 15}
}
}
};
+271 -271
View File
@@ -1,271 +1,271 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "fileBrowse.hpp"
#include "mainScreen.hpp"
#include "screenshot.hpp"
#include "storeUtils.hpp"
#include <unistd.h>
extern int fadeAlpha;
extern EshopInfo GetInfo(const std::string &file, const std::string &fileName);
extern void notConnectedMsg();
extern void DisplayChangelog();
/*
MainScreen Constructor.
Initialized Meta, Store and StoreEntry class and:
- Downloads darkstore-homebrew.eshop.. in case nothing exist.
*/
MainScreen::MainScreen() {
this->meta = std::make_unique<Meta>();
/* Check if lastStore is accessible. */
if (config->lastStore() != "darkstore-homebrew.eshop" || config->lastStore() != "") {
if (access((std::string(_STORE_PATH) + config->lastStore()).c_str(), F_OK) != 0) {
config->lastStore("darkstore-homebrew.eshop");
} else {
/* check version and file here. */
const EshopInfo info = GetInfo((std::string(_STORE_PATH) + config->lastStore()), config->lastStore());
if (info.Version != 3 && info.Version != _ESHOP_VERSION) {
config->lastStore("darkstore-homebrew.eshop");
}
if (info.File != "") { // Ensure to check for this.
if ((info.File.find("/") != std::string::npos)) {
config->lastStore("darkstore-homebrew.eshop"); // It does contain a '/' which is invalid.
}
}
}
}
/* If darkstore-homebrew.eshop --> Get! */
if (config->lastStore() == "darkstore-homebrew.eshop" || config->lastStore() == "") {
if (access("sdmc:/3ds/DarkStore/stores/darkstore-homebrew.eshop", F_OK) != 0) {
if (checkWifiStatus()) {
std::string tmp = ""; // Juste une intérimaire.
DownloadEshop("https://darkstore.ml/assets/darkstore-homebrew.eshop", -1, tmp, true, true);
DownloadSpriteSheet("https://darkstore.ml/assets/icon.t3x", "icon.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_1.t3x", "icon_1.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_2.t3x", "icon_2.t3x");
} else {
notConnectedMsg();
}
} else {
const EshopInfo info = GetInfo("sdmc:/3ds/DarkStore/stores/darkstore-homebrew.eshop", "darkstore-homebrew.eshop");
if (info.Version != 3 && info.Version != _ESHOP_VERSION) {
Msg::waitMsg("Not passing the check!");
if (checkWifiStatus()) {
std::string tmp = ""; // Juste une intérimaire.
DownloadEshop("https://darkstore.ml/assets/darkstore-homebrew.eshop", -1, tmp, true, true);
DownloadSpriteSheet("https://darkstore.ml/assets/icon.t3x", "icon.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_1.t3x", "icon_1.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_2.t3x", "icon_2.t3x");
} else {
notConnectedMsg();
}
}
}
}
this->store = std::make_unique<Store>(_STORE_PATH + config->lastStore(), config->lastStore());
StoreUtils::ResetAll(this->store, this->meta, this->entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, this->entries);
DisplayChangelog();
};
/*
MainScreen Main Draw.
*/
void MainScreen::Draw(void) const {
if (this->storeMode == 6) {
/* Screenshot Menu. */
StoreUtils::DrawScreenshotMenu(this->Screenshot, this->screenshotIndex, this->screenshotFetch, this->sSize, this->screenshotName, this->zoom, this->canDisplay);
return;
}
if (this->storeMode == 7) {
/* Release Notes. */
StoreUtils::DrawReleaseNotes(this->scrollIndex, this->entries[this->store->GetEntry()], this->store);
GFX::DrawBottom();
return;
}
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
if (this->store && this->store->GetValid()) Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, this->store->GetEshopTitle(), 370, 0, font);
else Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_ESHOP"), 370, 0, font);
config->list() ? StoreUtils::DrawList(this->store, this->entries) : StoreUtils::DrawGrid(this->store, this->entries);
/* Download-ception. */
if (this->storeMode == 1) {
StoreUtils::DrawDownList(this->store, this->dwnldList, this->fetchDown, this->entries[this->store->GetEntry()], this->dwnldSizes);
} else {
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(0, 0, 0, fadeAlpha));
GFX::DrawBottom();
switch(this->storeMode) {
case 0:
/* Entry Info. */
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DrawEntryInfo(this->store, this->entries[this->store->GetEntry()]);
break;
case 2:
StoreUtils::DrawQueueMenu(this->queueIndex);
break;
case 3:
/* Search + Favorites. */
StoreUtils::DrawSearchMenu(this->searchIncludes, this->searchResult, this->marks, this->updateFilter);
break;
case 4:
/* Sorting. */
StoreUtils::DrawSorting(this->ascending, this->sorttype);
break;
case 5:
/* Settings. */
StoreUtils::DrawSettings(this->sPage, this->sSelection, this->sPos);
break;
}
}
StoreUtils::DrawSideMenu(this->storeMode);
if (this->showMarks && this->store && this->store->GetValid()) StoreUtils::DisplayMarkBox(this->entries[this->store->GetEntry()]->GetMarks());
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, fadeAlpha));
}
/*
MainScreen Logic.
*/
void MainScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
/* Screenshots Menu. */
if (this->storeMode == 6) {
if (this->screenshotFetch) {
/* Delete Texture first. */
if (this->Screenshot.tex) {
C3D_TexDelete(this->Screenshot.tex);
this->Screenshot.tex = nullptr;
this->Screenshot.subtex = nullptr;
}
this->screenshotName = "";
if (this->screenshotIndex < (int)this->entries[this->store->GetEntry()]->GetScreenshotNames().size()) {
this->screenshotName = this->entries[this->store->GetEntry()]->GetScreenshotNames()[this->screenshotIndex];
}
this->sSize = 0;
this->sSize = this->entries[this->store->GetEntry()]->GetScreenshots().size();
if (this->screenshotIndex < this->sSize) {
if (this->sSize > 0) {
this->Screenshot = FetchScreenshot(this->entries[this->store->GetEntry()]->GetScreenshots()[this->screenshotIndex]);
if (this->Screenshot.tex) this->canDisplay = true;
else this->canDisplay = false;
}
}
this->screenshotFetch = false;
}
StoreUtils::ScreenshotMenu(this->Screenshot, this->screenshotIndex, this->screenshotFetch, this->storeMode, this->sSize, this->zoom, this->canDisplay);
return;
}
/* Release Notes. */
if (this->storeMode == 7) {
StoreUtils::ReleaseNotesLogic(this->scrollIndex, this->storeMode);
return;
}
/* Mark Menu. */
if (this->showMarks) StoreUtils::MarkHandle(this->entries[this->store->GetEntry()], this->store, this->showMarks, this->meta);
if (!this->showMarks) {
if (this->storeMode == 0 || this->storeMode == 3 || this->storeMode == 4) {
config->list() ? StoreUtils::ListLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay) : StoreUtils::GridLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay);
}
StoreUtils::SideMenuHandle(this->storeMode, this->fetchDown, this->lastMode);
/* Fetch Download list. */
if (this->fetchDown) {
this->dwnldList.clear();
this->dwnldSizes.clear();
if (this->store && this->store->GetValid()) {
this->store->SetDownloadIndex(0); // Reset to 0.
this->store->SetDownloadSIndex(0);
if ((int)this->entries.size() > this->store->GetEntry()) {
this->dwnldList = this->store->GetDownloadList(this->entries[this->store->GetEntry()]->GetEntryIndex());
this->dwnldSizes = this->entries[this->store->GetEntry()]->GetSizes();
}
}
this->fetchDown = false;
}
switch(this->storeMode) {
case 0:
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::EntryHandle(this->showMarks, this->fetchDown, this->screenshotFetch, this->storeMode, this->entries[this->store->GetEntry()]);
break;
case 1:
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DownloadHandle(this->store, this->entries[this->store->GetEntry()], this->dwnldList, this->storeMode, this->meta, this->lastMode, this->smallDelay);
break;
case 2:
StoreUtils::QueueMenuHandle(this->queueIndex);
break;
case 3:
StoreUtils::SearchHandle(this->store, this->entries, this->searchIncludes, this->meta, this->searchResult, this->marks, this->updateFilter, this->ascending, this->sorttype);
break;
case 4:
StoreUtils::SortHandle(this->store, this->entries, this->ascending, this->sorttype);
break;
case 5:
StoreUtils::SettingsHandle(this->sPage, this->showSettings, this->storeMode, this->sSelection, this->store, this->entries, this->meta, this->sPos);
break;
}
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "download.hpp"
#include "fileBrowse.hpp"
#include "mainScreen.hpp"
#include "screenshot.hpp"
#include "storeUtils.hpp"
#include <unistd.h>
extern int fadeAlpha;
extern EshopInfo GetInfo(const std::string &file, const std::string &fileName);
extern void notConnectedMsg();
extern void DisplayChangelog();
/*
MainScreen Constructor.
Initialized Meta, Store and StoreEntry class and:
- Downloads darkstore-homebrew.eshop.. in case nothing exist.
*/
MainScreen::MainScreen() {
this->meta = std::make_unique<Meta>();
/* Check if lastStore is accessible. */
if (config->lastStore() != "darkstore-homebrew.eshop" || config->lastStore() != "") {
if (access((std::string(_STORE_PATH) + config->lastStore()).c_str(), F_OK) != 0) {
config->lastStore("darkstore-homebrew.eshop");
} else {
/* check version and file here. */
const EshopInfo info = GetInfo((std::string(_STORE_PATH) + config->lastStore()), config->lastStore());
if (info.Version != 3 && info.Version != _ESHOP_VERSION) {
config->lastStore("darkstore-homebrew.eshop");
}
if (info.File != "") { // Ensure to check for this.
if ((info.File.find("/") != std::string::npos)) {
config->lastStore("darkstore-homebrew.eshop"); // It does contain a '/' which is invalid.
}
}
}
}
/* If darkstore-homebrew.eshop --> Get! */
if (config->lastStore() == "darkstore-homebrew.eshop" || config->lastStore() == "") {
if (access("sdmc:/3ds/DarkStore/stores/darkstore-homebrew.eshop", F_OK) != 0) {
if (checkWifiStatus()) {
std::string tmp = ""; // Juste une intérimaire.
DownloadEshop("https://darkstore.ml/assets/darkstore-homebrew.eshop", -1, tmp, true, true);
DownloadSpriteSheet("https://darkstore.ml/assets/icon.t3x", "icon.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_1.t3x", "icon_1.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_2.t3x", "icon_2.t3x");
} else {
notConnectedMsg();
}
} else {
const EshopInfo info = GetInfo("sdmc:/3ds/DarkStore/stores/darkstore-homebrew.eshop", "darkstore-homebrew.eshop");
if (info.Version != 3 && info.Version != _ESHOP_VERSION) {
Msg::waitMsg("Not passing the check!");
if (checkWifiStatus()) {
std::string tmp = ""; // Juste une intérimaire.
DownloadEshop("https://darkstore.ml/assets/darkstore-homebrew.eshop", -1, tmp, true, true);
DownloadSpriteSheet("https://darkstore.ml/assets/icon.t3x", "icon.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_1.t3x", "icon_1.t3x");
DownloadSpriteSheet("https://darkstore.ml/assets/icon_2.t3x", "icon_2.t3x");
} else {
notConnectedMsg();
}
}
}
}
this->store = std::make_unique<Store>(_STORE_PATH + config->lastStore(), config->lastStore());
StoreUtils::ResetAll(this->store, this->meta, this->entries);
StoreUtils::SortEntries(false, SortType::LAST_UPDATED, this->entries);
DisplayChangelog();
};
/*
MainScreen Main Draw.
*/
void MainScreen::Draw(void) const {
if (this->storeMode == 6) {
/* Screenshot Menu. */
StoreUtils::DrawScreenshotMenu(this->Screenshot, this->screenshotIndex, this->screenshotFetch, this->sSize, this->screenshotName, this->zoom, this->canDisplay);
return;
}
if (this->storeMode == 7) {
/* Release Notes. */
StoreUtils::DrawReleaseNotes(this->scrollIndex, this->entries[this->store->GetEntry()], this->store);
GFX::DrawBottom();
return;
}
Gui::ScreenDraw(Top);
Gui::Draw_Rect(0, 0, 400, 25, BAR_COLOR);
Gui::Draw_Rect(0, 25, 400, 1, BAR_OUTL_COLOR);
if (this->store && this->store->GetValid()) Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, this->store->GetEshopTitle(), 370, 0, font);
else Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, Lang::get("INVALID_ESHOP"), 370, 0, font);
config->list() ? StoreUtils::DrawList(this->store, this->entries) : StoreUtils::DrawGrid(this->store, this->entries);
/* Download-ception. */
if (this->storeMode == 1) {
StoreUtils::DrawDownList(this->store, this->dwnldList, this->fetchDown, this->entries[this->store->GetEntry()], this->dwnldSizes);
} else {
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(0, 0, 0, fadeAlpha));
GFX::DrawBottom();
switch(this->storeMode) {
case 0:
/* Entry Info. */
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DrawEntryInfo(this->store, this->entries[this->store->GetEntry()]);
break;
case 2:
StoreUtils::DrawQueueMenu(this->queueIndex);
break;
case 3:
/* Search + Favorites. */
StoreUtils::DrawSearchMenu(this->searchIncludes, this->searchResult, this->marks, this->updateFilter);
break;
case 4:
/* Sorting. */
StoreUtils::DrawSorting(this->ascending, this->sorttype);
break;
case 5:
/* Settings. */
StoreUtils::DrawSettings(this->sPage, this->sSelection, this->sPos);
break;
}
}
StoreUtils::DrawSideMenu(this->storeMode);
if (this->showMarks && this->store && this->store->GetValid()) StoreUtils::DisplayMarkBox(this->entries[this->store->GetEntry()]->GetMarks());
if (fadeAlpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, fadeAlpha));
}
/*
MainScreen Logic.
*/
void MainScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
/* Screenshots Menu. */
if (this->storeMode == 6) {
if (this->screenshotFetch) {
/* Delete Texture first. */
if (this->Screenshot.tex) {
C3D_TexDelete(this->Screenshot.tex);
this->Screenshot.tex = nullptr;
this->Screenshot.subtex = nullptr;
}
this->screenshotName = "";
if (this->screenshotIndex < (int)this->entries[this->store->GetEntry()]->GetScreenshotNames().size()) {
this->screenshotName = this->entries[this->store->GetEntry()]->GetScreenshotNames()[this->screenshotIndex];
}
this->sSize = 0;
this->sSize = this->entries[this->store->GetEntry()]->GetScreenshots().size();
if (this->screenshotIndex < this->sSize) {
if (this->sSize > 0) {
this->Screenshot = FetchScreenshot(this->entries[this->store->GetEntry()]->GetScreenshots()[this->screenshotIndex]);
if (this->Screenshot.tex) this->canDisplay = true;
else this->canDisplay = false;
}
}
this->screenshotFetch = false;
}
StoreUtils::ScreenshotMenu(this->Screenshot, this->screenshotIndex, this->screenshotFetch, this->storeMode, this->sSize, this->zoom, this->canDisplay);
return;
}
/* Release Notes. */
if (this->storeMode == 7) {
StoreUtils::ReleaseNotesLogic(this->scrollIndex, this->storeMode);
return;
}
/* Mark Menu. */
if (this->showMarks) StoreUtils::MarkHandle(this->entries[this->store->GetEntry()], this->store, this->showMarks, this->meta);
if (!this->showMarks) {
if (this->storeMode == 0 || this->storeMode == 3 || this->storeMode == 4) {
config->list() ? StoreUtils::ListLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay) : StoreUtils::GridLogic(this->store, this->entries, this->storeMode, this->lastMode, this->fetchDown, this->smallDelay);
}
StoreUtils::SideMenuHandle(this->storeMode, this->fetchDown, this->lastMode);
/* Fetch Download list. */
if (this->fetchDown) {
this->dwnldList.clear();
this->dwnldSizes.clear();
if (this->store && this->store->GetValid()) {
this->store->SetDownloadIndex(0); // Reset to 0.
this->store->SetDownloadSIndex(0);
if ((int)this->entries.size() > this->store->GetEntry()) {
this->dwnldList = this->store->GetDownloadList(this->entries[this->store->GetEntry()]->GetEntryIndex());
this->dwnldSizes = this->entries[this->store->GetEntry()]->GetSizes();
}
}
this->fetchDown = false;
}
switch(this->storeMode) {
case 0:
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::EntryHandle(this->showMarks, this->fetchDown, this->screenshotFetch, this->storeMode, this->entries[this->store->GetEntry()]);
break;
case 1:
if (this->store && this->store->GetValid() && this->entries.size() > 0) StoreUtils::DownloadHandle(this->store, this->entries[this->store->GetEntry()], this->dwnldList, this->storeMode, this->meta, this->lastMode, this->smallDelay);
break;
case 2:
StoreUtils::QueueMenuHandle(this->queueIndex);
break;
case 3:
StoreUtils::SearchHandle(this->store, this->entries, this->searchIncludes, this->meta, this->searchResult, this->marks, this->updateFilter, this->ascending, this->sorttype);
break;
case 4:
StoreUtils::SortHandle(this->store, this->entries, this->ascending, this->sorttype);
break;
case 5:
StoreUtils::SettingsHandle(this->sPage, this->showSettings, this->storeMode, this->sSelection, this->store, this->entries, this->meta, this->sPos);
break;
}
}
}
+567 -567
View File
File diff suppressed because it is too large Load Diff
+69 -69
View File
@@ -1,70 +1,70 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeEntry.hpp"
/*
Chercher des informations sur le constructeur.
const std::unique_ptrStore> &store : Const Référence à la classe Store.
const std::unique_ptrMeta> &meta : Const Référence à la classe Meta.
int index : Index de lentrée.
*/
StoreEntry::StoreEntry(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, int index) {
this->Title = store->GetTitleEntry(index);
this->Author = store->GetAuthorEntry(index);
this->Description = store->GetDescriptionEntry(index);
this->Category = StringUtils::FetchStringsFromVector(store->GetCategoryIndex(index));
this->Version = store->GetVersionEntry(index);
this->Console = StringUtils::FetchStringsFromVector(store->GetConsoleEntry(index));
this->LastUpdated = store->GetLastUpdatedEntry(index);
this->Size = store->GetSizeEntry(index);
this->Additional = store->GetAdditionalcontentEntry(index);
this->MarkString = StringUtils::GetMarkString(meta->GetMarks(store->GetEshopTitle(), this->Title));
this->Icon = store->GetIconEntry(index);
this->SheetIndex = 0;
this->EntryIndex = index;
this->FullCategory = store->GetCategoryIndex(index);
this->FullConsole = store->GetConsoleEntry(index);
this->UpdateAvailable = meta->UpdateAvailable(store->GetEshopTitle(), this->Title, store->GetLastUpdatedEntry(index));
this->Marks = meta->GetMarks(store->GetEshopTitle(), this->Title);
const std::vector<std::string> entries = store->GetDownloadList(index);
if (!entries.empty()) {
for (int i = 0; i < (int)entries.size(); i++) {
this->Sizes.push_back( store->GetFileSizes(index, entries[i]) );
}
}
this->Screenshots = store->GetScreenshotList(index);
this->ScreenshotNames = store->GetScreenshotNames(index);
this->ReleaseNotes = store->GetReleaseNotes(index);
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeEntry.hpp"
/*
Chercher des informations sur le constructeur.
const std::unique_ptrStore> &store : Const Référence à la classe Store.
const std::unique_ptrMeta> &meta : Const Référence à la classe Meta.
int index : Index de lentrée.
*/
StoreEntry::StoreEntry(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, int index) {
this->Title = store->GetTitleEntry(index);
this->Author = store->GetAuthorEntry(index);
this->Description = store->GetDescriptionEntry(index);
this->Category = StringUtils::FetchStringsFromVector(store->GetCategoryIndex(index));
this->Version = store->GetVersionEntry(index);
this->Console = StringUtils::FetchStringsFromVector(store->GetConsoleEntry(index));
this->LastUpdated = store->GetLastUpdatedEntry(index);
this->Size = store->GetSizeEntry(index);
this->Additional = store->GetAdditionalcontentEntry(index);
this->MarkString = StringUtils::GetMarkString(meta->GetMarks(store->GetEshopTitle(), this->Title));
this->Icon = store->GetIconEntry(index);
this->SheetIndex = 0;
this->EntryIndex = index;
this->FullCategory = store->GetCategoryIndex(index);
this->FullConsole = store->GetConsoleEntry(index);
this->UpdateAvailable = meta->UpdateAvailable(store->GetEshopTitle(), this->Title, store->GetLastUpdatedEntry(index));
this->Marks = meta->GetMarks(store->GetEshopTitle(), this->Title);
const std::vector<std::string> entries = store->GetDownloadList(index);
if (!entries.empty()) {
for (int i = 0; i < (int)entries.size(); i++) {
this->Sizes.push_back( store->GetFileSizes(index, entries[i]) );
}
}
this->Screenshots = store->GetScreenshotList(index);
this->ScreenshotNames = store->GetScreenshotNames(index);
this->ReleaseNotes = store->GetReleaseNotes(index);
}
+169 -169
View File
@@ -1,170 +1,170 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
/*
Comparez le titre.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareTitleDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetTitle()).c_str(), StringUtils::lower_case(b->GetTitle()).c_str()) > 0;
return true;
}
bool StoreUtils::compareTitleAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetTitle()).c_str(), StringUtils::lower_case(a->GetTitle()).c_str()) > 0;
return true;
}
/*
Comparer lauteur.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareAuthorDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetAuthor()).c_str(), StringUtils::lower_case(b->GetAuthor()).c_str()) > 0;
return true;
}
bool StoreUtils::compareAuthorAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetAuthor()).c_str(), StringUtils::lower_case(a->GetAuthor()).c_str()) > 0;
return true;
}
/*
Comparer la dernière mise à jour.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareUpdateDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetLastUpdated()).c_str(), StringUtils::lower_case(b->GetLastUpdated()).c_str()) > 0;
return true;
}
bool StoreUtils::compareUpdateAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetLastUpdated()).c_str(), StringUtils::lower_case(a->GetLastUpdated()).c_str()) > 0;
return true;
}
/*
Triez les entrées.
bool Ascending : Si Ascending.
SortType sorttype : Le type de tri.
std::vector<std::unique_ptr<StoreEntry>> &entries : référence aux entrées, qui doivent être triées.
*/
void StoreUtils::SortEntries(bool Ascending, SortType sorttype, std::vector<std::unique_ptr<StoreEntry>> &entries) {
switch(sorttype) {
case SortType::TITLE:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleDescending);
break;
case SortType::AUTHOR:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorDescending);
break;
case SortType::LAST_UPDATED:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateDescending);
break;
}
}
/*
Trouvez une requête à partir dun vecteur.
const std::vector<std::string> &items : Const Référence aux chaînes/éléments vectoriels.
const std::string &query : Const Référence à la requête.
*/
static bool findInVector(const std::vector<std::string> &items, const std::string &query) {
for(const std::string &item : items) {
if (StringUtils::lower_case(item).find(query) != std::string::npos) return true;
}
return false;
}
/*
Cherche des trucs du magasin.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
const std::string &query : Const Référence à la requête.
bool title : si les titres doivent être inclus.
bool author : si les auteurs doivent être inclus.
catégorie bool : si les catégories doivent être incluses.
console bool : si les consoles doivent être incluses.
int selectedMarks : Les options de marque sélectionnées.
bool updateAvl : si les mises à jour disponibles doivent être un drapeau inclus
*/
void StoreUtils::search(std::vector<std::unique_ptr<StoreEntry>> &entries, const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl) {
for (auto it = entries.begin(); it != entries.end(); ++it) {
if (!(((title && StringUtils::lower_case((*it)->GetTitle()).find(StringUtils::lower_case(query)) != std::string::npos)
|| (author && StringUtils::lower_case((*it)->GetAuthor()).find(StringUtils::lower_case(query)) != std::string::npos)
|| (category && findInVector((*it)->GetCategoryFull(), StringUtils::lower_case(query)))
|| (console && findInVector((*it)->GetConsoleFull(), StringUtils::lower_case(query)))
|| (!title && !author && !category && !console))
&& ((selectedMarks == 0 && !updateAvl) || (*it)->GetMarks() & selectedMarks || (updateAvl && (*it)->GetUpdateAvl())))) {
entries.erase(it);
--it;
}
}
}
/*
Filtrer les mises à jour disponibles.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
*/
void StoreUtils::FilterUpdateAvailable(std::vector<std::unique_ptr<StoreEntry>> &entries) {
for (auto it = entries.begin(); it != entries.end(); ++it) {
if (!((*it)->GetUpdateAvl())) {
entries.erase(it);
--it;
}
}
}
/*
Réinitialiser tout le magasin et effacer + récupérer les entrées à nouveau.
const std::unique_ptrStore> &store : Const Référence à la classe Store.
const std::unique_ptrMeta> &meta : Const Référence à la classe Meta.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
*/
void StoreUtils::ResetAll(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) {
entries.clear();
if (store->GetValid()) {
for (int i = 0; i < store->GetStoreSize(); i++) {
entries.push_back( std::make_unique<StoreEntry>(store, meta, i) );
}
store->SetBox(0);
store->SetEntry(0);
store->SetScreenIndx(0);
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "storeUtils.hpp"
/*
Comparez le titre.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareTitleDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetTitle()).c_str(), StringUtils::lower_case(b->GetTitle()).c_str()) > 0;
return true;
}
bool StoreUtils::compareTitleAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetTitle()).c_str(), StringUtils::lower_case(a->GetTitle()).c_str()) > 0;
return true;
}
/*
Comparer lauteur.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareAuthorDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetAuthor()).c_str(), StringUtils::lower_case(b->GetAuthor()).c_str()) > 0;
return true;
}
bool StoreUtils::compareAuthorAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetAuthor()).c_str(), StringUtils::lower_case(a->GetAuthor()).c_str()) > 0;
return true;
}
/*
Comparer la dernière mise à jour.
const std::unique_ptr<StoreEntry> &a : Const Référence à lentrée A.
const std::unique_ptr<StoreEntry> &b : Const Référence à lentrée B.
*/
bool StoreUtils::compareUpdateDescending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(a->GetLastUpdated()).c_str(), StringUtils::lower_case(b->GetLastUpdated()).c_str()) > 0;
return true;
}
bool StoreUtils::compareUpdateAscending(const std::unique_ptr<StoreEntry> &a, const std::unique_ptr<StoreEntry> &b) {
if (a && b) return strcasecmp(StringUtils::lower_case(b->GetLastUpdated()).c_str(), StringUtils::lower_case(a->GetLastUpdated()).c_str()) > 0;
return true;
}
/*
Triez les entrées.
bool Ascending : Si Ascending.
SortType sorttype : Le type de tri.
std::vector<std::unique_ptr<StoreEntry>> &entries : référence aux entrées, qui doivent être triées.
*/
void StoreUtils::SortEntries(bool Ascending, SortType sorttype, std::vector<std::unique_ptr<StoreEntry>> &entries) {
switch(sorttype) {
case SortType::TITLE:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareTitleDescending);
break;
case SortType::AUTHOR:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareAuthorDescending);
break;
case SortType::LAST_UPDATED:
Ascending ? std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateAscending) : std::sort(entries.begin(), entries.end(), StoreUtils::compareUpdateDescending);
break;
}
}
/*
Trouvez une requête à partir dun vecteur.
const std::vector<std::string> &items : Const Référence aux chaînes/éléments vectoriels.
const std::string &query : Const Référence à la requête.
*/
static bool findInVector(const std::vector<std::string> &items, const std::string &query) {
for(const std::string &item : items) {
if (StringUtils::lower_case(item).find(query) != std::string::npos) return true;
}
return false;
}
/*
Cherche des trucs du magasin.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
const std::string &query : Const Référence à la requête.
bool title : si les titres doivent être inclus.
bool author : si les auteurs doivent être inclus.
catégorie bool : si les catégories doivent être incluses.
console bool : si les consoles doivent être incluses.
int selectedMarks : Les options de marque sélectionnées.
bool updateAvl : si les mises à jour disponibles doivent être un drapeau inclus
*/
void StoreUtils::search(std::vector<std::unique_ptr<StoreEntry>> &entries, const std::string &query, bool title, bool author, bool category, bool console, int selectedMarks, bool updateAvl) {
for (auto it = entries.begin(); it != entries.end(); ++it) {
if (!(((title && StringUtils::lower_case((*it)->GetTitle()).find(StringUtils::lower_case(query)) != std::string::npos)
|| (author && StringUtils::lower_case((*it)->GetAuthor()).find(StringUtils::lower_case(query)) != std::string::npos)
|| (category && findInVector((*it)->GetCategoryFull(), StringUtils::lower_case(query)))
|| (console && findInVector((*it)->GetConsoleFull(), StringUtils::lower_case(query)))
|| (!title && !author && !category && !console))
&& ((selectedMarks == 0 && !updateAvl) || (*it)->GetMarks() & selectedMarks || (updateAvl && (*it)->GetUpdateAvl())))) {
entries.erase(it);
--it;
}
}
}
/*
Filtrer les mises à jour disponibles.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
*/
void StoreUtils::FilterUpdateAvailable(std::vector<std::unique_ptr<StoreEntry>> &entries) {
for (auto it = entries.begin(); it != entries.end(); ++it) {
if (!((*it)->GetUpdateAvl())) {
entries.erase(it);
--it;
}
}
}
/*
Réinitialiser tout le magasin et effacer + récupérer les entrées à nouveau.
const std::unique_ptrStore> &store : Const Référence à la classe Store.
const std::unique_ptrMeta> &meta : Const Référence à la classe Meta.
std::vectorstd::unique_ptrStoreEntry>> &entries : Référence aux entrées.
*/
void StoreUtils::ResetAll(const std::unique_ptr<Store> &store, const std::unique_ptr<Meta> &meta, std::vector<std::unique_ptr<StoreEntry>> &entries) {
if (store) {
entries.clear();
if (store->GetValid()) {
for (int i = 0; i < store->GetStoreSize(); i++) {
entries.push_back( std::make_unique<StoreEntry>(store, meta, i) );
}
store->SetBox(0);
store->SetEntry(0);
store->SetScreenIndx(0);
}
}
}
+141 -141
View File
@@ -1,142 +1,142 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "animation.hpp"
#include "common.hpp"
#include "stringutils.hpp"
#include <curl/curl.h>
extern int filesExtracted, extractFilesCount;
extern std::string extractingFile;
char progressBarMsg[128] = "";
bool showProgressBar = false;
ProgressBar progressbarType = ProgressBar::Downloading;
extern u32 extractSize, writeOffset;
extern u32 installSize, installOffset;
extern u32 copyOffset, copySize;
extern curl_off_t downloadTotal;
extern curl_off_t downloadNow;
/*
Dessinez la barre de progression.
u64 current Progress : Le progrès actuel.
u64 totalProgrès : Le progrès total.
*/
void Animation::DrawProgressBar(u64 currentProgress, u64 totalProgress) {
Gui::Draw_Rect(30, 120, 340, 30, PROGRESSBAR_OUT_COLOR);
Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, PROGRESSBAR_IN_COLOR);
}
/*
Afficher la barre de progression.
*/
void Animation::displayProgressBar() {
char str[256];
while(showProgressBar) {
switch(progressbarType) {
case ProgressBar::Downloading:
if (downloadTotal < 1.0f) downloadTotal = 1.0f;
if (downloadTotal < downloadNow) downloadTotal = downloadNow;
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(downloadNow).c_str(),
StringUtils::formatBytes(downloadTotal).c_str(),
((float)downloadNow/(float)downloadTotal) * 100.0f);
break;
case ProgressBar::Extracting:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(writeOffset).c_str(),
StringUtils::formatBytes(extractSize).c_str(),
((float)writeOffset/(float)extractSize) * 100.0f);
break;
case ProgressBar::Installing:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(installOffset).c_str(),
StringUtils::formatBytes(installSize).c_str(),
((float)installOffset/(float)installSize) * 100.0f);
break;
case ProgressBar::Copying:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(copyOffset).c_str(),
StringUtils::formatBytes(copySize).c_str(),
((float)copyOffset/(float)copySize) * 100.0f);
break;
}
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, progressBarMsg, 390, 0, font);
switch(progressbarType) {
case ProgressBar::Downloading:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(downloadNow, downloadTotal);
break;
case ProgressBar::Extracting:
Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 390, 0, font);
Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 390, 0, font);
Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING"), 390, 0, font);
Gui::DrawStringCentered(0, 70, 0.6f, TEXT_COLOR, extractingFile, 390, 0, font);
Animation::DrawProgressBar(writeOffset, extractSize);
break;
case ProgressBar::Installing:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(installOffset, installSize);
break;
case ProgressBar::Copying:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(copyOffset, copySize);
break;
}
GFX::DrawBottom();
C3D_FrameEnd(0);
}
}
static int frame = 0; // 0 - 7.
static int advanceFrame = 0; // Only animate every 4 frames.
extern bool QueueRuns;
void Animation::DrawQueue(int x, int y) { GFX::DrawSprite(sprites_queue0_idx + frame, x, y); };
void Animation::QueueAnimHandle() {
if (QueueRuns) {
advanceFrame = (advanceFrame + 1) % 4;
if (advanceFrame == 0) frame = (frame + 1) % 8;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "animation.hpp"
#include "common.hpp"
#include "stringutils.hpp"
#include <curl/curl.h>
extern int filesExtracted, extractFilesCount;
extern std::string extractingFile;
char progressBarMsg[128] = "";
bool showProgressBar = false;
ProgressBar progressbarType = ProgressBar::Downloading;
extern u32 extractSize, writeOffset;
extern u32 installSize, installOffset;
extern u32 copyOffset, copySize;
extern curl_off_t downloadTotal;
extern curl_off_t downloadNow;
/*
Dessinez la barre de progression.
u64 current Progress : Le progrès actuel.
u64 totalProgrès : Le progrès total.
*/
void Animation::DrawProgressBar(u64 currentProgress, u64 totalProgress) {
Gui::Draw_Rect(30, 120, 340, 30, PROGRESSBAR_OUT_COLOR);
Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, PROGRESSBAR_IN_COLOR);
}
/*
Afficher la barre de progression.
*/
void Animation::displayProgressBar() {
char str[256];
while(showProgressBar) {
switch(progressbarType) {
case ProgressBar::Downloading:
if (downloadTotal < 1.0f) downloadTotal = 1.0f;
if (downloadTotal < downloadNow) downloadTotal = downloadNow;
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(downloadNow).c_str(),
StringUtils::formatBytes(downloadTotal).c_str(),
((float)downloadNow/(float)downloadTotal) * 100.0f);
break;
case ProgressBar::Extracting:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(writeOffset).c_str(),
StringUtils::formatBytes(extractSize).c_str(),
((float)writeOffset/(float)extractSize) * 100.0f);
break;
case ProgressBar::Installing:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(installOffset).c_str(),
StringUtils::formatBytes(installSize).c_str(),
((float)installOffset/(float)installSize) * 100.0f);
break;
case ProgressBar::Copying:
snprintf(str, sizeof(str), "%s / %s (%.2f%%)",
StringUtils::formatBytes(copyOffset).c_str(),
StringUtils::formatBytes(copySize).c_str(),
((float)copyOffset/(float)copySize) * 100.0f);
break;
}
Gui::clearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(Top, TRANSPARENT);
C2D_TargetClear(Bottom, TRANSPARENT);
GFX::DrawTop();
Gui::DrawStringCentered(0, 1, 0.7f, TEXT_COLOR, progressBarMsg, 390, 0, font);
switch(progressbarType) {
case ProgressBar::Downloading:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(downloadNow, downloadTotal);
break;
case ProgressBar::Extracting:
Gui::DrawStringCentered(0, 180, 0.6f, TEXT_COLOR, str, 390, 0, font);
Gui::DrawStringCentered(0, 100, 0.6f, TEXT_COLOR, std::to_string(filesExtracted) + " / " + std::to_string(extractFilesCount) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 390, 0, font);
Gui::DrawStringCentered(0, 40, 0.6f, TEXT_COLOR, Lang::get("CURRENTLY_EXTRACTING"), 390, 0, font);
Gui::DrawStringCentered(0, 70, 0.6f, TEXT_COLOR, extractingFile, 390, 0, font);
Animation::DrawProgressBar(writeOffset, extractSize);
break;
case ProgressBar::Installing:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(installOffset, installSize);
break;
case ProgressBar::Copying:
Gui::DrawStringCentered(0, 80, 0.6f, TEXT_COLOR, str, 390, 0, font);
Animation::DrawProgressBar(copyOffset, copySize);
break;
}
GFX::DrawBottom();
C3D_FrameEnd(0);
}
}
static int frame = 0; // 0 - 7.
static int advanceFrame = 0; // Only animate every 4 frames.
extern bool QueueRuns;
void Animation::DrawQueue(int x, int y) { GFX::DrawSprite(sprites_queue0_idx + frame, x, y); };
void Animation::QueueAnimHandle() {
if (QueueRuns) {
advanceFrame = (advanceFrame + 1) % 4;
if (advanceFrame == 0) frame = (frame + 1) % 8;
}
}
+81 -81
View File
@@ -1,82 +1,82 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "argumentParser.hpp"
#include "common.hpp"
#include "scriptUtils.hpp"
#include <unistd.h>
/*
Le constructeur de lanalyseur darguments.
const std::string &file : Const Référence au fichier.
const std::string &entry : Const Référence au nom du titre de lentrée.
int dlIndex : Lindex de téléchargement.
*/
ArgumentParser::ArgumentParser(const std::string &file, const std::string &entry, int dlIndex) {
if (dlIndex != -1 && file != "") {
this->file = file;
this->entry = entry;
this->dlIndex = dlIndex;
this->Load();
}
}
/*
Préparez eShop et obtenez un état valide.
*/
void ArgumentParser::Load() {
if (access((std::string(_STORE_PATH) + this->file).c_str(), F_OK) != 0) return;
this->store = std::make_unique<Store>(_STORE_PATH + this->file, this->file, true);
if (!this->store->GetValid()) return;
for (int i = 0; i < this->store->GetStoreSize(); i++) {
if (this->store->GetTitleEntry(i) == this->entry) {
this->entryIndex = i;
const std::vector<std::string> dlList = this->store->GetDownloadList(this->entryIndex);
if (dlList.empty()) return;
if ((int)dlList.size() >= this->dlIndex) {
this->executeEntry = dlList[this->dlIndex];
this->isValid = true;
return;
}
}
}
}
/*
Exécutez lentrée de largument, si elle est valide.
*/
void ArgumentParser::Execute() {
if (this->isValid) {
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + this->executeEntry)) {
ScriptUtils::runFunctions(this->store->GetJson(), this->entryIndex, this->executeEntry);
}
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "argumentParser.hpp"
#include "common.hpp"
#include "scriptUtils.hpp"
#include <unistd.h>
/*
Le constructeur de lanalyseur darguments.
const std::string &file : Const Référence au fichier.
const std::string &entry : Const Référence au nom du titre de lentrée.
int dlIndex : Lindex de téléchargement.
*/
ArgumentParser::ArgumentParser(const std::string &file, const std::string &entry, int dlIndex) {
if (dlIndex != -1 && file != "") {
this->file = file;
this->entry = entry;
this->dlIndex = dlIndex;
this->Load();
}
}
/*
Préparez eShop et obtenez un état valide.
*/
void ArgumentParser::Load() {
if (access((std::string(_STORE_PATH) + this->file).c_str(), F_OK) != 0) return;
this->store = std::make_unique<Store>(_STORE_PATH + this->file, this->file, true);
if (!this->store->GetValid()) return;
for (int i = 0; i < this->store->GetStoreSize(); i++) {
if (this->store->GetTitleEntry(i) == this->entry) {
this->entryIndex = i;
const std::vector<std::string> dlList = this->store->GetDownloadList(this->entryIndex);
if (dlList.empty()) return;
if ((int)dlList.size() >= this->dlIndex) {
this->executeEntry = dlList[this->dlIndex];
this->isValid = true;
return;
}
}
}
}
/*
Exécutez lentrée de largument, si elle est valide.
*/
void ArgumentParser::Execute() {
if (this->isValid) {
if (Msg::promptMsg(Lang::get("EXECUTE_ENTRY") + "\n\n" + this->executeEntry)) {
ScriptUtils::runFunctions(this->store->GetJson(), this->entryIndex, this->executeEntry);
}
}
}
+164 -164
View File
@@ -1,165 +1,165 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "cia.hpp"
#include "files.hpp"
Result Title::Launch(u64 titleId, FS_MediaType mediaType) {
Result ret = 0;
u8 param[0x300];
u8 hmac[0x20];
if (R_FAILED(ret = APT_PrepareToDoApplicationJump(0, titleId, mediaType))) {
printf("Error In:\nAPT_PrepareToDoApplicationJump");
return ret;
}
if (R_FAILED(ret = APT_DoApplicationJump(param, sizeof(param), hmac))) {
printf("Error In:\nAPT_DoApplicationJump");
return ret;
}
return 0;
}
Result Title::DeletePrevious(u64 titleid, FS_MediaType media) {
Result ret = 0;
u32 titles_amount = 0;
ret = AM_GetTitleCount(media, &titles_amount);
if (R_FAILED(ret)) {
printf("Error in:\nAM_GetTitleCount\n");
return ret;
}
u32 read_titles = 0;
u64 *titleIDs = (u64 *)malloc(titles_amount * sizeof(u64));
ret = AM_GetTitleList(&read_titles, media, titles_amount, titleIDs);
if (R_FAILED(ret)) {
free(titleIDs);
printf("Error in:\nAM_GetTitleList\n");
return ret;
}
for (u32 i = 0; i < read_titles; i++) {
if (titleIDs[i] == titleid) {
ret = AM_DeleteAppTitle(media, titleid);
break;
}
}
free(titleIDs);
if (R_FAILED(ret)) {
printf("Error in:\nAM_DeleteAppTitle\n");
return ret;
}
return 0;
}
static FS_MediaType getTitleDestination(u64 titleId) {
u16 platform = (u16) ((titleId >> 48) & 0xFFFF);
u16 category = (u16) ((titleId >> 32) & 0xFFFF);
u8 variation = (u8) (titleId & 0xFF);
// DSiWare 3DS DSiWare, System, DLP Application Titre Système
return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD;
}
u32 installSize = 0, installOffset = 0;
Result Title::Install(const char *ciaPath, bool updatingSelf) {
u32 bytes_read = 0, bytes_written;
installSize = 0, installOffset = 0; u64 size = 0;
Handle ciaHandle, fileHandle;
AM_TitleEntry info;
Result ret = 0;
FS_MediaType media = MEDIATYPE_SD;
ret = openFile(&fileHandle, ciaPath, false);
if (R_FAILED(ret)) {
printf("Error in:\nopenFile\n");
return ret;
}
ret = AM_GetCiaFileInfo(media, &info, fileHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_GetCiaFileInfo\n");
return ret;
}
media = getTitleDestination(info.titleID);
if (!updatingSelf) {
ret = Title::DeletePrevious(info.titleID, media);
if (R_FAILED(ret)) return ret;
}
ret = FSFILE_GetSize(fileHandle, &size);
if (R_FAILED(ret)) {
printf("Error in:\nFSFILE_GetSize\n");
return ret;
}
ret = AM_StartCiaInstall(media, &ciaHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_StartCiaInstall\n");
return ret;
}
u32 toRead = 0x200000;
u8 *buf = new u8[toRead];
if (!buf) return -1;
installSize = size;
do {
FSFILE_Read(fileHandle, &bytes_read, installOffset, buf, toRead);
FSFILE_Write(ciaHandle, &bytes_written, installOffset, buf, toRead, FS_WRITE_FLUSH);
installOffset += bytes_read;
} while(installOffset < installSize);
delete[] buf;
ret = AM_FinishCiaInstall(ciaHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_FinishCiaInstall\n");
return ret;
}
ret = FSFILE_Close(fileHandle);
if (R_FAILED(ret)) {
printf("Error in:\nFSFILE_Close\n");
return ret;
}
if (updatingSelf) {
if (R_FAILED(ret = Title::Launch(info.titleID, MEDIATYPE_SD))) return ret;
}
return 0;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "cia.hpp"
#include "files.hpp"
Result Title::Launch(u64 titleId, FS_MediaType mediaType) {
Result ret = 0;
u8 param[0x300];
u8 hmac[0x20];
if (R_FAILED(ret = APT_PrepareToDoApplicationJump(0, titleId, mediaType))) {
printf("Error In:\nAPT_PrepareToDoApplicationJump");
return ret;
}
if (R_FAILED(ret = APT_DoApplicationJump(param, sizeof(param), hmac))) {
printf("Error In:\nAPT_DoApplicationJump");
return ret;
}
return 0;
}
Result Title::DeletePrevious(u64 titleid, FS_MediaType media) {
Result ret = 0;
u32 titles_amount = 0;
ret = AM_GetTitleCount(media, &titles_amount);
if (R_FAILED(ret)) {
printf("Error in:\nAM_GetTitleCount\n");
return ret;
}
u32 read_titles = 0;
u64 *titleIDs = (u64 *)malloc(titles_amount * sizeof(u64));
ret = AM_GetTitleList(&read_titles, media, titles_amount, titleIDs);
if (R_FAILED(ret)) {
free(titleIDs);
printf("Error in:\nAM_GetTitleList\n");
return ret;
}
for (u32 i = 0; i < read_titles; i++) {
if (titleIDs[i] == titleid) {
ret = AM_DeleteAppTitle(media, titleid);
break;
}
}
free(titleIDs);
if (R_FAILED(ret)) {
printf("Error in:\nAM_DeleteAppTitle\n");
return ret;
}
return 0;
}
static FS_MediaType getTitleDestination(u64 titleId) {
u16 platform = (u16) ((titleId >> 48) & 0xFFFF);
u16 category = (u16) ((titleId >> 32) & 0xFFFF);
u8 variation = (u8) (titleId & 0xFF);
// DSiWare 3DS DSiWare, System, DLP Application Titre Système
return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD;
}
u32 installSize = 0, installOffset = 0;
Result Title::Install(const char *ciaPath, bool updatingSelf) {
u32 bytes_read = 0, bytes_written;
installSize = 0, installOffset = 0; u64 size = 0;
Handle ciaHandle, fileHandle;
AM_TitleEntry info;
Result ret = 0;
FS_MediaType media = MEDIATYPE_SD;
ret = openFile(&fileHandle, ciaPath, false);
if (R_FAILED(ret)) {
printf("Error in:\nopenFile\n");
return ret;
}
ret = AM_GetCiaFileInfo(media, &info, fileHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_GetCiaFileInfo\n");
return ret;
}
media = getTitleDestination(info.titleID);
if (!updatingSelf) {
ret = Title::DeletePrevious(info.titleID, media);
if (R_FAILED(ret)) return ret;
}
ret = FSFILE_GetSize(fileHandle, &size);
if (R_FAILED(ret)) {
printf("Error in:\nFSFILE_GetSize\n");
return ret;
}
ret = AM_StartCiaInstall(media, &ciaHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_StartCiaInstall\n");
return ret;
}
u32 toRead = 0x200000;
u8 *buf = new u8[toRead];
if (!buf) return -1;
installSize = size;
do {
FSFILE_Read(fileHandle, &bytes_read, installOffset, buf, toRead);
FSFILE_Write(ciaHandle, &bytes_written, installOffset, buf, toRead, FS_WRITE_FLUSH);
installOffset += bytes_read;
} while(installOffset < installSize);
delete[] buf;
ret = AM_FinishCiaInstall(ciaHandle);
if (R_FAILED(ret)) {
printf("Error in:\nAM_FinishCiaInstall\n");
return ret;
}
ret = FSFILE_Close(fileHandle);
if (R_FAILED(ret)) {
printf("Error in:\nFSFILE_Close\n");
return ret;
}
if (updatingSelf) {
if (R_FAILED(ret = Title::Launch(info.titleID, MEDIATYPE_SD))) return ret;
}
return 0;
}
+183 -183
View File
@@ -1,183 +1,183 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "config.hpp"
#include "json.hpp"
#include <string>
#include <unistd.h>
/*
Détecte la langue du système et est utilisé plus tard pour définir la langue de lapplication à la langue du système.
*/
void Config::sysLang() {
u8 language = 1;
CFGU_GetSystemLanguage(&language);
switch(language) {
case 0:
this->language("jp"); // Japonais (日本人), traduit.
break;
case 1:
this->language("en"); // Anglais (English), traduit.
break;
case 2:
this->language("fr"); // Français (Français), traduit.
break;
case 3:
this->language("de"); // Allemand (Deutsche), traduit.
break;
case 4:
this->language("it"); // Italien (Italiano), traduit.
break;
case 5:
this->language("es"); // Espagnol (Español), traduit.
break;
case 6:
this->language("cn-SI"); // Chinois simplifié (简体中文), traduit.
break;
case 7:
this->language("kr"); // Coréen (한국어), traduit.
break;
case 8:
this->language("nl"); // Néerlandais (Nederlands), pas totalement traduit.
break;
case 9:
this->language("pt"); // Portugais (Português), pas totalement traduit.
break;
case 10:
this->language("ru"); // Russe (русский), pas totalement traduit.
break;
case 11:
this->language("cn-TR"); // chinois traditionnel (繁體中文), traduit.
break;
}
}
/*
Au cas ça nexiste pas.
*/
void Config::initialize() {
FILE *temp = fopen("sdmc:/3ds/DarkStore/Config.json", "w");
char tmp[2] = { '{', '}' };
fwrite(tmp, sizeof(tmp), 1, temp);
fclose(temp);
}
/*
Constructeur de la configuration.
*/
Config::Config() {
if (access("sdmc:/3ds/DarkStore/Config.json", F_OK) != 0) {
this->initialize();
}
FILE *file = fopen("sdmc:/3ds/DarkStore/Config.json", "r");
this->json = nlohmann::json::parse(file, nullptr, false);
fclose(file);
/* Créons-en une nouvelle. */
if (!this->json.contains("Version")) this->initialize();
if (!this->json.contains("Language")) this->sysLang();
else this->language(this->getString("Language"));
if (this->json.contains("LastStore")) this->lastStore(this->getString("LastStore"));
if (this->json.contains("List")) this->list(this->getBool("List"));
if (this->json.contains("AutoUpdate")) this->autoupdate(this->getBool("AutoUpdate"));
if (this->json.contains("_3DSX_Path")) this->_3dsxPath(this->getString("_3DSX_Path"));
if (this->json.contains("NDS_Path")) this->ndsPath(this->getString("NDS_Path"));
if (this->json.contains("Archive_Path")) this->archPath(this->getString("Archive_Path"));
if (this->json.contains("MetaData")) this->metadata(this->getBool("MetaData"));
if (this->json.contains("UpdateCheck")) this->updatecheck(this->getBool("UpdateCheck"));
if (this->json.contains("UseBG")) this->usebg(this->getBool("UseBG"));
if (this->json.contains("CustomFont")) this->customfont(this->getBool("CustomFont"));
if (this->json.contains("Shortcut_Path")) this->shortcut(this->getString("Shortcut_Path"));
if (this->json.contains("Display_Changelog")) this->changelog(this->getBool("Display_Changelog"));
this->changesMade = false; // Aucune modification na encore été apportée.
}
/* Ecrivez à config si changesMade. */
void Config::save() {
if (this->changesMade) {
FILE *file = fopen("sdmc:/3ds/DarkStore/Config.json", "w");
/* Valeurs Théoriques. */
this->setString("Language", this->language());
this->setInt("Version", 1);
this->setString("LastStore", this->lastStore());
this->setBool("List", this->list());
this->setBool("AutoUpdate", this->autoupdate());
this->setString("_3DSX_Path", this->_3dsxPath());
this->setString("NDS_Path", this->ndsPath());
this->setString("Archive_Path", this->archPath());
this->setBool("MetaData", this->metadata());
this->setBool("UpdateCheck", this->updatecheck());
this->setBool("UseBG", this->usebg());
this->setBool("CustomFont", this->customfont());
this->setString("Shortcut_Path", this->shortcut());
this->setBool("Display_Changelog", this->changelog());
/* Écrire les modifications au fichier. */
const std::string dump = this->json.dump(1, '\t');
fwrite(dump.c_str(), 1, this->json.dump(1, '\t').size(), file);
fclose(file);
}
}
/* Fonctions daide. */
bool Config::getBool(const std::string &key) {
if (!this->json.contains(key)) return false;
return this->json.at(key).get_ref<const bool &>();
}
void Config::setBool(const std::string &key, bool v) { this->json[key] = v; };
int Config::getInt(const std::string &key) {
if (!this->json.contains(key)) return 0;
return this->json.at(key).get_ref<const int64_t &>();
}
void Config::setInt(const std::string &key, int v) { this->json[key] = v; };
std::string Config::getString(const std::string &key) {
if (!this->json.contains(key)) return "";
return this->json.at(key).get_ref<const std::string &>();
}
void Config::setString(const std::string &key, const std::string &v) { this->json[key] = v; };
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "config.hpp"
#include "json.hpp"
#include <string>
#include <unistd.h>
/*
Détecte la langue du système et est utilisé plus tard pour définir la langue de lapplication à la langue du système.
*/
void Config::sysLang() {
u8 language = 1;
CFGU_GetSystemLanguage(&language);
switch(language) {
case 0:
this->language("jp"); // Japonais (日本人), traduit.
break;
case 1:
this->language("en"); // Anglais (English), traduit.
break;
case 2:
this->language("fr"); // Français (Français), traduit.
break;
case 3:
this->language("de"); // Allemand (Deutsche), traduit.
break;
case 4:
this->language("it"); // Italien (Italiano), traduit.
break;
case 5:
this->language("es"); // Espagnol (Español), traduit.
break;
case 6:
this->language("cn-SI"); // Chinois simplifié (简体中文), traduit.
break;
case 7:
this->language("kr"); // Coréen (한국어), traduit.
break;
case 8:
this->language("nl"); // Néerlandais (Nederlands), pas totalement traduit.
break;
case 9:
this->language("pt"); // Portugais (Português), pas totalement traduit.
break;
case 10:
this->language("ru"); // Russe (русский), pas totalement traduit.
break;
case 11:
this->language("cn-TR"); // chinois traditionnel (繁體中文), traduit.
break;
}
}
/*
Au cas ça nexiste pas.
*/
void Config::initialize() {
FILE *temp = fopen("sdmc:/3ds/DarkStore/Config.json", "w");
char tmp[2] = { '{', '}' };
fwrite(tmp, sizeof(tmp), 1, temp);
fclose(temp);
}
/*
Constructeur de la configuration.
*/
Config::Config() {
if (access("sdmc:/3ds/DarkStore/Config.json", F_OK) != 0) {
this->initialize();
}
FILE *file = fopen("sdmc:/3ds/DarkStore/Config.json", "r");
this->json = nlohmann::json::parse(file, nullptr, false);
fclose(file);
/* Créons-en une nouvelle. */
if (!this->json.contains("Version")) this->initialize();
if (!this->json.contains("Language")) this->sysLang();
else this->language(this->getString("Language"));
if (this->json.contains("LastStore")) this->lastStore(this->getString("LastStore"));
if (this->json.contains("List")) this->list(this->getBool("List"));
if (this->json.contains("AutoUpdate")) this->autoupdate(this->getBool("AutoUpdate"));
if (this->json.contains("_3DSX_Path")) this->_3dsxPath(this->getString("_3DSX_Path"));
if (this->json.contains("NDS_Path")) this->ndsPath(this->getString("NDS_Path"));
if (this->json.contains("Archive_Path")) this->archPath(this->getString("Archive_Path"));
if (this->json.contains("MetaData")) this->metadata(this->getBool("MetaData"));
if (this->json.contains("UpdateCheck")) this->updatecheck(this->getBool("UpdateCheck"));
if (this->json.contains("UseBG")) this->usebg(this->getBool("UseBG"));
if (this->json.contains("CustomFont")) this->customfont(this->getBool("CustomFont"));
if (this->json.contains("Shortcut_Path")) this->shortcut(this->getString("Shortcut_Path"));
if (this->json.contains("Display_Changelog")) this->changelog(this->getBool("Display_Changelog"));
this->changesMade = false; // Aucune modification na encore été apportée.
}
/* Ecrivez à config si changesMade. */
void Config::save() {
if (this->changesMade) {
FILE *file = fopen("sdmc:/3ds/DarkStore/Config.json", "w");
/* Valeurs Théoriques. */
this->setString("Language", this->language());
this->setInt("Version", 1);
this->setString("LastStore", this->lastStore());
this->setBool("List", this->list());
this->setBool("AutoUpdate", this->autoupdate());
this->setString("_3DSX_Path", this->_3dsxPath());
this->setString("NDS_Path", this->ndsPath());
this->setString("Archive_Path", this->archPath());
this->setBool("MetaData", this->metadata());
this->setBool("UpdateCheck", this->updatecheck());
this->setBool("UseBG", this->usebg());
this->setBool("CustomFont", this->customfont());
this->setString("Shortcut_Path", this->shortcut());
this->setBool("Display_Changelog", this->changelog());
/* Écrire les modifications au fichier. */
const std::string dump = this->json.dump(1, '\t');
fwrite(dump.c_str(), 1, this->json.dump(1, '\t').size(), file);
fclose(file);
}
}
/* Fonctions daide. */
bool Config::getBool(const std::string &key) {
if (!this->json.contains(key)) return false;
return this->json.at(key).get_ref<const bool &>();
}
void Config::setBool(const std::string &key, bool v) { this->json[key] = v; };
int Config::getInt(const std::string &key) {
if (!this->json.contains(key)) return 0;
return this->json.at(key).get_ref<const int64_t &>();
}
void Config::setInt(const std::string &key, int v) { this->json[key] = v; };
std::string Config::getString(const std::string &key) {
if (!this->json.contains(key)) return "";
return this->json.at(key).get_ref<const std::string &>();
}
void Config::setString(const std::string &key, const std::string &v) { this->json[key] = v; };
+1113 -1113
View File
File diff suppressed because it is too large Load Diff
+138 -138
View File
@@ -1,139 +1,139 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "extract.hpp"
#include "scriptUtils.hpp"
#include <archive.h>
#include <archive_entry.h>
#include <regex>
int filesExtracted = 0, extractFilesCount = 0;
std::string extractingFile = "";
/* Cest notre variable File Progressbar. */
u32 extractSize = 0, writeOffset = 0;
Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile) {
extractSize = 0, writeOffset = 0, filesExtracted = 0, extractFilesCount = 0;
archive *a = archive_read_new();
archive_entry *entry;
archive_read_support_format_all(a);
if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) return EXTRACT_ERROR_OPENFILE;
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
int size = archive_entry_size(entry);
if (size > 0) { /* Ignorer les dossiers. */
std::smatch match;
std::string entryName(archive_entry_pathname(entry));
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
extractSize += size;
extractFilesCount++;
}
}
}
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_NONE;
}
Result extractArchive(const std::string &archivePath, const std::string &wantedFile, const std::string &outputPath) {
archive *a = archive_read_new();
archive_entry *entry;
a = archive_read_new();
archive_read_support_format_all(a);
if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) {
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_OPENFILE;
}
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
if (archive_entry_size(entry) > 0) { /* Ignorer les dossiers.. */
std::smatch match;
std::string entryName(archive_entry_pathname(entry));
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
extractingFile = outputPath + match.suffix().str();
/* Faire les répertoires. */
for (char *slashpos = strchr(extractingFile.c_str() + 1, '/'); slashpos != NULL; slashpos = strchr(slashpos + 1, '/')) {
char bak = *(slashpos);
*(slashpos) = '\0';
mkdir(extractingFile.c_str(), 0777);
*(slashpos) = bak;
}
uint sizeLeft = archive_entry_size(entry);
FILE *file = fopen(extractingFile.c_str(), "wb");
if (!file) {
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_WRITEFILE;
}
u8 *buf = new u8[0x30000];
if (!buf) {
fclose(file);
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_ALLOC;
}
while(sizeLeft > 0) {
u64 toRead = std::min(0x30000u, sizeLeft);
ssize_t size = archive_read_data(a, buf, toRead);
// Archive error, stop extracting
if(size < 0) {
fclose(file);
delete[] buf;
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_ARCHIVE;
}
fwrite(buf, 1, size, file);
sizeLeft -= size;
writeOffset += size;
}
filesExtracted++;
fclose(file);
delete[] buf;
}
}
}
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_NONE;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "extract.hpp"
#include "scriptUtils.hpp"
#include <archive.h>
#include <archive_entry.h>
#include <regex>
int filesExtracted = 0, extractFilesCount = 0;
std::string extractingFile = "";
/* Cest notre variable File Progressbar. */
u32 extractSize = 0, writeOffset = 0;
Result getExtractedSize(const std::string &archivePath, const std::string &wantedFile) {
extractSize = 0, writeOffset = 0, filesExtracted = 0, extractFilesCount = 0;
archive *a = archive_read_new();
archive_entry *entry;
archive_read_support_format_all(a);
if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) return EXTRACT_ERROR_OPENFILE;
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
int size = archive_entry_size(entry);
if (size > 0) { /* Ignorer les dossiers. */
std::smatch match;
std::string entryName(archive_entry_pathname(entry));
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
extractSize += size;
extractFilesCount++;
}
}
}
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_NONE;
}
Result extractArchive(const std::string &archivePath, const std::string &wantedFile, const std::string &outputPath) {
archive *a = archive_read_new();
archive_entry *entry;
a = archive_read_new();
archive_read_support_format_all(a);
if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) {
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_OPENFILE;
}
while(archive_read_next_header(a, &entry) == ARCHIVE_OK) {
if (archive_entry_size(entry) > 0) { /* Ignorer les dossiers.. */
std::smatch match;
std::string entryName(archive_entry_pathname(entry));
if (std::regex_search(entryName, match, std::regex(wantedFile))) {
extractingFile = outputPath + match.suffix().str();
/* Faire les répertoires. */
for (char *slashpos = strchr(extractingFile.c_str() + 1, '/'); slashpos != NULL; slashpos = strchr(slashpos + 1, '/')) {
char bak = *(slashpos);
*(slashpos) = '\0';
mkdir(extractingFile.c_str(), 0777);
*(slashpos) = bak;
}
uint sizeLeft = archive_entry_size(entry);
FILE *file = fopen(extractingFile.c_str(), "wb");
if (!file) {
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_WRITEFILE;
}
u8 *buf = new u8[0x30000];
if (!buf) {
fclose(file);
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_ALLOC;
}
while(sizeLeft > 0) {
u64 toRead = std::min(0x30000u, sizeLeft);
ssize_t size = archive_read_data(a, buf, toRead);
// Archive error, stop extracting
if(size < 0) {
fclose(file);
delete[] buf;
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_ARCHIVE;
}
fwrite(buf, 1, size, file);
sizeLeft -= size;
writeOffset += size;
}
filesExtracted++;
fclose(file);
delete[] buf;
}
}
}
archive_read_close(a);
archive_read_free(a);
return EXTRACT_ERROR_NONE;
}
+283 -283
View File
@@ -1,284 +1,284 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "fileBrowse.hpp"
#include "json.hpp"
#include "structs.hpp"
#include <3ds.h>
#include <cstring>
#include <functional>
#include <unistd.h>
bool nameEndsWith(const std::string &name, const std::vector<std::string> &extensionList) {
if (name.substr(0, 2) == "._") return false;
if (name.size() == 0) return false;
if (extensionList.size() == 0) return true;
for(int i = 0; i < (int)extensionList.size(); i++) {
const std::string ext = extensionList.at(i);
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true;
}
return false;
}
bool dirEntryPredicate(const DirEntry &lhs, const DirEntry &rhs) {
if (!lhs.isDirectory && rhs.isDirectory) return false;
if (lhs.isDirectory && !rhs.isDirectory) return true;
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
}
void getDirectoryContents(std::vector<DirEntry> &dirContents, const std::vector<std::string> &extensionList) {
struct stat st;
dirContents.clear();
DIR *pdir = opendir(".");
if (pdir != nullptr) {
while(true) {
DirEntry dirEntry;
struct dirent *pent = readdir(pdir);
if (pent == NULL) break;
stat(pent->d_name, &st);
dirEntry.name = pent->d_name;
dirEntry.isDirectory = (st.st_mode & S_IFDIR) ? true : false;
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDirectory || nameEndsWith(dirEntry.name, extensionList))) {
dirContents.push_back(dirEntry);
}
}
closedir(pdir);
}
sort(dirContents.begin(), dirContents.end(), dirEntryPredicate);
}
void getDirectoryContents(std::vector<DirEntry> &dirContents) {
getDirectoryContents(dirContents, {});
}
std::vector<std::string> getContents(const std::string &name, const std::vector<std::string> &extensionList) {
std::vector<std::string> dirContents;
DIR *pdir = opendir(name.c_str());
struct dirent *pent;
while ((pent = readdir(pdir)) != NULL) {
if (nameEndsWith(pent->d_name, extensionList)) dirContents.push_back(pent->d_name);
}
closedir(pdir);
return dirContents;
}
/*
Retourner les informations eShop.
const std::string &file : Const Référence au chemin du fichier.
const std::string &fieName : Const Référence au nom de fichier, sans chemin.
*/
EshopInfo GetInfo(const std::string &file, const std::string &fileName) {
EshopInfo Temp = { "", "", "", "", fileName, "", -1, -1, -1 }; // Titre, Auteur, URL, Fichier (pour vérifier sil nexiste pas de barre oblique), FileName, Desc, Version, Révision, Entrées.
nlohmann::json JSON = nullptr;
FILE *temp = fopen(file.c_str(), "r");
JSON = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (!JSON.contains("storeInfo")) return Temp; // storeInfo n'existe pas.
if (JSON["storeInfo"].contains("title") && JSON["storeInfo"]["title"].is_string()) {
Temp.Title = JSON["storeInfo"]["title"];
}
if (JSON["storeInfo"].contains("file") && JSON["storeInfo"]["file"].is_string()) {
Temp.File = JSON["storeInfo"]["file"];
}
if (JSON["storeInfo"].contains("author") && JSON["storeInfo"]["author"].is_string()) {
Temp.Author = JSON["storeInfo"]["author"];
}
if (JSON["storeInfo"].contains("url") && JSON["storeInfo"]["url"].is_string()) {
Temp.URL = JSON["storeInfo"]["url"];
}
if (JSON["storeInfo"].contains("description") && JSON["storeInfo"]["description"].is_string()) {
Temp.Description = JSON["storeInfo"]["description"];
}
if (JSON["storeInfo"].contains("version") && JSON["storeInfo"]["version"].is_number()) {
Temp.Version = JSON["storeInfo"]["version"];
}
if (JSON["storeInfo"].contains("revision") && JSON["storeInfo"]["revision"].is_number()) {
Temp.Revision = JSON["storeInfo"]["revision"];
}
if (JSON.contains("storeContent")) Temp.StoreSize = JSON["storeContent"].size();
return Temp;
}
/*
Renvoie le vecteur dinformations eShop.
const std::string &path : Const Référence au chemin, vérifier.
*/
std::vector<EshopInfo> GetEshopInfo(const std::string &path) {
std::vector<EshopInfo> info;
std::vector<DirEntry> dirContents;
if (access(path.c_str(), F_OK) != 0) return {}; // Le dossier nexiste pas.
chdir(path.c_str());
getDirectoryContents(dirContents, { "eshop" });
for(uint i = 0; i < dirContents.size(); i++) {
/* Assurez-vous de SEULEMENT pousser .eshop, et pas de dossiers. Évite les plantages dans ce cas aussi. */
if ((path + dirContents[i].name).find(".eshop") != std::string::npos) {
info.push_back( GetInfo(path + dirContents[i].name, dirContents[i].name) );
}
}
return info;
}
#define copyBufSize 0x8000
u32 copyBuf[copyBufSize];
/*
Copiez un répertoire.
DirEntry *entry : pointeur vers un DirEntry.
const char *destinationPath : pointeur vers le chemin de destination.
const char *sourcePath : pointeur vers le chemin source.
*/
void dirCopy(DirEntry *entry, const char *destinationPath, const char *sourcePath) {
std::vector<DirEntry> dirContents;
dirContents.clear();
if (entry->isDirectory) chdir((sourcePath + ("/" + entry->name)).c_str());
getDirectoryContents(dirContents);
if (((int)dirContents.size()) == 1) mkdir((destinationPath + ("/" + entry->name)).c_str(), 0777);
if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry->name)).c_str(), (destinationPath + ("/" + entry->name)).c_str());
}
u32 copyOffset = 0, copySize = 0;
/*
Lopération de copie.
const char *destinationPath : pointeur vers le chemin de destination.
const char *sourcePath : pointeur vers le chemin source.
*/
int fcopy(const char *sourcePath, const char *destinationPath) {
copyOffset = 0, copySize = 0;
DIR *isDir = opendir(sourcePath);
if (isDir != NULL) {
closedir(isDir);
/* Le chemin source est un répertoire. */
chdir(sourcePath);
std::vector<DirEntry> dirContents;
getDirectoryContents(dirContents);
DirEntry *entry = &dirContents.at(1);
mkdir(destinationPath, 0777);
for(int i = 1; i < ((int)dirContents.size()); i++) {
chdir(sourcePath);
entry = &dirContents.at(i);
dirCopy(entry, destinationPath, sourcePath);
}
chdir(destinationPath);
chdir("..");
return 1;
} else {
closedir(isDir);
/* Le chemin source est un fichier. */
FILE *sourceFile = fopen(sourcePath, "rb");
copySize = 0, copyOffset = 0;
if (sourceFile) {
fseek(sourceFile, 0, SEEK_END);
copySize = ftell(sourceFile); // Obtenir la taille du fichier source.
fseek(sourceFile, 0, SEEK_SET);
} else {
fclose(sourceFile);
return -1;
}
FILE *destinationFile = fopen(destinationPath, "wb");
//if (destinationFile) {
fseek(destinationFile, 0, SEEK_SET);
/*} else {
fclose(sourceFile);
fclose(destinationFile);
return -1;
}*/
int numr;
while(1) {
scanKeys();
if (keysHeld() & KEY_B) {
/* Annuler la copie. */
fclose(sourceFile);
fclose(destinationFile);
return -1;
break;
}
printf("\x1b[16;0H");
printf("Progress:\n");
printf("%i/%i Bytes ", (int)copyOffset, (int)copySize);
/* Copier le fichier vers le chemin de destination. */
numr = fread(copyBuf, 2, copyBufSize, sourceFile);
fwrite(copyBuf, 2, numr, destinationFile);
copyOffset += copyBufSize;
if (copyOffset > copySize) {
fclose(sourceFile);
fclose(destinationFile);
printf("\x1b[17;0H");
printf("%i/%i Bytes ", (int)copyOffset, (int)copySize);
for(int i = 0; i < 30; i++) gspWaitForVBlank();
return 1;
break;
}
}
return -1;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "fileBrowse.hpp"
#include "json.hpp"
#include "structs.hpp"
#include <3ds.h>
#include <cstring>
#include <functional>
#include <unistd.h>
bool nameEndsWith(const std::string &name, const std::vector<std::string> &extensionList) {
if (name.substr(0, 2) == "._") return false;
if (name.size() == 0) return false;
if (extensionList.size() == 0) return true;
for(int i = 0; i < (int)extensionList.size(); i++) {
const std::string ext = extensionList.at(i);
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true;
}
return false;
}
bool dirEntryPredicate(const DirEntry &lhs, const DirEntry &rhs) {
if (!lhs.isDirectory && rhs.isDirectory) return false;
if (lhs.isDirectory && !rhs.isDirectory) return true;
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
}
void getDirectoryContents(std::vector<DirEntry> &dirContents, const std::vector<std::string> &extensionList) {
struct stat st;
dirContents.clear();
DIR *pdir = opendir(".");
if (pdir != nullptr) {
while(true) {
DirEntry dirEntry;
struct dirent *pent = readdir(pdir);
if (pent == NULL) break;
stat(pent->d_name, &st);
dirEntry.name = pent->d_name;
dirEntry.isDirectory = (st.st_mode & S_IFDIR) ? true : false;
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDirectory || nameEndsWith(dirEntry.name, extensionList))) {
dirContents.push_back(dirEntry);
}
}
closedir(pdir);
}
sort(dirContents.begin(), dirContents.end(), dirEntryPredicate);
}
void getDirectoryContents(std::vector<DirEntry> &dirContents) {
getDirectoryContents(dirContents, {});
}
std::vector<std::string> getContents(const std::string &name, const std::vector<std::string> &extensionList) {
std::vector<std::string> dirContents;
DIR *pdir = opendir(name.c_str());
struct dirent *pent;
while ((pent = readdir(pdir)) != NULL) {
if (nameEndsWith(pent->d_name, extensionList)) dirContents.push_back(pent->d_name);
}
closedir(pdir);
return dirContents;
}
/*
Retourner les informations eShop.
const std::string &file : Const Référence au chemin du fichier.
const std::string &fieName : Const Référence au nom de fichier, sans chemin.
*/
EshopInfo GetInfo(const std::string &file, const std::string &fileName) {
EshopInfo Temp = { "", "", "", "", fileName, "", -1, -1, -1 }; // Titre, Auteur, URL, Fichier (pour vérifier sil nexiste pas de barre oblique), FileName, Desc, Version, Révision, Entrées.
nlohmann::json JSON = nullptr;
FILE *temp = fopen(file.c_str(), "r");
JSON = nlohmann::json::parse(temp, nullptr, false);
fclose(temp);
if (!JSON.contains("storeInfo")) return Temp; // storeInfo n'existe pas.
if (JSON["storeInfo"].contains("title") && JSON["storeInfo"]["title"].is_string()) {
Temp.Title = JSON["storeInfo"]["title"];
}
if (JSON["storeInfo"].contains("file") && JSON["storeInfo"]["file"].is_string()) {
Temp.File = JSON["storeInfo"]["file"];
}
if (JSON["storeInfo"].contains("author") && JSON["storeInfo"]["author"].is_string()) {
Temp.Author = JSON["storeInfo"]["author"];
}
if (JSON["storeInfo"].contains("url") && JSON["storeInfo"]["url"].is_string()) {
Temp.URL = JSON["storeInfo"]["url"];
}
if (JSON["storeInfo"].contains("description") && JSON["storeInfo"]["description"].is_string()) {
Temp.Description = JSON["storeInfo"]["description"];
}
if (JSON["storeInfo"].contains("version") && JSON["storeInfo"]["version"].is_number()) {
Temp.Version = JSON["storeInfo"]["version"];
}
if (JSON["storeInfo"].contains("revision") && JSON["storeInfo"]["revision"].is_number()) {
Temp.Revision = JSON["storeInfo"]["revision"];
}
if (JSON.contains("storeContent")) Temp.StoreSize = JSON["storeContent"].size();
return Temp;
}
/*
Renvoie le vecteur dinformations eShop.
const std::string &path : Const Référence au chemin, vérifier.
*/
std::vector<EshopInfo> GetEshopInfo(const std::string &path) {
std::vector<EshopInfo> info;
std::vector<DirEntry> dirContents;
if (access(path.c_str(), F_OK) != 0) return {}; // Le dossier nexiste pas.
chdir(path.c_str());
getDirectoryContents(dirContents, { "eshop" });
for(uint i = 0; i < dirContents.size(); i++) {
/* Assurez-vous de SEULEMENT pousser .eshop, et pas de dossiers. Évite les plantages dans ce cas aussi. */
if ((path + dirContents[i].name).find(".eshop") != std::string::npos) {
info.push_back( GetInfo(path + dirContents[i].name, dirContents[i].name) );
}
}
return info;
}
#define copyBufSize 0x8000
u32 copyBuf[copyBufSize];
/*
Copiez un répertoire.
DirEntry *entry : pointeur vers un DirEntry.
const char *destinationPath : pointeur vers le chemin de destination.
const char *sourcePath : pointeur vers le chemin source.
*/
void dirCopy(DirEntry *entry, const char *destinationPath, const char *sourcePath) {
std::vector<DirEntry> dirContents;
dirContents.clear();
if (entry->isDirectory) chdir((sourcePath + ("/" + entry->name)).c_str());
getDirectoryContents(dirContents);
if (((int)dirContents.size()) == 1) mkdir((destinationPath + ("/" + entry->name)).c_str(), 0777);
if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry->name)).c_str(), (destinationPath + ("/" + entry->name)).c_str());
}
u32 copyOffset = 0, copySize = 0;
/*
Lopération de copie.
const char *destinationPath : pointeur vers le chemin de destination.
const char *sourcePath : pointeur vers le chemin source.
*/
int fcopy(const char *sourcePath, const char *destinationPath) {
copyOffset = 0, copySize = 0;
DIR *isDir = opendir(sourcePath);
if (isDir != NULL) {
closedir(isDir);
/* Le chemin source est un répertoire. */
chdir(sourcePath);
std::vector<DirEntry> dirContents;
getDirectoryContents(dirContents);
DirEntry *entry = &dirContents.at(1);
mkdir(destinationPath, 0777);
for(int i = 1; i < ((int)dirContents.size()); i++) {
chdir(sourcePath);
entry = &dirContents.at(i);
dirCopy(entry, destinationPath, sourcePath);
}
chdir(destinationPath);
chdir("..");
return 1;
} else {
closedir(isDir);
/* Le chemin source est un fichier. */
FILE *sourceFile = fopen(sourcePath, "rb");
copySize = 0, copyOffset = 0;
if (sourceFile) {
fseek(sourceFile, 0, SEEK_END);
copySize = ftell(sourceFile); // Obtenir la taille du fichier source.
fseek(sourceFile, 0, SEEK_SET);
} else {
fclose(sourceFile);
return -1;
}
FILE *destinationFile = fopen(destinationPath, "wb");
//if (destinationFile) {
fseek(destinationFile, 0, SEEK_SET);
/*} else {
fclose(sourceFile);
fclose(destinationFile);
return -1;
}*/
int numr;
while(1) {
scanKeys();
if (keysHeld() & KEY_B) {
/* Annuler la copie. */
fclose(sourceFile);
fclose(destinationFile);
return -1;
break;
}
printf("\x1b[16;0H");
printf("Progress:\n");
printf("%i/%i Bytes ", (int)copyOffset, (int)copySize);
/* Copier le fichier vers le chemin de destination. */
numr = fread(copyBuf, 2, copyBufSize, sourceFile);
fwrite(copyBuf, 2, numr, destinationFile);
copyOffset += copyBufSize;
if (copyOffset > copySize) {
fclose(sourceFile);
fclose(destinationFile);
printf("\x1b[17;0H");
printf("%i/%i Bytes ", (int)copyOffset, (int)copySize);
for(int i = 0; i < 30; i++) gspWaitForVBlank();
return 1;
break;
}
}
return -1;
}
}
+129 -129
View File
@@ -1,130 +1,130 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "files.hpp"
FS_Path getPathInfo(const char *path, FS_ArchiveID *archive) {
*archive = ARCHIVE_SDMC;
FS_Path filePath = { PATH_INVALID, 0, nullptr };
unsigned int prefixlen = 0;
if (!strncmp(path, "sdmc:/", 6)) {
prefixlen = 5;
} else if (*path != '/') {
/*
Si le chemin est local (ne pas commencer par une barre oblique),
il doit être ajouté au répertoire de travail pour être valide.
*/
char *actualPath = NULL;
asprintf(&actualPath, "%s%s", "/", path);
filePath = fsMakePath(PATH_ASCII, actualPath);
free(actualPath);
}
/* Si la valeur filePath est définie ci-dessus, définissez-la. */
if (filePath.size == 0) filePath = fsMakePath(PATH_ASCII, path + prefixlen);
return filePath;
}
Result makeDirs(const char *path) {
Result ret = 0;
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
for (char *slashpos = strchr(path + 1, '/'); slashpos != NULL; slashpos = strchr(slashpos + 1, '/')) {
char bak = *(slashpos);
*(slashpos) = '\0';
Handle dirHandle;
ret = FSUSER_OpenDirectory(&dirHandle, archive, filePath);
if (R_SUCCEEDED(ret)) FSDIR_Close(dirHandle);
else ret = FSUSER_CreateDirectory(archive, filePath, FS_ATTRIBUTE_DIRECTORY);
*(slashpos) = bak;
}
FSUSER_CloseArchive(archive);
return ret;
}
Result openFile(Handle *fileHandle, const char *path, bool write) {
FS_ArchiveID archive;
FS_Path filePath = getPathInfo(path, &archive);
u32 flags = (write ? (FS_OPEN_CREATE | FS_OPEN_WRITE) : FS_OPEN_READ);
Result ret = 0;
ret = makeDirs(strdup(path));
ret = FSUSER_OpenFileDirectly(fileHandle, archive, fsMakePath(PATH_EMPTY, ""), filePath, flags, 0);
if (write) ret = FSFILE_SetSize(*fileHandle, 0); // Tronquer le fichier pour supprimer le contenu précédent avant l’écriture.
return ret;
}
Result deleteFile(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteFile(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
}
Result removeDir(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteDirectory(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
}
Result removeDirRecursive(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteDirectoryRecursively(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "files.hpp"
FS_Path getPathInfo(const char *path, FS_ArchiveID *archive) {
*archive = ARCHIVE_SDMC;
FS_Path filePath = { PATH_INVALID, 0, nullptr };
unsigned int prefixlen = 0;
if (!strncmp(path, "sdmc:/", 6)) {
prefixlen = 5;
} else if (*path != '/') {
/*
Si le chemin est local (ne pas commencer par une barre oblique),
il doit être ajouté au répertoire de travail pour être valide.
*/
char *actualPath = NULL;
asprintf(&actualPath, "%s%s", "/", path);
filePath = fsMakePath(PATH_ASCII, actualPath);
free(actualPath);
}
/* Si la valeur filePath est définie ci-dessus, définissez-la. */
if (filePath.size == 0) filePath = fsMakePath(PATH_ASCII, path + prefixlen);
return filePath;
}
Result makeDirs(const char *path) {
Result ret = 0;
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
for (char *slashpos = strchr(path + 1, '/'); slashpos != NULL; slashpos = strchr(slashpos + 1, '/')) {
char bak = *(slashpos);
*(slashpos) = '\0';
Handle dirHandle;
ret = FSUSER_OpenDirectory(&dirHandle, archive, filePath);
if (R_SUCCEEDED(ret)) FSDIR_Close(dirHandle);
else ret = FSUSER_CreateDirectory(archive, filePath, FS_ATTRIBUTE_DIRECTORY);
*(slashpos) = bak;
}
FSUSER_CloseArchive(archive);
return ret;
}
Result openFile(Handle *fileHandle, const char *path, bool write) {
FS_ArchiveID archive;
FS_Path filePath = getPathInfo(path, &archive);
u32 flags = (write ? (FS_OPEN_CREATE | FS_OPEN_WRITE) : FS_OPEN_READ);
Result ret = 0;
ret = makeDirs(strdup(path));
ret = FSUSER_OpenFileDirectly(fileHandle, archive, fsMakePath(PATH_EMPTY, ""), filePath, flags, 0);
if (write) ret = FSFILE_SetSize(*fileHandle, 0); // Tronquer le fichier pour supprimer le contenu précédent avant l’écriture.
return ret;
}
Result deleteFile(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteFile(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
}
Result removeDir(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteDirectory(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
}
Result removeDirRecursive(const char *path) {
FS_ArchiveID archiveID;
FS_Path filePath = getPathInfo(path, &archiveID);
FS_Archive archive;
Result ret = FSUSER_OpenArchive(&archive, archiveID, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(ret)) return ret;
ret = FSUSER_DeleteDirectoryRecursively(archive, filePath);
FSUSER_CloseArchive(archive);
return ret;
}
+54 -54
View File
@@ -1,55 +1,55 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "lang.hpp"
#include <stdio.h>
#include <unistd.h>
static nlohmann::json appJson;
std::string Lang::get(const std::string &key) {
if (!appJson.contains(key)) return key;
return appJson.at(key).get_ref<const std::string&>();
}
void Lang::load(const std::string &lang) {
FILE *values;
/* Vérifier si il existe. */
if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) {
values = fopen(std::string(("romfs:/lang/" + lang + "/app.json")).c_str(), "rt");
appJson = nlohmann::json::parse(values, nullptr, false);
fclose(values);
return;
} else {
values = fopen(("romfs:/lang/en/app.json"), "rt");
appJson = nlohmann::json::parse(values, nullptr, false);
fclose(values);
return;
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "lang.hpp"
#include <stdio.h>
#include <unistd.h>
static nlohmann::json appJson;
std::string Lang::get(const std::string &key) {
if (!appJson.contains(key)) return key;
return appJson.at(key).get_ref<const std::string&>();
}
void Lang::load(const std::string &lang) {
FILE *values;
/* Vérifier si il existe. */
if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) {
values = fopen(std::string(("romfs:/lang/" + lang + "/app.json")).c_str(), "rt");
appJson = nlohmann::json::parse(values, nullptr, false);
fclose(values);
return;
} else {
values = fopen(("romfs:/lang/en/app.json"), "rt");
appJson = nlohmann::json::parse(values, nullptr, false);
fclose(values);
return;
}
}
+6489 -6489
View File
File diff suppressed because it is too large Load Diff
+317 -317
View File
@@ -1,318 +1,318 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "files.hpp"
#include "queueSystem.hpp"
#include "scriptUtils.hpp"
#include <unistd.h>
std::deque<std::unique_ptr<Queue>> queueEntries;
bool QueueRuns = false;
static Thread queueThread = nullptr;
LightLock QueueSystem::lock;
/*
Adds an entry to the queue.
nlohmann::json obj: The object.
C2D_Image icn: The icon.
*/
void QueueSystem::AddToQueue(nlohmann::json obj, C2D_Image icn, std::string name) {
LightLock_Lock(&lock);
queueEntries.push_back( std::make_unique<Queue>(obj, icn, name) );
LightLock_Unlock(&lock);
/* If not already running, let it run!! */
if (!QueueRuns) {
QueueRuns = true; // We enable the queue run state here.
s32 prio = 0;
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
queueThread = threadCreate((ThreadFunc)QueueSystem::QueueHandle, NULL, 64 * 1024, prio - 1, -2, false);
}
}
/*
Clears the queue.
*/
void QueueSystem::ClearQueue() {
QueueRuns = false;
queueEntries.clear();
}
/*
The whole handle.
*/
void QueueSystem::QueueHandle() {
while(QueueRuns) {
Result ret = NONE; // No Error as of yet.
LightLock_Lock(&lock);
queueEntries[0]->total = queueEntries[0]->obj.size();
queueEntries[0]->current = 0;
LightLock_Unlock(&lock);
for(int i = 0; i < (int)queueEntries[0]->obj.size(); i++) {
LightLock_Lock(&lock);
queueEntries[0]->current++;
LightLock_Unlock(&lock);
if (ret == NONE) {
std::string type = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("type") && queueEntries[0]->obj[i]["type"].is_string()) {
type = queueEntries[0]->obj[i]["type"];
} else {
ret = SYNTAX_ERROR;
}
LightLock_Unlock(&lock);
/* Deleting a file. */
if (type == "deleteFile") {
bool missing = false;
std::string file = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::removeFile(file, "");
else ret = SYNTAX_ERROR;
/* Downloading from a URL. */
} else if (type == "downloadFile") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Downloading;
bool missing = false;
std::string file = "", output = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::downloadFile(file, output, "");
else ret = SYNTAX_ERROR;
/* Download from a GitHub Release. */
} else if (type == "downloadRelease") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Downloading;
bool missing = false, includePrereleases = false;
std::string repo = "", file = "", output = "";
if (queueEntries[0]->obj[i].contains("repo") && queueEntries[0]->obj[i]["repo"].is_string()) {
repo = queueEntries[0]->obj[i]["repo"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("includePrereleases") && queueEntries[0]->obj[i]["includePrereleases"].is_boolean())
includePrereleases = queueEntries[0]->obj[i]["includePrereleases"];
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::downloadRelease(repo, file, output, includePrereleases, "");
else ret = SYNTAX_ERROR;
/* Extracting files. */
} else if (type == "extractFile") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Extracting;
bool missing = false;
std::string file = "", input = "", output = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("input") && queueEntries[0]->obj[i]["input"].is_string()) {
input = queueEntries[0]->obj[i]["input"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ScriptUtils::extractFile(file, input, output, "");
else ret = SYNTAX_ERROR;
/* Installing CIAs. */
} else if (type == "installCia") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Installing;
bool missing = false, updateSelf = false;
std::string file = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("updateSelf") && queueEntries[0]->obj[i]["updateSelf"].is_boolean()) {
updateSelf = queueEntries[0]->obj[i]["updateSelf"];
}
LightLock_Unlock(&lock);
if (!missing) ScriptUtils::installFile(file, updateSelf, "");
else ret = SYNTAX_ERROR;
} else if (type == "mkdir") {
bool missing = false;
std::string directory = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
directory = queueEntries[0]->obj[i]["directory"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) makeDirs(directory.c_str());
else ret = SYNTAX_ERROR;
} else if (type == "rmdir") {
bool missing = false;
std::string directory = "", message = "", promptmsg = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
directory = queueEntries[0]->obj[i]["directory"];
} else missing = true;
LightLock_Unlock(&lock);
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
if (!missing && directory != "") {
if (access(directory.c_str(), F_OK) != 0) ret = DELETE_ERROR;
else {
if (Msg::promptMsg(promptmsg)) removeDirRecursive(directory.c_str());
}
}
else ret = SYNTAX_ERROR;
} else if (type == "promptMessage" || type == "promptMsg") {
std::string Message = "";
int skipCount = -1;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("message") && queueEntries[0]->obj[i]["message"].is_string()) {
Message = queueEntries[0]->obj[i]["message"];
}
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
skipCount = queueEntries[0]->obj[i]["count"];
}
LightLock_Unlock(&lock);
Result res = ScriptUtils::prompt(Message);
if (skipCount > -1 && res == SCRIPT_CANCELED) i += skipCount; // Skip.
} else if (type == "exit") {
ret = SCRIPT_CANCELED;
} else if (type == "copy") {
std::string source = "", destination = "";
bool missing = false;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("source") && queueEntries[0]->obj[i]["source"].is_string()) {
source = queueEntries[0]->obj[i]["source"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("destination") && queueEntries[0]->obj[i]["destination"].is_string()) {
destination = queueEntries[0]->obj[i]["destination"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::copyFile(source, destination, "");
else ret = SYNTAX_ERROR;
} else if (type == "move") {
std::string oldFile = "", newFile = "";
bool missing = false;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("old") && queueEntries[0]->obj[i]["old"].is_string()) {
oldFile = queueEntries[0]->obj[i]["old"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("new") && queueEntries[0]->obj[i]["new"].is_string()) {
newFile = queueEntries[0]->obj[i]["new"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::renameFile(oldFile, newFile, "");
else ret = SYNTAX_ERROR;
} else if (type == "skip") {
int skipCount = -1;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
skipCount = queueEntries[0]->obj[i]["count"];
}
LightLock_Unlock(&lock);
if (skipCount > 0) i += skipCount; // Skip.
}
}
}
LightLock_Lock(&lock);
/* Canceled or None is for me -> Done. */
if (ret == NONE || ret == SCRIPT_CANCELED) {
queueEntries[0]->status = QueueStatus::Done;
} else { // Else it failed..
queueEntries[0]->status = QueueStatus::Failed;
}
queueEntries.pop_front();
if (queueEntries.empty()) QueueRuns = false; // The queue ended.
ret = NONE; // Reset.
LightLock_Unlock(&lock);
/* TODO: Display a message if something ends? */
}
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "files.hpp"
#include "queueSystem.hpp"
#include "scriptUtils.hpp"
#include <unistd.h>
std::deque<std::unique_ptr<Queue>> queueEntries;
bool QueueRuns = false;
static Thread queueThread = nullptr;
LightLock QueueSystem::lock;
/*
Adds an entry to the queue.
nlohmann::json obj: The object.
C2D_Image icn: The icon.
*/
void QueueSystem::AddToQueue(nlohmann::json obj, C2D_Image icn, std::string name) {
LightLock_Lock(&lock);
queueEntries.push_back( std::make_unique<Queue>(obj, icn, name) );
LightLock_Unlock(&lock);
/* If not already running, let it run!! */
if (!QueueRuns) {
QueueRuns = true; // We enable the queue run state here.
s32 prio = 0;
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
queueThread = threadCreate((ThreadFunc)QueueSystem::QueueHandle, NULL, 64 * 1024, prio - 1, -2, false);
}
}
/*
Clears the queue.
*/
void QueueSystem::ClearQueue() {
QueueRuns = false;
queueEntries.clear();
}
/*
The whole handle.
*/
void QueueSystem::QueueHandle() {
while(QueueRuns) {
Result ret = NONE; // No Error as of yet.
LightLock_Lock(&lock);
queueEntries[0]->total = queueEntries[0]->obj.size();
queueEntries[0]->current = 0;
LightLock_Unlock(&lock);
for(int i = 0; i < (int)queueEntries[0]->obj.size(); i++) {
LightLock_Lock(&lock);
queueEntries[0]->current++;
LightLock_Unlock(&lock);
if (ret == NONE) {
std::string type = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("type") && queueEntries[0]->obj[i]["type"].is_string()) {
type = queueEntries[0]->obj[i]["type"];
} else {
ret = SYNTAX_ERROR;
}
LightLock_Unlock(&lock);
/* Deleting a file. */
if (type == "deleteFile") {
bool missing = false;
std::string file = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::removeFile(file, "");
else ret = SYNTAX_ERROR;
/* Downloading from a URL. */
} else if (type == "downloadFile") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Downloading;
bool missing = false;
std::string file = "", output = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::downloadFile(file, output, "");
else ret = SYNTAX_ERROR;
/* Download from a GitHub Release. */
} else if (type == "downloadRelease") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Downloading;
bool missing = false, includePrereleases = false;
std::string repo = "", file = "", output = "";
if (queueEntries[0]->obj[i].contains("repo") && queueEntries[0]->obj[i]["repo"].is_string()) {
repo = queueEntries[0]->obj[i]["repo"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("includePrereleases") && queueEntries[0]->obj[i]["includePrereleases"].is_boolean())
includePrereleases = queueEntries[0]->obj[i]["includePrereleases"];
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::downloadRelease(repo, file, output, includePrereleases, "");
else ret = SYNTAX_ERROR;
/* Extracting files. */
} else if (type == "extractFile") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Extracting;
bool missing = false;
std::string file = "", input = "", output = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("input") && queueEntries[0]->obj[i]["input"].is_string()) {
input = queueEntries[0]->obj[i]["input"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("output") && queueEntries[0]->obj[i]["output"].is_string()) {
output = queueEntries[0]->obj[i]["output"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ScriptUtils::extractFile(file, input, output, "");
else ret = SYNTAX_ERROR;
/* Installing CIAs. */
} else if (type == "installCia") {
LightLock_Lock(&lock);
queueEntries[0]->status = QueueStatus::Installing;
bool missing = false, updateSelf = false;
std::string file = "";
if (queueEntries[0]->obj[i].contains("file") && queueEntries[0]->obj[i]["file"].is_string()) {
file = queueEntries[0]->obj[i]["file"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("updateSelf") && queueEntries[0]->obj[i]["updateSelf"].is_boolean()) {
updateSelf = queueEntries[0]->obj[i]["updateSelf"];
}
LightLock_Unlock(&lock);
if (!missing) ScriptUtils::installFile(file, updateSelf, "");
else ret = SYNTAX_ERROR;
} else if (type == "mkdir") {
bool missing = false;
std::string directory = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
directory = queueEntries[0]->obj[i]["directory"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) makeDirs(directory.c_str());
else ret = SYNTAX_ERROR;
} else if (type == "rmdir") {
bool missing = false;
std::string directory = "", message = "", promptmsg = "";
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("directory") && queueEntries[0]->obj[i]["directory"].is_string()) {
directory = queueEntries[0]->obj[i]["directory"];
} else missing = true;
LightLock_Unlock(&lock);
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
if (!missing && directory != "") {
if (access(directory.c_str(), F_OK) != 0) ret = DELETE_ERROR;
else {
if (Msg::promptMsg(promptmsg)) removeDirRecursive(directory.c_str());
}
}
else ret = SYNTAX_ERROR;
} else if (type == "promptMessage" || type == "promptMsg") {
std::string Message = "";
int skipCount = -1;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("message") && queueEntries[0]->obj[i]["message"].is_string()) {
Message = queueEntries[0]->obj[i]["message"];
}
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
skipCount = queueEntries[0]->obj[i]["count"];
}
LightLock_Unlock(&lock);
Result res = ScriptUtils::prompt(Message);
if (skipCount > -1 && res == SCRIPT_CANCELED) i += skipCount; // Skip.
} else if (type == "exit") {
ret = SCRIPT_CANCELED;
} else if (type == "copy") {
std::string source = "", destination = "";
bool missing = false;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("source") && queueEntries[0]->obj[i]["source"].is_string()) {
source = queueEntries[0]->obj[i]["source"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("destination") && queueEntries[0]->obj[i]["destination"].is_string()) {
destination = queueEntries[0]->obj[i]["destination"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::copyFile(source, destination, "");
else ret = SYNTAX_ERROR;
} else if (type == "move") {
std::string oldFile = "", newFile = "";
bool missing = false;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("old") && queueEntries[0]->obj[i]["old"].is_string()) {
oldFile = queueEntries[0]->obj[i]["old"];
} else missing = true;
if (queueEntries[0]->obj[i].contains("new") && queueEntries[0]->obj[i]["new"].is_string()) {
newFile = queueEntries[0]->obj[i]["new"];
} else missing = true;
LightLock_Unlock(&lock);
if (!missing) ret = ScriptUtils::renameFile(oldFile, newFile, "");
else ret = SYNTAX_ERROR;
} else if (type == "skip") {
int skipCount = -1;
LightLock_Lock(&lock);
if (queueEntries[0]->obj[i].contains("count") && queueEntries[0]->obj[i]["count"].is_number()) {
skipCount = queueEntries[0]->obj[i]["count"];
}
LightLock_Unlock(&lock);
if (skipCount > 0) i += skipCount; // Skip.
}
}
}
LightLock_Lock(&lock);
/* Canceled or None is for me -> Done. */
if (ret == NONE || ret == SCRIPT_CANCELED) {
queueEntries[0]->status = QueueStatus::Done;
} else { // Else it failed..
queueEntries[0]->status = QueueStatus::Failed;
}
queueEntries.pop_front();
if (queueEntries.empty()) QueueRuns = false; // The queue ended.
ret = NONE; // Reset.
LightLock_Unlock(&lock);
/* TODO: Display a message if something ends? */
}
}
+90 -90
View File
@@ -1,91 +1,91 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "lodepng.h"
#include "msg.hpp"
#include "screenshot.hpp"
C2D_Image Screenshot::Convert(const std::string &filename) {
std::vector<u8> ImageBuffer;
unsigned width, height;
C2D_Image img;
lodepng::decode(ImageBuffer, width, height, filename.c_str());
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];
}
}
return img;
}
C2D_Image Screenshot::ConvertFromBuffer(const std::vector<u8> &buffer) {
std::vector<u8> ImageBuffer;
unsigned width, height;
C2D_Image img;
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];
}
}
return img;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "lodepng.h"
#include "msg.hpp"
#include "screenshot.hpp"
C2D_Image Screenshot::Convert(const std::string &filename) {
std::vector<u8> ImageBuffer;
unsigned width, height;
C2D_Image img;
lodepng::decode(ImageBuffer, width, height, filename.c_str());
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];
}
}
return img;
}
C2D_Image Screenshot::ConvertFromBuffer(const std::vector<u8> &buffer) {
std::vector<u8> ImageBuffer;
unsigned width, height;
C2D_Image img;
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];
}
}
return img;
}
File diff suppressed because it is too large Load Diff
+165 -165
View File
@@ -1,166 +1,166 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "sound.hpp"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
/*
Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/
*/
typedef struct _WavHeader {
char magic[4]; // "RIFF"
u32 totallength; // Total file length, minus 8.
char wavefmt[8]; // Should be "WAVEfmt ".
u32 format; // 16 for PCM format.
u16 pcm; // 1 for PCM format.
u16 channels; // Channels.
u32 frequency; // Sampling frequency.
u32 bytes_per_second;
u16 bytes_by_capture;
u16 bits_per_sample;
char data[4]; // "data".
u32 bytes_in_data;
} WavHeader;
static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes.");
#define _MAX_SIZE 10485760 // 10 MiB.
/*
Initialize the sound.
const std::string &path: Path to the file to play.
const int channel: The channel to use. 1 by default.
const bool toloop: If should loop or not. True by default.
*/
Sound::Sound(const std::string &path, const int channel, const bool toloop) {
ndspSetOutputMode(NDSP_OUTPUT_MONO);
ndspSetOutputCount(2); // Amount of buffers.
/* Reading wav file. */
FILE *file = fopen(path.c_str(), "rb");
if (!file) {
printf("Could not open the WAV file: %s.\n", path.c_str());
this->good = false;
return;
}
WavHeader wavHeader;
size_t read = fread(&wavHeader, 1, sizeof(wavHeader), file);
if (read != sizeof(wavHeader)) {
/* Short read. */
printf("WAV file header is too short: %s.\n", path.c_str());
fclose(file);
this->good = false;
return;
}
/* Verify the header. */
static const char RIFF_magic[4] = { 'R','I','F','F' };
if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) {
/* Incorrect magic number. */
printf("Wrong file format.\n");
fclose(file);
this->good = false;
return;
}
if (wavHeader.totallength == 0 ||
(wavHeader.channels != 1 && wavHeader.channels != 2) ||
(wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) {
/* Unsupported WAV file. */
printf("Corrupted wav file.\n");
fclose(file);
this->good = false;
return;
}
/* Get the file size. */
fseek(file, 0, SEEK_END);
this->dataSize = ftell(file) - sizeof(wavHeader);
if (this->dataSize > _MAX_SIZE) {
fclose(file);
this->good = false;
return;
}
/* Allocating and reading samples. */
this->data = reinterpret_cast<u8 *>(linearAlloc(this->dataSize));
fseek(file, 44, SEEK_SET);
fread(this->data, 1, this->dataSize, file);
fclose(file);
//if (wavHeader.bits_per_sample == 16) this->dataSize /= 2; // Not sure.. if that is actually needed at all.
this->chnl = channel;
ndspChnReset(this->chnl);
ndspChnSetInterp(this->chnl, NDSP_INTERP_NONE);
ndspChnSetRate(this->chnl, float(wavHeader.frequency));
ndspChnSetFormat(this->chnl, ((wavHeader.bits_per_sample == 8) ? NDSP_FORMAT_MONO_PCM8 : NDSP_FORMAT_MONO_PCM16));
/* Create and play a wav buffer. */
memset(&this->waveBuf, 0, sizeof(this->waveBuf));
this->waveBuf.data_vaddr = reinterpret_cast<u32 *>(this->data);
this->waveBuf.nsamples = this->dataSize / (wavHeader.bits_per_sample >> 3);
this->waveBuf.looping = toloop;
this->waveBuf.status = NDSP_WBUF_FREE;
}
Sound::~Sound() {
if (this->good) {
this->waveBuf.data_vaddr = 0;
this->waveBuf.nsamples = 0;
this->waveBuf.looping = false;
this->waveBuf.status = 0;
ndspChnWaveBufClear(this->chnl);
if (this->data) linearFree(this->data);
}
}
/*
Plays the sound.
*/
void Sound::play() {
if (!this->data || !this->good) return;
DSP_FlushDataCache(this->data, this->dataSize);
ndspChnWaveBufAdd(this->chnl, &this->waveBuf);
}
/*
Stops the sound.
*/
void Sound::stop() {
if (!this->data || !this->good) return;
ndspChnWaveBufClear(this->chnl);
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "sound.hpp"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
/*
Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/
*/
typedef struct _WavHeader {
char magic[4]; // "RIFF"
u32 totallength; // Total file length, minus 8.
char wavefmt[8]; // Should be "WAVEfmt ".
u32 format; // 16 for PCM format.
u16 pcm; // 1 for PCM format.
u16 channels; // Channels.
u32 frequency; // Sampling frequency.
u32 bytes_per_second;
u16 bytes_by_capture;
u16 bits_per_sample;
char data[4]; // "data".
u32 bytes_in_data;
} WavHeader;
static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes.");
#define _MAX_SIZE 10485760 // 10 MiB.
/*
Initialize the sound.
const std::string &path: Path to the file to play.
const int channel: The channel to use. 1 by default.
const bool toloop: If should loop or not. True by default.
*/
Sound::Sound(const std::string &path, const int channel, const bool toloop) {
ndspSetOutputMode(NDSP_OUTPUT_MONO);
ndspSetOutputCount(2); // Amount of buffers.
/* Reading wav file. */
FILE *file = fopen(path.c_str(), "rb");
if (!file) {
printf("Could not open the WAV file: %s.\n", path.c_str());
this->good = false;
return;
}
WavHeader wavHeader;
size_t read = fread(&wavHeader, 1, sizeof(wavHeader), file);
if (read != sizeof(wavHeader)) {
/* Short read. */
printf("WAV file header is too short: %s.\n", path.c_str());
fclose(file);
this->good = false;
return;
}
/* Verify the header. */
static const char RIFF_magic[4] = { 'R','I','F','F' };
if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) {
/* Incorrect magic number. */
printf("Wrong file format.\n");
fclose(file);
this->good = false;
return;
}
if (wavHeader.totallength == 0 ||
(wavHeader.channels != 1 && wavHeader.channels != 2) ||
(wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) {
/* Unsupported WAV file. */
printf("Corrupted wav file.\n");
fclose(file);
this->good = false;
return;
}
/* Get the file size. */
fseek(file, 0, SEEK_END);
this->dataSize = ftell(file) - sizeof(wavHeader);
if (this->dataSize > _MAX_SIZE) {
fclose(file);
this->good = false;
return;
}
/* Allocating and reading samples. */
this->data = reinterpret_cast<u8 *>(linearAlloc(this->dataSize));
fseek(file, 44, SEEK_SET);
fread(this->data, 1, this->dataSize, file);
fclose(file);
//if (wavHeader.bits_per_sample == 16) this->dataSize /= 2; // Not sure.. if that is actually needed at all.
this->chnl = channel;
ndspChnReset(this->chnl);
ndspChnSetInterp(this->chnl, NDSP_INTERP_NONE);
ndspChnSetRate(this->chnl, float(wavHeader.frequency));
ndspChnSetFormat(this->chnl, ((wavHeader.bits_per_sample == 8) ? NDSP_FORMAT_MONO_PCM8 : NDSP_FORMAT_MONO_PCM16));
/* Create and play a wav buffer. */
memset(&this->waveBuf, 0, sizeof(this->waveBuf));
this->waveBuf.data_vaddr = reinterpret_cast<u32 *>(this->data);
this->waveBuf.nsamples = this->dataSize / (wavHeader.bits_per_sample >> 3);
this->waveBuf.looping = toloop;
this->waveBuf.status = NDSP_WBUF_FREE;
}
Sound::~Sound() {
if (this->good) {
this->waveBuf.data_vaddr = 0;
this->waveBuf.nsamples = 0;
this->waveBuf.looping = false;
this->waveBuf.status = 0;
ndspChnWaveBufClear(this->chnl);
if (this->data) linearFree(this->data);
}
}
/*
Plays the sound.
*/
void Sound::play() {
if (!this->data || !this->good) return;
DSP_FlushDataCache(this->data, this->dataSize);
ndspChnWaveBufAdd(this->chnl, &this->waveBuf);
}
/*
Stops the sound.
*/
void Sound::stop() {
if (!this->data || !this->good) return;
ndspChnWaveBufClear(this->chnl);
}
+104 -104
View File
@@ -1,105 +1,105 @@
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "stringutils.hpp"
/*
Pour la conversion en minuscules.
const std::string &str : La chaîne qui doit être convertie.
*/
std::string StringUtils::lower_case(const std::string &str) {
std::string lower;
transform(str.begin(), str.end(), std::back_inserter(lower), tolower); // Transformez la chaîne en minuscules.
return lower;
}
/*
Récupère les chaînes dun vecteur et les retourne comme une seule chaîne.
std::vector<std::string> fetch : Le vecteur.
*/
std::string StringUtils::FetchStringsFromVector(const std::vector<std::string> &fetch) {
std::string temp;
if (fetch.size() < 1) return ""; // Plus petit que 1 --> Retour vide.
for (int i = 0; i < (int)fetch.size(); i++) {
if (i != (int)fetch.size() - 1) {
temp += fetch[i] + ", ";
} else {
temp += fetch[i];
}
}
return temp;
}
/*
Adapté de lanalyse doctets de GM9i.
*/
std::string StringUtils::formatBytes(int bytes) {
char out[32];
if (bytes == 1) snprintf(out, sizeof(out), "%d Byte", bytes);
else if (bytes < 1024) snprintf(out, sizeof(out), "%d Bytes", bytes);
else if (bytes < 1024 * 1024) snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024);
else if (bytes < 1024 * 1024 * 1024) snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024);
else snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024);
return out;
}
/*
Renvoie un vecteur de toutes les marques.
*/
std::vector<std::string> StringUtils::GetMarks(int marks) {
std::vector<std::string> out;
if (marks & favoriteMarks::STAR) out.push_back( "" );
if (marks & favoriteMarks::HEART) out.push_back( "" );
if (marks & favoriteMarks::DIAMOND) out.push_back( "" );
if (marks & favoriteMarks::CLUBS) out.push_back( "" );
if (marks & favoriteMarks::SPADE) out.push_back( "" );
return out;
}
/*
Renvoie une chaîne de toutes les marques.
*/
std::string StringUtils::GetMarkString(int marks) {
std::string out;
if (marks & favoriteMarks::STAR) out += "";
if (marks & favoriteMarks::HEART) out += "";
if (marks & favoriteMarks::DIAMOND) out += "";
if (marks & favoriteMarks::CLUBS) out += "";
if (marks & favoriteMarks::SPADE) out += "";
return out;
/*
* This file is part of Universal-Updater
* Copyright (C) 2019-2020 Universal-Team
*
* 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/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "common.hpp"
#include "stringutils.hpp"
/*
Pour la conversion en minuscules.
const std::string &str : La chaîne qui doit être convertie.
*/
std::string StringUtils::lower_case(const std::string &str) {
std::string lower;
transform(str.begin(), str.end(), std::back_inserter(lower), tolower); // Transformez la chaîne en minuscules.
return lower;
}
/*
Récupère les chaînes dun vecteur et les retourne comme une seule chaîne.
std::vector<std::string> fetch : Le vecteur.
*/
std::string StringUtils::FetchStringsFromVector(const std::vector<std::string> &fetch) {
std::string temp;
if (fetch.size() < 1) return ""; // Plus petit que 1 --> Retour vide.
for (int i = 0; i < (int)fetch.size(); i++) {
if (i != (int)fetch.size() - 1) {
temp += fetch[i] + ", ";
} else {
temp += fetch[i];
}
}
return temp;
}
/*
Adapté de lanalyse doctets de GM9i.
*/
std::string StringUtils::formatBytes(int bytes) {
char out[32];
if (bytes == 1) snprintf(out, sizeof(out), "%d Byte", bytes);
else if (bytes < 1024) snprintf(out, sizeof(out), "%d Bytes", bytes);
else if (bytes < 1024 * 1024) snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024);
else if (bytes < 1024 * 1024 * 1024) snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024);
else snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024);
return out;
}
/*
Renvoie un vecteur de toutes les marques.
*/
std::vector<std::string> StringUtils::GetMarks(int marks) {
std::vector<std::string> out;
if (marks & favoriteMarks::STAR) out.push_back( "" );
if (marks & favoriteMarks::HEART) out.push_back( "" );
if (marks & favoriteMarks::DIAMOND) out.push_back( "" );
if (marks & favoriteMarks::CLUBS) out.push_back( "" );
if (marks & favoriteMarks::SPADE) out.push_back( "" );
return out;
}
/*
Renvoie une chaîne de toutes les marques.
*/
std::string StringUtils::GetMarkString(int marks) {
std::string out;
if (marks & favoriteMarks::STAR) out += "";
if (marks & favoriteMarks::HEART) out += "";
if (marks & favoriteMarks::DIAMOND) out += "";
if (marks & favoriteMarks::CLUBS) out += "";
if (marks & favoriteMarks::SPADE) out += "";
return out;
}