Push r1235 in internal update menu and window's installer.

Added used libraries to /branches/libs/
You need to "make" and "make install" both libsicksaxis and libupc to compile USBLoaderGX r1235+
This commit is contained in:
Cyan 2015-01-04 21:00:24 +00:00
parent da71bf99dc
commit 0cd2573062
18 changed files with 2049 additions and 0 deletions

131
libruntimeiospatch/API Normal file
View File

@ -0,0 +1,131 @@
libruntimeiospatch function overview
====================================
>>>>>>>> libruntimeiospatch 1.3: <<<<<<<<
===================== ===================
=== ERROR_AHBPROT === === ERROR_PATCH ===
===================== ===================
Use those to catch occuring errors
******
if (IosPatch_AHBPROT(false) == ERROR_AHBPROT)
printf("AHBPROT is still enabled!");
if (IosPatch_RUNTIME(true, false, false, false) == ERROR_PATCH)
printf("Patching IOS failed!");
========================
=== AHBPROT_DISABLED ===
========================
Returns true when HW_AHBPROT access can be applied
******
If(AHBPROT_DISABLED) {
do_something
} else {
do_something_else
}
******
===================================
=== LIB_RUNTIMEIOSPATCH_VERSION ===
===================================
Stores printable version of libruntimeiospatch.
>>>>>>>> libruntimeiospatch 1.1: <<<<<<<<
=====================
=== IosPatch_FULL ===
=====================
This function combines IosPatch_AHBPROT + IOS_ReloadIOS + IosPatch_RUNTIME
>> Flags: [bool]wii (whether to apply Wii patches)
[bool]sciifii (whether to apply extra Sciifii patches)
[bool]vwii (whether to apply extra vWii patches)
[bool]verbose (whether to print messages on-screen)
[int]ios (which IOS to reload into)
>> Return:
-5: no HW_AHBPROT access
-7: patching HW_AHBPROT access failed
>0: success (return equals to number of applied patches)
******
If(AHBPROT_DISABLED) {
IosPatch_FULL(true, false, false, false, 58);
}
******
>>>>>>>> libruntimeiospatch 1.0: <<<<<<<<
========================
=== IosPatch_AHBPROT ===
========================
This function can be used to keep HW_AHBPROT access when going to reload IOS
>> Flags: [bool]verbose (whether to print messages on-screen)
>> Return:
-5: no HW_AHBPROT access
-7: patching HW_AHBPROT access failed
>0: success
******
if(AHBPROT_DISABLED) {
s32 ret;
ret = IosPatch_AHBPROT(false);
if (ret) {
IOS_ReloadIOS(36);
} else {
printf("IosPatch_AHBPROT failed.");
}
}
******
========================
=== IosPatch_RUNTIME ===
========================
This function applies patches on current IOS
>> Flags: [bool]wii (whether to apply Wii patches)
[bool]sciifii (whether to apply extra Sciifii patches)
[bool]vwii (whether to apply extra vWii patches)
[bool]verbose (whether to print messages on-screen)
>> Return:
-5: no HW_AHBPROT access
>0: success (return equals to number of applied patches)
<< Patchsets:
Wii:
* DI Readlimit
* ISFS Permissions
* ES SetUID
* ES SetIdentify
* Hash Check (aka Trucha)
* New Hash Check (aka New Trucha)
Sciifii:
* MEM2 Prot
* ES OpenTitleContent 1 & 2
* ES ReadContent Prot
* ES CloseContent
* ES TitleVersionCheck
* ES TitleDeleteCheck
vWii:
* Kill Anti-SystemTitle-Install 1, 2, 3, 4 & 5
******
If(AHBPROT_DISABLED) {
IosPatch_RUNTIME(true, false, false, false);
}
******

View File

@ -0,0 +1,41 @@
1.5.1:
* code clean-up (JoostinOnline)
* add typedef for s32 (JoostinOnline)
* misc minor changes (JoostinOnline)
1.5:
* add ISFS_SetAttr() patches. (megazig)
Forces the ISFS_SetAttr() function to continue instead of
returning -102 when you're trying to change the UID/GID of a file.
1.4:
* fix value for hash_old (spotted by DarkMatterCore)
1.3: thanks to JoostinOnline/damysteryman
* replaced HAVE_ABHPROT by AHBPROT_DISABLED (now public)
* removed (now) redundant have_ahbprot()
* store version in #LIB_RUNTIMEIOSPATCH_VERSION
* removed (now) redundant get_libruntimeiospatch_version()
* minor code clean-ups
* changed some unsigned ints to signed
* added license header to runtimeiospatch.[ch]
* new vWii patches by damysteryman (fixes installation of hidden channels)
* updated API
1.2:
[NEW] get_libruntimeiospatch_version()
[MOD] IosPatch_AHBPROT() - return code re-work
[MOD] IosPatch_RUNTIME() - return code re-work
[MOD] IosPatch_FULL() - retun code re-work
[MOD] API doc file updated
[NEW] CHANGES doc file
1.1:
[NEW] IosPatch_FULL()
[MOD] IosPatch_AHBPROT() - proper return work
[NEW] API doc file
1.0: initial release
[NEW] have_ahbprot()
[NEW] IosPatch_AHBPROT()
[NEW] IosPatch_RUNTIME()

153
libruntimeiospatch/Makefile Normal file
View File

@ -0,0 +1,153 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>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 := runtimeiospatch
BUILD := build
SOURCES := source
DATA := data
INCLUDES := $(DEVKITPRO)/libogc
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -save-temps -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
ASFLAGS = $(INCLUDE) -D_LANGUAGE_ASSEMBLY
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
ARFLAGS = rcs
#---------------------------------------------------------------------------------
# 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 := $(DEVKITPRO)/libogc
#---------------------------------------------------------------------------------
# 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)
@rm -f lib$(TARGET).a
#---------------------------------------------------------------------------------
run:
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
install:
@echo Installing ...
@mkdir -p $(LIBOGC_INC)/$(TARGET)
@install -v -m 644 lib$(TARGET).a $(LIBOGC_LIB)
@install -v -m 644 source/$(TARGET).h $(LIBOGC_INC)/$(TARGET)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).a: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .bin extension
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
# This rule will create a library with all the object files
#---------------------------------------------------------------------------------
%.a:
@echo Archiving ... lib$(notdir $@)
@$(AR) $(ARFLAGS) ../lib$(notdir $@) $^
@echo $(TARGET)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

21
libruntimeiospatch/README Normal file
View File

@ -0,0 +1,21 @@
=== libruntimeiospatch ===
a library providing necessary functions for patching IOS at runtime using HW_AHBPROT.
It is distributed under the terms of the GNU General Public License v2
=== Including ===
include the library as
#include <libruntimeiospatch.h> // Code
LIBS := -lruntimeiospatch // Makefile
=== API ===
see File "API"
= Thanks =
- libOGC devs
- Team Twizzers
- damysterman
- anyone I forgot to mention here

View File

