BASE.CPP

The galvadrs.cpp file is where you find the game-entry main(), and game initialization code.
/****************************************************************
    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()