Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 68 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
arch: [x86, x86_64]
arch: [x86, x86_64, arm64]
exclude:
- os: windows-latest
arch: arm64
include:
# Windows
- os: windows-latest
Expand All @@ -23,6 +26,9 @@ jobs:
- os: ubuntu-latest
arch: x86_64
platform: linux
- os: ubuntu-latest
arch: arm64
platform: linux

steps:
- uses: actions/checkout@v7
Expand All @@ -32,7 +38,29 @@ jobs:
shell: bash
run: |
sudo apt-get update # && sudo apt-get upgrade -y
sudo apt-get install -y build-essential libc6-dev-i386 g++-multilib gcc-mingw-w64 p7zip-full
sudo apt-get install -y build-essential p7zip-full
# 32-bit and multilib support only exists/is needed on x86 hosts;
# there's no i386 or multilib package on the arm64 runner
if [ "${{ matrix.arch }}" == "x86" ]; then
sudo apt-get install -y libc6-dev-i386 g++-multilib
fi
if [ "${{ matrix.arch }}" != "arm64" ]; then
sudo apt-get install -y gcc-mingw-w64
fi
if [ "${{ matrix.arch }}" == "arm64" ]; then
sudo apt-get install -y gcc-aarch64-linux-gnu
fi

- name: Install llvm-mingw (arm64 Windows cross-compile)
if: ${{ matrix.os != 'windows-latest' && matrix.arch == 'arm64' }}
shell: bash
run: |
LLVM_MINGW_VERSION=20241203
HOST_ARCH=$(uname -m)
curl -L -o llvm-mingw.tar.xz \
"https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-20.04-${HOST_ARCH}.tar.xz"
tar -xf llvm-mingw.tar.xz
echo "$PWD/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-20.04-${HOST_ARCH}/bin" >> "$GITHUB_PATH"

- name: Build for ${{ matrix.os }} ${{ matrix.arch }}
shell: bash
Expand Down Expand Up @@ -65,8 +93,8 @@ jobs:
ARCHIVE: 1

- name: Store QVM artifacts
# store only with Linux x86_64
if: ${{ matrix.os != 'windows-latest' && matrix.arch != 'x86' }}
# store only once, from Linux x86_64
if: ${{ matrix.os != 'windows-latest' && matrix.arch == 'x86_64' }}
uses: actions/upload-artifact@v7
with:
name: QVMs
Expand Down Expand Up @@ -114,4 +142,40 @@ jobs:
path: |
binaries/debug-windows-${{ matrix.arch }}
if-no-files-found: error
retention-days: 5

build-macos:
runs-on: macos-latest
strategy:
matrix:
arch: [x86_64, arm64]
steps:
- uses: actions/checkout@v7

- name: Build native macOS
shell: bash
run: |
mkdir -p binaries/release-darwin-${{ matrix.arch }}
make -j$(sysctl -n hw.ncpu) install ARCH="${{ matrix.arch }}" DESTDIR=./binaries/release-darwin-${{ matrix.arch }}
mkdir -p binaries/debug-darwin-${{ matrix.arch }}
make -j$(sysctl -n hw.ncpu) install_debug ARCH="${{ matrix.arch }}" DESTDIR=./binaries/debug-darwin-${{ matrix.arch }}
env:
ARCHIVE: 1

- name: Store macOS release ${{ matrix.arch }} .dylib artifacts
uses: actions/upload-artifact@v7
with:
name: release-darwin-${{ matrix.arch }}
path: |
binaries/release-darwin-${{ matrix.arch }}
if-no-files-found: error
retention-days: 5

- name: Store macOS debug ${{ matrix.arch }} .dylib artifacts
uses: actions/upload-artifact@v7
with:
name: debug-darwin-${{ matrix.arch }}
path: |
binaries/debug-darwin-${{ matrix.arch }}
if-no-files-found: error
retention-days: 5
75 changes: 75 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ ARCH=$(COMPILE_ARCH)
endif
export ARCH

ifeq ($(ARCH),arm64)
override ARCH=aarch64
endif