@ -0,0 +1,188 @@
// 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, version 2.0.
// 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 2.0 for more details.
// Copyright (C) 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
// Copyright (C) 2012-2013 damysteryman
// Copyright (C) 2012-2013 Christopher Bratusek <nano@tuxfamily.org>
// Copyright (C) 2013 DarkMatterCore
// Copyright (C) 2014 megazig
#include <gccore.h>
#include <ogc/machine/processor.h>
#include <stdio.h>
#include <string.h>
#include "runtimeiospatch.h"
#define MEM_REG_BASE 0xd8b4000
#define MEM_PROT (MEM_REG_BASE + 0x20a)
static inline void disable_memory_protection(void) {
write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF);
}
static const u8 di_readlimit_old[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0A, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x7E, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
};
static const u8 di_readlimit_patch[] = { 0x7e, 0xd4 };
static const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 };
static const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 };
static const u8 setuid_old[] = { 0xD1, 0x2A, 0x1C, 0x39 };
static const u8 setuid_patch[] = { 0x46, 0xC0 };
static const u8 es_identify_old[] = { 0x28, 0x03, 0xD1, 0x23 };
static const u8 es_identify_patch[] = { 0x00, 0x00 };
static const u8 hash_old[] = { 0x20, 0x07, 0x23, 0xA2 };
static const u8 hash_patch[] = { 0x00 };
static const u8 new_hash_old[] = { 0x20, 0x07, 0x4B, 0x0B };
static const u8 addticket_vers_check[] = { 0xD2, 0x01, 0x4E, 0x56 };
static const u8 addticket_patch[] = { 0xE0 };
static const u8 es_set_ahbprot_old[] = { 0x68, 0x5B, 0x22, 0xEC, 0x00, 0x52, 0x18, 0x9B, 0x68, 0x1B, 0x46, 0x98, 0x07, 0xDB };
static const u8 es_set_ahbprot_patch[] = { 0x01 };
//Following patches added to iospatch.c by damysteryman, taken from sciifii v5
static const u8 MEM2_prot_old[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x01, 0x80, 0x1A, 0x22, 0xF0 };
static const u8 MEM2_prot_patch[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x00, 0x80, 0x1A, 0x22, 0xF0 };
static const u8 ES_OpenTitleContent1_old[] = { 0x9D, 0x05, 0x42, 0x9D, 0xD0, 0x03 };
static const u8 ES_OpenTitleContent1_patch[] = { 0x9D, 0x05, 0x42, 0x9D, 0xE0, 0x03 };
static const u8 ES_OpenTitleContent2_old[] = { 0xD4, 0x01, 0x4C, 0x36, 0xE0, 0x3B };
static const u8 ES_OpenTitleContent2_patch[] = { 0xE0, 0x01, 0x4C, 0x36, 0xE0, 0x3B };
static const u8 ES_ReadContent_old[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B,
0x0E, 0x68, 0x9B, 0x2B, 0x00, 0xD0, 0x03, 0x29, 0x00, 0xDB, 0x01,
0x29, 0x0F, 0xDD, 0x01 };
static const u8 ES_ReadContent_patch[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B,
0x0E, 0x68, 0x9B, 0x2B, 0x00, 0x46, 0xC0, 0x29, 0x00, 0x46, 0xC0,
0x29, 0x0F, 0xE0, 0x01 };
static const u8 ES_CloseContent_old[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0xD0,
0x03, 0x29, 0x00, 0xDB, 0x01, 0x29, 0x0F, 0xDD, 0x01 };
static const u8 ES_CloseContent_patch[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0x46,
0xC0, 0x29, 0x00, 0x46, 0xC0, 0x29, 0x0F, 0xE0, 0x01 };
static const u8 ES_TitleVersionCheck_old[] = { 0xD2, 0x01, 0x4E, 0x56 };
static const u8 ES_TitleVersionCheck_patch[] = { 0xE0, 0x01, 0x4E, 0x56 };
static const u8 ES_TitleDeleteCheck_old[] = { 0xD8, 0x00, 0x4A, 0x04 };
static const u8 ES_TitleDeleteCheck_patch[] = { 0xE0, 0x00, 0x4A, 0x04 };
//Following set of patches made by damysteryman for use with Wii U's vWii
static const u8 Kill_AntiSysTitleInstallv3_pt1_old[] = { 0x68, 0x1A, 0x2A, 0x01, 0xD0, 0x05 }; // Make sure that the pt1
static const u8 Kill_AntiSysTitleInstallv3_pt1_patch[] = { 0x68, 0x1A, 0x2A, 0x01, 0x46, 0xC0 }; // patch is applied twice. -dmm
static const u8 Kill_AntiSysTitleInstallv3_pt2_old[] = { 0xD0, 0x02, 0x33, 0x06, 0x42, 0x9A, 0xD1, 0x01 }; // Make sure that the pt2 patch
static const u8 Kill_AntiSysTitleInstallv3_pt2_patch[] = { 0x46, 0xC0, 0x33, 0x06, 0x42, 0x9A, 0xE0, 0x01 }; // is also applied twice. -dmm
static const u8 Kill_AntiSysTitleInstallv3_pt3_old[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x01 };
static const u8 Kill_AntiSysTitleInstallv3_pt3_patch[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x10 };
static const u8 isfs_setattr_pt1_old[] = { 0x42, 0xAB, 0xD0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt1_patch[] = { 0x42, 0xAB, 0xE0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt2_old[] = { 0x2D, 0x00, 0xD0, 0x02, 0x20, 0x66 };
static const u8 isfs_setattr_pt2_patch[] = { 0x2D, 0x00, 0xE0, 0x02, 0x20, 0x66 };
static u8 apply_patch(const char *name, const u8 *old, u32 old_size, const u8 *patch, size_t patch_size, u32 patch_offset, bool verbose) {
u8 *ptr_start = (u8*)*((u32*)0x80003134), *ptr_end = (u8*)0x94000000;
u8 found = 0;
if(verbose)
printf(" Patching %-30s", name);
u8 *location = NULL;
while (ptr_start < (ptr_end - patch_size)) {
if (!memcmp(ptr_start, old, old_size)) {
found++;
location = ptr_start + patch_offset;
u8 *start = location;
u32 i;
for (i = 0; i < patch_size; i++) {
*location++ = patch[i];
}
DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
ICInvalidateRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
}
ptr_start++;
}
if(verbose){
if (found)
printf(" patched\n");
else
printf(" not patched\n");
}
return found;
}
s32 IosPatch_AHBPROT(bool verbose) {
if (AHBPROT_DISABLED) {
disable_memory_protection();
s32 ret = apply_patch("es_set_ahbprot", es_set_ahbprot_old, sizeof(es_set_ahbprot_old), es_set_ahbprot_patch, sizeof(es_set_ahbprot_patch), 25, verbose);
if (ret)
return ret;
else
return ERROR_PATCH;
}
return ERROR_AHBPROT;
}
s32 IosPatch_RUNTIME(bool wii, bool sciifii, bool vwii, bool verbose) {
s32 count = 0;
if (AHBPROT_DISABLED) {
disable_memory_protection();
if(wii)
{
if(verbose) printf(">> Applying standard Wii patches:\n");
count += apply_patch("di_readlimit", di_readlimit_old, sizeof(di_readlimit_old), di_readlimit_patch, sizeof(di_readlimit_patch), 12, verbose);
count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0, verbose);
count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0, verbose);
count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2, verbose);
count += apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1, verbose);
count += apply_patch("new_hash_check", new_hash_old, sizeof(new_hash_old), hash_patch, sizeof(hash_patch), 1, verbose);
count += apply_patch("isfs_setattr_pt1", isfs_setattr_pt1_old, sizeof(isfs_setattr_pt1_old), isfs_setattr_pt1_patch, sizeof(isfs_setattr_pt1_patch), 0, verbose);
count += apply_patch("isfs_setattr_pt2", isfs_setattr_pt2_old, sizeof(isfs_setattr_pt2_old), isfs_setattr_pt2_patch, sizeof(isfs_setattr_pt2_patch), 0, verbose);
}
if(sciifii)
{
if(verbose) printf(">> Applying Sciifii patches:\n");
count += apply_patch("MEM2_prot", MEM2_prot_old, sizeof(MEM2_prot_old), MEM2_prot_patch, sizeof(MEM2_prot_patch), 0, verbose);
count += apply_patch("ES_OpenTitleContent1", ES_OpenTitleContent1_old, sizeof(ES_OpenTitleContent1_old), ES_OpenTitleContent1_patch, sizeof(ES_OpenTitleContent1_patch), 0, verbose);
count += apply_patch("ES_OpenTitleContent2", ES_OpenTitleContent2_old, sizeof(ES_OpenTitleContent2_old), ES_OpenTitleContent2_patch, sizeof(ES_OpenTitleContent2_patch), 0, verbose);
count += apply_patch("ES_ReadContent_prot", ES_ReadContent_old, sizeof(ES_ReadContent_old), ES_ReadContent_patch, sizeof(ES_ReadContent_patch), 0, verbose);
count += apply_patch("ES_CloseContent", ES_CloseContent_old, sizeof(ES_CloseContent_old), ES_CloseContent_patch, sizeof(ES_CloseContent_patch), 0, verbose);
count += apply_patch("ES_TitleVersionCheck", ES_TitleVersionCheck_old, sizeof(ES_TitleVersionCheck_old), ES_TitleVersionCheck_patch, sizeof(ES_TitleVersionCheck_patch), 0, verbose);
count += apply_patch("ES_TitleDeleteCheck", ES_TitleDeleteCheck_old, sizeof(ES_TitleDeleteCheck_old), ES_TitleDeleteCheck_patch, sizeof(ES_TitleDeleteCheck_patch), 0, verbose);
}
if(vwii)
{
if(verbose) printf(">> Applying vWii patches:\n");
count += apply_patch("Kill_AntiSysTitleInstallv3_pt1", Kill_AntiSysTitleInstallv3_pt1_old, sizeof(Kill_AntiSysTitleInstallv3_pt1_old), Kill_AntiSysTitleInstallv3_pt1_patch, sizeof(Kill_AntiSysTitleInstallv3_pt1_patch), 0, verbose);
count += apply_patch("Kill_AntiSysTitleInstallv3_pt2", Kill_AntiSysTitleInstallv3_pt2_old, sizeof(Kill_AntiSysTitleInstallv3_pt2_old), Kill_AntiSysTitleInstallv3_pt2_patch, sizeof(Kill_AntiSysTitleInstallv3_pt2_patch), 0, verbose);
count += apply_patch("Kill_AntiSysTitleInstallv3_pt3", Kill_AntiSysTitleInstallv3_pt3_old, sizeof(Kill_AntiSysTitleInstallv3_pt3_old), Kill_AntiSysTitleInstallv3_pt3_patch, sizeof(Kill_AntiSysTitleInstallv3_pt3_patch), 0, verbose);
}
return count;
}
return ERROR_AHBPROT;
}
s32 IosPatch_FULL(bool wii, bool sciifii, bool vwii, bool verbose, int IOS) {
s32 ret = 0;
s32 xret = 0;
if (AHBPROT_DISABLED)
ret = IosPatch_AHBPROT(verbose);
else
return ERROR_AHBPROT;
if (ret) {
IOS_ReloadIOS(IOS);
xret = IosPatch_RUNTIME(wii, sciifii, vwii, verbose);
} else {
xret = ERROR_PATCH;
}
return xret;
}

