Hacking New Classic Controller Hacks

  • Thread starter Thread starter Vague Rant
  • Start date Start date
  • Views Views 244,583
  • Replies Replies 687
  • Likes Likes 42
@Vague Rant Hi. Do you have the knowledge for making wii u controllers hacks ?
Some games like planes have multiplayer mode, but the second player must play with wiimote+nunchuk instead of pro controller. Thanks.
 
  • Like
Reactions: awesomeee
Any chance we could get a "Classic Controller = GameCube Controller" hack? I have a bunch of the GameCube styled classic controllers and it would be nice to have them recognized as GameCube controllers in the games that support the GC controller.
 
@Vague Rant
Re: Accelerometer data
Do you have an example PPC assembly for accelerometer stuff? I know i put the 0x20 wiimote unused values in the button assembly, but we need an example for the calc_acc assembly part 👍
I can't really give an example that applies to many games simultaneously (like the button or pointer support) because the read_kpad_acc() function changed a lot over the course of the Wii's lifespan, so my accelerometer hacks are never the same between any two games. Basically you have to locate where the accelerometer data gets loaded into read_kpad_acc() (where this data is pulled from also varies) and insert your own floating point values. Here's an example of a basic single-frame, single-axis swing:
Code:
  lfs f1, 0x???(r3)     ; load in the real accelerometer data

  lwz r4, 0x4(r3)       ; read newly pressed buttons this frame
  andi. r0, r4, 0x80    ; was fake shake 0x80 pressed?
  beq- RETURN           ; if not, don't do anything

; magic
  bl GRAB
MAGIC:
    SHAKE:  .float  3.4     ; maximum value registered by the wiimote accelerometer
GRAB:
  mflr r5

  lfs f1, SHAKE-MAGIC(r5)   ; replace real accelerometer data with 3.4

RETURN:

And here's another example, I'll put this one in a spoiler because it's quite a bit longer due to the specific requirements of the game:
Code:
; read_kpad_acc
; 80330DF8 for USA
; 80330C4C for EUR (Es,It)
  cmpwi r15, 0x1
  bne- RETURN

; magic
  bl GRAB
MAGIC:
  SHAKE:    .float  3.4
  WREST:    .hword  0
  NREST:    .hword  0
  P2SHAKE:  .float  3.4
  P2WREST:  .hword  0
  P2NREST:  .hword  0
GRAB:
  mflr r5

; handle multiple players
  slwi r6, r27, 3
  add r5, r5, r6

  lfs f0, SHAKE-MAGIC(r5)

  lwz r0, 0x4(r3)
  andi. r0, r0, 0xC0
  beq- WIISHAKE
  fabs f0, f0
  li r0, 1
  stw r0, WREST-MAGIC(r5)    ; reset both

WIISHAKE:
  lwz r6, 0x0(r3)
  andi. r0, r6, 0x80
  beq- CHUKSHAKE

  lha r0, WREST-MAGIC(r5)
  xori r0, r0, 1
  sth r0, WREST-MAGIC(r5)

  cmpwi r0, 0x0
  beq- CHUKSHAKE
  fmr f4, f0
  stfs f4, 0x4A4(r3)
  fneg f0, f0

CHUKSHAKE:
  andi. r0, r6, 0x40
  beq- OSCILLATE
  lha r0, NREST-MAGIC(r5)
  xori r0, r0, 1

  sth r0, NREST-MAGIC(r5)

  cmpwi r0, 0x0
  bne- CHUKCESS
  stw r0, 0x68(r3)
  stw r0, 0x6C(r3)
  b OSCILLATE

CHUKCESS:
  stfs f0, 0x68(r3)
  stfs f0, 0x6C(r3)

OSCILLATE:
  stfs f0, SHAKE-MAGIC(r5)

RETURN:
  stfs f4, 0x4A8(r3)
This one handles shaking both the Wiimote and Nunchuk on two axes, oscillating continuous shakes in alternating directions while also ensuring that the Wiimote and Nunchuk are shaking in opposite directions to one another, because that was important for this game (Simpsons). It also handles doing this separately for two players, since the game is multiplayer.

You can sometimes locate where the data gets read from by looking for calc_acc() as I mentioned in a previous post, but older games don't use calc_acc() at all. Also, because different games have different expectations for what swinging, shaking, etc. looks like, they all have different requirements. Some games want a swing or shake to last for multiple frames, some expect the shake to first go in one direction then return again (as the forces would naturally from you moving the Wiimote), etc.

Accelerometer support is 100% the toughest part of any of these hacks. To the extent that many of them have stumped me, the two things I hit up against are the accelerometers (both Wiimote and Nunchuk have eluded me many times) and games not using KPAD at all. Since I don't have a solid handle on it myself and it's just something I have to work on individually each game, I don't really have much in the way of general advice for accelerometer stuff.

@Vague Rant Hi. Do you have the knowledge for making wii u controllers hacks ?
Some games like planes have multiplayer mode, but the second player must play with wiimote+nunchuk instead of pro controller. Thanks.
I don't really know much at all about Wii U game hacking, unfortunately. JGecko U never really worked for me, but apparently there was an attempt a while back at making a more reliable Gecko code tool for Wii U. I haven't heard any news about it in a while ago though, so it may not have ended up happening. It's definitely something I'd be interested to look into if it ever becomes more approachable, because I have a similar problem with games that only support the GamePad, e.g. all the Lego games require player 1 to be on the Wii U GamePad. It would be nice to not have to start a 2-player game then drop player 1 and play as player 2 forever, etc.

Any chance we could get a "Classic Controller = GameCube Controller" hack? I have a bunch of the GameCube styled classic controllers and it would be nice to have them recognized as GameCube controllers in the games that support the GC controller.
Not something I have planned or that I know anything about currently, but I'm in the same situation, so I agree it would be nice. It's a lot more complex translating between one controller library and another, and GameCube pads have their own separate library to Wii Remotes/Nunchuks/Classic Controllers.



SI_Wii_MarioStrikersChargedFootball_image1600w.jpg


The second entry in Next Level Games' Strikers series, many would argue Mario Strikers Charged remains the best in the franchise. Building upon the solid foundations set by the GameCube debut, the titular charging mechanic rewards players who make more dynamic plays by enabling Skillshots. In classic Mario style, characters and fields in the game all have their own uniquely themed characteristics, making every match different. However, unlike the rest of the Mario sports games, the Strikers titles have a unique style that's explosive and sometimes downright violent, something we don't often see in the Mushroom Kingdom.

Highlight for @awesomeee who was interested in this game.

USAEUR (Rev 1)EUR (Rev 2)JPNKOR

  1. Code:
    Classic Controller Support [Vague Rant]
    C2375444 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237579C 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2375858 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AB550 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040C148
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D51C4 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D4F80 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  2. Code:
    Classic Controller Support [Vague Rant]
    C2373998 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C2373CF0 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2373DAC 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23A9AA0 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040A200
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D341C 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D31D8 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  3. Code:
    Classic Controller Support [Vague Rant]
    C2373F24 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237427C 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2374338 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AA030 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040A790
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D39AC 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D3768 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  4. Code:
    Classic Controller Support [Vague Rant]
    C237589C 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C2375BF4 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2375CB0 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AB9B0 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040C5A8
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D5624 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D53E0 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  5. Code:
    Classic Controller Support [Vague Rant]
    C2379FCC 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237A330 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDEC214 00000000
    C237A3EC 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23B3248 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C140001
    40820088 80030000
    70000040 4082007C
    48000015 80418000
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23DE5BC 00000008
    A9660030 7C002850
    2C00FF00 41810008
    60E70008 2C0000FF
    41800008 60E70004
    2C0BFF00 41810008
    60E70001 2C0B00FF
    41800008 60E70002
    B0E60000 00000000
    C23DE414 00000018
    A8E50000 70060800
    41820008 60E78000
    70060001 41820008
    60E70008 70064000
    41820008 60E70004
    70060002 41820008
    60E70001 70068000
    41820008 60E70002
    70060010 41820008
    60E70800 70060040
    41820008 60E70400
    70060008 41820008
    60E74000 70060020
    41820008 60E70080
    70062000 41820008
    60E70040 70060200
    41820008 60E70002
    70060080 41820008
    60E72000 70060004
    41820008 60E70400
    70060400 41820008
    60E70200 70061000
    41820008 60E70200
    B0E50000 00000000

Button Mapping​

Wii Remote/NunchukClassic ControllerFunction
Wiimote HomeHome
Works normally
Open/Close Home Button Menu
Wiimote D-PadD-Pad
R
Right Stick
Menus
Navigation
Gameplay
Deke
Slide Tackle
Wiimote AAMenus
Confirm
Gameplay
Pass
Switch Character
Wiimote BB
ZR
Menus
Cancel
Gameplay
Shoot
Wiimote 1Plus
Minus
Gameplay
Pause
Wiimote 2Not mappedNot used?
Wiimote Plus & MinusNot mappedNot used?
Wiimote PointerLeft StickMenus
Navigation
Gameplay
Defend Goal against Mega-Strike
Wiimote ShakeYGameplay
Big Hit
(rough tackle)
Nunchuk StickLeft StickGameplay
Movement
Nunchuk CXGameplay
Use Item
Nunchuk ZZLGameplay
Chip Ball
Modify Shots and Passes
Nunchuk ShakeLGameplay
Switch Item

General Notes​

  • If you're using this hack in a Wii VC injection on Wii U, you must use the "Force Classic Controller connected" option in your injection software. Thanks to @awesomeee for the report!

  • The control scheme here is adapted from both the GameCube prequel and Switch sequel. Where possible it mostly mimics the Switch version due to the more similar controller layout compared to the GameCube, but both get some decent representation here.

    • The biggest difference compared to the Switch version is that it uses B to Pass and A to Shoot, while this hack has those the opposite way around (like the GameCube and Wii games). This is mainly so that the menu behavior is normal, but it's also perfectly fine. I'm not sure why Nintendo swapped them on Switch anyway.

    • The Switch game doesn't include the feature of being able to toggle between your held items. That was performed with Z on the GameCube version, but here it's on L. That's because the R button was added as an additional way to Deke/Slide Tackle in the Switch release, so I mirrored that here. That function is also available on the Right Stick, as it was in both the GameCube and Switch games.

    • The GameCube and Switch games both have a Dash button (R/ZR), but there's no dashing in Charged, so the extra trigger is just a backup Shoot button. I couldn't think of anything else particularly useful to put there. 🤷

Technical Notes​

Code breakdown:
  • C2: Bypass Nunchuk error and read controllers in "Nunchuk mode" when Classic is connected
  • C2: simulate Wiimote shakes
  • C2: read Classic Controller left stick as Nunchuk stick and simulate Nunchuk shakes
  • C2 in calc_dpd_variable: IR pointer emulation
  • C2 and C2 in __a1_37_data_type() (WOR)/__parse_cl_data() (KOR): right stick d-pad emulation and button injector

