Skip to content
Merged

Lua #21

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
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:
${{ matrix.prefix }}-SDL2
${{ matrix.prefix }}-openal
${{ matrix.prefix }}-freetype
${{ matrix.prefix }}-lua
msystem: ${{ matrix.msystem }}
path-type: minimal
release: false
Expand Down Expand Up @@ -218,7 +219,7 @@ jobs:
sudo rm -f /etc/apt/sources.list.d/azure-cli.list
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get -qq update
sudo apt-get -y install cmake ninja-build libcurl4-openssl-dev mesa-common-dev libxxf86dga-dev libxrandr-dev libxxf86vm-dev libasound-dev libsdl2-dev libopenal-dev libfreetype6-dev
sudo apt-get -y install cmake ninja-build libcurl4-openssl-dev mesa-common-dev libxxf86dga-dev libxrandr-dev libxxf86vm-dev libasound-dev libsdl2-dev libopenal-dev libfreetype6-dev lua5.4 liblua5.4-dev

- uses: actions/checkout@v4

Expand Down Expand Up @@ -315,7 +316,7 @@ jobs:

apt-get -qq update
apt-get install -y make gcc g++ cmake ninja-build
apt-get -y install libcurl4-openssl-dev mesa-common-dev libxxf86dga-dev libxrandr-dev libxxf86vm-dev libasound-dev libsdl2-dev libopenal-dev libfreetype6-dev
apt-get -y install libcurl4-openssl-dev mesa-common-dev libxxf86dga-dev libxrandr-dev libxxf86vm-dev libasound-dev libsdl2-dev libopenal-dev libfreetype6-dev lua5.4 liblua5.4-dev

OUTDIR="${GITHUB_WORKSPACE}/bin"
mkdir -p "$OUTDIR"
Expand Down Expand Up @@ -378,7 +379,7 @@ jobs:

steps:
- name: Install tools
run: brew install coreutils sdl2 openal-soft cmake ninja freetype
run: brew install coreutils sdl2 openal-soft cmake ninja freetype lua

- uses: actions/checkout@v4

