This commit is contained in:
2025-04-23 22:55:22 +02:00
commit 8fd5f1cf1e
8 changed files with 565 additions and 0 deletions

50
util/audio.c Normal file
View File

@@ -0,0 +1,50 @@
/*
// Created by bruno on 16.2.2025.
*/
#include "audio.h"
AudioData audioData;
void audio_callback(void *userdata, Uint8 *stream, int len) {
AudioData *audio = (AudioData *) userdata;
int samples = len / sizeof(float);
for (int i = 0; i < samples; i++) {
float mix = 0.0f;
int activeVoices = 0;
for (int v = 0; v < NUM_SYNTH_VOICES; v++) {
SynthVoice *voice = &audio->synthVoices[v];
if (voice->volume == 0 || voice->frequency == 0) continue;
float sample = 0.0f;
float t = (float) voice->phase / 255.0f * 2.0f - 1.0f;
switch (voice->waveform) {
default:
case WAVE_SINE:
sample = sinf(voice->phase * 2.0f * M_PI / 256.0f);
break;
case WAVE_SQUARE:
sample = (t >= 0.0f) ? 1.0f : -1.0f;
break;
case WAVE_SAWTOOTH:
sample = t;
break;
case WAVE_TRIANGLE:
sample = (t < 0) ? -t : t;
break;
case WAVE_NOISE:
sample = ((float) rand() / RAND_MAX) * 2.0f - 1.0f;
break;
}
voice->phase += (uint8_t) ((voice->frequency * 256) / SAMPLE_RATE);
mix += sample * (voice->volume / 255.0f);
activeVoices++;
}
((float *) stream)[i] = (activeVoices > 0) ? mix / activeVoices : 0.0f;
}
}

39
util/audio.h Normal file
View File

@@ -0,0 +1,39 @@
/*
// Created by bruno on 16.2.2025.
*/
#ifndef RISCB_AUDIO_H
#define RISCB_AUDIO_H
#include <SDL2/SDL.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define SAMPLE_RATE 44100
#define NUM_SYNTH_VOICES 3
typedef enum {
WAVE_SINE,
WAVE_SQUARE,
WAVE_SAWTOOTH,
WAVE_TRIANGLE,
WAVE_NOISE
} Waveform;
typedef struct {
uint8_t volume;
uint16_t frequency;
uint8_t phase;
Waveform waveform;
} SynthVoice;
typedef struct {
SynthVoice synthVoices[NUM_SYNTH_VOICES];
} AudioData;
extern AudioData audioData;
void audio_callback(void *userdata, Uint8 *stream, int len);
#endif //RISCB_AUDIO_H

61
util/font.c Normal file
View File

@@ -0,0 +1,61 @@
//
// Created by bruno on 1.2.2025.
//
#include "font.h"
BitmapFont
prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
TTF_Font *gFont = TTF_OpenFont(file, pxSize);
BitmapFont out;
out.size = pxSize;
out.color = (SDL_Color) {r, g, b, a};
unsigned int i = 1;
do {
if (i == 173) { //specifically this char is 0 width (IDK why)
out.surface[i] = SDL_CreateRGBSurface(0, pxSize, pxSize, 32, 0, 0, 0, 0);
} else {
char tmpOut[2] = {i, 0};
out.surface[i] = TTF_RenderText_Solid(gFont, tmpOut, out.color);
}
out.texture[i] = SDL_CreateTextureFromSurface(renderer, out.surface[i]);
i++;
} while (i < 256);
TTF_CloseFont(gFont);
return out;
}
void renderText(SDL_Renderer *renderer, BitmapFont font, char *string, uint16_t x, uint16_t y) {
SDL_Rect charRect;
charRect.x = 0;
charRect.y = 0;
charRect.w = font.size;
charRect.h = font.size;
SDL_Rect outRect = charRect;
outRect.x = x;
outRect.y = y;
while (*string) {
if (*string == '\n') {
outRect.x = x;
outRect.y += charRect.h + 4;
string++;
continue;
}
SDL_RenderCopy(renderer, font.texture[*string], &charRect, &outRect);
outRect.x += charRect.w + 1;
string++;
}
}
void destroyFont(BitmapFont *font) {
for (uint16_t i = 1; i < 256; i++) {
if (font->texture[i]) {
SDL_DestroyTexture(font->texture[i]);
}
if (font->surface[i]) {
SDL_FreeSurface(font->surface[i]);
}
}
}

26
util/font.h Normal file
View File

@@ -0,0 +1,26 @@
//
// Created by bruno on 1.2.2025.
//
#ifndef RISCB_FONT_H
#define RISCB_FONT_H
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_ttf.h>
#include <math.h>
typedef struct {
SDL_Texture *texture[256];
SDL_Surface *surface[256];
uint8_t size;
SDL_Color color;
} BitmapFont;
BitmapFont
prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
void destroyFont(BitmapFont *font);
void renderText(SDL_Renderer *renderer, BitmapFont font, char *string, uint16_t x, uint16_t y);
#endif //RISCB_FONT_H