mirror of
https://github.com/ApfelTeeSaft/Itemzflow.git
synced 2026-08-26 19:23:39 +00:00
- Fixed dumping DLCs and AC w/p data - Added an Install all PKGs option for folders with more than 1 PKG - Installing a PKG will no longer boot you back to settings - Carried over some improvements from the PS5 version of IF - Replaced reg. vectors for ThreadSafeVectors - Added the Chinese lang files - Fixed a bug that would cause the Utility thread to deadlock - Fixed a Bug that caused the daemon not to give a backtrace on 9.00
563 lines
16 KiB
C++
563 lines
16 KiB
C++
#include "defines.h"
|
|
#include <utils.h>
|
|
#include <sys/signal.h>
|
|
#include <orbisGl.h>
|
|
#include <orbisPad.h>
|
|
#include <pthread.h>
|
|
#include <signal.h>
|
|
#include "net.h"
|
|
#include <atomic>
|
|
#include <thread>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <patcher.h>
|
|
#include <sys/mount.h>
|
|
#include "feature_classes.hpp"
|
|
#include "log.h"
|
|
|
|
double dt, u_t = 0;
|
|
|
|
int libcmi = -1;
|
|
OrbisGlConfig* GlConf;
|
|
OrbisPadConfig *confPad;
|
|
bool flag=true;
|
|
extern ThreadSafeVector<item_t> all_apps;
|
|
std::atomic_bool is_idle = false;
|
|
|
|
|
|
|
|
int selected_icon;
|
|
struct timeval t1, t2;
|
|
|
|
#define DELTA (123) // dpad delta movement
|
|
|
|
static int (*jailbreak_me)(void) = NULL;
|
|
|
|
extern std::atomic_bool found_usb;
|
|
extern std::atomic_int inserted_disc;
|
|
std::atomic_bool reset_idle_timer = false;
|
|
extern bool is_connected_app;
|
|
|
|
extern "C" void standalone_main(void);
|
|
|
|
extern void* __stack_chk_guard;
|
|
std::atomic_bool is_disc_inserted = false;
|
|
std::atomic_int mins_played = MIN_STATUS_RESET;
|
|
std::atomic_long started_epoch = MIN_STATUS_RESET;
|
|
std::atomic_int AppVis = -1;
|
|
|
|
typedef struct UtiltiyPadConfig
|
|
{
|
|
ScePadData padDataCurrent;
|
|
ScePadData padDataLast;
|
|
|
|
}UtiltiyPadConfig;
|
|
|
|
|
|
void* ItemzCore_Util_thread(void* args) {
|
|
int ret = -1;
|
|
u32 userId = -1;
|
|
bool usb_found = false;
|
|
char name[100];
|
|
|
|
UtiltiyPadConfig pad;
|
|
|
|
log_info("Starting thread main loop");
|
|
if(sceUserServiceGetForegroundUser(&userId) == ITEMZCORE_SUCCESS){
|
|
memset(name, 0, sizeof(name));
|
|
sceUserServiceGetUserName(userId, name, sizeof(name));
|
|
ani_notify(NOTIFI::PROFILE, fmt::format("{0:}: {1:}", getLangSTR(LANG_STR::SIGN_IN_USER_NOTIF), name), "");
|
|
}
|
|
|
|
time_t idle_clock = time(NULL);
|
|
|
|
while (true)
|
|
{
|
|
IPC_Client& ipc = IPC_Client::getInstance();
|
|
std::string ipc_msg;
|
|
if(reset_idle_timer.load()) {
|
|
idle_clock = time(NULL);
|
|
reset_idle_timer = false;
|
|
is_idle = false;
|
|
GLES2_refresh_sysinfo();
|
|
}
|
|
|
|
time_t fifteenMinutesAgo = idle_clock + 15 * 60;
|
|
if (!is_idle.load() && time(NULL) > fifteenMinutesAgo) {
|
|
log_info("15 mins have passed and its now idling %llx %llx",idle_clock, fifteenMinutesAgo);
|
|
is_idle = true;
|
|
GLES2_refresh_sysinfo();
|
|
}
|
|
|
|
if(is_idle.load()) {
|
|
continue;
|
|
}
|
|
// re-get the userid incase it changed
|
|
sceUserServiceGetForegroundUser(&userId);
|
|
|
|
ret = scePadReadState(scePadGetHandle(userId,0,0), &pad.padDataCurrent);
|
|
if (ret < 0 || !pad.padDataCurrent.connected) {
|
|
// Function is thread-safe
|
|
// Notfiy func has mutexs in place for threads
|
|
ani_notify(NOTIFI::GAME, getLangSTR(LANG_STR::CON_DIS), getLangSTR(LANG_STR::CON_DIS_2));
|
|
is_idle = true;
|
|
GLES2_refresh_sysinfo();
|
|
log_error("scePadReadState: %x, userid: %x, handle: %x", ret, userId, scePadGetHandle(userId,0,0));
|
|
}
|
|
|
|
scan_for_disc();
|
|
|
|
//check if theres a usb
|
|
if(!usb_found && usbpath() != -1){
|
|
usb_found = true;
|
|
//USB Notify
|
|
ani_notify(NOTIFI::INFO, getLangSTR(LANG_STR::USB_NOTIFY), getLangSTR(LANG_STR::USB_NOTIFY1));
|
|
log_info("[UTIL] USB Inserted");
|
|
}
|
|
else if (usb_found && usbpath() == -1){
|
|
usb_found = false;
|
|
ani_notify(NOTIFI::INFO, getLangSTR(LANG_STR::USB_DISCONNECTED), getLangSTR(LANG_STR::USB_DISCONNECTED1));
|
|
log_info("[UTIL] USB removed");
|
|
}
|
|
|
|
// Replace the use of ipc_msg with vecto
|
|
if(title_id.get().empty() || app_status.load() == NO_APP_OPENED)
|
|
continue;
|
|
|
|
int BigAppid = sceSystemServiceGetAppIdOfBigApp();
|
|
// IS Big App Running?
|
|
if ((BigAppid & ~0xFFFFFF) == 0x60000000){
|
|
memset(name, 0, 100);
|
|
// Get TID of Big App
|
|
if(sceLncUtilGetAppTitleId(BigAppid, &name[0]) == 0){
|
|
// Check if its the same as the current app
|
|
if(title_id.get().compare(name) == 0){
|
|
// log_info("[TEST] Big App is running");
|
|
}
|
|
else{
|
|
// log_info("[TEST] Big App is not running");
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
ipc_msg = title_id.get();
|
|
|
|
if (is_connected_app && ipc.IPCSendCommand(IPC_Commands::GAME_GET_MINS, ipc_msg, true) == IPC_Ret::NO_ERROR) {
|
|
int result;
|
|
sscanf(ipc_msg.c_str(), "%d", &result);
|
|
mins_played = result;
|
|
} else {
|
|
mins_played = MIN_STATUS_NA;
|
|
}
|
|
|
|
sleep(1);
|
|
}
|
|
|
|
log_error("Utility Thread failed to start");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct timeval last_tv;
|
|
int button_numb = -1;
|
|
int if_numb = -1;
|
|
bool check_if_held = false;
|
|
|
|
|
|
void updateController()
|
|
{
|
|
unsigned int buttons=0;
|
|
int ret = orbisPadUpdate();
|
|
if(ret==0)
|
|
{
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L2|ORBISPAD_R2) || orbisPadGetButtonHold(ORBISPAD_L2|ORBISPAD_R2))
|
|
{
|
|
log_info("Combo L2R2 pressed");
|
|
buttons=orbisPadGetCurrentButtonsPressed();
|
|
buttons&= ~(ORBISPAD_L2|ORBISPAD_R2);
|
|
orbisPadSetCurrentButtonsPressed(buttons);
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_TOUCH_PAD))
|
|
{
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L1|ORBISPAD_R1) )
|
|
{
|
|
log_info("Combo L1R1 pressed");
|
|
buttons=orbisPadGetCurrentButtonsPressed();
|
|
buttons&= ~(ORBISPAD_L1|ORBISPAD_R1);
|
|
orbisPadSetCurrentButtonsPressed(buttons);
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L1|ORBISPAD_R2) || orbisPadGetButtonHold(ORBISPAD_L1|ORBISPAD_R2))
|
|
{
|
|
log_info("Combo L1R2 pressed");
|
|
buttons=orbisPadGetCurrentButtonsPressed();
|
|
buttons&= ~(ORBISPAD_L1|ORBISPAD_R2);
|
|
orbisPadSetCurrentButtonsPressed(buttons);
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L2|ORBISPAD_R1) || orbisPadGetButtonHold(ORBISPAD_L2|ORBISPAD_R1) )
|
|
{
|
|
log_info("Combo L2R1 pressed");
|
|
buttons=orbisPadGetCurrentButtonsPressed();
|
|
buttons&= ~(ORBISPAD_L2|ORBISPAD_R1);
|
|
orbisPadSetCurrentButtonsPressed(buttons);
|
|
}
|
|
|
|
if(orbisPadGetButtonPressed(ORBISPAD_UP) || confPad->padDataCurrent->ly < (127 - DELTA)){
|
|
fw_action_to_cf(UP);
|
|
if(!(confPad->padDataCurrent->ly < (127 - DELTA))){
|
|
check_if_held = true;
|
|
button_numb = ORBISPAD_UP;
|
|
if_numb = UP;
|
|
}
|
|
reset_idle_timer = true;
|
|
gettimeofday(&last_tv, NULL);
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_DOWN)
|
|
|| confPad->padDataCurrent->ly > (127 + DELTA))
|
|
{
|
|
fw_action_to_cf(DOW);
|
|
if(!(confPad->padDataCurrent->ly > (127 + DELTA))){
|
|
check_if_held = true;
|
|
button_numb = ORBISPAD_DOWN;
|
|
if_numb = DOW;
|
|
}
|
|
reset_idle_timer = true;
|
|
gettimeofday(&last_tv, NULL);
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_RIGHT)
|
|
|| confPad->padDataCurrent->lx > (127 + DELTA))
|
|
{
|
|
fw_action_to_cf(RIG);
|
|
if(!(confPad->padDataCurrent->lx > (127 + DELTA))){
|
|
check_if_held = true;
|
|
button_numb = ORBISPAD_RIGHT;
|
|
if_numb = RIG;
|
|
}
|
|
reset_idle_timer = true;
|
|
gettimeofday(&last_tv, NULL);
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_LEFT)
|
|
|| confPad->padDataCurrent->lx < (127 - DELTA))
|
|
{
|
|
fw_action_to_cf(LEF);
|
|
if(!(confPad->padDataCurrent->lx < (127 - DELTA))){
|
|
check_if_held = true;
|
|
button_numb = ORBISPAD_LEFT;
|
|
if_numb = LEF;
|
|
}
|
|
reset_idle_timer = true;
|
|
gettimeofday(&last_tv, NULL);
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_TRIANGLE))
|
|
{
|
|
log_info( "Triangle pressed exit");
|
|
fw_action_to_cf(TRI);
|
|
reset_idle_timer = true;
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_CIRCLE))
|
|
{
|
|
log_info( "Circle pressed");
|
|
fw_action_to_cf(CIR);
|
|
reset_idle_timer = true;
|
|
|
|
}
|
|
else
|
|
if(orbisPadGetButtonPressed(ORBISPAD_CROSS))
|
|
{
|
|
log_info( "Cross pressed");
|
|
fw_action_to_cf(CRO);
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_SQUARE))
|
|
{
|
|
log_info( "Square pressed");
|
|
fw_action_to_cf(SQU);
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L1))
|
|
{
|
|
log_info( "L1 pressed");
|
|
if(v_curr != FILE_BROWSER_LEFT && v_curr != FILE_BROWSER_RIGHT)
|
|
trigger_dump_frame();
|
|
|
|
fw_action_to_cf(L1);
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_L2))
|
|
{
|
|
log_info( "L2 pressed");
|
|
fw_action_to_cf(L2);
|
|
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_R1))
|
|
{
|
|
fw_action_to_cf(R1);
|
|
reset_idle_timer = true;
|
|
}
|
|
if(orbisPadGetButtonPressed(ORBISPAD_R2))
|
|
{
|
|
reset_idle_timer = true;
|
|
}
|
|
if (orbisPadGetButtonPressed(ORBISPAD_OPTIONS))
|
|
{
|
|
fw_action_to_cf(OPT);
|
|
reset_idle_timer = true;
|
|
//patch_lnc_debug();
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void finishApp()
|
|
{
|
|
orbisPadFinish();
|
|
orbisNfsFinish();
|
|
}
|
|
|
|
static bool initAppGl()
|
|
{
|
|
int ret = orbisGlInit(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT);
|
|
if (ret > 0)
|
|
{
|
|
glViewport(0, 0, ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT);
|
|
ret = glGetError();
|
|
if (ret)
|
|
{
|
|
log_info("[%s] glViewport failed: 0x%08X", __FUNCTION__, ret);
|
|
return false;
|
|
}
|
|
|
|
// glClearColor(0.f, 0.f, 1.f, 1.f); // blue RGBA
|
|
glClearColor(0.1211, 0.1211, 0.1211, 1.); // background color
|
|
|
|
ret = glGetError();
|
|
if (ret)
|
|
{
|
|
log_info("[%s] glClearColor failed: 0x%08X", __FUNCTION__, ret);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool initApp()
|
|
{
|
|
#if defined (USE_NFS)
|
|
orbisNfsInit(NFSEXPORT);
|
|
orbisFileInit();
|
|
int ret = initOrbisLinkApp();
|
|
#endif
|
|
|
|
sceSystemServiceHideSplashScreen();
|
|
|
|
confPad = orbisPadGetConf();
|
|
|
|
if (!initAppGl()) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
float toMilliSeconds(uint64_t t)
|
|
{
|
|
return (float)t / 1000.0f ;
|
|
}
|
|
|
|
/// for timing, fps
|
|
#define WEN (2048)
|
|
unsigned int frame = 1;
|
|
float time_ms = 0.f;
|
|
int main(int argc, char* argv[])
|
|
{
|
|
|
|
int ret = -1;
|
|
bool speed1 = true,speed2 = false,speed3 = false;
|
|
vec2 pen = (vec2){ 26, 990 };
|
|
vec4 col = (vec4){ .8164, .8164, .8125, 1. };
|
|
int fpsCount = 0;
|
|
uint64_t fpsTime1 = 0;
|
|
uint64_t fpsTime2 = 0;
|
|
VertexBuffer fps_vbo;
|
|
std::chrono::time_point<std::chrono::system_clock> now, prev;
|
|
std::chrono::steady_clock::time_point lastUpdate;
|
|
// vec4 c = col * .75f;
|
|
|
|
pthread_t utility_thread = NULL;
|
|
/* load custom .prx, resolve and call a function */
|
|
rejail_multi = (int (*)(void))prx_func_loader("/app0/Media/jb.prx", "rejail_multi");
|
|
jailbreak_me = (int (*)(void))prx_func_loader("/app0/Media/jb.prx", "jailbreak_me");
|
|
if (jailbreak_me)
|
|
{
|
|
log_info("jailbreak_me resolved from PRX");
|
|
if ((ret = jailbreak_me() != 0)) goto error;
|
|
}
|
|
else
|
|
goto error;
|
|
|
|
if (Start_IF_internal_Services(argv[0]) == INIT_FAILED) goto error;
|
|
|
|
// init some libraries
|
|
flag = initApp();
|
|
|
|
// feedback
|
|
log_info("Here we are!");
|
|
|
|
/* init GLES2 stuff */
|
|
// demo-font.c init
|
|
es2init_text(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT);
|
|
// ES_UI
|
|
log_info("Starting ItemzCore ....");
|
|
init_ItemzCore(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT);
|
|
log_info("ItemzCore started.");
|
|
|
|
log_info("Starting the ItemzCore Utility Thread ...");
|
|
pthread_create(&utility_thread, NULL, ItemzCore_Util_thread, NULL);
|
|
log_info("ItemzCore Utility Thread Started");
|
|
|
|
|
|
/// reset timers
|
|
now = std::chrono::system_clock::now();
|
|
time_ms = get_time_ms(now);
|
|
|
|
lastUpdate = std::chrono::steady_clock::now();
|
|
|
|
//close any still running dialogs
|
|
sceMsgDialogTerminate();
|
|
|
|
// Initialize FPS counter
|
|
fpsTime1 = sceKernelGetProcessTime();
|
|
prev = std::chrono::system_clock::now();
|
|
|
|
/// enter main render loop
|
|
while (flag)
|
|
{
|
|
//skip the first frame
|
|
//so theres no race between
|
|
//the countroller update and the GLES UI
|
|
|
|
if (frame != 1)
|
|
updateController();
|
|
|
|
if(check_if_held && !orbisPadGetButtonReleased(button_numb)) {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
//log_info("Holding UP %i %i", tv.tv_usec, last_tv.tv_usec);
|
|
int elapsed_time = (tv.tv_sec - last_tv.tv_sec) * 1000000 + (tv.tv_usec - last_tv.tv_usec);
|
|
if(speed1 && elapsed_time > 500000) {
|
|
fw_action_to_cf(if_numb);
|
|
gettimeofday(&last_tv, NULL);
|
|
speed1 = false;
|
|
speed2 = true;
|
|
}
|
|
else if(speed2 && elapsed_time > 300000) {
|
|
fw_action_to_cf(if_numb);
|
|
gettimeofday(&last_tv, NULL);
|
|
speed2 = false;
|
|
speed3 = true;
|
|
}
|
|
else if(speed3 && elapsed_time > 50000) {
|
|
fw_action_to_cf(if_numb);
|
|
gettimeofday(&last_tv, NULL);
|
|
}
|
|
}
|
|
else {
|
|
check_if_held = false;
|
|
speed1 = true;
|
|
speed2 = false;
|
|
speed3 = false;
|
|
}
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
ret = glGetError();
|
|
if (ret) {
|
|
log_info("[ORBIS_GL] glClear failed: 0x%08X", ret);
|
|
//goto err;
|
|
}
|
|
|
|
// Render ItemzCore
|
|
Render_ItemzCore();
|
|
|
|
fpsCount++;
|
|
|
|
if (fpsCount == 120 ) {
|
|
fpsTime2 = sceKernelGetProcessTime();
|
|
float time = get_time_ms(prev) * 1000.0f;
|
|
float avgFrameTime = time / 60.0f;
|
|
fps_vbo = VertexBuffer( "vertex:3f,tex_coord:2f,color:4f" );
|
|
float s_fps = 60.0f / toMilliSeconds(fpsTime2 - fpsTime1) * 1000.0f;
|
|
std::string str = fmt::format("DEBUG FPS: {0:.2f}", s_fps);
|
|
vec2 bk = pen;
|
|
texture_font_load_glyphs(sub_font, str.c_str());
|
|
fps_vbo.add_text(sub_font, str, col, bk);
|
|
str = fmt::format("DEBUG ms: {0:.2f}", avgFrameTime);
|
|
// log_info("%.f ", avgFrameTime);
|
|
texture_font_load_glyphs(sub_font, str.c_str());
|
|
bk.x = pen.x;
|
|
bk.y -= 30;
|
|
fps_vbo.add_text(sub_font, str, col, bk);
|
|
|
|
fpsTime1 = fpsTime2;
|
|
fpsCount = 0;
|
|
}
|
|
//fps_vbo.render_vbo(NULL);
|
|
|
|
|
|
/// get timing, fps
|
|
if (!(frame % WEN))
|
|
{
|
|
float ti = get_time_ms(now);
|
|
double framerate = 1000.f / ti;
|
|
log_info("--------------------------------------------------");
|
|
log_info("[Render] AVG_time: %.3lf ms AVG_FPS: %.3lf", ti, framerate);
|
|
print_memory();
|
|
//reset Frame so we dont overflow later in release
|
|
frame = 1;
|
|
// MIN_STATUS_RESET wait for 120 frames to reset the status
|
|
mins_played = MIN_STATUS_RESET;
|
|
log_info("---------------------------------------------------");
|
|
//time_ms = now;
|
|
}
|
|
|
|
if (1) // update for the GLES uniform time
|
|
{
|
|
auto now = std::chrono::steady_clock::now();
|
|
dt = std::chrono::duration_cast<std::chrono::microseconds>(now - lastUpdate).count() / 1000000.0f;
|
|
lastUpdate = now;
|
|
u_t += dt;
|
|
}
|
|
|
|
orbisGlSwapBuffers(); /// flip frame
|
|
frame++;
|
|
|
|
MP3_Player(get->setting_strings[MP3_PATH]);
|
|
dump_frame();
|
|
|
|
}
|
|
|
|
error:
|
|
sceKernelIccSetBuzzer(2);
|
|
msgok(MSG_DIALOG::FATAL, fmt::format("App has Died: ({0:#x})", ret));
|
|
|
|
// destructors
|
|
ORBIS_RenderFillRects_fini();
|
|
on_GLES2_Final();
|
|
pixelshader_fini();
|
|
|
|
finishOrbisLinkApp();
|
|
raise(SIGQUIT);
|
|
return -1;
|
|
} |