mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2025-01-11 00:59:06 +01:00
WUPS 0.6, add support for config and storage
This commit is contained in:
parent
77e931969a
commit
6510dd5c21
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,3 +29,4 @@ debug/
|
||||
*.cbp
|
||||
lib/
|
||||
cmake-build-debug/
|
||||
CMakeLists.txt
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM wiiuenv/devkitppc:20210917
|
||||
FROM wiiuenv/devkitppc:20210920
|
||||
|
||||
WORKDIR tmp_build
|
||||
COPY . .
|
||||
|
8
Makefile
8
Makefile
@ -2,7 +2,7 @@ TOPDIR ?= $(CURDIR)
|
||||
include $(TOPDIR)/share/wups_rules
|
||||
|
||||
export WUT_MAJOR := 0
|
||||
export WUT_MINOR := 5
|
||||
export WUT_MINOR := 6
|
||||
export WUT_PATCH := 0
|
||||
|
||||
VERSION := $(WUT_MAJOR).$(WUT_MINOR).$(WUT_PATCH)
|
||||
@ -16,7 +16,8 @@ VERSION := $(WUT_MAJOR).$(WUT_MINOR).$(WUT_PATCH)
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := wups
|
||||
#BUILD := build
|
||||
SOURCES := libraries/libwups/
|
||||
SOURCES := libraries/libwups/ \
|
||||
libraries/libwups/utils
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
@ -25,12 +26,13 @@ INCLUDES := include
|
||||
#---------------------------------------------------------------------------------
|
||||
CFLAGS := -g -Wall -Werror -save-temps \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-fno-exceptions -fno-rtti \
|
||||
$(MACHDEP) \
|
||||
$(BUILD_CFLAGS)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++17
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++20
|
||||
|
||||
ASFLAGS := -g $(MACHDEP)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* by Alex Chadwick
|
||||
*
|
||||
* Copyright (C) 2014, Alex Chadwick
|
||||
* Modified by Maschell, 2018
|
||||
* Modified by Maschell, 2018-2021
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -23,12 +23,12 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WUPS_H_
|
||||
#define WUPS_H_
|
||||
#pragma once
|
||||
|
||||
#include "wups/common.h"
|
||||
#include "wups/meta.h"
|
||||
#include "wups/function_patching.h"
|
||||
#include "wups/config.h"
|
||||
#include "wups/hooks.h"
|
||||
|
||||
#endif /* WUPS_WUPS_H_ */
|
||||
#include "wups/config_imports.h"
|
||||
#include "wups/storage.h"
|
||||
|
@ -23,8 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WUPS_COMMON_DEF_H_
|
||||
#define WUPS_COMMON_DEF_H_
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -48,5 +47,3 @@ extern "C" {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WUPS_COMMON_DEF_H_ */
|
||||
|
55
include/wups/config.h
Normal file
55
include/wups/config.h
Normal file
@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2021 Maschell
|
||||
*
|
||||
* This program 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 Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define WUPS_CONFIG_BUTTON_NONE 0
|
||||
#define WUPS_CONFIG_BUTTON_LEFT (1<<0)
|
||||
#define WUPS_CONFIG_BUTTON_RIGHT (1<<1)
|
||||
#define WUPS_CONFIG_BUTTON_UP (1<<2)
|
||||
#define WUPS_CONFIG_BUTTON_DOWN (1<<3)
|
||||
#define WUPS_CONFIG_BUTTON_A (1<<4)
|
||||
#define WUPS_CONFIG_BUTTON_B (1<<5)
|
||||
#define WUPS_CONFIG_BUTTON_ZL (1<<6)
|
||||
#define WUPS_CONFIG_BUTTON_ZR (1<<7)
|
||||
#define WUPS_CONFIG_BUTTON_L (1<<8)
|
||||
#define WUPS_CONFIG_BUTTON_R (1<<9)
|
||||
typedef int32_t WUPSConfigButtons;
|
||||
|
||||
typedef struct {
|
||||
int32_t (*getCurrentValueDisplay)(void *context, char *out_buf, int32_t out_size);
|
||||
|
||||
int32_t (*getCurrentValueSelectedDisplay)(void *context, char *out_buf, int32_t out_size);
|
||||
|
||||
void (*onSelected)(void *context, bool isSelected);
|
||||
|
||||
void (*restoreDefault)(void *context);
|
||||
|
||||
bool (*isMovementAllowed)(void *context);
|
||||
|
||||
bool (*callCallback)(void *context);
|
||||
|
||||
void (*onButtonPressed)(void *context, WUPSConfigButtons button);
|
||||
|
||||
void (*onDelete)(void *context);
|
||||
} WUPSConfigCallbacks_t;
|
||||
|
||||
typedef uint32_t WUPSConfigItemHandle;
|
||||
typedef uint32_t WUPSConfigHandle;
|
||||
typedef uint32_t WUPSConfigCategoryHandle;
|
40
include/wups/config/WUPSConfigItemBoolean.h
Normal file
40
include/wups/config/WUPSConfigItemBoolean.h
Normal file
@ -0,0 +1,40 @@
|
||||
#include <wups.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ConfigItemBoolean {
|
||||
WUPSConfigItemHandle handle;
|
||||
bool defaultValue;
|
||||
bool value;
|
||||
char trueValue[32];
|
||||
char falseValue[32];
|
||||
void *callback;
|
||||
} ConfigItemBoolean;
|
||||
|
||||
typedef void (*BooleanValueChangedCallback)(ConfigItemBoolean *, bool);
|
||||
|
||||
bool WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback);
|
||||
bool WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback, const char *trueValue,
|
||||
const char *falseValue);
|
||||
|
||||
#define WUPSConfigItemBoolean_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__) \
|
||||
do { \
|
||||
if (!WUPSConfigItemBoolean_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __callback__)) { \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define WUPSConfigItemBoolean_AddToCategoryHandledEx(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__) \
|
||||
do { \
|
||||
if (!WUPSConfigItemBoolean_AddToCategoryEx(__cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__)) { \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
33
include/wups/config/WUPSConfigItemIntegerRange.h
Normal file
33
include/wups/config/WUPSConfigItemIntegerRange.h
Normal file
@ -0,0 +1,33 @@
|
||||
#include <wups.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ConfigItemIntegerRange {
|
||||
WUPSConfigItemHandle handle;
|
||||
int defaultValue;
|
||||
int value;
|
||||
int minValue;
|
||||
int maxValue;
|
||||
void *callback;
|
||||
} ConfigItemIntegerRange;
|
||||
|
||||
typedef void (*IntegerRangeValueChangedCallback)(ConfigItemIntegerRange *, int32_t);
|
||||
|
||||
bool
|
||||
WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName,
|
||||
int32_t defaultValue, int32_t minValue, int32_t maxValue,
|
||||
IntegerRangeValueChangedCallback callback);
|
||||
|
||||
#define WUPSConfigItemIntegerRange_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__) \
|
||||
do { \
|
||||
if (!WUPSConfigItemIntegerRange_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__)) { \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
37
include/wups/config/WUPSConfigItemMultipleValues.h
Normal file
37
include/wups/config/WUPSConfigItemMultipleValues.h
Normal file
@ -0,0 +1,37 @@
|
||||
#include <wups.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ConfigItemMultipleValuesPair {
|
||||
uint32_t value;
|
||||
char *valueName;
|
||||
} ConfigItemMultipleValuesPair;
|
||||
|
||||
typedef struct ConfigItemMultipleValues {
|
||||
char *configID;
|
||||
WUPSConfigItemHandle handle;
|
||||
int32_t defaultValueIndex;
|
||||
int32_t valueIndex;
|
||||
void *callback;
|
||||
ConfigItemMultipleValuesPair *values;
|
||||
int valueCount;
|
||||
} ConfigItemMultipleValues;
|
||||
|
||||
typedef void (*MultipleValuesChangedCallback)(ConfigItemMultipleValues *, uint32_t);
|
||||
|
||||
bool WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, int defaultValueIndex, ConfigItemMultipleValuesPair *possibleValues,
|
||||
int pairCount, MultipleValuesChangedCallback callback);
|
||||
|
||||
#define WUPSConfigItemMultipleValues_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__) \
|
||||
do { \
|
||||
if(!WUPSConfigItemMultipleValues_AddToCategory(__cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__)) { \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
53
include/wups/config_imports.h
Normal file
53
include/wups/config_imports.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
#include "config.h"
|
||||
|
||||
extern "C" int32_t WUPSConfigItem_Create(WUPSConfigItemHandle *out, const char *configID, const char *displayName, WUPSConfigCallbacks_t callbacks, void *context);
|
||||
|
||||
extern "C" int32_t WUPSConfig_Destroy(WUPSConfigHandle handle);
|
||||
|
||||
extern "C" int32_t WUPSConfigItem_SetDisplayName(WUPSConfigItemHandle handle, const char *displayName);
|
||||
|
||||
extern "C" int32_t WUPSConfigItem_GetDisplayName(WUPSConfigItemHandle handle, char *out_buf, int32_t out_len);
|
||||
|
||||
extern "C" int32_t WUPSConfigItem_SetConfigID(WUPSConfigItemHandle handle, const char *configID);
|
||||
|
||||
extern "C" int32_t WUPSConfigItem_GetConfigID(WUPSConfigItemHandle handle, char *out_buf, int32_t out);
|
||||
|
||||
extern "C" int32_t WUPSConfig_Create(WUPSConfigHandle *out, const char *name);
|
||||
|
||||
extern "C" int32_t WUPSConfigCategory_Destroy(WUPSConfigCategoryHandle handle);
|
||||
|
||||
extern "C" int32_t WUPSConfig_GetName(WUPSConfigHandle handle, char *out_buf, int32_t out_len);
|
||||
|
||||
extern "C" int32_t WUPSConfig_AddCategoryByName(WUPSConfigHandle handle, const char *categoryName, WUPSConfigCategoryHandle *out);
|
||||
|
||||
extern "C" int32_t WUPSConfig_AddCategory(WUPSConfigHandle handle, WUPSConfigCategoryHandle category);
|
||||
|
||||
/*
|
||||
extern "C" int32_t WUPSConfig_GetCategoryCount(WUPSConfigHandle handle, int32_t *category_count);
|
||||
|
||||
extern "C" int32_t WUPSConfig_GetCategories(WUPSConfigHandle handle, WUPSConfigCategoryHandle *categories_out, int32_t categories_out_size);
|
||||
*/
|
||||
|
||||
extern "C" int32_t WUPSConfigCategory_Create(WUPSConfigCategoryHandle *out, const char *name);
|
||||
|
||||
extern "C" int32_t WUPSConfigCategory_GetName(WUPSConfigCategoryHandle handle, char *out_buf, int32_t out_len);
|
||||
|
||||
extern "C" int32_t WUPSConfigCategory_AddItem(WUPSConfigCategoryHandle handle, WUPSConfigItemHandle item_Handle);
|
||||
|
||||
#define WUPSConfig_AddCategoryByNameHandled(__config__, __categoryName__, __out__) \
|
||||
do { \
|
||||
if (WUPSConfig_AddCategoryByName(__config__, __categoryName__, __out__) < 0) { \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0;\
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define WUPSConfig_CreateHandled(__config__, __configName__) \
|
||||
do { \
|
||||
if (WUPSConfig_Create(__config__, __configName__) < 0) { \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
@ -23,8 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WUPS_FUNCTION_PATCHING_DEF_H_
|
||||
#define WUPS_FUNCTION_PATCHING_DEF_H_
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@ -100,8 +99,7 @@ typedef enum wups_loader_library_type_t {
|
||||
WUPS_LOADER_LIBRARY_VPADBASE,
|
||||
WUPS_LOADER_LIBRARY_ZLIB125,
|
||||
WUPS_LOADER_LIBRARY_OTHER,
|
||||
}
|
||||
wups_loader_library_type_t;
|
||||
} wups_loader_library_type_t;
|
||||
|
||||
typedef enum wups_loader_entry_type_t {
|
||||
WUPS_LOADER_ENTRY_FUNCTION,
|
||||
@ -143,11 +141,11 @@ typedef struct wups_loader_entry_t {
|
||||
} _function;
|
||||
} wups_loader_entry_t;
|
||||
|
||||
#define WUPS_MUST_REPLACE_PHYSICAL(x, physical_address, virtual_address) WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU);
|
||||
#define WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, targetProcess) WUPS_MUST_REPLACE_EX(physical_address, virtual_address, real_ ## x, WUPS_LOADER_LIBRARY_OTHER, my_ ## x, x, targetProcess);
|
||||
#define WUPS_MUST_REPLACE_PHYSICAL(x, physical_address, virtual_address) WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU)
|
||||
#define WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, targetProcess) WUPS_MUST_REPLACE_EX(physical_address, virtual_address, real_ ## x, WUPS_LOADER_LIBRARY_OTHER, my_ ## x, x, targetProcess)
|
||||
|
||||
#define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU);
|
||||
#define WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, targetProcess) WUPS_MUST_REPLACE_EX(NULL, NULL, real_ ## x, lib, my_ ## x, function_name, targetProcess);
|
||||
#define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU)
|
||||
#define WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, targetProcess) WUPS_MUST_REPLACE_EX(NULL, NULL, real_ ## x, lib, my_ ## x, function_name, targetProcess)
|
||||
|
||||
#define WUPS_MUST_REPLACE_EX(pAddress, vAddress, original_func, rpl_type, replace_func, replace_function_name, process) \
|
||||
extern const wups_loader_entry_t wups_load_ ## replace_func \
|
||||
@ -172,6 +170,4 @@ typedef struct wups_loader_entry_t {
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WUPS_FUNCTION_PATCHING_DEF_H_ */
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
* Copyright (C) 2018-2021 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -15,8 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WUPS_HOOKS_DEF_H_
|
||||
#define WUPS_HOOKS_DEF_H_
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@ -24,7 +23,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WUPS_HOOK_EX(type_def,original_func) \
|
||||
#define WUPS_HOOK_EX(type_def, original_func) \
|
||||
extern const wups_loader_hook_t wups_hooks_ ## original_func WUPS_SECTION("hooks"); \
|
||||
const wups_loader_hook_t wups_hooks_ ## original_func = { \
|
||||
.type = type_def, \
|
||||
@ -43,6 +42,11 @@ typedef enum wups_loader_hook_type_t {
|
||||
WUPS_LOADER_HOOK_INIT_WUT_SOCKETS,
|
||||
WUPS_LOADER_HOOK_FINI_WUT_SOCKETS,
|
||||
|
||||
WUPS_LOADER_HOOK_GET_CONFIG,
|
||||
WUPS_LOADER_HOOK_CONFIG_CLOSED,
|
||||
|
||||
WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */
|
||||
|
||||
WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */
|
||||
WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */
|
||||
WUPS_LOADER_HOOK_APPLICATION_STARTS, /* Called when an application gets started */
|
||||
@ -51,7 +55,6 @@ typedef enum wups_loader_hook_type_t {
|
||||
WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */
|
||||
WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */
|
||||
WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */
|
||||
WUPS_LOADER_HOOK_VSYNC, /* Called when an application calls GX2WaitForVsync (most times each frame) */
|
||||
} wups_loader_hook_type_t;
|
||||
|
||||
typedef struct wups_loader_hook_t {
|
||||
@ -88,7 +91,7 @@ typedef struct wups_loader_hook_t {
|
||||
void on_acquired_foreground(void);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND,on_acquired_foreground); \
|
||||
void on_acquired_foreground(void)
|
||||
|
||||
|
||||
#define ON_APPLICATION_REQUESTS_EXIT() \
|
||||
void on_app_requests_exit(void);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT,on_app_requests_exit); \
|
||||
@ -99,14 +102,25 @@ typedef struct wups_loader_hook_t {
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_ENDS,on_app_ending); \
|
||||
void on_app_ending(void)
|
||||
|
||||
#define ON_VYSNC() \
|
||||
void on_vsync(void);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_VSYNC,on_vsync); \
|
||||
void on_vsync(void)
|
||||
#define WUPS_GET_CONFIG() \
|
||||
WUPSConfigHandle on_get_wups_config(void);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_GET_CONFIG,on_get_wups_config); \
|
||||
WUPSConfigHandle on_get_wups_config(void)
|
||||
|
||||
#define WUPS_CONFIG_CLOSED() \
|
||||
void on_wups_config_closed(void);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_CONFIG_CLOSED,on_wups_config_closed); \
|
||||
void on_wups_config_closed(void)
|
||||
|
||||
#define WUPS_USE_STORAGE() \
|
||||
void init_storage(wups_loader_init_storage_args_t);\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_STORAGE,init_storage); \
|
||||
void init_storage(wups_loader_init_storage_args_t args){ \
|
||||
WUPS_InitStorage(args);\
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define __EXTERN_C_MACRO extern "C"
|
||||
#define __EXTERN_C_MACRO extern "C"
|
||||
#else
|
||||
#define __EXTERN_C_MACRO
|
||||
#endif
|
||||
@ -121,7 +135,7 @@ typedef struct wups_loader_hook_t {
|
||||
void on_fini_wut_malloc(){ \
|
||||
__fini_wut_malloc(); \
|
||||
} \
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_MALLOC,on_fini_wut_malloc); \
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_MALLOC,on_fini_wut_malloc)
|
||||
|
||||
#define WUPS_USE_WUT_DEVOPTAB() \
|
||||
__EXTERN_C_MACRO void __init_wut_devoptab(); \
|
||||
@ -133,7 +147,7 @@ typedef struct wups_loader_hook_t {
|
||||
void on_fini_wut_devoptab(){ \
|
||||
__fini_wut_devoptab(); \
|
||||
}\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB,on_fini_wut_devoptab);
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB,on_fini_wut_devoptab)
|
||||
|
||||
#define WUPS_USE_WUT_NEWLIB() \
|
||||
__EXTERN_C_MACRO void __init_wut_newlib(); \
|
||||
@ -145,8 +159,8 @@ typedef struct wups_loader_hook_t {
|
||||
void on_fini_wut_newlib(){ \
|
||||
__fini_wut_newlib(); \
|
||||
}\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_NEWLIB,on_fini_wut_newlib);
|
||||
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_NEWLIB,on_fini_wut_newlib)
|
||||
|
||||
#define WUPS_USE_WUT_STDCPP() \
|
||||
__EXTERN_C_MACRO void __init_wut_stdcpp(); \
|
||||
void on_init_wut_stdcpp(){ \
|
||||
@ -157,7 +171,7 @@ typedef struct wups_loader_hook_t {
|
||||
void on_fini_wut_stdcpp(){ \
|
||||
__fini_wut_stdcpp(); \
|
||||
}\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_STDCPP,on_fini_wut_stdcpp);
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_STDCPP,on_fini_wut_stdcpp)
|
||||
|
||||
#define WUPS_USE_WUT_SOCKETS() \
|
||||
__EXTERN_C_MACRO void __attribute__((weak)) __init_wut_socket(); \
|
||||
@ -169,10 +183,8 @@ typedef struct wups_loader_hook_t {
|
||||
void on_fini_wut_sockets(){ \
|
||||
if (&__fini_wut_socket) __fini_wut_socket(); \
|
||||
}\
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_SOCKETS,on_fini_wut_sockets);
|
||||
|
||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_SOCKETS,on_fini_wut_sockets)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WUPS_WUPS_H_ */
|
||||
|
@ -23,8 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WUPS_META_DEF_H_
|
||||
#define WUPS_META_DEF_H_
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "hooks.h"
|
||||
@ -33,16 +32,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WUPS_PLUGIN_NAME(x) WUPS_META(name, x); WUPS_META(wups, "0.5"); WUPS_USE_WUT_MALLOC() WUPS_USE_WUT_SOCKETS() WUPS_USE_WUT_NEWLIB() WUPS_USE_WUT_STDCPP() WUPS_META(buildtimestamp, __DATE__ " " __TIME__);
|
||||
#define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x)
|
||||
#define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x)
|
||||
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
|
||||
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
|
||||
#define WUPS_PLUGIN_ID(x) WUPS_META(id, x)
|
||||
#define WUPS_PLUGIN_CONFIG_REVISION(x) WUPS_META(config_revision, #x)
|
||||
#define WUPS_PLUGIN_NAME(x) WUPS_META(name, x); \
|
||||
WUPS_META(wups, "0.6"); \
|
||||
WUPS_USE_WUT_MALLOC(); \
|
||||
WUPS_USE_WUT_SOCKETS(); \
|
||||
WUPS_USE_WUT_NEWLIB(); \
|
||||
WUPS_USE_WUT_STDCPP(); \
|
||||
WUPS_META(buildtimestamp, __DATE__ " " __TIME__);
|
||||
|
||||
#define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x)
|
||||
#define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x)
|
||||
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
|
||||
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
|
||||
#define WUPS_PLUGIN_ID(x) WUPS_META(id, x)
|
||||
#define WUPS_PLUGIN_CONFIG_REVISION(x) WUPS_META(config_revision, #x)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WUPS_COMMON_DEF_H_ */
|
||||
|
79
include/wups/storage.h
Normal file
79
include/wups/storage.h
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum wups_storage_type_t_ {
|
||||
WUPS_STORAGE_TYPE_INVALID,
|
||||
WUPS_STORAGE_TYPE_STRING,
|
||||
WUPS_STORAGE_TYPE_INT,
|
||||
WUPS_STORAGE_TYPE_ITEM,
|
||||
} wups_storage_type_t;
|
||||
|
||||
enum {
|
||||
WUPS_STORAGE_ERROR_SUCCESS = 0,
|
||||
WUPS_STORAGE_ERROR_NOT_OPENED = -1,
|
||||
WUPS_STORAGE_ERROR_ALREADY_OPENED = -2,
|
||||
WUPS_STORAGE_ERROR_INVALID_ARGS = -3,
|
||||
WUPS_STORAGE_ERROR_NOT_FOUND = -4,
|
||||
WUPS_STORAGE_ERROR_NOT_INITIALIZED = -5,
|
||||
WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS = -6,
|
||||
WUPS_STORAGE_ERROR_INVALID_JSON = -7,
|
||||
WUPS_STORAGE_ERROR_IO = -8,
|
||||
WUPS_STORAGE_ERROR_B64_DECODE_FAILED = -9,
|
||||
WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL = -10,
|
||||
};
|
||||
|
||||
typedef struct wups_storage_item_t_ {
|
||||
char *key;
|
||||
void *data;
|
||||
uint32_t data_size;
|
||||
uint32_t pending_delete;
|
||||
wups_storage_type_t type;
|
||||
} wups_storage_item_t;
|
||||
|
||||
typedef int32_t (*OpenStorageFunction)(const char *plugin_id, wups_storage_item_t *items);
|
||||
typedef int32_t (*CloseStorageFunction)(const char *plugin_id, wups_storage_item_t *items);
|
||||
|
||||
typedef struct wups_loader_init_storage_args_t_ {
|
||||
OpenStorageFunction open_storage_ptr;
|
||||
CloseStorageFunction close_storage_ptr;
|
||||
const char *plugin_id;
|
||||
} wups_loader_init_storage_args_t;
|
||||
|
||||
/* called by backend */
|
||||
void WUPS_InitStorage(wups_loader_init_storage_args_t args);
|
||||
|
||||
/* opens storage for reading and writing */
|
||||
int32_t WUPS_OpenStorage(void);
|
||||
|
||||
/* closes storage and saves changes */
|
||||
int32_t WUPS_CloseStorage(void);
|
||||
|
||||
/* deletes key from storage */
|
||||
int32_t WUPS_DeleteItem(wups_storage_item_t *parent, const char *key);
|
||||
|
||||
/* returns the size of key on success, or an error code */
|
||||
// TODO do we need this? what about binary data?
|
||||
// int32_t WUPS_GetSize(const char* key);
|
||||
|
||||
int32_t WUPS_CreateSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem);
|
||||
int32_t WUPS_GetSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem);
|
||||
|
||||
int32_t WUPS_StoreString(wups_storage_item_t *parent, const char *key, const char *string);
|
||||
int32_t WUPS_StoreBool(wups_storage_item_t *parent, const char *key, bool value);
|
||||
int32_t WUPS_StoreInt(wups_storage_item_t *parent, const char *key, int32_t value);
|
||||
int32_t WUPS_StoreBinary(wups_storage_item_t *parent, const char *key, const void *data, uint32_t size);
|
||||
|
||||
int32_t WUPS_GetString(wups_storage_item_t *parent, const char *key, char *outString, uint32_t maxSize);
|
||||
int32_t WUPS_GetBool(wups_storage_item_t *parent, const char *key, bool *outBool);
|
||||
int32_t WUPS_GetInt(wups_storage_item_t *parent, const char *key, int32_t *outInt);
|
||||
int32_t WUPS_GetBinary(wups_storage_item_t *parent, const char *key, void *outData, uint32_t maxSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
106
libraries/libwups/WUPSConfigItemBoolean.cpp
Normal file
106
libraries/libwups/WUPSConfigItemBoolean.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include <wups.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "wups/config/WUPSConfigItemBoolean.h"
|
||||
|
||||
void WUPSConfigItemBoolean_onDelete(void *context);
|
||||
|
||||
int32_t WUPSConfigItemBoolean_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
snprintf(out_buf, out_size, " %s", item->value ? item->trueValue : item->falseValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void toggleValue(ConfigItemBoolean *item) {
|
||||
item->value = !item->value;
|
||||
}
|
||||
|
||||
bool WUPSConfigItemBoolean_callCallback(void *context) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
if (item->callback != nullptr) {
|
||||
((BooleanValueChangedCallback) (item->callback))(item, item->value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WUPSConfigItemBoolean_onButtonPressed(void *context, WUPSConfigButtons buttons) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) {
|
||||
toggleValue(item);
|
||||
} else if (buttons & WUPS_CONFIG_BUTTON_LEFT && !item->value) {
|
||||
toggleValue(item);
|
||||
} else if ((buttons & WUPS_CONFIG_BUTTON_RIGHT) && item->value) {
|
||||
toggleValue(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool WUPSConfigItemBoolean_isMovementAllowed(void *context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t WUPSConfigItemBoolean_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
if (item->value) {
|
||||
snprintf(out_buf, out_size, " %s >", item->trueValue);
|
||||
} else {
|
||||
snprintf(out_buf, out_size, "< %s ", item->falseValue);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WUPSConfigItemBoolean_restoreDefault(void *context) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
item->value = item->defaultValue;
|
||||
}
|
||||
|
||||
void WUPSConfigItemBoolean_onSelected(void *context, bool isSelected) {
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback, const char *trueValue,
|
||||
const char *falseValue) {
|
||||
if (cat == 0) {
|
||||
return false;
|
||||
}
|
||||
auto *item = (ConfigItemBoolean *) malloc(sizeof(ConfigItemBoolean));
|
||||
if (item == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
item->defaultValue = defaultValue;
|
||||
item->value = defaultValue;
|
||||
item->callback = (void *) callback;
|
||||
snprintf(item->trueValue, sizeof(item->trueValue), "%s", trueValue);
|
||||
snprintf(item->falseValue, sizeof(item->falseValue), "%s", falseValue);
|
||||
|
||||
WUPSConfigCallbacks_t callbacks = {
|
||||
.getCurrentValueDisplay = &WUPSConfigItemBoolean_getCurrentValueDisplay,
|
||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemBoolean_getCurrentValueSelectedDisplay,
|
||||
.onSelected = &WUPSConfigItemBoolean_onSelected,
|
||||
.restoreDefault = &WUPSConfigItemBoolean_restoreDefault,
|
||||
.isMovementAllowed = &WUPSConfigItemBoolean_isMovementAllowed,
|
||||
.callCallback = &WUPSConfigItemBoolean_callCallback,
|
||||
.onButtonPressed = &WUPSConfigItemBoolean_onButtonPressed,
|
||||
.onDelete = &WUPSConfigItemBoolean_onDelete
|
||||
};
|
||||
|
||||
if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) {
|
||||
free(item);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WUPSConfigItemBoolean_onDelete(void *context) {
|
||||
auto *item = (ConfigItemBoolean *) context;
|
||||
free(item);
|
||||
}
|
||||
|
||||
extern "C" bool WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback) {
|
||||
return WUPSConfigItemBoolean_AddToCategoryEx(cat, configID, displayName, defaultValue, callback, "true", "false");
|
||||
}
|
106
libraries/libwups/WUPSConfigItemIntegerRange.cpp
Normal file
106
libraries/libwups/WUPSConfigItemIntegerRange.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include <wups.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "wups/config/WUPSConfigItemIntegerRange.h"
|
||||
|
||||
int32_t WUPSConfigItemIntegerRange_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
snprintf(out_buf, out_size, "%d", item->value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WUPSConfigItemIntegerRange_callCallback(void *context) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
if (item->callback != nullptr) {
|
||||
((IntegerRangeValueChangedCallback) item->callback)(item, item->value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WUPSConfigItemIntegerRange_onButtonPressed(void *context, WUPSConfigButtons buttons) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
if (buttons & WUPS_CONFIG_BUTTON_LEFT) {
|
||||
item->value--;
|
||||
} else if ((buttons & WUPS_CONFIG_BUTTON_RIGHT)) {
|
||||
item->value++;
|
||||
} else if ((buttons & WUPS_CONFIG_BUTTON_L)) {
|
||||
item->value = item->value - 50;
|
||||
} else if ((buttons & WUPS_CONFIG_BUTTON_R)) {
|
||||
item->value = item->value + 50;
|
||||
}
|
||||
|
||||
if (item->value < item->minValue) {
|
||||
item->value = item->minValue;
|
||||
} else if (item->value > item->maxValue) {
|
||||
item->value = item->maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
bool WUPSConfigItemIntegerRange_isMovementAllowed(void *context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
if (item->value == item->minValue) {
|
||||
snprintf(out_buf, out_size, " %d >", item->value);
|
||||
} else if (item->value == item->maxValue) {
|
||||
snprintf(out_buf, out_size, "< %d ", item->value);
|
||||
} else {
|
||||
snprintf(out_buf, out_size, "< %d >", item->value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WUPSConfigItemIntegerRange_restoreDefault(void *context) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
item->value = item->defaultValue;
|
||||
}
|
||||
|
||||
void WUPSConfigItemIntegerRange_onDelete(void *context) {
|
||||
auto *item = (ConfigItemIntegerRange *) context;
|
||||
free(item);
|
||||
}
|
||||
|
||||
void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) {
|
||||
|
||||
}
|
||||
|
||||
extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, int32_t defaultValue, int32_t minValue, int32_t maxValue,
|
||||
IntegerRangeValueChangedCallback callback) {
|
||||
if (cat == 0) {
|
||||
return false;
|
||||
}
|
||||
auto *item = (ConfigItemIntegerRange *) malloc(sizeof(ConfigItemIntegerRange));
|
||||
if (item == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
item->defaultValue = defaultValue;
|
||||
item->value = defaultValue;
|
||||
item->minValue = minValue;
|
||||
item->maxValue = maxValue;
|
||||
item->callback = (void *) callback;
|
||||
|
||||
WUPSConfigCallbacks_t callbacks = {
|
||||
.getCurrentValueDisplay = &WUPSConfigItemIntegerRange_getCurrentValueDisplay,
|
||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay,
|
||||
.onSelected = &WUPSConfigItemIntegerRange_onSelected,
|
||||
.restoreDefault = &WUPSConfigItemIntegerRange_restoreDefault,
|
||||
.isMovementAllowed = &WUPSConfigItemIntegerRange_isMovementAllowed,
|
||||
.callCallback = &WUPSConfigItemIntegerRange_callCallback,
|
||||
.onButtonPressed = &WUPSConfigItemIntegerRange_onButtonPressed,
|
||||
.onDelete = &WUPSConfigItemIntegerRange_onDelete
|
||||
};
|
||||
|
||||
if (WUPSConfigItem_Create(&(item->handle), configID, displayName, callbacks, item) < 0) {
|
||||
free(item);
|
||||
return false;
|
||||
};
|
||||
|
||||
if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
147
libraries/libwups/WUPSConfigItemMultipleValues.cpp
Normal file
147
libraries/libwups/WUPSConfigItemMultipleValues.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include <wups.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "wups/config/WUPSConfigItemMultipleValues.h"
|
||||
|
||||
void WUPSConfigItemMultipleValues_onDelete(void *context);
|
||||
|
||||
int32_t WUPSConfigItemMultipleValues_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
|
||||
if (item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) {
|
||||
if (item->values[item->valueIndex].valueName == nullptr) {
|
||||
return -2;
|
||||
}
|
||||
strncpy(out_buf, item->values[item->valueIndex].valueName, out_size);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool WUPSConfigItemMultipleValues_callCallback(void *context) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
if (item->callback != nullptr && item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) {
|
||||
((MultipleValuesChangedCallback) (item->callback))(item, item->values[item->valueIndex].value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WUPSConfigItemMultipleValues_onButtonPressed(void *context, WUPSConfigButtons buttons) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
if (buttons & WUPS_CONFIG_BUTTON_LEFT) {
|
||||
item->valueIndex--;
|
||||
} else if (buttons & WUPS_CONFIG_BUTTON_RIGHT) {
|
||||
item->valueIndex++;
|
||||
}
|
||||
if (item->valueIndex < 0) {
|
||||
item->valueIndex = 0;
|
||||
} else if (item->valueIndex >= item->valueCount) {
|
||||
item->valueIndex = item->valueCount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool WUPSConfigItemMultipleValues_isMovementAllowed(void *context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
if (item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) {
|
||||
if (item->valueCount == 1) {
|
||||
snprintf(out_buf, out_size, " %s ", item->values[item->valueIndex].valueName);
|
||||
} else if (item->valueIndex == 0) {
|
||||
snprintf(out_buf, out_size, " %s >", item->values[item->valueIndex].valueName);
|
||||
} else if (item->valueIndex + 1 == item->valueCount) {
|
||||
snprintf(out_buf, out_size, "< %s ", item->values[item->valueIndex].valueName);
|
||||
} else {
|
||||
snprintf(out_buf, out_size, "< %s >", item->values[item->valueIndex].valueName);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WUPSConfigItemMultipleValues_restoreDefault(void *context) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
item->valueIndex = item->defaultValueIndex;
|
||||
}
|
||||
|
||||
void WUPSConfigItemMultipleValues_onSelected(void *context, bool isSelected) {
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName,
|
||||
int32_t defaultValueIndex, ConfigItemMultipleValuesPair *possibleValues,
|
||||
int pairCount, MultipleValuesChangedCallback callback) {
|
||||
if (cat == 0 || displayName == nullptr || possibleValues == nullptr || pairCount < 0) {
|
||||
return false;
|
||||
}
|
||||
auto *item = (ConfigItemMultipleValues *) malloc(sizeof(ConfigItemMultipleValues));
|
||||
if (item == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *values = (ConfigItemMultipleValuesPair *) malloc(sizeof(ConfigItemMultipleValuesPair) * pairCount);
|
||||
|
||||
for (int i = 0; i < pairCount; ++i) {
|
||||
values[i].value = possibleValues[i].value;
|
||||
if (possibleValues[i].valueName == nullptr) {
|
||||
values[i].valueName = nullptr;
|
||||
continue;
|
||||
}
|
||||
auto bufLen = strlen(possibleValues[i].valueName) + 1;
|
||||
values[i].valueName = (char *) malloc(bufLen);
|
||||
strncpy(values[i].valueName, possibleValues[i].valueName, bufLen);
|
||||
}
|
||||
|
||||
item->valueCount = pairCount;
|
||||
item->values = values;
|
||||
item->valueIndex = defaultValueIndex;
|
||||
item->defaultValueIndex = defaultValueIndex;
|
||||
item->callback = (void *) callback;
|
||||
|
||||
if (configID != nullptr) {
|
||||
auto configIDLen = strlen(configID) + 1;
|
||||
item->configID = (char *) malloc(configIDLen);
|
||||
strncpy(item->configID, configID, configIDLen);
|
||||
} else {
|
||||
item->configID = nullptr;
|
||||
}
|
||||
|
||||
WUPSConfigCallbacks_t callbacks = {
|
||||
.getCurrentValueDisplay = &WUPSConfigItemMultipleValues_getCurrentValueDisplay,
|
||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay,
|
||||
.onSelected = &WUPSConfigItemMultipleValues_onSelected,
|
||||
.restoreDefault = &WUPSConfigItemMultipleValues_restoreDefault,
|
||||
.isMovementAllowed = &WUPSConfigItemMultipleValues_isMovementAllowed,
|
||||
.callCallback = &WUPSConfigItemMultipleValues_callCallback,
|
||||
.onButtonPressed = &WUPSConfigItemMultipleValues_onButtonPressed,
|
||||
.onDelete = &WUPSConfigItemMultipleValues_onDelete
|
||||
};
|
||||
|
||||
if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) {
|
||||
free(item);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WUPSConfigItemMultipleValues_onDelete(void *context) {
|
||||
auto *item = (ConfigItemMultipleValues *) context;
|
||||
|
||||
for (int i = 0; i < item->valueCount; ++i) {
|
||||
free(item->values[i].valueName);
|
||||
}
|
||||
|
||||
free(item->configID);
|
||||
free(item->values);
|
||||
|
||||
free(item);
|
||||
}
|
19
libraries/libwups/config.def
Normal file
19
libraries/libwups/config.def
Normal file
@ -0,0 +1,19 @@
|
||||
:NAME homebrew_wupsbackend
|
||||
|
||||
:TEXT
|
||||
WUPSConfigItem_Create
|
||||
WUPSConfigItem_SetDisplayName
|
||||
WUPSConfigItem_GetDisplayName
|
||||
WUPSConfigItem_SetConfigID
|
||||
WUPSConfigItem_GetConfigID
|
||||
|
||||
WUPSConfig_Create
|
||||
WUPSConfig_Destroy
|
||||
WUPSConfig_GetName
|
||||
WUPSConfig_AddCategoryByName
|
||||
WUPSConfig_AddCategory
|
||||
|
||||
WUPSConfigCategory_Create
|
||||
WUPSConfigCategory_Destroy
|
||||
WUPSConfigCategory_GetName
|
||||
WUPSConfigCategory_AddItem
|
@ -1,10 +1,11 @@
|
||||
extern "C" void OSFatal(const char *msg);
|
||||
|
||||
extern "C" void __wups_start(){
|
||||
extern "C" void __wups_start() {
|
||||
OSFatal("This file needs to be run with the Wii U Plugin System.");
|
||||
}
|
||||
|
||||
extern __attribute__((weak)) void __wut_socket_init_devoptab();
|
||||
|
||||
extern __attribute__((weak)) void __wut_socket_fini_devoptab();
|
||||
|
||||
static int __wut_socket_devoptab_added = 0;
|
||||
@ -12,7 +13,7 @@ static int __wut_socket_devoptab_added = 0;
|
||||
extern void socket_lib_init();
|
||||
|
||||
void __attribute__((weak)) __init_wut_socket() {
|
||||
if(!&__wut_socket_init_devoptab) return;
|
||||
if (!&__wut_socket_init_devoptab) return;
|
||||
if (!__wut_socket_devoptab_added) {
|
||||
socket_lib_init();
|
||||
__wut_socket_init_devoptab();
|
||||
@ -21,7 +22,7 @@ void __attribute__((weak)) __init_wut_socket() {
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __fini_wut_socket() {
|
||||
if(!&__wut_socket_init_devoptab || !&__wut_socket_fini_devoptab) return;
|
||||
if (!&__wut_socket_init_devoptab || !&__wut_socket_fini_devoptab) return;
|
||||
if (__wut_socket_devoptab_added) {
|
||||
__wut_socket_fini_devoptab();
|
||||
__wut_socket_devoptab_added = 0;
|
||||
|
452
libraries/libwups/storage.cpp
Normal file
452
libraries/libwups/storage.cpp
Normal file
@ -0,0 +1,452 @@
|
||||
#include <wups.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "utils/base64.h"
|
||||
|
||||
static OpenStorageFunction openfunction_ptr __attribute__((section(".data"))) = nullptr;
|
||||
static CloseStorageFunction closefunction_ptr __attribute__((section(".data"))) = nullptr;
|
||||
static const char *plugin_id __attribute__((section(".data"))) = nullptr;
|
||||
|
||||
static uint32_t storage_initialized __attribute__((section(".data"))) = false;
|
||||
static uint32_t isOpened __attribute__((section(".data")));
|
||||
static uint32_t isDirty __attribute__((section(".data")));
|
||||
static wups_storage_item_t rootItem __attribute__((section(".data")));
|
||||
|
||||
void WUPS_InitStorage(wups_loader_init_storage_args_t args) {
|
||||
openfunction_ptr = args.open_storage_ptr;
|
||||
closefunction_ptr = args.close_storage_ptr;
|
||||
plugin_id = args.plugin_id;
|
||||
|
||||
storage_initialized = true;
|
||||
isOpened = false;
|
||||
isDirty = false;
|
||||
|
||||
rootItem.key = nullptr;
|
||||
rootItem.data = nullptr;
|
||||
rootItem.data_size = 0;
|
||||
rootItem.pending_delete = false;
|
||||
rootItem.type = WUPS_STORAGE_TYPE_ITEM;
|
||||
}
|
||||
|
||||
int32_t WUPS_OpenStorage(void) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (isOpened) {
|
||||
return WUPS_STORAGE_ERROR_ALREADY_OPENED;
|
||||
}
|
||||
|
||||
int32_t result = openfunction_ptr(plugin_id, &rootItem);
|
||||
|
||||
if (result == WUPS_STORAGE_ERROR_SUCCESS || result == WUPS_STORAGE_ERROR_INVALID_JSON) {
|
||||
isOpened = true;
|
||||
isDirty = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void closeItem(wups_storage_item_t *item) {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *items = (wups_storage_item_t *) item->data;
|
||||
|
||||
for (uint32_t i = 0; i < item->data_size; i++) {
|
||||
if (items[i].type == WUPS_STORAGE_TYPE_ITEM) {
|
||||
closeItem(&items[i]);
|
||||
}
|
||||
free(items[i].data);
|
||||
free(items[i].key);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t WUPS_CloseStorage(void) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
int32_t result = 0;
|
||||
if (isDirty) {
|
||||
result = closefunction_ptr(plugin_id, &rootItem);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
isOpened = false;
|
||||
isDirty = false;
|
||||
|
||||
closeItem(&rootItem);
|
||||
free(rootItem.data);
|
||||
rootItem.data_size = 0;
|
||||
rootItem.data = nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t WUPS_DeleteItem(wups_storage_item_t *parent, const char *key) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
isDirty = true;
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (item->pending_delete || item->type == WUPS_STORAGE_TYPE_INVALID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
item->pending_delete = true;
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// int32_t WUPS_GetSize(const char* key) {
|
||||
// if (!storage_initialized) {
|
||||
// return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
// }
|
||||
|
||||
// if (!isOpened) {
|
||||
// return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
// }
|
||||
|
||||
// for (uint32_t i = 0; i < amount_of_items; i++) {
|
||||
// wups_loader_storage_item_t* item = &items[i];
|
||||
|
||||
// if (item->pending_delete || item->type == WUPS_STORAGE_TYPE_INVALID) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (strcmp(item->key, key) == 0) {
|
||||
// return item->data_size;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
// }
|
||||
|
||||
static wups_storage_item_t *addItem(wups_storage_item_t *parent, const char *key, wups_storage_type_t type) {
|
||||
wups_storage_item_t *foundItem = nullptr;
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
free(item->data);
|
||||
foundItem = item;
|
||||
break;
|
||||
}
|
||||
|
||||
if (item->pending_delete) {
|
||||
free(item->data);
|
||||
free(item->key);
|
||||
|
||||
item->key = (char *) malloc(strlen(key) + 1);
|
||||
strcpy(item->key, key);
|
||||
|
||||
foundItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundItem) {
|
||||
parent->data_size++;
|
||||
parent->data = (wups_storage_item_t *) realloc(parent->data, parent->data_size * sizeof(wups_storage_item_t));
|
||||
|
||||
foundItem = &((wups_storage_item_t *) parent->data)[parent->data_size - 1];
|
||||
|
||||
foundItem->key = (char *) malloc(strlen(key) + 1);
|
||||
strcpy(foundItem->key, key);
|
||||
}
|
||||
|
||||
foundItem->type = type;
|
||||
foundItem->pending_delete = false;
|
||||
foundItem->data = nullptr;
|
||||
foundItem->data_size = 0;
|
||||
return foundItem;
|
||||
}
|
||||
|
||||
int32_t WUPS_CreateSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !outItem) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
isDirty = true;
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_ITEM);
|
||||
|
||||
*outItem = item;
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t WUPS_GetSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || outItem == nullptr) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (item->pending_delete || item->type != WUPS_STORAGE_TYPE_ITEM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
*outItem = item;
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int32_t WUPS_StoreString(wups_storage_item_t *parent, const char *key, const char *string) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !string) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
isDirty = true;
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING);
|
||||
|
||||
uint32_t size = strlen(string) + 1;
|
||||
item->data = malloc(size);
|
||||
item->data_size = size;
|
||||
strcpy((char *) item->data, string);
|
||||
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t WUPS_StoreBool(wups_storage_item_t *parent, const char *key, bool value) {
|
||||
return WUPS_StoreInt(parent, key, (int32_t) value);
|
||||
}
|
||||
|
||||
int32_t WUPS_StoreInt(wups_storage_item_t *parent, const char *key, int32_t value) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
isDirty = true;
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_INT);
|
||||
|
||||
item->data = malloc(sizeof(int32_t));
|
||||
item->data_size = sizeof(int32_t);
|
||||
*(int32_t *) item->data = value;
|
||||
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t WUPS_StoreBinary(wups_storage_item_t *parent, const char *key, const void *data, uint32_t size) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !data || size == 0) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING);
|
||||
|
||||
item->data = b64_encode((const uint8_t *) data, size);
|
||||
item->data_size = strlen((char *) data) + 1;
|
||||
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t WUPS_GetString(wups_storage_item_t *parent, const char *key, char *outString, uint32_t maxSize) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !outString || maxSize == 0) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (item->pending_delete || item->type != WUPS_STORAGE_TYPE_STRING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
strncpy(outString, (char *) item->data, maxSize);
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int32_t WUPS_GetBool(wups_storage_item_t *parent, const char *key, bool *outBool) {
|
||||
int32_t out;
|
||||
int32_t result = WUPS_GetInt(parent, key, &out);
|
||||
if (result != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
*outBool = out != 0;
|
||||
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t WUPS_GetInt(wups_storage_item_t *parent, const char *key, int32_t *outInt) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !outInt) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (item->pending_delete || item->type != WUPS_STORAGE_TYPE_INT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
*outInt = *(int32_t *) item->data;
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int32_t WUPS_GetBinary(wups_storage_item_t *parent, const char *key, void *outData, uint32_t maxSize) {
|
||||
if (!storage_initialized) {
|
||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!isOpened) {
|
||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!key || !outData || maxSize == 0) {
|
||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
parent = &rootItem;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
||||
|
||||
if (item->pending_delete || item->type != WUPS_STORAGE_TYPE_STRING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(item->key, key) == 0) {
|
||||
if (b64_decoded_size((char *) item->data) > maxSize) {
|
||||
return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (b64_decode((char *) item->data, (uint8_t *) outData, item->data_size)) {
|
||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||
} else {
|
||||
return WUPS_STORAGE_ERROR_B64_DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||
}
|
128
libraries/libwups/utils/base64.cpp
Normal file
128
libraries/libwups/utils/base64.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "base64.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
size_t b64_encoded_size(size_t inlen) {
|
||||
size_t ret;
|
||||
|
||||
ret = inlen;
|
||||
if (inlen % 3 != 0)
|
||||
ret += 3 - (inlen % 3);
|
||||
ret /= 3;
|
||||
ret *= 4;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *b64_encode(const uint8_t *in, size_t len) {
|
||||
char *out;
|
||||
size_t elen;
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t v;
|
||||
|
||||
if (in == NULL || len == 0)
|
||||
return NULL;
|
||||
|
||||
elen = b64_encoded_size(len);
|
||||
out = (char *) malloc(elen + 1);
|
||||
out[elen] = '\0';
|
||||
|
||||
for (i = 0, j = 0; i < len; i += 3, j += 4) {
|
||||
v = in[i];
|
||||
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
|
||||
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
|
||||
|
||||
out[j] = b64chars[(v >> 18) & 0x3F];
|
||||
out[j + 1] = b64chars[(v >> 12) & 0x3F];
|
||||
if (i + 1 < len) {
|
||||
out[j + 2] = b64chars[(v >> 6) & 0x3F];
|
||||
} else {
|
||||
out[j + 2] = '=';
|
||||
}
|
||||
if (i + 2 < len) {
|
||||
out[j + 3] = b64chars[v & 0x3F];
|
||||
} else {
|
||||
out[j + 3] = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
size_t b64_decoded_size(const char *in) {
|
||||
size_t len;
|
||||
size_t ret;
|
||||
size_t i;
|
||||
|
||||
if (in == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(in);
|
||||
ret = len / 4 * 3;
|
||||
|
||||
for (i = len; i-- > 0;) {
|
||||
if (in[i] == '=') {
|
||||
ret--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const int b64invs[] = {
|
||||
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
|
||||
static int b64_isvalidchar(char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return 1;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return 1;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return 1;
|
||||
if (c == '+' || c == '/' || c == '=')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int b64_decode(const char *in, uint8_t *out, size_t outlen) {
|
||||
size_t len;
|
||||
size_t i;
|
||||
size_t j;
|
||||
int v;
|
||||
|
||||
if (in == NULL || out == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(in);
|
||||
if (outlen < b64_decoded_size(in) || len % 4 != 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!b64_isvalidchar(in[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < len; i += 4, j += 3) {
|
||||
v = b64invs[in[i] - 43];
|
||||
v = (v << 6) | b64invs[in[i + 1] - 43];
|
||||
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43];
|
||||
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43];
|
||||
|
||||
out[j] = (v >> 16) & 0xFF;
|
||||
if (in[i + 2] != '=')
|
||||
out[j + 1] = (v >> 8) & 0xFF;
|
||||
if (in[i + 3] != '=')
|
||||
out[j + 2] = v & 0xFF;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
20
libraries/libwups/utils/base64.h
Normal file
20
libraries/libwups/utils/base64.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t b64_encoded_size(size_t inlen);
|
||||
char *b64_encode(const uint8_t *in, size_t len);
|
||||
|
||||
size_t b64_decoded_size(const char *in);
|
||||
int b64_decode(const char *in, uint8_t *out, size_t outlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -2,17 +2,18 @@
|
||||
#include <whb/libmanager.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <nsysnet/socket.h>
|
||||
#include <utils/logger.h>
|
||||
#include <coreinit/time.h>
|
||||
#include <coreinit/thread.h>
|
||||
#include <coreinit/filesystem.h>
|
||||
#include <whb/log_udp.h>
|
||||
#include <wups/config/WUPSConfigItemBoolean.h>
|
||||
|
||||
/**
|
||||
Mandatory plugin information.
|
||||
If not set correctly, the loader will refuse to use the plugin.
|
||||
**/
|
||||
WUPS_PLUGIN_ID("example_plugin");
|
||||
WUPS_PLUGIN_NAME("Example plugin");
|
||||
WUPS_PLUGIN_DESCRIPTION("This is just an example plugin and will log the FSOpenFile function.");
|
||||
WUPS_PLUGIN_VERSION("v1.0");
|
||||
@ -25,7 +26,10 @@ WUPS_PLUGIN_LICENSE("BSD");
|
||||
|
||||
**/
|
||||
|
||||
WUPS_USE_WUT_DEVOPTAB() // Use the wut devoptabs
|
||||
WUPS_USE_WUT_DEVOPTAB(); // Use the wut devoptabs
|
||||
WUPS_USE_STORAGE(); // Use the storage API
|
||||
|
||||
bool logFSOpen = true;
|
||||
|
||||
/**
|
||||
Get's called ONCE when the loader exits, but BEFORE the ON_APPLICATION_START gets called or functions are overridden.
|
||||
@ -33,6 +37,18 @@ WUPS_USE_WUT_DEVOPTAB() // Use the wut devoptabs
|
||||
INITIALIZE_PLUGIN(){
|
||||
WHBLogUdpInit();
|
||||
DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!");
|
||||
|
||||
// Open storage to read values
|
||||
WUPS_OpenStorage();
|
||||
|
||||
// Try to get value from storage
|
||||
if(WUPS_GetBool(nullptr, "logFSOpen", &logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS){
|
||||
// Add the value to the storage if it's missing.
|
||||
WUPS_StoreBool(nullptr, "logFSOpen", logFSOpen);
|
||||
}
|
||||
|
||||
// Close storage
|
||||
WUPS_CloseStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,6 +77,33 @@ ON_APPLICATION_REQUESTS_EXIT(){
|
||||
DEBUG_FUNCTION_LINE("ON_APPLICATION_REQUESTS_EXIT of example_plugin!");
|
||||
}
|
||||
|
||||
void logFSOpenChanged(ConfigItemBoolean *item, bool newValue) {
|
||||
DEBUG_FUNCTION_LINE("New value in logFSOpenChanged: %d", newValue);
|
||||
logFSOpen = newValue;
|
||||
// If the value has changed, we store it in the storage.
|
||||
WUPS_StoreInt(nullptr, "logFSOpen", logFSOpen);
|
||||
}
|
||||
|
||||
WUPS_GET_CONFIG() {
|
||||
// We open the storage so we can persist the configuration the user did.
|
||||
WUPS_OpenStorage();
|
||||
|
||||
WUPSConfigHandle config;
|
||||
WUPSConfig_CreateHandled(&config, "Example Plugin");
|
||||
|
||||
WUPSConfigCategoryHandle cat;
|
||||
WUPSConfig_AddCategoryByNameHandled(config, "Logging", &cat);
|
||||
|
||||
WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, "logFSOpen", "Log FSOpen calls", logFSOpen, &logFSOpenChanged);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
WUPS_CONFIG_CLOSED() {
|
||||
// Save all changes
|
||||
WUPS_CloseStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
This defines a function replacement.
|
||||
It allows to replace the system function with an own function.
|
||||
@ -91,8 +134,9 @@ ON_APPLICATION_REQUESTS_EXIT(){
|
||||
**/
|
||||
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
|
||||
int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
|
||||
|
||||
DEBUG_FUNCTION_LINE("FSOpenFile called for folder %s! Result %d\n",path,result);
|
||||
if (logFSOpen) {
|
||||
DEBUG_FUNCTION_LINE("FSOpenFile called for folder %s! Result %d",path,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,14 @@
|
||||
SECTIONS
|
||||
{
|
||||
.fimport_homebrew_wupsbackend ALIGN(16) : {
|
||||
KEEP ( *(.fimport_homebrew_wupsbackend) )
|
||||
*(.fimport_homebrew_wupsbackend.*)
|
||||
} > loadmem
|
||||
.dimport_homebrew_wupsbackend ALIGN(16) : {
|
||||
KEEP ( *(.dimport_homebrew_wupsbackend) )
|
||||
*(.dimport_homebrew_wupsbackend.*)
|
||||
} > loadmem
|
||||
|
||||
.wups.meta : {
|
||||
*(.wups.meta*)
|
||||
KEEP(*(.wups.meta*))
|
||||
|
Loading…
x
Reference in New Issue
Block a user