mirror of
https://github.com/Maschell/WiiUPluginLoader.git
synced 2024-09-28 15:38:35 +02:00
Compare commits
26 Commits
WiiUPlugin
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
6fa1a45d68 | ||
|
0c0f9f36e2 | ||
|
2e51b9918d | ||
|
284912c3ea | ||
|
597e98d60a | ||
|
16fb3a7080 | ||
|
9442c5d62a | ||
|
8b0df7b6b8 | ||
|
81ce92aae7 | ||
|
c29e3e77cd | ||
|
e647925e50 | ||
|
492571207d | ||
|
fb71817c33 | ||
|
7ccc9e0b92 | ||
|
7f491da297 | ||
|
40bb31885a | ||
|
14d4ab0b5c | ||
|
2fc11412f3 | ||
|
64e4ed5f71 | ||
|
2c743ec133 | ||
|
9ed45f82de | ||
|
e6f246b947 | ||
|
993b328f4c | ||
|
ad759ff269 | ||
|
8eaf9cc026 | ||
|
6d8de35973 |
21
.travis.yml
21
.travis.yml
@ -1,23 +1,10 @@
|
|||||||
sudo: required
|
sudo: required
|
||||||
|
branches:
|
||||||
before_cache:
|
only:
|
||||||
# Save tagged docker images see https://github.com/travis-ci/travis-ci/issues/5358#issuecomment-248915326
|
- master
|
||||||
- >
|
|
||||||
mkdir -p $HOME/docker && docker images -a --filter='dangling=false' --format '{{.Repository}}:{{.Tag}} {{.ID}}'
|
|
||||||
| xargs -n 2 -t sh -c 'test -e $HOME/docker/$1.tar.gz || docker save $0 | gzip -2 > $HOME/docker/$1.tar.gz'
|
|
||||||
|
|
||||||
cache:
|
|
||||||
bundler: true
|
|
||||||
directories:
|
|
||||||
- $HOME/docker
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
before_install:
|
|
||||||
# Load cached docker images
|
|
||||||
- if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi
|
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
@ -54,5 +41,3 @@ deploy:
|
|||||||
file: WiiUPluginLoader_$versiontag.zip
|
file: WiiUPluginLoader_$versiontag.zip
|
||||||
on:
|
on:
|
||||||
repo: Maschell/WiiUPluginLoader
|
repo: Maschell/WiiUPluginLoader
|
||||||
tags: false
|
|
||||||
all_branches: true
|
|
@ -4,8 +4,8 @@ FROM wups/core:latest
|
|||||||
RUN rm -rf $DEVKITPRO/portlibs
|
RUN rm -rf $DEVKITPRO/portlibs
|
||||||
|
|
||||||
# Install devkitARM. Needed to build mocha.
|
# Install devkitARM. Needed to build mocha.
|
||||||
RUN yes | sudo dkp-pacman -Syu devkitARM --needed
|
|
||||||
ENV DEVKITARM=${DEVKITPRO}/devkitARM
|
ENV DEVKITARM=${DEVKITPRO}/devkitARM
|
||||||
|
COPY --from=devkitpro/devkitarm $DEVKITARM $DEVKITARM
|
||||||
|
|
||||||
# Get dependencies
|
# Get dependencies
|
||||||
COPY --from=wiiulegacy/dynamic_libs:0.1 /artifacts $DEVKITPRO/portlibs
|
COPY --from=wiiulegacy/dynamic_libs:0.1 /artifacts $DEVKITPRO/portlibs
|
||||||
|
2
Makefile
2
Makefile
@ -77,7 +77,7 @@ MAKEFLAGS += --no-print-directory
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -lgui -lm -lgcc -lfat -lntfs -liosuhax -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec
|
LIBS := -lgui -lm -lgcc -lfat -liosuhax -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec -logg -lbz2
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
[Nightly builds](https://github.com/Maschell/WiiUPluginLoader/releases) | [Issue Tracker](https://github.com/Maschell/WiiUPluginLoader/issues) | [Discussion](https://gbatemp.net/threads/wii-u-plugin-system.496659/) | [Discord](https://discord.gg/bZ2rep2) | [Wiki](https://maschell.github.io/WiiUPluginSystem/dev_overview.html)
|
# This project is outdated, new version is at: https://github.com/wiiu-env/WiiUPluginLoaderBackend
|
||||||
|
|
||||||
|
[Nightly builds](https://github.com/Maschell/WiiUPluginLoader/releases) | [Issue Tracker](https://github.com/Maschell/WiiUPluginLoader/issues) | [Discussion](https://gbatemp.net/threads/wii-u-plugin-system.496659/) | [Discord](https://discord.gg/bZ2rep2) | [Wiki](https://maschell.github.io/WiiUPluginSystem/dev_overview.html)
|
||||||
|
|
||||||
# Wii U Plugin Loader [![Build Status](https://api.travis-ci.org/Maschell/WiiUPluginLoader.svg?branch=master)](https://travis-ci.org/Maschell/WiiUPluginLoader)
|
# Wii U Plugin Loader [![Build Status](https://api.travis-ci.org/Maschell/WiiUPluginLoader.svg?branch=master)](https://travis-ci.org/Maschell/WiiUPluginLoader)
|
||||||
|
|
||||||
@ -33,10 +35,14 @@ This means it's not possible to combine this with other homebrews (yet).
|
|||||||
Information on how to create plugin can be found in the [wiki](https://maschell.github.io/WiiUPluginSystem/dev_plugin_creation_overview.html).
|
Information on how to create plugin can be found in the [wiki](https://maschell.github.io/WiiUPluginSystem/dev_plugin_creation_overview.html).
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
Make sure the toolchain is uptodate `pacman -Syu devkitPPC devkitARM vim general-tools`
|
||||||
|
|
||||||
For building you need:
|
For building you need:
|
||||||
|
- [libiosuhax](https://github.com/dimok789/libiosuhax) (Build WITHOUT the WUT flag set.)
|
||||||
|
- [libfat](https://github.com/Maschell/libfat/) (Build with `make wiiu-release && make wiiu-install`)
|
||||||
- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions.
|
- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions.
|
||||||
- [libutils](https://github.com/Maschell/libutils) for common functions.
|
- [libutils](https://github.com/Maschell/libutils) for common functions.
|
||||||
|
- [libgui](https://github.com/Maschell/libgui) for the gui elements.
|
||||||
|
|
||||||
Install them (in this order) according to their README's. Don't forget the dependencies of the libs itself.
|
Install them (in this order) according to their README's. Don't forget the dependencies of the libs itself.
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
#
|
#
|
||||||
7z x -y ./loader/libs/portlibs.zip -o${DEVKITPRO}
|
7z x -y ./libs/portlibs.zip -o${DEVKITPRO}
|
||||||
mkdir portlib_repos
|
mkdir portlib_repos
|
||||||
cd portlib_repos
|
cd portlib_repos
|
||||||
((git clone https://github.com/Maschell/dynamic_libs.git -b lib && (7z x -y ./dynamic_libs/libs/portlibs.zip -o${DEVKITPRO})) || (cd dynamic_libs && git pull))
|
((git clone https://github.com/Maschell/dynamic_libs.git -b lib && (7z x -y ./dynamic_libs/libs/portlibs.zip -o${DEVKITPRO})) || (cd dynamic_libs && git pull))
|
||||||
(git clone https://github.com/dimok789/libiosuhax.git || (cd libiosuhax && git pull))
|
(git clone https://github.com/dimok789/libiosuhax.git || (cd libiosuhax && git pull))
|
||||||
(git clone https://github.com/Maschell/libfat.git || (cd libfat && git pull))
|
(git clone https://github.com/Maschell/libfat.git || (cd libfat && git pull))
|
||||||
(git clone https://github.com/Maschell/libntfs-wiiu.git || (cd libntfs-wiiu && git pull))
|
|
||||||
(git clone https://github.com/Maschell/libutils.git || (cd libutils && git pull))
|
(git clone https://github.com/Maschell/libutils.git || (cd libutils && git pull))
|
||||||
((git clone https://github.com/Maschell/libgui.git && (7z x -y ./libgui/libs/portlibs.zip -o${DEVKITPRO})) || (cd libgui && git pull))
|
((git clone https://github.com/Maschell/libgui.git && (7z x -y ./libgui/libs/portlibs.zip -o${DEVKITPRO})) || (cd libgui && git pull))
|
||||||
(git clone https://github.com/Maschell/fs_wrapper.git || (cd fs_wrapper && git pull))
|
(git clone https://github.com/Maschell/fs_wrapper.git || (cd fs_wrapper && git pull))
|
||||||
@ -14,7 +13,6 @@ cd portlib_repos
|
|||||||
(cd dynamic_libs && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
(cd dynamic_libs && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
||||||
(cd libiosuhax && make -j8 && make install)
|
(cd libiosuhax && make -j8 && make install)
|
||||||
(cd libfat && make wiiu-release && make wiiu-install)
|
(cd libfat && make wiiu-release && make wiiu-install)
|
||||||
(cd libntfs-wiiu && make wiiu-install)
|
|
||||||
(cd libutils && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
(cd libutils && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
||||||
(cd libgui && ((make -j8 | grep -c "built ... ") && make install) || echo "no need for make install")
|
(cd libgui && ((make -j8 | grep -c "built ... ") && make install) || echo "no need for make install")
|
||||||
(cd fs_wrapper && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
(cd fs_wrapper && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
|
||||||
|
@ -187,7 +187,7 @@ void Application::executeThread(void) {
|
|||||||
bool result = linkPluginsCallback();
|
bool result = linkPluginsCallback();
|
||||||
if(!result) {
|
if(!result) {
|
||||||
// On linking errors return to the HBL.
|
// On linking errors return to the HBL.
|
||||||
#warning TODO: proper error handling when linking fails.
|
#warning TODO: proper error handling when linking fails.
|
||||||
exitCode = APPLICATION_CLOSE_MIIMAKER;
|
exitCode = APPLICATION_CLOSE_MIIMAKER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ replacement_data_t gbl_replacement_data __attribute__((section(".data")));
|
|||||||
dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data")));
|
dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data")));
|
||||||
|
|
||||||
uint8_t gAppStatus __attribute__((section(".data"))) = 0;
|
uint8_t gAppStatus __attribute__((section(".data"))) = 0;
|
||||||
|
bool g_NotInLoader __attribute__((section(".data"))) = false;
|
||||||
uint64_t gGameTitleID __attribute__((section(".data"))) = 0;
|
uint64_t gGameTitleID __attribute__((section(".data"))) = 0;
|
||||||
volatile uint8_t gSDInitDone __attribute__((section(".data"))) = 0;
|
volatile uint8_t gSDInitDone __attribute__((section(".data"))) = 0;
|
||||||
|
|
||||||
@ -16,3 +17,10 @@ struct buffer_store tv_store __attribute__((section(".data")));
|
|||||||
|
|
||||||
char gbl_common_data[0x20000] __attribute__((section(".data")));
|
char gbl_common_data[0x20000] __attribute__((section(".data")));
|
||||||
char * gbl_common_data_ptr __attribute__((section(".data"))) = gbl_common_data;
|
char * gbl_common_data_ptr __attribute__((section(".data"))) = gbl_common_data;
|
||||||
|
|
||||||
|
GX2ColorBuffer g_vid_main_cbuf __attribute__((section(".data")));
|
||||||
|
GX2Texture g_vid_drcTex __attribute__((section(".data")));
|
||||||
|
GX2Sampler g_vid_sampler __attribute__((section(".data")));
|
||||||
|
GX2Texture g_vid_tvTex __attribute__((section(".data")));
|
||||||
|
GX2ContextState* g_vid_ownContextState __attribute__((section(".data")));
|
||||||
|
GX2ContextState* g_vid_originalContextSave __attribute__((section(".data")))= NULL;
|
||||||
|
@ -2,10 +2,14 @@
|
|||||||
#define RETAINS_VARS_H_
|
#define RETAINS_VARS_H_
|
||||||
#include "patcher/function_patcher.h"
|
#include "patcher/function_patcher.h"
|
||||||
#include "plugin/dynamic_linking_defines.h"
|
#include "plugin/dynamic_linking_defines.h"
|
||||||
|
#include <dynamic_libs/gx2_functions.h>
|
||||||
|
|
||||||
extern replacement_data_t gbl_replacement_data;
|
extern replacement_data_t gbl_replacement_data;
|
||||||
extern dyn_linking_relocation_data_t gbl_dyn_linking_data;
|
extern dyn_linking_relocation_data_t gbl_dyn_linking_data;
|
||||||
|
|
||||||
|
|
||||||
|
extern bool g_NotInLoader;
|
||||||
|
|
||||||
extern uint8_t gAppStatus;
|
extern uint8_t gAppStatus;
|
||||||
extern uint64_t gGameTitleID;
|
extern uint64_t gGameTitleID;
|
||||||
extern volatile uint8_t gSDInitDone;
|
extern volatile uint8_t gSDInitDone;
|
||||||
@ -17,4 +21,11 @@ extern int32_t ntfs_mount_count;
|
|||||||
extern struct buffer_store drc_store;
|
extern struct buffer_store drc_store;
|
||||||
extern struct buffer_store tv_store;
|
extern struct buffer_store tv_store;
|
||||||
|
|
||||||
|
extern GX2ColorBuffer g_vid_main_cbuf;
|
||||||
|
extern GX2Texture g_vid_drcTex;
|
||||||
|
extern GX2Texture g_vid_tvTex;
|
||||||
|
extern GX2ContextState* g_vid_ownContextState;
|
||||||
|
extern GX2ContextState* g_vid_originalContextSave;
|
||||||
|
extern GX2Sampler g_vid_sampler;
|
||||||
|
|
||||||
#endif // RETAINS_VARS_H_
|
#endif // RETAINS_VARS_H_
|
||||||
|
@ -20,16 +20,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
DefaultGuiSelectBox::DefaultGuiSelectBox(std::string caption, GuiFrame *parent)
|
DefaultGuiSelectBox::DefaultGuiSelectBox(std::string caption, GuiFrame *parent)
|
||||||
: GuiSelectBox(NULL,caption)
|
: GuiSelectBox(NULL,caption)
|
||||||
,topBackgroundImg_imgdata(Resources::GetImageData("gameSettingsButton.png"))
|
,topBackgroundImg_imgdata(Resources::GetImageData("gameSettingsButton.png"))
|
||||||
,topBackgroundImg_img(topBackgroundImg_imgdata)
|
,topBackgroundImg_img(topBackgroundImg_imgdata)
|
||||||
,topHighlightedImg_imgdata(Resources::GetImageData("gameSettingsButtonSelected.png"))
|
,topHighlightedImg_imgdata(Resources::GetImageData("gameSettingsButtonSelected.png"))
|
||||||
,topHighlightedImg_img(topHighlightedImg_imgdata)
|
,topHighlightedImg_img(topHighlightedImg_imgdata)
|
||||||
,valueImageData(Resources::GetImageData("gameSettingsButtonEx.png"))
|
,valueImageData(Resources::GetImageData("gameSettingsButtonEx.png"))
|
||||||
,valueSelectedImageData(Resources::GetImageData("gameSettingsButtonExSelected.png"))
|
,valueSelectedImageData(Resources::GetImageData("gameSettingsButtonExSelected.png"))
|
||||||
,valueHighlightedImageData(Resources::GetImageData("gameSettingsButtonExHighlighted.png"))
|
,valueHighlightedImageData(Resources::GetImageData("gameSettingsButtonExHighlighted.png"))
|
||||||
,buttonClickSound(Resources::GetSound("settings_click_2.mp3"))
|
,buttonClickSound(Resources::GetSound("settings_click_2.mp3")) {
|
||||||
{
|
|
||||||
setSize(topBackgroundImg_img.getWidth(),topBackgroundImg_img.getHeight());
|
setSize(topBackgroundImg_img.getWidth(),topBackgroundImg_img.getHeight());
|
||||||
this->setImageTopBackground(&topBackgroundImg_img);
|
this->setImageTopBackground(&topBackgroundImg_img);
|
||||||
this->setImageTopHighlighted(&topHighlightedImg_img);
|
this->setImageTopHighlighted(&topHighlightedImg_img);
|
||||||
@ -41,8 +40,7 @@ DefaultGuiSelectBox::DefaultGuiSelectBox(std::string caption, GuiFrame *parent)
|
|||||||
/**
|
/**
|
||||||
* Destructor for the DefaultGuiSelectBox class.
|
* Destructor for the DefaultGuiSelectBox class.
|
||||||
*/
|
*/
|
||||||
DefaultGuiSelectBox::~DefaultGuiSelectBox()
|
DefaultGuiSelectBox::~DefaultGuiSelectBox() {
|
||||||
{
|
|
||||||
Resources::RemoveImageData(topBackgroundImg_imgdata);
|
Resources::RemoveImageData(topBackgroundImg_imgdata);
|
||||||
Resources::RemoveImageData(topHighlightedImg_imgdata);
|
Resources::RemoveImageData(topHighlightedImg_imgdata);
|
||||||
Resources::RemoveImageData(valueImageData);
|
Resources::RemoveImageData(valueImageData);
|
||||||
|
@ -20,26 +20,26 @@
|
|||||||
#include <gui/GuiSelectBox.h>
|
#include <gui/GuiSelectBox.h>
|
||||||
|
|
||||||
//!A simple select box with default values.
|
//!A simple select box with default values.
|
||||||
class DefaultGuiSelectBox : public GuiSelectBox{
|
class DefaultGuiSelectBox : public GuiSelectBox {
|
||||||
public:
|
public:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
//!\param checked Checked
|
//!\param checked Checked
|
||||||
DefaultGuiSelectBox(std::string caption, GuiFrame *parent = NULL);
|
DefaultGuiSelectBox(std::string caption, GuiFrame *parent = NULL);
|
||||||
//!Destructor
|
//!Destructor
|
||||||
virtual ~DefaultGuiSelectBox();
|
virtual ~DefaultGuiSelectBox();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GuiImageData * topBackgroundImg_imgdata;
|
GuiImageData * topBackgroundImg_imgdata;
|
||||||
GuiImage topBackgroundImg_img;
|
GuiImage topBackgroundImg_img;
|
||||||
|
|
||||||
GuiImageData * topHighlightedImg_imgdata;
|
GuiImageData * topHighlightedImg_imgdata;
|
||||||
GuiImage topHighlightedImg_img;
|
GuiImage topHighlightedImg_img;
|
||||||
|
|
||||||
GuiImageData * valueImageData;
|
GuiImageData * valueImageData;
|
||||||
GuiImageData * valueSelectedImageData;
|
GuiImageData * valueSelectedImageData;
|
||||||
GuiImageData * valueHighlightedImageData;
|
GuiImageData * valueHighlightedImageData;
|
||||||
|
|
||||||
GuiSound * buttonClickSound;
|
GuiSound * buttonClickSound;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,16 +20,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
DefaultGuiSwitch::DefaultGuiSwitch(bool checked)
|
DefaultGuiSwitch::DefaultGuiSwitch(bool checked)
|
||||||
: GuiSwitch(NULL,checked)
|
: GuiSwitch(NULL,checked)
|
||||||
,switchbase_imgdata(Resources::GetImageData("switchIconBase.png"))
|
,switchbase_imgdata(Resources::GetImageData("switchIconBase.png"))
|
||||||
,switchbase_img(switchbase_imgdata)
|
,switchbase_img(switchbase_imgdata)
|
||||||
,switchbase_highlighted_imgdata(Resources::GetImageData("switchIconBaseHighlighted.png"))
|
,switchbase_highlighted_imgdata(Resources::GetImageData("switchIconBaseHighlighted.png"))
|
||||||
,switchbase_highlighted_img(switchbase_highlighted_imgdata)
|
,switchbase_highlighted_img(switchbase_highlighted_imgdata)
|
||||||
,switchOn_imgdata(Resources::GetImageData("switchIconOn.png"))
|
,switchOn_imgdata(Resources::GetImageData("switchIconOn.png"))
|
||||||
,switchOn_img(switchOn_imgdata)
|
,switchOn_img(switchOn_imgdata)
|
||||||
,switchOff_imgdata(Resources::GetImageData("switchIconOff.png"))
|
,switchOff_imgdata(Resources::GetImageData("switchIconOff.png"))
|
||||||
,switchOff_img(switchOff_imgdata)
|
,switchOff_img(switchOff_imgdata) {
|
||||||
{
|
|
||||||
setSize(switchbase_img.getWidth(),switchbase_img.getHeight());
|
setSize(switchbase_img.getWidth(),switchbase_img.getHeight());
|
||||||
this->setImageBackground(&switchbase_img);
|
this->setImageBackground(&switchbase_img);
|
||||||
this->setImageHighlighted(&switchbase_highlighted_img);
|
this->setImageHighlighted(&switchbase_highlighted_img);
|
||||||
@ -39,8 +38,7 @@ DefaultGuiSwitch::DefaultGuiSwitch(bool checked)
|
|||||||
/**
|
/**
|
||||||
* Destructor for the DefaultGuiSwitch class.
|
* Destructor for the DefaultGuiSwitch class.
|
||||||
*/
|
*/
|
||||||
DefaultGuiSwitch::~DefaultGuiSwitch()
|
DefaultGuiSwitch::~DefaultGuiSwitch() {
|
||||||
{
|
|
||||||
Resources::RemoveImageData(switchbase_imgdata);
|
Resources::RemoveImageData(switchbase_imgdata);
|
||||||
Resources::RemoveImageData(switchbase_highlighted_imgdata);
|
Resources::RemoveImageData(switchbase_highlighted_imgdata);
|
||||||
Resources::RemoveImageData(switchOn_imgdata);
|
Resources::RemoveImageData(switchOn_imgdata);
|
||||||
|
@ -20,26 +20,26 @@
|
|||||||
#include <gui/GuiSwitch.h>
|
#include <gui/GuiSwitch.h>
|
||||||
|
|
||||||
//!A simple switch
|
//!A simple switch
|
||||||
class DefaultGuiSwitch : public GuiSwitch{
|
class DefaultGuiSwitch : public GuiSwitch {
|
||||||
public:
|
public:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
//!\param checked Checked
|
//!\param checked Checked
|
||||||
DefaultGuiSwitch(bool checked);
|
DefaultGuiSwitch(bool checked);
|
||||||
//!Destructor
|
//!Destructor
|
||||||
virtual ~DefaultGuiSwitch();
|
virtual ~DefaultGuiSwitch();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GuiImageData * switchbase_imgdata = NULL;
|
GuiImageData * switchbase_imgdata = NULL;
|
||||||
GuiImage switchbase_img;
|
GuiImage switchbase_img;
|
||||||
|
|
||||||
GuiImageData * switchbase_highlighted_imgdata = NULL;
|
GuiImageData * switchbase_highlighted_imgdata = NULL;
|
||||||
GuiImage switchbase_highlighted_img;
|
GuiImage switchbase_highlighted_img;
|
||||||
|
|
||||||
GuiImageData * switchOn_imgdata = NULL;
|
GuiImageData * switchOn_imgdata = NULL;
|
||||||
GuiImage switchOn_img;
|
GuiImage switchOn_img;
|
||||||
|
|
||||||
GuiImageData * switchOff_imgdata = NULL;
|
GuiImageData * switchOff_imgdata = NULL;
|
||||||
GuiImage switchOff_img;
|
GuiImage switchOff_img;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
35
src/main.cpp
35
src/main.cpp
@ -52,7 +52,9 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "patcher/function_patcher.h"
|
#include "patcher/function_patcher.h"
|
||||||
#include "patcher/hooks_patcher.h"
|
#include "patcher/hooks_patcher.h"
|
||||||
|
#include "patcher/hooks_patcher_static.h"
|
||||||
#include "plugin/dynamic_linking_defines.h"
|
#include "plugin/dynamic_linking_defines.h"
|
||||||
|
#include "myutils/mem_utils.h"
|
||||||
#include "myutils/mocha.h"
|
#include "myutils/mocha.h"
|
||||||
#include "myutils/libntfs.h"
|
#include "myutils/libntfs.h"
|
||||||
#include "myutils/libfat.h"
|
#include "myutils/libfat.h"
|
||||||
@ -95,8 +97,15 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
init_kernel_syscalls();
|
init_kernel_syscalls();
|
||||||
wups_init_kernel_syscalls();
|
wups_init_kernel_syscalls();
|
||||||
|
|
||||||
|
if(!MemoryMapping::isMemoryMapped()) {
|
||||||
|
MemoryMapping::setupMemoryMapping();
|
||||||
|
}
|
||||||
|
|
||||||
gGameTitleID = OSGetTitleID();
|
gGameTitleID = OSGetTitleID();
|
||||||
|
|
||||||
|
g_vid_ownContextState = NULL;
|
||||||
|
g_vid_originalContextSave = NULL;
|
||||||
|
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
//Reset everything when were going back to the Mii Maker
|
//Reset everything when were going back to the Mii Maker
|
||||||
@ -129,13 +138,22 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
memoryRelease();
|
memoryRelease();
|
||||||
CSettings::destroyInstance();
|
CSettings::destroyInstance();
|
||||||
PluginLoader::destroyInstance();
|
PluginLoader::destroyInstance();
|
||||||
|
|
||||||
|
MemoryUtils::init();
|
||||||
|
|
||||||
|
// Memory on custon heap is reset anyway so we don't need to free the image buffers.
|
||||||
|
memset((void*)&g_vid_main_cbuf,0,sizeof(g_vid_main_cbuf));
|
||||||
|
memset((void*)&g_vid_drcTex,0,sizeof(g_vid_drcTex));
|
||||||
|
memset((void*)&g_vid_tvTex,0,sizeof(g_vid_tvTex));
|
||||||
|
g_vid_originalContextSave = NULL;
|
||||||
|
g_vid_ownContextState = NULL;
|
||||||
|
g_NotInLoader = false;
|
||||||
|
} else {
|
||||||
|
g_NotInLoader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result == APPLICATION_CLOSE_APPLY_MEMORY) {
|
DEBUG_FUNCTION_LINE("Patch own stuff\n");
|
||||||
if(!MemoryMapping::isMemoryMapped()) {
|
PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static);
|
||||||
MemoryMapping::setupMemoryMapping();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Do relocations\n");
|
DEBUG_FUNCTION_LINE("Do relocations\n");
|
||||||
|
|
||||||
@ -149,12 +167,11 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
if(!isInMiiMakerHBL()) {
|
if(!isInMiiMakerHBL()) {
|
||||||
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
||||||
ApplyPatchesAndCallHookStartingApp();
|
ApplyPatchesAndCallHookStartingApp();
|
||||||
ConfigUtils::loadConfigFromSD();
|
|
||||||
|
|
||||||
if(MemoryMapping::isMemoryMapped()) {
|
if(MemoryMapping::isMemoryMapped()) {
|
||||||
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
|
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
|
||||||
readAndPrintSegmentRegister(NULL,NULL);
|
readAndPrintSegmentRegister(NULL,NULL);
|
||||||
MemoryMapping::readTestValuesFromMemory();
|
//MemoryMapping::readTestValuesFromMemory();
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
|
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
|
||||||
DEBUG_FUNCTION_LINE("<---------------- COPY PASTE ME START-----------------> \n");
|
DEBUG_FUNCTION_LINE("<---------------- COPY PASTE ME START-----------------> \n");
|
||||||
@ -169,9 +186,11 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result == APPLICATION_CLOSE_APPLY || result == APPLICATION_CLOSE_APPLY_MEMORY) {
|
if(result == APPLICATION_CLOSE_APPLY || result == APPLICATION_CLOSE_APPLY_MEMORY) {
|
||||||
|
CallHook(WUPS_LOADER_HOOK_INIT_VID_MEM);
|
||||||
CallHook(WUPS_LOADER_HOOK_INIT_KERNEL);
|
CallHook(WUPS_LOADER_HOOK_INIT_KERNEL);
|
||||||
CallHook(WUPS_LOADER_HOOK_INIT_FS);
|
CallHook(WUPS_LOADER_HOOK_INIT_FS);
|
||||||
CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY);
|
CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY);
|
||||||
|
ConfigUtils::loadConfigFromSD();
|
||||||
CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN);
|
CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN);
|
||||||
DEBUG_FUNCTION_LINE("Loading the system menu.\n");
|
DEBUG_FUNCTION_LINE("Loading the system menu.\n");
|
||||||
DeInit();
|
DeInit();
|
||||||
@ -191,6 +210,7 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ApplyPatchesAndCallHookStartingApp() {
|
void ApplyPatchesAndCallHookStartingApp() {
|
||||||
|
PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static);
|
||||||
PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks);
|
PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks);
|
||||||
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
||||||
CallHookEx(WUPS_LOADER_HOOK_STARTING_APPLICATION,plugin_index);
|
CallHookEx(WUPS_LOADER_HOOK_STARTING_APPLICATION,plugin_index);
|
||||||
@ -209,6 +229,7 @@ void RestorePatches() {
|
|||||||
new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]);
|
new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]);
|
||||||
}
|
}
|
||||||
RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks);
|
RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks);
|
||||||
|
RestoreInvidualInstructions(method_hooks_hooks_static, method_hooks_size_hooks_static);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t isInMiiMakerHBL() {
|
int32_t isInMiiMakerHBL() {
|
||||||
|
@ -231,7 +231,7 @@ bool ContentHome::linkPlugins() {
|
|||||||
|
|
||||||
void ContentHome::update(GuiController * c) {
|
void ContentHome::update(GuiController * c) {
|
||||||
ContentTemplate::update(c);
|
ContentTemplate::update(c);
|
||||||
if(updateButtons){
|
if(updateButtons) {
|
||||||
for (auto const& x : selectionMapping) {
|
for (auto const& x : selectionMapping) {
|
||||||
int index = x.first;
|
int index = x.first;
|
||||||
GuiToggle* toggle = x.second;
|
GuiToggle* toggle = x.second;
|
||||||
|
@ -8,20 +8,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _sr_table_t
|
typedef struct _sr_table_t {
|
||||||
{
|
|
||||||
uint32_t value[16];
|
uint32_t value[16];
|
||||||
uint32_t sdr1;
|
uint32_t sdr1;
|
||||||
} sr_table_t;
|
} sr_table_t;
|
||||||
|
|
||||||
typedef struct _bat_t
|
typedef struct _bat_t {
|
||||||
{
|
|
||||||
uint32_t h;
|
uint32_t h;
|
||||||
uint32_t l;
|
uint32_t l;
|
||||||
} bat_t;
|
} bat_t;
|
||||||
|
|
||||||
typedef struct _bat_table_t
|
typedef struct _bat_table_t {
|
||||||
{
|
|
||||||
bat_t bat[8];
|
bat_t bat[8];
|
||||||
} bat_table_t;
|
} bat_table_t;
|
||||||
|
|
||||||
|
@ -58,22 +58,23 @@ static void KernelWriteSRs(sr_table_t * table) {
|
|||||||
// Writing didn't work for all at once so we only write number 8.
|
// Writing didn't work for all at once so we only write number 8.
|
||||||
// TODO: fix this and change it if required.
|
// TODO: fix this and change it if required.
|
||||||
|
|
||||||
/*asm volatile("mtsr 0, %0" : : "r" (table->value[i])); i++;
|
/*asm volatile("mtsr 0, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 1, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 1, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 2, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 2, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 3, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 3, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 4, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 4, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 5, %0" : : "r" (table->value[i])); i++;*/
|
asm volatile("mtsr 5, %0" : : "r" (table->value[i])); i++;*/
|
||||||
//asm volatile("mtsr 6, %0" : : "r" (table->value[6])); i++;
|
//asm volatile("mtsr 6, %0" : : "r" (table->value[6])); i++;
|
||||||
/*asm volatile("mtsr 7, %0" : : "r" (table->value[i])); i++;*/
|
/*asm volatile("mtsr 7, %0" : : "r" (table->value[i])); i++;*/
|
||||||
asm volatile("mtsr 8, %0" : : "r" (table->value[8])); i++;
|
asm volatile("mtsr 8, %0" : : "r" (table->value[8]));
|
||||||
/*asm volatile("mtsr 9, %0" : : "r" (table->value[i])); i++;
|
i++;
|
||||||
asm volatile("mtsr 10, %0" : : "r" (table->value[i])); i++;
|
/*asm volatile("mtsr 9, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 11, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 10, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 12, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 11, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 13, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 12, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 14, %0" : : "r" (table->value[i])); i++;
|
asm volatile("mtsr 13, %0" : : "r" (table->value[i])); i++;
|
||||||
asm volatile("mtsr 15, %0" : : "r" (table->value[i])); i++;*/
|
asm volatile("mtsr 14, %0" : : "r" (table->value[i])); i++;
|
||||||
|
asm volatile("mtsr 15, %0" : : "r" (table->value[i])); i++;*/
|
||||||
|
|
||||||
|
|
||||||
asm volatile("isync");
|
asm volatile("isync");
|
||||||
@ -87,7 +88,7 @@ void KernelReadPTE(uint32_t* dest, uint32_t size) {
|
|||||||
asm volatile("mfmsr %0" : "=r" (msr));
|
asm volatile("mfmsr %0" : "=r" (msr));
|
||||||
oldmsr = msr;
|
oldmsr = msr;
|
||||||
msr &= ~0x10;
|
msr &= ~0x10;
|
||||||
for(uint32_t i = 0;i<size/0x04;i++){
|
for(uint32_t i = 0; i<size/0x04; i++) {
|
||||||
uint32_t value_read = 0;
|
uint32_t value_read = 0;
|
||||||
uint32_t addr = addr_base + (i*4);
|
uint32_t addr = addr_base + (i*4);
|
||||||
// Disable Data address translation
|
// Disable Data address translation
|
||||||
@ -107,7 +108,7 @@ void KernelWritePTE(uint32_t * in_addr, uint32_t size) {
|
|||||||
asm volatile("mfmsr %0" : "=r" (msr));
|
asm volatile("mfmsr %0" : "=r" (msr));
|
||||||
oldmsr = msr;
|
oldmsr = msr;
|
||||||
msr &= ~0x10;
|
msr &= ~0x10;
|
||||||
for(uint32_t i = 0;i<size/0x04;i++){
|
for(uint32_t i = 0; i<size/0x04; i++) {
|
||||||
uint32_t addr = addr_base + (i*4);
|
uint32_t addr = addr_base + (i*4);
|
||||||
uint32_t value = in_addr[i];
|
uint32_t value = in_addr[i];
|
||||||
// Disable Data address translation
|
// Disable Data address translation
|
||||||
@ -135,7 +136,7 @@ void KernelWriteWitoutDAT(uint32_t addr, uint32_t value) {
|
|||||||
|
|
||||||
void SC0x0A_KernelWriteWitoutDAT(uint32_t addr,uint32_t value);
|
void SC0x0A_KernelWriteWitoutDAT(uint32_t addr,uint32_t value);
|
||||||
|
|
||||||
void wups_init_kernel_syscalls(){
|
void wups_init_kernel_syscalls() {
|
||||||
//! assign 1 so that this variable gets into the retained .data section
|
//! assign 1 so that this variable gets into the retained .data section
|
||||||
static uint8_t ucSyscallsSetupRequired = 1;
|
static uint8_t ucSyscallsSetupRequired = 1;
|
||||||
if(!ucSyscallsSetupRequired)
|
if(!ucSyscallsSetupRequired)
|
||||||
|
@ -76,6 +76,14 @@ uint32_t MemoryMapping::getHeapSize() {
|
|||||||
return getAreaSizeFromPageTable(MEMORY_START_PLUGIN_HEAP,MEMORY_START_PLUGIN_HEAP_END - MEMORY_START_PLUGIN_HEAP);
|
return getAreaSizeFromPageTable(MEMORY_START_PLUGIN_HEAP,MEMORY_START_PLUGIN_HEAP_END - MEMORY_START_PLUGIN_HEAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t MemoryMapping::getVideoMemoryAddress() {
|
||||||
|
return MEMORY_START_VIDEO_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MemoryMapping::getVideoMemorySize() {
|
||||||
|
return getAreaSizeFromPageTable(MEMORY_START_VIDEO_SPACE,MEMORY_START_VIDEO_SPACE_END - MEMORY_START_VIDEO_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryMapping::searchEmptyMemoryRegions() {
|
void MemoryMapping::searchEmptyMemoryRegions() {
|
||||||
DEBUG_FUNCTION_LINE("Searching for empty memory.\n");
|
DEBUG_FUNCTION_LINE("Searching for empty memory.\n");
|
||||||
|
|
||||||
@ -325,7 +333,7 @@ void MemoryMapping::setupMemoryMapping() {
|
|||||||
// This is nice because it leads to SR[8] which also seems to be unused (was set to 0x30FFFFFF)
|
// This is nice because it leads to SR[8] which also seems to be unused (was set to 0x30FFFFFF)
|
||||||
// The content of the segment was chosen randomly.
|
// The content of the segment was chosen randomly.
|
||||||
uint32_t segment_index = MEMORY_START_BASE >> 28;
|
uint32_t segment_index = MEMORY_START_BASE >> 28;
|
||||||
uint32_t segment_content = 0x20000000 | SEGMENT_UNIQUE_ID;
|
uint32_t segment_content = 0x00000000 | SEGMENT_UNIQUE_ID;
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Setting SR[%d] to %08X\n",segment_index,segment_content);
|
DEBUG_FUNCTION_LINE("Setting SR[%d] to %08X\n",segment_index,segment_content);
|
||||||
srTableCpy.value[segment_index] = segment_content;
|
srTableCpy.value[segment_index] = segment_content;
|
||||||
@ -349,10 +357,10 @@ void MemoryMapping::setupMemoryMapping() {
|
|||||||
|
|
||||||
runOnAllCores(readAndPrintSegmentRegister,NULL,0,16,0x80000);
|
runOnAllCores(readAndPrintSegmentRegister,NULL,0,16,0x80000);
|
||||||
|
|
||||||
searchEmptyMemoryRegions();
|
//searchEmptyMemoryRegions();
|
||||||
|
|
||||||
writeTestValuesToMemory();
|
//writeTestValuesToMemory();
|
||||||
readTestValuesFromMemory();
|
//readTestValuesFromMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -549,9 +557,8 @@ void MemoryMapping::printPageTableTranslation(sr_table_t srTable, uint32_t * tra
|
|||||||
|
|
||||||
for(std::vector<pageInformation>::iterator it = pageInfos.begin(); it != pageInfos.end(); ++it) {
|
for(std::vector<pageInformation>::iterator it = pageInfos.begin(); it != pageInfos.end(); ++it) {
|
||||||
pageInformation cur = *it;
|
pageInformation cur = *it;
|
||||||
// TODO: print if it's executable
|
|
||||||
DEBUG_FUNCTION_LINE("%08X %08X -> %08X %08X. user access %s. supervisor access %s. %s\n",cur.addr,cur.addr+cur.size,cur.phys,cur.phys+cur.size,cur.kp ? access2[cur.pp] : access1[cur.pp],
|
DEBUG_FUNCTION_LINE("%08X %08X -> %08X %08X. user access %s. supervisor access %s. %s\n",cur.addr,cur.addr+cur.size,cur.phys,cur.phys+cur.size,cur.kp ? access2[cur.pp] : access1[cur.pp],
|
||||||
cur.ks ? access2[cur.pp] : access1[cur.pp],cur.nx? " not executable " : " executable");
|
cur.ks ? access2[cur.pp] : access1[cur.pp],cur.nx? "not executable" : "executable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,3 +683,66 @@ bool MemoryMapping::mapMemory(uint32_t pa_start_address,uint32_t pa_end_address,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t MemoryMapping::PhysicalToEffective(uint32_t phyiscalAddress) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
const memory_values_t * curMemValues = NULL;
|
||||||
|
int32_t curOffset = 0;
|
||||||
|
//iterate through all own mapped memory regions
|
||||||
|
for(int32_t i = 0; true; i++) {
|
||||||
|
if(mem_mapping[i].physical_addresses == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
curMemValues = mem_mapping[i].physical_addresses;
|
||||||
|
uint32_t curOffsetInEA = 0;
|
||||||
|
// iterate through all memory values of this region
|
||||||
|
for(int32_t j= 0; true; j++) {
|
||||||
|
if(curMemValues[j].end_address == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(phyiscalAddress >= curMemValues[j].start_address && phyiscalAddress < curMemValues[j].end_address) {
|
||||||
|
// calculate the EA
|
||||||
|
result = (phyiscalAddress - curMemValues[j].start_address) + (mem_mapping[i].effective_start_address + curOffsetInEA);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
curOffsetInEA += curMemValues[j].end_address - curMemValues[j].start_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MemoryMapping::EffectiveToPhysical(uint32_t effectiveAddress) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
// CAUTION: The data may be fragmented between multiple areas in PA.
|
||||||
|
const memory_values_t * curMemValues = NULL;
|
||||||
|
int32_t curOffset = 0;
|
||||||
|
|
||||||
|
for(int32_t i = 0; true; i++) {
|
||||||
|
if(mem_mapping[i].physical_addresses == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(effectiveAddress >= mem_mapping[i].effective_start_address && effectiveAddress < mem_mapping[i].effective_end_address) {
|
||||||
|
curMemValues = mem_mapping[i].physical_addresses;
|
||||||
|
curOffset = mem_mapping[i].effective_start_address;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curMemValues == NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t i= 0; true; i++) {
|
||||||
|
if(curMemValues[i].end_address == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int32_t curChunkSize = curMemValues[i].end_address - curMemValues[i].start_address;
|
||||||
|
if(effectiveAddress < (curOffset + curChunkSize)) {
|
||||||
|
result = (effectiveAddress - curOffset) + curMemValues[i].start_address;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
curOffset += curChunkSize;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,7 @@ typedef struct _memory_values_t {
|
|||||||
|
|
||||||
typedef struct _memory_mapping_t {
|
typedef struct _memory_mapping_t {
|
||||||
uint32_t effective_start_address;
|
uint32_t effective_start_address;
|
||||||
|
uint32_t effective_end_address;
|
||||||
const memory_values_t* physical_addresses;
|
const memory_values_t* physical_addresses;
|
||||||
} memory_mapping_t;
|
} memory_mapping_t;
|
||||||
|
|
||||||
@ -35,7 +36,8 @@ typedef struct _memory_mapping_t {
|
|||||||
#define MEMORY_START_BASE 0x80000000
|
#define MEMORY_START_BASE 0x80000000
|
||||||
|
|
||||||
#define MEMORY_LOADER_SPACE_SIZE 0x00800000 // At most: 8MB for the plugin loader.
|
#define MEMORY_LOADER_SPACE_SIZE 0x00800000 // At most: 8MB for the plugin loader.
|
||||||
#define MEMORY_PLUGIN_SPACE_SIZE 0x07800000 // At most: 120MB for plugins.
|
#define MEMORY_PLUGIN_SPACE_SIZE 0x04000000 // At most: 64MB for plugins.
|
||||||
|
#define MEMORY_VIDEO_SPACE_SIZE 0x03600000 // At most: 56MB for video.
|
||||||
#define MEMORY_PLUGIN_HEAP_SIZE 0x08000000 // At most: 128MB for plugins heap.
|
#define MEMORY_PLUGIN_HEAP_SIZE 0x08000000 // At most: 128MB for plugins heap.
|
||||||
|
|
||||||
#define MEMORY_START_PLUGIN_LOADER MEMORY_START_BASE
|
#define MEMORY_START_PLUGIN_LOADER MEMORY_START_BASE
|
||||||
@ -44,16 +46,53 @@ typedef struct _memory_mapping_t {
|
|||||||
#define MEMORY_START_PLUGIN_SPACE MEMORY_START_PLUGIN_LOADER_END
|
#define MEMORY_START_PLUGIN_SPACE MEMORY_START_PLUGIN_LOADER_END
|
||||||
#define MEMORY_START_PLUGIN_SPACE_END MEMORY_START_PLUGIN_SPACE + MEMORY_PLUGIN_SPACE_SIZE
|
#define MEMORY_START_PLUGIN_SPACE_END MEMORY_START_PLUGIN_SPACE + MEMORY_PLUGIN_SPACE_SIZE
|
||||||
|
|
||||||
#define MEMORY_START_PLUGIN_HEAP MEMORY_START_PLUGIN_SPACE_END
|
#define MEMORY_START_VIDEO_SPACE MEMORY_START_PLUGIN_SPACE_END
|
||||||
|
#define MEMORY_START_VIDEO_SPACE_END MEMORY_START_VIDEO_SPACE + MEMORY_VIDEO_SPACE_SIZE
|
||||||
|
|
||||||
|
#define MEMORY_START_PLUGIN_HEAP MEMORY_START_VIDEO_SPACE_END
|
||||||
#define MEMORY_START_PLUGIN_HEAP_END MEMORY_START_PLUGIN_HEAP + MEMORY_PLUGIN_HEAP_SIZE
|
#define MEMORY_START_PLUGIN_HEAP_END MEMORY_START_PLUGIN_HEAP + MEMORY_PLUGIN_HEAP_SIZE
|
||||||
|
|
||||||
const memory_values_t mem_vals_loader[] = {
|
const memory_values_t mem_vals_loader[] = {
|
||||||
{0x28000000 + 0x06620000 , 0x28000000 + 0x06E20000}, // 8MB 0x80000000 0x80800000 -> 0x2E700000 0x2EF00000
|
{0x28000000 + 0x06620000, 0x28000000 + 0x06E20000}, // 8MB 0x80000000 0x80800000 -> 0x2E700000 0x2EF00000
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
const memory_values_t mem_vals_plugins[] = {
|
const memory_values_t mem_vals_plugins[] = {
|
||||||
{0x28000000 + 0x06E20000 , 0x28000000 + 0x07E20000}, // 16MB 0x80800000 0x81800000 -> 0x2EF00000 0x2FF00000
|
{0x28000000 + 0x06E20000, 0x28000000 + 0x07E20000}, // 16MB 0x80800000 0x81800000 -> 0x2EF00000 0x2FF00000
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const memory_values_t mem_vals_video[] = {
|
||||||
|
// The GPU doesn't have access to the 0x28000000 - 0x32000000 area, so we need memory from somewhere else.
|
||||||
|
// From the SharedReadHeap of the loader.
|
||||||
|
//
|
||||||
|
// #define TinyHeap_Alloc ((int32_t (*)(void* heap, int32_t size, int32_t align,void ** outPtr))0x0101235C)
|
||||||
|
// #define TinyHeap_Free ((void (*)(void* heap, void * ptr))0x01012814)
|
||||||
|
// uint32_t SharedReadHeapTrackingAddr = 0xFA000000 + 0x18 + 0x830 // see https://github.com/decaf-emu/decaf-emu/blob/master/src/libdecaf/src/cafe/loader/cafe_loader_shared.cpp#L490
|
||||||
|
//
|
||||||
|
// Map the area of the heap to somewhere in the user space and test allocation with
|
||||||
|
// void * heap = (void*) SharedReadHeapTrackingAddr - [delta due mapping e.g (0xF8000000 + 0x80000000)];
|
||||||
|
// int size = 0x20000; // value have to be a multiple of 0x20000;
|
||||||
|
// while(true){
|
||||||
|
// void * outPtr = NULL;
|
||||||
|
// if(TinyHeap_Alloc(heap,size, 0x20000,&outPtr) == 0){ // value have to be a multiple of 0x20000;
|
||||||
|
// DEBUG_FUNCTION_LINE("Allocated %d kb on heap %08X (PA %08X)\n",size/1024,(uint32_t)outPtr, OSEffectiveToPhysical(outPtr));
|
||||||
|
// TinyHeap_Free(heap, outPtr);
|
||||||
|
// }else{
|
||||||
|
// DEBUG_FUNCTION_LINE("Failed %08X\n",(uint32_t)outPtr);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// size += 0x20000; // value have to be a multiple of 0x20000;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
{0x1A020000, 0x1A020000 +0xE60000}, // size: 14720 kB
|
||||||
|
// The following chunk were empty while early tests and are maybe promising. However we can get 15mb from
|
||||||
|
// a loader heap. Which should be enough for now.
|
||||||
|
//{0x14000000 + 0x02E00000 , 0x14000000 +0x034E0000}, // size: 7040 kB
|
||||||
|
//{0x14000000 + 0x02820000 , 0x14000000 +0x02C20000}, // size: 4096 kB
|
||||||
|
//{0x14000000 + 0x05AE0000 , 0x14000000 +0x06000000}, // size: 5248 kB
|
||||||
|
//{0x14000000 + 0x08040000 , 0x14000000 +0x08400000}, // size: 3840 kB
|
||||||
|
//{0x18000000 , 0x18000000 +0x3000000}, // size: 3840 kB
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,10 +141,11 @@ const memory_values_t mem_vals_heap[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const memory_mapping_t mem_mapping[] = {
|
const memory_mapping_t mem_mapping[] = {
|
||||||
{MEMORY_START_PLUGIN_LOADER, mem_vals_loader},
|
{MEMORY_START_VIDEO_SPACE, MEMORY_START_VIDEO_SPACE_END, mem_vals_video},
|
||||||
{MEMORY_START_PLUGIN_SPACE, mem_vals_plugins},
|
{MEMORY_START_PLUGIN_LOADER, MEMORY_START_PLUGIN_LOADER_END, mem_vals_loader},
|
||||||
{MEMORY_START_PLUGIN_HEAP, mem_vals_heap},
|
{MEMORY_START_PLUGIN_SPACE, MEMORY_START_PLUGIN_SPACE_END, mem_vals_plugins},
|
||||||
{0,NULL}
|
{MEMORY_START_PLUGIN_HEAP, MEMORY_START_PLUGIN_HEAP_END, mem_vals_heap},
|
||||||
|
{0,0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemoryMapping {
|
class MemoryMapping {
|
||||||
@ -127,8 +167,20 @@ public:
|
|||||||
|
|
||||||
static uint32_t getHeapSize();
|
static uint32_t getHeapSize();
|
||||||
|
|
||||||
|
static uint32_t getVideoMemoryAddress();
|
||||||
|
|
||||||
|
static uint32_t getVideoMemorySize();
|
||||||
|
|
||||||
static uint32_t getAreaSizeFromPageTable(uint32_t start, uint32_t maxSize);
|
static uint32_t getAreaSizeFromPageTable(uint32_t start, uint32_t maxSize);
|
||||||
|
|
||||||
|
// Caution when using the result. A chunk of memory in effective address may be split up
|
||||||
|
// into several small chunks inside physical space.
|
||||||
|
static uint32_t PhysicalToEffective(uint32_t phyiscalAddress);
|
||||||
|
|
||||||
|
// Caution when using the result. A chunk of memory in effective address may be split up
|
||||||
|
// into several small chunks inside physical space.
|
||||||
|
static uint32_t EffectiveToPhysical(uint32_t effectiveAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void memoryMappingForRegions(const memory_mapping_t * memory_mapping, sr_table_t SRTable, uint32_t * translation_table);
|
static void memoryMappingForRegions(const memory_mapping_t * memory_mapping, sr_table_t SRTable, uint32_t * translation_table);
|
||||||
|
@ -25,12 +25,10 @@ ConfigInformation::ConfigInformation(WUPSConfig * config, std::string persistPat
|
|||||||
this->persistPath = persistPath;
|
this->persistPath = persistPath;
|
||||||
this->persistFileName = persistFileName;
|
this->persistFileName = persistFileName;
|
||||||
createConfigSettings();
|
createConfigSettings();
|
||||||
loadValuesFromSD();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigInformation::~ConfigInformation() {
|
ConfigInformation::~ConfigInformation() {
|
||||||
if(configSettings != NULL) {
|
if(configSettings != NULL) {
|
||||||
updateAndSaveSettings();
|
|
||||||
delete configSettings;
|
delete configSettings;
|
||||||
configSettings = NULL;
|
configSettings = NULL;
|
||||||
}
|
}
|
||||||
@ -82,19 +80,19 @@ bool ConfigInformation::loadValuesFromSD() {
|
|||||||
if(prevValue.compare(loadedValue) != 0) {
|
if(prevValue.compare(loadedValue) != 0) {
|
||||||
//DEBUG_FUNCTION_LINE("Call loadValue\n");
|
//DEBUG_FUNCTION_LINE("Call loadValue\n");
|
||||||
curItem->loadValue(loadedValue);
|
curItem->loadValue(loadedValue);
|
||||||
// calling the callback here is _NOT_ needed. It will be called when the menu is closed.
|
curItem->callCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigInformation::updateAndSaveSettings() {
|
void ConfigInformation::updateAndSaveSettings(bool forceAll) {
|
||||||
if(this->config == NULL || this->configSettings == NULL) {
|
if(this->config == NULL || this->configSettings == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateConfigSettings();
|
updateConfigSettings();
|
||||||
configSettings->Save();
|
configSettings->Save(forceAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigInformation::updateConfigSettings() {
|
bool ConfigInformation::updateConfigSettings() {
|
||||||
@ -106,7 +104,7 @@ bool ConfigInformation::updateConfigSettings() {
|
|||||||
for (auto & curItem : curCat->getItems()) {
|
for (auto & curItem : curCat->getItems()) {
|
||||||
std::string configID = curItem->getConfigID();
|
std::string configID = curItem->getConfigID();
|
||||||
std::string newValue = curItem->persistValue();
|
std::string newValue = curItem->persistValue();
|
||||||
if(this->configSettings->setValueAsString(this->configSettings->getIdByName(configID), newValue)){
|
if(this->configSettings->setValueAsString(this->configSettings->getIdByName(configID), newValue)) {
|
||||||
// When the value has changed, call the callback.
|
// When the value has changed, call the callback.
|
||||||
DEBUG_FUNCTION_LINE("Called callback. Reason. Menu was closed and value has changed\n");
|
DEBUG_FUNCTION_LINE("Called callback. Reason. Menu was closed and value has changed\n");
|
||||||
curItem->callCallback();
|
curItem->callCallback();
|
||||||
|
@ -35,12 +35,13 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes the given WUPSConfig
|
Deletes the given WUPSConfig
|
||||||
Calls updateAndSaveSettings
|
|
||||||
Deletes the created ConfigSettings
|
Deletes the created ConfigSettings
|
||||||
**/
|
**/
|
||||||
~ConfigInformation();
|
~ConfigInformation();
|
||||||
|
|
||||||
void updateAndSaveSettings();
|
void updateAndSaveSettings(bool forceAll);
|
||||||
|
|
||||||
|
bool loadValuesFromSD();
|
||||||
|
|
||||||
WUPSConfig * getConfig() {
|
WUPSConfig * getConfig() {
|
||||||
return config;
|
return config;
|
||||||
@ -48,7 +49,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool createConfigSettings();
|
bool createConfigSettings();
|
||||||
bool loadValuesFromSD();
|
|
||||||
bool updateConfigSettings();
|
bool updateConfigSettings();
|
||||||
|
|
||||||
WUPSConfig * config = NULL;
|
WUPSConfig * config = NULL;
|
||||||
|
@ -167,6 +167,18 @@ void ConfigUtils::configMenuOpenedCallback(wups_overlay_options_type_t screen, v
|
|||||||
if(vpad_data.btns_d & VPAD_BUTTON_RIGHT) {
|
if(vpad_data.btns_d & VPAD_BUTTON_RIGHT) {
|
||||||
pressedButtons |= WUPS_CONFIG_BUTTON_RIGHT;
|
pressedButtons |= WUPS_CONFIG_BUTTON_RIGHT;
|
||||||
}
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_L) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_L;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_R) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_R;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_ZL) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_ZL;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_ZR) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_ZR;
|
||||||
|
}
|
||||||
|
|
||||||
if(vpad_data.btns_r & VPAD_BUTTON_DOWN) {
|
if(vpad_data.btns_r & VPAD_BUTTON_DOWN) {
|
||||||
newSelect++;
|
newSelect++;
|
||||||
@ -217,9 +229,9 @@ void ConfigUtils::configMenuOpenedCallback(wups_overlay_options_type_t screen, v
|
|||||||
if(!ignore && curSelect == inSelect) {
|
if(!ignore && curSelect == inSelect) {
|
||||||
if(curSelect == 0) {
|
if(curSelect == 0) {
|
||||||
curScreenOffset = 0;
|
curScreenOffset = 0;
|
||||||
}else if(cur_visible_rows + curScreenOffset >= visible_rows_range) {
|
} else if(cur_visible_rows + curScreenOffset >= visible_rows_range) {
|
||||||
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range;
|
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range;
|
||||||
}else if(cur_visible_rows + curScreenOffset < visible_rows_range/2 && cur_visible_rows >= visible_rows_range/2) {
|
} else if(cur_visible_rows + curScreenOffset < visible_rows_range/2 && cur_visible_rows >= visible_rows_range/2) {
|
||||||
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range/2;
|
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range/2;
|
||||||
}
|
}
|
||||||
ignore = true;
|
ignore = true;
|
||||||
@ -330,12 +342,35 @@ void ConfigUtils::deleteConfigInformation(std::vector<ConfigInformation *> confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigUtils::loadConfigFromSD() {
|
void ConfigUtils::loadConfigFromSD() {
|
||||||
deleteConfigInformation(getConfigInformation());
|
std::vector<ConfigInformation *> configInfos = getConfigInformation();
|
||||||
|
|
||||||
|
for (auto & curConfig : configInfos) {
|
||||||
|
curConfig->loadValuesFromSD();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteConfigInformation(configInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigUtils::saveConfigToSD() {
|
||||||
|
std::vector<ConfigInformation *> configInfos = getConfigInformation();
|
||||||
|
|
||||||
|
for (auto & curConfig : configInfos) {
|
||||||
|
curConfig->updateAndSaveSettings(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteConfigInformation(configInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigUtils::openConfigMenu() {
|
void ConfigUtils::openConfigMenu() {
|
||||||
std::vector<ConfigInformation *> configInfos = getConfigInformation();
|
std::vector<ConfigInformation *> configInfos = getConfigInformation();
|
||||||
|
|
||||||
|
// We rely on the default values here.
|
||||||
|
//if(loadFromSD){
|
||||||
|
// for (auto & curConfig : configInfos) {
|
||||||
|
// configs.loadValuesFromSD();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
std::vector<WUPSConfig *> configs;
|
std::vector<WUPSConfig *> configs;
|
||||||
|
|
||||||
for (auto & curConfig : configInfos) {
|
for (auto & curConfig : configInfos) {
|
||||||
@ -352,5 +387,9 @@ void ConfigUtils::openConfigMenu() {
|
|||||||
DCFlushRange(curConfig, sizeof(WUPSConfig));
|
DCFlushRange(curConfig, sizeof(WUPSConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto & curConfig : configInfos) {
|
||||||
|
curConfig->updateAndSaveSettings(false);
|
||||||
|
}
|
||||||
|
|
||||||
deleteConfigInformation(configInfos);
|
deleteConfigInformation(configInfos);
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,21 @@ class ConfigUtils {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Loads the configuration files of all loaded plugins from the SDCard
|
Loads the configuration files of all loaded plugins from the SDCard
|
||||||
and triggers the "loadValue" if they differ the default value.
|
and triggers the "callback" if they differ the default/current value.
|
||||||
**/
|
**/
|
||||||
static void loadConfigFromSD();
|
static void loadConfigFromSD();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the current values from all plugins via the WUPS_GET_CONFIG() hook and
|
||||||
|
save them to the SD Card.
|
||||||
|
**/
|
||||||
|
static void saveConfigToSD();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Opens the configuration menu where plugins can be configured.
|
Opens the configuration menu where plugins can be configured.
|
||||||
Plugins need to implement the WUPS_GET_CONFIG() hook to show up in the menu.
|
Plugins need to implement the WUPS_GET_CONFIG() hook to show up in the menu.
|
||||||
The menu will be rendered on the TV and DRC screen, with optimization for the DRC.
|
The menu will be rendered on the TV and DRC screen, with optimization for the DRC.
|
||||||
If the menu is low, the menu may be only rendered to the DRC.
|
If the memory is low, the menu may be only rendered to the DRC.
|
||||||
**/
|
**/
|
||||||
static void openConfigMenu();
|
static void openConfigMenu();
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include "libntfs.h"
|
#include "libntfs.h"
|
||||||
#include <iosuhax.h>
|
#include <iosuhax.h>
|
||||||
#include <ntfs.h>
|
//#include <ntfs.h>
|
||||||
#include "common/retain_vars.h"
|
#include "common/retain_vars.h"
|
||||||
|
|
||||||
int32_t mountAllNTFS() {
|
int32_t mountAllNTFS() {
|
||||||
int32_t i;
|
/*int32_t i;
|
||||||
// Mount all NTFS volumes on all inserted block devices
|
// Mount all NTFS volumes on all inserted block devices
|
||||||
ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER);
|
ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER);
|
||||||
if (ntfs_mount_count == -1) {
|
if (ntfs_mount_count == -1) {
|
||||||
@ -22,11 +22,12 @@ int32_t mountAllNTFS() {
|
|||||||
for (i = 0; i < ntfs_mount_count; i++) {
|
for (i = 0; i < ntfs_mount_count; i++) {
|
||||||
DEBUG_FUNCTION_LINE("%i - %s:/ (%s)\n", i + 1, ((ntfs_md *)ntfs_mounts)[i].name, ntfsGetVolumeName(((ntfs_md *)ntfs_mounts)[i].name));
|
DEBUG_FUNCTION_LINE("%i - %s:/ (%s)\n", i + 1, ((ntfs_md *)ntfs_mounts)[i].name, ntfsGetVolumeName(((ntfs_md *)ntfs_mounts)[i].name));
|
||||||
}
|
}
|
||||||
return ntfs_mount_count;
|
return ntfs_mount_count;*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t unmountAllNTFS(void) {
|
int32_t unmountAllNTFS(void) {
|
||||||
if (ntfs_mounts) {
|
/*if (ntfs_mounts) {
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
for (i = 0; i < ntfs_mount_count; i++) {
|
for (i = 0; i < ntfs_mount_count; i++) {
|
||||||
ntfsUnmount(((ntfs_md *)ntfs_mounts)[i].name, true);
|
ntfsUnmount(((ntfs_md *)ntfs_mounts)[i].name, true);
|
||||||
@ -34,6 +35,6 @@ int32_t unmountAllNTFS(void) {
|
|||||||
free(ntfs_mounts);
|
free(ntfs_mounts);
|
||||||
ntfs_mounts = NULL;
|
ntfs_mounts = NULL;
|
||||||
ntfs_mount_count = 0;
|
ntfs_mount_count = 0;
|
||||||
}
|
}*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
37
src/myutils/mem_utils.cpp
Normal file
37
src/myutils/mem_utils.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <utils/logger.h>
|
||||||
|
#include <wups.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "mem_utils.h"
|
||||||
|
#include "mymemory/memory_mapping.h"
|
||||||
|
|
||||||
|
|
||||||
|
int32_t memHandle __attribute__((section(".data"))) = -1;
|
||||||
|
|
||||||
|
void MemoryUtils::init() {
|
||||||
|
memHandle = MEMCreateExpHeapEx((void*)MemoryMapping::getVideoMemoryAddress(), MemoryMapping::getVideoMemorySize(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* MemoryUtils::alloc(uint32_t size, int32_t align) {
|
||||||
|
return MEMAllocFromExpHeapEx(memHandle,size, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryUtils::free(void * ptr) {
|
||||||
|
MEMFreeToExpHeap(memHandle,ptr);
|
||||||
|
}
|
32
src/myutils/mem_utils.h
Normal file
32
src/myutils/mem_utils.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __MEMORY_UTILS_UTILS_H_
|
||||||
|
#define __MEMORY_UTILS_UTILS_H_
|
||||||
|
|
||||||
|
class MemoryUtils {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
|
||||||
|
static void* alloc(uint32_t size, int32_t align);
|
||||||
|
|
||||||
|
static void free(void * ptr);
|
||||||
|
private:
|
||||||
|
MemoryUtils() {}
|
||||||
|
~MemoryUtils() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
@ -18,8 +18,12 @@ uint32_t * getFromGX2Buffer(struct buffer_store store, uint32_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback, void * args) {
|
void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback, void * args) {
|
||||||
if(callback == NULL) return;
|
if(callback == NULL) {
|
||||||
if(!OSIsHomeButtonMenuEnabled()) return; // This pauses the game. Make sure to only do it when the home button is allowed.
|
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.
|
//TODO: Make sure this actually pauses the game (Hook on GX2VSync?) . Currently only tested from VPADRead which also pauses the game.
|
||||||
|
|
||||||
|
174
src/myutils/texture_utils.cpp
Normal file
174
src/myutils/texture_utils.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <utils/logger.h>
|
||||||
|
#include "texture_utils.h"
|
||||||
|
#include <wups.h>
|
||||||
|
#include <gd.h>
|
||||||
|
#include <dynamic_libs/gx2_functions.h>
|
||||||
|
#include <dynamic_libs/gx2_types.h>
|
||||||
|
#include "mem_utils.h"
|
||||||
|
|
||||||
|
void gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *imgBuffer, u32 width, u32 height, u32 pitch) {
|
||||||
|
for(u32 y = 0; y < height; ++y) {
|
||||||
|
for(u32 x = 0; x < width; ++x) {
|
||||||
|
u32 pixel = gdImageGetPixel(gdImg, x, y);
|
||||||
|
|
||||||
|
u8 a = 254 - 2*((u8)gdImageAlpha(gdImg, pixel));
|
||||||
|
if(a == 254)
|
||||||
|
a++;
|
||||||
|
|
||||||
|
u8 r = gdImageRed(gdImg, pixel);
|
||||||
|
u8 g = gdImageGreen(gdImg, pixel);
|
||||||
|
u8 b = gdImageBlue(gdImg, pixel);
|
||||||
|
|
||||||
|
imgBuffer[y * pitch + x] = (r << 24) | (g << 16) | (b << 8) | (a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TextureUtils::drawTexture(GX2Texture * texture, GX2Sampler* sampler, float x, float y, int32_t width, int32_t height, float alpha = 1.0f) {
|
||||||
|
float widthScaleFactor = 1.0f / (float)1280;
|
||||||
|
float heightScaleFactor = 1.0f / (float)720;
|
||||||
|
|
||||||
|
glm::vec3 positionOffsets = glm::vec3(0.0f);
|
||||||
|
|
||||||
|
positionOffsets[0] = (x-((1280)/2)+(width/2)) * widthScaleFactor * 2.0f;
|
||||||
|
positionOffsets[1] = -(y-((720)/2)+(height/2)) * heightScaleFactor * 2.0f;
|
||||||
|
|
||||||
|
glm::vec3 scale(width*widthScaleFactor,height*heightScaleFactor,1.0f);
|
||||||
|
|
||||||
|
Texture2DShader::instance()->setShaders();
|
||||||
|
Texture2DShader::instance()->setAttributeBuffer();
|
||||||
|
Texture2DShader::instance()->setAngle(0.0f);
|
||||||
|
Texture2DShader::instance()->setOffset(positionOffsets);
|
||||||
|
Texture2DShader::instance()->setScale(scale);
|
||||||
|
Texture2DShader::instance()->setColorIntensity(glm::vec4(alpha));
|
||||||
|
Texture2DShader::instance()->setBlurring(glm::vec3(0.0f));
|
||||||
|
Texture2DShader::instance()->setTextureAndSampler(texture, sampler);
|
||||||
|
Texture2DShader::instance()->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TextureUtils::copyToTexture(GX2ColorBuffer* sourceBuffer, GX2Texture * target) {
|
||||||
|
if(sourceBuffer == NULL || target == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sourceBuffer->surface.aa == GX2_AA_MODE_1X) {
|
||||||
|
// If AA is disabled, we can simply use GX2CopySurface.
|
||||||
|
GX2CopySurface(&sourceBuffer->surface,
|
||||||
|
sourceBuffer->view_mip,
|
||||||
|
sourceBuffer->view_first_slice,
|
||||||
|
&target->surface, 0, 0);
|
||||||
|
GX2DrawDone();
|
||||||
|
} else {
|
||||||
|
// If AA is enabled, we need to resolve the AA buffer.
|
||||||
|
|
||||||
|
// Allocate surface to resolve buffer onto
|
||||||
|
GX2Surface tempSurface;
|
||||||
|
tempSurface = sourceBuffer->surface;
|
||||||
|
tempSurface.aa = GX2_AA_MODE_1X;
|
||||||
|
GX2CalcSurfaceSizeAndAlignment(&tempSurface);
|
||||||
|
|
||||||
|
tempSurface.image_data = MemoryUtils::alloc(
|
||||||
|
tempSurface.image_size,
|
||||||
|
tempSurface.align
|
||||||
|
);
|
||||||
|
if(tempSurface.image_data == NULL) {
|
||||||
|
DEBUG_FUNCTION_LINE("VideoSquoosher: failed to allocate AA surface\n");
|
||||||
|
if(target->surface.image_data != NULL) {
|
||||||
|
MemoryUtils::free(target->surface.image_data);
|
||||||
|
target->surface.image_data = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve, then copy result to target
|
||||||
|
GX2ResolveAAColorBuffer(sourceBuffer,&tempSurface, 0, 0);
|
||||||
|
GX2CopySurface(&tempSurface, 0, 0,&target->surface, 0, 0);
|
||||||
|
|
||||||
|
if(tempSurface.image_data != NULL) {
|
||||||
|
MemoryUtils::free(tempSurface.image_data);
|
||||||
|
tempSurface.image_data = NULL;
|
||||||
|
}
|
||||||
|
GX2DrawDone();
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU, target->surface.image_data, target->surface.image_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureUtils::convertImageToTexture(const uint8_t *img, int32_t imgSize, void * _texture) {
|
||||||
|
if(!img || (imgSize < 8) || _texture == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GX2Texture * texture = (GX2Texture *) _texture;
|
||||||
|
|
||||||
|
gdImagePtr gdImg = 0;
|
||||||
|
|
||||||
|
if (img[0] == 0xFF && img[1] == 0xD8) {
|
||||||
|
//! not needed for now therefore comment out to safe ELF size
|
||||||
|
//! if needed uncomment, adds 200 kb to the ELF size
|
||||||
|
// IMAGE_JPEG
|
||||||
|
gdImg = gdImageCreateFromJpegPtr(imgSize, (uint8_t*) img);
|
||||||
|
} else if (img[0] == 'B' && img[1] == 'M') {
|
||||||
|
// IMAGE_BMP
|
||||||
|
//gdImg = gdImageCreateFromBmpPtr(imgSize, (uint8_t*) img);
|
||||||
|
} else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G') {
|
||||||
|
// IMAGE_PNG
|
||||||
|
gdImg = gdImageCreateFromPngPtr(imgSize, (uint8_t*) img);
|
||||||
|
}
|
||||||
|
//!This must be last since it can also intefere with outher formats
|
||||||
|
else if(img[0] == 0x00) {
|
||||||
|
// Try loading TGA image
|
||||||
|
//gdImg = gdImageCreateFromTgaPtr(imgSize, (uint8_t*) img);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gdImg == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t width = (gdImageSX(gdImg));
|
||||||
|
uint32_t height = (gdImageSY(gdImg));
|
||||||
|
|
||||||
|
//! Initialize texture
|
||||||
|
GX2InitTexture(texture, width, height, 1, 0, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
|
||||||
|
|
||||||
|
//! if this fails something went horribly wrong
|
||||||
|
if(texture->surface.image_size == 0) {
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->surface.image_data = MemoryUtils::alloc(texture->surface.image_size, texture->surface.align);
|
||||||
|
|
||||||
|
//! check if memory is available for image
|
||||||
|
if(!texture->surface.image_data) {
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! set mip map data pointer
|
||||||
|
texture->surface.mip_data = NULL;
|
||||||
|
|
||||||
|
gdImageToUnormR8G8B8A8(gdImg, (uint32_t*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch);
|
||||||
|
|
||||||
|
//! free memory of image as its not needed anymore
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
|
||||||
|
//! invalidate the memory
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, texture->surface.image_data, texture->surface.image_size);
|
||||||
|
return true;
|
||||||
|
}
|
33
src/myutils/texture_utils.h
Normal file
33
src/myutils/texture_utils.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __TEXTURE_UTILS_UTILS_H_
|
||||||
|
#define __TEXTURE_UTILS_UTILS_H_
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <dynamic_libs/gx2_functions.h>
|
||||||
|
#include <video/shaders/Texture2DShader.h>
|
||||||
|
|
||||||
|
class TextureUtils {
|
||||||
|
public:
|
||||||
|
static bool convertImageToTexture(const uint8_t *img, int32_t imgSize, void * texture);
|
||||||
|
static void drawTexture(GX2Texture * texture, GX2Sampler* sampler, float x, float y, int32_t width, int32_t height, float alpha);
|
||||||
|
static void copyToTexture(GX2ColorBuffer* sourceBuffer, GX2Texture * target);
|
||||||
|
private:
|
||||||
|
TextureUtils() {}
|
||||||
|
~TextureUtils() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
@ -8,17 +8,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "mymemory/memory_mapping.h"
|
#include "mymemory/memory_mapping.h"
|
||||||
|
#include <video/shaders/Texture2DShader.h>
|
||||||
DECL(void, __PPCExit, void) {
|
|
||||||
// Only continue if we are in the "right" application.
|
|
||||||
//if(OSGetTitleID() == gGameTitleID) {
|
|
||||||
//DEBUG_FUNCTION_LINE("__PPCExit\n");
|
|
||||||
//CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
|
||||||
//DeInit();
|
|
||||||
//}
|
|
||||||
|
|
||||||
real___PPCExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
DECL(uint32_t, ProcUIProcessMessages, uint32_t u) {
|
DECL(uint32_t, ProcUIProcessMessages, uint32_t u) {
|
||||||
uint32_t res = real_ProcUIProcessMessages(u);
|
uint32_t res = real_ProcUIProcessMessages(u);
|
||||||
@ -29,114 +19,17 @@ DECL(uint32_t, ProcUIProcessMessages, uint32_t u) {
|
|||||||
CallHook(WUPS_LOADER_HOOK_APP_STATUS_CHANGED);
|
CallHook(WUPS_LOADER_HOOK_APP_STATUS_CHANGED);
|
||||||
if(gAppStatus == WUPS_APP_STATUS_CLOSED) {
|
if(gAppStatus == WUPS_APP_STATUS_CLOSED) {
|
||||||
CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
||||||
|
ConfigUtils::saveConfigToSD();
|
||||||
DeInit();
|
DeInit();
|
||||||
|
Texture2DShader::destroyInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t 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, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t 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) {
|
|
||||||
CallHook(WUPS_LOADER_HOOK_VSYNC);
|
|
||||||
real_GX2WaitForVsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t vpadPressCooldown = 0xFF;
|
|
||||||
|
|
||||||
uint8_t angleX_counter = 0;
|
|
||||||
float angleX_delta = 0.0f;
|
|
||||||
float angleX_last = 0.0f;
|
|
||||||
uint8_t angleX_frameCounter = 0;
|
|
||||||
|
|
||||||
bool checkMagic(VPADData *buffer) {
|
|
||||||
// buffer->angle stores the rotations per axis since the app started.
|
|
||||||
// Each full rotation add/subtracts 1.0f (depending on the direction).
|
|
||||||
|
|
||||||
// Check for rotation every only 5 frames.
|
|
||||||
angleX_frameCounter++;
|
|
||||||
if(angleX_frameCounter >= 5) {
|
|
||||||
// Get how much the gamepad rotated within the last 5 frames.
|
|
||||||
float diff_angle = -(buffer->angle.x - angleX_last);
|
|
||||||
// We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row).
|
|
||||||
float target_diff = (0.16f);
|
|
||||||
// Calculate if rotated enough in this step (including the delta from the last step).
|
|
||||||
float total_diff = (diff_angle + angleX_delta) - target_diff;
|
|
||||||
if(total_diff > 0.0f) {
|
|
||||||
// The rotation in this step was enough.
|
|
||||||
angleX_counter++;
|
|
||||||
// When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation!
|
|
||||||
if(angleX_counter > 5) {
|
|
||||||
ConfigUtils::openConfigMenu();
|
|
||||||
// reset stuff.
|
|
||||||
angleX_counter = 0;
|
|
||||||
angleX_delta = 0.0f;
|
|
||||||
} else {
|
|
||||||
// Save difference as it will be added on the next check.
|
|
||||||
angleX_delta = total_diff;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// reset counter if it stopped rotating.
|
|
||||||
angleX_counter = 0;
|
|
||||||
}
|
|
||||||
angleX_frameCounter = 0;
|
|
||||||
angleX_last = buffer->angle.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) {
|
|
||||||
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
|
||||||
|
|
||||||
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
|
||||||
if(MemoryMapping::isMemoryMapped()) {
|
|
||||||
MemoryMapping::readTestValuesFromMemory();
|
|
||||||
} else {
|
|
||||||
DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n");
|
|
||||||
}
|
|
||||||
vpadPressCooldown = 0x3C;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
|
||||||
ConfigUtils::openConfigMenu();
|
|
||||||
vpadPressCooldown = 0x3C;
|
|
||||||
} else if(result > 0 && OSIsHomeButtonMenuEnabled()) {
|
|
||||||
checkMagic(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vpadPressCooldown > 0) {
|
|
||||||
vpadPressCooldown--;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hooks_magic_t method_hooks_hooks[] __attribute__((section(".data"))) = {
|
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(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),
|
|
||||||
MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
340
src/patcher/hooks_patcher_static.cpp
Normal file
340
src/patcher/hooks_patcher_static.cpp
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
#include <utils/logger.h>
|
||||||
|
#include <utils/function_patcher.h>
|
||||||
|
#include <dynamic_libs/vpad_functions.h>
|
||||||
|
#include "common/retain_vars.h"
|
||||||
|
#include "hooks_patcher.h"
|
||||||
|
#include "myutils/overlay_helper.h"
|
||||||
|
#include "myutils/ConfigUtils.h"
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "mymemory/memory_mapping.h"
|
||||||
|
#include "myutils/mem_utils.h"
|
||||||
|
#include "myutils/texture_utils.h"
|
||||||
|
|
||||||
|
DECL(void, __PPCExit, void) {
|
||||||
|
// Only continue if we are in the "right" application.
|
||||||
|
//if(OSGetTitleID() == gGameTitleID) {
|
||||||
|
//DEBUG_FUNCTION_LINE("__PPCExit\n");
|
||||||
|
//CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
||||||
|
//DeInit();
|
||||||
|
//}
|
||||||
|
|
||||||
|
real___PPCExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveCached, uint32_t phyiscalAddress) {
|
||||||
|
uint32_t result = real___OSPhysicalToEffectiveCached(phyiscalAddress);
|
||||||
|
if(result == 0) {
|
||||||
|
result = MemoryMapping::PhysicalToEffective(phyiscalAddress);
|
||||||
|
//DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveCached in %08X out %08X\n",phyiscalAddress,result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveUncached, uint32_t phyiscalAddress) {
|
||||||
|
uint32_t result = real___OSPhysicalToEffectiveUncached(phyiscalAddress);
|
||||||
|
if(result == 0) {
|
||||||
|
result = MemoryMapping::PhysicalToEffective(phyiscalAddress);
|
||||||
|
//DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveUncached in %08X out %08X\n",phyiscalAddress,result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DECL_FUNCTION(uint32_t, OSEffectiveToPhysical, uint32_t virtualAddress) {
|
||||||
|
uint32_t result = real_OSEffectiveToPhysical(virtualAddress);
|
||||||
|
if(result == 0) {
|
||||||
|
result = MemoryMapping::EffectiveToPhysical(virtualAddress);
|
||||||
|
//DEBUG_FUNCTION_LINE("OSEffectiveToPhysical in %08X out %08X\n",virtualAddress,result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(int32_t, OSIsAddressValid, uint32_t virtualAddress) {
|
||||||
|
int32_t result = real_OSIsAddressValid(virtualAddress);
|
||||||
|
if(result == 0) {
|
||||||
|
result = (MemoryMapping::EffectiveToPhysical(virtualAddress) > 0);
|
||||||
|
//DEBUG_FUNCTION_LINE("OSIsAddressValid in %08X out %d\n",virtualAddress,result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t 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, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t 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) {
|
||||||
|
CallHook(WUPS_LOADER_HOOK_VSYNC);
|
||||||
|
real_GX2WaitForVsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t vpadPressCooldown = 0xFF;
|
||||||
|
|
||||||
|
uint8_t angleX_counter = 0;
|
||||||
|
float angleX_delta = 0.0f;
|
||||||
|
float angleX_last = 0.0f;
|
||||||
|
uint8_t angleX_frameCounter = 0;
|
||||||
|
|
||||||
|
void checkMagic(VPADData *buffer) {
|
||||||
|
// buffer->angle stores the rotations per axis since the app started.
|
||||||
|
// Each full rotation add/subtracts 1.0f (depending on the direction).
|
||||||
|
|
||||||
|
// Check for rotation every only 5 frames.
|
||||||
|
angleX_frameCounter++;
|
||||||
|
if(angleX_frameCounter >= 5) {
|
||||||
|
// Get how much the gamepad rotated within the last 5 frames.
|
||||||
|
float diff_angle = -(buffer->angle.x - angleX_last);
|
||||||
|
// We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row).
|
||||||
|
float target_diff = (0.16f);
|
||||||
|
// Calculate if rotated enough in this step (including the delta from the last step).
|
||||||
|
float total_diff = (diff_angle + angleX_delta) - target_diff;
|
||||||
|
if(total_diff > 0.0f) {
|
||||||
|
// The rotation in this step was enough.
|
||||||
|
angleX_counter++;
|
||||||
|
// When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation!
|
||||||
|
if(angleX_counter > 5) {
|
||||||
|
ConfigUtils::openConfigMenu();
|
||||||
|
// reset stuff.
|
||||||
|
angleX_counter = 0;
|
||||||
|
angleX_delta = 0.0f;
|
||||||
|
} else {
|
||||||
|
// Save difference as it will be added on the next check.
|
||||||
|
angleX_delta = total_diff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// reset counter if it stopped rotating.
|
||||||
|
angleX_counter = 0;
|
||||||
|
}
|
||||||
|
angleX_frameCounter = 0;
|
||||||
|
angleX_last = buffer->angle.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) {
|
||||||
|
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
||||||
|
|
||||||
|
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
||||||
|
if(MemoryMapping::isMemoryMapped()) {
|
||||||
|
MemoryMapping::readTestValuesFromMemory();
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n");
|
||||||
|
}
|
||||||
|
vpadPressCooldown = 0x3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
||||||
|
ConfigUtils::openConfigMenu();
|
||||||
|
vpadPressCooldown = 0x3C;
|
||||||
|
} else if(result > 0 && OSIsHomeButtonMenuEnabled()) {
|
||||||
|
checkMagic(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vpadPressCooldown > 0) {
|
||||||
|
vpadPressCooldown--;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupContextState() {
|
||||||
|
g_vid_ownContextState = (GX2ContextState*)memalign(
|
||||||
|
GX2_CONTEXT_STATE_ALIGNMENT,
|
||||||
|
sizeof(GX2ContextState)
|
||||||
|
);
|
||||||
|
if(g_vid_ownContextState == NULL) {
|
||||||
|
OSFatal("VideoSquoosher: Failed to alloc g_vid_ownContextState\n");
|
||||||
|
}
|
||||||
|
GX2SetupContextStateEx(g_vid_ownContextState, 1);
|
||||||
|
|
||||||
|
GX2SetContextState(g_vid_ownContextState);
|
||||||
|
GX2SetColorBuffer(&g_vid_main_cbuf, GX2_RENDER_TARGET_0);
|
||||||
|
//GX2SetDepthBuffer(&tvDepthBuffer);
|
||||||
|
GX2SetContextState(g_vid_originalContextSave);
|
||||||
|
DEBUG_FUNCTION_LINE("Setup contest state done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void initTextures() {
|
||||||
|
GX2InitColorBuffer(&g_vid_main_cbuf,
|
||||||
|
GX2_SURFACE_DIM_2D,
|
||||||
|
1280, 720, 1,
|
||||||
|
GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
|
||||||
|
GX2_AA_MODE_1X
|
||||||
|
);
|
||||||
|
|
||||||
|
if (g_vid_main_cbuf.surface.image_size) {
|
||||||
|
g_vid_main_cbuf.surface.image_data = MemoryUtils::alloc(
|
||||||
|
g_vid_main_cbuf.surface.image_size,
|
||||||
|
g_vid_main_cbuf.surface.align
|
||||||
|
);
|
||||||
|
if(g_vid_main_cbuf.surface.image_data == NULL) {
|
||||||
|
OSFatal("Failed to alloc g_vid_main_cbuf\n");
|
||||||
|
}
|
||||||
|
DEBUG_FUNCTION_LINE("Allocated %dx%d g_vid_main_cbuf %08X\n",
|
||||||
|
g_vid_main_cbuf.surface.width,
|
||||||
|
g_vid_main_cbuf.surface.height,
|
||||||
|
g_vid_main_cbuf.surface.image_data);
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("GX2InitTexture failed for g_vid_main_cbuf!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2InitTexture(&g_vid_drcTex,
|
||||||
|
854, 480, 1, 0,
|
||||||
|
GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
|
||||||
|
GX2_SURFACE_DIM_2D,
|
||||||
|
GX2_TILE_MODE_LINEAR_ALIGNED
|
||||||
|
);
|
||||||
|
g_vid_drcTex.surface.use = (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE);
|
||||||
|
|
||||||
|
if (g_vid_drcTex.surface.image_size) {
|
||||||
|
|
||||||
|
g_vid_drcTex.surface.image_data = MemoryUtils::alloc(
|
||||||
|
g_vid_drcTex.surface.image_size,
|
||||||
|
g_vid_drcTex.surface.align);
|
||||||
|
|
||||||
|
if(g_vid_drcTex.surface.image_data == NULL) {
|
||||||
|
OSFatal("VideoSquoosher: Failed to alloc g_vid_drcTex\n");
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU, g_vid_drcTex.surface.image_data, g_vid_drcTex.surface.image_size);
|
||||||
|
DEBUG_FUNCTION_LINE("VideoSquoosher: allocated %dx%d g_vid_drcTex %08X\n",
|
||||||
|
g_vid_drcTex.surface.width,
|
||||||
|
g_vid_drcTex.surface.height,
|
||||||
|
g_vid_drcTex.surface.image_data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("VideoSquoosher: GX2InitTexture failed for g_vid_drcTex!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2InitTexture(&g_vid_tvTex,
|
||||||
|
1280, 720, 1, 0,
|
||||||
|
GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
|
||||||
|
GX2_SURFACE_DIM_2D,
|
||||||
|
GX2_TILE_MODE_LINEAR_ALIGNED
|
||||||
|
);
|
||||||
|
g_vid_tvTex.surface.use =
|
||||||
|
(GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE);
|
||||||
|
|
||||||
|
DCFlushRange(&g_vid_tvTex, sizeof(GX2Texture));
|
||||||
|
|
||||||
|
if (g_vid_tvTex.surface.image_size) {
|
||||||
|
g_vid_tvTex.surface.image_data = MemoryUtils::alloc(
|
||||||
|
g_vid_tvTex.surface.image_size,
|
||||||
|
g_vid_tvTex.surface.align
|
||||||
|
);
|
||||||
|
if(g_vid_tvTex.surface.image_data == NULL) {
|
||||||
|
OSFatal("VideoSquoosher: Failed to alloc g_vid_tvTex\n");
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU, g_vid_tvTex.surface.image_data, g_vid_tvTex.surface.image_size);
|
||||||
|
DEBUG_FUNCTION_LINE("VideoSquoosher: allocated %dx%d g_vid_tvTex %08X\n",
|
||||||
|
g_vid_tvTex.surface.width,
|
||||||
|
g_vid_tvTex.surface.height,
|
||||||
|
g_vid_tvTex.surface.image_data);
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("VideoSquoosher: GX2InitTexture failed for g_vid_tvTex!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2InitSampler(&g_vid_sampler,
|
||||||
|
GX2_TEX_CLAMP_CLAMP,
|
||||||
|
GX2_TEX_XY_FILTER_BILINEAR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(void, GX2SetContextState, GX2ContextState * curContext) {
|
||||||
|
if(gAppStatus == WUPS_APP_STATUS_FOREGROUND) {
|
||||||
|
g_vid_originalContextSave = curContext;
|
||||||
|
}
|
||||||
|
real_GX2SetContextState(curContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer* cbuf, int32_t target) {
|
||||||
|
bool hasDRCHook = HasHookCallHook(WUPS_LOADER_HOOK_VID_DRC_DRAW);
|
||||||
|
bool hasTVHook = HasHookCallHook(WUPS_LOADER_HOOK_VID_TV_DRAW);
|
||||||
|
if(gAppStatus != WUPS_APP_STATUS_FOREGROUND || !g_NotInLoader || (!hasDRCHook && !hasTVHook)) {
|
||||||
|
return real_GX2CopyColorBufferToScanBuffer(cbuf,target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_vid_drcTex.surface.image_data) {
|
||||||
|
initTextures();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g_vid_ownContextState == NULL) {
|
||||||
|
setupContextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(target == 1) {
|
||||||
|
TextureUtils::copyToTexture(cbuf,&g_vid_tvTex);
|
||||||
|
if(!hasTVHook) {
|
||||||
|
return real_GX2CopyColorBufferToScanBuffer(cbuf,target);
|
||||||
|
}
|
||||||
|
} else if(target == 4) {
|
||||||
|
TextureUtils::copyToTexture(cbuf,&g_vid_drcTex);
|
||||||
|
if(!hasDRCHook) {
|
||||||
|
return real_GX2CopyColorBufferToScanBuffer(cbuf,target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2SetContextState(g_vid_ownContextState);
|
||||||
|
GX2ClearColor(&g_vid_main_cbuf, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
GX2SetContextState(g_vid_ownContextState);
|
||||||
|
|
||||||
|
GX2SetViewport(
|
||||||
|
0.0f, 0.0f,
|
||||||
|
g_vid_main_cbuf.surface.width, g_vid_main_cbuf.surface.height,
|
||||||
|
0.0f, 1.0f
|
||||||
|
);
|
||||||
|
GX2SetScissor(
|
||||||
|
0, 0,
|
||||||
|
g_vid_main_cbuf.surface.width, g_vid_main_cbuf.surface.height
|
||||||
|
);
|
||||||
|
|
||||||
|
if(target == 1) {
|
||||||
|
//drawTexture(&g_vid_tvTex, &g_vid_sampler, 0, 0, 1280, 720, 1.0f);
|
||||||
|
CallHook(WUPS_LOADER_HOOK_VID_TV_DRAW);
|
||||||
|
} else if(target == 4) {
|
||||||
|
//drawTexture(&g_vid_drcTex, &g_vid_sampler, 0, 0, 1280, 720, 1.0f);
|
||||||
|
CallHook(WUPS_LOADER_HOOK_VID_DRC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2SetContextState(g_vid_originalContextSave);
|
||||||
|
|
||||||
|
return real_GX2CopyColorBufferToScanBuffer(&g_vid_main_cbuf,target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {
|
||||||
|
MAKE_MAGIC(__PPCExit, LIB_CORE_INIT, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION),
|
||||||
|
MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION),
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t);
|
||||||
|
|
||||||
|
//! buffer to store our instructions needed for our replacements
|
||||||
|
volatile uint32_t method_calls_hooks_static[sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t) * FUNCTION_PATCHER_METHOD_STORE_SIZE] __attribute__((section(".data")));
|
||||||
|
|
18
src/patcher/hooks_patcher_static.h
Normal file
18
src/patcher/hooks_patcher_static.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _HOOKS_STATIC_FUNCTION_PATCHER_H
|
||||||
|
#define _HOOKS_STATIC_FUNCTION_PATCHER_H
|
||||||
|
|
||||||
|
#include <utils/function_patcher.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern hooks_magic_t method_hooks_hooks_static[];
|
||||||
|
extern uint32_t method_hooks_size_hooks_static;
|
||||||
|
extern volatile uint32_t method_calls_hooks_static[];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _HOOKS_STATIC_FUNCTION_PATCHER_H */
|
@ -81,14 +81,14 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DynamicLinkingHelper() {
|
DynamicLinkingHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
~DynamicLinkingHelper() {
|
~DynamicLinkingHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DynamicLinkingHelper *instance;
|
static DynamicLinkingHelper *instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DYNAMICLINKINGHELPER_H
|
#endif // DYNAMICLINKINGHELPER_H
|
||||||
|
@ -272,7 +272,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
|||||||
uint32_t size = symtab[symbol].st_size;
|
uint32_t size = symtab[symbol].st_size;
|
||||||
|
|
||||||
uint32_t address = pluginData->getMemoryForCommonBySymbol(symbol, align, size);
|
uint32_t address = pluginData->getMemoryForCommonBySymbol(symbol, align, size);
|
||||||
if(address == 0){
|
if(address == 0) {
|
||||||
DEBUG_FUNCTION_LINE("Failed to get memory for common relocation\n");
|
DEBUG_FUNCTION_LINE("Failed to get memory for common relocation\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -494,7 +494,8 @@ bool ElfTools::elfLinkOne(char type, size_t offset, int32_t addend, void *destin
|
|||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
exit_error:
|
exit_error:
|
||||||
if (!result) DEBUG_FUNCTION_LINE("Plugin_ElfLinkOne: exit_error\n");
|
if (!result)
|
||||||
|
DEBUG_FUNCTION_LINE("Plugin_ElfLinkOne: exit_error\n");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(dfd != NULL){
|
if(dfd != NULL) {
|
||||||
closedir(dfd);
|
closedir(dfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
|
|||||||
|
|
||||||
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
||||||
|
|
||||||
#warning TODO: add GUI option to let the user choose
|
#warning TODO: add GUI option to let the user choose
|
||||||
plugin_data->kernel_allowed = true;
|
plugin_data->kernel_allowed = true;
|
||||||
plugin_data->kernel_init_done = false;
|
plugin_data->kernel_init_done = false;
|
||||||
|
|
||||||
|
@ -54,25 +54,26 @@ extern const uint32_t switchIconOn_png_size;
|
|||||||
extern const uint8_t TwitterIcon_png[];
|
extern const uint8_t TwitterIcon_png[];
|
||||||
extern const uint32_t TwitterIcon_png_size;
|
extern const uint32_t TwitterIcon_png_size;
|
||||||
|
|
||||||
static ResourceFile ResourceList[] =
|
static ResourceFile ResourceList[] = {
|
||||||
{
|
{"font.ttf", font_ttf, font_ttf_size, NULL, 0},
|
||||||
{"font.ttf", font_ttf, font_ttf_size, NULL, 0},
|
{"gameSettingsButton.png", gameSettingsButton_png, gameSettingsButton_png_size, NULL, 0},
|
||||||
{"gameSettingsButton.png", gameSettingsButton_png, gameSettingsButton_png_size, NULL, 0},
|
{"gameSettingsButtonEx.png", gameSettingsButtonEx_png, gameSettingsButtonEx_png_size, NULL, 0},
|
||||||
{"gameSettingsButtonEx.png", gameSettingsButtonEx_png, gameSettingsButtonEx_png_size, NULL, 0},
|
{"gameSettingsButtonExHighlighted.png", gameSettingsButtonExHighlighted_png, gameSettingsButtonExHighlighted_png_size, NULL, 0},
|
||||||
{"gameSettingsButtonExHighlighted.png", gameSettingsButtonExHighlighted_png, gameSettingsButtonExHighlighted_png_size, NULL, 0},
|
{"gameSettingsButtonExSelected.png", gameSettingsButtonExSelected_png, gameSettingsButtonExSelected_png_size, NULL, 0},
|
||||||
{"gameSettingsButtonExSelected.png", gameSettingsButtonExSelected_png, gameSettingsButtonExSelected_png_size, NULL, 0},
|
{"gameSettingsButtonSelected.png", gameSettingsButtonSelected_png, gameSettingsButtonSelected_png_size, NULL, 0},
|
||||||
{"gameSettingsButtonSelected.png", gameSettingsButtonSelected_png, gameSettingsButtonSelected_png_size, NULL, 0},
|
{"GithubIcon.png", GithubIcon_png, GithubIcon_png_size, NULL, 0},
|
||||||
{"GithubIcon.png", GithubIcon_png, GithubIcon_png_size, NULL, 0},
|
{"HomeButtonIcon.png", HomeButtonIcon_png, HomeButtonIcon_png_size, NULL, 0},
|
||||||
{"HomeButtonIcon.png", HomeButtonIcon_png, HomeButtonIcon_png_size, NULL, 0},
|
{"PlusButtonIcon.png", PlusButtonIcon_png, PlusButtonIcon_png_size, NULL, 0},
|
||||||
{"PlusButtonIcon.png", PlusButtonIcon_png, PlusButtonIcon_png_size, NULL, 0},
|
{"settings_click_2.mp3", settings_click_2_mp3, settings_click_2_mp3_size, NULL, 0},
|
||||||
{"settings_click_2.mp3", settings_click_2_mp3, settings_click_2_mp3_size, NULL, 0},
|
{"switchIconBase.png", switchIconBase_png, switchIconBase_png_size, NULL, 0},
|
||||||
{"switchIconBase.png", switchIconBase_png, switchIconBase_png_size, NULL, 0},
|
{"switchIconBaseHighlighted.png", switchIconBaseHighlighted_png, switchIconBaseHighlighted_png_size, NULL, 0},
|
||||||
{"switchIconBaseHighlighted.png", switchIconBaseHighlighted_png, switchIconBaseHighlighted_png_size, NULL, 0},
|
{"switchIconOff.png", switchIconOff_png, switchIconOff_png_size, NULL, 0},
|
||||||
{"switchIconOff.png", switchIconOff_png, switchIconOff_png_size, NULL, 0},
|
{"switchIconOn.png", switchIconOn_png, switchIconOn_png_size, NULL, 0},
|
||||||
{"switchIconOn.png", switchIconOn_png, switchIconOn_png_size, NULL, 0},
|
{"TwitterIcon.png", TwitterIcon_png, TwitterIcon_png_size, NULL, 0},
|
||||||
{"TwitterIcon.png", TwitterIcon_png, TwitterIcon_png_size, NULL, 0},
|
{NULL, NULL, 0, NULL, 0}
|
||||||
{NULL, NULL, 0, NULL, 0}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ResourceFile * getResourceList(){ return ResourceList; }
|
ResourceFile * getResourceList() {
|
||||||
|
return ResourceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ bool ConfigSettings::Reset() {
|
|||||||
this->SetDefault();
|
this->SetDefault();
|
||||||
bChanged = true;
|
bChanged = true;
|
||||||
|
|
||||||
if (this->Save()) {
|
if (this->Save(true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,8 +197,8 @@ int32_t ConfigSettings::getIdByName(std::string configID) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigSettings::Save() {
|
bool ConfigSettings::Save(bool force) {
|
||||||
if(!bChanged) {
|
if(!force && !bChanged) {
|
||||||
DEBUG_FUNCTION_LINE("Nothing has changed, we can skip\n");
|
DEBUG_FUNCTION_LINE("Nothing has changed, we can skip\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
//!Load Settings
|
//!Load Settings
|
||||||
bool Load();
|
bool Load();
|
||||||
//!Save Settings
|
//!Save Settings
|
||||||
bool Save();
|
bool Save(bool force);
|
||||||
//!Reset Settings
|
//!Reset Settings
|
||||||
bool Reset();
|
bool Reset();
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ public:
|
|||||||
|
|
||||||
int32_t getIdByName(std::string configID);
|
int32_t getIdByName(std::string configID);
|
||||||
|
|
||||||
bool hasChanged(){
|
bool hasChanged() {
|
||||||
return bChanged;
|
return bChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/retain_vars.h"
|
#include "common/retain_vars.h"
|
||||||
#include "myutils/overlay_helper.h"
|
#include "myutils/overlay_helper.h"
|
||||||
|
#include "myutils/mem_utils.h"
|
||||||
|
#include "myutils/texture_utils.h"
|
||||||
#include "kernel/syscalls.h"
|
#include "kernel/syscalls.h"
|
||||||
|
|
||||||
void CallHook(wups_loader_hook_type_t hook_type) {
|
void CallHook(wups_loader_hook_type_t hook_type) {
|
||||||
@ -23,13 +25,28 @@ void CallHook(wups_loader_hook_type_t hook_type) {
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
// Part of libutils
|
// Part of libutils
|
||||||
extern uint32_t kern_read(const void *addr);
|
extern uint32_t kern_read(const void *addr);
|
||||||
extern void kern_write(void *addr, uint32_t value);
|
extern void kern_write(void *addr, uint32_t value);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool HasHookCallHook(wups_loader_hook_type_t hook_type) {
|
||||||
|
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
||||||
|
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
||||||
|
|
||||||
|
for(int32_t j=0; j<plugin_data->number_used_hooks; j++) {
|
||||||
|
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
|
||||||
|
if(hook_data->type == hook_type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) {
|
void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) {
|
||||||
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
||||||
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
||||||
@ -37,13 +54,13 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning TODO: change the order of the wups_loader_hook_type_t enum before an offical release.
|
#warning TODO: change the order of the wups_loader_hook_type_t enum before an offical release.
|
||||||
//DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name);
|
//DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name);
|
||||||
//DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks);
|
//DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks);
|
||||||
for(int32_t j=0; j<plugin_data->number_used_hooks; j++) {
|
for(int32_t j=0; j<plugin_data->number_used_hooks; j++) {
|
||||||
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
|
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
|
||||||
if(hook_data->type == hook_type) {
|
if(hook_data->type == hook_type) {
|
||||||
DEBUG_FUNCTION_LINE("Calling hook of type %d for plugin %s\n",hook_data->type,plugin_data->plugin_name);
|
//DEBUG_FUNCTION_LINE("Calling hook of type %d for plugin %s\n",hook_data->type,plugin_data->plugin_name);
|
||||||
void * func_ptr = hook_data->func_pointer;
|
void * func_ptr = hook_data->func_pointer;
|
||||||
//TODO: Switch cases depending on arguments etc.
|
//TODO: Switch cases depending on arguments etc.
|
||||||
// Adding arguments!
|
// Adding arguments!
|
||||||
@ -66,6 +83,8 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed)
|
|||||||
} else if(hook_type == WUPS_LOADER_HOOK_INIT_OVERLAY) {
|
} else if(hook_type == WUPS_LOADER_HOOK_INIT_OVERLAY) {
|
||||||
wups_loader_init_overlay_args_t args;
|
wups_loader_init_overlay_args_t args;
|
||||||
args.overlayfunction_ptr = &overlay_helper;
|
args.overlayfunction_ptr = &overlay_helper;
|
||||||
|
args.textureconvertfunction_ptr = &TextureUtils::convertImageToTexture;
|
||||||
|
args.drawtexturefunction_ptr = (void (*)(void*,void*,float,float,int32_t,int32_t,float)) &TextureUtils::drawTexture;
|
||||||
((void (*)(wups_loader_init_overlay_args_t))((uint32_t*)func_ptr) )(args);
|
((void (*)(wups_loader_init_overlay_args_t))((uint32_t*)func_ptr) )(args);
|
||||||
} else if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) {
|
} else if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) {
|
||||||
((void (*)(void))((uint32_t*)func_ptr) )();
|
((void (*)(void))((uint32_t*)func_ptr) )();
|
||||||
@ -80,7 +99,7 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed)
|
|||||||
if(gSDInitDone & WUPS_USB_MOUNTED) {
|
if(gSDInitDone & WUPS_USB_MOUNTED) {
|
||||||
args.usb_mounted = true;
|
args.usb_mounted = true;
|
||||||
}
|
}
|
||||||
if(plugin_data->kernel_allowed && plugin_data->kernel_init_done){
|
if(plugin_data->kernel_allowed && plugin_data->kernel_init_done) {
|
||||||
args.kernel_access = true;
|
args.kernel_access = true;
|
||||||
}
|
}
|
||||||
((void (*)(wups_loader_app_started_args_t))((uint32_t*)func_ptr) )(args);
|
((void (*)(wups_loader_app_started_args_t))((uint32_t*)func_ptr) )(args);
|
||||||
@ -102,9 +121,9 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed)
|
|||||||
status = WUPS_APP_STATUS_UNKNOWN;
|
status = WUPS_APP_STATUS_UNKNOWN;
|
||||||
}
|
}
|
||||||
((void (*)(wups_loader_app_status_t))((uint32_t*)func_ptr))(status);
|
((void (*)(wups_loader_app_status_t))((uint32_t*)func_ptr))(status);
|
||||||
} else if(hook_type == WUPS_LOADER_HOOK_INIT_KERNEL){
|
} else if(hook_type == WUPS_LOADER_HOOK_INIT_KERNEL) {
|
||||||
// Only call the hook if kernel is allowed.
|
// Only call the hook if kernel is allowed.
|
||||||
if(plugin_data->kernel_allowed){
|
if(plugin_data->kernel_allowed) {
|
||||||
wups_loader_init_kernel_args_t args;
|
wups_loader_init_kernel_args_t args;
|
||||||
args.kern_read_ptr = &kern_read;
|
args.kern_read_ptr = &kern_read;
|
||||||
args.kern_write_ptr = &kern_write;
|
args.kern_write_ptr = &kern_write;
|
||||||
@ -112,6 +131,25 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed)
|
|||||||
((void (*)(wups_loader_init_kernel_args_t))((uint32_t*)func_ptr) )(args);
|
((void (*)(wups_loader_init_kernel_args_t))((uint32_t*)func_ptr) )(args);
|
||||||
plugin_data->kernel_init_done = true;
|
plugin_data->kernel_init_done = true;
|
||||||
}
|
}
|
||||||
|
} else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM) {
|
||||||
|
wups_loader_init_vid_mem_args_t args;
|
||||||
|
args.vid_mem_alloc_ptr = &MemoryUtils::alloc;
|
||||||
|
args.vid_mem_free_ptr = &MemoryUtils::free;
|
||||||
|
((void (*)(wups_loader_init_vid_mem_args_t))((uint32_t*)func_ptr) )(args);
|
||||||
|
} else if(hook_type == WUPS_LOADER_HOOK_VID_DRC_DRAW) {
|
||||||
|
wups_loader_vid_buffer_t args;
|
||||||
|
args.color_buffer_ptr = &g_vid_main_cbuf;
|
||||||
|
args.tv_texture_ptr = &g_vid_tvTex;
|
||||||
|
args.drc_texture_ptr = &g_vid_drcTex;
|
||||||
|
args.sampler_ptr = &g_vid_sampler;
|
||||||
|
((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args);
|
||||||
|
} else if(hook_type == WUPS_LOADER_HOOK_VID_TV_DRAW) {
|
||||||
|
wups_loader_vid_buffer_t args;
|
||||||
|
args.color_buffer_ptr = &g_vid_main_cbuf;
|
||||||
|
args.tv_texture_ptr = &g_vid_tvTex;
|
||||||
|
args.drc_texture_ptr = &g_vid_drcTex;
|
||||||
|
args.sampler_ptr = &g_vid_sampler;
|
||||||
|
((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args);
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type);
|
DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ extern "C" {
|
|||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
bool HasHookCallHook(wups_loader_hook_type_t hook_type);
|
||||||
void CallHook(wups_loader_hook_type_t hook_type);
|
void CallHook(wups_loader_hook_type_t hook_type);
|
||||||
|
|
||||||
void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed);
|
void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed);
|
||||||
|
Loading…
Reference in New Issue
Block a user