View File

@ -0,0 +1,147 @@
// 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, version 2.0.
// 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 2.0 for more details.
// Copyright (C) 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
// Copyright (C) 2012-2013 damysteryman
// Copyright (C) 2012-2013 Christopher Bratusek <nano@tuxfamily.org>
// Copyright (C) 2013 DarkMatterCore
// Copyright (C) 2014 megazig
#ifndef __RUNTIMEIOSPATCH_H__
#define __RUNTIMEIOSPATCH_H__
/**
* Version information for Libruntimeiospatch.
*/
#define LIB_RUNTIMEIOSPATCH_VERSION "1.5.1"
//==============================================================================
// HW_RVL header
//==============================================================================
#if defined(HW_RVL) /* defined(HW_RVL) */
/**
*Returns true when HW_AHBPROT access can be applied
*/
#define AHBPROT_DISABLED (*(vu32*)0xcd800064 == 0xFFFFFFFF)
//==============================================================================
// Error code definitions:
//==============================================================================
#define ERROR_AHBPROT -5
#define ERROR_PATCH -7
//==============================================================================
// C++ header
//==============================================================================
#ifdef __cplusplus
extern "C" {
#endif
/* __cplusplus */
//==============================================================================
// Extra standard declarations
//==============================================================================
typedef signed int s32;
//==============================================================================
//==============================================================================
// Patchsets:
//==============================================================================
/*
Wii:
* DI Readlimit
* ISFS Permissions
* ES SetUID
* ES SetIdentify
* Hash Check (aka Trucha)
* New Hash Check (aka New Trucha)
Sciifii:
* MEM2 Prot
* ES OpenTitleContent 1 & 2
* ES ReadContent Prot
* ES CloseContent
* ES TitleVersionCheck
* ES TitleDeleteCheck
vWii:
* Kill Anti-SystemTitle-Install 1, 2, 3, 4 & 5
*/
//==============================================================================
// Functions:
//==============================================================================
/**
* This function can be used to keep HW_AHBPROT access when going to reload IOS
* @param verbose Flag determing whether or not to print messages on-screen
* @example
* if(AHBPROT_DISABLED) {
* s32 ret;
* ret = IosPatch_AHBPROT(false);
* if (ret) {
* IOS_ReloadIOS(36);
* } else {
* printf("IosPatch_AHBPROT failed.");
* }
* }
* @return Signed 32bit integer representing code
* > 0 : Success - return equals to number of applied patches
* ERROR_AHBPROT : Error - No HW_AHBPROT access
*/
s32 IosPatch_AHBPROT(bool verbose);
/**
* This function applies patches on current IOS
* @see Patchsets
* @param wii Flag determing whether or not to apply Wii patches.
* @param sciifii Flag determing whether or not to apply extra Sciifii patches.
* @param vwii Flag determing whether or not to apply extra vWii patches.
* @param verbose Flag determing whether or not to print messages on-screen.
* @example if(AHBPROT_DISABLED) IosPatch_FULL(true, false, false, false);
* @return Signed 32bit integer representing code
* > 0 : Success - return equals to number of applied patches
* ERROR_AHBPROT : Error - No HW_AHBPROT access
* ERROR_PATCH : Error - Patching HW_AHBPROT access failed
*/
s32 IosPatch_RUNTIME(bool wii, bool sciifii, bool vwii, bool verbose);
/**
* This function combines IosPatch_AHBPROT + IOS_ReloadIOS + IosPatch_RUNTIME
* @see Patchsets
* @param wii Flag determing whether or not to apply Wii patches.
* @param sciifii Flag determing whether or not to apply extra Sciifii patches.
* @param vwii Flag determing whether or not to apply extra vWii patches.
* @param verbose Flag determing whether or not to print messages on-screen.
* @param IOS Which IOS to reload into.
* @example if(AHBPROT_DISABLED) IosPatch_FULL(true, false, false, false, 58);
* @return Signed 32bit integer representing code
* > 0 : Success - return equals to number of applied patches
* ERROR_AHBPROT : Error - No HW_AHBPROT access
* ERROR_PATCH : Error - Patching HW_AHBPROT access failed
*/
s32 IosPatch_FULL(bool wii, bool sciifii, bool vwii, bool verbose, int IOS);
//==============================================================================
// C++ footer
//==============================================================================
#ifdef __cplusplus
}
#endif /* __cplusplus */
//==============================================================================
// HW_RVL footer
//==============================================================================
#endif /* defined(HW_RVL) */
#endif

28
libsicksaxis/Makefile Normal file
View File

