show QWERTY controls in settings
This commit is contained in:
parent
3e5c51d838
commit
6a9be7f811
38
src/horizontal-layout.zig
Normal file
38
src/horizontal-layout.zig
Normal file
@ -0,0 +1,38 @@
|
||||
const Self = @This();
|
||||
const rl = @import("raylib");
|
||||
|
||||
bounds: rl.Rectangle,
|
||||
gap: f32,
|
||||
used_width: f32,
|
||||
|
||||
pub fn init(gap: f32, bounds: rl.Rectangle) Self {
|
||||
return Self{
|
||||
.bounds = bounds,
|
||||
.gap = gap,
|
||||
.used_width = 0
|
||||
};
|
||||
}
|
||||
|
||||
pub fn column_sized(self: *Self, width: f32, height: f32) rl.Rectangle {
|
||||
const rect = rl.Rectangle{
|
||||
.x = self.bounds.x + self.used_width,
|
||||
.y = self.bounds.y,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
self.used_width += width + self.gap;
|
||||
return rect;
|
||||
}
|
||||
|
||||
pub fn column(self: *Self, width: f32) rl.Rectangle {
|
||||
return self.column_sized(width, self.bounds.height);
|
||||
}
|
||||
|
||||
pub fn column_full(self: *Self) rl.Rectangle {
|
||||
const left_width = self.bounds.width - self.used_width;
|
||||
return self.column_sized(left_width, self.bounds.height);
|
||||
}
|
||||
|
||||
pub fn add_gap(self: *Self, gap: f32) void {
|
||||
self.used_width += gap;
|
||||
}
|
@ -5,6 +5,7 @@ const std = @import("std");
|
||||
const roms = @import("./roms.zig");
|
||||
const GUILayout = @import("./gui-layout.zig");
|
||||
const VerticalLayout = @import("./vertical-layout.zig");
|
||||
const HorizontalLayout = @import("./horizontal-layout.zig");
|
||||
const ROM = roms.ROM;
|
||||
|
||||
const ChipContext = @import("chip.zig");
|
||||
@ -71,7 +72,8 @@ pub fn init(allocator: Allocator) !Self {
|
||||
.chip_sound = chip_sound,
|
||||
};
|
||||
|
||||
self.set_rom(3);
|
||||
const breakout = comptime roms.findIndexbyName(&rom_list, "br8kout") orelse unreachable;
|
||||
self.set_rom(@intCast(breakout));
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -100,6 +102,7 @@ pub fn update(self: *Self, dt: f32) void {
|
||||
rl.ResumeSound(self.chip_sound);
|
||||
self.raylib_chip.update(dt);
|
||||
} else {
|
||||
self.raylib_chip.update_input();
|
||||
rl.PauseSound(self.chip_sound);
|
||||
}
|
||||
}
|
||||
@ -184,7 +187,7 @@ fn GuiListViewMinWidth(allocator: Allocator, height: i32, items: []const []const
|
||||
}
|
||||
|
||||
pub fn getWindowBodyBounds(bounds: rl.Rectangle) rl.Rectangle {
|
||||
const status_bar_height = 24; // defined as RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT in raygui.h
|
||||
const status_bar_height = gui.RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT;
|
||||
const margin = 8;
|
||||
|
||||
return rl.Rectangle {
|
||||
@ -203,6 +206,55 @@ pub fn pushGuiWindowBox(layout: *GUILayout, bounds: rl.Rectangle, title: [*:0]co
|
||||
return gui.GuiWindowBox(bounds, title) != 0;
|
||||
}
|
||||
|
||||
fn GetColor(hex_value: i32) rl.Color {
|
||||
const hex_value_unsigned: u32 = @bitCast(hex_value);
|
||||
return rl.Color{
|
||||
.r = @truncate(hex_value_unsigned >> 24),
|
||||
.g = @truncate(hex_value_unsigned >> 16),
|
||||
.b = @truncate(hex_value_unsigned >> 8),
|
||||
.a = @truncate(hex_value_unsigned)
|
||||
};
|
||||
}
|
||||
|
||||
fn drawKeyboard(bounds: rl.Rectangle, keyboard_labels: [16]u8, keyboard_state: [16]bool) void {
|
||||
const font_size = gui.GuiGetStyle(.DEFAULT , @intFromEnum(gui.GuiDefaultProperty.TEXT_SIZE))*2;
|
||||
const text_color_normal = GetColor(gui.GuiGetStyle(.LABEL, @intFromEnum(gui.GuiControlProperty.TEXT_COLOR_NORMAL)));
|
||||
const text_color_pressed = GetColor(gui.GuiGetStyle(.LABEL, @intFromEnum(gui.GuiControlProperty.TEXT_COLOR_PRESSED)));
|
||||
const border_color_normal = GetColor(gui.GuiGetStyle(.LABEL, @intFromEnum(gui.GuiControlProperty.BORDER_COLOR_NORMAL)));
|
||||
const border_color_pressed = GetColor(gui.GuiGetStyle(.LABEL, @intFromEnum(gui.GuiControlProperty.BORDER_COLOR_PRESSED)));
|
||||
|
||||
const cell_margin = 2;
|
||||
const cell_size = font_size+2*cell_margin;
|
||||
rl.rlPushMatrix();
|
||||
rl.rlTranslatef(bounds.x, bounds.y, 0);
|
||||
|
||||
const key_indexes = [16]usize {
|
||||
0x1, 0x2, 0x3, 0xC,
|
||||
0x4, 0x5, 0x6, 0xD,
|
||||
0x7, 0x8, 0x9, 0xE,
|
||||
0xA, 0x0, 0xB, 0xF,
|
||||
};
|
||||
for (0.., key_indexes) |i, key_index| {
|
||||
const cell_y: i32 = @intCast(@divTrunc(i, 4));
|
||||
const cell_x: i32 = @intCast(i % 4);
|
||||
const label = [_:0]u8{ keyboard_labels[key_index], 0 };
|
||||
const label_width = rl.MeasureText(&label, font_size);
|
||||
|
||||
var color = text_color_normal;
|
||||
var border_color = border_color_normal;
|
||||
if (keyboard_state[key_index]) {
|
||||
color = text_color_pressed;
|
||||
color = border_color_pressed;
|
||||
}
|
||||
const x = cell_x*(cell_size-1);
|
||||
const y = cell_y*(cell_size-1);
|
||||
rl.DrawRectangleLines(x, y, cell_size, cell_size, border_color);
|
||||
rl.DrawText(&label, x + @divTrunc(cell_size - label_width, 2), y+cell_margin, font_size, color);
|
||||
}
|
||||
|
||||
rl.rlPopMatrix();
|
||||
}
|
||||
|
||||
pub fn drawGui(self: *Self, allocator: Allocator) !void {
|
||||
if (rl.IsKeyPressed(.KEY_TAB)) {
|
||||
self.is_gui_open = !self.is_gui_open;
|
||||
@ -231,38 +283,75 @@ pub fn drawGui(self: *Self, allocator: Allocator) !void {
|
||||
.width = window_width,
|
||||
.height = window_height
|
||||
};
|
||||
if (pushGuiWindowBox(&window_layout, window, "CHIP-8 Settings")) {
|
||||
if (pushGuiWindowBox(&window_layout, window, "Settings")) {
|
||||
self.is_gui_open = false;
|
||||
}
|
||||
|
||||
var vertical_layout = VerticalLayout.init(4, getWindowBodyBounds(window));
|
||||
const rom_list_names = try allocator.alloc([]const u8, rom_list.len);
|
||||
defer allocator.free(rom_list_names);
|
||||
|
||||
if (gui.GuiButton(vertical_layout.row_sized(100, 24), "Reset") == 1) {
|
||||
self.reset_rom();
|
||||
for (0.., rom_list) |i, rom| {
|
||||
rom_list_names[i] = rom.name;
|
||||
}
|
||||
|
||||
_ = gui.GuiLabel(vertical_layout.row(16), "Current ROM:");
|
||||
{ // ROM list view
|
||||
const rom_list_names = try allocator.alloc([]const u8, rom_list.len);
|
||||
defer allocator.free(rom_list_names);
|
||||
const rom_list_height = 100;
|
||||
const rom_list_width = try GuiListViewMinWidth(allocator, rom_list_height, rom_list_names) + 20;
|
||||
|
||||
for (0.., rom_list) |i, rom| {
|
||||
rom_list_names[i] = rom.name;
|
||||
var columns = HorizontalLayout.init(32, getWindowBodyBounds(window));
|
||||
|
||||
{ // First column
|
||||
var column1 = VerticalLayout.init(4, columns.column(@floatFromInt(rom_list_width)));
|
||||
if (gui.GuiButton(column1.row_sized(100, 24), "Reset") == 1) {
|
||||
self.reset_rom();
|
||||
}
|
||||
|
||||
const list_height = 100;
|
||||
const list_width = try GuiListViewMinWidth(allocator, list_height, rom_list_names) + 20;
|
||||
var selected_rom = self.selected_rom_index;
|
||||
_ = try GuiListView(
|
||||
allocator,
|
||||
vertical_layout.row_sized(@floatFromInt(list_width), list_height),
|
||||
rom_list_names,
|
||||
&self.rom_list_scroll_index,
|
||||
&selected_rom
|
||||
);
|
||||
_ = gui.GuiLabel(column1.row(16), "Current ROM:");
|
||||
{ // ROM list view
|
||||
var selected_rom = self.selected_rom_index;
|
||||
_ = try GuiListView(
|
||||
allocator,
|
||||
column1.row_sized(@floatFromInt(rom_list_width), rom_list_height),
|
||||
rom_list_names,
|
||||
&self.rom_list_scroll_index,
|
||||
&selected_rom
|
||||
);
|
||||
|
||||
if (selected_rom != self.selected_rom_index) {
|
||||
self.set_rom(selected_rom);
|
||||
if (selected_rom != self.selected_rom_index) {
|
||||
self.set_rom(selected_rom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Controls column
|
||||
var column2 = VerticalLayout.init(0, columns.column(200));
|
||||
|
||||
_ = gui.GuiLabel(column2.row(16), "Controls:");
|
||||
_ = gui.GuiLabel(column2.row(16), "TAB - Toggle settings (this window)");
|
||||
column2.add_gap(8);
|
||||
|
||||
var keyboard_columns = HorizontalLayout.init(0, column2.row_full());
|
||||
const keyboard_width = 128;
|
||||
|
||||
{
|
||||
var keyboard_column1 = VerticalLayout.init(0, keyboard_columns.column(keyboard_width));
|
||||
_ = gui.GuiLabel(keyboard_column1.row(16), "Input state (QWERTY):");
|
||||
var keyboard_labels: [16]u8 = undefined;
|
||||
for (0.., RaylibChip.default_controls) |i, key| {
|
||||
keyboard_labels[i] = @intCast(@intFromEnum(key));
|
||||
}
|
||||
drawKeyboard(keyboard_column1.row_full(), keyboard_labels, self.chip.input);
|
||||
}
|
||||
|
||||
{
|
||||
var keyboard_column2 = VerticalLayout.init(0, keyboard_columns.column(keyboard_width));
|
||||
_ = gui.GuiLabel(keyboard_column2.row(16), "Input state:");
|
||||
var reference_labels = [16]u8{
|
||||
'0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B',
|
||||
'C', 'D', 'E', 'F',
|
||||
};
|
||||
drawKeyboard(keyboard_column2.row_full(), reference_labels, self.chip.input);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,25 @@ 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,
|
||||
@ -27,26 +46,7 @@ pub fn init(chip: *ChipContext, beep_sound: ?rl.Sound) Self {
|
||||
}
|
||||
|
||||
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| {
|
||||
for (0.., default_controls) |i, key| {
|
||||
self.chip.input[i] = rl.IsKeyDown(key);
|
||||
}
|
||||
}
|
||||
|
@ -23,3 +23,12 @@ pub fn listROMs() [options.roms.len]ROM {
|
||||
|
||||
return roms;
|
||||
}
|
||||
|
||||
pub fn findIndexbyName(roms: []const ROM, name: []const u8) ?usize {
|
||||
for (0.., roms) |i, rom| {
|
||||
if (std.mem.eql(u8, rom.name, name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -3,27 +3,36 @@ const rl = @import("raylib");
|
||||
|
||||
bounds: rl.Rectangle,
|
||||
gap: f32,
|
||||
used: f32,
|
||||
used_height: f32,
|
||||
|
||||
pub fn init(gap: f32, bounds: rl.Rectangle) Self {
|
||||
return Self{
|
||||
.bounds = bounds,
|
||||
.gap = gap,
|
||||
.used = 0
|
||||
.used_height = 0
|
||||
};
|
||||
}
|
||||
|
||||
pub fn row_sized(self: *Self, width: f32, height: f32) rl.Rectangle {
|
||||
const rect = rl.Rectangle{
|
||||
.x = self.bounds.x,
|
||||
.y = self.bounds.y + self.used,
|
||||
.y = self.bounds.y + self.used_height,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
self.used += height + self.gap;
|
||||
self.used_height += height + self.gap;
|
||||
return rect;
|
||||
}
|
||||
|
||||
pub fn row(self: *Self, height: f32) rl.Rectangle {
|
||||
return self.row_sized(self.bounds.width, height);
|
||||
}
|
||||
|
||||
pub fn row_full(self: *Self) rl.Rectangle {
|
||||
const left_height = self.bounds.height - self.used_height;
|
||||
return self.row_sized(self.bounds.width, left_height);
|
||||
}
|
||||
|
||||
pub fn add_gap(self: *Self, gap: f32) void {
|
||||
self.used_height += gap;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user