Compare commits
No commits in common. "master" and "v3.0.0" have entirely different histories.
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
.*/
|
|
||||||
*~
|
*~
|
||||||
*.exe
|
*.exe
|
||||||
*.o
|
*.o
|
||||||
|
12
Makefile
@ -1,4 +1,4 @@
|
|||||||
export APP_VERSION := 3.5.1
|
export APP_VERSION := 3.0.0
|
||||||
|
|
||||||
ifeq ($(RELEASE),)
|
ifeq ($(RELEASE),)
|
||||||
export APP_VERSION := $(APP_VERSION)-$(shell git describe --dirty --always)
|
export APP_VERSION := $(APP_VERSION)-$(shell git describe --dirty --always)
|
||||||
@ -8,20 +8,18 @@ endif
|
|||||||
|
|
||||||
all: nx pc
|
all: nx pc
|
||||||
|
|
||||||
romfs:
|
romfs : assets
|
||||||
@mkdir -p romfs
|
@mkdir -p romfs
|
||||||
|
|
||||||
romfs/assets.zip : romfs assets
|
|
||||||
@rm -f romfs/assets.zip
|
@rm -f romfs/assets.zip
|
||||||
@zip -rj romfs/assets.zip assets
|
@zip -rj romfs/assets.zip assets
|
||||||
|
|
||||||
dist-bin: romfs/assets.zip
|
dist-bin: romfs
|
||||||
$(MAKE) -f Makefile.nx dist-bin
|
$(MAKE) -f Makefile.nx dist-bin
|
||||||
|
|
||||||
nx: romfs/assets.zip
|
nx: romfs
|
||||||
$(MAKE) -f Makefile.nx
|
$(MAKE) -f Makefile.nx
|
||||||
|
|
||||||
pc: romfs/assets.zip
|
pc: romfs
|
||||||
$(MAKE) -f Makefile.pc
|
$(MAKE) -f Makefile.pc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
55
Makefile.nx
@ -15,6 +15,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# DATA is a list of directories containing data files
|
# DATA is a list of directories containing data files
|
||||||
# INCLUDES is a list of directories containing header files
|
# INCLUDES is a list of directories containing header files
|
||||||
|
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||||
#
|
#
|
||||||
# NO_ICON: if set to anything, do not use icon.
|
# NO_ICON: if set to anything, do not use icon.
|
||||||
@ -28,26 +29,17 @@ include $(DEVKITPRO)/libnx/switch_rules
|
|||||||
# - <Project name>.jpg
|
# - <Project name>.jpg
|
||||||
# - icon.jpg
|
# - icon.jpg
|
||||||
# - <libnx folder>/default_icon.jpg
|
# - <libnx folder>/default_icon.jpg
|
||||||
#
|
|
||||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
|
||||||
# If not set, it attempts to use one of the following (in this order):
|
|
||||||
# - <Project name>.json
|
|
||||||
# - config.json
|
|
||||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
|
||||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
|
||||||
# NACP building is skipped as well.
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := $(notdir $(CURDIR))
|
TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := common/ nx_main/ nx_main/loaders/
|
SOURCES := common/ nx_main/ nx_main/loaders/
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
EXEFS_SRC := exefs_src
|
||||||
ROMFS := romfs
|
ROMFS := romfs
|
||||||
|
|
||||||
DIST_PATH := $(TARGET)_v$(APP_VERSION)
|
DIST_PATH := $(TARGET)_v$(APP_VERSION)
|
||||||
|
|
||||||
APP_AUTHOR := switchbrew
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@ -63,7 +55,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
|||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS := -ldeko3d -lphysfs `freetype-config --libs` -lconfig -lturbojpeg -lpng
|
LIBS := -lminizip `freetype-config --libs` -lconfig -lturbojpeg
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
@ -117,18 +109,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|||||||
|
|
||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
ifeq ($(strip $(CONFIG_JSON)),)
|
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||||
jsons := $(wildcard *.json)
|
|
||||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
|
||||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
|
||||||
else
|
|
||||||
ifneq (,$(findstring config.json,$(jsons)))
|
|
||||||
export APP_JSON := $(TOPDIR)/config.json
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(ICON)),)
|
ifeq ($(strip $(ICON)),)
|
||||||
icons := $(wildcard *.jpg)
|
icons := $(wildcard *.jpg)
|
||||||
@ -171,11 +152,7 @@ $(BUILD):
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
ifeq ($(strip $(APP_JSON)),)
|
@rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||||
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
|
||||||
else
|
|
||||||
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
|
|
||||||
endif
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
dist-bin: all
|
dist-bin: all
|
||||||
@ -192,9 +169,11 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
ifeq ($(strip $(APP_JSON)),)
|
all : $(OUTPUT).pfs0 $(OUTPUT).nro
|
||||||
|
|
||||||
all : $(OUTPUT).nro
|
$(OUTPUT).pfs0 : $(OUTPUT).nso
|
||||||
|
|
||||||
|
$(OUTPUT).nso : $(OUTPUT).elf
|
||||||
|
|
||||||
ifeq ($(strip $(NO_NACP)),)
|
ifeq ($(strip $(NO_NACP)),)
|
||||||
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
|
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
|
||||||
@ -202,17 +181,6 @@ else
|
|||||||
$(OUTPUT).nro : $(OUTPUT).elf
|
$(OUTPUT).nro : $(OUTPUT).elf
|
||||||
endif
|
endif
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
all : $(OUTPUT).nsp
|
|
||||||
|
|
||||||
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
|
|
||||||
|
|
||||||
$(OUTPUT).nso : $(OUTPUT).elf
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
menu.o : $(TOPDIR)/Makefile
|
|
||||||
$(OUTPUT).elf : $(OFILES)
|
$(OUTPUT).elf : $(OFILES)
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
$(OFILES_SRC) : $(HFILES_BIN)
|
||||||
@ -225,6 +193,11 @@ $(OFILES_SRC) : $(HFILES_BIN)
|
|||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(bin2o)
|
@$(bin2o)
|
||||||
|
|
||||||
|
%.nxfnt.o : %.nxfnt
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
-include $(DEPENDS)
|
-include $(DEPENDS)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
|
@ -9,12 +9,12 @@ EXTRA_CFLAGS="-D__USE_MINGW_ANSI_STDIO"
|
|||||||
EXTRA_LDFLAGS="-lws2_32"
|
EXTRA_LDFLAGS="-lws2_32"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test : pc_main/main.cpp pc_main/pc_launch.c pc_main/pc_power.c pc_main/pc_netstatus.c pc_main/pc_thermalstatus.c \
|
test : pc_main/main.cpp pc_main/pc_launch.c pc_main/pc_power.c \
|
||||||
common/menu.c common/font.c common/language.c common/launch.c common/worker.c common/status.c \
|
common/menu.c common/font.c common/language.c common/launch.c common/worker.c \
|
||||||
common/menu-entry.c common/menu-list.c common/message-box.c common/text.c \
|
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/ui.c common/assets.c common/math.c common/theme.c \
|
||||||
common/netloader.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 -lphysfs -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 -lminizip -lz -lconfig -lturbojpeg $(EXTRA_LDFLAGS) -I. -iquote $(DEVKITPRO)/libnx/include -Ibuild_pc -g -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build_pc/ test test.*
|
rm -rf build_pc/ test test.*
|
||||||
|
28
README.md
@ -1,31 +1,17 @@
|
|||||||
### Usage
|
#### Usage
|
||||||
See [Homebrew_Applications](https://switchbrew.org/wiki/Homebrew_Applications) for SD layout and applications, etc. See [Switchbrew](https://switchbrew.org/wiki/Homebrew_Menu) for hbmenu docs.
|
See [Homebrew_Applications](https://switchbrew.org/wiki/Homebrew_Applications) for SD layout and applications, etc. See [Switchbrew](https://switchbrew.org/wiki/Homebrew_Menu) for hbmenu docs.
|
||||||
|
|
||||||
### Download
|
#### Download
|
||||||
The latest release is available from the [releases](https://github.com/switchbrew/nx-hbmenu/releases/latest) page.
|
The latest release is available from the [releases](https://github.com/switchbrew/nx-hbmenu/releases/latest) page.
|
||||||
|
|
||||||
### Building
|
#### Building
|
||||||
Build for the Nintendo Switch with ```make nx``` and for the PC with ```make pc```.
|
Build with ```make nx``` or just run ```make```.
|
||||||
Running ```make``` builds for both systems.
|
|
||||||
|
|
||||||
The following [pacman packages](https://devkitpro.org/wiki/devkitPro_pacman) are required to build for Switch:
|
The following is required to build: libfreetype (switch-freetype), libconfig (switch-libconfig), and libjpeg-turbo (switch-libjpeg-turbo). Where "({name})" is the pacman package. For the pc-build libminizip is required (for the Switch build, the switch-zlib package includes this).
|
||||||
- `switch-dev`
|
|
||||||
- `switch-freetype`
|
|
||||||
- `switch-libconfig`
|
|
||||||
- `switch-libjpeg-turbo`
|
|
||||||
- `switch-physfs`
|
|
||||||
|
|
||||||
The following libraries are required to build for PC:
|
C11-threads are used, hence building for the pc-build may fail if C11-threads are not available.
|
||||||
- `libfreetype`
|
|
||||||
- `libconfig`
|
|
||||||
- `libjpeg-turbo`
|
|
||||||
- `libphysfs`
|
|
||||||
|
|
||||||
Building for Switch/PC requires `zip`.
|
|
||||||
|
|
||||||
Since C11 threads are used, building for the PC may fail if C11 threads are not available.
|
|
||||||
|
|
||||||
#### Credits
|
#### Credits
|
||||||
|
|
||||||
* This uses code based on 3DS [new-hbmenu](https://github.com/fincs/new-hbmenu).
|
* This uses code based on 3DS [new-hbmenu](https://github.com/fincs/new-hbmenu).
|
||||||
* `libjpeg-turbo` is used for handling JPEG icons. This library doesn't support lossless JPEG (likewise for official sw which uses `libjpeg-turbo`).
|
* libjpeg-turbo is used for handling JPEG icons. This library doesn't support lossless JPEG (likewise for official sw which uses libjpeg-turbo).
|
||||||
|
305
common/assets.c
@ -1,28 +1,25 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <physfs.h>
|
#include <minizip/unzip.h>
|
||||||
#include <png.h>
|
|
||||||
|
|
||||||
#define GENASSET(_p, _mode, _w, _h) {{.path = _p, .imageMode = _mode, .imageSize = {_w, _h}}, {}}
|
typedef struct {
|
||||||
|
u8 *buffer;
|
||||||
|
size_t size;
|
||||||
|
const char *filename;
|
||||||
|
} assetsDataEntry;
|
||||||
|
|
||||||
|
#define GENASSET(x) {.filename = x}
|
||||||
|
|
||||||
static bool g_assetsInitialized = 0;
|
static bool g_assetsInitialized = 0;
|
||||||
assetsDataEntry g_assetsDataList[AssetId_Max][2] = {
|
assetsDataEntry g_assetsDataList[AssetId_Max] = {
|
||||||
GENASSET("battery_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
GENASSET("battery_icon.bin"),
|
||||||
GENASSET("charging_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
GENASSET("charging_icon.bin"),
|
||||||
GENASSET("folder_icon.bin", IMAGE_MODE_RGB24, 256, 256),
|
GENASSET("folder_icon.bin"),
|
||||||
GENASSET("invalid_icon.bin", IMAGE_MODE_RGB24, 256, 256),
|
GENASSET("invalid_icon.bin"),
|
||||||
GENASSET("hbmenu_logo_dark.bin", IMAGE_MODE_RGBA32, 140, 60),
|
GENASSET("hbmenu_logo_dark.bin"),
|
||||||
GENASSET("hbmenu_logo_light.bin", IMAGE_MODE_RGBA32, 140, 60),
|
GENASSET("hbmenu_logo_light.bin"),
|
||||||
GENASSET("theme_icon_dark.bin", IMAGE_MODE_RGB24, 256, 256),
|
GENASSET("theme_icon_dark.bin"),
|
||||||
GENASSET("theme_icon_light.bin", IMAGE_MODE_RGB24, 256, 256),
|
GENASSET("theme_icon_light.bin"),
|
||||||
GENASSET("airplane_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("wifi_none_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("wifi1_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("wifi2_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("wifi3_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("eth_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("eth_none_icon.bin", IMAGE_MODE_RGBA32, 24, 24),
|
|
||||||
GENASSET("", IMAGE_MODE_RGB24, 1280, 720),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void assetsClearEntry(assetsDataEntry *entry) {
|
static void assetsClearEntry(assetsDataEntry *entry) {
|
||||||
@ -30,27 +27,61 @@ static void assetsClearEntry(assetsDataEntry *entry) {
|
|||||||
|
|
||||||
entry->size = 0;
|
entry->size = 0;
|
||||||
entry->buffer = NULL;
|
entry->buffer = NULL;
|
||||||
|
|
||||||
memset(entry, 0, sizeof(*entry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assetsSetPixelSize(assetsDataEntry *entry) {
|
static int assetsLoadFile(unzFile zipf, assetsDataEntry *entry) {
|
||||||
switch (entry->imageMode) {
|
int ret;
|
||||||
case IMAGE_MODE_RGB24:
|
int filesize=0;
|
||||||
entry->pixSize = 3;
|
unz_file_info file_info;
|
||||||
break;
|
u8* buffer = NULL;
|
||||||
|
|
||||||
case IMAGE_MODE_RGBA32:
|
ret = unzLocateFile(zipf, entry->filename, 0);
|
||||||
entry->pixSize = 4;
|
|
||||||
break;
|
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 == 0) 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) {
|
Result assetsInit(void) {
|
||||||
bool ret=false;
|
int ret=0;
|
||||||
int i, stopi;
|
int i, stopi;
|
||||||
|
unzFile zipf;
|
||||||
assetsDataEntry *entry = NULL;
|
assetsDataEntry *entry = NULL;
|
||||||
char tmp_path[PATH_MAX];
|
char tmp_path[PATH_MAX+1];
|
||||||
|
|
||||||
if (g_assetsInitialized) return 0;
|
if (g_assetsInitialized) return 0;
|
||||||
|
|
||||||
@ -67,211 +98,65 @@ Result assetsInit(void) {
|
|||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/romfs/assets.zip", menuGetRootBasePath());
|
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/romfs/assets.zip", menuGetRootBasePath());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (PHYSFS_mount(tmp_path, "", 0)) {
|
zipf = unzOpen(tmp_path);
|
||||||
ret=true;
|
if(zipf==NULL) {
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
romfsExit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<AssetId_Max; i++) {
|
for (i=0; i<AssetId_Max; i++) {
|
||||||
stopi = i;
|
stopi = i;
|
||||||
entry = &g_assetsDataList[i][0];
|
entry = &g_assetsDataList[i];
|
||||||
if (entry->path[0]) {
|
ret = assetsLoadFile(zipf, entry);
|
||||||
ret = assetsLoadData(i, NULL, NULL);
|
if (ret!=UNZ_OK) break;
|
||||||
if (!ret) break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) {
|
if (ret!=UNZ_OK) {
|
||||||
for (i=0; i<stopi; i++) {
|
for (i=0; i<stopi; i++) {
|
||||||
assetsClearEntry(&g_assetsDataList[i][0]);
|
assetsClearEntry(&g_assetsDataList[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) g_assetsInitialized = 1;
|
if (ret==UNZ_OK) g_assetsInitialized = 1;
|
||||||
|
|
||||||
PHYSFS_unmount(tmp_path);
|
unzClose(zipf);
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
romfsExit();
|
romfsExit();
|
||||||
return ret ? 0 : MAKERESULT(Module_Libnx, LibnxError_IoError);
|
|
||||||
#else
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assetsExit(void) {
|
void assetsExit(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!g_assetsInitialized) return;
|
if (!g_assetsInitialized) return;
|
||||||
g_assetsInitialized = 0;
|
g_assetsInitialized = 0;
|
||||||
|
|
||||||
for (int i=0; i<AssetId_Max; i++) {
|
for (i=0; i<AssetId_Max; i++) {
|
||||||
assetsClearEntry(&g_assetsDataList[i][0]);
|
assetsClearEntry(&g_assetsDataList[i]);
|
||||||
}
|
|
||||||
|
|
||||||
assetsClearTheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
void assetsClearTheme(void) {
|
|
||||||
for (int i=0; i<AssetId_Max; i++) {
|
|
||||||
assetsClearEntry(&g_assetsDataList[i][1]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assetsLoadJpgFromMemory(u8 *indata, size_t indata_size, u8 *outdata, ImageMode imageMode, size_t width, size_t height) {
|
void assetsGetData(AssetId id, u8 **buffer, size_t *size) {
|
||||||
int w,h,samp;
|
if (buffer) *buffer = NULL;
|
||||||
|
if (size) *size = 0;
|
||||||
tjhandle _jpegDecompressor = tjInitDecompress();
|
|
||||||
|
|
||||||
if (_jpegDecompressor == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tjDecompressHeader2(_jpegDecompressor, indata, indata_size, &w, &h, &samp) == -1) {
|
|
||||||
tjDestroy(_jpegDecompressor);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w != width || h != height ) {
|
|
||||||
tjDestroy(_jpegDecompressor);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tjDecompress2(_jpegDecompressor, indata, indata_size, outdata, w, 0, h, imageMode == IMAGE_MODE_RGB24 ? TJPF_RGB : TJPF_RGBA, TJFLAG_ACCURATEDCT) == -1) {
|
|
||||||
tjDestroy(_jpegDecompressor);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tjDestroy(_jpegDecompressor);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool assetsLoadPngFromMemory(u8 *indata, size_t indata_size, u8 *outdata, ImageMode imageMode, size_t width, size_t height) {
|
|
||||||
png_image image;
|
|
||||||
bool ret=true;
|
|
||||||
|
|
||||||
memset(&image, 0, sizeof(image));
|
|
||||||
image.version = PNG_IMAGE_VERSION;
|
|
||||||
|
|
||||||
if (png_image_begin_read_from_memory(&image, indata, indata_size) != 0) {
|
|
||||||
if (image.width != width || image.height != height)
|
|
||||||
ret = false;
|
|
||||||
|
|
||||||
if (ret) image.format = imageMode == IMAGE_MODE_RGB24 ? PNG_FORMAT_RGB : PNG_FORMAT_RGBA;
|
|
||||||
|
|
||||||
if (ret && png_image_finish_read(&image, NULL, outdata, 0, NULL) == 0)
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = false;
|
|
||||||
|
|
||||||
png_image_free(&image);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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][path ? 1 : 0];
|
|
||||||
if (entry->initialized) return false;
|
|
||||||
|
|
||||||
if (path) memset(entry, 0, sizeof(*entry));
|
|
||||||
|
|
||||||
if (imageSize) {
|
|
||||||
entry->imageSize[0] = imageSize[0];
|
|
||||||
entry->imageSize[1] = imageSize[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path) entry->imageMode = g_assetsDataList[id][0].imageMode;
|
|
||||||
assetsSetPixelSize(entry);
|
|
||||||
entry->size = entry->imageSize[0] * entry->imageSize[1] * entry->pixSize;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
entry->buffer = (u8*)malloc(entry->size);
|
|
||||||
if (entry->buffer) memset(entry->buffer, 0, entry->size);
|
|
||||||
else ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) ret = assetsPhysfsReadFile(entry->path, &data_buf, &filesize, false);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
if (strcasecmp(ext, ".bin")==0) {
|
|
||||||
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, filesize, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
|
|
||||||
else if (strcasecmp(ext, ".png")==0)
|
|
||||||
ret = assetsLoadPngFromMemory(data_buf, filesize, entry->buffer, entry->imageMode, entry->imageSize[0], entry->imageSize[1]);
|
|
||||||
else
|
|
||||||
ret = false; // File extension not recognized.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) entry->initialized = true;
|
|
||||||
else assetsClearEntry(entry);
|
|
||||||
|
|
||||||
free(data_buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void assetsGetData(AssetId id, assetsDataEntry **out) {
|
|
||||||
if (out) *out = NULL;
|
|
||||||
if (id < 0 || id >= AssetId_Max) return;
|
if (id < 0 || id >= AssetId_Max) return;
|
||||||
|
|
||||||
u32 pos = g_assetsDataList[id][1].initialized ? 1 : 0;
|
assetsDataEntry *entry = &g_assetsDataList[id];
|
||||||
assetsDataEntry *entry = &g_assetsDataList[id][pos];
|
|
||||||
if (entry->initialized) *out = entry;
|
if (buffer) *buffer = entry->buffer;
|
||||||
|
if (size) *size = entry->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *assetsGetDataBuffer(AssetId id) {
|
u8 *assetsGetDataBuffer(AssetId id) {
|
||||||
assetsDataEntry *entry = NULL;
|
u8 *buffer = NULL;
|
||||||
|
|
||||||
assetsGetData(id, &entry);
|
assetsGetData(id, &buffer, NULL);
|
||||||
return entry ? entry->buffer : NULL;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,35 +10,12 @@ typedef enum {
|
|||||||
AssetId_hbmenu_logo_light,
|
AssetId_hbmenu_logo_light,
|
||||||
AssetId_theme_icon_dark,
|
AssetId_theme_icon_dark,
|
||||||
AssetId_theme_icon_light,
|
AssetId_theme_icon_light,
|
||||||
AssetId_airplane_icon,
|
|
||||||
AssetId_wifi_none_icon,
|
|
||||||
AssetId_wifi1_icon,
|
|
||||||
AssetId_wifi2_icon,
|
|
||||||
AssetId_wifi3_icon,
|
|
||||||
AssetId_eth_icon,
|
|
||||||
AssetId_eth_none_icon,
|
|
||||||
AssetId_background_image,
|
|
||||||
|
|
||||||
AssetId_Max,
|
AssetId_Max
|
||||||
} AssetId;
|
} AssetId;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool initialized;
|
|
||||||
u8 *buffer;
|
|
||||||
size_t size;
|
|
||||||
ImageMode imageMode;
|
|
||||||
size_t pixSize;
|
|
||||||
size_t imageSize[2];
|
|
||||||
char path[PATH_MAX];
|
|
||||||
} assetsDataEntry;
|
|
||||||
|
|
||||||
Result assetsInit(void);
|
Result assetsInit(void);
|
||||||
void assetsExit(void);
|
void assetsExit(void);
|
||||||
void assetsClearTheme(void);
|
void assetsGetData(AssetId id, u8 **buffer, size_t *size);
|
||||||
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);
|
u8 *assetsGetDataBuffer(AssetId id);
|
||||||
|
|
||||||
bool assetsLoadJpgFromMemory(u8 *indata, size_t indata_size, u8 *outdata, ImageMode imageMode, size_t width, size_t height);
|
|
||||||
|
|
||||||
|
@ -21,11 +21,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
typedef int8_t s8;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef u32 Result;
|
typedef u32 Result;
|
||||||
|
|
||||||
typedef void (*workerThreadFunc)(void *);
|
typedef void (*workerThreadFunc)(void *);
|
||||||
@ -48,49 +45,6 @@ typedef union {
|
|||||||
};
|
};
|
||||||
} color_t;
|
} color_t;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ThemeLayoutId_Logo,
|
|
||||||
ThemeLayoutId_HbmenuVersion,
|
|
||||||
ThemeLayoutId_LoaderInfo,
|
|
||||||
ThemeLayoutId_AttentionText,
|
|
||||||
ThemeLayoutId_LogInfo,
|
|
||||||
ThemeLayoutId_InfoMsg,
|
|
||||||
ThemeLayoutId_MenuPath,
|
|
||||||
ThemeLayoutId_MenuTypeMsg,
|
|
||||||
ThemeLayoutId_MsgBoxSeparator,
|
|
||||||
ThemeLayoutId_MsgBoxBottomText,
|
|
||||||
ThemeLayoutId_BackgroundImage,
|
|
||||||
ThemeLayoutId_BackWave,
|
|
||||||
ThemeLayoutId_MiddleWave,
|
|
||||||
ThemeLayoutId_FrontWave,
|
|
||||||
ThemeLayoutId_ButtonA,
|
|
||||||
ThemeLayoutId_ButtonAText,
|
|
||||||
ThemeLayoutId_ButtonB,
|
|
||||||
ThemeLayoutId_ButtonBText,
|
|
||||||
ThemeLayoutId_ButtonY,
|
|
||||||
ThemeLayoutId_ButtonYText,
|
|
||||||
ThemeLayoutId_ButtonM,
|
|
||||||
ThemeLayoutId_ButtonMText,
|
|
||||||
ThemeLayoutId_ButtonX,
|
|
||||||
ThemeLayoutId_ButtonXText,
|
|
||||||
ThemeLayoutId_NetworkIcon,
|
|
||||||
ThemeLayoutId_BatteryCharge,
|
|
||||||
ThemeLayoutId_BatteryIcon,
|
|
||||||
ThemeLayoutId_ChargingIcon,
|
|
||||||
ThemeLayoutId_Status,
|
|
||||||
ThemeLayoutId_Temperature,
|
|
||||||
ThemeLayoutId_MenuList,
|
|
||||||
ThemeLayoutId_MenuListTiles,
|
|
||||||
ThemeLayoutId_MenuListIcon,
|
|
||||||
ThemeLayoutId_MenuListName,
|
|
||||||
ThemeLayoutId_MenuActiveEntryIcon,
|
|
||||||
ThemeLayoutId_MenuActiveEntryName,
|
|
||||||
ThemeLayoutId_MenuActiveEntryAuthor,
|
|
||||||
ThemeLayoutId_MenuActiveEntryVersion,
|
|
||||||
ThemeLayoutId_Total,
|
|
||||||
} ThemeLayoutId;
|
|
||||||
|
|
||||||
// when building for pc we need to include these separately
|
// when building for pc we need to include these separately
|
||||||
#ifndef __SWITCH__
|
#ifndef __SWITCH__
|
||||||
#include "switch/nro.h"
|
#include "switch/nro.h"
|
||||||
@ -110,9 +64,6 @@ typedef enum
|
|||||||
#include "message-box.h"
|
#include "message-box.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "netloader.h"
|
#include "netloader.h"
|
||||||
#include "netstatus.h"
|
|
||||||
#include "thermalstatus.h"
|
|
||||||
#include "status.h"
|
|
||||||
|
|
||||||
void menuStartupPath(void);
|
void menuStartupPath(void);
|
||||||
void menuStartup(void);
|
void menuStartup(void);
|
||||||
@ -142,7 +93,7 @@ static inline void DrawPixel(uint32_t x, uint32_t y, color_t clr)
|
|||||||
{
|
{
|
||||||
if (x >= 1280 || y >= 720)
|
if (x >= 1280 || y >= 720)
|
||||||
return;
|
return;
|
||||||
u32 off = y*g_framebuf_width + x*4;
|
u32 off = (y * g_framebuf_width + x)*4;
|
||||||
g_framebuf[off] = BlendColor(g_framebuf[off], clr.r, clr.a); off++;
|
g_framebuf[off] = BlendColor(g_framebuf[off], clr.r, clr.a); off++;
|
||||||
g_framebuf[off] = BlendColor(g_framebuf[off], clr.g, clr.a); off++;
|
g_framebuf[off] = BlendColor(g_framebuf[off], clr.g, clr.a); off++;
|
||||||
g_framebuf[off] = BlendColor(g_framebuf[off], clr.b, clr.a); off++;
|
g_framebuf[off] = BlendColor(g_framebuf[off], clr.b, clr.a); off++;
|
||||||
@ -152,7 +103,7 @@ static inline void DrawPixelRaw(uint32_t x, uint32_t y, color_t clr)
|
|||||||
{
|
{
|
||||||
if (x >= 1280 || y >= 720)
|
if (x >= 1280 || y >= 720)
|
||||||
return;
|
return;
|
||||||
u32 off = y*g_framebuf_width + x*4;
|
u32 off = (y * g_framebuf_width + x)*4;
|
||||||
*((u32*)&g_framebuf[off]) = clr.r | (clr.g<<8) | (clr.b<<16) | (0xff<<24);
|
*((u32*)&g_framebuf[off]) = clr.r | (clr.g<<8) | (clr.b<<16) | (0xff<<24);
|
||||||
}
|
}
|
||||||
static inline void Draw4PixelsRaw(uint32_t x, uint32_t y, color_t clr)
|
static inline void Draw4PixelsRaw(uint32_t x, uint32_t y, color_t clr)
|
||||||
@ -162,12 +113,12 @@ static inline void Draw4PixelsRaw(uint32_t x, uint32_t y, color_t clr)
|
|||||||
|
|
||||||
u32 color = clr.r | (clr.g<<8) | (clr.b<<16) | (0xff<<24);
|
u32 color = clr.r | (clr.g<<8) | (clr.b<<16) | (0xff<<24);
|
||||||
u128 val = color | ((u128)color<<32) | ((u128)color<<64) | ((u128)color<<96);
|
u128 val = color | ((u128)color<<32) | ((u128)color<<64) | ((u128)color<<96);
|
||||||
u32 off = y*g_framebuf_width + x*4;
|
u32 off = (y * g_framebuf_width + x)*4;
|
||||||
*((u128*)&g_framebuf[off]) = val;
|
*((u128*)&g_framebuf[off]) = val;
|
||||||
}
|
}
|
||||||
static inline color_t FetchPixelColor(uint32_t x, uint32_t y)
|
static inline color_t FetchPixelColor(uint32_t x, uint32_t y)
|
||||||
{
|
{
|
||||||
u32 off = y*g_framebuf_width + x*4;
|
u32 off = (y * g_framebuf_width + x)*4;
|
||||||
u32 val = *((u32*)&g_framebuf[off]);
|
u32 val = *((u32*)&g_framebuf[off]);
|
||||||
u8 r = (u8)val;
|
u8 r = (u8)val;
|
||||||
u8 g = (u8)(val>>8);
|
u8 g = (u8)(val>>8);
|
||||||
@ -207,8 +158,6 @@ static inline color_t FetchPixelColor(uint32_t x, uint32_t y)
|
|||||||
|
|
||||||
void DrawPixel(uint32_t x, uint32_t y, color_t clr);
|
void DrawPixel(uint32_t x, uint32_t y, color_t clr);
|
||||||
void DrawText(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text);
|
void DrawText(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text);
|
||||||
void DrawTextFromLayout(ThemeLayoutId id, color_t clr, const char* text);
|
|
||||||
void DrawTextFromLayoutRelative(ThemeLayoutId id, int base_x, int base_y, int *inPos, int *outPos, color_t clr, const char* text, const char align);
|
|
||||||
void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text);
|
void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text);
|
||||||
void GetTextDimensions(u32 font, const char* text, uint32_t* width_out, uint32_t* height_out);
|
void GetTextDimensions(u32 font, const char* text, uint32_t* width_out, uint32_t* height_out);
|
||||||
uint32_t GetTextXCoordinate(u32 font, uint32_t rX, const char* text, const char align);
|
uint32_t GetTextXCoordinate(u32 font, uint32_t rX, const char* text, const char align);
|
||||||
|
@ -9,20 +9,16 @@
|
|||||||
#define FONT_FACES_MAX 2
|
#define FONT_FACES_MAX 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
static bool s_plinited;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static FT_Error s_font_libret=1, s_font_facesret[FONT_FACES_MAX];
|
static FT_Error s_font_libret=1, s_font_facesret[FONT_FACES_MAX];
|
||||||
|
|
||||||
static FT_Library s_font_library;
|
static FT_Library s_font_library;
|
||||||
static FT_Face s_font_faces[FONT_FACES_MAX];
|
static FT_Face s_font_faces[FONT_FACES_MAX];
|
||||||
static FT_Face s_font_lastusedface;
|
static FT_Face s_font_lastusedface;
|
||||||
static s32 s_font_faces_total = 0;
|
static size_t s_font_faces_total = 0;
|
||||||
|
|
||||||
static bool FontSetType(u32 font)
|
static bool FontSetType(u32 font)
|
||||||
{
|
{
|
||||||
s32 i=0;
|
u32 i=0;
|
||||||
u32 scale=0;
|
u32 scale=0;
|
||||||
FT_Error ret=0;
|
FT_Error ret=0;
|
||||||
|
|
||||||
@ -48,10 +44,6 @@ static bool FontSetType(u32 font)
|
|||||||
scale = 8;
|
scale = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case largestar:
|
|
||||||
scale = 18;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
@ -84,12 +76,12 @@ static bool FontSetType(u32 font)
|
|||||||
|
|
||||||
static inline bool FontLoadGlyph(glyph_t* glyph, u32 font, uint32_t codepoint)
|
static inline bool FontLoadGlyph(glyph_t* glyph, u32 font, uint32_t codepoint)
|
||||||
{
|
{
|
||||||
FT_Face face=0;
|
FT_Face face;
|
||||||
FT_Error ret=0;
|
FT_Error ret=0;
|
||||||
FT_GlyphSlot slot;
|
FT_GlyphSlot slot;
|
||||||
FT_UInt glyph_index;
|
FT_UInt glyph_index;
|
||||||
FT_Bitmap* bitmap;
|
FT_Bitmap* bitmap;
|
||||||
s32 i=0;
|
u32 i=0;
|
||||||
|
|
||||||
//__builtin_printf("LoadGlyph %u\n", (unsigned int)codepoint);
|
//__builtin_printf("LoadGlyph %u\n", (unsigned int)codepoint);
|
||||||
/*const ffnt_page_t* page = FontGetPage(font, codepoint >> 8);
|
/*const ffnt_page_t* page = FontGetPage(font, codepoint >> 8);
|
||||||
@ -280,38 +272,6 @@ void DrawText(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text)
|
|||||||
DrawText_(font, x, y, clr, text, 0, NULL);
|
DrawText_(font, x, y, clr, text, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTextFromLayout(ThemeLayoutId id, color_t clr, const char* text)
|
|
||||||
{
|
|
||||||
ThemeLayoutObject *obj = &themeCurrent.layoutObjects[id];
|
|
||||||
if (!obj->visible) return;
|
|
||||||
|
|
||||||
DrawText(obj->font, obj->posStart[0], obj->posStart[1], clr, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawTextFromLayoutRelative(ThemeLayoutId id, int base_x, int base_y, int *inPos, int *outPos, color_t clr, const char* text, const char align)
|
|
||||||
{
|
|
||||||
ThemeLayoutObject *obj = &themeCurrent.layoutObjects[id];
|
|
||||||
|
|
||||||
base_x = obj->posType ? base_x + inPos[0] : inPos[0];
|
|
||||||
base_y = obj->posType ? base_y + inPos[1] : inPos[1];
|
|
||||||
|
|
||||||
base_x = GetTextXCoordinate(obj->font, base_x, text, align);
|
|
||||||
|
|
||||||
if (outPos) {
|
|
||||||
outPos[0] = base_x;
|
|
||||||
outPos[1] = base_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->posFinal[0] = base_x;
|
|
||||||
obj->posFinal[1] = base_y;
|
|
||||||
|
|
||||||
if (!obj->visible) return;
|
|
||||||
|
|
||||||
GetTextDimensions(obj->font, text, &obj->textSize[0], &obj->textSize[1]);
|
|
||||||
|
|
||||||
DrawText(obj->font, base_x, base_y, clr, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text)
|
void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text)
|
||||||
{
|
{
|
||||||
DrawText_(font, x, y, clr, text, max_width, end_text);
|
DrawText_(font, x, y, clr, text, max_width, end_text);
|
||||||
@ -349,14 +309,14 @@ void GetTextDimensions(u32 font, const char* text, uint32_t* width_out, uint32_t
|
|||||||
width = x;
|
width = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(width_out) *width_out = width;
|
*width_out = width;
|
||||||
if(height_out) *height_out = height;
|
*height_out = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fontInitialize(void)
|
bool fontInitialize(void)
|
||||||
{
|
{
|
||||||
FT_Error ret=0;
|
FT_Error ret=0;
|
||||||
s32 i;
|
u32 i;
|
||||||
|
|
||||||
for (i=0; i<FONT_FACES_MAX; i++) s_font_facesret[i] = 1;
|
for (i=0; i<FONT_FACES_MAX; i++) s_font_facesret[i] = 1;
|
||||||
|
|
||||||
@ -368,11 +328,7 @@ bool fontInitialize(void)
|
|||||||
PlFontData fonts[PlSharedFontType_Total];
|
PlFontData fonts[PlSharedFontType_Total];
|
||||||
|
|
||||||
Result rc=0;
|
Result rc=0;
|
||||||
rc = plInitialize(PlServiceType_User);
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
s_plinited = true;
|
|
||||||
rc = plGetSharedFont(textGetLanguageCode(), fonts, FONT_FACES_MAX, &s_font_faces_total);
|
rc = plGetSharedFont(textGetLanguageCode(), fonts, FONT_FACES_MAX, &s_font_faces_total);
|
||||||
}
|
|
||||||
if (R_FAILED(rc)) return false;
|
if (R_FAILED(rc)) return false;
|
||||||
|
|
||||||
for (i=0; i<s_font_faces_total; i++) {
|
for (i=0; i<s_font_faces_total; i++) {
|
||||||
@ -412,16 +368,12 @@ bool fontInitialize(void)
|
|||||||
|
|
||||||
void fontExit()
|
void fontExit()
|
||||||
{
|
{
|
||||||
s32 i=0;
|
u32 i=0;
|
||||||
|
|
||||||
for (i=0; i<s_font_faces_total; i++)
|
for (i=0; i<s_font_faces_total; i++)
|
||||||
if (s_font_facesret[i]==0) FT_Done_Face(s_font_faces[i]);
|
if (s_font_facesret[i]==0) FT_Done_Face(s_font_faces[i]);
|
||||||
|
|
||||||
if (s_font_libret==0) FT_Done_FreeType(s_font_library);
|
if (s_font_libret==0) FT_Done_FreeType(s_font_library);
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
if (s_plinited) plExit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Automatically gives you the desired x-coordinate
|
/*Automatically gives you the desired x-coordinate
|
||||||
|
@ -43,4 +43,3 @@ extern const ffnt_header_t interuiregular18_nxfnt;*/
|
|||||||
#define interuiregular14 0//&interuiregular14_nxfnt
|
#define interuiregular14 0//&interuiregular14_nxfnt
|
||||||
#define interuiregular18 1//&interuiregular18_nxfnt
|
#define interuiregular18 1//&interuiregular18_nxfnt
|
||||||
#define fontscale7 4
|
#define fontscale7 4
|
||||||
#define largestar 5
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "language.h"
|
#include "language.h"
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#define STR_JP(_str) [SetLanguage_JA] = _str
|
#define STR_JP(_str) [SetLanguage_JA] = _str
|
||||||
@ -7,12 +7,12 @@
|
|||||||
#define STR_DE(_str) [SetLanguage_DE] = _str
|
#define STR_DE(_str) [SetLanguage_DE] = _str
|
||||||
#define STR_IT(_str) [SetLanguage_IT] = _str
|
#define STR_IT(_str) [SetLanguage_IT] = _str
|
||||||
#define STR_ES(_str) [SetLanguage_ES] = _str, [SetLanguage_ES419] = _str
|
#define STR_ES(_str) [SetLanguage_ES] = _str, [SetLanguage_ES419] = _str
|
||||||
#define STR_ZH_HANS(_str) [SetLanguage_ZHCN] = _str, [SetLanguage_ZHHANS] = _str
|
#define STR_ZH(_str) [SetLanguage_ZHCN] = _str
|
||||||
#define STR_KO(_str) [SetLanguage_KO] = _str
|
#define STR_KO(_str) [SetLanguage_KO] = _str
|
||||||
#define STR_NL(_str) [SetLanguage_NL] = _str
|
#define STR_NL(_str) [SetLanguage_NL] = _str
|
||||||
#define STR_PT(_str) [SetLanguage_PT] = _str
|
#define STR_PT(_str) [SetLanguage_PT] = _str
|
||||||
#define STR_RU(_str) [SetLanguage_RU] = _str
|
#define STR_RU(_str) [SetLanguage_RU] = _str
|
||||||
#define STR_ZH_HANT(_str) [SetLanguage_ZHTW] = _str, [SetLanguage_ZHHANT] = _str
|
#define STR_TW(_str) [SetLanguage_ZHTW] = _str
|
||||||
#else
|
#else
|
||||||
#define STR_JP(_str) [0] = _str
|
#define STR_JP(_str) [0] = _str
|
||||||
#define STR_EN(_str) [1] = _str
|
#define STR_EN(_str) [1] = _str
|
||||||
@ -20,15 +20,15 @@
|
|||||||
#define STR_DE(_str) [3] = _str
|
#define STR_DE(_str) [3] = _str
|
||||||
#define STR_IT(_str) [4] = _str
|
#define STR_IT(_str) [4] = _str
|
||||||
#define STR_ES(_str) [5] = _str
|
#define STR_ES(_str) [5] = _str
|
||||||
#define STR_ZH_HANS(_str) [6] = _str
|
#define STR_ZH(_str) [6] = _str
|
||||||
#define STR_KO(_str) [7] = _str
|
#define STR_KO(_str) [7] = _str
|
||||||
#define STR_NL(_str) [8] = _str
|
#define STR_NL(_str) [8] = _str
|
||||||
#define STR_PT(_str) [9] = _str
|
#define STR_PT(_str) [9] = _str
|
||||||
#define STR_RU(_str) [10] = _str
|
#define STR_RU(_str) [10] = _str
|
||||||
#define STR_ZH_HANT(_str) [11] = _str
|
#define STR_TW(_str) [11] = _str
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* const g_strings[StrId_Max][17] =
|
const char* const g_strings[StrId_Max][16] =
|
||||||
{
|
{
|
||||||
[StrId_Loading] =
|
[StrId_Loading] =
|
||||||
{
|
{
|
||||||
@ -42,16 +42,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Laden…"),
|
STR_NL("Laden…"),
|
||||||
STR_KO("로딩중…"),
|
STR_KO("로딩중…"),
|
||||||
STR_RU("загрузка…"),
|
STR_RU("загрузка…"),
|
||||||
STR_ZH_HANS("加载中…"),
|
STR_ZH("加载中…"),
|
||||||
STR_ZH_HANT("載入中…"),
|
STR_TW("加載中…"),
|
||||||
},
|
|
||||||
|
|
||||||
[StrId_AppletMode] =
|
|
||||||
{
|
|
||||||
STR_EN("● Applet Mode ●"),
|
|
||||||
STR_ES("● Modo Applet ●"),
|
|
||||||
STR_FR("● Mode Applet ●"),
|
|
||||||
STR_ZH_HANS("● 小程序模式 ●"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_Directory] =
|
[StrId_Directory] =
|
||||||
@ -66,8 +58,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Map"),
|
STR_NL("Map"),
|
||||||
STR_KO("디렉토리"),
|
STR_KO("디렉토리"),
|
||||||
STR_RU("каталог"),
|
STR_RU("каталог"),
|
||||||
STR_ZH_HANS("目录"),
|
STR_ZH("目录"),
|
||||||
STR_ZH_HANT("資料夾"),
|
STR_TW("資料夾"),
|
||||||
},
|
},
|
||||||
|
|
||||||
/*[StrId_DefaultLongTitle] =
|
/*[StrId_DefaultLongTitle] =
|
||||||
@ -82,8 +74,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Homebrew toepassing"),
|
STR_NL("Homebrew toepassing"),
|
||||||
STR_KO("홈브류 애플리케이션"),
|
STR_KO("홈브류 애플리케이션"),
|
||||||
STR_RU("приложение хомебреw"),
|
STR_RU("приложение хомебреw"),
|
||||||
STR_ZH_HANS("自制应用程序"),
|
STR_ZH("自制应用程序"),
|
||||||
STR_ZH_HANT("自製程式"),
|
STR_TW("自製程式"),
|
||||||
},*/
|
},*/
|
||||||
|
|
||||||
[StrId_DefaultPublisher] =
|
[StrId_DefaultPublisher] =
|
||||||
@ -98,24 +90,24 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Auteur onbekend"),
|
STR_NL("Auteur onbekend"),
|
||||||
STR_KO("알 수 없는 개발자"),
|
STR_KO("알 수 없는 개발자"),
|
||||||
STR_RU("неизвестный автор"),
|
STR_RU("неизвестный автор"),
|
||||||
STR_ZH_HANS("未知作者"),
|
STR_ZH("未知作者"),
|
||||||
STR_ZH_HANT("作者未知"),
|
STR_TW("作者不詳"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_IOError] =
|
[StrId_IOError] =
|
||||||
{
|
{
|
||||||
STR_EN("I/O Error"),
|
STR_EN("I/O Error"),
|
||||||
STR_ES("Error de E/S"),
|
STR_ES("Error de E/S"),
|
||||||
STR_DE("I/O-Fehler"),
|
STR_DE("E/A-Fehler"),
|
||||||
STR_FR("Erreur d'E/S"),
|
STR_FR("Erreur d'E/S"),
|
||||||
STR_IT("Errore I/O"),
|
STR_IT("Errore di I/O"),
|
||||||
STR_JP("入出力エラー"),
|
STR_JP("入出力エラー"),
|
||||||
STR_PT("Erro de E/S"),
|
STR_PT("Erro de E/S"),
|
||||||
STR_NL("I/O Fout"),
|
STR_NL("I/O Fout"),
|
||||||
STR_KO("입출력 오류"),
|
STR_KO("입출력 오류"),
|
||||||
STR_RU("I/O-ошибка"),
|
STR_RU("I/O-ошибка"),
|
||||||
STR_ZH_HANS("读写出错"),
|
STR_ZH("读写出错"),
|
||||||
STR_ZH_HANT("取存錯誤"),
|
STR_TW("讀寫錯誤"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_CouldNotOpenFile] =
|
[StrId_CouldNotOpenFile] =
|
||||||
@ -130,15 +122,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Kan bestand niet openen:\n%s"),
|
STR_NL("Kan bestand niet openen:\n%s"),
|
||||||
STR_KO("파일을 열 수 없습니다:\n%s"),
|
STR_KO("파일을 열 수 없습니다:\n%s"),
|
||||||
STR_RU("Не могу открыть файл:\n%s"),
|
STR_RU("Не могу открыть файл:\n%s"),
|
||||||
STR_ZH_HANS("无法打开文件:\n%s"),
|
STR_ZH("无法打开文件:\n%s"),
|
||||||
STR_ZH_HANT("無法開啟檔案:\n%s"),
|
STR_TW("開啓檔案失敗:\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] =
|
[StrId_NoAppsFound_Title] =
|
||||||
@ -153,8 +138,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Geen toepassingen gevonden"),
|
STR_NL("Geen toepassingen gevonden"),
|
||||||
STR_KO("애플리케이션을 찾을 수 없습니다"),
|
STR_KO("애플리케이션을 찾을 수 없습니다"),
|
||||||
STR_RU("приложение не найдено"),
|
STR_RU("приложение не найдено"),
|
||||||
STR_ZH_HANS("找不到可执行的自制程序"),
|
STR_ZH("找不到可执行的自制程序"),
|
||||||
STR_ZH_HANT("沒有可執行的自製程式"),
|
STR_TW("未能找到可執行的自製程式"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NoAppsFound_Msg] =
|
[StrId_NoAppsFound_Msg] =
|
||||||
@ -172,7 +157,7 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_DE(
|
STR_DE(
|
||||||
"Auf der SD-Karte wurden keine Anwendungen\n"
|
"Auf der SD-Karte wurden keine Anwendungen\n"
|
||||||
"gefunden. Stelle sicher, dass ein Verzeichnis\n"
|
"gefunden. Stelle sicher, dass ein Verzeichnis\n"
|
||||||
"namens /switch im Hauptverzeichnis der SD-Karte\n"
|
"namens /switch im Wurzelverzeichnis der SD-Karte\n"
|
||||||
"existiert und Anwendungen enthält!"
|
"existiert und Anwendungen enthält!"
|
||||||
),
|
),
|
||||||
STR_FR(
|
STR_FR(
|
||||||
@ -214,15 +199,15 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"Убедитесь, что на карте SD есть каталог с\n"
|
"Убедитесь, что на карте SD есть каталог с\n"
|
||||||
"названием switch и она содержит приложения."
|
"названием switch и она содержит приложения."
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"找不到任何自制程序(nro)。\n"
|
"内存卡找不到任何可执行的应用程序。\n"
|
||||||
"在SD卡根目录建立“switch”文件夹,\n"
|
"请在内存卡的根目录建立「switch」子目录,\n"
|
||||||
"并将自制程序(nro)放在其中。"
|
"并存放自制应用软件至该目录。"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"記憶卡內沒有可供執行的應用程式。\n"
|
"記憶體找不到任何可執行的應用程式。\n"
|
||||||
"請在根目錄下建立「switch」資料夾,\n"
|
"請在記憶體建立「switch」資料夾,\n"
|
||||||
"並將自製軟體複製到switch資料夾內。"
|
"然後儲存自製軟體到此處。"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -230,24 +215,15 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
{
|
{
|
||||||
STR_EN("The last application returned an error:"),
|
STR_EN("The last application returned an error:"),
|
||||||
STR_ES("La última aplicación devolvió un error:"),
|
STR_ES("La última aplicación devolvió un error:"),
|
||||||
STR_DE("Die letzte Anwendung erzeugte einen Fehler:"),
|
|
||||||
STR_FR("La dernière application a retourné une erreur:"),
|
STR_FR("La dernière application a retourné une erreur:"),
|
||||||
STR_IT("L'ultima applicazione ha restituito un errore:"),
|
|
||||||
STR_JP("直前に実行したアプリでエラーが発生しました:"),
|
STR_JP("直前に実行したアプリでエラーが発生しました:"),
|
||||||
STR_KO("최근 애플리케이션에서 오류가 발생했습니다:"),
|
STR_KO("최근 애플리케이션에서 오류가 발생했습니다:"),
|
||||||
STR_ZH_HANS("程序运行后出现错误:"),
|
STR_TW("程式執行時發生錯誤:"),
|
||||||
STR_ZH_HANT("程式執行後出現錯誤:"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_AppLaunchError] =
|
[StrId_AppLaunchError] =
|
||||||
{
|
{
|
||||||
STR_EN("Failed to launch the application:"),
|
STR_EN("Failed to launch the application:"),
|
||||||
STR_DE("Konnte die Anwendung nicht starten:"),
|
|
||||||
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] =
|
[StrId_AppInfo_Author] =
|
||||||
@ -262,8 +238,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Auteur"),
|
STR_NL("Auteur"),
|
||||||
STR_KO("개발자"),
|
STR_KO("개발자"),
|
||||||
STR_RU("автор"),
|
STR_RU("автор"),
|
||||||
STR_ZH_HANS("作者"),
|
STR_ZH("作者"),
|
||||||
STR_ZH_HANT("作者"),
|
STR_TW("作者"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_AppInfo_Version] =
|
[StrId_AppInfo_Version] =
|
||||||
@ -278,8 +254,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Versie"),
|
STR_NL("Versie"),
|
||||||
STR_KO("버전"),
|
STR_KO("버전"),
|
||||||
STR_RU("Версия"),
|
STR_RU("Версия"),
|
||||||
STR_ZH_HANS("版本"),
|
STR_ZH("版"),
|
||||||
STR_ZH_HANT("版本"),
|
STR_TW("版"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_Actions_Launch] =
|
[StrId_Actions_Launch] =
|
||||||
@ -287,15 +263,15 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_EN("Launch"),
|
STR_EN("Launch"),
|
||||||
STR_ES("Lanzamiento"),
|
STR_ES("Lanzamiento"),
|
||||||
STR_DE("Starten"),
|
STR_DE("Starten"),
|
||||||
STR_FR("Lancer"),
|
STR_FR("Lancement"),
|
||||||
STR_IT("Avvia"),
|
STR_IT("Lanciare"),
|
||||||
STR_JP("起動"),
|
STR_JP("起動"),
|
||||||
STR_PT("Lançamento"),
|
STR_PT("Lançamento"),
|
||||||
STR_NL("Lancering"),
|
STR_NL("Lancering"),
|
||||||
STR_KO("실행"),
|
STR_KO("실행"),
|
||||||
STR_RU("запуск"),
|
STR_RU("запуск"),
|
||||||
STR_ZH_HANS("发射"),
|
STR_ZH("发射"),
|
||||||
STR_ZH_HANT("啟動"),
|
STR_TW("啟動"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_Actions_Open] =
|
[StrId_Actions_Open] =
|
||||||
@ -304,14 +280,14 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_ES("Abrir"),
|
STR_ES("Abrir"),
|
||||||
STR_DE("Öffnen"),
|
STR_DE("Öffnen"),
|
||||||
STR_FR("Ouvrir"),
|
STR_FR("Ouvrir"),
|
||||||
STR_IT("Apri"),
|
STR_IT("Aprire"),
|
||||||
STR_JP("開く"),
|
STR_JP("開く"),
|
||||||
STR_PT("Abrir"),
|
STR_PT("Abrir"),
|
||||||
STR_NL("Open"),
|
STR_NL("Open"),
|
||||||
STR_KO("열기"),
|
STR_KO("열기"),
|
||||||
STR_RU("открыто"),
|
STR_RU("открыто"),
|
||||||
STR_ZH_HANS("打开"),
|
STR_ZH("打开"),
|
||||||
STR_ZH_HANT("開啟"),
|
STR_TW("開啟"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_Actions_Back] =
|
[StrId_Actions_Back] =
|
||||||
@ -326,89 +302,54 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Terug"),
|
STR_NL("Terug"),
|
||||||
STR_KO("뒤로 가기"),
|
STR_KO("뒤로 가기"),
|
||||||
STR_RU("возвращаться"),
|
STR_RU("возвращаться"),
|
||||||
STR_ZH_HANS("返回"),
|
STR_ZH("回去"),
|
||||||
STR_ZH_HANT("返回"),
|
STR_TW("回去"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_MsgBox_OK] =
|
[StrId_MsgBox_OK] =
|
||||||
{
|
{
|
||||||
STR_EN("OK"),
|
STR_EN("OK"),
|
||||||
STR_DE("OK"),
|
|
||||||
STR_FR("OK"),
|
STR_FR("OK"),
|
||||||
STR_IT("OK"),
|
|
||||||
STR_ES("Aceptar"),
|
STR_ES("Aceptar"),
|
||||||
STR_JP("了解"),
|
STR_JP("了解"),
|
||||||
STR_KO("확인"),
|
STR_KO("확인"),
|
||||||
STR_ZH_HANS("确认"),
|
STR_TW("確認"),
|
||||||
STR_ZH_HANT("確認"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_Actions_Apply] =
|
[StrId_Actions_Apply] =
|
||||||
{
|
{
|
||||||
STR_EN("Apply"),
|
STR_EN("Apply"),
|
||||||
STR_FR("Appliquer"),
|
STR_FR("Appliquer"),
|
||||||
STR_DE("Anwenden"),
|
|
||||||
STR_ES("Aplicar"),
|
STR_ES("Aplicar"),
|
||||||
STR_IT("Applica"),
|
|
||||||
STR_JP("適用"),
|
STR_JP("適用"),
|
||||||
STR_KO("적용"),
|
STR_KO("적용"),
|
||||||
STR_ZH_HANS("应用"),
|
STR_TW("应用"),
|
||||||
STR_ZH_HANT("套用"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[StrId_Actions_Star] =
|
|
||||||
{
|
|
||||||
STR_EN("Star"),
|
|
||||||
STR_ES("Agregar a favoritos"),
|
|
||||||
STR_IT("Aggiungi ai preferiti"),
|
|
||||||
STR_FR("Ajouter aux favoris"),
|
|
||||||
STR_ZH_HANS("收藏"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[StrId_Actions_Unstar] =
|
|
||||||
{
|
|
||||||
STR_EN("Unstar"),
|
|
||||||
STR_ES("Borrar de favoritos"),
|
|
||||||
STR_IT("Rimuovi dai preferiti"),
|
|
||||||
STR_FR("Retirer des favoris"),
|
|
||||||
STR_ZH_HANS("取消收藏"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_ThemeMenu] =
|
[StrId_ThemeMenu] =
|
||||||
{
|
{
|
||||||
STR_EN("Theme Menu"),
|
STR_EN("Theme Menu"),
|
||||||
STR_FR("Menu thèmes"),
|
STR_FR("Menu Thème"),
|
||||||
STR_DE("Theme Menü"),
|
|
||||||
STR_ES("Menú temático"),
|
STR_ES("Menú temático"),
|
||||||
STR_IT("Tema Menu"),
|
|
||||||
STR_JP("テーマメニュー"),
|
STR_JP("テーマメニュー"),
|
||||||
STR_KO("테마 메뉴"),
|
STR_KO("테마 메뉴"),
|
||||||
STR_ZH_HANS("主题菜单"),
|
STR_TW("主题菜单"),
|
||||||
STR_ZH_HANT("主題選單"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_ThemeNotApplied] =
|
[StrId_ThemeNotApplied] =
|
||||||
{
|
{
|
||||||
STR_EN("Theme cannot be applied because an error occurred."),
|
STR_EN("Theme cannot be applied because an error occurred."),
|
||||||
STR_DE("Das Theme konnte nicht geladen werden, da ein Fehler aufgetreten ist."),
|
|
||||||
STR_FR("Le thème ne peut pas être appliqué car une erreur est survenue."),
|
STR_FR("Le thème ne peut pas être appliqué car une erreur est survenue."),
|
||||||
STR_ES("El tema no se pudo aplicar porque se ha producido un error."),
|
STR_ES("El tema no se pudo aplicar porque se ha producido un error."),
|
||||||
STR_IT("Il tema non è stato applicato a causa di un errore."),
|
|
||||||
STR_JP("エラーが発生したため、テーマを適用できませんでした。"),
|
STR_JP("エラーが発生したため、テーマを適用できませんでした。"),
|
||||||
STR_KO("오류가 발생 했기 때문에 테마를 적용할 수 없습니다."),
|
STR_KO("오류가 발생 했기 때문에 테마를 적용할 수 없습니다."),
|
||||||
STR_ZH_HANS("由于发生错误, 无法应用主题。"),
|
STR_TW("由于发生错误, 无法应用主题。"),
|
||||||
STR_ZH_HANT("出現錯誤,無法套用主題。"),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_DefaultThemeName] =
|
[StrId_DefaultThemeName] =
|
||||||
{
|
{
|
||||||
STR_EN("Default Theme"),
|
STR_EN("Default Theme"),
|
||||||
STR_FR("Thème par défaut"),
|
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] =
|
/*[StrId_Reboot] =
|
||||||
@ -474,13 +415,13 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
" \xEE\x80\x80 Перезагрузите\n"
|
" \xEE\x80\x80 Перезагрузите\n"
|
||||||
" \xEE\x80\x81 Отмена"
|
" \xEE\x80\x81 Отмена"
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"无法返回至主机的 \xEE\x81\xB3HOME 菜单。\n"
|
"无法返回至主机的 \xEE\x81\xB3HOME 菜单。\n"
|
||||||
"您需要重新启动您的 3DS 设备。\n\n"
|
"您需要重新启动您的 3DS 设备。\n\n"
|
||||||
" \xEE\x80\x80 重启设备\n"
|
" \xEE\x80\x80 重启设备\n"
|
||||||
" \xEE\x80\x81 取消操作"
|
" \xEE\x80\x81 取消操作"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"無法返回至主機的 \xEE\x81\xB3HOME 選單。\n"
|
"無法返回至主機的 \xEE\x81\xB3HOME 選單。\n"
|
||||||
"您需要重新啓動您的 3DS 設備。\n\n"
|
"您需要重新啓動您的 3DS 設備。\n\n"
|
||||||
" \xEE\x80\x80 重啓設備\n"
|
" \xEE\x80\x80 重啓設備\n"
|
||||||
@ -550,13 +491,13 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
" \xEE\x80\x81 Отмена\n"
|
" \xEE\x80\x81 Отмена\n"
|
||||||
" \xEE\x80\x82 Перезагрузите"
|
" \xEE\x80\x82 Перезагрузите"
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"您即将返回到主機的 \xEE\x81\xB3HOME 菜单。\n\n"
|
"您即将返回到主機的 \xEE\x81\xB3HOME 菜单。\n\n"
|
||||||
" \xEE\x80\x80 确认返回\n"
|
" \xEE\x80\x80 确认返回\n"
|
||||||
" \xEE\x80\x81 取消操作\n"
|
" \xEE\x80\x81 取消操作\n"
|
||||||
" \xEE\x80\x82 重启设备"
|
" \xEE\x80\x82 重启设备"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"您即將返回到主機的 \xEE\x81\xB3HOME 選單。\n\n"
|
"您即將返回到主機的 \xEE\x81\xB3HOME 選單。\n\n"
|
||||||
" \xEE\x80\x80 確認返回\n"
|
" \xEE\x80\x80 確認返回\n"
|
||||||
" \xEE\x80\x81 取消操作\n"
|
" \xEE\x80\x81 取消操作\n"
|
||||||
@ -568,7 +509,7 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
{
|
{
|
||||||
STR_EN("Title selector"),
|
STR_EN("Title selector"),
|
||||||
STR_ES("Selector de título"),
|
STR_ES("Selector de título"),
|
||||||
STR_DE("Titel-Auswahl"),
|
STR_DE("Titel-Selektor"),
|
||||||
STR_FR("Sélecteur de titre"),
|
STR_FR("Sélecteur de titre"),
|
||||||
STR_IT("Selettore del titolo"),
|
STR_IT("Selettore del titolo"),
|
||||||
STR_JP("タイトルセレクタ"),
|
STR_JP("タイトルセレクタ"),
|
||||||
@ -576,18 +517,18 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Titel selector"),
|
STR_NL("Titel selector"),
|
||||||
STR_KO("타이틀 선택기"),
|
STR_KO("타이틀 선택기"),
|
||||||
STR_RU("Селектор заголовков"),
|
STR_RU("Селектор заголовков"),
|
||||||
STR_ZH_HANS("应用启动器"),
|
STR_ZH("应用启动器"),
|
||||||
STR_ZH_HANT("自製程式啓動器"),
|
STR_TW("自製程式啓動器"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_ErrorReadingTitleMetadata] =
|
[StrId_ErrorReadingTitleMetadata] =
|
||||||
{
|
{
|
||||||
STR_EN("Error reading title metadata.\n%08lX%08lX@%d"),
|
STR_EN("Error reading title metadata.\n%08lX%08lX@%d"),
|
||||||
STR_ES("Error leyendo los metadatos de los títulos.\n%08lX%08lX@%d"),
|
STR_ES("Error leyendo los metadatos de los títulos.\n%08lX%08lX@%d"),
|
||||||
STR_DE("Fehler beim Lesen der Titel-Metadaten.\n%08lX%08lX@%d"),
|
STR_DE("Fehler beim lesen der Titel-Metadaten.\n%08lX%08lX@%d"),
|
||||||
STR_FR(
|
STR_FR(
|
||||||
"Erreur lors de la lecture des métadonnées\n"
|
"Erreur lors de la lecture des métadonnées\n"
|
||||||
"du titre.\n%08lX%08lX@%d"
|
"de titre.\n%08lX%08lX@%d"
|
||||||
),
|
),
|
||||||
STR_IT("Errore nella lettura dei metadata dei titoli.\n%08lX%08lX@%d"),
|
STR_IT("Errore nella lettura dei metadata dei titoli.\n%08lX%08lX@%d"),
|
||||||
STR_JP("タイトルメタデータを読み取ることができませんでした。\n%08lX%08lX@%d"),
|
STR_JP("タイトルメタデータを読み取ることができませんでした。\n%08lX%08lX@%d"),
|
||||||
@ -595,8 +536,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Fout bij het lezen van titel metadata.\n%08lX%08lX@%d"),
|
STR_NL("Fout bij het lezen van titel metadata.\n%08lX%08lX@%d"),
|
||||||
STR_KO("타이틀 메타데이터를 읽는데 실패하였습니다.\n%08lX%08lX@%d"),
|
STR_KO("타이틀 메타데이터를 읽는데 실패하였습니다.\n%08lX%08lX@%d"),
|
||||||
STR_RU("Ошибка чтения метаданных заголовка\n.%08lX%08lX@%d"),
|
STR_RU("Ошибка чтения метаданных заголовка\n.%08lX%08lX@%d"),
|
||||||
STR_ZH_HANS("读取软件相关信息时发生错误:\n%08lX%08lX@%d"),
|
STR_ZH("读取软件相关信息时发生错误:\n%08lX%08lX@%d"),
|
||||||
STR_ZH_HANT("讀取軟體相關資訊時發生錯誤:\n%08lX%08lX@%d"),
|
STR_TW("讀取軟體相關數據時發生錯誤:\n%08lX%08lX@%d"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NoTitlesFound] =
|
[StrId_NoTitlesFound] =
|
||||||
@ -611,8 +552,8 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Geen titels gevonden."),
|
STR_NL("Geen titels gevonden."),
|
||||||
STR_KO("타이틀을 찾을 수 없습니다."),
|
STR_KO("타이틀을 찾을 수 없습니다."),
|
||||||
STR_RU("Заголовки не обнаружены"),
|
STR_RU("Заголовки не обнаружены"),
|
||||||
STR_ZH_HANS("主机内找不到任何软件。"),
|
STR_ZH("主机内找不到任何软件。"),
|
||||||
STR_ZH_HANT("主機内找不到任何軟體。"),
|
STR_TW("主機内找不到任何軟體。"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_SelectTitle] =
|
[StrId_SelectTitle] =
|
||||||
@ -667,12 +608,12 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
" \xEE\x80\x80 Выберите\n"
|
" \xEE\x80\x80 Выберите\n"
|
||||||
" \xEE\x80\x81 Отмена"
|
" \xEE\x80\x81 Отмена"
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"请选择一个目标软件。\n\n"
|
"请选择一个目标软件。\n\n"
|
||||||
" \xEE\x80\x80 确认\n"
|
" \xEE\x80\x80 确认\n"
|
||||||
" \xEE\x80\x81 取消"
|
" \xEE\x80\x81 取消"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"請選擇一個目標軟體。\n\n"
|
"請選擇一個目標軟體。\n\n"
|
||||||
" \xEE\x80\x80 確認\n"
|
" \xEE\x80\x80 確認\n"
|
||||||
" \xEE\x80\x81 取消"
|
" \xEE\x80\x81 取消"
|
||||||
@ -731,14 +672,14 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"приложений под целевыми заголовками.\n"
|
"приложений под целевыми заголовками.\n"
|
||||||
"Пожалуйста, используйте другой эксплойт."
|
"Пожалуйста, используйте другой эксплойт."
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"您所利用漏洞启动的「自制软件启动器」,\n"
|
"您所利用漏洞启动的「自制软件启动器」,\n"
|
||||||
"无法在当前选中的软件中启动自制软件。\n"
|
"无法在当前选中的软件中启动自制软件。\n"
|
||||||
"请使用其它的漏洞来启动「自制软件启动器」。"
|
"请使用其它的漏洞来启动「自制软件启动器」。"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"您所利用漏洞開啓的「自製軟體啓動器」\n"
|
"您所利用漏洞開啓的「自製軟體啓動器」\n"
|
||||||
"無法在當前選中的軟體啓動自製軟體。\n"
|
"無法在當前選中的軟體啓動自製軟件。\n"
|
||||||
"請利用其它漏洞來啓動「自製軟體啓動器」。"
|
"請利用其它漏洞來啓動「自製軟體啓動器」。"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -755,7 +696,7 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
),
|
),
|
||||||
STR_DE(
|
STR_DE(
|
||||||
"Die ausgewählte Anwendung benötigt einen\n"
|
"Die ausgewählte Anwendung benötigt einen\n"
|
||||||
"Titel der nicht installiert ist."
|
"Titel der nicht installiert ist"
|
||||||
),
|
),
|
||||||
STR_FR(
|
STR_FR(
|
||||||
"L'application sélectionnée requiert un titre\n"
|
"L'application sélectionnée requiert un titre\n"
|
||||||
@ -785,11 +726,11 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"Для приложения требуется зависимость,\n"
|
"Для приложения требуется зависимость,\n"
|
||||||
"которая не установлена."
|
"которая не установлена."
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"主机找不到该应用程序\n"
|
"主机找不到该应用程序\n"
|
||||||
"所需求的软件。"
|
"所需求的软件。"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"主機找不到該應用程式\n"
|
"主機找不到該應用程式\n"
|
||||||
"所需求的軟體。"
|
"所需求的軟體。"
|
||||||
),
|
),
|
||||||
@ -800,15 +741,15 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_EN("NetLoader"),
|
STR_EN("NetLoader"),
|
||||||
STR_ES("Cargador de programas"),
|
STR_ES("Cargador de programas"),
|
||||||
STR_DE("Netzwerk-Loader"),
|
STR_DE("Netzwerk-Loader"),
|
||||||
STR_FR("NetLoader"),
|
STR_FR("Chargeur de programme"),
|
||||||
STR_IT("Caricamento programmi"),
|
STR_IT("Caricamento programmi"),
|
||||||
STR_JP("ネットローダ"),
|
STR_JP("ネットローダ"),
|
||||||
STR_PT("Carregador de programas"),
|
STR_PT("Carregador de programas"),
|
||||||
STR_NL("netwerk lader"),
|
STR_NL("netwerk lader"),
|
||||||
STR_KO("네트워크 로더"),
|
STR_KO("네트워크 로더"),
|
||||||
STR_RU("Загрузчик"),
|
STR_RU("Загрузчик"),
|
||||||
STR_ZH_HANS("网络执行模块"),
|
STR_ZH("网络执行模块"),
|
||||||
STR_ZH_HANT("網路執行模組"),
|
STR_TW("網路執行模組"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NetLoaderUnavailable] =
|
[StrId_NetLoaderUnavailable] =
|
||||||
@ -816,15 +757,15 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_EN("The NetLoader is currently unavailable."),
|
STR_EN("The NetLoader is currently unavailable."),
|
||||||
STR_ES("El cargador de programas no está disponible."),
|
STR_ES("El cargador de programas no está disponible."),
|
||||||
STR_DE("Der Netzwerk-Loader ist zur Zeit nicht verfügbar."),
|
STR_DE("Der Netzwerk-Loader ist zur Zeit nicht verfügbar."),
|
||||||
STR_FR("Le programme nxlink est indisponible."),
|
STR_FR("Le chargeur de programme nxlink est indisponible."),
|
||||||
STR_IT("Il caricamento programmi nxlink non è disponibile."),
|
STR_IT("Il caricamento programmi nxlink non è disponibile."),
|
||||||
STR_JP("nxlinkネットローダは現在利用できません。"),
|
STR_JP("nxlinkネットローダは現在利用できません。"),
|
||||||
STR_PT("O carregador de programas está de momento indisponível."),
|
STR_PT("O carregador de programas está de momento indisponível."),
|
||||||
STR_NL("De netwerk lader is niet beschikbaar."),
|
STR_NL("De netwerk lader is niet beschikbaar."),
|
||||||
STR_KO("현재 네트워크 로더는 사용이 불가합니다."),
|
STR_KO("현재 네트워크 로더는 사용이 불가합니다."),
|
||||||
STR_RU("Загрузчик в настоящее время недоступен."),
|
STR_RU("Загрузчик в настоящее время недоступен."),
|
||||||
STR_ZH_HANS("无法启动 nxlink 网络执行模块。"),
|
STR_ZH("无法启动 nxlink 网络执行模块。"),
|
||||||
STR_ZH_HANT("無法啓動 nxlink 網路執行模組。"),
|
STR_TW("無法啓動 nxlink 網路執行模組。"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NetLoaderError] =
|
[StrId_NetLoaderError] =
|
||||||
@ -839,21 +780,19 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
STR_NL("Er is een fout opgetreden\nTechnische details: [%s:%d]"),
|
STR_NL("Er is een fout opgetreden\nTechnische details: [%s:%d]"),
|
||||||
STR_KO("오류가 발생했습니다.\n기술적인 세부사항: [%s:%d]"),
|
STR_KO("오류가 발생했습니다.\n기술적인 세부사항: [%s:%d]"),
|
||||||
STR_RU("Произошла ошибка.\nТехнические подробности: [%s:%d]"),
|
STR_RU("Произошла ошибка.\nТехнические подробности: [%s:%d]"),
|
||||||
STR_ZH_HANS("发生错误。\n详细错误信息:[%s:%d]"),
|
STR_ZH("发生错误。\n详细错误信息:[%s:%d]"),
|
||||||
STR_ZH_HANT("發生錯誤。\n詳細錯誤資訊:[%s:%d]"),
|
STR_TW("發生錯誤。\n詳細錯誤資訊:[%s:%d]"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NetLoaderOffline] =
|
[StrId_NetLoaderOffline] =
|
||||||
{
|
{
|
||||||
STR_EN("Offline, waiting for network…"),
|
STR_EN("Offline, waiting for network…"),
|
||||||
STR_DE("Offline, warte auf Netzwerk…"),
|
|
||||||
STR_FR("Hors-ligne, en attente d'une connection..."),
|
STR_FR("Hors-ligne, en attente d'une connection..."),
|
||||||
STR_IT("Disconnesso, in attesa della connessione…"),
|
STR_IT("Disconnesso, in attesa della connessione…"),
|
||||||
STR_ES("Desconectado, esperando a la red..."),
|
|
||||||
STR_JP("オフラインです。ネットワーク接続を待っています…"),
|
STR_JP("オフラインです。ネットワーク接続を待っています…"),
|
||||||
STR_KO("연결 끊김, 네트워크 기다리는 중…"),
|
STR_KO("연결 끊김, 네트워크 기다리는 중…"),
|
||||||
STR_ZH_HANS("无法连接网络,等待网络连接…"),
|
STR_ZH("无法连接网络,等待网络连接…"),
|
||||||
STR_ZH_HANT("目前已離線,等待網路連線…"),
|
STR_TW("當前離線,等待網路連線…"),
|
||||||
},
|
},
|
||||||
|
|
||||||
[StrId_NetLoaderActive] =
|
[StrId_NetLoaderActive] =
|
||||||
@ -867,7 +806,7 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"Dir.IP: %lu.%lu.%lu.%lu, Puerto: %d"
|
"Dir.IP: %lu.%lu.%lu.%lu, Puerto: %d"
|
||||||
),
|
),
|
||||||
STR_DE(
|
STR_DE(
|
||||||
"Warte auf Verbindung von nxlink…\n"
|
"Warte auf Verbindung von 3dslink…\n"
|
||||||
"IP Addr: %lu.%lu.%lu.%lu, Port: %d"
|
"IP Addr: %lu.%lu.%lu.%lu, Port: %d"
|
||||||
),
|
),
|
||||||
STR_FR(
|
STR_FR(
|
||||||
@ -898,11 +837,11 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"Ожидание подключения nxlink…\n"
|
"Ожидание подключения nxlink…\n"
|
||||||
"айпи адрес: %lu.%lu.%lu.%lu, Порт: %d"
|
"айпи адрес: %lu.%lu.%lu.%lu, Порт: %d"
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"等待 nxlink 连接…\n"
|
"等待 nxlink 连接…\n"
|
||||||
"IP 地址:%lu.%lu.%lu.%lu,端口:%d"
|
"IP 地址:%lu.%lu.%lu.%lu,端口:%d"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"等待 nxlink 連接…\n"
|
"等待 nxlink 連接…\n"
|
||||||
"IP 位址:%lu.%lu.%lu.%lu,連接埠:%d"
|
"IP 位址:%lu.%lu.%lu.%lu,連接埠:%d"
|
||||||
),
|
),
|
||||||
@ -950,13 +889,14 @@ const char* const g_strings[StrId_Max][17] =
|
|||||||
"Передача…\n"
|
"Передача…\n"
|
||||||
"%zu из %zu КИБ написано"
|
"%zu из %zu КИБ написано"
|
||||||
),
|
),
|
||||||
STR_ZH_HANS(
|
STR_ZH(
|
||||||
"正在传输…\n"
|
"正在传输…\n"
|
||||||
"已完成 %zu / %zu KiB"
|
"已完成 %zu / %zu KiB"
|
||||||
),
|
),
|
||||||
STR_ZH_HANT(
|
STR_TW(
|
||||||
"正在傳輸…\n"
|
"正在傳輸…\n"
|
||||||
"已完成 %zu / %zu KiB"
|
"已完成 %zu / %zu KiB"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,12 +6,10 @@
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
StrId_Loading = 0,
|
StrId_Loading = 0,
|
||||||
StrId_AppletMode,
|
|
||||||
StrId_Directory,
|
StrId_Directory,
|
||||||
StrId_DefaultPublisher,
|
StrId_DefaultPublisher,
|
||||||
StrId_IOError,
|
StrId_IOError,
|
||||||
StrId_CouldNotOpenFile,
|
StrId_CouldNotOpenFile,
|
||||||
StrId_NroNotFound,
|
|
||||||
|
|
||||||
StrId_NoAppsFound_Title,
|
StrId_NoAppsFound_Title,
|
||||||
StrId_NoAppsFound_Msg,
|
StrId_NoAppsFound_Msg,
|
||||||
@ -25,8 +23,6 @@ typedef enum
|
|||||||
StrId_Actions_Open,
|
StrId_Actions_Open,
|
||||||
StrId_Actions_Back,
|
StrId_Actions_Back,
|
||||||
StrId_Actions_Apply,
|
StrId_Actions_Apply,
|
||||||
StrId_Actions_Star,
|
|
||||||
StrId_Actions_Unstar,
|
|
||||||
|
|
||||||
StrId_MsgBox_OK,
|
StrId_MsgBox_OK,
|
||||||
|
|
||||||
@ -55,5 +51,5 @@ typedef enum
|
|||||||
StrId_Max,
|
StrId_Max,
|
||||||
} StrId;
|
} StrId;
|
||||||
|
|
||||||
extern const char* const g_strings[StrId_Max][17];
|
extern const char* const g_strings[StrId_Max][16];
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
void menuEntryInit(menuEntry_s* me, MenuEntryType type) {
|
void menuEntryInit(menuEntry_s* me, MenuEntryType type) {
|
||||||
memset(me, 0, sizeof(*me));
|
memset(me, 0, sizeof(*me));
|
||||||
@ -81,13 +80,9 @@ static bool menuEntryLoadEmbeddedIcon(menuEntry_s* me) {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool menuEntryLoadExternalIcon(menuEntry_s* me, const char* path, bool data_source) {
|
static bool menuEntryLoadExternalIcon(menuEntry_s* me, const char* path) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
if (data_source) {
|
|
||||||
return assetsPhysfsReadFile(path, &me->icon, &me->icon_size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stat(path, &st)==-1) return false;
|
if(stat(path, &st)==-1) return false;
|
||||||
|
|
||||||
FILE* f = fopen(path, "rb");
|
FILE* f = fopen(path, "rb");
|
||||||
@ -111,15 +106,12 @@ static bool menuEntryImportIconGfx(menuEntry_s* me, uint8_t* icon_gfx, uint8_t*
|
|||||||
|
|
||||||
if (icon_gfx == NULL || icon_gfx_small == NULL) return false;
|
if (icon_gfx == NULL || icon_gfx_small == NULL) return false;
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon];
|
tmpsize = 256*256*3;
|
||||||
ThemeLayoutObject *layoutobj2 = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon];
|
|
||||||
|
|
||||||
tmpsize = layoutobj->size[0]*layoutobj->size[1]*3;
|
|
||||||
me->icon_gfx = (uint8_t*)malloc(tmpsize);
|
me->icon_gfx = (uint8_t*)malloc(tmpsize);
|
||||||
if (me->icon_gfx) memcpy(me->icon_gfx, icon_gfx, tmpsize);
|
if (me->icon_gfx) memcpy(me->icon_gfx, icon_gfx, tmpsize);
|
||||||
|
|
||||||
if (me->icon_gfx) {
|
if (me->icon_gfx) {
|
||||||
tmpsize = layoutobj2->size[0]*layoutobj2->size[1]*3;
|
tmpsize = 140*140*3;
|
||||||
me->icon_gfx_small = (uint8_t*)malloc(tmpsize);
|
me->icon_gfx_small = (uint8_t*)malloc(tmpsize);
|
||||||
if (me->icon_gfx_small) memcpy(me->icon_gfx_small, icon_gfx_small, tmpsize);
|
if (me->icon_gfx_small) memcpy(me->icon_gfx_small, icon_gfx_small, tmpsize);
|
||||||
|
|
||||||
@ -176,26 +168,6 @@ static bool menuEntryLoadEmbeddedNacp(menuEntry_s* me) {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool menuEntryLoadExternalNacp(menuEntry_s* me, const char* path) {
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if(stat(path, &st)==-1) return false;
|
|
||||||
|
|
||||||
FILE* f = fopen(path, "rb");
|
|
||||||
if (!f) return false;
|
|
||||||
|
|
||||||
me->nacp = (NacpStruct*)malloc(sizeof(NacpStruct));
|
|
||||||
if (me->nacp == NULL) {
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memset(me->nacp, 0, sizeof(NacpStruct));
|
|
||||||
|
|
||||||
bool ok = fread(me->nacp, sizeof(NacpStruct), 1, f) == 1;
|
|
||||||
fclose(f);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static void fixSpaceNewLine(char* buf) {
|
/*static void fixSpaceNewLine(char* buf) {
|
||||||
char *outp = buf, *inp = buf;
|
char *outp = buf, *inp = buf;
|
||||||
char lastc = 0;
|
char lastc = 0;
|
||||||
@ -210,18 +182,18 @@ static bool menuEntryLoadExternalNacp(menuEntry_s* me, const char* path) {
|
|||||||
} while (lastc);
|
} while (lastc);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_exists) {
|
bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) {
|
||||||
int i=0, tmplen;
|
int i=0;
|
||||||
menu_s *menu_fileassoc = menuFileassocGetCurrent();
|
menu_s *menu_fileassoc = menuFileassocGetCurrent();
|
||||||
menuEntry_s* fileassoc_me = NULL;
|
menuEntry_s* fileassoc_me = NULL;
|
||||||
char *strptr = NULL;
|
char *strptr = NULL;
|
||||||
char tempbuf[PATH_MAX+16];
|
static char tempbuf[PATH_MAX+1];
|
||||||
//bool isOldAppFolder = false;
|
//bool isOldAppFolder = false;
|
||||||
|
|
||||||
if (check_exists && !fsobjExists(me->path)) return false;
|
if (!fsobjExists(me->path)) return false;
|
||||||
|
|
||||||
tempbuf[PATH_MAX] = 0;
|
tempbuf[PATH_MAX] = 0;
|
||||||
strncpy(me->name, name, sizeof(me->name)-1);
|
strcpy(me->name, name);
|
||||||
|
|
||||||
if (me->type == ENTRY_TYPE_FOLDER)
|
if (me->type == ENTRY_TYPE_FOLDER)
|
||||||
{
|
{
|
||||||
@ -231,8 +203,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
bool fileassoc_flag = 0;
|
bool fileassoc_flag = 0;
|
||||||
|
|
||||||
//Use the first .nro found in the directory, if there's only 1 NRO in the directory. Only used for paths starting with "sdmc:/switch/".
|
//Use the first .nro found in the directory, if there's only 1 NRO in the directory. Only used for paths starting with "sdmc:/switch/".
|
||||||
tmplen = strlen(menuGetRootPath());
|
if (!found && strncmp(me->path, menuGetRootPath(), strlen(menuGetRootPath()))==0) {
|
||||||
if (!found && strncmp(me->path, menuGetRootPath(), tmplen)==0 && me->path[tmplen]=='/') {
|
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* dp;
|
struct dirent* dp;
|
||||||
u32 nro_count=0;
|
u32 nro_count=0;
|
||||||
@ -293,8 +264,9 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
|
|
||||||
if (me->type == ENTRY_TYPE_FILE)
|
if (me->type == ENTRY_TYPE_FILE)
|
||||||
{
|
{
|
||||||
strncpy(me->author, textGetString(StrId_DefaultPublisher), sizeof(me->author)-1);
|
//strcpy(me->name, name);//This is already done before both if statements
|
||||||
strncpy(me->version, "1.0.0", sizeof(me->version)-1);
|
strcpy(me->author, textGetString(StrId_DefaultPublisher));
|
||||||
|
strcpy(me->version, "1.0.0");
|
||||||
|
|
||||||
//shortcut_s sc;
|
//shortcut_s sc;
|
||||||
|
|
||||||
@ -331,7 +303,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
char* ext = getExtension(tempbuf);
|
char* ext = getExtension(tempbuf);
|
||||||
|
|
||||||
strcpy(ext, ".jpg");
|
strcpy(ext, ".jpg");
|
||||||
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
|
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
|
||||||
if (iconLoaded) break;
|
if (iconLoaded) break;
|
||||||
|
|
||||||
if (isOldAppFolder)
|
if (isOldAppFolder)
|
||||||
@ -339,7 +311,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
char* slash = getSlash(tempbuf);
|
char* slash = getSlash(tempbuf);
|
||||||
|
|
||||||
strcpy(slash, "/icon.jpg");
|
strcpy(slash, "/icon.jpg");
|
||||||
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
|
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
|
||||||
if (iconLoaded) break;
|
if (iconLoaded) break;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@ -412,44 +384,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
*author = textGetString(StrId_DefaultPublisher),
|
*author = textGetString(StrId_DefaultPublisher),
|
||||||
*version = "1.0.0";
|
*version = "1.0.0";
|
||||||
|
|
||||||
const char* cfg_path = me->path;
|
if (config_read_file(&cfg, me->path)) {
|
||||||
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 (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");
|
themeInfo = config_lookup(&cfg, "themeInfo");
|
||||||
if (themeInfo != NULL) {
|
if (themeInfo != NULL) {
|
||||||
if(config_setting_lookup_string(themeInfo, "name", &name))
|
if(config_setting_lookup_string(themeInfo, "name", &name))
|
||||||
@ -462,20 +397,6 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
strncpy(me->author, author, sizeof(me->author)-1);
|
strncpy(me->author, author, sizeof(me->author)-1);
|
||||||
strncpy(me->version, version, sizeof(me->version)-1);
|
strncpy(me->version, version, sizeof(me->version)-1);
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
|
|
||||||
if (good_cfg && is_archive) {
|
|
||||||
bool iconLoaded = false;
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->type == ENTRY_TYPE_FILE_OTHER)
|
if (me->type == ENTRY_TYPE_FILE_OTHER)
|
||||||
@ -507,7 +428,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
|
|
||||||
bool iconLoaded = false;
|
bool iconLoaded = false;
|
||||||
|
|
||||||
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf, false);
|
iconLoaded = menuEntryLoadExternalIcon(me, tempbuf);
|
||||||
|
|
||||||
if (iconLoaded) menuEntryParseIcon(me);
|
if (iconLoaded) menuEntryParseIcon(me);
|
||||||
|
|
||||||
@ -516,48 +437,17 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
if (!iconLoaded && fileassoc_me->icon_gfx && fileassoc_me->icon_gfx_small)
|
if (!iconLoaded && fileassoc_me->icon_gfx && fileassoc_me->icon_gfx_small)
|
||||||
iconLoaded = menuEntryImportIconGfx(me, fileassoc_me->icon_gfx, fileassoc_me->icon_gfx_small);
|
iconLoaded = menuEntryImportIconGfx(me, fileassoc_me->icon_gfx, fileassoc_me->icon_gfx_small);
|
||||||
|
|
||||||
//Attempt to load the nacp from {me->path filepath with extension .nacp}, then on failure use the config from fileassoc_me.
|
|
||||||
memset(tempbuf, 0, sizeof(tempbuf));
|
|
||||||
strncpy(tempbuf, me->path, sizeof(tempbuf));
|
|
||||||
tempbuf[sizeof(tempbuf)-1] = 0;
|
|
||||||
strptr = getExtension(tempbuf);
|
|
||||||
strncpy(strptr, ".nacp", sizeof(tempbuf)-1 - ((ptrdiff_t)strptr - (ptrdiff_t)tempbuf));
|
|
||||||
|
|
||||||
bool nacpLoaded = menuEntryLoadExternalNacp(me, tempbuf);
|
|
||||||
|
|
||||||
if (nacpLoaded) menuEntryParseNacp(me);
|
|
||||||
else {
|
|
||||||
strncpy(me->author, fileassoc_me->author, sizeof(me->author));
|
strncpy(me->author, fileassoc_me->author, sizeof(me->author));
|
||||||
me->author[sizeof(me->author)-1] = 0;
|
me->author[sizeof(me->author)-1] = 0;
|
||||||
|
|
||||||
strncpy(me->version, fileassoc_me->version, sizeof(me->version));
|
strncpy(me->version, fileassoc_me->version, sizeof(me->version));
|
||||||
me->version[sizeof(me->version)-1] = 0;
|
me->version[sizeof(me->version)-1] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the argument data
|
// Initialize the argument data
|
||||||
argData_s* ad = &me->args;
|
argData_s* ad = &me->args;
|
||||||
argData_s* ad_assoc = &fileassoc_me->args;
|
|
||||||
char *arg_src = (char*)&ad_assoc->buf[1];
|
|
||||||
bool ftoken_found=0;
|
|
||||||
ad->dst = (char*)&ad->buf[1];
|
ad->dst = (char*)&ad->buf[1];
|
||||||
|
launchAddArg(ad, fileassoc_me->path);
|
||||||
for (u32 argi=0; argi<ad_assoc->buf[0]; argi++, arg_src+= strlen(arg_src)+1) {
|
launchAddArg(ad, me->path);
|
||||||
if (argi) {
|
|
||||||
strptr = strchr(arg_src, '%');
|
|
||||||
if (strptr && strptr[0] && strptr[1] && (strptr == arg_src || strptr[-1] != '\\')) {
|
|
||||||
if (strptr[1] == 'f') {
|
|
||||||
memset(tempbuf, 0, sizeof(tempbuf));
|
|
||||||
snprintf(tempbuf, sizeof(tempbuf)-1, "%.*s%s%s", (int)((uintptr_t)strptr-(uintptr_t)arg_src), arg_src, me->path, &strptr[2]);
|
|
||||||
launchAddArg(ad, tempbuf);
|
|
||||||
ftoken_found = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
launchAddArg(ad, arg_src);
|
|
||||||
}
|
|
||||||
if (!ftoken_found) launchAddArg(ad, me->path);
|
|
||||||
|
|
||||||
strncpy(me->path, fileassoc_me->path, sizeof(me->path));
|
strncpy(me->path, fileassoc_me->path, sizeof(me->path));
|
||||||
me->path[sizeof(me->path)-1] = 0;
|
me->path[sizeof(me->path)-1] = 0;
|
||||||
@ -567,23 +457,16 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for .filename.star in same path
|
|
||||||
strptr = getSlash(me->path);
|
|
||||||
if (strptr[0] == '/') strptr++;
|
|
||||||
int strptrLen = strlen(strptr);
|
|
||||||
snprintf(me->starpath, sizeof(me->starpath)-1, "%.*s.%.*s.star", (int)(strlen(me->path) - strptrLen), me->path, (int)strptrLen, strptr);
|
|
||||||
me->starred = fileExists(me->starpath);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuEntryFileassocLoad(const char* filepath) {
|
void menuEntryFileassocLoad(const char* filepath) {
|
||||||
bool success=0, iconLoaded=0;
|
bool success=0, success2=0;
|
||||||
menuEntry_s* me = NULL;
|
menuEntry_s* me = NULL;
|
||||||
|
|
||||||
config_setting_t *fileassoc = NULL, *targets = NULL, *target = NULL, *app_args = NULL, *target_args = NULL;
|
config_setting_t *fileassoc = NULL, *targets = NULL, *target = NULL;
|
||||||
config_t cfg = {0};
|
config_t cfg = {0};
|
||||||
int targets_len=0, args_len=0, i;
|
int targets_len=0, i;
|
||||||
const char *strptr = NULL;
|
const char *strptr = NULL;
|
||||||
|
|
||||||
char app_path[PATH_MAX+8];
|
char app_path[PATH_MAX+8];
|
||||||
@ -592,8 +475,8 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
char target_file_extension[PATH_MAX+1];
|
char target_file_extension[PATH_MAX+1];
|
||||||
char target_filename[PATH_MAX+1];
|
char target_filename[PATH_MAX+1];
|
||||||
|
|
||||||
char app_author[ENTRY_AUTHORLENGTH+2];
|
char app_author[ENTRY_AUTHORLENGTH+1];
|
||||||
char app_version[ENTRY_VERLENGTH+2];
|
char app_version[ENTRY_VERLENGTH+1];
|
||||||
|
|
||||||
uint8_t *app_icon_gfx = NULL;
|
uint8_t *app_icon_gfx = NULL;
|
||||||
uint8_t *app_icon_gfx_small = NULL;
|
uint8_t *app_icon_gfx_small = NULL;
|
||||||
@ -615,8 +498,7 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
snprintf(app_path, sizeof(app_path)-1, "%s%s", menuGetRootBasePath(), strptr);
|
snprintf(app_path, sizeof(app_path)-1, "%s%s", menuGetRootBasePath(), strptr);
|
||||||
if (config_setting_lookup_string(fileassoc, "icon_path", &strptr))
|
if (config_setting_lookup_string(fileassoc, "icon_path", &strptr))
|
||||||
snprintf(main_icon_path, sizeof(main_icon_path)-1, "%s%s", menuGetRootBasePath(), strptr);
|
snprintf(main_icon_path, sizeof(main_icon_path)-1, "%s%s", menuGetRootBasePath(), strptr);
|
||||||
app_args = config_setting_lookup(fileassoc, "app_args");
|
targets = config_setting_get_member(fileassoc, "targets");
|
||||||
targets = config_setting_lookup(fileassoc, "targets");
|
|
||||||
|
|
||||||
if (app_path[0] && targets) {
|
if (app_path[0] && targets) {
|
||||||
targets_len = config_setting_length(targets);
|
targets_len = config_setting_length(targets);
|
||||||
@ -632,7 +514,7 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
strptr = getSlash(app_path);
|
strptr = getSlash(app_path);
|
||||||
if(strptr[0] == '/') strptr++;
|
if(strptr[0] == '/') strptr++;
|
||||||
|
|
||||||
if (menuEntryLoad(me, strptr, 0, true)) {
|
if (menuEntryLoad(me, strptr, 0)) {
|
||||||
strncpy(app_author, me->author, sizeof(app_author));
|
strncpy(app_author, me->author, sizeof(app_author));
|
||||||
app_author[sizeof(app_author)-1] = 0;
|
app_author[sizeof(app_author)-1] = 0;
|
||||||
strncpy(app_version, me->version, sizeof(app_version));
|
strncpy(app_version, me->version, sizeof(app_version));
|
||||||
@ -662,13 +544,12 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
strncpy(target_file_extension, strptr, sizeof(target_file_extension)-1);
|
strncpy(target_file_extension, strptr, sizeof(target_file_extension)-1);
|
||||||
if (config_setting_lookup_string(target, "filename", &strptr))
|
if (config_setting_lookup_string(target, "filename", &strptr))
|
||||||
strncpy(target_filename, strptr, sizeof(target_filename)-1);
|
strncpy(target_filename, strptr, sizeof(target_filename)-1);
|
||||||
target_args = config_setting_lookup(target, "app_args");
|
|
||||||
|
|
||||||
//string_is_set for target_file_extension and target_filename must differ: only 1 can be set, not both set or both not set.
|
//string_is_set for target_file_extension and target_filename must differ: only 1 can be set, not both set or both not set.
|
||||||
if ((target_file_extension[0]!=0) == (target_filename[0]!=0)) continue;
|
if ((target_file_extension[0]!=0) == (target_filename[0]!=0)) continue;
|
||||||
|
|
||||||
me = menuCreateEntry(ENTRY_TYPE_FILEASSOC);
|
me = menuCreateEntry(ENTRY_TYPE_FILEASSOC);
|
||||||
iconLoaded = 0;
|
success2 = 0;
|
||||||
|
|
||||||
if (me) {
|
if (me) {
|
||||||
strncpy(me->path, app_path, sizeof(me->path));
|
strncpy(me->path, app_path, sizeof(me->path));
|
||||||
@ -687,32 +568,22 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
}
|
}
|
||||||
me->fileassoc_str[sizeof(me->fileassoc_str)-1] = 0;
|
me->fileassoc_str[sizeof(me->fileassoc_str)-1] = 0;
|
||||||
|
|
||||||
if (target_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, target_icon_path, false);
|
if (target_icon_path[0]) success2 = menuEntryLoadExternalIcon(me, target_icon_path);
|
||||||
if (!iconLoaded && main_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, main_icon_path, false);
|
if (!success2 && main_icon_path[0]) success2 = menuEntryLoadExternalIcon(me, main_icon_path);
|
||||||
|
|
||||||
if (iconLoaded) {
|
if (success2) {
|
||||||
menuEntryParseIcon(me);
|
menuEntryParseIcon(me);
|
||||||
} else {
|
} else {
|
||||||
iconLoaded = menuEntryImportIconGfx(me, app_icon_gfx, app_icon_gfx_small);
|
success2 = menuEntryImportIconGfx(me, app_icon_gfx, app_icon_gfx_small);
|
||||||
}
|
|
||||||
|
|
||||||
argData_s* ad = &me->args;
|
|
||||||
ad->dst = (char*)&ad->buf[1];
|
|
||||||
launchAddArg(ad, me->path);
|
|
||||||
|
|
||||||
config_setting_t *config_args = target_args ? target_args : app_args;
|
|
||||||
if (config_args) {
|
|
||||||
args_len = config_setting_length(config_args);
|
|
||||||
for (int argi=0; argi<args_len; argi++) {
|
|
||||||
strptr = config_setting_get_string_elem(config_args, argi);
|
|
||||||
if (strptr==NULL) continue;
|
|
||||||
|
|
||||||
launchAddArg(ad, strptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me) menuFileassocAddEntry(me);
|
if (me) {
|
||||||
|
if (success2)
|
||||||
|
menuFileassocAddEntry(me);
|
||||||
|
else
|
||||||
|
menuDeleteEntry(me, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,33 +602,65 @@ void menuEntryFileassocLoad(const char* filepath) {
|
|||||||
void menuEntryParseIcon(menuEntry_s* me) {
|
void menuEntryParseIcon(menuEntry_s* me) {
|
||||||
if (me->icon_size==0 || me->icon==NULL) return;
|
if (me->icon_size==0 || me->icon==NULL) return;
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon];
|
int w,h,samp;
|
||||||
ThemeLayoutObject *layoutobj2 = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon];
|
size_t imagesize = 256*256*3;
|
||||||
|
me->icon_gfx = (uint8_t*)malloc(imagesize);
|
||||||
|
|
||||||
size_t imagesize = layoutobj->imageSize[0]*layoutobj->imageSize[1]*3;
|
if (me->icon_gfx == NULL) {
|
||||||
bool ret=true;
|
me->icon_size = 0;
|
||||||
uint8_t *tmp_gfx = (uint8_t*)malloc(imagesize);
|
free(me->icon);
|
||||||
|
me->icon = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp_gfx == NULL) ret = false;
|
tjhandle _jpegDecompressor = tjInitDecompress();
|
||||||
|
|
||||||
if (ret) ret = assetsLoadJpgFromMemory(me->icon, me->icon_size, tmp_gfx, IMAGE_MODE_RGB24, layoutobj->imageSize[0], layoutobj->imageSize[1]);
|
if (_jpegDecompressor == NULL) {
|
||||||
|
free(me->icon_gfx);
|
||||||
|
me->icon_gfx = NULL;
|
||||||
|
|
||||||
if (ret) me->icon_gfx = downscaleImg(tmp_gfx, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj->size[0], layoutobj->size[1], IMAGE_MODE_RGB24);
|
me->icon_size = 0;
|
||||||
|
free(me->icon);
|
||||||
|
me->icon = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret && me->icon_gfx==NULL) ret = false;
|
if (tjDecompressHeader2(_jpegDecompressor, me->icon, me->icon_size, &w, &h, &samp) == -1) {
|
||||||
|
free(me->icon_gfx);
|
||||||
|
me->icon_gfx = NULL;
|
||||||
|
|
||||||
|
me->icon_size = 0;
|
||||||
|
free(me->icon);
|
||||||
|
me->icon = NULL;
|
||||||
|
tjDestroy(_jpegDecompressor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w != 256 || h != 256 ) return;
|
||||||
|
|
||||||
|
if (tjDecompress2(_jpegDecompressor, me->icon, me->icon_size, me->icon_gfx, w, 0, h, TJPF_RGB, TJFLAG_ACCURATEDCT) == -1) {
|
||||||
|
free(me->icon_gfx);
|
||||||
|
me->icon_gfx = NULL;
|
||||||
|
|
||||||
|
me->icon_size = 0;
|
||||||
|
free(me->icon);
|
||||||
|
me->icon = NULL;
|
||||||
|
tjDestroy(_jpegDecompressor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
me->icon_size = 0;
|
me->icon_size = 0;
|
||||||
free(me->icon);
|
free(me->icon);
|
||||||
me->icon = NULL;
|
me->icon = NULL;
|
||||||
|
|
||||||
if (ret) me->icon_gfx_small = downscaleImg(tmp_gfx, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj2->size[0], layoutobj2->size[1], IMAGE_MODE_RGB24);
|
tjDestroy(_jpegDecompressor);
|
||||||
|
|
||||||
if (!ret || me->icon_gfx_small == NULL) {
|
me->icon_gfx_small = downscaleImg(me->icon_gfx, 256, 256, 140, 140, IMAGE_MODE_RGB24);
|
||||||
|
|
||||||
|
if (me->icon_gfx_small == NULL) {
|
||||||
free(me->icon_gfx);
|
free(me->icon_gfx);
|
||||||
me->icon_gfx = NULL;
|
me->icon_gfx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tmp_gfx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *downscaleImg(const uint8_t *image, int srcWidth, int srcHeight, int destWidth, int destHeight, ImageMode mode) {
|
uint8_t *downscaleImg(const uint8_t *image, int srcWidth, int srcHeight, int destWidth, int destHeight, ImageMode mode) {
|
||||||
@ -777,11 +680,6 @@ uint8_t *downscaleImg(const uint8_t *image, int srcWidth, int srcHeight, int des
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcWidth == destWidth && srcHeight == destHeight) {
|
|
||||||
memcpy(out, image, destWidth*destHeight*(mode==IMAGE_MODE_RGBA32 ? 4 : 3));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tmpx, tmpy;
|
int tmpx, tmpy;
|
||||||
int pos;
|
int pos;
|
||||||
float sourceX, sourceY;
|
float sourceX, sourceY;
|
||||||
@ -888,7 +786,7 @@ void menuEntryParseNacp(menuEntry_s* me) {
|
|||||||
|
|
||||||
if (me->nacp==NULL) return;
|
if (me->nacp==NULL) return;
|
||||||
|
|
||||||
strncpy(me->version, me->nacp->display_version, sizeof(me->version)-1);
|
strncpy(me->version, me->nacp->version, sizeof(me->version)-1);
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
Result rc=0;
|
Result rc=0;
|
||||||
|
@ -35,7 +35,6 @@ static void _menuAddEntry(menu_s *m, menuEntry_s* me) {
|
|||||||
m->lastEntry = me;
|
m->lastEntry = me;
|
||||||
}
|
}
|
||||||
m->xPos = 0;
|
m->xPos = 0;
|
||||||
m->slideSpeed = 0;
|
|
||||||
m->nEntries ++;
|
m->nEntries ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +59,6 @@ static void menuAddEntryToFront(menuEntry_s* me) {
|
|||||||
m->lastEntry = me;
|
m->lastEntry = me;
|
||||||
}
|
}
|
||||||
m->xPos = 0;
|
m->xPos = 0;
|
||||||
m->slideSpeed = 0;
|
|
||||||
m->nEntries ++;
|
m->nEntries ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,34 +96,20 @@ static void menuSort(void) {
|
|||||||
menu_s* m = &s_menu[!s_curMenu];
|
menu_s* m = &s_menu[!s_curMenu];
|
||||||
int nEntries = m->nEntries;
|
int nEntries = m->nEntries;
|
||||||
if (nEntries==0) return;
|
if (nEntries==0) return;
|
||||||
int nEntriesStar = 0, nEntriesNoStar = 0;
|
|
||||||
|
|
||||||
menuEntry_s** list = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*));
|
menuEntry_s** list = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*));
|
||||||
if(list == NULL) return;
|
if(list == NULL) return;
|
||||||
menuEntry_s** listStar = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*));
|
|
||||||
if(listStar == NULL) {
|
|
||||||
free(list);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuEntry_s* p = m->firstEntry;
|
menuEntry_s* p = m->firstEntry;
|
||||||
for(i = 0; i < nEntries; ++i) {
|
for(i = 0; i < nEntries; ++i) {
|
||||||
if (p->starred)
|
list[i] = p;
|
||||||
listStar[nEntriesStar++] = p;
|
|
||||||
else
|
|
||||||
list[nEntriesNoStar++] = p;
|
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(listStar, nEntriesStar, sizeof(menuEntry_s*), menuEntryCmp);
|
qsort(list, nEntries, sizeof(menuEntry_s*), menuEntryCmp);
|
||||||
qsort(list, nEntriesNoStar, sizeof(menuEntry_s*), menuEntryCmp);
|
|
||||||
|
|
||||||
menuEntry_s** pp = &m->firstEntry;
|
menuEntry_s** pp = &m->firstEntry;
|
||||||
for(i = 0; i < nEntriesStar; ++i) {
|
for(i = 0; i < nEntries; ++i) {
|
||||||
*pp = listStar[i];
|
|
||||||
pp = &(*pp)->next;
|
|
||||||
}
|
|
||||||
for(i = 0; i < nEntriesNoStar; ++i) {
|
|
||||||
*pp = list[i];
|
*pp = list[i];
|
||||||
pp = &(*pp)->next;
|
pp = &(*pp)->next;
|
||||||
}
|
}
|
||||||
@ -133,33 +117,13 @@ static void menuSort(void) {
|
|||||||
*pp = NULL;
|
*pp = NULL;
|
||||||
|
|
||||||
free(list);
|
free(list);
|
||||||
free(listStar);
|
|
||||||
}
|
|
||||||
|
|
||||||
void menuReorder (void) {
|
|
||||||
s_curMenu = !s_curMenu;
|
|
||||||
menuSort();
|
|
||||||
s_curMenu = !s_curMenu;
|
|
||||||
menuClear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int menuScan(const char* target) {
|
int menuScan(const char* target) {
|
||||||
int pos;
|
|
||||||
char dirsep[8];
|
|
||||||
|
|
||||||
if (chdir(target) < 0) return 1;
|
if (chdir(target) < 0) return 1;
|
||||||
if (getcwd(s_menu[!s_curMenu].dirname, PATH_MAX+1) == NULL)
|
if (getcwd(s_menu[!s_curMenu].dirname, PATH_MAX+1) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
memset(dirsep, 0, sizeof(dirsep));
|
|
||||||
dirsep[0] = '/';
|
|
||||||
|
|
||||||
//While cwd will not have '/' at the end normally, it will have it when cwd is the root dir ("sdmc:/"). Don't add '/' to the path below when it's already present.
|
|
||||||
pos = strlen(s_menu[!s_curMenu].dirname);
|
|
||||||
if (pos > 0) {
|
|
||||||
if (s_menu[!s_curMenu].dirname[pos-1] == '/') dirsep[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* dp;
|
struct dirent* dp;
|
||||||
char tmp_path[PATH_MAX+1];
|
char tmp_path[PATH_MAX+1];
|
||||||
@ -176,12 +140,13 @@ int menuScan(const char* target) {
|
|||||||
bool entrytype=0;
|
bool entrytype=0;
|
||||||
|
|
||||||
memset(tmp_path, 0, sizeof(tmp_path));
|
memset(tmp_path, 0, sizeof(tmp_path));
|
||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "%s%s%s", s_menu[!s_curMenu].dirname, dirsep, dp->d_name);
|
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/%s", s_menu[!s_curMenu].dirname, dp->d_name);
|
||||||
|
|
||||||
#ifdef _DIRENT_HAVE_D_TYPE
|
#ifdef __SWITCH__
|
||||||
if (dp->d_type == DT_UNKNOWN)
|
fsdev_dir_t* dirSt = (fsdev_dir_t*)dir->dirData->dirStruct;
|
||||||
continue;
|
FsDirectoryEntry* entry = &dirSt->entry_data[dirSt->index];
|
||||||
entrytype = dp->d_type != DT_REG;
|
|
||||||
|
entrytype = entry->type == ENTRYTYPE_DIR;
|
||||||
#else
|
#else
|
||||||
struct stat tmpstat;
|
struct stat tmpstat;
|
||||||
|
|
||||||
@ -209,7 +174,7 @@ int menuScan(const char* target) {
|
|||||||
strncpy(me->path, tmp_path, sizeof(me->path)-1);
|
strncpy(me->path, tmp_path, sizeof(me->path)-1);
|
||||||
me->path[sizeof(me->path)-1] = 0;
|
me->path[sizeof(me->path)-1] = 0;
|
||||||
|
|
||||||
if (menuEntryLoad(me, dp->d_name, shortcut, true))
|
if (menuEntryLoad(me, dp->d_name, shortcut))
|
||||||
menuAddEntry(me);
|
menuAddEntry(me);
|
||||||
else
|
else
|
||||||
menuDeleteEntry(me, 0);
|
menuDeleteEntry(me, 0);
|
||||||
@ -246,23 +211,8 @@ int themeMenuScan(const char* target) {
|
|||||||
memset(tmp_path, 0, sizeof(tmp_path));
|
memset(tmp_path, 0, sizeof(tmp_path));
|
||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/%s", s_menu[!s_curMenu].dirname, dp->d_name);
|
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);
|
const char* ext = getExtension(dp->d_name);
|
||||||
if (entrytype || strcasecmp(ext, ".cfg")==0 || strcasecmp(ext, ".romfs")==0 || strcasecmp(ext, ".zip")==0)
|
if (strcasecmp(ext, ".cfg")==0)
|
||||||
me = menuCreateEntry(ENTRY_TYPE_THEME);
|
me = menuCreateEntry(ENTRY_TYPE_THEME);
|
||||||
|
|
||||||
if (!me)
|
if (!me)
|
||||||
@ -270,7 +220,7 @@ int themeMenuScan(const char* target) {
|
|||||||
|
|
||||||
strncpy(me->path, tmp_path, sizeof(me->path)-1);
|
strncpy(me->path, tmp_path, sizeof(me->path)-1);
|
||||||
me->path[sizeof(me->path)-1] = 0;
|
me->path[sizeof(me->path)-1] = 0;
|
||||||
if (menuEntryLoad(me, dp->d_name, shortcut, true))
|
if (menuEntryLoad(me, dp->d_name, shortcut))
|
||||||
menuAddEntry(me);
|
menuAddEntry(me);
|
||||||
else
|
else
|
||||||
menuDeleteEntry(me, 0);
|
menuDeleteEntry(me, 0);
|
||||||
@ -282,7 +232,7 @@ int themeMenuScan(const char* target) {
|
|||||||
menuEntry_s* me = menuCreateEntry(ENTRY_TYPE_THEME);
|
menuEntry_s* me = menuCreateEntry(ENTRY_TYPE_THEME);
|
||||||
|
|
||||||
if(me) {
|
if(me) {
|
||||||
if(menuEntryLoad(me, textGetString(StrId_DefaultThemeName), false, false))//Create Default theme Menu Entry
|
if(menuEntryLoad(me, textGetString(StrId_DefaultThemeName), false))//Create Default theme Menu Entry
|
||||||
menuAddEntryToFront(me);
|
menuAddEntryToFront(me);
|
||||||
else
|
else
|
||||||
menuDeleteEntry(me, 0);
|
menuDeleteEntry(me, 0);
|
||||||
|
487
common/menu.c
@ -6,19 +6,10 @@
|
|||||||
#include "switch/runtime/nxlink.h"
|
#include "switch/runtime/nxlink.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
double menuTimer;
|
|
||||||
|
|
||||||
char rootPathBase[PATH_MAX];
|
char rootPathBase[PATH_MAX];
|
||||||
char rootPath[PATH_MAX+8];
|
char rootPath[PATH_MAX+8];
|
||||||
|
|
||||||
uint8_t *folder_icon_large, *folder_icon_small;
|
|
||||||
uint8_t *invalid_icon_large, *invalid_icon_small;
|
|
||||||
uint8_t *theme_icon_large, *theme_icon_small;
|
|
||||||
|
|
||||||
void computeFrontGradient(color_t baseColor, int height);
|
void computeFrontGradient(color_t baseColor, int height);
|
||||||
|
|
||||||
void menuLoadFileassoc(void);
|
|
||||||
|
|
||||||
char *menuGetRootPath(void) {
|
char *menuGetRootPath(void) {
|
||||||
return rootPath;
|
return rootPath;
|
||||||
}
|
}
|
||||||
@ -38,35 +29,6 @@ void launchMenuEntryTask(menuEntry_s* arg) {
|
|||||||
launchMenuEntry(me);
|
launchMenuEntry(me);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleStarState(menuEntry_s* arg) {
|
|
||||||
menuEntry_s* me = arg;
|
|
||||||
if (me->starred) {
|
|
||||||
if (fileExists(me->starpath))
|
|
||||||
remove(me->starpath);
|
|
||||||
} else {
|
|
||||||
if (!fileExists(me->starpath)) {
|
|
||||||
FILE* f = fopen(me->starpath, "w");
|
|
||||||
if (f) fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
me->starred = fileExists(me->starpath);
|
|
||||||
//todo: error handling/message?
|
|
||||||
|
|
||||||
menuReorder();
|
|
||||||
menu_s* menu = menuGetCurrent();
|
|
||||||
menuEntry_s* meSearch = menu->firstEntry;
|
|
||||||
menu->curEntry = -1;
|
|
||||||
int i = 0;
|
|
||||||
while (menu->curEntry < 0) {
|
|
||||||
if (me == meSearch)
|
|
||||||
menu->curEntry = i;
|
|
||||||
else {
|
|
||||||
meSearch = meSearch->next;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
HBMENU_DEFAULT,
|
HBMENU_DEFAULT,
|
||||||
@ -111,74 +73,11 @@ void menuHandleAButton(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuHandleXButton(void) {
|
|
||||||
menu_s* menu = menuGetCurrent();
|
|
||||||
|
|
||||||
if (menu->nEntries > 0 && hbmenu_state == HBMENU_DEFAULT) {
|
|
||||||
int i;
|
|
||||||
menuEntry_s* me;
|
|
||||||
for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next);
|
|
||||||
toggleStarState(me);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void menuStartupCommon(void) {
|
|
||||||
free(folder_icon_large);
|
|
||||||
free(folder_icon_small);
|
|
||||||
free(invalid_icon_large);
|
|
||||||
free(invalid_icon_small);
|
|
||||||
free(theme_icon_large);
|
|
||||||
free(theme_icon_small);
|
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon];
|
|
||||||
ThemeLayoutObject *layoutobj2 = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon];
|
|
||||||
assetsDataEntry *data = NULL;
|
|
||||||
|
|
||||||
assetsGetData(AssetId_folder_icon, &data);
|
|
||||||
folder_icon_large = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj->size[0], layoutobj->size[1], data->imageMode);
|
|
||||||
folder_icon_small = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj2->size[0], layoutobj2->size[1], data->imageMode);
|
|
||||||
assetsGetData(AssetId_invalid_icon, &data);
|
|
||||||
invalid_icon_large = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj->size[0], layoutobj->size[1], data->imageMode);
|
|
||||||
invalid_icon_small = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj2->size[0], layoutobj2->size[1], data->imageMode);
|
|
||||||
if(themeGlobalPreset == THEME_PRESET_DARK)
|
|
||||||
assetsGetData(AssetId_theme_icon_dark, &data);
|
|
||||||
else
|
|
||||||
assetsGetData(AssetId_theme_icon_light, &data);
|
|
||||||
theme_icon_large = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj->size[0], layoutobj->size[1], data->imageMode);
|
|
||||||
theme_icon_small = downscaleImg(data->buffer, layoutobj->imageSize[0], layoutobj->imageSize[1], layoutobj2->size[0], layoutobj2->size[1], data->imageMode);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave];
|
|
||||||
computeFrontGradient(themeCurrent.frontWaveColor, layoutobj->size[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void menuThemeSelectCurrentEntry(void) {
|
|
||||||
menu_s* menu = menuGetCurrent();
|
|
||||||
char themePath[PATH_MAX] = {0};
|
|
||||||
GetThemePathFromConfig(themePath, PATH_MAX);
|
|
||||||
if (themePath[0]==0) menu->curEntry = 0;
|
|
||||||
else {
|
|
||||||
int i;
|
|
||||||
menuEntry_s* me;
|
|
||||||
for (i = 0, me = menu->firstEntry; me != NULL; i ++, me = me->next) {
|
|
||||||
if (strcmp(me->path, themePath)==0) {
|
|
||||||
menu->curEntry = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void launchApplyThemeTask(menuEntry_s* arg) {
|
void launchApplyThemeTask(menuEntry_s* arg) {
|
||||||
const char* themePath = arg->path;
|
const char* themePath = arg->path;
|
||||||
menu_s* menu = menuGetCurrent();
|
|
||||||
SetThemePathToConfig(themePath);
|
SetThemePathToConfig(themePath);
|
||||||
themeStartup(themeGlobalPreset);
|
themeStartup(themeGlobalPreset);
|
||||||
menuStartupCommon();
|
computeFrontGradient(themeCurrent.frontWaveColor, 280);
|
||||||
menuLoadFileassoc();
|
|
||||||
if (hbmenu_state == HBMENU_THEME_MENU) { // Normally this should never be used outside of theme-menu.
|
|
||||||
themeMenuScan(menu->dirname);
|
|
||||||
menuThemeSelectCurrentEntry();
|
|
||||||
} else menuScan(menu->dirname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool menuIsNetloaderActive(void) {
|
bool menuIsNetloaderActive(void) {
|
||||||
@ -225,18 +124,20 @@ static void drawIcon(int x, int y, int width, int height, const uint8_t *image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t *folder_icon_small;
|
||||||
|
uint8_t *invalid_icon_small;
|
||||||
|
uint8_t *theme_icon_small;
|
||||||
|
|
||||||
static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
|
static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList];
|
|
||||||
int x, y;
|
int x, y;
|
||||||
int start_y = layoutobj->posStart[1];//*(n % 2);
|
int start_y = 720 - 100 - 145;//*(n % 2);
|
||||||
int end_y = start_y + layoutobj->size[1];
|
int end_y = start_y + 140 + 32;
|
||||||
int start_x = off_x;//(n / 2);
|
int start_x = off_x;//(n / 2);
|
||||||
int end_x = start_x + layoutobj->size[0];
|
int end_x = start_x + 140;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
const uint8_t *smallimg = NULL;
|
const uint8_t *smallimg = NULL;
|
||||||
const uint8_t *largeimg = NULL;
|
const uint8_t *largeimg = NULL;
|
||||||
char *strptr = NULL;
|
|
||||||
char tmpstr[1024];
|
char tmpstr[1024];
|
||||||
|
|
||||||
int border_start_x, border_end_x;
|
int border_start_x, border_end_x;
|
||||||
@ -252,7 +153,7 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
|
|||||||
|
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
highlight_multiplier = fmax(0.0, fabs(fmod(menuTimer, 1.0) - 0.5) / 0.5);
|
highlight_multiplier = fmax(0.0, fabs(fmod(menuTimer, 1.0) - 0.5) / 0.5);
|
||||||
border_color = MakeColor(themeCurrent.highlightColor.r + (themeCurrent.highlightGradientEdgeColor.r - themeCurrent.highlightColor.r) * highlight_multiplier, themeCurrent.highlightColor.g + (themeCurrent.highlightGradientEdgeColor.g - themeCurrent.highlightColor.g) * highlight_multiplier, themeCurrent.highlightColor.b + (themeCurrent.highlightGradientEdgeColor.b - themeCurrent.highlightColor.b) * highlight_multiplier, 255);
|
border_color = MakeColor(themeCurrent.highlightColor.r + (255 - themeCurrent.highlightColor.r) * highlight_multiplier, themeCurrent.highlightColor.g + (255 - themeCurrent.highlightColor.g) * highlight_multiplier, themeCurrent.highlightColor.b + (255 - themeCurrent.highlightColor.b) * highlight_multiplier, 255);
|
||||||
border_start_x = start_x-6;
|
border_start_x = start_x-6;
|
||||||
border_end_x = end_x+6;
|
border_end_x = end_x+6;
|
||||||
border_start_y = start_y-5;
|
border_start_y = start_y-5;
|
||||||
@ -330,29 +231,29 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
|
|||||||
}
|
}
|
||||||
else if (me->type == ENTRY_TYPE_FOLDER) {
|
else if (me->type == ENTRY_TYPE_FOLDER) {
|
||||||
smallimg = folder_icon_small;
|
smallimg = folder_icon_small;
|
||||||
largeimg = folder_icon_large;
|
largeimg = assetsGetDataBuffer(AssetId_folder_icon);
|
||||||
}
|
}
|
||||||
else if (me->type == ENTRY_TYPE_THEME){
|
else if (me->type == ENTRY_TYPE_THEME){
|
||||||
smallimg = theme_icon_small;
|
smallimg = theme_icon_small;
|
||||||
largeimg = theme_icon_large;
|
if(themeGlobalPreset == THEME_PRESET_DARK)
|
||||||
|
largeimg = assetsGetDataBuffer(AssetId_theme_icon_dark);
|
||||||
|
else largeimg = assetsGetDataBuffer(AssetId_theme_icon_light);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
smallimg = invalid_icon_small;
|
smallimg = invalid_icon_small;
|
||||||
largeimg = invalid_icon_large;
|
largeimg = assetsGetDataBuffer(AssetId_invalid_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smallimg) {
|
if (smallimg) {
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon];
|
drawImage(start_x, start_y + 32, 140, 140, smallimg, IMAGE_MODE_RGB24);
|
||||||
drawImage(start_x + layoutobj->posStart[0], start_y + layoutobj->posStart[1], layoutobj->size[0], layoutobj->size[1], smallimg, IMAGE_MODE_RGB24);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon];
|
if (is_active && largeimg) {
|
||||||
if (is_active && largeimg && layoutobj->visible) {
|
drawImage(117, 100, 256, 256, largeimg, IMAGE_MODE_RGB24);
|
||||||
drawImage(layoutobj->posStart[0], layoutobj->posStart[1], layoutobj->size[0], layoutobj->size[1], largeimg, IMAGE_MODE_RGB24);
|
|
||||||
|
|
||||||
shadow_start_y = layoutobj->posStart[1]+layoutobj->size[1];
|
shadow_start_y = 100+256;
|
||||||
border_start_x = layoutobj->posStart[0];
|
border_start_x = 117;
|
||||||
border_end_x = layoutobj->posStart[0]+layoutobj->size[0];
|
border_end_x = 117+256;
|
||||||
|
|
||||||
for (shadow_y=shadow_start_y; shadow_y <shadow_start_y+shadow_size; shadow_y++) {
|
for (shadow_y=shadow_start_y; shadow_y <shadow_start_y+shadow_size; shadow_y++) {
|
||||||
for (x=border_start_x; x<border_end_x; x++) {
|
for (x=border_start_x; x<border_end_x; x++) {
|
||||||
@ -366,31 +267,21 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->type != ENTRY_TYPE_THEME)
|
DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, themeCurrent.borderTextColor, me->name, 140 - 32, "...");
|
||||||
strptr = me->starred ? themeCurrent.labelStarOnText : "";
|
|
||||||
else
|
|
||||||
strptr = "";
|
|
||||||
|
|
||||||
memset(tmpstr, 0, sizeof(tmpstr));
|
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%s%s", strptr, me->name);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListName];
|
|
||||||
DrawTextTruncate(layoutobj->font, start_x + layoutobj->posStart[0], start_y + layoutobj->posStart[1], themeCurrent.borderTextColor, tmpstr, layoutobj->size[0], "...");
|
|
||||||
|
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryName];
|
start_x = 1280 - 790;
|
||||||
if (layoutobj->visible) DrawTextTruncate(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr, layoutobj->size[0], "...");
|
start_y = 135;
|
||||||
|
|
||||||
|
DrawTextTruncate(interuimedium30, start_x, start_y + 39, themeCurrent.textColor, me->name, 1280 - start_x - 120 ,"...");
|
||||||
|
|
||||||
if (me->type != ENTRY_TYPE_FOLDER) {
|
if (me->type != ENTRY_TYPE_FOLDER) {
|
||||||
memset(tmpstr, 0, sizeof(tmpstr));
|
memset(tmpstr, 0, sizeof(tmpstr));
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Author), me->author);
|
snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Author), me->author);
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryAuthor];
|
DrawText(interuiregular14, start_x, start_y + 28 + 30 + 18, themeCurrent.textColor, tmpstr);
|
||||||
if (layoutobj->visible) DrawText(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr);
|
|
||||||
|
|
||||||
memset(tmpstr, 0, sizeof(tmpstr));
|
memset(tmpstr, 0, sizeof(tmpstr));
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Version), me->version);
|
snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Version), me->version);
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryVersion];
|
DrawText(interuiregular14, start_x, start_y + 28 + 30 + 18 + 6 + 18, themeCurrent.textColor, tmpstr);
|
||||||
if (layoutobj->visible) DrawText(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,8 +294,6 @@ void computeFrontGradient(color_t baseColor, int height) {
|
|||||||
float dark_mult, dark_sub = 75;
|
float dark_mult, dark_sub = 75;
|
||||||
color_t color;
|
color_t color;
|
||||||
|
|
||||||
if (height < 0 || height > 720) return;
|
|
||||||
|
|
||||||
for (y=0; y<720; y++) {
|
for (y=0; y<720; y++) {
|
||||||
alpha = y - (720 - height);
|
alpha = y - (720 - height);
|
||||||
|
|
||||||
@ -453,20 +342,22 @@ void menuStartupPath(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuLoadFileassoc(void) {
|
void menuStartup(void) {
|
||||||
char tmp_path[PATH_MAX+28];
|
char tmp_path[PATH_MAX+28];
|
||||||
|
|
||||||
memset(tmp_path, 0, sizeof(tmp_path)-1);
|
|
||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/config/nx-hbmenu/fileassoc", rootPathBase);
|
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/config/nx-hbmenu/fileassoc", rootPathBase);
|
||||||
menuFileassocScan(tmp_path);
|
menuFileassocScan(tmp_path);
|
||||||
}
|
|
||||||
|
|
||||||
void menuStartup(void) {
|
|
||||||
menuLoadFileassoc();
|
|
||||||
|
|
||||||
menuScan(rootPath);
|
menuScan(rootPath);
|
||||||
|
|
||||||
menuStartupCommon();
|
folder_icon_small = downscaleImg(assetsGetDataBuffer(AssetId_folder_icon), 256, 256, 140, 140, IMAGE_MODE_RGB24);
|
||||||
|
invalid_icon_small = downscaleImg(assetsGetDataBuffer(AssetId_invalid_icon), 256, 256, 140, 140, IMAGE_MODE_RGB24);
|
||||||
|
if(themeGlobalPreset == THEME_PRESET_DARK)
|
||||||
|
theme_icon_small = downscaleImg(assetsGetDataBuffer(AssetId_theme_icon_dark), 256, 256, 140, 140, IMAGE_MODE_RGB24);
|
||||||
|
else
|
||||||
|
theme_icon_small = downscaleImg(assetsGetDataBuffer(AssetId_theme_icon_light), 256, 256, 140, 140, IMAGE_MODE_RGB24);
|
||||||
|
computeFrontGradient(themeCurrent.frontWaveColor, 280);
|
||||||
|
//menuCreateMsgBox(780, 300, "This is a test");
|
||||||
}
|
}
|
||||||
|
|
||||||
void themeMenuStartup(void) {
|
void themeMenuStartup(void) {
|
||||||
@ -477,7 +368,6 @@ void themeMenuStartup(void) {
|
|||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "%s%s%s%s%s%s%s", rootPathBase, DIRECTORY_SEPARATOR, "config", DIRECTORY_SEPARATOR, "nx-hbmenu" , DIRECTORY_SEPARATOR, "themes");
|
snprintf(tmp_path, sizeof(tmp_path)-1, "%s%s%s%s%s%s%s", rootPathBase, DIRECTORY_SEPARATOR, "config", DIRECTORY_SEPARATOR, "nx-hbmenu" , DIRECTORY_SEPARATOR, "themes");
|
||||||
|
|
||||||
themeMenuScan(tmp_path);
|
themeMenuScan(tmp_path);
|
||||||
menuThemeSelectCurrentEntry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color_t waveBlendAdd(color_t a, color_t b, float alpha) {
|
color_t waveBlendAdd(color_t a, color_t b, float alpha) {
|
||||||
@ -489,7 +379,6 @@ void drawWave(int id, float timer, color_t color, int height, float phase, float
|
|||||||
float wave_top_y, alpha, one_minus_alpha;
|
float wave_top_y, alpha, one_minus_alpha;
|
||||||
color_t existing_color, new_color;
|
color_t existing_color, new_color;
|
||||||
|
|
||||||
if (height < 0 || height > 720) return;
|
|
||||||
height = 720 - height;
|
height = 720 - height;
|
||||||
|
|
||||||
for (x=0; x<1280; x++) {
|
for (x=0; x<1280; x++) {
|
||||||
@ -525,6 +414,25 @@ void drawWave(int id, float timer, color_t color, int height, float phase, float
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawTime() {
|
||||||
|
|
||||||
|
char timeString[9];
|
||||||
|
|
||||||
|
time_t unixTime = time(NULL);
|
||||||
|
struct tm* timeStruct = localtime((const time_t *)&unixTime);
|
||||||
|
|
||||||
|
int hours = timeStruct->tm_hour;
|
||||||
|
int minutes = timeStruct->tm_min;
|
||||||
|
int seconds = timeStruct->tm_sec;
|
||||||
|
|
||||||
|
sprintf(timeString, "%02d:%02d:%02d", hours, minutes, seconds);
|
||||||
|
|
||||||
|
int tmpX = GetTextXCoordinate(interuimedium20, 1180, timeString, 'r');
|
||||||
|
|
||||||
|
DrawText(interuimedium20, tmpX, 0 + 47 + 10, themeCurrent.textColor, timeString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void drawCharge() {
|
void drawCharge() {
|
||||||
char chargeString[5];
|
char chargeString[5];
|
||||||
uint32_t batteryCharge;
|
uint32_t batteryCharge;
|
||||||
@ -539,101 +447,51 @@ void drawCharge() {
|
|||||||
|
|
||||||
sprintf(chargeString, "%d%%", batteryCharge);
|
sprintf(chargeString, "%d%%", batteryCharge);
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BatteryCharge];
|
int tmpX = GetTextXCoordinate(interuiregular14, 1180, chargeString, 'r');
|
||||||
|
|
||||||
if (layoutobj->visible) {
|
DrawText(interuiregular14, tmpX - 15, 0 + 47 + 10 + 21, themeCurrent.textColor, chargeString);
|
||||||
int tmpX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], chargeString, 'r');
|
drawIcon(1180 - 11, 0 + 47 + 10 + 6, 10, 15, assetsGetDataBuffer(AssetId_battery_icon), themeCurrent.textColor);
|
||||||
DrawText(layoutobj->font, tmpX, layoutobj->posStart[1], themeCurrent.textColor, chargeString);
|
if (isCharging)
|
||||||
}
|
drawIcon(tmpX - 32, 0 + 47 + 10 + 6, 9, 15, assetsGetDataBuffer(AssetId_charging_icon), themeCurrent.textColor);
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BatteryIcon];
|
|
||||||
assetsDataEntry *data = NULL;
|
|
||||||
assetsGetData(AssetId_battery_icon, &data);
|
|
||||||
if (layoutobj->visible) drawIcon(layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], data->imageSize[1], data->buffer, themeCurrent.textColor);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ChargingIcon];
|
|
||||||
assetsGetData(AssetId_charging_icon, &data);
|
|
||||||
if (isCharging && layoutobj->visible)
|
|
||||||
drawIcon(layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], data->imageSize[1], data->buffer, themeCurrent.textColor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawNetwork(int tmpX, AssetId id) {
|
void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) {
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_NetworkIcon];
|
int x_image = 1280 - 252 - 30 - 32;
|
||||||
assetsDataEntry *data = NULL;
|
int x_text = 1280 - 216 - 30 - 32;
|
||||||
assetsGetData(id, &data);
|
|
||||||
if (layoutobj->visible) drawIcon(layoutobj->posType ? tmpX + layoutobj->posStart[0] : layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], data->imageSize[1], data->buffer, themeCurrent.textColor);
|
if(emptyDir) {
|
||||||
|
x_image = 1280 - 126 - 30 - 32;
|
||||||
|
x_text = 1280 - 90 - 30 - 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 drawStatus() {
|
|
||||||
bool netstatusFlag=0;
|
|
||||||
bool temperatureFlag=0;
|
|
||||||
s32 temperature=0;
|
|
||||||
AssetId id;
|
|
||||||
|
|
||||||
char tmpstr[32];
|
|
||||||
|
|
||||||
time_t unixTime = time(NULL);
|
|
||||||
struct tm* timeStruct = localtime((const time_t *)&unixTime);
|
|
||||||
|
|
||||||
int hours = timeStruct->tm_hour;
|
|
||||||
int minutes = timeStruct->tm_min;
|
|
||||||
int seconds = timeStruct->tm_sec;
|
|
||||||
|
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%02d:%02d:%02d", hours, minutes, seconds);
|
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_Status];
|
|
||||||
|
|
||||||
u32 tmpX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], tmpstr, 'r');
|
|
||||||
|
|
||||||
if (layoutobj->visible) DrawText(layoutobj->font, tmpX, layoutobj->posStart[1], themeCurrent.textColor, tmpstr);
|
|
||||||
|
|
||||||
drawCharge();
|
|
||||||
|
|
||||||
if (statusGet(&netstatusFlag, &id, &temperatureFlag, &temperature)) {
|
|
||||||
if (netstatusFlag) drawNetwork(tmpX, id);
|
|
||||||
if (temperatureFlag) {
|
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%d°C", temperature);
|
|
||||||
DrawTextFromLayout(ThemeLayoutId_Temperature, themeCurrent.textColor, tmpstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawButtons(menu_s* menu, bool emptyDir, int *out_basePos) {
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA];
|
|
||||||
int basePos[2]={0};
|
|
||||||
|
|
||||||
basePos[0] = layoutobj->posStart[0];
|
|
||||||
basePos[1] = layoutobj->posStart[1];
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
if (strcmp( menu->dirname, "sdmc:/") != 0)
|
if (strcmp( menu->dirname, "sdmc:/") != 0)
|
||||||
#else
|
#else
|
||||||
if (strcmp( menu->dirname, "/") != 0)
|
if (strcmp( menu->dirname, "/") != 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonBText];
|
//drawImage(x_image, 720 - 48, 32, 32, themeCurrent.buttonBImage, IMAGE_MODE_RGBA32);
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonBText, basePos[0], basePos[1], !emptyDir ? layoutobj->posStart : layoutobj->posEnd, basePos, themeCurrent.textColor, textGetString(StrId_Actions_Back), 'l');
|
DrawText(fontscale7, x_image, 720 - 47 + 26, themeCurrent.textColor, themeCurrent.buttonBText);//Display the 'B' button from SharedFont.
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonB];
|
DrawText(interuimedium20, x_text, 720 - 47 + 26, themeCurrent.textColor, textGetString(StrId_Actions_Back));
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonB, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonBText, 'l');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hbmenu_state == HBMENU_DEFAULT)
|
if(hbmenu_state == HBMENU_DEFAULT)
|
||||||
{
|
{
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonYText];
|
x_text = GetTextXCoordinate(interuiregular18, x_image - 32, textGetString(StrId_NetLoader), 'r');
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonYText, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, textGetString(StrId_NetLoader), 'r');
|
x_image = x_text - 36;
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonY];
|
*x_image_out = x_image - 40;
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonY, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonYText, 'l');
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonMText];
|
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonMText, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, textGetString(StrId_ThemeMenu), 'r');
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonM];
|
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonM, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonMText, 'l');
|
|
||||||
}
|
|
||||||
|
|
||||||
out_basePos[0] = basePos[0];
|
DrawText(fontscale7, x_image, 720 - 47 + 26, themeCurrent.textColor, themeCurrent.buttonYText);
|
||||||
out_basePos[1] = basePos[1];
|
DrawText(interuiregular18, x_text, 720 - 47 + 26, themeCurrent.textColor, textGetString(StrId_NetLoader));
|
||||||
|
|
||||||
|
x_text = GetTextXCoordinate(interuiregular18, x_image - 32, textGetString(StrId_ThemeMenu), 'r');
|
||||||
|
x_image = x_text - 36;
|
||||||
|
*x_image_out = x_image - 40;
|
||||||
|
|
||||||
|
DrawText(fontscale7, x_image, 720 - 47 + 26, themeCurrent.textColor, themeCurrent.buttonMText);
|
||||||
|
DrawText(interuiregular18, x_text, 720 - 47 + 26, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuUpdateNetloader(netloaderState *netloader_state) {
|
void menuUpdateNetloader(netloaderState *netloader_state) {
|
||||||
@ -668,89 +526,40 @@ void menuLoop(void) {
|
|||||||
menuEntry_s* me;
|
menuEntry_s* me;
|
||||||
menu_s* menu = NULL;
|
menu_s* menu = NULL;
|
||||||
int i;
|
int i;
|
||||||
int x, y, endy = 720;
|
int x, y;
|
||||||
int curPos[2]={0};
|
int menupath_x_endpos = 918 + 40;
|
||||||
netloaderState netloader_state;
|
netloaderState netloader_state;
|
||||||
ThemeLayoutObject *layoutobj = NULL;
|
|
||||||
|
|
||||||
for (i=0; i<3; i++) {
|
for (y=0; y<450; y++) {
|
||||||
if (i==2) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BackWave];
|
|
||||||
if (i==1) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave];
|
|
||||||
if (i==0) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave];
|
|
||||||
if (layoutobj->visible && layoutobj->size[1] >= 0 && layoutobj->size[1] <= 720-10) {
|
|
||||||
endy = 720 - layoutobj->size[1] + 10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y=0; y<endy; y++) {
|
|
||||||
for (x=0; x<1280; x+=4) {// don't draw bottom pixels as they are covered by the waves
|
for (x=0; x<1280; x+=4) {// don't draw bottom pixels as they are covered by the waves
|
||||||
Draw4PixelsRaw(x, y, themeCurrent.backgroundColor);
|
Draw4PixelsRaw(x, y, themeCurrent.backgroundColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BackgroundImage];
|
drawWave(0, menuTimer, themeCurrent.backWaveColor, 295, 0.0, 3.0);
|
||||||
assetsDataEntry *data = NULL;
|
drawWave(1, menuTimer, themeCurrent.middleWaveColor, 290, 2.0, 3.5);
|
||||||
assetsGetData(AssetId_background_image, &data);
|
drawWave(2, menuTimer, themeCurrent.frontWaveColor, 280, 4.0, -2.5);
|
||||||
if (layoutobj->visible && data) drawImage(layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], endy < data->imageSize[1] ? endy : data->imageSize[1], data->buffer, data->imageMode);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BackWave];
|
|
||||||
if (layoutobj->visible) drawWave(0, menuTimer, themeCurrent.backWaveColor, layoutobj->size[1], 0.0, 3.0);
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave];
|
|
||||||
if (layoutobj->visible) drawWave(1, menuTimer, themeCurrent.middleWaveColor, layoutobj->size[1], 2.0, 3.5);
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave];
|
|
||||||
if (layoutobj->visible) drawWave(2, menuTimer, themeCurrent.frontWaveColor, layoutobj->size[1], 4.0, -2.5);
|
|
||||||
menuTimer += 0.05;
|
menuTimer += 0.05;
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_Logo];
|
drawImage(40, 20, 140, 60, themeCurrent.hbmenuLogoImage, IMAGE_MODE_RGBA32);
|
||||||
if(themeGlobalPreset == THEME_PRESET_DARK)
|
DrawText(interuiregular14, 180, 46 + 18, themeCurrent.textColor, VERSION);
|
||||||
assetsGetData(AssetId_hbmenu_logo_dark, &data);
|
|
||||||
else assetsGetData(AssetId_hbmenu_logo_light, &data);
|
|
||||||
|
|
||||||
if (layoutobj->visible) {
|
|
||||||
if (!themeCurrent.logoColor_set)
|
|
||||||
drawImage(layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], data->imageSize[1], data->buffer, data->imageMode);
|
|
||||||
else {
|
|
||||||
drawIcon(layoutobj->posStart[0], layoutobj->posStart[1], data->imageSize[0], data->imageSize[1], data->buffer, themeCurrent.logoColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawTextFromLayout(ThemeLayoutId_HbmenuVersion, themeCurrent.textColor, VERSION);
|
|
||||||
u32 statusXPos = drawStatus();
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
AppletType at = appletGetAppletType();
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_AttentionText];
|
|
||||||
if (at != AppletType_Application && at != AppletType_SystemApplication && layoutobj->visible) {
|
|
||||||
const char* appletMode = textGetString(StrId_AppletMode);
|
|
||||||
u32 x_pos = GetTextXCoordinate(layoutobj->font, statusXPos, appletMode, 'r');
|
|
||||||
DrawText(layoutobj->font, layoutobj->posType ? x_pos + layoutobj->posStart[0] : layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.attentionTextColor, appletMode);
|
|
||||||
}
|
|
||||||
const char* loaderInfo = envGetLoaderInfo();
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_LoaderInfo];
|
|
||||||
if (loaderInfo && layoutobj->visible) {
|
|
||||||
u32 x_pos = layoutobj->posStart[0];
|
|
||||||
char* spacePos = strchr(loaderInfo, ' ');
|
|
||||||
if (spacePos) {
|
|
||||||
char tempbuf[64] = {0};
|
|
||||||
size_t tempsize = spacePos - loaderInfo + 1;
|
|
||||||
if (tempsize > sizeof(tempbuf)-1) tempsize = sizeof(tempbuf)-1;
|
|
||||||
memcpy(tempbuf, loaderInfo, tempsize);
|
|
||||||
x_pos = GetTextXCoordinate(layoutobj->font, layoutobj->posEnd[0], tempbuf, 'r');
|
|
||||||
}
|
|
||||||
DrawText(layoutobj->font, x_pos, layoutobj->posStart[1], themeCurrent.textColor, loaderInfo);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PERF_LOG_DRAW//Seperate from the PERF_LOG define since this might affect perf.
|
#ifdef PERF_LOG_DRAW//Seperate from the PERF_LOG define since this might affect perf.
|
||||||
|
extern u64 g_tickdiff_vsync;
|
||||||
extern u64 g_tickdiff_frame;
|
extern u64 g_tickdiff_frame;
|
||||||
|
|
||||||
char tmpstr[64];
|
char tmpstr[64];
|
||||||
|
|
||||||
|
snprintf(tmpstr, sizeof(tmpstr)-1, "%lu", g_tickdiff_vsync);
|
||||||
|
DrawText(interuiregular14, 180 + 256, 46 + 18, themeCurrent.textColor, tmpstr);
|
||||||
|
|
||||||
snprintf(tmpstr, sizeof(tmpstr)-1, "%lu", g_tickdiff_frame);
|
snprintf(tmpstr, sizeof(tmpstr)-1, "%lu", g_tickdiff_frame);
|
||||||
DrawTextFromLayout(ThemeLayoutId_LogInfo, themeCurrent.textColor, tmpstr);
|
DrawText(interuiregular14, 180 + 256, 46 + 16 + 18, themeCurrent.textColor, tmpstr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
drawTime();
|
||||||
|
drawCharge();
|
||||||
|
|
||||||
memset(&netloader_state, 0, sizeof(netloader_state));
|
memset(&netloader_state, 0, sizeof(netloader_state));
|
||||||
netloaderGetState(&netloader_state);
|
netloaderGetState(&netloader_state);
|
||||||
|
|
||||||
@ -765,11 +574,8 @@ void menuLoop(void) {
|
|||||||
|
|
||||||
menuCloseMsgBox();
|
menuCloseMsgBox();
|
||||||
menuMsgBoxSetNetloaderState(0, NULL, 0, 0);
|
menuMsgBoxSetNetloaderState(0, NULL, 0, 0);
|
||||||
}
|
|
||||||
|
|
||||||
if (netloader_state.errormsg[0]) {
|
if (netloader_state.errormsg[0]) menuCreateMsgBox(780,300, netloader_state.errormsg);
|
||||||
menuCloseMsgBox();
|
|
||||||
menuCreateMsgBox(780,300, netloader_state.errormsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hbmenu_state == HBMENU_NETLOADER_ACTIVE) {
|
if(hbmenu_state == HBMENU_NETLOADER_ACTIVE) {
|
||||||
@ -789,21 +595,16 @@ void menuLoop(void) {
|
|||||||
launchMenuEntryTask(netloader_state.me);
|
launchMenuEntryTask(netloader_state.me);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DrawTextFromLayout(ThemeLayoutId_InfoMsg, themeCurrent.textColor, textGetString(StrId_NoAppsFound_Msg));
|
DrawText(interuiregular14, 64, 128 + 18, themeCurrent.textColor, textGetString(StrId_NoAppsFound_Msg));
|
||||||
}
|
}
|
||||||
drawButtons(menu, true, curPos);
|
drawButtons(menu, true, &menupath_x_endpos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static int v = 0;
|
static int v = 0;
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles];
|
|
||||||
int entries_count = layoutobj->posEnd[0];
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList];
|
|
||||||
|
|
||||||
// Gentle Realign only when not manually moving
|
if (menu->nEntries > 7) {
|
||||||
if (menu->slideSpeed == 0) {
|
int wanted_x = clamp(-menu->curEntry * (140 + 30), -(menu->nEntries - 7) * (140 + 30), 0);
|
||||||
if (menu->nEntries > entries_count) {
|
|
||||||
int wanted_x = clamp(-menu->curEntry * layoutobj->posEnd[0], -(menu->nEntries - entries_count) * layoutobj->posEnd[0], 0);
|
|
||||||
menu->xPos += v;
|
menu->xPos += v;
|
||||||
v += (wanted_x - menu->xPos) / 3;
|
v += (wanted_x - menu->xPos) / 3;
|
||||||
v /= 2;
|
v /= 2;
|
||||||
@ -811,32 +612,12 @@ void menuLoop(void) {
|
|||||||
else {
|
else {
|
||||||
menu->xPos = v = 0;
|
menu->xPos = v = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
menu->xPos += menu->slideSpeed;
|
|
||||||
|
|
||||||
if (abs(menu->slideSpeed) > 2) {
|
|
||||||
// Slow down way faster when outside the normal bounds
|
|
||||||
if (menu->xPos > 0 || menu->xPos < -(menu->nEntries) * layoutobj->posEnd[0]) {
|
|
||||||
menu->slideSpeed *= .5f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menu->slideSpeed *= .9f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menu->slideSpeed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu->curEntry = clamp(roundf(-((float) menu->xPos / layoutobj->posEnd[0])), 0, menu->nEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
menuEntry_s *active_entry = NULL;
|
menuEntry_s *active_entry = NULL;
|
||||||
|
|
||||||
// Draw menu entries
|
// Draw menu entries
|
||||||
for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) {
|
for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) {
|
||||||
int entry_start_x = layoutobj->posStart[0] + i * layoutobj->posEnd[0];
|
int entry_start_x = 29 + i * (140 + 30);
|
||||||
int entry_draw_x = entry_start_x + menu->xPos;
|
|
||||||
|
|
||||||
int screen_width = 1280;
|
int screen_width = 1280;
|
||||||
if (entry_start_x >= (screen_width - menu->xPos))
|
if (entry_start_x >= (screen_width - menu->xPos))
|
||||||
@ -847,61 +628,37 @@ void menuLoop(void) {
|
|||||||
if (is_active)
|
if (is_active)
|
||||||
active_entry = me;
|
active_entry = me;
|
||||||
|
|
||||||
if (!is_active && entry_draw_x < -(layoutobj->posStart[0] + layoutobj->posEnd[0]))
|
drawEntry(me, entry_start_x + menu->xPos, is_active);
|
||||||
continue;
|
|
||||||
|
|
||||||
drawEntry(me, entry_draw_x, is_active);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuTypeMsg];
|
int getX = GetTextXCoordinate(interuiregular18, 1180, textGetString(StrId_ThemeMenu), 'r');
|
||||||
int getX=0;
|
|
||||||
|
|
||||||
if (layoutobj->visible) {
|
|
||||||
getX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], textGetString(StrId_ThemeMenu), 'r');
|
|
||||||
|
|
||||||
if(hbmenu_state == HBMENU_THEME_MENU) {
|
if(hbmenu_state == HBMENU_THEME_MENU) {
|
||||||
DrawText(layoutobj->font, getX, layoutobj->posStart[1], themeCurrent.textColor, textGetString(StrId_ThemeMenu));
|
DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
|
||||||
} else {
|
} else {
|
||||||
//DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
|
//DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
|
||||||
//DrawText(fontscale7, getX - 40, 30 + 26 + 32 + 10, themeCurrent.textColor, themeCurrent.buttonMText);
|
//DrawText(fontscale7, getX - 40, 30 + 26 + 32 + 10, themeCurrent.textColor, themeCurrent.buttonMText);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(active_entry != NULL) {
|
if(active_entry != NULL) {
|
||||||
const char *buttonstr = "";
|
if (active_entry->type == ENTRY_TYPE_THEME) {
|
||||||
|
DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText);
|
||||||
if (active_entry->type == ENTRY_TYPE_THEME)
|
DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Apply));
|
||||||
buttonstr = textGetString(StrId_Actions_Apply);
|
}
|
||||||
else if (active_entry->type != ENTRY_TYPE_FOLDER)
|
else if (active_entry->type != ENTRY_TYPE_FOLDER) {
|
||||||
buttonstr = textGetString(StrId_Actions_Launch);
|
DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText);//Display the 'A' button from SharedFont.
|
||||||
else
|
DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Launch));
|
||||||
buttonstr = textGetString(StrId_Actions_Open);
|
}
|
||||||
|
else {
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonAText];
|
DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText);
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonAText, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, buttonstr, 'l');
|
DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Open));
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA];
|
}
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonA, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, themeCurrent.buttonAText, 'l');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawButtons(menu, false, curPos);
|
drawButtons(menu, false, &menupath_x_endpos);
|
||||||
|
|
||||||
if (active_entry && active_entry->type != ENTRY_TYPE_THEME) {
|
|
||||||
const char *buttonstr = "";
|
|
||||||
if (active_entry->starred)
|
|
||||||
buttonstr = textGetString(StrId_Actions_Unstar);
|
|
||||||
else
|
|
||||||
buttonstr = textGetString(StrId_Actions_Star);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonXText];
|
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonXText, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, buttonstr, 'r');
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonX];
|
|
||||||
DrawTextFromLayoutRelative(ThemeLayoutId_ButtonX, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, themeCurrent.buttonXText, 'l');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
DrawTextTruncate(interuiregular18, 40, 720 - 47 + 24, themeCurrent.textColor, menu->dirname, menupath_x_endpos - 40, "...");
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuPath];
|
|
||||||
if (layoutobj->visible) DrawTextTruncate(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, menu->dirname, layoutobj->size[0], "...");
|
|
||||||
|
|
||||||
menuDrawMsgBox();
|
menuDrawMsgBox();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ struct menu_s_tag
|
|||||||
int nEntries;
|
int nEntries;
|
||||||
int curEntry;
|
int curEntry;
|
||||||
int xPos;
|
int xPos;
|
||||||
int slideSpeed;
|
|
||||||
|
|
||||||
char dirname[PATH_MAX+1];
|
char dirname[PATH_MAX+1];
|
||||||
};
|
};
|
||||||
@ -52,7 +51,6 @@ struct menuEntry_s_tag
|
|||||||
MenuEntryType type;
|
MenuEntryType type;
|
||||||
|
|
||||||
char path[PATH_MAX+8];
|
char path[PATH_MAX+8];
|
||||||
char starpath[PATH_MAX+8];
|
|
||||||
argData_s args;
|
argData_s args;
|
||||||
|
|
||||||
bool fileassoc_type;//0=file_extension, 1 = filename
|
bool fileassoc_type;//0=file_extension, 1 = filename
|
||||||
@ -67,8 +65,6 @@ struct menuEntry_s_tag
|
|||||||
uint8_t *icon_gfx;
|
uint8_t *icon_gfx;
|
||||||
uint8_t *icon_gfx_small;
|
uint8_t *icon_gfx_small;
|
||||||
|
|
||||||
bool starred;
|
|
||||||
|
|
||||||
NacpStruct *nacp;
|
NacpStruct *nacp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +74,7 @@ typedef enum
|
|||||||
IMAGE_MODE_RGBA32
|
IMAGE_MODE_RGBA32
|
||||||
} ImageMode;
|
} ImageMode;
|
||||||
|
|
||||||
extern double menuTimer;
|
double menuTimer;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -87,7 +83,7 @@ extern "C" {
|
|||||||
void menuEntryInit(menuEntry_s* me, MenuEntryType type);
|
void menuEntryInit(menuEntry_s* me, MenuEntryType type);
|
||||||
void menuEntryFree(menuEntry_s* me, bool skip_icongfx);
|
void menuEntryFree(menuEntry_s* me, bool skip_icongfx);
|
||||||
bool fileExists(const char* path);
|
bool fileExists(const char* path);
|
||||||
bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_exists);
|
bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut);
|
||||||
void menuEntryParseIcon(menuEntry_s* me);
|
void menuEntryParseIcon(menuEntry_s* me);
|
||||||
uint8_t *downscaleImg(const uint8_t *image, int srcWidth, int srcHeight, int destWidth, int destHeight, ImageMode mode);
|
uint8_t *downscaleImg(const uint8_t *image, int srcWidth, int srcHeight, int destWidth, int destHeight, ImageMode mode);
|
||||||
void menuEntryParseNacp(menuEntry_s* me);
|
void menuEntryParseNacp(menuEntry_s* me);
|
||||||
@ -101,13 +97,11 @@ void menuDeleteEntry(menuEntry_s* me, bool skip_icongfx);
|
|||||||
|
|
||||||
menu_s* menuGetCurrent(void);
|
menu_s* menuGetCurrent(void);
|
||||||
menu_s* menuFileassocGetCurrent(void);
|
menu_s* menuFileassocGetCurrent(void);
|
||||||
void menuReorder (void);
|
|
||||||
int menuScan(const char* target);
|
int menuScan(const char* target);
|
||||||
int themeMenuScan(const char* target);
|
int themeMenuScan(const char* target);
|
||||||
int menuFileassocScan(const char* target);
|
int menuFileassocScan(const char* target);
|
||||||
|
|
||||||
void launchMenuEntryTask(menuEntry_s* arg);
|
void launchMenuEntryTask(menuEntry_s* arg);
|
||||||
void toggleStarState(menuEntry_s* arg);
|
|
||||||
void launchApplyThemeTask(menuEntry_s* arg);
|
void launchApplyThemeTask(menuEntry_s* arg);
|
||||||
void launchMenuBackTask();
|
void launchMenuBackTask();
|
||||||
void launchMenuNetloaderTask();
|
void launchMenuNetloaderTask();
|
||||||
@ -115,7 +109,6 @@ char *menuGetRootPath(void);
|
|||||||
char *menuGetRootBasePath(void);
|
char *menuGetRootBasePath(void);
|
||||||
|
|
||||||
void menuHandleAButton(void);
|
void menuHandleAButton(void);
|
||||||
void menuHandleXButton(void);
|
|
||||||
|
|
||||||
bool menuIsNetloaderActive(void);
|
bool menuIsNetloaderActive(void);
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ void drawMsgBoxBgToBuff(color_t *buff, int width, int height) {
|
|||||||
float rad, alpha;
|
float rad, alpha;
|
||||||
color_t base_color = themeCurrent.backgroundColor;
|
color_t base_color = themeCurrent.backgroundColor;
|
||||||
color_t color;
|
color_t color;
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator];
|
|
||||||
|
|
||||||
for (y=0; y<height; y++) {
|
for (y=0; y<height; y++) {
|
||||||
for (x=0; x<width; x++) {
|
for (x=0; x<width; x++) {
|
||||||
@ -63,7 +62,7 @@ void drawMsgBoxBgToBuff(color_t *buff, int width, int height) {
|
|||||||
else
|
else
|
||||||
color = base_color;
|
color = base_color;
|
||||||
|
|
||||||
if (y == height + layoutobj->posStart[1]) {
|
if (y == height - 80) {
|
||||||
color = themeCurrent.separatorColor;
|
color = themeCurrent.separatorColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +76,6 @@ void menuDrawMsgBox() {
|
|||||||
if (!menuIsMsgBoxOpen())
|
if (!menuIsMsgBoxOpen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator];
|
|
||||||
int off;
|
int off;
|
||||||
int x, y;
|
int x, y;
|
||||||
int start_x = 1280 / 2 - currMsgBox.width / 2;
|
int start_x = 1280 / 2 - currMsgBox.width / 2;
|
||||||
@ -87,7 +85,7 @@ void menuDrawMsgBox() {
|
|||||||
color_t curr_color;
|
color_t curr_color;
|
||||||
|
|
||||||
color_t border_color;
|
color_t border_color;
|
||||||
int sep_start_y = currMsgBox.height + layoutobj->posStart[1];
|
int sep_start_y = currMsgBox.height - 80;
|
||||||
int border_thickness = 6;
|
int border_thickness = 6;
|
||||||
|
|
||||||
int shadow_start_y, shadow_y;
|
int shadow_start_y, shadow_y;
|
||||||
@ -123,7 +121,7 @@ void menuDrawMsgBox() {
|
|||||||
curr_color = border_color;
|
curr_color = border_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (msgboxNetloaderProgressEnabled && y > sep_start_y && x < progress_width) {
|
else if (msgboxNetloaderProgressEnabled && y > currMsgBox.height - 80 && x < progress_width) {
|
||||||
curr_color = themeCurrent.progressBarColor;
|
curr_color = themeCurrent.progressBarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,11 +135,10 @@ void menuDrawMsgBox() {
|
|||||||
x = GetTextXCoordinate(interuiregular18, start_x + (currMsgBox.width / 2), textptr, 'c');
|
x = GetTextXCoordinate(interuiregular18, start_x + (currMsgBox.width / 2), textptr, 'c');
|
||||||
|
|
||||||
if (text_width < currMsgBox.width && text_height < sep_start_y) {
|
if (text_width < currMsgBox.width && text_height < sep_start_y) {
|
||||||
DrawText(interuiregular18, x, start_y + (sep_start_y - text_height) / 2, themeCurrent.textColor, textptr);
|
DrawText(interuiregular18, x, start_y + (currMsgBox.height - text_height - 80) / 2, themeCurrent.textColor, textptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxBottomText];
|
y = start_y + 245 + 26;
|
||||||
y = start_y + currMsgBox.height + layoutobj->posStart[1];
|
|
||||||
|
|
||||||
if (!msgboxNetloaderEnabled) {
|
if (!msgboxNetloaderEnabled) {
|
||||||
x = GetTextXCoordinate(interuimedium20, start_x + (currMsgBox.width / 2), textGetString(StrId_MsgBox_OK), 'c');
|
x = GetTextXCoordinate(interuimedium20, start_x + (currMsgBox.width / 2), textGetString(StrId_MsgBox_OK), 'c');
|
||||||
|
@ -274,7 +274,7 @@ static int decompress(int sock, FILE *fh, size_t filesize) {
|
|||||||
int ret;
|
int ret;
|
||||||
unsigned have;
|
unsigned have;
|
||||||
z_stream strm;
|
z_stream strm;
|
||||||
uint32_t chunksize=0;
|
size_t chunksize;
|
||||||
|
|
||||||
/* allocate inflate state */
|
/* allocate inflate state */
|
||||||
strm.zalloc = Z_NULL;
|
strm.zalloc = Z_NULL;
|
||||||
@ -304,12 +304,6 @@ static int decompress(int sock, FILE *fh, size_t filesize) {
|
|||||||
return Z_DATA_ERROR;
|
return Z_DATA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunksize > sizeof(in)) {
|
|
||||||
(void)inflateEnd(&strm);
|
|
||||||
netloader_error("Invalid chunk size",chunksize);
|
|
||||||
return Z_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
strm.avail_in = recvall(sock,in,chunksize,0);
|
strm.avail_in = recvall(sock,in,chunksize,0);
|
||||||
|
|
||||||
if (strm.avail_in == 0) {
|
if (strm.avail_in == 0) {
|
||||||
@ -368,7 +362,7 @@ static int decompress(int sock, FILE *fh, size_t filesize) {
|
|||||||
int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int len, namelen, filelen;
|
int len, namelen, filelen;
|
||||||
char filepath[PATH_MAX+1];
|
char filename[PATH_MAX+1];
|
||||||
len = recvall(sock, &namelen, 4, 0);
|
len = recvall(sock, &namelen, 4, 0);
|
||||||
|
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
@ -376,19 +370,19 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (namelen >= sizeof(filepath)-1) {
|
if (namelen >= sizeof(filename)-1) {
|
||||||
netloader_error("File-path length is too large",errno);
|
netloader_error("Filename length is too large",errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = recvall(sock, filepath, namelen, 0);
|
len = recvall(sock, filename, namelen, 0);
|
||||||
|
|
||||||
if (len != namelen) {
|
if (len != namelen) {
|
||||||
netloader_error("Error getting file-path", errno);
|
netloader_error("Error getting filename", errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
filepath[namelen] = 0;
|
filename[namelen] = 0;
|
||||||
|
|
||||||
len = recvall(sock, &filelen, 4, 0);
|
len = recvall(sock, &filelen, 4, 0);
|
||||||
|
|
||||||
@ -403,34 +397,21 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
|||||||
|
|
||||||
int response = 0;
|
int response = 0;
|
||||||
|
|
||||||
sanitisePath(filepath);
|
sanitisePath(filename);
|
||||||
|
|
||||||
snprintf(me->path, sizeof(me->path)-1, "%s%s%s", menuGetRootPath(), DIRECTORY_SEPARATOR, filepath);
|
snprintf(me->path, sizeof(me->path)-1, "%s%s%s", menuGetRootPath(), DIRECTORY_SEPARATOR, filename);
|
||||||
|
me->path[PATH_MAX] = 0;
|
||||||
// make sure it's terminated
|
// make sure it's terminated
|
||||||
me->path[sizeof(me->path)-1] = 0;
|
me->path[PATH_MAX] = 0;
|
||||||
strncpy(filepath, me->path, sizeof(filepath)-1); // menuEntryLoad() below will overwrite me->path, so copy me->path to filepath and use that instead.
|
|
||||||
filepath[sizeof(filepath)-1] = 0;
|
|
||||||
|
|
||||||
argData_s* ad = &me->args;
|
argData_s* ad = &me->args;
|
||||||
ad->dst = (char*)&ad->buf[1];
|
ad->dst = (char*)&ad->buf[1];
|
||||||
ad->nxlink_host = remote;
|
ad->nxlink_host = remote;
|
||||||
|
|
||||||
const char* ext = getExtension(me->path);
|
|
||||||
if (ext && strcasecmp(ext, ".nro")==0)
|
|
||||||
launchAddArg(ad, me->path);
|
launchAddArg(ad, me->path);
|
||||||
else {
|
|
||||||
me->type = ENTRY_TYPE_FILE_OTHER; // Handle fileassoc when extension isn't .nro.
|
|
||||||
if (!menuEntryLoad(me, "", false, false)) {
|
|
||||||
response = -3;
|
|
||||||
errno = EINVAL;
|
|
||||||
netloader_error("File-extension/filename not recognized",0);
|
|
||||||
}
|
|
||||||
menuEntryFree(me, false); // We don't need any of the buffers which may have been allocated.
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (response == 0) {
|
int fd = open(me->path,O_CREAT|O_WRONLY, ACCESSPERMS);
|
||||||
int fd = open(filepath,O_CREAT|O_WRONLY, ACCESSPERMS);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
response = -1;
|
response = -1;
|
||||||
@ -442,36 +423,25 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
|||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
|
|
||||||
if (response == 0) {
|
if (response == 0) file = fopen(me->path,"wb");
|
||||||
file = fopen(filepath,"wb");
|
|
||||||
if(file == NULL) {
|
if(NULL == file) {
|
||||||
perror("file");
|
perror("file");
|
||||||
response = -1;
|
response = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
send(sock,(char *)&response,sizeof(response),0);
|
send(sock,(char *)&response,sizeof(response),0);
|
||||||
|
|
||||||
char *writebuffer = NULL;
|
|
||||||
if (response == 0 ) {
|
if (response == 0 ) {
|
||||||
writebuffer = malloc(FILE_BUFFER_SIZE);
|
|
||||||
if (writebuffer==NULL) {
|
|
||||||
netloader_error("Failed to allocate memory",ENOMEM);
|
|
||||||
response = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memset(writebuffer, 0, FILE_BUFFER_SIZE);
|
|
||||||
setvbuf(file,writebuffer,_IOFBF, FILE_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response == 0 ) {
|
//char *writebuffer=malloc(FILE_BUFFER_SIZE);
|
||||||
//printf("transferring %s\n%d bytes.\n", filepath, filelen);
|
//setvbuf(file,writebuffer,_IOFBF, FILE_BUFFER_SIZE);
|
||||||
|
|
||||||
|
//printf("transferring %s\n%d bytes.\n", filename, filelen);
|
||||||
|
|
||||||
if (decompress(sock,file,filelen)==Z_OK) {
|
if (decompress(sock,file,filelen)==Z_OK) {
|
||||||
int netloaded_cmdlen = 0;
|
int netloaded_cmdlen = 0;
|
||||||
@ -494,7 +464,7 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (response == 0 ) {
|
if (response == 0 ) {
|
||||||
if ((me->args.dst+netloaded_cmdlen) >= (char*)(me->args.buf + sizeof(me->args.buf))) netloaded_cmdlen = (uintptr_t)me->args.buf + sizeof(me->args.buf)-1 - (uintptr_t)me->args.dst;
|
if (netloaded_cmdlen > sizeof(me->args.buf)-1) netloaded_cmdlen = sizeof(me->args.buf)-1;
|
||||||
|
|
||||||
len = recvall(sock,me->args.dst, netloaded_cmdlen,0);
|
len = recvall(sock,me->args.dst, netloaded_cmdlen,0);
|
||||||
|
|
||||||
@ -516,14 +486,13 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) {
|
|||||||
} else {
|
} else {
|
||||||
response = -1;
|
response = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (file) {
|
//free(writebuffer);
|
||||||
fflush(file);
|
fflush(file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
if (response == -1) unlink(me->path);
|
||||||
}
|
}
|
||||||
if (response == -1) unlink(filepath);
|
|
||||||
free(writebuffer);
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -567,15 +536,7 @@ int netloader_activate(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tmpval=1;
|
int rc = bind(netloader_listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
|
||||||
int rc = setsockopt(netloader_listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&tmpval, sizeof(tmpval));
|
|
||||||
if(rc != 0)
|
|
||||||
{
|
|
||||||
netloader_socket_error("setsockopt");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bind(netloader_listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
|
|
||||||
if(rc != 0)
|
if(rc != 0)
|
||||||
{
|
{
|
||||||
netloader_socket_error("bind");
|
netloader_socket_error("bind");
|
||||||
@ -727,10 +688,6 @@ Result netloaderInit(void) {
|
|||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
rc = socketInitializeDefault();
|
rc = socketInitializeDefault();
|
||||||
if (R_SUCCEEDED(rc)) {
|
|
||||||
rc = nifmInitialize(NifmServiceType_User);
|
|
||||||
if (R_FAILED(rc)) socketExit();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
@ -757,7 +714,6 @@ void netloaderExit(void) {
|
|||||||
mtx_destroy(&netloader_mtx);
|
mtx_destroy(&netloader_mtx);
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
nifmExit();
|
|
||||||
socketExit();
|
socketExit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
bool netstatusGetDetails(AssetId *id);
|
|
||||||
|
|
130
common/status.c
@ -1,130 +0,0 @@
|
|||||||
#include "status.h"
|
|
||||||
|
|
||||||
static bool s_statusInitialized = 0;
|
|
||||||
static thrd_t s_statusThread;
|
|
||||||
static cnd_t s_statusCdn;
|
|
||||||
static mtx_t s_statusMtx;
|
|
||||||
static mtx_t s_statusAccessMtx;
|
|
||||||
static bool s_statusExit;
|
|
||||||
|
|
||||||
static bool s_statusReady;
|
|
||||||
static bool s_statusNetFlag;
|
|
||||||
static AssetId s_statusNetAssetId;
|
|
||||||
static bool s_statusTemperatureFlag;
|
|
||||||
static s32 s_statusTemperature;
|
|
||||||
|
|
||||||
// This uses netstatusGetDetails from a dedicated thread, since nifmGetInternetConnectionStatus can block for a few seconds.
|
|
||||||
|
|
||||||
static int statusThreadProc(void* unused)
|
|
||||||
{
|
|
||||||
mtx_lock(&s_statusMtx);
|
|
||||||
|
|
||||||
struct timespec timeout = {0};
|
|
||||||
bool tmpflag=0;
|
|
||||||
bool thermalflag=0;
|
|
||||||
bool thermal_initialized=0;
|
|
||||||
AssetId tmpid;
|
|
||||||
s32 temperature;
|
|
||||||
|
|
||||||
thermal_initialized = thermalstatusInit();
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &timeout);
|
|
||||||
timeout.tv_sec++;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
cnd_timedwait(&s_statusCdn, &s_statusMtx, &timeout);
|
|
||||||
|
|
||||||
if (s_statusExit)
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmpflag = netstatusGetDetails(&tmpid);
|
|
||||||
if (thermal_initialized) thermalflag = thermalstatusGetDetails(&temperature);
|
|
||||||
|
|
||||||
mtx_lock(&s_statusAccessMtx);
|
|
||||||
|
|
||||||
s_statusNetFlag = tmpflag;
|
|
||||||
s_statusNetAssetId = tmpid;
|
|
||||||
|
|
||||||
s_statusTemperatureFlag = thermalflag;
|
|
||||||
s_statusTemperature = temperature;
|
|
||||||
|
|
||||||
s_statusReady = 1;
|
|
||||||
|
|
||||||
mtx_unlock(&s_statusAccessMtx);
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &timeout);
|
|
||||||
timeout.tv_sec++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mtx_unlock(&s_statusMtx);
|
|
||||||
|
|
||||||
if (thermal_initialized) thermalstatusExit();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool statusGet(bool *netstatusFlag, AssetId *netstatusAssetId, bool *temperatureFlag, s32 *temperature) {
|
|
||||||
if (!s_statusReady) return 0;
|
|
||||||
|
|
||||||
mtx_lock(&s_statusAccessMtx);
|
|
||||||
|
|
||||||
*netstatusFlag = s_statusNetFlag;
|
|
||||||
*netstatusAssetId = s_statusNetAssetId;
|
|
||||||
|
|
||||||
*temperatureFlag = s_statusTemperatureFlag;
|
|
||||||
*temperature = s_statusTemperature;
|
|
||||||
|
|
||||||
mtx_unlock(&s_statusAccessMtx);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool statusInit(void)
|
|
||||||
{
|
|
||||||
if (s_statusInitialized) return 1;
|
|
||||||
|
|
||||||
if (cnd_init(&s_statusCdn) != thrd_success) return 0;
|
|
||||||
if (mtx_init(&s_statusMtx, mtx_plain) != thrd_success) {
|
|
||||||
cnd_destroy(&s_statusCdn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mtx_init(&s_statusAccessMtx, mtx_plain) != thrd_success) {
|
|
||||||
mtx_destroy(&s_statusMtx);
|
|
||||||
cnd_destroy(&s_statusCdn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thrd_create(&s_statusThread, statusThreadProc, 0) != thrd_success) {
|
|
||||||
mtx_destroy(&s_statusAccessMtx);
|
|
||||||
mtx_destroy(&s_statusMtx);
|
|
||||||
cnd_destroy(&s_statusCdn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_statusInitialized = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void statusExit(void)
|
|
||||||
{
|
|
||||||
int res=0;
|
|
||||||
|
|
||||||
if (!s_statusInitialized) return;
|
|
||||||
s_statusInitialized = 0;
|
|
||||||
|
|
||||||
mtx_lock(&s_statusMtx);
|
|
||||||
s_statusExit = true;
|
|
||||||
cnd_signal(&s_statusCdn);
|
|
||||||
mtx_unlock(&s_statusMtx);
|
|
||||||
|
|
||||||
thrd_join(s_statusThread, &res);
|
|
||||||
|
|
||||||
s_statusReady = 0;
|
|
||||||
|
|
||||||
mtx_destroy(&s_statusAccessMtx);
|
|
||||||
mtx_destroy(&s_statusMtx);
|
|
||||||
cnd_destroy(&s_statusCdn);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
bool statusInit(void);
|
|
||||||
void statusExit(void);
|
|
||||||
bool statusGet(bool *netstatusFlag, AssetId *netstatusAssetId, bool *temperatureFlag, s32 *temperature);
|
|
||||||
|
|
@ -10,14 +10,14 @@ static int s_textLang = 1;
|
|||||||
|
|
||||||
Result textInit(void) {
|
Result textInit(void) {
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
SetLanguage Language=SetLanguage_ENUS;
|
s32 Language=0;
|
||||||
|
|
||||||
s_textLang = Language;
|
s_textLang = SetLanguage_ENUS;
|
||||||
|
|
||||||
Result rc = setInitialize();
|
Result rc = setInitialize();
|
||||||
if (R_SUCCEEDED(rc)) rc = setGetSystemLanguage(&s_textLanguageCode);
|
if (R_SUCCEEDED(rc)) rc = setGetSystemLanguage(&s_textLanguageCode);
|
||||||
if (R_SUCCEEDED(rc)) rc = setMakeLanguage(s_textLanguageCode, &Language);
|
if (R_SUCCEEDED(rc)) rc = setMakeLanguage(s_textLanguageCode, &Language);
|
||||||
//if (R_SUCCEEDED(rc) && Language < 17) s_textLang = Language;//TODO: Re-enable this once language.c supports all used languages.
|
//if (R_SUCCEEDED(rc) && Language < 16) s_textLang = Language;//TODO: Re-enable this once language.c supports all used languages.
|
||||||
setExit();
|
setExit();
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc)) return rc;
|
||||||
#else
|
#else
|
||||||
|
534
common/theme.c
@ -1,5 +1,4 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
theme_t themeCurrent;
|
theme_t themeCurrent;
|
||||||
ThemePreset themeGlobalPreset;
|
ThemePreset themeGlobalPreset;
|
||||||
@ -11,94 +10,15 @@ bool colorFromSetting(config_setting_t *rgba, color_t *col) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intElemFromSetting(config_setting_t *setting, int *out, size_t count) {
|
|
||||||
if (!setting || config_setting_length(setting) < count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (size_t i=0; i<count; i++) {
|
|
||||||
out[i] = config_setting_get_int_elem(setting, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool layoutObjectFromSetting(config_setting_t *layout_setting, ThemeLayoutObject *obj, bool ignore_cfg_visible) {
|
|
||||||
int tmp=0;
|
|
||||||
ThemeLayoutObject tmpobj={0};
|
|
||||||
if (!layout_setting)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memcpy(tmpobj.posStart, obj->posStart, sizeof(obj->posStart));
|
|
||||||
memcpy(tmpobj.posEnd, obj->posEnd, sizeof(obj->posEnd));
|
|
||||||
memcpy(tmpobj.size, obj->size, sizeof(obj->size));
|
|
||||||
|
|
||||||
if (config_setting_lookup_bool(layout_setting, "visible", &tmp)==CONFIG_TRUE)
|
|
||||||
tmpobj.visible = tmp;
|
|
||||||
else
|
|
||||||
tmpobj.visible = obj->visible;
|
|
||||||
if (config_setting_lookup_bool(layout_setting, "posType", &tmp)==CONFIG_TRUE)
|
|
||||||
tmpobj.posType = tmp;
|
|
||||||
else
|
|
||||||
tmpobj.posType = obj->posType;
|
|
||||||
|
|
||||||
intElemFromSetting(config_setting_lookup(layout_setting, "posStart"), tmpobj.posStart, 2);
|
|
||||||
intElemFromSetting(config_setting_lookup(layout_setting, "posEnd"), tmpobj.posEnd, 2);
|
|
||||||
intElemFromSetting(config_setting_lookup(layout_setting, "size"), tmpobj.size, 2);
|
|
||||||
|
|
||||||
if (!tmpobj.posType && (tmpobj.posStart[0] < 0 || tmpobj.posStart[1] < 0 || tmpobj.posEnd[0] < 0 || tmpobj.posEnd[1] < 0))
|
|
||||||
return false;
|
|
||||||
if (tmpobj.size[0] < 0 || tmpobj.size[1] < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
obj->posStart[0] = tmpobj.posStart[0];
|
|
||||||
obj->posStart[1] = tmpobj.posStart[1];
|
|
||||||
obj->posEnd[0] = tmpobj.posEnd[0];
|
|
||||||
obj->posEnd[1] = tmpobj.posEnd[1];
|
|
||||||
|
|
||||||
if (!ignore_cfg_visible) obj->visible = tmpobj.visible;
|
|
||||||
obj->posType = tmpobj.posType;
|
|
||||||
obj->size[0] = tmpobj.size[0];
|
|
||||||
obj->size[1] = tmpobj.size[1];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool assetObjectFromSetting(config_setting_t *asset_setting, AssetId id, ThemeLayoutObject *layoutobj) {
|
|
||||||
int imageSize[2]={0};
|
|
||||||
const char *path = NULL;
|
|
||||||
char tmp_path[PATH_MAX];
|
|
||||||
if (!asset_setting)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (config_setting_lookup_string(asset_setting, "path", &path)==CONFIG_FALSE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!intElemFromSetting(config_setting_lookup(asset_setting, "imageSize"), imageSize, 2))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (imageSize[0] <= 0 || imageSize[1] <= 0 || imageSize[0] > 1280 || imageSize[1] > 720)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (layoutobj && (imageSize[0] != layoutobj->imageSize[0] || imageSize[1] != layoutobj->imageSize[1]))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memset(tmp_path, 0, sizeof(tmp_path));
|
|
||||||
snprintf(tmp_path, sizeof(tmp_path)-1, "theme/%s", path);
|
|
||||||
|
|
||||||
return assetsLoadData(id, tmp_path, imageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void themeStartup(ThemePreset preset) {
|
void themeStartup(ThemePreset preset) {
|
||||||
themeGlobalPreset = preset;
|
themeGlobalPreset = preset;
|
||||||
theme_t themeLight = (theme_t) {
|
theme_t themeLight = (theme_t) {
|
||||||
.textColor = MakeColor(0, 0, 0, 255),
|
.textColor = MakeColor(0, 0, 0, 255),
|
||||||
.attentionTextColor = MakeColor(255, 0, 0, 255),
|
|
||||||
.frontWaveColor = MakeColor(100, 212, 250, 255),
|
.frontWaveColor = MakeColor(100, 212, 250, 255),
|
||||||
.middleWaveColor = MakeColor(100, 153, 255, 255),
|
.middleWaveColor = MakeColor(100, 153, 255, 255),
|
||||||
.backWaveColor = MakeColor(154, 171, 255, 255),
|
.backWaveColor = MakeColor(154, 171, 255, 255),
|
||||||
.backgroundColor = MakeColor(233, 236, 241, 255),
|
.backgroundColor = MakeColor(233, 236, 241, 255),
|
||||||
.highlightColor = MakeColor(91, 237, 224, 255),
|
.highlightColor = MakeColor(91, 237, 224, 255),
|
||||||
.highlightGradientEdgeColor = MakeColor(91,176,224,255),
|
|
||||||
.separatorColor = MakeColor(219, 218, 219, 255),
|
.separatorColor = MakeColor(219, 218, 219, 255),
|
||||||
.borderColor = MakeColor(255,255,255,255),
|
.borderColor = MakeColor(255,255,255,255),
|
||||||
.borderTextColor = MakeColor(64,64,64,255),
|
.borderTextColor = MakeColor(64,64,64,255),
|
||||||
@ -106,23 +26,19 @@ void themeStartup(ThemePreset preset) {
|
|||||||
.enableWaveBlending = 0,
|
.enableWaveBlending = 0,
|
||||||
.buttonAText = "\uE0E0",
|
.buttonAText = "\uE0E0",
|
||||||
.buttonBText = "\uE0E1",
|
.buttonBText = "\uE0E1",
|
||||||
.buttonXText = "\uE0E2",
|
|
||||||
.buttonYText = "\uE0E3",
|
.buttonYText = "\uE0E3",
|
||||||
.buttonPText = "\uE0EF",
|
.buttonPText = "\uE0EF",
|
||||||
.buttonMText = "\uE0F0",
|
.buttonMText = "\uE0F0",
|
||||||
.labelStarOnText = "\u2605",
|
.hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_light)
|
||||||
.labelStarOffText = "\u2606",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
theme_t themeDark = (theme_t) {
|
theme_t themeDark = (theme_t) {
|
||||||
.textColor = MakeColor(255, 255, 255, 255),
|
.textColor = MakeColor(255, 255, 255, 255),
|
||||||
.attentionTextColor = MakeColor(255, 0, 0, 255),
|
|
||||||
.frontWaveColor = MakeColor(96, 204, 204, 255),
|
.frontWaveColor = MakeColor(96, 204, 204, 255),
|
||||||
.middleWaveColor = MakeColor(66, 154, 159, 255),
|
.middleWaveColor = MakeColor(66, 154, 159, 255),
|
||||||
.backWaveColor = MakeColor(73, 103, 169, 255),
|
.backWaveColor = MakeColor(73, 103, 169, 255),
|
||||||
.backgroundColor = MakeColor(45, 45, 50, 255),
|
.backgroundColor = MakeColor(45, 45, 50, 255),
|
||||||
.highlightColor = MakeColor(91, 237, 224, 255),
|
.highlightColor = MakeColor(91, 237, 224, 255),
|
||||||
.highlightGradientEdgeColor = MakeColor(91,176,224,255),
|
|
||||||
.separatorColor = MakeColor(219, 218, 219, 255),
|
.separatorColor = MakeColor(219, 218, 219, 255),
|
||||||
.borderColor = MakeColor(255,255,255,255),
|
.borderColor = MakeColor(255,255,255,255),
|
||||||
.borderTextColor = MakeColor(64,64,64,255),
|
.borderTextColor = MakeColor(64,64,64,255),
|
||||||
@ -130,282 +46,10 @@ void themeStartup(ThemePreset preset) {
|
|||||||
.enableWaveBlending = 0,
|
.enableWaveBlending = 0,
|
||||||
.buttonAText = "\uE0A0",
|
.buttonAText = "\uE0A0",
|
||||||
.buttonBText = "\uE0A1",
|
.buttonBText = "\uE0A1",
|
||||||
.buttonXText = "\uE0A2",
|
|
||||||
.buttonYText = "\uE0A3",
|
.buttonYText = "\uE0A3",
|
||||||
.buttonPText = "\uE0B3",
|
.buttonPText = "\uE0B3",
|
||||||
.buttonMText = "\uE0B4",
|
.buttonMText = "\uE0B4",
|
||||||
.labelStarOnText = "\u2605",
|
.hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark)
|
||||||
.labelStarOffText = "\u2606",
|
|
||||||
};
|
|
||||||
|
|
||||||
theme_t themeCommon = {
|
|
||||||
.layoutObjects = {
|
|
||||||
[ThemeLayoutId_Logo] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {40, 20},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_HbmenuVersion] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {184, 46 + 18},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_LoaderInfo] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {43, 46 + 18 + 20},
|
|
||||||
.posEnd = {184},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_AttentionText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-32, 46 + 18},
|
|
||||||
.font = interuimedium30,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_LogInfo] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {180 + 256, 46 + 16 + 18},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_InfoMsg] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {64, 128 + 18},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuPath] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {40, 720 - 47 + 24},
|
|
||||||
.size = {380},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuTypeMsg] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180, 30 + 26 + 32 + 20},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MsgBoxSeparator] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {0, -80},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MsgBoxBottomText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {0, -29},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ThemeLayoutId_BackgroundImage is not set with the defaults.
|
|
||||||
|
|
||||||
[ThemeLayoutId_BackWave] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.size = {0, 295},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MiddleWave] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.size = {0, 290},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_FrontWave] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.size = {0, 280},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonA] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1280 - 126 - 30 - 32, 720 - 47 + 24},
|
|
||||||
.touchSize = {36, 25},
|
|
||||||
.font = fontscale7,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonAText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1280 - 90 - 30 - 32, 720 - 47 + 24},
|
|
||||||
.touchSize = {0, 25},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonB] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-36, 0},
|
|
||||||
.posEnd = {0},
|
|
||||||
.touchSize = {36, 25},
|
|
||||||
.font = fontscale7,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonBText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-90, 0},
|
|
||||||
.touchSize = {0, 32},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonY] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-36, 0},
|
|
||||||
.font = fontscale7,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonYText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-32, 0},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonM] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-36, 0},
|
|
||||||
.font = fontscale7,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonMText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-32, 0},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonX] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-36, 0},
|
|
||||||
.touchSize = {36, 25},
|
|
||||||
.font = fontscale7,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ButtonXText] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {-40 + 8, 0},
|
|
||||||
.touchSize = {0, 25},
|
|
||||||
.font = interuiregular18,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_NetworkIcon] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {0, 0 + 47 + 10 + 3},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_BatteryCharge] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180 - 10 - 24 - 8, 0 + 47 + 10 + 21 + 4},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_BatteryIcon] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180 - 8 - 24 - 8, 0 + 47 + 10 + 6},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_ChargingIcon] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180 - 20, 0 + 47 + 10 + 6},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_Status] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180, 0 + 47 + 10},
|
|
||||||
.font = interuimedium20,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_Temperature] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1180 + 4, 0 + 47 + 10 + + 21 + 6},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuList] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {29, 720 - 100 - 145},
|
|
||||||
.posEnd = {140 + 30, 0},
|
|
||||||
.size = {140, 140 + 32},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuListTiles] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posEnd = {7, 0},
|
|
||||||
.size = {0, 0},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuListIcon] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {0, 32},
|
|
||||||
.size = {140, 140},
|
|
||||||
.imageSize = {256, 256},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuListName] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = true,
|
|
||||||
.posStart = {4, 4 + 18},
|
|
||||||
.size = {140 - 32, 0},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuActiveEntryIcon] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {117, 100+10},
|
|
||||||
.size = {256, 256},
|
|
||||||
.imageSize = {256, 256},
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuActiveEntryName] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1280 - 790, 135+10 + 39},
|
|
||||||
.size = {790 - 120, 0},
|
|
||||||
.font = interuimedium30,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuActiveEntryAuthor] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1280 - 790, 135+10 + 28 + 30 + 18},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ThemeLayoutId_MenuActiveEntryVersion] = {
|
|
||||||
.visible = true,
|
|
||||||
.posType = false,
|
|
||||||
.posStart = {1280 - 790, 135+10 + 28 + 30 + 18 + 6 + 18},
|
|
||||||
.font = interuiregular14,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
char themePath[PATH_MAX] = {0};
|
char themePath[PATH_MAX] = {0};
|
||||||
@ -414,55 +58,14 @@ void themeStartup(ThemePreset preset) {
|
|||||||
theme_t *themeDefault;
|
theme_t *themeDefault;
|
||||||
config_t cfg = {0};
|
config_t cfg = {0};
|
||||||
config_init(&cfg);
|
config_init(&cfg);
|
||||||
config_setting_t *theme = NULL, *layout = NULL, *assets = NULL;
|
config_setting_t *theme = NULL;
|
||||||
color_t text, logoColor={0}, attentionText, frontWave, middleWave, backWave, background, highlight, highlightGradientEdgeColor, separator, borderColor, borderTextColor, progressBarColor;
|
color_t text, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor, progressBarColor;
|
||||||
int waveBlending;
|
int waveBlending;
|
||||||
const char *AText, *BText, *XText, *YText, *PText, *MText, *starOnText, *starOffText;
|
const char *AText, *BText, *YText, *PText, *MText;
|
||||||
bool logoColor_set = false;
|
|
||||||
bool good_cfg = 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)
|
||||||
|
good_cfg = config_read_file(&cfg, themePath);
|
||||||
if(themePath[0]!=0) {
|
|
||||||
const char* cfg_path = themePath;
|
|
||||||
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) {
|
|
||||||
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) {
|
switch (preset) {
|
||||||
case THEME_PRESET_LIGHT:
|
case THEME_PRESET_LIGHT:
|
||||||
@ -483,10 +86,6 @@ void themeStartup(ThemePreset preset) {
|
|||||||
if (theme != NULL) {
|
if (theme != NULL) {
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "textColor"), &text))
|
if (!colorFromSetting(config_setting_lookup(theme, "textColor"), &text))
|
||||||
text = themeDefault->textColor;
|
text = themeDefault->textColor;
|
||||||
if (colorFromSetting(config_setting_lookup(theme, "logoColor"), &logoColor))
|
|
||||||
logoColor_set = true;
|
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "attentionTextColor"), &attentionText))
|
|
||||||
attentionText = themeDefault->attentionTextColor;
|
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "frontWaveColor"), &frontWave))
|
if (!colorFromSetting(config_setting_lookup(theme, "frontWaveColor"), &frontWave))
|
||||||
frontWave = themeDefault->frontWaveColor;
|
frontWave = themeDefault->frontWaveColor;
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "middleWaveColor"), &middleWave))
|
if (!colorFromSetting(config_setting_lookup(theme, "middleWaveColor"), &middleWave))
|
||||||
@ -497,8 +96,6 @@ void themeStartup(ThemePreset preset) {
|
|||||||
background = themeDefault->backgroundColor;
|
background = themeDefault->backgroundColor;
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "highlightColor"), &highlight))
|
if (!colorFromSetting(config_setting_lookup(theme, "highlightColor"), &highlight))
|
||||||
highlight = themeDefault->highlightColor;
|
highlight = themeDefault->highlightColor;
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "highlightGradientEdgeColor"), &highlightGradientEdgeColor))
|
|
||||||
highlightGradientEdgeColor = themeDefault->highlightGradientEdgeColor;
|
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "separatorColor"), &separator))
|
if (!colorFromSetting(config_setting_lookup(theme, "separatorColor"), &separator))
|
||||||
separator = themeDefault->separatorColor;
|
separator = themeDefault->separatorColor;
|
||||||
if (!colorFromSetting(config_setting_lookup(theme, "borderColor"), &borderColor))
|
if (!colorFromSetting(config_setting_lookup(theme, "borderColor"), &borderColor))
|
||||||
@ -513,143 +110,38 @@ void themeStartup(ThemePreset preset) {
|
|||||||
AText = themeDefault->buttonAText;
|
AText = themeDefault->buttonAText;
|
||||||
if (!config_setting_lookup_string(theme, "buttonBText", &BText))
|
if (!config_setting_lookup_string(theme, "buttonBText", &BText))
|
||||||
BText = themeDefault->buttonBText;
|
BText = themeDefault->buttonBText;
|
||||||
if (!config_setting_lookup_string(theme, "buttonXText", &XText))
|
|
||||||
XText = themeDefault->buttonXText;
|
|
||||||
if (!config_setting_lookup_string(theme, "buttonYText", &YText))
|
if (!config_setting_lookup_string(theme, "buttonYText", &YText))
|
||||||
YText = themeDefault->buttonYText;
|
YText = themeDefault->buttonYText;
|
||||||
if (!config_setting_lookup_string(theme, "buttonPText", &PText))
|
if (!config_setting_lookup_string(theme, "buttonPText", &PText))
|
||||||
PText = themeDefault->buttonPText;
|
PText = themeDefault->buttonPText;
|
||||||
if (!config_setting_lookup_string(theme, "buttonMText", &MText))
|
if (!config_setting_lookup_string(theme, "buttonMText", &MText))
|
||||||
MText = themeDefault->buttonMText;
|
MText = themeDefault->buttonMText;
|
||||||
if (!config_setting_lookup_string(theme, "labelStarOnText", &starOnText))
|
|
||||||
starOnText = themeDefault->labelStarOnText;
|
|
||||||
if (!config_setting_lookup_string(theme, "labelStarOffText", &starOffText))
|
|
||||||
starOffText = themeDefault->labelStarOffText;
|
|
||||||
themeCurrent = (theme_t) {
|
themeCurrent = (theme_t) {
|
||||||
.textColor = text,
|
.textColor = text,
|
||||||
.logoColor = logoColor,
|
|
||||||
.attentionTextColor = attentionText,
|
|
||||||
.frontWaveColor = frontWave,
|
.frontWaveColor = frontWave,
|
||||||
.middleWaveColor = middleWave,
|
.middleWaveColor = middleWave,
|
||||||
.backWaveColor = backWave,
|
.backWaveColor = backWave,
|
||||||
.backgroundColor = background,
|
.backgroundColor = background,
|
||||||
.highlightColor = highlight,
|
.highlightColor = highlight,
|
||||||
.highlightGradientEdgeColor = highlightGradientEdgeColor,
|
|
||||||
.separatorColor = separator,
|
.separatorColor = separator,
|
||||||
.borderColor = borderColor,
|
.borderColor = borderColor,
|
||||||
.borderTextColor = borderTextColor,
|
.borderTextColor = borderTextColor,
|
||||||
.progressBarColor = progressBarColor,
|
.progressBarColor = progressBarColor,
|
||||||
.logoColor_set = logoColor_set,
|
|
||||||
.enableWaveBlending = waveBlending,
|
.enableWaveBlending = waveBlending,
|
||||||
|
.hbmenuLogoImage = themeDefault->hbmenuLogoImage
|
||||||
};
|
};
|
||||||
strncpy(themeCurrent.buttonAText, AText, sizeof(themeCurrent.buttonAText));
|
strncpy(themeCurrent.buttonAText, AText, sizeof(themeCurrent.buttonAText)-1);
|
||||||
themeCurrent.buttonAText[sizeof(themeCurrent.buttonAText)-1] = 0;
|
strncpy(themeCurrent.buttonBText, BText, sizeof(themeCurrent.buttonBText)-1);
|
||||||
strncpy(themeCurrent.buttonBText, BText, sizeof(themeCurrent.buttonBText));
|
strncpy(themeCurrent.buttonYText, YText, sizeof(themeCurrent.buttonYText)-1);
|
||||||
themeCurrent.buttonBText[sizeof(themeCurrent.buttonBText)-1] = 0;
|
strncpy(themeCurrent.buttonPText, PText, sizeof(themeCurrent.buttonPText)-1);
|
||||||
strncpy(themeCurrent.buttonXText, XText, sizeof(themeCurrent.buttonXText));
|
strncpy(themeCurrent.buttonMText, MText, sizeof(themeCurrent.buttonMText)-1);
|
||||||
themeCurrent.buttonXText[sizeof(themeCurrent.buttonXText)-1] = 0;
|
|
||||||
strncpy(themeCurrent.buttonYText, YText, sizeof(themeCurrent.buttonYText));
|
|
||||||
themeCurrent.buttonYText[sizeof(themeCurrent.buttonYText)-1] = 0;
|
|
||||||
strncpy(themeCurrent.buttonPText, PText, sizeof(themeCurrent.buttonPText));
|
|
||||||
themeCurrent.buttonPText[sizeof(themeCurrent.buttonPText)-1] = 0;
|
|
||||||
strncpy(themeCurrent.buttonMText, MText, sizeof(themeCurrent.buttonMText));
|
|
||||||
themeCurrent.buttonMText[sizeof(themeCurrent.buttonMText)-1] = 0;
|
|
||||||
strncpy(themeCurrent.labelStarOnText, starOnText, sizeof(themeCurrent.labelStarOnText));
|
|
||||||
themeCurrent.labelStarOnText[sizeof(themeCurrent.labelStarOnText)-1] = 0;
|
|
||||||
strncpy(themeCurrent.labelStarOffText, starOffText, sizeof(themeCurrent.labelStarOffText));
|
|
||||||
themeCurrent.labelStarOffText[sizeof(themeCurrent.labelStarOffText)-1] = 0;
|
|
||||||
} else {
|
} else {
|
||||||
themeCurrent = *themeDefault;
|
themeCurrent = *themeDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(themeCurrent.layoutObjects, themeCommon.layoutObjects, sizeof(themeCommon.layoutObjects));
|
|
||||||
|
|
||||||
layout = config_lookup(&cfg, "layout");
|
|
||||||
|
|
||||||
if (layout != NULL) {
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "logo"), &themeCurrent.layoutObjects[ThemeLayoutId_Logo], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "hbmenuVersion"), &themeCurrent.layoutObjects[ThemeLayoutId_HbmenuVersion], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "loaderInfo"), &themeCurrent.layoutObjects[ThemeLayoutId_LoaderInfo], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "attentionText"), &themeCurrent.layoutObjects[ThemeLayoutId_AttentionText], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "logInfo"), &themeCurrent.layoutObjects[ThemeLayoutId_LogInfo], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "infoMsg"), &themeCurrent.layoutObjects[ThemeLayoutId_InfoMsg], true);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuPath"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuPath], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuTypeMsg"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuTypeMsg], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "msgBoxSeparator"), &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "msgBoxBottomText"), &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxBottomText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "backgroundImage"), &themeCurrent.layoutObjects[ThemeLayoutId_BackgroundImage], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "backWave"), &themeCurrent.layoutObjects[ThemeLayoutId_BackWave], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "middleWave"), &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "frontWave"), &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonA"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonAText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonAText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonB"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonB], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonBText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonBText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonY"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonY], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonYText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonYText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonM"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonM], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonMText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonMText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonX"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonX], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "buttonXText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonXText], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "networkIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_NetworkIcon], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "batteryCharge"), &themeCurrent.layoutObjects[ThemeLayoutId_BatteryCharge], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "batteryIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_BatteryIcon], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "chargingIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_ChargingIcon], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "status"), &themeCurrent.layoutObjects[ThemeLayoutId_Status], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "temperature"), &themeCurrent.layoutObjects[ThemeLayoutId_Temperature], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuList"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuList], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuListTiles"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuListIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuListName"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListName], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryName"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryName], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryAuthor"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryAuthor], false);
|
|
||||||
layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryVersion"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryVersion], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
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]);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "invalid_icon"), AssetId_invalid_icon, &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon]);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "theme_icon_dark"), AssetId_theme_icon_dark, &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon]);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "theme_icon_light"), AssetId_theme_icon_light, &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon]);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "airplane_icon"), AssetId_airplane_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "wifi_none_icon"), AssetId_wifi_none_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "wifi1_icon"), AssetId_wifi1_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "wifi2_icon"), AssetId_wifi2_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "wifi3_icon"), AssetId_wifi3_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "eth_icon"), AssetId_eth_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "eth_none_icon"), AssetId_eth_none_icon, NULL);
|
|
||||||
assetObjectFromSetting(config_setting_lookup(assets, "background_image"), AssetId_background_image, NULL);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
themeCurrent = *themeDefault;
|
themeCurrent = *themeDefault;
|
||||||
memcpy(themeCurrent.layoutObjects, themeCommon.layoutObjects, sizeof(themeCommon.layoutObjects));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles];
|
|
||||||
if (layoutobj->posEnd[0] < 1) layoutobj->posEnd[0] = 1;
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon];
|
|
||||||
if (layoutobj->size[0] <= 0 || layoutobj->size[1] <= 0 || layoutobj->size[0] > layoutobj->imageSize[0] || layoutobj->size[1] > layoutobj->imageSize[1]) {
|
|
||||||
layoutobj->size[0] = layoutobj->imageSize[0];
|
|
||||||
layoutobj->size[1] = layoutobj->imageSize[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon];
|
|
||||||
if (layoutobj->size[0] <= 0 || layoutobj->size[1] <= 0 || layoutobj->size[0] > layoutobj->imageSize[0] || layoutobj->size[1] > layoutobj->imageSize[1]) {
|
|
||||||
layoutobj->size[0] = layoutobj->imageSize[0];
|
|
||||||
layoutobj->size[1] = layoutobj->imageSize[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
|
|
||||||
if (is_archive) PHYSFS_unmount(theme_archive_path);
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
if (is_romfs) romfsUnmount("theme");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetThemePathFromConfig(char* themePath, size_t size) {
|
void GetThemePathFromConfig(char* themePath, size_t size) {
|
||||||
|
@ -3,55 +3,33 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
color_t textColor;
|
||||||
|
color_t frontWaveColor;
|
||||||
|
color_t middleWaveColor;
|
||||||
|
color_t backWaveColor;
|
||||||
|
color_t backgroundColor;
|
||||||
|
color_t highlightColor;
|
||||||
|
color_t separatorColor;
|
||||||
|
color_t borderColor;
|
||||||
|
color_t borderTextColor;
|
||||||
|
color_t progressBarColor;
|
||||||
|
bool enableWaveBlending;
|
||||||
|
char buttonAText[32];
|
||||||
|
char buttonBText[32];
|
||||||
|
char buttonYText[32];
|
||||||
|
char buttonPText[32];
|
||||||
|
char buttonMText[32];
|
||||||
|
const uint8_t *hbmenuLogoImage;
|
||||||
|
} theme_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
THEME_PRESET_LIGHT,
|
THEME_PRESET_LIGHT,
|
||||||
THEME_PRESET_DARK,
|
THEME_PRESET_DARK,
|
||||||
} ThemePreset;
|
} ThemePreset;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool visible;
|
|
||||||
bool posType; // false = absolute, true = relative
|
|
||||||
int posStart[2];
|
|
||||||
int posEnd[2];
|
|
||||||
int size[2]; // width/height
|
|
||||||
int imageSize[2]; // width/height for the actual image data
|
|
||||||
int touchSize[2];
|
|
||||||
int posFinal[2];
|
|
||||||
uint32_t textSize[2];
|
|
||||||
u32 font;
|
|
||||||
} ThemeLayoutObject;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
color_t textColor;
|
|
||||||
color_t logoColor;
|
|
||||||
color_t attentionTextColor;
|
|
||||||
color_t frontWaveColor;
|
|
||||||
color_t middleWaveColor;
|
|
||||||
color_t backWaveColor;
|
|
||||||
color_t backgroundColor;
|
|
||||||
color_t highlightColor;
|
|
||||||
color_t highlightGradientEdgeColor;
|
|
||||||
color_t separatorColor;
|
|
||||||
color_t borderColor;
|
|
||||||
color_t borderTextColor;
|
|
||||||
color_t progressBarColor;
|
|
||||||
bool logoColor_set;
|
|
||||||
bool enableWaveBlending;
|
|
||||||
char buttonAText[32];
|
|
||||||
char buttonBText[32];
|
|
||||||
char buttonXText[32];
|
|
||||||
char buttonYText[32];
|
|
||||||
char buttonPText[32];
|
|
||||||
char buttonMText[32];
|
|
||||||
char labelStarOnText[32];
|
|
||||||
char labelStarOffText[32];
|
|
||||||
|
|
||||||
ThemeLayoutObject layoutObjects[ThemeLayoutId_Total];
|
|
||||||
} theme_t;
|
|
||||||
|
|
||||||
bool colorFromSetting(config_setting_t *rgba, color_t *col);
|
bool colorFromSetting(config_setting_t *rgba, color_t *col);
|
||||||
void themeStartup(ThemePreset preset);
|
void themeStartup(ThemePreset preset);
|
||||||
void GetThemePathFromConfig(char* themePath, size_t size);
|
void GetThemePathFromConfig(char* themePath, size_t size);
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
bool thermalstatusInit(void);
|
|
||||||
void thermalstatusExit(void);
|
|
||||||
bool thermalstatusGetDetails(s32 *temperature);
|
|
||||||
|
|
@ -68,20 +68,10 @@ static void launchFile(const char* path, argData_s* args)
|
|||||||
|
|
||||||
init_args(argBuf, sizeof(argBuf)-1, args->buf, sizeof(args->buf));
|
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);
|
Result rc = envSetNextLoad(path, argBuf);
|
||||||
if(R_FAILED(rc)) {
|
if(R_FAILED(rc)) {
|
||||||
memset(msg, 0, sizeof(msg));
|
memset(msg, 0, sizeof(msg));
|
||||||
snprintf(msg, sizeof(msg)-1, "%s\n2%03d-%04d", textGetString(StrId_AppLaunchError), R_MODULE(rc), R_DESCRIPTION(rc));
|
snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_AppLaunchError), rc);
|
||||||
|
|
||||||
menuCreateMsgBox(780, 300, msg);
|
menuCreateMsgBox(780, 300, msg);
|
||||||
}
|
}
|
||||||
@ -89,7 +79,6 @@ static void launchFile(const char* path, argData_s* args)
|
|||||||
uiExitLoop();
|
uiExitLoop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const loaderFuncs_s loader_builtin =
|
const loaderFuncs_s loader_builtin =
|
||||||
{
|
{
|
||||||
|
127
nx_main/main.c
@ -1,25 +1,17 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
#include "nx_graphics.h"
|
|
||||||
#include "nx_touch.h"
|
#include "nx_touch.h"
|
||||||
|
|
||||||
// Define the desired framebuffer resolution (here we set it to 720p).
|
|
||||||
#define FB_WIDTH 1280
|
|
||||||
#define FB_HEIGHT 720
|
|
||||||
|
|
||||||
uint8_t* g_framebuf;
|
uint8_t* g_framebuf;
|
||||||
u32 g_framebuf_width;
|
u32 g_framebuf_width;
|
||||||
|
|
||||||
PadState g_pad;
|
|
||||||
PadRepeater g_pad_repeater;
|
|
||||||
|
|
||||||
bool menuUpdateErrorScreen(void);
|
bool menuUpdateErrorScreen(void);
|
||||||
|
|
||||||
#ifdef PERF_LOG
|
#ifdef PERF_LOG
|
||||||
|
u64 g_tickdiff_vsync=0;
|
||||||
u64 g_tickdiff_frame=0;
|
u64 g_tickdiff_frame=0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -42,44 +34,35 @@ int main(int argc, char **argv)
|
|||||||
u64 start_tick=0;
|
u64 start_tick=0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
padConfigureInput(8, HidNpadStyleSet_NpadStandard);
|
|
||||||
padInitializeAny(&g_pad);
|
|
||||||
padRepeaterInitialize(&g_pad_repeater, 20, 10);
|
|
||||||
hidSetNpadHandheldActivationMode(HidNpadHandheldActivationMode_Single);
|
|
||||||
touchInit();
|
|
||||||
|
|
||||||
memset(errormsg, 0, sizeof(errormsg));
|
memset(errormsg, 0, sizeof(errormsg));
|
||||||
|
|
||||||
appletLockExit();
|
appletLockExit();
|
||||||
appletSetScreenShotPermission(AppletScreenShotPermission_Enable);
|
appletSetScreenShotPermission(1);
|
||||||
|
|
||||||
ColorSetId theme = ColorSetId_Light;
|
ColorSetId theme;
|
||||||
rc = setsysInitialize();
|
rc = setsysInitialize();
|
||||||
|
if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: setsysInitialize() failed: 0x%x.", rc);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) setsysGetColorSetId(&theme);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
setsysGetColorSetId(&theme);
|
rc = plInitialize();
|
||||||
setsysExit();
|
if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: plInitialize() failed: 0x%x.", rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
rc = textInit();
|
rc = textInit();
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: textInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc));
|
snprintf(errormsg, sizeof(errormsg)-1, "Error: textInit() failed: 0x%x.", rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) menuStartupPath();
|
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)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
rc = assetsInit();
|
rc = assetsInit();
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: assetsInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc));
|
snprintf(errormsg, sizeof(errormsg)-1, "Error: assetsInit() failed: 0x%x.", rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +73,7 @@ int main(int argc, char **argv)
|
|||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
rc = netloaderInit();
|
rc = netloaderInit();
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: netloaderInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc));
|
snprintf(errormsg, sizeof(errormsg)-1, "Error: netloaderInit() failed: 0x%x.", rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,11 +82,6 @@ int main(int argc, char **argv)
|
|||||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: workerInit() failed.");
|
snprintf(errormsg, sizeof(errormsg)-1, "Error: workerInit() failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc) && !statusInit()) {
|
|
||||||
rc = 1;
|
|
||||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: statusInit() failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) menuStartup();
|
if (R_SUCCEEDED(rc)) menuStartup();
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
@ -127,7 +105,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (R_FAILED(lastret)) {
|
if (R_FAILED(lastret)) {
|
||||||
memset(msg, 0, sizeof(msg));
|
memset(msg, 0, sizeof(msg));
|
||||||
snprintf(msg, sizeof(msg)-1, "%s\n2%03d-%04d", textGetString(StrId_LastLoadResult), R_MODULE(lastret), R_DESCRIPTION(lastret));
|
snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_LastLoadResult), lastret);
|
||||||
|
|
||||||
menuCreateMsgBox(780, 300, msg);
|
menuCreateMsgBox(780, 300, msg);
|
||||||
}
|
}
|
||||||
@ -136,7 +114,7 @@ int main(int argc, char **argv)
|
|||||||
if (errormsg[0]) error_screen = 1;
|
if (errormsg[0]) error_screen = 1;
|
||||||
|
|
||||||
if (!error_screen) {
|
if (!error_screen) {
|
||||||
graphicsInit(FB_WIDTH, FB_HEIGHT);
|
gfxInitDefault();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
consoleInit(NULL);
|
consoleInit(NULL);
|
||||||
@ -144,21 +122,29 @@ int main(int argc, char **argv)
|
|||||||
printf("Press the + button to exit.\n");
|
printf("Press the + button to exit.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PERF_LOG
|
||||||
|
if (!error_screen) {
|
||||||
|
gfxWaitForVsync();
|
||||||
|
|
||||||
|
start_tick = svcGetSystemTick();
|
||||||
|
gfxWaitForVsync();
|
||||||
|
g_tickdiff_vsync = svcGetSystemTick() - start_tick;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (appletMainLoop())
|
while (appletMainLoop())
|
||||||
{
|
{
|
||||||
// Scan the gamepad. This should be done once for each frame
|
#ifdef PERF_LOG
|
||||||
padUpdate(&g_pad);
|
if (!error_screen) start_tick = svcGetSystemTick();
|
||||||
padRepeaterUpdate(&g_pad_repeater, padGetButtons(&g_pad) & (
|
#endif
|
||||||
HidNpadButton_AnyLeft | HidNpadButton_AnyUp | HidNpadButton_AnyRight | HidNpadButton_AnyDown
|
|
||||||
));
|
//Scan all the inputs. This should be done once for each frame
|
||||||
|
hidScanInput();
|
||||||
|
|
||||||
if (!error_screen) {
|
if (!error_screen) {
|
||||||
|
g_framebuf = gfxGetFramebuffer(&g_framebuf_width, NULL);
|
||||||
|
memset(g_framebuf, 237, gfxGetFramebufferSize());
|
||||||
if (!uiUpdate()) break;
|
if (!uiUpdate()) break;
|
||||||
g_framebuf = graphicsFrameBegin(&g_framebuf_width);
|
|
||||||
#ifdef PERF_LOG
|
|
||||||
start_tick = armGetSystemTick();
|
|
||||||
#endif
|
|
||||||
memset(g_framebuf, 237, g_framebuf_width * FB_HEIGHT);
|
|
||||||
menuLoop();
|
menuLoop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -166,11 +152,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!error_screen) {
|
if (!error_screen) {
|
||||||
graphicsFrameEnd();
|
gfxFlushBuffers();
|
||||||
|
|
||||||
#ifdef PERF_LOG
|
#ifdef PERF_LOG
|
||||||
g_tickdiff_frame = armGetSystemTick() - start_tick;
|
g_tickdiff_frame = svcGetSystemTick() - start_tick;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gfxSwapBuffers();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
consoleUpdate(NULL);
|
consoleUpdate(NULL);
|
||||||
@ -178,7 +166,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!error_screen) {
|
if (!error_screen) {
|
||||||
graphicsExit();
|
gfxExit();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
consoleExit(NULL);
|
consoleExit(NULL);
|
||||||
@ -192,54 +180,41 @@ int main(int argc, char **argv)
|
|||||||
fontExit();
|
fontExit();
|
||||||
launchExit();
|
launchExit();
|
||||||
netloaderSignalExit();
|
netloaderSignalExit();
|
||||||
statusExit();
|
|
||||||
workerExit();
|
workerExit();
|
||||||
netloaderExit();
|
netloaderExit();
|
||||||
powerExit();
|
powerExit();
|
||||||
assetsExit();
|
assetsExit();
|
||||||
PHYSFS_deinit();
|
plExit();
|
||||||
|
setsysExit();
|
||||||
|
|
||||||
appletUnlockExit();
|
appletUnlockExit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 menuGetKeysDown(void) {
|
|
||||||
u64 keys = padGetButtonsDown(&g_pad);
|
|
||||||
keys |= padRepeaterGetButtons(&g_pad_repeater);
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is implemented here due to the hid code.
|
//This is implemented here due to the hid code.
|
||||||
bool menuUpdate(void) {
|
bool menuUpdate(void) {
|
||||||
bool exitflag = 0;
|
bool exitflag = 0;
|
||||||
menu_s* menu = menuGetCurrent();
|
menu_s* menu = menuGetCurrent();
|
||||||
u64 down = menuGetKeysDown();
|
u32 down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles];
|
|
||||||
int entries_count = layoutobj->posEnd[0];
|
|
||||||
|
|
||||||
handleTouch(menu);
|
handleTouch(menu);
|
||||||
|
|
||||||
if (down & HidNpadButton_Y)
|
if (down & KEY_Y)
|
||||||
{
|
{
|
||||||
launchMenuNetloaderTask();
|
launchMenuNetloaderTask();
|
||||||
}
|
}
|
||||||
else if (down & HidNpadButton_X)
|
else if (down & KEY_A)
|
||||||
{
|
|
||||||
menuHandleXButton();
|
|
||||||
}
|
|
||||||
else if (down & HidNpadButton_A)
|
|
||||||
{
|
{
|
||||||
menuHandleAButton();
|
menuHandleAButton();
|
||||||
}
|
}
|
||||||
else if (down & HidNpadButton_B)
|
else if (down & KEY_B)
|
||||||
{
|
{
|
||||||
launchMenuBackTask();
|
launchMenuBackTask();
|
||||||
}
|
}
|
||||||
else if(down & HidNpadButton_Minus){
|
else if(down & KEY_MINUS){
|
||||||
themeMenuStartup();
|
themeMenuStartup();
|
||||||
}
|
}
|
||||||
else if (down & HidNpadButton_Plus)
|
else if (down & KEY_PLUS)
|
||||||
{
|
{
|
||||||
exitflag = 1;
|
exitflag = 1;
|
||||||
}
|
}
|
||||||
@ -247,10 +222,10 @@ bool menuUpdate(void) {
|
|||||||
{
|
{
|
||||||
int move = 0;
|
int move = 0;
|
||||||
|
|
||||||
if (down & HidNpadButton_AnyLeft) move--;
|
if (down & KEY_LEFT) move--;
|
||||||
if (down & HidNpadButton_AnyRight) move++;
|
if (down & KEY_RIGHT) move++;
|
||||||
if (down & HidNpadButton_AnyDown) move-=entries_count;
|
if (down & KEY_DOWN) move-=7;
|
||||||
if (down & HidNpadButton_AnyUp) move+=entries_count;
|
if (down & KEY_UP) move+=7;
|
||||||
|
|
||||||
int newEntry = menu->curEntry + move;
|
int newEntry = menu->curEntry + move;
|
||||||
if (newEntry < 0) newEntry = 0;
|
if (newEntry < 0) newEntry = 0;
|
||||||
@ -263,9 +238,9 @@ bool menuUpdate(void) {
|
|||||||
|
|
||||||
bool menuUpdateErrorScreen(void) {
|
bool menuUpdateErrorScreen(void) {
|
||||||
bool exitflag = 0;
|
bool exitflag = 0;
|
||||||
u64 down = menuGetKeysDown();
|
u32 down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||||
|
|
||||||
if (down & HidNpadButton_Plus)
|
if (down & KEY_PLUS)
|
||||||
{
|
{
|
||||||
exitflag = 1;
|
exitflag = 1;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ static void audio_playback_thread(void* arg)
|
|||||||
playing = 1;
|
playing = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(audoutWaitPlayFinish(&released_buffer, &released_count, UINT64_MAX)))
|
if (R_SUCCEEDED(audoutWaitPlayFinish(&released_buffer, &released_count, U64_MAX)))
|
||||||
playing = 0;
|
playing = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
#include <switch.h>
|
|
||||||
#include <deko3d.h>
|
|
||||||
|
|
||||||
#include "nx_graphics.h"
|
|
||||||
|
|
||||||
#define FB_NUM 2
|
|
||||||
#define CMDMEMSIZE 0x1000
|
|
||||||
|
|
||||||
static u32 s_fbWidth, s_fbHeight;
|
|
||||||
|
|
||||||
static DkDevice s_device;
|
|
||||||
static DkMemBlock s_fbMemBlock, s_workMemBlock, s_cmdMemBlock;
|
|
||||||
static DkSwapchain s_swapchain;
|
|
||||||
static DkCmdBuf s_cmdBuf;
|
|
||||||
static DkCmdList s_cmdLists[FB_NUM];
|
|
||||||
static DkFence s_fence;
|
|
||||||
static DkQueue s_queue;
|
|
||||||
|
|
||||||
void graphicsInit(u32 width, u32 height)
|
|
||||||
{
|
|
||||||
DkImageLayoutMaker imgLayoutMaker;
|
|
||||||
DkMemBlockMaker memBlockMaker;
|
|
||||||
|
|
||||||
// Create the device, which is the root object
|
|
||||||
DkDeviceMaker deviceMaker;
|
|
||||||
dkDeviceMakerDefaults(&deviceMaker);
|
|
||||||
s_device = dkDeviceCreate(&deviceMaker);
|
|
||||||
|
|
||||||
// Calculate layout for the framebuffers
|
|
||||||
DkImageLayout fbLayout;
|
|
||||||
dkImageLayoutMakerDefaults(&imgLayoutMaker, s_device);
|
|
||||||
imgLayoutMaker.flags = DkImageFlags_UsagePresent;
|
|
||||||
imgLayoutMaker.format = DkImageFormat_RGBA8_Unorm;
|
|
||||||
imgLayoutMaker.dimensions[0] = s_fbWidth = width;
|
|
||||||
imgLayoutMaker.dimensions[1] = s_fbHeight = height;
|
|
||||||
dkImageLayoutInitialize(&fbLayout, &imgLayoutMaker);
|
|
||||||
|
|
||||||
// Retrieve necessary size and alignment for the framebuffers
|
|
||||||
uint32_t fbSize = dkImageLayoutGetSize(&fbLayout);
|
|
||||||
uint32_t fbAlign = dkImageLayoutGetAlignment(&fbLayout);
|
|
||||||
fbSize = (fbSize + fbAlign - 1) &~ (fbAlign - 1);
|
|
||||||
|
|
||||||
// Create a memory block that will host the framebuffers
|
|
||||||
dkMemBlockMakerDefaults(&memBlockMaker, s_device, FB_NUM*fbSize);
|
|
||||||
memBlockMaker.flags = DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image;
|
|
||||||
s_fbMemBlock = dkMemBlockCreate(&memBlockMaker);
|
|
||||||
|
|
||||||
// Initialize the framebuffers with the layout and backing memory we've just created
|
|
||||||
DkImage fbImages[FB_NUM];
|
|
||||||
DkImage const* swapchainImages[FB_NUM];
|
|
||||||
for (unsigned i = 0; i < FB_NUM; i ++)
|
|
||||||
{
|
|
||||||
swapchainImages[i] = &fbImages[i];
|
|
||||||
dkImageInitialize(&fbImages[i], &fbLayout, s_fbMemBlock, i*fbSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a swapchain out of the framebuffers we've just initialized
|
|
||||||
DkSwapchainMaker swapchainMaker;
|
|
||||||
dkSwapchainMakerDefaults(&swapchainMaker, s_device, nwindowGetDefault(), swapchainImages, FB_NUM);
|
|
||||||
s_swapchain = dkSwapchainCreate(&swapchainMaker);
|
|
||||||
|
|
||||||
// Create a memory block for the linear framebuffer
|
|
||||||
dkMemBlockMakerDefaults(&memBlockMaker, s_device, width*height*4);
|
|
||||||
memBlockMaker.flags = DkMemBlockFlags_CpuCached | DkMemBlockFlags_GpuUncached;
|
|
||||||
s_workMemBlock = dkMemBlockCreate(&memBlockMaker);
|
|
||||||
|
|
||||||
// Create a memory block for the command lists
|
|
||||||
dkMemBlockMakerDefaults(&memBlockMaker, s_device, CMDMEMSIZE);
|
|
||||||
memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached;
|
|
||||||
s_cmdMemBlock = dkMemBlockCreate(&memBlockMaker);
|
|
||||||
|
|
||||||
// Create a command buffer
|
|
||||||
DkCmdBufMaker cmdBufMaker;
|
|
||||||
dkCmdBufMakerDefaults(&cmdBufMaker, s_device);
|
|
||||||
s_cmdBuf = dkCmdBufCreate(&cmdBufMaker);
|
|
||||||
dkCmdBufAddMemory(s_cmdBuf, s_cmdMemBlock, 0, CMDMEMSIZE);
|
|
||||||
|
|
||||||
// Define source for linear framebuffer copies
|
|
||||||
const DkCopyBuf linearSrc = {
|
|
||||||
.addr = dkMemBlockGetGpuAddr(s_workMemBlock),
|
|
||||||
.rowLength = 0,
|
|
||||||
.imageHeight = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define rectangle for the copies
|
|
||||||
const DkImageRect copyRect = {
|
|
||||||
.x = 0, .y = 0, .z = 0,
|
|
||||||
.width = width, .height = height, .depth = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Record command lists for the copies
|
|
||||||
for (unsigned i = 0; i < FB_NUM; i ++) {
|
|
||||||
DkImageView tiledDst;
|
|
||||||
dkImageViewDefaults(&tiledDst, &fbImages[i]);
|
|
||||||
dkCmdBufCopyBufferToImage(s_cmdBuf, &linearSrc, &tiledDst, ©Rect, 0);
|
|
||||||
dkCmdBufSignalFence(s_cmdBuf, &s_fence, false);
|
|
||||||
s_cmdLists[i] = dkCmdBufFinishList(s_cmdBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a queue, to which we will submit our command lists
|
|
||||||
DkQueueMaker queueMaker;
|
|
||||||
dkQueueMakerDefaults(&queueMaker, s_device);
|
|
||||||
queueMaker.flags = 0; // we will only use this queue for transferring
|
|
||||||
s_queue = dkQueueCreate(&queueMaker);
|
|
||||||
}
|
|
||||||
|
|
||||||
void graphicsExit(void)
|
|
||||||
{
|
|
||||||
// Make sure the queue is idle before destroying anything
|
|
||||||
dkQueueWaitIdle(s_queue);
|
|
||||||
|
|
||||||
// Destroy all the resources we've created
|
|
||||||
dkQueueDestroy(s_queue);
|
|
||||||
dkCmdBufDestroy(s_cmdBuf);
|
|
||||||
dkMemBlockDestroy(s_cmdMemBlock);
|
|
||||||
dkMemBlockDestroy(s_workMemBlock);
|
|
||||||
dkSwapchainDestroy(s_swapchain);
|
|
||||||
dkMemBlockDestroy(s_fbMemBlock);
|
|
||||||
dkDeviceDestroy(s_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* graphicsFrameBegin(u32* out_stride)
|
|
||||||
{
|
|
||||||
// Ensure the GPU is not reading from the framebuffer
|
|
||||||
dkFenceWait(&s_fence, -1);
|
|
||||||
|
|
||||||
// Return information
|
|
||||||
if (out_stride) *out_stride = s_fbWidth*4;
|
|
||||||
return dkMemBlockGetCpuAddr(s_workMemBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void graphicsFrameEnd(void)
|
|
||||||
{
|
|
||||||
// Flush the linear framebuffer
|
|
||||||
dkMemBlockFlushCpuCache(s_workMemBlock, 0, s_fbWidth*s_fbHeight*4);
|
|
||||||
|
|
||||||
// Present a frame
|
|
||||||
int slot = dkQueueAcquireImage(s_queue, s_swapchain);
|
|
||||||
dkQueueSubmitCommands(s_queue, s_cmdLists[slot]);
|
|
||||||
dkQueuePresentImage(s_queue, s_swapchain, slot);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <switch.h>
|
|
||||||
|
|
||||||
void graphicsInit(u32 width, u32 height);
|
|
||||||
void graphicsExit(void);
|
|
||||||
|
|
||||||
void* graphicsFrameBegin(u32* out_stride);
|
|
||||||
void graphicsFrameEnd(void);
|
|
@ -1,36 +0,0 @@
|
|||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
bool netstatusGetDetails(AssetId *id) {
|
|
||||||
Result rc=0;
|
|
||||||
NifmInternetConnectionType contype;
|
|
||||||
u32 wifiStrength=0;
|
|
||||||
NifmInternetConnectionStatus connectionStatus;
|
|
||||||
|
|
||||||
rc = nifmGetInternetConnectionStatus(&contype, &wifiStrength, &connectionStatus);
|
|
||||||
if (R_FAILED(rc)) {
|
|
||||||
*id = AssetId_airplane_icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contype == NifmInternetConnectionType_Ethernet) {
|
|
||||||
if (connectionStatus != NifmInternetConnectionStatus_Connected)
|
|
||||||
*id = AssetId_eth_none_icon;
|
|
||||||
else
|
|
||||||
*id = AssetId_eth_icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wifiStrength==0) {
|
|
||||||
*id = AssetId_wifi_none_icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wifiStrength==3)
|
|
||||||
*id = AssetId_wifi3_icon;
|
|
||||||
if (wifiStrength==2)
|
|
||||||
*id = AssetId_wifi2_icon;
|
|
||||||
else
|
|
||||||
*id = AssetId_wifi1_icon;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,14 +1,13 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
|
|
||||||
static bool powerInitialized;
|
static bool psmInitialized;
|
||||||
static bool powerCacheInitialized;
|
static bool psmCacheInitialized;
|
||||||
static uint32_t powerCacheCharge;
|
static uint32_t psmCacheCharge;
|
||||||
static bool powerCacheIsCharging;
|
static bool psmCacheIsCharging;
|
||||||
static PsmSession powerSession;
|
|
||||||
|
|
||||||
bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
|
bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
|
||||||
PsmChargerType charger = PsmChargerType_Unconnected;
|
ChargerType charger = ChargerType_None;
|
||||||
bool hwReadsSucceeded = false;
|
bool hwReadsSucceeded = false;
|
||||||
bool use_cache = false;
|
bool use_cache = false;
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
@ -16,9 +15,9 @@ bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
|
|||||||
*isCharging = false;
|
*isCharging = false;
|
||||||
*batteryCharge = 0;
|
*batteryCharge = 0;
|
||||||
|
|
||||||
if (powerInitialized) {
|
if (psmInitialized) {
|
||||||
if (powerCacheInitialized) {
|
if (psmCacheInitialized) {
|
||||||
rc = psmWaitStateChangeEvent(&powerSession, 0);
|
rc = psmWaitStateChangeEvent(0);
|
||||||
|
|
||||||
if (R_FAILED(rc)) use_cache = true;
|
if (R_FAILED(rc)) use_cache = true;
|
||||||
}
|
}
|
||||||
@ -26,17 +25,17 @@ bool powerGetDetails(uint32_t *batteryCharge, bool *isCharging) {
|
|||||||
rc = psmGetBatteryChargePercentage(batteryCharge);
|
rc = psmGetBatteryChargePercentage(batteryCharge);
|
||||||
hwReadsSucceeded = R_SUCCEEDED(rc);
|
hwReadsSucceeded = R_SUCCEEDED(rc);
|
||||||
if (use_cache) {
|
if (use_cache) {
|
||||||
*isCharging = powerCacheIsCharging;
|
*isCharging = psmCacheIsCharging;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = psmGetChargerType(&charger);
|
rc = psmGetChargerType(&charger);
|
||||||
hwReadsSucceeded &= R_SUCCEEDED(rc);
|
hwReadsSucceeded &= R_SUCCEEDED(rc);
|
||||||
*isCharging = (charger != PsmChargerType_Unconnected);
|
*isCharging = (charger > ChargerType_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
powerCacheCharge = *batteryCharge;
|
psmCacheCharge = *batteryCharge;
|
||||||
powerCacheIsCharging = *isCharging;
|
psmCacheIsCharging = *isCharging;
|
||||||
powerCacheInitialized = true;
|
psmCacheInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hwReadsSucceeded;
|
return hwReadsSucceeded;
|
||||||
@ -46,18 +45,18 @@ void powerInit(void) {
|
|||||||
uint32_t charge=0;
|
uint32_t charge=0;
|
||||||
bool isCharging=0;
|
bool isCharging=0;
|
||||||
|
|
||||||
powerCacheInitialized = false;
|
psmCacheInitialized = false;
|
||||||
powerCacheCharge = 0;
|
psmCacheCharge = 0;
|
||||||
powerCacheIsCharging = false;
|
psmCacheIsCharging = false;
|
||||||
|
|
||||||
if (!powerInitialized) {
|
if (!psmInitialized) {
|
||||||
Result rc = psmInitialize();
|
Result rc = psmInitialize();
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
rc = psmBindStateChangeEvent(&powerSession, 1, 1, 1);
|
rc = psmBindStateChangeEvent(1, 1, 1);
|
||||||
|
|
||||||
if (R_FAILED(rc)) psmExit();
|
if (R_FAILED(rc)) psmExit();
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
powerInitialized = true;
|
psmInitialized = true;
|
||||||
powerGetDetails(&charge, &isCharging);//Init the cache.
|
powerGetDetails(&charge, &isCharging);//Init the cache.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,10 +64,9 @@ void powerInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void powerExit(void) {
|
void powerExit(void) {
|
||||||
if (powerInitialized) {
|
if (psmInitialized) {
|
||||||
psmUnbindStateChangeEvent(&powerSession);
|
|
||||||
psmExit();
|
psmExit();
|
||||||
powerInitialized = false;
|
psmInitialized = false;
|
||||||
powerCacheInitialized = false;
|
psmCacheInitialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
bool thermalstatusInit(void) {
|
|
||||||
return R_SUCCEEDED(tsInitialize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void thermalstatusExit(void) {
|
|
||||||
tsExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool thermalstatusGetDetails(s32 *temperature) {
|
|
||||||
return R_SUCCEEDED(tsGetTemperature(TsLocation_Internal, temperature));
|
|
||||||
}
|
|
||||||
|
|
@ -5,33 +5,38 @@
|
|||||||
#define VERTICAL_SWIPE_MINIMUM_DISTANCE 300
|
#define VERTICAL_SWIPE_MINIMUM_DISTANCE 300
|
||||||
#define HORIZONTAL_SWIPE_VERTICAL_PLAY 250
|
#define HORIZONTAL_SWIPE_VERTICAL_PLAY 250
|
||||||
#define HORIZONTAL_SWIPE_MINIMUM_DISTANCE 300
|
#define HORIZONTAL_SWIPE_MINIMUM_DISTANCE 300
|
||||||
|
#define LISTING_START_Y 475
|
||||||
|
#define LISTING_END_Y 647
|
||||||
|
#define BUTTON_START_Y 672
|
||||||
|
#define BUTTON_END_Y 704
|
||||||
|
#define BACK_BUTTON_START_X 966
|
||||||
|
#define BACK_BUTTON_END_X 1048
|
||||||
|
#define LAUNCH_BUTTON_START_X 1092
|
||||||
|
#define LAUNCH_BUTTON_END_X 1200
|
||||||
|
|
||||||
#define distance(x1, y1, x2, y2) (int) sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
|
#define distance(x1, y1, x2, y2) (int) sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
|
||||||
|
|
||||||
struct touchInfo_s touchInfo;
|
struct touchInfo_s touchInfo;
|
||||||
|
|
||||||
void touchInit(void) {
|
void touchInit() {
|
||||||
touchInfo.gestureInProgress = false;
|
touchInfo.gestureInProgress = false;
|
||||||
touchInfo.isTap = true;
|
touchInfo.isTap = true;
|
||||||
touchInfo.initMenuXPos = 0;
|
touchInfo.initMenuXPos = 0;
|
||||||
touchInfo.initMenuIndex = 0;
|
touchInfo.initMenuIndex = 0;
|
||||||
touchInfo.lastSlideSpeed = 0;
|
|
||||||
hidInitializeTouchScreen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleTappingOnApp(menu_s* menu, int px) {
|
void handleTappingOnApp(menu_s* menu, int px) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
menuEntry_s *me = NULL;
|
menuEntry_s *me = NULL;
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList];
|
|
||||||
|
|
||||||
for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) {
|
for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) {
|
||||||
int entry_start_x = layoutobj->posStart[0] + i * layoutobj->posEnd[0];
|
int entry_start_x = 29 + i * (140 + 30);
|
||||||
|
|
||||||
int screen_width = 1280;
|
int screen_width = 1280;
|
||||||
if (entry_start_x >= (screen_width - menu->xPos))
|
if (entry_start_x >= (screen_width - menu->xPos))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (px >= (entry_start_x + menu->xPos) && px <= (entry_start_x + menu->xPos) + layoutobj->size[0]) {
|
if (px >= (entry_start_x + menu->xPos) && px <= (entry_start_x + menu->xPos) + 140 ) {
|
||||||
launchMenuEntryTask(me);
|
launchMenuEntryTask(me);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -48,97 +53,78 @@ void handleTappingOnOpenLaunch(menu_s* menu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool checkInsideTextLayoutObject(ThemeLayoutId id, int x, int y) {
|
|
||||||
ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[id];
|
|
||||||
if (!layoutobj->visible) return false;
|
|
||||||
|
|
||||||
return x > layoutobj->posFinal[0] && x < layoutobj->posFinal[0]+(layoutobj->touchSize[0] ? layoutobj->touchSize[0] : layoutobj->textSize[0]) && y > layoutobj->posFinal[1]-layoutobj->touchSize[1] && y < layoutobj->posFinal[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleTouch(menu_s* menu) {
|
void handleTouch(menu_s* menu) {
|
||||||
ThemeLayoutObject *layoutobj = NULL;
|
touchPosition currentTouch;
|
||||||
HidTouchScreenState touch = {0};
|
u32 touches = hidTouchCount();
|
||||||
hidGetTouchScreenStates(&touch, 1);
|
|
||||||
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles];
|
|
||||||
int entries_count = layoutobj->posEnd[0];
|
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList];
|
|
||||||
|
|
||||||
// On touch start.
|
// On touch start.
|
||||||
if (touch.count == 1 && !touchInfo.gestureInProgress) {
|
if (touches == 1 && !touchInfo.gestureInProgress) {
|
||||||
|
hidTouchRead(¤tTouch, 0);
|
||||||
|
|
||||||
touchInfo.gestureInProgress = true;
|
touchInfo.gestureInProgress = true;
|
||||||
touchInfo.firstTouch = touch.touches[0];
|
touchInfo.firstTouch = currentTouch;
|
||||||
touchInfo.prevTouch = touch.touches[0];
|
touchInfo.prevTouch = currentTouch;
|
||||||
touchInfo.isTap = true;
|
touchInfo.isTap = true;
|
||||||
touchInfo.initMenuXPos = menu->xPos;
|
touchInfo.initMenuXPos = menu->xPos;
|
||||||
touchInfo.initMenuIndex = menu->curEntry;
|
touchInfo.initMenuIndex = menu->curEntry;
|
||||||
touchInfo.lastSlideSpeed = 0;
|
|
||||||
menu->slideSpeed = 0;
|
|
||||||
}
|
}
|
||||||
// On touch moving.
|
// On touch moving.
|
||||||
else if (touch.count >= 1 && touchInfo.gestureInProgress) {
|
else if (touches >= 1 && touchInfo.gestureInProgress) {
|
||||||
touchInfo.lastSlideSpeed = ((int)(touch.touches[0].x - touchInfo.prevTouch.x));
|
hidTouchRead(¤tTouch, 0);
|
||||||
|
|
||||||
touchInfo.prevTouch = touch.touches[0];
|
touchInfo.prevTouch = currentTouch;
|
||||||
|
|
||||||
if (touchInfo.isTap && (abs(touchInfo.firstTouch.x - touch.touches[0].x) > TAP_MOVEMENT_GAP || abs(touchInfo.firstTouch.y - touch.touches[0].y) > TAP_MOVEMENT_GAP)) {
|
if (touchInfo.isTap && (abs(touchInfo.firstTouch.px - currentTouch.px) > TAP_MOVEMENT_GAP || abs(touchInfo.firstTouch.py - currentTouch.py) > TAP_MOVEMENT_GAP)) {
|
||||||
touchInfo.isTap = false;
|
touchInfo.isTap = false;
|
||||||
}
|
}
|
||||||
if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.y > layoutobj->posStart[1] && touchInfo.firstTouch.y < layoutobj->posStart[1]+layoutobj->size[1] && !touchInfo.isTap && menu->nEntries > entries_count) {
|
if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.py > LISTING_START_Y && touchInfo.firstTouch.py < LISTING_END_Y && !touchInfo.isTap && menu->nEntries > 7) {
|
||||||
|
menu->xPos = touchInfo.initMenuXPos + (currentTouch.px - touchInfo.firstTouch.px);
|
||||||
|
menu->curEntry = touchInfo.initMenuIndex + ((int) (touchInfo.firstTouch.px - currentTouch.px) / 170);
|
||||||
|
|
||||||
if (!touchInfo.isTap) {
|
if (menu->curEntry < 0)
|
||||||
menu->slideSpeed = touchInfo.lastSlideSpeed;
|
menu->curEntry = 0;
|
||||||
}
|
|
||||||
|
if (menu->curEntry >= menu->nEntries - 6)
|
||||||
|
menu->curEntry = menu->nEntries - 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// On touch end.
|
// On touch end.
|
||||||
else if (touchInfo.gestureInProgress) {
|
else if (touchInfo.gestureInProgress) {
|
||||||
int x1 = touchInfo.firstTouch.x;
|
int x1 = touchInfo.firstTouch.px;
|
||||||
int y1 = touchInfo.firstTouch.y;
|
int y1 = touchInfo.firstTouch.py;
|
||||||
int x2 = touchInfo.prevTouch.x;
|
int x2 = touchInfo.prevTouch.px;
|
||||||
int y2 = touchInfo.prevTouch.y;
|
int y2 = touchInfo.prevTouch.py;
|
||||||
|
|
||||||
if (!touchInfo.isTap) {
|
|
||||||
menu->slideSpeed = touchInfo.lastSlideSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool netloader_active = menuIsNetloaderActive();
|
bool netloader_active = menuIsNetloaderActive();
|
||||||
|
|
||||||
if (menuIsMsgBoxOpen() && !netloader_active) {
|
if (menuIsMsgBoxOpen() && !netloader_active) {
|
||||||
layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator];
|
|
||||||
MessageBox currMsgBox = menuGetCurrentMsgBox();
|
MessageBox currMsgBox = menuGetCurrentMsgBox();
|
||||||
int start_x = 1280 / 2 - currMsgBox.width / 2;
|
int start_x = 1280 / 2 - currMsgBox.width / 2;
|
||||||
int start_y = (720 / 2 - currMsgBox.height / 2) + currMsgBox.height;
|
int start_y = (720 / 2 - currMsgBox.height / 2) + (currMsgBox.height - 80);
|
||||||
int end_x = start_x + currMsgBox.width;
|
int end_x = start_x + currMsgBox.width;
|
||||||
int end_y = start_y;
|
int end_y = start_y + 80;
|
||||||
start_y+= layoutobj->posStart[1];
|
|
||||||
|
|
||||||
if (x1 > start_x && x1 < end_x && y1 > start_y && y1 < end_y && touchInfo.isTap) {
|
if (x1 > start_x && x1 < end_x && y1 > start_y && y1 < end_y && touchInfo.isTap) {
|
||||||
menuCloseMsgBox();
|
menuCloseMsgBox();
|
||||||
}
|
}
|
||||||
} else if (touchInfo.isTap && !netloader_active) {
|
} else if (touchInfo.isTap && !netloader_active) {
|
||||||
// App Icons
|
// App Icons
|
||||||
if (y1 > layoutobj->posStart[1] && y1 < layoutobj->posStart[1]+layoutobj->size[1]) {
|
if (y1 > LISTING_START_Y && y1 < LISTING_END_Y) {
|
||||||
handleTappingOnApp(menu, touchInfo.prevTouch.x);
|
handleTappingOnApp(menu, touchInfo.prevTouch.px);
|
||||||
}
|
}
|
||||||
// Bottom Buttons
|
// Bottom Buttons
|
||||||
else {
|
else if (y1 > BUTTON_START_Y && y1 < BUTTON_END_Y) {
|
||||||
// Back Button
|
// Back Button for non-empty directory
|
||||||
if (checkInsideTextLayoutObject(ThemeLayoutId_ButtonB, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonBText, x1, y1)) {
|
if (menu->nEntries != 0 && x1 > BACK_BUTTON_START_X && x1 < BACK_BUTTON_END_X) {
|
||||||
launchMenuBackTask();
|
launchMenuBackTask();
|
||||||
}
|
}
|
||||||
// Open/Launch Button
|
// Open/Launch Button / Back Button for empty directories
|
||||||
else if (menu->nEntries != 0 && (checkInsideTextLayoutObject(ThemeLayoutId_ButtonA, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonAText, x1, y1))) {
|
else if (x1 > LAUNCH_BUTTON_START_X && x1 < LAUNCH_BUTTON_END_X) {
|
||||||
|
if (menu->nEntries == 0) {
|
||||||
|
launchMenuBackTask();
|
||||||
|
} else {
|
||||||
handleTappingOnOpenLaunch(menu);
|
handleTappingOnOpenLaunch(menu);
|
||||||
}
|
}
|
||||||
// Star Button
|
|
||||||
else if (menu->nEntries != 0) {
|
|
||||||
int i;
|
|
||||||
menuEntry_s* me;
|
|
||||||
for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next);
|
|
||||||
if (me->type != ENTRY_TYPE_THEME && (checkInsideTextLayoutObject(ThemeLayoutId_ButtonX, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonXText, x1, y1))) {
|
|
||||||
menuHandleXButton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,14 +140,12 @@ void handleTouch(menu_s* menu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Horizontal Swipe
|
// Horizontal Swipe
|
||||||
else if (y1 < layoutobj->posStart[1] && y2 < layoutobj->posStart[1]) {
|
else if (abs(y1 - y2) < HORIZONTAL_SWIPE_VERTICAL_PLAY && distance(x1, y1, x2, y2) > HORIZONTAL_SWIPE_MINIMUM_DISTANCE) {
|
||||||
if (abs(y1 - y2) < HORIZONTAL_SWIPE_VERTICAL_PLAY && distance(x1, y1, x2, y2) > HORIZONTAL_SWIPE_MINIMUM_DISTANCE) {
|
|
||||||
// Swipe left to go into theme-menu
|
// Swipe left to go into theme-menu
|
||||||
if (x1 - x2 > 0) {
|
if (x1 - x2 > 0) {
|
||||||
themeMenuStartup();
|
themeMenuStartup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
touchInfo.gestureInProgress = false;
|
touchInfo.gestureInProgress = false;
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,11 @@
|
|||||||
|
|
||||||
struct touchInfo_s {
|
struct touchInfo_s {
|
||||||
bool gestureInProgress;
|
bool gestureInProgress;
|
||||||
HidTouchState firstTouch;
|
touchPosition firstTouch;
|
||||||
HidTouchState prevTouch;
|
touchPosition prevTouch;
|
||||||
bool isTap;
|
bool isTap;
|
||||||
int initMenuXPos;
|
int initMenuXPos;
|
||||||
int initMenuIndex;
|
int initMenuIndex;
|
||||||
int lastSlideSpeed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void touchInit(void);
|
|
||||||
void handleTouch(menu_s* menu);
|
void handleTouch(menu_s* menu);
|
@ -1,7 +1,6 @@
|
|||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@ -11,20 +10,18 @@ extern "C" {
|
|||||||
|
|
||||||
color_t pixels[720][1280];
|
color_t pixels[720][1280];
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main()
|
||||||
{
|
{
|
||||||
sf::RenderWindow window(sf::VideoMode(1280, 720), "Test");
|
sf::RenderWindow window(sf::VideoMode(1280, 720), "Test");
|
||||||
window.setFramerateLimit(60);
|
window.setFramerateLimit(60);
|
||||||
|
|
||||||
menuStartupPath();
|
menuStartupPath();
|
||||||
PHYSFS_init(argv[0]);
|
|
||||||
assetsInit();
|
assetsInit();
|
||||||
themeStartup(THEME_PRESET_LIGHT);
|
themeStartup(THEME_PRESET_LIGHT);
|
||||||
textInit();
|
textInit();
|
||||||
fontInitialize();
|
fontInitialize();
|
||||||
netloaderInit();
|
netloaderInit();
|
||||||
workerInit();
|
workerInit();
|
||||||
statusInit();
|
|
||||||
menuStartup();
|
menuStartup();
|
||||||
|
|
||||||
while (window.isOpen())
|
while (window.isOpen())
|
||||||
@ -59,12 +56,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
netloaderSignalExit();
|
netloaderSignalExit();
|
||||||
statusExit();
|
|
||||||
workerExit();
|
workerExit();
|
||||||
netloaderExit();
|
netloaderExit();
|
||||||
fontExit();
|
fontExit();
|
||||||
assetsExit();
|
assetsExit();
|
||||||
PHYSFS_deinit();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -77,8 +72,6 @@ extern "C" bool menuUpdate(void) {
|
|||||||
int new_esc_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Escape);
|
int new_esc_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Escape);
|
||||||
static int return_state = 0;
|
static int return_state = 0;
|
||||||
int new_return_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Return);
|
int new_return_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Return);
|
||||||
static int x_state = 0;
|
|
||||||
int new_x_state = sf::Keyboard::isKeyPressed(sf::Keyboard::X);
|
|
||||||
static int y_state = 0;
|
static int y_state = 0;
|
||||||
int new_y_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Y);
|
int new_y_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Y);
|
||||||
static int t_state = 0;
|
static int t_state = 0;
|
||||||
@ -87,11 +80,7 @@ extern "C" bool menuUpdate(void) {
|
|||||||
if(!new_y_state && y_state)
|
if(!new_y_state && y_state)
|
||||||
{
|
{
|
||||||
launchMenuNetloaderTask();
|
launchMenuNetloaderTask();
|
||||||
}
|
|
||||||
|
|
||||||
if(!new_x_state && x_state)
|
|
||||||
{
|
|
||||||
menuHandleXButton();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_esc_state && esc_state)
|
if (!new_esc_state && esc_state)
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
bool netstatusGetDetails(AssetId *id) {
|
|
||||||
*id = AssetId_wifi3_icon;
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
bool thermalstatusInit(void) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void thermalstatusExit(void) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool thermalstatusGetDetails(s32 *temperature) {
|
|
||||||
*temperature = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 188 B |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 405 B |
Before Width: | Height: | Size: 481 B |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.5 KiB |