@ -0,0 +1,28 @@
.SUFFIXES:
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
TARGET := libsicksaxis.a
CFLAGS = -g -O2 -Wall $(MACHDEP) -I$(LIBOGC_INC)
all: sicksaxis.o
powerpc-eabi-ar rcs $(TARGET) -c sicksaxis.o
@echo "Type 'make install' to install"
sicksaxis.o:
powerpc-eabi-gcc $(CFLAGS) -c sicksaxis.c
install: all
@echo install ...
cp $(TARGET) $(LIBOGC_LIB)
cp sicksaxis.h $(LIBOGC_INC)
clean:
@echo clean ...
@rm -fr sicksaxis.o $(TARGET)

View File

@ -0,0 +1,135 @@
/*
// A simple wrapper for libsicksaxis, to make it resemble WPAD/PAD more closely.
// Written by daxtsu/thedax. I'm releasing this code into the public domain, so do whatever you want with it.
//
// 2015-01 Cyan
// Added Buttons state Up and Held.
//
*/
#include <sicksaxis.h>
#include "sicksaxis-wrapper.h"
static DS3 first;
static bool psPressed = false;
static unsigned int ButtonsUp;
static unsigned int ButtonsDown;
static unsigned int ButtonsHeld;
bool DS3_Init()
{
USB_Initialize();
if (ss_init() < 0)
{
return false;
}
ss_initialize(&first);
return true;
}
void DS3_Rumble()
{
if (first.connected && psPressed)
{
ss_set_rumble(&first, 2, 255, 2, 255);
}
}
void DS3_Cleanup()
{
psPressed = false;
ss_close(&first);
USB_Deinitialize();
}
unsigned int DS3_ButtonsDown()
{
if (!ss_is_connected(&first) || !psPressed)
return 0;
DS3 *controller;
controller = &first;
unsigned int pressed = 0;
pressed |= controller->pad.buttons.PS ? DS3_BUTTON_PS : 0;
pressed |= controller->pad.buttons.start ? DS3_BUTTON_START : 0;
pressed |= controller->pad.buttons.select ? DS3_BUTTON_SELECT : 0;
pressed |= controller->pad.buttons.triangle ? DS3_BUTTON_TRIANGLE : 0;
pressed |= controller->pad.buttons.circle ? DS3_BUTTON_CIRCLE : 0;
pressed |= controller->pad.buttons.cross ? DS3_BUTTON_CROSS : 0;
pressed |= controller->pad.buttons.square ? DS3_BUTTON_SQUARE : 0;
pressed |= controller->pad.buttons.up ? DS3_BUTTON_UP : 0;
pressed |= controller->pad.buttons.right ? DS3_BUTTON_RIGHT : 0;
pressed |= controller->pad.buttons.down ? DS3_BUTTON_DOWN : 0;
pressed |= controller->pad.buttons.left ? DS3_BUTTON_LEFT : 0;
pressed |= controller->pad.buttons.L1 ? DS3_BUTTON_L1 : 0;
pressed |= controller->pad.buttons.L2 ? DS3_BUTTON_L2 : 0;
// pressed |= controller->pad.buttons.L3 ? DS3_BUTTON_L3 : 0;
pressed |= controller->pad.buttons.R1 ? DS3_BUTTON_R1 : 0;
pressed |= controller->pad.buttons.R2 ? DS3_BUTTON_R2 : 0;
// pressed |= controller->pad.buttons.R3 ? DS3_BUTTON_R3 : 0;
ButtonsUp = ButtonsHeld & ~pressed;
ButtonsDown = ~ButtonsHeld & pressed;
ButtonsHeld = pressed;
return ButtonsDown;
}
unsigned int DS3_ButtonsHeld()
{
return ButtonsHeld;
}
unsigned int DS3_ButtonsUp()
{
return ButtonsUp;
}
bool DS3_Connected()
{
return first.connected > 0 && psPressed;
}
void DS3_ScanPads()
{
if (!ss_is_connected(&first))
{
psPressed = false;
ss_initialize(&first);
if (ss_open(&first) > 0)
{
ss_start_reading(&first);
ss_set_led(&first, 0);
}
}
else if (first.pad.buttons.PS && !psPressed)
{
psPressed = true;
ss_set_led(&first, 1);
}
}
int DS3_StickX()
{
return psPressed? first.pad.left_analog.x - 128 : 0;
}
int DS3_SubStickX()
{
return psPressed? first.pad.right_analog.x - 128 : 0;
}
int DS3_StickY()
{
return psPressed? 127 - first.pad.left_analog.y : 0;
}
int DS3_SubStickY()
{
return psPressed? 127 - first.pad.right_analog.y : 0;
}

View File

