Here is the source code for the main file of my game that I was doing :
Rem Project: TheRace
Rem Created: 11/10/2003 17:43:28
Rem ***** Main Source File *****
`set display mode 1024,768,32
set display mode 800,600,32
sync on
sync rate 0
autocam off
set text opaque
set image colorkey 0,0,0
cls 0:sync:sync
draw to front
draw sprites last
hide mouse
global highestBlockNumber as DWORD
global numberOfPlayers as DWORD
global screenInfo as _SCREENINFO
global dim playerCamera(MAXPLAYERS) as _PLAYERCAMERA
global dim playerInfo(MAXPLAYERS) as _PLAYERINFO
global dim gridData(MAXGRIDX,MAXGRIDY) as _GRIDDATA
global dim craftInfo(MAX_CRAFTS) as _CRAFTINFO
global dim freeTiles(MAXGRIDX*MAXGRIDY) as _FREETILES
global dim titleTiles(MAXTITLETILES) as _TITLETILE
global dim collectables(MAX_COLLECTABLES) as _COLLECTABLES
global levelInfo as _LEVELINFO
global gameInfo as _GAMEINFO
global fps as DWORD
global gameSpeed as _GAMESPEED
global move# as double float
global numPlayers as DWORD
global maxFreeTiles as DWORD
global dim acid() as _ACID
global titleCount# as double float
global titleXAngle# as double float
`The maximum number of crafts loaded
global maxCrafts as DWORD
global yInfo as DWORD
local numFreeTiles as DWORD:REM Number of free tiles
local anyAcid as DWORD
local statusCount as DWORD
local temp as DWORD
local l as DWORD
getScreenSize()
getConrolDevices()
loadUnloadGraphics(LOAD_FILE)
initTimeMovement()
REM Make sure all player names are blank (later on set to last entered)
for l=PLAYER1 to PLAYER4
playerInfo(l).name$=""
next l
for l=1 to MAX_COLLECTABLES
collectables(l).obj=COLLECTABLE_ADDLITTLETIME+(l-1)
scaleToSize(collectables(l).obj,300.0,300.0,300.0)
next l
repeat
if title()=_EXITGAME
end
endif
l=enterName(gameInfo.numPlayers)
until l=TRUE()
REM Recolour the light
color light 0,255,255,255
for l=PLAYER1 to PLAYER4
if l<=gameInfo.numPlayers
playerInfo(l).craftNumber=OBJECT_PLAYER1CRAFT+(l-PLAYER1)
if object exist(playerInfo(l).craftNumber) then delete object playerInfo(l).craftNumber
clone object playerInfo(l).craftNumber,CRAFT_THRUST+(playerInfo(l).craftIndex-1)
scaleToSize(playerInfo(l).craftNumber,300.0,300.0,300.0)
playerInfo(l).status=GAME_PLAYING
_positionGeneralSprites(SPRITE_TIMETEXT1+(l-PLAYER1),_
IMAGE_TIMETEXT1+(l-PLAYER1),_
playerCamera(l).viewDX-TIMETEXTXSIZE,_
playerCamera(l).viewY)
_positionGeneralSprites(SPRITE_TILESTEXT1+(l-PLAYER1),_
IMAGE_TILESTEXT1+(l-PLAYER1),_
0,_
playerCamera(l).viewY)
else
playerInfo(l).status=GAME_NOTPLAYING
endif
next l
gameInfo.currentLevel=1
highestBlockNumber=0
numFreeTiles=loadLevel(gameInfo.currentLevel)
REM Create the End Of Game font (for Out Of Time/Game Over/Level Complete) messages
for l=PLAYER1 to PLAYER4
if playerInfo(l).status=GAME_PLAYING
fps=SPRITE_TIMETEXT1+(l-PLAYER1)
temp=IMAGE_TIMETEXT1+(l-PLAYER1)
sprite fps,0,0,temp
sprite fps,playerCamera(l).viewDX-sprite width(fps),playerCamera(l).viewY,temp
sprite SPRITE_TILESTEXT1+(l-PLAYER1),_
playerCamera(l).viewX,playerCamera(l).viewY,_
IMAGE_TILESTEXT1+(l-PLAYER1)
showInGameText(l)
endif
next l
`set camera to image 0,IMAGE_BLACK,100,100
anyAcid=array count(acid())
if anyAcid>0
array index to top acid()
next array index acid()
endif
repeat
updateTimer()
fps=screen fps()
text 200,300,"FPS:"+str$(fps)+" "+str$(move#)
for l=PLAYER1 to PLAYER4
if playerInfo(l).status=GAME_PLAYING
movePlayer(l)
checkTiles(l)
decreaseTime(l)
checkCollectable(l)
else
if playerInfo(l).status<>GAME_NOTPLAYING
if playerInfo(l).status=GAME_PROCESSOUTOFTIME or _
playerInfo(l).status=GAME_PROCESSLEVELCOMPLETE
inc playerInfo(l).fadeAlpha#,1.0
if playerInfo(l).fadeAlpha#>255.0
if playerInfo(l).status=GAME_PROCESSOUTOFTIME
playerInfo(l).status=GAME_OUTOFTIME
else
playerInfo(l).status=GAME_LEVELCOMPLETE
endif
else
set sprite alpha SPRITE_PLAYER1GAMEFINISH+(l-PLAYER1),playerInfo(l).fadeAlpha#
text 0,250,str$(playerInfo(l).fadeAlpha#)
endif
endif
endif
endif
next l
REM Update any acid animations
REM One tile isn't animatesd for some reason
if anyAcid>0
if array index valid(acid())
inc acid().animIndex#,move#*30.0
if acid().animIndex#>MAX_ACIDFRAMES
acid().animIndex#=0.0
endif
texture object acid().objNum,acid().animIndex#+IMAGE_ACID01
else
array index to top acid()
endif
next array index acid()
endif
processCollectables(numFreeTiles)
sync
until finishLevel()=4
deleteAllPlayerTempImages()
deleteAllPlayerTempBitmaps()
deleteAllPlayerTempSprites()
REM Fade the complete screen
wait key
end
function processCollectables(numFreeTiles as DWORD)
local l as DWORD
text 0,480,str$(collectables(1)._timer#)+" "+str$(collectables(1).status)+" "+str$(numFreeTiles)
for l=1 to MAX_COLLECTABLES
select collectables(l).status
case COLLECTABLE_NOTINUSE : REM Not used
endcase
case COLLECTABLE_WAITINGTOFALL: REM The timer decreases until its <= 0.0, then we set it up to fall over a collectable tile
dec collectables(l)._timer#,move#*collectables(l).ySpeed#
if collectables(l)._timer#<=0.0
which=rnd(numFreeTiles)
if freeTiles(which).takenByCollectable=FALSE()
collectables(l).zPos#=freeTiles(which).z#
collectables(l).yPos#=4000.0
collectables(l).xPos#=freeTiles(which).x#
collectables(l).ySpeed#=rnd(75)+50.0
collectables(l).status=COLLECTABLE_FALLING
collectables(l).alpha#=255.0
set object collision off collectables(l).obj
position object collectables(l).obj,_
collectables(l).xPos#,_
collectables(l).yPos#,_
collectables(l).zPos#
show object collectables(l).obj
fade object collectables(l).obj,collectables(l).alpha#
freeTiles(which).takenByCollectable=TRUE()
endif
endif
endcase
case COLLECTABLE_FALLING : REM Move the object until its <=0
dec collectables(l).yPos#,move#*collectables(l).ySpeed#
if collectables(l).yPos#<=0.0
collectables(l).yPos#=0.0
collectables(l)._timer#=rnd(2500)+1200.0
collectables(l).ySpeed#=rnd(76)+2.0
collectables(l).status=COLLECTABLE_ACTIVE
set object collision on collectables(l).obj
endif
position object collectables(l).obj,_
collectables(l).xPos#,_
collectables(l).yPos#,_
collectables(l).zPos#
endcase
case COLLECTABLE_ACTIVE : REM Keep active until timer runs out
dec collectables(l)._timer#,move#*collectables(l).ySpeed#
if collectables(l)._timer#<=0.0
collectables(l)._timer#=rnd(1000)+50.0
collectables(l).ySpeed#=(rnd(50)+1.0)/1000.0
collectables(l).status=COLLECTABLE_FADING
endif
endcase
case COLLECTABLE_FADING : REM Fade the object out
dec collectables(l).alpha#,collectables(l).ySpeed#*move#
if collectables(l).alpha#<=0.0
hide object collectables(l).obj
collectables(l).status=COLLECTABLE_COLLECTED
else
fade object collectables(l).obj,collectables(l).alpha#
endif
endcase
case COLLECTABLE_COLLECTED : REM Player has collected this object
hide object collectables(l).obj
collectables(l).status=COLLECTABLE_WAITINGTOFALL
endcase
endselect
next l
endfunction
function finishLevel()
local finish as DWORD
local l as DWORD
finish=0
for l=PLAYER1 to PLAYER4
if playerInfo(l).status=GAME_NOTPLAYING or _
playerInfo(l).status=GAME_OUTOFTIME or _
playerInfo(l).status=GAME_LEVELCOMPLETE
inc finish
endif
next l
endfunction finish
function decreaseTime(player as DWORD)
dec playerInfo(player).time#,move#*2.5
if playerInfo(player).time#<0.0
REM Find out if the minimum number of tiles has been reached
hide sprite SPRITE_TIMETEXT1+(l-PLAYER1)
hide sprite SPRITE_TILESTEXT1+(l-PLAYER1)
if playerInfo(player).numTiles>=levelInfo.numTiles
playerInfo(player).status=GAME_PROCESSLEVELCOMPLETE
createLevelCompleteText(player)
REM Yes, tiles have been reached
else
REM No, the limit hasn't been reached
playerInfo(player).status=GAME_PROCESSOUTOFTIME
createOutOfTimeText(player)
endif
playerInfo(player).fadeAlpha#=0.0
sprite SPRITE_TEMP1+(player-PLAYER1),_
playerCamera(player).viewX,_
playerCamera(player).viewY,_
IMAGE_TEMP1+(player-PLAYER1)
set sprite alpha SPRITE_TEMP1+(player-PLAYER1),playerInfo(player).fadeAlpha#
endif
endfunction
function checkCollectableVisible(obj as DWORD,player as DWORD)
if object collision(obj,playerInfo(player).craftNumber)
if object visible(obj)
exitfunction TRUE()
endif
endif
endfunction FALSE()
function removeCollectable(obj as DWORD)
local l as DWORD
l=(obj-COLLECTABLE_ADDLITTLETIME)+1
hide object obj
set object collision off obj
collectables(l).status=COLLECTABLE_COLLECTED
endfunction
function checkCollectable(player as DWORD)
local l as DWORD
text 0,500,"Coll:"+str$(object collision(COLLECTABLE_ADDLITTLETIME,playerInfo(3).craftNumber))
if checkCollectableVisible(COLLECTABLE_ADDLITTLETIME,player)=TRUE()
REM Add a small amount of time to the player
inc playerInfo(player).time#,10.0
removeCollectable(COLLECTABLE_ADDLITTLETIME)
else
if checkCollectableVisible(COLLECTABLE_BECOMEBESTPLAYER,player)=TRUE()
REM Become best player
removeCollectable(COLLECTABLE_BECOMEBESTPLAYER)
else
if checkCollectableVisible(COLLECTABLE_NULL,player)=TRUE()
REM NULL - Does nothing
removeCollectable(COLLECTABLE_NULL)
else
if checkCollectableVisible(COLLECTABLE_REVERSE,player)=TRUE()
REM Reverse controls for a limited time
removeCollectable(COLLECTABLE_REVERSE)
else
if checkCollectableVisible(COLLECTABLE_TIMEROTATION,player)=TRUE()
REM Rotate times around
removeCollectable(COLLECTABLE_TIMEROTATION)
endif
endif
endif
endif
endif
endfunction
function checkTiles(player as DWORD)
local x as DWORD
local y as DWORD
local coll as DWORD
local prevP as DWORD
local tX as DWORD
local tY as DWORD
local found as DWORD
` x=position(int(playerInfo(player).x#))
` y=position(int(playerInfo(player).z#))
found=FALSE()
for tX=0 to MAXGRIDX>>1
for tY=0 to MAXGRIDY>>1
if gridData(tX,tY).inRange=GRID_INRANGE
if playerInfo(player).x#>=gridData(tX,tY).x and playerInfo(player).x#<=gridData(tX,tY).dx and _
playerInfo(player).z#>=gridData(tX,tY).y and playerInfo(player).z#<=gridData(tX,tY).dy
x=tX
y=tY
found=TRUE()
else
` endif
if gridData(MAXGRIDX-tX,MAXGRIDY-tY).inRange=GRID_INRANGE
if playerInfo(player).x#>=gridData(MAXGRIDX-tX,MAXGRIDY-tY).x and playerInfo(player).x#<=gridData(MAXGRIDX-tX,MAXGRIDY-tY).dx and _
playerInfo(player).z#>=gridData(MAXGRIDX-tX,MAXGRIDY-tY).y and playerInfo(player).z#<=gridData(MAXGRIDX-tX,MAXGRIDY-tY).dy
x=tX
y=tY
found=TRUE()
endif
endif
endif
endif
if found=TRUE() then exit
next tY
next tX
if player=3
` text 0,500,str$(playerInfo(player).x#)+" "+str$(gridData(0,21).x)+" "+str$(gridData(0,21).y)
` text 0,560,str$(playerInfo(player).z#)+" "+str$(gridData(0,21).dx)+" "+str$(gridData(0,21).dy)
endif
if found=TRUE()
if gridData(x,y).collectable
REM A Collectable tile
playerInfo(player).move#=0.0
prevP=gridData(x,y).controlledBy
if prevP<>CONTROL_NONE and prevP<>player
dec playerInfo(prevP).numTiles
endif
if prevP<>player
color object gridData(x,y).objNum,playerInfo(player).colour
gridData(x,y).controlledBy=player
inc playerInfo(player).numTiles
endif
else
REM A Special tile
select gridData(x,y).tileCode
case TILE_SPEEDUP : REM Continue moving player
playerInfo(player).move#=2.0
endcase
case TILE_SLOWDOWN : REM Continue moving player (but slower)
playerInfo(player).move#=0.25
endcase
case TILE_BREAKABLE : REM Breakable tile
inc gridData(x,y).breakableIndex#,2.0*move#*craftInfo(playerInfo(player).craftIndex).weight#
if gridData(x,y).breakableIndex#<=MAX_BREAKABLEFRAMES
texture object gridData(x,y).objNum,gridData(x,y).breakableIndex#+IMAGE_BREAKABLE01
else
gridData(x,y).tileCode=TILE_NOTHING
texture object gridData(x,y).objNum,IMAGE_BLACK
endif
endcase
case TILE_NOTHING : REM A nothing tile, so make sure players are punished
playerInfo(player).x#=playerInfo(player).startX#
playerInfo(player).y#=playerInfo(player).startY#
playerInfo(player).z#=playerInfo(player).startZ#
position object OBJECT_PLAYER1CRAFT+(player-1),_
playerInfo(player).x#,_
playerInfo(player).y#,_
playerInfo(player).z#
endcase
endselect
endif
else
` x=msgbox("*","*",1)
endif
endfunction
function movePlayer(player as DWORD)
local _min as DWORD
local sec as DWORD
local a$ as string
local l as DWORD
local speed# as float
`text player*32,400,str$(craftInfo(playerInfo(player).craftIndex).turnSpeed#)+" C:"+str$(playerInfo(3).controlType)
text player*32,400,str$(playerInfo(player).controlType)
select playerInfo(player).controlType
case _JOYSTICK : controlUsingJoystick(player)
endcase
case _MOUSE : controlUsingMouse(player)
endcase
case _KEYBOARD : controlUsingKeyboard(player)
endcase
endselect
REM Now update player
if playerInfo(player).toRotate<>NO_ROTATION
playerInfo(player).yAng#=wrapvalue(playerInfo(player).yAng#+_
(craftInfo(playerInfo(player).craftIndex).turnSpeed#*_
playerInfo(player).toRotate*_
move#))
endif
if playerInfo(player).move#<>0.0
playerInfo(player).toMove=MOVE_THRUST
speed#=playerInfo(player).move#
else
speed#=1.0
endif
if playerInfo(player).toMove<>NO_MOVEMENT
move object playerInfo(player).craftNumber,_
craftInfo(playerInfo(player).craftIndex).moveSpeed#*_
move#*_
playerInfo(player).toMove*_
speed#*_
-1.0
endif
rotate object playerInfo(player).craftNumber,playerInfo(player).xAng#,playerInfo(player).yAng#,playerInfo(player).zAng#
playerInfo(player).x#=object position x(playerInfo(player).craftNumber)
playerInfo(player).y#=object position y(playerInfo(player).craftNumber)
playerInfo(player).z#=object position z(playerInfo(player).craftNumber)
set camera to follow playerCamera(player).camNum,_
playerInfo(player).x#,_
playerInfo(player).y#,_
playerInfo(player).z#,_
wrapvalue(object angle y(playerInfo(player).craftNumber)-180.0),_
1500.0,_
700,_
1,_
0
REM Display Time
_min=playerInfo(player).time#/60.0
sec=playerInfo(player).time#-(_min*60.0)
a$=fillnumber$(_min,2,"0")+":"+fillnumber$(sec,2,"0")
displayInGameText(a$,_
playerCamera(player).viewDX-(len(a$)*NAMEFONT_XSIZE),_
playerCamera(player).viewY+NAMEFONT_YSIZE+2,_
SPRITE_INGAMETIME11+((player-PLAYER1)*11))
REM Display tiles
a$=fillnumber$(playerInfo(player).numTiles,PADNUMTILESTO,"0")
displayInGameText(a$,_
playerCamera(player).viewX,_
playerCamera(player).viewY+NAMEFONT_YSIZE+2,_
SPRITE_INGAMETILE11+((player-PLAYER1)*11))
` a$=
` writeFontChars(a$,_
` playerCamera(player).viewDX-(len(a$)*INGAMEFONT_XSIZE),_
` playerCamera(player).viewY+18,_
` INGAMEFONT_XSIZE,_
` BANK_INGAME,_
` 1)
endfunction
function controlUsingJoystick(player as DWORD)
local objNum as DWORD
objNum=playerInfo(player).craftNumber
set control device playerInfo(player).joypadName$
`if joystick up()
` move object objNum,4
`endif
endfunction
function controlUsingMouse(player as DWORD)
local temp as integer
`local objNum as DWORD
` objNum=playerInfo(player).craftNumber
temp=mousemovex()
if temp<>0
playerInfo(player).toRotate=sgn(temp)
`playerInfo(player).yAng#=wrapvalue(playerInfo(player).yAng#+(temp*8.0*move#))
else
playerInfo(player).toRotate=NO_ROTATION
endif
if mouseclick() && 1
playerInfo(player).toMove=MOVE_THRUST
else
playerInfo(player).toMove=NO_MOVEMENT
endif
endfunction
function controlUsingKeyboard(player as DWORD)
local objNum as DWORD
objNum=playerInfo(player).craftNumber
if scancode()=playerInfo(player).keyThrust
`move object objNum,-2.0
playerInfo(player).toMove=MOVE_THRUST
else
playerInfo(player).toMove=NO_MOVEMENT
endif
if scancode()=playerInfo(player).keyTurnLeft
playerInfo(player).toRotate=-1
`playerInfo(player).yAng#=wrapvalue(playerInfo(player).yAng#-2.0)
else
if scancode()=playerInfo(player).keyTurnRight
playerInfo(player).toRotate=1
`playerInfo(player).yAng#=wrapvalue(playerInfo(player).yAng#+2.0)
else
playerInfo(player).toRotate=NO_ROTATION
endif
endif
endfunction
function getConrolDevices()
local l as DWORD
perform checklist for control devices
l=checklist quantity()
`Check for joysticks - if none present then reduce the maximum number of players
`do later
playerInfo(PLAYER1).controlType=_NONE
playerInfo(PLAYER1).keyThrust=200
playerInfo(PLAYER1).keyBrake=208
playerInfo(PLAYER1).keyTurnLeft=203
playerInfo(PLAYER1).keyTurnRight=205
playerInfo(PLAYER2).controlType=_NONE
playerInfo(PLAYER2).keyThrust=200
playerInfo(PLAYER2).keyBrake=208
playerInfo(PLAYER2).keyTurnLeft=203
playerInfo(PLAYER2).keyTurnRight=205
playerInfo(PLAYER3).controlType=_MOUSE
playerInfo(PLAYER4).controlType=_KEYBOARD
playerInfo(PLAYER4).keyThrust=200
playerInfo(PLAYER4).keyBrake=208
playerInfo(PLAYER4).keyTurnLeft=203
playerInfo(PLAYER4).keyTurnRight=205
playerInfo(PLAYER1).colour=rgb(255,0,0)
playerInfo(PLAYER2).colour=rgb(255,255,0)
playerInfo(PLAYER3).colour=rgb(255,0,255)
playerInfo(PLAYER4).colour=rgb(0,0,255)
endfunction
function deleteAPlayerTempImages(player as DWORD)
local img as DWORD
img=IMAGE_TEMP1+(player-PLAYER1)
if image exist(img)<>0 then delete image img
endfunction
function deleteAllPlayerTempImages()
local l as DWORD
local img as DWORD
for l=PLAYER1 to PLAYER4
deleteAPlayerTempImages(l)
next l
endfunction
function createAPlayerTempBitmap(player as DWORD)
local img as DWORD
img=BITMAP_TEMP1+(player-PLAYER1)
a$=str$(playerCamera(player).viewDX-playerCamera(player).viewX)+" "+str$(playerCamera(player).viewDY-playerCamera(player).viewY)
create bitmap img,_
playerCamera(player).viewDX-playerCamera(player).viewX,_
playerCamera(player).viewDY-playerCamera(player).viewY
set current bitmap img
endfunction
function deleteAPlayerTempBitmap(player as DWORD)
local img as DWORD
img=BITMAP_TEMP1+(player-PLAYER1)
if bitmap exist(img)<>0 then delete bitmap img
endfunction
function deleteTempBitmap()
deleteAPlayerTempBitmap(PLAYER_1)
endfunction
function deleteAllPlayerTempBitmaps()
local l as DWORD
local img as DWORD
for l=PLAYER1 to PLAYER4
deleteAPlayerTempBitmap(l)
next l
endfunction
function deleteAPlayerTempSprite(player as DWORD)
local img as DWORD
img=SPRITE_TEMP1+(player-PLAYER1)
if sprite exist(img)<>0 then delete sprite img
endfunction
function deleteAllPlayerTempSprites()
local l as DWORD
local img as DWORD
for l=PLAYER1 to PLAYER4
deleteAPlayerTempSprite(l)
next l
endfunction
function createBitmapFont(bitmapWidth as DWORD,text$ as string,fontWidth as DWORD)
local temp as DWORD
temp=(bitmapWidth-(len(text$)*fontWidth))>>1
endfunction temp
function createLevelCompleteText(player as DWORD)
hideInGameText(player)
sprNum=SPRITE_PLAYER1GAMEFINISH+(player-PLAYER1)
sprite sprNum,_
playerCamera(player).viewX,_
playerCamera(player).viewY,_
IMAGE_LEVELCOMPLETE
set sprite alpha sprNum,0
REM Scale the sprite according to the required range
`x#=((playerCamera(player).viewDX-playerCamera(player).viewX)/sprite width(sprNum))*100.0
`y#=((playerCamera(player).viewDY-playerCamera(player).viewY)/sprite height(sprNum))*100.0
size sprite sprNum,_
playerCamera(player).viewDX-playerCamera(player).viewX,_
playerCamera(player).viewDY-playerCamera(player).viewY
show sprite sprNum
endfunction
function createOutOfTimeText(player as DWORD)
local sprNum as DWORD
`local x# as double float
hideInGameText(player)
sprNum=SPRITE_PLAYER1GAMEFINISH+(player-PLAYER1)
sprite sprNum,_
playerCamera(player).viewX,_
playerCamera(player).viewY,_
IMAGE_GAMEOVER
set sprite alpha sprNum,0
REM Scale the sprite according to the required range
`x#=((playerCamera(player).viewDX-playerCamera(player).viewX)/sprite width(sprNum))*100.0
`y#=((playerCamera(player).viewDY-playerCamera(player).viewY)/sprite height(sprNum))*100.0
size sprite sprNum,_
playerCamera(player).viewDX-playerCamera(player).viewX,_
playerCamera(player).viewDY-playerCamera(player).viewY
show sprite sprNum
endfunction
function initTimeMovement()
gameSpeed.t1=timer()
gameSpeed.t2=0
gameSpeed.t3=0
gameSpeed.t4=0
gameSpeed.t9=1000
endfunction
function updateTimer()
gameSpeed.t2=timer()
inc gameSpeed.t3
if gameSpeed.t2-gameSpeed.t1 >= gameSpeed.t9
move#=((gameSpeed.t2-gameSpeed.t1)/1000.0)/gameSpeed.t3
gameSpeed.t1=gameSpeed.t2
gameSpeed.t3=0
gameSpeed.t4=1
else
if gameSpeed.t4=0 then move#=((gameSpeed.t2-gameSpeed.t1)/1000.0)/gameSpeed.t3
endif
endfunction
The source code and media is availiable from my web site.
Mirrors are more fun than television. Well, that was fun, in a not-so-fun sort of way...