Compare commits

...

13 Commits

Author SHA1 Message Date
yellows8
2c53af56cc
Release 3.5.1 2022-06-14 18:20:43 -04:00
yellows8
7bdfce172c
Fix temperature display on [14.0.0+]. 2022-03-24 20:53:19 -04:00
imxyd
34f7f16cb1 Update language.c
Improve Chinese language
2022-01-22 19:34:54 +01:00
yellows8
73d7108a62
Release 3.5.0 2021-10-29 19:47:15 -04:00
yellows8
422039f727
Use physfs instead of minizip for asset loading, etc. 2021-10-22 13:18:30 -04:00
yellows8
3f73855170
Added theme support for dirs and .zip via physfs. Closes #121. 2021-10-21 15:26:30 -04:00
qazrfv1234
6e654ec2af Update language.c (typo fixed) 2021-08-27 20:06:28 +02:00
Dave Murphy
5c85dd784b 3.4.1 release 2021-07-16 14:53:06 +01:00
Dave Murphy
8c87b1c46f ensure build picks up version from Makefile 2021-07-16 14:52:34 +01:00
fincs
47fd18cabb
Update psm charger type 2021-07-15 21:59:49 +02:00
Chronoss
c1640f4b54
Update language.c (#130) 2021-06-09 08:21:37 +01:00
HamletDuFromage
aef37e10f7
stat(path) before trying to launch a nro (#129) 2021-06-09 08:16:37 +01:00
Mehdi Khelfi
95411fe5e9
Added some spanish and french strings (#132) 2021-04-18 14:51:03 +02:00
17 changed files with 255 additions and 168 deletions

View File

@ -1,4 +1,4 @@
export APP_VERSION := 3.4.0
export APP_VERSION := 3.5.1
ifeq ($(RELEASE),)
export APP_VERSION := $(APP_VERSION)-$(shell git describe --dirty --always)

View File

@ -63,7 +63,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -ldeko3d -lminizip `freetype-config --libs` -lconfig -lturbojpeg -lpng
LIBS := -ldeko3d -lphysfs `freetype-config --libs` -lconfig -lturbojpeg -lpng
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -212,6 +212,7 @@ $(OUTPUT).nso : $(OUTPUT).elf
endif
menu.o : $(TOPDIR)/Makefile
$(OUTPUT).elf : $(OFILES)
$(OFILES_SRC) : $(HFILES_BIN)

View File

@ -14,7 +14,7 @@ test : pc_main/main.cpp pc_main/pc_launch.c pc_main/pc_power.c pc_main/pc_netsta
common/menu-entry.c common/menu-list.c common/message-box.c common/text.c \
common/ui.c common/assets.c common/math.c common/theme.c \
common/netloader.c
gcc -Wall -O2 -g -DVERSION=\"v$(APP_VERSION)\" $(EXTRA_CFLAGS) `pkg-config freetype2 --cflags` $^ -lsfml-graphics -lsfml-window -lsfml-system -lstdc++ -lpthread `pkg-config freetype2 --libs` -lm -lminizip -lz -lconfig -lturbojpeg -lpng $(EXTRA_LDFLAGS) -I. -iquote $(DEVKITPRO)/libnx/include -Ibuild_pc -g -o $@
gcc -Wall -O2 -g -DVERSION=\"v$(APP_VERSION)\" $(EXTRA_CFLAGS) `pkg-config freetype2 --cflags` $^ -lsfml-graphics -lsfml-window -lsfml-system -lstdc++ -lpthread `pkg-config freetype2 --libs` -lm -lphysfs -lz -lconfig -lturbojpeg -lpng $(EXTRA_LDFLAGS) -I. -iquote $(DEVKITPRO)/libnx/include -Ibuild_pc -g -o $@
clean:
rm -rf build_pc/ test test.*

View File

@ -13,13 +13,13 @@ The following [pacman packages](https://devkitpro.org/wiki/devkitPro_pacman) are
- `switch-freetype`
- `switch-libconfig`
- `switch-libjpeg-turbo`
- `switch-zlib`
- `switch-physfs`
The following libraries are required to build for PC:
- `libfreetype`
- `libconfig`
- `libjpeg-turbo`
- `libminizip`
- `libphysfs`
Building for Switch/PC requires `zip`.

View File

@ -1,6 +1,6 @@
#include "common.h"
#include <minizip/unzip.h>
#include <physfs.h>
#include <png.h>
#define GENASSET(_p, _mode, _w, _h) {{.path = _p, .imageMode = _mode, .imageSize = {_w, _h}}, {}}
@ -46,59 +46,9 @@ static void assetsSetPixelSize(assetsDataEntry *entry) {
}
}
static int assetsLoadFile(unzFile zipf, assetsDataEntry *entry) {
int ret;
int filesize=0;
unz_file_info file_info;
u8* buffer = NULL;
assetsSetPixelSize(entry);
ret = unzLocateFile(zipf, entry->path, 0);
if (ret==UNZ_OK) ret = unzOpenCurrentFile(zipf);
if (ret==UNZ_OK) {
ret = unzGetCurrentFileInfo(zipf, &file_info, NULL, 0, NULL, 0, NULL, 0);
filesize = file_info.uncompressed_size;
if (filesize != entry->imageSize[0] * entry->imageSize[1] * entry->pixSize) ret = -10;
if (ret==UNZ_OK) {
buffer = (u8*)malloc(filesize);
if (buffer) {
memset(buffer, 0, filesize);
} else {
ret = -11;
}
}
if (ret==UNZ_OK) {
ret = unzReadCurrentFile(zipf, buffer, filesize);
if(ret < filesize) {
ret = -12;
} else {
ret = UNZ_OK;
}
}
if (ret!=UNZ_OK && buffer!=NULL) free(buffer);
unzCloseCurrentFile(zipf);
}
if (ret==UNZ_OK) {
entry->buffer = buffer;
entry->size = filesize;
}
return ret;
}
Result assetsInit(void) {
int ret=0;
bool ret=false;
int i, stopi;
unzFile zipf;
assetsDataEntry *entry = NULL;
char tmp_path[PATH_MAX];
@ -117,40 +67,34 @@ Result assetsInit(void) {
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/romfs/assets.zip", menuGetRootBasePath());
#endif
zipf = unzOpen(tmp_path);
if(zipf==NULL) {
#ifdef __SWITCH__
romfsExit();
#endif
return 0x80;
}
if (PHYSFS_mount(tmp_path, "", 0)) {
ret=true;
for (i=0; i<AssetId_Max; i++) {
stopi = i;
entry = &g_assetsDataList[i][0];
if (entry->path[0]) {
ret = assetsLoadFile(zipf, entry);
if (ret!=UNZ_OK) break;
entry->initialized = true;
ret = assetsLoadData(i, NULL, NULL);
if (!ret) break;
}
}
if (ret!=UNZ_OK) {
if (!ret) {
for (i=0; i<stopi; i++) {
assetsClearEntry(&g_assetsDataList[i][0]);
}
}
if (ret==UNZ_OK) g_assetsInitialized = 1;
if (ret) g_assetsInitialized = 1;
unzClose(zipf);
PHYSFS_unmount(tmp_path);
}
#ifdef __SWITCH__
romfsExit();
return ret ? 0 : MAKERESULT(Module_Libnx, LibnxError_IoError);
#else
return ret ? 0 : 1;
#endif
return ret;
}
void assetsExit(void) {
@ -223,31 +167,67 @@ bool assetsLoadPngFromMemory(u8 *indata, size_t indata_size, u8 *outdata, ImageM
return ret;
}
bool assetsLoadFromTheme(AssetId id, const char *path, int *imageSize) {
bool assetsPhysfsReadFile(const char *path, u8 **data_buf, size_t *filesize, bool nul_term) {
bool ret=true;
*data_buf = NULL;
if (filesize) *filesize = 0;
PHYSFS_Stat tmpstat={0};
if (!(PHYSFS_stat(path, &tmpstat) && tmpstat.filesize!=-1)) ret = false;
if (ret) {
size_t bufsize = tmpstat.filesize;
if (nul_term) bufsize++;
*data_buf = (u8*)malloc(bufsize);
if (*data_buf) memset(*data_buf, 0, bufsize);
else ret = false;
}
if (ret) {
PHYSFS_File *f = PHYSFS_openRead(path);
if (f==NULL) ret = false;
else {
ret = PHYSFS_readBytes(f, *data_buf, tmpstat.filesize) == tmpstat.filesize;
PHYSFS_close(f);
}
}
if (ret) {
if (filesize) *filesize = tmpstat.filesize;
}
else {
free(*data_buf);
*data_buf = NULL;
}
return ret;
}
bool assetsLoadData(AssetId id, const char *path, int *imageSize) {
if (id < 0 || id >= AssetId_Max) return false;
assetsDataEntry *entry = &g_assetsDataList[id][1];
assetsDataEntry *entry = &g_assetsDataList[id][path ? 1 : 0];
if (entry->initialized) return false;
memset(entry, 0, sizeof(*entry));
if (path) memset(entry, 0, sizeof(*entry));
if (imageSize) {
entry->imageSize[0] = imageSize[0];
entry->imageSize[1] = imageSize[1];
}
entry->imageMode = g_assetsDataList[id][0].imageMode;
if (path) entry->imageMode = g_assetsDataList[id][0].imageMode;
assetsSetPixelSize(entry);
entry->size = entry->imageSize[0] * entry->imageSize[1] * entry->pixSize;
strncpy(entry->path, path, sizeof(entry->path)-1);
if (path) strncpy(entry->path, path, sizeof(entry->path)-1);
const char* ext = getExtension(entry->path);
bool ret=true;
size_t filesize=0;
if (ext==NULL) ret = false;
u8 *data_buf = NULL;
struct stat st;
if (ret && stat(path, &st)==-1) ret = false;
if (ret) {
entry->buffer = (u8*)malloc(entry->size);
@ -255,31 +235,18 @@ bool assetsLoadFromTheme(AssetId id, const char *path, int *imageSize) {
else ret = false;
}
if (ret) {
data_buf = (u8*)malloc(st.st_size);
if (data_buf) memset(data_buf, 0, st.st_size);
else ret = false;
}
if (ret) {
FILE *f = fopen(entry->path, "rb");
if (f==NULL) ret = false;
else {
ret = fread(data_buf, st.st_size, 1, f) == 1;
fclose(f);
}
}
if (ret) ret = assetsPhysfsReadFile(entry->path, &data_buf, &filesize, false);
if (ret) {
if (strcasecmp(ext, ".bin")==0) {
if (st.st_size != entry->size) ret = false;
if (filesize != entry->size) ret = false;
if (ret) memcpy(entry->buffer, data_buf, entry->size);
}
else if (strcasecmp(ext, ".jpg")==0 || strcasecmp(ext, ".jpeg")==0)
ret = assetsLoadJpgFromMemory(data_buf, st.st_size, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
ret = assetsLoadJpgFromMemory(data_buf, filesize, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
else if (strcasecmp(ext, ".png")==0)
ret = assetsLoadPngFromMemory(data_buf, st.st_size, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
ret = assetsLoadPngFromMemory(data_buf, filesize, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
else
ret = false; // File extension not recognized.
}

View File

@ -35,7 +35,8 @@ typedef struct {
Result assetsInit(void);
void assetsExit(void);
void assetsClearTheme(void);
bool assetsLoadFromTheme(AssetId id, const char *path, int *imageSize);
bool assetsPhysfsReadFile(const char *path, u8 **data_buf, size_t *filesize, bool nul_term);
bool assetsLoadData(AssetId id, const char *path, int *imageSize);
void assetsGetData(AssetId id, assetsDataEntry **out);
u8 *assetsGetDataBuffer(AssetId id);

View File

@ -43,13 +43,15 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("로딩중…"),
STR_RU("загрузка…"),
STR_ZH_HANS("加载中…"),
STR_ZH_HANT("載中…"),
STR_ZH_HANT("中…"),
},
[StrId_AppletMode] =
{
STR_EN("● Applet Mode ●"),
STR_ES("● Modo Applet ●"),
STR_FR("● Mode Applet ●"),
STR_ZH_HANS("● 小程序模式 ●"),
},
[StrId_Directory] =
@ -97,7 +99,7 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("알 수 없는 개발자"),
STR_RU("неизвестный автор"),
STR_ZH_HANS("未知作者"),
STR_ZH_HANT("作者不詳"),
STR_ZH_HANT("作者未知"),
},
[StrId_IOError] =
@ -113,7 +115,7 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("입출력 오류"),
STR_RU("I/O-ошибка"),
STR_ZH_HANS("读写出错"),
STR_ZH_HANT("讀寫錯誤"),
STR_ZH_HANT("取存錯誤"),
},
[StrId_CouldNotOpenFile] =
@ -129,7 +131,14 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("파일을 열 수 없습니다:\n%s"),
STR_RU("Не могу открыть файл:\n%s"),
STR_ZH_HANS("无法打开文件:\n%s"),
STR_ZH_HANT("開啓檔案失敗:\n%s"),
STR_ZH_HANT("無法開啟檔案:\n%s"),
},
[StrId_NroNotFound] =
{
STR_EN("Could not find executable: %s"),
STR_FR("Impossible trouver l'exécutable : %s"),
STR_ZH_HANS("找不到可执行文件"),
},
[StrId_NoAppsFound_Title] =
@ -145,7 +154,7 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("애플리케이션을 찾을 수 없습니다"),
STR_RU("приложение не найдено"),
STR_ZH_HANS("找不到可执行的自制程序"),
STR_ZH_HANT("未能找到可執行的自製程式"),
STR_ZH_HANT("沒有可執行的自製程式"),
},
[StrId_NoAppsFound_Msg] =
@ -206,14 +215,14 @@ const char* const g_strings[StrId_Max][17] =
"названием switch и она содержит приложения."
),
STR_ZH_HANS(
"内存卡找不到任何可执行的应用程序\n"
"请在内存卡的根目录建立「switch」子目录\n"
"存放自制应用软件至该目录"
"找不到任何自制程序(nro)\n"
"在SD卡根目录建立“switch”文件夹\n"
"将自制程序(nro)放在其中"
),
STR_ZH_HANT(
"記憶體找不到任何可執行的應用程式。\n"
"請在記憶體建立「switch」資料夾\n"
"然後儲存自製軟體到此處"
"記憶卡內沒有可供執行的應用程式。\n"
"請在根目錄下建立「switch」資料夾\n"
"並將自製軟體複製到switch資料夾內"
),
},
@ -226,15 +235,19 @@ const char* const g_strings[StrId_Max][17] =
STR_IT("L'ultima applicazione ha restituito un errore:"),
STR_JP("直前に実行したアプリでエラーが発生しました:"),
STR_KO("최근 애플리케이션에서 오류가 발생했습니다:"),
STR_ZH_HANT("程式執行時發生錯誤:"),
STR_ZH_HANS("程序运行后出现错误:"),
STR_ZH_HANT("程式執行後出現錯誤:"),
},
[StrId_AppLaunchError] =
{
STR_EN("Failed to launch the application:"),
STR_DE("Konnte die Anwendung nicht starten:"),
STR_FR("Erreur au lancement de l'application"),
STR_FR("Erreur au lancement de l'application:"),
STR_IT("Errore nell'avvio dell'applicazione:"),
STR_ES("No se ha podido iniciar la aplicación:"),
STR_ZH_HANS("运行程序时发生错误:"),
STR_ZH_HANT("執行程式時發生錯誤:"),
},
[StrId_AppInfo_Author] =
@ -265,8 +278,8 @@ const char* const g_strings[StrId_Max][17] =
STR_NL("Versie"),
STR_KO("버전"),
STR_RU("Версия"),
STR_ZH_HANS(""),
STR_ZH_HANT(""),
STR_ZH_HANS(""),
STR_ZH_HANT(""),
},
[StrId_Actions_Launch] =
@ -274,7 +287,7 @@ const char* const g_strings[StrId_Max][17] =
STR_EN("Launch"),
STR_ES("Lanzamiento"),
STR_DE("Starten"),
STR_FR("Lancement"),
STR_FR("Lancer"),
STR_IT("Avvia"),
STR_JP("起動"),
STR_PT("Lançamento"),
@ -313,8 +326,8 @@ const char* const g_strings[StrId_Max][17] =
STR_NL("Terug"),
STR_KO("뒤로 가기"),
STR_RU("возвращаться"),
STR_ZH_HANS(""),
STR_ZH_HANT(""),
STR_ZH_HANS(""),
STR_ZH_HANT(""),
},
[StrId_MsgBox_OK] =
@ -326,6 +339,7 @@ const char* const g_strings[StrId_Max][17] =
STR_ES("Aceptar"),
STR_JP("了解"),
STR_KO("확인"),
STR_ZH_HANS("确认"),
STR_ZH_HANT("確認"),
},
@ -338,7 +352,8 @@ const char* const g_strings[StrId_Max][17] =
STR_IT("Applica"),
STR_JP("適用"),
STR_KO("적용"),
STR_ZH_HANT("应用"),
STR_ZH_HANS("应用"),
STR_ZH_HANT("套用"),
},
[StrId_Actions_Star] =
@ -347,6 +362,7 @@ const char* const g_strings[StrId_Max][17] =
STR_ES("Agregar a favoritos"),
STR_IT("Aggiungi ai preferiti"),
STR_FR("Ajouter aux favoris"),
STR_ZH_HANS("收藏"),
},
[StrId_Actions_Unstar] =
@ -354,19 +370,21 @@ const char* const g_strings[StrId_Max][17] =
STR_EN("Unstar"),
STR_ES("Borrar de favoritos"),
STR_IT("Rimuovi dai preferiti"),
STR_FR("Retirer des favoris")
STR_FR("Retirer des favoris"),
STR_ZH_HANS("取消收藏"),
},
[StrId_ThemeMenu] =
{
STR_EN("Theme Menu"),
STR_FR("Menu Thème"),
STR_FR("Menu thèmes"),
STR_DE("Theme Menü"),
STR_ES("Menú temático"),
STR_IT("Tema Menu"),
STR_JP("テーマメニュー"),
STR_KO("테마 메뉴"),
STR_ZH_HANT("主题菜单"),
STR_ZH_HANS("主题菜单"),
STR_ZH_HANT("主題選單"),
},
[StrId_ThemeNotApplied] =
@ -378,7 +396,8 @@ const char* const g_strings[StrId_Max][17] =
STR_IT("Il tema non è stato applicato a causa di un errore."),
STR_JP("エラーが発生したため、テーマを適用できませんでした。"),
STR_KO("오류가 발생 했기 때문에 테마를 적용할 수 없습니다."),
STR_ZH_HANT("由于发生错误, 无法应用主题。"),
STR_ZH_HANS("由于发生错误, 无法应用主题。"),
STR_ZH_HANT("出現錯誤,無法套用主題。"),
},
[StrId_DefaultThemeName] =
@ -387,6 +406,9 @@ const char* const g_strings[StrId_Max][17] =
STR_FR("Thème par défaut"),
STR_DE("Standard Theme"),
STR_IT("Tema di default"),
STR_ES("Tema por defecto"),
STR_ZH_HANS("默认主题"),
STR_ZH_HANT("預設主題"),
},
/*[StrId_Reboot] =
@ -565,7 +587,7 @@ const char* const g_strings[StrId_Max][17] =
STR_DE("Fehler beim Lesen der Titel-Metadaten.\n%08lX%08lX@%d"),
STR_FR(
"Erreur lors de la lecture des métadonnées\n"
"de titre.\n%08lX%08lX@%d"
"du titre.\n%08lX%08lX@%d"
),
STR_IT("Errore nella lettura dei metadata dei titoli.\n%08lX%08lX@%d"),
STR_JP("タイトルメタデータを読み取ることができませんでした。\n%08lX%08lX@%d"),
@ -574,7 +596,7 @@ const char* const g_strings[StrId_Max][17] =
STR_KO("타이틀 메타데이터를 읽는데 실패하였습니다.\n%08lX%08lX@%d"),
STR_RU("Ошибка чтения метаданных заголовка\n.%08lX%08lX@%d"),
STR_ZH_HANS("读取软件相关信息时发生错误:\n%08lX%08lX@%d"),
STR_ZH_HANT("讀取軟體相關數據時發生錯誤:\n%08lX%08lX@%d"),
STR_ZH_HANT("讀取軟體相關資訊時發生錯誤:\n%08lX%08lX@%d"),
},
[StrId_NoTitlesFound] =
@ -716,7 +738,7 @@ const char* const g_strings[StrId_Max][17] =
),
STR_ZH_HANT(
"您所利用漏洞開啓的「自製軟體啓動器」\n"
"無法在當前選中的軟體啓動自製軟\n"
"無法在當前選中的軟體啓動自製軟\n"
"請利用其它漏洞來啓動「自製軟體啓動器」。"
),
},
@ -778,7 +800,7 @@ const char* const g_strings[StrId_Max][17] =
STR_EN("NetLoader"),
STR_ES("Cargador de programas"),
STR_DE("Netzwerk-Loader"),
STR_FR("Chargeur de programme"),
STR_FR("NetLoader"),
STR_IT("Caricamento programmi"),
STR_JP("ネットローダ"),
STR_PT("Carregador de programas"),
@ -794,7 +816,7 @@ const char* const g_strings[StrId_Max][17] =
STR_EN("The NetLoader is currently unavailable."),
STR_ES("El cargador de programas no está disponible."),
STR_DE("Der Netzwerk-Loader ist zur Zeit nicht verfügbar."),
STR_FR("Le chargeur de programme nxlink est indisponible."),
STR_FR("Le programme nxlink est indisponible."),
STR_IT("Il caricamento programmi nxlink non è disponibile."),
STR_JP("nxlinkネットローダは現在利用できません。"),
STR_PT("O carregador de programas está de momento indisponível."),
@ -827,10 +849,11 @@ const char* const g_strings[StrId_Max][17] =
STR_DE("Offline, warte auf Netzwerk…"),
STR_FR("Hors-ligne, en attente d'une connection..."),
STR_IT("Disconnesso, in attesa della connessione…"),
STR_ES("Desconectado, esperando a la red..."),
STR_JP("オフラインです。ネットワーク接続を待っています…"),
STR_KO("연결 끊김, 네트워크 기다리는 중…"),
STR_ZH_HANS("无法连接网络,等待网络连接…"),
STR_ZH_HANT("當前離線,等待網路連線…"),
STR_ZH_HANT("目前已離線,等待網路連線…"),
},
[StrId_NetLoaderActive] =
@ -937,4 +960,3 @@ const char* const g_strings[StrId_Max][17] =
),
},
};

View File

@ -11,6 +11,7 @@ typedef enum
StrId_DefaultPublisher,
StrId_IOError,
StrId_CouldNotOpenFile,
StrId_NroNotFound,
StrId_NoAppsFound_Title,
StrId_NoAppsFound_Msg,

View File

@ -1,4 +1,5 @@
#include "common.h"
#include <physfs.h>
void menuEntryInit(menuEntry_s* me, MenuEntryType type) {
memset(me, 0, sizeof(*me));
@ -80,9 +81,13 @@ static bool menuEntryLoadEmbeddedIcon(menuEntry_s* me) {
return ok;
}
static bool menuEntryLoadExternalIcon(menuEntry_s* me, const char* path) {
static bool menuEntryLoadExternalIcon(menuEntry_s* me, const char* path, bool data_source) {
struct stat st;
if (data_source) {
return assetsPhysfsReadFile(path, &me->icon, &me->icon_size, false);
}
if(stat(path, &st)==-1) return false;
FILE* f = fopen(path, "rb");
@ -326,7 +331,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
char* ext = getExtension(tempbuf);
strcpy(ext, ".jpg");
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
if (iconLoaded) break;
if (isOldAppFolder)
@ -334,7 +339,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
char* slash = getSlash(tempbuf);
strcpy(slash, "/icon.jpg");
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
if (iconLoaded) break;
}*/
@ -408,18 +413,43 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
*version = "1.0.0";
const char* cfg_path = me->path;
#ifdef __SWITCH__
const char* theme_archive_path = NULL;
const char* ext = getExtension(me->path);
bool good_cfg = false;
bool is_archive = false;
#ifdef __SWITCH__
bool is_romfs = false;
if (strcasecmp(ext, ".romfs")==0) {
if (R_FAILED(romfsMountFromFsdev(me->path, 0, "themetmp")))
return false;
is_romfs = true;
cfg_path = "themetmp:/theme.cfg";
theme_archive_path = "themetmp:/";
}
#endif
if (config_read_file(&cfg, cfg_path)) {
if (strcasecmp(ext, ".romfs")!=0 && strcasecmp(ext, ".cfg")!=0) {
theme_archive_path = me->path;
}
if (theme_archive_path) {
if (!PHYSFS_mount(theme_archive_path, "themetmp", 0)) cfg_path = NULL;
else {
is_archive = true;
cfg_path = "themetmp/theme.cfg";
}
}
if (cfg_path) {
if (!is_archive) good_cfg = config_read_file(&cfg, cfg_path);
else {
u8 *cfg_buf = NULL;
good_cfg = assetsPhysfsReadFile(cfg_path, &cfg_buf, NULL, true);
if (good_cfg) good_cfg = config_read_string(&cfg, (char*)cfg_buf);
free(cfg_buf);
}
}
if (good_cfg) {
themeInfo = config_lookup(&cfg, "themeInfo");
if (themeInfo != NULL) {
if(config_setting_lookup_string(themeInfo, "name", &name))
@ -433,15 +463,17 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
strncpy(me->version, version, sizeof(me->version)-1);
config_destroy(&cfg);
#ifdef __SWITCH__
if (is_romfs) {
if (good_cfg && is_archive) {
bool iconLoaded = false;
iconLoaded = menuEntryLoadExternalIcon(me, "themetmp:/icon.jpg");
iconLoaded = menuEntryLoadExternalIcon(me, "themetmp/icon.jpg", true);
if (iconLoaded) menuEntryParseIcon(me);
}
if (is_archive) PHYSFS_unmount(theme_archive_path);
#ifdef __SWITCH__
if (is_romfs) romfsUnmount("themetmp");
#endif
}
@ -475,7 +507,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
bool iconLoaded = false;
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
if (iconLoaded) menuEntryParseIcon(me);
@ -655,8 +687,8 @@ void menuEntryFileassocLoad(const char* filepath) {
}
me->fileassoc_str[sizeof(me->fileassoc_str)-1] = 0;
if (target_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, target_icon_path);
if (!iconLoaded && main_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, main_icon_path);
if (target_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, target_icon_path, false);
if (!iconLoaded && main_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, main_icon_path, false);
if (iconLoaded) {
menuEntryParseIcon(me);

View File

@ -246,8 +246,23 @@ int themeMenuScan(const char* target) {
memset(tmp_path, 0, sizeof(tmp_path));
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/%s", s_menu[!s_curMenu].dirname, dp->d_name);
bool entrytype=0;
#ifdef _DIRENT_HAVE_D_TYPE
if (dp->d_type == DT_UNKNOWN)
continue;
entrytype = dp->d_type != DT_REG;
#else
struct stat tmpstat;
if(stat(tmp_path, &tmpstat)==-1)
continue;
entrytype = (tmpstat.st_mode & S_IFMT) != S_IFREG;
#endif
const char* ext = getExtension(dp->d_name);
if (strcasecmp(ext, ".cfg")==0 || strcasecmp(ext, ".romfs")==0)
if (entrytype || strcasecmp(ext, ".cfg")==0 || strcasecmp(ext, ".romfs")==0 || strcasecmp(ext, ".zip")==0)
me = menuCreateEntry(ENTRY_TYPE_THEME);
if (!me)

View File

@ -593,7 +593,7 @@ u32 drawStatus() {
if (statusGet(&netstatusFlag, &id, &temperatureFlag, &temperature)) {
if (netstatusFlag) drawNetwork(tmpX, id);
if (temperatureFlag) {
snprintf(tmpstr, sizeof(tmpstr)-1, "%.1f°C", ((float)temperature) / 1000);
snprintf(tmpstr, sizeof(tmpstr)-1, "%d°C", temperature);
DrawTextFromLayout(ThemeLayoutId_Temperature, themeCurrent.textColor, tmpstr);
}
}

View File

@ -1,4 +1,5 @@
#include "theme.h"
#include <physfs.h>
theme_t themeCurrent;
ThemePreset themeGlobalPreset;
@ -82,9 +83,9 @@ bool assetObjectFromSetting(config_setting_t *asset_setting, AssetId id, ThemeLa
return false;
memset(tmp_path, 0, sizeof(tmp_path));
snprintf(tmp_path, sizeof(tmp_path)-1, "theme:/%s", path);
snprintf(tmp_path, sizeof(tmp_path)-1, "theme/%s", path);
return assetsLoadFromTheme(id, tmp_path, imageSize);
return assetsLoadData(id, tmp_path, imageSize);
}
void themeStartup(ThemePreset preset) {
@ -419,25 +420,48 @@ void themeStartup(ThemePreset preset) {
const char *AText, *BText, *XText, *YText, *PText, *MText, *starOnText, *starOffText;
bool logoColor_set = false;
bool good_cfg = false;
#ifdef __SWITCH__
bool is_romfs = false;
#endif
bool is_archive = false;
const char* theme_archive_path = NULL;
assetsClearTheme();
if(themePath[0]!=0) {
const char* cfg_path = themePath;
#ifdef __SWITCH__
const char* ext = getExtension(themePath);
#ifdef __SWITCH__
if (strcasecmp(ext, ".romfs")==0) {
if (R_FAILED(romfsMountFromFsdev(themePath, 0, "theme")))
cfg_path = NULL;
else {
is_romfs = true;
cfg_path = "theme:/theme.cfg";
theme_archive_path = "theme:/";
}
}
#endif
if (strcasecmp(ext, ".romfs")!=0 && strcasecmp(ext, ".cfg")!=0) {
theme_archive_path = themePath;
}
if (theme_archive_path) {
if (!PHYSFS_mount(theme_archive_path, "theme", 0)) cfg_path = NULL;
else {
is_archive = true;
cfg_path = "theme/theme.cfg";
}
}
if (cfg_path) good_cfg = config_read_file(&cfg, cfg_path);
if (cfg_path) {
if (!is_archive) good_cfg = config_read_file(&cfg, cfg_path);
else {
u8 *cfg_buf = NULL;
good_cfg = assetsPhysfsReadFile(cfg_path, &cfg_buf, NULL, true);
if (good_cfg) good_cfg = config_read_string(&cfg, (char*)cfg_buf);
free(cfg_buf);
}
}
}
switch (preset) {
@ -583,8 +607,8 @@ void themeStartup(ThemePreset preset) {
layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryVersion"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryVersion], false);
}
if (is_romfs) assets = config_lookup(&cfg, "assets");
if (is_romfs && assets) {
if (is_archive) assets = config_lookup(&cfg, "assets");
if (is_archive && assets) {
assetObjectFromSetting(config_setting_lookup(assets, "battery_icon"), AssetId_battery_icon, NULL);
assetObjectFromSetting(config_setting_lookup(assets, "charging_icon"), AssetId_charging_icon, NULL);
assetObjectFromSetting(config_setting_lookup(assets, "folder_icon"), AssetId_folder_icon, &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon]);
@ -622,6 +646,7 @@ void themeStartup(ThemePreset preset) {
config_destroy(&cfg);
if (is_archive) PHYSFS_unmount(theme_archive_path);
#ifdef __SWITCH__
if (is_romfs) romfsUnmount("theme");
#endif

View File

@ -68,6 +68,16 @@ static void launchFile(const char* path, argData_s* args)
init_args(argBuf, sizeof(argBuf)-1, args->buf, sizeof(args->buf));
struct stat st;
if (stat(path, &st) == -1) {
memset(msg, 0, sizeof(msg));
snprintf(msg, sizeof(msg)-1, textGetString(StrId_NroNotFound), path);
menuCreateMsgBox(780, 300, msg);
menuScan(".");
}
else {
Result rc = envSetNextLoad(path, argBuf);
if(R_FAILED(rc)) {
memset(msg, 0, sizeof(msg));
@ -79,6 +89,7 @@ static void launchFile(const char* path, argData_s* args)
uiExitLoop();
}
}
}
const loaderFuncs_s loader_builtin =
{

View File

@ -1,6 +1,7 @@
#include <switch.h>
#include <string.h>
#include <stdio.h>
#include <physfs.h>
#include "../common/common.h"
#include "nx_graphics.h"
@ -68,6 +69,13 @@ int main(int argc, char **argv)
if (R_SUCCEEDED(rc)) menuStartupPath();
if (R_SUCCEEDED(rc)) {
if (!PHYSFS_init(argv[0])) {
rc = 1;
snprintf(errormsg, sizeof(errormsg)-1, "Error: PHYSFS_init() failed: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
}
}
if (R_SUCCEEDED(rc)) {
rc = assetsInit();
if (R_FAILED(rc)) {
@ -189,6 +197,7 @@ int main(int argc, char **argv)
netloaderExit();
powerExit();
assetsExit();
PHYSFS_deinit();
appletUnlockExit();

View File

@ -8,7 +8,7 @@ static bool powerCacheIsCharging;
static PsmSession powerSession;
bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
ChargerType charger = ChargerType_None;
PsmChargerType charger = PsmChargerType_Unconnected;
bool hwReadsSucceeded = false;
bool use_cache = false;
Result rc = 0;
@ -31,7 +31,7 @@ bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
else {
rc = psmGetChargerType(&charger);
hwReadsSucceeded &= R_SUCCEEDED(rc);
*isCharging = (charger > ChargerType_None);
*isCharging = (charger != PsmChargerType_Unconnected);
}
powerCacheCharge = *batteryCharge;

View File

@ -9,6 +9,6 @@ void thermalstatusExit(void) {
}
bool thermalstatusGetDetails(s32 *temperature) {
return R_SUCCEEDED(tsGetTemperatureMilliC(TsLocation_Internal, temperature));
return R_SUCCEEDED(tsGetTemperature(TsLocation_Internal, temperature));
}

View File

@ -1,6 +1,7 @@
#include <SFML/Graphics.hpp>
#include <string.h>
#include <math.h>
#include <physfs.h>
extern "C" {
@ -10,12 +11,13 @@ extern "C" {
color_t pixels[720][1280];
int main()
int main(int argc, char **argv)
{
sf::RenderWindow window(sf::VideoMode(1280, 720), "Test");
window.setFramerateLimit(60);
menuStartupPath();
PHYSFS_init(argv[0]);
assetsInit();
themeStartup(THEME_PRESET_LIGHT);
textInit();
@ -62,6 +64,7 @@ int main()
netloaderExit();
fontExit();
assetsExit();
PHYSFS_deinit();
return 0;
}