[ALL] Added overlay callback

- Improved the overlay example. It's now using the wups api.
- Not working on TV when the game is rendered in 1080p. (Maybe add option to force screen to 720p?)
This commit is contained in:
Maschell 2018-02-20 12:41:58 +01:00
parent 285fc3b51a
commit 409527fb21
17 changed files with 363 additions and 134 deletions

View File

@ -61,7 +61,7 @@ ifneq ($(BUILD),$(notdir $(CURDIR)))
export TOPDIR ?= $(CURDIR)/..
export DEPSDIR := $(CURDIR)/$(BUILD)
export INCLUDEDIR := $(PORTLIBS)/include/libgui
export INCLUDEDIR := $(PORTLIBS)/include/
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
@ -78,7 +78,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include)
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)

View File

@ -1,7 +1,11 @@
#include "retain_vars.h"
#include "myutils/overlay_helper.h"
replacement_data_t gbl_replacement_data __attribute__((section(".data")));
u8 gAppStatus __attribute__((section(".data"))) = 0;
volatile u8 gSDInitDone __attribute__((section(".data"))) = 0;
void * ntfs_mounts __attribute__((section(".data"))) = NULL;
int ntfs_mount_count __attribute__((section(".data"))) = 0;
struct buffer_store drc_store __attribute__((section(".data")));
struct buffer_store tv_store __attribute__((section(".data")));

View File

@ -6,7 +6,11 @@ extern replacement_data_t gbl_replacement_data;
extern u8 gAppStatus;
extern volatile u8 gSDInitDone;
extern void * ntfs_mounts;
extern int ntfs_mount_count;
extern struct buffer_store drc_store;
extern struct buffer_store tv_store;
#endif // RETAINS_VARS_H_

View File