@ -0,0 +1,74 @@
// A simple wrapper for libsicksaxis, to make it resemble WPAD/PAD more closely.
// Written by daxtsu/thedax. I'm releasing this code into the public domain, so do whatever you want with it.
#ifndef _DS3WRAPPER_H_
#define _DS3WRAPPER_H_
#include <gctypes.h>
#include <wiiuse/wpad.h>
struct ss_device;
enum
{
// DS3_BUTTON_PS = 1,
// DS3_BUTTON_START = 2,
// DS3_BUTTON_SELECT = 4,
// DS3_BUTTON_TRIANGLE = 8,
// DS3_BUTTON_CIRCLE = 16,
// DS3_BUTTON_CROSS = 32,
// DS3_BUTTON_SQUARE = 64,
// DS3_BUTTON_UP = 128,
// DS3_BUTTON_RIGHT = 256,
// DS3_BUTTON_DOWN = 512,
// DS3_BUTTON_LEFT = 1024,
// DS3_BUTTON_L1 = 2048,
// DS3_BUTTON_L2 = 4096,
// DS3_BUTTON_L3 = 8192,
// DS3_BUTTON_R1 = 16384,
// DS3_BUTTON_R2 = 32768,
// DS3_BUTTON_R3 = 65536,
// Classic Controller mapping
DS3_BUTTON_PS = WPAD_CLASSIC_BUTTON_HOME,
DS3_BUTTON_START = WPAD_CLASSIC_BUTTON_PLUS,
DS3_BUTTON_SELECT = WPAD_CLASSIC_BUTTON_MINUS,
DS3_BUTTON_TRIANGLE = WPAD_CLASSIC_BUTTON_X,
DS3_BUTTON_CIRCLE = WPAD_CLASSIC_BUTTON_A,
DS3_BUTTON_CROSS = WPAD_CLASSIC_BUTTON_B,
DS3_BUTTON_SQUARE = WPAD_CLASSIC_BUTTON_Y,
DS3_BUTTON_UP = WPAD_CLASSIC_BUTTON_UP,
DS3_BUTTON_RIGHT = WPAD_CLASSIC_BUTTON_RIGHT,
DS3_BUTTON_DOWN = WPAD_CLASSIC_BUTTON_DOWN,
DS3_BUTTON_LEFT = WPAD_CLASSIC_BUTTON_LEFT,
DS3_BUTTON_L1 = WPAD_CLASSIC_BUTTON_FULL_L,
DS3_BUTTON_L2 = WPAD_CLASSIC_BUTTON_ZL,
// DS3_BUTTON_L3 =
DS3_BUTTON_R1 = WPAD_CLASSIC_BUTTON_FULL_R,
DS3_BUTTON_R2 = WPAD_CLASSIC_BUTTON_ZR,
// DS3_BUTTON_R3 =
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct ss_device DS3;
bool DS3_Init();
void DS3_Rumble();
void DS3_Cleanup();
u32 DS3_ButtonsDown();
u32 DS3_ButtonsHeld();
u32 DS3_ButtonsUp();
bool DS3_Connected();
void DS3_ScanPads();
int DS3_StickX();
int DS3_SubStickX();
int DS3_StickY();
int DS3_SubStickY();
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

346
libsicksaxis/sicksaxis.c Normal file
View File

@ -0,0 +1,346 @@
#include "sicksaxis.h"
#include <gccore.h>
#include <stdio.h>
#include <string.h>
static uint8_t ATTRIBUTE_ALIGN(32) _ss_attributes_payload[] =
{
0x52,
0x00, 0x00, 0x00, 0x00, //Rumble
0xff, 0x80, //Gyro
0x00, 0x00,
0x00, //* LED_1 = 0x02, LED_2 = 0x04, ... */
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
};
static const uint8_t _ss_led_pattern[] = {0x0, 0x02, 0x04, 0x08, 0x10, 0x12, 0x14, 0x18};
static int _ss_heap_id = -1;
static int _ss_inited = 0;
static int _ss_dev_number = 1;
static int _ss_dev_id_list[SS_MAX_DEV] = {0};
static int _ss_dev_id_list_exists(int id);
static int _ss_dev_id_list_add(int id);
static int _ss_dev_id_list_remove(int id);
static int _ss_removal_cb(int result, void *usrdata);
static int _ss_read_cb(int result, void *usrdata);
static int _ss_operational_cb(int result, void *usrdata);
static int _ss_read(struct ss_device *dev);
static int _ss_set_operational(struct ss_device *dev);
static int _ss_build_attributes_payload(struct ss_device *dev);
static int _ss_send_attributes_payload(struct ss_device *dev);
int ss_init()
{
if (!_ss_inited) {
_ss_heap_id = iosCreateHeap(SS_HEAP_SIZE);
_ss_inited = 1;
}
return 1;
}
int ss_initialize(struct ss_device *dev)
{
dev->device_id = -1;
dev->fd = -1;
dev->connected = 0;
dev->enabled = 0;
dev->reading = 0;
dev->removal_callback = NULL;
dev->removal_usrdata = NULL;
dev->read_callback = NULL;
dev->read_usrdata = NULL;
memset(&dev->pad, 0x0, sizeof(struct SS_GAMEPAD));
memset(&dev->attributes, 0x0, sizeof(struct SS_ATTRIBUTES));
return 1;
}
int ss_open(struct ss_device *dev)
{
if (!_ss_inited) return -1;
if (dev->connected) ss_close(dev);
usb_device_entry dev_entry[8];
unsigned char dev_count;
if (USB_GetDeviceList(dev_entry, 8, USB_CLASS_HID, &dev_count) < 0) {
return -2;
}
int i;
for (i = 0; i < dev_count; ++i) {
if ((dev_entry[i].vid == SS_VENDOR_ID) && (dev_entry[i].pid == SS_PRODUCT_ID)) {
if (!_ss_dev_id_list_exists(dev_entry[i].device_id)) {
if (USB_OpenDevice(dev_entry[i].device_id, SS_VENDOR_ID, SS_PRODUCT_ID, &dev->fd) < 0) {
return -3;
}
dev->device_id = dev_entry[i].device_id;
dev->connected = 1;
dev->enabled = 0;
dev->reading = 0;
_ss_set_operational(dev);
ss_set_led(dev, _ss_dev_number);
_ss_dev_id_list_add(dev_entry[i].device_id);
_ss_dev_number++;
USB_DeviceRemovalNotifyAsync(dev->fd, &_ss_removal_cb, dev);
return 1;
}
}
}
return -4;
}
int ss_close(struct ss_device *dev)
{
if (dev && dev->fd > 0) {
USB_CloseDevice(&dev->fd);
}
return 1;
}
int ss_is_connected(struct ss_device *dev)
{
return dev->connected;
}
int ss_set_read_cb(struct ss_device *dev,ss_usb_callback cb, void *usrdata)
{
dev->read_callback = cb;
dev->read_usrdata = usrdata;
return 1;
}
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata)
{
dev->removal_callback = cb;
dev->removal_usrdata = usrdata;
return 1;
}
int ss_start_reading(struct ss_device *dev)
{
if (dev) {
dev->reading = 1;
if (dev->enabled) {
_ss_read(dev);
}
return 1;
}
return 0;
}
int ss_stop_reading(struct ss_device *dev)
{
if (dev) {
dev->reading = 0;
return 1;
}
return 0;
}
static int _ss_build_attributes_payload(struct ss_device *dev)
{
_ss_attributes_payload[1] = dev->attributes.rumble.duration_right;
_ss_attributes_payload[2] = dev->attributes.rumble.power_right;
_ss_attributes_payload[3] = dev->attributes.rumble.duration_left;
_ss_attributes_payload[4] = dev->attributes.rumble.power_left;
_ss_attributes_payload[9] = _ss_led_pattern[dev->attributes.led];
return 1;
}
static int _ss_send_attributes_payload(struct ss_device *dev)
{
if (!dev->connected) return 0;
_ss_build_attributes_payload(dev);
return USB_WriteCtrlMsgAsync(dev->fd,
USB_REQTYPE_INTERFACE_SET,
USB_REQ_SETREPORT,
(USB_REPTYPE_OUTPUT<<8) | 0x01,
0x0,
sizeof(_ss_attributes_payload),
_ss_attributes_payload,
NULL, NULL);
}
inline int ss_set_led(struct ss_device *dev, int led)
{
dev->attributes.led = led;
return _ss_send_attributes_payload(dev);
}
inline int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left)
{
dev->attributes.rumble.duration_right = duration_right;
dev->attributes.rumble.power_right = power_right;
dev->attributes.rumble.duration_left = duration_left;
dev->attributes.rumble.power_left = power_left;
return _ss_send_attributes_payload(dev);
}
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac)
{
uint8_t ATTRIBUTE_ALIGN(32) msg[17];
int ret = USB_WriteCtrlMsgAsync(dev->fd,
USB_REQTYPE_INTERFACE_GET,
USB_REQ_GETREPORT,
(USB_REPTYPE_FEATURE<<8) | 0xf2,
0,
sizeof(msg),
msg,
NULL, NULL);
mac[0] = msg[4];
mac[1] = msg[5];
mac[2] = msg[6];
mac[3] = msg[7];
mac[4] = msg[8];
mac[5] = msg[9];
return ret;
}
int ss_get_mac(struct ss_device *dev, uint8_t *mac)
{
uint8_t ATTRIBUTE_ALIGN(32) msg[8];
int ret = USB_WriteCtrlMsgAsync(dev->fd,
USB_REQTYPE_INTERFACE_GET,
USB_REQ_GETREPORT,
(USB_REPTYPE_FEATURE<<8) | 0xf5,
0,
sizeof(msg),
msg,
NULL, NULL);
mac[0] = msg[2];
mac[1] = msg[3];
mac[2] = msg[4];
mac[3] = msg[5];
mac[4] = msg[6];
mac[5] = msg[7];
return ret;
}
int ss_set_mac(struct ss_device *dev, const uint8_t *mac)
{
uint8_t ATTRIBUTE_ALIGN(32) msg[] = {0x01, 0x00, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]};
int ret = USB_WriteCtrlMsgAsync(dev->fd,
USB_REQTYPE_INTERFACE_SET,
USB_REQ_SETREPORT,
(USB_REPTYPE_FEATURE<<8) | 0xf5,
0,
sizeof(msg),
msg,
NULL, NULL);
return ret;
}
static int _ss_read(struct ss_device *dev)
{
return USB_WriteCtrlMsgAsync(
dev->fd,
USB_REQTYPE_INTERFACE_GET,
USB_REQ_GETREPORT,
(USB_REPTYPE_INPUT<<8) | 0x01,
0x0,
SS_PAYLOAD_SIZE,
&dev->pad,
&_ss_read_cb,
dev);
}
static int _ss_removal_cb(int result, void *usrdata)
{
struct ss_device *dev = (struct ss_device*)usrdata;
if (dev->device_id > 0) {
_ss_dev_id_list_remove(dev->device_id);
_ss_dev_number--;
if (dev->removal_callback)
dev->removal_callback(dev->removal_usrdata);
ss_initialize(dev);
return 1;
}
return 0;
}
static int _ss_set_operational(struct ss_device *dev)
{
uint8_t ATTRIBUTE_ALIGN(32) buf[17];
return USB_WriteCtrlMsgAsync(
dev->fd,
USB_REQTYPE_INTERFACE_GET,
USB_REQ_GETREPORT,
(USB_REPTYPE_FEATURE<<8) | 0xf2,
0x0,
17,
buf,
&_ss_operational_cb,
dev);
}
static int _ss_read_cb(int result, void *usrdata)
{
if (usrdata) {
struct ss_device *dev = (struct ss_device*)usrdata;
if (dev->reading) {
_ss_read(dev);
if (dev->read_callback)
dev->read_callback(dev->read_usrdata);
}
}
return 1;
}
static int _ss_operational_cb(int result, void *usrdata)
{
struct ss_device *dev = (struct ss_device*)usrdata;
dev->enabled = 1;
if (dev->reading) {
_ss_read(dev);
}
return 1;
}
static int _ss_dev_id_list_exists(int id)
{
int i;
for (i = 0; i < SS_MAX_DEV; ++i) {
if (_ss_dev_id_list[i] == id) return 1;
}
return 0;
}
static int _ss_dev_id_list_add(int id)
{
int i;
for (i = 0; i < SS_MAX_DEV; ++i) {
if (_ss_dev_id_list[i] == 0) {
_ss_dev_id_list[i] = id;
return 1;
}
}
return 0;
}
static int _ss_dev_id_list_remove(int id)
{
int i;
for (i = 0; i < SS_MAX_DEV; ++i) {
if (_ss_dev_id_list[i] == id) {
_ss_dev_id_list[i] = 0;
return 1;
}
}
return 0;
}

