const Self = @This(); const rl = @import("raylib"); const ChipContext = @import("chip.zig"); const print = @import("std").debug.print; chip: *ChipContext, on_color: rl.Color, off_color: rl.Color, timer_speed: f32, tick_speed: f32, beep_sound: ?rl.Sound, tick_time: f32, timer_time: f32, pub fn init(chip: *ChipContext, beep_sound: ?rl.Sound) Self { return Self{ .chip = chip, .off_color = rl.BLACK, .on_color = rl.RAYWHITE, .timer_speed = 60, .tick_speed = 500, .tick_time = 0, .timer_time = 0, .beep_sound = beep_sound, }; } pub fn update_input(self: *Self) void { const keys = [16]rl.KeyboardKey{ .KEY_X, .KEY_ONE, .KEY_TWO, .KEY_THREE, .KEY_Q, .KEY_W, .KEY_E, .KEY_A, .KEY_S, .KEY_D, .KEY_Z, .KEY_C, .KEY_FOUR, .KEY_R, .KEY_F, .KEY_V, }; for (0.., keys) |i, key| { self.chip.input[i] = rl.IsKeyDown(key); } } pub fn update(self: *Self, dt: f32) void { self.update_input(); self.tick_time += dt; while (self.tick_time > 1/self.tick_speed) { // const inst = self.chip.current_instruction(); // const inst_fmt = ChipContext.decode_instruction_fmt(inst); // print("[{x:0>4}] ({x:0>4}) {s}\n", .{ self.chip.PC, inst, inst_fmt }); self.chip.step() catch {}; self.tick_time -= 1/self.tick_speed; } self.timer_time += dt; while (self.timer_time > 1/self.timer_speed) { self.chip.update_timer(); self.timer_time -= 1/self.timer_speed; } if (self.beep_sound) |beep_sound| { if (self.chip.ST > 0) { if (!rl.IsSoundPlaying(beep_sound)) { rl.PlaySound(beep_sound); } } else { if (rl.IsSoundPlaying(beep_sound)) { rl.StopSound(beep_sound); } } } } pub fn render(self: *Self) void { rl.DrawRectangle(0, 0, self.chip.display_width, self.chip.display_height, self.off_color); for (0..self.chip.display_height) |y| { for (0..self.chip.display_width) |x| { if (self.chip.display_get(@intCast(x), @intCast(y))) { rl.DrawPixel(@intCast(x), @intCast(y), self.on_color); } } } }