GlovePIE:FCE Ultra + Zapper + Tilt mode
From WiiLi
The following script is an algorithm for The Emulator FCE Ultra written for GlovePIE. The control feature a Tilt Mode to play games like Marble Madness. To enable this feature, press the "Home" button on your Wiimote.
Contents |
[edit] Configuration
Hold the Wiimote like an NES controller
[edit] P1 controls
UP : Up
DOWN : Down
LEFT : Left
RIGHT : Right
Minus : Select
Plus : Start
one : B
two : A
[edit] Tilt mode
Home : Enable/Disable Tilt Mode
[edit] Zapper
Aim at the screen and press A or B to shoot
[edit] GlovePIE script
/*******************************************************************/
// FCE Ultra Emulator + Zapper + Tilt Mode (Marble Madness, Rad racer...)
// for 1 or 2 player
// Created by Marc-Andre Larouche
// marclar83@gmail.com
//
// *The nunchuk is optional
// (perfect for games with 1 controller + 1 Zapper) like: "Gotcha! The Sport!"
//
// Version 0.12
// tested on GlovePIE 0.29
// September 2007
/********************************************************************/
// READ THIS
// ************************ Important ***************************
//
// By default the second player is not mapped.
// In order to correct this problem, please map
// the Player 2 input to the following keys.
// (you can use this script with the wiimote to do that)
//
// UP: Numpad W | A: Keyboard M
// DOWN: Numpad S | B: Keyboard N
// LEFT: Numpad A | Select: O
// RIGHT: Numpad D | Start: P
//
// The Zapper will only work if you add the Zapper as the 2nd input controller
//
// Press Home to activate the Tilt mode
/*******************
// Player 1
*******************/
// Select/Start
Key.Enter = Wiimote1.Plus
Key.Tab = Wiimote1.Minus
//DPAD Mapping on Analog controls
Key.Up = Wiimote1.Right;
Key.Down = Wiimote1.Left;
Key.Left = Wiimote1.Up;
Key.Right = Wiimote1.Down;
// Button 1 and 2 for P1 btn 1 and 2
Key.Z = Wiimote1.One;
Key.X = Wiimote1.Two;
Key.Z = Wiimote1.Nunchuk.CButton;
Key.X = Wiimote1.Nunchuk.ZButton;
// Press Home to Activate tilt motion
if Wiimote1.Home == true and Var.checked != true then
Var.checked = true;
if Var.active1 == true then
Var.active1 = false;
else
Var.active1 = true;
end if
end if
if Wiimote1.Home == false and Var.checked == true then
Var.checked = false;
end if
if Var.active1 == true then
if MapRange(Wiimote1.gz, 0,1, 0,1) >= 0.33 then
Key.Left = false;
Key.Right = true;
else if MapRange(Wiimote1.gz, 0,1, 0,1) <= -0.33 then
Key.Right = false;
Key.Left = true;
else
Key.Left = false;
Key.Right = false;
end if
if MapRange(Wiimote1.gx, 0,1, 0,1) >= 0.33 then
Key.Up = false;
Key.Down = true;
else if MapRange(Wiimote1.gx, 0,1, 0,1) <= -0.33 then
Key.Down = false;
Key.Up = true;
else
Key.Down = false;
Key.Up = false;
end if
else
debug = "Press Home to activate Tilt Mode"
end if
/*******************
// Player 2
*******************/
// Select/Start
Key.P = Wiimote2.Plus
Key.O = Wiimote2.Minus
//DPAD Mapping on Analog controls
Key.W = Wiimote2.Right;
Key.S = Wiimote2.Left;
Key.A = Wiimote2.Up;
Key.D = Wiimote2.Down;
// Button 1 and 2 for P1 btn 1 and 2
Key.N = Wiimote2.One;
Key.M = Wiimote2.Two;
Key.N = Wiimote2.Nunchuk.CButton;
Key.M = Wiimote2.Nunchuk.ZButton;
// Press Home to Activate tilt motion
if Wiimote2.Home == true and Var.checked2 != true then
Var.checked2 = true;
if Var.active2 == true then
Var.active2 = false;
else
Var.active2 = true;
end if
end if
if Wiimote2.Home == false and Var.checked2 == true then
Var.checked2 = false;
end if
if Var.active2 == true then
if MapRange(Wiimote2.gz, 0,1, 0,1) >= 0.33 then
Key.A = false;
Key.D = true;
else if MapRange(Wiimote2.gz, 0,1, 0,1) <= -0.33 then
Key.D = false;
Key.A = true;
else
Key.A = false;
Key.D = false;
end if
if MapRange(Wiimote2.gx, 0,1, 0,1) >= 0.33 then
Key.W = false;
Key.S = true;
else if MapRange(Wiimote1.gx, 0,1, 0,1) <= -0.33 then
Key.S = false;
Key.W = true;
else
Key.S = false;
Key.W = false;
end if
end if
Wiimote1.LED1 = true;
Wiimote1.LED2 = false;
Wiimote1.LED3 = false;
Wiimote1.LED4 = false;
Wiimote2.LED1 = false;
Wiimote2.LED2 = true;
Wiimote2.LED3 = false;
Wiimote2.LED4 = false;
// I'm using Carl Kenner: "My best IR Mouse Script, with 5DOF Tracking" to handle the IR sensors.
// I had tweaks the cursor motions for the purpose of this script.
var.SensorBarSeparation = 7.5 inches // distance between middles of two sensor bar dots
var.NoYawAllowed = true // Calculates X if no yaw is allowed, otherwise calculates Yaw but not X
var.IRMulX = 1.2
var.IRMulY = 1.2
var.IROffsetX = 0 // add to mouse.x
var.IROffsetY = 0 // add to mouse.y
var.IRLeftButton = Wiimote1.A
var.IRRightButton = Wiimote1.B
// Compensate for roll
var.c = cos(Smooth(wiimote1.roll, 10))
var.s = sin(Smooth(wiimote1.roll, 10))
if wiimote1.dot1vis then
var.dot1x = var.c*(511.5-wiimote1.dot1x)/511.5 - var.s*(wiimote1.dot1y-383.5)/511.5
var.dot1y = var.s*(511.5-wiimote1.dot1x)/511.5 + var.c*(wiimote1.dot1y-383.5)/511.5
end if
if wiimote1.dot2vis then
var.dot2x = var.c*(511.5-wiimote1.dot2x)/511.5 - var.s*(wiimote1.dot2y-383.5)/511.5
var.dot2y = var.s*(511.5-wiimote1.dot2x)/511.5 + var.c*(wiimote1.dot2y-383.5)/511.5
end if
// if both dots are visible check which is which and how far apart
if wiimote1.dot1vis and wiimote1.dot2vis then
if var.dot1x <= var.dot2x then
var.leftdot = 1
var.dotdeltay = var.dot2y - var.dot1y
else
var.leftdot = 2
var.dotdeltay = var.dot1y - var.dot2y
end if
var.dotdeltax = abs(var.dot1x-var.dot2x)
var.DotSep = hypot(var.dotdeltax, var.dotdeltay) * 511.5
var.IRDistance = var.SensorBarSeparation * 1320 / var.DotSep
end if
// sort out the position of the left and right dots
if var.leftdot = 1 then
if wiimote1.dot1vis and wiimote1.dot2vis then
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.LeftDotVis = true
var.RightDotX = var.dot2x
var.RightDotY = var.dot2y
var.RightDotVis = true
else if wiimote1.dot1vis then
if hypot(var.leftdotx-var.dot1x,var.leftdoty-var.dot1y) <= hypot(var.rightdotx-var.dot1x,var.rightdoty-var.dot1y) then
// is the real dot 1
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.dot1x + var.dotdeltax
var.RightDotY = var.dot1y + var.dotdeltay
var.LeftDotVis = true
var.RightDotVis = false
else
// was originally dot 2, but now called dot 1.
var.leftdot = 2 // this dot (1) is actually the right dot
var.LeftDotX = var.dot1x - var.dotdeltax
var.LeftDotY = var.dot1y - var.dotdeltay
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if wiimote.dot2vis then
var.LeftDotX = var.dot2x - var.dotdeltax
var.LeftDotY = var.dot2y - var.dotdeltay
var.RightDotX = var.dot2x
var.RightDotY = var.dot2y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if var.leftdot = 2 then
if wiimote1.dot1vis and wiimote1.dot2vis then
var.LeftDotX = var.dot2x
var.LeftDotY = var.dot2y
var.LeftDotVis = true
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
else if wiimote1.dot1vis then
if hypot(var.leftdotx-var.dot1x,var.leftdoty-var.dot1y) <= hypot(var.rightdotx-var.dot1x,var.rightdoty-var.dot1y) then
var.leftdot = 1 // dot 1 is now the left dot
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.dot1x + var.dotdeltax
var.RightDotY = var.dot1y + var.dotdeltay
var.LeftDotVis = true
var.RightDotVis = false
else
// the real dot 1 (on the right)
var.LeftDotX = var.dot1x - var.dotdeltax
var.LeftDotY = var.dot1y - var.dotdeltay
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if wiimote1.dot2vis then
var.RightDotX = var.dot2x + var.dotdeltax
var.RightDotY = var.dot2y + var.dotdeltay
var.LeftDotX = var.dot2x
var.LeftDotY = var.dot2y
var.LeftDotVis = true
var.RightDotVis = false
end if
else
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.LeftDotX
var.RightDotY = var.LeftDotY
var.LeftDotVis = true
var.RightDotVis = true
end if
// Find the imaginary middle dot
var.MiddleDotX = (var.leftdotx + var.rightdotx)/2
var.MiddleDotY = (var.leftdoty + var.rightdoty)/2
var.MiddleDotVis = wiimote1.dot1vis or wiimote1.dot2vis
if var.MiddleDotVis then
var.TotalPitch = atan2(511.5*var.MiddleDotY,1320) + Wiimote1.Pitch
var.DotYaw = atan2(-511.5*var.MiddleDotX,1320) // assume yaw is 0
var.WiimoteYawNoX = atan2(511.5*var.MiddleDotX,1320)
var.WiimoteXNoYaw = -sin(var.dotyaw)*var.IRDistance
var.WiimoteY = -sin(var.totalpitch)*var.IRDistance
var.WiimoteZ = (-sqrt(sqr(var.IRDistance) - sqr(var.WiimoteY)))*var.IRDistance/RemoveUnits(var.IRDistance)
end if
// scale it to the screen range 0 to 1
var.IRx = var.IRMulX*var.middledotx/2 + 0.5
var.IRy = var.IRMulY*var.middledoty*1023/767/2 + 0.5
var.IRvis = wiimote.dot1vis or wiimote.dot2vis
var.IROnScreen = 0 <= var.IRx <= 1 and 0 <= var.IRy <= 1
// is it off the screen?
var.IRTooFarLeft = var.IRx < 0 or (var.IRx < 0.1 and (not var.IRvis))
var.IRTooFarRight = var.IRx > 1 or (var.IRx > 1-0.1 and (not var.IRvis))
var.IRTooFarUp = var.IRy < 0 or (var.IRy < 0.1 and (not var.IRvis))
var.IRTooFarDown = var.IRy > 1 or (var.IRy > 1-0.1 and (not var.IRvis))
// Heavily smooth small movements, but do zero lag for quick movements
var.MoveAmount = 1024*hypot(delta(var.IRx), delta(var.IRy))
if smooth(var.MoveAmount) > 12 then
var.SmoothX = var.IRx
var.SmoothY = var.IRy
var.LastSureFrame = PIE.Frame
else if (PIE.frame-var.LastSureFrame) > 18 then
var.SmoothX = Smooth(var.IRx, 18, 4/1024)
var.SmoothY = Smooth(var.IRy, 18, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 14 then
var.SmoothX = Smooth(var.IRx, 14, 4/1024)
var.SmoothY = Smooth(var.IRy, 14, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 10 then
var.SmoothX = Smooth(var.IRx, 10, 4/1024)
var.SmoothY = Smooth(var.IRy, 10, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 6 then
var.SmoothX = Smooth(var.IRx, 6, 4/1024)
var.SmoothY = Smooth(var.IRy, 6, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 2 then
var.SmoothX = Smooth(var.IRx, 2, 4/1024)
var.SmoothY = Smooth(var.IRy, 2, 4/1024)
end if
// Freeze the mouse cursor while they start pressing the button
// otherwise it will make the cursor jump
var.Freeze = (var.IRLeftButton or var.IRRightButton) and KeepDown(pressed(var.IRLeftButton) or pressed(var.IRRightButton), 600ms)
// Only change the mouse position if pointing at the screen
// otherwise they can still use a real mouse
if var.IRvis and (not var.Freeze) then
mouse.x = var.SmoothX
mouse.y = var.SmoothY
end if
// delay the buttons slightly so we have time to freeze the cursor (is that needed?)
mouse.LeftButton = var.IRLeftButton and (not KeepDown(pressed(var.IRLeftButton), 40ms))
mouse.RightButton = var.IRRightButton and (not KeepDown(pressed(var.IRRightButton), 40ms))
//! Player 1: nunchuck analog stick mapped to the DPAD
if Wiimote1.Nunchuk.JoyX >= 0.75 and !Var.Joy1Right_en == true then
Var.Joy1Right_en = true
Key.Right = true;
end if
if Wiimote1.Nunchuk.JoyX <= 0.45 and Var.Joy1Right_en == true then
Var.Joy1Right_en = false
Key.Right = false;
end if
if Wiimote1.Nunchuk.JoyX <= -0.75 and !Var.Joy1Left_en == true then
Var.Joy1Left_en = true
Key.Left = true;
end if
if Wiimote1.Nunchuk.JoyX >= -0.45 and Var.Joy1Left_en == true then
Var.Joy1Left_en = false
Key.Left = false;
end if
if Wiimote1.Nunchuk.JoyY <= -0.75 and !Var.Joy1Up_en == true then
Var.Joy1Up_en = true
Key.Up = true;
end if
if Wiimote1.Nunchuk.JoyY >= -0.45 and Var.Joy1Up_en == true then
Var.Joy1Up_en = false
Key.Up = false;
end if
if Wiimote1.Nunchuk.JoyY >= 0.75 and !Var.Joy1Down_en == true then
Var.Joy1Down_en = true
Key.Down = true;
end if
if Wiimote1.Nunchuk.JoyY <= 0.45 and Var.Joy1Down_en == true then
Var.Joy1Down_en = false
Key.Down = false;
end if
//! Player 2
if Wiimote2.Nunchuk.JoyX >= 0.75 and !Var.Joy2Right_en == true then
Var.Joy2Right_en = true
Key.D = true;
end if
if Wiimote2.Nunchuk.JoyX <= 0.45 and Var.Joy2Right_en == true then
Var.Joy2Right_en = false
Key.D = false;
end if
if Wiimote2.Nunchuk.JoyX <= -0.75 and !Var.Joy2Left_en == true then
Var.Joy2Left_en = true
Key.A = true;
end if
if Wiimote2.Nunchuk.JoyX >= -0.45 and Var.Joy2Left_en == true then
Var.Joy2Left_en = false
Key.A = false;
end if
if Wiimote2.Nunchuk.JoyY <= -0.75 and !Var.Joy2Up_en == true then
Var.Joy2Up_en = true
Key.W = true;
end if
if Wiimote2.Nunchuk.JoyY >= -0.45 and Var.Joy2Up_en == true then
Var.Joy2Up_en = false
Key.W = false;
end if
if Wiimote2.Nunchuk.JoyY >= 0.75 and !Var.Joy2Down_en == true then
Var.Joy2Down_en = true
Key.S = true;
end if
if Wiimote2.Nunchuk.JoyY <= 0.45 and Var.Joy2Down_en == true then
Var.Joy2Down_en = false
Key.S = false;
end if

