feat: use framebuffer size to choose sprite set
Using multiple sizes of sprites will hopefully make porting the game to a wider range of devices easier.dev
parent
15e1670ec3
commit
755518bb5d
192
src/main.zig
192
src/main.zig
|
@ -54,9 +54,10 @@ const TileSheet = struct {
|
||||||
@floatFromInt(this.tile_size[0]),
|
@floatFromInt(this.tile_size[0]),
|
||||||
@floatFromInt(this.tile_size[1]),
|
@floatFromInt(this.tile_size[1]),
|
||||||
};
|
};
|
||||||
|
// add a half to round up
|
||||||
const size_in_tiles = [2]u32{
|
const size_in_tiles = [2]u32{
|
||||||
@as(u32, @intCast(this.texture.size[0])) / this.tile_size[0],
|
(@as(u32, @intCast(this.texture.size[0])) + (this.tile_size[0] / 2)) / this.tile_size[0],
|
||||||
@as(u32, @intCast(this.texture.size[1])) / this.tile_size[1],
|
(@as(u32, @intCast(this.texture.size[1])) + (this.tile_size[1] / 2)) / this.tile_size[1],
|
||||||
};
|
};
|
||||||
const pos_in_tiles = [2]u32{
|
const pos_in_tiles = [2]u32{
|
||||||
tile_id % size_in_tiles[0],
|
tile_id % size_in_tiles[0],
|
||||||
|
@ -76,14 +77,30 @@ const TileSheet = struct {
|
||||||
((pos_in_tilesf[1] + 1) * tile_sizef[1]) / texture_sizef[1],
|
((pos_in_tilesf[1] + 1) * tile_sizef[1]) / texture_sizef[1],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
_ = canvas.printText(.{ 0, 0 }, "uv = {}", .{uv}, .{});
|
|
||||||
canvas.rect(pos, options.size orelse tile_sizef, .{
|
canvas.rect(pos, options.size orelse tile_sizef, .{
|
||||||
.texture = this.texture.glTexture,
|
.texture = this.texture.glTexture,
|
||||||
.uv = uv,
|
.uv = uv,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// const cards_medium_spritesheet =
|
|
||||||
|
/// A texture with a regular grid of sprites
|
||||||
|
const DeckSprites = struct {
|
||||||
|
tilesheet: TileSheet,
|
||||||
|
/// Return the tile index for a given card,
|
||||||
|
mapping: std.AutoHashMapUnmanaged(Card, u32),
|
||||||
|
blank: u32,
|
||||||
|
back: u32,
|
||||||
|
|
||||||
|
pub fn deinit(this: *@This(), gpa: std.mem.Allocator) void {
|
||||||
|
this.tilesheet.deinit();
|
||||||
|
this.mapping.deinit(gpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getTileForCard(this: @This(), card: Card) u32 {
|
||||||
|
return this.mapping.get(card) orelse 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
@ -118,16 +135,11 @@ pub fn main() !void {
|
||||||
// Set up input callbacks
|
// Set up input callbacks
|
||||||
_ = seizer.backend.glfw.c.glfwSetFramebufferSizeCallback(window, &glfw_framebuffer_size_callback);
|
_ = seizer.backend.glfw.c.glfwSetFramebufferSizeCallback(window, &glfw_framebuffer_size_callback);
|
||||||
|
|
||||||
var card_tilemap = try TileSheet.init(.{
|
var card_tilemap_medium: ?DeckSprites = null;
|
||||||
.allocator = gpa.allocator(),
|
defer if (card_tilemap_medium) |*tilemap| tilemap.deinit(gpa.allocator());
|
||||||
.image_file_contents = @embedFile("./cardsMedium_tilemap.png"),
|
|
||||||
.tile_size = .{ 32, 32 },
|
var card_tilemap_large: ?DeckSprites = null;
|
||||||
.texture_options = .{
|
defer if (card_tilemap_large) |*tilemap| tilemap.deinit(gpa.allocator());
|
||||||
.min_filter = .nearest,
|
|
||||||
.mag_filter = .nearest,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
defer card_tilemap.deinit();
|
|
||||||
|
|
||||||
var canvas = try seizer.Canvas.init(gpa.allocator(), .{});
|
var canvas = try seizer.Canvas.init(gpa.allocator(), .{});
|
||||||
defer canvas.deinit(gpa.allocator());
|
defer canvas.deinit(gpa.allocator());
|
||||||
|
@ -154,19 +166,157 @@ pub fn main() !void {
|
||||||
@floatFromInt(framebuffer_size[1]),
|
@floatFromInt(framebuffer_size[1]),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
card_tilemap.renderTile(&canvas, 1, .{ 10, 10 }, .{});
|
|
||||||
// canvas.rect(.{ 10, 10 }, .{ @as(f32, @floatFromInt(card_tilemap.size[0])) / 15.0, @as(f32, @floatFromInt(card_tilemap.size[1])) / 10.0 }, .{
|
const render_large = framebuffer_size[1] > 1000;
|
||||||
// .texture = card_tilemap.glTexture,
|
if (render_large) {
|
||||||
// .uv = .{ .min = .{ 0, 0 }, .max = .{ 1.0 / 15.0, 1.0 / 10.0 } },
|
if (card_tilemap_large == null) {
|
||||||
// });
|
card_tilemap_large = try loadLargeCards(gpa.allocator());
|
||||||
_ = canvas.writeText(.{ 50, 50 }, "Hello, world!", .{});
|
}
|
||||||
_ = canvas.printText(.{ 50, 100 }, "window_size = {}, {}\nframebuffer_size = {}, {}", .{ window_size[0], window_size[1], framebuffer_size[0], framebuffer_size[1] }, .{});
|
} else {
|
||||||
|
if (card_tilemap_medium == null) {
|
||||||
|
card_tilemap_medium = try loadMediumCards(gpa.allocator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deck_sprites = if (framebuffer_size[1] > 1000) card_tilemap_large.? else card_tilemap_medium.?;
|
||||||
|
for (0..4) |suit| {
|
||||||
|
for (1..14) |rank| {
|
||||||
|
const card = Card{ .suit = @enumFromInt(suit), .rank = @intCast(rank) };
|
||||||
|
const tile_index = deck_sprites.getTileForCard(card);
|
||||||
|
deck_sprites.tilesheet.renderTile(&canvas, @intCast(tile_index), .{
|
||||||
|
@floatFromInt(rank * deck_sprites.tilesheet.tile_size[0]),
|
||||||
|
@floatFromInt(suit * deck_sprites.tilesheet.tile_size[1]),
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.blank, .{
|
||||||
|
@floatFromInt(1 * deck_sprites.tilesheet.tile_size[0]),
|
||||||
|
@floatFromInt(5 * deck_sprites.tilesheet.tile_size[1]),
|
||||||
|
}, .{});
|
||||||
|
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.back, .{
|
||||||
|
@floatFromInt(2 * deck_sprites.tilesheet.tile_size[0]),
|
||||||
|
@floatFromInt(5 * deck_sprites.tilesheet.tile_size[1]),
|
||||||
|
}, .{});
|
||||||
|
|
||||||
canvas.end();
|
canvas.end();
|
||||||
|
|
||||||
seizer.backend.glfw.c.glfwSwapBuffers(window);
|
seizer.backend.glfw.c.glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn loadMediumCards(gpa: std.mem.Allocator) !DeckSprites {
|
||||||
|
var tilesheet = try TileSheet.init(.{
|
||||||
|
.allocator = gpa,
|
||||||
|
.image_file_contents = @embedFile("./cardsMedium_tilemap.png"),
|
||||||
|
.tile_size = .{ 33, 33 },
|
||||||
|
.texture_options = .{
|
||||||
|
.min_filter = .nearest,
|
||||||
|
.mag_filter = .nearest,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
errdefer tilesheet.deinit();
|
||||||
|
|
||||||
|
var mapping = std.AutoHashMap(Card, u32).init(gpa);
|
||||||
|
errdefer mapping.deinit();
|
||||||
|
try mapping.ensureTotalCapacity(52);
|
||||||
|
|
||||||
|
const hearts_start_index: u32 = 0;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .hearts, .rank = @intCast(rank + 1) },
|
||||||
|
hearts_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const diamonds_start_index: u32 = 15;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .diamonds, .rank = @intCast(rank + 1) },
|
||||||
|
diamonds_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clubs_start_index: u32 = 30;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .clubs, .rank = @intCast(rank + 1) },
|
||||||
|
clubs_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const spades_start_index: u32 = 45;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .spades, .rank = @intCast(rank + 1) },
|
||||||
|
spades_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeckSprites{
|
||||||
|
.tilesheet = tilesheet,
|
||||||
|
.mapping = mapping.unmanaged,
|
||||||
|
.blank = 14,
|
||||||
|
.back = 29,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loadLargeCards(gpa: std.mem.Allocator) !DeckSprites {
|
||||||
|
var tilesheet = try TileSheet.init(.{
|
||||||
|
.allocator = gpa,
|
||||||
|
.image_file_contents = @embedFile("./cardsLarge_tilemap.png"),
|
||||||
|
.tile_size = .{ 65, 65 },
|
||||||
|
.texture_options = .{
|
||||||
|
.min_filter = .nearest,
|
||||||
|
.mag_filter = .nearest,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
errdefer tilesheet.deinit();
|
||||||
|
|
||||||
|
var mapping = std.AutoHashMap(Card, u32).init(gpa);
|
||||||
|
errdefer mapping.deinit();
|
||||||
|
try mapping.ensureTotalCapacity(52);
|
||||||
|
|
||||||
|
const hearts_start_index: u32 = 0;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .hearts, .rank = @intCast(rank + 1) },
|
||||||
|
hearts_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const diamonds_start_index: u32 = 14;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .diamonds, .rank = @intCast(rank + 1) },
|
||||||
|
diamonds_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clubs_start_index: u32 = 28;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .clubs, .rank = @intCast(rank + 1) },
|
||||||
|
clubs_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const spades_start_index: u32 = 42;
|
||||||
|
for (0..13) |rank| {
|
||||||
|
mapping.putAssumeCapacityNoClobber(
|
||||||
|
Card{ .suit = .spades, .rank = @intCast(rank + 1) },
|
||||||
|
spades_start_index + @as(u32, @intCast(rank)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeckSprites{
|
||||||
|
.tilesheet = tilesheet,
|
||||||
|
.mapping = mapping.unmanaged,
|
||||||
|
.blank = 13,
|
||||||
|
.back = 27,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn glfw_framebuffer_size_callback(window: ?*seizer.backend.glfw.c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
fn glfw_framebuffer_size_callback(window: ?*seizer.backend.glfw.c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
||||||
_ = window;
|
_ = window;
|
||||||
gl.viewport(
|
gl.viewport(
|
||||||
|
|
Loading…
Reference in New Issue