Can a mod fix this post please?

Miscellaneous Forums/General Discussion/Can a mod fix this post please?

http://blitzmax.com/Community/posts.php?topic=75453

Chroma's posted some code down the bottom whih as a deletedir command in it which specifies .bmx. I'm not sure if this will erase all the .bmx files in your directory if you run it, and I'm sure if it does, it wasn't intentional, but if this would result in dangerous behavior then the post should be edited, and I don't know when Chroma will arrive to fix it himself.

I have no idea why Chroma is deleting that folder, but it's nothing to worry about. Maybe he's short on hard drive space or something. It's just the folder where BlitzMax builds some temporary files during compilation.

Ah. He must be very short on space then cause the files in there are like 8k each and there's not that many of them.

FALSE ALARM!

Still, not a good idea to delete directories in code postings. :-)

the files in there are like 8k each and there's not that many of them.

That really depends where you are looking.
My current module project has 30meg of stuff in 850+ files inside .bmx folders.
If, for example, you wanted to archive it to take somewhere else, you'd save both time and space by removing the gunk first :-)

Maybe if you were uploading it, but these days 30 megs is NOTHING! :-) I don't even THINK about bothering to delete 30 meg files from my download folder when I haven't used them for four years anymore.

Everyone should have a terabyte on their desktop PC. :-)

30 meg makes a huge difference if you're archiving your project with something like 7z on ultra - no matter what machine you've got.

Plays nicer with source control too.

You compress your projects? I just copy all my files to a second drive where I have as "backup" directory.

For BlitzMax I have 10,000 files there taking up a mere 2 gigs of space, and that's including all the uncompressed media for al lthe projects, including all the variations and in-progress photoshop files.

It would take forever to compress all that, and I'd save what, a gig? Not worth the effort! And compressing with 7z on Ultra? Now that's just insanity. What do you save, 2% more? And for what, an hour long wait? And then you can't even access the files directly as if it were a directory like you can if you just zipped them I'll bet.

Yer crazy. :-)

Less data means less data to be corrupted, then again regaining data from a corrupted compressed file would be even harder ;)

Personally i use a local SVN server for my projects, and once in a while i upload the repositories to gmail in case all my hds brake.

You compress your projects? I just copy all my files to a second drive where I have as "backup" directory.

For BlitzMax I have 10,000 files there taking up a mere 2 gigs of space, and that's including all the uncompressed media for al lthe projects, including all the variations and in-progress photoshop files.

It would take forever to compress all that, and I'd save what, a gig? Not worth the effort! And compressing with 7z on Ultra? Now that's just insanity. What do you save, 2% more? And for what, an hour long wait? And then you can't even access the files directly as if it were a directory like you can if you just zipped them I'll bet.

Yer crazy. :-


I have a 3.16ghz core 2 duo and the world's slowest broadband connection. It's faster, believe me.

Anyway, I'm not the one using the worlds most ridiculous source control system.

Hey, I still have code which I wrote on my commodore 64 back in 1986, so don't tell me my source control system is rediculous. :-) IT WORKS!

Well michael's works better cos he finishes full games so there :)

Lowcs:

Hey, I'll have you know I have finished games! One of which was:

http://www.bigfishgames.com/download-games/970/legobuilderbots/index.html

Which I wrote in BlitzPlus.

Another I finished last year in BlitzMax, but I can't tell you the name of it. All I can say was it was a puzzle game, and it hasn't been released.

the worlds most ridiculous source control system

Perhaps I'm just a bit slow, but what is this a reference to? I am intrigued.

He's making fun of how every time I save my source, I increment a number on the end like so: SpaceBeetles-026.bmx

Then when I have like 10 of those in the directory I move them to a subdirectory called "Old", and every few months I just copy my whole BlitzMax directory to another drive in my system in case I ever have a hard drive crash.

That's all. There's nothing rediculous about it. It works for me. I don't need that SVC crap, I'm not one programmer among 20 at some big corporation. :-) Retro64 once tried to get me to use SVC for a game I was doing for them, I think, but we couldn't get it to work with Blitz properly, and I hated how it kept leaving all these stupid little data files all over the place. And using it meant that if I saved a blank file by accident, then I'd lose all my data since the last time I sent him an update, since I'd only have the one source file I kept saving over.

Personally, I think it's overrated. :-) Back when I worked for Irrational Games, they were constantly passing around this pink brick to signify something that had to do with who had control of the source or something. I don't know exaclty what it was, but they had a source control system too, and if they needed a little pink brick to make sure stuff didn't get all screwed up ANYWAY, then it seems to me that that sort of thing isn't all it's cracked up to be. :-)

