X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame.c;h=7c3786c8ab4247491c0d80a8b3386407ddd9357b;hb=9127e1899cdbf7cd0a261a93722e1b1d691f5a37;hp=2c5d49b5ad3902581f31f66248cd46239a054f52;hpb=f39a5e6864d1fe69f90523222654fe428156c613;p=nothing.git diff --git a/src/game.c b/src/game.c index 2c5d49b5..7c3786c8 100644 --- a/src/game.c +++ b/src/game.c @@ -1,5 +1,4 @@ -#include -#include +#include #include "system/stacktrace.h" #include @@ -15,12 +14,17 @@ #include "system/str.h" #include "ebisp/builtins.h" #include "broadcast.h" +#include "sdl/texture.h" +#include "game/level/level_editor.h" + +static int game_render_cursor(const Game *game); typedef enum Game_state { GAME_STATE_RUNNING = 0, GAME_STATE_PAUSE, GAME_STATE_CONSOLE, GAME_STATE_LEVEL_PICKER, + GAME_STATE_LEVEL_EDITOR, GAME_STATE_QUIT } Game_state; @@ -31,11 +35,15 @@ typedef struct Game { Broadcast *broadcast; Sprite_font *font; LevelPicker *level_picker; + LevelEditor *level_editor; Level *level; Sound_samples *sound_samples; Camera *camera; Console *console; SDL_Renderer *renderer; + SDL_Texture *texture_cursor; + int cursor_x; + int cursor_y; } Game; Game *create_game(const char *level_folder, @@ -45,12 +53,9 @@ Game *create_game(const char *level_folder, { trace_assert(level_folder); - Lt *const lt = create_lt(); - if (lt == NULL) { - return NULL; - } + Lt *lt = create_lt(); - Game *game = PUSH_LT(lt, nth_alloc(sizeof(Game)), free); + Game *game = PUSH_LT(lt, nth_calloc(1, sizeof(Game)), free); if (game == NULL) { RETURN_LT(lt, NULL); } @@ -69,7 +74,7 @@ Game *create_game(const char *level_folder, game->font = PUSH_LT( lt, create_sprite_font_from_file( - "fonts/charmap-oldschool.bmp", + "images/charmap-oldschool.bmp", renderer), destroy_sprite_font); if (game->font == NULL) { @@ -86,8 +91,6 @@ Game *create_game(const char *level_folder, RETURN_LT(lt, NULL); } - game->level = NULL; - game->sound_samples = PUSH_LT( lt, create_sound_samples( @@ -115,6 +118,23 @@ Game *create_game(const char *level_folder, } game->renderer = renderer; + game->texture_cursor = PUSH_LT( + lt, + texture_from_bmp("images/cursor.bmp", renderer), + SDL_DestroyTexture); + if (SDL_SetTextureBlendMode( + game->texture_cursor, + SDL_ComposeCustomBlendMode( + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR, + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR, + SDL_BLENDOPERATION_ADD, + SDL_BLENDFACTOR_ONE, + SDL_BLENDFACTOR_ZERO, + SDL_BLENDOPERATION_ADD)) < 0) { + log_warn("SDL error: %s\n", SDL_GetError()); + } + game->cursor_x = 0; + game->cursor_y = 0; return game; } @@ -142,7 +162,7 @@ int game_render(const Game *game) return -1; } - if (console_render(game->console, game->renderer) < 0) { + if (console_render(game->console, game->camera, game->renderer) < 0) { return -1; } } break; @@ -151,6 +171,20 @@ int game_render(const Game *game) if (level_picker_render(game->level_picker, game->camera, game->renderer) < 0) { return -1; } + + if (game_render_cursor(game) < 0) { + return -1; + } + } break; + + case GAME_STATE_LEVEL_EDITOR: { + if (level_editor_render(game->level_editor, game->camera) < 0) { + return -1; + } + + if (game_render_cursor(game) < 0) { + return -1; + } } break; case GAME_STATE_QUIT: break; @@ -167,6 +201,7 @@ int game_sound(Game *game) case GAME_STATE_CONSOLE: return level_sound(game->level, game->sound_samples); case GAME_STATE_LEVEL_PICKER: + case GAME_STATE_LEVEL_EDITOR: case GAME_STATE_QUIT: return 0; } @@ -214,19 +249,39 @@ int game_update(Game *game, float delta_time) return -1; } - const char *level_folder = level_picker_selected_level(game->level_picker); + const char *level_filename = level_picker_selected_level(game->level_picker); + + if (level_filename != NULL) { + if (game->level_editor == NULL) { + game->level_editor = PUSH_LT( + game->lt, + create_level_editor_from_file(level_filename), + destroy_level_editor); + } else { + game->level_editor = RESET_LT( + game->lt, + game->level_editor, + create_level_editor_from_file(level_filename)); + } + + if (game->level_editor == NULL) { + return -1; + } - if (level_folder != NULL) { if (game->level == NULL) { game->level = PUSH_LT( game->lt, - create_level_from_file(level_folder, game->broadcast), + create_level_from_level_editor( + game->level_editor, + game->broadcast), destroy_level); } else { game->level = RESET_LT( game->lt, game->level, - create_level_from_file(level_folder, game->broadcast)); + create_level_from_level_editor( + game->level_editor, + game->broadcast)); } if (game->level == NULL) { @@ -238,6 +293,14 @@ int game_update(Game *game, float delta_time) } break; + case GAME_STATE_LEVEL_EDITOR: { + if (level_editor_focus_camera( + game->level_editor, + game->camera) < 0) { + return -1; + } + } break; + case GAME_STATE_PAUSE: case GAME_STATE_QUIT: break; @@ -253,10 +316,6 @@ static int game_event_pause(Game *game, const SDL_Event *event) trace_assert(event); switch (event->type) { - case SDL_QUIT: - game->state = GAME_STATE_QUIT; - break; - case SDL_KEYDOWN: switch (event->key.keysym.sym) { case SDLK_p: @@ -281,24 +340,29 @@ static int game_event_running(Game *game, const SDL_Event *event) trace_assert(event); switch (event->type) { - case SDL_QUIT: - game->state = GAME_STATE_QUIT; - break; - - case SDL_KEYDOWN: + case SDL_KEYDOWN: { switch (event->key.keysym.sym) { case SDLK_r: { const char *level_filename = level_picker_selected_level(game->level_picker); log_info("Reloading the level from '%s'...\n", level_filename); + game->level_editor = RESET_LT( + game->lt, + game->level_editor, + create_level_editor_from_file(level_filename)); + if (game->level_editor == NULL) { + log_fail("Could not reload level %s\n", level_filename); + game->state = GAME_STATE_QUIT; + return -1; + } + game->level = RESET_LT( game->lt, game->level, - create_level_from_file( - level_filename, + create_level_from_level_editor( + game->level_editor, game->broadcast)); - if (game->level == NULL) { log_fail("Could not reload level %s\n", level_filename); game->state = GAME_STATE_QUIT; @@ -308,37 +372,34 @@ static int game_event_running(Game *game, const SDL_Event *event) camera_disable_debug_mode(game->camera); } break; - case SDLK_q: - if (level_reload_preserve_player(game->level, game->broadcast) < 0) { - log_fail("Could not reload level\n"); - game->state = GAME_STATE_QUIT; - return -1; - } - break; - - case SDLK_p: + case SDLK_p: { game->state = GAME_STATE_PAUSE; camera_toggle_blackwhite_mode(game->camera); sound_samples_toggle_pause(game->sound_samples); - break; + } break; - case SDLK_l: + case SDLK_l: { camera_toggle_debug_mode(game->camera); level_toggle_debug_mode(game->level); - break; + } break; + + case SDLK_TAB: { + game->state = GAME_STATE_LEVEL_EDITOR; + SDL_SetRelativeMouseMode(true); + } break; } - break; - case SDL_KEYUP: + } break; + + case SDL_KEYUP: { switch (event->key.keysym.sym) { case SDLK_BACKQUOTE: - case SDLK_c: + case SDLK_c: { SDL_StartTextInput(); game->state = GAME_STATE_CONSOLE; console_slide_down(game->console); - break; + } break; } - break; - + } break; } return level_event(game->level, event); @@ -347,10 +408,6 @@ static int game_event_running(Game *game, const SDL_Event *event) static int game_event_console(Game *game, const SDL_Event *event) { switch (event->type) { - case SDL_QUIT: - game->state = GAME_STATE_QUIT; - return 0; - case SDL_KEYDOWN: switch (event->key.keysym.sym) { case SDLK_ESCAPE: @@ -373,13 +430,80 @@ static int game_event_level_picker(Game *game, const SDL_Event *event) trace_assert(event); switch (event->type) { - case SDL_QUIT: - game->state = GAME_STATE_QUIT; - return 0; + case SDL_KEYDOWN: { + switch(event->key.keysym.sym) { + case SDLK_n: { + if (game->level_editor == NULL) { + game->level_editor = PUSH_LT( + game->lt, + create_level_editor(), + destroy_level_editor); + } else { + game->level_editor = RESET_LT( + game->lt, + game->level_editor, + create_level_editor()); + } + + if (game->level_editor == NULL) { + return -1; + } + + if (game->level == NULL) { + game->level = PUSH_LT( + game->lt, + create_level_from_level_editor( + game->level_editor, + game->broadcast), + destroy_level); + } else { + game->level = RESET_LT( + game->lt, + game->level, + create_level_from_level_editor( + game->level_editor, + game->broadcast)); + } + + if (game->level == NULL) { + return -1; + } + + game->state = GAME_STATE_RUNNING; + } break; + } + } break; + } - default: - return level_picker_event(game->level_picker, event); + return level_picker_event(game->level_picker, event); +} + +static int game_event_level_editor(Game *game, const SDL_Event *event) +{ + trace_assert(game); + trace_assert(event); + + switch (event->type) { + case SDL_KEYDOWN: { + switch (event->key.keysym.sym) { + case SDLK_TAB: { + game->level = RESET_LT( + game->lt, + game->level, + create_level_from_level_editor( + game->level_editor, + game->broadcast)); + if (game->level == NULL) { + return -1; + } + game->state = GAME_STATE_RUNNING; + SDL_SetRelativeMouseMode(false); + } break; + } + } break; } + + return level_editor_event(game->level_editor, event, game->camera); } int game_event(Game *game, const SDL_Event *event) @@ -387,6 +511,18 @@ int game_event(Game *game, const SDL_Event *event) trace_assert(game); trace_assert(event); + switch (event->type) { + case SDL_QUIT: { + game->state = GAME_STATE_QUIT; + return 0; + } break; + + case SDL_MOUSEMOTION: { + game->cursor_x = event->motion.x; + game->cursor_y = event->motion.y; + } break; + } + switch (game->state) { case GAME_STATE_RUNNING: return game_event_running(game, event); @@ -400,10 +536,14 @@ int game_event(Game *game, const SDL_Event *event) case GAME_STATE_LEVEL_PICKER: return game_event_level_picker(game, event); - default: {} + case GAME_STATE_LEVEL_EDITOR: + return game_event_level_editor(game, event); + + case GAME_STATE_QUIT: + return 0; } - return 0; + return -1; } @@ -418,6 +558,7 @@ int game_input(Game *game, case GAME_STATE_QUIT: case GAME_STATE_PAUSE: case GAME_STATE_CONSOLE: + case GAME_STATE_LEVEL_EDITOR: return 0; case GAME_STATE_RUNNING: @@ -460,3 +601,18 @@ game_send(Game *game, Gc *gc, struct Scope *scope, return unknown_target(gc, "game", target); } + +// Private Functions + +static int game_render_cursor(const Game *game) +{ + trace_assert(game); + + SDL_Rect src = {0, 0, 32, 32}; + SDL_Rect dest = {game->cursor_x, game->cursor_y, 32, 32}; + if (SDL_RenderCopy(game->renderer, game->texture_cursor, &src, &dest) < 0) { + return -1; + } + + return 0; +}