mirror of
https://github.com/libretro/RetroArch
synced 2024-12-28 18:31:05 +00:00
9ae2514009
Set USE_CTRULIB_2=1 to build with libctru 2.0. When unset, this code is compatible with the older toolchain. Some 2.0 changes addressed rare problems in earlier versions: - Save / restore stack pointer for init / exit Otherwise, it could be outside of the range we deallocate. - Run aptMainLoop in the audio driver to react correctly to sleep events Other changes for 2.0: - Remove ninjhax1 -- requires outdated APIs that have been removed - Switch from __sync_arbiter to syncArbitrateAddress - Use implicit gxCmdBuf - Use gpuPresentBuffer for double buffering
92 lines
2.0 KiB
C
92 lines
2.0 KiB
C
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "mini-hb-menu/common.h"
|
|
|
|
extern const loaderFuncs_s loader_Ninjhax2;
|
|
extern const loaderFuncs_s loader_Rosalina;
|
|
|
|
static void (*launch_3dsx)(const char* path,
|
|
argData_s* args, executableMetadata_s* em);
|
|
|
|
static int exec_3dsx_actual(const char* path,
|
|
const char** args, bool appendPath)
|
|
{
|
|
bool inited;
|
|
bool fileExists;
|
|
struct stat sBuff;
|
|
argData_s newProgramArgs;
|
|
unsigned int argChars = 0;
|
|
unsigned int argNum = 0;
|
|
|
|
if (!path || path[0] == '\0')
|
|
{
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
fileExists = stat(path, &sBuff) == 0;
|
|
if (!fileExists)
|
|
{
|
|
errno = ENOENT;
|
|
return -1;
|
|
}
|
|
else if (S_ISDIR(sBuff.st_mode))
|
|
{
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
/* args the string functions write to the passed string,
|
|
* this will cause a write to read only memory,
|
|
* so the string must be cloned */
|
|
memset(newProgramArgs.buf, '\0', sizeof(newProgramArgs.buf));
|
|
newProgramArgs.dst = (char*)&newProgramArgs.buf[1];
|
|
if (appendPath)
|
|
{
|
|
strcpy(newProgramArgs.dst, path);
|
|
newProgramArgs.dst += strlen(path) + 1;
|
|
newProgramArgs.buf[0]++;
|
|
}
|
|
|
|
while(args[argNum])
|
|
{
|
|
strcpy(newProgramArgs.dst, args[argNum]);
|
|
newProgramArgs.dst += strlen(args[argNum]) + 1;
|
|
newProgramArgs.buf[0]++;
|
|
argNum++;
|
|
}
|
|
|
|
inited = loader_Rosalina.init();
|
|
launch_3dsx = loader_Rosalina.launchFile;
|
|
|
|
if (!inited)
|
|
{
|
|
inited = loader_Ninjhax2.init();
|
|
launch_3dsx = loader_Ninjhax2.launchFile;
|
|
}
|
|
|
|
if (inited)
|
|
{
|
|
osSetSpeedupEnable(false);
|
|
launch_3dsx(path, &newProgramArgs, NULL);
|
|
exit(0);
|
|
}
|
|
|
|
/* should never be reached */
|
|
errno = ENOTSUP;
|
|
return -1;
|
|
}
|
|
|
|
int exec_3dsx(const char* path, const char** args)
|
|
{
|
|
return exec_3dsx_actual(path, args, true/*appendPath*/);
|
|
}
|
|
|
|
int exec_3dsx_no_path_in_args(const char* path, const char** args)
|
|
{
|
|
return exec_3dsx_actual(path, args, false/*appendPath*/);
|
|
}
|