1
0
chip8-zig/src/raylib-chip.zig

112 lines
2.8 KiB
Zig

const Self = @This();
const rl = @import("raylib");
const ChipContext = @import("chip.zig");
const print = @import("std").debug.print;
pub const default_controls = [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,
};
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 {
for (0.., default_controls) |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.update_timers(dt);
}
pub fn update_timers(self: *Self, dt: f32) void {
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: *const Self, x: i32, y: i32, width: i32, height: i32) void {
const display_width = self.chip.display_width;
const display_height = self.chip.display_height;
const x_scale = @as(f32,@floatFromInt(width)) / @as(f32, @floatFromInt(display_width));
const y_scale = @as(f32,@floatFromInt(height)) / @as(f32, @floatFromInt(display_height));
rl.rlPushMatrix();
rl.rlTranslatef(@floatFromInt(x), @floatFromInt(y), 0);
rl.rlScalef(x_scale, y_scale, 1);
rl.DrawRectangle(0, 0, display_width, display_height, self.off_color);
for (0..display_height) |iy| {
for (0..display_width) |ix| {
if (self.chip.display_get(@intCast(ix), @intCast(iy))) {
rl.DrawRectangle(@intCast(ix), @intCast(iy), 1, 1, self.on_color);
}
}
}
rl.rlPopMatrix();
}