But my silly reasoning for my prejudices is neither here not there. Point is, I've been using this system since I started coding, and I've NEVER lost code, and I can always go back to old versions and find what I need easily. There's nothing ridiculous about it!


Oh and he's probably complaining simply because he had to work on my Builder Bots code after I finished the game because the people wanted some additions, and it was probably hell cause I wrote it in BlitzPlus in a rush and did not have time to work out the very best way of handling state systems and menus and crap, so the code was a bit hard to follow. (Not my sprite system of course since I spent lots of time making sure that was perfect.)

SO HE'S JUST BITTER. :-)

Oh that's pretty much how I do things. I mean I don't increment the number often (certainly not every save, just whenever I feel like I've made a major change) but same idea. Not really knowing anything about computer science or engineering or anything, I don't understand what CVS does. The one time I tried to use SourceForge I ran away screaming. I felt like I failed as a nerd.

That's still MUCH better than this one friend of mine who I collaborate with a lot. He's a 3D artist, and when we work together on projects (eg. right now) he'll frequently save additional copies of models to experiment on, with the result that he'll send me a folder full of stuff like "building.b3d", "buildingz.b3d", "buildingzzz.b3d", and "_building.b3d", and he has no idea which one is which or what the difference is between them. @#$!@%$!@#$!

I don't need that SVC crap, I'm not one programmer among 20 at some big corporation.

Oh dear...

SVN I meant SVN!

Oh and here's a page on it:
http://en.wikipedia.org/wiki/Subversion_(software)

Still don't like it. :-)

Oh and he's probably complaining simply because he had to work on my Builder Bots code after I finished the game because the people wanted some additions, and it was probably hell cause I wrote it in BlitzPlus in a rush and did not have time to work out the very best way of handling state systems and menus and crap, so the code was a bit hard to follow. (Not my sprite system of course since I spent lots of time making sure that was perfect.)


Funny, when I want to develop something as quickly as possible, I make it flexible...

Actually I don't really have an opinion on the BB source. I wish you listened to Mike, because that was some good advice you're turning down, but whatever. You finished the project, that's all that matters.

But I think you finished it because of persistance. Your sprite system isn't that good, the ABSOLUTELY CRAZY way you stuck everything in an array was just, well... aboslutely crazy. Your source control method might work but if you'd take a few seconds to learn how to actually use SVN it would be safer and faster.

So whatever works for you, just please refrain from giving advice along those lines. It will save a whole new generation of newbies. :)

All I can say was it was a puzzle game, and it hasn't been released.
ooh, is it going to be released? I'd like to see it.

Oh dear...
Indeed.

Still don't like it. :-)
Don't worry sswift. Nobody's expecting you to come willingly into the 21st century.

I still have code which I wrote on my commodore 64 back in 1986, so don't tell me my source control system is rediculous.
I rest my case.


Funny, when I want to develop something as quickly as possible, I make it flexible...



It takes time to design something to be flexible. You have to consider all possibilities for its use. Do you deny that it is faster to write simple programs using global variables and arrays than to carefully design types which are far more powerful?

My sprite system for example. Easier in the short run to just create an array to hold loaded images and an array of XY positions and health and a count of how many monsters there are and shuffle that stuff around as they are created and destroyed... But not very flexible when you want to start animating them with the same automated system that animates all your other objects. Yet it takes far longer to properly design and code the sprite system than it does to use the arrays. But if you us the arrays you end up with spaghetti code that gets harder and harder to maintain and add to as it gets bigger.

Which is just what happened with Builder Bots. I was in a rush, I used the equivalent of arrays for the menus. I didn't design the loop in a way which was easy to read. I didn't bother trying to figure out what should be stuck in a function outside the main loop.


Your sprite system isn't that good, the ABSOLUTELY CRAZY way you stuck everything in an array was just, well... aboslutely crazy.



Now wait just a minute. Im gonna assume you're talking about my BlitzPlus sprite system which is a whole different beast than my BlitzMax one, but neither uses arrays to store anything.

