X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame%2Flevel.c;h=eeb5b65478b93c2a4145b50a22b23eddec18bd23;hb=c1021a9d6a49eae97ad17755414279530ca9e21c;hp=cfec4939d939288a5a25d5eb7fe72d751db10319;hpb=e615890aab65cd09716c294667f92f0c4f67b6b5;p=nothing.git diff --git a/src/game/level.c b/src/game/level.c index cfec4939..eeb5b654 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -1,10 +1,7 @@ -#include +#include #include "system/stacktrace.h" -#include "broadcast.h" #include "color.h" -#include "ebisp/builtins.h" -#include "ebisp/interpreter.h" #include "game/camera.h" #include "game/level.h" #include "game/level/background.h" @@ -16,90 +13,61 @@ #include "game/level/player.h" #include "game/level/regions.h" #include "game/level/rigid_bodies.h" -#include "game/level_metadata.h" -#include "game/level/level_editor/proto_rect.h" #include "game/level/level_editor/rect_layer.h" #include "game/level/level_editor/point_layer.h" -#include "system/line_stream.h" +#include "game/level/level_editor/player_layer.h" +#include "game/level/level_editor/label_layer.h" +#include "game/level/level_editor/background_layer.h" #include "system/log.h" #include "system/lt.h" -#include "system/lt/lt_adapters.h" #include "system/nth_alloc.h" #include "system/str.h" #include "game/level/level_editor.h" +#include "ui/console.h" -#define LEVEL_LINE_MAX_LENGTH 512 #define LEVEL_GRAVITY 1500.0f +#define JOYSTICK_THRESHOLD 1000 + +typedef enum { + LEVEL_STATE_IDLE = 0, + LEVEL_STATE_PAUSE +} LevelState; struct Level { Lt *lt; - const char *file_name; - LevelMetadata *metadata; - // TODO(#812): LevelEditor does not support Background - Background *background; + LevelState state; + Background background; RigidBodies *rigid_bodies; - // TODO(#813): LevelEditor does not support Player Player *player; Platforms *platforms; Goals *goals; - // TODO(#816): LevelEditor does not support Lava Lava *lava; Platforms *back_platforms; Boxes *boxes; - // TODO(#818): LevelEditor does not support Labels Labels *labels; - // TODO(#819): LevelEditor does not support Regions Regions *regions; - - bool edit_mode; - LevelEditor *level_editor; }; -Level *create_level_from_file(const char *file_name, Broadcast *broadcast) +Level *create_level_from_level_editor(const LevelEditor *level_editor) { - trace_assert(file_name); + trace_assert(level_editor); Lt *lt = create_lt(); - Level *const level = PUSH_LT(lt, nth_calloc(1, sizeof(Level)), free); + Level *level = PUSH_LT( + lt, + nth_calloc(1, sizeof(Level)), + free); if (level == NULL) { RETURN_LT(lt, NULL); } level->lt = lt; - level->file_name = PUSH_LT(lt, string_duplicate(file_name, NULL), free); - if (level->file_name == NULL) { - RETURN_LT(lt, NULL); - } - - LineStream *level_stream = PUSH_LT( - lt, - create_line_stream( - file_name, - "r", - LEVEL_LINE_MAX_LENGTH), - destroy_line_stream); - if (level_stream == NULL) { - RETURN_LT(lt, NULL); - } - - level->metadata = PUSH_LT( - lt, - create_level_metadata_from_line_stream(level_stream), - destroy_level_metadata); - if (level->metadata == NULL) { - RETURN_LT(lt, NULL); - } - - level->background = PUSH_LT( - lt, - create_background_from_line_stream(level_stream), - destroy_background); - if (level->background == NULL) { - RETURN_LT(lt, NULL); - } + level->background = create_background( + color_picker_rgba( + &level_editor->background_layer.color_picker)); level->rigid_bodies = PUSH_LT(lt, create_rigid_bodies(1024), destroy_rigid_bodies); if (level->rigid_bodies == NULL) { @@ -108,33 +76,25 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast) level->player = PUSH_LT( lt, - create_player_from_line_stream(level_stream, level->rigid_bodies, broadcast), + create_player_from_player_layer( + &level_editor->player_layer, + level->rigid_bodies), destroy_player); if (level->player == NULL) { RETURN_LT(lt, NULL); } - RectLayer *platforms_layer = create_rect_layer_from_line_stream(level_stream); - if (platforms_layer == NULL) { - RETURN_LT(lt, NULL); - } - level->platforms = PUSH_LT( lt, - create_platforms_from_rect_layer(platforms_layer), + create_platforms_from_rect_layer(level_editor->platforms_layer), destroy_platforms); if (level->platforms == NULL) { RETURN_LT(lt, NULL); } - PointLayer *goals_layer = create_point_layer_from_line_stream(level_stream); - if (goals_layer == NULL) { - RETURN_LT(lt, NULL); - } - level->goals = PUSH_LT( lt, - create_goals_from_point_layer(goals_layer), + create_goals_from_point_layer(level_editor->goals_layer), destroy_goals); if (level->goals == NULL) { RETURN_LT(lt, NULL); @@ -142,33 +102,23 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast) level->lava = PUSH_LT( lt, - create_lava_from_line_stream(level_stream), + create_lava_from_rect_layer(level_editor->lava_layer), destroy_lava); if (level->lava == NULL) { RETURN_LT(lt, NULL); } - RectLayer *back_platforms_layer = create_rect_layer_from_line_stream(level_stream); - if (back_platforms_layer == NULL) { - RETURN_LT(lt, NULL); - } - level->back_platforms = PUSH_LT( lt, - create_platforms_from_rect_layer(back_platforms_layer), + create_platforms_from_rect_layer(level_editor->back_platforms_layer), destroy_platforms); if (level->back_platforms == NULL) { RETURN_LT(lt, NULL); } - RectLayer *boxes_layer = create_rect_layer_from_line_stream(level_stream); - if (boxes_layer == NULL) { - RETURN_LT(lt, NULL); - } - level->boxes = PUSH_LT( lt, - create_boxes_from_rect_layer(boxes_layer, level->rigid_bodies), + create_boxes_from_rect_layer(level_editor->boxes_layer, level->rigid_bodies), destroy_boxes); if (level->boxes == NULL) { RETURN_LT(lt, NULL); @@ -176,7 +126,7 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast) level->labels = PUSH_LT( lt, - create_labels_from_line_stream(level_stream), + create_labels_from_label_layer(level_editor->label_layer), destroy_labels); if (level->labels == NULL) { RETURN_LT(lt, NULL); @@ -184,27 +134,15 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast) level->regions = PUSH_LT( lt, - create_regions_from_line_stream(level_stream, broadcast), + create_regions_from_rect_layer( + level_editor->regions_layer, + level->labels, + level->goals), destroy_regions); if (level->regions == NULL) { RETURN_LT(lt, NULL); } - level->edit_mode = false; - level->level_editor = PUSH_LT( - lt, - create_level_editor( - boxes_layer, - platforms_layer, - back_platforms_layer, - goals_layer), - destroy_level_editor); - if (level->level_editor == NULL) { - RETURN_LT(lt, NULL); - } - - destroy_line_stream(RELEASE_LT(lt, level_stream)); - return level; } @@ -214,23 +152,14 @@ void destroy_level(Level *level) RETURN_LT0(level->lt); } - -int level_render(const Level *level, Camera *camera) +int level_render(const Level *level, const Camera *camera) { trace_assert(level); - if (background_render(level->background, camera) < 0) { + if (background_render(&level->background, camera) < 0) { return -1; } - if (level->edit_mode) { - if (level_editor_render(level->level_editor, camera) < 0) { - return -1; - } - - return 0; - } - if (platforms_render(level->back_platforms, camera) < 0) { return -1; } @@ -271,6 +200,10 @@ int level_update(Level *level, float delta_time) trace_assert(level); trace_assert(delta_time > 0); + if (level->state == LEVEL_STATE_PAUSE) { + return 0; + } + boxes_float_in_lava(level->boxes, level->lava); rigid_bodies_apply_omniforce(level->rigid_bodies, vec(0.0f, LEVEL_GRAVITY)); @@ -279,7 +212,6 @@ int level_update(Level *level, float delta_time) rigid_bodies_collide(level->rigid_bodies, level->platforms); - player_hide_goals(level->player, level->goals); player_die_from_lava(level->player, level->lava); regions_player_enter(level->regions, level->player); regions_player_leave(level->regions, level->player); @@ -291,64 +223,30 @@ int level_update(Level *level, float delta_time) return 0; } -int level_event(Level *level, const SDL_Event *event, const Camera *camera) +static +int level_event_idle(Level *level, const SDL_Event *event, + Camera *camera, Sound_samples *sound_samples) { trace_assert(level); - trace_assert(event); switch (event->type) { case SDL_KEYDOWN: switch (event->key.keysym.sym) { + case SDLK_w: + case SDLK_UP: case SDLK_SPACE: { player_jump(level->player); } break; - // TODO(#858): Player state is not exchanged between Level and LevelEditor - case SDLK_TAB: { - level->edit_mode = !level->edit_mode; - SDL_SetRelativeMouseMode(level->edit_mode); - if (!level->edit_mode) { - level->boxes = RESET_LT( - level->lt, - level->boxes, - create_boxes_from_rect_layer( - level_editor_boxes(level->level_editor), - level->rigid_bodies)); - if (level->boxes == NULL) { - return -1; - } - - level->platforms = RESET_LT( - level->lt, - level->platforms, - create_platforms_from_rect_layer( - level_editor_platforms( - level->level_editor))); - if (level->platforms == NULL) { - return -1; - } - - level->back_platforms = RESET_LT( - level->lt, - level->back_platforms, - create_platforms_from_rect_layer( - level_editor_back_platforms( - level->level_editor))); - if (level->back_platforms == NULL) { - return -1; - } - - level->goals = RESET_LT( - level->lt, - level->goals, - create_goals_from_point_layer( - level_editor_goals_layer( - level->level_editor))); - if (level->goals == NULL) { - return -1; - } - } - }; + case SDLK_p: { + level->state = LEVEL_STATE_PAUSE; + camera->blackwhite_mode = true; + sound_samples_toggle_pause(sound_samples); + } break; + + case SDLK_l: { + camera_toggle_debug_mode(camera); + } break; } break; @@ -359,8 +257,44 @@ int level_event(Level *level, const SDL_Event *event, const Camera *camera) break; } - if (level->edit_mode) { - level_editor_event(level->level_editor, event, camera); + return 0; +} + +static +int level_event_pause(Level *level, const SDL_Event *event, + Camera *camera, Sound_samples *sound_samples) +{ + trace_assert(level); + + switch (event->type) { + case SDL_KEYDOWN: { + switch (event->key.keysym.sym) { + case SDLK_p: { + level->state = LEVEL_STATE_IDLE; + camera->blackwhite_mode = false; + sound_samples_toggle_pause(sound_samples); + } break; + } + } break; + } + + return 0; +} + +int level_event(Level *level, const SDL_Event *event, + Camera *camera, Sound_samples *sound_samples) +{ + trace_assert(level); + trace_assert(event); + + switch (level->state) { + case LEVEL_STATE_IDLE: { + return level_event_idle(level, event, camera, sound_samples); + } break; + + case LEVEL_STATE_PAUSE: { + return level_event_pause(level, event, camera, sound_samples); + } break; } return 0; @@ -372,15 +306,18 @@ int level_input(Level *level, { trace_assert(level); trace_assert(keyboard_state); - (void) the_stick_of_joy; - if (keyboard_state[SDL_SCANCODE_A]) { + if (level->state == LEVEL_STATE_PAUSE) { + return 0; + } + + if (keyboard_state[SDL_SCANCODE_A] || keyboard_state[SDL_SCANCODE_LEFT]) { player_move_left(level->player); - } else if (keyboard_state[SDL_SCANCODE_D]) { + } else if (keyboard_state[SDL_SCANCODE_D] || keyboard_state[SDL_SCANCODE_RIGHT]) { player_move_right(level->player); - } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) < 0) { + } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) < -JOYSTICK_THRESHOLD) { player_move_left(level->player); - } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) > 0) { + } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) > JOYSTICK_THRESHOLD) { player_move_right(level->player); } else { player_stop(level->player); @@ -391,6 +328,10 @@ int level_input(Level *level, int level_sound(Level *level, Sound_samples *sound_samples) { + if (level->state == LEVEL_STATE_PAUSE) { + return 0; + } + if (goals_sound(level->goals, sound_samples) < 0) { return -1; } @@ -402,68 +343,28 @@ int level_sound(Level *level, Sound_samples *sound_samples) return 0; } -void level_toggle_debug_mode(Level *level) -{ - background_toggle_debug_mode(level->background); -} - int level_enter_camera_event(Level *level, Camera *camera) { - if (!level->edit_mode) { - player_focus_camera(level->player, camera); - camera_scale(camera, 1.0f); - } else { - level_editor_focus_camera( - level->level_editor, - camera); + if (level->state == LEVEL_STATE_PAUSE) { + return 0; } + player_focus_camera(level->player, camera); + camera_scale(camera, 1.0f); + goals_cue(level->goals, camera); goals_checkpoint(level->goals, level->player); labels_enter_camera_event(level->labels, camera); return 0; } -struct EvalResult level_send(Level *level, Gc *gc, struct Scope *scope, struct Expr path) -{ - trace_assert(level); - trace_assert(gc); - trace_assert(scope); - - const char *target = NULL; - struct Expr rest = void_expr(); - struct EvalResult res = match_list(gc, "q*", path, &target, &rest); - if (res.is_error) { - return res; - } - - if (strcmp(target, "goal") == 0) { - return goals_send(level->goals, gc, scope, rest); - } else if (strcmp(target, "label") == 0) { - return labels_send(level->labels, gc, scope, rest); - } else if (strcmp(target, "box") == 0) { - return boxes_send(level->boxes, gc, scope, rest); - } else if (strcmp(target, "body-push") == 0) { - long int id = 0, x = 0, y = 0; - res = match_list(gc, "ddd", rest, &id, &x, &y); - if (res.is_error) { - return res; - } - - rigid_bodies_apply_force(level->rigid_bodies, (size_t) id, vec((float) x, (float) y)); - - return eval_success(NIL(gc)); - } else if (strcmp(target, "edit") == 0) { - level->edit_mode = !level->edit_mode; - SDL_SetRelativeMouseMode(level->edit_mode); - return eval_success(NIL(gc)); - } - - return unknown_target(gc, "level", target); -} - -bool level_edit_mode(const Level *level) +void level_disable_pause_mode(Level *level, Camera *camera, + Sound_samples *sound_samples) { trace_assert(level); - return level->edit_mode; + trace_assert(camera); + trace_assert(sound_samples); + level->state = LEVEL_STATE_IDLE; + camera->blackwhite_mode = false; + sound_samples_toggle_pause(sound_samples); }