diff --git a/cmake/FindAllegro5Color.cmake b/cmake/FindAllegro5Color.cmake new file mode 100644 index 0000000..ff40a64 --- /dev/null +++ b/cmake/FindAllegro5Color.cmake @@ -0,0 +1,22 @@ +# Try to find allegro 5 +# +# ALLEGRO5_COLOR_FOUND - system has allegro5 +# ALLEGRO5_COLOR_INCLUDE_DIR - the allrgo5 include directory +# ALLEGRO5_COLOR_LIBRARIES - Link these to use allegro5 +# + +FIND_PATH(ALLEGRO5_COLOR_INCLUDE_DIR allegro5/allegro_color.h) + +SET(ALLEGRO5_COLOR_NAMES ${ALLEGRO5_COLOR_NAMES} allegro_color allegro_color_static liballegro_color liballegro_color_static) +FIND_LIBRARY(ALLEGRO5_COLOR_LIBRARY NAMES ${ALLEGRO5_COLOR_NAMES} ) + +# handle the QUIETLY and REQUIRED arguments and set ALLEGRO5_COLOR_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALLEGRO5_COLOR DEFAULT_MSG ALLEGRO5_COLOR_LIBRARY ALLEGRO5_COLOR_INCLUDE_DIR) + +IF(ALLEGRO5_COLOR_FOUND) + SET(ALLEGRO5_COLOR_LIBRARIES ${ALLEGRO5_COLOR_LIBRARY}) +ENDIF(ALLEGRO5_COLOR_FOUND) + +MARK_AS_ADVANCED(ALLEGRO5_COLOR_LIBRARY ALLEGRO5_COLOR_INCLUDE_DIR ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd51115..398dedb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ find_package(Allegro5Primitives REQUIRED) find_package(Allegro5Audio REQUIRED) find_package(Allegro5ACodec REQUIRED) find_package(Allegro5Image REQUIRED) +find_package(Allegro5Color REQUIRED) if(APPLE) find_package(Allegro5Main) endif(APPLE) @@ -27,24 +28,24 @@ if(MINGW) set(LINK_FLAGS -Wl,-subsystem,windows) endif(MINGW) -SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/ticklemonster:\$ORIGIN/gamestates:\$ORIGIN:\$ORIGIN/../lib:\$ORIGIN/lib:\$ORIGIN/bin") +SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/mediator:\$ORIGIN/gamestates:\$ORIGIN:\$ORIGIN/../lib:\$ORIGIN/lib:\$ORIGIN/bin") if(APPLE) - set(EXECUTABLE "TickleMonster") + set(EXECUTABLE "mediator") else(APPLE) - set(EXECUTABLE "ticklemonster") + set(EXECUTABLE "mediator") endif(APPLE) -add_library("libsuperderpy-ticklemonster" SHARED ${SRC_LIST}) +add_library("libsuperderpy-mediator" SHARED ${SRC_LIST}) add_executable(${EXECUTABLE} WIN32 MACOSX_BUNDLE ${EXECUTABLE_SRC_LIST}) -SET_TARGET_PROPERTIES("libsuperderpy-ticklemonster" PROPERTIES PREFIX "") +SET_TARGET_PROPERTIES("libsuperderpy-mediator" PROPERTIES PREFIX "") include_directories(${ALLEGRO5_INCLUDE_DIR} ${ALLEGRO5_FONT_INCLUDE_DIR} ${ALLEGRO5_TTF_INCLUDE_DIR} ${ALLEGRO5_PRIMITIVES_INCLUDE_DIR} ${ALLEGRO5_AUDIO_INCLUDE_DIR} ${ALLEGRO5_ACODEC_INCLUDE_DIR} ${ALLEGRO5_IMAGE_INCLUDE_DIR}) -target_link_libraries(${EXECUTABLE} ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m dl libsuperderpy-ticklemonster) +target_link_libraries(${EXECUTABLE} ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m dl libsuperderpy-mediator) -target_link_libraries("libsuperderpy-ticklemonster" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m) +target_link_libraries("libsuperderpy-mediator" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m) if(ALLEGRO5_MAIN_FOUND) target_link_libraries(${EXECUTABLE} ${ALLEGRO5_MAIN_LIBRARIES}) @@ -53,4 +54,4 @@ endif(ALLEGRO5_MAIN_FOUND) add_subdirectory(gamestates) install(TARGETS ${EXECUTABLE} DESTINATION ${BIN_INSTALL_DIR}) -install(TARGETS "libsuperderpy-ticklemonster" DESTINATION ${LIB_INSTALL_DIR}) +install(TARGETS "libsuperderpy-mediator" DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/gamestates/CMakeLists.txt b/src/gamestates/CMakeLists.txt index 9f730c7..9756c3f 100644 --- a/src/gamestates/CMakeLists.txt +++ b/src/gamestates/CMakeLists.txt @@ -1,18 +1,26 @@ MACRO(GAMESTATE name) - add_library("libsuperderpy-ticklemonster-${name}" SHARED "${name}.c") + add_library("libsuperderpy-mediator-${name}" SHARED "${name}.c") - SET_TARGET_PROPERTIES("libsuperderpy-ticklemonster-${name}" PROPERTIES PREFIX "") + SET_TARGET_PROPERTIES("libsuperderpy-mediator-${name}" PROPERTIES PREFIX "") - target_link_libraries("libsuperderpy-ticklemonster-${name}" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} m libsuperderpy-ticklemonster) + target_link_libraries("libsuperderpy-mediator-${name}" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_COLOR_LIBRARIES} m libsuperderpy-mediator) - install(TARGETS "libsuperderpy-ticklemonster-${name}" DESTINATION ${LIB_INSTALL_DIR}) + install(TARGETS "libsuperderpy-mediator-${name}" DESTINATION ${LIB_INSTALL_DIR}) ENDMACRO() GAMESTATE("dosowisko") +GAMESTATE("burndt") + GAMESTATE("menu") + GAMESTATE("info") -GAMESTATE("level") +GAMESTATE("theend") + +GAMESTATE("rockets") +GAMESTATE("lollipop") +GAMESTATE("riots") +GAMESTATE("bonus") GAMESTATE("loading") diff --git a/src/gamestates/bonus.c b/src/gamestates/bonus.c new file mode 100644 index 0000000..88e1b7a --- /dev/null +++ b/src/gamestates/bonus.c @@ -0,0 +1,452 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include +#include "../utils.h" +#include "../timeline.h" +#include "bonus.h" + +int Gamestate_ProgressCount = 11; + +struct Rocket* CreateRocket(struct Game *game, struct RocketsResources* data, struct Rocket* rockets, bool right) { + struct Rocket *n = malloc(sizeof(struct Rocket)); + n->next = NULL; + n->prev = NULL; + n->dx = (right ? -1.5 : 1.5) + (rand() / (float)RAND_MAX) * 0.6 - 0.3; + n->dy = -2.1 + (rand() / (float)RAND_MAX) * 0.5 - 0.25; + n->modifier = 0.025; + n->blown = false; + n->character = CreateCharacter(game, "rocket"); + n->character->spritesheets = data->rocket_template->spritesheets; + n->character->shared = true; + SelectSpritesheet(game, n->character, rand() % 2 ? "usa" : "ru"); + SetCharacterPosition(game, n->character, (data->ru_flag->x + 40) + rand() % 100 - 50, 100, right ? -0.33 : 0.33); + al_play_sample_instance(data->jump_sound); + data->currentspawn = data->spawnspeed + (data->spawnspeed * 0.1) * (float)(rand() / (float)RAND_MAX * 2) - (data->spawnspeed * 0.05); + + if (rockets) { + struct Rocket *tmp = rockets; + while (tmp->next) { + tmp=tmp->next; + } + tmp->next = n; + n->prev = tmp; + return rockets; + } else { + return n; + } +} + + +void DrawRockets(struct Game *game, struct RocketsResources* data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + DrawCharacter(game, tmp->character, al_map_rgb(255,255,255), 0); + + tmp=tmp->next; + } +} + +bool switchMinigame(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "bonus"); + StartGamestate(game, game->mediator.next); + } + return true; +} + +bool theEnd(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "bonus"); + StartGamestate(game, "theend"); + } + return true; +} + +void UpdateRockets(struct Game *game, struct RocketsResources *data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + tmp->dy+= tmp->modifier; + if (!tmp->blown) { + tmp->dx+= (tmp->dx > 0) ? (-tmp->modifier / 5 + 0.001) : (tmp->modifier / 5 - 0.001); + } + MoveCharacter(game, tmp->character, tmp->dx, tmp->dy, tmp->blown ? 0 : ((tmp->dx > 0) ? 0.0166 : -0.0166)); + AnimateCharacter(game, tmp->character, 1); + + if (!tmp->blown) { + + //if (((((tmp->character->y > 90) && (rand() % 4 == 0) && (tmp->dy > 0)))) && (tmp->character->x > -20 && tmp->character->x < 320)) { + if ((tmp->character->x > 200) && (tmp->character->y < 50) && (tmp->character->x < 260) && (rand() % 4 == 0)) { + tmp->blown = true; + tmp->modifier = 0; + tmp->character->angle = 0; + tmp->dx = 0; + tmp->dy = 0; + SelectSpritesheet(game, tmp->character, "boom"); + MoveCharacter(game, tmp->character, 5, 5, 0); + + data->lizakpowa--; + + } + } + tmp=tmp->next; + } +} + +void Gamestate_Logic(struct Game *game, struct RocketsResources* data) { + + if (!data->flash) { + if ((!data->lost) && (!data->won)) { + + UpdateRockets(game, data, data->rockets_left); + UpdateRockets(game, data, data->rockets_right); + } + } else { + data->flash--; + } + + if (data->lost) { + data->zadyma++; + if (data->zadyma >= 255) { + data->zadyma = 255; + } + } + + AnimateCharacter(game, data->usa_flag, 1); + AnimateCharacter(game, data->ru_flag, 1); + AnimateCharacter(game, data->riot, 1); + if ((data->lost) && (data->hearts > 80)) { + AnimateCharacter(game, game->mediator.heart, 1); + if (game->mediator.heart->pos == 6) { + al_play_sample_instance(data->boom_sound); + } + } + + + if ((data->lizakpowa <= 0) && (!data->won) && (!data->lost)) { + data->won = true; + al_play_sample_instance(data->rainbow_sound); + al_play_sample_instance(data->boom_sound); + data->flash = 4; + game->mediator.lives++; + AdvanceLevel(game, true); + MoveCharacter(game, data->ru_flag, 0, -24, 0); + SelectSpritesheet(game, data->ru_flag, "lollipop"); + TM_AddDelay(data->timeline, 2500); + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } + + if ((data->counter >= data->timelimit) && (!data->lost) && (!data->won)) { + + data->lost = true; + game->mediator.lives++; + AdvanceLevel(game, false); + + SelectSpritesheet(game, data->ru_flag, "cry"); + al_play_sample_instance(data->wuwu_sound); + + TM_AddDelay(data->timeline, 1500); + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + + + } + + if (!data->won) { + data->counter++; + } + data->spawncounter++; + data->cloud_rotation += 0.002; + data->tick ++; + + data->color += 2; + if (data->color >= 360) { + data->color = 0; + } + + TM_Process(data->timeline); +} + +void Gamestate_Draw(struct Game *game, struct RocketsResources* data) { + + al_set_target_bitmap(data->pixelator); + + al_draw_tinted_bitmap(data->bg, al_color_hsv(abs(data->color), 0.498, 1.0), 0, 0, 0); + + + if (data->won) { + // DrawCharacter(game, data->euro, al_map_rgb(255,255,255), 0); + } + + if (data->lizakpowa > 30) { + al_draw_rotated_bitmap(data->loli, 200, 200, 370, 65, -1, 0); + } else if (data->lizakpowa > 15) { + al_draw_rotated_bitmap(data->loli2, 200, 200, 370, 65, -1, 0); + } else if (data->lizakpowa > 0) { + al_draw_rotated_bitmap(data->loli3, 200, 200, 370, 65, -1, 0); + } + + if ((!data->lost) && (!data->won)) { + + + DrawRockets(game, data, data->rockets_left); + DrawRockets(game, data, data->rockets_right); + + } + + + DrawCharacter(game, data->ru_flag, al_map_rgb(255,255,255), 0); + + if ((!data->lost) && (!data->won)) { + al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142)); + al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30)); + al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+ 160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80)); + } + + if (data->flash) { + al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgb(255, 255, 255)); + } + + al_set_target_backbuffer(game->display); + al_draw_bitmap(data->pixelator, 0, 0, 0); + + if ((data->lost) && (data->hearts > 80)) { + ShowLevelStatistics(game); + } + + if (data->tick < 86) { + + if ((data->tick / 11) % 2 == 0) { + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), 320 /2 , 45 , ALLEGRO_ALIGN_CENTER, "BONUS LEVEL"); + } + } + + //Gamestate_Logic(game, data); + +} + +void Gamestate_Start(struct Game *game, struct RocketsResources* data) { + data->rockets_left = NULL; + data->rockets_right = NULL; + + data->tick = 0; + + data->timelimit = 420 / game->mediator.modificator; + data->spawnspeed = 80 / game->mediator.modificator; + data->currentspawn = data->spawnspeed; + data->spawncounter = data->spawnspeed - 20; + + data->lost = false; + data->won = false; + data->hearts = 0; + + data->flash = 0; + data->zadyma = 16; + data->lizakpowa = 60; + + SetCharacterPosition(game, data->usa_flag, 185, 80, 0); + SetCharacterPosition(game, data->ru_flag, 25, 80, 0); + + SetCharacterPosition(game, data->cursor, -320, 50, 0); + + SetCharacterPosition(game, data->riot, 0, 0, 0); + SelectSpritesheet(game, data->riot, "riot"); + + SelectSpritesheet(game, data->usa_flag, "legia"); + SelectSpritesheet(game, data->ru_flag, "lech"); + + SelectSpritesheet(game, data->cursor, "hand"); + + data->counter = 0; + data->cloud_rotation = 0; + + data->mousemove.bottom = false; + data->mousemove.top = false; + data->mousemove.left = false; + data->mousemove.right = false; + + al_set_mouse_xy(game->display, al_get_display_width(game->display) / 2, al_get_display_height(game->display) / 2); + + al_set_sample_instance_gain(game->muzyczka.instance.bg, 0.0); + al_set_sample_instance_gain(game->muzyczka.instance.fg, 0.0); + al_set_sample_instance_gain(data->riot_sound, 1.5); + al_set_sample_instance_gain(data->wuwu_sound, 1.25); + al_play_sample_instance(data->riot_sound); + al_play_sample_instance(data->wuwu_sound); +} + +void Gamestate_ProcessEvent(struct Game *game, struct RocketsResources* data, ALLEGRO_EVENT *ev) { + TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "bonus", "theend"); + } else if (ev->type == ALLEGRO_EVENT_MOUSE_AXES) { + int mousex = ev->mouse.x / (al_get_display_width(game->display) / 320); + int mousey = 80; + data->mousemove.right = mousex > data->cursor->x; + data->mousemove.top = mousey < data->cursor->y; + data->mousemove.left = mousex < data->cursor->x; + data->mousemove.bottom = mousey > data->cursor->y; + if ((!data->won)&& (!data->lost)) { + SetCharacterPosition(game, data->ru_flag, mousex, mousey , 0); // FIXMEEEE! + } + } else if (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if ((!data->won)&& (!data->lost)) { + data->rockets_left = CreateRocket(game, data, data->rockets_left, false); + } + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct RocketsResources *data = malloc(sizeof(struct RocketsResources)); + + data->timeline = TM_Init(game, "bonus"); + + data->bg = al_load_bitmap( GetDataFilePath(game, "bg.png")); + + data->earth = al_load_bitmap( GetDataFilePath(game, "riots/separator.png")); + + data->loli = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop.png")); + data->loli2 = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop2.png")); + data->loli3 = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop3.png")); + + (*progress)(game); + + data->rocket_sample = al_load_sample( GetDataFilePath(game, "bump.flac") ); + (*progress)(game); + data->boom_sample = al_load_sample( GetDataFilePath(game, "boom.flac") ); + (*progress)(game); + data->jump_sample = al_load_sample( GetDataFilePath(game, "launch.flac") ); + (*progress)(game); + data->rainbow_sample = al_load_sample( GetDataFilePath(game, "win.flac") ); + (*progress)(game); + data->wuwu_sample = al_load_sample( GetDataFilePath(game, "warning.flac") ); + (*progress)(game); + data->riot_sample = al_load_sample( GetDataFilePath(game, "bonus.flac") ); + (*progress)(game); + + data->rocket_sound = al_create_sample_instance(data->rocket_sample); + al_attach_sample_instance_to_mixer(data->rocket_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rocket_sound, ALLEGRO_PLAYMODE_ONCE); + + data->boom_sound = al_create_sample_instance(data->boom_sample); + al_attach_sample_instance_to_mixer(data->boom_sound, game->audio.fx); + al_set_sample_instance_playmode(data->boom_sound, ALLEGRO_PLAYMODE_ONCE); + + data->rainbow_sound = al_create_sample_instance(data->rainbow_sample); + al_attach_sample_instance_to_mixer(data->rainbow_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rainbow_sound, ALLEGRO_PLAYMODE_ONCE); + al_set_sample_instance_gain(data->rainbow_sound, 1.25); + + data->jump_sound = al_create_sample_instance(data->jump_sample); + al_attach_sample_instance_to_mixer(data->jump_sound, game->audio.fx); + al_set_sample_instance_playmode(data->jump_sound, ALLEGRO_PLAYMODE_ONCE); + + data->riot_sound = al_create_sample_instance(data->riot_sample); + al_attach_sample_instance_to_mixer(data->riot_sound, game->audio.music); + al_set_sample_instance_playmode(data->riot_sound, ALLEGRO_PLAYMODE_LOOP); + + data->wuwu_sound = al_create_sample_instance(data->wuwu_sample); + al_attach_sample_instance_to_mixer(data->wuwu_sound, game->audio.fx); + al_set_sample_instance_playmode(data->wuwu_sound, ALLEGRO_PLAYMODE_ONCE); + + + data->cursor = CreateCharacter(game, "cursor"); + RegisterSpritesheet(game, data->cursor, "hand"); + LoadSpritesheets(game, data->cursor); + (*progress)(game); + + data->pixelator = al_create_bitmap(320, 180); + al_set_target_bitmap(data->pixelator); + al_clear_to_color(al_map_rgb(0, 0, 0)); + + al_set_target_backbuffer(game->display); + + data->rocket_template = CreateCharacter(game, "rocket"); + RegisterSpritesheet(game, data->rocket_template, "usa"); + RegisterSpritesheet(game, data->rocket_template, "ru"); + RegisterSpritesheet(game, data->rocket_template, "atom"); + RegisterSpritesheet(game, data->rocket_template, "boom"); + RegisterSpritesheet(game, data->rocket_template, "blank"); + LoadSpritesheets(game, data->rocket_template); + (*progress)(game); + + data->usa_flag = CreateCharacter(game, "kibols"); + RegisterSpritesheet(game, data->usa_flag, "legia"); + RegisterSpritesheet(game, data->usa_flag, "lollipop"); + RegisterSpritesheet(game, data->usa_flag, "cry"); + LoadSpritesheets(game, data->usa_flag); + + data->ru_flag = CreateCharacter(game, "kibols"); + RegisterSpritesheet(game, data->ru_flag, "lech"); + RegisterSpritesheet(game, data->ru_flag, "lollipop"); + RegisterSpritesheet(game, data->ru_flag, "cry"); + LoadSpritesheets(game, data->ru_flag); + (*progress)(game); + + data->rainbow = CreateCharacter(game, "rainbow"); + RegisterSpritesheet(game, data->rainbow, "shine"); + RegisterSpritesheet(game, data->rainbow, "be"); + LoadSpritesheets(game, data->rainbow); + + data->riot = CreateCharacter(game, "riot"); + RegisterSpritesheet(game, data->riot, "riot"); + LoadSpritesheets(game, data->riot); + (*progress)(game); + + data->euro = CreateCharacter(game, "euro"); + RegisterSpritesheet(game, data->euro, "euro"); + LoadSpritesheets(game, data->euro); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct RocketsResources* data) { + TM_CleanQueue(data->timeline); + al_set_sample_instance_gain(game->muzyczka.instance.bg, 1.5); + al_set_sample_instance_gain(game->muzyczka.instance.fg, 1.5); + al_stop_sample_instance(data->riot_sound); +} + +void Gamestate_Unload(struct Game *game, struct RocketsResources* data) { + al_destroy_bitmap(data->bg); + al_destroy_bitmap(data->earth); + al_destroy_bitmap(data->pixelator); + al_destroy_bitmap(data->loli); + al_destroy_bitmap(data->loli2); + al_destroy_bitmap(data->loli3); + al_destroy_sample_instance(data->rocket_sound); + al_destroy_sample_instance(data->boom_sound); + al_destroy_sample(data->rocket_sample); + al_destroy_sample(data->boom_sample); + // TODO: DestroyCharacters + free(data); +} + +void Gamestate_Reload(struct Game *game, struct RocketsResources* data) {} + +void Gamestate_Resume(struct Game *game, struct RocketsResources* data) { + TM_Resume(data->timeline); +} +void Gamestate_Pause(struct Game *game, struct RocketsResources* data) { + TM_Pause(data->timeline); +} diff --git a/src/gamestates/bonus.h b/src/gamestates/bonus.h new file mode 100644 index 0000000..96f38c3 --- /dev/null +++ b/src/gamestates/bonus.h @@ -0,0 +1,54 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct RocketsResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bg, *earth, *earth2, *pixelator, *loli, *loli2, *loli3; + struct Character *rocket_template, *usa_flag, *ru_flag, *cursor, *rainbow, *riot, *euro; + + struct Rocket { + struct Character *character; + float dx, dy, modifier; + bool blown, bumped; + struct Rocket *next, *prev; + } *rockets_left, *rockets_right; + + int counter, hearts, tick; + float cloud_rotation; + + struct { + bool top, right, left, bottom; + } mousemove; + + ALLEGRO_SAMPLE *rocket_sample, *boom_sample, *rainbow_sample, *jump_sample, *wuwu_sample, *riot_sample; + ALLEGRO_SAMPLE_INSTANCE *rocket_sound, *boom_sound, *rainbow_sound, *jump_sound, *wuwu_sound, *riot_sound; + + bool lost, won; + + int flash, zadyma; + + int timelimit, spawnspeed, currentspawn, spawncounter; + + struct Timeline *timeline; + + int color; + int lizakpowa; +}; diff --git a/src/gamestates/burndt.c b/src/gamestates/burndt.c new file mode 100644 index 0000000..7b68ac4 --- /dev/null +++ b/src/gamestates/burndt.c @@ -0,0 +1,101 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include "../utils.h" +#include "../timeline.h" +#include "burndt.h" + +int Gamestate_ProgressCount = 1; + +void Gamestate_Logic(struct Game *game, struct burndtResources* data) { + data->tick++; + if (data->tick > 260) { + SwitchGamestate(game, "burndt", "menu"); + } +} + +void Gamestate_Draw(struct Game *game, struct burndtResources* data) { + + float light = 1 - data->tick / 20.0; + + if (data->tick >= 190) { + light = 1 - (data->tick-190) / 20.0; + } + + if (light > 1) { + light = 1; + } + if (light < 0) { + light = 0; + } + + if (data->tick < 190) { + al_clear_to_color(al_map_rgb(82 + (255-82) * light, 82 + (255-82) * light, 186 + (255-186) * light)); + al_draw_bitmap(data->bitmap, 0, 0, 0); + } else { + al_clear_to_color(al_map_rgb(255 * light, 255 * light, 255 * light)); + + } + +} + +void Gamestate_Start(struct Game *game, struct burndtResources* data) { + data->tick = 0; + al_play_sample_instance(data->sound); +} + +void Gamestate_ProcessEvent(struct Game *game, struct burndtResources* data, ALLEGRO_EVENT *ev) { + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "burndt", "menu"); + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct burndtResources *data = malloc(sizeof(struct burndtResources)); + data->bitmap = al_load_bitmap( GetDataFilePath(game, "burndt.png") ); + (*progress)(game); + + data->sample = al_load_sample( GetDataFilePath(game, "burndt.flac") ); + data->sound = al_create_sample_instance(data->sample); + al_attach_sample_instance_to_mixer(data->sound, game->audio.music); + al_set_sample_instance_playmode(data->sound, ALLEGRO_PLAYMODE_ONCE); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct burndtResources* data) { + al_stop_sample_instance(data->sound); +} + +void Gamestate_Unload(struct Game *game, struct burndtResources* data) { + al_destroy_sample_instance(data->sound); + al_destroy_sample(data->sample); + al_destroy_bitmap(data->bitmap); + free(data); +} + +void Gamestate_Reload(struct Game *game, struct burndtResources* data) {} + +void Gamestate_Resume(struct Game *game, struct burndtResources* data) {} +void Gamestate_Pause(struct Game *game, struct burndtResources* data) {} diff --git a/src/gamestates/burndt.h b/src/gamestates/burndt.h new file mode 100644 index 0000000..9a32ae3 --- /dev/null +++ b/src/gamestates/burndt.h @@ -0,0 +1,27 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct burndtResources { + ALLEGRO_SAMPLE *sample; + ALLEGRO_SAMPLE_INSTANCE *sound; + ALLEGRO_BITMAP *bitmap; + int tick; +}; diff --git a/src/gamestates/dosowisko.c b/src/gamestates/dosowisko.c index a965198..e652cc0 100644 --- a/src/gamestates/dosowisko.c +++ b/src/gamestates/dosowisko.c @@ -55,7 +55,7 @@ bool FadeOut(struct Game *game, struct TM_Action *action, enum TM_ActionState st } bool End(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { - if (state == TM_ACTIONSTATE_RUNNING) SwitchGamestate(game, "dosowisko", "menu"); + if (state == TM_ACTIONSTATE_RUNNING) SwitchGamestate(game, "dosowisko", "burndt"); return true; } @@ -150,7 +150,7 @@ void Gamestate_Start(struct Game *game, struct dosowiskoResources* data) { void Gamestate_ProcessEvent(struct Game *game, struct dosowiskoResources* data, ALLEGRO_EVENT *ev) { TM_HandleEvent(data->timeline, ev); if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { - SwitchGamestate(game, "dosowisko", "menu"); + SwitchGamestate(game, "dosowisko", "menu"); } } @@ -223,5 +223,9 @@ void Gamestate_Unload(struct Game *game, struct dosowiskoResources* data) { void Gamestate_Reload(struct Game *game, struct dosowiskoResources* data) {} -void Gamestate_Resume(struct Game *game, struct dosowiskoResources* data) {} -void Gamestate_Pause(struct Game *game, struct dosowiskoResources* data) {} +void Gamestate_Resume(struct Game *game, struct dosowiskoResources* data) { + TM_Resume(data->timeline); +} +void Gamestate_Pause(struct Game *game, struct dosowiskoResources* data) { + TM_Pause(data->timeline); +} diff --git a/src/gamestates/info.c b/src/gamestates/info.c index ba2b5ea..73c3f20 100644 --- a/src/gamestates/info.c +++ b/src/gamestates/info.c @@ -1,5 +1,5 @@ -/*! \file menu.c - * \brief Main Menu view. +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. */ /* * Copyright (c) Sebastian Krzyszkowiak @@ -18,182 +18,77 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include + #include #include -#include "../config.h" +#include +#include + #include "../utils.h" #include "../timeline.h" -#include "level.h" +#include "../config.h" +#include "info.h" -#define TILE_SIZE 20 -#define MAX_FUN 250.0 - -int Gamestate_ProgressCount = 4; - - -void Gamestate_Draw(struct Game *game, struct LevelResources* data) { - - al_set_target_bitmap(al_get_backbuffer(game->display)); - - al_clear_to_color(al_map_rgb(3, 213, 255)); - - al_draw_bitmap(data->bg,0, 0,0); - al_draw_bitmap(data->buildings,0, 0,0); - - al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgba(0,0,0,64)); - - - DrawCharacter(game, data->monster, al_map_rgb(255,255,255), 0); - - al_draw_bitmap(data->meter,0, 0,0); - - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 19, ALLEGRO_ALIGN_CENTRE, "You're the TICKLE MONSTER!"); - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 29, ALLEGRO_ALIGN_CENTRE, "You tickle kids to ensure they "); - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 39, ALLEGRO_ALIGN_CENTRE, "are raised with proper amounts of fun!"); - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 54, ALLEGRO_ALIGN_CENTRE, "Use ARROWS to move and SPACE to tickle!"); - - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 104, ALLEGRO_ALIGN_CENTRE, "Beware - if you give them wrong amount"); - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 114, ALLEGRO_ALIGN_CENTRE, "of fun, they turn into fun hating"); - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), game->viewport.width*0.5, 124, ALLEGRO_ALIGN_CENTRE, "grown ups! Don't let them catch you!"); - - DrawTextWithShadow(data->font, al_map_rgb(255,255,255), 5, 162, ALLEGRO_ALIGN_LEFT, "Press ENTER to start!"); +int Gamestate_ProgressCount = 1; +void Gamestate_Logic(struct Game *game, struct dosowiskoResources* data) { + data->tick++; + if (data->tick > 86) { + SwitchGamestate(game, "info", "lollipop"); + } } +void Gamestate_Draw(struct Game *game, struct dosowiskoResources* data) { + al_draw_bitmap(data->bitmap, 0, 0, 0); + if ((data->tick / 11) % 2 == 0) { + al_draw_bitmap(data->icon, 320 / 2 - al_get_bitmap_width(data->icon) / 2, 180 / 2 - al_get_bitmap_height(data->icon) / 2 , 0); + } +} -void Gamestate_Logic(struct Game *game, struct LevelResources* data) { - - AnimateCharacter(game, data->monster, 1); +void Gamestate_Start(struct Game *game, struct dosowiskoResources* data) { + data->tick = 0; + al_grab_mouse(game->display); + al_hide_mouse_cursor(game->display); + al_play_sample_instance(data->sound); +} +void Gamestate_ProcessEvent(struct Game *game, struct dosowiskoResources* data, ALLEGRO_EVENT *ev) { + //TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "info", "lollipop"); + } + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ENTER)) { + SwitchGamestate(game, "info", "lollipop"); + } } void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct dosowiskoResources *data = malloc(sizeof(struct dosowiskoResources)); + data->bitmap = al_load_bitmap( GetDataFilePath(game, "bg.png")); + data->icon = al_load_bitmap( GetDataFilePath(game, "mouse.png")); - struct LevelResources *data = malloc(sizeof(struct LevelResources)); - - data->timer = al_create_timer(1); - al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(data->timer)); - - data->timeline = TM_Init(game, "main"); + data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),100,0 ); (*progress)(game); - data->bg = al_load_bitmap( GetDataFilePath(game, "bg2.png") ); - data->buildings = al_load_bitmap( GetDataFilePath(game, "buildings.png") ); - data->hid = al_load_bitmap( GetDataFilePath(game, "hid.png") ); - data->meter = al_load_bitmap( GetDataFilePath(game, "meter.png") ); - (*progress)(game); + data->sample = al_load_sample( GetDataFilePath(game, "warning.flac") ); - data->font_title = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),game->viewport.height*0.16,0 ); - data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),12,0 ); - (*progress)(game); + data->sound = al_create_sample_instance(data->sample); + al_attach_sample_instance_to_mixer(data->sound, game->audio.fx); + al_set_sample_instance_playmode(data->sound, ALLEGRO_PLAYMODE_ONCE); + al_set_sample_instance_gain(data->sound, 1.25); - data->monster = CreateCharacter(game, "monster"); - RegisterSpritesheet(game, data->monster, "stand"); - RegisterSpritesheet(game, data->monster, "tickle"); - RegisterSpritesheet(game, data->monster, "ticklefail"); - RegisterSpritesheet(game, data->monster, "fail"); - RegisterSpritesheet(game, data->monster, "jump"); - LoadSpritesheets(game, data->monster); - (*progress)(game); - - al_set_target_backbuffer(game->display); return data; } - -void Gamestate_Stop(struct Game *game, struct LevelResources* data) { - +void Gamestate_Stop(struct Game *game, struct dosowiskoResources* data) { + al_stop_sample_instance(data->sound); } -void Gamestate_Unload(struct Game *game, struct LevelResources* data) { - al_destroy_bitmap(data->bg); - al_destroy_bitmap(data->buildings); - al_destroy_bitmap(data->meter); - al_destroy_font(data->font_title); - al_destroy_font(data->font); - DestroyCharacter(game, data->monster); +void Gamestate_Unload(struct Game *game, struct dosowiskoResources* data) { + free(data); } +void Gamestate_Reload(struct Game *game, struct dosowiskoResources* data) {} -void StartGame(struct Game *game, struct LevelResources *data) { - TM_CleanQueue(data->timeline); - TM_CleanBackgroundQueue(data->timeline); - ChangeSpritesheet(game, data->monster, "stand"); - ChangeSpritesheet(game, data->suit, "stand"); - } - -void Gamestate_Start(struct Game *game, struct LevelResources* data) { - data->cloud_position = 100; - SetCharacterPosition(game, data->monster, 150, 73, 0); - - data->score = 0; - data->time = 0; - - data->lost = false; - data->tickling = false; - data->haskid = false; - - data->movedown = false; - data->moveup = false; - - data->markx = 119; - data->marky = 2; - - data->soloactive = false; - data->soloanim = 0; - data->soloflash = 0; - data->soloready = 0; - - data->keys.key = 0; - data->keys.delay = 0; - data->keys.shift = false; - data->keys.lastkey = -1; - - data->lightanim=0; - - data->kidSpeed = 0.8; - - data->usage = 0; - - SelectSpritesheet(game, data->monster, "stand"); - - //TM_AddQueuedBackgroundAction(data->timeline, &Anim_FixGuitar, TM_AddToArgs(NULL, 1, data), 15*1000, "fix_guitar"); - //TM_AddQueuedBackgroundAction(data->timeline, &Anim_CowLook, TM_AddToArgs(NULL, 1, data), 5*1000, "cow_look"); - - data->kids[0] = NULL; - data->kids[1] = NULL; - data->kids[2] = NULL; - data->kids[3] = NULL; - data->kids[4] = NULL; - data->kids[5] = NULL; - data->destroyQueue = NULL; - - data->kidRate = 100; - data->timeTillNextBadguy = 0; -} - -void Gamestate_ProcessEvent(struct Game *game, struct LevelResources* data, ALLEGRO_EVENT *ev) { - TM_HandleEvent(data->timeline, ev); - - if (ev->type == ALLEGRO_EVENT_KEY_DOWN) { - if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) { - SwitchGamestate(game, "info", "level"); - return; - } - if (ev->keyboard.keycode == ALLEGRO_KEY_ENTER) { - SwitchGamestate(game, "info", "level"); - return; - } - } - -} - -void Gamestate_Pause(struct Game *game, struct LevelResources* data) { - TM_Pause(data->timeline); -} -void Gamestate_Resume(struct Game *game, struct LevelResources* data) { - TM_Resume(data->timeline); -} -void Gamestate_Reload(struct Game *game, struct LevelResources* data) {} +void Gamestate_Resume(struct Game *game, struct dosowiskoResources* data) {} +void Gamestate_Pause(struct Game *game, struct dosowiskoResources* data) {} diff --git a/src/gamestates/info.h b/src/gamestates/info.h index 301985a..04ec216 100644 --- a/src/gamestates/info.h +++ b/src/gamestates/info.h @@ -1,5 +1,5 @@ -/*! \file menu.h - * \brief Main Menu view headers. +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. */ /* * Copyright (c) Sebastian Krzyszkowiak @@ -19,66 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include -#include - -/*! \brief Resources used by Menu state. */ -struct LevelResources { - ALLEGRO_BITMAP *bg; /*!< Bitmap with lower portion of menu landscape. */ - ALLEGRO_BITMAP *buildings; - ALLEGRO_BITMAP *hid; - ALLEGRO_BITMAP *meter; - ALLEGRO_BITMAP *busted; - - ALLEGRO_TIMER *timer; - - float kidSpeed; - - int markx, marky; - - int usage; - int lightx, lighty, lightanim; - - int soloready, soloanim, soloflash; - bool soloactive; - - bool tickling, moveup, movedown, haskid, lost; - - struct Kid { - struct Character *character; - struct Kid *next, *prev; - float speed; - bool tickled; - bool grownup; - int fun; - bool happy; - bool right; - } *kids[6], *destroyQueue, *tickledKid; - - int timeTillNextBadguy, kidRate; - - struct Character *monster; - struct Character *suit; - struct Character *kid; - struct Timeline *timeline; - float cloud_position; /*!< Position of bigger cloud. */ - ALLEGRO_SAMPLE *sample; /*!< Music sample. */ - ALLEGRO_SAMPLE *click_sample; /*!< Click sound sample. */ - ALLEGRO_SAMPLE_INSTANCE *laughter; /*!< Sample instance with music sound. */ - ALLEGRO_SAMPLE_INSTANCE *click; /*!< Sample instance with click sound. */ - ALLEGRO_FONT *font_title; /*!< Font of "Super Derpy" text. */ - ALLEGRO_FONT *font; /*!< Font of standard menu item. */ - int selected; /*!< Number of selected menu item. */ - - struct { - int key; - bool shift; - int delay; - // workaround for random bogus UP/DOWN events - int lastkey; - int lastdelay; - } keys; - - int score, time; +struct dosowiskoResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bitmap, *icon; + ALLEGRO_SAMPLE *sample; + ALLEGRO_SAMPLE_INSTANCE *sound; + int tick; }; diff --git a/src/gamestates/lollipop.c b/src/gamestates/lollipop.c new file mode 100644 index 0000000..3833646 --- /dev/null +++ b/src/gamestates/lollipop.c @@ -0,0 +1,311 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include "../utils.h" +#include "../timeline.h" +#include "lollipop.h" + +int Gamestate_ProgressCount = 4; + + +bool switchMinigame(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "lollipop"); + game->mediator.next = "riots"; + StartGamestate(game, GetAbstractIsItBonusLevelTimeNowFactoryProvider(game) ? "bonus" : "riots"); + } + return true; +} + +bool theEnd(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "lollipop"); + StartGamestate(game, "theend"); + } + return true; +} + +void Gamestate_Logic(struct Game *game, struct RocketsResources* data) { + + if ((data->spawncounter == data->currentspawn) && ((data->counter < data->timelimit) || (data->lost))) { + data->dx = (( (rand() / (float)RAND_MAX) - 0.5)/ 200.0) * game->mediator.modificator; + PrintConsole(game, "DX %f", data->dx); + data->spawncounter = 0; + } + + if ((data->lost) && (data->hearts > 80)) { + AnimateCharacter(game, game->mediator.heart, 1); + if (game->mediator.heart->pos == 6) { + al_play_sample_instance(data->jump_sound); + } + } + + if (data->lost) { + data->hearts++; + } + + if ((data->counter >= data->timelimit) && (!data->lost) && (!data->won)) { + al_play_sample_instance(data->rainbow_sound); + data->won = true; + AdvanceLevel(game, true); + SelectSpritesheet(game, data->riot, "win"); + + TM_AddDelay(data->timeline, 2500); + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } + + if (data->won) { + AnimateCharacter(game, data->riot, 1); + } else { + + if ((data->currentpos < -0.15) || (data->currentpos > 0.15)) { + if (!data->lost) { + AdvanceLevel(game, false); + data->lost = true; + SelectSpritesheet(game, data->riot, "end"); + TM_AddDelay(data->timeline, 3500); + if (game->mediator.lives > 0) { + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } else { + + TM_AddAction(data->timeline, theEnd, NULL, "switchMinigame"); + } + al_play_sample_instance(data->boom_sound); + } + + } + + } + + int newstate = 0; + if (data->currentpos < -0.05) { + newstate = -1; + } else if (data->currentpos > 0.05) { + newstate = 1; + } + + if (data->oldstate != newstate) { + if (newstate == 0) { + SelectSpritesheet(game, data->faces, "center"); + } else if (newstate == 1) { + SelectSpritesheet(game, data->faces, "right"); + } else { + SelectSpritesheet(game, data->faces, "left"); + } + data->oldstate = newstate; + } + + data->counter++; + data->spawncounter++; + + if (!data->lost) { + data->currentpos += data->dx; + } + + TM_Process(data->timeline); +} + +void Gamestate_Draw(struct Game *game, struct RocketsResources* data) { + + al_set_target_bitmap(data->pixelator); + al_clear_to_color(al_map_rgba(128,192,255,0)); + al_draw_bitmap(data->bg, 0, 0, 0); + + + if (data->won) { + //DrawCharacter(game, data->euro, al_map_rgb(255,255,255), 0); + } + + if ((!data->lost) && (!data->won)) { + if (data->counter / (float)data->timelimit < 0.5) { + al_draw_rotated_bitmap(data->earth2, 158, 140, 158, 140, data->currentpos, 0); + } else if (data->counter / (float)data->timelimit < 0.8) { + al_draw_rotated_bitmap(data->earth3, 158, 140, 158, 140, data->currentpos, 0); + } else { + al_draw_rotated_bitmap(data->earth4, 158, 140, 158, 140, data->currentpos, 0); + } + al_draw_bitmap(data->earth, 0, 0, 0); + DrawCharacter(game, data->faces, al_map_rgb(255,255,255), 0); + + //DrawCharacter(game, data->cursor, al_map_rgb(255,255,255), 0); + } + + if ((!data->lost) && (!data->won)) { + al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142)); + al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30)); + al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+ 160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80)); + } + + al_set_target_backbuffer(game->display); + al_draw_bitmap(data->pixelator, 0, 0, 0); + + if ((!data->lost) && (!data->won)) { + al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142)); + al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30)); + al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80)); + } + + if (data->won) { + DrawCharacter(game, data->riot, al_map_rgb(255,255,255), 0); + } + + if (data->lost) { + al_draw_bitmap(data->currentpos < 0 ? data->clouds : data->combined, 0, 0, 0); + if (data->hearts > 80) { + ShowLevelStatistics(game); + } + } + + //Gamestate_Logic(game, data); + +} + +void Gamestate_Start(struct Game *game, struct RocketsResources* data) { + + data->timelimit = 400 * game->mediator.modificator; + data->spawnspeed = 40 / game->mediator.modificator; + data->currentspawn = data->spawnspeed; + data->spawncounter = data->spawnspeed; + + data->lost = false; + data->won = false; + + data->hearts = 0; + + data->currentpos = 0; + data->dx = 0; + + SetCharacterPosition(game, data->riot, 0, 0, 0); + SelectSpritesheet(game, data->riot, "win"); + SelectSpritesheet(game, data->faces, "center"); + SetCharacterPosition(game, data->faces, 0, 0, 0); + + data->oldstate = 0; + + data->counter = 0; + + al_set_mouse_xy(game->display, al_get_display_width(game->display) / 2, al_get_display_height(game->display) / 2); + +} + +void Gamestate_ProcessEvent(struct Game *game, struct RocketsResources* data, ALLEGRO_EVENT *ev) { + TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "lollipop", "theend"); + } else if (ev->type == ALLEGRO_EVENT_MOUSE_AXES) { + int mousex = ev->mouse.dx / (al_get_display_width(game->display) / 320); + + if (!data->lost) { + data->currentpos += mousex / 5000.0 / game->mediator.modificator; + } + al_set_mouse_xy(game->display, al_get_display_width(game->display) / 2, al_get_display_height(game->display) / 2); + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct RocketsResources *data = malloc(sizeof(struct RocketsResources)); + + data->timeline = TM_Init(game, "lollipop"); + + data->bg = al_load_bitmap( GetDataFilePath(game, "lollipop/bg.png")); + (*progress)(game); + + data->earth = al_load_bitmap( GetDataFilePath(game, "lollipop/peoples.png")); + data->earth2 = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop.png")); + data->earth3 = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop2.png")); + data->earth4 = al_load_bitmap( GetDataFilePath(game, "lollipop/lollipop3.png")); + + data->clouds = al_load_bitmap( GetDataFilePath(game, "lollipop/przegrywdziew.png")); + data->combined = al_load_bitmap( GetDataFilePath(game, "lollipop/przegrywchop.png")); + + data->boom_sample = al_load_sample( GetDataFilePath(game, "lollipop/lost.flac") ); + data->jump_sample = al_load_sample( GetDataFilePath(game, "boom.flac") ); + data->rainbow_sample = al_load_sample( GetDataFilePath(game, "lollipop/success.flac") ); + (*progress)(game); + + data->boom_sound = al_create_sample_instance(data->boom_sample); + al_attach_sample_instance_to_mixer(data->boom_sound, game->audio.fx); + al_set_sample_instance_playmode(data->boom_sound, ALLEGRO_PLAYMODE_ONCE); + + data->rainbow_sound = al_create_sample_instance(data->rainbow_sample); + al_attach_sample_instance_to_mixer(data->rainbow_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rainbow_sound, ALLEGRO_PLAYMODE_ONCE); + al_set_sample_instance_gain(data->rainbow_sound, 1.25); + + data->jump_sound = al_create_sample_instance(data->jump_sample); + al_attach_sample_instance_to_mixer(data->jump_sound, game->audio.fx); + al_set_sample_instance_playmode(data->jump_sound, ALLEGRO_PLAYMODE_ONCE); + + (*progress)(game); + + data->riot = CreateCharacter(game, "loliwin"); + RegisterSpritesheet(game, data->riot, "win"); + RegisterSpritesheet(game, data->riot, "end"); + LoadSpritesheets(game, data->riot); + (*progress)(game); + + data->faces = CreateCharacter(game, "faces"); + RegisterSpritesheet(game, data->faces, "left"); + RegisterSpritesheet(game, data->faces, "center"); + RegisterSpritesheet(game, data->faces, "right"); + LoadSpritesheets(game, data->faces); + (*progress)(game); + + data->pixelator = al_create_bitmap(320, 180); + al_set_target_bitmap(data->pixelator); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_set_target_backbuffer(game->display); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct RocketsResources* data) { + TM_CleanQueue(data->timeline); +} + +void Gamestate_Unload(struct Game *game, struct RocketsResources* data) { + al_destroy_bitmap(data->bg); + al_destroy_bitmap(data->earth); + al_destroy_bitmap(data->earth2); + al_destroy_bitmap(data->earth3); + al_destroy_bitmap(data->earth4); + al_destroy_bitmap(data->clouds); + al_destroy_bitmap(data->combined); + al_destroy_bitmap(data->pixelator); + al_destroy_sample_instance(data->boom_sound); + al_destroy_sample(data->boom_sample); + DestroyCharacter(game, data->faces); + DestroyCharacter(game, data->riot); + // TODO: Destroy all the stuff + free(data); +} + +void Gamestate_Reload(struct Game *game, struct RocketsResources* data) {} + +void Gamestate_Resume(struct Game *game, struct RocketsResources* data) { + TM_Resume(data->timeline); +} +void Gamestate_Pause(struct Game *game, struct RocketsResources* data) { + TM_Pause(data->timeline); +} diff --git a/src/gamestates/lollipop.h b/src/gamestates/lollipop.h new file mode 100644 index 0000000..b5718a9 --- /dev/null +++ b/src/gamestates/lollipop.h @@ -0,0 +1,42 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct RocketsResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bg, *earth, *earth2, *earth3, *earth4, *pixelator, *combined, *clouds; + struct Character *riot, *faces; + + int counter, hearts; + + ALLEGRO_SAMPLE *boom_sample, *rainbow_sample, *jump_sample; + ALLEGRO_SAMPLE_INSTANCE *boom_sound, *rainbow_sound, *jump_sound; + + bool lost, won; + + int oldstate; + + int timelimit, spawnspeed, currentspawn, spawncounter; + + float dx; + float currentpos; + + struct Timeline *timeline; +}; diff --git a/src/gamestates/menu.c b/src/gamestates/menu.c index 2228bf3..aedcc70 100644 --- a/src/gamestates/menu.c +++ b/src/gamestates/menu.c @@ -30,430 +30,476 @@ int Gamestate_ProgressCount = 4; void About(struct Game *game, struct MenuResources* data) { - ALLEGRO_TRANSFORM trans; - al_identity_transform(&trans); - al_use_transform(&trans); + ALLEGRO_TRANSFORM trans; + al_identity_transform(&trans); + al_use_transform(&trans); - if (!game->_priv.font_bsod) { - game->_priv.font_bsod = al_create_builtin_font(); - } + if (!game->_priv.font_bsod) { + game->_priv.font_bsod = al_create_builtin_font(); + } - al_set_target_backbuffer(game->display); - al_clear_to_color(al_map_rgb(0,0,170)); + al_set_target_backbuffer(game->display); + al_clear_to_color(al_map_rgb(0,0,170)); - char *header = "TICKLE MONSTER"; + char *header = "MEDIATOR"; - al_draw_filled_rectangle(al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display)/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170)); + al_draw_filled_rectangle(al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display)/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170)); - al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32), ALLEGRO_ALIGN_CENTRE, header); + al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32), ALLEGRO_ALIGN_CENTRE, header); - char *header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +"; + char *header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +"; - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+2*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, header2); - al_draw_textf(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+3*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", (void*)game); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+2*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, header2); + al_draw_textf(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+3*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", (void*)game); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+5*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "About screen not implemented!"); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+6*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "See http://dosowisko.net/ticklemonster/"); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+7*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Made for Ludum Dare 33 by Sebastian Krzyszkowiak"); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+5*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "About screen not implemented!"); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+7*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Made in the theater by Sebastian Krzyszkowiak and Konrad Burandt"); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+9*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error."); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+10*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world."); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway."); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+9*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error."); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+10*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world."); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway."); - al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _"); + al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _"); - al_use_transform(&game->projection); + al_use_transform(&game->projection); } void DrawMenuState(struct Game *game, struct MenuResources *data) { - const ALLEGRO_TRANSFORM *tmp_trans = al_get_current_transform(); - ALLEGRO_TRANSFORM trans, cur_trans; - al_copy_transform(&trans, tmp_trans); - al_copy_transform(&cur_trans, tmp_trans); - al_translate_transform(&trans, (al_get_display_width(game->display) / 320.0) * 100, (al_get_display_height(game->display) / 260.0) * ((180-data->screen_pos) - 48)); - al_use_transform(&trans); + const ALLEGRO_TRANSFORM *tmp_trans = al_get_current_transform(); + ALLEGRO_TRANSFORM trans, cur_trans; + al_copy_transform(&trans, tmp_trans); + al_copy_transform(&cur_trans, tmp_trans); + al_translate_transform(&trans, (al_get_display_width(game->display) / 320.0) * 80, (al_get_display_height(game->display) / 260.0) * ((180-data->screen_pos) - 48)); + al_use_transform(&trans); - ALLEGRO_FONT *font = data->font; - char* text = malloc(255*sizeof(char)); - struct ALLEGRO_COLOR color; - switch (data->menustate) { - case MENUSTATE_MAIN: - case MENUSTATE_HIDDEN: - if (!data->invisible) { - DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Start game"); - DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Options"); - DrawTextWithShadow(font, data->selected==2 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.7, ALLEGRO_ALIGN_CENTRE, "About"); - DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Exit"); - } - break; - case MENUSTATE_OPTIONS: - DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Video settings"); - DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Audio settings"); - DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); - break; - case MENUSTATE_AUDIO: - if (game->config.music) snprintf(text, 255, "Music volume: %d0%%", game->config.music); - else sprintf(text, "Music disabled"); - DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text); - if (game->config.fx) snprintf(text, 255, "Effects volume: %d0%%", game->config.fx); - else sprintf(text, "Effects disabled"); - DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text); - DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); - break; - case MENUSTATE_ABOUT: - al_use_transform(&cur_trans); - About(game, data); - break; - case MENUSTATE_VIDEO: - if (data->options.fullscreen) { - sprintf(text, "Fullscreen: yes"); - color = al_map_rgba(0,0,0,128); - } - else { - sprintf(text, "Fullscreen: no"); - color = data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255); - } - DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text); - sprintf(text, "Resolution: %dx", data->options.resolution); - DrawTextWithShadow(font, color, game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text); - DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); - break; - default: - data->selected=0; - DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Not implemented yet"); - break; - } - free(text); + ALLEGRO_FONT *font = data->font; + char* text = malloc(255*sizeof(char)); + struct ALLEGRO_COLOR color; + switch (data->menustate) { + case MENUSTATE_MAIN: + case MENUSTATE_HIDDEN: + if (!data->invisible) { + DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Start game"); + DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Options"); + DrawTextWithShadow(font, data->selected==2 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.7, ALLEGRO_ALIGN_CENTRE, "About"); + DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Exit"); + } + break; + case MENUSTATE_OPTIONS: + DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Video settings"); + DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Audio settings"); + DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); + break; + case MENUSTATE_AUDIO: + if (game->config.music) snprintf(text, 255, "Music volume: %d0%%", game->config.music); + else sprintf(text, "Music disabled"); + DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text); + if (game->config.fx) snprintf(text, 255, "Effects volume: %d0%%", game->config.fx); + else sprintf(text, "Effects disabled"); + DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text); + DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); + break; + case MENUSTATE_ABOUT: + al_use_transform(&cur_trans); + About(game, data); + break; + case MENUSTATE_VIDEO: + if (data->options.fullscreen) { + sprintf(text, "Fullscreen: yes"); + color = al_map_rgba(0,0,0,128); + } + else { + sprintf(text, "Fullscreen: no"); + color = data->selected==1 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255); + } + DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text); + sprintf(text, "Resolution: %dx", data->options.resolution); + DrawTextWithShadow(font, color, game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text); + DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back"); + break; + default: + data->selected=0; + DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(255,222, 120) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Not implemented yet"); + break; + } + free(text); - al_use_transform(&cur_trans); + al_use_transform(&cur_trans); } void ChangeMenuState(struct Game *game, struct MenuResources* data, enum menustate_enum state) { - data->menustate=state; - data->selected=0; - PrintConsole(game, "menu state changed %d", state); + data->menustate=state; + data->selected=0; + if (state == MENUSTATE_HIDDEN) { + al_set_sample_instance_gain(game->muzyczka.instance.fg, 0.0); + } else { + al_set_sample_instance_gain(game->muzyczka.instance.fg, 1.5); + } + PrintConsole(game, "menu state changed %d", state); } void Gamestate_Draw(struct Game *game, struct MenuResources* data) { - al_set_target_bitmap(al_get_backbuffer(game->display)); + al_set_target_bitmap(al_get_backbuffer(game->display)); - al_clear_to_color(al_map_rgb(3, 213, 255)); + al_clear_to_color(al_map_rgb(3, 213, 255)); - al_draw_bitmap(data->bg, 0, 0, 0); - al_draw_bitmap(data->monster, data->monster_pos, 10, 0); - if (!data->starting) { - al_draw_bitmap(data->title, 123, 25 - (pow(sin(data->title_pos), 2) * 16) - data->screen_pos, 0); - } + al_draw_bitmap(data->bg, 0, 0, 0); + al_draw_bitmap(data->monster, data->monster_pos, 10, 0); + if (!data->starting) { + al_draw_bitmap(data->title, 12, 25 - (pow(sin(data->title_pos), 2) * 16) - data->screen_pos, 0); + } - DrawMenuState(game, data); + if ((data->menustate == MENUSTATE_HIDDEN) && (!data->starting)) { + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.9, ALLEGRO_ALIGN_CENTRE, "Press RETURN"); + } + + DrawMenuState(game, data); } void Gamestate_Logic(struct Game *game, struct MenuResources* data) { - data->title_pos += 0.05; + data->title_pos += 0.05; - if (data->starting) { - data->monster_pos -= 6; + if (data->starting) { + data->monster_pos -= 6; - if (data->monster_pos < -202) { - data->starting = false; - LoadGamestate(game, "info"); - LoadGamestate(game, "level"); - StartGamestate(game, "info"); - StopGamestate(game, "menu"); - } + if (data->monster_pos < -202) { + data->starting = false; + LoadGamestate(game, "theend"); + LoadGamestate(game, "info"); + LoadGamestate(game, "rockets"); + LoadGamestate(game, "riots"); + LoadGamestate(game, "lollipop"); + LoadGamestate(game, "bonus"); + StartGamestate(game, "info"); + StopGamestate(game, "menu"); + } - } else { - data->monster_pos += 6; - if (data->monster_pos > 0) { - data->monster_pos = 0; - } - } + } else { + data->monster_pos += 6; + if (data->monster_pos > -40) { + data->monster_pos = -40; + } + } - if (data->menustate == MENUSTATE_HIDDEN) { - data->screen_pos -= (180 - data->screen_pos) / 4 + 1; - if (data->screen_pos < 0) { - data->screen_pos = 0; - data->invisible = false; - } - } else { - data->screen_pos += (data->screen_pos) / 4 + 1; - if (data->screen_pos > 180) { - data->screen_pos = 180; - } - } + if (data->menustate == MENUSTATE_HIDDEN) { + data->screen_pos -= (180 - data->screen_pos) / 4 + 1; + if (data->screen_pos < 0) { + data->screen_pos = 0; + data->invisible = false; + } + } else { + data->invisible = false; + data->screen_pos += (data->screen_pos) / 4 + 1; + if (data->screen_pos > 180) { + data->screen_pos = 180; + } + } } void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { - struct MenuResources *data = malloc(sizeof(struct MenuResources)); + struct MenuResources *data = malloc(sizeof(struct MenuResources)); - data->options.fullscreen = game->config.fullscreen; - data->options.fps = game->config.fps; - data->options.width = game->config.width; - data->options.height = game->config.height; - data->options.resolution = game->config.width / 320; - if (game->config.height / 180 < data->options.resolution) data->options.resolution = game->config.height / 180; - (*progress)(game); + data->options.fullscreen = game->config.fullscreen; + data->options.fps = game->config.fps; + data->options.width = game->config.width; + data->options.height = game->config.height; + data->options.resolution = game->config.width / 320; + if (game->config.height / 180 < data->options.resolution) data->options.resolution = game->config.height / 180; + (*progress)(game); - data->bg = al_load_bitmap( GetDataFilePath(game, "bg.png") ); - data->monster = al_load_bitmap( GetDataFilePath(game, "monster.png") ); - data->title = al_load_bitmap( GetDataFilePath(game, "title.png") ); - (*progress)(game); + data->bg = al_load_bitmap( GetDataFilePath(game, "bg.png") ); + data->monster = al_load_bitmap( GetDataFilePath(game, "light.png") ); + data->title = al_load_bitmap( GetDataFilePath(game, "title.png") ); + (*progress)(game); - data->sample = al_load_sample( GetDataFilePath(game, "monster.flac") ); - data->click_sample = al_load_sample( GetDataFilePath(game, "click.flac") ); - (*progress)(game); + game->muzyczka.sample.fg = al_load_sample( GetDataFilePath(game, "song-fg.flac") ); + game->muzyczka.sample.bg = al_load_sample( GetDataFilePath(game, "song-bg.flac") ); + game->muzyczka.sample.drums = al_load_sample( GetDataFilePath(game, "song-drums.flac") ); + data->click_sample = al_load_sample( GetDataFilePath(game, "click.flac") ); + (*progress)(game); - data->music = al_create_sample_instance(data->sample); - al_attach_sample_instance_to_mixer(data->music, game->audio.music); - al_set_sample_instance_playmode(data->music, ALLEGRO_PLAYMODE_LOOP); + game->muzyczka.instance.fg = al_create_sample_instance(game->muzyczka.sample.fg); + al_attach_sample_instance_to_mixer(game->muzyczka.instance.fg, game->audio.music); + al_set_sample_instance_playmode(game->muzyczka.instance.fg, ALLEGRO_PLAYMODE_LOOP); - data->click = al_create_sample_instance(data->click_sample); - al_attach_sample_instance_to_mixer(data->click, game->audio.fx); - al_set_sample_instance_playmode(data->click, ALLEGRO_PLAYMODE_ONCE); + game->muzyczka.instance.bg = al_create_sample_instance(game->muzyczka.sample.bg); + al_attach_sample_instance_to_mixer(game->muzyczka.instance.bg, game->audio.music); + al_set_sample_instance_playmode(game->muzyczka.instance.bg, ALLEGRO_PLAYMODE_LOOP); - if (!data->click_sample){ - fprintf(stderr, "Audio clip sample not loaded!\n" ); - exit(-1); - } - (*progress)(game); + game->muzyczka.instance.drums = al_create_sample_instance(game->muzyczka.sample.drums); + al_attach_sample_instance_to_mixer(game->muzyczka.instance.drums, game->audio.music); + al_set_sample_instance_playmode(game->muzyczka.instance.drums, ALLEGRO_PLAYMODE_LOOP); - data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),game->viewport.height*0.05,0 ); + data->click = al_create_sample_instance(data->click_sample); + al_attach_sample_instance_to_mixer(data->click, game->audio.fx); + al_set_sample_instance_playmode(data->click, ALLEGRO_PLAYMODE_ONCE); - al_set_target_backbuffer(game->display); - return data; + if (!data->click_sample){ + fprintf(stderr, "Audio clip sample not loaded!\n" ); + exit(-1); + } + (*progress)(game); + + data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),game->viewport.height*0.05,0 ); + + al_set_target_backbuffer(game->display); + return data; } void Gamestate_Stop(struct Game *game, struct MenuResources* data) { - //al_stop_sample_instance(data->music); + //al_stop_sample_instance(data->music); } void Gamestate_Unload(struct Game *game, struct MenuResources* data) { - al_stop_sample_instance(data->music); - al_destroy_bitmap(data->bg); - al_destroy_bitmap(data->title); - al_destroy_bitmap(data->monster); - al_destroy_font(data->font); - //al_destroy_sample_instance(data->music); - al_destroy_sample_instance(data->click); - //al_destroy_sample(data->sample); - al_destroy_sample(data->click_sample); + //al_stop_sample_instance(data->music); + al_destroy_bitmap(data->bg); + al_destroy_bitmap(data->title); + al_destroy_bitmap(data->monster); + al_destroy_font(data->font); + //al_destroy_sample_instance(data->music); + al_destroy_sample_instance(data->click); + //al_destroy_sample(data->sample); + al_destroy_sample(data->click_sample); } void StartGame(struct Game *game, struct MenuResources *data) { - ChangeMenuState(game,data,MENUSTATE_HIDDEN); - data->starting = true; + + game->mediator.lives = 3; + game->mediator.score = 0; + game->mediator.modificator = 0.9756; + + ChangeMenuState(game,data,MENUSTATE_HIDDEN); + al_set_sample_instance_gain(game->muzyczka.instance.drums, 0.0); + al_set_sample_instance_gain(game->muzyczka.instance.fg, 1.5); + al_set_sample_instance_gain(game->muzyczka.instance.bg, 1.5); + data->starting = true; } void Gamestate_Start(struct Game *game, struct MenuResources* data) { - data->title_pos = 0; - data->screen_pos = 180; - data->invisible = true; - data->monster_pos = -202; - data->starting = false; + al_ungrab_mouse(); + if (!game->config.fullscreen) al_show_mouse_cursor(game->display); + + data->title_pos = 0; + data->screen_pos = 180; + data->invisible = true; + data->monster_pos = -202; + data->starting = false; + + ChangeMenuState(game,data,MENUSTATE_HIDDEN); + al_play_sample_instance(game->muzyczka.instance.fg); + al_play_sample_instance(game->muzyczka.instance.bg); + al_play_sample_instance(game->muzyczka.instance.drums); + al_set_sample_instance_gain(game->muzyczka.instance.fg, 0.0); + al_set_sample_instance_gain(game->muzyczka.instance.bg, 1.5); + al_set_sample_instance_gain(game->muzyczka.instance.drums, 1.5); - ChangeMenuState(game,data,MENUSTATE_HIDDEN); - al_play_sample_instance(data->music); } void Gamestate_ProcessEvent(struct Game *game, struct MenuResources* data, ALLEGRO_EVENT *ev) { - if ((data->menustate == MENUSTATE_ABOUT) && (ev->type == ALLEGRO_EVENT_KEY_DOWN)) { - ChangeMenuState(game, data, MENUSTATE_MAIN); - return; - } + if ((data->menustate == MENUSTATE_ABOUT) && (ev->type == ALLEGRO_EVENT_KEY_DOWN)) { + ChangeMenuState(game, data, MENUSTATE_MAIN); + return; + } - if (ev->type != ALLEGRO_EVENT_KEY_DOWN) return; + if (ev->type != ALLEGRO_EVENT_KEY_DOWN) return; - if (data->starting) return; + if (data->starting) return; - if (ev->keyboard.keycode==ALLEGRO_KEY_UP) { - data->selected--; - if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { - data->selected --; - } - if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected--; - al_play_sample_instance(data->click); - } else if (ev->keyboard.keycode==ALLEGRO_KEY_DOWN) { - data->selected++; - if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected++; - if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { - data->selected ++; - } + if (ev->keyboard.keycode==ALLEGRO_KEY_UP) { + data->selected--; + if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { + data->selected --; + } + if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected--; + al_play_sample_instance(data->click); + } else if (ev->keyboard.keycode==ALLEGRO_KEY_DOWN) { + data->selected++; + if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected++; + if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { + data->selected ++; + } - al_play_sample_instance(data->click); - } + al_play_sample_instance(data->click); + } - if (ev->keyboard.keycode==ALLEGRO_KEY_ENTER) { - char *text; - al_play_sample_instance(data->click); - switch (data->menustate) { - case MENUSTATE_MAIN: - switch (data->selected) { - case 0: - StartGame(game, data); - break; - case 1: - ChangeMenuState(game,data,MENUSTATE_OPTIONS); - break; - case 2: - ChangeMenuState(game,data,MENUSTATE_ABOUT); - break; - case 3: - UnloadGamestate(game, "menu"); - break; - } - break; - case MENUSTATE_HIDDEN: - ChangeMenuState(game,data,MENUSTATE_MAIN); - break; - case MENUSTATE_AUDIO: - text = malloc(255*sizeof(char)); - switch (data->selected) { - case 0: - game->config.music--; - if (game->config.music<0) game->config.music=10; - snprintf(text, 255, "%d", game->config.music); - SetConfigOption(game, "SuperDerpy", "music", text); - al_set_mixer_gain(game->audio.music, game->config.music/10.0); - break; - case 1: - game->config.fx--; - if (game->config.fx<0) game->config.fx=10; - snprintf(text, 255, "%d", game->config.fx); - SetConfigOption(game, "SuperDerpy", "fx", text); - al_set_mixer_gain(game->audio.fx, game->config.fx/10.0); - break; - case 2: - game->config.voice--; - if (game->config.voice<0) game->config.voice=10; - snprintf(text, 255, "%d", game->config.voice); - SetConfigOption(game, "SuperDerpy", "voice", text); - al_set_mixer_gain(game->audio.voice, game->config.voice/10.0); - break; - case 3: - ChangeMenuState(game,data,MENUSTATE_OPTIONS); - break; - } - free(text); - break; - case MENUSTATE_OPTIONS: - switch (data->selected) { - case 0: - ChangeMenuState(game,data,MENUSTATE_VIDEO); - break; - case 1: - ChangeMenuState(game,data,MENUSTATE_AUDIO); - break; - case 3: - ChangeMenuState(game,data,MENUSTATE_MAIN); - break; - default: - break; - } - break; - case MENUSTATE_VIDEO: - switch (data->selected) { - case 0: - data->options.fullscreen = !data->options.fullscreen; - if (data->options.fullscreen) - SetConfigOption(game, "SuperDerpy", "fullscreen", "1"); - else - SetConfigOption(game, "SuperDerpy", "fullscreen", "0"); - al_set_display_flag(game->display, ALLEGRO_FULLSCREEN_WINDOW, data->options.fullscreen); - SetupViewport(game); - PrintConsole(game, "Fullscreen toggled"); - break; - case 1: - data->options.resolution++; + if (ev->keyboard.keycode==ALLEGRO_KEY_ENTER) { + char *text; + al_play_sample_instance(data->click); + switch (data->menustate) { + case MENUSTATE_MAIN: + switch (data->selected) { + case 0: + StartGame(game, data); + break; + case 1: + ChangeMenuState(game,data,MENUSTATE_OPTIONS); + break; + case 2: + ChangeMenuState(game,data,MENUSTATE_ABOUT); + break; + case 3: + UnloadGamestate(game, "menu"); + break; + } + break; + case MENUSTATE_HIDDEN: + ChangeMenuState(game,data,MENUSTATE_MAIN); + break; + case MENUSTATE_AUDIO: + text = malloc(255*sizeof(char)); + switch (data->selected) { + case 0: + game->config.music--; + if (game->config.music<0) game->config.music=10; + snprintf(text, 255, "%d", game->config.music); + SetConfigOption(game, "SuperDerpy", "music", text); + al_set_mixer_gain(game->audio.music, game->config.music/10.0); + break; + case 1: + game->config.fx--; + if (game->config.fx<0) game->config.fx=10; + snprintf(text, 255, "%d", game->config.fx); + SetConfigOption(game, "SuperDerpy", "fx", text); + al_set_mixer_gain(game->audio.fx, game->config.fx/10.0); + break; + case 2: + game->config.voice--; + if (game->config.voice<0) game->config.voice=10; + snprintf(text, 255, "%d", game->config.voice); + SetConfigOption(game, "SuperDerpy", "voice", text); + al_set_mixer_gain(game->audio.voice, game->config.voice/10.0); + break; + case 3: + ChangeMenuState(game,data,MENUSTATE_OPTIONS); + break; + } + free(text); + break; + case MENUSTATE_OPTIONS: + switch (data->selected) { + case 0: + ChangeMenuState(game,data,MENUSTATE_VIDEO); + break; + case 1: + ChangeMenuState(game,data,MENUSTATE_AUDIO); + break; + case 3: + ChangeMenuState(game,data,MENUSTATE_MAIN); + break; + default: + break; + } + break; + case MENUSTATE_VIDEO: + switch (data->selected) { + case 0: + data->options.fullscreen = !data->options.fullscreen; + if (data->options.fullscreen) + SetConfigOption(game, "SuperDerpy", "fullscreen", "1"); + else + SetConfigOption(game, "SuperDerpy", "fullscreen", "0"); + al_set_display_flag(game->display, ALLEGRO_FULLSCREEN_WINDOW, data->options.fullscreen); + game->config.fullscreen = data->options.fullscreen; + if (!data->options.fullscreen) { + al_show_mouse_cursor(game->display); + } else { + al_hide_mouse_cursor(game->display); + } + SetupViewport(game); + PrintConsole(game, "Fullscreen toggled"); + break; + case 1: + data->options.resolution++; - int max = 0, i = 0; + int max = 0, i = 0; - for (i=0; i < al_get_num_video_adapters(); i++) { - ALLEGRO_MONITOR_INFO aminfo; - al_get_monitor_info(i , &aminfo); - int desktop_width = aminfo.x2 - aminfo.x1 + 1; - int desktop_height = aminfo.y2 - aminfo.y1 + 1; - int localmax = desktop_width / 320; - if (desktop_height / 180 < localmax) localmax = desktop_height / 180; - if (localmax > max) max = localmax; - } + for (i=0; i < al_get_num_video_adapters(); i++) { + ALLEGRO_MONITOR_INFO aminfo; + al_get_monitor_info(i , &aminfo); + int desktop_width = aminfo.x2 - aminfo.x1 + 1; + int desktop_height = aminfo.y2 - aminfo.y1 + 1; + int localmax = desktop_width / 320; + if (desktop_height / 180 < localmax) localmax = desktop_height / 180; + if (localmax > max) max = localmax; + } - if (data->options.resolution > max) data->options.resolution = 1; - text = malloc(255*sizeof(char)); - snprintf(text, 255, "%d", data->options.resolution * 320); - SetConfigOption(game, "SuperDerpy", "width", text); - snprintf(text, 255, "%d", data->options.resolution * 180); - SetConfigOption(game, "SuperDerpy", "height", text); - free(text); - al_resize_display(game->display, data->options.resolution * 320, data->options.resolution * 180); + if (data->options.resolution > max) data->options.resolution = 1; + text = malloc(255*sizeof(char)); + snprintf(text, 255, "%d", data->options.resolution * 320); + SetConfigOption(game, "SuperDerpy", "width", text); + snprintf(text, 255, "%d", data->options.resolution * 180); + SetConfigOption(game, "SuperDerpy", "height", text); + free(text); + al_resize_display(game->display, data->options.resolution * 320, data->options.resolution * 180); - if ((al_get_display_width(game->display) < (data->options.resolution * 320)) || (al_get_display_height(game->display) < (data->options.resolution * 180))) { - SetConfigOption(game, "SuperDerpy", "width", "320"); - SetConfigOption(game, "SuperDerpy", "height", "180"); - data->options.resolution = 1; - al_resize_display(game->display, 320, 180); - } + if ((al_get_display_width(game->display) < (data->options.resolution * 320)) || (al_get_display_height(game->display) < (data->options.resolution * 180))) { + SetConfigOption(game, "SuperDerpy", "width", "320"); + SetConfigOption(game, "SuperDerpy", "height", "180"); + data->options.resolution = 1; + al_resize_display(game->display, 320, 180); + } - SetupViewport(game); - PrintConsole(game, "Resolution changed"); - break; - case 3: - ChangeMenuState(game,data,MENUSTATE_OPTIONS); - break; - default: - break; - } - break; - case MENUSTATE_ABOUT: - break; - default: - UnloadGamestate(game, "menu"); - return; - break; - } - } else if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) { - switch (data->menustate) { - case MENUSTATE_OPTIONS: - ChangeMenuState(game,data,MENUSTATE_MAIN); - break; - case MENUSTATE_ABOUT: - ChangeMenuState(game,data,MENUSTATE_MAIN); - break; - case MENUSTATE_HIDDEN: - UnloadGamestate(game, "menu"); - break; - case MENUSTATE_VIDEO: - ChangeMenuState(game,data,MENUSTATE_OPTIONS); - break; - case MENUSTATE_AUDIO: - ChangeMenuState(game,data,MENUSTATE_OPTIONS); - break; - default: - ChangeMenuState(game,data,MENUSTATE_HIDDEN); - data->selected = -1; - data->title_pos = 0; - return; - } - } + SetupViewport(game); + PrintConsole(game, "Resolution changed"); + break; + case 3: + ChangeMenuState(game,data,MENUSTATE_OPTIONS); + break; + default: + break; + } + break; + case MENUSTATE_ABOUT: + break; + default: + UnloadGamestate(game, "menu"); + return; + break; + } + } else if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) { + switch (data->menustate) { + case MENUSTATE_OPTIONS: + ChangeMenuState(game,data,MENUSTATE_MAIN); + break; + case MENUSTATE_ABOUT: + ChangeMenuState(game,data,MENUSTATE_MAIN); + break; + case MENUSTATE_HIDDEN: + UnloadGamestate(game, "menu"); + break; + case MENUSTATE_VIDEO: + ChangeMenuState(game,data,MENUSTATE_OPTIONS); + break; + case MENUSTATE_AUDIO: + ChangeMenuState(game,data,MENUSTATE_OPTIONS); + break; + default: + ChangeMenuState(game,data,MENUSTATE_HIDDEN); + data->selected = -1; + data->title_pos = 0; + return; + } + } - if (data->selected==-1) data->selected=3; - if (data->selected==4) data->selected=0; - return; + if (data->selected==-1) data->selected=3; + if (data->selected==4) data->selected=0; + return; } void Gamestate_Pause(struct Game *game, struct MenuResources* data) {} diff --git a/src/gamestates/riots.c b/src/gamestates/riots.c new file mode 100644 index 0000000..9b5a878 --- /dev/null +++ b/src/gamestates/riots.c @@ -0,0 +1,506 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include "../utils.h" +#include "../timeline.h" +#include "riots.h" + +int Gamestate_ProgressCount = 11; + +struct Rocket* CreateRocket(struct Game *game, struct RocketsResources* data, struct Rocket* rockets, bool right) { + struct Rocket *n = malloc(sizeof(struct Rocket)); + n->next = NULL; + n->prev = NULL; + n->dx = (right ? -1.5 : 1.5) + (rand() / (float)RAND_MAX) * 0.6 - 0.3; + n->dy = -2.1 + (rand() / (float)RAND_MAX) * 0.5 - 0.25; + n->modifier = 0.025; + n->blown = false; + n->character = CreateCharacter(game, "rocket"); + n->character->spritesheets = data->rocket_template->spritesheets; + n->character->shared = true; + SelectSpritesheet(game, n->character, rand() % 2 ? "rock" : rand() % 2 ? "bottle" : "bottle2"); + SetCharacterPosition(game, n->character, (right ? 250 : 50) + rand() % 90 - 40, 100, right ? -0.33 : 0.33); + al_play_sample_instance(data->jump_sound); + data->currentspawn = data->spawnspeed + (data->spawnspeed * 0.1) * (float)(rand() / (float)RAND_MAX * 2) - (data->spawnspeed * 0.05); + + if (rockets) { + struct Rocket *tmp = rockets; + while (tmp->next) { + tmp=tmp->next; + } + tmp->next = n; + n->prev = tmp; + return rockets; + } else { + return n; + } +} + + +void DrawRockets(struct Game *game, struct RocketsResources* data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + DrawCharacter(game, tmp->character, al_map_rgb(255,255,255), 0); + + tmp=tmp->next; + } +} + +bool switchMinigame(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "riots"); + game->mediator.next = "rockets"; + StartGamestate(game, GetAbstractIsItBonusLevelTimeNowFactoryProvider(game) ? "bonus" : "rockets"); + } + return true; +} + +bool theEnd(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "riots"); + StartGamestate(game, "theend"); + } + return true; +} + +void UpdateRockets(struct Game *game, struct RocketsResources *data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + tmp->dy+= tmp->modifier; + if (!tmp->blown) { + tmp->dx+= (tmp->dx > 0) ? (-tmp->modifier / 5 + 0.001) : (tmp->modifier / 5 - 0.001); + } + MoveCharacter(game, tmp->character, tmp->dx, tmp->dy, tmp->blown ? 0 : ((tmp->dx > 0) ? 0.0166 : -0.0166)); + AnimateCharacter(game, tmp->character, 1); + + if (!tmp->blown) { + + if (((((tmp->character->y > 90) && (rand() % 4 == 0) && (tmp->dy > 0)))) && (tmp->character->x > -20 && tmp->character->x < 320)) { + tmp->blown = true; + tmp->modifier = 0; + tmp->character->angle = 0; + tmp->dx = 0; + tmp->dy = 0; + SelectSpritesheet(game, tmp->character, "boom"); + MoveCharacter(game, tmp->character, 5, 5, 0); + + if (!((tmp->character->x > 140) && (tmp->character->x < 180))) { + if (!data->lost) { + AdvanceLevel(game, false); + + data->lost = true; + data->flash = 4; + data->counter = 0; + TM_AddDelay(data->timeline, 3500); + if (game->mediator.lives > 0) { + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } else { + TM_AddAction(data->timeline, theEnd, NULL, "theEnd"); + } + data->spawnspeed = 10; + + al_play_sample_instance(data->riot_sound); + + } + al_play_sample_instance(data->boom_sound); + + } + + } else if (tmp->character->x < -20 || tmp->character->x > 320) { + tmp->blown = true; + tmp->modifier = 0; + tmp->character->angle = 0; + tmp->dx = 0; + tmp->dy = 0; + SelectSpritesheet(game, tmp->character, "blank"); + al_play_sample_instance(data->boom_sound); + } + } + tmp=tmp->next; + } +} + +void Gamestate_Logic(struct Game *game, struct RocketsResources* data) { + + if ((data->spawncounter == data->currentspawn) && ((data->counter < data->timelimit) || (data->lost))) { + if (rand() % 2 == 0) { + data->rockets_left = CreateRocket(game, data, data->rockets_left, false); + } else { + data->rockets_right = CreateRocket(game, data, data->rockets_right, true); + } + data->spawncounter = 0; + } + + if (!data->flash) { + UpdateRockets(game, data, data->rockets_left); + UpdateRockets(game, data, data->rockets_right); + } else { + data->flash--; + } + + if (data->lost) { + data->zadyma++; + if (data->zadyma >= 255) { + data->zadyma = 255; + } + } + + AnimateCharacter(game, data->usa_flag, 1); + AnimateCharacter(game, data->ru_flag, 1); + AnimateCharacter(game, data->riot, 1); + if ((data->lost) && (data->hearts > 80)) { + AnimateCharacter(game, game->mediator.heart, 1); + if (game->mediator.heart->pos == 6) { + al_play_sample_instance(data->boom_sound); + } + } + + if (data->lost) { + data->hearts++; + } + + if (data->won) { + AnimateCharacter(game, data->euro, 1); + } + + if ((data->counter >= data->timelimit) && (!data->lost) && (!data->won)) { + bool stillthere = false; + struct Rocket *tmp = data->rockets_left; + while (tmp) { + if (!tmp->blown) { + stillthere = true; + break; + } + tmp = tmp->next; + } + tmp = data->rockets_right; + while (tmp) { + if (!tmp->blown) { + stillthere = true; + break; + } + tmp = tmp->next; + } + if (!stillthere) { + SelectSpritesheet(game, data->euro, "euro"); + SetCharacterPosition(game, data->euro, 0, 0, 0); + al_play_sample_instance(data->wuwu_sound); + data->won = true; + AdvanceLevel(game, true); + SelectSpritesheet(game, data->usa_flag, "poland"); + SelectSpritesheet(game, data->ru_flag, "poland"); + TM_AddDelay(data->timeline, 2500); + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } + } + + + void iterate(struct Rocket *start) { + struct Rocket *tmp1 = start; + while (tmp1) { + if (!tmp1->blown) { + // if (CheckCollision(game, data, data->cursor, tmp1->character)) { + + if ( (abs(tmp1->character->y - data->cursor->y) <= 10) && + (((tmp1->character->x <= data->cursor->x + al_get_bitmap_width(data->cursor->bitmap)) && (tmp1->character->x + al_get_bitmap_width(tmp1->character->bitmap) >= data->cursor->x + al_get_bitmap_width(data->cursor->bitmap))) || + + ((tmp1->character->x + al_get_bitmap_width(tmp1->character->bitmap) >= data->cursor->x) && (tmp1->character->x + al_get_bitmap_width(tmp1->character->bitmap) <= data->cursor->x + al_get_bitmap_width(data->cursor->bitmap))) )) { + + if (tmp1->character->y < data->cursor->y) { + tmp1->dx = 0; + tmp1->dy = 0; + tmp1->modifier = 0; + tmp1->blown = true; + SelectSpritesheet(game, tmp1->character, "blank"); + } else if (tmp1->dy < 0) { + tmp1->dy *= -1; + } + + al_play_sample_instance(data->rocket_sound); + + } + + } + tmp1 = tmp1->next; + } + + } + iterate(data->rockets_left); + iterate(data->rockets_right); + + data->counter++; + data->spawncounter++; + data->cloud_rotation += 0.002; + + TM_Process(data->timeline); +} + +void Gamestate_Draw(struct Game *game, struct RocketsResources* data) { + + al_set_target_bitmap(data->pixelator); + + if (!data->lost) { + al_draw_bitmap(data->bg, 0, 0, 0); + //al_draw_bitmap(data->earth2, 0, 0, 0); + //al_draw_bitmap(data->combined, 0, 0, 0); + } else if (!data->won) { + al_draw_tinted_bitmap(data->bg, al_map_rgb(255, 192, 128), 0, 0, 0); + //al_draw_tinted_bitmap(data->earth2, al_map_rgb(255, 192, 128), 0, 0, 0); + //al_draw_tinted_bitmap(data->combined, al_map_rgb(255, 192, 128), 0, 0, 0); + } else { + al_draw_bitmap(data->bg, 0, 0, 0); + al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgba(255,255,255, 64)); + } + + if (data->won) { + DrawCharacter(game, data->euro, al_map_rgb(255,255,255), 0); + } + + + if ((!data->lost) && (!data->won)) { + DrawCharacter(game, data->cursor, al_map_rgb(255,255,255), 0); + } + + DrawRockets(game, data, data->rockets_left); + DrawRockets(game, data, data->rockets_right); + + if (data->lost) { + DrawCharacter(game, data->riot, al_map_rgb(255,255,255), 0); + } else { + DrawCharacter(game, data->usa_flag, al_map_rgb(255,255,255), 1); + DrawCharacter(game, data->ru_flag, al_map_rgb(255,255,255), 0); + al_draw_bitmap(data->earth, 5, 50, 0); + } + + + if (data->lost) { + al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 2, 0, 0); + al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 2 + 640, 0, 0); + } else { + al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 3, 0, 0); + al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 3 + 640, 0, 0); + } + + + if ((!data->lost) && (!data->won)) { + al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142)); + al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30)); + al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+ 160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80)); + } + + if (data->flash) { + al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgb(255, 255, 255)); + } + + al_set_target_backbuffer(game->display); + al_draw_bitmap(data->pixelator, 0, 0, 0); + + if ((data->lost) && (data->hearts > 80)) { + ShowLevelStatistics(game); + } + + //Gamestate_Logic(game, data); + +} + +void Gamestate_Start(struct Game *game, struct RocketsResources* data) { + data->rockets_left = NULL; + data->rockets_right = NULL; + + data->timelimit = 400 * game->mediator.modificator; + data->spawnspeed = 80 / game->mediator.modificator; + data->currentspawn = data->spawnspeed; + data->spawncounter = data->spawnspeed - 20; + + data->lost = false; + data->won = false; + data->hearts = 0; + + data->flash = 0; + data->zadyma = 16; + + SetCharacterPosition(game, data->usa_flag, 185, 80, 0); + SetCharacterPosition(game, data->ru_flag, 25, 80, 0); + + SetCharacterPosition(game, data->cursor, 320/2, 50, 0); + + SetCharacterPosition(game, data->riot, 0, 0, 0); + SelectSpritesheet(game, data->riot, "riot"); + + SelectSpritesheet(game, data->usa_flag, "legia"); + SelectSpritesheet(game, data->ru_flag, "lech"); + + SelectSpritesheet(game, data->cursor, "hand"); + + data->counter = 0; + data->cloud_rotation = 0; + + data->mousemove.bottom = false; + data->mousemove.top = false; + data->mousemove.left = false; + data->mousemove.right = false; + + al_set_mouse_xy(game->display, al_get_display_width(game->display) / 2, al_get_display_height(game->display) / 2); + +} + +void Gamestate_ProcessEvent(struct Game *game, struct RocketsResources* data, ALLEGRO_EVENT *ev) { + TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "riots", "theend"); + } else if (ev->type == ALLEGRO_EVENT_MOUSE_AXES) { + int mousex = ev->mouse.x / (al_get_display_width(game->display) / 320); + int mousey = 50; + data->mousemove.right = mousex > data->cursor->x; + data->mousemove.top = mousey < data->cursor->y; + data->mousemove.left = mousex < data->cursor->x; + data->mousemove.bottom = mousey > data->cursor->y; + SetCharacterPosition(game, data->cursor, mousex, mousey , 0); // FIXMEEEE! + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct RocketsResources *data = malloc(sizeof(struct RocketsResources)); + + data->timeline = TM_Init(game, "riots"); + + data->bg = al_load_bitmap( GetDataFilePath(game, "riots/bg.png")); + + data->earth = al_load_bitmap( GetDataFilePath(game, "riots/separator.png")); + + data->clouds = al_load_bitmap( GetDataFilePath(game, "riots/fog.png")); + (*progress)(game); + + data->rocket_sample = al_load_sample( GetDataFilePath(game, "bump.flac") ); + (*progress)(game); + data->boom_sample = al_load_sample( GetDataFilePath(game, "boom.flac") ); + (*progress)(game); + data->jump_sample = al_load_sample( GetDataFilePath(game, "launch.flac") ); + (*progress)(game); + data->rainbow_sample = al_load_sample( GetDataFilePath(game, "win.flac") ); + (*progress)(game); + data->wuwu_sample = al_load_sample( GetDataFilePath(game, "riots/vuvu.flac") ); + (*progress)(game); + data->riot_sample = al_load_sample( GetDataFilePath(game, "riots/riot.flac") ); + (*progress)(game); + + data->rocket_sound = al_create_sample_instance(data->rocket_sample); + al_attach_sample_instance_to_mixer(data->rocket_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rocket_sound, ALLEGRO_PLAYMODE_ONCE); + + data->boom_sound = al_create_sample_instance(data->boom_sample); + al_attach_sample_instance_to_mixer(data->boom_sound, game->audio.fx); + al_set_sample_instance_playmode(data->boom_sound, ALLEGRO_PLAYMODE_ONCE); + + data->rainbow_sound = al_create_sample_instance(data->rainbow_sample); + al_attach_sample_instance_to_mixer(data->rainbow_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rainbow_sound, ALLEGRO_PLAYMODE_ONCE); + + data->jump_sound = al_create_sample_instance(data->jump_sample); + al_attach_sample_instance_to_mixer(data->jump_sound, game->audio.fx); + al_set_sample_instance_playmode(data->jump_sound, ALLEGRO_PLAYMODE_ONCE); + + data->riot_sound = al_create_sample_instance(data->riot_sample); + al_attach_sample_instance_to_mixer(data->riot_sound, game->audio.fx); + al_set_sample_instance_playmode(data->riot_sound, ALLEGRO_PLAYMODE_ONCE); + + data->wuwu_sound = al_create_sample_instance(data->wuwu_sample); + al_attach_sample_instance_to_mixer(data->wuwu_sound, game->audio.fx); + al_set_sample_instance_playmode(data->wuwu_sound, ALLEGRO_PLAYMODE_ONCE); + + + data->cursor = CreateCharacter(game, "cursor"); + RegisterSpritesheet(game, data->cursor, "hand"); + LoadSpritesheets(game, data->cursor); + (*progress)(game); + + data->pixelator = al_create_bitmap(320, 180); + al_set_target_bitmap(data->pixelator); + al_clear_to_color(al_map_rgb(0, 0, 0)); + + al_set_target_backbuffer(game->display); + + data->rocket_template = CreateCharacter(game, "rocket"); + RegisterSpritesheet(game, data->rocket_template, "rock"); + RegisterSpritesheet(game, data->rocket_template, "bottle"); + RegisterSpritesheet(game, data->rocket_template, "bottle2"); + RegisterSpritesheet(game, data->rocket_template, "atom"); + RegisterSpritesheet(game, data->rocket_template, "boom"); + RegisterSpritesheet(game, data->rocket_template, "blank"); + LoadSpritesheets(game, data->rocket_template); + (*progress)(game); + + data->usa_flag = CreateCharacter(game, "kibols"); + RegisterSpritesheet(game, data->usa_flag, "legia"); + RegisterSpritesheet(game, data->usa_flag, "poland"); + LoadSpritesheets(game, data->usa_flag); + + data->ru_flag = CreateCharacter(game, "kibols"); + RegisterSpritesheet(game, data->ru_flag, "lech"); + RegisterSpritesheet(game, data->ru_flag, "poland"); + LoadSpritesheets(game, data->ru_flag); + (*progress)(game); + + data->rainbow = CreateCharacter(game, "rainbow"); + RegisterSpritesheet(game, data->rainbow, "shine"); + RegisterSpritesheet(game, data->rainbow, "be"); + LoadSpritesheets(game, data->rainbow); + + data->riot = CreateCharacter(game, "riot"); + RegisterSpritesheet(game, data->riot, "riot"); + LoadSpritesheets(game, data->riot); + (*progress)(game); + + data->euro = CreateCharacter(game, "euro"); + RegisterSpritesheet(game, data->euro, "euro"); + LoadSpritesheets(game, data->euro); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct RocketsResources* data) { + TM_CleanQueue(data->timeline); +} + +void Gamestate_Unload(struct Game *game, struct RocketsResources* data) { + al_destroy_bitmap(data->bg); + al_destroy_bitmap(data->earth); + al_destroy_bitmap(data->clouds); + al_destroy_bitmap(data->pixelator); + al_destroy_sample_instance(data->rocket_sound); + al_destroy_sample_instance(data->boom_sound); + al_destroy_sample(data->rocket_sample); + al_destroy_sample(data->boom_sample); + // TODO: DestroyCharacters + free(data); +} + +void Gamestate_Reload(struct Game *game, struct RocketsResources* data) {} + +void Gamestate_Resume(struct Game *game, struct RocketsResources* data) { + TM_Resume(data->timeline); +} +void Gamestate_Pause(struct Game *game, struct RocketsResources* data) { + TM_Pause(data->timeline); +} diff --git a/src/gamestates/riots.h b/src/gamestates/riots.h new file mode 100644 index 0000000..6255f4f --- /dev/null +++ b/src/gamestates/riots.h @@ -0,0 +1,51 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct RocketsResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bg, *earth, *earth2, *pixelator, *clouds; + struct Character *rocket_template, *usa_flag, *ru_flag, *cursor, *rainbow, *riot, *euro; + + struct Rocket { + struct Character *character; + float dx, dy, modifier; + bool blown, bumped; + struct Rocket *next, *prev; + } *rockets_left, *rockets_right; + + int counter, hearts; + float cloud_rotation; + + struct { + bool top, right, left, bottom; + } mousemove; + + ALLEGRO_SAMPLE *rocket_sample, *boom_sample, *rainbow_sample, *jump_sample, *wuwu_sample, *riot_sample; + ALLEGRO_SAMPLE_INSTANCE *rocket_sound, *boom_sound, *rainbow_sound, *jump_sound, *wuwu_sound, *riot_sound; + + bool lost, won; + + int flash, zadyma; + + int timelimit, spawnspeed, currentspawn, spawncounter; + + struct Timeline *timeline; +}; diff --git a/src/gamestates/rockets.c b/src/gamestates/rockets.c new file mode 100644 index 0000000..ab329a1 --- /dev/null +++ b/src/gamestates/rockets.c @@ -0,0 +1,588 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include "../utils.h" +#include "../timeline.h" +#include "rockets.h" + +int Gamestate_ProgressCount = 9; + +struct Rocket* CreateRocket(struct Game *game, struct RocketsResources* data, struct Rocket* rockets, bool right) { + struct Rocket *n = malloc(sizeof(struct Rocket)); + n->next = NULL; + n->prev = NULL; + n->dx = (right ? -1.5 : 1.5) + (rand() / (float)RAND_MAX) * 0.6 - 0.3; + n->dy = -2.1 + (rand() / (float)RAND_MAX) * 0.5 - 0.25; + n->modifier = 0.025; + n->blown = false; + n->character = CreateCharacter(game, "rocket"); + n->character->spritesheets = data->rocket_template->spritesheets; + n->character->shared = true; + SelectSpritesheet(game, n->character, right ? "usa" : "ru"); + SetCharacterPosition(game, n->character, right ? 270 : 48, right ? 136 : 122, right ? -0.33 : 0.33); + al_play_sample_instance(data->jump_sound); + + data->currentspawn = data->spawnspeed + (data->spawnspeed * 0.1) * (float)(rand() / (float)RAND_MAX * 2) - (data->spawnspeed * 0.05); + + if (rockets) { + struct Rocket *tmp = rockets; + while (tmp->next) { + tmp=tmp->next; + } + tmp->next = n; + n->prev = tmp; + return rockets; + } else { + return n; + } +} + +bool CheckCollision(struct Game *game, struct RocketsResources* data, struct Character* character1, struct Character* character2) { + + bool check(int x, int y, int w, int h, int x2, int y2, int w2, int h2) { + + // HACK LOL I DON'T EVEN + w /= character2->spritesheet->cols; + h /= character2->spritesheet->cols; + w2 /= character1->spritesheet->cols; + h2 /= character1->spritesheet->cols; + + //if ((((x>=derpyx+0.38*derpyw+derpyo) && (x<=derpyx+0.94*derpyw+derpyo)) || ((x+w>=derpyx+0.38*derpyw+derpyo) && (x+w<=derpyx+0.94*derpyw+derpyo)) || ((x<=derpyx+0.38*derpyw+derpyo) && (x+w>=derpyx+0.94*derpyw+derpyo))) && + // (((y>=derpyy+0.26*derpyh) && (y<=derpyy+0.76*derpyh)) || ((y+h>=derpyy+0.26*derpyh) && (y+h<=derpyy+0.76*derpyh)) || ((y<=derpyy+0.26*derpyh) && (y+h>=derpyy+0.76*derpyh)))) { + al_draw_rectangle(x, y, x+w, y+h, al_map_rgb(255, 255, 255), 1); + al_draw_rectangle(x2, y2, x2+w2, y2+h2, al_map_rgb(255, 255, 255), 1); + if ((((x>=x2) && (x<=x2+w2)) || ((x+w>=x2) && (x+w<=x2+w2))) && (((y>=y2) && (y<=y2+h2)) || ((y+h>=y2) && (y+h<=y2+h2)))) { + al_draw_rectangle(x, y, x+w, y+h, al_map_rgb(255, 0, 0), 1); + al_draw_rectangle(x2, y2, x2+w2, y2+h2, al_map_rgb(0, 255, 0), 1); + return true; + } + + return false; + } + + bool pointInside(int x, int y, int w, int h) { + + bool value = false; + + if ((character2->angle <= 1.0 && character2->angle >= 0.0) || (character2->angle < -2.0 && character2->angle > -2.6)) { + value = value || check(character2->x + 8, character2->y + 15, al_get_bitmap_width(character2->bitmap) - 16, al_get_bitmap_height(character2->bitmap) - 9, x, y, w, h); + value = value || check(character2->x + 15, character2->y + 7, al_get_bitmap_width(character2->bitmap) - 9, al_get_bitmap_height(character2->bitmap) - 15, x, y, w, h); + } else if ((character2->angle >= -1.0 && character2->angle <= 0.0) || (character2->angle > 2.0 && character2->angle < 2.6)) { + value = value || check(character2->x + 14, character2->y + 15, al_get_bitmap_width(character2->bitmap) - 9,al_get_bitmap_height(character2->bitmap) - 10, x, y, w, h); + value = value || check(character2->x + 7, character2->y + 7, al_get_bitmap_width(character2->bitmap) - 16, al_get_bitmap_height(character2->bitmap) - 16, x, y, w, h); + } else if ((character2->angle > 1.0 && character2->angle < 2.0) || (character2->angle < -1.0 && character2->angle > -2.0)) { + value = value || check(character2->x + 6, character2->y + 12, al_get_bitmap_width(character2->bitmap) + 10, al_get_bitmap_height(character2->bitmap) - 18, x, y, w, h); + } else { + value = value || check(character2->x + 13, character2->y + 5, al_get_bitmap_width(character2->bitmap) - 18,al_get_bitmap_height(character2->bitmap) + 8, x, y, w, h); + } + + return value; + + } + + bool value = false; + + if (character1 == data->cursor) { + return pointInside(character1->x, character1->y, al_get_bitmap_width(character1->bitmap), al_get_bitmap_height(character1->bitmap)); + } + + if ((character1->angle <= 1.0 && character1->angle >= 0.0) || (character1->angle < -2.0 && character1->angle > -2.6)) { + value = value || pointInside(character1->x + 8, character1->y + 15, al_get_bitmap_width(character1->bitmap) - 16, al_get_bitmap_height(character1->bitmap) - 9); + value = value || pointInside(character1->x + 15, character1->y + 7, al_get_bitmap_width(character1->bitmap) - 9, al_get_bitmap_height(character1->bitmap) - 15); + } else if ((character1->angle >= -1.0 && character1->angle <= 0.0) || (character1->angle > 2.0 && character1->angle < 2.6)) { + value = value || pointInside(character1->x + 14, character1->y + 15, al_get_bitmap_width(character1->bitmap) - 9, al_get_bitmap_height(character1->bitmap) - 10); + value = value || pointInside(character1->x + 7, character1->y + 7,al_get_bitmap_width(character1->bitmap) - 16,al_get_bitmap_height(character1->bitmap) - 16); + } else if ((character1->angle > 1.0 && character1->angle < 2.0) || (character1->angle < -1.0 && character1->angle > -2.0)) { + value = value || pointInside(character1->x + 6, character1->y + 12, al_get_bitmap_width(character1->bitmap) + 10,al_get_bitmap_height(character1->bitmap) - 18); + } else { + value = value || pointInside(character1->x + 13, character1->y + 5, al_get_bitmap_width(character1->bitmap) - 18,al_get_bitmap_height(character1->bitmap) + 8); + } + + return value; +} + +void DrawRockets(struct Game *game, struct RocketsResources* data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + DrawCharacter(game, tmp->character, al_map_rgb(255,255,255), 0); + + tmp=tmp->next; + } +} + +bool switchMinigame(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "rockets"); + game->mediator.next = "lollipop"; + StartGamestate(game, GetAbstractIsItBonusLevelTimeNowFactoryProvider(game) ? "bonus" : "lollipop"); + } + return true; +} + +bool theEnd(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { + if (state == TM_ACTIONSTATE_START) { + StopGamestate(game, "rockets"); + StartGamestate(game, "theend"); + } + return true; +} + +void UpdateRockets(struct Game *game, struct RocketsResources *data, struct Rocket* rockets) { + struct Rocket *tmp = rockets; + while (tmp) { + tmp->dy+= tmp->modifier; + if (!tmp->blown) { + tmp->dx+= (tmp->dx > 0) ? (-tmp->modifier / 5 + 0.001) : (tmp->modifier / 5 - 0.001); + } + MoveCharacter(game, tmp->character, tmp->dx, tmp->dy, tmp->blown ? 0 : ((tmp->dx > 0) ? 0.0166 : -0.0166)); + AnimateCharacter(game, tmp->character, 1); + + if (!tmp->blown) { + + bool dupy = false; // nice sos, sos + + void iterate(struct Rocket *start) { + struct Rocket *tmp1 = start; + while (tmp1) { + if ((tmp != tmp1) && (!tmp1->blown)) { + if (CheckCollision(game, data, tmp->character, tmp1->character)) { + dupy = true; + + tmp1->blown = true; + tmp1->modifier = 0; + tmp1->character->angle = 0; + tmp1->dx = 0; + tmp1->dy = 0; + SelectSpritesheet(game, tmp1->character, "boom"); + MoveCharacter(game, tmp1->character, 5, 5, 0); + //DrawCharacter(game, tmp->character, al_map_rgb(255,0,0), 0); + al_play_sample_instance(data->boom_sound); + } + + } + tmp1 = tmp1->next; + } + + } + iterate(data->rockets_left); + iterate(data->rockets_right); + + + if (((((tmp->character->y > 120) && (rand() % 4 == 0) && (tmp->dy > 0)) || (dupy))) && (tmp->character->x > -20 && tmp->character->x < 310)) { + tmp->blown = true; + tmp->modifier = 0; + tmp->character->angle = 0; + tmp->dx = 0; + tmp->dy = 0; + SelectSpritesheet(game, tmp->character, "boom"); + MoveCharacter(game, tmp->character, 5, 5, 0); + + if (!dupy) { + if (!data->lost) { + AdvanceLevel(game, false); + } + data->lost = true; + data->flash = 4; + TM_AddDelay(data->timeline, 3500); + if (game->mediator.lives > 0) { + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } else { + + TM_AddAction(data->timeline, theEnd, NULL, "switchMinigame"); + } + data->spawnspeed = 10; + al_play_sample_instance(data->atom_sound); + SelectSpritesheet(game, data->usa_flag, "brokenusa"); + SelectSpritesheet(game, data->ru_flag, "brokenru"); + } + if (!dupy) { + SelectSpritesheet(game, tmp->character, "atom"); + MoveCharacter(game, tmp->character, 0, -11, 0); + tmp->character->angle = ((tmp->character->x - 160) / 160) * 0.8; + } + } else if (tmp->character->x <= -20 || tmp->character->x >= 310) { + tmp->blown = true; + tmp->modifier = 0; + tmp->character->angle = 0; + tmp->dx = 0; + tmp->dy = 0; + SelectSpritesheet(game, tmp->character, "blank"); + } + } + tmp=tmp->next; + } +} + +void Gamestate_Logic(struct Game *game, struct RocketsResources* data) { + + if ((data->spawncounter == data->currentspawn) && ((data->counter < data->timelimit) || (data->lost))) { + data->next = !data->next; + if (data->next) { + data->rockets_left = CreateRocket(game, data, data->rockets_left, false); + } else { + data->rockets_right = CreateRocket(game, data, data->rockets_right, true); + } + data->spawncounter = 0; + } + + if (!data->flash) { + UpdateRockets(game, data, data->rockets_left); + UpdateRockets(game, data, data->rockets_right); + } else { + data->flash--; + } + + + if (data->lost) { + data->hearts++; + } + + AnimateCharacter(game, data->usa_flag, 1); + AnimateCharacter(game, data->ru_flag, 1); + if ((data->lost) && (data->hearts > 80)) { + AnimateCharacter(game, game->mediator.heart, 1); + if (game->mediator.heart->pos == 6) { + al_play_sample_instance(data->boom_sound); + } + } + + if (data->won) { + AnimateCharacter(game, data->rainbow, 1); + } + + if ((data->counter >= data->timelimit) && (!data->lost) && (!data->won)) { + bool stillthere = false; + struct Rocket *tmp = data->rockets_left; + while (tmp) { + if (!tmp->blown) { + stillthere = true; + break; + } + tmp = tmp->next; + } + tmp = data->rockets_right; + while (tmp) { + if (!tmp->blown) { + stillthere = true; + break; + } + tmp = tmp->next; + } + if (!stillthere) { + SelectSpritesheet(game, data->rainbow, "shine"); + SetCharacterPosition(game, data->rainbow, 89, 42, 0); + al_play_sample_instance(data->rainbow_sound); + data->won = true; + AdvanceLevel(game, true); + TM_AddDelay(data->timeline, 2500); + TM_AddAction(data->timeline, switchMinigame, NULL, "switchMinigame"); + } + } + + + void iterate(struct Rocket *start) { + struct Rocket *tmp1 = start; + while (tmp1) { + if (!tmp1->blown) { + if (CheckCollision(game, data, data->cursor, tmp1->character)) { + + if (!tmp1->bumped) { + tmp1->bumped = true; + al_play_sample_instance(data->rocket_sound); + if (data->mousemove.top || data->mousemove.bottom) { + tmp1->dy = (data->mousemove.bottom * 2) - 1; + } + tmp1->dx += (data->mousemove.left * -0.3) + (data->mousemove.right * 0.3); + tmp1->character->angle += (tmp1->character->angle < 0) ? 0.25 : -0.25; + + //PrintConsole(game, "collision TOP %d rIGHT %d", data->mousemove.top, data->mousemove.right); + + int movex = 0, movey = 0; + + if (data->mousemove.right) { + movex = -3; + } + if (data->mousemove.left) { + movex = 3; + } + if (data->mousemove.top) { + movey = 3; + } + if (data->mousemove.bottom) { + movey =-3; + } + + MoveCharacter(game, data->cursor, movex, movey, 0); + al_set_mouse_xy(game->display, data->cursor->x * (al_get_display_width(game->display) / 320), data->cursor->y * (al_get_display_height(game->display) / 180)); + + data->mousemove.top = false; + data->mousemove.bottom = false; + data->mousemove.left = false; + data->mousemove.right = false; + + } + } else { + tmp1->bumped = false; + } + + } + tmp1 = tmp1->next; + } + + } + iterate(data->rockets_left); + iterate(data->rockets_right); + + data->counter++; + data->spawncounter++; + data->cloud_rotation += 0.002; + + TM_Process(data->timeline); +} + +void Gamestate_Draw(struct Game *game, struct RocketsResources* data) { + + al_set_target_bitmap(data->combined); + al_clear_to_color(al_map_rgba(0,0,0,0)); + al_draw_bitmap(data->earth, 0, 0, 0); + //al_draw_bitmap(data->clouds, -140, -210, 0); + //al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_INVERSE_ALPHA); + al_draw_rotated_bitmap(data->clouds, 250, 250, -90 + 250, -160 + 250 + 20, data->cloud_rotation, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + al_set_target_bitmap(data->pixelator); + + if (!data->lost) { + al_draw_bitmap(data->bg, 0, 0, 0); + al_draw_bitmap(data->earth2, 0, 0, 0); + al_draw_bitmap(data->combined, 0, 0, 0); + } else { + al_draw_tinted_bitmap(data->bg, al_map_rgb(255, 192, 128), 0, 0, 0); + //al_draw_tinted_bitmap(data->earth2, al_map_rgb(255, 192, 128), 0, 0, 0); + al_draw_tinted_bitmap(data->combined, al_map_rgb(255, 192, 128), 0, 0, 0); + } + + if (data->won) { + DrawCharacter(game, data->rainbow, al_map_rgb(255,255,255), 0); + } + + DrawCharacter(game, data->usa_flag, al_map_rgb(255,255,255), 0); + DrawCharacter(game, data->ru_flag, al_map_rgb(255,255,255), 0); + + if ((!data->lost) && (!data->won)) { + DrawCharacter(game, data->cursor, al_map_rgb(255,255,255), 0); + } + + DrawRockets(game, data, data->rockets_left); + DrawRockets(game, data, data->rockets_right); + + if ((!data->lost) && (!data->won)) { + al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142)); + al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30)); + al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80)); + } + + if (data->flash) { + al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgb(255, 255, 255)); + } + + al_set_target_backbuffer(game->display); + al_draw_bitmap(data->pixelator, 0, 0, 0); + + if ((data->lost) && (data->hearts > 80)) { + ShowLevelStatistics(game); + } + + //Gamestate_Logic(game, data); + +} + +void Gamestate_Start(struct Game *game, struct RocketsResources* data) { + data->rockets_left = NULL; + data->rockets_right = NULL; + + data->timelimit = 480 * game->mediator.modificator; + data->spawnspeed = 60 / game->mediator.modificator; + data->currentspawn = data->spawnspeed; + data->spawncounter = data->spawnspeed - 20; + + data->lost = false; + data->won = false; + data->hearts = 0; + + data->flash = 0; + + data->next = rand() % 2; + + SetCharacterPosition(game, data->usa_flag, 266, 105, 0); + SetCharacterPosition(game, data->ru_flag, 13, 103, 0); + + SetCharacterPosition(game, data->cursor, 320 / 2, 180 / 2, 0); + + SelectSpritesheet(game, data->usa_flag, "usa"); + SelectSpritesheet(game, data->ru_flag, "ru"); + + SelectSpritesheet(game, data->cursor, "be"); + + data->counter = 0; + data->cloud_rotation = 0; + + al_set_mouse_xy(game->display, al_get_display_width(game->display) / 2, al_get_display_height(game->display) / 2); + + data->mousemove.bottom = false; + data->mousemove.top = false; + data->mousemove.left = false; + data->mousemove.right = false; +} + +void Gamestate_ProcessEvent(struct Game *game, struct RocketsResources* data, ALLEGRO_EVENT *ev) { + TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "rockets", "theend"); + } else if (ev->type == ALLEGRO_EVENT_MOUSE_AXES) { + int mousex = ev->mouse.x / (al_get_display_width(game->display) / 320); + int mousey = ev->mouse.y / (al_get_display_height(game->display) / 180); + data->mousemove.right = mousex > data->cursor->x; + data->mousemove.top = mousey < data->cursor->y; + data->mousemove.left = mousex < data->cursor->x; + data->mousemove.bottom = mousey > data->cursor->y; + SetCharacterPosition(game, data->cursor, mousex, mousey , 0); // FIXMEEEE! + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct RocketsResources *data = malloc(sizeof(struct RocketsResources)); + + data->timeline = TM_Init(game, "rockets"); + + data->bg = al_load_bitmap( GetDataFilePath(game, "rockets/bg.png")); + + data->earth = al_load_bitmap( GetDataFilePath(game, "rockets/earth.png")); + data->earth2 = al_load_bitmap( GetDataFilePath(game, "rockets/earth2.png")); + + data->clouds = al_load_bitmap( GetDataFilePath(game, "rockets/clouds.png")); + (*progress)(game); + + data->rocket_sample = al_load_sample( GetDataFilePath(game, "bump.flac") ); + (*progress)(game); + data->boom_sample = al_load_sample( GetDataFilePath(game, "boom.flac") ); + (*progress)(game); + data->atom_sample = al_load_sample( GetDataFilePath(game, "rockets/atom.flac") ); + (*progress)(game); + data->jump_sample = al_load_sample( GetDataFilePath(game, "launch.flac") ); + (*progress)(game); + data->rainbow_sample = al_load_sample( GetDataFilePath(game, "win.flac") ); + (*progress)(game); + + data->rocket_sound = al_create_sample_instance(data->rocket_sample); + al_attach_sample_instance_to_mixer(data->rocket_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rocket_sound, ALLEGRO_PLAYMODE_ONCE); + + data->atom_sound = al_create_sample_instance(data->atom_sample); + al_attach_sample_instance_to_mixer(data->atom_sound, game->audio.fx); + al_set_sample_instance_playmode(data->atom_sound, ALLEGRO_PLAYMODE_ONCE); + + data->boom_sound = al_create_sample_instance(data->boom_sample); + al_attach_sample_instance_to_mixer(data->boom_sound, game->audio.fx); + al_set_sample_instance_playmode(data->boom_sound, ALLEGRO_PLAYMODE_ONCE); + + data->jump_sound = al_create_sample_instance(data->jump_sample); + al_attach_sample_instance_to_mixer(data->jump_sound, game->audio.fx); + al_set_sample_instance_playmode(data->jump_sound, ALLEGRO_PLAYMODE_ONCE); + + data->rainbow_sound = al_create_sample_instance(data->rainbow_sample); + al_attach_sample_instance_to_mixer(data->rainbow_sound, game->audio.fx); + al_set_sample_instance_playmode(data->rainbow_sound, ALLEGRO_PLAYMODE_ONCE); + + data->cursor = CreateCharacter(game, "cursor"); + RegisterSpritesheet(game, data->cursor, "be"); + LoadSpritesheets(game, data->cursor); + (*progress)(game); + + data->pixelator = al_create_bitmap(320, 180); + al_set_target_bitmap(data->pixelator); + al_clear_to_color(al_map_rgb(0, 0, 0)); + + data->combined = al_create_bitmap(320, 180); + al_set_target_bitmap(data->combined); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + al_set_target_backbuffer(game->display); + + data->rocket_template = CreateCharacter(game, "rocket"); + RegisterSpritesheet(game, data->rocket_template, "usa"); + RegisterSpritesheet(game, data->rocket_template, "ru"); + RegisterSpritesheet(game, data->rocket_template, "atom"); + RegisterSpritesheet(game, data->rocket_template, "boom"); + RegisterSpritesheet(game, data->rocket_template, "blank"); + LoadSpritesheets(game, data->rocket_template); + (*progress)(game); + + data->usa_flag = CreateCharacter(game, "flag"); + RegisterSpritesheet(game, data->usa_flag, "usa"); + RegisterSpritesheet(game, data->usa_flag, "brokenusa"); + LoadSpritesheets(game, data->usa_flag); + + data->ru_flag = CreateCharacter(game, "flag"); + RegisterSpritesheet(game, data->ru_flag, "ru"); + RegisterSpritesheet(game, data->ru_flag, "brokenru"); + LoadSpritesheets(game, data->ru_flag); + (*progress)(game); + + data->rainbow = CreateCharacter(game, "rainbow"); + RegisterSpritesheet(game, data->rainbow, "shine"); + RegisterSpritesheet(game, data->rainbow, "be"); + LoadSpritesheets(game, data->rainbow); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct RocketsResources* data) { + TM_CleanQueue(data->timeline); +} + +void Gamestate_Unload(struct Game *game, struct RocketsResources* data) { + al_destroy_bitmap(data->bg); + al_destroy_bitmap(data->earth); + al_destroy_bitmap(data->earth2); + al_destroy_bitmap(data->clouds); + al_destroy_bitmap(data->combined); + al_destroy_bitmap(data->pixelator); + al_destroy_sample_instance(data->rocket_sound); + al_destroy_sample_instance(data->boom_sound); + al_destroy_sample(data->rocket_sample); + al_destroy_sample(data->boom_sample); + // TODO: DestroyCharacters + free(data); +} + +void Gamestate_Reload(struct Game *game, struct RocketsResources* data) {} + +void Gamestate_Resume(struct Game *game, struct RocketsResources* data) { + TM_Resume(data->timeline); +} +void Gamestate_Pause(struct Game *game, struct RocketsResources* data) { + TM_Pause(data->timeline); +} diff --git a/src/gamestates/rockets.h b/src/gamestates/rockets.h new file mode 100644 index 0000000..ad3ffd4 --- /dev/null +++ b/src/gamestates/rockets.h @@ -0,0 +1,53 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct RocketsResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bg, *earth, *earth2, *pixelator, *combined, *clouds; + struct Character *rocket_template, *usa_flag, *ru_flag, *cursor, *rainbow; + + struct Rocket { + struct Character *character; + float dx, dy, modifier; + bool blown, bumped; + struct Rocket *next, *prev; + } *rockets_left, *rockets_right; + + int counter, hearts; + float cloud_rotation; + + struct { + bool top, right, left, bottom; + } mousemove; + + ALLEGRO_SAMPLE *rocket_sample, *boom_sample, *rainbow_sample, *atom_sample, *jump_sample; + ALLEGRO_SAMPLE_INSTANCE *rocket_sound, *boom_sound, *rainbow_sound, *atom_sound, *jump_sound; + + bool lost, won; + + int flash; + + int timelimit, spawnspeed, currentspawn, spawncounter; + + bool next; + + struct Timeline *timeline; +}; diff --git a/src/gamestates/theend.c b/src/gamestates/theend.c new file mode 100644 index 0000000..3189810 --- /dev/null +++ b/src/gamestates/theend.c @@ -0,0 +1,113 @@ +/*! \file dosowisko.c + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +#include +#include +#include +#include + +#include "../utils.h" +#include "../timeline.h" +#include "../config.h" +#include "theend.h" + +int Gamestate_ProgressCount = 1; + +void Gamestate_Logic(struct Game *game, struct dosowiskoResources* data) { + +} + +void Gamestate_Draw(struct Game *game, struct dosowiskoResources* data) { + al_draw_bitmap(data->bitmap, 0, 0, 0); + char text[255]; + snprintf(text, 255, "%d", game->mediator.score); + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), 320/2, 20, ALLEGRO_ALIGN_CENTER, "Score:"); + DrawTextWithShadow(data->font, al_map_rgb(255,255,255), 320/2, 30, ALLEGRO_ALIGN_CENTER, text); + snprintf(text, 255, "High score: %d", data->score); + if (game->mediator.score == data->score) { + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,222, 120), 320/2, 140, ALLEGRO_ALIGN_CENTER, text); + } else { + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), 320/2, 140, ALLEGRO_ALIGN_CENTER, text); + } + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), 320/2, 162, ALLEGRO_ALIGN_CENTER, "Press RETURN"); +} + +void Gamestate_Start(struct Game *game, struct dosowiskoResources* data) { + al_set_sample_instance_gain(game->muzyczka.instance.drums, 0.0); + al_set_sample_instance_gain(game->muzyczka.instance.fg, 0.0); + al_set_sample_instance_gain(game->muzyczka.instance.bg, 1.5); + + char *end = ""; + data->score = strtol(GetConfigOptionDefault(game, "Mediator", "score", "0"), &end, 10); + + if (game->mediator.score > data->score) { + char text[255]; + snprintf(text, 255, "%d", game->mediator.score); + SetConfigOption(game, "Mediator", "score", text); + data->score = game->mediator.score; + } + + al_ungrab_mouse(); + if (!game->config.fullscreen) al_show_mouse_cursor(game->display); + + al_play_sample_instance(data->sound); + +} + +void Gamestate_ProcessEvent(struct Game *game, struct dosowiskoResources* data, ALLEGRO_EVENT *ev) { + //TM_HandleEvent(data->timeline, ev); + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + SwitchGamestate(game, "theend", "menu"); + } + if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ENTER)) { + SwitchGamestate(game, "theend", "menu"); + } +} + +void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) { + struct dosowiskoResources *data = malloc(sizeof(struct dosowiskoResources)); + data->bitmap = al_load_bitmap( GetDataFilePath(game, "bg.png")); + + data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"),100,0 ); + (*progress)(game); + + data->sample = al_load_sample( GetDataFilePath(game, "end.flac") ); + + data->sound = al_create_sample_instance(data->sample); + al_attach_sample_instance_to_mixer(data->sound, game->audio.fx); + al_set_sample_instance_playmode(data->sound, ALLEGRO_PLAYMODE_ONCE); + al_set_sample_instance_gain(data->sound, 1.5); + + return data; +} + +void Gamestate_Stop(struct Game *game, struct dosowiskoResources* data) { + +} + +void Gamestate_Unload(struct Game *game, struct dosowiskoResources* data) { + free(data); +} + +void Gamestate_Reload(struct Game *game, struct dosowiskoResources* data) {} + +void Gamestate_Resume(struct Game *game, struct dosowiskoResources* data) {} +void Gamestate_Pause(struct Game *game, struct dosowiskoResources* data) {} diff --git a/src/gamestates/theend.h b/src/gamestates/theend.h new file mode 100644 index 0000000..103691b --- /dev/null +++ b/src/gamestates/theend.h @@ -0,0 +1,28 @@ +/*! \file dosowisko.h + * \brief Init animation with dosowisko.net logo. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * 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. + */ + +struct dosowiskoResources { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_SAMPLE *sample; + ALLEGRO_SAMPLE_INSTANCE *sound; + int score; +}; diff --git a/src/main.c b/src/main.c index 3687331..71ceefe 100644 --- a/src/main.c +++ b/src/main.c @@ -45,9 +45,16 @@ void DrawGamestates(struct Game *game) { } tmp = tmp->next; } + + if (game->mediator.pause) { + al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgba(0,0,0,192)); + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5 - 25, ALLEGRO_ALIGN_CENTRE, "Game paused!"); + DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5 + 5, ALLEGRO_ALIGN_CENTRE, "SPACE to resume"); + } } void LogicGamestates(struct Game *game) { + if (game->mediator.pause) return; struct Gamestate *tmp = game->_priv.gamestates; while (tmp) { if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) { @@ -67,6 +74,28 @@ void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) { } } +void PauseGamestates(struct Game *game) { + struct Gamestate *tmp = game->_priv.gamestates; + while (tmp) { + if ((tmp->loaded) && (tmp->started)) { + (*tmp->api.Gamestate_Pause)(game, tmp->data); + } + tmp = tmp->next; + } +} + + +void ResumeGamestates(struct Game *game) { + struct Gamestate *tmp = game->_priv.gamestates; + while (tmp) { + if ((tmp->loaded) && (tmp->started)) { + (*tmp->api.Gamestate_Resume)(game, tmp->data); + } + tmp = tmp->next; + } +} + + void derp(int sig) { int __attribute__((unused)) n = write(STDERR_FILENO, "Segmentation fault\nI just don't know what went wrong!\n", 54); abort(); @@ -78,7 +107,7 @@ int main(int argc, char **argv){ srand(time(NULL)); al_set_org_name("Super Derpy"); - al_set_app_name("Tickle Monster"); + al_set_app_name("Mediator"); if(!al_init()) { fprintf(stderr, "failed to initialize allegro!\n"); @@ -132,6 +161,11 @@ int main(int argc, char **argv){ fprintf(stderr, "failed to initialize primitives!\n"); return -1; } + + if(!al_install_mouse()) { + fprintf(stderr, "failed to initialize the mouse!\n"); + return -1; + } al_init_font_addon(); @@ -158,13 +192,13 @@ int main(int argc, char **argv){ PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height); - ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/ticklemonster.png")); - al_set_window_title(game.display, "Tickle Monster vs Suits"); + ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/mediator.png")); + al_set_window_title(game.display, "Mediator"); al_set_display_icon(game.display, icon); al_destroy_bitmap(icon); - if (game.config.fullscreen) al_hide_mouse_cursor(game.display); - al_inhibit_screensaver(true); + if (game.config.fullscreen) al_hide_mouse_cursor(game.display); + al_inhibit_screensaver(true); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR); @@ -191,7 +225,8 @@ int main(int argc, char **argv){ al_set_mixer_gain(game.audio.voice, game.config.voice/10.0); al_register_event_source(game._priv.event_queue, al_get_display_event_source(game.display)); - al_register_event_source(game._priv.event_queue, al_get_keyboard_event_source()); + al_register_event_source(game._priv.event_queue, al_get_mouse_event_source()); + al_register_event_source(game._priv.event_queue, al_get_keyboard_event_source()); game._priv.showconsole = game.config.debug; @@ -211,6 +246,19 @@ int main(int argc, char **argv){ game.shuttingdown = false; game.restart = false; + game.mediator.lives = 3; + game.mediator.score = 0; + game.mediator.modificator = 1; + game.mediator.strike = 0; + game.mediator.next = "lollipop"; + game.mediator.pause = false; + + game.mediator.heart = CreateCharacter(&game, "heart"); + RegisterSpritesheet(&game, game.mediator.heart, "heart"); + RegisterSpritesheet(&game, game.mediator.heart, "blank"); + LoadSpritesheets(&game, game.mediator.heart); + SelectSpritesheet(&game, game.mediator.heart, "heart"); + char* gamestate = strdup("dosowisko"); // FIXME: don't hardcore gamestate int c; @@ -228,12 +276,14 @@ int main(int argc, char **argv){ } LoadGamestate(&game, gamestate); - game._priv.gamestates->showLoading = false; // we have only one gamestate right now - StartGamestate(&game, gamestate); + LoadGamestate(&game, "burndt"); + game._priv.gamestates->showLoading = false; // we have only one gamestate right now + game._priv.gamestates->next->showLoading = false; // well, now two + StartGamestate(&game, gamestate); free(gamestate); char libname[1024] = {}; - snprintf(libname, 1024, "libsuperderpy-%s-loading" LIBRARY_EXTENTION, "ticklemonster"); + snprintf(libname, 1024, "libsuperderpy-%s-loading" LIBRARY_EXTENTION, "mediator"); void *handle = dlopen(libname, RTLD_NOW); if (!handle) { FatalError(&game, true, "Error while initializing loading screen %s", dlerror()); @@ -278,6 +328,8 @@ int main(int argc, char **argv){ // FIXME: move to function // TODO: support dependences + double t = -1; + while (tmp) { if ((tmp->pending_load) && (tmp->loaded)) { PrintConsole(&game, "Unloading gamestate \"%s\"...", tmp->name); @@ -293,7 +345,7 @@ int main(int argc, char **argv){ al_stop_timer(game._priv.timer); // TODO: take proper game name char libname[1024]; - snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENTION, "ticklemonster", tmp->name); + snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENTION, "mediator", tmp->name); tmp->handle = dlopen(libname,RTLD_NOW); if (!tmp->handle) { //PrintConsole(&game, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror()); @@ -321,6 +373,7 @@ int main(int argc, char **argv){ if (!(tmp->api.Gamestate_ProgressCount = dlsym(tmp->handle, "Gamestate_ProgressCount"))) { GS_ERROR; } int p = 0; + void progress(struct Game *game) { p++; DrawGamestates(game); @@ -328,16 +381,24 @@ int main(int argc, char **argv){ if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), p, *(tmp->api.Gamestate_ProgressCount)); if (tmp->showLoading) (*game->_priv.loading.Draw)(game, game->_priv.loading.data, progress); DrawConsole(game); - al_flip_display(); + if (al_get_time() - t >= 1/60.0) { + al_flip_display(); + } + t = al_get_time(); } + t = al_get_time(); + // initially draw loading screen with empty bar DrawGamestates(&game); if (tmp->showLoading) { - (*game._priv.loading.Draw)(&game, game._priv.loading.data, 0); + (*game._priv.loading.Draw)(&game, game._priv.loading.data, loaded/(float)toLoad); } DrawConsole(&game); - al_flip_display(); + if (al_get_time() - t >= 1/60.0) { + al_flip_display(); + } + t = al_get_time(); tmp->data = (*tmp->api.Gamestate_Load)(&game, &progress); // feel free to replace "progress" with empty function if you want to compile with clang loaded++; @@ -423,13 +484,22 @@ int main(int argc, char **argv){ } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) { ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH); char filename[255] = { }; - snprintf(filename, 255, "TickleMonster_%ld_%ld.png", time(NULL), clock()); + snprintf(filename, 255, "Mediator_%ld_%ld.png", time(NULL), clock()); al_set_path_filename(path, filename); al_save_bitmap(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), al_get_backbuffer(game.display)); PrintConsole(&game, "Screenshot stored in %s", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); al_destroy_path(path); + } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_SPACE)) { + game.mediator.pause = !game.mediator.pause; + if (game.mediator.pause) { + PauseGamestates(&game); + } else { + ResumeGamestates(&game); + } } else { - EventGamestates(&game, &ev); + if (!game.mediator.pause) { + EventGamestates(&game, &ev); + } } } } diff --git a/src/main.h b/src/main.h index e7ccef1..0cec015 100644 --- a/src/main.h +++ b/src/main.h @@ -95,6 +95,25 @@ struct Game { bool shuttingdown; /*!< If true then shut down of the game is pending. */ bool restart; /*!< If true then restart of the game is pending. */ + struct { + struct { + ALLEGRO_SAMPLE *bg, *fg, *drums; + } sample; + struct { + ALLEGRO_SAMPLE_INSTANCE *bg, *fg, *drums; + } instance; + } muzyczka; + + struct { + int score; + int lives; + float modificator; + struct Character *heart; + char* next; + int strike; + bool pause; + } mediator; + }; #endif diff --git a/src/utils.c b/src/utils.c index ec13bf0..2f3f575 100644 --- a/src/utils.c +++ b/src/utils.c @@ -64,7 +64,7 @@ void Console_Load(struct Game *game) { game->_priv.console = NULL; game->_priv.font_console = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"),al_get_display_height(game->display)*0.025,0 ); if (al_get_display_height(game->display)*0.025 >= 16) { - game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/PerfectDOSVGA437.ttf"),16,0 ); + game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/PerfectDOSVGA437.ttf"),16 * ((al_get_display_height(game->display) > 1080) ? 2 : 1) ,0 ); } else { game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"), al_get_display_height(game->display)*0.025,0 ); } @@ -86,6 +86,8 @@ void SetupViewport(struct Game *game) { game->viewport.width = 320; game->viewport.height = 180; + al_clear_to_color(al_map_rgb(0,0,0)); + int resolution = al_get_display_width(game->display) / 320; if (al_get_display_height(game->display) / 180 < resolution) resolution = al_get_display_height(game->display) / 180; if (resolution < 1) resolution = 1; @@ -237,7 +239,7 @@ void FatalError(struct Game *game, bool fatal, char* format, ...) { al_set_target_backbuffer(game->display); al_clear_to_color(al_map_rgb(0,0,170)); - char *header = "TICKLE MONSTER"; + char *header = "MEDIATOR"; al_draw_filled_rectangle(al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display)/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170)); @@ -317,7 +319,7 @@ char* GetDataFilePath(struct Game *game, char* filename) { } TestPath(filename, "data/", &result); - TestPath(filename, "../share/ticklemonster/data/", &result); + TestPath(filename, "../share/mediator/data/", &result); TestPath(filename, "../data/", &result); #ifdef ALLEGRO_MACOSX TestPath(filename, "../Resources/data/", &result); @@ -499,14 +501,14 @@ void AnimateCharacter(struct Game *game, struct Character *character, float spee character->pos_tmp = 0; character->pos++; } - if (character->pos>=character->spritesheet->cols*character->spritesheet->rows-character->spritesheet->blanks) { - character->pos=0; - if (character->spritesheet->kill) { + if (character->pos>=character->spritesheet->cols*character->spritesheet->rows-character->spritesheet->blanks) { + character->pos=0; + if (character->spritesheet->kill) { character->dead = true; } else if (character->successor) { - SelectSpritesheet(game, character, character->successor); + SelectSpritesheet(game, character, character->successor); } - } + } } } @@ -524,7 +526,53 @@ void SetCharacterPosition(struct Game *game, struct Character *character, int x, character->angle = angle; } -void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, int flags) { - if (character->dead) return; - al_draw_tinted_bitmap_region(character->spritesheet->bitmap, tilt, al_get_bitmap_width(character->bitmap)*(character->pos%character->spritesheet->cols),al_get_bitmap_height(character->bitmap)*(character->pos/character->spritesheet->cols),al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), character->x, character->y, flags); +bool GetAbstractIsItBonusLevelTimeNowFactoryProvider(struct Game *game) { + return game->mediator.strike && (game->mediator.strike % 5 == 0); +} + +void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, int flags) { + if (character->dead) return; + int spritesheetX = al_get_bitmap_width(character->bitmap)*(character->pos%character->spritesheet->cols); + int spritesheetY = al_get_bitmap_height(character->bitmap)*(character->pos/character->spritesheet->cols); + al_draw_tinted_scaled_rotated_bitmap_region(character->spritesheet->bitmap, spritesheetX, spritesheetY, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), tint, al_get_bitmap_width(character->bitmap)/2, al_get_bitmap_height(character->bitmap)/2, character->x + al_get_bitmap_width(character->bitmap)/2, character->y + al_get_bitmap_height(character->bitmap)/2, 1, 1, character->angle, flags); +} + +void AdvanceLevel(struct Game *game, bool won) { + if (won) { + game->mediator.score++; + game->mediator.strike++; + } else { + game->mediator.lives--; + game->mediator.strike = 0; + } + game->mediator.modificator *= 1.025; + SelectSpritesheet(game, game->mediator.heart, "heart"); +} + +void ShowLevelStatistics(struct Game *game) { + // show as many bitmaps as there are lives + // show additional one as a animated character + + al_draw_filled_rectangle(0, 0, 320, 240, al_map_rgba(0, 0, 0, 192)); + + int x = 75; + + int pos = game->mediator.heart->pos; + struct Spritesheet *a = game->mediator.heart->spritesheet; + + for (int i = 0; i < game->mediator.lives; i++) { + SetCharacterPosition(game, game->mediator.heart, x, 50, 0); + SelectSpritesheet(game, game->mediator.heart, "heart"); + DrawCharacter(game, game->mediator.heart, al_map_rgb(255, 255, 255), 0); + x += 48; + } + game->mediator.heart->pos = pos; + game->mediator.heart->spritesheet = a; + + if (game->mediator.lives >= 0) { + SetCharacterPosition(game, game->mediator.heart, x, 50, 0); + DrawCharacter(game, game->mediator.heart, al_map_rgb(255, 255, 255), 0); + } + + //DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), 50, 50, 0, text); } diff --git a/src/utils.h b/src/utils.h index 5240eed..5307a09 100644 --- a/src/utils.h +++ b/src/utils.h @@ -48,6 +48,9 @@ void SetupViewport(struct Game *game); void Console_Unload(struct Game *game); void DrawConsole(struct Game *game); +void AdvanceLevel(struct Game *game, bool won); +void ShowLevelStatistics(struct Game *game); + /*! \brief Draws rectangle filled with vertical gradient. */ void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom); /*! \brief Draws rectangle filled with horizontal gradient. */ @@ -126,3 +129,8 @@ void UnloadSpritesheets(struct Game *game, struct Character *character); void AnimateCharacter(struct Game *game, struct Character *character, float speed_modifier); void MoveCharacter(struct Game *game, struct Character *character, float x, float y, float angle); void SetCharacterPosition(struct Game *game, struct Character *character, int x, int y, float angle); + +// FIXME: game specific +bool GetAbstractIsItBonusLevelTimeNowFactoryProvider(struct Game *game); +void AdvanceLevel(struct Game *game, bool won); +void ShowLevelStatistics(struct Game *game);