GlovePIE:ZSNES - Smash TV
From WiiLi
The following is an algorithm for The Smash TV written with GlovePIE. The control is mapped for ZSNES and support IR sensor and DPad to shot.
Contents |
[edit] Nunchuk
The Nunchuk is mandatory to control the character. The DPad is reserved for alternative shooting.
[edit] IR Sensor
This script split the screen in 9 zones, the first 8 represents each directions and diagonals for shooting, the center is split again in four portions mapped on diagonals for quick turnover.
To shot, aim at the screen and press A or B.
(A virtual cursor is always indicating where you aim.)
[edit] Traditional DPAD
If you're not confortable with the IR mode, the DPAD is also mapped for shooting.
[edit] Classic controller
If you want a script for Smash TV and the Classic controller [Classic Controller Script]
// Smash TV (for ZSNES)
// Created by Marc-Andre Larouche
// marclar83@gmail.com
//
// 2 fire modes: {IR mode, DPAD}
// Version 0.2
//
// *The Nunchuk is mandatory.
//
// To shot, aim the virtual cursor to one of the extremity of the screen and
// press A or B to shot. You can also use the DPAD as well.
// August 2007
/*********************************************
Displacement:
Nunchuck: Thumbstick
Select/Start:
Select:
Minus
Start:
Plus
Fast Foward:
Home
********************************************/
Key.Z = Wiimote.Down
Key.X = Wiimote.Right
Key.A = Wiimote.Left
Key.S = Wiimote.Up
Key.D = Wiimote.Nunchuk.CButton
Key.C = Wiimote.Nunchuk.ZButton
Key.Enter = Wiimote.Plus
Key.Space = Wiimote.Minus
Key.Console = Wiimote.Home
Key.left = Wiimote.Nunchuk.JoyX <= -25%
Key.right = Wiimote.Nunchuk.JoyX >= 25%
Key.up = Wiimote.Nunchuk.JoyY <= -25%
Key.down = Wiimote.Nunchuk.JoyY >= 25%
wiimote.LED1 = true;
wiimote.LED2 = false;
wiimote.LED3 = false;
wiimote.LED4 = false;
//Fire in the direction of your cursor in relation with the center of the screen.
if Wiimote.A == true or Wiimote.B == true then
var.active = true;
if var.dir_left == true and var.prevY != "left" then
var.prevY = "left";
Key.A = true;
else
var.prevY = "";
Key.A = false;
end if
if var.dir_right == true and var.prevY != "right" then
var.prevY = "right";
Key.X = true;
else
var.prevY = "";
Key.X = false;
end if
if var.dir_up == true and var.prevX != "up" then
var.prevX = "up";
Key.S = true;
else
var.prevX = "";
Key.S = false;
end if
if var.dir_down == true and var.prevX != "down" then
var.prevX = "down";
Key.Z = true;
else
var.prevX = "";
Key.Z = false;
end if
end if
// on btn release
if Wiimote.A != true and Wiimote.B != true and var.active == true then
var.active = false;
var.prevX = "";
var.prevY = "";
Key.Z = false;
Key.X = false;
Key.A = false;
Key.S = false;
end if
// Indicate in which portion of the screen you aim with the virtual cursor.
if (var.SmoothX * Screen.Width)<= var.screenPortionWidth then
var.dir_left = true;
else
var.dir_left = false;
end if
if (var.SmoothX * Screen.Width)>= var.screenPortionWidth*2 then
var.dir_right = true;
else
var.dir_right = false;
end if
if (var.SmoothY * Screen.Height)<= var.screenPortionHeight then
var.dir_up = true;
else
var.dir_up = false;
end if
if (var.SmoothY * Screen.Height)>= var.screenPortionHeight*2 then
var.dir_down = true;
else
var.dir_down = false;
end if
// We had split the screen in 9 portions, the firsts 8 are easy to assign,
// but the middle is split again in four diagonals for more accuracy.
if (var.SmoothX * Screen.Width)>= var.screenPortionWidth and (var.SmoothX * Screen.Width)<= var.screenPortionWidth*2 and (var.SmoothY * Screen.Height)>= var.screenPortionHeight and (var.SmoothY * Screen.Height)<= var.screenPortionHeight*2 then
if (var.SmoothX * Screen.Width)<= var.screenPortionWidth+(var.screenPortionWidth/2) then
var.dir_left = true;
else
var.dir_left = false;
end if
if (var.SmoothX * Screen.Width)>= var.screenPortionWidth+(var.screenPortionWidth/2) then
var.dir_right = true;
else
var.dir_right = false;
end if
if (var.SmoothY * Screen.Height)<= var.screenPortionHeight+(var.screenPortionHeight/2) then
var.dir_up = true;
else
var.dir_up = false;
end if
if (var.SmoothY * Screen.Height)>= var.screenPortionHeight*2+(var.screenPortionHeight/2) then
var.dir_down = true;
else
var.dir_down = false;
end if
end if
// 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


