Author : Filipe Medeiros
Page : << Previous 11 Next >>
the `dx' and `dy' from the mouse code onto the range [-128,128] that we are using here, we need to divide by `max_mousespeed' and multiply by 128, where `max_mousespeed' is a variable controlling the sensitivity of the mouse. We will do this the other way around, though, because then we can leave it as an integer calculation. Where possible, you should avoid casting between floating point types and integer types -- it's slow to convert between them.
The complete code for what we have discussed so far is in function `input_getinput'.
Before we can use that, though, we need a way of telling this input module what sort of input we're looking for. This will be by a call to `input_create_*', which may take some parameters (depending on what `*' actually is), make an input structure, and return a pointer to it. The joystick input routine doesn't need any extra information, but the mouse input routine needs to know what value to use for `max_mousespeed', and the keyboard input routine needs to know which keys to use. We could have used a single function with a variable number of parameters, but that's a bit complicated for this tutorial.
So we define these functions:
input_t *input_create_joystick ();
input_t *input_create_mouse (int max_mousespeed);
input_t *input_create_keybd (int left_key, int right_key, int up_key, int down_key, int fire1_key, int fire2_key);
We also need a function to initialise the input module, a shutdown function for it, and a function to destroy previously-registered input devices (e.g. if you change the keys); we'll prototype these:
void input_init (); void input_shutdown (); void input_destroy (input_t *what);
In summary, programs will call `input_init' initially, to set up the module. They will then call some of the `input_create_*' functions to register input devices for the players; the `input_create_keybd' may be called more than once, with different keys, to allow for more than one player on the keyboard. The `input_create_*' functions return pointers to `input_t' structs, whose fields will be updated on each call to `input_getinput'. Registered devices can be unregistered using `input_destroy' by passing the `struct input_t' pointer; this will also deallocate the structure pointed to. The `input_shutdown' function will unregister all devices and deallocate any memory still allocated.
The input_t struct contains fields `dx', `dy', `fire1' and `fire2'. `dx' and `dy' range from -128 to 128, indicating the amount of movement in each direction, and `fire1' and `fire2' are non-zero if the corresponding fire button is pressed.
Once again, see the program in `src/6.5' for an example of how to use this system.
6.5 Ways of interpretting input
This section isn't written yet. When it is written, it will contain information about physical models (no, it's not as boring as it sounds!) and how you can use the input data.
This section isn't written yet. When it is, it will talk about:
* memory bitmaps
* sprites
* moving things without disturbing the background
* double buffering and dirty rectangles again, and introducing page flipping
8.1 Sound configuration
8.1.1 Initialising sound drivers
To install the sound drivers, you call the function:
install_sound (digi_driver, midi_driver, NULL);
putting a `DIGI_*' constant in place of `digi_driver' and a `MIDI_*' constant in place of `midi_driver'. The third parameter is obselete and you should just pass NULL.
The function returns zero if it was successful. A non-zero return probably means that the driver you requested is not available. If you used a `*_AUTODETECT' setting for either driver, this may mean that a config file specified a precise driver to use, and that driver was unusable.
I think there's rarely any good reason not to use `DIGI_AUTODETECT' and `MIDI_AUTODETECT'. My reasoning here is that if you specify a device explicitly the game won't work if that device is not available, and won't be able to make use of a better device if one is available. Even if you have some hardware conflict which makes these options fail normally, that's no reason to stop your game working properly on other people's machines -- you should create a configuration file (see below). Config files always override the autodetection routines, so the conflict should disappear -- you're relying on this to be true so that the end-users can fix such problems if they occur. If you hardcode values here people won't be able to override the settings without rebuilding -- bad news!
So unless there's a very good reason (I can't think of any) just use the `*_AUTODETECT' constants here. Even the `play.exe' example program in Allegro's tests directory is borderline in my mind -- it uses a hardcoded table of driver numbers and names. That's pretty bad; the justification (I think) is that its purpose is to test drivers quickly. Not much justification really...
One further thing to note is that the MIDI player uses Allegro's timer routines to operate, so you must initialise those before you'll be able to play MIDI files. See Subsec 9.2.1: Initialising the timer system, for more details.
8.1.2 Using a configuration file
Allegro supports a wide range of features in config files; sound configuration is just part of the standard data, and you can add data of your own for your game's internal use. For full details on using config files, see Allegro's help system (type `info allegro config' at a DOS prompt, if you use Info). Here I'll only mention what applies to the sound drivers.
Unless you say otherwise, the files `allegro.cfg' and `sound.cfg' will be checked for in the program's home directory. To specify a different filename, pass it to the `set_config_file' function.
The sound configuration information is in the `[sound]' section of the file, and holds information about which drivers to use if you ask for autodetection and the settings for those drivers, among other things. The way the autodetection works in Allegro is such that if you specify a driver explicitly in the config file then that driver will be used. If you don't specify one then Allegro will start poking around trying to see what's there; this *may* have adverse effects, and in addition some things (like an external MIDI device) are never autodetected for technical reasons.
The safest and easiest way to write config files is through the setup utility. This is designed to be packageable with your games, and lets the user choose some settings (or autodetect them) and try them out. It then saves the settings to a config file ready for your program to read.
The simplest way to distribute this, then, is to put the `setup.exe' file in the same directory as your program's executable, so that the output from the setup program is right where your program expects to see it. There are many things about the setup program that you can customise; or you can just leave it alone. See `setup.txt' for full information (it's in the same directory as the rest of the setup program).
828.2 Digital sound
8218.2.1 Loading sound files
Allegro can read digital samples from WAV and VOC files. Both types of file must be mono. WAV files can be 8 or 16 bit; VOC files must be 8 bit.
Loading a sample couldn't be easier -- you pass the filename of the WAV or VOC file (it must have the right extension) to the `load_sample' function, and it returns a `SAMPLE *' which you can use to refer to the sample, or NULL if it could not load the sample (e.g. it didn't recognise the extension, the file was not found, or the format of the file was incorrect or not supported).
You can also call `load_voc' or `load_wav' directly, in the same way. The benefit of doing this is that if the file does not have a .WAV or .VOC extension it will still be processed.
8.2.2 Playing samples
Allegro's digital sound player can manipulate samples in several ways whilst playing them. The parameters you can set at the basic level are the volume, pan and frequency. You can also tell the sound player whether or not to loop back to the beginning of the sample when it reaches the end.
To start a sample playing, call the play_sample function. You pass the following parameters:
* the sample to play (a `SAMPLE *')
* the volume of the sample, from 0 (min) to 255 (max)
* the pan position of the sample, from 0 (left) to 255 (right)
* the frequency of the sample relative to its original frequency -- 1000 would play it at the original frequency, 2000 would double that frequency (raise the pitch by one octave, musically speaking) and 500 would halve the frequency (lower the pitch by one octave)
* a loop flag; 1 = loop, 0 = don't loop
Note that offsetting a sample's frequency can introduce distortion of the sample -- Allegro is a game programming library, not a sophisticated audio suite. Also, playing sounds at generally
Page : << Previous 11 Next >>