I think what you're talking about is how in the main program I used arrays to store the pointers to the images the robots needed and stuff:

	Const TOTAL_ROBOT_CLASSES    = 4
	Const TOTAL_ROBOT_COLORS     = 4
	Const TOTAL_ROBOT_ANIMATIONS = 12


	Dim IMG_Robot.IMG(TOTAL_ROBOT_COLORS, TOTAL_ROBOT_CLASSES, TOTAL_ROBOT_ANIMATIONS)	; Images of robots: IMG_Robot(Color, Class, Animation)			

	Global Building_Bot_Color 								; This is the color of the robot the player is currently building.
	Global Building_Bot_Class 								; This is the class of the robot the player is currently building.


	Dim Robot_Blocks_Needed(TOTAL_ROBOT_CLASSES)			; This is the number of bricks needed to construct a particular class of robot.		

		Robot_Blocks_Needed(0) = 6
		Robot_Blocks_Needed(1) = 12
		Robot_Blocks_Needed(2) = 18
		Robot_Blocks_Needed(3) = 24

	; These are values which are loaded from the config file at the start of each level:															

		Global RECYCLE_BIN_SPEED = 400							; The speed at which the recycle bins move in pixels per second.

		Dim Default_Robot_Color_Weight(TOTAL_ROBOT_COLORS)		; These arrays define the probaiblity that a particular color of robot will appear.
		Dim Robot_Color_Weight(TOTAL_ROBOT_COLORS)				; Why do I store defaults?										
	
		Dim Default_Robot_Class_Weight(TOTAL_ROBOT_CLASSES)		; These arrays define the probaiblity that a particular class of robot will appear.
		Dim Robot_Class_Weight(TOTAL_ROBOT_CLASSES)														
		
		Dim Robot_Build_Repeats(TOTAL_ROBOT_CLASSES)			; This is the number of times the robot's build animation repeats.
		Dim Robot_Pattern_Bricks(TOTAL_ROBOT_CLASSES)			; This is the number of bricks each robot class will place at one time
		Dim Robot_Pattern_Area(TOTAL_ROBOT_CLASSES, 2)			; This is the size of the area in which the robot can place those bricks.  In the form of an X and Y radius.  Pattern only extends up in Y direction, so if the Y radius is three, the area built in will be three bricks tall.
		Dim Robot_Walk_Speed(TOTAL_ROBOT_CLASSES)				; This is the speed at which each class of robot moves in pixels per second.
		Dim Robot_Recharge_Time(TOTAL_ROBOT_CLASSES)			; This is the number of milliseconds it takes each class of robot to recharge.
		Dim Robot_Lifespan(TOTAL_ROBOT_CLASSES)					; This is the default lifespan of this class of robot.



And while I might do this differently if I had more than four classes to worry about, this is hardly any more difficult to use than it would have been if I created a type with one field for each of those properties and created four instances of that and referenced those instead for the properties of the class.

As for the individual robots, those has a type to handle them:


	Type Robot

		Field BOB.BOB												; This is the pointer to the sprite that represents the object.

		Field Robot_Color
		Field Robot_Class
		
		Field X#, Y#
		Field Vy#
		
		Field Speed_X#, Direction_X#
		
		Field State 
		
		Field Life_Remaining												
		
		Field NextFlash												; This is the time at which the robot should next go from visible to hidden, or vice versa.
		Field FlashState 
		
		Field NextBrickTime											; This is the time at which the robot should next place a brick.		
	
		Field Expiring
	
		Field Paused
		
		
		Field RecycleBin.BOB										; This is the BOB that represents the recycle bin currently moving to collect the robot.
		Field RecycleBinWheels.BOB									
		
		Field LastSpeedEffectTime
		
	End Type	



I also noticed that in the end I did end up cleaning up the menu system and making types and functions for it. Not as tidy as what I could do now in BlitzMax, but that was a limitation of the language.

The real problem was the main loop being messy with gosubs to try to move sections of code out of the main loop to make things easier to read, and a horrible state system which results in a big case statement with lots of code in it. I still haven't come up with a good solution for that, but at least the state systems I'm currently using are a bit neater and tider than this:

