aboutsummaryrefslogtreecommitdiff
path: root/main.ha
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--main.ha58
1 files changed, 40 insertions, 18 deletions
diff --git a/main.ha b/main.ha
index 8051da4..e3e9332 100644
--- a/main.ha
+++ b/main.ha
@@ -9,6 +9,7 @@ use sdl2;
def SCALE: int = 20;
def CLOCKSPEED: int = 600;
+def VOLUME: i16 = 3000;
def SCREEN_WIDTH: size = 64;
def SCREEN_HEIGHT: size = 32;
@@ -70,20 +71,6 @@ fn chip8() state = {
return state;
};
-fn reset(state: *state) void = {
- state.display = [false...];
- state.keys = [false...];
- state.stack = [0...];
- state.SP = 0;
- state.PC = START_ADDR;
- state.V = [0...];
- state.I = 0;
- state.DT = 0;
- state.ST = 0;
-
- state.mem[..FONT_SIZE] = FONT[..];
-};
-
fn instruction(opcode: u16) inst = inst {
op = opcode,
X = (opcode >> 8): u8 & 0x0F,
@@ -365,14 +352,15 @@ fn execute_instruction(state: *state, inst: inst, random: *random::random) void
};
};
-fn tick_timers(state: *state) void = {
+fn tick_timers(state: *state, audio_device: SDL_AudioDeviceID) void = {
if (state.DT > 0)
state.DT -= 1;
if (state.ST > 0) {
- // BEEP
-
state.ST -= 1;
+ SDL_PauseAudioDevice(audio_device, 0);
+ } else {
+ SDL_PauseAudioDevice(audio_device, 1);
};
};
@@ -415,6 +403,22 @@ fn update_screen(state: *state, renderer: *sdl2::SDL_Renderer) (void | sdl2::err
sdl2::SDL_RenderPresent(renderer);
};
+fn audio_callback(userdata: nullable *opaque, stream: *u8, len_: int) void = {
+ let stream: []i16 = *(&types::slice {
+ data = stream: *[*]i16,
+ length = len_: size / 2,
+ capacity = 0
+ }: *[]i16);
+
+ let sample_index = 0;
+ const half_square_wave_period = 44100 / 440 / 2;
+
+ for (let i = 0; i < len_ / 2; i += 1) {
+ stream[i] = if ((sample_index / half_square_wave_period) % 2 == 0) -VOLUME else VOLUME;
+ sample_index += 1;
+ };
+};
+
fn run() (void | fs::error | io::error | sdl2::error) = {
if (len(os::args) < 2) {
fmt::fatalf("Usage: {} <rom>", os::args[0]);
@@ -440,6 +444,24 @@ fn run() (void | fs::error | io::error | sdl2::error) = {
let renderer = sdl2::SDL_CreateRenderer(window, -1, sdl2::SDL_RendererFlags::ACCELERATED)?;
defer sdl2::SDL_DestroyRenderer(renderer);
+ const want_spec = SDL_AudioSpec {
+ freq = 44100,
+ format = AUDIO_S16LSB,
+ channels = 1,
+ samples = 512,
+ callback = &audio_callback,
+ userdata = null,
+ ...
+ };
+
+ let have_spec = SDL_AudioSpec {
+ callback = &audio_callback,
+ ...
+ };
+
+ let dev = SDL_OpenAudioDevice(null, 0, &want_spec, &have_spec, 0)?;
+ defer SDL_CloseAudioDevice(dev);
+
sdl2::SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF)?;
sdl2::SDL_RenderClear(renderer)?;
@@ -551,7 +573,7 @@ fn run() (void | fs::error | io::error | sdl2::error) = {
chip8.draw = false;
};
- tick_timers(&chip8);
+ tick_timers(&chip8, dev);
};
};