mirror of
https://github.com/thepigeongenerator/breakout_clone.git
synced 2025-12-16 22:05:45 +01:00
rebase project on SDL template, added audio and fixed some bugs
This commit is contained in:
198
src/main.c
198
src/main.c
@@ -1,105 +1,93 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "error_codes.h"
|
||||
#include "renderer.h"
|
||||
#include "level.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#define UPDATES_PER_SEC 50
|
||||
#define CLOCKS_PER_UPDATE (CLOCKS_PER_SEC / UPDATES_PER_SEC)
|
||||
#define CLOCKS_PER_UPDATE_F (((float)CLOCKS_PER_SEC) / UPDATES_PER_SEC)
|
||||
|
||||
Level level = { 0 }; // stores the game's state
|
||||
SDL_Window* window = NULL; // the window that is given to the OS
|
||||
SDL_Renderer* renderer = NULL; // the renderer used to draw to the window
|
||||
|
||||
// initializes the game
|
||||
static int init(void) {
|
||||
level_init(&level);
|
||||
return renderer_init(&window, &renderer);
|
||||
}
|
||||
|
||||
|
||||
// called on each game update
|
||||
static bool update(void) {
|
||||
const clock_t clock_start = clock();
|
||||
|
||||
//update the event keys
|
||||
{
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderData render_data = { window, renderer, &level }; //contains the data which is used to render the game
|
||||
const Uint8* keys = SDL_GetKeyboardState(NULL);
|
||||
|
||||
// preform updates
|
||||
{
|
||||
level_update(&level, keys); //update the level
|
||||
renderer_update(&render_data); //update the render
|
||||
}
|
||||
|
||||
const clock_t clock_end = clock();
|
||||
|
||||
// provide a delay if needed, otherwise log a warning
|
||||
const clock_t clock_diff = clock_end - clock_start; // difference / how long the operations took
|
||||
const int remaining_ms = (int)((CLOCKS_PER_UPDATE_F - clock_diff) / CLOCKS_PER_SEC) * 1000;
|
||||
|
||||
if (remaining_ms < 0) {
|
||||
(void)printf("delay between updates was %dms too long.", -remaining_ms);
|
||||
}
|
||||
else {
|
||||
SDL_Delay(remaining_ms); // wait the time in ms
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
static void update_game(void) {
|
||||
// stop updating if update returns false
|
||||
if (update() == false) {
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// cleans up resources
|
||||
static void close(SDL_Window* window, SDL_Renderer* renderer) {
|
||||
renderer_destroy(window, renderer);
|
||||
}
|
||||
|
||||
// entry-point of the application
|
||||
int main(int argc, char *argv[]) {
|
||||
// initialize
|
||||
{
|
||||
const int code = init();
|
||||
if (code != SUCCESS)
|
||||
exit(code);
|
||||
}
|
||||
|
||||
// TEMP: tell me that the program has been initialized
|
||||
(void)printf("initialized!\n");
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(update_game, 0, 1); // don't utilise setting the FPS, as we already do this
|
||||
#else
|
||||
while (update() && (level.stop == false));
|
||||
#endif
|
||||
|
||||
// frees media and shuts down SDL
|
||||
close(window, renderer);
|
||||
(void)printf("finished!\n");
|
||||
return 0;
|
||||
}
|
||||
#include "main.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "errors.h"
|
||||
#include "game/level.h"
|
||||
#include "window/audio.h"
|
||||
#include "window/renderer.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__ // for web builds
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
|
||||
bool playing = true;
|
||||
|
||||
SDL_Window* window = NULL;
|
||||
SDL_Renderer* renderer = NULL;
|
||||
Level* level = NULL;
|
||||
|
||||
// handles game application initialisation
|
||||
static void init(void) {
|
||||
// initialize SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
error(FAILURE_SDL_INIT, "SDL could not initialize! SDL Error: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize the renderer
|
||||
if (renderer_init(&window, &renderer) < 0) {
|
||||
error(FAILURE_SDL_RENDERER, SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize level
|
||||
level = malloc(sizeof(Level));
|
||||
level_init(level);
|
||||
|
||||
// initialize audio
|
||||
level->audio_device = audio_device_init(32000, AUDIO_S16, 1, 4096);
|
||||
level->bounce_sfx = audio_load_wav(level->audio_device, "./assets/bounce.wav");
|
||||
}
|
||||
|
||||
// handles game application updating
|
||||
static void update(void) {
|
||||
// update the input
|
||||
{
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
exit(SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// preform updates
|
||||
level_update(level, SDL_GetKeyboardState(NULL));
|
||||
renderer_update(&(RenderData){window, renderer, level});
|
||||
}
|
||||
|
||||
// handles game application quitting
|
||||
void stop(void) {
|
||||
playing = false;
|
||||
|
||||
#if __EMSCRIPTEN__
|
||||
emscripten_cancel_main_loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
// entry point of the application
|
||||
int main(int argc, char** argv) {
|
||||
init();
|
||||
|
||||
#if __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(update, 0, 1);
|
||||
#else
|
||||
while (playing)
|
||||
update();
|
||||
#endif
|
||||
|
||||
// cleanup of resources
|
||||
SDL_FreeWAV(level->bounce_sfx.buffer);
|
||||
SDL_CloseAudioDevice(level->audio_device->id);
|
||||
free(level);
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user