Refactor texture code + start splitting networking into threads.
This commit is contained in:
parent
759a99edcf
commit
1d30dba681
116
main.c
116
main.c
@ -2,6 +2,9 @@
|
|||||||
#include <SDL2/SDL_ttf.h>
|
#include <SDL2/SDL_ttf.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
@ -9,15 +12,18 @@
|
|||||||
|
|
||||||
#define SCREEN_WIDTH 640
|
#define SCREEN_WIDTH 640
|
||||||
#define SCREEN_HEIGHT 480
|
#define SCREEN_HEIGHT 480
|
||||||
|
#define TEXT_LINES 20
|
||||||
|
#define BODY_TEXT_LINES TEXT_LINES-2
|
||||||
|
#define FONT_SIZE SCREEN_HEIGHT/TEXT_LINES
|
||||||
|
|
||||||
#define PORT 55555
|
#define PORT 55555
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
SOCKET_LISTEN,
|
||||||
SELECTING_DEVICE,
|
SELECTING_DEVICE,
|
||||||
RECORDING,
|
RECORDING,
|
||||||
RECORDED,
|
RECORDED,
|
||||||
PLAYBACK,
|
PLAYBACK,
|
||||||
SOCKET,
|
|
||||||
} application_state;
|
} application_state;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -25,6 +31,7 @@ typedef struct {
|
|||||||
audio_state audio;
|
audio_state audio;
|
||||||
int device_index;
|
int device_index;
|
||||||
int update_ui;
|
int update_ui;
|
||||||
|
sem_t sem;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
int init();
|
int init();
|
||||||
@ -32,6 +39,8 @@ void destroy();
|
|||||||
int select_device(SDL_KeyboardEvent* key_event, int max_index);
|
int select_device(SDL_KeyboardEvent* key_event, int max_index);
|
||||||
void application_state_to_string(application_state state, char* string);
|
void application_state_to_string(application_state state, char* string);
|
||||||
|
|
||||||
|
void* peer_discovery_t(void* args);
|
||||||
|
|
||||||
SDL_Window* window = NULL;
|
SDL_Window* window = NULL;
|
||||||
SDL_Renderer* renderer = NULL;
|
SDL_Renderer* renderer = NULL;
|
||||||
|
|
||||||
@ -39,6 +48,7 @@ int num_devices = 0;
|
|||||||
|
|
||||||
int handle_input(SDL_Event* event, state* state);
|
int handle_input(SDL_Event* event, state* state);
|
||||||
void handle_task(state* state);
|
void handle_task(state* state);
|
||||||
|
void render_body_text(text_texture* textures, int len);
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (!init()) return 1;
|
if (!init()) return 1;
|
||||||
@ -46,33 +56,43 @@ int main(int argc, char* argv[])
|
|||||||
num_devices = SDL_GetNumAudioDevices(1);
|
num_devices = SDL_GetNumAudioDevices(1);
|
||||||
log_message(LOG_INFO, "Num audio devices: %i", num_devices);
|
log_message(LOG_INFO, "Num audio devices: %i", num_devices);
|
||||||
char char_buffer[64];
|
char char_buffer[64];
|
||||||
char default_fmt[] = "Device selected: %i";
|
char device_selected_fmt[] = "Device selected: %i";
|
||||||
|
|
||||||
state state;
|
state state;
|
||||||
state.application_state = SOCKET;
|
//state.application_state = SOCKET_LISTEN;
|
||||||
|
state.application_state = SELECTING_DEVICE;
|
||||||
if (!audio_init(&state.audio)) return 1;
|
if (!audio_init(&state.audio)) return 1;
|
||||||
state.device_index = -1;
|
state.device_index = -1;
|
||||||
state.update_ui = 0;
|
state.update_ui = 0;
|
||||||
|
sem_init(&state.sem, 0, 1);
|
||||||
|
|
||||||
text_texture display_text_texture;
|
text_texture display_text_texture;
|
||||||
text_texture_init(&display_text_texture, renderer);
|
text_texture_init(&display_text_texture, renderer, FONT_SIZE);
|
||||||
sprintf(char_buffer, default_fmt, state.device_index);
|
sprintf(char_buffer, device_selected_fmt, state.device_index);
|
||||||
text_texture_load(&display_text_texture, char_buffer);
|
text_texture_load(&display_text_texture, char_buffer);
|
||||||
|
|
||||||
text_texture device_textures[num_devices];
|
|
||||||
for (int i = 0; i < num_devices; i++) {
|
|
||||||
text_texture_init(&device_textures[i], renderer);
|
|
||||||
sprintf(char_buffer, "%i: %s", i, SDL_GetAudioDeviceName(i, 1));
|
|
||||||
text_texture_load(&device_textures[i], char_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
text_texture state_text_texture;
|
text_texture state_text_texture;
|
||||||
text_texture_init(&state_text_texture, renderer);
|
text_texture_init(&state_text_texture, renderer, FONT_SIZE);
|
||||||
application_state_to_string(state.application_state, char_buffer);
|
application_state_to_string(state.application_state, char_buffer);
|
||||||
text_texture_load(&state_text_texture, char_buffer);
|
text_texture_load(&state_text_texture, char_buffer);
|
||||||
|
|
||||||
|
text_texture_frame socket_frame;
|
||||||
|
text_texture_frame_init(&socket_frame, BODY_TEXT_LINES, renderer, FONT_SIZE);
|
||||||
|
|
||||||
|
text_texture_frame select_device_frame;
|
||||||
|
text_texture_frame_init(&select_device_frame, num_devices, renderer, FONT_SIZE);
|
||||||
|
|
||||||
|
for (int i = 0; i < select_device_frame.len; i++) {
|
||||||
|
sprintf(char_buffer, "%i: %s", i, SDL_GetAudioDeviceName(i, 1));
|
||||||
|
text_texture_load(&select_device_frame.textures[i], char_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t peer_discovery_thread;
|
||||||
|
pthread_create(&peer_discovery_thread, NULL, peer_discovery_t, &state);
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
sem_wait(&state.sem);
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
SDL_Keycode keysym = event.key.keysym.sym;
|
SDL_Keycode keysym = event.key.keysym.sym;
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@ -91,7 +111,7 @@ int main(int argc, char* argv[])
|
|||||||
handle_task(&state);
|
handle_task(&state);
|
||||||
|
|
||||||
if (state.update_ui) {
|
if (state.update_ui) {
|
||||||
sprintf(char_buffer, default_fmt, state.device_index);
|
sprintf(char_buffer, device_selected_fmt, state.device_index);
|
||||||
text_texture_load(&display_text_texture, char_buffer);
|
text_texture_load(&display_text_texture, char_buffer);
|
||||||
application_state_to_string(state.application_state, char_buffer);
|
application_state_to_string(state.application_state, char_buffer);
|
||||||
text_texture_load(&state_text_texture, char_buffer);
|
text_texture_load(&state_text_texture, char_buffer);
|
||||||
@ -106,29 +126,29 @@ int main(int argc, char* argv[])
|
|||||||
// Render
|
// Render
|
||||||
text_texture_render(&display_text_texture, 0, 0);
|
text_texture_render(&display_text_texture, 0, 0);
|
||||||
|
|
||||||
|
if (state.application_state == SOCKET_LISTEN) {
|
||||||
|
text_texture_frame_render(&socket_frame, 0, FONT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if (state.application_state == SELECTING_DEVICE) {
|
if (state.application_state == SELECTING_DEVICE) {
|
||||||
int text_y_offset_step = display_text_texture.height * 2;
|
text_texture_frame_render(&select_device_frame, 0, FONT_SIZE);
|
||||||
int text_y_offset = text_y_offset_step;
|
|
||||||
for (int i = 0; i < num_devices; i++) {
|
|
||||||
text_texture_render(&device_textures[i], 0, text_y_offset);
|
|
||||||
text_y_offset += text_y_offset_step;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text_texture_render(&state_text_texture, 0, SCREEN_HEIGHT - state_text_texture.height);
|
text_texture_render(&state_text_texture, 0, SCREEN_HEIGHT - state_text_texture.height);
|
||||||
|
|
||||||
// Update the screen
|
// Update the screen
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
|
sem_post(&state.sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
log_message(LOG_INFO, "Cleanup start");
|
log_message(LOG_INFO, "Cleanup start");
|
||||||
audio_destroy(&state.audio);
|
audio_destroy(&state.audio);
|
||||||
log_message(LOG_INFO, "Audio done");
|
log_message(LOG_INFO, "Audio done");
|
||||||
text_texture_free(&display_text_texture);
|
text_texture_destroy(&display_text_texture);
|
||||||
for (int i = 0; i < num_devices; i++) {
|
text_texture_destroy(&state_text_texture);
|
||||||
text_texture_free(&device_textures[i]);
|
text_texture_frame_destroy(&socket_frame);
|
||||||
}
|
text_texture_frame_destroy(&select_device_frame);
|
||||||
log_message(LOG_INFO, "Texture done");
|
log_message(LOG_INFO, "Texture done");
|
||||||
destroy();
|
destroy();
|
||||||
log_message(LOG_INFO, "Done");
|
log_message(LOG_INFO, "Done");
|
||||||
@ -140,6 +160,18 @@ int handle_input(SDL_Event* event, state* state)
|
|||||||
SDL_Keycode keysym = event->key.keysym.sym;
|
SDL_Keycode keysym = event->key.keysym.sym;
|
||||||
switch (state->application_state) {
|
switch (state->application_state) {
|
||||||
|
|
||||||
|
case SOCKET_LISTEN:
|
||||||
|
switch (keysym) {
|
||||||
|
case SDLK_1:
|
||||||
|
log_message(LOG_INFO, "Socket button 1 pressed");
|
||||||
|
net_broadcast();
|
||||||
|
break;
|
||||||
|
case SDLK_2:
|
||||||
|
log_message(LOG_INFO, "Socket button 2 pressed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SELECTING_DEVICE:
|
case SELECTING_DEVICE:
|
||||||
switch (keysym) {
|
switch (keysym) {
|
||||||
case SDLK_y:
|
case SDLK_y:
|
||||||
@ -163,7 +195,6 @@ int handle_input(SDL_Event* event, state* state)
|
|||||||
audio_device_close(&state->audio, 1);
|
audio_device_close(&state->audio, 1);
|
||||||
audio_recording_init(&state->audio, state->device_index);
|
audio_recording_init(&state->audio, state->device_index);
|
||||||
state->update_ui = 1;
|
state->update_ui = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RECORDING:
|
case RECORDING:
|
||||||
@ -207,17 +238,6 @@ int handle_input(SDL_Event* event, state* state)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOCKET:
|
|
||||||
switch (keysym) {
|
|
||||||
case SDLK_1:
|
|
||||||
log_message(LOG_INFO, "Socket button 1 pressed");
|
|
||||||
net_broadcast();
|
|
||||||
break;
|
|
||||||
case SDLK_2:
|
|
||||||
log_message(LOG_INFO, "Socket button 2 pressed");
|
|
||||||
net_listen_clients();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -226,6 +246,9 @@ void handle_task(state* state)
|
|||||||
{
|
{
|
||||||
switch (state->application_state) {
|
switch (state->application_state) {
|
||||||
|
|
||||||
|
case SOCKET_LISTEN:
|
||||||
|
break;
|
||||||
|
|
||||||
case SELECTING_DEVICE:
|
case SELECTING_DEVICE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -246,8 +269,6 @@ void handle_task(state* state)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOCKET:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,8 +339,11 @@ int select_device(SDL_KeyboardEvent* key_event, int max_index)
|
|||||||
void application_state_to_string(application_state state, char* string)
|
void application_state_to_string(application_state state, char* string)
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
case SOCKET_LISTEN:
|
||||||
|
sprintf(string, "Socket");
|
||||||
|
break;
|
||||||
case SELECTING_DEVICE:
|
case SELECTING_DEVICE:
|
||||||
sprintf(string, "Selecting Device [0-9] -> [y/RET], ");
|
sprintf(string, "Selecting Device [0-9] -> [y/RET]");
|
||||||
break;
|
break;
|
||||||
case RECORDING:
|
case RECORDING:
|
||||||
sprintf(string, "Recording [ESC]: CANCEL");
|
sprintf(string, "Recording [ESC]: CANCEL");
|
||||||
@ -330,8 +354,16 @@ void application_state_to_string(application_state state, char* string)
|
|||||||
case PLAYBACK:
|
case PLAYBACK:
|
||||||
sprintf(string, "Playing [ESC]: CANCEL");
|
sprintf(string, "Playing [ESC]: CANCEL");
|
||||||
break;
|
break;
|
||||||
case SOCKET:
|
}
|
||||||
sprintf(string, "Socket");
|
}
|
||||||
break;
|
|
||||||
|
void* peer_discovery_t(void* args)
|
||||||
|
{
|
||||||
|
state* state = args;
|
||||||
|
while (1) {
|
||||||
|
sem_wait(&state->sem);
|
||||||
|
net_listen_clients();
|
||||||
|
sem_post(&state->sem);
|
||||||
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
texture.c
40
texture.c
@ -1,11 +1,11 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer)
|
int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer, int font_size)
|
||||||
{
|
{
|
||||||
text_texture->texture = NULL;
|
text_texture->texture = NULL;
|
||||||
text_texture->renderer = renderer;
|
text_texture->renderer = renderer;
|
||||||
text_texture->font = TTF_OpenFont("FiraCode-Regular.ttf", 24);
|
text_texture->font = TTF_OpenFont("FiraCode-Regular.ttf", font_size);
|
||||||
if (!text_texture->font) {
|
if (!text_texture->font) {
|
||||||
log_message(LOG_ERROR, "Failed to load font! TTF_Error: %s", TTF_GetError());
|
log_message(LOG_ERROR, "Failed to load font! TTF_Error: %s", TTF_GetError());
|
||||||
return 0;
|
return 0;
|
||||||
@ -23,6 +23,7 @@ int text_texture_load(text_texture* text_texture, char* string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_Color text_color = { 255, 255, 255 };
|
SDL_Color text_color = { 255, 255, 255 };
|
||||||
|
if (strlen(string) == 0) string = " ";
|
||||||
SDL_Surface* text_surface = TTF_RenderText_Solid(text_texture->font, string, text_color);
|
SDL_Surface* text_surface = TTF_RenderText_Solid(text_texture->font, string, text_color);
|
||||||
if (!text_surface) {
|
if (!text_surface) {
|
||||||
log_message(LOG_ERROR, "Unable to render text surface! TTF_Error: %s", TTF_GetError());
|
log_message(LOG_ERROR, "Unable to render text surface! TTF_Error: %s", TTF_GetError());
|
||||||
@ -35,7 +36,7 @@ int text_texture_load(text_texture* text_texture, char* string)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
text_texture->texture = SDL_CreateTextureFromSurface(text_texture->renderer, text_surface);
|
text_texture->texture = texture;
|
||||||
text_texture->width = text_surface->w;
|
text_texture->width = text_surface->w;
|
||||||
text_texture->height = text_surface->h;
|
text_texture->height = text_surface->h;
|
||||||
|
|
||||||
@ -62,11 +63,42 @@ int text_texture_render(text_texture* text_texture, int x, int y)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int text_texture_free(text_texture* text_texture)
|
int text_texture_destroy(text_texture* text_texture)
|
||||||
{
|
{
|
||||||
if (!text_texture->texture) {
|
if (!text_texture->texture) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SDL_DestroyTexture(text_texture->texture);
|
SDL_DestroyTexture(text_texture->texture);
|
||||||
|
TTF_CloseFont(text_texture->font);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_texture_frame_init(text_texture_frame* text_texture_frame, int len, SDL_Renderer* renderer, int font_size)
|
||||||
|
{
|
||||||
|
text_texture_frame->textures = malloc(len*sizeof(text_texture));
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
text_texture_init(&text_texture_frame->textures[i], renderer, font_size);
|
||||||
|
}
|
||||||
|
text_texture_frame->len = len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_texture_frame_render(text_texture_frame* text_texture_frame, int x, int y)
|
||||||
|
{
|
||||||
|
int text_y_offset_step = TTF_FontHeight(text_texture_frame->textures[0].font);
|
||||||
|
int text_y_offset = y;
|
||||||
|
for (int i = 0; i < text_texture_frame->len; i++) {
|
||||||
|
text_texture_render(&text_texture_frame->textures[i], x, text_y_offset);
|
||||||
|
text_y_offset += text_y_offset_step;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_texture_frame_destroy(text_texture_frame* text_texture_frame)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < text_texture_frame->len; i++) {
|
||||||
|
text_texture_destroy(&text_texture_frame->textures[i]);
|
||||||
|
}
|
||||||
|
free(text_texture_frame->textures);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
13
texture.h
13
texture.h
@ -12,9 +12,18 @@ typedef struct {
|
|||||||
int height;
|
int height;
|
||||||
} text_texture;
|
} text_texture;
|
||||||
|
|
||||||
int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer);
|
typedef struct {
|
||||||
|
text_texture* textures;
|
||||||
|
int len;
|
||||||
|
} text_texture_frame;
|
||||||
|
|
||||||
|
int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer, int font_size);
|
||||||
int text_texture_load(text_texture* text_texture, char* string);
|
int text_texture_load(text_texture* text_texture, char* string);
|
||||||
int text_texture_render(text_texture* text_texture, int x, int y);
|
int text_texture_render(text_texture* text_texture, int x, int y);
|
||||||
int text_texture_free(text_texture* text_texture);
|
int text_texture_destroy(text_texture* text_texture);
|
||||||
|
|
||||||
|
int text_texture_frame_init(text_texture_frame* text_texture_frame, int len, SDL_Renderer* renderer, int font_size);
|
||||||
|
int text_texture_frame_render(text_texture_frame* text_texture_frame, int x, int y);
|
||||||
|
int text_texture_frame_destroy(text_texture_frame* text_texture_frame);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user