DirectX 2d Tilebased Demo 4
Author: James McCue
Author's e-mail: aloiterer@juno.com
Author's homepage: Jim the loiterer's PC games, programming, & stuff
Contents:
This one is cool
This demo/source has alot of routines in it, many I've whipped up myself. Of course, the one's that will probably get most of your attention are the Andre' Lamothe DirectSound™ ones.
I got as far as initializing the directsound object, and freeing it myself, (which was cake and a half) but I couldn't figure out how to use the routines in DSUTIL.C (included in your directx\sdk\samples\misc folder) to load sounds. So, as usual, it was Andre' to the rescue.
Searching the web, it seemed no one had gotten further than I had, (including some sites that are ADVERTISING that they have DirectSound code!) and when I wasn't finding anything, and banging my head against the wall trying to use DSUTIL.C to load wavs for me, Snacks decided to show me a little dsound code.
Alot of people have helped me get this far. I mean... of course Gio, Dhonn, and everybody else I've been mentioning in this series on 2d directx 16-bit tile demos.
This time around, I owe alot to Mr. Knudson's linked list tutorials. I've studied advanced data structures in the past, but honestly hadn't used linked lists in C. (though I often use pointers in other ways) Mr. Knutson's stuff really saved my butt as far as missile spawning/processing goes.
Get ready to blow some stuff up!
OH - and if you'd prefer to check out a 256 color version of this tile demo, just goto my site, the 256 color demo should perform better for those of you out there with 1 meg video cards.
Shooting the bad guys
The missiles in this demo are only pixels. I figured it would be safer to do that because then I'd have less harsh criticism of my graphics.
At one point I saw using arrays of structures for missile positions, but although that could work, I wanted a better solution, so I used linked lists for the missiles.
I've noticed showing the code on these pages makes them HUGE, so I'll just tell you to examine:
- Spawn_Missile
- Delete_Missile
- Process_Missile_Motion
- Process_Missile_Collisions (NOTE: Should be in PMM)
- Draw_Missiles
Here's the missile structures: (from gamedefs.h)
typedef struct missile
{
float mid_x;
float mid_y;
float angle;
float magnitude_per_sec;
float time_away;
WORD color;
struct missile *next;
} missile;
typedef struct _linkedlist
{
missile *first;
int curr_num_missiles;
} missile_list;
Using linked lists was really convenient for spawning missiles, though I traverse the linked list a lot more than I need to, the processing of missile collisions with enemy ships and the motion in general should be processed in one routine, some of you might want to combine Process_Missile_Motion, Process_Missile_Collisions, AND Draw_Missiles into one routine. It's up to you...
Newer ship structure
Good structures always take some planning, and since I made these up as I went along, I wouldn't suggest for a second that they're the best solution:
typedef struct vertex_typ
{
float x,y;
} vertex, *vertex_ptr;
typedef struct poly_typ
{
float x,y;
int scrn_x, scrn_y;
int hit_points;
int game_state;
int draw_state;
int counter;
int threshold;
float magnitude_per_sec;
vertex vertices_local_original[4];
vertex vertices_local_rotated[4];
WORD *SpriteRGB16[MAX_FRAMES];
} polygon, *polygon_ptr;
I had an idea for using graphics POOLS, so I wouldn't have to allot X amount of memory for EACH ship that I use.
Let's say I have 3 enemy ships - Identical ships - and that I have only 3 frames for each. Using a pointer like I do, I don't need to hold the contents from 9 bitmaps in memory, I can just use 3.
game_state and draw_state are there because, if a ship is running away from me, I figure "why should it look different?".
DirectSound
I leave it to Andre' to teach you how he does what he does in his DirectSound code, andresDS.cpp in this project. (I only added includes to give it my program's main_window_handle) I couldn't do DSound without him, so go get his Windows Game Programming (for dummies) from IDG Books today!
I WILL, however, talk about how one dope named Jim uses his code in a demo! So here we go...
Unlike what most of you will do, I load VOC files instead of WAVs. As each is loaded, it is given a sound_ID:
Load_VOC("plyrshot.voc"); // this will have snd_id 0
Set_Sound_Freq(0,8000);
Set_Sound_Volume(0,80);
Load_VOC("pickup.voc"); // this will have snd_id 1
Set_Sound_Freq(1,11020);
Set_Sound_Volume(1,80);
Load_VOC("boom.voc"); // this will have snd_id 2
Set_Sound_Freq(2,8000);
Set_Sound_Volume(2,80);
Notice I've set the sound frequencies here, normally you'll want to set them to the frequency of the sound sample you loaded.
I wanted to add a dialog to this project that let you control sound without going to the Win95 sound control, but I'm still learning, so you're stuck with that for now.
You'll need to call DSound_Init() to initialize the dsound object, and DSound_Shutdown() to free all the sound buffers, and the dsound object itself, but that's pretty straightforward - like with directdraw.
Loading the sounds, and setting the volume/frequency where the parts I couldn't find any success with doing myself. God Bless Andre'.
Here's me playing a sound:
Stop_Sound(PLAYER_SHOT);
Play_Sound(PLAYER_SHOT);
Although sounds will mix for you using directsound, you'll have to duplicate buffers to play a sound and mix it with a previously started version of the SAME sound. I don't do any of that in this demo program.
A note about the project
Typically we should split our projects into multiple files. This makes reading the code easier, and makes for short build times.
However, you all know me, and I've taken many a good idea and messed it up ; )
Since the .H file that contains my main window's handle is the same file that holds my #defines, and other project global variables & structures, VC4 tries to rebuild andresDS.cpp when I make changes to it.
In other words, feel free to reconstitute this project's files, for better build times, or even better performance.
Just don't cop my graphics ok?
Anyhow, this is a short web "tutorial" for once, you can always contact me with questions or comments.
Building the source code
You'll need the directX 5 SDK to build this project.
Download the zip, I recommend using WinZip to unzip it... unzip it someplace...
Open your VC++ 4, goto File->New, (select a new workspace) make a new workspace in the directory with the unzipped files...
Goto ADD->Files into project, and add these files:
tiled4.cpp
world.cpp (the world data)
polydraw.cpp
andresDS.cpp (an Andre' Lamothe directsound module)
ddutil.cpp
myddraw.cpp
tiled4.rc (I'm a little iffy about whether you have to make your own dialog resource for this project)
ddraw.lib (from your directX sdk\lib folder)
dsound.lib (from your directX sdk\lib folder)
winmm.lib (from your MSDEVSTD\LIB folder)
Save ALL, and the BUILD
Have fun!
Oh, by the way:
DISCLAIMER: This source code and demo program is provided as is, without warranty of any kind. James McCue is not responsible for any damages that may arise due to the use, or abuse of this code.
Demo, Source, and article Copyright 1998 - by James McCue