@ -48,6 +48,7 @@
#include "myutils/mocha.h"
#include "myutils/libntfs.h"
#include "myutils/libfat.h"
#include "myutils/overlay_helper.h"
#include "version.h"
#include "settings/CSettings.h"
@ -81,8 +82,7 @@ extern "C" int Menu_Main(int argc, char **argv){
setup_os_exceptions();
DEBUG_FUNCTION_LINE("Mount SD partition\n");
Init_SD_USB();
Init();
s32 result = 0;
@ -167,6 +167,7 @@ void CallHook(wups_loader_hook_type_t hook_type){
args.fs_wrapper.opendir_repl = (const void*)&opendir;
args.fs_wrapper.closedir_repl = (const void*)&closedir;
args.fs_wrapper.readdir_repl = (const void*)&readdir;
args.overlayfunction_ptr = (const void*)&overlay_helper;
( (void (*)(wups_loader_init_args_t *))((unsigned int*)func_ptr) )(&args);
}
@ -202,6 +203,13 @@ s32 isInMiiMakerHBL(){
return 0;
}
void Init(){
memset(&tv_store,0,sizeof(tv_store));
memset(&drc_store,0,sizeof(drc_store));
DEBUG_FUNCTION_LINE("Mount SD partition\n");
Init_SD_USB();
}
void Init_SD_USB() {
int res = IOSUHAX_Open(NULL);
if(res < 0){

View File

@ -35,6 +35,7 @@ void Init_SD_USB();
void DeInit_SD_USB();
void Init();
void DeInit();
#ifdef __cplusplus

View File

@ -20,6 +20,7 @@
#include <dynamic_libs/padscore_functions.h>
#include <utils/StringTools.h>
#include <utils/logger.h>
#include "myutils/overlay_helper.h"
#include "MainWindow.h"
#include "MainWindowGUI.h"
#include "Application.h"

View File

@ -0,0 +1,161 @@
#include <utils/logger.h>
#include <malloc.h>
#include "libfat.h"
#include <iosuhax.h>
#include <wups.h>
#include <fat.h>
#include "common/retain_vars.h"
#include "overlay_helper.h"
#include <dynamic_libs/gx2_functions.h>
#ifdef __cplusplus
extern "C" {
#endif
u32 * getFromGX2Buffer(struct buffer_store store, u32 size){
if(store.buffer != NULL){
DEBUG_FUNCTION_LINE("We try to use the GX2 buffer. Needed space %08X (%d kb), available %08X (%d kb).\n",size,size/1024,store.buffer_size,store.buffer_size/1024);
if(store.buffer_size >= size){
return (u32*) store.buffer;
}
}
return NULL;
}
void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback){
if(callback == NULL) return;
if(!OSIsHomeButtonMenuEnabled()) return; // This pauses the game. Make sure to only do it when the home button is allowed.
//TODO: Make sure this actually pauses the game (Hook on GX2VSync?) . Currently only tested from VPADRead which also pauses the game.
OSScreenInit();
u32 * screenbuffer0 = NULL;
u32 * screenbuffer1 = NULL;
bool allocated_tv = false;
bool allocated_drc = false;
if(screen == WUPS_OVERLAY_DRC_ONLY){
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size);
if(screenbuffer1 == NULL){
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n");
screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer1 != NULL){
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
allocated_drc = true;
}
}
} else if(screen == WUPS_OVERLAY_TV_ONLY){
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size);
if(screenbuffer0 == NULL){
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n");
screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
if(screenbuffer0 != NULL){
DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n");
allocated_tv = true;
}
}
} else if( screen == WUPS_OVERLAY_DRC_AND_TV || WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO){
// TV Buffer init.
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size);
if(screenbuffer0 == NULL){
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n");
screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
if(screenbuffer0 != NULL){
DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n");
allocated_tv = true;
}
}
// DRC Buffer init.
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
// Doesn't fit in the GX2 DRC buffer, we don't need to check it.
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n");
screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer1 != NULL){
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
allocated_drc = true;
}
if(screenbuffer1 == NULL){ // FAILED to allocate,
if(screen == WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO){
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
//but we can use the TV buffer from GX2.
if(!allocated_tv){ // Make sure it's not allocated
screenbuffer0 = NULL; // Bye bye
}
screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); // Use it! Hopefully this works.
}
}
}
if(screenbuffer0 == NULL && screenbuffer1 == NULL){
goto error_exit;
}
if(screenbuffer0 != NULL){ OSScreenSetBufferEx(0, (void *)screenbuffer0); }
if(screenbuffer1 != NULL){ OSScreenSetBufferEx(1, (void *)screenbuffer1); }
if(screenbuffer0 != NULL){ OSScreenEnableEx(0, 1); }
if(screenbuffer1 != NULL){ OSScreenEnableEx(1, 1); }
// Clear screens
if(screenbuffer0 != NULL){ OSScreenClearBufferEx(0, 0); }
if(screenbuffer1 != NULL){ OSScreenClearBufferEx(1, 0); }
// Flip buffers
if(screenbuffer0 != NULL){ OSScreenFlipBuffersEx(0); }
if(screenbuffer1 != NULL){ OSScreenFlipBuffersEx(1); }
wups_overlay_options_type_t real_screen_type;
if(screenbuffer0 != NULL){
if(screenbuffer1 != NULL){
real_screen_type = WUPS_OVERLAY_DRC_AND_TV;
} else {
real_screen_type = WUPS_OVERLAY_TV_ONLY;
}
} else if(screenbuffer1 != NULL){
real_screen_type = WUPS_OVERLAY_DRC_ONLY;
} else {
real_screen_type = WUPS_OVERLAY_NONE;
}
// call the callback.
if(real_screen_type != WUPS_OVERLAY_NONE){
callback(real_screen_type);
}
if(tv_store.buffer != NULL){
GX2SetTVBuffer(tv_store.buffer,tv_store.buffer_size,tv_store.mode,tv_store.surface_format,tv_store.buffering_mode);
}
if(drc_store.buffer != NULL){
GX2SetDRCBuffer(drc_store.buffer,drc_store.buffer_size,drc_store.mode,drc_store.surface_format,drc_store.buffering_mode);
}
error_exit:
if(allocated_tv){
free(screenbuffer0);
screenbuffer0 = NULL;
}
if(allocated_drc){
free(screenbuffer1);
screenbuffer1 = NULL;
}
return;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,24 @@
#ifndef __OVERLAY_HELPER_H_
#define __OVERLAY_HELPER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <wups.h>
struct buffer_store{
void * buffer;
s32 buffer_size;
s32 mode;
s32 surface_format;
vs32 buffering_mode;
};
void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -2,6 +2,7 @@
#include <utils/function_patcher.h>
#include "common/retain_vars.h"
#include "hooks_patcher.h"
#include "myutils/overlay_helper.h"
#include "main.h"
DECL(void, __PPCExit, void){
@ -22,11 +23,39 @@ DECL(u32, ProcUIProcessMessages, u32 u){
return res;
}
DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode){
tv_store.buffer = buffer;
tv_store.buffer_size = buffer_size;
tv_store.mode = tv_render_mode;
tv_store.surface_format = format;
tv_store.buffering_mode = buffering_mode;
return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode);
}
DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode){
drc_store.buffer = buffer;
drc_store.buffer_size = buffer_size;
drc_store.mode = drc_mode;
drc_store.surface_format = surface_format;
drc_store.buffering_mode = buffering_mode;
return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode);
}
DECL(void, GX2WaitForVsync, void){
real_GX2WaitForVsync();
}
hooks_magic_t method_hooks_hooks[] __attribute__((section(".data"))) = {
MAKE_MAGIC(__PPCExit, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION),
MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
};
u32 method_hooks_size_hooks __attribute__((section(".data"))) = sizeof(method_hooks_hooks) / sizeof(hooks_magic_t);
//! buffer to store our instructions needed for our replacements

