Compare commits

..

1 Commits

Author SHA1 Message Date
Alibek Omarov
71b715875a scripts: gha: try to update vitaGL 2025-02-05 14:48:24 +03:00
90 changed files with 2469 additions and 3248 deletions

View File

@@ -4,7 +4,7 @@ task:
image_family: freebsd-14-2
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
@@ -16,7 +16,7 @@ task:
image_family: freebsd-15-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated

View File

@@ -66,7 +66,7 @@ jobs:
targetos: apple
targetarch: amd64
env:
SDL_VERSION: 2.32.0
SDL_VERSION: 2.30.12
GH_CPU_ARCH: ${{ matrix.targetarch }}
GH_CROSSCOMPILING: ${{ matrix.cross }}
steps:
@@ -120,6 +120,7 @@ jobs:
--yes \
--cleanup-tag \
--repo "$GITHUB_REPOSITORY" || true
sleep 20s
gh run download "$GITHUB_RUN_ID" \
--dir artifacts/ \
--repo "$GITHUB_REPOSITORY"

3
.gitmodules vendored
View File

@@ -34,6 +34,3 @@
[submodule "3rdparty/opusfile/opusfile"]
path = 3rdparty/opusfile/opusfile
url = https://gitlab.xiph.org/xiph/opusfile.git
[submodule "3rdparty/libbacktrace/libbacktrace"]
path = 3rdparty/libbacktrace/libbacktrace
url = https://github.com/ianlancetaylor/libbacktrace

View File