Expand Down
22 changes: 22 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,25 @@ Or let the helper script do it:
```

The flag targets the renderer code under `src/renderers/rendercommon/tr_font.c`, links with your platform’s FreeType library, and defines `BUILD_FREETYPE` for the build. Make sure the FreeType headers/libraries (`libfreetype6-dev`, `freetype-devel`, etc.) are installed before you configure the project.

---

### Lua scripting support

Lua support is enabled by default.

To disable it explicitly:

```bash
cmake -S . -B build -DUSE_LUA=OFF
```

`scripts/compile_engine.sh` also supports a `lua` flag, which passes `-DUSE_LUA=ON`.

The engine looks for common Lua installs, including `lua5.5` / `lua-5.5` (plus `5.4`..`5.1` variants). Lua support requires Lua 5.1 or newer.

When enabled, these commands are available:

- `script_reload [file1.lua ...]`
- `script_list`
- `script_dump [maxEntries]`
180 changes: 180 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,173 @@ endif()
if(NOT DEFINED USE_WEBM)
option(USE_WEBM "Enable WebM audio support" ON)
endif()
if(NOT DEFINED USE_LUA)
option(USE_LUA "Enable Lua scripting support" ON)
endif()

set(LUA_FOUND FALSE)
set(LUA_LINK_LIBRARIES "")
set(LUA_VERSION_NUM 0)
set(LUA_VERSION_STRING "")
set(LUA_EXTRA_LIBRARIES "")

if(USE_LUA)
set(_LUA_HINT_PATHS
$ENV{LUA_DIR}
$ENV{LUA_PATH}
${CMAKE_PREFIX_PATH}
${CMAKE_INSTALL_PREFIX}
/usr/local
/usr
/opt/local
/opt
/opt/homebrew
/sw
)
if(WIN32)
list(APPEND _LUA_HINT_PATHS
"C:/msys64/mingw64"
"C:/msys64/ucrt64"
"C:/msys64/mingw32"
"C:/msys64/usr"
"C:/Lua"
"C:/Program Files/Lua"
"C:/Program Files (x86)/Lua"
)
endif()

find_path(LUA_INCLUDE_DIR
NAMES lua.h
PATH_SUFFIXES
include
include/lua
include/lua5.5
include/lua-5.5
include/lua5.4
include/lua-5.4
include/lua5.3
include/lua-5.3
include/lua5.2
include/lua-5.2
include/lua5.1
include/lua-5.1
PATHS ${_LUA_HINT_PATHS}
)

set(_LUA_HEADER_PATH "")
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
set(_LUA_HEADER_PATH "${LUA_INCLUDE_DIR}/lua.h")
endif()

if(_LUA_HEADER_PATH)
file(STRINGS "${_LUA_HEADER_PATH}" LUA_VERSION_MAJOR_LINE REGEX "^#define[ \t]+LUA_VERSION_MAJOR_N[ \t]+[0-9]+" LIMIT_COUNT 1)
file(STRINGS "${_LUA_HEADER_PATH}" LUA_VERSION_MINOR_LINE REGEX "^#define[ \t]+LUA_VERSION_MINOR_N[ \t]+[0-9]+" LIMIT_COUNT 1)
if(LUA_VERSION_MAJOR_LINE AND LUA_VERSION_MINOR_LINE)
string(REGEX REPLACE ".*LUA_VERSION_MAJOR_N[ \t]+([0-9]+).*" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_MAJOR_LINE}")
string(REGEX REPLACE ".*LUA_VERSION_MINOR_N[ \t]+([0-9]+).*" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_MINOR_LINE}")
math(EXPR LUA_VERSION_NUM "${LUA_VERSION_MAJOR} * 100 + ${LUA_VERSION_MINOR}")
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
else()
file(STRINGS "${_LUA_HEADER_PATH}" LUA_VERSION_NUM_LINE REGEX "^#define[ \t]+LUA_VERSION_NUM[ \t]+[0-9]+" LIMIT_COUNT 1)
if(LUA_VERSION_NUM_LINE)
string(REGEX REPLACE ".*LUA_VERSION_NUM[ \t]+([0-9]+).*" "\\1" LUA_VERSION_NUM "${LUA_VERSION_NUM_LINE}")
math(EXPR LUA_VERSION_MAJOR "${LUA_VERSION_NUM} / 100")
math(EXPR LUA_VERSION_MINOR "${LUA_VERSION_NUM} % 100")
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
endif()
endif()
endif()

set(_LUA_LIB_NAMES lua5.5 lua-5.5 lua55 lua5.4 lua-5.4 lua54 lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua51 lua)
if(LUA_VERSION_STRING)
set(_LUA_LIB_NAMES lua${LUA_VERSION_STRING} lua-${LUA_VERSION_STRING} lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR} ${_LUA_LIB_NAMES})
list(REMOVE_DUPLICATES _LUA_LIB_NAMES)
endif()

set(_LUA_LIB_HINTS "")
if(LUA_INCLUDE_DIR)
get_filename_component(_LUA_INCLUDE_PARENT "${LUA_INCLUDE_DIR}" DIRECTORY)
list(APPEND _LUA_LIB_HINTS
"${LUA_INCLUDE_DIR}/../lib"
"${LUA_INCLUDE_DIR}/../lib64"
"${_LUA_INCLUDE_PARENT}/lib"
"${_LUA_INCLUDE_PARENT}/lib64"
)
list(REMOVE_DUPLICATES _LUA_LIB_HINTS)
endif()

if(_LUA_LIB_HINTS)
find_library(LUA_LIBRARY
NAMES ${_LUA_LIB_NAMES}
HINTS ${_LUA_LIB_HINTS}
PATH_SUFFIXES "" lib lib64
NO_DEFAULT_PATH
)
endif()

if(NOT LUA_LIBRARY)
find_library(LUA_LIBRARY
NAMES ${_LUA_LIB_NAMES}
PATH_SUFFIXES lib64 lib
PATHS ${_LUA_HINT_PATHS}
)
endif()

if((NOT LUA_INCLUDE_DIR OR NOT LUA_LIBRARY) AND NOT WIN32)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
set(_LUA_PKG_NAMES ${_LUA_LIB_NAMES})
list(REMOVE_DUPLICATES _LUA_PKG_NAMES)
if(_LUA_PKG_NAMES)
set(_LUA_PKG_DETECTED FALSE)
foreach(_LUA_PKG_NAME ${_LUA_PKG_NAMES})
pkg_search_module(LUA_PKG QUIET ${_LUA_PKG_NAME})
if(LUA_PKG_FOUND)
set(_LUA_PKG_DETECTED TRUE)
break()
endif()
endforeach()
if(_LUA_PKG_DETECTED)
if(NOT LUA_INCLUDE_DIR AND LUA_PKG_INCLUDE_DIRS)
list(GET LUA_PKG_INCLUDE_DIRS 0 LUA_INCLUDE_DIR)
endif()
if(NOT LUA_LIBRARY)
if(LUA_PKG_LIBRARIES)
list(GET LUA_PKG_LIBRARIES 0 LUA_LIBRARY)
list(REMOVE_AT LUA_PKG_LIBRARIES 0)
set(LUA_EXTRA_LIBRARIES ${LUA_PKG_LIBRARIES})
elseif(LUA_PKG_LINK_LIBRARIES)
list(GET LUA_PKG_LINK_LIBRARIES 0 LUA_LIBRARY)
list(REMOVE_AT LUA_PKG_LINK_LIBRARIES 0)
set(LUA_EXTRA_LIBRARIES ${LUA_PKG_LINK_LIBRARIES})
endif()
endif()
endif()
endif()
endif()
endif()

if(NOT LUA_INCLUDE_DIR OR NOT LUA_LIBRARY)
message(WARNING "Lua headers/library not found; Lua scripting support will be disabled.")
else()
set(LUA_FOUND TRUE)

if(LUA_VERSION_NUM GREATER 0 AND LUA_VERSION_NUM LESS 501)
message(FATAL_ERROR "Lua 5.1+ is required.")
endif()

if(LUA_VERSION_STRING)
message(STATUS "Lua support enabled: ${LUA_VERSION_STRING} (${LUA_LIBRARY})")
else()
message(STATUS "Lua support enabled: ${LUA_LIBRARY}")
endif()

list(APPEND LUA_LINK_LIBRARIES ${LUA_LIBRARY})
if(LUA_EXTRA_LIBRARIES)
list(APPEND LUA_LINK_LIBRARIES ${LUA_EXTRA_LIBRARIES})
endif()
endif()
endif()

set(OPUS_FOUND FALSE)
set(FLAC_FOUND FALSE)
Expand Down Expand Up @@ -634,6 +801,10 @@ target_include_directories(qcommon PRIVATE
${CMAKE_SOURCE_DIR}/src/audio
)
set_property(TARGET qcommon PROPERTY POSITION_INDEPENDENT_CODE ON)
if(USE_LUA AND LUA_FOUND)
target_compile_definitions(qcommon PRIVATE USE_LUA)
target_include_directories(qcommon PRIVATE ${LUA_INCLUDE_DIR})
endif()

# dedicated server
ADD_LIBRARY(qcommon_ded OBJECT ${QCOMMON_SRCS} ${SERVER_SRCS})
Expand All @@ -649,6 +820,10 @@ target_include_directories(qcommon_ded PRIVATE
${CMAKE_SOURCE_DIR}/src/audio
)
set_property(TARGET qcommon_ded PROPERTY POSITION_INDEPENDENT_CODE ON)
if(USE_LUA AND LUA_FOUND)
target_compile_definitions(qcommon_ded PRIVATE USE_LUA)
target_include_directories(qcommon_ded PRIVATE ${LUA_INCLUDE_DIR})
endif()

# Apply SKIP_IDPAK_CHECK to qcommon targets that compile files.c
if(SKIP_IDPAK_CHECK)
Expand Down Expand Up @@ -1145,6 +1320,11 @@ if(UNIX AND NOT MSVC AND NOT APPLE)
target_link_options(${DNAME}${BINEXT} PRIVATE "-Wl,--export-dynamic")
endif()

if(USE_LUA AND LUA_FOUND)
TARGET_LINK_LIBRARIES(${CNAME}${BINEXT} PRIVATE ${LUA_LINK_LIBRARIES})
TARGET_LINK_LIBRARIES(${DNAME}${BINEXT} PRIVATE ${LUA_LINK_LIBRARIES})
endif()

IF(WIN32)
TARGET_LINK_LIBRARIES(${CNAME}${BINEXT} PRIVATE winmm comctl32 ws2_32)
TARGET_LINK_LIBRARIES(${DNAME}${BINEXT} PRIVATE winmm comctl32 ws2_32)
Expand Down
9 changes: 8 additions & 1 deletion scripts/compile_engine.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail

# Usage: ./compile_engine.sh [game_name] [Debug|Release] [clean] [quiet] [coverage] [vulkan] [opengl] [freetype]
# Usage: ./compile_engine.sh [game_name] [Debug|Release] [clean] [quiet] [coverage] [vulkan] [opengl] [freetype] [lua]
# Notes:
# - build type defaults to Release
# - vulkan and opengl are mutually exclusive
Expand All @@ -12,6 +12,7 @@ VULKAN=0
OPENGL=0
SKIP_IDPAK=0
FREETYPE=0
LUA=0

GAME_NAME="idtech3"
BUILD_TYPE="Release"
Expand Down Expand Up @@ -55,6 +56,7 @@ for arg in "$@"; do
skip-idpak-check|skip_idpak_check|skip-pak|skip-paks) SKIP_IDPAK=1 ;;
opengl) OPENGL=1 ;;
freetype) FREETYPE=1 ;;
lua) LUA=1 ;;
*) GAME_NAME="$arg" ;;
esac
done
Expand Down Expand Up @@ -114,6 +116,11 @@ if [ "$FREETYPE" -eq 1 ]; then
echo "CMake: BUILD_FREETYPE=ON"
fi

if [ "$LUA" -eq 1 ]; then
CMAKE_FLAGS+=("-DUSE_LUA=ON")
echo "CMake: USE_LUA=ON"
fi

if [ "$VULKAN" -eq 1 ]; then
CMAKE_FLAGS+=("-DRENDERER_DEFAULT=vulkan")
else
Expand Down
78 changes: 78 additions & 0 deletions src/qcommon/lua_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef LUA_COMPAT_H
#define LUA_COMPAT_H

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#if !defined(LUA_VERSION_NUM)
#error "LUA_VERSION_NUM is required"
#endif

#if LUA_VERSION_NUM < 501
#error "Lua 5.1+ is required"
#endif

#ifndef LUA_OK
#define LUA_OK 0
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_GETGLOBAL(L, N) lua_getglobal((L), (N))
#else
#define ID3_LUA_GETGLOBAL(L, N) lua_getfield((L), LUA_GLOBALSINDEX, (N))
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_SETGLOBAL(L, N) lua_setglobal((L), (N))
#else
#define ID3_LUA_SETGLOBAL(L, N) lua_setfield((L), LUA_GLOBALSINDEX, (N))
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_PUSH_GLOBAL_TABLE(L) lua_pushglobaltable((L))
#else
#define ID3_LUA_PUSH_GLOBAL_TABLE(L) lua_pushvalue((L), LUA_GLOBALSINDEX)
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_ABSINDEX(L, IDX) lua_absindex((L), (IDX))
#else
#define ID3_LUA_ABSINDEX(L, IDX) ((IDX) > 0 || (IDX) <= LUA_REGISTRYINDEX ? (IDX) : lua_gettop((L)) + (IDX) + 1)
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_RAWLEN(L, IDX) lua_rawlen((L), (IDX))
#else
#define ID3_LUA_RAWLEN(L, IDX) lua_objlen((L), (IDX))
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_TONUMBERX(L, IDX, ISNUM) lua_tonumberx((L), (IDX), (ISNUM))
#define ID3_LUA_TOINTEGERX(L, IDX, ISNUM) lua_tointegerx((L), (IDX), (ISNUM))
#else
#define ID3_LUA_TONUMBERX(L, IDX, ISNUM) (((ISNUM) ? (*(ISNUM) = lua_isnumber((L), (IDX))) : 0), lua_tonumber((L), (IDX)))
#define ID3_LUA_TOINTEGERX(L, IDX, ISNUM) (((ISNUM) ? (*(ISNUM) = lua_isnumber((L), (IDX))) : 0), lua_tointeger((L), (IDX)))
#endif

#if LUA_VERSION_NUM >= 503
#define ID3_LUA_ISINTEGER(L, IDX) lua_isinteger((L), (IDX))
#else
#define ID3_LUA_ISINTEGER(L, IDX) (0)
#endif

#if LUA_VERSION_NUM >= 502
#define ID3_LUA_NEWLIB(L, LREG) luaL_newlib((L), (LREG))
#else
#define ID3_LUA_NEWLIB(L, LREG) (lua_newtable((L)), luaL_register((L), NULL, (LREG)))
#endif

#if LUA_VERSION_NUM >= 504
#define ID3_LUA_RESUME(L, FROM, NARGS, NRES_OUT) lua_resume((L), (FROM), (NARGS), (NRES_OUT))
#elif LUA_VERSION_NUM >= 502
#define ID3_LUA_RESUME(L, FROM, NARGS, NRES_OUT) ((void)(NRES_OUT), lua_resume((L), (FROM), (NARGS)))
#else
#define ID3_LUA_RESUME(L, FROM, NARGS, NRES_OUT) ((void)(NRES_OUT), lua_resume((L), (NARGS)))
#endif

#endif
Loading
Loading