fttlov 24 Nov, 2024 @ 10:45am
Wiimote as Mouse and Joystick Glovepie Script (WiiJoy)
Hello. I'd like to introduce a Glovepie Script for WiiMote.
Based on script by "lednerg" fixed for Windows 10/11 with properly working function from me - full working auto-centering axis, extra buttons and hotkeys features.
Examples of use:
- Wiimote (MotionPlus) as mouse
- Real Gamepad emulation: use nunchuck as left stick, Wiimote as right stick (ppjoy* virtual axis) with auto-centering like a real gamepad stick.
- Switching in game between the first two modes using hotkeys! See "Alt. method" in the script
- Real mouse can be used as axis* with auto-centering for flight, racing games or something else

*PPJoy - app to create virtual Gamepad. All commands from real devices (mouse, keyboard, wiimote .etc) translate to one virtual device.

How it look like for FPS (first thing that came up on youtube):
https://www.youtube.com/watch?v=UVfJuuVmZNI
Any axis, button or value can be customized. All important notes and settings are annotated inside the script.

What is needed:
Glovepie [github.com] for interpretation wii command to windows directinput.

PPJoy [github.com]
Virtual joystick. Unfortunately, for use on x64 system need to disable driver signature, because driver is not signed by developer. In bios disable secure boot, then open cmd console with admin priv., put "bcdedit /set testsigning on" without quotes, enter and restart.
Install ppjoy, start "Configure Joystick.exe", add button - add joystick, mapping button - next - next - next - ok.

