From 7922ef1cc5a0db1284fdcc5828d27647a4a64fc0 Mon Sep 17 00:00:00 2001 From: FIX94 Date: Thu, 14 Sep 2017 00:11:40 +0200 Subject: [PATCH] first commit --- Makefile | 90 +++++++++++++++++++++++++++ README.md | 5 +- demo/Makefile | 132 ++++++++++++++++++++++++++++++++++++++++ demo/source/main.c | 71 +++++++++++++++++++++ include/wiidrc/wiidrc.h | 60 ++++++++++++++++++ source/wiidrc.c | 132 ++++++++++++++++++++++++++++++++++++++++ source/wiidrc_structs.h | 23 +++++++ 7 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 demo/Makefile create mode 100644 demo/source/main.c create mode 100644 include/wiidrc/wiidrc.h create mode 100644 source/wiidrc.c create mode 100644 source/wiidrc_structs.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e278fd9 --- /dev/null +++ b/Makefile @@ -0,0 +1,90 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_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 +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := libwiidrc +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS = -g -O2 -Wall -Wextra $(MACHDEP) $(INCLUDE) + +#--------------------------------------------------------------------------------- +# 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)/lib/$(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 +#--------------------------------------------------------------------------------- +export CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +#--------------------------------------------------------------------------------- +export OFILES := $(CFILES:.c=.o) +export LD := $(CC) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).a + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).a: $(OFILES) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/README.md b/README.md index 1b51319..fdb583c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # libwiidrc -wiiu gamepad input in wii homebrew with a special firmware +This is only usable with a sepcial patched fw.img injected into a wii vc title, details on all the requirements may follow at some point. +The usage is quite simple, call WiiDRC_Init on boot and after that call WiiDRC_ScanPads every time you update your pad inputs. +See the "demo" folder for an example on how to use it in a bit more detail. +Both compiled Library and Demo can be grabbed from the Releases tab. \ No newline at end of file diff --git a/demo/Makefile b/demo/Makefile new file mode 100644 index 0000000..8f53d22 --- /dev/null +++ b/demo/Makefile @@ -0,0 +1,132 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_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 +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := boot +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lwiidrc -lwiiuse -lm -lbte -logc + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(DEVKITPPC)/lib $(CURDIR) + +#--------------------------------------------------------------------------------- +# 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 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)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.png.o : %.png +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/demo/source/main.c b/demo/source/main.c new file mode 100644 index 0000000..ab659f4 --- /dev/null +++ b/demo/source/main.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + void *xfb = NULL; + GXRModeObj *rmode = NULL; + VIDEO_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(xfb); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + int x = 24, y = 32, w, h; + w = rmode->fbWidth - (32); + h = rmode->xfbHeight - (48); + CON_InitEx(rmode, x, y, w, h); + VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK); + PAD_Init(); + WPAD_Init(); + WiiDRC_Init(); + while(1) + { + printf("\x1b[2J"); + printf("\x1b[37m"); + printf("WiiDRC v1.0 Demo by FIX94\n"); + printf("Press any button on a real Wiimote to exit\n"); + WiiDRC_ScanPads(); + const struct WiiDRCData *drcdat = WiiDRC_Data(); + printf("Left Stick X: %i, Y: %i; Right Stick X: %i, Y: %i\n", + drcdat->xAxisL, drcdat->yAxisL, drcdat->xAxisR, drcdat->yAxisR); + if(drcdat->button & WIIDRC_BUTTON_A) printf("A pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_B) printf("B pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_X) printf("X pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_Y) printf("Y pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_LEFT) printf("D-Pad Left pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_RIGHT) printf("D-Pad Right pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_UP) printf("D-Pad Up pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_DOWN) printf("D-Pad Down pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_ZL) printf("ZL pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_ZR) printf("ZR pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_L) printf("L pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_R) printf("R pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_PLUS) printf("Plus pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_MINUS) printf("Minus pressed\n"); + if(drcdat->button & WIIDRC_BUTTON_HOME) printf("HOME pressed\n"); + if(drcdat->extra & WIIDRC_EXTRA_BUTTON_L3) printf("L3 pressed\n"); + if(drcdat->extra & WIIDRC_EXTRA_BUTTON_R3) printf("R3 pressed\n"); + if(drcdat->extra & WIIDRC_EXTRA_BUTTON_TV) printf("TV pressed\n"); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + PAD_ScanPads(); + WPAD_ScanPads(); + if(PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0)) + break; + } + return 0; +} diff --git a/include/wiidrc/wiidrc.h b/include/wiidrc/wiidrc.h new file mode 100644 index 0000000..875610d --- /dev/null +++ b/include/wiidrc/wiidrc.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#ifndef _WIIDRC_H_ +#define _WIIDRC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct WiiDRCData { + s16 xAxisL; + s16 xAxisR; + s16 yAxisL; + s16 yAxisR; + u16 button; + u8 extra; +}; + +#define WIIDRC_BUTTON_A 0x8000 +#define WIIDRC_BUTTON_B 0x4000 +#define WIIDRC_BUTTON_X 0x2000 +#define WIIDRC_BUTTON_Y 0x1000 +#define WIIDRC_BUTTON_LEFT 0x0800 +#define WIIDRC_BUTTON_RIGHT 0x0400 +#define WIIDRC_BUTTON_UP 0x0200 +#define WIIDRC_BUTTON_DOWN 0x0100 +#define WIIDRC_BUTTON_ZL 0x0080 +#define WIIDRC_BUTTON_ZR 0x0040 +#define WIIDRC_BUTTON_L 0x0020 +#define WIIDRC_BUTTON_R 0x0010 +#define WIIDRC_BUTTON_PLUS 0x0008 +#define WIIDRC_BUTTON_MINUS 0x0004 +#define WIIDRC_BUTTON_HOME 0x0002 + +#define WIIDRC_EXTRA_BUTTON_L3 0x80 +#define WIIDRC_EXTRA_BUTTON_R3 0x40 +#define WIIDRC_EXTRA_BUTTON_TV 0x30 + +bool WiiDRC_Init(); +bool WiiDRC_Inited(); +bool WiiDRC_Recalibrate(); +bool WiiDRC_ScanPads(); +const struct WiiDRCData *WiiDRC_Data(); +u32 WiiDRC_ButtonsUp(); +u32 WiiDRC_ButtonsDown(); +u32 WiiDRC_ButtonsHeld(); +s16 WiiDRC_lStickX(); +s16 WiiDRC_lStickY(); +s16 WiiDRC_rStickX(); +s16 WiiDRC_rStickY(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/wiidrc.c b/source/wiidrc.c new file mode 100644 index 0000000..62d7c27 --- /dev/null +++ b/source/wiidrc.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#include +#include +#include +#include "wiidrc_structs.h" +#include "wiidrc/wiidrc.h" + +static struct WiiDRCStat __WiiDRC_Status; +static struct WiiDRCData __WiiDRC_PadData; +static struct WiiDRCButtons __WiiDRC_PadButtons; + +static u32 __WiiDRC_Inited = 0; +static u8 *__WiiDRC_I2CBuf = NULL; + +static bool __WiiDRC_SetI2CBuf() +{ + DCInvalidateRange((void*)0x938B2964, 4); + if(*(vu32*)0x938B2964 == 0x138BB004) //r569 + { + __WiiDRC_I2CBuf = (u8*)0x938BB004; + return true; + } + DCInvalidateRange((void*)0x938B2564, 4); + if(*(vu32*)0x938B2564 == 0x138BB004) //r570 + { + __WiiDRC_I2CBuf = (u8*)0x938BB004; + return true; + } + else if(*(vu32*)0x938B2564 == 0x138BA004) //r590 + { + __WiiDRC_I2CBuf = (u8*)0x938BA004; + return true; + } + return false; +} + +bool WiiDRC_Init() +{ + if(__WiiDRC_Inited == 1) + return false; + if(!__WiiDRC_SetI2CBuf()) + return false; + + __WiiDRC_Inited = 1; + + WiiDRC_Recalibrate(); //sets up __WiiDRC_Status + memset(&__WiiDRC_PadData,0,sizeof(struct WiiDRCData)); + memset(&__WiiDRC_PadButtons,0,sizeof(struct WiiDRCButtons)); + + return true; +} + +bool WiiDRC_Inited() +{ + return !!__WiiDRC_Inited; +} + +bool WiiDRC_Recalibrate() +{ + if(__WiiDRC_Inited == 0) + return false; + + DCInvalidateRange(__WiiDRC_I2CBuf,9); + __WiiDRC_Status.xAxisLmid = (s8)(__WiiDRC_I2CBuf[4]-0x80); + __WiiDRC_Status.yAxisLmid = (s8)(__WiiDRC_I2CBuf[5]-0x80); + __WiiDRC_Status.xAxisRmid = (s8)(__WiiDRC_I2CBuf[6]-0x80); + __WiiDRC_Status.yAxisRmid = (s8)(__WiiDRC_I2CBuf[7]-0x80); + + return true; +} + +bool WiiDRC_ScanPads() +{ + if(__WiiDRC_Inited == 0) + return false; + + DCInvalidateRange(__WiiDRC_I2CBuf,9); + __WiiDRC_PadData.button = (__WiiDRC_I2CBuf[2]<<8) | (__WiiDRC_I2CBuf[3]); + __WiiDRC_PadData.xAxisL = ((s8)(__WiiDRC_I2CBuf[4]-0x80)) - __WiiDRC_Status.xAxisLmid; + __WiiDRC_PadData.yAxisL = ((s8)(__WiiDRC_I2CBuf[5]-0x80)) - __WiiDRC_Status.yAxisLmid; + __WiiDRC_PadData.xAxisR = ((s8)(__WiiDRC_I2CBuf[6]-0x80)) - __WiiDRC_Status.xAxisRmid; + __WiiDRC_PadData.yAxisR = ((s8)(__WiiDRC_I2CBuf[7]-0x80)) - __WiiDRC_Status.yAxisRmid; + __WiiDRC_PadData.extra = __WiiDRC_I2CBuf[8]; + + u16 newstate, oldstate; + + newstate = __WiiDRC_PadData.button; + oldstate = __WiiDRC_PadButtons.state; + __WiiDRC_PadButtons.state = newstate; + __WiiDRC_PadButtons.up = oldstate & ~newstate; + __WiiDRC_PadButtons.down = newstate & (newstate ^ oldstate); + + return true; +} + +const struct WiiDRCData *WiiDRC_Data() +{ + return &__WiiDRC_PadData; +} +u32 WiiDRC_ButtonsUp() +{ + return __WiiDRC_PadButtons.up; +} +u32 WiiDRC_ButtonsDown() +{ + return __WiiDRC_PadButtons.down; +} +u32 WiiDRC_ButtonsHeld() +{ + return __WiiDRC_PadButtons.state; +} +s16 WiiDRC_lStickX() +{ + return __WiiDRC_PadData.xAxisL; +} +s16 WiiDRC_lStickY() +{ + return __WiiDRC_PadData.yAxisL; +} +s16 WiiDRC_rStickX() +{ + return __WiiDRC_PadData.xAxisR; +} +s16 WiiDRC_rStickY() +{ + return __WiiDRC_PadData.yAxisR; +} diff --git a/source/wiidrc_structs.h b/source/wiidrc_structs.h new file mode 100644 index 0000000..e6e27ad --- /dev/null +++ b/source/wiidrc_structs.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2017 FIX94 + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +#ifndef _WIIDRC_STRUCTS_H_ +#define _WIIDRC_STRUCTS_H_ + +struct WiiDRCStat { + s16 xAxisLmid; + s16 xAxisRmid; + s16 yAxisLmid; + s16 yAxisRmid; +}; + +struct WiiDRCButtons { + u32 up; + u32 down; + u32 state; +}; + +#endif