2012-02-28 13:09:12 +01:00
/*! \file level.c
* \ brief Playable Level code .
*/
2012-03-04 13:32:42 +01:00
/*
* Copyright ( c ) Sebastian Krzyszkowiak < dos @ dosowisko . net >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
2012-02-22 12:43:14 +01:00
# include <stdio.h>
2012-04-06 17:28:38 +02:00
# include "moonwalk.h"
2012-04-06 18:25:04 +02:00
# include "config.h"
# include "pause.h"
2012-02-22 12:43:14 +01:00
# include "level.h"
2012-04-06 23:32:15 +02:00
# include "timeline.h"
2012-04-14 22:26:33 +02:00
/* TODO: check if spritesheet speed still depends on FPS */
2012-04-08 23:56:13 +02:00
2012-05-03 19:42:23 +02:00
void SelectDerpySpritesheet ( struct Game * game , char * name ) {
struct Spritesheet * tmp = game - > level . derpy_sheets ;
if ( ! tmp ) {
PrintConsole ( game , " ERROR: No spritesheets registered for Derpy! " ) ;
return ;
}
while ( tmp ) {
if ( ! strcmp ( tmp - > name , name ) ) {
PrintConsole ( game , " Selecting Derpy spritesheet: %s " , name ) ;
game - > level . derpy_sheet = & ( tmp - > bitmap ) ;
game - > level . sheet_rows = tmp - > rows ;
game - > level . sheet_cols = tmp - > cols ;
2012-05-08 13:22:56 +02:00
game - > level . sheet_blanks = tmp - > blanks ;
2012-05-03 19:42:23 +02:00
game - > level . sheet_speed_modifier = tmp - > speed ;
game - > level . sheet_pos = 0 ;
2012-05-10 12:21:53 +02:00
game - > level . sheet_scale = tmp - > scale ;
if ( game - > level . derpy ) al_destroy_bitmap ( game - > level . derpy ) ;
2012-05-08 13:22:56 +02:00
game - > level . derpy = al_create_bitmap ( al_get_display_height ( game - > display ) * 0.25 * tmp - > aspect * tmp - > scale , al_get_display_height ( game - > display ) * 0.25 * tmp - > scale ) ;
2012-05-03 19:42:23 +02:00
return ;
}
tmp = tmp - > next ;
}
PrintConsole ( game , " ERROR: No spritesheets registered for Derpy with given name: %s " , name ) ;
return ;
}
void RegisterDerpySpritesheet ( struct Game * game , char * name ) {
char filename [ 255 ] = { } ;
sprintf ( filename , " data/levels/derpy/%s.ini " , name ) ;
ALLEGRO_CONFIG * config = al_load_config_file ( filename ) ;
struct Spritesheet * s = malloc ( sizeof ( struct Spritesheet ) ) ;
s - > name = malloc ( ( strlen ( name ) + 1 ) * sizeof ( char ) ) ;
strcpy ( s - > name , name ) ;
s - > bitmap = NULL ;
s - > cols = atoi ( al_get_config_value ( config , " " , " cols " ) ) ;
s - > rows = atoi ( al_get_config_value ( config , " " , " rows " ) ) ;
2012-05-08 13:22:56 +02:00
s - > blanks = atoi ( al_get_config_value ( config , " " , " blanks " ) ) ;
2012-05-03 19:42:23 +02:00
s - > speed = atof ( al_get_config_value ( config , " " , " speed " ) ) ;
2012-05-08 13:22:56 +02:00
s - > aspect = atof ( al_get_config_value ( config , " " , " aspect " ) ) ;
s - > scale = atof ( al_get_config_value ( config , " " , " scale " ) ) ;
2012-05-03 19:42:23 +02:00
s - > next = game - > level . derpy_sheets ;
game - > level . derpy_sheets = s ;
al_destroy_config ( config ) ;
}
2012-04-06 18:25:04 +02:00
void Level_Passed ( struct Game * game ) {
if ( game - > level . current_level < 6 ) {
int available = atoi ( GetConfigOptionDefault ( " MuffinAttack " , " level " , " 1 " ) ) ;
available + + ;
if ( ( available < 2 ) | | ( available > 7 ) ) available = 1 ;
if ( available = = ( game - > level . current_level + 1 ) ) {
char * text = malloc ( 2 * sizeof ( char ) ) ;
sprintf ( text , " %d " , available ) ;
SetConfigOption ( " MuffinAttack " , " level " , text ) ;
free ( text ) ;
}
} else {
SetConfigOption ( " MuffinAttack " , " completed " , " 1 " ) ;
}
}
2012-04-08 19:01:30 +02:00
bool Accelerate ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
2012-05-18 13:12:58 +02:00
game - > level . speed + = 0.000015 ;
if ( game - > level . speed < 0.0025 ) return false ;
2012-04-08 23:25:14 +02:00
return true ;
}
bool Walk ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
2012-05-03 19:42:23 +02:00
if ( state = = TM_ACTIONSTATE_INIT ) action - > arguments = NULL ;
2012-04-08 23:25:14 +02:00
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
2012-05-03 19:42:23 +02:00
if ( ! ( action - > arguments ) ) SelectDerpySpritesheet ( game , " walk " ) ;
action - > arguments + + ;
2012-04-09 13:31:14 +02:00
game - > level . derpy_x + = tps ( game , 60 * 0.001 ) ;
2012-04-08 23:25:14 +02:00
if ( game - > level . derpy_x < 0.05 ) return false ;
return true ;
}
bool Move ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
2012-05-07 14:56:32 +02:00
game - > level . speed = 0.00035 ;
2012-04-08 23:25:14 +02:00
if ( game - > level . st_pos < 0.275 ) return false ;
return true ;
}
2012-05-09 10:58:45 +02:00
bool ShowMeter ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
2012-05-09 12:40:21 +02:00
game - > level . meter_alpha + = tps ( game , 60 * 4 ) ;
2012-05-09 10:58:45 +02:00
if ( game - > level . meter_alpha > = 255 ) {
game - > level . meter_alpha = 255 ;
return true ;
}
return false ;
}
2012-04-08 23:25:14 +02:00
bool Fly ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
2012-05-03 19:42:23 +02:00
if ( state = = TM_ACTIONSTATE_INIT ) action - > arguments = NULL ;
2012-04-08 23:25:14 +02:00
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
2012-05-09 10:58:45 +02:00
if ( ! ( action - > arguments ) ) {
SelectDerpySpritesheet ( game , " fly " ) ;
game - > level . flying = true ;
TM_AddBackgroundAction ( & ShowMeter , NULL , 0 , " showmeter " ) ;
}
2012-05-03 19:42:23 +02:00
action - > arguments + + ;
2012-04-09 13:31:14 +02:00
game - > level . derpy_y - = tps ( game , 60 * 0.004 ) ;
2012-04-08 23:25:14 +02:00
if ( game - > level . derpy_y > 0.2 ) return false ;
2012-04-08 23:41:22 +02:00
game - > level . handle_input = true ;
2012-04-08 23:25:14 +02:00
return true ;
}
2012-05-03 02:19:55 +02:00
void Obst_MoveUpDown ( struct Game * game , struct Obstracle * obstracle ) {
if ( obstracle - > data ) {
obstracle - > y - = 0.5 ;
if ( obstracle - > y < = 0 ) {
obstracle - > data = NULL ;
}
} else {
obstracle - > y + = 0.5 ;
if ( obstracle - > y > = 100 ) {
obstracle - > data + + ;
}
}
}
2012-05-01 22:52:30 +02:00
bool GenerateObstracles ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
/*float* tmp; bool* in;*/
int * count ;
if ( ! action - > arguments ) {
action - > arguments = TM_AddToArgs ( action - > arguments , malloc ( sizeof ( int ) ) ) ;
/* action->arguments = TM_AddToArgs(action->arguments, malloc(sizeof(bool))); */
}
count = ( int * ) action - > arguments - > value ;
/*tmp = (float*)action->arguments->value;
in = ( bool * ) action - > arguments - > next - > value ; */
if ( state = = TM_ACTIONSTATE_INIT ) {
* count = 0 ;
/* *tmp = 0;
* in = true ; */
}
else if ( state = = TM_ACTIONSTATE_RUNNING ) {
2012-05-18 13:12:58 +02:00
if ( rand ( ) % ( 10000 / ( int ) tps ( game , 60 * 100 ) ) < = 1 ) {
2012-05-01 22:52:30 +02:00
PrintConsole ( game , " OBSTRACLE %d " , * count ) ;
( * count ) + + ;
struct Obstracle * obst = malloc ( sizeof ( struct Obstracle ) ) ;
obst - > prev = NULL ;
obst - > x = 100 ;
obst - > y = ( rand ( ) % 91 ) - 1 ;
obst - > speed = 0 ;
2012-05-18 13:12:58 +02:00
obst - > points = - 10 ;
obst - > hit = false ;
2012-05-03 13:20:25 +02:00
obst - > bitmap = & ( game - > level . obst_bmps . pie ) ;
2012-05-01 22:52:30 +02:00
obst - > callback = NULL ;
2012-05-07 20:17:35 +02:00
obst - > data = ( void * ) ( rand ( ) % 2 ) ;
2012-05-03 02:19:55 +02:00
if ( rand ( ) % 100 < = 50 ) obst - > callback = Obst_MoveUpDown ;
2012-05-01 22:52:30 +02:00
if ( game - > level . obstracles ) {
game - > level . obstracles - > prev = obst ;
obst - > next = game - > level . obstracles ;
} else {
obst - > next = NULL ;
}
game - > level . obstracles = obst ;
if ( * count > 64 ) return true ;
}
} else {
free ( action - > arguments - > value ) ;
TM_DestroyArgs ( action - > arguments ) ;
action - > arguments = NULL ;
}
return false ;
}
2012-04-08 23:25:14 +02:00
bool Stop ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
game - > level . speed = 0 ;
2012-05-03 19:42:23 +02:00
SelectDerpySpritesheet ( game , " stand " ) ;
/*game->level.sheet_speed = 0;*/
2012-04-08 19:01:30 +02:00
return true ;
}
2012-04-09 16:21:45 +02:00
bool Letter ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
if ( state ! = TM_ACTIONSTATE_RUNNING ) return false ;
al_draw_text_with_shadow ( game - > menu . font_title , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) * 0.5 , al_get_display_height ( game - > display ) * 0.45 , ALLEGRO_ALIGN_CENTRE , " Letter from Twilight " ) ;
struct ALLEGRO_KEYBOARD_STATE keyboard ;
al_get_keyboard_state ( & keyboard ) ;
if ( al_key_down ( & keyboard , ALLEGRO_KEY_ENTER ) ) {
return true ;
}
return false ;
}
2012-02-22 12:43:14 +01:00
void Level_Draw ( struct Game * game ) {
2012-05-07 20:17:35 +02:00
if ( ! al_get_sample_instance_playing ( game - > level . music ) & & ( game - > loadstate = = GAMESTATE_LEVEL ) ) {
2012-04-09 15:25:56 +02:00
al_set_sample_instance_playing ( game - > level . music , true ) ;
al_set_sample_instance_position ( game - > level . music , game - > level . music_pos ) ;
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Draw ( game ) ;
else {
2012-05-07 20:17:35 +02:00
2012-04-09 15:58:01 +02:00
struct ALLEGRO_KEYBOARD_STATE keyboard ;
al_get_keyboard_state ( & keyboard ) ;
if ( game - > level . handle_input ) {
if ( al_key_down ( & keyboard , ALLEGRO_KEY_UP ) ) {
2012-05-18 13:12:58 +02:00
game - > level . derpy_y - = tps ( game , 60 * 0.0075 ) ;
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-05-07 20:17:35 +02:00
}
2012-04-09 15:58:01 +02:00
if ( al_key_down ( & keyboard , ALLEGRO_KEY_DOWN ) ) {
2012-05-18 13:12:58 +02:00
game - > level . derpy_y + = tps ( game , 60 * 0.0075 ) ;
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-04-09 15:58:01 +02:00
}
2012-05-18 13:12:58 +02:00
/*if ((game->level.derpy_y > 0.6) && (game->level.flying)) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet ( game , " run " ) ;
game - > level . flying = false ;
game - > level . sheet_speed = tps ( game , 60 * 0.0020 / game - > level . speed ) ;
}
2012-05-10 12:21:53 +02:00
else if ( ( game - > level . derpy_y < = 0.6 ) & & ( ! game - > level . flying ) ) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet ( game , " fly " ) ;
game - > level . flying = true ;
game - > level . sheet_speed = tps ( game , 60 * 2.4 ) ;
2012-05-18 13:12:58 +02:00
} */
2012-05-08 13:22:56 +02:00
if ( ! game - > level . flying ) game - > level . sheet_speed = tps ( game , 60 * 0.0020 / game - > level . speed ) ;
2012-04-09 16:14:10 +02:00
if ( game - > level . derpy_y < 0 ) game - > level . derpy_y = 0 ;
2012-05-10 12:21:53 +02:00
else if ( game - > level . derpy_y > 0.8 ) game - > level . derpy_y = 0.8 ;
2012-04-09 15:58:01 +02:00
}
2012-05-04 02:13:46 +02:00
al_hold_bitmap_drawing ( true ) ;
2012-05-07 20:17:35 +02:00
2012-04-08 19:01:30 +02:00
al_draw_bitmap ( game - > level . clouds , ( - game - > level . cl_pos ) * al_get_bitmap_width ( game - > level . clouds ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . clouds , ( 1 + ( - game - > level . cl_pos ) ) * al_get_bitmap_width ( game - > level . clouds ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . background , ( - game - > level . bg_pos ) * al_get_bitmap_width ( game - > level . background ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . background , ( 1 + ( - game - > level . bg_pos ) ) * al_get_bitmap_width ( game - > level . background ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . stage , ( - game - > level . st_pos ) * al_get_bitmap_width ( game - > level . stage ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . stage , ( 1 + ( - game - > level . st_pos ) ) * al_get_bitmap_width ( game - > level . stage ) , 0 , 0 ) ;
2012-05-07 20:17:35 +02:00
2012-05-03 02:49:08 +02:00
int derpyx = game - > level . derpy_x * al_get_display_width ( game - > display ) ;
int derpyy = game - > level . derpy_y * al_get_display_height ( game - > display ) ;
int derpyw = al_get_bitmap_width ( game - > level . derpy ) ;
int derpyh = al_get_bitmap_height ( game - > level . derpy ) ;
bool colision = false ;
2012-05-01 22:52:30 +02:00
struct Obstracle * tmp = game - > level . obstracles ;
while ( tmp ) {
/*PrintConsole(game, "DRAWING %f %f", tmp->x, tmp->y);*/
if ( tmp - > x > - 10 ) {
2012-05-03 02:49:08 +02:00
int x = ( tmp - > x / 100.0 ) * al_get_display_width ( game - > display ) ;
int y = ( tmp - > y / 100.0 ) * al_get_display_height ( game - > display ) ;
2012-05-03 13:20:25 +02:00
int w = al_get_bitmap_width ( * ( tmp - > bitmap ) ) ;
int h = al_get_bitmap_height ( * ( tmp - > bitmap ) ) ;
2012-05-18 13:12:58 +02:00
if ( ! tmp - > hit )
if ( ( ( ( x > = derpyx + 0.36 * derpyw ) & & ( x < = derpyx + 0.94 * derpyw ) ) | | ( ( x + w > = derpyx + 0.36 * derpyw ) & & ( x + w < = derpyx + 0.94 * derpyw ) ) ) & &
( ( ( y > = derpyy + 0.26 * derpyh ) & & ( y < = derpyy + 0.76 * derpyh ) ) | | ( ( y + h > = derpyy + 0.26 * derpyh ) & & ( y + h < = derpyy + 0.76 * derpyh ) ) ) ) {
tmp - > hit = true ;
game - > level . hp + = tps ( game , 60 * 0.0002 * tmp - > points ) ;
}
al_draw_bitmap ( * ( tmp - > bitmap ) , x , y , 0 ) ;
if ( tmp - > hit ) colision = true ;
2012-05-07 14:56:32 +02:00
tmp - > x - = tps ( game , game - > level . speed * 60 ) * 310 ;
2012-05-03 02:19:55 +02:00
if ( tmp - > callback ) tmp - > callback ( game , tmp ) ;
2012-05-03 02:49:08 +02:00
tmp = tmp - > next ;
2012-05-01 22:52:30 +02:00
} else {
2012-05-03 02:49:08 +02:00
if ( tmp - > next )
tmp - > next - > prev = tmp - > prev ;
if ( tmp - > prev )
tmp - > prev - > next = tmp - > next ;
else
game - > level . obstracles = tmp - > next ;
struct Obstracle * t = tmp ;
tmp = tmp - > next ;
free ( t ) ;
2012-05-01 22:52:30 +02:00
}
}
2012-05-18 13:12:58 +02:00
if ( colision ) game - > level . hp - = tps ( game , 60 * 0.002 ) ;
2012-05-04 02:13:46 +02:00
al_hold_bitmap_drawing ( false ) ;
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
al_set_target_bitmap ( game - > level . derpy ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2012-05-03 19:42:23 +02:00
al_draw_bitmap_region ( * ( game - > level . derpy_sheet ) , al_get_bitmap_width ( game - > level . derpy ) * ( game - > level . sheet_pos % game - > level . sheet_cols ) , al_get_bitmap_height ( game - > level . derpy ) * ( game - > level . sheet_pos / game - > level . sheet_cols ) , al_get_bitmap_width ( game - > level . derpy ) , al_get_bitmap_height ( game - > level . derpy ) , 0 , 0 , 0 ) ;
2012-05-03 19:59:53 +02:00
if ( ( game - > level . sheet_speed ) & & ( game - > level . sheet_speed_modifier ) ) {
2012-04-14 22:26:33 +02:00
game - > level . sheet_tmp + = tps ( game , 60 ) ;
2012-05-03 19:59:53 +02:00
if ( game - > level . sheet_tmp > = game - > level . sheet_speed / game - > level . sheet_speed_modifier ) {
2012-04-14 22:26:33 +02:00
game - > level . sheet_pos + + ;
game - > level . sheet_tmp = 0 ;
}
2012-05-08 13:22:56 +02:00
if ( game - > level . sheet_pos > = game - > level . sheet_cols * game - > level . sheet_rows - game - > level . sheet_blanks ) game - > level . sheet_pos = 0 ;
2012-04-08 23:25:14 +02:00
}
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-05-04 02:13:46 +02:00
al_hold_bitmap_drawing ( true ) ;
2012-05-08 13:22:56 +02:00
al_draw_tinted_bitmap ( game - > level . derpy , al_map_rgba ( 255 , 255 - colision * 255 , 255 - colision * 255 , 255 ) , derpyx + al_get_display_width ( game - > display ) * 0.1953125 - al_get_bitmap_width ( game - > level . derpy ) , derpyy , 0 ) ;
2012-05-04 01:12:19 +02:00
2012-04-08 19:01:30 +02:00
al_draw_bitmap ( game - > level . foreground , ( - game - > level . fg_pos ) * al_get_bitmap_width ( game - > level . foreground ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . foreground , ( 1 + ( - game - > level . fg_pos ) ) * al_get_bitmap_width ( game - > level . foreground ) , 0 , 0 ) ;
2012-05-04 01:12:19 +02:00
2012-04-08 19:01:30 +02:00
if ( game - > level . speed > 0 ) {
2012-05-07 14:56:32 +02:00
game - > level . cl_pos + = tps ( game , 60 * game - > level . speed ) * 0.2 ;
game - > level . bg_pos + = tps ( game , 60 * game - > level . speed ) * 0.6 ;
game - > level . st_pos + = tps ( game , 60 * game - > level . speed ) * 1 ;
game - > level . fg_pos + = tps ( game , 60 * game - > level . speed ) * 1.75 ;
2012-04-09 18:11:09 +02:00
if ( game - > level . bg_pos > = 1 ) game - > level . bg_pos = game - > level . bg_pos - 1 ;
if ( game - > level . st_pos > = 1 ) game - > level . st_pos = game - > level . st_pos - 1 ;
if ( game - > level . fg_pos > = 1 ) game - > level . fg_pos = game - > level . fg_pos - 1 ;
2012-04-08 19:01:30 +02:00
}
2012-04-09 18:11:09 +02:00
game - > level . cl_pos + = tps ( game , 60 * 0.00005 ) ;
if ( game - > level . cl_pos > = 1 ) game - > level . cl_pos = game - > level . cl_pos - 1 ;
2012-05-04 02:13:46 +02:00
al_hold_bitmap_drawing ( false ) ;
2012-05-07 20:17:35 +02:00
2012-05-09 10:58:45 +02:00
al_set_target_bitmap ( game - > level . meter_bmp ) ;
2012-05-09 12:40:21 +02:00
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2012-05-17 00:18:19 +02:00
al_draw_filled_rounded_rectangle ( al_get_bitmap_width ( game - > level . meter_bmp ) * 0.1 , al_get_bitmap_height ( game - > level . meter_bmp ) * 0.3 , al_get_bitmap_width ( game - > level . meter_bmp ) , al_get_bitmap_height ( game - > level . meter_bmp ) * 0.7 ,
7.5 , 7.5 , al_map_rgb ( 232 , 234 , 239 ) ) ;
al_draw_horizontal_gradient_rect ( al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 , al_get_display_width ( game - > display ) * 0.215 * 0.975 , al_get_display_height ( game - > display ) * 0.025 , al_map_rgb ( 150 , 159 , 182 ) , al_map_rgb ( 130 , 139 , 162 ) ) ;
al_draw_filled_rectangle ( al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 , al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 + ( al_get_display_width ( game - > display ) * 0.215 * 0.975 ) * game - > level . hp , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 + al_get_display_height ( game - > display ) * 0.025 , al_map_rgb ( 214 , 172 , 55 ) ) ;
2012-05-09 12:40:21 +02:00
al_draw_bitmap ( game - > level . meter_image , 0 , 0 , 0 ) ;
2012-05-09 10:58:45 +02:00
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-05-17 00:18:19 +02:00
2012-05-09 12:40:21 +02:00
al_draw_tinted_bitmap ( game - > level . meter_bmp , al_map_rgba ( game - > level . meter_alpha , game - > level . meter_alpha , game - > level . meter_alpha , game - > level . meter_alpha ) , al_get_display_width ( game - > display ) * 0.95 - al_get_bitmap_width ( game - > level . meter_bmp ) , al_get_display_height ( game - > display ) * 0.975 - al_get_bitmap_height ( game - > level . meter_bmp ) , 0 ) ;
2012-05-09 10:58:45 +02:00
2012-04-06 23:32:15 +02:00
TM_Process ( ) ;
2012-04-06 18:25:04 +02:00
}
2012-02-22 12:43:14 +01:00
}
2012-04-07 13:33:04 +02:00
bool FadeIn ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
2012-05-07 20:17:35 +02:00
if ( ! action - > arguments ) {
2012-04-07 20:32:47 +02:00
action - > arguments = TM_AddToArgs ( action - > arguments , malloc ( sizeof ( float ) ) ) ;
action - > arguments = TM_AddToArgs ( action - > arguments , ( void * ) al_create_bitmap ( al_get_display_width ( game - > display ) , al_get_display_height ( game - > display ) ) ) ;
2012-04-07 13:33:04 +02:00
}
float * fadeloop ;
ALLEGRO_BITMAP * fade_bitmap ;
fadeloop = ( float * ) action - > arguments - > value ;
fade_bitmap = ( ALLEGRO_BITMAP * ) action - > arguments - > next - > value ;
if ( state = = TM_ACTIONSTATE_INIT ) {
* fadeloop = 255 ;
al_set_target_bitmap ( fade_bitmap ) ;
al_clear_to_color ( al_map_rgb ( 0 , 0 , 0 ) ) ;
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
} else if ( state = = TM_ACTIONSTATE_RUNNING ) {
al_draw_tinted_bitmap ( fade_bitmap , al_map_rgba_f ( 1 , 1 , 1 , * fadeloop / 255.0 ) , 0 , 0 , 0 ) ;
* fadeloop - = tps ( game , 600 ) ;
if ( * fadeloop < = 0 ) return true ;
} else {
al_destroy_bitmap ( fade_bitmap ) ;
free ( fadeloop ) ;
2012-04-07 18:32:47 +02:00
TM_DestroyArgs ( action - > arguments ) ;
2012-04-07 18:41:39 +02:00
action - > arguments = NULL ;
2012-04-09 15:25:56 +02:00
al_play_sample_instance ( game - > level . music ) ;
2012-04-07 13:33:04 +02:00
}
return false ;
}
bool FadeOut ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
2012-05-07 20:17:35 +02:00
if ( ! action - > arguments ) {
2012-04-07 20:32:47 +02:00
action - > arguments = TM_AddToArgs ( action - > arguments , malloc ( sizeof ( float ) ) ) ;
action - > arguments = TM_AddToArgs ( action - > arguments , ( void * ) al_create_bitmap ( al_get_display_width ( game - > display ) , al_get_display_height ( game - > display ) ) ) ;
2012-04-07 13:33:04 +02:00
}
float * fadeloop ;
ALLEGRO_BITMAP * fade_bitmap ;
fadeloop = ( float * ) action - > arguments - > value ;
fade_bitmap = ( ALLEGRO_BITMAP * ) action - > arguments - > next - > value ;
if ( state = = TM_ACTIONSTATE_INIT ) {
* fadeloop = 0 ;
al_set_target_bitmap ( fade_bitmap ) ;
al_clear_to_color ( al_map_rgb ( 0 , 0 , 0 ) ) ;
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
} else if ( state = = TM_ACTIONSTATE_RUNNING ) {
al_draw_tinted_bitmap ( fade_bitmap , al_map_rgba_f ( 1 , 1 , 1 , * fadeloop / 255.0 ) , 0 , 0 , 0 ) ;
* fadeloop + = tps ( game , 600 ) ;
if ( * fadeloop > = 256 ) return true ;
} else {
al_destroy_bitmap ( fade_bitmap ) ;
free ( fadeloop ) ;
Level_Unload ( game ) ;
game - > gamestate = GAMESTATE_LOADING ;
game - > loadstate = GAMESTATE_MAP ;
2012-04-07 18:32:47 +02:00
TM_DestroyArgs ( action - > arguments ) ;
2012-04-07 18:41:39 +02:00
action - > arguments = NULL ;
2012-04-07 13:33:04 +02:00
}
return false ;
}
2012-04-08 23:25:14 +02:00
bool Welcome ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
float * tmp ; bool * in ;
2012-05-07 20:17:35 +02:00
if ( ! action - > arguments ) {
2012-04-08 23:25:14 +02:00
action - > arguments = TM_AddToArgs ( action - > arguments , malloc ( sizeof ( float ) ) ) ;
action - > arguments = TM_AddToArgs ( action - > arguments , malloc ( sizeof ( bool ) ) ) ;
2012-04-07 13:04:55 +02:00
}
2012-04-08 23:25:14 +02:00
tmp = ( float * ) action - > arguments - > value ;
in = ( bool * ) action - > arguments - > next - > value ;
2012-04-07 13:04:55 +02:00
if ( state = = TM_ACTIONSTATE_INIT ) {
* tmp = 0 ;
2012-04-08 23:25:14 +02:00
* in = true ;
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "WELCOME INIT");*/
2012-04-07 13:04:55 +02:00
}
2012-04-08 23:25:14 +02:00
else if ( state = = TM_ACTIONSTATE_RUNNING ) {
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "WELCOME RUNNING FADE=%f, IN=%d", *in); */
2012-05-04 03:17:18 +02:00
float fade = * tmp ;
2012-04-08 23:25:14 +02:00
if ( fade > 255 ) fade = 255 ;
2012-04-09 15:25:56 +02:00
if ( * tmp > 2048 ) { * tmp = 255 ; * in = false ; }
2012-04-08 23:25:14 +02:00
al_draw_tinted_bitmap ( game - > level . welcome , al_map_rgba_f ( fade / 255.0 , fade / 255.0 , fade / 255.0 , fade / 255.0 ) , 0 , 0 , 0 ) ;
if ( * in ) {
* tmp + = tps ( game , 600 ) ;
} else {
* tmp - = tps ( game , 600 ) ;
if ( * tmp < = 0 ) { return true ; }
}
2012-04-07 13:33:04 +02:00
} else {
2012-04-08 23:25:14 +02:00
free ( action - > arguments - > value ) ;
free ( action - > arguments - > next - > value ) ;
2012-04-07 18:32:47 +02:00
TM_DestroyArgs ( action - > arguments ) ;
2012-04-07 18:41:39 +02:00
action - > arguments = NULL ;
2012-04-07 13:04:55 +02:00
}
2012-04-06 23:32:15 +02:00
return false ;
}
2012-04-08 23:25:14 +02:00
bool PassLevel ( struct Game * game , struct TM_Action * action , enum TM_ActionState state ) {
2012-04-07 13:04:55 +02:00
if ( state = = TM_ACTIONSTATE_DESTROY ) {
Level_Passed ( game ) ;
2012-04-09 17:17:16 +02:00
TM_AddBackgroundAction ( & FadeOut , NULL , 0 , " fadeout " ) ;
2012-04-07 13:04:55 +02:00
}
2012-04-06 23:32:15 +02:00
return true ;
}
2012-02-22 12:43:14 +01:00
void Level_Load ( struct Game * game ) {
2012-05-17 00:18:19 +02:00
game - > level . hp = 1 ;
2012-04-08 19:01:30 +02:00
game - > level . cl_pos = 0 ;
game - > level . bg_pos = 0 ;
game - > level . fg_pos = 0.2 ;
game - > level . st_pos = 0.1 ;
2012-04-08 23:25:14 +02:00
game - > level . speed = 0 ;
game - > level . derpy_x = - 0.2 ;
game - > level . derpy_y = 0.6 ;
2012-05-08 13:22:56 +02:00
game - > level . sheet_speed = tps ( game , 60 * 2.4 ) ;
2012-04-08 23:25:14 +02:00
game - > level . sheet_tmp = 0 ;
2012-04-08 23:41:22 +02:00
game - > level . handle_input = false ;
2012-05-01 22:52:30 +02:00
game - > level . obstracles = NULL ;
2012-05-08 13:22:56 +02:00
game - > level . flying = false ;
2012-05-09 10:58:45 +02:00
game - > level . meter_alpha = 0 ;
2012-04-06 23:32:15 +02:00
al_clear_to_color ( al_map_rgb ( 0 , 0 , 0 ) ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Load ( game ) ;
2012-04-06 23:32:15 +02:00
else {
TM_Init ( game ) ;
2012-04-09 17:17:16 +02:00
TM_AddBackgroundAction ( & FadeIn , NULL , 0 , " fadein " ) ;
2012-04-08 23:25:14 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddQueuedBackgroundAction ( & Welcome , NULL , 0 , " welcome " ) ;
2012-04-09 15:25:56 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddAction ( & Walk , NULL , " walk " ) ;
TM_AddAction ( & Move , NULL , " move " ) ;
TM_AddAction ( & Stop , NULL , " stop " ) ;
2012-04-09 16:21:45 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddAction ( & Letter , NULL , " letter " ) ;
2012-05-18 13:12:58 +02:00
TM_AddDelay ( 200 ) ;
2012-04-09 17:17:16 +02:00
TM_AddQueuedBackgroundAction ( & Accelerate , NULL , 0 , " accelerate " ) ;
TM_AddAction ( & Fly , NULL , " fly " ) ;
2012-05-18 13:12:58 +02:00
/*TM_AddDelay(2*1000);*/
2012-04-14 22:26:33 +02:00
/* first part gameplay goes here */
2012-04-30 00:55:27 +02:00
/* actions for generating obstracles should go here
* probably as regular actions . When one ends , harder one
* begins . After last one part with muffins starts .
* Should obstracles themselves be handled as objects
* on timeline ? ( probably not ) . Hmm . . . */
2012-05-01 22:52:30 +02:00
TM_AddAction ( & GenerateObstracles , NULL , " obstracles " ) ;
TM_AddDelay ( 5 * 1000 ) ;
2012-04-08 23:25:14 +02:00
2012-04-14 22:26:33 +02:00
/*
// wings disappear, deccelerate, fall down
2012-04-08 23:25:14 +02:00
// run
// show Fluttershy's house
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
// second part gameplay goes here
//
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
// cutscene goes here
//
2012-04-14 22:26:33 +02:00
*/
2012-05-07 20:17:35 +02:00
2012-04-09 17:17:16 +02:00
TM_AddAction ( & PassLevel , NULL , " passlevel " ) ;
2012-04-06 23:32:15 +02:00
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
2012-02-22 12:43:14 +01:00
int Level_Keydown ( struct Game * game , ALLEGRO_EVENT * ev ) {
2012-04-09 15:25:56 +02:00
if ( ev - > keyboard . keycode = = ALLEGRO_KEY_ESCAPE ) {
game - > level . music_pos = al_get_sample_instance_position ( game - > level . music ) ;
al_set_sample_instance_playing ( game - > level . music , false ) ;
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Keydown ( game , ev ) ;
if ( ev - > keyboard . keycode = = ALLEGRO_KEY_ESCAPE ) {
game - > gamestate = GAMESTATE_PAUSE ;
game - > loadstate = GAMESTATE_LEVEL ;
Pause_Load ( game ) ;
}
return 0 ;
2012-03-08 22:21:02 +01:00
}
2012-04-06 23:32:15 +02:00
void Level_ProcessLogic ( struct Game * game , ALLEGRO_EVENT * ev ) {
if ( game - > level . current_level = = 1 ) TM_HandleEvent ( ev ) ;
2012-04-09 15:58:01 +02:00
2012-04-06 23:32:15 +02:00
}
2012-03-08 22:21:02 +01:00
void Level_Preload ( struct Game * game ) {
2012-05-03 19:42:23 +02:00
game - > level . derpy_sheets = NULL ;
2012-05-10 12:21:53 +02:00
game - > level . derpy = NULL ;
2012-04-06 18:25:04 +02:00
Pause_Preload ( game ) ;
2012-05-03 19:42:23 +02:00
RegisterDerpySpritesheet ( game , " walk " ) ;
RegisterDerpySpritesheet ( game , " fly " ) ;
RegisterDerpySpritesheet ( game , " run " ) ;
RegisterDerpySpritesheet ( game , " stand " ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Preload ( game ) ;
2012-04-09 15:25:56 +02:00
else {
game - > level . sample = al_load_sample ( " data/levels/1/music.flac " ) ;
game - > level . music = al_create_sample_instance ( game - > level . sample ) ;
al_attach_sample_instance_to_mixer ( game - > level . music , game - > audio . music ) ;
al_set_sample_instance_playmode ( game - > level . music , ALLEGRO_PLAYMODE_LOOP ) ;
if ( ! game - > level . sample ) {
fprintf ( stderr , " Audio clip sample not loaded! \n " ) ;
exit ( - 1 ) ;
}
}
2012-04-08 19:01:30 +02:00
Level_PreloadBitmaps ( game ) ;
2012-04-06 17:28:38 +02:00
}
2012-03-08 22:21:02 +01:00
2012-04-06 17:28:38 +02:00
void Level_Unload ( struct Game * game ) {
2012-04-06 18:25:04 +02:00
Pause_Unload_Real ( game ) ;
2012-04-09 15:25:56 +02:00
al_destroy_sample_instance ( game - > level . music ) ;
al_destroy_sample ( game - > level . sample ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Unload ( game ) ;
2012-04-06 23:32:15 +02:00
else {
TM_Destroy ( ) ;
}
2012-05-03 19:42:23 +02:00
struct Obstracle * t = game - > level . obstracles ;
if ( t ) {
while ( t - > next ) {
if ( t - > prev ) free ( t - > prev ) ;
t = t - > next ;
}
free ( t ) ;
2012-05-01 22:52:30 +02:00
}
2012-04-08 19:01:30 +02:00
Level_UnloadBitmaps ( game ) ;
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp , * s = game - > level . derpy_sheets ;
tmp = s ;
while ( s ) {
tmp = s ;
s = s - > next ;
free ( tmp ) ;
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
2012-03-08 22:21:02 +01:00
void Level_UnloadBitmaps ( struct Game * game ) {
2012-04-08 23:25:14 +02:00
al_destroy_bitmap ( game - > level . derpy ) ;
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp = game - > level . derpy_sheets ;
while ( tmp ) {
al_destroy_bitmap ( tmp - > bitmap ) ;
tmp = tmp - > next ;
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_UnloadBitmaps ( game ) ;
2012-04-08 19:01:30 +02:00
else {
al_destroy_bitmap ( game - > level . foreground ) ;
al_destroy_bitmap ( game - > level . background ) ;
al_destroy_bitmap ( game - > level . stage ) ;
al_destroy_bitmap ( game - > level . clouds ) ;
2012-04-08 23:25:14 +02:00
al_destroy_bitmap ( game - > level . welcome ) ;
2012-05-01 22:52:30 +02:00
al_destroy_bitmap ( game - > level . obst_bmps . pie ) ;
2012-05-09 10:58:45 +02:00
al_destroy_bitmap ( game - > level . meter_bmp ) ;
2012-05-09 12:40:21 +02:00
al_destroy_bitmap ( game - > level . meter_image ) ;
2012-04-08 19:01:30 +02:00
}
2012-03-08 22:21:02 +01:00
}
2012-04-06 17:28:38 +02:00
void Level_PreloadBitmaps ( struct Game * game ) {
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp = game - > level . derpy_sheets ;
while ( tmp ) {
char filename [ 255 ] = { } ;
sprintf ( filename , " levels/derpy/%s.png " , tmp - > name ) ;
2012-05-08 13:22:56 +02:00
tmp - > bitmap = LoadScaledBitmap ( filename , al_get_display_height ( game - > display ) * 0.25 * tmp - > aspect * tmp - > cols * tmp - > scale , al_get_display_height ( game - > display ) * 0.25 * tmp - > rows * tmp - > scale ) ;
2012-05-03 19:42:23 +02:00
tmp = tmp - > next ;
}
2012-05-10 12:21:53 +02:00
if ( ! game - > level . derpy ) SelectDerpySpritesheet ( game , " stand " ) ;
game - > level . derpy = al_create_bitmap ( al_get_bitmap_width ( * ( game - > level . derpy_sheet ) ) / game - > level . sheet_cols , al_get_bitmap_height ( * ( game - > level . derpy_sheet ) ) / game - > level . sheet_rows ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_PreloadBitmaps ( game ) ;
2012-04-08 19:01:30 +02:00
else {
2012-04-14 22:26:33 +02:00
/* TODO: handle strange display aspects */
2012-04-08 19:01:30 +02:00
game - > level . clouds = LoadScaledBitmap ( " levels/1/clouds.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
game - > level . foreground = LoadScaledBitmap ( " levels/1/foreground.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
game - > level . background = LoadScaledBitmap ( " levels/1/background.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
game - > level . stage = LoadScaledBitmap ( " levels/1/stage.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
2012-05-01 22:52:30 +02:00
game - > level . obst_bmps . pie = LoadScaledBitmap ( " menu/pie.png " , al_get_display_width ( game - > display ) * 0.1 , al_get_display_height ( game - > display ) * 0.1 ) ;
2012-05-04 02:13:46 +02:00
game - > level . welcome = al_create_bitmap ( al_get_display_width ( game - > display ) , al_get_display_height ( game - > display ) / 2 ) ;
2012-04-08 23:25:14 +02:00
al_set_target_bitmap ( game - > level . welcome ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
al_draw_text_with_shadow ( game - > menu . font_title , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) * 0.5 , al_get_display_height ( game - > display ) * 0.1 , ALLEGRO_ALIGN_CENTRE , " Level 1 " ) ;
al_draw_text_with_shadow ( game - > menu . font_subtitle , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) * 0.5 , al_get_display_height ( game - > display ) * 0.275 , ALLEGRO_ALIGN_CENTRE , " Fluttershy " ) ;
2012-05-09 10:58:45 +02:00
2012-05-09 12:40:21 +02:00
game - > level . meter_image = LoadScaledBitmap ( " levels/meter.png " , al_get_display_width ( game - > display ) * 0.075 , al_get_display_width ( game - > display ) * 0.075 * 0.96470588235294117647 ) ;
game - > level . meter_bmp = al_create_bitmap ( al_get_display_width ( game - > display ) * 0.2 + al_get_bitmap_width ( game - > level . meter_image ) , al_get_bitmap_height ( game - > level . meter_image ) ) ;
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-04-08 19:01:30 +02:00
}
2012-02-22 12:43:14 +01:00
}