; --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.Get_Input
	
	; Get any pending events.
	; Pause app if application loses focus.
	EventHandler()
	
	; Get mouse input.

		Old_Mouse_X = Mouse_X
		Old_Mouse_Y = Mouse_Y

		If Not Windowed 
	
			; Fullscreen.
	
			If MouseDown(1) Then MouseDown_Left   = True
			If MouseDown(2) Then MouseDown_Right  = True
			If MouseDown(3) Then MouseDown_Middle = True

			If MouseHit(1)  Then MouseHit_Left    = True
			If MouseHit(2)  Then MouseHit_Right   = True
			If MouseHit(3)  Then MouseHit_Middle  = True
		
			Mouse_X = MouseX()
			Mouse_Y = MouseY()
	
		Else
		
			; Windowed.
		
			; In windowed mode, the MouseDown and MouseHit variables are updated in the event handler.
	
			Mouse_X = MouseX(Window_Canvas)
			Mouse_Y = MouseY(Window_Canvas)

		EndIf

		MouseSpeed_X = Mouse_X - Old_Mouse_X
		MouseSpeed_Y = Mouse_Y - Old_Mouse_Y
		
		; Recenter the mouse if desired.
		; Recentering the mouse allows MouseSpeed to work 

			If Mouse_ForceRecenter 
			
				If Windowed 
					MoveMouse SCREEN_WIDTH/2, SCREEN_HEIGHT/2, Window_Canvas
				Else
					MoveMouse SCREEN_WIDTH/2, SCREEN_HEIGHT/2
				EndIf
				
				Mouse_X = SCREEN_WIDTH/2
				Mouse_Y = SCREEN_HEIGHT/2			
				
			EndIf
			
	
	Select True 
	
		; Logos are being displayed.
		Case (GLOBAL_State >= GS_BUILDERBOTS_LOGO_FADING_IN) And (GLOBAL_State <= GS_RETRO64_LOGO_PAUSE2)
		
			; If the ESC key or the SPACEBAR is pressed while the logos are being displayed, skip directly to the main menu.
				If (KeyHit(KEY_ESC) = True) Or (KeyHit(KEY_SPACE) = True) Or (MouseHit_Left = True) 
					GotoMainMenu()
				EndIf
		
		; The game is displaying a menu. 
		; This could be over the gameplay screen, or over a background of clouds.
		; When a menu is active, no input will go to the game, and a mouse cursor may be displayed in addition to the catcher. 
		; The catcher will not move with the mouse however.
		Case GLOBAL_State = GS_MENU_ACTIVE

			
			; If the left mouse button is no longer down, deselect the selected menu item.					
				If (MouseDown_Left = False) Then Selected_Menu_Item = 0				


			; If the user has clicked on a menu button with the left mouse button, select it.
													
				If MouseDown_Left
	
					For Loop = 1 To MAX_MENU_ITEMS-1

						Select True
							
							; Ths following should not be treated like buttons:
							; I really ought to have made the menus have a number to tell what the last item that is clickable is.
							
							Case (Active_Menu = MENU_MAIN)          And (Loop > 8)		; Arcade/advanced togggle button special states							
							Case (Active_Menu = MENU_HELP)          And (Loop > 2)  	; The text on the context sensitive help menu. 
							Case (Active_Menu = MENU_HELP_ARCADE)   And (Loop > 3)		; The text on the arcade help menu.  
							Case (Active_Menu = MENU_HELP_ADVANCED) And (Loop > 3)		; The text on the advanced help menu. 
							Case (Active_Menu = MENU_PLAYERSELECT)  And (Loop > 14)		; The player selection outlines on the player selection screen.
							Case (Active_Menu = MENU_LEVELSTART)    And (Loop > 0)		; Level numbers
							Case (Active_Menu = MENU_CREDITS)       And (Loop > 1)		; The credit scroll.
							Case (Active_Menu = MENU_HIGHSCORES)	And (Loop > 1)		; The alternate background.
							Case (Active_Menu = MENU_OPTIONS)		And (Loop > 6)		; Checks for help and fulslcreen buttons.
							
							; What to do if this item is a button:

							Case True
								
								; If a BOB exists for this menu item...
								If BOB_Menu(Active_Menu, Loop) <> Null

									; If the top left pixel of the mouse cursor is over it...
									If BOB_RectOverlap(BOB_Menu(Active_Menu, Loop), Mouse_X, Mouse_Y, 1, 1)

										; If the left mouse button was clicked...
										If (MouseHit_Left = True)

											; Play a click sound.
												PlaySND(3)
														
											; Record which menu item was clicked.
												Selected_Menu_Item = Loop
								
												Last_Selected_Menu_Item = Selected_Menu_Item
												Last_Active_Menu = Active_Menu

											; Exit loop.
												Exit 
																		
										EndIf
		
									EndIf
							
								EndIf
						
						End Select
						
					Next
	
				EndIf
					
				
			; Highlight the menu item which the mouse is hovering over.
					
				; If no menu item is currently selected...
				If Selected_Menu_Item = 0
						
					For Loop = 1 To MAX_MENU_ITEMS-1

						Select True
							
							; This item is not a button:
							Case (Active_Menu = MENU_MAIN)          And (Loop > 8)		; Arcade/advanced togggle button special states	
							Case (Active_Menu = MENU_HELP)          And (Loop > 2)		; The text on the context sensitive help menu.
							Case (Active_Menu = MENU_HELP_ARCADE)   And (Loop > 3)		; The text on the arcade help menu.
							Case (Active_Menu = MENU_HELP_ADVANCED) And (Loop > 3)		; The text on the advanced help menu. 
							Case (Active_Menu = MENU_PLAYERSELECT)  And (Loop > 14)		; The player selection outlines on the player selection screen.
							Case (Active_Menu = MENU_LEVELSTART)    And (Loop > 0)		; Level numbers
							Case (Active_Menu = MENU_CREDITS)       And (Loop = 2)		; The credit scroll.	
							Case (Active_Menu = MENU_HIGHSCORES)	And (Loop > 1)		; The alternate background.
							Case (Active_Menu = MENU_OPTIONS)		And (Loop > 6)		; Checks for help and fulslcreen buttons.
							
							; This item is a button:
							Case True	

								; If a BOB exists for this menu item...
								If BOB_Menu(Active_Menu, Loop) <> Null

									; If the top left pixel of the mouse cursor is over this menu item...
									If BOB_RectOverlap(BOB_Menu(Active_Menu, Loop), Mouse_X, Mouse_Y, 1, 1)
						
										; If this menu item is not hidden...
										If BOBHidden(BOB_Menu(Active_Menu, Loop))
										
											Select True
							
												Case (Active_Menu = MENU_PLAYERSELECT) And (Loop > 4)
											
													; This is a player selection highlight. 
													; Do nothing.
										
												Default
									
													; Highlight menu item and play a sound.
				
														ShowBOB(BOB_Menu(Active_Menu, Loop))
														PlaySND(2)
																				
											End Select
								
										EndIf							
															
									Else
		
										; The mouse isn't over this menu item.  Hide the menu item's highlight.
						
											Select True
												
												; This is a button whose highlight image should never be hidden:
												Case (Active_Menu = MENU_GALLERY) And (Loop >= 5) 		; This is one of the thumbnails in the gallery.  Don't hide it.	
												Case (Active_Menu = MENU_GALLERYZOOM)					; This is a zoomed image in the gallery.  Don't hide it.
												Case (Active_Menu = MENU_PLAYERSELECT) And (Loop >= 5)	; This is a a player name selection box on the player selection screen.  Don't hide it.
										
												; This is a normal button:
												Default
												
													; Hide the highlight for this menu item.
														HideBOB(BOB_Menu(Active_Menu, Loop))
										
											End Select

									EndIf						
							
								EndIf
							
						End Select
									
					Next
		
				EndIf


			; If a menu item is selected, perform the appropriate action.
			Select Active_Menu

				Case MENU_MAIN         

					; ESC = Quit
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 6

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_MAIN_Play()
							Case 2 MENU_MAIN_Toggle()
							Case 3 MENU_MAIN_Options()
							Case 4 MENU_MAIN_HighScores()
							Case 5 MENU_MAIN_Help()
							Case 6 MENU_MAIN_Quit()
							Case 7 MENU_MAIN_Gallery()
							Case 8 MENU_MAIN_PlayerSelect()
											
						End Select							
										
				
				Case MENU_PLAYERSELECT 

					; ESC = Cancel
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 3
						
					; DEL = Delete
						If KeyHit(KEY_DELETE) 
							Selected_Menu_Item = 2
							MouseHit_Left = True		; Need to do this because function checks mouse state to avoid repeating.
						EndIf

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_PLAYERSELECT_NewPlayer()
							Case 2 MENU_PLAYERSELECT_Delete()
							Case 3 MENU_PLAYERSELECT_Cancel()
							Case 4 MENU_PLAYERSELECT_Okay()
							Case 5,6,7,8,9,10,11,12,13,14 MENU_PLAYERSELECT_PlayerHighlight(Selected_Menu_Item-5) 
																						
						End Select
			
				
				Case MENU_NAMEENTRY  

					; ESC = Cancel
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
						
					; ENTER = Ok
						If KeyHit(KEY_ENTER) Then Selected_Menu_Item = 2	

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_NAMEENTRY_Cancel()
							Case 2 MENU_NAMEENTRY_Okay()
								
						End Select

					; Record keystrokes.

						Key = GetKey()
					
						; Was a key hit?
						If Key <> 0 
						
							; Is the key in the allowed character set?
							If Instr(FONT_PlayerName\CharacterSet$, Chr$(Key)) 
							
								; Is the player name being edited shorter than the allowed maximum length?
								If Len(GLOBAL_NewName$) < 30
									
									; Add character to player name being edited.
										GLOBAL_NewName$ = GLOBAL_NewName$ + Chr$(Key)
									
									; Update name display.
										UpdateText(TEXT2D_PlayerNameEntry, GLOBAL_NewName$)
									
									; Play keyclick sound.
										PlaySND(4)
																		
								Else
								
									; Player is trying to enter too many characters into text field.
									; Play error beep.
									
								EndIf
									
							Else
							
								; Is this key a backspace?
								If (Key = 8)  
									 
									; Are there are characters in the player name being edited?
									If Len(GLOBAL_NewName$) > 0
									
										; Remove one character from the end of the player name.
											GLOBAL_NewName$ = Left$(GLOBAL_NewName$, Len(GLOBAL_NewName$)-1)

										; Update name display.
											UpdateText(TEXT2D_PlayerNameEntry, GLOBAL_NewName$)
										
										; Play keyclick sound.
											PlaySND(4)
											
									Else
									
										; No characters to delete.
										; Play error beep.
										
									EndIf
									
								EndIf
								
							EndIf		

						EndIf

			
				Case MENU_ARCADE       
					
					; ESC = Cancel
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
					
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_ARCADE_Cancel()
							Case 2 MENU_ARCADE_Continue()
							Case 3 MENU_ARCADE_NewGame()
						
						End Select							
					
				
				Case MENU_ADVANCED     

					; ESC = Cancel
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
					
					; If a menu item was selected, perform the action linked to it.

						Select Selected_Menu_Item
								
							Case 1 MENU_ADVANCED_Cancel()
							Case 2 MENU_ADVANCED_Continue()
							Case 3 MENU_ADVANCED_NewGame()
																				
						End Select							
		
				
				Case MENU_OPTIONS

					; Display and position the sliders. 
						ShowBOB(BOB_Menu(MENU_OPTIONS, 4))
						ShowBOB(BOB_Menu(MENU_OPTIONS, 5))
												
					; Show the radio button dot if fullscren mode is active.  
					;
					; Doing this causes the button to click repeatedly while the mouse is over it in windowed mode, presumably because it is being hidden
					; and the above code shows a hidden button and plays a click if the mouse is over it.
					
					;		HideBOB(BOB_Menu(Active_Menu, 6))
					;		If Not Windowed Then ShowBOB(BOB_Menu(Active_Menu, 6))


					; ESC = Main Menu
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 2

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_OPTIONS_Credits()
							Case 2 MENU_OPTIONS_MainMenu()
							Case 3 MENU_OPTIONS_ContextualHelp()
							Case 4 MENU_OPTIONS_SoundFXSlider()
							Case 5 MENU_OPTIONS_MusicSlider()
							Case 6 MENU_OPTIONS_Fullscreen()
																			
						End Select
									
				
				Case MENU_HIGHSCORES   
					
					; ESC = Main Menu
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
					
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_HIGHSCORES_MainMenu()
																			
						End Select							
					

				Case MENU_CREDITS     

					; ESC = Main Menu
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
								
							Case 1 MENU_CREDITS_MainMenu()
																												
						End Select							
				
				
				Case MENU_BUYNOW       

					; ESC = No Thanks.
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 2

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_BUYNOW_BuyNow()
							Case 2 MENU_BUYNOW_NoThanks()

						End Select							
	

				Case MENU_LEVELSTART

					; ESC, SPACE, ENTER. LEFT MOUSE BUTTON = Proceed
						If (KeyHit(KEY_SPACE) = True) Or (KeyHit(KEY_ESC) = True) Or (MouseHit_Left = True) Or (KeyHit(KEY_ENTER) =True) Then Selected_Menu_Item = 1

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_LEVELSTART_Proceed()
						
						End Select
						
							
				Case MENU_PAUSE

					; P = Resume
						If (KeyHit(KEY_P) = True) Then Selected_Menu_Item = 1
					
					; ESC = Main Menu
						If (KeyHit(KEY_ESC) = True) Then Selected_Menu_Item = 2
					
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_PAUSE_ResumeGame()
							Case 2 MENU_PAUSE_ExitToMainMenu()
						
						End Select
					

				Case MENU_LEVELEND     

					; ESC, SPACE, ENTER. LEFT MOUSE BUTTON = Proceed
					;	If (KeyHit(KEY_ESC) = True) Then Selected_Menu_Item = 2

					; ESC, SPACE, ENTER. LEFT MOUSE BUTTON = Proceed
						If (KeyHit(KEY_SPACE) = True) Or (KeyHit(KEY_ESC) = True) Or (MouseHit_Left = True) Or (KeyHit(KEY_ENTER) =True) Then Selected_Menu_Item = 1
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_LEVELEND_Proceed()
							Case 2 MENU_LEVELEND_MainMenu()
						
						End Select
						

				Case MENU_GAMEOVER    

					; ESC, SPACE, ENTER = Main Menu
						If (KeyHit(KEY_SPACE) = True) Or (KeyHit(KEY_ESC) = True) Or (KeyHit(KEY_ENTER) = True) Then Selected_Menu_Item = 2

					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_GAMEOVER_PlayAgain()
							Case 2 MENU_GAMEOVER_MainMenu()

						End Select
				
				
				Case MENU_GALLERY

					; ESC = Main Menu
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 3
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_GALLERY_LeftArrow()
							Case 2 MENU_GALLERY_RightArrow()
							Case 3 MENU_GALLERY_MainMenu()
							;Case 4 MENU_GALLERY_Print()
							Case 5,6,7,8,9 MENU_GALLERY_GalleryImage(Selected_Menu_Item-5)

						End Select
				

				Case MENU_GALLERYZOOM 
				
					; ESC = Image clicked
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
	
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_GALLERYZOOM_Image()
								
						End Select
							
				
				Case MENU_HELP
				
					; ESC = Okay clicked.
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 2
						
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
							
							Case 1 MENU_HELP_TurnOffHelpMessage()
							Case 2 MENU_HELP_Okay()
					
						End Select
					
					
				Case MENU_HELP_SELECT

					; ESC = Main Menu
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 3
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_HELP_SELECT_Arcade()
							Case 2 MENU_HELP_SELECT_Advanced()
							Case 3 MENU_HELP_SELECT_MainMenu()
							
						End Select
				
				
				Case MENU_HELP_ARCADE  

					; ESC = Done
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_HELP_ARCADE_Done()
							Case 2 MENU_HELP_ARCADE_LeftArrow()
							Case 3 MENU_HELP_ARCADE_RightArrow()
														
						End Select
				
				
				Case MENU_HELP_ADVANCED 

					; ESC = Done
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 1
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_HELP_ADVANCED_Done()
							Case 2 MENU_HELP_ADVANCED_LeftArrow()
							Case 3 MENU_HELP_ADVANCED_RightArrow()
														
						End Select
					
				
				Case MENU_CONFIRM_ENDGAME
				
					; ESC = Done
						If KeyHit(KEY_ESC) Then Selected_Menu_Item = 2
				
					; If a menu item was selected, perform the action linked to it.							
					
						Select Selected_Menu_Item
						
							Case 1 MENU_CONFIRM_ENDGAME_Cancel()
							Case 2 MENU_CONFIRM_ENDGAME_Okay()
					
						End Select
										
					
			End Select

			
			; If the selected menu item was a button, checkbox, or radio button, deselect it.
			; If it was a slider, allow it to remain selected.
			
			; This needs to be updated.  The buttons should be contained in types and contain the type of button they are so this can be managed easier.
			; But it's much too late to write a proper GUI system for the game at this point.
			
				Select True
			
					Case (Active_Menu = MENU_OPTIONS) And ((Selected_Menu_Item = 4) Or (Selected_Menu_Item = 5))
						; Do nothing.
					
					Default
						Selected_Menu_Item = 0
					
				End Select
			
			
			; Reset mouse state.
			; Failing to do this causes the advanced mode bot change to trigger when the level begins or a contextual help screen appears.
			; Because this only triggers when a menu is active, it won't affect the gameplay.
				MouseHit_Left  = False
				MouseHit_Right = False
				
		
		Case GLOBAL_State = GS_GAME_PLAYING
		
			; If player hit P or ESC, pause the game and the music.
				If (KeyHit(KEY_P) = True) Or (KeyHit(KEY_ESC) = True)
					ShowMenu(MENU_PAUSE)
					Pause_Music()
				EndIf					

			; Cheat keys:

				If Upper$(Savegame_Name$(GLOBAL_Editing_Savegame)) = "SHAWN SWIFT"

					; If player hit S, spawn a random robot.
						If KeyHit(KEY_S) Then SpawnRobot(Rand(0,3), Rand(0,3))
			
					; Go to next/previous level.
						If (KeyHit(KEY_PGUP) = True) And (Level > 1)  
				
							; End the level.
								End_Level()
					
							; Decrement the level by 2 so that when the menu goes to the "next level" it will be the previous level.			
								Level = Level - 2
					
						EndIf		
					
				 		If (KeyHit(KEY_PGDN) = True) And (Level < GLOBAL_Total_Levels+1) Then End_Level()
					
					; Skip to end.
						If KeyHit(KEY_END)
						
							End_Level()
							Level = 100
						
						EndIf
						
				EndIf
						
					
	End Select

	
	; Keys which work at any time during game:

		
		; Take a screenshot.		
			If KeyHit(KEY_F8) Then SaveScreenshot()


		; Switch between fullscreen and windowed mode.
	
			; If the F key was hit, and the game is not in player name entry mode, then switch to fullscreen mode.
			If (KeyHit(KEY_F) = True) And (((GLOBAL_State = GS_MENU_ACTIVE) And (Active_Menu = MENU_NAMEENTRY)) = False)
	
				If Windowed
					Switch_to_Fullscreen()
				Else
					Switch_to_Windowed()
				EndIf
	
			EndIf
			
			