View File

@ -36,7 +36,6 @@ INITIALIZE(args){
ControllerPatcher::Init(NULL);
}
ControllerPatcher::disableControllerMapping();
log_print("Start network server\n");

View File

@ -17,52 +17,38 @@
#include <wups.h>
#include "main.h"
#include <utils/logger.h>
#include <utils/StringTools.h>
#include <dynamic_libs/vpad_functions.h>
#include <dynamic_libs/os_functions.h>
u8 logVSync __attribute__((section(".data"))) = 0;
void SplashScreen_callback(wups_overlay_options_type_t screen){
s32 i=0;
while(i<100){
WUPS_Overlay_OSScreenClear(screen);
WUPS_Overlay_PrintTextOnScreen(screen, 0,0,"This could be something cool.");
WUPS_Overlay_PrintTextOnScreen(screen, 0,5,"Testing changing text: %d",i);
WUPS_Overlay_FlipBuffers(screen);
i++;
}
}
u8 gCallbackCooldown __attribute__((section(".data"))) = 0;
struct buffer_store{
void * buffer;
s32 buffer_size;
s32 mode;
s32 surface_format;
vs32 buffering_mode;
};
struct buffer_store drc_store __attribute__((section(".data")));
struct buffer_store tv_store __attribute__((section(".data")));
DECL_FUNCTION(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode){
tv_store.buffer = buffer;
tv_store.buffer_size = buffer_size;
tv_store.mode = tv_render_mode;
tv_store.surface_format = format;
tv_store.buffering_mode = buffering_mode;
return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode);
}
DECL_FUNCTION(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode){
drc_store.buffer = buffer;
drc_store.buffer_size = buffer_size;
drc_store.mode = drc_mode;
drc_store.surface_format = surface_format;
drc_store.buffering_mode = buffering_mode;
return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode);
}
DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
int result = real_VPADRead(chan, buffer, buffer_size, error);
int btns = VPAD_BUTTON_Y | VPAD_BUTTON_X | VPAD_BUTTON_A | VPAD_BUTTON_B;
if(result > 0 && ((buffer[0].btns_h & (btns)) == btns) && gCallbackCooldown == 0 ){
gCallbackCooldown = 0x3C;
logVSync = 1;
DCFlushRange(&logVSync,sizeof(logVSync));
DCInvalidateRange(&logVSync,sizeof(logVSync));
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_ONLY ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_TV_ONLY ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO ,SplashScreen_callback);
}
if(gCallbackCooldown > 0){
gCallbackCooldown--;
@ -71,21 +57,4 @@ DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *e
return result;
}
DECL_FUNCTION(void, GX2WaitForVsync, void){
real_GX2WaitForVsync();
if(logVSync){
if(OSIsHomeButtonMenuEnabled()){
SplashScreen(2);
// Restore the original buffer.
real_GX2SetTVBuffer(tv_store.buffer,tv_store.buffer_size,tv_store.mode,tv_store.surface_format,tv_store.buffering_mode);
real_GX2SetDRCBuffer(drc_store.buffer,drc_store.buffer_size,drc_store.mode,drc_store.surface_format,drc_store.buffering_mode);
}
logVSync = 0;
}
}
WUPS_MUST_REPLACE(GX2SetTVBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetTVBuffer);
WUPS_MUST_REPLACE(GX2SetDRCBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetDRCBuffer);
WUPS_MUST_REPLACE(GX2WaitForVsync, WUPS_LOADER_LIBRARY_GX2, GX2WaitForVsync);
WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead);

