├── .gitignore ├── LICENSE ├── PSVshellPlus.sln ├── PSVshellPlus_Kernel ├── PSVshellPlus_Kernel.vcxproj ├── PSVshellPlus_Kernel.vcxproj.filters ├── PSVshellPlus_Kernel.vcxproj.user ├── clock.c ├── clock.h ├── common.h ├── info.c ├── info.h ├── lib.emd ├── libPSVshellPlus_KernelForUser_stub.a └── main.c ├── PSVshellPlus_Shell ├── PSVshellPlus_Shell.vcxproj ├── PSVshellPlus_Shell.vcxproj.filters ├── PSVshellPlus_Shell.vcxproj.user ├── RES_RCO │ ├── locale │ │ ├── psvshell_locale_en.xml │ │ ├── psvshell_locale_fr.xml │ │ ├── psvshell_locale_ja.xml │ │ ├── psvshell_locale_ru.xml │ │ ├── psvshell_locale_zh-s.xml │ │ └── psvshell_locale_zh-t.xml │ ├── psvshell_plugin.xml │ └── texture │ │ └── tex_icon_impose.png ├── gen_rco.bat ├── global.h ├── hud.cpp ├── hud.h ├── impose.cpp ├── impose.h ├── main.cpp ├── profile.cpp ├── profile.h ├── psvs.c ├── psvs.h ├── psvshell_plugin.rco ├── tracker.cpp ├── tracker.h ├── utils.cpp └── utils.h ├── README.md └── guide.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.la 22 | *.lo 23 | 24 | # Shared objects (inc. Windows DLLs) 25 | *.dll 26 | *.so 27 | *.so.* 28 | *.dylib 29 | 30 | # Executables 31 | *.exe 32 | *.out 33 | *.app 34 | *.i*86 35 | *.x86_64 36 | *.hex 37 | 38 | # Debug files 39 | *.dSYM/ 40 | *.su 41 | *.idb 42 | *.pdb 43 | 44 | # Kernel Module Compile Results 45 | *.mod* 46 | *.cmd 47 | .tmp_versions/ 48 | modules.order 49 | Module.symvers 50 | Mkfile.old 51 | dkms.conf 52 | 53 | # VDS 54 | *.vs 55 | eboot.bin 56 | eboot2.bin 57 | param.sfo 58 | param2.sfo 59 | PSVita_Debug 60 | PSVita_Release 61 | RES_RCO_TMP -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 GrapheneCt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PSVshellPlus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1525 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSVshellPlus_Shell", "PSVshellPlus_Shell\PSVshellPlus_Shell.vcxproj", "{F84FFBB6-2013-43F2-985E-C94E0ADF711D}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {F54C8C2B-86B4-4DC3-A858-F19136590E83} = {F54C8C2B-86B4-4DC3-A858-F19136590E83} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSVshellPlus_Kernel", "PSVshellPlus_Kernel\PSVshellPlus_Kernel.vcxproj", "{F54C8C2B-86B4-4DC3-A858-F19136590E83}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|PSVita = Debug|PSVita 16 | Release|PSVita = Release|PSVita 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {F84FFBB6-2013-43F2-985E-C94E0ADF711D}.Debug|PSVita.ActiveCfg = Debug|PSVita 20 | {F84FFBB6-2013-43F2-985E-C94E0ADF711D}.Debug|PSVita.Build.0 = Debug|PSVita 21 | {F84FFBB6-2013-43F2-985E-C94E0ADF711D}.Release|PSVita.ActiveCfg = Release|PSVita 22 | {F84FFBB6-2013-43F2-985E-C94E0ADF711D}.Release|PSVita.Build.0 = Release|PSVita 23 | {F54C8C2B-86B4-4DC3-A858-F19136590E83}.Debug|PSVita.ActiveCfg = Debug|PSVita 24 | {F54C8C2B-86B4-4DC3-A858-F19136590E83}.Debug|PSVita.Build.0 = Debug|PSVita 25 | {F54C8C2B-86B4-4DC3-A858-F19136590E83}.Release|PSVita.ActiveCfg = Release|PSVita 26 | {F54C8C2B-86B4-4DC3-A858-F19136590E83}.Release|PSVita.Build.0 = Release|PSVita 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | GlobalSection(ExtensibilityGlobals) = postSolution 32 | SolutionGuid = {9EC2EDAB-F25A-47F5-9B8C-B7326D89CADF} 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/PSVshellPlus_Kernel.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | PSVita 7 | 8 | 9 | Release 10 | PSVita 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Document 21 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/armlibgen.exe" %(Filename).emd --entry-src "$(IntDir)%(Filename).s" 22 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/psp2snc.exe" "$(IntDir)%(Filename).s" -c -o "$(IntDir)%(Filename).o" 23 | $(IntDir)%(Filename).s;%(Outputs) 24 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/armlibgen.exe" %(Filename).emd --entry-src "$(IntDir)%(Filename).s" 25 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/psp2snc.exe" "$(IntDir)%(Filename).s" -c -o "$(IntDir)%(Filename).o" 26 | $(IntDir)%(Filename).s;%(Outputs) 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {F54C8C2B-86B4-4DC3-A858-F19136590E83} 36 | 37 | 38 | 39 | DynamicLibrary 40 | 41 | 42 | DynamicLibrary 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | _DEBUG;%(PreprocessorDefinitions); 67 | true 68 | NotUsing 69 | $(SCE_PSP2_SDK_DIR)\target\include\vdsuite\kernel;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;%(AdditionalIncludeDirectories) 70 | 71 | 72 | --prx-no-runtime-support "$(ProjectDir)$(IntDir)lib.o" 73 | $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;%(AdditionalLibraryDirectories) 74 | -lSceDebugForDriver_stub 75 | ;-lSceSysmemForDriver_stub 76 | ;-lSceThreadmgrForDriver_stub 77 | ;-lSceSysclibForDriver_stub 78 | ;-lScePowerForDriver_stub 79 | ;-lSceDisplayForDriver_stub 80 | ;-lSceProcessmgrForDriver_stub;-lSceSysrootForKernel_stub;-ltaihenForKernel_stub;-ltaihenModuleUtils_stub;%(AdditionalDependencies) 81 | 82 | 83 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/vdsuite-pubprx.exe" --compress "$(LocalDebuggerCommand)" "$(OutDir)_$(TargetName).skprx" 84 | "$(SCE_PSP2_SDK_DIR)\host_tools\build\bin\armlibgen.exe" --dump lib.emd --stub-archive 85 | 86 | 87 | 88 | 89 | NDEBUG;%(PreprocessorDefinitions); 90 | Level3 91 | NotUsing 92 | $(SCE_PSP2_SDK_DIR)\target\include\vdsuite\kernel;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;%(AdditionalIncludeDirectories) 93 | 94 | 95 | --prx-no-runtime-support "$(ProjectDir)$(IntDir)lib.o" 96 | StripSymsAndDebug 97 | StripFuncsAndData 98 | true 99 | $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;%(AdditionalLibraryDirectories) 100 | -lSceDebugForDriver_stub 101 | ;-lSceSysmemForDriver_stub 102 | ;-lSceThreadmgrForDriver_stub 103 | ;-lSceSysclibForDriver_stub 104 | ;-lScePowerForDriver_stub 105 | ;-lSceDisplayForDriver_stub 106 | ;-lSceProcessmgrForDriver_stub;-lSceSysrootForKernel_stub;-ltaihenForKernel_stub;-ltaihenModuleUtils_stub;%(AdditionalDependencies) 107 | 108 | 109 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/vdsuite-pubprx.exe" --compress "$(LocalDebuggerCommand)" "$(OutDir)$(TargetName).skprx" 110 | "$(SCE_PSP2_SDK_DIR)\host_tools\build\bin\armlibgen.exe" --dump lib.emd --stub-archive 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/PSVshellPlus_Kernel.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;cc;s;asm 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/PSVshellPlus_Kernel.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/clock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "clock.h" 5 | #include "common.h" 6 | 7 | #define PSVS_LOCKED_PID_MAX_COUNT 16 8 | 9 | int scePowerSetArmClockFrequency(int clock); 10 | int scePowerSetGpuClockFrequencyInternal(int corefreq, int mpfreq); 11 | int scePowerSetGpuXbarClockFrequency(int clock); 12 | int scePowerSetBusClockFrequency(int clock); 13 | 14 | int scePowerGetArmClockFrequencyProc(ScePID pid); 15 | int scePowerGetGpuClockFrequencyProc(ScePID pid); 16 | int scePowerGetGpuXbarClockFrequencyProc(ScePID pid); 17 | int scePowerGetBusClockFrequencyProc(ScePID pid); 18 | 19 | int scePowerGetArmClockFrequency(void); 20 | int scePowerGetGpuClockFrequencyInternal(SceInt32 *corefreq, SceInt32 *mpfreq); 21 | int scePowerGetBusClockFrequency(void); 22 | int scePowerGetGpuXbarClockFrequency(void); 23 | 24 | SceInt32 psvsClockFrequencyLockProc(ScePID pid, PsvsLockDevice type) 25 | { 26 | PSVSKPLS *kpls = NULL; 27 | SceInt32 ret = sceKernelGetRemoteKPLS(pid, g_psvsKpls, &kpls, SCE_TRUE); 28 | if (ret == SCE_OK && kpls != NULL) { 29 | kpls->lock |= type; 30 | } 31 | 32 | return ret; 33 | } 34 | 35 | SceInt32 psvsClockFrequencyUnlockProc(ScePID pid, PsvsLockDevice type) 36 | { 37 | PSVSKPLS *kpls = NULL; 38 | SceInt32 ret = sceKernelGetRemoteKPLS(pid, g_psvsKpls, &kpls, SCE_TRUE); 39 | if (ret == SCE_OK && kpls != NULL) { 40 | kpls->lock &= ~type; 41 | } 42 | 43 | return ret; 44 | } 45 | 46 | SceBool psvsClockFrequencyIsLockedProc(ScePID pid, PsvsLockDevice type) 47 | { 48 | PSVSKPLS *kpls = NULL; 49 | SceInt32 ret = sceKernelGetRemoteKPLS(pid, g_psvsKpls, &kpls, SCE_TRUE); 50 | if (ret == SCE_OK && kpls != NULL) { 51 | return kpls->lock & type; 52 | } 53 | 54 | return SCE_FALSE; 55 | } 56 | 57 | SceInt32 psvsSetArmClockFrequency(SceInt32 clock) 58 | { 59 | SYSCALL_ENTER 60 | clock += PSVS_CLOCK_MAGIC; 61 | SceInt32 ret = scePowerSetArmClockFrequency(clock); 62 | SYSCALL_EXIT 63 | return ret; 64 | } 65 | 66 | SceInt32 psvsSetGpuClockFrequency(SceInt32 clock) 67 | { 68 | SYSCALL_ENTER 69 | clock += PSVS_CLOCK_MAGIC; 70 | SceInt32 corefreq = clock; 71 | SceInt32 mpfreq = clock; 72 | SceInt32 ret = scePowerSetGpuClockFrequencyInternal(corefreq, mpfreq); 73 | SYSCALL_EXIT 74 | return ret; 75 | } 76 | 77 | SceInt32 psvsSetGpuXbarClockFrequency(SceInt32 clock) 78 | { 79 | SYSCALL_ENTER 80 | clock += PSVS_CLOCK_MAGIC; 81 | SceInt32 ret = scePowerSetGpuXbarClockFrequency(clock); 82 | SYSCALL_EXIT 83 | return ret; 84 | } 85 | 86 | SceInt32 psvsSetBusClockFrequency(SceInt32 clock) 87 | { 88 | SYSCALL_ENTER 89 | clock += PSVS_CLOCK_MAGIC; 90 | SceInt32 ret = scePowerSetBusClockFrequency(clock); 91 | SYSCALL_EXIT 92 | return ret; 93 | } 94 | 95 | SceInt32 psvsGetClockFrequency(PSVSClockFrequency *clocks) 96 | { 97 | SceInt32 ret = 0; 98 | SceInt32 unused; 99 | if (!clocks) 100 | return SCE_KERNEL_ERROR_INVALID_ARGUMENT; 101 | 102 | SYSCALL_ENTER 103 | 104 | PSVSClockFrequency kclocks; 105 | kclocks.cpu = scePowerGetArmClockFrequency(); 106 | if (psvsClockFrequencyIsLockedProc(psvsGetClockingPid(), PSVS_500_MHZ_KEY)) 107 | kclocks.cpu = 500; 108 | scePowerGetGpuClockFrequencyInternal(&kclocks.gpu, &unused); 109 | kclocks.xbar = scePowerGetGpuXbarClockFrequency(); 110 | kclocks.bus = scePowerGetBusClockFrequency(); 111 | 112 | ret = sceKernelCopyToUser(clocks, &kclocks, sizeof(PSVSClockFrequency)); 113 | 114 | SYSCALL_EXIT 115 | return ret; 116 | } -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/clock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define PSVS_CLOCK_MAGIC (0x4000) 6 | #define PSVS_500_MHZ_KEY (65536) 7 | 8 | typedef enum { 9 | PSVS_LOCK_DEVICE_NONE = 0, 10 | PSVS_LOCK_DEVICE_CPU = 1, 11 | PSVS_LOCK_DEVICE_GPU_ES4 = 2, 12 | PSVS_LOCK_DEVICE_BUS = 4, 13 | PSVS_LOCK_DEVICE_GPU_XBAR = 8, 14 | /*PSVS_LOCK_DEVICE_VENEZIA = 16, 15 | PSVS_LOCK_DEVICE_DMAC5 = 32, 16 | PSVS_LOCK_DEVICE_COMPAT = 64, 17 | PSVS_LOCK_DEVICE_VIP = 128, 18 | PSVS_LOCK_DEVICE_SYS = 256,*/ 19 | PSVS_LOCK_DEVICE_ALL = PSVS_LOCK_DEVICE_CPU | PSVS_LOCK_DEVICE_GPU_ES4 | PSVS_LOCK_DEVICE_BUS | PSVS_LOCK_DEVICE_GPU_XBAR 20 | } PsvsLockDevice; 21 | 22 | SceBool psvsClockFrequencyIsLockedProc(ScePID pid, PsvsLockDevice type); -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SYSCALL_ENTER unsigned int scstate = __builtin_mrc(15, 0, 13, 0, 3); \ 4 | __builtin_mcr(15, 0, 13, 0, 3, scstate << 16); 5 | 6 | #define SYSCALL_EXIT __builtin_mcr(15, 0, 13, 0, 3, scstate); 7 | 8 | #define SCE_KERNEL_PARTITION_OWNER_APP (0x00000) 9 | #define SCE_KERNEL_PARTITION_OWNER_SYSTEM (0x00002) 10 | #define SCE_KERNEL_PARTITION_OWNER_GAME (0x00004) 11 | 12 | #define SCE_KERNEL_PARTITION_MEMTYPE_MAIN (0x10000) 13 | #define SCE_KERNEL_PARTITION_MEMTYPE_CDRAM (0x30000) 14 | 15 | typedef struct SceKernelPhyMemPart { // size is at least 0x9C on FWs 0.931-3.60 16 | uint32_t field_0x0; 17 | uint32_t field_0x4; 18 | uint32_t some_counter; // always positive 19 | uint32_t field_0xc; 20 | char *field_0x10; 21 | int type; // 0x10000 for Lpddr2Main, 0x30000 for Cdram 22 | int mutex; 23 | void* pbase; 24 | SceSize totalSize; 25 | int field_0x24; 26 | void *pRoot; 27 | uint32_t field_0x2c; 28 | uint32_t field_0x30; 29 | uint32_t field_0x34; 30 | uint32_t field_0x38; 31 | int status; 32 | int pindex40; //1 33 | int field_0x44; 34 | int pindex48; //2 35 | int field_0x4c; 36 | int pindex50; //3 37 | int field_0x54; 38 | int pindex58; //4 39 | int field_0x5c; 40 | int pindex60; //5 41 | int field_0x64; 42 | int pindex68; //6 43 | int field_0x6c; 44 | int pindex70; //7 45 | int field_0x74; 46 | int pindex78; //8 47 | int field_0x7c; 48 | int pindex80; //9 49 | SceSize freeSize; 50 | int min; 51 | char name[32]; //10 52 | int field_0xac; 53 | SceUInt32 nClient; 54 | SceSize field_0xb4; 55 | } SceKernelPhyMemPart; 56 | 57 | typedef struct ScePhyMemPartInfoCore { // size is 0x10 on FWs 0.990-3.60 58 | SceUInt32 unk_0; // same as SceKernelPhyMemPart field 0x1C 59 | SceSize totalSize; 60 | SceSize freeSize; 61 | SceUInt32 unk_C; // maybe some counter 62 | } ScePhyMemPartInfoCore; 63 | 64 | typedef enum SceDisplayHead { 65 | SCE_DISPLAY_HEAD_MAIN_LCD_OLED = 0, 66 | SCE_DISPLAY_HEAD_HDMI = 1, 67 | SCE_DISPLAY_HEAD_SUB_LCD = 2 68 | } SceDisplayHead; 69 | 70 | typedef enum SceDisplayFrameBufType { 71 | SCE_DISPLAY_FRAMEBUF_GAME_APP = 0, 72 | SCE_DISPLAY_FRAMEBUF_LIVEAREA = 1 // including HOME and PS overlays 73 | } SceDisplayFrameBufType; 74 | 75 | typedef struct PSVSClockFrequency { 76 | SceInt32 cpu; 77 | SceInt32 gpu; 78 | SceInt32 xbar; 79 | SceInt32 bus; 80 | } PSVSClockFrequency; 81 | 82 | typedef struct PSVSMem { 83 | SceUInt32 mainFree; 84 | SceUInt32 mainTotal; 85 | SceUInt32 cdramFree; 86 | SceUInt32 cdramTotal; 87 | SceUInt32 phycontFree; 88 | SceUInt32 phycontTotal; 89 | SceUInt32 cdialogFree; 90 | SceUInt32 cdialogTotal; 91 | } PSVSMem; 92 | 93 | typedef struct PSVSVenezia { 94 | SceInt32 core0; 95 | SceInt32 core1; 96 | SceInt32 core2; 97 | SceInt32 core3; 98 | SceInt32 core4; 99 | SceInt32 core5; 100 | SceInt32 core6; 101 | SceInt32 core7; 102 | SceInt32 average; 103 | SceInt32 peak; 104 | } PSVSVenezia; 105 | 106 | typedef struct PSVSBattery { 107 | SceInt32 current; 108 | } PSVSBattery; 109 | 110 | typedef struct PSVSKPLS { 111 | SceUInt32 lock; 112 | } PSVSKPLS; 113 | 114 | extern SceInt32 g_psvsKpls; 115 | 116 | SceUID psvsGetClockingPid(); -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/info.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "info.h" 7 | #include "common.h" 8 | 9 | #define PSVS_CHECK_ASSIGN(struct, field, new_value) \ 10 | struct.field = (new_value) 11 | 12 | #define PSVS_PERF_FPS_SAMPLES 5 13 | #define SECOND 1000000 14 | 15 | static SceUInt32 s_perfTickFpsLast = 0; 16 | static SceUInt32 g_perfFrametimeSum = 0; 17 | static SceUInt8 g_perfFrametimeN = 0; 18 | static SceInt32 s_perfFps = 0; 19 | static SceInt32 s_casShift = 0; 20 | 21 | int(*_sceVeneziaGetProcessorLoad)(PSVSVenezia *data) = NULL; 22 | 23 | SceInt32 psvsGetFps() 24 | { 25 | return sceAtomicLoad32AcqRel(&s_perfFps); 26 | } 27 | 28 | SceInt32 psvsSetRecommendedCasShift(char *name, SceInt32 namelen) 29 | { 30 | char appName[10]; 31 | SceKernelPhyMemPart *memPart = NULL; 32 | 33 | if (namelen > sizeof(appName) || name == NULL) 34 | return SCE_KERNEL_ERROR_INVALID_ARGUMENT; 35 | 36 | sceKernelStrncpyFromUser(appName, name, namelen); 37 | 38 | SceUInt32 sysrootCas = sceKernelSysrootGetCurrentAddressSpaceCB(); 39 | SceUInt32 sysrootCasSearch = sysrootCas; 40 | SceInt32 shift = 0; 41 | SceUInt32 searchType = -1; 42 | SceInt32 iAppName = *(SceInt32 *)appName; 43 | 44 | if (iAppName == 0x6E69616D) { // "main" 45 | searchType = SCE_KERNEL_PARTITION_MEMTYPE_MAIN | SCE_KERNEL_PARTITION_OWNER_SYSTEM; 46 | } 47 | else if (iAppName == 0x656D6167) { // "game" 48 | searchType = SCE_KERNEL_PARTITION_MEMTYPE_MAIN | SCE_KERNEL_PARTITION_OWNER_GAME; 49 | } 50 | 51 | for (int i = 0; i < 7; i++) 52 | { 53 | sysrootCasSearch = sysrootCas; 54 | shift = 0x1000 * i; 55 | sysrootCasSearch += shift; 56 | 57 | if (*(SceKernelPhyMemPart **)(sysrootCasSearch + 328) < 0x1000000 && *(SceKernelPhyMemPart **)(sysrootCasSearch + 328) > 0x1000) { 58 | memPart = *(SceKernelPhyMemPart **)(sysrootCasSearch + 328); 59 | if (searchType != -1) { 60 | if (memPart->type == searchType) 61 | break; 62 | } 63 | else { 64 | if (strstr(memPart->name, appName)) 65 | break; 66 | } 67 | } 68 | } 69 | 70 | s_casShift = shift; 71 | 72 | return SCE_OK; 73 | } 74 | 75 | SceInt32 psvsGetMem(SceInt32 casShift, PSVSMem *mem) 76 | { 77 | if (!mem) 78 | return SCE_KERNEL_ERROR_INVALID_ARGUMENT; 79 | 80 | PSVSMem kmemUsage; 81 | ScePhyMemPartInfoCore info; 82 | SceUInt32 sysrootCas = sceKernelSysrootGetCurrentAddressSpaceCB(); 83 | 84 | if (casShift < 0) { 85 | sysrootCas += s_casShift; 86 | } 87 | else { 88 | sysrootCas += casShift; 89 | } 90 | 91 | if (*(SceKernelPhyMemPart **)(sysrootCas + 328) < 0x1000000) { 92 | 93 | if (*(SceKernelPhyMemPart **)(sysrootCas + 328) > 0x1000) { 94 | sceKernelGetPhyMemPartInfoCore(*(SceKernelPhyMemPart **)(sysrootCas + 328), &info); 95 | PSVS_CHECK_ASSIGN(kmemUsage, mainFree, info.freeSize); 96 | PSVS_CHECK_ASSIGN(kmemUsage, mainTotal, info.totalSize); 97 | } 98 | else { 99 | PSVS_CHECK_ASSIGN(kmemUsage, mainFree, 0); 100 | PSVS_CHECK_ASSIGN(kmemUsage, mainTotal, 0); 101 | } 102 | 103 | if (*(SceKernelPhyMemPart **)(sysrootCas + 332) > 0x1000) { 104 | sceKernelGetPhyMemPartInfoCore(*(SceKernelPhyMemPart **)(sysrootCas + 332), &info); 105 | PSVS_CHECK_ASSIGN(kmemUsage, cdramFree, info.freeSize); 106 | PSVS_CHECK_ASSIGN(kmemUsage, cdramTotal, info.totalSize); 107 | } 108 | else { 109 | PSVS_CHECK_ASSIGN(kmemUsage, cdramFree, 0); 110 | PSVS_CHECK_ASSIGN(kmemUsage, cdramTotal, 0); 111 | } 112 | 113 | if (*(SceKernelPhyMemPart **)(sysrootCas + 316) > 0x1000) { 114 | sceKernelGetPhyMemPartInfoCore(*(SceKernelPhyMemPart **)(sysrootCas + 316), &info); 115 | PSVS_CHECK_ASSIGN(kmemUsage, phycontFree, info.freeSize); 116 | PSVS_CHECK_ASSIGN(kmemUsage, phycontTotal, info.totalSize); 117 | } 118 | else { 119 | PSVS_CHECK_ASSIGN(kmemUsage, phycontFree, 0); 120 | PSVS_CHECK_ASSIGN(kmemUsage, phycontTotal, 0); 121 | } 122 | 123 | if (*(SceKernelPhyMemPart **)(sysrootCas + 324) > 0x1000) { 124 | sceKernelGetPhyMemPartInfoCore(*(SceKernelPhyMemPart **)(sysrootCas + 324), &info); 125 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogFree, info.freeSize); 126 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogTotal, info.totalSize); 127 | } 128 | else { 129 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogFree, 0); 130 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogTotal, 0); 131 | } 132 | } 133 | else { 134 | PSVS_CHECK_ASSIGN(kmemUsage, mainFree, 0); 135 | PSVS_CHECK_ASSIGN(kmemUsage, mainTotal, 0); 136 | PSVS_CHECK_ASSIGN(kmemUsage, cdramFree, 0); 137 | PSVS_CHECK_ASSIGN(kmemUsage, cdramTotal, 0); 138 | PSVS_CHECK_ASSIGN(kmemUsage, phycontFree, 0); 139 | PSVS_CHECK_ASSIGN(kmemUsage, phycontTotal, 0); 140 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogFree, 0); 141 | PSVS_CHECK_ASSIGN(kmemUsage, cdialogTotal, 0); 142 | } 143 | 144 | return sceKernelCopyToUser(mem, &kmemUsage, sizeof(PSVSMem)); 145 | } 146 | 147 | SceVoid psvsCalcFps() 148 | { 149 | SceUInt32 tickNow = sceKernelGetProcessTimeLow(); 150 | SceUInt32 frametime = tickNow - s_perfTickFpsLast; 151 | 152 | // Update FPS when enough samples are collected 153 | if (g_perfFrametimeN > PSVS_PERF_FPS_SAMPLES) { 154 | SceUInt32 frametimeAvg = g_perfFrametimeSum / g_perfFrametimeN; 155 | sceAtomicStore32AcqRel(&s_perfFps, (SECOND + (frametimeAvg / 2) + 1) / frametimeAvg); 156 | g_perfFrametimeN = 0; 157 | g_perfFrametimeSum = 0; 158 | } 159 | 160 | g_perfFrametimeN++; 161 | g_perfFrametimeSum += frametime; 162 | s_perfTickFpsLast = tickNow; 163 | } 164 | 165 | SceInt32 psvsGetVeneziaInfo(PSVSVenezia *data) 166 | { 167 | PSVSVenezia kdata; 168 | SceInt32 ret = SCE_KERNEL_ERROR_UNSUP; 169 | 170 | if (!data) 171 | return SCE_KERNEL_ERROR_INVALID_ARGUMENT; 172 | 173 | if (!_sceVeneziaGetProcessorLoad) { 174 | tai_module_info_t info; 175 | memset(&info, 0, sizeof(tai_module_info_t)); 176 | info.size = sizeof(tai_module_info_t); 177 | taiGetModuleInfoForKernel(KERNEL_PID, "SceCodecEngineWrapper", &info); 178 | module_get_offset(KERNEL_PID, info.modid, 0, 0x36EC | 1, (uintptr_t *)&_sceVeneziaGetProcessorLoad); 179 | } 180 | 181 | if (_sceVeneziaGetProcessorLoad) 182 | ret = _sceVeneziaGetProcessorLoad(&kdata); 183 | 184 | sceKernelCopyToUser(data, &kdata, sizeof(PSVSVenezia)); 185 | 186 | return ret; 187 | } 188 | 189 | SceInt32 psvsGetBatteryInfo(PSVSBattery *data) 190 | { 191 | PSVSBattery kdata; 192 | SceInt32 ret = SCE_KERNEL_ERROR_UNSUP; 193 | 194 | kdata.current = 0; 195 | ret = sceSysconGetBatteryCurrent(&kdata.current); 196 | kdata.current = -kdata.current; 197 | 198 | sceKernelCopyToUser(data, &kdata, sizeof(PSVSBattery)); 199 | return ret; 200 | } -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "common.h" 7 | 8 | int(*sceKernelGetPhyMemPartInfoCore)(SceKernelPhyMemPart *pPhyMemPart, ScePhyMemPartInfoCore *pInfo); 9 | 10 | int(*sceSysconGetBatteryCurrent)(SceInt32 *res); 11 | 12 | SceVoid psvsCalcFps(); -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/lib.emd: -------------------------------------------------------------------------------- 1 | Module: PSVshellPlus_Kernel major_version: 1 minor_version: 0 2 | module_attr: exclusive_load 3 | module_attr: exclusive_start 4 | sceModuleInfo_type: 6 5 | module_function: module_start localname: __module_start 6 | module_function: module_stop localname: __module_stop 7 | Library: PSVshellPlus_KernelForUser attr: auto_export 8 | Library: PSVshellPlus_KernelForUser attr: syscall_export 9 | Library: PSVshellPlus_KernelForUser version: 1 10 | Library: PSVshellPlus_KernelForUser stubfile: "libPSVshellPlus_KernelForUser_stub" 11 | Library: PSVshellPlus_KernelForUser nidsuffix: "" 12 | Library: PSVshellPlus_KernelForUser function: psvsSetArmClockFrequency 13 | Library: PSVshellPlus_KernelForUser function: psvsSetGpuClockFrequency 14 | Library: PSVshellPlus_KernelForUser function: psvsSetGpuXbarClockFrequency 15 | Library: PSVshellPlus_KernelForUser function: psvsSetBusClockFrequency 16 | Library: PSVshellPlus_KernelForUser function: psvsGetClockFrequency 17 | Library: PSVshellPlus_KernelForUser function: psvsGetVeneziaInfo 18 | Library: PSVshellPlus_KernelForUser function: psvsGetBatteryInfo 19 | Library: PSVshellPlus_KernelForUser function: psvsClockFrequencyLockProc 20 | Library: PSVshellPlus_KernelForUser function: psvsClockFrequencyUnlockProc 21 | Library: PSVshellPlus_KernelForUser function: psvsClockFrequencyIsLockedProc 22 | Library: PSVshellPlus_KernelForUser function: psvsSetFpsCounterTarget 23 | Library: PSVshellPlus_KernelForUser function: psvsGetFps 24 | Library: PSVshellPlus_KernelForUser function: psvsGetMem 25 | Library: PSVshellPlus_KernelForUser function: psvsSetRecommendedCasShift 26 | Library: PSVshellPlus_KernelForUser function: psvsSetClockingPid -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/libPSVshellPlus_KernelForUser_stub.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrapheneCt/PSVshellPlus/b70f1c7fe78882ff1327d50ccd703b0ea429076e/PSVshellPlus_Kernel/libPSVshellPlus_KernelForUser_stub.a -------------------------------------------------------------------------------- /PSVshellPlus_Kernel/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "clock.h" 7 | #include "info.h" 8 | #include "common.h" 9 | 10 | SceInt32 g_psvsKpls = 0; 11 | 12 | static tai_hook_ref_t s_hookRef[20]; 13 | static SceUID s_hookId[20]; 14 | static SceUID s_injectId[1]; 15 | 16 | static SceInt32 s_fpsCounterTarget = -1; 17 | 18 | static SceUID s_reqPid = -1; 19 | 20 | static SceUInt32 *scePowerKPLSKey = NULL; 21 | 22 | static SceUInt32 **ScePervasiveBaseClk = NULL; 23 | 24 | int(*scePervasiveArmClockSelect)(int mul, int ndiv); 25 | 26 | SceVoid psvsSetFpsCounterTarget(SceInt32 target) 27 | { 28 | s_fpsCounterTarget = target; 29 | } 30 | 31 | SceVoid psvsSetClockingPid(SceUID pid) 32 | { 33 | s_reqPid = pid; 34 | } 35 | 36 | SceUID psvsGetClockingPid() 37 | { 38 | return s_reqPid; 39 | } 40 | 41 | //HOOKS 42 | int sceDisplaySetFrameBufInternal_patched(SceDisplayHead head, SceDisplayFrameBufType fb_idx, const SceDisplayFrameBuf *pFrameBuf, SceInt32 iUpdateTimingMode) 43 | { 44 | if (head != sceDisplayGetPrimaryHead() || !pFrameBuf || !pFrameBuf->base) 45 | goto DISPLAY_HOOK_RET; 46 | 47 | if (fb_idx == s_fpsCounterTarget) 48 | psvsCalcFps(); 49 | 50 | DISPLAY_HOOK_RET: 51 | 52 | return TAI_NEXT(sceDisplaySetFrameBufInternal_patched, s_hookRef[0], head, fb_idx, pFrameBuf, iUpdateTimingMode); 53 | } 54 | 55 | int scePowerSetArmClockFrequency_patched(int clock) 56 | { 57 | SceInt32 ret = SCE_OK; 58 | SceUID pid = s_reqPid; 59 | 60 | if (!psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_CPU) || clock > PSVS_CLOCK_MAGIC) { 61 | if (clock > PSVS_CLOCK_MAGIC) 62 | clock -= PSVS_CLOCK_MAGIC; 63 | 64 | if (clock == 500) { 65 | //First set to 444 to disable auto clockdown 66 | TAI_NEXT(scePowerSetArmClockFrequency_patched, s_hookRef[5], 444); 67 | 68 | //Write clock to KPLS 69 | ret = psvsClockFrequencyLockProc(pid, PSVS_500_MHZ_KEY); 70 | if (ret == SCE_OK) { 71 | // Apply mul:div (15:0) 72 | ret = scePervasiveArmClockSelect(15, 16 - 0); 73 | } 74 | 75 | return ret; 76 | } 77 | else { 78 | //Write clock to KPLS 79 | psvsClockFrequencyUnlockProc(pid, PSVS_500_MHZ_KEY); 80 | } 81 | 82 | ret = TAI_NEXT(scePowerSetArmClockFrequency_patched, s_hookRef[5], clock); 83 | } 84 | 85 | return ret; 86 | } 87 | int scePowerSetBusClockFrequency_patched(int clock) 88 | { 89 | if (!psvsClockFrequencyIsLockedProc(s_reqPid, PSVS_LOCK_DEVICE_BUS) || clock > PSVS_CLOCK_MAGIC) { 90 | if (clock > PSVS_CLOCK_MAGIC) 91 | clock -= PSVS_CLOCK_MAGIC; 92 | return TAI_NEXT(scePowerSetBusClockFrequency_patched, s_hookRef[6], clock); 93 | } 94 | 95 | return SCE_OK; 96 | } 97 | 98 | int scePowerSetGpuClockFrequencyInternal_patched(int corefreq, int mpfreq) 99 | { 100 | if (!psvsClockFrequencyIsLockedProc(s_reqPid, PSVS_LOCK_DEVICE_GPU_ES4) || corefreq > PSVS_CLOCK_MAGIC) { 101 | if (corefreq > PSVS_CLOCK_MAGIC) { 102 | corefreq -= PSVS_CLOCK_MAGIC; 103 | mpfreq -= PSVS_CLOCK_MAGIC; 104 | } 105 | 106 | return TAI_NEXT(scePowerSetGpuClockFrequencyInternal_patched, s_hookRef[7], corefreq, mpfreq); 107 | } 108 | 109 | return SCE_OK; 110 | } 111 | 112 | int scePowerSetGpuXbarClockFrequency_patched(int clock) 113 | { 114 | if (!psvsClockFrequencyIsLockedProc(s_reqPid, PSVS_LOCK_DEVICE_GPU_XBAR) || clock > PSVS_CLOCK_MAGIC) { 115 | if (clock > PSVS_CLOCK_MAGIC) 116 | clock -= PSVS_CLOCK_MAGIC; 117 | return TAI_NEXT(scePowerSetGpuXbarClockFrequency_patched, s_hookRef[8], clock); 118 | } 119 | 120 | return SCE_OK; 121 | } 122 | 123 | int __sce_aeabi_idiv0() 124 | { 125 | return 1; 126 | } 127 | 128 | long long __sce_aeabi_ldiv0() 129 | { 130 | return 1; 131 | } 132 | 133 | //MAIN 134 | int __module_start(SceSize args, const void * argp) 135 | { 136 | SceInt32 ret = 0; 137 | 138 | g_psvsKpls = sceKernelRegisterKPLS("PSVS", sizeof(PSVSKPLS)); 139 | if (g_psvsKpls < 0) 140 | return SCE_KERNEL_START_SUCCESS; 141 | 142 | tai_module_info_t tai_info; 143 | tai_info.size = sizeof(tai_module_info_t); 144 | taiGetModuleInfoForKernel(KERNEL_PID, "ScePower", &tai_info); 145 | 146 | module_get_offset(KERNEL_PID, tai_info.modid, 1, 0, (uintptr_t *)&scePowerKPLSKey); 147 | 148 | tai_info.size = sizeof(tai_module_info_t); 149 | taiGetModuleInfoForKernel(KERNEL_PID, "SceLowio", &tai_info); 150 | 151 | module_get_offset(KERNEL_PID, tai_info.modid, 1, 0xa0, (uintptr_t *)&ScePervasiveBaseClk); 152 | 153 | s_hookId[0] = taiHookFunctionExportForKernel(KERNEL_PID, &s_hookRef[0], 154 | "SceDisplay", 0x9FED47AC, 0x16466675, sceDisplaySetFrameBufInternal_patched); 155 | 156 | //Hook kernel functions 157 | s_hookId[5] = taiHookFunctionExportForKernel(KERNEL_PID, &s_hookRef[5], 158 | "ScePower", 0x1590166F, 0x74DB5AE5, scePowerSetArmClockFrequency_patched); 159 | s_hookId[6] = taiHookFunctionExportForKernel(KERNEL_PID, &s_hookRef[6], 160 | "ScePower", 0x1590166F, 0xB8D7B3FB, scePowerSetBusClockFrequency_patched); 161 | s_hookId[7] = taiHookFunctionExportForKernel(KERNEL_PID, &s_hookRef[7], 162 | "ScePower", 0x1590166F, 0x264C24FC, scePowerSetGpuClockFrequencyInternal_patched); 163 | s_hookId[8] = taiHookFunctionExportForKernel(KERNEL_PID, &s_hookRef[8], 164 | "ScePower", 0x1590166F, 0xA7739DBE, scePowerSetGpuXbarClockFrequency_patched); 165 | 166 | ret = module_get_export_func(KERNEL_PID, 167 | "SceSysmem", 0x63A519E5, 0x3650963F, (uintptr_t *)&sceKernelGetPhyMemPartInfoCore); // 3.60 168 | if (ret < 0) { 169 | module_get_export_func(KERNEL_PID, 170 | "SceSysmem", 0x02451F0F, 0xB9B69700, (uintptr_t *)&sceKernelGetPhyMemPartInfoCore); // 3.65 171 | } 172 | 173 | module_get_export_func(KERNEL_PID, 174 | "SceLowio", 0xE692C727, 0xE9D95643, (uintptr_t *)&scePervasiveArmClockSelect); 175 | 176 | module_get_export_func(KERNEL_PID, 177 | "SceSyscon", 0x60A35F64, 0x0826BA07, (uintptr_t *)&sceSysconGetBatteryCurrent); 178 | 179 | /* 180 | ret = module_get_export_func(KERNEL_PID, 181 | "SceSysmem", 0x63A519E5, 0x2F6F9C2C, (uintptr_t *)&sceKernelGetPhyMemPartAll); // 3.60 182 | if (ret < 0) { 183 | module_get_export_func(KERNEL_PID, 184 | "SceSysmem", 0x02451F0F, 0x021053DD, (uintptr_t *)&sceKernelGetPhyMemPartAll); // 3.65 185 | } 186 | 187 | ret = module_get_export_func(KERNEL_PID, 188 | "SceSysmem", 0x63A519E5, 0xF4FA0575, (uintptr_t *)&sceKernelGetPhyMemPartInfoByID); // 3.60 189 | if (ret < 0) { 190 | module_get_export_func(KERNEL_PID, 191 | "SceSysmem", 0x02451F0F, 0x029F5989, (uintptr_t *)&sceKernelGetPhyMemPartInfoByID); // 3.65 192 | } 193 | 194 | ret = module_get_export_func(KERNEL_PID, 195 | "SceSysmem", 0x63A519E5, 0x0FC24464, (uintptr_t *)&sceKernelGUIDGetObject); // 3.60 196 | if (ret < 0) { 197 | module_get_export_func(KERNEL_PID, 198 | "SceSysmem", 0x02451F0F, 0x0FC24464, (uintptr_t *)&sceKernelGUIDGetObject); // 3.65 199 | } 200 | 201 | ret = module_get_export_func(KERNEL_PID, 202 | "SceSysmem", 0x63A519E5, 0x4D809B47, (uintptr_t *)&sceKernelGetGamePhyMemPartGrowSize); // 3.60 203 | if (ret < 0) { 204 | module_get_export_func(KERNEL_PID, 205 | "SceSysmem", 0x02451F0F, 0xBC36755F, (uintptr_t *)&sceKernelGetGamePhyMemPartGrowSize); // 3.65 206 | } 207 | 208 | ret = module_get_export_func(KERNEL_PID, 209 | "SceSysmem", 0x63A519E5, 0x6B3F4102, (uintptr_t *)&sceKernelGrowPhyMemPart); // 3.60 210 | if (ret < 0) { 211 | module_get_export_func(KERNEL_PID, 212 | "SceSysmem", 0x02451F0F, 0x36FDA794, (uintptr_t *)&sceKernelGrowPhyMemPart); // 3.65 213 | } 214 | 215 | ret = module_get_export_func(KERNEL_PID, 216 | "SceSysmem", 0x63A519E5, 0xEEB85560, (uintptr_t *)&sceKernelShrinkPhyMemPart); // 3.60 217 | if (ret < 0) { 218 | module_get_export_func(KERNEL_PID, 219 | "SceSysmem", 0x02451F0F, 0x9B7E673F, (uintptr_t *)&sceKernelShrinkPhyMemPart); // 3.65 220 | } 221 | */ 222 | 223 | //Auto clockdown 224 | /* 225 | ret = module_get_export_func(KERNEL_PID, 226 | "SceSysmem", 0x2A5DBD38, 0xEEF091A7, (uintptr_t *)&sceKernelSysrootEnableAutoClockDown); // 3.60 227 | ret = module_get_export_func(KERNEL_PID, 228 | "SceSysmem", 0x2A5DBD38, 0xEE934615, (uintptr_t *)&sceKernelSysrootDisableAutoClockDown); // 3.60 229 | 230 | if (ret < 0) { 231 | module_get_export_func(KERNEL_PID, 232 | "SceSysmem", 0x2ED7F97A, 0xEEF091A7, (uintptr_t *)&sceKernelSysrootEnableAutoClockDown); // 3.65 233 | module_get_export_func(KERNEL_PID, 234 | "SceSysmem", 0x2ED7F97A, 0xEE934615, (uintptr_t *)&sceKernelSysrootDisableAutoClockDown); // 3.65 235 | } 236 | */ 237 | 238 | const SceUInt8 nop[] = { 0x00, 0xBF }; 239 | s_injectId[0] = taiInjectAbsForKernel(KERNEL_PID, 240 | (void *)((uintptr_t)scePervasiveArmClockSelect + 0x1D), &nop, 2); 241 | 242 | return SCE_KERNEL_START_SUCCESS; 243 | } 244 | 245 | int __module_stop(SceSize args, const void * argp) 246 | { 247 | return SCE_KERNEL_STOP_SUCCESS; 248 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/PSVshellPlus_Shell.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | PSVita 7 | 8 | 9 | Release 10 | PSVita 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {F84FFBB6-2013-43F2-985E-C94E0ADF711D} 33 | 34 | 35 | 36 | DynamicLibrary 37 | 38 | 39 | DynamicLibrary 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | _DEBUG;%(PreprocessorDefinitions); 64 | false 65 | NotUsing 66 | $(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;%(AdditionalIncludeDirectories) 67 | Cpp11 68 | Level3 69 | 70 | 71 | --no-standard-libraries --no-required-files 72 | -lSceDbg_stub;-lScePafTopLevel_stub_weak;-lScePafStdc_stub_weak;-lScePafCommon_stub_weak;-lScePafWidget_stub_weak;-lScePafThread_stub_weak;-lScePafResource_stub_weak;-lScePafGraphics_stub_weak;-lScePafMisc_stub_weak;-lSceLibKernel_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceAppMgrUser_stub;-lSceAppMgr_stub;-lSceSysmodule_stub;-lSceVshBridge_stub;-lSceDisplay_stub;-lScePower_stub;-lSceCodecEngineWrapper_stub;-ltaihen_stub;$(SolutionDir)PSVshellPlus_Kernel\libPSVshellPlus_KernelForUser_stub.a;-lsnc;%(AdditionalDependencies) 73 | $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;%(AdditionalLibraryDirectories) 74 | StripSymsAndDebug 75 | StripFuncsAndData 76 | true 77 | 78 | 79 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/vdsuite-pubprx.exe" --compress "$(LocalDebuggerCommand)" "$(LocalDebuggerCommand)" 80 | 81 | 82 | 83 | 84 | NDEBUG;SCE_DBG_LOGGING_ENABLED=0;%(PreprocessorDefinitions) 85 | Level3 86 | NotUsing 87 | $(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;%(AdditionalIncludeDirectories) 88 | Cpp11 89 | true 90 | 91 | 92 | --no-standard-libraries --no-required-files 93 | -lScePafTopLevel_stub_weak;-lScePafStdc_stub_weak;-lScePafCommon_stub_weak;-lScePafWidget_stub_weak;-lScePafThread_stub_weak;-lScePafResource_stub_weak;-lScePafGraphics_stub_weak;-lScePafMisc_stub_weak;-lSceLibKernel_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceAppMgrUser_stub;-lSceAppMgr_stub;-lSceSysmodule_stub;-lSceVshBridge_stub;-lSceDisplay_stub;-lScePower_stub;-lSceCodecEngineWrapper_stub;-ltaihen_stub;$(SolutionDir)PSVshellPlus_Kernel\libPSVshellPlus_KernelForUser_stub.a;-lsnc;%(AdditionalDependencies) 94 | $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;%(AdditionalLibraryDirectories) 95 | StripSymsAndDebug 96 | StripFuncsAndData 97 | true 98 | 99 | 100 | "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/vdsuite-pubprx.exe" --compress "$(LocalDebuggerCommand)" "$(LocalDebuggerCommand)" 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/PSVshellPlus_Shell.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;cc;s;asm 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | 37 | 38 | Header Files 39 | 40 | 41 | Header Files 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | Header Files 51 | 52 | 53 | Header Files 54 | 55 | 56 | Header Files 57 | 58 | 59 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/PSVshellPlus_Shell.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_en.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_fr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_ja.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_ru.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_zh-s.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/locale/psvshell_locale_zh-t.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/psvshell_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 47 | 58 | 63 | 86 | 130 | 169 | 261 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/RES_RCO/texture/tex_icon_impose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrapheneCt/PSVshellPlus/b70f1c7fe78882ff1327d50ccd703b0ea429076e/PSVshellPlus_Shell/RES_RCO/texture/tex_icon_impose.png -------------------------------------------------------------------------------- /PSVshellPlus_Shell/gen_rco.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SET PLUGIN=psvshell 3 | SET COMPILER=%SCE_PSP2_SDK_DIR%/host_tools/build/rco/bin/acdc.exe 4 | SET TMP=RES_RCO/RES_RCO_TMP 5 | 6 | @RD /S /Q "%TMP%" 7 | mkdir "%TMP%" 8 | 9 | for %%f in (RES_RCO/locale/*.xml) do ( 10 | 11 | "%COMPILER%" -c -i "RES_RCO/locale/%%f" -s "%SCE_PSP2_SDK_DIR%/host_tools/build/rco/def/rcs.cxmldef" -o "%TMP%/%%f.rcs" 12 | 13 | ) 14 | 15 | "%COMPILER%" -c -i "RES_RCO/%PLUGIN%_plugin.xml" -s "%SCE_PSP2_SDK_DIR%/host_tools/build/rco/def/rco.cxmldef" -o "%PLUGIN%_plugin.rco" -------------------------------------------------------------------------------- /PSVshellPlus_Shell/global.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | extern paf::Plugin *g_corePlugin; 7 | extern paf::ui::ScrollView *g_imposeRoot; -------------------------------------------------------------------------------- /PSVshellPlus_Shell/hud.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "global.h" 6 | #include "utils.h" 7 | #include "psvs.h" 8 | #include "hud.h" 9 | #include "tracker.h" 10 | 11 | using namespace paf; 12 | 13 | namespace psvs 14 | { 15 | static psvs::Hud *s_currentHud = NULL; 16 | static int32_t s_casShift = -1; 17 | 18 | Hud *Hud::GetCurrentHud() 19 | { 20 | return s_currentHud; 21 | } 22 | 23 | void Hud::SetCasShift(int32_t shift) 24 | { 25 | s_casShift = shift; 26 | } 27 | 28 | Hud::Hud(BaseType type) 29 | { 30 | Plugin::TemplateOpenParam tmpParam; 31 | Plugin::PageOpenParam pgiParam; 32 | 33 | pgiParam.overwrite_draw_priority = 6; 34 | coreRoot = g_corePlugin->PageOpen("psvs_page_hud", pgiParam); 35 | 36 | switch (type) { 37 | case BaseType_Mini: 38 | g_corePlugin->TemplateOpen(coreRoot, psvs_template_hud_bg_mini, tmpParam); 39 | this->root = coreRoot->GetChild(coreRoot->GetChildrenNum() - 1); 40 | this->root->Show(common::transition::Type_Fadein1); 41 | break; 42 | case BaseType_Full: 43 | g_corePlugin->TemplateOpen(coreRoot, psvs_template_hud_bg_full, tmpParam); 44 | this->root = coreRoot->GetChild(coreRoot->GetChildrenNum() - 1); 45 | this->root->Show(common::transition::Type_Fadein1); 46 | break; 47 | case BaseType_Dev: 48 | g_corePlugin->TemplateOpen(coreRoot, psvs_template_hud_bg_dev, tmpParam); 49 | this->root = coreRoot->GetChild(coreRoot->GetChildrenNum() - 1); 50 | this->root->Show(common::transition::Type_Fadein1); 51 | break; 52 | default: 53 | break; 54 | } 55 | 56 | psvsSetFpsCounterTarget(tracker::GetFpsCounterTarget()); 57 | } 58 | 59 | Hud::~Hud() 60 | { 61 | Plugin::PageCloseParam pgcParam; 62 | 63 | psvsSetFpsCounterTarget(PSVS_FPS_COUNTER_TARGET_NONE); 64 | 65 | pgcParam.fade = true; 66 | g_corePlugin->PageClose("psvs_page_hud", pgcParam); 67 | 68 | s_currentHud = NULL; 69 | } 70 | 71 | HudMicro::HudMicro() : Hud::Hud(Hud::BaseType_None) 72 | { 73 | Plugin::TemplateOpenParam tmpParam; 74 | 75 | this->oldFps = 0; 76 | 77 | g_corePlugin->TemplateOpen(coreRoot, psvs_template_hud_micro, tmpParam); 78 | this->fps = (ui::Text *)coreRoot->FindChild(psvs_text_fps_micro); 79 | this->root = this->fps; 80 | common::MainThreadCallList::Register(Update, this); 81 | s_currentHud = this; 82 | } 83 | 84 | HudMicro::~HudMicro() 85 | { 86 | common::MainThreadCallList::Unregister(Update, this); 87 | } 88 | 89 | void HudMicro::SetPosition(Position pos) 90 | { 91 | math::v4 vec(0.0f); 92 | 93 | switch (pos) { 94 | case Position_UpLeft: 95 | vec.set_x(-920.0f); 96 | vec.set_y(-10.0f); 97 | break; 98 | case Position_UpRight: 99 | vec.set_x(-16.0f); 100 | vec.set_y(-10.0f); 101 | break; 102 | case Position_DownLeft: 103 | vec.set_x(-920.0f); 104 | vec.set_y(-520.0f); 105 | break; 106 | case Position_DownRight: 107 | vec.set_x(-16.0f); 108 | vec.set_y(-520.0f); 109 | break; 110 | } 111 | 112 | this->root->SetPos(vec); 113 | } 114 | 115 | void HudMicro::Update(void *arg) 116 | { 117 | wstring wtext; 118 | wchar_t wbuf[6]; 119 | HudMicro *obj = (HudMicro *)arg; 120 | 121 | //Update FPS 122 | psvsSetFpsCounterTarget(tracker::GetFpsCounterTarget()); 123 | int32_t fps = psvsGetFps(); 124 | 125 | if (fps != obj->oldFps) { 126 | sce_paf_swprintf(wbuf, 6, L"%d", fps); 127 | wtext = wbuf; 128 | obj->fps->SetString(wtext); 129 | } 130 | 131 | obj->oldFps = fps; 132 | } 133 | 134 | HudMini::HudMini(Hud::BaseType type) : Hud::Hud(type) 135 | { 136 | Plugin::TemplateOpenParam tmpParam; 137 | 138 | this->oldFps = 0; 139 | 140 | g_corePlugin->TemplateOpen(this->root, psvs_template_hud_mini, tmpParam); 141 | 142 | this->cpuAvg[0] = (ui::Text *)this->root->FindChild(psvs_text_cpu_0); 143 | this->cpuAvg[1] = (ui::Text *)this->root->FindChild(psvs_text_cpu_1); 144 | this->cpuAvg[2] = (ui::Text *)this->root->FindChild(psvs_text_cpu_2); 145 | this->cpuAvg[3] = (ui::Text *)this->root->FindChild(psvs_text_cpu_3); 146 | this->cpuPeak = (ui::Text *)this->root->FindChild(psvs_text_cpu_peak); 147 | this->fps = (ui::Text *)this->root->FindChild(psvs_text_fps); 148 | 149 | common::MainThreadCallList::Register(Update, this); 150 | 151 | s_currentHud = this; 152 | } 153 | 154 | HudMini::~HudMini() 155 | { 156 | common::MainThreadCallList::Unregister(Update, this); 157 | } 158 | 159 | void HudMini::SetPosition(Position pos) 160 | { 161 | math::v4 vec(0.0f); 162 | 163 | switch (pos) { 164 | case Position_UpLeft: 165 | vec.set_x(10.0f); 166 | vec.set_y(-10.0f); 167 | break; 168 | case Position_UpRight: 169 | vec.set_x(600.0f); 170 | vec.set_y(-10.0f); 171 | break; 172 | case Position_DownLeft: 173 | vec.set_x(10.0f); 174 | vec.set_y(-470.0f); 175 | break; 176 | case Position_DownRight: 177 | vec.set_x(600.0f); 178 | vec.set_y(-470.0f); 179 | break; 180 | } 181 | 182 | this->root->SetPos(vec); 183 | } 184 | 185 | void HudMini::Update(void *arg) 186 | { 187 | wstring wtext; 188 | wchar_t wbuf[16]; 189 | PSVSCpu cpu; 190 | HudMini *obj = (HudMini *)arg; 191 | 192 | //Update FPS 193 | psvsSetFpsCounterTarget(tracker::GetFpsCounterTarget()); 194 | int32_t fps = psvsGetFps(); 195 | 196 | if (fps != obj->oldFps) { 197 | sce_paf_swprintf(wbuf, 16, L" %d FPS", fps); 198 | wtext = wbuf; 199 | obj->fps->SetString(wtext); 200 | //obj->fps->SetColor(ui::Text::ColorType_Text, 1, 2, &ScaleColor(30 - fps, 0, 30)); 201 | } 202 | 203 | obj->oldFps = fps; 204 | 205 | //Update CPU 206 | psvsGetCpu(&cpu); 207 | 208 | for (int i = 0; i < SCE_KERNEL_MAX_CPU; i++) { 209 | sce_paf_swprintf(wbuf, 16, L" %d%%", cpu.avg[i]); 210 | wtext = wbuf; 211 | obj->cpuAvg[i]->SetString(wtext); 212 | //obj->cpuAvg[i]->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(cpu.avg[i]), &ScaleColor(cpu.avg[i], 0, 100)); 213 | } 214 | 215 | sce_paf_swprintf(wbuf, 16, L" %d%%", cpu.peak); 216 | wtext = wbuf; 217 | obj->cpuPeak->SetString(wtext); 218 | //obj->cpuPeak->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(cpu.peak), &ScaleColor(cpu.peak, 0, 100)); 219 | } 220 | 221 | HudFull::HudFull() : HudMini::HudMini(Hud::BaseType_Full) 222 | { 223 | Plugin::TemplateOpenParam tmpParam; 224 | 225 | this->oldMem.mainTotal = __INT_MAX__; 226 | this->oldMem.cdramTotal = __INT_MAX__; 227 | this->oldMem.phycontTotal = __INT_MAX__; 228 | this->oldMem.cdialogTotal = __INT_MAX__; 229 | this->memTick = 0; 230 | 231 | g_corePlugin->TemplateOpen(this->root, psvs_template_hud_full, tmpParam); 232 | 233 | this->ramUsed = (ui::Text *)this->root->FindChild(psvs_text_ram_used); 234 | this->cdramUsed = (ui::Text *)this->root->FindChild(psvs_text_cdram_used); 235 | this->phyUsed = (ui::Text *)this->root->FindChild(psvs_text_phy_used); 236 | this->cdlgUsed = (ui::Text *)this->root->FindChild(psvs_text_cdlg_used); 237 | this->ramTotal = (ui::Text *)this->root->FindChild(psvs_text_ram_total); 238 | this->cdramTotal = (ui::Text *)this->root->FindChild(psvs_text_cdram_total); 239 | this->phyTotal = (ui::Text *)this->root->FindChild(psvs_text_phy_total); 240 | this->cdlgTotal = (ui::Text *)this->root->FindChild(psvs_text_cdlg_total); 241 | this->app = (ui::Text *)this->root->FindChild(psvs_text_app); 242 | 243 | common::MainThreadCallList::Register(Update, this); 244 | 245 | s_currentHud = this; 246 | } 247 | 248 | HudFull::~HudFull() 249 | { 250 | common::MainThreadCallList::Unregister(Update, this); 251 | } 252 | 253 | void HudFull::SetPosition(Position pos) 254 | { 255 | math::v4 vec(0.0f); 256 | 257 | switch (pos) { 258 | case Position_UpLeft: 259 | vec.set_x(10.0f); 260 | vec.set_y(-10.0f); 261 | break; 262 | case Position_UpRight: 263 | vec.set_x(600.0f); 264 | vec.set_y(-10.0f); 265 | break; 266 | case Position_DownLeft: 267 | vec.set_x(10.0f); 268 | vec.set_y(-334.0f); 269 | break; 270 | case Position_DownRight: 271 | vec.set_x(600.0f); 272 | vec.set_y(-334.0f); 273 | break; 274 | } 275 | 276 | this->root->SetPos(vec); 277 | } 278 | 279 | void HudFull::Update(void *arg) 280 | { 281 | wstring wtext; 282 | PSVSMem mem; 283 | uint32_t tickNow = sceKernelGetProcessTimeLow(); 284 | HudFull *obj = (HudFull *)arg; 285 | 286 | if (tickNow - obj->memTick > PSVS_FULL_UPDATE_WINDOW_USEC) { 287 | //Update memory 288 | psvsGetMem(s_casShift, &mem); 289 | 290 | if (obj->oldMem.mainTotal != mem.mainTotal || obj->oldMem.mainFree != mem.mainFree) 291 | SetMemLabel(mem.mainTotal - mem.mainFree, mem.mainTotal, obj->ramUsed, obj->ramTotal); 292 | if (obj->oldMem.cdramTotal != mem.cdramTotal || obj->oldMem.cdramFree != mem.cdramFree) 293 | SetMemLabel(mem.cdramTotal - mem.cdramFree, mem.cdramTotal, obj->cdramUsed, obj->cdramTotal); 294 | if (obj->oldMem.phycontTotal != mem.phycontTotal || obj->oldMem.phycontFree != mem.phycontFree) 295 | SetMemLabel(mem.phycontTotal - mem.phycontFree, mem.phycontTotal, obj->phyUsed, obj->phyTotal); 296 | if (obj->oldMem.cdialogTotal != mem.cdialogTotal || obj->oldMem.cdialogFree != mem.cdialogFree) 297 | SetMemLabel(mem.cdialogTotal - mem.cdialogFree, mem.cdialogTotal, obj->cdlgUsed, obj->cdlgTotal); 298 | 299 | //Update fg app 300 | obj->app->SetString(*tracker::GetCurrentAppName()); 301 | 302 | obj->memTick = tickNow; 303 | obj->oldMem = mem; 304 | } 305 | } 306 | 307 | void HudFull::SetMemLabel(uint32_t used, uint32_t total, paf::ui::Text *usedText, paf::ui::Text *totalText) 308 | { 309 | wstring wtext; 310 | wchar_t wbuf[32]; 311 | math::v4 green(0.0f, 1.0f, 0.0f, 1.0f); 312 | 313 | int32_t usedValue = ValueFromSize(used); 314 | int32_t totalValue = ValueFromSize(total); 315 | 316 | sce_paf_swprintf(wbuf, 32, L" %d %ls /", usedValue, UnitsFromSize(used)); 317 | wtext = wbuf; 318 | usedText->SetString(wtext); 319 | //usedText->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(usedValue), &ScaleColor(used, total - (total / 10), total + (total / 10))); 320 | 321 | sce_paf_swprintf(wbuf, 32, L" %d %ls", totalValue, UnitsFromSize(total)); 322 | wtext = wbuf; 323 | totalText->SetString(wtext); 324 | //totalText->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(totalValue), &green); 325 | } 326 | 327 | HudDev::HudDev() : HudMini::HudMini(Hud::BaseType_Dev) 328 | { 329 | Plugin::TemplateOpenParam tmpParam; 330 | 331 | this->oldMem.mainTotal = __INT_MAX__; 332 | this->oldMem.cdramTotal = __INT_MAX__; 333 | this->oldMem.phycontTotal = __INT_MAX__; 334 | this->oldMem.cdialogTotal = __INT_MAX__; 335 | this->oldVnz.core0 = __INT_MAX__; 336 | this->oldVnz.core1 = __INT_MAX__; 337 | this->oldVnz.core2 = __INT_MAX__; 338 | this->oldVnz.core3 = __INT_MAX__; 339 | this->oldVnz.core4 = __INT_MAX__; 340 | this->oldVnz.core5 = __INT_MAX__; 341 | this->oldVnz.core6 = __INT_MAX__; 342 | this->oldVnz.core7 = __INT_MAX__; 343 | this->oldVnz.average = __INT_MAX__; 344 | this->oldVnz.peak = __INT_MAX__; 345 | this->vnzNeedUpdate = false; 346 | this->memTickCommon = 0; 347 | this->memTickVnzUpd = 0; 348 | this->memTickBat = 0; 349 | 350 | g_corePlugin->TemplateOpen(this->root, psvs_template_hud_dev, tmpParam); 351 | 352 | this->vnz[0] = (ui::Text *)this->root->FindChild(psvs_text_vnz_0); 353 | this->vnz[1] = (ui::Text *)this->root->FindChild(psvs_text_vnz_1); 354 | this->vnz[2] = (ui::Text *)this->root->FindChild(psvs_text_vnz_2); 355 | this->vnz[3] = (ui::Text *)this->root->FindChild(psvs_text_vnz_3); 356 | this->vnz[4] = (ui::Text *)this->root->FindChild(psvs_text_vnz_4); 357 | this->vnz[5] = (ui::Text *)this->root->FindChild(psvs_text_vnz_5); 358 | this->vnz[6] = (ui::Text *)this->root->FindChild(psvs_text_vnz_6); 359 | this->vnz[7] = (ui::Text *)this->root->FindChild(psvs_text_vnz_7); 360 | this->vnzPeak = (ui::Text *)this->root->FindChild(psvs_text_vnz_peak); 361 | this->batCur = (ui::Text *)this->root->FindChild(psvs_text_bat_cur); 362 | 363 | if (SCE_PAF_IS_DOLCE) { 364 | wstring wtext = L"DOLCE"; 365 | this->batCur->SetString(wtext); 366 | } 367 | 368 | this->ramUsed = (ui::Text *)this->root->FindChild(HudFull::psvs_text_ram_used); 369 | this->cdramUsed = (ui::Text *)this->root->FindChild(HudFull::psvs_text_cdram_used); 370 | this->phyUsed = (ui::Text *)this->root->FindChild(HudFull::psvs_text_phy_used); 371 | this->cdlgUsed = (ui::Text *)this->root->FindChild(HudFull::psvs_text_cdlg_used); 372 | this->ramTotal = (ui::Text *)this->root->FindChild(HudFull::psvs_text_ram_total); 373 | this->cdramTotal = (ui::Text *)this->root->FindChild(HudFull::psvs_text_cdram_total); 374 | this->phyTotal = (ui::Text *)this->root->FindChild(HudFull::psvs_text_phy_total); 375 | this->cdlgTotal = (ui::Text *)this->root->FindChild(HudFull::psvs_text_cdlg_total); 376 | this->app = (ui::Text *)this->root->FindChild(HudFull::psvs_text_app); 377 | 378 | common::MainThreadCallList::Register(Update, this); 379 | 380 | s_currentHud = this; 381 | } 382 | 383 | HudDev::~HudDev() 384 | { 385 | common::MainThreadCallList::Unregister(Update, this); 386 | } 387 | 388 | void HudDev::SetPosition(Position pos) 389 | { 390 | math::v4 vec(0.0f); 391 | 392 | switch (pos) { 393 | case Position_UpLeft: 394 | vec.set_x(10.0f); 395 | vec.set_y(-10.0f); 396 | break; 397 | case Position_UpRight: 398 | vec.set_x(600.0f); 399 | vec.set_y(-10.0f); 400 | break; 401 | case Position_DownLeft: 402 | vec.set_x(10.0f); 403 | vec.set_y(-256.0f); 404 | break; 405 | case Position_DownRight: 406 | vec.set_x(600.0f); 407 | vec.set_y(-256.0f); 408 | break; 409 | } 410 | 411 | this->root->SetPos(vec); 412 | } 413 | 414 | void HudDev::Update(void *arg) 415 | { 416 | wstring wtext; 417 | wchar_t wbuf[16]; 418 | PSVSMem mem; 419 | PSVSVenezia vnz; 420 | PSVSBattery bat; 421 | uint32_t tickNow = sceKernelGetProcessTimeLow(); 422 | HudDev *obj = (HudDev *)arg; 423 | 424 | if (tickNow - obj->memTickVnzUpd > PSVS_VNZ_UPDATE_WINDOW_USEC) { 425 | //Update Venezia 426 | sceCodecEnginePmonStop(); 427 | psvsGetVeneziaInfo(&vnz); 428 | sceCodecEnginePmonReset(); 429 | sceCodecEnginePmonStart(); 430 | obj->vnzNeedUpdate = true; 431 | obj->memTickVnzUpd = tickNow; 432 | } 433 | 434 | if (!SCE_PAF_IS_DOLCE && (tickNow - obj->memTickBat > PSVS_BAT_UPDATE_WINDOW_USEC)) { 435 | //Update battery 436 | psvsGetBatteryInfo(&bat); 437 | 438 | if (obj->oldBat.current != bat.current) { 439 | sce_paf_swprintf(wbuf, 16, L" %d mA", bat.current); 440 | wtext = wbuf; 441 | obj->batCur->SetString(wtext); 442 | } 443 | 444 | obj->memTickBat = tickNow; 445 | obj->oldBat = bat; 446 | } 447 | 448 | if (tickNow - obj->memTickCommon > PSVS_FULL_UPDATE_WINDOW_USEC) { 449 | 450 | if (obj->vnzNeedUpdate) { 451 | if (obj->oldVnz.core0 != vnz.core0) { 452 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core0); 453 | wtext = wbuf; 454 | obj->vnz[0]->SetString(wtext); 455 | } 456 | if (obj->oldVnz.core1 != vnz.core1) { 457 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core1); 458 | wtext = wbuf; 459 | obj->vnz[1]->SetString(wtext); 460 | } 461 | if (obj->oldVnz.core2 != vnz.core2) { 462 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core2); 463 | wtext = wbuf; 464 | obj->vnz[2]->SetString(wtext); 465 | } 466 | if (obj->oldVnz.core3 != vnz.core3) { 467 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core3); 468 | wtext = wbuf; 469 | obj->vnz[3]->SetString(wtext); 470 | } 471 | if (obj->oldVnz.core4 != vnz.core4) { 472 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core4); 473 | wtext = wbuf; 474 | obj->vnz[4]->SetString(wtext); 475 | } 476 | if (obj->oldVnz.core5 != vnz.core5) { 477 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core5); 478 | wtext = wbuf; 479 | obj->vnz[5]->SetString(wtext); 480 | } 481 | if (obj->oldVnz.core6 != vnz.core6) { 482 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core6); 483 | wtext = wbuf; 484 | obj->vnz[6]->SetString(wtext); 485 | } 486 | if (obj->oldVnz.core7 != vnz.core7) { 487 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.core7); 488 | wtext = wbuf; 489 | obj->vnz[7]->SetString(wtext); 490 | } 491 | if (obj->oldVnz.peak != vnz.peak) { 492 | sce_paf_swprintf(wbuf, 16, L" %d%%", vnz.peak); 493 | wtext = wbuf; 494 | obj->vnzPeak->SetString(wtext); 495 | } 496 | obj->vnzNeedUpdate = SCE_FALSE; 497 | } 498 | 499 | //Update memory 500 | psvsGetMem(s_casShift, &mem); 501 | 502 | if (obj->oldMem.mainTotal != mem.mainTotal || obj->oldMem.mainFree != mem.mainFree) 503 | SetMemLabel(mem.mainTotal - mem.mainFree, mem.mainTotal, obj->ramUsed, obj->ramTotal); 504 | if (obj->oldMem.cdramTotal != mem.cdramTotal || obj->oldMem.cdramFree != mem.cdramFree) 505 | SetMemLabel(mem.cdramTotal - mem.cdramFree, mem.cdramTotal, obj->cdramUsed, obj->cdramTotal); 506 | if (obj->oldMem.phycontTotal != mem.phycontTotal || obj->oldMem.phycontFree != mem.phycontFree) 507 | SetMemLabel(mem.phycontTotal - mem.phycontFree, mem.phycontTotal, obj->phyUsed, obj->phyTotal); 508 | if (obj->oldMem.cdialogTotal != mem.cdialogTotal || obj->oldMem.cdialogFree != mem.cdialogFree) 509 | SetMemLabel(mem.cdialogTotal - mem.cdialogFree, mem.cdialogTotal, obj->cdlgUsed, obj->cdlgTotal); 510 | 511 | //Update fg app 512 | obj->app->SetString(*tracker::GetCurrentAppName()); 513 | 514 | obj->memTickCommon = tickNow; 515 | obj->oldMem = mem; 516 | obj->oldVnz = vnz; 517 | } 518 | } 519 | 520 | void HudDev::SetMemLabel(uint32_t used, uint32_t total, paf::ui::Text *usedText, paf::ui::Text *totalText) 521 | { 522 | wstring wtext; 523 | wchar_t wbuf[32]; 524 | math::v4 green(0.0f, 1.0f, 0.0f, 1.0f); 525 | 526 | int32_t usedValue = ValueFromSize(used); 527 | int32_t totalValue = ValueFromSize(total); 528 | 529 | sce_paf_swprintf(wbuf, 32, L" %d %ls /", usedValue, UnitsFromSize(used)); 530 | wtext = wbuf; 531 | usedText->SetString(wtext); 532 | //usedText->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(usedValue), &ScaleColor(used, total - (total / 10), total + (total / 10))); 533 | 534 | sce_paf_swprintf(wbuf, 32, L" %d %ls", totalValue, UnitsFromSize(total)); 535 | wtext = wbuf; 536 | totalText->SetString(wtext); 537 | //totalText->SetColor(ui::Text::ColorType_Text, 1, LengthOfValue(totalValue), &green); 538 | } 539 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/hud.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace psvs 7 | { 8 | 9 | class Hud 10 | { 11 | public: 12 | 13 | enum BaseType 14 | { 15 | BaseType_None, 16 | BaseType_Mini, 17 | BaseType_Full, 18 | BaseType_Dev, 19 | }; 20 | 21 | enum Position 22 | { 23 | Position_UpLeft, 24 | Position_UpRight, 25 | Position_DownLeft, 26 | Position_DownRight 27 | }; 28 | 29 | enum Hash 30 | { 31 | psvs_page_hud = 0x6c5a295a, 32 | psvs_template_hud_bg_mini = 0x6147e689, 33 | psvs_template_hud_bg_full = 0x34b71af6, 34 | psvs_template_hud_bg_dev = 0xddc6d9a0, 35 | }; 36 | 37 | static Hud *GetCurrentHud(); 38 | static void SetCasShift(int32_t shift); 39 | 40 | Hud(BaseType type); 41 | 42 | virtual ~Hud(); 43 | virtual void SetPosition(Position pos) = 0; 44 | 45 | protected: 46 | 47 | paf::ui::Widget *root; 48 | paf::ui::Scene *coreRoot; 49 | 50 | }; 51 | 52 | class HudMicro : public Hud 53 | { 54 | public: 55 | 56 | enum Hash 57 | { 58 | psvs_template_hud_micro = 0xcd140cb5, 59 | psvs_text_fps_micro = 0x8d7c94a7, 60 | }; 61 | 62 | static void Update(void *arg); 63 | 64 | HudMicro(); 65 | 66 | virtual ~HudMicro(); 67 | virtual void SetPosition(Position pos); 68 | 69 | protected: 70 | 71 | paf::ui::Text *fps; 72 | 73 | int32_t oldFps; 74 | }; 75 | 76 | class HudMini : public Hud 77 | { 78 | public: 79 | 80 | enum Hash 81 | { 82 | psvs_template_hud_mini = 0xf9d6a49a, 83 | psvs_text_cpu_0 = 0xc1df9fc1, 84 | psvs_text_cpu_1 = 0x4c9f265a, 85 | psvs_text_cpu_2 = 0x63d6aaf3, 86 | psvs_text_cpu_3 = 0xc401e054, 87 | psvs_text_cpu_peak = 0x4a1b0900, 88 | psvs_text_fps = 0x7a26c57e, 89 | }; 90 | 91 | static void Update(void *arg); 92 | 93 | HudMini(Hud::BaseType type = Hud::BaseType_Mini); 94 | 95 | virtual ~HudMini(); 96 | virtual void SetPosition(Position pos); 97 | 98 | protected: 99 | 100 | paf::ui::Text *cpuAvg[SCE_KERNEL_MAX_CPU]; 101 | paf::ui::Text *cpuPeak; 102 | paf::ui::Text *fps; 103 | 104 | int32_t oldFps; 105 | }; 106 | 107 | class HudFull : public HudMini 108 | { 109 | public: 110 | 111 | #define PSVS_FULL_UPDATE_WINDOW_USEC (100000) 112 | 113 | enum Hash 114 | { 115 | psvs_template_hud_full = 0x367de75c, 116 | psvs_text_ram_used = 0xe161c101, 117 | psvs_text_ram_total = 0x588ba69b, 118 | psvs_text_cdram_used = 0x4561b54f, 119 | psvs_text_cdram_total = 0x02c2c2ba, 120 | psvs_text_phy_used = 0x463933d3, 121 | psvs_text_phy_total = 0x62589882, 122 | psvs_text_cdlg_used = 0x3ce6a143, 123 | psvs_text_cdlg_total = 0x937ff95c, 124 | psvs_text_app = 0xee6b6287, 125 | }; 126 | 127 | static void Update(void *arg); 128 | 129 | HudFull(); 130 | 131 | virtual ~HudFull(); 132 | virtual void SetPosition(Position pos); 133 | 134 | static void SetMemLabel(uint32_t used, uint32_t total, paf::ui::Text *usedText, paf::ui::Text *totalText); 135 | 136 | protected: 137 | 138 | paf::ui::Text *ramUsed; 139 | paf::ui::Text *cdramUsed; 140 | paf::ui::Text *phyUsed; 141 | paf::ui::Text *cdlgUsed; 142 | paf::ui::Text *ramTotal; 143 | paf::ui::Text *cdramTotal; 144 | paf::ui::Text *phyTotal; 145 | paf::ui::Text *cdlgTotal; 146 | paf::ui::Text *app; 147 | 148 | uint32_t memTick; 149 | PSVSMem oldMem; 150 | }; 151 | 152 | class HudDev : public HudMini 153 | { 154 | public: 155 | 156 | #define PSVS_VNZ_UPDATE_WINDOW_USEC (1000) 157 | #define PSVS_BAT_UPDATE_WINDOW_USEC (500000) 158 | 159 | enum Hash 160 | { 161 | psvs_template_hud_dev = 0xf6e17467, 162 | psvs_text_vnz_0 = 0x7524c263, 163 | psvs_text_vnz_1 = 0x56c14879, 164 | psvs_text_vnz_2 = 0x03cd5e60, 165 | psvs_text_vnz_3 = 0x8c6b209e, 166 | psvs_text_vnz_4 = 0x98e73415, 167 | psvs_text_vnz_5 = 0xd8c59975, 168 | psvs_text_vnz_6 = 0x7cb8ea8d, 169 | psvs_text_vnz_7 = 0xf646c3a1, 170 | psvs_text_vnz_peak = 0xebc15716, 171 | psvs_text_bat_cur = 0x18869f58, 172 | }; 173 | 174 | static void Update(void *arg); 175 | 176 | HudDev(); 177 | 178 | virtual ~HudDev(); 179 | virtual void SetPosition(Position pos); 180 | 181 | static void SetMemLabel(uint32_t used, uint32_t total, paf::ui::Text *usedText, paf::ui::Text *totalText); 182 | 183 | protected: 184 | 185 | paf::ui::Text *vnz[8]; 186 | paf::ui::Text *vnzPeak; 187 | paf::ui::Text *batCur; 188 | paf::ui::Text *ramUsed; 189 | paf::ui::Text *cdramUsed; 190 | paf::ui::Text *phyUsed; 191 | paf::ui::Text *cdlgUsed; 192 | paf::ui::Text *ramTotal; 193 | paf::ui::Text *cdramTotal; 194 | paf::ui::Text *phyTotal; 195 | paf::ui::Text *cdlgTotal; 196 | paf::ui::Text *app; 197 | 198 | uint32_t memTickCommon; 199 | uint32_t memTickVnzUpd; 200 | uint32_t memTickBat; 201 | bool vnzNeedUpdate; 202 | PSVSMem oldMem; 203 | PSVSVenezia oldVnz; 204 | PSVSBattery oldBat; 205 | }; 206 | 207 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/impose.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "global.h" 6 | #include "utils.h" 7 | #include "psvs.h" 8 | #include "impose.h" 9 | #include "tracker.h" 10 | #include "hud.h" 11 | #include "profile.h" 12 | 13 | using namespace paf; 14 | 15 | namespace psvs 16 | { 17 | static int32_t s_hudMode = Impose::HudMode_Off; 18 | static int32_t s_hudPos = Hud::Position_UpLeft; 19 | static int32_t s_cas = -0x1000; 20 | 21 | const int32_t k_cpuClock[] = { 41, 83, 111, 166, 222, 333, 444, 500 }; 22 | const int32_t k_gpuClock[] = { 41, 55, 83, 111, 166, 222 }; 23 | const int32_t k_busClock[] = { 55, 83, 111, 166, 222 }; 24 | const int32_t k_xbarClock[] = { 83, 111, 166 }; 25 | 26 | void Impose::ControlButtonCBFun(int32_t type, ui::Handler *self, ui::Event *e, void *userdata) 27 | { 28 | wstring wstr; 29 | wchar_t casVal[2]; 30 | int32_t arraySize = 0; 31 | const int32_t *arrayPtr = NULL; 32 | int32_t direction = 0; 33 | int32_t currentClock = 0; 34 | Impose *obj = (Impose *)userdata; 35 | ui::Widget *wdg = (ui::Widget *)self; 36 | Hud *currHud = NULL; 37 | int32_t(*clockSet)(int clock) = NULL; 38 | PSVSClockFrequency clock; 39 | psvsGetClockFrequency(&clock); 40 | 41 | switch (wdg->GetName().GetIDHash()) { 42 | case psvs_button_impose_cpu_down: 43 | currentClock = clock.cpu; 44 | clockSet = psvsSetArmClockFrequency; 45 | direction = -1; 46 | arraySize = sizeof(k_cpuClock) / sizeof(int32_t); 47 | arrayPtr = k_cpuClock; 48 | break; 49 | case psvs_button_impose_cpu_up: 50 | currentClock = clock.cpu; 51 | clockSet = psvsSetArmClockFrequency; 52 | direction = 1; 53 | arraySize = sizeof(k_cpuClock) / sizeof(int32_t); 54 | arrayPtr = k_cpuClock; 55 | break; 56 | case psvs_button_impose_gpu_down: 57 | currentClock = clock.gpu; 58 | clockSet = psvsSetGpuClockFrequency; 59 | direction = -1; 60 | arraySize = sizeof(k_gpuClock) / sizeof(int32_t); 61 | arrayPtr = k_gpuClock; 62 | break; 63 | case psvs_button_impose_gpu_up: 64 | currentClock = clock.gpu; 65 | clockSet = psvsSetGpuClockFrequency; 66 | direction = 1; 67 | arraySize = sizeof(k_gpuClock) / sizeof(int32_t); 68 | arrayPtr = k_gpuClock; 69 | break; 70 | /* 71 | case psvs_button_impose_bus_down: 72 | currentClock = clock.bus; 73 | clockSet = psvsSetBusClockFrequency; 74 | direction = -1; 75 | arraySize = sizeof(k_busClock) / sizeof(int32_t); 76 | arrayPtr = k_busClock; 77 | break; 78 | case psvs_button_impose_bus_up: 79 | currentClock = clock.bus; 80 | clockSet = psvsSetBusClockFrequency; 81 | direction = 1; 82 | arraySize = sizeof(k_busClock) / sizeof(int32_t); 83 | arrayPtr = k_busClock; 84 | break; 85 | */ 86 | case psvs_button_impose_xbar_down: 87 | currentClock = clock.xbar; 88 | clockSet = psvsSetGpuXbarClockFrequency; 89 | direction = -1; 90 | arraySize = sizeof(k_xbarClock) / sizeof(int32_t); 91 | arrayPtr = k_xbarClock; 92 | break; 93 | case psvs_button_impose_xbar_up: 94 | currentClock = clock.xbar; 95 | clockSet = psvsSetGpuXbarClockFrequency; 96 | direction = 1; 97 | arraySize = sizeof(k_xbarClock) / sizeof(int32_t); 98 | arrayPtr = k_xbarClock; 99 | break; 100 | case psvs_button_impose_hud_down: 101 | if (s_hudMode != HudMode_Off) { 102 | s_hudMode--; 103 | } 104 | else { 105 | break; 106 | } 107 | thread::RMutex::main_thread_mutex.Lock(); 108 | currHud = Hud::GetCurrentHud(); 109 | if (currHud != NULL) { 110 | delete currHud; 111 | } 112 | switch (s_hudMode) { 113 | case HudMode_Off: 114 | wstr = g_corePlugin->GetString("psvs_msg_hud_off"); 115 | break; 116 | case HudMode_Micro: 117 | wstr = g_corePlugin->GetString("psvs_msg_hud_micro"); 118 | currHud = new HudMicro(); 119 | currHud->SetPosition((Hud::Position)s_hudPos); 120 | break; 121 | case HudMode_Mini: 122 | wstr = g_corePlugin->GetString("psvs_msg_hud_mini"); 123 | currHud = new HudMini(); 124 | currHud->SetPosition((Hud::Position)s_hudPos); 125 | break; 126 | case HudMode_Full: 127 | wstr = g_corePlugin->GetString("psvs_msg_hud_full"); 128 | currHud = new HudFull(); 129 | currHud->SetPosition((Hud::Position)s_hudPos); 130 | break; 131 | case HudMode_Dev: 132 | wstr = g_corePlugin->GetString("psvs_msg_hud_dev"); 133 | currHud = new HudDev(); 134 | currHud->SetPosition((Hud::Position)s_hudPos); 135 | break; 136 | } 137 | obj->hud->SetString(wstr); 138 | thread::RMutex::main_thread_mutex.Unlock(); 139 | break; 140 | case psvs_button_impose_hud_up: 141 | if (s_hudMode != HudMode_Dev) { 142 | s_hudMode++; 143 | } 144 | else { 145 | break; 146 | } 147 | thread::RMutex::main_thread_mutex.Lock(); 148 | currHud = Hud::GetCurrentHud(); 149 | if (currHud != NULL) { 150 | delete currHud; 151 | } 152 | switch (s_hudMode) { 153 | case HudMode_Off: 154 | wstr = g_corePlugin->GetString("psvs_msg_hud_off"); 155 | break; 156 | case HudMode_Micro: 157 | wstr = g_corePlugin->GetString("psvs_msg_hud_micro"); 158 | currHud = new HudMicro(); 159 | currHud->SetPosition((Hud::Position)s_hudPos); 160 | break; 161 | case HudMode_Mini: 162 | wstr = g_corePlugin->GetString("psvs_msg_hud_mini"); 163 | currHud = new HudMini(); 164 | currHud->SetPosition((Hud::Position)s_hudPos); 165 | break; 166 | case HudMode_Full: 167 | wstr = g_corePlugin->GetString("psvs_msg_hud_full"); 168 | currHud = new HudFull(); 169 | currHud->SetPosition((Hud::Position)s_hudPos); 170 | break; 171 | case HudMode_Dev: 172 | wstr = g_corePlugin->GetString("psvs_msg_hud_dev"); 173 | currHud = new HudDev(); 174 | currHud->SetPosition((Hud::Position)s_hudPos); 175 | break; 176 | } 177 | obj->hud->SetString(wstr); 178 | thread::RMutex::main_thread_mutex.Unlock(); 179 | break; 180 | case psvs_button_impose_hud_pos_down: 181 | currHud = Hud::GetCurrentHud(); 182 | if (s_hudPos != Hud::Position_UpLeft) { 183 | s_hudPos--; 184 | } 185 | else { 186 | break; 187 | } 188 | thread::RMutex::main_thread_mutex.Lock(); 189 | switch (s_hudPos) { 190 | case Hud::Position_UpLeft: 191 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ul"); 192 | break; 193 | case Hud::Position_UpRight: 194 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ur"); 195 | break; 196 | case Hud::Position_DownLeft: 197 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dl"); 198 | break; 199 | case Hud::Position_DownRight: 200 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dr"); 201 | break; 202 | } 203 | obj->hudpos->SetString(wstr); 204 | if (currHud != NULL) 205 | currHud->SetPosition((Hud::Position)s_hudPos); 206 | thread::RMutex::main_thread_mutex.Unlock(); 207 | break; 208 | case psvs_button_impose_hud_pos_up: 209 | currHud = Hud::GetCurrentHud(); 210 | if (s_hudPos != Hud::Position_DownRight) { 211 | s_hudPos++; 212 | } 213 | else { 214 | break; 215 | } 216 | thread::RMutex::main_thread_mutex.Lock(); 217 | switch (s_hudPos) { 218 | case Hud::Position_UpLeft: 219 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ul"); 220 | break; 221 | case Hud::Position_UpRight: 222 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ur"); 223 | break; 224 | case Hud::Position_DownLeft: 225 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dl"); 226 | break; 227 | case Hud::Position_DownRight: 228 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dr"); 229 | break; 230 | } 231 | obj->hudpos->SetString(wstr); 232 | if (currHud != NULL) 233 | currHud->SetPosition((Hud::Position)s_hudPos); 234 | thread::RMutex::main_thread_mutex.Unlock(); 235 | break; 236 | case psvs_button_impose_cas_down: 237 | if (s_cas >= 0) { 238 | s_cas -= 0x1000; 239 | } 240 | else { 241 | break; 242 | } 243 | thread::RMutex::main_thread_mutex.Lock(); 244 | if (s_cas < 0) { 245 | wstr = g_corePlugin->GetString("psvs_msg_auto"); 246 | } 247 | else { 248 | sce_paf_swprintf(casVal, 2, L"%d", s_cas / 0x1000); 249 | wstr = casVal; 250 | } 251 | obj->cas->SetString(wstr); 252 | Hud::SetCasShift(s_cas); 253 | thread::RMutex::main_thread_mutex.Unlock(); 254 | break; 255 | case psvs_button_impose_cas_up: 256 | if (s_cas != 0x7000) { 257 | s_cas += 0x1000; 258 | } 259 | else { 260 | break; 261 | } 262 | thread::RMutex::main_thread_mutex.Lock(); 263 | sce_paf_swprintf(casVal, 2, L"%d", s_cas / 0x1000); 264 | wstr = casVal; 265 | obj->cas->SetString(wstr); 266 | Hud::SetCasShift(s_cas); 267 | thread::RMutex::main_thread_mutex.Unlock(); 268 | break; 269 | } 270 | 271 | if (direction == -1) { 272 | for (int i = arraySize - 1; i > -1; i--) { 273 | if (arrayPtr[i] < currentClock) { 274 | clockSet(arrayPtr[i]); 275 | break; 276 | } 277 | } 278 | } 279 | else if (direction == 1) { 280 | for (int i = 0; i < arraySize; i++) { 281 | if (arrayPtr[i] > currentClock) { 282 | clockSet(arrayPtr[i]); 283 | break; 284 | } 285 | } 286 | } 287 | } 288 | 289 | void Impose::ProfileButtonCBFun(int32_t type, ui::Handler *self, ui::Event *e, void *userdata) 290 | { 291 | ui::Button *wdg = (ui::Button *)self; 292 | uint32_t hash = wdg->GetName().GetIDHash(); 293 | 294 | if (hash == psvs_button_impose_save) { 295 | psvs::Profile *profile = new psvs::Profile(); 296 | profile->Save(); 297 | delete profile; 298 | 299 | tracker::ReloadCurrentProfile(); 300 | wdg->Enable(true); 301 | } 302 | else if (hash == psvs_button_impose_delete) { 303 | psvs::Profile::Delete(); 304 | tracker::ReloadCurrentProfile(); 305 | wdg->Disable(true); 306 | } 307 | } 308 | 309 | void Impose::LockCBFun(int32_t type, ui::Handler *self, ui::Event *e, void *userdata) 310 | { 311 | ui::CheckBox *wdg = (ui::CheckBox *)self; 312 | ScePID pid = psvs::tracker::GetCurrentPID(); 313 | PsvsLockDevice target = PSVS_LOCK_DEVICE_NONE; 314 | 315 | switch (wdg->GetName().GetIDHash()) { 316 | case psvs_check_box_impose_cpu_lock: 317 | target = PSVS_LOCK_DEVICE_CPU; 318 | break; 319 | case psvs_check_box_impose_gpu_lock: 320 | target = PSVS_LOCK_DEVICE_GPU_ES4; 321 | break; 322 | case psvs_check_box_impose_bus_lock: 323 | target = PSVS_LOCK_DEVICE_BUS; 324 | break; 325 | case psvs_check_box_impose_xbar_lock: 326 | target = PSVS_LOCK_DEVICE_GPU_XBAR; 327 | break; 328 | } 329 | 330 | if (wdg->IsChecked()) 331 | psvsClockFrequencyLockProc(pid, target); 332 | else 333 | psvsClockFrequencyUnlockProc(pid, target); 334 | } 335 | 336 | void Impose::Update(void *arg) 337 | { 338 | PSVSClockFrequency clock; 339 | wstring wtext; 340 | wchar_t wbuf[16]; 341 | uint32_t tickNow = sceKernelGetProcessTimeLow(); 342 | Impose *obj = (Impose *)arg; 343 | 344 | if (tickNow - obj->oldTick > PSVS_IMPOSE_UPDATE_WINDOW_USEC) { 345 | if (!g_imposeRoot->FindChild(0x0EE0C8AF)) { 346 | delete obj; 347 | return; 348 | } 349 | 350 | //Update clock 351 | psvsGetClockFrequency(&clock); 352 | 353 | if (obj->oldClock.cpu != clock.cpu) { 354 | sce_paf_swprintf(wbuf, 16, L"%d MHz", clock.cpu); 355 | wtext = wbuf; 356 | obj->cpu->SetString(wtext); 357 | } 358 | 359 | if (obj->oldClock.gpu != clock.gpu) { 360 | sce_paf_swprintf(wbuf, 16, L"%d MHz", clock.gpu); 361 | wtext = wbuf; 362 | obj->gpu->SetString(wtext); 363 | } 364 | 365 | /* 366 | if (obj->oldClock.bus != clock.bus) { 367 | sce_paf_swprintf(wbuf, sizeof(wbuf), L"%d MHz", clock.bus); 368 | wtext = wbuf; 369 | obj->bus->SetString(wtext); 370 | } 371 | */ 372 | 373 | if (obj->oldClock.xbar != clock.xbar) { 374 | sce_paf_swprintf(wbuf, 16, L"%d MHz", clock.xbar); 375 | wtext = wbuf; 376 | obj->xbar->SetString(wtext); 377 | } 378 | 379 | obj->oldTick = tickNow; 380 | obj->oldClock = clock; 381 | } 382 | } 383 | 384 | Hud::Position Impose::GetHudPosition() 385 | { 386 | return (Hud::Position)s_hudPos; 387 | } 388 | 389 | void Impose::SetHudPosition(Hud::Position pos) 390 | { 391 | s_hudPos = pos; 392 | Hud *currHud = Hud::GetCurrentHud(); 393 | if (currHud != NULL) { 394 | currHud->SetPosition(pos); 395 | } 396 | } 397 | 398 | Impose::Impose(Plugin *plugin, ui::Box *root) 399 | { 400 | wstring wstr; 401 | wchar_t casVal[2]; 402 | math::v4 sz; 403 | Plugin::TemplateOpenParam tmpParam; 404 | ScePID pid = psvs::tracker::GetCurrentPID(); 405 | 406 | this->oldTick = 0; 407 | this->plugin = plugin; 408 | this->root = root; 409 | this->imposePlugin = Plugin::Find("impose_plugin"); 410 | sce_paf_memset(&this->oldClock, 0, sizeof(PSVSClockFrequency)); 411 | 412 | ui::Widget *sep0 = this->imposePlugin->CreateWidget(this->root, "plane", 0x7ac075f7, 0x26c7781e); 413 | sz.set_x(835.0f); 414 | sz.set_y(20.0f); 415 | sep0->SetSize(sz); 416 | 417 | this->plugin->TemplateOpen(this->root, psvs_template_impose, tmpParam); 418 | 419 | ui::Widget *sep1 = this->imposePlugin->CreateWidget(this->root, "plane", 0x7ac075f7, 0x26c7781e); 420 | sz.set_x(835.0f); 421 | sz.set_y(20.0f); 422 | sep1->SetSize(sz); 423 | 424 | this->plugin->TemplateOpen(this->root, psvs_template_impose_2, tmpParam); 425 | this->cpu = (ui::Text *)this->root->FindChild(psvs_text_impose_cpu_value); 426 | this->gpu = (ui::Text *)this->root->FindChild(psvs_text_impose_gpu_value); 427 | /* 428 | this->bus = (ui::Text *)this->root->FindChild(psvs_text_impose_bus_value); 429 | */ 430 | this->xbar = (ui::Text *)this->root->FindChild(psvs_text_impose_xbar_value); 431 | this->hud = (ui::Text *)this->root->FindChild(psvs_text_impose_hud_value); 432 | 433 | switch (s_hudMode) { 434 | case HudMode_Off: 435 | wstr = g_corePlugin->GetString("psvs_msg_hud_off"); 436 | break; 437 | case HudMode_Micro: 438 | wstr = g_corePlugin->GetString("psvs_msg_hud_micro"); 439 | break; 440 | case HudMode_Mini: 441 | wstr = g_corePlugin->GetString("psvs_msg_hud_mini"); 442 | break; 443 | case HudMode_Full: 444 | wstr = g_corePlugin->GetString("psvs_msg_hud_full"); 445 | break; 446 | case HudMode_Dev: 447 | wstr = g_corePlugin->GetString("psvs_msg_hud_dev"); 448 | break; 449 | } 450 | this->hud->SetString(wstr); 451 | 452 | this->hudpos = (ui::Text *)this->root->FindChild(psvs_text_impose_hud_pos_value); 453 | 454 | switch (s_hudPos) { 455 | case Hud::Position_UpLeft: 456 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ul"); 457 | break; 458 | case Hud::Position_UpRight: 459 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_ur"); 460 | break; 461 | case Hud::Position_DownLeft: 462 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dl"); 463 | break; 464 | case Hud::Position_DownRight: 465 | wstr = g_corePlugin->GetString("psvs_msg_hud_pos_dr"); 466 | break; 467 | } 468 | this->hudpos->SetString(wstr); 469 | 470 | this->cas = (ui::Text *)this->root->FindChild(psvs_text_impose_cas_value); 471 | 472 | if (s_cas < 0) { 473 | wstr = g_corePlugin->GetString("psvs_msg_auto"); 474 | } 475 | else { 476 | sce_paf_swprintf(casVal, 2, L"%d", s_cas / 0x1000); 477 | wstr = casVal; 478 | } 479 | this->cas->SetString(wstr); 480 | 481 | ui::Widget *widget = NULL; 482 | ui::Button *bt = NULL; 483 | ui::CheckBox *box = NULL; 484 | 485 | widget = this->root->FindChild(psvs_button_impose_cpu_down); 486 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 487 | widget = this->root->FindChild(psvs_button_impose_cpu_up); 488 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 489 | widget = this->root->FindChild(psvs_button_impose_gpu_down); 490 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 491 | widget = this->root->FindChild(psvs_button_impose_gpu_up); 492 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 493 | /* 494 | widget = this->root->FindChild(psvs_button_impose_bus_down); 495 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 496 | widget = this->root->FindChild(psvs_button_impose_bus_up); 497 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 498 | */ 499 | widget = this->root->FindChild(psvs_button_impose_xbar_down); 500 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 501 | widget = this->root->FindChild(psvs_button_impose_xbar_up); 502 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 503 | widget = this->root->FindChild(psvs_button_impose_hud_up); 504 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 505 | widget = this->root->FindChild(psvs_button_impose_hud_down); 506 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 507 | widget = this->root->FindChild(psvs_button_impose_hud_pos_up); 508 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 509 | widget = this->root->FindChild(psvs_button_impose_hud_pos_down); 510 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 511 | widget = this->root->FindChild(psvs_button_impose_cas_up); 512 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 513 | widget = this->root->FindChild(psvs_button_impose_cas_down); 514 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ControlButtonCBFun, this); 515 | widget = this->root->FindChild(psvs_button_impose_delete); 516 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ProfileButtonCBFun, this); 517 | if (psvs::tracker::GetCurrentProfile()) { 518 | bt = (ui::Button *)widget; 519 | bt->Enable(true); 520 | } 521 | widget = this->root->FindChild(psvs_button_impose_save); 522 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, ProfileButtonCBFun, this); 523 | widget = this->root->FindChild(psvs_check_box_impose_cpu_lock); 524 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, LockCBFun, this); 525 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_CPU)) { 526 | box = (ui::CheckBox *)widget; 527 | box->SetCheck(true); 528 | } 529 | widget = this->root->FindChild(psvs_check_box_impose_gpu_lock); 530 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, LockCBFun, this); 531 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_GPU_ES4)) { 532 | box = (ui::CheckBox *)widget; 533 | box->SetCheck(true); 534 | } 535 | /* 536 | widget = this->root->FindChild(psvs_check_box_impose_bus_lock); 537 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, LockCBFun, this); 538 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_BUS)) { 539 | box = (ui::CheckBox *)widget; 540 | box->SetCheck(true); 541 | } 542 | */ 543 | widget = this->root->FindChild(psvs_check_box_impose_xbar_lock); 544 | widget->AddEventCallback(ui::Button::CB_BTN_DECIDE, LockCBFun, this); 545 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_GPU_XBAR)) { 546 | box = (ui::CheckBox *)widget; 547 | box->SetCheck(true); 548 | } 549 | 550 | common::MainThreadCallList::Register(Update, this); 551 | } 552 | 553 | Impose::~Impose() 554 | { 555 | common::MainThreadCallList::Unregister(Update, this); 556 | } 557 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/impose.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "psvs.h" 7 | #include "hud.h" 8 | 9 | namespace psvs 10 | { 11 | class Impose 12 | { 13 | public: 14 | 15 | #define PSVS_IMPOSE_UPDATE_WINDOW_USEC (100000) 16 | 17 | enum HudMode 18 | { 19 | HudMode_Off, 20 | HudMode_Micro, 21 | HudMode_Mini, 22 | HudMode_Full, 23 | HudMode_Dev 24 | }; 25 | 26 | enum Hash 27 | { 28 | psvs_template_impose = 0x1986fda5, 29 | psvs_template_impose_2 = 0x6825067c, 30 | psvs_text_impose_cpu_value = 0x480b4ef2, 31 | psvs_text_impose_gpu_value = 0x0b6cea96, 32 | psvs_text_impose_bus_value = 0xe0749e46, 33 | psvs_text_impose_xbar_value = 0xa3affcc2, 34 | psvs_button_impose_cpu_down = 0x6059f1bb, 35 | psvs_button_impose_cpu_up = 0x90fb2648, 36 | psvs_button_impose_gpu_down = 0xe503c992, 37 | psvs_button_impose_gpu_up = 0x81c4d74b, 38 | psvs_button_impose_bus_down = 0xa8d809ea, 39 | psvs_button_impose_bus_up = 0x402fe552, 40 | psvs_button_impose_xbar_down = 0xe1dcd852, 41 | psvs_button_impose_xbar_up = 0x63977f99, 42 | psvs_check_box_impose_cpu_lock = 0x44908086, 43 | psvs_check_box_impose_gpu_lock = 0xd39ce0ad, 44 | psvs_check_box_impose_bus_lock = 0xd522f917, 45 | psvs_check_box_impose_xbar_lock = 0xf5974793, 46 | psvs_button_impose_save = 0xf36ed842, 47 | psvs_button_impose_delete = 0x11f27c8a, 48 | psvs_button_impose_hud_down = 0x0071ecee, 49 | psvs_button_impose_hud_up = 0x88aa0668, 50 | psvs_button_impose_hud_pos_up = 0xe0d3e2ae, 51 | psvs_button_impose_hud_pos_down = 0xa5be81ad, 52 | psvs_text_impose_hud_pos_value = 0x3a6de20e, 53 | psvs_button_impose_cas_down = 0xed48e0d3, 54 | psvs_button_impose_cas_up = 0x0eea6bfa, 55 | psvs_text_impose_hud_value = 0xc7be30c1, 56 | psvs_text_impose_cas_value = 0xd0bd439b 57 | }; 58 | 59 | static void ControlButtonCBFun(int32_t type, paf::ui::Handler *self, paf::ui::Event *e, void *userdata); 60 | static void ProfileButtonCBFun(int32_t type, paf::ui::Handler *self, paf::ui::Event *e, void *userdata); 61 | static void LockCBFun(int32_t type, paf::ui::Handler *self, paf::ui::Event *e, void *userdata); 62 | 63 | static void Update(void *arg); 64 | static Hud::Position GetHudPosition(); 65 | static void SetHudPosition(Hud::Position pos); 66 | 67 | Impose(paf::Plugin *plugin, paf::ui::Box *root); 68 | 69 | ~Impose(); 70 | 71 | protected: 72 | 73 | paf::Plugin *plugin; 74 | paf::Plugin *imposePlugin; 75 | paf::ui::Box *root; 76 | 77 | paf::ui::Text *cpu; 78 | paf::ui::Text *gpu; 79 | paf::ui::Text *bus; 80 | paf::ui::Text *xbar; 81 | paf::ui::Text *hud; 82 | paf::ui::Text *hudpos; 83 | paf::ui::Text *cas; 84 | 85 | PSVSClockFrequency oldClock; 86 | uint32_t oldTick; 87 | }; 88 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "utils.h" 7 | #include "psvs.h" 8 | #include "hud.h" 9 | #include "tracker.h" 10 | #include "impose.h" 11 | #include "profile.h" 12 | 13 | using namespace paf; 14 | 15 | Plugin *g_corePlugin = NULL; 16 | ui::ScrollView *g_imposeRoot = NULL; 17 | 18 | static bool s_imposeOpened = false; 19 | 20 | extern "C" 21 | { 22 | SceUID _vshKernelSearchModuleByName(const char *, int *); 23 | } 24 | 25 | void corePluginStartCb(Plugin *plugin) 26 | { 27 | if (!plugin) { 28 | SCE_DBG_LOG_ERROR("g_corePlugin is NULL\n"); 29 | } 30 | 31 | g_corePlugin = plugin; 32 | } 33 | 34 | void coreSetImposeTask(void *arg) 35 | { 36 | ui::Box *box = (ui::Box *)g_imposeRoot->FindChild(0x0EE0C8AF, 0); 37 | if (!box) 38 | return; 39 | 40 | new psvs::Impose(g_corePlugin, box); 41 | 42 | s_imposeOpened = false; 43 | 44 | common::MainThreadCallList::Unregister(coreSetImposeTask, NULL); 45 | } 46 | 47 | void coreSetImpose(bool enable) 48 | { 49 | if (enable && !s_imposeOpened) { 50 | common::MainThreadCallList::Register(coreSetImposeTask, NULL); 51 | s_imposeOpened = true; 52 | } 53 | } 54 | 55 | void coreInitImpose() 56 | { 57 | SCE_DBG_LOG_INFO("coreInitImpose\n"); 58 | 59 | //Get power manage plugin object 60 | Plugin *powerManagePlugin = Plugin::Find("power_manage_plugin"); 61 | if (!powerManagePlugin) 62 | return; 63 | 64 | //Power manage plugin -> power manage interface 65 | void *powerIf = powerManagePlugin->GetInterface(1); 66 | if (!powerIf) 67 | return; 68 | 69 | //Power manage interface -> impose root 70 | ui::ScrollView *(*getImposeRoot)(); 71 | getImposeRoot = (ui::ScrollView *(*)()) *(int *)((int)powerIf + 0x54); 72 | if (!getImposeRoot) 73 | return; 74 | 75 | //Power manage root -> impose root (some virtual function) 76 | g_imposeRoot = getImposeRoot(); 77 | if (!g_imposeRoot) 78 | return; 79 | 80 | SCE_DBG_LOG_INFO("coreInitImpose OK\n"); 81 | } 82 | 83 | void coreInitPlugin() 84 | { 85 | SCE_DBG_LOG_INFO("coreInitPlugin\n"); 86 | 87 | Plugin::InitParam pluginParam; 88 | 89 | pluginParam.name = "psvshell_plugin"; 90 | pluginParam.resource_file = "ur0:data/PSVshell/psvshell_plugin.rco"; 91 | pluginParam.caller_name = "__main__"; 92 | pluginParam.start_func = corePluginStartCb; 93 | 94 | Plugin::LoadSync(pluginParam); 95 | 96 | psvs::Profile::Init(); 97 | 98 | //task::Register(leakTestTask, NULL); 99 | psvs::tracker::Init(); 100 | 101 | SCE_DBG_LOG_INFO("coreInitPlugin OK\n"); 102 | } 103 | 104 | extern "C" { 105 | 106 | static tai_hook_ref_t s_hookRef[2]; 107 | static SceUID s_hookId[2]; 108 | 109 | bool paf_system_SupportsWiredEthernet_patched() 110 | { 111 | coreSetImpose(true); 112 | return TAI_NEXT(paf_system_SupportsWiredEthernet_patched, s_hookRef[1]); 113 | } 114 | 115 | SceInt32 sceAVConfigRegisterCallback_patched(SceUID cbid, SceInt32 a2) 116 | { 117 | coreInitPlugin(); 118 | coreInitImpose(); 119 | 120 | s_hookId[1] = taiHookFunctionImport( 121 | &s_hookRef[1], 122 | "SceShell", 123 | 0x3D643CE8, 124 | 0xB7CFFF5C, 125 | paf_system_SupportsWiredEthernet_patched); 126 | 127 | taiHookRelease(s_hookId[0], s_hookRef[0]); 128 | 129 | return TAI_NEXT(sceAVConfigRegisterCallback_patched, s_hookRef[0], cbid, a2); 130 | } 131 | 132 | int __module_start(SceSize args, const void * argp) 133 | { 134 | SceInt32 opt[2]; 135 | 136 | SceUID fd = sceIoOpen("ur0:data/PSVshell/psvshell_plugin.rco", SCE_O_RDONLY, 0); 137 | if (fd <= 0) 138 | return SCE_KERNEL_START_NO_RESIDENT; 139 | 140 | sceIoClose(fd); 141 | 142 | if (_vshKernelSearchModuleByName("PSVshellPlus_Kernel", opt) <= 0) { 143 | return SCE_KERNEL_START_NO_RESIDENT; 144 | } 145 | 146 | s_hookId[0] = taiHookFunctionImport( 147 | &s_hookRef[0], 148 | "SceShell", 149 | 0x79E0F03F, 150 | 0xFB5E3E74, 151 | sceAVConfigRegisterCallback_patched); 152 | 153 | return SCE_KERNEL_START_SUCCESS; 154 | } 155 | 156 | int __module_stop(SceSize args, const void * argp) 157 | { 158 | return SCE_KERNEL_STOP_SUCCESS; 159 | } 160 | 161 | void __module_exit(void) 162 | { 163 | 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/profile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "global.h" 6 | #include "utils.h" 7 | #include "psvs.h" 8 | #include "tracker.h" 9 | #include "profile.h" 10 | 11 | using namespace paf; 12 | 13 | void psvs::Profile::Init() 14 | { 15 | Dir::Create(PSVS_PROFILES_DIR); 16 | } 17 | 18 | psvs::Profile::Profile() 19 | { 20 | PSVSClockFrequency clock; 21 | ScePID pid = psvs::tracker::GetCurrentPID(); 22 | 23 | psvsGetClockFrequency(&clock); 24 | 25 | sce_paf_memcpy(this->ver, PSVS_VERSION_VER, sizeof(this->ver)); 26 | 27 | this->clock[PSVS_OC_DEVICE_CPU] = clock.cpu; 28 | this->clock[PSVS_OC_DEVICE_GPU_ES4] = clock.gpu; 29 | this->clock[PSVS_OC_DEVICE_BUS] = clock.bus; 30 | this->clock[PSVS_OC_DEVICE_GPU_XBAR] = clock.xbar; 31 | this->lock = PSVS_LOCK_DEVICE_NONE; 32 | 33 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_CPU)) 34 | this->lock |= PSVS_LOCK_DEVICE_CPU; 35 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_GPU_ES4)) 36 | this->lock |= PSVS_LOCK_DEVICE_GPU_ES4; 37 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_BUS)) 38 | this->lock |= PSVS_LOCK_DEVICE_BUS; 39 | if (psvsClockFrequencyIsLockedProc(pid, PSVS_LOCK_DEVICE_GPU_XBAR)) 40 | this->lock |= PSVS_LOCK_DEVICE_GPU_XBAR; 41 | } 42 | 43 | psvs::Profile::Profile(const char *path) 44 | { 45 | LocalFile file; 46 | LocalFile::OpenArg oarg; 47 | 48 | oarg.filename = path; 49 | file.Open(&oarg); 50 | file.Read(this, sizeof(psvs::Profile)); 51 | file.Close(); 52 | } 53 | 54 | psvs::Profile::~Profile() 55 | { 56 | 57 | } 58 | 59 | psvs::Profile *psvs::Profile::Load() 60 | { 61 | string path = PSVS_PROFILES_DIR; 62 | string path2; 63 | Profile *prof = NULL; 64 | 65 | common::Utf16ToUtf8(*psvs::tracker::GetCurrentAppName(), &path2); 66 | 67 | path += path2; 68 | 69 | if (LocalFile::Exists(path.c_str()) && LocalFile::GetFileSize(path.c_str()) == sizeof(psvs::Profile)) { 70 | prof = new Profile(path.c_str()); 71 | if (!sce_paf_strncmp(prof->ver, PSVS_VERSION_VER, sizeof(prof->ver))) 72 | return prof; 73 | } 74 | 75 | if (prof) 76 | delete prof; 77 | 78 | return NULL; 79 | } 80 | 81 | void psvs::Profile::Delete() 82 | { 83 | string path = PSVS_PROFILES_DIR; 84 | string path2; 85 | 86 | common::Utf16ToUtf8(*psvs::tracker::GetCurrentAppName(), &path2); 87 | 88 | path += path2; 89 | 90 | LocalFile::RemoveFile(path.c_str()); 91 | } 92 | 93 | void psvs::Profile::Save() 94 | { 95 | LocalFile file; 96 | LocalFile::OpenArg oarg; 97 | string path = PSVS_PROFILES_DIR; 98 | string path2; 99 | 100 | common::Utf16ToUtf8(*psvs::tracker::GetCurrentAppName(), &path2); 101 | 102 | path += path2; 103 | 104 | oarg.flag = SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC; 105 | oarg.mode = 0666; 106 | oarg.filename = path.c_str(); 107 | file.Open(&oarg); 108 | file.Write(this, sizeof(psvs::Profile)); 109 | file.Close(); 110 | 111 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/profile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "psvs.h" 7 | 8 | #define PSVS_PROFILES_DIR "ur0:data/PSVshell/profiles/" 9 | #define PSVS_VERSION_VER "PSVS0300" 10 | 11 | namespace psvs 12 | { 13 | class Profile 14 | { 15 | public: 16 | 17 | static void Init(); 18 | 19 | static Profile *Load(); 20 | 21 | static void Delete(); 22 | 23 | Profile(); 24 | 25 | Profile(const char *path); 26 | 27 | ~Profile(); 28 | 29 | void Save(); 30 | 31 | char ver[8]; 32 | uint32_t lock; 33 | int32_t clock[PSVS_OC_DEVICE_MAX]; 34 | 35 | private: 36 | }; 37 | 38 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/psvs.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "psvs.h" 4 | 5 | #define PSVS_PERF_CPU_SAMPLERATE 500 * 1000 6 | #define PSVS_PERF_PEAK_SAMPLES 10 7 | 8 | static SceInt32 g_perfPeakUsageSamples[PSVS_PERF_PEAK_SAMPLES] = { 0 }; 9 | static SceInt32 g_perfPeakUsageRotation = 0; 10 | static SceInt32 g_perfUsage[4] = { 0, 0, 0, 0 }; 11 | 12 | static SceUInt32 g_perfTickLast = 0; // AVG CPU load 13 | static SceUInt32 g_perfTickQLast = 0; // Peak CPU load 14 | 15 | static SceUInt64 g_perfIdleClockLast[4] = { 0, 0, 0, 0 }; 16 | static SceUInt64 g_perfIdleClockQLast[4] = { 0, 0, 0, 0 }; 17 | 18 | SceVoid psvsCalcCpu() 19 | { 20 | SceUInt32 tickNow = sceKernelGetProcessTimeLow(); 21 | SceUInt32 tickDiff = tickNow - g_perfTickLast; 22 | SceUInt32 tickQDiff = tickNow - g_perfTickQLast; 23 | 24 | SceKernelSystemInfo info; 25 | info.size = sizeof(SceKernelSystemInfo); 26 | sceKernelGetSystemInfo(&info); 27 | 28 | // Calculate AVG CPU usage 29 | if (tickDiff >= PSVS_PERF_CPU_SAMPLERATE) { 30 | for (int i = 0; i < 4; i++) { 31 | g_perfUsage[i] = (int)(100.0f - ((info.cpuInfo[i].idleClock.quad - g_perfIdleClockLast[i]) / (float)tickDiff) * 100); 32 | if (g_perfUsage[i] < 0) 33 | g_perfUsage[i] = 0; 34 | if (g_perfUsage[i] > 100) 35 | g_perfUsage[i] = 100; 36 | g_perfIdleClockLast[i] = info.cpuInfo[i].idleClock.quad; 37 | } 38 | 39 | g_perfTickLast = tickNow; 40 | } 41 | 42 | // Calculate peak ST CPU usage 43 | SceInt32 maxUsage = 0; 44 | for (int i = 0; i < 4; i++) { 45 | int usage = (int)(100.0f - ((info.cpuInfo[i].idleClock.quad - g_perfIdleClockQLast[i]) / (float)tickQDiff) * 100); 46 | if (usage > maxUsage) 47 | maxUsage = usage; 48 | g_perfIdleClockQLast[i] = info.cpuInfo[i].idleClock.quad; 49 | } 50 | if (maxUsage < 0) 51 | maxUsage = 0; 52 | if (maxUsage > 100) 53 | maxUsage = 100; 54 | g_perfPeakUsageSamples[g_perfPeakUsageRotation] = maxUsage; 55 | g_perfPeakUsageRotation++; 56 | if (g_perfPeakUsageRotation >= PSVS_PERF_PEAK_SAMPLES) 57 | g_perfPeakUsageRotation = 0; // flip 58 | g_perfTickQLast = tickNow; 59 | } 60 | 61 | SceInt32 psvsGetCpu(PSVSCpu *cpu) 62 | { 63 | if (!cpu) 64 | return SCE_KERNEL_ERROR_INVALID_ARGUMENT; 65 | 66 | psvsCalcCpu(); 67 | 68 | SceInt32 peakTotal = 0; 69 | for (int i = 0; i < PSVS_PERF_PEAK_SAMPLES; i++) 70 | peakTotal += g_perfPeakUsageSamples[i]; 71 | cpu->peak = peakTotal / PSVS_PERF_PEAK_SAMPLES; 72 | 73 | for (int i = 0; i < SCE_KERNEL_MAX_CPU; i++) 74 | cpu->avg[i] = g_perfUsage[i]; 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/psvs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #define PSVS_FPS_COUNTER_TARGET_NONE -1 10 | #define PSVS_FPS_COUNTER_TARGET_GAME 0 11 | #define PSVS_FPS_COUNTER_TARGET_SHFB 1 12 | 13 | typedef enum { 14 | PSVS_OC_DEVICE_CPU, 15 | PSVS_OC_DEVICE_GPU_ES4, 16 | PSVS_OC_DEVICE_BUS, 17 | PSVS_OC_DEVICE_GPU_XBAR, 18 | /*PSVS_OC_DEVICE_VENEZIA, 19 | PSVS_OC_DEVICE_DMAC5, 20 | PSVS_OC_DEVICE_COMPAT, 21 | PSVS_OC_DEVICE_VIP, 22 | PSVS_OC_DEVICE_SYS,*/ 23 | PSVS_OC_DEVICE_MAX 24 | } PsvsOcDevice; 25 | 26 | typedef enum { 27 | PSVS_LOCK_DEVICE_NONE = 0, 28 | PSVS_LOCK_DEVICE_CPU = 1, 29 | PSVS_LOCK_DEVICE_GPU_ES4 = 2, 30 | PSVS_LOCK_DEVICE_BUS = 4, 31 | PSVS_LOCK_DEVICE_GPU_XBAR = 8, 32 | /*PSVS_LOCK_DEVICE_VENEZIA = 16, 33 | PSVS_LOCK_DEVICE_DMAC5 = 32, 34 | PSVS_LOCK_DEVICE_COMPAT = 64, 35 | PSVS_LOCK_DEVICE_VIP = 128, 36 | PSVS_LOCK_DEVICE_SYS = 256,*/ 37 | PSVS_LOCK_DEVICE_ALL = PSVS_LOCK_DEVICE_CPU | PSVS_LOCK_DEVICE_GPU_ES4 | PSVS_LOCK_DEVICE_BUS | PSVS_LOCK_DEVICE_GPU_XBAR 38 | } PsvsLockDevice; 39 | 40 | typedef struct PSVSClockFrequency { 41 | SceInt32 cpu; 42 | SceInt32 gpu; 43 | SceInt32 xbar; 44 | SceInt32 bus; 45 | } PSVSClockFrequency; 46 | 47 | typedef struct PSVSMem { 48 | SceUInt32 mainFree; 49 | SceUInt32 mainTotal; 50 | SceUInt32 cdramFree; 51 | SceUInt32 cdramTotal; 52 | SceUInt32 phycontFree; 53 | SceUInt32 phycontTotal; 54 | SceUInt32 cdialogFree; 55 | SceUInt32 cdialogTotal; 56 | } PSVSMem; 57 | 58 | typedef struct PSVSVenezia { 59 | SceInt32 core0; 60 | SceInt32 core1; 61 | SceInt32 core2; 62 | SceInt32 core3; 63 | SceInt32 core4; 64 | SceInt32 core5; 65 | SceInt32 core6; 66 | SceInt32 core7; 67 | SceInt32 average; 68 | SceInt32 peak; 69 | } PSVSVenezia; 70 | 71 | typedef struct PSVSBattery { 72 | SceInt32 current; 73 | } PSVSBattery; 74 | 75 | typedef struct PSVSCpu { 76 | SceInt32 avg[SCE_KERNEL_MAX_CPU]; 77 | SceInt32 peak; 78 | } PSVSCpu; 79 | 80 | SceInt32 psvsSetArmClockFrequency(SceInt32 clock); 81 | SceInt32 psvsSetGpuClockFrequency(SceInt32 clock); 82 | SceInt32 psvsSetGpuXbarClockFrequency(SceInt32 clock); 83 | SceInt32 psvsSetBusClockFrequency(SceInt32 clock); 84 | SceInt32 psvsGetClockFrequency(PSVSClockFrequency *clocks); 85 | SceInt32 psvsGetFps(); 86 | SceInt32 psvsGetMem(SceUInt32 casShift, PSVSMem *mem); 87 | SceVoid psvsSetFpsCounterTarget(SceInt32 target); 88 | SceInt32 psvsClockFrequencyLockProc(ScePID pid, PsvsLockDevice type); 89 | SceInt32 psvsClockFrequencyUnlockProc(ScePID pid, PsvsLockDevice type); 90 | SceBool psvsClockFrequencyIsLockedProc(ScePID pid, PsvsLockDevice type); 91 | SceInt32 psvsSetRecommendedCasShift(char *name, SceInt32 namelen); 92 | SceVoid psvsSetClockingPid(SceUID pid); 93 | SceInt32 psvsGetVeneziaInfo(PSVSVenezia *data); 94 | SceInt32 psvsGetBatteryInfo(PSVSBattery *data); 95 | 96 | SceVoid psvsCalcCpu(); 97 | SceInt32 psvsGetCpu(PSVSCpu *cpu); 98 | 99 | int _sceCodecEnginePmonStop(); 100 | int _sceCodecEnginePmonReset(); 101 | int _sceCodecEnginePmonStart(); 102 | #define sceCodecEnginePmonStop _sceCodecEnginePmonStop 103 | #define sceCodecEnginePmonReset _sceCodecEnginePmonReset 104 | #define sceCodecEnginePmonStart _sceCodecEnginePmonStart 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/psvshell_plugin.rco: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrapheneCt/PSVshellPlus/b70f1c7fe78882ff1327d50ccd703b0ea429076e/PSVshellPlus_Shell/psvshell_plugin.rco -------------------------------------------------------------------------------- /PSVshellPlus_Shell/tracker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "global.h" 8 | #include "utils.h" 9 | #include "impose.h" 10 | #include "hud.h" 11 | #include "psvs.h" 12 | #include "tracker.h" 13 | #include "profile.h" 14 | 15 | using namespace paf; 16 | 17 | namespace psvs 18 | { 19 | namespace tracker 20 | { 21 | static int32_t s_currAppId = -1; 22 | static ScePID s_currPid = -1; 23 | static wstring *s_currAppName = NULL; 24 | static uint32_t s_tickOld = 0; 25 | static int32_t s_fpsTarget = PSVS_FPS_COUNTER_TARGET_SHFB; 26 | static psvs::Profile *s_currProfile = NULL; 27 | 28 | void Update(void *arg) 29 | { 30 | char name[32]; 31 | int32_t appId = -1; 32 | uint32_t tickNow = sceKernelGetProcessTimeLow(); 33 | bool appChanged = false; 34 | 35 | if (tickNow - s_tickOld > PSVS_APP_UPDATE_WINDOW_USEC) { 36 | appId = sceAppMgrGetAppIdByAppId(SCE_APPMGR_APP_ID_ACTIVE); 37 | if (appId > 0) { 38 | if (s_currAppId != appId) { 39 | s_currPid = sceAppMgrGetProcessIdByAppIdForShell(appId); 40 | sceAppMgrGetNameById(sceAppMgrGetProcessIdByAppIdForShell(appId), name); 41 | common::Utf8ToUtf16(name, s_currAppName); 42 | if (sceAppMgrGetAppIdByAppId(SCE_APPMGR_APP_ID_GAME) != appId) { 43 | s_fpsTarget = PSVS_FPS_COUNTER_TARGET_SHFB; 44 | psvsSetRecommendedCasShift(name, sce_paf_strlen(name) + 1); 45 | } 46 | else { 47 | s_fpsTarget = PSVS_FPS_COUNTER_TARGET_GAME; 48 | psvsSetRecommendedCasShift("game", sizeof("game")); 49 | } 50 | s_currAppId = appId; 51 | appChanged = true; 52 | } 53 | } 54 | else { 55 | if (s_currAppId != -1) { 56 | s_currPid = sceKernelGetProcessId(); 57 | *s_currAppName = L"main"; 58 | psvsSetRecommendedCasShift("main", sizeof("main")); 59 | s_fpsTarget = PSVS_FPS_COUNTER_TARGET_SHFB; 60 | s_currAppId = -1; 61 | appChanged = true; 62 | } 63 | } 64 | 65 | if (appChanged) { 66 | psvsSetClockingPid(s_currPid); 67 | if (s_currProfile) 68 | delete s_currProfile; 69 | s_currProfile = psvs::Profile::Load(); 70 | if (s_currProfile) { 71 | psvsSetArmClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_CPU]); 72 | psvsSetGpuClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_GPU_ES4]); 73 | //psvsSetBusClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_BUS]); 74 | psvsSetGpuXbarClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_GPU_XBAR]); 75 | psvsClockFrequencyLockProc(s_currPid, (PsvsLockDevice)s_currProfile->lock); 76 | } 77 | else { 78 | psvsClockFrequencyUnlockProc(s_currPid, PSVS_LOCK_DEVICE_ALL); 79 | } 80 | } 81 | 82 | s_tickOld = tickNow; 83 | } 84 | } 85 | 86 | wstring *GetCurrentAppName() 87 | { 88 | return s_currAppName; 89 | } 90 | 91 | ScePID GetCurrentPID() 92 | { 93 | return s_currPid; 94 | } 95 | 96 | void ReloadCurrentProfile() 97 | { 98 | s_currProfile = psvs::Profile::Load(); 99 | } 100 | 101 | psvs::Profile *GetCurrentProfile() 102 | { 103 | return s_currProfile; 104 | } 105 | 106 | int32_t GetFpsCounterTarget() 107 | { 108 | return s_fpsTarget; 109 | } 110 | 111 | SceInt32 PowerCallback(SceUID notifyId, SceInt32 notifyCount, SceInt32 notifyArg, void *pCommon) 112 | { 113 | if ((notifyArg & SCE_POWER_CALLBACKARG_RESERVED_23) == SCE_POWER_CALLBACKARG_RESERVED_23) { 114 | // Set clocks after resume reset 115 | PSVSClockFrequency clocks; 116 | psvsGetClockFrequency(&clocks); 117 | psvsSetArmClockFrequency(clocks.cpu); 118 | psvsSetGpuClockFrequency(clocks.gpu); 119 | //psvsSetBusClockFrequency(clocks.bus); 120 | psvsSetGpuXbarClockFrequency(clocks.xbar); 121 | 122 | // Prevent HUD from blocking peel screen 123 | if (!SCE_PAF_IS_DOLCE && Impose::GetHudPosition() == Hud::Position_UpRight && Hud::GetCurrentHud() != SCE_NULL) { 124 | Impose::SetHudPosition(Hud::Position_UpLeft); 125 | } 126 | } 127 | 128 | return SCE_OK; 129 | } 130 | 131 | void Init() 132 | { 133 | s_currPid = sceKernelGetProcessId(); 134 | s_currAppName = new wstring(L"main"); 135 | psvsSetClockingPid(s_currPid); 136 | s_currProfile = psvs::Profile::Load(); 137 | if (s_currProfile) { 138 | psvsSetArmClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_CPU]); 139 | psvsSetGpuClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_GPU_ES4]); 140 | //psvsSetBusClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_BUS]); 141 | psvsSetGpuXbarClockFrequency(s_currProfile->clock[PSVS_OC_DEVICE_GPU_XBAR]); 142 | psvsClockFrequencyLockProc(s_currPid, (PsvsLockDevice)s_currProfile->lock); 143 | } 144 | else { 145 | psvsClockFrequencyUnlockProc(s_currPid, PSVS_LOCK_DEVICE_ALL); 146 | } 147 | 148 | SceUID cbid = sceKernelCreateCallback("PSVshellPlus_PCB", 0, PowerCallback, NULL); 149 | scePowerRegisterCallback(cbid); 150 | 151 | common::MainThreadCallList::Register(Update, NULL); 152 | } 153 | 154 | void Term() 155 | { 156 | common::MainThreadCallList::Unregister(Update, NULL); 157 | delete s_currAppName; 158 | } 159 | } 160 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/tracker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "profile.h" 7 | 8 | namespace psvs 9 | { 10 | namespace tracker 11 | { 12 | #define PSVS_APP_UPDATE_WINDOW_USEC (100000) 13 | 14 | void Init(); 15 | void Term(); 16 | void Update(void *arg); 17 | paf::wstring *GetCurrentAppName(); 18 | ScePID GetCurrentPID(); 19 | void ReloadCurrentProfile(); 20 | psvs::Profile *GetCurrentProfile(); 21 | int32_t GetFpsCounterTarget(); 22 | SceInt32 PowerCallback(SceUID notifyId, SceInt32 notifyCount, SceInt32 notifyArg, void *pCommon); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /PSVshellPlus_Shell/utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "global.h" 5 | #include "utils.h" 6 | 7 | using namespace paf; 8 | 9 | namespace psvs 10 | { 11 | math::v4 ScaleColor(int32_t value, int32_t min, int32_t max) 12 | { 13 | if (value < min) 14 | value = min; 15 | if (value > max) 16 | value = max; 17 | 18 | int32_t v = ((float)(value - min) / (max - min)) * 255; // 0-255 19 | 20 | int32_t r = (v <= 127) ? v * 2 : 255; 21 | int32_t g = (v > 127) ? 255 - ((v - 128) * 2) : 255; 22 | 23 | return math::v4((float)r / 255.0f, (float)g / 255.0f, 0.0f, 1.0f); 24 | } 25 | 26 | const wchar_t *UnitsFromSize(int32_t bytes) 27 | { 28 | if (bytes >= 1024 * 1024) 29 | return L"MB"; 30 | else if (bytes >= 1024) 31 | return L"kB"; 32 | else 33 | return L" B"; 34 | } 35 | 36 | int32_t ValueFromSize(int32_t bytes) 37 | { 38 | if (bytes >= 1024 * 1024) 39 | return bytes / 1024 / 1024; 40 | else if (bytes >= 1024) 41 | return bytes / 1024; 42 | else 43 | return bytes; 44 | } 45 | 46 | int32_t LengthOfValue(int32_t num) 47 | { 48 | int32_t len = 3; 49 | 50 | if (num < 10) 51 | len = 1; 52 | else if (num < 100) 53 | len = 2; 54 | 55 | return len; 56 | } 57 | } -------------------------------------------------------------------------------- /PSVshellPlus_Shell/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace psvs 7 | { 8 | paf::math::v4 ScaleColor(int32_t value, int32_t min, int32_t max); 9 | const wchar_t *UnitsFromSize(int32_t bytes); 10 | int32_t ValueFromSize(int32_t bytes); 11 | int32_t LengthOfValue(int32_t num); 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PSVshellPlus 2 | Advanced OC&Info plugin for PS Vita 3 | 4 | Provides fully GPU accelerated HUD, accurate memory and FPS tracking with full Quick Menu integration. 5 | 6 | ![alt text](https://github.com/GrapheneCt/PSVshellPlus/raw/main/guide.jpg) 7 | 8 | ## Installation 9 | 0. PSVshellPlus is not compatible with original PSVshell profiles. If you used PSVshell before, please manually clean ```ur0:data/PSVshell/profiles/``` before using PSVshellPlus 10 | 1. Download latest release 11 | 2. Install plugins: 12 | ``` 13 | *KERNEL 14 | ur0:tai/PSVshellPlus_Kernel.skprx 15 | *main 16 | ur0:tai/PSVshellPlus_Shell.suprx 17 | ``` 18 | 3. Copy ```psvshell_plugin.rco``` to ```ur0:data/PSVshell/psvshell_plugin.rco``` 19 | 4. Reboot system 20 | 21 | ## Credits 22 | Original [PSVshell](https://github.com/Electry/PSVshell) plugin by Electry - HUD layout 23 | -------------------------------------------------------------------------------- /guide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrapheneCt/PSVshellPlus/b70f1c7fe78882ff1327d50ccd703b0ea429076e/guide.jpg --------------------------------------------------------------------------------