diff --git a/makefile b/makefile index ac08754..055cf0d 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ NAME = sdl_template CC := clang STD := c17 LANG = c -CFLAGS := $(shell pkg-config --cflags sdl2) -Wall -g +CFLAGS := $(shell pkg-config --cflags sdl2) -Wall -g -pedantic LDFLAGS := $(shell pkg-config --libs sdl2) -lm # file locations diff --git a/src/errors.c b/src/errors.c index fa7d860..b2dcd75 100644 --- a/src/errors.c +++ b/src/errors.c @@ -1,8 +1,9 @@ #include "errors.h" -#include +#include #include #include +#include #define MAX_STR_LEN 128 diff --git a/src/game/game.c b/src/game/game.c index 9a7935b..5ee4a33 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -1,10 +1,12 @@ #include "game.h" +#include #include #include #include #include "../main.h" +#include "../window/colour.h" #include "shapes.h" @@ -38,7 +40,7 @@ static void clear_rows(Row* row) { } // sets a shape to the screen -static void _set_shape(Row* row, const Shape shape, const Colour colour, const uint8_t pos_x) { +static void set_shape_i(Row* row, const Shape shape, const Colour colour, const uint8_t pos_x) { for (uint8_t y = 0; y < SHAPE_HEIGHT; y++) { ShapeRow shape_row = shape_get_row(shape, y); @@ -52,11 +54,11 @@ static void _set_shape(Row* row, const Shape shape, const Colour colour, const u } static inline void set_shape(Row* row, const Shape shape, const Colour colour, const uint8_t pos_x, const uint8_t pos_y) { - _set_shape(&row[pos_y], shape, colour, pos_x); // calls itself, but omitting the pos_y argument, instead opting for specifying the row + set_shape_i(&row[pos_y], shape, colour, pos_x); // calls itself, but omitting the pos_y argument, instead opting for specifying the row } // called every time the game's state is updated -void game_update(GameData* game_data, const Uint8* keys) { +void game_update(GameData* game_data, const uint8_t* keys) { if (keys[SDL_SCANCODE_ESCAPE]) { stop(); } diff --git a/src/game/game.h b/src/game/game.h index 7a1eabf..3435eb3 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -1,5 +1,6 @@ #pragma once -#include + +#include #include "../window/colour.h" @@ -7,7 +8,7 @@ typedef uint32_t PackedRow; // stores the data used in the game #define COLUMNS ((uint8_t)(sizeof(PackedRow) * 8 / 3)) -#define ROWS ((uint8_t)(COLUMNS * 2)) +#define ROWS ((uint8_t)(COLUMNS * 2)) typedef struct { Colour columns[COLUMNS]; @@ -18,4 +19,4 @@ typedef struct { } GameData; // updates the game's state -void game_update(GameData* game_data, const Uint8* keys); +void game_update(GameData* game_data, const uint8_t* keys); diff --git a/src/game/shapes.h b/src/game/shapes.h index b1299c1..103a64a 100644 --- a/src/game/shapes.h +++ b/src/game/shapes.h @@ -1,36 +1,40 @@ +#pragma once #include + +#include "../util/typed_enums.h" + #define SHAPE_WIDTH 4 #define SHAPE_HEIGHT 4 -typedef enum : uint16_t { +typedef enum_t(uint16_t){ // clang-format off - /* 0 1 2 3 */ - TETROMINO_I = 0b1000100010001000, // 1000 1000 1000 1000 the I tetromino with no rotation - TETROMINO_I_90 = 0b0000000000001111, // 0000 0000 0000 1111 the I tetromino with a no rotation - TETROMINO_O = 0b1100110000000000, // 1100 1100 0000 0000 the O tetromino with no rotation - TETROMINO_T = 0b1110010000000000, // 1110 0100 0000 0000 the T tetromino with no rotation - TETROMINO_T_90 = 0b1100110010000000, // 1100 1100 1000 0000 the T tetromino with a no rotation - TETROMINO_T_180 = 0b0100111000000000, // 0100 1110 0000 0000 the T tetromino with a 180° rotation - TETROMINO_T_270 = 0b0010011000100000, // 0010 0110 0010 0000 the T tetromino with a 270° rotation - TETROMINO_L = 0b1000100011000000, // 1000 1000 1100 0000 the L tetromino with no rotation - TETROMINO_L_90 = 0b1110100000000000, // 1110 1000 0000 0000 the L tetromino with a no rotation - TETROMINO_L_180 = 0b1100010001000000, // 1100 0100 0100 0000 the L tetromino with a 180° rotation - TETROMINO_L_270 = 0b0000001011100000, // 0000 0010 1110 0000 the L tetromino with a 270° rotation - TETROMINO_J = 0b0100010011000000, // 0100 0100 1100 0000 the J tetromino with no rotation - TETROMINO_J_90 = 0b1000111000000000, // 1000 1110 0000 0000 the J tetromino with a no rotation - TETROMINO_J_180 = 0b1100100010000000, // 1100 1000 1000 0000 the J tetromino with a 180° rotation - TETROMINO_J_270 = 0b1110001000000000, // 1110 0010 0000 0000 the J tetromino with a 270° rotation - TETROMINO_S = 0b0110110000000000, // 0110 1100 0000 0000 the S tetromino with no rotation - TETROMINO_S_90 = 0b1000110001000000, // 1000 1100 0100 0000 the S tetromino with a no rotation - TETROMINO_Z = 0b1100011000000000, // 1100 0110 0000 0000 the Z tetromino with no rotation - TETROMINO_Z_90 = 0b0100110010000000, // 0100 1100 1000 0000 the Z tetromino with a no rotation + /* 0 1 2 3 */ + TETROMINO_I = 0x8888, // 1000 1000 1000 1000 the I tetromino with no rotation + TETROMINO_I_90 = 0x000F, // 0000 0000 0000 1111 the I tetromino with a no rotation + TETROMINO_O = 0xCC00, // 1100 1100 0000 0000 the O tetromino with no rotation + TETROMINO_T = 0xE400, // 1110 0100 0000 0000 the T tetromino with no rotation + TETROMINO_T_90 = 0xCC80, // 1100 1100 1000 0000 the T tetromino with a no rotation + TETROMINO_T_180 = 0x4E00, // 0100 1110 0000 0000 the T tetromino with a 180° rotation + TETROMINO_T_270 = 0x2620, // 0010 0110 0010 0000 the T tetromino with a 270° rotation + TETROMINO_L = 0x88C0, // 1000 1000 1100 0000 the L tetromino with no rotation + TETROMINO_L_90 = 0xE800, // 1110 1000 0000 0000 the L tetromino with a no rotation + TETROMINO_L_180 = 0xC440, // 1100 0100 0100 0000 the L tetromino with a 180° rotation + TETROMINO_L_270 = 0x02E0, // 0000 0010 1110 0000 the L tetromino with a 270° rotation + TETROMINO_J = 0x44C0, // 0100 0100 1100 0000 the J tetromino with no rotation + TETROMINO_J_90 = 0x8E00, // 1000 1110 0000 0000 the J tetromino with a no rotation + TETROMINO_J_180 = 0xC880, // 1100 1000 1000 0000 the J tetromino with a 180° rotation + TETROMINO_J_270 = 0xC400, // 1110 0010 0000 0000 the J tetromino with a 270° rotation + TETROMINO_S = 0x6C00, // 0110 1100 0000 0000 the S tetromino with no rotation + TETROMINO_S_90 = 0x8C40, // 1000 1100 0100 0000 the S tetromino with a no rotation + TETROMINO_Z = 0xC600, // 1100 0110 0000 0000 the Z tetromino with no rotation + TETROMINO_Z_90 = 0x4C80, // 0100 1100 1000 0000 the Z tetromino with a no rotation // clang-format on } Shape; typedef uint8_t ShapeRow; static inline ShapeRow shape_get_row(Shape shape, uint8_t index) { - return shape >> (((SHAPE_HEIGHT - 1) - index) * 4) & 0b1111; + return shape >> (((SHAPE_HEIGHT - 1) - index) * 4) & 0xF; } static inline _Bool is_set(ShapeRow row, uint8_t index) { diff --git a/src/main.c b/src/main.c index 6684535..8c4ebb0 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,14 @@ #include "main.h" -#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include "errors.h" @@ -19,7 +25,7 @@ bool playing = true; SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; -GameData game_data = {}; +GameData game_data = {0}; // handles game application initialisation @@ -68,6 +74,9 @@ void stop(void) { // entry point of the application int main(int argc, char** argv) { + (void)argc; + (void)argv; + init(); while (playing) diff --git a/src/util/typed_enums.h b/src/util/typed_enums.h new file mode 100644 index 0000000..8751aed --- /dev/null +++ b/src/util/typed_enums.h @@ -0,0 +1,8 @@ +#pragma once + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wfixed-enum-extension" +#define enum_t(T) enum : T +#else +#define enum_t(T) enum +#endif diff --git a/src/window/audio.c b/src/window/audio.c index 9791118..a3d633f 100644 --- a/src/window/audio.c +++ b/src/window/audio.c @@ -1,6 +1,11 @@ #include "audio.h" -#include +#include +#include +#include +#include +#include +#include #include "../errors.h" @@ -13,19 +18,19 @@ typedef struct { } AudioCallbackData; // audio callback from SDL_AudioSpec; called when the audio device needs more data -static void audio_mixer(void* userdata, Uint8* stream, int len) { +static void audio_mixer(void* userdata, uint8_t* stream, int32_t len) { memset(stream, 0, len); // clear the playing audio AudioDevice* device = userdata; // get the callback data AudioData* audio = device->playing_audio; - for (int i = 0; i < MAX_SOUNDS; i++) { + for (int32_t i = 0; i < MAX_SOUNDS; i++) { // skip if the audio doesn't conain any further data if (audio[i].length <= 0) { continue; } // get the length of which we shall be mixing - Uint32 mix_length = SDL_min(audio[i].length, len); + uint32_t mix_length = SDL_min(audio[i].length, len); // mix the audio with the stream SDL_MixAudioFormat(stream, audio[i].buffer, device->format, mix_length, SDL_MIX_MAXVOLUME); @@ -35,14 +40,15 @@ static void audio_mixer(void* userdata, Uint8* stream, int len) { } // converts the audio to the format of the audio device -static void convert_audio(const AudioDevice* audio_device, const SDL_AudioSpec wav_spec, Uint8** wav_buffer, Uint32* wav_length) { +static void convert_audio(const AudioDevice* audio_device, const SDL_AudioSpec wav_spec, uint8_t** wav_buffer, uint32_t* wav_length) { // build the audio converter with the audio given SDL_AudioCVT cvt = {0}; SDL_BuildAudioCVT(&cvt, wav_spec.format, wav_spec.channels, wav_spec.freq, audio_device->format, audio_device->channels, audio_device->freq); - cvt.len = (*wav_length) * wav_spec.channels; // the buffer length - cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult); // allocate size for the new buffer - memcpy(cvt.buf, *wav_buffer, *wav_length); // copy wav data to cvt buffer; + // suddenly becomes signed + cvt.len = (*wav_length) * wav_spec.channels; // the buffer length + cvt.buf = (uint8_t*)SDL_malloc(cvt.len * cvt.len_mult); // allocate size for the new buffer + memcpy(cvt.buf, *wav_buffer, *wav_length); // copy wav data to cvt buffer; // convert SDL_ConvertAudio(&cvt); @@ -67,7 +73,7 @@ AudioData audio_load_wav(const AudioDevice* audio_device, const char* file_path) } // initializes the audio device -AudioDevice* audio_device_init(const int freq, const SDL_AudioFormat format, const Uint8 channels, const Uint16 samples) { +AudioDevice* audio_device_init(const int32_t freq, const SDL_AudioFormat format, const uint8_t channels, const Uint16 samples) { // allocate memory for the audio device AudioDevice* audio_device = malloc(sizeof(AudioDevice)); @@ -100,10 +106,9 @@ AudioDevice* audio_device_init(const int freq, const SDL_AudioFormat format, con void audio_play(const AudioDevice* audio_device, const AudioData audio) { AudioData* playing_audio = audio_device->playing_audio; - for (int i = 0; i < MAX_SOUNDS; i++) { + for (int32_t i = 0; i < MAX_SOUNDS; i++) { // overrite audio that has been deallocated if (playing_audio[i].length <= 0) { - // override the audio playing_audio[i] = audio; break; // don't continue. :3 diff --git a/src/window/audio.h b/src/window/audio.h index bd54743..215bf35 100644 --- a/src/window/audio.h +++ b/src/window/audio.h @@ -1,21 +1,23 @@ #pragma once -#include + +#include +#include typedef struct { - Uint32 length; - Uint32 mixed_amount; - Uint8* buffer; + uint32_t length; + uint32_t mixed_amount; + uint8_t* buffer; } AudioData; typedef struct { SDL_AudioDeviceID id; - int freq; + int32_t freq; SDL_AudioFormat format; - Uint8 channels; + uint8_t channels; AudioData* playing_audio; } AudioDevice; AudioData audio_load_wav(const AudioDevice* audio_device, const char* file_path); -AudioDevice* audio_device_init(const int freq, const SDL_AudioFormat format, const Uint8 channels, const Uint16 samples); +AudioDevice* audio_device_init(const int freq, const SDL_AudioFormat format, const uint8_t channels, const uint16_t samples); void audio_play(const AudioDevice* audio_device, const AudioData audio); diff --git a/src/window/colour.h b/src/window/colour.h index dc761e9..3a4c8a7 100644 --- a/src/window/colour.h +++ b/src/window/colour.h @@ -13,27 +13,24 @@ typedef union { } Colour; -#define RED ((uint8_t)0b11000011) -#define YELLOW ((uint8_t)0b11110011) -#define ORANGE ((uint8_t)0b11100011) -#define GREEN ((uint8_t)0b00110011) -#define CYAN ((uint8_t)0b00111111) -#define BLUE ((uint8_t)0b00001111) -#define MAGENTA ((uint8_t)0b11001111) +#define NONE ((uint8_t)0) +#define BLACK ((uint8_t)3) +#define RED ((uint8_t)0xC0 | BLACK) +#define YELLOW ((uint8_t)0xF0 | BLACK) +#define ORANGE ((uint8_t)0xE0 | BLACK) +#define GREEN ((uint8_t)0x30 | BLACK) +#define CYAN ((uint8_t)0x3C | BLACK) +#define BLUE ((uint8_t)0x0C | BLACK) +#define MAGENTA ((uint8_t)0xCC | BLACK) +#define WHITE ((uint8_t)0xFF) -#define NONE ((uint8_t)0) -#define BLACK ((uint8_t)3) -#define WHITE ((uint8_t)0xFF) - - -#define COLOUR_RED ((Colour){RED}) -#define COLOUR_YELLOW ((Colour){YELLOW}) -#define COLOUR_ORANGE ((Colour){ORANGE}) -#define COLOUR_GREEN ((Colour){GREEN}) -#define COLOUR_CYAN ((Colour){CYAN}) -#define COLOUR_BLUE ((Colour){BLUE}) +#define COLOUR_NONE ((Colour){NONE}) +#define COLOUR_BLACK ((Colour){BLACK}) +#define COLOUR_RED ((Colour){RED}) +#define COLOUR_YELLOW ((Colour){YELLOW}) +#define COLOUR_ORANGE ((Colour){ORANGE}) +#define COLOUR_GREEN ((Colour){GREEN}) +#define COLOUR_CYAN ((Colour){CYAN}) +#define COLOUR_BLUE ((Colour){BLUE}) #define COLOUR_MAGENTA ((Colour){MAGENTA}) - -#define COLOUR_NONE ((Colour){NONE}) -#define COLOUR_BLACK ((Colour){BLACK}) -#define COLOUR_WHITE ((Colour){WHITE}) +#define COLOUR_WHITE ((Colour){WHITE}) diff --git a/src/window/renderer.c b/src/window/renderer.c index b10f0f7..31a4112 100644 --- a/src/window/renderer.c +++ b/src/window/renderer.c @@ -1,10 +1,15 @@ // initializes the window and renderer #include "renderer.h" -#include +#include +#include +#include +#include +#include #include #include "../errors.h" +#include "../game/game.h" #include "colour.h" #include "renderer.h" diff --git a/src/window/renderer.h b/src/window/renderer.h index c52e2b1..f6e6fb4 100644 --- a/src/window/renderer.h +++ b/src/window/renderer.h @@ -1,13 +1,14 @@ #pragma once -#include +#include +#include #include #include "../game/game.h" -#define SCREEN_WIDTH 256 +#define SCREEN_WIDTH 256 #define SCREEN_HEIGHT (SCREEN_WIDTH * 2) -#define BLOCK_WIDTH (SCREEN_WIDTH / COLUMNS) -#define BLOCK_HEIGHT (SCREEN_HEIGHT / ROWS) +#define BLOCK_WIDTH (SCREEN_WIDTH / COLUMNS) +#define BLOCK_HEIGHT (SCREEN_HEIGHT / ROWS) typedef struct { SDL_Window* window;