

; ==============================================================================
; Blitz3D GeoWall Game Engine Template
; (C) 2004 Jason Leigh, Electronic Visualization Laboratory
;
; 
;
; Keys:
;	1 = mono
;	2 = stereo
;	3 = reverse stereo
;	
;
; Created: 7/15/2004
; Version: 8/17/2004
; For comments email: spiff@evl.uic.edu
;
;
;
;modified almost completely by Chris Turek 10/01/2004
;
;
; -----------------------------------------------------------------------------




; Include geowall stereo library
Include "BlitzGeoWallStereoLib.bb"

Include "setupworld.bb"; to help setup the initial world
Include "ChaseCameraLib.bb"
Include "hanoi.bb";the code for the towers of hanoi puzzle
Include "carsAI.bb";ai for the cars to run around the city
Include "pellets.bb";display and handle the pellets the car can collect



; ==============================================================================
; Init graphics and stereo cameras
Global g_screenXSize = 1024
Global g_screenYSize = 768



;global values for the keystrokes
Global U = 200;up
Global D = 208;down
Global L = 203;left
Global R = 205 ;right


; values to help with the hanoi towers setup
Global towersKey = 0
Global movingFlag = 0
Global hanoiSolved = 0
Global allflyers = False
Global lockControls = False


;collision groups
Global SCENERY = 1
Global PLAYER = 2
Global PUZZLE1 = 3
Global POLICE = 4
Global HEARSE = 5
Global USCAR = 6
Global WHITECAR = 7
Global TAXI = 8
Global RED = 9

;pellet collision groups
Global HAPPY_1 = 10
Global HAPPY_2 = 11
Global HAPPY_3 = 12
Global HAPPY_4 = 13
Global HAPPY_5 = 14
Global SAD_1 = 15
Global SAD_2 = 16
Global SAD_3 = 17
Global SAD_4 = 18
Global SAD_5 = 19
Global FLYER_1 = 20
Global FLYER_2 = 21
Global FLYER_3 = 22
Global FLYER_4 = 23


;flags for the car collisions
Global policeFlag = 0
Global hearseFlag = 0
Global uscarFlag = 0
Global whitecarFlag = 0
Global taxiFlag = 0
Global redFlag = 0

Global playAVI = 1



Print "Choose Display Mode:"
Print "1 - Standard GeoWall Stereo (2048x768)"
Print "2 - Desktop (1280x1024)"
Print "3 - Desktop (1024x768)"

choice=WaitKey()

Select choice

Case 49
	g_screenXSize=2048
	g_screenYSize=768
	

Case 50
	g_screenXSize=1280
	g_screenYSize=1024
	

Default
	g_screenXSize=1024
	g_screenYSize=768
	
	
End Select


Graphics3D g_screenXSize, g_screenYSize






