mirror of
https://github.com/DarkStore-3DS/DarkStore.git
synced 2026-07-03 00:39:02 +00:00
Changed Some More Stuff To DarkStore & Removed All Translations For Now
This commit is contained in:
+105
-105
@@ -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 l’inté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 l’inté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
@@ -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 jusqu’au 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 d’avertissement 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 n’importe 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 jusqu’au 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 d’avertissement 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 n’importe 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
@@ -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, s’il 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 l’accé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 n’est 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 l’application. */
|
||||
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 l’ancienne 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, s’il 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 l’accé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 n’est 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 l’application. */
|
||||
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 l’ancienne limite.
|
||||
aptSetSleepAllowed(true);
|
||||
|
||||
romfsExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
+67
-67
@@ -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
@@ -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 d’args, 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, s’il 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 l’accé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 d’args, 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, s’il 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 l’accé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
@@ -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 ¤tMenu: 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 ¤tMenu, 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 ¤tMenu: 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 ¤tMenu, 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
@@ -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 l’enregistrement 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 l’enregistrement 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
@@ -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 n’est 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 l’index. */
|
||||
if ((int)entries.size() > i2) {
|
||||
if (entries[i2]) { // Assurez-vous que l’entrée n’est 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 à l’aide 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 ¤tMode : 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 ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Assurez-vous que le magasin n’est 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 n’est 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 l’index. */
|
||||
if ((int)entries.size() > i2) {
|
||||
if (entries[i2]) { // Assurez-vous que l’entrée n’est 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 à l’aide 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 ¤tMode : 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 ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Assurez-vous que le magasin n’est 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
@@ -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 n’est 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 l’index. */
|
||||
if ((int)entries.size() > i + store->GetScreenIndx()) {
|
||||
if (entries[i + store->GetScreenIndx()]) { // Assurez-vous que l’entrée n’est 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 ¤tMode : 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 ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Assurez-vous que le magasin n’est 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 n’est 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 l’index. */
|
||||
if ((int)entries.size() > i + store->GetScreenIndx()) {
|
||||
if (entries[i + store->GetScreenIndx()]) { // Assurez-vous que l’entrée n’est 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 ¤tMode : 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 ¤tMode, int &lastMode, bool &fetch, int &smallDelay) {
|
||||
if (store) { // Assurez-vous que le magasin n’est 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
@@ -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 l’application 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 n’y 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 l’application 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 n’y 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
@@ -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 n’existe 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 l’entré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 n’existe 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 l’entré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 n’existe 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 l’entré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;
|
||||
}
|
||||
|
||||
/*
|
||||
L’appel 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 n’existe 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 l’entré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 n’existe 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 l’entré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 n’existe 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 l’entré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;
|
||||
}
|
||||
|
||||
/*
|
||||
L’appel 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
@@ -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
@@ -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
@@ -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
@@ -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 c’est 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 c’est 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
File diff suppressed because it is too large
Load Diff
+101
-101
@@ -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 ¤tMenu, 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 ¤tMenu, 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
@@ -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
@@ -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
@@ -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
@@ -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 c’est 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 c’est 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 c’est 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 c’est 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
File diff suppressed because it is too large
Load Diff
+1292
-1292
File diff suppressed because it is too large
Load Diff
+450
-450
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+69
-69
@@ -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 l’entré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 l’entré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
@@ -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 à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 l’auteur.
|
||||
const std::unique_ptr<StoreEntry> &a : Const Référence à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 d’un 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 à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 l’auteur.
|
||||
const std::unique_ptr<StoreEntry> &a : Const Référence à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 à l’entrée A.
|
||||
const std::unique_ptr<StoreEntry> &b : Const Référence à l’entré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 d’un 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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 l’analyseur d’arguments.
|
||||
const std::string &file : Const Référence au fichier.
|
||||
const std::string &entry : Const Référence au nom du titre de l’entrée.
|
||||
int dlIndex : L’index 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 l’entrée de l’argument, 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 l’analyseur d’arguments.
|
||||
const std::string &file : Const Référence au fichier.
|
||||
const std::string &entry : Const Référence au nom du titre de l’entrée.
|
||||
int dlIndex : L’index 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 l’entrée de l’argument, 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
@@ -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
@@ -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 l’application à 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 où ça n’existe 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 n’a 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 d’aide. */
|
||||
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 l’application à 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 où ça n’existe 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 n’a 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 d’aide. */
|
||||
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
File diff suppressed because it is too large
Load Diff
+138
-138
@@ -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 = "";
|
||||
|
||||
/* C’est 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 = "";
|
||||
|
||||
/* C’est 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
@@ -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 s’il n’existe 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 d’informations eShop.
|
||||
const std::string &path : Const Référence au chemin, où 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 n’existe 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;
|
||||
/*
|
||||
L’opé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 s’il n’existe 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 d’informations eShop.
|
||||
const std::string &path : Const Référence au chemin, où 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 n’existe 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;
|
||||
/*
|
||||
L’opé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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+317
-317
@@ -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
@@ -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;
|
||||
}
|
||||
+564
-564
File diff suppressed because it is too large
Load Diff
+165
-165
@@ -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
@@ -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 d’un 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 l’analyse d’octets 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 d’un 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 l’analyse d’octets 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;
|
||||
}
|
||||
Reference in New Issue
Block a user