mirror of
https://github.com/astronautlevel2/Anemone3DS.git
synced 2026-01-24 16:52:43 -05:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 730a0cd3d7 | |||
| fa37bcec99 | |||
| 1c3e8809f6 | |||
|
|
3dad4e2a67 | ||
|
|
403453c3fc | ||
| fe58e2d938 | |||
|
|
c28b794349 | ||
| d2b83659ea | |||
| 8189264908 | |||
| 5bb98a7fe2 | |||
| 305c55e6b2 | |||
| cb6f90adc7 | |||
| 7beb9b72db | |||
|
|
8e43bb1a74 | ||
| 4dbc71489f | |||
|
|
8022ed1682 | ||
| 5520ec2b2f | |||
| f2aa7420df | |||
| 05b56b1aa1 | |||
|
|
cac2450fde | ||
|
|
1c24d08eef | ||
|
|
24b12023ca | ||
|
|
9ccc705046 | ||
| 95d8808a73 | |||
|
|
6c2f09147f | ||
|
|
7b1d6f9860 | ||
|
|
6f7c2489d5 | ||
|
|
38e70df17b | ||
|
|
ad6117404f |
18
CONTRIBUTORS.md
Normal file
18
CONTRIBUTORS.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Main Contributors
|
||||||
|
* Alex Taber ([@astronautlevel2](https://github.com/astronautlevel2))
|
||||||
|
* [@LiquidFenrir](https://github.com/LiquidFenrir)
|
||||||
|
* Dawid Eckert ([@daedreth](https://github.com/daedreth))
|
||||||
|
* Dylan G. ([@helloman892](https://github.com/helloman892))
|
||||||
|
* Nils P. ([@ZetaDesigns](https://github.com/ZetaDesigns))
|
||||||
|
* Matt Kenny ([@mattkenster](https://github.com/mattkenster))
|
||||||
|
|
||||||
|
# Minor Contributors
|
||||||
|
* Nic ([@Wizzrobes](https://github.com/Wizzrobes))
|
||||||
|
* [@saibotu](https://github.com/saibotu)
|
||||||
|
* Jeremy Postelnek ([@TurtleP](https://github.com/TurtleP))
|
||||||
|
* [@FrozenChen](https://github.com/FrozenChen)
|
||||||
|
* Luís Marques ([@luigoalma](https://github.com/luigoalma))
|
||||||
|
* [@uyuiyu](https://github.com/uyuiyu)
|
||||||
|
* Guillaume Gérard ([@GreatWizard](https://github.com/GreatWizard))
|
||||||
|
* Joel ([@joel16](https://github.com/joel16))
|
||||||
|
* [@thedax](https://github.com/thedax)
|
||||||
6
Makefile
6
Makefile
@@ -12,7 +12,7 @@ include $(DEVKITARM)/3ds_rules
|
|||||||
# Your values.
|
# Your values.
|
||||||
APP_TITLE := Anemone3DS
|
APP_TITLE := Anemone3DS
|
||||||
APP_DESCRIPTION := A complete theming tool for the 3DS
|
APP_DESCRIPTION := A complete theming tool for the 3DS
|
||||||
APP_AUTHOR := astronautlevel and daedreth
|
APP_AUTHOR := Anemone3DS Team
|
||||||
|
|
||||||
|
|
||||||
TARGET := $(subst $e ,_,$(notdir $(APP_TITLE)))
|
TARGET := $(subst $e ,_,$(notdir $(APP_TITLE)))
|
||||||
@@ -55,7 +55,7 @@ CFLAGS := -g -Wall -Wextra -O2 -mword-relocations \
|
|||||||
|
|
||||||
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/')
|
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/')
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS -D_GNU_SOURCE -DVERSION="\"$(revision)\"" -DUSER_AGENT="\"$(APP_TITLE)/$(revision)\""
|
CFLAGS += $(INCLUDE) -DARM11 -D_3DS -D_GNU_SOURCE -DVERSION="\"$(revision)\"" -DUSER_AGENT="\"$(APP_TITLE)/$(revision)\"" -DAPP_TITLE="\"$(APP_TITLE)\""
|
||||||
ifneq ($(strip $(CITRA_MODE)),)
|
ifneq ($(strip $(CITRA_MODE)),)
|
||||||
CFLAGS += -DCITRA_MODE
|
CFLAGS += -DCITRA_MODE
|
||||||
endif
|
endif
|
||||||
@@ -65,7 +65,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS := -larchive -ljansson -lcitro3d -lctrud -lm -lz
|
LIBS := -lvorbisidec -logg -larchive -ljansson -lcitro3d -lctrud -lm -lz
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -4,31 +4,36 @@ A Theme and Splashscreen Manager for the Nintendo 3DS, written in C.\
|
|||||||
To-do list here: https://trello.com/b/F1YSa1VK
|
To-do list here: https://trello.com/b/F1YSa1VK
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
* zlib, jansson, and libarchive, which can be retrieved from the [3ds_portlibs](https://github.com/devkitPro/3ds_portlibs).
|
* devkitPro, which can be installed following the instructions [here](https://devkitpro.org/wiki/Getting_Started).
|
||||||
|
* zlib, jansson, libvorbisidec, and libarchive, which can be retrieved from [devkitPro pacman](https://devkitpro.org/viewtopic.php?f=13&t=8702).
|
||||||
|
* A recent build of [makerom](https://github.com/profi200/Project_CTR) and the latest release of [bannertool](https://github.com/Steveice10/bannertool). These must be added to your PATH.
|
||||||
|
A 64-bit Windows binary of makerom is available [here](https://hm892.s-ul.eu/U0Irkqih).
|
||||||
|
* ~~[pp2d](https://github.com/BernardoGiordano/pp2d), which is included in the repo if you do a git clone --recursive.~~
|
||||||
|
Due to circumstances surrounding the privacy settings on the pp2d repo, the source files are now included directly within the repo.
|
||||||
|
* Git needs to be on your PATH (this is usually only manual under Windows).
|
||||||
|
|
||||||
* [makerom](https://github.com/profi200/Project_CTR) and [bannertool](https://github.com/Steveice10/buildtools), which can be retrieved from [SteveIce10's](https://github.com/Steveice10) buildtools repo. These must be added to your PATH.
|
|
||||||
* ~~[pp2d](https://github.com/BernardoGiordano/pp2d), which is included in the repo if you do a git clone --recursive.~~ Due to circumstances surrounding the privacy settings on the pp2d repo, the source files are now included directly within the repo.
|
|
||||||
* Git needs to be on your PATH, if building in a non-*nix environment.
|
|
||||||
# Building
|
# Building
|
||||||
First of all, make sure devkitPRO is properly installed and added to the PATH.
|
First of all, make sure devkitPro is properly installed and added to your PATH.
|
||||||
After that, open the directory you want to clone the repo into, and type: `git clone https://github.com/astronautlevel2/Anemone3DS/ --recursive`.
|
After that, open the directory you want to clone the repo into, and execute
|
||||||
Instructions for installing zlib, jansson and libarchive can be found on the [3ds_portlibs repo](https://github.com/devkitPro/3ds_portlibs) (its easy, just run `make` and `make install-zlib`). After also adding [makerom](https://github.com/profi200/Project_CTR) and [bannertool](https://github.com/Steveice10/buildtools) to your PATH, just enter your directory and run `make`. All built files will be in `/out/`.
|
`git clone https://github.com/astronautlevel2/Anemone3DS` (or any other cloning method).
|
||||||
|
To install zlib, jansson and libarchive, begin by following the instructions found above ([here](https://devkitpro.org/viewtopic.php?f=13&t=8702)) on the devkitPro forums, and then install the dkP packages `3ds-zlib`, `3ds-jansson` and `3ds-libarchive`.
|
||||||
|
After also adding [makerom](https://github.com/profi200/Project_CTR) and [bannertool](https://github.com/Steveice10/buildtools) to your PATH, just enter your directory and run `make`. All built files will be in `/out/`.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
This project is licensed under the GNU GPLv3. See LICENSE.md for details. Additional terms 7b and 7c apply to this project.
|
This project is licensed under the GNU GPLv3. See LICENSE.md for details. Additional terms 7b and 7c apply to this project.
|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
The following people contributed to Anemone3DS in some way. Without these people, Anemone3DS wouldn't exist, or wouldn't be as good as it is:
|
The following people contributed to Anemone3DS in some way. Without these people, Anemone3DS wouldn't exist, or wouldn't be as good as it is: [CONTRIBUTORS.md](CONTRIBUTORS.md)
|
||||||
* [Daedreth](https://github.com/daedreth), who wrote the initial implementation of theme installation code and SMDH parsing.
|
|
||||||
* [LiquidFenrir](https://github.com/LiquidFenrir), who refactored a lot of my messy code and has been essential in development.
|
|
||||||
* [Kenn (mattkenster)](https://github.com/mattkenster), for designing the GUI, a number of sprites used in the application, and drawing the banner and icon.
|
|
||||||
|
|
||||||
Special thanks go to these people who, while not directly contributing, helped immensely:
|
Most of the icons under `romfs` are from the site [icons8.com](https://icons8.com) and are licensed under the [CC-BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/3.0/)
|
||||||
|
|
||||||
|
Special thanks go to these people who, whilst not directly contributing, helped immensely:
|
||||||
* [Rinnegatamante](https://github.com/Rinnegatamante), whose code served as reference on theme installation.
|
* [Rinnegatamante](https://github.com/Rinnegatamante), whose code served as reference on theme installation.
|
||||||
* [SteveIce10](https://github.com/SteveIce10), whose QR code in FBI was essential.
|
* [SteveIce10](https://github.com/SteveIce10), whose QR code in FBI was essential.
|
||||||
* [BernardoGiordano](https://github.com/BernardoGiordano) for making pp2d, and being super responsive to feature requests and just general help.
|
* [BernardoGiordano](https://github.com/BernardoGiordano) for making pp2d, and being super responsive to feature requests and just general help.
|
||||||
* [yellows8](https://github.com/yellows8) for his home menu extdump tool, which was invaluable in debugging.
|
* [yellows8](https://github.com/yellows8) for his home menu extdump tool, which was invaluable in debugging.
|
||||||
* the folks on #dev of Nintendo Homebrew, who helped with unicode shenanigans (especially [Stary2001](https://github.com/Stary2001), [Fenrir](https://github.com/FenrirWolf), and DanielKO).
|
* the folks on #dev of Nintendo Homebrew, who helped with unicode shenanigans (especially [Stary2001](https://github.com/Stary2001), [Fenrir](https://github.com/FenrirWolf), and DanielKO).
|
||||||
* the maintainers for all used libraries, including ctrulib, zlib, citro3d, pp2d, quirc and minizip.
|
* the maintainers for all used libraries, including but not limited to ctrulib, zlib, citro3d, pp2d, and quirc.
|
||||||
* all the people who helped keep me going and motivated me to work. This includes, but is definitely not limited to:
|
* all the people who helped keep me going and motivated me to work. This includes, but is definitely not limited to:
|
||||||
|
|
||||||
+ The members of the [Nintendo Homebrew Discord](https://discord.gg/C29hYvh)
|
+ The members of the [Nintendo Homebrew Discord](https://discord.gg/C29hYvh)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -60,8 +60,10 @@ enum TextureID {
|
|||||||
TEXTURE_ARROW,
|
TEXTURE_ARROW,
|
||||||
TEXTURE_ARROW_SIDE,
|
TEXTURE_ARROW_SIDE,
|
||||||
TEXTURE_SHUFFLE,
|
TEXTURE_SHUFFLE,
|
||||||
|
TEXTURE_SHUFFLE_NO_BGM,
|
||||||
TEXTURE_INSTALLED,
|
TEXTURE_INSTALLED,
|
||||||
TEXTURE_PREVIEW_ICON,
|
TEXTURE_PREVIEW_ICON,
|
||||||
|
TEXTURE_SORT,
|
||||||
TEXTURE_DOWNLOAD,
|
TEXTURE_DOWNLOAD,
|
||||||
TEXTURE_BROWSE,
|
TEXTURE_BROWSE,
|
||||||
TEXTURE_LIST,
|
TEXTURE_LIST,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -51,6 +51,7 @@ typedef enum {
|
|||||||
INSTALL_LOADING_REMOTE_THEMES,
|
INSTALL_LOADING_REMOTE_THEMES,
|
||||||
INSTALL_LOADING_REMOTE_SPLASHES,
|
INSTALL_LOADING_REMOTE_SPLASHES,
|
||||||
INSTALL_LOADING_REMOTE_PREVIEW,
|
INSTALL_LOADING_REMOTE_PREVIEW,
|
||||||
|
INSTALL_LOADING_REMOTE_BGM,
|
||||||
|
|
||||||
INSTALL_NONE,
|
INSTALL_NONE,
|
||||||
} InstallType;
|
} InstallType;
|
||||||
@@ -92,6 +93,7 @@ bool draw_confirm(const char* conf_msg, Entry_List_s* list);
|
|||||||
void draw_preview(ssize_t previewID, int preview_offset);
|
void draw_preview(ssize_t previewID, int preview_offset);
|
||||||
|
|
||||||
void draw_install(InstallType type);
|
void draw_install(InstallType type);
|
||||||
|
void draw_loading_bar(u32 current, u32 max, InstallType type);
|
||||||
|
|
||||||
void draw_base_interface(void);
|
void draw_base_interface(void);
|
||||||
void draw_grid_interface(Entry_List_s* list, Instructions_s instructions);
|
void draw_grid_interface(Entry_List_s* list, Instructions_s instructions);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -40,7 +40,7 @@ u32 file_to_buf(FS_Path path, FS_Archive archive, char** buf);
|
|||||||
u32 zip_memory_to_buf(char *file_name, void * zip_memory, size_t zip_size, char ** buf);
|
u32 zip_memory_to_buf(char *file_name, void * zip_memory, size_t zip_size, char ** buf);
|
||||||
u32 zip_file_to_buf(char *file_name, u16 *zip_path, char **buf);
|
u32 zip_file_to_buf(char *file_name, u16 *zip_path, char **buf);
|
||||||
|
|
||||||
Result buf_to_file(u32 size, char *path, FS_Archive archive, char *buf);
|
Result buf_to_file(u32 size, FS_Path path, FS_Archive archive, char *buf);
|
||||||
void remake_file(char *path, FS_Archive archive, u32 size);
|
void remake_file(FS_Path path, FS_Archive archive, u32 size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -98,16 +98,17 @@ Instructions_s install_instructions = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Instructions_s extra_instructions = {
|
Instructions_s extra_instructions[3] = {
|
||||||
.info_line = L"Release \uE002 to cancel or hold \uE006 and release \uE002 to do stuff",
|
{
|
||||||
|
.info_line = L"Release \uE002 to cancel or hold \uE006 and release \uE002 to sort",
|
||||||
.info_line_color = COLOR_WHITE,
|
.info_line_color = COLOR_WHITE,
|
||||||
.instructions = {
|
.instructions = {
|
||||||
{
|
{
|
||||||
L"\uE079 Jump in the list",
|
L"\uE079 Sort by name",
|
||||||
L"\uE07A Reload broken icons"
|
L"\uE07A Sort by author"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
L"\uE07B Browse ThemePlaza",
|
L"\uE07B Sort by filename",
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -119,6 +120,29 @@ Instructions_s extra_instructions = {
|
|||||||
NULL
|
NULL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.info_line = L"Release \uE002 to cancel or hold \uE006 and release \uE002 to do stuff",
|
||||||
|
.info_line_color = COLOR_WHITE,
|
||||||
|
.instructions = {
|
||||||
|
{
|
||||||
|
L"\uE079 Jump in the list",
|
||||||
|
L"\uE07A Reload broken icons"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\uE07B Browse ThemePlaza",
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\uE004 Sorting menu",
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"Exit",
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#define LOADING_H
|
#define LOADING_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "music.h"
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
enum ICON_IDS_OFFSET {
|
enum ICON_IDS_OFFSET {
|
||||||
@@ -38,6 +39,14 @@ enum ICON_IDS_OFFSET {
|
|||||||
ICONS_OFFSET_AMOUNT,
|
ICONS_OFFSET_AMOUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SORT_NONE,
|
||||||
|
|
||||||
|
SORT_NAME,
|
||||||
|
SORT_AUTHOR,
|
||||||
|
SORT_PATH,
|
||||||
|
} SortMode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 _padding1[4 + 2 + 2];
|
u8 _padding1[4 + 2 + 2];
|
||||||
|
|
||||||
@@ -62,6 +71,7 @@ typedef struct {
|
|||||||
bool is_zip;
|
bool is_zip;
|
||||||
|
|
||||||
bool in_shuffle;
|
bool in_shuffle;
|
||||||
|
bool no_bgm_shuffle;
|
||||||
bool installed;
|
bool installed;
|
||||||
|
|
||||||
json_int_t tp_download_id;
|
json_int_t tp_download_id;
|
||||||
@@ -88,6 +98,8 @@ typedef struct {
|
|||||||
int entries_loaded;
|
int entries_loaded;
|
||||||
int entry_size;
|
int entry_size;
|
||||||
|
|
||||||
|
SortMode current_sort;
|
||||||
|
|
||||||
json_int_t tp_current_page;
|
json_int_t tp_current_page;
|
||||||
json_int_t tp_page_count;
|
json_int_t tp_page_count;
|
||||||
char * tp_search;
|
char * tp_search;
|
||||||
@@ -98,9 +110,14 @@ typedef struct {
|
|||||||
volatile bool run_thread;
|
volatile bool run_thread;
|
||||||
} Thread_Arg_s;
|
} Thread_Arg_s;
|
||||||
|
|
||||||
|
void sort_by_name(Entry_List_s * list);
|
||||||
|
void sort_by_author(Entry_List_s * list);
|
||||||
|
void sort_by_filename(Entry_List_s * list);
|
||||||
|
|
||||||
void delete_entry(Entry_s * entry, bool is_file);
|
void delete_entry(Entry_s * entry, bool is_file);
|
||||||
Result load_entries(const char * loading_path, Entry_List_s * list);
|
Result load_entries(const char * loading_path, Entry_List_s * list);
|
||||||
bool load_preview(Entry_List_s list, int * preview_offset);
|
bool load_preview(Entry_List_s list, int * preview_offset);
|
||||||
|
Result load_audio(Entry_s, audio_s *);
|
||||||
void load_icons_first(Entry_List_s * current_list, bool silent);
|
void load_icons_first(Entry_List_s * current_list, bool silent);
|
||||||
void handle_scrolling(Entry_List_s * list);
|
void handle_scrolling(Entry_List_s * list);
|
||||||
void load_icons_thread(void * void_arg);
|
void load_icons_thread(void * void_arg);
|
||||||
|
|||||||
54
include/music.h
Normal file
54
include/music.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Anemone3DS
|
||||||
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MUSIC_H
|
||||||
|
#define MUSIC_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "unicode.h"
|
||||||
|
|
||||||
|
#include <tremor/ivorbisfile.h>
|
||||||
|
#include <tremor/ivorbiscodec.h>
|
||||||
|
|
||||||
|
#define BUF_TO_READ 40960 // How much data should be buffered at a time
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OggVorbis_File vf;
|
||||||
|
ndspWaveBuf wave_buf[2];
|
||||||
|
float mix[12];
|
||||||
|
u8 buf_pos;
|
||||||
|
long data_read;
|
||||||
|
char *filebuf;
|
||||||
|
u32 filesize;
|
||||||
|
|
||||||
|
volatile bool stop;
|
||||||
|
Handle finished;
|
||||||
|
} audio_s;
|
||||||
|
|
||||||
|
void play_audio(audio_s *);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#define REMOTE_H
|
#define REMOTE_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "draw.h"
|
||||||
|
|
||||||
#define THEMEPLAZA_BASE_URL "https://themeplaza.eu"
|
#define THEMEPLAZA_BASE_URL "https://themeplaza.eu"
|
||||||
#define THEMEPLAZA_API_URL "/api/anemone/v1"
|
#define THEMEPLAZA_API_URL "/api/anemone/v1"
|
||||||
@@ -41,17 +42,15 @@
|
|||||||
#define THEMEPLAZA_JSON_ERROR_MESSAGE_NOT_FOUND "No items found"
|
#define THEMEPLAZA_JSON_ERROR_MESSAGE_NOT_FOUND "No items found"
|
||||||
|
|
||||||
|
|
||||||
#define THEMEPLAZA_ENTRY_FORMAT THEMEPLAZA_BASE_API_URL "/query?item_id=%" JSON_INTEGER_FORMAT
|
|
||||||
#define THEMEPLAZA_JSON_ENTRY_NAME "title"
|
|
||||||
#define THEMEPLAZA_JSON_ENTRY_DESC "description"
|
|
||||||
#define THEMEPLAZA_JSON_ENTRY_AUTH "author"
|
|
||||||
|
|
||||||
#define THEMEPLAZA_DOWNLOAD_FORMAT THEMEPLAZA_BASE_URL "/download/%" JSON_INTEGER_FORMAT
|
#define THEMEPLAZA_DOWNLOAD_FORMAT THEMEPLAZA_BASE_URL "/download/%" JSON_INTEGER_FORMAT
|
||||||
#define THEMEPLAZA_PREVIEW_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/preview"
|
#define THEMEPLAZA_PREVIEW_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/preview"
|
||||||
#define THEMEPLAZA_BGM_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/bgm"
|
#define THEMEPLAZA_BGM_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/bgm"
|
||||||
#define THEMEPLAZA_ICON_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/preview/icon"
|
#define THEMEPLAZA_ICON_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/preview/icon"
|
||||||
|
#define THEMEPLAZA_SMDH_FORMAT THEMEPLAZA_DOWNLOAD_FORMAT "/smdh"
|
||||||
|
|
||||||
|
#define CACHE_PATH_FORMAT "/3ds/" APP_TITLE "/cache/%" JSON_INTEGER_FORMAT
|
||||||
|
|
||||||
bool themeplaza_browser(EntryMode mode);
|
bool themeplaza_browser(EntryMode mode);
|
||||||
u32 http_get(const char *url, char ** filename, char ** buf);
|
u32 http_get(const char *url, char ** filename, char ** buf, InstallType install_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
BIN
meta/logo.bin
BIN
meta/logo.bin
Binary file not shown.
BIN
romfs/shuffle_no_bgm.png
Normal file
BIN
romfs/shuffle_no_bgm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 511 B |
BIN
romfs/sort.png
Normal file
BIN
romfs/sort.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 291 B |
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -46,15 +46,16 @@ static u16 * camera_buf = NULL;
|
|||||||
|
|
||||||
void exit_qr(qr_data *data)
|
void exit_qr(qr_data *data)
|
||||||
{
|
{
|
||||||
|
DEBUG("Exiting QR\n");
|
||||||
svcSignalEvent(data->cancel);
|
svcSignalEvent(data->cancel);
|
||||||
while(!data->finished)
|
while(!data->finished)
|
||||||
svcSleepThread(1000000);
|
svcSleepThread(1000000);
|
||||||
|
svcCloseHandle(data->cancel);
|
||||||
data->capturing = false;
|
data->capturing = false;
|
||||||
|
|
||||||
free(data->camera_buffer);
|
free(data->camera_buffer);
|
||||||
free(data->texture_buffer);
|
free(data->texture_buffer);
|
||||||
quirc_destroy(data->context);
|
quirc_destroy(data->context);
|
||||||
free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void capture_cam_thread(void *arg)
|
void capture_cam_thread(void *arg)
|
||||||
@@ -87,6 +88,7 @@ void capture_cam_thread(void *arg)
|
|||||||
svcWaitSynchronizationN(&index, events, 3, false, U64_MAX);
|
svcWaitSynchronizationN(&index, events, 3, false, U64_MAX);
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
|
DEBUG("Cancel event received\n");
|
||||||
cancel = true;
|
cancel = true;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@@ -202,7 +204,7 @@ void update_qr(qr_data *data)
|
|||||||
draw_install(INSTALL_DOWNLOAD);
|
draw_install(INSTALL_DOWNLOAD);
|
||||||
char * zip_buf = NULL;
|
char * zip_buf = NULL;
|
||||||
char * filename = NULL;
|
char * filename = NULL;
|
||||||
u32 zip_size = http_get((char*)scan_data.payload, &filename, &zip_buf);
|
u32 zip_size = http_get((char*)scan_data.payload, &filename, &zip_buf, INSTALL_DOWNLOAD);
|
||||||
|
|
||||||
if(zip_size != 0)
|
if(zip_size != 0)
|
||||||
{
|
{
|
||||||
@@ -255,8 +257,8 @@ void update_qr(qr_data *data)
|
|||||||
if (extension == NULL || strcmp(extension, ".zip"))
|
if (extension == NULL || strcmp(extension, ".zip"))
|
||||||
strcat(path_to_file, ".zip");
|
strcat(path_to_file, ".zip");
|
||||||
|
|
||||||
remake_file(path_to_file, ArchiveSD, zip_size);
|
remake_file(fsMakePath(PATH_ASCII, path_to_file), ArchiveSD, zip_size);
|
||||||
buf_to_file(zip_size, path_to_file, ArchiveSD, zip_buf);
|
buf_to_file(zip_size, fsMakePath(PATH_ASCII, path_to_file), ArchiveSD, zip_buf);
|
||||||
data->success = true;
|
data->success = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -293,7 +295,8 @@ bool init_qr(void)
|
|||||||
data->texture_buffer = calloc(1, 400 * 240 * sizeof(u32));
|
data->texture_buffer = calloc(1, 400 * 240 * sizeof(u32));
|
||||||
|
|
||||||
while (!data->finished) update_qr(data);
|
while (!data->finished) update_qr(data);
|
||||||
|
bool success = data->success;
|
||||||
|
free(data);
|
||||||
|
|
||||||
return (bool)data->success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -42,9 +42,11 @@ void init_screens(void)
|
|||||||
pp2d_load_texture_png(TEXTURE_ARROW, "romfs:/arrow.png");
|
pp2d_load_texture_png(TEXTURE_ARROW, "romfs:/arrow.png");
|
||||||
pp2d_load_texture_png(TEXTURE_ARROW_SIDE, "romfs:/arrow_side.png");
|
pp2d_load_texture_png(TEXTURE_ARROW_SIDE, "romfs:/arrow_side.png");
|
||||||
pp2d_load_texture_png(TEXTURE_SHUFFLE, "romfs:/shuffle.png");
|
pp2d_load_texture_png(TEXTURE_SHUFFLE, "romfs:/shuffle.png");
|
||||||
|
pp2d_load_texture_png(TEXTURE_SHUFFLE_NO_BGM, "romfs:/shuffle_no_bgm.png");
|
||||||
pp2d_load_texture_png(TEXTURE_INSTALLED, "romfs:/installed.png");
|
pp2d_load_texture_png(TEXTURE_INSTALLED, "romfs:/installed.png");
|
||||||
pp2d_load_texture_png(TEXTURE_DOWNLOAD, "romfs:/download.png");
|
|
||||||
pp2d_load_texture_png(TEXTURE_PREVIEW_ICON, "romfs:/preview.png");
|
pp2d_load_texture_png(TEXTURE_PREVIEW_ICON, "romfs:/preview.png");
|
||||||
|
pp2d_load_texture_png(TEXTURE_SORT, "romfs:/sort.png");
|
||||||
|
pp2d_load_texture_png(TEXTURE_DOWNLOAD, "romfs:/download.png");
|
||||||
pp2d_load_texture_png(TEXTURE_BROWSE, "romfs:/browse.png");
|
pp2d_load_texture_png(TEXTURE_BROWSE, "romfs:/browse.png");
|
||||||
pp2d_load_texture_png(TEXTURE_LIST, "romfs:/list.png");
|
pp2d_load_texture_png(TEXTURE_LIST, "romfs:/list.png");
|
||||||
pp2d_load_texture_png(TEXTURE_EXIT, "romfs:/exit.png");
|
pp2d_load_texture_png(TEXTURE_EXIT, "romfs:/exit.png");
|
||||||
@@ -180,9 +182,8 @@ void draw_preview(ssize_t previewID, int preview_offset)
|
|||||||
pp2d_draw_texture_part(previewID, 0, 0, 40 + preview_offset, 240, 320, 240);
|
pp2d_draw_texture_part(previewID, 0, 0, 40 + preview_offset, 240, 320, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_install(InstallType type)
|
static void draw_install_handler(InstallType type)
|
||||||
{
|
{
|
||||||
draw_base_interface();
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case INSTALL_LOADING_THEMES:
|
case INSTALL_LOADING_THEMES:
|
||||||
@@ -203,6 +204,9 @@ void draw_install(InstallType type)
|
|||||||
case INSTALL_LOADING_REMOTE_PREVIEW:
|
case INSTALL_LOADING_REMOTE_PREVIEW:
|
||||||
pp2d_draw_text_center(GFX_TOP, 120, 0.8, 0.8, COLOR_WHITE, "Downloading preview, please wait...");
|
pp2d_draw_text_center(GFX_TOP, 120, 0.8, 0.8, COLOR_WHITE, "Downloading preview, please wait...");
|
||||||
break;
|
break;
|
||||||
|
case INSTALL_LOADING_REMOTE_BGM:
|
||||||
|
pp2d_draw_text_center(GFX_TOP, 120, 0.8, 0.8, COLOR_WHITE, "Downloading BGM, please wait...");
|
||||||
|
break;
|
||||||
case INSTALL_SINGLE:
|
case INSTALL_SINGLE:
|
||||||
pp2d_draw_text_center(GFX_TOP, 120, 0.8, 0.8, COLOR_WHITE, "Installing a single theme...");
|
pp2d_draw_text_center(GFX_TOP, 120, 0.8, 0.8, COLOR_WHITE, "Installing a single theme...");
|
||||||
break;
|
break;
|
||||||
@@ -233,6 +237,25 @@ void draw_install(InstallType type)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_install(InstallType type)
|
||||||
|
{
|
||||||
|
draw_base_interface();
|
||||||
|
draw_install_handler(type);
|
||||||
|
pp2d_end_draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_loading_bar(u32 current, u32 max, InstallType type)
|
||||||
|
{
|
||||||
|
draw_base_interface();
|
||||||
|
draw_install_handler(type);
|
||||||
|
pp2d_draw_on(GFX_BOTTOM, GFX_LEFT);
|
||||||
|
double percent = 100*((double)current/(double)max);
|
||||||
|
u32 width = (u32)percent;
|
||||||
|
width *= 2;
|
||||||
|
pp2d_draw_rectangle(60-1, 110-1, 200+2, 20+2, COLOR_CURSOR);
|
||||||
|
pp2d_draw_rectangle(60, 110, width, 20, COLOR_ACCENT);
|
||||||
pp2d_end_draw();
|
pp2d_end_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,10 +431,12 @@ void draw_interface(Entry_List_s* list, Instructions_s instructions)
|
|||||||
|
|
||||||
pp2d_draw_on(GFX_BOTTOM, GFX_LEFT);
|
pp2d_draw_on(GFX_BOTTOM, GFX_LEFT);
|
||||||
|
|
||||||
pp2d_draw_texture_blend(TEXTURE_EXIT, 320-120, 0, COLOR_WHITE);
|
pp2d_draw_texture_blend(TEXTURE_SORT, 320-144, 0, COLOR_WHITE);
|
||||||
pp2d_draw_texture_blend(TEXTURE_DOWNLOAD, 320-96, 0, COLOR_WHITE);
|
pp2d_draw_texture_blend(TEXTURE_DOWNLOAD, 320-120, 0, COLOR_WHITE);
|
||||||
for(int i = 0; i < MODE_AMOUNT; i++)
|
pp2d_draw_texture_blend(TEXTURE_BROWSE, 320-96, 0, COLOR_WHITE);
|
||||||
pp2d_draw_textf(320-(24*(i+1))+2.5, -3, 1, 1, COLOR_WHITE, "%c", mode_string[i][0]);
|
pp2d_draw_texture_blend(TEXTURE_EXIT, 320-72, 0, COLOR_WHITE);
|
||||||
|
pp2d_draw_texture_blend(TEXTURE_PREVIEW_ICON, 320-48, 0, COLOR_WHITE);
|
||||||
|
pp2d_draw_textf(320-24+2.5, -3, 1, 1, COLOR_WHITE, "%c", mode_string[!list->mode][0]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -433,6 +458,7 @@ void draw_interface(Entry_List_s* list, Instructions_s instructions)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pp2d_draw_texture_blend(TEXTURE_SORT, 320-144, 0, COLOR_WHITE);
|
||||||
pp2d_draw_texture_blend(TEXTURE_DOWNLOAD, 320-120, 0, COLOR_WHITE);
|
pp2d_draw_texture_blend(TEXTURE_DOWNLOAD, 320-120, 0, COLOR_WHITE);
|
||||||
pp2d_draw_texture_blend(TEXTURE_BROWSE, 320-96, 0, COLOR_WHITE);
|
pp2d_draw_texture_blend(TEXTURE_BROWSE, 320-96, 0, COLOR_WHITE);
|
||||||
pp2d_draw_texture_blend(TEXTURE_EXIT, 320-72, 0, COLOR_WHITE);
|
pp2d_draw_texture_blend(TEXTURE_EXIT, 320-72, 0, COLOR_WHITE);
|
||||||
@@ -471,8 +497,11 @@ void draw_interface(Entry_List_s* list, Instructions_s instructions)
|
|||||||
|
|
||||||
pp2d_draw_wtext(list->entry_size+6, vertical_offset + 16, 0.55, 0.55, font_color, name);
|
pp2d_draw_wtext(list->entry_size+6, vertical_offset + 16, 0.55, 0.55, font_color, name);
|
||||||
|
|
||||||
if(current_entry->in_shuffle)
|
if(current_entry->no_bgm_shuffle)
|
||||||
|
pp2d_draw_texture_blend(TEXTURE_SHUFFLE_NO_BGM, 320-24-4, vertical_offset, font_color);
|
||||||
|
else if(current_entry->in_shuffle)
|
||||||
pp2d_draw_texture_blend(TEXTURE_SHUFFLE, 320-24-4, vertical_offset, font_color);
|
pp2d_draw_texture_blend(TEXTURE_SHUFFLE, 320-24-4, vertical_offset, font_color);
|
||||||
|
|
||||||
if(current_entry->installed)
|
if(current_entry->installed)
|
||||||
pp2d_draw_texture_blend(TEXTURE_INSTALLED, 320-24-4, vertical_offset + 22, font_color);
|
pp2d_draw_texture_blend(TEXTURE_INSTALLED, 320-24-4, vertical_offset + 22, font_color);
|
||||||
|
|
||||||
|
|||||||
17
source/fs.c
17
source/fs.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -68,6 +68,9 @@ Result open_archives(void)
|
|||||||
|
|
||||||
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Themes"), FS_ATTRIBUTE_DIRECTORY);
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Themes"), FS_ATTRIBUTE_DIRECTORY);
|
||||||
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Splashes"), FS_ATTRIBUTE_DIRECTORY);
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Splashes"), FS_ATTRIBUTE_DIRECTORY);
|
||||||
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/3ds"), FS_ATTRIBUTE_DIRECTORY);
|
||||||
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/3ds/" APP_TITLE), FS_ATTRIBUTE_DIRECTORY);
|
||||||
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/3ds/" APP_TITLE "/cache"), FS_ATTRIBUTE_DIRECTORY);
|
||||||
|
|
||||||
u32 homeMenuPath[3] = {MEDIATYPE_SD, archive2, 0};
|
u32 homeMenuPath[3] = {MEDIATYPE_SD, archive2, 0};
|
||||||
home.type = PATH_BINARY;
|
home.type = PATH_BINARY;
|
||||||
@@ -178,23 +181,23 @@ u32 zip_file_to_buf(char *file_name, u16 *zip_path, char **buf)
|
|||||||
return zip_to_buf(a, file_name, buf);
|
return zip_to_buf(a, file_name, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result buf_to_file(u32 size, char *path, FS_Archive archive, char *buf)
|
Result buf_to_file(u32 size, FS_Path path, FS_Archive archive, char *buf)
|
||||||
{
|
{
|
||||||
Handle handle;
|
Handle handle;
|
||||||
Result res = 0;
|
Result res = 0;
|
||||||
if (R_FAILED(res = FSUSER_OpenFile(&handle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_WRITE, 0))) return res;
|
if (R_FAILED(res = FSUSER_OpenFile(&handle, archive, path, FS_OPEN_WRITE, 0))) return res;
|
||||||
if (R_FAILED(res = FSFILE_Write(handle, NULL, 0, buf, size, FS_WRITE_FLUSH))) return res;
|
if (R_FAILED(res = FSFILE_Write(handle, NULL, 0, buf, size, FS_WRITE_FLUSH))) return res;
|
||||||
if (R_FAILED(res = FSFILE_Close(handle))) return res;
|
if (R_FAILED(res = FSFILE_Close(handle))) return res;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remake_file(char *path, FS_Archive archive, u32 size)
|
void remake_file(FS_Path path, FS_Archive archive, u32 size)
|
||||||
{
|
{
|
||||||
Handle handle;
|
Handle handle;
|
||||||
if (R_SUCCEEDED(FSUSER_OpenFile(&handle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, 0)))
|
if (R_SUCCEEDED(FSUSER_OpenFile(&handle, archive, path, FS_OPEN_READ, 0)))
|
||||||
{
|
{
|
||||||
FSFILE_Close(handle);
|
FSFILE_Close(handle);
|
||||||
FSUSER_DeleteFile(archive, fsMakePath(PATH_ASCII, path));
|
FSUSER_DeleteFile(archive, path);
|
||||||
}
|
}
|
||||||
FSUSER_CreateFile(archive, fsMakePath(PATH_ASCII, path), 0, size);
|
FSUSER_CreateFile(archive, path, 0, size);
|
||||||
}
|
}
|
||||||
104
source/loading.c
104
source/loading.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "pp2d/pp2d/pp2d.h"
|
#include "pp2d/pp2d/pp2d.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
#include "music.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
void delete_entry(Entry_s * entry, bool is_file)
|
void delete_entry(Entry_s * entry, bool is_file)
|
||||||
@@ -104,20 +105,51 @@ static void load_smdh_icon(Entry_s entry, const ssize_t textureID)
|
|||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_entries(const void * a, const void * b)
|
typedef int (*sort_comparator)(const void *, const void *);
|
||||||
|
static int compare_entries_by_name(const void * a, const void * b)
|
||||||
{
|
{
|
||||||
Entry_s *entry_a = (Entry_s *)a;
|
Entry_s *entry_a = (Entry_s *)a;
|
||||||
Entry_s *entry_b = (Entry_s *)b;
|
Entry_s *entry_b = (Entry_s *)b;
|
||||||
|
|
||||||
return memcmp(entry_a->name, entry_b->name, 0x40*sizeof(u16));
|
return memcmp(entry_a->name, entry_b->name, 0x40*sizeof(u16));
|
||||||
}
|
}
|
||||||
|
static int compare_entries_by_author(const void * a, const void * b)
|
||||||
static void sort_list(Entry_List_s * list)
|
|
||||||
{
|
{
|
||||||
if(list->entries != NULL)
|
Entry_s *entry_a = (Entry_s *)a;
|
||||||
|
Entry_s *entry_b = (Entry_s *)b;
|
||||||
|
|
||||||
|
return memcmp(entry_a->author, entry_b->author, 0x40*sizeof(u16));
|
||||||
|
}
|
||||||
|
static int compare_entries_by_filename(const void * a, const void * b)
|
||||||
|
{
|
||||||
|
Entry_s *entry_a = (Entry_s *)a;
|
||||||
|
Entry_s *entry_b = (Entry_s *)b;
|
||||||
|
|
||||||
|
return memcmp(entry_a->path, entry_b->path, 0x106*sizeof(u16));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_list(Entry_List_s * list, sort_comparator compare_entries)
|
||||||
|
{
|
||||||
|
if(list->entries != NULL && list->entries != NULL)
|
||||||
qsort(list->entries, list->entries_count, sizeof(Entry_s), compare_entries); //alphabet sort
|
qsort(list->entries, list->entries_count, sizeof(Entry_s), compare_entries); //alphabet sort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sort_by_name(Entry_List_s * list)
|
||||||
|
{
|
||||||
|
sort_list(list, compare_entries_by_name);
|
||||||
|
list->current_sort = SORT_NAME;
|
||||||
|
}
|
||||||
|
void sort_by_author(Entry_List_s * list)
|
||||||
|
{
|
||||||
|
sort_list(list, compare_entries_by_author);
|
||||||
|
list->current_sort = SORT_AUTHOR;
|
||||||
|
}
|
||||||
|
void sort_by_filename(Entry_List_s * list)
|
||||||
|
{
|
||||||
|
sort_list(list, compare_entries_by_filename);
|
||||||
|
list->current_sort = SORT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
Result load_entries(const char * loading_path, Entry_List_s * list)
|
Result load_entries(const char * loading_path, Entry_List_s * list)
|
||||||
{
|
{
|
||||||
Handle dir_handle;
|
Handle dir_handle;
|
||||||
@@ -165,8 +197,6 @@ Result load_entries(const char * loading_path, Entry_List_s * list)
|
|||||||
|
|
||||||
FSDIR_Close(dir_handle);
|
FSDIR_Close(dir_handle);
|
||||||
|
|
||||||
sort_list(list);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +230,9 @@ void load_icons_first(Entry_List_s * list, bool silent)
|
|||||||
|
|
||||||
for(int i = starti; i < endi; i++, id++)
|
for(int i = starti; i < endi; i++, id++)
|
||||||
{
|
{
|
||||||
|
if(!silent)
|
||||||
|
draw_loading_bar(i - starti, endi-starti, INSTALL_LOADING_ICONS);
|
||||||
|
|
||||||
int offset = i;
|
int offset = i;
|
||||||
if(offset < 0)
|
if(offset < 0)
|
||||||
offset += list->entries_count;
|
offset += list->entries_count;
|
||||||
@@ -429,3 +462,60 @@ bool load_preview(Entry_List_s list, int * preview_offset)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the audio struct
|
||||||
|
Result load_audio(Entry_s entry, audio_s *audio)
|
||||||
|
{
|
||||||
|
audio->filesize = load_data("/bgm.ogg", entry, &audio->filebuf);
|
||||||
|
if (audio->filesize == 0) {
|
||||||
|
free(audio);
|
||||||
|
DEBUG("File not found!\n");
|
||||||
|
return MAKERESULT(RL_FATAL, RS_NOTFOUND, RM_APPLICATION, RD_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
audio->mix[0] = audio->mix[1] = 1.0f; // Determines volume for the 12 (?) different outputs. See http://smealum.github.io/ctrulib/channel_8h.html#a30eb26f1972cc3ec28370263796c0444
|
||||||
|
svcCreateEvent(&audio->finished, RESET_STICKY);
|
||||||
|
|
||||||
|
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
||||||
|
ndspChnSetMix(0, audio->mix); // See mix comment above
|
||||||
|
|
||||||
|
FILE *file = fmemopen(audio->filebuf, audio->filesize, "rb");
|
||||||
|
DEBUG("Filesize: %lld\n", audio->filesize);
|
||||||
|
if(file != NULL)
|
||||||
|
{
|
||||||
|
int e = ov_open(file, &audio->vf, NULL, 0);
|
||||||
|
if (e < 0)
|
||||||
|
{
|
||||||
|
DEBUG("Vorbis: %d\n", e);
|
||||||
|
free(audio->filebuf);
|
||||||
|
free(audio);
|
||||||
|
fclose(file);
|
||||||
|
return MAKERESULT(RL_FATAL, RS_INVALIDARG, RM_APPLICATION, RD_NO_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
vorbis_info *vi = ov_info(&audio->vf, -1);
|
||||||
|
ndspChnSetRate(0, vi->rate);// Set sample rate to what's read from the ogg file
|
||||||
|
if (vi->channels == 2) {
|
||||||
|
DEBUG("Using stereo\n");
|
||||||
|
ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); // 2 channels == Stereo
|
||||||
|
} else {
|
||||||
|
DEBUG("Invalid number of channels\n");
|
||||||
|
free(audio->filebuf);
|
||||||
|
free(audio);
|
||||||
|
fclose(file);
|
||||||
|
return MAKERESULT(RL_FATAL, RS_INVALIDARG, RM_APPLICATION, RD_NO_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
audio->wave_buf[0].nsamples = audio->wave_buf[1].nsamples = vi->rate / 4; // 4 bytes per sample, samples = rate (bytes) / 4
|
||||||
|
audio->wave_buf[0].status = audio->wave_buf[1].status = NDSP_WBUF_DONE; // Used in play to stop from writing to current buffer
|
||||||
|
audio->wave_buf[0].data_vaddr = linearAlloc(BUF_TO_READ); // Most vorbis packets should only be 4 KB at most (?) Possibly dangerous assumption
|
||||||
|
audio->wave_buf[1].data_vaddr = linearAlloc(BUF_TO_READ);
|
||||||
|
DEBUG("Success!\n");
|
||||||
|
return MAKERESULT(RL_SUCCESS, RS_SUCCESS, RM_APPLICATION, RD_SUCCESS);
|
||||||
|
} else {
|
||||||
|
free(audio->filebuf);
|
||||||
|
free(audio);
|
||||||
|
DEBUG("fmemopen failed!\n");
|
||||||
|
return MAKERESULT(RL_FATAL, RS_NOTFOUND, RM_APPLICATION, RD_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
125
source/main.c
125
source/main.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,12 +30,14 @@
|
|||||||
#include "splashes.h"
|
#include "splashes.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "music.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "instructions.h"
|
#include "instructions.h"
|
||||||
#include "pp2d/pp2d/pp2d.h"
|
#include "pp2d/pp2d/pp2d.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
|
audio_s * audio = NULL;
|
||||||
static bool homebrew = false;
|
static bool homebrew = false;
|
||||||
static bool installed_themes = false;
|
static bool installed_themes = false;
|
||||||
|
|
||||||
@@ -75,6 +77,7 @@ static void init_services(void)
|
|||||||
cfguInit();
|
cfguInit();
|
||||||
ptmuInit();
|
ptmuInit();
|
||||||
acInit();
|
acInit();
|
||||||
|
ndspInit();
|
||||||
APT_GetAppCpuTimeLimit(&old_time_limit);
|
APT_GetAppCpuTimeLimit(&old_time_limit);
|
||||||
APT_SetAppCpuTimeLimit(30);
|
APT_SetAppCpuTimeLimit(30);
|
||||||
httpcInit(0);
|
httpcInit(0);
|
||||||
@@ -95,6 +98,7 @@ static void exit_services(void)
|
|||||||
if (old_time_limit != UINT32_MAX) APT_SetAppCpuTimeLimit(old_time_limit);
|
if (old_time_limit != UINT32_MAX) APT_SetAppCpuTimeLimit(old_time_limit);
|
||||||
httpcExit();
|
httpcExit();
|
||||||
acExit();
|
acExit();
|
||||||
|
ndspExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_install_check(void)
|
static void stop_install_check(void)
|
||||||
@@ -132,6 +136,11 @@ void free_lists(void)
|
|||||||
|
|
||||||
void exit_function(bool power_pressed)
|
void exit_function(bool power_pressed)
|
||||||
{
|
{
|
||||||
|
if(audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
}
|
||||||
free_lists();
|
free_lists();
|
||||||
svcCloseHandle(update_icons_handle);
|
svcCloseHandle(update_icons_handle);
|
||||||
exit_screens();
|
exit_screens();
|
||||||
@@ -187,6 +196,8 @@ static void load_lists(Entry_List_s * lists)
|
|||||||
if(current_list->entries_count > current_list->entries_loaded*ICONS_OFFSET_AMOUNT)
|
if(current_list->entries_count > current_list->entries_loaded*ICONS_OFFSET_AMOUNT)
|
||||||
iconLoadingThread_arg.run_thread = true;
|
iconLoadingThread_arg.run_thread = true;
|
||||||
|
|
||||||
|
sort_by_name(current_list);
|
||||||
|
|
||||||
DEBUG("total: %i\n", current_list->entries_count);
|
DEBUG("total: %i\n", current_list->entries_count);
|
||||||
|
|
||||||
current_list->texture_id_offset = texture_id_offset;
|
current_list->texture_id_offset = texture_id_offset;
|
||||||
@@ -280,9 +291,24 @@ static void change_selected(Entry_List_s * list, int change_value)
|
|||||||
static void toggle_shuffle(Entry_List_s * list)
|
static void toggle_shuffle(Entry_List_s * list)
|
||||||
{
|
{
|
||||||
Entry_s * current_entry = &list->entries[list->selected_entry];
|
Entry_s * current_entry = &list->entries[list->selected_entry];
|
||||||
if(current_entry->in_shuffle) list->shuffle_count--;
|
if(current_entry->in_shuffle)
|
||||||
else list->shuffle_count++;
|
{
|
||||||
current_entry->in_shuffle = !current_entry->in_shuffle;
|
if(current_entry->no_bgm_shuffle)
|
||||||
|
{
|
||||||
|
current_entry->in_shuffle = false;
|
||||||
|
current_entry->no_bgm_shuffle = false;
|
||||||
|
list->shuffle_count--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_entry->no_bgm_shuffle = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_entry->in_shuffle = true;
|
||||||
|
list->shuffle_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
@@ -317,7 +343,7 @@ int main(void)
|
|||||||
bool install_mode = false;
|
bool install_mode = false;
|
||||||
bool extra_mode = false;
|
bool extra_mode = false;
|
||||||
|
|
||||||
while(aptMainLoop())
|
while(true)
|
||||||
{
|
{
|
||||||
if(quit)
|
if(quit)
|
||||||
{
|
{
|
||||||
@@ -345,10 +371,25 @@ int main(void)
|
|||||||
if(install_mode)
|
if(install_mode)
|
||||||
instructions = install_instructions;
|
instructions = install_instructions;
|
||||||
if(extra_mode)
|
if(extra_mode)
|
||||||
instructions = extra_instructions;
|
{
|
||||||
|
int index = 1;
|
||||||
|
bool key_l = (kDown | kHeld) & KEY_L;
|
||||||
|
bool key_r = (kDown | kHeld) & KEY_R;
|
||||||
|
if(key_l ^ key_r)
|
||||||
|
{
|
||||||
|
if(key_l)
|
||||||
|
index = 0;
|
||||||
|
// else if(key_r) // uncomment when we use the right menu. we don't for now
|
||||||
|
// index = 2;
|
||||||
|
}
|
||||||
|
instructions = extra_instructions[index];
|
||||||
|
}
|
||||||
|
|
||||||
if(qr_mode) take_picture();
|
if(qr_mode) take_picture();
|
||||||
else if(preview_mode) draw_preview(TEXTURE_PREVIEW, preview_offset);
|
else if(preview_mode)
|
||||||
|
{
|
||||||
|
draw_preview(TEXTURE_PREVIEW, preview_offset);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if(!iconLoadingThread_arg.run_thread)
|
if(!iconLoadingThread_arg.run_thread)
|
||||||
{
|
{
|
||||||
@@ -412,14 +453,37 @@ int main(void)
|
|||||||
{
|
{
|
||||||
toggle_preview:
|
toggle_preview:
|
||||||
if(!preview_mode)
|
if(!preview_mode)
|
||||||
|
{
|
||||||
preview_mode = load_preview(*current_list, &preview_offset);
|
preview_mode = load_preview(*current_list, &preview_offset);
|
||||||
|
if(current_mode == MODE_THEMES)
|
||||||
|
{
|
||||||
|
audio = calloc(1, sizeof(audio_s));
|
||||||
|
Result r = load_audio(current_list->entries[current_list->selected_entry], audio);
|
||||||
|
if (R_SUCCEEDED(r)) play_audio(audio);
|
||||||
|
else audio = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
|
if(current_mode == MODE_THEMES && audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(preview_mode && kDown & (KEY_B | KEY_TOUCH))
|
else if(preview_mode && kDown & (KEY_B | KEY_TOUCH))
|
||||||
{
|
{
|
||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
|
if(current_mode == MODE_THEMES && audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,6 +588,10 @@ int main(void)
|
|||||||
if(kUp & KEY_X)
|
if(kUp & KEY_X)
|
||||||
extra_mode = false;
|
extra_mode = false;
|
||||||
if(!extra_mode)
|
if(!extra_mode)
|
||||||
|
{
|
||||||
|
bool key_l = (kDown | kHeld) & KEY_L;
|
||||||
|
bool key_r = (kDown | kHeld) & KEY_R;
|
||||||
|
if(!(key_l ^ key_r))
|
||||||
{
|
{
|
||||||
if((kDown | kHeld) & KEY_DLEFT)
|
if((kDown | kHeld) & KEY_DLEFT)
|
||||||
{
|
{
|
||||||
@@ -539,16 +607,34 @@ int main(void)
|
|||||||
jump:
|
jump:
|
||||||
jump_menu(current_list);
|
jump_menu(current_list);
|
||||||
|
|
||||||
}
|
|
||||||
else if((kDown | kHeld) & KEY_DRIGHT)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if((kDown | kHeld) & KEY_DDOWN)
|
else if((kDown | kHeld) & KEY_DDOWN)
|
||||||
{
|
{
|
||||||
load_icons_first(current_list, false);
|
load_icons_first(current_list, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(key_l)
|
||||||
|
{
|
||||||
|
if((kDown | kHeld) & KEY_DLEFT)
|
||||||
|
{
|
||||||
|
sort_path:
|
||||||
|
sort_by_filename(current_list);
|
||||||
|
load_icons_first(current_list, false);
|
||||||
|
}
|
||||||
|
else if(((kDown | kHeld)) & KEY_DUP)
|
||||||
|
{
|
||||||
|
sort_name:
|
||||||
|
sort_by_name(current_list);
|
||||||
|
load_icons_first(current_list, false);
|
||||||
|
}
|
||||||
|
else if(((kDown | kHeld)) & KEY_DDOWN)
|
||||||
|
{
|
||||||
|
sort_author:
|
||||||
|
sort_by_author(current_list);
|
||||||
|
load_icons_first(current_list, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,6 +751,23 @@ int main(void)
|
|||||||
{
|
{
|
||||||
change_selected(current_list, -current_list->entries_per_screen_v);
|
change_selected(current_list, -current_list->entries_per_screen_v);
|
||||||
}
|
}
|
||||||
|
else if(BETWEEN(320-144, x, 320-120))
|
||||||
|
{
|
||||||
|
switch(current_list->current_sort)
|
||||||
|
{
|
||||||
|
case SORT_NAME:
|
||||||
|
goto sort_author;
|
||||||
|
break;
|
||||||
|
case SORT_AUTHOR:
|
||||||
|
goto sort_path;
|
||||||
|
break;
|
||||||
|
case SORT_PATH:
|
||||||
|
goto sort_name;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(BETWEEN(320-120, x, 320-96))
|
else if(BETWEEN(320-120, x, 320-96))
|
||||||
{
|
{
|
||||||
goto enable_qr;
|
goto enable_qr;
|
||||||
|
|||||||
85
source/music.c
Normal file
85
source/music.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Anemone3DS
|
||||||
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
|
*
|
||||||
|
* 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 "music.h"
|
||||||
|
#include "loading.h"
|
||||||
|
|
||||||
|
// Play a given audio struct
|
||||||
|
Result update_audio(audio_s *audio)
|
||||||
|
{
|
||||||
|
long size = BUF_TO_READ - audio->data_read;
|
||||||
|
DEBUG("Audio Size: %ld\n", size);
|
||||||
|
if (audio->wave_buf[audio->buf_pos].status == NDSP_WBUF_DONE) // only run if the current selected buffer has already finished playing
|
||||||
|
{
|
||||||
|
DEBUG("Attempting ov_read\n");
|
||||||
|
int bitstream;
|
||||||
|
size_t read = ov_read(&audio->vf, (char*)audio->wave_buf[audio->buf_pos].data_vaddr + audio->data_read, size, &bitstream); // read 1 vorbis packet into wave buffer
|
||||||
|
DEBUG("ov_read successful\n");
|
||||||
|
|
||||||
|
if (read <= 0) // EoF or error
|
||||||
|
{
|
||||||
|
ov_clear(&audio->vf);
|
||||||
|
if (read == 0) // EoF
|
||||||
|
{
|
||||||
|
ov_open(fmemopen(audio->filebuf, audio->filesize, "rb"), &audio->vf, NULL, 0); // Reopen file. Don't need to reinit channel stuff since it's all the same as before
|
||||||
|
} else // Error :(
|
||||||
|
{
|
||||||
|
DEBUG("Vorbis play error: %d\n", read);
|
||||||
|
ndspChnReset(0);
|
||||||
|
return MAKERESULT(RL_FATAL, RS_INVALIDARG, RM_APPLICATION, RD_NO_DATA);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
audio->data_read += read;
|
||||||
|
if (read == size) {
|
||||||
|
audio->data_read = 0;
|
||||||
|
ndspChnWaveBufAdd(0, &audio->wave_buf[audio->buf_pos]); // Add buffer to ndsp
|
||||||
|
audio->buf_pos = 1 - audio->buf_pos; // switch to other buffer to load and prepare it while the current one is playing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MAKERESULT(RL_SUCCESS, RS_SUCCESS, RM_APPLICATION, RD_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_audio(void* data) {
|
||||||
|
audio_s *audio = (audio_s*)data;
|
||||||
|
while(!audio->stop) {
|
||||||
|
update_audio(audio);
|
||||||
|
}
|
||||||
|
free(audio->filebuf);
|
||||||
|
ov_clear(&audio->vf);
|
||||||
|
linearFree(audio->wave_buf[0].data_vaddr);
|
||||||
|
linearFree(audio->wave_buf[1].data_vaddr);
|
||||||
|
while (audio->wave_buf[0].status != NDSP_WBUF_DONE || audio->wave_buf[1].status != NDSP_WBUF_DONE) svcSleepThread(1e7);
|
||||||
|
svcSignalEvent(audio->finished);
|
||||||
|
svcSleepThread(1e8);
|
||||||
|
svcCloseHandle(audio->finished);
|
||||||
|
free(audio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void play_audio(audio_s *audio) {
|
||||||
|
threadCreate(thread_audio, audio, 0x1000, 0x3F, 1, true);
|
||||||
|
}
|
||||||
273
source/remote.c
273
source/remote.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,8 +26,9 @@
|
|||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "loading.h"
|
#include "loading.h"
|
||||||
#include "draw.h"
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include "unicode.h"
|
||||||
|
#include "music.h"
|
||||||
#include "pp2d/pp2d/pp2d.h"
|
#include "pp2d/pp2d/pp2d.h"
|
||||||
|
|
||||||
static Instructions_s browser_instructions[MODE_AMOUNT] = {
|
static Instructions_s browser_instructions[MODE_AMOUNT] = {
|
||||||
@@ -85,7 +86,7 @@ static Instructions_s extra_instructions = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
L"\uE07B Toggle splash/theme",
|
L"\uE07B Toggle splash/theme",
|
||||||
NULL
|
L"\uE07C Reload without cache"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
@@ -98,60 +99,71 @@ static Instructions_s extra_instructions = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void load_remote_entry(Entry_s * entry)
|
static void load_remote_smdh(Entry_s * entry, size_t textureID, bool ignore_cache)
|
||||||
{
|
{
|
||||||
char * entry_json = NULL;
|
bool not_cached = true;
|
||||||
|
char * smdh_buf = NULL;
|
||||||
|
u32 smdh_size = load_data("/info.smdh", *entry, &smdh_buf);
|
||||||
|
Icon_s * smdh = (Icon_s *)smdh_buf;
|
||||||
|
|
||||||
|
not_cached = !smdh_size || ignore_cache; // if the size is 0, the file wasn't there
|
||||||
|
|
||||||
|
if(not_cached)
|
||||||
|
{
|
||||||
|
free(smdh_buf);
|
||||||
|
smdh_buf = NULL;
|
||||||
char * api_url = NULL;
|
char * api_url = NULL;
|
||||||
asprintf(&api_url, THEMEPLAZA_ENTRY_FORMAT, entry->tp_download_id);
|
asprintf(&api_url, THEMEPLAZA_SMDH_FORMAT, entry->tp_download_id);
|
||||||
u32 json_len = http_get(api_url, NULL, &entry_json);
|
smdh_size = http_get(api_url, NULL, &smdh_buf, INSTALL_NONE);
|
||||||
free(api_url);
|
free(api_url);
|
||||||
|
smdh = (Icon_s *)smdh_buf;
|
||||||
if(json_len)
|
|
||||||
{
|
|
||||||
json_error_t error;
|
|
||||||
json_t *root = json_loadb(entry_json, json_len, 0, &error);
|
|
||||||
if(root)
|
|
||||||
{
|
|
||||||
const char *key;
|
|
||||||
json_t *value;
|
|
||||||
json_object_foreach(root, key, value)
|
|
||||||
{
|
|
||||||
if(json_is_string(value))
|
|
||||||
{
|
|
||||||
if(!strcmp(key, THEMEPLAZA_JSON_ENTRY_NAME))
|
|
||||||
{
|
|
||||||
utf8_to_utf16(entry->name, (u8*)json_string_value(value), 0x40);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(!strcmp(key, THEMEPLAZA_JSON_ENTRY_DESC))
|
|
||||||
utf8_to_utf16(entry->desc, (u8*)json_string_value(value), 0x80);
|
|
||||||
else if(!strcmp(key, THEMEPLAZA_JSON_ENTRY_AUTH))
|
|
||||||
utf8_to_utf16(entry->author, (u8*)json_string_value(value), 0x40);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DEBUG("json error on line %d: %s\n", error.line, error.text);
|
|
||||||
|
|
||||||
json_decref(root);
|
|
||||||
}
|
|
||||||
free(entry_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_remote_icon(size_t textureID, json_int_t id)
|
if(!smdh_size)
|
||||||
{
|
{
|
||||||
char * icon_data = NULL;
|
free(smdh_buf);
|
||||||
char * icon_url = NULL;
|
utf8_to_utf16(entry->name, (u8*)"No name", 0x80);
|
||||||
asprintf(&icon_url, THEMEPLAZA_ICON_FORMAT, id);
|
utf8_to_utf16(entry->desc, (u8*)"No description", 0x100);
|
||||||
u32 icon_size = http_get(icon_url, NULL, &icon_data);
|
utf8_to_utf16(entry->author, (u8*)"Unknown author", 0x80);
|
||||||
free(icon_url);
|
entry->placeholder_color = RGBA8(rand() % 255, rand() % 255, rand() % 255, 255);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(entry->name, smdh->name, 0x40*sizeof(u16));
|
||||||
|
memcpy(entry->desc, smdh->desc, 0x80*sizeof(u16));
|
||||||
|
memcpy(entry->author, smdh->author, 0x40*sizeof(u16));
|
||||||
|
|
||||||
|
const u32 width = 48, height = 48;
|
||||||
|
u32 *image = malloc(width*height*sizeof(u32));
|
||||||
|
|
||||||
|
for(u32 x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
for(u32 y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
unsigned int dest_pixel = (x + y*width);
|
||||||
|
unsigned int source_pixel = (((y >> 3) * (width >> 3) + (x >> 3)) << 6) + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3));
|
||||||
|
|
||||||
|
image[dest_pixel] = RGB565_TO_ABGR8(smdh->big_icon[source_pixel]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pp2d_free_texture(textureID);
|
pp2d_free_texture(textureID);
|
||||||
pp2d_load_texture_png_memory(textureID, icon_data, icon_size);
|
pp2d_load_texture_memory(textureID, (u8*)image, (u32)width, (u32)height);
|
||||||
free(icon_data);
|
free(image);
|
||||||
|
|
||||||
|
if(not_cached)
|
||||||
|
{
|
||||||
|
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_UTF16, entry->path), FS_ATTRIBUTE_DIRECTORY);
|
||||||
|
u16 path[0x107] = {0};
|
||||||
|
strucat(path, entry->path);
|
||||||
|
struacat(path, "/info.smdh");
|
||||||
|
remake_file(fsMakePath(PATH_UTF16, path), ArchiveSD, smdh_size);
|
||||||
|
buf_to_file(smdh_size, fsMakePath(PATH_UTF16, path), ArchiveSD, smdh_buf);
|
||||||
|
}
|
||||||
|
free(smdh_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_remote_entries(Entry_List_s * list, json_t *ids_array)
|
static void load_remote_entries(Entry_List_s * list, json_t *ids_array, bool ignore_cache, InstallType type)
|
||||||
{
|
{
|
||||||
list->entries_count = json_array_size(ids_array);
|
list->entries_count = json_array_size(ids_array);
|
||||||
free(list->entries);
|
free(list->entries);
|
||||||
@@ -164,18 +176,23 @@ static void load_remote_entries(Entry_List_s * list, json_t *ids_array)
|
|||||||
json_t * id = NULL;
|
json_t * id = NULL;
|
||||||
json_array_foreach(ids_array, i, id)
|
json_array_foreach(ids_array, i, id)
|
||||||
{
|
{
|
||||||
|
draw_loading_bar(i, list->entries_count, type);
|
||||||
size_t offset = i;
|
size_t offset = i;
|
||||||
Entry_s * current_entry = &list->entries[offset];
|
Entry_s * current_entry = &list->entries[offset];
|
||||||
current_entry->tp_download_id = json_integer_value(id);
|
current_entry->tp_download_id = json_integer_value(id);
|
||||||
load_remote_entry(current_entry);
|
|
||||||
|
|
||||||
size_t textureID = list->texture_id_offset + i;
|
size_t textureID = list->texture_id_offset + i;
|
||||||
load_remote_icon(textureID, current_entry->tp_download_id);
|
|
||||||
|
char * entry_path = NULL;
|
||||||
|
asprintf(&entry_path, CACHE_PATH_FORMAT, current_entry->tp_download_id);
|
||||||
|
utf8_to_utf16(current_entry->path, (u8*)entry_path, 0x106);
|
||||||
|
free(entry_path);
|
||||||
|
|
||||||
|
load_remote_smdh(current_entry, textureID, ignore_cache);
|
||||||
list->icons_ids[offset] = textureID;
|
list->icons_ids[offset] = textureID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mode)
|
static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mode, bool ignore_cache)
|
||||||
{
|
{
|
||||||
if(page > list->tp_page_count)
|
if(page > list->tp_page_count)
|
||||||
page = 1;
|
page = 1;
|
||||||
@@ -192,7 +209,7 @@ static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mod
|
|||||||
char * page_json = NULL;
|
char * page_json = NULL;
|
||||||
char * api_url = NULL;
|
char * api_url = NULL;
|
||||||
asprintf(&api_url, THEMEPLAZA_PAGE_FORMAT, page, mode+1, list->tp_search);
|
asprintf(&api_url, THEMEPLAZA_PAGE_FORMAT, page, mode+1, list->tp_search);
|
||||||
u32 json_len = http_get(api_url, NULL, &page_json);
|
u32 json_len = http_get(api_url, NULL, &page_json, INSTALL_NONE);
|
||||||
free(api_url);
|
free(api_url);
|
||||||
|
|
||||||
if(json_len)
|
if(json_len)
|
||||||
@@ -215,7 +232,7 @@ static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mod
|
|||||||
if(json_is_integer(value) && !strcmp(key, THEMEPLAZA_JSON_PAGE_COUNT))
|
if(json_is_integer(value) && !strcmp(key, THEMEPLAZA_JSON_PAGE_COUNT))
|
||||||
list->tp_page_count = json_integer_value(value);
|
list->tp_page_count = json_integer_value(value);
|
||||||
else if(json_is_array(value) && !strcmp(key, THEMEPLAZA_JSON_PAGE_IDS))
|
else if(json_is_array(value) && !strcmp(key, THEMEPLAZA_JSON_PAGE_IDS))
|
||||||
load_remote_entries(list, value);
|
load_remote_entries(list, value, ignore_cache, loading_screen);
|
||||||
else if(json_is_string(value) && !strcmp(key, THEMEPLAZA_JSON_ERROR_MESSAGE) && !strcmp(json_string_value(value), THEMEPLAZA_JSON_ERROR_MESSAGE_NOT_FOUND))
|
else if(json_is_string(value) && !strcmp(key, THEMEPLAZA_JSON_ERROR_MESSAGE) && !strcmp(json_string_value(value), THEMEPLAZA_JSON_ERROR_MESSAGE_NOT_FOUND))
|
||||||
throw_error("No results for this search.", ERROR_LEVEL_WARNING);
|
throw_error("No results for this search.", ERROR_LEVEL_WARNING);
|
||||||
}
|
}
|
||||||
@@ -231,22 +248,31 @@ static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mod
|
|||||||
free(page_json);
|
free(page_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char previous_preview_url[0x100] = {0};
|
static u16 previous_path_preview[0x106] = {0};
|
||||||
static bool load_remote_preview(Entry_List_s list, int * preview_offset)
|
static bool load_remote_preview(Entry_s * entry, int * preview_offset)
|
||||||
{
|
{
|
||||||
Entry_s entry = list.entries[list.selected_entry];
|
bool not_cached = true;
|
||||||
|
|
||||||
|
if(!memcmp(&previous_path_preview, entry->path, 0x106*sizeof(u16))) return true;
|
||||||
|
|
||||||
|
char * preview_png = NULL;
|
||||||
|
u32 preview_size = load_data("/preview.png", *entry, &preview_png);
|
||||||
|
|
||||||
|
not_cached = !preview_size;
|
||||||
|
|
||||||
|
if(not_cached)
|
||||||
|
{
|
||||||
|
free(preview_png);
|
||||||
|
preview_png = NULL;
|
||||||
|
|
||||||
char * preview_url = NULL;
|
char * preview_url = NULL;
|
||||||
asprintf(&preview_url, THEMEPLAZA_PREVIEW_FORMAT, entry.tp_download_id);
|
asprintf(&preview_url, THEMEPLAZA_PREVIEW_FORMAT, entry->tp_download_id);
|
||||||
if(!strncmp(previous_preview_url, preview_url, 0x100))
|
|
||||||
{
|
|
||||||
free(preview_url);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_install(INSTALL_LOADING_REMOTE_PREVIEW);
|
draw_install(INSTALL_LOADING_REMOTE_PREVIEW);
|
||||||
char * preview_png = NULL;
|
|
||||||
u32 preview_size = http_get(preview_url, NULL, &preview_png);
|
preview_size = http_get(preview_url, NULL, &preview_png, INSTALL_LOADING_REMOTE_PREVIEW);
|
||||||
|
free(preview_url);
|
||||||
|
}
|
||||||
|
|
||||||
if(!preview_size)
|
if(!preview_size)
|
||||||
{
|
{
|
||||||
@@ -270,7 +296,7 @@ static bool load_remote_preview(Entry_List_s list, int * preview_offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mark the new preview as loaded for optimisation
|
// mark the new preview as loaded for optimisation
|
||||||
strncpy(previous_preview_url, preview_url, 0x100);
|
memcpy(&previous_path_preview, entry->path, 0x106*sizeof(u16));
|
||||||
// free the previously loaded preview. wont do anything if there wasnt one
|
// free the previously loaded preview. wont do anything if there wasnt one
|
||||||
pp2d_free_texture(TEXTURE_REMOTE_PREVIEW);
|
pp2d_free_texture(TEXTURE_REMOTE_PREVIEW);
|
||||||
|
|
||||||
@@ -285,12 +311,53 @@ static bool load_remote_preview(Entry_List_s list, int * preview_offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(image);
|
free(image);
|
||||||
free(preview_url);
|
|
||||||
|
if(not_cached)
|
||||||
|
{
|
||||||
|
u16 path[0x107] = {0};
|
||||||
|
strucat(path, entry->path);
|
||||||
|
struacat(path, "/preview.png");
|
||||||
|
remake_file(fsMakePath(PATH_UTF16, path), ArchiveSD, preview_size);
|
||||||
|
buf_to_file(preview_size, fsMakePath(PATH_UTF16, path), ArchiveSD, preview_png);
|
||||||
|
}
|
||||||
free(preview_png);
|
free(preview_png);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u16 previous_path_bgm[0x106] = {0};
|
||||||
|
static void load_remote_bgm(Entry_s * entry)
|
||||||
|
{
|
||||||
|
if(!memcmp(&previous_path_bgm, entry->path, 0x106*sizeof(u16))) return;
|
||||||
|
|
||||||
|
char * bgm_ogg = NULL;
|
||||||
|
u32 bgm_size = load_data("/bgm.ogg", *entry, &bgm_ogg);
|
||||||
|
|
||||||
|
if(!bgm_size)
|
||||||
|
{
|
||||||
|
free(bgm_ogg);
|
||||||
|
bgm_ogg = NULL;
|
||||||
|
|
||||||
|
char * bgm_url = NULL;
|
||||||
|
asprintf(&bgm_url, THEMEPLAZA_BGM_FORMAT, entry->tp_download_id);
|
||||||
|
|
||||||
|
draw_install(INSTALL_LOADING_REMOTE_BGM);
|
||||||
|
|
||||||
|
bgm_size = http_get(bgm_url, NULL, &bgm_ogg, INSTALL_LOADING_REMOTE_BGM);
|
||||||
|
free(bgm_url);
|
||||||
|
|
||||||
|
u16 path[0x107] = {0};
|
||||||
|
strucat(path, entry->path);
|
||||||
|
struacat(path, "/bgm.ogg");
|
||||||
|
remake_file(fsMakePath(PATH_UTF16, path), ArchiveSD, bgm_size);
|
||||||
|
buf_to_file(bgm_size, fsMakePath(PATH_UTF16, path), ArchiveSD, bgm_ogg);
|
||||||
|
|
||||||
|
memcpy(&previous_path_bgm, entry->path, 0x106*sizeof(u16));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(bgm_ogg);
|
||||||
|
}
|
||||||
|
|
||||||
static void download_remote_entry(Entry_s * entry, EntryMode mode)
|
static void download_remote_entry(Entry_s * entry, EntryMode mode)
|
||||||
{
|
{
|
||||||
char * download_url = NULL;
|
char * download_url = NULL;
|
||||||
@@ -299,7 +366,7 @@ static void download_remote_entry(Entry_s * entry, EntryMode mode)
|
|||||||
char * zip_buf = NULL;
|
char * zip_buf = NULL;
|
||||||
char * filename = NULL;
|
char * filename = NULL;
|
||||||
draw_install(INSTALL_DOWNLOAD);
|
draw_install(INSTALL_DOWNLOAD);
|
||||||
u32 zip_size = http_get(download_url, &filename, &zip_buf);
|
u32 zip_size = http_get(download_url, &filename, &zip_buf, INSTALL_DOWNLOAD);
|
||||||
free(download_url);
|
free(download_url);
|
||||||
|
|
||||||
char path_to_file[0x107] = {0};
|
char path_to_file[0x107] = {0};
|
||||||
@@ -311,8 +378,8 @@ static void download_remote_entry(Entry_s * entry, EntryMode mode)
|
|||||||
strcat(path_to_file, ".zip");
|
strcat(path_to_file, ".zip");
|
||||||
|
|
||||||
DEBUG("Saving to sd: %s\n", path_to_file);
|
DEBUG("Saving to sd: %s\n", path_to_file);
|
||||||
remake_file(path_to_file, ArchiveSD, zip_size);
|
remake_file(fsMakePath(PATH_ASCII, path_to_file), ArchiveSD, zip_size);
|
||||||
buf_to_file(zip_size, path_to_file, ArchiveSD, zip_buf);
|
buf_to_file(zip_size, fsMakePath(PATH_ASCII, path_to_file), ArchiveSD, zip_buf);
|
||||||
free(zip_buf);
|
free(zip_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +428,7 @@ static void jump_menu(Entry_List_s * list)
|
|||||||
{
|
{
|
||||||
json_int_t newpage = (json_int_t)atoi(numbuf);
|
json_int_t newpage = (json_int_t)atoi(numbuf);
|
||||||
if(newpage != list->tp_current_page)
|
if(newpage != list->tp_current_page)
|
||||||
load_remote_list(list, newpage, list->mode);
|
load_remote_list(list, newpage, list->mode, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +456,7 @@ static void search_menu(Entry_List_s * list)
|
|||||||
search[i] = '+';
|
search[i] = '+';
|
||||||
}
|
}
|
||||||
list->tp_search = search;
|
list->tp_search = search;
|
||||||
load_remote_list(list, 1, list->mode);
|
load_remote_list(list, 1, list->mode, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -425,11 +492,12 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
|
|
||||||
bool preview_mode = false;
|
bool preview_mode = false;
|
||||||
int preview_offset = 0;
|
int preview_offset = 0;
|
||||||
|
audio_s * audio = NULL;
|
||||||
|
|
||||||
Entry_List_s list = {0};
|
Entry_List_s list = {0};
|
||||||
Entry_List_s * current_list = &list;
|
Entry_List_s * current_list = &list;
|
||||||
current_list->tp_search = strdup("");
|
current_list->tp_search = strdup("");
|
||||||
load_remote_list(current_list, 1, mode);
|
load_remote_list(current_list, 1, mode, false);
|
||||||
|
|
||||||
bool extra_mode = false;
|
bool extra_mode = false;
|
||||||
|
|
||||||
@@ -454,13 +522,17 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
u32 kHeld = hidKeysHeld();
|
u32 kHeld = hidKeysHeld();
|
||||||
u32 kUp = hidKeysUp();
|
u32 kUp = hidKeysUp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(kDown & KEY_START)
|
if(kDown & KEY_START)
|
||||||
{
|
{
|
||||||
exit:
|
exit:
|
||||||
quit = true;
|
quit = true;
|
||||||
downloaded = false;
|
downloaded = false;
|
||||||
|
if(audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +551,7 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
free(current_list->tp_search);
|
free(current_list->tp_search);
|
||||||
current_list->tp_search = strdup("");
|
current_list->tp_search = strdup("");
|
||||||
|
|
||||||
load_remote_list(current_list, 1, mode);
|
load_remote_list(current_list, 1, mode, false);
|
||||||
}
|
}
|
||||||
else if((kDown | kHeld) & KEY_DUP)
|
else if((kDown | kHeld) & KEY_DUP)
|
||||||
{
|
{
|
||||||
@@ -487,7 +559,7 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
}
|
}
|
||||||
else if((kDown | kHeld) & KEY_DRIGHT)
|
else if((kDown | kHeld) & KEY_DRIGHT)
|
||||||
{
|
{
|
||||||
|
load_remote_list(current_list, current_list->tp_current_page, mode, true);
|
||||||
}
|
}
|
||||||
else if((kDown | kHeld) & KEY_DDOWN)
|
else if((kDown | kHeld) & KEY_DDOWN)
|
||||||
{
|
{
|
||||||
@@ -504,14 +576,39 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
{
|
{
|
||||||
toggle_preview:
|
toggle_preview:
|
||||||
if(!preview_mode)
|
if(!preview_mode)
|
||||||
preview_mode = load_remote_preview(*current_list, &preview_offset);
|
{
|
||||||
|
preview_mode = load_remote_preview(current_entry, &preview_offset);
|
||||||
|
if(mode == MODE_THEMES)
|
||||||
|
{
|
||||||
|
load_remote_bgm(current_entry);
|
||||||
|
audio = calloc(1, sizeof(audio_s));
|
||||||
|
load_audio(*current_entry, audio);
|
||||||
|
play_audio(audio);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
|
if(mode == MODE_THEMES && audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(kDown & KEY_B)
|
else if(kDown & KEY_B)
|
||||||
{
|
{
|
||||||
if(preview_mode)
|
if(preview_mode)
|
||||||
|
{
|
||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
|
if(mode == MODE_THEMES && audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -530,11 +627,11 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
}
|
}
|
||||||
else if(kDown & KEY_L)
|
else if(kDown & KEY_L)
|
||||||
{
|
{
|
||||||
load_remote_list(current_list, current_list->tp_current_page-1, mode);
|
load_remote_list(current_list, current_list->tp_current_page-1, mode, false);
|
||||||
}
|
}
|
||||||
else if(kDown & KEY_R)
|
else if(kDown & KEY_R)
|
||||||
{
|
{
|
||||||
load_remote_list(current_list, current_list->tp_current_page+1, mode);
|
load_remote_list(current_list, current_list->tp_current_page+1, mode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movement in the UI
|
// Movement in the UI
|
||||||
@@ -595,6 +692,12 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
if(preview_mode)
|
if(preview_mode)
|
||||||
{
|
{
|
||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
|
if(mode == MODE_THEMES && audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(y < 24)
|
else if(y < 24)
|
||||||
@@ -628,11 +731,11 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
{
|
{
|
||||||
if(BETWEEN(0, x, border))
|
if(BETWEEN(0, x, border))
|
||||||
{
|
{
|
||||||
load_remote_list(current_list, current_list->tp_current_page-1, mode);
|
load_remote_list(current_list, current_list->tp_current_page-1, mode, false);
|
||||||
}
|
}
|
||||||
else if(BETWEEN(320-border, x, 320))
|
else if(BETWEEN(320-border, x, 320))
|
||||||
{
|
{
|
||||||
load_remote_list(current_list, current_list->tp_current_page+1, mode);
|
load_remote_list(current_list, current_list->tp_current_page+1, mode, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -667,7 +770,7 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
return downloaded;
|
return downloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 http_get(const char *url, char ** filename, char ** buf)
|
u32 http_get(const char *url, char ** filename, char ** buf, InstallType install_type)
|
||||||
{
|
{
|
||||||
Result ret;
|
Result ret;
|
||||||
httpcContext context;
|
httpcContext context;
|
||||||
@@ -722,7 +825,7 @@ u32 http_get(const char *url, char ** filename, char ** buf)
|
|||||||
{
|
{
|
||||||
httpcCloseContext(&context);
|
httpcCloseContext(&context);
|
||||||
if (new_url != NULL) free(new_url);
|
if (new_url != NULL) free(new_url);
|
||||||
DEBUG("status_code\n");
|
DEBUG("status_code, %lu\n", status_code);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,6 +894,9 @@ u32 http_get(const char *url, char ** filename, char ** buf)
|
|||||||
ret = httpcDownloadData(&context, (*(u8**)buf) + size, 0x1000, &read_size);
|
ret = httpcDownloadData(&context, (*(u8**)buf) + size, 0x1000, &read_size);
|
||||||
size += read_size;
|
size += read_size;
|
||||||
|
|
||||||
|
if(content_size && install_type != INSTALL_NONE)
|
||||||
|
draw_loading_bar(size, content_size, install_type);
|
||||||
|
|
||||||
if (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
|
if (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
|
||||||
{
|
{
|
||||||
last_buf = *buf;
|
last_buf = *buf;
|
||||||
@@ -820,5 +926,6 @@ u32 http_get(const char *url, char ** filename, char ** buf)
|
|||||||
httpcCloseContext(&context);
|
httpcCloseContext(&context);
|
||||||
free(new_url);
|
free(new_url);
|
||||||
|
|
||||||
|
DEBUG("size: %lu\n", size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -41,15 +41,15 @@ void splash_install(Entry_s splash)
|
|||||||
u32 size = load_data("/splash.bin", splash, &screen_buf);
|
u32 size = load_data("/splash.bin", splash, &screen_buf);
|
||||||
if(size != 0)
|
if(size != 0)
|
||||||
{
|
{
|
||||||
remake_file("/luma/splash.bin", ArchiveSD, size);
|
remake_file(fsMakePath(PATH_ASCII, "/luma/splash.bin"), ArchiveSD, size);
|
||||||
buf_to_file(size, "/luma/splash.bin", ArchiveSD, screen_buf);
|
buf_to_file(size, fsMakePath(PATH_ASCII, "/luma/splash.bin"), ArchiveSD, screen_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 bottom_size = load_data("/splashbottom.bin", splash, &screen_buf);
|
u32 bottom_size = load_data("/splashbottom.bin", splash, &screen_buf);
|
||||||
if(bottom_size != 0)
|
if(bottom_size != 0)
|
||||||
{
|
{
|
||||||
remake_file("/luma/splashbottom.bin", ArchiveSD, bottom_size);
|
remake_file(fsMakePath(PATH_ASCII, "/luma/splashbottom.bin"), ArchiveSD, bottom_size);
|
||||||
buf_to_file(bottom_size, "/luma/splashbottom.bin", ArchiveSD, screen_buf);
|
buf_to_file(bottom_size, fsMakePath(PATH_ASCII, "/luma/splashbottom.bin"), ArchiveSD, screen_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size == 0 && bottom_size == 0)
|
if(size == 0 && bottom_size == 0)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -56,12 +56,14 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
return MAKERESULT(RL_USAGE, RS_INVALIDARG, RM_COMMON, RD_INVALID_SELECTION);
|
return MAKERESULT(RL_USAGE, RS_INVALIDARG, RM_COMMON, RD_INVALID_SELECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * padded = NULL;
|
||||||
|
|
||||||
int shuffle_count = 0;
|
int shuffle_count = 0;
|
||||||
Handle body_cache_handle;
|
Handle body_cache_handle;
|
||||||
|
|
||||||
if(installmode & THEME_INSTALL_BODY)
|
if(installmode & THEME_INSTALL_BODY)
|
||||||
{
|
{
|
||||||
remake_file("/BodyCache_rd.bin", ArchiveThemeExt, BODY_CACHE_SIZE * MAX_SHUFFLE_THEMES);
|
remake_file(fsMakePath(PATH_ASCII, "/BodyCache_rd.bin"), ArchiveThemeExt, BODY_CACHE_SIZE * MAX_SHUFFLE_THEMES);
|
||||||
FSUSER_OpenFile(&body_cache_handle, ArchiveThemeExt, fsMakePath(PATH_ASCII, "/BodyCache_rd.bin"), FS_OPEN_WRITE, 0);
|
FSUSER_OpenFile(&body_cache_handle, ArchiveThemeExt, fsMakePath(PATH_ASCII, "/BodyCache_rd.bin"), FS_OPEN_WRITE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,14 +85,29 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
shuffle_body_sizes[shuffle_count] = body_size;
|
shuffle_body_sizes[shuffle_count] = body_size;
|
||||||
FSFILE_Write(body_cache_handle, NULL, BODY_CACHE_SIZE * shuffle_count, body, body_size, FS_WRITE_FLUSH);
|
|
||||||
|
padded = calloc(BODY_CACHE_SIZE, sizeof(char));
|
||||||
|
memcpy(padded, body, body_size);
|
||||||
free(body);
|
free(body);
|
||||||
|
|
||||||
|
FSFILE_Write(body_cache_handle, NULL, BODY_CACHE_SIZE * shuffle_count, padded, BODY_CACHE_SIZE, FS_WRITE_FLUSH);
|
||||||
|
|
||||||
|
free(padded);
|
||||||
|
padded = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(installmode & THEME_INSTALL_BGM)
|
if(installmode & THEME_INSTALL_BGM)
|
||||||
{
|
{
|
||||||
char bgm_cache_path[26] = {0};
|
char bgm_cache_path[26] = {0};
|
||||||
sprintf(bgm_cache_path, "/BgmCache_%.2i.bin", shuffle_count);
|
sprintf(bgm_cache_path, "/BgmCache_%.2i.bin", shuffle_count);
|
||||||
|
|
||||||
|
if(current_theme->no_bgm_shuffle)
|
||||||
|
{
|
||||||
|
music = NULL;
|
||||||
|
music_size = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
music_size = load_data("/bgm.bcstm", *current_theme, &music);
|
music_size = load_data("/bgm.bcstm", *current_theme, &music);
|
||||||
|
|
||||||
if(music_size > BGM_MAX_SIZE)
|
if(music_size > BGM_MAX_SIZE)
|
||||||
@@ -99,25 +116,43 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
DEBUG("bgm too big\n");
|
DEBUG("bgm too big\n");
|
||||||
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_TOO_LARGE);
|
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_TOO_LARGE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
shuffle_music_sizes[shuffle_count] = music_size;
|
shuffle_music_sizes[shuffle_count] = music_size;
|
||||||
remake_file(bgm_cache_path, ArchiveThemeExt, BGM_MAX_SIZE);
|
remake_file(fsMakePath(PATH_ASCII, bgm_cache_path), ArchiveThemeExt, BGM_MAX_SIZE);
|
||||||
buf_to_file(music_size, bgm_cache_path, ArchiveThemeExt, music);
|
|
||||||
|
Handle bgm_cache_handle;
|
||||||
|
FSUSER_OpenFile(&bgm_cache_handle, ArchiveThemeExt, fsMakePath(PATH_ASCII, bgm_cache_path), FS_OPEN_WRITE, 0);
|
||||||
|
|
||||||
|
padded = calloc(BGM_MAX_SIZE, sizeof(char));
|
||||||
|
if(!current_theme->no_bgm_shuffle)
|
||||||
|
{
|
||||||
|
memcpy(padded, music, music_size);
|
||||||
free(music);
|
free(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSFILE_Write(bgm_cache_handle, NULL, 0, padded, BGM_MAX_SIZE, FS_WRITE_FLUSH);
|
||||||
|
|
||||||
|
FSFILE_Close(bgm_cache_handle);
|
||||||
|
free(padded);
|
||||||
|
padded = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
shuffle_count++;
|
shuffle_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(installmode & THEME_INSTALL_BGM)
|
if(installmode & THEME_INSTALL_BGM)
|
||||||
{
|
{
|
||||||
|
char * blank = calloc(BGM_MAX_SIZE, sizeof(char));
|
||||||
for(int i = shuffle_count; i < MAX_SHUFFLE_THEMES; i++)
|
for(int i = shuffle_count; i < MAX_SHUFFLE_THEMES; i++)
|
||||||
{
|
{
|
||||||
char bgm_cache_path[26] = {0};
|
char bgm_cache_path[26] = {0};
|
||||||
sprintf(bgm_cache_path, "/BgmCache_%.2i.bin", i);
|
sprintf(bgm_cache_path, "/BgmCache_%.2i.bin", i);
|
||||||
remake_file(bgm_cache_path, ArchiveThemeExt, BGM_MAX_SIZE);
|
remake_file(fsMakePath(PATH_ASCII, bgm_cache_path), ArchiveThemeExt, BGM_MAX_SIZE);
|
||||||
|
buf_to_file(BGM_MAX_SIZE, fsMakePath(PATH_ASCII, bgm_cache_path), ArchiveThemeExt, blank);
|
||||||
}
|
}
|
||||||
|
free(blank);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(installmode & THEME_INSTALL_BODY)
|
if(installmode & THEME_INSTALL_BODY)
|
||||||
@@ -140,7 +175,7 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_NOT_FOUND);
|
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = buf_to_file(body_size, "/BodyCache.bin", ArchiveThemeExt, body); // Write body data to file
|
res = buf_to_file(body_size, fsMakePath(PATH_ASCII, "/BodyCache.bin"), ArchiveThemeExt, body); // Write body data to file
|
||||||
free(body);
|
free(body);
|
||||||
|
|
||||||
if(R_FAILED(res)) return res;
|
if(R_FAILED(res)) return res;
|
||||||
@@ -156,10 +191,15 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_TOO_LARGE);
|
return MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_TOO_LARGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = buf_to_file(music_size, "/BgmCache.bin", ArchiveThemeExt, music);
|
res = buf_to_file(music_size, fsMakePath(PATH_ASCII, "/BgmCache.bin"), ArchiveThemeExt, music);
|
||||||
free(music);
|
free(music);
|
||||||
|
|
||||||
if(R_FAILED(res)) return res;
|
if(R_FAILED(res)) return res;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
music = calloc(BGM_MAX_SIZE, 1);
|
||||||
|
res = buf_to_file(BGM_MAX_SIZE, fsMakePath(PATH_ASCII, "/BgmCache.bin"), ArchiveThemeExt, music);
|
||||||
|
free(music);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +235,7 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
theme_manage->dlc_theme_content_index = 0xFF;
|
theme_manage->dlc_theme_content_index = 0xFF;
|
||||||
theme_manage->use_theme_cache = 0x0200;
|
theme_manage->use_theme_cache = 0x0200;
|
||||||
|
|
||||||
res = buf_to_file(0x800, "/ThemeManage.bin", ArchiveThemeExt, thememanage_buf);
|
res = buf_to_file(0x800, fsMakePath(PATH_ASCII, "/ThemeManage.bin"), ArchiveThemeExt, thememanage_buf);
|
||||||
free(thememanage_buf);
|
free(thememanage_buf);
|
||||||
if(R_FAILED(res)) return res;
|
if(R_FAILED(res)) return res;
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
@@ -220,7 +260,7 @@ static Result install_theme_internal(Entry_List_s themes, int installmode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = buf_to_file(savedata_size, "/SaveData.dat", ArchiveHomeExt, savedata_buf);
|
res = buf_to_file(savedata_size, fsMakePath(PATH_ASCII, "/SaveData.dat"), ArchiveHomeExt, savedata_buf);
|
||||||
free(savedata_buf);
|
free(savedata_buf);
|
||||||
if(R_FAILED(res)) return res;
|
if(R_FAILED(res)) return res;
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of Anemone3DS
|
* This file is part of Anemone3DS
|
||||||
* Copyright (C) 2016-2017 Alex Taber ("astronautlevel"), Dawid Eckert ("daedreth")
|
* Copyright (C) 2016-2018 Contributors in CONTRIBUTORS.md
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -48,7 +48,9 @@ void printu(u16 *input)
|
|||||||
ssize_t buf_len = in_len + 1; // Plus 1 for proper null termination
|
ssize_t buf_len = in_len + 1; // Plus 1 for proper null termination
|
||||||
wchar_t *buf = calloc(buf_len, sizeof(wchar_t));
|
wchar_t *buf = calloc(buf_len, sizeof(wchar_t));
|
||||||
utf16_to_utf32((u32*)buf, input, buf_len);
|
utf16_to_utf32((u32*)buf, input, buf_len);
|
||||||
printf("%ls\n", buf);
|
char cbuf[0x106];
|
||||||
|
sprintf(cbuf, "%ls\n", buf);
|
||||||
|
DEBUG(cbuf);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user