Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "platform.h"
- #include "fastfile.h"
- #include "ogldrv.h"
- #include "aldrv.h"
- #include "tgaLoader.h"
- #include "vmath.h"
- #include "game.h"
- #include "gold.h"
- #include "input.h"
- #include "texfont.h"
- #include "menu.h"
- #include "spline.h"
- #include "wavstream.h"
- /* Enemy types */
- #define ENEMY_PARTICLE 0
- #define ENEMY_REDDRAGON 1
- #define ENEMY_GREENDRAGON 2
- #define ENEMY_BLUEDRAGON 3
- #define ENEMY_BLACKDRAGON 4
- #define ENEMY_WATERDRAGON 5
- #define ENEMY_FAIRY 6
- #define ENEMY_PHOENIX 7
- #define ENEMY_SQUID 8
- #define ENEMY_SEASERPENT 9
- #define ENEMY_TANK 10
- #define ENEMY_ZEPPELIN 11
- #define ENEMY_DRONE 12
- #define ENEMY_SUPERDRAGON 13
- /* Boss types */
- #define BOSS_MASK 0
- #define BOSS_SQUID 1
- #define BOSS_BLUEDEATH 2
- #define BOSS_AIRSHIP 3
- #define BOSS_REAPER 4
- /* Power up types */
- #define POWER_CRYSTAL1 1
- #define POWER_CRYSTAL2 2
- #define POWER_CRYSTAL3 3
- #define POWER_HEART1 4
- #define POWER_HEART2 5
- int game_state = GAME_STATE_INTRO1;
- int menu_state = MENU_STATE_TITLE;
- int score = 0;
- int level = 1;
- int boss_mode = No;
- int ingame_fade = -1;
- int bgm_fade = No;
- char bgm_next_track[16] = "";
- int bgm_volume = 10; /* 10=loudest,0=silent */
- int sfx_volume = 10;
- float scroll_speed = 0.5f; /* Ground scroll speed */
- int background = 0; /* Background image number */
- int fps_limit = 60; /* FPS cap (varies depending on game speed */
- /* and halves when too many sprites are ingame */
- int game_speed = 100; /* Game movement speed */
- int active_shoots = 0; /* Number of active shoots in the game */
- BYTE keys[256];
- struct vec2d_t ch;
- struct mouse_t mouse;
- struct dragon_t dragon;
- struct lock_t locks[MAX_LOCKS];
- struct enemy_t enemies[MAX_ENEMIES];
- struct boss_t boss;
- struct enemyshoot_t enemyshoots[MAX_ENEMYSHOOTS];
- struct guard_t guard;
- int overdrive_timer = 0;
- struct powerup_t powerups[4];
- struct smoke_t smoke[MAX_SMOKE];
- unsigned int textures[MAX_TEXTURES];
- struct sound_t sfx[MAX_SOUNDFX];
- struct font_t fonts[7];
- struct homingblast_t homingblasts[MAX_HOMINGBLASTS];
- struct fullautoblast_t fullautoblasts[MAX_FULLAUTOBLASTS];
- struct explosion_t explosions[MAX_EXPLOSIONS];
- struct vec2d_t trees[8], rocks[8], clouds[3];
- struct wave_stream bgm;
- unsigned int render_target = 0;
- #if 1
- struct spline_t spline;
- #endif
- char* tex_files[] =
- {
- "aircrft1.tga",
- "aircrft2.tga",
- "bkg1.tga",
- "bkg2.tga",
- "bkg3.tga",
- "bkg4.tga",
- "bkg5.tga",
- "bkg6.tga",
- "bkg7.tga",
- "blade1.tga",
- "blade2.tga",
- "bomb.tga",
- "boss1.tga",
- "boss2.tga",
- "boss3.tga",
- "boss4.tga",
- "boss5.tga",
- "blade1.tga",
- "blade2.tga",
- "cloud1.tga",
- "cloud2.tga",
- "cloud3.tga",
- "cross1.tga",
- "cross2.tga",
- "desc1.tga",
- "desc2.tga",
- "desc3.tga",
- "diamond1.tga",
- "diamond2.tga",
- "diamond3.tga",
- "dirt1a.tga",
- "dirt1b.tga",
- "dragon1.tga",
- "dragon2.tga",
- "dragon3.tga",
- "dragon4.tga",
- "drone.tga",
- "expl1.tga",
- "expl2.tga",
- "fairy.tga",
- "fbgreen.tga",
- "fbred.tga",
- "firebal1.tga",
- "firebal2.tga",
- "firebal3.tga",
- "firebird.tga",
- "flare0.tga",
- "flare.tga",
- "gold.tga",
- "grass1a.tga",
- "grass1b.tga",
- "guard.tga",
- "hblast2.tga",
- "hblast.tga",
- "heart1.tga",
- "heart2.tga",
- "hero.tga",
- "intile1.tga",
- "intile2.tga",
- "intile2d.tga",
- "intile3.tga",
- "intile3d.tga",
- "palmtree.tga",
- "particle.tga",
- "phoenix.tga",
- "pinetree.tga",
- "plasma1.tga",
- "plasma2.tga",
- "rock.tga",
- "sand1a.tga",
- "sand1b.tga",
- "sdragon.tga",
- "shogun3d.tga",
- "shot1.tga",
- "shot2.tga",
- "shot.tga",
- "smoke.tga",
- "sparkle.tga",
- "squid.tga",
- "sserpent.tga",
- "tank.tga",
- "title1.tga",
- "title2.tga",
- "water1a.tga",
- "water1b.tga",
- "zeppelin.tga",
- };
- int tex_file_sizes[MAX_TEXTURES];
- char* sfx_files[] =
- {
- "crystal3.wav",
- "firefa.wav",
- "hblast.wav",
- "lock8.wav",
- "mmove.wav",
- "msel.wav"
- "woosh.wav",
- };
- #if 0
- int sfx_file_sizes[MAX_SOUNDFX] =
- {
- 22134, /* crystal.wav */
- 6376, /* firefa.wav */
- 91674, /* hblast.wav */
- 43280, /* mmove.wav */
- 38780, /* msel.wav */
- };
- #else
- int sfx_file_sizes[MAX_SOUNDFX];
- #endif
- unsigned int get_texture( char* texname );
- int active_homing_blasts();
- void activate_explosion( int expl_id, float x, float y, int type );
- void give_possible_powerup( float x, float y );
- void reset_smoke_puffs();
- void add_smoke_puff( float x, float y, int type );
- void update_crosshair_position()
- {
- get_crosshair_position( &ch.x, &ch.y );
- }
- void reset_dragon()
- {
- /* Reset dragon values */
- dragon.width = 106.0f/2.0f;
- dragon.height = 149.0f/2.0f;
- dragon.x = ( 640.0f / 2.0f ) - ( dragon.width / 2.0f );
- dragon.y = ( 480.0f / 2.0f ) - ( dragon.height / 2.0f );
- dragon.vx = 5.0f;
- dragon.vy = 5.0f;
- dragon.energy = 100;
- dragon.max_energy = 100;
- dragon.attack_mode = 1;
- dragon.powers[0] = Yes;
- dragon.powers[1] = Yes;
- dragon.powers[2] = Yes;
- dragon.inv_t = 0;
- }
- void reset_enemies()
- {
- int i = 0;
- /* Reset all enemies to dead and with no locks */
- while( i < MAX_ENEMIES )
- {
- enemies[i].dead = 1;
- enemies[i].dying = No;
- enemies[i].lock = -1;
- enemies[i].type = 0;
- enemies[i].movement = EMOVEMENT_STATIONARY;
- enemies[i].line = 0;
- enemies[i].energy = 1;
- i++;
- }
- #if 0
- /* Test: Create one enemy (particle) */
- /*enemies[0].dead = 0;
- enemies[0].frame = 0;
- enemies[0].type = ENEMY_PARTICLE;
- enemies[0].x = 320.0f;
- enemies[0].y = 150.0f;
- enemies[0].sx = 32.0f;
- enemies[0].sy = 32.0f;
- enemies[0].max_frame = 29;
- enemies[0].timer = 0;
- enemies[0].max_timer = 0;
- enemies[0].energy = 1;
- enemies[1].dead = 0;
- enemies[1].frame = 0;
- enemies[1].type = ENEMY_REDDRAGON;
- enemies[1].x = 375.0f;
- enemies[1].y = 120.0f;
- enemies[1].sx = 96.0f;
- enemies[1].sy = 64.0f;
- enemies[1].max_frame = 3;
- enemies[1].timer = 0;
- enemies[1].max_timer = 15;
- enemies[1].energy = 5;
- enemies[2].dead = 0;
- enemies[2].frame = 0;
- enemies[2].type = ENEMY_GREENDRAGON;
- enemies[2].x = 275.0f;
- enemies[2].y = 120.0f;
- enemies[2].sx = 96.0f;
- enemies[2].sy = 64.0f;
- enemies[2].max_frame = 3;
- enemies[2].timer = 0;
- enemies[2].max_timer = 15;
- enemies[2].energy = 5;
- enemies[3].dead = 0;
- enemies[3].frame = 0;
- enemies[3].type = ENEMY_BLACKDRAGON;
- enemies[3].x = 325.0f;
- enemies[3].y = 90.0f;
- enemies[3].sx = 96.0f;
- enemies[3].sy = 64.0f;
- enemies[3].max_frame = 3;
- enemies[3].timer = 0;
- enemies[3].max_timer = 15;
- enemies[3].energy = 5;
- enemies[4].dead = 0;
- enemies[4].frame = 0;
- enemies[4].type = ENEMY_FAIRY;
- enemies[4].x = 405.0f;
- enemies[4].y = 40.0f;
- enemies[4].sx = 56.0f;
- enemies[4].sy = 62.0f;
- enemies[4].max_frame = 1;
- enemies[4].timer = 0;
- enemies[4].max_timer = 0;
- enemies[0].energy = 1;*/
- enemies[5].dead = 0;
- enemies[5].frame = 0;
- enemies[5].type = ENEMY_FAIRY;
- enemies[5].x = spline.points[spline.start_point].x;
- enemies[5].y = spline.points[spline.start_point].y;
- enemies[5].sx = 56.0f;
- enemies[5].sy = 62.0f;
- enemies[5].max_frame = 1;
- enemies[5].timer = 0;
- enemies[5].max_timer = 0;
- enemies[5].movement = EMOVEMENT_SPLINE;
- enemies[6].dead = 0;
- enemies[6].dying = 0;
- enemies[6].frame = 0;
- enemies[6].type = ENEMY_ZEPPELIN;
- enemies[6].x = 320.0f;
- enemies[6].y = 150.0f;
- enemies[6].sx = 76.0f;
- enemies[6].sy = 100.0f;
- enemies[6].max_frame = 1;
- enemies[6].timer = 0;
- enemies[6].max_timer = 0;
- enemies[6].energy = EMAX_ZEPPELIN;
- /* enemies[7].dead = 0;
- enemies[7].dying = 0;
- enemies[7].frame = 0;
- enemies[7].type = ENEMY_TANK;
- enemies[7].x = 320.0f;
- enemies[7].y = 0.0f;
- enemies[7].sx = 84.0f;
- enemies[7].sy = 91.0f;
- enemies[7].max_frame = 1;
- enemies[7].timer = 0;
- enemies[7].max_timer = 0;
- enemies[7].energy = EMAX_TANK;
- enemies[7].rot = 180.0f; // /* Turn completely around */
- /*enemies[7].movement = EMOVEMENT_STILL;*/
- enemies[8].dead = 0;
- enemies[8].dying = 0;
- enemies[8].frame = 0;
- enemies[8].type = ENEMY_DRONE;
- enemies[8].x = 280.0f;
- enemies[8].y = 100.0f;
- enemies[8].sx = 16.0f;
- enemies[8].sy = 16.0f;
- enemies[8].max_frame = 1;
- enemies[8].timer = 0;
- enemies[8].max_timer = 0;
- enemies[8].energy = 1;
- enemies[9].dead = 0;
- enemies[9].dying = 0;
- enemies[9].frame = 0;
- enemies[9].type = ENEMY_DRONE;
- enemies[9].x = 360.0f;
- enemies[9].y = 100.0f;
- enemies[9].sx = 16.0f;
- enemies[9].sy = 16.0f;
- enemies[9].max_frame = 1;
- enemies[9].timer = 0;
- enemies[9].max_timer = 0;
- enemies[9].energy = 1;
- enemies[10].dead = 0;
- enemies[10].dying = 0;
- enemies[10].frame = 0;
- enemies[10].type = ENEMY_DRONE;
- enemies[10].x = 320.0f;
- enemies[10].y = 80.0f;
- enemies[10].sx = 16.0f;
- enemies[10].sy = 16.0f;
- enemies[10].max_frame = 1;
- enemies[10].timer = 0;
- enemies[10].max_timer = 0;
- enemies[10].energy = 1;
- /*i = find_inactive_lock();
- if( i != -1 )
- {
- enemies[0].lock = i;
- activate_lock( i, enemies[0].x, enemies[0].y );
- }*/
- #endif
- }
- int get_enemy_point_value( int type )
- {
- switch( type )
- {
- case ENEMY_REDDRAGON:
- case ENEMY_GREENDRAGON:
- case ENEMY_BLUEDRAGON:
- case ENEMY_BLACKDRAGON:
- case ENEMY_WATERDRAGON:
- return 100;
- case ENEMY_FAIRY:
- return 25;
- case ENEMY_PHOENIX:
- case ENEMY_SQUID:
- case ENEMY_SEASERPENT:
- return 50;
- case ENEMY_ZEPPELIN:
- case ENEMY_TANK:
- return 150;
- case ENEMY_DRONE:
- return 10;
- case ENEMY_SUPERDRAGON:
- return 300;
- }
- return 0;
- }
- void kill_enemy( struct enemy_t* e, int expl_sfx )
- {
- int expl = 0;
- /* Okay, it looks like we have a hit here. Now kill this targetable
- entity and deactivate this homing blast */
- e->dead = Yes;
- /* Increase the user's score */
- score += get_enemy_point_value( e->type );
- /* Do explosion and sound effects */
- play_sound_effect_static( &sfx[expl_sfx], 0 );
- expl = find_inactive_explosion();
- if( expl != -1 )
- {
- activate_explosion( expl, e->x, e->y, 0 );
- }
- /* Award the user with a gold peice */
- add_gold_peice( e->x, e->y );
- /* Possible powerup time */
- give_possible_powerup( e->x, e->y );
- }
- void add_new_enemy_shoot( float x, float y, float speed, int type );
- void update_drone( struct enemy_t* e )
- {
- static int delay = 0;
- /* Every 10 frames, make the drones shoot */
- if( ++delay == 4 )
- {
- add_new_enemy_shoot( e->x, e->y, 2.0f, 0 );
- delay = 0;
- }
- }
- void reset_all_locks( int reset_enemy_locks )
- {
- int i = 0;
- /* Reset all lock values */
- memset( locks, 0, sizeof( struct lock_t ) );
- while( i < MAX_LOCKS )
- {
- locks[i].active = 0;
- locks[i].size = 500.0f;
- i++;
- }
- /* Remove locks from all enemies if necessary */
- if( reset_enemy_locks )
- {
- i = 0;
- while( i < MAX_ENEMIES )
- {
- enemies[i].lock = -1;
- i++;
- }
- }
- }
- void reset_lock_to_inactive( int id )
- {
- locks[id].active = 0;
- locks[id].size = 500.0f;
- locks[id].flash = 0;
- }
- int find_inactive_lock()
- {
- /* Search for an inactive lock. If one is free, return the id number
- of that lock and let the caller activate it and track it's position.
- If not, return -1 for no inactive lock. */
- int i = 0;
- while( i < MAX_LOCKS )
- {
- if( !locks[i].active )
- return i;
- i++;
- }
- return -1;
- }
- int active_locks_available()
- {
- /* Search for any active locks and return the number of active locks. */
- int i = 0;
- int lock_count = 0;
- while( i < MAX_LOCKS )
- {
- if( locks[i].active )
- lock_count++;
- i++;
- }
- return lock_count;
- }
- void activate_lock( int id, float x, float y )
- {
- locks[id].active = 1;
- locks[id].x = x;
- locks[id].y = y;
- }
- void draw_active_locks()
- {
- int i;
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- wireframe( Yes );
- for( i = 0; i < MAX_LOCKS; i++ )
- {
- if( locks[i].active )
- {
- float size = locks[i].size;
- push_pos();
- translate( locks[i].x, locks[i].y );
- rotate( locks[i].rotz );
- if( locks[i].flash == 0 )
- draw_quad( 0, -size/2.0f, -size/2.0f, size, size );// size += 5.0f;
- pop_pos();
- }
- }
- wireframe( No );
- disable_2d();
- }
- void update_active_locks()
- {
- int i = 0;
- while( i < MAX_LOCKS )
- {
- if( locks[i].active )
- {
- locks[i].rotz += 4.0f;
- locks[i].size -= 15.0f;
- if( locks[i].size < 30.0f )
- locks[i].size = 30.0f;
- }
- if( locks[i].size == 30.0f )
- {
- locks[i].rotz = 0.0f;
- locks[i].flash++;
- if( locks[i].flash > 5 )
- locks[i].flash = 0;
- }
- i++;
- }
- /* Update the position of each active lock with the position of
- that particular targetable entity */
- i = 0;
- while( i < MAX_LOCKS )
- {
- if( locks[i].active )
- {
- locks[i].x = enemies[locks[i].owner].x;
- locks[i].y = enemies[locks[i].owner].y;
- }
- i++;
- }
- }
- void draw_explosion( struct explosion_t* e )
- {
- div_t result;
- float tex[8];// = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
- float s, t;
- float w = 320.0f, h = 320.0f;
- result = div( e->frame, 5 );
- s = (float) result.rem * ( e->sx / w );
- t = (float) 1.0f - ( result.quot * ( e->sy / h ) );
- tex[0] = s; tex[1] = t - e->sy / h;
- tex[2] = s + e->sx / w; tex[3] = t - e->sy / h;
- tex[4] = s + e->sx / w; tex[5] = t;
- tex[6] = s; tex[7] = t;
- enable_2d();
- push_pos();
- transparent_blend( TRUE );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- translate( e->x, e->y );
- draw_quad2( get_texture( "expl2" ), tex, -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- transparent_blend( FALSE );
- pop_pos();
- disable_2d();
- }
- void draw_particle( const struct enemy_t* e )
- {
- div_t result;
- float tex[8];// = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
- float s, t;
- result = div( e->frame, 5 );
- s = (float) result.rem * ( e->sx / 160.0f );
- t = (float) 1.0f - ( result.quot * ( e->sy / 192.0f ) );
- tex[0] = s; tex[1] = t + e->sy / 192.0f;
- tex[2] = s + e->sx / 160.0f; tex[3] = t + e->sy / 192.0f;
- tex[4] = s + e->sx / 160.0f; tex[5] = t;
- tex[6] = s; tex[7] = t;
- enable_2d();
- push_pos();
- transparent_blend( TRUE );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- translate( e->x, e->y );
- draw_quad2( get_texture( "particle" ), tex, -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- transparent_blend( FALSE );
- pop_pos();
- disable_2d();
- }
- void draw_dragon( const struct enemy_t* e, int frame_offset )
- {
- div_t result;
- float tex[8];// = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
- float s, t;
- float w = 288.0f;
- float h = 256.0f;
- result = div( e->frame + frame_offset, 5 );
- s = (float) result.rem * ( e->sx / w );
- t = (float) 1.0f - ( result.quot * ( e->sy / h ) );
- tex[0] = s; tex[1] = t + e->sy / h;
- tex[2] = s + e->sx / w; tex[3] = t + e->sy / h;
- tex[4] = s + e->sx / w; tex[5] = t;
- tex[6] = s; tex[7] = t;
- enable_2d();
- push_pos();
- transparent_blend( TRUE );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- translate( e->x, e->y );
- draw_quad2( get_texture( "dragon2" ), tex, -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- transparent_blend( FALSE );
- pop_pos();
- disable_2d();
- }
- void draw_fairy( const struct enemy_t* e )
- {
- /* Draw a simple fairy sprite */
- /* Enable 2D rendering */
- enable_2d();
- /* Translate to the fairy's position */
- push_pos();
- translate( e->x, e->y );
- /* Alpha blending for colour key */
- transparent_blend( TRUE );
- /* Set base colour to white */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Draw the fairy sprite */
- draw_quad( get_texture( "fairy" ), -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- /* Disable alpha blending */
- transparent_blend( FALSE );
- /* Restore previous position */
- pop_pos();
- /* Disable 2D rendering */
- disable_2d();
- }
- void draw_zeppelin( const struct enemy_t* e )
- {
- float f = 0.0f;
- /* Draw a zeppelin sprite */
- /* Enable 2D rendering */
- enable_2d();
- /* Translate to the fairy's position */
- push_pos();
- translate( e->x, e->y );
- /* Alpha blending for colour key */
- transparent_blend( TRUE );
- /* Set base colour to white */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Draw the fairy sprite */
- draw_quad( get_texture( "zeppelin" ), -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- /* Disable alpha blending */
- transparent_blend( FALSE );
- /* Let's draw an energy bar! */
- if( !e->dying )
- {
- set_colour( 1.0f, 0.0f, 0.0f, 1.0f );
- draw_line( -25.0f, -(e->sy/2.0f) - 10.0f, 25.0f, -(e->sy/2.0f) - 10.0f );
- f = (float) (((float)e->energy) / ((float)EMAX_ZEPPELIN) );
- set_colour( 0.0f, 1.0f, 0.0f, 1.0f );
- draw_line( -25.0f, -(e->sy/2.0f) - 10.0f, (f*50.0f)-25.0f, -(e->sy/2.0f) - 10.0f );
- }
- /* Restore previous position */
- pop_pos();
- /* Disable 2D rendering */
- disable_2d();
- }
- void draw_tank( const struct enemy_t* e )
- {
- float f = 0.0f;
- /* Draw a tank sprite */
- /* Enable 2D rendering */
- enable_2d();
- /* Translate to the tank's position */
- push_pos();
- translate( e->x, e->y );
- /* Rotate the tank as necessary */
- push_pos();
- rotate( e->rot );
- /* Alpha blending for colour key */
- transparent_blend( TRUE );
- /* Set base colour to white */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Draw the fairy sprite */
- draw_quad( get_texture( "tank" ), -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- /* Disable alpha blending */
- transparent_blend( FALSE );
- /* Undo rotation */
- pop_pos();
- /* Let's draw an energy bar! */
- if( !e->dying )
- {
- set_colour( 1.0f, 0.0f, 0.0f, 1.0f );
- draw_line( -25.0f, -(e->sy/2.0f) - 10.0f, 25.0f, -(e->sy/2.0f) - 10.0f );
- f = (float) (((float)e->energy) / ((float)EMAX_TANK) );
- set_colour( 0.0f, 1.0f, 0.0f, 1.0f );
- draw_line( -25.0f, -(e->sy/2.0f) - 10.0f, (f*50.0f)-25.0f, -(e->sy/2.0f) - 10.0f );
- }
- /* Restore previous position */
- pop_pos();
- /* Disable 2D rendering */
- disable_2d();
- }
- void draw_drone( const struct enemy_t* e )
- {
- /* Draw a simple drone sprite */
- /* Enable 2D rendering */
- enable_2d();
- /* Translate to the drone's position */
- push_pos();
- translate( e->x, e->y );
- /* Alpha blending for colour key */
- transparent_blend( TRUE );
- /* Set base colour to white */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Draw the fairy sprite */
- draw_quad( get_texture( "drone" ), -(e->sx/2.0f), -(e->sy/2.0f), e->sx, e->sy );
- /* Disable alpha blending */
- transparent_blend( FALSE );
- /* Restore previous position */
- pop_pos();
- /* Disable 2D rendering */
- disable_2d();
- }
- void move_dragon()
- {
- if( move_up() )
- {
- dragon.y -= 4.0f;
- }
- if( move_down() )
- {
- dragon.y += 4.0f;
- }
- if( move_left() )
- {
- dragon.x -= 4.0f;
- }
- if( move_right() )
- {
- dragon.x += 4.0f;
- }
- /* Boundary detection */
- if( dragon.x < 160.0f )
- dragon.x = 160.0f;
- if( dragon.x > 480.0f - dragon.width )
- dragon.x = 480.0f - dragon.width;
- if( dragon.y < 0.0f )
- dragon.y = 0.0f;
- if( dragon.y > 480.0f - dragon.height )
- dragon.y = 480.0f - dragon.height;
- }
- void reset_and_activate_guard();
- int activate_overdrive();
- void turn_all_enemy_shoots_into_gold();
- void check_for_special_input()
- {
- if( special1_button() && dragon.powers[0] )
- {
- turn_all_enemy_shoots_into_gold();
- dragon.powers[0] = No;
- }
- if( special2_button() && dragon.powers[1] )
- {
- if( activate_overdrive() )
- dragon.powers[1] = No;
- }
- if( special3_button() && dragon.powers[2] )
- {
- if( !guard.activated )
- {
- dragon.powers[2] = No;
- reset_and_activate_guard();
- }
- }
- }
- void ready_homing_blasts();
- void activate_fullautoblast( int id );
- void handle_mouse_input()
- {
- static int lb_down = 0;
- static int rb_down = 0;
- static int delay = 0;
- /* Process left mouse clicks */
- if( shoot_button_down() )
- {
- /* Signify that the left mouse button is down */
- lb_down = 1;
- /* What firing mode are we using? */
- if( dragon.attack_mode == 0 )
- {
- /* Full auto plays the rapid fire sound effect */
- if( ++delay == 3 )
- {
- int fa_id = 0;
- play_sound_effect_static( &sfx[10], 0 );
- fa_id = find_inactive_fullautoblast();
- if( fa_id != -1 )
- {
- activate_fullautoblast( fa_id );
- }
- delay = 0;
- }
- }
- else
- {
- /* Lock mode plays the lock sound effect when new locks are aquired
- (not in this function) and the homing blast sound effect when the
- button is released */
- }
- }
- else
- {
- /* Was the left mouse button just released? */
- if( lb_down == 1 )
- {
- lb_down = 0;
- /* Play the homing blast sound effect if there are any locks */
- /* Also reset any locks */
- if( active_locks_available() && active_homing_blasts() == 0 )
- {
- play_sound_effect( &sfx[2], 0 );
- ready_homing_blasts();
- reset_all_locks( TRUE );
- }
- }
- }
- }
- void draw_enemies()
- {
- #if 0
- struct enemy_t e;
- static frame = 0;
- e.dead = 0;
- e.frame = frame;
- e.lock = 0;
- e.sx = 32.0f;
- e.sy = 32.0f;
- e.type = ENEMY_PARTICLE;
- e.x = 160.0f;
- e.y = 50.0f;
- draw_particle( &e );
- if( ++frame > 29 )
- frame = 0;
- #else
- int i = 0;
- /* Go through list of enemies */
- while( i < MAX_ENEMIES )
- {
- /* Is this enemy active/alive? */
- if( !enemies[i].dead )
- {
- /* If so, render it */
- /* Flash if flashing */
- if( enemies[i].flash ) flash_white( Yes );
- switch( enemies[i].type )
- {
- case ENEMY_PARTICLE: draw_particle( &enemies[i] ); break;
- case ENEMY_REDDRAGON: draw_dragon( &enemies[i], 10 ); break;
- case ENEMY_GREENDRAGON: draw_dragon( &enemies[i], 0 ); break;
- case ENEMY_BLUEDRAGON: draw_dragon( &enemies[i], 15 ); break;
- case ENEMY_BLACKDRAGON: draw_dragon( &enemies[i], 5 ); break;
- case ENEMY_FAIRY: draw_fairy( &enemies[i] ); break;
- case ENEMY_ZEPPELIN: draw_zeppelin( &enemies[i] ); break;
- case ENEMY_TANK: draw_tank( &enemies[i] ); break;
- case ENEMY_DRONE: draw_drone( &enemies[i] ); break;
- default: break;
- }
- /* Stop flashing */
- if( enemies[i].flash ) flash_white( No );
- /* Stop flashing */
- enemies[i].flash = No;
- /* Update the sprite's key frame animation */
- if( enemies[i].timer++ >= enemies[i].max_timer )
- {
- enemies[i].timer = 0;
- if( ++enemies[i].frame >= enemies[i].max_frame )
- enemies[i].frame = 0;
- }
- /* Move this enemy according to it's movement pattern */
- if( enemies[i].movement == EMOVEMENT_SPLINE )
- {
- /* TODO: Move enemy along it's spline. */
- /* TODO: When enemy moves offscreen to it's final destination.
- mark it as dead, but obviously give no score for it either */
- if( move_position_on_spline( &spline ) )
- enemies[i].dead = Yes;
- else
- {
- struct Vector2 v;
- get_current_position_on_spline( &spline, &v );
- enemies[i].x = v.x;
- enemies[i].y = v.y;
- }
- }
- else if( enemies[i].movement == EMOVEMENT_STILL )
- {
- /* Move the enemy with the screen */
- enemies[i].y += scroll_speed;
- /* When the enemy has gone below the screen, mark it as inactive */
- if( enemies[i].y > 480.0f )
- enemies[i].dead = Yes;
- }
- /* Check for dying enemies */
- if( enemies[i].dying && !enemies[i].dead )
- {
- /* Dying enemies (such as zeppelins) need special attention */
- if( enemies[i].type == ENEMY_ZEPPELIN )
- {
- static int interval = 0;
- /* Decrease ship size to make it look like it's falling */
- enemies[i].sx -= 1.0f;
- enemies[i].sy -= 1.0f;
- enemies[i].y += 0.5f;
- /* Add a new smoke puff every 10 frames */
- if( interval <= 0 )
- {
- add_smoke_puff( enemies[i].x, enemies[i].y, SMOKEANIM_RISE );
- interval = 10;
- }
- else
- interval--;
- /* Is the zeppelin small enough now? */
- if( enemies[i].sx < ( 76.0f/3.0f ) && enemies[i].sy < ( 100.0f/3.0f ) )
- {
- enemies[i].dead = Yes;
- kill_enemy( &enemies[i], 9 );
- }
- }
- }
- /* Enemy specific updates */
- if( enemies[i].type == ENEMY_DRONE )
- update_drone( &enemies[i] );
- }
- i++;
- }
- #endif
- }
- void reset_and_activate_guard()
- {
- /* Reset and activate the guard ability */
- guard.activated = Yes;
- guard.angle = 0.0f;
- guard.dist = 1.0f;
- guard.expired = No;
- guard.timer = 1000;
- }
- void draw_guard_if_activated()
- {
- int i = 0;
- float size = 24.0f;
- if( !guard.activated )
- return 0;
- /* Draw guard crystals */
- enable_2d();
- transparent_blend( Yes );
- while( i < 3 )
- {
- push_pos();
- translate( guard.x[i], guard.y[i] );
- draw_quad( get_texture( "guard" ), -(size/2.0f), -(size/2.0f), size, size );
- pop_pos();
- i++;
- }
- transparent_blend( No );
- disable_2d();
- }
- void update_guard_if_activated()
- {
- int i = 0;
- if( !guard.activated )
- return 0;
- /* Update the angle that the guard crystal is rotating */
- guard.angle += 0.1f;
- /* Move further outward if the maximum distance was not reached */
- if( guard.dist < 70.0f && !guard.expired )
- guard.dist++;
- /* Move inward if the guard is expiring */
- if( guard.expired && guard.dist > 0.0f )
- guard.dist--;
- /* Deactivate the guard if finished */
- if( guard.expired && guard.dist <= 0.0f )
- guard.activated = No;
- /* Set the position of all 3 guard crystals */
- while( i < 3 )
- {
- guard.x[i] = guard.dist * cos( ( i * 2.0f * 3.14f / 3.0f ) + guard.angle ) + ( dragon.x + ( dragon.width / 2.0f ) );
- guard.y[i] = guard.dist * sin( ( i * 2.0f * 3.14f / 3.0f ) + guard.angle ) + ( dragon.y + ( dragon.height / 2.0f ) );
- i++;
- }
- /* Update expiration timer */
- if( --guard.timer <= 0 )
- guard.expired = Yes;
- i = 0;
- /* Check each guard crystal for a collision */
- while( i < 3 )
- {
- int j = 0;
- /* Check each enemy for a collision test */
- while( j < MAX_ENEMIES )
- {
- /* Is this enemy alive so we can kill it? */
- if( !enemies[j].dead )
- {
- /* It is, let's check to see if the guard crystal did it's job */
- if( guard.x[i] >= enemies[j].x && guard.x[i] <= enemies[j].x+enemies[j].sx &&
- guard.y[i] >= enemies[j].y && guard.y[i] <= enemies[j].y+enemies[j].sy )
- {
- /* Do 5 damage */
- enemies[j].energy -= 25;
- /* Is this enemy dead? */
- if( enemies[j].energy <= 0 )
- {
- /* Enemy zeppelin's don't die automatically */
- if( enemies[j].type == ENEMY_ZEPPELIN )
- enemies[j].dying = Yes;
- else
- {
- /* Katsu! */
- kill_enemy( &enemies[j], 7 );
- }
- }
- else
- {
- /* If not, just flash white for a frame */
- enemies[j].flash = Yes;
- }
- /* Let homing blast go */
- // homingblasts[i].target = -1;
- // homingblasts[i].fade_timer = 200;
- }
- }
- j++;
- }
- i++;
- }
- }
- int activate_overdrive()
- {
- /* Activates overdrive! */
- /* Don't activate overdrive if the timer from the previous session
- has not expired. If it hasn't return 0 so that the power up is
- not marked as used until this session is over! */
- if( overdrive_timer > 0 )
- return 0;
- overdrive_timer = 500;
- }
- void update_overdrive_if_active()
- {
- /* If the overdrive power up is active, decrease the timer */
- if( overdrive_timer > 0 )
- overdrive_timer--;
- }
- void reset_powerups()
- {
- memset( powerups, 0, sizeof( struct powerup_t ) * 4 );
- }
- void give_possible_powerup( float x, float y )
- {
- /* This function should be called every time an applicable targetable enemy is
- destroyed. It randomly decides wither the player gets a power up to recieve.
- There is a 1 in 20 chance of getting a power up, but the odds for getting
- certain ones can vary. The odds table contains a list of powerups. The less
- frequent the powerup is on the table, the less likely you are to get that one.
- Heart #2 is designed to the the rarest. */
- int i = 0;
- int odds[10] = { 1, 1, 1, 2, 2, 3, 3, 4, 4, 5 };
- /* Check odds of actually getting anything.... */
- if( (rand()%5) != 1 )
- return; /* *BUZZER!* Not this time. */
- /* *DING DING DING!* We have a winner! */
- while( i < 4 )
- {
- /* Search the list for an inactive powerup. If we find one, activate it */
- if( !powerups[i].active )
- {
- powerups[i].active = Yes;
- powerups[i].x = x;
- powerups[i].y = y;
- powerups[i].type = odds[(rand()%10)];
- powerups[i].vx = 3.0f;
- powerups[i].vy = 3.0f;
- powerups[i].sx = powerups[i].sy = 32.0f;
- return;
- }
- i++;
- }
- }
- void draw_powerups()
- {
- int i = 0;
- char string[16];
- enable_2d();
- transparent_blend( Yes );
- /* Render each power up */
- while( i < 4 )
- {
- /* Is it active? */
- if( powerups[i].active )
- {
- /* get the actual texture name */
- switch( powerups[i].type )
- {
- case POWER_CRYSTAL1:
- sprintf( string, "diamond1.tga" );
- break;
- case POWER_CRYSTAL2:
- sprintf( string, "diamond2.tga" );
- break;
- case POWER_CRYSTAL3:
- sprintf( string, "diamond3.tga" );
- break;
- case POWER_HEART1:
- sprintf( string, "heart1.tga" );
- break;
- case POWER_HEART2:
- sprintf( string, "heart2.tga" );
- break;
- }
- /* Now actually render the powerup sprite */
- push_pos();
- translate( powerups[i].x, powerups[i].y );
- draw_quad( get_texture( string ), -16.0f, -16.0f, 32.0f, 32.0f );
- pop_pos();
- }
- i++;
- }
- transparent_blend( Yes );
- disable_2d();
- }
- void update_powerups()
- {
- int i = 0;
- /* Update each active powerup */
- while( i < 4 )
- {
- /* Only if it's active... */
- if( powerups[i].active )
- {
- /* Move the powerup icon around */
- powerups[i].x += powerups[i].vx;
- powerups[i].y += powerups[i].vy;
- /* Check boundaries */
- if( powerups[i].x <= 160.0f )
- powerups[i].vx *= -1.0f;
- if( powerups[i].x >= 480.0f )
- powerups[i].vx *= -1.0f;
- if( powerups[i].y <= 0.0f || powerups[i].y >= 480.0f )
- powerups[i].vy *= -1.0f;
- /* Check for collision with player */
- if( powerups[i].x >= dragon.x && powerups[i].x <= dragon.x + dragon.width &&
- powerups[i].y >= dragon.y && powerups[i].y <= dragon.y + dragon.height )
- {
- /* Deactivate powerup */
- powerups[i].active = No;
- /* Play the confirmation sound */
- play_sound_effect_static( &sfx[0], 0 );
- /* Get the actual texture name */
- switch( powerups[i].type )
- {
- case POWER_CRYSTAL1:
- dragon.powers[0] = Yes;
- break;
- case POWER_CRYSTAL2:
- dragon.powers[1] = Yes;
- break;
- case POWER_CRYSTAL3:
- dragon.powers[2] = Yes;
- break;
- case POWER_HEART1:
- dragon.energy += 25;
- if( dragon.energy > dragon.max_energy )
- dragon.energy = dragon.max_energy;
- break;
- case POWER_HEART2:
- dragon.max_energy += 25;
- dragon.energy += 25;
- break;
- }
- }
- }
- i++;
- }
- }
- void reset_enemy_shoots()
- {
- memset( enemyshoots, 0, sizeof( struct enemyshoot_t ) * MAX_ENEMYSHOOTS );
- }
- int find_inactive_enemy_shoots()
- {
- int i = 0;
- /* Traverse through the list of enemy shoots and find the first inactive shoot */
- while( i < MAX_ENEMYSHOOTS )
- {
- if( !enemyshoots[i].active )
- return i;
- i++;
- }
- return -1;
- }
- void add_new_enemy_shoot( float x, float y, float speed, int type )
- {
- /* Activate a new enemy shoot. If none are free, abort */
- /* TODO: Respond to above issue if we run out of shoots to make more space later */
- int shoot = find_inactive_enemy_shoots();
- /* Verify we have any inactive shoots */
- if( shoot == -1 )
- return;
- /* Update the number of active shoots */
- active_shoots++;
- /* Activate this shoot */
- enemyshoots[shoot].active = Yes;
- enemyshoots[shoot].x = x;
- enemyshoots[shoot].y = y;
- enemyshoots[shoot].angle = angle( x, y, dragon.x+(dragon.width/2.0f), dragon.y+(dragon.height/2.0f) );
- enemyshoots[shoot].dx = cos( enemyshoots[shoot].angle );
- enemyshoots[shoot].dy = sin( enemyshoots[shoot].angle );
- enemyshoots[shoot].speed = speed;
- enemyshoots[shoot].type = type;
- /*fullautoblasts[id].active = Yes;
- fullautoblasts[id].x = dragon.x + (dragon.width/2.0f);
- fullautoblasts[id].y = dragon.y + (dragon.height/2.0f);
- fullautoblasts[id].size = ( overdrive_timer > 0 ) ? 64.0f : 32.0f;
- fullautoblasts[id].angle = angle( dragon.x+(dragon.width/2.0f), dragon.y+(dragon.height/2.0f),
- ch.x, ch.y );
- fullautoblasts[id].dirx = cos( fullautoblasts[id].angle );
- fullautoblasts[id].diry = sin( fullautoblasts[id].angle );
- fullautoblasts[id].speed = 15.0f;*/
- /* TODO: Handle animations, etc */
- /* TODO: Different shot types */
- switch( type )
- {
- case 0: /* Standard */
- enemyshoots[shoot].damage = 15;
- enemyshoots[shoot].frame = 0;
- enemyshoots[shoot].max_frame = 0;
- enemyshoots[shoot].sx = 12.0f;
- enemyshoots[shoot].sy = 22.0f;
- break;
- case 1: /* Cannon ball */
- enemyshoots[shoot].damage = 30;
- break;
- }
- }
- void draw_enemy_shoots()
- {
- int i = 0;
- /* Draw each enemy shoot */
- enable_2d();
- transparent_blend( Yes );
- while( i < MAX_ENEMYSHOOTS )
- {
- /* Is this shoot active? */
- if( enemyshoots[i].active )
- {
- push_pos();
- translate( enemyshoots[i].x, enemyshoots[i].y );
- rotate( enemyshoots[i].angle*(180.0f/3.14f)+90.0f );
- draw_quad( get_texture( "shot1" ),
- -(enemyshoots[i].sx/2.0f),
- -(enemyshoots[i].sy/2.0f),
- enemyshoots[i].sx, enemyshoots[i].sy );
- pop_pos();
- }
- i++;
- }
- transparent_blend( No );
- disable_2d();
- }
- void update_enemy_shoots()
- {
- int i = 0;
- /* Update each enemy shoot */
- while( i < MAX_ENEMYSHOOTS )
- {
- if( enemyshoots[i].active )
- {
- float x1 = (dragon.x+(dragon.width/2.0f)-4.0f);
- float x2 = (dragon.x+(dragon.width/2.0f)+4.0f);
- float y1 = (dragon.y+(dragon.height/2.0f)-4.0f);
- float y2 = (dragon.y+(dragon.height/2.0f)+4.0f);
- /* Move each shoot in it's designated direction */
- enemyshoots[i].x += enemyshoots[i].dx * enemyshoots[i].speed;
- enemyshoots[i].y += enemyshoots[i].dy * enemyshoots[i].speed;
- /* Deactivate any shoots that go out of the boundaries */
- if( enemyshoots[i].x < 160.0f || enemyshoots[i].x > 480.0f ||
- enemyshoots[i].y < 0.0f || enemyshoots[i].y > 480.0f )
- {
- enemyshoots[i].active = No;
- active_shoots--;
- }
- /* Check for collisions with player dragon */
- if( enemyshoots[i].x > x1 && enemyshoots[i].x < x2 &&
- enemyshoots[i].y > y1 && enemyshoots[i].y < y2 )
- {
- /* Oh no, we've been hit! */
- /* Don't do damage if we are flashing */
- if( dragon.inv_t == 0 )
- {
- dragon.energy -= enemyshoots[i].damage;
- dragon.inv_t = 100;
- }
- if( dragon.energy < 0 )
- dragon.energy = 0;
- enemyshoots[i].active = No;
- active_shoots--;
- }
- /* Check for collisions with guard crystals if active */
- if( guard.activated && enemyshoots[i].active )
- {
- /* TODO: FIXME!!! */
- int j = 0;
- while( j < 3 )
- {
- float gx1 = (guard.x[i]-12.0f);
- float gy1 = (guard.y[i]-12.0f);
- float gx2 = (guard.x[i]+12.0f);
- float gy2 = (guard.y[i]+12.0f);
- /*enable_2d();
- wireframe(Yes);
- draw_quad( 0, gx1, gy1, 24, 24 );
- wireframe(No);
- disable_2d();*/
- /* Did it collide? */
- if( enemyshoots[i].x > gx1 && enemyshoots[i].x < gx2 &&
- enemyshoots[i].y > gy1 && enemyshoots[i].y < gy2 )
- {
- /* If so, deactivate shot */
- enemyshoots[i].active = No;
- active_shoots--;
- break;
- }
- j++;
- }
- }
- }
- i++;
- }
- }
- void check_enemy_shoots_for_collisions()
- {
- /* TODO */
- }
- void turn_all_enemy_shoots_into_gold()
- {
- /* Turn all active enemy shoots into gold peices */
- int i = 0;
- while( i < MAX_ENEMYSHOOTS )
- {
- if( enemyshoots[i].active )
- {
- enemyshoots[i].active = No;
- active_shoots--;
- add_gold_peice( enemyshoots[i].x, enemyshoots[i].y );
- }
- i++;
- }
- }
- void init_boss( int level )
- {
- /* Setup the boss structure depending on what boss we are facing */
- memset( &boss, 0, sizeof( struct boss_t ) );
- /* Mask */
- if( level == 1 )
- {
- boss.x = 320.0f /*- (365.0f/2.0f)*/;
- boss.y = 150.0f;
- boss.sx = 365.0f;
- boss.sy = 285.0f;
- boss.max_energy = 1000.0f;
- boss.energy = 900.0f;
- boss.type = BOSS_MASK;
- boss.lock_points = 8;
- }
- boss_mode = Yes;
- }
- void draw_boss()
- {
- float f = 0.0f;
- if( boss_mode )
- {
- enable_2d();
- transparent_blend(Yes);
- push_pos();
- translate( boss.x, boss.y );
- draw_quad( get_texture( "boss1" ), -boss.sx/2.0f, -boss.sy/2.0f, boss.sx, boss.sy );
- pop_pos();
- f = (boss.energy/boss.max_energy) * 300.0f;
- set_colour( 1.0f, 0.0f, 0.0f, 0.5f );
- translate( 160.0f, 20.0f );
- draw_quad( 0, 10.0f, 0, f, 8.0f );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_line( 10.0f, 0.0f, 310.0f, 0.0f );
- draw_line( 10.0f, 8.0f, 310.0f, 8.0f );
- draw_line( 10.0f, 0.0f, 10.0f, 8.0f );
- draw_line( 310.0f, 0.0f, 310.0f, 8.0f );
- transparent_blend(No);
- disable_2d();
- }
- }
- void update_boss()
- {
- }
- int init_textures()
- {
- HFASTFILE ff;
- struct _iobuf* fp;
- struct _iobuf* out;
- void* buffer;
- int i = 0;
- int failed = 0;
- /* Try to open data00.dat */
- out = fopen( "data00.dat", "r" );
- /* If it's there, read the fastfile attributes from there. */
- /* If not, then either create it ourselves or just fail (release builds) */
- if( !out )
- {
- /* Create a data file to contain the sizes of each texture */
- out = fopen( "data00.dat", "w" );
- fprintf( out, "files: %d\n\n", MAX_TEXTURES );
- /* Retrieve the file size of each texture (TEMPORARY) */
- while( i < MAX_TEXTURES )
- {
- char filename[128];
- sprintf( filename, "..\\Media\\textures\\%s", tex_files[i] );
- fp = fopen( filename, "rb" );
- if( !fp )
- {
- MessageBox( NULL, filename, "Pale Dragon", MB_OK );
- return 0;
- }
- fseek( fp, 0, SEEK_END );
- tex_file_sizes[i] = ftell( fp );
- if( out )
- fprintf( out, "%d\n", tex_file_sizes[i] );
- fclose(fp);
- i++;
- }
- }
- else
- {
- int files = 0;
- /* Get the number of files within this fastfile */
- fscanf( out, "files: %d\n\n", &files );
- /* Get the sizes of each file within this fastfile */
- while( i < files )
- {
- fscanf( out, "%d\n", &tex_file_sizes[i] );
- i++;
- }
- }
- /* Close the data file */
- if( out )
- fclose( out );
- /* Initialize the fastfile */
- if( !FastFileInit( "data00.bin", MAX_TEXTURES ) )
- return 0;
- /* Start loading files from the fast file */
- i = 0;
- while( i < MAX_TEXTURES )
- {
- /* Get a handle to the file */
- ff = FastFileOpen( tex_files[i] );
- if(ff)
- {
- /* If we find the file, allocate a buffer large enough so it can
- be read as a file in memory */
- buffer = malloc( tex_file_sizes[i] );
- /* Now actually read in the file's data */
- FastFileRead( ff, buffer, tex_file_sizes[i] );
- /* Now that we have a valid file pointer with data, create a
- texture from it */
- textures[i] = create_texture_from_file( buffer, tex_files[i] );
- /* Free the buffer */
- free( buffer );
- /* Close the fastfile handle */
- FastFileClose( ff );
- }
- else
- {
- failed++;
- }
- i++;
- }
- /* Uninitialize the fast file */
- FastFileFini();
- /* Show any failed texture loads */
- if( failed )
- {
- char string[64];
- sprintf( string, "%d out of %d failed texture loads!", failed, MAX_TEXTURES );
- MessageBox( NULL, string, "Pale Dragon", MB_OK );
- }
- #if 0
- /* TODO: Load textures from fastfile resource */
- if( !( textures[TEX_CROSSHAIR1] = create_texture( "..\\Media\\textures\\crosshair1.tga" ) ) ) return 0;
- if( !( textures[TEX_CROSSHAIR2] = create_texture( "..\\Media\\textures\\crosshair2.tga" ) ) ) return 0;
- if( !( textures[TEX_DRAGON1] = create_texture( "..\\Media\\textures\\dragon1.tga" ) ) ) return 0;
- if( !( textures[TEX_DRAGON2] = create_texture( "..\\Media\\textures\\dragon2.tga" ) ) ) return 0;
- if( !( textures[TEX_HEALTH] = create_texture( "..\\Media\\textures\\heart.tga" ) ) ) return 0;
- if( !( textures[TEX_POWERUP1] = create_texture( "..\\Media\\textures\\diamond1.tga" ) ) ) return 0;
- if( !( textures[TEX_POWERUP2] = create_texture( "..\\Media\\textures\\diamond2.tga" ) ) ) return 0;
- if( !( textures[TEX_POWERUP3] = create_texture( "..\\Media\\textures\\diamond3.tga" ) ) ) return 0;
- if( !( textures[TEX_BACKGROUND] = create_texture( "..\\Media\\textures\\bkg1.tga" ) ) ) return 0;
- if( !( textures[TEX_HOMINGSHOT] = create_texture( "..\\Media\\textures\\hblast.tga" ) ) ) return 0;
- if( !( textures[TEX_SHOT] = create_texture( "..\\Media\\textures\\shot.tga" ) ) ) return 0;
- if( !( textures[TEX_REDSHOT] = create_texture( "..\\Media\\textures\\fbred.tga" ) ) ) return 0;
- if( !( textures[TEX_GREENSHOT] = create_texture( "..\\Media\\textures\\fbgreen.tga" ) ) ) return 0;
- if( !( textures[TEX_PARTICLE] = create_texture( "..\\Media\\textures\\particle.tga" ) ) ) return 0;
- if( !( textures[TEX_EXPLOSION] = create_texture( "..\\Media\\textures\\explosion.tga" ) ) ) return 0;
- if( !( textures[TEX_DIRT] = create_texture( "..\\Media\\textures\\dirt.tga" ) ) ) return 0;
- if( !( textures[TEX_SAND] = create_texture( "..\\Media\\textures\\sand.tga" ) ) ) return 0;
- if( !( textures[TEX_GRASS] = create_texture( "..\\Media\\textures\\grass.tga" ) ) ) return 0;
- if( !( textures[TEX_WATER] = create_texture( "..\\Media\\textures\\water.tga" ) ) ) return 0;
- if( !( textures[TEX_INDOOR1] = create_texture( "..\\Media\\textures\\intile1.tga" ) ) ) return 0;
- if( !( textures[TEX_INDOOR2] = create_texture( "..\\Media\\textures\\intile2.tga" ) ) ) return 0;
- if( !( textures[TEX_INDOOR2D] = create_texture( "..\\Media\\textures\\intile2d.tga" ) ) ) return 0;
- if( !( textures[TEX_INDOOR3] = create_texture( "..\\Media\\textures\\intile3.tga" ) ) ) return 0;
- if( !( textures[TEX_INDOOR3D] = create_texture( "..\\Media\\textures\\intile3d.tga" ) ) ) return 0;
- if( !( textures[TEX_PALMTREE] = create_texture( "..\\Media\\textures\\palmtree.tga" ) ) ) return 0;
- if( !( textures[TEX_PINETREE] = create_texture( "..\\Media\\textures\\pinetree.tga" ) ) ) return 0;
- #endif
- return 1;
- }
- void uninit_textures()
- {
- delete_textures( MAX_TEXTURES, textures );
- }
- unsigned int get_texture( char* texname )
- {
- int i = 0;
- /* Loop through each texture and find one with a matching name. */
- /* When the '.' signifying the end of the texture's name is reached. */
- while( i < MAX_TEXTURES )
- {
- int c = 0;
- int match = 1;
- char str[16];
- /* Test the file name against the current one on the list */
- strcpy( str, tex_files[i] );
- while( str[c] != '.' )
- {
- if( str[c] != texname[c] )
- {
- match = 0;
- break;
- }
- c++;
- }
- /* If it matches, return that texture */
- if( match )
- return textures[i];
- i++;
- }
- return 0;
- }
- int init_soundfx()
- {
- HFASTFILE ff = NULL;
- struct _iobuf* fp = NULL;
- struct _iobuf* out = NULL;
- int i = 0;
- int failed = 0;
- #if 0
- /* Try to open data01.dat */
- out = fopen( "data01.dat", "r" );
- /* If it's there, read the fastfile attributes from there. */
- /* If not, then either create it ourselves or just fail (release builds) */
- if( !out )
- {
- /* Create a data file to contain the sizes of each wav file */
- out = fopen( "data01.dat", "w" );
- fprintf( out, "files: %d\n\n", MAX_SOUNDFX );
- /* Retrieve the file size of each wav file (TEMPORARY) */
- while( i < MAX_SOUNDFX )
- {
- char filename[128];
- sprintf( filename, "..\\Media\\sounds\\%s", sfx_files[i] );
- fp = fopen( filename, "rb" );
- if( !fp )
- {
- MessageBox( NULL, filename, "Pale Dragon", MB_OK );
- return 0;
- }
- fseek( fp, 0, SEEK_END );
- tex_file_sizes[i] = ftell( fp );
- if( out )
- fprintf( out, "%d\n", sfx_file_sizes[i] );
- fclose(fp);
- i++;
- }
- }
- else
- {
- int files = 0;
- /* Get the number of files within this fastfile */
- fscanf( out, "files: %d\n\n", &files );
- /* Get the sizes of each file within this fastfile */
- while( i < files )
- {
- fscanf( out, "%d\n", &tex_file_sizes[i] );
- i++;
- }
- }
- /* Close the data file */
- if( out )
- fclose( out );
- /* Initialize the fastfile */
- if( !FastFileInit( "data01.bin", MAX_SOUNDFX ) )
- return 0;
- /* Start loading files from the fast file */
- i = 0;
- while( i < MAX_SOUNDFX )
- {
- /* Get a handle to the file */
- ff = FastFileOpen( sfx_files[i] );
- if(ff)
- {
- /* If we find the file, allocate a buffer large enough so it can
- be read as a file in memory */
- ALubyte* buffer = (ALubyte*) malloc( sfx_file_sizes[i] );
- /* Now actually read in the file's data */
- FastFileRead( ff, buffer, sfx_file_sizes[i] );
- /* Now that we have a valid file pointer with data, create a
- wav file from it */
- sfx[i].position.x = 0.0f;
- sfx[i].position.y = 0.0f;
- sfx[i].position.z = 0.0f;
- sfx[i].velocity.z = 0.0f;
- sfx[i].velocity.y = 0.0f;
- sfx[i].velocity.x = 0.0f;
- sfx[i].pitch = 1.0f;
- if( !create_sound_wav_from_memory( buffer, &sfx[i] ) )
- failed++;
- /* Free the buffer */
- free( buffer );
- /* Close the fastfile handle */
- FastFileClose( ff );
- }
- else
- {
- failed++;
- }
- i++;
- }
- /* Uninitialize the fast file */
- FastFileFini();
- /* Show any failed wav loads */
- if( failed )
- {
- char string[64];
- sprintf( string, "%d out of %d failed wav loads!", failed, MAX_SOUNDFX );
- MessageBox( NULL, string, "Pale Dragon", MB_OK );
- }
- #else
- struct sound_t snd;
- /* Set default values for sound effects */
- while( i < MAX_SOUNDFX )
- {
- memcpy( &sfx[i], &snd, sizeof( struct sound_t ) );
- i++;
- }
- /* Load each sound effect from disk */
- i = 0;
- if( !create_sound_wav( "..\\media\\sounds\\crystal3.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\firefa.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\hblast.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\lock.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\mmove.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\msel.wav", &sfx[i] ) ) return 0; i++;
- // if( !create_sound_au( "..\\media\\sounds\\msel.au", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\woosh2.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\expl1s.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\gold2.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\expl2s.wav", &sfx[i] ) ) return 0; i++;
- if( !create_sound_wav( "..\\media\\sounds\\firefa2.wav", &sfx[i] ) ) return 0; i++;
- #endif
- play_sound_effect_static( &sfx[5], 0 );
- return 1;
- }
- void uninit_soundfx()
- {
- int i = 0;
- while( i < MAX_SOUNDFX )
- {
- delete_sound( &sfx[i] );
- i++;
- }
- }
- int init_fonts()
- {
- int size = 0;
- /* Initialize fonts */
- memset( fonts, 0, sizeof( struct font_t ) * 7 );
- /* Small font */
- fonts[0].has_colour_key = 1;
- fonts[0].width = 160.0f;
- fonts[0].height = 64.0f;
- fonts[0].letter_width = 160.0f/20.0f;
- fonts[0].letter_height = 60.0f/5.0f;
- fonts[0].letter_offset = 0;
- fonts[0].texname = "sfont.tga";
- fonts[0].texsize = 40991;
- if( !init_font( &fonts[0] ) )
- return 0;
- /* Medium font */
- fonts[1].has_colour_key = 1;
- fonts[1].width = 256.0f;
- fonts[1].height = 256.0f;
- fonts[1].letter_width = 16.0f;
- fonts[1].letter_height = 16.0f;
- fonts[1].letter_offset = 5.0f;
- fonts[1].texname = "mfont.tga";
- fonts[1].texsize = 262175;
- if( !init_font( &fonts[1] ) )
- return 0;
- /* Medium font */
- fonts[2].has_colour_key = 1;
- fonts[2].width = 512.0f;
- fonts[2].height = 512.0f;
- fonts[2].letter_width = 32.0f;
- fonts[2].letter_height = 32.0f;
- fonts[2].letter_offset = 16.0f;
- fonts[2].texname = "lfont.tga";
- fonts[2].texsize = 1048607;
- if( !init_font( &fonts[2] ) )
- return 0;
- /* Small font 2 */
- fonts[FONT_SMALL2].has_colour_key = 1;
- fonts[FONT_SMALL2].width = 181.0f;
- fonts[FONT_SMALL2].height = 56.0f;
- fonts[FONT_SMALL2].letter_width = 9.0f;//180.0f/20.0f;
- fonts[FONT_SMALL2].letter_height = 11.0f;//55.0f/5.0f;
- fonts[FONT_SMALL2].letter_offset = 1.0f;
- fonts[FONT_SMALL2].texname = "sfont2.tga";
- fonts[FONT_SMALL2].texsize = 11883;//39644;
- fonts[FONT_SMALL2].char_offset = 0;//249;
- if( !init_font( &fonts[FONT_SMALL2] ) )
- return 0;
- /* Menu font */
- fonts[FONT_MENU].has_colour_key = 1;
- fonts[FONT_MENU].width = 258.0f;
- fonts[FONT_MENU].height = 99.0f;
- fonts[FONT_MENU].letter_width = 258.0f/16.0f;
- fonts[FONT_MENU].letter_height = 99.0f/6.0f;
- fonts[FONT_MENU].letter_offset = 6.0f;
- fonts[FONT_MENU].texname = "menufont.tga";
- fonts[FONT_MENU].texsize = 102199;
- if( !init_font( &fonts[FONT_MENU] ) )
- return 0;
- /* Violet font */
- fonts[FONT_BOLD].has_colour_key = 1;
- fonts[FONT_BOLD].width = 255.0f;
- fonts[FONT_BOLD].height = 109.0f;
- fonts[FONT_BOLD].letter_width = 255.0f/16.0f;
- fonts[FONT_BOLD].letter_height = 109.0f/6.0f;
- fonts[FONT_BOLD].letter_offset = 0.0f;
- fonts[FONT_BOLD].texname = "7X8B2.tga";
- fonts[FONT_BOLD].texsize = 111211;
- if( !init_font( &fonts[FONT_BOLD] ) )
- return 0;
- /* Steel font */
- fonts[FONT_STEEL].has_colour_key = 1;
- fonts[FONT_STEEL].width = 225.0f;
- fonts[FONT_STEEL].height = 79.0f;
- fonts[FONT_STEEL].letter_width = 225.0f/16.0f;
- fonts[FONT_STEEL].letter_height = 79.0f/6.0f;
- fonts[FONT_STEEL].letter_offset = 5.0f;
- fonts[FONT_STEEL].texname = "fsteel.tga";
- fonts[FONT_STEEL].texsize = 71144;
- if( !init_font( &fonts[FONT_STEEL] ) )
- return 0;
- return 1;
- }
- void uninit_fonts()
- {
- int i = 0;
- while( i < 7 )
- {
- uninit_font( &fonts[i] );
- i++;
- }
- }
- int init_splines( int stage )
- {
- /* Initialise splines for a given stage */
- char dir[32];
- int i = 0;
- struct _iobuf* fp = NULL;
- struct Vector2 p[32];
- sprintf( dir, "st%02d\\spline002.dat", stage );
- fp = fopen( dir, "rb" );
- if( !fp )
- return 0;
- fread( &spline.num_base_points, 1, sizeof( int ), fp );
- fread( &spline.tesselation, 1, sizeof( int ), fp );
- fread( p, 1, sizeof( struct Vector2 ) * spline.num_base_points, fp );
- fclose(fp);
- return create_spline( &spline, p, spline.num_base_points, spline.tesselation, 5.0f );
- }
- void uninit_splines()
- {
- delete_spline( &spline );
- }
- void reset_homing_blasts();
- void reset_fullautoblasts();
- int init_game()
- {
- /*if(AllocConsole())
- {
- freopen("CONOUT$", "wt", stdout);
- SetConsoleTitle(L"MyApp : Debug Console");
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
- }*/
- /* TEST: Initialize splines */
- if( !init_splines(0) )
- return 0;
- /* Seed random number generator */
- srand( time( NULL ) );
- /* Reset the player's dragon attributes */
- reset_dragon();
- /* Reset lock icons */
- reset_all_locks( FALSE );
- /* Reset all enemies */
- reset_enemies();
- /* Reset all homing blasts */
- reset_homing_blasts();
- /* Reset all fullauto blasts */
- reset_fullautoblasts();
- /* Reset explosions */
- memset( explosions, 0, sizeof( struct explosion_t ) );
- /* Reset powerups */
- reset_powerups();
- /* Reset smoke puffs */
- reset_smoke_puffs();
- /* Reset enemy shoots */
- reset_enemy_shoots();
- /* TEST: Boss */
- if( !boss_mode )
- init_boss(1);
- /* Set input type */
- set_input_type(0);
- /* Reset mouse position */
- center_mouse();
- /* Create a render target */
- render_target = create_texture_rectangle( 640, 480, 32 );
- if( !render_target )
- return 0;
- /* Initialize gold cache */
- if( !init_gold_cache( 2000 ) )
- return 0;
- /* Initialize textures */
- if( !init_textures() )
- return 0;
- /* Initialize sound effects */
- if( !init_soundfx() )
- return 0;
- /* Initialize fonts */
- if( !init_fonts() )
- return 0;
- /* Initialize menu data */
- if( !init_menus() )
- return 0;
- /* BGM test */
- if( !wavestream_open( "00.wav", &bgm ) )
- return 0;
- // wavestream_play(&bgm);
- return 1;
- }
- void uninit_game()
- {
- /* Uninit textures and sound effects */
- uninit_splines();
- wavestream_close(&bgm);
- uninit_menus();
- uninit_fonts();
- uninit_soundfx();
- uninit_textures();
- uninit_gold_cache();
- delete_textures( 1, &render_target );
- }
- void draw_background()
- {
- /* Draw the background image */
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_quad( get_texture( tex_files[background+2] ), 0.0f, 0.0f, 640.0f, 480.0f );
- disable_2d();
- }
- void draw_environment()
- {
- float tex[] = { 0.0f, 10.0f, 15.0f, 10.0f, 15.0f, 0.0f, 0.0f, 0.0f };
- static float h1 = 0;
- static float h2 = -480.0f;
- static int setup_trees_n_stuff = 0; /* Temporary */
- int i = 0;
- // static float tree_x = 160.0f;//(float) ( rand() % 320 );
- // static float tree_y = -121.0f;
- /* Place trees at random places */
- if( !setup_trees_n_stuff )
- {
- i = 0;
- setup_trees_n_stuff = 1;
- while( i < 8 )
- {
- trees[i].x = (float) ( rand() % ( 320 - 121 ) ) + 160;
- trees[i].y = (float) -( rand() % 480 ) + 121;
- i++;
- }
- }
- /* Draw the menu and ingame boundaries */
- enable_2d();
- /* First half of the scrolling effect */
- push_pos();
- translate( 640.0f/4.0f, h1 );
- set_colour( 0.0f, 0.0f, 0.0f, 1.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f/2.0f, 480.0f );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_quad2( get_texture( "grass1a" ), tex, 0.0f, 0.0f, 640.0f/2.0f, 480.0f );
- pop_pos();
- /* Second half of the scrolling effect */
- push_pos();
- translate( 640.0f/4.0f, h2 );
- // set_colour( 0.0f, 0.0f, 0.0f, 1.0f );
- // draw_quad( 0, 0.0f, 0.0f, 640.0f/2.0f, 480.0f );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_quad2( get_texture( "grass1a" ), tex, 0.0f, 0.0f, 640.0f/2.0f, 480.0f );
- pop_pos();
- push_pos();
- // translate( 640.0f/4.0f, 0.0f );
- transparent_blend( TRUE );
- i = 0;
- while( i < 8 )
- {
- draw_quad( get_texture( "palmtree" ), trees[i].x, trees[i].y, 101.0f, 121.0f );
- i++;
- }
- transparent_blend( FALSE );
- pop_pos();
- disable_2d();
- h1 += scroll_speed;
- h2 += scroll_speed;
- if( h1 >= 480.0f )
- h1 = 0.0f;
- if( h2 >= 0.0f )
- h2 = -480.0f;
- /* Update trees 'n stuff */
- if( setup_trees_n_stuff )
- {
- i = 0;
- while( i < 8 )
- {
- trees[i].y += scroll_speed;
- if( trees[i].y >= 480.0f )
- {
- trees[i].y = (float) -(( rand() % 480 ) + 121);
- trees[i].x = (float) (rand() % (320-121))+160;
- }
- i++;
- }
- }
- }
- void draw_boundaries()
- {
- float tex1[] = { 0.0f, 1.0f, 0.25f, 1.0f, 0.25f, 0.0f, 0.0f, 0.0f };
- float tex2[] = { 0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.75f, 0.0f };
- /* Draw the play area boundaries */
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Helps hide things outside of the game's boundaries */
- push_pos();
- draw_quad2( get_texture( tex_files[background+2] ), tex1, 0, 0, 160, 480 );
- translate( 480.0f, 0.0f );
- draw_quad2( get_texture( tex_files[background+2] ), tex2, 0, 0, 160, 480 );
- pop_pos();
- push_pos();
- translate( 640.0f/4.0f, 0.0f );
- draw_line( 0.0f, 0.0f, 0.0f, 480.0f );
- draw_line( 640.0f/2.0f+1.0f, 0.0f, 640.0f/2.0f+1.0f, 480.0f );
- pop_pos();
- disable_2d();
- }
- void get_attack_mode_changes()
- {
- static int change = 0;
- /* Change attack mode when the right mouse button is clicked */
- if( changefire_button_down() && !change )
- {
- change = 1;
- dragon.attack_mode = !dragon.attack_mode;
- /* If we are switching to full auto, release all locks on
- any targeted enemies since it will be of no use to us. */
- if( dragon.attack_mode == 0 )
- reset_all_locks( TRUE );
- }
- /* Only register one click */
- if( !changefire_button_down() && change )
- change = 0;
- }
- void draw_crosshair()
- {
- float size = dragon.attack_mode == 0 ? 128.0f : 64.0f;
- unsigned int ch_tex = dragon.attack_mode == 0 ?
- get_texture( "cross2" ) : get_texture( "cross1" );
- float x = ch.x;
- float y = ch.y;
- if( x < 160.0f )
- x = 160.0f;
- if( x > 480.0f )
- x = 480.0f;
- if( y < 0.0f )
- y = 0.0f;
- if( y > 480.0f )
- y = 480.0f;
- /* Draw the crosshair */
- enable_2d();
- transparent_blend( TRUE );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- translate( x-(size/2.0f), y-(size/2.0f) );
- draw_quad( ch_tex, 0.0f, 0.0f, size, size );
- transparent_blend( FALSE );
- disable_2d();
- }
- void acquire_new_locks()
- {
- /* Only check for locks when in lock mode */
- /* Don't check if we are using full auto */
- if( dragon.attack_mode == 1 )
- {
- int i = 0;
- /* Loop though the list of enemies and check for locks */
- while( i < MAX_ENEMIES )
- {
- /* Check all enemies that aren't dead and that don't already have a lock acquired */
- if( !enemies[i].dead && !enemies[i].dying && enemies[i].lock == -1 && shoot_button_down() )
- {
- /* Check to see of the crosshair has caught this enemy */
- if( ch.x > enemies[i].x-(enemies[i].sx/2.0f) && ch.x < enemies[i].x+(enemies[i].sx/2.0f) )
- {
- if( ch.y > enemies[i].y-(enemies[i].sy/2.0f) && ch.y < enemies[i].y+(enemies[i].sy/2.0f) )
- {
- /* We got a lock! Now check if there are any free locks */
- int lock = find_inactive_lock();
- if( lock != -1 )
- {
- /* We have a free lock! Release the shoot button and blow this sucker away! */
- enemies[i].lock = lock;
- locks[lock].owner = i;
- activate_lock( lock, enemies[i].x, enemies[i].y );
- play_sound_effect_static( &sfx[3], 0 );
- }
- }
- }
- }
- i++;
- }
- }
- }
- void reset_homing_blasts()
- {
- int i = 0;
- /* Reset all homing blasts */
- memset( homingblasts, 0, sizeof( struct homingblast_t ) * MAX_HOMINGBLASTS );
- while( i < MAX_HOMINGBLASTS )
- {
- homingblasts[i].target = -1;
- homingblasts[i].fade_timer = 200;
- homingblasts[i].sx = homingblasts[i].sy = 32.0f;
- i++;
- }
- }
- int active_homing_blasts()
- {
- int i = 0;
- int count = 0;
- /* Return the number of active homing blasts */
- while( i < MAX_HOMINGBLASTS )
- {
- if( homingblasts[i].target != -1 )
- count++;
- i++;
- }
- return count;
- }
- void ready_homing_blasts()
- {
- int i = 0;
- int j = 0;
- /* Assign each targetable entity a seperate homing blast to destroy it */
- /* Limit the number of homing blasts assigned to MAX_HOMINGBLASTS. */
- while( i < MAX_ENEMIES )
- {
- if( enemies[i].lock != -1 )
- {
- homingblasts[j].target = i;
- homingblasts[j].fade_timer = 200;
- homingblasts[j].x = dragon.x+(dragon.width/2.0f);
- homingblasts[j++].y = dragon.y+(dragon.height/2.0f);
- if( j == MAX_HOMINGBLASTS )
- break;
- }
- i++;
- }
- }
- void clamp_float( float* d, float min, float max )
- {
- if( *d < min )
- *d = min;
- if( *d > max )
- *d = max;
- }
- #if 0
- void test_track()
- {
- static struct Vector2 p = { 0.0f, 320.0f };
- static struct Vector2 v = { 0.0f, 0.0f };
- float angle_to_player = angle( p.x, p.y, dragon.x, dragon.y );
- float speed = 10.0f;
- v.x += cos(angle_to_player);
- v.y += sin(angle_to_player);
- clamp_float( &v.x, -speed, speed );
- clamp_float( &v.y, -speed, speed );
- p.x += v.x;
- p.y += v.y;
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- transparent_blend(TRUE);
- draw_quad( get_texture("hblast2"), p.x+(106.0f/2.0f), p.y+(149.0f/2.0f), 32.0f, 32.0f );
- transparent_blend(FALSE);
- disable_2d();
- }
- #endif
- void draw_homing_blasts()
- {
- int i = 0;
- /* Draw each active homing blast */
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- transparent_blend( TRUE );
- while( i < MAX_HOMINGBLASTS )
- {
- if( homingblasts[i].target != -1 )
- {
- draw_quad( get_texture( "hblast2" ),
- homingblasts[i].x-(homingblasts[i].sx/2.0f),
- homingblasts[i].y-(homingblasts[i].sy/2.0f),
- homingblasts[i].sx, homingblasts[i].sy );
- }
- i++;
- }
- transparent_blend( FALSE );
- disable_2d();
- }
- void update_homing_blasts()
- {
- int i = 0;
- while( i < MAX_HOMINGBLASTS )
- {
- if( homingblasts[i].target != -1 )
- {
- float angle_to_target = angle( homingblasts[i].x, homingblasts[i].y,
- enemies[homingblasts[i].target].x /*-(enemies[homingblasts[i].target].sx/2.0f)*/,
- enemies[homingblasts[i].target].y /*-(enemies[homingblasts[i].target].sy/2.0f)*/ );
- float speed = 10.0f;
- float cx = 0, cy = 0;
- homingblasts[i].vx += cos(angle_to_target);
- homingblasts[i].vy += sin(angle_to_target);
- #if 0
- clamp_float( &homingblasts[i].vx, -speed, speed );
- clamp_float( &homingblasts[i].vy, -speed, speed );
- #else
- cx = cos( angle_to_target );
- cy = sin( angle_to_target );
- // cx = (abs(cx));
- // cy = (abs(cy));
- clamp_float( &homingblasts[i].vx, -speed*cx, speed*cx );
- clamp_float( &homingblasts[i].vy, -speed*cy, speed*cy );
- #endif
- homingblasts[i].x += homingblasts[i].vx;
- homingblasts[i].y += homingblasts[i].vy;
- }
- /* If this homing blast expires, let it shrink and set it as inactive */
- if( --homingblasts[i].fade_timer <= 0 )
- {
- homingblasts[i].sx -= 0.5f;
- homingblasts[i].sy -= 0.5f;
- if( homingblasts[i].sx <= 1.0f )
- {
- homingblasts[i].target = -1;
- homingblasts[i].fade_timer = 200;
- homingblasts[i].sx = homingblasts[i].sy = 32.0f;
- }
- }
- i++;
- }
- }
- void check_homing_blasts_for_collisions()
- {
- int i = 0;
- /* Check each homing blast for a collision with an enemy. */
- /* If we get a hit, then mark the enemy as dead and the homing blast
- as inactive and stop updating it. */
- while( i < MAX_HOMINGBLASTS )
- {
- /* Is this homing blast even tracking anything? */
- if( homingblasts[i].target != -1 )
- {
- /* Looks like it is. Let's see if it hit anything! */
- /* The collision rect is (should be) a constant 32x32 pixels
- which is centered around the center of the targetable entity. */
- int j = 0;
- while( j < MAX_ENEMIES )
- {
- /* Target only living enemies */
- if( !enemies[j].dead && !enemies[j].dying )
- {
- /* Good, it's alive. Now, did we actually hit it? */
- if( homingblasts[i].x >= (enemies[j].x-(enemies[j].sx/2.0f)) &&
- homingblasts[i].x <= (enemies[j].x+(enemies[j].sx/2.0f)) &&
- homingblasts[i].y >= (enemies[j].y-(enemies[j].sy/2.0f)) &&
- homingblasts[i].y <= (enemies[j].y+(enemies[j].sy/2.0f)) )
- {
- /* Do 5 damage */
- enemies[j].energy -= 5;
- /* Is this enemy dead? */
- if( enemies[j].energy <= 0 )
- {
- /* Enemy zeppelin's don't die automatically */
- if( enemies[j].type == ENEMY_ZEPPELIN )
- enemies[j].dying = Yes;
- else
- {
- /* Katsu! */
- kill_enemy( &enemies[j], 7 );
- }
- }
- else
- {
- /* If not, just flash white for a frame */
- enemies[j].flash = Yes;
- }
- /* Let homing blast go */
- homingblasts[i].target = -1;
- homingblasts[i].fade_timer = 200;
- homingblasts[i].sx = homingblasts[i].sy = 32.0f;
- break;
- }
- }
- j++;
- }
- }
- i++;
- }
- }
- void reset_fullautoblasts()
- {
- /* Reset all full auto blasts */
- memset( fullautoblasts, 0, sizeof( struct fullautoblast_t ) * MAX_FULLAUTOBLASTS );
- }
- int find_inactive_fullautoblast()
- {
- int i = 0;
- /* Finds an inactive fullauto blast. If we find one, return that id number.
- If not, return -1 for a failure to find one */
- while( i < MAX_FULLAUTOBLASTS )
- {
- if( !fullautoblasts[i].active )
- return i;
- i++;
- }
- return -1;
- }
- void activate_fullautoblast( int id )
- {
- /* Activate full auto blast and initialize the variables that make it "go"! */
- fullautoblasts[id].active = Yes;
- fullautoblasts[id].x = dragon.x + (dragon.width/2.0f);
- fullautoblasts[id].y = dragon.y + (dragon.height/2.0f);
- fullautoblasts[id].size = ( overdrive_timer > 0 ) ? 64.0f : 32.0f;
- fullautoblasts[id].angle = angle( dragon.x+(dragon.width/2.0f), dragon.y+(dragon.height/2.0f),
- ch.x, ch.y );
- fullautoblasts[id].dirx = cos( fullautoblasts[id].angle );
- fullautoblasts[id].diry = sin( fullautoblasts[id].angle );
- fullautoblasts[id].speed = 15.0f;
- }
- void draw_fullautoblasts()
- {
- int i = 0;
- /* Draw each active fullauto blast */
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- transparent_blend( TRUE );
- while( i < MAX_FULLAUTOBLASTS )
- {
- if( fullautoblasts[i].active )
- {
- if( distance2d( fullautoblasts[i].x, fullautoblasts[i].y,
- dragon.x+(dragon.width/2.0f), dragon.y+(dragon.height/2.0f) ) > 15.0f )
- {
- draw_quad( get_texture( "hblast2" ),
- fullautoblasts[i].x - ( fullautoblasts[i].size/2.0f ),
- fullautoblasts[i].y - ( fullautoblasts[i].size/2.0f ),
- fullautoblasts[i].size, fullautoblasts[i].size );
- }
- }
- i++;
- }
- transparent_blend( FALSE );
- disable_2d();
- }
- void update_fullautoblasts()
- {
- int i = 0;
- /* Update each fullauto blast */
- while( i < MAX_FULLAUTOBLASTS )
- {
- /* Is this blast active ? */
- if( fullautoblasts[i].active )
- {
- /* If so, then move it in the desired direction */
- /* But before we do that, let's check to see if this blast is */
- /* beyond the boundaries, or if it hit anything */
- if( fullautoblasts[i].x <= 0 || fullautoblasts[i].x > 640 ||
- fullautoblasts[i].y <= 0 || fullautoblasts[i].y > 480 )
- {
- /* Out of bounds */
- fullautoblasts[i].active = No;
- }
- fullautoblasts[i].x += fullautoblasts[i].dirx * fullautoblasts[i].speed;
- fullautoblasts[i].y += fullautoblasts[i].diry * fullautoblasts[i].speed;
- }
- i++;
- }
- }
- void check_fullauto_blasts_for_collisions()
- {
- int i = 0;
- /* Check each fullauto blast for a collision with any enemies */
- while( i < MAX_FULLAUTOBLASTS )
- {
- /* Don't check any inactive ones */
- if( fullautoblasts[i].active )
- {
- /* If it is, check it against each active enemy */
- int j = 0;
- /* Check each enemy for a collision test */
- while( j < MAX_ENEMIES )
- {
- /* Is this enemy alive so we can kill it? */
- if( !enemies[j].dead && !enemies[j].dying )
- {
- /* It is, let's check to see if the full auto blast hit it */
- if( fullautoblasts[i].x >= (enemies[j].x-(enemies[j].sx/2.0f)) &&
- fullautoblasts[i].x <= (enemies[j].x+(enemies[j].sx/2.0f)) &&
- fullautoblasts[i].y >= (enemies[j].y-(enemies[j].sy/2.0f)) &&
- fullautoblasts[i].y <= (enemies[j].y+(enemies[j].sy/2.0f)) )
- {
- /* Do 1 damage for normal, 2 for overdrive */
- enemies[j].energy -= (overdrive_timer > 0) ? 2 : 1;
- /* Is this enemy dead? */
- if( enemies[j].energy <= 0 )
- {
- /* Enemy zeppelin's don't die automatically */
- if( enemies[j].type == ENEMY_ZEPPELIN )
- enemies[j].dying = Yes;
- else
- {
- /* Katsu! */
- kill_enemy( &enemies[j], 7 );
- }
- }
- else
- {
- /* If not, just flash white for a frame */
- enemies[j].flash = Yes;
- }
- /* Let fullauto blast go */
- fullautoblasts[i].active = No;
- }
- }
- j++;
- }
- }
- i++;
- }
- }
- void activate_explosion( int expl_id, float x, float y, int type )
- {
- explosions[expl_id].active = Yes;
- explosions[expl_id].frame = 0;
- explosions[expl_id].last_frame = 24;
- explosions[expl_id].timer = 0;
- explosions[expl_id].max_timer = 2;
- explosions[expl_id].x = x;
- explosions[expl_id].y = y;
- explosions[expl_id].sx = 320.0f / 5.0f;
- explosions[expl_id].sy = 320.0f / 5.0f;
- explosions[expl_id].type = type;
- }
- int find_inactive_explosion()
- {
- int i = 0;
- /* Find the first inactive explosion */
- while( i < MAX_EXPLOSIONS )
- {
- /* Is this explosion active? If so, go to the next one.
- If not, then return that explosion id. */
- if( !explosions[i].active )
- return i;
- i++;
- }
- return -1;
- }
- void render_explosions()
- {
- int i = 0;
- /* Render each active explosion */
- while( i < MAX_EXPLOSIONS )
- {
- /* Is this explosion active? */
- if( explosions[i].active )
- {
- /* Draw it! */
- draw_explosion( &explosions[i] );
- }
- i++;
- }
- }
- void update_explosions()
- {
- int i = 0;
- /* Update each active explosion */
- while( i < MAX_EXPLOSIONS )
- {
- /* Is this explosion active? */
- if( explosions[i].active )
- {
- /* Is it time to update this explosion? */
- if( ++explosions[i].timer >= explosions[i].max_timer )
- {
- /* Okay, let's move on to the next frame, then check if we reached
- the final frame. */
- explosions[i].timer = 0;
- if( ++explosions[i].frame >= explosions[i].last_frame )
- {
- /* Now that we have reached the last frame, set this explosion
- as inactive to be reused later */
- explosions[i].active = No;
- }
- }
- }
- i++;
- }
- }
- void reset_smoke_puffs()
- {
- memset( &smoke, 0, sizeof( struct smoke_t ) * MAX_SMOKE );
- }
- void add_smoke_puff( float x, float y, int type )
- {
- int i = 0;
- /* Search for an unused smoke puff */
- while( i < MAX_SMOKE )
- {
- /* Is this puff active? */
- if( !smoke[i].active )
- {
- /* Activate it */
- smoke[i].x = x;
- smoke[i].y = y;
- smoke[i].sx = smoke[i].sy = 4.0f;
- smoke[i].active = Yes;
- smoke[i].type = type;
- break;
- }
- i++;
- }
- }
- void draw_smoke_puffs()
- {
- int i = 0;
- /* Draw each smoke puff */
- enable_2d();
- transparent_blend(Yes);
- while( i < MAX_SMOKE )
- {
- if( smoke[i].active )
- {
- push_pos();
- translate( smoke[i].x, smoke[i].y ),
- rotate( smoke[i].rot );
- draw_quad( get_texture( "smoke" ), -(smoke[i].sx/2.0f), -(smoke[i].sy/2.0f), smoke[i].sx, smoke[i].sy );
- pop_pos();
- }
- i++;
- }
- transparent_blend(No);
- disable_2d();
- }
- void update_smoke_puffs()
- {
- int i = 0;
- /* Draw each smoke puff */
- while( i < MAX_SMOKE )
- {
- if( smoke[i].active )
- {
- /* Expand the size of this smoke puff */
- smoke[i].sx += 1.0f;
- smoke[i].sy += 1.0f;
- /* Rotate the smoke puff */
- smoke[i].rot += 0.5f;
- /* Move smoke puff according to it's movement type */
- if( smoke[i].type == SMOKEANIM_RISE )
- {
- smoke[i].y -= 1.0f;
- }
- /* Check for maximum size */
- if( smoke[i].sx >= 64.0f || smoke[i].sx >= 64.0f )
- smoke[i].active = No;
- }
- i++;
- }
- }
- void draw_player_dragon()
- {
- /* Update the dragon's position */
- // dragon.x += dragon.vx;
- // dragon.y += dragon.vy;
- static int flash = No;
- /* Draw the dragon sprite */
- if( !flash )
- {
- enable_2d();
- transparent_blend( TRUE );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- translate( dragon.x, dragon.y );
- draw_quad( get_texture( "dragon1" ), 0.0f, 0.0f, dragon.width, dragon.height );
- transparent_blend( FALSE );
- disable_2d();
- }
- if( dragon.inv_t > 0 )
- {
- dragon.inv_t--;
- flash = !flash;
- }
- else
- flash = No;
- }
- void draw_hud()
- {
- char string[64];
- /* Enable 2D drawing with colour key enabled */
- enable_2d();
- transparent_blend( TRUE );
- /* draw the health bar */
- push_pos();
- set_colour( 0.0f, 1.0f, 0.0f, 0.5f );
- translate( 160.0f, 480.0f - 50.0f );
- draw_quad( 0, 10.0f, 0, (float) dragon.energy, 8.0f );
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_line( 10.0f, 0.0f, (float) dragon.max_energy + 10.0f, 0.0f );
- draw_line( 10.0f, 8.0f, (float) dragon.max_energy + 10.0f, 8.0f );
- draw_line( 10.0f, 0.0f, 10.0f, 8.0f );
- draw_line( (float) dragon.max_energy + 10.0f, 0.0f, (float) dragon.max_energy + 10.0f, 8.0f );
- pop_pos();
- /* display player's score and attack mode*/
- push_pos();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- // translate( 640.0f/4.0f, 0.0f );
- sprintf( string, "SCORE: %d", score );
- draw_text( &fonts[FONT_STEEL], 640.0f/4.0f, 0, string );
- draw_text( &fonts[FONT_BOLD], 330.0f, 0,
- (dragon.attack_mode == 0) ? "FULL AUTO" : "HOMING" );
- pop_pos();
- /* draw the powerups obtained (crystals) */
- push_pos();
- transparent_blend( TRUE );
- translate( 165.0f, 480.0f - 38.0f );
- /* Special attack */
- if( dragon.powers[0] )
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- else
- set_colour( 1.0f, 1.0f, 1.0f, .5f );
- draw_quad( get_texture( "diamond1" ), 0, 0, 32.0f, 32.0f );
- /* Overdrive */
- if( dragon.powers[1] )
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- else
- set_colour( 1.0f, 1.0f, 1.0f, .5f );
- draw_quad( get_texture( "diamond2" ), 32.0f, 0, 32.0f, 32.0f );
- /* Barrier */
- if( dragon.powers[2] )
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- else
- set_colour( 1.0f, 1.0f, 1.0f, .5f );
- draw_quad( get_texture( "diamond3" ), 64.0f, 0, 32.0f, 32.0f );
- pop_pos();
- /* Disable 2D drawing and colour key */
- transparent_blend( FALSE );
- disable_2d();
- }
- int draw_shogun3d_logo()
- {
- static float a = 255.0f;
- static int timer = 0;
- int finished = 0;
- /* Enable 2D rendering */
- enable_2d();
- /* Draw the Shogun3D logo */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_quad( get_texture( "shogun3d" ), 0.0f, 0.0f, 640.0f, 480.0f );
- /* Draw the transparent quad over it to simulate fading in/out */
- transparent_blend( TRUE );
- set_colour( 0.0f, 0.0f, 0.0f, a/255.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f, 480.0f );
- transparent_blend( FALSE );
- /* Return to default colour (opaque white) */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Disable 2D rendering */
- disable_2d();
- /* Update timing and alpha values */
- if( timer != 200 && a > 0.0f )
- a -= 5.0f;
- if( a <= 0.0f && timer != 200 )
- timer++;
- if( timer >= 200 /*&& a < 255.0f*/ )
- a += 5.0f;
- if( timer >= 200 && a >= 255.0f )
- {
- timer = 0;
- finished = 1;
- }
- /* Return result */
- return finished;
- }
- int draw_purpose_disclaimer()
- {
- static float a = 255.0f;
- static int timer = 0;
- int finished = 0;
- /* Enable 2D rendering */
- enable_2d();
- /* Draw black backdrop quad */
- set_colour( 0.0f, 0.0f, 0.0f, 1.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f, 480.0f );
- /* Set base colour to white */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Tell the whole world who I did this for and why =) */
- draw_text( &fonts[2], 75, 200, "This game is a labour of love!" );
- draw_text( &fonts[2], 75, 232, " For Lady Mia..." );
- /* Draw some hearts to show her some love! */
- draw_quad( get_texture( "heart1" ), 50.0f, 200.0f, 32.0f, 32.0f );
- draw_quad( get_texture( "heart2" ), 560.0f, 200.0f, 32.0f, 32.0f );
- // draw_quad( get_texture( "heart" ), 180.0f, 232, 32.0f, 32.0f );
- // draw_quad( get_texture( "heart" ), 450.0f, 232, 32.0f, 32.0f );
- // draw_text( &fonts[3], 0, 10, "%" );
- // draw_text( &fonts[4], 0, 10, "LOVE YOU FOREVER!" );
- // set_colour( 1.0f, 1.0f, 0.0f, 1.0f );
- // draw_text( &fonts[5], 0, 10, "This is text..." );
- /* Draw the transparent quad over it to simulate fading in/out */
- #if 1
- transparent_blend( TRUE );
- set_colour( 0.0f, 0.0f, 0.0f, a/255.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f, 480.0f );
- transparent_blend( FALSE );
- #endif
- /* Return to default colour (opaque white) */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- /* Disable 2D rendering */
- disable_2d();
- #if 1
- /* Update timing and alpha values */
- if( timer != 200 && a > 0.0f )
- a -= 5.0f;
- if( a <= 0.0f && timer != 200 )
- timer++;
- if( timer >= 200 /*&& a < 255.0f*/ )
- a += 5.0f;
- if( timer >= 200 && a >= 255.0f )
- {
- timer = 0;
- finished = 1;
- }
- #endif
- /* Return result */
- return finished;
- }
- int draw_hero_intro()
- {
- const float end_x = 320.0f-125.0f;
- const float end_y = 240.0f-160.0f;
- static struct Vector2 blur_v[5];
- static float a = 255.0f;
- static float blur_a[5] = { (255.0f), (255.0f/2.0f), (255.0f/3.0f), (255.0f/4.0f), (255.0f/5.0f) };
- static int timer = 0;
- int finished = 0;
- static int first = 1;
- int i = 4;
- if( first )
- {
- play_sound_effect_static( &sfx[6], 0 );
- blur_v[0].x = end_x-(20.0f*20.0f); blur_v[0].y = end_y-(20.0f*20.0f);
- blur_v[1].x = end_x-(20.0f*22.0f), blur_v[1].y = end_y-(20.0f*22.0f);
- blur_v[2].x = end_x-(20.0f*24.0f), blur_v[2].y = end_y-(20.0f*24.0f);
- blur_v[3].x = end_x-(20.0f*26.0f), blur_v[3].y = end_y-(20.0f*26.0f);
- blur_v[4].x = end_x-(20.0f*28.0f), blur_v[4].y = end_y-(20.0f*28.0f);
- first = 0;
- }
- enable_2d();
- /* Draw white backdrop quad */
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f, 480.0f );
- transparent_blend( TRUE );
- /* Draw the image of the hero */
- while( i != -1 )
- {
- set_colour( 1.0f, 1.0f, 1.0f, (blur_a[i]/255.0f) );
- draw_quad( get_texture( "hero" ), blur_v[i].x, blur_v[i].y, 250.0f, 320.0f );
- if( blur_v[i].x < end_x )
- blur_v[i].x += 10.0f;
- if( blur_v[i].y < end_y )
- blur_v[i].y += 10.0f;
- i--;
- }
- /* Draw transparent foreground */
- set_colour( 1.0f, 1.0f, 1.0f, a/255.0f );
- draw_quad( 0, 0.0f, 0.0f, 640.0f, 480.0f );
- transparent_blend( FALSE );
- disable_2d();
- /* */
- if( a > 0.0f && timer == 0 )
- a -= 5.0f;
- if( a == 0.0f && timer != 50 )
- timer++;
- if( timer >= 50 )
- a += 5.0f;
- if( a >= 255.0f && timer >= 50 )
- {
- timer = 0;
- finished = 1;
- wavestream_play(&bgm);
- }
- return finished;
- }
- int do_fade( int fade_in )
- {
- int finished = No;
- extern float current_colour[4];
- /* Enable 2D rendering */
- enable_2d();
- if( fade_in )
- {
- static float a = 255.0f;
- transparent_blend(Yes);
- set_colour( current_colour[0], current_colour[0], current_colour[0], a/255.0f );
- draw_quad( 0, 160.0f, 0.0f, 320.0f, 480.0f );
- transparent_blend(No);
- a -= 5.0f;
- if( a < 0.0f )
- {
- a = 255.0f;
- finished = Yes;
- }
- }
- else
- {
- static float a = 0.0f;
- transparent_blend(Yes);
- set_colour( current_colour[0], current_colour[0], current_colour[0], a/255.0f );
- draw_quad( 0, 160.0f, 0.0f, 320.0f, 480.0f );
- transparent_blend(No);
- a += 5.0f;
- if( a > 255.0f )
- {
- a = 0.0f;
- finished = Yes;
- }
- }
- /* Disable 2D rendering */
- disable_2d();
- return finished;
- }
- int fade_out_bgm()
- {
- int finished = No;
- static float volume = 1.0f;
- /* Continually decrease bgm volume until it reaches 0 */
- /* Are we done yet? */
- if( volume < 0.0f )
- {
- /* Mark as finished */
- finished = Yes;
- volume = 1.0f;
- /* Close the current track */
- wavestream_close(&bgm);
- /* Are we loading a new track? */
- if( strcmp( "", bgm_next_track ) )
- {
- /* If so, open it and start playing */
- wavestream_open(bgm_next_track, &bgm);
- wavestream_play(&bgm);
- }
- else
- {
- /* If not, don't do a darn thing */
- }
- }
- else
- {
- wavestream_set_volume( &bgm, volume );
- volume -= 0.01f;
- }
- return finished;
- }
- #if 0
- /* Test code for target tracking */
- void clamp_float( float* d, float min, float max )
- {
- if( *d < min )
- *d = min;
- if( *d > max )
- *d = max;
- }
- void test_track()
- {
- static struct Vector2 p = { 0.0f, 320.0f };
- static struct Vector2 v = { 0.0f, 0.0f };
- float angle_to_player = angle( p.x, p.y, dragon.x, dragon.y );
- float speed = 10.0f;
- v.x += cos(angle_to_player);
- v.y += sin(angle_to_player);
- clamp_float( &v.x, -speed, speed );
- clamp_float( &v.y, -speed, speed );
- p.x += v.x;
- p.y += v.y;
- enable_2d();
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- transparent_blend(TRUE);
- draw_quad( get_texture("hblast2"), p.x+(106.0f/2.0f), p.y+(149.0f/2.0f), 32.0f, 32.0f );
- transparent_blend(FALSE);
- disable_2d();
- }
- #endif
- void adjust_framerate()
- {
- if( game_state == GAME_STATE_INGAME )
- {
- if( get_spf() > 150 )
- fps_limit = (int)(30.0f*((float)(game_speed/100.0f)));
- else
- fps_limit = (int)(60.0f*((float)(game_speed/100.0f)));;
- }
- else
- {
- fps_limit = 60;
- }
- }
- void render()
- {
- /* The background is displayed regardless of game state */
- draw_background();
- wavestream_update(&bgm);
- /* Input devices are updated regardless of game state */
- update_input_devices();
- switch( game_state )
- {
- case GAME_STATE_INTRO1:
- if( draw_shogun3d_logo() )
- game_state = GAME_STATE_INTRO2;
- break;
- case GAME_STATE_INTRO2:
- if( draw_purpose_disclaimer() )
- game_state = GAME_STATE_INTRO3;
- break;
- case GAME_STATE_INTRO3:
- if( draw_hero_intro() )
- game_state = GAME_STATE_MENU;
- break;
- case GAME_STATE_MENU:
- draw_menus();
- break;
- case GAME_STATE_INGAME:
- update_crosshair_position();
- draw_environment();
- draw_boss();
- update_boss();
- draw_enemies();
- render_explosions();
- draw_player_dragon();
- draw_active_locks();
- acquire_new_locks();
- update_active_locks();
- update_explosions();
- draw_homing_blasts();
- update_homing_blasts();
- draw_fullautoblasts();
- update_fullautoblasts();
- check_homing_blasts_for_collisions();
- check_fullauto_blasts_for_collisions();
- draw_enemy_shoots();
- update_enemy_shoots();
- draw_smoke_puffs();
- update_smoke_puffs();
- draw_powerups();
- update_powerups();
- draw_gold_peices();
- update_gold_peices();
- update_guard_if_activated(); /* Update guard first */
- draw_guard_if_activated();
- draw_hud();
- get_attack_mode_changes();
- handle_mouse_input();
- move_dragon();
- check_for_special_input();
- update_overdrive_if_active();
- draw_crosshair();
- /* Should be last */
- draw_boundaries();
- #if 0
- test_track();
- #endif
- if( ingame_fade == 0 ) /* Fade out */
- {
- if( do_fade(No) )
- ingame_fade = -1;
- }
- if( ingame_fade == 1 ) /* Fade in */
- {
- if( do_fade(Yes) )
- ingame_fade = -1;
- }
- adjust_framerate();
- break;
- case GAME_STATE_EXITING:
- uninit_game();
- PostQuitMessage(0);
- break;
- }
- /* If we are transitioning to a new level... */
- if( bgm_fade )
- {
- if( fade_out_bgm() )
- bgm_fade = No;
- }
- /* Copy the screen to a texture */
- /*copy_scene_to_texture( &render_target, 640, 480 );
- transparent_blend(No);
- set_colour( 1.0f, 1.0f, 1.0f, 1.0f );
- enable_2d();
- draw_quad( render_target, 0, 0, 320.0f, 240.0f );
- disable_2d();*/
- /* Disable vsync when ingame */
- /*enable_vsync( (game_state != GAME_STATE_INGAME) );*/
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement