libsuperderpy/src/level.c

565 lines
21 KiB
C
Raw Normal View History

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>
#include "moonwalk.h"
#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-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;
game->level.sheet_speed_modifier = tmp->speed;
game->level.sheet_pos = 0;
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"));
s->speed = atof(al_get_config_value(config, "", "speed"));
s->next = game->level.derpy_sheets;
game->level.derpy_sheets = s;
al_destroy_config(config);
}
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-04-09 13:31:14 +02:00
game->level.speed+=tps(game, 0.000005*60);
if (game->level.speed<tps(game, 0.0020*60)) 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-04-09 13:31:14 +02:00
game->level.speed=tps(game, 60*0.00035);
2012-04-08 23:25:14 +02:00
if (game->level.st_pos<0.275) return false;
return true;
}
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-03 19:42:23 +02:00
if (!(action->arguments)) SelectDerpySpritesheet(game, "fly");
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;
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) {
if (rand()%100<=2) {
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;
obst->bitmap = &(game->level.obst_bmps.pie);
2012-05-01 22:52:30 +02:00
obst->callback = NULL;
2012-05-03 02:19:55 +02:00
obst->data = NULL;
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;
}
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-04-09 15:25:56 +02:00
if (!al_get_sample_instance_playing(game->level.music) && (game->loadstate==GAMESTATE_LEVEL)) {
al_set_sample_instance_playing(game->level.music, true);
al_set_sample_instance_position(game->level.music, game->level.music_pos);
}
if (game->level.current_level!=1) Moonwalk_Draw(game);
else {
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)) {
game->level.derpy_y -= 0.005;
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
}
if (al_key_down(&keyboard, ALLEGRO_KEY_DOWN)) {
game->level.derpy_y += 0.005;
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-03 19:42:23 +02:00
if ((game->level.derpy_y > 0.5) && (!game->level.sheet_speed)) { SelectDerpySpritesheet(game, "run"); game->level.sheet_speed = 0.0020/game->level.speed; }
else if ((game->level.derpy_y <= 0.5) && (game->level.sheet_speed)) { SelectDerpySpritesheet(game, "fly"); game->level.sheet_speed=0; }
2012-04-09 16:14:10 +02:00
if (game->level.derpy_y < 0) game->level.derpy_y=0;
else if (game->level.derpy_y > 0.75) game->level.derpy_y=0.75;
2012-04-09 15:58:01 +02:00
}
2012-04-08 19:01:30 +02:00
al_clear_to_color(al_map_rgb(0,0,0));
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-04 01:12:19 +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) {
bool col = false;
int x = (tmp->x/100.0)*al_get_display_width(game->display);
int y = (tmp->y/100.0)*al_get_display_height(game->display);
int w = al_get_bitmap_width(*(tmp->bitmap));
int h = al_get_bitmap_height(*(tmp->bitmap));
if ((((x>=derpyx) && (x<=derpyx+derpyw)) || ((x+w>=derpyx) && (x+w<=derpyx+derpyw))) &&
(((y>=derpyy) && (y<=derpyy+derpyh)) || ((y+h>=derpyy) && (y+h<=derpyy+derpyh))))
col = true;
al_draw_tinted_bitmap(*(tmp->bitmap), al_map_rgba_f(255,255-col*255,255-col*255,1), x, y, 0);
if (col) colision = true;
2012-05-01 22:52:30 +02:00
tmp->x -= game->level.speed*310;
2012-05-03 02:19:55 +02:00
if (tmp->callback) tmp->callback(game, tmp);
tmp = tmp->next;
2012-05-01 22:52:30 +02:00
} else {
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-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);
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);
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;
}
if (game->level.sheet_pos>=game->level.sheet_cols*game->level.sheet_rows) game->level.sheet_pos=0;
2012-04-08 23:25:14 +02:00
}
al_set_target_bitmap(al_get_backbuffer(game->display));
al_draw_tinted_bitmap(game->level.derpy, al_map_rgba_f(255,255-colision*255,255-colision*255,1), derpyx, 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-04-09 18:11:09 +02:00
game->level.cl_pos += game->level.speed * 0.2;
2012-04-08 19:01:30 +02:00
game->level.bg_pos += game->level.speed * 0.6;
game->level.st_pos += game->level.speed * 1;
game->level.fg_pos += 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-04-06 23:32:15 +02:00
TM_Process();
}
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) {
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) {
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;
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-08 23:25:14 +02:00
tmp = (float*)action->arguments->value;
in = (bool*)action->arguments->next->value;
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-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-04-08 23:25:14 +02:00
int fade = *tmp;
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-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) {
if (state == TM_ACTIONSTATE_DESTROY) {
Level_Passed(game);
TM_AddBackgroundAction(&FadeOut, NULL, 0, "fadeout");
}
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-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-03 19:42:23 +02:00
SelectDerpySpritesheet(game, "stand");
2012-04-10 14:07:36 +02:00
game->level.sheet_speed = 2.4;
2012-04-08 23:25:14 +02:00
game->level.sheet_tmp = 0;
game->level.handle_input = false;
2012-05-01 22:52:30 +02:00
game->level.obstracles = NULL;
2012-04-06 23:32:15 +02:00
al_clear_to_color(al_map_rgb(0,0,0));
if (game->level.current_level!=1) Moonwalk_Load(game);
2012-04-06 23:32:15 +02:00
else {
TM_Init(game);
TM_AddBackgroundAction(&FadeIn, NULL, 0, "fadein");
2012-04-08 23:25:14 +02:00
TM_AddDelay(1000);
TM_AddQueuedBackgroundAction(&Welcome, NULL, 0, "welcome");
2012-04-09 15:25:56 +02:00
TM_AddDelay(1000);
TM_AddAction(&Walk, NULL, "walk");
TM_AddAction(&Move, NULL, "move");
TM_AddAction(&Stop, NULL, "stop");
TM_AddDelay(1000);
TM_AddAction(&Letter, NULL, "letter");
TM_AddDelay(500);
TM_AddQueuedBackgroundAction(&Accelerate, NULL, 0, "accelerate");
TM_AddAction(&Fly, NULL, "fly");
2012-05-01 22:52:30 +02:00
TM_AddDelay(5*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
// second part gameplay goes here
//
// cutscene goes here
//
2012-04-14 22:26:33 +02:00
*/
2012-04-08 23:25:14 +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);
}
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-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
}
void Level_Preload(struct Game *game) {
2012-05-03 19:42:23 +02:00
game->level.derpy_sheets = NULL;
Pause_Preload(game);
2012-05-03 19:42:23 +02:00
RegisterDerpySpritesheet(game, "walk");
RegisterDerpySpritesheet(game, "fly");
RegisterDerpySpritesheet(game, "run");
RegisterDerpySpritesheet(game, "stand");
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);
}
void Level_Unload(struct Game *game) {
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);
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
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;
}
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-04-08 19:01:30 +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);
tmp->bitmap = LoadScaledBitmap(filename, al_get_display_width(game->display)*0.1953125*tmp->cols, al_get_display_height(game->display)*0.25*tmp->rows);
tmp = tmp->next;
}
2012-04-08 23:25:14 +02:00
game->level.derpy = al_create_bitmap(al_get_display_width(game->display)*0.1953125, al_get_display_height(game->display)*0.25);
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-04-08 23:25:14 +02:00
game->level.welcome = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
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");
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
}