feat: Add to Favorites folder (Part 1)

This commit is contained in:
robshape 2023-04-20 21:08:53 +02:00
parent 4c5afd68e6
commit 36ad88176c
4 changed files with 127 additions and 5 deletions

View file

@ -112,7 +112,7 @@ Run `./start-toolchain.sh` and then `make all` in the Docker container shell.
- ~~Include extras in release by default~~ - ~~Include extras in release by default~~
- ~~Add Clear Recent setting~~ - ~~Add Clear Recent setting~~
- ~~Refactor Tools to Settings~~ - ~~Refactor Tools to Settings~~
- Add "mark as finished" OR "add as favorite" to menu - Add to Favorites
- Improve battery capacity readings (2100 mAh, 2600 mAh, 3500 mAh) - Improve battery capacity readings (2100 mAh, 2600 mAh, 3500 mAh)
- Adjust overclocking - Adjust overclocking
- Update Installation instructions for microSD cards of all sizes - Update Installation instructions for microSD cards of all sizes

View file

@ -118,6 +118,7 @@ report:
clean: clean:
rm -rf ./build rm -rf ./build
rm -rf ./releases
cd ./src/libmsettings && make clean cd ./src/libmsettings && make clean
cd ./src/keymon && make clean cd ./src/keymon && make clean
cd ./src/minui && make clean cd ./src/minui && make clean

View file

@ -56,6 +56,8 @@
#define PAKS_PATH SYSTEM_PATH "/paks" #define PAKS_PATH SYSTEM_PATH "/paks"
#define RECENT_PATH USERDATA_PATH "/.minui/recent.txt" #define RECENT_PATH USERDATA_PATH "/.minui/recent.txt"
#define FAUX_RECENT_PATH SDCARD_PATH "/Recently Played" #define FAUX_RECENT_PATH SDCARD_PATH "/Recently Played"
#define FAVORITE_PATH USERDATA_PATH "/.minui/favorite.txt"
#define FAUX_FAVORITE_PATH SDCARD_PATH "/Favorites"
#define COLLECTIONS_PATH SDCARD_PATH "/Collections" #define COLLECTIONS_PATH SDCARD_PATH "/Collections"
#define LAST_PATH "/tmp/last.txt" // transient #define LAST_PATH "/tmp/last.txt" // transient

View file

