Compare commits
No commits in common. "master" and "v1_0" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
.vscode
|
.vscode
|
||||||
zig-cache
|
zig-cache
|
||||||
zig-out
|
zig-out
|
||||||
|
allegro.path
|
||||||
**/*~
|
**/*~
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
**Attention**: make sure the working directory contains the `src/assets/...` directory otherwise the application will crash (reporting a "FailedToLoadBitmap" error).
|
**Attention**: make sure the working directory contains the `src/assets/...` directory otherwise the application will crash (reporting a "FailedToLoadBitmap" error).
|
||||||
|
|
||||||
If you unzip the binaries package or build from sources this means that the root of the zip/sources is your working directory and you're executing `./zig-out/bin/jungle_tale` or `.\zig-out\bin\jungle_tale.exe`.
|
If you unzip the binaries package or build from sources this means that the root of the zip/sources is your working directory and you're executing `./zig-out/bin/tins2023` or `.\zig-out\bin\tins2023.exe`.
|
||||||
|
|
||||||
# Rules
|
# Rules
|
||||||
|
|
||||||
@ -50,13 +50,13 @@ For building you need:
|
|||||||
- A recent (0.11.0-dev) Zig compiler.
|
- A recent (0.11.0-dev) Zig compiler.
|
||||||
- Allegro 5.2.8 development libraries.
|
- Allegro 5.2.8 development libraries.
|
||||||
|
|
||||||
You can use `allegro-dir` build option if your Allegro development libraries can't be natively found. In this file you can put the path to a directory that contains the Allegro `lib`, `bin` and `include` folders.
|
You can use `allegro.path` if your Allegro development libraries can't be natively found. In this file you can put the path to a directory that contains the Allegro `lib`, `bin` and `include` folders.
|
||||||
|
|
||||||
Build:
|
Build:
|
||||||
`zig build`
|
`zig build`
|
||||||
|
|
||||||
And run (after building):
|
And run (after building):
|
||||||
`./zig-out/bin/jungle_tale`
|
`./zig-out/bin/tins2023`
|
||||||
|
|
||||||
Build & run automatically:
|
Build & run automatically:
|
||||||
`zig build run`
|
`zig build run`
|
||||||
|
0
allegro.path
Normal file
0
allegro.path
Normal file
4
allegro/.gitignore
vendored
4
allegro/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
.vscode
|
|
||||||
zig-cache
|
|
||||||
zig-out
|
|
||||||
**/*~
|
|
@ -14,22 +14,22 @@ pub const Bitmap = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawCentered(self: Bitmap, x: f32, y: f32) void {
|
pub fn drawCentered(self: Bitmap, x: f32, y: f32) void {
|
||||||
self.draw(x - 0.5 * self.widthF(), y - 0.5 * self.heightF(), DrawFlags{});
|
self.draw(x - 0.5 * @intToFloat(f32, self.width()), y - 0.5 * @intToFloat(f32, self.height()), DrawFlags{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawCenteredScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void {
|
pub fn drawCenteredScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void {
|
||||||
const w = s * self.widthF();
|
const w = s * @intToFloat(f32, self.width());
|
||||||
const h = s * self.heightF();
|
const h = s * @intToFloat(f32, self.height());
|
||||||
self.drawScaled(x - 0.5 * w, y - 0.5 * h, w, h);
|
self.drawScaled(x - 0.5 * w, y - 0.5 * h, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawScaled(self: Bitmap, x: f32, y: f32, w: f32, h: f32) void {
|
pub fn drawScaled(self: Bitmap, x: f32, y: f32, w: f32, h: f32) void {
|
||||||
drawScaledBitmap(self, 0, 0, self.widthF(), self.heightF(), x, y, w, h, DrawFlags{});
|
drawScaledBitmap(self, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, DrawFlags{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void {
|
pub fn drawScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void {
|
||||||
const sourceW = self.widthF();
|
const sourceW = @intToFloat(f32, self.width());
|
||||||
const sourceH = self.heightF();
|
const sourceH = @intToFloat(f32, self.height());
|
||||||
const scaledW = s * sourceW;
|
const scaledW = s * sourceW;
|
||||||
const scaledH = s * sourceH;
|
const scaledH = s * sourceH;
|
||||||
drawScaledBitmap(self, 0, 0, sourceW, sourceH, x, y, scaledW, scaledH, DrawFlags{});
|
drawScaledBitmap(self, 0, 0, sourceW, sourceH, x, y, scaledW, scaledH, DrawFlags{});
|
||||||
@ -40,22 +40,22 @@ pub const Bitmap = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedCentered(self: Bitmap, tint: Color, x: f32, y: f32) void {
|
pub fn drawTintedCentered(self: Bitmap, tint: Color, x: f32, y: f32) void {
|
||||||
self.drawTinted(tint, x - 0.5 * self.widthF(), y - 0.5 * self.heightF(), DrawFlags{});
|
self.drawTinted(tint, x - 0.5 * @intToFloat(f32, self.width()), y - 0.5 * @intToFloat(f32, self.height()), DrawFlags{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedCenteredScaled(self: Bitmap, tint: Color, x: f32, y: f32, s: f32) void {
|
pub fn drawTintedCenteredScaled(self: Bitmap, tint: Color, x: f32, y: f32, s: f32) void {
|
||||||
const w = s * self.widthF();
|
const w = s * @intToFloat(f32, self.width());
|
||||||
const h = s * self.heightF();
|
const h = s * @intToFloat(f32, self.height());
|
||||||
self.drawTintedScaled(tint, x - 0.5 * w, y - 0.5 * h, w, h);
|
self.drawTintedScaled(tint, x - 0.5 * w, y - 0.5 * h, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedScaled(self: Bitmap, tint: Color, x: f32, y: f32, w: f32, h: f32) void {
|
pub fn drawTintedScaled(self: Bitmap, tint: Color, x: f32, y: f32, w: f32, h: f32) void {
|
||||||
drawTintedScaledBitmap(self, tint, 0, 0, self.widthF(), self.heightF(), x, y, w, h, DrawFlags{});
|
drawTintedScaledBitmap(self, tint, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, DrawFlags{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedScaledUniform(self: Bitmap, tint: Color, x: f32, y: f32, s: f32) void {
|
pub fn drawTintedScaledUniform(self: Bitmap, tint: Color, x: f32, y: f32, s: f32) void {
|
||||||
const sourceW = self.widthF();
|
const sourceW = @intToFloat(f32, self.width());
|
||||||
const sourceH = self.heightF();
|
const sourceH = @intToFloat(f32, self.height());
|
||||||
const scaledW = s * sourceW;
|
const scaledW = s * sourceW;
|
||||||
const scaledH = s * sourceH;
|
const scaledH = s * sourceH;
|
||||||
drawTintedScaledBitmap(self, tint, 0, 0, sourceW, sourceH, x, y, scaledW, scaledH, DrawFlags{});
|
drawTintedScaledBitmap(self, tint, 0, 0, sourceW, sourceH, x, y, scaledW, scaledH, DrawFlags{});
|
||||||
@ -65,10 +65,6 @@ pub const Bitmap = struct {
|
|||||||
return getBitmapHeight(self);
|
return getBitmapHeight(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn heightF(self: Bitmap) f32 {
|
|
||||||
return @as(f32, @floatFromInt(self.height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sub(self: Bitmap, x: i32, y: i32, w: i32, h: i32) !Bitmap {
|
pub fn sub(self: Bitmap, x: i32, y: i32, w: i32, h: i32) !Bitmap {
|
||||||
return createSubBitmap(self, x, y, w, h);
|
return createSubBitmap(self, x, y, w, h);
|
||||||
}
|
}
|
||||||
@ -76,10 +72,6 @@ pub const Bitmap = struct {
|
|||||||
pub fn width(self: Bitmap) i32 {
|
pub fn width(self: Bitmap) i32 {
|
||||||
return getBitmapWidth(self);
|
return getBitmapWidth(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn widthF(self: Bitmap) f32 {
|
|
||||||
return @as(f32, @floatFromInt(self.width()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Color = struct {
|
pub const Color = struct {
|
||||||
@ -87,9 +79,9 @@ pub const Color = struct {
|
|||||||
|
|
||||||
fn hexToU4(hex: u8) u4 {
|
fn hexToU4(hex: u8) u4 {
|
||||||
return switch (hex) {
|
return switch (hex) {
|
||||||
'0'...'9' => @as(u4, @intCast(hex - '0')),
|
'0'...'9' => @intCast(u4, hex - '0'),
|
||||||
'a'...'f' => @as(u4, @intCast(hex - 'a')) + 10,
|
'a'...'f' => @intCast(u4, hex - 'a') + 10,
|
||||||
'A'...'F' => @as(u4, @intCast(hex - 'A')) + 10,
|
'A'...'F' => @intCast(u4, hex - 'A') + 10,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -101,13 +93,13 @@ pub const Color = struct {
|
|||||||
|
|
||||||
if (hex.len < left + 6) unreachable;
|
if (hex.len < left + 6) unreachable;
|
||||||
|
|
||||||
const r = (@as(u8, @intCast(hexToU4(hex[left]))) << 4) + @as(u8, @intCast(hexToU4(hex[left + 1])));
|
const r = (@intCast(u8, hexToU4(hex[left])) << 4) + @intCast(u8, hexToU4(hex[left + 1]));
|
||||||
const g = (@as(u8, @intCast(hexToU4(hex[left + 2]))) << 4) + @as(u8, @intCast(hexToU4(hex[left + 3])));
|
const g = (@intCast(u8, hexToU4(hex[left + 2])) << 4) + @intCast(u8, hexToU4(hex[left + 3]));
|
||||||
const b = (@as(u8, @intCast(hexToU4(hex[left + 4]))) << 4) + @as(u8, @intCast(hexToU4(hex[left + 5])));
|
const b = (@intCast(u8, hexToU4(hex[left + 4])) << 4) + @intCast(u8, hexToU4(hex[left + 5]));
|
||||||
if (hex.len < left + 8) {
|
if (hex.len < left + 8) {
|
||||||
return mapRgb(r, g, b);
|
return mapRgb(r, g, b);
|
||||||
}
|
}
|
||||||
const a = (@as(u8, @intCast(hexToU4(hex[left + 6]))) << 4) + @as(u8, @intCast(hexToU4(hex[left + 7])));
|
const a = (@intCast(u8, hexToU4(hex[left + 6])) << 4) + @intCast(u8, hexToU4(hex[left + 7]));
|
||||||
return mapRgba(r, g, b, a);
|
return mapRgba(r, g, b, a);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -127,21 +119,9 @@ pub const Display = struct {
|
|||||||
return getDisplayHeight(self);
|
return getDisplayHeight(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn heightF(self: Display) f32 {
|
|
||||||
return @as(f32, @floatFromInt(self.height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setTitle(self: Display, title: []const u8) void {
|
|
||||||
setWindowTitle(self, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn width(self: Display) i32 {
|
pub fn width(self: Display) i32 {
|
||||||
return getDisplayWidth(self);
|
return getDisplayWidth(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn widthF(self: Display) f32 {
|
|
||||||
return @as(f32, @floatFromInt(self.width()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DrawFlags = packed struct(c_int) {
|
pub const DrawFlags = packed struct(c_int) {
|
||||||
@ -473,23 +453,23 @@ pub fn destroyTimer(timer: Timer) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawBitmap(bitmap: Bitmap, dx: f32, dy: f32, flags: DrawFlags) void {
|
pub fn drawBitmap(bitmap: Bitmap, dx: f32, dy: f32, flags: DrawFlags) void {
|
||||||
c.al_draw_bitmap(bitmap.native, dx, dy, @as(c_int, @bitCast(flags)));
|
c.al_draw_bitmap(bitmap.native, dx, dy, @bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawScaledBitmap(bitmap: Bitmap, sx: f32, sy: f32, sw: f32, sh: f32, dx: f32, dy: f32, dw: f32, dh: f32, flags: DrawFlags) void {
|
pub fn drawScaledBitmap(bitmap: Bitmap, sx: f32, sy: f32, sw: f32, sh: f32, dx: f32, dy: f32, dw: f32, dh: f32, flags: DrawFlags) void {
|
||||||
c.al_draw_scaled_bitmap(bitmap.native, sx, sy, sw, sh, dx, dy, dw, dh, @as(c_int, @bitCast(flags)));
|
c.al_draw_scaled_bitmap(bitmap.native, sx, sy, sw, sh, dx, dy, dw, dh, @bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawText(font: Font, color: Color, x: f32, y: f32, flags: DrawTextFlags, text: [*:0]const u8) void {
|
pub fn drawText(font: Font, color: Color, x: f32, y: f32, flags: DrawTextFlags, text: [*:0]const u8) void {
|
||||||
c.al_draw_text(font.native, color.native, x, y, @intFromEnum(flags), text);
|
c.al_draw_text(font.native, color.native, x, y, @enumToInt(flags), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedBitmap(bitmap: Bitmap, tint: Color, dx: f32, dy: f32, flags: DrawFlags) void {
|
pub fn drawTintedBitmap(bitmap: Bitmap, tint: Color, dx: f32, dy: f32, flags: DrawFlags) void {
|
||||||
c.al_draw_tinted_bitmap(bitmap.native, tint.native, dx, dy, @as(c_int, @bitCast(flags)));
|
c.al_draw_tinted_bitmap(bitmap.native, tint.native, dx, dy, @bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTintedScaledBitmap(bitmap: Bitmap, tint: Color, sx: f32, sy: f32, sw: f32, sh: f32, dx: f32, dy: f32, dw: f32, dh: f32, flags: DrawFlags) void {
|
pub fn drawTintedScaledBitmap(bitmap: Bitmap, tint: Color, sx: f32, sy: f32, sw: f32, sh: f32, dx: f32, dy: f32, dw: f32, dh: f32, flags: DrawFlags) void {
|
||||||
c.al_draw_tinted_scaled_bitmap(bitmap.native, tint.native, sx, sy, sw, sh, dx, dy, dw, dh, @as(c_int, @bitCast(flags)));
|
c.al_draw_tinted_scaled_bitmap(bitmap.native, tint.native, sx, sy, sw, sh, dx, dy, dw, dh, @bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dropNextEvent(queue: EventQueue) bool {
|
pub fn dropNextEvent(queue: EventQueue) bool {
|
||||||
@ -541,7 +521,7 @@ pub fn getDisplayEventSource(display: Display) EventSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisplayFlags(display: Display) NewDisplayFlags {
|
pub fn getDisplayFlags(display: Display) NewDisplayFlags {
|
||||||
return @as(NewDisplayFlags, @bitCast(c.al_get_display_flags(display.native)));
|
return @bitCast(NewDisplayFlags, c.al_get_display_flags(display.native));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDisplayHeight(display: Display) i32 {
|
pub fn getDisplayHeight(display: Display) i32 {
|
||||||
@ -573,7 +553,7 @@ pub fn getNewBitmapFlags() NewBitmapFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNewDisplayOption(option: NewDisplayOption, importance: *OptionImportance) c_int {
|
pub fn getNewDisplayOption(option: NewDisplayOption, importance: *OptionImportance) c_int {
|
||||||
return c.al_get_new_display_option(@intFromEnum(option), @as(*c_int, @ptrCast(importance)));
|
return c.al_get_new_display_option(@enumToInt(option), @ptrCast(*c_int, importance));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNewBitmapFormat() PixelFormat {
|
pub fn getNewBitmapFormat() PixelFormat {
|
||||||
@ -661,7 +641,7 @@ pub fn loadFont(path: [*:0]const u8, size: i32, flags: c_int) !Font {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn loadTtfFont(path: [*:0]const u8, size: i32, flags: LoadTtfFontFlags) !Font {
|
pub fn loadTtfFont(path: [*:0]const u8, size: i32, flags: LoadTtfFontFlags) !Font {
|
||||||
const font = c.al_load_ttf_font(path, size, @as(c_int, @bitCast(flags)));
|
const font = c.al_load_ttf_font(path, size, @bitCast(c_int, flags));
|
||||||
if (font) |native| {
|
if (font) |native| {
|
||||||
return Font{ .native = native };
|
return Font{ .native = native };
|
||||||
}
|
}
|
||||||
@ -685,7 +665,7 @@ pub fn mapRgbF(r: f32, g: f32, b: f32) Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn openMemfile(data: []u8, mode: []const u8) !File {
|
pub fn openMemfile(data: []u8, mode: []const u8) !File {
|
||||||
const file = c.al_open_memfile(&data[0], @as(i64, @intCast(data.len)), &mode[0]);
|
const file = c.al_open_memfile(&data[0], @intCast(i64, data.len), &mode[0]);
|
||||||
if (file) |native| {
|
if (file) |native| {
|
||||||
return File{ .native = native };
|
return File{ .native = native };
|
||||||
}
|
}
|
||||||
@ -709,11 +689,11 @@ pub fn saveBitmapF(file: File, ident: []const u8, bitmap: Bitmap) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisplayFlag(display: Display, flag: NewDisplayFlags, on: bool) bool {
|
pub fn setDisplayFlag(display: Display, flag: NewDisplayFlags, on: bool) bool {
|
||||||
return c.al_set_display_flag(display.native, @as(c_int, @bitCast(flag)), on);
|
return c.al_set_display_flag(display.native, @bitCast(c_int, flag), on);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setNewBitmapFlags(flags: NewBitmapFlags) void {
|
pub fn setNewBitmapFlags(flags: NewBitmapFlags) void {
|
||||||
c.al_set_new_bitmap_flags(@as(c_int, @bitCast(flags)));
|
c.al_set_new_bitmap_flags(@bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setNewBitmapFormat(format: PixelFormat) void {
|
pub fn setNewBitmapFormat(format: PixelFormat) void {
|
||||||
@ -721,15 +701,11 @@ pub fn setNewBitmapFormat(format: PixelFormat) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setNewDisplayFlags(flags: NewDisplayFlags) void {
|
pub fn setNewDisplayFlags(flags: NewDisplayFlags) void {
|
||||||
c.al_set_new_display_flags(@as(c_int, @bitCast(flags)));
|
c.al_set_new_display_flags(@bitCast(c_int, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setNewDisplayOption(option: NewDisplayOption, value: i32, importance: OptionImportance) void {
|
pub fn setNewDisplayOption(option: NewDisplayOption, value: i32, importance: OptionImportance) void {
|
||||||
c.al_set_new_display_option(@intFromEnum(option), value, @intFromEnum(importance));
|
c.al_set_new_display_option(@enumToInt(option), value, @enumToInt(importance));
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setNewWindowTitle(title: []const u8) void {
|
|
||||||
c.al_set_new_window_title(&title[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setTargetBitmap(bitmap: Bitmap) void {
|
pub fn setTargetBitmap(bitmap: Bitmap) void {
|
||||||
@ -740,10 +716,6 @@ pub fn setTargetBackbuffer(display: Display) void {
|
|||||||
c.al_set_target_bitmap(display.native);
|
c.al_set_target_bitmap(display.native);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setWindowTitle(display: Display, title: []const u8) void {
|
|
||||||
c.al_set_window_title(display.native, &title[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn startTimer(timer: Timer) void {
|
pub fn startTimer(timer: Timer) void {
|
||||||
c.al_start_timer(timer.native);
|
c.al_start_timer(timer.native);
|
||||||
}
|
}
|
@ -8,88 +8,17 @@ const cwd = std.fs.path.dirname(current_file()).?;
|
|||||||
const path_separator = std.fs.path.sep_str;
|
const path_separator = std.fs.path.sep_str;
|
||||||
|
|
||||||
/// add this package to exe
|
/// add this package to exe
|
||||||
pub fn addModule(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) void {
|
pub fn addTo(comptime allegro_dir: []const u8, exe: *std.build.LibExeObjStep) void {
|
||||||
// _ = b.addStaticLibrary(.{
|
exe.addAnonymousModule("allegro", .{ .source_file = .{ .path = cwd ++ path_separator ++ "allegro.zig" } });
|
||||||
// .name = "allegro",
|
if (allegro_dir.len > 0) {
|
||||||
// .root_source_file = .{ .path = cwd ++ path_separator ++ "allegro.zig" },
|
exe.addIncludePath(allegro_dir ++ path_separator ++ "include");
|
||||||
// .target = target,
|
exe.addLibraryPath(allegro_dir ++ path_separator ++ "lib");
|
||||||
// .optimize = optimize,
|
}
|
||||||
// });
|
exe.linkLibC();
|
||||||
_ = b.addModule("allegro", .{
|
|
||||||
.root_source_file = .{ .path = cwd ++ path_separator ++ "allegro.zig" },
|
exe.linkSystemLibrary("allegro");
|
||||||
.target = target,
|
exe.linkSystemLibrary("allegro_font");
|
||||||
.optimize = optimize,
|
exe.linkSystemLibrary("allegro_image");
|
||||||
});
|
exe.linkSystemLibrary("allegro_memfile");
|
||||||
}
|
exe.linkSystemLibrary("allegro_ttf");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const static = false;
|
|
||||||
|
|
||||||
// Expose this as a module that others can import
|
|
||||||
var module = b.addModule("allegro", .{
|
|
||||||
.root_source_file = .{ .path = "src/allegro.zig" },
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const allegro_dir = b.option([]const u8, "allegro-dir", "path to a directory that contains the Allegro `lib`, `bin` and `include` folders") orelse "";
|
|
||||||
if (allegro_dir.len != 0) {
|
|
||||||
module.addIncludePath(.{ .path = b.pathJoin(&[_][]const u8{ allegro_dir, "include" }) });
|
|
||||||
module.addLibraryPath(.{ .path = b.pathJoin(&[_][]const u8{ allegro_dir, "lib" }) });
|
|
||||||
}
|
|
||||||
|
|
||||||
module.link_libc = true;
|
|
||||||
|
|
||||||
if (static) {
|
|
||||||
module.linkSystemLibrary("allegro-static", .{});
|
|
||||||
module.linkSystemLibrary("allegro_font-static", .{});
|
|
||||||
module.linkSystemLibrary("allegro_image-static", .{});
|
|
||||||
module.linkSystemLibrary("allegro_memfile-static", .{});
|
|
||||||
module.linkSystemLibrary("allegro_ttf-static", .{});
|
|
||||||
module.linkSystemLibrary("dumb", .{});
|
|
||||||
module.linkSystemLibrary("FLAC", .{});
|
|
||||||
module.linkSystemLibrary("freetype", .{});
|
|
||||||
module.linkSystemLibrary("jpeg", .{});
|
|
||||||
module.linkSystemLibrary("ogg", .{});
|
|
||||||
module.linkSystemLibrary("opus", .{});
|
|
||||||
module.linkSystemLibrary("opusfile", .{});
|
|
||||||
module.linkSystemLibrary("physfs", .{});
|
|
||||||
module.linkSystemLibrary("png16", .{});
|
|
||||||
// module.linkSystemLibrary("theoradec", .{});
|
|
||||||
module.linkSystemLibrary("vorbis", .{});
|
|
||||||
module.linkSystemLibrary("vorbisfile", .{});
|
|
||||||
module.linkSystemLibrary("webp", .{});
|
|
||||||
module.linkSystemLibrary("webpdecoder", .{});
|
|
||||||
module.linkSystemLibrary("webpdemux", .{});
|
|
||||||
module.linkSystemLibrary("zlib", .{});
|
|
||||||
module.linkSystemLibrary("opengl32", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
if (target.result.os.tag == .windows) {
|
|
||||||
module.linkSystemLibrary("gdi32", .{});
|
|
||||||
module.linkSystemLibrary("ole32", .{});
|
|
||||||
module.linkSystemLibrary("shlwapi", .{});
|
|
||||||
module.linkSystemLibrary("winmm", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
// module.linkSystemLibrary("", .{});
|
|
||||||
if (target.result.isGnu()) {
|
|
||||||
// module.linkSystemLibrary("stdc++", .{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
module.linkSystemLibrary("allegro.dll", .{});
|
|
||||||
module.linkSystemLibrary("allegro_font.dll", .{});
|
|
||||||
module.linkSystemLibrary("allegro_image.dll", .{});
|
|
||||||
module.linkSystemLibrary("allegro_memfile.dll", .{});
|
|
||||||
module.linkSystemLibrary("allegro_ttf.dll", .{});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = "allegro",
|
|
||||||
.version = "0.1.0",
|
|
||||||
.paths = .{
|
|
||||||
"build.zig",
|
|
||||||
"build.zig.zon",
|
|
||||||
"src",
|
|
||||||
},
|
|
||||||
}
|
|
19
build.zig
19
build.zig
@ -1,4 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const allegro = @import("allegro/build.zig");
|
||||||
|
|
||||||
|
const allegroPath = @embedFile("allegro.path");
|
||||||
|
|
||||||
// Although this function looks imperative, note that its job is to
|
// Although this function looks imperative, note that its job is to
|
||||||
// declaratively construct a build graph that will be executed by an external
|
// declaratively construct a build graph that will be executed by an external
|
||||||
@ -16,7 +19,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "jungle_tale",
|
.name = "tins2023",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
@ -24,6 +27,8 @@ pub fn build(b: *std.Build) void {
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
allegro.addTo(allegroPath, exe);
|
||||||
|
|
||||||
// This declares intent for the executable to be installed into the
|
// This declares intent for the executable to be installed into the
|
||||||
// standard location when the user invokes the "install" step (the default
|
// standard location when the user invokes the "install" step (the default
|
||||||
// step when running `zig build`).
|
// step when running `zig build`).
|
||||||
@ -40,18 +45,6 @@ pub fn build(b: *std.Build) void {
|
|||||||
// files, this ensures they will be present and in the expected location.
|
// files, this ensures they will be present and in the expected location.
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
const allegro_dep = b.dependency("allegro", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
const allegro_mod = allegro_dep.module("allegro");
|
|
||||||
const allegro_dir = b.option([]const u8, "allegro-dir", "path to a directory that contains the Allegro `lib`, `bin` and `include` folders") orelse "";
|
|
||||||
if (allegro_dir.len != 0) {
|
|
||||||
allegro_mod.addIncludePath(.{ .path = b.pathJoin(&[_][]const u8{ allegro_dir, "include" }) });
|
|
||||||
allegro_mod.addLibraryPath(.{ .path = b.pathJoin(&[_][]const u8{ allegro_dir, "lib" }) });
|
|
||||||
}
|
|
||||||
exe.root_module.addImport("allegro", allegro_mod);
|
|
||||||
|
|
||||||
// This allows the user to pass arguments to the application in the build
|
// This allows the user to pass arguments to the application in the build
|
||||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||||
if (b.args) |args| {
|
if (b.args) |args| {
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = "tins2023",
|
|
||||||
.version = "0.1.0",
|
|
||||||
.paths = .{
|
|
||||||
"build.zig",
|
|
||||||
"build.zig.zon",
|
|
||||||
"README.md",
|
|
||||||
"src",
|
|
||||||
},
|
|
||||||
.dependencies = .{
|
|
||||||
.allegro = .{
|
|
||||||
.path = "allegro",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 174 KiB |
Binary file not shown.
Before Width: | Height: | Size: 248 KiB |
BIN
src/assets/images/title_untitled.png
Normal file
BIN
src/assets/images/title_untitled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@ -1,6 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const allegro = @import("allegro");
|
const allegro = @import("allegro");
|
||||||
const engine = @import("engine.zig");
|
const engine = @import("engine.zig");
|
||||||
|
const paths = @import("paths.zig");
|
||||||
const Palette = @import("palette.zig").Palette;
|
const Palette = @import("palette.zig").Palette;
|
||||||
const Scene = @import("scene.zig").Scene;
|
const Scene = @import("scene.zig").Scene;
|
||||||
const Renderer = @import("renderer.zig").Renderer;
|
const Renderer = @import("renderer.zig").Renderer;
|
||||||
@ -49,7 +50,6 @@ pub const Context = struct {
|
|||||||
// allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLE_BUFFERS, 1, allegro.OptionImportance.REQUIRE);
|
// allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLE_BUFFERS, 1, allegro.OptionImportance.REQUIRE);
|
||||||
// allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLES, 4, allegro.OptionImportance.REQUIRE);
|
// allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLES, 4, allegro.OptionImportance.REQUIRE);
|
||||||
allegro.setNewDisplayFlags(allegro.NewDisplayFlags{ .RESIZABLE = true });
|
allegro.setNewDisplayFlags(allegro.NewDisplayFlags{ .RESIZABLE = true });
|
||||||
allegro.setNewWindowTitle("Jungle Tale");
|
|
||||||
const display = try allegro.createDisplay(DefaultDisplayWidth, DefaultDisplayHeight);
|
const display = try allegro.createDisplay(DefaultDisplayWidth, DefaultDisplayHeight);
|
||||||
|
|
||||||
events.registerDisplay(display);
|
events.registerDisplay(display);
|
||||||
@ -65,13 +65,6 @@ pub const Context = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enterScene(self: *Context, scene: Scene) void {
|
|
||||||
self.exitScene();
|
|
||||||
|
|
||||||
self.scene = scene;
|
|
||||||
scene.enter(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exitScene(self: *Context) void {
|
fn exitScene(self: *Context) void {
|
||||||
if (self.scene) |scene| {
|
if (self.scene) |scene| {
|
||||||
scene.exit(self);
|
scene.exit(self);
|
||||||
@ -86,12 +79,25 @@ pub const Context = struct {
|
|||||||
self.events.destroy();
|
self.events.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn registerFonts(self: *Context) !void {
|
||||||
|
const viewport = self.renderer.viewport;
|
||||||
|
const fonts = &self.renderer.fonts;
|
||||||
|
try fonts.addFromFileTTF("default", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(32));
|
||||||
|
try fonts.addFromFileTTF("small", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(16));
|
||||||
|
try fonts.addFromFileTTF("extra-small", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(12));
|
||||||
|
try fonts.addFromFileTTF("large", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(64));
|
||||||
|
try fonts.addFromFileTTF("debug", paths.AssetsDir ++ "/fonts/Cabin-Regular.ttf", viewport.scaledInteger(16));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn quit(self: *Context) void {
|
pub fn quit(self: *Context) void {
|
||||||
self.shouldQuit = true;
|
self.shouldQuit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn switchToScene(self: *Context, comptime SceneType: type) !void {
|
pub fn switchToScene(self: *Context, comptime SceneType: type, build: ?*const fn (*SceneType) void) !void {
|
||||||
const scene = try Scene.init(SceneType, self.allocator);
|
self.exitScene();
|
||||||
self.enterScene(scene);
|
|
||||||
|
const scene = try Scene.init(SceneType, self.allocator, build);
|
||||||
|
self.scene = scene;
|
||||||
|
scene.enter(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -109,13 +109,13 @@ pub const Sprite = struct {
|
|||||||
|
|
||||||
const horizontal = @divTrunc(bitmapWidth, width);
|
const horizontal = @divTrunc(bitmapWidth, width);
|
||||||
const vertical = @divTrunc(bitmapHeight, height);
|
const vertical = @divTrunc(bitmapHeight, height);
|
||||||
const n = @as(usize, @intCast(horizontal * vertical));
|
const n = @intCast(usize, horizontal * vertical);
|
||||||
const frames = try allocator.alloc(allegro.Bitmap, n);
|
const frames = try allocator.alloc(allegro.Bitmap, n);
|
||||||
var i: i32 = 0;
|
var i: i32 = 0;
|
||||||
while (i < n) : (i += 1) {
|
while (i < n) : (i += 1) {
|
||||||
const left = @mod(i, horizontal) * width;
|
const left = @mod(i, horizontal) * width;
|
||||||
const top = @divTrunc(i, horizontal) * height;
|
const top = @divTrunc(i, horizontal) * height;
|
||||||
frames[@as(usize, @intCast(i))] = try bitmap.sub(left, top, width, height);
|
frames[@intCast(usize, i)] = try bitmap.sub(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sprite{
|
return Sprite{
|
||||||
|
@ -22,6 +22,6 @@ pub const FPS = struct {
|
|||||||
pub fn fps(self: FPS) usize {
|
pub fn fps(self: FPS) usize {
|
||||||
if (self.framesCounted == 0) return 0;
|
if (self.framesCounted == 0) return 0;
|
||||||
|
|
||||||
return @as(usize, @intFromFloat(@as(f32, @floatFromInt(self.framesCounted)) / self.total));
|
return @floatToInt(usize, @intToFloat(f32, self.framesCounted) / self.total);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
|
|
||||||
pub const OpaquePtr = struct {
|
pub const OpaquePtr = struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
ptr: usize = undefined,
|
object: usize = undefined,
|
||||||
virtualTable: VirtualTable = undefined,
|
virtualTable: VirtualTable = undefined,
|
||||||
|
|
||||||
const VirtualTable = struct {
|
const VirtualTable = struct {
|
||||||
@ -13,37 +13,28 @@ pub const OpaquePtr = struct {
|
|||||||
pub fn Object(comptime Type: type) type {
|
pub fn Object(comptime Type: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
ptr: *Type,
|
ptr: *Type,
|
||||||
opaque_ptr: OpaquePtr,
|
opaquePtr: OpaquePtr,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(comptime Type: type, allocator: Allocator) !OpaquePtr {
|
pub fn create(comptime Type: type, allocator: Allocator) !Object(Type) {
|
||||||
const ptr = try allocator.create(Type);
|
const ptr = try allocator.create(Type);
|
||||||
return OpaquePtr.init(Type, allocator, ptr);
|
const opaq = OpaquePtr{
|
||||||
}
|
|
||||||
|
|
||||||
pub fn createObject(comptime Type: type, allocator: Allocator) !Object(Type) {
|
|
||||||
const ptr = try allocator.create(Type);
|
|
||||||
const opaq = OpaquePtr.init(Type, allocator, ptr);
|
|
||||||
return Object(Type){
|
|
||||||
.ptr = ptr,
|
|
||||||
.opaque_ptr = opaq,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(comptime Type: type, allocator: Allocator, ptr: *Type) OpaquePtr {
|
|
||||||
return OpaquePtr{
|
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.ptr = @intFromPtr(ptr),
|
.object = @ptrToInt(ptr),
|
||||||
.virtualTable = .{
|
.virtualTable = .{
|
||||||
.destroy = struct {
|
.destroy = struct {
|
||||||
fn destroy(self: OpaquePtr) void {
|
fn destroy(self: OpaquePtr) void {
|
||||||
const p = @as(*Type, @ptrFromInt(self.ptr));
|
const object = @intToPtr(*Type, self.object);
|
||||||
self.allocator.destroy(p);
|
self.allocator.destroy(object);
|
||||||
}
|
}
|
||||||
}.destroy,
|
}.destroy,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
return Object(Type){
|
||||||
|
.ptr = ptr,
|
||||||
|
.opaquePtr = opaq,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(self: OpaquePtr) void {
|
pub fn destroy(self: OpaquePtr) void {
|
||||||
|
@ -13,7 +13,7 @@ pub const Point = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn initUsize(x: usize, y: usize) Point {
|
pub fn initUsize(x: usize, y: usize) Point {
|
||||||
return Point.init(@as(i64, @intCast(x)), @as(i64, @intCast(y)));
|
return Point.init(@intCast(i64, x), @intCast(i64, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self: Point, other: Point) Point {
|
pub fn add(self: Point, other: Point) Point {
|
||||||
@ -31,7 +31,7 @@ pub const Point = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn float(self: Point) PointF {
|
pub fn float(self: Point) PointF {
|
||||||
return PointF{ .x = @as(f32, @floatFromInt(self.x)), .y = @as(f32, @floatFromInt(self.y)) };
|
return PointF{ .x = @intToFloat(f32, self.x), .y = @intToFloat(f32, self.y) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multiply(self: Point, factor: i64) Point {
|
pub fn multiply(self: Point, factor: i64) Point {
|
||||||
|
@ -37,7 +37,7 @@ pub const PointF = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn integer(self: PointF) Point {
|
pub fn integer(self: PointF) Point {
|
||||||
return Point{ .x = @as(i64, @intFromFloat(self.x)), .y = @as(i64, @intFromFloat(self.y)) };
|
return Point{ .x = @floatToInt(i64, self.x), .y = @floatToInt(i64, self.y) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multiply(self: PointF, factor: f32) PointF {
|
pub fn multiply(self: PointF, factor: f32) PointF {
|
||||||
|
@ -5,9 +5,9 @@ pub fn Scene(comptime Context: type, comptime Event: type) type {
|
|||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
scene_ptr: usize = undefined,
|
object: usize = undefined,
|
||||||
virtualTable: VirtualTable = undefined,
|
virtualTable: VirtualTable = undefined,
|
||||||
opaque_ptr: ?OpaquePtr = null,
|
opaquePtr: ?OpaquePtr = null,
|
||||||
|
|
||||||
const VirtualTable = struct {
|
const VirtualTable = struct {
|
||||||
enter: *const fn (Self, *Context) void,
|
enter: *const fn (Self, *Context) void,
|
||||||
@ -37,81 +37,52 @@ pub fn Scene(comptime Context: type, comptime Event: type) type {
|
|||||||
self.virtualTable.tick(self, ctx, t, dt);
|
self.virtualTable.tick(self, ctx, t, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Builder(comptime SceneType: type) type {
|
pub fn makeOpaque(comptime SceneType: type, object: *SceneType) Self {
|
||||||
return struct {
|
return Self{ .object = @ptrToInt(object), .virtualTable = .{
|
||||||
const SelfBuilder = @This();
|
|
||||||
|
|
||||||
pub const Object = struct {
|
|
||||||
ptr: *SceneType,
|
|
||||||
opaque_ptr: Scene,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !Self {
|
|
||||||
const ptr = try OpaquePtr.create(SceneType, allocator);
|
|
||||||
return SelfBuilder.initOpaque(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initBuild(allocator: std.mem.Allocator, build: *const fn (*SceneType) void) !Self {
|
|
||||||
const ptr = try OpaquePtr.createObject(SceneType, allocator);
|
|
||||||
build(ptr.ptr);
|
|
||||||
return SelfBuilder.initOpaque(ptr.opaque_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initObject(allocator: std.mem.Allocator) !Object {
|
|
||||||
const ptr = try OpaquePtr.createObject(SceneType, allocator);
|
|
||||||
return Object{
|
|
||||||
.ptr = ptr.ptr,
|
|
||||||
.opaque_ptr = SelfBuilder.initOpaque(ptr.opaque_ptr),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initOpaque(ptr: OpaquePtr) Self {
|
|
||||||
return Self{
|
|
||||||
.scene_ptr = ptr.ptr,
|
|
||||||
.virtualTable = .{
|
|
||||||
.enter = struct {
|
.enter = struct {
|
||||||
fn enter(self: Self, ctx: *Context) void {
|
fn enter(self: Self, ctx: *Context) void {
|
||||||
const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr));
|
const scene = @intToPtr(*SceneType, self.object);
|
||||||
scene.enter(ctx);
|
scene.enter(ctx);
|
||||||
}
|
}
|
||||||
}.enter,
|
}.enter,
|
||||||
.exit = struct {
|
.exit = struct {
|
||||||
fn exit(self: Self, ctx: *Context) void {
|
fn exit(self: Self, ctx: *Context) void {
|
||||||
const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr));
|
const scene = @intToPtr(*SceneType, self.object);
|
||||||
scene.exit(ctx);
|
scene.exit(ctx);
|
||||||
}
|
}
|
||||||
}.exit,
|
}.exit,
|
||||||
.handle = struct {
|
.handle = struct {
|
||||||
fn handle(self: Self, ctx: *Context, event: Event) !void {
|
fn handle(self: Self, ctx: *Context, event: Event) !void {
|
||||||
const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr));
|
const scene = @intToPtr(*SceneType, self.object);
|
||||||
try scene.handle(ctx, event);
|
try scene.handle(ctx, event);
|
||||||
}
|
}
|
||||||
}.handle,
|
}.handle,
|
||||||
.tick = struct {
|
.tick = struct {
|
||||||
fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void {
|
fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void {
|
||||||
const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr));
|
const scene = @intToPtr(*SceneType, self.object);
|
||||||
scene.tick(ctx, t, dt);
|
scene.tick(ctx, t, dt);
|
||||||
}
|
}
|
||||||
}.tick,
|
}.tick,
|
||||||
.render = struct {
|
.render = struct {
|
||||||
fn render(self: Self, ctx: *Context) void {
|
fn render(self: Self, ctx: *Context) void {
|
||||||
const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr));
|
const scene = @intToPtr(*SceneType, self.object);
|
||||||
scene.render(ctx);
|
scene.render(ctx);
|
||||||
}
|
}
|
||||||
}.render,
|
}.render,
|
||||||
},
|
} };
|
||||||
.opaque_ptr = ptr,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(comptime SceneType: type, allocator: std.mem.Allocator) !Self {
|
pub fn init(comptime SceneType: type, allocator: std.mem.Allocator, build: ?*const fn (*SceneType) void) !Self {
|
||||||
return Builder(SceneType).init(allocator);
|
const object = try OpaquePtr.create(SceneType, allocator);
|
||||||
|
var scene = Self.makeOpaque(SceneType, object.ptr);
|
||||||
|
if (build) |b| {
|
||||||
|
b(object.ptr);
|
||||||
|
}
|
||||||
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: Self) void {
|
pub fn deinit(self: Self) void {
|
||||||
if (self.opaque_ptr) |ptr| {
|
if (self.opaquePtr) |ptr| {
|
||||||
ptr.destroy();
|
ptr.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ pub const Viewport = struct {
|
|||||||
.actualHeight = height,
|
.actualHeight = height,
|
||||||
.scaledWidth = width,
|
.scaledWidth = width,
|
||||||
.scaledHeight = height,
|
.scaledHeight = height,
|
||||||
.bounds = RectangleF.initRelative(0, 0, @as(f32, @floatFromInt(width)), @as(f32, @floatFromInt(height))),
|
.bounds = RectangleF.initRelative(0, 0, @intToFloat(f32, width), @intToFloat(f32, height)),
|
||||||
.scale = 1.0,
|
.scale = 1.0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ pub const Viewport = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn scaledInteger(self: Viewport, i: i32) i32 {
|
pub fn scaledInteger(self: Viewport, i: i32) i32 {
|
||||||
return @as(i32, @intFromFloat(std.math.round(@as(f32, @floatFromInt(i)) * self.scale)));
|
return @floatToInt(i32, std.math.round(@intToFloat(f32, i) * self.scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn viewToScreen(self: Viewport, x: f32, y: f32) PointF {
|
pub fn viewToScreen(self: Viewport, x: f32, y: f32) PointF {
|
||||||
@ -49,25 +49,20 @@ pub const Viewport = struct {
|
|||||||
self.actualWidth = width;
|
self.actualWidth = width;
|
||||||
self.actualHeight = height;
|
self.actualHeight = height;
|
||||||
|
|
||||||
const widthF = @as(f32, @floatFromInt(width));
|
const horizontalRatio = @intToFloat(f32, width) / @intToFloat(f32, self.unscaledWidth);
|
||||||
const heightF = @as(f32, @floatFromInt(height));
|
const verticalRatio = @intToFloat(f32, height) / @intToFloat(f32, self.unscaledHeight);
|
||||||
const unscaledWidthF = @as(f32, @floatFromInt(self.unscaledWidth));
|
|
||||||
const unscaledHeightF = @as(f32, @floatFromInt(self.unscaledHeight));
|
|
||||||
|
|
||||||
const horizontalRatio = widthF / unscaledWidthF;
|
|
||||||
const verticalRatio = heightF / unscaledHeightF;
|
|
||||||
|
|
||||||
if (horizontalRatio < verticalRatio) {
|
if (horizontalRatio < verticalRatio) {
|
||||||
self.scaledWidth = width;
|
self.scaledWidth = width;
|
||||||
self.scaledHeight = @as(i32, @intFromFloat(horizontalRatio * unscaledHeightF));
|
self.scaledHeight = @floatToInt(i32, horizontalRatio * @intToFloat(f32, self.unscaledHeight));
|
||||||
const top = @divFloor(height - self.scaledHeight, 2);
|
const top = @divFloor(height - self.scaledHeight, 2);
|
||||||
self.bounds = RectangleF.initRelative(0, @as(f32, @floatFromInt(top)), widthF, @as(f32, @floatFromInt(self.scaledHeight)));
|
self.bounds = RectangleF.initRelative(0, @intToFloat(f32, top), @intToFloat(f32, width), @intToFloat(f32, self.scaledHeight));
|
||||||
self.scale = horizontalRatio;
|
self.scale = horizontalRatio;
|
||||||
} else {
|
} else {
|
||||||
self.scaledWidth = @as(i32, @intFromFloat(verticalRatio * unscaledWidthF));
|
self.scaledWidth = @floatToInt(i32, verticalRatio * @intToFloat(f32, self.unscaledWidth));
|
||||||
self.scaledHeight = height;
|
self.scaledHeight = height;
|
||||||
const left = @divFloor(width - self.scaledWidth, 2);
|
const left = @divFloor(width - self.scaledWidth, 2);
|
||||||
self.bounds = RectangleF.initRelative(@as(f32, @floatFromInt(left)), 0, @as(f32, @floatFromInt(self.scaledWidth)), heightF);
|
self.bounds = RectangleF.initRelative(@intToFloat(f32, left), 0, @intToFloat(f32, self.scaledWidth), @intToFloat(f32, height));
|
||||||
self.scale = verticalRatio;
|
self.scale = verticalRatio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ pub const Animation = struct {
|
|||||||
pub fn tick(self: *Animation, t: f32) void {
|
pub fn tick(self: *Animation, t: f32) void {
|
||||||
const delta = t - self.lastUpdate;
|
const delta = t - self.lastUpdate;
|
||||||
|
|
||||||
const skip = @as(usize, @intFromFloat(@divFloor(delta, self.interval)));
|
const skip = @floatToInt(usize, @divFloor(delta, self.interval));
|
||||||
self.lastUpdate = t - @rem(delta, self.interval);
|
self.lastUpdate = t - @rem(delta, self.interval);
|
||||||
|
|
||||||
self.current = self.currentOffset(skip);
|
self.current = self.currentOffset(skip);
|
||||||
|
@ -111,17 +111,17 @@ pub const Game = struct {
|
|||||||
self.playerVelocity.y = 0.1;
|
self.playerVelocity.y = 0.1;
|
||||||
}
|
}
|
||||||
if (self.playerVelocity.x != 0) {
|
if (self.playerVelocity.x != 0) {
|
||||||
const playerTileTop = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.y)));
|
const playerTileTop = @floatToInt(i64, std.math.floor(self.playerPosition.y));
|
||||||
const playerTileBottom = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.y + 0.99)));
|
const playerTileBottom = @floatToInt(i64, std.math.floor(self.playerPosition.y + 0.99));
|
||||||
if (self.playerVelocity.x < 0) {
|
if (self.playerVelocity.x < 0) {
|
||||||
const playerTileLeft = @as(i64, @intFromFloat(std.math.ceil(self.playerPosition.x))) - 1;
|
const playerTileLeft = @floatToInt(i64, std.math.ceil(self.playerPosition.x)) - 1;
|
||||||
if (self.level.tiles.get(playerTileLeft, playerTileTop) != null or self.level.tiles.get(playerTileLeft, playerTileBottom) != null) {
|
if (self.level.tiles.get(playerTileLeft, playerTileTop) != null or self.level.tiles.get(playerTileLeft, playerTileBottom) != null) {
|
||||||
self.playerPosition.x = std.math.ceil(self.playerPosition.x);
|
self.playerPosition.x = std.math.ceil(self.playerPosition.x);
|
||||||
self.playerVelocity.x = 0;
|
self.playerVelocity.x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self.playerVelocity.x > 0) {
|
if (self.playerVelocity.x > 0) {
|
||||||
const playerTileRight = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.x))) + 1;
|
const playerTileRight = @floatToInt(i64, std.math.floor(self.playerPosition.x)) + 1;
|
||||||
if (self.level.tiles.get(playerTileRight, playerTileTop) != null or self.level.tiles.get(playerTileRight, playerTileBottom) != null) {
|
if (self.level.tiles.get(playerTileRight, playerTileTop) != null or self.level.tiles.get(playerTileRight, playerTileBottom) != null) {
|
||||||
self.playerPosition.x = std.math.floor(self.playerPosition.x);
|
self.playerPosition.x = std.math.floor(self.playerPosition.x);
|
||||||
self.playerVelocity.x = 0;
|
self.playerVelocity.x = 0;
|
||||||
@ -158,17 +158,17 @@ pub const Game = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn playerIsOnTile(self: Game) bool {
|
pub fn playerIsOnTile(self: Game) bool {
|
||||||
const playerTileHeight = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.y))) + 1;
|
const playerTileHeight = @floatToInt(i64, std.math.floor(self.playerPosition.y)) + 1;
|
||||||
const playerTileLeft = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.x + 0.5)));
|
const playerTileLeft = @floatToInt(i64, std.math.floor(self.playerPosition.x + 0.5));
|
||||||
const playerTileRight = @as(i64, @intFromFloat(std.math.ceil(self.playerPosition.x - 0.5)));
|
const playerTileRight = @floatToInt(i64, std.math.ceil(self.playerPosition.x - 0.5));
|
||||||
|
|
||||||
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn playerIsUnderTile(self: Game) bool {
|
pub fn playerIsUnderTile(self: Game) bool {
|
||||||
const playerTileHeight = @as(i64, @intFromFloat(std.math.ceil(self.playerPosition.y))) - 1;
|
const playerTileHeight = @floatToInt(i64, std.math.ceil(self.playerPosition.y)) - 1;
|
||||||
const playerTileLeft = @as(i64, @intFromFloat(std.math.floor(self.playerPosition.x + 0.5)));
|
const playerTileLeft = @floatToInt(i64, std.math.floor(self.playerPosition.x + 0.5));
|
||||||
const playerTileRight = @as(i64, @intFromFloat(std.math.ceil(self.playerPosition.x - 0.5)));
|
const playerTileRight = @floatToInt(i64, std.math.ceil(self.playerPosition.x - 0.5));
|
||||||
|
|
||||||
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ pub const Level = struct {
|
|||||||
defer y += 1;
|
defer y += 1;
|
||||||
|
|
||||||
for (line, 0..) |tile, column| {
|
for (line, 0..) |tile, column| {
|
||||||
const x = @as(i64, @intCast(column));
|
var x = @intCast(i64, column);
|
||||||
switch (tile) {
|
switch (tile) {
|
||||||
'P' => character = engine.pt(x, y),
|
'P' => character = engine.pt(x, y),
|
||||||
'S' => try collectables.set(x, y, .Star),
|
'S' => try collectables.set(x, y, .Star),
|
||||||
|
@ -56,11 +56,11 @@ pub const GameScene = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_LEFT)) {
|
if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_LEFT)) {
|
||||||
self.game.playerVelocity.x = @max(-maxHorizontalWalkVelocity, self.game.playerVelocity.x - horizontalWalkAcceleration);
|
self.game.playerVelocity.x = std.math.max(-maxHorizontalWalkVelocity, self.game.playerVelocity.x - horizontalWalkAcceleration);
|
||||||
} else if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_RIGHT)) {
|
} else if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_RIGHT)) {
|
||||||
self.game.playerVelocity.x = @min(maxHorizontalWalkVelocity, self.game.playerVelocity.x + horizontalWalkAcceleration);
|
self.game.playerVelocity.x = std.math.min(maxHorizontalWalkVelocity, self.game.playerVelocity.x + horizontalWalkAcceleration);
|
||||||
} else {
|
} else {
|
||||||
if (@abs(self.game.playerVelocity.x) > 0.2) {
|
if (std.math.fabs(self.game.playerVelocity.x) > 0.2) {
|
||||||
self.game.playerVelocity.x = self.game.playerVelocity.x - std.math.sign(self.game.playerVelocity.x) * horizontalWalkAcceleration * dt;
|
self.game.playerVelocity.x = self.game.playerVelocity.x - std.math.sign(self.game.playerVelocity.x) * horizontalWalkAcceleration * dt;
|
||||||
} else {
|
} else {
|
||||||
self.game.playerVelocity.x = 0;
|
self.game.playerVelocity.x = 0;
|
||||||
@ -70,10 +70,10 @@ pub const GameScene = struct {
|
|||||||
if (self.game.playerVelocity.y == 0 and ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_SPACE)) {
|
if (self.game.playerVelocity.y == 0 and ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_SPACE)) {
|
||||||
self.game.playerVelocity.y = jumpVelocity;
|
self.game.playerVelocity.y = jumpVelocity;
|
||||||
} else if (!self.game.playerIsOnTile()) {
|
} else if (!self.game.playerIsOnTile()) {
|
||||||
self.game.playerVelocity.y = @min(maxFallVelocity, self.game.playerVelocity.y + gravity * dt);
|
self.game.playerVelocity.y = std.math.min(maxFallVelocity, self.game.playerVelocity.y + gravity * dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// self.game.playerVelocity.y = @min(maxFallVelocity, self.game.playerVelocity.y + self.game.playerAcceleration.y * dt);
|
// self.game.playerVelocity.y = std.math.min(maxFallVelocity, self.game.playerVelocity.y + self.game.playerAcceleration.y * dt);
|
||||||
if (self.game.playerVelocity.y != 0) {
|
if (self.game.playerVelocity.y != 0) {
|
||||||
self.game.playerFallingAnimation.tick(t);
|
self.game.playerFallingAnimation.tick(t);
|
||||||
self.game.playerIdleAnimation.reset();
|
self.game.playerIdleAnimation.reset();
|
||||||
@ -166,7 +166,7 @@ pub const GameScene = struct {
|
|||||||
switch (collectable) {
|
switch (collectable) {
|
||||||
.Star => {
|
.Star => {
|
||||||
const distanceToPlayer = engine.pt(x, y).float().distance(self.game.playerPosition);
|
const distanceToPlayer = engine.pt(x, y).float().distance(self.game.playerPosition);
|
||||||
self.game.drawSpriteFrame("item_star_32", self.game.starAnimation.currentOffset(@as(usize, @intFromFloat(@mod(distanceToPlayer * 0.54, 1) * 16))), x, y);
|
self.game.drawSpriteFrame("item_star_32", self.game.starAnimation.currentOffset(@floatToInt(usize, @mod(distanceToPlayer * 0.54, 1) * 16)), x, y);
|
||||||
},
|
},
|
||||||
.Exit => {
|
.Exit => {
|
||||||
const position = self.game.tileP(engine.pt(x, y).float().subtract(engine.ptF(0.5, 1)));
|
const position = self.game.tileP(engine.pt(x, y).float().subtract(engine.ptF(0.5, 1)));
|
||||||
@ -196,7 +196,7 @@ pub const GameScene = struct {
|
|||||||
const textColor = allegro.mapRgb(0x48, 0x91, 0x00);
|
const textColor = allegro.mapRgb(0x48, 0x91, 0x00);
|
||||||
|
|
||||||
if (self.game.state != .InProgress) {
|
if (self.game.state != .InProgress) {
|
||||||
ctx.renderer.textures.get("opaque").?.drawTintedScaled(allegro.mapRgba(0, 0, 0, 191), 0, 0, ctx.renderer.display.widthF(), ctx.renderer.display.heightF());
|
ctx.renderer.textures.get("opaque").?.drawTintedScaled(allegro.mapRgba(0, 0, 0, 191), 0, 0, @intToFloat(f32, ctx.renderer.display.width()), @intToFloat(f32, ctx.renderer.display.height()));
|
||||||
|
|
||||||
if (self.game.state == .Over) {
|
if (self.game.state == .Over) {
|
||||||
ctx.renderer.drawTextV("default", textColor, 0.5, 0.2, .Center, "Game over");
|
ctx.renderer.drawTextV("default", textColor, 0.5, 0.2, .Center, "Game over");
|
||||||
|
17
src/main.zig
17
src/main.zig
@ -7,7 +7,6 @@ const Context = @import("context.zig").Context;
|
|||||||
const GameScene = @import("game_scene.zig").GameScene;
|
const GameScene = @import("game_scene.zig").GameScene;
|
||||||
const Palette = @import("palette.zig").Palette;
|
const Palette = @import("palette.zig").Palette;
|
||||||
const Renderer = @import("renderer.zig").Renderer;
|
const Renderer = @import("renderer.zig").Renderer;
|
||||||
const Scene = @import("scene.zig").Scene;
|
|
||||||
const TitleScene = @import("title_scene.zig").TitleScene;
|
const TitleScene = @import("title_scene.zig").TitleScene;
|
||||||
|
|
||||||
fn hexColor(hex: []const u8) allegro.Color {
|
fn hexColor(hex: []const u8) allegro.Color {
|
||||||
@ -40,8 +39,7 @@ pub fn main() !void {
|
|||||||
|
|
||||||
allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = true, .MAG_LINEAR = true });
|
allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = true, .MAG_LINEAR = true });
|
||||||
try renderer.textures.addFromFile("opaque", paths.AssetsDir ++ "/images/opaque.png");
|
try renderer.textures.addFromFile("opaque", paths.AssetsDir ++ "/images/opaque.png");
|
||||||
try renderer.textures.addFromFile("title_screen", paths.AssetsDir ++ "/images/title_screen.jpg");
|
try renderer.textures.addFromFile("title_untitled", paths.AssetsDir ++ "/images/title_untitled.png");
|
||||||
try renderer.textures.addFromFile("main_menu", paths.AssetsDir ++ "/images/main_menu.jpg");
|
|
||||||
try renderer.textures.addFromFile("background_jungle", paths.AssetsDir ++ "/images/background_jungle.png");
|
try renderer.textures.addFromFile("background_jungle", paths.AssetsDir ++ "/images/background_jungle.png");
|
||||||
|
|
||||||
allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = false, .MAG_LINEAR = false });
|
allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = false, .MAG_LINEAR = false });
|
||||||
@ -62,12 +60,12 @@ pub fn main() !void {
|
|||||||
|
|
||||||
allegro.convertMemoryBitmaps();
|
allegro.convertMemoryBitmaps();
|
||||||
|
|
||||||
try renderer.registerFonts();
|
try context.registerFonts();
|
||||||
|
|
||||||
context.switchToScene(TitleScene) catch unreachable;
|
try context.switchToScene(GameScene, null);
|
||||||
|
|
||||||
var t = allegro.getTime();
|
var t = allegro.getTime();
|
||||||
const fpsBuffer = [_]u8{0} ** 32;
|
var fpsBuffer = [_]u8{0} ** 32;
|
||||||
_ = fpsBuffer;
|
_ = fpsBuffer;
|
||||||
while (!context.shouldQuit) {
|
while (!context.shouldQuit) {
|
||||||
const scene = if (context.scene) |scene| scene else {
|
const scene = if (context.scene) |scene| scene else {
|
||||||
@ -75,10 +73,10 @@ pub fn main() !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const newT = allegro.getTime();
|
const newT = allegro.getTime();
|
||||||
const deltaT = @as(f32, @floatCast(newT - t));
|
const deltaT = @floatCast(f32, newT - t);
|
||||||
t = newT;
|
t = newT;
|
||||||
context.fps.update(deltaT);
|
context.fps.update(deltaT);
|
||||||
scene.tick(&context, @as(f32, @floatCast(t)), deltaT);
|
scene.tick(&context, @floatCast(f32, t), deltaT);
|
||||||
|
|
||||||
while (!context.events.isEmpty()) {
|
while (!context.events.isEmpty()) {
|
||||||
var event: allegro.Event = undefined;
|
var event: allegro.Event = undefined;
|
||||||
@ -86,8 +84,9 @@ pub fn main() !void {
|
|||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
allegro.c.ALLEGRO_EVENT_DISPLAY_CLOSE => context.quit(),
|
allegro.c.ALLEGRO_EVENT_DISPLAY_CLOSE => context.quit(),
|
||||||
allegro.c.ALLEGRO_EVENT_DISPLAY_RESIZE => {
|
allegro.c.ALLEGRO_EVENT_DISPLAY_RESIZE => {
|
||||||
|
context.renderer.resized(event.display.width, event.display.height);
|
||||||
|
try context.registerFonts();
|
||||||
_ = allegro.acknowledgeResize(allegro.Display{ .native = event.display.source.? });
|
_ = allegro.acknowledgeResize(allegro.Display{ .native = event.display.source.? });
|
||||||
context.renderer.resized();
|
|
||||||
},
|
},
|
||||||
allegro.c.ALLEGRO_EVENT_KEY_CHAR => {
|
allegro.c.ALLEGRO_EVENT_KEY_CHAR => {
|
||||||
switch (event.keyboard.keycode) {
|
switch (event.keyboard.keycode) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
const allegro = @import("allegro");
|
const allegro = @import("allegro");
|
||||||
const game = @import("game.zig");
|
const game = @import("game.zig");
|
||||||
const Context = @import("context.zig").Context;
|
const Context = @import("context.zig").Context;
|
||||||
const GameScene = @import("game_scene.zig").GameScene;
|
|
||||||
|
|
||||||
pub const MainMenuScene = struct {
|
pub const MainMenuScene = struct {
|
||||||
pub fn enter(self: *MainMenuScene, ctx: *Context) void {
|
pub fn enter(self: *MainMenuScene, ctx: *Context) void {
|
||||||
@ -15,20 +14,12 @@ pub const MainMenuScene = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle(self: *MainMenuScene, ctx: *Context, event: *allegro.Event) !void {
|
pub fn handle(self: *MainMenuScene, ctx: *Context, event: *allegro.Event) !void {
|
||||||
switch (event.type) {
|
_ = event;
|
||||||
allegro.c.ALLEGRO_EVENT_KEY_CHAR => {
|
_ = ctx;
|
||||||
switch (event.keyboard.keycode) {
|
|
||||||
allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(GameScene),
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
_ = self;
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *MainMenuScene, ctx: *Context, t: f32, dt: f32) void {
|
pub fn update(self: *MainMenuScene, ctx: *Context, dt: f32) void {
|
||||||
_ = t;
|
|
||||||
_ = self;
|
_ = self;
|
||||||
_ = dt;
|
_ = dt;
|
||||||
_ = ctx;
|
_ = ctx;
|
||||||
@ -38,8 +29,10 @@ pub const MainMenuScene = struct {
|
|||||||
_ = self;
|
_ = self;
|
||||||
allegro.clearToColor(ctx.palette.background.background);
|
allegro.clearToColor(ctx.palette.background.background);
|
||||||
|
|
||||||
ctx.renderer.drawBackground("main_menu");
|
const center = ctx.viewport.center();
|
||||||
ctx.renderer.drawTextV("default", ctx.palette.background.text, 0.5, 0.5, .Center, "Press [enter] to");
|
ctx.textures.get("title_untitled").?.drawTintedCenteredScaled(ctx.palette.background.text, center.x, ctx.viewport.bounds.min.y + ctx.viewport.scale * 100, 0.5 * ctx.viewport.scale);
|
||||||
ctx.renderer.drawTextV("default", ctx.palette.background.text, 0.5, 0.56, .Center, "play the game.");
|
|
||||||
|
ctx.renderer.drawTextV("default", ctx.palette.background.text, 0, 0.3, game.Renderer.TextAlignment.Center, "Play game");
|
||||||
|
allegro.drawText(ctx.fonts.get("default").?, ctx.palette.background.text, center.x, ctx.viewport.bounds.min.y + ctx.viewport.scale * 200, allegro.DrawTextFlags.ALIGN_CENTER, "Play game");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const allegro = @import("allegro");
|
const allegro = @import("allegro");
|
||||||
const engine = @import("engine.zig");
|
const engine = @import("engine.zig");
|
||||||
const paths = @import("paths.zig");
|
|
||||||
const Context = @import("context.zig").Context;
|
const Context = @import("context.zig").Context;
|
||||||
|
|
||||||
pub const Renderer = struct {
|
pub const Renderer = struct {
|
||||||
@ -46,12 +45,6 @@ pub const Renderer = struct {
|
|||||||
self.display.destroy();
|
self.display.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawBackground(self: Renderer, textureName: []const u8) void {
|
|
||||||
if (self.textures.get(textureName)) |texture| {
|
|
||||||
allegro.drawScaledBitmap(texture, 0, 0, texture.widthF(), texture.heightF(), 0, 0, self.display.widthF(), self.display.heightF(), .{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn drawSpriteFrame(self: Renderer, spriteName: []const u8, frame: usize, x: f32, y: f32) void {
|
pub fn drawSpriteFrame(self: Renderer, spriteName: []const u8, frame: usize, x: f32, y: f32) void {
|
||||||
if (self.sprites.getFrame(spriteName, frame)) |sprite| {
|
if (self.sprites.getFrame(spriteName, frame)) |sprite| {
|
||||||
sprite.drawScaledUniform(x, y, self.viewport.scale);
|
sprite.drawScaledUniform(x, y, self.viewport.scale);
|
||||||
@ -110,19 +103,8 @@ pub const Renderer = struct {
|
|||||||
self.printText(font, color, screen.x, screen.y, alignment, fmt, args);
|
self.printText(font, color, screen.x, screen.y, alignment, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerFonts(self: *Renderer) !void {
|
pub fn resized(self: *Renderer, width: i32, height: i32) void {
|
||||||
const viewport = self.viewport;
|
self.viewport.update(width, height);
|
||||||
const fonts = &self.fonts;
|
|
||||||
try fonts.addFromFileTTF("default", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(32));
|
|
||||||
try fonts.addFromFileTTF("small", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(16));
|
|
||||||
try fonts.addFromFileTTF("extra-small", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(12));
|
|
||||||
try fonts.addFromFileTTF("large", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(64));
|
|
||||||
try fonts.addFromFileTTF("debug", paths.AssetsDir ++ "/fonts/Cabin-Regular.ttf", viewport.scaledInteger(16));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resized(self: *Renderer) void {
|
|
||||||
self.viewport.update(self.display.width(), self.display.height());
|
|
||||||
self.registerFonts() catch {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn takeScreenshot(self: Renderer) !void {
|
pub fn takeScreenshot(self: Renderer) !void {
|
||||||
@ -131,8 +113,8 @@ pub const Renderer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggleFullScreen(self: *Renderer) void {
|
pub fn toggleFullScreen(self: *Renderer) void {
|
||||||
const displayFlags = allegro.getDisplayFlags(self.display);
|
var displayFlags = allegro.getDisplayFlags(self.display);
|
||||||
_ = allegro.setDisplayFlag(self.display, allegro.NewDisplayFlags{ .FULLSCREEN_WINDOW = true }, !displayFlags.FULLSCREEN_WINDOW);
|
_ = allegro.setDisplayFlag(self.display, allegro.NewDisplayFlags{ .FULLSCREEN_WINDOW = true }, !displayFlags.FULLSCREEN_WINDOW);
|
||||||
self.resized();
|
self.viewport.update(self.display.width(), self.display.height());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ pub const TitleScene = struct {
|
|||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
allegro.c.ALLEGRO_EVENT_KEY_CHAR => {
|
allegro.c.ALLEGRO_EVENT_KEY_CHAR => {
|
||||||
switch (event.keyboard.keycode) {
|
switch (event.keyboard.keycode) {
|
||||||
allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(MainMenuScene),
|
allegro.c.ALLEGRO_KEY_SPACE => try ctx.switchToScene(MainMenuScene, null),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -38,6 +38,9 @@ pub const TitleScene = struct {
|
|||||||
pub fn render(self: *TitleScene, ctx: *Context) void {
|
pub fn render(self: *TitleScene, ctx: *Context) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
allegro.clearToColor(ctx.palette.background.background);
|
allegro.clearToColor(ctx.palette.background.background);
|
||||||
ctx.renderer.drawBackground("title_screen");
|
ctx.textures.get("opaque").?.drawTintedScaled(ctx.palette.tertiaryContainer.background, ctx.viewport.bounds.min.x, ctx.viewport.bounds.min.y, ctx.viewport.bounds.width(), ctx.viewport.bounds.height(), allegro.DrawFlags{});
|
||||||
|
|
||||||
|
const center = ctx.viewport.center();
|
||||||
|
ctx.textures.get("title_untitled").?.drawTintedCenteredScaled(ctx.palette.background.text, center.x, center.y, ctx.viewport.scale);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user