WORKOR

  1. Code:
    ; __a1_37_data_type
    ; note: separate d-pad emulation after injector
    
    ; button injector
    ; 803D4F80 for USA
    ; 803D31D8 for EUR (Rev 1)
    ; 803D3768 for EUR (Rev 2)
    ; 803D53E0 for JPN
      lha r3, 0x0(r30)
    
    CLASSIC_HOME:
      andi. r4, r0, 0x800
      beq- CLASSIC_UP
      ori r3, r3, 0x8000    ; home
    
    CLASSIC_UP:
      andi. r4, r0, 0x1
      beq- CLASSIC_DOWN
      ori r3, r3, 0x8       ; up (v) / left (h)
    
    CLASSIC_DOWN:
      andi. r4, r0, 0x4000
      beq- CLASSIC_LEFT
      ori r3, r3, 0x4       ; down (v) / right (h)
    
    CLASSIC_LEFT:
      andi. r4, r0, 0x2
      beq- CLASSIC_RIGHT
      ori r3, r3, 0x1       ; left (v) / down (h)
    
    CLASSIC_RIGHT:
      andi. r4, r0, 0x8000
      beq- CLASSIC_A
      ori r3, r3, 0x2       ; right (v) / up (h)
    
    CLASSIC_A:
      andi. r4, r0, 0x10
      beq- CLASSIC_B
      ori r3, r3, 0x800     ; a
    
    CLASSIC_B:
      andi. r4, r0, 0x40
      beq- CLASSIC_X
      ori r3, r3, 0x400     ; b
    
    CLASSIC_X:
      andi. r4, r0, 0x8
      beq- CLASSIC_Y
      ori r3, r3, 0x4000    ; c
    
    CLASSIC_Y:
      andi. r4, r0, 0x20
      beq- CLASSIC_L
      ori r3, r3, 0x80      ; wiimote shake
    
    CLASSIC_L:
      andi. r4, r0, 0x2000
      beq- CLASSIC_R
      ori r3, r3, 0x40      ; nunchuk shake
    
    CLASSIC_R:
      andi. r4, r0, 0x200
      beq- CLASSIC_ZL
      ori r3, r3, 0x2       ; right (v) / up (h)
    
    CLASSIC_ZL:
      andi. r4, r0, 0x80
      beq- CLASSIC_ZR
      ori r3, r3, 0x2000    ; z
    
    CLASSIC_ZR:
      andi. r4, r0, 0x4
      beq- CLASSIC_PLUS
      ori r3, r3, 0x400     ; b
    
    CLASSIC_PLUS:
      andi. r4, r0, 0x400
      beq- CLASSIC_MINUS
      ori r3, r3, 0x200     ; 1
    
    CLASSIC_MINUS:
      andi. r4, r0, 0x1000
      beq- CLASSIC_DONE
      ori r3, r3, 0x200     ; 1
    
    CLASSIC_DONE:
      sth r3, 0x0(r30)
  2. Code:
    ; __parse_cl_data
    ; note: separate d-pad emulation after injector
    
    ; button injector
    ; 803DE414 for KOR
      lha r7, 0x0(r5)
    
    CLASSIC_HOME:
      andi. r6, r0, 0x800
      beq- CLASSIC_UP
      ori r7, r7, 0x8000    ; home
    
    CLASSIC_UP:
      andi. r6, r0, 0x1
      beq- CLASSIC_DOWN
      ori r7, r7, 0x8       ; up (v) / left (h)
    
    CLASSIC_DOWN:
      andi. r6, r0, 0x4000
      beq- CLASSIC_LEFT
      ori r7, r7, 0x4       ; down (v) / right (h)
    
    CLASSIC_LEFT:
      andi. r6, r0, 0x2
      beq- CLASSIC_RIGHT
      ori r7, r7, 0x1       ; left (v) / down (h)
    
    CLASSIC_RIGHT:
      andi. r6, r0, 0x8000
      beq- CLASSIC_A
      ori r7, r7, 0x2       ; right (v) / up (h)
    
    CLASSIC_A:
      andi. r6, r0, 0x10
      beq- CLASSIC_B
      ori r7, r7, 0x800     ; a
    
    CLASSIC_B:
      andi. r6, r0, 0x40
      beq- CLASSIC_X
      ori r7, r7, 0x400     ; b
    
    CLASSIC_X:
      andi. r6, r0, 0x8
      beq- CLASSIC_Y
      ori r7, r7, 0x4000    ; c
    
    CLASSIC_Y:
      andi. r6, r0, 0x20
      beq- CLASSIC_L
      ori r7, r7, 0x80      ; wiimote shake
    
    CLASSIC_L:
      andi. r6, r0, 0x2000
      beq- CLASSIC_R
      ori r7, r7, 0x40      ; nunchuk shake
    
    CLASSIC_R:
      andi. r6, r0, 0x200
      beq- CLASSIC_ZL
      ori r7, r7, 0x2       ; right (v) / up (h)
    
    CLASSIC_ZL:
      andi. r6, r0, 0x80
      beq- CLASSIC_ZR
      ori r7, r7, 0x2000    ; z
    
    CLASSIC_ZR:
      andi. r6, r0, 0x4
      beq- CLASSIC_PLUS
      ori r7, r7, 0x400     ; b
    
    CLASSIC_PLUS:
      andi. r6, r0, 0x400
      beq- CLASSIC_MINUS
      ori r7, r7, 0x200     ; 1
    
    CLASSIC_MINUS:
      andi. r6, r0, 0x1000
      beq- CLASSIC_DONE
      ori r7, r7, 0x200     ; 1
    
    CLASSIC_DONE:
      sth r7, 0x0(r5)
The dreaded Next Level Games! Again! Doing Spider-Man first ended up being a huge help here, as the games do some things similarly. The major difference between them is that Mario Strikers uses low-level WPAD accelerometer data, meaning this game is a step more difficult again from Spider-Man. The rest was all pretty much adapted from Spider-Man, which was nice. Like with the Nunchuk stick stuff in Spider-Man, my approach to the WPAD accelerometer stuff was very much game-specific, so it's not likely to be portable to other games, possibly barring other NLG titles.

Without looking up release dates, it seems like this game's region ports must have spanned a long time. The EUR versions seem the oldest, SDK-wise, followed by USA/JPN and lastly KOR. This mostly just amounted to finding everything again multiple times, but the much-newer SDK used in the KOR release meant I had to track down a completely separate function to do the button injections. Ubisoft's Rabbids Go Home was useful when doing the KOR version, as it seems to be from about the same period and comes with debug symbols.
 
Last edited by Vague Rant,
I can't really give an example that applies to many games simultaneously (like the button or pointer support) because the read_kpad_acc() function changed a lot over the course of the Wii's lifespan, so my accelerometer hacks are never the same between any two games. Basically you have to locate where the accelerometer data gets loaded into read_kpad_acc() (where this data is pulled from also varies) and insert your own floating point values. Here's an example of a basic single-frame, single-axis swing:
Code:
  lfs f1, 0x???(r3)     ; load in the real accelerometer data

  lwz r4, 0x4(r3)       ; read newly pressed buttons this frame
  andi. r0, r4, 0x80    ; was fake shake 0x80 pressed?
  beq- RETURN           ; if not, don't do anything

; magic
  bl GRAB
MAGIC:
    SHAKE:  .float  3.4     ; maximum value registered by the wiimote accelerometer
GRAB:
  mflr r5

  lfs f1, SHAKE-MAGIC(r5)   ; replace real accelerometer data with 3.4

RETURN:

And here's another example, I'll put this one in a spoiler because it's quite a bit longer due to the specific requirements of the game:
Code:
; read_kpad_acc
; 80330DF8 for USA
; 80330C4C for EUR (Es,It)
  cmpwi r15, 0x1
  bne- RETURN

; magic
  bl GRAB
MAGIC:
  SHAKE:    .float  3.4
  WREST:    .hword  0
  NREST:    .hword  0
  P2SHAKE:  .float  3.4
  P2WREST:  .hword  0
  P2NREST:  .hword  0
GRAB:
  mflr r5

; handle multiple players
  slwi r6, r27, 3
  add r5, r5, r6

  lfs f0, SHAKE-MAGIC(r5)

  lwz r0, 0x4(r3)
  andi. r0, r0, 0xC0
  beq- WIISHAKE
  fabs f0, f0
  li r0, 1
  stw r0, WREST-MAGIC(r5)    ; reset both

WIISHAKE:
  lwz r6, 0x0(r3)
  andi. r0, r6, 0x80
  beq- CHUKSHAKE

  lha r0, WREST-MAGIC(r5)
  xori r0, r0, 1
  sth r0, WREST-MAGIC(r5)

  cmpwi r0, 0x0
  beq- CHUKSHAKE
  fmr f4, f0
  stfs f4, 0x4A4(r3)
  fneg f0, f0

CHUKSHAKE:
  andi. r0, r6, 0x40
  beq- OSCILLATE
  lha r0, NREST-MAGIC(r5)
  xori r0, r0, 1

  sth r0, NREST-MAGIC(r5)

  cmpwi r0, 0x0
  bne- CHUKCESS
  stw r0, 0x68(r3)
  stw r0, 0x6C(r3)
  b OSCILLATE

CHUKCESS:
  stfs f0, 0x68(r3)
  stfs f0, 0x6C(r3)

OSCILLATE:
  stfs f0, SHAKE-MAGIC(r5)

RETURN:
  stfs f4, 0x4A8(r3)
This one handles shaking both the Wiimote and Nunchuk on two axes, oscillating continuous shakes in alternating directions while also ensuring that the Wiimote and Nunchuk are shaking in opposite directions to one another, because that was important for this game (Simpsons). It also handles doing this separately for two players, since the game is multiplayer.

You can sometimes locate where the data gets read from by looking for calc_acc() as I mentioned in a previous post, but older games don't use calc_acc() at all. Also, because different games have different expectations for what swinging, shaking, etc. looks like, they all have different requirements. Some games want a swing or shake to last for multiple frames, some expect the shake to first go in one direction then return again (as the forces would naturally from you moving the Wiimote), etc.

Accelerometer support is 100% the toughest part of any of these hacks. To the extent that many of them have stumped me, the two things I hit up against are the accelerometers (both Wiimote and Nunchuk have eluded me many times) and games not using KPAD at all. Since I don't have a solid handle on it myself and it's just something I have to work on individually each game, I don't really have much in the way of general advice for accelerometer stuff.


I don't really know much at all about Wii U game hacking, unfortunately. JGecko U never really worked for me, but apparently there was an attempt a while back at making a more reliable Gecko code tool for Wii U. I haven't heard any news about it in a while ago though, so it may not have ended up happening. It's definitely something I'd be interested to look into if it ever becomes more approachable, because I have a similar problem with games that only support the GamePad, e.g. all the Lego games require player 1 to be on the Wii U GamePad. It would be nice to not have to start a 2-player game then drop player 1 and play as player 2 forever, etc.


Not something I have planned or that I know anything about currently, but I'm in the same situation, so I agree it would be nice. It's a lot more complex translating between one controller library and another, and GameCube pads have their own separate library to Wii Remotes/Nunchuks/Classic Controllers.



View attachment 476715

The second entry in Next Level Games' Strikers series, many would argue Mario Strikers Charged remains the best in the franchise. Building upon the solid foundations set by the GameCube debut, the titular charging mechanic rewards players who make more dynamic plays by enabling Skillshots. In classic Mario style, characters and fields in the game all have their own uniquely themed characteristics, making every match different. However, unlike the rest of the Mario sports games, the Strikers titles have a unique style that's explosive and sometimes downright violent, something we don't often see in the Mushroom Kingdom.

Highlight for @awesomeee who was interested in this game.

USAEUR (Rev 1)EUR (Rev 2)JPNKOR

  1. Code:
    Classic Controller Support [Vague Rant]
    C2375444 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237579C 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2375858 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AB550 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040C148
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D51C4 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D4F80 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  2. Code:
    Classic Controller Support [Vague Rant]
    C2373998 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C2373CF0 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2373DAC 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23A9AA0 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040A200
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D341C 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D31D8 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  3. Code:
    Classic Controller Support [Vague Rant]
    C2373F24 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237427C 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2374338 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AA030 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040A790
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D39AC 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D3768 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  4. Code:
    Classic Controller Support [Vague Rant]
    C237589C 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C2375BF4 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDDBA14 00000000
    C2375CB0 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23AB9B0 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C0F0001
    40820088 80030000
    70000040 4082007C
    48000015 8040C5A8
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23D5624 00000008
    7C030050 A87E0000
    2C0000FF 41800008
    60630008 2C00FF00
    41810008 60630004
    2C0400FF 41800008
    60630001 2C04FF00
    41810008 60630002
    B07E0000 00000000
    C23D53E0 00000018
    A87E0000 70040800
    41820008 60638000
    70040001 41820008
    60630008 70044000
    41820008 60630004
    70040002 41820008
    60630001 70048000
    41820008 60630002
    70040010 41820008
    60630800 70040040
    41820008 60630400
    70040008 41820008
    60634000 70040020
    41820008 60630080
    70042000 41820008
    60630040 70040200
    41820008 60630002
    70040080 41820008
    60632000 70040004
    41820008 60630400
    70040400 41820008
    60630200 70041000
    41820008 60630200
    B07E0000 00000000
  5. Code:
    Classic Controller Support [Vague Rant]
    C2379FCC 00000003
    83010008 28180002
    40820008 3B000001
    60000000 00000000
    C237A330 0000000C
    81610008 2C0B0002
    40820050 4800000D
    00000000 00000000
    7CA802A6 7CA51A14
    88C50000 98050000
    7C003078 70000080
    4182000C 38C00004
    48000014 88C50004
    2C060000 40810014
    38C6FFFF 98C50004
    380001FF B001007C
    7CDEC214 00000000
    C237A3EC 00000012
    2C0B0002 4182000C
    A80100A4 48000080
    39600005 A80100A4
    7C005BD6 980100A8
    A80100A6 7C005BD6
    980100A9 4800000D
    00000000 00000000
    7D6802A6 A0010078
    7D6B1A14 88EB0000
    980B0000 7C003878
    70000040 4182000C
    38E00009 48000014
    88EB0004 2C070000
    40810020 38E7FFFF
    98EB0004 380001FF
    2C070004 41810010
    7C0000D0 48000008
    38000000 00000000
    C23B3248 0000001D
    90010024 2C040000
    408200DC 8803005C
    2C000002 408200D0
    9803005E 2C140001
    40820088 80030000
    70000040 4082007C
    48000015 80418000
    3FAAAAAB 3D4CCCCD
    3F800000 7CA802A6
    80650000 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650000
    2C030001 7FE3FB78
    C0450004 40820008
    EC4200B2 C0650008
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C025000C
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    C23DE5BC 00000008
    A9660030 7C002850
    2C00FF00 41810008
    60E70008 2C0000FF
    41800008 60E70004
    2C0BFF00 41810008
    60E70001 2C0B00FF
    41800008 60E70002
    B0E60000 00000000
    C23DE414 00000018
    A8E50000 70060800
    41820008 60E78000
    70060001 41820008
    60E70008 70064000
    41820008 60E70004
    70060002 41820008
    60E70001 70068000
    41820008 60E70002
    70060010 41820008
    60E70800 70060040
    41820008 60E70400
    70060008 41820008
    60E74000 70060020
    41820008 60E70080
    70062000 41820008
    60E70040 70060200
    41820008 60E70002
    70060080 41820008
    60E72000 70060004
    41820008 60E70400
    70060400 41820008
    60E70200 70061000
    41820008 60E70200
    B0E50000 00000000