View File

@ -29,7 +29,6 @@
#include <dynamic_libs/gx2_types.h>
#include <dynamic_libs/socket_functions.h>
#include <utils/logger.h>
#include <utils/StringTools.h>
#include "main.h"
WUPS_PLUGIN_NAME("Overlay test");
@ -40,7 +39,6 @@ WUPS_PLUGIN_LICENSE("GPL");
/* Entry point */
INITIALIZE(args){
WUPS_InitFS(args);
InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging
InitVPadFunctionPointers();
@ -49,68 +47,6 @@ INITIALIZE(args){
InitGX2FunctionPointers();
log_init();
DEBUG_FUNCTION_LINE("OVERLAY TEST INIT DONE.\n");
}
void printTextOnScreen(int x,int y, const char * msg){
OSScreenPutFontEx(0, x, y, msg);
OSScreenPutFontEx(1, x, y, msg);
}
#define FPS 60
u32 SplashScreen(s32 time){
u32 result = 0;
OSScreenInit();
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
u32 * screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
u32 * screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer0 == NULL){
return 0;
}
if(screenbuffer1 == NULL){
free(screenbuffer0);
return 0;
}
OSScreenSetBufferEx(0, (void *)screenbuffer0);
OSScreenSetBufferEx(1, (void *)screenbuffer1);
OSScreenEnableEx(0, 1);
OSScreenEnableEx(1, 1);
// Clear screens
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
s32 tickswait = time * FPS * 16;
s32 sleepingtime = 16;
s32 times = tickswait/16;
s32 i=0;
while(i<times){
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
printTextOnScreen(0,0,"This could be something cool.");
printTextOnScreen(0,5,StringTools::strfmt("Testing changing text: %d",i).c_str());
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
i++;
os_usleep(sleepingtime*1000);
}
free(screenbuffer0);
free(screenbuffer1);
return result;
}

View File

@ -31,7 +31,4 @@ extern "C" {
}
#endif
u32 SplashScreen(s32 time);
#endif

View File

