mirror of
https://github.com/libretro/RetroArch
synced 2025-03-01 16:13:40 +00:00
This can fix a lot of performance issues, like audio crackling and frame time spikes. This requires the GameMode package to be installed. See: https://github.com/FeralInteractive/gamemode This commit adds a "Game Mode" bool option to the "Power Management" and "Latency" settings sections, and it can be toggled on/off without restarting RA. The actual toggling of game mode happens in a new frontend platform interface function. Perhaps this will become useful for other platforms that provide some equivalent of Linux GameMode. Since the GameMode ABI is fixed, and the API comes as a single, header-only file with no actual deps, we simply bundle the header (deps/feralgamemode/gamemode_client.h.) That way, all Linux builds will have support for GameMode regardless of whether the GameMode development package is installed or not.
379 lines
11 KiB
C
379 lines
11 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "../../config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <kernel.h>
|
|
#include <systemservice.h>
|
|
#include <orbis2d.h>
|
|
#include <orbisPad.h>
|
|
#include <orbisAudio.h>
|
|
#include <modplayer.h>
|
|
#include <ps4link.h>
|
|
#include <orbisKeyboard.h>
|
|
#include <debugnet.h>
|
|
#include <orbisFile.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <string/stdstring.h>
|
|
#include <boolean.h>
|
|
#include <file/file_path.h>
|
|
#ifndef IS_SALAMANDER
|
|
#include <lists/file_list.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_MENU
|
|
#include "../../menu/menu_driver.h"
|
|
#endif
|
|
|
|
#include "../frontend_driver.h"
|
|
#include "../../defaults.h"
|
|
#include "../../file_path_special.h"
|
|
#include "../../retroarch.h"
|
|
#include "../../paths.h"
|
|
#include "../../verbosity.h"
|
|
|
|
typedef struct OrbisGlobalConf
|
|
{
|
|
Orbis2dConfig *conf;
|
|
OrbisPadConfig *confPad;
|
|
OrbisAudioConfig *confAudio;
|
|
OrbisKeyboardConfig *confKeyboard;
|
|
ps4LinkConfiguration *confLink;
|
|
int orbisLinkFlag;
|
|
}OrbisGlobalConf;
|
|
|
|
OrbisGlobalConf *myConf;
|
|
|
|
char eboot_path[512];
|
|
char user_path[512];
|
|
|
|
static enum frontend_fork orbis_fork_mode = FRONTEND_FORK_NONE;
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
#endif
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int ret;
|
|
|
|
sceSystemServiceHideSplashScreen();
|
|
|
|
uintptr_t intptr=0;
|
|
sscanf(argv[1],"%p",&intptr);
|
|
myConf=(OrbisGlobalConf *)intptr;
|
|
ret=ps4LinkInitWithConf(myConf->confLink);
|
|
if(!ret)
|
|
{
|
|
ps4LinkFinish();
|
|
return -1;
|
|
}
|
|
|
|
return rarch_main(argc, argv, NULL);
|
|
}
|
|
|
|
static void frontend_orbis_get_env(int *argc, char *argv[],
|
|
void *args, void *params_data)
|
|
{
|
|
unsigned i;
|
|
struct rarch_main_wrap *params = NULL;
|
|
|
|
(void)args;
|
|
|
|
#ifndef IS_SALAMANDER
|
|
#if defined(HAVE_LOGGER)
|
|
logger_init();
|
|
#elif defined(HAVE_FILE_LOGGER)
|
|
retro_main_log_file_init("host0:app/temp/retroarch-log.txt");
|
|
#endif
|
|
#endif
|
|
|
|
int ret;
|
|
|
|
sceSystemServiceHideSplashScreen();
|
|
|
|
uintptr_t intptr=0;
|
|
sscanf(argv[1],"%p",&intptr);
|
|
argv[1] = NULL;
|
|
myConf=(OrbisGlobalConf *)intptr;
|
|
ret=ps4LinkInitWithConf(myConf->confLink);
|
|
if(!ret)
|
|
{
|
|
ps4LinkFinish();
|
|
return;
|
|
}
|
|
orbisFileInit();
|
|
orbisPadInitWithConf(myConf->confPad);
|
|
scePadClose(myConf->confPad->padHandle);
|
|
|
|
strcpy_literal(eboot_path, "host0:app");
|
|
strlcpy(g_defaults.dirs[DEFAULT_DIR_PORT], eboot_path, sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]));
|
|
strcpy_literal(user_path, "host0:app/data/retroarch/");
|
|
|
|
RARCH_LOG("port dir: [%s]\n", g_defaults.dirs[DEFAULT_DIR_PORT]);
|
|
|
|
/* bundle data*/
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], g_defaults.dirs[DEFAULT_DIR_PORT],
|
|
"", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_PORT],
|
|
"info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
|
|
/* user data*/
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], user_path,
|
|
"assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], user_path,
|
|
"database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], user_path,
|
|
"database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], user_path,
|
|
"cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], user_path,
|
|
"config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], user_path,
|
|
"downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], user_path,
|
|
"playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], user_path,
|
|
"remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], user_path,
|
|
"savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], user_path,
|
|
"savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path,
|
|
"system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], user_path,
|
|
"temp", sizeof(g_defaults.dirs[DEFAULT_DIR_CACHE]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], user_path,
|
|
"overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
|
|
#ifdef HAVE_VIDEO_LAYOUT
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], user_path,
|
|
"layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT]));
|
|
#endif
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path,
|
|
"thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS]));
|
|
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path,
|
|
"logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS]));
|
|
strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY],
|
|
user_path, sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY]));
|
|
fill_pathname_join(g_defaults.path_config, user_path,
|
|
FILE_PATH_MAIN_CONFIG, sizeof(g_defaults.path_config));
|
|
|
|
#ifndef IS_SALAMANDER
|
|
params = (struct rarch_main_wrap*)params_data;
|
|
params->verbose = true;
|
|
|
|
if (!string_is_empty(argv[2]))
|
|
{
|
|
static char path[PATH_MAX_LENGTH] = {0};
|
|
struct rarch_main_wrap *args =
|
|
(struct rarch_main_wrap*)params_data;
|
|
|
|
if (args)
|
|
{
|
|
strlcpy(path, argv[2], sizeof(path));
|
|
|
|
args->touched = true;
|
|
args->no_content = false;
|
|
args->verbose = false;
|
|
args->config_path = NULL;
|
|
args->sram_path = NULL;
|
|
args->state_path = NULL;
|
|
args->content_path = path;
|
|
args->libretro_path = NULL;
|
|
|
|
RARCH_LOG("argv[0]: %s\n", argv[0]);
|
|
RARCH_LOG("argv[1]: %s\n", argv[1]);
|
|
RARCH_LOG("argv[2]: %s\n", argv[2]);
|
|
|
|
RARCH_LOG("Auto-start game %s.\n", argv[2]);
|
|
}
|
|
}
|
|
|
|
dir_check_defaults("host0:app/custom.ini");
|
|
#endif
|
|
}
|
|
|
|
static void frontend_orbis_deinit(void *data)
|
|
{
|
|
(void)data;
|
|
#ifndef IS_SALAMANDER
|
|
verbosity_disable();
|
|
#ifdef HAVE_FILE_LOGGER
|
|
retro_main_log_file_deinit();
|
|
#endif
|
|
#endif
|
|
ps4LinkFinish();
|
|
}
|
|
|
|
static void frontend_orbis_shutdown(bool unused)
|
|
{
|
|
(void)unused;
|
|
return;
|
|
}
|
|
|
|
static void frontend_orbis_init(void *data)
|
|
{
|
|
|
|
}
|
|
|
|
static void frontend_orbis_exec(const char *path, bool should_load_game)
|
|
{
|
|
char argp[512] = {0};
|
|
int args = 0;
|
|
|
|
#ifndef IS_SALAMANDER
|
|
if (should_load_game && !path_is_empty(RARCH_PATH_CONTENT))
|
|
{
|
|
argp[args] = '\0';
|
|
strlcat(argp + args, path_get(RARCH_PATH_CONTENT), sizeof(argp) - args);
|
|
args += strlen(argp + args) + 1;
|
|
}
|
|
#endif
|
|
|
|
RARCH_LOG("Attempt to load executable: [%s].\n", path);
|
|
RARCH_LOG("Attempt to load executable: %d [%s].\n", args, argp);
|
|
//int ret = sceAppMgrLoadExec(path, args==0? NULL : (char * const*)((const char*[]){argp, 0}), NULL);
|
|
//RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
|
|
|
}
|
|
|
|
#ifndef IS_SALAMANDER
|
|
static bool frontend_orbis_set_fork(enum frontend_fork fork_mode)
|
|
{
|
|
switch (fork_mode)
|
|
{
|
|
case FRONTEND_FORK_CORE:
|
|
RARCH_LOG("FRONTEND_FORK_CORE\n");
|
|
orbis_fork_mode = fork_mode;
|
|
break;
|
|
case FRONTEND_FORK_CORE_WITH_ARGS:
|
|
RARCH_LOG("FRONTEND_FORK_CORE_WITH_ARGS\n");
|
|
orbis_fork_mode = fork_mode;
|
|
break;
|
|
case FRONTEND_FORK_RESTART:
|
|
RARCH_LOG("FRONTEND_FORK_RESTART\n");
|
|
/* NOTE: We don't implement Salamander, so just turn
|
|
* this into FRONTEND_FORK_CORE. */
|
|
orbis_fork_mode = FRONTEND_FORK_CORE;
|
|
break;
|
|
case FRONTEND_FORK_NONE:
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
static void frontend_orbis_exitspawn(char *s, size_t len, char *args)
|
|
{
|
|
bool should_load_game = false;
|
|
#ifndef IS_SALAMANDER
|
|
if (orbis_fork_mode == FRONTEND_FORK_NONE)
|
|
return;
|
|
|
|
switch (orbis_fork_mode)
|
|
{
|
|
case FRONTEND_FORK_CORE_WITH_ARGS:
|
|
should_load_game = true;
|
|
break;
|
|
case FRONTEND_FORK_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
frontend_orbis_exec(s, should_load_game);
|
|
}
|
|
|
|
static int frontend_orbis_get_rating(void)
|
|
{
|
|
return 6; /* Go with a conservative figure for now. */
|
|
}
|
|
|
|
enum frontend_architecture frontend_orbis_get_arch(void)
|
|
{
|
|
return FRONTEND_ARCH_X86_64;
|
|
}
|
|
|
|
static int frontend_orbis_parse_drive_list(void *data, bool load_content)
|
|
{
|
|
#ifndef IS_SALAMANDER
|
|
file_list_t *list = (file_list_t*)data;
|
|
enum msg_hash_enums enum_idx = load_content ?
|
|
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
|
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
|
|
|
menu_entries_append_enum(list,
|
|
"host0:app",
|
|
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
|
enum_idx,
|
|
FILE_TYPE_DIRECTORY, 0, 0);
|
|
#endif
|
|
return 0;
|
|
|
|
}
|
|
|
|
frontend_ctx_driver_t frontend_ctx_orbis = {
|
|
frontend_orbis_get_env,
|
|
frontend_orbis_init,
|
|
frontend_orbis_deinit,
|
|
frontend_orbis_exitspawn,
|
|
NULL, /* process_args */
|
|
frontend_orbis_exec,
|
|
#ifdef IS_SALAMANDER
|
|
NULL,
|
|
#else
|
|
frontend_orbis_set_fork,
|
|
#endif
|
|
frontend_orbis_shutdown,
|
|
NULL, /* get_name */
|
|
NULL, /* get_os */
|
|
frontend_orbis_get_rating,
|
|
NULL, /* content_loaded */
|
|
frontend_orbis_get_arch,
|
|
NULL,
|
|
frontend_orbis_parse_drive_list,
|
|
NULL, /* get_total_mem */
|
|
NULL, /* get_free_mem */
|
|
NULL, /* install_signal_handler */
|
|
NULL, /* get_sighandler_state */
|
|
NULL, /* set_sighandler_state */
|
|
NULL, /* destroy_sighandler_state */
|
|
NULL, /* attach_console */
|
|
NULL, /* detach_console */
|
|
NULL, /* get_lakka_version */
|
|
NULL, /* set_screen_brightness */
|
|
NULL, /* watch_path_for_changes */
|
|
NULL, /* check_for_path_changes */
|
|
NULL, /* set_sustained_performance_mode */
|
|
NULL, /* get_cpu_model_name */
|
|
NULL, /* get_user_language */
|
|
NULL, /* is_narrator_running */
|
|
NULL, /* accessibility_speak */
|
|
NULL, /* set_gamemode */
|
|
"orbis", /* ident */
|
|
NULL /* get_video_driver */
|
|
};
|