Button Mapping​

Wii Remote/NunchukClassic ControllerFunction
Wiimote HomeHome
Works normally
Open/Close Home Button Menu
Wiimote D-PadD-Pad
R
Right Stick
Menus
Navigation
Gameplay
Deke
Slide Tackle
Wiimote AAMenus
Confirm
Gameplay
Pass
Switch Character
Wiimote BB
ZR
Menus
Cancel
Gameplay
Shoot
Wiimote 1Plus
Minus
Gameplay
Pause
Wiimote 2Not mappedNot used?
Wiimote Plus & MinusNot mappedNot used?
Wiimote PointerLeft StickMenus
Navigation
Gameplay
Defend Goal against Mega-Strike
Wiimote ShakeYGameplay
Big Hit
(rough tackle)
Nunchuk StickLeft StickGameplay
Movement
Nunchuk CXGameplay
Use Item
Nunchuk ZZLGameplay
Chip Ball
Modify Shots and Passes
Nunchuk ShakeLGameplay
Switch Item

General Notes​

  • The control scheme here is adapted from both the GameCube prequel and Switch sequel. Where possible it mostly mimics the Switch version due to the more similar controller layout compared to the GameCube, but both get some decent representation here.

    • The biggest difference compared to the Switch version is that it uses B to Pass and A to Shoot, while this hack has those the opposite way around (like the GameCube and Wii games). This is mainly so that the menu behavior is normal, but it's also perfectly fine. I'm not sure why Nintendo swapped them on Switch anyway.

    • The Switch game doesn't include the feature of being able to toggle between your held items. That was performed with Z on the GameCube version, but here it's on L. That's because the R button was added as an additional way to Deke/Slide Tackle in the Switch release, so I mirrored that here. That function is also available on the Right Stick, as it was in both the GameCube and Switch games.

    • The GameCube and Switch games both have a Dash button (R/ZR), but there's no dashing in Charged, so the extra trigger is just a backup Shoot button. I couldn't think of anything else particularly useful to put there. 🤷

Technical Notes​

Code breakdown:
  • C2: Bypass Nunchuk error and read controllers in "Nunchuk mode" when Classic is connected
  • C2: simulate Wiimote shakes
  • C2: read Classic Controller left stick as Nunchuk stick and simulate Nunchuk shakes
  • C2 in calc_dpd_variable: IR pointer emulation
  • C2 and C2 in __a1_37_data_type() (WOR)/__parse_cl_data() (KOR): right stick d-pad emulation and button injector

WORKOR

  1. Code:
    ; __a1_37_data_type
    ; note: separate d-pad emulation after injector
    
    ; button injector
    ; 803D4F80 for USA
    ; 803D31D8 for EUR (Rev 1)
    ; 803D3768 for EUR (Rev 2)
    ; 803D53E0 for JPN
      lha r3, 0x0(r30)
    
    CLASSIC_HOME:
      andi. r4, r0, 0x800
      beq- CLASSIC_UP
      ori r3, r3, 0x8000    ; home
    
    CLASSIC_UP:
      andi. r4, r0, 0x1
      beq- CLASSIC_DOWN
      ori r3, r3, 0x8       ; up (v) / left (h)
    
    CLASSIC_DOWN:
      andi. r4, r0, 0x4000
      beq- CLASSIC_LEFT
      ori r3, r3, 0x4       ; down (v) / right (h)
    
    CLASSIC_LEFT:
      andi. r4, r0, 0x2
      beq- CLASSIC_RIGHT
      ori r3, r3, 0x1       ; left (v) / down (h)
    
    CLASSIC_RIGHT:
      andi. r4, r0, 0x8000
      beq- CLASSIC_A
      ori r3, r3, 0x2       ; right (v) / up (h)
    
    CLASSIC_A:
      andi. r4, r0, 0x10
      beq- CLASSIC_B
      ori r3, r3, 0x800     ; a
    
    CLASSIC_B:
      andi. r4, r0, 0x40
      beq- CLASSIC_X
      ori r3, r3, 0x400     ; b
    
    CLASSIC_X:
      andi. r4, r0, 0x8
      beq- CLASSIC_Y
      ori r3, r3, 0x4000    ; c
    
    CLASSIC_Y:
      andi. r4, r0, 0x20
      beq- CLASSIC_L
      ori r3, r3, 0x80      ; wiimote shake
    
    CLASSIC_L:
      andi. r4, r0, 0x2000
      beq- CLASSIC_R
      ori r3, r3, 0x40      ; nunchuk shake
    
    CLASSIC_R:
      andi. r4, r0, 0x200
      beq- CLASSIC_ZL
      ori r3, r3, 0x2       ; right (v) / up (h)
    
    CLASSIC_ZL:
      andi. r4, r0, 0x80
      beq- CLASSIC_ZR
      ori r3, r3, 0x2000    ; z
    
    CLASSIC_ZR:
      andi. r4, r0, 0x4
      beq- CLASSIC_PLUS
      ori r3, r3, 0x400     ; b
    
    CLASSIC_PLUS:
      andi. r4, r0, 0x400
      beq- CLASSIC_MINUS
      ori r3, r3, 0x200     ; 1
    
    CLASSIC_MINUS:
      andi. r4, r0, 0x1000
      beq- CLASSIC_DONE
      ori r3, r3, 0x200     ; 1
    
    CLASSIC_DONE:
      sth r3, 0x0(r30)
  2. Code:
    ; __parse_cl_data
    ; note: separate d-pad emulation after injector
    
    ; button injector
    ; 803DE414 for KOR
      lha r7, 0x0(r5)
    
    CLASSIC_HOME:
      andi. r6, r0, 0x800
      beq- CLASSIC_UP
      ori r7, r7, 0x8000    ; home
    
    CLASSIC_UP:
      andi. r6, r0, 0x1
      beq- CLASSIC_DOWN
      ori r7, r7, 0x8       ; up (v) / left (h)
    
    CLASSIC_DOWN:
      andi. r6, r0, 0x4000
      beq- CLASSIC_LEFT
      ori r7, r7, 0x4       ; down (v) / right (h)
    
    CLASSIC_LEFT:
      andi. r6, r0, 0x2
      beq- CLASSIC_RIGHT
      ori r7, r7, 0x1       ; left (v) / down (h)
    
    CLASSIC_RIGHT:
      andi. r6, r0, 0x8000
      beq- CLASSIC_A
      ori r7, r7, 0x2       ; right (v) / up (h)
    
    CLASSIC_A:
      andi. r6, r0, 0x10
      beq- CLASSIC_B
      ori r7, r7, 0x800     ; a
    
    CLASSIC_B:
      andi. r6, r0, 0x40
      beq- CLASSIC_X
      ori r7, r7, 0x400     ; b
    
    CLASSIC_X:
      andi. r6, r0, 0x8
      beq- CLASSIC_Y
      ori r7, r7, 0x4000    ; c
    
    CLASSIC_Y:
      andi. r6, r0, 0x20
      beq- CLASSIC_L
      ori r7, r7, 0x80      ; wiimote shake
    
    CLASSIC_L:
      andi. r6, r0, 0x2000
      beq- CLASSIC_R
      ori r7, r7, 0x40      ; nunchuk shake
    
    CLASSIC_R:
      andi. r6, r0, 0x200
      beq- CLASSIC_ZL
      ori r7, r7, 0x2       ; right (v) / up (h)
    
    CLASSIC_ZL:
      andi. r6, r0, 0x80
      beq- CLASSIC_ZR
      ori r7, r7, 0x2000    ; z
    
    CLASSIC_ZR:
      andi. r6, r0, 0x4
      beq- CLASSIC_PLUS
      ori r7, r7, 0x400     ; b
    
    CLASSIC_PLUS:
      andi. r6, r0, 0x400
      beq- CLASSIC_MINUS
      ori r7, r7, 0x200     ; 1
    
    CLASSIC_MINUS:
      andi. r6, r0, 0x1000
      beq- CLASSIC_DONE
      ori r7, r7, 0x200     ; 1
    
    CLASSIC_DONE:
      sth r7, 0x0(r5)
The dreaded Next Level Games! Again! Doing Spider-Man first ended up being a huge help here, as the games do some things similarly. The major difference between them is that Mario Strikers uses low-level WPAD accelerometer data, meaning this game is a step more difficult again from Spider-Man. The rest was all pretty much adapted from Spider-Man, which was nice. Like with the Nunchuk stick stuff in Spider-Man, my approach to the WPAD accelerometer stuff was very much game-specific, so it's not likely to be portable to other games, possibly barring other NLG titles.

