mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 14:05:45 +01:00
code cleanup:
- rename typedefs to a lowercase variant - change variable names to shorter variants
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define MAX_STR_LEN 128
|
#define MAX_STR_LEN 128
|
||||||
|
|
||||||
void error(ErrorCode const error_code, char const* const format, ...) {
|
void error(error_code const error_code, char const* const format, ...) {
|
||||||
char buffer[MAX_STR_LEN] = {0}; // contains the buffer of the final string
|
char buffer[MAX_STR_LEN] = {0}; // contains the buffer of the final string
|
||||||
|
|
||||||
va_list args = {0};
|
va_list args = {0};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef unsigned char ErrorCode;
|
typedef unsigned char error_code;
|
||||||
enum {
|
enum {
|
||||||
ERROR_MISC = -1,
|
ERROR_MISC = -1,
|
||||||
|
|
||||||
@@ -26,5 +26,5 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// call when a fatal error has occurred, the program will immediately terminate when called
|
// call when a fatal error has occurred, the program will immediately terminate when called
|
||||||
void error(ErrorCode error_code, char const* format, ...);
|
void error(error_code error_code, char const* format, ...);
|
||||||
void warn(char const* format, ...);
|
void warn(char const* format, ...);
|
||||||
|
|||||||
@@ -16,39 +16,39 @@
|
|||||||
|
|
||||||
|
|
||||||
// shuffle the array using a Fisher–Yates shuffle
|
// shuffle the array using a Fisher–Yates shuffle
|
||||||
static inline void shuffle(uint8_t const size, ShapeId* const elmnts) {
|
static inline void shuffle(uint8_t const size, shape_id* const elmnts) {
|
||||||
for (uint8_t i = 0; i < (size - 1); i++) {
|
for (uint8_t i = 0; i < (size - 1); i++) {
|
||||||
uint8_t const j = i + rand() % (size - i);
|
uint8_t const j = i + rand() % (size - i);
|
||||||
ShapeId const cache = elmnts[i];
|
shape_id const cache = elmnts[i];
|
||||||
elmnts[i] = elmnts[j];
|
elmnts[i] = elmnts[j];
|
||||||
elmnts[j] = cache;
|
elmnts[j] = cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void next_shape(GameData* const game_data) {
|
void next_shape(game_data* const dat) {
|
||||||
game_data->curr_idx++; // increase the current shape index
|
dat->curr_idx++; // increase the current shape index
|
||||||
game_data->sel_x = COLUMNS / 2 - SHAPE_WIDTH / 2; // move the shape position to the centre
|
dat->sel_x = COLUMNS / 2 - SHAPE_WIDTH / 2; // move the shape position to the centre
|
||||||
game_data->sel_y = 0;
|
dat->sel_y = 0;
|
||||||
|
|
||||||
// return if know which shape is next
|
// return if know which shape is next
|
||||||
if (game_data->curr_idx < (TETROMINO_COUNT - 1))
|
if (dat->curr_idx < (TETROMINO_COUNT - 1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
game_data->curr_idx = 0;
|
dat->curr_idx = 0;
|
||||||
|
|
||||||
shuffle(TETROMINO_COUNT - 1, game_data->nxt);
|
shuffle(TETROMINO_COUNT - 1, dat->nxt);
|
||||||
ShapeId cache = game_data->nxt[0];
|
shape_id cache = dat->nxt[0];
|
||||||
game_data->nxt[0] = game_data->nxt[TETROMINO_COUNT - 1];
|
dat->nxt[0] = dat->nxt[TETROMINO_COUNT - 1];
|
||||||
game_data->nxt[TETROMINO_COUNT - 1] = cache;
|
dat->nxt[TETROMINO_COUNT - 1] = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_init(GameData* const game_data) {
|
void game_init(game_data* const dat) {
|
||||||
// zero-initialize the game data
|
// zero-initialize the game data
|
||||||
*game_data = (GameData){0};
|
*dat = (game_data){0};
|
||||||
|
|
||||||
// allocate size for each row
|
// allocate size for each row
|
||||||
for (int8_t i = 0; i < ROWS; i++) {
|
for (int8_t i = 0; i < ROWS; i++) {
|
||||||
game_data->rows[i] = calloc(COLUMNS, sizeof(colour8));
|
dat->rows[i] = calloc(COLUMNS, sizeof(colour8));
|
||||||
// game_data->rows[i][0] = (colour8){(uint8_t)((((i + 1) ^ ((i + 1) >> 3)) * 0x27) & 0xFF)}; // for debugging rows
|
// game_data->rows[i][0] = (colour8){(uint8_t)((((i + 1) ^ ((i + 1) >> 3)) * 0x27) & 0xFF)}; // for debugging rows
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,21 +56,21 @@ void game_init(GameData* const game_data) {
|
|||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
// set the shape data in each slot to it's corrsponding ID
|
// set the shape data in each slot to it's corrsponding ID
|
||||||
for (ShapeId i = 0; i < TETROMINO_COUNT; i++)
|
for (shape_id i = 0; i < TETROMINO_COUNT; i++)
|
||||||
game_data->nxt[i] = i;
|
dat->nxt[i] = i;
|
||||||
|
|
||||||
game_data->curr_idx = -1; // set the current index to the max so it becomes zero after increasement
|
dat->curr_idx = -1; // set the current index to the max so it becomes zero after increasement
|
||||||
next_shape(game_data); // select the next shape (shuffle should not be triggered)
|
next_shape(dat); // select the next shape (shuffle should not be triggered)
|
||||||
shuffle(TETROMINO_COUNT, game_data->nxt); // manually trigger a shuffle
|
shuffle(TETROMINO_COUNT, dat->nxt); // manually trigger a shuffle
|
||||||
|
|
||||||
// initialize audio
|
// initialize audio
|
||||||
game_data->audio_device = audio_device_init(32000, AUDIO_S16, 1, 4096);
|
dat->audio_device = audio_device_init(32000, AUDIO_S16, 1, 4096);
|
||||||
game_data->music = audio_load_wav(game_data->audio_device, "korobeiniki.wav");
|
dat->music = audio_load_wav(dat->audio_device, "korobeiniki.wav");
|
||||||
audio_play(game_data->audio_device, game_data->music);
|
audio_play(dat->audio_device, dat->music);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called every time the game's state is updated
|
// called every time the game's state is updated
|
||||||
void game_update(GameData* const game_data, uint8_t const* const keys) {
|
void game_update(game_data* const dat, uint8_t const* const keys) {
|
||||||
if (keys[SDL_SCANCODE_ESCAPE])
|
if (keys[SDL_SCANCODE_ESCAPE])
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
@@ -80,10 +80,10 @@ void game_update(GameData* const game_data, uint8_t const* const keys) {
|
|||||||
if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_SPACE]) move |= MOVE_DOWN;
|
if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_SPACE]) move |= MOVE_DOWN;
|
||||||
if (keys[SDL_SCANCODE_Q]) move |= MOVE_ROTLEFT;
|
if (keys[SDL_SCANCODE_Q]) move |= MOVE_ROTLEFT;
|
||||||
if (keys[SDL_SCANCODE_E]) move |= MOVE_ROTRIGHT;
|
if (keys[SDL_SCANCODE_E]) move |= MOVE_ROTRIGHT;
|
||||||
place_update(game_data, move);
|
place_update(dat, move);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_free(GameData* const game_data) {
|
void game_free(game_data* const game_data) {
|
||||||
// clear each row
|
// clear each row
|
||||||
for (int8_t i = 0; i < ROWS; i++) {
|
for (int8_t i = 0; i < ROWS; i++) {
|
||||||
free(game_data->rows[i]);
|
free(game_data->rows[i]);
|
||||||
|
|||||||
@@ -10,21 +10,21 @@
|
|||||||
#define COLUMNS ((int8_t)10)
|
#define COLUMNS ((int8_t)10)
|
||||||
#define ROWS ((int8_t)24)
|
#define ROWS ((int8_t)24)
|
||||||
|
|
||||||
typedef const colour8* const CRow;
|
typedef colour8 const* const row_const;
|
||||||
typedef colour8* Row;
|
typedef colour8* row;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Row rows[ROWS];
|
row rows[ROWS];
|
||||||
AudioDevice const* audio_device;
|
audio_device const* audio_device;
|
||||||
AudioData music;
|
audio_data music;
|
||||||
uint16_t score;
|
uint16_t score;
|
||||||
ShapeId nxt[7]; // the order of the shape ids that they should appear in
|
shape_id nxt[7]; // the order of the shape ids that they should appear in
|
||||||
uint8_t curr_idx; // current shape index
|
uint8_t curr_idx; // current shape index
|
||||||
int8_t sel_x; // selected shape x position
|
int8_t sel_x; // selected shape x position
|
||||||
int8_t sel_y; // selected shape y position
|
int8_t sel_y; // selected shape y position
|
||||||
} GameData;
|
} game_data;
|
||||||
|
|
||||||
void next_shape(GameData* game_data);
|
void next_shape(game_data* dat);
|
||||||
void game_init(GameData* game_data); // initializes the game
|
void game_init(game_data* dat); // initializes the game
|
||||||
void game_update(GameData* game_data, uint8_t const* keys); // updates the game's state
|
void game_update(game_data* dat, uint8_t const* keys); // updates the game's state
|
||||||
void game_free(GameData* game_data); // free all data stored with the game
|
void game_free(game_data* dat); // free all data stored with the game
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "shapes.h"
|
#include "shapes.h"
|
||||||
|
|
||||||
|
|
||||||
static bool is_filled(CRow const row) {
|
static bool is_filled(row_const const row) {
|
||||||
for (int8_t x = 0; x < COLUMNS; x++) {
|
for (int8_t x = 0; x < COLUMNS; x++) {
|
||||||
if (row[x].packed == 0) {
|
if (row[x].packed == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -17,8 +17,8 @@ static bool is_filled(CRow const row) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_rows(Row* const rows, uint16_t* const score) {
|
static void clear_rows(row* const rows, uint16_t* const score) {
|
||||||
Row cache[4] = {0}; // you can only clear four rows at a time
|
row cache[4] = {0}; // you can only clear four rows at a time
|
||||||
struct {
|
struct {
|
||||||
uint8_t filled : 3; // values will only ever be 0..4
|
uint8_t filled : 3; // values will only ever be 0..4
|
||||||
uint8_t checked : 3; // values will only ever be 0..4
|
uint8_t checked : 3; // values will only ever be 0..4
|
||||||
@@ -57,7 +57,7 @@ static void clear_rows(Row* const rows, uint16_t* const score) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sets a shape to the screen
|
// sets a shape to the screen
|
||||||
static void set_shape_i(Row const* const row, ShapeId const id, int8_t const pos_x) {
|
static void set_shape_i(row const* const row, shape_id const id, int8_t const pos_x) {
|
||||||
Shape const shape = shape_from_id(id);
|
Shape const shape = shape_from_id(id);
|
||||||
colour8 const colour = colour_from_id(id);
|
colour8 const colour = colour_from_id(id);
|
||||||
for (int8_t y = 0; y < SHAPE_HEIGHT; y++) {
|
for (int8_t y = 0; y < SHAPE_HEIGHT; y++) {
|
||||||
@@ -72,11 +72,11 @@ static void set_shape_i(Row const* const row, ShapeId const id, int8_t const pos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_shape(Row const* const row, ShapeId const id, int8_t const pos_x, int8_t const pos_y) {
|
static inline void set_shape(row const* const row, shape_id const id, int8_t const pos_x, int8_t const pos_y) {
|
||||||
set_shape_i(&row[pos_y], id, pos_x); // calls itself, but omitting the pos_y argument, instead opting for specifying the row
|
set_shape_i(&row[pos_y], id, pos_x); // calls itself, but omitting the pos_y argument, instead opting for specifying the row
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shape_intersects(Row const* const rows, ShapeId const id, int8_t const x, int8_t const y) {
|
static bool shape_intersects(row const* const rows, shape_id const id, int8_t const x, int8_t const y) {
|
||||||
Shape const shape = shape_from_id(id);
|
Shape const shape = shape_from_id(id);
|
||||||
|
|
||||||
for (int8_t y0 = 0; y0 < SHAPE_HEIGHT; y0++) {
|
for (int8_t y0 = 0; y0 < SHAPE_HEIGHT; y0++) {
|
||||||
@@ -96,14 +96,14 @@ static bool shape_intersects(Row const* const rows, ShapeId const id, int8_t con
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ShapeId rotate_id(ShapeId const id, int const dir) {
|
static inline shape_id rotate_id(shape_id const id, int const dir) {
|
||||||
return (id + dir) & 31;
|
return (id + dir) & 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
void place_update(GameData* const game_data, InputData const move) {
|
void place_update(game_data* const game_data, InputData const move) {
|
||||||
// store the current index and ID, only changes when placed (which yields no movement) and rotation (which occurs last)
|
// store the current index and ID, only changes when placed (which yields no movement) and rotation (which occurs last)
|
||||||
uint8_t const curr_idx = game_data->curr_idx;
|
uint8_t const curr_idx = game_data->curr_idx;
|
||||||
ShapeId const curr_id = game_data->nxt[curr_idx];
|
shape_id const curr_id = game_data->nxt[curr_idx];
|
||||||
|
|
||||||
|
|
||||||
// set the shape if we moved vertically and intersected
|
// set the shape if we moved vertically and intersected
|
||||||
@@ -131,7 +131,7 @@ void place_update(GameData* const game_data, InputData const move) {
|
|||||||
|
|
||||||
// update the shape's rotation
|
// update the shape's rotation
|
||||||
if (move & 8 || move & 16) {
|
if (move & 8 || move & 16) {
|
||||||
ShapeId const id = move & 8 // check which direction we should move
|
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) {
|
if (shape_intersects(game_data->rows, id, game_data->sel_x, game_data->sel_y) == false) {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ enum {
|
|||||||
MOVE_ROTRIGHT = 16,
|
MOVE_ROTRIGHT = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
void place_update(GameData* game_data, InputData move);
|
void place_update(game_data* game_data, InputData move);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void dbg_set_all(GameData* game_data);
|
void dbg_set_all(game_data* game_data);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#define SHAPE_J_180 ((Shape)0x6440) // 0110 0100 0100 0000 the J tetromino with a 180° rotation
|
#define SHAPE_J_180 ((Shape)0x6440) // 0110 0100 0100 0000 the J tetromino with a 180° rotation
|
||||||
#define SHAPE_J_270 ((Shape)0x0E20) // 0000 1110 0010 0000 the J tetromino with a 270° rotation
|
#define SHAPE_J_270 ((Shape)0x0E20) // 0000 1110 0010 0000 the J tetromino with a 270° rotation
|
||||||
|
|
||||||
Shape shape_from_id(ShapeId const id) {
|
Shape shape_from_id(shape_id const id) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static Shape const shapes[TETROMINO_COUNT][4] = {
|
static Shape const shapes[TETROMINO_COUNT][4] = {
|
||||||
// 0° 90° 180° 170°
|
// 0° 90° 180° 170°
|
||||||
@@ -53,7 +53,7 @@ Shape shape_from_id(ShapeId const id) {
|
|||||||
return shapes[id & 7][id >> 3];
|
return shapes[id & 7][id >> 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
colour8 colour_from_id(ShapeId const id) {
|
colour8 colour_from_id(shape_id const id) {
|
||||||
switch (id & 7) {
|
switch (id & 7) {
|
||||||
case TETROMINO_O: return COLOUR_YELLOW;
|
case TETROMINO_O: return COLOUR_YELLOW;
|
||||||
case TETROMINO_I: return COLOUR_CYAN;
|
case TETROMINO_I: return COLOUR_CYAN;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
typedef uint16_t Shape;
|
typedef uint16_t Shape;
|
||||||
typedef uint8_t ShapeRow;
|
typedef uint8_t ShapeRow;
|
||||||
|
|
||||||
typedef uint8_t ShapeId;
|
typedef uint8_t shape_id;
|
||||||
enum {
|
enum {
|
||||||
TETROMINO_O = 0,
|
TETROMINO_O = 0,
|
||||||
TETROMINO_I = 1,
|
TETROMINO_I = 1,
|
||||||
@@ -35,5 +35,5 @@ static inline bool is_set(ShapeRow const row, uint8_t const index) {
|
|||||||
return (row >> ((SHAPE_WIDTH - 1) - index) & 1) != 0;
|
return (row >> ((SHAPE_WIDTH - 1) - index) & 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape shape_from_id(ShapeId id);
|
Shape shape_from_id(shape_id id);
|
||||||
colour8 colour_from_id(ShapeId id);
|
colour8 colour_from_id(shape_id id);
|
||||||
|
|||||||
14
src/main.c
14
src/main.c
@@ -23,8 +23,8 @@
|
|||||||
|
|
||||||
bool playing = true;
|
bool playing = true;
|
||||||
|
|
||||||
RenderData render_data = {0};
|
RenderData render_dat = {0};
|
||||||
GameData game_data = {0};
|
game_data game_dat = {0};
|
||||||
|
|
||||||
|
|
||||||
// handles game application initialisation
|
// handles game application initialisation
|
||||||
@@ -36,8 +36,8 @@ static void init(void) {
|
|||||||
error(ERROR_SDL_FONT_INIT, "the TTF module of SDL could not initialize! TTF Error: %s", TTF_GetError());
|
error(ERROR_SDL_FONT_INIT, "the TTF module of SDL could not initialize! TTF Error: %s", TTF_GetError());
|
||||||
|
|
||||||
// initialize units
|
// initialize units
|
||||||
game_init(&game_data);
|
game_init(&game_dat);
|
||||||
renderer_init(&render_data, &game_data);
|
renderer_init(&render_dat, &game_dat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles game application updating
|
// handles game application updating
|
||||||
@@ -55,8 +55,8 @@ static void update(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// preform updates
|
// preform updates
|
||||||
game_update(&game_data, SDL_GetKeyboardState(NULL));
|
game_update(&game_dat, SDL_GetKeyboardState(NULL));
|
||||||
renderer_update(&render_data);
|
renderer_update(&render_dat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles game application quitting
|
// handles game application quitting
|
||||||
@@ -77,7 +77,7 @@ int main(int const argc, char const* const* const argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cleanup of resources
|
// cleanup of resources
|
||||||
game_free(&game_data);
|
game_free(&game_dat);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -13,37 +13,37 @@
|
|||||||
#define MAX_SOUNDS 64
|
#define MAX_SOUNDS 64
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AudioData const* const playing_audio;
|
audio_data const* const playing_audio;
|
||||||
AudioDevice const audio_device;
|
audio_device const audio_device;
|
||||||
} AudioCallbackData;
|
} AudioCallbackData;
|
||||||
|
|
||||||
// audio callback from SDL_AudioSpec; called when the audio device needs more data
|
// audio callback from SDL_AudioSpec; called when the audio device needs more data
|
||||||
static void audio_mixer(void* const userdata, uint8_t* const stream, int32_t const len) {
|
static void audio_mixer(void* const userdata, uint8_t* const stream, int32_t const len) {
|
||||||
memset(stream, 0, len); // clear the playing audio
|
memset(stream, 0, len); // clear the playing audio
|
||||||
AudioDevice const* const device = userdata; // get the callback data
|
audio_device const* const device = userdata; // get the callback data
|
||||||
AudioData* const audio = device->playing_audio;
|
audio_data* const audio = device->playing_audio;
|
||||||
|
|
||||||
for (int32_t 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
|
// skip if the audio doesn't conain any further data
|
||||||
if (audio[i].length <= 0) {
|
if (audio[i].len <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the length of which we shall be mixing
|
// get the length of which we shall be mixing
|
||||||
uint32_t const mix_length = SDL_min(audio[i].length, (uint32_t)len);
|
uint32_t const mix_length = SDL_min(audio[i].len, (uint32_t)len);
|
||||||
|
|
||||||
// mix the audio with the stream
|
// mix the audio with the stream
|
||||||
SDL_MixAudioFormat(stream, audio[i].buffer, device->format, mix_length, SDL_MIX_MAXVOLUME);
|
SDL_MixAudioFormat(stream, audio[i].buf, device->fmt, mix_length, SDL_MIX_MAXVOLUME);
|
||||||
audio[i].buffer += mix_length; // move the pointer up a a bit
|
audio[i].buf += mix_length; // move the pointer up a a bit
|
||||||
audio[i].length -= mix_length; // move up the mixed amount
|
audio[i].len -= mix_length; // move up the mixed amount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts the audio to the format of the audio device
|
// converts the audio to the format of the audio device
|
||||||
static void convert_audio(AudioDevice const* const audio_device, SDL_AudioSpec const wav_spec, uint8_t* const* const wav_buffer, uint32_t* const wav_length) {
|
static void convert_audio(audio_device const* const audio_device, SDL_AudioSpec const wav_spec, uint8_t* const* const wav_buffer, uint32_t* const wav_length) {
|
||||||
// build the audio converter with the audio given
|
// build the audio converter with the audio given
|
||||||
SDL_AudioCVT cvt = {0};
|
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);
|
SDL_BuildAudioCVT(&cvt, wav_spec.format, wav_spec.channels, wav_spec.freq, audio_device->fmt, audio_device->channels, audio_device->freq);
|
||||||
|
|
||||||
// suddenly becomes signed
|
// suddenly becomes signed
|
||||||
cvt.len = (*wav_length) * wav_spec.channels; // the buffer length
|
cvt.len = (*wav_length) * wav_spec.channels; // the buffer length
|
||||||
@@ -61,54 +61,54 @@ static void convert_audio(AudioDevice const* const audio_device, SDL_AudioSpec c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loads a WAV file and returns the relevant information
|
// loads a WAV file and returns the relevant information
|
||||||
AudioData audio_load_wav(AudioDevice const* const audio_device, char const* const file_path) {
|
audio_data audio_load_wav(audio_device const* const dev, char const* const fpath) {
|
||||||
SDL_AudioSpec wav_spec = {0};
|
SDL_AudioSpec wav_spec = {0};
|
||||||
AudioData audio = {0};
|
audio_data audio = {0};
|
||||||
|
|
||||||
SDL_LoadWAV(file_path, &wav_spec, &audio.buffer, &audio.length);
|
SDL_LoadWAV(fpath, &wav_spec, &audio.buf, &audio.len);
|
||||||
convert_audio(audio_device, wav_spec, &audio.buffer, &audio.length);
|
convert_audio(dev, wav_spec, &audio.buf, &audio.len);
|
||||||
audio.mixed_amount = audio.length;
|
audio.mix_amt = audio.len;
|
||||||
|
|
||||||
return audio;
|
return audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializes the audio device
|
// initializes the audio device
|
||||||
AudioDevice const* audio_device_init(int32_t const freq, SDL_AudioFormat const format, uint8_t const channels, Uint16 const samples) {
|
audio_device const* audio_device_init(int32_t const freq, SDL_AudioFormat const fmt, uint8_t const channels, uint16_t const samples) {
|
||||||
// allocate memory for the audio device
|
// allocate memory for the audio device
|
||||||
AudioDevice* const audio_device = malloc(sizeof(AudioDevice));
|
audio_device* const dev = malloc(sizeof(audio_device));
|
||||||
|
|
||||||
// define the audio specification
|
// define the audio specification
|
||||||
SDL_AudioSpec spec = {freq, format, channels, 0, samples, 0, 0, NULL, NULL};
|
SDL_AudioSpec spec = {freq, fmt, channels, 0, samples, 0, 0, NULL, NULL};
|
||||||
spec.callback = audio_mixer;
|
spec.callback = audio_mixer;
|
||||||
spec.userdata = audio_device;
|
spec.userdata = dev;
|
||||||
|
|
||||||
// create the audio device
|
// create the audio device
|
||||||
*audio_device = (AudioDevice){
|
*dev = (audio_device){
|
||||||
|
calloc(MAX_SOUNDS, sizeof(audio_data)), // allocate memory on the heap for the playing audio array
|
||||||
SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0),
|
SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0),
|
||||||
freq,
|
freq,
|
||||||
format,
|
fmt,
|
||||||
channels,
|
channels,
|
||||||
calloc(MAX_SOUNDS, sizeof(AudioData)), // allocate memory on the heap for the playing audio array
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// if the audio device isn't set, cause an error
|
// if the audio device isn't set, cause an error
|
||||||
if (audio_device->id < 1) {
|
if (dev->id < 1) {
|
||||||
error(ERROR_SDL_AUDIO_INIT, "AudioDivice failed to open! SDL Error: %s", SDL_GetError());
|
error(ERROR_SDL_AUDIO_INIT, "AudioDivice failed to open! SDL Error: %s", SDL_GetError());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default state of the device is paused, so we unpause it here
|
// default state of the device is paused, so we unpause it here
|
||||||
SDL_PauseAudioDevice(audio_device->id, 0);
|
SDL_PauseAudioDevice(dev->id, 0);
|
||||||
return audio_device;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// plays the audio
|
// plays the audio
|
||||||
void audio_play(AudioDevice const* const audio_device, AudioData const audio) {
|
void audio_play(audio_device const* const dev, audio_data const audio) {
|
||||||
AudioData* const playing_audio = audio_device->playing_audio;
|
audio_data* const playing_audio = dev->playing_audio;
|
||||||
|
|
||||||
for (int32_t i = 0; i < MAX_SOUNDS; i++) {
|
for (int32_t i = 0; i < MAX_SOUNDS; i++) {
|
||||||
// overrite audio that has been deallocated
|
// overrite audio that has been deallocated
|
||||||
if (playing_audio[i].length <= 0) {
|
if (playing_audio[i].len <= 0) {
|
||||||
// override the audio
|
// override the audio
|
||||||
playing_audio[i] = audio;
|
playing_audio[i] = audio;
|
||||||
break; // don't continue. :3
|
break; // don't continue. :3
|
||||||
|
|||||||
@@ -4,20 +4,21 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t length;
|
uint32_t len;
|
||||||
uint32_t mixed_amount;
|
uint32_t mix_amt;
|
||||||
uint8_t* buffer;
|
uint8_t* buf;
|
||||||
} AudioData;
|
} audio_data;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
audio_data* playing_audio;
|
||||||
SDL_AudioDeviceID id;
|
SDL_AudioDeviceID id;
|
||||||
int32_t freq;
|
int32_t freq;
|
||||||
SDL_AudioFormat format;
|
SDL_AudioFormat fmt;
|
||||||
uint8_t channels;
|
uint8_t channels;
|
||||||
AudioData* playing_audio;
|
} audio_device;
|
||||||
} AudioDevice;
|
|
||||||
|
|
||||||
|
|
||||||
AudioData audio_load_wav(AudioDevice const* audio_device, char const* file_path);
|
audio_data audio_load_wav(audio_device const* audio_device, char const* file_path);
|
||||||
AudioDevice const* audio_device_init(int freq, SDL_AudioFormat format, uint8_t channels, uint16_t samples);
|
audio_device const* audio_device_init(int freq, SDL_AudioFormat format, uint8_t channels, uint16_t samples);
|
||||||
void audio_play(AudioDevice const* audio_device, AudioData const audio);
|
void audio_play(audio_device const* audio_device, audio_data const audio);
|
||||||
|
void audio_device_free(audio_device const* dev); // TODO: implement this
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ typedef union {
|
|||||||
uint8_t r : 3;
|
uint8_t r : 3;
|
||||||
};
|
};
|
||||||
} colour8;
|
} colour8;
|
||||||
|
#define color8 colour8
|
||||||
|
|
||||||
/* rrrg ggbb */
|
/* rrrg ggbb */
|
||||||
#define COLOUR_BLACK ((colour8){0x00}) // 0000 0000
|
#define COLOUR_BLACK ((colour8){0x00}) // 0000 0000
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#define COLOUR_SCORE COLOUR_YELLOW
|
#define COLOUR_SCORE COLOUR_YELLOW
|
||||||
|
|
||||||
void renderer_init(RenderData* const render_data, GameData const* const game_data) {
|
void renderer_init(RenderData* const render_dat, game_data 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);
|
SDL_Window* const window = SDL_CreateWindow("tetris clone", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||||
if (window == NULL) error(ERROR_SDL_RENDERER_INIT, "Window failed to be created! SDL Error: %s", SDL_GetError());
|
if (window == NULL) error(ERROR_SDL_RENDERER_INIT, "Window failed to be created! SDL Error: %s", SDL_GetError());
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ void renderer_init(RenderData* const render_data, GameData const* const game_dat
|
|||||||
if (font == NULL) error(ERROR_SDL_FONT_INIT, "Failed to open font! TTF Error: %s", TTF_GetError());
|
if (font == NULL) error(ERROR_SDL_FONT_INIT, "Failed to open font! TTF Error: %s", TTF_GetError());
|
||||||
|
|
||||||
// initialize the render data
|
// initialize the render data
|
||||||
*render_data = (RenderData){
|
*render_dat = (RenderData){
|
||||||
game_data,
|
game_dat,
|
||||||
window,
|
window,
|
||||||
renderer,
|
renderer,
|
||||||
font};
|
font};
|
||||||
@@ -74,7 +74,7 @@ static inline void set_colour(SDL_Renderer* const renderer, colour8 const c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draws a shape at the specified position
|
// draws a shape at the specified position
|
||||||
static void draw_shape(SDL_Renderer* const renderer, ShapeId const id, int8_t const pos_x, int8_t const pos_y) {
|
static void draw_shape(SDL_Renderer* const renderer, shape_id const id, int8_t const pos_x, int8_t const pos_y) {
|
||||||
Shape const shape = shape_from_id(id);
|
Shape const shape = shape_from_id(id);
|
||||||
set_colour(renderer, colour_from_id(id));
|
set_colour(renderer, colour_from_id(id));
|
||||||
|
|
||||||
@@ -91,9 +91,9 @@ static void draw_shape(SDL_Renderer* const renderer, ShapeId const id, int8_t co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draw the block data in the level
|
// draw the block data in the level
|
||||||
static void render_level(SDL_Renderer* const renderer, GameData const* const data) {
|
static void render_level(SDL_Renderer* const renderer, game_data const* const data) {
|
||||||
for (int8_t y = 0; y < ROWS; y++) {
|
for (int8_t y = 0; y < ROWS; y++) {
|
||||||
CRow const row = data->rows[y];
|
row_const const row = data->rows[y];
|
||||||
|
|
||||||
for (int8_t x = 0; x < COLUMNS; x++) {
|
for (int8_t x = 0; x < COLUMNS; x++) {
|
||||||
if (row[x].packed != 0) {
|
if (row[x].packed != 0) {
|
||||||
@@ -104,9 +104,9 @@ static void render_level(SDL_Renderer* const renderer, GameData const* const dat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_update(RenderData const* const render_data) {
|
void renderer_update(RenderData const* const dat) {
|
||||||
SDL_Renderer* const renderer = render_data->renderer;
|
SDL_Renderer* const renderer = dat->renderer;
|
||||||
GameData const* const game_data = render_data->game_data;
|
game_data const* const game_data = dat->game_dat;
|
||||||
|
|
||||||
|
|
||||||
int success = 0; // if an error occurs, this value is <0
|
int success = 0; // if an error occurs, this value is <0
|
||||||
@@ -121,9 +121,9 @@ void renderer_update(RenderData const* const render_data) {
|
|||||||
SDL_RenderDrawRect(renderer, &field_size);
|
SDL_RenderDrawRect(renderer, &field_size);
|
||||||
draw_shape(renderer, game_data->nxt[game_data->curr_idx + 1], COLUMNS + 1, 3); // draw the next shape
|
draw_shape(renderer, game_data->nxt[game_data->curr_idx + 1], COLUMNS + 1, 3); // draw the next shape
|
||||||
|
|
||||||
draw_score_text(renderer, render_data->font, render_data->game_data->score);
|
draw_score_text(renderer, dat->font, dat->game_dat->score);
|
||||||
|
|
||||||
render_level(renderer, render_data->game_data);
|
render_level(renderer, dat->game_dat);
|
||||||
draw_shape(renderer, game_data->nxt[game_data->curr_idx], game_data->sel_x, game_data->sel_y); // draw the current shape
|
draw_shape(renderer, game_data->nxt[game_data->curr_idx], game_data->sel_x, game_data->sel_y); // draw the current shape
|
||||||
|
|
||||||
if (success < 0) {
|
if (success < 0) {
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
#define BLOCK_HEIGHT (TET_HEIGHT / ROWS) // height of a block
|
#define BLOCK_HEIGHT (TET_HEIGHT / ROWS) // height of a block
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GameData const* game_data;
|
game_data const* game_dat;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
TTF_Font* font;
|
TTF_Font* font;
|
||||||
} RenderData;
|
} RenderData;
|
||||||
|
|
||||||
void renderer_init(RenderData* render_data, GameData const* game_data);
|
void renderer_init(RenderData* render_dat, game_data const* game_dat);
|
||||||
void renderer_update(RenderData const* render_data);
|
void renderer_update(RenderData const* dat);
|
||||||
void renderer_free(RenderData* render_data);
|
void renderer_free(RenderData* dat);
|
||||||
|
|||||||
Reference in New Issue
Block a user