An elegant way of doing this simple thing?

Blitz3D Forums/Blitz3D Beginners Area/An elegant way of doing this simple thing?

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Right, I've just begun project #1 which I'm aiming to be similar Spheres of Chaos (see http://www.spheresofchaos.com/ and download the demo and then buy the full game!).

Rather than just trying to get the thing done and finished I'm using it as an excercise in re-learning good programming practice (I haven't 'done code' since the Amiga's hey-day).

Anyhoo, I'm looking for comments on the following code, of which [EDIT 3rd Oct: removed dead link, see later post in the thread] has a runnable version (i.e, has keyboard.bb and the wav files).

All it does at the moment is load in 4 wavs and plays them when you bash the numbers 1-4 on the keyboard.

Not exactly impressive, I know. What took me the time (half of the day) was figuring the best way of doing things. I'm especially interested in peoples views on how the wavs get loaded.

Main program:
; Spheres.

; Version 0.02 25th Sep 2005.

; copyright (c) 2005 Stefan Holmes a.k.a VinylPusher.

; This project started just after a new install of Blitz3D on 24th Sep 2005. This project, unlike most
; other first-projects, is intended to provide functions reusable in all future projects.

AppTitle "Spheres"

Const DEBUG=False

Const SCREEN_WIDTH	= 800 , SCREEN_HALFWIDTH	= SCREEN_WIDTH / 2	; Used when calculating sound
																	; panning.
Const SCREEN_HEIGHT	= 600 , SCREEN_HALFHEIGHT	= SCREEN_HEIGHT / 2	; Haven't decided a use yet!
Const SCREEN_BPP	= 32	; I'm not aiming for this to run on an S3 Virge.

Graphics SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,2
SetBuffer BackBuffer()

Include "include\keyboard.bb"	; This loads a bunch of Consts all starting KEY_
								; My brain cannot remember scancodes and I cannot be bothered looking
								; through the help files.

Include "include\sfx.bb"		; Do have a read of this file if you want to see how a reusable sound
								; effect loading routine works.

bootstrap()	; Let's load in all the resources we need.
			; Only a small game so everything can easily go into RAM on startup.


While Not KeyDown(KEY_ESC)
	
	If KeyHit(KEY_1) Then PlaySound sfx_array(SFX_BIGEXP)\sound
	If KeyHit(KEY_2) Then PlaySound sfx_array(SFX_LASER)\sound
	If KeyHit(KEY_3) Then PlaySound sfx_array(SFX_SHOOT)\sound
	If KeyHit(KEY_4) Then PlaySound sfx_array(SFX_ZAPPER)\sound

	WaitKey
Wend

Function bootstrap()
	returned$=""
	returned$=sfx_acquire$("sfx-44.1k-16b")	; Here I'm just selecting the folder to load samples from.
											; Perhaps future Blitz versions will support 96Khz 24bit.
	If returned$<>""
		If DEBUG
			Print "DEBUG INFO"
			Print "Error loading samples: " + Left$(returned$,Len(returned$)-1) + "."
			Print
			If Len(returned$)=1
				Print "Either the file was missing, misnamed or it got loaded out-of-order."
			Else
				Print "Either the files were missing, misnamed or were loaded out-of-order."
			End If
			Print
			Print "** Press any key to continue **"
			WaitKey
		Else
			Print "There was an error loading sound(s)."
			Print "We will continue in a moment, but things may be a little quiet..."
			For i=0 To 499 : VWait : Next 
		End If
	EndIf
	gfx_acquire()
End Function

Function gfx_acquire()
End Function


included sfx.bb
;-----------------------------------------------------------------------------------------------------
; One of the first things I didn't like about BB was that the most popular way of implementing sound
; effect code was to use a proliferation of individual Global variables. Messy.
;
; I had a think, and in the back of my mind I had the idea that the next best thing to Globals were
; Const's.
;
; Having poked around a lot I found there are no totally elegant ways to do this, but here's my
; attempt at making the whole thing as modular as possible.
;
; This implementation generates only one Global (sfx_array). The identifiers for individual sounds are
; Const's (which are, IMHO, better). These can be eliminated and you can just use the numerical index
; to identify each sound. Thing is though, this isn't DarkBasic ;-)
;
; The whole point is to make the main code as human-readable as possible.
;-----------------------------------------------------------------------------------------------------

Type	sfx
Field	sound		; This is to hold the value returned by LoadSound().
Field	volume#
Field	panning#
Field	filename$
End Type


; ****************************************************************************************************
; **                                                                                                **
; **  This section is the config area, everything else is to be left well alone.                    **
; **                                                                                                **
; ****************************************************************************************************

Const SFX_COUNT		= 4-1:Dim sfx_array.sfx(SFX_COUNT)

; Use SFX_<anything> (except SFX_COUNT, duh!) to keep things consistent.
Const SFX_BIGEXP	= 0
Const SFX_LASER		= 1
Const SFX_SHOOT		= 2
Const SFX_ZAPPER	= 3

Function sfx_acquire$(folder$)
	error$=""
	i=0
	
	; I can't think of a neater way to do this. Can't go in a loop. Suggestions welcome.
	
	sfx_array(SFX_BIGEXP)\sound	= LoadSound(folder$ + "" + sfx_array(SFX_BIGEXP)\filename$)
	error$ = error$ + sfx_errorCheck$(i) : i=i+1

	sfx_array(SFX_LASER)\sound	= LoadSound(folder$ + "" + sfx_array(SFX_LASER)\filename$)
	error$ = error$ + sfx_errorCheck$(i) : i=i+1

	sfx_array(SFX_SHOOT)\sound	= LoadSound(folder$ + "" + sfx_array(SFX_SHOOT)\filename$)
	error$ = error$ + sfx_errorCheck$(i) : i=i+1

	sfx_array(SFX_ZAPPER)\sound	= LoadSound(folder$ + "" + sfx_array(SFX_ZAPPER)\filename$)
	error$ = error$ + sfx_errorCheck$(i) : i=i+1
	
	Return error$
	

End Function

.sfx_filenames
; Data <filename$,volume#,panning#>. sfx_acquire() prepends "" to the filenames.
; These latter 2 values could have been initialised later, but it makes sense to initiliase things in
; one place and not split the code between different source files.
Data "bigexp.wav",1,0
Data "laser.wav",1,0
Data "shoot.wav",1,0
Data "zapper.wav",1,0

; ****************************************************************************************************
; **                                                                                                **
; **  End of the configuration section. Shouldn't need to change anything outside of here.          **
; **                                                                                                **
; ****************************************************************************************************


Restore sfx_filenames
For i = 0 To SFX_COUNT
	sfx_array(i) = New sfx
	Read sfx_array(i)\filename$
	Read sfx_array(i)\volume#
	Read sfx_array(i)\panning#
Next

Function sfx_errorCheck$(j)
	err$=""
	If Not sfx_array(j)\sound Then err$ = sfx_array(j)\filename$+","
	
	Return err$
End Function