GlovePIE:MAME/MAME32 - Space Harrier
From WiiLi
The following is an algorithm for the classic Arcade game "Space Harrier" written for GlovePIE. The control is mapped for M.A.M.E and support IR Analog control with a Virtual Joystick.
Contents |
[edit] **IMPORTANT**
You need to install PPJoy before using the script.
The package could be found here:
http://www.geocities.com/deonvdw/PPJoy.htm
or
Download the package directly here (mirror)
[edit] Wiimote Setup
[edit] Wiimote
[edit] Wiimote Tilting
**Hold the Wiimote like a TV controller
Aim at your screen: Move the Harrier
[edit] DPAD
Left: Move Harrier Left
Right: Move Harrier Right
Up: Move Harrier Up
Down: Move Harrier Down
[edit] Action button
A: P1 Btn 1
B: P1 Btn 1
[edit] Emulator controls
Minus: P1 Coin
Home: M.A.M.E Throttle
Plus: P1 Start
[edit] GlovePIE Script v0.2 (GlovePIE 0.3+)
// Space Harrier (for MAME*) // Tested on MAME32 // Created by Marc-Andre Larouche // marclar83@gmail.com // version 0.2 // // for GlovePIE 0.3+ // // IR Analog control // To move, aim the virtual cursor at the screen and // press A or B to shot. You can also use the DPAD as well. // September 2007 /********************************************************************/ // READ THIS // ************************ Important *************************** // Enable Joystick input // and Disable Mouse input on M.A.M.E // also // PPJoy must be install and configured to enable // a virtualJoystick as Windows the first controller // // Download here: // http://www.geocities.com/deonvdw/PPJoy.htm // Otherwise the IR control won't work!!! PPJoy1.Analog0 = MapRange(Wiimote1.PointerX,0,1,-1,1); PPJoy1.Analog1 = MapRange(Wiimote1.PointerY,0,1,-1,1); Key.LeftControl = Wiimote1.A; Key.LeftControl = Wiimote1.B; Key.one = Wiimote1.Plus Key.Five = Wiimote1.Minus Key.F10 = Wiimote1.Home Key.Down = Wiimote1.Down; Key.Up = Wiimote1.Up; Key.Left = Wiimote1.Left; Key.Right = Wiimote1.Right; Wiimote1.Led1 = true; Wiimote1.Led2 = false; Wiimote1.Led3 = false; Wiimote1.Led4 = false; Cursor1.Visible = true // Change this for your current Windows/cursors directory!!! Cursor1.image = "C:\WINDOWS\Cursors\cross_i.cur" Cursor1.caption = "" Cursor1.x = Wiimote1.PointerX Cursor1.y = Wiimote1.PointerY
[edit] Older versions
[edit] GlovePIE Script v0.1 (GlovePIE 0.28+)
// Space Harrier (for MAME*)
// Tested on MAME32
// Created by Marc-Andre Larouche
// marclar83@gmail.com
// version 0.1
//
// Special Thanks to Carl Kenner for his best IR mouse Script that I use.
//
// IR Analog control
// To move, aim the virtual cursor at the screen and
// press A or B to shot. You can also use the DPAD as well.
// September 2007
/********************************************************************/
// READ THIS
// ************************ Important ***************************
// Enable Joystick input
// and Disable Mouse input on M.A.M.E
// also
// PPJoy must be install and configured to enable
// a virtualJoystick as Windows the first controller
//
// Download here:
// http://www.geocities.com/deonvdw/PPJoy.htm
// Otherwise the IR control won't work!!!
PPJoy1.Analog0 = MapRange(var.SmoothX,0,1,-1,1);
PPJoy1.Analog1 = MapRange(var.SmoothY,0,1,-1,1);
Key.LeftControl = Wiimote.A;
Key.LeftControl = Wiimote.B;
Key.one = Wiimote.Plus
Key.Five = Wiimote.Minus
Key.F10 = Wiimote.Home
Key.Down = Wiimote.Down;
Key.Up = Wiimote.Up;
Key.Left = Wiimote.Left;
Key.Right = Wiimote.Right;
// 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.screenPortionWidth = Screen.Width/3;
var.screenPortionHeight = Screen.Height/3;
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 = Wiimote.A
var.IRRightButton = Wiimote.B
// Compensate for roll
var.c = cos(Smooth(wiimote.roll, 10))
var.s = sin(Smooth(wiimote.roll, 10))
if wiimote.dot1vis then
var.dot1x = var.c*(511.5-wiimote.dot1x)/511.5 - var.s*(wiimote.dot1y-383.5)/511.5
var.dot1y = var.s*(511.5-wiimote.dot1x)/511.5 + var.c*(wiimote.dot1y-383.5)/511.5
end if
if wiimote.dot2vis then
var.dot2x = var.c*(511.5-wiimote.dot2x)/511.5 - var.s*(wiimote.dot2y-383.5)/511.5
var.dot2y = var.s*(511.5-wiimote.dot2x)/511.5 + var.c*(wiimote.dot2y-383.5)/511.5
end if
// if both dots are visible check which is which and how far apart
if wiimote.dot1vis and wiimote.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 wiimote.dot1vis and wiimote.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 wiimote.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 wiimote.dot1vis and wiimote.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 wiimote.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 wiimote.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 = wiimote.dot1vis or wiimote.dot2vis
if var.MiddleDotVis then
var.TotalPitch = atan2(511.5*var.MiddleDotY,1320) + Wiimote.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)
// This is the only changes I have made to Carl' script
if var.IRvis and (not var.Freeze) then
Cursor1.Visible = true
Cursor1.CursorPosX = var.SmoothX * Screen.Width
Cursor1.CursorPosY = var.SmoothY * Screen.Height
end if