Return


sswift, it won't delete all your stuff. A lot of people use the DeleteDir ".bmx",2 to clean out the pesky .bmx folder that's created with every compile. It's perfectly safe.

I have no idea why Chroma is deleting that folder, but it's nothing to worry about. Maybe he's short on hard drive space or something
I actually got that habit from Leadwerks and I like it quite a lot. He has even made a module called CleanUp or something like that for it.

And...I assure you I have way more space on my harddrive than you ever will. $$$ :)

And...I assure you I have way more space on my harddrive than you ever will. $$$ :)

Thank god. I was lying awake nights worrying that you had less harddrive space than I do.

Chroma:
So you have more than 1TB of space? Okay, but better upgrade soon, cause I'll have 2TB in short order. :-)

Excellent !
Everyone whip out your hard-drives, looks like we're about to compare sizes...

He has even made a module called CleanUp or something like that for it.

And I have shell scripts for the same ;-)

Do you deny that it is faster to write simple programs using global variables and arrays than to carefully design types which are far more powerful?

Yes.
There's nothing to say it will take longer to write something using Types than it will using globals and arrays - *if* you know what you're doing.

I put my hand up to using Global variables - but I use these as static variables in Types, for example, where there's "no other way" to do that - to keep an internal counter, for example.

Some folks might in fact believe that it's occasionally a good idea to sit down and think about what you are writing, as you put it "carefully design types", but I guess everyone else must just dive in and create monsters with lots of Globals and Arrays. Good for them :-)

