mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 08:30:16 +00:00
233 lines
4.5 KiB
C
233 lines
4.5 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2014-2016 - Ali Bouhlel
|
|
* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fat.h>
|
|
#include <iosuhax.h>
|
|
#include <sys/iosupport.h>
|
|
|
|
#include "hbl.h"
|
|
|
|
#include "fs/fs_utils.h"
|
|
#include "fs/sd_fat_devoptab.h"
|
|
|
|
#include "system/dynamic.h"
|
|
#include "system/memory.h"
|
|
#include "system/exception_handler.h"
|
|
|
|
#include <wiiu/gx2.h>
|
|
#include <wiiu/ios.h>
|
|
#include <wiiu/kpad.h>
|
|
#include <wiiu/os.h>
|
|
#include <wiiu/procui.h>
|
|
#include <wiiu/sysapp.h>
|
|
|
|
/**
|
|
* This file contains the main entrypoints for the Wii U executable that
|
|
* set up the call to main().
|
|
*/
|
|
|
|
int main(int argc, char **argv);
|
|
void __fini(void);
|
|
void __init(void);
|
|
|
|
static void fsdev_init(void);
|
|
static void fsdev_exit(void);
|
|
|
|
bool iosuhaxMount = 0;
|
|
|
|
static int mcp_hook_fd = -1;
|
|
|
|
/* HBL elf entry point */
|
|
int __entry_menu(int argc, char **argv)
|
|
{
|
|
int ret;
|
|
|
|
InitFunctionPointers();
|
|
memoryInitialize();
|
|
__init();
|
|
fsdev_init();
|
|
|
|
ret = main(argc, argv);
|
|
|
|
fsdev_exit();
|
|
__fini();
|
|
memoryRelease();
|
|
return ret;
|
|
}
|
|
|
|
/* RPX entry point */
|
|
__attribute__((noreturn))
|
|
void _start(int argc, char **argv)
|
|
{
|
|
memoryInitialize();
|
|
__init();
|
|
fsdev_init();
|
|
main(argc, argv);
|
|
fsdev_exit();
|
|
|
|
/* TODO: fix elf2rpl so it doesn't error with "Could not find matching symbol
|
|
for relocation" then uncomment this */
|
|
#if 0
|
|
__fini();
|
|
#endif
|
|
memoryRelease();
|
|
SYSRelaunchTitle(0, 0);
|
|
exit(0);
|
|
}
|
|
|
|
void __eabi(void)
|
|
{
|
|
|
|
}
|
|
|
|
__attribute__((weak))
|
|
void __init(void)
|
|
{
|
|
extern void (*const __CTOR_LIST__)(void);
|
|
extern void (*const __CTOR_END__)(void);
|
|
|
|
void (*const *ctor)(void) = &__CTOR_LIST__;
|
|
while (ctor < &__CTOR_END__) {
|
|
(*ctor++)();
|
|
}
|
|
}
|
|
|
|
__attribute__((weak))
|
|
void __fini(void)
|
|
{
|
|
extern void (*const __DTOR_LIST__)(void);
|
|
extern void (*const __DTOR_END__)(void);
|
|
|
|
void (*const *dtor)(void) = &__DTOR_LIST__;
|
|
while (dtor < &__DTOR_END__) {
|
|
(*dtor++)();
|
|
}
|
|
}
|
|
|
|
/* libiosuhax related */
|
|
|
|
//just to be able to call async
|
|
void someFunc(void *arg)
|
|
{
|
|
(void)arg;
|
|
}
|
|
|
|
int MCPHookOpen(void)
|
|
{
|
|
//take over mcp thread
|
|
mcp_hook_fd = IOS_Open("/dev/mcp", 0);
|
|
|
|
if (mcp_hook_fd < 0)
|
|
return -1;
|
|
|
|
IOS_IoctlAsync(mcp_hook_fd, 0x62, (void *)0, 0, (void *)0, 0, someFunc, (void *)0);
|
|
//let wupserver start up
|
|
usleep(1000);
|
|
|
|
if (IOSUHAX_Open("/dev/mcp") < 0)
|
|
{
|
|
IOS_Close(mcp_hook_fd);
|
|
mcp_hook_fd = -1;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void MCPHookClose(void)
|
|
{
|
|
if (mcp_hook_fd < 0)
|
|
return;
|
|
|
|
//close down wupserver, return control to mcp
|
|
IOSUHAX_Close();
|
|
//wait for mcp to return
|
|
usleep(1000);
|
|
IOS_Close(mcp_hook_fd);
|
|
mcp_hook_fd = -1;
|
|
}
|
|
|
|
static bool try_init_iosuhax(void)
|
|
{
|
|
int result = IOSUHAX_Open(NULL);
|
|
if(result < 0)
|
|
result = MCPHookOpen();
|
|
|
|
return (result < 0) ? false : true;
|
|
}
|
|
|
|
static void try_shutdown_iosuhax(void)
|
|
{
|
|
if(!iosuhaxMount)
|
|
return;
|
|
|
|
if (mcp_hook_fd >= 0)
|
|
MCPHookClose();
|
|
else
|
|
IOSUHAX_Close();
|
|
|
|
iosuhaxMount = false;
|
|
}
|
|
|
|
/**
|
|
* Mount the filesystem(s) needed by the application. By default, we
|
|
* mount the SD card to /sd.
|
|
*
|
|
* The 'iosuhaxMount' symbol used here is public and can be referenced
|
|
* in overriding implementations.
|
|
*/
|
|
__attribute__((weak))
|
|
void __mount_filesystems(void)
|
|
{
|
|
if(iosuhaxMount)
|
|
fatInitDefault();
|
|
else
|
|
mount_sd_fat("sd");
|
|
}
|
|
|
|
/**
|
|
* Unmount filesystems. Implementing applications should be careful to
|
|
* clean up anything mounted in __mount_filesystems() here.
|
|
*/
|
|
__attribute__((weak))
|
|
void __unmount_filesystems(void)
|
|
{
|
|
if (iosuhaxMount)
|
|
{
|
|
fatUnmount("sd:");
|
|
fatUnmount("usb:");
|
|
}
|
|
else
|
|
unmount_sd_fat("sd");
|
|
}
|
|
|
|
static void fsdev_init(void)
|
|
{
|
|
iosuhaxMount = try_init_iosuhax();
|
|
|
|
__mount_filesystems();
|
|
}
|
|
|
|
static void fsdev_exit(void)
|
|
{
|
|
__unmount_filesystems();
|
|
try_shutdown_iosuhax();
|
|
}
|