112 lines
2.8 KiB
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();
|
|
}
|