ifneq ($(PLATFORM),$(COMPILE_PLATFORM))
CROSS_COMPILING=1
else
Expand Down Expand Up @@ -127,9 +131,54 @@ ifeq ($(PLATFORM),linux)
BASE_CFLAGS += -m32
endif

ifeq ($(ARCH),aarch64)
LIB=lib64
ifeq ($(CROSS_COMPILING),1)
ifneq ($(filter $(CC),cc gcc),)
CC=aarch64-linux-gnu-gcc
endif
endif

CC_TARGET_MACHINE := $(shell $(CC) -dumpmachine 2>/dev/null)
ifeq (,$(findstring aarch64,$(CC_TARGET_MACHINE)))
$(error CC='$(CC)' does not target aarch64 (reports '$(CC_TARGET_MACHINE)'). \
Install an aarch64 cross-toolchain (e.g. 'apt install gcc-aarch64-linux-gnu' \
on Debian/Ubuntu) and/or pass CC=aarch64-linux-gnu-gcc explicitly, e.g.: \
make ARCH=aarch64 CC=aarch64-linux-gnu-gcc)
endif
endif

endif #Linux


ifeq ($(PLATFORM),darwin)

BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes -pipe

OPTIMIZE = -O3 -fomit-frame-pointer -ffast-math

SHLIBEXT=dylib
SHLIBCFLAGS=-fPIC -fvisibility=hidden
SHLIBLDFLAGS=-bundle -flat_namespace -undefined suppress $(LDFLAGS)

LIBS= -lm

ifeq ($(ARCH),x86_64)
BASE_CFLAGS += -arch x86_64
SHLIBLDFLAGS += -arch x86_64
endif
ifeq ($(ARCH),aarch64)
BASE_CFLAGS += -march=armv8-a -arch arm64
SHLIBLDFLAGS += -arch arm64
endif
ifeq ($(ARCH),x86)
BASE_CFLAGS += -arch i386
SHLIBLDFLAGS += -arch i386
endif

endif #Darwin


ifdef MINGW

ifeq ($(CROSS_COMPILING),1)
Expand All @@ -147,12 +196,25 @@ ifdef MINGW
ifeq ($(ARCH),x86)
MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32
endif
ifeq ($(ARCH),aarch64)
MINGW_PREFIXES=aarch64-w64-mingw32
STRIP=aarch64-w64-mingw32-strip
endif

ifndef CC
CC=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-gcc))))
endif

ifeq ($(ARCH),aarch64)
ifeq ($(strip $(CC)),)
$(error No aarch64-w64-mingw32-gcc found on PATH for ARCH=aarch64 \
Windows cross-compile. Install llvm-mingw (provides the \
aarch64-w64-mingw32 toolchain) and ensure its bin/ directory is \
on PATH, then retry.)
endif
endif

# STRIP=$(MINGW_PREFIX)-strip -g

ifndef WINDRES
Expand Down Expand Up @@ -201,11 +263,24 @@ ifeq ($(PLATFORM),windows)
ifeq ($(ARCH),x86)
MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32
endif
ifeq ($(ARCH),aarch64)
MINGW_PREFIXES=aarch64-w64-mingw32
STRIP=aarch64-w64-mingw32-strip
endif

ifndef CC
CC=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-gcc))))
endif

ifeq ($(ARCH),aarch64)
ifeq ($(strip $(CC)),)
$(error No aarch64-w64-mingw32-gcc found on PATH for ARCH=aarch64 \
Windows cross-compile. Install llvm-mingw (provides the \
aarch64-w64-mingw32 toolchain) and ensure its bin/ directory is \
on PATH, then retry.)
endif
endif

STRIP=$(MINGW_PREFIX)-strip -g

