X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame%2Flevel.c;h=adcdbe80a6fd5a306f17ad2b28c017f800f72570;hb=fe18909bbf0d9766c3e76b2d1ca9d1776520bcf5;hp=c7b1aff96fedd929cd9bdc782ea12d7303549619;hpb=e84c06202c1356f7fa16a4c6bdb1e2f2dd28cb05;p=nothing.git diff --git a/src/game/level.c b/src/game/level.c index c7b1aff9..adcdbe80 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -1,26 +1,32 @@ #include #include +#include "game/camera.h" #include "game/level.h" -#include "game/level/camera.h" +#include "game/level/background.h" +#include "game/level/boxes.h" #include "game/level/goals.h" #include "game/level/lava.h" +#include "game/level/physical_world.h" #include "game/level/platforms.h" #include "game/level/player.h" #include "system/error.h" #include "system/lt.h" - -/* TODO(#118): Level doesn't play the Nothing and Something sounds when the goal get into view */ +#include "system/lt/lt_adapters.h" struct level_t { lt_t *lt; + + physical_world_t *physical_world; player_t *player; platforms_t *platforms; - camera_t *camera; goals_t *goals; lava_t *lava; color_t background_color; + platforms_t *back_platforms; + background_t *background; + boxes_t *boxes; }; level_t *create_level_from_file(const char *file_name) @@ -38,7 +44,7 @@ level_t *create_level_from_file(const char *file_name) RETURN_LT(lt, NULL); } - FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose); + FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt); if (level_file == NULL) { throw_error(ERROR_TYPE_LIBC); RETURN_LT(lt, NULL); @@ -71,10 +77,31 @@ level_t *create_level_from_file(const char *file_name) RETURN_LT(lt, NULL); } - level->camera = PUSH_LT(lt, create_camera(vec(0.0f, 0.0f)), destroy_camera); - if (level->camera == NULL) { + level->back_platforms = PUSH_LT(lt, create_platforms_from_stream(level_file), destroy_platforms); + if (level->back_platforms == NULL) { + RETURN_LT(lt, NULL); + } + + level->boxes = PUSH_LT(lt, create_boxes_from_stream(level_file), destroy_boxes); + if (level->boxes == NULL) { + RETURN_LT(lt, NULL); + } + + level->background = PUSH_LT(lt, create_background(level->background_color), destroy_background); + if (level->background == NULL) { + RETURN_LT(lt, NULL); + } + + level->physical_world = PUSH_LT(lt, create_physical_world(), destroy_physical_world); + if (level->physical_world == NULL) { RETURN_LT(lt, NULL); } + if (physical_world_add_solid( + level->physical_world, + player_as_solid(level->player)) < 0) { RETURN_LT(lt, NULL); } + if (boxes_add_to_physical_world( + level->boxes, + level->physical_world) < 0) { RETURN_LT(lt, NULL); } level->lt = lt; @@ -89,36 +116,44 @@ void destroy_level(level_t *level) RETURN_LT0(level->lt); } -int level_render(const level_t *level, SDL_Renderer *renderer) +int level_render(const level_t *level, camera_t *camera) { assert(level); - assert(renderer); - if (camera_clear_background(level->camera, renderer, level->background_color) < 0) { + player_focus_camera(level->player, camera); + + if (camera_clear_background(camera, level->background_color) < 0) { return -1; } - if (player_render(level->player, renderer, level->camera) < 0) { + if (background_render(level->background, camera) < 0) { return -1; } - if (lava_render(level->lava, renderer, level->camera) < 0) { + if (platforms_render(level->back_platforms, camera) < 0) { return -1; } - if (platforms_render(level->platforms, renderer, level->camera) < 0) { + if (player_render(level->player, camera) < 0) { return -1; } - if (goals_render(level->goals, renderer, level->camera) < 0) { + if (boxes_render(level->boxes, camera) < 0) { + return -1; + } + + if (lava_render(level->lava, camera) < 0) { + return -1; + } + + if (platforms_render(level->platforms, camera) < 0) { + return -1; + } + + if (goals_render(level->goals, camera) < 0) { return -1; } - /* TODO(#157): goals_cue is not supposed to be invoked in level_render - * - * But I simply couldn't find a better place for it. - */ - goals_cue(level->goals, renderer, level->camera); return 0; } @@ -128,13 +163,17 @@ int level_update(level_t *level, float delta_time) assert(level); assert(delta_time > 0); - player_update(level->player, level->platforms, delta_time); - player_focus_camera(level->player, level->camera); + physical_world_apply_gravity(level->physical_world); + + boxes_update(level->boxes, delta_time); + player_update(level->player, delta_time); + + physical_world_collide_solids(level->physical_world, level->platforms); + player_hide_goals(level->player, level->goals); player_die_from_lava(level->player, level->lava); goals_update(level->goals, delta_time); - goals_checkpoint(level->goals, level->player); lava_update(level->lava, delta_time); return 0; @@ -187,16 +226,6 @@ int level_input(level_t *level, return 0; } -void level_toggle_debug_mode(level_t *level) -{ - camera_toggle_debug_mode(level->camera); -} - -void level_toggle_pause_mode(level_t *level) -{ - camera_toggle_blackwhite_mode(level->camera); -} - int level_reload_preserve_player(level_t *level, const char *file_name) { lt_t * const lt = create_lt(); @@ -206,7 +235,9 @@ int level_reload_preserve_player(level_t *level, const char *file_name) /* TODO(#104): duplicate code in create_level_from_file and level_reload_preserve_player */ - FILE * const level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose); + + + FILE * const level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt); if (level_file == NULL) { throw_error(ERROR_TYPE_LIBC); RETURN_LT(lt, -1); @@ -241,15 +272,53 @@ int level_reload_preserve_player(level_t *level, const char *file_name) if (lava == NULL) { RETURN_LT(lt, -1); } + level->lava = RESET_LT(level->lt, level->lava, lava); + + platforms_t * const back_platforms = create_platforms_from_stream(level_file); + if (back_platforms == NULL) { + RETURN_LT(lt, -1); + } + level->back_platforms = RESET_LT(level->lt, level->back_platforms, back_platforms); + + boxes_t * const boxes = create_boxes_from_stream(level_file); + if (level->boxes == NULL) { + RETURN_LT(lt, -1); + } + level->boxes = RESET_LT(level->lt, level->boxes, boxes); + + physical_world_clean(level->physical_world); + if (physical_world_add_solid( + level->physical_world, + player_as_solid(level->player)) < 0) { RETURN_LT(lt, -1); } + if (boxes_add_to_physical_world( + level->boxes, + level->physical_world) < 0) { RETURN_LT(lt, -1); } RETURN_LT(lt, 0); } -int level_sound(level_t *level, sound_medium_t *sound_medium) +int level_sound(level_t *level, sound_samples_t *sound_samples) { - if (goals_sound(level->goals, sound_medium) < 0) { + if (goals_sound(level->goals, sound_samples) < 0) { + return -1; + } + + if (player_sound(level->player, sound_samples) < 0) { return -1; } return 0; } + +void level_toggle_debug_mode(level_t *level) +{ + background_toggle_debug_mode(level->background); +} + +int level_enter_camera_event(level_t *level, + const camera_t *camera) +{ + goals_cue(level->goals, camera); + goals_checkpoint(level->goals, level->player); + return 0; +}