@ -21,7 +21,6 @@ WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL");
INITIALIZE(args){
WUPS_InitFS(args);
InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging
InitVPadFunctionPointers(); //For logging

View File

@ -46,10 +46,6 @@ u32 SplashScreen(s32 time,s32 combotime);
/* Entry point */
INITIALIZE(args){
if(gAppStatus == 2){
log_printf("No, we don't want to patch stuff again.");
return;
}
gAppStatus = 0;
InitOSFunctionPointers();

77
src/overlay.c Normal file
View File

@ -0,0 +1,77 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <wups.h>
#include <dynamic_libs/os_functions.h>
static void * overlayfunction_ptr __attribute__((section(".data"))) = NULL;
#ifdef __cplusplus
extern "C" {
#endif
void WUPS_InitOverlay(wups_loader_init_args_t* args){
if(args != NULL){
InitOSFunctionPointers();
overlayfunction_ptr = (void*) args->overlayfunction_ptr;
}
}
void WUPS_Overlay_PrintTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...){
if(screen == WUPS_OVERLAY_NONE){ return; }
char * tmp = NULL;
va_list va;
va_start(va, msg);
if((vasprintf(&tmp, msg, va) >= 0) && tmp){
if(screen != WUPS_OVERLAY_DRC_ONLY){ // Draw TV if it's not DRC exclusive.
OSScreenPutFontEx(0, x, y, tmp);
}
if(screen != WUPS_OVERLAY_TV_ONLY){ // Draw DRC if it's not TV exclusive.
OSScreenPutFontEx(1, x, y, tmp);
}
}
va_end(va);
if(tmp){
free(tmp);
}
}
void WUPS_Overlay_OSScreenClear(wups_overlay_options_type_t screen){
if(screen == WUPS_OVERLAY_NONE){ return; }
if(screen != WUPS_OVERLAY_DRC_ONLY){ // Clear TV if it's not DRC exclusive.
OSScreenClearBufferEx(0, 0);
}
if(screen != WUPS_OVERLAY_TV_ONLY){ // Clear DRC if it's not TV exclusive.
OSScreenClearBufferEx(1, 0);
}
}
void WUPS_Overlay_FlipBuffers(wups_overlay_options_type_t screen){
if(screen == WUPS_OVERLAY_NONE){ return; }
if(screen != WUPS_OVERLAY_DRC_ONLY){ // Flip TV buffer if it's not DRC exclusive.
OSScreenFlipBuffersEx(0);
}
if(screen != WUPS_OVERLAY_TV_ONLY){ // Flip DRC buffer if it's not TV exclusive.
OSScreenFlipBuffersEx(1);
}
}
void WUPS_OpenOverlay(wups_overlay_options_type_t screen, overlay_callback callback){
if(overlayfunction_ptr != NULL){
( (void (*)(wups_overlay_options_type_t, overlay_callback))((unsigned int*)overlayfunction_ptr) )(screen,callback);
}
}
#ifdef __cplusplus
}
#endif

View File

@ -143,6 +143,15 @@ typedef struct wups_loader_hook_t {
#define WUPS_SD_MOUNTED (WUPS_SDUSB_MOUNTED_OS_SD | WUPS_SD_MOUNTED_LIBFAT)
#define WUPS_USB_MOUNTED (WUPS_USB_MOUNTED_LIBFAT)
typedef enum wups_overlay_options_type_t {
WUPS_OVERLAY_NONE,
WUPS_OVERLAY_DRC_ONLY, /* Tries to display only on gamepad screen */
WUPS_OVERLAY_TV_ONLY, /* Tries to display only on tv screen */
WUPS_OVERLAY_DRC_AND_TV, /* Tries to display on both screens. Prioritizes the TV screen if memory is low. */
WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO /* Tries to display on both screens. But if memory is low, prioritize the DRC screen.*/
} wups_overlay_options_type_t;
typedef struct wups_loader_init_args_t {
int device_mounted;
struct {
@ -157,8 +166,12 @@ typedef struct wups_loader_init_args_t {
const void * closedir_repl;
const void * readdir_repl;
} fs_wrapper;
const void * overlayfunction_ptr;
} wups_loader_init_args_t;
void WUPS_InitFS(wups_loader_init_args_t* args);
void WUPS_InitOverlay(wups_loader_init_args_t* args);
#ifdef __cplusplus
#define EXTERN_C_START extern "C" {
#define EXTERN_C_END }
@ -173,6 +186,9 @@ typedef struct wups_loader_init_args_t {
WUPS_HOOK_INIT(init); \
void init(wups_loader_init_args_t* args){ \
if(args != NULL){\
WUPS_InitFS(args);\
WUPS_InitOverlay(args);\
\
}\
myInit(args);\
} \
@ -221,7 +237,15 @@ typedef struct wups_loader_entry_t {
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
void WUPS_InitFS(wups_loader_init_args_t* args);
typedef void (*overlay_callback)(wups_overlay_options_type_t);
void WUPS_Overlay_PrintTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...);
void WUPS_Overlay_OSScreenClear(wups_overlay_options_type_t screen);
void WUPS_Overlay_FlipBuffers(wups_overlay_options_type_t screen);
void WUPS_OpenOverlay(wups_overlay_options_type_t screen, overlay_callback callback);
#ifdef __cplusplus
}