143
libsicksaxis/sicksaxis.h Normal file
View File

@ -0,0 +1,143 @@
#ifndef _SICKSAXIS_H_
#define _SICKSAXIS_H_
#include <gccore.h>
#define SS_HEAP_SIZE 4096
#define SS_MAX_DEV 8
#define SS_VENDOR_ID 0x054C
#define SS_PRODUCT_ID 0x0268
#define SS_PAYLOAD_SIZE 49
struct SS_BUTTONS
{
uint8_t left : 1;
uint8_t down : 1;
uint8_t right : 1;
uint8_t up : 1;
uint8_t start : 1;
uint8_t R3 : 1;
uint8_t L3 : 1;
uint8_t select : 1;
uint8_t square : 1;
uint8_t cross : 1;
uint8_t circle : 1;
uint8_t triangle : 1;
uint8_t R1 : 1;
uint8_t L1 : 1;
uint8_t R2 : 1;
uint8_t L2 : 1;
uint8_t not_used : 7;
uint8_t PS : 1;
};
struct SS_ANALOG
{
uint8_t x;
uint8_t y;
};
struct SS_DPAD_SENSITIVE
{
uint8_t up;
uint8_t right;
uint8_t down;
uint8_t left;
};
struct SS_SHOULDER_SENSITIVE
{
uint8_t L2;
uint8_t R2;
uint8_t L1;
uint8_t R1;
};
struct SS_BUTTON_SENSITIVE
{
uint8_t triangle;
uint8_t circle;
uint8_t cross;
uint8_t square;
};
struct SS_MOTION
{
uint16_t acc_x;
uint16_t acc_y;
uint16_t acc_z;
uint16_t z_gyro;
};
struct SS_GAMEPAD
{
uint8_t hid_data;
uint8_t unk0;
struct SS_BUTTONS buttons;
uint8_t unk1;
struct SS_ANALOG left_analog;
struct SS_ANALOG right_analog;
uint32_t unk2;
struct SS_DPAD_SENSITIVE dpad_sens;
struct SS_SHOULDER_SENSITIVE shoulder_sens;
struct SS_BUTTON_SENSITIVE button_sens;
uint16_t unk3;
uint8_t unk4;
uint8_t status;
uint8_t power_rating;
uint8_t comm_status;
uint32_t unk5;
uint32_t unk6;
uint8_t unk7;
struct SS_MOTION motion;
}__attribute__((packed));
struct SS_ATTRIBUTE_RUMBLE
{
uint8_t duration_right;
uint8_t power_right;
uint8_t duration_left;
uint8_t power_left;
};
struct SS_ATTRIBUTES
{
struct SS_ATTRIBUTE_RUMBLE rumble;
int led;
};
typedef void (*ss_usb_callback)(void *usrdata);
struct ss_device {
struct SS_GAMEPAD pad;
struct SS_ATTRIBUTES attributes;
int device_id, fd;
int connected, enabled, reading;
ss_usb_callback read_callback;
ss_usb_callback removal_callback;
void *read_usrdata, *removal_usrdata;
}__attribute__((aligned(32)));
int ss_init();
int ss_initialize(struct ss_device *dev);
int ss_open(struct ss_device *dev);
int ss_close(struct ss_device *dev);
int ss_is_connected(struct ss_device *dev);
int ss_set_read_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata);
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata);
int ss_start_reading(struct ss_device *dev);
int ss_stop_reading(struct ss_device *dev);
int ss_set_led(struct ss_device *dev, int led);
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left);
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac);
int ss_get_paired_mac(struct ss_device *dev, uint8_t *mac);
int ss_set_paired_mac(struct ss_device *dev, const uint8_t *mac);
#endif

98
libwupc/Makefile Normal file
View File