And just for those that like examples :-)
Rem
bbdoc: Generates a new unique event type
End Rem
Function wxNewEventType:Int()
	Global eventTypeId:Int = wxEVT_USER_FIRST
	Local id:Int = eventTypeId
	eventTypeId:+ 1
	Return id
End Function

...the "global" variable isn't even accessible "globally", only inside the function, which makes it perfect for its intended use.

@sswift: dude, codebox

Brucey:

I don't even understand what your example is doing.

You have a function which returns an int.

You have a global variable in that function, accessable only to that function, which retains its value when the function exits.

But you set that global variable to the value of some other global variable the minute you enter the function, overwriting any value you saved.

Unless I don't understand how globals in functions work and an assignment like that, which would set a local variable every time you enter the function, is only used to set the global variable's initial state and is never executed again after that, so it does indeed retain the value from the previous run. I don't use globals in functions, because I have never found a situation where they're useful. I almost always find I need to be able to access any value I might store like that in other functions, so it must be a global in the type instead.

Anyway.. Let's say the global isn't overwritten every time in your example. So the first time you enter the function the event is set to wxEVT_USER_FIRST. And a local ID is set to whatever was in that global when you entered the function. You then increment the global variable by 1, and then exit returning the value which the global had when you entered the function...

So... All this does is return a number one higher than the last, every time it's called? So it'll go 0,1,2,3... etc?

And you needed this difficult to understand function to do this simple task... why?

I mean when you think about it, in your code, you're just gonna be saying "Okay, I need a new event type to assign to this variable."

Which you will then code like this:

ThisEvent = wxNewEventType()

Calling your complicated function.

But you could have just created a global NextEvent (in whatever type uses these events), and then written the code:

ThisEvent = NextEvent
NextEvent = NextEvent + 1

And it would have been clear to anyone what it does immediately, and would have required near zero thinking to implement.

That is not to say I would do that in a library I intended other people to use, because asking people to increment a global every time they get a value just isn't good design, but if it was my own program, and I was trying to do things the fast way, and the way that would be easiest for me to go back to later to understand what the hell I was doing... I might go for the global. :-)

Jhocking:
Thanks, I knew I'd seen those on the board but I didn't know how people were generating them. :-)

@sswift,

yeah, code-complexity on that scale is definitely not for the fainthearted :-)

It all adds up, mr smartypants! :-)