Expand Down
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ A legendary Quake 3 Arena mod from the late 90s to early 2000s.
> > > 3.3.2. [Building QVM (using .bat)](#building-qvm-using-bat-1)<br/>
> > > 3.3.3. [Building shared libraries (.so)](#building-shared-libraries-so)
> >
> > 3.4. [Optional](#optional)
> > 3.4. [macOS](#macos)
> > > 3.4.1. [Building dynamic libraries (.dylib)](#building-dynamic-libraries-dylib)
> >
> > 3.5. [Optional](#optional)
> 4. [Notes](#notes)
> 5. [Legal](#legal)
> 6. [Credits](#credits)
Expand Down Expand Up @@ -140,6 +143,13 @@ You'll notice some differences and things that the original Bid For Power didn't
- `missileArch [0/1]`: the projectile, with missile or rdmissile attack type, moves like an arch across the crosshair
- `missileDlightRainbow [0/1]` to see rainbow dynamic rainbow light effect, and `missileTrailRainbow [0/1]` to see rainbow trail effect, in the skin config
- new confetti particle, use `explosionConfetti <number of confetti leafs>` in the skin config for the explosion
- free-lock death camera, the player, as corpse, can see around their position
- moderation features:
- player list: list player entity ids, names, IPs (server admin side only), bot info (if there's) and teams, usage: `playerlist`
- ignore: (client side only) ignores a client in the chat and voice, usage: `ignore <client id>`; to remove from ignore list: `unignore <client id>`; to clear all ignored clients: `clear_ignores`
- muteban: (server side only) stores a ban to mute completely a client in the server, like ignore but in server permanently, usage: `mute <client id>`; to remove from mute ban list: `unmute <ban_id, ip or guid>`; to check mute ban list: `mutebans`
- voteban: (server side only) stores a ban to avoid calling a vote and voting in the server, usage: `voteban <client id>`; to remove from vote ban list: `unvoteban <ban_id, ip or guid>`; to check vote ban list: `votebans`
- playban: (server side only) stores a ban and forces to spectate a client in the server and cannot join in the matches, usage: `playban <client id>`; to remove from play ban list: `unplayban <ban_id, ip or guid>`; to check play ban list: `playbans`


# How to build
Expand Down Expand Up @@ -198,7 +208,7 @@ The information in the map file can be useful for debugging and performance anal

To build, follow these instructions:

1. Install msys2 from https://msys2.github.io/, following the instructions there.It doesnt matter which version you download, just get one appropriate for your OS.
1. Install msys2 from https://msys2.github.io/, following the instructions there. It doesn't matter which version you download, just get one appropriate for your OS.

2. Start "MSYS2 MinGW 64-bit" from the Start Menu. If you're using 32-bit system, use "MSYS2 MinGW 32-bit".

Expand Down Expand Up @@ -269,7 +279,7 @@ The information in the map file can be useful for debugging and performance anal
2. Build the solution

In the *Solution Configurations* tab, you can switch `Debug` or `Release` and `Win32` or `x64`.<br/>
Right-click to the solution in the *Solution Explorer* and click `Build Solution`, check the log until the build is succeded. Go to `Win32` or `x64` folder in `win32-msvc`, look inside `Debug` or `Release` and get the dlls you built.
Right-click to the solution in the *Solution Explorer* and click `Build Solution`, check the log until the build succeeds. Go to `Win32` or `x64` folder in `win32-msvc`, look inside `Debug` or `Release` and get the dlls you built.

3. Debugging

Expand Down Expand Up @@ -341,13 +351,35 @@ The information in the map file can be useful for debugging and performance anal
```
3. And find .so files in `build/release-linux-x86_64`, for 32-bit: `build/release-linux-x86`. <br/><br/>

- ### macOS:

* #### _Building dynamic libraries (.dylib)_:

Requires Xcode Command Line Tools (or full Xcode) to be installed. If you don't have them, install with:
```sh
xcode-select --install
```

1. Keep in mind you must be in the repository directory. Simply execute (`-j4` is the number of parallel jobs you want to run during the compilation, in that case is set to 4):
```sh
make -j4
```
By default, this builds for whatever architecture your Mac is running (`x86_64` on Intel Macs, `arm64` on Apple Silicon).

2. And find .dylib files in `build/release-darwin-x86_64` or `build/release-darwin-arm64` depending on the architecture you built.

> [!NOTE]
> **About 32-bit (`ARCH=x86`) on macOS**: this is *not* supported by any current Xcode/Clang toolchain, and it isn't something this Makefile can work around with flags — Apple removed the i386 SDK (including `libSystem`, the most basic system library) starting with Xcode 10 in 2018.
>
> The Makefile still has an `ARCH=x86` code path under `PLATFORM=darwin` for the rare case where someone has an old Xcode 9 (or earlier) toolchain lying around, paired with an old macOS SDK (10.13/10.14-era). If you do get a working i386 build this way, keep in mind the resulting binary will only *run* on macOS 10.14 (Mojave) or earlier — Catalina (10.15) and every version after it refuse to execute 32-bit binaries at all, regardless of how they were compiled.

- ### Optional:

You can use the optional part, if you followed and used some of these sections:
- [MSYS2 (mingw) (Building dynamic libraries (.dll))](#msys2-mingw-building-dynamic-libraries-dll)
- [Cygwin (mingw) (Building dynamic libraries (.dll))](#cygwin-mingw-building-dynamic-libraries-dll)
- [Building shared libraries (.so)](#building-shared-libraries-so)
- [macOS (Building dynamic libraries (.dylib))](#building-dynamic-libraries-dylib)

You can execute optionally the parameters using the following ways:

Expand All @@ -361,7 +393,12 @@ The information in the map file can be useful for debugging and performance anal
make ARCH=x86 PLATFORM=windows # compiles release x86 .dll builds (creates "release-windows-x86" directory inside "build")
```

... Optionally, you can play the parameters like `ARCH=x86_64` (compiles 64-bits builds), `PLATFORM=windows` (compiles dlls), `PLATFORM=linux` (compiles shared libraries (.so files)) ...
* To compile release arm64 (aarch64) .dylib builds on macOS:
```sh
make ARCH=arm64 PLATFORM=darwin # compiles release arm64 .dylib builds (creates "release-darwin-arm64" directory inside "build")
```

... Optionally, you can play the parameters like `ARCH=x86_64` (compiles 64-bits builds), `ARCH=arm64` (compiles arm64(aarch64) builds, only for `PLATFORM=darwin` or Linux), `PLATFORM=windows` (compiles dlls), `PLATFORM=linux` (compiles shared libraries (.so files)), `PLATFORM=darwin` (compiles dynamic libraries (.dylib files), macOS only) ...

* To compile and copy release builds at the destination directory, `DESTDIR` parameter is mandatory:
```sh
Expand All @@ -370,7 +407,7 @@ The information in the map file can be useful for debugging and performance anal

* To compile and copy debug builds at the destination directory, `DESTDIR` parameter is mandatory:
```sh
make install DESTDIR=/your/path/q3/baseq3mod # compiles debug builds and copy the builds to the destination directory (you can also put ARCH=x86 PLATFORM=windows if you want)
make install_debug DESTDIR=/your/path/q3/baseq3mod # compiles debug builds and copy the builds to the destination directory (you can also put ARCH=x86 PLATFORM=windows if you want)
```

<br/>
Expand Down
11 changes: 11 additions & 0 deletions source/cgame/cg_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ typedef struct {

typedef struct {
lerpFrame_t legs, torso, flag;
// BFPR - Head to avoid player model look deformed when dead while camera can move freely
#ifdef BFPR_DEAD_CAMERA_FREE_MOVE
lerpFrame_t head;
#endif
int painTime;
int painDirection; // flip from 0 to 1
//int lightningFiring;
Expand All @@ -155,6 +159,13 @@ typedef struct {

qboolean constantFireAtkPlayed; // BFP - To play constantFireAttack fire sound once
int lastChargeVoiceLevel; // BFP - To play charge voice in one charge count once

// BFPR - For dead player angles
#ifdef BFPR_DEAD_CAMERA_FREE_MOVE
qboolean deadAnglesFrozen;
int deadAnglesClientNum;
vec3_t deadAnglesOrigin;
#endif
} playerEntity_t;

//=================================================
Expand Down
Loading