@@ -1,185 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import TaskGen
FRAGMENT_ATOMIC='''int i;
int main(void) {
__atomic_load_n(&i, __ATOMIC_ACQUIRE);
__atomic_store_n(&i, 1, __ATOMIC_RELEASE);
return 0;
}'''
FRAGMENT_SYNC='''int i;
int main (void) {
__sync_bool_compare_and_swap (&i, i, i);
__sync_lock_test_and_set (&i, 1);
__sync_lock_release (&i);
return 0;
}'''
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
int main(void) { return getpagesize() }'''
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
int main(void) { return getexecname() != 0 }'''
FRAGMENT_STRNLEN='''#include <string.h>
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
FRAGMENT_DL_ITERATE_PHDR='''#include <%s>
int main(void) { return dl_iterate_phdr(0, 0); }'''
FRAGMENT_FCNTL='''#include <fcntl.h>
int main(void) { return fcntl(0, 0, 0); }'''
FRAGMENT_GETIPINFO='''#include "unwind.h"
struct _Unwind_Context *context;
int ip_before_insn = 0;
int main(void) { return _Unwind_GetIPInfo(context, &ip_before_insn); }'''
FRAGMENT_LOADQUERY='''#include <sys/ldr.h>
#include <sys/debug.h>
int main(void) { return loadquery(0, 0, 0); }'''
FRAGMENT_KERN_PROC='''#include <sys/sysctl.h>
#if !defined(%s) || !defined(KERN_PROC_PATHNAME)
#error
#endif
int main(void) { return 0; }'''
FRAGMENT_LSTAT='''#include <sys/stat.h>
struct stat st;
int main(int argc, char **argv) { return lstat(argv[0], &st); }'''
FRAGMENT_READLINK='''#include <unistd.h>
char buf[100];
int main(int argc, char **argv) { return readlink(argv[0], buf, sizeof(buf)); }'''
def options(opt):
pass
def configure(conf):
# add unsupported platforms here
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
conf.env.DISABLE_LIBBACKTRACE = True
return
# win32 has it's own dbghelp-based backtrace, that's why we ship PDBs
if conf.env.COMPILER_CC == 'msvc':
conf.env.DISABLE_LIBBACKTRACE = True
return
if not conf.path.find_dir('libbacktrace') or not conf.path.find_dir('libbacktrace/config'):
conf.fatal('Can\'t find libbacktrace submodule. Run `git submodule update --init --recursive`.')
return
if conf.env.DEST_SIZEOF_VOID_P == 8:
conf.define('BACKTRACE_ELF_SIZE', 64)
conf.define('BACKTRACE_XCOFF_SIZE', 64)
else:
conf.define('BACKTRACE_ELF_SIZE', 32)
conf.define('BACKTRACE_XCOFF_SIZE', 32)
conf.define('_ALL_SOURCE', 1)
conf.define('_GNU_SOURCE', 1)
conf.define('_POSIX_PTHREAD_SEMANTICS', 1)
conf.define('_TANDEM_SOURCE', 1)
conf.define('__EXTENSIONS__', 1)
conf.define('_DARWIN_USE_64_BIT_INODE', 1)
conf.define('_LARGE_FILES', 1)
conf.check_large_file(compiler='c', execute=False, mandatory=False) # sets _FILE_OFFSET_BITS
conf.env.CFLAGS_EXTRAFLAGS = conf.filter_cflags(['-funwind-tables', '-g'], [])
if conf.filter_cflags(['-frandom-seed=test'], []):
conf.env.HAVE_FRANDOM_SEED = True
def check_header(hdr):
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr}
conf.multicheck(
check_header('dlfcn.h'),
check_header('inttypes.h'),
check_header('link.h'),
check_header('sys/link.h'),
check_header('mach-o/dyld.h'),
check_header('memory.h'),
check_header('stdint.h'),
check_header('stdlib.h'),
check_header('strings.h'),
check_header('string.h'),
check_header('sys/ldr.h'),
check_header('sys/mman.h'),
check_header('sys/stat.h'),
check_header('sys/types.h'),
check_header('tlhelp32.h'),
check_header('unistd.h'),
check_header('windows.h'),
{'fragment':FRAGMENT_ATOMIC, 'msg':'... __atomic extensions', 'define_name':'HAVE_ATOMIC_FUNCTIONS', 'mandatory':False},
{'fragment':FRAGMENT_SYNC, 'msg':'... __sync extensions', 'define_name':'HAVE_SYNC_FUNCTIONS', 'mandatory':False},
{'fragment':FRAGMENT_GETPAGESIZE, 'msg':'... getpagesize function', 'define_name':'HAVE_DECL_GETPAGESIZE', 'mandatory':False},
{'fragment':FRAGMENT_STRNLEN, 'msg':'... strnlen function', 'define_name':'HAVE_DECL_STRNLEN', 'mandatory':False},
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'link.h', 'msg':'... dl_iterate_phdr function in link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['link.h'], 'mandatory':False},
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', 'msg':'... dl_iterate_phdr function in sys/link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['sys/link.h'], 'mandatory':False},
{'fragment':FRAGMENT_FCNTL,'msg':'... fnctl function', 'define_name':'HAVE_FCNTL', 'mandatory':False},
{'fragment':FRAGMENT_GETEXECNAME,'msg':'... getexecname function','define_name':'HAVE_GETEXECNAME', 'mandatory':False},
{'fragment':FRAGMENT_GETIPINFO, 'msg':'... _Unwind_GetIPInfo function', 'define_name':'HAVE_GETIPINFO', 'mandatory':False},
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC', 'msg': '... KERN_PROC and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC', 'mandatory':False},
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC_ARGS', 'msg': '... KERN_PROC_ARGS and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC_ARGS', 'mandatory':False},
{'fragment':FRAGMENT_LOADQUERY, 'msg': '... loadquery function', 'define_name':'HAVE_LOADQUERY', 'mandatory':False},
{'fragment':FRAGMENT_LSTAT, 'msg': '... lstat function', 'define_name':'HAVE_LSTAT', 'mandatory':False},
{'fragment':FRAGMENT_READLINK, 'msg': '... readlink function', 'define_name':'HAVE_READLINK', 'mandatory':False},
# {'lib':'lzma', 'define_name':'HAVE_LIBLZMA', 'uselib_store':'lzma', 'msg':'... lzma library', 'mandatory':False},
# {'lib':'z', 'define_name':'HAVE_ZLIB', 'uselib_store':'z', 'msg':'... zlib library', 'mandatory':False},
# {'lib':'zstd', 'define_name':'HAVE_ZSTD', 'uselib_store':'zstd', 'msg':'... zstd library', 'mandatory':False},
msg='Checking for in parallel'
)
conf.write_config_header()
conf.define('BACKTRACE_SUPPORTED', 1)
conf.define('BACKTRACE_USES_MALLOC', 0)
conf.define('BACKTRACE_SUPPORTS_THREADS', 1)
conf.define('BACKTRACE_SUPPORTS_DATA', conf.env.DEST_BINFMT in ['elf', 'mac-o'])
conf.write_config_header('backtrace-supported.h')
@TaskGen.feature('frandomseed')
@TaskGen.after_method('propagate_uselib_vars')
def process_frandom_seed(ctx):
tasks = getattr(ctx, 'compiled_tasks', [])
for task in tasks:
out = task.outputs[0]
task.env.CFLAGS = list(task.env.CFLAGS) # need a copy
task.env.CFLAGS += ['-frandom-seed=%s' % out.path_from(out.ctx.bldnode)]
def build(bld):
if bld.env.DISABLE_LIBBACKTRACE:
return
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c', 'mmap.c', 'mmapio.c']
if bld.env.DEST_BINFMT == 'pe':
sources += ['pecoff.c']
elif bld.env.DEST_BINFMT == 'mac-o':
sources += ['macho.c']
elif bld.env.DEST_BINFMT == 'elf':
sources += ['elf.c']
else:
sources += ['unknown.c']
task = bld.stlib(
source = ['libbacktrace/' + i for i in sources],
target = 'backtrace',
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
use = 'EXTRAFLAGS lzma z zstd',
includes = '. libbacktrace/',
export_defines = 'HAVE_LIBBACKTRACE=1',
export_includes = 'libbacktrace/'
)

View File

@@ -6,7 +6,7 @@ For connecting to GoldSrc-based servers, use this command:
connect ip:port gs
```
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion or Dproto.
Without this requirement, you will just get "Steam validation rejected" error on connecting.
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).

View File

@@ -38,9 +38,6 @@ Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Ct
## Deathmatch Classic
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Delta Particles
Available on ModDB - https://www.moddb.com/mods/half-life-delta/downloads/delta-particles-full-sources-maps-and-c-code
## Earth Special Forces
Alpha 2.0 - https://www.gamers-desire.de/details/2830

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
[![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
[![Discord Server](https://img.shields.io/discord/355697768582610945?logo=Discord&label=International%20Discord%20chat)](http://fwgsdiscord.mentality.rip/) [![Russian speakers Telegram Chat](https://img.shields.io/badge/Russian_speakers_Telegram_chat-gray?logo=Telegram)](https://t.me/flyingwithgauss) \
[![Download Daily Build](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
[![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.

View File

@@ -5,13 +5,13 @@ cmake_minimum_required(VERSION 3.6)
project(XASH_ANDROID)
# armeabi-v7a requires cpufeatures library
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
target_link_libraries(cpufeatures dl)
endif()
include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()
include(FindPython)
find_package(PythonInterp 2.7 REQUIRED)
get_filename_component(C_COMPILER_ID ${CMAKE_C_COMPILER} NAME_WE)
get_filename_component(CXX_COMPILER_ID ${CMAKE_CXX_COMPILER} NAME_WE)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(BUILD_TYPE "debug")
@@ -20,20 +20,30 @@ else()
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto)
endif()
if(ANDROID_ABI STREQUAL "x86")
# HACKHACK: I don't know why but engine gets built as 64-bit binary here
list(APPEND WAF_EXTRA_ARGS -4)
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
set(64BIT ON CACHE BOOL "" FORCE)
list(APPEND WAF_EXTRA_ARGS -8) # only required for x86 when testing this cmakelist under linux
endif()
set(CMAKE_VERBOSE_MAKEFILE ON)
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
# not cleanest way to get upper directory
set(ENGINE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
set(WAF ${Python_EXECUTABLE} ${ENGINE_SOURCE_DIR}waf -t ${ENGINE_SOURCE_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/xash3d-fwgs)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
CC=${WAF_CC} CXX=${WAF_CXX}
AR=${CMAKE_AR} STRIP=${CMAKE_STRIP}
${PYTHON_EXECUTABLE} waf configure -T ${BUILD_TYPE} ${WAF_EXTRA_ARGS} cmake
--check-c-compiler=${C_COMPILER_ID} --check-cxx-compiler=${CXX_COMPILER_ID}
-s "${ENGINE_SOURCE_DIR}/SDL" --skip-sdl2-sanity-check --enable-bundled-deps
WORKING_DIRECTORY "${ENGINE_SOURCE_DIR}"
)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
# try to build minimal SDL. Enable features as we're gonna use them
set(SDL_RENDER OFF)
@@ -46,50 +56,5 @@ set(SDL_VULKAN OFF)
set(SDL_OFFSCREEN OFF)
set(SDL_STATIC OFF)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/SDL" SDL)
include(ExternalProject)
# gradle passes backslashes to cmake, how does this even work for everybody else?
string(REPLACE "\\" "/" CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
ExternalProject_Add(
Xash3DFWGS
SOURCE_DIR ${ENGINE_SOURCE_DIR}
INSTALL_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
BUILD_IN_SOURCE TRUE
DEPENDS SDL2
BUILD_ALWAYS TRUE
LOG_CONFIGURE TRUE
LOG_BUILD TRUE
LOG_INSTALL TRUE
LOG_OUTPUT_ON_FAILURE TRUE
LOG_MERGED_STDOUTERR TRUE
# USES_TERMINAL_CONFIGURE TRUE
# USES_TERMINAL_BUILD TRUE
# USES_TERMINAL_INSTALL TRUE
# NOTE: setting up WAFLOCK is important to avoid possible race conditions
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env
ANDROID_NDK=${ANDROID_NDK}
BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} configure -T ${BUILD_TYPE} --android=${ANDROID_ABI},,${CMAKE_SYSTEM_VERSION}
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps
BUILD_COMMAND ${CMAKE_COMMAND} -E env
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} build -v
INSTALL_COMMAND ${CMAKE_COMMAND} -E env
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} install --destdir=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
# a1ba: without this, xash3d target will be ignored as nothing depends on it
add_dependencies(client Xash3DFWGS)
add_dependencies(server Xash3DFWGS)
add_subdirectory("${ENGINE_SOURCE_DIR}/" xash3d-fwgs)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/mainui" mainui)

View File

@@ -9,7 +9,7 @@ plugins {
android {
namespace = "su.xash.engine"
ndkVersion = "28.0.13004108"
ndkVersion = "27.2.12479018"
defaultConfig {
applicationId = "su.xash"
@@ -96,7 +96,6 @@ android {
packaging {
jniLibs {
useLegacyPackaging = true
keepDebugSymbols.add("**/*.so")
}
}
}
@@ -113,7 +112,7 @@ dependencies {
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.work:work-runtime-ktx:2.9.0")
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation("com.madgag.spongycastle:prov:1.58.0.0")
implementation("in.dragonbra:javasteam:1.2.0")

View File

@@ -20,7 +20,4 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
# Enable verbose output for CMake
android.native.buildOutput=verbose
android.nonTransitiveRClass=true

View File

@@ -28,17 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PORT_ANY -1
typedef enum netadrtype_e
{
NA_UNDEFINED = 0,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX,
NA_IP6,
NA_MULTICAST_IP6
} netadrtype_t;
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
/*
Original Quake-2 structure:
@@ -56,60 +46,29 @@ typedef struct
#pragma pack( push, 1 )
typedef struct netadr_s
{
// the reason we do this evil thing, is that when this struct contains IPv6
// address the `type` is 2-byte wide, but when it doesn't `type` must 4-byte
// wide _and_ ip6_0 must be zeroed, to keep it binary compatible.
#if XASH_LITTLE_ENDIAN
uint16_t type;
uint8_t ip6_0[2];
#elif XASH_BIG_ENDIAN
uint8_t ip6_0[2];
uint16_t type;
#else
#error
#endif
union
{
// IPv6 struct
uint8_t ip6_1[14];
struct
{
uint16_t type6;
uint8_t ip6[16];
};
struct
{
uint32_t type; // must be netadrtype_t but will break with short enums
union
{
uint8_t ip[4];
uint32_t ip4; // for easier conversions
uint8_t ip[4];
uint32_t ip4; // for easier conversions
};
uint8_t ipx[10];
};
};
uint16_t port;
uint16_t port;
} netadr_t;
#pragma pack( pop )
static inline netadrtype_t NET_NetadrType( const netadr_t *a )
{
if( a->type == NA_IP6 || a->type == NA_MULTICAST_IP6 )
return (netadrtype_t)a->type;
if( a->ip6_0[0] || a->ip6_0[1] )
return NA_UNDEFINED;
return (netadrtype_t)a->type;
}
static inline void NET_NetadrSetType( netadr_t *a, netadrtype_t type )
{
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
{
a->type = type;
return;
}
a->ip6_0[0] = a->ip6_0[1] = 0;
a->type = type;
}
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
#endif // NET_ADR_H

View File

@@ -13,19 +13,13 @@
#endif // _WIN32
#include <sys/types.h> // off_t
#ifdef STDINT_H
#include STDINT_H
#else // !STDINT_H
#include <stdint.h>
#endif // !STDINT_H
#include <assert.h>
typedef uint8_t byte;
typedef float vec_t;
typedef vec_t vec2_t[2];
#ifndef vec3_t // SDK renames it to Vector
typedef vec_t vec3_t[3];
#endif
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
@@ -50,7 +44,6 @@ typedef int qboolean;
#define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
@@ -67,8 +60,6 @@ typedef int qboolean;
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#undef EXPORT
#if defined( __GNUC__ )
#if defined( __i386__ )
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))

View File

@@ -173,7 +173,7 @@ static int CL_CalcTabStop( const cl_font_t *font, int x )
return stop;
}
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags )
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
{
wrect_t *rc;
float w, h;
@@ -231,7 +231,7 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
return font->charWidths[number];
}
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
{
rgba_t current_color;
int draw_len = 0;
@@ -287,7 +287,7 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
return draw_len;
}
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];

View File

@@ -306,22 +306,21 @@ void SPR_AdjustSize( float *x, float *y, float *w, float *h )
static void SPR_AdjustTexCoords( int texnum, float width, float height, float *s1, float *t1, float *s2, float *t2 )
{
const qboolean filtering = REF_GET_PARM( PARM_TEX_FILTERING, texnum );
const int xremainder = refState.width % clgame.scrInfo.iWidth;
const int yremainder = refState.height % clgame.scrInfo.iHeight;
if(( filtering || xremainder ) && refState.width != clgame.scrInfo.iWidth )
if( REF_GET_PARM( PARM_TEX_FILTERING, texnum ))
{
// align to texel if scaling
*s1 += 0.5f;
*s2 -= 0.5f;
}
if( refState.width != clgame.scrInfo.iWidth )
{
// align to texel if scaling
*s1 += 0.5f;
*s2 -= 0.5f;
}
if(( filtering || yremainder ) && refState.height != clgame.scrInfo.iHeight )
{
// align to texel if scaling
*t1 += 0.5f;
*t2 -= 0.5f;
if( refState.height != clgame.scrInfo.iHeight )
{
// align to texel if scaling
*t1 += 0.5f;
*t2 -= 0.5f;
}
}
*s1 /= width;
@@ -1699,12 +1698,7 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
if( hud_scale.value >= 320.0f && hud_scale.value >= hud_scale_minimal_width.value )
{
scale_factor = refState.width / hud_scale.value;
apply_scale_factor = true;
}
else if( scale_factor && scale_factor != 1.0f )
if( scale_factor && scale_factor != 1.0f )
{
float scaled_width = (float)refState.width / scale_factor;
if( scaled_width >= hud_scale_minimal_width.value )
@@ -3427,7 +3421,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
return;
}
if( NET_NetadrType( remote_address ) == NA_IPX || NET_NetadrType( remote_address ) == NA_BROADCAST_IPX )
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
return; // IPX no longer support
if( request == NETAPI_REQUEST_SERVERLIST )

View File

@@ -1063,7 +1063,6 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
const char *key = ID_GetMD5();
netadr_t adr = { 0 };
int input_devices;
netadrtype_t adrtype;
protinfo[0] = 0;
@@ -1074,16 +1073,14 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
return;
}
adrtype = NET_NetadrType( &adr );
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
input_devices = IN_CollectInputDevices();
IN_LockInputDevices( adrtype != NA_LOOPBACK ? true : false );
IN_LockInputDevices( adr.type != NA_LOOPBACK ? true : false );
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
// it also doesn't need useragent string
if( adrtype != NA_LOOPBACK && proto != PROTO_GOLDSRC )
if( adr.type != NA_LOOPBACK && proto != PROTO_GOLDSRC )
{
Cvar_SetCheatState();
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
@@ -1221,7 +1218,7 @@ static void CL_CheckForResend( void )
cls.signon = 0;
cls.state = ca_connecting;
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
NET_NetadrSetType( &cls.serveradr, NA_LOOPBACK );
cls.serveradr.type = NA_LOOPBACK;
cls.legacymode = PROTO_CURRENT;
// we don't need a challenge on the localhost
@@ -1557,8 +1554,8 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
MSG_WriteString( &buf, "dropclient\n" );
else MSG_WriteString( &buf, "disconnect" );
if( NET_NetadrType( &cls.netchan.remote_address ) == NA_UNDEFINED )
NET_NetadrSetType( &cls.netchan.remote_address, NA_LOOPBACK );
if( !cls.netchan.remote_address.type )
cls.netchan.remote_address.type = NA_LOOPBACK;
// make sure message will be delivered
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
@@ -1727,17 +1724,19 @@ CL_LocalServers_f
*/
static void CL_LocalServers_f( void )
{
netadr_t adr = { 0 };
netadr_t adr;
memset( &adr, 0, sizeof( adr ));
Con_Printf( "Scanning for servers on the local network area...\n" );
NET_Config( true, true ); // allow remote
// send a broadcast packet
NET_NetadrSetType( &adr, NA_BROADCAST );
adr.type = NA_BROADCAST;
adr.port = MSG_BigShort( PORT_SERVER );
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
NET_NetadrSetType( &adr, NA_MULTICAST_IP6 );
adr.type = NA_MULTICAST_IP6;
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
}
@@ -2481,18 +2480,18 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
while( MSG_GetNumBitsLeft( msg ) > 8 )
{
uint8_t addr[16];
netadr_t servadr = { 0 };
netadr_t servadr;
if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
if( from.type6 == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
{
MSG_ReadBytes( msg, addr, sizeof( addr ));
NET_IP6BytesToNetadr( &servadr, addr );
NET_NetadrSetType( &servadr, NA_IP6 );
servadr.type6 = NA_IP6;
}
else
{
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
NET_NetadrSetType( &servadr, NA_IP );
servadr.type = NA_IP;
}
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
@@ -3140,9 +3139,6 @@ static qboolean CL_ShouldRescanFilesystem( void )
}
}
if( FBitSet( fs_mount_lv.flags|fs_mount_hd.flags|fs_mount_addon.flags|fs_mount_l10n.flags|ui_language.flags, FCVAR_CHANGED ))
retval = true;
return retval;
}
@@ -3152,7 +3148,7 @@ qboolean CL_PrecacheResources( void )
// if we downloaded new WAD files or any other archives they must be added to searchpath
if( CL_ShouldRescanFilesystem( ))
FS_Rescan_f();
g_fsapi.Rescan();
// NOTE: world need to be loaded as first model
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )

View File

@@ -92,11 +92,6 @@ static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned i
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
}
static void GAME_EXPORT pfnSetCustomClientID( const char *id )
{
// deprecated
}
static const mobile_engfuncs_t gMobileEngfuncs =
{
MOBILITY_API_VERSION,
@@ -111,7 +106,7 @@ static const mobile_engfuncs_t gMobileEngfuncs =
pfnDrawScaledCharacter,
Sys_Warn,
Sys_GetNativeObject,
pfnSetCustomClientID,
ID_SetCustomClientID,
pfnParseFileSafe
};

View File

@@ -83,10 +83,7 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
R_SetupSky( clgame.movevars.skyName );
clgame.oldmovevars = clgame.movevars;
// FIXME: set world wave height when entities will be allocated
if( clgame.entities )
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
// keep features an actual!
clgame.oldmovevars.features = clgame.movevars.features = host.features;

View File

@@ -2429,7 +2429,7 @@ void CL_SetLightstyle( int style, const char *s, float f )
if( unlikely( style < 0 || style >= MAX_LIGHTSTYLES ))
{
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", __func__, style );
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", style );
return;
}

View File

@@ -807,11 +807,11 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
void CL_FreeFont( cl_font_t *font );
void CL_SetFontRendermode( cl_font_t *font );
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags );
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
//
@@ -844,21 +844,19 @@ void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int he
void CL_DisableScissor( scissor_state_t *scissor );
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
static inline cl_entity_t *CL_EDICT_NUM( int index )
static inline cl_entity_t *CL_EDICT_NUM( int n )
{
if( !clgame.entities ) // not in game yet
if( !clgame.entities )
{
Host_Error( "%s: clgame.entities is NULL\n", __func__ );
return NULL;
}
if( index < 0 || index >= clgame.maxEntities )
{
Host_Error( "%s: bad number %i\n", __func__, index );
return NULL;
}
if(( n >= 0 ) && ( n < clgame.maxEntities ))
return clgame.entities + n;
return clgame.entities + index;
Host_Error( "%s: bad number %i\n", __func__, n );
return NULL;
}
static inline cl_entity_t *CL_GetEntityByIndex( int index )
@@ -869,7 +867,10 @@ static inline cl_entity_t *CL_GetEntityByIndex( int index )
if( index < 0 || index >= clgame.maxEntities )
return NULL;
return clgame.entities + index;
if( index == 0 )
return clgame.entities;
return CL_EDICT_NUM( index );
}
static inline model_t *CL_ModelHandle( int modelindex )
@@ -879,7 +880,7 @@ static inline model_t *CL_ModelHandle( int modelindex )
static inline qboolean CL_IsThirdPerson( void )
{
return clgame.dllFuncs.CL_IsThirdPerson();
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
}
static inline cl_entity_t *CL_GetLocalPlayer( void )
@@ -1107,7 +1108,7 @@ int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
cl_font_t *Con_GetCurFont( void );
cl_font_t *Con_GetFont( int num );
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor ); // legacy, use cl_font.c
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
void Con_CharEvent( int key );
void Key_Console( int key );
@@ -1214,6 +1215,7 @@ void OSK_Draw( void );
//
void ID_Init( void );
const char *ID_GetMD5( void );
void GAME_EXPORT ID_SetCustomClientID( const char *id );
extern rgba_t g_color_table[8];
extern triangleapi_t gTriApi;

View File

@@ -759,7 +759,7 @@ Con_DrawString
client version of routine
====================
*/
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor )
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
{
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
}
@@ -843,14 +843,11 @@ If no console is visible, the notify window will pop up.
*/
void Con_Print( const char *txt )
{
static qboolean cr_pending = false;
static qboolean colorstring = false;
static char buf[MAX_PRINT_MSG];
static int lastlength = 0;
static int bufpos = 0;
static int charpos = 0;
qboolean norefresh = false;
static int cr_pending = 0;
static char buf[MAX_PRINT_MSG];
qboolean norefresh = false;
static int lastlength = 0;
static int bufpos = 0;
int c, mask = 0;
// client not running
@@ -876,7 +873,7 @@ void Con_Print( const char *txt )
if( cr_pending )
{
Con_DeleteLastLine();
cr_pending = false;
cr_pending = 0;
}
c = *txt;
@@ -889,42 +886,23 @@ void Con_Print( const char *txt )
{
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
cr_pending = true;
cr_pending = 1;
bufpos = 0;
charpos = 0;
}
break;
case '\n':
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
bufpos = 0;
charpos = 0;
break;
default:
buf[bufpos++] = c | mask;
if( IsColorString( txt ))
{
// first color string character
colorstring = true;
}
else if( colorstring )
{
// second color string character
colorstring = false;
}
else
{
// not a color string, move char counter
charpos++;
}
if(( bufpos >= sizeof( buf ) - 1 ) || charpos >= ( con.linewidth - 1 ))
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
{
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
bufpos = 0;
charpos = 0;
}
break;
}
@@ -940,7 +918,6 @@ void Con_Print( const char *txt )
Con_AddLine( buf, bufpos, lastlength != 0 );
lastlength = 0;
bufpos = 0;
charpos = 0;
}
// pump messages to avoid window hanging
@@ -1490,16 +1467,6 @@ Handles history and console scrollback
*/
void Key_Console( int key )
{
// exit the console by pressing MINUS on NSwitch
// or both Back(Select)/Start buttons for everyone else
if( key == K_BACK_BUTTON || key == K_START_BUTTON || key == K_ESCAPE )
{
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
}
// ctrl-L clears screen
if( key == 'l' && Key_IsDown( K_CTRL ))
{
@@ -1608,6 +1575,16 @@ void Key_Console( int key )
return;
}
// exit the console by pressing MINUS on NSwitch
// or both Back(Select)/Start buttons for everyone else
if( key == K_BACK_BUTTON || key == K_START_BUTTON )
{
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
}
// pass to the normal editline routine
Field_KeyDownEvent( &con.input, key );
}

View File

@@ -19,8 +19,8 @@ GNU General Public License for more details.
#if !XASH_WIN32
#include <dirent.h>
#endif
static char id_md5[33];
static char id_customid[MAX_STRING];
/*
==========================================================
@@ -590,9 +590,25 @@ static void ID_Check( void )
const char *ID_GetMD5( void )
{
if( id_customid[0] )
return id_customid;
return id_md5;
}
/*
===============
ID_SetCustomClientID
===============
*/
void GAME_EXPORT ID_SetCustomClientID( const char *id )
{
if( !id )
return;
Q_strncpy( id_customid, id, sizeof( id_customid ) );
}
void ID_Init( void )
{
MD5Context_t hash = { 0 };

File diff suppressed because it is too large Load Diff

View File

@@ -332,7 +332,7 @@ static void IN_MouseMove( void )
if( !in_mouseinitialized )
return;
if( Touch_WantVisibleCursor( ))
if( Touch_Emulated( ))
{
// touch emulation overrides all input
Touch_KeyEvent( 0, 0 );
@@ -363,7 +363,7 @@ void IN_MouseEvent( int key, int down )
else ClearBits( in_mstate, BIT( key ));
// touch emulation overrides all input
if( Touch_WantVisibleCursor( ))
if( Touch_Emulated( ))
{
Touch_KeyEvent( K_MOUSE1 + key, down );
}

View File

@@ -74,6 +74,7 @@ void Touch_ResetDefaultButtons( void );
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
void Touch_KeyEvent( int key, int down );
qboolean Touch_WantVisibleCursor( void );
qboolean Touch_Emulated( void );
void Touch_NotifyResize( void );
//

View File

@@ -726,8 +726,18 @@ void GAME_EXPORT Key_Event( int key, int down )
return; // handled in client.dll
}
break;
default:
break;
case key_message:
Key_Message( key );
return;
case key_console:
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
case key_menu:
UI_KeyEvent( key, true );
return;
default: return;
}
}

View File

@@ -167,11 +167,6 @@ extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password;
extern convar_t hpk_custom_file;
extern convar_t con_gamemaps;
extern convar_t fs_mount_lv;
extern convar_t fs_mount_hd;
extern convar_t fs_mount_addon;
extern convar_t fs_mount_l10n;
extern convar_t ui_language; // historically used for UI, but now controls mounted localization directory
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
@@ -415,8 +410,6 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
void FS_Rescan_f( void );
void FS_CheckConfig( void );
//
// cmd.c

View File

@@ -498,6 +498,7 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
return true;
}
#if !XASH_DEDICATED
/*
=====================================
Cmd_GetItemsList
@@ -507,7 +508,6 @@ Prints or complete item classname (weapons only)
*/
static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
{
#if !XASH_DEDICATED
search_t *t;
string matchbuf;
int i, numitems;
@@ -521,7 +521,7 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
for( i = 0, numitems = 0; i < t->numfilenames; i++ )
for(i = 0, numitems = 0; i < t->numfilenames; i++)
{
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
continue;
@@ -544,8 +544,6 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
}
}
return true;
#endif // !XASH_DEDICATED
return false;
}
/*
@@ -557,7 +555,6 @@ Autocomplete for bind command
*/
static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
{
#if !XASH_DEDICATED
size_t i, numkeys;
string keys[256];
string matchbuf;
@@ -598,9 +595,8 @@ static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length
}
return true;
#endif // !XASH_DEDICATED
return false;
}
#endif // XASH_DEDICATED
/*
===============
@@ -608,20 +604,13 @@ Con_AddCommandToList
===============
*/
static void Con_AddCommandToList( const char *s, const char *value, const void *ptoggle, void *_autocompleteList )
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *_autocompleteList )
{
con_autocomplete_t *list = (con_autocomplete_t*)_autocompleteList;
qboolean toggle = ptoggle != NULL && *(qboolean *)ptoggle;
if( *s == '@' ) return; // never show system cvars or cmds
if( list->matchCount >= CON_MAXCMDS ) return; // list is full
if( toggle )
{
if( Q_strcmp( value, "0" ) && Q_strcmp( value, "1" ))
return; // exclude non-toggable cvars
}
if( Q_strnicmp( s, list->completionString, Q_strlen( list->completionString ) ) )
return; // no match
@@ -645,11 +634,13 @@ Cmd_GetCommandsList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname, int length, qboolean cmds, qboolean cvars, qboolean toggle )
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
{
size_t i;
string matchbuf;
con_autocomplete_t list = { 0 }; // local autocomplete list
con_autocomplete_t list; // local autocomplete list
memset( &list, 0, sizeof( list ));
list.completionString = s;
@@ -661,16 +652,8 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
return false;
// find matching commands and variables
if( cvars )
{
Cvar_LookupVars( 0, &toggle, &list, (setpair_t)Con_AddCommandToList );
}
if( cmds )
{
toggle = false;
Cmd_LookupCmds( &toggle, &list, (setpair_t)Con_AddCommandToList );
}
Cmd_LookupCmds( NULL, &list, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, NULL, &list, (setpair_t)Con_AddCommandToList );
if( !list.matchCount ) return false;
Q_strncpy( matchbuf, list.cmds[0], sizeof( matchbuf ));
@@ -686,7 +669,7 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
Con_Printf( "%16s\n", matchbuf );
}
Con_Printf( "\n^3 %i %s found.\n", list.matchCount, cmds ? "commands" : "variables" );
Con_Printf( "\n^3 %i commands found.\n", list.matchCount );
if( completedname && length )
{
@@ -708,30 +691,6 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
return true;
}
/*
=====================================
Cmd_GetCommandsList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
{
return Cmd_GetCommandsAndCvarsList( s, completedname, length, true, true, false );
}
/*
=====================================
Cmd_GetCvarList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCvarsList( const char *s, char *completedname, int length )
{
qboolean toggle = !Q_stricmp( Cmd_Argv( 0 ), "toggle" );
return Cmd_GetCommandsAndCvarsList( s, completedname, length, false, true, toggle );
}
/*
=====================================
@@ -1051,38 +1010,36 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
return Cmd_CheckMapsList_R( fRefresh, true );
}
// keep this sorted
static const autocomplete_list_t cmd_list[] =
{
{ "bind", 1, Cmd_GetKeysList },
{ "bind", 2, Cmd_GetCommandsList },
{ "cd", 1, Cmd_GetCDList },
{ "map_background", 1, Cmd_GetMapList },
{ "changelevel2", 1, Cmd_GetMapList },
{ "changelevel", 1, Cmd_GetMapList },
{ "drop", 1, Cmd_GetItemsList },
{ "entpatch", 1, Cmd_GetMapList },
{ "exec", 1, Cmd_GetConfigList },
{ "game", 1, Cmd_GetGamesList },
{ "give", 1, Cmd_GetItemsList },
{ "hpkextract", 1, Cmd_GetCustomList },
{ "hpklist", 1, Cmd_GetCustomList },
{ "hpkval", 1, Cmd_GetCustomList },
{ "listdemo", 1, Cmd_GetDemoList, },
{ "load", 1, Cmd_GetSavesList },
{ "map", 1, Cmd_GetMapList },
{ "map_background", 1, Cmd_GetMapList },
{ "movie", 1, Cmd_GetMovieList },
{ "mp3", 1, Cmd_GetCDList },
{ "music", 1, Cmd_GetMusicList, },
{ "play", 1, Cmd_GetSoundList },
{ "playdemo", 1, Cmd_GetDemoList, },
{ "timedemo", 1, Cmd_GetDemoList, },
{ "listdemo", 1, Cmd_GetDemoList, },
{ "playvol", 1, Cmd_GetSoundList },
{ "reset", 1, Cmd_GetCvarsList },
{ "save", 1, Cmd_GetSavesList },
{ "set", 1, Cmd_GetCvarsList },
{ "timedemo", 1, Cmd_GetDemoList },
{ "toggle", 1, Cmd_GetCvarsList },
{ "hpkval", 1, Cmd_GetCustomList },
{ "hpklist", 1, Cmd_GetCustomList },
{ "hpkextract", 1, Cmd_GetCustomList },
{ "entpatch", 1, Cmd_GetMapList },
{ "music", 1, Cmd_GetMusicList, },
{ "movie", 1, Cmd_GetMovieList },
{ "exec", 1, Cmd_GetConfigList },
#if !XASH_DEDICATED
{ "give", 1, Cmd_GetItemsList },
{ "drop", 1, Cmd_GetItemsList },
{ "bind", 1, Cmd_GetKeysList },
{ "unbind", 1, Cmd_GetKeysList },
{ "bind", 2, Cmd_GetCommandsList },
#endif
{ "game", 1, Cmd_GetGamesList },
{ "save", 1, Cmd_GetSavesList },
{ "load", 1, Cmd_GetSavesList },
{ "play", 1, Cmd_GetSoundList },
{ "map", 1, Cmd_GetMapList },
{ "cd", 1, Cmd_GetCDList },
{ "mp3", 1, Cmd_GetCDList },
};
/*
@@ -1203,7 +1160,6 @@ void Con_CompleteCommand( field_t *field )
{
field_t temp;
string filename;
qboolean toggle = false;
qboolean nextcmd;
int i;
@@ -1238,8 +1194,8 @@ void Con_CompleteCommand( field_t *field )
con.shortestMatch[0] = 0;
// find matching commands and variables
Cmd_LookupCmds( &toggle, &con, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, &toggle, &con, (setpair_t)Con_AddCommandToList );
Cmd_LookupCmds( NULL, &con, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, NULL, &con, (setpair_t)Con_AddCommandToList );
if( !con.matchCount ) return; // no matches

View File

@@ -1,4 +1,4 @@
/*
/*
filesystem.c - game filesystem based on DP fs
Copyright (C) 2003-2006 Mathieu Olivier
Copyright (C) 2000-2007 DarkPlaces contributors
@@ -21,12 +21,6 @@ GNU General Public License for more details.
#include "library.h"
#include "platform/platform.h"
CVAR_DEFINE_AUTO( fs_mount_hd, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount high definition content folder" );
CVAR_DEFINE_AUTO( fs_mount_lv, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount low violence models content folder" );
CVAR_DEFINE_AUTO( fs_mount_addon, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount addon content folder" );
CVAR_DEFINE_AUTO( fs_mount_l10n, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount localization content folder" );
CVAR_DEFINE_AUTO( ui_language, "english", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "selected game language" );
fs_api_t g_fsapi;
fs_globals_t *FI;
@@ -75,23 +69,9 @@ void *FS_GetNativeObject( const char *obj )
return NULL;
}
void FS_Rescan_f( void )
static void FS_Rescan_f( void )
{
uint32_t flags = 0;
// FIXME: VFS shouldn't care about this, allow engine to mount gamedirs
if( fs_mount_lv.value ) SetBits( flags, FS_MOUNT_LV );
if( fs_mount_hd.value ) SetBits( flags, FS_MOUNT_HD );
if( fs_mount_addon.value ) SetBits( flags, FS_MOUNT_ADDON );
if( fs_mount_l10n.value ) SetBits( flags, FS_MOUNT_L10N );
g_fsapi.Rescan( flags, ui_language.string );
ClearBits( fs_mount_lv.flags, FCVAR_CHANGED );
ClearBits( fs_mount_hd.flags, FCVAR_CHANGED );
ClearBits( fs_mount_addon.flags, FCVAR_CHANGED );
ClearBits( fs_mount_l10n.flags, FCVAR_CHANGED );
ClearBits( ui_language.flags, FCVAR_CHANGED );
FS_Rescan();
}
static void FS_ClearPaths_f( void )
@@ -256,12 +236,6 @@ static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
return false;
}
void FS_CheckConfig( void )
{
if( fs_mount_lv.value || fs_mount_hd.value || fs_mount_addon.value || fs_mount_l10n.value )
FS_Rescan_f();
}
/*
================
FS_Init
@@ -314,11 +288,6 @@ void FS_Init( const char *basedir )
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_make_gameinfo", FS_MakeGameInfo_f, "create gameinfo.txt for current running game" );
Cvar_RegisterVariable( &fs_mount_hd );
Cvar_RegisterVariable( &fs_mount_lv );
Cvar_RegisterVariable( &fs_mount_addon );
Cvar_RegisterVariable( &fs_mount_l10n );
if( !Sys_GetParmFromCmdLine( "-dll", host.gamedll ))
host.gamedll[0] = 0;

View File

@@ -140,8 +140,7 @@ static void Sys_PrintUsage( const char *exename )
"\nCommon options:\n"
O("-dev [level] ", "set log verbosity 0-2")
O("-log [file name] ", "write log to \"engine.log\" or [file name] if specified")
O("-logtime ", "enable writing timestamps to the log file")
O("-log ", "write log to \"engine.log\"")
O("-nowriteconfig ", "disable config save")
O("-noch ", "disable crashhandler")
#if XASH_WIN32 // !!!!
@@ -698,17 +697,17 @@ static qboolean Host_Autosleep( double dt, double scale )
static double timewindow; // allocate a time window for sleeps
static int counter; // for debug
static double realsleeptime;
const double sleeptime = sleep * 0.000001;
const double sleeptime = sleep * 0.001;
if( dt < targetframetime * scale )
{
// if we have allocated time window, try to sleep
if( timewindow > realsleeptime )
{
// Platform_Sleep isn't guaranteed to sleep an exact amount of microseconds
// Platform_Sleep isn't guaranteed to sleep an exact amount of milliseconds
// so we measure the real sleep time and use it to decrease the window
double t1 = Sys_DoubleTime(), t2;
Platform_NanoSleep( sleep * 1000 ); // in usec!
Platform_Sleep( sleep ); // in msec!
t2 = Sys_DoubleTime();
realsleeptime = t2 - t1;
@@ -1044,7 +1043,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
}
if( !Sys_CheckParm( "-noch" ))
Sys_SetupCrashHandler( argv[0] );
Sys_SetupCrashHandler();
#if XASH_DLL_LOADER
host.enabledll = !Sys_CheckParm( "-nodll" );
@@ -1311,7 +1310,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_RemoveCommand( "setgl" );
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
SCR_CheckStartupVids(); // must be last
FS_CheckConfig();
if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
Cbuf_AddTextf( "timedemo %s\n", demoname );

View File

@@ -419,21 +419,14 @@ void NET_InitMasters( void )
Cvar_RegisterVariable( &sv_verbose_heartbeats );
{ // IPv4-only
NET_AddMaster( "mentality.rip:27010", false, false );
NET_AddMaster( "ms2.mentality.rip:27010", false, false );
NET_AddMaster( "ms3.mentality.rip:27010", false, false );
}
// keep main master always there
NET_AddMaster( MASTERSERVER_ADR, false, false );
NET_AddMaster( "mentality.rip:27011", false, false ); // testing server, might be offline
NET_AddMaster( "ms2.mentality.rip:27010", false, false ); // secondary master
{ // IPv6-only
NET_AddMaster( "aaaa.mentality.rip:27010", false, true );
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, true );
}
{ // testing servers, might be offline
NET_AddMaster( "mentality.rip:27011", false, false );
NET_AddMaster( "aaaa.mentality.rip:27011", false, true );
}
NET_AddMaster( "aaaa.mentality.rip:27010", false, true ); // IPv6-only
NET_AddMaster( "aaaa.mentality.rip:27011", false, true ); // IPv6-only, testing server, might be offline
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, false ); // secondary IPv6-only master
NET_LoadMasters( );
}

View File

@@ -382,7 +382,8 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
for( j = numbones - 1; j >= 0; j-- )
{
i = boneused[j];
R_StudioCalcBones( frame, s, &pbone[i], &panim[i], adj, pos[i], q[i] );
R_StudioCalcBoneQuaternion( frame, s, &pbone[i], &panim[i], adj, q[i] );
R_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
}
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
@@ -723,7 +724,7 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean i
{
for( k = 0; k < pseqdesc->numframes; k++ )
{
R_StudioCalcBones( k, 0, &pbones[j], panim, NULL, pos, NULL );
R_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos );
Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos );
}
}

View File

@@ -151,24 +151,17 @@ static inline qboolean NET_IsSocketValid( int socket )
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr )
{
memcpy( &ip6[0], adr->ip6_0, 2 );
memcpy( &ip6[2], adr->ip6_1, 14 );
memcpy( ip6, adr->ip6, sizeof( adr->ip6 ));
}
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 )
{
memcpy( adr->ip6_0, &ip6[0], 2 );
memcpy( adr->ip6_1, &ip6[2], 14 );
memcpy( adr->ip6, ip6, sizeof( adr->ip6 ));
}
static int NET_NetadrIP6Compare( const netadr_t *a, const netadr_t *b )
{
uint8_t ip6_a[16], ip6_b[16];
NET_NetadrToIP6Bytes( ip6_a, a );
NET_NetadrToIP6Bytes( ip6_b, b );
return memcmp( ip6_a, ip6_b, sizeof( ip6_a ));
return memcmp( a->ip6, b->ip6, sizeof( a->ip6 ));
}
/*
@@ -178,29 +171,27 @@ NET_NetadrToSockadr
*/
static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
{
netadrtype_t type = NET_NetadrType( a );
memset( s, 0, sizeof( *s ));
if( type == NA_BROADCAST )
if( a->type == NA_BROADCAST )
{
s->ss_family = AF_INET;
((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
}
else if( type == NA_IP )
else if( a->type == NA_IP )
{
s->ss_family = AF_INET;
((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
}
else if( type == NA_IP6 )
else if( a->type6 == NA_IP6 )
{
s->ss_family = AF_INET6;
((struct sockaddr_in6 *)s)->sin6_port = a->port;
NET_NetadrToIP6Bytes(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, a );
}
else if( type == NA_MULTICAST_IP6 )
else if( a->type6 == NA_MULTICAST_IP6 )
{
s->ss_family = AF_INET6;
((struct sockaddr_in6 *)s)->sin6_port = a->port;
@@ -217,13 +208,13 @@ static void NET_SockadrToNetadr( const struct sockaddr_storage *s, netadr_t *a )
{
if( s->ss_family == AF_INET )
{
NET_NetadrSetType( a, NA_IP );
a->type = NA_IP;
a->ip4 = ((struct sockaddr_in *)s)->sin_addr.s_addr;
a->port = ((struct sockaddr_in *)s)->sin_port;
}
else if( s->ss_family == AF_INET6 )
{
NET_NetadrSetType( a, NA_IP6 );
a->type6 = NA_IP6;
NET_IP6BytesToNetadr( a, ((struct sockaddr_in6 *)s)->sin6_addr.s6_addr );
a->port = ((struct sockaddr_in6 *)s)->sin6_port;
}
@@ -558,8 +549,8 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
// try to parse as IPv6 first
if( ParseIPv6Addr( copy, ip6, NULL, NULL ))
{
NET_NetadrSetType( adr, NA_IP6 );
NET_IP6BytesToNetadr( adr, ip6 );
adr->type6 = NA_IP6;
if( !hasCIDR )
*prefixlen = 128;
@@ -629,7 +620,7 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
adr->ip4 = ntohl( mask );
}
NET_NetadrSetType( adr, NA_IP );
adr->type = NA_IP;
}
return true;
@@ -643,11 +634,10 @@ NET_AdrToString
const char *NET_AdrToString( const netadr_t a )
{
static char s[64];
netadrtype_t type = NET_NetadrType( &a );
if( type == NA_LOOPBACK )
if( a.type == NA_LOOPBACK )
return "loopback";
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@@ -671,11 +661,10 @@ NET_BaseAdrToString
const char *NET_BaseAdrToString( const netadr_t a )
{
static char s[64];
netadrtype_t type = NET_NetadrType( &a );
if( type == NA_LOOPBACK )
if( a.type == NA_LOOPBACK )
return "loopback";
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@@ -700,19 +689,16 @@ Compares without the port
*/
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
{
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b )
if( a.type6 != b.type6 )
return false;
if( type_a == NA_LOOPBACK )
if( a.type == NA_LOOPBACK )
return true;
if( type_a == NA_IP )
if( a.type == NA_IP )
return a.ip4 == b.ip4;
if( type_a == NA_IP6 )
if( a.type6 == NA_IP6 )
{
if( !NET_NetadrIP6Compare( &a, &b ))
return true;
@@ -721,6 +707,36 @@ qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
return false;
}
/*
====================
NET_CompareClassBAdr
Compare local masks
====================
*/
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b )
{
if( a.type6 != b.type6 )
return false;
if( a.type == NA_LOOPBACK )
return true;
if( a.type == NA_IP )
{
if( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] )
return true;
}
// NOTE: we don't check for IPv6 here
// this check is very dumb and only used for LAN restriction
// Actual check is in IsReservedAdr
// for real mask compare use NET_CompareAdrByMask
return false;
}
/*
====================
NET_CompareAdrByMask
@@ -730,13 +746,10 @@ Checks if adr is a part of subnet
*/
qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixlen )
{
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b || type_a == NA_LOOPBACK )
if( a.type6 != b.type6 || a.type == NA_LOOPBACK )
return false;
if( type_a == NA_IP )
if( a.type == NA_IP )
{
uint32_t ipa = htonl( a.ip4 );
uint32_t ipb = htonl( b.ip4 );
@@ -744,7 +757,7 @@ qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixle
if(( ipa & (( 0xFFFFFFFFU ) << ( 32 - prefixlen ))) == ipb )
return true;
}
else if( type_a == NA_IP6 )
else if( a.type6 == NA_IP6 )
{
uint16_t a_[8], b_[8];
size_t check = prefixlen / 16;
@@ -785,13 +798,11 @@ Check for reserved ip's
*/
qboolean NET_IsReservedAdr( netadr_t a )
{
netadrtype_t type_a = NET_NetadrType( &a );
if( type_a == NA_LOOPBACK )
if( a.type == NA_LOOPBACK )
return true;
// Following checks was imported from GameNetworkingSockets library
if( type_a == NA_IP )
if( a.type == NA_IP )
{
if(( a.ip[0] == 10 ) || // 10.x.x.x is reserved
( a.ip[0] == 127 ) || // 127.x.x.x
@@ -803,7 +814,7 @@ qboolean NET_IsReservedAdr( netadr_t a )
}
}
if( type_a == NA_IP6 )
if( a.type6 == NA_IP6 )
{
uint8_t ip6[16];
@@ -836,23 +847,20 @@ Compare full address
*/
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b )
{
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b )
if( a.type6 != b.type6 )
return false;
if( type_a == NA_LOOPBACK )
if( a.type == NA_LOOPBACK )
return true;
if( type_a == NA_IP )
if( a.type == NA_IP )
{
if( a.ip4 == b.ip4 && a.port == b.port )
return true;
return false;
}
if( type_a == NA_IP6 )
if( a.type6 == NA_IP6 )
{
if( a.port == b.port && !NET_NetadrIP6Compare( &a, &b ))
return true;
@@ -875,13 +883,9 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
{
const netadr_t *a = _a, *b = _b;
int porta, portb, portdiff, addrdiff;
netadrtype_t type_a, type_b;
type_a = NET_NetadrType( a );
type_b = NET_NetadrType( b );
if( type_a != type_b )
return bound( -1, (int)type_a - (int)type_b, 1 );
if( a->type6 != b->type6 )
return bound( -1, (int)a->type6 - (int)b->type6, 1 );
porta = ntohs( a->port );
portb = ntohs( b->port );
@@ -892,7 +896,7 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
else
portdiff = 0;
switch( type_a )
switch( a->type6 )
{
case NA_IP6:
if(( addrdiff = NET_NetadrIP6Compare( a, b )))
@@ -900,7 +904,14 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
// fallthrough
case NA_MULTICAST_IP6:
return portdiff;
}
// don't check for full type earlier, as it's value depends on v6 address
if( a->type != b->type )
return bound( -1, (int)a->type - (int)b->type, 1 );
switch( a->type )
{
case NA_IP:
if(( addrdiff = memcmp( a->ip, b->ip, sizeof( a->ipx ))))
return addrdiff;
@@ -935,7 +946,7 @@ static qboolean NET_StringToAdrEx( const char *string, netadr_t *adr, int family
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{
NET_NetadrSetType( adr, NA_LOOPBACK );
adr->type = NA_LOOPBACK;
return true;
}
@@ -960,7 +971,7 @@ net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{
NET_NetadrSetType( adr, NA_LOOPBACK );
adr->type = NA_LOOPBACK;
return NET_EAI_OK;
}
@@ -1006,7 +1017,7 @@ static qboolean NET_GetLoopPacket( netsrc_t sock, netadr_t *from, byte *data, si
*length = loop->msgs[i].datalen;
memset( from, 0, sizeof( *from ));
NET_NetadrSetType( from, NA_LOOPBACK );
from->type = NA_LOOPBACK;
return true;
}
@@ -1512,7 +1523,7 @@ static int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t
total_sent += size;
len -= size;
packet_number++;
Platform_NanoSleep( 100 * 1000 );
Platform_Sleep( 1 );
}
return total_sent;
@@ -1535,20 +1546,19 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
int ret;
struct sockaddr_storage addr = { 0 };
SOCKET net_socket = 0;
netadrtype_t type = NET_NetadrType( &to );
if( !net.initialized || type == NA_LOOPBACK )
if( !net.initialized || to.type == NA_LOOPBACK )
{
NET_SendLoopPacket( sock, length, data, to );
return;
}
else if( type == NA_BROADCAST || type == NA_IP )
else if( to.type == NA_BROADCAST || to.type == NA_IP )
{
net_socket = net.ip_sockets[sock];
if( !NET_IsSocketValid( net_socket ))
return;
}
else if( type == NA_MULTICAST_IP6 || type == NA_IP6 )
else if( to.type6 == NA_MULTICAST_IP6 || to.type6 == NA_IP6 )
{
net_socket = net.ip6_sockets[sock];
if( !NET_IsSocketValid( net_socket ))
@@ -1556,7 +1566,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
}
else
{
Host_Error( "%s: bad address type %i (%i, %i)\n", __func__, to.type, to.ip6_0[0], to.ip6_0[1] );
Host_Error( "%s: bad address type %i (%i)\n", __func__, to.type, to.type6 );
}
NET_NetadrToSockadr( &to, &addr );
@@ -1572,7 +1582,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
return;
// some PPP links don't allow broadcasts
if( err == WSAEADDRNOTAVAIL && ( type == NA_BROADCAST || type == NA_MULTICAST_IP6 ))
if( err == WSAEADDRNOTAVAIL && ( to.type == NA_BROADCAST || to.type6 == NA_MULTICAST_IP6 ))
return;
if( Host_IsDedicated( ))

View File

@@ -64,6 +64,7 @@ void NET_Config( qboolean net_enable, qboolean changeport );
const char *NET_AdrToString( const netadr_t a ) RETURNS_NONNULL;
const char *NET_BaseAdrToString( const netadr_t a ) RETURNS_NONNULL;
qboolean NET_IsReservedAdr( netadr_t a );
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b );
qboolean NET_StringToAdr( const char *string, netadr_t *adr );
qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen );
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v6only );
@@ -79,7 +80,7 @@ void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr );
static inline qboolean NET_IsLocalAddress( netadr_t adr )
{
return NET_NetadrType( &adr ) == NA_LOOPBACK;
return adr.type == NA_LOOPBACK ? true : false;
}
#if !XASH_DEDICATED

View File

@@ -69,6 +69,7 @@ GNU General Public License for more details.
// bytes will be stripped by the networking channel layer
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
#define MASTERSERVER_ADR "mentality.rip:27010"
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
#define PORT_MASTER 27010

View File

@@ -31,14 +31,15 @@ GNU General Public License for more details.
#define XASH_COLORIZE_CONSOLE 0
#endif
static struct logdata_s {
char title[64];
qboolean log_active;
qboolean log_time;
char log_path[MAX_SYSPATH];
FILE *logfile;
int logfileno;
} s_ld;
typedef struct {
char title[64];
qboolean log_active;
char log_path[MAX_SYSPATH];
FILE *logfile;
int logfileno;
} LogData;
static LogData s_ld;
void Sys_DestroyConsole( void )
{
@@ -77,19 +78,14 @@ static void Sys_FlushLogfile( void )
void Sys_InitLog( void )
{
const char *mode;
const char *mode;
if( Sys_CheckParm( "-log" ))
if( Sys_CheckParm( "-log" ) && host.allow_console != 0 )
{
if( !Sys_GetParmFromCmdLine( "-log", s_ld.log_path ) || !isalnum( s_ld.log_path[0] ))
Q_strncpy( s_ld.log_path, "engine.log", sizeof( s_ld.log_path ));
COM_DefaultExtension( s_ld.log_path, ".log", sizeof( s_ld.log_path ));
s_ld.log_active = true;
Q_strncpy( s_ld.log_path, "engine.log", sizeof( s_ld.log_path ));
}
s_ld.log_time = Sys_CheckParm( "-logtime" );
if( host.change_game && host.type != HOST_DEDICATED )
mode = "a";
else mode = "w";
@@ -105,7 +101,7 @@ void Sys_InitLog( void )
if ( !s_ld.logfile )
{
Con_Reportf( S_ERROR "%s: can't create log file %s: %s\n", __func__, s_ld.log_path, strerror( errno ));
Con_Reportf( S_ERROR "Sys_InitLog: can't create log file %s: %s\n", s_ld.log_path, strerror( errno ));
return;
}
@@ -299,23 +295,17 @@ void Sys_PrintLog( const char *pMsg )
// save last char to detect when line was not ended
lastchar = len > 0 ? pMsg[len - 1] : 0;
// spew to engine.log
if( s_ld.logfile )
{
if( s_ld.log_time && print_time )
{
logtime_len = strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S] ", crt_tm ); //full time
logtime_len = Q_min( logtime_len, sizeof( logtime ) - 1 ); // just in case
}
else
{
logtime[0] = '\0';
logtime_len = 0;
}
if( !s_ld.logfile )
return;
Sys_PrintLogfile( s_ld.logfileno, logtime, logtime_len, pMsg, false );
Sys_FlushLogfile();
if( print_time )
{
logtime_len = strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S] ", crt_tm ); //full time
logtime_len = Q_min( logtime_len, sizeof( logtime ) - 1 ); // just in case
}
Sys_PrintLogfile( s_ld.logfileno, logtime, logtime_len, pMsg, false );
Sys_FlushLogfile();
}
/*

View File

@@ -65,8 +65,6 @@ typedef struct memheader_s
// immediately followed by data, which is followed by a MEMHEADER_SENTINEL2 byte
} memheader_t;
STATIC_CHECK_SIZEOF( memheader_t, 24, 40 );
typedef struct mempool_s
{
struct memheader_s *chain; // chain of individual memory allocations

View File

@@ -184,7 +184,7 @@ qboolean SNDDMA_Init( void )
return false;
}
dma.buffer = Mem_Calloc( sndpool, samples * 2 ); //allocate pcm frame buffer
dma.buffer = Mem_Malloc( sndpool, samples * 2 ); //allocate pcm frame buffer
dma.samplepos = 0;
dma.samples = samples;
dma.format.width = 2;

View File

@@ -70,9 +70,6 @@ void Android_Shutdown( void );
#endif
#if XASH_WIN32
void Win32_Init( qboolean con_showalways );
void Win32_Shutdown( void );
qboolean Win32_NanoSleep( int nsec );
void Wcon_CreateConsole( qboolean con_showalways );
void Wcon_DestroyConsole( void );
void Wcon_InitConsoleCommands( void );
@@ -127,7 +124,7 @@ static inline void Platform_Init( qboolean con_showalways, const char *basedir )
#elif XASH_DOS
DOS_Init( );
#elif XASH_WIN32
Win32_Init( con_showalways );
Wcon_CreateConsole( con_showalways );
#elif XASH_LINUX
Linux_Init( );
#endif
@@ -142,7 +139,7 @@ static inline void Platform_Shutdown( void )
#elif XASH_DOS
DOS_Shutdown( );
#elif XASH_WIN32
Win32_Shutdown( );
Wcon_DestroyConsole( );
#elif XASH_LINUX
Linux_Shutdown( );
#endif
@@ -181,28 +178,11 @@ static inline void Platform_Sleep( int msec )
#endif
}
static inline qboolean Platform_NanoSleep( int nsec )
{
// SDL2 doesn't have nanosleep, so use low-level functions here
// When this code will be ported to SDL3, use SDL_DelayNS
#if XASH_POSIX
struct timespec ts = {
.tv_sec = 0,
.tv_nsec = nsec, // just don't put large numbers here
};
return nanosleep( &ts, NULL ) == 0;
#elif XASH_WIN32
return Win32_NanoSleep( nsec );
#else
return false;
#endif
}
#if XASH_WIN32 || XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX || XASH_APPLE
void Sys_SetupCrashHandler( const char *argv0 );
void Sys_SetupCrashHandler( void );
void Sys_RestoreCrashHandler( void );
#else
static inline void Sys_SetupCrashHandler( const char *argv0 )
static inline void Sys_SetupCrashHandler( void )
{
}

View File

@@ -29,15 +29,9 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
void *addrs[16];
char **syms;
(void)context;
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
// safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch() );
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD && !XASH_APPLE // they don't have si_ptr
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
@@ -47,6 +41,10 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
write( STDERR_FILENO, message, len );
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
// now get log fd and write trace directly to log
logfd = Sys_LogFileNo();
write( logfd, message, len );

View File

@@ -1,186 +0,0 @@
/*
crashhandler.c - advanced crashhandler
Copyright (C) 2016 Mittorn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#if HAVE_LIBBACKTRACE
#include <signal.h>
#include "common.h"
#include "backtrace.h"
static struct backtrace_state *g_bt_state;
static qboolean enable_libbacktrace;
static void Sys_BacktraceError( void *data, const char *msg, int errnum )
{
if( errnum < 0 )
{
Con_Printf( S_ERROR "no symbol info, no libbacktrace\n" );
return;
}
Con_Printf( S_ERROR "libbacktrace error: %s (%d)\n", msg, errnum );
enable_libbacktrace = false;
}
struct print_data
{
char *message;
size_t message_size;
int len;
int idx;
int logfd;
};
static void Sys_AppendPrint( struct print_data *pd, const char *fmt, ... )
{
va_list va;
int len;
va_start( va, fmt );
len = Q_vsnprintf( pd->message, pd->message_size, fmt, va );
va_end( va );
if( len > 0 )
{
char ch = '\n';
write( pd->logfd, pd->message, len );
write( pd->logfd, &ch, 1 );
write( STDERR_FILENO, pd->message, len );
write( STDERR_FILENO, &ch, 1 );
pd->message += len;
pd->len += len;
pd->message_size -= len;
}
}
static void Sys_BacktracePrintError( void *data, const char *msg, int errnum )
{
struct print_data *pd = data;
Sys_AppendPrint( pd, "%2d: error: %s (%d)\n", pd->idx++, msg, errnum );
}
static void Sys_BacktracePrintSyminfo( void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize )
{
struct print_data *pd = data;
Dl_info dlinfo = { 0 };
const char *module_name;
if( dladdr((void *)pc, &dlinfo ))
module_name = dlinfo.dli_fname;
else module_name = NULL;
if( symname )
{
if( module_name )
Sys_AppendPrint( pd, "%2d: <%s+%d> (%s)\n", pd->idx++, symname, pc - symval, module_name );
else
Sys_AppendPrint( pd, "%2d: <%s+%d>\n", pd->idx++, symname, pc - symval );
}
else
{
if( module_name )
Sys_AppendPrint( pd, "%2d: %p (%s)\n", pd->idx++, pc, module_name );
else
Sys_AppendPrint( pd, "%2d: %p\n", pd->idx++, pc );
}
}
static int Sys_BacktracePrintFull( void *data, uintptr_t pc, const char *filename, int lineno, const char *function )
{
struct print_data *pd = data;
Dl_info dlinfo = { 0 };
const char *module_name;
if( dladdr((void *)pc, &dlinfo ))
module_name = dlinfo.dli_fname;
else module_name = NULL;
if( filename && lineno && function )
{
if( module_name )
Sys_AppendPrint( pd, "%2d: %s (%s:%d) (%s)\n", pd->idx++, function, filename, lineno, module_name );
else
Sys_AppendPrint( pd, "%2d: %s (%s:%d)\n", pd->idx++, function, filename, lineno );
}
else
{
backtrace_syminfo( g_bt_state, pc, Sys_BacktracePrintSyminfo, Sys_BacktraceError, data );
}
return 0;
}
void Sys_CrashLibbacktrace( int signal, siginfo_t *si, void *context )
{
char message[8192];
int len, logfd;
struct print_data pd = { .idx = 0 };
(void)context;
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
// safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD && !XASH_APPLE // they don't have si_ptr
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
#else
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
#endif
write( STDERR_FILENO, message, len );
// now get log fd and write trace directly to log
pd.logfd = logfd = Sys_LogFileNo();
write( logfd, message, len );
pd.message = message + len;
pd.message_size = sizeof( message ) - len;
pd.len = 0;
backtrace_full( g_bt_state, 1, Sys_BacktracePrintFull, Sys_BacktracePrintError, &pd );
// put MessageBox as Sys_Error
Msg( "%s\n", message );
#ifdef XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif
host.crashed = true;
Platform_MessageBox( "Xash Error", message, false );
// log saved, now we can try to save configs and close log correctly, it may crash
if( host.type == HOST_NORMAL )
CL_Crashed();
host.status = HOST_CRASHED;
Sys_Quit( "crashed" );
}
qboolean Sys_SetupLibbacktrace( const char *argv0 )
{
enable_libbacktrace = true;
g_bt_state = backtrace_create_state( argv0, true, Sys_BacktraceError, NULL );
return g_bt_state != NULL && enable_libbacktrace;
}
#endif // HAVE_EXECINFO

View File

@@ -28,8 +28,6 @@ GNU General Public License for more details.
#include "library.h"
void Sys_Crash( int signal, siginfo_t *si, void *context );
void Sys_CrashLibbacktrace( int signal, siginfo_t *si, void *context );
qboolean Sys_SetupLibbacktrace( const char *argv0 );
static struct sigaction oldFilter;
#if !HAVE_EXECINFO
@@ -47,16 +45,16 @@ static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
if( len <= 0 )
return 0; // overflow
if( dladdr( addr, &dlinfo ))
{
if( dlinfo.dli_sname )
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
if( dladdr( addr, &dlinfo ))
{
if( dlinfo.dli_sname )
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
}
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
}
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
}
void Sys_Crash( int signal, siginfo_t *si, void *context )
@@ -71,10 +69,6 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
ucontext_t *ucontext = (ucontext_t*)context;
#endif
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
#if XASH_AMD64
#if XASH_FREEBSD
pc = (void*)ucontext->uc_mcontext.mc_rip;
@@ -122,8 +116,8 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
#endif
// safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch() );
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD && !XASH_APPLE
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
@@ -133,6 +127,10 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
write( STDERR_FILENO, message, len );
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
// now get log fd and write trace directly to log
logfd = Sys_LogFileNo();
write( logfd, message, len );
@@ -208,25 +206,15 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
#endif // !HAVE_EXECINFO
void Sys_SetupCrashHandler( const char *argv0 )
void Sys_SetupCrashHandler( void )
{
struct sigaction act = { 0 };
#if HAVE_LIBBACKTRACE
if( Sys_SetupLibbacktrace( argv0 ))
{
act.sa_sigaction = Sys_CrashLibbacktrace;
}
else
#endif
{
act.sa_sigaction = Sys_Crash;
}
act.sa_sigaction = Sys_Crash;
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction( SIGSEGV, &act, &oldFilter );
sigaction( SIGABRT, &act, &oldFilter );
sigaction( SIGBUS, &act, &oldFilter );
sigaction( SIGILL, &act, &oldFilter );
}
void Sys_RestoreCrashHandler( void )

View File

@@ -481,19 +481,19 @@ static void SDLash_EventHandler( SDL_Event *event )
switch( event->window.event )
{
case SDL_WINDOWEVENT_MOVED:
{
char val[32];
if( vid_fullscreen.value == WINDOW_MODE_WINDOWED )
{
char val[32];
Q_snprintf( val, sizeof( val ), "%d", event->window.data1 );
Cvar_DirectSet( &window_xpos, val );
Q_snprintf( val, sizeof( val ), "%d", event->window.data1 );
Cvar_DirectSet( &window_xpos, val );
Q_snprintf( val, sizeof( val ), "%d", event->window.data2 );
Cvar_DirectSet( &window_ypos, val );
Q_snprintf( val, sizeof( val ), "%d", event->window.data2 );
Cvar_DirectSet( &window_ypos, val );
if ( vid_fullscreen.value == WINDOW_MODE_WINDOWED )
Cvar_DirectSet( &vid_maximized, "0" );
}
break;
}
case SDL_WINDOWEVENT_MINIMIZED:
host.status = HOST_SLEEP;
Cvar_DirectSet( &vid_maximized, "0" );

View File

@@ -33,12 +33,6 @@ static struct
} cursors;
#endif
static struct
{
int x, y;
qboolean pushed;
} in_visible_cursor_pos;
/*
=============
Platform_GetMousePos
@@ -209,6 +203,11 @@ void Platform_SetCursorType( VGUI_DefaultCursor type )
{
qboolean visible;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( !cursors.initialized )
return;
#endif
switch( type )
{
case dc_user:
@@ -221,7 +220,7 @@ void Platform_SetCursorType( VGUI_DefaultCursor type )
}
// never disable cursor in touch emulation mode
if( !visible && Touch_WantVisibleCursor( ))
if( !visible && Touch_Emulated( ))
return;
host.mouse_visible = visible;
@@ -230,28 +229,11 @@ void Platform_SetCursorType( VGUI_DefaultCursor type )
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( host.mouse_visible )
{
if( cursors.initialized )
SDL_SetCursor( cursors.cursors[type] );
SDL_SetCursor( cursors.cursors[type] );
SDL_ShowCursor( true );
// restore the last mouse position
if( in_visible_cursor_pos.pushed )
{
SDL_WarpMouseInWindow( host.hWnd, in_visible_cursor_pos.x, in_visible_cursor_pos.y );
in_visible_cursor_pos.pushed = false;
}
}
else
{
// save last mouse position and warp it to the center
if( !in_visible_cursor_pos.pushed )
{
SDL_GetMouseState( &in_visible_cursor_pos.x, &in_visible_cursor_pos.y );
SDL_WarpMouseInWindow( host.hWnd, host.window_center_x, host.window_center_y );
in_visible_cursor_pos.pushed = true;
}
SDL_ShowCursor( false );
}
#else

View File

@@ -171,18 +171,6 @@ static void SDLash_GameControllerAdded( int device_index )
return;
}
// this "game controller" only exists on Android within emulator and tries to map
// keyboard events into game controller events, which as you can expect, doesn't
// work and I don't understand the intention here. When debugging Xash in Android
// Studio emulator, just enable hardware input passthrough.
#if XASH_ANDROID
if( !Q_strcmp( SDL_GameControllerName( gc ), "qwerty2" ))
{
SDL_GameControllerClose( gc );
return;
}
#endif // XASH_ANDROID
list = Mem_Realloc( host.mempool, g_gamepads, sizeof( *list ) * ( g_num_gamepads + 1 ));
list[g_num_gamepads++] = gc;

View File

@@ -175,7 +175,7 @@ qboolean SNDDMA_Init( void )
if( !samplecount )
samplecount = 0x8000;
dma.samples = samplecount * obtained.channels;
dma.buffer = Mem_Calloc( sndpool, dma.samples * 2 );
dma.buffer = Mem_Malloc( sndpool, dma.samples * 2 );
dma.samplepos = 0;
sdl_format = obtained.format;

View File

@@ -257,8 +257,7 @@ static void R_InitVideoModes( void )
{
char buf[MAX_VA_STRING];
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_Point point = { window_xpos.value, window_ypos.value };
int displayIndex = SDL_GetPointDisplayIndex( &point );
int displayIndex = 0; // TODO: handle multiple displays somehow
int i, modes;
num_vidmodes = 0;
@@ -736,24 +735,6 @@ static qboolean VID_CreateWindowWithSafeGL( const char *wndname, int xpos, int y
return true;
}
static qboolean RectFitsInDisplay( const SDL_Rect *rect, const SDL_Rect *display )
{
return rect->x >= display->x
&& rect->y >= display->y
&& rect->x + rect->w <= display->x + display->w
&& rect->y + rect->h <= display->y + display->h;
}
// Function to check if the rectangle fits in any display
static qboolean RectFitsInAnyDisplay( const SDL_Rect *rect, const SDL_Rect *display_rects, int num_displays )
{
for( int i = 0; i < num_displays; i++ )
{
if( RectFitsInDisplay( rect, &display_rects[i] ))
return true; // Rectangle fits in this display
}
return false; // Rectangle does not fit in any display
}
/*
=================
VID_CreateWindow
@@ -766,8 +747,6 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
qboolean maximized = vid_maximized.value != 0.0f;
Uint32 wndFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_MOUSE_FOCUS;
int xpos, ypos;
int num_displays = SDL_GetNumVideoDisplays();
SDL_Rect rect = { window_xpos.value, window_ypos.value, width, height };
Q_strncpy( wndname, GI->title, sizeof( wndname ));
@@ -778,43 +757,35 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
if( window_mode == WINDOW_MODE_WINDOWED )
{
SDL_Rect *display_rects = ( SDL_Rect * )malloc( num_displays * sizeof( SDL_Rect ));
SDL_Rect r;
SetBits( wndFlags, SDL_WINDOW_RESIZABLE );
if( maximized )
SetBits( wndFlags, SDL_WINDOW_MAXIMIZED );
if( !display_rects )
#if SDL_VERSION_ATLEAST( 2, 0, 5 )
if( SDL_GetDisplayUsableBounds( 0, &r ) < 0 &&
SDL_GetDisplayBounds( 0, &r ) < 0 )
#else
if( SDL_GetDisplayBounds( 0, &r ) < 0 )
#endif
{
Con_Printf( S_ERROR "Failed to allocate memory for display rects!\n" );
xpos = SDL_WINDOWPOS_UNDEFINED;
ypos = SDL_WINDOWPOS_UNDEFINED;
Con_Reportf( S_ERROR "%s: SDL_GetDisplayBounds failed: %s\n", __func__, SDL_GetError( ));
xpos = SDL_WINDOWPOS_CENTERED;
ypos = SDL_WINDOWPOS_CENTERED;
}
else
{
for( int i = 0; i < num_displays; i++ )
{
if( SDL_GetDisplayBounds( i, &display_rects[i] ) != 0 )
{
Con_Printf( S_ERROR "Failed to get bounds for display %d! SDL_Error: %s\n", i, SDL_GetError());
display_rects[i] = ( SDL_Rect ){ 0, 0, 0, 0 };
}
}
// Check if the rectangle fits in any display
if( !RectFitsInAnyDisplay( &rect, display_rects, num_displays ))
{
// Rectangle doesn't fit in any display, center it
xpos = window_xpos.value;
ypos = window_ypos.value;
// don't create window outside of usable display space
if( xpos < r.x || xpos + width > r.x + r.w )
xpos = SDL_WINDOWPOS_CENTERED;
if( ypos < r.y || ypos + height > r.y + r.h )
ypos = SDL_WINDOWPOS_CENTERED;
Con_Printf( S_ERROR "Rectangle does not fit in any display. Centering window.\n" );
}
else
{
xpos = rect.x;
ypos = rect.y;
}
}
free( display_rects );
}
else
{
@@ -824,16 +795,7 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
else
SetBits( wndFlags, SDL_WINDOW_FULLSCREEN_DESKTOP );
SetBits( wndFlags, SDL_WINDOW_BORDERLESS );
if ( window_xpos.value < 0 || window_ypos.value < 0 )
{
xpos = SDL_WINDOWPOS_UNDEFINED;
ypos = SDL_WINDOWPOS_UNDEFINED;
}
else
{
xpos = window_xpos.value;
ypos = window_ypos.value;
}
xpos = ypos = 0;
}
if( !VID_CreateWindowWithSafeGL( wndname, xpos, ypos, width, height, wndFlags ))
@@ -1056,8 +1018,7 @@ qboolean R_Init_Video( const int type )
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_DisplayMode displayMode;
SDL_Point point = { window_xpos.value, window_ypos.value };
SDL_GetCurrentDisplayMode( SDL_GetPointDisplayIndex( &point ), &displayMode );
SDL_GetCurrentDisplayMode( 0, &displayMode );
refState.desktopBitsPixel = SDL_BITSPERPIXEL( displayMode.format );
#else
refState.desktopBitsPixel = 16;

View File

@@ -49,6 +49,10 @@ typedef struct
qboolean inputEnabled;
qboolean consoleVisible;
qboolean attached;
// log stuff
qboolean log_active;
char log_path[MAX_SYSPATH];
} WinConData;
static WinConData s_wcd;
@@ -498,13 +502,19 @@ create win32 console
*/
void Wcon_CreateConsole( qboolean con_showalways )
{
if( Sys_CheckParm( "-log" ))
s_wcd.log_active = true;
if( host.type == HOST_NORMAL )
{
Q_strncpy( s_wcd.title, XASH_ENGINE_NAME " " XASH_VERSION, sizeof( s_wcd.title ));
Q_strncpy( s_wcd.log_path, "engine.log", sizeof( s_wcd.log_path ));
}
else // dedicated console
{
Q_strncpy( s_wcd.title, XASH_DEDICATED_SERVER_NAME " " XASH_VERSION, sizeof( s_wcd.title ));
Q_strncpy( s_wcd.log_path, "dedicated.log", sizeof( s_wcd.log_path ));
s_wcd.log_active = true; // always make log
}
s_wcd.attached = ( AttachConsole( ATTACH_PARENT_PROCESS ) != 0 );
@@ -586,8 +596,10 @@ void Wcon_DestroyConsole( void )
// last text message into console or log
Con_Reportf( "%s: Unloading xash.dll\n", __func__ );
Sys_CloseLog( NULL );
if( !s_wcd.attached )
{
{
if( s_wcd.hWnd )
{
ShowWindow( s_wcd.hWnd, SW_HIDE );

View File

@@ -318,7 +318,7 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
return EXCEPTION_CONTINUE_EXECUTION;
}
void Sys_SetupCrashHandler( const char *argv0 )
void Sys_SetupCrashHandler( void )
{
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors
oldFilter = SetUnhandledExceptionFilter( Sys_Crash );

View File

@@ -18,8 +18,6 @@ GNU General Public License for more details.
#include "server.h"
#include <shellapi.h>
HANDLE g_waitable_timer;
#if XASH_TIMER == TIMER_WIN32
double Platform_DoubleTime( void )
{
@@ -38,67 +36,6 @@ double Platform_DoubleTime( void )
}
#endif // XASH_TIMER == TIMER_WIN32
void Win32_Init( qboolean con_showalways )
{
HMODULE hModule = LoadLibrary( "kernel32.dll" );
if( hModule )
{
HANDLE ( __stdcall *pfnCreateWaitableTimerExW)( LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess );
if(( pfnCreateWaitableTimerExW = (void *)GetProcAddress( hModule, "CreateWaitableTimerExW" )))
{
g_waitable_timer = pfnCreateWaitableTimerExW(
NULL,
NULL,
0x1 /* CREATE_WAITABLE_TIMER_MANUAL_RESET */ | 0x2 /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION */,
0x0002 /* TIMER_MODIFY_STATE */ | SYNCHRONIZE | DELETE
);
}
FreeLibrary( hModule );
}
#if 0 // FIXME: creates object but doesn't wait for specific time for me on Windows 10, with the code above commented
if( !g_waitable_timer )
g_waitable_timer = CreateWaitableTimer( NULL, TRUE, NULL );
#endif
Wcon_CreateConsole( con_showalways );
}
void Win32_Shutdown( void )
{
Wcon_DestroyConsole( );
if( g_waitable_timer )
{
CloseHandle( g_waitable_timer );
g_waitable_timer = 0;
}
}
qboolean Win32_NanoSleep( int nsec )
{
LARGE_INTEGER ts;
if( !g_waitable_timer )
return false;
ts.QuadPart = -nsec / 100;
if( !SetWaitableTimer( g_waitable_timer, &ts, 0, NULL, NULL, FALSE ))
{
CloseHandle( g_waitable_timer );
g_waitable_timer = 0;
return false;
}
if( WaitForSingleObject( g_waitable_timer, Q_max( 1, nsec / 1000000 )) != WAIT_OBJECT_0 )
return false;
return true;
}
qboolean Platform_DebuggerPresent( void )
{
return IsDebuggerPresent();

View File

@@ -348,7 +348,7 @@ typedef struct ref_api_s
void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
void (*CL_CenterPrint)( const char *s, float y );
void (*Con_DrawStringLen)( const char *pText, int *length, int *height );
int (*Con_DrawString)( int x, int y, const char *string, const rgba_t setColor );
int (*Con_DrawString)( int x, int y, const char *string, rgba_t setColor );
void (*CL_DrawCenterPrint)( void );
// entity management

View File

@@ -279,6 +279,19 @@ typedef struct sv_client_s
a program error, like an overflowed reliable buffer
=============================================================================
*/
// MAX_CHALLENGES is made large to prevent a denial
// of service attack that could cycle all of them
// out before legitimate users connected
#define MAX_CHALLENGES 1024
typedef struct
{
netadr_t adr;
double time;
int challenge;
qboolean connected;
} challenge_t;
typedef struct
{
char name[32]; // in GoldSrc max name length is 12
@@ -372,7 +385,7 @@ typedef struct
entity_state_t *baselines; // [GI->max_edicts]
entity_state_t *static_entities; // [MAX_STATIC_ENTITIES];
uint32_t challenge_salt[16]; // pregenerated random numbers for generating challenged based on IP's MD5 address
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
sizebuf_t testpacket; // pregenerataed testpacket, only needs CRC32 patching
byte *testpacket_buf; // check for NULL if testpacket is available

View File

@@ -86,54 +86,38 @@ flood the server with invalid connection IPs. With a
challenge, they must give a valid IP address.
=================
*/
static int SV_GetChallenge( netadr_t from, qboolean *error )
static void SV_GetChallenge( netadr_t from )
{
const netadrtype_t type = NET_NetadrType( &from );
MD5Context_t ctx;
byte digest[16];
int i, oldest = 0;
double oldestTime;
*error = false;
oldestTime = 0x7fffffff;
MD5Init( &ctx );
switch( type )
// see if we already have a challenge for this ip
for( i = 0; i < MAX_CHALLENGES; i++ )
{
case NA_IP:
MD5Update( &ctx, from.ip, sizeof( from.ip ));
break;
case NA_IPX:
MD5Update( &ctx, from.ipx, sizeof( from.ipx ));
break;
case NA_IP6:
{
byte ip6[16];
NET_NetadrToIP6Bytes( ip6, &from );
MD5Update( &ctx, ip6, sizeof( ip6 ));
break;
}
case NA_LOOPBACK:
return 0;
default:
*error = true;
return 0;
if( !svs.challenges[i].connected && NET_CompareAdr( from, svs.challenges[i].adr ))
break;
if( svs.challenges[i].time < oldestTime )
{
oldestTime = svs.challenges[i].time;
oldest = i;
}
}
MD5Update( &ctx, (byte *)svs.challenge_salt, sizeof( svs.challenge_salt ));
MD5Final( digest, &ctx );
return digest[0] | digest[1] << 8 | digest[2] << 16 | digest[3] << 24;
}
static void SV_SendChallenge( netadr_t from )
{
qboolean error = false;
int challenge = SV_GetChallenge( from, &error );
if( error )
return;
if( i == MAX_CHALLENGES )
{
// this is the first time this client has asked for a challenge
svs.challenges[oldest].challenge = (COM_RandomLong( 0, 0x7FFF ) << 16) | COM_RandomLong( 0, 0xFFFF );
svs.challenges[oldest].adr = from;
svs.challenges[oldest].time = host.realtime;
svs.challenges[oldest].connected = false;
i = oldest;
}
// send it back
Netchan_OutOfBandPrint( NS_SERVER, from, S2C_CHALLENGE" %i", challenge );
Netchan_OutOfBandPrint( NS_SERVER, svs.challenges[i].adr, S2C_CHALLENGE" %i", svs.challenges[i].challenge );
}
static int SV_GetFragmentSize( void *pcl, fragsize_t mode )
@@ -227,16 +211,35 @@ Make sure connecting client is not spoofing
*/
static int SV_CheckChallenge( netadr_t from, int challenge )
{
qboolean error = false;
int challenge2 = SV_GetChallenge( from, &error );
int i;
if( error || challenge2 != challenge )
// see if the challenge is valid
// don't care if it is a local address.
if( NET_IsLocalAddress( from ))
return 1;
for( i = 0; i < MAX_CHALLENGES; i++ )
{
SV_RejectConnection( from, "no challenge for your address\n" );
return false;
if( NET_CompareAdr( from, svs.challenges[i].adr ))
{
if( challenge == svs.challenges[i].challenge )
break; // valid challenge
#if 0
// g-cont. this breaks multiple connections from single machine
SV_RejectConnection( from, "bad challenge %i\n", challenge );
return 0;
#endif
}
}
return true;
if( i == MAX_CHALLENGES )
{
SV_RejectConnection( from, "no challenge for your address\n" );
return 0;
}
svs.challenges[i].connected = true;
return 1;
}
/*
@@ -250,7 +253,7 @@ static int SV_CheckIPRestrictions( netadr_t from )
{
if( sv_lan.value )
{
if( !NET_IsReservedAdr( from ))
if( !NET_CompareClassBAdr( from, net_local ) && !NET_IsReservedAdr( from ))
return 0;
}
return 1;
@@ -264,17 +267,23 @@ Get slot # and set client_t pointer for player, if possible
We don't do this search on a "reconnect, we just reuse the slot
================
*/
static sv_client_t *SV_FindEmptySlot( void )
static int SV_FindEmptySlot( netadr_t from, int *pslot, sv_client_t **ppClient )
{
int i;
sv_client_t *cl;
int i;
for( i = 0; i < svs.maxclients; i++ )
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
if( svs.clients[i].state == cs_free )
return &svs.clients[i];
if( cl->state == cs_free )
{
*ppClient = cl;
*pslot = i;
return 1;
}
}
return NULL;
SV_RejectConnection( from, "server is full\n" );
return 0;
}
/*
@@ -286,13 +295,15 @@ A connection request that did not come from the master
*/
static void SV_ConnectClient( netadr_t from )
{
char userinfo[MAX_INFO_STRING];
char protinfo[MAX_INFO_STRING];
sv_client_t *newcl = NULL;
int qport, version;
int i, count = 0;
int challenge;
const char *s;
char userinfo[MAX_INFO_STRING];
char protinfo[MAX_INFO_STRING];
sv_client_t *cl, *newcl = NULL;
qboolean reconnect = false;
int nClientSlot = 0;
int qport, version;
int i, count = 0;
int challenge;
const char *s;
int extensions;
uint netchan_flags = 0;
@@ -310,6 +321,39 @@ static void SV_ConnectClient( netadr_t from )
return;
}
challenge = Q_atoi( Cmd_Argv( 2 )); // get challenge
// see if the challenge is valid (local clients don't need to challenge)
if( !SV_CheckChallenge( from, challenge ))
return;
s = Cmd_Argv( 3 ); // protocol info
if( !Info_IsValid( s ))
{
SV_RejectConnection( from, "invalid protinfo in connect command\n" );
return;
}
Q_strncpy( protinfo, s, sizeof( protinfo ));
if( !SV_ProcessUserAgent( from, protinfo ) )
{
return;
}
// extract qport from protocol info
qport = Q_atoi( Info_ValueForKey( protinfo, "qport" ));
s = Info_ValueForKey( protinfo, "uuid" );
if( Q_strlen( s ) != 32 )
{
SV_RejectConnection( from, "invalid authentication certificate length\n" );
return;
}
extensions = Q_atoi( Info_ValueForKey( protinfo, "ext" ) );
// LAN servers restrict to class b IP addresses
if( !SV_CheckIPRestrictions( from ))
{
@@ -317,37 +361,9 @@ static void SV_ConnectClient( netadr_t from )
return;
}
challenge = Q_atoi( Cmd_Argv( 2 )); // get challenge
// see if the challenge is valid (local clients don't need to challenge)
if( !SV_CheckChallenge( from, challenge ))
return;
s = Cmd_Argv( 3 );
if( Q_strlen( s ) > sizeof( protinfo ) || !Info_IsValid( s ))
{
SV_RejectConnection( from, "invalid protinfo in connect command\n" );
return;
}
Q_strncpy( protinfo, s, sizeof( protinfo )); // protocol info
if( !SV_ProcessUserAgent( from, protinfo ))
return;
if( Q_strlen( Info_ValueForKey( protinfo, "uuid" )) != 32 )
{
SV_RejectConnection( from, "invalid authentication certificate length\n" );
return;
}
// extract qport from protocol info
qport = Q_atoi( Info_ValueForKey( protinfo, "qport" ));
extensions = Q_atoi( Info_ValueForKey( protinfo, "ext" ));
s = Cmd_Argv( 4 ); // user info
if( Q_strlen( s ) > sizeof( userinfo ) || !Info_IsValid( s ))
if( Q_strlen( s ) > MAX_INFO_STRING || !Info_IsValid( s ))
{
SV_RejectConnection( from, "invalid userinfo in connect command\n" );
return;
@@ -366,43 +382,43 @@ static void SV_ConnectClient( netadr_t from )
}
// if there is already a slot for this ip, reuse it
for( i = 0; i < svs.maxclients; i++ )
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
sv_client_t *cl = &svs.clients[i];
if( cl->state == cs_free || cl->state == cs_zombie )
continue;
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
{
reconnect = true;
newcl = cl;
Con_Reportf( S_NOTE "%s:reconnect\n", NET_AdrToString( from ));
break;
}
}
// A reconnecting client will re-use the slot found above when checking for reconnection.
// the slot will be wiped clean.
if( !newcl )
if( !reconnect )
{
// connect the client if there are empty slots.
newcl = SV_FindEmptySlot();
if( !newcl )
{
SV_RejectConnection( from, "server is full\n" );
if( !SV_FindEmptySlot( from, &nClientSlot, &newcl ))
return;
}
}
else
{
Con_Reportf( S_NOTE "%s:reconnect\n", NET_AdrToString( from ));
}
// find a client slot
ASSERT( newcl != NULL );
// build a new connection
// accept the new client
sv.current_client = newcl;
newcl->edict = EDICT_NUM(( newcl - svs.clients ) + 1 );
newcl->edict = EDICT_NUM( (newcl - svs.clients) + 1 );
newcl->challenge = challenge; // save challenge for checksumming
newcl->frames = (client_frame_t *)Mem_Realloc( host.mempool, newcl->frames, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
memset( newcl->frames, 0, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
if( newcl->frames ) Mem_Free( newcl->frames );
newcl->frames = (client_frame_t *)Z_Calloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
newcl->userid = g_userid++; // create unique userid
newcl->state = cs_connected;
newcl->extensions = extensions & (NET_EXT_SPLITSIZE);
@@ -466,11 +482,8 @@ static void SV_ConnectClient( netadr_t from )
// if this was the first client on the server, or the last client
// the server can hold, send a heartbeat to the master.
for( i = 0; i < svs.maxclients; i++ )
{
if( svs.clients[i].state >= cs_connected )
count++;
}
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
if( cl->state >= cs_connected ) count++;
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n", newcl->name, newcl->userid, i, NET_AdrToString( newcl->netchan.remote_address ));
@@ -841,7 +854,7 @@ static void SV_TestBandWidth( netadr_t from )
( packetsize > FRAGMENT_MAX_SIZE ))
{
// skip the test and just get challenge
SV_SendChallenge( from );
SV_GetChallenge( from );
return;
}
@@ -849,7 +862,7 @@ static void SV_TestBandWidth( netadr_t from )
ofs = packetsize - svs.testpacket_filepos - 1;
if(( ofs < 0 ) || ( ofs > svs.testpacket_filelen ))
{
SV_SendChallenge( from );
SV_GetChallenge( from );
return;
}
@@ -1772,7 +1785,7 @@ static qboolean SV_ShouldUpdateUserinfo( sv_client_t *cl )
if( host.realtime < cl->userinfo_next_changetime + cl->userinfo_penalty * sv_userinfo_penalty_multiplier.value )
{
// player changes userinfo too quick! ignore!
if( host.realtime < cl->userinfo_next_changetime && cl->userinfo_change_attempts > 0 )
if( host.realtime < cl->userinfo_next_changetime )
{
Con_Reportf( "%s: ignore userinfo update for %s: penalty %f, attempts %i\n",
__func__, cl->name, cl->userinfo_penalty, cl->userinfo_change_attempts );
@@ -1783,15 +1796,15 @@ static qboolean SV_ShouldUpdateUserinfo( sv_client_t *cl )
}
// they spammed too fast, increase penalty
if( cl->userinfo_change_attempts >= (int)sv_userinfo_penalty_attempts.value )
if( cl->userinfo_change_attempts > sv_userinfo_penalty_attempts.value )
{
Con_Reportf( "%s: penalty set %f for %s\n", __func__,
cl->userinfo_penalty, cl->name );
cl->userinfo_penalty *= sv_userinfo_penalty_multiplier.value;
cl->userinfo_change_attempts = 0;
Con_Reportf( "%s: penalty set %f for %s\n", __func__, cl->userinfo_penalty, cl->name );
}
cl->userinfo_next_changetime = host.realtime + cl->userinfo_penalty * sv_userinfo_penalty_multiplier.value;
cl->userinfo_next_changetime = host.realtime + cl->userinfo_penalty;
return allow;
}
@@ -1895,10 +1908,13 @@ static void SV_UserinfoChanged( sv_client_t *cl )
val = Info_ValueForKey( cl->userinfo, "cl_updaterate" );
if( COM_CheckString( val ))
if( COM_CheckString( val ) )
{
float rate = Q_atoi( val );
cl->cl_updaterate = 1.0 / bound( sv_minupdaterate.value, rate, sv_maxupdaterate.value );
if( Q_atoi( val ) != 0 )
{
cl->cl_updaterate = 1.0 / bound( sv_minupdaterate.value, Q_atoi( val ), sv_maxupdaterate.value );
}
else cl->cl_updaterate = 0.0;
}
// call prog code to allow overrides
@@ -3163,7 +3179,7 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
}
else if( !Q_strcmp( pcmd, C2S_GETCHALLENGE ))
{
SV_SendChallenge( from );
SV_GetChallenge( from );
}
else if( !Q_strcmp( pcmd, C2S_CONNECT ))
{

View File

@@ -573,7 +573,7 @@ static void SV_Kick_f( void )
sv_client_t *cl;
const char *param;
if( Cmd_Argc() < 2 )
if( Cmd_Argc() != 2 )
{
Con_Printf( S_USAGE "kick <#id|name> [reason]\n" );
return;

View File

@@ -302,7 +302,7 @@ static int SV_FilterToString( char *dest, size_t size, qboolean config, ipfilter
static qboolean SV_IPFilterIncludesIPFilter( ipfilter_t *a, ipfilter_t *b )
{
if( NET_NetadrType( &a->adr ) != NET_NetadrType( &b->adr ))
if( a->adr.type6 != b->adr.type6 )
return false;
// can't include bigger subnet in small
@@ -359,7 +359,7 @@ qboolean SV_CheckIP( netadr_t *adr )
if( entry->endTime && host.realtime > entry->endTime )
continue; // expired
switch( NET_NetadrType( &entry->adr ))
switch( entry->adr.type6 )
{
case NA_IP:
case NA_IP6:

View File

@@ -2379,7 +2379,7 @@ void GAME_EXPORT pfnClientCommand( edict_t* pEdict, char* szFmt, ... )
if( sv.state != ss_active )
return; // early out
if(( cl = SV_ClientFromEdict( pEdict, false )) == NULL )
if(( cl = SV_ClientFromEdict( pEdict, true )) == NULL )
{
Con_Printf( S_ERROR "stuffcmd: client is not spawned!\n" );
return;
@@ -4600,7 +4600,7 @@ static void GAME_EXPORT pfnQueryClientCvarValue( const edict_t *player, const ch
if( !COM_CheckString( cvarName ))
return;
if(( cl = SV_ClientFromEdict( player, false )) != NULL )
if(( cl = SV_ClientFromEdict( player, true )) != NULL )
{
MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue );
MSG_WriteString( &cl->netchan.message, cvarName );
@@ -4627,7 +4627,7 @@ static void GAME_EXPORT pfnQueryClientCvarValue2( const edict_t *player, const c
if( !COM_CheckString( cvarName ))
return;
if(( cl = SV_ClientFromEdict( player, false )) != NULL )
if(( cl = SV_ClientFromEdict( player, true )) != NULL )
{
MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue2 );
MSG_WriteLong( &cl->netchan.message, requestID );

View File

@@ -1027,9 +1027,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba
svs.timestart = Sys_DoubleTime();
svs.spawncount++; // any partially connected client will be restarted
for( i = 0; i < ARRAYSIZE( svs.challenge_salt ); i++ )
svs.challenge_salt[i] = COM_RandomLong( 0, 0x7FFFFFFE );
cycle = Cvar_VariableString( "mapchangecfgfile" );
if( COM_CheckString( cycle ))

View File

@@ -106,7 +106,7 @@ CVAR_DEFINE_AUTO( sv_skyvec_y, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "skylight dir
CVAR_DEFINE_AUTO( sv_skyvec_z, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "skylight direction by z-axis" );
CVAR_DEFINE_AUTO( sv_wateralpha, "1", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "world surfaces water transparency factor. 1.0 - solid, 0.0 - fully transparent" );
CVAR_DEFINE_AUTO( sv_background_freeze, "1", FCVAR_ARCHIVE, "freeze player movement on background maps (e.g. to prevent falling)" );
static CVAR_DEFINE_AUTO( showtriggers, "0", FCVAR_LATCH|FCVAR_TEMPORARY, "debug cvar shows triggers" );
static CVAR_DEFINE_AUTO( showtriggers, "0", FCVAR_LATCH, "debug cvar shows triggers" );
static CVAR_DEFINE_AUTO( sv_airmove, "1", FCVAR_SERVER, "obsolete, compatibility issues" );
static CVAR_DEFINE_AUTO( sv_version, "", FCVAR_READ_ONLY, "engine version string" );
CVAR_DEFINE_AUTO( hostname, "", FCVAR_PRINTABLEONLY, "name of current host" );
@@ -189,15 +189,24 @@ void SV_UpdateMovevars( qboolean initialize )
if( !initialize && !host.movevars_changed )
return;
// NOTE: Natural Selection mod on ns_machina map that uses model as sky
// it sets the value to 4000000 that even exceeds the coord limit, but
// it's fine until the value fits in "zmax" delta field
// However, some stupid mappers set an insane value like 999999999 which
// overflows delta. In this case, just clamp it to something bigger
if( sv_zmax.value < 256.0f )
Cvar_DirectSet( &sv_zmax, "256" );
else if( sv_zmax.value > 16777216.0f ) // 2^24
Cvar_DirectSet( &sv_zmax, "16777216" );
// NOTE: this breaks Natural Selection mod on ns_machina map that uses model as sky
// it sets the value to 4000000 that even exceeds the coord limit
#if 0
// check range
if( sv_zmax.value < 256.0f ) Cvar_SetValue( "sv_zmax", 256.0f );
// clamp it right
if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD ))
{
if( sv_zmax.value > 131070.0f )
Cvar_SetValue( "sv_zmax", 131070.0f );
}
else
{
if( sv_zmax.value > 32767.0f )
Cvar_SetValue( "sv_zmax", 32767.0f );
}
#endif
svgame.movevars.gravity = sv_gravity.value;
svgame.movevars.stopspeed = sv_stopspeed.value;

View File

@@ -948,6 +948,12 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed )
clent->v.light_level = ucmd->lightlevel;
if( ucmd->impulse ) clent->v.impulse = ucmd->impulse;
if( ucmd->impulse == 204 )
{
// force client.dll update
SV_RefreshUserinfo();
}
svgame.globals->time = cl->timebase;
svgame.dllFuncs.pfnPlayerPreThink( clent );
SV_PlayerRunThink( clent, frametime, cl->timebase );

View File

@@ -601,7 +601,7 @@ static void SV_FindTouchedLeafs( edict_t *ent, model_t *mod, mnode_t *node, int
// add an efrag if the node is a leaf
if( node->contents < 0 )
{
if( ent->num_leafs >= MAX_ENT_LEAFS( FBitSet( mod->flags, MODEL_QBSP2 )))
if( ent->num_leafs > MAX_ENT_LEAFS( FBitSet( mod->flags, MODEL_QBSP2 )))
{
// continue counting leafs,
// so we know how many it's overrun

View File

@@ -136,7 +136,7 @@ def build(bld):
# public includes for renderers and utils use
bld(name = 'engine_includes', export_includes = '. common common/imagelib', use = 'filesystem_includes')
libs = ['engine_includes', 'public', 'dllemu', 'werror', 'backtrace']
libs = ['engine_includes', 'public', 'dllemu', 'werror']
includes = ['server', 'client', 'client/vgui', 'common/soundlib']
# basic build: dedicated only

View File

@@ -59,9 +59,8 @@ char fs_rootdir[MAX_SYSPATH];
searchpath_t *fs_writepath;
static searchpath_t *fs_searchpaths = NULL; // chain
static char fs_basedir[MAX_SYSPATH]; // base game directory
static char fs_gamedir[MAX_SYSPATH]; // game current directory
static string fs_language;
static char fs_basedir[MAX_SYSPATH]; // base game directory
static char fs_gamedir[MAX_SYSPATH]; // game current directory
// add archives in specific order PAK -> PK3 -> WAD
// so raw WADs takes precedence over WADs included into PAKs and PK3s
@@ -1250,39 +1249,14 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
if( isGameDir )
{
Q_snprintf( buf, sizeof( buf ), "%s/" DEFAULT_DOWNLOADED_DIRECTORY, dir );
FS_AddGameDirectory( buf, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
FS_AddGameDirectory( buf, FS_NOWRITE_PATH | FS_CUSTOM_PATH );
}
Q_snprintf( buf, sizeof( buf ), "%s/", dir );
FS_AddGameDirectory( buf, flags );
if( FBitSet( flags, FS_MOUNT_HD ))
{
Q_snprintf( buf, sizeof( buf ), "%s_hd/", dir );
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
}
if( FBitSet( flags, FS_MOUNT_ADDON ))
{
Q_snprintf( buf, sizeof( buf ), "%s_addon/", dir );
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
}
if( FBitSet( flags, FS_MOUNT_LV ))
{
Q_snprintf( buf, sizeof( buf ), "%s_lv/", dir );
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
}
if( FBitSet( flags, FS_MOUNT_L10N ) && COM_CheckStringEmpty( fs_language ) && Q_isalpha( fs_language ))
{
Q_snprintf( buf, sizeof( buf ), "%s_%s/", dir, fs_language );
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
}
if( isGameDir )
{
Q_snprintf( buf, sizeof( buf ), "%s/" DEFAULT_CUSTOM_DIRECTORY, dir );
FS_AddGameDirectory( buf, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
FS_AddGameDirectory( buf, FS_NOWRITE_PATH | FS_CUSTOM_PATH );
}
}
@@ -1291,35 +1265,29 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
FS_Rescan
================
*/
void FS_Rescan( uint32_t flags, const char *language )
void FS_Rescan( void )
{
const char *str;
const int extrasFlags = FS_NOWRITE_PATH | FS_CUSTOM_PATH;
Con_Reportf( "%s( %s )\n", __func__, GI->title );
FS_ClearSearchPath();
flags &= FS_MOUNT_HD|FS_MOUNT_LV|FS_MOUNT_ADDON|FS_MOUNT_L10N;
if( FBitSet( flags, FS_MOUNT_L10N ))
Q_strncpy( fs_language, language, sizeof( fs_language ));
else
fs_language[0] = 0;
str = getenv( "XASH3D_EXTRAS_PAK1" );
if( COM_CheckString( str ))
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
FS_MountArchive_Fullpath( str, extrasFlags );
str = getenv( "XASH3D_EXTRAS_PAK2" );
if( COM_CheckString( str ))
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
FS_MountArchive_Fullpath( str, extrasFlags );
if( Q_stricmp( GI->basedir, GI->gamefolder ))
FS_AddGameHierarchy( GI->basedir, flags );
FS_AddGameHierarchy( GI->basedir, 0 );
if( Q_stricmp( GI->basedir, GI->falldir ) && Q_stricmp( GI->gamefolder, GI->falldir ))
FS_AddGameHierarchy( GI->falldir, flags );
FS_AddGameHierarchy( GI->falldir, 0 );
GI->added = true;
FS_AddGameHierarchy( GI->gamefolder, FS_GAMEDIR_PATH | flags );
FS_AddGameHierarchy( GI->gamefolder, FS_GAMEDIR_PATH );
}
/*
@@ -1364,7 +1332,7 @@ void FS_LoadGameInfo( const char *rootfolder )
FS_CreatePath( buf );
}
FS_Rescan( 0, NULL ); // create new filesystem
FS_Rescan(); // create new filesystem
}
/*
@@ -1607,7 +1575,6 @@ qboolean FS_InitStdio( qboolean unused_set_to_true, const char *rootdir, const c
Q_strncpy( fs_gamedir, gamedir, sizeof( fs_gamedir ));
Q_strncpy( fs_basedir, basedir, sizeof( fs_basedir ));
Q_strncpy( fs_rodir, rodir, sizeof( fs_rodir ));
fs_language[0] = 0;
// validate user input
if( COM_CheckStringEmpty( fs_rodir ) && !Q_stricmp( fs_rodir, fs_rootdir ))
@@ -1729,17 +1696,12 @@ FS_Shutdown
void FS_ShutdownStdio( void )
{
int i;
// release gamedirs
for( i = 0; i < FI.numgames; i++ )
{
if( FI.games[i] )
{
Mem_Free( FI.games[i] );
FI.games[i] = NULL;
}
}
FI.numgames = 0;
FS_ClearSearchPath(); // release all wad files too
Mem_FreePool( &fs_mempool );
@@ -3119,10 +3081,6 @@ qboolean FS_Rename( const char *oldname, const char *newname )
char oldname2[MAX_SYSPATH], newname2[MAX_SYSPATH], oldpath[MAX_SYSPATH], newpath[MAX_SYSPATH];
int ret;
// a1ba: disallow path traversal
if( FS_CheckNastyPath( oldname ) || FS_CheckNastyPath( newname ))
return false;
if( !fs_writepath )
return false;
@@ -3171,10 +3129,6 @@ qboolean GAME_EXPORT FS_Delete( const char *path )
char path2[MAX_SYSPATH], real_path[MAX_SYSPATH];
int ret;
// a1ba: disallow path traversal
if( FS_CheckNastyPath( path ))
return false;
if( !fs_writepath || !COM_CheckString( path ))
return false;

View File

@@ -48,11 +48,6 @@ enum
FS_SKIP_ARCHIVED_WADS = BIT( 5 ), // don't mount wads inside archives automatically
FS_LOAD_PACKED_WAD = BIT( 6 ), // this wad is packed inside other archive
FS_MOUNT_HD = BIT( 7 ), // mount high definition content folder
FS_MOUNT_LV = BIT( 8 ), // mount low violence content folder
FS_MOUNT_ADDON = BIT( 9 ), // mount addon folder
FS_MOUNT_L10N = BIT( 10 ), // mount localization folder
FS_GAMEDIRONLY_SEARCH_FLAGS = FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH
};
@@ -156,7 +151,7 @@ typedef struct fs_api_t
void (*ShutdownStdio)( void );
// search path utils
void (*Rescan)( uint32_t flags, const char *language );
void (*Rescan)( void );
void (*ClearSearchPath)( void );
void (*AllowDirectPaths)( qboolean enable );
void (*AddGameDirectory)( const char *dir, uint flags );

View File

@@ -167,7 +167,7 @@ void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
// search path utils
void FS_Rescan( uint32_t flags, const char *language );
void FS_Rescan( void );
void FS_ClearSearchPath( void );
void FS_AllowDirectPaths( qboolean enable );
void FS_AddGameDirectory( const char *dir, uint flags );

View File

@@ -13,11 +13,10 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <stdio.h>
#include "crtlib.h"
#include "buildenums.h"
static const char *const mon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static const char *mon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static const char mond[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int Q_buildnum_date( const char *date )
@@ -39,31 +38,9 @@ int Q_buildnum_date( const char *date )
b = d + (int)((y - 1) * 365.25f );
if((( y % 4 ) == 0 ) && m > 1 )
{
b += 1;
b -= 41728; // Apr 1 2015
return b;
}
int Q_buildnum_iso( const char *date )
{
int y, m, d, b, i;
if( sscanf( date, "%d-%d-%d", &y, &m, &d ) != 3 || y <= 1900 || m <= 0 || d <= 0 )
return -1;
// fixup day and month
m--;
d--;
for( i = 0; i < m; i++ )
d += mond[i];
y -= 1900;
b = d + (int)((y - 1) * 365.25f );
if((( y % 4 ) == 0 ) && m > 1 )
b += 1;
}
b -= 41728; // Apr 1 2015
return b;
@@ -80,13 +57,8 @@ int Q_buildnum( void )
{
static int b = 0;
if( b ) return b;
if( COM_CheckString( g_buildcommit_date ))
b = Q_buildnum_iso( g_buildcommit_date );
if( b <= 0 )
b = Q_buildnum_date( g_build_date );
if( !b )
b = Q_buildnum_date( __DATE__ );
return b;
}

View File

@@ -15,5 +15,4 @@ GNU General Public License for more details.
const char *g_buildcommit = XASH_BUILD_COMMIT;
const char *g_buildbranch = XASH_BUILD_BRANCH;
const char *g_buildcommit_date = XASH_BUILD_COMMIT_DATE;
const char *g_build_date = __DATE__;

View File

@@ -339,9 +339,6 @@ int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list ar
{
int result;
if( unlikely( buffersize == 0 ))
return -1; // report as overflow
#ifndef _MSC_VER
result = vsnprintf( buffer, buffersize, format, args );
#else

View File

@@ -57,7 +57,6 @@ enum
//
int Q_buildnum( void );
int Q_buildnum_date( const char *date );
int Q_buildnum_iso( const char *date );
int Q_buildnum_compat( void );
const char *Q_PlatformStringByID( const int platform );
const char *Q_buildos( void );
@@ -65,8 +64,6 @@ const char *Q_ArchitectureStringByID( const int arch, const uint abi, const int
const char *Q_buildarch( void );
extern const char *g_buildcommit;
extern const char *g_buildbranch;
extern const char *g_build_date;
extern const char *g_buildcommit_date;
//
// crtlib.c
@@ -141,29 +138,24 @@ static inline char Q_tolower( const char in )
return out;
}
static inline qboolean Q_istype( const char *str, int (*istype)( int c ))
static inline qboolean Q_isdigit( const char *str )
{
if( likely( str && *str ))
{
while( istype( *str )) str++;
while( isdigit( *str )) str++;
if( !*str ) return true;
}
return false;
}
static inline qboolean Q_isdigit( const char *str )
{
return Q_istype( str, isdigit );
}
static inline qboolean Q_isalpha( const char *str )
{
return Q_istype( str, isalpha );
}
static inline qboolean Q_isspace( const char *str )
{
return Q_istype( str, isspace );
if( likely( str && *str ))
{
while( isspace( *str ) ) str++;
if( !*str ) return true;
}
return false;
}
static inline int Q_strcmp( const char *s1, const char *s2 )

View File

@@ -180,14 +180,8 @@ int main( void )
if( Q_buildnum_date( "Apr 02 2015" ) != 1 )
return 201;
if( Q_buildnum_date( "Apr 02 2015" ) != Q_buildnum_iso( "2015-04-02 21:19:10 +0300" ))
return 202;
if( Q_buildnum_date( "Apr 17 2023" ) != 2938 )
return 203;
if( Q_buildnum_date( "Apr 17 2023" ) != Q_buildnum_iso( "2023-04-17 21:19:10 +0300" ))
return 204;
return 202;
return EXIT_SUCCESS;
}

View File

@@ -3,7 +3,6 @@
# mittorn, 2018
from waflib import Logs, Configure
from waflib.extras import gitversion
import os
top = '.'
@@ -61,16 +60,6 @@ def export_define(conf, define, value=1):
def simple_check(conf, fragment, msg, mandatory=False, **kw):
return conf.check_cc(fragment=fragment, msg='Checking for %s' % msg, mandatory=mandatory, **kw)
@Configure.conf
def get_git_commit_date(conf):
node = conf.srcnode.find_node('.git')
if not node:
Logs.debug('can\'t find .git in conf.srcnode')
return None
return gitversion.run_git(conf, ['log', '-1', '--format=%ci'])
def options(opt):
opt.add_option('--validate-target', action='store', dest='VALIDATE_TARGET', default=None,
help='development option, needs --enable-tests flag')
@@ -78,11 +67,6 @@ def options(opt):
def configure(conf):
# private to libpublic
conf.load('gitversion')
conf.start_msg('Git commit date')
conf.env.GIT_COMMIT_DATE = conf.get_git_commit_date()
conf.end_msg(conf.env.GIT_COMMIT_DATE)
conf.env.VALIDATE_TARGET = conf.options.VALIDATE_TARGET
# need to expose it for everyone using libpublic headers
@@ -137,7 +121,7 @@ def build(bld):
# build it separately to slightly improve rebuild times
bld.stlib(source = 'build_vcs.c',
target = 'build_vcs',
defines = ['XASH_BUILD_COMMIT=\"%s\"' % bld.env.GIT_VERSION, 'XASH_BUILD_BRANCH=\"%s\"' % bld.env.GIT_BRANCH, 'XASH_BUILD_COMMIT_DATE=\"%s\"' % bld.env.GIT_COMMIT_DATE])
defines = ['XASH_BUILD_COMMIT=\"%s\"' % bld.env.GIT_VERSION, 'XASH_BUILD_BRANCH=\"%s\"' % bld.env.GIT_BRANCH])
bld.stlib(source = bld.path.ant_glob('*.c', excl='build_vcs.c'),
target = 'public',

View File

@@ -453,83 +453,174 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p )
return sides;
}
void R_StudioCalcBones( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos, vec4_t q )
/*
====================
StudioCalcBoneQuaternion
====================
*/
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q )
{
float v1[6], v2[6];
int i, max;
vec3_t angles1;
vec3_t angles2;
int j, k;
max = q != NULL ? 6 : 3;
for( i = 0; i < max; i++ )
for( j = 0; j < 3; j++ )
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[i] );
int j = frame;
float fadj = 0.0f;
if( pbone->bonecontroller[i] >= 0 && adj != NULL )
fadj = adj[pbone->bonecontroller[i]];
if( panim->offset[i] == 0 )
if( !panim || panim->offset[j+3] == 0 )
{
v1[i] = v2[i] = pbone->value[i] + fadj;
continue;
}
if( panimvalue->num.total < panimvalue->num.valid )
j = 0;
while( panimvalue->num.total <= j )
{
j -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
if( panimvalue->num.total < panimvalue->num.valid )
j = 0;
}
if( panimvalue->num.valid > j )
{
v1[i] = panimvalue[j + 1].value;
if( panimvalue->num.valid > j + 1 )
v2[i] = panimvalue[j + 2].value;
else if( panimvalue->num.total > j + 1 )
v2[i] = v1[i];
else
v2[i] = panimvalue[panimvalue->num.valid + 2].value;
angles2[j] = angles1[j] = pbone->value[j+3]; // default;
}
else
{
v1[i] = panimvalue[panimvalue->num.valid].value;
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
if( panimvalue->num.total > j + 1 )
v2[i] = v1[i];
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
angles1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
angles2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
v2[i] = panimvalue[panimvalue->num.valid + 2].value;
{
angles1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
angles1[j] = pbone->value[j+3] + angles1[j] * pbone->scale[j+3];
angles2[j] = pbone->value[j+3] + angles2[j] * pbone->scale[j+3];
}
v1[i] = pbone->value[i] + v1[i] * pbone->scale[i] + fadj;
v2[i] = pbone->value[i] + v2[i] * pbone->scale[i] + fadj;
if( pbone->bonecontroller[j+3] != -1 && adj != NULL )
{
angles1[j] += adj[pbone->bonecontroller[j+3]];
angles2[j] += adj[pbone->bonecontroller[j+3]];
}
}
if( !VectorCompare( v1, v2 ))
VectorLerp( v1, s, v2, pos );
else
VectorCopy( v1, pos );
if( q != NULL )
if( !VectorCompare( angles1, angles2 ))
{
if( !VectorCompare( &v1[3], &v2[3] ))
{
vec4_t q1, q2;
vec4_t q1, q2;
AngleQuaternion( &v1[3], q1, true );
AngleQuaternion( &v2[3], q2, true );
QuaternionSlerp( q1, q2, s, q );
}
else
{
AngleQuaternion( &v1[3], q, true );
}
AngleQuaternion( angles1, q1, true );
AngleQuaternion( angles2, q2, true );
QuaternionSlerp( q1, q2, s, q );
}
else
{
AngleQuaternion( angles1, q, true );
}
}
/*
====================
StudioCalcBonePosition
====================
*/
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos )
{
vec3_t origin1;
vec3_t origin2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j] == 0 )
{
origin2[j] = origin1[j] = pbone->value[j]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
origin1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
origin2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
origin1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
origin1[j] = pbone->value[j] + origin1[j] * pbone->scale[j];
origin2[j] = pbone->value[j] + origin2[j] * pbone->scale[j];
}
if( pbone->bonecontroller[j] != -1 && adj != NULL )
{
origin1[j] += adj[pbone->bonecontroller[j]];
origin2[j] += adj[pbone->bonecontroller[j]];
}
}
if( !VectorCompare( origin1, origin2 ))
{
VectorLerp( origin1, s, origin2, pos );
}
else
{
VectorCopy( origin1, pos );
}
}

View File

@@ -168,8 +168,8 @@ void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, v
void PlaneIntersect( const mplane_t *plane, const vec3_t p0, const vec3_t p1, vec3_t out );
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir );
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt );
void R_StudioCalcBones( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos, vec4_t q );
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q );
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const vec3_t adj, vec3_t pos );
int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p );
#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \
((( p )->type < 3 ) ? \

View File

@@ -81,20 +81,6 @@ static void CL_FillRGBA( int rendermode, float _x, float _y, float _w, float _h,
pglDisable( GL_BLEND );
}
static qboolean Mod_LooksLikeWaterTexture( const char *name )
{
if(( name[0] == '*' && Q_stricmp( name, REF_DEFAULT_TEXTURE )) || name[0] == '!' )
return true;
if( !ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ))
{
if( !Q_strncmp( name, "water", 5 ) || !Q_strnicmp( name, "laser", 5 ))
return true;
}
return false;
}
static void Mod_BrushUnloadTextures( model_t *mod )
{
int i;
@@ -107,12 +93,8 @@ static void Mod_BrushUnloadTextures( model_t *mod )
if( tx->gl_texturenum != tr.defaultTexture )
GL_FreeTexture( tx->gl_texturenum ); // main texture
if( !Mod_LooksLikeWaterTexture( tx->name ))
{
GL_FreeTexture( tx->fb_texturenum ); // luma texture
GL_FreeTexture( tx->dt_texturenum ); // detail texture
}
GL_FreeTexture( tx->fb_texturenum ); // luma texture
GL_FreeTexture( tx->dt_texturenum ); // detail texture
}
}

View File

@@ -388,7 +388,7 @@ void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
@@ -436,6 +436,7 @@ void R_DrawWorld( void );
void R_DrawWaterSurfaces( void );
void R_DrawBrushModel( cl_entity_t *e );
void GL_SubdivideSurface( model_t *mod, msurface_t *fa );
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa );
void GL_SetupFogColorForSurfaces( void );
void R_DrawAlphaTextureChains( void );
void GL_RebuildLightmaps( void );
@@ -812,7 +813,6 @@ extern convar_t r_ripple;
extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps;
extern convar_t r_dlight_virtual_radius;
//
// engine shared convars

View File

@@ -38,7 +38,6 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
@@ -1156,7 +1155,6 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );

View File

@@ -99,76 +99,48 @@ void CL_RunLightStyles( lightstyle_t *ls )
R_MarkLights
=============
*/
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
{
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius;
float dist;
int i;
float dist;
msurface_t *surf;
int i;
mnode_t *children[2];
int firstsurface, numsurfaces;
start:
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
node_children( children, node, RI.currentmodel );
if( dist > virtual_radius )
{
node = children[0];
goto start;
}
if( dist < -virtual_radius )
{
node = children[1];
goto start;
}
// mark the polygons
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
for( i = 0; i < numsurfaces; i++ )
if( dist > light->radius )
{
vec3_t impact;
float s, t, l;
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
R_MarkLights( light, bit, children[0] );
return;
}
if( dist < -light->radius )
{
R_MarkLights( light, bit, children[1] );
return;
}
if( surf->plane->type < 3 )
{
VectorCopy( light->origin, impact );
impact[surf->plane->type] -= dist;
}
else VectorMA( light->origin, -dist, surf->plane->normal, impact );
// mark the polygons
surf = RI.currentmodel->surfaces + firstsurface;
// a1ba: the fix was taken from JoeQuake, which traces back to FitzQuake,
// which attributes it to LadyHavoc (Darkplaces author)
// clamp center of light to corner and check brightness
l = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
s = l + 0.5;
s = bound( 0, s, info->lightextents[0] );
s = l - s;
l = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
t = l + 0.5;
t = bound( 0, t, info->lightextents[1] );
t = l - t;
if( s * s + t * t + dist * dist >= maxdist )
continue;
for( i = 0; i < numsurfaces; i++, surf++ )
{
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
continue; // no intersection
if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = bit;
surf->dlightbits = 0;
surf->dlightframe = tr.dlightframecount;
}
else surf->dlightbits |= bit;
surf->dlightbits |= bit;
}
R_MarkLights( light, bit, children[0] );

View File

@@ -26,6 +26,7 @@ typedef struct
byte lightmap_buffer[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*4];
} gllightmapstate_t;
static int nColinElim; // stats
static vec2_t world_orthocenter;
static vec2_t world_orthohalf;
static uint r_blocklights[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*3];
@@ -334,16 +335,16 @@ void GL_SubdivideSurface( model_t *loadmodel, msurface_t *fa )
GL_BuildPolygonFromSurface
================
*/
static int GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
{
int i, lnumverts, nColinElim = 0;
int i, lnumverts;
float sample_size;
texture_t *tex;
gl_texture_t *glt;
glpoly2_t *poly;
if( !mod || !fa->texinfo || !fa->texinfo->texture )
return nColinElim; // bad polygon ?
return; // bad polygon ?
if( FBitSet( fa->flags, SURF_CONVEYOR ) && fa->texinfo->texture->gl_texturenum != 0 )
{
@@ -416,7 +417,6 @@ static int GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
}
poly->numverts = lnumverts;
return nColinElim;
}
@@ -2476,14 +2476,10 @@ static void R_SetupVBOArrayDlight( vboarray_t *vbo, texture_t *texture )
static void R_SetupVBOArrayDecalDlight( int decalcount )
{
if( vbos.decal_dlight_vbo )
{
pglBindBufferARB( GL_ARRAY_BUFFER_ARB, vbos.decal_dlight_vbo );
pglBindBufferARB( GL_ARRAY_BUFFER_ARB, vbos.decal_dlight_vbo );
#if !SPARSE_DECALS_UPLOAD
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbovertex_t ) * DECAL_VERTS_MAX * decalcount, vbos.decal_dlight, GL_STREAM_DRAW_ARB );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbovertex_t ) * DECAL_VERTS_MAX * decalcount, vbos.decal_dlight , GL_STREAM_DRAW_ARB );
#endif
}
R_SetDecalMode( true );
// hack: fix decal dlights on gl_vbo_details == 2 (wrong state??)
/*if( mtst.details_enabled && mtst.tmu_dt != -1 )
@@ -3848,7 +3844,7 @@ with all the surfaces from all brush models
*/
void GL_BuildLightmaps( void )
{
int i, j, nColinElim = 0;
int i, j;
model_t *m;
// release old lightmaps
@@ -3872,6 +3868,7 @@ void GL_BuildLightmaps( void )
gl_lms.current_lightmap_texture = 0;
tr.modelviewIdentity = false;
tr.realframecount = 1;
nColinElim = 0;
// setup the texture for dlights
R_InitDlightTexture();
@@ -3900,7 +3897,7 @@ void GL_BuildLightmaps( void )
if( m->surfaces[j].flags & SURF_DRAWTURB )
continue;
nColinElim += GL_BuildPolygonFromSurface( m, m->surfaces + j );
GL_BuildPolygonFromSurface( m, m->surfaces + j );
}
// clearing visframe

View File

@@ -816,7 +816,10 @@ static void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, ms
R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen );
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
R_StudioCalcBones( frame, s, pbone, panim, adj, pos[i], q[i] );
{
R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
}
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
if( pseqdesc->motiontype & STUDIO_Y ) pos[pseqdesc->motionbone][1] = 0.0f;

View File

@@ -40,16 +40,16 @@ set rendermode
void TriRenderMode( int mode )
{
ds.renderMode = mode;
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
switch( mode )
{
case kRenderNormal:
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglDisable( GL_BLEND );
pglDepthMask( GL_TRUE );
break;
case kRenderTransAlpha:
pglEnable( GL_BLEND );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglDepthMask( GL_FALSE );
break;
@@ -60,6 +60,7 @@ void TriRenderMode( int mode )
break;
case kRenderGlow:
case kRenderTransAdd:
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglEnable( GL_BLEND );
pglDepthMask( GL_FALSE );

View File

@@ -835,7 +835,10 @@ static void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, ms
R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen );
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
R_StudioCalcBones( frame, s, pbone, panim, adj, pos[i], q[i] );
{
R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
}
if( pseqdesc->motiontype & STUDIO_X )
pos[pseqdesc->motionbone][0] = 0.0f;

View File

@@ -59,7 +59,6 @@ x-compat-i386-opts: &compat-i386-opts
CC: i686-unknown-linux-gnu-gcc
CXX: i686-unknown-linux-gnu-g++
libdir: /app/lib32
no-debuginfo: true # libbacktrace relies on this
modules:
- name: bundle-setup

View File

@@ -15,8 +15,6 @@ build_hlsdk()
export VITASDK=/usr/local/vitasdk
export PATH=$VITASDK/bin:$PATH
JOBS=$(($(nproc)+1))
cd "$BUILDDIR" || die
rm -rf artifacts build pkgtemp
@@ -26,13 +24,13 @@ mkdir -p artifacts/ || die
echo "Building vitaGL..."
make -C vitaGL NO_TEX_COMBINER=1 HAVE_UNFLIPPED_FBOS=1 HAVE_PTHREAD=1 MATH_SPEEDHACK=1 DRAW_SPEEDHACK=1 -j$JOBS install || die
make -C vitaGL NO_TEX_COMBINER=1 HAVE_UNFLIPPED_FBOS=1 HAVE_PTHREAD=1 MATH_SPEEDHACK=1 DRAW_SPEEDHACK=1 -j2 install || die
echo "Building vrtld..."
pushd vita-rtld || die
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release || die_configure
cmake --build build -- -j$JOBS || die
cmake --build build -- -j2 || die
cmake --install build || die
popd
@@ -40,7 +38,7 @@ echo "Building SDL..."
pushd SDL || die
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DVIDEO_VITA_VGL=ON -DSDL_RENDER=OFF || die_configure
cmake --build build -- -j$JOBS || die
cmake --build build -- -j2 || die
cmake --install build || die
popd

View File

@@ -6,7 +6,7 @@ echo "Downloading vitasdk..."
export VITASDK=/usr/local/vitasdk
VITAGL_SRCREV="064db9efb15833e18777a3e768b8b1fb2abee78f" # lock vitaGL version to avoid compilation errors
VITAGL_SRCREV="4d3ab1053424abe3b2164a50d15c5e355e33ed99" # lock vitaGL version to avoid compilation errors
install_package()
{

View File

@@ -48,12 +48,6 @@ def sdl2_configure_path(conf, path, libname):
conf.env[FRAMEWORKPATH] = [my_dirname(path)]
conf.env[FRAMEWORK] = [libname]
conf.end_msg('yes: {0}, {1}, {2}'.format(conf.env[FRAMEWORK], conf.env[FRAMEWORKPATH], conf.env[INCLUDES]))
elif conf.env.DEST_OS == 'android':
# Special setup for waf called from CMake, through ExternalProject_Add
conf.env[INCLUDES] = [os.path.abspath(os.path.join(path, 'include'))]
conf.env[LIBPATH] = [os.environ['BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY']]
conf.env[LIB] = [libname]
conf.end_msg('yes: {0}, {1}, {2}'.format(conf.env[LIB], conf.env[LIBPATH], conf.env[INCLUDES]))
else:
conf.env[INCLUDES] = [
os.path.abspath(os.path.join(path, 'include')),

View File

@@ -20,20 +20,12 @@ import os
import sys
ANDROID_NDK_ENVVARS = ['ANDROID_NDK_HOME', 'ANDROID_NDK']
ANDROID_NDK_SUPPORTED = [10, 19, 20, 23, 25, 27, 28]
ANDROID_NDK_SUPPORTED = [10, 19, 20, 23, 25]
ANDROID_NDK_HARDFP_MAX = 11 # latest version that supports hardfp
ANDROID_NDK_GCC_MAX = 17 # latest NDK that ships with GCC
ANDROID_NDK_UNIFIED_SYSROOT_MIN = 15
ANDROID_NDK_SYSROOT_FLAG_MAX = 19 # latest NDK that need --sysroot flag
ANDROID_NDK_API_MIN = {
10: 3,
19: 16,
20: 16,
23: 16,
25: 19,
27: 19,
28: 19,
} # minimal API level ndk revision supports
ANDROID_NDK_API_MIN = { 10: 3, 19: 16, 20: 16, 23: 16, 25: 19 } # minimal API level ndk revision supports
ANDROID_STPCPY_API_MIN = 21 # stpcpy() introduced in SDK 21
ANDROID_64BIT_API_MIN = 21 # minimal API level that supports 64-bit targets
@@ -58,7 +50,6 @@ class Android:
self.api = api
self.toolchain = toolchain
self.arch = arch
self.exe = '.exe' if sys.platform.startswith('win32') or sys.platform.startswith('cygwin') else ''
for i in ANDROID_NDK_ENVVARS:
self.ndk_home = os.getenv(i)
@@ -205,10 +196,10 @@ class Android:
def gen_toolchain_path(self):
if self.is_clang():
base = ''
triplet = '%s%d-' % (self.ndk_triplet(llvm_toolchain = True), self.api)
else:
base = self.ndk_triplet() + '-'
return os.path.join(self.gen_gcc_toolchain_path(), 'bin', base)
triplet = self.ndk_triplet() + '-'
return os.path.join(self.gen_gcc_toolchain_path(), 'bin', triplet)
def gen_binutils_path(self):
if self.ndk_rev >= 23:
@@ -224,11 +215,7 @@ class Android:
s = environ['CC']
return '%s --target=%s%d' % (s, self.ndk_triplet(), self.api)
if self.is_clang():
return '%s --target=%s%d' % (self.gen_toolchain_path() + 'clang' + self.exe, self.ndk_triplet(), self.api)
return self.gen_toolchain_path() + 'gcc'
return self.gen_toolchain_path() + ('clang' if self.is_clang() else 'gcc')
def cxx(self):
if self.is_host():
@@ -239,33 +226,19 @@ class Android:
s = environ['CXX']
return '%s --target=%s%d' % (s, self.ndk_triplet(), self.api)
if self.is_clang():
return '%s --target=%s%d' % (self.gen_toolchain_path() + 'clang++' + self.exe, self.ndk_triplet(), self.api)
return self.gen_toolchain_path() + 'g++'
return self.gen_toolchain_path() + ('clang++' if self.is_clang() else 'g++')
def strip(self):
if self.is_host():
environ = getattr(self.ctx, 'environ', os.environ)
if 'STRIP' in environ:
return environ['STRIP']
return 'llvm-strip'
if self.ndk_rev >= 23:
return os.path.join(self.gen_binutils_path(), 'llvm-strip' + self.exe)
return os.path.join(self.gen_binutils_path(), 'strip' + self.exe)
def ar(self):
if self.is_host():
environ = getattr(self.ctx, 'environ', os.environ)
if 'AR' in environ:
return environ['AR']
return 'llvm-ar'
if self.ndk_rev >= 23:
return os.path.join(self.gen_binutils_path(), 'llvm-ar' + self.exe)
return os.path.join(self.gen_binutils_path(), 'ar' + self.exe)
return os.path.join(self.gen_binutils_path(), 'llvm-strip')
return os.path.join(self.gen_binutils_path(), 'strip')
def system_stl(self):
# TODO: proper STL support
@@ -363,7 +336,7 @@ class Android:
ldflags += ['-lgcc']
if self.is_clang() or self.is_host():
ldflags += ['-stdlib=libstdc++', '-lc++abi']
ldflags += ['-stdlib=libstdc++']
else: ldflags += ['-no-canonical-prefixes']
if self.is_arm():
@@ -548,33 +521,25 @@ def configure(conf):
valid_archs = ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'aarch64']
if values[0] == 'arm64-v8a':
values[0] = 'aarch64'
if values[0] not in valid_archs:
conf.fatal('Unknown arch: %s. Supported: %r' % (values[0], ', '.join(valid_archs)))
conf.android = android = Android(conf, values[0], values[1], int(values[2]))
conf.environ['CC'] = android.cc()
conf.environ['CXX'] = android.cxx()
conf.environ['STRIP'] = android.strip()
conf.environ['AR'] = android.ar()
conf.env.CFLAGS += android.cflags()
conf.env.CXXFLAGS += android.cflags(True)
conf.env.LINKFLAGS += android.linkflags()
conf.env.LDFLAGS += android.ldflags()
from waflib.Tools.compiler_c import c_compiler
from waflib.Tools.compiler_cxx import cxx_compiler
c_compiler['win32'] = ['clang' if android.is_clang() or android.is_host() else 'gcc']
cxx_compiler['win32'] = ['clang++' if android.is_clang() or android.is_host() else 'gxx']
conf.env.HAVE_M = True
if android.is_hardfp():
conf.env.LIB_M = ['m_hard']
else: conf.env.LIB_M = ['m']
conf.env.PREFIX = '/lib/%s' % android.apk_arch()
conf.msg('Selected Android NDK', '%s, version: %d' % (android.ndk_home, android.ndk_rev))
# no need to print C/C++ compiler, as it would be printed by compiler_c/cxx
conf.msg('... C/C++ flags', ' '.join(android.cflags()).replace(android.ndk_home, '$NDK/'))

57
wscript
View File

@@ -84,7 +84,6 @@ SUBDIRS = [
Subproject('filesystem'),
Subproject('stub/server'),
Subproject('dllemu'),
Subproject('3rdparty/libbacktrace'),
# disable only by engine feature, makes no sense to even parse subprojects in dedicated mode
Subproject('3rdparty/extras', lambda x: x.env.CLIENT and x.env.DEST_OS != 'android'),
@@ -274,13 +273,9 @@ def configure(conf):
else:
force_32bit = conf.options.FORCE32
# FIXME: move this whole logic to force_32bit.py, and ensure
# DEST_SIZEOF_VOID_P is always set
if force_32bit:
Logs.info('WARNING: will build engine for 32-bit target')
conf.force_32bit(True)
else:
conf.env.DEST_SIZEOF_VOID_P = 4 if conf.check_32bit() else 8
cflags, linkflags = conf.get_optimization_flags()
cxxflags = list(cflags) # optimization flags are common between C and C++ but we need a copy
@@ -468,16 +463,7 @@ def configure(conf):
# set _FILE_OFFSET_BITS=64 for filesystems with 64-bit inodes
# must be set globally as it changes ABI
if conf.env.DEST_OS == 'android' and conf.env.DEST_SIZEOF_VOID_P == 4:
# Android in 32-bit mode don't have good enough large file support
# with our native API level
# https://android.googlesource.com/platform/bionic/+/HEAD/docs/32-bit-abi.md
pass
elif conf.env.DEST_OS == 'psvita':
# PSVita don't have large file support at all
pass
else:
# try to guess how to support large files
if conf.env.DEST_OS not in ['psvita']:
conf.check_large_file(compiler = 'c', execute = False)
# indicate if we are packaging for Linux/BSD
@@ -493,35 +479,28 @@ def configure(conf):
else:
conf.env.SHAREDIR = conf.env.LIBDIR = conf.env.BINDIR = conf.env.PREFIX
if not conf.options.BUILD_BUNDLED_DEPS:
# there was a check for system libbacktrace but we can't be sure if it supports fileline or not
# therefore, always build libbacktrace ourselves
# dedicated server don't have external dependencies
if not conf.options.BUILD_BUNDLED_DEPS and not conf.options.DEDICATED:
for i in ('ogg','opusfile','vorbis','vorbisfile'):
if conf.check_cfg(package=i, uselib_store=i, args='--cflags --libs', mandatory=False):
conf.env['HAVE_SYSTEM_%s' % i.upper()] = True
if conf.env.CLIENT:
for i in ('ogg','opusfile','vorbis','vorbisfile'):
if conf.check_cfg(package=i, uselib_store=i, args='--cflags --libs', mandatory=False):
conf.env['HAVE_SYSTEM_%s' % i.upper()] = True
if conf.env.HAVE_SYSTEM_OPUSFILE:
frag='''#include <opusfile.h>
int main(int argc, char **argv) { return opus_tagcompare(argv[0], argv[1]); }'''
conf.env.HAVE_SYSTEM_OPUSFILE = conf.check_cc(msg='Checking for libopusfile sanity', use='opusfile werror', fragment=frag, mandatory=False)
# search for opus 1.4 only, it has fixes for custom modes
# 1.5 breaks custom modes: https://github.com/xiph/opus/issues/374
if conf.check_cfg(package='opus', uselib_store='opus', args='opus = 1.4 --cflags --libs', mandatory=False):
# now try to link with export that only exists with CUSTOM_MODES defined
frag='''#include <opus_custom.h>
# search for opus 1.4 only, it has fixes for custom modes
# 1.5 breaks custom modes: https://github.com/xiph/opus/issues/374
if conf.check_cfg(package='opus', uselib_store='opus', args='opus = 1.4 --cflags --libs', mandatory=False):
# now try to link with export that only exists with CUSTOM_MODES defined
frag='''#include <opus_custom.h>
int main(void) { return !opus_custom_encoder_init((OpusCustomEncoder *)1, (const OpusCustomMode *)1, 1); }'''
conf.env.HAVE_SYSTEM_OPUS = conf.check_cc(msg='Checking if opus supports custom modes', defines='CUSTOM_MODES=1', use='opus werror', fragment=frag, mandatory=False)
if conf.check_cc(msg='Checking if opus supports custom modes', defines='CUSTOM_MODES=1', use='opus werror', fragment=frag, mandatory=False):
conf.env.HAVE_SYSTEM_OPUS = True
# search for bzip2
BZIP2_CHECK='''#include <bzlib.h>
# search for bzip2
BZIP2_CHECK='''#include <bzlib.h>
int main(void) { return (int)BZ2_bzlibVersion(); }'''
conf.env.HAVE_SYSTEM_BZ2 = conf.check_cc(lib='bz2', fragment=BZIP2_CHECK, uselib_store='bzip2', mandatory=False)
if conf.check_cc(lib='bz2', fragment=BZIP2_CHECK, uselib_store='bzip2', mandatory=False):
conf.env.HAVE_SYSTEM_BZ2 = True
conf.define('XASH_LOW_MEMORY', conf.options.LOW_MEMORY)
@@ -538,7 +517,7 @@ def build(bld):
# don't clean QtCreator files and reconfigure saved options
bld.clean_files = bld.bldnode.ant_glob('**',
excl='*.user configuration.py .lock* *conf_check_*/** config.log 3rdparty/libbacktrace/*.h %s/*' % Build.CACHE_DIR,
excl='*.user configuration.py .lock* *conf_check_*/** config.log %s/*' % Build.CACHE_DIR,
quiet=True, generator=True)
bld.load('xshlib')