diff options
-rw-r--r-- | .build.yml | 15 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .gitmodules | 11 | ||||
-rw-r--r-- | .reuse/dep5 | 102 | ||||
-rw-r--r-- | REUSE.toml | 101 | ||||
-rw-r--r-- | build.zig | 74 | ||||
-rw-r--r-- | build.zig.zon | 36 | ||||
m--------- | lib/gfz | 0 | ||||
m--------- | lib/ini | 0 | ||||
m--------- | lib/loca | 0 | ||||
m--------- | lib/qoi | 0 | ||||
m--------- | lib/zeal | 0 | ||||
-rw-r--r-- | src/Decals.zig | 4 | ||||
-rw-r--r-- | src/Skeleton.cpp | 2 | ||||
-rw-r--r-- | src/config.zig | 15 | ||||
-rw-r--r-- | src/geom.zig | 14 | ||||
-rw-r--r-- | src/main.zig | 22 | ||||
-rw-r--r-- | src/misc.zig | 6 | ||||
-rw-r--r-- | src/model.zig | 14 |
19 files changed, 213 insertions, 205 deletions
diff --git a/.build.yml b/.build.yml deleted file mode 100644 index 7ef127b..0000000 --- a/.build.yml +++ /dev/null @@ -1,15 +0,0 @@ -image: alpine/edge -packages: - - glfw-dev - - glu-dev - - libsndfile-dev - - openal-soft-dev - - reuse - - zig -sources: - - https://git.sr.ht/~cnx/blackshades -tasks: - - build: | - cd blackshades - zig build -Doptimize=ReleaseSafe - - reuse: reuse --root blackshades lint diff --git a/.gitignore b/.gitignore index e73c965..3389c86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -zig-cache/ +.zig-cache/ zig-out/ diff --git a/.gitmodules b/.gitmodules index c564c4d..43b758c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,6 @@ -[submodule "lib/zeal"] - path = lib/zeal - url = https://git.sr.ht/~cnx/zeal -[submodule "lib/loca"] - path = lib/loca - url = https://git.sr.ht/~cnx/zig-loca [submodule "lib/ini"] path = lib/ini url = https://github.com/ziglibs/ini -[submodule "lib/gfz"] - path = lib/gfz - url = https://git.sr.ht/~cnx/gfz [submodule "lib/qoi"] path = lib/qoi - url = https://github.com/MasterQ32/zig-qoi + url = https://github.com/ikskuh/zig-qoi diff --git a/.reuse/dep5 b/.reuse/dep5 deleted file mode 100644 index d51c471..0000000 --- a/.reuse/dep5 +++ /dev/null @@ -1,102 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Source: https://sr.ht/~cnx/blackshades -Upstream-Name: Black Shades -Upstream-Contact: Nguyễn Gia Phong <cnx@loang.net> - -Files: *.cpp *.h *.zig -Copyright: See individual files -License: GPL-3.0-or-later - -Files: - *.tsv - data/models/blocks/* - data/models/collide/* - data/models/knife.off - data/models/skeleton/* - data/models/streets/* - data/sounds/Lose.ogg - data/sounds/bounce.ogg - data/sounds/bounce2.ogg - data/sounds/disguise-kill.ogg - data/sounds/explosion.ogg - data/sounds/footstep/* - data/sounds/handlerelease.ogg - data/sounds/headland.ogg - data/sounds/headshot.ogg - data/sounds/riflewhack.ogg - data/sounds/soul-in.ogg - data/sounds/soul-out.ogg - data/sounds/underwater.ogg - data/textures/blood/* - data/textures/flare.qoi - data/textures/font.qoi - data/textures/scope.qoi - data/textures/sprites/blood.qoi - data/textures/sprites/flash-hit.qoi - data/textures/sprites/flash-muzzle.qoi - data/textures/sprites/person-dead.qoi - data/textures/sprites/person.qoi - data/textures/sprites/smoke.qoi -Copyright: David Rosen -License: GPL-3.0-or-later - -Files: data/levels.ini -Copyright: - David Rosen - Nguyễn Gia Phong -License: GPL-3.0-or-later - -Files: - data/models/grenade/* - data/models/guns/* -Copyright: David Drew -License: GPL-3.0-or-later - -Files: - data/sounds/gun/* - data/sounds/impact/body-fall.wav - data/sounds/impact/body-hit.wav - data/sounds/impact/knife-stab.wav - data/sounds/impact/munch.wav - data/sounds/music/menu.opus - data/sounds/rain.ogg - data/textures/black.qoi - data/textures/bullet-hole.qoi - data/textures/sprites/snowflake.qoi - data/textures/sprites/white.qoi -Copyright: N/A -License: CC0-1.0 - -Files: data/sounds/grenade/* -Copyright: CGEffex -License: CC-BY-3.0 - -Files: data/sounds/gun/near-bullet.wav -Copyright: _def -License: CC-BY-3.0 - -Files: data/sounds/music/assassin.opus -Copyright: remaxim -License: CC-BY-4.0 - -Files: data/sounds/music/zombie.opus -Copyright: remaxim -License: CC-BY-SA-3.0 - -Files: data/sounds/impact/wall-hit.wav -Copyright: toxicwafflezz -License: CC-BY-3.0 - -Files: screenshot.png -Copyright: Wolfire Games -License: GPL-3.0-or-later - -Files: - .build.yml - .gitignore - .gitmodules - CHANGES - README.md - data/config.ini -Copyright: N/A -License: CC0-1.0 diff --git a/REUSE.toml b/REUSE.toml new file mode 100644 index 0000000..fd19dcd --- /dev/null +++ b/REUSE.toml @@ -0,0 +1,101 @@ +version = 1 + +[[annotations]] +path = ["**.cpp", "**.h", "**.zig"] +SPDX-FileCopyrightText = "See individual files" +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = [ "data/models/grenade/*.off", "data/models/guns/*.off" ] +SPDX-FileCopyrightText = "David Drew" +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = [ "**.tsv", "**.off", + "data/sounds/Lose.ogg", + "data/sounds/bounce.ogg", + "data/sounds/bounce2.ogg", + "data/sounds/disguise-kill.ogg", + "data/sounds/explosion.ogg", + "data/sounds/footstep/*.ogg", + "data/sounds/handlerelease.ogg", + "data/sounds/headland.ogg", + "data/sounds/headshot.ogg", + "data/sounds/riflewhack.ogg", + "data/sounds/soul-in.ogg", + "data/sounds/soul-out.ogg", + "data/sounds/underwater.ogg", + "data/textures/blood/*.qoi", + "data/textures/flare.qoi", + "data/textures/font.qoi", + "data/textures/scope.qoi", + "data/textures/sprites/blood.qoi", + "data/textures/sprites/flash-hit.qoi", + "data/textures/sprites/flash-muzzle.qoi", + "data/textures/sprites/person-dead.qoi", + "data/textures/sprites/person.qoi", + "data/textures/sprites/smoke.qoi" ] +SPDX-FileCopyrightText = "David Rosen" +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = "data/levels.ini" +precedence = "aggregate" +SPDX-FileCopyrightText = [ "David Rosen", "Nguyễn Gia Phong" ] +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = [ "data/sounds/gun/**.wav", + "data/sounds/impact/body-fall.wav", + "data/sounds/impact/body-hit.wav", + "data/sounds/impact/knife-stab.wav", + "data/sounds/impact/munch.wav", + "data/sounds/music/menu.opus", + "data/sounds/rain.ogg", + "data/textures/black.qoi", + "data/textures/bullet-hole.qoi", + "data/textures/sprites/snowflake.qoi", + "data/textures/sprites/white.qoi"] +SPDX-FileCopyrightText = "None" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "data/sounds/grenade/**" +SPDX-FileCopyrightText = "CGEffex" +SPDX-License-Identifier = "CC-BY-3.0" + +[[annotations]] +path = "data/sounds/gun/near-bullet.wav" +SPDX-FileCopyrightText = "_def" +SPDX-License-Identifier = "CC-BY-3.0" + +[[annotations]] +path = "data/sounds/music/assassin.opus" +SPDX-FileCopyrightText = "remaxim" +SPDX-License-Identifier = "CC-BY-4.0" + +[[annotations]] +path = "data/sounds/music/zombie.opus" +SPDX-FileCopyrightText = "remaxim" +SPDX-License-Identifier = "CC-BY-SA-3.0" + +[[annotations]] +path = "data/sounds/impact/wall-hit.wav" +SPDX-FileCopyrightText = "toxicwafflezz" +SPDX-License-Identifier = "CC-BY-3.0" + +[[annotations]] +path = "screenshot.png" +SPDX-FileCopyrightText = "Wolfire Games" +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = [ ".gitignore", + ".gitmodules", + "CHANGES", + "README.md", + "REUSE.toml", + "build.zig.zon", + "data/config.ini" ] +SPDX-FileCopyrightText = "None" +SPDX-License-Identifier = "CC0-1.0" diff --git a/build.zig b/build.zig index 8c5c4c8..97957bd 100644 --- a/build.zig +++ b/build.zig @@ -1,5 +1,5 @@ // Build recipe -// Copyright (C) 2021-2023 Nguyễn Gia Phong +// Copyright (C) 2021-2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -18,61 +18,51 @@ const Build = @import("std").Build; const Compile = Build.Step.Compile; -const InstallDirectoryOptions = Build.InstallDirectoryOptions; - -const data = InstallDirectoryOptions{ - .source_dir = .{ .path = "data" }, - .install_dir = .{ .custom = "share" }, - .install_subdir = "blackshades", -}; pub fn build(b: *Build) void { - const bin = b.addExecutable(.{ - .name = "blackshades", - .root_source_file = .{ .path = "src/main.zig" }, + const mod = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), .target = b.standardTargetOptions(.{}), .optimize = b.standardOptimizeOption(.{}), }); - bin.addIncludePath(.{ .path = "src" }); - bin.addCSourceFiles(&.{ - "src/GameDraw.cpp", - "src/GameInitDispose.cpp", - "src/GameLoop.cpp", - "src/GameTick.cpp", - "src/Globals.cpp", - "src/Person.cpp", - "src/Skeleton.cpp", - "src/Sprites.cpp", - }, &.{ "--std=c++17", "-Wall", "-Werror", "-fno-sanitize=undefined" }); - - for ([_]struct { []const u8, []const u8 }{ - .{ "gfz", "lib/gfz/src/gfz.zig" }, - .{ "ini", "lib/ini/src/ini.zig" }, - .{ "loca", "lib/loca/src/main.zig" }, - .{ "qoi", "lib/qoi/src/qoi.zig" }, - .{ "zeal", "lib/zeal/src/zeal.zig" }, - }) |lib| - bin.addModule(lib[0], b.createModule(.{ - .source_file = .{ .path = lib[1] }, - })); - @import("lib/gfz/build.zig").link(bin); - @import("lib/zeal/build.zig").link(bin); - bin.linkSystemLibrary("GL"); - bin.linkSystemLibrary("GLU"); - bin.linkSystemLibrary("c++"); + mod.addIncludePath(b.path("src")); + mod.addCSourceFiles(.{ + .files = &.{ + "src/GameDraw.cpp", + "src/GameInitDispose.cpp", + "src/GameLoop.cpp", + "src/GameTick.cpp", + "src/Globals.cpp", + "src/Person.cpp", + "src/Skeleton.cpp", + "src/Sprites.cpp", + }, + .flags = &.{ "--std=c++17", "-Wall", "-Werror" }, + }); + mod.linkSystemLibrary("GL", .{}); + mod.linkSystemLibrary("GLU", .{}); + mod.linkSystemLibrary("c++", .{}); + inline for (.{ "gfz", "ini", "known-folders", "qoi", "zeal" }) |lib| + mod.addImport(lib, b.dependency(lib, .{}).module(lib)); + const data = Build.Step.InstallDir.Options{ + .source_dir = b.path("data"), + .install_dir = .{ .custom = "share" }, + .install_subdir = "blackshades", + }; b.installDirectory(data); const options = b.addOptions(); const data_dir = b.getInstallPath(data.install_dir, data.install_subdir); options.addOption([]const u8, "data_dir", data_dir); - bin.addOptions("build_options", options); - b.installArtifact(bin); + mod.addOptions("build_options", options); + const bin = b.addExecutable(.{ .name = "blackshades", .root_module = mod }); + b.installArtifact(bin); const run_cmd = b.addRunArtifact(bin); - run_cmd.step.dependOn(b.getInstallStep()); + //run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| run_cmd.addArgs(args); - const run_step = b.step("run", "Run the app"); + const run_step = b.step("run", "Run the game"); run_step.dependOn(&run_cmd.step); } diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..e5e0969 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,36 @@ +.{ + .name = .blackshades, + .version = "2.5.3", + .fingerprint = 0xd1f5f56cdf18153, + .minimum_zig_version = "0.14.0", + .dependencies = .{ + .gfz = .{ + .url = "git+https://trong.loang.net/~cnx/gfz?ref=0.1.0#601c886f4b40d6a513563b5a883010633e52bf43", + .hash = "gfz-0.1.0-3UBgOH-DAAD1E3l0QB8DihsttSChM4VWHeU1QKeG6btY", + }, + .ini = .{ + .url = "lib/ini", + .hash = "ini-0.1.0-AAAAAJ4lAAAeuOSEbouG5uNtHCmngXktnF3PTsfjxvDq", + }, + .@"known-folders" = .{ + .url = "git+https://github.com/ziglibs/known-folders#aa24df42183ad415d10bc0a33e6238c437fc0f59", + .hash = "known_folders-0.0.0-Fy-PJtLDAADGDOwYwMkVydMSTp_aN-nfjCZw6qPQ2ECL", + }, + .qoi = .{ + .url = "lib/qoi", + .hash = "qoi-0.1.0-5Hmo8rpqAAD1pnE4OYX2tdvxLupff9nkjBGxuxVNtky8", + }, + .zeal = .{ + .url = "git+https://trong.loang.net/~cnx/zeal?ref=0.1.0#7580c25a081e39732afaaa7a630d7f58005d5ab1", + .hash = "zeal-0.1.0-90hghYyhAAAKkKkGWzVjxtxlZiwyRD2YNd3xDZRqrC9a", + }, + }, + .paths = .{ + "LICENSES", + "README.md", + "build.zig", + "build.zig.zon", + "data", + "src", + }, +} diff --git a/lib/gfz b/lib/gfz deleted file mode 160000 -Subproject d30ae1d4a46ad4b1f7b3c45c59dee268ab95c6b diff --git a/lib/ini b/lib/ini -Subproject 2b11e8fef86d0eefb225156e695be1c1d5c35cb +Subproject 684113312f9d8a70fa6cf928277a77be3316fc7 diff --git a/lib/loca b/lib/loca deleted file mode 160000 -Subproject aac1315920bb9f2c1e3492825c69f764d4a8525 diff --git a/lib/qoi b/lib/qoi -Subproject 524efec9e9522f8e2b72e9d67b36d5d5e69a767 +Subproject 63caa52c9d590ef76405922f419540e47bf393d diff --git a/lib/zeal b/lib/zeal deleted file mode 160000 -Subproject eb65c5633e1bfae26ae95c6183cc74c2b593794 diff --git a/src/Decals.zig b/src/Decals.zig index ecbc71c..b81b030 100644 --- a/src/Decals.zig +++ b/src/Decals.zig @@ -1,7 +1,7 @@ // Decal construction and drawing // Copyright (C) 2002 David Rosen // Copyright (C) 2003 Steven Fuller -// Copyright (C) 2023 Nguyễn Gia Phong +// Copyright (C) 2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -83,7 +83,7 @@ export fn addDecal(d: *Decals, kind: Kind, location: XYZ, size: f32, normal: XYZ, poly: c_int, m: *const Model, move: XYZ, rot: f32) void { const n: @Vector(3, f32) = @bitCast(normal); - const abs_n = @fabs(n); + const abs_n = @abs(n); var major: u2 = 0; if (abs_n[1] > abs_n[major]) major = 1; diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp index 8692213..b7f1684 100644 --- a/src/Skeleton.cpp +++ b/src/Skeleton.cpp @@ -450,7 +450,7 @@ void Skeleton::reload() lowforwardjoints[2] = lefthip; num_muscles = 29; - MuscleData muscles_data[num_muscles]; + MuscleData muscles_data[29]; loadMuscles(muscles_data); for (int i = 0; i < num_muscles; ++i) { muscles[i].length = muscles_data[i].length; diff --git a/src/config.zig b/src/config.zig index 0d18223..723e95c 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,5 +1,5 @@ // Configuration parser -// Copyright (C) 2021-2022 Nguyễn Gia Phong +// Copyright (C) 2021-2022, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -23,6 +23,7 @@ const allocator = std.heap.c_allocator; const cwd = std.fs.cwd; const endian = @import("builtin").target.cpu.arch.endian(); const eql = std.mem.eql; +const free = std.c.free; const join = std.fs.path.join; const maxInt = std.math.maxInt; const mkdir = std.os.mkdir; @@ -30,7 +31,7 @@ const parseFloat = std.fmt.parseFloat; const parseInt = std.fmt.parseInt; const std = @import("std"); const stringToEnum = std.meta.stringToEnum; -const tokenize = std.mem.tokenize; +const tokenizeScalar = std.mem.tokenizeScalar; const Key = @import("gfz").Key; const ini = @import("ini"); @@ -69,7 +70,7 @@ fn parseLevels(dir_path: []const u8, length: usize) ![*]Level { defer input.close(); const levels = try allocator.alloc(Level, length); errdefer allocator.free(levels); - var parser = ini.parse(allocator, input.reader()); + var parser = ini.parse(allocator, input.reader(), "#;"); defer parser.deinit(); var i: usize = maxInt(usize); @@ -92,7 +93,7 @@ fn parseLevels(dir_path: []const u8, length: usize) ![*]Level { else return error.InvalidData; } else if (eql(u8, kv.key, "evil weapons")) { var weapons = IntegerBitSet(8).initEmpty(); - var enums = tokenize(u8, kv.value, " "); + var enums = tokenizeScalar(u8, kv.value, ' '); while (enums.next()) |weapon| weapons.set(try parseInt(u3, weapon, 10)); levels[i].evil_weapons = weapons.mask; @@ -145,6 +146,10 @@ pub const Config = extern struct { levels: extern struct { ptr: [*]Level = undefined, len: usize = 0 } = .{}, debug: bool = false, + + pub fn deinit(self: Config) void { + defer free(self.levels.ptr); + } }; /// Parse config.ini in the given base directory. @@ -155,7 +160,7 @@ pub fn parse(base_dir: []const u8) !Config { defer dir.close(); const input = try openData(dir, "config.ini"); defer input.close(); - var parser = ini.parse(allocator, input.reader()); + var parser = ini.parse(allocator, input.reader(), "#;"); defer parser.deinit(); var config = Config{}; diff --git a/src/geom.zig b/src/geom.zig index d86c682..4bb92e1 100644 --- a/src/geom.zig +++ b/src/geom.zig @@ -1,6 +1,6 @@ // Geometry functions // Copyright (C) 2002 David Rosen -// Copyright (C) 2023 Nguyễn Gia Phong +// Copyright (C) 2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -81,9 +81,9 @@ pub fn rotate2d(i: *f32, j: *f32, a: f32) void { export fn rotate(v: XYZ, deg_x: f32, deg_y: f32, deg_z: f32) XYZ { var u = v; // TODO: optimize - rotate2d(&u.x, &u.y, degreesToRadians(f32, deg_z)); - rotate2d(&u.z, &u.x, degreesToRadians(f32, deg_y)); - rotate2d(&u.y, &u.z, degreesToRadians(f32, deg_x)); + rotate2d(&u.x, &u.y, degreesToRadians(deg_z)); + rotate2d(&u.z, &u.x, degreesToRadians(deg_y)); + rotate2d(&u.y, &u.z, degreesToRadians(deg_x)); return u; } @@ -106,7 +106,7 @@ pub export fn segCrossTrigon(start: XYZ, end: XYZ, const q: @Vector(3, f32) = @bitCast(end); const n: @Vector(3, f32) = @bitCast(normal.*); const denom = dot(q - p, n); - if (@fabs(denom) < floatEps(f32)) + if (@abs(denom) < floatEps(f32)) return false; // parallel segment and triangle const a: @Vector(3, f32) = @bitCast(p_a.*); @@ -116,7 +116,7 @@ pub export fn segCrossTrigon(start: XYZ, end: XYZ, return false; // intersection not within segment // Check if intersection is in the triangle - const n_abs = @fabs(n); + const n_abs = @abs(n); const n_max = @reduce(.Max, n_abs); const k: struct { usize, usize } = if (n_max == n_abs[0]) .{ 1, 2 } @@ -132,7 +132,7 @@ pub export fn segCrossTrigon(start: XYZ, end: XYZ, const v = @Vector(3, f32){ i[k[1]], b[k[1]], c[k[1]] } - splat(3, a[k[1]]); intersection.* = @bitCast(i); - if (@fabs(u[1]) < floatEps(f32)) { + if (@abs(u[1]) < floatEps(f32)) { const s = u[0] / u[2]; if (s >= 0 and s <= 1) { const t = (v[0] - s * v[2]) / v[1]; diff --git a/src/main.zig b/src/main.zig index 9accfc8..08c84ab 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,5 @@ // Main function -// Copyright (C) 2021-2023 Nguyễn Gia Phong +// Copyright (C) 2021-2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -16,13 +16,12 @@ // You should have received a copy of the GNU General Public License // along with Black Shades. If not, see <https://www.gnu.org/licenses/>. -const DefaultPrng = std.rand.DefaultPrng; +const DefaultPrng = std.Random.DefaultPrng; const allocator = std.heap.c_allocator; -const free = std.c.free; const std = @import("std"); -const Loca = @import("loca").Loca; const al = @import("zeal"); +const folders = @import("known-folders"); const gf = @import("gfz"); const gl = @import("zgl"); @@ -84,10 +83,10 @@ fn click(window: gf.Window, button: gf.MouseButton, } pub fn main() !void { - const loca = try Loca.init(allocator, .{}); - defer loca.deinit(); - const config = try configuration.parse(loca.user_config); - defer free(config.levels.ptr); + const user_config = (try folders.getPath(allocator, .local_configuration)).?; + defer allocator.free(user_config); + const config = try configuration.parse(user_config); + defer config.deinit(); try gf.init(); defer gf.deinit() catch unreachable; @@ -100,10 +99,11 @@ pub fn main() !void { defer textures.deinit(); var decals = Decals.init(allocator, &textures); defer decals.deinit(); + const user_data = (try folders.getPath(allocator, .data)).?; + defer allocator.free(user_data); game = c.makeGame(&decals, @bitCast(config), - @bitCast(try loadScores(loca.user_data))).?; - defer saveScores(loca.user_data, @bitCast(c.getScores(game))) - catch unreachable; + @bitCast(try loadScores(user_data))).?; + defer saveScores(user_data, @bitCast(c.getScores(game))) catch unreachable; try window.setSizeCallback(resizeWindow); try gf.swapInterval(@intFromBool(config.vsync)); diff --git a/src/misc.zig b/src/misc.zig index 46237cb..3bed694 100644 --- a/src/misc.zig +++ b/src/misc.zig @@ -1,6 +1,6 @@ // Miscellaneous functions // Copyright (C) 2002 David Rosen -// Copyright (C) 2021-2023 Nguyễn Gia Phong +// Copyright (C) 2021-2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -193,7 +193,7 @@ pub fn loadScores(base_dir: []const u8) !Scores { const path = "blackshades" ++ [_]u8{ sep } ++ "scores.ini"; const input = dir.openFile(path, .{}) catch return scores; defer input.close(); - var parser = ini.parse(allocator, input.reader()); + var parser = ini.parse(allocator, input.reader(), "#;"); defer parser.deinit(); while (try parser.next()) |record| @@ -241,7 +241,7 @@ pub fn saveScores(base_dir: []const u8, current: Scores) !void { previous.completed or current.completed, }); defer allocator.free(data); - try dir.writeFile("scores.ini", data); + try dir.writeFile(.{ .sub_path = "scores.ini", .data = data }); } const Text = struct { diff --git a/src/model.zig b/src/model.zig index 9773027..3acfe9d 100644 --- a/src/model.zig +++ b/src/model.zig @@ -1,6 +1,6 @@ // 3D model // Copyright (C) 2002 David Rosen -// Copyright (C) 2023 Nguyễn Gia Phong +// Copyright (C) 2023, 2025 Nguyễn Gia Phong // // This file is part of Black Shades. // @@ -25,7 +25,7 @@ const c = @import("cimport.zig"); const crossProduct = geom.crossProduct; const cwd = std.fs.cwd; const data_dir = misc.data_dir; -const degToRad = std.math.degreesToRadians; +const degreesToRadians = std.math.degreesToRadians; const endsWith = std.mem.endsWith; const eql = std.mem.eql; const floatMax = std.math.floatMax; @@ -63,7 +63,9 @@ const OffIterator = struct { token_iterator: TokenIterator, pub fn init(buffer: []const u8) OffIterator { - var self = .{ .token_iterator = tokenizeScalar(u8, buffer, '\n') }; + var self = OffIterator{ + .token_iterator = tokenizeScalar(u8, buffer, '\n'), + }; if (!endsWith(u8, self.token_iterator.next().?, "OFF")) self.token_iterator.reset(); return self; @@ -198,12 +200,12 @@ pub export fn segCrossModelTrans(start: XYZ, end: XYZ, m: *const Model, intersection: *XYZ) c_int { const t: @Vector(3, f32) = @bitCast(move); var p = @as(@Vector(3, f32), @bitCast(start)) - t; - rotate2d(&p[2], &p[0], degToRad(f32, -rot)); + rotate2d(&p[2], &p[0], degreesToRadians(-rot)); var q = @as(@Vector(3, f32), @bitCast(end)) - t; - rotate2d(&q[2], &q[0], degToRad(f32, -rot)); + rotate2d(&q[2], &q[0], degreesToRadians(-rot)); defer { - rotate2d(&intersection.z, &intersection.x, degToRad(f32, rot)); + rotate2d(&intersection.z, &intersection.x, degreesToRadians(rot)); intersection.* = @bitCast(@as(@Vector(3, f32), @bitCast(intersection.*)) + t); } |