@ -0,0 +1,98 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>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 := libwupc
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
INCDIR := $(LIBOGC_INC)/wupc/
INCFILE := include/wupc/wupc
LIBFILE := lib/$(TARGET)
#---------------------------------------------------------------------------------
# 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
#---------------------------------------------------------------------------------
install:
@echo Installing ...
@mkdir -p $(INCDIR)
@install -v -m 644 $(LIBFILE).a $(LIBOGC_LIB)
@install -v -m 644 $(INCFILE).h $(INCDIR)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).a: $(OFILES)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,59 @@
/****************************************************************************
* Copyright (C) 2014 FIX94
*
* 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 _WUPC_H_
#define _WUPC_H_
#ifdef __cplusplus
extern "C" {
#endif
struct WUPCData {
s16 xAxisL;
s16 xAxisR;
s16 yAxisL;
s16 yAxisR;
u32 button;
u8 battery;
u8 extra;
};
#define WUPC_EXTRA_BUTTON_RSTICK 0x01
#define WUPC_EXTRA_BUTTON_LSTICK 0x02
#define WUPC_EXTRA_CHARGING 0x04
#define WUPC_EXTRA_USBCONNECTED 0x08
void WUPC_Init();
void WUPC_Disconnect(u8 chan);
void WUPC_Shutdown();
struct WUPCData *WUPC_Data(u8 chan);
void WUPC_Rumble(u8 chan, bool rumble);
u32 WUPC_UpdateButtonStats();
u32 WUPC_ButtonsUp(u8 chan);
u32 WUPC_ButtonsDown(u8 chan);
u32 WUPC_ButtonsHeld(u8 chan);
s16 WUPC_lStickX(u8 chan);
s16 WUPC_lStickY(u8 chan);
s16 WUPC_rStickX(u8 chan);
s16 WUPC_rStickY(u8 chan);
u8 WUPC_extra(u8 chan);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,80 @@
Index: Makefile
===================================================================
--- Makefile (revision 3)
+++ Makefile (working copy)
@@ -20,7 +20,9 @@
SOURCES := source
DATA := data
INCLUDES := include
-
+INCDIR := $(LIBOGC_INC)/wupc/
+INCFILE := include/wupc/wupc
+LIBFILE := lib/$(TARGET)
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
@@ -72,7 +74,13 @@
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).a
+#---------------------------------------------------------------------------------
+install:
+ @echo Installing ...
+ @mkdir -p $(INCDIR)
+ @install -v -m 644 $(LIBFILE).a $(LIBOGC_LIB)
+ @install -v -m 644 $(INCFILE).h $(INCDIR)
#---------------------------------------------------------------------------------
else
Index: usage.txt
===================================================================
--- usage.txt (revision 3)
+++ usage.txt (working copy)
@@ -1,23 +1,23 @@
-libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94
-WiiU Pro Controller Documentation from TeHaxor69
-
-1. Copy the "lib" and "include" folder into your "portlibs" folder
-
-2. Make these modifications to your Makefile:
--add "-lwupc" right behind "-lwiiuse" to your LIBS
--add ",-wrap,wiiuse_register" to your LDFLAGS
-
-3. Modify your code like this:
--make sure to include <wupc/wupc.h> in all files you use WUPC calls
--call "WUPC_Init" before "WPAD_Init"
--call "WUPC_Shutdown" before "WPAD_Shutdown"
--either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling
--if you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_UpdateButtonStats" before "WPAD_ScanPads",
-if you dont use any of these you can ignore "WUPC_UpdateButtonStats"
-
-Notes:
--The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that
--The Buttons are using the same layout as the classic controller buttons, use the "WPAD_CLASSIC_BUTTON_" definitions in <wiiuse/wpad.h>
--The Battery Status goes from 0 (critical) to 4 (full)
-
+libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94
+WiiU Pro Controller Documentation from TeHaxor69
+
+1. Copy the "lib" and "include" folder into your "portlibs" folder
+
+2. Make these modifications to your Makefile:
+-add "-lwupc" right after "-lwiiuse" to your LIBS
+-add ",-wrap,wiiuse_register" to your LDFLAGS
+
+3. Modify your code like this:
+-make sure to include <wupc/wupc.h> in all files you use WUPC calls
+-call "WUPC_Init" before "WPAD_Init"
+-call "WUPC_Shutdown" before "WPAD_Shutdown"
+-either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling
+-if you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_UpdateButtonStats" before "WPAD_ScanPads",
+if you dont use any of these you can ignore "WUPC_UpdateButtonStats"
+
+Notes:
+-The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that
+-The Buttons are using the same layout as the classic controller buttons, use the "WPAD_CLASSIC_BUTTON_" definitions in <wiiuse/wpad.h>
+-The Battery Status goes from 0 (critical) to 4 (full)
+
Have Fun!
\ No newline at end of file

View File

@ -0,0 +1,76 @@
Index: include/wupc/wupc.h
===================================================================
--- include/wupc/wupc.h (revision 3)
+++ include/wupc/wupc.h (working copy)
@@ -50,6 +50,7 @@
s16 WUPC_lStickY(u8 chan);
s16 WUPC_rStickX(u8 chan);
s16 WUPC_rStickY(u8 chan);
+u8 WUPC_extra(u8 chan);
#ifdef __cplusplus
}
Index: Makefile
===================================================================
--- Makefile (revision 3)
+++ Makefile (working copy)
@@ -20,7 +20,9 @@
SOURCES := source
DATA := data
INCLUDES := include
-
+INCDIR := $(LIBOGC_INC)/wupc/
+INCFILE := include/wupc/wupc
+LIBFILE := lib/$(TARGET)
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
@@ -72,7 +74,13 @@
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).a
+#---------------------------------------------------------------------------------
+install:
+ @echo Installing ...
+ @mkdir -p $(INCDIR)
+ @install -v -m 644 $(LIBFILE).a $(LIBOGC_LIB)
+ @install -v -m 644 $(INCFILE).h $(INCDIR)
#---------------------------------------------------------------------------------
else
Index: source/wupc.c
===================================================================
--- source/wupc.c (revision 3)
+++ source/wupc.c (working copy)
@@ -230,7 +230,7 @@
{
if(__WUPC_Connected[i] == NULL)
return ret;
- newstate = __WUPC_PadData[i].button;
+ newstate = __WUPC_PadData[i].button | (__WUPC_PadData[i].extra & WUPC_EXTRA_BUTTON_RSTICK) | (__WUPC_PadData[i].extra & WUPC_EXTRA_BUTTON_LSTICK);
oldstate = __WUPC_PadButtons[i].state;
__WUPC_PadButtons[i].state = newstate;
__WUPC_PadButtons[i].up = oldstate & ~newstate;
@@ -275,3 +275,8 @@
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].yAxisR;
}
+u8 WUPC_extra(u8 chan)
+{
+ if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
+ return __WUPC_PadData[chan].extra;
+}
Index: usage.txt
===================================================================
--- usage.txt (revision 3)
+++ usage.txt (working copy)
@@ -4,7 +4,7 @@
1. Copy the "lib" and "include" folder into your "portlibs" folder
2. Make these modifications to your Makefile:
--add "-lwupc" right behind "-lwiiuse" to your LIBS
+-add "-lwupc" right after "-lwiiuse" to your LIBS
-add ",-wrap,wiiuse_register" to your LDFLAGS
3. Modify your code like this:

282
libwupc/source/wupc.c Normal file
View File

@ -0,0 +1,282 @@
/****************************************************************************
* Copyright (C) 2014 FIX94
*
* 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/>.
****************************************************************************/
/* WiiU Pro Controller Documentation from TeHaxor69 */
#include <gccore.h>
#include <ogc/machine/processor.h>
#include <wiiuse/wiiuse.h>
#include <stdio.h>
#include <string.h>
#include "wupc_structs.h"
#include "wupc/wupc.h"
extern __typeof(wiiuse_register) __real_wiiuse_register;
static vu32 __WUPC_ChannelsUsed = 0;
static conf_pads __WUPC_Devices;
static struct WUPCStat *__WUPC_Connected[4];
static struct WUPCStat __WUPC_Status[CONF_PAD_MAX_REGISTERED];
static struct WUPCData __WUPC_PadData[4];
static struct WUPCButtons __WUPC_PadButtons[4];
static u32 __WUPC_Inited = 0;
static const u8 __WUPC_LEDState[] = { 0x10, 0x20, 0x40, 0x80 };
#define CHAN_MAX 4
#define TRANSFER_CALIBRATE 0
#define TRANSFER_DONE 1
static void __WUPC_SetLED(struct bte_pcb *sock, u32 state)
{
u8 buf[2];
buf[0] = 0x11;
buf[1] = __WUPC_LEDState[state];
bte_senddata(sock,buf,2);
}
static s32 __WUPC_HandleData(void *arg,void *buffer,u16 len)
{
struct WUPCStat *stat = (struct WUPCStat*)arg;
u32 chan = stat->channel;
if(*(u8*)buffer == 0x3D && len == 22)
{
if(stat->transferstate == TRANSFER_CALIBRATE)
{
stat->xAxisLmid = bswap16(*(u16*)(((u8*)buffer)+1));
stat->xAxisRmid = bswap16(*(u16*)(((u8*)buffer)+3));
stat->yAxisLmid = bswap16(*(u16*)(((u8*)buffer)+5));
stat->yAxisRmid = bswap16(*(u16*)(((u8*)buffer)+7));
stat->transferstate = TRANSFER_DONE;
}
__WUPC_PadData[chan].xAxisL = bswap16(*(u16*)(((u8*)buffer)+1)) - stat->xAxisLmid;
__WUPC_PadData[chan].xAxisR = bswap16(*(u16*)(((u8*)buffer)+3)) - stat->xAxisRmid;
__WUPC_PadData[chan].yAxisL = bswap16(*(u16*)(((u8*)buffer)+5)) - stat->yAxisLmid;
__WUPC_PadData[chan].yAxisR = bswap16(*(u16*)(((u8*)buffer)+7)) - stat->yAxisRmid;
__WUPC_PadData[chan].button = ~(*(u16*)(((u8*)buffer)+9)) << 16;
u8 extradata = ~(*(((u8*)buffer)+11));
__WUPC_PadData[chan].battery = (extradata >> 4) & 0x7;
__WUPC_PadData[chan].extra = extradata & 0xF;
}
return ERR_OK;
}
static s32 __WUPC_HandleConnect(void *arg,struct bte_pcb *pcb,u8 err)
{
struct WUPCStat *stat = (struct WUPCStat*)arg;
if(__WUPC_ChannelsUsed >= CHAN_MAX)
{
bte_disconnect(pcb);
return err;
}
stat->channel = __WUPC_ChannelsUsed;
stat->rumble = 0;
__WUPC_SetLED(pcb, __WUPC_ChannelsUsed);
u8 buf[3];
buf[0] = 0x12;
buf[1] = 0x00;
buf[2] = 0x3D;
bte_senddata(pcb,buf,3);
stat->transferstate = TRANSFER_CALIBRATE;
__WUPC_Connected[__WUPC_ChannelsUsed] = stat;
__WUPC_ChannelsUsed++;
return err;
}
static s32 __WUPC_HandleDisconnect(void *arg,struct bte_pcb *pcb __attribute__((unused)),u8 err)
{
struct WUPCStat *stat = (struct WUPCStat*)arg;
if(__WUPC_ChannelsUsed) __WUPC_ChannelsUsed--;
u32 i;
for(i = stat->channel; i < 3; ++i)
__WUPC_Connected[i] = __WUPC_Connected[i+1];
__WUPC_Connected[3] = NULL;
for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i)
{
if(__WUPC_Status[i].channel > stat->channel && __WUPC_Status[i].channel != CHAN_MAX)
{
__WUPC_Status[i].channel--;
__WUPC_SetLED(__WUPC_Status[i].sock, __WUPC_Status[i].channel);
}
}
stat->channel = CHAN_MAX;
return err;
}
int __WUPC_RegisterPad(struct WUPCStat *stat, struct bd_addr *_bdaddr)
{
stat->channel = CHAN_MAX;
stat->bdaddr = *_bdaddr;
if(stat->sock == NULL)
{
stat->sock = bte_new();
if(stat->sock == NULL)
return ERR_OK;
}
bte_arg(stat->sock, stat);
bte_received(stat->sock, __WUPC_HandleData);
bte_disconnected(stat->sock, __WUPC_HandleDisconnect);
bte_registerdeviceasync(stat->sock, _bdaddr, __WUPC_HandleConnect);
return ERR_OK;
}
int __wrap_wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr))
{
if(__WUPC_Inited)
{
u8 got_addr[] = { bdaddr->addr[5], bdaddr->addr[4], bdaddr->addr[3], bdaddr->addr[2], bdaddr->addr[1], bdaddr->addr[0] };
u32 i;
for(i = 0; i < __WUPC_Devices.num_registered; ++i)
{
if(strstr(__WUPC_Devices.registered[i].name, "-UC") != NULL)
{
u8 *cur_bdaddr = __WUPC_Devices.registered[i].bdaddr;
if(memcmp(cur_bdaddr, got_addr, 6) == 0)
return __WUPC_RegisterPad(&__WUPC_Status[i], bdaddr);
}
}
}
return __real_wiiuse_register(wml,bdaddr,assign_cb);
}
void WUPC_Init()
{
if(__WUPC_Inited == 1)
return;
if(CONF_GetPadDevices(&__WUPC_Devices) < 0)
return;
u32 i;
for(i = 0; i < CHAN_MAX; ++i)
__WUPC_Connected[i] = NULL;
for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i)
__WUPC_Status[i].channel = CHAN_MAX;
__WUPC_ChannelsUsed = 0;
__WUPC_Inited = 1;
}
void WUPC_Disconnect(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return;
bte_disconnect(__WUPC_Connected[chan]->sock);
}
void WUPC_Shutdown()
{
if(__WUPC_Inited == 0)
return;
__WUPC_Inited = 0;
u32 i;
for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i)
{
if(__WUPC_Status[i].channel != CHAN_MAX)
bte_disconnect(__WUPC_Status[i].sock);
}
}
struct WUPCData *WUPC_Data(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return NULL;
return &__WUPC_PadData[chan];
}
void WUPC_Rumble(u8 chan, bool rumble)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return;
u8 buf[2];
buf[0] = 0x11;
buf[1] = __WUPC_LEDState[chan] | rumble;
bte_senddata(__WUPC_Connected[chan]->sock,buf,2);
}
u32 WUPC_UpdateButtonStats()
{
u32 newstate, oldstate;
u32 i, ret = 0;
for(i = 0; i < CHAN_MAX; ++i)
{
if(__WUPC_Connected[i] == NULL)
return ret;
newstate = __WUPC_PadData[i].button | (__WUPC_PadData[i].extra & WUPC_EXTRA_BUTTON_RSTICK) | (__WUPC_PadData[i].extra & WUPC_EXTRA_BUTTON_LSTICK);
oldstate = __WUPC_PadButtons[i].state;
__WUPC_PadButtons[i].state = newstate;
__WUPC_PadButtons[i].up = oldstate & ~newstate;
__WUPC_PadButtons[i].down = newstate & (newstate ^ oldstate);
ret |= (1<<i);
}
return ret;
}
u32 WUPC_ButtonsUp(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadButtons[chan].up;
}
u32 WUPC_ButtonsDown(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadButtons[chan].down;
}
u32 WUPC_ButtonsHeld(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadButtons[chan].state;
}
s16 WUPC_lStickX(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].xAxisL;
}
s16 WUPC_lStickY(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].yAxisL;
}
s16 WUPC_rStickX(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].xAxisR;
}
s16 WUPC_rStickY(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].yAxisR;
}
u8 WUPC_extra(u8 chan)
{
if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0;
return __WUPC_PadData[chan].extra;
}