Connect Wiimote with standard microsoft bluetooth driver without pairing pin:
Windows 10 settings-Bluetooth&Devices-More Devices and printer settings(at the very bottom)-add device-1+2 wii button to pair.
Open Glovepie and put this script:
/* Troubleshooting: - When you run the script, Wiimote should be stationary on a horizontal surface a couple of seconds for calibration - If after a few minutes the mouse/joy axis moves up without your input, press F4 half sec. to restart script and don't touch REAL mouse while the script is running - Timer problem on Windows 10/11 for old games. If you see microstutter when you looking in game (even with VSYNC, Freesync .etc), Google: GlobalTimerResolutionRequests - Right click Windows Start button - run: joy.cpl or GlovePie-CP Settings-Joystick - test ppjoy - Glovepie-TroubleShotter: Tick "No auto bluetooth connect" if connecting problem About var.Mouse: 0 or 1 value below depends on how the developer implements controls in the game. For example in FPS games: In most of Unreal and Cryengine games, mouse and joystick work simultaneously, use var.Mouse = 0. In Dying Light mouse not work simultaneously with gamepad input and you can't walk by gamepad stick and look by mouse (real or wiimote). Use var.Mouse = 1 and Wiimote will control virtual (ppjoy) gamepad axis (right stick).*/ PIE.FrameRate = 125hz //frequency of script execution (default USB polling rate) if Helddown(Keyboard.F4, 250ms) { // Restart script Hotkey without minimizing game chain("G:\Games\Utils\JoyPack\0M.PIE") // Path to your script } var.Mouse = 0 // 0 - Wiimote control mouse cursor, 1 - Wiimote control fake right stick, mouse off. // - comment var.Mouse above to activate alternative method below. //Alt. method to switching var.Mouse between 0 - 1 by pressing buttons when script is active. //Script starts as WiiMouse, to change that search line in code BELOW: " if var.Mouse = " and Swap 0 and 1 in three places if Helddown(Keyboard.F3, 250ms) then toggle var.Mouse // pressed F3 250ms to switch //if Helddown(Wiimote.Down, 200ms) + DoubleClicked(Wiimote.Nunchuk.C) then toggle var.Mouse var.RealMouse = 0 // 1 - Control ppjoy axis fake stick by REAL mouse, 0 - off, !!Work only when var.Mouse = 0 // set Virtual Gamepad (ppjoy) "fake" stick sensitivity. Lower - faster var.sensitivityX = 275 //X axis sensitivity var.sensitivityY = 275 //Y axis sensitivity //Autocentering "fake" stick. Lower - faster var.autocenterspeed = 92/100 //how fast "fake stick" return to center. 100/100 - no autocentering //Wii MoutionPlus mouse settings. No effect to control ppjoy axis var.Speed = 85 //Wiimote mouse cursor sensitivity. Higher - faster //Hold to Move button to move mouse cursor / ppjoy axis var.MoveButton = Wiimote.Nunchuk.CButton //FireButton. Wiimote shifts slightly to the side when click to Wiimote B button (Hand muscles) var.sensitivityGyro = [0.4, 0.4] //Firebutton Sensitivity, work separatly from var.Speed above var.deadzoneGyro = [10.0, 10.0] //Firebutton Deadzone, eliminates the shift to the side var.Gyro = [0, 0] var.FireButton = Wiimote.B //- add if not use /* ZoomButton. When aiming in FPS games view speed slows down a lot, especially on gamepad, it can be fixed: Search value belown in script: var.YawSpeed = wiimote.MotionPlus.YawSpeed * 2 and the same for var.PitchSpeed *2 - for x2 speed up movement (set now); /2 - for x2 slow down movement. */ var.ZoomButton = Wiimote.A //- add if not use // Code. Don't touch if you don't know what you're doing if var.RealMouse = 1 var.deltaX = delta(realmouse.DirectInputX) / var.sensitivityX var.deltay = delta(realmouse.DirectInputY) / var.sensitivityY else var.deltax = delta(var.StickX) / var.sensitivityX var.deltay = delta(var.StickY) / var.sensitivityY } var.HoldToMove = True IF HeldDown(abs(wiimote.SmoothRoll)>135, 1 seconds) THEN var.WiimoteUpsideDown = true ELSE var.WiimoteUpsideDown = false IF var.HoldToMove = true { var.Move = var.MoveButton else IF var.MoveButton = false AND var.WiimoteUpsideDown = false THEN var.Move = true ELSE var.Move = false } if wiimote.HasMotionPlus = false then debug = "WiiMotion Plus NOT DETECTED!" if Wiimote.HasNunchuk then Nunchuk.Calibrated = True IF wiimote.HasMotionPlus = true AND var.Move = true { var.YawSpeed = wiimote.MotionPlus.YawSpeed var.PitchSpeed = wiimote.MotionPlus.PitchSpeed if helddown(var.ZoomButton, 1ms) { // add "and var.Mouse = 1" and it work for ppjoy axis only var.YawSpeed = wiimote.MotionPlus.YawSpeed * 2 // Zoom Button x2 more speed X axis var.PitchSpeed = wiimote.MotionPlus.PitchSpeed * 2 // Zoom Button x2 more speed Y axis } if SameValue( Smooth(wiimote.SmoothRoll, 10), wiimote.SmoothRoll, 10) then var.SmoothRoll = Smooth(wiimote.SmoothRoll, 10) else var.SmoothRoll = wiimote.SmoothRoll if var.Roll < 0 and var.Roll >= -90 { var.XYswap = 1 - EnsureMapRange(var.Roll, -90, 0, 0, 1) var.RightDown = -1 var.TopUp = 1 } if var.Roll <= 90 and var.Roll >= 0 { var.XYswap = 1 - EnsureMapRange(var.Roll, 90, 0, 0, 1) var.RightDown = 1 var.TopUp = 1 } if var.Roll > 90 and var.Roll <= 180 { var.XYswap = 1 - EnsureMapRange(var.Roll, 90, 180, 0, 1) var.RightDown = 1 var.TopUp = -1 } if var.Roll < -90 and var.Roll >= -180 { var.XYswap = 1 - EnsureMapRange(var.Roll, -90, -180, 0, 1) var.RightDown = -1 var.TopUp = -1 } var.SpeedX = var.TopUp * var.YawSpeed - ( var.TopUp * var.YawSpeed * var.XYswap ) + ( var.RightDown * var.PitchSpeed * var.XYswap ) var.SpeedY = var.TopUp * var.PitchSpeed - ( var.TopUp * var.PitchSpeed * var.XYswap) + ( -var.RightDown * var.YawSpeed * var.XYswap ) if var.Mouse = 0 and var.FireButton = true { // For alt. method in this line: 1 - script start as fakestick, 0 - Wiimouse if (Abs(WiiMote.MotionPlus.YawSpeed + var.calibrationGyro[1]) > var.deadzoneGyro[1]) then var.Gyro[1] = RemoveUnits(WiiMote.MotionPlus.YawSpeed + var.calibrationGyro[1]) - (Sign(WiiMote.MotionPlus.YawSpeed) * var.deadzoneGyro[1]) if (Abs(WiiMote.MotionPlus.PitchSpeed + var.calibrationGyro[2]) > var.deadzoneGyro[2]) then var.Gyro[2] = RemoveUnits(WiiMote.MotionPlus.PitchSpeed + var.calibrationGyro[2]) - (Sign(WiiMote.MotionPlus.PitchSpeed) * var.deadzoneGyro[2]) Mouse.DirectInputX = Mouse.DirectInputX + (var.Gyro[1] * var.sensitivityGyro[1]) Mouse.DirectInputY = Mouse.DirectInputY + (-1 * var.Gyro[2] * var.sensitivityGyro[2]) } if var.Mouse = 0 and var.FireButton = false { // For alt. method in this line: 1 - script start as fakestick, 0 - as Wiimouse fakemouse.DirectInputX = int(var.MouseX) // Can try = smooth(int(var.MouseX) - smoother but add a huge delay fakemouse.DirectInputY = int(var.MouseY) // Can try = smooth(int(var.MouseY) - smoother but add a huge delay var.MouseX = var.MouseX + ( var.SpeedX / (10500000 - EnsureMapRange(var.Speed, 0, 100, 0, 10000000) ) ) var.MouseY = var.MouseY - ( var.SpeedY / (10500000 - EnsureMapRange(var.Speed, 0, 100, 0, 10000000) ) ) } if var.Mouse = 1 // For alt. method in this line: 1 - script start as Wiimouse, 0 - fakestick var.JoyX += var.SpeedX var.JoyY -= var.SpeedY var.StickX = MapRange(var.JoyX, -4, 4, -1, 1) var.StickY = MapRange(var.JoyY, -4, 4, -1, 1) } } if var.MoveButton = false { var.MouseX = fakemouse.DirectInputX var.MouseY = fakeMouse.DirectInputY } // Bind Wiimote to Axis PPJoy.Analog0 = deadzone(Wiimote.Nunchuk.JoyX, 0.0%) // Left stick X axis, can change deadzone in "%" PPJoy.Analog1 = -deadzone(Wiimote.Nunchuk.JoyY, 0.0%) // Left stick Y axis (= -deadzone to invert axis ) //Next 2 axis with autocentering. Remap axis while keep logical numbering if abs(ppjoy.Analog2) >= 0 and abs(ppjoy.Analog3) >= 0 {// duno how it work, but it is.. PPJoy.Analog2 = PPJoy.Analog2 * var.autocenterspeed + var.deltax // Right stick X axis emulation. "+var.deltax" normal axis PPJoy.Analog3 = PPJoy.Analog3 * var.autocenterspeed - var.deltay // Right stick Y axis emulation. "-var.deltay" invert axis } //Button Mapping PPJoy.Digital0 = Wiimote.Up //Button 1 - # button for x360ce PPJoy.Digital1 = Wiimote1.Left //Button 2 PPJoy.Digital2 = Wiimote1.Right //Button 3 PPJoy.Digital3 = Wiimote1.Down //Button 4 ppjoy.Digital4 = Wiimote.1 //Button 5 ppjoy.Digital5 = Wiimote.2 //Button 6 ppjoy.Digital6 = Wiimote.Home //Button 7 ppjoy.Digital7 = Wiimote.Minus //Button 8 ppjoy.Digital8 = Wiimote.Plus //Button 9 ppjoy.Digital9 = Wiimote.A //Button 10 ppjoy.digital10 = Wiimote.B //Button 11 ppjoy.Digital11 = Wiimote.Nunchuk.Z //Button 12 ppjoy.Digital12 = DoubleClicked(Wiimote.Nunchuk.C) //Button 13 - !!it's a var.MoveButton, can't use as regular button, but Double or TrippleClicked is allowed //Extra buttons and examples ppjoy.Digital13 = -Nunchuk.RelAccZ > 16 //Button 14 //nunchuck gyro (nunchuck move like a blow hammer to release button, for melee attack etc.) /* -Delete all line to use // Bind two virtual button to one physical button. Example: // Pressing Wiimote Up 350ms to release button 15, fast click Wiimote Up = button 16. // Comment button 1 above ppjoy.Digital14 = HeldDown(Wiimote.Up, 350ms) //button 15 if ppjoy.Digital14 { elseif singleClicked(Wiimote.Up) { //button 16 ppjoy.Digital15 = SingleClicked(Wiimote.Up) // This code fix a Glovepie SingleClicked fuction timings for Wiimote, wait 50ms // cause simple "ppjoy.Digital15 = SingleClicked(Wiimote.Up)" ppjoy.Digital15 = SingleClicked(Wiimote.Up) // not work properly, pressing a button sometimes does not work. } */ //ppjoy.Digital14 = Nunchuk.Roll < -55 //Button 1x //nunchuck accel (clockwise(anti) hand on 55 degrees to release button) //ppjoy.Digital14 = Wiimote.Nunchuk.Pitch > 75 //ppjoy.Digital14 = Wiimote.Nunchuk.Pitch < -15 //ppjoy.Digital14 = Wiimote.Nunchuk.Roll > 65 //ppjoy.Digital14 = HeldDown(Wiimote.Minus, 10ms) + Wiimote.Nunchuk.C =true //ppjoy.Digital14 = Wiimote.Nunchuk.Z or HeldDown(Wiimote.Nunchuk.JoyY < -0.96, 100ms) //ppjoy.Digital15 = Helddown(Wiimote.A, 100ms) + DoubleClicked(Wiimote.Nunchuk.C) //PPJoy.Digital3 = Wiimote1.Down or HeldDown(Wiimote.Minus, 500ms) + Wiimote.Nunchuk.C or HeldDown(Wiimote.Plus, 500ms) + Wiimote.Nunchuk.C //mass effect click nuchuck in power wheel to choice //ppjoy.Digital15 = DoubleClicked(Mouse.LeftButton) //ppjoy.Digital15 = TrippleClicked(Wiimote.Nunchuk.Z) //if -Wiimote.Nunchuk.JoyY > 0.97 then press Keyboard.Shift else release Keyboard.Shift //autosprint when stick up //Keyboard.Shift = HeldDown(Wiimote.plus, 200ms) //Keyboard.BackSpace = wiimote.RelAccY > 30 //Keyboard.M = DoubleClicked(Wiimote.Minus) //Keyboard.LeftControl = Wiimote.A /* -Delete all this line to use // one physical button press two different keys (hold or quick click) if HeldDown(Wiimote.Up, 2500ms) { press Key.a wait 100ms release Key.a elseif singleClicked(Wiimote.Up) press Key.b release Key.b } */ //Mouse.LeftButton = Wiimote.B //Mouse.RightButton = Wiimote.A //Mouse.MiddleButton = Wiimote.Home // quick press Wiimote Down and Nuchuck stick to Left - mouse wheel up if HeldDown(Wiimote.Down, 400ms) and -Wiimote.Nunchuk.JoyX > 0.40 { press Mouse.WheelUp wait 350ms release Mouse.WheelUp // quick press Wiimote Down and Nuchuck stick to Right - mouse wheel Down else if HeldDown(Wiimote.Down, 400ms) and Wiimote.Nunchuk.JoyX > 0.40 { press Mouse.WheelDown wait 350ms release Mouse.WheelDown } } //Battery status // Very Inaccurate indicator var.Batt = wiimote.Battery / 48 //if wiimote.1 + wiimote.2 = true { // Debug = "Battery at " + wiimote.Battery /1.4 debug = "Battery level: " + 100*48*var.Batt/192 + "%" //else // Debug ="" //} //Enable (Disable) leds (at the time of callibration led2 & led3 be on, after sucсsessful calibration - led1). Wiimote.Led1 = True Wiimote.Led2 = false Wiimote.Led3 = false Wiimote.Led4 = false


**Important: PPjoy use Windows old "dinput" method. Modern games use "xinput" (Xbox like Pad) instead and we need dinput to xinput translator, i use x360ce [www.x360ce.com]
Download 4.x version and follow the instructions on site below. Map button and axis. In this case for left stick axis 1 and 2, right stick - 3 and 6. Invert axis depends on each game.
Last edited by fttlov; 15 Jun @ 4:28pm
< >
Showing 1-2 of 2 comments
rawWwRrr 24 Nov, 2024 @ 10:52am 
Why hide the code in spoiler?
fttlov 24 Nov, 2024 @ 11:04am 
Fixed
< >
Showing 1-2 of 2 comments
Per page: 1530 50

Date Posted: 24 Nov, 2024 @ 10:45am
Posts: 2