From 0d1384fc5955480b510b537a52aeed4e3eb58fdb Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 25 Dec 2021 20:22:54 +0100 Subject: [PATCH] first commit --- .github/workflows/ci.yml | 58 ++++++++++++++++ .github/workflows/pr.yml | 17 +++++ .gitignore | 9 +++ Dockerfile | 3 + Makefile | 138 +++++++++++++++++++++++++++++++++++++++ README.md | 28 ++++++++ source/crt.c | 36 ++++++++++ source/crt0.s | 29 ++++++++ source/main.cpp | 51 +++++++++++++++ 9 files changed, 369 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 README.md create mode 100644 source/crt.c create mode 100644 source/crt0.s create mode 100644 source/main.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..bb323ff --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI-Release + +on: + push: + branches: + - main + +jobs: + build-binary: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: build binary + run: | + docker build . -t builder + docker run --rm -v ${PWD}:/project builder make + - uses: actions/upload-artifact@master + with: + name: binary + path: "*.rpx" + deploy-binary: + needs: build-binary + runs-on: ubuntu-18.04 + steps: + - name: Get environment variables + id: get_repository_name + run: | + echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//") >> $GITHUB_ENV + echo DATETIME=$(echo $(date '+%Y%m%d-%H%M%S')) >> $GITHUB_ENV + - uses: actions/download-artifact@master + with: + name: binary + path: / + - name: zip artifact + run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip wiiu + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }} + release_name: Nightly-${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }} + draft: false + prerelease: true + body: | + Not a stable release: + ${{ github.event.head_commit.message }} + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps + asset_path: ./${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip + asset_name: ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip + asset_content_type: application/unknown \ No newline at end of file diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..f907f7e --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,17 @@ +name: CI-PR + +on: [pull_request] + +jobs: + build-binary: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: build binary + run: | + docker build . -t builder + docker run --rm -v ${PWD}:/project builder make + - uses: actions/upload-artifact@master + with: + name: binary + path: "*.rpx" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7432917 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.elf +*.rpx +build/ +*.cbp +*.layout +*_syms.h +cmake-build-debug/ +.idea/ +CMakeLists.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1fcc684 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM wiiuenv/devkitppc:20211106 + +WORKDIR project \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..de69f31 --- /dev/null +++ b/Makefile @@ -0,0 +1,138 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) + +include $(DEVKITPRO)/wut/share/wut_rules + +#------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#------------------------------------------------------------------------------- +TARGET := 90_launch_installer +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#------------------------------------------------------------------------------- +# options for code generation +#------------------------------------------------------------------------------- +CFLAGS := -g -Wall -O2 -ffunction-sections \ + $(MACHDEP) + +CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ + +CXXFLAGS := $(CFLAGS) + +ASFLAGS := -g $(ARCH) -mregnames +LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map) + +LIBS := -lwut + +#------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level +# containing include and lib +#------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) + + +#------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#------------------------------------------------------------------------------- + export LD := $(CC) +#------------------------------------------------------------------------------- +else +#------------------------------------------------------------------------------- + export LD := $(CXX) +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean all + +#------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) -j1 --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf + +#------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#------------------------------------------------------------------------------- +# main targets +#------------------------------------------------------------------------------- +all : $(OUTPUT).rpx + +$(OUTPUT).rpx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +$(OFILES_SRC) : $(HFILES_BIN) + +#------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +#--------------------------------------------------------------------------------- +%.o: %.s + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) + +-include $(DEPENDS) + +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..3acf8ad --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# LaunchInstaller + +## Usage +Place the `90_launch_installer.rpx` in the `[ENVIROMENT]/modules/setup` folder and run the [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader). +Requires [MochaPayload](https://github.com/wiiu-env/MochaPayload) as a setup module in `[ENVIROMENT]/modules/setup`. +Will automatically launch `sd:/wiiu/apps/payload_loader_installer.rpx` + +## Building + +For building you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command. + +## Building using the Dockerfile + +It's possible to use a docker image for building. This way you don't need anything installed on your host system. + +``` +# Build docker image (only needed once) +docker build . -t launchinstaller-builder + +# make +docker run -it --rm -v ${PWD}:/project launchinstaller-builder make + +# make clean +docker run -it --rm -v ${PWD}:/project launchinstaller-builder make clean +``` + +## Credits +Maschell \ No newline at end of file diff --git a/source/crt.c b/source/crt.c new file mode 100644 index 0000000..2fcd925 --- /dev/null +++ b/source/crt.c @@ -0,0 +1,36 @@ +void __init_wut_malloc(); + +void __init_wut_newlib(); + +void __init_wut_stdcpp(); + +void __init_wut_devoptab(); + +void __attribute__((weak)) __init_wut_socket(); + +void __fini_wut_malloc(); + +void __fini_wut_newlib(); + +void __fini_wut_stdcpp(); + +void __fini_wut_devoptab(); + +void __attribute__((weak)) __fini_wut_socket(); + +void __attribute__((weak)) +__init_wut_() { + __init_wut_malloc(); + __init_wut_newlib(); + __init_wut_stdcpp(); + __init_wut_devoptab(); + if (&__init_wut_socket) __init_wut_socket(); +} + +void __attribute__((weak)) +__fini_wut_() { + __fini_wut_devoptab(); + __fini_wut_stdcpp(); + __fini_wut_newlib(); + __fini_wut_malloc(); +} diff --git a/source/crt0.s b/source/crt0.s new file mode 100644 index 0000000..318de30 --- /dev/null +++ b/source/crt0.s @@ -0,0 +1,29 @@ +.extern main +.extern exit +.extern __init_wut_ +.extern __fini_wut_ + +.global _start +_start: + stwu 1, -0x28(1) + mflr 0 + stw 0, 0x2C(1) + stw 31, 0x24(1) + or 31, 1, 1 + stw 3, 0x18(31) + stw 4, 0x1C(31) + bl __init_wut_ + lwz 4, 0x1C(31) + lwz 3, 0x18(31) + bl main + or 9, 3, 3 + stw 9, 0x8(31) + bl __fini_wut_ + lwz 9, 0x8(31) + or 3, 9, 9 + addi 11, 31, 0x28 + lwz 0, 0x4(11) + mtlr 0 + lwz 31, -0x4(11) + or 1, 11, 11 + blr \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp new file mode 100644 index 0000000..625759a --- /dev/null +++ b/source/main.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +typedef struct __attribute((packed)) { + uint32_t command; + uint32_t target; + uint32_t filesize; + uint32_t fileoffset; + char path[256]; +} LOAD_REQUEST; + +extern "C" void _SYSLaunchTitleWithStdArgsInNoSplash(uint64_t, int); +extern "C" void OSRestartGame(); + +int main(int argc, char **argv) { + LOAD_REQUEST request; + memset(&request, 0, sizeof(request)); + + request.command = 0xFC; // IPC_CUSTOM_LOAD_CUSTOM_RPX; + request.target = 0; // LOAD_FILE_TARGET_SD_CARD + request.filesize = 0; // unknown filesize + request.fileoffset = 0; // + request.path[0] = '\0'; + + strncat(request.path, "/wiiu/apps/payload_loader_installer.rpx", sizeof(request.path) - 1); + DCFlushRange(&request, sizeof(LOAD_REQUEST)); + + int mcpFd = IOS_Open("/dev/mcp", (IOSOpenMode) 0); + if (mcpFd >= 0) { + int out = 0; + IOS_Ioctl(mcpFd, 100, &request, sizeof(request), &out, sizeof(out)); + + int in = 0xFA; // IPC_CUSTOM_START_USB_LOGGING + IOS_Ioctl(mcpFd, 100, &in, sizeof(in), &out, sizeof(out)); + + IOS_Close(mcpFd); + } + + uint64_t titleID = _SYSGetSystemApplicationTitleId(SYSTEM_APP_ID_HEALTH_AND_SAFETY); + if( OSGetTitleID() == titleID){ + OSRestartGame(); + } else { + _SYSLaunchTitleWithStdArgsInNoSplash(titleID, 0); + } + + return 0; +}