From b88bf159ac81666001b374a413f181f56e1fac6b Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 30 Jun 2018 13:42:02 +0200 Subject: [PATCH] First commit! Have fun! --- .gitignore | 2 + .travis.yml | 65 ++++++++ Makefile | 300 +++++++++++++++++++++++++++++++++++ README.md | 27 ++++ makefile.mk | 66 ++++++++ src/common/c_retain_vars.cpp | 24 +++ src/common/c_retain_vars.h | 27 ++++ src/function_patcher.cpp | 119 ++++++++++++++ src/main.cpp | 154 ++++++++++++++++++ src/utils/voice_info.h | 30 ++++ src/utils/voice_swapper.cpp | 65 ++++++++ src/utils/voice_swapper.h | 34 ++++ 12 files changed, 913 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 Makefile create mode 100644 README.md create mode 100644 makefile.mk create mode 100644 src/common/c_retain_vars.cpp create mode 100644 src/common/c_retain_vars.h create mode 100644 src/function_patcher.cpp create mode 100644 src/main.cpp create mode 100644 src/utils/voice_info.h create mode 100644 src/utils/voice_swapper.cpp create mode 100644 src/utils/voice_swapper.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb82516 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/* +*.mod \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3aa05ab --- /dev/null +++ b/.travis.yml @@ -0,0 +1,65 @@ +language: cpp +os: linux +sudo: false +dist: trusty +branches: + only: + - master +env: + global: + - DEVKITPRO=/opt/devkitpro + - WUT_ROOT=/opt/devkitpro/wut + - DEVKITPPC=/opt/devkitpro/devkitPPC + - PORTLIBREPOS=$HOME/portlibrepos +cache: + directories: + - "$HOME/.local" + - "$DEVKITPRO" +addons: + apt: + packages: + - p7zip-full +before_install: +- mkdir -p "${PORTLIBREPOS}" +- mkdir -p "${DEVKITPRO}" +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb + -O /tmp/devkitpro-pacman.deb; fi +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg -i /tmp/devkitpro-pacman.deb; + fi +- yes | sudo dkp-pacman -Syu devkitPPC --needed +- yes | sudo dkp-pacman -Syu general-tools --needed +- wget https://github.com/decaf-emu/wut/releases/download/1.0.0-beta/wut.linux64.7z +install: +- 7z x -y $(ls | grep "linux") -o${WUT_ROOT} +- cd $PORTLIBREPOS +- git clone https://github.com/Maschell/WiiUPluginSystem.git +- git clone https://github.com/Maschell/libutils.git -b wut +- cd WiiUPluginSystem +- make && make install +- cd $PORTLIBREPOS +- cd libutils +- mkdir build && cd build +- cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$WUT_ROOT ../ +- make install +- cd $PORTLIBREPOS +before_script: +- cd $TRAVIS_BUILD_DIR/ +script: +- make -j8 +before_deploy: +- cd $TRAVIS_BUILD_DIR/ +- mkdir -p "wiiu/plugins" +- commit="$(git rev-parse --short=7 HEAD)" +- find -type f -name "*.mod" | xargs -i cp {} wiiu/plugins +- zip -r swipswapme_nightly_$commit.zip wiiu +- git config --local user.name "Maschell" +- git config --local user.email "Maschell@gmx.de" +- git tag "SwipSwapMe-$(date +'%Y%m%d%H%M%S')-$(git log --format=%h -1)" +deploy: + provider: releases + skip_cleanup: true + api_key: + secure: Gqu3sySILamrn1sY2Hcr32DHHXHvffzPg6uIR9gsJxMLReZT+OU4x9Pys88epPqpQCAnwbmoJYDSBrUTAumfwLxBeBv4FzySL87Ztbv9JLIvOakwNAi0d0dAtHYl7D/+2JlU57pY2CYK/k/Y/kKz0WswAi2QYZ68uY028l+2dc5a2y4L06ZMqbd3xWIzBGxgyJurmMXrHGdsiLz+2WEbDf/9dSuBrwjqGC5StfmupOwZVIBivZgrQz/g9Y8snK4FDPuR2eLOZKxas1QxcjFKI5hWlex/oHpxD41Zy5DyfawvgZU3YmScCJs/BzaOBkEs3boHbC199ppHCB0fl/GFgHdlmVmjdKOKJhuhRbj5zLKoEem0ujFi6MQF+OBHdEFhgpqC+CWuz+HZR3M/2p/e90W/0ZJOhWpWUWaIFLnQJ3abXAbd0oqnqJCbPZI5m7z+N/cNjGAJg/AQqYi/ophT4+Nh+9zNcDRtOwY8eQsYXKMCGOiaP/84LaO708TJQJFpY2GScorVrCWdFW/BPOU/RICLdKlBP6ljaMsC+TYFlJv1VRAh2+gLC8kNO5tdG6oNMYHgAPTGS45AHhIJNSiUOL0DhuTbrFEHVsae8uzmMdgxnQQVMRf17UVr7t5Dsap2CdD36eZspbPjmin4xFfaUxPoUoVrfwaSPpsWQJH+vYA= + file: swipswapme_nightly_$commit.zip + on: + repo: Maschell/SwipSwapMe diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd480be --- /dev/null +++ b/Makefile @@ -0,0 +1,300 @@ +# You probably never need to adjust this Makefile. +# All changes can be done in the makefile.mk + +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif + +export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) +export PORTLIBS := $(DEVKITPRO)/portlibs/ppc +export WUPSDIR := $(DEVKITPRO)/wups +export GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion) + +PREFIX := powerpc-eabi- + +export AS := $(PREFIX)as +export CC := $(PREFIX)gcc +export CXX := $(PREFIX)g++ +export LD := $(PREFIX)ld +export AR := $(PREFIX)ar +export OBJCOPY := $(PREFIX)objcopy + +#--------------------------------------------------------------------------------- +# 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 +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build + +ifeq ($(notdir $(CURDIR)),$(BUILD)) + include ../makefile.mk +else + include makefile.mk +endif + +include $(WUPSDIR)/plugin_makefile.mk + + +#MAP ?= $(TARGET:.mod=.map) + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +# -Os: optimise size +# -Wall: generate lots of warnings +# -D__wiiu__: define the symbol __wiiu__ (used in some headers) +# -mcpu=750: enable processor specific compilation +# -meabi: enable eabi specific compilation +# -mhard-float: enable hardware floating point instructions +# -nostartfiles: Do not use the standard system startup files when linking +# -ffunction-sections: split up functions so linker can garbage collect +# -fdata-sections: split up data so linker can garbage collect +COMMON_CFLAGS := -Os -Wall -mcpu=750 -meabi -mhard-float -D__WIIU__ -nostartfiles -ffunction-sections -fdata-sections -Wl,-q $(COMMON_CFLAGS) + +# -x c: compile as c code +# -std=c11: use the c11 standard +CFLAGS := $(COMMON_CFLAGS) -x c -std=gnu11 $(CFLAGS) + +# -x c: compile as c++ code +# -std=gnu++11: use the c++11 standard +CXXFLAGS := $(COMMON_CFLAGS) -x c++ -std=gnu++11 $(CXXFLAGS) + +ifeq ($(DO_LOGGING), 1) + CFLAGS += -D__LOGGING__ + CXXFLAGS += -D__LOGGING__ +endif + +#--------------------------------------------------------------------------------- +# any extra ld flags +#-------------------------------------------------------------------------------- +# --gc-sections: remove unneeded symbols +# -Map: generate a map file +LDFLAGS += -Wl,-Map,$(notdir $@).map,--gc-sections + + +#--------------------------------------------------------------------------------- +Q := @ +MAKEFLAGS += --no-print-directory +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS += +# +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS += + +NEEDS_WUT := 0 + +ifeq ($(WUT_ENABLE_CPP), 1) + WUT_ENABLE_NEWLIB := 1 + + LDFLAGS += -Wl,-whole-archive,-lwutstdc++,-no-whole-archive + NEEDS_WUT := 1 +endif + +ifeq ($(WUT_ENABLE_NEWLIB), 1) + LDFLAGS += -Wl,-whole-archive,-lwutnewlib,-no-whole-archive + NEEDS_WUT := 1 +endif + +ifeq ($(WUT_DEFAULT_MALLOC), 1) + LDFLAGS += -Wl,-whole-archive,-lwutmalloc,-no-whole-archive + NEEDS_WUT := 1 +endif + +ifeq ($(NEEDS_WUT), 1) + ifeq ($(strip $(WUT_ROOT)),) + $(error "Please set WUT_ROOT in your environment. export WUT_ROOT=wut) + endif + CFLAGS += -D__WUT__ + CXXFLAGS += -D__WUT__ +endif + +#--------------------------------------------------------------------------------- +# 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 PROJECTDIR := $(CURDIR) +export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export REAL_LD := $(CC) +else + export REAL_LD := $(CXX) +endif + +export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE_FULL += $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(EXTERNAL_INCLUDE) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS_FULL += $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + $(EXTERNAL_LIBPATHS) + + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean install + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).mod $(OUTPUT) + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +############################################################################### +# Rule to make everything. +PHONY += all + +all : $(OUTPUT) +############################################################################### +# Special build rules + + +# Rule to make the module file. +$(OUTPUT) : $(OFILES) + @echo "linking ... " $@ + @$(REAL_LD) $(OFILES) $(LDFLAGS) $(LIBS) $(LIBPATHS_FULL) -o $@ + +############################################################################### +# Standard build rules +#--------------------------------------------------------------------------------- +%.a: +#--------------------------------------------------------------------------------- + @echo $(notdir $@) + @rm -f $@ + @$(AR) -rc $@ $^ + +#--------------------------------------------------------------------------------- +%.o: %.cpp + @echo $(notdir $<) + @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.c + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.S + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(INCLUDE_FULL) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.png.o : %.png + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.wav.o : %.wav + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.mp3.o : %.mp3 + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ogg.o : %.ogg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +############################################################################### +# Assembly listing rules + +# Rule to make assembly listing. +PHONY += list +list : $(LIST) + +# Rule to make the listing file. +%.list : $(TARGET) + $(LOG) + -$Qmkdir -p $(dir $@) + $Q$(OBJDUMP) -d $< > $@ + +############################################################################### +# Clean rule + +# Rule to clean files. +PHONY += clean +clean : + $Qrm -rf $(wildcard $(BUILD) $(BIN)) + +############################################################################### +# Phony targets + +.PHONY : $(PHONY) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..72f4d9c --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# SwipSwapMe Plugin for the Wii U Plugin System + +This little app can be used to swap the TV and DRC screen. + +# Wii U Plugin System +This is a plugin for the [Wii U Plugin System (WUPS)](https://github.com/Maschell/WiiUPluginSystem/). To be able to use this plugin you have to place the resulting `.mod` file in to the following folder: + +``` +sd:/wiiu/plugins +``` +When the file is placed on the SDCard you can load it with [Wii U Plugin System (WUPS)](plugin loader). + +# Usage + +When starting the app, you have the option to set your own button combo. Just press the button combo you want for 2 seconds. +Otherwise it will use the default settings (TV button). + +Press the TV button (or your button combo) on the Gamepad to swap the screens. Thats all. + +## Building + +For building you need: +- [wups](https://github.com/Maschell/WiiUPluginSystem) +- [wut](https://github.com/decaf-emu/wut) +- [libutilswut](https://github.com/Maschell/libutils/tree/wut) (WUT version) for common functions. + +Install them (in this order) according to their README's. Don't forget the dependencies of the libs itself. \ No newline at end of file diff --git a/makefile.mk b/makefile.mk new file mode 100644 index 0000000..3fad7d9 --- /dev/null +++ b/makefile.mk @@ -0,0 +1,66 @@ +# Compiling the projects with libutils logging code? +DO_LOGGING := 1 + +# Links against the wut implementation of newlib, this is useful for using any function +# from the C standard library +WUT_ENABLE_NEWLIB := 0 + +# Links against the wut implementation of stdcpp, this is useful for using any function +# from the C++ standard library. This will enable WUT_ENABLE_NEWLIB if you have not already done so. +WUT_ENABLE_CPP := 0 + +# By default newlib will allocate 90% of the default heap for use with sbrk & malloc, +# if this is unacceptable to you then you should use this as it replaces the newlib +# malloc functions which ones which redirect to the CafeOS default heap functions +# such as MEMAllocFromDefaultHeap. +WUT_DEFAULT_MALLOC := 1 + +# Target filename +TARGET := $(notdir $(CURDIR)).mod + +# Source directories +SOURCES := src/ \ + src/common \ + src/utils \ + +# Data directories +DATA := + +# Include directories +INCLUDES := src + +#--------------------------------------------------------------------------------- +# options for code generation and linking +#--------------------------------------------------------------------------------- +# Extra C AND C++ compiler flags +COMMON_CFLAGS := +# Extra C compiler flags +CFLAGS := +# Extra C++ compiler flags +CXXFLAGS := +# Extra linking flags for all linking steps +LDFLAGS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(WUPSDIR) $(WUT_ROOT) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lwups -lutilswut -lcoreinit -lvpad -lnsysnet + +#--------------------------------------------------------------------------------- +# Will be added to the final lib paths +# example: +# -L$C:/library1/lib +#--------------------------------------------------------------------------------- +EXTERNAL_LIBPATHS := + +#--------------------------------------------------------------------------------- +# Will be added to the final include paths +# -IC:/library1/include +#--------------------------------------------------------------------------------- +EXTERNAL_INCLUDE := -I$(WUT_ROOT)/include/libutilswut diff --git a/src/common/c_retain_vars.cpp b/src/common/c_retain_vars.cpp new file mode 100644 index 0000000..721bae3 --- /dev/null +++ b/src/common/c_retain_vars.cpp @@ -0,0 +1,24 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ +#include "common/c_retain_vars.h" + +uint8_t gSwap __attribute__((section(".data"))) = 0; +uint8_t gCallbackCooldown __attribute__((section(".data"))) = 0; +uint8_t gAppStatus __attribute__((section(".data"))) = 0; +uint32_t gButtonCombo __attribute__((section(".data"))) = 0; + +VoiceInfo gVoiceInfos[VOICE_INFO_MAX] __attribute__((section(".data"))); diff --git a/src/common/c_retain_vars.h b/src/common/c_retain_vars.h new file mode 100644 index 0000000..d954135 --- /dev/null +++ b/src/common/c_retain_vars.h @@ -0,0 +1,27 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ +#ifndef C_RETAINS_VARS_H_ +#define C_RETAINS_VARS_H_ + +#include "utils/voice_info.h" +extern uint8_t gSwap; +extern uint8_t gCallbackCooldown; +extern uint8_t gAppStatus; +extern uint32_t gButtonCombo; +extern VoiceInfo gVoiceInfos[VOICE_INFO_MAX]; + +#endif // C_RETAINS_VARS_H_ diff --git a/src/function_patcher.cpp b/src/function_patcher.cpp new file mode 100644 index 0000000..97cda30 --- /dev/null +++ b/src/function_patcher.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ +#include +#include +#include +#include + +#include "utils/voice_swapper.h" +#include "common/c_retain_vars.h" + +DECL_FUNCTION(int32_t, AXSetVoiceDeviceMixOld, void *v, int32_t device, uint32_t id, void *mix){ + if(gSwap){ device = !device;} + if(VOICE_SWAP_LOG == 1){log_printf("AXSetVoiceDeviceMixOld voice: %08X device: %d, mix: %08X\n",v,device,mix);} + VoiceSwapper_setMix(v,device,mix); + return real_AXSetVoiceDeviceMixOld(v,device,id,mix); +} + +DECL_FUNCTION(int32_t, AXSetVoiceDeviceMix, void *v, int32_t device, uint32_t id, void *mix){ + if(gSwap){ device = !device;} + if(VOICE_SWAP_LOG == 1){log_printf("AXSetVoiceDeviceMix voice: %08X device: %d, mix: %08X\n",v,device,mix);} + VoiceSwapper_setMix(v,device,mix); + return real_AXSetVoiceDeviceMix(v,device,id,mix); +} + +DECL_FUNCTION(void *, AXAcquireVoiceExOld, uint32_t prio, void * callback, uint32_t arg){ + void * result = real_AXAcquireVoiceExOld(prio,callback,arg); + if(VOICE_SWAP_LOG == 1){log_printf("AXAcquireVoiceExOld result: %08X \n",result);} + VoiceSwapper_acquireVoice(result); + return result; +} + +DECL_FUNCTION(void *, AXAcquireVoiceEx, uint32_t prio, void * callback, uint32_t arg){ + void * result = real_AXAcquireVoiceEx(prio,callback,arg); + if(VOICE_SWAP_LOG == 1){log_printf("AXAcquireVoiceEx result: %08X \n",result);} + VoiceSwapper_acquireVoice(result); + return result; +} + +DECL_FUNCTION(void, AXFreeVoiceOld, void *v){ + if(VOICE_SWAP_LOG == 1){log_printf("AXFreeVoiceOld v: %08X \n",v);} + VoiceSwapper_freeVoice(v); + real_AXFreeVoiceOld(v); +} + +DECL_FUNCTION(void, AXFreeVoice, void *v){ + if(VOICE_SWAP_LOG == 1){log_printf("AXFreeVoice v: %08X \n",v);} + VoiceSwapper_freeVoice(v); + real_AXFreeVoice(v); +} + +DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer, int32_t scan_target){ + if(gSwap){ + if(scan_target == 1){ + scan_target = 4; + }else{ + scan_target = 1; + } + } + real_GX2CopyColorBufferToScanBuffer(colorBuffer,scan_target); +} + +/* +DECL(int32_t, AXSetDefaultMixerSelectOld, uint32_t s){ + int32_t result = real_AXSetDefaultMixerSelectOld(s); + return result; +}*/ + + +void swapVoices(){ + VoiceSwapper_swapAll(); + for(int32_t i = 0;i 0 && *error == VPAD_READ_SUCCESS && ((buffer[0].hold & gButtonCombo) == gButtonCombo) && gCallbackCooldown == 0 ){ + gCallbackCooldown = 0x3C; + if(gAppStatus == WUPS_APP_STATUS_FOREGROUND){ + gSwap = !gSwap; + swapVoices(); + } + } + if(gCallbackCooldown > 0) gCallbackCooldown--; + + return result; +} + + +WUPS_MUST_REPLACE(GX2CopyColorBufferToScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2CopyColorBufferToScanBuffer); +WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead); +WUPS_MUST_REPLACE(AXAcquireVoiceExOld, WUPS_LOADER_LIBRARY_SND_CORE, AXAcquireVoiceEx); +WUPS_MUST_REPLACE(AXFreeVoiceOld, WUPS_LOADER_LIBRARY_SND_CORE, AXFreeVoice); +WUPS_MUST_REPLACE(AXSetVoiceDeviceMixOld, WUPS_LOADER_LIBRARY_SND_CORE, AXSetVoiceDeviceMix); +//WUPS_MUST_REPLACE(AXSetDefaultMixerSelectOld, , WUPS_LOADER_LIBRARY_SND_CORE, AXSetDefaultMixerSelect), +WUPS_MUST_REPLACE(AXAcquireVoiceEx, WUPS_LOADER_LIBRARY_SNDCORE2, AXAcquireVoiceEx); +WUPS_MUST_REPLACE(AXFreeVoice, WUPS_LOADER_LIBRARY_SNDCORE2, AXFreeVoice); +WUPS_MUST_REPLACE(AXSetVoiceDeviceMix, WUPS_LOADER_LIBRARY_SNDCORE2, AXSetVoiceDeviceMix); diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..63e8e0c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +WUPS_PLUGIN_NAME("SwipSwapMe"); +WUPS_PLUGIN_DESCRIPTION("Swaps the gamepad and tv screen when pressing a certain button (TV is default)"); +WUPS_PLUGIN_VERSION("v1.0"); +WUPS_PLUGIN_AUTHOR("Maschell"); +WUPS_PLUGIN_LICENSE("GPL"); + +WUPS_FS_ACCESS() + +uint32_t SplashScreen(int32_t time,int32_t combotime); + +/* Entry point */ +ON_APPLICATION_START(args) { + memset(gVoiceInfos,0,sizeof(gVoiceInfos)); + socket_lib_init(); + log_init(); +} + +ON_APP_STATUS_CHANGED(status) { + gAppStatus = status; +} + +INITIALIZE_PLUGIN() { + uint32_t res = SplashScreen(10,2); + gButtonCombo = res; +} + +#define FPS 60 +uint32_t SplashScreen(int32_t time,int32_t combotime) { + uint32_t result = VPAD_BUTTON_TV; + + // Init screen + OSScreenInit(); + + uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); + uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC); + + uint32_t * screenbuffer0 = (uint32_t*)memalign(0x100, screen_buf0_size); + uint32_t * screenbuffer1 = (uint32_t*)memalign(0x100, screen_buf1_size); + + if(screenbuffer0 == NULL || screenbuffer1 == NULL) { + if(screenbuffer0 != NULL) { + free(screenbuffer0); + } + if(screenbuffer1 != NULL) { + free(screenbuffer1); + } + return result; + } + + OSScreenSetBufferEx(SCREEN_TV, (void *)screenbuffer0); + OSScreenSetBufferEx(SCREEN_DRC, (void *)screenbuffer1); + + OSScreenEnableEx(SCREEN_TV, 1); + OSScreenEnableEx(SCREEN_DRC, 1); + + // Clear screens + OSScreenClearBufferEx(SCREEN_TV, 0); + OSScreenClearBufferEx(SCREEN_DRC, 0); + + // Flip buffers + OSScreenFlipBuffersEx(SCREEN_TV); + OSScreenFlipBuffersEx(SCREEN_DRC); + + OSScreenClearBufferEx(SCREEN_TV, 0); + OSScreenClearBufferEx(SCREEN_DRC, 0); + + std::vector strings; + strings.push_back("SwipSwapMe 0.2 - by Maschell."); + strings.push_back(""); + strings.push_back(""); + strings.push_back("Press the combo you want to use for swapping now for 2 seconds."); + strings.push_back("Pressing the TV button will return directly."); + strings.push_back(""); + strings.push_back("Otherwise the default combo (TV button) will be used in 10 seconds."); + uint8_t pos = 0; + for (std::vector::iterator it = strings.begin() ; it != strings.end(); ++it) { + OSScreenPutFontEx(SCREEN_TV, 0, pos, (*it).c_str()); + OSScreenPutFontEx(SCREEN_DRC, 0, pos, (*it).c_str()); + pos++; + } + + OSScreenFlipBuffersEx(SCREEN_TV); + OSScreenFlipBuffersEx(SCREEN_DRC); + + int32_t tickswait = time * FPS * 16; + + int32_t sleepingtime = 16; + int32_t times = tickswait/16; + int32_t i=0; + + VPADStatus vpad_data; + VPADReadError error; + uint32_t last = 0xFFFFFFFF; + int32_t timer = 0; + while(i= combotime*FPS) { + result = vpad_data.hold; + break; + } + i++; + OSSleepTicks(OSMicrosecondsToTicks(sleepingtime*1000)); + } + + if(screenbuffer0 != NULL) { + free(screenbuffer0); + } + if(screenbuffer1 != NULL) { + free(screenbuffer1); + } + + return result; +} diff --git a/src/utils/voice_info.h b/src/utils/voice_info.h new file mode 100644 index 0000000..c1eb5f6 --- /dev/null +++ b/src/utils/voice_info.h @@ -0,0 +1,30 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ +#ifndef _VOICE_INFO_H_ +#define _VOICE_INFO_H_ + +#define VOICE_INFO_MAX 100 + +#include + +typedef struct _VoiceInfo { + void* voice; /**< Pointer to the voice */ + uint32_t mixTV[24]; /**< Mix to the TV */ + uint32_t mixDRC[24]; /**< Mix of the DRC */ +} VoiceInfo; + +#endif //_VOICE_INFO_H_ diff --git a/src/utils/voice_swapper.cpp b/src/utils/voice_swapper.cpp new file mode 100644 index 0000000..93d54f8 --- /dev/null +++ b/src/utils/voice_swapper.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** + * Copyright (C) 2017,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 . + ****************************************************************************/ + +#include +#include "voice_info.h" +#include "voice_swapper.h" + +void VoiceSwapper_acquireVoice(void * voice){ + for(int32_t i = 0;i. + ****************************************************************************/ +#ifndef _VOICE_SWAPPER_H_ +#define _VOICE_SWAPPER_H_ +#define VOICE_SWAP_LOG 0 +#include "voice_info.h" +#include "common/c_retain_vars.h" + +#include +#include + +void VoiceSwapper_acquireVoice(void * voice); + +void VoiceSwapper_freeVoice(void * voice); + +void VoiceSwapper_setMix(void * voice,uint32_t device, void* mix); + +void VoiceSwapper_swapAll(); + +#endif //_VOICE_SWAPPER_H_