diff --git a/README.md b/README.md index 6aee990a1..9c7ec7352 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,20 @@ A Wii Homebrew Project to play GC Games on Wii and vWii on Wii U 3. Connect your storage device to your Wii or Wii U and start The Homebrew Channel. 4. Select Nintendont. +### Compiling: +For compile Nintendont yourself, get the following versions of the toolchain compiling PPC tools: +* **devkitARM r53-1** +* **devkitPPC r35-2** +* **libOGC 1.8.23-1** + +These versions can be downloaded here: https://www.mediafire.com/folder/j0juqb5vvd6z5/devkitPro_archives + +On Windows, run the "Build.bat" batch script for build Nintendont. + +On Unix, run the "Build.sh" script. + +Please use these specific versions for compiling Nintendont, **because if you try to compile them on latest dkARM/dkPPC/libOGC, you'll get a lot of compiler warnings and your build will crash when attemping to return to Nintendont menu**, so be warned about that. + ### Notes * The Wii and Wii U SD card slot is known to be slow. If you're using an SD card and are having performance issues, consider either using a USB SD reader or a USB hard drive. * USB flash drives are known to be problematic. diff --git a/common/include/CommonConfig.h b/common/include/CommonConfig.h index da605104c..d85dce41b 100644 --- a/common/include/CommonConfig.h +++ b/common/include/CommonConfig.h @@ -5,7 +5,7 @@ #include "NintendontVersion.h" #include "Metadata.h" -#define NIN_CFG_VERSION 0x00000009 +#define NIN_CFG_VERSION 0x0000000A #define NIN_CFG_MAXPAD 4 @@ -24,6 +24,7 @@ typedef struct NIN_CFG signed char VideoScale; signed char VideoOffset; unsigned char NetworkProfile; + unsigned int WiiUGamepadSlot; } NIN_CFG; enum ninconfigbitpos diff --git a/common/include/NintendontVersion.h b/common/include/NintendontVersion.h index bc7dbd7dc..5459cf9fe 100644 --- a/common/include/NintendontVersion.h +++ b/common/include/NintendontVersion.h @@ -2,7 +2,7 @@ #define __NINTENDONT_VERSION_H__ #define NIN_MAJOR_VERSION 6 -#define NIN_MINOR_VERSION 489 +#define NIN_MINOR_VERSION 502 #define NIN_VERSION ((NIN_MAJOR_VERSION << 16) | NIN_MINOR_VERSION) diff --git a/controllerconfigs/Saitek_P990_Dual_Analog_pad.ini b/controllerconfigs/Saitek_P990_Dual_Analog_pad.ini new file mode 100644 index 000000000..2a6b59741 --- /dev/null +++ b/controllerconfigs/Saitek_P990_Dual_Analog_pad.ini @@ -0,0 +1,26 @@ +[Saitek P990 Dual Analog pad] +VID=06A3 +PID=040B +Polltype=1 +DPAD=1 +DigitalLR=0 +Power=7,20 +A=6,4 +B=6,2 +X=7,1 +Y=7,2 +Z=6,20 +L=6,40 +R=6,80 +S=7,10 +Left=5,7 +Down=5,5 +Right=5,3 +Up=5,1 +StickX=0 +StickY=1 +CStickX=2 +CStickY=3 +RAnalog=7,8 +LAnalog=7,4 + diff --git a/controllerconfigs/controller_8Bitdo_SNES30_Pro.ini b/controllerconfigs/controller_8Bitdo_SNES30_Pro.ini new file mode 100644 index 000000000..ebdcf04d1 --- /dev/null +++ b/controllerconfigs/controller_8Bitdo_SNES30_Pro.ini @@ -0,0 +1,30 @@ +[8Bitdo SNES30 Pro MAC Mode] +VID=054C +PID=05C4 +Polltype=1 +DPAD=1 +DigitalLR=0 +A=5,40 +B=5,20 +X=5,80 +Y=5,10 +CStickY=4 +CStickX=3 +StickY=2 +StickX=1 +S=6,20 +Up=5,00 +Right=5,02 +Left=5,06 +Down=5,04 +L=6,04 +R=6,08 +Z=6,02 +Power=6,10 +MultiIn=0 +RightUp=5,01 +DownRight=5,03 +DownLeft=5,05 +UpLeft=5,07 +LAnalog=8 +RAnalog=9 diff --git a/controllerconfigs/controller_Generic_GC Controller Adapter.ini b/controllerconfigs/controller_Generic_GC Controller Adapter.ini new file mode 100644 index 000000000..ccf79e457 --- /dev/null +++ b/controllerconfigs/controller_Generic_GC Controller Adapter.ini @@ -0,0 +1,46 @@ +; Configuration file made for 'Generic GC Controller Adapter' device. +; The label behind this contained the following information - +; 'GC Controller Adapter For Switch/Wii U/PC ITEM TO HS-SW305' +; Device must be set in 'PC' mode. +; Made by cesarmades. + +[Generic GC Controller Adapter] +VID=0079 +PID=1846 + +Polltype=1 + +; Multiple input (several ports). Don't know if it's the same settings for 2 ports than 4 ports. +MultiIn=1 +MultiInValue=01 + +A=1,02 +B=1,04 +X=1,01 +Y=1,08 + +Z=1,80 + +; Notes from what was seen in other files: +; 1 = Typical Digital input | 2 = Mix of both? +DigitalLR=2 +L=1,10 +R=1,20 +LAnalog=7 +RAnalog=8 + +; Power= +S=2,02 + +; Similar to the HID2VPAD functions: +; 0 = NORMAL | 1 = HAT | etc +DPAD=0 +Left=2,80 +Right=2,20 +Up=2,10 +Down=2,40 + +StickX=3 +StickY=4 +CStickX=6 +CStickY=5 diff --git a/controllerconfigs/controller_Generic_USB_Gamepad_PID=0810_VID=e501.ini b/controllerconfigs/controller_Generic_USB_Gamepad_PID=0810_VID=e501.ini new file mode 100644 index 000000000..3948ac493 --- /dev/null +++ b/controllerconfigs/controller_Generic_USB_Gamepad_PID=0810_VID=e501.ini @@ -0,0 +1,52 @@ +[Generic USB Gamepad] +VID=0810 +PID=e501 + +# Polltype: Use 1 (so far only the ps3 controller needed 0) +Polltype=1 +DigitalLR=1 + +# [Button]=[offset],[mask] +X=5,10 +A=5,20 +B=5,40 +Y=5,80 + +# L, R, Z left, Z right +L=6,01 +R=6,02 +ZL=6,04 +Z=6,08 + +# Select, Start +Power=6,10 +S=6,20 + +# Certain Pads use BITs for each dpad direction other use numbers going form 0 to 7 for each direction. +# An easy test for this is if one direction doesn't change any bits then use 1 and fill in all 8 values +# for the DPAD otherwise use 0 and just fill in the four values. +# (the stick value for center is 7F and the extreme values can be mapped to dpad instead if desired) +#DPAD=1 +#Right=3,FF +#Left=3,00 +#Down=4,FF +#Up=4,00 + +# Composite directions have 2 values modified simultaneously so can't be configured +# Center position is xx xx xx 7F 7F xx xx xx xx +# 3,FF FF +#DownRight= +# 3,00 FF +#DownLeft= +# 3,00 00 +#UpLeft= +# 3,FF 00 +#RightUp= + +StickX=3,0,100 +StickY=4,0,100 + +# When the stick is missing the value is fixed at 80 +CStickX=1 +CStickY=2 + diff --git a/controllerconfigs/controller_Genius_MaxFire G-12UV.ini b/controllerconfigs/controller_Genius_MaxFire G-12UV.ini new file mode 100644 index 000000000..fc1fb5041 --- /dev/null +++ b/controllerconfigs/controller_Genius_MaxFire G-12UV.ini @@ -0,0 +1,38 @@ +[Genius MaxFire G-12U VIBRATION] +VID=0583 +PID=A009 +Polltype=1 +DPAD=1 +DigitalLR=1 + +; 1 +A=5,01 +; 3 +B=5,04 +; 2 +X=5,02 +; 4 +Y=5,08 +; 6 +Z=5,20 +; 7 +L=5,40 +; 8 +R=5,80 +; 10 +S=6,02 + +Left=4,06 +Down=4,04 +Right=4,02 +Up=4,00 +RightUp=4,01 +DownRight=4,03 +DownLeft=4,05 +UpLeft=4,07 + +StickX=0 +StickY=1 + +CStickX=2 +CStickY=3 diff --git a/controllerconfigs/controller_Gravis_Eliminator_AfterShock.ini b/controllerconfigs/controller_Gravis_Eliminator_AfterShock.ini new file mode 100644 index 000000000..0600c13d8 --- /dev/null +++ b/controllerconfigs/controller_Gravis_Eliminator_AfterShock.ini @@ -0,0 +1,56 @@ +[Gravis Eliminator AfterShock] +VID=047D +PID=4006 +Polltype=1 +DPAD=1 +B=6,02 +A=6,04 +Y=6,01 +X=6,08 +L=6,10 +ZL=6,40 +Z=6,80 +R=6,20 +S=7,02 +Power=7,03 +Left=4,00 +Down=5,FF +Right=4,FF +Up=5,00 +StickX=0 +StickY=1 +CStickX=3 +CStickY=2 +DigitalLR=1 +LAnalog=0 +RAnalog=0 +Rumble=1 +RumbleType=0 +RumbleDataLen=05 +RumbleDataOn=01,00,00,7F,7F +RumbleDataOff=01,00,00,00,00 +RumbleTransferLen=05 +RumbleTransfers=1 + +#Gravis Eliminator AfterShock for Nintendon't +#--------------------------------------------- +#Controller Type: Arcade-style/dual-analog gamepad (like DualShock 2) +#Rumble Support: Force Feedback +#Special Features: Analog sticks, D-pad, precision control toggles +#Note: This controller is probably common for Windows 95-98 & up. + +#Button Setup: +# D-Pad: GameCube D-Pad +# Left Control Stick: Control Stick +# Right Control Stick: C Stick +# Button 1: Y +# Button 2: B +# Button 3: A +# Button 4: X +# Button 5: L +# Button 6: R +# Button 7: Half shoulder button force +# Button 8: Z +# Button 9: unused +# Button 10: Start/Pause +# Button 9 & Button 10: Power diff --git a/controllerconfigs/controller_Gravis_Eliminator_GamePad_Pro.ini b/controllerconfigs/controller_Gravis_Eliminator_GamePad_Pro.ini new file mode 100644 index 000000000..4e441adde --- /dev/null +++ b/controllerconfigs/controller_Gravis_Eliminator_GamePad_Pro.ini @@ -0,0 +1,59 @@ +[Gravis Eliminator GamePad Pro] +VID=047D +PID=4005 +Polltype=1 +DPAD=0 +Power=3,03 +A=2,04 +B=2,02 +X=2,08 +Y=2,01 +Z=2,20 +L=2,40 +R=2,80 +S=3,02 +#Left=2,26 +#Down=2,24 +#Right=2,22 +#Up=2,20 +#RightUp=2,21 +#DownRight=2,23 +#DownLeft=2,25 +#UpLeft=2,27 +StickX=0 +StickY=1 +#CStickX=5 +#CStickY=6 +DigitalLR=1 +LAnalog=0 +RAnalog=0 + +#Gravis Eliminator GamePad Pro for Nintendon't +#--------------------------------------------- +#Controller Type: Arcade/Retro gamepad +#Rumble Support: None +#Special Features: Analog D-pad, precision control toggle + +#Button Setup: +# D-Pad: Control Stick +# Button 1: Y +# Button 2: B +# Button 3: A +# Button 4: X +# Button 5: unused (Full shoulder button force) +# Button 6: Z +# Button 7: L +# Button 8: R +# Button 9: unused +# Button 10: Start/Pause +# Button 9 & Button 10: Power + +#Recommended Games: +# * Ikaruga +# * Chaos Field Expanded +# * Mobile Light Force 2 / Castle of Shikigami +# * Capcom vs. SNK EO +# * Rave Master +# * Super Smash Bros. Melee +# * Sonic Gems Collection +# * Sonic Mega Collection diff --git a/controllerconfigs/controller_Logitech_F310.ini b/controllerconfigs/controller_Logitech_F310.ini index 157152a13..7302e9138 100644 --- a/controllerconfigs/controller_Logitech_F310.ini +++ b/controllerconfigs/controller_Logitech_F310.ini @@ -3,6 +3,7 @@ VID=046D PID=C216 Polltype=1 DPAD=1 +DigitalLR=1 # This pad only supports digital triggers, doesn't work with games like Luigi's mansion otherwise A=4,20 B=4,40 X=4,10 @@ -10,6 +11,7 @@ Y=4,80 Z=5,02 L=5,04 R=5,08 +ZL=5,01 # Adds the ZL switch in the L1 position to allow half-presses S=5,20 Power=5,10 Left=4,06 @@ -25,4 +27,4 @@ StickY=1 CStickX=2 CStickY=3 LAnalog=0F -RAnalog=0E \ No newline at end of file +RAnalog=0E diff --git a/controllerconfigs/controller_PowerA_Wired_PS3.ini b/controllerconfigs/controller_PowerA_Wired_PS3.ini new file mode 100644 index 000000000..687e95a94 --- /dev/null +++ b/controllerconfigs/controller_PowerA_Wired_PS3.ini @@ -0,0 +1,49 @@ +[POWER A WIRED PS3 Controller] +# Model Num: 1429765-01 + +VID=20D6 +PID=CA6D + +Polltype=1 +DPAD=1 + +# Enable Analog triggers +DigitalLR=2 + +MultiIn=0 +MultiInValue=01 + +# PS3 "Home" Button +Power=1,10 + +A=0,02 +B=0,01 +X=0,04 +Y=0,08 +Z=0,20 +L=11,F0 +R=12,F0 + +# Start +S=1,02 + +# DPad +Left=2,06 +Down=2,04 +Right=2,02 +Up=2,00 +RightUp=2,01 +DownRight=2,03 +DownLeft=2,05 +UpLeft=2,07 + +# Left Analog Stick +StickX=3 +StickY=4 + +# Right Analog Stick +CStickX=5 +CStickY=6 + +LAnalog=11 +RAnalog=12 \ No newline at end of file diff --git a/controllerconfigs/controller_UnderControl_Switch.ini b/controllerconfigs/controller_UnderControl_Switch.ini new file mode 100644 index 000000000..8a8617f17 --- /dev/null +++ b/controllerconfigs/controller_UnderControl_Switch.ini @@ -0,0 +1,28 @@ +[UnderControl Switch] +VID=0079 +PID=181C +Polltype=1 +DPAD=1 +DigitalLR=1 +A=0,02 +B=0,01 +X=0,10 +Y=0,08 +CStickY=6 +CStickX=5 +StickY=4 +StickX=3 +S=1,08 +Up=2,00 +Right=2,02 +Left=2,06 +Down=2,04 +L=0,40 +R=0,80 +ZL=1,01 +Z=1,02 +Power=1,10 +RightUp=2,01 +DownRight=2,03 +DownLeft=2,05 +UpLeft=2,07 diff --git a/controllerconfigs/controller_brook_ps3_4_fighting_board.ini b/controllerconfigs/controller_brook_ps3_4_fighting_board.ini new file mode 100644 index 000000000..a40923e8d --- /dev/null +++ b/controllerconfigs/controller_brook_ps3_4_fighting_board.ini @@ -0,0 +1,30 @@ +[Brook PS3/PS4 fighting board] +VID=0C12 +PID=0EF9 +Polltype=1 +DPAD=1 +DigitalLR=1 +MultiIn=0 +LAnalog=0 +RAnalog=0 +Power=1,04 +Left=2,06 +Down=2,04 +Right=2,02 +Up=2,00 +RightUp=2,01 +DownRight=2,03 +DownLeft=2,05 +UpLeft=2,07 +A=0,01 +B=0,02 +X=0,08 +Y=0,04 +Z=0,10 +L=0,40 +R=0,80 +S=1,02 +StickX=3 +StickY=4 +CStickX=5 +CStickY=6 diff --git a/controllerconfigs/controller_ps4.ini b/controllerconfigs/controller_ps4.ini index e9a6ea982..4be26707f 100644 --- a/controllerconfigs/controller_ps4.ini +++ b/controllerconfigs/controller_ps4.ini @@ -4,6 +4,7 @@ PID=05C4 Polltype=1 DPAD=1 DigitalLR=2 +Power=6,10 A=5,40 B=5,20 X=5,80 @@ -26,4 +27,10 @@ CStickX=3 CStickY=4 LAnalog=8 RAnalog=9 -Power=6,10 \ No newline at end of file +Rumble=1 +RumbleType=1 +RumbleDataLen=06 +RumbleDataOn=05,01,00,00,FF,FF +RumbleDataOff=05,01,00,00,00,00 +RumbleTransferLen=06 +RumbleTransfers=1 \ No newline at end of file diff --git a/controllerconfigs/controller_ps4v2.ini b/controllerconfigs/controller_ps4v2.ini index a70e63c36..0e69521d1 100644 --- a/controllerconfigs/controller_ps4v2.ini +++ b/controllerconfigs/controller_ps4v2.ini @@ -4,6 +4,7 @@ PID=09CC Polltype=1 DPAD=1 DigitalLR=2 +Power=6,10 A=5,40 B=5,20 X=5,80 @@ -26,4 +27,10 @@ CStickX=3 CStickY=4 LAnalog=8 RAnalog=9 -Power=6,10 \ No newline at end of file +Rumble=1 +RumbleType=1 +RumbleDataLen=06 +RumbleDataOn=05,01,00,00,FF,FF +RumbleDataOff=05,01,00,00,00,00 +RumbleTransferLen=06 +RumbleTransfers=1 \ No newline at end of file diff --git a/controllerconfigs/controller_ps5.ini b/controllerconfigs/controller_ps5.ini new file mode 100644 index 000000000..d0b7789f9 --- /dev/null +++ b/controllerconfigs/controller_ps5.ini @@ -0,0 +1,29 @@ +[DualSense] +VID=054C +PID=0CE6 +Polltype=1 +DPAD=1 +DigitalLR=2 +Power=9,10 +A=8,40 +B=8,20 +X=8,80 +Y=8,10 +Z=9,02 +L=9,04 +R=9,08 +S=9,20 +Left=8,06 +Down=8,04 +Right=8,02 +Up=8,00 +RightUp=8,01 +DownRight=8,03 +DownLeft=8,05 +UpLeft=8,07 +StickX=1 +StickY=2 +CStickX=3 +CStickY=4 +LAnalog=5 +RAnalog=6 \ No newline at end of file diff --git a/controllerconfigs/controller_psx_ps2_splitter.ini b/controllerconfigs/controller_psx_ps2_splitter.ini new file mode 100644 index 000000000..9bf457cb4 --- /dev/null +++ b/controllerconfigs/controller_psx_ps2_splitter.ini @@ -0,0 +1,53 @@ +[PSX/PS2 Splitter Controller] +VID=0925 +PID=8866 +Polltype=1 +DPAD=1 +DigitalLR=1 +MultiIn=4 +MultiInValue=02 +A=1,04 +B=1,08 +X=1,02 +Y=1,01 +Z=1,80 +ZL=1,40 +L=1,10 +R=1,20 +S=2,01 +Power=2,03 +Left=2,60 +Down=2,40 +Right=2,20 +Up=2,00 +RightUp=2,10 +DownRight=2,30 +DownLeft=2,50 +UpLeft=2,70 +StickX=3,1A,100 +StickY=4,1A,100 +CStickX=5,1A,100 +CStickY=6,1A,100 +LAnalog=0 +RAnalog=0 + +# Generic PSX/PS2 Splitter +# ------------------------ +# This ini file is for one of those cheap (often blue) PSX/PS2 splitters, +# which converts one or two, PSX or PS2 controllers into a single USB port. +# There are lots of them around, with various VID/PID numbers and button layouts, +# so you might want to make your own ini file by using crediar's HIDTest homebrew app. +# +# The interesting thing about this ini file is that it uses a new "MultiIn=4" mode, +# which was developed by Gi, in order to allow you to use Nintendont with multiple +# controllers from splitters like this one, which give their input data as multiple +# packets (one per controller), instead of a single packet. +# +# To get similar splitters to work in Nintendon't, you must: +# +# - Have a splitter that sends 1 packet per controller, in turn, where the +# first byte is the index of the controller (starting from 0x01) and the +# maximum packet size in bytes is 32 (you can use HIDTest to confirm this). +# - Know the VID#, PID# and button details (again you can use HIDTest for this). +# - Create an ini file for your splitter named VID#_PID#.ini with MultiInValue +# set to the number of gamepads the splitter supports and MultiIn set to 4. \ No newline at end of file diff --git a/controllerconfigs/controller_switch_gamecube.ini b/controllerconfigs/controller_switch_gamecube.ini new file mode 100644 index 000000000..7b6801a6a --- /dev/null +++ b/controllerconfigs/controller_switch_gamecube.ini @@ -0,0 +1,29 @@ +[Switch Wired Game Cube] +VID=0E6F +PID=0185 +Polltype=1 +DPAD=1 +DigitalLR=1 +A=0,04 +B=0,02 +X=0,08 +Y=0,01 +Z=0,20 +L=0,40 +R=0,80 +S=1,02 +Left=2,06 +Down=2,04 +Right=2,02 +Up=2,00 +RightUp=2,01 +DownRight=2,03 +DownLeft=2,05 +UpLeft=2,07 +StickX=3 +StickY=4 +CStickX=5 +CStickY=6 +Power=1,20 +LAnalog=1,04 +RAnalog=1,08 diff --git a/controllerconfigs/controllers.zip b/controllerconfigs/controllers.zip index 46ad578b0..aacb32ad6 100644 Binary files a/controllerconfigs/controllers.zip and b/controllerconfigs/controllers.zip differ diff --git a/kernel/HID.c b/kernel/HID.c index 6b793e110..bcab215bf 100644 --- a/kernel/HID.c +++ b/kernel/HID.c @@ -558,6 +558,8 @@ s32 HIDOpen( u32 LoaderRequest ) if( HID_CTRL->Polltype == 0 ) MemPacketSize = 128; + else if (HID_CTRL->MultiIn == 4) + MemPacketSize = 128; else MemPacketSize = wMaxPacketSize; @@ -823,6 +825,8 @@ void HIDCTRLRumble(u32 Enable) void HIDIRQRead() { + u8 controllerNumber; + switch( HID_CTRL->MultiIn ) { default: @@ -837,6 +841,27 @@ void HIDIRQRead() if ((Packet[0] < HID_CTRL->MultiInValue) || (Packet[0] > NIN_CFG_MAXPAD)) goto dohidirqread; break; + case 4: // Multiple controllers from a single adapter, under seperate packets, to be merged into a single HID_Packet. + // The first byte of each packet contains the controller number; the first pad is assumed to have index 1. + // MultiInValue is used to set the number of pads (from 1 to 4). E.g. a basic PS2 splitter would have 2. + // When the packets are merged to the single HID_Packet, they will be aligned on 32 byte boundaries. + // The wMaxPacketSize for each split packet must therefore be 32 bytes or less for this to work. + + controllerNumber = Packet[0]; + + // Unwanted packet => try again + if ((controllerNumber < 1) || (controllerNumber > HID_CTRL->MultiInValue)) + goto dohidirqread; + + // Wanted packet => merge it in on its 32 byte boundary + memcpy(HID_Packet + (32 * (controllerNumber-1)), Packet, wMaxPacketSize); + + // Final packet => sync all the packets + if (controllerNumber == HID_CTRL->MultiInValue) + sync_after_write(HID_Packet, 128); + + goto dohidirqread; + break; } memcpy(HID_Packet, Packet, wMaxPacketSize); sync_after_write(HID_Packet, wMaxPacketSize); @@ -1062,6 +1087,7 @@ void HIDUpdateRegisters(u32 LoaderRequest) } } } - HID_Timer = read32(HW_TIMER); + // crashes wiivc with hid controllers connected + //HID_Timer = read32(HW_TIMER); } } diff --git a/kernel/HID_controllers.h b/kernel/HID_controllers.h index 67b4b57dd..fdc38d332 100644 --- a/kernel/HID_controllers.h +++ b/kernel/HID_controllers.h @@ -118,9 +118,16 @@ u8 RumbleDataOn_0079_0006[14] = { 0x51, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfa u8 RumbleDataOff_0079_0006[14] = { 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 RumbleDataOn_0810_0001[5] = { 0x01, 0x00, 0x00, 0x7f, 0x7f }; u8 RumbleDataOff_0810_0001[5] = { 0x01, 0x00, 0x00, 0x00, 0x00 }; +u8 RumbleDataOn_054C_05C4[6] = { 0x05, 0x01, 0x00, 0x00, 0xff, 0xff }; +u8 RumbleDataOff_054C_05C4[6] = { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }; +u8 RumbleDataOn_054C_09CC[6] = { 0x05, 0x01, 0x00, 0x00, 0xff, 0xff }; +u8 RumbleDataOff_054C_09CC[6] = { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }; + rumble DefRumble[] = { { 0x0079, 0x0006, 1, 14, 2, 7, RumbleDataOn_0079_0006, RumbleDataOff_0079_0006 }, + { 0x054C, 0x05C4, 1, 6, 1, 6, RumbleDataOn_054C_05C4, RumbleDataOff_054C_05C4 }, + { 0x054C, 0x09CC, 1, 6, 1, 6, RumbleDataOn_054C_09CC, RumbleDataOff_054C_09CC }, { 0x0810, 0x0001, 0, 5, 1, 5, RumbleDataOn_0810_0001, RumbleDataOff_0810_0001 }, }; diff --git a/kernel/JVSIO.c b/kernel/JVSIO.c index 8572edffa..72ceca7f1 100644 --- a/kernel/JVSIO.c +++ b/kernel/JVSIO.c @@ -275,14 +275,14 @@ void JVSIOCommand( char *DataIn, char *DataOut ) PlayerData[0] |= 0x80; // Start if( PadBuff[i].triggerRight > 0x44 && inTestMenu ) PlayerData[0] |= 0x40; // Service button - if( PadBuff[i].stickY > 0x30 ) + if( (PadBuff[i].stickY > 0x30) || (PadBuff[i].button & PAD_BUTTON_UP) ) PlayerData[0] |= 0x20; // Move Up - if( PadBuff[i].stickY < -0x30 ) + if( (PadBuff[i].stickY < -0x30) || (PadBuff[i].button & PAD_BUTTON_DOWN) ) PlayerData[0] |= 0x10; // Move Down - if( PadBuff[i].stickX < -0x30 ) - PlayerData[0] |= 0x08; // Move Right - if( PadBuff[i].stickX > 0x30 ) - PlayerData[0] |= 0x04; // Move Left + if( (PadBuff[i].stickX > 0x30) || (PadBuff[i].button & PAD_BUTTON_RIGHT) ) + PlayerData[0] |= 0x04; // Move Right + if( (PadBuff[i].stickX < -0x30) || (PadBuff[i].button & PAD_BUTTON_LEFT) ) + PlayerData[0] |= 0x08; // Move Left if( PadBuff[i].button & PAD_BUTTON_A ) PlayerData[0] |= 0x02; // Long Pass if( PadBuff[i].button & PAD_BUTTON_X ) @@ -315,14 +315,14 @@ void JVSIOCommand( char *DataIn, char *DataOut ) PlayerData[0] |= 0x80; // Start if( PadBuff[i].triggerRight > 0x44 && inTestMenu ) PlayerData[0] |= 0x40; // Service button - if( PadBuff[i].stickY > 0x30 ) + if( (PadBuff[i].stickY > 0x30) || (PadBuff[i].button & PAD_BUTTON_UP) ) PlayerData[0] |= 0x20; // Move Up - if( PadBuff[i].stickY < -0x30 ) + if( (PadBuff[i].stickY < -0x30) || (PadBuff[i].button & PAD_BUTTON_DOWN) ) PlayerData[0] |= 0x10; // Move Down - if( PadBuff[i].stickX < -0x30 ) - PlayerData[0] |= 0x08; // Move Right - if( PadBuff[i].stickX > 0x30 ) - PlayerData[0] |= 0x04; // Move Left + if( (PadBuff[i].stickX > 0x30) || (PadBuff[i].button & PAD_BUTTON_RIGHT) ) + PlayerData[0] |= 0x04; // Move Right + if( (PadBuff[i].stickX < -0x30) || (PadBuff[i].button & PAD_BUTTON_LEFT) ) + PlayerData[0] |= 0x08; // Move Left if( PadBuff[i].button & PAD_BUTTON_A ) PlayerData[0] |= 0x02; // A if( PadBuff[i].button & PAD_BUTTON_B ) @@ -396,11 +396,11 @@ void JVSIOCommand( char *DataIn, char *DataOut ) break; case TRI_VS4: if(i == 0) - val = -PadBuff[0].stickY + 0x7F; // Analog Y + val = -PadBuff[0].stickY + 0x80; // Analog Y else if(i == 1) val = PadBuff[0].stickX + 0x80; // Analog X else if(i == 2) - val = -PadBuff[1].stickY + 0x7F; // Analog Y (P2) + val = -PadBuff[1].stickY + 0x80; // Analog Y (P2) else if(i == 3) val = PadBuff[1].stickX + 0x80; // Analog X (P2) break; diff --git a/kernel/Patch.c b/kernel/Patch.c index 9f779b6b2..e3cb959fe 100644 --- a/kernel/Patch.c +++ b/kernel/Patch.c @@ -107,6 +107,7 @@ extern u32 drcAddress; extern u32 drcAddressAligned; u32 IsN64Emu = 0; u32 isKirby = 0; +u32 isdisneyskt = 0; // SHA-1 hashes of known DSP modules. static const unsigned char DSPHashes[][20] = @@ -1025,13 +1026,18 @@ static bool GameNeedsHook() static inline bool PADSwitchRequired() { return( (TITLE_ID) == 0x47434F || // Call of Duty - (TITLE_ID) == 0x475449 || // Tiger Woods PGA Tour 2003 + (TITLE_ID) == 0x475449 || // Tiger Woods PGA Tour 2003 (TITLE_ID) == 0x475734 ); // Tiger Woods PGA Tour 2004 + } static inline bool PADForceConnected() { - return( (TITLE_ID) == 0x474C5A ); // 007 From Russia With Love + return( (TITLE_ID) == 0x474C5A || // 007 From Russia With Love + (TITLE_ID) == 0x474153 || // sonic dx jap + (TITLE_ID) == 0x475853 || // sonic dx usa and pal + (TITLE_ID) == 0x475735 || // Need For Speed Carbon + (TITLE_ID) == 0x474f57 ); // Nedd For Speed Most Wanted } static inline bool GameRelTimerPatches() @@ -1486,6 +1492,8 @@ void DoPatches( char *Buffer, u32 Length, u32 DiscOffset ) } /* requires lots of additional timer patches for BBA */ isKirby = (TITLE_ID == 0x474B59); + if(TITLE_ID == 0x474458) + isdisneyskt = 0x474458; sync_before_read(Buffer, Length); @@ -4450,9 +4458,13 @@ void PatchGame() DoPatches( (void*)DOLMinOff, FullLength, 0 ); // Some games need special timings EXISetTimings(TITLE_ID, GAME_ID & 0xFF); - // Init Cache if its a new ISO - if(TRIGame != TRI_SB) - ISOSetupCache(); + if(TRIGame != TRI_SB) + { + if((TITLE_ID) != 0x474645) + { + ISOSetupCache(); + } + } // Reset SI status SIInit(); u32 SiInitSet = 0; diff --git a/kernel/PatchTimers.c b/kernel/PatchTimers.c index f5393c9a8..999d08eca 100644 --- a/kernel/PatchTimers.c +++ b/kernel/PatchTimers.c @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "PatchTimers.h" extern u32 isKirby; +extern u32 isdisneyskt; static bool write64A( u32 Offset, u64 Value, u64 CurrentValue ) { @@ -298,11 +299,14 @@ bool PatchTimers(u32 FirstVal, u32 Buffer, bool checkFloats) u32 NextP = CheckFor(Buffer, 0x38009E34); if(NextP > 0) { + if(isdisneyskt != 0x474458) + { W16AH(Buffer + 2, U32_TIMER_CLOCK_MSECS_WII); W16L(NextP + 2, U32_TIMER_CLOCK_MSECS_WII); dbgprintf("PatchTimers:[Timer Clock addi ms] applied (0x%08X)\r\n", Buffer ); return true; - } + } + } } /* RADTimerRead split into subparts */ if( FirstVal == 0x3C000001 ) diff --git a/kernel/TRI.c b/kernel/TRI.c index 8f5ea8f76..ca74d8538 100644 --- a/kernel/TRI.c +++ b/kernel/TRI.c @@ -354,7 +354,10 @@ void TRISetupGames() { dbgprintf("TRI:F-Zero AX (Rev C)\r\n"); TRIGame = TRI_AX; - SystemRegion = REGION_JAPAN; + if(ncfg->Language == NIN_LAN_ENGLISH) + SystemRegion = REGION_EXPORT; + else + SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CD1C0; TRISettingsName = SETTINGS_AX_RVC; TRISettingsLoc = 0x3CF6F0; @@ -387,9 +390,6 @@ void TRISetupGames() //Remove Overscan on first VIConfigure write32( 0x001FB998, 0x38C00000 ); - //English - write32( 0x000DF430, 0x38000000 ); - if(!arcadeMode) { //Remove some menu timers (thanks dj_skual) @@ -437,7 +437,10 @@ void TRISetupGames() { dbgprintf("TRI:F-Zero AX (Rev D)\r\n"); TRIGame = TRI_AX; - SystemRegion = REGION_JAPAN; + if(ncfg->Language == NIN_LAN_ENGLISH) + SystemRegion = REGION_EXPORT; + else + SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CD6A0; TRISettingsName = SETTINGS_AX_RVD; TRISettingsLoc = 0x3CFBD0; @@ -480,9 +483,6 @@ void TRISetupGames() //Remove Overscan on first VIConfigure write32( 0x001FBE54, 0x38C00000 ); - //English - write32( 0x000DF698, 0x38000000 ); - if(!arcadeMode) { //Remove some menu timers (thanks dj_skual) @@ -531,7 +531,10 @@ void TRISetupGames() { dbgprintf("TRI:F-Zero AX (Rev E)\r\n"); TRIGame = TRI_AX; - SystemRegion = REGION_JAPAN; + if(ncfg->Language == NIN_LAN_ENGLISH) + SystemRegion = REGION_EXPORT; + else + SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CDC20; TRISettingsName = SETTINGS_AX_RVE; TRISettingsLoc = 0x3D0150; @@ -570,10 +573,7 @@ void TRISetupGames() //Remove Overscan on first VIConfigure write32( 0x001FC2C4, 0x38C00000 ); - - //English - write32( 0x000DF818, 0x38000000 ); - + if(!arcadeMode) { //Remove some menu timers (thanks dj_skual) diff --git a/kernel/asm/SonicRidersCopy.S b/kernel/asm/SonicRidersCopy.S index 1f4d472c1..ea08d15da 100644 --- a/kernel/asm/SonicRidersCopy.S +++ b/kernel/asm/SonicRidersCopy.S @@ -5,7 +5,7 @@ SonicRidersCopy: #original instruction mr r31, r7 -#7 might be enough too, going safe +#7 works but going safe slwi r5, r5, 8 waitLoop: subi r5, r5, 1 diff --git a/loader/source/global.c b/loader/source/global.c index 6f81c288f..ce528fbb2 100644 --- a/loader/source/global.c +++ b/loader/source/global.c @@ -457,6 +457,21 @@ void UpdateNinCFG() ncfg->NetworkProfile = 0; ncfg->Version = 9; } + if (ncfg->Version == 9) + { + ncfg->WiiUGamepadSlot = 0; + ncfg->Version = 10; + } + if (ncfg->Version == 10) + { + // NIN_CFG with version 10 may have loaded + // garbage bytes into WiiUGamepadSlot so sanitize + // the slot if necessary. + if (ncfg->WiiUGamepadSlot > NIN_CFG_MAXPAD) + { + ncfg->WiiUGamepadSlot = 0; + } + } } int CreateNewFile(const char *Path, unsigned int size) diff --git a/loader/source/main.c b/loader/source/main.c index 437bcd523..e3ba6c08b 100644 --- a/loader/source/main.c +++ b/loader/source/main.c @@ -844,9 +844,10 @@ int main(int argc, char **argv) { // Autobooting. gprintf("Autobooting:\"%s\"\r\n", ncfg->GamePath ); - PrintInfo(); - GRRLIB_Render(); - ClearScreen(); + //this aparently can break some vc autoboot issues + //PrintInfo(); + //GRRLIB_Render(); + //ClearScreen(); } //Init DI and set correct ID if needed @@ -1027,27 +1028,32 @@ int main(int argc, char **argv) //Set Language if(ncfg->Language == NIN_LAN_AUTO || ncfg->Language >= NIN_LAN_LAST) { - switch (CONF_GetLanguage()) + if(BI2region == BI2_REGION_PAL) { - case CONF_LANG_GERMAN: - ncfg->Language = NIN_LAN_GERMAN; - break; - case CONF_LANG_FRENCH: - ncfg->Language = NIN_LAN_FRENCH; - break; - case CONF_LANG_SPANISH: - ncfg->Language = NIN_LAN_SPANISH; - break; - case CONF_LANG_ITALIAN: - ncfg->Language = NIN_LAN_ITALIAN; - break; - case CONF_LANG_DUTCH: - ncfg->Language = NIN_LAN_DUTCH; - break; - default: - ncfg->Language = NIN_LAN_ENGLISH; - break; + switch (CONF_GetLanguage()) + { + case CONF_LANG_GERMAN: + ncfg->Language = NIN_LAN_GERMAN; + break; + case CONF_LANG_FRENCH: + ncfg->Language = NIN_LAN_FRENCH; + break; + case CONF_LANG_SPANISH: + ncfg->Language = NIN_LAN_SPANISH; + break; + case CONF_LANG_ITALIAN: + ncfg->Language = NIN_LAN_ITALIAN; + break; + case CONF_LANG_DUTCH: + ncfg->Language = NIN_LAN_DUTCH; + break; + default: + ncfg->Language = NIN_LAN_ENGLISH; + break; + } } + else + ncfg->Language = NIN_LAN_ENGLISH; } if(ncfg->Config & NIN_CFG_MEMCARDEMU) @@ -1116,6 +1122,19 @@ int main(int argc, char **argv) __SYS_UnlockSram(1); // 1 -> write changes while(!__SYS_SyncSram()); } + + //Check if game is Triforce game + u32 IsTRIGame = 0; + if (ncfg->GameID != 0x47545050) //Damn you Knights Of The Temple! + IsTRIGame = TRISetupGames(ncfg->GamePath, CurDICMD, ISOShift); + + if(IsTRIGame != 0) + { + // Create saves directory. + char BasePath[20]; + snprintf(BasePath, sizeof(BasePath), "%s:/saves", GetRootDevice()); + f_mkdir_char(BasePath); + } #define GCN_IPL_SIZE 2097152 #define TRI_IPL_SIZE 1048576 @@ -1123,11 +1142,6 @@ int main(int argc, char **argv) bool useipl = false; bool useipltri = false; - //Check if game is Triforce game - u32 IsTRIGame = 0; - if (ncfg->GameID != 0x47545050) //Damn you Knights Of The Temple! - IsTRIGame = TRISetupGames(ncfg->GamePath, CurDICMD, ISOShift); - if (!(ncfg->Config & (NIN_CFG_SKIP_IPL))) { if(IsTRIGame == 0) diff --git a/loader/source/menu.c b/loader/source/menu.c index 555791369..9ca452e47 100644 --- a/loader/source/menu.c +++ b/loader/source/menu.c @@ -1147,7 +1147,7 @@ static bool UpdateSettingsMenu(MenuCtx *ctx) // Check for wraparound. if ((ctx->settings.settingPart == 0 && ctx->settings.posX >= NIN_SETTINGS_LAST) || - (ctx->settings.settingPart == 1 && ctx->settings.posX >= 8)) + (ctx->settings.settingPart == 1 && ctx->settings.posX >= 9)) { ctx->settings.posX = 0; ctx->settings.settingPart ^= 1; @@ -1174,7 +1174,7 @@ static bool UpdateSettingsMenu(MenuCtx *ctx) if (ctx->settings.settingPart == 0) { ctx->settings.posX = NIN_SETTINGS_LAST - 1; } else { - ctx->settings.posX = 7; + ctx->settings.posX = 8; } } @@ -1421,6 +1421,16 @@ static bool UpdateSettingsMenu(MenuCtx *ctx) ctx->redraw = true; break; + case 8: + // Wii U Gamepad Slot + ctx->saveSettings = true; + ncfg->WiiUGamepadSlot++; + if (ncfg->WiiUGamepadSlot > NIN_CFG_MAXPAD) { + ncfg->WiiUGamepadSlot = 0; + } + ctx->redraw = true; + break; + default: break; } @@ -1602,6 +1612,17 @@ static bool UpdateSettingsMenu(MenuCtx *ctx) "%-18s:%-4s", "Network Profile", netProfile); ListLoopIndex++; + + // Controller slot for the Wii U gamepad. + if (ncfg->WiiUGamepadSlot < NIN_CFG_MAXPAD) { + PrintFormat(MENU_SIZE, (IsWiiU() ? BLACK : DARK_GRAY), MENU_POS_X+320, SettingY(ListLoopIndex), + "%-18s:%d", "WiiU Gamepad Slot", (ncfg->WiiUGamepadSlot + 1)); + } else { + PrintFormat(MENU_SIZE, (IsWiiU() ? BLACK : DARK_GRAY), MENU_POS_X+320, SettingY(ListLoopIndex), + "%-18s:%-4s", "WiiU Gamepad Slot", "None"); + } + ListLoopIndex++; + // Draw the cursor. u32 cursor_color = BLACK; if (ctx->settings.settingPart == 0) { diff --git a/loader/source/ppc/IOSInterface/source/sock.c b/loader/source/ppc/IOSInterface/source/sock.c index 49400aab9..dc71472ad 100644 --- a/loader/source/ppc/IOSInterface/source/sock.c +++ b/loader/source/ppc/IOSInterface/source/sock.c @@ -18,8 +18,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + #include "sock.h" #include "cache.h" +//#include "string.h" +//#include //#define DEBUG_SOCK 1 @@ -63,11 +66,12 @@ extern void (*OSWakeupThread)(void *queue); //1080 avalanche ntsc-u //static void (*OSReport)(char *in, ...) = (void*)0x80136174; //pso plus ntsc-u -static void (*OSReport)(char *in, ...) = (void*)0x80371DF8; +//static void (*OSReport)(char *in, ...) = (void*)0x80371DF8; //pso 1.0 ntsc-u //static void (*OSReport)(char *in, ...) = (void*)0x8036E6B4; //homeland 1.0 //static void (*OSReport)(char *in, ...) = (void*)0x8004D438; + #endif int getFreeFD() @@ -124,8 +128,9 @@ void SOInit(void) //ready to accept requests IsInited = 1; sync_after_write((void*)SO_HSP_LOC, 0x20); - OSReport("SOInit done\n"); + restoreIRQs(val); + //OSReport("SOInit done\n"); } void doCallStart(int call, int fd, void *queue) @@ -283,7 +288,7 @@ int SOCleanup(void) interface_started = 0; reset_cache_vals(); restoreIRQs(val); - OSReport("SOCleanup done\n"); + //OSReport("SOCleanup done\n"); return 0; } @@ -432,8 +437,8 @@ int SORecvFrom(int snum, char *buf, int len, int flags, char *sock) int ret; int fd = getFreeFD(); //max len - if(len >= (1<= (1<<(SOShift-1))) + len = (1<<(SOShift-1)); u32 curbuf = (SO_DATA_BUF+(fd< 0) - { - u32 outbuf = threadReqDat[type][i].buf; - u32 curbuf = (SO_DATA_BUF+(i<= 0) //copy back return value - { - buf[0] = sock_entry_arm[i].cmd1; - buf[1] = sock_entry_arm[i].cmd2; - } - u16 port = (u16)(buf[0]&0xFFFF); - buf[0] = 4; - ((acpt_cb)cb)(ret, sock, (char*)buf, port); - } - //cb done, disable irqs again - val = disableIRQs(); - //done processing, free up fd - freeUpFD(i); - } - } - //no updates happened, so no interrupts were enabled for - //another update to happen during that time, end check - if(donecheck) - break; + +void test_debug(char *txt, int cnt, int p1, int p2, int p3){ +#if 0 + if (dbgSock == -1){ + dbgSock = SOSocket(2,1,0); + + u32 garbage = 0xFFFF; + while(garbage--) ; + + u32 input[2]; + input[0] = 0x08020000 | 0xc0c; + input[1] = 0xc0a801c7; + SOConnect(dbgSock,(char*)input); + + garbage = 0xFFFF; + while(garbage--) ; } - return val; + int i; + char buf[128]; + for (i=0; i<128; i++) buf[i] = 0; + *(volatile u32*)(buf+0) = cnt; + *(volatile u32*)(buf+4) = p1; + *(volatile u32*)(buf+8) = p2; + *(volatile u32*)(buf+12) = p3; + for (i=0; i<100; i++) if (txt[i] != 0) buf[i+16] = txt[i]; else break; + SOSendTo(dbgSock, buf, 128, 0, 0); +#endif +} + +int test_socket(int type, int sock){ + int i; + for (i = 0; i 0) + if (threadReqDat[type][i].sock == sock) return 0; + return 1; } -static void threadHandle(myCtx *ctx) +static void threadHandleNew(myCtx *ctx) { int val = disableIRQs(); void *queue = ctx->queue; u32 type = ctx->type; while(threadsRunning) { + if(!threadsRunning) break; //no requests for now, so sleep OSSleepThread(queue); //had irq enabled so check if(!threadsRunning) break; //woke up, either request or callback - val = doCbChecks(type, val); - //had irq enabled so check - if(!threadsRunning) break; - //handle new requests - while(threadReq[type]) - { - u32 fd = threadReqFD[type]; - u32 buf = threadReqDat[type][fd].buf; - short len = threadReqDat[type][fd].len; - short sock = threadReqDat[type][fd].sock; - //clear request, so next OSSleepThread can make new one - threadReq[type] = 0; - //set this to busy so doCbChecks knows - threadBusy[type][fd] = 1; - if(type == T_SEND) - { - u32 curbuf = (SO_DATA_BUF+(fd< 0) - { - int i; - for(i = 0; i < len; i++) - *(volatile u8*)(curbuf+i) = *(volatile u8*)(buf+i); - sync_after_write((void*)curbuf, len); + + + int pool; + int active = 1; + //loop until all is done + while (active){ + if(!threadsRunning) break; + active = 0; + //process any pending request to send + for (pool = 0; pool < SO_TOTAL_FDS; pool++){ + if ((threadInUse[type][pool] & 6) == 2){ + active = 1; //still have stuff to do + //this entry is to be processed + u32 fd = pool; + u32 buf = threadReqDat[type][fd].buf; + short len = threadReqDat[type][fd].len; + short sock = threadReqDat[type][fd].sock; + + if(type == T_SEND) + { + u32 curbuf = (SO_DATA_BUF+(fd< 0) + { + int i; + for(i = 0; i < len; i++) + *(volatile u8*)(curbuf+i) = *(volatile u8*)(buf+i); + sync_after_write((void*)curbuf, len); + } + sock_entry_arm[fd].cmd0 = sock; + sock_entry_arm[fd].cmd1 = curbuf; + sock_entry_arm[fd].cmd2 = len; + sock_entry_arm[fd].cmd3 = 0; + sock_entry_arm[fd].cmd4 = 0; + sock_entry_arm[fd].cmd5 = 0; + doCallStart(SO_THREAD_FD|so_sendto, fd, queue); + } + else if(type == T_RECV) + { + u32 curbuf = (SO_DATA_BUF+(fd< 0) + { + u32 outbuf = threadReqDat[type][pool].buf; + u32 curbuf = (SO_DATA_BUF+(pool<= 0) //copy back return value + { + buf[0] = sock_entry_arm[pool].cmd1; + buf[1] = sock_entry_arm[pool].cmd2; + } + u16 port = (u16)(buf[0]&0xFFFF); + buf[0] = 4; + threadInUse[type][pool] = 0; + ((acpt_cb)cb)(ret, sock, (char*)buf, port); + } + //cb done, disable irqs again + val = disableIRQs(); + //done processing, free up fd + + freeUpFD(pool); + } + } + } if(!threadsRunning) break; } } } + + int avetcp_init() { SOInit(); @@ -1046,6 +1090,11 @@ int avetcp_init() //start up io threads threadsRunning = 1; int i; + for (i = 0; i < SO_TOTAL_FDS; i++) { + threadInUse[T_SEND][i] = 0; //clear it for later + threadInUse[T_RECV][i] = 0; + threadInUse[T_ACPT][i] = 0; + } so_queue[SO_THREAD_FD|so_sendto] = 0; threadCtx[T_SEND].queue = &so_queue[SO_THREAD_FD|so_sendto]; so_queue[SO_THREAD_FD|so_recvfrom] = 0; @@ -1055,7 +1104,7 @@ int avetcp_init() for(i = 0; i < T_MAX; i++) { threadCtx[i].type = i; - OSCreateThread(ioThread[i], threadHandle, &threadCtx[i], threadStack[i] + 0x1000, 0x1000, 5, 0); + OSCreateThread(ioThread[i], threadHandleNew, &threadCtx[i], threadStack[i] + 0x1000, 0x1000, 5, 0); OSResumeThread(ioThread[i]); } avetcp_inited = 1; @@ -1173,15 +1222,19 @@ int dns_close(int fd) return 0; } + + int tcp_create() { OSReport("tcp_create\n"); + test_debug("tcp_create",0,0,0,0); return SOSocket(2,1,0); } int tcp_bind(int sock, u32 *arr, u16 port) { OSReport("tcp_bind %i %08x %i\n", sock, arr[1], sock); + test_debug("tcp_bind",2,arr[1],port,0); u32 input[2]; input[0] = 0x08020000 | port; input[1] = arr[1]; @@ -1191,22 +1244,28 @@ int tcp_bind(int sock, u32 *arr, u16 port) int tcp_listen(int sock, u32 unk1, u32 unk2, int list, u32 unk3, u32 unk4) { OSReport("tcp_listen %i %i\n", sock, list); + test_debug("tcp_listen",0,0,0,0); return SOListen(sock, list); } -int tcp_stat(int sock, short *someweirdthing, u32 *unk1free, u32 *sendfree, u32 *unk2free) +int tcp_stat(int sock, short *status, u32 *unk1free, u32 *sendfree, u32 *dataAvaible) { OSReport("tcp_stat %i\n", sock); + test_debug("tcp_stat",0,0,0,0); + //should find real value of the socket //this on init has to be 4 or more to work - if(someweirdthing) *someweirdthing = 4; + if(status) *status = 4; //AT_STAT_ESTABLISHED //always say we have the full buffer to send - if(sendfree) *sendfree = (1< 1024*8) len = 1024*8; OSReport("tcp_receive %i %08x %i %08x\n", sock, cb, len, (u32)buf); + if(cb) { + if (test_socket(T_RECV,sock)==0) return 0; //already something pending if(!lockThread(T_RECV)) return -1; int fd = getFreeFD(); - threadReqFD[T_RECV] = fd; + threadInUse[T_RECV][fd] = 1; threadReqDat[T_RECV][fd].len = len; threadReqDat[T_RECV][fd].buf = (u32)buf; threadReqDat[T_RECV][fd].cb = cb; threadReqDat[T_RECV][fd].sock = sock; - threadReq[T_RECV] = 1; + threadInUse[T_RECV][fd] = 3; OSWakeupThread(&so_queue[SO_THREAD_FD|so_recvfrom]); unlockThread(T_RECV); - return -1; + return 0; } - return SORecvFrom(sock, buf, len, 0, 0); + int ret = SORecvFrom(sock, buf, len, 0, 0); + + test_debug("tcp_receive read",2,sock,ret,0); + return ret; } //just do the same for abort and delete for now, @@ -1304,12 +1376,14 @@ int tcp_receive(int sock, u32 cb, u32 len, char *buf) int tcp_abort(int sock) { OSReport("tcp_abort %i\n", sock); + test_debug("tcp_abort",1,sock,0,0); SOShutdown(sock, 2); return SOClose(sock); } int tcp_delete(int sock) { OSReport("tcp_delete %i\n", sock); + test_debug("tcp_delete",1,sock,0,0); SOShutdown(sock, 2); return SOClose(sock); } @@ -1317,6 +1391,7 @@ int tcp_delete(int sock) int DHCP_request_nb(u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 *ip, u32 *netmask, u32 *bcast, u32 tries) { OSReport("DHCP_request_nb\n"); + test_debug("DHCP_request_nb",0,0,0,0); SOStartup(); *ip = 0; //should be more than enough retries @@ -1344,6 +1419,7 @@ int DHCP_request_nb(u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 *ip, u32 *netmas int DHCP_get_gateway(u32 unk, u32 *addr) { OSReport("DHCP_get_gateway\n"); + test_debug("DHCP_get_gateway",0,0,0,0); *addr = 0; //default interface request int fd = getFreeFD(); @@ -1377,6 +1453,7 @@ int DHCP_get_gateway(u32 unk, u32 *addr) int DHCP_get_dns(u32 unk, char *domain, u32 *addr1, u32 *addr2) { OSReport("DHCP_get_dns\n"); + test_debug("DHCP_get_dns",0,0,0,0); //default interface request int fd = getFreeFD(); u32 curbuf = (SO_DATA_BUF+(fd<WiiUGamepadSlot; u32 HIDPad = (*HID_STATUS == 0) ? HID_PAD_NONE : HID_PAD_NOT_SET; u32 chan; + s16 tempStick; + memInvalidate = (u32)SIInited; asm volatile("dcbi 0,%0; sync" : : "b"(memInvalidate) : "memory"); /* For Wii VC */ - if(calledByGame && *drcAddress) + if(calledByGame && *drcAddress && WiiUGamepadSlot != NIN_CFG_MAXPAD) { - used |= (1<<0); //always use channel 0 + used |= (1< 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + Pad[chan].stickX = (s8)tempStick; + + tempStick = (s8)Pad[chan].stickY; + tempStick -= OffsetY[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + Pad[chan].stickY = (s8)tempStick; + + tempStick = (s8)Pad[chan].substickX; + tempStick -= OffsetCX[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + Pad[chan].substickX = (s8)tempStick; + + tempStick = (s8)Pad[chan].substickY; + tempStick -= OffsetCY[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + Pad[chan].substickY = (s8)tempStick; + if((Pad[chan].button&0x1030) == 0x1030) //reset by pressing start, Z, R { /* reset status 3 */ @@ -312,7 +366,7 @@ u32 PADRead(u32 calledByGame) if (HIDPad == HID_PAD_NOT_SET) HIDPad = MaxPads; - for (chan = HIDPad; (chan < HID_PAD_NONE); (HID_CTRL->MultiIn == 3) ? (++chan) : (chan = HID_PAD_NONE)) // Run once unless MultiIn == 3 + for (chan = HIDPad; (chan < HID_PAD_NONE); (HID_CTRL->MultiIn == 3 || HID_CTRL->MultiIn == 4) ? (++chan) : (chan = HID_PAD_NONE)) // Run once unless MultiIn == 3 { if(HIDMemPrep == 0) // first run { @@ -327,7 +381,7 @@ u32 PADRead(u32 calledByGame) if (HID_CTRL->MultiIn == 2) //multiple controllers connected to a single usb port { used |= (1<<(PrevAdapterChannel1 + chan)) | (1<<(PrevAdapterChannel2 + chan)) | (1<<(PrevAdapterChannel3 + chan))| (1<<(PrevAdapterChannel4 + chan)); //depending on adapter it may only send every 4th time - chan = chan + HID_Packet[0] - 1; // the controller number is in the first byte + chan = chan + HID_Packet[0] - 1; // the controller number is in the first byte if (chan >= NIN_CFG_MAXPAD) //if would be higher than the maxnumber of controllers continue; //toss it and try next usb port PrevAdapterChannel1 = PrevAdapterChannel2; @@ -377,6 +431,20 @@ u32 PADRead(u32 calledByGame) } } + if (HID_CTRL->MultiIn == 4) // multiple controllers, connected to one usb port via a splitter, merged into a single HID_Packet + { + if (chan == HID_CTRL->MultiInValue) break; // MultiInValue defines how many controllers we are expecting + + HID_Packet = (vu8*)(0x930050F0 + (chan * 32)); //skip forward how ever many bytes in each controller + u32 HID_CacheEndBlock = ALIGN32(((u32)HID_Packet) + 32); //calculate upper cache block used + if(HID_CacheEndBlock > HIDMemPrep) //new cache block, prepare memory + { + memInvalidate = HID_CacheEndBlock; + asm volatile("dcbi 0,%0; sync" : : "b"(memInvalidate) : "memory"); + HIDMemPrep = memInvalidate; + } + } + if(calledByGame && HID_CTRL->Power.Mask && //exit if power configured and all power buttons pressed ((HID_Packet[HID_CTRL->Power.Offset] & HID_CTRL->Power.Mask) == HID_CTRL->Power.Mask)) { @@ -391,13 +459,13 @@ u32 PADRead(u32 calledByGame) { if( HID_Packet[HID_CTRL->Left.Offset] & HID_CTRL->Left.Mask ) button |= PAD_BUTTON_LEFT; - + if( HID_Packet[HID_CTRL->Right.Offset] & HID_CTRL->Right.Mask ) button |= PAD_BUTTON_RIGHT; - + if( HID_Packet[HID_CTRL->Down.Offset] & HID_CTRL->Down.Mask ) button |= PAD_BUTTON_DOWN; - + if( HID_Packet[HID_CTRL->Up.Offset] & HID_CTRL->Up.Mask ) button |= PAD_BUTTON_UP; } @@ -405,13 +473,13 @@ u32 PADRead(u32 calledByGame) { if(((HID_Packet[HID_CTRL->Up.Offset] & HID_CTRL->DPADMask) == HID_CTRL->Up.Mask) || ((HID_Packet[HID_CTRL->UpLeft.Offset] & HID_CTRL->DPADMask) == HID_CTRL->UpLeft.Mask) || ((HID_Packet[HID_CTRL->RightUp.Offset] & HID_CTRL->DPADMask) == HID_CTRL->RightUp.Mask)) button |= PAD_BUTTON_UP; - + if(((HID_Packet[HID_CTRL->Right.Offset] & HID_CTRL->DPADMask) == HID_CTRL->Right.Mask) || ((HID_Packet[HID_CTRL->DownRight.Offset] & HID_CTRL->DPADMask) == HID_CTRL->DownRight.Mask) || ((HID_Packet[HID_CTRL->RightUp.Offset] & HID_CTRL->DPADMask) == HID_CTRL->RightUp.Mask)) button |= PAD_BUTTON_RIGHT; - + if(((HID_Packet[HID_CTRL->Down.Offset] & HID_CTRL->DPADMask) == HID_CTRL->Down.Mask) || ((HID_Packet[HID_CTRL->DownRight.Offset] & HID_CTRL->DPADMask) == HID_CTRL->DownRight.Mask) || ((HID_Packet[HID_CTRL->DownLeft.Offset] & HID_CTRL->DPADMask) == HID_CTRL->DownLeft.Mask)) button |= PAD_BUTTON_DOWN; - + if(((HID_Packet[HID_CTRL->Left.Offset] & HID_CTRL->DPADMask) == HID_CTRL->Left.Mask) || ((HID_Packet[HID_CTRL->DownLeft.Offset] & HID_CTRL->DPADMask) == HID_CTRL->DownLeft.Mask) || ((HID_Packet[HID_CTRL->UpLeft.Offset] & HID_CTRL->DPADMask) == HID_CTRL->UpLeft.Mask)) button |= PAD_BUTTON_LEFT; } @@ -475,7 +543,7 @@ u32 PADRead(u32 calledByGame) if (PADBarrelPress[0+chan] == 0) // bongos not pressed last 6 cycles (dont pickup bongo noise as clap) button |= PAD_TRIGGER_R; //force button presss todo: bogo should only be using analog } - + if(HID_Packet[HID_CTRL->S.Offset] & HID_CTRL->S.Mask) button |= PAD_BUTTON_START; Pad[chan].button = button; @@ -503,7 +571,7 @@ u32 PADRead(u32 calledByGame) substickY = 127 - HID_Packet[HID_CTRL->CStickY.Offset]; //raw 00 01...7F 80 ... FE FF (up...center...down) } else - if ((HID_CTRL->VID == 0x0926) && (HID_CTRL->PID == 0x2526)) //Mayflash 3 in 1 Magic Joy Box + if ((HID_CTRL->VID == 0x0926) && (HID_CTRL->PID == 0x2526)) //Mayflash 3 in 1 Magic Joy Box { stickX = HID_Packet[HID_CTRL->StickX.Offset] - 128; //raw 1A 1B...80 81 ... E4 E5 (left...center...right) stickY = 127 - HID_Packet[HID_CTRL->StickY.Offset]; //raw 0E 0F...7E 7F ... E4 E5 (up...center...down) @@ -546,6 +614,45 @@ u32 PADRead(u32 calledByGame) stickY = HID_Packet[HID_CTRL->StickY.Offset] - 128; //raw EE ED EC ... 82 81 80 7F 7E ... 1A 19 18 (up, center, down) substickX = HID_Packet[HID_CTRL->CStickX.Offset] - 128; //raw 22 23 24 ... 7F 80 81 ... D2 D3 D4 (left ... center ... right) substickY = HID_Packet[HID_CTRL->CStickY.Offset] - 128; //raw DB DA D9 ... 81 80 7F ... 2B 2A 29 (up, center, down) + if((Pad[chan].button&0x1c00) == 0x1c00 || ((*PadUsed & (1 << chan)) == 0)) + { + OffsetX[chan] = stickX; + OffsetY[chan] = stickY; + OffsetCX[chan] = substickX; + OffsetCY[chan] = substickY; + } + + tempStick = (s8)stickX; + tempStick -= OffsetX[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + stickX = (s8)tempStick; + + tempStick = (s8)stickY; + tempStick -= OffsetY[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + stickY = (s8)tempStick; + + tempStick = (s8)substickX; + tempStick -= OffsetCX[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + substickX = (s8)tempStick; + + tempStick = (s8)substickY; + tempStick -= OffsetCY[chan]; + if (tempStick > 0x7F) + tempStick = 0x7F; + else if (tempStick < -0x80) + tempStick = -0x80; + substickY = (s8)tempStick; } else //standard sticks { @@ -554,28 +661,28 @@ u32 PADRead(u32 calledByGame) substickX = HID_Packet[HID_CTRL->CStickX.Offset] - 128; substickY = 127 - HID_Packet[HID_CTRL->CStickY.Offset]; } - + s8 tmp_stick = 0; if(stickX > HID_CTRL->StickX.DeadZone && stickX > 0) tmp_stick = (double)(stickX - HID_CTRL->StickX.DeadZone) * HID_CTRL->StickX.Radius / 1000; else if(stickX < -HID_CTRL->StickX.DeadZone && stickX < 0) tmp_stick = (double)(stickX + HID_CTRL->StickX.DeadZone) * HID_CTRL->StickX.Radius / 1000; Pad[chan].stickX = tmp_stick; - + tmp_stick = 0; if(stickY > HID_CTRL->StickY.DeadZone && stickY > 0) tmp_stick = (double)(stickY - HID_CTRL->StickY.DeadZone) * HID_CTRL->StickY.Radius / 1000; else if(stickY < -HID_CTRL->StickY.DeadZone && stickY < 0) tmp_stick = (double)(stickY + HID_CTRL->StickY.DeadZone) * HID_CTRL->StickY.Radius / 1000; Pad[chan].stickY = tmp_stick; - + tmp_stick = 0; if(substickX > HID_CTRL->CStickX.DeadZone && substickX > 0) tmp_stick = (double)(substickX - HID_CTRL->CStickX.DeadZone) * HID_CTRL->CStickX.Radius / 1000; else if(substickX < -HID_CTRL->CStickX.DeadZone && substickX < 0) tmp_stick = (double)(substickX + HID_CTRL->CStickX.DeadZone) * HID_CTRL->CStickX.Radius / 1000; Pad[chan].substickX = tmp_stick; - + tmp_stick = 0; if(substickY > HID_CTRL->CStickY.DeadZone && substickY > 0) tmp_stick = (double)(substickY - HID_CTRL->CStickY.DeadZone) * HID_CTRL->CStickY.Radius / 1000; @@ -610,10 +717,10 @@ u32 PADRead(u32 calledByGame) { /* much to do with analog */ u8 tmp_triggerL = 0; u8 tmp_triggerR = 0; - if (((HID_CTRL->VID == 0x0926) && (HID_CTRL->PID == 0x2526)) //Mayflash 3 in 1 Magic Joy Box - || ((HID_CTRL->VID == 0x2006) && (HID_CTRL->PID == 0x0118))) //Trio Linker Plus + if (((HID_CTRL->VID == 0x0926) && (HID_CTRL->PID == 0x2526)) //Mayflash 3 in 1 Magic Joy Box + || ((HID_CTRL->VID == 0x2006) && (HID_CTRL->PID == 0x0118))) //Trio Linker Plus { - tmp_triggerL = HID_Packet[HID_CTRL->LAnalog] & 0xF0; //high nibble raw 1x 2x ... Dx Ex + tmp_triggerL = HID_Packet[HID_CTRL->LAnalog] & 0xF0; //high nibble raw 1x 2x ... Dx Ex tmp_triggerR = (HID_Packet[HID_CTRL->RAnalog] & 0x0F) * 16 ; //low nibble raw x1 x2 ...xD xE if(Pad[chan].button & PAD_TRIGGER_L) tmp_triggerL = 255; @@ -752,7 +859,7 @@ u32 PADRead(u32 calledByGame) if(BTPad[chan].button & BT_TRIGGER_R) button |= PAD_TRIGGER_Z; } - + // Nunchuck Buttons if((BTPad[chan].used & C_NUN) && !(BTPad[chan].button & WM_BUTTON_TWO)) //nunchuck not being configured { @@ -760,7 +867,7 @@ u32 PADRead(u32 calledByGame) { case 0: // (2) default: - { //Howards general config + { //Howards general config //A=A B=B Z=Z +=X -=Y Dpad=Standard //C not pressed L R tilt tied to L R analog triggers. //C pressed tilt control the cStick @@ -775,7 +882,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0x78; else Pad[chan].substickX = (BTPad[chan].xAccel - 512) * 0xF0 / (674 - 350); - + /* yAccel up=280 C=512 down=720 */ if(BTPad[chan].yAccel < 344) Pad[chan].substickY = -0x78; @@ -796,17 +903,17 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerLeft = (475 - BTPad[chan].xAccel) * 0xF0 / (475 - 340); else Pad[chan].triggerLeft = 0; - + if(BTPad[chan].xAccel > 670) { button |= PAD_TRIGGER_R; Pad[chan].triggerRight = 0xFF; } else if(BTPad[chan].xAccel > 550) - Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); + Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); else Pad[chan].triggerRight = 0; - + if (!(BTPad[chan].used & C_ISWAP)) //not using IR { Pad[chan].substickX = 0; @@ -844,15 +951,15 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0; Pad[chan].substickY = 0; } - + if(BTPad[chan].button & WM_BUTTON_A) button |= PAD_BUTTON_A; if(BTPad[chan].button & WM_BUTTON_B) button |= PAD_BUTTON_B; if(BTPad[chan].button & NUN_BUTTON_C) - button |= PAD_BUTTON_X; + button |= PAD_BUTTON_X; if(BTPad[chan].button & NUN_BUTTON_Z) - button |= PAD_BUTTON_Y; + button |= PAD_BUTTON_Y; if(BTPad[chan].button & WM_BUTTON_MINUS) button |= PAD_TRIGGER_Z; @@ -864,7 +971,7 @@ u32 PADRead(u32 calledByGame) button |= PAD_BUTTON_RIGHT; if(BTPad[chan].button & WM_BUTTON_LEFT) button |= PAD_BUTTON_LEFT; - + //Pad[chan].triggerLeft = BTPad[chan].triggerL; if(BTPad[chan].button & WM_BUTTON_PLUS) { @@ -876,7 +983,7 @@ u32 PADRead(u32 calledByGame) }break; case 2: // (2 & right) { //config asked for by naggers - //A=A + //A=A //C not pressed U=Z D=B R=X L=Y B=R Z=L //C pressed Dpad=Standard B=R1/2 Z=L1/2 tilt controls cStick if((BTPad[chan].button & NUN_BUTTON_Z) && @@ -889,7 +996,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerLeft = 0xFF; } // else if(BTPad[chan].button & WM_BUTTON_MINUS) -// Pad[chan].triggerLeft = 0x7F; +// Pad[chan].triggerLeft = 0x7F; else Pad[chan].triggerLeft = 0; @@ -906,10 +1013,10 @@ u32 PADRead(u32 calledByGame) // Pad[chan].triggerRight = 0x7F; else Pad[chan].triggerRight = 0; - + if(BTPad[chan].button & WM_BUTTON_A) button |= PAD_BUTTON_A; - + if(BTPad[chan].button & NUN_BUTTON_C) { if (!(BTPad[chan].used & C_ISWAP)) //not using IR @@ -922,7 +1029,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0x78; else Pad[chan].substickX = (BTPad[chan].xAccel - 512) * 0xF0 / (674 - 350); - + /* yAccel up=280 C=512 down=720 */ if(BTPad[chan].yAccel < 344) Pad[chan].substickY = -0x78; @@ -948,7 +1055,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0; Pad[chan].substickY = 0; } - + if(BTPad[chan].button & WM_BUTTON_UP) button |= PAD_TRIGGER_Z; if(BTPad[chan].button & WM_BUTTON_DOWN) @@ -975,7 +1082,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0x78; else Pad[chan].substickX = (BTPad[chan].xAccel - 512) * 0xF0 / (674 - 350); - + /* yAccel up=280 C=512 down=720 */ if(BTPad[chan].yAccel < 344) Pad[chan].substickY = -0x78; @@ -997,7 +1104,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerLeft = (485 - BTPad[chan].yAccel) * 0xF0 / (485 - 357); else Pad[chan].triggerLeft = 0; - + //gas pedal if(BTPad[chan].yAccel > 668) { @@ -1005,10 +1112,10 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerRight = 0xFF; } else if(BTPad[chan].yAccel > 540) - Pad[chan].triggerRight = (BTPad[chan].yAccel - 540) * 0xF0 / (668 - 540); + Pad[chan].triggerRight = (BTPad[chan].yAccel - 540) * 0xF0 / (668 - 540); else Pad[chan].triggerRight = 0; - + if (!(BTPad[chan].used & C_ISWAP)) //not using IR { Pad[chan].substickX = 0; @@ -1052,7 +1159,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0x78; else Pad[chan].substickX = (BTPad[chan].xAccel - 512) * 0xF0 / (674 - 350); - + /* yAccel up=280 C=512 down=720 */ if(BTPad[chan].yAccel < 344) Pad[chan].substickY = -0x78; @@ -1073,17 +1180,17 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerLeft = (475 - BTPad[chan].xAccel) * 0xF0 / (475 - 340); else Pad[chan].triggerLeft = 0; - + if(BTPad[chan].xAccel > 670) { button |= PAD_TRIGGER_R; Pad[chan].triggerRight = 0xFF; } else if(BTPad[chan].xAccel > 550) - Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); + Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); else Pad[chan].triggerRight = 0; - + if (!(BTPad[chan].used & C_ISWAP)) //not using IR { Pad[chan].substickX = 0; @@ -1112,11 +1219,11 @@ u32 PADRead(u32 calledByGame) button |= PAD_BUTTON_UP; }break; case 5: // (2 & minus) - { //Troopage config + { //Troopage config //A=A //C not pressed +=X -=B Z=L B=R Dpad=cStick //C pressed +=Y -=Z Z=1/2L B=1/2R Dpad=Standard - if(BTPad[chan].button & NUN_BUTTON_C) + if(BTPad[chan].button & NUN_BUTTON_C) { if(BTPad[chan].button & WM_BUTTON_PLUS) button |= PAD_BUTTON_Y; @@ -1130,8 +1237,8 @@ u32 PADRead(u32 calledByGame) if(BTPad[chan].button & WM_BUTTON_MINUS) button |= PAD_BUTTON_B; } - - if((BTPad[chan].button & NUN_BUTTON_C) + + if((BTPad[chan].button & NUN_BUTTON_C) || (BTPad[chan].used & C_ISWAP)) //using IR { if (!(BTPad[chan].used & C_ISWAP)) //not using IR @@ -1139,7 +1246,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0; Pad[chan].substickY = 0; } - + if(BTPad[chan].button & WM_BUTTON_LEFT) button |= PAD_BUTTON_LEFT; if(BTPad[chan].button & WM_BUTTON_RIGHT) @@ -1158,7 +1265,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].substickX = 0x78; else Pad[chan].substickX = 0; - + if(BTPad[chan].button & WM_BUTTON_DOWN) Pad[chan].substickY = -0x78; else if(BTPad[chan].button & WM_BUTTON_UP) @@ -1189,21 +1296,21 @@ u32 PADRead(u32 calledByGame) if(BTPad[chan].button & WM_BUTTON_A) button |= PAD_BUTTON_A; - }break; + }break; case 6: // (2 & 1) { //FPS using IR as cStick alt based on naggers //A=A B=R Z=L +=R1/2 -=L1/2 //C not pressed U=Z D=B R=X L=Y //C pressed Dpad=Standard, L R tilt tied to L R analog triggers. //IR controls the cStick - + if(BTPad[chan].button & NUN_BUTTON_Z) { button |= PAD_TRIGGER_L; Pad[chan].triggerLeft = 0xFF; } else if(BTPad[chan].button & WM_BUTTON_MINUS) - Pad[chan].triggerLeft = 0x7F; + Pad[chan].triggerLeft = 0x7F; else if(BTPad[chan].button & NUN_BUTTON_C) { // use tilt as AnalogL @@ -1220,7 +1327,7 @@ u32 PADRead(u32 calledByGame) } else Pad[chan].triggerLeft = 0; - + if(BTPad[chan].button & WM_BUTTON_B) { button |= PAD_TRIGGER_R; @@ -1238,13 +1345,13 @@ u32 PADRead(u32 calledByGame) Pad[chan].triggerRight = 0xFF; } else if(BTPad[chan].xAccel > 550) - Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); + Pad[chan].triggerRight = (BTPad[chan].xAccel - 550) * 0xF0 / (670 - 550); else Pad[chan].triggerRight = 0; } else Pad[chan].triggerRight = 0; - + if(BTPad[chan].button & WM_BUTTON_A) button |= PAD_BUTTON_A; @@ -1276,7 +1383,7 @@ u32 PADRead(u32 calledByGame) // }break; } if(BTPad[chan].button & WM_BUTTON_ONE) - button |= PAD_BUTTON_START; + button |= PAD_BUTTON_START; if(BTPad[chan].button & WM_BUTTON_HOME) goto DoExit; } //end nunchuck configs @@ -1307,7 +1414,7 @@ u32 PADRead(u32 calledByGame) } if(BTPad[chan].button & BT_BUTTON_START) button |= PAD_BUTTON_START; - + if(BTPad[chan].button & BT_DPAD_LEFT) button |= PAD_BUTTON_LEFT; if(BTPad[chan].button & BT_DPAD_RIGHT) @@ -1316,11 +1423,11 @@ u32 PADRead(u32 calledByGame) button |= PAD_BUTTON_DOWN; if(BTPad[chan].button & BT_DPAD_UP) button |= PAD_BUTTON_UP; - + if(BTPad[chan].button & BT_BUTTON_HOME) goto DoExit; - } - + } + Pad[chan].button = button; //#define DEBUG_cStick 1 @@ -1329,7 +1436,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].stickX = Pad[chan].substickX; Pad[chan].stickY = Pad[chan].substickY; #endif - + //#define DEBUG_Triggers 1 #ifdef DEBUG_Triggers //mirrors triggers on main Stick so f-Zero GX calibration can be used @@ -1337,7 +1444,7 @@ u32 PADRead(u32 calledByGame) Pad[chan].stickY = Pad[chan].triggerLeft; #endif - //exit by pressing B,Z,R,PAD_BUTTON_DOWN + //exit by pressing B,Z,R,PAD_BUTTON_DOWN if((Pad[chan].button&0x234) == 0x234) { goto DoExit; @@ -1452,22 +1559,22 @@ static void kbDoSpecial(u8 *in, u8 *out) static const unsigned char kb_matrix[256] = { - 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, - 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x61, 0x4C, 0x50, 0x51, 0x59, 0x34, 0x35, 0x37, - 0x38, 0x52, 0x3B, 0x39, 0x3A, 0x4F, 0x3C, 0x3D, 0x3E, 0x53, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x36, 0x0A, 0x00, 0x4D, 0x06, 0x08, 0x4E, 0x07, 0x09, 0x5F, - 0x5C, 0x5D, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0x3D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x5B, 0x36, 0x5A, 0x58, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, + 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x61, 0x4C, 0x50, 0x51, 0x59, 0x34, 0x35, 0x37, + 0x38, 0x52, 0x3B, 0x39, 0x3A, 0x4F, 0x3C, 0x3D, 0x3E, 0x53, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x36, 0x0A, 0x00, 0x4D, 0x06, 0x08, 0x4E, 0x07, 0x09, 0x5F, + 0x5C, 0x5D, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x3D, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x5B, 0x36, 0x5A, 0x58, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } ; static u8 *kb_input = (u8*)0x93026C60;