mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 14:05:45 +01:00
clean up code
This commit is contained in:
60
src/error.c
60
src/error.c
@@ -1,60 +0,0 @@
|
||||
#include "error.h"
|
||||
|
||||
#include <SDL_messagebox.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdnoreturn.h>
|
||||
|
||||
#define PRINT_BUFFER_SIZE 128 // defines the buffer size for printing
|
||||
|
||||
// writes the arguments to the specified buffer
|
||||
// using a macro instead of an inline function because fmt otherwise gets horribly messed up
|
||||
#define write_args(buf, fmt) \
|
||||
va_list args; \
|
||||
va_start(args, fmt); \
|
||||
(void)vsnprintf(buf, PRINT_BUFFER_SIZE, fmt, args); \
|
||||
va_end(args);
|
||||
|
||||
void debug(char const* restrict fmt, ...) {
|
||||
char const* env = getenv("DEBUG");
|
||||
if (env == NULL || *env != '1')
|
||||
return;
|
||||
|
||||
char buf[PRINT_BUFFER_SIZE] = {0};
|
||||
write_args(buf, fmt);
|
||||
|
||||
(void)fprintf(stdout, "\033[95m%s\033[0m\n", buf);
|
||||
}
|
||||
|
||||
void info(char const* restrict fmt, ...) {
|
||||
char buf[PRINT_BUFFER_SIZE] = {0};
|
||||
write_args(buf, fmt);
|
||||
(void)fprintf(stdout, "\033[0m%s\033[0m\n", buf); // write colour here for consistency
|
||||
}
|
||||
|
||||
void warn(char const* restrict fmt, ...) {
|
||||
char buf[PRINT_BUFFER_SIZE] = {0};
|
||||
write_args(buf, fmt);
|
||||
(void)fprintf(stderr, "\033[93mW: %s\033[0m\n", buf);
|
||||
}
|
||||
|
||||
void error(char const* restrict fmt, ...) {
|
||||
char buf[PRINT_BUFFER_SIZE] = {0};
|
||||
write_args(buf, fmt);
|
||||
(void)fprintf(stderr, "\033[91mE: %s\033[0m\n", buf);
|
||||
}
|
||||
|
||||
noreturn void fatal(unsigned error_code, char const* restrict fname, unsigned ln, char const* restrict fmt, ...) {
|
||||
char buf1[PRINT_BUFFER_SIZE] = {0};
|
||||
write_args(buf1, fmt);
|
||||
|
||||
char buf2[PRINT_BUFFER_SIZE * 2] = {0};
|
||||
sprintf(buf2, "%s\n at %s:%u (exitcode: %u)", buf1, fname, ln, error_code);
|
||||
|
||||
(void)fprintf(stderr, "\033[101mF: %s\033[0m\n", buf2);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "something went wrong! :O", buf2, NULL);
|
||||
|
||||
// set status, but exit immediately, as code is not allowed to execute beyond this point
|
||||
exit(error_code);
|
||||
}
|
||||
24
src/error.h
24
src/error.h
@@ -29,10 +29,22 @@ enum gamestatus {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
__attribute__((nonnull(1))) __attribute__((format(printf, 1, 2))) void debug(char const* restrict, ...); // prints a debug message to stdout if the DEBUG environment variable is set, otherwise the call is ignored.
|
||||
__attribute__((nonnull(1))) __attribute__((format(printf, 1, 2))) void info(char const* restrict, ...); // prints an info message to stdout
|
||||
__attribute__((nonnull(1))) __attribute__((format(printf, 1, 2))) void warn(char const* restrict, ...); // prints a warning message to stderr
|
||||
__attribute__((nonnull(1))) __attribute__((format(printf, 1, 2))) void error(char const* restrcit, ...); // prints an warning message to stderr
|
||||
#if __INCLUDE_LEVEL__ > 0
|
||||
#include <SDL_messagebox.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// prints an error message to stderr before exiting
|
||||
__attribute__((nonnull(2, 5))) __attribute__((format(printf, 4, 5))) noreturn void fatal(unsigned, char const* restrict file_name, unsigned line, char const* restrict fmt, ...);
|
||||
#include "util/macro.h"
|
||||
#endif
|
||||
|
||||
#define debug(s, ...) printf("\033[95m" __FILE__ ":" MACRO_STR2(__LINE__) ": [DBG]: " s "\033[0m\n" __VA_OPT__(, __VA_ARGS__))
|
||||
#define info(s, ...) printf(__FILE__ ":" MACRO_STR2(__LINE__) ": [INF]: " s "\n", __VA_OPT__(, __VA_ARGS__))
|
||||
#define warn(s, ...) fprintf(stderr, "\033[93m" __FILE__ ":" MACRO_STR2(__LINE__) ": [WAR]: " s "\033[0m\n" __VA_OPT__(, __VA_ARGS__))
|
||||
#define error(s, ...) fprintf(stderr, "\033[91m" __FILE__ ":" MACRO_STR2(__LINE__) ": [ERR]: " s "\033[0m\n" __VA_OPT__(, __VA_ARGS__))
|
||||
|
||||
#define fatal(c, s, ...) \
|
||||
do { \
|
||||
printf("\033[101m" __FILE__ ":" MACRO_STR2(__LINE__) ": [FAT]: " s "\033[0m\n" __VA_OPT__(, __VA_ARGS__)); \
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "something went wrong! :O", "view stderr for full details: \n" s, NULL); \
|
||||
exit(c); \
|
||||
} while (0)
|
||||
|
||||
@@ -6,18 +6,15 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../error.h"
|
||||
#include "../window/audio.h"
|
||||
#include "./tetromino/shapes.h"
|
||||
#include "gametime.h"
|
||||
#include "opts.h"
|
||||
#include "paths.h"
|
||||
#include "tetromino/placing.h"
|
||||
|
||||
// shuffle the array using a Fisher–Yates shuffle
|
||||
/* shuffle the array using a Fisher–Yates shuffle */
|
||||
static inline void shuffle(uint8_t const size, shape_id* const elmnts) {
|
||||
for (uint8_t i = 0; i < (size - 1); i++) {
|
||||
uint8_t const j = i + rand() % (size - i);
|
||||
|
||||
@@ -7,20 +7,17 @@ struct gametime {
|
||||
};
|
||||
|
||||
#if __has_include(<features.h>)
|
||||
# include <features.h>
|
||||
# if _POSIX_C_SOURCE >= 199309L
|
||||
# include <bits/time.h>
|
||||
#include <features.h>
|
||||
#endif
|
||||
#if __has_include(<features.h>) && _POSIX_C_SOURCE >= 199309L
|
||||
#include <bits/time.h>
|
||||
static inline void gametime_get(struct timespec* ts) {
|
||||
clock_gettime(CLOCK_MONOTONIC, ts);
|
||||
}
|
||||
# define GTIME_USE_UNIX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && !defined GTIME_USE_UNIX
|
||||
# include <profileapi.h>
|
||||
# include <windows.h>
|
||||
# include <winnt.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <profileapi.h>
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
static inline void gametime_get(struct timespec* ts) {
|
||||
LARGE_INTEGER cnt, frq;
|
||||
QueryPerformanceCounter(&cnt);
|
||||
@@ -28,8 +25,4 @@ static inline void gametime_get(struct timespec* ts) {
|
||||
ts->tv_sec = (time_t)(cnt.QuadPart / frq.QuadPart);
|
||||
ts->tv_nsec = (time_t)((cnt.QuadPart % frq.QuadPart) * 1000000000 / frq.QuadPart);
|
||||
}
|
||||
#elif defined GTIME_USE_UNIX
|
||||
# undef GTIME_USE_UNIX
|
||||
#else
|
||||
# error platform not supported
|
||||
#endif
|
||||
|
||||
@@ -125,12 +125,10 @@ static void proc_buf(char const* restrict buf, struct proc_buf_dat* restrict dat
|
||||
|
||||
// allocate memory for the resulting string(s)
|
||||
if (dat->pval_len < dat->val_len) { // first check this condition, as key won't have changed if this is true
|
||||
if (str_put(&dat->pval, dat->pval_len, dat->val, dat->val_len))
|
||||
fatal(ERROR_STD_MEMORY_INIT, __FILE_NAME__, __LINE__, "something went wrong when attempting to allocate space for the option string");
|
||||
if (str_put(&dat->pval, dat->pval_len, dat->val, dat->val_len)) fatal(ERROR_STD_MEMORY_INIT, "something went wrong when attempting to allocate space for the option string", );
|
||||
dat->pval_len = dat->val_len;
|
||||
} else if (dat->pkey_len < dat->key_len) {
|
||||
if (str_put(&dat->pkey, dat->pkey_len, dat->key, dat->key_len))
|
||||
fatal(ERROR_STD_MEMORY_INIT, __FILE_NAME__, __LINE__, "something went wrong when attempting to allocate space for the option string");
|
||||
if (str_put(&dat->pkey, dat->pkey_len, dat->key, dat->key_len)) fatal(ERROR_STD_MEMORY_INIT, "something went wrong when attempting to allocate space for the option string", );
|
||||
dat->pkey_len = dat->key_len;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +149,7 @@ static void proc_buf(char const* restrict buf, struct proc_buf_dat* restrict dat
|
||||
returns 1 upon failure */
|
||||
int load_opts(void) {
|
||||
if (!path_opts) {
|
||||
error("the variable to the path to the options failed to initialize");
|
||||
error("the variable to the path to the options failed to initialize", );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static unsigned getdatpath(void) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline char const* init_path(char const* const restrict str, unsigned len) {
|
||||
static inline char const* init_path(char const* restrict const str, unsigned len) {
|
||||
void* ptr = malloc(len);
|
||||
if (!ptr) return NULL;
|
||||
strcpy(ptr, path_dat);
|
||||
|
||||
@@ -135,8 +135,8 @@ void place_update(gamedata* const game_data, input_data const move) {
|
||||
// update the shape's rotation
|
||||
if (move & 8 || move & 16) {
|
||||
shape_id const id = move & 8 // check which direction we should move
|
||||
? rotate_id(curr_id, -8)
|
||||
: rotate_id(curr_id, 8);
|
||||
? rotate_id(curr_id, -8)
|
||||
: rotate_id(curr_id, 8);
|
||||
if (shape_intersects(game_data->rows, id, game_data->sel_x, game_data->sel_y) == false) {
|
||||
game_data->nxt[curr_idx] = id;
|
||||
}
|
||||
|
||||
@@ -37,10 +37,9 @@
|
||||
#define SHAPE_J_270 ((shape)0x0E20) // 0000 1110 0010 0000 the J tetromino with a 270° rotation
|
||||
|
||||
shape shape_from_id(shape_id const id) {
|
||||
// clang-format off
|
||||
static shape const shapes[TETROMINO_COUNT][4] = {
|
||||
// 0° 90° 180° 170°
|
||||
{SHAPE_O, SHAPE_O, SHAPE_O, SHAPE_O},
|
||||
{SHAPE_O, SHAPE_O, SHAPE_O, SHAPE_O },
|
||||
{SHAPE_I, SHAPE_I_90, SHAPE_I_180, SHAPE_I_270},
|
||||
{SHAPE_S, SHAPE_S_90, SHAPE_S_180, SHAPE_S_270},
|
||||
{SHAPE_Z, SHAPE_Z_90, SHAPE_Z_180, SHAPE_Z_270},
|
||||
@@ -48,7 +47,6 @@ shape shape_from_id(shape_id const id) {
|
||||
{SHAPE_L, SHAPE_L_90, SHAPE_L_180, SHAPE_L_270},
|
||||
{SHAPE_J, SHAPE_J_90, SHAPE_J_180, SHAPE_J_270},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// first 3 bits is the shape type, the rest is rotation data
|
||||
return shapes[id & 7][id >> 3];
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -15,10 +15,8 @@ static renderdata rdat;
|
||||
// initialize the game
|
||||
static void init(void) {
|
||||
// initialize SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
|
||||
fatal(ERROR_SDL_INIT, __FILE_NAME__, __LINE__, "SDL could not initialize! SDL Error: %s", SDL_GetError());
|
||||
if (TTF_Init() != 0)
|
||||
fatal(ERROR_SDL_FONT_INIT, __FILE_NAME__, __LINE__, "the TTF module of SDL could not initialize! TTF Error: %s", TTF_GetError());
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) fatal(ERROR_SDL_INIT, "SDL could not initialize! SDL Error: %s", SDL_GetError());
|
||||
if (TTF_Init() != 0) fatal(ERROR_SDL_FONT_INIT, "the TTF module of SDL could not initialize! TTF Error: %s", TTF_GetError());
|
||||
|
||||
// initialize other game components
|
||||
paths_init();
|
||||
@@ -50,12 +48,12 @@ int main(int argc, char** argv) {
|
||||
(void)argc, (void)argv;
|
||||
|
||||
init();
|
||||
debug("successfully initialized!");
|
||||
debug("successfully initialized!", );
|
||||
|
||||
while (gdat.run == true)
|
||||
update();
|
||||
|
||||
debug("done! starting to free resources...");
|
||||
debug("done! starting to free resources...", );
|
||||
game_free(&gdat);
|
||||
render_free(&rdat);
|
||||
paths_free();
|
||||
|
||||
@@ -10,26 +10,26 @@
|
||||
// define the attributes where possible
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
# if __has_attribute(deprecated)
|
||||
# undef atrb_deprecated
|
||||
# define atrb_deprecated __attribute__((deprecated))
|
||||
# endif
|
||||
|
||||
# if __has_attribute(unused)
|
||||
# undef atrb_unused
|
||||
# define atrb_unused __attribute__((unused))
|
||||
# endif
|
||||
|
||||
# if __has_attribute(pure)
|
||||
# undef atrb_pure
|
||||
# define atrb_pure __attribute__((pure))
|
||||
# endif
|
||||
|
||||
# if __has_attribute(const)
|
||||
# undef atrb_const
|
||||
# define atrb_const __attribute__((const))
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# undef atrb_depatrb_deprecated
|
||||
# define atrb_deprecated __declspec(deprecated)
|
||||
#if __has_attribute(deprecated)
|
||||
#undef atrb_deprecated
|
||||
#define atrb_deprecated __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#if __has_attribute(unused)
|
||||
#undef atrb_unused
|
||||
#define atrb_unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#if __has_attribute(pure)
|
||||
#undef atrb_pure
|
||||
#define atrb_pure __attribute__((pure))
|
||||
#endif
|
||||
|
||||
#if __has_attribute(const)
|
||||
#undef atrb_const
|
||||
#define atrb_const __attribute__((const))
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#undef atrb_depatrb_deprecated
|
||||
#define atrb_deprecated __declspec(deprecated)
|
||||
#endif
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#if defined __unix__
|
||||
# include <features.h>
|
||||
# include <unistd.h>
|
||||
#include <features.h>
|
||||
#include <unistd.h>
|
||||
#elif defined _WIN32
|
||||
# include <io.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
# error platform not supported!
|
||||
#error platform not supported!
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define PATH_SEP '\\' // contains the path separator as a character. Yes it is extremely annoying that this has to exist.
|
||||
# define PATH_SEP_STR "\\" // contains the path separator as a string, useful for concatenation. Yes it is extremely annoying that this has to exist.
|
||||
#define PATH_SEP '\\' // contains the path separator as a character. Yes it is extremely annoying that this has to exist.
|
||||
#define PATH_SEP_STR "\\" // contains the path separator as a string, useful for concatenation. Yes it is extremely annoying that this has to exist.
|
||||
|
||||
# define unixonly(_exec) // (no-op) executes inline code when __unix__ is defined, otherwise is no-op
|
||||
# define winonly(_exec) _exec // executes inline code when _WIN32 is defined, otherwise is no-op
|
||||
#define unixonly(_exec) // (no-op) executes inline code when __unix__ is defined, otherwise is no-op
|
||||
#define winonly(_exec) _exec // executes inline code when _WIN32 is defined, otherwise is no-op
|
||||
#else
|
||||
# define PATH_SEP '/' // contains the path separator as a character. Yes it is extremely annoying that this has to exist.
|
||||
# define PATH_SEP_STR "/" // contains the path separator as a string, useful for concatenation. Yes it is extremely annoying that this has to exist.
|
||||
#define PATH_SEP '/' // contains the path separator as a character. Yes it is extremely annoying that this has to exist.
|
||||
#define PATH_SEP_STR "/" // contains the path separator as a string, useful for concatenation. Yes it is extremely annoying that this has to exist.
|
||||
|
||||
# define unixonly(_exec) _exec // executes inline code when __unix__ is defined, otherwise is no-op
|
||||
# define winonly(_exec) // (no-op) executes inline code when _WIN32 is defined, otherwise is no-op
|
||||
#define unixonly(_exec) _exec // executes inline code when __unix__ is defined, otherwise is no-op
|
||||
#define winonly(_exec) // (no-op) executes inline code when _WIN32 is defined, otherwise is no-op
|
||||
#endif
|
||||
|
||||
// define the constants if they haven't been
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
#define F_OK 0
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
# define X_OK 1
|
||||
#define X_OK 1
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
# define W_OK 2
|
||||
#define W_OK 2
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
# define R_OK 4
|
||||
#define R_OK 4
|
||||
#endif
|
||||
|
||||
enum faccess_perms {
|
||||
@@ -52,6 +52,6 @@ static inline int faccess(char const* restrict fname, int perms) {
|
||||
#elif defined _WIN32
|
||||
return _access(fname, perms);
|
||||
#else
|
||||
# error platform unsupported!
|
||||
#error platform unsupported!
|
||||
#endif
|
||||
}
|
||||
|
||||
6
src/util/macro.h
Normal file
6
src/util/macro.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#define MACRO_WIDTH(t) (sizeof(t) * 8) // gets the bit width of a type
|
||||
#define MACRO_CAT(x, y) x##y // concatenate two macro variables together
|
||||
#define MACRO_CAT2(x, y) MACRO_CAT(x, y) // concatenate two macro variables together
|
||||
#define MACRO_STR(v) #v // for converting macro variable into a string
|
||||
#define MACRO_STR2(v) MACRO_STR(v) // for a recursive string generation
|
||||
@@ -10,9 +10,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "../error.h"
|
||||
#include "../game/game.h"
|
||||
@@ -24,10 +22,10 @@
|
||||
|
||||
void render_init(renderdata* const render_dat, gamedata const* const game_dat) {
|
||||
SDL_Window* const window = SDL_CreateWindow("tetris clone", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
if (window == NULL) fatal(ERROR_SDL_RENDERING_INIT, __FILE_NAME__, __LINE__, "Window failed to be created! SDL Error: %s", SDL_GetError());
|
||||
if (window == NULL) fatal(ERROR_SDL_RENDERING_INIT, "Window failed to be created! SDL Error: %s", SDL_GetError());
|
||||
|
||||
SDL_Renderer* const renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == NULL) fatal(ERROR_SDL_RENDERING_INIT, __FILE_NAME__, __LINE__, "Renderer failed to be created! SDL Error: %s", SDL_GetError());
|
||||
if (renderer == NULL) fatal(ERROR_SDL_RENDERING_INIT, "Renderer failed to be created! SDL Error: %s", SDL_GetError());
|
||||
|
||||
TTF_Font* const font = TTF_OpenFont("pixeldroid_botic-regular.ttf", PX_DENS);
|
||||
if (font == NULL) error("Failed to open font! TTF Error: %s", TTF_GetError());
|
||||
@@ -77,7 +75,7 @@ static void draw_score_text(renderdata const* dat) {
|
||||
}
|
||||
|
||||
if (cache->score_surface == NULL || cache->score_texture == NULL) {
|
||||
error("the score texture was unavailable!");
|
||||
error("the score texture was unavailable!",);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <SDL_video.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../game/game.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user