diff --git a/Makefile b/Makefile index 437c14c..5a8662d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -export APP_VERSION := 3.0.1 +export APP_VERSION := 3.1.0 ifeq ($(RELEASE),) export APP_VERSION := $(APP_VERSION)-$(shell git describe --dirty --always) @@ -8,18 +8,20 @@ endif all: nx pc -romfs : assets +romfs: @mkdir -p romfs + +romfs/assets.zip : romfs assets @rm -f romfs/assets.zip @zip -rj romfs/assets.zip assets -dist-bin: romfs +dist-bin: romfs/assets.zip $(MAKE) -f Makefile.nx dist-bin -nx: romfs +nx: romfs/assets.zip $(MAKE) -f Makefile.nx -pc: romfs +pc: romfs/assets.zip $(MAKE) -f Makefile.pc clean: diff --git a/Makefile.nx b/Makefile.nx index 59f3955..beb7691 100644 --- a/Makefile.nx +++ b/Makefile.nx @@ -15,7 +15,6 @@ include $(DEVKITPRO)/libnx/switch_rules # SOURCES is a list of directories containing source code # DATA is a list of directories containing data 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) # # NO_ICON: if set to anything, do not use icon. @@ -29,13 +28,20 @@ include $(DEVKITPRO)/libnx/switch_rules # - .jpg # - icon.jpg # - /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): +# - .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)) BUILD := build SOURCES := common/ nx_main/ nx_main/loaders/ DATA := data INCLUDES := include -EXEFS_SRC := exefs_src ROMFS := romfs DIST_PATH := $(TARGET)_v$(APP_VERSION) @@ -109,7 +115,18 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) +ifeq ($(strip $(CONFIG_JSON)),) + 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)),) icons := $(wildcard *.jpg) @@ -152,7 +169,11 @@ $(BUILD): #--------------------------------------------------------------------------------- clean: @echo clean ... - @rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf +ifeq ($(strip $(APP_JSON)),) + @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 @@ -169,11 +190,9 @@ DEPENDS := $(OFILES:.o=.d) #--------------------------------------------------------------------------------- # main targets #--------------------------------------------------------------------------------- -all : $(OUTPUT).pfs0 $(OUTPUT).nro +ifeq ($(strip $(APP_JSON)),) -$(OUTPUT).pfs0 : $(OUTPUT).nso - -$(OUTPUT).nso : $(OUTPUT).elf +all : $(OUTPUT).nro ifeq ($(strip $(NO_NACP)),) $(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp @@ -181,6 +200,16 @@ else $(OUTPUT).nro : $(OUTPUT).elf endif +else + +all : $(OUTPUT).nsp + +$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm + +$(OUTPUT).nso : $(OUTPUT).elf + +endif + $(OUTPUT).elf : $(OFILES) $(OFILES_SRC) : $(HFILES_BIN) @@ -188,12 +217,7 @@ $(OFILES_SRC) : $(HFILES_BIN) #--------------------------------------------------------------------------------- # you need a rule like this for each extension you use as binary data #--------------------------------------------------------------------------------- -%.bin.o %_bin.h: %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -%.nxfnt.o : %.nxfnt +%.bin.o %_bin.h : %.bin #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) diff --git a/Makefile.pc b/Makefile.pc index dd65b1f..e15c645 100644 --- a/Makefile.pc +++ b/Makefile.pc @@ -9,8 +9,8 @@ EXTRA_CFLAGS="-D__USE_MINGW_ANSI_STDIO" EXTRA_LDFLAGS="-lws2_32" endif -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 \ +test : pc_main/main.cpp pc_main/pc_launch.c pc_main/pc_power.c pc_main/pc_netstatus.c \ + common/menu.c common/font.c common/language.c common/launch.c common/worker.c common/status.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/netloader.c diff --git a/assets/airplane_icon.bin b/assets/airplane_icon.bin new file mode 100644 index 0000000..6ec4682 Binary files /dev/null and b/assets/airplane_icon.bin differ diff --git a/assets/battery_icon.bin b/assets/battery_icon.bin index 75936fa..99bfdc8 100644 Binary files a/assets/battery_icon.bin and b/assets/battery_icon.bin differ diff --git a/assets/charging_icon.bin b/assets/charging_icon.bin index 634fb12..b0ccb8a 100644 Binary files a/assets/charging_icon.bin and b/assets/charging_icon.bin differ diff --git a/assets/eth_icon.bin b/assets/eth_icon.bin new file mode 100644 index 0000000..effa46a Binary files /dev/null and b/assets/eth_icon.bin differ diff --git a/assets/eth_none_icon.bin b/assets/eth_none_icon.bin new file mode 100644 index 0000000..e06357b Binary files /dev/null and b/assets/eth_none_icon.bin differ diff --git a/assets/wifi1_icon.bin b/assets/wifi1_icon.bin new file mode 100644 index 0000000..03f842f Binary files /dev/null and b/assets/wifi1_icon.bin differ diff --git a/assets/wifi2_icon.bin b/assets/wifi2_icon.bin new file mode 100644 index 0000000..7480e6e Binary files /dev/null and b/assets/wifi2_icon.bin differ diff --git a/assets/wifi3_icon.bin b/assets/wifi3_icon.bin new file mode 100644 index 0000000..a6df67c Binary files /dev/null and b/assets/wifi3_icon.bin differ diff --git a/assets/wifi_none_icon.bin b/assets/wifi_none_icon.bin new file mode 100644 index 0000000..696bf6f Binary files /dev/null and b/assets/wifi_none_icon.bin differ diff --git a/common/assets.c b/common/assets.c index c7c3a06..e3cc541 100644 --- a/common/assets.c +++ b/common/assets.c @@ -20,6 +20,13 @@ assetsDataEntry g_assetsDataList[AssetId_Max] = { GENASSET("hbmenu_logo_light.bin"), GENASSET("theme_icon_dark.bin"), GENASSET("theme_icon_light.bin"), + GENASSET("airplane_icon.bin"), + GENASSET("wifi_none_icon.bin"), + GENASSET("wifi1_icon.bin"), + GENASSET("wifi2_icon.bin"), + GENASSET("wifi3_icon.bin"), + GENASSET("eth_icon.bin"), + GENASSET("eth_none_icon.bin"), }; static void assetsClearEntry(assetsDataEntry *entry) { diff --git a/common/assets.h b/common/assets.h index 797f957..6eb23e2 100644 --- a/common/assets.h +++ b/common/assets.h @@ -10,6 +10,13 @@ typedef enum { AssetId_hbmenu_logo_light, AssetId_theme_icon_dark, 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_Max } AssetId; diff --git a/common/common.h b/common/common.h index 37ad0e4..b59f77f 100644 --- a/common/common.h +++ b/common/common.h @@ -64,6 +64,8 @@ typedef union { #include "message-box.h" #include "power.h" #include "netloader.h" +#include "netstatus.h" +#include "status.h" void menuStartupPath(void); void menuStartup(void); diff --git a/common/font.c b/common/font.c index 43fd442..2acdf7d 100644 --- a/common/font.c +++ b/common/font.c @@ -44,6 +44,10 @@ static bool FontSetType(u32 font) scale = 8; break; + case largestar: + scale = 18; + break; + default: return false; break; @@ -309,8 +313,8 @@ void GetTextDimensions(u32 font, const char* text, uint32_t* width_out, uint32_t width = x; } - *width_out = width; - *height_out = height; + if(width_out) *width_out = width; + if(height_out) *height_out = height; } bool fontInitialize(void) @@ -376,11 +380,11 @@ void fontExit() if (s_font_libret==0) FT_Done_FreeType(s_font_library); } -/*Automatically gives you the desired x-coordinate +/*Automatically gives you the desired x-coordinate *based on the string length and desired alignment *rY=reference point... where to align around *align='t','b','c' translates to (top,bottom,center) - *'t' aligned, top of text aligns with rY, + *'t' aligned, top of text aligns with rY, *you get the rest.... */ uint32_t GetTextYCoordinate(u32 font, uint32_t rY, const char* text, const char align) { @@ -401,7 +405,7 @@ uint32_t GetTextYCoordinate(u32 font, uint32_t rY, const char* text, const char } } -/*Automatically gives you the desired x-coordinate +/*Automatically gives you the desired x-coordinate *based on the string length and desired alignment *rX=reference point... where to align around *text=string you want to display diff --git a/common/font.h b/common/font.h index 45ed8fe..fb9d300 100644 --- a/common/font.h +++ b/common/font.h @@ -43,3 +43,4 @@ extern const ffnt_header_t interuiregular18_nxfnt;*/ #define interuiregular14 0//&interuiregular14_nxfnt #define interuiregular18 1//&interuiregular18_nxfnt #define fontscale7 4 +#define largestar 5 diff --git a/common/language.c b/common/language.c index e634e02..9d4de14 100644 --- a/common/language.c +++ b/common/language.c @@ -1,4 +1,4 @@ -#include "language.h" +#include "language.h" #ifdef __SWITCH__ #define STR_JP(_str) [SetLanguage_JA] = _str @@ -46,6 +46,12 @@ const char* const g_strings[StrId_Max][16] = STR_TW("加載中…"), }, + [StrId_AppletMode] = + { + STR_EN("● Applet Mode ●"), + STR_ES("● Modo Applet ●"), + }, + [StrId_Directory] = { STR_EN("Directory"), @@ -292,7 +298,7 @@ const char* const g_strings[StrId_Max][16] = STR_ZH("打开"), STR_TW("開啟"), }, - + [StrId_Actions_Back] = { STR_EN("Back"), @@ -331,6 +337,18 @@ const char* const g_strings[StrId_Max][16] = STR_TW("应用"), }, + [StrId_Actions_Star] = + { + STR_EN("Star"), + STR_ES("Agregar a favoritos"), + }, + + [StrId_Actions_Unstar] = + { + STR_EN("Unstar"), + STR_ES("Borrar de favoritos"), + }, + [StrId_ThemeMenu] = { STR_EN("Theme Menu"), diff --git a/common/language.h b/common/language.h index d76839c..95bbcd8 100644 --- a/common/language.h +++ b/common/language.h @@ -6,6 +6,7 @@ typedef enum { StrId_Loading = 0, + StrId_AppletMode, StrId_Directory, StrId_DefaultPublisher, StrId_IOError, @@ -23,6 +24,8 @@ typedef enum StrId_Actions_Open, StrId_Actions_Back, StrId_Actions_Apply, + StrId_Actions_Star, + StrId_Actions_Unstar, StrId_MsgBox_OK, diff --git a/common/menu-entry.c b/common/menu-entry.c index ab34d3a..250c3da 100644 --- a/common/menu-entry.c +++ b/common/menu-entry.c @@ -168,6 +168,26 @@ static bool menuEntryLoadEmbeddedNacp(menuEntry_s* me) { 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) { char *outp = buf, *inp = buf; char lastc = 0; @@ -438,11 +458,23 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) { if (!iconLoaded && fileassoc_me->icon_gfx && fileassoc_me->icon_gfx_small) iconLoaded = menuEntryImportIconGfx(me, fileassoc_me->icon_gfx, fileassoc_me->icon_gfx_small); - strncpy(me->author, fileassoc_me->author, sizeof(me->author)); - me->author[sizeof(me->author)-1] = 0; + //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)); - strncpy(me->version, fileassoc_me->version, sizeof(me->version)); - me->version[sizeof(me->version)-1] = 0; + bool nacpLoaded = menuEntryLoadExternalNacp(me, tempbuf); + + if (nacpLoaded) menuEntryParseNacp(me); + else { + strncpy(me->author, fileassoc_me->author, sizeof(me->author)); + me->author[sizeof(me->author)-1] = 0; + + strncpy(me->version, fileassoc_me->version, sizeof(me->version)); + me->version[sizeof(me->version)-1] = 0; + } // Initialize the argument data argData_s* ad = &me->args; @@ -458,6 +490,13 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) { 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; } diff --git a/common/menu-list.c b/common/menu-list.c index d693f54..61227bc 100644 --- a/common/menu-list.c +++ b/common/menu-list.c @@ -96,20 +96,34 @@ static void menuSort(void) { menu_s* m = &s_menu[!s_curMenu]; int nEntries = m->nEntries; if (nEntries==0) return; + int nEntriesStar = 0, nEntriesNoStar = 0; menuEntry_s** list = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*)); 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; for(i = 0; i < nEntries; ++i) { - list[i] = p; + if (p->starred) + listStar[nEntriesStar++] = p; + else + list[nEntriesNoStar++] = p; p = p->next; } - qsort(list, nEntries, sizeof(menuEntry_s*), menuEntryCmp); + qsort(listStar, nEntriesStar, sizeof(menuEntry_s*), menuEntryCmp); + qsort(list, nEntriesNoStar, sizeof(menuEntry_s*), menuEntryCmp); menuEntry_s** pp = &m->firstEntry; - for(i = 0; i < nEntries; ++i) { + for(i = 0; i < nEntriesStar; ++i) { + *pp = listStar[i]; + pp = &(*pp)->next; + } + for(i = 0; i < nEntriesNoStar; ++i) { *pp = list[i]; pp = &(*pp)->next; } @@ -117,6 +131,14 @@ static void menuSort(void) { *pp = NULL; free(list); + free(listStar); +} + +void menuReorder (void) { + s_curMenu = !s_curMenu; + menuSort(); + s_curMenu = !s_curMenu; + menuClear(); } int menuScan(const char* target) { diff --git a/common/menu.c b/common/menu.c index 3a2dc90..b0f7d96 100644 --- a/common/menu.c +++ b/common/menu.c @@ -29,6 +29,35 @@ void launchMenuEntryTask(menuEntry_s* arg) { 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 { HBMENU_DEFAULT, @@ -73,11 +102,23 @@ 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 launchApplyThemeTask(menuEntry_s* arg) { const char* themePath = arg->path; SetThemePathToConfig(themePath); themeStartup(themeGlobalPreset); - computeFrontGradient(themeCurrent.frontWaveColor, 280); + computeFrontGradient(themeCurrent.frontWaveColor, 280); } bool menuIsNetloaderActive(void) { @@ -138,6 +179,7 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) { const uint8_t *smallimg = NULL; const uint8_t *largeimg = NULL; + char *strptr = NULL; char tmpstr[1024]; int border_start_x, border_end_x; @@ -249,9 +291,9 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) { } if (is_active && largeimg) { - drawImage(117, 100, 256, 256, largeimg, IMAGE_MODE_RGB24); + drawImage(117, 100+10, 256, 256, largeimg, IMAGE_MODE_RGB24); - shadow_start_y = 100+256; + shadow_start_y = 100+10+256; border_start_x = 117; border_end_x = 117+256; @@ -267,13 +309,21 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) { } } - DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, themeCurrent.borderTextColor, me->name, 140 - 32, "..."); + if (me->type != ENTRY_TYPE_THEME) + strptr = me->starred ? themeCurrent.labelStarOnText : ""; + else + strptr = ""; + + memset(tmpstr, 0, sizeof(tmpstr)); + snprintf(tmpstr, sizeof(tmpstr)-1, "%s%s", strptr, me->name); + + DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, themeCurrent.borderTextColor, tmpstr, 140 - 32, "..."); if (is_active) { start_x = 1280 - 790; - start_y = 135; + start_y = 135+10; - DrawTextTruncate(interuimedium30, start_x, start_y + 39, themeCurrent.textColor, me->name, 1280 - start_x - 120 ,"..."); + DrawTextTruncate(interuimedium30, start_x, start_y + 39, themeCurrent.textColor, tmpstr, 1280 - start_x - 120 ,"..."); if (me->type != ENTRY_TYPE_FOLDER) { memset(tmpstr, 0, sizeof(tmpstr)); @@ -414,7 +464,39 @@ void drawWave(int id, float timer, color_t color, int height, float phase, float } } -void drawTime() { +void drawCharge() { + char chargeString[5]; + uint32_t batteryCharge; + bool isCharging; + bool validPower; + + validPower = powerGetDetails(&batteryCharge, &isCharging); + + if (validPower) + { + batteryCharge = (batteryCharge > 100) ? 100 : batteryCharge; + + sprintf(chargeString, "%d%%", batteryCharge); + + int tmpX = GetTextXCoordinate(interuiregular14, 1180 - 10, chargeString, 'r'); + + DrawText(interuiregular14, tmpX - 24 - 8, 0 + 47 + 10 + 21 + 4, themeCurrent.textColor, chargeString); + drawIcon(1180 - 8 - 24 - 8, 0 + 47 + 10 + 6, 24, 24, assetsGetDataBuffer(AssetId_battery_icon), themeCurrent.textColor); + if (isCharging) + drawIcon(1180 - 20, 0 + 47 + 10 + 6, 24, 24, assetsGetDataBuffer(AssetId_charging_icon), themeCurrent.textColor); + } +} + +void drawNetwork(int tmpX) { + bool netstatusFlag=0; + AssetId id; + if (statusGet(&netstatusFlag, &id)) { + if (netstatusFlag) + drawIcon(tmpX, 0 + 47 + 10 + 3, 24, 24, assetsGetDataBuffer(id), themeCurrent.textColor); + } +} + +u32 drawStatus() { char timeString[9]; @@ -427,33 +509,14 @@ void drawTime() { sprintf(timeString, "%02d:%02d:%02d", hours, minutes, seconds); - int tmpX = GetTextXCoordinate(interuimedium20, 1180, timeString, 'r'); + u32 tmpX = GetTextXCoordinate(interuimedium20, 1180, timeString, 'r'); DrawText(interuimedium20, tmpX, 0 + 47 + 10, themeCurrent.textColor, timeString); -} + drawCharge(); + drawNetwork(tmpX); -void drawCharge() { - char chargeString[5]; - uint32_t batteryCharge; - bool isCharging; - bool validPower; - - validPower = powerGetDetails(&batteryCharge, &isCharging); - - if (validPower) - { - batteryCharge = (batteryCharge > 100) ? 100 : batteryCharge; - - sprintf(chargeString, "%d%%", batteryCharge); - - int tmpX = GetTextXCoordinate(interuiregular14, 1180, chargeString, 'r'); - - DrawText(interuiregular14, tmpX - 15, 0 + 47 + 10 + 21, themeCurrent.textColor, chargeString); - drawIcon(1180 - 11, 0 + 47 + 10 + 6, 10, 15, assetsGetDataBuffer(AssetId_battery_icon), themeCurrent.textColor); - if (isCharging) - drawIcon(tmpX - 32, 0 + 47 + 10 + 6, 9, 15, assetsGetDataBuffer(AssetId_charging_icon), themeCurrent.textColor); - } + return tmpX; } void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) { @@ -472,8 +535,8 @@ void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) { #endif { //drawImage(x_image, 720 - 48, 32, 32, themeCurrent.buttonBImage, IMAGE_MODE_RGBA32); - DrawText(fontscale7, x_image, 720 - 47 + 26, themeCurrent.textColor, themeCurrent.buttonBText);//Display the 'B' button from SharedFont. - DrawText(interuimedium20, x_text, 720 - 47 + 26, themeCurrent.textColor, textGetString(StrId_Actions_Back)); + DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonBText);//Display the 'B' button from SharedFont. + DrawText(interuiregular18, x_text, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Back)); } if(hbmenu_state == HBMENU_DEFAULT) @@ -482,15 +545,15 @@ void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) { x_image = x_text - 36; *x_image_out = x_image - 40; - DrawText(fontscale7, x_image, 720 - 47 + 26, themeCurrent.textColor, themeCurrent.buttonYText); - DrawText(interuiregular18, x_text, 720 - 47 + 26, themeCurrent.textColor, textGetString(StrId_NetLoader)); + DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonYText); + DrawText(interuiregular18, x_text, 720 - 47 + 24, 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)); + DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonMText); + DrawText(interuiregular18, x_text, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); } } @@ -542,7 +605,30 @@ void menuLoop(void) { menuTimer += 0.05; drawImage(40, 20, 140, 60, themeCurrent.hbmenuLogoImage, IMAGE_MODE_RGBA32); - DrawText(interuiregular14, 180, 46 + 18, themeCurrent.textColor, VERSION); + DrawText(interuiregular14, 184, 46 + 18, themeCurrent.textColor, VERSION); + u32 statusXPos = drawStatus(); + + #ifdef __SWITCH__ + AppletType at = appletGetAppletType(); + if (at != AppletType_Application && at != AppletType_SystemApplication) { + const char* appletMode = textGetString(StrId_AppletMode); + u32 x_pos = GetTextXCoordinate(interuimedium30, statusXPos, appletMode, 'r'); + DrawText(interuimedium30, x_pos - 32, 46 + 18, themeCurrent.attentionTextColor, appletMode); + } + const char* loaderInfo = envGetLoaderInfo(); + if (loaderInfo) { + u32 x_pos = 43; + 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(interuiregular14, 184, tempbuf, 'r'); + } + DrawText(interuiregular14, x_pos, 46 + 18 + 20, themeCurrent.textColor, loaderInfo); + } + #endif #ifdef PERF_LOG_DRAW//Seperate from the PERF_LOG define since this might affect perf. extern u64 g_tickdiff_frame; @@ -553,9 +639,6 @@ void menuLoop(void) { DrawText(interuiregular14, 180 + 256, 46 + 16 + 18, themeCurrent.textColor, tmpstr); #endif - drawTime(); - drawCharge(); - memset(&netloader_state, 0, sizeof(netloader_state)); netloaderGetState(&netloader_state); @@ -614,6 +697,7 @@ void menuLoop(void) { // Draw menu entries for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) { int entry_start_x = 29 + i * (140 + 30); + int entry_draw_x = entry_start_x + menu->xPos; int screen_width = 1280; if (entry_start_x >= (screen_width - menu->xPos)) @@ -624,18 +708,21 @@ void menuLoop(void) { if (is_active) active_entry = me; - drawEntry(me, entry_start_x + menu->xPos, is_active); + if (!is_active && entry_draw_x < -(29 + 140 + 30)) + continue; + + drawEntry(me, entry_draw_x, is_active); } int getX = GetTextXCoordinate(interuiregular18, 1180, textGetString(StrId_ThemeMenu), 'r'); if(hbmenu_state == HBMENU_THEME_MENU) { - DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); + DrawText(interuiregular18, getX, 30 + 26 + 32 + 20, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); } else { //DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); //DrawText(fontscale7, getX - 40, 30 + 26 + 32 + 10, themeCurrent.textColor, themeCurrent.buttonMText); } - + if(active_entry != NULL) { if (active_entry->type == ENTRY_TYPE_THEME) { DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText); @@ -652,6 +739,20 @@ void menuLoop(void) { } drawButtons(menu, false, &menupath_x_endpos); + + if (active_entry && active_entry->type != ENTRY_TYPE_THEME) { + if (active_entry->starred) { + getX = GetTextXCoordinate(interuiregular18, menupath_x_endpos + 8, textGetString(StrId_Actions_Unstar), 'r'); + DrawText(fontscale7, getX - 36, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonXText); + DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Unstar)); + } else { + getX = GetTextXCoordinate(interuiregular18, menupath_x_endpos + 8, textGetString(StrId_Actions_Star), 'r'); + DrawText(fontscale7, getX - 36, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonXText); + DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Star)); + } + menupath_x_endpos = getX - 36 - 40; + } + } DrawTextTruncate(interuiregular18, 40, 720 - 47 + 24, themeCurrent.textColor, menu->dirname, menupath_x_endpos - 40, "..."); diff --git a/common/menu.h b/common/menu.h index bd7894f..ff54a4f 100644 --- a/common/menu.h +++ b/common/menu.h @@ -51,6 +51,7 @@ struct menuEntry_s_tag MenuEntryType type; char path[PATH_MAX+8]; + char starpath[PATH_MAX+8]; argData_s args; bool fileassoc_type;//0=file_extension, 1 = filename @@ -64,6 +65,8 @@ struct menuEntry_s_tag size_t icon_size; uint8_t *icon_gfx; uint8_t *icon_gfx_small; + + bool starred; NacpStruct *nacp; }; @@ -97,11 +100,13 @@ void menuDeleteEntry(menuEntry_s* me, bool skip_icongfx); menu_s* menuGetCurrent(void); menu_s* menuFileassocGetCurrent(void); +void menuReorder (void); int menuScan(const char* target); int themeMenuScan(const char* target); int menuFileassocScan(const char* target); void launchMenuEntryTask(menuEntry_s* arg); +void toggleStarState(menuEntry_s* arg); void launchApplyThemeTask(menuEntry_s* arg); void launchMenuBackTask(); void launchMenuNetloaderTask(); @@ -109,6 +114,7 @@ char *menuGetRootPath(void); char *menuGetRootBasePath(void); void menuHandleAButton(void); +void menuHandleXButton(void); bool menuIsNetloaderActive(void); diff --git a/common/netloader.c b/common/netloader.c index dd3ad6a..471b03d 100644 --- a/common/netloader.c +++ b/common/netloader.c @@ -274,7 +274,7 @@ static int decompress(int sock, FILE *fh, size_t filesize) { int ret; unsigned have; z_stream strm; - size_t chunksize; + uint32_t chunksize=0; /* allocate inflate state */ strm.zalloc = Z_NULL; @@ -304,6 +304,12 @@ static int decompress(int sock, FILE *fh, size_t filesize) { 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); if (strm.avail_in == 0) { @@ -436,11 +442,18 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) { send(sock,(char *)&response,sizeof(response),0); + char *writebuffer = NULL; if (response == 0 ) { + writebuffer = malloc(FILE_BUFFER_SIZE); + if (writebuffer==NULL) { + netloader_error("Failed to allocate memory",ENOMEM); + response = -1; + } + else + setvbuf(file,writebuffer,_IOFBF, FILE_BUFFER_SIZE); + } - //char *writebuffer=malloc(FILE_BUFFER_SIZE); - //setvbuf(file,writebuffer,_IOFBF, FILE_BUFFER_SIZE); - + if (response == 0 ) { //printf("transferring %s\n%d bytes.\n", filename, filelen); if (decompress(sock,file,filelen)==Z_OK) { @@ -487,9 +500,9 @@ int loadnro(menuEntry_s *me, int sock, struct in_addr remote) { response = -1; } - //free(writebuffer); fflush(file); fclose(file); + free(writebuffer); if (response == -1) unlink(me->path); } diff --git a/common/netstatus.h b/common/netstatus.h new file mode 100644 index 0000000..ceebc2b --- /dev/null +++ b/common/netstatus.h @@ -0,0 +1,5 @@ +#pragma once +#include "common.h" + +bool netstatusGetDetails(AssetId *id); + diff --git a/common/status.c b/common/status.c new file mode 100644 index 0000000..b0f0d9e --- /dev/null +++ b/common/status.c @@ -0,0 +1,114 @@ +#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; + +// 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; + AssetId tmpid; + + clock_gettime(CLOCK_MONOTONIC, &timeout); + timeout.tv_sec++; + + for (;;) + { + cnd_timedwait(&s_statusCdn, &s_statusMtx, &timeout); + + if (s_statusExit) + break; + + tmpflag = netstatusGetDetails(&tmpid); + + mtx_lock(&s_statusAccessMtx); + + s_statusNetFlag = tmpflag; + s_statusNetAssetId = tmpid; + + s_statusReady = 1; + + mtx_unlock(&s_statusAccessMtx); + + clock_gettime(CLOCK_MONOTONIC, &timeout); + timeout.tv_sec++; + } + + mtx_unlock(&s_statusMtx); + + return 0; +} + +bool statusGet(bool *netstatusFlag, AssetId *netstatusAssetId) { + if (!s_statusReady) return 0; + + mtx_lock(&s_statusAccessMtx); + + *netstatusFlag = s_statusNetFlag; + *netstatusAssetId = s_statusNetAssetId; + + 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); +} + diff --git a/common/status.h b/common/status.h new file mode 100644 index 0000000..7e52eba --- /dev/null +++ b/common/status.h @@ -0,0 +1,7 @@ +#pragma once +#include "common.h" + +bool statusInit(void); +void statusExit(void); +bool statusGet(bool *netstatusFlag, AssetId *netstatusAssetId); + diff --git a/common/theme.c b/common/theme.c index c18853b..a67069f 100644 --- a/common/theme.c +++ b/common/theme.c @@ -12,8 +12,9 @@ bool colorFromSetting(config_setting_t *rgba, color_t *col) { void themeStartup(ThemePreset preset) { themeGlobalPreset = preset; - theme_t themeLight = (theme_t) { + theme_t themeLight = (theme_t) { .textColor = MakeColor(0, 0, 0, 255), + .attentionTextColor = MakeColor(255, 0, 0, 255), .frontWaveColor = MakeColor(100, 212, 250, 255), .middleWaveColor = MakeColor(100, 153, 255, 255), .backWaveColor = MakeColor(154, 171, 255, 255), @@ -26,14 +27,18 @@ void themeStartup(ThemePreset preset) { .enableWaveBlending = 0, .buttonAText = "\uE0E0", .buttonBText = "\uE0E1", + .buttonXText = "\uE0E2", .buttonYText = "\uE0E3", .buttonPText = "\uE0EF", .buttonMText = "\uE0F0", - .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_light) + .labelStarOnText = "\u2605", + .labelStarOffText = "\u2606", + .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_light), }; - - theme_t themeDark = (theme_t) { + + theme_t themeDark = (theme_t) { .textColor = MakeColor(255, 255, 255, 255), + .attentionTextColor = MakeColor(255, 0, 0, 255), .frontWaveColor = MakeColor(96, 204, 204, 255), .middleWaveColor = MakeColor(66, 154, 159, 255), .backWaveColor = MakeColor(73, 103, 169, 255), @@ -46,10 +51,13 @@ void themeStartup(ThemePreset preset) { .enableWaveBlending = 0, .buttonAText = "\uE0A0", .buttonBText = "\uE0A1", + .buttonXText = "\uE0A2", .buttonYText = "\uE0A3", .buttonPText = "\uE0B3", .buttonMText = "\uE0B4", - .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark) + .labelStarOnText = "\u2605", + .labelStarOffText = "\u2606", + .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark), }; char themePath[PATH_MAX] = {0}; @@ -59,9 +67,9 @@ void themeStartup(ThemePreset preset) { config_t cfg = {0}; config_init(&cfg); config_setting_t *theme = NULL; - color_t text, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor, progressBarColor; + color_t text, attentionText, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor, progressBarColor; int waveBlending; - const char *AText, *BText, *YText, *PText, *MText; + const char *AText, *BText, *XText, *YText, *PText, *MText, *starOnText, *starOffText; bool good_cfg = false; if(themePath[0]!=0) @@ -86,6 +94,8 @@ void themeStartup(ThemePreset preset) { if (theme != NULL) { if (!colorFromSetting(config_setting_lookup(theme, "textColor"), &text)) text = themeDefault->textColor; + if (!colorFromSetting(config_setting_lookup(theme, "attentionTextColor"), &attentionText)) + attentionText = themeDefault->attentionTextColor; if (!colorFromSetting(config_setting_lookup(theme, "frontWaveColor"), &frontWave)) frontWave = themeDefault->frontWaveColor; if (!colorFromSetting(config_setting_lookup(theme, "middleWaveColor"), &middleWave)) @@ -110,14 +120,21 @@ void themeStartup(ThemePreset preset) { AText = themeDefault->buttonAText; if (!config_setting_lookup_string(theme, "buttonBText", &BText)) BText = themeDefault->buttonBText; + if (!config_setting_lookup_string(theme, "buttonXText", &XText)) + XText = themeDefault->buttonXText; if (!config_setting_lookup_string(theme, "buttonYText", &YText)) YText = themeDefault->buttonYText; if (!config_setting_lookup_string(theme, "buttonPText", &PText)) PText = themeDefault->buttonPText; if (!config_setting_lookup_string(theme, "buttonMText", &MText)) MText = themeDefault->buttonMText; - themeCurrent = (theme_t) { + 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) { .textColor = text, + .attentionTextColor = attentionText, .frontWaveColor = frontWave, .middleWaveColor = middleWave, .backWaveColor = backWave, @@ -132,9 +149,12 @@ void themeStartup(ThemePreset preset) { }; strncpy(themeCurrent.buttonAText, AText, sizeof(themeCurrent.buttonAText)-1); strncpy(themeCurrent.buttonBText, BText, sizeof(themeCurrent.buttonBText)-1); + strncpy(themeCurrent.buttonXText, XText, sizeof(themeCurrent.buttonXText)-1); strncpy(themeCurrent.buttonYText, YText, sizeof(themeCurrent.buttonYText)-1); strncpy(themeCurrent.buttonPText, PText, sizeof(themeCurrent.buttonPText)-1); strncpy(themeCurrent.buttonMText, MText, sizeof(themeCurrent.buttonMText)-1); + strncpy(themeCurrent.labelStarOffText, starOffText, sizeof(themeCurrent.labelStarOffText)-1); + strncpy(themeCurrent.labelStarOnText, starOnText, sizeof(themeCurrent.labelStarOnText)-1); } else { themeCurrent = *themeDefault; } @@ -154,7 +174,7 @@ void GetThemePathFromConfig(char* themePath, size_t size) { snprintf(tmp_path, sizeof(tmp_path)-1, "%s/config/nx-hbmenu/settings.cfg", menuGetRootBasePath()); snprintf(tmp_path_theme, sizeof(tmp_path_theme)-1, "%s/config/nx-hbmenu/themes/", menuGetRootBasePath()); bool good_cfg = config_read_file(&cfg, tmp_path); - + if(good_cfg) { settings = config_lookup(&cfg, "settings"); if(settings != NULL) { @@ -172,7 +192,7 @@ void SetThemePathToConfig(const char* themePath) { char settingPath[PATH_MAX] = {0}; config_setting_t *root = NULL, - *group = NULL, + *group = NULL, *settings = NULL; themePath = getSlash(themePath); @@ -184,7 +204,7 @@ void SetThemePathToConfig(const char* themePath) { snprintf(settingPath, sizeof(settingPath)-1, "%s/config/nx-hbmenu/settings.cfg", menuGetRootBasePath()); bool good_cfg = config_read_file(&cfg, settingPath); - + if(good_cfg) { group = config_lookup(&cfg, "settings"); if(group != NULL) @@ -195,9 +215,9 @@ void SetThemePathToConfig(const char* themePath) { root = config_root_setting(&cfg); if(root != NULL) group = config_setting_add(root, "settings", CONFIG_TYPE_GROUP); - if(group != NULL) + if(group != NULL) settings = config_setting_add(group, "themePath", CONFIG_TYPE_STRING); - if(settings != NULL) + if(settings != NULL) config_setting_set_string(settings, themePath); } diff --git a/common/theme.h b/common/theme.h index 65ef7d4..2cc48b0 100644 --- a/common/theme.h +++ b/common/theme.h @@ -6,6 +6,7 @@ typedef struct { color_t textColor; + color_t attentionTextColor; color_t frontWaveColor; color_t middleWaveColor; color_t backWaveColor; @@ -18,9 +19,12 @@ typedef struct 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]; const uint8_t *hbmenuLogoImage; } theme_t; diff --git a/nx_main/main.c b/nx_main/main.c index cb2caf7..25f0950 100644 --- a/nx_main/main.c +++ b/nx_main/main.c @@ -42,7 +42,7 @@ int main(int argc, char **argv) memset(errormsg, 0, sizeof(errormsg)); appletLockExit(); - appletSetScreenShotPermission(1); + appletSetScreenShotPermission(AppletScreenShotPermission_Enable); ColorSetId theme; rc = setsysInitialize(); @@ -87,6 +87,11 @@ int main(int argc, char **argv) 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)) { @@ -175,6 +180,7 @@ int main(int argc, char **argv) fontExit(); launchExit(); netloaderSignalExit(); + statusExit(); workerExit(); netloaderExit(); powerExit(); @@ -198,6 +204,10 @@ bool menuUpdate(void) { { launchMenuNetloaderTask(); } + else if (down & KEY_X) + { + menuHandleXButton(); + } else if (down & KEY_A) { menuHandleAButton(); diff --git a/nx_main/nx_netstatus.c b/nx_main/nx_netstatus.c new file mode 100644 index 0000000..378e30f --- /dev/null +++ b/nx_main/nx_netstatus.c @@ -0,0 +1,36 @@ +#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; +} diff --git a/nx_main/nx_touch.c b/nx_main/nx_touch.c index 1584033..593997b 100644 --- a/nx_main/nx_touch.c +++ b/nx_main/nx_touch.c @@ -13,6 +13,11 @@ #define BACK_BUTTON_END_X 1048 #define LAUNCH_BUTTON_START_X 1092 #define LAUNCH_BUTTON_END_X 1200 +#define STAR_BUTTON_START_X 426 +#define STAR_BUTTON_END_X 490 +#define STAR_BUTTON_START_Y 100 +#define STAR_BUTTON_END_Y 161 + #define distance(x1, y1, x2, y2) (int) sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) @@ -127,6 +132,16 @@ void handleTouch(menu_s* menu) { } } } + // Star + else { + int i; + menuEntry_s* me; + for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next); + if (me->type != ENTRY_TYPE_THEME && x1 > STAR_BUTTON_START_X && x1 < STAR_BUTTON_END_X + && y1 > STAR_BUTTON_START_Y && y1 < STAR_BUTTON_END_Y) { + menuHandleXButton(); + } + } } // Vertical Swipe else if (abs(x1 - x2) < VERTICAL_SWIPE_HORIZONTAL_PLAY && distance(x1, y1, x2, y2) > VERTICAL_SWIPE_MINIMUM_DISTANCE) { diff --git a/pc_main/main.cpp b/pc_main/main.cpp index 0ddaa2f..e8adbe0 100644 --- a/pc_main/main.cpp +++ b/pc_main/main.cpp @@ -22,6 +22,7 @@ int main() fontInitialize(); netloaderInit(); workerInit(); + statusInit(); menuStartup(); while (window.isOpen()) @@ -56,6 +57,7 @@ int main() } netloaderSignalExit(); + statusExit(); workerExit(); netloaderExit(); fontExit(); @@ -72,6 +74,8 @@ extern "C" bool menuUpdate(void) { int new_esc_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Escape); static int return_state = 0; 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; int new_y_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Y); static int t_state = 0; @@ -80,7 +84,11 @@ extern "C" bool menuUpdate(void) { if(!new_y_state && y_state) { launchMenuNetloaderTask(); + } + if(!new_x_state && x_state) + { + menuHandleXButton(); } if (!new_esc_state && esc_state) diff --git a/pc_main/pc_netstatus.c b/pc_main/pc_netstatus.c new file mode 100644 index 0000000..dc4e1ab --- /dev/null +++ b/pc_main/pc_netstatus.c @@ -0,0 +1,6 @@ +#include "../common/common.h" + +bool netstatusGetDetails(AssetId *id) { + *id = AssetId_wifi3_icon; + return true; +} diff --git a/resources/airplane_icon.png b/resources/airplane_icon.png new file mode 100644 index 0000000..7808f33 Binary files /dev/null and b/resources/airplane_icon.png differ diff --git a/resources/battery_icon.png b/resources/battery_icon.png index 5c89f72..a0a53ff 100644 Binary files a/resources/battery_icon.png and b/resources/battery_icon.png differ diff --git a/resources/charging_icon.png b/resources/charging_icon.png index 2229590..88c47f2 100644 Binary files a/resources/charging_icon.png and b/resources/charging_icon.png differ diff --git a/resources/eth_icon.png b/resources/eth_icon.png new file mode 100644 index 0000000..82dc3fa Binary files /dev/null and b/resources/eth_icon.png differ diff --git a/resources/wifi1_icon.png b/resources/wifi1_icon.png new file mode 100644 index 0000000..f0fa3b5 Binary files /dev/null and b/resources/wifi1_icon.png differ diff --git a/resources/wifi2_icon.png b/resources/wifi2_icon.png new file mode 100644 index 0000000..e445672 Binary files /dev/null and b/resources/wifi2_icon.png differ diff --git a/resources/wifi3_icon.png b/resources/wifi3_icon.png new file mode 100644 index 0000000..52902be Binary files /dev/null and b/resources/wifi3_icon.png differ diff --git a/resources/wifi_none_icon.png b/resources/wifi_none_icon.png new file mode 100644 index 0000000..ee25978 Binary files /dev/null and b/resources/wifi_none_icon.png differ