251 lines
6.9 KiB
Zig
251 lines
6.9 KiB
Zig
const std = @import("std");
|
|
|
|
const board = @import("chess/board.zig");
|
|
const piece = @import("chess/piece.zig");
|
|
|
|
pub const Vertex = extern struct {
|
|
position: [2]f32,
|
|
color: [4]f32,
|
|
uv: [2]f32,
|
|
};
|
|
|
|
pub const BoardRect = struct {
|
|
left: f32,
|
|
bottom: f32,
|
|
width: f32,
|
|
height: f32,
|
|
};
|
|
|
|
pub const Light = [4]f32{ 0.85, 0.75, 0.60, 1.0 };
|
|
pub const Dark = [4]f32{ 0.35, 0.20, 0.10, 1.0 };
|
|
pub const White = [4]f32{ 1.0, 1.0, 1.0, 1.0 };
|
|
|
|
pub fn boardRectForExtent(width: u32, height: u32) BoardRect {
|
|
return boardRectForExtentWithPalette(width, height, true);
|
|
}
|
|
|
|
pub fn boardRectForExtentWithPalette(width: u32, height: u32, show_palette: bool) BoardRect {
|
|
const window_w: f32 = @floatFromInt(width);
|
|
const window_h: f32 = @floatFromInt(height);
|
|
|
|
const margin_px: f32 = 32.0;
|
|
const palette_gap_px: f32 = if (show_palette) 16.0 else 0.0;
|
|
const palette_width_ratio: f32 = if (show_palette) 1.0 / 12.0 else 0.0;
|
|
const menu_area_px: f32 = 80.0;
|
|
const fen_gap_ratio: f32 = 1.0 / 18.0;
|
|
const fen_glyph_height_ratio: f32 = 7.0 / 95.0;
|
|
const fen_area_ratio = fen_gap_ratio + fen_glyph_height_ratio;
|
|
|
|
const available_w = @max(1.0, window_w - (2.0 * margin_px) - palette_gap_px);
|
|
const available_h = @max(1.0, window_h - (2.0 * margin_px) - menu_area_px);
|
|
|
|
const board_from_width = available_w / (1.0 + palette_width_ratio);
|
|
const board_from_height = available_h / (1.0 + fen_area_ratio);
|
|
const board_size_px = @min(board_from_width, board_from_height);
|
|
const palette_width_px = board_size_px * palette_width_ratio;
|
|
const group_width_px = board_size_px + palette_gap_px + palette_width_px;
|
|
|
|
const board_left_px = (window_w - group_width_px) / 2.0;
|
|
const board_bottom_px = margin_px + (board_size_px * fen_area_ratio);
|
|
const max_board_top_px = window_h - margin_px - menu_area_px;
|
|
const board_top_px = @min(board_bottom_px + board_size_px, max_board_top_px);
|
|
const adjusted_board_size_px = @max(1.0, board_top_px - board_bottom_px);
|
|
|
|
return .{
|
|
.left = (board_left_px / window_w) * 2.0 - 1.0,
|
|
.bottom = (board_bottom_px / window_h) * 2.0 - 1.0,
|
|
.width = (adjusted_board_size_px / window_w) * 2.0,
|
|
.height = (adjusted_board_size_px / window_h) * 2.0,
|
|
};
|
|
}
|
|
|
|
pub fn appendQuad(
|
|
vertices: *std.ArrayList(Vertex),
|
|
allocator: std.mem.Allocator,
|
|
bottom_left: [2]f32,
|
|
bottom_right: [2]f32,
|
|
top_right: [2]f32,
|
|
top_left: [2]f32,
|
|
color: [4]f32,
|
|
) !void {
|
|
try appendTexturedQuad(
|
|
vertices,
|
|
allocator,
|
|
bottom_left,
|
|
bottom_right,
|
|
top_right,
|
|
top_left,
|
|
color,
|
|
.{ 0.0, 0.0 },
|
|
.{ 0.0, 0.0 },
|
|
.{ 0.0, 0.0 },
|
|
.{ 0.0, 0.0 },
|
|
);
|
|
}
|
|
|
|
pub fn appendTexturedQuad(
|
|
vertices: *std.ArrayList(Vertex),
|
|
allocator: std.mem.Allocator,
|
|
bottom_left: [2]f32,
|
|
bottom_right: [2]f32,
|
|
top_right: [2]f32,
|
|
top_left: [2]f32,
|
|
color: [4]f32,
|
|
bottom_left_uv: [2]f32,
|
|
bottom_right_uv: [2]f32,
|
|
top_right_uv: [2]f32,
|
|
top_left_uv: [2]f32,
|
|
) !void {
|
|
try vertices.append(allocator, .{
|
|
.position = bottom_left,
|
|
.color = color,
|
|
.uv = bottom_left_uv,
|
|
});
|
|
try vertices.append(allocator, .{
|
|
.position = bottom_right,
|
|
.color = color,
|
|
.uv = bottom_right_uv,
|
|
});
|
|
try vertices.append(allocator, .{
|
|
.position = top_right,
|
|
.color = color,
|
|
.uv = top_right_uv,
|
|
});
|
|
|
|
try vertices.append(allocator, .{
|
|
.position = bottom_left,
|
|
.color = color,
|
|
.uv = bottom_left_uv,
|
|
});
|
|
try vertices.append(allocator, .{
|
|
.position = top_right,
|
|
.color = color,
|
|
.uv = top_right_uv,
|
|
});
|
|
try vertices.append(allocator, .{
|
|
.position = top_left,
|
|
.color = color,
|
|
.uv = top_left_uv,
|
|
});
|
|
}
|
|
|
|
pub fn appendChessboard(
|
|
vertices: *std.ArrayList(Vertex),
|
|
board_rect: BoardRect,
|
|
allocator: std.mem.Allocator,
|
|
) !void {
|
|
var rank: usize = 0;
|
|
while (rank < 8) : (rank += 1) {
|
|
var file: usize = 0;
|
|
while (file < 8) : (file += 1) {
|
|
const color = if ((rank + file) % 2 == 0) Dark else Light;
|
|
|
|
const x0: f32 = @floatFromInt(file);
|
|
const x1: f32 = @floatFromInt(file + 1);
|
|
const y0: f32 = @floatFromInt(rank);
|
|
const y1: f32 = @floatFromInt(rank + 1);
|
|
|
|
try appendQuad(
|
|
vertices,
|
|
allocator,
|
|
boardToNdc(board_rect, x0, y0),
|
|
boardToNdc(board_rect, x1, y0),
|
|
boardToNdc(board_rect, x1, y1),
|
|
boardToNdc(board_rect, x0, y1),
|
|
color,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn appendPieceQuad(
|
|
vertices: *std.ArrayList(Vertex),
|
|
board_rect: BoardRect,
|
|
allocator: std.mem.Allocator,
|
|
file: f32,
|
|
rank: f32,
|
|
) !void {
|
|
try appendPieceQuadWithColor(vertices, board_rect, allocator, file, rank, White);
|
|
}
|
|
|
|
pub fn appendPieceQuadWithColor(
|
|
vertices: *std.ArrayList(Vertex),
|
|
board_rect: BoardRect,
|
|
allocator: std.mem.Allocator,
|
|
file: f32,
|
|
rank: f32,
|
|
color: [4]f32,
|
|
) !void {
|
|
const inset: f32 = 0.08;
|
|
const x0 = file + inset;
|
|
const x1 = file + 1.0 - inset;
|
|
const y0 = rank + inset;
|
|
const y1 = rank + 1.0 - inset;
|
|
|
|
try appendTexturedQuad(
|
|
vertices,
|
|
allocator,
|
|
boardToNdc(board_rect, x0, y0),
|
|
boardToNdc(board_rect, x1, y0),
|
|
boardToNdc(board_rect, x1, y1),
|
|
boardToNdc(board_rect, x0, y1),
|
|
color,
|
|
.{ 0.0, 1.0 },
|
|
.{ 1.0, 1.0 },
|
|
.{ 1.0, 0.0 },
|
|
.{ 0.0, 0.0 },
|
|
);
|
|
}
|
|
|
|
pub fn appendPieceQuadCenteredAtNdc(
|
|
vertices: *std.ArrayList(Vertex),
|
|
allocator: std.mem.Allocator,
|
|
center: [2]f32,
|
|
size: [2]f32,
|
|
color: [4]f32,
|
|
) !void {
|
|
const half_w = size[0] / 2.0;
|
|
const half_h = size[1] / 2.0;
|
|
const x0 = center[0] - half_w;
|
|
const x1 = center[0] + half_w;
|
|
const y0 = center[1] - half_h;
|
|
const y1 = center[1] + half_h;
|
|
|
|
try appendTexturedQuad(
|
|
vertices,
|
|
allocator,
|
|
.{ x0, y0 },
|
|
.{ x1, y0 },
|
|
.{ x1, y1 },
|
|
.{ x0, y1 },
|
|
color,
|
|
.{ 0.0, 1.0 },
|
|
.{ 1.0, 1.0 },
|
|
.{ 1.0, 0.0 },
|
|
.{ 0.0, 0.0 },
|
|
);
|
|
}
|
|
|
|
pub fn appendPiecesFromBoard(
|
|
vertices: *std.ArrayList(Vertex),
|
|
board_rect: BoardRect,
|
|
allocator: std.mem.Allocator,
|
|
state: board.BoardState,
|
|
) !void {
|
|
for (0..8) |rank| {
|
|
for (0..8) |file| {
|
|
const p = state.getSquare(@intCast((rank * 8) + file));
|
|
if (piece.typeOf(p) != piece.PieceType.none) {
|
|
try appendPieceQuad(vertices, board_rect, allocator, @floatFromInt(file), @floatFromInt(rank));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn boardToNdc(rect: BoardRect, x: f32, y: f32) [2]f32 {
|
|
return .{
|
|
rect.left + (x / 8.0) * rect.width,
|
|
rect.bottom + (y / 8.0) * rect.height,
|
|
};
|
|
}
|