; Eye separation (-ve means cross-eyed stereo) 
Global g_eyeSeparation#=0.2
Global g_reverseStereo#=1
SL_SetEyeSeparation(g_reverseStereo# * g_eyeSeparation#)

; Stereo viewing flag: 0=stereo 1=mono
Global g_viewMode=0
SetBuffer BackBuffer() 

;hanoi towers flag
Global hanoiWait = 0

;number of map pieces remaining
Global mapPiecesNeeded = 4;**************************************

;sound -- daft punk
Global soundDaft, chnDaft

;sprite
Global winner, sprite2, completeFlyer




; This is the main camera that you control in the game.
Global g_mainCamera = SL_CreateStereoCameras()
SL_SetUpCameras()

camera=SL_GetRightCamera()
CameraRange camera,1,20000
CameraFogMode camera,1
CameraFogRange camera,60,20000
camera=SL_GetLeftCamera()
CameraFogMode camera,1
CameraFogRange camera,60,20000
CameraRange camera,1,20000



PositionEntity g_mainCamera,0, 10, 0


;*******************************************************************
;the gameend variable is the total number of seconds the game will run
;
;*********************************************************************
Global seconds = 300;modify this variable to change the number of seconds in the game



Global GameEnd 		;=  MilliSecs() + (seconds * 1000)
Global length = 1 ; a positive number so the game will start


;setup the initial world
; scenery, buildings, etc.
SetUpWorld()
hideWorld()
Global sprite ;to play the avi




; ==============================================================================
; Set the game update/calculation rate to 30 frames per second.
; This is NOT the same as FRAME RATE which marks how rapidly the graphics image is updating.
; In this code, the game update/calculation rate is locked down so that the game behaves
; the same for different speed of computers, but the graphics always refreshes as fast as possible.
Const c_GameRate=80
period=1000/c_GameRate
;theTime=MilliSecs()-period
theTime=MilliSecs()

; ==============================================================================



; ==============================================================================
;
;                      *******  MAIN GAME LOOP  *******
;
; ==============================================================================
; MAIN GAME LOOP that maintains stable frame rate for all parts of the game
;
While Not KeyHit( 1 ) 


	




	; Compute how much time has elapsed thru the entire main loop
	Repeat
		elapsedTime=MilliSecs()-theTime
	Until elapsedTime<>0
	
	;how many 'frames' have elapsed	
	elapsedFrames=elapsedTime/period
	
	; If more than 1 frame has elapsed then we have to compute
	; where what the state of the world would have been.
	; This is crucial for slower computers.
	; So this loop goes thru each frame of missed time and computes
	; what the new state of the world should be by simplying
	; calling the users UpdateGameState elapsedFrames times.
	For k=1 To elapsedFrames
	
		; When elapsedFrames is reached, save the state of the world so that tweening
		; can be used to get an accurate interpolation of what the state of the world
		; should be.
		If k=elapsedFrames Then CaptureWorld
		theTime=theTime+period
		
		;play intro movie
		If playAVI = 0 Then
		
		
			; Update the game's state (e.g. position of each entity)		
			GameProcess()
			
			
		ElseIf playAVI = 1 Then
		
		
		
		
		light=CreateLight(2,SL_GetLeftCamera()) 
		moviefilename$ = "scene.avi"
 		movie=OpenMovie( moviefilename$ )
 		mw=MovieWidth(movie) 
		mh=MovieHeight(movie)
 		texture=CreateTexture(mw,mh) 
		toX=(TextureWidth(texture)-mw)/2 
		toY=(TextureHeight(texture)-mh)/2 
		sprite=CreateCube() 
		EntityTexture sprite,texture 
		PositionEntity sprite,-.7,10,3 
		
		sprite2 = LoadSprite("intro.jpg", 8, SL_GetLeftCamera())
		SpriteViewMode sprite2, 3
		EntityOrder sprite2, -11
		ShowEntity sprite2
		PositionEntity sprite2, 1.5, 0, 2.7

		Repeat 
			While MoviePlaying(movie) And (Not KeyDown(25)) 

			SetBuffer TextureBuffer(texture) 
			DrawMovie (movie,toX,toY) 
			SetBuffer BackBuffer() 
			SL_Update()
			UpdateWorld:RenderWorld 
			
			Flip 
		Wend 
		movie=OpenMovie(moviefilename ) 
		Until KeyHit(25) 

		HideEntity sprite2

		playAVI = 0
		showWorld()
		
		SL_SetUpCameras()

		camera=SL_GetRightCamera()
		CameraRange camera,1,20000
		CameraFogMode camera,1
		CameraFogRange camera,60,20000
		camera=SL_GetLeftCamera()
		CameraFogMode camera,1
		CameraFogRange camera,60,20000
		CameraRange camera,1,20000
		
		soundDaft =LoadSound("daftpunk.mp3") ; Load sound 
		chnDaft = PlaySound(soundDaft) 
		PlaySound soundDaft
		LoopSound soundDaft
		
		;start the clock
		GameEnd =  MilliSecs() + (seconds * 1000)
		length = 1 ; a positive number so the game will start
		
		EndIf 
		
	
		
		

		; Update all animation properties- e.g. compute collision checks
		UpdateWorld
	Next

	;Compute the tweening value (a number from 0 to 1)
	; 0 means the state of the world when CaptureWorld was called
	; 1 means the current interpolated state of the world
	; e.g. if elapsedTime is 1 second and desired period is 3 second
	; then 1mod3=1 hence tween=1/period = 1/3 
	; so we interpolate 1/3 distance from the captured point and the present time.
	;
	; if elapsedTime = 5 seconds and desired period is 3 seconds;
	; 1 frame of time would have passed so it would have gone thru
	; the for loop once computing the new frame state
	; Since 5mod3=2 hence tween=2/3 so we tween 2/3 the way between the captured state
	; and the current state.
	tween#=Float(elapsedTime Mod period)/Float(period)


	; Switch to mono mode by pressing 1
	If KeyHit(2)>0 Then
	g_viewMode=1
		SL_SwitchToMono()
		hudMono()
	EndIf
	
	; Switch to stereo mode by pressing 2
	If KeyHit(3)>0 Then
	g_viewMode=0
		g_reverseStereo#=1
		SL_SwitchToStereo()
		SL_SetEyeSeparation(g_reverseStereo# * g_eyeSeparation#)
		hudStereo()
	EndIf

	; Switch to cross eye stereo mode by pressing 3
	If KeyHit(4)>0 Then
		g_viewMode=0
		g_reverseStereo#=-1
		SL_SwitchToStereo()
		SL_SetEyeSeparation(g_reverseStereo# * g_eyeSeparation#)
		hudStereo()
	EndIf
	
	; Change eye separation by pressing + and -
	If KeyHit(13)>0  Then
		g_eyeSeparation#=g_eyeSeparation#+0.1
		SL_SetEyeSeparation(g_reverseStereo# * g_eyeSeparation#)
		hudStereo()
	EndIf
	
	If KeyHit(12) > 0 Then
		g_eyeSeparation#=g_eyeSeparation#-0.1
		If g_eyeSeparation# < 0 Then g_eyeSeparation#=0
		SL_SetEyeSeparation(g_reverseStereo# * g_eyeSeparation#)
		hudStereo()
	EndIf
	

	; Adjust stereo cameras and render the world
	SL_Update()
	RenderWorld tween#/tween


	;debugging tool
	;x# = EntityX# (g_model)
	;y# = EntityY#(g_model)
	;z# = EntityZ#(g_model)
				
	;Text 10,10, "X = " + x#
	;Text 10,25, "Y = " + y#
	;Text 10,40, "Z = " + z#
		

	
	
	If length > 0 And hanoiSolved = 0 Then
	
		length =  ( GameEnd - MilliSecs()  ) / 1000 
		Color(0,153,0) 
		;fntArialB=LoadFont("Arial",19,True,False,False) 
		;SetFont fntArialB

		Text 10, g_screenYSize - 49, "       " + length
	EndIf
	

	If puzzleMode = True And (Not(hanoiSolved = 1)) Then
	
		Color(0,153,0) 
		Text 10, g_screenYSize - 170, "               Spindles of Chi-Town"
		Text 10, g_screenYSize - 155, "               The goal is to move all the discs from the left spindle to the right spindle."
		Text 10, g_screenYSize - 140, "               Only one disc can be moved at a time.  Larger discs cannot be placed on top of smaller ones."
		Text 10, g_screenYSize - 125, "               UP to select a disc, DOWN to release a disc, RIGHT and LEFT to move a disc."
		Text 10, g_screenYSize - 110, "               Good Luck! -- click X to leave the puzzle for now."
		
	
	EndIf 


	; Drawing occurs to the backbuffer, so you need to flip the backbuffer
	; to the front to see it. 
	Flip




Wend 


; ***********************************************************************
; 
;
;
;
;
;************************************************************************
Function GameProcess()
		
		
		;move the AI cars
		moveAICars()

		
		;up arrow key
		If KeyDown(200) And puzzlemode = False And length > 0 And lockControls = False Then
			MoveEntity g_model,0,0, -0.2
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3)	; original
		
			;ChaseCamera(SL_GetLeftCamera(), g_model, 0,600,0)
			EndIf
			
		;down arrow key	
		If KeyDown(208)	And puzzlemode = False And length > 0 And lockControls = False Then
			MoveEntity g_model,0,0,0.2
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3)	; original
			
			;ChaseCamera(SL_GetLeftCamera(), g_model, 0,600,0)
			EndIf
			
		; left arrrow key	
		If KeyDown(203) And puzzlemode = False And length > 0 And lockControls = False Then
			TurnEntity g_model,0,1.4,0			
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3)	; original
			
			;ChaseCamera(SL_GetLeftCamera(), g_model, 0,600,0)
			EndIf
		
		;right arrow key	
		If KeyDown(205) And puzzlemode = False And length > 0 And lockControls = False Then 
			TurnEntity g_model,0,-1.4,0			
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3)	; original
			
			;ChaseCamera(SL_GetLeftCamera(), g_model, 0,600,0)
			EndIf
			
				
				
				
				
				
				
		;**********************************************************
		;CAR AI collisions
		;***********************************************************
		
		
		;the car collided with the scenery
		If EntityCollided (g_model, SCENERY) Then
		 
			
		EndIf
	
	
	
		;the car collided with the cop car
		If EntityCollided (g_model, POLICE) Then
		 
			policeFlag = 1
			
			
		EndIf
		
		
	
	
		;the car collided with the hearse
		If EntityCollided (g_model, HEARSE) Then
		 
			hearseFlag = 1
			
			
		EndIf
	
		;the car collided with the uscar
		If EntityCollided (g_model, USCAR) Then
		 
			uscarFlag = 1
			
			
		EndIf
		
		
		;the car collided with the uscar
		If EntityCollided (g_model, WHITECAR) Then
		 
			whitecarFlag = 1
			
			
		EndIf
		
		;the car collided with the uscar
		If EntityCollided (g_model, TAXI) Then
		 
			taxiFlag = 1
			
			
		EndIf
	
	
		;the car collided with the redcar
		If EntityCollided (g_model, RED) Then
		 
			redFlag = 1
			
			
		EndIf
		
		
		;**********************************************************
		;END CAR AI collisions
		;***********************************************************
		
		
		
		
		
		
		
		
		
	
	;***********************************************************
	;PELLET COLLISIONS
	;***********************************************************
	
	
	;happy face collsions -- add time to the total
	If EntityCollided (g_model, HAPPY_1) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) + 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity happy1
			happysound=LoadSound("shield.wav")
			PlaySound happysound
			
			
		EndIf
		
	If EntityCollided (g_model, HAPPY_2) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) + 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity happy2
			happysound=LoadSound("shield.wav")
			PlaySound happysound
			
			
		EndIf
		
	If EntityCollided (g_model, HAPPY_3) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) + 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity happy3
			happysound=LoadSound("shield.wav")
			PlaySound happysound
			
		EndIf
		
	If EntityCollided (g_model, HAPPY_4) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) + 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity happy4
			happysound=LoadSound("shield.wav")
			PlaySound happysound
			
		EndIf
		
	If EntityCollided (g_model, HAPPY_5) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) + 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity happy5
			happysound=LoadSound("shield.wav")
			PlaySound happysound
			
			
		EndIf
		
		
	;sad face collsions -- reduce time from the total
	If EntityCollided (g_model, SAD_1) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) - 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity sad1
			sadsound=LoadSound("bell1.wav")
			PlaySound sadsound
			
			
		EndIf
		
	If EntityCollided (g_model, SAD_2) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) - 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity sad2
			sadsound=LoadSound("bell1.wav")
			PlaySound sadsound
			
			
		EndIf
		
	If EntityCollided (g_model, SAD_3) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) - 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity sad3
			sadsound=LoadSound("bell1.wav")
			PlaySound sadsound
			
		EndIf
		
	If EntityCollided (g_model, SAD_4) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) - 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity sad4
			sadsound=LoadSound("bell1.wav")
			PlaySound sadsound
			
			
		EndIf
		
	If EntityCollided (g_model, SAD_5) Then
		 
			seconds = ( ( GameEnd - MilliSecs()  ) / 1000 ) - 25
			GameEnd =  MilliSecs() + (seconds * 1000)
			HideEntity sad5
			sadsound=LoadSound("bell1.wav")
			PlaySound sadsound
			
		EndIf
		
		
	;map pieces collsions 
	If EntityCollided (g_model, FLYER_1) Then
		 
			mapPiecesNeeded = mapPiecesNeeded - 1
			ShowEntity hudf1
			HideEntity flyer1
			
			If mapPiecesNeeded > 0 Then
				flyersound=LoadSound("frstC.wav")
				PlaySound flyersound
			EndIf
			
			
		EndIf
		
	If EntityCollided (g_model, FLYER_2) Then
		 
			mapPiecesNeeded = mapPiecesNeeded - 1
			ShowEntity hudf2	
			HideEntity flyer2
			
			If mapPiecesNeeded > 0 Then
				flyersound=LoadSound("frstC.wav")
				PlaySound flyersound
			EndIf
			
		EndIf
		
	If EntityCollided (g_model, FLYER_3) Then
		 
			mapPiecesNeeded = mapPiecesNeeded - 1
			ShowEntity hudf3
			HideEntity flyer3
			
			If mapPiecesNeeded > 0 Then
				flyersound=LoadSound("frstC.wav")
				PlaySound flyersound
			EndIf
			
		EndIf
		
	If EntityCollided (g_model, FLYER_4) Then
		 
			mapPiecesNeeded = mapPiecesNeeded - 1
			ShowEntity hudf4
			HideEntity flyer4
			
			If mapPiecesNeeded > 0 Then
				flyersound=LoadSound("frstC.wav")
				PlaySound flyersound
			EndIf
			
			
		EndIf
	

	
	
	
	
	
	;***********************************************************
	;END PELLET COLLISIONS
	;***********************************************************
	
	
	
	
	
	
	
	
	
	
	
	;PUZZLE RELATED KEYSTROKES
	
	
		;*********************************************************
		;CONTROLS for the TOWERS OF HANOI
		;
		;
		;up arrow -- alternate between the 3 discs
		;
		;left/right arrows -- alternate the currently selected disc between the 3 towers
		;
		;
		;down arrow -- release/drop the currently selected disc onto the currently selected tower
		;
		;X key -- exit and reset the puzzle
		;
		;
		;*********************************************************
	
	
	
		If mapPiecesNeeded < 1 And allflyers = False Then
		
			lockControls = True	
			;completeFlyer = LoadSprite ("flyer.jpg", 8)
			completeFlyer = LoadSprite ("flyer.jpg")
			SpriteViewMode completeFlyer, 1
			ShowEntity completeFlyer
			
			PositionEntity completeFlyer,-63, 4, 97 
			
			PositionEntity SL_GetLeftCamera(), -63, 4, 100
			ChaseCamera(SL_GetLeftCamera(), completeFlyer, 0,5,3)
			
			
			allFlyers = True
			hideWorld()
			ShowEntity hud
			
		
		
		
		EndIf
		

		;spacebar to make the flyer disappear
		If KeyDown(57) Then
		
			HideEntity completeFlyer
			lockControls = False
			showWorld()		
			
			
			x = EntityX#(g_model)
			y = EntityY#(g_model)
			z = EntityZ#(g_model)
			PositionEntity SL_GetLeftCamera(), x,y,z
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3)
		
		EndIf
		



	
	
		;collide with a PUZZLE
		If EntityCollided (g_model, PUZZLE1) Then
		
		If mapPiecesNeeded < 1 Then 
		
		If hanoiSolved = 0 Then
		
		
			If towersKey = 0 Then
				;display the towers of hanoi and set the mode to puzzlemode
				puzzlemode = True
				
				showTowers();display the towers, hide everything else
				hideWorld()
				ShowEntity sky
				ShowEntity road
				ShowEntity hud
			
				towersKey = 1;
			
				EndIf
			
			;are the towers solved?	
			If isSolved() Then
		
		
				HideEntity hudf1
				HideEntity hudf2
				HideEntity hudf3
				HideEntity hudf4
		
		
				;display a sprite 
			
			
				winner = LoadSprite("win_game.jpg",8)
				SpriteViewMode winner, 1
			
				PositionEntity winner,-63, 4, 99 
			
				PositionEntity SL_GetLeftCamera(), -63, 4, 100
				ChaseCamera(SL_GetLeftCamera(), winner, 0,5,3)
				ShowEntity winner
			
		
				puzzlemode = False		

		
				hanoiSolved = 1

			
				towersKey = 0
				movingFlag = 0
		
				hideTowers()
				resetTowers()
				hideWorld()
				
	
		
				EndIf
			
			
			
			
			
			
			EndIf
			
			
		EndIf
				
		
		EndIf


		;in PUZZLE MODE
		
		
		
	
		
	
		
		;up arrow key
		If KeyDown(200) And puzzlemode = True And length > 0 And movingFlag = 0 Then
			
			If hanoiWait = 3 Then
			
				moveDisc(U)
				hanoiWait = 0
			
			Else
			
				hanoiWait = hanoiWait + 1
				
			EndIf
			
			
			
			EndIf
			
		
			
		; left arrrow key	
		If KeyDown(203) And puzzlemode = True And length > 0  Then
			

			If hanoiWait = 3 Then
			
				moveDisc(L)
				hanoiWait = 0
			
			Else
			
				hanoiWait = hanoiWait + 1
				
			EndIf

			
			EndIf
		
		;right arrow key	
		If KeyDown(205) And puzzlemode = True And length > 0  Then 
			


			If hanoiWait = 3 Then
			
				moveDisc(R)
				hanoiWait = 0
			
			Else
			
				hanoiWait = hanoiWait + 1
				
			EndIf

	
			
			EndIf
			
			
			
		;down key is hit -- release the selected block on the current tower
		If KeyDown(208) And puzzlemode = True And length > 0 And movingFlag = 1 Then
			releaseDisc(getTower#())
			movingFlag = 0
			EndIf
				
		
		
		;x key is hit -- solve the puzzle later
		If KeyHit(45) And puzzlemode = True Then
				
			puzzlemode = False		
		
			ShowEntity g_model
			
			towersKey = 0
			movingFlag = 0
			
			hideTowers()
			resetTowers()
			showWorld()
			PositionEntity SL_GetLeftCamera(), -42, 5, 51
			ChaseCamera(SL_GetLeftCamera(), g_model, 0,5,3);reset the camera to the car
		
		EndIf


		;time is soon to run out, so change the pitch of the sound to reflect it
		;the music basically goes faster
		If length <= 20 Then
			;ChannelPitch chnDaft, 3000
		
		EndIf
		
		



		;time runs out
		If length <= 0 Then
			
			hideWorld()
			
			
			PositionEntity gameover,-63, 4, 99 
			
			PositionEntity SL_GetLeftCamera(), -63, 4, 100
			ChaseCamera(SL_GetLeftCamera(), gameover, 0,5,3)
			ShowEntity gameover
			
			
		EndIf
		


	
End Function







End