diff --git a/.clang-format b/.clang-format index 5c1061b..b19a042 100644 --- a/.clang-format +++ b/.clang-format @@ -14,14 +14,14 @@ ContinuationIndentWidth: 4 # width for a line continuation # --------------------------- # alignment options # --------------------------- -AlignAfterOpenBracket: Align # (Align,DontAlign,AlwaysBreak,BlockIndent) +AlignAfterOpenBracket: DontAlign # (Align,DontAlign,AlwaysBreak,BlockIndent) AlignArrayOfStructures: Left # (Left,Right,None) AlignConsecutiveMacros: AcrossEmptyLines # (None,Consecutive,AcrossEmptyLines,AcrossComments,AcrossEmptyLinesAndComments) AlignConsecutiveAssignments: None # (None,Consecutive,AcrossEmptyLines,AcrossComments,AcrossEmptyLinesAndComments) AlignConsecutiveBitFields: AcrossEmptyLines # (None,Consecutive,AcrossEmptyLines,AcrossComments,AcrossEmptyLinesAndComments) AlignConsecutiveDeclarations: None # (None,Consecutive,AcrossEmptyLines,AcrossComments,AcrossEmptyLinesAndComments) AlignEscapedNewlines: Left # (DontAlign,Left,LeftWithLastLine,Right) -AlignOperands: Align # (DontAlign,Align,AlignAfterOperator) +AlignOperands: DontAlign # (DontAlign,Align,AlignAfterOperator) AlignTrailingComments: Always # (Leave,Always,Never) # --------------------------- @@ -59,6 +59,7 @@ BraceWrapping: AfterEnum: false AfterFunction: false AfterNamespace: false + AfterObjCDeclaration: false AfterStruct: false AfterUnion: false AfterExternBlock: false @@ -85,6 +86,7 @@ BinPackArguments: false # false: function calls either on DerivePointerAlignment: false # automatically detect pointer alignment PointerAlignment: Left # (Left,Right,Middle) ReferenceAlignment: Pointer # (Pointer,Left,Right,Middle) +QualifierAlignment: Right # (Leave,Left,Right,Custom) # --------------------------- # include settings and sorting @@ -93,12 +95,12 @@ IncludeIsMainSourceRegex: '' # only [*.{c,cc,cpp,c++,cxx, IncludeIsMainRegex: '([-_](test|unittest))?$' # regex used for identifying an include as "main", to assign catagory 0 IncludeBlocks: Regroup # (Preserve,Merge,Regroup) IncludeCategories: - - Regex: '^<.*\.h>' # system headers - Priority: 1 + - Regex: '^<.*\.h>' # system headers + Priority: 2 SortPriority: 0 CaseSensitive: true - - Regex: '^".*' # custom headers - Priority: 2 + - Regex: '^".*' # custom headers + Priority: 3 SortPriority: 0 CaseSensitive: true @@ -140,6 +142,7 @@ RemoveBracesLLVM: false # don't automatically rem SeparateDefinitionBlocks: Leave # (Leave,Always.Never) ShortNamespaceLines: 1 # how many lines a namespaces can be to be regarded "short" SortIncludes: CaseSensitive # (Never,CaseSensitive,CaseInsensitive) +SortJavaStaticImport: Before # (After,Before) SortUsingDeclarations: LexicographicNumeric # (Never,Lexicographic,LexicographicNumeric) # --------------------------- @@ -192,6 +195,17 @@ IndentCaseBlocks: false IndentGotoLabels: true IndentExternBlock: AfterExternBlock # (AfterExternBlock,NoIndent,Indent) IndentRequiresClause: false -IndentPPDirectives: AfterHash # preprocessor indent style (None,AfterHash,BeforeHash) +IndentPPDirectives: None # preprocessor indent style (None,AfterHash,BeforeHash) PPIndentWidth: 1 + +--- +# --------------------------- +# Objective-C specific settings +# --------------------------- +Language: ObjC +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true ... diff --git a/src/error.c b/src/error.c deleted file mode 100644 index 06129c7..0000000 --- a/src/error.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "error.h" - -#include -#include -#include -#include -#include - -#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); -} diff --git a/src/error.h b/src/error.h index 469c61b..e672cff 100644 --- a/src/error.h +++ b/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 +#include +#include -// 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) diff --git a/src/game/game.c b/src/game/game.c index 4ca0bc4..5beb8ef 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -6,18 +6,15 @@ #include #include #include -#include #include -#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); diff --git a/src/game/gametime.h b/src/game/gametime.h index 598079d..0014c72 100644 --- a/src/game/gametime.h +++ b/src/game/gametime.h @@ -7,20 +7,17 @@ struct gametime { }; #if __has_include() -# include -# if _POSIX_C_SOURCE >= 199309L -# include +#include +#endif +#if __has_include() && _POSIX_C_SOURCE >= 199309L +#include 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 -# include -# include +#elif defined(_WIN32) +#include +#include +#include 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 diff --git a/src/game/opts.c b/src/game/opts.c index 6764f24..af88d8b 100644 --- a/src/game/opts.c +++ b/src/game/opts.c @@ -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; } diff --git a/src/game/paths.c b/src/game/paths.c index e6b4539..cb074c4 100644 --- a/src/game/paths.c +++ b/src/game/paths.c @@ -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); diff --git a/src/game/tetromino/placing.c b/src/game/tetromino/placing.c index a65be2f..179f775 100644 --- a/src/game/tetromino/placing.c +++ b/src/game/tetromino/placing.c @@ -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; } diff --git a/src/game/tetromino/shapes.c b/src/game/tetromino/shapes.c index 23dadc0..02fbe05 100644 --- a/src/game/tetromino/shapes.c +++ b/src/game/tetromino/shapes.c @@ -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]; diff --git a/src/main.c b/src/main.c index a3746c9..bbf8e7d 100644 --- a/src/main.c +++ b/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(); diff --git a/src/util/attributes.h b/src/util/attributes.h index 223f4fe..75c5536 100644 --- a/src/util/attributes.h +++ b/src/util/attributes.h @@ -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 diff --git a/src/util/compat.h b/src/util/compat.h index ecf4598..5ff785f 100644 --- a/src/util/compat.h +++ b/src/util/compat.h @@ -1,40 +1,40 @@ #pragma once #if defined __unix__ -# include -# include +#include +#include #elif defined _WIN32 -# include +#include #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 } diff --git a/src/util/macro.h b/src/util/macro.h new file mode 100644 index 0000000..e2b8247 --- /dev/null +++ b/src/util/macro.h @@ -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 diff --git a/src/window/renderer.c b/src/window/renderer.c index bc96889..247dbda 100644 --- a/src/window/renderer.c +++ b/src/window/renderer.c @@ -10,9 +10,7 @@ #include #include #include -#include #include -#include #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; } diff --git a/src/window/renderer.h b/src/window/renderer.h index d31c721..5b69851 100644 --- a/src/window/renderer.h +++ b/src/window/renderer.h @@ -1,8 +1,10 @@ #pragma once #include +#include #include #include +#include #include "../game/game.h"