View File

@ -0,0 +1,24 @@
#ifndef _WUPC_STRUCTS_H_
#define _WUPC_STRUCTS_H_
struct WUPCStat {
u32 connected;
u32 transferstate;
u32 channel;
u32 rumble;
s16 xAxisLmid;
s16 xAxisRmid;
s16 yAxisLmid;
s16 yAxisRmid;
struct bte_pcb *sock;
struct bd_addr bdaddr;
};
struct WUPCButtons {
u32 up;
u32 down;
u32 state;
};
#endif

23
libwupc/usage.txt Normal file
View File

@ -0,0 +1,23 @@
libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94
WiiU Pro Controller Documentation from TeHaxor69
1. Copy the "lib" and "include" folder into your "portlibs" folder
2. Make these modifications to your Makefile:
-add "-lwupc" right after "-lwiiuse" to your LIBS
-add ",-wrap,wiiuse_register" to your LDFLAGS
3. Modify your code like this:
-make sure to include <wupc/wupc.h> in all files you use WUPC calls
-call "WUPC_Init" before "WPAD_Init"
-call "WUPC_Shutdown" before "WPAD_Shutdown"
-either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling
-if you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_UpdateButtonStats" before "WPAD_ScanPads",
if you dont use any of these you can ignore "WUPC_UpdateButtonStats"
Notes:
-The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that
-The Buttons are using the same layout as the classic controller buttons, use the "WPAD_CLASSIC_BUTTON_" definitions in <wiiuse/wpad.h>
-The Battery Status goes from 0 (critical) to 4 (full)
Have Fun!