/****************************************************************
GALVADERS (V1.0), BY AHARON HILLEL.
gcc version 3.2 (mingw special 20020817-1)
ALLEGRO VERSION: 4.1.12 (WIP)
ALLEGRO DATE: 2003-11-10
****************************************************************/
#include <string.h>
#include "menu.h"
#include "inv.h"
#include "galaxy.h"
#define DATA_FILE_NAME "galvaders.dat"
#define SAMPLES_FILE_NAME "samples.dat"
#define ENEMIES_SPRITE_WIDTH 32
#define TOTAL_NUMBER_OF_SPRITES 155
/****** START **** GAME GLOBALS ****/
DATAFILE *s_data;
st_game_params *game_sprites;
class player *player_1;
class player *player_2;
class inv_formation *invaders;
class gal_formation *galaxians;
sprite_list p_bullets_list;
sprite_list e_bullets_list;
sprite_list explosions_list;
attack_list gal_attack_list;
unsigned int sound_flag;
class menu *current_menu = NULL;
#define GAME_FRAME_RATE 20
volatile int time_for_frame;
void set_time_for_frame()
{
time_for_frame = G_TRUE;
};
/****** END **** GAME GLOBALS ****/
void init_classes_static_data(unsigned char game_type)
{
player::bullet_params.x_inc = 0;
player::bullet_params.y_inc = -10;
player::bullet_params.x_min = 0;
player::bullet_params.x_max = SCREEN_W;
player::bullet_params.y_max = SCREEN_H;
player::bullet_params.y_min = 0;
if(!(game_type & BIT_GALAXIANS)) // Space Invaders game.
player::bullet_params.y_min = GAME_HEADER_BORDER_LINE+1;
if(game_type & BIT_INVADERS)
{ // Use Invaders bullets and ship.
player::bullet_params.hit_pixels = player::inv_bullet_hit_pixles;
player::bullet_params.n_hit_pixels = 6;
}
else
{ // Use galaxians bullets and ship.
player::bullet_params.hit_pixels = player::gal_bullet_hit_pixles;
player::bullet_params.n_hit_pixels = 5;
}
player::bullet_params.colors = player::bullet_hit_colors;
player::bullet_params.hit_z_order_low = INVADERS_Z_ORDER;
player::bullet_params.hit_z_order_high = GALAXY_Z_ORDER;
formation::set_attack_ok();
inv_formation::bullet_params.x_inc = 0;
inv_formation::bullet_params.y_inc = 3;
inv_formation::bullet_params.x_min = 0;
inv_formation::bullet_params.x_max = SCREEN_W;
inv_formation::bullet_params.y_min = 0;
inv_formation::bullet_params.y_max = GAME_FOOTER_BORDER_LINE-((*game_sprites->images)[(*game_sprites).inv_missile]->h);
inv_formation::bullet_params.hit_pixels = inv_formation::bullet_test_pixles;
inv_formation::bullet_params.n_hit_pixels = 6;
inv_formation::bullet_params.colors = inv_formation::bullet_test_colors;
inv_formation::bullet_params.hit_z_order_low = PLAYER_Z_ORDER;
inv_formation::bullet_params.hit_z_order_high = PLAYER_Z_ORDER;
gal_formation::bullet_params.x_inc = 0;
gal_formation::bullet_params.y_inc = 5;
gal_formation::bullet_params.x_min = 0;
gal_formation::bullet_params.x_max = SCREEN_W;
gal_formation::bullet_params.y_min = 0;
gal_formation::bullet_params.y_max = SCREEN_H;
gal_formation::bullet_params.hit_pixels = gal_formation::bullet_test_pixles;
gal_formation::bullet_params.n_hit_pixels = 6;
gal_formation::bullet_params.colors = gal_formation::bullet_test_colors;
gal_formation::bullet_params.hit_z_order_low = PLAYER_Z_ORDER;
gal_formation::bullet_params.hit_z_order_high = PLAYER_Z_ORDER;
gal_attack::set_lowest_y_shooting_point(2*(SCREEN_H / 3));
if(game_type & BIT_INVADERS)
gal_attack::set_player_half_width((*game_sprites->images)[game_sprites->inv_players]->w >> 1);
else
gal_attack::set_player_half_width((*game_sprites->images)[game_sprites->gal_players]->w >> 1);
}
END_OF_FUNCTION(init_classes_static_data);
int get_sprites_from_bmp(DATAFILE *data, images_array *img, int index, int w, int h, int count)
{ /* Adds count number of (RLE_SPRITE * wXh size) to vector from BITMAP. */
int i;
BITMAP *temp;
RLE_SPRITE *p;
temp = create_bitmap(w, h);
if(!temp)
return G_FALSE;
for(i = 0; i < count ; i++)
{
blit((BITMAP *) data[index].dat, temp, i*w, 0, 0, 0, w, h);
/* blit(temp, screen, 0, 0, i*w, 0, w, h); Remove after DEBUG */
p = get_rle_sprite(temp);
if(!p)
{
destroy_bitmap(temp);
return G_FALSE;
}
img->push_back(p);
}
destroy_bitmap(temp);
return G_TRUE;
}
END_OF_FUNCTION(get_sprites_from_bmp);
void free_game_params()
{
if(game_sprites->dir)
free(game_sprites->dir);
if(game_sprites->game_logo)
destroy_bitmap(game_sprites->game_logo);
for(int i = 0; i < game_sprites->images->size() ; i++)
if((*game_sprites->images)[i])
destroy_rle_sprite((*game_sprites->images)[i]);
game_sprites->images->clear();
delete(game_sprites->images);
delete(game_sprites);
}
END_OF_FUNCTION(free_game_params);
#define ADD_SPRITE_TO_VECTOR(SPRITE,INDEX) \
INDEX = p->images->size(); \
s = get_rle_sprite((BITMAP *) data[SPRITE].dat); \
if(s) p->images->push_back(s);
#define ADD_SPRITES_TO_VECTOR(SPRITES,INDEX, COUNT) \
INDEX = p->images->size(); \
temp = (BITMAP *) data[SPRITES].dat; \
get_sprites_from_bmp(data, p->images, SPRITES, temp->w / COUNT, temp->h, COUNT);
st_game_params *create_game_params(DATAFILE *data, char *game_dir)
{ // Returns pointer to game-parameter-struct. NULL on ERROR
int status;
BITMAP *temp;
RLE_SPRITE *s;
st_game_params *p = new st_game_params;
if(!p)
return NULL;
memset(p, 0, sizeof(st_game_params)); // Clear all.
/* Copy the game pallete */
memcpy(p->game_pal, (RGB *) data[GAME_P].dat, sizeof(RGB)*256);
p->images = new (images_array); // Create the (RLE_SPRITE *) vector.
ADD_SPRITES_TO_VECTOR(ENEMIES, p->enemies, ((((BITMAP *) data[ENEMIES].dat)->w) / ENEMIES_SPRITE_WIDTH));
ADD_SPRITE_TO_VECTOR(ALLEGRO_LOGO, p->allegro_logo);
ADD_SPRITE_TO_VECTOR(G_BLAST1, p->g_blast);
ADD_SPRITE_TO_VECTOR(G_BLAST2, status);
ADD_SPRITE_TO_VECTOR(G_BLAST3, status);
ADD_SPRITES_TO_VECTOR(GAL_PLAYER_BLAST, p->gal_player_blast, 3);
ADD_SPRITE_TO_VECTOR(GAL_BULLET, p->gal_bullet);
ADD_SPRITES_TO_VECTOR(GAL_PLAYERS, p->gal_players, 2);
ADD_SPRITES_TO_VECTOR(GAL_PLAYERS_HT, p->halftone_gal_players, 2);
ADD_SPRITES_TO_VECTOR(GAL_PLAYERS_SMALL, p->gal_players_small, 2);
ADD_SPRITES_TO_VECTOR(I_BLAST, p->i_blast, 3);
ADD_SPRITE_TO_VECTOR(INV_MISSILE, p->inv_missile);
ADD_SPRITES_TO_VECTOR(INV_PLAYERS, p->inv_players, 2);
ADD_SPRITES_TO_VECTOR(INV_PLAYERS_HT, p->halftone_inv_players, 2);
ADD_SPRITES_TO_VECTOR(INV_PLAYER_BLAST, p->inv_player_blast, 3);
ADD_SPRITES_TO_VECTOR(INV_PLAYERS_SMALL, p->inv_players_small, 2);
ADD_SPRITES_TO_VECTOR(INV_MOTHER_SHIP, p->inv_mother_ship,4);
ADD_SPRITES_TO_VECTOR(INV_MOTHER_SHIP_EXP, p->inv_mother_ship_explosion,3);
ADD_SPRITES_TO_VECTOR(INV_MOTHER_SHIP_150, p->inv_mother_ship_150,3);
ADD_SPRITES_TO_VECTOR(INV_MOTHER_SHIP_300, p->inv_mother_ship_300,3);
ADD_SPRITES_TO_VECTOR(INV_PLAYER_BULLET, p->inv_player_bullet,2);
ADD_SPRITES_TO_VECTOR(GAL_PLAYER_BULLET, p->gal_player_bullet,2);
ADD_SPRITE_TO_VECTOR(INV_MISSILE_EXP, p->inv_missile_explosion);
ADD_SPRITE_TO_VECTOR(SHIELD, p->shield);
ADD_SPRITES_TO_VECTOR(AHARON_LOGO, p->aharon_logo,3);
ADD_SPRITES_TO_VECTOR(GAL_BONUS_200, p->gal_bonus_200,4);
ADD_SPRITES_TO_VECTOR(GAL_BONUS_400, p->gal_bonus_400,4);
ADD_SPRITES_TO_VECTOR(GAL_BONUS_800, p->gal_bonus_800,4);
p->game_logo = create_bitmap(((BITMAP *) data[GAME_LOGO].dat)->w, ((BITMAP *) data[GAME_LOGO].dat)->h);
if(p->game_logo)
blit((BITMAP *) data[GAME_LOGO].dat, p->game_logo, 0, 0, 0, 0, p->game_logo->w, p->game_logo->h);
p->dir = NULL;
if(game_dir)
{
p->dir = (char *) malloc(sizeof(char) * (strlen(game_dir)+1));
strcpy(p->dir, game_dir);
}
/* allegro_message("Number of Sprites: <%d>", p->images->size()); */
return p; // Return game parameters
}
END_OF_FUNCTION(create_game_params);
void do_game_cleanup(BITMAP *buffer, char *workingdir)
{
if(game_sprites)
free_game_params();
if(buffer)
destroy_bitmap(buffer);
if(workingdir)
free(workingdir);
if(s_data)
unload_datafile(s_data);
}
END_OF_FUNCTION(do_game_cleanup);
DATAFILE *open_data_file(char *dir, char *name)
{
int len = strlen(dir) + strlen(name)+1;
DATAFILE *data = NULL;
char *data_file = (char *) malloc(len);
if(!data_file)
{
allegro_message("Failed to allocate memory (%d - bytes)", len);
return NULL;
}
sprintf(data_file, "%s%s", dir, name);
data = load_datafile(data_file);
if(!data)
{
allegro_message("Failed to load datafile <%s>\n", data_file);
return NULL;
}
free(data_file);
return data;
};
END_OF_FUNCTION(open_data_file);
void set_menu_after_get_window_focus(void)
{
if(current_menu)
current_menu->set_pause_after_get_focus();
}
END_OF_FUNCTION(set_menu_after_get_window_focus)
int main(int argc, char *argv[])
{
int status;
char *workingdir = NULL;
BITMAP *buffer = NULL;
DATAFILE *data;
allegro_init();
/* START - Init globals */
game_sprites = NULL;
s_data = NULL;
player_1 = player_2 = NULL;
invaders = NULL;
galaxians = NULL;
/* END - Init globals */
workingdir = (char *) malloc(strlen(argv[0])+1);
if(!workingdir)
{
allegro_message("Failed to allocate memory (%d - bytes)", strlen(argv[0]));
exit(1);
}
strcpy(workingdir, argv[0]);
status = strlen(workingdir)-1;
while((status) && (workingdir[status] != '\\'))
{
workingdir[status] = '\0';
status--;
}
data = open_data_file(workingdir, DATA_FILE_NAME);
if(!data)
{
do_game_cleanup(buffer, workingdir);
exit(3);
}
set_color_depth(8);
/***** Do not use fullscreen */
if (set_gfx_mode(GFX_DIRECTX_ACCEL, 640, 480, 0, 0) != 0)
if (set_gfx_mode(GFX_DIRECTX_SOFT, 640, 480, 0, 0) != 0)
if (set_gfx_mode(GFX_DIRECTX_SAFE, 640, 480, 0, 0) != 0)
status = set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
/*****/
/* Temporarly use windowed mode for tests
status = set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
*****/
if(status < 0)
{
allegro_message("Failed to start gfx-mode <%d>\n", status);
exit(4);
}
buffer = create_bitmap(640, 480);
if(!buffer)
{
allegro_message("Failed to create buffer (BITMAP).");
do_game_cleanup(buffer, workingdir);
exit(5);
}
game_sprites = create_game_params(data, workingdir);
if(!game_sprites)
{
allegro_message("Failed to create game sprits.");
do_game_cleanup(buffer, workingdir);
exit(6);
}
unload_datafile(data);
if(game_sprites->images->size() < TOTAL_NUMBER_OF_SPRITES)
{
allegro_message("Failed to create sprites.\nCreated <%d> sprites instead of <%d> sprites.", game_sprites->images->size(), TOTAL_NUMBER_OF_SPRITES);
do_game_cleanup(buffer, workingdir);
exit(7);
}
/* Load samples */
s_data = open_data_file(workingdir, SAMPLES_FILE_NAME);
if(!s_data)
{
do_game_cleanup(buffer, workingdir);
exit(3);
}
set_palette((RGB *) s_data[GAME_P].dat);
install_keyboard();
/* START - Sound init */
unsigned int max_digi_sounds;
unsigned int max_midi_sounds;
unsigned int sound_ok_max;
max_digi_sounds = detect_digi_driver(DIGI_AUTODETECT);
max_midi_sounds = detect_midi_driver(MIDI_AUTODETECT);
if(max_digi_sounds > 16)
max_digi_sounds = 16;
if(max_midi_sounds > 2)
max_midi_sounds = 2;
reserve_voices(max_digi_sounds, max_midi_sounds);
sound_ok_max = install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);
set_volume(255,255);
if(!sound_ok_max)
sound_ok_max = SOUND_GALVADERS;
else
sound_ok_max = 0;
/* END - Sound init */
set_display_switch_mode(SWITCH_PAUSE);
set_display_switch_callback(SWITCH_IN, &set_menu_after_get_window_focus);
/************** START ***************/
time_for_frame = G_FALSE;
vsync();
install_int(&set_time_for_frame, GAME_FRAME_RATE);
LOCK_VARIABLE(time_for_frame);
LOCK_FUNCTION(set_time_for_frame);
LOCK_VARIABLE(current_menu);
LOCK_FUNCTION(set_menu_after_get_window_focus);
class menu game_menu(buffer, sound_ok_max);
current_menu = &game_menu;
game_menu.do_menu();
/* status = play_the_game(buffer, 1); */
/************** END ***************/
remove_display_switch_callback(&set_menu_after_get_window_focus);
remove_timer();
remove_keyboard();
do_game_cleanup(buffer, workingdir);
return 0;
};
END_OF_MAIN()
|