@ -215,7 +215,7 @@ static void getUniqueName(Entry* entry, char* out_name) {
} }
static void Directory_index(Directory* self) { static void Directory_index(Directory* self) {
int skip_index = exactMatch(FAUX_RECENT_PATH, self->path) || prefixMatch(COLLECTIONS_PATH, self->path); // not alphabetized int skip_index = exactMatch(FAUX_RECENT_PATH, self->path) || exactMatch(FAUX_FAVORITE_PATH, self->path) || prefixMatch(COLLECTIONS_PATH, self->path); // not alphabetized
Entry* prior = NULL; Entry* prior = NULL;
int alpha = -1; int alpha = -1;
@ -259,6 +259,7 @@ static void Directory_index(Directory* self) {
static Array* getRoot(void); static Array* getRoot(void);
static Array* getRecents(void); static Array* getRecents(void);
static Array* getFavorites(void);
static Array* getCollection(char* path); static Array* getCollection(char* path);
static Array* getDiscs(char* path); static Array* getDiscs(char* path);
static Array* getEntries(char* path); static Array* getEntries(char* path);
@ -276,6 +277,9 @@ static Directory* Directory_new(char* path, int selected) {
else if (exactMatch(path, FAUX_RECENT_PATH)) { else if (exactMatch(path, FAUX_RECENT_PATH)) {
self->entries = getRecents(); self->entries = getRecents();
} }
else if (exactMatch(path, FAUX_FAVORITE_PATH)) {
self->entries = getFavorites();
}
else if (!exactMatch(path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, path)) { else if (!exactMatch(path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, path)) {
self->entries = getCollection(path); self->entries = getCollection(path);
} }
@ -349,9 +353,48 @@ static void RecentArray_free(Array* self) {
/////////////////////////////////////// ///////////////////////////////////////
typedef struct Favorite {
char* path; // NOTE: this is without the SDCARD_PATH prefix!
int available;
} Favorite;
static Favorite* Favorite_new(char* path) {
Favorite* self = malloc(sizeof(Favorite));
char sd_path[256]; // only need to get emu name
sprintf(sd_path, "%s%s", SDCARD_PATH, path);
char emu_name[256];
getEmuName(sd_path, emu_name);
self->path = strdup(path);
self->available = hasEmu(emu_name);
return self;
}
static void Favorite_free(Favorite* self) {
free(self->path);
free(self);
}
static int FavoriteArray_indexOf(Array* self, char* str) {
for (int i=0; i<self->count; i++) {
Favorite* item = self->items[i];
if (exactMatch(item->path, str)) return i;
}
return -1;
}
static void FavoriteArray_free(Array* self) {
for (int i=0; i<self->count; i++) {
Favorite_free(self->items[i]);
}
Array_free(self);
}
///////////////////////////////////////
static Directory* top; static Directory* top;
static Array* stack; // DirectoryArray static Array* stack; // DirectoryArray
static Array* recents; // RecentArray static Array* recents; // RecentArray
static Array* favorites; // FavoriteArray
static int quit = 0; static int quit = 0;
static int can_resume = 0; static int can_resume = 0;
@ -397,6 +440,29 @@ static void addRecent(char* path) {
saveRecents(); saveRecents();
} }
static void saveFavorites(void) {
FILE* file = fopen(FAVORITE_PATH, "w");
if (file) {
for (int i=0; i<favorites->count; i++) {
Favorite* favorite = favorites->items[i];
fputs(favorite->path, file);
putc('\n', file);
}
fclose(file);
}
}
static void toggleFavorite(char* path) {
path += strlen(SDCARD_PATH); // makes paths platform agnostic
int id = FavoriteArray_indexOf(favorites, path);
if (id==-1) { // add
Array_unshift(favorites, Favorite_new(path));
}
else if (id>0) { // remove
// TODO: remove from favorite
}
saveFavorites();
}
static int hasEmu(char* emu_name) { static int hasEmu(char* emu_name) {
char pak_path[256]; char pak_path[256];
sprintf(pak_path, "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); sprintf(pak_path, "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name);
@ -506,7 +572,35 @@ static int hasRecents(void) {
saveRecents(); saveRecents();
StringArray_free(parent_paths); StringArray_free(parent_paths);
return has>0; //return has>0;
return 1; // Always show directory, even if empty.
}
static int hasFavorites(void) {
int has = 0;
FILE* file = fopen(FAVORITE_PATH, "r"); // newest at top
if (file) {
char line[256];
while (fgets(line,256,file)!=NULL) {
normalizeNewline(line);
trimTrailingNewlines(line);
if (strlen(line)==0) continue; // skip empty lines
char sd_path[256];
sprintf(sd_path, "%s%s", SDCARD_PATH, line);
if (exists(sd_path)) {
Favorite* favorite = Favorite_new(line);
if (favorite->available) has += 1;
Array_push(favorites, favorite);
}
}
fclose(file);
}
saveFavorites();
//return has>0;
return 1; // Always show directory, even if empty.
} }
static int hasCollections(void) { static int hasCollections(void) {
int has = 0; int has = 0;
@ -551,6 +645,7 @@ static Array* getRoot(void) {
Array* root = Array_new(); Array* root = Array_new();
if (hasRecents()) Array_push(root, Entry_new(FAUX_RECENT_PATH, ENTRY_DIR)); if (hasRecents()) Array_push(root, Entry_new(FAUX_RECENT_PATH, ENTRY_DIR));
if (hasFavorites()) Array_push(root, Entry_new(FAUX_FAVORITE_PATH, ENTRY_DIR));
DIR *dh; DIR *dh;
@ -637,6 +732,19 @@ static Array* getRecents(void) {
} }
return entries; return entries;
} }
static Array* getFavorites(void) {
Array* entries = Array_new();
for (int i=0; i<favorites->count; i++) {
Favorite* favorite = favorites->items[i];
if (!favorite->available) continue;
char sd_path[256];
sprintf(sd_path, "%s%s", SDCARD_PATH, favorite->path);
int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ???
Array_push(entries, Entry_new(sd_path, type));
}
return entries;
}
static Array* getCollection(char* path) { static Array* getCollection(char* path) {
Array* entries = Array_new(); Array* entries = Array_new();
FILE* file = fopen(path, "r"); FILE* file = fopen(path, "r");
@ -1075,6 +1183,8 @@ static void saveLast(char* path) {
// your most recently played game will always be at // your most recently played game will always be at
// the top which is also the default selection // the top which is also the default selection
path = FAUX_RECENT_PATH; path = FAUX_RECENT_PATH;
} else if (exactMatch(top->path, FAUX_FAVORITE_PATH)) {
path = FAUX_FAVORITE_PATH;
} }
putFile(LAST_PATH, path); putFile(LAST_PATH, path);
} }
@ -1145,12 +1255,14 @@ static void loadLast(void) { // call after loading root directory
static void Menu_init(void) { static void Menu_init(void) {
stack = Array_new(); // array of open Directories stack = Array_new(); // array of open Directories
recents = Array_new(); recents = Array_new();
favorites = Array_new();
openDirectory(SDCARD_PATH, 0); openDirectory(SDCARD_PATH, 0);
loadLast(); // restore state when available loadLast(); // restore state when available
} }
static void Menu_quit(void) { static void Menu_quit(void) {
RecentArray_free(recents); RecentArray_free(recents);
FavoriteArray_free(favorites);
DirectoryArray_free(stack); DirectoryArray_free(stack);
} }
@ -1316,6 +1428,13 @@ int main (int argc, char *argv[]) {
// can_resume = 0; // can_resume = 0;
if (total>0) readyResume(top->entries->items[top->selected]); if (total>0) readyResume(top->entries->items[top->selected]);
} }
else if (total>0 && PAD_justPressed(BTN_SELECT)) {
Entry* entry = top->entries->items[top->selected];
if (entry->type == ENTRY_ROM) {
toggleFavorite(entry->path);
dirty = 1;
}
}
} }
POW_update(&dirty, &show_setting, NULL, NULL); POW_update(&dirty, &show_setting, NULL, NULL);