-#include <stdio.h>
-#include <stdlib.h>
#include <SDL2/SDL.h>
+#include <SDL2/SDL_mixer.h>
-#include "./player.h"
-#include "./platforms.h"
-#include "./error.h"
-#include "./game.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "game.h"
+#include "game/level/platforms.h"
+#include "game/level/player.h"
+#include "game/sound_samples.h"
+#include "game/sprite_font.h"
+#include "math/point.h"
+#include "sdl/renderer.h"
+#include "system/log.h"
+#include "system/lt.h"
+#include "system/lt/lt_adapters.h"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
-#define GAME_FPS 60
-#define LEVEL_FILE_NAME "./levels/platforms.txt"
+
+static void print_usage(FILE *stream)
+{
+ fprintf(stream, "Usage: nothing [--fps <fps>] <level-file>\n");
+}
int main(int argc, char *argv[])
{
- (void) argc; /* unused */
- (void) argv; /* unused */
+ srand((unsigned int) time(NULL));
+
+ Lt *const lt = create_lt();
+
+ char *level_filename = NULL;
+ int fps = 30;
+
+ for (int i = 1; i < argc;) {
+ if (strcmp(argv[i], "--fps") == 0) {
+ if (i + 1 < argc) {
+ if (sscanf(argv[i + 1], "%d", &fps) == 0) {
+ log_fail("Cannot parse FPS: %s is not a number\n", argv[i + 1]);
+ print_usage(stderr);
+ RETURN_LT(lt, -1);
+ }
+ i += 2;
+ } else {
+ log_fail("Value of FPS is not provided\n");
+ print_usage(stderr);
+ RETURN_LT(lt, -1);
+ }
+ } else {
+ level_filename = argv[i];
+ i++;
+ }
+ }
- int exit_code = 0;
+ if (level_filename == NULL) {
+ log_fail("Path to level file is not provided\n");
+ print_usage(stderr);
+ RETURN_LT(lt, -1);
+ }
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
- print_error_msg(ERROR_TYPE_SDL2, "Could not initialize SDL");
- exit_code = -1;
- goto sdl_init_fail;
+ log_fail("Could not initialize SDL: %s\n", SDL_GetError());
+ RETURN_LT(lt, -1);
}
+ PUSH_LT(lt, 42, SDL_Quit_lt);
- SDL_Window *const window = SDL_CreateWindow("Nothing",
- 100, 100,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- SDL_WINDOW_SHOWN);
+ SDL_ShowCursor(SDL_DISABLE);
+
+ SDL_Window *const window = PUSH_LT(
+ lt,
+ SDL_CreateWindow(
+ "Nothing",
+ 100, 100,
+ SCREEN_WIDTH, SCREEN_HEIGHT,
+ SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE),
+ SDL_DestroyWindow);
if (window == NULL) {
- print_error_msg(ERROR_TYPE_SDL2, "Could not create SDL window");
- exit_code = -1;
- goto sdl_create_window_fail;
+ log_fail("Could not create SDL window: %s\n", SDL_GetError());
+ RETURN_LT(lt, -1);
}
- SDL_Renderer *const renderer = SDL_CreateRenderer(window, -1,
- SDL_RENDERER_ACCELERATED |
- SDL_RENDERER_PRESENTVSYNC);
+ SDL_Renderer *const renderer = PUSH_LT(
+ lt,
+ SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
+ SDL_DestroyRenderer);
if (renderer == NULL) {
- print_error_msg(ERROR_TYPE_SDL2, "Could not create SDL renderer");
- exit_code = -1;
- goto sdl_create_renderer_fail;
+ log_fail("Could not create SDL renderer: %s\n", SDL_GetError());
+ RETURN_LT(lt, -1);
+ }
+ if (SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND) < 0) {
+ log_fail("Could not set up blending mode for the renderer: %s\n", SDL_GetError());
+ RETURN_LT(lt, -1);
}
SDL_Joystick *the_stick_of_joy = NULL;
if (SDL_NumJoysticks() > 0) {
- the_stick_of_joy = SDL_JoystickOpen(0);
+ the_stick_of_joy = PUSH_LT(lt, SDL_JoystickOpen(0), SDL_JoystickClose);
if (the_stick_of_joy == NULL) {
- print_error_msg(ERROR_TYPE_SDL2, "Could not open 0th Stick of the Joy: %s\n");
- exit_code = -1;
- goto sdl_joystick_open_fail;
+ log_fail("Could not open 0th Stick of the Joy: %s\n", SDL_GetError());
+ RETURN_LT(lt, -1);
}
- printf("Opened Joystick 0\n");
- printf("Name: %s\n", SDL_JoystickNameForIndex(0));
- printf("Number of Axes: %d\n", SDL_JoystickNumAxes(the_stick_of_joy));
- printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(the_stick_of_joy));
- printf("Number of Balls: %d\n", SDL_JoystickNumBalls(the_stick_of_joy));
+ log_info("Opened Joystick 0\n");
+ log_info("Name: %s\n", SDL_JoystickNameForIndex(0));
+ log_info("Number of Axes: %d\n", SDL_JoystickNumAxes(the_stick_of_joy));
+ log_info("Number of Buttons: %d\n", SDL_JoystickNumButtons(the_stick_of_joy));
+ log_info("Number of Balls: %d\n", SDL_JoystickNumBalls(the_stick_of_joy));
SDL_JoystickEventState(SDL_ENABLE);
} else {
- fprintf(stderr, "[WARNING] Could not find any Sticks of the Joy\n");
+ log_warn("Could not find any Sticks of the Joy\n");
}
+ if (Mix_OpenAudio(
+ MIX_DEFAULT_FREQUENCY,
+ MIX_DEFAULT_FORMAT,
+ 2,
+ 1024) < 0) {
+ log_fail("Could not initialize the audio: %s\n", Mix_GetError());
+ RETURN_LT(lt, -1);
+ }
+ PUSH_LT(lt, 42, Mix_CloseAudio_lt);
+
// ------------------------------
- game_t *const game = create_game(LEVEL_FILE_NAME);
+ const char * sound_sample_files[] = {
+ "./sounds/nothing.wav",
+ "./sounds/something.wav"
+ };
+ const size_t sound_sample_files_count = sizeof(sound_sample_files) / sizeof(char*);
+
+ Game *const game = PUSH_LT(
+ lt,
+ create_game(
+ level_filename,
+ sound_sample_files,
+ sound_sample_files_count,
+ renderer),
+ destroy_game);
if (game == NULL) {
- print_current_error_msg("Could not create the game object");
- exit_code = -1;
- goto create_game_failed;
+ RETURN_LT(lt, -1);
}
const Uint8 *const keyboard_state = SDL_GetKeyboardState(NULL);
- const Uint32 delay_ms = (Uint32) roundf(1000.0f / GAME_FPS);
+
+ SDL_StopTextInput();
SDL_Event e;
- while (!is_game_over(game)) {
- while (!is_game_over(game) && SDL_PollEvent(&e)) {
+ const int64_t delta_time = (int64_t) roundf(1000.0f / 60.0f);
+ int64_t render_timer = (int64_t) roundf(1000.0f / (float) fps);
+ while (!game_over_check(game)) {
+ const int64_t begin_frame_time = (int64_t) SDL_GetTicks();
+
+ while (!game_over_check(game) && SDL_PollEvent(&e)) {
if (game_event(game, &e) < 0) {
- print_current_error_msg("Failed handling event");
- exit_code = -1;
- goto game_failed;
+ RETURN_LT(lt, -1);
}
}
if (game_input(game, keyboard_state, the_stick_of_joy) < 0) {
- print_current_error_msg("Failed handling input");
- exit_code = -1;
- goto game_failed;
+ RETURN_LT(lt, -1);
}
- if (game_update(game, delay_ms) < 0) {
- print_current_error_msg("Failed handling updating");
- exit_code = -1;
- goto game_failed;
+ if (game_update(game, (float) delta_time * 0.001f) < 0) {
+ RETURN_LT(lt, -1);
}
- if (game_render(game, renderer) < 0) {
- print_current_error_msg("Failed rendering the game");
- exit_code = -1;
- goto game_failed;
+ if (game_sound(game) < 0) {
+ RETURN_LT(lt, -1);
}
+
+ render_timer -= delta_time;
+ if (render_timer <= 0) {
+ if (game_render(game) < 0) {
+ RETURN_LT(lt, -1);
+ }
+ SDL_RenderPresent(renderer);
+ render_timer = (int64_t) roundf(1000.0f / (float) fps);
+ }
+
+ const int64_t end_frame_time = (int64_t) SDL_GetTicks();
+#define max_int64(a, b) (a > b ? a : b)
+ SDL_Delay((unsigned int) max_int64(10, delta_time - (end_frame_time - begin_frame_time)));
+#undef max_int64
}
-game_failed:
- destroy_game(game);
-create_game_failed:
- if (the_stick_of_joy) { SDL_JoystickClose(the_stick_of_joy); }
-sdl_joystick_open_fail:
- SDL_DestroyRenderer(renderer);
-sdl_create_renderer_fail:
- SDL_DestroyWindow(window);
-sdl_create_window_fail:
- SDL_Quit();
-sdl_init_fail:
- return exit_code;
+ RETURN_LT(lt, 0);
}