diff --git a/Source/Horizon-OC-Monitor (deprecated)/.gitignore b/Source/Horizon-OC-Monitor (deprecated)/.gitignore deleted file mode 100644 index 3e35c18f..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ - -build/ - -*.ovl - -*.elf - -*.nacp - -*.nro diff --git a/Source/Horizon-OC-Monitor (deprecated)/Horizon-OC-Monitor.lst b/Source/Horizon-OC-Monitor (deprecated)/Horizon-OC-Monitor.lst deleted file mode 100644 index 1a834f7f..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/Horizon-OC-Monitor.lst +++ /dev/null @@ -1,2 +0,0 @@ --CSn -/home/sould/Documents/GitHub/Horizon-OC/Source/Horizon-OC-Monitor/Horizon-OC-Monitor.elf diff --git a/Source/Horizon-OC-Monitor (deprecated)/LICENSE b/Source/Horizon-OC-Monitor (deprecated)/LICENSE deleted file mode 100644 index d159169d..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/Source/Horizon-OC-Monitor (deprecated)/Makefile b/Source/Horizon-OC-Monitor (deprecated)/Makefile deleted file mode 100644 index e2e4776b..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/Makefile +++ /dev/null @@ -1,243 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") -endif - -TOPDIR ?= $(CURDIR) -include $(DEVKITPRO)/libnx/switch_rules - -#--------------------------------------------------------------------------------- -# TARGET is the name of the output -# BUILD is the directory where object files & intermediate files will be placed -# 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 -# 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_NACP: if set to anything, no .nacp file is generated. -# APP_TITLE is the name of the app stored in the .nacp file (Optional) -# APP_AUTHOR is the author of the app stored in the .nacp file (Optional) -# APP_VERSION is the version of the app stored in the .nacp file (Optional) -# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional) -# ICON is the filename of the icon (.jpg), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .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. -#--------------------------------------------------------------------------------- -APP_TITLE := Horizon OC Monitor -APP_VERSION := 1.3.2+r4-hoc-r4 -TARGET := $(notdir $(CURDIR)) -BUILD := build -SOURCES := source -INCLUDES := include lib/Atmosphere-libs/libstratosphere/source/dmnt lib/Atmosphere-libs/libstratosphere/source ../hoc-clk/common/include/ -NO_ICON := 1 -#ROMFS := romfs - -# This location should reflect where you place the libultrahand directory (lib can vary between projects). -include ${TOPDIR}/lib/libultrahand/ultrahand.mk - - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -march=armv8-a+simd+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE - -CFLAGS := -g -Wall -Wno-address-of-packed-member -O3 -ffunction-sections -ffast-math -flto -fomit-frame-pointer \ - -fuse-linker-plugin -finline-small-functions \ - -fno-strict-aliasing -frename-registers -falign-functions=16 \ - $(ARCH) $(DEFINES) - -# For compiling Ultrahand Overlay only -IS_STATUS_MONITOR_DIRECTIVE := 1 -CFLAGS += -DIS_STATUS_MONITOR_DIRECTIVE=$(IS_STATUS_MONITOR_DIRECTIVE) - -# Enable appearance overriding -export MSYS2_ARG_CONV_EXCL := -DUI_OVERRIDE_PATH -UI_OVERRIDE_PATH := /config/status-monitor/ -CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\"" - - -CFLAGS += $(INCLUDE) -D__SWITCH__ -DAPP_VERSION="\"$(APP_VERSION)\"" - -CXXFLAGS := $(CFLAGS) -std=c++26 -Wno-dangling-else -fno-unwind-tables -fno-asynchronous-unwind-tables - -ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) - -LIBS := -lnx - -CXXFLAGS += -fno-exceptions -ffunction-sections -fdata-sections -fno-rtti -LDFLAGS += -Wl,--gc-sections -Wl,--as-needed - - -# For Ensuring Parallel LTRANS Jobs w/ GCC, make -j6 -CXXFLAGS += -flto -fuse-linker-plugin -flto=6 -LDFLAGS += -flto=6 - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(PORTLIBS) $(LIBNX) - - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export OUTPUT := $(CURDIR)/$(TARGET) -export TOPDIR := $(CURDIR) - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -export DEPSDIR := $(CURDIR)/$(BUILD) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES_BIN := $(addsuffix .o,$(BINFILES)) -export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) -export OFILES := $(OFILES_BIN) $(OFILES_SRC) -export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) - -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) - ifneq (,$(findstring $(TARGET).jpg,$(icons))) - export APP_ICON := $(TOPDIR)/$(TARGET).jpg - else - ifneq (,$(findstring icon.jpg,$(icons))) - export APP_ICON := $(TOPDIR)/icon.jpg - endif - endif -else - export APP_ICON := $(TOPDIR)/$(ICON) -endif - -ifeq ($(strip $(NO_ICON)),) - export NROFLAGS += --icon=$(APP_ICON) -endif - -ifeq ($(strip $(NO_NACP)),) - export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp -endif - -ifneq ($(APP_TITLEID),) - export NACPFLAGS += --titleid=$(APP_TITLEID) -endif - -ifneq ($(ROMFS),) - export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) -endif - -.PHONY: $(BUILD) clean all - -#--------------------------------------------------------------------------------- -all: $(BUILD) - - -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - @rm -rf out/ - @mkdir -p out/switch/.overlays/ - @cp -a $(CURDIR)/config out/ - @cp $(CURDIR)/$(TARGET).ovl out/switch/.overlays/$(TARGET).ovl - -#--------------------------------------------------------------------------------- -clean: - @echo "Cleanning ... $(TARGET)" - @rm -fr $(BUILD) $(TARGET).ovl $(TARGET).nro $(TARGET).nacp $(TARGET).elf - @rm -rf out/ - @rm -f $(TARGET).zip - -#--------------------------------------------------------------------------------- -dist: all - @echo making dist ... - @rm -f $(TARGET).zip - @cd out; zip -r ../$(TARGET).zip ./*; cd ../ -#--------------------------------------------------------------------------------- -else -.PHONY: all - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -all : $(OUTPUT).ovl - -$(OUTPUT).ovl : $(OUTPUT).elf $(OUTPUT).nacp - @elf2nro $< $@ $(NROFLAGS) - @echo "built ... $(notdir $(OUTPUT).ovl)" - @printf 'ULTR' >> $@ - @printf "Ultrahand signature has been added.\n" - -$(OUTPUT).elf : $(OFILES) - -$(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) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/Source/Horizon-OC-Monitor (deprecated)/README.md b/Source/Horizon-OC-Monitor (deprecated)/README.md deleted file mode 100644 index 234e0d02..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Thanks to NaGa for Status Monitor Pro!

- -**Horizon-OC-Monitor is deprecated.** If you want to compile it anyway, create a `lib` folder and clone Atmosphere-libs and libultrahand into it:

- -```bash -mkdir lib -git clone https://github.com/Atmosphere-NX/Atmosphere-libs lib/Atmosphere-libs -git clone https://github.com/ppkantorski/libultrahand lib/libultrahand -``` diff --git a/Source/Horizon-OC-Monitor (deprecated)/config/status-monitor/config.ini.template b/Source/Horizon-OC-Monitor (deprecated)/config/status-monitor/config.ini.template deleted file mode 100644 index a11d524b..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/config/status-monitor/config.ini.template +++ /dev/null @@ -1,127 +0,0 @@ -[status-monitor] -battery_avg_iir_filter=false -battery_time_left_refreshrate=60 -average_gpu_load=false -use_old_fps_average=false - -[full] -refresh_rate=1 -layer_width_align=left -show_real_freqs=true -show_deltas=true -show_target_freqs=true -show_fps=true -show_res=true -show_read_speed=true -use_dynamic_colors=true -disable_screenshots=false -separator_color=#888F -cat_color_1=#8FFF -cat_color_2=#8CFF -text_color=#FFFF - -[mini] -refresh_rate=1 -handheld_font_size=15 -docked_font_size=15 -spacing=8 -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=true -show_fan_percentage=true -show_soc_voltage=false -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%m-%d-%Y%H:%M:%S -show=DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES -replace_MB_with_RAM_load=true -show_RAM_load_CPU_GPU=false -invert_battery_display=true -disable_screenshots=false -sleep_exit=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[micro] -refresh_rate=1 -layer_height_align=top -handheld_font_size=15 -docked_font_size=15 -text_align=center -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=false -show_soc_voltage=true -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%H:%M:%S -show=FPS+CPU+GPU+RAM+SOC+BAT+DTC -replace_GB_with_RAM_load=true -invert_battery_display=false -disable_screenshots=false -sleep_exit=false -background_color=#0009 -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[fps-counter] -refresh_rate=30 -handheld_font_size=40 -docked_font_size=40 -use_integer_counter=false -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -text_color=#8CFF - -[fps-graph] -refresh_rate=30 -show_info=false -use_dynamic_colors=true -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -fps_counter_color=#888C -border_color=#2DFF -dashed_line_color=#8888 -main_line_color=#FFFF -rounded_line_color=#F0FF -perfect_line_color=#0C0F -max_fps_text_color=#FFFF -min_fps_text_color=#FFFF -text_color=#FFFF -cat_color=#0F0F - -[game_resolutions] -refresh_rate=10 -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -cat_color=#8FFF -text_color=#FFFF diff --git a/Source/Horizon-OC-Monitor (deprecated)/docs/config.md b/Source/Horizon-OC-Monitor (deprecated)/docs/config.md deleted file mode 100644 index e01b8466..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/docs/config.md +++ /dev/null @@ -1,103 +0,0 @@ -# Configuration file - -Configuration file is in `sdmc:/config/status-monitor/`. By default it's named `config.ini.template`. To be detected by overlay it must be renamed to `config.ini`. - ---- - -Explanation of what each setting does.
-Colors are provided in RGBA4444 format, which means that each character represents different channel: red, green, blue, alpha. - -> [status-monitor] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `key_combo` | Buttons combination that allows exiting Full, Mini, Micro, FPS Graph and FPS Counter modes; max 4 buttons, otherwise next buttons will be ignored. Combine different buttons with `+` | `A`, `B`, `X`, `Y`, `L`, `R`, `ZL`, `ZR`, `PLUS`, `MINUS`, `DUP`, `DDOWN`, `DLEFT`, `DRIGHT`, `SL`, `SR`, `LSTICK`, `RSTICK`, `UP`, `DOWN`, `LEFT`, `RIGHT` | `L+DDOWN+RSTICK` | -| `battery_avg_iir_filter` | Read voltage + current averages directly from fuel gauge, that uses infinite impulse response filter | `true`, `false` | `false` | -| `battery_time_left_refreshrate` | How many seconds must pass to refresh Battery Remaining Time | from `1` to `60` | `60` | -| `average_gpu_load` | Average 5 last GPU load readings. Because GPU load by design shows only load for last 1/60s, this option allows for more accurate gpu load readings at the cost of slight bump in CPU Core #3 usage (from 2 to 4 percentage points depending on CPU clock). | `true`, `false` | `false` | -| `font_cache` | Allow caching generated glyphs for better performance. Cache is cleaned up when moving between modes. | `true`, `false` | `true` | - - -> [full] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `refresh_rate` | How often per second this mode should be refreshed. Higher value means higher CPU Core #3 usage, that's why it is recommended to stay at 1. | From `1` to `60` | `1` | -| `layer_width_align` | On which side of the screen X axis you want this mode | `left`, `right` | `left` | -| `show_real_freqs` | This works only if you have sys-clk 2.0.0_rc4+ installed. Show real frequencies for CPU, GPU and RAM | `false`, `true` | `true` | -| `show_deltas` | This works only if you have sys-clk 2.0.0_rc4+ installed. Show difference for CPU, GPU and RAM between target frequencies and real frequencies. They are not showed if both keys `show_real_freqs` and `show_target_freqs` are set to `false` | `false`, `true` | `true` | -| `show_target_freqs` | Show target frequencies for CPU, GPU and RAM | `false`, `true` | `true` | -| `show_fps` | Show game's FPS and PFPS | `false`, `true` | `true` | -| `show_res` | Show game's 2 best candidates for internal resolution, it won't show when game is not using NVN | `false`, `true` | `true` | -| `show_read_speed` | Show game's read speed per second | `false`, `true` | `true` | - -> [mini] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `refresh_rate` | How often per second this mode should be refreshed. Higher value means higher CPU Core #3 usage, that's why it is recommended to stay at 1. | From `1` to `60` | `1` | -| `layer_width_align` | On which side of the screen X axis you want this mode | `left`, `center`, `right` | `left` | -| `layer_height_align` | On which side of the screen Y axis you want this mode | `top`, `center`, `bottom` | `top` | -| `handheld_font_size` | How big should be rendered text in handheld mode | From `8` to `22` | `15` | -| `docked_font_size` | How big should be rendered text in docked mode | From `8` to `22` | `15` | -| `real_freqs` | This works only if you have sys-clk 2.0.0_rc4+ installed. It shows real frequencies for CPU, GPU and RAM instead of target frequencies | `true`, `false` | `false` | -| `show` | Which data should be rendered. Connect different stats with `+` in any order. | `CPU`, `GPU`, `RAM`, `TEMP`, `FAN`, `DRAW`, `FPS`, `RES`, `READ` | `CPU+GPU+RAM+TEMP+FAN+DRAW+FPS+RES+READ` | -| `replace_MB_with_RAM_load` | This works only if you have sys-clk 2.0.0_rc4+ installed. Instead of RAM total usage it shows RAM load. | `true`, `false` | `true` | -| `background_color` | Background color in RGBA4444 format | From `#0000` to `#FFFF` | `#1117` | -| `cat_color` | Category text color (left side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | -| `text_color` | Stats text color (right side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | - -> [micro] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `refresh_rate` | How often per second this mode should be refreshed. Higher value means higher CPU Core #3 usage, that's why it is recommended to stay at 1. | From `1` to `60` | `1` | -| `layer_height_align` | On which side of the screen Y axis you want this mode | `top`, `bottom` | `top` | -| `handheld_font_size` | How big should be rendered text in handheld mode | From `8` to `18` | `18` | -| `docked_font_size` | How big should be rendered text in docked mode | From `8` to `18` | `18` | -| `text_align` | How shown text should be aligned | `left`, `center`, `right`| `center` | -| `real_freqs` | This works only if you have sys-clk 2.0.0_rc4+ installed. It shows real frequencies for CPU, GPU and RAM instead of target frequencies | `true`, `false` | `false` | -| `show` | Which data should be rendered. Connect different stats with `+` in any order. | `CPU`, `GPU`, `RAM`, `BRD`, `FAN`, `FPS` | `CPU+GPU+RAM+BRD+FAN+FPS` | -| `replace_GB_with_RAM_load` | This works only if you have sys-clk 2.0.0_rc4+ installed. Instead of RAM total usage it shows RAM load. | `true`, `false` | `true` | -| `background_color` | Background color in RGBA4444 format | From `#0000` to `#FFFF` | `#1117` | -| `cat_color` | Category text color (left side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FCCF` | -| `text_color` | Stats text color (right side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | - - -> [fps-counter] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `layer_width_align` | On which side of the screen X axis you want this mode | `left`, `center`, `right` | `left` | -| `layer_height_align` | On which side of the screen Y axis you want this mode | `top`, `center`, `bottom` | `top` | -| `handheld_font_size` | How big should be rendered text in handheld mode | From `8` to `150` | `40` | -| `docked_font_size` | How big should be rendered text in docked mode | From `8` to `150` | `40` | -| `background_color` | Background color in RGBA4444 format | From `#0000` to `#FFFF` | `#1117` | -| `text_color` | Text color in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | - -> [fps-graph] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `layer_width_align` | On which side of the screen X axis you want this mode | `left`, `center`, `right` | `left` | -| `layer_height_align` | On which side of the screen Y axis you want this mode | `top`, `center`, `bottom` | `top` | -| `max_fps_text_color` | Text color of "60" in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | -| `min_fps_text_color` | Text color of "0" in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | -| `background_color` | Background color in RGBA4444 format | From `#0000` to `#FFFF` | `#1117` | -| `fps_counter_color` | Text color of average FPS printed behind graph in RGBA4444 format | From `#0000` to `#FFFF` | `#4444` | -| `border_color` | Color of rectangle in RGBA4444 format | From `#0000` to `#FFFF` | `#F77F` | -| `dashed_line_color` | Color of dashed line at the center of rectangle in RGBA4444 format | From `#0000` to `#FFFF` | `#8888` | -| `main_line_color` | Color of line representing FPS value on graph in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | -| `rounded_line_color` | Color of line representing FPS value on graph if it's divisble by 10 in RGBA4444 format | From `#0000` to `#FFFF` | `#F0FF` | -| `perfect_line_color` | Color of line representing FPS value on graph if it's divisble by 30 in RGBA4444 format | From `#0000` to `#FFFF` | `#0C0F` | - -> [game_resolutions] - -| Key | Explanation | Possible values | Default Value | -|-----|-------------|-----------------|---------------| -| `refresh_rate` | How often per second this mode should be refreshed. Higher value means higher CPU Core #3 usage, that's why it is recommended to stay at 1. | From `1` to `60` | `10` | -| `layer_width_align` | On which side of the screen X axis you want this mode | `left`, `center`, `right` | `left` | -| `layer_height_align` | On which side of the screen Y axis you want this mode | `top`, `center`, `bottom` | `top` | -| `background_color` | Background color in RGBA4444 format | From `#0000` to `#FFFF` | `#1117` | -| `cat_color` | Category text color (left side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | -| `text_color` | Stats text color (right side) in RGBA4444 format | From `#0000` to `#FFFF` | `#FFFF` | diff --git a/Source/Horizon-OC-Monitor (deprecated)/docs/modes.md b/Source/Horizon-OC-Monitor (deprecated)/docs/modes.md deleted file mode 100644 index 665237dd..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/docs/modes.md +++ /dev/null @@ -1,252 +0,0 @@ -# Modes - -Horizon OC Monitor Overlay from 1.0.0 release contains five modes to choose from Main Menu.
-For additional functions you need to install: -- [SaltyNX](https://github.com/masagrator/SaltyNX/releases) -- [sys-clk 2.0.0_rc4+](https://github.com/retronx-team/sys-clk/releases) (using closed source forks of sys-clk can result in retrieving wrong real clockrates and ram load) - -# Full - -This mode you can know from older releases of Horizon OC Monitor. It contains all informations properly described and supported with high precision. - -- CPU Usage - - Real Frequency: `%.1f` = Real clockrate of all CPU cores in MHz (This shows only when sys-clk 2.0.0_4c+ is installed) - - Target Frequency: `%.1f` = Target clockrate of all CPU cores in MHz - - Core #0-#3: `%.2f` = Load of CPU Cores calculated from IdleTickCount to percent value - -- GPU Usage - - Real Frequency: `%.1f` = Real clockrate of GPU in MHz (This shows only when sys-clk 2.0.0_rc4+ is installed) - - Target Frequency: `%.1f` = Target clockrate of GPU in MHz - - Load: `%.1f` = GPU Load provided by PMU in percent - -- RAM Usage - - Real Frequency: `%.1f` = Real clockrate of EMC in MHz (This shows only when sys-clk 2.0.0_rc4+ is installed) - - Target Frequency: `%.1f` = Target clockrate of EMC in MHz - - Load: `%.1f` (CPU `%.1f` | GPU `%.1f`) = RAM Load in % (Which part of that are CPU and GPU (with other hardware, but their impact on GPU readings is negligible)) - - `%s`: `%.2f`/`%.2f` = %s memory used/%s memory available in MB (not working with FW <5.0.0) - -- Board - - Battery Power Flow: `%+.2f`[h:mm] = How much power in watts is discharged from or charged to the battery [time left before shutdown] - - Temperatures: SoC: `%.1f` / PCB: `%.1f` / Skin: `%.1f` = SoC / PCB / Skin temperature in Celsius degrees (Explanation provided at the end of file) - - Fan Rotation Level: `%.1f` = Fan rotation level in percent - - -```Optional (shows only when SaltyNX is installed and game is running)``` - -| Category | Format | Explanation | -|----------|-------------------|--------------------------------------------------------------------------| -| PFPS | %u | Pushed Frames Per Second - how many frames were displayed in last second | -| FPS | %.2f | Frames Per Second - value calculated by averaging frametime | -| Resolutions | %dx%d \|\| %dx%d | Two the most promising candidates for internal game resolution `(^1)` | -| Read speed | %.2f MiB/s | Show game read speed in the last second | - -- ^1 - read more informations in explanation for "Game Resolutions" menu - -# Mini - -Contains most of supported informations with lower precision. You can use touch screen to change its position temporarily. - -| Category | Format | Explanation | -|----------|---------------------------------------------------|---------------------------------------------------------------------------| -| CPU | [%.0f,%.0f,%.0f,%.0f]@%.1f | Core #0 usage, Core #1 usage, Core #2 usage, Core #3 usage@CPU Target/Real frequency`(^1)` | -| GPU | %.1f@%.1f | Load@GPU Target/Real Frequency`(^1)` | -| RAM | %.0f/%.0f@%.1f
`or`
%.1f(%.1f \| %.1f)@%.1f | Total RAM used/Total RAM available in MB@EMC Target/Real frequency `or` RAM load (CPU \| GPU)@EMC Target frequency `(^1)` | -| TEMP | %2.1f/%2.1f/%2.1f | SoC temperature/PCB temperature/Skin temperature `(^2)` | -| FAN | %2.1f | Fan rotation level | -| DRAW | %+.2f[h:mm] | How much power in watts is discharged from or charged to the battery [Time left before shutdown] | -| RES | %dx%d \|\| %dx%d | Two the most promising candidates for internal game resolution `(^3)` | -| READ | %.2f MiB/s | Show game read speed in the last second | - -- ^1 - Real Frequency + RAM Load available only with sys-clk 2.0.0_rc4+ -- ^2 - Explanation provided at the end of file -- ^3 - read more informations in explanation for "Game Resolutions" menu - -```Optional``` - -> shows only when SaltyNX is installed and game is running -> -| Category | Format | Explanation | -|----------|-------------------|--------------------------------------------------------------------------| -| FPS | %.2f | Frames Per Second | - -# Micro - -Contains most of supported informations with lower precision in one line. - -| Category | Format | Explanation | -|----------|------------------------------------------------------------|---------------------------------------------------------------------------| -| CPU | [%.0f,%.0f,%.0f,%.0f]%s%.1f | [Core #0 usage, Core #1 usage, Core #2 usage, Core #3 usage] `(^1)` CPU Target/Real Frequency `(^3)` | -| GPU | %.1f%s%.1f | Load (^1) GPU Target/Real Frequency | -| RAM | %.1f/%.1f%s%.1f `or` %.1f%s%.1f | Total RAM used/Total RAM available in GB `(^1)` EMC Target frequency `or` RAM Load in % `(^1)` EMC Target frequency | -| BRD | %2.1f/%2.1f/%2.1f@+.1f[h:mm] | SoC temperature/PCB temperature/Skin temperature(^2)/Battery Power Flow[Time left before shutdown] | -| FAN | %2.1f | Fan rotation level | - -- ^1 - by default it's `@`, but if you have sys-clk 2.0.0_rc4+ installed, this changes depending on difference between real clocks and targeted clocks.
- - `△` - real clocks are higher by at least 20 MHz than expected - - `▽` - real clocks are lower by at least 20 MHz than expected - - `≠` - real clocks are lower by at least 50 MHz than expected (If this shows constantly for longer than few seconds, this is a sign of throttling, usually caused by bad overclocking configuration) -- ^2 - Explanation provided at the end of file -- ^3 - Real frequencies + RAM Load available only with sys-clk 2.0.0_rc4+ - -```Optional``` - -> shows only when SaltyNX is installed and game is running - -| Category | Format | Explanation | -|----------|--------------------|--------------------------------------------------------------------------| -| FPS | %.1f | Frames Per Second | - - -# FPS - -> Counter - -It shows only FPS value in 31Hz + vsync signal.
-If game is not launched, it will show always `n/d` aka `no data`.
- -Mode available only with SaltyNX installed. You can use touch screen to change its position temporarily. - -> Graph - -It shows average FPS graph in 31Hz + vsync signal. In background of graph you can see rendered actual average FPS.
-If game is not launched, graph will be empty.
-If game is not rendering any new frame, graph is not updated. - -If line is within rounding error of graph line, it's colored. Average FPS must be between -0.05 and +0.04 of graph line target FPS. So for 30 FPS it's between 29.95 - 30.04 FPS. For 43 FPS it's 42.95 - 43.04 FPS. -If it's in display refresh rate or half of it rounding error range, it's green. Any other FPS graph target is purple. - -Colors can be changed in config file. - -Mode available only with SaltyNX installed. You can use touch screen to change its position temporarily. - -# Other - -> Battery - -- Battery Actual Capacity: `%d` = Battery Designed Capacity multiplied by Battery Age in mAh -- Battery Designed Capacity: `%d` = Battery capacity targeted by manufacturer in mAh -- Battery Temperature: `%.1f` = Battery temperature in Celsius -- Battery Raw Charge: `%.1f` = Raw battery charged capacity in percent -- Battery Age: `%.1f` = How much of designed capacity was charged last time battery was charged completely in percent -- Battery Voltage: `%.0f` = Battery average voltage in mV (time period: 5s, or with `battery_avg_iir_filter` enabled: 45s) -- Battery Current Flow: `%+.0f` = Battery average current flow in mA (time period: 5s, or with `battery_avg_iir_filter` enabled: 11.25s) -- Battery Power Flow: `%+.3f` = Battery average power flow in W calculated from Battery Voltage and Battery Current Flow -- Battery Remaining Time: h:mm - How much time is left before shutdown - -Shows only if charger is connected: -| Category | Format | Explanation | -|---------------------------|--------------|----------------------------------------------------------------------------------| -| Charger Type | %u | Connected charger type, more in Battery.hpp "BatteryChargeInfoFieldsChargerType" | -| Charger Max Voltage | %u | Charger and external device voltage limit in mV | -| Charger Max Current | %u | Charger and external device current limit in mA | - -> Miscellaneous - -| Category | Format | Explanation | -|------------------------|-------------------|----------------------------------------------------------------------------------| -| DSP Usage | %u | In percent (not available on 17.0.0+) | -| NVDEC | %.2f | Target frequency in MHz (shows 0 if chip is not active) | -| NVENC | %.2f | Target frequency in MHz (shows 0 if chip is not active) | -| NVJPG | %.2f | Target frequency in MHz (shows 0 if chip is not active) | -| Network Type | %s | It shows if Switch is connected to internet, and if it's using Ethernet or Wi-Fi | - -If Network Type is "Wi-Fi", you can press Y to show password. Since max password length is 64 characters, it may show in up to 3 lines. - -> Game Resolutions - -For this mode to show and work properly you must have SaltyNX 0.9.0+ installed. You can use touch screen to change its position temporarily. - -When game runs, this menu shows what resolutions and how many times they were passed to GPU via two functions: -- __Depth__ shows info from depth texture passed to `nvnCommandBufferSetRenderTargets` -- __Viewport__ shows info from arguments passed to: - - for NVN: `nvnCommandBufferSetViewport`, `nvnCommandBufferSetViewports`, `nvnCommandBufferSetScissor` and `nvnCommandBufferSetScissors` - - for EGL: `glViewport`, `glViewportArrayv`, `glViewportIndexedf`, `glViewportIndexedfv` and all their variations - - for Vulkan: `vkCmdSetViewport` and `vkCmdSetViewportWithCount` - -This menu shows first 8 resolutions passed to those functions in last frame rendering loop, sorted in descending order of calls number.
-Its main purpose is to catch game rendering resolution, but user must deduce which ones are correct.
-I have limited catched resolutions only to ones that have ratio higher than 0.6 and lower than 1.8. Such low value comes from the fact that some games are rendering at width lower than height (f.e. 480x720). There is also a limit where it won't accept resolutions which height is lower than 160 px or higher than 1440 px.
- -Remember that resolutions you can see in this mode may be used in different ways - for example Tokyo Xanadu Ex+ max dynamic resolution in handheld will show 1280x736, but it's not that game will squeeze this into 720p screen, it's just removing those additional 16 pixels from showing on screen. - -Those commands are used by all 3D games using NVN, EGL and Vulkan APIs (that's why it may not work with games using 2D engines).
-This mode is not 100% fullproof, so it can show that nothing is catched or it won't catch what is used for 3D rendering (if this happens for some 3D game, please report an issue). - -By default refresh rate of this menu is 10 FPS. You can change that in config.ini, more in config.md
-Exiting is done by using the same combo buttons used in other main modes. - -Games that don't mesh well with RES category in `Mini` and Resolution in `Full` modes while showing properly rendering resolutions in this menu: -- `Kirby and The Forgotten Land`: dynamic resolution has much less calls than other resolutions, it shows up correctly only when it's max dynamic resolution set. It shows up always first in Depth category of Game Resolutions menu. -- `Darksiders 2`: Dynamic resolution is randomly showing up, fighting for attention with native resolution call. In Game Resolutions menu it shows up either at 2nd or 3rd place of Viewport. - -# Additional info - -> How Battery Remaining Time is calculated - -It is calculated from the last 3 minutes of power draw readings. In the first minute of running any mode, it is updated every 0.5s, after one minute it's updated every minute. When exiting the currently used mode, calculations are reset. When connecting or disconnecting the charger, calculations are reset. When Battery Power Draw is positive instead of negative, time is shown as [-:--] and calculations are reset. - -> What is Skin temperature ($\mathbf{T}skin$)? - -This is temperature calculated from SoC and PCB temperatures that is mainly used to prevent Switch from overheating. Reading it is not supported on FWs <5.0.0. - -Explanation provided by CTCaer ->Temperature ($\mathbf{T}skin$) calculation. -> -> ->Console and Handheld: -> ->$\mathbf{T}soc >= 84°C$ - Immediate sleep. No questions asked. -> ->$\mathbf{T}pcb >= 84°C$ - Immediate sleep. No questions asked. -> -> ->Console only: -> ->$\mathbf{T}skin < 63°C$ - Clears both timers. -> ->$\mathbf{T}skin >= 63°C$ - Immediate sleep. No questions asked. -> -> ->Handheld only: -> ->$\mathbf{T}skin < 58°C$ - Clears both timers. -> ->$58°C <= \mathbf{T}skin < 61°C$ - Starts 60s timer and clears 10s timer. -> ->$61°C <= \mathbf{T}skin < 63°C$ - Starts 10s timer. -> ->$\mathbf{T}skin >= 63°C$ - Immediate sleep. No questions asked. -> -> ->The two timers are separate. If 61°C is reached, the 10s timer is immediatly started. -> ->If a timer ends and the temperature is not dropped, goes into sleep. -> -> ->tskin is the specific calculation below: -``` -soc_adj = (temps.iir_filter_gain_soc * (temps.soc - temps.soc_adj_prev)) + temps.soc_adj_prev; -pcb_adj = (temps.iir_filter_gain_pcb * (temps.pcb - temps.pcb_adj_prev)) + temps.pcb_adj_prev; -temps.soc_adj_prev = soc_adj; -temps.pcb_adj_prev = pcb_adj; - -if (soc_adj >= 38000) -{ - if (temps.handheld) - soc_adj = (temps.tskin_soc_coeff_handheld[0] * soc_adj) + (1000 * temps.tskin_soc_coeff_handheld[1]); - else - soc_adj = (temps.tskin_soc_coeff_console[0] * soc_adj) + (1000 * temps.tskin_soc_coeff_console[1]); - soc_adj = (soc_adj / 10000) + 500; -} - -if (pcb_adj >= 38000) -{ - if (temps.handheld) - pcb_adj = (temps.tskin_pcb_coeff_handheld[0] * pcb_adj) + (1000 * temps.tskin_pcb_coeff_handheld[1]); - else - pcb_adj = (temps.tskin_pcb_coeff_console[0] * soc_adj) + (1000 * temps.tskin_pcb_coeff_console[1]); - pcb_adj = (pcb_adj / 10000) + 500; -} - -skin_adj = MAX(soc_adj, pcb_adj); //tskin -``` diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/Battery.hpp b/Source/Horizon-OC-Monitor (deprecated)/include/Battery.hpp deleted file mode 100644 index 8c39547c..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/Battery.hpp +++ /dev/null @@ -1,81 +0,0 @@ -///* Notes VoltageAvg -// -// Vavg time = 175.8ms x 2^(6+VOLT), default: VOLT = 2 (Vavg time = 45s) -// -///End of Notes - -typedef enum { - NoHub = BIT(0), //If hub is disconnected - Rail = BIT(8), //At least one Joy-con is charging from rail - SPDSRC = BIT(12), //OTG - ACC = BIT(16) //Accessory -} BatteryChargeInfoFieldsFlags; - -typedef enum { - NewPDO = 1, //Received new Power Data Object - NoPD = 2, //No Power Delivery source is detected - AcceptedRDO = 3 //Received and accepted Request Data Object -} BatteryChargeInfoFieldsPDControllerState; //BM92T series - -typedef enum { - None = 0, - PD = 1, - TypeC_1500mA = 2, - TypeC_3000mA = 3, - DCP = 4, - CDP = 5, - SDP = 6, - Apple_500mA = 7, - Apple_1000mA = 8, - Apple_2000mA = 9 -} BatteryChargeInfoFieldsChargerType; - -typedef enum { - Sink = 1, - Source = 2 -} BatteryChargeInfoFieldsPowerRole; - -typedef struct { - int32_t InputCurrentLimit; //Input (Sink) current limit in mA - int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA - int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C) - int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C) - int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases - int32_t unk_x14; //Possibly flags - BatteryChargeInfoFieldsPDControllerState PDControllerState; //Power Delivery Controller State - int32_t BatteryTemperature; //Battery temperature in milli C - int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm) - int32_t VoltageAvg; //Voltage avg in mV (more in Notes) - int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm) - BatteryChargeInfoFieldsPowerRole PowerRole; - BatteryChargeInfoFieldsChargerType ChargerType; - int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV - int32_t ChargerCurrentLimit; //Charger and external device current limit in mA - BatteryChargeInfoFieldsFlags Flags; //Unknown flags - char reserved[0x14]; //17.0.0+ data -} BatteryChargeInfoFields; - -typedef struct { - int32_t InputCurrentLimit; //Input (Sink) current limit in mA - int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA - int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C) - int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C) - int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases - int32_t unk_x14; //Possibly flags - BatteryChargeInfoFieldsPDControllerState PDControllerState; //Power Delivery Controller State - int32_t BatteryTemperature; //Battery temperature in milli C - int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm) - int32_t VoltageAvg; //Voltage avg in mV (more in Notes) - int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm) - char reserved[4]; //17.0.0+ data - BatteryChargeInfoFieldsPowerRole PowerRole; - BatteryChargeInfoFieldsChargerType ChargerType; - int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV - int32_t ChargerCurrentLimit; //Charger and external device current limit in mA - BatteryChargeInfoFieldsFlags Flags; //Unknown flags - char reserved2[0x10]; //17.0.0+ data -} BatteryChargeInfoFields17; - -Result psmGetBatteryChargeInfoFields(Service* psmService, BatteryChargeInfoFields *out) { - return serviceDispatchOut(psmService, 17, *out); -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/Misc.hpp b/Source/Horizon-OC-Monitor (deprecated)/include/Misc.hpp deleted file mode 100644 index d5f21a08..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/Misc.hpp +++ /dev/null @@ -1,41 +0,0 @@ -typedef struct { - u8 ssid_len; ///< NifmSfWirelessSettingData::ssid_len - char ssid[0x21]; ///< NifmSfWirelessSettingData::ssid - u8 unk_x22; ///< NifmSfWirelessSettingData::unk_x21 - u8 pad; ///< Padding - u32 unk_x24; ///< NifmSfWirelessSettingData::unk_x22 - u32 unk_x28; ///< NifmSfWirelessSettingData::unk_x23 - u8 passphrase_len; ///< Passphrase length - u8 passphrase[0x41]; ///< NifmSfWirelessSettingData::passphrase - u8 pad2[0x2]; ///< Padding -} NifmWirelessSettingData_new; - -/// NetworkProfileData. Converted from/to \ref NifmSfNetworkProfileData. -typedef struct { - Uuid uuid; ///< NifmSfNetworkProfileData::uuid - char network_name[0x40]; ///< NifmSfNetworkProfileData::network_name - u32 unk_x50; ///< NifmSfNetworkProfileData::unk_x112 - u32 unk_x54; ///< NifmSfNetworkProfileData::unk_x113 - u8 unk_x58; ///< NifmSfNetworkProfileData::unk_x114 - u8 unk_x59; ///< NifmSfNetworkProfileData::unk_x115 - u8 pad[2]; ///< Padding - NifmWirelessSettingData_new wireless_setting_data; ///< \ref NifmWirelessSettingData - NifmIpSettingData ip_setting_data; ///< \ref NifmIpSettingData -} NifmNetworkProfileData_new; - -Result getNvChannelClockRate(NvChannel *channel, u32 module_id, u32 *clock_rate) { - struct nvhost_clk_rate_args { - uint32_t rate; - uint32_t moduleid; - } args = { - .rate = 0, - .moduleid = module_id, - }; - - const u32 id = hosversionBefore(8,0,0) ? _NV_IOWR(0, 0x14, args) : _NV_IOWR(0, 0x23, args); - Result rc = nvIoctl(channel->fd, id, &args); - if (R_SUCCEEDED(rc) && clock_rate) - *clock_rate = args.rate; - - return rc; -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/SaltyNX.h b/Source/Horizon-OC-Monitor (deprecated)/include/SaltyNX.h deleted file mode 100644 index e0dbb80b..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/SaltyNX.h +++ /dev/null @@ -1,231 +0,0 @@ -#pragma once -#include "ipc.h" - -Handle saltysd_orig; - -Result SaltySD_Connect() { - for (int i = 0; i < 200; i++) { - if (!svcConnectToNamedPort(&saltysd_orig, "SaltySD")) - return 0; - svcSleepThread(1000*1000); - } - return 1; -} - -Result SaltySD_Term() -{ - Result ret; - IpcCommand c; - - ipcInitialize(&c); - ipcSendPid(&c); - - struct input - { - u64 magic; - u64 cmd_id; - u64 zero; - u64 reserved[2]; - } *raw; - - raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->zero = 0; - - ret = ipcDispatch(saltysd_orig); - - if (R_SUCCEEDED(ret)) - { - IpcParsedCommand r; - ipcParse(&r); - - struct output { - u64 magic; - u64 result; - } *resp = (output*)r.Raw; - - ret = resp->result; - } - - // Session terminated works too. - svcCloseHandle(saltysd_orig); - if (ret == 0xf601) return 0; - - return ret; -} - -Result SaltySD_CheckIfSharedMemoryAvailable(ptrdiff_t *offset, u64 size) -{ - Result ret = 0; - - // Send a command - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct input { - u64 magic; - u64 cmd_id; - u64 size; - u32 reserved[2]; - } *raw; - - raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 6; - raw->size = size; - - ret = ipcDispatch(saltysd_orig); - - if (R_SUCCEEDED(ret)) { - IpcParsedCommand r; - ipcParse(&r); - - struct output { - u64 magic; - u64 result; - u64 offset; - } *resp = (output*)r.Raw; - - ret = resp->result; - - if (!ret) - { - *offset = resp->offset; - } - } - - return ret; -} - -Result SaltySD_GetSharedMemoryHandle(Handle *retrieve) -{ - Result ret = 0; - - // Send a command - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct input { - u64 magic; - u64 cmd_id; - u32 reserved[4]; - } *raw; - - raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 7; - - ret = ipcDispatch(saltysd_orig); - - if (R_SUCCEEDED(ret)) { - IpcParsedCommand r; - ipcParse(&r); - - struct output { - u64 magic; - u64 result; - u64 reserved[2]; - } *resp = (output*)r.Raw; - - ret = resp->result; - - if (!ret) - { - *retrieve = r.Handles[0]; - } - } - - return ret; -} - -Result SaltySD_GetDisplayRefreshRate(uint8_t* refreshRate) -{ - Result ret = 0; - - // Send a command - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct input { - u64 magic; - u64 cmd_id; - u64 zero; - u64 reserved; - } *raw; - - raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 10; - raw->zero = 0; - - ret = ipcDispatch(saltysd_orig); - - if (R_SUCCEEDED(ret)) { - IpcParsedCommand r; - ipcParse(&r); - - struct output { - u64 magic; - u64 result; - u64 refreshRate; - u64 reserved; - } *resp = (output*)r.Raw; - - ret = resp->result; - - if (!ret) - { - *refreshRate = (uint8_t)(resp->refreshRate); - } - } - - return ret; -} - -Result SaltySD_SetDisplayRefreshRate(uint8_t refreshRate) -{ - Result ret = 0; - - // Send a command - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct input { - u64 magic; - u64 cmd_id; - u64 refreshRate; - u64 reserved; - } *raw; - - raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 11; - raw->refreshRate = refreshRate; - - ret = ipcDispatch(saltysd_orig); - - if (R_SUCCEEDED(ret)) { - IpcParsedCommand r; - ipcParse(&r); - - struct output { - u64 magic; - u64 result; - u64 reserved[2]; - } *resp = (output*)r.Raw; - - ret = resp->result; - } - - return ret; -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/audsnoop.h b/Source/Horizon-OC-Monitor (deprecated)/include/audsnoop.h deleted file mode 100644 index ac0dacdf..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/audsnoop.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -Result audsnoopInitialize(void); -void audsnoopExit(void); - -Result audsnoopEnableDspUsageMeasurement(void); -Result audsnoopDisableDspUsageMeasurement(void); - -Result audsnoopGetDspUsage(u32 *usage); - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/i2c.h b/Source/Horizon-OC-Monitor (deprecated)/include/i2c.h deleted file mode 100644 index 6c2d68eb..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/i2c.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -Result I2cReadRegHandler16(u8 reg, I2cDevice dev, u16 *out) -{ - struct readReg { - u8 send; - u8 sendLength; - u8 sendData; - u8 receive; - u8 receiveLength; - }; - - I2cSession _session; - - Result res = i2cOpenSession(&_session, dev); - if (res) - return res; - - u16 val; - - struct readReg readRegister = { - .send = 0 | (I2cTransactionOption_Start << 6), - .sendLength = sizeof(reg), - .sendData = reg, - .receive = 1 | (I2cTransactionOption_All << 6), - .receiveLength = sizeof(val), - }; - - res = i2csessionExecuteCommandList(&_session, &val, sizeof(val), &readRegister, sizeof(readRegister)); - if (res) - { - i2csessionClose(&_session); - return res; - } - - *out = val; - i2csessionClose(&_session); - return 0; -} - -Result I2cReadRegHandler8(u8 reg, I2cDevice dev, u8 *out) -{ - struct readReg { - u8 send; - u8 sendLength; - u8 sendData; - u8 receive; - u8 receiveLength; - }; - - I2cSession _session; - - Result res = i2cOpenSession(&_session, dev); - if (res) - return res; - - u8 val; - - struct readReg readRegister = { - .send = 0 | (I2cTransactionOption_Start << 6), - .sendLength = sizeof(reg), - .sendData = reg, - .receive = 1 | (I2cTransactionOption_All << 6), - .receiveLength = sizeof(val), - }; - - res = i2csessionExecuteCommandList(&_session, &val, sizeof(val), &readRegister, sizeof(readRegister)); - if (res) - { - i2csessionClose(&_session); - return res; - } - - *out = val; - i2csessionClose(&_session); - return 0; -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/ipc.h b/Source/Horizon-OC-Monitor (deprecated)/include/ipc.h deleted file mode 100644 index ef370f7e..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/ipc.h +++ /dev/null @@ -1,755 +0,0 @@ -/** - * @file ipc.h - * @brief Inter-process communication handling - * @author plutoo - * @copyright libnx Authors - */ -#pragma once - -/// IPC input header magic -#define SFCI_MAGIC 0x49434653 -/// IPC output header magic -#define SFCO_MAGIC 0x4f434653 - -/// IPC invalid object ID -#define IPC_INVALID_OBJECT_ID UINT32_MAX - -///@name IPC request building -///@{ - -/// IPC command (request) structure. -#define IPC_MAX_BUFFERS 8 -#define IPC_MAX_OBJECTS 8 - -typedef enum { - BufferType_Normal=0, ///< Regular buffer. - BufferType_Type1=1, ///< Allows ProcessMemory and shared TransferMemory. - BufferType_Invalid=2, - BufferType_Type3=3 ///< Same as Type1 except remote process is not allowed to use device-mapping. -} BufferType; - -typedef enum { - BufferDirection_Send=0, - BufferDirection_Recv=1, - BufferDirection_Exch=2, -} BufferDirection; - -typedef enum { - IpcCommandType_Invalid = 0, - IpcCommandType_LegacyRequest = 1, - IpcCommandType_Close = 2, - IpcCommandType_LegacyControl = 3, - IpcCommandType_Request = 4, - IpcCommandType_Control = 5, - IpcCommandType_RequestWithContext = 6, - IpcCommandType_ControlWithContext = 7, -} IpcCommandType; - -typedef enum { - DomainMessageType_Invalid = 0, - DomainMessageType_SendMessage = 1, - DomainMessageType_Close = 2, -} DomainMessageType; - -/// IPC domain message header. -typedef struct { - u8 Type; - u8 NumObjectIds; - u16 Length; - u32 ThisObjectId; - u32 Pad[2]; -} DomainMessageHeader; - -/// IPC domain response header. -typedef struct { - u32 NumObjectIds; - u32 Pad[3]; -} DomainResponseHeader; - - -typedef struct { - size_t NumSend; // A - size_t NumRecv; // B - size_t NumExch; // W - const void* Buffers[IPC_MAX_BUFFERS]; - size_t BufferSizes[IPC_MAX_BUFFERS]; - BufferType BufferTypes[IPC_MAX_BUFFERS]; - - size_t NumStaticIn; // X - size_t NumStaticOut; // C - const void* Statics[IPC_MAX_BUFFERS]; - size_t StaticSizes[IPC_MAX_BUFFERS]; - u8 StaticIndices[IPC_MAX_BUFFERS]; - - bool SendPid; - size_t NumHandlesCopy; - size_t NumHandlesMove; - Handle Handles[IPC_MAX_OBJECTS]; - - size_t NumObjectIds; - u32 ObjectIds[IPC_MAX_OBJECTS]; -} IpcCommand; - -/** - * @brief Initializes an IPC command structure. - * @param cmd IPC command structure. - */ -static inline void ipcInitialize(IpcCommand* cmd) { - *cmd = (IpcCommand){}; -} - -/// IPC buffer descriptor. -typedef struct { - u32 Size; ///< Size of the buffer. - u32 Addr; ///< Lower 32-bits of the address of the buffer - u32 Packed; ///< Packed data (including higher bits of the address) -} IpcBufferDescriptor; - -/// IPC static send-buffer descriptor. -typedef struct { - u32 Packed; ///< Packed data (including higher bits of the address) - u32 Addr; ///< Lower 32-bits of the address -} IpcStaticSendDescriptor; - -/// IPC static receive-buffer descriptor. -typedef struct { - u32 Addr; ///< Lower 32-bits of the address of the buffer - u32 Packed; ///< Packed data (including higher bits of the address) -} IpcStaticRecvDescriptor; - -/** - * @brief Adds a buffer to an IPC command structure. - * @param cmd IPC command structure. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param type Buffer type. - */ -static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, BufferType type) { - const size_t off = cmd->NumSend; - cmd->Buffers[off] = buffer; - cmd->BufferSizes[off] = size; - cmd->BufferTypes[off] = type; - cmd->NumSend++; -} - -/** - * @brief Adds a receive-buffer to an IPC command structure. - * @param cmd IPC command structure. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param type Buffer type. - */ -static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) { - const size_t off = cmd->NumSend + cmd->NumRecv; - cmd->Buffers[off] = buffer; - cmd->BufferSizes[off] = size; - cmd->BufferTypes[off] = type; - cmd->NumRecv++; -} - -/** - * @brief Adds an exchange-buffer to an IPC command structure. - * @param cmd IPC command structure. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param type Buffer type. - */ -static inline void ipcAddExchBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) { - const size_t off = cmd->NumSend + cmd->NumRecv + cmd->NumExch; - cmd->Buffers[off] = buffer; - cmd->BufferSizes[off] = size; - cmd->BufferTypes[off] = type; - cmd->NumExch++; -} - -/** - * @brief Adds a static-buffer to an IPC command structure. - * @param cmd IPC command structure. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param index Index of buffer. - */ -static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t size, u8 index) { - const size_t off = cmd->NumStaticIn; - cmd->Statics[off] = buffer; - cmd->StaticSizes[off] = size; - cmd->StaticIndices[off] = index; - cmd->NumStaticIn++; -} - -/** - * @brief Adds a static-receive-buffer to an IPC command structure. - * @param cmd IPC command structure. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param index Index of buffer. - */ -static inline void ipcAddRecvStatic(IpcCommand* cmd, void* buffer, size_t size, u8 index) { - const size_t off = cmd->NumStaticIn + cmd->NumStaticOut; - cmd->Statics[off] = buffer; - cmd->StaticSizes[off] = size; - cmd->StaticIndices[off] = index; - cmd->NumStaticOut++; -} - -/** - * @brief Adds a smart-buffer (buffer + static-buffer pair) to an IPC command structure. - * @param cmd IPC command structure. - * @param pointer_buffer_size Pointer buffer size. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param index Index of buffer. - */ -static inline void ipcAddSendSmart(IpcCommand* cmd, size_t pointer_buffer_size, const void* buffer, size_t size, u8 index) { - if (pointer_buffer_size != 0 && size <= pointer_buffer_size) { - ipcAddSendBuffer(cmd, NULL, 0, BufferType_Normal); - ipcAddSendStatic(cmd, buffer, size, index); - } else { - ipcAddSendBuffer(cmd, buffer, size, BufferType_Normal); - ipcAddSendStatic(cmd, NULL, 0, index); - } -} - -/** - * @brief Adds a smart-receive-buffer (buffer + static-receive-buffer pair) to an IPC command structure. - * @param cmd IPC command structure. - * @param pointer_buffer_size Pointer buffer size. - * @param buffer Address of the buffer. - * @param size Size of the buffer. - * @param index Index of buffer. - */ -static inline void ipcAddRecvSmart(IpcCommand* cmd, size_t pointer_buffer_size, void* buffer, size_t size, u8 index) { - if (pointer_buffer_size != 0 && size <= pointer_buffer_size) { - ipcAddRecvBuffer(cmd, NULL, 0, BufferType_Normal); - ipcAddRecvStatic(cmd, buffer, size, index); - } else { - ipcAddRecvBuffer(cmd, buffer, size, BufferType_Normal); - ipcAddRecvStatic(cmd, NULL, 0, index); - } -} - -/** - * @brief Tags an IPC command structure to send the PID. - * @param cmd IPC command structure. - */ -static inline void ipcSendPid(IpcCommand* cmd) { - cmd->SendPid = true; -} - -/** - * @brief Adds a copy-handle to be sent through an IPC command structure. - * @param cmd IPC command structure. - * @param h Handle to send. - * @remark The receiving process gets a copy of the handle. - */ -static inline void ipcSendHandleCopy(IpcCommand* cmd, Handle h) { - cmd->Handles[cmd->NumHandlesCopy++] = h; -} - -/** - * @brief Adds a move-handle to be sent through an IPC command structure. - * @param cmd IPC command structure. - * @param h Handle to send. - * @remark The sending process loses ownership of the handle, which is transferred to the receiving process. - */ -static inline void ipcSendHandleMove(IpcCommand* cmd, Handle h) { - cmd->Handles[cmd->NumHandlesCopy + cmd->NumHandlesMove++] = h; -} - -/** - * @brief Prepares the header of an IPC command structure. - * @param cmd IPC command structure. - * @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request - * @return Pointer to the raw embedded data structure in the request, ready to be filled out. - */ -static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { - u32* buf = (u32*)armGetTls(); - size_t i; - *buf++ = IpcCommandType_Request | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumExch << 28); - - u32* fill_in_size_later = buf; - - if (cmd->NumStaticOut > 0) { - *buf = (cmd->NumStaticOut + 2) << 10; - } - else { - *buf = 0; - } - - if (cmd->SendPid || cmd->NumHandlesCopy > 0 || cmd->NumHandlesMove > 0) { - *buf++ |= 0x80000000; - *buf++ = (!!cmd->SendPid) | (cmd->NumHandlesCopy << 1) | (cmd->NumHandlesMove << 5); - - if (cmd->SendPid) - buf += 2; - - for (i=0; i<(cmd->NumHandlesCopy + cmd->NumHandlesMove); i++) - *buf++ = cmd->Handles[i]; - } - else { - buf++; - } - - for (i=0; iNumStaticIn; i++, buf+=2) { - IpcStaticSendDescriptor* desc = (IpcStaticSendDescriptor*) buf; - - const uintptr_t ptr = (uintptr_t) cmd->Statics[i]; - desc->Addr = ptr; - desc->Packed = cmd->StaticIndices[i] | (cmd->StaticSizes[i] << 16) | - (((ptr >> 32) & 15) << 12) | (((ptr >> 36) & 15) << 6); - } - - for (i=0; i<(cmd->NumSend + cmd->NumRecv + cmd->NumExch); i++, buf+=3) { - IpcBufferDescriptor* desc = (IpcBufferDescriptor*) buf; - desc->Size = cmd->BufferSizes[i]; - - const uintptr_t ptr = (uintptr_t) cmd->Buffers[i]; - desc->Addr = ptr; - desc->Packed = cmd->BufferTypes[i] | - (((ptr >> 32) & 15) << 28) | ((ptr >> 36) << 2); - } - - const u32 padding = ((16 - (((uintptr_t) buf) & 15)) & 15) / 4; - u32* raw = (u32*) (buf + padding); - - size_t raw_size = (sizeof_raw/4) + 4; - buf += raw_size; - - u16* buf_u16 = (u16*) buf; - - for (i=0; iNumStaticOut; i++) { - const size_t off = cmd->NumStaticIn + i; - const size_t sz = (uintptr_t) cmd->StaticSizes[off]; - - buf_u16[i] = (sz > 0xFFFF) ? 0 : sz; - } - - const size_t u16s_size = ((2*cmd->NumStaticOut) + 3)/4; - buf += u16s_size; - raw_size += u16s_size; - - *fill_in_size_later |= raw_size; - - for (i=0; iNumStaticOut; i++, buf+=2) { - IpcStaticRecvDescriptor* desc = (IpcStaticRecvDescriptor*) buf; - const size_t off = cmd->NumStaticIn + i; - - const uintptr_t ptr = (uintptr_t) cmd->Statics[off]; - desc->Addr = ptr; - desc->Packed = (ptr >> 32) | (cmd->StaticSizes[off] << 16); - } - - return (void*) raw; -} - -/** - * @brief Dispatches an IPC request. - * @param session IPC session handle. - * @return Result code. - */ -static inline Result ipcDispatch(Handle session) { - return svcSendSyncRequest(session); -} - -///@} - -///@name IPC response parsing -///@{ - -/// IPC parsed command (response) structure. -typedef struct { - IpcCommandType CommandType; ///< Type of the command - - bool HasPid; ///< true if the 'Pid' field is filled out. - u64 Pid; ///< PID included in the response (only if HasPid is true) - - size_t NumHandles; ///< Number of handles copied. - Handle Handles[IPC_MAX_OBJECTS]; ///< Handles. - bool WasHandleCopied[IPC_MAX_OBJECTS]; ///< true if the handle was moved, false if it was copied. - - bool IsDomainRequest; ///< true if the the message is a Domain message. - DomainMessageType InMessageType; ///< Type of the domain message. - u32 InMessageLength; ///< Size of rawdata (for domain messages). - u32 InThisObjectId; ///< Object ID to call the command on (for domain messages). - size_t InNumObjectIds; ///< Number of object IDs (for domain messages). - u32 InObjectIds[IPC_MAX_OBJECTS]; ///< Object IDs (for domain messages). - - bool IsDomainResponse; ///< true if the the message is a Domain response. - size_t OutNumObjectIds; ///< Number of object IDs (for domain responses). - u32 OutObjectIds[IPC_MAX_OBJECTS]; ///< Object IDs (for domain responses). - - size_t NumBuffers; ///< Number of buffers in the response. - void* Buffers[IPC_MAX_BUFFERS]; ///< Pointers to the buffers. - size_t BufferSizes[IPC_MAX_BUFFERS]; ///< Sizes of the buffers. - BufferType BufferTypes[IPC_MAX_BUFFERS]; ///< Types of the buffers. - BufferDirection BufferDirections[IPC_MAX_BUFFERS]; ///< Direction of each buffer. - - size_t NumStatics; ///< Number of statics in the response. - void* Statics[IPC_MAX_BUFFERS]; ///< Pointers to the statics. - size_t StaticSizes[IPC_MAX_BUFFERS]; ///< Sizes of the statics. - u8 StaticIndices[IPC_MAX_BUFFERS]; ///< Indices of the statics. - - size_t NumStaticsOut; ///< Number of output statics available in the response. - - void* Raw; ///< Pointer to the raw embedded data structure in the response. - void* RawWithoutPadding; ///< Pointer to the raw embedded data structure, without padding. - size_t RawSize; ///< Size of the raw embedded data. -} IpcParsedCommand; - -/** - * @brief Parse an IPC command response into an IPC parsed command structure. - * @param r IPC parsed command structure to fill in. - * @return Result code. - */ -static inline Result ipcParse(IpcParsedCommand* r) { - u32* buf = (u32*)armGetTls(); - u32 ctrl0 = *buf++; - u32 ctrl1 = *buf++; - size_t i; - - r->IsDomainRequest = false; - r->IsDomainResponse = false; - - r->CommandType = (IpcCommandType) (ctrl0 & 0xffff); - r->HasPid = false; - r->RawSize = (ctrl1 & 0x1ff) * 4; - r->NumHandles = 0; - - r->NumStaticsOut = (ctrl1 >> 10) & 15; - if (r->NumStaticsOut >> 1) r->NumStaticsOut--; // Value 2 -> Single descriptor - if (r->NumStaticsOut >> 1) r->NumStaticsOut--; // Value 3+ -> (Value - 2) descriptors - - if (ctrl1 & 0x80000000) { - u32 ctrl2 = *buf++; - - if (ctrl2 & 1) { - r->HasPid = true; - r->Pid = *buf++; - r->Pid |= ((u64)(*buf++)) << 32; - } - - const size_t num_handles_copy = ((ctrl2 >> 1) & 15); - const size_t num_handles_move = ((ctrl2 >> 5) & 15); - - size_t num_handles = num_handles_copy + num_handles_move; - u32* buf_after_handles = buf + num_handles; - - if (num_handles > IPC_MAX_OBJECTS) - num_handles = IPC_MAX_OBJECTS; - - for (i=0; iHandles[i] = *(buf+i); - r->WasHandleCopied[i] = (i < num_handles_copy); - } - - r->NumHandles = num_handles; - buf = buf_after_handles; - } - - size_t num_statics = (ctrl0 >> 16) & 15; - u32* buf_after_statics = buf + num_statics*2; - - if (num_statics > IPC_MAX_BUFFERS) - num_statics = IPC_MAX_BUFFERS; - - for (i=0; iPacked; - - r->Statics[i] = (void*) (desc->Addr | (((packed >> 12) & 15) << 32) | (((packed >> 6) & 15) << 36)); - r->StaticSizes[i] = packed >> 16; - r->StaticIndices[i] = packed & 63; - } - - r->NumStatics = num_statics; - buf = buf_after_statics; - - const size_t num_bufs_send = (ctrl0 >> 20) & 15; - const size_t num_bufs_recv = (ctrl0 >> 24) & 15; - const size_t num_bufs_exch = (ctrl0 >> 28) & 15; - - size_t num_bufs = num_bufs_send + num_bufs_recv + num_bufs_exch; - r->Raw = (void*)(((uintptr_t)(buf + num_bufs*3) + 15) &~ 15); - r->RawWithoutPadding = (void*)((uintptr_t)(buf + num_bufs*3)); - - if (num_bufs > IPC_MAX_BUFFERS) - num_bufs = IPC_MAX_BUFFERS; - - for (i=0; iPacked; - - r->Buffers[i] = (void*) (desc->Addr | ((packed >> 28) << 32) | (((packed >> 2) & 15) << 36)); - r->BufferSizes[i] = desc->Size; - r->BufferTypes[i] = (BufferType) (packed & 3); - - if (i < num_bufs_send) - r->BufferDirections[i] = BufferDirection_Send; - else if (i < (num_bufs_send + num_bufs_recv)) - r->BufferDirections[i] = BufferDirection_Recv; - else - r->BufferDirections[i] = BufferDirection_Exch; - } - - r->NumBuffers = num_bufs; - return 0; -} - -/** - * @brief Queries the size of an IPC pointer buffer. - * @param session IPC session handle. - * @param size Output variable in which to store the size. - * @return Result code. - */ -static inline Result ipcQueryPointerBufferSize(Handle session, size_t *size) { - u32* buf = (u32*)armGetTls(); - - buf[0] = IpcCommandType_Control; - buf[1] = 8; - buf[2] = 0; - buf[3] = 0; - buf[4] = SFCI_MAGIC; - buf[5] = 0; - buf[6] = 3; - buf[7] = 0; - - Result rc = ipcDispatch(session); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct ipcQueryPointerBufferSizeResponse { - u64 magic; - u64 result; - u32 size; - } *raw = (struct ipcQueryPointerBufferSizeResponse*)r.Raw; - - rc = raw->result; - - if (R_SUCCEEDED(rc)) { - *size = raw->size & 0xffff; - } - } - - return rc; -} - -/** - * @brief Closes the IPC session with proper clean up. - * @param session IPC session handle. - * @return Result code. - */ -static inline Result ipcCloseSession(Handle session) { - u32* buf = (u32*)armGetTls(); - buf[0] = IpcCommandType_Close; - buf[1] = 0; - return ipcDispatch(session); -} - -/** - * @brief Clones an IPC session. - * @param session IPC session handle. - * @param unk Unknown. - * @param new_session_out Output cloned IPC session handle. - * @return Result code. - */ -static inline Result ipcCloneSession(Handle session, u32 unk, Handle* new_session_out) { - u32* buf = (u32*)armGetTls(); - - buf[0] = IpcCommandType_Control; - buf[1] = 9; - buf[2] = 0; - buf[3] = 0; - buf[4] = SFCI_MAGIC; - buf[5] = 0; - buf[6] = 4; - buf[7] = 0; - buf[8] = unk; - - Result rc = ipcDispatch(session); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct ipcCloneSessionResponse { - u64 magic; - u64 result; - } *raw = (struct ipcCloneSessionResponse*)r.Raw; - - rc = raw->result; - - if (R_SUCCEEDED(rc) && new_session_out) { - *new_session_out = r.Handles[0]; - } - } - - return rc; -} - -///@} - -///@name IPC domain handling -///@{ - -/** - * @brief Converts an IPC session handle into a domain. - * @param session IPC session handle. - * @param object_id_out Output variable in which to store the object ID. - * @return Result code. - */ -static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_out) { - u32* buf = (u32*)armGetTls(); - - buf[0] = IpcCommandType_Control; - buf[1] = 8; - buf[4] = SFCI_MAGIC; - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - - Result rc = ipcDispatch(session); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct ipcConvertSessionToDomainResponse { - u64 magic; - u64 result; - u32 object_id; - } *raw = (struct ipcConvertSessionToDomainResponse*)r.Raw; - - rc = raw->result; - - if (R_SUCCEEDED(rc)) { - *object_id_out = raw->object_id; - } - } - - return rc; -} - -/** - * @brief Adds an object ID to be sent through an IPC domain command structure. - * @param cmd IPC domain command structure. - * @param object_id Object ID to send. - */ -static inline void ipcSendObjectId(IpcCommand* cmd, u32 object_id) { - cmd->ObjectIds[cmd->NumObjectIds++] = object_id; -} - -/** - * @brief Prepares the header of an IPC command structure (domain version). - * @param cmd IPC command structure. - * @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request - * @param object_id Domain object ID. - * @return Pointer to the raw embedded data structure in the request, ready to be filled out. - */ -static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, u32 object_id) { - void* raw = ipcPrepareHeader(cmd, sizeof_raw + sizeof(DomainMessageHeader) + cmd->NumObjectIds*sizeof(u32)); - DomainMessageHeader* hdr = (DomainMessageHeader*) raw; - u32 *object_ids = (u32*)(((uintptr_t) raw) + sizeof(DomainMessageHeader) + sizeof_raw); - - hdr->Type = DomainMessageType_SendMessage; - hdr->NumObjectIds = (u8)cmd->NumObjectIds; - hdr->Length = sizeof_raw; - hdr->ThisObjectId = object_id; - hdr->Pad[0] = hdr->Pad[1] = 0; - - for(size_t i = 0; i < cmd->NumObjectIds; i++) - object_ids[i] = cmd->ObjectIds[i]; - return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader)); -} - -/** - * @brief Parse an IPC command request into an IPC parsed command structure (domain version). - * @param r IPC parsed command structure to fill in. - * @return Result code. - */ -static inline Result ipcParseDomainRequest(IpcParsedCommand* r) { - Result rc = ipcParse(r); - DomainMessageHeader *hdr; - u32 *object_ids; - if(R_FAILED(rc)) - return rc; - - hdr = (DomainMessageHeader*) r->Raw; - object_ids = (u32*)(((uintptr_t) hdr) + sizeof(DomainMessageHeader) + hdr->Length); - r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainMessageHeader)); - - r->IsDomainRequest = true; - r->InMessageType = (DomainMessageType)(hdr->Type); - switch (r->InMessageType) { - case DomainMessageType_SendMessage: - case DomainMessageType_Close: - break; - default: - return MAKERESULT(Module_Libnx, LibnxError_DomainMessageUnknownType); - } - - r->InThisObjectId = hdr->ThisObjectId; - r->InNumObjectIds = hdr->NumObjectIds > 8 ? 8 : hdr->NumObjectIds; - if ((uintptr_t)object_ids + sizeof(u32) * r->InNumObjectIds - (uintptr_t)armGetTls() >= 0x100) { - return MAKERESULT(Module_Libnx, LibnxError_DomainMessageTooManyObjectIds); - } - for(size_t i = 0; i < r->InNumObjectIds; i++) - r->InObjectIds[i] = object_ids[i]; - - return rc; -} - -/** - * @brief Parse an IPC command response into an IPC parsed command structure (domain version). - * @param r IPC parsed command structure to fill in. - * @param sizeof_raw Size in bytes of the raw data structure. - * @return Result code. - */ -static inline Result ipcParseDomainResponse(IpcParsedCommand* r, size_t sizeof_raw) { - Result rc = ipcParse(r); - DomainResponseHeader *hdr; - u32 *object_ids; - if(R_FAILED(rc)) - return rc; - - hdr = (DomainResponseHeader*) r->Raw; - r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainResponseHeader)); - object_ids = (u32*)(((uintptr_t) r->Raw) + sizeof_raw);//Official sw doesn't align this. - - r->IsDomainResponse = true; - - r->OutNumObjectIds = hdr->NumObjectIds > 8 ? 8 : hdr->NumObjectIds; - if ((uintptr_t)object_ids + sizeof(u32) * r->OutNumObjectIds - (uintptr_t)armGetTls() >= 0x100) { - return MAKERESULT(Module_Libnx, LibnxError_DomainMessageTooManyObjectIds); - } - for(size_t i = 0; i < r->OutNumObjectIds; i++) - r->OutObjectIds[i] = object_ids[i]; - - return rc; -} - -/** - * @brief Closes a domain object by ID. - * @param session IPC session handle. - * @param object_id ID of the object to close. - * @return Result code. - */ -static inline Result ipcCloseObjectById(Handle session, u32 object_id) { - IpcCommand c; - DomainMessageHeader* hdr; - - ipcInitialize(&c); - hdr = (DomainMessageHeader*)ipcPrepareHeader(&c, sizeof(DomainMessageHeader)); - - hdr->Type = DomainMessageType_Close; - hdr->NumObjectIds = 0; - hdr->Length = 0; - hdr->ThisObjectId = object_id; - hdr->Pad[0] = hdr->Pad[1] = 0; - - return ipcDispatch(session); // this command has no associated response -} - -///@} diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/max17050.h b/Source/Horizon-OC-Monitor (deprecated)/include/max17050.h deleted file mode 100644 index e69ab9b1..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/max17050.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Fuel gauge driver for Nintendo Switch's Maxim 17050 - * - * Copyright (c) 2011 Samsung Electronics - * MyungJoo Ham - * Copyright (c) 2018-2020 CTCaer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Modified by: MasaGratoR - */ - -#ifndef __MAX17050_H_ -#define __MAX17050_H_ - -//#include -#include "i2c.h" - -/* Board default values */ -#define MAX17050_BOARD_CGAIN 2 /* Actual: 1.99993 */ -#define MAX17050_BOARD_SNS_RESISTOR_UOHM 5000 /* 0.005 Ohm */ - -//#define MAX17050_STATUS_BattAbsent BIT(3) - -/* Consider RepCap which is less then 10 units below FullCAP full */ -/* -#define MAX17050_FULL_THRESHOLD 10 - -#define MAX17050_CHARACTERIZATION_DATA_SIZE 48 - -#define MAXIM17050_I2C_ADDR 0x36 -*/ - -#define MAX17050_WAIT_NS 1000000000 - -constexpr float max17050SenseResistor = MAX17050_BOARD_SNS_RESISTOR_UOHM / 1000; // in uOhm -constexpr float max17050CGain = 1.99993; - - -enum MAX17050_reg { - MAX17050_STATUS = 0x00, - MAX17050_VALRT_Th = 0x01, - MAX17050_TALRT_Th = 0x02, - MAX17050_SALRT_Th = 0x03, - MAX17050_AtRate = 0x04, - MAX17050_RepCap = 0x05, - MAX17050_RepSOC = 0x06, - MAX17050_Age = 0x07, - MAX17050_TEMP = 0x08, - MAX17050_VCELL = 0x09, - MAX17050_Current = 0x0A, - MAX17050_AvgCurrent = 0x0B, - - MAX17050_SOC = 0x0D, - MAX17050_AvSOC = 0x0E, - MAX17050_RemCap = 0x0F, - MAX17050_FullCAP = 0x10, - MAX17050_TTE = 0x11, - MAX17050_QRTbl00 = 0x12, - MAX17050_FullSOCThr = 0x13, - MAX17050_RSLOW = 0x14, - - MAX17050_AvgTA = 0x16, - MAX17050_Cycles = 0x17, - MAX17050_DesignCap = 0x18, - MAX17050_AvgVCELL = 0x19, - MAX17050_MinMaxTemp = 0x1A, - MAX17050_MinMaxVolt = 0x1B, - MAX17050_MinMaxCurr = 0x1C, - MAX17050_CONFIG = 0x1D, - MAX17050_ICHGTerm = 0x1E, - MAX17050_AvCap = 0x1F, - MAX17050_ManName = 0x20, - MAX17050_DevName = 0x21, - MAX17050_QRTbl10 = 0x22, - MAX17050_FullCAPNom = 0x23, - MAX17050_TempNom = 0x24, - MAX17050_TempLim = 0x25, - MAX17050_TempHot = 0x26, - MAX17050_AIN = 0x27, - MAX17050_LearnCFG = 0x28, - MAX17050_FilterCFG = 0x29, - MAX17050_RelaxCFG = 0x2A, - MAX17050_MiscCFG = 0x2B, - MAX17050_TGAIN = 0x2C, - MAX17050_TOFF = 0x2D, - MAX17050_CGAIN = 0x2E, - MAX17050_COFF = 0x2F, - - MAX17050_QRTbl20 = 0x32, - MAX17050_SOC_empty = 0x33, - MAX17050_T_empty = 0x34, - MAX17050_FullCAP0 = 0x35, - MAX17050_LAvg_empty = 0x36, - MAX17050_FCTC = 0x37, - MAX17050_RCOMP0 = 0x38, - MAX17050_TempCo = 0x39, - MAX17050_V_empty = 0x3A, - MAX17050_K_empty0 = 0x3B, - MAX17050_TaskPeriod = 0x3C, - MAX17050_FSTAT = 0x3D, - MAX17050_TIMER = 0x3E, - MAX17050_SHDNTIMER = 0x3F, - - MAX17050_QRTbl30 = 0x42, - - MAX17050_dQacc = 0x45, - MAX17050_dPacc = 0x46, - - MAX17050_VFSOC0 = 0x48, - - Max17050_QH0 = 0x4C, - MAX17050_QH = 0x4D, - MAX17050_QL = 0x4E, - - MAX17050_MinVolt = 0x50, // Custom ID. Not to be sent to i2c. - MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c. - - MAX17050_VFSOC0Enable = 0x60, - MAX17050_MODELEnable1 = 0x62, - MAX17050_MODELEnable2 = 0x63, - - MAX17050_MODELChrTbl = 0x80, - - MAX17050_OCV = 0xEE, - - MAX17050_OCVInternal = 0xFB, - - MAX17050_VFSOC = 0xFF, -}; - -/* -int max17050_get_property(enum MAX17050_reg reg, int *value); -int max17050_fix_configuration(); -u32 max17050_get_cached_batt_volt(); -*/ -#endif /* __MAX17050_H_ */ - -Result Max17050ReadReg(u8 reg, u16 *out) -{ - u16 data = 0; - Result res = I2cReadRegHandler16(reg, I2cDevice_Max17050, &data); - - if (R_FAILED(res)) - { - return res; - } - - *out = data; - return res; -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/pcv_types.h b/Source/Horizon-OC-Monitor (deprecated)/include/pcv_types.h deleted file mode 100644 index 50d3e3ea..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/pcv_types.h +++ /dev/null @@ -1,41 +0,0 @@ -typedef enum { - PcvPowerDomain_Max77620_Sd0 = 0, - PcvPowerDomain_Max77620_Sd1 = 1, - PcvPowerDomain_Max77620_Sd2 = 2, - PcvPowerDomain_Max77620_Sd3 = 3, - PcvPowerDomain_Max77620_Ldo0 = 4, - PcvPowerDomain_Max77620_Ldo1 = 5, - PcvPowerDomain_Max77620_Ldo2 = 6, - PcvPowerDomain_Max77620_Ldo3 = 7, - PcvPowerDomain_Max77620_Ldo4 = 8, - PcvPowerDomain_Max77620_Ldo5 = 9, - PcvPowerDomain_Max77620_Ldo6 = 10, - PcvPowerDomain_Max77620_Ldo7 = 11, - PcvPowerDomain_Max77620_Ldo8 = 12, - PcvPowerDomain_Max77621_Cpu = 13, - PcvPowerDomain_Max77621_Gpu = 14, - PcvPowerDomain_Max77812_Cpu = 15, - PcvPowerDomain_Max77812_Gpu = 16, - PcvPowerDomain_Max77812_Dram = 17, -} PowerDomain; - -typedef enum { - PcvPowerDomainId_Max77620_Sd0 = 0x3A000080, - PcvPowerDomainId_Max77620_Sd1 = 0x3A000081, - PcvPowerDomainId_Max77620_Sd2 = 0x3A000082, - PcvPowerDomainId_Max77620_Sd3 = 0x3A000083, - PcvPowerDomainId_Max77620_Ldo0 = 0x3A0000A0, - PcvPowerDomainId_Max77620_Ldo1 = 0x3A0000A1, - PcvPowerDomainId_Max77620_Ldo2 = 0x3A0000A2, - PcvPowerDomainId_Max77620_Ldo3 = 0x3A0000A3, - PcvPowerDomainId_Max77620_Ldo4 = 0x3A0000A4, - PcvPowerDomainId_Max77620_Ldo5 = 0x3A0000A5, - PcvPowerDomainId_Max77620_Ldo6 = 0x3A0000A6, - PcvPowerDomainId_Max77620_Ldo7 = 0x3A0000A7, - PcvPowerDomainId_Max77620_Ldo8 = 0x3A0000A8, - PcvPowerDomainId_Max77621_Cpu = 0x3A000003, - PcvPowerDomainId_Max77621_Gpu = 0x3A000004, - PcvPowerDomainId_Max77812_Cpu = 0x3A000003, - PcvPowerDomainId_Max77812_Gpu = 0x3A000004, - PcvPowerDomainId_Max77812_Dram = 0x3A000005, -} PowerDomainId; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/pwm.h b/Source/Horizon-OC-Monitor (deprecated)/include/pwm.h deleted file mode 100644 index 559ff873..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/pwm.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - Service s; -} PwmChannelSession; - -Result pwmInitialize(void); -void pwmExit(void); -Service* pwmGetServiceSession(void); -Result pwmOpenSession2(PwmChannelSession *out, u32 device_code); -Result pwmChannelSessionGetDutyCycle(PwmChannelSession *c, double* out); -void pwmChannelSessionClose(PwmChannelSession *c); - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/rgltr.h b/Source/Horizon-OC-Monitor (deprecated)/include/rgltr.h deleted file mode 100644 index dd57f4c5..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/rgltr.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include -#include "pcv_types.h" - -typedef struct { - Service s; -} RgltrSession; - -Result rgltrInitialize(void); - -void rgltrExit(void); - -Service* rgltrGetServiceSession(void); - -Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id); -void rgltrCloseSession(RgltrSession* session); -Result rgltrGetVoltage(RgltrSession* session, u32 *out_volt); -Result rgltrGetPowerModuleNumLimit(u32 *out); -Result rgltrGetVoltageEnabled(RgltrSession* session, u32 *out); diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/rgltr_services.h b/Source/Horizon-OC-Monitor (deprecated)/include/rgltr_services.h deleted file mode 100644 index 32becbf8..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/rgltr_services.h +++ /dev/null @@ -1,29 +0,0 @@ -// rgltr_services.h -// ======== -// Minimal header declarations for rgltr‐related functionality. -// Any file that wants to call rgltrOpenSession(), rgltrGetVoltage(), etc. should -// simply do `#include "infonx.h"` (NOT infonx.cpp). - -#pragma once - -#include // for Service, Result, hosversionBefore(), smGetService(), serviceClose(), etc. -#include "rgltr.h" // for RgltrSession, PowerDomainId, etc. - -// Global service handle for "rgltr". Defined in infonx.cpp. -extern Service g_rgltrSrv; - -// Open/close the "rgltr" service. You must call rgltrInitialize() (once) before using -// rgltrOpenSession() & friends. Call rgltrExit() when your app is shutting down. -Result rgltrInitialize(void); -void rgltrExit(void); - -// Open a regulator session for the given PowerDomainId (e.g. CPU, GPU, DRAM). -// On success, (*session_out).s will contain a valid Service handle. -Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id); - -// Query the current voltage (in microvolts, µV) from a previously opened session. -// Writes the result into *out_volt. -Result rgltrGetVoltage(RgltrSession* session, u32* out_volt); - -// Close a previously opened regulator session. -void rgltrCloseSession(RgltrSession* session); diff --git a/Source/Horizon-OC-Monitor (deprecated)/include/tmp451.h b/Source/Horizon-OC-Monitor (deprecated)/include/tmp451.h deleted file mode 100644 index 507585da..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/include/tmp451.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SOC/PCB Temperature driver for Nintendo Switch's TI TMP451 - * - * Copyright (c) 2018 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - * Modified by: MasaGratoR - */ - -#ifndef __TMP451_H_ -#define __TMP451_H_ - -//#include -#include "i2c.h" - -//#define TMP451_I2C_ADDR 0x4C - -#define TMP451_PCB_TEMP_REG 0x00 -#define TMP451_SOC_TEMP_REG 0x01 - -/* -#define TMP451_CONFIG_REG 0x09 -#define TMP451_CNV_RATE_REG 0x0A -*/ - -#define TMP451_SOC_TEMP_DEC_REG 0x10 -#define TMP451_PCB_TEMP_DEC_REG 0x15 - -/* -#define TMP451_SOC_TMP_OFH_REG 0x11 -#define TMP451_SOC_TMP_OFL_REG 0x12 -*/ - -// If input is false, the return value is packed. MSByte is the integer in oC -// and the LSByte is the decimal point truncated to 2 decimal places. -// Otherwise it's an integer oC. -/* -u16 tmp451_get_soc_temp(bool integer); -u16 tmp451_get_pcb_temp(bool integer); -void tmp451_init(); -void tmp451_end(); -*/ - -Result Tmp451ReadReg(u8 reg, u8 *out) -{ - u8 data = 0; - Result res = I2cReadRegHandler8(reg, I2cDevice_Tmp451, &data); - - if (R_FAILED(res)) - { - return res; - } - - *out = data; - return res; -} - -Result Tmp451GetSocTemp(float* temperature) { - u8 integer = 0; - u8 decimals = 0; - - Result rc = Tmp451ReadReg(TMP451_SOC_TEMP_REG, &integer); - if (R_FAILED(rc)) - return rc; - rc = Tmp451ReadReg(TMP451_SOC_TEMP_DEC_REG, &decimals); - if (R_FAILED(rc)) - return rc; - - decimals = ((u16)(decimals >> 4) * 625) / 100; - *temperature = (float)(integer) + ((float)(decimals) / 100); - return rc; -} - -Result Tmp451GetPcbTemp(float* temperature) { - u8 integer = 0; - u8 decimals = 0; - - Result rc = Tmp451ReadReg(TMP451_PCB_TEMP_REG, &integer); - if (R_FAILED(rc)) - return rc; - rc = Tmp451ReadReg(TMP451_PCB_TEMP_DEC_REG, &decimals); - if (R_FAILED(rc)) - return rc; - - decimals = ((u16)(decimals >> 4) * 625) / 100; - *temperature = (float)(integer) + ((float)(decimals) / 100); - return rc; -} - -#endif /* __TMP451_H_ */ diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/de.json b/Source/Horizon-OC-Monitor (deprecated)/lang/de.json deleted file mode 100644 index f7c9a332..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/de.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modi", - "Modes   Configure": "Modi   Konfigurieren", - "Full": "Voll", - "Mini": "Mini", - "Micro": "Mikro", - "FPS Graph": "FPS-Diagramm", - "FPS Counter": "FPS-Zähler", - "Game Resolutions": "Spielauflösungen", - "Other": "Sonstiges", - "Battery/Charger": "Akku/Ladegerät", - "Miscellaneous": "Verschiedenes", - "CPU Usage": "CPU-Auslastung", - "GPU Usage": "GPU-Auslastung", - "RAM Usage": "RAM-Auslastung", - "Target Frequency": "Ziel-Frequenz", - "Real Frequency": "Aktuelle Frequenz", - "Core 0 ": "Kern 0 ", - "Core 1 ": "Kern 1 ", - "Core 2 ": "Kern 2 ", - "Core 3 ": "Kern 3 ", - "Load": "Auslastung", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Gesamt\nAnwendung\nApplet\nSystem\nSystem (unsicher)", - "Board": "Board", - "Battery Power Flow": "Akkuleistungsfluss", - "\nTemperatures": "\nTemperaturen", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Lüfterdrehzahl", - "Game": "Spiel", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Auflösungen ", - "Read Speed ": "Lesegeschwindigkeit ", - "Press ": "Drücke ", - " to Exit": " zum Beenden", - "Depth": "Tiefe", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Spiel läuft nicht\noder ist inkompatibel.", - "Battery Stats": "Akkustatistiken", - "Actual Capacity": "Aktuelle Kapazität", - "Designed Capacity": "Nennkapazität", - "Temperature": "Temperatur", - "Raw Charge": "Rohladung", - "Age": "Alter", - "Voltage": "Spannung", - "Current Flow": "Stromfluss", - "Power Flow": "Leistungsfluss", - "Remaining Time": "Verbleibende Zeit", - "Charger Stats": "Ladegerät-Statistiken", - "Input Current Limit": "Eingangsstrombegrenzung", - "VBUS Current Limit": "VBUS-Strombegrenzung", - "Voltage Limit": "Spannungsbegrenzung", - "Current Limit": "Strombegrenzung", - "Type": "Typ", - "Max Voltage": "Max. Spannung", - "Max Current": "Max. Strom", - "Multimedia Clock Rates": "Multimedia-Taktraten", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Netzwerk", - "Type: Wi-Fi": "Typ: Wi-Fi", - "Press Y to show password": "Drücke Y, um Passwort anzuzeigen", - "Type: Ethernet": "Typ: Ethernet", - "Type: Not connected": "Typ: Nicht verbunden", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elemente   Nach unten   Nach oben", - "Transparent": "Transparent", - "Opaque": "Undurchsichtig", - "Alpha": "Alpha", - "Pretty": "Hübsch", - "Compact": "Kompakt", - "FileSafe": "Dateisicher", - "Day+Time": "Tag+Uhrzeit", - "Date+Time(s)": "Datum+Uhrzeit(s)", - "Date+Time AM/PM": "Datum+Uhrzeit AM/PM", - "Date+Time(s) AM/PM": "Datum+Uhrzeit(s) AM/PM", - "Date+Time EU": "Datum+Uhrzeit EU", - "Date+Time EU AM/PM": "Datum+Uhrzeit EU AM/PM", - "Date+Time(s) EU AM/PM": "Datum+Uhrzeit(s) EU AM/PM", - "Date+Time ISO": "Datum+Uhrzeit ISO", - "Time 24h": "Uhrzeit 24h", - "Time AM/PM": "Uhrzeit AM/PM", - "Time(s) 24h": "Uhrzeit(s) 24h", - "Time(s) AM/PM": "Uhrzeit(s) AM/PM", - "Date US": "Datum US", - "Date EU": "Datum EU", - "Date ISO": "Datum ISO", - "Date Short": "Datum kurz", - "DTC Format": "DTC-Format", - "Toggles": "Schalter", - "Info": "Info anzeigen", - "Disable Screenshots": "Bildschirmfotos deaktivieren", - "Real Freqs": "Aktuelle Frequenzen", - "Deltas": "Deltas", - "Target Freqs": "Ziel-Frequenzen", - "FPS": "FPS", - "RES": "AUFL", - "Read Speed": "Lesegeschwindigkeit", - "Real Frequencies": "Aktuelle Frequenzen", - "Real Voltages": "Aktuelle Spannungen", - "Full CPU": "Volle CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Volle Auflösung", - "SOC Voltage": "SOC-Spannung", - "RAM Load CPU/GPU": "RAM-Last CPU/GPU", - "Use DTC Symbol": "DTC-Symbol verwenden", - "Use Dynamic Colors": "Dynamische Farben verwenden", - "Sleep Exit": "Beenden aus Ruhezustand", - "Configuration": "Konfiguration", - "Refresh Rate": "Bildwiederholrate", - "Frame Padding": "Rahmenabstand", - " Font Size": " Schriftgröße", - "Font Sizes": "Schriftgrößen", - "Handheld Font Size": "Handheld-Schriftgröße", - "Docked Font Size": "Docked-Schriftgröße", - "Black": "Schwarz", - "Dark Gray": "Dunkelgrau", - "Gray": "Grau", - "Light Gray": "Hellgrau", - "Silver": "Silber", - "White": "Weiß", - "Dark Red": "Dunkelrot", - "Red": "Rot", - "Light Red": "Hellrot", - "Pink": "Pink", - "Dark Green": "Dunkelgrün", - "Green": "Grün", - "Lime Green": "Limette", - "Light Green": "Hellgrün", - "Dark Blue": "Dunkelblau", - "Blue": "Blau", - "Light Blue": "Hellblau", - "Sky Blue": "Himmelblau", - "Dark Purple": "Dunkellila", - "Purple": "Lila", - "Light Purple": "Helllila", - "Violet": "Violett", - "Orange": "Orange", - "Yellow": "Gelb", - "Light Yellow": "Hellgelb", - "Teal": "Petrol", - "Cyan": "Cyan", - "Light Cyan": "Hellcyan", - "Magenta": "Magenta", - "Hot Pink": "Knallpink", - "Brown": "Braun", - "Light Brown": "Hellbraun", - "Colors": "Farben", - "Background Color": "Hintergrundfarbe", - "Background Alpha": "Hintergrund-Alpha", - "Focus Color": "Fokusfarbe", - "Focus Alpha": "Fokus-Alpha", - "Text Color": "Textfarbe", - "Border": "Rahmen", - "Dashed Line": "Gestrichelte Linie", - "Max FPS Text": "Max-FPS-Text", - "Min FPS Text": "Min-FPS-Text", - "Main Line": "Hauptlinie", - "Rounded Line": "Abgerundete Linie", - "Perfect Line": "Perfekte Linie", - " Color": " Farbe", - " Alpha": " Alpha", - "Category Color": "Kategoriefarbe", - "Category Color 1": "Kategoriefarbe 1", - "Category Color 2": "Kategoriefarbe 2", - "Separator Color": "Trennlinienfarbe", - "Elements": "Elemente", - "Text Alignment": "Textausrichtung", - "Vertical Position": "Vertikale Position", - "Horizontal Position": "Horizontale Position", - "Left": "Links", - "Right": "Rechts", - "Top": "Oben", - "Center": "Mitte", - "Bottom": "Unten", - "FPS Counter Color": "FPS-Zähler-Farbe", - "FPS Counter Alpha": "FPS-Zähler-Alpha", - "Border Color": "Rahmenfarbe", - "Dashed Line Color": "Gestrichelte-Linie-Farbe", - "Dashed Line Alpha": "Gestrichelte-Linie-Alpha", - "Max FPS Text Color": "Max-FPS-Textfarbe", - "Min FPS Text Color": "Min-FPS-Textfarbe", - "Main Line Color": "Hauptlinienfarbe", - "Rounded Line Color": "Abgerundete-Linienfarbe", - "Perfect Line Color": "Perfekte-Linienfarbe" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/en.json b/Source/Horizon-OC-Monitor (deprecated)/lang/en.json deleted file mode 100644 index 836b8f0d..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/en.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modes", - "Modes   Configure": "Modes   Configure", - "Full": "Full", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "FPS Graph", - "FPS Counter": "FPS Counter", - "Game Resolutions": "Game Resolutions", - "Other": "Other", - "Battery/Charger": "Battery/Charger", - "Miscellaneous": "Miscellaneous", - "CPU Usage": "CPU Usage", - "GPU Usage": "GPU Usage", - "RAM Usage": "RAM Usage", - "Target Frequency": "Target Frequency", - "Real Frequency": "Real Frequency", - "Core 0 ": "Core 0 ", - "Core 1 ": "Core 1 ", - "Core 2 ": "Core 2 ", - "Core 3 ": "Core 3 ", - "Load": "Load", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Total\nApplication\nApplet\nSystem\nSystem Unsafe", - "Board": "Board", - "Battery Power Flow": "Battery Power Flow", - "\nTemperatures": "\nTemperatures", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Fan Rotation Level", - "Game": "Game", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Resolutions ", - "Read Speed ": "Read speed ", - "Press ": "Press ", - " to Exit": " to Exit", - "Depth": "Depth", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Game is not running\nor it's incompatible.", - "Battery Stats": "Battery Stats", - "Actual Capacity": "Actual Capacity", - "Designed Capacity": "Designed Capacity", - "Temperature": "Temperature", - "Raw Charge": "Raw Charge", - "Age": "Age", - "Voltage": "Voltage", - "Current Flow": "Current Flow", - "Power Flow": "Power Flow", - "Remaining Time": "Remaining Time", - "Charger Stats": "Charger Stats", - "Input Current Limit": "Input Current Limit", - "VBUS Current Limit": "VBUS Current Limit", - "Voltage Limit": "Voltage Limit", - "Current Limit": "Current Limit", - "Type": "Type", - "Max Voltage": "Max Voltage", - "Max Current": "Max Current", - "Multimedia Clock Rates": "Multimedia Clock Rates", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Network", - "Type: Wi-Fi": "Type: Wi-Fi", - "Press Y to show password": "Press Y to show password", - "Type: Ethernet": "Type: Ethernet", - "Type: Not connected": "Tipo: Not connected", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elements   Move Down   Move Up", - "Transparent": "Transparent", - "Opaque": "Opaque", - "Alpha": "Alpha", - "Pretty": "Pretty", - "Compact": "Compact", - "FileSafe": "FileSafe", - "Day+Time": "Day+Time", - "Date+Time(s)": "Date+Time(s)", - "Date+Time AM/PM": "Date+Time AM/PM", - "Date+Time(s) AM/PM": "Date+Time(s) AM/PM", - "Date+Time EU": "Date+Time EU", - "Date+Time EU AM/PM": "Date+Time EU AM/PM", - "Date+Time(s) EU AM/PM": "Date+Time(s) EU AM/PM", - "Date+Time ISO": "Date+Time ISO", - "Time 24h": "Time 24h", - "Time AM/PM": "Time AM/PM", - "Time(s) 24h": "Time(s) 24h", - "Time(s) AM/PM": "Time(s) AM/PM", - "Date US": "Date US", - "Date EU": "Date EU", - "Date ISO": "Date ISO", - "Date Short": "Date Short", - "DTC Format": "DTC Format", - "Toggles": "Toggles", - "Info": "Show Info", - "Disable Screenshots": "Disable Screenshots", - "Real Freqs": "Real Freqs", - "Deltas": "Deltas", - "Target Freqs": "Target Freqs", - "FPS": "FPS", - "RES": "RES", - "Read Speed": "Read Speed", - "Real Frequencies": "Real Frequencies", - "Real Voltages": "Real Voltages", - "Full CPU": "Full CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Full Resolution", - "SOC Voltage": "SOC Voltage", - "RAM Load CPU/GPU": "RAM Load CPU/GPU", - "Use DTC Symbol": "Use DTC Symbol", - "Use Dynamic Colors": "Use Dynamic Colors", - "Sleep Exit": "Sleep Exit", - "Configuration": "Configuration", - "Refresh Rate": "Refresh Rate", - "Frame Padding": "Frame Padding", - " Font Size": " Font Size", - "Font Sizes": "Font Sizes", - "Handheld Font Size": "Handheld Font Size", - "Docked Font Size": "Docked Font Size", - "Black": "Black", - "Dark Gray": "Dark Gray", - "Gray": "Gray", - "Light Gray": "Light Gray", - "Silver": "Silver", - "White": "White", - "Dark Red": "Dark Red", - "Red": "Red", - "Light Red": "Light Red", - "Pink": "Pink", - "Dark Green": "Dark Green", - "Green": "Green", - "Lime Green": "Lime Green", - "Light Green": "Light Green", - "Dark Blue": "Dark Blue", - "Blue": "Blue", - "Light Blue": "Light Blue", - "Sky Blue": "Sky Blue", - "Dark Purple": "Dark Purple", - "Purple": "Purple", - "Light Purple": "Light Purple", - "Violet": "Violet", - "Orange": "Orange", - "Yellow": "Yellow", - "Light Yellow": "Light Yellow", - "Teal": "Teal", - "Cyan": "Cyan", - "Light Cyan": "Light Cyan", - "Magenta": "Magenta", - "Hot Pink": "Hot Pink", - "Brown": "Brown", - "Light Brown": "Light Brown", - "Colors": "Colors", - "Background Color": "Background Color", - "Background Alpha": "Background Alpha", - "Focus Color": "Focus Color", - "Focus Alpha": "Focus Alpha", - "Text Color": "Text Color", - "Border": "Border", - "Dashed Line": "Dashed Line", - "Max FPS Text": "Max FPS Text", - "Min FPS Text": "Min FPS Text", - "Main Line": "Main Line", - "Rounded Line": "Rounded Line", - "Perfect Line": "Perfect Line", - " Color": " Color", - " Alpha": " Alpha", - "Category Color": "Category Color", - "Category Color 1": "Category Color 1", - "Category Color 2": "Category Color 2", - "Separator Color": "Separator Color", - "Elements": "Elements", - "Text Alignment": "Text Alignment", - "Vertical Position": "Vertical Position", - "Horizontal Position": "Horizontal Position", - "Left": "Left", - "Right": "Right", - "Top": "Top", - "Center": "Center", - "Bottom": "Bottom", - "FPS Counter Color":"FPS Counter Color", - "FPS Counter Alpha":"FPS Counter Alpha", - "Border Color":"Border Color", - "Dashed Line Color":"Dashed Line Color", - "Dashed Line Alpha":"Dashed Line Alpha", - "Max FPS Text Color":"Max FPS Text Color", - "Min FPS Text Color":"Min FPS Text Color", - "Main Line Color":"Main Line Color", - "Rounded Line Color":"Rounded Line Color", - "Perfect Line Color":"Perfect Line Color" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/es.json b/Source/Horizon-OC-Monitor (deprecated)/lang/es.json deleted file mode 100644 index bacf1152..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/es.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modos", - "Modes   Configure": "Modos   Configurar", - "Full": "Completo", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "Gráfico FPS", - "FPS Counter": "Contador FPS", - "Game Resolutions": "Resoluciones del juego", - "Other": "Otros", - "Battery/Charger": "Batería/Cargador", - "Miscellaneous": "Varios", - "CPU Usage": "Uso de CPU", - "GPU Usage": "Uso de GPU", - "RAM Usage": "Uso de RAM", - "Target Frequency": "Frecuencia objetivo", - "Real Frequency": "Frecuencia real", - "Core 0 ": "Núcleo 0 ", - "Core 1 ": "Núcleo 1 ", - "Core 2 ": "Núcleo 2 ", - "Core 3 ": "Núcleo 3 ", - "Load": "Carga", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Total\nAplicación\nApplet\nSistema\nSistema (inseguro)", - "Board": "Placa", - "Battery Power Flow": "Flujo de energía de batería", - "\nTemperatures": "\nTemperaturas", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Nivel de rotación del ventilador", - "Game": "Juego", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Resoluciones ", - "Read Speed ": "Velocidad de lectura ", - "Press ": "Pulsa ", - " to Exit": " para salir", - "Depth": "Profundidad", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "El juego no está en ejecución\no es incompatible.", - "Battery Stats": "Estadísticas de batería", - "Actual Capacity": "Capacidad actual", - "Designed Capacity": "Capacidad nominal", - "Temperature": "Temperatura", - "Raw Charge": "Carga bruta", - "Age": "Edad", - "Voltage": "Voltaje", - "Current Flow": "Flujo de corriente", - "Power Flow": "Flujo de potencia", - "Remaining Time": "Tiempo restante", - "Charger Stats": "Estadísticas del cargador", - "Input Current Limit": "Límite de corriente de entrada", - "VBUS Current Limit": "Límite de corriente VBUS", - "Voltage Limit": "Límite de voltaje", - "Current Limit": "Límite de corriente", - "Type": "Tipo", - "Max Voltage": "Voltaje máx.", - "Max Current": "Corriente máx.", - "Multimedia Clock Rates": "Frecuencias de reloj multimedia", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Red", - "Type: Wi-Fi": "Tipo: Wi-Fi", - "Press Y to show password": "Pulsa Y para mostrar contraseña", - "Type: Ethernet": "Tipo: Ethernet", - "Type: Not connected": "Tipo: No conectado", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elementos   Bajar   Subir", - "Transparent": "Transparente", - "Opaque": "Opaco", - "Alpha": "Alfa", - "Pretty": "Bonito", - "Compact": "Compacto", - "FileSafe": "FileSafe", - "Day+Time": "Día+Hora", - "Date+Time(s)": "Fecha+Hora(s)", - "Date+Time AM/PM": "Fecha+Hora AM/PM", - "Date+Time(s) AM/PM": "Fecha+Hora(s) AM/PM", - "Date+Time EU": "Fecha+Hora EU", - "Date+Time EU AM/PM": "Fecha+Hora EU AM/PM", - "Date+Time(s) EU AM/PM": "Fecha+Hora(s) EU AM/PM", - "Date+Time ISO": "Fecha+Hora ISO", - "Time 24h": "Hora 24h", - "Time AM/PM": "Hora AM/PM", - "Time(s) 24h": "Hora(s) 24h", - "Time(s) AM/PM": "Hora(s) AM/PM", - "Date US": "Fecha EE.UU.", - "Date EU": "Fecha EU", - "Date ISO": "Fecha ISO", - "Date Short": "Fecha corta", - "DTC Format": "Formato DTC", - "Toggles": "Conmutadores", - "Info": "Mostrar info", - "Disable Screenshots": "Desactivar capturas", - "Real Freqs": "Frecuencias reales", - "Deltas": "Deltas", - "Target Freqs": "Frecuencias objetivo", - "FPS": "FPS", - "RES": "RES", - "Read Speed": "Velocidad de lectura", - "Real Frequencies": "Frecuencias reales", - "Real Voltages": "Voltajes reales", - "Full CPU": "CPU completo", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Resolución completa", - "SOC Voltage": "Voltaje SOC", - "RAM Load CPU/GPU": "Carga RAM CPU/GPU", - "Use DTC Symbol": "Usar símbolo DTC", - "Use Dynamic Colors": "Usar colores dinámicos", - "Sleep Exit": "Salir del reposo", - "Configuration": "Configuración", - "Refresh Rate": "Tasa de refresco", - "Frame Padding": "Relleno de marco", - " Font Size": " Tamaño de fuente", - "Font Sizes": "Tamaños de fuente", - "Handheld Font Size": "Tamaño fuente portátil", - "Docked Font Size": "Tamaño fuente acoplado", - "Black": "Negro", - "Dark Gray": "Gris oscuro", - "Gray": "Gris", - "Light Gray": "Gris claro", - "Silver": "Plata", - "White": "Blanco", - "Dark Red": "Rojo oscuro", - "Red": "Rojo", - "Light Red": "Rojo claro", - "Pink": "Rosa", - "Dark Green": "Verde oscuro", - "Green": "Verde", - "Lime Green": "Verde lima", - "Light Green": "Verde claro", - "Dark Blue": "Azul oscuro", - "Blue": "Azul", - "Light Blue": "Azul claro", - "Sky Blue": "Azul cielo", - "Dark Purple": "Púrpura oscuro", - "Purple": "Púrpura", - "Light Purple": "Púrpura claro", - "Violet": "Violeta", - "Orange": "Naranja", - "Yellow": "Amarillo", - "Light Yellow": "Amarillo claro", - "Teal": "Verde azulado", - "Cyan": "Cian", - "Light Cyan": "Cian claro", - "Magenta": "Magenta", - "Hot Pink": "Rosa intenso", - "Brown": "Marrón", - "Light Brown": "Marrón claro", - "Colors": "Colores", - "Background Color": "Color de fondo", - "Background Alpha": "Alfa de fondo", - "Focus Color": "Color de foco", - "Focus Alpha": "Alfa de foco", - "Text Color": "Color de texto", - "Border": "Borde", - "Dashed Line": "Línea discontinua", - "Max FPS Text": "Texto FPS máx.", - "Min FPS Text": "Texto FPS mín.", - "Main Line": "Línea principal", - "Rounded Line": "Línea redondeada", - "Perfect Line": "Línea perfecta", - " Color": " Color", - " Alpha": " Alfa", - "Category Color": "Color de categoría", - "Category Color 1": "Color categoría 1", - "Category Color 2": "Color categoría 2", - "Separator Color": "Color separador", - "Elements": "Elementos", - "Text Alignment": "Alineación de texto", - "Vertical Position": "Posición vertical", - "Horizontal Position": "Posición horizontal", - "Left": "Izquierda", - "Right": "Derecha", - "Top": "Arriba", - "Center": "Centro", - "Bottom": "Abajo", - "FPS Counter Color": "Color contador FPS", - "FPS Counter Alpha": "Alfa contador FPS", - "Border Color": "Color de borde", - "Dashed Line Color": "Color línea discontinua", - "Dashed Line Alpha": "Alfa línea discontinua", - "Max FPS Text Color": "Color texto FPS máx.", - "Min FPS Text Color": "Color texto FPS mín.", - "Main Line Color": "Color línea principal", - "Rounded Line Color": "Color línea redondeada", - "Perfect Line Color": "Color línea perfecta" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/fr.json b/Source/Horizon-OC-Monitor (deprecated)/lang/fr.json deleted file mode 100644 index 95bc2d9e..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/fr.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modes", - "Modes   Configure": "Modes   Configurer", - "Full": "Complet", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "Graphique FPS", - "FPS Counter": "Compteur FPS", - "Game Resolutions": "Résolutions du jeu", - "Other": "Autres", - "Battery/Charger": "Batterie/Chargeur", - "Miscellaneous": "Divers", - "CPU Usage": "Utilisation CPU", - "GPU Usage": "Utilisation GPU", - "RAM Usage": "Utilisation RAM", - "Target Frequency": "Fréquence cible", - "Real Frequency": "Fréquence réelle", - "Core 0 ": "Cœur 0 ", - "Core 1 ": "Cœur 1 ", - "Core 2 ": "Cœur 2 ", - "Core 3 ": "Cœur 3 ", - "Load": "Charge", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Total\nApplication\nApplet\nSystème\nSystème non sécurisé", - "Board": "Carte", - "Battery Power Flow": "Flux de puissance batterie", - "\nTemperatures": "\nTempératures", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Niveau de rotation ventilateur", - "Game": "Jeu", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Résolutions ", - "Read Speed ": "Vitesse de lecture ", - "Press ": "Appuyez sur ", - " to Exit": " pour quitter", - "Depth": "Profondeur", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Le jeu ne fonctionne pas\nou est incompatible.", - "Battery Stats": "Statistiques batterie", - "Actual Capacity": "Capacité actuelle", - "Designed Capacity": "Capacité nominale", - "Temperature": "Température", - "Raw Charge": "Charge brute", - "Age": "Âge", - "Voltage": "Tension", - "Current Flow": "Flux de courant", - "Power Flow": "Flux de puissance", - "Remaining Time": "Temps restant", - "Charger Stats": "Statistiques chargeur", - "Input Current Limit": "Limite courant entrée", - "VBUS Current Limit": "Limite courant VBUS", - "Voltage Limit": "Limite tension", - "Current Limit": "Limite courant", - "Type": "Type", - "Max Voltage": "Tension max", - "Max Current": "Courant max", - "Multimedia Clock Rates": "Fréquences horloge multimédia", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Réseau", - "Type: Wi-Fi": "Type : Wi-Fi", - "Press Y to show password": "Appuyez sur Y pour afficher le mot de passe", - "Type: Ethernet": "Type : Ethernet", - "Type: Not connected": "Type : Non connecté", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Éléments   Descendre   Monter", - "Transparent": "Transparent", - "Opaque": "Opaque", - "Alpha": "Alpha", - "Pretty": "Joli", - "Compact": "Compact", - "FileSafe": "FileSafe", - "Day+Time": "Jour+Heure", - "Date+Time(s)": "Date+Heure(s)", - "Date+Time AM/PM": "Date+Heure AM/PM", - "Date+Time(s) AM/PM": "Date+Heure(s) AM/PM", - "Date+Time EU": "Date+Heure EU", - "Date+Time EU AM/PM": "Date+Heure EU AM/PM", - "Date+Time(s) EU AM/PM": "Date+Heure(s) EU AM/PM", - "Date+Time ISO": "Date+Heure ISO", - "Time 24h": "Heure 24h", - "Time AM/PM": "Heure AM/PM", - "Time(s) 24h": "Heure(s) 24h", - "Time(s) AM/PM": "Heure(s) AM/PM", - "Date US": "Date US", - "Date EU": "Date EU", - "Date ISO": "Date ISO", - "Date Short": "Date courte", - "DTC Format": "Format DTC", - "Toggles": "Basculement", - "Info": "Afficher infos", - "Disable Screenshots": "Désactiver captures d'écran", - "Real Freqs": "Fréquences réelles", - "Deltas": "Deltas", - "Target Freqs": "Fréquences cibles", - "FPS": "FPS", - "RES": "RÉS", - "Read Speed": "Vitesse de lecture", - "Real Frequencies": "Fréquences réelles", - "Real Voltages": "Tensions réelles", - "Full CPU": "CPU complet", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Résolution complète", - "SOC Voltage": "Tension SOC", - "RAM Load CPU/GPU": "Charge RAM CPU/GPU", - "Use DTC Symbol": "Utiliser symbole DTC", - "Use Dynamic Colors": "Utiliser couleurs dynamiques", - "Sleep Exit": "Sortie veille", - "Configuration": "Configuration", - "Refresh Rate": "Taux de rafraîchissement", - "Frame Padding": "Marge de cadre", - " Font Size": " Taille police", - "Font Sizes": "Tailles de police", - "Handheld Font Size": "Taille police portable", - "Docked Font Size": "Taille police dockée", - "Black": "Noir", - "Dark Gray": "Gris foncé", - "Gray": "Gris", - "Light Gray": "Gris clair", - "Silver": "Argent", - "White": "Blanc", - "Dark Red": "Rouge foncé", - "Red": "Rouge", - "Light Red": "Rouge clair", - "Pink": "Rose", - "Dark Green": "Vert foncé", - "Green": "Vert", - "Lime Green": "Vert citron", - "Light Green": "Vert clair", - "Dark Blue": "Bleu foncé", - "Blue": "Bleu", - "Light Blue": "Bleu clair", - "Sky Blue": "Bleu ciel", - "Dark Purple": "Violet foncé", - "Purple": "Violet", - "Light Purple": "Violet clair", - "Violet": "Violet", - "Orange": "Orange", - "Yellow": "Jaune", - "Light Yellow": "Jaune clair", - "Teal": "Sarcelle", - "Cyan": "Cyan", - "Light Cyan": "Cyan clair", - "Magenta": "Magenta", - "Hot Pink": "Rose vif", - "Brown": "Marron", - "Light Brown": "Marron clair", - "Colors": "Couleurs", - "Background Color": "Couleur d'arrière-plan", - "Background Alpha": "Alpha d'arrière-plan", - "Focus Color": "Couleur de focus", - "Focus Alpha": "Alpha de focus", - "Text Color": "Couleur du texte", - "Border": "Bordure", - "Dashed Line": "Ligne pointillée", - "Max FPS Text": "Texte FPS max", - "Min FPS Text": "Texte FPS min", - "Main Line": "Ligne principale", - "Rounded Line": "Ligne arrondie", - "Perfect Line": "Ligne parfaite", - " Color": " Couleur", - " Alpha": " Alpha", - "Category Color": "Couleur de catégorie", - "Category Color 1": "Couleur catégorie 1", - "Category Color 2": "Couleur catégorie 2", - "Separator Color": "Couleur de séparateur", - "Elements": "Éléments", - "Text Alignment": "Alignement du texte", - "Vertical Position": "Position verticale", - "Horizontal Position": "Position horizontale", - "Left": "Gauche", - "Right": "Droite", - "Top": "Haut", - "Center": "Centre", - "Bottom": "Bas", - "FPS Counter Color": "Couleur compteur FPS", - "FPS Counter Alpha": "Alpha compteur FPS", - "Border Color": "Couleur de bordure", - "Dashed Line Color": "Couleur ligne pointillée", - "Dashed Line Alpha": "Alpha ligne pointillée", - "Max FPS Text Color": "Couleur texte FPS max", - "Min FPS Text Color": "Couleur texte FPS min", - "Main Line Color": "Couleur ligne principale", - "Rounded Line Color": "Couleur ligne arrondie", - "Perfect Line Color": "Couleur ligne parfaite" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/it.json b/Source/Horizon-OC-Monitor (deprecated)/lang/it.json deleted file mode 100644 index 3a76ba57..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/it.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modalità", - "Modes   Configure": "Modalità   Configura", - "Full": "Completo", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "Grafico FPS", - "FPS Counter": "Contatore FPS", - "Game Resolutions": "Risoluzioni di gioco", - "Other": "Altro", - "Battery/Charger": "Batteria/Caricatore", - "Miscellaneous": "Varie", - "CPU Usage": "Utilizzo CPU", - "GPU Usage": "Utilizzo GPU", - "RAM Usage": "Utilizzo RAM", - "Target Frequency": "Frequenza target", - "Real Frequency": "Frequenza reale", - "Core 0 ": "Core 0 ", - "Core 1 ": "Core 1 ", - "Core 2 ": "Core 2 ", - "Core 3 ": "Core 3 ", - "Load": "Carico", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Totale\nApplicazione\nApplet\nSistema\nSistema non sicuro", - "Board": "Scheda", - "Battery Power Flow": "Flusso potenza batteria", - "\nTemperatures": "\nTemperature", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Livello rotazione ventola", - "Game": "Gioco", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Risoluzioni ", - "Read Speed ": "Velocità di lettura ", - "Press ": "Premi ", - " to Exit": " per uscire", - "Depth": "Profondità", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Il gioco non è in esecuzione\no è incompatibile.", - "Battery Stats": "Statistiche batteria", - "Actual Capacity": "Capacità attuale", - "Designed Capacity": "Capacità nominale", - "Temperature": "Temperatura", - "Raw Charge": "Carica grezza", - "Age": "Età", - "Voltage": "Voltaggio", - "Current Flow": "Flusso corrente", - "Power Flow": "Flusso potenza", - "Remaining Time": "Tempo rimanente", - "Charger Stats": "Statistiche caricatore", - "Input Current Limit": "Limite corrente ingresso", - "VBUS Current Limit": "Limite corrente VBUS", - "Voltage Limit": "Limite tensione", - "Current Limit": "Limite corrente", - "Type": "Tipo", - "Max Voltage": "Tensione max", - "Max Current": "Corrente max", - "Multimedia Clock Rates": "Frequenze clock multimediali", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Rete", - "Type: Wi-Fi": "Tipo: Wi-Fi", - "Press Y to show password": "Premi Y per mostrare la password", - "Type: Ethernet": "Tipo: Ethernet", - "Type: Not connected": "Tipo: Non connesso", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elementi   Sposta giù   Sposta su", - "Transparent": "Trasparente", - "Opaque": "Opaco", - "Alpha": "Alfa", - "Pretty": "Carino", - "Compact": "Compatto", - "FileSafe": "FileSafe", - "Day+Time": "Giorno+Ora", - "Date+Time(s)": "Data+Ora(s)", - "Date+Time AM/PM": "Data+Ora AM/PM", - "Date+Time(s) AM/PM": "Data+Ora(s) AM/PM", - "Date+Time EU": "Data+Ora EU", - "Date+Time EU AM/PM": "Data+Ora EU AM/PM", - "Date+Time(s) EU AM/PM": "Data+Ora(s) EU AM/PM", - "Date+Time ISO": "Data+Ora ISO", - "Time 24h": "Ora 24h", - "Time AM/PM": "Ora AM/PM", - "Time(s) 24h": "Ora(s) 24h", - "Time(s) AM/PM": "Ora(s) AM/PM", - "Date US": "Data US", - "Date EU": "Data EU", - "Date ISO": "Data ISO", - "Date Short": "Data breve", - "DTC Format": "Formato DTC", - "Toggles": "Interruttori", - "Info": "Mostra info", - "Disable Screenshots": "Disabilita screenshot", - "Real Freqs": "Frequenze reali", - "Deltas": "Delta", - "Target Freqs": "Frequenze target", - "FPS": "FPS", - "RES": "RIS", - "Read Speed": "Velocità di lettura", - "Real Frequencies": "Frequenze reali", - "Real Voltages": "Voltaggi reali", - "Full CPU": "CPU completo", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Risoluzione completa", - "SOC Voltage": "Voltaggio SOC", - "RAM Load CPU/GPU": "Carico RAM CPU/GPU", - "Use DTC Symbol": "Usa simbolo DTC", - "Use Dynamic Colors": "Usa colori dinamici", - "Sleep Exit": "Uscita standby", - "Configuration": "Configurazione", - "Refresh Rate": "Frequenza di aggiornamento", - "Frame Padding": "Spaziatura cornice", - " Font Size": " Dimensione font", - "Font Sizes": "Dimensioni font", - "Handheld Font Size": "Dimensione font portatile", - "Docked Font Size": "Dimensione font docked", - "Black": "Nero", - "Dark Gray": "Grigio scuro", - "Gray": "Grigio", - "Light Gray": "Grigio chiaro", - "Silver": "Argento", - "White": "Bianco", - "Dark Red": "Rosso scuro", - "Red": "Rosso", - "Light Red": "Rosso chiaro", - "Pink": "Rosa", - "Dark Green": "Verde scuro", - "Green": "Verde", - "Lime Green": "Verde lime", - "Light Green": "Verde chiaro", - "Dark Blue": "Blu scuro", - "Blue": "Blu", - "Light Blue": "Azzurro", - "Sky Blue": "Azzurro cielo", - "Dark Purple": "Viola scuro", - "Purple": "Viola", - "Light Purple": "Viola chiaro", - "Violet": "Viola", - "Orange": "Arancione", - "Yellow": "Giallo", - "Light Yellow": "Giallo chiaro", - "Teal": "Verde acqua", - "Cyan": "Ciano", - "Light Cyan": "Ciano chiaro", - "Magenta": "Magenta", - "Hot Pink": "Rosa shocking", - "Brown": "Marrone", - "Light Brown": "Marrone chiaro", - "Colors": "Colori", - "Background Color": "Colore sfondo", - "Background Alpha": "Alfa sfondo", - "Focus Color": "Colore focus", - "Focus Alpha": "Alfa focus", - "Text Color": "Colore testo", - "Border": "Bordo", - "Dashed Line": "Linea tratteggiata", - "Max FPS Text": "Testo FPS max", - "Min FPS Text": "Testo FPS min", - "Main Line": "Linea principale", - "Rounded Line": "Linea arrotondata", - "Perfect Line": "Linea perfetta", - " Color": " Colore", - " Alpha": " Alfa", - "Category Color": "Colore categoria", - "Category Color 1": "Colore categoria 1", - "Category Color 2": "Colore categoria 2", - "Separator Color": "Colore separatore", - "Elements": "Elementi", - "Text Alignment": "Allineamento testo", - "Vertical Position": "Posizione verticale", - "Horizontal Position": "Posizione orizzontale", - "Left": "Sinistra", - "Right": "Destra", - "Top": "Sopra", - "Center": "Centro", - "Bottom": "Sotto", - "FPS Counter Color": "Colore contatore FPS", - "FPS Counter Alpha": "Alfa contatore FPS", - "Border Color": "Colore bordo", - "Dashed Line Color": "Colore linea tratteggiata", - "Dashed Line Alpha": "Alfa linea tratteggiata", - "Max FPS Text Color": "Colore testo FPS max", - "Min FPS Text Color": "Colore testo FPS min", - "Main Line Color": "Colore linea principale", - "Rounded Line Color": "Colore linea arrotondata", - "Perfect Line Color": "Colore linea perfetta" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/ja.json b/Source/Horizon-OC-Monitor (deprecated)/lang/ja.json deleted file mode 100644 index a4000d02..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/ja.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "モード", - "Modes   Configure": "モード   設定", - "Full": "フル", - "Mini": "ミニ", - "Micro": "マイクロ", - "FPS Graph": "FPSグラフ", - "FPS Counter": "FPSカウンター", - "Game Resolutions": "ゲーム解像度", - "Other": "その他", - "Battery/Charger": "バッテリー/充電器", - "Miscellaneous": "その他", - "CPU Usage": "CPU使用率", - "GPU Usage": "GPU使用率", - "RAM Usage": "RAM使用率", - "Target Frequency": "目標周波数", - "Real Frequency": "実際の周波数", - "Core 0 ": "コア 0 ", - "Core 1 ": "コア 1 ", - "Core 2 ": "コア 2 ", - "Core 3 ": "コア 3 ", - "Load": "負荷", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "合計\nアプリケーション\nアプレット\nシステム\nシステム(非安全)", - "Board": "ボード", - "Battery Power Flow": "バッテリー電力フロー", - "\nTemperatures": "\n温度", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "ファン回転レベル", - "Game": "ゲーム", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "解像度 ", - "Read Speed ": "読み込み速度 ", - "Press ": "押す ", - " to Exit": " で終了", - "Depth": "深度", - "Viewport": "ビューポート", - "Game is not running\nor it's incompatible.": "ゲームが実行されていない\nまたは非対応です。", - "Battery Stats": "バッテリー統計", - "Actual Capacity": "実際の容量", - "Designed Capacity": "設計容量", - "Temperature": "温度", - "Raw Charge": "生充電量", - "Age": "経年", - "Voltage": "電圧", - "Current Flow": "電流フロー", - "Power Flow": "電力フロー", - "Remaining Time": "残り時間", - "Charger Stats": "充電器統計", - "Input Current Limit": "入力電流制限", - "VBUS Current Limit": "VBUS電流制限", - "Voltage Limit": "電圧制限", - "Current Limit": "電流制限", - "Type": "タイプ", - "Max Voltage": "最大電圧", - "Max Current": "最大電流", - "Multimedia Clock Rates": "マルチメディアクロックレート", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "ネットワーク", - "Type: Wi-Fi": "タイプ: Wi-Fi", - "Press Y to show password": "Yを押してパスワードを表示", - "Type: Ethernet": "タイプ: Ethernet", - "Type: Not connected": "タイプ: 未接続", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "要素   下へ   上へ", - "Transparent": "透明", - "Opaque": "不透明", - "Alpha": "アルファ", - "Pretty": "プリティ", - "Compact": "コンパクト", - "FileSafe": "ファイルセーフ", - "Day+Time": "日+時間", - "Date+Time(s)": "日付+時間(s)", - "Date+Time AM/PM": "日付+時間 AM/PM", - "Date+Time(s) AM/PM": "日付+時間(s) AM/PM", - "Date+Time EU": "日付+時間 EU", - "Date+Time EU AM/PM": "日付+時間 EU AM/PM", - "Date+Time(s) EU AM/PM": "日付+時間(s) EU AM/PM", - "Date+Time ISO": "日付+時間 ISO", - "Time 24h": "時間 24h", - "Time AM/PM": "時間 AM/PM", - "Time(s) 24h": "時間(s) 24h", - "Time(s) AM/PM": "時間(s) AM/PM", - "Date US": "日付 US", - "Date EU": "日付 EU", - "Date ISO": "日付 ISO", - "Date Short": "短い日付", - "DTC Format": "DTC形式", - "Toggles": "トグル", - "Info": "情報表示", - "Disable Screenshots": "スクリーンショット無効", - "Real Freqs": "実際の周波数", - "Deltas": "デルタ", - "Target Freqs": "目標周波数", - "FPS": "FPS", - "RES": "解像度", - "Read Speed": "読み込み速度", - "Real Frequencies": "実際の周波数", - "Real Voltages": "実際の電圧", - "Full CPU": "フルCPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "フル解像度", - "SOC Voltage": "SOC電圧", - "RAM Load CPU/GPU": "RAM負荷 CPU/GPU", - "Use DTC Symbol": "DTCシンボル使用", - "Use Dynamic Colors": "ダイナミックカラー使用", - "Sleep Exit": "スリープ解除", - "Configuration": "設定", - "Refresh Rate": "リフレッシュレート", - "Frame Padding": "フレームパディング", - " Font Size": " フォントサイズ", - "Font Sizes": "フォントサイズ", - "Handheld Font Size": "携帯モードフォントサイズ", - "Docked Font Size": "ドックモードフォントサイズ", - "Black": "黒", - "Dark Gray": "ダークグレー", - "Gray": "グレー", - "Light Gray": "ライトグレー", - "Silver": "シルバー", - "White": "白", - "Dark Red": "ダークレッド", - "Red": "赤", - "Light Red": "ライト レッド", - "Pink": "ピンク", - "Dark Green": "ダークグリーン", - "Green": "緑", - "Lime Green": "ライムグリーン", - "Light Green": "ライトグリーン", - "Dark Blue": "ダークブルー", - "Blue": "青", - "Light Blue": "ライトブルー", - "Sky Blue": "スカイブルー", - "Dark Purple": "ダークパープル", - "Purple": "パープル", - "Light Purple": "ライトパープル", - "Violet": "バイオレット", - "Orange": "オレンジ", - "Yellow": "黄", - "Light Yellow": "ライトイエロー", - "Teal": "ティール", - "Cyan": "シアン", - "Light Cyan": "ライトシアン", - "Magenta": "マゼンタ", - "Hot Pink": "ホットピンク", - "Brown": "ブラウン", - "Light Brown": "ライトブラウン", - "Colors": "色", - "Background Color": "背景色", - "Background Alpha": "背景アルファ", - "Focus Color": "フォーカス色", - "Focus Alpha": "フォーカスアルファ", - "Text Color": "文字色", - "Border": "枠線", - "Dashed Line": "破線", - "Max FPS Text": "最大FPSテキスト", - "Min FPS Text": "最小FPSテキスト", - "Main Line": "主線", - "Rounded Line": "丸角線", - "Perfect Line": "完璧線", - " Color": " 色", - " Alpha": " アルファ", - "Category Color": "カテゴリ色", - "Category Color 1": "カテゴリ色 1", - "Category Color 2": "カテゴリ色 2", - "Separator Color": "セパレータ色", - "Elements": "要素", - "Text Alignment": "テキスト配置", - "Vertical Position": "垂直位置", - "Horizontal Position": "水平位置", - "Left": "左", - "Right": "右", - "Top": "上", - "Center": "中央", - "Bottom": "下", - "FPS Counter Color": "FPSカウンター色", - "FPS Counter Alpha": "FPSカウンターアルファ", - "Border Color": "枠線色", - "Dashed Line Color": "破線色", - "Dashed Line Alpha": "破線アルファ", - "Max FPS Text Color": "最大FPSテキスト色", - "Min FPS Text Color": "最小FPSテキスト色", - "Main Line Color": "主線色", - "Rounded Line Color": "丸角線色", - "Perfect Line Color": "完璧線色" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/ko.json b/Source/Horizon-OC-Monitor (deprecated)/lang/ko.json deleted file mode 100644 index a001d36d..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/ko.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "모드", - "Modes   Configure": "모드   설정", - "Full": "전체", - "Mini": "미니", - "Micro": "마이크로", - "FPS Graph": "FPS 그래프", - "FPS Counter": "FPS 카운터", - "Game Resolutions": "게임 해상도", - "Other": "기타", - "Battery/Charger": "배터리/충전기", - "Miscellaneous": "기타", - "CPU Usage": "CPU 사용량", - "GPU Usage": "GPU 사용량", - "RAM Usage": "RAM 사용량", - "Target Frequency": "목표 주파수", - "Real Frequency": "실제 주파수", - "Core 0 ": "코어 0 ", - "Core 1 ": "코어 1 ", - "Core 2 ": "코어 2 ", - "Core 3 ": "코어 3 ", - "Load": "부하", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "합계\n앱\n애플릿\n시스템\n시스템(비안전)", - "Board": "보드", - "Battery Power Flow": "배터리 전력 흐름", - "\nTemperatures": "\n온도", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "팬 회전 레벨", - "Game": "게임", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "해상도 ", - "Read Speed ": "읽기 속도 ", - "Press ": "누르기 ", - " to Exit": " 종료", - "Depth": "깊이", - "Viewport": "뷰포트", - "Game is not running\nor it's incompatible.": "게임이 실행 중이 아니거나\n호환되지 않습니다.", - "Battery Stats": "배터리 통계", - "Actual Capacity": "실제 용량", - "Designed Capacity": "설계 용량", - "Temperature": "온도", - "Raw Charge": "원시 충전량", - "Age": "수명", - "Voltage": "전압", - "Current Flow": "전류 흐름", - "Power Flow": "전력 흐름", - "Remaining Time": "남은 시간", - "Charger Stats": "충전기 통계", - "Input Current Limit": "입력 전류 제한", - "VBUS Current Limit": "VBUS 전류 제한", - "Voltage Limit": "전압 제한", - "Current Limit": "전류 제한", - "Type": "유형", - "Max Voltage": "최대 전압", - "Max Current": "최대 전류", - "Multimedia Clock Rates": "멀티미디어 클럭 속도", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "네트워크", - "Type: Wi-Fi": "유형: Wi-Fi", - "Press Y to show password": "Y를 눌러 비밀번호 표시", - "Type: Ethernet": "유형: 이더넷", - "Type: Not connected": "유형: 연결 안 됨", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "요소   아래로   위로", - "Transparent": "투명", - "Opaque": "불투명", - "Alpha": "알파", - "Pretty": "예쁨", - "Compact": "컴팩트", - "FileSafe": "파일세이프", - "Day+Time": "일+시간", - "Date+Time(s)": "날짜+시간(s)", - "Date+Time AM/PM": "날짜+시간 AM/PM", - "Date+Time(s) AM/PM": "날짜+시간(s) AM/PM", - "Date+Time EU": "날짜+시간 EU", - "Date+Time EU AM/PM": "날짜+시간 EU AM/PM", - "Date+Time(s) EU AM/PM": "날짜+시간(s) EU AM/PM", - "Date+Time ISO": "날짜+시간 ISO", - "Time 24h": "시간 24시", - "Time AM/PM": "시간 AM/PM", - "Time(s) 24h": "시간(s) 24시", - "Time(s) AM/PM": "시간(s) AM/PM", - "Date US": "날짜 US", - "Date EU": "날짜 EU", - "Date ISO": "날짜 ISO", - "Date Short": "짧은 날짜", - "DTC Format": "DTC 형식", - "Toggles": "토글", - "Info": "정보 표시", - "Disable Screenshots": "스크린샷 비활성화", - "Real Freqs": "실제 주파수", - "Deltas": "델타", - "Target Freqs": "목표 주파수", - "FPS": "FPS", - "RES": "해상도", - "Read Speed": "읽기 속도", - "Real Frequencies": "실제 주파수", - "Real Voltages": "실제 전압", - "Full CPU": "전체 CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "전체 해상도", - "SOC Voltage": "SOC 전압", - "RAM Load CPU/GPU": "RAM 부하 CPU/GPU", - "Use DTC Symbol": "DTC 심볼 사용", - "Use Dynamic Colors": "동적 색상 사용", - "Sleep Exit": "절전 종료", - "Configuration": "설정", - "Refresh Rate": "리프레시 레이트", - "Frame Padding": "프레임 패딩", - " Font Size": " 글꼴 크기", - "Font Sizes": "글꼴 크기", - "Handheld Font Size": "핸드헬드 글꼴 크기", - "Docked Font Size": "도킹 글꼴 크기", - "Black": "검정", - "Dark Gray": "짙은 회색", - "Gray": "회색", - "Light Gray": "밝은 회색", - "Silver": "은색", - "White": "흰색", - "Dark Red": "짙은 빨강", - "Red": "빨강", - "Light Red": "밝은 빨강", - "Pink": "분홍", - "Dark Green": "짙은 초록", - "Green": "초록", - "Lime Green": "라임 그린", - "Light Green": "밝은 초록", - "Dark Blue": "짙은 파랑", - "Blue": "파랑", - "Light Blue": "밝은 파랑", - "Sky Blue": "하늘색", - "Dark Purple": "짙은 보라", - "Purple": "보라", - "Light Purple": "밝은 보라", - "Violet": "바이올렛", - "Orange": "주황", - "Yellow": "노랑", - "Light Yellow": "밝은 노랑", - "Teal": "청록", - "Cyan": "시안", - "Light Cyan": "밝은 시안", - "Magenta": "마젠타", - "Hot Pink": "핫핑크", - "Brown": "갈색", - "Light Brown": "밝은 갈색", - "Colors": "색상", - "Background Color": "배경색", - "Background Alpha": "배경 투명도", - "Focus Color": "포커스 색상", - "Focus Alpha": "포커스 투명도", - "Text Color": "텍스트 색상", - "Border": "테두리", - "Dashed Line": "점선", - "Max FPS Text": "최대 FPS 텍스트", - "Min FPS Text": "최소 FPS 텍스트", - "Main Line": "주선", - "Rounded Line": "둥근 선", - "Perfect Line": "완벽 선", - " Color": " 색상", - " Alpha": " 투명도", - "Category Color": "카테고리 색상", - "Category Color 1": "카테고리 색상 1", - "Category Color 2": "카테고리 색상 2", - "Separator Color": "구분선 색상", - "Elements": "요소", - "Text Alignment": "텍스트 정렬", - "Vertical Position": "세로 위치", - "Horizontal Position": "가로 위치", - "Left": "왼쪽", - "Right": "오른쪽", - "Top": "위", - "Center": "가운데", - "Bottom": "아래", - "FPS Counter Color": "FPS 카운터 색상", - "FPS Counter Alpha": "FPS 카운터 투명도", - "Border Color": "테두리 색상", - "Dashed Line Color": "점선 색상", - "Dashed Line Alpha": "점선 투명도", - "Max FPS Text Color": "최대 FPS 텍스트 색상", - "Min FPS Text Color": "최소 FPS 텍스트 색상", - "Main Line Color": "주선 색상", - "Rounded Line Color": "둥근 선 색상", - "Perfect Line Color": "완벽 선 색상" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/nl.json b/Source/Horizon-OC-Monitor (deprecated)/lang/nl.json deleted file mode 100644 index febfacdc..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/nl.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modi", - "Modes   Configure": "Modi   Configureren", - "Full": "Volledig", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "FPS-grafiek", - "FPS Counter": "FPS-teller", - "Game Resolutions": "Spelresoluties", - "Other": "Overig", - "Battery/Charger": "Batterij/Oplader", - "Miscellaneous": "Diversen", - "CPU Usage": "CPU-gebruik", - "GPU Usage": "GPU-gebruik", - "RAM Usage": "RAM-gebruik", - "Target Frequency": "Doelfrequentie", - "Real Frequency": "Werkelijke frequentie", - "Core 0 ": "Kern 0 ", - "Core 1 ": "Kern 1 ", - "Core 2 ": "Kern 2 ", - "Core 3 ": "Kern 3 ", - "Load": "Belasting", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Totaal\nApplicatie\nApplet\nSysteem\nSysteem onveilig", - "Board": "Bord", - "Battery Power Flow": "Batterijstroom", - "\nTemperatures": "\nTemperaturen", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Ventilatorrotatieniveau", - "Game": "Spel", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Resoluties ", - "Read Speed ": "Leessnelheid ", - "Press ": "Druk op ", - " to Exit": " om af te sluiten", - "Depth": "Diepte", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Spel draait niet\nof is incompatibel.", - "Battery Stats": "Batterijstatistieken", - "Actual Capacity": "Werkelijke capaciteit", - "Designed Capacity": "Ontworpen capaciteit", - "Temperature": "Temperatuur", - "Raw Charge": "Ruwe lading", - "Age": "Leeftijd", - "Voltage": "Spanning", - "Current Flow": "Stroomstroom", - "Power Flow": "Stroomverbruik", - "Remaining Time": "Resterende tijd", - "Charger Stats": "Opladerstatistieken", - "Input Current Limit": "Ingangsstroomlimiet", - "VBUS Current Limit": "VBUS-stroomlimiet", - "Voltage Limit": "Spanningslimiet", - "Current Limit": "Stroomlimiet", - "Type": "Type", - "Max Voltage": "Max spanning", - "Max Current": "Max stroom", - "Multimedia Clock Rates": "Multimedia kloksnelheden", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Netwerk", - "Type: Wi-Fi": "Type: Wi-Fi", - "Press Y to show password": "Druk op Y om wachtwoord te tonen", - "Type: Ethernet": "Type: Ethernet", - "Type: Not connected": "Type: Niet verbonden", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elementen   Omlaag verplaatsen   Omhoog verplaatsen", - "Transparent": "Transparant", - "Opaque": "Ondoorzichtig", - "Alpha": "Alpha", - "Pretty": "Mooi", - "Compact": "Compact", - "FileSafe": "FileSafe", - "Day+Time": "Dag+Tijd", - "Date+Time(s)": "Datum+Tijd(s)", - "Date+Time AM/PM": "Datum+Tijd AM/PM", - "Date+Time(s) AM/PM": "Datum+Tijd(s) AM/PM", - "Date+Time EU": "Datum+Tijd EU", - "Date+Time EU AM/PM": "Datum+Tijd EU AM/PM", - "Date+Time(s) EU AM/PM": "Datum+Tijd(s) EU AM/PM", - "Date+Time ISO": "Datum+Tijd ISO", - "Time 24h": "Tijd 24u", - "Time AM/PM": "Tijd AM/PM", - "Time(s) 24h": "Tijd(s) 24u", - "Time(s) AM/PM": "Tijd(s) AM/PM", - "Date US": "Datum VS", - "Date EU": "Datum EU", - "Date ISO": "Datum ISO", - "Date Short": "Datum kort", - "DTC Format": "DTC-formaat", - "Toggles": "Schakelaars", - "Info": "Info tonen", - "Disable Screenshots": "Schermafbeeldingen uitschakelen", - "Real Freqs": "Werkelijke frequenties", - "Deltas": "Delta's", - "Target Freqs": "Doelfrequenties", - "FPS": "FPS", - "RES": "RES", - "Read Speed": "Leessnelheid", - "Real Frequencies": "Werkelijke frequenties", - "Real Voltages": "Werkelijke spanningen", - "Full CPU": "Volledige CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Volledige resolutie", - "SOC Voltage": "SOC-spanning", - "RAM Load CPU/GPU": "RAM-belasting CPU/GPU", - "Use DTC Symbol": "DTC-symbool gebruiken", - "Use Dynamic Colors": "Dynamische kleuren gebruiken", - "Sleep Exit": "Slaap afsluiten", - "Configuration": "Configuratie", - "Refresh Rate": "Vernieuwingsfrequentie", - "Frame Padding": "Frame opvulling", - " Font Size": " Lettergrootte", - "Font Sizes": "Lettergroottes", - "Handheld Font Size": "Handheld lettergrootte", - "Docked Font Size": "Docked lettergrootte", - "Black": "Zwart", - "Dark Gray": "Donkergrijs", - "Gray": "Grijs", - "Light Gray": "Lichtgrijs", - "Silver": "Zilver", - "White": "Wit", - "Dark Red": "Donkerrood", - "Red": "Rood", - "Light Red": "Lichtrood", - "Pink": "Roze", - "Dark Green": "Donkergroen", - "Green": "Groen", - "Lime Green": "Limoengroen", - "Light Green": "Lichtgroen", - "Dark Blue": "Donkerblauw", - "Blue": "Blauw", - "Light Blue": "Lichtblauw", - "Sky Blue": "Hemelsblauw", - "Dark Purple": "Donkerpaars", - "Purple": "Paars", - "Light Purple": "Lichtpaars", - "Violet": "Violet", - "Orange": "Oranje", - "Yellow": "Geel", - "Light Yellow": "Lichtgeel", - "Teal": "Teal", - "Cyan": "Cyaan", - "Light Cyan": "Lichtcyaan", - "Magenta": "Magenta", - "Hot Pink": "Felroze", - "Brown": "Bruin", - "Light Brown": "Lichtbruin", - "Colors": "Kleuren", - "Background Color": "Achtergrondkleur", - "Background Alpha": "Achtergrond alpha", - "Focus Color": "Focuskleur", - "Focus Alpha": "Focus alpha", - "Text Color": "Tekstkleur", - "Border": "Rand", - "Dashed Line": "Gestippelde lijn", - "Max FPS Text": "Max FPS tekst", - "Min FPS Text": "Min FPS tekst", - "Main Line": "Hoofdlijn", - "Rounded Line": "Afgeronde lijn", - "Perfect Line": "Perfecte lijn", - " Color": " Kleur", - " Alpha": " Alpha", - "Category Color": "Categoriekleur", - "Category Color 1": "Categoriekleur 1", - "Category Color 2": "Categoriekleur 2", - "Separator Color": "Scheidingskleur", - "Elements": "Elementen", - "Text Alignment": "Tekstuitlijning", - "Vertical Position": "Verticale positie", - "Horizontal Position": "Horizontale positie", - "Left": "Links", - "Right": "Rechts", - "Top": "Boven", - "Center": "Midden", - "Bottom": "Onder", - "FPS Counter Color":"FPS-tellerkleur", - "FPS Counter Alpha":"FPS-teller alpha", - "Border Color":"Randkleur", - "Dashed Line Color":"Gestippelde lijnkleur", - "Dashed Line Alpha":"Gestippelde lijn alpha", - "Max FPS Text Color":"Max FPS tekstkleur", - "Min FPS Text Color":"Min FPS tekstkleur", - "Main Line Color":"Hoofdlijnkleur", - "Rounded Line Color":"Afgeronde lijnkleur", - "Perfect Line Color":"Perfecte lijnkleur" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/pl.json b/Source/Horizon-OC-Monitor (deprecated)/lang/pl.json deleted file mode 100644 index e2dd49e5..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/pl.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Tryby", - "Modes   Configure": "Tryby   Konfiguruj", - "Full": "Pełny", - "Mini": "Mini", - "Micro": "Mikro", - "FPS Graph": "Wykres FPS", - "FPS Counter": "Licznik FPS", - "Game Resolutions": "Rozdzielczości gry", - "Other": "Inne", - "Battery/Charger": "Bateria/Ładowarka", - "Miscellaneous": "Różne", - "CPU Usage": "Użycie CPU", - "GPU Usage": "Użycie GPU", - "RAM Usage": "Użycie RAM", - "Target Frequency": "Częstotliwość docelowa", - "Real Frequency": "Rzeczywista częstotliwość", - "Core 0 ": "Rdzeń 0 ", - "Core 1 ": "Rdzeń 1 ", - "Core 2 ": "Rdzeń 2 ", - "Core 3 ": "Rdzeń 3 ", - "Load": "Obciążenie", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Razem\nAplikacja\nApplet\nSystem\nSystem (niebezpieczny)", - "Board": "Płyta", - "Battery Power Flow": "Przepływ mocy baterii", - "\nTemperatures": "\nTemperatury", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Poziom obrotów wentylatora", - "Game": "Gra", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Rozdzielczości ", - "Read Speed ": "Prędkość odczytu ", - "Press ": "Naciśnij ", - " to Exit": " aby wyjść", - "Depth": "Głębia", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Gra nie jest uruchomiona\nlub jest niekompatybilna.", - "Battery Stats": "Statystyki baterii", - "Actual Capacity": "Rzeczywista pojemność", - "Designed Capacity": "Pojemność znamionowa", - "Temperature": "Temperatura", - "Raw Charge": "Surowy poziom naładowania", - "Age": "Wiek", - "Voltage": "Napięcie", - "Current Flow": "Przepływ prądu", - "Power Flow": "Przepływ mocy", - "Remaining Time": "Pozostały czas", - "Charger Stats": "Statystyki ładowarki", - "Input Current Limit": "Limit prądu wejściowego", - "VBUS Current Limit": "Limit prądu VBUS", - "Voltage Limit": "Limit napięcia", - "Current Limit": "Limit prądu", - "Type": "Typ", - "Max Voltage": "Maks. napięcie", - "Max Current": "Maks. prąd", - "Multimedia Clock Rates": "Taktowanie multimediów", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Sieć", - "Type: Wi-Fi": "Typ: Wi-Fi", - "Press Y to show password": "Naciśnij Y, aby pokazać hasło", - "Type: Ethernet": "Typ: Ethernet", - "Type: Not connected": "Typ: Nie połączono", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elementy   Przesuń w dół   Przesuń w górę", - "Transparent": "Przezroczysty", - "Opaque": "Nieprzezroczysty", - "Alpha": "Alfa", - "Pretty": "Ładny", - "Compact": "Kompaktowy", - "FileSafe": "FileSafe", - "Day+Time": "Dzień+Czas", - "Date+Time(s)": "Data+Czas(s)", - "Date+Time AM/PM": "Data+Czas AM/PM", - "Date+Time(s) AM/PM": "Data+Czas(s) AM/PM", - "Date+Time EU": "Data+Czas EU", - "Date+Time EU AM/PM": "Data+Czas EU AM/PM", - "Date+Time(s) EU AM/PM": "Data+Czas(s) EU AM/PM", - "Date+Time ISO": "Data+Czas ISO", - "Time 24h": "Czas 24h", - "Time AM/PM": "Czas AM/PM", - "Time(s) 24h": "Czas(s) 24h", - "Time(s) AM/PM": "Czas(s) AM/PM", - "Date US": "Data US", - "Date EU": "Data EU", - "Date ISO": "Data ISO", - "Date Short": "Krótka data", - "DTC Format": "Format DTC", - "Toggles": "Przełączniki", - "Info": "Pokaż informacje", - "Disable Screenshots": "Wyłącz zrzuty ekranu", - "Real Freqs": "Rzeczywiste częstotliwości", - "Deltas": "Delty", - "Target Freqs": "Docelowe częstotliwości", - "FPS": "FPS", - "RES": "ROZDZ.", - "Read Speed": "Prędkość odczytu", - "Real Frequencies": "Rzeczywiste częstotliwości", - "Real Voltages": "Rzeczywiste napięcia", - "Full CPU": "Pełny CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Pełna rozdzielczość", - "SOC Voltage": "Napięcie SOC", - "RAM Load CPU/GPU": "Obciążenie RAM CPU/GPU", - "Use DTC Symbol": "Użyj symbolu DTC", - "Use Dynamic Colors": "Użyj dynamicznych kolorów", - "Sleep Exit": "Wyjście z uśpienia", - "Configuration": "Konfiguracja", - "Refresh Rate": "Częstotliwość odświeżania", - "Frame Padding": "Wypełnienie ramki", - " Font Size": " Rozmiar czcionki", - "Font Sizes": "Rozmiary czcionki", - "Handheld Font Size": "Rozmiar czcionki w trybie przenośnym", - "Docked Font Size": "Rozmiar czcionki w trybie stacjonarnym", - "Black": "Czarny", - "Dark Gray": "Ciemnoszary", - "Gray": "Szary", - "Light Gray": "Jasnoszary", - "Silver": "Srebrny", - "White": "Biały", - "Dark Red": "Ciemnoczerwony", - "Red": "Czerwony", - "Light Red": "Jasnoczerwony", - "Pink": "Różowy", - "Dark Green": "Ciemnozielony", - "Green": "Zielony", - "Lime Green": "Limonkowy", - "Light Green": "Jasnozielony", - "Dark Blue": "Ciemnoniebieski", - "Blue": "Niebieski", - "Light Blue": "Jasnoniebieski", - "Sky Blue": "Błękitny", - "Dark Purple": "Ciemnofioletowy", - "Purple": "Fioletowy", - "Light Purple": "Jasnofioletowy", - "Violet": "Fiolet", - "Orange": "Pomarańczowy", - "Yellow": "Żółty", - "Light Yellow": "Jasnożółty", - "Teal": "Morski", - "Cyan": "Cyjan", - "Light Cyan": "Jasny cyjan", - "Magenta": "Magenta", - "Hot Pink": "Jaskrawo różowy", - "Brown": "Brązowy", - "Light Brown": "Jasnobrązowy", - "Colors": "Kolory", - "Background Color": "Kolor tła", - "Background Alpha": "Przezroczystość tła", - "Focus Color": "Kolor fokusu", - "Focus Alpha": "Przezroczystość fokusu", - "Text Color": "Kolor tekstu", - "Border": "Obramowanie", - "Dashed Line": "Linia przerywana", - "Max FPS Text": "Tekst maks. FPS", - "Min FPS Text": "Tekst min. FPS", - "Main Line": "Główna linia", - "Rounded Line": "Zaokrąglona linia", - "Perfect Line": "Idealna linia", - " Color": " Kolor", - " Alpha": " Alfa", - "Category Color": "Kolor kategorii", - "Category Color 1": "Kolor kategorii 1", - "Category Color 2": "Kolor kategorii 2", - "Separator Color": "Kolor separatora", - "Elements": "Elementy", - "Text Alignment": "Wyrównanie tekstu", - "Vertical Position": "Pozycja pionowa", - "Horizontal Position": "Pozycja pozioma", - "Left": "Lewo", - "Right": "Prawo", - "Top": "Góra", - "Center": "Środek", - "Bottom": "Dół", - "FPS Counter Color": "Kolor licznika FPS", - "FPS Counter Alpha": "Alfa licznika FPS", - "Border Color": "Kolor obramowania", - "Dashed Line Color": "Kolor linii przerywanej", - "Dashed Line Alpha": "Alfa linii przerywanej", - "Max FPS Text Color": "Kolor tekstu maks. FPS", - "Min FPS Text Color": "Kolor tekstu min. FPS", - "Main Line Color": "Kolor głównej linii", - "Rounded Line Color": "Kolor zaokrąglonej linii", - "Perfect Line Color": "Kolor idealnej linii" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/pt.json b/Source/Horizon-OC-Monitor (deprecated)/lang/pt.json deleted file mode 100644 index 3805ce59..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/pt.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Modos", - "Modes   Configure": "Modos   Configurar", - "Full": "Completo", - "Mini": "Mini", - "Micro": "Micro", - "FPS Graph": "Gráfico FPS", - "FPS Counter": "Contador FPS", - "Game Resolutions": "Resoluções no Jogo", - "Other": "Outros", - "Battery/Charger": "Bateria/Carregador", - "Miscellaneous": "Diversos", - "CPU Usage": "Uso da CPU", - "GPU Usage": "Uso da GPU", - "RAM Usage": "Uso da RAM", - "Target Frequency": "Frequência Alvo", - "Real Frequency": "Frequência Real", - "Core 0 ": "Núcleo 0 ", - "Core 1 ": "Núcleo 1 ", - "Core 2 ": "Núcleo 2 ", - "Core 3 ": "Núcleo 3 ", - "Load": "Carga", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Total\nAplicativo\nMiniAplicativo\nSistema\nSistema Inseguro", - "Board": "Placa", - "Battery Power Flow": "Fluxo de Energia", - "\nTemperatures": "\nTemperaturas", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Rotação da Fan", - "Game": "Jogo", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Resoluções ", - "Read Speed ": "Velocidade de Leitura ", - "Press ": "Pressione ", - " to Exit": " para Sair", - "Depth": "Profundidade", - "Viewport": "Visualização", - "Game is not running\nor it's incompatible.": "O jogo não está rodando\n ou não é compatível.", - "Battery Stats": "Estatísticas da Bateria", - "Actual Capacity": "Capacidade Atual", - "Designed Capacity": "Capacidade Designada", - "Temperature": "Temperatura", - "Raw Charge": "Carga Bruta", - "Age": "Idade", - "Voltage": "Voltagem", - "Current Flow": "Fluxo de Corrente", - "Power Flow": "Fluxo de Potência", - "Remaining Time": "Tempo Restante", - "Charger Stats": "Estatísticas do Carregador", - "Input Current Limit": "Limite Corrente Entrada", - "VBUS Current Limit": "Limite Corrente VBUS", - "Voltage Limit": "Limite de Voltagem", - "Current Limit": "Limite Atual", - "Type": "Tipo", - "Max Voltage": "Voltagem Máxima", - "Max Current": "Corrente Máxima", - "Multimedia Clock Rates": "Frequências Multimídia", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Rede", - "Type: Wi-Fi": "Tipo: Wi-Fi", - "Press Y to show password": "Pressione Y para exibir a senha", - "Type: Ethernet": "Tipo: Ethernet", - "Type: Not connected": "Tipo: Não conectado", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Elementos   Descer   Subir", - "Transparent": "Transparente", - "Opaque": "Opaco", - "Alpha": "Alfa", - "Pretty": "Bonito", - "Compact": "Compacto", - "FileSafe": "Seguro", - "Day+Time": "Dia+Hora", - "Date+Time(s)": "Data+Hora(s)", - "Date+Time AM/PM": "Data+Hora AM/PM", - "Date+Time(s) AM/PM": "Data+Hora(s) AM/PM", - "Date+Time EU": "Data+Hora EU", - "Date+Time EU AM/PM": "Data+Hora EU AM/PM", - "Date+Time(s) EU AM/PM": "Data+Hora(s) EU AM/PM", - "Date+Time ISO": "Data+Hora ISO", - "Time 24h": "Hora 24h", - "Time AM/PM": "Hora AM/PM", - "Time(s) 24h": "Hora(s) 24h", - "Time(s) AM/PM": "Hora(s) AM/PM", - "Date US": "Data US", - "Date EU": "Data EU", - "Date ISO": "Data ISO", - "Date Short": "Data Abreviada", - "DTC Format": "Formato DTC", - "Toggles": "Alternar", - "Info": "Informações", - "Disable Screenshots": "Desativar Capturas", - "Real Freqs": "Frequências Reais", - "Deltas": "Deltas", - "Target Freqs": "Frequências Alvo", - "FPS": "FPS", - "RES": "RES", - "Read Speed": "Velocidade de Leitura", - "Real Frequencies": "Frequências Reais", - "Real Voltages": "Voltagens Reais", - "Full CPU": "CPU Completa", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Resolução Completa", - "SOC Voltage": "Voltagem do SOC", - "RAM Load CPU/GPU": "Carga na CPU/GPU", - "Use DTC Symbol": "Usar Símbolo DTC", - "Use Dynamic Colors": "Usar Cores Dinâmicas", - "Sleep Exit": "Sair do Repouso", - "Configuration": "Configuração", - "Refresh Rate": "Taxa de Atualização", - "Frame Padding": "Preenc. de Quadro", - " Font Size": " Tamanho da Fonte", - "Font Sizes": "Tamanho das Fontes", - "Handheld Font Size": "Modo Portátil", - "Docked Font Size": "Modo Dock", - "Black": "Preto", - "Dark Gray": "Cinza Escuro", - "Gray": "Cinza", - "Light Gray": "Cinza Claro", - "Silver": "Prata", - "White": "Branco", - "Dark Red": "Vermelho Escuro", - "Red": "Vermelho", - "Light Red": "LVermelho Claro", - "Pink": "Rosa", - "Dark Green": "Verde Escuro", - "Green": "Verde", - "Lime Green": "Verde Limão", - "Light Green": "Verde Claro", - "Dark Blue": "Azul Escuro", - "Blue": "Azul", - "Light Blue": "Azul Claro", - "Sky Blue": "Azul Céu", - "Dark Purple": "Roxo Escuro", - "Purple": "Roxo", - "Light Purple": "Roxo Claro", - "Violet": "Violeta", - "Orange": "Laranja", - "Yellow": "Amarelo", - "Light Yellow": "Amarelo Claro", - "Teal": "Verde Azulado", - "Cyan": "Ciano", - "Light Cyan": "Ciano Claro", - "Magenta": "Magenta", - "Hot Pink": "Rosa Choque", - "Brown": "Marrom", - "Light Brown": "Marrom Claro", - "Colors": "Cores", - "Background Color": "Cor de Fundo", - "Background Alpha": "Opacidade", - "Focus Color": "Cor em Foco", - "Focus Alpha": "Alfa em Foco", - "Text Color": "Cor do Texto", - "Border": "Borda", - "Dashed Line": "Linha Tracejada", - "Max FPS Text": "Texto Máx. FPS", - "Min FPS Text": "Texto Min. FPS", - "Main Line": "Linha Principal", - "Rounded Line": "Linha Arredondada", - "Perfect Line": "Linha Perfeita", - " Color": " Cor", - " Alpha": " Alfa", - "Category Color": "Cor da Categoria", - "Category Color 1": "Cor Categoria 1", - "Category Color 2": "Cor Categoria 2", - "Separator Color": "Cor do Separador", - "Elements": "Elementos", - "Text Alignment": "Alinhamento do Texto", - "Vertical Position": "Posição Vertical", - "Horizontal Position": "Posição Horizontal", - "Left": "Esquerdo", - "Right": "Direito", - "Top": "Topo", - "Center": "Centro", - "Bottom": "Baixo", - "FPS Counter Color":"Cor Contador FPS", - "FPS Counter Alpha":"Opac. Contador FPS", - "Border Color":"Cor da Borda", - "Dashed Line Color":"Cor Linha Trac.", - "Dashed Line Alpha":"Opac. Linha Trac.", - "Max FPS Text Color":"Cor Texto FPS Máx.", - "Min FPS Text Color":"Cor Texto FPS Min.", - "Main Line Color":"Cor Linha Principal", - "Rounded Line Color":"Cor Linha Arrend.", - "Perfect Line Color":"Cor Linha Perfeita" -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/ru.json b/Source/Horizon-OC-Monitor (deprecated)/lang/ru.json deleted file mode 100644 index 841b0b75..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/ru.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Режимы", - "Modes   Configure": "Режимы   Настроить", - "Full": "Полный", - "Mini": "Мини", - "Micro": "Микро", - "FPS Graph": "График FPS", - "FPS Counter": "Счётчик FPS", - "Game Resolutions": "Разрешения игры", - "Other": "Прочее", - "Battery/Charger": "Аккумулятор/Зарядка", - "Miscellaneous": "Разное", - "CPU Usage": "Загрузка CPU", - "GPU Usage": "Загрузка GPU", - "RAM Usage": "Загрузка RAM", - "Target Frequency": "Целевая частота", - "Real Frequency": "Реальная частота", - "Core 0 ": "Ядро 0 ", - "Core 1 ": "Ядро 1 ", - "Core 2 ": "Ядро 2 ", - "Core 3 ": "Ядро 3 ", - "Load": "Нагрузка", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Всего\nПриложение\nАпплет\nСистема\nСистема (небезопасно)", - "Board": "Плата", - "Battery Power Flow": "Поток энергии аккумулятора", - "\nTemperatures": "\nТемпературы", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Уровень вращения вентилятора", - "Game": "Игра", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Разрешения ", - "Read Speed ": "Скорость чтения ", - "Press ": "Нажмите ", - " to Exit": " для выхода", - "Depth": "Глубина", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Игра не запущена\nили несовместима.", - "Battery Stats": "Статистика аккумулятора", - "Actual Capacity": "Фактическая ёмкость", - "Designed Capacity": "Номинальная ёмкость", - "Temperature": "Температура", - "Raw Charge": "Сырой заряд", - "Age": "Возраст", - "Voltage": "Напряжение", - "Current Flow": "Ток", - "Power Flow": "Мощность", - "Remaining Time": "Оставшееся время", - "Charger Stats": "Статистика зарядки", - "Input Current Limit": "Лимит входного тока", - "VBUS Current Limit": "Лимит тока VBUS", - "Voltage Limit": "Лимит напряжения", - "Current Limit": "Лимит тока", - "Type": "Тип", - "Max Voltage": "Макс. напряжение", - "Max Current": "Макс. ток", - "Multimedia Clock Rates": "Частоты мультимедиа", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Сеть", - "Type: Wi-Fi": "Тип: Wi-Fi", - "Press Y to show password": "Нажмите Y, чтобы показать пароль", - "Type: Ethernet": "Тип: Ethernet", - "Type: Not connected": "Тип: Не подключено", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Элементы   Вниз   Вверх", - "Transparent": "Прозрачный", - "Opaque": "Непрозрачный", - "Alpha": "Альфа", - "Pretty": "Красивый", - "Compact": "Компактный", - "FileSafe": "FileSafe", - "Day+Time": "День+Время", - "Date+Time(s)": "Дата+Время(с)", - "Date+Time AM/PM": "Дата+Время AM/PM", - "Date+Time(s) AM/PM": "Дата+Время(с) AM/PM", - "Date+Time EU": "Дата+Время EU", - "Date+Time EU AM/PM": "Дата+Время EU AM/PM", - "Date+Time(s) EU AM/PM": "Дата+Время(с) EU AM/PM", - "Date+Time ISO": "Дата+Время ISO", - "Time 24h": "Время 24ч", - "Time AM/PM": "Время AM/PM", - "Time(s) 24h": "Время(с) 24ч", - "Time(s) AM/PM": "Время(с) AM/PM", - "Date US": "Дата US", - "Date EU": "Дата EU", - "Date ISO": "Дата ISO", - "Date Short": "Краткая дата", - "DTC Format": "Формат DTC", - "Toggles": "Переключатели", - "Info": "Показать информацию", - "Disable Screenshots": "Отключить скриншоты", - "Real Freqs": "Реальные частоты", - "Deltas": "Дельты", - "Target Freqs": "Целевые частоты", - "FPS": "FPS", - "RES": "РАЗР.", - "Read Speed": "Скорость чтения", - "Real Frequencies": "Реальные частоты", - "Real Voltages": "Реальные напряжения", - "Full CPU": "Полный CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Полное разрешение", - "SOC Voltage": "Напряжение SOC", - "RAM Load CPU/GPU": "Нагрузка RAM CPU/GPU", - "Use DTC Symbol": "Использовать символ DTC", - "Use Dynamic Colors": "Использовать динамические цвета", - "Sleep Exit": "Выход из сна", - "Configuration": "Конфигурация", - "Refresh Rate": "Частота обновления", - "Frame Padding": "Отступ кадра", - " Font Size": " Размер шрифта", - "Font Sizes": "Размеры шрифта", - "Handheld Font Size": "Размер шрифта в портативном режиме", - "Docked Font Size": "Размер шрифта в док-режиме", - "Black": "Чёрный", - "Dark Gray": "Тёмно-серый", - "Gray": "Серый", - "Light Gray": "Светло-серый", - "Silver": "Серебряный", - "White": "Белый", - "Dark Red": "Тёмно-красный", - "Red": "Красный", - "Light Red": "Светло-красный", - "Pink": "Розовый", - "Dark Green": "Тёмно-зелёный", - "Green": "Зелёный", - "Lime Green": "Лаймовый", - "Light Green": "Светло-зелёный", - "Dark Blue": "Тёмно-синий", - "Blue": "Синий", - "Light Blue": "Светло-синий", - "Sky Blue": "Небесно-голубой", - "Dark Purple": "Тёмно-фиолетовый", - "Purple": "Фиолетовый", - "Light Purple": "Светло-фиолетовый", - "Violet": "Фиолетовый", - "Orange": "Оранжевый", - "Yellow": "Жёлтый", - "Light Yellow": "Светло-жёлтый", - "Teal": "Бирюзовый", - "Cyan": "Голубой", - "Light Cyan": "Светло-голубой", - "Magenta": "Пурпурный", - "Hot Pink": "Ярко-розовый", - "Brown": "Коричневый", - "Light Brown": "Светло-коричневый", - "Colors": "Цвета", - "Background Color": "Цвет фона", - "Background Alpha": "Прозрачность фона", - "Focus Color": "Цвет фокуса", - "Focus Alpha": "Прозрачность фокуса", - "Text Color": "Цвет текста", - "Border": "Граница", - "Dashed Line": "Пунктирная линия", - "Max FPS Text": "Текст макс. FPS", - "Min FPS Text": "Текст мин. FPS", - "Main Line": "Основная линия", - "Rounded Line": "Скруглённая линия", - "Perfect Line": "Идеальная линия", - " Color": " Цвет", - " Alpha": " Прозрачность", - "Category Color": "Цвет категории", - "Category Color 1": "Цвет категории 1", - "Category Color 2": "Цвет категории 2", - "Separator Color": "Цвет разделителя", - "Elements": "Элементы", - "Text Alignment": "Выравнивание текста", - "Vertical Position": "Вертикальная позиция", - "Horizontal Position": "Горизонтальная позиция", - "Left": "Слева", - "Right": "Справа", - "Top": "Сверху", - "Center": "По центру", - "Bottom": "Снизу", - "FPS Counter Color": "Цвет счётчика FPS", - "FPS Counter Alpha": "Прозрачность счётчика FPS", - "Border Color": "Цвет границы", - "Dashed Line Color": "Цвет пунктирной линии", - "Dashed Line Alpha": "Прозрачность пунктирной линии", - "Max FPS Text Color": "Цвет текста макс. FPS", - "Min FPS Text Color": "Цвет текста мин. FPS", - "Main Line Color": "Цвет основной линии", - "Rounded Line Color": "Цвет скруглённой линии", - "Perfect Line Color": "Цвет идеальной линии" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/uk.json b/Source/Horizon-OC-Monitor (deprecated)/lang/uk.json deleted file mode 100644 index c41c1beb..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/uk.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "Режими", - "Modes   Configure": "Режими   Налаштувати", - "Full": "Повний", - "Mini": "Міні", - "Micro": "Мікро", - "FPS Graph": "Графік FPS", - "FPS Counter": "Лічильник FPS", - "Game Resolutions": "Роздільна здатність гри", - "Other": "Інше", - "Battery/Charger": "Акумулятор/Зарядка", - "Miscellaneous": "Різне", - "CPU Usage": "Завантаження CPU", - "GPU Usage": "Завантаження GPU", - "RAM Usage": "Завантаження RAM", - "Target Frequency": "Цільова частота", - "Real Frequency": "Реальна частота", - "Core 0 ": "Ядро 0 ", - "Core 1 ": "Ядро 1 ", - "Core 2 ": "Ядро 2 ", - "Core 3 ": "Ядро 3 ", - "Load": "Навантаження", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "Всього\nДодаток\nАплет\nСистема\nСистема (небезпечно)", - "Board": "Плата", - "Battery Power Flow": "Потік енергії акумулятора", - "\nTemperatures": "\nТемператури", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "Рівень обертання вентилятора", - "Game": "Гра", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "Роздільна здатність ", - "Read Speed ": "Швидкість зчитування ", - "Press ": "Натисніть ", - " to Exit": " для виходу", - "Depth": "Глибина", - "Viewport": "Viewport", - "Game is not running\nor it's incompatible.": "Гра не запущена\nабо несумісна.", - "Battery Stats": "Статистика акумулятора", - "Actual Capacity": "Фактична ємність", - "Designed Capacity": "Номінальна ємність", - "Temperature": "Температура", - "Raw Charge": "Сирий заряд", - "Age": "Вік", - "Voltage": "Напруга", - "Current Flow": "Струм", - "Power Flow": "Потужність", - "Remaining Time": "Залишковий час", - "Charger Stats": "Статистика зарядки", - "Input Current Limit": "Ліміт вхідного струму", - "VBUS Current Limit": "Ліміт струму VBUS", - "Voltage Limit": "Ліміт напруги", - "Current Limit": "Ліміт струму", - "Type": "Тип", - "Max Voltage": "Макс. напруга", - "Max Current": "Макс. струм", - "Multimedia Clock Rates": "Частоти мультимедіа", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "Мережа", - "Type: Wi-Fi": "Тип: Wi-Fi", - "Press Y to show password": "Натисніть Y, щоб показати пароль", - "Type: Ethernet": "Тип: Ethernet", - "Type: Not connected": "Тип: Не підключено", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "Елементи   Вниз   Вгору", - "Transparent": "Прозорий", - "Opaque": "Непрозорий", - "Alpha": "Альфа", - "Pretty": "Красивий", - "Compact": "Компактний", - "FileSafe": "FileSafe", - "Day+Time": "День+Час", - "Date+Time(s)": "Дата+Час(с)", - "Date+Time AM/PM": "Дата+Час AM/PM", - "Date+Time(s) AM/PM": "Дата+Час(с) AM/PM", - "Date+Time EU": "Дата+Час EU", - "Date+Time EU AM/PM": "Дата+Час EU AM/PM", - "Date+Time(s) EU AM/PM": "Дата+Час(с) EU AM/PM", - "Date+Time ISO": "Дата+Час ISO", - "Time 24h": "Час 24год", - "Time AM/PM": "Час AM/PM", - "Time(s) 24h": "Час(с) 24год", - "Time(s) AM/PM": "Час(с) AM/PM", - "Date US": "Дата US", - "Date EU": "Дата EU", - "Date ISO": "Дата ISO", - "Date Short": "Коротка дата", - "DTC Format": "Формат DTC", - "Toggles": "Перемикачі", - "Info": "Показати інформацію", - "Disable Screenshots": "Вимкнути знімки екрана", - "Real Freqs": "Реальні частоти", - "Deltas": "Дельти", - "Target Freqs": "Цільові частоти", - "FPS": "FPS", - "RES": "РОЗД.", - "Read Speed": "Швидкість зчитування", - "Real Frequencies": "Реальні частоти", - "Real Voltages": "Реальні напруги", - "Full CPU": "Повний CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "Повна роздільна здатність", - "SOC Voltage": "Напруга SOC", - "RAM Load CPU/GPU": "Навантаження RAM CPU/GPU", - "Use DTC Symbol": "Використовувати символ DTC", - "Use Dynamic Colors": "Використовувати динамічні кольори", - "Sleep Exit": "Вихід зі сну", - "Configuration": "Конфігурація", - "Refresh Rate": "Частота оновлення", - "Frame Padding": "Відступ кадру", - " Font Size": " Розмір шрифту", - "Font Sizes": "Розміри шрифту", - "Handheld Font Size": "Розмір шрифту в портативному режимі", - "Docked Font Size": "Розмір шрифту в док-режимі", - "Black": "Чорний", - "Dark Gray": "Темно-сірий", - "Gray": "Сірий", - "Light Gray": "Світло-сірий", - "Silver": "Сріблястий", - "White": "Білий", - "Dark Red": "Темно-червоний", - "Red": "Червоний", - "Light Red": "Світло-червоний", - "Pink": "Рожевий", - "Dark Green": "Темно-зелений", - "Green": "Зелений", - "Lime Green": "Лаймовий", - "Light Green": "Світло-зелений", - "Dark Blue": "Темно-синій", - "Blue": "Синій", - "Light Blue": "Світло-синій", - "Sky Blue": "Небесно-блакитний", - "Dark Purple": "Темно-фіолетовий", - "Purple": "Фіолетовий", - "Light Purple": "Світло-фіолетовий", - "Violet": "Фіолетовий", - "Orange": "Помаранчевий", - "Yellow": "Жовтий", - "Light Yellow": "Світло-жовтий", - "Teal": "Бірюзовий", - "Cyan": "Блакитний", - "Light Cyan": "Світло-блакитний", - "Magenta": "Пурпуровий", - "Hot Pink": "Яскраво-рожевий", - "Brown": "Коричневий", - "Light Brown": "Світло-коричневий", - "Colors": "Кольори", - "Background Color": "Колір фону", - "Background Alpha": "Прозорість фону", - "Focus Color": "Колір фокусу", - "Focus Alpha": "Прозорість фокусу", - "Text Color": "Колір тексту", - "Border": "Межа", - "Dashed Line": "Пунктирна лінія", - "Max FPS Text": "Текст макс. FPS", - "Min FPS Text": "Текст мін. FPS", - "Main Line": "Основна лінія", - "Rounded Line": "Закруглена лінія", - "Perfect Line": "Ідеальна лінія", - " Color": " Колір", - " Alpha": " Прозорість", - "Category Color": "Колір категорії", - "Category Color 1": "Колір категорії 1", - "Category Color 2": "Колір категорії 2", - "Separator Color": "Колір роздільника", - "Elements": "Елементи", - "Text Alignment": "Вирівнювання тексту", - "Vertical Position": "Вертикальна позиція", - "Horizontal Position": "Горизонтальна позиція", - "Left": "Зліва", - "Right": "Справа", - "Top": "Зверху", - "Center": "По центру", - "Bottom": "Знизу", - "FPS Counter Color": "Колір лічильника FPS", - "FPS Counter Alpha": "Прозорість лічильника FPS", - "Border Color": "Колір межі", - "Dashed Line Color": "Колір пунктирної лінії", - "Dashed Line Alpha": "Прозорість пунктирної лінії", - "Max FPS Text Color": "Колір тексту макс. FPS", - "Min FPS Text Color": "Колір тексту мін. FPS", - "Main Line Color": "Колір основної лінії", - "Rounded Line Color": "Колір закругленої лінії", - "Perfect Line Color": "Колір ідеальної лінії" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/zh-cn.json b/Source/Horizon-OC-Monitor (deprecated)/lang/zh-cn.json deleted file mode 100644 index df7d264a..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/zh-cn.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "模式", - "Modes   Configure": "模式   配置", - "Full": "完整", - "Mini": "迷你", - "Micro": "微型", - "FPS Graph": "FPS 图表", - "FPS Counter": "FPS 计数器", - "Game Resolutions": "游戏分辨率", - "Other": "其他", - "Battery/Charger": "电池/充电器", - "Miscellaneous": "杂项", - "CPU Usage": "CPU 使用率", - "GPU Usage": "GPU 使用率", - "RAM Usage": "RAM 使用率", - "Target Frequency": "目标频率", - "Real Frequency": "实际频率", - "Core 0 ": "核心 0 ", - "Core 1 ": "核心 1 ", - "Core 2 ": "核心 2 ", - "Core 3 ": "核心 3 ", - "Load": "负载", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "总计\n应用\n小程序\n系统\n系统(不安全)", - "Board": "主板", - "Battery Power Flow": "电池功率流", - "\nTemperatures": "\n温度", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "风扇转速级别", - "Game": "游戏", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "分辨率 ", - "Read Speed ": "读取速度 ", - "Press ": "按 ", - " to Exit": " 退出", - "Depth": "深度", - "Viewport": "视口", - "Game is not running\nor it's incompatible.": "游戏未运行\n或不兼容。", - "Battery Stats": "电池统计", - "Actual Capacity": "实际容量", - "Designed Capacity": "设计容量", - "Temperature": "温度", - "Raw Charge": "原始电量", - "Age": "寿命", - "Voltage": "电压", - "Current Flow": "电流", - "Power Flow": "功率", - "Remaining Time": "剩余时间", - "Charger Stats": "充电器统计", - "Input Current Limit": "输入电流限制", - "VBUS Current Limit": "VBUS 电流限制", - "Voltage Limit": "电压限制", - "Current Limit": "电流限制", - "Type": "类型", - "Max Voltage": "最大电压", - "Max Current": "最大电流", - "Multimedia Clock Rates": "多媒体时钟频率", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "网络", - "Type: Wi-Fi": "类型:Wi-Fi", - "Press Y to show password": "按 Y 显示密码", - "Type: Ethernet": "类型:以太网", - "Type: Not connected": "类型:未连接", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "元素   下移   上移", - "Transparent": "透明", - "Opaque": "不透明", - "Alpha": "透明度", - "Pretty": "美观", - "Compact": "紧凑", - "FileSafe": "文件安全", - "Day+Time": "日期+时间", - "Date+Time(s)": "日期+时间(秒)", - "Date+Time AM/PM": "日期+时间 AM/PM", - "Date+Time(s) AM/PM": "日期+时间(秒) AM/PM", - "Date+Time EU": "日期+时间 EU", - "Date+Time EU AM/PM": "日期+时间 EU AM/PM", - "Date+Time(s) EU AM/PM": "日期+时间(秒) EU AM/PM", - "Date+Time ISO": "日期+时间 ISO", - "Time 24h": "时间 24时", - "Time AM/PM": "时间 AM/PM", - "Time(s) 24h": "时间(秒) 24时", - "Time(s) AM/PM": "时间(秒) AM/PM", - "Date US": "日期 US", - "Date EU": "日期 EU", - "Date ISO": "日期 ISO", - "Date Short": "短日期", - "DTC Format": "DTC 格式", - "Toggles": "开关", - "Info": "显示信息", - "Disable Screenshots": "禁用截图", - "Real Freqs": "实际频率", - "Deltas": "差值", - "Target Freqs": "目标频率", - "FPS": "FPS", - "RES": "分辨率", - "Read Speed": "读取速度", - "Real Frequencies": "实际频率", - "Real Voltages": "实际电压", - "Full CPU": "完整 CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "完整分辨率", - "SOC Voltage": "SOC 电压", - "RAM Load CPU/GPU": "RAM 负载 CPU/GPU", - "Use DTC Symbol": "使用 DTC 符号", - "Use Dynamic Colors": "使用动态颜色", - "Sleep Exit": "退出睡眠", - "Configuration": "配置", - "Refresh Rate": "刷新率", - "Frame Padding": "帧填充", - " Font Size": " 字体大小", - "Font Sizes": "字体大小", - "Handheld Font Size": "手持模式字体大小", - "Docked Font Size": "底座模式字体大小", - "Black": "黑色", - "Dark Gray": "深灰", - "Gray": "灰色", - "Light Gray": "浅灰", - "Silver": "银色", - "White": "白色", - "Dark Red": "深红", - "Red": "红色", - "Light Red": "浅红", - "Pink": "粉红", - "Dark Green": "深绿", - "Green": "绿色", - "Lime Green": "酸橙绿", - "Light Green": "浅绿", - "Dark Blue": "深蓝", - "Blue": "蓝色", - "Light Blue": "浅蓝", - "Sky Blue": "天蓝", - "Dark Purple": "深紫", - "Purple": "紫色", - "Light Purple": "浅紫", - "Violet": "紫罗兰", - "Orange": "橙色", - "Yellow": "黄色", - "Light Yellow": "浅黄", - "Teal": "蓝绿", - "Cyan": "青色", - "Light Cyan": "浅青", - "Magenta": "品红", - "Hot Pink": "艳粉", - "Brown": "棕色", - "Light Brown": "浅棕", - "Colors": "颜色", - "Background Color": "背景颜色", - "Background Alpha": "背景透明度", - "Focus Color": "焦点颜色", - "Focus Alpha": "焦点透明度", - "Text Color": "文字颜色", - "Border": "边框", - "Dashed Line": "虚线", - "Max FPS Text": "最大 FPS 文字", - "Min FPS Text": "最小 FPS 文字", - "Main Line": "主线", - "Rounded Line": "圆角线", - "Perfect Line": "完美线", - " Color": " 颜色", - " Alpha": " 透明度", - "Category Color": "分类颜色", - "Category Color 1": "分类颜色 1", - "Category Color 2": "分类颜色 2", - "Separator Color": "分隔线颜色", - "Elements": "元素", - "Text Alignment": "文字对齐", - "Vertical Position": "垂直位置", - "Horizontal Position": "水平位置", - "Left": "左", - "Right": "右", - "Top": "上", - "Center": "中", - "Bottom": "下", - "FPS Counter Color": "FPS 计数器颜色", - "FPS Counter Alpha": "FPS 计数器透明度", - "Border Color": "边框颜色", - "Dashed Line Color": "虚线颜色", - "Dashed Line Alpha": "虚线透明度", - "Max FPS Text Color": "最大 FPS 文字颜色", - "Min FPS Text Color": "最小 FPS 文字颜色", - "Main Line Color": "主线颜色", - "Rounded Line Color": "圆角线颜色", - "Perfect Line Color": "完美线颜色" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/lang/zh-tw.json b/Source/Horizon-OC-Monitor (deprecated)/lang/zh-tw.json deleted file mode 100644 index ce8015e4..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/lang/zh-tw.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "Horizon OC Monitor": "Horizon OC Monitor", - "Modes": "模式", - "Modes   Configure": "模式   設定", - "Full": "完整", - "Mini": "迷你", - "Micro": "微型", - "FPS Graph": "FPS 圖表", - "FPS Counter": "FPS 計數器", - "Game Resolutions": "遊戲解析度", - "Other": "其他", - "Battery/Charger": "電池/充電器", - "Miscellaneous": "雜項", - "CPU Usage": "CPU 使用率", - "GPU Usage": "GPU 使用率", - "RAM Usage": "RAM 使用率", - "Target Frequency": "目標頻率", - "Real Frequency": "實際頻率", - "Core 0 ": "核心 0 ", - "Core 1 ": "核心 1 ", - "Core 2 ": "核心 2 ", - "Core 3 ": "核心 3 ", - "Load": "負載", - "Total\nApplication\nApplet\nSystem\nSystem Unsafe": "總計\n應用程式\n小程式\n系統\n系統(不安全)", - "Board": "主機板", - "Battery Power Flow": "電池功率流", - "\nTemperatures": "\n溫度", - "SoC\nPCB\nSkin": "SoC\nPCB\nSkin", - "Fan Rotation Level": "風扇轉速等級", - "Game": "遊戲", - "PFPS ": "PFPS ", - "FPS ": "FPS ", - "Resolutions ": "解析度 ", - "Read Speed ": "讀取速度 ", - "Press ": "按 ", - " to Exit": " 退出", - "Depth": "深度", - "Viewport": "視口", - "Game is not running\nor it's incompatible.": "遊戲未執行\n或不相容。", - "Battery Stats": "電池統計", - "Actual Capacity": "實際容量", - "Designed Capacity": "設計容量", - "Temperature": "溫度", - "Raw Charge": "原始電量", - "Age": "壽命", - "Voltage": "電壓", - "Current Flow": "電流", - "Power Flow": "功率", - "Remaining Time": "剩餘時間", - "Charger Stats": "充電器統計", - "Input Current Limit": "輸入電流限制", - "VBUS Current Limit": "VBUS 電流限制", - "Voltage Limit": "電壓限制", - "Current Limit": "電流限制", - "Type": "類型", - "Max Voltage": "最大電壓", - "Max Current": "最大電流", - "Multimedia Clock Rates": "多媒體時脈頻率", - "NVDEC": "NVDEC", - "NVENC": "NVENC", - "NVJPG": "NVJPG", - "Network": "網路", - "Type: Wi-Fi": "類型:Wi-Fi", - "Press Y to show password": "按 Y 顯示密碼", - "Type: Ethernet": "類型:乙太網路", - "Type: Not connected": "類型:未連線", - "CPU\nGPU\nRAM\nSOC\nPCB\nSKN": "CPU\nGPU\nRAM\nSOC\nPCB\nSKN", - "Elements   Move Down   Move Up": "元素   下移   上移", - "Transparent": "透明", - "Opaque": "不透明", - "Alpha": "透明度", - "Pretty": "美觀", - "Compact": "緊湊", - "FileSafe": "檔案安全", - "Day+Time": "日期+時間", - "Date+Time(s)": "日期+時間(秒)", - "Date+Time AM/PM": "日期+時間 AM/PM", - "Date+Time(s) AM/PM": "日期+時間(秒) AM/PM", - "Date+Time EU": "日期+時間 EU", - "Date+Time EU AM/PM": "日期+時間 EU AM/PM", - "Date+Time(s) EU AM/PM": "日期+時間(秒) EU AM/PM", - "Date+Time ISO": "日期+時間 ISO", - "Time 24h": "時間 24時", - "Time AM/PM": "時間 AM/PM", - "Time(s) 24h": "時間(秒) 24時", - "Time(s) AM/PM": "時間(秒) AM/PM", - "Date US": "日期 US", - "Date EU": "日期 EU", - "Date ISO": "日期 ISO", - "Date Short": "短日期", - "DTC Format": "DTC 格式", - "Toggles": "開關", - "Info": "顯示資訊", - "Disable Screenshots": "停用截圖", - "Real Freqs": "實際頻率", - "Deltas": "差值", - "Target Freqs": "目標頻率", - "FPS": "FPS", - "RES": "解析度", - "Read Speed": "讀取速度", - "Real Frequencies": "實際頻率", - "Real Voltages": "實際電壓", - "Full CPU": "完整 CPU", - "VDDQ": "VDDQ", - "VDD2": "VDD2", - "Full Resolution": "完整解析度", - "SOC Voltage": "SOC 電壓", - "RAM Load CPU/GPU": "RAM 負載 CPU/GPU", - "Use DTC Symbol": "使用 DTC 符號", - "Use Dynamic Colors": "使用動態顏色", - "Sleep Exit": "退出睡眠", - "Configuration": "設定", - "Refresh Rate": "更新率", - "Frame Padding": "畫面邊距", - " Font Size": " 字型大小", - "Font Sizes": "字型大小", - "Handheld Font Size": "掌機模式字型大小", - "Docked Font Size": "主機模式字型大小", - "Black": "黑色", - "Dark Gray": "深灰", - "Gray": "灰色", - "Light Gray": "淺灰", - "Silver": "銀色", - "White": "白色", - "Dark Red": "深紅", - "Red": "紅色", - "Light Red": "淺紅", - "Pink": "粉紅", - "Dark Green": "深綠", - "Green": "綠色", - "Lime Green": "萊姆綠", - "Light Green": "淺綠", - "Dark Blue": "深藍", - "Blue": "藍色", - "Light Blue": "淺藍", - "Sky Blue": "天空藍", - "Dark Purple": "深紫", - "Purple": "紫色", - "Light Purple": "淺紫", - "Violet": "紫羅蘭", - "Orange": "橙色", - "Yellow": "黃色", - "Light Yellow": "淺黃", - "Teal": "藍綠", - "Cyan": "青色", - "Light Cyan": "淺青", - "Magenta": "洋紅", - "Hot Pink": "熱粉", - "Brown": "棕色", - "Light Brown": "淺棕", - "Colors": "顏色", - "Background Color": "背景顏色", - "Background Alpha": "背景透明度", - "Focus Color": "焦點顏色", - "Focus Alpha": "焦點透明度", - "Text Color": "文字顏色", - "Border": "邊框", - "Dashed Line": "虛線", - "Max FPS Text": "最大 FPS 文字", - "Min FPS Text": "最小 FPS 文字", - "Main Line": "主線", - "Rounded Line": "圓角線", - "Perfect Line": "完美線", - " Color": " 顏色", - " Alpha": " 透明度", - "Category Color": "分類顏色", - "Category Color 1": "分類顏色 1", - "Category Color 2": "分類顏色 2", - "Separator Color": "分隔線顏色", - "Elements": "元素", - "Text Alignment": "文字對齊", - "Vertical Position": "垂直位置", - "Horizontal Position": "水平位置", - "Left": "左", - "Right": "右", - "Top": "上", - "Center": "中", - "Bottom": "下", - "FPS Counter Color": "FPS 計數器顏色", - "FPS Counter Alpha": "FPS 計數器透明度", - "Border Color": "邊框顏色", - "Dashed Line Color": "虛線顏色", - "Dashed Line Alpha": "虛線透明度", - "Max FPS Text Color": "最大 FPS 文字顏色", - "Min FPS Text Color": "最小 FPS 文字顏色", - "Main Line Color": "主線顏色", - "Rounded Line Color": "圓角線顏色", - "Perfect Line Color": "完美線顏色" -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/out/config/status-monitor/config.ini.template b/Source/Horizon-OC-Monitor (deprecated)/out/config/status-monitor/config.ini.template deleted file mode 100644 index a11d524b..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/out/config/status-monitor/config.ini.template +++ /dev/null @@ -1,127 +0,0 @@ -[status-monitor] -battery_avg_iir_filter=false -battery_time_left_refreshrate=60 -average_gpu_load=false -use_old_fps_average=false - -[full] -refresh_rate=1 -layer_width_align=left -show_real_freqs=true -show_deltas=true -show_target_freqs=true -show_fps=true -show_res=true -show_read_speed=true -use_dynamic_colors=true -disable_screenshots=false -separator_color=#888F -cat_color_1=#8FFF -cat_color_2=#8CFF -text_color=#FFFF - -[mini] -refresh_rate=1 -handheld_font_size=15 -docked_font_size=15 -spacing=8 -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=true -show_fan_percentage=true -show_soc_voltage=false -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%m-%d-%Y%H:%M:%S -show=DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES -replace_MB_with_RAM_load=true -show_RAM_load_CPU_GPU=false -invert_battery_display=true -disable_screenshots=false -sleep_exit=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[micro] -refresh_rate=1 -layer_height_align=top -handheld_font_size=15 -docked_font_size=15 -text_align=center -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=false -show_soc_voltage=true -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%H:%M:%S -show=FPS+CPU+GPU+RAM+SOC+BAT+DTC -replace_GB_with_RAM_load=true -invert_battery_display=false -disable_screenshots=false -sleep_exit=false -background_color=#0009 -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[fps-counter] -refresh_rate=30 -handheld_font_size=40 -docked_font_size=40 -use_integer_counter=false -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -text_color=#8CFF - -[fps-graph] -refresh_rate=30 -show_info=false -use_dynamic_colors=true -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -fps_counter_color=#888C -border_color=#2DFF -dashed_line_color=#8888 -main_line_color=#FFFF -rounded_line_color=#F0FF -perfect_line_color=#0C0F -max_fps_text_color=#FFFF -min_fps_text_color=#FFFF -text_color=#FFFF -cat_color=#0F0F - -[game_resolutions] -refresh_rate=10 -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -cat_color=#8FFF -text_color=#FFFF diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/Utils.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/Utils.hpp deleted file mode 100644 index 466a86aa..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/Utils.hpp +++ /dev/null @@ -1,2538 +0,0 @@ -#pragma once -#define ALWAYS_INLINE inline __attribute__((always_inline)) -#include "SaltyNX.h" - -#include "Battery.hpp" -#include "audsnoop.h" -#include "Misc.hpp" -#include "max17050.h" -#include "tmp451.h" -#include "pwm.h" -#include -#include -#include - -// rgltr_services.cpp (no changes needed here—just compile it once) -#include -#include "rgltr.h" -#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc. - - - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#include - -#if defined(__cplusplus) -} -#endif - -#define NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD 0x80044715 -#define FieldDescriptor uint32_t -#define BASE_SNS_UOHM 5000 - -static bool fixHiding = false; -static bool fixForeground = false; - -//Common -bool isMariko = false; -Thread t0; -Thread t1; -Thread t2; -Thread t3; -Thread t4; -Thread t5; -Thread t6; -Thread t7; -uint64_t systemtickfrequency = 19200000; - -LEvent threadexit; -PwmChannelSession g_ICon; -const std::string folderpath = "sdmc:/switch/.overlays/"; - -// Use const string_view for paths to avoid string copying -constexpr const char* directoryPath = "sdmc:/config/status-monitor/"; -constexpr const char* configIniPath = "sdmc:/config/status-monitor/config.ini"; -constexpr const char* ultrahandConfigIniPath = "sdmc:/config/ultrahand/config.ini"; -constexpr const char* teslaConfigIniPath = "sdmc:/config/tesla/config.ini"; - -std::string filename; -std::string filepath; -std::string keyCombo = "ZL+ZR+DDOWN"; // default Ultrahand Menu combo - -//Misc2 -MmuRequest nvdecRequest; -MmuRequest nvencRequest; -MmuRequest nvjpgRequest; - -//Checks -Result nvCheck = 1; -Result i2cCheck = 1; -Result pwmCheck = 1; -Result tcCheck = 1; -Result Hinted = 1; -Result pmdmntCheck = 1; -Result psmCheck = 1; -Result audsnoopCheck = 1; -Result nvdecCheck = 1; -Result nvencCheck = 1; -Result nvjpgCheck = 1; -Result nifmCheck = 1; -Result hocclkCheck = 1; -Result pwmDutyCycleCheck = 1; - -//Wi-Fi -NifmInternetConnectionType NifmConnectionType = (NifmInternetConnectionType)-1; -NifmInternetConnectionStatus NifmConnectionStatus = (NifmInternetConnectionStatus)-1; -bool Nifm_showpass = false; -Result Nifm_internet_rc = -1; -Result Nifm_profile_rc = -1; -NifmNetworkProfileData_new Nifm_profile = {0}; - -//Multimedia engines -uint32_t NVDEC_Hz = 0; -uint32_t NVENC_Hz = 0; -uint32_t NVJPG_Hz = 0; - -//DSP -uint32_t DSP_Load_u = -1; - -//Battery -Service* psmService = 0; -BatteryChargeInfoFields _batteryChargeInfoFields = {0}; -float batCurrentAvg = 0; -float batVoltageAvg = 0; -float PowerConsumption = 0; -int16_t batTimeEstimate = -1; -float actualFullBatCapacity = 0; -float designedFullBatCapacity = 0; -bool batteryFiltered = false; -uint8_t batteryTimeLeftRefreshRate = 60; -int32_t BatteryTimeCache[120]; - -//Temperatures -float SOC_temperatureF = 0; -float PCB_temperatureF = 0; -int32_t skin_temperaturemiliC = 0; - -//CPU Usage -//uint64_t idletick0 = systemtickfrequency; -//uint64_t idletick1 = systemtickfrequency; -//uint64_t idletick2 = systemtickfrequency; -//uint64_t idletick3 = systemtickfrequency; - -std::atomic idletick0{systemtickfrequency}; -std::atomic idletick1{systemtickfrequency}; -std::atomic idletick2{systemtickfrequency}; -std::atomic idletick3{systemtickfrequency}; - - -//Frequency -uint32_t CPU_Hz = 0; -uint32_t GPU_Hz = 0; -uint32_t RAM_Hz = 0; - -//RAM Size -uint64_t RAM_Total_all_u = 0; -uint64_t RAM_Total_application_u = 0; -uint64_t RAM_Total_applet_u = 0; -uint64_t RAM_Total_system_u = 0; -uint64_t RAM_Total_systemunsafe_u = 0; -uint64_t RAM_Used_all_u = 0; -uint64_t RAM_Used_application_u = 0; -uint64_t RAM_Used_applet_u = 0; -uint64_t RAM_Used_system_u = 0; -uint64_t RAM_Used_systemunsafe_u = 0; - -//Fan -double Rotation_Duty = 0; - -//GPU Usage -FieldDescriptor fd = 0; -uint32_t GPU_Load_u = 0; -bool GPULoadPerFrame = true; - -//NX-FPS - -struct resolutionCalls { - uint16_t width; - uint16_t height; - uint16_t calls; -}; - -struct NxFpsSharedBlock { - uint32_t MAGIC; - uint8_t FPS; - float FPSavg; - bool pluginActive; - uint8_t FPSlocked; - uint8_t FPSmode; - uint8_t ZeroSync; - uint8_t patchApplied; - uint8_t API; - uint32_t FPSticks[10]; - uint8_t Buffers; - uint8_t SetBuffers; - uint8_t ActiveBuffers; - uint8_t SetActiveBuffers; - union { - struct { - bool handheld: 1; - bool docked: 1; - unsigned int reserved: 6; - } NX_PACKED ds; - uint8_t general; - } displaySync; - resolutionCalls renderCalls[8]; - resolutionCalls viewportCalls[8]; - bool forceOriginalRefreshRate; - bool dontForce60InDocked; - bool forceSuspend; - uint8_t currentRefreshRate; - float readSpeedPerSecond; - uint8_t FPSlockedDocked; - uint64_t frameNumber; -} NX_PACKED; - -NxFpsSharedBlock* NxFps = 0; -std::atomic GameRunning{false}; -std::atomic check{true}; -std::atomic SaltySD{false}; -std::atomic realVoltsPolling{false}; -uintptr_t FPSaddress = 0; -uintptr_t FPSavgaddress = 0; -uint64_t PID = 0; -uint32_t FPS = 0xFE; -float FPSmin = 254; -float FPSmax = 0; -float FPSavg = 254; -float FPSavg_old = 254; -bool useOldFPSavg = false; -SharedMemory _sharedmemory = {}; -std::atomic SharedMemoryUsed{false}; -Handle remoteSharedMemory = 1; -uint64_t lastFrameNumber = 0; - -//Read real freqs from sys-clk sysmodule -uint32_t realCPU_Hz = 0; -uint32_t realGPU_Hz = 0; -uint32_t realRAM_Hz = 0; -uint32_t partLoad[HocClkPartLoad_EnumMax]; -uint32_t realCPU_mV = 0; -uint32_t realGPU_mV = 0; -uint32_t realVDD2_mV = 0; -uint32_t realVDDQ_mV = 0; -uint32_t realSOC_mV = 0; -uint8_t refreshRate = 0; - -//Read real temps from sys-clk sysmodule -int32_t realCPU_Temp = 0; -int32_t realGPU_Temp = 0; -u32 realPLLX_Temp = 0; -int32_t realRAM_Temp = 0; - -int compare (const void* elem1, const void* elem2) { - if ((((resolutionCalls*)(elem1))->calls) > (((resolutionCalls*)(elem2))->calls)) return -1; - else return 1; -} - -void LoadSharedMemoryAndRefreshRate() { - if (SaltySD_Connect()) - return; - - SaltySD_GetSharedMemoryHandle(&remoteSharedMemory); - SaltySD_GetDisplayRefreshRate(&refreshRate); - SaltySD_Term(); - - shmemLoadRemote(&_sharedmemory, remoteSharedMemory, 0x1000, Perm_Rw); - if (!shmemMap(&_sharedmemory)) - SharedMemoryUsed = true; - else FPS = 1234; -} - -void LoadSharedMemory() { - if (SaltySD_Connect()) - return; - - SaltySD_GetSharedMemoryHandle(&remoteSharedMemory); - SaltySD_Term(); - - shmemLoadRemote(&_sharedmemory, remoteSharedMemory, 0x1000, Perm_Rw); - if (!shmemMap(&_sharedmemory)) - SharedMemoryUsed = true; - else FPS = 1234; -} - -void searchSharedMemoryBlock(uintptr_t base) { - if (!base || !SharedMemoryUsed) { - NxFps = 0; - return; - } - - ptrdiff_t search_offset = 0; - const uintptr_t memory_end = base + 0x1000; - - while (search_offset < 0x1000) { - const uintptr_t current_addr = base + search_offset; - - // Ensure we don't read past the end of shared memory - if (current_addr + sizeof(NxFpsSharedBlock) > memory_end) { - break; - } - - NxFps = (NxFpsSharedBlock*)current_addr; - - // Add bounds checking and magic validation - if (NxFps && current_addr >= base && NxFps->MAGIC == 0x465053) { - return; - } - search_offset += 4; - } - NxFps = 0; -} - -//Check if SaltyNX is working -bool CheckPort() { - Handle saltysd; - - // Try up to 67 times with exponential backoff for better responsiveness - for (int i = 0; i < 50; i++) { - if (R_SUCCEEDED(svcConnectToNamedPort(&saltysd, "InjectServ"))) { - svcCloseHandle(saltysd); - return true; - } - - // Progressive sleep - start fast, then slow down - //if (i < 10) { - // svcSleepThread(100'000); // 0.1ms for first 10 attempts - //} else if (i < 30) { - // svcSleepThread(500'000); // 0.5ms for next 20 attempts - //} else { - // svcSleepThread(1'000'000); // 1ms for remaining attempts - //} - } - - return false; -} - -Mutex mutex_Misc = {0}; - -void CheckIfGameRunning(void*) { - do { - mutexLock(&mutex_Misc); - if (!check && R_FAILED(pmdmntGetApplicationProcessId(&PID))) { - GameRunning = false; - check = true; - } - else if (!GameRunning && SharedMemoryUsed) { - const uintptr_t base = (uintptr_t)shmemGetAddr(&_sharedmemory); - searchSharedMemoryBlock(base); - if (NxFps) { - (NxFps->pluginActive) = false; - mutexUnlock(&mutex_Misc); // ← Fix: Unlock before return - if (leventWait(&threadexit, 100'000'000)) { - return; - } - mutexLock(&mutex_Misc); - if ((NxFps->pluginActive)) { - GameRunning = true; - check = false; - } - } - } - mutexUnlock(&mutex_Misc); - } while (!leventWait(&threadexit, 1'000'000'000)); -} - -// Utils.hpp or your relevant header -static constexpr size_t CACHE_ELEMENTS = sizeof(BatteryTimeCache) / sizeof(BatteryTimeCache[0]); - -Mutex mutex_BatteryChecker = {0}; -void BatteryChecker(void*) { - if (R_FAILED(psmCheck) || R_FAILED(i2cCheck)){ - return; - } - uint16_t data = 0; - float tempV = 0.0; - float tempA = 0.0; - size_t ArraySize = 10; - if (batteryFiltered) { - ArraySize = 1; - } - float* readingsAmp = new float[ArraySize]; - float* readingsVolt = new float[ArraySize]; - - Max17050ReadReg(MAX17050_AvgCurrent, &data); - tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data; - for (size_t i = 0; i < ArraySize; i++) { - readingsAmp[i] = tempA; - } - Max17050ReadReg(MAX17050_AvgVCELL, &data); - tempV = 0.625 * (data >> 3); - for (size_t i = 0; i < ArraySize; i++) { - readingsVolt[i] = tempV; - } - if (!actualFullBatCapacity) { - Max17050ReadReg(MAX17050_FullCAP, &data); - actualFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN; - } - if (!designedFullBatCapacity) { - Max17050ReadReg(MAX17050_DesignCap, &data); - designedFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN; - } - if (readingsAmp[0] >= 0) { - batTimeEstimate = -1; - } - else { - Max17050ReadReg(MAX17050_TTE, &data); - float batteryTimeEstimateInMinutes = (5.625 * data) / 60; - if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) { - batTimeEstimate = (99*60)+59; - } - else batTimeEstimate = (int16_t)batteryTimeEstimateInMinutes; - } - - size_t counter = 0; - uint64_t tick_TTE = svcGetSystemTick(); - uint64_t nanoseconds = 1000; - do { - mutexLock(&mutex_BatteryChecker); - const uint64_t startTick = svcGetSystemTick(); - - psmGetBatteryChargeInfoFields(psmService, &_batteryChargeInfoFields); - - // Calculation is based on Hekate's max17050.c - // Source: https://github.com/CTCaer/hekate/blob/master/bdk/power/max17050.c - - if (!batteryFiltered) { - Max17050ReadReg(MAX17050_Current, &data); - tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data; - Max17050ReadReg(MAX17050_VCELL, &data); - tempV = 0.625 * (data >> 3); - } else { - Max17050ReadReg(MAX17050_AvgCurrent, &data); - tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data; - Max17050ReadReg(MAX17050_AvgVCELL, &data); - tempV = 0.625 * (data >> 3); - } - - if (tempA && tempV) { - readingsAmp[counter % ArraySize] = tempA; - readingsVolt[counter % ArraySize] = tempV; - counter++; - } - - float batCurrent = 0.0; - float batVoltage = 0.0; - float batPowerAvg = 0.0; - for (size_t x = 0; x < ArraySize; x++) { - batCurrent += readingsAmp[x]; - batVoltage += readingsVolt[x]; - batPowerAvg += (readingsAmp[x] * readingsVolt[x]) / 1'000; - } - batCurrent /= ArraySize; - batVoltage /= ArraySize; - batCurrentAvg = batCurrent; - batVoltageAvg = batVoltage; - batPowerAvg /= ArraySize * 1000; - PowerConsumption = batPowerAvg; - - if (batCurrentAvg >= 0) { - batTimeEstimate = -1; - } - else { - static float batteryTimeEstimateInMinutes = 0; - Max17050ReadReg(MAX17050_TTE, &data); - batteryTimeEstimateInMinutes = (5.625 * data) / 60; - if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) { - batteryTimeEstimateInMinutes = (99.0*60.0)+59.0; - } - static int itr = 0; - const int cacheElements = (sizeof(BatteryTimeCache) / sizeof(BatteryTimeCache[0])); - BatteryTimeCache[itr++ % cacheElements] = (int32_t)batteryTimeEstimateInMinutes; - const uint64_t new_tick_TTE = svcGetSystemTick(); - if (armTicksToNs(new_tick_TTE - tick_TTE) / 1'000'000'000 >= batteryTimeLeftRefreshRate) { - const size_t to_divide = itr < cacheElements ? itr : cacheElements; - batTimeEstimate = (int16_t)(std::accumulate(&BatteryTimeCache[0], &BatteryTimeCache[to_divide], 0) / to_divide); - tick_TTE = new_tick_TTE; - } - } - - mutexUnlock(&mutex_BatteryChecker); - nanoseconds = armTicksToNs(svcGetSystemTick() - startTick); - if (nanoseconds < 1'000'000'000 / 2) { - nanoseconds = (1'000'000'000 / 2) - nanoseconds; - } else { - nanoseconds = 1000; - } - } while(!leventWait(&threadexit, nanoseconds)); - - batTimeEstimate = -1; - _batteryChargeInfoFields = {0}; - memset(BatteryTimeCache, 0, sizeof(BatteryTimeCache)); - delete[] readingsAmp; - delete[] readingsVolt; -} - - -void StartBatteryThread() { - //if (!skip) { - // threadWaitForExit(&t7); - // threadClose(&t7); - // leventClear(&threadexit); - //} - leventClear(&threadexit); - threadCreate(&t7, BatteryChecker, NULL, NULL, 0x2000, 0x3F, 3); - threadStart(&t7); -} - -void CloseBatteryThread() { - leventSignal(&threadexit); - threadWaitForExit(&t7); - threadClose(&t7); -} - - - -void gpuLoadThread(void*) { - #define gpu_samples_average 8 - uint32_t gpu_load_array[gpu_samples_average] = {0}; - size_t i = 0; - if (!GPULoadPerFrame && R_SUCCEEDED(nvCheck)) do { - u32 temp; - if (R_SUCCEEDED(nvIoctl(fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &temp))) { - gpu_load_array[i++ % gpu_samples_average] = temp; - GPU_Load_u = std::accumulate(&gpu_load_array[0], &gpu_load_array[gpu_samples_average], 0) / gpu_samples_average; - } - } while(!leventWait(&threadexit, 16'666'000)); -} - -std::string getVersionString() { - char buf[0x100] = ""; // 256 bytes — safe for any expected version string - Result rc = hocclkIpcGetVersionString(buf, sizeof(buf)); - if (R_FAILED(rc) || buf[0] == '\0') { - return "unknown"; - } - return std::string(buf); -} - - -bool usingEOS() { - const std::string versionString = getVersionString(); - return versionString.find("eos") != std::string::npos; -} - -// === ULTRA-FAST VOLTAGE READING === -static constexpr PowerDomainId domains[] = { - PcvPowerDomainId_Max77621_Cpu, // [0] CPU - PcvPowerDomainId_Max77621_Gpu, // [1] GPU - PcvPowerDomainId_Max77812_Dram, // [2] VDD2 (EMC/DRAM) - PcvPowerDomainId_Max77620_Sd0, // [3] SOC - PcvPowerDomainId_Max77620_Sd1 // [4] VDDQ -}; - - -// Stuff that doesn't need multithreading -void Misc(void*) { - const uint64_t timeout_ns = TeslaFPS < 10 ? (1'000'000'000 / TeslaFPS) : 100'000'000; - const bool isUsingEOS = usingEOS(); - - // Initialize voltage reading if needed - bool canReadVoltages = false; - if (!isUsingEOS && realVoltsPolling) { - canReadVoltages = R_SUCCEEDED(rgltrInitialize()); - if (!canReadVoltages) { - realVoltsPolling = false; - } - } - - do { - mutexLock(&mutex_Misc); - - // Get sys-clk data - if (R_SUCCEEDED(hocclkCheck)) { - HocClkContext hocclkCTX; - if (R_SUCCEEDED(hocclkIpcGetCurrentContext(&hocclkCTX))) { - realCPU_Hz = hocclkCTX.realFreqs[HocClkModule_CPU]; - realGPU_Hz = hocclkCTX.realFreqs[HocClkModule_GPU]; - realRAM_Hz = hocclkCTX.realFreqs[HocClkModule_MEM]; - partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC]; - partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu]; - partLoad[HocClkPartLoad_RamBWAll] = hocclkCTX.partLoad[HocClkPartLoad_RamBWAll]; - partLoad[HocClkPartLoad_RamBWCpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWCpu]; - partLoad[HocClkPartLoad_RamBWGpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWGpu]; - partLoad[HocClkPartLoad_RamBWPeak] = hocclkCTX.partLoad[HocClkPartLoad_RamBWPeak]; - realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU]; - realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU]; - realPLLX_Temp = hocclkCTX.temps[HocClkThermalSensor_PLLX]; - realRAM_Temp = hocclkCTX.temps[HocClkThermalSensor_MEM]; - - realCPU_mV = hocclkCTX.voltages[HocClkVoltage_CPU]; - realGPU_mV = hocclkCTX.voltages[HocClkVoltage_GPU]; - realSOC_mV = hocclkCTX.voltages[HocClkVoltage_SOC]; - realVDD2_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDD2]; - realVDDQ_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDDQ]; - CPU_Hz = hocclkCTX.freqs[HocClkModule_CPU]; - GPU_Hz = hocclkCTX.freqs[HocClkModule_GPU]; - RAM_Hz = hocclkCTX.freqs[HocClkModule_MEM]; - } - } - - - // Temperatures - if (R_SUCCEEDED(i2cCheck)) { - Tmp451GetSocTemp(&SOC_temperatureF); - Tmp451GetPcbTemp(&PCB_temperatureF); - } - if (R_SUCCEEDED(tcCheck)) { - tcGetSkinTemperatureMilliC(&skin_temperaturemiliC); - } - - // RAM Memory Used - if (R_SUCCEEDED(Hinted)) { - svcGetSystemInfo(&RAM_Total_application_u, 0, INVALID_HANDLE, 0); - svcGetSystemInfo(&RAM_Total_applet_u, 0, INVALID_HANDLE, 1); - svcGetSystemInfo(&RAM_Total_system_u, 0, INVALID_HANDLE, 2); - svcGetSystemInfo(&RAM_Total_systemunsafe_u, 0, INVALID_HANDLE, 3); - svcGetSystemInfo(&RAM_Used_application_u, 1, INVALID_HANDLE, 0); - svcGetSystemInfo(&RAM_Used_applet_u, 1, INVALID_HANDLE, 1); - svcGetSystemInfo(&RAM_Used_system_u, 1, INVALID_HANDLE, 2); - svcGetSystemInfo(&RAM_Used_systemunsafe_u, 1, INVALID_HANDLE, 3); - } - - // Fan - if (R_SUCCEEDED(pwmCheck)) { - double temp = 0; - if (R_SUCCEEDED(pwmChannelSessionGetDutyCycle(&g_ICon, &temp))) { - temp *= 10; - temp = trunc(temp); - temp /= 10; - Rotation_Duty = 100.0 - temp; - if (Rotation_Duty <= 0) { - Rotation_Duty = 0.0000001; - } - } - } - - // GPU Load - if (R_SUCCEEDED(nvCheck) && GPULoadPerFrame) { - nvIoctl(fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &GPU_Load_u); - } - - // FPS - with proper null checks - if (GameRunning) { - if (NxFps && SharedMemoryUsed) { - FPS = NxFps->FPS; - const size_t element_count = sizeof(NxFps->FPSticks) / sizeof(NxFps->FPSticks[0]); - FPSavg_old = static_cast(systemtickfrequency) / - (std::accumulate(&NxFps->FPSticks[0], &NxFps->FPSticks[element_count], 0.0f) / element_count); - - const float FPS_in = static_cast(FPS); - if (FPSavg_old >= (FPS_in - 0.25f) && FPSavg_old <= (FPS_in + 0.25f)) { - FPSavg = FPS_in; - } else { - FPSavg = FPSavg_old; - } - - lastFrameNumber = NxFps->frameNumber; - - if (FPSavg > FPSmax) FPSmax = FPSavg; - if (FPSavg < FPSmin) FPSmin = FPSavg; - } - } else { - FPSavg = 254; - FPSmin = 254; - FPSmax = 0; - } - - mutexUnlock(&mutex_Misc); - - } while (!leventWait(&threadexit, timeout_ns)); - - // Cleanup voltage reading if initialized - if (canReadVoltages) { - rgltrExit(); - } -} - -void Misc2(void*) { - u32 dummy = 0; - do { - //DSP - if (R_SUCCEEDED(audsnoopCheck)) audsnoopGetDspUsage(&DSP_Load_u); - - //Multimedia clock rates - if (R_SUCCEEDED(nvdecCheck)) mmuRequestGet(&nvdecRequest, &NVDEC_Hz); - if (R_SUCCEEDED(nvencCheck)) mmuRequestGet(&nvencRequest, &NVENC_Hz); - if (R_SUCCEEDED(nvjpgCheck)) mmuRequestGet(&nvjpgRequest, &NVJPG_Hz); - - if (R_SUCCEEDED(nifmCheck)) { - //u32 dummy = 0; - Nifm_internet_rc = nifmGetInternetConnectionStatus(&NifmConnectionType, &dummy, &NifmConnectionStatus); - if (!Nifm_internet_rc && (NifmConnectionType == NifmInternetConnectionType_WiFi)) - Nifm_profile_rc = nifmGetCurrentNetworkProfile((NifmNetworkProfileData*)&Nifm_profile); - } - } while (!leventWait(&threadexit, 100'000'000)); -} - -void Misc3(void*) { - const bool isUsingEOS = usingEOS(); - - // Initialize voltage reading if needed - bool canReadVoltages = false; - if (!isUsingEOS && realVoltsPolling) { - canReadVoltages = R_SUCCEEDED(rgltrInitialize()); - if (!canReadVoltages) { - realVoltsPolling = false; - } - } - - do { - mutexLock(&mutex_Misc); - - // Get sys-clk data - if (R_SUCCEEDED(hocclkCheck)) { - HocClkContext hocclkCTX; - if (R_SUCCEEDED(hocclkIpcGetCurrentContext(&hocclkCTX))) { - partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC]; - partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu]; - partLoad[HocClkPartLoad_RamBWAll] = hocclkCTX.partLoad[HocClkPartLoad_RamBWAll]; - partLoad[HocClkPartLoad_RamBWCpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWCpu]; - partLoad[HocClkPartLoad_RamBWGpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWGpu]; - partLoad[HocClkPartLoad_RamBWPeak] = hocclkCTX.partLoad[HocClkPartLoad_RamBWPeak]; - - realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU]; - realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU]; - realPLLX_Temp = hocclkCTX.temps[HocClkThermalSensor_PLLX]; - realRAM_Temp = hocclkCTX.temps[HocClkThermalSensor_MEM]; - - realCPU_mV = hocclkCTX.voltages[HocClkVoltage_CPU]; - realGPU_mV = hocclkCTX.voltages[HocClkVoltage_GPU]; - realSOC_mV = hocclkCTX.voltages[HocClkVoltage_SOC]; - realVDD2_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDD2]; - realVDDQ_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDDQ]; - - } - } - - - // Temperatures - if (R_SUCCEEDED(i2cCheck)) { - Tmp451GetSocTemp(&SOC_temperatureF); - Tmp451GetPcbTemp(&PCB_temperatureF); - } - if (R_SUCCEEDED(tcCheck)) { - tcGetSkinTemperatureMilliC(&skin_temperaturemiliC); - } - - // Fan - if (R_SUCCEEDED(pwmCheck)) { - double temp = 0; - if (R_SUCCEEDED(pwmChannelSessionGetDutyCycle(&g_ICon, &temp))) { - temp *= 10; - temp = trunc(temp); - temp /= 10; - Rotation_Duty = 100.0 - temp; - if (Rotation_Duty <= 0) { - Rotation_Duty = 0.0000001; - } - } - } - - // GPU Load - if (R_SUCCEEDED(nvCheck)) { - nvIoctl(fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &GPU_Load_u); - } - - mutexUnlock(&mutex_Misc); - - } while (!leventWait(&threadexit, 1'000'000'000)); // 1 second timeout - - // Cleanup voltage reading if initialized - if (canReadVoltages) { - rgltrExit(); - } -} - -//Check each core for idled ticks in intervals, they cannot read info about other core than they are assigned -//In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less -//This is because making each loop also takes time, which is not considered because this will take also additional time - -//Check each core for idled ticks in intervals, they cannot read info about other core than they are assigned -//In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less -//This is because making each loop also takes time, which is not considered because this will take also additional time -//void CheckCore0(void*) { -// uint64_t timeout_ns = 1'000'000'000 / TeslaFPS; -// while(true) { -// uint64_t idletick_a0 = 0; -// uint64_t idletick_b0 = 0; -// svcGetInfo(&idletick_b0, InfoType_IdleTickCount, INVALID_HANDLE, 0); -// if (leventWait(&threadexit, timeout_ns)) -// return; -// svcGetInfo(&idletick_a0, InfoType_IdleTickCount, INVALID_HANDLE, 0); -// idletick0 = idletick_a0 - idletick_b0; -// } -//} -// -//void CheckCore1(void*) { -// uint64_t timeout_ns = 1'000'000'000 / TeslaFPS; -// while(true) { -// uint64_t idletick_a1 = 0; -// uint64_t idletick_b1 = 0; -// svcGetInfo(&idletick_b1, InfoType_IdleTickCount, INVALID_HANDLE, 1); -// if (leventWait(&threadexit, timeout_ns)) -// return; -// svcGetInfo(&idletick_a1, InfoType_IdleTickCount, INVALID_HANDLE, 1); -// idletick1 = idletick_a1 - idletick_b1; -// } -//} -// -//void CheckCore2(void*) { -// uint64_t timeout_ns = 1'000'000'000 / TeslaFPS; -// while(true) { -// uint64_t idletick_a2 = 0; -// uint64_t idletick_b2 = 0; -// svcGetInfo(&idletick_b2, InfoType_IdleTickCount, INVALID_HANDLE, 2); -// if (leventWait(&threadexit, timeout_ns)) -// return; -// svcGetInfo(&idletick_a2, InfoType_IdleTickCount, INVALID_HANDLE, 2); -// idletick2 = idletick_a2 - idletick_b2; -// } -//} -// -//void CheckCore3(void*) { -// uint64_t timeout_ns = 1'000'000'000 / TeslaFPS; -// while(true) { -// uint64_t idletick_a3 = 0; -// uint64_t idletick_b3 = 0; -// svcGetInfo(&idletick_b3, InfoType_IdleTickCount, INVALID_HANDLE, 3); -// if (leventWait(&threadexit, timeout_ns)) -// return; -// svcGetInfo(&idletick_a3, InfoType_IdleTickCount, INVALID_HANDLE, 3); -// idletick3 = idletick_a3 - idletick_b3; -// } -//} - -void CheckCore(void* idletick_ptr) { - const uint64_t timeout_ns = 1'000'000'000ULL / TeslaFPS; - std::atomic* idletick = (std::atomic*)idletick_ptr; - while (true) { - uint64_t idletick_a; - uint64_t idletick_b; - svcGetInfo(&idletick_b, InfoType_IdleTickCount, INVALID_HANDLE, -1); - Result rc_break = leventWait(&threadexit, timeout_ns); - svcGetInfo(&idletick_a, InfoType_IdleTickCount, INVALID_HANDLE, -1); - if (rc_break) return; - idletick->store(idletick_a - idletick_b, std::memory_order_release); - } -} - - -//Start reading all stats -void StartThreads() { - // Clear the thread exit event for new threads - leventClear(&threadexit); - - threadCreate(&t0, CheckCore, &idletick0, NULL, 0x1000, 0x10, 0); - threadCreate(&t1, CheckCore, &idletick1, NULL, 0x1000, 0x10, 1); - threadCreate(&t2, CheckCore, &idletick2, NULL, 0x1000, 0x10, 2); - threadCreate(&t3, CheckCore, &idletick3, NULL, 0x1000, 0x10, 3); - - //threadCreate(&t0, CheckCore, &coreIds[0], NULL, 0x1000, 0x10, 0); - //threadCreate(&t1, CheckCore, &coreIds[1], NULL, 0x1000, 0x10, 1); - //threadCreate(&t2, CheckCore, &coreIds[2], NULL, 0x1000, 0x10, 2); - //threadCreate(&t3, CheckCore, &coreIds[3], NULL, 0x1000, 0x10, 3); - threadCreate(&t4, Misc, NULL, NULL, 0x4000, 0x3F, -2); - threadCreate(&t5, gpuLoadThread, NULL, NULL, 0x1000, 0x3F, -2); - threadCreate(&t7, BatteryChecker, NULL, NULL, 0x4000, 0x3F, -2); - - threadStart(&t0); - threadStart(&t1); - threadStart(&t2); - threadStart(&t3); - threadStart(&t4); - threadStart(&t5); - threadStart(&t7); - - if (SaltySD) { - //Assign NX-FPS to default core - threadCreate(&t6, CheckIfGameRunning, NULL, NULL, 0x1000, 0x38, -2); - threadStart(&t6); - } -} - -//End reading all stats -void CloseThreads() { - leventSignal(&threadexit); - threadWaitForExit(&t0); - threadWaitForExit(&t1); - threadWaitForExit(&t2); - threadWaitForExit(&t3); - threadWaitForExit(&t4); - threadWaitForExit(&t5); - threadWaitForExit(&t6); - threadWaitForExit(&t7); - threadClose(&t0); - threadClose(&t1); - threadClose(&t2); - threadClose(&t3); - threadClose(&t4); - threadClose(&t5); - threadClose(&t6); - threadClose(&t7); -} - -//Separate functions dedicated to "FPS Counter" mode -void FPSCounter(void*) { - const uint64_t timeout_ns = 1'000'000'000 / TeslaFPS; - do { - if (GameRunning) { - if (SharedMemoryUsed && NxFps) { - FPS = (NxFps -> FPS); - const size_t element_count = sizeof(NxFps -> FPSticks) / sizeof(NxFps -> FPSticks[0]); - FPSavg_old = (float)systemtickfrequency / (std::accumulate(&NxFps->FPSticks[0], &NxFps->FPSticks[element_count], 0) / element_count); - const float FPS_in = (float)FPS; - if (FPSavg_old >= (FPS_in-0.25) && FPSavg_old <= (FPS_in+0.25)) - FPSavg = FPS_in; - else FPSavg = FPSavg_old; - lastFrameNumber = NxFps -> frameNumber; - } - } - else FPSavg = 254; - } while (!leventWait(&threadexit, timeout_ns)); -} - -void StartFPSCounterThread() { - leventClear(&threadexit); - - threadCreate(&t6, CheckIfGameRunning, NULL, NULL, 0x1000, 0x38, -2); - threadStart(&t6); - - threadCreate(&t4, FPSCounter, NULL, NULL, 0x1000, 0x3F, 3); - threadStart(&t4); -} - -void EndFPSCounterThread() { - leventSignal(&threadexit); - threadWaitForExit(&t6); - threadWaitForExit(&t4); - threadClose(&t6); - threadClose(&t4); -} - -void StartInfoThread() { - // Clear the thread exit event for new threads - leventClear(&threadexit); - - threadCreate(&t0, CheckCore, &idletick0, NULL, 0x1000, 0x10, 0); - threadCreate(&t1, CheckCore, &idletick1, NULL, 0x1000, 0x10, 1); - threadCreate(&t2, CheckCore, &idletick2, NULL, 0x1000, 0x10, 2); - threadCreate(&t3, CheckCore, &idletick3, NULL, 0x1000, 0x10, 3); - - //threadCreate(&t1, CheckCore, &coreIds[0], NULL, 0x1000, 0x10, 0); - //threadCreate(&t2, CheckCore, &coreIds[1], NULL, 0x1000, 0x10, 1); - //threadCreate(&t3, CheckCore, &coreIds[2], NULL, 0x1000, 0x10, 2); - //threadCreate(&t4, CheckCore, &coreIds[3], NULL, 0x1000, 0x10, 3); - threadCreate(&t7, Misc3, NULL, NULL, 0x1000, 0x3F, -2); - - threadStart(&t0); - threadStart(&t1); - threadStart(&t2); - threadStart(&t3); - threadStart(&t7); -} - -void EndInfoThread() { - // Signal the thread exit event - leventSignal(&threadexit); - - // Wait for all threads to exit - threadWaitForExit(&t0); - threadWaitForExit(&t1); - threadWaitForExit(&t2); - threadWaitForExit(&t3); - threadWaitForExit(&t7); - - // Close thread handles - threadClose(&t0); - threadClose(&t1); - threadClose(&t2); - threadClose(&t3); - threadClose(&t7); -} - -// String formatting functions -void removeSpaces(std::string& str) { - str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); -} - -void convertToUpper(std::string& str) { - std::transform(str.begin(), str.end(), str.begin(), ::toupper); -} - -void convertToLower(std::string& str) { - std::transform(str.begin(), str.end(), str.begin(), ::tolower); -} - -std::map replaces{ - {"A", "\uE0E0"}, - {"B", "\uE0E1"}, - {"X", "\uE0E2"}, - {"Y", "\uE0E3"}, - {"L", "\uE0E4"}, - {"R", "\uE0E5"}, - {"ZL", "\uE0E6"}, - {"ZR", "\uE0E7"}, - {"SL", "\uE0E8"}, - {"SR", "\uE0E9"}, - {"DUP", "\uE0EB"}, - {"DDOWN", "\uE0EC"}, - {"DLEFT", "\uE0ED"}, - {"DRIGHT", "\uE0EE"}, - {"PLUS", "\uE0EF"}, - {"MINUS", "\uE0F0"}, - {"LSTICK", "\uE104"}, - {"RSTICK", "\uE105"}, - {"RS", "\uE105"}, - {"LS", "\uE104"} -}; - -void formatButtonCombination(std::string& line) { - // Remove all spaces from the line - line.erase(std::remove(line.begin(), line.end(), ' '), line.end()); - - // Replace '+' with ' + ' - size_t pos = 0; - size_t max_pluses = 3; - while ((pos = line.find('+', pos)) != std::string::npos) { - if (!max_pluses) { - line = line.substr(0, pos); - return; - } - if (pos > 0 && pos < line.size() - 1) { - if (std::isalnum(line[pos - 1]) && std::isalnum(line[pos + 1])) { - line.replace(pos, 1, " + "); - pos += 3; - } - } - ++pos; - max_pluses--; - } - pos = 0; - size_t old_pos = 0; - - static std::string button; - while ((pos = line.find(" + ", pos)) != std::string::npos) { - - button = line.substr(old_pos, pos - old_pos); - if (replaces.find(button) != replaces.end()) { - line.replace(old_pos, button.length(), replaces[button]); - pos = 0; - old_pos = 0; - } - else pos += 3; - old_pos = pos; - } - button = line.substr(old_pos); - if (replaces.find(button) != replaces.end()) { - line.replace(old_pos, button.length(), replaces[button]); - } -} - -//uint64_t comboBitmask = 0; -// -//constexpr uint64_t MapButtons(const std::string& buttonCombo) { -// static std::map buttonMap = { -// {"A", HidNpadButton_A}, -// {"B", HidNpadButton_B}, -// {"X", HidNpadButton_X}, -// {"Y", HidNpadButton_Y}, -// {"L", HidNpadButton_L}, -// {"R", HidNpadButton_R}, -// {"ZL", HidNpadButton_ZL}, -// {"ZR", HidNpadButton_ZR}, -// {"PLUS", HidNpadButton_Plus}, -// {"MINUS", HidNpadButton_Minus}, -// {"DUP", HidNpadButton_Up}, -// {"DDOWN", HidNpadButton_Down}, -// {"DLEFT", HidNpadButton_Left}, -// {"DRIGHT", HidNpadButton_Right}, -// {"SL", HidNpadButton_AnySL}, -// {"SR", HidNpadButton_AnySR}, -// {"LSTICK", HidNpadButton_StickL}, -// {"RSTICK", HidNpadButton_StickR}, -// {"LS", HidNpadButton_StickL}, -// {"RS", HidNpadButton_StickR}, -// {"UP", HidNpadButton_AnyUp}, -// {"DOWN", HidNpadButton_AnyDown}, -// {"LEFT", HidNpadButton_AnyLeft}, -// {"RIGHT", HidNpadButton_AnyRight} -// }; -// -// -// std::string comboCopy = buttonCombo; // Make a copy of buttonCombo -// -// static const std::string delimiter = "+"; -// size_t pos = 0; -// static std::string button; -// size_t max_delimiters = 4; -// while ((pos = comboCopy.find(delimiter)) != std::string::npos) { -// button = comboCopy.substr(0, pos); -// if (buttonMap.find(button) != buttonMap.end()) { -// comboBitmask |= buttonMap[button]; -// } -// comboCopy.erase(0, pos + delimiter.length()); -// if (!--max_delimiters) { -// return comboBitmask; -// } -// } -// if (buttonMap.find(comboCopy) != buttonMap.end()) { -// comboBitmask |= buttonMap[comboCopy]; -// } -// return comboBitmask; -//} - -ALWAYS_INLINE bool isKeyComboPressed(uint64_t keysHeld, uint64_t keysDown) { - // Check if any of the combo buttons are pressed down this frame - // while the rest of the combo buttons are being held - - const uint64_t comboButtonsDown = keysDown & tsl::cfg::launchCombo; - const uint64_t comboButtonsHeld = keysHeld & tsl::cfg::launchCombo; - - // If any combo buttons are pressed down this frame - if (comboButtonsDown != 0) { - // Check if the remaining combo buttons are being held - // (the full combo should be active when combining held + down) - const uint64_t totalComboActive = comboButtonsHeld | comboButtonsDown; - - if (totalComboActive == tsl::cfg::launchCombo) { - fixHiding = true; // for fixing hiding when returning - //triggerRumbleDoubleClick.store(true, std::memory_order_release); - //triggerExitSound.store(true, std::memory_order_release); - return true; - } - } - - return false; -} - -inline int safeFanDuty(int raw) { - if (raw < 0) return 0; - if (raw > 100) return 100; - return raw; -} - -// Helper function to check if comboBitmask is satisfied with at least one key in keysDown and the rest in keysHeld -bool isKeyComboPressed2(uint64_t keysDown, uint64_t keysHeld) { - uint64_t requiredKeys = tsl::cfg::launchCombo; - bool hasKeyDown = false; // Tracks if at least one key is in keysDown - - static uint64_t keyBit; - // Iterate over each bit in the comboBitmask - while (requiredKeys) { - keyBit = requiredKeys & ~(requiredKeys - 1); // Get the lowest bit set in requiredKeys - - // Check if the key is in keysDown or keysHeld - if (keysDown & keyBit) { - hasKeyDown = true; // Found at least one key in keysDown - } else if (!(keysHeld & keyBit)) { - return false; // If the key is neither in keysDown nor keysHeld, the combo is incomplete - } - - // Remove the lowest bit and continue to check other keys - requiredKeys &= ~keyBit; - } - - // Ensure that at least one key was in keysDown and the rest were in keysHeld - return hasKeyDown; -} - - -// Custom utility function for parsing an ini file -void ParseIniFile() { - // Check and create directory if needed - //struct stat st; - //if (stat(directoryPath, &st) != 0) { - // mkdir(directoryPath, 0777); - //} - ult::createSingleDirectory(directoryPath); - - // Load main config INI once - auto configData = ult::getParsedDataFromIniFile(configIniPath); - auto statusIt = configData.find("status-monitor"); - - if (statusIt != configData.end()) { - const auto& statusSection = statusIt->second; - std::string key; - - // Process all settings with direct lookups - auto batteryFilterIt = statusSection.find("battery_avg_iir_filter"); - if (batteryFilterIt != statusSection.end()) { - key = batteryFilterIt->second; - convertToUpper(key); - batteryFiltered = (key == "TRUE"); - } - - auto refreshRateIt = statusSection.find("battery_time_left_refreshrate"); - if (refreshRateIt != statusSection.end()) { - batteryTimeLeftRefreshRate = std::clamp(atol(refreshRateIt->second.c_str()), 1L, 60L); - } - - auto gpuLoadIt = statusSection.find("average_gpu_load"); - if (gpuLoadIt != statusSection.end()) { - key = gpuLoadIt->second; - convertToUpper(key); - GPULoadPerFrame = (key != "TRUE"); - } - - auto fpsAvgIt = statusSection.find("use_old_fps_average"); - if (fpsAvgIt != statusSection.end()) { - key = fpsAvgIt->second; - convertToUpper(key); - useOldFPSavg = (key == "TRUE"); - } - } - - // Handle external combo - load each file once - const struct { const char* path; const char* section; } externalConfigs[] = { - {ultrahandConfigIniPath, "ultrahand"}, - {teslaConfigIniPath, "tesla"} - }; - - for (const auto& config : externalConfigs) { - auto extConfigData = ult::getParsedDataFromIniFile(config.path); - auto sectionIt = extConfigData.find(config.section); - - if (sectionIt != extConfigData.end()) { - auto keyComboIt = sectionIt->second.find("key_combo"); - if (keyComboIt != sectionIt->second.end() && !keyComboIt->second.empty()) { - keyCombo = keyComboIt->second; - removeSpaces(keyCombo); - convertToUpper(keyCombo); - break; - } - } - } - - //comboBitmask = MapButtons(keyCombo); -} - -ALWAYS_INLINE bool isValidRGBA4Color(const std::string& hexColor) { - const char* data = hexColor.data(); - const size_t size = hexColor.size(); - - static unsigned char c; - for (size_t i = 0; i < size; ++i) { - c = data[i]; - // Branchless hex digit check: (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') - if (!((c - '0') <= 9 || (c - 'A') <= 5 || (c - 'a') <= 5)) { - return false; - } - } - - return true; -} - -bool convertStrToRGBA4444(std::string hexColor, uint16_t* returnValue) { - // Check if # is present - if (hexColor.size() != 5 || hexColor[0] != '#') - return false; - - hexColor = hexColor.substr(1); - - if (isValidRGBA4Color(hexColor)) { - *returnValue = std::stoi(std::string(hexColor.rbegin(), hexColor.rend()), nullptr, 16); - return true; - } - return false; -} - -struct FullSettings { - uint8_t refreshRate; - bool setPosRight; - bool showRealFreqs; - bool realVolts; - bool realTemps; - bool showDeltas; - bool showTargetFreqs; - bool showFPS; - bool showRES; - bool showRDSD; - std::string ramInfoMode; - bool useDynamicColors; - bool disableScreenshots; - uint16_t separatorColor; - uint16_t catColor1; - uint16_t catColor2; - uint16_t textColor; -}; - -struct MiniSettings { - uint8_t refreshRate; - bool realFrequencies; - bool realVolts; - bool realTemps; - bool showFullCPU; - bool showFullResolution; - bool showFanPercentage; - bool showSOCVoltage; - bool useDynamicColors; - bool showVDDQ; - bool showVDD2; - bool decimalVDD2; - bool showDTC; - bool useDTCSymbol; - std::string dtcFormat; - size_t handheldFontSize; - size_t dockedFontSize; - size_t spacing; - uint16_t backgroundColor; - uint16_t focusBackgroundColor; - uint16_t separatorColor; - uint16_t catColor; - uint16_t textColor; - std::string show; - bool showpartLoad; - bool showpartLoadCPUGPU; - std::string ramInfoMode; - bool invertBatteryDisplay; - bool disableScreenshots; - bool sleepExit; - //int setPos; - int frameOffsetX; - int frameOffsetY; - size_t framePadding; -}; - -struct MicroSettings { - uint8_t refreshRate; - bool realFrequencies; - bool realVolts; - bool realTemps; - bool showFullCPU; - bool showFullResolution; - bool showSOCVoltage; - bool useDynamicColors; - bool showVDDQ; - bool showVDD2; - bool decimalVDD2; - bool showDTC; - bool useDTCSymbol; - std::string dtcFormat; - bool invertBatteryDisplay; - size_t handheldFontSize; - size_t dockedFontSize; - uint8_t alignTo; - uint16_t backgroundColor; - uint16_t separatorColor; - uint16_t catColor; - uint16_t textColor; - std::string show; - bool showpartLoad; - std::string ramInfoMode; - bool setPosBottom; - bool disableScreenshots; - bool sleepExit; -}; - -struct FpsCounterSettings { - uint8_t refreshRate; - size_t handheldFontSize; - size_t dockedFontSize; - uint16_t backgroundColor; - uint16_t focusBackgroundColor; - uint16_t textColor; - //int setPos; - bool useIntegerCounter; - bool disableScreenshots; - int frameOffsetX; - int frameOffsetY; - size_t framePadding; -}; - -struct FpsGraphSettings { - bool showInfo; - bool realTemps; - uint8_t refreshRate; - uint16_t backgroundColor; - uint16_t focusBackgroundColor; - uint16_t fpsColor; - uint16_t mainLineColor; - uint16_t roundedLineColor; - uint16_t perfectLineColor; - uint16_t dashedLineColor; - uint16_t borderColor; - uint16_t maxFPSTextColor; - uint16_t minFPSTextColor; - uint16_t textColor; - uint16_t catColor; - //int setPos; - bool useDynamicColors; - bool disableScreenshots; - int frameOffsetX; - int frameOffsetY; - size_t framePadding; -}; - -struct ResolutionSettings { - uint8_t refreshRate; - uint16_t backgroundColor; - uint16_t focusBackgroundColor; - uint16_t catColor; - //uint16_t catColor2; - uint16_t textColor; - //int setPos; - bool disableScreenshots; - - int frameOffsetX; - int frameOffsetY; - size_t framePadding; -}; - -ALWAYS_INLINE void GetConfigSettings(MiniSettings* settings) { - // Initialize defaults - settings->realFrequencies = true; - settings->realVolts = true; - settings->realTemps = true; - settings->showFullCPU = false; - settings->showFullResolution = true; - settings->showFanPercentage = true; - settings->useDynamicColors = true; - settings->showFullCPU = false; - settings->showSOCVoltage = false; - settings->showVDDQ = false; - settings->showVDD2 = true; - settings->decimalVDD2 = false; - settings->showDTC = true; - settings->useDTCSymbol = true; - settings->dtcFormat = "%m-%d-%Y%H:%M:%S";//"%Y-%m-%d %I:%M:%S %p"; - settings->handheldFontSize = 15; - settings->dockedFontSize = 15; - settings->spacing = 8; - convertStrToRGBA4444("#0009", &(settings->backgroundColor)); - convertStrToRGBA4444("#000F", &(settings->focusBackgroundColor)); - convertStrToRGBA4444("#888F", &(settings->separatorColor)); - convertStrToRGBA4444("#2DFF", &(settings->catColor)); - convertStrToRGBA4444("#FFFF", &(settings->textColor)); - settings->show = "DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES"; - settings->showpartLoad = true; - settings->showpartLoadCPUGPU = false; - settings->ramInfoMode = "LOAD"; - settings->invertBatteryDisplay = true; - settings->refreshRate = 1; - settings->disableScreenshots = false; - settings->sleepExit = false; - //settings->setPos = 0; - settings->frameOffsetX = 10; - settings->frameOffsetY = 10; - settings->framePadding = 10; - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("mini"); - if (sectionIt == parsedData.end()) return; - - std::string key; - uint16_t temp; - - const auto& section = sectionIt->second; - - // Process refresh_rate - auto it = section.find("refresh_rate"); - if (it != section.end()) { - settings->refreshRate = std::clamp(atol(it->second.c_str()), 1L, 60L); - } - - // Process boolean flags - it = section.find("real_freqs"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realFrequencies = (key == "TRUE"); - } - - it = section.find("real_volts"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realVolts = (key == "TRUE"); - } - - it = section.find("real_temps"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realTemps = (key == "TRUE"); - } - - // Process font sizes with shared bounds - static constexpr long minFontSize = 8; - static constexpr long maxFontSize = 22; - - it = section.find("handheld_font_size"); - if (it != section.end()) { - settings->handheldFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - it = section.find("docked_font_size"); - if (it != section.end()) { - settings->dockedFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - it = section.find("spacing"); - if (it != section.end()) { - settings->spacing = atol(it->second.c_str()); - } - - // Process colors - it = section.find("background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->backgroundColor = temp; - } - it = section.find("focus_background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->focusBackgroundColor = temp; - } - - it = section.find("separator_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->separatorColor = temp; - } - - it = section.find("cat_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->catColor = temp; - } - - it = section.find("text_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->textColor = temp; - } - - // Process RAM load flag - it = section.find("show_full_cpu"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showFullCPU = !(key == "FALSE"); - } - - it = section.find("show_full_res"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showFullResolution = !(key == "FALSE"); - } - - it = section.find("show_soc_voltage"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showSOCVoltage = !(key == "FALSE"); - } - - it = section.find("use_dynamic_colors"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDynamicColors = (key == "TRUE"); - } - - it = section.find("show_vddq"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showVDDQ = !(key == "FALSE"); - } - - it = section.find("show_vdd2"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showVDD2 = !(key == "FALSE"); - } - - it = section.find("decimal_vdd2"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->decimalVDD2 = !(key == "FALSE"); - } - - it = section.find("show_dtc"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showDTC = !(key == "FALSE"); - } - - it = section.find("use_dtc_symbol"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDTCSymbol = !(key == "FALSE"); - } - - it = section.find("dtc_format"); - if (it != section.end()) { - key = it->second; - settings->dtcFormat = std::move(key); - } - - // Process show string - it = section.find("show"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->show = std::move(key); - } - - // Process RAM load flag - it = section.find("replace_MB_with_RAM_load"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showpartLoad = (key != "FALSE"); - } - - // Process CPU/GPU RAM load flag - it = section.find("show_RAM_load_CPU_GPU"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showpartLoadCPUGPU = (key != "FALSE"); - } - - // Process RAM info mode - it = section.find("ram_info_mode"); - if (it != section.end()) { - settings->ramInfoMode = it->second; - } - - // Invert the battery display value - it = section.find("invert_battery_display"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->invertBatteryDisplay = (key != "FALSE"); - } - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } - - // Process exit on sleep - it = section.find("sleep_exit"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->sleepExit = (key != "FALSE"); - } - - // Process alignment settings - //it = section.find("layer_width_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos = 1; - // } else if (key == "RIGHT") { - // settings->setPos = 2; - // } - //} - // - //it = section.find("layer_height_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos += 3; - // } else if (key == "BOTTOM") { - // settings->setPos += 6; - // } - //} - - it = section.find("frame_offset_x"); - if (it != section.end()) { - settings->frameOffsetX = atol(it->second.c_str()); - } - - it = section.find("frame_offset_y"); - if (it != section.end()) { - settings->frameOffsetY = atol(it->second.c_str()); - } - - it = section.find("frame_padding"); - if (it != section.end()) { - settings->framePadding = atol(it->second.c_str()); - } -} - -ALWAYS_INLINE void GetConfigSettings(MicroSettings* settings) { - // Initialize defaults - settings->realFrequencies = true; - settings->realVolts = true; - settings->realTemps = true; - settings->showFullCPU = false; - settings->showFullResolution = false; - settings->showSOCVoltage = true; - settings->useDynamicColors = true; - settings->showVDDQ = false; - settings->showVDD2 = true; - settings->decimalVDD2 = false; - settings->showDTC = true; - settings->useDTCSymbol = true; - settings->dtcFormat = "%H:%M:%S";//"%Y-%m-%d %I:%M:%S %p"; - settings->invertBatteryDisplay = false; - settings->handheldFontSize = 14; - settings->dockedFontSize = 14; - settings->alignTo = 1; // CENTER - convertStrToRGBA4444("#0009", &(settings->backgroundColor)); - convertStrToRGBA4444("#888F", &(settings->separatorColor)); - convertStrToRGBA4444("#2DFF", &(settings->catColor)); - convertStrToRGBA4444("#FFFF", &(settings->textColor)); - settings->show = "FPS+CPU+GPU+RAM+SOC+BAT+DTC"; - settings->showpartLoad = true; - settings->ramInfoMode = "LOAD"; - settings->setPosBottom = false; - settings->disableScreenshots = false; - settings->sleepExit = false; - settings->refreshRate = 1; - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("micro"); - if (sectionIt == parsedData.end()) return; - - std::string key; - uint16_t temp; - - const auto& section = sectionIt->second; - - // Process refresh_rate - auto it = section.find("refresh_rate"); - if (it != section.end()) { - settings->refreshRate = std::clamp(atol(it->second.c_str()), 1L, 60L); - } - - // Process boolean flags - it = section.find("real_freqs"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realFrequencies = (key == "TRUE"); - } - - it = section.find("real_volts"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realVolts = (key == "TRUE"); - } - - it = section.find("real_temps"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realTemps = (key == "TRUE"); - } - - it = section.find("show_full_cpu"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showFullCPU = (key == "TRUE"); - } - - it = section.find("show_full_res"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showFullResolution = (key == "TRUE"); - } - - it = section.find("show_soc_voltage"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showSOCVoltage = !(key == "FALSE"); - } - - it = section.find("use_dynamic_colors"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDynamicColors = (key == "TRUE"); - } - - it = section.find("show_vddq"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showVDDQ = !(key == "FALSE"); - } - - it = section.find("show_vdd2"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showVDD2 = !(key == "FALSE"); - } - - it = section.find("decimal_vdd2"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->decimalVDD2 = !(key == "FALSE"); - } - - it = section.find("show_dtc"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showDTC = !(key == "FALSE"); - } - - it = section.find("use_dtc_symbol"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDTCSymbol = !(key == "FALSE"); - } - - it = section.find("dtc_format"); - if (it != section.end()) { - key = it->second; - settings->dtcFormat = std::move(key); - } - - // Invert the battery display value - it = section.find("invert_battery_display"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->invertBatteryDisplay = (key != "FALSE"); - } - - // Process font sizes with shared bounds - static constexpr long minFontSize = 8; - static constexpr long maxFontSize = 18; - - it = section.find("handheld_font_size"); - if (it != section.end()) { - settings->handheldFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - it = section.find("docked_font_size"); - if (it != section.end()) { - settings->dockedFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - // Process colors - it = section.find("background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->backgroundColor = temp; - } - - it = section.find("separator_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->separatorColor = temp; - } - - it = section.find("cat_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->catColor = temp; - } - - it = section.find("text_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->textColor = temp; - } - - // Process text alignment - it = section.find("text_align"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - if (key == "LEFT") { - settings->alignTo = 0; - } else if (key == "CENTER") { - settings->alignTo = 1; - } else if (key == "RIGHT") { - settings->alignTo = 2; - } - } - - // Process RAM load flag - it = section.find("replace_GB_with_RAM_load"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showpartLoad = (key != "FALSE"); - } - - // Process RAM info mode - it = section.find("ram_info_mode"); - if (it != section.end()) { - settings->ramInfoMode = it->second; - } - - // Process show string - it = section.find("show"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->show = std::move(key); - } - - // Process layer height alignment - it = section.find("layer_height_align"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->setPosBottom = (key == "BOTTOM"); - } - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } - - // Process exit on sleep - it = section.find("sleep_exit"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->sleepExit = (key != "FALSE"); - } - -} - -ALWAYS_INLINE void GetConfigSettings(FpsCounterSettings* settings) { - // Initialize defaults - settings->handheldFontSize = 40; - settings->dockedFontSize = 40; - convertStrToRGBA4444("#0009", &(settings->backgroundColor)); - convertStrToRGBA4444("#000F", &(settings->focusBackgroundColor)); - convertStrToRGBA4444("#8CFF", &(settings->textColor)); - //settings->setPos = 0; - settings->refreshRate = 30; - settings->useIntegerCounter = false; - settings->disableScreenshots = false; - - settings->frameOffsetX = 10; - settings->frameOffsetY = 10; - settings->framePadding = 10; - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("fps-counter"); - if (sectionIt == parsedData.end()) return; - - - std::string key; - uint16_t temp; - - const auto& section = sectionIt->second; - - // Process font sizes with shared bounds - static constexpr long minFontSize = 8; - static constexpr long maxFontSize = 150; - - auto it = section.find("handheld_font_size"); - if (it != section.end()) { - settings->handheldFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - it = section.find("docked_font_size"); - if (it != section.end()) { - settings->dockedFontSize = std::clamp(atol(it->second.c_str()), minFontSize, maxFontSize); - } - - // Process colors - it = section.find("background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->backgroundColor = temp; - } - - it = section.find("focus_background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->focusBackgroundColor = temp; - } - - - it = section.find("text_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->textColor = temp; - } - - // Process alignment settings - //it = section.find("layer_width_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos = 1; - // } else if (key == "RIGHT") { - // settings->setPos = 2; - // } - //} - - //it = section.find("layer_height_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos += 3; - // } else if (key == "BOTTOM") { - // settings->setPos += 6; - // } - //} - - it = section.find("use_integer_counter"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useIntegerCounter = (key != "FALSE"); - } - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } - - it = section.find("frame_offset_x"); - if (it != section.end()) { - settings->frameOffsetX = atol(it->second.c_str()); - } - - it = section.find("frame_offset_y"); - if (it != section.end()) { - settings->frameOffsetY = atol(it->second.c_str()); - } - - it = section.find("frame_padding"); - if (it != section.end()) { - settings->framePadding = atol(it->second.c_str()); - } -} - -ALWAYS_INLINE void GetConfigSettings(FpsGraphSettings* settings) { - // Initialize defaults - settings->showInfo = true; - settings->realTemps = false; - //settings->setPos = 0; - convertStrToRGBA4444("#0009", &(settings->backgroundColor)); - convertStrToRGBA4444("#000F", &(settings->focusBackgroundColor)); - convertStrToRGBA4444("#888C", &(settings->fpsColor)); - convertStrToRGBA4444("#2DFF", &(settings->borderColor)); - convertStrToRGBA4444("#8888", &(settings->dashedLineColor)); - convertStrToRGBA4444("#FFFF", &(settings->maxFPSTextColor)); - convertStrToRGBA4444("#FFFF", &(settings->minFPSTextColor)); - convertStrToRGBA4444("#FFFF", &(settings->mainLineColor)); - convertStrToRGBA4444("#F0FF", &(settings->roundedLineColor)); - convertStrToRGBA4444("#0C0F", &(settings->perfectLineColor)); - - convertStrToRGBA4444("#FFFF", &(settings->textColor)); - convertStrToRGBA4444("#0F0F", &(settings->catColor)); - - settings->refreshRate = 30; - settings->useDynamicColors = true; - settings->disableScreenshots = false; - - settings->frameOffsetX = 10; - settings->frameOffsetY = 10; - settings->framePadding = 10; - - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("fps-graph"); - if (sectionIt == parsedData.end()) return; - - std::string key; - uint16_t temp; - - const auto& section = sectionIt->second; - - // Process alignment settings - //auto it = section.find("layer_width_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos = 1; - // } else if (key == "RIGHT") { - // settings->setPos = 2; - // } - //} - // - //it = section.find("layer_height_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos += 3; - // } else if (key == "BOTTOM") { - // settings->setPos += 6; - // } - //} - - // Process show_info boolean - auto it = section.find("show_info"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showInfo = (key == "TRUE"); - } - - it = section.find("real_temps"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realTemps = (key == "TRUE"); - } - - it = section.find("use_dynamic_colors"); - - it = section.find("use_dynamic_colors"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDynamicColors = (key == "TRUE"); - } - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } - - it = section.find("frame_offset_x"); - if (it != section.end()) { - settings->frameOffsetX = atol(it->second.c_str()); - } - - it = section.find("frame_offset_y"); - if (it != section.end()) { - settings->frameOffsetY = atol(it->second.c_str()); - } - - it = section.find("frame_padding"); - if (it != section.end()) { - settings->framePadding = atol(it->second.c_str()); - } - - - // Process colors - using a struct for cleaner code - struct ColorMapping { - const char* key; - uint16_t* target; - }; - - const ColorMapping colorMappings[] = { - {"min_fps_text_color", &settings->minFPSTextColor}, - {"max_fps_text_color", &settings->maxFPSTextColor}, - {"background_color", &settings->backgroundColor}, - {"focus_background_color", &settings->focusBackgroundColor}, - {"fps_counter_color", &settings->fpsColor}, - {"border_color", &settings->borderColor}, - {"dashed_line_color", &settings->dashedLineColor}, - {"main_line_color", &settings->mainLineColor}, - {"rounded_line_color", &settings->roundedLineColor}, - {"perfect_line_color", &settings->perfectLineColor}, - {"text_color", &settings->textColor}, - {"cat_color", &settings->catColor} - }; - - for (const auto& mapping : colorMappings) { - it = section.find(mapping.key); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - *(mapping.target) = temp; - } - } -} - -ALWAYS_INLINE void GetConfigSettings(FullSettings* settings) { - // Initialize defaults - settings->setPosRight = false; - settings->refreshRate = 1; - settings->showRealFreqs = true; - settings->realTemps = false; - settings->showDeltas = true; - settings->showTargetFreqs = true; - settings->showFPS = true; - settings->showRES = true; - settings->showRDSD = true; - settings->ramInfoMode = "LOAD"; - settings->useDynamicColors = true; - settings->disableScreenshots = false; - convertStrToRGBA4444("#888F", &(settings->separatorColor)); - convertStrToRGBA4444("#8FFF", &(settings->catColor1)); - convertStrToRGBA4444("#8CFF", &(settings->catColor2)); - convertStrToRGBA4444("#FFFF", &(settings->textColor)); - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("full"); - if (sectionIt == parsedData.end()) return; - - std::string key; - uint16_t temp; - - const auto& section = sectionIt->second; - - // Process refresh_rate - auto it = section.find("refresh_rate"); - if (it != section.end()) { - settings->refreshRate = std::clamp(atol(it->second.c_str()), 1L, 60L); - } - - // Process layer position - it = section.find("layer_width_align"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->setPosRight = (key == "RIGHT"); - } - - // Process boolean flags - it = section.find("show_real_freqs"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showRealFreqs = !(key == "FALSE"); - } - - it = section.find("real_temps"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->realTemps = (key == "TRUE"); - } - - it = section.find("show_deltas"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showDeltas = !(key == "FALSE"); - } - - it = section.find("show_target_freqs"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showTargetFreqs = !(key == "FALSE"); - } - - it = section.find("show_fps"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showFPS = !(key == "FALSE"); - } - - it = section.find("show_res"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showRES = !(key == "FALSE"); - } - - it = section.find("show_read_speed"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->showRDSD = !(key == "FALSE"); - } - - it = section.find("ram_info_mode"); - if (it != section.end()) { - settings->ramInfoMode = it->second; - } - - it = section.find("use_dynamic_colors"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->useDynamicColors = (key == "TRUE"); - } - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } - - it = section.find("separator_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->separatorColor = temp; - } - - it = section.find("cat_color_1"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->catColor1 = temp; - } - - it = section.find("cat_color_2"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->catColor2 = temp; - } - - it = section.find("text_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->textColor = temp; - } -} - -ALWAYS_INLINE void GetConfigSettings(ResolutionSettings* settings) { - // Initialize defaults - convertStrToRGBA4444("#0009", &(settings->backgroundColor)); - convertStrToRGBA4444("#000F", &(settings->focusBackgroundColor)); - convertStrToRGBA4444("#8FFF", &(settings->catColor)); - //convertStrToRGBA4444("#8CFF", &(settings->catColor2)); - convertStrToRGBA4444("#FFFF", &(settings->textColor)); - settings->refreshRate = 10; - //ettings->setPos = 0; - settings->disableScreenshots = false; - - settings->frameOffsetX = 10; - settings->frameOffsetY = 10; - settings->framePadding = 10; - - - // Open and read file efficiently - FILE* configFile = fopen(configIniPath, "r"); - if (!configFile) return; - - fseek(configFile, 0, SEEK_END); - const long fileSize = ftell(configFile); - fseek(configFile, 0, SEEK_SET); - - std::string fileData; - fileData.resize(fileSize); - fread(fileData.data(), 1, fileSize, configFile); - fclose(configFile); - - auto parsedData = ult::parseIni(fileData); - - // Cache section lookup - auto sectionIt = parsedData.find("game_resolutions"); - if (sectionIt == parsedData.end()) return; - - std::string key; - - const auto& section = sectionIt->second; - - // Process refresh_rate - auto it = section.find("refresh_rate"); - if (it != section.end()) { - settings->refreshRate = std::clamp(atol(it->second.c_str()), 1L, 60L); - } - - uint16_t temp; - - // Process colors - it = section.find("background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->backgroundColor = temp; - } - - it = section.find("focus_background_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->focusBackgroundColor = temp; - } - - it = section.find("cat_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->catColor = temp; - } - - //it = section.find("cat_color_2"); - //if (it != section.end()) { - // temp = 0; - // if (convertStrToRGBA4444(it->second, &temp)) - // settings->catColor2 = temp; - //} - - - it = section.find("text_color"); - if (it != section.end()) { - temp = 0; - if (convertStrToRGBA4444(it->second, &temp)) - settings->textColor = temp; - } - - it = section.find("frame_offset_x"); - if (it != section.end()) { - settings->frameOffsetX = atol(it->second.c_str()); - } - - it = section.find("frame_offset_y"); - if (it != section.end()) { - settings->frameOffsetY = atol(it->second.c_str()); - } - - it = section.find("frame_padding"); - if (it != section.end()) { - settings->framePadding = atol(it->second.c_str()); - } - - // Process alignment settings - //it = section.find("layer_width_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos = 1; - // } else if (key == "RIGHT") { - // settings->setPos = 2; - // } - //} - // - //it = section.find("layer_height_align"); - //if (it != section.end()) { - // key = it->second; - // convertToUpper(key); - // if (key == "CENTER") { - // settings->setPos += 3; - // } else if (key == "BOTTOM") { - // settings->setPos += 6; - // } - //} - - // Process disable screenshots - it = section.find("disable_screenshots"); - if (it != section.end()) { - key = it->second; - convertToUpper(key); - settings->disableScreenshots = (key != "FALSE"); - } -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/audsnoop.c b/Source/Horizon-OC-Monitor (deprecated)/source/audsnoop.c deleted file mode 100644 index 6bc801f9..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/audsnoop.c +++ /dev/null @@ -1,35 +0,0 @@ -#define NX_SERVICE_ASSUME_NON_DOMAIN -#include -#include - -static Service g_audsnoopSrv; - -NX_GENERATE_SERVICE_GUARD(audsnoop); - -Result _audsnoopInitialize(void) { - return smGetService(&g_audsnoopSrv, "auddev"); -} - -void _audsnoopCleanup(void) { - serviceClose(&g_audsnoopSrv); -} - -Service* audsnoopGetServiceSession(void) { - return &g_audsnoopSrv; -} - -Result audsnoopEnableDspUsageMeasurement(void) { - return serviceDispatch(&g_audsnoopSrv, 0); -} - -Result audsnoopDisableDspUsageMeasurement(void) { - return serviceDispatch(&g_audsnoopSrv, 1); -} - -Result audsnoopGetDspUsage(u32 *usage) { - u32 tmp = 0; - Result rc = serviceDispatchOut(&g_audsnoopSrv, 6, tmp); - if (R_SUCCEEDED(rc) && usage) - *usage = tmp; - return rc; -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/main.cpp b/Source/Horizon-OC-Monitor (deprecated)/source/main.cpp deleted file mode 100644 index 082fb503..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/main.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -#define TESLA_INIT_IMPL -#include -#include "Utils.hpp" -#include -#include - -//static tsl::elm::HeaderOverlayFrame* rootFrame = nullptr; -static bool skipMain = false; -static std::string lastSelectedItem; - -#include "modes/FPS_Counter.hpp" -#include "modes/FPS_Graph.hpp" -#include "modes/Full.hpp" -#include "modes/Mini.hpp" -#include "modes/Micro.hpp" -#include "modes/Battery.hpp" -#include "modes/Misc.hpp" -#include "modes/Resolutions.hpp" -#include "modes/Configurator.hpp" - - - -//Graphs -//class GraphsMenu : public tsl::Gui { -//public: -// GraphsMenu() {} -// -// virtual tsl::elm::Element* createUI() override { -// -// auto* list = new tsl::elm::List(); -// -// list->addItem(new tsl::elm::CategoryHeader("FPS")); -// -// auto* comFPSGraph = new tsl::elm::ListItem("Graph"); -// comFPSGraph->setClickListener([](uint64_t keys) { -// if (keys & KEY_A) { -// tsl::swapTo(); -// return true; -// } -// return false; -// }); -// list->addItem(comFPSGraph); -// -// auto* comFPSCounter = new tsl::elm::ListItem("Counter"); -// comFPSCounter->setClickListener([](uint64_t keys) { -// if (keys & KEY_A) { -// tsl::swapTo(); -// return true; -// } -// return false; -// }); -// list->addItem(comFPSCounter); -// -// tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", "Modes"); -// rootFrame->setContent(list); -// -// return rootFrame; -// } -// -// virtual void update() override { -// if (fixForeground) { -// fixForeground = false; -// tsl::hlp::requestForeground(true); -// } -// } -// -// virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { -// if (disableJumpTo) -// disableJumpTo = false; -// if (fixHiding) { -// if (isKeyComboPressed2(keysDown, keysHeld)) { -// tsl::Overlay::get()->hide(); -// fixHiding = false; -// return true; -// } -// } -// -// if (keysDown & KEY_B) { -// tsl::goBack(); -// return true; -// } -// return false; -// } -//}; - -//Other -class OtherMenu : public tsl::Gui { -public: - OtherMenu() { } - - virtual tsl::elm::Element* createUI() override { - - auto* list = new tsl::elm::List(); - - list->addItem(new tsl::elm::CategoryHeader("Other")); - - auto* Battery = new tsl::elm::ListItem("Battery/Charger"); - Battery->disableClickAnimation(); - Battery->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - tsl::swapTo(); - return true; - } - return false; - }); - list->addItem(Battery); - - auto* Misc = new tsl::elm::ListItem("Miscellaneous"); - Misc->disableClickAnimation(); - Misc->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - tsl::swapTo(); - return true; - } - return false; - }); - list->addItem(Misc); - - //if (SaltySD) { - // auto* Res = new tsl::elm::ListItem("Game Resolutions"); - // Res->setClickListener([](uint64_t keys) { - // if (keys & KEY_A) { - // tsl::swapTo(); - // return true; - // } - // return false; - // }); - // list->addItem(Res); - //} - //tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", "Modes"); - if (!lastSelectedItem.empty()) - list->jumpToItem(lastSelectedItem); - - rootFrame->setContent(list); - - return rootFrame; - } - - virtual void update() override { - if (fixForeground) { - fixForeground = false; - tsl::hlp::requestForeground(true); - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (disableJumpTo) - disableJumpTo = false; - if (fixHiding) { - if (isKeyComboPressed2(keysDown, keysHeld)) { - tsl::Overlay::get()->hide(); - fixHiding = false; - return true; - } - } - - if (keysDown & KEY_B) { - lastSelectedItem = "Other"; - tsl::swapTo(); - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - return true; - } - return false; - } -}; - -//Main Menu -class MainMenu : public tsl::Gui { -public: - MainMenu() { - if (lastMode != "returning") - lastMode = ""; - } - - virtual tsl::elm::Element* createUI() override { - - auto* list = new tsl::elm::List(); - - //list->addItem(new tsl::elm::CategoryHeader("Modes " + ult::DIVIDER_SYMBOL + " \uE0E0 Enter " + ult::DIVIDER_SYMBOL + " \uE0E3 Configure")); - list->addItem(new tsl::elm::CategoryHeader("Modes " + ult::DIVIDER_SYMBOL + " \uE0E3 Configure")); - - auto* Full = new tsl::elm::ListItem("Full"); - Full->disableClickAnimation(); - Full->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - lastMode = "full"; - tsl::swapTo(); - return true; - } - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Mini mode - tsl::swapTo("Full"); - return true; - } - return false; - }); - list->addItem(Full); - //auto* Mini = new tsl::elm::ListItem("Mini"); - //Mini->setClickListener([](uint64_t keys) { - // if (keys & KEY_A) { - // tsl::swapTo(); - // return true; - // } - // return false; - //}); - //list->addItem(Mini); - - bool fileExist = false; - FILE* test = fopen(std::string(folderpath + filename).c_str(), "rb"); - if (test) { - fclose(test); - fileExist = true; - filepath = folderpath + filename; - } - else { - test = fopen(std::string(folderpath + "Status-Monitor-Overlay.ovl").c_str(), "rb"); - if (test) { - fclose(test); - fileExist = true; - filepath = folderpath + "Status-Monitor-Overlay.ovl"; - } - } - if (fileExist) { - auto* Mini = new tsl::elm::ListItem("Mini"); - Mini->disableClickAnimation(); - Mini->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - tsl::setNextOverlay(filepath, "-mini_"); - tsl::Overlay::get()->close(); - return true; - } - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Mini mode - tsl::swapTo("Mini"); - return true; - } - return false; - }); - list->addItem(Mini); - - auto* Micro = new tsl::elm::ListItem("Micro"); - Micro->disableClickAnimation(); - Micro->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - tsl::setNextOverlay(filepath, "-micro_"); - tsl::Overlay::get()->close(); - return true; - } - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Micro mode - tsl::swapTo("Micro"); - return true; - } - return false; - }); - list->addItem(Micro); - } - if (SaltySD) { - //auto* Graphs = new tsl::elm::ListItem("FPS"); - //Graphs->setValue(ult::DROPDOWN_SYMBOL); - //Graphs->setClickListener([](uint64_t keys) { - // if (keys & KEY_A) { - // tsl::swapTo(); - // return true; - // } - // return false; - //}); - //list->addItem(Graphs); - - auto* comFPSGraph = new tsl::elm::ListItem("FPS Graph"); - comFPSGraph->disableClickAnimation(); - comFPSGraph->setClickListener([](uint64_t keys) { - //if (keys & KEY_A) { - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - // lastMode = "fps_graph"; - // tsl::swapTo(); - // return true; - //} - if (keys & KEY_A) { - tsl::setNextOverlay(filepath, "-fps_graph_"); - tsl::Overlay::get()->close(); - return true; - } - - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Micro mode - tsl::swapTo("FPS Graph"); - return true; - } - return false; - }); - list->addItem(comFPSGraph); - - auto* comFPSCounter = new tsl::elm::ListItem("FPS Counter"); - comFPSCounter->disableClickAnimation(); - comFPSCounter->setClickListener([](uint64_t keys) { - //if (keys & KEY_A) { - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - // lastMode = "fps_counter"; - // tsl::swapTo(); - // return true; - //} - if (keys & KEY_A) { - tsl::setNextOverlay(filepath, "-fps_counter_"); - tsl::Overlay::get()->close(); - return true; - } - - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Micro mode - tsl::swapTo("FPS Counter"); - return true; - } - return false; - }); - list->addItem(comFPSCounter); - - auto* Res = new tsl::elm::ListItem("Game Resolutions"); - Res->disableClickAnimation(); - Res->setClickListener([](uint64_t keys) { - //if (keys & KEY_A) { - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - // lastMode = "game_resolutions"; - // tsl::swapTo(); - // return true; - //} - if (keys & KEY_A) { - tsl::setNextOverlay(filepath, "-game_resolutions_"); - tsl::Overlay::get()->close(); - return true; - } - if (keys & KEY_Y) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerSettingsSound.store(true, std::memory_order_release); - // Launch configurator for Micro mode - tsl::swapTo("Game Resolutions"); - return true; - } - return false; - }); - list->addItem(Res); - - } - auto* Other = new tsl::elm::ListItem("Other"); - Other->disableClickAnimation(); - Other->setValue(ult::DROPDOWN_SYMBOL); - Other->setClickListener([](uint64_t keys) { - if (keys & KEY_A) { - triggerRumbleClick.store(true, std::memory_order_release); - triggerEnterSound.store(true, std::memory_order_release); - tsl::swapTo(); - return true; - } - return false; - }); - list->addItem(Other); - - if (!lastSelectedItem.empty()) - list->jumpToItem(lastSelectedItem); - - //list->disableCaching(); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION); - rootFrame->setContent(list); - - return rootFrame; - } - - virtual void update() override { - if (!ult::useRightAlignment) { - //if ((tsl::cfg::LayerPosX || tsl::cfg::LayerPosY)) { - tsl::gfx::Renderer::get().setLayerPos(0, 0); - //} - } else { - const auto [horizontalUnderscanPixels, verticalUnderscanPixels] = tsl::gfx::getUnderscanPixels(); - tsl::gfx::Renderer::get().setLayerPos(1280-32 - horizontalUnderscanPixels, 0); - } - if (fixForeground) { - fixForeground = false; - tsl::hlp::requestForeground(true); - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (disableJumpTo) - disableJumpTo = false; - if (fixHiding) { - if (isKeyComboPressed2(keysDown, keysHeld)) { - tsl::Overlay::get()->hide(); - fixHiding = false; - return true; - } - } - - if (keysDown & KEY_B) { - tsl::goBack(); - return true; - } - return false; - } -}; - -class MonitorOverlay : public tsl::Overlay { -public: - - virtual void initServices() override { - //Initialize services - tsl::hlp::doWithSmSession([this]{ - - apmInitialize(); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - i2cCheck = i2cInitialize(); - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemoryAndRefreshRate(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - - }); - Hinted = envIsSyscallHinted(0x6F); - } - - virtual void exitServices() override { - CloseThreads(); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - shmemClose(&_sharedmemory); - //Exit services - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - nvClose(fd); - nvExit(); - psmExit(); - i2cExit(); - apmExit(); - } - - virtual void onShow() override {} // Called before overlay wants to change from invisible to visible state - virtual void onHide() override {} // Called before overlay wants to change from visible to invisible state - - virtual std::unique_ptr loadInitialGui() override { - return initially(); // Initial Gui to load. It's possible to pass arguments to it's constructor like this - } -}; - -class MicroMode : public tsl::Overlay { -public: - - virtual void initServices() override { - //tsl::hlp::requestForeground(false); - //Initialize services - tsl::hlp::doWithSmSession([this]{ - apmInitialize(); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - i2cCheck = i2cInitialize(); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemory(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - }); - Hinted = envIsSyscallHinted(0x6F); - } - - virtual void exitServices() override { - CloseThreads(); - shmemClose(&_sharedmemory); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - //Exit services - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - i2cExit(); - psmExit(); - nvClose(fd); - nvExit(); - apmExit(); - } - - virtual void onShow() override { // Called before overlay wants to change from invisible to visible state - tsl::hlp::requestForeground(false); - } - virtual void onHide() override {} // Called before overlay wants to change from visible to invisible state - - virtual std::unique_ptr loadInitialGui() override { - return initially(); // Initial Gui to load. It's possible to pass arguments to it's constructor like this - } -}; - -class MiniEntryOverlay : public tsl::Overlay { -public: - MiniEntryOverlay() {} - - virtual void initServices() override { - - //tsl::hlp::requestForeground(false); - // Same service‐init as before - tsl::hlp::doWithSmSession([this]{ - apmInitialize(); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - i2cCheck = i2cInitialize(); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemory(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - }); - Hinted = envIsSyscallHinted(0x6F); - - } - - virtual void exitServices() override { - CloseThreads(); - shmemClose(&_sharedmemory); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - // Exit services - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - i2cExit(); - psmExit(); - nvClose(fd); - nvExit(); - apmExit(); - } - - // **Override onShow** so that as soon as this Overlay appears, we let input pass through. - virtual void onShow() override { - // Request that Tesla stop grabbing all buttons/touches - tsl::hlp::requestForeground(false); - - // (Optional) hide Tesla’s footer if you don’t want it - //deactivateOriginalFooter = true; - } - - virtual std::unique_ptr loadInitialGui() override { - // Immediately show your MiniOverlay page - return initially(); - } -}; - -class FPSGraphEntryOverlay : public tsl::Overlay { -public: - FPSGraphEntryOverlay() {} - - virtual void initServices() override { - tsl::hlp::doWithSmSession([this]{ - apmInitialize(); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - i2cCheck = i2cInitialize(); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemoryAndRefreshRate(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - }); - Hinted = envIsSyscallHinted(0x6F); - } - - virtual void exitServices() override { - CloseThreads(); - shmemClose(&_sharedmemory); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - i2cExit(); - psmExit(); - nvClose(fd); - nvExit(); - apmExit(); - } - - virtual void onShow() override { - tsl::hlp::requestForeground(false); - //deactivateOriginalFooter = true; - } - - virtual std::unique_ptr loadInitialGui() override { - return initially(); - } -}; - -class FPSCounterEntryOverlay : public tsl::Overlay { -public: - FPSCounterEntryOverlay() {} - - virtual void initServices() override { - tsl::hlp::doWithSmSession([this]{ - apmInitialize(); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - i2cCheck = i2cInitialize(); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemoryAndRefreshRate(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - }); - Hinted = envIsSyscallHinted(0x6F); - } - - virtual void exitServices() override { - CloseThreads(); - shmemClose(&_sharedmemory); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - i2cExit(); - psmExit(); - nvClose(fd); - nvExit(); - apmExit(); - } - - virtual void onShow() override { - tsl::hlp::requestForeground(false); - //deactivateOriginalFooter = true; - } - - virtual std::unique_ptr loadInitialGui() override { - return initially(); - } -}; - -class GameResolutionsEntryOverlay : public tsl::Overlay { -public: - GameResolutionsEntryOverlay() {} - - virtual void initServices() override { - tsl::hlp::doWithSmSession([this]{ - apmInitialize(); - - if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); - - if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); - - if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { - pwmCheck = pwmOpenSession2(&g_ICon, 0x3D000001); - } - - i2cCheck = i2cInitialize(); - - psmCheck = psmInitialize(); - if (R_SUCCEEDED(psmCheck)) { - psmService = psmGetServiceSession(); - } - - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemoryAndRefreshRate(); - } - if (hocclkIpcRunning() && R_SUCCEEDED(hocclkIpcInitialize())) { - uint32_t hocClkApiVer = 0; - hocclkIpcGetAPIVersion(&hocClkApiVer); - if (hocClkApiVer != HOCCLK_IPC_API_VERSION) { - hocclkIpcExit(); - } - else hocclkCheck = 0; - } - if (R_SUCCEEDED(splInitialize())) { - u64 sku = 0; - splGetConfig(SplConfigItem_HardwareType, &sku); - switch(sku) { - case 2 ... 5: - isMariko = true; - break; - default: - isMariko = false; - } - } - splExit(); - }); - Hinted = envIsSyscallHinted(0x6F); - } - - virtual void exitServices() override { - CloseThreads(); - shmemClose(&_sharedmemory); - if (R_SUCCEEDED(hocclkCheck)) { - hocclkIpcExit(); - } - tsExit(); - tcExit(); - pwmChannelSessionClose(&g_ICon); - pwmExit(); - i2cExit(); - psmExit(); - nvClose(fd); - nvExit(); - apmExit(); - } - - virtual void onShow() override { - tsl::hlp::requestForeground(false); - //deactivateOriginalFooter = true; - } - - virtual std::unique_ptr loadInitialGui() override { - return initially(); - } -}; - - -// Helper function to check if overlay file exists -bool checkOverlayFile(const std::string& filename) { - struct stat buffer; - return stat(filename.c_str(), &buffer) == 0; -} - -// Helper function to setup micro mode paths -inline void setupMode(const std::string& modeType = "") { - - if (modeType == "micro") { - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } else { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 28; - } - } else { - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } - } - - // Try user-specified filename first, then fallback to default - const std::string primaryPath = folderpath + filename; - - if (checkOverlayFile(primaryPath)) { - filepath = primaryPath; - } else { - const std::string fallbackPath = folderpath + "Status-Monitor-Overlay.ovl"; - if (checkOverlayFile(fallbackPath)) { - filepath = fallbackPath; - } - } -} - -//void setupMicroMode() { -// ult::DefaultFramebufferWidth = 1280; -// //ult::DefaultFramebufferHeight = 28; -// ult::DefaultFramebufferHeight = 720; -// -// // Try user-specified filename first, then fallback to default -// const std::string primaryPath = folderpath + filename; -// -// if (checkOverlayFile(primaryPath)) { -// filepath = primaryPath; -// } else { -// const std::string fallbackPath = folderpath + "Status-Monitor-Overlay.ovl"; -// if (checkOverlayFile(fallbackPath)) { -// filepath = fallbackPath; -// } -// } -//} - - -// This function gets called on startup to create a new Overlay object -int main(int argc, char **argv) { - - // load heap settings outside of loop (only Status Monitor directive) - ult::currentHeapSize = ult::getCurrentHeapSize(); - ult::expandedMemory = ult::currentHeapSize >= ult::OverlayHeapSize::Size_8MB; - ult::limitedMemory = ult::currentHeapSize == ult::OverlayHeapSize::Size_4MB; - - - // Initialize buffer sizes based on expanded memory setting - if (ult::expandedMemory) { - ult::furtherExpandedMemory = ult::currentHeapSize > ult::OverlayHeapSize::Size_8MB; - - if (!ult::furtherExpandedMemory) { - ult::loaderTitle += "+"; - ult::COPY_BUFFER_SIZE = 262144; - ult::HEX_BUFFER_SIZE = 8192; - ult::UNZIP_READ_BUFFER = 262144; - ult::UNZIP_WRITE_BUFFER = 131072; - ult::DOWNLOAD_READ_BUFFER = 131072; - ult::DOWNLOAD_WRITE_BUFFER = 131072; - } else { - ult::loaderTitle += "×"; - ult::COPY_BUFFER_SIZE = 262144*2; - ult::HEX_BUFFER_SIZE = 8192; - ult::UNZIP_READ_BUFFER = 262144*2; - ult::UNZIP_WRITE_BUFFER = 131072*4; - ult::DOWNLOAD_READ_BUFFER = 131072*4; - ult::DOWNLOAD_WRITE_BUFFER = 131072*4; - } - } else if (ult::limitedMemory) { - ult::loaderTitle += "-"; - ult::DOWNLOAD_READ_BUFFER = 16*1024; - ult::UNZIP_READ_BUFFER = 16*1024; - } - - systemtickfrequency = armGetSystemTickFreq(); - ParseIniFile(); // parse INI from file - - if (argc > 0) { - filename = argv[0]; // set global - - { - // Read the entire INI file once - auto iniData = ult::getParsedDataFromIniFile(ult::OVERLAYS_INI_FILEPATH); - - auto sectionIt = iniData.find(filename); - if (sectionIt != iniData.end()) { - auto& section = sectionIt->second; - - // Compare and update if values differ - const std::string expectedArgs = "(-mini, -micro, -fps_graph, -fps_counter, -game_resolutions)"; - - if (section["mode_args"] != expectedArgs) { - section["mode_args"] = expectedArgs; - section["mode_labels"] = "(Mini, Micro, FPS Graph, FPS Counter, Game Resolutions)"; - ult::saveIniFileData(ult::OVERLAYS_INI_FILEPATH, iniData); - } - } else { - // If section doesn't exist, create it with expected values - iniData[filename]["mode_args"] = "(-mini, -micro, -fps_graph, -fps_counter, -game_resolutions)"; - iniData[filename]["mode_labels"] = "(Mini, Micro, FPS Graph, FPS Counter, Game Resolutions)"; - ult::saveIniFileData(ult::OVERLAYS_INI_FILEPATH, iniData); - } - } - - // Process command line arguments - for (u8 arg = 0; arg < argc; arg++) { - const char* argStr = argv[arg]; - if (argStr[0] != '-') continue; - - // Check if ends with underscore and create comparison string without it - const size_t len = strlen(argStr); - const bool hasUnderscore = (len > 1 && argStr[len-1] == '_'); - - // For underscore variants, compare without the trailing underscore - char modeStr[32]; - const char* compareStr; - if (hasUnderscore) { - strncpy(modeStr, argStr, len - 1); - modeStr[len - 1] = '\0'; - compareStr = modeStr; - } else { - compareStr = argStr; - } - - // Micro mode - if (strcasecmp(compareStr, "-micro") == 0) { - FullMode = false; - lastMode = "micro"; - if (hasUnderscore) { - setupMode(lastMode); - } else { - skipMain = true; - - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } else { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 28; - } - } - return tsl::loop(argc, argv); - } - // Mini mode - else if (strcasecmp(compareStr, "-mini") == 0) { - FullMode = false; - lastMode = "mini"; - if (hasUnderscore) { - setupMode(); - } else { - skipMain = true; - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } - } - return tsl::loop(argc, argv); - } - // FPS Graph mode - else if (strcasecmp(compareStr, "-fps_graph") == 0) { - FullMode = false; - lastMode = "fps_graph"; - if (hasUnderscore) { - setupMode(); - } else { - skipMain = true; - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } - } - return tsl::loop(argc, argv); - } - // FPS Counter mode - else if (strcasecmp(compareStr, "-fps_counter") == 0) { - FullMode = false; - lastMode = "fps_counter"; - if (hasUnderscore) { - setupMode(); - } else { - skipMain = true; - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } - } - return tsl::loop(argc, argv); - } - // Game Resolutions mode - else if (strcasecmp(compareStr, "-game_resolutions") == 0) { - FullMode = false; - lastMode = "game_resolutions"; - if (hasUnderscore) { - setupMode(); - } else { - skipMain = true; - if (!ult::limitedMemory) { - ult::DefaultFramebufferWidth = 1280; - ult::DefaultFramebufferHeight = 720; - } - } - return tsl::loop(argc, argv); - } - // Handle --lastSelectedItem (multi-token argument) - else if (strcmp(argStr, "--lastSelectedItem") == 0 && arg + 1 < argc) { - lastSelectedItem.clear(); - - for (++arg; arg < argc; ++arg) { - const char* token = argv[arg]; - - // Stop if we hit another flag - if (token[0] == '-' && !lastSelectedItem.empty()) - break; - - // Add space separator - if (!lastSelectedItem.empty()) - lastSelectedItem += ' '; - - lastSelectedItem += token; - - // Stop if token ends with quote - const char lastChar = token[strlen(token) - 1]; - if (lastChar == '"' || lastChar == '\'') { - ++arg; - break; - } - } - - // Clean up quotes and whitespace - ult::removeQuotes(lastSelectedItem); - - // Trim whitespace - const size_t start = lastSelectedItem.find_first_not_of(" \t"); - if (start != std::string::npos) { - const size_t end = lastSelectedItem.find_last_not_of(" \t"); - lastSelectedItem = lastSelectedItem.substr(start, end - start + 1); - } else { - lastSelectedItem.clear(); - } - } - } - } - - // Default case - return tsl::loop(argc, argv); -} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Battery.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Battery.hpp deleted file mode 100644 index c996ed06..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Battery.hpp +++ /dev/null @@ -1,220 +0,0 @@ -class OtherMenu; - -class BatteryOverlay : public tsl::Gui { -private: - // Separated value buffers - char actualCapacity_c[32] = ""; - char designedCapacity_c[32] = ""; - char batteryTemp_c[32] = ""; - char rawCharge_c[32] = ""; - char batteryAge_c[32] = ""; - char voltageAvg_c[64] = ""; - char currentFlow_c[64] = ""; - char powerFlow_c[64] = ""; - char remainingTime_c[16] = ""; - char inputCurrentLimit_c[32] = ""; - char vbusCurrentLimit_c[32] = ""; - char chargeVoltageLimit_c[32] = ""; - char chargeCurrentLimit_c[32] = ""; - char chargerType_c[32] = ""; - char chargerMaxVoltage_c[32] = ""; - char chargerMaxCurrent_c[32] = ""; - - bool skipOnce = true; - bool runOnce = true; - bool isChargerConnected = false; - FullSettings settings; -public: - BatteryOverlay() { - GetConfigSettings(&settings); - disableJumpTo = true; - mutexInit(&mutex_BatteryChecker); - StartBatteryThread(); - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - } - ~BatteryOverlay() { - CloseBatteryThread(); - fixForeground = true; - } - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - static constexpr u16 Y_OFFSET = 40; - static constexpr u16 X_OFFSET = 20; - static const u16 LABEL_X = 20 + X_OFFSET; - static const u16 VALUE_X = 240+ X_OFFSET; - static const u16 START_Y = 155 + Y_OFFSET; - static constexpr u16 LINE_HEIGHT = 18; - static constexpr u8 FONT_SIZE = 18; - static const tsl::Color LABEL_COLOR_1= settings.catColor1; - static const tsl::Color LABEL_COLOR_2 = settings.catColor2; - static const tsl::Color VALUE_COLOR = settings.textColor; - - renderer->drawString("Battery Stats", false, LABEL_X, 120 + Y_OFFSET, 20, LABEL_COLOR_1); - - u16 currentY = START_Y; - - // Actual Capacity - renderer->drawString("Actual Capacity", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(actualCapacity_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Designed Capacity - renderer->drawString("Designed Capacity", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(designedCapacity_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Temperature - renderer->drawString("Temperature", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(batteryTemp_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Raw Charge - renderer->drawString("Raw Charge", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(rawCharge_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Age - renderer->drawString("Age", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(batteryAge_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Voltage - renderer->drawString("Voltage", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(voltageAvg_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Current Flow - renderer->drawString("Current Flow", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(currentFlow_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Power Flow - renderer->drawString("Power Flow", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(powerFlow_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Remaining Time - renderer->drawString("Remaining Time", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(remainingTime_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charger-specific fields (only shown when charger is connected) - if (isChargerConnected) { - currentY += 3*LINE_HEIGHT; - renderer->drawString("Charger Stats", false, LABEL_X, currentY, 20, LABEL_COLOR_1); - currentY += 2*LINE_HEIGHT; - // Input Current Limit - renderer->drawString("Input Current Limit", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(inputCurrentLimit_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // VBUS Current Limit - renderer->drawString("VBUS Current Limit", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(vbusCurrentLimit_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charge Voltage Limit - renderer->drawString("Voltage Limit", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(chargeVoltageLimit_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charge Current Limit - renderer->drawString("Current Limit", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(chargeCurrentLimit_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charger Type - renderer->drawString("Type", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(chargerType_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charger Max Voltage - renderer->drawString("Max Voltage", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(chargerMaxVoltage_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - currentY += LINE_HEIGHT; - - // Charger Max Current - renderer->drawString("Max Current", false, LABEL_X, currentY, FONT_SIZE, LABEL_COLOR_2); - renderer->drawString(chargerMaxCurrent_c, false, VALUE_X, currentY, FONT_SIZE, VALUE_COLOR); - } - }); - - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - mutexLock(&mutex_BatteryChecker); - - char tempBatTimeEstimate[8] = "--:--"; - if (batTimeEstimate >= 0) { - snprintf(tempBatTimeEstimate, sizeof(tempBatTimeEstimate), "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } - - const BatteryChargeInfoFieldsChargerType ChargerConnected = hosversionAtLeast(17,0,0) ? - ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields)->ChargerType : - _batteryChargeInfoFields.ChargerType; - const int32_t ChargerVoltageLimit = hosversionAtLeast(17,0,0) ? - ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields)->ChargerVoltageLimit : - _batteryChargeInfoFields.ChargerVoltageLimit; - const int32_t ChargerCurrentLimit = hosversionAtLeast(17,0,0) ? - ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields)->ChargerCurrentLimit : - _batteryChargeInfoFields.ChargerCurrentLimit; - - isChargerConnected = (ChargerConnected != 0); - - // Format all values - snprintf(actualCapacity_c, sizeof(actualCapacity_c), "%.0f mAh", actualFullBatCapacity); - snprintf(designedCapacity_c, sizeof(designedCapacity_c), "%.0f mAh", designedFullBatCapacity); - snprintf(batteryTemp_c, sizeof(batteryTemp_c), "%.1f\u00B0C", (float)_batteryChargeInfoFields.BatteryTemperature / 1000); - snprintf(rawCharge_c, sizeof(rawCharge_c), "%.1f%%", (float)_batteryChargeInfoFields.RawBatteryCharge / 1000); - snprintf(batteryAge_c, sizeof(batteryAge_c), "%.1f%%", (float)_batteryChargeInfoFields.BatteryAge / 1000); - snprintf(voltageAvg_c, sizeof(voltageAvg_c), "%.0f mV (%ds)", batVoltageAvg, batteryFiltered ? 45 : 5); - snprintf(currentFlow_c, sizeof(currentFlow_c), "%+.0f mA (%ss)", batCurrentAvg, batteryFiltered ? "11.25" : "5"); - snprintf(powerFlow_c, sizeof(powerFlow_c), "%+.3f W%s", PowerConsumption, batteryFiltered ? "" : " (5s)"); - snprintf(remainingTime_c, sizeof(remainingTime_c), "%s", tempBatTimeEstimate); - - if (isChargerConnected) { - snprintf(inputCurrentLimit_c, sizeof(inputCurrentLimit_c), "%d mA", _batteryChargeInfoFields.InputCurrentLimit); - snprintf(vbusCurrentLimit_c, sizeof(vbusCurrentLimit_c), "%d mA", _batteryChargeInfoFields.VBUSCurrentLimit); - snprintf(chargeVoltageLimit_c, sizeof(chargeVoltageLimit_c), "%d mV", _batteryChargeInfoFields.ChargeVoltageLimit); - snprintf(chargeCurrentLimit_c, sizeof(chargeCurrentLimit_c), "%d mA", _batteryChargeInfoFields.ChargeCurrentLimit); - snprintf(chargerType_c, sizeof(chargerType_c), "%u", ChargerConnected); - snprintf(chargerMaxVoltage_c, sizeof(chargerMaxVoltage_c), "%u mV", ChargerVoltageLimit); - snprintf(chargerMaxCurrent_c, sizeof(chargerMaxCurrent_c), "%u mA", ChargerCurrentLimit); - } - - mutexUnlock(&mutex_BatteryChecker); - - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override { - if (keysDown & KEY_B) { - isRendering = false; - leventSignal(&renderingStopEvent); - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - skipOnce = true; - runOnce = true; - lastSelectedItem = "Battery/Charger"; - lastMode = ""; - tsl::swapTo(); - return true; - } - return false; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Configurator.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Configurator.hpp deleted file mode 100644 index b18c940b..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Configurator.hpp +++ /dev/null @@ -1,2290 +0,0 @@ -/* - * Mode-Specific Configuration Settings - * - * Based on actual settings structures, each mode only shows applicable settings: - * - * Mini Mode: Refresh Rate, Colors (background, focus_background, separator, category, text), - * Toggles, Font Sizes, Elements, DTC Format - * - * Micro Mode: Refresh Rate, Colors (background, separator, category, text), Toggles, - * Font Sizes, Elements, Text Alignment, Vertical Position (Top/Bottom only), DTC Format - * - * Full Mode: Refresh Rate, Toggles (show_real_freqs, show_deltas, etc.), - * Horizontal Position (Left/Right only) - NO colors, fonts, or elements - * - * FPS Counter: Refresh Rate, Colors (background, text only), Font Sizes, - * Horizontal/Vertical Position - * - * FPS Graph: Refresh Rate, Colors (8 graph-specific colors), Toggles (show_info only), - * Horizontal/Vertical Position - NO fonts - * - * Game Resolutions: Refresh Rate, Colors (background, category, text only), - * Horizontal/Vertical Position - NO toggles, fonts, or elements - */ - -#pragma once -#include -#include "../Utils.hpp" - -#include - -// External variables for navigation -extern std::string jumpItemName; -extern std::string jumpItemValue; -extern std::atomic jumpItemExactMatch; -static tsl::elm::ListItem* lastSelectedListItem; - -// Forward declarations -class ConfiguratorOverlay; -class RefreshRateConfig; -class FontSizeConfig; -class FontSizeSelector; -class ColorConfig; -class ColorSelector; -class AlphaSelector; -class ShowConfig; -class TogglesConfig; -class DTCFormatConfig; - -// Helper functions for color manipulation -inline std::string extractColorWithoutAlpha(const std::string& rgba) { - if (rgba.length() >= 5 && rgba[0] == '#') { - return rgba.substr(0, 4); // Return #RGB without alpha - } - return rgba; -} - -inline std::string extractAlphaFromColor(const std::string& rgba) { - if (rgba.length() == 5 && rgba[0] == '#') { - return std::string(1, rgba[4]); // Return just the alpha character - } - return "9"; // Default alpha -} - -inline std::string setAlphaInColor(const std::string& rgba, char alpha) { - if (rgba.length() >= 4 && rgba[0] == '#') { - std::string result = rgba.substr(0, 4); // Get #RGB - result += alpha; // Add new alpha - return result; - } - return rgba; -} - -// Alpha Selector for background colors -class AlphaSelector : public tsl::Gui { -private: - std::string modeName; - std::string colorKey; - std::string title; - bool isMiniMode; - bool isMicroMode; - bool isFPSCounterMode; - bool isFPSGraphMode; - bool isGameResolutionsMode; - -public: - AlphaSelector(const std::string& mode, const std::string& key, const std::string& displayTitle) - : modeName(mode), colorKey(key), title(displayTitle) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFPSCounterMode = (mode == "FPS Counter"); - isFPSGraphMode = (mode == "FPS Graph"); - isGameResolutionsMode = (mode == "Game Resolutions"); - } - ~AlphaSelector() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader(title)); - - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - else if (isGameResolutionsMode) section = "game_resolutions"; - - // Get current color value and extract alpha - std::string currentColor = ult::parseValueFromIniSection(configIniPath, section, colorKey); - if (currentColor.empty()) { - currentColor = "#0009"; // Default - } - std::string currentAlpha = extractAlphaFromColor(currentColor); - - // Alpha options - static const std::vector> alphaOptions = { - {"Transparent", '0'}, - {"10%", '1'}, - {"20%", '3'}, - {"30%", '4'}, - {"40%", '6'}, - {"50%", '8'}, - {"60%", '9'}, - {"70%", 'B'}, - {"80%", 'C'}, - {"90%", 'E'}, - {"Opaque", 'F'} - }; - - for (const auto& option : alphaOptions) { - auto* alphaItem = new tsl::elm::ListItem(option.first); - if (currentAlpha[0] == option.second) { - alphaItem->setValue(ult::CHECKMARK_SYMBOL); - lastSelectedListItem = alphaItem; - } - alphaItem->setClickListener([this, alphaItem, option, section, currentColor](uint64_t keys) { - if (keys & KEY_A) { - // Get current color and update only the alpha - std::string color = ult::parseValueFromIniSection(configIniPath, section, colorKey); - if (color.empty()) color = "#0009"; - - std::string newColor = setAlphaInColor(color, option.second); - ult::setIniFileValue(configIniPath, section, colorKey, newColor); - - alphaItem->setValue(ult::CHECKMARK_SYMBOL); - if (lastSelectedListItem && lastSelectedListItem != alphaItem) { - lastSelectedListItem->setValue(""); - } - lastSelectedListItem = alphaItem; - return true; - } - return false; - }); - list->addItem(alphaItem); - } - - list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Alpha"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = title; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - - -// Define available DTC format options -static const std::vector> dtcFormats = { - // Special - {"Pretty", "%a, %b %d"+ult::DIVIDER_SYMBOL+"%I:%M %p"}, - {"Compact", "%Y%m%d"+ult::DIVIDER_SYMBOL+"%H:%M:%S"}, - {"FileSafe", "%Y-%m-%d"+ult::DIVIDER_SYMBOL+"%H-%M-%S"}, - {"Day+Time", "%a"+ult::DIVIDER_SYMBOL+"%H:%M"}, - - // Datetime (default included here) - {"Date+Time(s)", "%m-%d-%Y"+ult::DIVIDER_SYMBOL+"%H:%M:%S"}, // default - {"Date+Time AM/PM", "%m-%d-%Y"+ult::DIVIDER_SYMBOL+"%I:%M %p"}, - {"Date+Time(s) AM/PM", "%m-%d-%Y"+ult::DIVIDER_SYMBOL+"%I:%M:%S %p"}, - {"Date+Time EU", "%d/%m/%Y"+ult::DIVIDER_SYMBOL+"%H:%M"}, - {"Date+Time EU AM/PM", "%d/%m/%Y"+ult::DIVIDER_SYMBOL+"%I:%M %p"}, - {"Date+Time(s) EU AM/PM", "%d/%m/%Y"+ult::DIVIDER_SYMBOL+"%I:%M:%S %p"}, - {"Date+Time ISO", "%Y-%m-%dT"+ult::DIVIDER_SYMBOL+"%H:%M:%S"}, - - // Time only - {"Time 24h", "%H:%M"}, - {"Time AM/PM", "%I:%M %p"}, - {"Time(s) 24h", "%H:%M:%S"}, - {"Time(s) AM/PM", "%I:%M:%S %p"}, - - // Date only - {"Date US", "%m-%d-%Y"}, - {"Date EU", "%d/%m/%Y"}, - {"Date ISO", "%Y-%m-%d"}, - {"Date Short", "%m/%d/%y"} -}; - -// DTC Format Configuration (Mini/Micro only) -class DTCFormatConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - -public: - DTCFormatConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - } - ~DTCFormatConfig() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("DTC Format")); - - const std::string section = isMiniMode ? "mini" : "micro"; - std::string currentValue = ult::parseValueFromIniSection(configIniPath, section, "dtc_format"); - - // Handle default values - if (currentValue.empty()) { - currentValue = isMiniMode ? "%m-%d-%Y"+ult::DIVIDER_SYMBOL+"%H:%M:%S" : "%H:%M:%S"; - } - - - for (const auto& format : dtcFormats) { - auto* formatItem = new tsl::elm::ListItem(format.first); - //formatItem->setValue(format.second); - if (format.second == currentValue) { - formatItem->setValue(ult::CHECKMARK_SYMBOL); - lastSelectedListItem = formatItem; - } - formatItem->setClickListener([this, formatItem, format, section](uint64_t keys) { - if (keys & KEY_A) { - ult::setIniFileValue(configIniPath, section, "dtc_format", format.second); - formatItem->setValue(ult::CHECKMARK_SYMBOL); - if (lastSelectedListItem && lastSelectedListItem != formatItem) { - lastSelectedListItem->setValue(""); - } - lastSelectedListItem = formatItem; - return true; - } - return false; - }); - list->addItem(formatItem); - } - - // Jump to currently selected item - list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "DTC Format"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = "DTC Format"; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - -// Toggles Configuration -class TogglesConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - bool isFullMode; - bool isFPSGraphMode; - bool isGameResolutionsMode; - bool isFPSCounterMode; - -public: - TogglesConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFullMode = (mode == "Full"); - isFPSGraphMode = (mode == "FPS Graph"); - isGameResolutionsMode = (mode == "Game Resolutions"); - isFPSCounterMode = (mode == "FPS Counter"); - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Toggles")); - - if (isFPSGraphMode) { - // FPS Graph: show_info and disable_screenshots - auto* showInfo = new tsl::elm::ToggleListItem("Info", getCurrentShowInfo()); - showInfo->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-graph", "show_info", state ? "true" : "false"); - }); - list->addItem(showInfo); - - auto* realTemps = new tsl::elm::ToggleListItem("Real Temperatures", getCurrentFPSGraphRealTemps()); - realTemps->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-graph", "real_temps", state ? "true" : "false"); - }); - list->addItem(realTemps); - - auto* dynamicColors = new tsl::elm::ToggleListItem("Use Dynamic Colors", getCurrentUseDynamicColors()); - dynamicColors->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-graph", "use_dynamic_colors", state ? "true" : "false"); - }); - list->addItem(dynamicColors); - - auto* disableScreenshots = new tsl::elm::ToggleListItem("Disable Screenshots", getCurrentDisableScreenshots("fps-graph")); - disableScreenshots->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-graph", "disable_screenshots", state ? "true" : "false"); - }); - list->addItem(disableScreenshots); - - } else if (isFullMode) { - // Full mode: specific full toggles - auto* realFreqs = new tsl::elm::ToggleListItem("Real Freqs", getCurrentShowRealFreqs()); - realFreqs->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_real_freqs", state ? "true" : "false"); - }); - list->addItem(realFreqs); - - auto* realTemps = new tsl::elm::ToggleListItem("Real Temperatures", getCurrentFullRealTemps()); - realTemps->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "real_temps", state ? "true" : "false"); - }); - list->addItem(realTemps); - - auto* showDeltas = new tsl::elm::ToggleListItem("Deltas", getCurrentShowDeltas()); - showDeltas->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_deltas", state ? "true" : "false"); - }); - list->addItem(showDeltas); - - auto* targetFreqs = new tsl::elm::ToggleListItem("Target Freqs", getCurrentShowTargetFreqs()); - targetFreqs->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_target_freqs", state ? "true" : "false"); - }); - list->addItem(targetFreqs); - - auto* showFPS = new tsl::elm::ToggleListItem("FPS", getCurrentShowFPS()); - showFPS->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_fps", state ? "true" : "false"); - }); - list->addItem(showFPS); - - auto* showRES = new tsl::elm::ToggleListItem("RES", getCurrentShowRES()); - showRES->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_res", state ? "true" : "false"); - }); - list->addItem(showRES); - - auto* showRDSD = new tsl::elm::ToggleListItem("Read Speed", getCurrentShowRDSD()); - showRDSD->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "show_read_speed", state ? "true" : "false"); - }); - list->addItem(showRDSD); - - { - const std::string curRamInfoMode = getCurrentRamInfoMode("full"); - auto* ramInfoModeItem = new tsl::elm::ListItem("RAM Info Mode"); - ramInfoModeItem->setValue(curRamInfoMode); - ramInfoModeItem->setClickListener([this, ramInfoModeItem](u64 keys) -> bool { - if (!(keys & KEY_A)) return false; - const std::string cur = ult::parseValueFromIniSection(configIniPath, "full", "ram_info_mode"); - const std::string next = cur == "Bandwidth" ? "Load" : "Bandwidth"; - ult::setIniFileValue(configIniPath, "full", "ram_info_mode", next); - ramInfoModeItem->setValue(next); - return true; - }); - list->addItem(ramInfoModeItem); - } - - auto* dynamicColors = new tsl::elm::ToggleListItem("Use Dynamic Colors", getCurrentUseDynamicColors()); - dynamicColors->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-graph", "use_dynamic_colors", state ? "true" : "false"); - }); - list->addItem(dynamicColors); - - auto* disableScreenshots = new tsl::elm::ToggleListItem("Disable Screenshots", getCurrentDisableScreenshots("full")); - disableScreenshots->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "full", "disable_screenshots", state ? "true" : "false"); - }); - list->addItem(disableScreenshots); - - } else if (isMiniMode || isMicroMode) { - // Mini/Micro modes: shared toggles - const std::string section = isMiniMode ? "mini" : "micro"; - - auto* realFreqs = new tsl::elm::ToggleListItem("Real Frequencies", getCurrentRealFreqs()); - realFreqs->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "real_freqs", state ? "true" : "false"); - }); - list->addItem(realFreqs); - - auto* realVolts = new tsl::elm::ToggleListItem("Real Voltages", getCurrentRealVolts()); - realVolts->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "real_volts", state ? "true" : "false"); - }); - list->addItem(realVolts); - - auto* realTemps = new tsl::elm::ToggleListItem("Real Temperatures", getCurrentRealTemps()); - realTemps->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "real_temps", state ? "true" : "false"); - }); - list->addItem(realTemps); - - auto* showFullCPU = new tsl::elm::ToggleListItem("Full CPU", getCurrentShowFullCPU()); - showFullCPU->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_full_cpu", state ? "true" : "false"); - }); - list->addItem(showFullCPU); - - auto* showVDDQ = new tsl::elm::ToggleListItem("VDDQ", getCurrentShowVDDQ()); - showVDDQ->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_vddq", state ? "true" : "false"); - }); - list->addItem(showVDDQ); - - auto* showVDD2 = new tsl::elm::ToggleListItem("VDD2", getCurrentShowVDD2()); - showVDD2->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_vdd2", state ? "true" : "false"); - }); - list->addItem(showVDD2); - - auto* showFullRes = new tsl::elm::ToggleListItem("Full Resolution", getCurrentShowFullRes()); - showFullRes->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_full_res", state ? "true" : "false"); - }); - list->addItem(showFullRes); - - auto* socVoltage = new tsl::elm::ToggleListItem("SOC Voltage", getCurrentShowSOCVoltage()); - socVoltage->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_soc_voltage", state ? "true" : "false"); - }); - list->addItem(socVoltage); - - if (isMiniMode) { - auto* partLoadCPUGPU = new tsl::elm::ToggleListItem("RAM Load CPU/GPU", getCurrentShowpartLoadCPUGPU()); - partLoadCPUGPU->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "show_RAM_load_CPU_GPU", state ? "true" : "false"); - }); - list->addItem(partLoadCPUGPU); - } - - if (isMiniMode || isMicroMode) { - const std::string curRamInfoMode = getCurrentRamInfoMode(section); - auto* ramInfoModeItem = new tsl::elm::ListItem("RAM Info Mode"); - ramInfoModeItem->setValue(curRamInfoMode); - ramInfoModeItem->setClickListener([this, section, ramInfoModeItem](u64 keys) -> bool { - if (!(keys & KEY_A)) return false; - const std::string cur = ult::parseValueFromIniSection(configIniPath, section, "ram_info_mode"); - const std::string next = cur == "Bandwidth" ? "Load" : "Bandwidth"; - ult::setIniFileValue(configIniPath, section, "ram_info_mode", next); - ramInfoModeItem->setValue(next); - return true; - }); - list->addItem(ramInfoModeItem); - } - - if (isMiniMode || isMicroMode) { - auto* invertBatteryDisplay = new tsl::elm::ToggleListItem("Invert Battery Display", getCurrentInvertBatteryDisplay()); - invertBatteryDisplay->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "invert_battery_display", state ? "true" : "false"); - }); - list->addItem(invertBatteryDisplay); - } - - auto* dtcSymbol = new tsl::elm::ToggleListItem("Use DTC Symbol", getCurrentUseDTCSymbol()); - dtcSymbol->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "use_dtc_symbol", state ? "true" : "false"); - }); - list->addItem(dtcSymbol); - - auto* dynamicColors = new tsl::elm::ToggleListItem("Use Dynamic Colors", getCurrentUseDynamicColors()); - dynamicColors->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "use_dynamic_colors", state ? "true" : "false"); - }); - list->addItem(dynamicColors); - - auto* disableScreenshots = new tsl::elm::ToggleListItem("Disable Screenshots", getCurrentDisableScreenshots(section)); - disableScreenshots->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "disable_screenshots", state ? "true" : "false"); - }); - list->addItem(disableScreenshots); - - auto* sleepExit = new tsl::elm::ToggleListItem("Sleep Exit", getCurrentSleepExit(section)); - sleepExit->setStateChangedListener([this, section](bool state) { - ult::setIniFileValue(configIniPath, section, "sleep_exit", state ? "true" : "false"); - }); - list->addItem(sleepExit); - - } else if (isGameResolutionsMode) { - // Game Resolutions mode: only disable_screenshots - auto* disableScreenshots = new tsl::elm::ToggleListItem("Disable Screenshots", getCurrentDisableScreenshots("game_resolutions")); - disableScreenshots->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "game_resolutions", "disable_screenshots", state ? "true" : "false"); - }); - list->addItem(disableScreenshots); - - } else if (isFPSCounterMode) { - // FPS Counter mode: only disable_screenshots - auto* integerCounter = new tsl::elm::ToggleListItem("Use Integer Counter", getCurrentUseIntegerCounter("fps-counter")); - integerCounter->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-counter", "use_integer_counter", state ? "true" : "false"); - }); - list->addItem(integerCounter); - - // FPS Counter mode: only disable_screenshots - auto* disableScreenshots = new tsl::elm::ToggleListItem("Disable Screenshots", getCurrentDisableScreenshots("fps-counter")); - disableScreenshots->setStateChangedListener([this](bool state) { - ult::setIniFileValue(configIniPath, "fps-counter", "disable_screenshots", state ? "true" : "false"); - }); - list->addItem(disableScreenshots); - } - - list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch); - { - jumpItemName = ""; - jumpItemValue = ""; - jumpItemExactMatch = false; - } - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - tsl::goBack(); - return true; - } - return false; - } - -private: - // Helper methods for getting current toggle states - bool getCurrentShowInfo() { - std::string value = ult::parseValueFromIniSection(configIniPath, "fps-graph", "show_info"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentFPSGraphRealTemps() { - std::string value = ult::parseValueFromIniSection(configIniPath, "fps-graph", "real_temps"); - if (value.empty()) return false; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentRealFreqs() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "real_freqs"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentRealVolts() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "real_volts"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentRealTemps() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "real_temps"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentShowFullCPU() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_full_cpu"); - if (value.empty()) return false; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentShowVDDQ() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_vddq"); - if (value.empty()) return false; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentShowVDD2() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_vdd2"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - - bool getCurrentShowFullRes() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_full_res"); - if (value.empty()) return true; // Default: true for mini, false for micro - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowSOCVoltage() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_soc_voltage"); - if (value.empty()) return false; // Default: false for mini, true for micro - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowpartLoadCPUGPU() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "show_RAM_load_CPU_GPU"); - if (value.empty()) return false; // Default: false for mini, true for micro - convertToUpper(value); - return value != "FALSE"; - } - - std::string getCurrentRamInfoMode(const std::string& section) { - const std::string value = ult::parseValueFromIniSection(configIniPath, section, "ram_info_mode"); - return (value == "Bandwidth") ? "Bandwidth" : "Load"; - } - - bool getCurrentInvertBatteryDisplay() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "invert_battery_display"); - if (value.empty()) return isMiniMode ? true : false; // Default: false for mini, true for micro - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentUseDTCSymbol() { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "use_dtc_symbol"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentUseDynamicColors() { - const std::string section = isFPSGraphMode? "fps-graph" : (isMiniMode ? "mini" : "micro"); - std::string value = ult::parseValueFromIniSection(configIniPath, section, "use_dynamic_colors"); - if (value.empty()) return true; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentUseIntegerCounter(const std::string& section) { - std::string value = ult::parseValueFromIniSection(configIniPath, section, "use_integer_counter"); - if (value.empty()) return false; // Default is false (screenshots enabled) - convertToUpper(value); - return value != "FALSE"; // True if not explicitly "FALSE" - } - - bool getCurrentDisableScreenshots(const std::string& section) { - std::string value = ult::parseValueFromIniSection(configIniPath, section, "disable_screenshots"); - if (value.empty()) return false; // Default is false (screenshots enabled) - convertToUpper(value); - return value != "FALSE"; // True if not explicitly "FALSE" - } - - bool getCurrentSleepExit(const std::string& section) { - std::string value = ult::parseValueFromIniSection(configIniPath, section, "sleep_exit"); - if (value.empty()) return false; - convertToUpper(value); - return value != "FALSE"; // True if not explicitly "FALSE" - } - - // Full mode toggle helpers - bool getCurrentShowRealFreqs() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_real_freqs"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentFullRealTemps() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "real_temps"); - if (value.empty()) return false; - convertToUpper(value); - return value == "TRUE"; - } - - bool getCurrentShowDeltas() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_deltas"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowTargetFreqs() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_target_freqs"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowFPS() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_fps"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowRES() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_res"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } - - bool getCurrentShowRDSD() { - std::string value = ult::parseValueFromIniSection(configIniPath, "full", "show_read_speed"); - if (value.empty()) return true; - convertToUpper(value); - return value != "FALSE"; - } -}; - -// Refresh Rate Configuration -class RefreshRateConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - bool isFullMode; - bool isGameResolutionsMode; - bool isFPSCounterMode; - bool isFPSGraphMode; - int currentRate; - -public: - RefreshRateConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFullMode = (mode == "Full"); - isGameResolutionsMode = (mode == "Game Resolutions"); - isFPSCounterMode = (mode == "FPS Counter"); - isFPSGraphMode = (mode == "FPS Graph"); - - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - const std::string value = ult::parseValueFromIniSection(configIniPath, section, "refresh_rate"); - int defaultRate = (isGameResolutionsMode) ? 10 : ((isFPSCounterMode || isFPSGraphMode) ? 30 : 1); - currentRate = value.empty() ? defaultRate : std::clamp(atoi(value.c_str()), 1, 60); - } - - ~RefreshRateConfig() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Refresh Rate")); - - static const std::vector rates = {1, 2, 3, 5, 10, 15, 30, 60}; - for (int rate : rates) { - auto* rateItem = new tsl::elm::ListItem(std::to_string(rate) + " Hz"); - if (rate == currentRate) { - rateItem->setValue(ult::CHECKMARK_SYMBOL); - lastSelectedListItem = rateItem; - } - rateItem->setClickListener([this, rateItem, rate](uint64_t keys) { - if (keys & KEY_A) { - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - ult::setIniFileValue(configIniPath, section, "refresh_rate", std::to_string(rate)); - rateItem->setValue(ult::CHECKMARK_SYMBOL); - if (lastSelectedListItem && rateItem != lastSelectedListItem) - lastSelectedListItem->setValue(""); - lastSelectedListItem = rateItem; - return true; - } - return false; - }); - list->addItem(rateItem); - } - - list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = "Refresh Rate"; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - -// Frame Padding Configuration (Mini only) -class FramePaddingConfig : public tsl::Gui { -private: - std::string modeName; - int currentPadding; - -public: - FramePaddingConfig(const std::string& mode) : modeName(mode) { - const std::string value = ult::parseValueFromIniSection(configIniPath, "mini", "frame_padding"); - currentPadding = value.empty() ? 10 : std::clamp(atoi(value.c_str()), 0, 14); // max value 14 - } - - ~FramePaddingConfig() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Frame Padding")); - - static const std::vector paddingValues = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - for (int padding : paddingValues) { - auto* paddingItem = new tsl::elm::ListItem(std::to_string(padding) + " px"); - if (padding == currentPadding) { - paddingItem->setValue(ult::CHECKMARK_SYMBOL); - lastSelectedListItem = paddingItem; - } - paddingItem->setClickListener([this, paddingItem, padding](uint64_t keys) { - if (keys & KEY_A) { - ult::setIniFileValue(configIniPath, "mini", "frame_padding", std::to_string(padding)); - paddingItem->setValue(ult::CHECKMARK_SYMBOL); - if (lastSelectedListItem && paddingItem != lastSelectedListItem) - lastSelectedListItem->setValue(""); - lastSelectedListItem = paddingItem; - return true; - } - return false; - }); - list->addItem(paddingItem); - } - - list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = "Frame Padding"; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - - -// Font Size Selector -class FontSizeSelector : public tsl::Gui { -private: - std::string modeName; - std::string fontType; - bool isMiniMode; - bool isMicroMode; - bool isFPSCounterMode; - std::string title; - -public: - FontSizeSelector(const std::string& mode, const std::string& type) - : modeName(mode), fontType(type) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFPSCounterMode = (mode == "FPS Counter"); - title = fontType; - title[0] = std::toupper(title[0]); - title += " Font Size"; - } - ~FontSizeSelector() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader(title)); - - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFPSCounterMode) section = "fps-counter"; - - const std::string keyName = fontType + "_font_size"; - const std::string currentValue = ult::parseValueFromIniSection(configIniPath, section, keyName); - int defaultSize = isFPSCounterMode ? 40 : 15; - const int currentSize = currentValue.empty() ? defaultSize : atoi(currentValue.c_str()); - - // Font size range depends on mode - int minSize = 8; - int maxSize; - if (isFPSCounterMode) maxSize = 150; - else if (isMiniMode) maxSize = 22; - else maxSize = 18; // Micro mode - - for (int size = minSize; size <= maxSize; size++) { - auto* sizeItem = new tsl::elm::ListItem(std::to_string(size) + " pt"); - if (size == currentSize) { - sizeItem->setValue(ult::CHECKMARK_SYMBOL); - lastSelectedListItem = sizeItem; - } - sizeItem->setClickListener([this, sizeItem, size, keyName, section](uint64_t keys) { - if (keys & KEY_A) { - ult::setIniFileValue(configIniPath, section, keyName, std::to_string(size)); - sizeItem->setValue(ult::CHECKMARK_SYMBOL); - if (lastSelectedListItem && lastSelectedListItem != sizeItem) - lastSelectedListItem->setValue(""); - lastSelectedListItem = sizeItem; - return true; - } - return false; - }); - list->addItem(sizeItem); - } - - list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Font Sizes"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = title; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - -// Font Size Configuration -class FontSizeConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - bool isFPSCounterMode; - -public: - FontSizeConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFPSCounterMode = (mode == "FPS Counter"); - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Font Sizes")); - - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFPSCounterMode) section = "fps-counter"; - - const std::string handheldValue = ult::parseValueFromIniSection(configIniPath, section, "handheld_font_size"); - const std::string dockedValue = ult::parseValueFromIniSection(configIniPath, section, "docked_font_size"); - - int defaultSize = isFPSCounterMode ? 40 : 15; - const int handheldSize = handheldValue.empty() ? defaultSize : atoi(handheldValue.c_str()); - const int dockedSize = dockedValue.empty() ? defaultSize : atoi(dockedValue.c_str()); - - auto* handheldItem = new tsl::elm::ListItem("Handheld Font Size"); - handheldItem->setValue(std::to_string(handheldSize) + " pt"); - handheldItem->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "handheld"); - return true; - } - return false; - }); - list->addItem(handheldItem); - - auto* dockedItem = new tsl::elm::ListItem("Docked Font Size"); - dockedItem->setValue(std::to_string(dockedSize) + " pt"); - dockedItem->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "docked"); - return true; - } - return false; - }); - list->addItem(dockedItem); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch); - { - jumpItemName = ""; - jumpItemValue = ""; - jumpItemExactMatch = false; - } - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - tsl::goBack(); - return true; - } - return false; - } -}; - -// Color Selector -class ColorSelector : public tsl::Gui { -private: - std::string modeName; - std::string modeTitle; - std::string colorKey; - std::string defaultValue; - bool isMiniMode; - bool isMicroMode; - bool isFullMode; - bool isGameResolutionsMode; - bool isFPSCounterMode; - bool isFPSGraphMode; - bool isBackgroundColor; - bool isTextBasedColor; - -public: - ColorSelector(const std::string& mode, const std::string& title, const std::string& key, const std::string& def) - : modeName(mode), modeTitle(title), colorKey(key), defaultValue(def) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFullMode = (mode == "Full"); - isGameResolutionsMode = (mode == "Game Resolutions"); - isFPSCounterMode = (mode == "FPS Counter"); - isFPSGraphMode = (mode == "FPS Graph"); - - // Determine if this is a background color or text-based color - isBackgroundColor = (key == "background_color" || key == "focus_background_color" || - (isFPSGraphMode && (key == "fps_counter_color" || key == "dashed_line_color"))); - - isTextBasedColor = (key == "text_color" || key == "separator_color" || key == "cat_color" || - (isFPSGraphMode && (key == "border_color" || key == "max_fps_text_color" || - key == "min_fps_text_color" || key == "main_line_color" || - key == "rounded_line_color" || key == "perfect_line_color"))); - } - - ~ColorSelector() { - lastSelectedListItem = nullptr; - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader(modeTitle)); - - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - std::string currentValue = ult::parseValueFromIniSection(configIniPath, section, colorKey); - if (currentValue.empty()) currentValue = defaultValue; - - // Extract the color without alpha for comparison (for backgrounds and text colors) - std::string currentColorWithoutAlpha = extractColorWithoutAlpha(currentValue); - - // Updated colors list with comprehensive color palette - static const std::vector> colors = { - // Grays & Basics - {"Black", "#000F"}, - {"Dark Gray", "#333F"}, - {"Gray", "#444F"}, - {"Light Gray", "#888F"}, - {"Silver", "#CCCF"}, - {"White", "#FFFF"}, - - // Reds - {"Dark Red", "#800F"}, - {"Red", "#F00F"}, - {"Light Red", "#F88F"}, - {"Pink", "#F8AF"}, - - // Greens - {"Dark Green", "#080F"}, - {"Green", "#0F0F"}, - {"Lime Green", "#0C0F"}, - {"Light Green", "#8F8F"}, - - // Blues - {"Dark Blue", "#003F"}, - {"Blue", "#00FF"}, - {"Light Blue", "#2DFF"}, - {"Sky Blue", "#8CFF"}, - - // Purples - {"Dark Purple", "#808F"}, - {"Purple", "#80FF"}, - {"Light Purple", "#C8FF"}, - {"Violet", "#A0FF"}, - - // Yellows & Oranges - {"Orange", "#F80F"}, - {"Yellow", "#FF0F"}, - {"Light Yellow", "#FFCF"}, - - // Cyans & Teals - {"Teal", "#088F"}, - {"Cyan", "#0FFF"}, - {"Light Cyan", "#8FFF"}, - - // Magentas & Pinks - {"Magenta", "#F0FF"}, - {"Hot Pink", "#F8CF"}, - - // Browns - {"Brown", "#840F"}, - {"Light Brown", "#A86F"} - }; - - std::string _jumpItemValue; - for (const auto& color : colors) { - auto* colorItem = new tsl::elm::ListItem(color.first); - - // For display, show the color code based on type - std::string displayValue; - if (isTextBasedColor || isBackgroundColor) { - // For ALL text-based colors AND background colors, show without the alpha - displayValue = extractColorWithoutAlpha(color.second); - } else { - // For any remaining FPS Graph colors (shouldn't happen now), keep original behavior - displayValue = color.second; - } - - colorItem->setValue(displayValue); - - // Check if this is the selected color - bool isSelected = false; - if (isBackgroundColor || isTextBasedColor) { - // For background and text colors, compare without alpha - isSelected = (extractColorWithoutAlpha(color.second) == currentColorWithoutAlpha); - } else { - // For any remaining FPS Graph colors (shouldn't happen now) - isSelected = (color.second == currentValue); - } - - if (isSelected) { - colorItem->setValue(displayValue + " " + ult::CHECKMARK_SYMBOL); - lastSelectedListItem = colorItem; - _jumpItemValue = displayValue + " " + ult::CHECKMARK_SYMBOL; - } - - colorItem->setClickListener([this, colorItem, color, section, displayValue](uint64_t keys) { - if (keys & KEY_A) { - std::string valueToSave = color.second; - - if (isBackgroundColor) { - // For background colors, preserve existing alpha - std::string existingColor = ult::parseValueFromIniSection(configIniPath, section, colorKey); - if (!existingColor.empty() && existingColor.length() == 5) { - char existingAlpha = existingColor[4]; - valueToSave = setAlphaInColor(color.second, existingAlpha); - } - } else if (isTextBasedColor) { - // For text-based colors, ensure alpha is always F - valueToSave = setAlphaInColor(color.second, 'F'); - } - // For any remaining FPS Graph colors (shouldn't happen now), use as-is - - ult::setIniFileValue(configIniPath, section, colorKey, valueToSave); - - // Update the UI - clear old checkmark and set new one - if (lastSelectedListItem && lastSelectedListItem != colorItem) { - // Get the display value for the old selected item - std::string oldDisplayValue; - for (const auto& c : colors) { - if (lastSelectedListItem->getText() == c.first) { - if (isTextBasedColor || isBackgroundColor) { - oldDisplayValue = extractColorWithoutAlpha(c.second); - } else { - oldDisplayValue = c.second; - } - break; - } - } - lastSelectedListItem->setValue(oldDisplayValue); - } - - // Set new checkmark - colorItem->setValue(displayValue + " " + ult::CHECKMARK_SYMBOL); - lastSelectedListItem = colorItem; - return true; - } - return false; - }); - list->addItem(colorItem); - } - list->jumpToItem("", _jumpItemValue, false); - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Colors"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - jumpItemName = modeTitle; - jumpItemValue = ""; - jumpItemExactMatch = false; - - tsl::swapTo(SwapDepth(2), modeName); - return true; - } - return false; - } -}; - -// Color Configuration -class ColorConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - bool isFullMode; - bool isGameResolutionsMode; - bool isFPSCounterMode; - bool isFPSGraphMode; - -public: - ColorConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFullMode = (mode == "Full"); - isGameResolutionsMode = (mode == "Game Resolutions"); - isFPSCounterMode = (mode == "FPS Counter"); - isFPSGraphMode = (mode == "FPS Graph"); - - // Full mode should never access color configuration - //if (isFullMode) { - // // This should not happen, but if it does, go back - // tsl::goBack(); - //} - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Colors")); - - auto getCurrentColor = [this](const std::string& key, const std::string& def) { - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - std::string value = ult::parseValueFromIniSection(configIniPath, section, key); - return value.empty() ? def : value; - }; - - auto getColorName = [](const std::string& hexColor) -> std::string { - // Extract RGB without alpha for comparison - std::string rgb = hexColor; - if (hexColor.length() == 5 && hexColor[0] == '#') { - rgb = hexColor.substr(0, 4); - } - - // Map of hex colors to names (RGB only, no alpha) - static const std::map colorNames = { - // Grays & Basics - {"#000", "Black"}, - {"#333", "Dark Gray"}, - {"#444", "Gray"}, - {"#888", "Light Gray"}, - {"#CCC", "Silver"}, - {"#FFF", "White"}, - - // Reds - {"#800", "Dark Red"}, - {"#F00", "Red"}, - {"#F88", "Light Red"}, - {"#F8A", "Pink"}, - - // Greens - {"#080", "Dark Green"}, - {"#0F0", "Green"}, - {"#0C0", "Lime Green"}, - {"#8F8", "Light Green"}, - - // Blues - {"#003", "Dark Blue"}, - {"#00F", "Blue"}, - {"#2DF", "Light Blue"}, - {"#8CF", "Sky Blue"}, - - // Purples - {"#808", "Dark Purple"}, - {"#80F", "Purple"}, - {"#C8F", "Light Purple"}, - {"#A0F", "Violet"}, - - // Yellows & Oranges - {"#F80", "Orange"}, - {"#FF0", "Yellow"}, - {"#FFC", "Light Yellow"}, - - // Cyans & Teals - {"#088", "Teal"}, - {"#0FF", "Cyan"}, - {"#8FF", "Light Cyan"}, - - // Magentas & Pinks - {"#F0F", "Magenta"}, - {"#F8C", "Hot Pink"}, - - // Browns - {"#840", "Brown"}, - {"#A86", "Light Brown"} - }; - - auto it = colorNames.find(rgb); - if (it != colorNames.end()) { - // Special case for black/transparent disambiguation - if (rgb == "#000" && hexColor.length() == 5) { - char alpha = hexColor[4]; - if (alpha == '0') return "Transparent"; - else return "Black"; - } - return it->second; - } - return rgb; // Return hex if no name found - }; - - auto getAlphaPercentage = [](const std::string& color) -> std::string { - if (color.length() == 5 && color[0] == '#') { - char alpha = color[4]; - switch(alpha) { - case '0': return "0%"; - case '1': return "10%"; - case '3': return "20%"; - case '4': return "30%"; - case '6': return "40%"; - case '8': return "50%"; - case '9': return "60%"; - case 'B': case 'b': return "70%"; - case 'C': case 'c': return "80%"; - case 'E': case 'e': return "90%"; - case 'F': case 'f': return "100%"; - default: return "60%"; - } - } - return "60%"; - }; - - if (!isFullMode) { - // Background Color (all modes) - auto* bgColor = new tsl::elm::ListItem("Background Color"); - std::string bgDefault = "#0009"; - std::string bgCurrentColor = getCurrentColor("background_color", bgDefault); - // Display color name instead of hex - bgColor->setValue(getColorName(bgCurrentColor)); - bgColor->setClickListener([this, bgDefault](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Background Color", "background_color", bgDefault); - return true; - } - return false; - }); - list->addItem(bgColor); - - // Background Alpha (new) - auto* bgAlpha = new tsl::elm::ListItem("Background Alpha"); - bgAlpha->setValue(getAlphaPercentage(bgCurrentColor)); - bgAlpha->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "background_color", "Background Alpha"); - return true; - } - return false; - }); - list->addItem(bgAlpha); - - if (isMiniMode || isFPSCounterMode || isFPSGraphMode || isGameResolutionsMode) { - // Mini mode: has focus background - auto* focusBgColor = new tsl::elm::ListItem("Focus Color"); - std::string focusCurrentColor = getCurrentColor("focus_background_color", "#000F"); - focusBgColor->setValue(getColorName(focusCurrentColor)); - focusBgColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Focus Color", "focus_background_color", "#000F"); - return true; - } - return false; - }); - list->addItem(focusBgColor); - - // Focus Alpha (new) - auto* focusAlpha = new tsl::elm::ListItem("Focus Alpha"); - focusAlpha->setValue(getAlphaPercentage(focusCurrentColor)); - focusAlpha->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "focus_background_color", "Focus Alpha"); - return true; - } - return false; - }); - list->addItem(focusAlpha); - } - } - - // Text Color (all modes) - auto* textColor = new tsl::elm::ListItem("Text Color"); - std::string textCurrentColor = getCurrentColor("text_color", "#FFFF"); - // Display color name for text colors - textColor->setValue(getColorName(textCurrentColor)); - textColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Text Color", "text_color", "#FFFF"); - return true; - } - return false; - }); - list->addItem(textColor); - - if (isFPSGraphMode) { - // FPS Graph specific colors - struct ColorSetting { - std::string name; - std::string key; - std::string defaultVal; - bool isBackgroundType; // true for colors that allow alpha adjustment - }; - - // Game Resolutions: only category color (no separator) - auto* catColor = new tsl::elm::ListItem("Category Color"); - catColor->setValue(getColorName(getCurrentColor("cat_color", "#0F0F"))); - catColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color", "cat_color", "#0F0F"); - return true; - } - return false; - }); - list->addItem(catColor); - - static const std::vector fpsGraphColors = { - {"FPS Counter", "fps_counter_color", "#888C", true}, // background type - {"Border", "border_color", "#2DFF", false}, // text type - {"Dashed Line", "dashed_line_color", "#8888", true}, // background type - {"Max FPS Text", "max_fps_text_color", "#FFFF", false}, // text type - {"Min FPS Text", "min_fps_text_color", "#FFFF", false}, // text type - {"Main Line", "main_line_color", "#FFFF", false}, // text type - {"Rounded Line", "rounded_line_color", "#F0FF", false}, // text type - {"Perfect Line", "perfect_line_color", "#0C0F", false} // text type - }; - - for (const auto& color : fpsGraphColors) { - auto* colorItem = new tsl::elm::ListItem(color.name + " Color"); - const std::string currentVal = getCurrentColor(color.key, color.defaultVal); - - if (color.isBackgroundType) { - // For background-type colors, show color name - colorItem->setValue(getColorName(currentVal)); - } else { - // For text-type colors, show color name - colorItem->setValue(getColorName(currentVal)); - } - - colorItem->setClickListener([this, color](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, color.name, color.key, color.defaultVal); - return true; - } - return false; - }); - list->addItem(colorItem); - - // Add alpha selector for background-type colors - if (color.isBackgroundType) { - auto* alphaItem = new tsl::elm::ListItem(color.name + " Alpha"); - alphaItem->setValue(getAlphaPercentage(currentVal)); - alphaItem->setClickListener([this, color](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, color.key, color.name + " Alpha"); - return true; - } - return false; - }); - list->addItem(alphaItem); - } - } - - } else if (isFullMode) { - auto* catColor1 = new tsl::elm::ListItem("Category Color 1"); - // Display color name for category colors - catColor1->setValue(getColorName(getCurrentColor("cat_color_1", "#8FFF"))); - catColor1->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color 1", "cat_color_1", "#8FFF"); - return true; - } - return false; - }); - list->addItem(catColor1); - - auto* catColor2 = new tsl::elm::ListItem("Category Color 2"); - // Display color name for category colors - catColor2->setValue(getColorName(getCurrentColor("cat_color_2", "#2DFF"))); - catColor2->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color 2", "cat_color_2", "#2DFF"); - return true; - } - return false; - }); - list->addItem(catColor2); - - auto* sepColor = new tsl::elm::ListItem("Separator Color"); - // Display color name for separator colors - sepColor->setValue(getColorName(getCurrentColor("separator_color", "#888F"))); - sepColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Separator Color", "separator_color", "#888F"); - return true; - } - return false; - }); - list->addItem(sepColor); - } else if (isMiniMode) { - auto* catColor = new tsl::elm::ListItem("Category Color"); - // Display color name for category colors - catColor->setValue(getColorName(getCurrentColor("cat_color", "#2DFF"))); - catColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color", "cat_color", "#2DFF"); - return true; - } - return false; - }); - list->addItem(catColor); - - auto* sepColor = new tsl::elm::ListItem("Separator Color"); - // Display color name for separator colors - sepColor->setValue(getColorName(getCurrentColor("separator_color", "#888F"))); - sepColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Separator Color", "separator_color", "#888F"); - return true; - } - return false; - }); - list->addItem(sepColor); - - } else if (isMicroMode) { - auto* catColor = new tsl::elm::ListItem("Category Color"); - catColor->setValue(getColorName(getCurrentColor("cat_color", "#2DFF"))); - catColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color", "cat_color", "#2DFF"); - return true; - } - return false; - }); - list->addItem(catColor); - - // Micro mode: separator and category colors (no focus background like Mini) - auto* sepColor = new tsl::elm::ListItem("Separator Color"); - sepColor->setValue(getColorName(getCurrentColor("separator_color", "#888F"))); - sepColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Separator Color", "separator_color", "#888F"); - return true; - } - return false; - }); - list->addItem(sepColor); - - - } else if (isGameResolutionsMode) { - // Game Resolutions: only category color (no separator) - auto* catColor = new tsl::elm::ListItem("Category Color"); - catColor->setValue(getColorName(getCurrentColor("cat_color", "#2DFF"))); - catColor->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName, "Category Color", "cat_color", "#2DFF"); - return true; - } - return false; - }); - list->addItem(catColor); - } - // FPS Counter mode: only background and text colors (already added above) - // Full mode: NO color settings at all (excluded from this function) - - list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch); - { - jumpItemName = ""; - jumpItemValue = ""; - jumpItemExactMatch = false; - } - - //list->disableCaching(); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - tsl::goBack(); - return true; - } - return false; - } -}; - -// Show Configuration (Mini/Micro only) -class ShowConfig : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - std::vector elementOrder; - std::unordered_set enabledElements; - -public: - ShowConfig(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Elements " + ult::DIVIDER_SYMBOL + " \uE0E3 Move Down " + ult::DIVIDER_SYMBOL + " \uE0E2 Move Up")); - - const std::string section = isMiniMode ? "mini" : "micro"; - std::string showValue = ult::parseValueFromIniSection(configIniPath, section, "show"); - std::string orderValue = ult::parseValueFromIniSection(configIniPath, section, "element_order"); - - if (showValue.empty()) { - showValue = isMiniMode ? "DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES" : "FPS+CPU+GPU+RAM+SOC+BAT+DTC"; - } - convertToUpper(showValue); - - enabledElements.clear(); - ult::StringStream ss(showValue); - std::string item; - while (ss.getline(item, '+')) { - if (!item.empty()) { - enabledElements.insert(item); - } - } - - elementOrder.clear(); - if (!orderValue.empty()) { - convertToUpper(orderValue); - ult::StringStream orderSS(orderValue); - std::string orderItem; - while (orderSS.getline(orderItem, '+')) { - if (!orderItem.empty()) { - elementOrder.push_back(orderItem); - } - } - } else { - ult::StringStream ss2(showValue); - while (ss2.getline(item, '+')) { - if (!item.empty()) { - elementOrder.push_back(item); - } - } - } - - static constexpr std::string_view miniElements[] = { - "DTC","BAT","CPU","GPU","RAM","MEM","READ","SOC","TMP","FPS","RES" - }; - - static constexpr std::string_view microElements[] = { - "FPS","CPU","GPU","RAM","READ","SOC","TMP","RES","BAT","DTC" - }; - - // Use span or array reference instead of pointer - const auto* allElements = isMiniMode ? miniElements : microElements; - const size_t allElementsSize = isMiniMode ? std::size(miniElements) : std::size(microElements); - - elementOrder.clear(); - if (!orderValue.empty()) { - convertToUpper(orderValue); - ult::StringStream orderSS(orderValue); - std::string orderItem; - while (orderSS.getline(orderItem, '+')) { - if (!orderItem.empty()) { - elementOrder.push_back(orderItem); - } - } - } else { - // Initialize with allElements order instead - for (size_t i = 0; i < allElementsSize; i++) { - auto elem = allElements[i]; - if (!isMiniMode && elem == "MEM") - continue; - elementOrder.emplace_back(elem); - } - } - - for (size_t i = 0; i < elementOrder.size(); i++) { - const std::string& element = elementOrder[i]; - const bool isEnabled = enabledElements.find(element) != enabledElements.end(); - - auto* elementItem = new tsl::elm::ListItem(element); - elementItem->setValue(isEnabled ? ult::ON : ult::OFF, !isEnabled); - - elementItem->setClickListener([this, elementItem, element](uint64_t keys) { - static bool hasNotTriggeredAnimation = false; - - if (hasNotTriggeredAnimation) { - elementItem->triggerClickAnimation(); - hasNotTriggeredAnimation = false; - } - - if (keys & KEY_A) { - const bool currentlyEnabled = enabledElements.find(element) != enabledElements.end(); - - if (currentlyEnabled) { - enabledElements.erase(element); - } else { - enabledElements.insert(element); - } - - updateShowAndOrder(); - jumpItemName = element; - jumpItemValue = ""; - jumpItemExactMatch = true; - hasNotTriggeredAnimation = true; - - tsl::swapTo(SwapDepth(1), modeName); - return true; - } - else if (keys & KEY_Y || keys & KEY_X) { - size_t currentPos = 0; - for (size_t j = 0; j < elementOrder.size(); j++) { - if (elementOrder[j] == element) { - currentPos = j; - break; - } - } - - if (keys & KEY_X) { - if (currentPos > 0) { - std::swap(elementOrder[currentPos], elementOrder[currentPos - 1]); - } else { - const std::string temp = elementOrder[0]; - for (size_t j = 0; j < elementOrder.size() - 1; j++) { - elementOrder[j] = elementOrder[j + 1]; - } - elementOrder[elementOrder.size() - 1] = temp; - } - triggerRumbleClick.store(true, std::memory_order_release); - triggerMoveSound.store(true, std::memory_order_release); - } else if (keys & KEY_Y) { - if (currentPos < elementOrder.size() - 1) { - std::swap(elementOrder[currentPos], elementOrder[currentPos + 1]); - } else { - const std::string temp = elementOrder[elementOrder.size() - 1]; - for (size_t j = elementOrder.size() - 1; j > 0; j--) { - elementOrder[j] = elementOrder[j - 1]; - } - elementOrder[0] = temp; - } - triggerRumbleClick.store(true, std::memory_order_release); - triggerMoveSound.store(true, std::memory_order_release); - } - - updateShowAndOrder(); - jumpItemName = element; - jumpItemValue = ""; - jumpItemExactMatch = true; - - tsl::swapTo(SwapDepth(1), modeName); - return true; - } - return false; - }); - - list->addItem(elementItem); - } - - list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch); - { - jumpItemName = ""; - jumpItemValue = ""; - jumpItemExactMatch = false; - } - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - tsl::goBack(); - return true; - } - return false; - } - -private: - void updateShowAndOrder() { - std::string newShowValue; - std::string newOrderValue; - bool showFirst = true; - bool orderFirst = true; - - for (const std::string& element : elementOrder) { - if (!orderFirst) { - newOrderValue += "+"; - } - newOrderValue += element; - orderFirst = false; - - if (enabledElements.find(element) != enabledElements.end()) { - if (!showFirst) { - newShowValue += "+"; - } - newShowValue += element; - showFirst = false; - } - } - - const std::string section = isMiniMode ? "mini" : "micro"; - ult::setIniFileValue(configIniPath, section, "show", newShowValue); - ult::setIniFileValue(configIniPath, section, "element_order", newOrderValue); - } -}; - -// Main Configurator -class ConfiguratorOverlay : public tsl::Gui { -private: - std::string modeName; - bool isMiniMode; - bool isMicroMode; - bool isFullMode; - bool isGameResolutionsMode; - bool isFPSCounterMode; - bool isFPSGraphMode; - -public: - ConfiguratorOverlay(const std::string& mode) : modeName(mode) { - isMiniMode = (mode == "Mini"); - isMicroMode = (mode == "Micro"); - isFullMode = (mode == "Full"); - isGameResolutionsMode = (mode == "Game Resolutions"); - isFPSCounterMode = (mode == "FPS Counter"); - isFPSGraphMode = (mode == "FPS Graph"); - } - - virtual tsl::elm::Element* createUI() override { - auto* list = new tsl::elm::List(); - list->addItem(new tsl::elm::CategoryHeader("Configuration")); - - // 5. Elements (Mini/Micro only) - if (isMiniMode || isMicroMode) { - auto* showSettings = new tsl::elm::ListItem("Elements"); - showSettings->setValue(ult::DROPDOWN_SYMBOL); - showSettings->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(showSettings); - } - - // 3. Toggles (All modes) - //if (isMiniMode || isMicroMode || isFullMode || isFPSGraphMode) { - auto* toggles = new tsl::elm::ListItem("Toggles"); - toggles->setValue(ult::DROPDOWN_SYMBOL); - toggles->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(toggles); - //} - - // 2. Colors (not Full mode - it has no color settings) - //if (!isFullMode) { - auto* colors = new tsl::elm::ListItem("Colors"); - colors->setValue(ult::DROPDOWN_SYMBOL); - colors->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(colors); - //} - - - // 4. Font Sizes (Mini/Micro/FPS Counter only) - if (isMiniMode || isMicroMode || isFPSCounterMode) { - auto* fontSizes = new tsl::elm::ListItem("Font Sizes"); - fontSizes->setValue(ult::DROPDOWN_SYMBOL); - fontSizes->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(fontSizes); - } - - // 1. Refresh Rate (all modes) - auto* refreshRate = new tsl::elm::ListItem("Refresh Rate"); - refreshRate->setValue(std::to_string(getCurrentRefreshRate()) + " Hz"); - refreshRate->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(refreshRate); - - // 6. DTC Format (Mini/Micro only) - NEW ADDITION - if (isMiniMode || isMicroMode) { - auto* dtcFormat = new tsl::elm::ListItem("DTC Format"); - dtcFormat->setValue(getCurrentDTCFormat()); - dtcFormat->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(dtcFormat); - } - - // 7. Frame Padding (Mini only) - NEW ADDITION - if (isMiniMode || isGameResolutionsMode || isFPSCounterMode || isFPSGraphMode) { - auto* framePadding = new tsl::elm::ListItem("Frame Padding"); - framePadding->setValue(std::to_string(getCurrentFramePadding()) + " px"); - framePadding->setClickListener([this](uint64_t keys) { - if (keys & KEY_A) { - tsl::changeTo(modeName); - return true; - } - return false; - }); - list->addItem(framePadding); - } - - // 7. Mode-specific positioning settings - if (isMicroMode) { - // Text Alignment for Micro - auto* textAlign = new tsl::elm::ListItem("Text Alignment"); - textAlign->setValue(getCurrentTextAlign()); - textAlign->setClickListener([this, textAlign](uint64_t keys) { - if (keys & KEY_A) { - const std::string next = cycleTextAlign(); - textAlign->setValue(next); - return true; - } - return false; - }); - list->addItem(textAlign); - - // Vertical Position for Micro (Top/Bottom only) - auto* layerPos = new tsl::elm::ListItem("Vertical Position"); - layerPos->setValue(getCurrentLayerPosBottom()); - layerPos->setClickListener([this, layerPos](uint64_t keys) { - if (keys & KEY_A) { - const std::string next = cycleLayerPosBottom(); - layerPos->setValue(next); - return true; - } - return false; - }); - list->addItem(layerPos); - - } else if (isFullMode) { - // Horizontal Position for Full (Left/Right only) - auto* layerPos = new tsl::elm::ListItem("Horizontal Position"); - layerPos->setValue(getCurrentLayerPosRight()); - layerPos->setClickListener([this, layerPos](uint64_t keys) { - if (keys & KEY_A) { - const std::string next = cycleLayerPosRight(); - layerPos->setValue(next); - return true; - } - return false; - }); - list->addItem(layerPos); - - //} else if (isGameResolutionsMode || isFPSCounterMode || isFPSGraphMode) { - // // Both horizontal and vertical positioning - // auto* layerPosH = new tsl::elm::ListItem("Horizontal Position"); - // layerPosH->setValue(getCurrentLayerPosRight()); - // layerPosH->setClickListener([this, layerPosH](uint64_t keys) { - // if (keys & KEY_A) { - // const std::string next = cycleLayerPosRight(); - // layerPosH->setValue(next); - // return true; - // } - // return false; - // }); - // list->addItem(layerPosH); - // - // auto* layerPosV = new tsl::elm::ListItem("Vertical Position"); - // layerPosV->setValue(getCurrentLayerPosBottom()); - // layerPosV->setClickListener([this, layerPosV](uint64_t keys) { - // if (keys & KEY_A) { - // const std::string next = cycleLayerPosBottom(); - // layerPosV->setValue(next); - // return true; - // } - // return false; - // }); - // list->addItem(layerPosV); - } - - list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch.load(std::memory_order_acquire)); - { - jumpItemName = ""; - jumpItemValue = ""; - jumpItemExactMatch = false; - } - - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", modeName); - rootFrame->setContent(list); - return rootFrame; - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysDown & KEY_B) { - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - lastSelectedItem = modeName; - tsl::swapTo(); - return true; - } - return false; - } - -private: - int getCurrentRefreshRate() { - std::string section; - if (isMiniMode) section = "mini"; - else if (isMicroMode) section = "micro"; - else if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - std::string value = ult::parseValueFromIniSection(configIniPath, section, "refresh_rate"); - int defaultRate = (isGameResolutionsMode) ? 10 : ((isFPSCounterMode || isFPSGraphMode) ? 30 : 1); - return value.empty() ? defaultRate : atoi(value.c_str()); - } - - // NEW METHOD: Get current DTC format for display - std::string getCurrentDTCFormat() { - if (isMiniMode || isMicroMode) { - const std::string section = isMiniMode ? "mini" : "micro"; - std::string value = ult::parseValueFromIniSection(configIniPath, section, "dtc_format"); - - // Handle defaults properly - if (value.empty()) { - value = isMiniMode ? "%m-%d-%Y"+ult::DIVIDER_SYMBOL+"%H:%M:%S" : "%H:%M:%S"; - } - - // Convert format string to display name - return getDTCFormatName(value); - } - return ""; - } - - // Helper function to convert format string to display name - std::string getDTCFormatName(const std::string& formatStr) { - - for (const auto& format : dtcFormats) { - if (format.second == formatStr) { - return format.first; - } - } - - // Return the format string itself if no match found - return formatStr; - } - - int getCurrentFramePadding() { - if (isMiniMode) { - std::string value = ult::parseValueFromIniSection(configIniPath, "mini", "frame_padding"); - return value.empty() ? 10 : atoi(value.c_str()); - } - return 10; - } - - std::string getCurrentTextAlign() { - if (isMicroMode) { - std::string value = ult::parseValueFromIniSection(configIniPath, "micro", "text_align"); - convertToUpper(value); - if (value == "LEFT") return "Left"; - if (value == "RIGHT") return "Right"; - return "Center"; - } - return ""; - } - - std::string getCurrentLayerPosRight() { - std::string section; - if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - std::string value = ult::parseValueFromIniSection(configIniPath, section, "layer_width_align"); - convertToUpper(value); - - if (isFullMode) { - // Full mode: only Left and Right allowed - if (value == "RIGHT") return "Right"; - return "Left"; - } else { - // Other modes: allow Center - if (value == "RIGHT") return "Right"; - if (value == "CENTER") return "Center"; - return "Left"; - } - } - - std::string getCurrentLayerPosBottom() { - std::string section; - if (isMicroMode) section = "micro"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - std::string value = ult::parseValueFromIniSection(configIniPath, section, "layer_height_align"); - convertToUpper(value); - - if (isMicroMode) { - // Micro mode: only Top and Bottom allowed - if (value == "BOTTOM") return "Bottom"; - return "Top"; - } else { - // Other modes: allow Center - if (value == "BOTTOM") return "Bottom"; - if (value == "CENTER") return "Center"; - return "Top"; - } - } - - std::string cycleTextAlign() { - if (isMicroMode) { - const std::string current = getCurrentTextAlign(); - std::string next; - if (current == "Left") next = "Center"; - else if (current == "Center") next = "Right"; - else if (current == "Right") next = "Left"; - else next = "Center"; - - ult::setIniFileValue(configIniPath, "micro", "text_align", next); - return next; - } - return ""; - } - - std::string cycleLayerPosRight() { - std::string section; - if (isFullMode) section = "full"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - const std::string current = getCurrentLayerPosRight(); - std::string next; - - if (isFullMode) { - // Full mode: only Left and Right - if (current == "Left") next = "Right"; - else next = "Left"; - } else { - // Other modes: Left -> Center -> Right -> Left - if (current == "Left") next = "Center"; - else if (current == "Center") next = "Right"; - else next = "Left"; - } - - const std::string value = (next == "Right") ? "right" : (next == "Center" ? "center" : "left"); - ult::setIniFileValue(configIniPath, section, "layer_width_align", value); - return next; - } - - std::string cycleLayerPosBottom() { - std::string section; - if (isMicroMode) section = "micro"; - else if (isGameResolutionsMode) section = "game_resolutions"; - else if (isFPSCounterMode) section = "fps-counter"; - else if (isFPSGraphMode) section = "fps-graph"; - - const std::string current = getCurrentLayerPosBottom(); - std::string next; - - if (isMicroMode) { - // Micro mode: only Top and Bottom - if (current == "Top") next = "Bottom"; - else next = "Top"; - } else { - // Other modes: Top -> Center -> Bottom -> Top - if (current == "Top") next = "Center"; - else if (current == "Center") next = "Bottom"; - else next = "Top"; - } - - const std::string value = (next == "Bottom") ? "bottom" : (next == "Center" ? "center" : "top"); - ult::setIniFileValue(configIniPath, section, "layer_height_align", value); - return next; - } -}; diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Counter.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Counter.hpp deleted file mode 100644 index 56ee9ba6..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Counter.hpp +++ /dev/null @@ -1,525 +0,0 @@ -class MainMenu; - -class com_FPS : public tsl::Gui { -private: - char FPSavg_c[8]; - FpsCounterSettings settings; - size_t fontsize = 0; - ApmPerformanceMode performanceMode = ApmPerformanceMode_Invalid; - bool skipOnce = true; - bool runOnce = true; - - // Repositioning variables - int frameOffsetX = 0; - int frameOffsetY = 0; - bool isDragging = false; - size_t framePadding = 10; - static constexpr int screenWidth = 1280; - static constexpr int screenHeight = 720; - static constexpr int border = 8; - - bool originalUseRightAlignment = ult::useRightAlignment; - - struct ButtonState { - std::atomic minusDragActive{false}; - std::atomic plusDragActive{false}; - } buttonState; - - Thread touchPollThread; - std::atomic touchPollRunning{false}; - - // Store actual rendered dimensions - size_t actualTextWidth = 0; - size_t actualTotalWidth = 0; - size_t actualTotalHeight = 0; - -public: - com_FPS() { - tsl::hlp::requestForeground(false); - disableJumpTo = true; - GetConfigSettings(&settings); - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - fontsize = settings.handheldFontSize; - } - else if (performanceMode == ApmPerformanceMode_Boost) { - fontsize = settings.dockedFontSize; - } - - // Load saved frame offsets - frameOffsetX = settings.frameOffsetX; - frameOffsetY = settings.frameOffsetY; - framePadding = settings.framePadding; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - FullMode = false; - TeslaFPS = settings.refreshRate; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - deactivateOriginalFooter = true; - StartFPSCounterThread(); - - // Start touch polling thread for instant response at low FPS - touchPollRunning.store(true, std::memory_order_release); - threadCreate(&touchPollThread, [](void* arg) -> void { - com_FPS* overlay = static_cast(arg); - - // Allow only Player 1 and handheld mode - const HidNpadIdType id_list[2] = { HidNpadIdType_No1, HidNpadIdType_Handheld }; - - // Configure HID system to only listen to these IDs - hidSetSupportedNpadIdType(id_list, 2); - - // Configure input for up to 2 supported controllers (P1 + Handheld) - padConfigureInput(2, HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt); - - // Initialize separate pad states for both controllers - PadState pad_p1; - PadState pad_handheld; - padInitialize(&pad_p1, HidNpadIdType_No1); - padInitialize(&pad_handheld, HidNpadIdType_Handheld); - - u64 minusHoldStart = 0; - u64 plusHoldStart = 0; - static constexpr u64 HOLD_THRESHOLD_NS = 500'000'000ULL; - - HidTouchScreenState state = {0}; - bool inputDetected; - - while (overlay->touchPollRunning.load(std::memory_order_acquire)) { - // Only poll when rendering and not dragging - { - inputDetected = false; - - // Check touch in bounds - if (hidGetTouchScreenStates(&state, 1) && state.count > 0) { - const int touchX = state.touches[0].x; - const int touchY = state.touches[0].y; - - // Use actual dimensions, fallback to estimate if not yet rendered - size_t totalWidth = overlay->actualTotalWidth; - size_t totalHeight = overlay->actualTotalHeight; - - if (totalWidth == 0) { - // Fallback calculation - size_t approxFontSize = overlay->fontsize; - if (approxFontSize == 0) approxFontSize = 50; - const size_t textWidth = approxFontSize * 4; - const size_t margin = (approxFontSize / 8); - const size_t innerWidth = textWidth + margin; - const size_t innerHeight = approxFontSize; - totalWidth = innerWidth + (2 * border); - totalHeight = innerHeight + (2 * border); - } - - // Apply frame offsets - const int overlayX = overlay->frameOffsetX; - const int overlayY = overlay->frameOffsetY; - - // Touch padding - const int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = totalWidth + (touchPadding * 2); - const int touchableHeight = totalHeight + (touchPadding * 2); - - // Check if touch is within bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - inputDetected = true; - } - } - - // Poll buttons from both controllers - padUpdate(&pad_p1); - padUpdate(&pad_handheld); - - // Combine input from both controllers - const u64 keysHeld = padGetButtons(&pad_p1) | padGetButtons(&pad_handheld); - const u64 now = armTicksToNs(armGetSystemTick()); - - // Track MINUS hold duration - if ((keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK)) { - if (minusHoldStart == 0) { - minusHoldStart = now; - } - if (now - minusHoldStart >= HOLD_THRESHOLD_NS) { - inputDetected = true; - overlay->buttonState.minusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - // Track PLUS hold duration - else if ((keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK)) { - if (plusHoldStart == 0) { - plusHoldStart = now; - } - if (now - plusHoldStart >= HOLD_THRESHOLD_NS) { - inputDetected = true; - overlay->buttonState.plusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - else { - minusHoldStart = plusHoldStart = 0; - overlay->buttonState.minusDragActive.exchange(false, std::memory_order_acq_rel); - overlay->buttonState.plusDragActive.exchange(false, std::memory_order_acq_rel); - } - - // Disable rendering on any input, re-enable when no input - static bool resetOnce = true; - if (inputDetected) { - if (resetOnce && isRendering) { - isRendering = false; - leventSignal(&renderingStopEvent); - resetOnce = false; - } - } else { - resetOnce = true; - } - } - - if (ult::limitedMemory) { - static auto lastUnderscanPixels = std::make_pair(0, 0); - - if (lastUnderscanPixels != tsl::impl::currentUnderscanPixels) { - for (int i = 0; i < 2; i++) { - tsl::gfx::Renderer::get().updateLayerSize(); - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(overlay->frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - lastUnderscanPixels = tsl::impl::currentUnderscanPixels; - } - - svcSleepThread(16000000ULL*2); // 16ms polling - } - }, this, NULL, 0x1000, 0x2B, -2); - threadStart(&touchPollThread); - } - - ~com_FPS() { - // Stop touch polling thread - touchPollRunning.store(false, std::memory_order_release); - threadWaitForExit(&touchPollThread); - threadClose(&touchPollThread); - - TeslaFPS = 60; - EndFPSCounterThread(); - FullMode = true; - fixForeground = true; - ult::useRightAlignment = originalUseRightAlignment; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().addScreenshotStacks(); - } - deactivateOriginalFooter = false; - } - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - // Calculate text dimensions - const auto [textWidth, textHeight] = renderer->getTextDimensions( - (FPSavg != 254.0) ? FPSavg_c : "--", false, fontsize - ); - - const size_t margin = (fontsize / 8); - - // Inner rectangle dimensions (content area) - const size_t innerWidth = textWidth + margin; - const size_t innerHeight = textHeight; - - // Total dimensions including border - const size_t totalWidth = innerWidth + (2 * border); - const size_t totalHeight = innerHeight + (2 * border); - - // Store actual dimensions for input handling - actualTextWidth = textWidth; - actualTotalWidth = totalWidth; - actualTotalHeight = totalHeight; - - // Calculate position with frame offsets - //int posX = frameOffsetX; - //int posY = frameOffsetY; - - int _frameOffsetX = ult::limitedMemory ? std::max(0, frameOffsetX - (1280-448)) : frameOffsetX; - - // Clamp to screen bounds (accounting for total size including border) - const int posX = std::max(int(framePadding), std::min(_frameOffsetX, static_cast(screenWidth - totalWidth - framePadding))); - const int posY = std::max(int(framePadding), std::min(frameOffsetY, static_cast(screenHeight - totalHeight - framePadding))); - - // Draw the rounded rectangle (background) - const tsl::Color bgColor = !isDragging - ? settings.backgroundColor - : settings.focusBackgroundColor; - - renderer->drawRoundedRectSingleThreaded( - posX, - posY, - totalWidth, - totalHeight, - 16, - aWithOpacity(bgColor) - ); - - // Calculate centered text position within the bordered area - const int textX = posX + border + (margin / 2); - const int textY = posY + border + (fontsize - margin); - - // Draw the text - renderer->drawString( - (FPSavg != 254.0) ? FPSavg_c : "--", - false, - textX, - textY, - fontsize, - settings.textColor - ); - }); - - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("", ""); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - fontsize = settings.handheldFontSize; - } - else if (performanceMode == ApmPerformanceMode_Boost) { - fontsize = settings.dockedFontSize; - } - if (settings.useIntegerCounter) { - snprintf(FPSavg_c, sizeof FPSavg_c, "%d", (int)round(useOldFPSavg ? FPSavg_old : FPSavg)); - } else { - snprintf(FPSavg_c, sizeof FPSavg_c, "%2.1f", useOldFPSavg ? FPSavg_old : FPSavg); - } - - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - // Static variables to maintain drag state between function calls - static bool oldTouchDetected = false; - static bool oldMinusHeld = false; - static bool oldPlusHeld = false; - static HidTouchState initialTouchPos = {0}; - static int initialFrameOffsetX = 0; - static int initialFrameOffsetY = 0; - static constexpr int TOUCH_THRESHOLD = 8; - static bool hasMoved = false; - - // Touch detection - const bool currentTouchDetected = (touchPos.x > 0 && touchPos.y > 0 && - touchPos.x < screenWidth && touchPos.y < screenHeight); - - static bool clearOnRelease = false; - - if (clearOnRelease && !isRendering) { - clearOnRelease = false; - isRendering = true; - leventClear(&renderingStopEvent); - } - - // Use actual dimensions from last render, fallback to estimate if not available - size_t totalWidth = actualTotalWidth; - size_t totalHeight = actualTotalHeight; - - if (totalWidth == 0) { - // Fallback calculation if not yet rendered - const size_t textWidth = fontsize * 4; - const size_t margin = (fontsize / 8); - const size_t innerWidth = textWidth + margin; - const size_t innerHeight = fontsize + (margin / 2); - totalWidth = innerWidth + (2 * border); - totalHeight = innerHeight + (2 * border); - } - - // Current overlay position - const int overlayX = frameOffsetX; - const int overlayY = frameOffsetY; - - // Touch detection area (with padding for easier interaction) - static constexpr int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = totalWidth + (touchPadding * 2); - const int touchableHeight = totalHeight + (touchPadding * 2); - - // Screen boundaries for clamping (accounting for total size) - const int minX = framePadding; - const int maxX = screenWidth - totalWidth - framePadding; - const int minY = framePadding; - const int maxY = screenHeight - totalHeight - framePadding; - - const bool minusDragReady = buttonState.minusDragActive.load(std::memory_order_acquire); - const bool plusDragReady = buttonState.plusDragActive.load(std::memory_order_acquire); - - // Check button states - const bool currentMinusHeld = (keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK) && minusDragReady; - const bool currentPlusHeld = (keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK) && plusDragReady; - - // Handle touch dragging - if (currentTouchDetected && !isDragging) { - const int touchX = touchPos.x; - const int touchY = touchPos.y; - - if (!oldTouchDetected) { - // Touch just started - check if within overlay bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - - // Start touch dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - hasMoved = false; - initialTouchPos = touchPos; - initialFrameOffsetX = frameOffsetX; - initialFrameOffsetY = frameOffsetY; - } - } - } else if (currentTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Continue touch dragging - const int touchX = touchPos.x; - const int touchY = touchPos.y; - const int deltaX = touchX - initialTouchPos.x; - const int deltaY = touchY - initialTouchPos.y; - - // Check if we've moved enough to consider this a drag - if (!hasMoved) { - const int totalMovement = abs(deltaX) + abs(deltaY); - if (totalMovement >= TOUCH_THRESHOLD) { - hasMoved = true; - } - } - - if (hasMoved) { - // Update frame offsets with boundary checking - frameOffsetX = std::max(minX, std::min(maxX, initialFrameOffsetX + deltaX)); - frameOffsetY = std::max(minY, std::min(maxY, initialFrameOffsetY + deltaY)); - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - } else if (!currentTouchDetected && oldTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Touch just released - if (hasMoved) { - // Save position when touch drag ends - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["fps-counter"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["fps-counter"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - } - - // Reset touch drag state - isDragging = false; - hasMoved = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Handle joystick dragging (MINUS + right joystick OR PLUS + left joystick) - if ((currentMinusHeld || currentPlusHeld) && !isDragging) { - // Start joystick dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - } else if ((currentMinusHeld || currentPlusHeld) && isDragging) { - // Continue joystick dragging - static constexpr int JOYSTICK_DEADZONE = 20; - - // Choose the appropriate joystick based on which button is held - const HidAnalogStickState& activeJoystick = currentMinusHeld ? joyStickPosRight : joyStickPosLeft; - - // Only move if joystick is outside deadzone - if (abs(activeJoystick.x) > JOYSTICK_DEADZONE || abs(activeJoystick.y) > JOYSTICK_DEADZONE) { - // Calculate joystick magnitude - const float magnitude = sqrt((float)(activeJoystick.x * activeJoystick.x + activeJoystick.y * activeJoystick.y)); - const float normalizedMagnitude = magnitude / 32767.0f; - - // Smooth curve for sensitivity - static constexpr float baseSensitivity = 0.00008f; - static constexpr float maxSensitivity = 0.0005f; - - const float curveValue = pow(normalizedMagnitude, 8.0f); - const float currentSensitivity = baseSensitivity + (maxSensitivity - baseSensitivity) * curveValue; - - // Calculate movement delta with fractional accumulation - static float accumulatedX = 0.0f; - static float accumulatedY = 0.0f; - - accumulatedX += (float)activeJoystick.x * currentSensitivity; - accumulatedY += -(float)activeJoystick.y * currentSensitivity; - - const int deltaX = (int)accumulatedX; - const int deltaY = (int)accumulatedY; - accumulatedX -= deltaX; - accumulatedY -= deltaY; - - // Update frame offsets with boundary checking - frameOffsetX = std::max(minX, std::min(maxX, frameOffsetX + deltaX)); - frameOffsetY = std::max(minY, std::min(maxY, frameOffsetY + deltaY)); - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - } else if (((!currentMinusHeld && oldMinusHeld) || (!currentPlusHeld && oldPlusHeld)) && isDragging) { - // Button just released - stop joystick dragging - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["fps-counter"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["fps-counter"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - isDragging = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Update state for next frame - oldTouchDetected = currentTouchDetected; - oldMinusHeld = currentMinusHeld; - oldPlusHeld = currentPlusHeld; - - // Handle existing key input logic (but don't interfere with dragging) - if (!isDragging) { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - runOnce = true; - skipOnce = true; - TeslaFPS = 60; - lastSelectedItem = "FPS Counter"; - lastMode = ""; - if (skipMain) { - lastMode = "return"; - tsl::goBack(); - } - else { - tsl::setNextOverlay(filepath.c_str(), "--lastSelectedItem 'FPS Counter'"); - tsl::Overlay::get()->close(); - } - return true; - } - } - - // Return true if we handled the input (during dragging) - return isDragging; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Graph.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Graph.hpp deleted file mode 100644 index aa90a055..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/FPS_Graph.hpp +++ /dev/null @@ -1,757 +0,0 @@ -class MainMenu; - -class com_FPSGraph : public tsl::Gui { -private: - uint8_t refreshRate = 0; - char FPSavg_c[8]; - FpsGraphSettings settings; - uint64_t systemtickfrequency_impl = systemtickfrequency; - uint32_t cnt = 0; - char CPU_Load_c[12] = " -"; - char GPU_Load_c[12] = " -"; - char RAM_Load_c[12] = " -"; - char SOC_TEMP_c[12] = " -"; - char PCB_TEMP_c[12] = " -"; - char SKIN_TEMP_c[12] = " -"; - char CPU_TEMP_c[12] = " -"; - char GPU_TEMP_c[12] = " -"; - char RAM_TEMP_c[12] = " -"; - bool skipOnce = true; - bool runOnce = true; - - // Repositioning variables (matching Mini) - int frameOffsetX = 0; - int frameOffsetY = 0; - bool isDragging = false; - size_t framePadding = 10; - static constexpr int screenWidth = 1280; - static constexpr int screenHeight = 720; - static constexpr int border = 8; - - bool originalUseRightAlignment = ult::useRightAlignment; - - struct ButtonState { - std::atomic minusDragActive{false}; - std::atomic plusDragActive{false}; - } buttonState; - - Thread touchPollThread; - std::atomic touchPollRunning{false}; - - // Store actual rendered dimensions (including border) - size_t actualTotalWidth = 0; - size_t actualTotalHeight = 0; - -public: - bool isStarted = false; - com_FPSGraph() { - tsl::hlp::requestForeground(false); - disableJumpTo = true; - GetConfigSettings(&settings); - - if (R_SUCCEEDED(SaltySD_Connect())) { - if (R_FAILED(SaltySD_GetDisplayRefreshRate(&refreshRate))) - refreshRate = 0; - svcSleepThread(100'000); - SaltySD_Term(); - } - - // Load saved frame offsets - frameOffsetX = settings.frameOffsetX; - frameOffsetY = settings.frameOffsetY; - framePadding = settings.framePadding; - - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - FullMode = false; - TeslaFPS = settings.refreshRate; - systemtickfrequency_impl /= settings.refreshRate; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - deactivateOriginalFooter = true; - mutexInit(&mutex_Misc); - StartInfoThread(); - StartFPSCounterThread(); - - // Start touch polling thread for instant response at low FPS - touchPollRunning.store(true, std::memory_order_release); - threadCreate(&touchPollThread, [](void* arg) -> void { - com_FPSGraph* overlay = static_cast(arg); - - // Allow only Player 1 and handheld mode - const HidNpadIdType id_list[2] = { HidNpadIdType_No1, HidNpadIdType_Handheld }; - - // Configure HID system to only listen to these IDs - hidSetSupportedNpadIdType(id_list, 2); - - // Configure input for up to 2 supported controllers (P1 + Handheld) - padConfigureInput(2, HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt); - - // Initialize separate pad states for both controllers - PadState pad_p1; - PadState pad_handheld; - padInitialize(&pad_p1, HidNpadIdType_No1); - padInitialize(&pad_handheld, HidNpadIdType_Handheld); - - u64 minusHoldStart = 0; - u64 plusHoldStart = 0; - static constexpr u64 HOLD_THRESHOLD_NS = 500'000'000ULL; - - HidTouchScreenState state = {0}; - bool inputDetected; - - while (overlay->touchPollRunning.load(std::memory_order_acquire)) { - // Only poll when rendering and not dragging - { - inputDetected = false; - - // Check touch in bounds - if (hidGetTouchScreenStates(&state, 1) && state.count > 0) { - const int touchX = state.touches[0].x; - const int touchY = state.touches[0].y; - - // Use actual dimensions, fallback to estimate if not yet rendered - size_t totalWidth = overlay->actualTotalWidth; - size_t totalHeight = overlay->actualTotalHeight; - - if (totalWidth == 0) { - // Fallback calculation - const s16 refresh_rate_offset = (overlay->refreshRate < 100) ? 21 : 28; - const s16 info_width = overlay->settings.showInfo ? (6 + overlay->rectangle_width/2 - 4) : 0; - const s16 content_width = overlay->rectangle_width + refresh_rate_offset + info_width; - const s16 content_height = overlay->rectangle_height + 12; - totalWidth = content_width + (2 * border); - totalHeight = content_height + (2 * border); - } - - // Apply frame offsets (base position already includes border offset) - const int overlayX = overlay->base_x + overlay->frameOffsetX - border; - const int overlayY = overlay->base_y + overlay->frameOffsetY - border; - - // Touch padding - const int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = totalWidth + (touchPadding * 2); - const int touchableHeight = totalHeight + (touchPadding * 2); - - // Check if touch is within bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - inputDetected = true; - } - } - - // Poll buttons from both controllers - padUpdate(&pad_p1); - padUpdate(&pad_handheld); - - // Combine input from both controllers - const u64 keysHeld = padGetButtons(&pad_p1) | padGetButtons(&pad_handheld); - const u64 now = armTicksToNs(armGetSystemTick()); - - // Track MINUS hold duration - if ((keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK)) { - if (minusHoldStart == 0) { - minusHoldStart = now; - } - if (now - minusHoldStart >= HOLD_THRESHOLD_NS) { - inputDetected = true; - overlay->buttonState.minusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - // Track PLUS hold duration - else if ((keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK)) { - if (plusHoldStart == 0) { - plusHoldStart = now; - } - if (now - plusHoldStart >= HOLD_THRESHOLD_NS) { - inputDetected = true; - overlay->buttonState.plusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - else { - minusHoldStart = plusHoldStart = 0; - overlay->buttonState.minusDragActive.exchange(false, std::memory_order_acq_rel); - overlay->buttonState.plusDragActive.exchange(false, std::memory_order_acq_rel); - } - - // Disable rendering on any input, re-enable when no input - static bool resetOnce = true; - if (inputDetected) { - if (resetOnce && isRendering) { - isRendering = false; - leventSignal(&renderingStopEvent); - resetOnce = false; - } - } else { - resetOnce = true; - } - } - - if (ult::limitedMemory) { - static auto lastUnderscanPixels = std::make_pair(0, 0); - - if (lastUnderscanPixels != tsl::impl::currentUnderscanPixels) { - for (int i = 0; i < 2; i++) { - tsl::gfx::Renderer::get().updateLayerSize(); - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(overlay->frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - lastUnderscanPixels = tsl::impl::currentUnderscanPixels; - } - - svcSleepThread(16000000ULL*2); // 16ms polling - } - }, this, NULL, 0x1000, 0x2B, -2); - threadStart(&touchPollThread); - } - - ~com_FPSGraph() { - // Stop touch polling thread - touchPollRunning.store(false, std::memory_order_release); - threadWaitForExit(&touchPollThread); - threadClose(&touchPollThread); - - EndInfoThread(); - EndFPSCounterThread(); - FullMode = true; - fixForeground = true; - ult::useRightAlignment = originalUseRightAlignment; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().addScreenshotStacks(); - } - deactivateOriginalFooter = false; - } - - struct stats { - s16 value; - bool zero_rounded; - }; - - std::vector readings; - - s16 base_y = 0; - s16 base_x = 0; - s16 rectangle_width = 180; - s16 rectangle_height = 60; - s16 rectangle_x = 15; - s16 rectangle_y = 5; - s16 rectangle_range_max = 60; - s16 rectangle_range_min = 0; - char legend_max[4] = "60"; - char legend_min[2] = "0"; - s32 range = std::abs(rectangle_range_max - rectangle_range_min) + 1; - s16 x_end = rectangle_x + rectangle_width; - s16 y_old = rectangle_y+rectangle_height; - s16 y_30FPS = rectangle_y+(rectangle_height / 2); - s16 y_60FPS = rectangle_y; - bool isAbove = false; - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - - // Calculate content dimensions (what goes inside the border) - const s16 refresh_rate_offset = (refreshRate < 100) ? 21 : 28; - const s16 info_width = settings.showInfo ? (6 + rectangle_width/2 - 4) : 6; - const s16 content_width = rectangle_width + refresh_rate_offset + info_width; - const s16 content_height = rectangle_height + 12; - - // Total dimensions including border - const size_t totalWidth = content_width + (2 * border); - const size_t totalHeight = content_height + (2 * border); - - // Store actual dimensions for input handling - actualTotalWidth = totalWidth; - actualTotalHeight = totalHeight; - - if (refreshRate && refreshRate < 240) { - rectangle_height = refreshRate; - rectangle_range_max = refreshRate; - if (refreshRate < 100) { - rectangle_x = 15; - legend_max[0] = 0x30 + (refreshRate / 10); - legend_max[1] = 0x30 + (refreshRate % 10); - legend_max[2] = 0; - } - else { - rectangle_x = 22; - legend_max[0] = 0x30 + (refreshRate / 100); - legend_max[1] = 0x30 + ((refreshRate / 10) % 10); - legend_max[2] = 0x30 + (refreshRate % 10); - } - y_30FPS = rectangle_y+(rectangle_height / 2); - range = std::abs(rectangle_range_max - rectangle_range_min) + 1; - }; - - int _frameOffsetX = ult::limitedMemory ? std::max(0, frameOffsetX - (1280-448)) : frameOffsetX; - - // Calculate position with frame offsets (for the rounded rect, which includes border) - int posX = base_x + _frameOffsetX - border; - int posY = base_y + frameOffsetY - border; - - // Clamp to screen bounds (accounting for total size including border) - posX = std::max(int(framePadding), std::min(posX, static_cast(screenWidth - totalWidth - framePadding))); - posY = std::max(int(framePadding), std::min(posY, static_cast(screenHeight - totalHeight - framePadding))); - - // Draw the rounded rectangle (background) - const tsl::Color bgColor = !isDragging - ? settings.backgroundColor - : settings.focusBackgroundColor; - - renderer->drawRoundedRectSingleThreaded( - posX, - posY, - totalWidth, - totalHeight, - 16, - aWithOpacity(bgColor) - ); - - posX += 4; - - // Content drawing position (inside the border) - const int final_base_x = posX + border; - const int final_base_y = posY + border; - - const s16 size = (refreshRate > 60 || !refreshRate) ? 63 : (s32)(63.0/(60.0/refreshRate)); - const auto width = renderer->getTextDimensions(FPSavg_c, false, size).first; - - const s16 pos_y = size + final_base_y + rectangle_y + ((rectangle_height - size) / 2); - const s16 pos_x = final_base_x + rectangle_x + ((rectangle_width - width) / 2); - - if (FPSavg != 254.0) - renderer->drawString(FPSavg_c, false, pos_x, pos_y-5, size, settings.fpsColor); - renderer->drawEmptyRect(final_base_x+(rectangle_x - 1)+2, final_base_y+(rectangle_y - 1), rectangle_width + 2, rectangle_height + 4, aWithOpacity(settings.borderColor)); - renderer->drawDashedLine(final_base_x+rectangle_x+2, final_base_y+y_30FPS, final_base_x+rectangle_x+rectangle_width, final_base_y+y_30FPS, 6, aWithOpacity(settings.dashedLineColor)); - renderer->drawString(&legend_max[0], false, final_base_x+(rectangle_x-((refreshRate < 100) ? 15 : 22)), final_base_y+(rectangle_y+7), 10, (settings.maxFPSTextColor)); - renderer->drawString(&legend_min[0], false, final_base_x+(rectangle_x-10), final_base_y+(rectangle_y+rectangle_height+3), 10, settings.minFPSTextColor); - - size_t last_element = readings.size() - 1; - - s16 offset = 0; - if (refreshRate >= 100) offset = 7; - - static s32 y_on_range; - static tsl::Color color = {0}; - for (s16 x = x_end; x > static_cast(x_end-readings.size()); x--) { - y_on_range = readings[last_element].value + std::abs(rectangle_range_min) + 1; - if (y_on_range < 0) { - y_on_range = 0; - } - else if (y_on_range > range) { - isAbove = true; - y_on_range = range; - } - - const s16 y = rectangle_y + static_cast(std::lround((float)rectangle_height * ((float)(range - y_on_range) / (float)range))); - color = (settings.mainLineColor); - if (y == y_old && !isAbove && readings[last_element].zero_rounded) { - if ((y == y_30FPS || y == y_60FPS)) - color = (settings.perfectLineColor); - else - color = (settings.dashedLineColor); - } - - if (x == x_end) { - y_old = y; - } - - renderer->drawLine(final_base_x+x+offset, final_base_y+y, final_base_x+x+offset, final_base_y+y_old, color); - isAbove = false; - y_old = y; - last_element--; - } - - if (settings.showInfo) { - const s16 info_x = final_base_x+rectangle_width+rectangle_x + 6 +8; - const s16 info_y = final_base_y + 3; - const s16 fontSize = 11; - - // Get line height from font size (we'll use the actual rendered height) - const auto testDimensions = renderer->getTextDimensions("A", false, fontSize); - const s16 lineHeight = testDimensions.second; - - // Starting Y position for first line - const s16 startY = info_y + lineHeight; - - // Value X position (offset from labels) - const s16 value_x = info_x + 40; - - static constexpr s16 SPACING = 1; - - // Compute gradient colors for temperatures - const tsl::Color socColor = settings.useDynamicColors ? tsl::GradientColor(SOC_temperatureF) : settings.textColor; - const tsl::Color pcbColor = settings.useDynamicColors ? tsl::GradientColor(PCB_temperatureF) : settings.textColor; - const tsl::Color skinColor = settings.useDynamicColors ? tsl::GradientColor(static_cast(skin_temperaturemiliC) / 1000.0f) : settings.textColor; - - // Draw each label and value pair on the same baseline - // Line 0: CPU - renderer->drawString("CPU", false, info_x, startY, fontSize, settings.catColor); - renderer->drawString(CPU_Load_c, false, value_x, startY, fontSize, settings.textColor); - - // Line 1: GPU - renderer->drawString("GPU", false, info_x, startY + lineHeight+SPACING, fontSize, settings.catColor); - renderer->drawString(GPU_Load_c, false, value_x, startY + lineHeight+SPACING, fontSize, settings.textColor); - - // Line 2: RAM - renderer->drawString("RAM", false, info_x, startY + lineHeight * 2+2*SPACING, fontSize, settings.catColor); - renderer->drawString(RAM_Load_c, false, value_x, startY + lineHeight * 2+2*SPACING, fontSize, settings.textColor); - - // Line 3: CPU or SOC (with gradient color) - if (settings.realTemps && realCPU_Temp != 0) { - const tsl::Color cpuTempColor = settings.useDynamicColors ? tsl::GradientColor(realCPU_Temp / 1000.0f) : settings.textColor; - renderer->drawString("CPU", false, info_x, startY + lineHeight * 3+3*SPACING, fontSize, settings.catColor); - renderer->drawString(CPU_TEMP_c, false, value_x, startY + lineHeight * 3+3*SPACING, fontSize, cpuTempColor); - } else { - renderer->drawString("SOC", false, info_x, startY + lineHeight * 3+3*SPACING, fontSize, settings.catColor); - renderer->drawString(SOC_TEMP_c, false, value_x, startY + lineHeight * 3+3*SPACING, fontSize, socColor); - } - - // Line 4: GPU or PCB (with gradient color) - if (settings.realTemps && realGPU_Temp != 0) { - const tsl::Color gpuTempColor = settings.useDynamicColors ? tsl::GradientColor(realGPU_Temp / 1000.0f) : settings.textColor; - renderer->drawString("GPU", false, info_x, startY + lineHeight * 4+4*SPACING, fontSize, settings.catColor); - renderer->drawString(GPU_TEMP_c, false, value_x, startY + lineHeight * 4+4*SPACING, fontSize, gpuTempColor); - } else { - renderer->drawString("PCB", false, info_x, startY + lineHeight * 4+4*SPACING, fontSize, settings.catColor); - renderer->drawString(PCB_TEMP_c, false, value_x, startY + lineHeight * 4+4*SPACING, fontSize, pcbColor); - } - - // Line 5: RAM or SKIN (with gradient color) - if (settings.realTemps && realRAM_Temp != 0) { - const tsl::Color ramTempColor = settings.useDynamicColors ? tsl::GradientColor(realRAM_Temp / 1000.0f) : settings.textColor; - renderer->drawString("RAM", false, info_x, startY + lineHeight * 5+5*SPACING, fontSize, settings.catColor); - renderer->drawString(RAM_TEMP_c, false, value_x, startY + lineHeight * 5+5*SPACING, fontSize, ramTempColor); - } else { - renderer->drawString("Skin", false, info_x, startY + lineHeight * 5+5*SPACING, fontSize, settings.catColor); - renderer->drawString(SKIN_TEMP_c, false, value_x, startY + lineHeight * 5+5*SPACING, fontSize, skinColor); - } - } - }); - - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("", ""); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - cnt++; - if (cnt >= TeslaFPS) - cnt = 0; - - ///FPS - stats temp = {0, false}; - static uint64_t lastFrame = 0; - - snprintf(FPSavg_c, sizeof FPSavg_c, "%2.1f", FPSavg); - const uint8_t SaltySharedDisplayRefreshRate = *(uint8_t*)((uintptr_t)shmemGetAddr(&_sharedmemory) + 1); - if (SaltySharedDisplayRefreshRate) - refreshRate = SaltySharedDisplayRefreshRate; - else refreshRate = 60; - if (FPSavg < 254) { - snprintf(FPSavg_c, sizeof(FPSavg_c), "%.1f", useOldFPSavg ? FPSavg_old : FPSavg); - - if (lastFrame == lastFrameNumber) return; - else lastFrame = lastFrameNumber; - if ((s16)(readings.size()) >= rectangle_width) { - readings.erase(readings.begin()); - } - const float whole = std::round(useOldFPSavg ? FPSavg_old : FPSavg); - temp.value = static_cast(std::lround(useOldFPSavg ? FPSavg_old : FPSavg)); - if ((useOldFPSavg ? FPSavg_old : FPSavg) < whole+0.04 && (useOldFPSavg ? FPSavg_old : FPSavg) > whole-0.05) { - temp.zero_rounded = true; - } - readings.push_back(temp); - } - else { - if (readings.size()) { - readings.clear(); - readings.shrink_to_fit(); - lastFrame = 0; - } - FPSavg_c[0] = 0; - } - - if (cnt) - return; - - mutexLock(&mutex_Misc); - - // Format temperature strings separately for proper alignment - snprintf(SOC_TEMP_c, sizeof SOC_TEMP_c, "%2.1f\u00B0C", SOC_temperatureF); - snprintf(PCB_TEMP_c, sizeof PCB_TEMP_c, "%2.1f\u00B0C", PCB_temperatureF); - snprintf(SKIN_TEMP_c, sizeof SKIN_TEMP_c, "%2d.%d\u00B0C", - skin_temperaturemiliC / 1000, (skin_temperaturemiliC / 100) % 10); - - if (realCPU_Temp != 0) { - snprintf(CPU_TEMP_c, sizeof(CPU_TEMP_c), "%.1f\u00B0C", realCPU_Temp / 1000.0f); - } - if (realGPU_Temp != 0) { - snprintf(GPU_TEMP_c, sizeof(GPU_TEMP_c), "%.1f\u00B0C", realGPU_Temp / 1000.0f); - } - if (realRAM_Temp != 0) { - snprintf(RAM_TEMP_c, sizeof(RAM_TEMP_c), "%.1f\u00B0C", realRAM_Temp / 1000.0f); - } - - // Atomically snapshot each idle tick once - const uint64_t idle0 = idletick0.load(std::memory_order_acquire); - const uint64_t idle1 = idletick1.load(std::memory_order_acquire); - const uint64_t idle2 = idletick2.load(std::memory_order_acquire); - const uint64_t idle3 = idletick3.load(std::memory_order_acquire); - - // Clamp values to systemtickfrequency_impl (avoid div-by-zero / runaway) - const uint64_t safe0 = std::min(idle0, systemtickfrequency_impl); - const uint64_t safe1 = std::min(idle1, systemtickfrequency_impl); - const uint64_t safe2 = std::min(idle2, systemtickfrequency_impl); - const uint64_t safe3 = std::min(idle3, systemtickfrequency_impl); - - // Compute per-core CPU usage - const double cpu_usage0 = (1.0 - (static_cast(safe0) / systemtickfrequency_impl)) * 100.0; - const double cpu_usage1 = (1.0 - (static_cast(safe1) / systemtickfrequency_impl)) * 100.0; - const double cpu_usage2 = (1.0 - (static_cast(safe2) / systemtickfrequency_impl)) * 100.0; - const double cpu_usage3 = (1.0 - (static_cast(safe3) / systemtickfrequency_impl)) * 100.0; - - // Compute max core load (the highest usage) - const double cpu_usageM = std::max({cpu_usage0, cpu_usage1, cpu_usage2, cpu_usage3}); - - // Format output strings - snprintf(CPU_Load_c, sizeof(CPU_Load_c), "%.1f%%", cpu_usageM); - snprintf(GPU_Load_c, sizeof(GPU_Load_c), "%d.%d%%", GPU_Load_u / 10, GPU_Load_u % 10); - snprintf(RAM_Load_c, sizeof(RAM_Load_c), "%hu.%hhu%%", - partLoad[HocClkPartLoad_EMC] / 10, - partLoad[HocClkPartLoad_EMC] % 10); - - mutexUnlock(&mutex_Misc); - - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - // Static variables to maintain drag state between function calls - static bool oldTouchDetected = false; - static bool oldMinusHeld = false; - static bool oldPlusHeld = false; - static HidTouchState initialTouchPos = {0}; - static int initialFrameOffsetX = 0; - static int initialFrameOffsetY = 0; - static constexpr int TOUCH_THRESHOLD = 8; - static bool hasMoved = false; - - // Touch detection - const bool currentTouchDetected = (touchPos.x > 0 && touchPos.y > 0 && - touchPos.x < screenWidth && touchPos.y < screenHeight); - - static bool clearOnRelease = false; - - if (clearOnRelease && !isRendering) { - clearOnRelease = false; - isRendering = true; - leventClear(&renderingStopEvent); - } - - // Use actual dimensions from last render, fallback to estimate if not available - size_t totalWidth = actualTotalWidth; - size_t totalHeight = actualTotalHeight; - - if (totalWidth == 0) { - // Fallback calculation if not yet rendered - const s16 refresh_rate_offset = (refreshRate < 100) ? 21 : 28; - const s16 info_width = settings.showInfo ? (6 + rectangle_width/2 - 4) : 0; - const s16 content_width = rectangle_width + refresh_rate_offset + info_width; - const s16 content_height = rectangle_height + 12; - totalWidth = content_width + (2 * border); - totalHeight = content_height + (2 * border); - } - - // Current overlay position (top-left of rounded rect) - const int overlayX = base_x + frameOffsetX - border; - const int overlayY = base_y + frameOffsetY - border; - - // Touch detection area (with padding for easier interaction) - static constexpr int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = totalWidth + (touchPadding * 2); - const int touchableHeight = totalHeight + (touchPadding * 2); - - // Screen boundaries for clamping (accounting for total size) - const int minX = -(base_x - border) + framePadding; - const int maxX = screenWidth - totalWidth - (base_x - border) - framePadding; - const int minY = -(base_y - border) + framePadding; - const int maxY = screenHeight - totalHeight - (base_y - border) - framePadding; - - const bool minusDragReady = buttonState.minusDragActive.load(std::memory_order_acquire); - const bool plusDragReady = buttonState.plusDragActive.load(std::memory_order_acquire); - - // Check button states - const bool currentMinusHeld = (keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK) && minusDragReady; - const bool currentPlusHeld = (keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK) && plusDragReady; - - // Handle touch dragging - if (currentTouchDetected && !isDragging) { - const int touchX = touchPos.x; - const int touchY = touchPos.y; - - if (!oldTouchDetected) { - // Touch just started - check if within overlay bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - - // Start touch dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - hasMoved = false; - initialTouchPos = touchPos; - initialFrameOffsetX = frameOffsetX; - initialFrameOffsetY = frameOffsetY; - } - } - } else if (currentTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Continue touch dragging - const int touchX = touchPos.x; - const int touchY = touchPos.y; - const int deltaX = touchX - initialTouchPos.x; - const int deltaY = touchY - initialTouchPos.y; - - // Check if we've moved enough to consider this a drag - if (!hasMoved) { - const int totalMovement = abs(deltaX) + abs(deltaY); - if (totalMovement >= TOUCH_THRESHOLD) { - hasMoved = true; - } - } - - if (hasMoved) { - // Update frame offsets with boundary checking - frameOffsetX = std::max(minX, std::min(maxX, initialFrameOffsetX + deltaX)); - frameOffsetY = std::max(minY, std::min(maxY, initialFrameOffsetY + deltaY)); - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - } else if (!currentTouchDetected && oldTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Touch just released - if (hasMoved) { - // Save position when touch drag ends - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["fps-graph"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["fps-graph"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - } - - // Reset touch drag state - isDragging = false; - hasMoved = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Handle joystick dragging (MINUS + right joystick OR PLUS + left joystick) - if ((currentMinusHeld || currentPlusHeld) && !isDragging) { - // Start joystick dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - } else if ((currentMinusHeld || currentPlusHeld) && isDragging) { - // Continue joystick dragging - static constexpr int JOYSTICK_DEADZONE = 20; - - // Choose the appropriate joystick based on which button is held - const HidAnalogStickState& activeJoystick = currentMinusHeld ? joyStickPosRight : joyStickPosLeft; - - // Only move if joystick is outside deadzone - if (abs(activeJoystick.x) > JOYSTICK_DEADZONE || abs(activeJoystick.y) > JOYSTICK_DEADZONE) { - // Calculate joystick magnitude - const float magnitude = sqrt((float)(activeJoystick.x * activeJoystick.x + activeJoystick.y * activeJoystick.y)); - const float normalizedMagnitude = magnitude / 32767.0f; - - // Smooth curve for sensitivity - static constexpr float baseSensitivity = 0.00008f; - static constexpr float maxSensitivity = 0.0005f; - - const float curveValue = pow(normalizedMagnitude, 8.0f); - const float currentSensitivity = baseSensitivity + (maxSensitivity - baseSensitivity) * curveValue; - - // Calculate movement delta with fractional accumulation - static float accumulatedX = 0.0f; - static float accumulatedY = 0.0f; - - accumulatedX += (float)activeJoystick.x * currentSensitivity; - accumulatedY += -(float)activeJoystick.y * currentSensitivity; - - const int deltaX = (int)accumulatedX; - const int deltaY = (int)accumulatedY; - accumulatedX -= deltaX; - accumulatedY -= deltaY; - - // Update frame offsets with boundary checking - frameOffsetX = std::max(minX, std::min(maxX, frameOffsetX + deltaX)); - frameOffsetY = std::max(minY, std::min(maxY, frameOffsetY + deltaY)); - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - } else if (((!currentMinusHeld && oldMinusHeld) || (!currentPlusHeld && oldPlusHeld)) && isDragging) { - // Button just released - stop joystick dragging - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["fps-graph"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["fps-graph"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - isDragging = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Update state for next frame - oldTouchDetected = currentTouchDetected; - oldMinusHeld = currentMinusHeld; - oldPlusHeld = currentPlusHeld; - - // Handle existing key input logic (but don't interfere with dragging) - if (!isDragging) { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - runOnce = true; - skipOnce = true; - TeslaFPS = 60; - lastSelectedItem = "FPS Graph"; - lastMode = ""; - if (skipMain) { - lastMode = "return"; - tsl::goBack(); - } - else { - tsl::setNextOverlay(filepath.c_str(), "--lastSelectedItem 'FPS Graph'"); - tsl::Overlay::get()->close(); - } - return true; - } - } - - // Return true if we handled the input (during dragging) - return isDragging; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Full.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Full.hpp deleted file mode 100644 index 06965099..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Full.hpp +++ /dev/null @@ -1,727 +0,0 @@ -class MainMenu; - -class FullOverlay : public tsl::Gui { -private: - char DeltaCPU_c[12] = ""; - char DeltaGPU_c[12] = ""; - char DeltaRAM_c[12] = ""; - char RealCPU_Hz_c[64] = ""; - char RealGPU_Hz_c[64] = ""; - char RealRAM_Hz_c[64] = ""; - char GPU_Load_c[32] = ""; - char Rotation_SpeedLevel_c[64] = ""; - char RAM_compressed_c[64] = ""; - char RAM_var_compressed_c[128] = ""; - char RAM_percentage_var_compressed_c[128] = ""; - char CPU_Hz_c[64] = ""; - char GPU_Hz_c[64] = ""; - char RAM_Hz_c[64] = ""; - char CPU_compressed_c[160] = ""; - char SOC_temperature_c[32] = ""; - char PCB_temperature_c[32] = ""; - char skin_temperature_c[32] = ""; - char CPU_temp_c[32] = ""; - char GPU_temp_c[32] = ""; - char RAM_temp_c[32] = ""; - char BatteryDraw_c[64] = ""; - char FPS_var_compressed_c[64] = ""; - char RAM_load_c[64] = ""; - char RAM_load2_c[64] = ""; - char RAM_bw_peak_c[16] = ""; - char RAM_bw_total_c[16] = ""; - char RAM_bw_gpu_c[16] = ""; - char RAM_bw_cpu_c[16] = ""; - char Resolutions_c[64] = ""; - char readSpeed_c[32] = ""; - - // New separated value buffers for CPU cores - char CPU_Core0_c[16] = ""; - char CPU_Core1_c[16] = ""; - char CPU_Core2_c[16] = ""; - char CPU_Core3_c[16] = ""; - - // New separated value buffers for FPS - char PFPS_value_c[16] = ""; - char FPS_value_c[16] = ""; - - static constexpr uint8_t COMMON_MARGIN = 20; - FullSettings settings; - uint64_t systemtickfrequency_impl = systemtickfrequency; - std::string formattedKeyCombo = keyCombo; - std::string message; - const std::vector KEY_SYMBOLS = { - "\uE0E4", "\uE0E5", "\uE0E6", "\uE0E7", - "\uE0E8", "\uE0E9", "\uE0ED", "\uE0EB", - "\uE0EE", "\uE0EC", "\uE0E0", "\uE0E1", - "\uE0E2", "\uE0E3", "\uE08A", "\uE08B", - "\uE0B6", "\uE0B5" - }; - - bool skipOnce = true; - bool runOnce = true; - - bool originalUseRightAlignment = ult::useRightAlignment; -public: - FullOverlay() { - disableJumpTo = true; - GetConfigSettings(&settings); - mutexInit(&mutex_BatteryChecker); - mutexInit(&mutex_Misc); - tsl::hlp::requestForeground(false); - TeslaFPS = settings.refreshRate; - systemtickfrequency_impl /= settings.refreshRate; - idletick0.store(systemtickfrequency_impl, std::memory_order_relaxed); - idletick1.store(systemtickfrequency_impl, std::memory_order_relaxed); - idletick2.store(systemtickfrequency_impl, std::memory_order_relaxed); - idletick3.store(systemtickfrequency_impl, std::memory_order_relaxed); - if (settings.setPosRight) { - const auto [horizontalUnderscanPixels, verticalUnderscanPixels] = tsl::gfx::getUnderscanPixels(); - tsl::gfx::Renderer::get().setLayerPos(1280-32 - horizontalUnderscanPixels, 0); - ult::useRightAlignment = true; - } else { - tsl::gfx::Renderer::get().setLayerPos(0, 0); - ult::useRightAlignment = false; - } - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - deactivateOriginalFooter = true; - formatButtonCombination(formattedKeyCombo); - //message = "Press " + formattedKeyCombo + " to Exit"; - - realVoltsPolling = false; - StartThreads(); - } - ~FullOverlay() { - CloseThreads(); - fixForeground = true; - ult::useRightAlignment = originalUseRightAlignment; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().addScreenshotStacks(); - } - deactivateOriginalFooter = false; - } - - resolutionCalls m_resolutionRenderCalls[8] = {0}; - resolutionCalls m_resolutionViewportCalls[8] = {0}; - resolutionCalls m_resolutionOutput[8] = {0}; - uint8_t resolutionLookup = 0; - - virtual tsl::elm::Element* createUI() override { - - - auto Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency", false, 15).first; - //static auto realFreqWidth = renderer->getTextDimensions("Real Frequency", false, 15).first; - //static auto freqWidth = std::max(targetFreqWidth, realFreqWidth); - - //static auto batteryLabelWidth = renderer->getTextDimensions("Battery Power Flow", false, 15).first; - //static auto fanLabelWidth = renderer->getTextDimensions("Fan Rotation Level", false, 15).first; - //static auto boardWidth = std::max(batteryLabelWidth, fanLabelWidth); - - static constexpr size_t valueOffset = 150+10; - static constexpr size_t deltaOffset = 246+10; - static constexpr size_t ramPercentageOffset = 350+10; - - //Print strings - ///CPU - if (1) { - - uint32_t height_offset = 155; - if (realCPU_Hz && settings.showRealFreqs) { - height_offset = 162; - } - renderer->drawString("CPU Usage", false, COMMON_MARGIN, 120, 20, (settings.catColor1)); - if (settings.showTargetFreqs) { - //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first; - renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2)); - renderer->drawString(CPU_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset, 15, (settings.textColor)); - } - if (realCPU_Hz && settings.showRealFreqs) { - //static auto realFreqWidth = renderer->getTextDimensions("Real Frequency: ", false, 15).first; - renderer->drawString("Real Frequency", false, COMMON_MARGIN, height_offset - 15, 15, (settings.catColor2)); - renderer->drawString(RealCPU_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset - 15, 15, (settings.textColor)); - if (settings.showDeltas && settings.showTargetFreqs) { - renderer->drawString(DeltaCPU_c, false, COMMON_MARGIN + deltaOffset, height_offset - 7, 15, (settings.textColor)); - } - else if (settings.showDeltas && !settings.showTargetFreqs) { - renderer->drawString(DeltaCPU_c, false, COMMON_MARGIN + deltaOffset, height_offset - 15, 15, (settings.textColor)); - } - } - else if (realCPU_Hz && settings.showDeltas && (settings.showRealFreqs || settings.showTargetFreqs)) { - renderer->drawString(DeltaCPU_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor)); - } - - // CPU Core labels and values - static auto core0Width = renderer->getTextDimensions("Core 0 ", false, 15).first; - static auto core1Width = renderer->getTextDimensions("Core 1 ", false, 15).first; - static auto core2Width = renderer->getTextDimensions("Core 2 ", false, 15).first; - static auto core3Width = renderer->getTextDimensions("Core 3 ", false, 15).first; - - const uint32_t core_height = height_offset + 30; - renderer->drawString("Core 0 ", false, COMMON_MARGIN, core_height, 15, (settings.catColor2)); - renderer->drawString(CPU_Core0_c, false, COMMON_MARGIN + core0Width, core_height, 15, (settings.textColor)); - - renderer->drawString("Core 1 ", false, COMMON_MARGIN, core_height + 15, 15, (settings.catColor2)); - renderer->drawString(CPU_Core1_c, false, COMMON_MARGIN + core1Width, core_height + 15, 15, (settings.textColor)); - - renderer->drawString("Core 2 ", false, COMMON_MARGIN, core_height + 30, 15, (settings.catColor2)); - renderer->drawString(CPU_Core2_c, false, COMMON_MARGIN + core2Width, core_height + 30, 15, (settings.textColor)); - - renderer->drawString("Core 3 ", false, COMMON_MARGIN, core_height + 45, 15, (settings.catColor2)); - renderer->drawString(CPU_Core3_c, false, COMMON_MARGIN + core3Width, core_height + 45, 15, (settings.textColor)); - } - - ///GPU - if (R_SUCCEEDED(nvCheck)) { - - uint32_t height_offset = 320-8; - if (realGPU_Hz && settings.showRealFreqs) { - height_offset = 327-8; - } - - renderer->drawString("GPU Usage", false, COMMON_MARGIN, 285-8, 20, (settings.catColor1)); - if (1) { - if (settings.showTargetFreqs) { - //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first; - renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2)); - renderer->drawString(GPU_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset, 15, (settings.textColor)); - } - if (realCPU_Hz && settings.showRealFreqs) { - //static auto realFreqWidth = renderer->getTextDimensions("Real Frequency: ", false, 15).first; - renderer->drawString("Real Frequency", false, COMMON_MARGIN, height_offset - 15, 15, (settings.catColor2)); - renderer->drawString(RealGPU_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset - 15, 15, (settings.textColor)); - if (settings.showDeltas && settings.showTargetFreqs) { - renderer->drawString(DeltaGPU_c, false, COMMON_MARGIN + deltaOffset, height_offset - 7, 15, (settings.textColor)); - } - else if (settings.showDeltas && !settings.showTargetFreqs) { - renderer->drawString(DeltaGPU_c, false, COMMON_MARGIN + deltaOffset, height_offset - 15, 15, (settings.textColor)); - } - } - else if (realGPU_Hz && settings.showDeltas && (settings.showRealFreqs || settings.showTargetFreqs)) { - renderer->drawString(DeltaGPU_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor)); - } - } - if (R_SUCCEEDED(nvCheck)) { - //static auto loadWidth = renderer->getTextDimensions("Load: ", false, 15).first; - renderer->drawString("Load", false, COMMON_MARGIN, height_offset + 15, 15, (settings.catColor2)); - renderer->drawString(GPU_Load_c, false, COMMON_MARGIN + valueOffset, height_offset + 15, 15, (settings.textColor)); - } - - } - - static std::vector specialChars = {""}; - - ///RAM - if (R_SUCCEEDED(Hinted)) { - - uint32_t height_offset = 410; - if (realRAM_Hz && settings.showRealFreqs) { - height_offset += 7; - } - - renderer->drawString("RAM Usage", false, COMMON_MARGIN, 375, 20, (settings.catColor1)); - if (1) { - if (settings.showTargetFreqs) { - //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first; - renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2)); - renderer->drawString(RAM_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset, 15, (settings.textColor)); - } - if (realRAM_Hz && settings.showRealFreqs) { - //static auto realFreqWidth = renderer->getTextDimensions("Real Frequency: ", false, 15).first; - renderer->drawString("Real Frequency", false, COMMON_MARGIN, height_offset - 15, 15, (settings.catColor2)); - renderer->drawString(RealRAM_Hz_c, false, COMMON_MARGIN + valueOffset, height_offset - 15, 15, (settings.textColor)); - if (settings.showDeltas && settings.showTargetFreqs) { - renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset - 7, 15, (settings.textColor)); - } - else if (settings.showDeltas && !settings.showTargetFreqs) { - renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset - 15, 15, (settings.textColor)); - } - } - else if (realRAM_Hz && settings.showDeltas && (settings.showRealFreqs || settings.showTargetFreqs)) { - renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor)); - } - if (R_SUCCEEDED(hocclkCheck)) { - if (settings.ramInfoMode == "Bandwidth") { - // Fixed column layout: labels at fixed x, values at fixed x after max label width - // Col1: Peak/GPU labels, Col2: Total/CPU labels - // Values start at a fixed offset so columns don't shift with different digit counts - static const uint32_t bwLbl1W = renderer->getTextDimensions("Peak ", false, 15).first; - static const uint32_t bwLbl2W = renderer->getTextDimensions("Total ", false, 15).first; - static const uint32_t bwValW = renderer->getTextDimensions("99.9 GB/s", false, 15).first; - static const uint32_t bwGap = renderer->getTextDimensions(" ", false, 15).first; - const uint32_t xV1 = COMMON_MARGIN + bwLbl1W; - const uint32_t xL2 = xV1 + bwValW + bwGap; - const uint32_t xV2 = xL2 + bwLbl2W; - // Row 1: Peak ... Total - renderer->drawString("Peak", false, COMMON_MARGIN, height_offset+15, 15, settings.catColor2); - renderer->drawString(RAM_bw_peak_c, false, xV1, height_offset+15, 15, settings.textColor); - renderer->drawString("Total", false, xL2, height_offset+15, 15, settings.catColor2); - renderer->drawString(RAM_bw_total_c, false, xV2, height_offset+15, 15, settings.textColor); - // Row 2: GPU ... CPU - renderer->drawString("GPU", false, COMMON_MARGIN, height_offset+30, 15, settings.catColor2); - renderer->drawString(RAM_bw_gpu_c, false, xV1, height_offset+30, 15, settings.textColor); - renderer->drawString("CPU", false, xL2, height_offset+30, 15, settings.catColor2); - renderer->drawString(RAM_bw_cpu_c, false, xV2, height_offset+30, 15, settings.textColor); - } else { - static std::vector partLoadColoredChars = {"CPU", "GPU"}; - renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2)); - renderer->drawStringWithColoredSections(RAM_load_c, false, partLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2); - } - } - } - if (R_SUCCEEDED(Hinted)) { - const uint32_t ramUsageOffset = (R_SUCCEEDED(hocclkCheck) && settings.ramInfoMode == "Bandwidth") ? height_offset + 50 : height_offset + 40; - //static auto textWidth = renderer->getTextDimensions("Total \nApplication \nApplet \nSystem \nSystem Unsafe ", false, 15).first; - renderer->drawString("Total\nApplication\nApplet\nSystem\nSystem Unsafe", false, COMMON_MARGIN, ramUsageOffset, 15, (settings.catColor2)); - renderer->drawString(RAM_var_compressed_c, false, COMMON_MARGIN + valueOffset, ramUsageOffset, 15, (settings.textColor)); - renderer->drawString(RAM_percentage_var_compressed_c, false, ramPercentageOffset, ramUsageOffset, 15, (settings.textColor)); - } - } - - ///Thermal - if (R_SUCCEEDED(i2cCheck) || R_SUCCEEDED(tcCheck) || R_SUCCEEDED(pwmCheck)) { - renderer->drawString("Board", false, 20, 550+2, 20, (settings.catColor1)); - if (R_SUCCEEDED(i2cCheck)) { - renderer->drawString("Battery Power Flow", false, COMMON_MARGIN, 575+2, 15, (settings.catColor2)); - renderer->drawStringWithColoredSections(BatteryDraw_c, false, specialChars, COMMON_MARGIN + valueOffset, 575+2, 15, (settings.textColor), settings.separatorColor); - } - if (R_SUCCEEDED(pwmCheck)) { - renderer->drawString("Fan Rotation Level", false, COMMON_MARGIN, 590+2, 15, (settings.catColor2)); - renderer->drawString(Rotation_SpeedLevel_c, false, COMMON_MARGIN + valueOffset, 590+2, 15, (settings.textColor)); - } - if (R_SUCCEEDED(i2cCheck) || R_SUCCEEDED(tcCheck)) { - static auto socLabelWidth = renderer->getTextDimensions("SOC ", false, 15).first; - static auto pcbLabelWidth = renderer->getTextDimensions("PCB ", false, 15).first; - static auto maxLabelWidth = std::max(socLabelWidth, pcbLabelWidth); - static auto skinLabelWidth = renderer->getTextDimensions("Skin ", false, 15).first; - - // Compute gradient colors for temperatures - const tsl::Color socColor = settings.useDynamicColors ? tsl::GradientColor(SOC_temperatureF) : settings.textColor; - const tsl::Color pcbColor = settings.useDynamicColors ? tsl::GradientColor(PCB_temperatureF) : settings.textColor; - const tsl::Color skinColor = settings.useDynamicColors ? tsl::GradientColor(static_cast(skin_temperaturemiliC) / 1000.0f) : settings.textColor; - - renderer->drawString("Temperatures", false, COMMON_MARGIN, 605+2, 15, (settings.catColor2)); - - // SOC - starts at valueOffset next to "Temperatures" - uint32_t current_x = COMMON_MARGIN + valueOffset; - renderer->drawString("SOC ", false, current_x, 605+2, 15, (settings.catColor2)); - current_x += maxLabelWidth; - renderer->drawString(SOC_temperature_c, false, current_x, 605+2, 15, socColor); - - // SKIN - same spacing to the right - current_x += renderer->getTextDimensions(SOC_temperature_c, false, 15).first + 15; - renderer->drawString("Skin ", false, current_x, 605+2, 15, (settings.catColor2)); - current_x += skinLabelWidth; - renderer->drawString(skin_temperature_c, false, current_x, 605+2, 15, skinColor); - - // PCB - below SOC on next line - current_x = COMMON_MARGIN + valueOffset; - renderer->drawString("PCB ", false, current_x, 620+2, 15, (settings.catColor2)); - current_x += maxLabelWidth; - renderer->drawString(PCB_temperature_c, false, current_x, 620+2, 15, pcbColor); - } - } - - // Real temps - CPU, GPU, RAM - if (settings.realTemps && (realCPU_Temp != 0 || realGPU_Temp != 0 || realRAM_Temp != 0)) { - static auto cpuTempLabelWidth = renderer->getTextDimensions("CPU ", false, 15).first; - static auto gpuTempLabelWidth = renderer->getTextDimensions("GPU ", false, 15).first; - static auto ramTempLabelWidth = renderer->getTextDimensions("RAM ", false, 15).first; - - uint32_t current_x = COMMON_MARGIN + 58;; - - // CPU temp - if (realCPU_Temp != 0) { - const tsl::Color cpuTempColor = settings.useDynamicColors ? tsl::GradientColor(realCPU_Temp / 1000.0f) : settings.textColor; - renderer->drawString("CPU ", false, current_x, 635+2, 15, (settings.catColor2)); - current_x += cpuTempLabelWidth; - renderer->drawString(CPU_temp_c, false, current_x, 635+2, 15, cpuTempColor); - current_x += renderer->getTextDimensions(CPU_temp_c, false, 15).first + 15; - } - - // GPU temp - if (realGPU_Temp != 0) { - const tsl::Color gpuTempColor = settings.useDynamicColors ? tsl::GradientColor(realGPU_Temp / 1000.0f) : settings.textColor; - renderer->drawString("GPU ", false, current_x, 635+2, 15, (settings.catColor2)); - current_x += gpuTempLabelWidth; - renderer->drawString(GPU_temp_c, false, current_x, 635+2, 15, gpuTempColor); - current_x += renderer->getTextDimensions(GPU_temp_c, false, 15).first + 15; - } - - // RAM temp - if (realRAM_Temp != 0) { - const tsl::Color ramTempColor = settings.useDynamicColors ? tsl::GradientColor(realRAM_Temp / 1000.0f) : settings.textColor; - renderer->drawString("RAM ", false, current_x, 635+2, 15, (settings.catColor2)); - current_x += ramTempLabelWidth; - renderer->drawString(RAM_temp_c, false, current_x, 635+2, 15, ramTempColor); - } - } - - ///FPS - if (GameRunning) { - const uint32_t width_offset = valueOffset; - if (settings.showFPS || settings.showRES || settings.showRDSD) { - renderer->drawString("Game", false, COMMON_MARGIN + width_offset, 185+12, 20, (settings.catColor1)); - } - uint32_t height = 210+12; - if (settings.showFPS == true) { - static auto pfpsWidth = renderer->getTextDimensions("PFPS ", false, 15).first; - static auto fpsWidth = renderer->getTextDimensions("FPS ", false, 15).first; - - renderer->drawString("PFPS ", false, COMMON_MARGIN + width_offset, height, 15, (settings.catColor2)); - renderer->drawString(PFPS_value_c, false, COMMON_MARGIN + width_offset + pfpsWidth, height, 15, (settings.textColor)); - - // Calculate position for "FPS " label - add some spacing - const uint32_t fps_x_offset = COMMON_MARGIN + width_offset + pfpsWidth + renderer->getTextDimensions(PFPS_value_c, false, 15).first + 15; - renderer->drawString("FPS ", false, fps_x_offset, height, 15, (settings.catColor2)); - renderer->drawString(FPS_value_c, false, fps_x_offset + fpsWidth, height, 15, (settings.textColor)); - - height += 15; - } - if ((settings.showRES == true) && NxFps && SharedMemoryUsed && (NxFps -> API >= 1)) { - static auto resLabelWidth = renderer->getTextDimensions("Resolutions ", false, 15).first; - renderer->drawString("Resolutions ", false, COMMON_MARGIN + width_offset, height, 15, (settings.catColor2)); - - renderer->drawStringWithColoredSections(Resolutions_c, false, specialChars, COMMON_MARGIN + width_offset + resLabelWidth, height, 15, (settings.textColor), settings.separatorColor); - height += 15; - } - if (settings.showRDSD == true) { - static auto readLabelWidth = renderer->getTextDimensions("Read Speed ", false, 15).first; - renderer->drawString("Read Speed ", false, COMMON_MARGIN + width_offset, height, 15, (settings.catColor2)); - renderer->drawString(readSpeed_c, false, COMMON_MARGIN + width_offset + readLabelWidth, height, 15, (settings.textColor)); - } - } - - //renderer->drawStringWithColoredSections(message, false, KEY_SYMBOLS, 30, 693, 23, a(tsl::bottomTextColor), a(tsl::buttonColor)); - - - static const auto pressWidth = renderer->getTextDimensions("Press ", false, 23).first; - static const auto keyComboWidth = renderer->getTextDimensions(formattedKeyCombo.c_str(), false, 23).first; - - static constexpr u16 baseX = 30; - static constexpr u16 baseY = 693; - static constexpr u8 fontSize = 23; - - // Draw "Press " - renderer->drawString("Press ", false, baseX, baseY, fontSize, (tsl::bottomTextColor)); - - // Draw formatted key combo with colored sections - renderer->drawStringWithColoredSections(formattedKeyCombo, false, KEY_SYMBOLS, baseX + pressWidth, baseY, fontSize, (tsl::bottomTextColor), (tsl::buttonColor)); - - // Draw " to Exit" - renderer->drawString(" to Exit", false, baseX + pressWidth + keyComboWidth, baseY, fontSize, (tsl::bottomTextColor)); - }); - - auto rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - //Make stuff ready to print - ///CPU - if (systemtickfrequency_impl > 0) { - const uint64_t idle0_val = std::min(idletick0.load(std::memory_order_acquire), systemtickfrequency_impl); - const uint64_t idle1_val = std::min(idletick1.load(std::memory_order_acquire), systemtickfrequency_impl); - const uint64_t idle2_val = std::min(idletick2.load(std::memory_order_acquire), systemtickfrequency_impl); - const uint64_t idle3_val = std::min(idletick3.load(std::memory_order_acquire), systemtickfrequency_impl); - - const float usage0 = std::clamp(100.0f * (1.0f - float(idle0_val) / systemtickfrequency_impl), 0.0f, 100.0f); - const float usage1 = std::clamp(100.0f * (1.0f - float(idle1_val) / systemtickfrequency_impl), 0.0f, 100.0f); - const float usage2 = std::clamp(100.0f * (1.0f - float(idle2_val) / systemtickfrequency_impl), 0.0f, 100.0f); - const float usage3 = std::clamp(100.0f * (1.0f - float(idle3_val) / systemtickfrequency_impl), 0.0f, 100.0f); - - // Format individual core values - snprintf(CPU_Core0_c, sizeof(CPU_Core0_c), "%.2f%%", usage0); - snprintf(CPU_Core1_c, sizeof(CPU_Core1_c), "%.2f%%", usage1); - snprintf(CPU_Core2_c, sizeof(CPU_Core2_c), "%.2f%%", usage2); - snprintf(CPU_Core3_c, sizeof(CPU_Core3_c), "%.2f%%", usage3); - } - - mutexLock(&mutex_Misc); - snprintf(CPU_Hz_c, sizeof(CPU_Hz_c), "%u.%u MHz", CPU_Hz / 1000000, (CPU_Hz / 100000) % 10); - if (realCPU_Hz) { - snprintf(RealCPU_Hz_c, sizeof(RealCPU_Hz_c), "%u.%u MHz", realCPU_Hz / 1000000, (realCPU_Hz / 100000) % 10); - const int32_t deltaCPU = (int32_t)(realCPU_Hz / 1000) - (CPU_Hz / 1000); - snprintf(DeltaCPU_c, sizeof(DeltaCPU_c), "Δ %d.%u", deltaCPU / 1000, abs(deltaCPU / 100) % 10); - } - - ///GPU - snprintf(GPU_Hz_c, sizeof GPU_Hz_c, "%u.%u MHz", GPU_Hz / 1000000, (GPU_Hz / 100000) % 10); - if (realGPU_Hz) { - snprintf(RealGPU_Hz_c, sizeof(RealGPU_Hz_c), "%u.%u MHz", realGPU_Hz / 1000000, (realGPU_Hz / 100000) % 10); - const int32_t deltaGPU = (int32_t)(realGPU_Hz / 1000) - (GPU_Hz / 1000); - snprintf(DeltaGPU_c, sizeof(DeltaGPU_c), "Δ %d.%u", deltaGPU / 1000, abs(deltaGPU / 100) % 10); - } - snprintf(GPU_Load_c, sizeof GPU_Load_c, "%u.%u%%", GPU_Load_u / 10, GPU_Load_u % 10); - - ///RAM - snprintf(RAM_Hz_c, sizeof RAM_Hz_c, "%u.%u MHz", RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); - if (realRAM_Hz) { - snprintf(RealRAM_Hz_c, sizeof(RealRAM_Hz_c), "%u.%u MHz", realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); - const int32_t deltaRAM = (int32_t)(realRAM_Hz / 1000) - (RAM_Hz / 1000); - snprintf(DeltaRAM_c, sizeof(DeltaRAM_c), "Δ %d.%u", deltaRAM / 1000, abs(deltaRAM / 100) % 10); - } - - const float RAM_Total_application_f = (float)RAM_Total_application_u / 1024 / 1024; - const float RAM_Total_applet_f = (float)RAM_Total_applet_u / 1024 / 1024; - const float RAM_Total_system_f = (float)RAM_Total_system_u / 1024 / 1024; - const float RAM_Total_systemunsafe_f = (float)RAM_Total_systemunsafe_u / 1024 / 1024; - const float RAM_Total_all_f = RAM_Total_application_f + RAM_Total_applet_f + RAM_Total_system_f + RAM_Total_systemunsafe_f; - - const float RAM_Used_application_f = (float)RAM_Used_application_u / 1024 / 1024; - const float RAM_Used_applet_f = (float)RAM_Used_applet_u / 1024 / 1024; - const float RAM_Used_system_f = (float)RAM_Used_system_u / 1024 / 1024; - const float RAM_Used_systemunsafe_f = (float)RAM_Used_systemunsafe_u / 1024 / 1024; - const float RAM_Used_all_f = RAM_Used_application_f + RAM_Used_applet_f + RAM_Used_system_f + RAM_Used_systemunsafe_f; - - // Compute percentages - const int RAMPct_all = (int)((RAM_Used_all_f / RAM_Total_all_f) * 100.0f ); - const int RAMPct_app = (int)((RAM_Used_application_f / RAM_Total_application_f) * 100.0f ); - const int RAMPct_applet = (int)((RAM_Used_applet_f / RAM_Total_applet_f) * 100.0f ); - const int RAMPct_system = (int)((RAM_Used_system_f / RAM_Total_system_f) * 100.0f ); - const int RAMPct_systemunsafe = (int)((RAM_Used_systemunsafe_f/ RAM_Total_systemunsafe_f)* 100.0f ); - - snprintf(RAM_var_compressed_c, sizeof(RAM_var_compressed_c), - "%.1f MB / %.1f MB\n" - "%.1f MB / %.1f MB\n" - "%.1f MB / %.1f MB\n" - "%.1f MB / %.1f MB\n" - "%.1f MB / %.1f MB", - RAM_Used_all_f, RAM_Total_all_f, - RAM_Used_application_f, RAM_Total_application_f, - RAM_Used_applet_f, RAM_Total_applet_f, - RAM_Used_system_f, RAM_Total_system_f, - RAM_Used_systemunsafe_f, RAM_Total_systemunsafe_f - ); - - // 2. Percentages only (newlines preserved) - snprintf(RAM_percentage_var_compressed_c, sizeof(RAM_percentage_var_compressed_c), - "(%d%%)\n" - "(%d%%)\n" - "(%d%%)\n" - "(%d%%)\n" - "(%d%%)", - RAMPct_all, - RAMPct_app, - RAMPct_applet, - RAMPct_system, - RAMPct_systemunsafe - ); - - if (R_SUCCEEDED(hocclkCheck)) { - if (settings.ramInfoMode == "Bandwidth") { - const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000; - const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100; - const unsigned bwPeak = partLoad[HocClkPartLoad_RamBWPeak] / 1000; - const unsigned bwPeakD= (partLoad[HocClkPartLoad_RamBWPeak]% 1000) / 100; - const unsigned bwCpu = partLoad[HocClkPartLoad_RamBWCpu] / 1000; - const unsigned bwCpuD = (partLoad[HocClkPartLoad_RamBWCpu] % 1000) / 100; - const unsigned bwGpu = partLoad[HocClkPartLoad_RamBWGpu] / 1000; - const unsigned bwGpuD = (partLoad[HocClkPartLoad_RamBWGpu] % 1000) / 100; - snprintf(RAM_bw_peak_c, sizeof RAM_bw_peak_c, "%u.%u GB/s", bwPeak, bwPeakD); - snprintf(RAM_bw_total_c, sizeof RAM_bw_total_c, "%u.%u GB/s", bwAll, bwAllD); - snprintf(RAM_bw_gpu_c, sizeof RAM_bw_gpu_c, "%u.%u GB/s", bwGpu, bwGpuD); - snprintf(RAM_bw_cpu_c, sizeof RAM_bw_cpu_c, "%u.%u GB/s", bwCpu, bwCpuD); - } else { - const int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu]; - snprintf(RAM_load_c, sizeof RAM_load_c, - "%u.%u%% CPU %u.%u%% GPU %u.%u%%", - partLoad[HocClkPartLoad_EMC] / 10, partLoad[HocClkPartLoad_EMC] % 10, - partLoad[HocClkPartLoad_EMCCpu] / 10, partLoad[HocClkPartLoad_EMCCpu] % 10, - RAM_GPU_Load / 10, RAM_GPU_Load % 10); - } - } - ///Thermal - snprintf(SOC_temperature_c, sizeof SOC_temperature_c, "%.1f\u00B0C", SOC_temperatureF); - snprintf(PCB_temperature_c, sizeof PCB_temperature_c, "%.1f\u00B0C", PCB_temperatureF); - snprintf(skin_temperature_c, sizeof skin_temperature_c, "%d.%d\u00B0C", skin_temperaturemiliC / 1000, (skin_temperaturemiliC / 100) % 10); - - snprintf(Rotation_SpeedLevel_c, sizeof Rotation_SpeedLevel_c, "%.1f%%", Rotation_Duty); - - if (settings.realTemps) { - if (realCPU_Temp != 0) { - snprintf(CPU_temp_c, sizeof(CPU_temp_c), "%.1f°C", realCPU_Temp / 1000.0f); - } - if (realGPU_Temp != 0) { - snprintf(GPU_temp_c, sizeof(GPU_temp_c), "%.1f°C", realGPU_Temp / 1000.0f); - } - if (realRAM_Temp != 0) { - snprintf(RAM_temp_c, sizeof(RAM_temp_c), "%.1f°C", realRAM_Temp / 1000.0f); - } - } - ///FPS - if (settings.showFPS == true) { - snprintf(PFPS_value_c, sizeof PFPS_value_c, "%1u", FPS); - snprintf(FPS_value_c, sizeof FPS_value_c, "%.1f", useOldFPSavg ? FPSavg_old : FPSavg); - } - - //Resolutions - if ((settings.showRES == true) && GameRunning && NxFps) { - if (!resolutionLookup) { - (NxFps -> renderCalls[0].calls) = 0xFFFF; - resolutionLookup = 1; - } - else if (resolutionLookup == 1) { - if ((NxFps -> renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2; - } - else { - if (NxFps && SharedMemoryUsed) { - memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls)); - memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls)); - } else { - memset(&m_resolutionRenderCalls, 0, sizeof(m_resolutionRenderCalls)); - memset(&m_resolutionViewportCalls, 0, sizeof(m_resolutionViewportCalls)); - } - qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare); - qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare); - memset(&m_resolutionOutput, 0, sizeof(m_resolutionOutput)); - size_t out_iter = 0; - bool found = false; - for (size_t i = 0; i < 8; i++) { - for (size_t x = 0; x < 8; x++) { - if (m_resolutionRenderCalls[i].width == 0) { - break; - } - if ((m_resolutionRenderCalls[i].width == m_resolutionViewportCalls[x].width) && (m_resolutionRenderCalls[i].height == m_resolutionViewportCalls[x].height)) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = (m_resolutionRenderCalls[i].calls > m_resolutionViewportCalls[x].calls) ? m_resolutionRenderCalls[i].calls : m_resolutionViewportCalls[x].calls; - out_iter++; - found = true; - break; - } - } - if (!found && m_resolutionRenderCalls[i].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = m_resolutionRenderCalls[i].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - if (out_iter < 8) { - const size_t out_iter_s = out_iter; - for (size_t x = 0; x < 8; x++) { - for (size_t y = 0; y < out_iter_s; y++) { - if (m_resolutionViewportCalls[x].width == 0) { - break; - } - if ((m_resolutionViewportCalls[x].width == m_resolutionOutput[y].width) && (m_resolutionViewportCalls[x].height == m_resolutionOutput[y].height)) { - found = true; - break; - } - } - if (!found && m_resolutionViewportCalls[x].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionViewportCalls[x].width; - m_resolutionOutput[out_iter].height = m_resolutionViewportCalls[x].height; - m_resolutionOutput[out_iter].calls = m_resolutionViewportCalls[x].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - } - qsort(m_resolutionOutput, 8, sizeof(resolutionCalls), compare); - static std::pair old_res[2]; - - // Only swap if BOTH resolutions exist (prevent swapping with empty slot) - if (m_resolutionOutput[0].width && m_resolutionOutput[1].width) { - if ((m_resolutionOutput[0].width == old_res[1].first && m_resolutionOutput[0].height == old_res[1].second) || - (m_resolutionOutput[1].width == old_res[0].first && m_resolutionOutput[1].height == old_res[0].second)) { - const uint16_t swap_width = m_resolutionOutput[0].width; - const uint16_t swap_height = m_resolutionOutput[0].height; - m_resolutionOutput[0].width = m_resolutionOutput[1].width; - m_resolutionOutput[0].height = m_resolutionOutput[1].height; - m_resolutionOutput[1].width = swap_width; - m_resolutionOutput[1].height = swap_height; - } - } - - //if (!m_resolutionOutput[1].width) { - // snprintf(Resolutions_c, sizeof(Resolutions_c), "%dx%d", m_resolutionOutput[0].width, m_resolutionOutput[0].height); - //} - //else { - // snprintf(Resolutions_c, sizeof(Resolutions_c), "%dx%d%dx%d", m_resolutionOutput[0].width, m_resolutionOutput[0].height, m_resolutionOutput[1].width, m_resolutionOutput[1].height); - //} - - if (!m_resolutionOutput[1].width || !m_resolutionOutput[0].width) { - if (!m_resolutionOutput[1].width) - snprintf(Resolutions_c, sizeof(Resolutions_c), "%dx%d", m_resolutionOutput[0].width, m_resolutionOutput[0].height); - else snprintf(Resolutions_c, sizeof(Resolutions_c), "%dx%d", m_resolutionOutput[1].width, m_resolutionOutput[1].height); - } - else snprintf(Resolutions_c, sizeof(Resolutions_c),"%dx%d%dx%d", m_resolutionOutput[0].width, m_resolutionOutput[0].height, m_resolutionOutput[1].width, m_resolutionOutput[1].height); - - old_res[0] = std::make_pair(m_resolutionOutput[0].width, m_resolutionOutput[0].height); - old_res[1] = std::make_pair(m_resolutionOutput[1].width, m_resolutionOutput[1].height); - } - if (settings.showRDSD == true && GameRunning && NxFps) { - if ((NxFps -> readSpeedPerSecond) != 0.f) snprintf(readSpeed_c, sizeof(readSpeed_c), "%.2f MiB/s", (NxFps -> readSpeedPerSecond) / 1048576.f); - else snprintf(readSpeed_c, sizeof(readSpeed_c), "n/d"); - } - } - else if (!GameRunning && resolutionLookup != 0) { - resolutionLookup = 0; - } - - mutexUnlock(&mutex_Misc); - - /* ── Battery / power draw ───────────────────────────────────── */ - char remainingBatteryLife[8]; - - /* Normalise "-0.00" → "0.00" W */ - const float drawW = (fabsf(PowerConsumption) < 0.01f) ? 0.0f - : PowerConsumption; - - mutexLock(&mutex_BatteryChecker); - - /* keep "--:--" whenever estimate is negative */ - if (batTimeEstimate >= 0 && !(drawW <= 0.01f && drawW >= -0.01f)) { - snprintf(remainingBatteryLife, sizeof(remainingBatteryLife), - "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } else { - strcpy(remainingBatteryLife, "--:--"); - } - - const float batteryPercent = (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f; - - snprintf(BatteryDraw_c, sizeof(BatteryDraw_c), - "%.2f W%.0f%% [%s]", - drawW, - batteryPercent, - remainingBatteryLife); - - mutexUnlock(&mutex_BatteryChecker); - - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - skipOnce = true; - runOnce = true; - TeslaFPS = 60; - lastSelectedItem = "Full"; - lastMode = ""; - tsl::swapTo(); - return true; - } - return false; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Micro.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Micro.hpp deleted file mode 100644 index 9c999d13..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Micro.hpp +++ /dev/null @@ -1,1300 +0,0 @@ -class MainMenu; - -class MicroOverlay : public tsl::Gui { -private: - char GPU_Load_c[32]; - char RAM_var_compressed_c[128]; - char CPU_compressed_c[160]; - char CPU_Usage0[32]; - char CPU_Usage1[32]; - char CPU_Usage2[32]; - char CPU_Usage3[32]; - char CPU_UsageM[32]; - char soc_temperature_c[32]; - char skin_temperature_c[32]; - char FPS_var_compressed_c[64]; - char Battery_c[32]; - char CPU_volt_c[16]; - char GPU_volt_c[16]; - char RAM_volt_c[32]; - char SOC_volt_c[16]; - char CPU_temp_c[32]; - char GPU_temp_c[32]; - char RAM_temp_c[32]; - char RES_var_compressed_c[32]; - char READ_var_compressed_c[32]; - char DTC_c[32]; - - static constexpr uint32_t margin = 4; - - // Performance optimization members - bool Initialized = false; - MicroSettings settings; - size_t text_width = 0; - size_t fps_width = 0; - ApmPerformanceMode performanceMode = ApmPerformanceMode_Invalid; - size_t fontsize = 0; - bool showFPS = false; - uint64_t systemtickfrequency_impl = systemtickfrequency; - - // Pre-compiled render data structures - struct RenderItem { - uint8_t type; - const char* label; - const char* data_ptr; - const char* volt_ptr; - bool has_voltage; - }; - - // Resolution tracking - resolutionCalls m_resolutionRenderCalls[8] = {0}; - resolutionCalls m_resolutionViewportCalls[8] = {0}; - resolutionCalls m_resolutionOutput[8] = {0}; - uint8_t resolutionLookup = 0; - bool resolutionShow = false; - - std::vector renderItems; - uint32_t cachedMargin = 0; - tsl::Color catColorA = 0; - tsl::Color textColorA = 0; - uint32_t base_y = 0; - bool renderDataDirty = true; - - bool skipOnce = true; - bool runOnce = true; - - // Fixed spacing system - calculate actual widths at render time - struct LayoutMetrics { - uint32_t label_data_gap = 8; // Fixed gap between label and data - uint32_t volt_separator_gap = 0; // Fixed gap before voltage separator - uint32_t volt_data_gap = 0; // Fixed gap after voltage separator - uint32_t item_spacing = 16; // Minimum spacing between complete items - uint32_t side_margin = 3; // Margins on left and right - bool calculated = false; - } layout; - - // Lookup table for difference symbols - static constexpr const char* diffSymbols[4] = {"△", "@", "▽", "≠"}; - - inline const char* getDifferenceSymbol(int32_t delta) { - if (delta > 20000) return diffSymbols[0]; // △ - if (delta > -20000) return diffSymbols[1]; // @ - if (delta < -50000) return diffSymbols[3]; // ≠ - return diffSymbols[2]; // ▽ - } - - void calculateLayoutMetrics(tsl::gfx::Renderer *renderer) { - if (layout.calculated) return; - - // Use font size to determine appropriate spacing - if (fontsize <= 16) { - layout.label_data_gap = 6; - layout.volt_separator_gap = 0; - layout.volt_data_gap = 0; - layout.item_spacing = 12; - } else if (fontsize <= 20) { - layout.label_data_gap = 8; - layout.volt_separator_gap = 0; - layout.volt_data_gap = 0; - layout.item_spacing = 16; - } else { - layout.label_data_gap = 10; - layout.volt_separator_gap = 0; - layout.volt_data_gap = 0; - layout.item_spacing = 20; - } - - layout.calculated = true; - } - -public: - MicroOverlay() { - CPU_temp_c[0] = '\0'; - GPU_temp_c[0] = '\0'; - RAM_temp_c[0] = '\0'; - - tsl::hlp::requestForeground(false); - disableJumpTo = true; - //tsl::initializeUltrahandSettings(); - GetConfigSettings(&settings); - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - fontsize = settings.handheldFontSize; - } - else fontsize = settings.dockedFontSize; - - if (ult::limitedMemory && settings.setPosBottom) { - const auto [horizontalUnderscanPixels, verticalUnderscanPixels] = tsl::gfx::getUnderscanPixels(); - tsl::gfx::Renderer::get().setLayerPos(0, !verticalUnderscanPixels ? 1038 : 1038- (tsl::cfg::ScreenHeight/720. * verticalUnderscanPixels) +0.5); - } - - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - mutexInit(&mutex_BatteryChecker); - mutexInit(&mutex_Misc); - TeslaFPS = settings.refreshRate; - systemtickfrequency_impl /= settings.refreshRate; - FullMode = false; - //alphabackground = 0x0; - deactivateOriginalFooter = true; - StartThreads(); - - // Pre-allocate render items vector - //renderItems.reserve(8); - realVoltsPolling = settings.realVolts; - - // Get initial battery readings BEFORE starting threads - if (R_SUCCEEDED(psmCheck) && R_SUCCEEDED(i2cCheck)) { - uint16_t data = 0; - float tempA = 0.0; - - // Get initial power consumption - Max17050ReadReg(MAX17050_AvgCurrent, &data); - tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data; - PowerConsumption = tempA * batVoltageAvg / 1000000.0; // Rough initial estimate - - // Get initial battery info - psmGetBatteryChargeInfoFields(psmService, &_batteryChargeInfoFields); - - // Get initial time estimate - if (tempA >= 0) { - batTimeEstimate = -1; - } else { - Max17050ReadReg(MAX17050_TTE, &data); - const float batteryTimeEstimateInMinutes = (5.625 * data) / 60; - if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) { - batTimeEstimate = (99*60)+59; - } else { - batTimeEstimate = (int16_t)batteryTimeEstimateInMinutes; - } - } - } else { - // Fallback if checks failed - PowerConsumption = 0.0f; - batTimeEstimate = -1; - _batteryChargeInfoFields = {0}; - } - - // Now format the initial Battery_c string - char remainingBatteryLife[8]; - const float drawW = (fabsf(PowerConsumption) < 0.01f) ? 0.0f : PowerConsumption; - - if (batTimeEstimate >= 0 && !(drawW <= 0.01f && drawW >= -0.01f)) { - snprintf(remainingBatteryLife, sizeof(remainingBatteryLife), - "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } else { - strcpy(remainingBatteryLife, "--:--"); - } - - if (!settings.invertBatteryDisplay) { - snprintf(Battery_c, sizeof(Battery_c), - "%.2f W%.1f%% [%s]", - drawW, - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife); - } else { - snprintf(Battery_c, sizeof(Battery_c), - "%.1f%% [%s]%.2f W", - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife, - drawW); - } - - - } - - ~MicroOverlay() { - CloseThreads(); - fixForeground = true; - FullMode = true; - } - - // Fast parsing and render item preparation - void prepareRenderItems() { - if (!renderDataDirty) return; - - renderItems.clear(); - - // Fast manual parsing of settings.show - const std::string& show = settings.show; - size_t start = 0, end = 0; - uint8_t seen_flags = 0; - - static size_t len; - static uint32_t key3; - while (start < show.length()) { - end = show.find('+', start); - if (end == std::string::npos) end = show.length(); - - len = end - start; - if (len >= 3) { - const char* key = &show[start]; - - // Use first 3 chars for fast comparison - key3 = (key[0] << 16) | (key[1] << 8) | key[2]; - - switch (key3) { - case 0x435055: // "CPU" - if (!(seen_flags & 1)) { - renderItems.push_back({0, "CPU", CPU_compressed_c, CPU_volt_c, settings.realVolts}); - seen_flags |= 1; - } - break; - case 0x475055: // "GPU" - if (!(seen_flags & 2)) { - renderItems.push_back({1, "GPU", GPU_Load_c, GPU_volt_c, settings.realVolts}); - seen_flags |= 2; - } - break; - case 0x52414D: // "RAM" - if (!(seen_flags & 4)) { - renderItems.push_back({2, "RAM", RAM_var_compressed_c, RAM_volt_c, settings.realVolts}); - seen_flags |= 4; - } - break; - case 0x534F43: // "SOC" - if (!(seen_flags & 8)) { - renderItems.push_back({3, "SOC", soc_temperature_c, SOC_volt_c, settings.realVolts && settings.showSOCVoltage}); - seen_flags |= 8; - } - break; - case 0x544D50: // "TMP" - if (!(seen_flags & 16)) { - renderItems.push_back({4, "TMP", skin_temperature_c, SOC_volt_c, settings.realVolts && settings.showSOCVoltage}); - seen_flags |= 16; - } - break; - case 0x524553: // "RES" - if (!(seen_flags & 128)) { - renderItems.push_back({7, "RES", RES_var_compressed_c, nullptr, false}); // We'll reuse FPS buffer temporarily - seen_flags |= 128; - resolutionShow = true; - } - break; - case 0x465053: // "FPS" - if (!(seen_flags & 32)) { - renderItems.push_back({5, "FPS", FPS_var_compressed_c, nullptr, false}); - seen_flags |= 32; - } - break; - case 0x424154: // "BAT" - if (!(seen_flags & 64)) { - renderItems.push_back({6, "BAT", Battery_c, nullptr, false}); - seen_flags |= 64; - } - break; - case 0x524541: // "REA" (for READ) - if (len >= 4 && key[3] == 'D' && !(seen_flags & 512)) { - renderItems.push_back({9, "READ", READ_var_compressed_c, nullptr, false}); - seen_flags |= 512; - } - break; - case 0x445443: // "DTC" - if (!(seen_flags & 256) && settings.showDTC) { - renderItems.push_back({8, settings.useDTCSymbol ? "\uE007" : "DTC", DTC_c, nullptr, false}); - seen_flags |= 256; - } - break; - } - } - start = end + 1; - } - - renderDataDirty = false; - } - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - cachedMargin = renderer->getTextDimensions("CPUGPURAMSOCBAT[]", false, fontsize).second; - if (!Initialized) { - //cachedMargin = renderer->drawString(" ", false, 0, 0, fontsize, renderer->a(0x0000)).first; - - catColorA = settings.catColor; - textColorA = settings.textColor; - base_y = settings.setPosBottom ? - tsl::cfg::FramebufferHeight - (fontsize + (fontsize / 4)) +1: 0; - Initialized = true; - renderDataDirty = true; - layout.calculated = false; // Force recalculation - tsl::hlp::requestForeground(false); - } - - //renderer->drawRect(0, 0, tsl::cfg::FramebufferWidth, cachedMargin + 4, a(settings.backgroundColor)); - renderer->drawRect(0, settings.setPosBottom ? base_y-1 : 0, tsl::cfg::FramebufferWidth, cachedMargin + 4, a(settings.backgroundColor)); - - // Prepare render items if settings changed - prepareRenderItems(); - calculateLayoutMetrics(renderer); - - // Separate battery from other items - std::vector main_items; - //RenderItem* battery_item = nullptr; - - for (auto& item : renderItems) { - //if (item.type == 6) { // BAT - // battery_item = &item; - if (item.type == 5 && (!GameRunning || (strcmp(FPS_var_compressed_c, "254.0") == 0))) { - // Skip FPS if no game running - continue; - } else if (item.type == 7 && (!GameRunning || !m_resolutionOutput[0].width)) { - // Skip RES if no game running or no resolution data yet - continue; - } else if (item.type == 8 && !settings.showDTC) { - // Skip DTC if disabled in settings - continue; - } else if (item.type == 9 && (!GameRunning || !NxFps)) { - // Skip READ if no game running or no NxFps available - continue; - } else { - main_items.push_back(item); - } - } - - // Calculate actual widths for all main items - struct ItemLayout { - uint32_t label_width; - uint32_t data_width; - uint32_t volt_width; - uint32_t total_width; - }; - - std::vector item_layouts; - uint32_t total_main_width = 0; - - static const auto sep_width = renderer->getTextDimensions("", false, fontsize).first; - - static ItemLayout item_layout; - for (const auto& item : main_items) { - item_layout = {}; - - // Calculate actual label width - //auto label_dim = renderer->drawString(item.label, false, 0, 0, fontsize, renderer->a(0x0000)); - //auto label_dim = renderer->getTextDimensions(item.label, fontsize); - item_layout.label_width = renderer->getTextDimensions(item.label, false, fontsize).first; - - // Calculate actual data width - //auto data_dim = renderer->drawString(item.data_ptr, false, 0, 0, fontsize, renderer->a(0x0000)); - //auto data_dim = renderer->getTextDimensions(item.data_ptr, fontsize); - item_layout.data_width = renderer->getTextDimensions(item.data_ptr, false, fontsize).first; - - // Calculate voltage width if present - if (item.has_voltage && item.volt_ptr) { - //uto volt_dim = renderer->drawString(item.volt_ptr, false, 0, 0, fontsize, renderer->a(0x0000)); - //auto volt_dim = renderer->getTextDimensions(item.volt_ptr, fontsize); - item_layout.volt_width = renderer->getTextDimensions(item.volt_ptr, false, fontsize).first; - - // Total: label + gap + data + gap + "|" + gap + voltage - //auto sep_width = renderer->drawString("", false, 0, 0, fontsize, renderer->a(0x0000)); - item_layout.total_width = item_layout.label_width + layout.label_data_gap + - item_layout.data_width + layout.volt_separator_gap + - sep_width + layout.volt_data_gap + item_layout.volt_width; - } else { - // Total: label + gap + data - item_layout.total_width = item_layout.label_width + layout.label_data_gap + item_layout.data_width; - } - - item_layouts.push_back(item_layout); - total_main_width += item_layout.total_width; - } - - - - // Determine if we have battery and handle it as the rightmost item - std::vector all_items_ordered; - std::vector all_layouts_ordered; - - // Add main items first - for (size_t i = 0; i < main_items.size(); i++) { - all_items_ordered.push_back(main_items[i]); - all_layouts_ordered.push_back(item_layouts[i]); - } - - // Add battery as the last item if present - //if (battery_item) { - // //auto bat_label_dim = renderer->drawString("BAT", false, 0, 0, fontsize, renderer->a(0x0000)); - // //auto bat_label_dim = renderer->getTextDimensions("BAT", fontsize); - // //auto bat_data_dim = renderer->drawString(battery_item->data_ptr, false, 0, 0, fontsize, renderer->a(0x0000)); - // //auto bat_data_dim = renderer->getTextDimensions(battery_item->data_ptr, fontsize); - // - // ItemLayout battery_layout = {}; - // battery_layout.label_width = renderer->getTextDimensions("BAT", false, fontsize).first; - // battery_layout.data_width = renderer->getTextDimensions(battery_item->data_ptr, false, fontsize).first; - // battery_layout.volt_width = 0; - // battery_layout.total_width = battery_layout.label_width + layout.label_data_gap + battery_layout.data_width; - // - // all_items_ordered.push_back(*battery_item); - // all_layouts_ordered.push_back(battery_layout); - //} - - // Calculate total width of all items - uint32_t total_all_width = 0; - for (const auto& item_layout : all_layouts_ordered) { - total_all_width += item_layout.total_width; - } - - // Calculate available space for distribution - //uint32_t available_width = tsl::cfg::FramebufferWidth - (2 * layout.side_margin); - //uint32_t remaining_space = available_width - total_all_width; - - // Calculate positions based on alignment mode - std::vector item_positions; - const size_t N = all_items_ordered.size(); - if (N == 0) return; - - if (N == 1) { - // Single item positioning based on alignment - if (settings.alignTo == 2) { // RIGHT - const uint32_t total_width = all_layouts_ordered[0].total_width; - item_positions.push_back(tsl::cfg::FramebufferWidth - layout.side_margin - total_width); - } else { // LEFT or CENTER - item_positions.push_back(layout.side_margin); - } - } else { - uint32_t total_widths = 0; - for (const auto& layout : all_layouts_ordered) { - total_widths += layout.total_width; - } - - if (settings.alignTo == 0) { // LEFT alignment - // All items except last positioned from left with small gaps - // Last item (battery if present) positioned at far right - const uint32_t small_gap = layout.item_spacing; - - // Position items from left - uint32_t current_x = layout.side_margin; - for (size_t i = 0; i < N - 1; ++i) { - item_positions.push_back(current_x); - current_x += all_layouts_ordered[i].total_width + small_gap; - } - - // Position last item at far right - const uint32_t last_width = all_layouts_ordered[N-1].total_width; - item_positions.push_back(tsl::cfg::FramebufferWidth - layout.side_margin - last_width); - - } else if (settings.alignTo == 2) { // RIGHT alignment - // First item at far left, remaining items packed at right - const uint32_t small_gap = layout.item_spacing; - - // Resize vector to hold all positions - item_positions.resize(N); - - // Position first item at far left - item_positions[0] = layout.side_margin; - - // Calculate total width of items 1 to N-1 plus gaps between them - uint32_t right_group_width = 0; - for (size_t i = 1; i < N; ++i) { - right_group_width += all_layouts_ordered[i].total_width; - if (i < N - 1) right_group_width += small_gap; // Gap after each item except the last - } - - // Start positioning from right margin minus total width of right group - uint32_t current_x = tsl::cfg::FramebufferWidth - layout.side_margin - right_group_width; - - // Position items 1 to N-1 sequentially from left to right within the right group - for (size_t i = 1; i < N; ++i) { - item_positions[i] = current_x; - current_x += all_layouts_ordered[i].total_width + small_gap; - } - } else { // CENTER alignment (default behavior) - // Total available width for spacing = framebuffer width minus total item widths minus margins - const int32_t total_spacing = (int32_t)tsl::cfg::FramebufferWidth - (2 * (int32_t)layout.side_margin) - (int32_t)total_widths; - - // Number of gaps between items is N-1 - const uint32_t gap = total_spacing > 0 ? (uint32_t)(total_spacing / (N - 1)) : 0; - - // Position first item flush left - item_positions.push_back(layout.side_margin); - static uint32_t prev_pos, prev_width; - // Position subsequent items - for (size_t i = 1; i < N; ++i) { - prev_pos = item_positions[i - 1]; - prev_width = all_layouts_ordered[i - 1].total_width; - item_positions.push_back(prev_pos + prev_width + gap); - } - - // Fix any rounding error for center alignment - const int32_t last_item_end = item_positions.back() + all_layouts_ordered.back().total_width; - const int32_t overflow = (int32_t)tsl::cfg::FramebufferWidth - layout.side_margin - last_item_end; - - if (overflow != 0) { - for (size_t i = 1; i < item_positions.size(); ++i) { - item_positions[i] += overflow; - } - } - } - } - - - uint32_t current_x; - static std::vector specialChars = {""}; - - // Render all items at calculated positions - for (size_t i = 0; i < all_items_ordered.size(); i++) { - const auto& item = all_items_ordered[i]; - const auto& item_layout = all_layouts_ordered[i]; - current_x = item_positions[i]; - - // Draw label - renderer->drawString(item.label, false, current_x, base_y + cachedMargin, fontsize, catColorA); - current_x += item_layout.label_width + layout.label_data_gap; - - // Draw data - //renderer->drawString(item.data_ptr, false, current_x, base_y + fontsize, fontsize, textColorA); - - if (settings.useDynamicColors) { - // Draw data with temperature gradient support - if (item.type == 0) { // CPU - std::string dataStr(item.data_ptr); - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realCPU_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realCPU_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - uint32_t renderX = current_x; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - renderX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, tempColor, a(settings.separatorColor)); - - if (!postTempPart.empty()) { - renderX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - } else if (item.type == 1) { // GPU - std::string dataStr(item.data_ptr); - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realGPU_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realGPU_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - uint32_t renderX = current_x; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - renderX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, tempColor, a(settings.separatorColor)); - - if (!postTempPart.empty()) { - renderX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - } else if (item.type == 2) { // RAM - std::string dataStr(item.data_ptr); - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realRAM_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realRAM_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - uint32_t renderX = current_x; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - renderX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, tempColor, a(settings.separatorColor)); - - if (!postTempPart.empty()) { - renderX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - } else if (item.type == 3) { // SOC temperature - // Parse SOC temperature: "XX°C (XX%)" - std::string dataStr(item.data_ptr); - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos) { - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; // Include the 'C' - - // Extract temperature value and apply gradient - const int temp = atoi(item.data_ptr); - const tsl::Color tempColor = tsl::GradientColor((float)temp); - - // Split into temperature part and remaining part - const std::string tempPart = dataStr.substr(0, tempEnd); - const std::string restPart = dataStr.substr(tempEnd); - - // Render temperature with gradient color - renderer->drawString(tempPart, false, current_x, base_y + cachedMargin, fontsize, tempColor); - - // Render remaining text with normal color - if (!restPart.empty()) { - const uint32_t tempPartWidth = renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(restPart, false, specialChars, current_x + tempPartWidth, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - // Fallback: render normally - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - // Fallback: render normally - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - } else if (item.type == 4) { // TMP multiple temperatures - // Parse TMP temperatures: "XX°C XX°C XX°C (XX%)" - std::string dataStr(item.data_ptr); - uint32_t renderX = current_x; - size_t pos = 0; - bool parseSuccess = true; - - // Parse up to 3 temperatures - for (int tempCount = 0; tempCount < 3 && parseSuccess && pos < dataStr.length(); tempCount++) { - // Skip any leading spaces - while (pos < dataStr.length() && dataStr[pos] == ' ') { - renderer->drawString(" ", false, renderX, base_y + cachedMargin, fontsize, textColorA); - renderX += renderer->getTextDimensions(" ", false, fontsize).first; - pos++; - } - - if (pos >= dataStr.length()) break; - - // Find degrees symbol - const size_t degreesPos = dataStr.find("°", pos); - if (degreesPos == std::string::npos) { - parseSuccess = false; - break; - } - - // Find 'C' after degrees symbol - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos == std::string::npos) { - parseSuccess = false; - break; - } - - const size_t tempEnd = cPos + 1; // Include the 'C' - - // Extract and render temperature with gradient - const std::string tempPart = dataStr.substr(pos, tempEnd - pos); - const int temp = atoi(tempPart.c_str()); - const tsl::Color tempColor = tsl::GradientColor((float)temp); - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, tempColor, a(settings.separatorColor)); - renderX += renderer->getTextDimensions(tempPart, false, fontsize).first; - - pos = tempEnd; - } - - // Render any remaining text (like " (50%)") - if (pos < dataStr.length()) { - const std::string restPart = dataStr.substr(pos); - renderer->drawStringWithColoredSections(restPart, false, specialChars, renderX, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - // If parsing failed, fall back to normal rendering - if (!parseSuccess) { - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - - } else { - // Normal rendering for all other item types - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } else { - // Normal rendering for all other item types - renderer->drawStringWithColoredSections(item.data_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - current_x += item_layout.data_width; - - // Draw voltage if present - if (item.has_voltage && item.volt_ptr) { - current_x += layout.volt_separator_gap; - renderer->drawString("", false, current_x, base_y + cachedMargin, fontsize, a(settings.separatorColor)); - //auto sep_width = renderer->drawString("", false, 0, 0, fontsize, renderer->a(0x0000)); - //auto sep_width = renderer->getTextDimensions("", fontsize); - current_x += sep_width + layout.volt_data_gap; - renderer->drawStringWithColoredSections(item.volt_ptr, false, specialChars, current_x, base_y + cachedMargin, fontsize, textColorA, a(settings.separatorColor)); - } - } - }); - - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("", ""); - rootFrame->setContent(Status); - return rootFrame; - } - - virtual void update() override { - if (triggerExitNow) - return; - - if (!SaltySD) { - SaltySD = CheckPort(); - - if (SaltySD) { - LoadSharedMemory(); - //Assign NX-FPS to default core - threadCreate(&t6, CheckIfGameRunning, NULL, NULL, 0x1000, 0x38, -2); - threadStart(&t6); - } - } - - //static bool triggerExit = false; - //if (triggerExit) { - // ult::setIniFileValue( - // ult::ULTRAHAND_CONFIG_INI_PATH, - // ult::ULTRAHAND_PROJECT_NAME, - // ult::IN_OVERLAY_STR, - // ult::FALSE_STR - // ); - // tsl::setNextOverlay( - // ult::OVERLAY_PATH + "ovlmenu.ovl" - // ); - // tsl::Overlay::get()->close(); - // return; - //} - - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - if (fontsize != settings.handheldFontSize) { - Initialized = false; - layout.calculated = false; // Recalculate layout for new font size - fontsize = settings.handheldFontSize; - } - } - else if (performanceMode == ApmPerformanceMode_Boost) { - if (fontsize != settings.dockedFontSize) { - Initialized = false; - layout.calculated = false; // Recalculate layout for new font size - fontsize = settings.dockedFontSize; - } - } - - // CPU usage calculations - optimized with fewer conditionals - const double inv_freq = 1.0 / systemtickfrequency_impl; - - // Capture systemtickfrequency_impl and inv_freq safely - const auto formatUsage = [this](char* buf, size_t size, uint64_t idletick, double inv_freq) { - if (idletick > systemtickfrequency_impl) { - strcpy(buf, "0%"); - } else { - snprintf(buf, size, "%.0f%%", (1.0 - (idletick * inv_freq)) * 100.0); - } - }; - - // Atomically load idle ticks before using them - const uint64_t idle0 = idletick0.load(std::memory_order_acquire); - const uint64_t idle1 = idletick1.load(std::memory_order_acquire); - const uint64_t idle2 = idletick2.load(std::memory_order_acquire); - const uint64_t idle3 = idletick3.load(std::memory_order_acquire); - - formatUsage(CPU_Usage0, sizeof(CPU_Usage0), idle0, inv_freq); - formatUsage(CPU_Usage1, sizeof(CPU_Usage1), idle1, inv_freq); - formatUsage(CPU_Usage2, sizeof(CPU_Usage2), idle2, inv_freq); - formatUsage(CPU_Usage3, sizeof(CPU_Usage3), idle3, inv_freq); - - mutexLock(&mutex_Misc); - - // CPU frequency and voltage - const char* cpuDiff = "@"; - if (realCPU_Hz) { - const int32_t deltaCPU = (int32_t)(realCPU_Hz / 1000) - (CPU_Hz / 1000); - cpuDiff = getDifferenceSymbol(deltaCPU); - } - - const uint32_t cpuFreq = settings.realFrequencies && realCPU_Hz ? realCPU_Hz : CPU_Hz; - - if (settings.showFullCPU) { - snprintf(CPU_compressed_c, sizeof(CPU_compressed_c), - "[%s,%s,%s,%s]%s%u.%u", - CPU_Usage0, CPU_Usage1, CPU_Usage2, CPU_Usage3, - cpuDiff, cpuFreq / 1000000, (cpuFreq / 100000) % 10); - } else { - // Find max CPU usage across all cores - const auto extractUsage = [](const char* usage_str) -> double { - return strtod(usage_str, nullptr); - }; - - const double usage0 = extractUsage(CPU_Usage0); - const double usage1 = extractUsage(CPU_Usage1); - const double usage2 = extractUsage(CPU_Usage2); - const double usage3 = extractUsage(CPU_Usage3); - - const double maxUsage = std::max({usage0, usage1, usage2, usage3}); - - snprintf(CPU_compressed_c, sizeof(CPU_compressed_c), - "%.0f%%%s%u.%u", - maxUsage, cpuDiff, cpuFreq / 1000000, (cpuFreq / 100000) % 10); - } - - if (settings.realTemps && realCPU_Temp != 0 && CPU_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", CPU_temp_c); - strncat(CPU_compressed_c, temp_buffer, sizeof(CPU_compressed_c) - strlen(CPU_compressed_c) - 1); - } - - //if (settings.realVolts) { - // snprintf(CPU_volt_c, sizeof(CPU_volt_c), "%u.%u mV", - // realCPU_mV/1000, (isMariko ? (realCPU_mV/100)%10 : (realCPU_mV/10)%100)); - //} - - /* ── CPU voltage ───────────────────────────── */ - if (settings.realVolts) { - const uint32_t mv = realCPU_mV / 1000; // µV → mV - snprintf(CPU_volt_c, sizeof(CPU_volt_c), "%u mV", mv); - } - - // GPU frequency and voltage - const char* gpuDiff = "@"; - if (realGPU_Hz) { - const int32_t deltaGPU = (int32_t)(realGPU_Hz / 1000) - (GPU_Hz / 1000); - gpuDiff = getDifferenceSymbol(deltaGPU); - } - - const uint32_t gpuFreq = settings.realFrequencies && realGPU_Hz ? realGPU_Hz : GPU_Hz; - snprintf(GPU_Load_c, sizeof(GPU_Load_c), - "%u%%%s%u.%u", - GPU_Load_u / 10, - gpuDiff, gpuFreq / 1000000, (gpuFreq / 100000) % 10); - - if (settings.realTemps && realGPU_Temp != 0 && GPU_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", GPU_temp_c); - strncat(GPU_Load_c, temp_buffer, sizeof(GPU_Load_c) - strlen(GPU_Load_c) - 1); - } - - //if (settings.realVolts) { - // snprintf(GPU_volt_c, sizeof(GPU_volt_c), "%u.%u mV", - // realGPU_mV/1000, (isMariko ? (realGPU_mV/100)%10 : (realGPU_mV/10)%100)); - //} - - // For properly handling sleep exit - if (settings.sleepExit) { - const auto GPU_Hz_int = int(GPU_Hz / 1000000); - static auto lastGPU_Hz_int = GPU_Hz_int; - if (GPU_Hz_int == 0 && lastGPU_Hz_int != 0) { - isRendering = false; - leventSignal(&renderingStopEvent); - - triggerExitNow = true; - return; - } - lastGPU_Hz_int = GPU_Hz_int; - } - - - /* ── GPU voltage ───────────────────────────── */ - if (settings.realVolts) { - const uint32_t mv = realGPU_mV / 1000; - snprintf(GPU_volt_c, sizeof(GPU_volt_c), "%u mV", mv); - } - - // RAM usage and frequency - char MICRO_RAM_all_c[16]; - if (!settings.showpartLoad) { - // User wants GB display - const float RAM_Total_all_f = (RAM_Total_application_u + RAM_Total_applet_u + RAM_Total_system_u + RAM_Total_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f); - const float RAM_Used_all_f = (RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f); - snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%.0f%.0fGB", RAM_Used_all_f, RAM_Total_all_f); - } else if (settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) { - // Bandwidth mode: show GB/s from context (partLoad values are in MB/s) - const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000; - const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100; - snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%u.%uGB/s", bwAll, bwAllD); - } else { - // User wants percentage display - if (R_SUCCEEDED(hocclkCheck)) { - // Use sys-clk's RAM load if available - snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%hu%%", - partLoad[HocClkPartLoad_EMC] / 10); - } else { - // Calculate percentage manually when sys-clk isn't available - const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u + RAM_Total_system_u + RAM_Total_systemunsafe_u; - const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u; - const unsigned partLoadPercent = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; - snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%u%%", partLoadPercent); - } - } - - const char* ramDiff = "@"; - if (realRAM_Hz) { - const int32_t deltaRAM = (int32_t)(realRAM_Hz / 1000) - (RAM_Hz / 1000); - ramDiff = getDifferenceSymbol(deltaRAM); - } - - const uint32_t ramFreq = settings.realFrequencies && realRAM_Hz ? realRAM_Hz : RAM_Hz; - snprintf(RAM_var_compressed_c, sizeof(RAM_var_compressed_c), - "%s%s%u.%u", MICRO_RAM_all_c, ramDiff, - ramFreq / 1000000, (ramFreq / 100000) % 10); - - if (settings.realTemps && realRAM_Temp != 0 && RAM_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", RAM_temp_c); - strncat(RAM_var_compressed_c, temp_buffer, sizeof(RAM_var_compressed_c) - strlen(RAM_var_compressed_c) - 1); - } - - //if (settings.realVolts) { - // uint32_t vdd2 = realRAM_mV / 10000; - // uint32_t vddq = realRAM_mV % 10000; - // if (isMariko) { - // snprintf(RAM_volt_c, sizeof(RAM_volt_c), "%u.%u%u.%u mV", - // vdd2/10, vdd2%10, vddq/10, vddq%10); - // } else { - // snprintf(RAM_volt_c, sizeof(RAM_volt_c), "%u.%u mV", vdd2/10, vdd2%10); - // } - //} - - /* ── RAM voltage ───────────────────────────── */ - if (settings.realVolts && (settings.showVDD2 || settings.showVDDQ)) { - /* realRAM_mV packs VDD2 | VDDQ in 10-µV units * - * → split, convert to mV - */ - const float mv_vdd2 = realVDD2_mV / 1000.0f; // VDD2 - const uint32_t mv_vddq = realVDDQ_mV / 1000; // VDDQ - - // Build voltage string based on settings - RAM_volt_c[0] = '\0'; // Start with empty string - char temp_buffer[16]; - - if (settings.showVDD2) { - if (settings.decimalVDD2) { - snprintf(temp_buffer, sizeof(temp_buffer), "%.1f mV", mv_vdd2); - } else { - snprintf(temp_buffer, sizeof(temp_buffer), "%u mV", (uint32_t)mv_vdd2); - } - strcat(RAM_volt_c, temp_buffer); - } - - if (settings.showVDDQ && isMariko) { - if (RAM_volt_c[0] != '\0') { - strcat(RAM_volt_c, ""); - } - snprintf(temp_buffer, sizeof(temp_buffer), "%u mV", mv_vddq); - strcat(RAM_volt_c, temp_buffer); - } - } else { - RAM_volt_c[0] = '\0'; // Empty if voltages disabled - } - - /* ── Battery / power draw ───────────────────────────── */ - char remainingBatteryLife[8]; - - /* Normalise “-0.00” → “0.00” W */ - const float drawW = (fabsf(PowerConsumption) < 0.01f) ? 0.0f - : PowerConsumption; - - mutexLock(&mutex_BatteryChecker); - - /* show a time only when the estimate is valid **and** draw ≥ 0.01 W */ - if (batTimeEstimate >= 0 && !(drawW <= 0.01f && drawW >= -0.01f)) { - snprintf(remainingBatteryLife, sizeof remainingBatteryLife, - "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } else { - strcpy(remainingBatteryLife, "--:--"); - } - - if (!settings.invertBatteryDisplay) { - snprintf(Battery_c, sizeof Battery_c, - "%.2f W%.1f%% [%s]", - drawW, - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife); - } else { - snprintf(Battery_c, sizeof Battery_c, - "%.1f%% [%s]%.2f W", - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife, - drawW); - } - - mutexUnlock(&mutex_BatteryChecker); - - - // Format current datetime for DTC - if (settings.showDTC) { - time_t rawtime = time(NULL); - struct tm *timeinfo = localtime(&rawtime); - strftime(DTC_c, sizeof(DTC_c), settings.dtcFormat.c_str(), timeinfo); - } - - // Thermal info - const int duty = safeFanDuty((int)Rotation_Duty); - - /* Integer SoC temperature + duty */ - snprintf(soc_temperature_c, sizeof soc_temperature_c, - "%d°C %d%%", - (int)SOC_temperatureF, // SoC °C, no decimals - duty); // fan % - - /* Integer SOC, PCB and skin temperatures + duty * - * skin_temperaturemiliC is in milli-degrees C → divide by 1000 */ - snprintf(skin_temperature_c, sizeof skin_temperature_c, - "%d°C %d°C %hu°C %d%%", - (int)SOC_temperatureF, // SoC - (int)PCB_temperatureF, // PCB - (uint16_t)(skin_temperaturemiliC / 1000), // skin - duty); - - //if (settings.realVolts) { - // snprintf(SOC_volt_c, sizeof(SOC_volt_c), "%u.%u mV", - // realSOC_mV/1000, (realSOC_mV/100)%10); - //} - - /* ── SoC voltage ───────────────────────────── */ - if (settings.realVolts && settings.showSOCVoltage) { - const uint32_t mv = realSOC_mV / 1000; - snprintf(SOC_volt_c, sizeof(SOC_volt_c), "%u mV", mv); - } else { - SOC_volt_c[0] = '\0'; // Clear the buffer when disabled - } - - if (settings.realTemps) { - if (realCPU_Temp != 0) { - snprintf(CPU_temp_c, sizeof(CPU_temp_c), "%u°C", static_cast(realCPU_Temp / 1000.0)); - } - if (realGPU_Temp != 0) { - snprintf(GPU_temp_c, sizeof(GPU_temp_c), "%u°C", static_cast(realGPU_Temp / 1000.0)); - } - if (realRAM_Temp != 0) { - snprintf(RAM_temp_c, sizeof(RAM_temp_c), "%u°C", static_cast(realRAM_Temp / 1000.0)); - } - } - - // Resolution processing - //char RES_var_compressed_c[32] = ""; - if (GameRunning && NxFps && resolutionShow) { - if (!resolutionLookup) { - if (NxFps && SharedMemoryUsed) { - (NxFps -> renderCalls[0].calls) = 0xFFFF; - resolutionLookup = 1; - } - } - else if (resolutionLookup == 1) { - if (NxFps && SharedMemoryUsed && (NxFps -> renderCalls[0].calls) != 0xFFFF) { - resolutionLookup = 2; - } - } - else { - if (NxFps && SharedMemoryUsed) { - memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls)); - memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls)); - } else { - memset(&m_resolutionRenderCalls, 0, sizeof(m_resolutionRenderCalls)); - memset(&m_resolutionViewportCalls, 0, sizeof(m_resolutionViewportCalls)); - } - qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare); - qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare); - memset(&m_resolutionOutput, 0, sizeof(m_resolutionOutput)); - size_t out_iter = 0; - bool found = false; - for (size_t i = 0; i < 8; i++) { - for (size_t x = 0; x < 8; x++) { - if (m_resolutionRenderCalls[i].width == 0) { - break; - } - if ((m_resolutionRenderCalls[i].width == m_resolutionViewportCalls[x].width) && (m_resolutionRenderCalls[i].height == m_resolutionViewportCalls[x].height)) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = (m_resolutionRenderCalls[i].calls > m_resolutionViewportCalls[x].calls) ? m_resolutionRenderCalls[i].calls : m_resolutionViewportCalls[x].calls; - out_iter++; - found = true; - break; - } - } - if (!found && m_resolutionRenderCalls[i].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = m_resolutionRenderCalls[i].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - if (out_iter < 8) { - const size_t out_iter_s = out_iter; - for (size_t x = 0; x < 8; x++) { - for (size_t y = 0; y < out_iter_s; y++) { - if (m_resolutionViewportCalls[x].width == 0) { - break; - } - if ((m_resolutionViewportCalls[x].width == m_resolutionOutput[y].width) && (m_resolutionViewportCalls[x].height == m_resolutionOutput[y].height)) { - found = true; - break; - } - } - if (!found && m_resolutionViewportCalls[x].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionViewportCalls[x].width; - m_resolutionOutput[out_iter].height = m_resolutionViewportCalls[x].height; - m_resolutionOutput[out_iter].calls = m_resolutionViewportCalls[x].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - } - qsort(m_resolutionOutput, 8, sizeof(resolutionCalls), compare); - - // Anti-flicker swap logic - static std::pair old_res[2]; - - // Only swap if BOTH resolutions exist (prevent swapping with empty slot) - if (m_resolutionOutput[0].width && m_resolutionOutput[1].width) { - if ((m_resolutionOutput[0].width == old_res[1].first && m_resolutionOutput[0].height == old_res[1].second) || - (m_resolutionOutput[1].width == old_res[0].first && m_resolutionOutput[1].height == old_res[0].second)) { - const uint16_t swap_width = m_resolutionOutput[0].width; - const uint16_t swap_height = m_resolutionOutput[0].height; - m_resolutionOutput[0].width = m_resolutionOutput[1].width; - m_resolutionOutput[0].height = m_resolutionOutput[1].height; - m_resolutionOutput[1].width = swap_width; - m_resolutionOutput[1].height = swap_height; - } - } - - // Format resolution string - if (m_resolutionOutput[0].width) { - if (settings.showFullResolution) { - if (!m_resolutionOutput[1].width) { - snprintf(RES_var_compressed_c, sizeof(RES_var_compressed_c), "%dx%d", - m_resolutionOutput[0].width, m_resolutionOutput[0].height); - } - else { - snprintf(RES_var_compressed_c, sizeof(RES_var_compressed_c), "%dx%d%dx%d", - m_resolutionOutput[0].width, m_resolutionOutput[0].height, - m_resolutionOutput[1].width, m_resolutionOutput[1].height); - } - } else { - if (!m_resolutionOutput[1].width) { - snprintf(RES_var_compressed_c, sizeof(RES_var_compressed_c), "%dp", - m_resolutionOutput[0].height); - } - else { - snprintf(RES_var_compressed_c, sizeof(RES_var_compressed_c), "%dp%dp", - m_resolutionOutput[0].height, m_resolutionOutput[1].height); - } - } - } - - // Always store current resolutions for next frame comparison - old_res[0] = std::make_pair(m_resolutionOutput[0].width, m_resolutionOutput[0].height); - old_res[1] = std::make_pair(m_resolutionOutput[1].width, m_resolutionOutput[1].height); - } - } - else if (!GameRunning && resolutionLookup != 0) { - resolutionLookup = 0; - } - - // FPS - snprintf(FPS_var_compressed_c, sizeof FPS_var_compressed_c, "%2.1f", useOldFPSavg ? FPSavg_old : FPSavg); - - - // Read Speed - if (GameRunning && NxFps && SharedMemoryUsed) { - float readSpeed = 0.0f; - memcpy(&readSpeed, &(NxFps->readSpeedPerSecond), sizeof(float)); - if (readSpeed != 0.f) { - snprintf(READ_var_compressed_c, sizeof(READ_var_compressed_c), "%.2f MiB/s", readSpeed / 1048576.f); - } else { - strcpy(READ_var_compressed_c, "n/d"); - } - } else { - strcpy(READ_var_compressed_c, "n/d"); - } - - mutexUnlock(&mutex_Misc); - - //static bool skipOnce = true; - - if (!skipOnce) { - //static bool runOnce = true; - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; // Add this to prevent repeated calls - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - //triggerRumbleDoubleClick.store(true, std::memory_order_release); - skipOnce = true; - runOnce = true; - //TeslaFPS = 60; - if (skipMain) { - //lastSelectedItem = "Micro"; - lastMode = "returning"; - //tsl::swapTo(); - tsl::goBack(); - } - else { - tsl::setNextOverlay(filepath.c_str(), "--lastSelectedItem Micro"); - tsl::Overlay::get()->close(); - } - return true; - } - return false; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Mini.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Mini.hpp deleted file mode 100644 index 5d97ccc1..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Mini.hpp +++ /dev/null @@ -1,1853 +0,0 @@ -class MainMenu; - -class MiniOverlay : public tsl::Gui { -private: - char GPU_Load_c[32] = ""; - char Rotation_SpeedLevel_c[64] = ""; - char RAM_var_compressed_c[128] = ""; - char Battery_c[64] = ""; - char soc_temperature_c[64] = ""; - char skin_temperature_c[64] = ""; - char CPU_temp_c[32]; - char GPU_temp_c[32]; - char RAM_temp_c[32]; - - uint32_t rectangleWidth; - char Variables[512]; - size_t fontsize; - MiniSettings settings; - bool Initialized = false; - ApmPerformanceMode performanceMode = ApmPerformanceMode_Invalid; - uint64_t systemtickfrequency_impl = systemtickfrequency; - int frameOffsetX, frameOffsetY; - int topPadding, bottomPadding; - bool isDragging = false; - - bool skipOnce = true; - bool runOnce = true; - - size_t framePadding = 10; - static constexpr int screenWidth = 1280; - static constexpr int screenHeight = 720; - - struct ButtonState { - std::atomic minusDragActive{false}; - std::atomic plusDragActive{false}; - } buttonState; - - Thread touchPollThread; - std::atomic touchPollRunning{false}; -public: - MiniOverlay() { - CPU_temp_c[0] = '\0'; - GPU_temp_c[0] = '\0'; - RAM_temp_c[0] = '\0'; - - tsl::hlp::requestForeground(false); - disableJumpTo = true; - //tsl::initializeUltrahandSettings(); - PowerConsumption = 0.0f; - batTimeEstimate = -1; - strcpy(Battery_c, "-.-- W-.-% [--:--]"); // Default display - - GetConfigSettings(&settings); - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - fontsize = settings.handheldFontSize; - } - else fontsize = settings.dockedFontSize; - - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - mutexInit(&mutex_BatteryChecker); - mutexInit(&mutex_Misc); - //alphabackground = 0x0; - frameOffsetX = settings.frameOffsetX; - frameOffsetY = settings.frameOffsetY; - framePadding = settings.framePadding; - topPadding = 5; - bottomPadding = 2; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - FullMode = false; - TeslaFPS = settings.refreshRate; - systemtickfrequency_impl /= settings.refreshRate; - deactivateOriginalFooter = true; - realVoltsPolling = settings.realVolts; - StartThreads(); - - // Get initial battery readings BEFORE starting threads - if (R_SUCCEEDED(psmCheck) && R_SUCCEEDED(i2cCheck)) { - uint16_t data = 0; - float tempA = 0.0; - - // Get initial power consumption - Max17050ReadReg(MAX17050_AvgCurrent, &data); - tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data; - PowerConsumption = tempA * batVoltageAvg / 1000000.0; // Rough initial estimate - - // Get initial battery info - psmGetBatteryChargeInfoFields(psmService, &_batteryChargeInfoFields); - - // Get initial time estimate - if (tempA >= 0) { - batTimeEstimate = -1; - } else { - Max17050ReadReg(MAX17050_TTE, &data); - const float batteryTimeEstimateInMinutes = (5.625 * data) / 60; - if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) { - batTimeEstimate = (99*60)+59; - } else { - batTimeEstimate = (int16_t)batteryTimeEstimateInMinutes; - } - } - } else { - // Fallback if checks failed - PowerConsumption = 0.0f; - batTimeEstimate = -1; - _batteryChargeInfoFields = {0}; - } - - // Now format the initial Battery_c string - char remainingBatteryLife[8]; - const float drawW = (fabsf(PowerConsumption) < 0.01f) ? 0.0f : PowerConsumption; - - if (batTimeEstimate >= 0 && !(drawW <= 0.01f && drawW >= -0.01f)) { - snprintf(remainingBatteryLife, sizeof(remainingBatteryLife), - "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } else { - strcpy(remainingBatteryLife, "--:--"); - } - - if (!settings.invertBatteryDisplay) { - snprintf(Battery_c, sizeof(Battery_c), - "%.2f W%.1f%% [%s]", - drawW, - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife); - } else { - snprintf(Battery_c, sizeof(Battery_c), - "%.1f%% [%s]%.2f W", - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife, - drawW); - } - - - - - // Start touch polling thread for instant response at low FPS - touchPollRunning.store(true, std::memory_order_release); - threadCreate(&touchPollThread, [](void* arg) -> void { - MiniOverlay* overlay = static_cast(arg); - - // Allow only Player 1 and handheld mode - const HidNpadIdType id_list[2] = { HidNpadIdType_No1, HidNpadIdType_Handheld }; - - // Configure HID system to only listen to these IDs - hidSetSupportedNpadIdType(id_list, 2); - - // Configure input for up to 2 supported controllers (P1 + Handheld) - padConfigureInput(2, HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt); - - // Initialize separate pad states for both controllers - PadState pad_p1; - PadState pad_handheld; - padInitialize(&pad_p1, HidNpadIdType_No1); - padInitialize(&pad_handheld, HidNpadIdType_Handheld); - - u64 minusHoldStart = 0; - u64 plusHoldStart = 0; - static constexpr u64 HOLD_THRESHOLD_NS = 500'000'000ULL; - - HidTouchScreenState state = {0}; - bool inputDetected; - size_t actualEntryCount; - - while (overlay->touchPollRunning.load(std::memory_order_acquire)) { - // Only poll when rendering and not dragging - { - inputDetected = false; - - // Check touch in bounds - if (hidGetTouchScreenStates(&state, 1) && state.count > 0) { - const int touchX = state.touches[0].x; - const int touchY = state.touches[0].y; - - // Calculate bounds (same logic as handleInput) - const uint32_t margin = (overlay->fontsize * 4); - const int overlayX = overlay->frameOffsetX; - const int overlayY = overlay->frameOffsetY; - const int overlayWidth = margin + overlay->rectangleWidth + (overlay->fontsize / 3); - - // Calculate height from Variables string - actualEntryCount = 1; - for (size_t i = 0; overlay->Variables[i] != '\0'; i++) { - if (overlay->Variables[i] == '\n') { - actualEntryCount++; - } - } - const int overlayHeight = ((overlay->fontsize + overlay->settings.spacing) * actualEntryCount) + - (overlay->fontsize / 3) + overlay->settings.spacing + - overlay->topPadding + overlay->bottomPadding; - - // Add touch padding - const int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = overlayWidth + (touchPadding * 2); - const int touchableHeight = overlayHeight + (touchPadding * 2); - - // Check if touch is within bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - inputDetected = true; - } - } - - // Poll buttons from both controllers - padUpdate(&pad_p1); - padUpdate(&pad_handheld); - //const u64 keysHeld_p1 = padGetButtons(&pad_p1); - //const u64 keysHeld_handheld = padGetButtons(&pad_handheld); - - // Combine input from both controllers - const u64 keysHeld = padGetButtons(&pad_p1) | padGetButtons(&pad_handheld); - const u64 now = armTicksToNs(armGetSystemTick()); - - // Track MINUS hold duration - if ((keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK)) { - if (minusHoldStart == 0) { - minusHoldStart = now; - } - if (now - minusHoldStart >= HOLD_THRESHOLD_NS) { - // Long enough to start drag - inputDetected = true; - overlay->buttonState.minusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - // Track PLUS hold duration - else if ((keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK)) { - if (plusHoldStart == 0) { - plusHoldStart = now; - } - if (now - plusHoldStart >= HOLD_THRESHOLD_NS) { - // Long enough to start drag - inputDetected = true; - overlay->buttonState.plusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - else { - minusHoldStart = plusHoldStart = 0; - overlay->buttonState.minusDragActive.exchange(false, std::memory_order_acq_rel); - overlay->buttonState.plusDragActive.exchange(false, std::memory_order_acq_rel); - } - - // Disable rendering on any input, re-enable when no input - static bool resetOnce = true; - if (inputDetected) { - if (resetOnce && isRendering) { - isRendering = false; - leventSignal(&renderingStopEvent); - resetOnce = false; - } - } else { - resetOnce = true; - } - } - - if (ult::limitedMemory) { - static auto lastUnderscanPixels = std::make_pair(0, 0); - - if (lastUnderscanPixels != tsl::impl::currentUnderscanPixels) { - for (int i = 0; i < 2; i++) { - tsl::gfx::Renderer::get().updateLayerSize(); - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(overlay->frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - lastUnderscanPixels = tsl::impl::currentUnderscanPixels; - } - - svcSleepThread(32000000ULL); // 32ms polling - } - }, this, NULL, 0x1000, 0x2B, -2); - threadStart(&touchPollThread); - } - ~MiniOverlay() { - // Stop touch polling thread - touchPollRunning.store(false, std::memory_order_release); - threadWaitForExit(&touchPollThread); - threadClose(&touchPollThread); - - CloseThreads(); - FullMode = true; - fixForeground = true; - //tsl::hlp::requestForeground(true); - //alphabackground = 0xD; - deactivateOriginalFooter = false; - } - - resolutionCalls m_resolutionRenderCalls[8] = {0}; - resolutionCalls m_resolutionViewportCalls[8] = {0}; - resolutionCalls m_resolutionOutput[8] = {0}; - uint8_t resolutionLookup = 0; - bool resolutionShow = false; - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - //static constexpr u16 frameWidth = 448; - - // Cache parsed settings and calculations - static std::vector showKeys; - static std::string lastShowSetting; - static bool needsRecalc = true; - static std::vector labelLines; // Store individual label lines - static std::string lastVariables; // Track changes in Variables content - static size_t entryCount = 0; - static uint32_t cachedHeight = 0; - static int cachedBaseX = 0, cachedBaseY = 0; - static bool lastGameRunning = false; // Track game state changes - - // Check if we need to recalculate due to content changes - const bool contentChanged = (std::string(Variables) != lastVariables) || - (GameRunning != lastGameRunning); - - // Only recalculate if settings changed or content changed - if (settings.show != lastShowSetting || !Initialized || contentChanged) { - showKeys.clear(); - - // Parse once and cache - size_t start = 0, end = 0; - const std::string& show = settings.show; - while ((end = show.find('+', start)) != std::string::npos) { - showKeys.emplace_back(show.substr(start, end - start)); - start = end + 1; - } - if (start < show.length()) { - showKeys.emplace_back(show.substr(start)); - } - - lastShowSetting = settings.show; - lastVariables = Variables; - lastGameRunning = GameRunning; - needsRecalc = true; - } - - // Initial width calculation (only once) - if (!Initialized) { - - rectangleWidth = 0; - //std::pair dimensions; - u32 width; - - for (const auto& key : showKeys) { - if (key == "CPU") { - //dimensions = renderer->drawString("[100%,100%,100%,100%]@4444.4", false, 0, 0, fontsize, renderer->a(0x0000)); - if (!settings.realVolts) { - if (settings.showFullCPU) - width = renderer->getTextDimensions("[100%,100%,100%,100%]@4444.4", false, fontsize).first; - else - width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first; - } else { - if (settings.showFullCPU) - width = renderer->getTextDimensions("[100%,100%,100%,100%]@4444.4444 mV", false, fontsize).first; - else - width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first; - } - if (settings.realTemps) { - width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first; - } - } else if (key == "RAM" && settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) { - width = renderer->getTextDimensions("99.9GB/s@4444.4", false, fontsize).first; - if (settings.realVolts) { - if (isMariko) { - if (settings.showVDD2 && settings.decimalVDD2 && settings.showVDDQ) - width += renderer->getTextDimensions("4444.4444 mV 4444 mV", false, fontsize).first; - else if (settings.showVDD2 && !settings.decimalVDD2 && settings.showVDDQ) - width += renderer->getTextDimensions("4444 mV 4444 mV", false, fontsize).first; - else if (settings.showVDD2 && settings.decimalVDD2) - width += renderer->getTextDimensions("4444.4 mV", false, fontsize).first; - else if (settings.showVDD2 && !settings.decimalVDD2) - width += renderer->getTextDimensions("4444 mV", false, fontsize).first; - else if (settings.showVDDQ) - width += renderer->getTextDimensions("4444 mV", false, fontsize).first; - } else { - if (settings.decimalVDD2) - width += renderer->getTextDimensions("4444.44 mV", false, fontsize).first; - else - width += renderer->getTextDimensions("4444 mV", false, fontsize).first; - } - } - if (settings.realTemps) { - width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first; - } - } else if (key == "GPU" || (key == "RAM" && settings.showpartLoad && R_SUCCEEDED(hocclkCheck))) { - //dimensions = renderer->drawString("100.0%@4444.4", false, 0, 0, fontsize, renderer->a(0x0000)); - - if (!settings.showpartLoadCPUGPU) { - if (!settings.realVolts) { - width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first; - } else { - width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first; - } - } else { - if (!settings.realVolts) { - width = renderer->getTextDimensions("100%[100%,100%]@4444.4", false, fontsize).first; - } else { - width = renderer->getTextDimensions("100%[100%,100%]@4444.4444 mV", false, fontsize).first; - } - } - if (settings.realTemps) { - width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first; - } - } else if (key == "RAM" && (!settings.showpartLoad || R_FAILED(hocclkCheck))) { - //dimensions = renderer->drawString("44444444MB@4444.4", false, 0, 0, fontsize, renderer->a(0x0000)); - if (!settings.realVolts) { - width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first; - if (settings.realTemps) { - width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first; - } - } else { - if (isMariko) { - if (settings.showVDD2 && settings.decimalVDD2 && settings.showVDDQ) - width = renderer->getTextDimensions("100%@4444.44444.4444 mV", false, fontsize).first; - else if (settings.showVDD2 && !settings.decimalVDD2 && settings.showVDDQ) - width = renderer->getTextDimensions("100%@4444.44444444 mV", false, fontsize).first; - else if (settings.showVDD2 && settings.decimalVDD2) - width = renderer->getTextDimensions("100%@4444.44444.4 mV", false, fontsize).first; - else if (settings.showVDD2 && !settings.decimalVDD2) - width = renderer->getTextDimensions("100%@4444.44444 mV", false, fontsize).first; - else if (settings.showVDDQ) - width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first; - } else { - if (settings.decimalVDD2) - width = renderer->getTextDimensions("100%@4444.44444.4 mV", false, fontsize).first; - else - width = renderer->getTextDimensions("100%@4444.44444 mV", false, fontsize).first; - } - } - } else if (key == "SOC") { // new block - if (!settings.realVolts) - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88°C (100%)", false, fontsize).first; - else - width = renderer->getTextDimensions("88°C", false, fontsize).first; - else - if (settings.showSOCVoltage) { - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88°C 100%444 mV", false, fontsize).first; - else - width = renderer->getTextDimensions("88°C444 mV", false, fontsize).first; - } else { - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88°C 100%", false, fontsize).first; - else - width = renderer->getTextDimensions("88°C", false, fontsize).first; - } - } else if (key == "TMP") { - //dimensions = renderer->drawString("88.8\u00B0C88.8\u00B0C88.8\u00B0C (100%)", false, 0, 0, fontsize, renderer->a(0x0000)); - if (!settings.realVolts) { - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C 100%", false, fontsize).first; - else - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C", false, fontsize).first; - } else { - if (settings.showSOCVoltage) { - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C 100%444 mV", false, fontsize).first; - else - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C444 mV", false, fontsize).first; - } else { - if (settings.showFanPercentage) - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C 100%", false, fontsize).first; - else - width = renderer->getTextDimensions("88\u00B0C 88\u00B0C 88\u00B0C", false, fontsize).first; - } - } - } else if (key == "BAT") { - //dimensions = renderer->drawString("-44.44 W100.0% [44:44]", false, 0, 0, fontsize, renderer->a(0x0000)); - width = renderer->getTextDimensions("-44.44 W100.0% [44:44]", false, fontsize).first; - } else if (key == "FPS") { - //dimensions = renderer->drawString("444.4", false, 0, 0, fontsize, renderer->a(0x0000)); - width = renderer->getTextDimensions("444.4", false, fontsize).first; - } else if (key == "RES") { - //dimensions = renderer->drawString("3840x21603840x2160", false, 0, 0, fontsize, renderer->a(0x0000)); - if (settings.showFullResolution) - width = renderer->getTextDimensions("3840x21603840x2160", false, fontsize).first; - else - width = renderer->getTextDimensions("2160p2160p", false, fontsize).first; - } else if (key == "READ") { - // Calculate width for read speed display - width = renderer->getTextDimensions("999.99 MiB/s", false, fontsize).first; - } else if (key == "MEM") { - // Calculate width for system memory display (System + divider + memory value) - const u32 memValueWidth = renderer->getTextDimensions("999.9 MB "+ult::FREE, false, fontsize).first; - const u32 dividerWidth = renderer->getTextDimensions(ult::DIVIDER_SYMBOL, false, fontsize).first; - const u32 systemWidth = renderer->getTextDimensions("System", false, fontsize).first; - width = memValueWidth + dividerWidth + systemWidth; - } else if (key == "DTC" && settings.showDTC) { - // Calculate width based on the datetime format - // Use multiple sample dates to ensure longest possible textual output - - char sampleDateTime[64]; - size_t maxWidth = 0; - - // Representative dates that produce long names in most locales - constexpr int testDays[][3] = { - {2025, 11, 26}, // Wednesday – longest weekday - {2025, 9, 30}, // September – long month - {2025, 12, 31}, // December – another long month - {2025, 2, 28}, // February – to cover locales where it's long - }; - - struct tm t = {}; - for (auto &d : testDays) { - - t.tm_year = d[0] - 1900; - t.tm_mon = d[1] - 1; - t.tm_mday = d[2]; - t.tm_hour = 23; - t.tm_min = 59; - t.tm_sec = 59; - mktime(&t); // normalize (sets weekday, etc.) - - strftime(sampleDateTime, sizeof(sampleDateTime), settings.dtcFormat.c_str(), &t); - const size_t w = renderer->getTextDimensions(std::string(sampleDateTime) + " ", false, fontsize).first; - if (w > maxWidth) - maxWidth = w; - } - - width = maxWidth; - - } else { - continue; - } - - if (rectangleWidth < width) { - rectangleWidth = width; - } - } - Initialized = true; - needsRecalc = true; - } - - // Recalculate layout when needed (including content changes) - if (needsRecalc) { - // Build label lines array for individual centering - labelLines.clear(); - entryCount = 0; - uint16_t flags = 0; - - bool shouldAdd; - std::string labelText; - for (const auto& key : showKeys) { - shouldAdd = false; - labelText = ""; - - if (key == "CPU" && !(flags & 1)) { - shouldAdd = true; - labelText = "CPU"; - flags |= 1; - } else if (key == "GPU" && !(flags & 2)) { - shouldAdd = true; - labelText = "GPU"; - flags |= 2; - } else if (key == "RAM" && !(flags & 4)) { - shouldAdd = true; - labelText = "RAM"; - flags |= 4; - } else if (key == "SOC" && !(flags & 8)) { - shouldAdd = true; - labelText = "SOC"; - flags |= 8; - } else if (key == "TMP" && !(flags & 16)) { - shouldAdd = true; - labelText = "TMP"; - flags |= 16; - } else if ((key == "BAT" || key == "DRAW") && !(flags & 32)) { - shouldAdd = true; - labelText = "BAT"; - flags |= 32; - } else if (key == "FPS" && !(flags & 64) && GameRunning) { - shouldAdd = true; - labelText = "FPS"; - flags |= 64; - } else if (key == "RES" && !(flags & 128) && GameRunning) { - shouldAdd = true; - labelText = "RES"; - flags |= 128; - resolutionShow = true; - } else if (key == "READ" && !(flags & 512) && GameRunning) { - shouldAdd = true; - labelText = "READ"; - flags |= 512; - } else if (key == "DTC" && !(flags & 256) && settings.showDTC) { - shouldAdd = true; - labelText = settings.useDTCSymbol ? "\uE007" : "DTC"; - flags |= 256; - } else if (key == "MEM" && !(flags & 1024)) { - shouldAdd = true; - labelText = "MEM"; - flags |= 1024; - } - - - if (shouldAdd) { - labelLines.push_back(labelText); - entryCount++; - - //if (settings.realVolts && key != "BAT" && key != "DRAW" && key != "FPS" && key != "RES") { - // labelLines.push_back(""); // Empty line for voltage info - // entryCount++; - //} - } - } - - // Calculate actual entry count from Variables string - size_t actualEntryCount = 1; // Start with 1 for the first line - for (size_t i = 0; Variables[i] != '\0'; i++) { - if (Variables[i] == '\n') { - actualEntryCount++; - } - } - - // Use the actual entry count for height calculation - cachedHeight = ((fontsize + settings.spacing) * actualEntryCount) + (fontsize / 3) + settings.spacing + topPadding + bottomPadding; - //const uint32_t margin = (fontsize * 4); - - cachedBaseX = 0; - cachedBaseY = 0; - - needsRecalc = false; - } - - // Fast rendering using cached values - const uint32_t margin = (fontsize * 4); - - // Draw background - const tsl::Color bgColor = !isDragging - ? settings.backgroundColor // full opacity - : settings.focusBackgroundColor; - - int clippingOffsetX = 0, clippingOffsetY = 0; - - int _frameOffsetX = ult::limitedMemory ? std::max(0, frameOffsetX - (1280-448)) : frameOffsetX; - - // Check X bounds and calculate clipping offset - if (cachedBaseX + _frameOffsetX < int(framePadding)) { - clippingOffsetX = framePadding - (cachedBaseX + _frameOffsetX); - } else if ((cachedBaseX + _frameOffsetX + margin + rectangleWidth + (fontsize / 3)) > screenWidth - framePadding) { - clippingOffsetX = (screenWidth - framePadding) - (cachedBaseX + _frameOffsetX + margin + rectangleWidth + (fontsize / 3)); - } - - // Check Y bounds and calculate clipping offset - if (cachedBaseY + frameOffsetY < int(framePadding)) { - clippingOffsetY = framePadding - (cachedBaseY + frameOffsetY); - } else if ((cachedBaseY + frameOffsetY + cachedHeight) > screenHeight - framePadding) { - clippingOffsetY = (screenHeight - framePadding) - (cachedBaseY + frameOffsetY + cachedHeight); - } - - // Apply to all drawing calls - renderer->drawRoundedRectSingleThreaded( - cachedBaseX + _frameOffsetX + clippingOffsetX, - cachedBaseY + frameOffsetY + clippingOffsetY, - margin + rectangleWidth + (fontsize / 3), - cachedHeight, - 16, - a(bgColor) - ); - - - // Split Variables into lines for individual positioning - std::vector variableLines; - const std::string variablesStr(Variables); - size_t start = 0; - size_t pos = 0; - while ((pos = variablesStr.find('\n', start)) != std::string::npos) { - variableLines.push_back(variablesStr.substr(start, pos - start)); - start = pos + 1; - } - if (start < variablesStr.length()) { - variableLines.push_back(variablesStr.substr(start)); - } - - // Draw each label and variable line individually - uint32_t currentY = cachedBaseY + fontsize + settings.spacing + topPadding; - size_t labelIndex = 0; - - static const std::vector specialChars = {""}; - static uint32_t labelWidth, labelCenterX; - static std::vector _variableLines; - if (!delayUpdate) - _variableLines = variableLines; - for (size_t i = 0; i < _variableLines.size() && labelIndex < labelLines.size(); i++) { - // Check for RES label without corresponding RES data - if (labelIndex < labelLines.size() && labelLines[labelIndex] == "RES") { - //const std::string& currentLine = _variableLines[i]; - // Check if this data line looks like resolution data (contains 'x' or 'p') - bool isResolutionData = m_resolutionOutput[0].width; - - if (!isResolutionData) { - // This is RES label but data isn't resolution data - skip the label - ++labelIndex; - // Don't increment i, so the current data line gets paired with the next label - --i; - continue; - } - } - - // Draw label (centered in label region) - if (!labelLines[labelIndex].empty()) { - labelWidth = renderer->getTextDimensions(labelLines[labelIndex], false, fontsize).first; - labelCenterX = cachedBaseX + (margin / 2) - (labelWidth / 2); - renderer->drawString(labelLines[labelIndex], false, labelCenterX + _frameOffsetX + clippingOffsetX, currentY + frameOffsetY + clippingOffsetY, fontsize, settings.catColor); - } - - // Determine rendering method based on label type - const std::string& currentLine = _variableLines[i]; - const int baseX = cachedBaseX + margin + _frameOffsetX + clippingOffsetX; - const int baseY = currentY + frameOffsetY + clippingOffsetY; - - if (settings.useDynamicColors) { - if (labelIndex < labelLines.size() && labelLines[labelIndex] == "CPU") { - std::string dataStr = currentLine; - - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realCPU_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realCPU_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - int currentX = baseX; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - currentX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, currentX, baseY, fontsize, tempColor, settings.separatorColor); - - if (!postTempPart.empty()) { - currentX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - } else if (labelIndex < labelLines.size() && labelLines[labelIndex] == "GPU") { - std::string dataStr = currentLine; - - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realGPU_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realGPU_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - int currentX = baseX; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - currentX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, currentX, baseY, fontsize, tempColor, settings.separatorColor); - - if (!postTempPart.empty()) { - currentX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - } else if (labelIndex < labelLines.size() && labelLines[labelIndex] == "RAM") { - std::string dataStr = currentLine; - - const size_t degreesPos = dataStr.find("°"); - if (degreesPos != std::string::npos && settings.realTemps && realRAM_Temp != 0) { - size_t tempStart = dataStr.rfind(' ', degreesPos); - if (tempStart != std::string::npos) { - tempStart++; - const size_t cPos = dataStr.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; - - const std::string preTempPart = dataStr.substr(0, tempStart); - const std::string tempPart = dataStr.substr(tempStart, tempEnd - tempStart); - const std::string postTempPart = dataStr.substr(tempEnd); - - const float temp = realRAM_Temp / 1000.0f; - const tsl::Color tempColor = tsl::GradientColor(temp); - - int currentX = baseX; - if (!preTempPart.empty()) { - renderer->drawStringWithColoredSections(preTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - currentX += renderer->getTextDimensions(preTempPart, false, fontsize).first; - } - - renderer->drawStringWithColoredSections(tempPart, false, specialChars, currentX, baseY, fontsize, tempColor, settings.separatorColor); - - if (!postTempPart.empty()) { - currentX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(postTempPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - } else if (labelIndex < labelLines.size() && labelLines[labelIndex] == "SOC") { - // SOC temperature rendering with gradient - const size_t degreesPos = currentLine.find("°"); - if (degreesPos != std::string::npos) { - // Find the 'C' after the degrees symbol - const size_t cPos = currentLine.find("C", degreesPos); - if (cPos != std::string::npos) { - const size_t tempEnd = cPos + 1; // Include the 'C' - - // Extract temperature value and apply gradient - const int temp = atoi(currentLine.c_str()); - const tsl::Color tempColor = tsl::GradientColor((float)temp); - - // Split into temperature part and remaining part - const std::string tempPart = currentLine.substr(0, tempEnd); - const std::string restPart = currentLine.substr(tempEnd); - - // Render temperature with gradient color - int currentX = baseX; - renderer->drawString(tempPart, false, currentX, baseY, fontsize, tempColor); - - // Render remaining text with normal color - if (!restPart.empty()) { - currentX += renderer->getTextDimensions(tempPart, false, fontsize).first; - renderer->drawStringWithColoredSections(restPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - // Fallback: no C found after degrees, render normally - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - // Fallback: no degrees symbol found, render normally - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - } else if (labelIndex < labelLines.size() && labelLines[labelIndex] == "TMP") { - // TMP multiple temperatures rendering with gradients - int currentX = baseX; - size_t pos = 0; - bool parseSuccess = true; - - // Parse up to 3 temperatures in the format "XX°C XX°C XX°C (XX%)" - for (int tempCount = 0; tempCount < 3 && parseSuccess && pos < currentLine.length(); tempCount++) { - // Find start of current temperature (skip any leading spaces) - while (pos < currentLine.length() && currentLine[pos] == ' ') { - renderer->drawString(" ", false, currentX, baseY, fontsize, settings.textColor); - currentX += renderer->getTextDimensions(" ", false, fontsize).first; - pos++; - } - - if (pos >= currentLine.length()) break; - - // Find degrees symbol - const size_t degreesPos = currentLine.find("°", pos); - if (degreesPos == std::string::npos) { - parseSuccess = false; - break; - } - - // Find 'C' after degrees symbol - const size_t cPos = currentLine.find("C", degreesPos); - if (cPos == std::string::npos) { - parseSuccess = false; - break; - } - - const size_t tempEnd = cPos + 1; // Include the 'C' - - // Extract and render temperature with gradient - const std::string tempPart = currentLine.substr(pos, tempEnd - pos); - const int temp = atoi(tempPart.c_str()); - const tsl::Color tempColor = tsl::GradientColor((float)temp); - - renderer->drawString(tempPart, false, currentX, baseY, fontsize, tempColor); - currentX += renderer->getTextDimensions(tempPart, false, fontsize).first; - - pos = tempEnd; - } - - // Render any remaining text (like " (50%)" or voltage info) - if (pos < currentLine.length()) { - std::string restPart = currentLine.substr(pos); - renderer->drawStringWithColoredSections(restPart, false, specialChars, currentX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - // If parsing failed, fall back to normal rendering - if (!parseSuccess) { - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else if (labelIndex < labelLines.size() && labelLines[labelIndex] == "MEM") { - // MEM memory rendering with gradient color - // Extract numeric value for color determination - float sysValue = 0.0f; - sscanf(currentLine.c_str(), "%f", &sysValue); - - // Determine unit from string - const bool isGB = (currentLine.find("GB") != std::string::npos); - const float sysValueMB = isGB ? (sysValue * 1024.0f) : sysValue; - - // Apply same color scheme as in drawMemoryWidget - tsl::Color sysColor = settings.textColor; - if (sysValueMB >= 9.0f) { - sysColor = settings.useDynamicColors ? tsl::healthyRamTextColor : settings.textColor; - } else if (sysValueMB >= 3.0f) { - sysColor = settings.useDynamicColors ? tsl::neutralRamTextColor : settings.textColor; - } else { - sysColor = settings.useDynamicColors ? tsl::badRamTextColor : settings.textColor; - } - - // Draw the memory value with color on the left - int currentX = baseX; - renderer->drawStringWithColoredSections(currentLine, false, specialChars, currentX, baseY, fontsize, sysColor, settings.separatorColor); - currentX += renderer->getTextDimensions(currentLine, false, fontsize).first; - - // Draw separator " | " - renderer->drawString(ult::DIVIDER_SYMBOL, false, currentX, baseY, fontsize, settings.separatorColor); - currentX += renderer->getTextDimensions(ult::DIVIDER_SYMBOL, false, fontsize).first; - - // Draw "System" on the right - renderer->drawString("System", false, currentX, baseY, fontsize, settings.textColor); - } else { - // Normal rendering for all other line types (CPU, GPU, RAM, BAT, FPS, RES, DTC) - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - } else { - // Normal rendering for all other line types (CPU, GPU, RAM, BAT, FPS, RES, DTC) - renderer->drawStringWithColoredSections(currentLine, false, specialChars, baseX, baseY, fontsize, settings.textColor, settings.separatorColor); - } - - currentY += fontsize + settings.spacing; - ++labelIndex; - } - }); - - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("", ""); - rootFrame->setContent(Status); - return rootFrame; - } - - virtual void update() override { - if (triggerExitNow) - return; - - if (!SaltySD) { - SaltySD = CheckPort(); - if (SaltySD) { - LoadSharedMemory(); - threadCreate(&t6, CheckIfGameRunning, NULL, NULL, 0x1000, 0x38, -2); - threadStart(&t6); - } - } - - // Handle performance mode changes - apmGetPerformanceMode(&performanceMode); - if (performanceMode == ApmPerformanceMode_Normal) { - if (fontsize != settings.handheldFontSize) { - Initialized = false; - fontsize = settings.handheldFontSize; - } - } - else if (performanceMode == ApmPerformanceMode_Boost) { - if (fontsize != settings.dockedFontSize) { - Initialized = false; - fontsize = settings.dockedFontSize; - } - } - - // Parse show settings to determine what to calculate - std::vector showKeys; - { - size_t start = 0, end = 0; - const std::string& show = settings.show; - while ((end = show.find('+', start)) != std::string::npos) { - showKeys.emplace_back(show.substr(start, end - start)); - start = end + 1; - } - if (start < show.length()) { - showKeys.emplace_back(show.substr(start)); - } - } - - // Helper to check if a key is active - static auto isActive = [&showKeys](const std::string& key) { - return std::find(showKeys.begin(), showKeys.end(), key) != showKeys.end(); - }; - - mutexLock(&mutex_Misc); - - // Variables to store formatted strings - char MINI_CPU_compressed_c[42] = ""; - char MINI_CPU_volt_c[16] = ""; - char MINI_GPU_Load_c[32] = ""; - char MINI_GPU_volt_c[20] = ""; - char MINI_RAM_var_compressed_c[35] = ""; - char MINI_RAM_volt_c[32] = ""; - char MINI_MEM_RAM_c[32] = ""; - char MINI_SOC_volt_c[16] = ""; - - // Only process CPU if needed - if (isActive("CPU")) { - char MINI_CPU_Usage0[7], MINI_CPU_Usage1[7], MINI_CPU_Usage2[7], MINI_CPU_Usage3[7]; - - const uint64_t idle0 = idletick0.load(std::memory_order_acquire); - const uint64_t idle1 = idletick1.load(std::memory_order_acquire); - const uint64_t idle2 = idletick2.load(std::memory_order_acquire); - const uint64_t idle3 = idletick3.load(std::memory_order_acquire); - - auto formatMiniUsage = [this](char* buf, size_t size, uint64_t idletick) { - if (idletick > systemtickfrequency_impl) { - strcpy(buf, "0%"); - } else { - snprintf(buf, size, "%.0f%%", - (1.0 - (static_cast(idletick) / systemtickfrequency_impl)) * 100.0); - } - }; - - formatMiniUsage(MINI_CPU_Usage0, sizeof(MINI_CPU_Usage0), idle0); - formatMiniUsage(MINI_CPU_Usage1, sizeof(MINI_CPU_Usage1), idle1); - formatMiniUsage(MINI_CPU_Usage2, sizeof(MINI_CPU_Usage2), idle2); - formatMiniUsage(MINI_CPU_Usage3, sizeof(MINI_CPU_Usage3), idle3); - - if (settings.showFullCPU) { - if (settings.realFrequencies && realCPU_Hz) { - snprintf(MINI_CPU_compressed_c, sizeof(MINI_CPU_compressed_c), - "[%s,%s,%s,%s]@%hu.%hhu", - MINI_CPU_Usage0, MINI_CPU_Usage1, MINI_CPU_Usage2, MINI_CPU_Usage3, - realCPU_Hz / 1000000, (realCPU_Hz / 100000) % 10); - } else { - snprintf(MINI_CPU_compressed_c, sizeof(MINI_CPU_compressed_c), - "[%s,%s,%s,%s]@%hu.%hhu", - MINI_CPU_Usage0, MINI_CPU_Usage1, MINI_CPU_Usage2, MINI_CPU_Usage3, - CPU_Hz / 1000000, (CPU_Hz / 100000) % 10); - } - } else { - double usage0 = 0, usage1 = 0, usage2 = 0, usage3 = 0; - sscanf(MINI_CPU_Usage0, "%lf%%", &usage0); - sscanf(MINI_CPU_Usage1, "%lf%%", &usage1); - sscanf(MINI_CPU_Usage2, "%lf%%", &usage2); - sscanf(MINI_CPU_Usage3, "%lf%%", &usage3); - - double maxUsage = std::max({usage0, usage1, usage2, usage3}); - - if (settings.realFrequencies && realCPU_Hz) { - snprintf(MINI_CPU_compressed_c, sizeof(MINI_CPU_compressed_c), - "%.0f%%@%hu.%hhu", maxUsage, - realCPU_Hz / 1000000, (realCPU_Hz / 100000) % 10); - } else { - snprintf(MINI_CPU_compressed_c, sizeof(MINI_CPU_compressed_c), - "%.0f%%@%hu.%hhu", maxUsage, - CPU_Hz / 1000000, (CPU_Hz / 100000) % 10); - } - } - - if (settings.realVolts) { - const uint32_t mv = realCPU_mV / 1000; - snprintf(MINI_CPU_volt_c, sizeof(MINI_CPU_volt_c), "%u mV", mv); - } - } - - if (settings.realTemps && realCPU_Temp != 0 && CPU_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", CPU_temp_c); - strncat(MINI_CPU_compressed_c, temp_buffer, sizeof(MINI_CPU_compressed_c) - strlen(MINI_CPU_compressed_c) - 1); - } - - // Only process GPU if needed - if (isActive("GPU")) { - if (settings.realFrequencies && realGPU_Hz) { - snprintf(MINI_GPU_Load_c, sizeof(MINI_GPU_Load_c), - "%hu%%%s%hu.%hhu", - GPU_Load_u / 10, "@", - realGPU_Hz / 1000000, (realGPU_Hz / 100000) % 10); - } else { - snprintf(MINI_GPU_Load_c, sizeof(MINI_GPU_Load_c), - "%hu%%%s%hu.%hhu", - GPU_Load_u / 10, "@", - GPU_Hz / 1000000, (GPU_Hz / 100000) % 10); - } - - // Handle sleep exit - if (settings.sleepExit) { - const auto GPU_Hz_int = int(GPU_Hz / 1000000); - static auto lastGPU_Hz_int = GPU_Hz_int; - if (GPU_Hz_int == 0 && lastGPU_Hz_int != 0) { - isRendering = false; - leventSignal(&renderingStopEvent); - triggerExitNow = true; - mutexUnlock(&mutex_Misc); - return; - } - lastGPU_Hz_int = GPU_Hz_int; - } - - if (settings.realVolts) { - const uint32_t mv = realGPU_mV / 1000; - snprintf(MINI_GPU_volt_c, sizeof(MINI_GPU_volt_c), "%u mV", mv); - } - } - - if (settings.realTemps && realGPU_Temp != 0 && GPU_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", GPU_temp_c); - strncat(MINI_GPU_Load_c, temp_buffer, sizeof(MINI_GPU_Load_c) - strlen(MINI_GPU_Load_c) - 1); - } - - // Only process RAM if needed - if (isActive("RAM")) { - if (!settings.showpartLoad) { - const float ramTotalGiB = (RAM_Total_application_u + RAM_Total_applet_u + - RAM_Total_system_u + RAM_Total_systemunsafe_u) / - (1024.0f * 1024.0f); - const float ramUsedGiB = (RAM_Used_application_u + RAM_Used_applet_u + - RAM_Used_system_u + RAM_Used_systemunsafe_u) / - (1024.0f * 1024.0f); - - if (settings.realFrequencies && realRAM_Hz) { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%.0f/%.0fMB@%hu.%hhu", - ramUsedGiB, ramTotalGiB, - realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); - } else { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%.0f/%.0fMB@%hu.%hhu", - ramUsedGiB, ramTotalGiB, - RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); - } - } else { - if (settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) { - // Bandwidth mode: show GB/s from context (partLoad values are in MB/s) - const uint32_t ramFreq = settings.realFrequencies && realRAM_Hz ? realRAM_Hz : RAM_Hz; - const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000; - const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100; - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u.%uGB/s@%hu.%hhu", - bwAll, bwAllD, - ramFreq / 1000000, (ramFreq / 100000) % 10); - } else { - unsigned partLoadInt; - - if (R_SUCCEEDED(hocclkCheck)) { - partLoadInt = partLoad[HocClkPartLoad_EMC] / 10; - - if (settings.showpartLoadCPUGPU) { - unsigned ramCpuLoadInt = partLoad[HocClkPartLoad_EMCCpu] / 10; - int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu]; - unsigned ramGpuLoadInt = RAM_GPU_Load / 10; - - if (settings.realFrequencies && realRAM_Hz) { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%[%u%%,%u%%]@%hu.%hhu", - partLoadInt, ramCpuLoadInt, ramGpuLoadInt, - realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); - } else { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%[%u%%,%u%%]@%hu.%hhu", - partLoadInt, ramCpuLoadInt, ramGpuLoadInt, - RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); - } - } else { - if (settings.realFrequencies && realRAM_Hz) { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", partLoadInt, - realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); - } else { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", partLoadInt, - RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); - } - } - } else { - const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u + - RAM_Total_system_u + RAM_Total_systemunsafe_u; - const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u + - RAM_Used_system_u + RAM_Used_systemunsafe_u; - partLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; - - if (settings.realFrequencies && realRAM_Hz) { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", partLoadInt, - realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); - } else { - snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", partLoadInt, - RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); - } - } - } - } - - if (settings.realVolts) { - const float mv_vdd2_f = realVDD2_mV / 1000.0f; // VDD2 - const uint32_t mv_vddq = realVDDQ_mV / 1000; // VDDQ - const uint32_t mv_vdd2_i = realVDD2_mV / 1000; - - if (isMariko) { - if (settings.showVDDQ && settings.showVDD2) { - if (settings.decimalVDD2) - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), - "%.1f mV%u mV", mv_vdd2_f, mv_vddq); - else - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), - "%u mV%u mV", mv_vdd2_i, mv_vddq); - } else if (settings.showVDDQ) { - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), "%u mV", mv_vddq); - } else if (settings.showVDD2) { - if (settings.decimalVDD2) - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), "%.1f mV", mv_vdd2_f); - else - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), "%u mV", mv_vdd2_i); - } - } else { - if (settings.decimalVDD2) - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), "%.1f mV", mv_vdd2_f); - else - snprintf(MINI_RAM_volt_c, sizeof(MINI_RAM_volt_c), "%u mV", mv_vdd2_i); - } - } - } - - if (settings.realTemps && realRAM_Temp != 0 && RAM_temp_c[0] != '\0') { - char temp_buffer[48]; - snprintf(temp_buffer, sizeof(temp_buffer), " %s", RAM_temp_c); - strncat(MINI_RAM_var_compressed_c, temp_buffer, sizeof(MINI_RAM_var_compressed_c) - strlen(MINI_RAM_var_compressed_c) - 1); - } - - // Only process MEM if needed - if (isActive("MEM")) { - const u64 freeRamBytes = RAM_Total_system_u - RAM_Used_system_u; - - float value; - const char* unit; - - if (freeRamBytes >= 1024ULL * 1024 * 1024) { - value = static_cast(freeRamBytes) / (1024.0f * 1024.0f * 1024.0f); - unit = "GB"; - } else { - value = static_cast(freeRamBytes) / (1024.0f * 1024.0f); - unit = "MB"; - } - - int decimalPlaces; - if (value >= 1000.0f) { - decimalPlaces = 0; - } else if (value >= 100.0f) { - decimalPlaces = 1; - } else if (value >= 10.0f) { - decimalPlaces = 2; - } else { - decimalPlaces = 3; - } - - snprintf(MINI_MEM_RAM_c, sizeof(MINI_MEM_RAM_c), "%.*f %s %s", - decimalPlaces, value, unit, ult::FREE.c_str()); - } - - // Only process temperature/fan data if SOC or TMP is active - if (isActive("TMP") || isActive("SOC")) { - const int duty = safeFanDuty((int)Rotation_Duty); - - if (settings.realVolts && settings.showSOCVoltage) { - const uint32_t mv = realSOC_mV / 1000; - snprintf(MINI_SOC_volt_c, sizeof(MINI_SOC_volt_c), "%u mV", mv); - } - - if (isActive("SOC")) { - if (settings.showFanPercentage) { - snprintf(soc_temperature_c, sizeof(soc_temperature_c), - "%d°C %d%%", (int)SOC_temperatureF, duty); - } else { - snprintf(soc_temperature_c, sizeof(soc_temperature_c), - "%d°C", (int)SOC_temperatureF); - } - } - - if (isActive("TMP")) { - if (settings.showFanPercentage) { - snprintf(skin_temperature_c, sizeof(skin_temperature_c), - "%d\u00B0C %d\u00B0C %hu\u00B0C %d%%", - (int)SOC_temperatureF, (int)PCB_temperatureF, - skin_temperaturemiliC / 1000, duty); - } else { - snprintf(skin_temperature_c, sizeof(skin_temperature_c), - "%d\u00B0C %d\u00B0C %hu\u00B0C", - (int)SOC_temperatureF, (int)PCB_temperatureF, - skin_temperaturemiliC / 1000); - } - } - } - - if (settings.realTemps) { - if (realCPU_Temp != 0) { - snprintf(CPU_temp_c, sizeof(CPU_temp_c), "%u°C", static_cast(realCPU_Temp / 1000.0)); - } - if (realGPU_Temp != 0) { - snprintf(GPU_temp_c, sizeof(GPU_temp_c), "%u°C", static_cast(realGPU_Temp / 1000.0)); - } - if (realRAM_Temp != 0) { - snprintf(RAM_temp_c, sizeof(RAM_temp_c), "%u°C", static_cast(realRAM_Temp / 1000.0)); - } - } - - // Only process resolution if RES is active and game is running - if (isActive("RES") && GameRunning && NxFps) { - if (!resolutionLookup) { - (NxFps->renderCalls[0].calls) = 0xFFFF; - resolutionLookup = 1; - } else if (resolutionLookup == 1) { - if ((NxFps->renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2; - } else { - memcpy(&m_resolutionRenderCalls, &(NxFps->renderCalls), sizeof(m_resolutionRenderCalls)); - memcpy(&m_resolutionViewportCalls, &(NxFps->viewportCalls), sizeof(m_resolutionViewportCalls)); - qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare); - qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare); - memset(&m_resolutionOutput, 0, sizeof(m_resolutionOutput)); - size_t out_iter = 0; - bool found = false; - for (size_t i = 0; i < 8; i++) { - for (size_t x = 0; x < 8; x++) { - if (m_resolutionRenderCalls[i].width == 0) break; - if ((m_resolutionRenderCalls[i].width == m_resolutionViewportCalls[x].width) && - (m_resolutionRenderCalls[i].height == m_resolutionViewportCalls[x].height)) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = (m_resolutionRenderCalls[i].calls > m_resolutionViewportCalls[x].calls) - ? m_resolutionRenderCalls[i].calls : m_resolutionViewportCalls[x].calls; - out_iter++; - found = true; - break; - } - } - if (!found && m_resolutionRenderCalls[i].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionRenderCalls[i].width; - m_resolutionOutput[out_iter].height = m_resolutionRenderCalls[i].height; - m_resolutionOutput[out_iter].calls = m_resolutionRenderCalls[i].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - if (out_iter < 8) { - const size_t out_iter_s = out_iter; - for (size_t x = 0; x < 8; x++) { - for (size_t y = 0; y < out_iter_s; y++) { - if (m_resolutionViewportCalls[x].width == 0) break; - if ((m_resolutionViewportCalls[x].width == m_resolutionOutput[y].width) && - (m_resolutionViewportCalls[x].height == m_resolutionOutput[y].height)) { - found = true; - break; - } - } - if (!found && m_resolutionViewportCalls[x].width != 0) { - m_resolutionOutput[out_iter].width = m_resolutionViewportCalls[x].width; - m_resolutionOutput[out_iter].height = m_resolutionViewportCalls[x].height; - m_resolutionOutput[out_iter].calls = m_resolutionViewportCalls[x].calls; - out_iter++; - } - found = false; - if (out_iter == 8) break; - } - } - qsort(m_resolutionOutput, 8, sizeof(resolutionCalls), compare); - } - } else if (!GameRunning && resolutionLookup != 0) { - resolutionLookup = 0; - } - - mutexUnlock(&mutex_Misc); - - // Battery/power draw - always update since BAT/DRAW might be displayed - if (isActive("BAT") || isActive("DRAW")) { - char remainingBatteryLife[8]; - const float drawW = (fabsf(PowerConsumption) < 0.01f) ? 0.0f : PowerConsumption; - - mutexLock(&mutex_BatteryChecker); - - if (batTimeEstimate >= 0 && !(drawW <= 0.01f && drawW >= -0.01f)) { - snprintf(remainingBatteryLife, sizeof(remainingBatteryLife), - "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60); - } else { - strcpy(remainingBatteryLife, "--:--"); - } - - if (!settings.invertBatteryDisplay) { - snprintf(Battery_c, sizeof(Battery_c), - "%.2f W%.1f%% [%s]", - drawW, - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife); - } else { - snprintf(Battery_c, sizeof(Battery_c), - "%.1f%% [%s]%.2f W", - (float)_batteryChargeInfoFields.RawBatteryCharge / 1000.0f, - remainingBatteryLife, - drawW); - } - - mutexUnlock(&mutex_BatteryChecker); - } - - // Build Variables string - char Temp[512] = ""; - uint16_t flags = 0; - - for (const auto& key : showKeys) { - if (key == "CPU" && !(flags & 1)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, MINI_CPU_compressed_c); - if (settings.realVolts && MINI_CPU_volt_c[0]) { - strcat(Temp, ""); - strcat(Temp, MINI_CPU_volt_c); - } - flags |= 1; - } - else if (key == "GPU" && !(flags & 2)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, MINI_GPU_Load_c); - if (settings.realVolts && MINI_GPU_volt_c[0]) { - strcat(Temp, ""); - strcat(Temp, MINI_GPU_volt_c); - } - flags |= 2; - } - else if (key == "RAM" && !(flags & 4)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, MINI_RAM_var_compressed_c); - if (settings.realVolts && MINI_RAM_volt_c[0]) { - strcat(Temp, ""); - strcat(Temp, MINI_RAM_volt_c); - } - flags |= 4; - } - else if (key == "SOC" && !(flags & 8)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, soc_temperature_c); - if (settings.realVolts && settings.showSOCVoltage && MINI_SOC_volt_c[0]) { - strcat(Temp, ""); - strcat(Temp, MINI_SOC_volt_c); - } - flags |= 8; - } - else if (key == "TMP" && !(flags & 16)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, skin_temperature_c); - if (settings.realVolts && settings.showSOCVoltage && MINI_SOC_volt_c[0]) { - strcat(Temp, ""); - strcat(Temp, MINI_SOC_volt_c); - } - flags |= 16; - } - else if ((key == "BAT" || key == "DRAW") && !(flags & 32)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, Battery_c); - flags |= 32; - } - else if (key == "FPS" && !(flags & 64) && GameRunning) { - if (Temp[0]) strcat(Temp, "\n"); - char Temp_s[24]; - snprintf(Temp_s, sizeof(Temp_s), "%2.1f [%2.1f - %2.1f]", FPSavg, FPSmin, FPSmax); - strcat(Temp, Temp_s); - flags |= 64; - } - else if (key == "RES" && !(flags & 128) && GameRunning && m_resolutionOutput[0].width) { - if (Temp[0]) strcat(Temp, "\n"); - char Temp_s[32] = ""; - static std::pair old_res[2]; - - uint16_t w0 = m_resolutionOutput[0].width; - uint16_t h0 = m_resolutionOutput[0].height; - uint16_t w1 = m_resolutionOutput[1].width; - uint16_t h1 = m_resolutionOutput[1].height; - - if (w0 || w1) { - if (w0 && w1) { - if ((w0 == old_res[1].first && h0 == old_res[1].second) || - (w1 == old_res[0].first && h1 == old_res[0].second)) { - std::swap(w0, w1); - std::swap(h0, h1); - } - } - - - // Format based on whether we show full resolution or just height (p) - if (settings.showFullResolution) { - if (!w1 || !h1) - snprintf(Temp_s, sizeof(Temp_s), "%dx%d", w0 ? w0 : w1, h0 ? h0 : h1); - else - snprintf(Temp_s, sizeof(Temp_s), "%dx%d%dx%d", w0, h0, w1, h1); - } else { - if (!w1 || !h1) - snprintf(Temp_s, sizeof(Temp_s), "%dp", h0 ? h0 : h1); - else - snprintf(Temp_s, sizeof(Temp_s), "%dp%dp", h0, h1); - } - - // Update last-frame cache - old_res[0] = {m_resolutionOutput[0].width, m_resolutionOutput[0].height}; - old_res[1] = {m_resolutionOutput[1].width, m_resolutionOutput[1].height}; - - strcat(Temp, Temp_s); - flags |= 128; - } - } - else if (key == "READ" && !(flags & 512) && GameRunning && NxFps) { - if (Temp[0]) strcat(Temp, "\n"); - char Temp_s[24]; - if ((NxFps->readSpeedPerSecond) != 0.f) { - snprintf(Temp_s, sizeof(Temp_s), "%.2f MiB/s", (NxFps->readSpeedPerSecond) / 1048576.f); - } else { - strcpy(Temp_s, "n/d"); - } - strcat(Temp, Temp_s); - flags |= 512; - } - else if (key == "DTC" && !(flags & 256) && settings.showDTC) { - if (Temp[0]) strcat(Temp, "\n"); - char dateTimeStr[64]; - time_t rawtime = time(NULL); - struct tm *timeinfo = localtime(&rawtime); - strftime(dateTimeStr, sizeof(dateTimeStr), settings.dtcFormat.c_str(), timeinfo); - strcat(Temp, dateTimeStr); - flags |= 256; - } - else if (key == "MEM" && !(flags & 1024)) { - if (Temp[0]) strcat(Temp, "\n"); - strcat(Temp, MINI_MEM_RAM_c); - flags |= 1024; - } - } - - strcpy(Variables, Temp); - - // Enable rendering if needed - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - // Static variables to maintain drag state between function calls - static bool oldTouchDetected = false; - static bool oldMinusHeld = false; - static bool oldPlusHeld = false; - - static HidTouchState initialTouchPos = {0}; - static int initialFrameOffsetX = 0; - static int initialFrameOffsetY = 0; - static constexpr int TOUCH_THRESHOLD = 8; - static bool hasMoved = false; - //static u64 lastTouchTime = 0; - //static constexpr u64 TOUCH_DEBOUNCE_NS = 16000000ULL; // 16ms debounce - - // Get current time for debouncing - //const u64 currentTime = armTicksToNs(armGetSystemTick()); - - // Better touch detection - check if coordinates are within reasonable screen bounds - const bool currentTouchDetected = (touchPos.x > 0 && touchPos.y > 0 && - touchPos.x < screenWidth && touchPos.y < screenHeight); - - // Debounce touch detection - //if (currentTouchDetected && !oldTouchDetected) { - // if (currentTime - lastTouchTime < TOUCH_DEBOUNCE_NS) { - // currentTouchDetected = false; // Ignore rapid touch changes - // } else { - // lastTouchTime = currentTime; - // } - //} - - static bool clearOnRelease = false; - - if (clearOnRelease && !isRendering) { - clearOnRelease = false; - isRendering = true; - leventClear(&renderingStopEvent); - } - - // Calculate overlay bounds - const uint32_t margin = (fontsize * 4); - - // Cache bounds calculation - static int cachedBaseX = 0; - static int cachedBaseY = 0; - static uint32_t cachedOverlayHeight = 0; - static bool boundsNeedUpdate = true; - static std::string lastVariables = ""; - - // Only recalculate bounds when Variables change or first time - if (boundsNeedUpdate || std::string(Variables) != lastVariables) { - // Calculate actual entry count from Variables string - size_t actualEntryCount = 1; - for (size_t i = 0; Variables[i] != '\0'; i++) { - if (Variables[i] == '\n') { - actualEntryCount++; - } - } - - cachedOverlayHeight = ((fontsize + settings.spacing) * actualEntryCount) + - (fontsize / 3) + settings.spacing + topPadding + bottomPadding; - - // Position calculation based on settings - cachedBaseX = 0; - cachedBaseY = 0; - - boundsNeedUpdate = false; - lastVariables = Variables; - } - - const int overlayX = frameOffsetX;//ult::limitedMemory ? cachedBaseX + std::max(0, frameOffsetX - (1280-448)) : cachedBaseX + frameOffsetX; - const int overlayY = cachedBaseY + frameOffsetY; - const int overlayWidth = margin + rectangleWidth + (fontsize / 3); - const int overlayHeight = cachedOverlayHeight; - - // Add padding to make touch detection more forgiving - static constexpr int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = overlayWidth + (touchPadding * 2); - const int touchableHeight = overlayHeight + (touchPadding * 2); - - // Screen boundaries for clamping - const int minX = -cachedBaseX + framePadding; - const int maxX = screenWidth - overlayWidth - cachedBaseX - framePadding; - const int minY = -cachedBaseY + framePadding; - const int maxY = screenHeight - overlayHeight - cachedBaseY - framePadding; - - const bool minusDragReady = buttonState.minusDragActive.load(std::memory_order_acquire); - const bool plusDragReady = buttonState.plusDragActive.load(std::memory_order_acquire); - - // Check button states - const bool currentMinusHeld = (keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK) && minusDragReady; - const bool currentPlusHeld = (keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK) && plusDragReady; - - // Handle touch dragging - if (currentTouchDetected && !isDragging) { - // Touch detected and not currently dragging - check if we should start - const int touchX = touchPos.x; - const int touchY = touchPos.y; - - if (!oldTouchDetected) { - // Touch just started - check if within overlay bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - - // Start touch dragging - isDragging = true; - //isRendering = false; - //leventSignal(&renderingStopEvent); - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - hasMoved = false; - initialTouchPos = touchPos; - initialFrameOffsetX = frameOffsetX; - initialFrameOffsetY = frameOffsetY; - } - } - } else if (currentTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Continue touch dragging (only if neither MINUS nor PLUS is held) - const int touchX = touchPos.x; - const int touchY = touchPos.y; - const int deltaX = touchX - initialTouchPos.x; - const int deltaY = touchY - initialTouchPos.y; - - // Check if we've moved enough to consider this a drag - if (!hasMoved) { - const int totalMovement = abs(deltaX) + abs(deltaY); - if (totalMovement >= TOUCH_THRESHOLD) { - hasMoved = true; - } - } - - if (hasMoved) { - // Update frame offsets with boundary checking - const int newFrameOffsetX = std::max(minX, std::min(maxX, initialFrameOffsetX + deltaX)); - const int newFrameOffsetY = std::max(minY, std::min(maxY, initialFrameOffsetY + deltaY)); - - frameOffsetX = newFrameOffsetX; - frameOffsetY = newFrameOffsetY; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - boundsNeedUpdate = true; - } - } else if (!currentTouchDetected && oldTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Touch just released and we were touch dragging - if (hasMoved) { - // Save position when touch drag ends - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["mini"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["mini"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - } - - // Reset touch drag state - isDragging = false; - hasMoved = false; - //isRendering = true; - //leventClear(&renderingStopEvent); - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - - // Handle joystick dragging (MINUS + right joystick OR PLUS + left joystick) - if ((currentMinusHeld || currentPlusHeld) && !isDragging) { - // Start joystick dragging - isDragging = true; - //isRendering = false; - //leventSignal(&renderingStopEvent); - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - } else if ((currentMinusHeld || currentPlusHeld) && isDragging) { - // Continue joystick dragging - static constexpr int JOYSTICK_DEADZONE = 20; - - // Choose the appropriate joystick based on which button is held - const HidAnalogStickState& activeJoystick = currentMinusHeld ? joyStickPosRight : joyStickPosLeft; - - // Only move if joystick is outside deadzone - if (abs(activeJoystick.x) > JOYSTICK_DEADZONE || abs(activeJoystick.y) > JOYSTICK_DEADZONE) { - // Calculate joystick magnitude (distance from center) - const float magnitude = sqrt((float)(activeJoystick.x * activeJoystick.x + activeJoystick.y * activeJoystick.y)); - const float normalizedMagnitude = magnitude / 32767.0f; // Normalize to 0-1 range - - // Single smooth curve: stays very slow for wide range, then accelerates - static constexpr float baseSensitivity = 0.00008f; // Higher so small movements register - static constexpr float maxSensitivity = 0.0005f; - - // Use x^8 curve - stays very low until ~70% then curves up sharply - const float curveValue = pow(normalizedMagnitude, 8.0f); - const float currentSensitivity = baseSensitivity + (maxSensitivity - baseSensitivity) * curveValue; - - // Calculate movement delta with fractional accumulation - static float accumulatedX = 0.0f; - static float accumulatedY = 0.0f; - - accumulatedX += (float)activeJoystick.x * currentSensitivity; - accumulatedY += -(float)activeJoystick.y * currentSensitivity; - - // Extract integer movement and keep fractional part - const int deltaX = (int)accumulatedX; - const int deltaY = (int)accumulatedY; - accumulatedX -= deltaX; - accumulatedY -= deltaY; - - // Update frame offsets with boundary checking - const int newFrameOffsetX = std::max(minX, std::min(maxX, frameOffsetX + deltaX)); - const int newFrameOffsetY = std::max(minY, std::min(maxY, frameOffsetY + deltaY)); - - frameOffsetX = newFrameOffsetX; - frameOffsetY = newFrameOffsetY; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - boundsNeedUpdate = true; - } - } else if (((!currentMinusHeld && oldMinusHeld) || (!currentPlusHeld && oldPlusHeld)) && isDragging) { - // Button just released - stop joystick dragging - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["mini"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["mini"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - isDragging = false; - //isRendering = true; - //leventClear(&renderingStopEvent); - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Update state for next frame - oldTouchDetected = currentTouchDetected; - oldMinusHeld = currentMinusHeld; - oldPlusHeld = currentPlusHeld; - - // Handle existing key input logic (but don't interfere with dragging) - if (!isDragging) { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - //triggerRumbleDoubleClick.store(true, std::memory_order_release); - skipOnce = true; - runOnce = true; - //TeslaFPS = 60; - if (skipMain) { - //lastSelectedItem = "Mini"; - lastMode = "returning"; - tsl::goBack(); - } - else { - tsl::setNextOverlay(filepath.c_str(), "--lastSelectedItem Mini"); - tsl::Overlay::get()->close(); - } - return true; - } - else if (((keysDown & KEY_L) && (keysDown & KEY_ZL)) || ((keysDown & KEY_L) && (keysHeld & KEY_ZL)) || ((keysHeld & KEY_L) && (keysDown & KEY_ZL))) { - FPSmin = 254; - FPSmax = 0; - } - } - - // Return true if we handled the input (during dragging) - return isDragging; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Misc.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Misc.hpp deleted file mode 100644 index 98f52528..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Misc.hpp +++ /dev/null @@ -1,189 +0,0 @@ -class OtherMenu; - -void StartMiscThread() { - // Wait for existing thread to exit - threadWaitForExit(&t0); - - // Clear the thread exit event for new thread - leventClear(&threadexit); - - // Close and recreate thread - threadClose(&t0); - threadCreate(&t0, Misc2, NULL, NULL, 0x1000, 0x3F, 3); - threadStart(&t0); -} - -void EndMiscThread() { - // Signal the thread exit event - leventSignal(&threadexit); - - // Wait for thread to exit - threadWaitForExit(&t0); - - // Close thread handle - threadClose(&t0); -} - -class MiscOverlay : public tsl::Gui { -private: - char DSP_Load_c[16]; - // Separated value buffers for NV clocks - char NVDEC_value_c[16] = ""; - char NVENC_value_c[16] = ""; - char NVJPG_value_c[16] = ""; - char Nifm_pass[96]; - FullSettings settings; -public: - MiscOverlay() { - GetConfigSettings(&settings); - disableJumpTo = true; - smInitialize(); - nifmCheck = nifmInitialize(NifmServiceType_Admin); - if (R_SUCCEEDED(mmuInitialize())) { - nvdecCheck = mmuRequestInitialize(&nvdecRequest, MmuModuleId(5), 8, false); - nvencCheck = mmuRequestInitialize(&nvencRequest, MmuModuleId(6), 8, false); - nvjpgCheck = mmuRequestInitialize(&nvjpgRequest, MmuModuleId(7), 8, false); - } - - if (R_SUCCEEDED(audsnoopInitialize())) - audsnoopCheck = audsnoopEnableDspUsageMeasurement(); - - smExit(); - StartMiscThread(); - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - } - - ~MiscOverlay() { - EndMiscThread(); - nifmExit(); - mmuRequestFinalize(&nvdecRequest); - mmuRequestFinalize(&nvencRequest); - mmuRequestFinalize(&nvjpgRequest); - mmuExit(); - if (R_SUCCEEDED(audsnoopCheck)) { - audsnoopDisableDspUsageMeasurement(); - } - audsnoopExit(); - } - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - static constexpr u16 X_OFFSET = 30; - static constexpr u16 NV_VALUE_X = 120; // Aligned X position for NV values - - ///DSP - if (R_SUCCEEDED(audsnoopCheck)) { - renderer->drawString(DSP_Load_c, false, X_OFFSET, 120, 20, (settings.textColor)); - } - - //Multimedia engines - if (R_SUCCEEDED(nvdecCheck | nvencCheck | nvjpgCheck)) { - renderer->drawString("Multimedia Clock Rates", false, X_OFFSET, 165, 20, (settings.catColor1)); - - u16 currentY = 185; - - if (R_SUCCEEDED(nvdecCheck)) { - renderer->drawString("NVDEC", false, X_OFFSET+15, currentY, 15, (settings.catColor2)); - renderer->drawString(NVDEC_value_c, false, NV_VALUE_X, currentY, 15, (settings.textColor)); - currentY += 15; - } - if (R_SUCCEEDED(nvencCheck)) { - renderer->drawString("NVENC", false, X_OFFSET+15, currentY, 15, (settings.catColor2)); - renderer->drawString(NVENC_value_c, false, NV_VALUE_X, currentY, 15, (settings.textColor)); - currentY += 15; - } - if (R_SUCCEEDED(nvjpgCheck)) { - renderer->drawString("NVJPG", false, X_OFFSET+15, currentY, 15, (settings.catColor2)); - renderer->drawString(NVJPG_value_c, false, NV_VALUE_X, currentY, 15, (settings.textColor)); - } - } - - if (R_SUCCEEDED(nifmCheck)) { - renderer->drawString("Network", false, X_OFFSET, 255, 20, (settings.catColor1)); - if (!Nifm_internet_rc) { - if (NifmConnectionType == NifmInternetConnectionType_WiFi) { - renderer->drawString("Type: Wi-Fi", false, X_OFFSET, 280, 18, (settings.catColor2)); - if (!Nifm_profile_rc) { - if (Nifm_showpass) - renderer->drawString(Nifm_pass, false, X_OFFSET, 305, 15, (settings.textColor)); - else - renderer->drawString("Press Y to show password", false, X_OFFSET, 305, 15, (settings.textColor)); - } - } - else if (NifmConnectionType == NifmInternetConnectionType_Ethernet) - renderer->drawString("Type: Ethernet", false, X_OFFSET, 280, 18, (settings.textColor)); - } - else - renderer->drawString("Type: Not connected", false, X_OFFSET, 280, 18, (settings.textColor)); - } - - - }); - - // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - - snprintf(DSP_Load_c, sizeof DSP_Load_c, "DSP usage: %u%%", DSP_Load_u); - - // Format just the values for NV clocks - snprintf(NVDEC_value_c, sizeof(NVDEC_value_c), "%.1f MHz", (float)NVDEC_Hz / 1000000); - snprintf(NVENC_value_c, sizeof(NVENC_value_c), "%.1f MHz", (float)NVENC_Hz / 1000000); - snprintf(NVJPG_value_c, sizeof(NVJPG_value_c), "%.1f MHz", (float)NVJPG_Hz / 1000000); - - char pass_temp1[25] = ""; - char pass_temp2[25] = ""; - char pass_temp3[17] = ""; - if (Nifm_profile.wireless_setting_data.passphrase_len > 48) { - memcpy(&pass_temp1, &(Nifm_profile.wireless_setting_data.passphrase[0]), 24); - memcpy(&pass_temp2, &(Nifm_profile.wireless_setting_data.passphrase[24]), 24); - memcpy(&pass_temp3, &(Nifm_profile.wireless_setting_data.passphrase[48]), 16); - } - else if (Nifm_profile.wireless_setting_data.passphrase_len > 24) { - memcpy(&pass_temp1, &(Nifm_profile.wireless_setting_data.passphrase[0]), 24); - memcpy(&pass_temp2, &(Nifm_profile.wireless_setting_data.passphrase[24]), 24); - } - else { - memcpy(&pass_temp1, &(Nifm_profile.wireless_setting_data.passphrase[0]), 24); - } - snprintf(Nifm_pass, sizeof Nifm_pass, "%s\n%s\n%s", pass_temp1, pass_temp2, pass_temp3); - - static bool skipOnce = true; - - if (!skipOnce) { - static bool runOnce = true; - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysHeld & KEY_Y) { - Nifm_showpass = true; - } - else Nifm_showpass = false; - - if (keysDown & KEY_B) { - isRendering = false; - leventSignal(&renderingStopEvent); - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerExitSound.store(true, std::memory_order_release); - lastSelectedItem = "Miscellaneous"; - lastMode = ""; - tsl::swapTo(); - return true; - } - return false; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Resolutions.hpp b/Source/Horizon-OC-Monitor (deprecated)/source/modes/Resolutions.hpp deleted file mode 100644 index aca519b7..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/modes/Resolutions.hpp +++ /dev/null @@ -1,581 +0,0 @@ -class MainMenu; - -class ResolutionsOverlay : public tsl::Gui { -private: - char Resolutions_c[512] = {0}; - char Resolutions2_c[512] = {0}; - ResolutionSettings settings; - bool skipOnce = true; - bool runOnce = true; - - // Repositioning variables (matching Mini) - int frameOffsetX = 0; - int frameOffsetY = 0; - bool isDragging = false; - size_t framePadding = 10; - static constexpr int screenWidth = 1280; - static constexpr int screenHeight = 720; - - bool originalUseRightAlignment = ult::useRightAlignment; - - struct ButtonState { - std::atomic minusDragActive{false}; - std::atomic plusDragActive{false}; - } buttonState; - - Thread touchPollThread; - std::atomic touchPollRunning{false}; - - std::atomic inputDetected{false}; - -public: - ResolutionsOverlay() { - tsl::hlp::requestForeground(false); - disableJumpTo = true; - GetConfigSettings(&settings); - - // Load saved frame offsets - frameOffsetX = settings.frameOffsetX; - frameOffsetY = settings.frameOffsetY; - framePadding = settings.framePadding; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().removeScreenshotStacks(); - } - deactivateOriginalFooter = true; - FullMode = false; - TeslaFPS = settings.refreshRate; - StartFPSCounterThread(); - - // Start touch polling thread for instant response at low FPS - touchPollRunning.store(true, std::memory_order_release); - threadCreate(&touchPollThread, [](void* arg) -> void { - ResolutionsOverlay* overlay = static_cast(arg); - - // Allow only Player 1 and handheld mode - const HidNpadIdType id_list[2] = { HidNpadIdType_No1, HidNpadIdType_Handheld }; - - // Configure HID system to only listen to these IDs - hidSetSupportedNpadIdType(id_list, 2); - - // Configure input for up to 2 supported controllers (P1 + Handheld) - padConfigureInput(2, HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt); - - // Initialize separate pad states for both controllers - PadState pad_p1; - PadState pad_handheld; - padInitialize(&pad_p1, HidNpadIdType_No1); - padInitialize(&pad_handheld, HidNpadIdType_Handheld); - - u64 minusHoldStart = 0; - u64 plusHoldStart = 0; - static constexpr u64 HOLD_THRESHOLD_NS = 500'000'000ULL; - - HidTouchScreenState state = {0}; - - - while (overlay->touchPollRunning.load(std::memory_order_acquire)) { - // Only poll when rendering and not dragging - { - overlay->inputDetected.store(false, std::memory_order_release); - - // Check touch in bounds - if (hidGetTouchScreenStates(&state, 1) && state.count > 0) { - const int touchX = state.touches[0].x; - const int touchY = state.touches[0].y; - - // Calculate bounds (same logic as handleInput) - const int overlayX = overlay->frameOffsetX; - const int overlayY = overlay->frameOffsetY; - - // Overlay dimensions based on game state - int overlayWidth, overlayHeight; - overlayWidth = 360-20; - overlayHeight = 200; - - // Add touch padding - const int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = overlayWidth + (touchPadding * 2); - const int touchableHeight = overlayHeight + (touchPadding * 2); - - // Check if touch is within bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - overlay->inputDetected.store(true, std::memory_order_release); - } - } - - // Poll buttons from both controllers - padUpdate(&pad_p1); - padUpdate(&pad_handheld); - - // Combine input from both controllers - const u64 keysHeld = padGetButtons(&pad_p1) | padGetButtons(&pad_handheld); - const u64 now = armTicksToNs(armGetSystemTick()); - - // Track MINUS hold duration - if ((keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK)) { - if (minusHoldStart == 0) { - minusHoldStart = now; - } - if (now - minusHoldStart >= HOLD_THRESHOLD_NS) { - // Long enough to start drag - overlay->inputDetected.store(true, std::memory_order_release); - overlay->buttonState.minusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - // Track PLUS hold duration - else if ((keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK)) { - if (plusHoldStart == 0) { - plusHoldStart = now; - } - if (now - plusHoldStart >= HOLD_THRESHOLD_NS) { - // Long enough to start drag - overlay->inputDetected.store(true, std::memory_order_release); - overlay->buttonState.plusDragActive.exchange(true, std::memory_order_acq_rel); - } - } - - else { - minusHoldStart = plusHoldStart = 0; - overlay->buttonState.minusDragActive.exchange(false, std::memory_order_acq_rel); - overlay->buttonState.plusDragActive.exchange(false, std::memory_order_acq_rel); - } - - // Disable rendering on any input, re-enable when no input - static bool resetOnce = true; - if (overlay->inputDetected.load(std::memory_order_acquire)) { - if (resetOnce && isRendering) { - isRendering = false; - leventSignal(&renderingStopEvent); - resetOnce = false; - } - } else { - resetOnce = true; - } - } - - if (ult::limitedMemory) { - static auto lastUnderscanPixels = std::make_pair(0, 0); - - if (lastUnderscanPixels != tsl::impl::currentUnderscanPixels) { - for (int i = 0; i < 2; i++) { - tsl::gfx::Renderer::get().updateLayerSize(); - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(overlay->frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - } - lastUnderscanPixels = tsl::impl::currentUnderscanPixels; - } - - svcSleepThread(16000000ULL*2); // 16ms polling - } - }, this, NULL, 0x1000, 0x2B, -2); - threadStart(&touchPollThread); - } - - ~ResolutionsOverlay() { - // Stop touch polling thread - touchPollRunning.store(false, std::memory_order_release); - threadWaitForExit(&touchPollThread); - threadClose(&touchPollThread); - - EndFPSCounterThread(); - TeslaFPS = 60; - if (settings.disableScreenshots) { - tsl::gfx::Renderer::get().addScreenshotStacks(); - } - deactivateOriginalFooter = false; - ult::useRightAlignment = originalUseRightAlignment; - fixForeground = true; - FullMode = true; - } - - resolutionCalls m_resolutionRenderCalls[8] = {0}; - resolutionCalls m_resolutionViewportCalls[8] = {0}; - bool gameStart = false; - uint8_t resolutionLookup = 0; - u64 lastGameSeenTick = 0; - bool waitingForGame = true; - - virtual tsl::elm::Element* createUI() override { - - auto* Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) { - int base_y = 0; - int base_x = 0; - int clippingOffsetX = 0, clippingOffsetY = 0; - - int total_width = 360 - 20; - int total_height = 200; - - // Check clipping bounds (same as before) - if (base_x + frameOffsetX < int(framePadding)) - clippingOffsetX = framePadding - (base_x + frameOffsetX); - else if ((base_x + frameOffsetX + total_width) > static_cast(screenWidth - framePadding)) - clippingOffsetX = (screenWidth - framePadding) - (base_x + frameOffsetX + total_width); - - if (base_y + frameOffsetY < int(framePadding)) - clippingOffsetY = framePadding - (base_y + frameOffsetY); - else if ((base_y + frameOffsetY + total_height) > static_cast(screenHeight - framePadding)) - clippingOffsetY = (screenHeight - framePadding) - (base_y + frameOffsetY + total_height); - - int _frameOffsetX = ult::limitedMemory ? std::max(0, frameOffsetX - (1280-448)) : frameOffsetX; - - const int final_base_x = base_x + _frameOffsetX + clippingOffsetX; - const int final_base_y = base_y + frameOffsetY + clippingOffsetY; - - const tsl::Color bgColor = !isDragging ? settings.backgroundColor : settings.focusBackgroundColor; - - const u64 curTick = armGetSystemTick(); - - // guard: ensure lastGameSeenTick is initialized to something reasonable - if (lastGameSeenTick == 0) lastGameSeenTick = curTick; - - // threshold in ns (100 ms) - static constexpr u64 CHECK_NS = 2000000000ULL; - - // Game detected - if (gameStart && NxFps && NxFps->API >= 1 && (Resolutions_c[0] != '\0' && Resolutions2_c[0] != '\0')) { - lastGameSeenTick = curTick; - waitingForGame = true; // reset waiting state so next missing cycle shows "Checking..." - renderer->drawRoundedRectSingleThreaded(final_base_x, final_base_y, total_width, total_height, 16, aWithOpacity(bgColor)); - - int xOffset = 10; - int yOffset = 10; - renderer->drawString("Depth", false, xOffset + final_base_x + 20, yOffset + final_base_y + 20, 20, settings.catColor); - renderer->drawString(Resolutions_c, false, xOffset + final_base_x + 20, yOffset + final_base_y + 55, 18, settings.textColor); - renderer->drawString("Viewport", false, xOffset + final_base_x + 180, yOffset + final_base_y + 20, 20, settings.catColor); - renderer->drawString(Resolutions2_c, false, xOffset + final_base_x + 180, yOffset + final_base_y + 55, 18, settings.textColor); - } - // Game not detected - else { - renderer->drawRoundedRectSingleThreaded(final_base_x, final_base_y, total_width, total_height, 16, aWithOpacity(bgColor)); - - // Check elapsed time since last game detection - u64 elapsed_ns = armTicksToNs(curTick - lastGameSeenTick); - const bool under100ms = (elapsed_ns < CHECK_NS); // 100ms - - std::string msg; - if (under100ms && waitingForGame) - msg = "Checking for game..."; - else { - msg = "Game is not running\nor is incompatible."; - waitingForGame = false; - } - - const auto [textWidth, textHeight] = renderer->getTextDimensions(msg, false, 20); - const int text_x = final_base_x + (total_width - textWidth) / 2; - const int text_y = final_base_y + (total_height) / 2; - - renderer->drawString(msg, false, text_x, (under100ms && waitingForGame) ? text_y+textHeight/2 : text_y, 20, (under100ms && waitingForGame) ? 0xFFFF : 0xF00F); - } - }); - - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("", ""); - rootFrame->setContent(Status); - - return rootFrame; - } - - virtual void update() override { - - if (gameStart && NxFps) { - if (!resolutionLookup) { - NxFps -> renderCalls[0].calls = 0xFFFF; - resolutionLookup = 1; - } - else if (resolutionLookup == 1) { - if ((NxFps -> renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2; - else return; - } - memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls)); - memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls)); - qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare); - qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare); - snprintf(Resolutions_c, sizeof Resolutions_c, - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d", - m_resolutionRenderCalls[0].width, m_resolutionRenderCalls[0].height, m_resolutionRenderCalls[0].calls, - m_resolutionRenderCalls[1].width, m_resolutionRenderCalls[1].height, m_resolutionRenderCalls[1].calls, - m_resolutionRenderCalls[2].width, m_resolutionRenderCalls[2].height, m_resolutionRenderCalls[2].calls, - m_resolutionRenderCalls[3].width, m_resolutionRenderCalls[3].height, m_resolutionRenderCalls[3].calls, - m_resolutionRenderCalls[4].width, m_resolutionRenderCalls[4].height, m_resolutionRenderCalls[4].calls, - m_resolutionRenderCalls[5].width, m_resolutionRenderCalls[5].height, m_resolutionRenderCalls[5].calls, - m_resolutionRenderCalls[6].width, m_resolutionRenderCalls[6].height, m_resolutionRenderCalls[6].calls, - m_resolutionRenderCalls[7].width, m_resolutionRenderCalls[7].height, m_resolutionRenderCalls[7].calls - ); - snprintf(Resolutions2_c, sizeof Resolutions2_c, - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d\n" - "%dx%d, %d", - m_resolutionViewportCalls[0].width, m_resolutionViewportCalls[0].height, m_resolutionViewportCalls[0].calls, - m_resolutionViewportCalls[1].width, m_resolutionViewportCalls[1].height, m_resolutionViewportCalls[1].calls, - m_resolutionViewportCalls[2].width, m_resolutionViewportCalls[2].height, m_resolutionViewportCalls[2].calls, - m_resolutionViewportCalls[3].width, m_resolutionViewportCalls[3].height, m_resolutionViewportCalls[3].calls, - m_resolutionViewportCalls[4].width, m_resolutionViewportCalls[4].height, m_resolutionViewportCalls[4].calls, - m_resolutionViewportCalls[5].width, m_resolutionViewportCalls[5].height, m_resolutionViewportCalls[5].calls, - m_resolutionViewportCalls[6].width, m_resolutionViewportCalls[6].height, m_resolutionViewportCalls[6].calls, - m_resolutionViewportCalls[7].width, m_resolutionViewportCalls[7].height, m_resolutionViewportCalls[7].calls - ); - } - if (FPSavg < 254) { - gameStart = true; - } - else { - gameStart = false; - resolutionLookup = false; - } - - if (!skipOnce) { - if (runOnce) { - isRendering = true; - leventClear(&renderingStopEvent); - runOnce = false; - } - } else { - skipOnce = false; - } - } - - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - // Static variables to maintain drag state between function calls - static bool oldTouchDetected = false; - static bool oldMinusHeld = false; - static bool oldPlusHeld = false; - static HidTouchState initialTouchPos = {0}; - static int initialFrameOffsetX = 0; - static int initialFrameOffsetY = 0; - static constexpr int TOUCH_THRESHOLD = 8; - static bool hasMoved = false; - - // Better touch detection - check if coordinates are within reasonable screen bounds - const bool currentTouchDetected = (touchPos.x > 0 && touchPos.y > 0 && - touchPos.x < screenWidth && touchPos.y < screenHeight); - - static bool clearOnRelease = false; - - if (clearOnRelease && !isRendering) { - clearOnRelease = false; - isRendering = true; - leventClear(&renderingStopEvent); - } - - // Calculate overlay bounds - // Cache bounds calculation - static int cachedBaseX = 0; - static int cachedBaseY = 0; - static bool boundsNeedUpdate = true; - - // Only recalculate bounds when needed - if (boundsNeedUpdate) { - cachedBaseX = 0; - cachedBaseY = 0; - boundsNeedUpdate = false; - } - - const int overlayX = cachedBaseX + frameOffsetX; - const int overlayY = cachedBaseY + frameOffsetY; - - // Overlay dimensions based on game state - int overlayWidth, overlayHeight; - overlayWidth = 360-20; - overlayHeight = 200; - - // Add padding to make touch detection more forgiving - static constexpr int touchPadding = 4; - const int touchableX = overlayX - touchPadding; - const int touchableY = overlayY - touchPadding; - const int touchableWidth = overlayWidth + (touchPadding * 2); - const int touchableHeight = overlayHeight + (touchPadding * 2); - - // Screen boundaries for clamping - const int minX = -cachedBaseX + framePadding; - const int maxX = screenWidth - overlayWidth - cachedBaseX - framePadding; - const int minY = -cachedBaseY + framePadding; - const int maxY = screenHeight - overlayHeight - cachedBaseY - framePadding; - - const bool minusDragReady = buttonState.minusDragActive.load(std::memory_order_acquire); - const bool plusDragReady = buttonState.plusDragActive.load(std::memory_order_acquire); - - // Check button states - const bool currentMinusHeld = (keysHeld & KEY_MINUS) && !(keysHeld & ~KEY_MINUS & ALL_KEYS_MASK) && minusDragReady; - const bool currentPlusHeld = (keysHeld & KEY_PLUS) && !(keysHeld & ~KEY_PLUS & ALL_KEYS_MASK) && plusDragReady; - - // Handle touch dragging - if (currentTouchDetected && !isDragging) { - const int touchX = touchPos.x; - const int touchY = touchPos.y; - - if (!oldTouchDetected) { - // Touch just started - check if within overlay bounds - if (touchX >= touchableX && touchX <= touchableX + touchableWidth && - touchY >= touchableY && touchY <= touchableY + touchableHeight) { - - // Start touch dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - hasMoved = false; - initialTouchPos = touchPos; - initialFrameOffsetX = frameOffsetX; - initialFrameOffsetY = frameOffsetY; - } - } - } else if (currentTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Continue touch dragging - const int touchX = touchPos.x; - const int touchY = touchPos.y; - const int deltaX = touchX - initialTouchPos.x; - const int deltaY = touchY - initialTouchPos.y; - - // Check if we've moved enough to consider this a drag - if (!hasMoved) { - const int totalMovement = abs(deltaX) + abs(deltaY); - if (totalMovement >= TOUCH_THRESHOLD) { - hasMoved = true; - } - } - - if (hasMoved) { - // Update frame offsets with boundary checking - const int newFrameOffsetX = std::max(minX, std::min(maxX, initialFrameOffsetX + deltaX)); - const int newFrameOffsetY = std::max(minY, std::min(maxY, initialFrameOffsetY + deltaY)); - - frameOffsetX = newFrameOffsetX; - frameOffsetY = newFrameOffsetY; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - boundsNeedUpdate = true; - } - } else if (!currentTouchDetected && oldTouchDetected && isDragging && !currentMinusHeld && !currentPlusHeld) { - // Touch just released - if (hasMoved) { - // Save position when touch drag ends - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["game_resolutions"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["game_resolutions"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - } - - // Reset touch drag state - isDragging = false; - hasMoved = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Handle joystick dragging (MINUS + right joystick OR PLUS + left joystick) - if ((currentMinusHeld || currentPlusHeld) && !isDragging) { - // Start joystick dragging - isDragging = true; - triggerRumbleClick.store(true, std::memory_order_release); - triggerOnSound.store(true, std::memory_order_release); - } else if ((currentMinusHeld || currentPlusHeld) && isDragging) { - // Continue joystick dragging - static constexpr int JOYSTICK_DEADZONE = 20; - - // Choose the appropriate joystick based on which button is held - const HidAnalogStickState& activeJoystick = currentMinusHeld ? joyStickPosRight : joyStickPosLeft; - - // Only move if joystick is outside deadzone - if (abs(activeJoystick.x) > JOYSTICK_DEADZONE || abs(activeJoystick.y) > JOYSTICK_DEADZONE) { - // Calculate joystick magnitude - const float magnitude = sqrt((float)(activeJoystick.x * activeJoystick.x + activeJoystick.y * activeJoystick.y)); - const float normalizedMagnitude = magnitude / 32767.0f; - - // Smooth curve for sensitivity - static constexpr float baseSensitivity = 0.00008f; - static constexpr float maxSensitivity = 0.0005f; - - const float curveValue = pow(normalizedMagnitude, 8.0f); - const float currentSensitivity = baseSensitivity + (maxSensitivity - baseSensitivity) * curveValue; - - // Calculate movement delta with fractional accumulation - static float accumulatedX = 0.0f; - static float accumulatedY = 0.0f; - - accumulatedX += (float)activeJoystick.x * currentSensitivity; - accumulatedY += -(float)activeJoystick.y * currentSensitivity; - - const int deltaX = (int)accumulatedX; - const int deltaY = (int)accumulatedY; - accumulatedX -= deltaX; - accumulatedY -= deltaY; - - // Update frame offsets with boundary checking - const int newFrameOffsetX = std::max(minX, std::min(maxX, frameOffsetX + deltaX)); - const int newFrameOffsetY = std::max(minY, std::min(maxY, frameOffsetY + deltaY)); - - frameOffsetX = newFrameOffsetX; - frameOffsetY = newFrameOffsetY; - - if (ult::limitedMemory) { - tsl::gfx::Renderer::get().setLayerPos(std::max(std::min((int)(frameOffsetX*1.5 + 0.5) - tsl::impl::currentUnderscanPixels.first, 1280-32 - tsl::impl::currentUnderscanPixels.first), 0), 0); - } - - boundsNeedUpdate = true; - } - } else if (((!currentMinusHeld && oldMinusHeld) || (!currentPlusHeld && oldPlusHeld)) && isDragging) { - // Button just released - stop joystick dragging - auto iniData = ult::getParsedDataFromIniFile(configIniPath); - iniData["game_resolutions"]["frame_offset_x"] = std::to_string(frameOffsetX); - iniData["game_resolutions"]["frame_offset_y"] = std::to_string(frameOffsetY); - ult::saveIniFileData(configIniPath, iniData); - isDragging = false; - clearOnRelease = true; - triggerRumbleDoubleClick.store(true, std::memory_order_release); - triggerOffSound.store(true, std::memory_order_release); - } - - // Update state for next frame - oldTouchDetected = currentTouchDetected; - oldMinusHeld = currentMinusHeld; - oldPlusHeld = currentPlusHeld; - - // Handle existing key input logic (but don't interfere with dragging) - if (!isDragging) { - if (isKeyComboPressed(keysHeld, keysDown)) { - isRendering = false; - leventSignal(&renderingStopEvent); - runOnce = true; - skipOnce = true; - TeslaFPS = 60; - lastSelectedItem = "Game Resolutions"; - lastMode = ""; - if (skipMain) { - lastMode = "return"; - tsl::goBack(); - } - else { - tsl::setNextOverlay(filepath.c_str(), "--lastSelectedItem 'Game Resolutions'"); - tsl::Overlay::get()->close(); - } - return true; - } - } - - // Return true if we handled the input (during dragging) - return isDragging; - } -}; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/pwm.c b/Source/Horizon-OC-Monitor (deprecated)/source/pwm.c deleted file mode 100644 index d556e7ca..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/pwm.c +++ /dev/null @@ -1,35 +0,0 @@ -#define NX_SERVICE_ASSUME_NON_DOMAIN -#include -#include -#include "pwm.h" - -static Service g_pwmSrv; - -NX_GENERATE_SERVICE_GUARD(pwm); - -Result _pwmInitialize(void) { - return smGetService(&g_pwmSrv, "pwm"); -} - -void _pwmCleanup(void) { - serviceClose(&g_pwmSrv); -} - -Service* pwmGetServiceSession(void) { - return &g_pwmSrv; -} - -Result pwmOpenSession2(PwmChannelSession *out, u32 device_code) { - return serviceDispatchIn(&g_pwmSrv, 2, device_code, - .out_num_objects = 1, - .out_objects = &out->s, - ); -} - -Result pwmChannelSessionGetDutyCycle(PwmChannelSession *c, double* out) { - return serviceDispatchOut(&c->s, 7, *out); -} - -void pwmChannelSessionClose(PwmChannelSession *c) { - serviceClose(&c->s); -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/rgltr_services.cpp b/Source/Horizon-OC-Monitor (deprecated)/source/rgltr_services.cpp deleted file mode 100644 index 5f2160db..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/rgltr_services.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// rgltr_services.cpp (no changes needed here—just compile it once) -#include -#include "rgltr.h" -#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc. - -// Global service handle -Service g_rgltrSrv; - -Result rgltrInitialize(void) { - if (hosversionBefore(8, 0, 0)) { - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - } - return smGetService(&g_rgltrSrv, "rgltr"); -} - -void rgltrExit(void) { - serviceClose(&g_rgltrSrv); -} - -Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id) { - const u32 in = (u32)module_id; - return serviceDispatchIn( - &g_rgltrSrv, - 0, - in, - .out_num_objects = 1, - .out_objects = &session_out->s - ); -} - -Result rgltrGetVoltage(RgltrSession* session, u32* out_volt) { - // Service returns µV (microvolts) in a local u32: - u32 temp = 0; - Result rc = serviceDispatchOut(&session->s, 4, temp); - if (R_SUCCEEDED(rc)) { - *out_volt = temp; - } - return rc; -} - -void rgltrCloseSession(RgltrSession* session) { - serviceClose(&session->s); -} diff --git a/Source/Horizon-OC-Monitor (deprecated)/source/sysclk_ipc.c b/Source/Horizon-OC-Monitor (deprecated)/source/sysclk_ipc.c deleted file mode 100644 index 6d3172b3..00000000 --- a/Source/Horizon-OC-Monitor (deprecated)/source/sysclk_ipc.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* -------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * , , - * wrote this file. As long as you retain this notice you can do whatever you - * want with this stuff. If you meet any of us some day, and you think this - * stuff is worth it, you can buy us a beer in return. - The sys-clk authors - * -------------------------------------------------------------------------- - */ - - -#define NX_SERVICE_ASSUME_NON_DOMAIN -#include -#include -#include -#include - -static Service g_hocclkSrv; -static atomic_size_t g_refCnt; - -bool hocclkIpcRunning() -{ - Handle handle; - bool running = R_FAILED(smRegisterService(&handle, smEncodeName(HOCCLK_IPC_SERVICE_NAME), false, 1)); - - if (!running) - { - smUnregisterService(smEncodeName(HOCCLK_IPC_SERVICE_NAME)); - } - - return running; -} - -Result hocclkIpcInitialize(void) -{ - Result rc = 0; - - g_refCnt++; - - if (serviceIsActive(&g_hocclkSrv)) - return 0; - - rc = smGetService(&g_hocclkSrv, HOCCLK_IPC_SERVICE_NAME); - - if (R_FAILED(rc)) hocclkIpcExit(); - - return rc; -} - -void hocclkIpcExit(void) -{ - if (--g_refCnt == 0) - { - serviceClose(&g_hocclkSrv); - } -} - -Result hocclkIpcGetAPIVersion(u32* out_ver) -{ - return serviceDispatchOut(&g_hocclkSrv, HocClkIpcCmd_GetApiVersion, *out_ver); -} - -Result hocclkIpcGetVersionString(char* out, size_t len) -{ - return serviceDispatch(&g_hocclkSrv, HocClkIpcCmd_GetVersionString, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, - .buffers = {{out, len}}, - ); -} - -Result hocclkIpcGetCurrentContext(HocClkContext* out_context) -{ - return serviceDispatch(&g_hocclkSrv, HocClkIpcCmd_GetCurrentContext, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, - .buffers = {{out_context, sizeof(HocClkContext)}}, - ); -} - -Result hocclkIpcGetProfileCount(u64 tid, u8* out_count) -{ - return serviceDispatchInOut(&g_hocclkSrv, HocClkIpcCmd_GetProfileCount, tid, *out_count); -} - -Result hocclkIpcSetEnabled(bool enabled) -{ - u8 enabledRaw = (u8)enabled; - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_SetEnabled, enabledRaw); -} - -Result hocclkIpcSetOverride(HocClkModule module, u32 hz) -{ - HocClkIpc_SetOverride_Args args = { - .module = module, - .hz = hz - }; - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_SetOverride, args); -} - -Result hocclkIpcGetProfiles(u64 tid, HocClkTitleProfileList* out_profiles) -{ - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_GetProfiles, tid, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, - .buffers = {{out_profiles, sizeof(HocClkTitleProfileList)}}, - ); -} - -Result hocclkIpcSetProfiles(u64 tid, HocClkTitleProfileList* profiles) -{ - HocClkIpc_SetProfiles_Args args; - args.tid = tid; - memcpy(&args.profiles, profiles, sizeof(HocClkTitleProfileList)); - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_SetProfiles, args); -} - -Result hocclkIpcGetConfigValues(HocClkConfigValueList* out_configValues) -{ - return serviceDispatch(&g_hocclkSrv, HocClkIpcCmd_GetConfigValues, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, - .buffers = {{out_configValues, sizeof(HocClkConfigValueList)}}, - ); -} - -Result hocclkIpcSetConfigValues(HocClkConfigValueList* configValues) -{ - return serviceDispatch(&g_hocclkSrv, HocClkIpcCmd_SetConfigValues, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In }, - .buffers = {{configValues, sizeof(HocClkConfigValueList)}}, - ); -} - -Result hocclkIpcGetFreqList(HocClkModule module, u32* list, u32 maxCount, u32* outCount) -{ - HocClkIpc_GetFreqList_Args args = { - .module = module, - .maxCount = maxCount - }; - return serviceDispatchInOut(&g_hocclkSrv, HocClkIpcCmd_GetFreqList, args, *outCount, - .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, - .buffers = {{list, maxCount * sizeof(u32)}}, - ); -} - -Result hocClkIpcSetKipData() -{ - u32 temp = 0; - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_SetKipData, temp); -} - -Result hocClkIpcGetKipData() -{ - u32 temp = 0; - return serviceDispatchIn(&g_hocclkSrv, HocClkIpcCmd_GetKipData, temp); -} \ No newline at end of file