Without looking up release dates, it seems like this game's region ports must have spanned a long time. The EUR versions seem the oldest, SDK-wise, followed by USA/JPN and lastly KOR. This mostly just amounted to finding everything again multiple times, but the much-newer SDK used in the KOR release meant I had to track down a completely separate function to do the button injections. Ubisoft's Rabbids Go Home was useful when doing the KOR version, as it seems to be from about the same period and comes with debug symbols.
For first player gamepad games like lego games, the only way i know is to map a usb hid pad as gamepad with hid2vpad.
You can play wirelessly with cronus adapter (zen or max, i don't remember).
Aroma plugin gamepad2pro seems to do the same thing. I didn't test it yet because i'm still on haxchi cfw lol.
 
Ignore this once again, false report.
Post automatically merged:

Alright, im working on another hack, but an andi. instruction I found has different register values then usual. It is andi. r6, r0, 0x9F1F. Is this normal for some games? Thanks in advance.

Update: this was a game that read buttons inside of read_kpad_button.
 
Last edited by awesomeee,
  • Like
Reactions: NestorM
Ignore this once again, false report.
Post automatically merged:

Alright, im working on another hack, but an andi. instruction I found has different register values then usual. It is andi. r6, r0, 0x9F1F. Is this normal for some games? Thanks in advance.

Update: this was a game that read buttons inside of read_kpad_button.
I've never seen that myself, but it's probably not that unusual. That mask is filtering out 0x2000 and 0x4000 (the Nunchuk buttons) as well as 0x80, 0x40 and 0x20 (three unused Wiimote button values, which are what I use to check for fake inputs that I've created, e.g. Wiimote shakes, etc.), so nothing that would harm things in an unmodified game.



H2x1_Wii_AShadowsTale_enGB_image1600w.jpg


Hudson Soft's Lost in Shadow (USA)/A Shadow's Tale (EUR) is a creative puzzle-platformer about light and shadow. Taking on the role of a shadow severed from the body it belongs to, players must navigate what would traditionally be the background of a platforming landscape, the shadows cast by the world resting in the foreground. With its art direction headed up by Studio Ghibli's Hiromasa Ogura, its gentle aesthetic also saw frequent comparisons to Fumito Ueda's Ico. To be clear, this is not an Ico-tier game by any measure, but it's a fun and creative twist on platforming which asks players to consider light and perspective in a way no other platformers do, and that's cool.

USAEURJPN

  1. Code:
    Classic Controller Support [Vague Rant]
    C2008274 00000002
    28000001 41820008
    28000002 00000000
    C2033150 00000002
    28000001 41820008
    28000002 00000000
    C2033270 00000002
    28000001 41820008
    28000002 00000000
    C2172588 00000026
    90010024 2C040000
    40820124 8803005C
    2C000002 40820118
    2C160001 408200D4
    48000019 00000000
    801AA840 3FAAAAAB
    3D4CCCCD 3F800000
    7CA802A6 C0030074
    FC000210 C0230078
    FC200A10 FC00082A
    C025000C FC000840
    4180000C 388000D2
    48000028 80850000
    2C040000 4181000C
    9883005E 4800007C
    80C30000 70C60400
    40A2FFDC 3884FFFF
    90850000 9803005E
    80650004 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650004
    2C030001 7FE3FB78
    C0450008 40820008
    EC4200B2 C065000C
    C0030020 C0230074
    FC211024 4800002D
    D0030020 C0030024
    C0230078 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C0250010
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    041734D8 7FC3F378
    04174870 39000000
    04174A10 39000000
    C2171444 0000001A
    2C040002 408200C0
    38800001 71000800
    41820008 60E78000
    71000001 41820008
    60E70008 71004000
    41820008 60E70004
    71000002 41820008
    60E70001 71008000
    41820008 60E70002
    71000010 41820008
    60E70800 71000040
    41820008 60E70800
    71000008 41820008
    60E70400 71000020
    41820008 60E72000
    71002000 41820008
    60E70001 71000200
    41820008 60E70002
    71000080 41820008
    60E72000 71000004
    41820008 60E70400
    71000400 41820008
    60E70010 71001000
    41820008 60E71000
    7CC63B78 70C09FFF
    60000000 00000000
  2. Code:
    Classic Controller Support [Vague Rant]
    C20082B4 00000002
    28000001 41820008
    28000002 00000000
    C2033110 00000002
    28000001 41820008
    28000002 00000000
    C2033230 00000002
    28000001 41820008
    28000002 00000000
    C2172758 00000026
    90010024 2C040000
    40820124 8803005C
    2C000002 40820118
    2C160001 408200D4
    48000019 00000000
    801AAA10 3FAAAAAB
    3D4CCCCD 3F800000
    7CA802A6 C0030074
    FC000210 C0230078
    FC200A10 FC00082A
    C025000C FC000840
    4180000C 388000D2
    48000028 80850000
    2C040000 4181000C
    9883005E 4800007C
    80C30000 70C60400
    40A2FFDC 3884FFFF
    90850000 9803005E
    80650004 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650004
    2C030001 7FE3FB78
    C0450008 40820008
    EC4200B2 C065000C
    C0030020 C0230074
    FC211024 4800002D
    D0030020 C0030024
    C0230078 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C0250010
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    041736A8 7FC3F378
    04174A40 39000000
    04174BE0 39000000
    C2171614 0000001A
    2C040002 408200C0
    38800001 71000800
    41820008 60E78000
    71000001 41820008
    60E70008 71004000
    41820008 60E70004
    71000002 41820008
    60E70001 71008000
    41820008 60E70002
    71000010 41820008
    60E70800 71000040
    41820008 60E70800
    71000008 41820008
    60E70400 71000020
    41820008 60E72000
    71002000 41820008
    60E70001 71000200
    41820008 60E70002
    71000080 41820008
    60E72000 71000004
    41820008 60E70400
    71000400 41820008
    60E70010 71001000
    41820008 60E71000
    7CC63B78 70C09FFF
    60000000 00000000
  3. Code:
    Classic Controller Support [Vague Rant]
    C2008274 00000002
    28000001 41820008
    28000002 00000000
    C2033150 00000002
    28000001 41820008
    28000002 00000000
    C2033270 00000002
    28000001 41820008
    28000002 00000000
    C2172C38 00000026
    90010024 2C040000
    40820124 8803005C
    2C000002 40820118
    2C160001 408200D4
    48000019 00000000
    801AAEF0 3FAAAAAB
    3D4CCCCD 3F800000
    7CA802A6 C0030074
    FC000210 C0230078
    FC200A10 FC00082A
    C025000C FC000840
    4180000C 388000D2
    48000028 80850000
    2C040000 4181000C
    9883005E 4800007C
    80C30000 70C60400
    40A2FFDC 3884FFFF
    90850000 9803005E
    80650004 28030001
    40810018 90A1000C
    7C6803A6 4E800021
    80A1000C 90650004
    2C030001 7FE3FB78
    C0450008 40820008
    EC4200B2 C065000C
    C0030020 C0230074
    FC211024 4800002D
    D0030020 C0030024
    C0230078 FC200850
    48000019 D0030024
    80010024 7C0803A6
    38210020 4E800020
    FC0100FA C0250010
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 00000000
    04173B88 7FC3F378
    04174F20 39000000
    041750C0 39000000
    C2171AF4 0000001A
    2C040002 408200C0
    38800001 71000800
    41820008 60E78000
    71000001 41820008
    60E70008 71004000
    41820008 60E70004
    71000002 41820008
    60E70001 71008000
    41820008 60E70002
    71000010 41820008
    60E70800 71000040
    41820008 60E70800
    71000008 41820008
    60E70400 71000020
    41820008 60E72000
    71002000 41820008
    60E70001 71000200
    41820008 60E70002
    71000080 41820008
    60E72000 71000004
    41820008 60E70400
    71000400 41820008
    60E70010 71001000
    41820008 60E71000
    7CC63B78 70C09FFF
    60000000 00000000

Button Mapping​

Wii Remote/NunchukClassic ControllerFunction
Wiimote HomeHome
Works normally
Open/Close Home Button Menu
Wiimote D-PadD-Pad
L/R
(left/right)
Menus
Navigation
Gameplay
Rotate World
Wiimote AA
B
Menus
Confirm
Gameplay
Jump
Wiimote BX
ZR
Menus
Cancel
Gameplay
Interact
Wiimote 1 & 2Not mappedNot used?
Wiimote PlusPlusGameplay
Pause
Wiimote MinusNot mappedNot used?
Wiimote PointerRight StickMenus
Navigation
Gameplay
Aim Spangle
Nunchuk StickLeft StickGameplay
Movement
Nunchuk CNot mappedNot used?
Nunchuk ZY
ZL
Gameplay
Read

General Notes​

  • This was actually one of the very first games I looked at when exploring Classic Controller hacks. At the time, I had no idea how to handle the IR pointer, so I discounted it and moved on. Looking at my list of failed hacks (it's about as long as the success list!) I saw this and realized it deserved another shot.

  • This game makes pretty light use of the IR pointer, so I don't think traditional controls hurt it at all. You're mostly doing fairly conventional platforming (albeit with an unconventional presentation), with occasional interactive obstacles you can point at to change the environment. Doing this with the Right Stick and ZR feels pretty good, so I'm surprised the game has never been ported away from the Wii (unless you count the official Wii U VC release).

  • Shadow is practically a three-button game (A/B/Z), so there's lots of room to double map things here. Each of the three main buttons has two mappings, so you should be able to find something that feels satisfying to you. The menus are only slightly weird (with Cancel on X/ZR) but if you've played a Wii game before you should be used to canceling with the right trigger button.

  • I fixed a potential bug with this hack where the KPAD library might (rarely) return a bunch of random button values. In my testing, I've only encountered this with one game (a hack that didn't end up on that success list) but if you're playing any of the previous hacks and notice the controls ever going nuts, please tell me about it so I can add this fix to that game as well.

    • If you're interested in what I think is going on internally, I'll break it down in the Technical Notes.

Technical Notes​

Code breakdown:
  • C2: still read Nunchuk analog stick when Classic is connected
  • C2 and C2: bypass Nunchuk error
  • C2 in calc_dpd_variable(): IR pointer emulation, on a timer; because some obstacles just have you pointing and pressing B a few times in a row, pressing B also resets the delay before the IR pointer switches off again
  • 04 in read_kpad_ext(): redirect Classic into Nunchuk stick
  • 04 and 04 in KPADRead(): potential bug fix for lag frames, I'll go into more detail below
  • C2 in read_kpad_button(): button injector
Code:
; read_kpad_button
; 80171444 for USA
; 80171614 for EUR
; 80171AF4 for JPN
; r4 holds extType
; r6 holds wiimote bitfield
; r7 holds wiimote+nunchuk bitfield
; r8 holds classic bitfield
  cmpwi r4, 0x2
  bne- RETURN

  li r4, 0x1            ; i'm a nunchuk

    CLASSIC_HOME:
      andi. r0, r8, 0x800
      beq- CLASSIC_UP
      ori r7, r7, 0x8000    ; home

    CLASSIC_UP:
      andi. r0, r8, 0x1
      beq- CLASSIC_DOWN
      ori r7, r7, 0x8       ; up (v) / left (h)

    CLASSIC_DOWN:
      andi. r0, r8, 0x4000
      beq- CLASSIC_LEFT
      ori r7, r7, 0x4       ; down (v) / right (h)

    CLASSIC_LEFT:
      andi. r0, r8, 0x2
      beq- CLASSIC_RIGHT
      ori r7, r7, 0x1       ; left (v) / down (h)

    CLASSIC_RIGHT:
      andi. r0, r8, 0x8000
      beq- CLASSIC_A
      ori r7, r7, 0x2       ; right (v) / up (h)

    CLASSIC_A:
      andi. r0, r8, 0x10
      beq- CLASSIC_B
      ori r7, r7, 0x800     ; a

    CLASSIC_B:
      andi. r0, r8, 0x40
      beq- CLASSIC_X
      ori r7, r7, 0x800     ; a

    CLASSIC_X:
      andi. r0, r8, 0x8
      beq- CLASSIC_Y
      ori r7, r7, 0x400     ; b

    CLASSIC_Y:
      andi. r0, r8, 0x20
      beq- CLASSIC_L
      ori r7, r7, 0x2000    ; z

    CLASSIC_L:
      andi. r0, r8, 0x2000
      beq- CLASSIC_R
      ori r7, r7, 0x1       ; left (v) / down (h)

    CLASSIC_R:
      andi. r0, r8, 0x200
      beq- CLASSIC_ZL
      ori r7, r7, 0x2       ; right (v) / up (h)

    CLASSIC_ZL:
      andi. r0, r8, 0x80
      beq- CLASSIC_ZR
      ori r7, r7, 0x2000    ; z

    CLASSIC_ZR:
      andi. r0, r8, 0x4
      beq- CLASSIC_PLUS
      ori r7, r7, 0x400     ; b

    CLASSIC_PLUS:
      andi. r0, r8, 0x400
      beq- CLASSIC_MINUS
      ori r7, r7, 0x10      ; plus

    CLASSIC_MINUS:
      andi. r0, r8, 0x1000
      beq- CLASSIC_DONE
      ori r7, r7, 0x1000    ; minus

    CLASSIC_DONE:
      or r6, r6, r7

RETURN:
  andi. r0, r6, 0x9FFF

In a previous hack which I didn't release because I wasn't able to figure out all of the required motions, I had a super rare bug where sometimes the buttons would go haywire for a single frame, for no apparent reason. I think I've figured out what was going wrong in that game and I'll be including the above fix in any future hacks (and any I return to with fixes) just in case.

I don't know for certain this is what's going on, but KPADRead() has special handling for some type of input reads where instead of receiving new button values, the library gets back a -1/0xFFFF. In this event, KPADRead() will instead use the previous frame's buttons. The problem with that in these hacks is that the "previous frame's buttons" is the Nunchuk analog stick in these hacks, because we're emulating having a Nunchuk stick, which reads from the same location.

When the library tries to read back the previous frame's buttons, it gets a bunch of garbage data (analog stick movement) and then it feeds that garbage data into the button injector to translate into Wiimote button inputs, hence the buttons going haywire for a single frame. This workaround simply ensures that the CC buttons are blanked out in that situation instead, so nothing gets injected into the Wiimote.

I don't know what exactly causes this situation, whether it's games with poor performance that drop frames, missed packets in the Bluetooth controller connection or anything else. While I don't know why it happens, this fix should at least prevent random unintended inputs from occurring in future. Again, if you've encountered this in any other games, it'd be hugely helpful if you could let me know. It's difficult to test because it occurs so rarely in my experience, so I don't actually have confirmation that this workaround resolves the issue, but I'm almost certain it does.
 
I've never seen that myself, but it's probably not that unusual. That mask is filtering out 0x2000 and 0x4000 (the Nunchuk buttons) as well as 0x80, 0x40 and 0x20 (three unused Wiimote button values, which are what I use to check for fake inputs that I've created, e.g. Wiimote shakes, etc.), so nothing that would harm things in an unmodified game.
Quick reply, the weird instruction was normal. I found the injection andi in read kpad button 👍
 
  • Like
Reactions: Vague Rant
Sounds interesting! Are there enough buttons left for all of the things you can do in Mario Kart Wii? Accelerate, Brake, Slide, Item, Trick, Wheelie ... there's only really four buttons on the Wiimote that are (somewhat) usable in sideways layout, so it'd be pretty crowded. But it might be fun to see if anything could be worked out.



View attachment 460733

Classic Con Hacking Returns! Donkey Kong Country Returns is the revival of the classic SNES trilogy, crafted by Retro Studios (Metroid Prime). The game was critically acclaimed then and now, and remains one of the least controversial sequels on the Wii. There's no Kremlings, some people didn't like that. But the game is stellar in all respects and one of the best Wii games and/or 2D platformers ever created. Can you tell I like this one?

That said, this needs a bit more intro than most, because crediar's original Classic Controller hack for Donkey Kong Country Returns a) already exists and b) kicked off this entire genre of Wii hack. Where the original hack had the Classic Controller simulate a sideways Wii Remote, in revisiting this game, I've instead had the Classic Controller be recognized as a Wii Remote & Nunchuk combo, which provides full analog movement on the Classic Controller. As a small bonus, this feature is optional and can be toggled on/off individually for both players while in-game. Highlight for @NestorM who asked about this game.

USAUSA (Rev 1)EuropeJapan

  1. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438526C 28000009
    C23852E0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C2385FC0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2386050 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387214 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    04387300 28000002
    20387C1C 00000000
    04387C1C 02010201
    04387CE0 88ACFFFC
    04387CF0 88ACFFFD
    E2000001 00000000
    C2387C20 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A4D10 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C68370
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A369C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C7C20
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  2. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438710C 28000009
    C2387180 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C2387E60 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387EF0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C23890B4 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    043891A0 28000002
    20389ABC 00000000
    04389ABC 02010201
    04389B80 88ACFFFC
    04389B90 88ACFFFD
    E2000001 00000000
    C2389AC0 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A6CC0 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C6A320
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A564C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C9AC0
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  3. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438666C 28000009
    C23866E0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C23873C0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387450 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2388614 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    04388700 28000002
    2038901C 00000000
    0438901C 02010201
    043890E0 88ACFFFC
    043890F0 88ACFFFD
    E2000001 00000000
    C2389020 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A6160 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C697C0
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A4AEC 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C9020
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  4. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438B17C 28000009
    C238B1F0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C238BED0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C238BF60 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C238D124 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    0438D210 28000002
    2038DB2C 00000000
    0438DB2C 02010201
    0438DBF0 88ACFFFC
    0438DC00 88ACFFFD
    E2000001 00000000
    C238DB30 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24AAD90 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C6E3F0
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A971C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618CDB30
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000

Button Mapping​

As mentioned in the intro, this is essentially two Classic Controller hacks working in tandem, so there are two button layouts: one when simulating the Wiimote and Nunchuk and another for simulating the solo Wiimote.

The default is the Nunchuk layout, so let's start with that. This layout matches the one used by Donkey Kong Country Returns 3D on the 3DS and Tropical Freeze on Wii U and Switch.

[TABLE=full]
[TR]
[TH]Wii Remote & Nunchuk[/TH]
[TH]Classic Controller[/TH]
[TH]Game Function[/TH]
[/TR]
[TR]
[TD]Wiimote Home[/TD]
[TD]Home
Home Menu works as normal[/TD]
[TD]Open/Close Home Button Menu[/TD]
[/TR]
[TR]
[TD]Wiimote D-Pad[/TD]
[TD]D-Pad[/TD]
[TD]Not used?[/TD]
[/TR]
[TR]
[TD]Wiimote A[/TD]
[TD]A/B[/TD]
[TD]Menus
Confirm
Gameplay
Jump[/TD]
[/TR]
[TR]
[TD]Wiimote B[/TD]
[TD]R/ZR[/TD]
[TD]Menus
Cancel
Gameplay
Grab[/TD]
[/TR]
[TR]
[TD]Wiimote Plus[/TD]
[TD]Plus[/TD]
[TD]Menus
Copy Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Wiimote Minus[/TD]
[TD]Minus[/TD]
[TD]Menus
Delete Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Wiimote 1/2[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Nunchuk Analog Stick[/TD]
[TD]Left Stick[/TD]
[TD]Menus
Navigation
Gameplay
Movement[/TD]
[/TR]
[TR]
[TD]Nunchuk C[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Nunchuk Z[/TD]
[TD]L/ZL[/TD]
[TD]World Map
Zoom Out
Gameplay
Grab[/TD]
[/TR]
[TR]
[TD]Wiimote & Nunchuk Shake[/TD]
[TD]X/Y (either)[/TD]
[TD]Gameplay
Various[/TD]
[/TR]
[TR]
[TD]Insert/Remove Nunchuk[/TD]
[TD]Plus and Minus (together)[/TD]
[TD]Toggle Controller Mode[/TD]
[/TR]
[/TABLE]


Next, let's take a look at the Wiimote layout. I matched the later games in the series as closely as possible here, but since there's no analog movement on the Wii Remote, the Grab buttons are now both Grab and Run, as in the actual, physical Wiimote button layout.

[TABLE=full]
[TR]
[TH]Wii Remote[/TH]
[TH]Classic Controller[/TH]
[TH]Game Function[/TH]
[/TR]
[TR]
[TD]Home[/TD]
[TD]Home
Home Menu works as normal[/TD]
[TD]Open/Close Home Button Menu[/TD]
[/TR]
[TR]
[TD]D-Pad[/TD]
[TD]D-Pad[/TD]
[TD]Menus
Navigation
Gameplay
Movement[/TD]
[/TR]
[TR]
[TD]A[/TD]
[TD]A[/TD]
[TD]World Map
Zoom Out[/TD]
[/TR]
[TR]
[TD]B[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Plus[/TD]
[TD]Plus[/TD]
[TD]Menus
Copy Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Minus[/TD]
[TD]Minus[/TD]
[TD]Menus
Delete Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]1[/TD]
[TD]L/R
ZL/ZR[/TD]
[TD]Menus
Cancel
Gameplay
Grab/Run[/TD]
[/TR]
[TR]
[TD]2[/TD]
[TD]B/A[/TD]
[TD]Menus
Confirm
Gameplay
Jump[/TD]
[/TR]
[TR]
[TD]Shake[/TD]
[TD]X/Y[/TD]
[TD]Gameplay
Various[/TD]
[/TR]
[TR]
[TD]Insert/Remove Nunchuk[/TD]
[TD]Plus and Minus[/TD]
[TD]Toggle Controller Mode[/TD]
[/TR]
[/TABLE]

General Notes​

  • crediar's original hack is amazing and brought this game to many who might otherwise have been turned off by the motion controls. If this updated hack seems useless to you, it probably is. That said, this was an opportunity to expand on crediar's incredible work and make the game even more flexible in its controls. I credit crediar in all of my Classic Controller hacks, since they continue to use parts of the original DKCR hack, but obviously this one owes even more to crediar. A fun note is that the very first line of the code comes unchanged from crediar's original, which was pleasing to me.
  • In North America, two different disc revisions of Donkey Kong Country Returns were pressed, the original (Rev 0) and Rev 1 which included some minor fixes. You will need to know which hack to apply depending on which disc you own. Lazy approach: just try both and see which one works. Slightly less lazy: inspect the disc and look for the revision marking (00 or 01) etched on the inner ring. High effort: back up your disc, load it up in Dolphin, right click it, and look at Properties > Info > Name. It will say either Donkey Kong Country Returns (Disc 1, Revision 0) or (Disc 1, Revision 1). And then you'll know.
  • The Wiimote/Nunchuk toggle feature is relatively pointless, I know. Generally, people want to play with one or the other, not alternate between two different control schemes. Honestly, my main motivation was just that toggling between two different extension controllers with a button combo seemed funny. That said, there is maybe one situation where this is useful. If you've got one actual Classic Controller and one SNES Classic Mini controller and want to play multiplayer, the player with the SNES pad can toggle to Wiimote mode and have D-Pad control, while the Classic Controller retains analog support. Will anybody ever actually do this? Nope. Technically, this satisfies NestorM's request that you be able to play with both the D-Pad and analog stick, you just have to be two different people.

Technical Notes​

Besides the first line of the code mentioned earlier and the standard button injector, this is a complete rewrite of the Classic Controller hack. It's of course still derived from crediar's hack in other ways, as that hack provided something of a roadmap to several of the relevant functions. For example, while my approach ended up being completely different, the original Wiimote shaking hack was hugely informative when tracking down shaking on the Nunchuk. Anyway, let's break down the code.

04
crediar's original patch which prevents shaking from being disabled when a Classic Controller is inserted into the base of the Wiimote.

C2
This is the actual shake hack. In a point of difference from most Wii games, DKCR does not use read_kpad_acc() to read the accelerometers. That was a significant challenge since I've mostly worked with that function to emulate motion controls. Where crediar's original hack injected some fake motion data into the low-level accelerometer data, I took a different approach where I'm coming in at the "other end" (after the motion controls have been evaluated) and enabling the "player shook the controller/s" bits. This amounts to setting and unsetting six bits (presumably six axes?) on alternating frames. In Nunchuk mode, the shakes alternate each frame (Wiimote on frame 0, Nunchuk on frame 1, Wiimote on frame 2) so you're shaking every single frame. On the solo Wiimote, this is just Wiimote, no shake, Wiimote, no shake. I'm storing whether you're currently on the Wiimote or Nunchuk/no shake frame separately for each player.

C2, C2 and C2
The next three codes are all just checking if the user is on a Classic Controller and redirecting Nunchuk analog stick reads to the Classic Controller left stick. The third one is checking for relatively small movements; I don't know what it actually does but my guess is that it's keeping the controller awake (resetting the five minute sleep timer) if the player is touching the analog stick, while leaving some leeway for bad dead zone inputs. Just a guess, though.

04
This patches a check that your extension controller is not >1 (Nunchuk) to >2 (Classic Controller).

20 and C2
The first of these is setting up the default controller mode (Nunchuk style) in some free memory, then patching the game to read the mode from memory instead of using the hardcoded values. Then the C2 is handling multiplayer: adjusting the offset where the values should be read from depending on whether you're player 1 or 2. DKCR aligns all functions to 0x10 (16) bytes, so there's a lot of free space if you add it all up (between 0-12 bytes free between every function). I only needed 4 bytes to save both controllers, so that was fine. There was a one-in-four risk that one of the disc regions would have, by pure coincidence, already been aligned to 0x10 bytes, rendering this approach slightly more complicated, but thankfully none of them were and the hack was able to be reused unchanged.

C2 and C2
Finally getting to some SDK stuff, this is read_kpad_dpd() and read_kpad_button(). The former has nothing interesting going on, but button is doing a lot of heavy lifting this time around. Since we're using it to toggle between Nunchuk and Wiimote modes, we have to call the function which handles extension changes from within the button injector. This is actually the function from the above paragraph. DKCR doesn't have symbols, so the name I came up with for it was ControllerTypeEnumerator(), since it reads the extension and then sets different values for each EXT type (including several invalid ones like Classic Controller). Anyway, when the user toggles controls with Plus and Minus, I'm adjusting the controller values set up in the previous paragraph for the current player, storing r3, r4 and the link register on the stack, then calling the extension toggle function.

Sounds interesting! Are there enough buttons left for all of the things you can do in Mario Kart Wii? Accelerate, Brake, Slide, Item, Trick, Wheelie ... there's only really four buttons on the Wiimote that are (somewhat) usable in sideways layout, so it'd be pretty crowded. But it might be fun to see if anything could be worked out.



View attachment 460733

Classic Con Hacking Returns! Donkey Kong Country Returns is the revival of the classic SNES trilogy, crafted by Retro Studios (Metroid Prime). The game was critically acclaimed then and now, and remains one of the least controversial sequels on the Wii. There's no Kremlings, some people didn't like that. But the game is stellar in all respects and one of the best Wii games and/or 2D platformers ever created. Can you tell I like this one?

That said, this needs a bit more intro than most, because crediar's original Classic Controller hack for Donkey Kong Country Returns a) already exists and b) kicked off this entire genre of Wii hack. Where the original hack had the Classic Controller simulate a sideways Wii Remote, in revisiting this game, I've instead had the Classic Controller be recognized as a Wii Remote & Nunchuk combo, which provides full analog movement on the Classic Controller. As a small bonus, this feature is optional and can be toggled on/off individually for both players while in-game. Highlight for @NestorM who asked about this game.

USAUSA (Rev 1)EuropeJapan

  1. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438526C 28000009
    C23852E0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C2385FC0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2386050 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387214 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    04387300 28000002
    20387C1C 00000000
    04387C1C 02010201
    04387CE0 88ACFFFC
    04387CF0 88ACFFFD
    E2000001 00000000
    C2387C20 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A4D10 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C68370
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A369C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C7C20
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  2. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438710C 28000009
    C2387180 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C2387E60 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387EF0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C23890B4 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    043891A0 28000002
    20389ABC 00000000
    04389ABC 02010201
    04389B80 88ACFFFC
    04389B90 88ACFFFD
    E2000001 00000000
    C2389AC0 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A6CC0 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C6A320
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A564C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C9AC0
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  3. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438666C 28000009
    C23866E0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C23873C0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2387450 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C2388614 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    04388700 28000002
    2038901C 00000000
    0438901C 02010201
    043890E0 88ACFFFC
    043890F0 88ACFFFD
    E2000001 00000000
    C2389020 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24A6160 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C697C0
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A4AEC 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618C9020
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000
  4. Code:
    Classic Controller with Analog Support [Vague Rant, crediar]
    0438B17C 28000009
    C238B1F0 00000009
    4800000D 000001D5
    000001D5 7C8802A6
    5623103A 7C841A14
    80760000 70630080
    4082000C 386001D5
    48000010 80640000
    7C001B78 5463803E
    90640000 90190020
    60000000 00000000
    C238BED0 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C238BF60 00000003
    7C9A0214 88040064
    28000002 40820008
    3884000C 00000000
    C238D124 00000003
    28080001 4182000C
    28080002 38A5000C
    60000000 00000000
    0438D210 28000002
    2038DB2C 00000000
    0438DB2C 02010201
    0438DBF0 88ACFFFC
    0438DC00 88ACFFFD
    E2000001 00000000
    C238DB30 00000002
    5465083C 7D8C2A14
    9421FFF0 00000000
    C24AAD90 00000019
    88A40028 2C050002
    408200B8 9421FFF0
    7C0802A6 9001000C
    90610008 98A3005E
    3CC08051 60C6E3F0
    7CC803A6 4E800021
    2C030001 80610008
    48000005 7CA802A6
    C0450078 40820008
    EC4200B2 C065007C
    C0030020 C023006C
    FC211024 4800002D
    D0030020 C0030024
    C0230070 FC200850
    48000019 D0030024
    8001000C 7C0803A6
    38210010 4E800020
    FC0100FA C0250080
    FC000800 4180000C
    FC000890 48000014
    FC200850 FC000800
    41810008 FC000890
    4E800020 3FAAAAAB
    3C23D70A 3F800000
    9421FFC0 00000000
    C24A971C 00000043
    90030068 9421FFF8
    7C0802A6 9001000C
    90810004 90610000
    3D808038 618CDB30
    5729083C 3929FFFC
    7C0C4A2E 48000005
    7CA802A6 81030060
    48000069 80C30000
    7D083378 91030000
    71060080 7D0840F8
    80C30008 7CC84038
    91030008 81030064
    48000041 80C30004
    7D083378 91030004
    71081010 4182018C
    81030000 71081010
    28081010 4082017C
    68000301 7C0C4B2E
    7D8803A6 7F23CB78
    4E800021 48000164
    38E00000 71060800
    41820008 60E78000
    70060001 41820098
    71060001 41820008
    60E70008 71064000
    41820008 60E70004
    71060002 41820008
    60E70002 71068000
    41820008 60E70001
    71060010 41820008
    60E70800 71060040
    41820008 60E70800
    71060008 41820008
    60E70080 71060020
    41820008 60E70080
    71062000 41820008
    60E72000 71060200
    41820008 60E70400
    71060080 41820008
    60E72000 71060004
    4182009C 60E70400
    48000094 71060001
    41820008 60E70002
    71064000 41820008
    60E70001 71060002
    41820008 60E70008
    71068000 41820008
    60E70004 71060010
    41820008 60E70900
    71060040 41820008
    60E70100 71060008
    41820008 60E70080
    71060020 41820008
    60E70080 71062000
    41820008 60E70200
    71060200 41820008
    60E70200 71060080
    41820008 60E70200
    71060004 41820008
    60E70200 71060400
    41820008 60E70010
    71061000 41820008
    60E71000 7CE83B78
    4E800020 0000012D
    80610000 80810004
    8001000C 7C0803A6
    38210008 00000000

Button Mapping​

As mentioned in the intro, this is essentially two Classic Controller hacks working in tandem, so there are two button layouts: one when simulating the Wiimote and Nunchuk and another for simulating the solo Wiimote.

The default is the Nunchuk layout, so let's start with that. This layout matches the one used by Donkey Kong Country Returns 3D on the 3DS and Tropical Freeze on Wii U and Switch.

[TABLE=full]
[TR]
[TH]Wii Remote & Nunchuk[/TH]
[TH]Classic Controller[/TH]
[TH]Game Function[/TH]
[/TR]
[TR]
[TD]Wiimote Home[/TD]
[TD]Home
Home Menu works as normal[/TD]
[TD]Open/Close Home Button Menu[/TD]
[/TR]
[TR]
[TD]Wiimote D-Pad[/TD]
[TD]D-Pad[/TD]
[TD]Not used?[/TD]
[/TR]
[TR]
[TD]Wiimote A[/TD]
[TD]A/B[/TD]
[TD]Menus
Confirm
Gameplay
Jump[/TD]
[/TR]
[TR]
[TD]Wiimote B[/TD]
[TD]R/ZR[/TD]
[TD]Menus
Cancel
Gameplay
Grab[/TD]
[/TR]
[TR]
[TD]Wiimote Plus[/TD]
[TD]Plus[/TD]
[TD]Menus
Copy Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Wiimote Minus[/TD]
[TD]Minus[/TD]
[TD]Menus
Delete Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Wiimote 1/2[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Nunchuk Analog Stick[/TD]
[TD]Left Stick[/TD]
[TD]Menus
Navigation
Gameplay
Movement[/TD]
[/TR]
[TR]
[TD]Nunchuk C[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Nunchuk Z[/TD]
[TD]L/ZL[/TD]
[TD]World Map
Zoom Out
Gameplay
Grab[/TD]
[/TR]
[TR]
[TD]Wiimote & Nunchuk Shake[/TD]
[TD]X/Y (either)[/TD]
[TD]Gameplay
Various[/TD]
[/TR]
[TR]
[TD]Insert/Remove Nunchuk[/TD]
[TD]Plus and Minus (together)[/TD]
[TD]Toggle Controller Mode[/TD]
[/TR]
[/TABLE]


Next, let's take a look at the Wiimote layout. I matched the later games in the series as closely as possible here, but since there's no analog movement on the Wii Remote, the Grab buttons are now both Grab and Run, as in the actual, physical Wiimote button layout.

[TABLE=full]
[TR]
[TH]Wii Remote[/TH]
[TH]Classic Controller[/TH]
[TH]Game Function[/TH]
[/TR]
[TR]
[TD]Home[/TD]
[TD]Home
Home Menu works as normal[/TD]
[TD]Open/Close Home Button Menu[/TD]
[/TR]
[TR]
[TD]D-Pad[/TD]
[TD]D-Pad[/TD]
[TD]Menus
Navigation
Gameplay
Movement[/TD]
[/TR]
[TR]
[TD]A[/TD]
[TD]A[/TD]
[TD]World Map
Zoom Out[/TD]
[/TR]
[TR]
[TD]B[/TD]
[TD][/TD]

[TD]Not used[/TD]
[/TR]
[TR]
[TD]Plus[/TD]
[TD]Plus[/TD]
[TD]Menus
Copy Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]Minus[/TD]
[TD]Minus[/TD]
[TD]Menus
Delete Save
Gameplay
Pause[/TD]
[/TR]
[TR]
[TD]1[/TD]
[TD]L/R
ZL/ZR[/TD]
[TD]Menus
Cancel
Gameplay
Grab/Run[/TD]
[/TR]
[TR]
[TD]2[/TD]
[TD]B/A[/TD]
[TD]Menus
Confirm
Gameplay
Jump[/TD]
[/TR]
[TR]
[TD]Shake[/TD]
[TD]X/Y[/TD]
[TD]Gameplay
Various[/TD]
[/TR]
[TR]
[TD]Insert/Remove Nunchuk[/TD]
[TD]Plus and Minus[/TD]
[TD]Toggle Controller Mode[/TD]
[/TR]
[/TABLE]

General Notes​

  • crediar's original hack is amazing and brought this game to many who might otherwise have been turned off by the motion controls. If this updated hack seems useless to you, it probably is. That said, this was an opportunity to expand on crediar's incredible work and make the game even more flexible in its controls. I credit crediar in all of my Classic Controller hacks, since they continue to use parts of the original DKCR hack, but obviously this one owes even more to crediar. A fun note is that the very first line of the code comes unchanged from crediar's original, which was pleasing to me.
  • In North America, two different disc revisions of Donkey Kong Country Returns were pressed, the original (Rev 0) and Rev 1 which included some minor fixes. You will need to know which hack to apply depending on which disc you own. Lazy approach: just try both and see which one works. Slightly less lazy: inspect the disc and look for the revision marking (00 or 01) etched on the inner ring. High effort: back up your disc, load it up in Dolphin, right click it, and look at Properties > Info > Name. It will say either Donkey Kong Country Returns (Disc 1, Revision 0) or (Disc 1, Revision 1). And then you'll know.
  • The Wiimote/Nunchuk toggle feature is relatively pointless, I know. Generally, people want to play with one or the other, not alternate between two different control schemes. Honestly, my main motivation was just that toggling between two different extension controllers with a button combo seemed funny. That said, there is maybe one situation where this is useful. If you've got one actual Classic Controller and one SNES Classic Mini controller and want to play multiplayer, the player with the SNES pad can toggle to Wiimote mode and have D-Pad control, while the Classic Controller retains analog support. Will anybody ever actually do this? Nope. Technically, this satisfies NestorM's request that you be able to play with both the D-Pad and analog stick, you just have to be two different people.

Technical Notes​

Besides the first line of the code mentioned earlier and the standard button injector, this is a complete rewrite of the Classic Controller hack. It's of course still derived from crediar's hack in other ways, as that hack provided something of a roadmap to several of the relevant functions. For example, while my approach ended up being completely different, the original Wiimote shaking hack was hugely informative when tracking down shaking on the Nunchuk. Anyway, let's break down the code.

04
crediar's original patch which prevents shaking from being disabled when a Classic Controller is inserted into the base of the Wiimote.

C2
This is the actual shake hack. In a point of difference from most Wii games, DKCR does not use read_kpad_acc() to read the accelerometers. That was a significant challenge since I've mostly worked with that function to emulate motion controls. Where crediar's original hack injected some fake motion data into the low-level accelerometer data, I took a different approach where I'm coming in at the "other end" (after the motion controls have been evaluated) and enabling the "player shook the controller/s" bits. This amounts to setting and unsetting six bits (presumably six axes?) on alternating frames. In Nunchuk mode, the shakes alternate each frame (Wiimote on frame 0, Nunchuk on frame 1, Wiimote on frame 2) so you're shaking every single frame. On the solo Wiimote, this is just Wiimote, no shake, Wiimote, no shake. I'm storing whether you're currently on the Wiimote or Nunchuk/no shake frame separately for each player.

C2, C2 and C2
The next three codes are all just checking if the user is on a Classic Controller and redirecting Nunchuk analog stick reads to the Classic Controller left stick. The third one is checking for relatively small movements; I don't know what it actually does but my guess is that it's keeping the controller awake (resetting the five minute sleep timer) if the player is touching the analog stick, while leaving some leeway for bad dead zone inputs. Just a guess, though.

04
This patches a check that your extension controller is not >1 (Nunchuk) to >2 (Classic Controller).

20 and C2
The first of these is setting up the default controller mode (Nunchuk style) in some free memory, then patching the game to read the mode from memory instead of using the hardcoded values. Then the C2 is handling multiplayer: adjusting the offset where the values should be read from depending on whether you're player 1 or 2. DKCR aligns all functions to 0x10 (16) bytes, so there's a lot of free space if you add it all up (between 0-12 bytes free between every function). I only needed 4 bytes to save both controllers, so that was fine. There was a one-in-four risk that one of the disc regions would have, by pure coincidence, already been aligned to 0x10 bytes, rendering this approach slightly more complicated, but thankfully none of them were and the hack was able to be reused unchanged.

C2 and C2
Finally getting to some SDK stuff, this is read_kpad_dpd() and read_kpad_button(). The former has nothing interesting going on, but button is doing a lot of heavy lifting this time around. Since we're using it to toggle between Nunchuk and Wiimote modes, we have to call the function which handles extension changes from within the button injector. This is actually the function from the above paragraph. DKCR doesn't have symbols, so the name I came up with for it was ControllerTypeEnumerator(), since it reads the extension and then sets different values for each EXT type (including several invalid ones like Classic Controller). Anyway, when the user toggles controls with Plus and Minus, I'm adjusting the controller values set up in the previous paragraph for the current player, storing r3, r4 and the link register on the stack, then calling the extension toggle function.
You are doing a great work, yesterday i was daydreaming about a system level wii remote emulation with the classic controller, but i guess its something difficult. You are doing the second best thing, thank you.

I would also like to ask you if there is a way to remap the buttons, it would be better to set Grap on the Y and Jump on B even if confirm on menus become B, and the use ZR to do the shaking?
 
Does anyone want any game's controls remapped? I know how to remap now.
Post automatically merged:

You are doing a great work, yesterday i was daydreaming about a system level wii remote emulation with the classic controller, but i guess its something difficult. You are doing the second best thing, thank you.

I would also like to ask you if there is a way to remap the buttons, it would be better to set Grap on the Y and Jump on B even if confirm on menus become B, and the use ZR to do the shaking?
I would usually help, but sadly that game doesnt have any technical notes to do so. Even then the game has a complex + and - control swap which would further complicate it, apologies.
 
  • Like
Reactions: one-piece
You are doing a great work, yesterday i was daydreaming about a system level wii remote emulation with the classic controller, but i guess its something difficult. You are doing the second best thing, thank you.

I would also like to ask you if there is a way to remap the buttons, it would be better to set Grap on the Y and Jump on B even if confirm on menus become B, and the use ZR to do the shaking?
For Donkey Kong Country Returns, Confirm/Jump already is on B, so it sounds like you just want Y and ZR swapped? In that case uh, sec ... you want to Ctrl+F in the code and edit these lines:

Nunchuk layout:
Code:
41820008 60E70080

41820008 60E70400
The first one is the Y button shake (0080) and the second one is the ZR button grab (0400). Swap those values to have them trigger the opposite function.

Wiimote layout:
Code:
60E70080 71062000

60E70200 71060400
Same again here (but on the left side this time), you want to swap 0080 with 0200 to swap shake and grab.

I would usually help, but sadly that game doesnt have any technical notes to do so. Even then the game has a complex + and - control swap which would further complicate it, apologies.
Yeah, Donkey Kong Country Returns was before I wrote my own button injector and other functions, so it's not entirely my code to share (being co-credited to crediar who did the original hack) so I wouldn't really be comfortable posting it. It's still possible to manually edit the code like above but not as user-friendly.



GogoIndy.jpg


As the fourth(-ish) game in the TT Games series, Lego Indiana Jones: The Original Adventures was the first to branch out from the Star Wars branding, so at this point it's more of a Lego Harrison Ford series than anything else. Adapting the original trilogy of films from the '80s (Raiders of the Lost Ark, Temple of Doom and The Last Crusade), the game was released as a loose tie-in to the 2008 revival movie, Kingdom of the Crystal Skull, though it does not cover the events of that film. Besides the change in setting, gameplay continues in the same vein as previous entries, with the usual light platforming, puzzle-solving and combat. This one is generally regarded as the superior of the two Lego Indiana Jones games.

General Lego highlight for @NestorM. :D

USA/EUR

  1. Code:
    Classic Controller Support [Vague Rant]
    C2209730 00000003
    28030002 40820008
    38600001 28030001
    60000000 00000000
    C2021640 0000001F
    90010024 2C040000
    408200E8 8803005C
    2C000002 408200DC
    9803005E 2C0F0001
    40820094 48000015
    80065210 3FAAAAAB
    3D4CCCCD 3F800000
    7CA802A6 80030004
    70008000 41820010
    38000000 90030020
    90030024 80650000
    28030001 40810018
    90A1000C 7C6803A6
    4E800021 80A1000C
    90650000 2C030001
    7FE3FB78 C0450004
    40820008 EC4200B2
    C0650008 C0030020
    C0230060 FC211024
    4800002D D0030020
    C0030024 C0230064
    FC200850 48000019
    D0030024 80010024
    7C0803A6 38210020
    4E800020 FC0100FA
    C025000C FC000800
    4180000C FC000890
    48000014 FC200850
    FC000800 41810008
    FC000890 4E800020
    60000000 00000000
    040224F8 7FC3F378
    04022BE4 39200000
    C2022BE8 0000001A
    2C040002 408200BC
    38800001 71200800
    41820008 61088000
    71200001 41820008
    61080008 71204000
    41820008 61080004
    71200002 41820008
    61080001 71208000
    41820008 61080002
    71200010 41820008
    61082000 71200040
    41820008 61080800
    71200008 41820008
    61084000 71200020
    41820008 61080400
    71202000 41820008
    61080200 71200200
    41820008 61080100
    71200080 41820008
    61082000 71200004
    41820008 61080400
    71200400 41820008
    61080010 71201000
    41820008 61081000
    7CE74378 70E09FFF
    60000000 00000000

Button Mapping​

Wii Remote/NunchukClassic ControllerFunction
Wiimote HomeHome
Remember that B is your A button
Open/Close Home Menu
Wiimote D-PadD-PadMenus
Navigation
Gameplay
Movement
Wiimote ABMenus
Confirm
Gameplay
Jump
Wiimote BY
ZR
Menus
Cancel
Gameplay
Attack
Wiimote 1LGameplay
Switch Character
(Free Play)
Wiimote 2RGameplay
Switch Character
(Free Play)
Wiimote PlusPlusGameplay
Pause
Wiimote MinusMinusNot used?
Wiimote PointerLeft StickHome Button Menu
Navigation
Nunchuk StickLeft StickMenus
Navigation
Gameplay
Movement
Nunchuk CXGameplay
Switch Character
(Story)
Nunchuk ZA
ZL
Gameplay
Interact
(Build, Pull Levers, etc.)

General Notes​

  • It won't shock you to discover that the control handling in this game is extremely similar to Lego Star Wars: The Complete Saga. I believe they get slightly more complicated after this point as they added IR aiming to the series, so we'll see how that goes.

  • Once again, the control scheme here is essentially that of Lego games on traditional gamepads. Due to the button layout of the Wiimote & Nunchuk, this does lead to some menu weirdness (B to Confirm, Y/ZR to Cancel), but gameplay feels like a Lego game on any other platform. Button injector source in the Technical Notes if you need to change anything.

Technical Notes​

Code breakdown:
  • C2: support reading Nunchuk Stick from Classic Left Stick
  • C2 in calc_dpd_variable(): IR pointer emulation
  • 04 in read_kpad_stick(): Classic to Nunchuk stick redirection
  • 04 and C2 in KPADRead(): lag frame button fix and button injector
Code:
; button injector
; 80022BE8 for USA/EUR
; r4 holds extType
; r7 holds wiimote bitfield
; r8 holds wiimote+nunchuk bitfield
; r9 holds classic bitfield

CLASSIC:
  cmpwi r4, 0x2
  bne- RETURN

  li r4, 0x1            ; i'm a nunchuk

    CLASSIC_HOME:
      andi. r0, r9, 0x800
      beq- CLASSIC_UP
      ori r8, r8, 0x8000    ; home

    CLASSIC_UP:
      andi. r0, r9, 0x1
      beq- CLASSIC_DOWN
      ori r8, r8, 0x8       ; up (v) / left (h)

    CLASSIC_DOWN:
      andi. r0, r9, 0x4000
      beq- CLASSIC_LEFT
      ori r8, r8, 0x4       ; down (v) / right (h)

    CLASSIC_LEFT:
      andi. r0, r9, 0x2
      beq- CLASSIC_RIGHT
      ori r8, r8, 0x1       ; left (v) / down (h)

    CLASSIC_RIGHT:
      andi. r0, r9, 0x8000
      beq- CLASSIC_A
      ori r8, r8, 0x2       ; right (v) / up (h)

    CLASSIC_A:
      andi. r0, r9, 0x10
      beq- CLASSIC_B
      ori r8, r8, 0x2000    ; z

    CLASSIC_B:
      andi. r0, r9, 0x40
      beq- CLASSIC_X
      ori r8, r8, 0x800     ; a

    CLASSIC_X:
      andi. r0, r9, 0x8
      beq- CLASSIC_Y
      ori r8, r8, 0x4000    ; c

    CLASSIC_Y:
      andi. r0, r9, 0x20
      beq- CLASSIC_L
      ori r8, r8, 0x400     ; b

    CLASSIC_L:
      andi. r0, r9, 0x2000
      beq- CLASSIC_R
      ori r8, r8, 0x200     ; 1

    CLASSIC_R:
      andi. r0, r9, 0x200
      beq- CLASSIC_ZL
      ori r8, r8, 0x100     ; 2

    CLASSIC_ZL:
      andi. r0, r9, 0x80
      beq- CLASSIC_ZR
      ori r8, r8, 0x2000    ; z

    CLASSIC_ZR:
      andi. r0, r9, 0x4
      beq- CLASSIC_PLUS
      ori r8, r8, 0x400     ; b

    CLASSIC_PLUS:
      andi. r0, r9, 0x400
      beq- CLASSIC_MINUS
      ori r8, r8, 0x10      ; plus

    CLASSIC_MINUS:
      andi. r0, r9, 0x1000
      beq- RETURN
      ori r8, r8, 0x1000    ; minus

RETURN:
  or r7, r7, r8
  andi. r0, r7, 0x9FFF
 
Tested
Spiderman FoF
A shadows tale
Indiana Jones
Mario Strikers

The four works with gamepad, thanks as always, master.

One question, in RE4 you made a cheat that skips the nunchuck message, can you do that for both RE archives?
 
Merry christmas all! Im glad we were able to get these amazing hacks, @Vague Rant Thank you for all of your amazing work and documentation. You should 100% take a break now that i think about it, spend time with family etc. Anyways im still open to helping people remap any games controls. @tech_A_nina Do you still want the jett rocket controls remapped? If so, what WAD version are you using?

Early Happy new years aswell :) New hack will come out soon hopefully (one of my hacks)

Re: This whole project. @Vague Rant Before this awesome project finishes, i reccomend you make a seperate Wii thread with a LOT of documentation on these hacks. From how to make it, accelerometer examples, WPADProbe method documentation, maybe even a video.

Thanks, and have a good christmas break all! (Or whatever you celebrate lol)
 
Do you still want the jett rocket controls remapped? If so, what WAD version are you using?
I am playing Little Kings Story right now, so no need to hack Jett Rocket again any time soon, but thank you. You deserve a big break as well. After all it's Christmas. Everybody enjoy Christmas with your loved ones
 
Tested
Spiderman FoF
A shadows tale
Indiana Jones
Mario Strikers

The four works with gamepad, thanks as always, master.

One question, in RE4 you made a cheat that skips the nunchuck message, can you do that for both RE archives?
Thanks for the tests, great info to have. Do those two have the same issue with the Nunchuk message unnecessarily halting the game? I'll have a look at whether I can do the same for them. 👍



thecardigans.png


Well, it's almost Christmas, so let's all think back to the festive flop that was 2012's Rise of the Guardians from Dreamworks, and its video game adaptation from Torus Games. As a team of mythical holiday characters (Santa Claus, the Easter Bunny, the Tooth Fairy, etc.), players must defeat the villainous Pitch Black, the source of all nightmares. Gameplay is modeled after Gauntlet and similar top-down dungeon crawlers, amounting to an RPG-influenced four-player co-op hack-and-slash through environments connected to each character's respective seasonal tales.

USAEUR

  1. Code:
    Classic Controller Support [Vague Rant]
    C218E944 00000004
    80010008 7C600026
    2C000002 40820008
    38000001 7C6FF120
    60000000 00000000
    C218F980 00000004
    8BDF0084 2C1E0002
    4182000C 8BDF0087
    48000008 3BC00004
    60000000 00000000
    C20D4D40 00000019
    88DE005C 2C060002
    408200B4 2C160001
    408200AC 48000015
    BF800000 4059999A
    00000000 FFFFFFFF
    7CA802A6 7CE5CA14
    C0250000 D03E006C
    88C7000C 7CC60774
    2C060000 41800054
    809E0000 38000800
    7C840378 909E0000
    809E0008 7C840078
    909E0008 2C060008
    38C6FFFF 4082004C
    C0250004 88870008
    98C70008 70800080
    41820008 D03E05C0
    70800040 4182002C
    D03E006C 48000024
    809E0004 708000C0
    4182001C 98070008
    38C00011 2C0000C0
    40820008 38C60008
    98C7000C 80C3000C
    60000000 00000000
    C20D58E8 0000001F
    90010024 2C040000
    408200E8 8803005C
    2C000002 408200DC
    9803005E 2C160001
    40820094 48000015
    800B63A0 3FAAAAAB
    3DCCCCCD 3F800000
    7CA802A6 80030004
    70008000 41820010
    38000000 90030020
    90030024 80650000
    28030001 40810018
    90A1000C 7C6803A6
    4E800021 80A1000C
    90650000 2C030001
    7FE3FB78 C0450004
    40820008 EC4200B2
    C0650008 C0030020
    C0230060 FC211024
    4800002D D0030020
    C0030024 C0230064
    FC200850 48000019
    D0030024 80010024
    7C0803A6 38210020
    4E800020 FC0100FA
    C025000C FC000800
    4180000C FC000890
    48000014 FC200850
    FC000800 41810008
    FC000890 4E800020
    60000000 00000000
    040D6830 7FC3F378
    040D7C40 39000000
    040D7DE0 39000000
    C20D47A4 0000001A
    2C040002 408200C0
    38800001 71000800
    41820008 60E78000
    71000001 41820008
    60E70008 71004000
    41820008 60E70004
    71000002 41820008
    60E70001 71008000
    41820008 60E70002
    71000010 41820008
    60E70840 71000040
    41820008 60E70800
    71000008 41820008
    60E708C0 71000020
    41820008 60E70880
    71002000 41820008
    60E72000 71000200
    41820008 60E70010
    71000080 41820008
    60E74000 71000004
    41820008 60E70400
    71000400 41820008
    60E70100 71001000
    41820008 60E70200
    7CC63B78 70C09FFF
    60000000 00000000
  2. Code:
    Classic Controller Support [Vague Rant]
    C218EE54 00000004
    80010008 7C600026
    2C000002 40820008
    38000001 7C6FF120
    60000000 00000000
    C218FE90 00000004
    8BDF0084 2C1E0002
    4182000C 8BDF0087
    48000008 3BC00004
    60000000 00000000
    C20D5200 00000019
    88DE005C 2C060002
    408200B4 2C160001
    408200AC 48000015
    BF800000 4059999A
    00000000 FFFFFFFF
    7CA802A6 7CE5CA14
    C0250000 D03E006C
    88C7000C 7CC60774
    2C060000 41800054
    809E0000 38000800
    7C840378 909E0000
    809E0008 7C840078
    909E0008 2C060008
    38C6FFFF 4082004C
    C0250004 88870008
    98C70008 70800080
    41820008 D03E05C0
    70800040 4182002C
    D03E006C 48000024
    809E0004 708000C0
    4182001C 98070008
    38C00011 2C0000C0
    40820008 38C60008
    98C7000C 80C3000C
    60000000 00000000
    C20D5DA8 0000001F
    90010024 2C040000
    408200E8 8803005C
    2C000002 408200DC
    9803005E 2C160001
    40820094 48000015
    800B6860 3FAAAAAB
    3DCCCCCD 3F800000
    7CA802A6 80030004
    70008000 41820010
    38000000 90030020
    90030024 80650000
    28030001 40810018
    90A1000C 7C6803A6
    4E800021 80A1000C
    90650000 2C030001
    7FE3FB78 C0450004
    40820008 EC4200B2
    C0650008 C0030020
    C0230060 FC211024
    4800002D D0030020
    C0030024 C0230064
    FC200850 48000019
    D0030024 80010024
    7C0803A6 38210020
    4E800020 FC0100FA
    C025000C FC000800
    4180000C FC000890
    48000014 FC200850
    FC000800 41810008
    FC000890 4E800020
    60000000 00000000
    040D6CF0 7FC3F378
    040D82A0 39000000
    040D8100 39000000
    C20D4C64 0000001A
    2C040002 408200C0
    38800001 71000800
    41820008 60E78000
    71000001 41820008
    60E70008 71004000
    41820008 60E70004
    71000002 41820008
    60E70001 71008000
    41820008 60E70002
    71000010 41820008
    60E70840 71000040
    41820008 60E70800
    71000008 41820008
    60E708C0 71000020
    41820008 60E70880
    71002000 41820008
    60E72000 71000200
    41820008 60E70010
    71000080 41820008
    60E74000 71000004
    41820008 60E70400
    71000400 41820008
    60E70100 71001000
    41820008 60E70200
    7CC63B78 70C09FFF
    60000000 00000000

Button Mapping​

Wii Remote/NunchukClassic ControllerFunction
Wiimote HomeHome
Technically, B is your A button, but see General Notes
Open/Close Home Menu
Wiimote D-PadD-PadMenus
Navigation
Gameplay
Switch Characters
Wiimote ABMenus
Confirm
Gameplay
Attack
Wiimote BZRMenus
Cancel
Gameplay
Block
Wiimote 1MinusGameplay
View Map
Wiimote 2PlusGameplay
Pause
Wiimote PlusRGameplay
Dreamsand (Revive)
Co-Op Drop-In
Wiimote MinusNot mapped
(use R instead)
Gameplay
Dreamsand (Revive)
Wiimote PointerLeft StickHome Button Menu
Navigation
Wiimote A + Wiimote ShakeYGameplay
Special Attack 1
Nunchuk StickLeft StickGameplay
Movement
Nunchuk CZLGameplay
Dodge
Nunchuk ZLGameplay
Team Attack
Wiimote A + Nunchuk ShakeAGameplay
Special Attack 2
Wiimote A + Wiimote & Nunchuk ShakeXGameplay
Special Attack 3

General Notes​

  • Look, all right, this game is not great. Is there a better Christmas game on Wii? Probably, I dunno. This one has solid production values but there's barely a game here, all gameplay amounts to "Kill all the stuff in this area, then go to the next area." To the extent that there's variety in the gameplay, it's that the reason why you're killing all the stuff changes. "Kill all the stuff to secure this fast travel waypoint. Kill all the stuff to rescue this NPC. Kill all the stuff just because, we didn't make a reason this time."

    • I'm being kind of harsh. In defense of the game, I will say that it's very competently made by a studio with a solid reputation for making pretty all right licensed games. There's some interesting mechanics here like building your characters out with skill points and gems to suit your style of play. It's just that none of it matters because all you really need to do is stand around pressing the attack button until everything dies. If you or somebody you know is into the movie, you'll have a decent time with this game. The presentation is nice, it's not buggy or anything, there's just not much going on.

  • If you're here because you're playing these games as Wii VC injections on Wii U, you're doing it wrong, because this game launched simultaneously on the Wii U. You can just play the actual Wii U version in HD if that's what you're after. You're being weird.

  • Speaking of the Wii U version, that's where the control scheme here comes from. This does lead to a bit of weirdness (the Dodge move is on Nunchuk C originally, but the left trigger (ZL button) on all the traditional versions, stuff like that. Since I'm mirroring the other versions, your Nunchuk C/Z are basically inverted from what you'd expect them to be based on the original Nunchuk controls, with Nunchuk C on Classic ZL and Nunchuk Z on Classic L. The on-screen button prompts will be confusing until you remember this.

  • If you read the Button Mapping table closely, you'll know that all of the motion-based attacks simultaneously have you pressing A to perform them. Rather than requiring you to actually do this, pressing any of the "motion buttons" (Y/A/X) also handles "holding the A button down" for you. While B is the "real" A button, the one you should be using to attack in gameplay, you can get away with using any of A/X/Y as Confirm in the menus since they all press A for you. The menus won't care that you're theoretically waving your controllers around simultaneously.

Technical Notes​

Code breakdown:
  • C2: bypass Nunchuk error
  • C2: read "Nunchuk Stick" when Classic is connected
  • C2: simulate Wiimote, Nunchuk and double shakes--this game is quite particular about what it expects you to do, so pressing one of the three shake buttons actually simulates holding down the A button for 10 frames, then swinging the Wiimote/Nunchuk/both, continuing to hold the A button for another 8 frames, then releasing. When doing your ultimate (triple super) move, that's extended by another 8 frames before the shake is triggered.
  • C2 in calc_dpd_variable(): IR pointer emulation
  • 04 in read_kpad_ext(): redirect Classic Left Stick into Nunchuk Stick
  • 04 and 04 in KPADRead(): potential lag frame bug fix
  • C2 in read_kpad_button(): button injector
Code:
; read_kpad_button
; 800D47A4 for USA
; 800D4C64 for EUR
; r4 holds extType
; r6 holds wiimote bitfield
; r7 holds wiimote+nunchuk bitfield
; r8 holds classic bitfield
  cmpwi r4, 0x2
  bne- RETURN

  li r4, 0x1            ; i'm a nunchuk

    CLASSIC_HOME:
      andi. r0, r8, 0x800
      beq- CLASSIC_UP
      ori r7, r7, 0x8000    ; home

    CLASSIC_UP:
      andi. r0, r8, 0x1
      beq- CLASSIC_DOWN
      ori r7, r7, 0x8       ; up (v) / left (h)

    CLASSIC_DOWN:
      andi. r0, r8, 0x4000
      beq- CLASSIC_LEFT
      ori r7, r7, 0x4       ; down (v) / right (h)

    CLASSIC_LEFT:
      andi. r0, r8, 0x2
      beq- CLASSIC_RIGHT
      ori r7, r7, 0x1       ; left (v) / down (h)

    CLASSIC_RIGHT:
      andi. r0, r8, 0x8000
      beq- CLASSIC_A
      ori r7, r7, 0x2       ; right (v) / up (h)

    CLASSIC_A:
      andi. r0, r8, 0x10
      beq- CLASSIC_B
      ori r7, r7, 0x840     ; nunchuk shake

    CLASSIC_B:
      andi. r0, r8, 0x40
      beq- CLASSIC_X
      ori r7, r7, 0x800     ; a

    CLASSIC_X:
      andi. r0, r8, 0x8
      beq- CLASSIC_Y
      ori r7, r7, 0x8C0     ; both shake

    CLASSIC_Y:
      andi. r0, r8, 0x20
      beq- CLASSIC_L
      ori r7, r7, 0x880     ; wiimote shake

    CLASSIC_L:
      andi. r0, r8, 0x2000
      beq- CLASSIC_R
      ori r7, r7, 0x2000    ; z

    CLASSIC_R:
      andi. r0, r8, 0x200
      beq- CLASSIC_ZL
      ori r7, r7, 0x10      ; plus

    CLASSIC_ZL:
      andi. r0, r8, 0x80
      beq- CLASSIC_ZR
      ori r7, r7, 0x4000    ; c

    CLASSIC_ZR:
      andi. r0, r8, 0x4
      beq- CLASSIC_PLUS
      ori r7, r7, 0x400     ; b

    CLASSIC_PLUS:
      andi. r0, r8, 0x400
      beq- CLASSIC_MINUS
      ori r7, r7, 0x100     ; 2

    CLASSIC_MINUS:
      andi. r0, r8, 0x1000
      beq- CLASSIC_DONE
      ori r7, r7, 0x200     ; 1

    CLASSIC_DONE:
      or r6, r6, r7

RETURN:
  andi. r0, r6, 0x9FFF
 
Last edited by Vague Rant,
Im totally fine with that 👍

Btw im going to scrap that one sonic game, would be VERY hard to do, like super hard. The game is already very tedious lol
I actually couldnt resist, so i tried it but sadly it handles KPAD differently, and the read_kpad functions are way different, different locations then usual. Very interesting. (Please dont work on this, its still an awfully tedious game)

Although, if you do decide to check out the symbol map, you will see why 👍
Post automatically merged:

Update, i think the game uses Low-level WPAD controller report data. Sorry for anyone hoping this game got a classic controller hack, its extremely weird. Vague, this game has a LOT of symbols identifed, you should look into the symbol map if you are interested (but dont make a hack lol)

Heres some examples:
1735104931709.png

1735104951289.png

1735104972903.png


On a seperate note, merry christmas all!
Post automatically merged:
 
Last edited by awesomeee,
@Vague Rant Hi. Game resquest : Ougon No Kizuna/Golden bonds, a jap exclusive Wii game, translated in english by Brand Newman. This game looks very cool but isn't classic controller compatible. Thanks.
 
I am playing Little Kings Story right now, so no need to hack Jett Rocket again any time soon, but thank you. You deserve a big break as well. After all it's Christmas. Everybody enjoy Christmas with your loved ones
I actually tried, no luck. Sorry about that. Ill look at it again hopefully.
Post automatically merged:

For first player gamepad games like lego games, the only way i know is to map a usb hid pad as gamepad with hid2vpad.
You can play wirelessly with cronus adapter (zen or max, i don't remember).
Aroma plugin gamepad2pro seems to do the same thing. I didn't test it yet because i'm still on haxchi cfw lol.
I looked at cemu’s debugging UI, but it is pretty confusing. There are a LOT of symbols though, WPADRead, etc (yes, wpad lol

Very interesting though
 
Last edited by awesomeee,
  • Like
Reactions: NestorM

Site & Scene News

Popular threads in this forum