diff --git a/.github/workflows/CD.yml b/.github/workflows/CD.yml index f7bdc051a..a99d46c69 100644 --- a/.github/workflows/CD.yml +++ b/.github/workflows/CD.yml @@ -4,29 +4,30 @@ on: push: tags: '*' +permissions: + contents: read + jobs: build-lin: name: Linux Build runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v4 with: { fetch-depth: 0 } - - name: Install Dependencies - run: | - sudo apt-get update - sudo apt-get install -y g++-10-multilib + - uses: mlugg/setup-zig@v2 - name: Build env: - RELEASE_BUILD: 1 DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }} DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }} - run: make -j$(nproc) + run: zig build --summary all -Doptimize=ReleaseFast -Ddemo-sign-pubkey="$DEMO_SIGN_PUBKEY" -Ddemo-sign-privkey="$DEMO_SIGN_PRIVKEY" -Dcanary=false - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: sar-linux - path: sar.so + path: zig-out/lib/sar.so if-no-files-found: error - name: Upload to dl.sar.portal2.sr if: github.repository_owner == 'p2sr' @@ -43,12 +44,14 @@ jobs: -F "commit=$GITHUB_SHA" \ -F "branch=$GITHUB_REF_NAME" \ -F "count=1" \ - -F "hashes[0]=$(sha256sum sar.so | cut -d ' ' -f 1)" \ - -F "files[0]=@sar.so" \ + -F "hashes[0]=$(sha256sum zig-out/lib/sar.so | cut -d ' ' -f 1)" \ + -F "files[0]=@zig-out/lib/sar.so" \ "https://dl.sar.portal2.jonesy.moe/api/v1/upload" build-win: name: Windows Build runs-on: windows-2019 + permissions: + contents: write env: POWERSHELL_TELEMETRY_OPTOUT: 1 steps: @@ -101,6 +104,8 @@ jobs: if: github.repository == 'p2sr/SourceAutoRecord' needs: [build-lin, build-win] runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Get Release Version id: get_release diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 94f6d1179..c58b2a883 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,28 +16,30 @@ on: - 'Makefile' workflow_dispatch: +permissions: + contents: read + jobs: build-lin: name: Linux Build runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v4 with: { fetch-depth: 0 } - - name: Install Dependencies - run: | - sudo apt-get update - sudo apt-get install -y g++-10-multilib + - uses: mlugg/setup-zig@v2 - name: Build env: DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }} DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }} - run: make -j$(nproc) + run: zig build --summary all -Doptimize=Debug -Ddemo-sign-pubkey="$DEMO_SIGN_PUBKEY" -Ddemo-sign-privkey="$DEMO_SIGN_PRIVKEY" -Dcanary=true - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: sar-linux - path: sar.so + path: zig-out/lib/sar.so if-no-files-found: error - name: Upload to dl.sar.portal2.sr if: github.ref == 'refs/heads/master' && github.repository_owner == 'p2sr' @@ -54,13 +56,15 @@ jobs: -F "commit=$GITHUB_SHA" \ -F "branch=$GITHUB_REF_NAME" \ -F "count=1" \ - -F "hashes[0]=$(sha256sum sar.so | cut -d ' ' -f 1)" \ - -F "files[0]=@sar.so" \ + -F "hashes[0]=$(sha256sum zig-out/lib/sar.so | cut -d ' ' -f 1)" \ + -F "files[0]=@zig-out/lib/sar.so" \ "https://dl.sar.portal2.jonesy.moe/api/v1/upload" build-win: name: Windows Build runs-on: windows-2019 + permissions: + contents: write env: POWERSHELL_TELEMETRY_OPTOUT: 1 steps: diff --git a/.github/workflows/CodeQL.yml b/.github/workflows/CodeQL.yml new file mode 100644 index 000000000..8d04e293c --- /dev/null +++ b/.github/workflows/CodeQL.yml @@ -0,0 +1,55 @@ +name: "CodeQL Advanced" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '21 3 * * 5' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + - language: c-cpp + build-mode: manual + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Zig Compiler + uses: mlugg/setup-zig@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - if: matrix.build-mode == 'manual' + shell: bash + env: + DEMO_SIGN_PUBKEY: ${{ secrets.SAR_DEMO_SIGN_PUBKEY }} + DEMO_SIGN_PRIVKEY: ${{ secrets.SAR_DEMO_SIGN_PRIVKEY }} + run: | + zig build -Doptimize=Debug -Ddemo-sign-pubkey="$DEMO_SIGN_PUBKEY" -Ddemo-sign-privkey="$DEMO_SIGN_PRIVKEY" -Dcanary=true + cp zig-out/lib/sar.so sar.so + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.gitignore b/.gitignore index 6be7bbe1a..496eefdd3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ src/Features/Experimental/ docs/images/drawings/ sar.cvars .clangd +.zig-cache +zig-out ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. diff --git a/Makefile b/Makefile deleted file mode 100644 index 3e4f4a767..000000000 --- a/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -.PHONY: all clean cvars -.FORCE: - -CXX=g++-10 -SDIR=src -ODIR=obj - -SRCS=$(shell find $(SDIR) -name '*.cpp') -OBJS=$(patsubst $(SDIR)/%.cpp, $(ODIR)/%.o, $(SRCS)) - -VERSION=$(shell git describe --tags) - -# Header dependency target files; generated by g++ with -MMD -DEPS=$(OBJS:%.o=%.d) - -WARNINGS=-Wall -Wno-parentheses -Wno-unknown-pragmas -Wno-delete-non-virtual-dtor -Wno-overloaded-virtual -CXXFLAGS=-std=c++17 -m32 $(WARNINGS) -I$(SDIR) -fPIC -D_GNU_SOURCE -Ilib/ffmpeg/include -Ilib/SFML/include -Ilib/curl/include -Ilib/discord-rpc/include -DSFML_STATIC -DCURL_STATICLIB -LDFLAGS=-m32 -shared -lstdc++fs -Llib/ffmpeg/lib/linux -lavformat -lavcodec -lavutil -lswscale -lswresample -lx264 -lx265 -lvorbis -lvorbisenc -lvorbisfile -logg -lopus -lvpx -Llib/SFML/lib/linux -lsfml -Llib/curl/lib/linux -lcurl -lssl -lcrypto -lnghttp2 -Llib/discord-rpc/lib/linux -ldiscord-rpc - -# Import config.mk, which can be used for optional config --include config.mk - -all: sar.so -clean: - rm -rf $(ODIR) sar.so src/Version.hpp - --include $(DEPS) - -sar.so: src/Version.hpp $(OBJS) - $(CXX) $^ $(LDFLAGS) -o $@ - -$(ODIR)/%.o: $(SDIR)/%.cpp - @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -MMD -c $< -o $@ - -src/Version.hpp: .FORCE - if [ "$$RELEASE_BUILD" ]; then echo "#define SAR_VERSION \"$(VERSION)\"" >"$@"; fi - if [ -z "$$RELEASE_BUILD" ]; then echo "#define SAR_VERSION \"$(VERSION)-canary\"" >"$@"; fi - if [ -z "$$RELEASE_BUILD" ]; then echo "#define SAR_DEV_BUILD 1" >>"$@"; fi - echo "#define SAR_DEMO_SIGN_PUBKEY { $$DEMO_SIGN_PUBKEY }" >>"$@" - echo "#define SAR_DEMO_SIGN_PRIVKEY { $$DEMO_SIGN_PRIVKEY }" >>"$@" diff --git a/build.zig b/build.zig new file mode 100644 index 000000000..167de13e2 --- /dev/null +++ b/build.zig @@ -0,0 +1,340 @@ +const SarTarget = enum { linux, windows }; + +pub fn build(b: *std.Build) void { + const target_option: SarTarget = b.option(SarTarget, "target", "The target to build SAR for; default 'linux'") orelse .linux; + const target_query: std.Target.Query = std.Build.parseTargetQuery(switch (target_option) { + .linux => .{ .arch_os_abi = "x86-linux-gnu.2.28" }, + .windows => .{ .arch_os_abi = "x86-windows-msvc" }, + }) catch unreachable; // the queries are hardcoded and valid + const target = b.resolveTargetQuery(target_query); + const optimize = b.standardOptimizeOption(.{}); + + const sources = findSarSources(b) catch |err| std.debug.panic("error listing source files: {s}", .{@errorName(err)}); + + const disable_watermark = b.option(bool, "no-watermark", "Disable the development watermark in canary builds; default false") orelse false; + + const mod = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .link_libcpp = true, + .pic = true, + }); + mod.addCSourceFiles(.{ + .root = b.path("src"), + .files = sources, + .flags = &.{ + "-Wall", + "-Wno-parentheses", + "-Wno-unknown-pragmas", + "-Wno-delete-non-virtual-dtor", + "-Wno-overloaded-virtual", + "-Wno-inconsistent-missing-override", + "-Wno-date-time", + "-std=c++20", + "-fno-sanitize=alignment", + }, + .language = .cpp, + }); + if (disable_watermark) mod.addCMacro("NO_DEV_WATERMARK", "1"); + mod.addIncludePath(b.path("src")); + mod.addIncludePath(generateHeaders(b)); + mod.addIncludePath(b.path("lib/ffmpeg/include")); + switch (target_option) { + .linux => { + mod.addCMacro("_GNU_SOURCE", "1"); + mod.addCMacro("SFML_STATIC", "1"); + mod.addCMacro("CURL_STATICLIB", "1"); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libavcodec.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libavformat.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libavutil.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libogg.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libopus.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libswresample.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libswscale.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libvorbis.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libvorbisenc.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libvorbisfile.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libvpx.a")); + mod.addObjectFile(b.path("lib/ffmpeg/lib/linux/libx264.a")); + const curl_dep = b.dependency("curl", .{ + .target = target, + .optimize = optimize, + .libpsl = false, + .libssh2 = false, + .libidn2 = false, + .nghttp2 = false, + .@"disable-ldap" = true, + .@"use-openssl" = false, + .@"use-mbedtls" = true, + }); + mod.linkLibrary(@import("curl").artifact(curl_dep, .lib)); + mod.linkLibrary(makeSfml(b, target)); + mod.linkLibrary(makeDiscordRpc(b, target)); + mod.linkLibrary(makeX265(b, target)); + }, + .windows => { + mod.addIncludePath(b.path("lib/minhook")); + @panic("TODO"); + }, + } + + const lib = b.addSharedLibrary(.{ + .name = "sar", + .root_module = mod, + }); + lib.link_z_notext = true; + + // Don't just use `installArtifact` -- that'd name it `libsar.so`. + const install = b.addInstallArtifact(lib, .{ .dest_sub_path = "sar.so" }); + b.getInstallStep().dependOn(&install.step); +} + +fn makeSfml(b: *std.Build, target: std.Build.ResolvedTarget) *std.Build.Step.Compile { + const sfml = b.dependency("SFML", .{}); + const sfml_sources: []const []const u8 = &.{ + "SFML/System/Thread.cpp", + "SFML/System/Unix/SleepImpl.cpp", + "SFML/System/Unix/ThreadLocalImpl.cpp", + "SFML/System/Unix/ThreadImpl.cpp", + "SFML/System/Unix/ClockImpl.cpp", + "SFML/System/Unix/MutexImpl.cpp", + "SFML/System/Err.cpp", + "SFML/System/MemoryInputStream.cpp", + "SFML/System/Mutex.cpp", + //"SFML/System/Win32/SleepImpl.cpp", + //"SFML/System/Win32/ThreadLocalImpl.cpp", + //"SFML/System/Win32/ThreadImpl.cpp", + //"SFML/System/Win32/ClockImpl.cpp", + //"SFML/System/Win32/MutexImpl.cpp", + "SFML/System/Clock.cpp", + "SFML/System/FileInputStream.cpp", + "SFML/System/Sleep.cpp", + "SFML/System/Lock.cpp", + "SFML/System/ThreadLocal.cpp", + "SFML/System/Time.cpp", + "SFML/System/String.cpp", + "SFML/Network/UdpSocket.cpp", + "SFML/Network/Unix/SocketImpl.cpp", + "SFML/Network/Packet.cpp", + "SFML/Network/TcpSocket.cpp", + //"SFML/Network/Win32/SocketImpl.cpp", + "SFML/Network/Socket.cpp", + "SFML/Network/SocketSelector.cpp", + "SFML/Network/Ftp.cpp", + "SFML/Network/TcpListener.cpp", + "SFML/Network/Http.cpp", + "SFML/Network/IpAddress.cpp", + }; + const mod = b.createModule(.{ + .target = target, + .optimize = .ReleaseFast, + .link_libc = true, + .link_libcpp = true, + .pic = true, + }); + mod.addCSourceFiles(.{ + .root = sfml.path("src"), + .files = sfml_sources, + .flags = &.{"-std=c++20"}, + .language = .cpp, + }); + mod.addIncludePath(sfml.path("include")); + mod.addIncludePath(sfml.path("src")); + mod.addCMacro("SFML_STATIC", "1"); + const lib = b.addStaticLibrary(.{ + .name = "SFML", + .root_module = mod, + }); + lib.installHeadersDirectory(sfml.path("include"), "", .{ .include_extensions = &.{ ".hpp", ".inl" } }); + return lib; +} + +fn makeDiscordRpc(b: *std.Build, target: std.Build.ResolvedTarget) *std.Build.Step.Compile { + const discord_rpc = b.dependency("discord_rpc", .{}); + const rapidjson = b.dependency("rapidjson", .{}); + const discord_rpc_sources: []const []const u8 = &.{ + "rpc_connection.cpp", + "discord_rpc.cpp", + "connection_unix.cpp", + //"connection_win.cpp", + //"dllmain.cpp", + "discord_register_linux.cpp", + //"discord_register_win.cpp", + "serialization.cpp", + }; + const mod = b.createModule(.{ + .target = target, + .optimize = .ReleaseFast, + .link_libc = true, + .link_libcpp = true, + .pic = true, + }); + mod.addCSourceFiles(.{ + .root = discord_rpc.path("src"), + .files = discord_rpc_sources, + .flags = &.{"-std=c++11"}, + .language = .cpp, + }); + mod.addIncludePath(discord_rpc.path("include")); + mod.addIncludePath(rapidjson.path("include")); + const lib = b.addStaticLibrary(.{ + .name = "discord-rpc", + .root_module = mod, + }); + lib.installHeadersDirectory(discord_rpc.path("include"), "discord-rpc", .{}); + return lib; +} + +fn makeX265(b: *std.Build, target: std.Build.ResolvedTarget) *std.Build.Step.Compile { + const x265 = b.dependency("x265", .{}); + const x265_sources: []const []const u8 = &.{ + "x265.cpp", + "abrEncApp.cpp", + "output/output.cpp", + "output/raw.cpp", + "output/yuv.cpp", + "output/y4m.cpp", + "output/reconplay.cpp", + "encoder/frameencoder.cpp", + "encoder/search.cpp", + "encoder/encoder.cpp", + "encoder/nal.cpp", + "encoder/api.cpp", + "encoder/level.cpp", + "encoder/slicetype.cpp", + "encoder/sei.cpp", + "encoder/bitcost.cpp", + "encoder/analysis.cpp", + "encoder/ratecontrol.cpp", + "encoder/dpb.cpp", + "encoder/entropy.cpp", + "encoder/sao.cpp", + "encoder/motion.cpp", + "encoder/framefilter.cpp", + "encoder/reference.cpp", + "encoder/weightPrediction.cpp", + "common/md5.cpp", + "common/pixel.cpp", + "common/ipfilter.cpp", + "common/deblock.cpp", + "common/constants.cpp", + "common/cudata.cpp", + "common/threading.cpp", + "common/frame.cpp", + "common/threadpool.cpp", + "common/bitstream.cpp", + "common/x86/asm-primitives.cpp", + "common/picyuv.cpp", + "common/loopfilter.cpp", + "common/slice.cpp", + "common/wavefront.cpp", + "common/primitives.cpp", + "common/common.cpp", + "common/lowres.cpp", + "common/lowpassdct.cpp", + "common/framedata.cpp", + "common/version.cpp", + "common/piclist.cpp", + "common/param.cpp", + "common/yuv.cpp", + "common/predict.cpp", + "common/scaler.cpp", + "common/shortyuv.cpp", + "common/dct.cpp", + "common/quant.cpp", + "common/cpu.cpp", + "common/scalinglist.cpp", + "common/intrapred.cpp", + "input/input.cpp", + "input/yuv.cpp", + "input/y4m.cpp", + }; + const mod = b.createModule(.{ + .target = target, + .optimize = .ReleaseFast, + .link_libc = true, + .link_libcpp = true, + .pic = true, + }); + mod.addCSourceFiles(.{ + .root = x265.path("source"), + .files = x265_sources, + .flags = &.{ "-std=c++11", "-Wno-nontrivial-memaccess" }, + .language = .cpp, + }); + mod.addIncludePath(x265.path("source")); + mod.addIncludePath(x265.path("source/common")); + mod.addIncludePath(x265.path("source/encoder")); + const generate_headers = b.addWriteFiles(); + _ = generate_headers.add("x265_config.h", + \\#ifndef X265_CONFIG_H + \\#define X265_CONFIG_H + \\#define X265_BUILD 200 + \\#endif + \\ + ); + mod.addIncludePath(generate_headers.getDirectory()); + mod.addCMacro("X265_ARCH_X86", "1"); + mod.addCMacro("HAVE_INT_TYPES_H", "1"); + mod.addCMacro("HIGH_BIT_DEPTH", "0"); + mod.addCMacro("X265_DEPTH", "8"); + mod.addCMacro("EXPORT_C_API", "1"); + mod.addCMacro("X265_NS", "x265"); + mod.addCMacro("HAVE_STRTOK_R", "1"); + return b.addStaticLibrary(.{ + .name = "x265", + .root_module = mod, + }); +} + +fn generateHeaders(b: *std.Build) std.Build.LazyPath { + const generate_headers = b.addWriteFiles(); + var git_exit: u8 = undefined; + const version: []const u8 = b.runAllowFail( + &.{ "git", "describe", "--tags" }, + &git_exit, + .Inherit, + ) catch |err| v: { + std.log.warn("failed to run git: {s}", .{@errorName(err)}); + std.log.warn("using blank version string", .{}); + break :v ""; + }; + const is_canary = b.option(bool, "canary", "Whether this is a canary build of SAR; default true") orelse true; + const demo_sign_pubkey = b.option([]const u8, "demo-sign-pubkey", "The public key to use for demo signing.") orelse ""; + const demo_sign_privkey = b.option([]const u8, "demo-sign-privkey", "The private key to use for demo signing.") orelse ""; + const version_hpp_contents = b.fmt( + \\#define SAR_VERSION "{s}{s}" + \\{s} + \\#define SAR_DEMO_SIGN_PUBKEY {{ {s} }} + \\#define SAR_DEMO_SIGN_PRIVKEY {{ {s} }} + \\ + , .{ + std.mem.trim(u8, version, " \t\r\n"), + if (is_canary) "-canary" else "", + if (is_canary) "#define SAR_DEV_BUILD 1" else "", + demo_sign_pubkey, + demo_sign_privkey, + }); + _ = generate_headers.add("Version.hpp", version_hpp_contents); + return generate_headers.getDirectory(); +} + +/// Walks the `src/` directory to find all files whose names end `.cpp`. +/// Returns a slice of their paths relative to `src/`. +fn findSarSources(b: *std.Build) ![]const []const u8 { + const arena = b.graph.arena; + var sources: std.ArrayListUnmanaged([]const u8) = .empty; + var dir = try b.build_root.handle.openDir("src/", .{ .iterate = true }); + defer dir.close(); + var w = try dir.walk(arena); + defer w.deinit(); + while (try w.next()) |entry| { + if (entry.kind != .file) continue; + if (!std.mem.endsWith(u8, entry.path, ".cpp")) continue; + try sources.append(arena, b.dupe(entry.path)); + } + return sources.items; +} + +const std = @import("std"); diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 000000000..6353fbb49 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,31 @@ +.{ + .name = .SourceAutoRecord, + // Because SAR is not consumed as a Zig package, there is no need to include its actual version + // number here; it's not used anywhere. + .version = "0.0.0", + .fingerprint = 0x624553be3189c0f7, + .minimum_zig_version = "0.14.0", + .paths = .{""}, + .dependencies = .{ + .x265 = .{ + .url = "https://bitbucket.org/multicoreware/x265_git/get/bf91444e034831141e0ce02b1200e51996f8b6c6.tar.gz", + .hash = "N-V-__8AAGdkxwDhoQRBBu8Xdi_-k6mJF_mUq5NxgCG594a5", + }, + .SFML = .{ + .url = "https://github.com/mlugg/SFML/archive/54929d30ca09ab2ab79c2a6658cb9ca4843901cc.tar.gz", + .hash = "N-V-__8AACDhCgSN7eLNHyDZaMP66YK6wnCQEvYUJQb5IVfq", + }, + .discord_rpc = .{ + .url = "https://github.com/discord/discord-rpc/archive/963aa9f3e5ce81a4682c6ca3d136cddda614db33.tar.gz", + .hash = "N-V-__8AAAjEKwClBC-iaiewnaR2ldunbj-128yVVBULerN0", + }, + .rapidjson = .{ + .url = "https://github.com/Tencent/rapidjson/archive/24b5e7a8b27f42fa16b96fc70aade9106cf7102f.tar.gz", + .hash = "N-V-__8AAD2dNQDH5f-vkm-ZCt0HMKKVzrK2eOMYCjoGCHkT", + }, + .curl = .{ + .url = "https://github.com/allyourcodebase/curl/archive/b699f96a989ca2ae2d62f9774f436088ed47ea03.tar.gz", + .hash = "curl-8.13.0-mFDAWCXtAAAoC5sjcLO6XRYP-ljMSSWdpiYcVnxlt5GN", + }, + }, +} diff --git a/docs/contributing.md b/docs/contributing.md index 9e3d16bdb..855d02384 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -44,10 +44,16 @@ ### Linux -- g++ 8.3.0 -- g++-8-multilib -- Make 4.1 -- Configure paths in `config.mk` +- Zig 0.14.0 + - This can be downloaded from [ziglang.org](https://ziglang.org/download) as a self-contained archive with no dependencies +- Run `zig build` to get `zig-out/lib/sar.so` +- See available options with `zig build --help` +- For automatic "copy to game directory" functionality, consider wrapping `zig build` in a simple script: +``` +#!/bin/sh +zig build +cp zig-out/lib/sar.so /path/to/steamapps/common/Portal 2/portal2/sar.so +``` ## Pull Requests diff --git a/lib/SFML/lib/linux/libsfml.a b/lib/SFML/lib/linux/libsfml.a deleted file mode 100644 index fdf8f07f1..000000000 Binary files a/lib/SFML/lib/linux/libsfml.a and /dev/null differ diff --git a/lib/curl/lib/linux/libcrypto.a b/lib/curl/lib/linux/libcrypto.a deleted file mode 100644 index f4b83922a..000000000 Binary files a/lib/curl/lib/linux/libcrypto.a and /dev/null differ diff --git a/lib/curl/lib/linux/libcurl.a b/lib/curl/lib/linux/libcurl.a deleted file mode 100644 index 3d7c57b97..000000000 Binary files a/lib/curl/lib/linux/libcurl.a and /dev/null differ diff --git a/lib/curl/lib/linux/libnghttp2.a b/lib/curl/lib/linux/libnghttp2.a deleted file mode 100644 index 7275cc97e..000000000 Binary files a/lib/curl/lib/linux/libnghttp2.a and /dev/null differ diff --git a/lib/curl/lib/linux/libssl.a b/lib/curl/lib/linux/libssl.a deleted file mode 100644 index 3a4801a88..000000000 Binary files a/lib/curl/lib/linux/libssl.a and /dev/null differ diff --git a/lib/discord-rpc/lib/linux/libdiscord-rpc.a b/lib/discord-rpc/lib/linux/libdiscord-rpc.a deleted file mode 100644 index 3b7bb8ed8..000000000 Binary files a/lib/discord-rpc/lib/linux/libdiscord-rpc.a and /dev/null differ diff --git a/lib/ffmpeg/lib/linux/libx265.a b/lib/ffmpeg/lib/linux/libx265.a deleted file mode 100644 index aeed21909..000000000 Binary files a/lib/ffmpeg/lib/linux/libx265.a and /dev/null differ diff --git a/src/Features/Demo/DemoParser.cpp b/src/Features/Demo/DemoParser.cpp index f20007424..4280e842c 100644 --- a/src/Features/Demo/DemoParser.cpp +++ b/src/Features/Demo/DemoParser.cpp @@ -297,7 +297,7 @@ bool DemoParser::Parse(std::string filePath, Demo *demo, bool ghostRequest, std: "SAR: Error occurred when trying to parse the demo file.\n" "If you think this is an issue, report it at: https://github.com/p2sr/SourceAutoRecord/issues\n" "%s\n", - std::string(ex.what())); + ex.what()); return false; } return true; diff --git a/src/Features/Demo/GhostRenderer.hpp b/src/Features/Demo/GhostRenderer.hpp index ed3115519..85a5e06f9 100644 --- a/src/Features/Demo/GhostRenderer.hpp +++ b/src/Features/Demo/GhostRenderer.hpp @@ -8,13 +8,13 @@ class GhostEntity; class GhostRenderer { private: - GhostEntity *ghost; + GhostEntity *ghost = nullptr; - float lastUpdateCall; - std::vector animatedVerts; - float walkingCycle; - float squishForce; - bool oldGroundedState; + float lastUpdateCall = 0.0f; + std::vector animatedVerts = {}; + float walkingCycle = 0.0f; + float squishForce = 0.0f; + bool oldGroundedState = false; private: void UpdateAnimatedVerts(); diff --git a/src/Features/Hud/Crosshair.cpp b/src/Features/Hud/Crosshair.cpp index 0901606b7..0007d1f1a 100644 --- a/src/Features/Hud/Crosshair.cpp +++ b/src/Features/Hud/Crosshair.cpp @@ -299,7 +299,7 @@ int Crosshair::SetCrosshairTexture(const std::string filename) { console->Warning( "Failed to load \"%s\"\n" "Make sure both the path and the filename are correct.\n", - filename); + filename.c_str()); return -1; } diff --git a/src/Features/Summary.cpp b/src/Features/Summary.cpp index 486c23fa9..6ca9c5912 100644 --- a/src/Features/Summary.cpp +++ b/src/Features/Summary.cpp @@ -61,7 +61,7 @@ CON_COMMAND(sar_sum_result, "sar_sum_result - prints result of summary\n") { } for (size_t i = 0; i < summary->items.size(); ++i) { - console->Print("%s -> ", summary->items[i].map); + console->Print("%s -> ", summary->items[i].map.c_str()); console->Print("%i ticks", summary->items[i].ticks); console->Print("(%.3f)\n", summary->items[i].time); } diff --git a/src/Features/Timer/Timer.cpp b/src/Features/Timer/Timer.cpp index 17291793f..70e4a4a9c 100644 --- a/src/Features/Timer/Timer.cpp +++ b/src/Features/Timer/Timer.cpp @@ -111,7 +111,7 @@ CON_COMMAND(sar_avg_result, "sar_avg_result - prints result of average\n") { console->Print("Average of %i:\n", average); for (size_t i = 0; i < average; ++i) { - console->Print("%s -> ", timer->avg->items[i].map); + console->Print("%s -> ", timer->avg->items[i].map.c_str()); console->Print("%i ticks", timer->avg->items[i].ticks); console->Print("(%.3f)\n", timer->avg->items[i].time); } @@ -143,11 +143,11 @@ CON_COMMAND(sar_cps_result, "sar_cps_result - prints result of timer checkpoints for (size_t i = 0; i < cps; ++i) { if (i == cps - 1 && timer->isRunning) { - console->PrintActive("%s -> ", timer->cps->items[i].map); + console->PrintActive("%s -> ", timer->cps->items[i].map.c_str()); console->PrintActive("%i ticks", timer->cps->items[i].ticks); console->PrintActive("(%.3f)\n", timer->cps->items[i].time); } else { - console->Print("%s -> ", timer->cps->items[i].map); + console->Print("%s -> ", timer->cps->items[i].map.c_str()); console->Print("%i ticks", timer->cps->items[i].ticks); console->Print("(%.3f)\n", timer->cps->items[i].time); } diff --git a/src/Utils.cpp b/src/Utils.cpp index a9104903a..5afaab596 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -76,7 +76,8 @@ std::optional Utils::GetColor(const char *str, bool to_linear) { while (isspace(*str)) ++str; size_t len = strlen(str); - for (size_t i = len - 1; i; --i) { + for (size_t i = len; i > 0;) { + --i; if (!isspace(str[i])) break; --len; } diff --git a/src/Utils/Platform.hpp b/src/Utils/Platform.hpp index f37c670c6..724834daa 100644 --- a/src/Utils/Platform.hpp +++ b/src/Utils/Platform.hpp @@ -82,7 +82,7 @@ namespace { # define __cdecl __attribute__((__cdecl__)) # define __fastcall __attribute__((__fastcall__)) # define DLL_EXPORT extern "C" __attribute__((visibility("default"))) -# define SEEK_DIR_CUR std::ios_base::seekdir::_S_cur +# define SEEK_DIR_CUR std::ios_base::cur # define STDCALL_NAME(base, param_bytes) base # define DECL_DETOUR(name, ...) \ diff --git a/src/Utils/SDK/Math.hpp b/src/Utils/SDK/Math.hpp index f028f616e..737e00172 100644 --- a/src/Utils/SDK/Math.hpp +++ b/src/Utils/SDK/Math.hpp @@ -188,7 +188,7 @@ struct Bounds { return *this; } inline Bounds Scale(float amp) { - this.Scale(vBegin, amp); + Scale(vBegin, amp); return *this; } inline Bounds operator+(const Bounds &other) const {