merge changes from the defunct ubot

This commit is contained in:
dmitry 2020-06-12 18:52:38 +03:00 committed by jeefo
commit cf501b75b7
90 changed files with 11977 additions and 3907 deletions

92
ext/crlib/cr-alloc.h Normal file
View file

@ -0,0 +1,92 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <new>
#include <crlib/cr-basic.h>
#include <crlib/cr-movable.h>
#include <crlib/cr-platform.h>
CR_NAMESPACE_BEGIN
// default allocator for cr-objects
class Allocator : public Singleton <Allocator> {
public:
Allocator () = default;
~Allocator () = default;
public:
template <typename T> T *allocate (const size_t length = 1) {
auto ptr = reinterpret_cast <T *> (malloc (length * sizeof (T)));
if (!ptr) {
plat.abort ();
}
return ptr;
}
template <typename T> void deallocate (T *memory) {
free (memory);
memory = nullptr;
}
public:
template <typename T, typename ...Args> void construct (T *memory, Args &&...args) {
new (memory) T (cr::forward <Args> (args)...);
}
template <typename T> void destruct (T *memory) {
memory->~T ();
}
public:
template <typename T, typename ...Args> T *create (Args &&...args) {
auto d = allocate <T> ();
new (d) T (cr::forward <Args> (args)...);
return d;
}
template <typename T> T *createArray (const size_t amount) {
auto memory = allocate <T> (amount);
for (size_t i = 0; i < amount; ++i) {
new (memory + i) T ();
}
return memory;
}
template <typename T> void destroy (T *memory) {
if (memory) {
destruct (memory);
deallocate (memory);
}
}
};
CR_EXPOSE_GLOBAL_SINGLETON (Allocator, alloc);
template <typename T> class UniquePtr;
// implment singleton with UniquePtr
template <typename T> T &Singleton <T>::instance () {
static const UniquePtr <T> instance_ { alloc.create <T> () };
return *instance_;
}
CR_NAMESPACE_END

416
ext/crlib/cr-array.h Normal file
View file

@ -0,0 +1,416 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#include <crlib/cr-alloc.h>
#include <crlib/cr-movable.h>
#include <crlib/cr-random.h>
#include <initializer_list>
// policy to reserve memory
CR_DECLARE_SCOPED_ENUM (ReservePolicy,
Multiple,
Single,
)
CR_NAMESPACE_BEGIN
// simple array class like std::vector
template <typename T, ReservePolicy R = ReservePolicy::Multiple, size_t S = 0> class Array : public DenyCopying {
private:
T *m_data {};
size_t m_capacity {};
size_t m_length {};
public:
explicit Array () {
if (fix (S > 0)) {
reserve (S);
}
}
Array (const size_t amount) {
reserve (amount);
}
Array (Array &&rhs) noexcept {
m_data = rhs.m_data;
m_length = rhs.m_length;
m_capacity = rhs.m_capacity;
rhs.reset ();
}
Array (const std::initializer_list <T> &list) {
for (const auto &elem : list) {
push (elem);
}
}
~Array () {
destroy ();
}
private:
void destructElements () noexcept {
for (size_t i = 0; i < m_length; ++i) {
alloc.destruct (&m_data[i]);
}
}
void transferElements (T *dest, T *src, size_t length) noexcept {
for (size_t i = 0; i < length; ++i) {
alloc.construct (&dest[i], cr::move (src[i]));
alloc.destruct (&src[i]);
}
}
void destroy () {
destructElements ();
alloc.deallocate (m_data);
}
void reset () {
m_data = nullptr;
m_capacity = 0;
m_length = 0;
}
public:
bool reserve (const size_t amount) {
if (m_length + amount < m_capacity) {
return true;
}
auto capacity = m_capacity ? m_capacity : 12;
if (cr::fix (R == ReservePolicy::Multiple)) {
while (m_length + amount > capacity) {
capacity *= 2;
}
}
else {
capacity = amount + m_capacity + 1;
}
auto data = alloc.allocate <T> (capacity);
if (m_data) {
transferElements (data, m_data, m_length);
alloc.deallocate (m_data);
}
m_data = data;
m_capacity = capacity;
return true;
}
bool resize (const size_t amount) {
if (amount < m_length) {
while (amount < m_length) {
discard ();
}
}
else if (amount > m_length) {
if (!ensure (amount)) {
return false;
}
size_t resizeLength = amount - m_length;
while (resizeLength--) {
emplace ();
}
}
return true;
}
bool ensure (const size_t amount) {
if (amount <= m_length) {
return true;
}
return reserve (amount - m_length);
}
template <typename U = size_t> U length () const {
return static_cast <U> (m_length);
}
size_t capacity () const {
return m_capacity;
}
template <typename U> bool set (size_t index, U &&object) {
if (index >= m_capacity) {
if (!reserve (index + 1)) {
return false;
}
}
alloc.construct (&m_data[index], cr::forward <U> (object));
if (index >= m_length) {
m_length = index + 1;
}
return true;
}
template <typename U> bool insert (size_t index, U &&object) {
return insert (index, &object, 1);
}
template <typename U> bool insert (size_t index, U *objects, size_t count = 1) {
if (!objects || !count) {
return false;
}
const size_t capacity = (m_length > index ? m_length : index) + count;
if (capacity >= m_capacity && !reserve (capacity)) {
return false;
}
if (index >= m_length) {
for (size_t i = 0; i < count; ++i) {
alloc.construct (&m_data[i + index], cr::forward <U> (objects[i]));
}
m_length = capacity;
}
else {
size_t i = 0;
for (i = m_length; i > index; --i) {
m_data[i + count - 1] = cr::move (m_data[i - 1]);
}
for (i = 0; i < count; ++i) {
alloc.construct (&m_data[i + index], cr::forward <U> (objects[i]));
}
m_length += count;
}
return true;
}
bool insert (size_t at, const Array &rhs) {
if (&rhs == this) {
return false;
}
return insert (at, &rhs.m_data[0], rhs.m_length);
}
bool erase (const size_t index, const size_t count) {
if (index + count > m_capacity) {
return false;
}
for (size_t i = index; i < index + count; ++i) {
alloc.destruct (&m_data[i]);
}
m_length -= count;
for (size_t i = index; i < m_length; ++i) {
m_data[i] = cr::move (m_data[i + count]);
}
return true;
}
bool shift () {
return erase (0, 1);
}
template <typename U> bool unshift (U &&object) {
return insert (0, &object);
}
bool remove (const T &object) {
return erase (index (object), 1);
}
template <typename U> bool push (U &&object) {
if (!reserve (1)) {
return false;
}
alloc.construct (&m_data[m_length], cr::forward <U> (object));
++m_length;
return true;
}
template <typename ...Args> bool emplace (Args &&...args) {
if (!reserve (1)) {
return false;
}
alloc.construct (&m_data[m_length], cr::forward <Args> (args)...);
++m_length;
return true;
}
T pop () {
auto object = cr::move (m_data[m_length - 1]);
discard ();
return object;
}
void discard () {
erase (m_length - 1, 1);
}
size_t index (const T &object) const {
return &object - &m_data[0];
}
void shuffle () {
for (size_t i = m_length; i >= 1; --i) {
cr::swap (m_data[i - 1], m_data[rg.int_ (i, m_length - 2)]);
}
}
void reverse () {
for (size_t i = 0; i < m_length / 2; ++i) {
cr::swap (m_data[i], m_data[m_length - 1 - i]);
}
}
template <typename U> bool extend (U &&rhs) {
if (m_length == 0) {
*this = cr::move (rhs);
}
else {
for (size_t i = 0; i < rhs.length (); ++i) {
if (!push (cr::move (rhs[i]))) {
return false;
}
}
}
return true;
}
template <typename U> bool assign (U &&rhs) {
clear ();
return extend (cr::move (rhs));
}
void clear () {
destructElements ();
m_length = 0;
}
bool empty () const {
return m_length == 0;
}
bool shrink () {
if (m_length == m_capacity || !m_length) {
return false;
}
auto data = alloc.allocate <T> (m_length);
transferElements (data, m_data, m_length);
alloc.deallocate (m_data);
m_data = data;
m_capacity = m_length;
return true;
}
const T &at (size_t index) const {
return m_data[index];
}
T &at (size_t index) {
return m_data[index];
}
const T &first () const {
return m_data[0];
}
T &first () {
return m_data[0];
}
T &last () {
return m_data[m_length - 1];
}
const T &last () const {
return m_data[m_length - 1];
}
const T &random () const {
return m_data[rg.int_ <size_t> (0, m_length - 1)];
}
T &random () {
return m_data[rg.int_ <size_t> (0u, m_length - 1u)];
}
T *data () {
return m_data;
}
T *data () const {
return m_data;
}
public:
Array &operator = (Array &&rhs) noexcept {
if (this != &rhs) {
destroy ();
m_data = rhs.m_data;
m_length = rhs.m_length;
m_capacity = rhs.m_capacity;
rhs.reset ();
}
return *this;
}
public:
const T &operator [] (size_t index) const {
return at (index);
}
T &operator [] (size_t index) {
return at (index);
}
// for range-based loops
public:
T *begin () {
return m_data;
}
T *begin () const {
return m_data;
}
T *end () {
return m_data + m_length;
}
T *end () const {
return m_data + m_length;
}
};
// small array (with minimal reserve policy, something like fixed array, but still able to grow, by default allocates 64 elements)
template <typename T> using SmallArray = Array <T, ReservePolicy::Single, 64>;
CR_NAMESPACE_END

134
ext/crlib/cr-basic.h Normal file
View file

@ -0,0 +1,134 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
// our global namaespace
#define CR_NAMESPACE_BEGIN namespace cr {
#define CR_NAMESPACE_END }
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>
CR_NAMESPACE_BEGIN
//
// some useful type definitions
//
namespace types {
using int8 = signed char;
using int16 = signed short;
using int32 = signed int;
using uint8 = unsigned char;
using uint16 = unsigned short;
using uint32 = unsigned int;
using uint64 = unsigned long long;
}
// make types available for our own use
using namespace cr::types;
//
// global helper stuff
//
template <typename T, size_t N> constexpr size_t bufsize (const T (&)[N]) {
return N - 1;
}
template <typename T> constexpr T abs (const T &a) {
return a > 0 ? a : -a;
}
template <typename T> constexpr T bit (const T &a) {
return static_cast <T> (1ULL << a);
}
template <typename T> constexpr T min (const T &a, const T &b) {
return a < b ? a : b;
}
template <typename T> constexpr T max (const T &a, const T &b) {
return a > b ? a : b;
}
template <typename T> constexpr T square (const T &value) {
return value * value;
}
template <typename T> constexpr T clamp (const T &x, const T &a, const T &b) {
return min (max (x, a), b);
}
template <typename T> const T &fix (const T &type) {
return type;
}
//
// base classes
//
// simple non-copying base class
class DenyCopying {
protected:
explicit DenyCopying () = default;
~DenyCopying () = default;
public:
DenyCopying (const DenyCopying &) = delete;
DenyCopying &operator = (const DenyCopying &) = delete;
};
// singleton for objects
template<typename T> class Singleton : public DenyCopying {
protected:
Singleton ()
{ }
public:
static T &instance (); // implemented in cr-alloc.h
public:
T *operator -> () {
return &instance ();
}
};
// simple scoped enum, instaed of enum class
#define CR_DECLARE_SCOPED_ENUM_TYPE(enumName, enumType, ...) \
CR_NAMESPACE_BEGIN \
namespace enums { \
struct _##enumName : protected DenyCopying { \
enum Type : enumType { \
__VA_ARGS__ \
}; \
}; \
} \
CR_NAMESPACE_END \
using enumName = ::cr::enums::_##enumName::Type; \
// same as above, but with int32 type
#define CR_DECLARE_SCOPED_ENUM(enumName, ...) \
CR_DECLARE_SCOPED_ENUM_TYPE(enumName, int32, __VA_ARGS__) \
// exposes global variable from class singleton
#define CR_EXPOSE_GLOBAL_SINGLETON(className, variable) \
static auto &variable = className::instance () \
CR_NAMESPACE_END
// platform-dependant-stuff
#include <crlib/cr-platform.h>

159
ext/crlib/cr-binheap.h Normal file
View file

@ -0,0 +1,159 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-array.h>
CR_NAMESPACE_BEGIN
// simple priority queue
template <typename T> class BinaryHeap final : public DenyCopying {
private:
Array <T> contents_;
public:
explicit BinaryHeap () = default;
BinaryHeap (BinaryHeap &&rhs) noexcept : contents_ (cr::move (rhs.contents_))
{ }
~BinaryHeap () = default;
public:
template <typename U> bool push (U &&item) {
if (!contents_.push (cr::move (item))) {
return false;
}
const size_t length = contents_.length ();
if (length > 1) {
percolateUp (length - 1);
}
return true;
}
template <typename ...Args> bool emplace (Args &&...args) {
if (!contents_.emplace (cr::forward <Args> (args)...)) {
return false;
}
const size_t length = contents_.length ();
if (length > 1) {
percolateUp (length - 1);
}
return true;
}
const T &top () const {
return contents_[0];
}
T pop () {
if (contents_.length () == 1) {
return contents_.pop ();
}
auto key (cr::move (contents_[0]));
contents_[0] = cr::move (contents_.last ());
contents_.discard ();
percolateDown (0);
return key;
}
public:
size_t length () const {
return contents_.length ();
}
bool empty () const {
return !contents_.length ();
}
void clear () {
contents_.clear ();
}
private:
void percolateUp (size_t index) {
while (index != 0) {
const size_t parentIndex = parent (index);
if (contents_[parentIndex] > contents_[index]) {
cr::swap (contents_[index], contents_[parentIndex]);
index = parentIndex;
}
else {
break;
}
}
}
void percolateDown (size_t index) {
while (hasLeft (index)) {
size_t bestIndex = left (index);
if (hasRight (index)) {
const size_t rightIndex = right (index);
if (contents_[rightIndex] < contents_[bestIndex]) {
bestIndex = rightIndex;
}
}
if (contents_[index] > contents_[bestIndex]) {
cr::swap (contents_[index], contents_[bestIndex]);
index = bestIndex;
bestIndex = left (index);
}
else {
break;
}
}
}
private:
BinaryHeap &operator = (BinaryHeap &&rhs) noexcept {
if (this != &rhs) {
contents_ = cr::move (rhs.contents_);
}
return *this;
}
private:
static constexpr size_t parent (size_t index) {
return (index - 1) / 2;
}
static constexpr size_t left (size_t index) {
return (index * 2) + 1;
}
static constexpr size_t right (size_t index) {
return (index * 2) + 2;
}
bool hasLeft (size_t index) const {
return left (index) < contents_.length ();
}
bool hasRight (size_t index) const {
return right (index) < contents_.length ();
}
};
CR_NAMESPACE_END

47
ext/crlib/cr-color.h Normal file
View file

@ -0,0 +1,47 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
CR_NAMESPACE_BEGIN
// simple color holder
class Color final {
public:
int32 red = 0, green = 0, blue = 0;
public:
Color (int32 r, int32 g, int32 b) : red (r), green (g), blue (b) { }
explicit Color () = default;
~Color () = default;
public:
void reset () {
red = green = blue = 0;
}
int32 avg () const {
return sum () / (sizeof (Color) / sizeof (int32));
}
int32 sum () const {
return red + green + blue;
}
};
CR_NAMESPACE_END

47
ext/crlib/cr-complete.h Normal file
View file

@ -0,0 +1,47 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <stdio.h>
#include <crlib/cr-platform.h>
#include <crlib/cr-basic.h>
#include <crlib/cr-alloc.h>
#include <crlib/cr-array.h>
#include <crlib/cr-binheap.h>
#include <crlib/cr-files.h>
#include <crlib/cr-lambda.h>
#include <crlib/cr-http.h>
#include <crlib/cr-library.h>
#include <crlib/cr-dict.h>
#include <crlib/cr-logger.h>
#include <crlib/cr-math.h>
#include <crlib/cr-vector.h>
#include <crlib/cr-random.h>
#include <crlib/cr-ulz.h>
#include <crlib/cr-color.h>
#include <crlib/cr-hook.h>
CR_NAMESPACE_BEGIN
namespace types {
using StringArray = Array <String>;
using IntArray = Array <int>;
}
using namespace cr::types;
CR_NAMESPACE_END

270
ext/crlib/cr-dict.h Normal file
View file

@ -0,0 +1,270 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#include <crlib/cr-array.h>
#include <crlib/cr-string.h>
#include <crlib/cr-twin.h>
CR_NAMESPACE_BEGIN
// template for hashing our string
template <typename K> struct StringHash {
uint32 operator () (const K &key) const {
auto str = const_cast <char *> (key.chars ());
uint32 hash = 0;
while (*str++) {
hash = ((hash << 5) + hash) + *str;
}
return hash;
}
};
// template for hashing integers
template <typename K> struct IntHash {
uint32 operator () (K key) const {
key = ((key >> 16) ^ key) * 0x119de1f3;
key = ((key >> 16) ^ key) * 0x119de1f3;
key = (key >> 16) ^ key;
return key;
}
};
// template for np hashing integers
template <typename K> struct IntNoHash {
uint32 operator () (K key) const {
return static_cast <uint32> (key);
}
};
namespace detail {
struct DictionaryList {
uint32 index;
DictionaryList *next;
};
template <typename K, typename V> struct DictionaryBucket {
uint32 hash = static_cast <uint32> (-1);
K key {};
V value {};
public:
DictionaryBucket () = default;
~DictionaryBucket () = default;
public:
DictionaryBucket (DictionaryBucket &&rhs) noexcept : hash (rhs.hash), key (cr::move (rhs.key)), value (cr::move (rhs.value))
{ }
public:
DictionaryBucket &operator = (DictionaryBucket &&rhs) noexcept {
if (this != &rhs) {
key = cr::move (rhs.key);
value = cr::move (rhs.value);
hash = rhs.hash;
}
return *this;
}
};
}
// basic dictionary
template <class K, class V, class H = StringHash <K>, size_t HashSize = 36> class Dictionary final : public DenyCopying {
private:
using DictBucket = detail::DictionaryBucket <K, V>;
using DictList = detail::DictionaryList;
public:
enum : size_t {
InvalidIndex = static_cast <size_t> (-1)
};
private:
Array <DictList *> m_table;
Array <DictBucket> m_buckets{};
H m_hasher;
private:
uint32 hash (const K &key) const {
return m_hasher (key);
}
size_t find (const K &key, bool allocate) {
auto hashed = hash (key);
auto pos = hashed % m_table.length ();
for (auto bucket = m_table[pos]; bucket != nullptr; bucket = bucket->next) {
if (m_buckets[bucket->index].hash == hashed) {
return bucket->index;
}
}
if (allocate) {
size_t created = m_buckets.length ();
m_buckets.resize (created + 1);
auto allocated = alloc.allocate <DictList> ();
allocated->index = static_cast <int32> (created);
allocated->next = m_table[pos];
m_table[pos] = allocated;
m_buckets[created].key = key;
m_buckets[created].hash = hashed;
return created;
}
return InvalidIndex;
}
size_t findIndex (const K &key) const {
return const_cast <Dictionary *> (this)->find (key, false);
}
public:
explicit Dictionary () {
reset ();
}
Dictionary (Dictionary &&rhs) noexcept : m_table (cr::move (rhs.m_table)), m_buckets (cr::move (rhs.m_buckets)), m_hasher (cr::move (rhs.m_hasher))
{ }
~Dictionary () {
clear ();
}
public:
bool exists (const K &key) const {
return findIndex (key) != InvalidIndex;
}
bool empty () const {
return m_buckets.empty ();
}
size_t length () const {
return m_buckets.length ();
}
bool find (const K &key, V &value) const {
size_t index = findIndex (key);
if (index == InvalidIndex) {
return false;
}
value = m_buckets[index].value;
return true;
}
template <typename U> bool push (const K &key, U &&value) {
operator [] (key) = cr::forward <U> (value);
return true;
}
bool remove (const K &key) {
auto hashed = hash (key);
auto pos = hashed % m_table.length ();
auto *bucket = m_table[pos];
DictList *next = nullptr;
while (bucket != nullptr) {
if (m_buckets[bucket->index].hash == hashed) {
if (!next) {
m_table[pos] = bucket->next;
}
else {
next->next = bucket->next;
}
m_buckets.erase (bucket->index, 1);
alloc.deallocate (bucket);
bucket = nullptr;
return true;
}
next = bucket;
bucket = bucket->next;
}
return false;
}
void clear () {
for (auto object : m_table) {
while (object != nullptr) {
auto next = object->next;
alloc.deallocate (object);
object = next;
}
}
m_table.clear ();
m_buckets.clear ();
reset ();
}
void reset () {
m_table.resize (HashSize);
for (size_t i = 0; i < HashSize; ++i) {
m_table[i] = nullptr;
}
}
public:
V &operator [] (const K &key) {
return m_buckets[find (key, true)].value;
}
const V &operator [] (const K &key) const {
return m_buckets[findIndex (key)].value;
}
Dictionary &operator = (Dictionary &&rhs) noexcept {
if (this != &rhs) {
m_table = cr::move (rhs.m_table);
m_buckets = cr::move (rhs.m_buckets);
m_hasher = cr::move (rhs.m_hasher);
}
return *this;
}
// for range-based loops
public:
DictBucket *begin () {
return m_buckets.begin ();
}
DictBucket *begin () const {
return m_buckets.begin ();
}
DictBucket *end () {
return m_buckets.end ();
}
DictBucket *end () const {
return m_buckets.end ();
}
};
CR_NAMESPACE_END

393
ext/crlib/cr-files.h Normal file
View file

@ -0,0 +1,393 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <stdio.h>
#include <crlib/cr-string.h>
#include <crlib/cr-lambda.h>
CR_NAMESPACE_BEGIN
// simple stdio file wrapper
class File final : private DenyCopying {
private:
FILE *handle_ = nullptr;
size_t length_ {};
public:
explicit File () = default;
File (StringRef file, StringRef mode = "rt") {
open (file, mode);
}
~File () {
close ();
}
public:
bool open (StringRef file, StringRef mode) {
if (!openFile (file, mode)) {
return false;
}
fseek (handle_, 0L, SEEK_END);
length_ = ftell (handle_);
fseek (handle_, 0L, SEEK_SET);
return true;
}
void close () {
if (handle_ != nullptr) {
fclose (handle_);
handle_ = nullptr;
}
length_ = 0;
}
bool eof () const {
return !!feof (handle_);
}
bool flush () const {
return !!fflush (handle_);
}
int get () const {
return fgetc (handle_);
}
char *getString (char *buffer, int count) const {
return fgets (buffer, count, handle_);
}
bool getLine (String &line) {
int ch = 0;
SmallArray <char> data (255);
while ((ch = get ()) != EOF && !eof ()) {
data.push (static_cast <char> (ch));
if (ch == '\n') {
break;
}
}
line.assign (data.data (), data.length ());
return !eof ();
}
template <typename ...Args> size_t puts (const char *fmt, Args &&...args) {
if (!*this) {
return 0;
}
return fputs (strings.format (fmt, cr::forward <Args> (args)...), handle_);
}
bool puts (const char *buffer) {
if (!*this) {
return 0;
}
if (fputs (buffer, handle_) < 0) {
return false;
}
return true;
}
int putChar (int ch) {
return fputc (ch, handle_);
}
size_t read (void *buffer, size_t size, size_t count = 1) {
return fread (buffer, size, count, handle_);
}
size_t write (void *buffer, size_t size, size_t count = 1) {
return fwrite (buffer, size, count, handle_);
}
bool seek (long offset, int origin) {
if (fseek (handle_, offset, origin) != 0) {
return false;
}
return true;
}
void rewind () {
::rewind (handle_);
}
size_t length () const {
return length_;
}
public:
explicit operator bool () const {
return handle_ != nullptr;
}
public:
static inline bool exists (StringRef file) {
File fp;
if (fp.open (file, "rb")) {
fp.close ();
return true;
}
return false;
}
static inline void createPath (const char *path) {
for (auto str = const_cast <char *> (path) + 1; *str; ++str) {
if (*str == '/') {
*str = 0;
plat.createDirectory (path);
*str = '/';
}
}
plat.createDirectory (path);
}
private:
bool openFile (StringRef filename, StringRef mode) {
if (*this) {
close ();
}
#if defined (CR_WINDOWS)
fopen_s (&handle_, filename.chars (), mode.chars ());
#else
handle_ = fopen (filename.chars (), mode.chars ());
#endif
return handle_ != nullptr;
}
};
// wrapper for memory file for loading data into the memory
class MemFileStorage : public Singleton <MemFileStorage> {
private:
using LoadFunction = Lambda <uint8 * (const char *, int *)>;
using FreeFunction = Lambda <void (void *)>;
private:
LoadFunction loadFun_ = nullptr;
FreeFunction freeFun_ = nullptr;
public:
inline MemFileStorage () = default;
inline ~MemFileStorage () = default;
public:
void initizalize (LoadFunction loader, FreeFunction unloader) {
loadFun_ = cr::move (loader);
freeFun_ = cr::move (unloader);
}
public:
uint8 *load (StringRef file, int *size) {
if (loadFun_) {
return loadFun_ (file.chars (), size);
}
return nullptr;
}
void unload (void *buffer) {
if (freeFun_) {
freeFun_ (buffer);
}
}
public:
static uint8 *defaultLoad (const char *path, int *size) {
File file (path, "rb");
if (!file) {
*size = 0;
return nullptr;
}
*size = static_cast <int> (file.length ());
auto data = alloc.allocate <uint8> (*size);
file.read (data, *size);
return data;
}
static void defaultUnload (void *buffer) {
alloc.deallocate (buffer);
}
static String loadToString (StringRef filename) {
int32 result = 0;
auto buffer = defaultLoad (filename.chars (), &result);
if (result > 0 && buffer) {
String data (reinterpret_cast <char *> (buffer), result);
defaultUnload (buffer);
return data;
}
return "";
}
};
class MemFile final : public DenyCopying {
private:
enum : char {
Eof = static_cast <char> (-1)
};
private:
uint8 *contents_ = nullptr;
size_t length_ {};
size_t seek_ {};
public:
explicit MemFile () = default;
MemFile (StringRef file) {
open (file);
}
~MemFile () {
close ();
}
public:
bool open (StringRef file) {
length_ = 0;
seek_ = 0;
contents_ = MemFileStorage::instance ().load (file.chars (), reinterpret_cast <int *> (&length_));
if (!contents_) {
return false;
}
return true;
}
void close () {
MemFileStorage::instance ().unload (contents_);
length_ = 0;
seek_ = 0;
contents_ = nullptr;
}
char get () {
if (!contents_ || seek_ >= length_) {
return Eof;
}
auto ch = contents_[seek_];
++seek_;
return static_cast <char> (ch);
}
char *getString (char *buffer, size_t count) {
if (!contents_ || seek_ >= length_) {
return nullptr;
}
size_t index = 0;
buffer[0] = 0;
for (; index < count - 1;) {
if (seek_ < length_) {
buffer[index] = contents_[seek_++];
if (buffer[index++] == '\n') {
break;
}
}
else {
break;
}
}
buffer[index] = 0;
return index ? buffer : nullptr;
}
bool getLine (String &line) {
char ch;
SmallArray <char> data (255);
while ((ch = get ()) != Eof) {
data.push (ch);
if (ch == '\n') {
break;
}
}
line.assign (data.data (), data.length ());
return !eof ();
}
size_t read (void *buffer, size_t size, size_t count = 1) {
if (!contents_ || length_ <= seek_ || !buffer || !size || !count) {
return 0;
}
size_t blocksRead = size * count <= length_ - seek_ ? size * count : length_ - seek_;
memcpy (buffer, &contents_[seek_], blocksRead);
seek_ += blocksRead;
return blocksRead / size;
}
bool seek (size_t offset, int origin) {
if (!contents_ || seek_ >= length_) {
return false;
}
if (origin == SEEK_SET) {
if (offset >= length_) {
return false;
}
seek_ = offset;
}
else if (origin == SEEK_END) {
if (offset >= length_) {
return false;
}
seek_ = length_ - offset;
}
else {
if (seek_ + offset >= length_) {
return false;
}
seek_ += offset;
}
return true;
}
size_t length () const {
return length_;
}
bool eof () const {
return seek_ >= length_;
}
void rewind () {
seek_ = 0;
}
public:
explicit operator bool () const {
return !!contents_ && length_ > 0;
}
};
CR_NAMESPACE_END

170
ext/crlib/cr-hook.h Normal file
View file

@ -0,0 +1,170 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#if !defined (CR_WINDOWS)
# include <sys/mman.h>
#endif
CR_NAMESPACE_BEGIN
class SimpleHook : DenyCopying {
private:
#if defined (CR_ARCH_X64)
using uint = uint64;
#else
using uint = uint32;
#endif
private:
enum : uint32 {
#if defined (CR_ARCH_X64)
CodeLength = 5 + sizeof (uint)
#else
CodeLength = 1 + sizeof (uint)
#endif
};
private:
bool patched_;
uint pageSize_;
uint originalFun_;
uint hookedFun_;
UniquePtr <uint8 []> originalBytes_;
UniquePtr <uint8 []> hookedBytes_;
private:
void setPageSize () {
#if defined (CR_WINDOWS)
SYSTEM_INFO sysinfo;
GetSystemInfo (&sysinfo);
pageSize_ = sysinfo.dwPageSize;
#else
pageSize_ = sysconf (_SC_PAGESIZE);
#endif
}
#if !defined (CR_WINDOWS)
void *align (void *address) {
return reinterpret_cast <void *> ((reinterpret_cast <long> (address) & ~(pageSize_ - 1)));
}
#endif
bool unprotect () {
auto orig = reinterpret_cast <void *> (originalFun_);
#if defined (CR_WINDOWS)
DWORD oldProt;
FlushInstructionCache (GetCurrentProcess (), orig, CodeLength);
return VirtualProtect (orig, CodeLength, PAGE_EXECUTE_READWRITE, &oldProt);
#else
auto aligned = align (orig);
return !mprotect (aligned, pageSize_, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
}
public:
SimpleHook () : patched_ (false), pageSize_ (0), originalFun_ (0), hookedFun_ (0) {
setPageSize ();
originalBytes_ = makeUnique <uint8 []> (CodeLength);
hookedBytes_ = makeUnique <uint8 []> (CodeLength);
}
~SimpleHook () {
disable ();
}
public:
bool patch (void *address, void *replacement) {
constexpr uint16 jmp = 0x25ff;
if (plat.arm) {
return false;
}
auto ptr = reinterpret_cast <uint8 *> (address);
while (*reinterpret_cast <uint16 *> (ptr) == jmp) {
ptr = **reinterpret_cast <uint8 ***> (ptr + 2);
}
originalFun_ = reinterpret_cast <uint> (ptr);
hookedFun_ = reinterpret_cast <uint> (replacement);
memcpy (originalBytes_.get (), reinterpret_cast <void *> (originalFun_), CodeLength);
if (plat.x64) {
const uint16 nop = 0x00000000;
memcpy (&hookedBytes_[0], &jmp, sizeof (uint16));
memcpy (&hookedBytes_[2], &nop, sizeof (uint16));
memcpy (&hookedBytes_[6], &replacement, sizeof (uint));
}
else {
hookedBytes_[0] = 0xe9;
auto rel = hookedFun_ - originalFun_ - CodeLength;
memcpy (&hookedBytes_[0] + 1, &rel, sizeof (rel));
}
return enable ();
}
bool enable () {
if (patched_) {
return false;
}
patched_ = true;
if (unprotect ()) {
memcpy (reinterpret_cast <void *> (originalFun_), hookedBytes_.get (), CodeLength);
return true;
}
return false;
}
bool disable () {
if (!patched_) {
return false;
}
patched_ = false;
if (unprotect ()) {
memcpy (reinterpret_cast <void *> (originalFun_), originalBytes_.get (), CodeLength);
return true;
}
return false;
}
bool enabled () const {
return patched_;
}
public:
template <typename T, typename... Args > decltype (auto) call (Args &&...args) {
disable ();
auto res = reinterpret_cast <T *> (originalFun_) (args...);
enable ();
return res;
}
};
CR_NAMESPACE_END

468
ext/crlib/cr-http.h Normal file
View file

@ -0,0 +1,468 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <stdio.h>
#include <crlib/cr-string.h>
#include <crlib/cr-files.h>
#include <crlib/cr-logger.h>
#include <crlib/cr-platform.h>
#if defined (CR_LINUX) || defined (CR_OSX)
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <sys/uio.h>
# include <arpa/inet.h>
# include <unistd.h>
# include <errno.h>
# include <netdb.h>
# include <fcntl.h>
#elif defined (CR_WINDOWS)
# include <winsock2.h>
# include <ws2tcpip.h>
#endif
// status codes for http client
CR_DECLARE_SCOPED_ENUM (HttpClientResult,
OK = 0,
NotFound,
Forbidden,
SocketError,
ConnectError,
HttpOnly,
Undefined,
NoLocalFile = -1,
LocalFileExists = -2
)
CR_NAMESPACE_BEGIN
class Socket final : public DenyCopying {
private:
int32 socket_;
uint32 timeout_;
public:
Socket () : socket_ (-1), timeout_ (2) {
#if defined(CR_WINDOWS)
WSADATA wsa;
if (WSAStartup (MAKEWORD (2, 2), &wsa) != 0) {
logger.error ("Unable to inialize sockets.");
}
#endif
}
~Socket () {
disconnect ();
#if defined (CR_WINDOWS)
WSACleanup ();
#endif
}
public:
bool connect (StringRef hostname) {
addrinfo hints, *result = nullptr;
plat.bzero (&hints, sizeof (hints));
constexpr auto NumericServ = 0x00000008;
hints.ai_flags = NumericServ;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo (hostname.chars (), "80", &hints, &result) != 0) {
return false;
}
socket_ = static_cast <int> (socket (result->ai_family, result->ai_socktype, 0));
if (socket_ < 0) {
freeaddrinfo (result);
return false;
}
auto getTimeouts = [&] () -> Twin <char *, int32> {
#if defined (CR_WINDOWS)
DWORD tv = timeout_ * 1000;
#else
timeval tv { static_cast <time_t> (timeout_), 0 };
#endif
return { reinterpret_cast <char *> (&tv), static_cast <int32> (sizeof (tv)) };
};
auto timeouts = getTimeouts ();
if (setsockopt (socket_, SOL_SOCKET, SO_RCVTIMEO, timeouts.first, timeouts.second) == -1) {
logger.message ("Unable to set SO_RCVTIMEO.");
}
if (setsockopt (socket_, SOL_SOCKET, SO_SNDTIMEO, timeouts.first, timeouts.second) == -1) {
logger.message ("Unable to set SO_SNDTIMEO.");
}
if (::connect (socket_, result->ai_addr, static_cast <int32> (result->ai_addrlen)) == -1) {
disconnect ();
freeaddrinfo (result);
return false;
}
freeaddrinfo (result);
return true;
}
void setTimeout (uint32 timeout) {
timeout_ = timeout;
}
void disconnect () {
#if defined(CR_WINDOWS)
if (socket_ != -1) {
closesocket (socket_);
}
#else
if (socket_ != -1)
close (socket_);
#endif
}
public:
template <typename U> int32 send (const U *buffer, int32 length) const {
return ::send (socket_, reinterpret_cast <const char *> (buffer), length, 0);
}
template <typename U> int32 recv (U *buffer, int32 length) {
return ::recv (socket_, reinterpret_cast <char *> (buffer), length, 0);
}
public:
static int32 CR_STDCALL sendto (int socket, const void *message, size_t length, int flags, const struct sockaddr *dest, int32 destLength) {
#if defined (CR_WINDOWS)
WSABUF buffer = { static_cast <ULONG> (length), const_cast <char *> (reinterpret_cast <const char *> (message)) };
DWORD sendLength = 0;
if (WSASendTo (socket, &buffer, 1, &sendLength, flags, dest, destLength, NULL, NULL) == SOCKET_ERROR) {
errno = WSAGetLastError ();
return -1;
}
return static_cast <int32> (sendLength);
#else
iovec iov = { const_cast <void *> (message), length };
msghdr msg {};
msg.msg_name = reinterpret_cast <void *> (const_cast <struct sockaddr *> (dest));
msg.msg_namelen = destLength;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
return sendmsg (socket, &msg, flags);
#endif
}
};
namespace detail {
// simple http uri omitting query-string and port
struct HttpUri {
String path, protocol, host;
public:
static HttpUri parse (StringRef uri) {
HttpUri result;
if (uri.empty ()) {
return result;
}
size_t protocol = uri.find ("://");
if (protocol != String::InvalidIndex) {
result.protocol = uri.substr (0, protocol);
size_t hostIndex = uri.find ("/", protocol + 3);
if (hostIndex != String::InvalidIndex) {
result.path = uri.substr (hostIndex + 1);
result.host = uri.substr (protocol + 3, hostIndex - protocol - 3);
return result;
}
}
return result;
}
};
}
// simple http client for downloading/uploading files only
class HttpClient final : public Singleton <HttpClient> {
private:
enum : int32 {
MaxReceiveErrors = 12
};
private:
Socket socket_;
String userAgent_ = "crlib";
HttpClientResult statusCode_ = HttpClientResult::Undefined;
int32 chunkSize_ = 4096;
public:
HttpClient () = default;
~HttpClient () = default;
private:
HttpClientResult parseResponseHeader (uint8 *buffer) {
bool isFinished = false;
int32 pos = 0, symbols = 0, errors = 0;
// prase response header
while (!isFinished && pos < chunkSize_) {
if (socket_.recv (&buffer[pos], 1) < 1) {
if (++errors > MaxReceiveErrors) {
isFinished = true;
}
else {
continue;
}
}
switch (buffer[pos]) {
case '\r':
break;
case '\n':
isFinished = (symbols == 0);
symbols = 0;
break;
default:
++symbols;
break;
}
++pos;
}
String response { reinterpret_cast <const char *> (buffer) };
size_t responseCodeStart = response.find ("HTTP/1.1");
if (responseCodeStart != String::InvalidIndex) {
String respCode = response.substr (responseCodeStart + 9, 3);
respCode.trim ();
if (respCode == "200") {
return HttpClientResult::OK;
}
else if (respCode == "403") {
return HttpClientResult::Forbidden;
}
else if (respCode == "404") {
return HttpClientResult::NotFound;
}
}
return HttpClientResult::NotFound;
}
public:
// simple blocked download
bool downloadFile (StringRef url, StringRef localPath) {
if (File::exists (localPath.chars ())) {
statusCode_ = HttpClientResult::LocalFileExists;
return false;
}
auto uri = detail::HttpUri::parse (url);
// no https...
if (uri.protocol == "https") {
statusCode_ = HttpClientResult::HttpOnly;
return false;
}
// unable to connect...
if (!socket_.connect (uri.host)) {
statusCode_ = HttpClientResult::ConnectError;
socket_.disconnect ();
return false;
}
String request;
request.appendf ("GET /%s HTTP/1.1\r\n", uri.path);
request.append ("Accept: */*\r\n");
request.append ("Connection: close\r\n");
request.append ("Keep-Alive: 115\r\n");
request.appendf ("User-Agent: %s\r\n", userAgent_);
request.appendf ("Host: %s\r\n\r\n", uri.host);
if (socket_.send (request.chars (), static_cast <int32> (request.length ())) < 1) {
statusCode_ = HttpClientResult::SocketError;
socket_.disconnect ();
return false;
}
SmallArray <uint8> buffer (chunkSize_);
statusCode_ = parseResponseHeader (buffer.data ());
if (statusCode_ != HttpClientResult::OK) {
socket_.disconnect ();
return false;
}
// receive the file
File file (localPath, "wb");
if (!file) {
statusCode_ = HttpClientResult::Undefined;
socket_.disconnect ();
return false;
}
int32 length = 0;
int32 errors = 0;
for (;;) {
length = socket_.recv (buffer.data (), chunkSize_);
if (length > 0) {
file.write (buffer.data (), length);
}
else if (++errors > 12) {
break;
}
}
file.close ();
socket_.disconnect ();
statusCode_ = HttpClientResult::OK;
return true;
}
bool uploadFile (StringRef url, StringRef localPath) {
if (!File::exists (localPath.chars ())) {
statusCode_ = HttpClientResult::NoLocalFile;
return false;
}
auto uri = detail::HttpUri::parse (url);
// no https...
if (uri.protocol == "https") {
statusCode_ = HttpClientResult::HttpOnly;
return false;
}
// unable to connect...
if (!socket_.connect (uri.host)) {
statusCode_ = HttpClientResult::ConnectError;
socket_.disconnect ();
return false;
}
// receive the file
File file (localPath, "rb");
if (!file) {
statusCode_ = HttpClientResult::Undefined;
socket_.disconnect ();
return false;
}
String boundaryName = localPath;
size_t boundarySlash = localPath.findLastOf ("\\/");
if (boundarySlash != String::InvalidIndex) {
boundaryName = localPath.substr (boundarySlash + 1);
}
StringRef boundaryLine = "---crlib_upload_boundary_1337";
String request, start, end;
start.appendf ("--%s\r\n", boundaryLine);
start.appendf ("Content-Disposition: form-data; name='file'; filename='%s'\r\n", boundaryName);
start.append ("Content-Type: application/octet-stream\r\n\r\n");
end.appendf ("\r\n--%s--\r\n\r\n", boundaryLine);
request.appendf ("POST /%s HTTP/1.1\r\n", uri.path);
request.appendf ("Host: %s\r\n", uri.host);
request.appendf ("User-Agent: %s\r\n", userAgent_);
request.appendf ("Content-Type: multipart/form-data; boundary=%s\r\n", boundaryLine);
request.appendf ("Content-Length: %d\r\n\r\n", file.length () + start.length () + end.length ());
// send the main request
if (socket_.send (request.chars (), static_cast <int32> (request.length ())) < 1) {
statusCode_ = HttpClientResult::SocketError;
socket_.disconnect ();
return false;
}
// send boundary start
if (socket_.send (start.chars (), static_cast <int32> (start.length ())) < 1) {
statusCode_ = HttpClientResult::SocketError;
socket_.disconnect ();
return false;
}
SmallArray <uint8> buffer (chunkSize_);
int32 length = 0;
for (;;) {
length = static_cast <int32> (file.read (buffer.data (), 1, chunkSize_));
if (length > 0) {
socket_.send (buffer.data (), length);
}
else {
break;
}
}
// send boundary end
if (socket_.send (end.chars (), static_cast <int32> (end.length ())) < 1) {
statusCode_ = HttpClientResult::SocketError;
socket_.disconnect ();
return false;
}
statusCode_ = parseResponseHeader (buffer.data ());
socket_.disconnect ();
return statusCode_ == HttpClientResult::OK;
}
public:
void setUserAgent (StringRef ua) {
userAgent_ = ua;
}
HttpClientResult getLastStatusCode () {
return statusCode_;
}
void setChunkSize (int32 chunkSize) {
chunkSize_ = chunkSize;
}
void setTimeout (uint32 timeout) {
socket_.setTimeout (timeout);
}
};
// expose global http client
CR_EXPOSE_GLOBAL_SINGLETON (HttpClient, http);
CR_NAMESPACE_END

182
ext/crlib/cr-lambda.h Normal file
View file

@ -0,0 +1,182 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-alloc.h>
#include <crlib/cr-uniqueptr.h>
CR_NAMESPACE_BEGIN
template <typename> class Lambda;
template <typename R, typename ...Args> class Lambda <R (Args...)> {
private:
enum : uint32 {
LamdaSmallBufferLength = sizeof (void *) * 16
};
private:
class LambdaFunctorWrapper {
public:
LambdaFunctorWrapper () = default;
virtual ~LambdaFunctorWrapper () = default;
public:
virtual void move (uint8 *to) = 0;
virtual void small (uint8 *to) const = 0;
virtual R invoke (Args &&...) = 0;
virtual UniquePtr <LambdaFunctorWrapper> clone () const = 0;
public:
void operator delete (void *ptr) {
alloc.deallocate (ptr);
}
};
template <typename T> class LambdaFunctor : public LambdaFunctorWrapper {
private:
T callable_;
public:
LambdaFunctor (const T &callable) : LambdaFunctorWrapper (), callable_ (callable)
{ }
LambdaFunctor (T &&callable) : LambdaFunctorWrapper (), callable_ (cr::move (callable))
{ }
~LambdaFunctor () override = default;
public:
void move (uint8 *to) override {
new (to) LambdaFunctor <T> (cr::move (callable_));
}
void small (uint8 *to) const override {
new (to) LambdaFunctor <T> (callable_);
}
R invoke (Args &&... args) override {
return callable_ (cr::forward <Args> (args)...);
}
UniquePtr <LambdaFunctorWrapper> clone () const override {
return makeUnique <LambdaFunctor <T>> (callable_);
}
};
union {
UniquePtr <LambdaFunctorWrapper> functor_;
uint8 small_[LamdaSmallBufferLength];
};
bool ssoObject_ = false;
private:
void destroy () {
if (ssoObject_) {
reinterpret_cast <LambdaFunctorWrapper *> (small_)->~LambdaFunctorWrapper ();
}
else {
functor_.reset ();
}
}
void swap (Lambda &rhs) noexcept {
cr::swap (rhs, *this);
}
public:
explicit Lambda () noexcept : Lambda (nullptr)
{ }
Lambda (decltype (nullptr)) noexcept : functor_ (nullptr), ssoObject_ (false)
{ }
Lambda (const Lambda &rhs) {
if (rhs.ssoObject_) {
reinterpret_cast <const LambdaFunctorWrapper *> (rhs.small_)->small (small_);
}
else {
new (small_) UniquePtr <LambdaFunctorWrapper> (rhs.functor_->clone ());
}
ssoObject_ = rhs.ssoObject_;
}
Lambda (Lambda &&rhs) noexcept {
if (rhs.ssoObject_) {
reinterpret_cast <LambdaFunctorWrapper *> (rhs.small_)->move (small_);
new (rhs.small_) UniquePtr <LambdaFunctorWrapper> (nullptr);
}
else {
new (small_) UniquePtr <LambdaFunctorWrapper> (cr::move (rhs.functor_));
}
ssoObject_ = rhs.ssoObject_;
rhs.ssoObject_ = false;
}
template <typename F> Lambda (F function) {
if (cr::fix (sizeof (function) > LamdaSmallBufferLength)) {
ssoObject_ = false;
new (small_) UniquePtr <LambdaFunctorWrapper> (makeUnique <LambdaFunctor <F>> (cr::move (function)));
}
else {
ssoObject_ = true;
new (small_) LambdaFunctor <F> (cr::move (function));
}
}
~Lambda () {
destroy ();
}
public:
Lambda &operator = (const Lambda &rhs) {
destroy ();
Lambda tmp (rhs);
swap (tmp);
return *this;
}
Lambda &operator = (Lambda &&rhs) noexcept {
destroy ();
if (rhs.ssoObject_) {
reinterpret_cast <LambdaFunctorWrapper *> (rhs.small_)->move (small_);
new (rhs.small_) UniquePtr <LambdaFunctorWrapper> (nullptr);
}
else {
new (small_) UniquePtr <LambdaFunctorWrapper> (cr::move (rhs.functor_));
}
ssoObject_ = rhs.ssoObject_;
rhs.ssoObject_ = false;
return *this;
}
explicit operator bool () const noexcept {
return ssoObject_ || !!functor_;
}
public:
R operator () (Args ...args) {
return ssoObject_ ? reinterpret_cast <LambdaFunctorWrapper *> (small_)->invoke (cr::forward <Args> (args)...) : functor_->invoke (cr::forward <Args> (args)...);
}
};
CR_NAMESPACE_END

130
ext/crlib/cr-library.h Normal file
View file

@ -0,0 +1,130 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#include <crlib/cr-string.h>
#if defined (CR_LINUX) || defined (CR_OSX)
# include <dlfcn.h>
# include <errno.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <unistd.h>
#endif
CR_NAMESPACE_BEGIN
// handling dynamic library loading
class SharedLibrary final : public DenyCopying {
public:
using Handle = void *;
private:
Handle handle_ = nullptr;
public:
explicit SharedLibrary () = default;
SharedLibrary (StringRef file) {
if (file.empty ()) {
return;
}
load (file);
}
~SharedLibrary () {
unload ();
}
public:
bool load (StringRef file) noexcept {
if (*this) {
unload ();
}
#if defined (CR_WINDOWS)
handle_ = LoadLibraryA (file.chars ());
#else
handle_ = dlopen (file.chars (), RTLD_LAZY);
#endif
return handle_ != nullptr;
}
bool locate (Handle address) {
#if defined (CR_WINDOWS)
MEMORY_BASIC_INFORMATION mbi;
if (!VirtualQuery (address, &mbi, sizeof (mbi))) {
return false;
}
if (mbi.State != MEM_COMMIT) {
return false;
}
handle_ = reinterpret_cast <Handle> (mbi.AllocationBase);
#else
Dl_info dli;
plat.bzero (&dli, sizeof (dli));
if (dladdr (address, &dli)) {
return load (dli.dli_fname);
}
#endif
return handle_ != nullptr;
}
void unload () noexcept {
if (!*this) {
return;
}
#if defined (CR_WINDOWS)
FreeLibrary (static_cast <HMODULE> (handle_));
#else
dlclose (handle_);
#endif
handle_ = nullptr;
}
template <typename R> R resolve (const char *function) const {
if (!*this) {
return nullptr;
}
return SharedLibrary::getSymbol <R> (handle (), function);
}
Handle handle () const {
return handle_;
}
public:
explicit operator bool () const {
return handle_ != nullptr;
}
public:
template <typename R> static inline R CR_STDCALL getSymbol (Handle module, const char *function) {
return reinterpret_cast <R> (
#if defined (CR_WINDOWS)
GetProcAddress (static_cast <HMODULE> (module), function)
#else
dlsym (module, function)
#endif
);
}
};
CR_NAMESPACE_END

108
ext/crlib/cr-logger.h Normal file
View file

@ -0,0 +1,108 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <time.h>
#include <crlib/cr-files.h>
#include <crlib/cr-lambda.h>
CR_NAMESPACE_BEGIN
class SimpleLogger final : public Singleton <SimpleLogger> {
public:
using PrintFunction = Lambda <void (const char *)>;
private:
File handle_;
PrintFunction printFun_;
public:
SimpleLogger () = default;
~SimpleLogger () {
handle_.close ();
}
private:
void logToFile (const char *level, const char *msg) {
if (!handle_) {
return;
}
time_t ticks = time (&ticks);
tm *timeinfo = nullptr;
#if defined (CR_WINDOWS)
tm get;
localtime_s (&get, &ticks);
timeinfo = &get;
#else
timeinfo = localtime (&ticks);
#endif
auto timebuf = strings.chars ();
strftime (timebuf, StringBuffer::StaticBufferSize, "%Y-%m-%d %H:%M:%S", timeinfo);
handle_.puts ("%s (%s): %s\n", timebuf, level, msg);
}
public:
template <typename ...Args> void fatal (const char *fmt, Args &&...args) {
auto msg = strings.format (fmt, cr::forward <Args> (args)...);
logToFile ("FATAL", msg);
if (printFun_) {
printFun_ (msg);
}
plat.abort (msg);
}
template <typename ...Args> void error (const char *fmt, Args &&...args) {
auto msg = strings.format (fmt, cr::forward <Args> (args)...);
logToFile ("ERROR", msg);
if (printFun_) {
printFun_ (msg);
}
}
template <typename ...Args> void message (const char *fmt, Args &&...args) {
auto msg = strings.format (fmt, cr::forward <Args> (args)...);
logToFile ("INFO", msg);
if (printFun_) {
printFun_ (msg);
}
}
public:
void initialize (StringRef filename, PrintFunction printFunction) {
if (handle_) {
handle_.close ();
}
printFun_ = cr::move (printFunction);
handle_.open (filename, "at");
}
};
// expose global instance
CR_EXPOSE_GLOBAL_SINGLETON (SimpleLogger, logger);
CR_NAMESPACE_END

143
ext/crlib/cr-math.h Normal file
View file

@ -0,0 +1,143 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#if defined (CR_HAS_SSE)
# include <pmmintrin.h>
#endif
#include <math.h>
CR_NAMESPACE_BEGIN
constexpr float kFloatEpsilon = 0.01f;
constexpr float kFloatEqualEpsilon = 0.001f;
constexpr float kFloatCmpEpsilon = 1.192092896e-07f;
constexpr float kMathPi = 3.141592653589793115997963468544185161590576171875f;
constexpr float kMathPiHalf = kMathPi * 0.5f;
constexpr float kDegreeToRadians = kMathPi / 180.0f;
constexpr float kRadiansToDegree = 180.0f / kMathPi;
constexpr bool fzero (const float e) {
return cr::abs (e) < kFloatEpsilon;
}
constexpr bool fequal (const float a, const float b) {
return cr:: abs (a - b) < kFloatEqualEpsilon;
}
constexpr float rad2deg (const float r) {
return r * kRadiansToDegree;
}
constexpr float deg2rad (const float d) {
return d * kDegreeToRadians;
}
constexpr float modAngles (const float a) {
return 360.0f / 65536.0f * (static_cast <int> (a * (65536.0f / 360.0f)) & 65535);
}
constexpr float normalizeAngles (const float a) {
return 360.0f / 65536.0f * (static_cast <int> ((a + 180.0f) * (65536.0f / 360.0f)) & 65535) - 180.0f;
}
constexpr float anglesDifference (const float a, const float b) {
return normalizeAngles (a - b);
}
inline float sinf (const float value) {
return ::sinf (value);
}
inline float cosf (const float value) {
return ::cosf (value);
}
inline float atanf (const float value) {
return ::atanf (value);
}
inline float atan2f (const float y, const float x) {
return ::atan2f (y, x);
}
inline float powf (const float x, const float y) {
return ::powf (x, y);
}
inline float sqrtf (const float value) {
return ::sqrtf (value);
}
inline float tanf (const float value) {
return ::tanf (value);
}
inline float ceilf (const float value) {
return ::ceilf (value);
}
inline void sincosf (const float x, const float y, const float z, float *sines, float *cosines) {
#if defined (CR_HAS_SSE)
auto set = _mm_set_ps (x, y, z, 0.0f);
auto _mm_sin = [] (__m128 rad) -> __m128 {
static auto pi2 = _mm_set_ps1 (kMathPi * 2);
static auto rp1 = _mm_set_ps1 (4.0f / kMathPi);
static auto rp2 = _mm_set_ps1 (-4.0f / (kMathPi * kMathPi));
static auto val = _mm_cmpnlt_ps (rad, _mm_set_ps1 (kMathPi));
static auto csi = _mm_castsi128_ps (_mm_set1_epi32 (0x80000000));
val = _mm_and_ps (val, pi2);
rad = _mm_sub_ps (rad, val);
val = _mm_cmpngt_ps (rad, _mm_set_ps1 (-kMathPi));
val = _mm_and_ps (val, pi2);
rad = _mm_add_ps (rad, val);
val = _mm_mul_ps (_mm_andnot_ps (csi, rad), rp2);
val = _mm_add_ps (val, rp1);
auto si = _mm_mul_ps (val, rad);
val = _mm_mul_ps (_mm_andnot_ps (csi, si), si);
val = _mm_sub_ps (val, si);
val = _mm_mul_ps (val, _mm_set_ps1 (0.225f));
return _mm_add_ps (val, si);
};
static auto hpi = _mm_set_ps1 (kMathPiHalf);
auto s = _mm_sin (set);
auto c = _mm_sin (_mm_add_ps (set, hpi));
_mm_store_ps (sines, _mm_shuffle_ps (s, s, _MM_SHUFFLE (0, 1, 2, 3)));
_mm_store_ps (cosines, _mm_shuffle_ps (c, c, _MM_SHUFFLE (0, 1, 2, 3)));
#else
sines[0] = cr::sinf (x);
sines[1] = cr::sinf (y);
sines[2] = cr::sinf (z);
cosines[0] = cr::cosf (x);
cosines[1] = cr::cosf (y);
cosines[2] = cr::cosf (z);
#endif
}
CR_NAMESPACE_END

64
ext/crlib/cr-movable.h Normal file
View file

@ -0,0 +1,64 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
CR_NAMESPACE_BEGIN
namespace detail {
template <typename T> struct ClearRef {
using Type = T;
};
template <typename T> struct ClearRef <T &> {
using Type = T;
};
template <typename T> struct ClearRef <T &&> {
using Type = T;
};
}
template <typename T> typename detail::ClearRef <T>::Type constexpr &&move (T &&type) noexcept {
return static_cast <typename detail::ClearRef <T>::Type &&> (type);
}
template <typename T> constexpr T &&forward (typename detail::ClearRef <T>::Type &type) noexcept {
return static_cast <T &&> (type);
}
template <typename T> constexpr T &&forward (typename detail::ClearRef <T>::Type &&type) noexcept {
return static_cast <T &&> (type);
}
template <typename T> inline void swap (T &left, T &right) noexcept {
auto temp = cr::move (left);
left = cr::move (right);
right = cr::move (temp);
}
template <typename T, size_t S> inline void swap (T (&left)[S], T (&right)[S]) noexcept {
if (&left == &right) {
return;
}
auto begin = left;
auto end = begin + S;
for (auto temp = right; begin != end; ++begin, ++temp) {
cr::swap (*begin, *temp);
}
}
CR_NAMESPACE_END

283
ext/crlib/cr-platform.h Normal file
View file

@ -0,0 +1,283 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
CR_NAMESPACE_BEGIN
// detects the build platform
#if defined(__linux__)
# define CR_LINUX
#elif defined(__APPLE__)
# define CR_OSX
#elif defined(_WIN32)
# define CR_WINDOWS
#endif
#if defined(__ANDROID__)
# define CR_ANDROID
# if defined(LOAD_HARDFP)
# define CR_ANDROID_HARD_FP
# endif
#endif
// detects the compiler
#if defined(_MSC_VER)
# define CR_CXX_MSVC _MSC_VER
#endif
#if defined(__clang__)
# define CR_CXX_CLANG __clang__
#endif
#if defined(__INTEL_COMPILER)
# define CR_CXX_INTEL __INTEL_COMPILER
#endif
#if defined(__GNUC__)
# define CR_CXX_GCC __GNUC__
#endif
// configure macroses
#define CR_LINKAGE_C extern "C"
#if defined(CR_WINDOWS)
# define CR_EXPORT CR_LINKAGE_C __declspec (dllexport)
# define CR_STDCALL __stdcall
#elif defined(CR_LINUX) || defined(CR_OSX)
# define CR_EXPORT CR_LINKAGE_C __attribute__((visibility("default")))
# define CR_STDCALL
#else
# error "Can't configure export macros. Compiler unrecognized."
#endif
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || (defined(_MSC_VER) && defined(_M_X64))
# define CR_ARCH_X64
#elif defined(__i686) || defined(__i686__) || defined(__i386) || defined(__i386__) || defined(i386) || (defined(_MSC_VER) && defined(_M_IX86))
# define CR_ARCH_X86
#endif
#if defined(__arm__)
# define CR_ARCH_ARM
# if defined(__aarch64__)
# define CR_ARCH_ARM64
# endif
#endif
#if (defined(CR_ARCH_X86) || defined(CR_ARCH_X64)) && !defined(CR_DEBUG)
# define CR_HAS_SSE
#endif
#if defined(CR_HAS_SSE)
# if defined (CR_CXX_MSVC)
# define CR_ALIGN16 __declspec (align (16))
# else
# define CR_ALIGN16 __attribute__((aligned(16)))
# endif
#endif
// disable warnings regarding intel compiler
#if defined(CR_CXX_INTEL)
# pragma warning (disable : 3280) // declaration hides member "XXX" (declared at line XX)
# pragma warning (disable : 2415) // variable "XXX" of static storage duration was declared but never referenced
# pragma warning (disable : 873) // function "operator new(size_t={unsigned int}, void *)" has no corresponding operator delete (to be called if an exception is thrown during initialization of an allocated object)
# pragma warning (disable : 383) // value copied to temporary, reference to temporary used
# pragma warning (disable : 11074 11075) // remarks about inlining bla-bla-bla
#endif
CR_NAMESPACE_END
#if defined(CR_WINDOWS)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <direct.h>
# if defined (max)
# undef max
# endif
# if defined (min)
# undef min
# endif
#else
# include <unistd.h>
# include <strings.h>
# include <sys/stat.h>
# include <sys/time.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <locale.h>
#include <string.h>
#include <stdarg.h>
#if defined (CR_ANDROID)
# include <android/log.h>
#endif
CR_NAMESPACE_BEGIN
// helper struct for platform detection
struct Platform : public Singleton <Platform> {
bool win32 = false;
bool linux = false;
bool osx = false;
bool android = false;
bool hfp = false;
bool x64 = false;
bool arm = false;
Platform () {
#if defined(CR_WINDOWS)
win32 = true;
#endif
#if defined(CR_ANDROID)
android = true;
# if defined (CR_ANDROID_HARD_FP)
hfp = true;
# endif
#endif
#if defined(CR_LINUX)
linux = true;
#endif
#if defined(CR_OSX)
osx = true;
#endif
#if defined(CR_ARCH_X64) || defined(CR_ARCH_ARM64)
x64 = true;
#endif
#if defined(CR_ARCH_ARM)
arm = true;
android = true;
#endif
}
// helper platform-dependant functions
template <typename U> bool checkPointer (U *ptr) {
#if defined(CR_WINDOWS)
if (IsBadCodePtr (reinterpret_cast <FARPROC> (ptr))) {
return false;
}
#else
(void) (ptr);
#endif
return true;
}
bool createDirectory (const char *dir) {
int result = 0;
#if defined(CR_WINDOWS)
result = _mkdir (dir);
#else
result = mkdir (dir, 0777);
#endif
return !!result;
}
bool removeFile (const char *dir) {
#if defined(CR_WINDOWS)
_unlink (dir);
#else
unlink (dir);
#endif
return true;
}
bool hasModule (const char *mod) {
#if defined(CR_WINDOWS)
return GetModuleHandleA (mod) != nullptr;
#else
(void) (mod);
return true;
#endif
}
float seconds () {
#if defined(CR_WINDOWS)
LARGE_INTEGER count, freq;
count.QuadPart = 0;
freq.QuadPart = 0;
QueryPerformanceFrequency (&freq);
QueryPerformanceCounter (&count);
return static_cast <float> (count.QuadPart) / static_cast <float> (freq.QuadPart);
#else
timeval tv;
gettimeofday (&tv, NULL);
return static_cast <float> (tv.tv_sec) + (static_cast <float> (tv.tv_usec)) / 1000000.0;
#endif
}
void abort (const char *msg = "OUT OF MEMORY!") noexcept {
fprintf (stderr, "%s\n", msg);
#if defined (CR_ANDROID)
__android_log_write (ANDROID_LOG_ERROR, "crlib.fatal", msg);
#endif
#if defined(CR_WINDOWS)
DestroyWindow (GetForegroundWindow ());
MessageBoxA (GetActiveWindow (), msg, "crlib.fatal", MB_ICONSTOP);
#endif
::abort ();
}
// anologue of memset
template <typename U> void bzero (U *ptr, size_t len) noexcept {
#if defined (CR_WINDOWS)
memset (ptr, 0, len);
#else
auto zeroing = reinterpret_cast <uint8 *> (ptr);
for (size_t i = 0; i < len; ++i) {
zeroing[i] = 0;
}
#endif
}
const char *env (const char *var) {
static char result[256];
bzero (result, sizeof (result));
#if defined(CR_WINDOWS) && !defined(CR_CXX_GCC)
char *buffer = nullptr;
size_t size = 0;
if (_dupenv_s (&buffer, &size, var) == 0 && buffer != nullptr) {
strncpy_s (result, buffer, sizeof (result));
free (buffer);
}
#else
strncpy (result, getenv (var), cr::bufsize (result));
#endif
return result;
}
};
// expose platform singleton
CR_EXPOSE_GLOBAL_SINGLETON (Platform, plat);
CR_NAMESPACE_END

72
ext/crlib/cr-random.h Normal file
View file

@ -0,0 +1,72 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <time.h>
#include <crlib/cr-basic.h>
CR_NAMESPACE_BEGIN
// random number generator see: https://github.com/preshing/RandomSequence/
class Random final : public Singleton <Random> {
private:
uint32 index_, offset_;
uint64 divider_;
public:
explicit Random () {
const auto base = static_cast <uint32> (time (nullptr));
const auto offset = base + 1;
index_ = premute (premute (base) + 0x682f0161);
offset_ = premute (premute (offset) + 0x46790905);
divider_ = (static_cast <uint64> (1)) << 32;
}
~Random () = default;
private:
uint32 premute (uint32 index) {
static constexpr auto prime = 4294967291u;
if (index >= prime) {
return index;
}
const uint32 residue = (static_cast <uint64> (index) * index) % prime;
return (index <= prime / 2) ? residue : prime - residue;
}
uint32 generate () {
return premute ((premute (index_++) + offset_) ^ 0x5bf03635);
}
public:
template <typename U> U int_ (U low, U high) {
return static_cast <U> (generate () * (static_cast <double> (high) - static_cast <double> (low) + 1.0) / divider_ + static_cast <double> (low));
}
float float_ (float low, float high) {
return static_cast <float> (generate () * (static_cast <double> (high) - static_cast <double> (low)) / (divider_ - 1) + static_cast <double> (low));
}
template <typename U> bool chance (const U max, const U maxChance = 100) {
return int_ <U> (0, maxChance) < max;
}
};
// expose global random generator
CR_EXPOSE_GLOBAL_SINGLETON (Random, rg);
CR_NAMESPACE_END

1133
ext/crlib/cr-string.h Normal file

File diff suppressed because it is too large Load diff

64
ext/crlib/cr-twin.h Normal file
View file

@ -0,0 +1,64 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#include <crlib/cr-movable.h>
CR_NAMESPACE_BEGIN
// simple pair (twin)
template <typename A, typename B> class Twin final {
public:
A first;
B second;
public:
template <typename T, typename U> Twin (T &&a, U &&b) : first (cr::forward <T> (a)), second (cr::forward <U> (b)) { }
template <typename T, typename U> Twin (const Twin <T, U> &rhs) : first (rhs.first), second (rhs.second) { }
template <typename T, typename U> Twin (Twin <T, U> &&rhs) noexcept : first (cr::move (rhs.first)), second (cr::move (rhs.second)) { }
public:
explicit Twin () = default;
~Twin () = default;
public:
template <typename T, typename U> Twin &operator = (const Twin <T, U> &rhs) {
first = rhs.first;
second = rhs.second;
return *this;
}
template <typename T, typename U> Twin &operator = (Twin <T, U> &&rhs) {
first = cr::move (rhs.first);
second = cr::move (rhs.second);
return *this;
}
// specialized operators for binary heap, do not use as it's test only second element
public:
friend bool operator < (const Twin &a, const Twin &b) {
return a.second < b.second;
}
friend bool operator > (const Twin &a, const Twin &b) {
return b.second < a.second;
}
};
CR_NAMESPACE_END

317
ext/crlib/cr-ulz.h Normal file
View file

@ -0,0 +1,317 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-array.h>
CR_NAMESPACE_BEGIN
// see https://github.com/encode84/ulz/
class ULZ final : DenyCopying {
public:
enum : int32 {
Excess = 16,
UncompressFailure = -1
};
private:
enum : int32 {
WindowBits = 17,
WindowSize = cr::bit (WindowBits),
WindowMask = WindowSize - 1,
MinMatch = 4,
MaxChain = cr::bit (5),
HashBits = 19,
HashLength = cr::bit (HashBits),
EmptyHash = -1,
};
private:
SmallArray <int32> hashTable_;
SmallArray <int32> prevTable_;
public:
explicit ULZ () {
hashTable_.resize (HashLength);
prevTable_.resize (WindowSize);
}
~ULZ () = default;
public:
int32 compress (uint8 *in, int32 inputLength, uint8 *out) {
for (auto &htb : hashTable_) {
htb = EmptyHash;
}
auto op = out;
int32 anchor = 0;
int32 cur = 0;
while (cur < inputLength) {
const int32 maxMatch = inputLength - cur;
int32 bestLength = 0;
int32 dist = 0;
if (maxMatch >= MinMatch) {
const int32 limit = cr::max <int32> (cur - WindowSize, EmptyHash);
int32 chainLength = MaxChain;
int32 lookup = hashTable_[hash32 (&in[cur])];
while (lookup > limit) {
if (in[lookup + bestLength] == in[cur + bestLength] && load <uint32> (&in[lookup]) == load <uint32> (&in[cur])) {
int32 length = MinMatch;
while (length < maxMatch && in[lookup + length] == in[cur + length]) {
++length;
}
if (length > bestLength) {
bestLength = length;
dist = cur - lookup;
if (length == maxMatch) {
break;
}
}
}
if (--chainLength == 0) {
break;
}
lookup = prevTable_[lookup & WindowMask];
}
}
if (bestLength == MinMatch && (cur - anchor) >= (7 + 128)) {
bestLength = 0;
}
if (bestLength >= MinMatch && bestLength < maxMatch && (cur - anchor) != 6) {
const auto next = cur + 1;
const auto target = bestLength + 1;
const auto limit = cr::max <int32> (next - WindowSize, EmptyHash);
int32 chainLength = MaxChain;
int32 lookup = hashTable_[hash32 (&in[next])];
while (lookup > limit) {
if (in[lookup + bestLength] == in[next + bestLength] && load <uint32> (&in[lookup]) == load <uint32> (&in[next])) {
int32 length = MinMatch;
while (length < target && in[lookup + length] == in[next + length]) {
++length;
}
if (length == target) {
bestLength = 0;
break;
}
}
if (--chainLength == 0) {
break;
}
lookup = prevTable_[lookup & WindowMask];
}
}
if (bestLength >= MinMatch) {
const auto length = bestLength - MinMatch;
const auto token = ((dist >> 12) & 16) + cr::min <int32> (length, 15);
if (anchor != cur) {
const auto run = cur - anchor;
if (run >= 7) {
add (op, (7 << 5) + token);
encode (op, run - 7);
}
else {
add (op, (run << 5) + token);
}
copy (op, &in[anchor], run);
op += run;
}
else {
add (op, token);
}
if (length >= 15) {
encode (op, length - 15);
}
store16 (op, static_cast <uint16> (dist));
op += 2;
while (bestLength-- != 0) {
const auto hash = hash32 (&in[cur]);
prevTable_[cur & WindowMask] = hashTable_[hash];
hashTable_[hash] = cur++;
}
anchor = cur;
}
else {
const auto hash = hash32 (&in[cur]);
prevTable_[cur & WindowMask] = hashTable_[hash];
hashTable_[hash] = cur++;
}
}
if (anchor != cur) {
const auto run = cur - anchor;
if (run >= 7) {
add (op, 7 << 5);
encode (op, run - 7);
}
else {
add (op, run << 5);
}
copy (op, &in[anchor], run);
op += run;
}
return static_cast <int32> (op - out);
}
int32 uncompress (uint8 *in, int32 inputLength, uint8 *out, int32 outLength) {
auto op = out;
auto ip = in;
const auto opEnd = op + outLength;
const auto ipEnd = ip + inputLength;
while (ip < ipEnd) {
const auto token = *ip++;
if (token >= 32) {
auto run = token >> 5;
if (run == 7) {
run += decode (ip);
}
if ((opEnd - op) < run || (ipEnd - ip) < run) {
return UncompressFailure;
}
copy (op, ip, run);
op += run;
ip += run;
if (ip >= ipEnd) {
break;
}
}
auto length = (token & 15) + MinMatch;
if (length == (15 + MinMatch)) {
length += decode (ip);
}
if ((opEnd - op) < length) {
return UncompressFailure;
}
const auto dist = ((token & 16) << 12) + load <uint16> (ip);
ip += 2;
auto cp = op - dist;
if ((op - out) < dist) {
return UncompressFailure;
}
if (dist >= 8) {
copy (op, cp, length);
op += length;
}
else {
for (int32 i = 0; i < 4; ++i) {
*op++ = *cp++;
}
while (length-- != 4) {
*op++ = *cp++;
}
}
}
return static_cast <int32> (ip == ipEnd) ? static_cast <int32> (op - out) : UncompressFailure;
}
private:
template <typename U> U load (void *ptr) {
U ret;
memcpy (&ret, ptr, sizeof (U));
return ret;
}
void store16 (void *ptr, uint16 val) {
memcpy (ptr, &val, sizeof (uint16));
}
void copy64 (void *dst, void *src) {
memcpy (dst, src, sizeof (uint64));
}
uint32 hash32 (void *ptr) {
return (load <uint32> (ptr) * 0x9e3779b9) >> (32 - HashBits);
}
void copy (uint8 *dst, uint8 *src, int32 count) {
copy64 (dst, src);
for (int32 i = 8; i < count; i += 8) {
copy64 (dst + i, src + i);
}
}
void add (uint8 *&dst, int32 val) {
*dst++ = static_cast <uint8> (val);
}
void encode (uint8 *&ptr, uint32 val) {
while (val >= 128) {
val -= 128;
*ptr++ = 128 + (val & 127);
val >>= 7;
}
*ptr++ = static_cast <uint8> (val);
}
uint32 decode (uint8 *&ptr) {
uint32 val = 0;
for (int32 i = 0; i <= 21; i += 7) {
const uint32 cur = *ptr++;
val += cur << i;
if (cur < 128) {
break;
}
}
return val;
}
};
CR_NAMESPACE_END

212
ext/crlib/cr-uniqueptr.h Normal file
View file

@ -0,0 +1,212 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-basic.h>
#include <crlib/cr-alloc.h>
#include <crlib/cr-movable.h>
CR_NAMESPACE_BEGIN
// simple unique ptr
template <typename T> class UniquePtr final : public DenyCopying {
private:
T *ptr_ {};
public:
UniquePtr () = default;
explicit UniquePtr (T *ptr) : ptr_ (ptr)
{ }
UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ())
{ }
template <typename U> UniquePtr (UniquePtr <U> &&rhs) noexcept : ptr_ (rhs.release ())
{ }
~UniquePtr () {
destroy ();
}
public:
T *get () const {
return ptr_;
}
T *release () {
auto ret = ptr_;
ptr_ = nullptr;
return ret;
}
void reset (T *ptr = nullptr) {
destroy ();
ptr_ = ptr;
}
private:
void destroy () {
alloc.destroy (ptr_);
ptr_ = nullptr;
}
public:
UniquePtr &operator = (UniquePtr &&rhs) noexcept {
if (this != &rhs) {
reset (rhs.release ());
}
return *this;
}
template <typename U> UniquePtr &operator = (UniquePtr <U> &&rhs) noexcept {
if (this != &rhs) {
reset (rhs.release ());
}
return *this;
}
UniquePtr &operator = (decltype (nullptr)) {
destroy ();
return *this;
}
T &operator * () const {
return *ptr_;
}
T *operator -> () const {
return ptr_;
}
explicit operator bool () const {
return ptr_ != nullptr;
}
};
template <typename T> class UniquePtr <T[]> final : public DenyCopying {
private:
T *ptr_ { };
public:
UniquePtr () = default;
explicit UniquePtr (T *ptr) : ptr_ (ptr)
{ }
UniquePtr (UniquePtr &&rhs) noexcept : ptr_ (rhs.release ())
{ }
template <typename U> UniquePtr (UniquePtr <U> &&rhs) noexcept : ptr_ (rhs.release ())
{ }
~UniquePtr () {
destroy ();
}
public:
T *get () const {
return ptr_;
}
T *release () {
auto ret = ptr_;
ptr_ = nullptr;
return ret;
}
void reset (T *ptr = nullptr) {
destroy ();
ptr_ = ptr;
}
private:
void destroy () {
alloc.destroy (ptr_);
ptr_ = nullptr;
}
public:
UniquePtr &operator = (UniquePtr &&rhs) noexcept {
if (this != &rhs) {
reset (rhs.release ());
}
return *this;
}
template <typename U> UniquePtr &operator = (UniquePtr <U> &&rhs) noexcept {
if (this != &rhs) {
reset (rhs.release ());
}
return *this;
}
UniquePtr &operator = (decltype (nullptr)) {
destroy ();
return *this;
}
T &operator [] (size_t index) {
return ptr_[index];
}
const T &operator [] (size_t index) const {
return ptr_[index];
}
explicit operator bool () const {
return ptr_ != nullptr;
}
};
namespace detail {
template <typename T> struct ClearExtent {
using Type = T;
};
template <typename T> struct ClearExtent <T[]> {
using Type = T;
};
template <typename T, size_t N> struct ClearExtent <T[N]> {
using Type = T;
};
template <typename T> struct UniqueIf {
using SingleObject = UniquePtr <T>;
};
template <typename T> struct UniqueIf<T[]> {
using UnknownBound = UniquePtr <T[]>;
};
template <typename T, size_t N> struct UniqueIf <T[N]> {
using KnownBound = void;
};
}
template <typename T, typename... Args> typename detail::UniqueIf <T>::SingleObject makeUnique (Args &&... args) {
return UniquePtr <T> (alloc.create <T> (cr::forward <Args> (args)...));
}
template <typename T> typename detail::UniqueIf <T>::UnknownBound makeUnique (size_t size) {
return UniquePtr <T> (alloc.createArray <typename detail::ClearExtent <T>::Type> (size));
}
template <typename T, typename... Args> typename detail::UniqueIf <T>::KnownBound makeUnique (Args &&...) = delete;
CR_NAMESPACE_END

335
ext/crlib/cr-vector.h Normal file
View file

@ -0,0 +1,335 @@
//
// CRLib - Simple library for STL replacement in private projects.
// Copyright © 2020 YaPB Development Team <team@yapb.ru>.
//
// 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.
//
#pragma once
#include <crlib/cr-math.h>
CR_NAMESPACE_BEGIN
// small simd operations for 3d vector
#if defined (CR_HAS_SSE)
template <typename T> class CR_ALIGN16 SimdWrap {
private:
__m128 wrap_dp_sse2 (__m128 v1, __m128 v2) {
auto mul = _mm_mul_ps (v1, v2);
auto res = _mm_add_ps (_mm_shuffle_ps (v2, mul, _MM_SHUFFLE (1, 0, 0, 0)), mul);
mul = _mm_add_ps (_mm_shuffle_ps (mul, res, _MM_SHUFFLE (0, 3, 0, 0)), res);
return _mm_shuffle_ps (mul, mul, _MM_SHUFFLE (2, 2, 2, 2));
}
public:
union {
__m128 m;
struct {
T x, y, z;
} vec;
};
SimdWrap (const T &x, const T &y, const T &z) {
m = _mm_set_ps (0.0f, z, y, x);
}
SimdWrap (const T &x, const T &y) {
m = _mm_set_ps (0.0f, 0.0f, y, x);
}
SimdWrap (__m128 m) : m (m)
{ }
public:
SimdWrap normalize () {
return { _mm_div_ps (m, _mm_sqrt_ps (wrap_dp_sse2 (m, m))) };
}
};
#endif
// 3dmath vector
template <typename T> class Vec3D {
public:
T x {};
T y {};
T z {};
public:
Vec3D (const T &scaler = 0.0f) : x (scaler), y (scaler), z (scaler)
{ }
Vec3D (const T &x, const T &y, const T &z) : x (x), y (y), z (z)
{ }
Vec3D (T *rhs) : x (rhs[0]), y (rhs[1]), z (rhs[2])
{ }
#if defined (CR_HAS_SSE)
Vec3D (const SimdWrap <T> &rhs) : x (rhs.vec.x), y (rhs.vec.y), z (rhs.vec.z)
{ }
#endif
Vec3D (const Vec3D &) = default;
Vec3D (decltype (nullptr)) {
clear ();
}
public:
operator T * () {
return &x;
}
operator const T * () const {
return &x;
}
Vec3D operator + (const Vec3D &rhs) const {
return { x + rhs.x, y + rhs.y, z + rhs.z };
}
Vec3D operator - (const Vec3D &rhs) const {
return { x - rhs.x, y - rhs.y, z - rhs.z };
}
Vec3D operator - () const {
return { -x, -y, -z };
}
friend Vec3D operator * (const T &scale, const Vec3D &rhs) {
return { rhs.x * scale, rhs.y * scale, rhs.z * scale };
}
Vec3D operator * (const T &scale) const {
return { scale * x, scale * y, scale * z };
}
Vec3D operator / (const T &rhs) const {
const auto inv = 1 / (rhs + kFloatEqualEpsilon);
return { inv * x, inv * y, inv * z };
}
// cross product
Vec3D operator ^ (const Vec3D &rhs) const {
return { y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x };
}
// dot product
T operator | (const Vec3D &rhs) const {
return x * rhs.x + y * rhs.y + z * rhs.z;
}
const Vec3D &operator += (const Vec3D &rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
const Vec3D &operator -= (const Vec3D &rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
const Vec3D &operator *= (const T &rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
const Vec3D &operator /= (const T &rhs) {
const auto inv = 1 / (rhs + kFloatEqualEpsilon);
x *= inv;
y *= inv;
z *= inv;
return *this;
}
bool operator == (const Vec3D &rhs) const {
return cr::fequal (x, rhs.x) && cr::fequal (y, rhs.y) && cr::fequal (z, rhs.z);
}
bool operator != (const Vec3D &rhs) const {
return !operator == (rhs);
}
void operator = (decltype (nullptr)) {
clear ();
}
const float &operator [] (const int i) const {
return &(x)[i];
}
float &operator [] (const int i) {
return &(x)[i];
}
Vec3D &operator = (const Vec3D &) = default;
public:
T length () const {
return cr::sqrtf (lengthSq ());
}
T length2d () const {
return cr::sqrtf (cr::square (x) + cr::square (y));
}
T lengthSq () const {
return cr::square (x) + cr::square (y) + cr::square (z);
}
Vec3D get2d () const {
return { x, y, 0.0f };
}
Vec3D normalize () const {
#if defined (CR_HAS_SSE)
return SimdWrap <T> { x, y, z }.normalize ();
#else
auto len = length () + cr::kFloatCmpEpsilon;
if (cr::fzero (len)) {
return { 0.0f, 0.0f, 1.0f };
}
len = 1.0f / len;
return { x * len, y * len, z * len };
#endif
}
Vec3D normalize2d () const {
#if defined (CR_HAS_SSE)
return SimdWrap <T> { x, y }.normalize ();
#else
auto len = length2d () + cr::kFloatCmpEpsilon;
if (cr::fzero (len)) {
return { 0.0f, 1.0f, 0.0f };
}
len = 1.0f / len;
return { x * len, y * len, 0.0f };
#endif
}
bool empty () const {
return cr::fzero (x) && cr::fzero (y) && cr::fzero (z);
}
void clear () {
x = y = z = 0.0f;
}
Vec3D clampAngles () {
x = cr::normalizeAngles (x);
y = cr::normalizeAngles (y);
z = 0.0f;
return *this;
}
T pitch () const {
if (cr::fzero (z)) {
return 0.0f;
}
return cr::deg2rad (cr::atan2f (z, length2d ()));
}
T yaw () const {
if (cr::fzero (x) && cr::fzero (y)) {
return 0.0f;
}
return cr::rad2deg (cr:: atan2f (y, x));
}
Vec3D angles () const {
if (cr::fzero (x) && cr::fzero (y)) {
return { z > 0.0f ? 90.0f : 270.0f, 0.0, 0.0f };
}
return { cr::rad2deg (cr::atan2f (z, length2d ())), cr::rad2deg (cr::atan2f (y, x)), 0.0f };
}
void angleVectors (Vec3D *forward, Vec3D *right, Vec3D *upward) const {
enum { pitch, yaw, roll, unused, max };
T sines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
T cosines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
// compute the sine and cosine compontents
cr::sincosf (cr::deg2rad (x), cr::deg2rad (y), cr::deg2rad (z), sines, cosines);
if (forward) {
*forward = {
cosines[pitch] * cosines[yaw],
cosines[pitch] * sines[yaw],
-sines[pitch]
};
}
if (right) {
*right = {
-sines[roll] * sines[pitch] * cosines[yaw] + cosines[roll] * sines[yaw],
-sines[roll] * sines[pitch] * sines[yaw] - cosines[roll] * cosines[yaw],
-sines[roll] * cosines[pitch]
};
}
if (upward) {
*upward = {
cosines[roll] * sines[pitch] * cosines[yaw] + sines[roll] * sines[yaw],
upward->y = cosines[roll] * sines[pitch] * sines[yaw] - sines[roll] * cosines[yaw],
upward->z = cosines[roll] * cosines[pitch]
};
}
}
const Vec3D &forward () {
static Vec3D s_fwd {};
angleVectors (&s_fwd, nullptr, nullptr);
return s_fwd;
}
const Vec3D &upward () {
static Vec3D s_up {};
angleVectors (nullptr, nullptr, &s_up);
return s_up;
}
const Vec3D &right () {
static Vec3D s_right {};
angleVectors (nullptr, &s_right, nullptr);
return s_right;
}
};
// default is float
using Vector = Vec3D <float>;
CR_NAMESPACE_END

881
ext/hlsdk/const.h Normal file
View file

@ -0,0 +1,881 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef CONST_H
#define CONST_H
//
// Constants shared by the engine and dlls
// This header file included by engine files and DLL files.
// Most came from server.h
#define INTERFACE_VERSION 140
// Dot products for view cone checking
#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
#define FCVAR_ARCHIVE (1 << 0) // set to cause it to be saved to vars.rc
#define FCVAR_USERINFO (1 << 1) // changes the client's info string
#define FCVAR_SERVER (1 << 2) // notifies players when changed
#define FCVAR_EXTDLL (1 << 3) // defined by external DLL
#define FCVAR_CLIENTDLL (1 << 4) // defined by the client dll
#define FCVAR_PROTECTED (1 << 5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
#define FCVAR_SPONLY (1 << 6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1 << 7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1 << 8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
// edict->flags
#define FL_FLY (1 << 0) // Changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1 << 1) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define FL_CONVEYOR (1 << 2)
#define FL_CLIENT (1 << 3)
#define FL_INWATER (1 << 4)
#define FL_MONSTER (1 << 5)
#define FL_GODMODE (1 << 6)
#define FL_NOTARGET (1 << 7)
#define FL_SKIPLOCALHOST (1 << 8) // Don't send entity to local host, it's predicting this entity itself
#define FL_ONGROUND (1 << 9) // At rest / on the ground
#define FL_PARTIALGROUND (1 << 10) // not all corners are valid
#define FL_WATERJUMP (1 << 11) // player jumping out of water
#define FL_FROZEN (1 << 12) // Player is frozen for 3rd person camera
#define FL_FAKECLIENT (1 << 13) // JAC: fake client, simulated server side; don't send network messages to them
#define FL_DUCKING (1 << 14) // Player flag -- Player is fully crouched
#define FL_FLOAT (1 << 15) // Apply floating force to this entity when in water
#define FL_GRAPHED (1 << 16) // worldgraph has this ent listed as something that blocks a connection
// UNDONE: Do we need these?
#define FL_IMMUNE_WATER (1 << 17)
#define FL_IMMUNE_SLIME (1 << 18)
#define FL_IMMUNE_LAVA (1 << 19)
#define FL_PROXY (1 << 20) // This is a spectator proxy
#define FL_ALWAYSTHINK (1 << 21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path)
#define FL_BASEVELOCITY (1 << 22) // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_MONSTERCLIP (1 << 23) // Only collide in with monsters who have FL_MONSTERCLIP set
#define FL_ONTRAIN (1 << 24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_WORLDBRUSH (1 << 25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_SPECTATOR (1 << 26) // This client is a spectator, don't run touch functions, etc.
#define FL_CUSTOMENTITY (1 << 29) // This is a custom entity
#define FL_KILLME (1 << 30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time
#define FL_DORMANT (1 << 31) // Entity is dormant, no updates to client
// Goes into globalvars_t.trace_flags
#define FTRACE_SIMPLEBOX (1 << 0) // Traceline with a simple box
// walkmove modes
#define WALKMOVE_NORMAL 0 // normal walkmove
#define WALKMOVE_WORLDONLY 1 // doesn't hit ANY entities, no matter what the solid type
#define WALKMOVE_CHECKONLY 2 // move, but don't touch triggers
// edict->movetype values
#define MOVETYPE_NONE 0 // never moves
#define MOVETYPE_WALK 3 // Player only - moving on the ground
#define MOVETYPE_STEP 4 // gravity, special edge handling -- monsters use this
#define MOVETYPE_FLY 5 // No gravity, but still collides with stuff
#define MOVETYPE_TOSS 6 // gravity/collisions
#define MOVETYPE_PUSH 7 // no clip to world, push and crush
#define MOVETYPE_NOCLIP 8 // No gravity, no collisions, still do velocity/avelocity
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
#define MOVETYPE_BOUNCE 10 // Just like Toss, but reflect velocity when contacting surfaces
#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity
#define MOVETYPE_FOLLOW 12 // track movement of aiment
#define MOVETYPE_PUSHSTEP 13 // BSP model that needs physics/world collisions (uses nearest hull for world collision)
// edict->solid values
// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves
// SOLID only effects OTHER entities colliding with this one when they move - UGH!
#define SOLID_NOT 0 // no interaction with other objects
#define SOLID_TRIGGER 1 // touch on edge, but not blocking
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
// edict->deadflag values
#define DEAD_NO 0 // alive
#define DEAD_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground
#define DEAD_DEAD 2 // dead. lying still.
#define DEAD_RESPAWNABLE 3
#define DEAD_DISCARDBODY 4
#define DAMAGE_NO 0
#define DAMAGE_YES 1
#define DAMAGE_AIM 2
// entity effects
#define EF_BRIGHTFIELD 1 // swirling cloud of particles
#define EF_MUZZLEFLASH 2 // single frame ELIGHT on entity attachment 0
#define EF_BRIGHTLIGHT 4 // DLIGHT centered at entity origin
#define EF_DIMLIGHT 8 // player flashlight
#define EF_INVLIGHT 16 // get lighting from ceiling
#define EF_NOINTERP 32 // don't interpolate the next frame
#define EF_LIGHT 64 // rocket flare glow sprite
#define EF_NODRAW 128 // don't draw entity
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
//
// temp entity events
//
#define TE_BEAMPOINTS 0 // beam effect between two points
// coord coord coord (start position)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMENTPOINT 1 // beam effect between point and entity
// short (start entity)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_GUNSHOT 2 // particle effect plus ricochet sound
// coord coord coord (position)
#define TE_EXPLOSION 3 // additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
// byte (flags)
//
// The Explosion effect has some flags to control performance/aesthetic features:
#define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
#define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
#define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
#define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
#define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
#define TE_TAREXPLOSION 4 // Quake1 "tarbaby" explosion with sound
// coord coord coord (position)
#define TE_SMOKE 5 // alphablend sprite, move vertically 30 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
#define TE_TRACER 6 // tracer effect from point to point
// coord, coord, coord (start)
// coord, coord, coord (end)
#define TE_LIGHTNING 7 // TE_BEAMPOINTS with simplified parameters
// coord, coord, coord (start)
// coord, coord, coord (end)
// byte (life in 0.1's)
// byte (width in 0.1's)
// byte (amplitude in 0.01's)
// short (sprite model index)
#define TE_BEAMENTS 8
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_SPARKS 9 // 8 random tracers with gravity, ricochet sprite
// coord coord coord (position)
#define TE_LAVASPLASH 10 // Quake1 lava splash
// coord coord coord (position)
#define TE_TELEPORT 11 // Quake1 teleport splash
// coord coord coord (position)
#define TE_EXPLOSION2 12 // Quake1 colormaped (base palette) particle explosion with sound
// coord coord coord (position)
// byte (starting color)
// byte (num colors)
#define TE_BSPDECAL 13 // Decal from the .BSP file
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// short (texture index of precached decal texture name)
// short (entity index)
// [optional - only included if previous short is non-zero (not the world)] short (index of model of above entity)
#define TE_IMPLOSION 14 // tracers moving toward a point
// coord, coord, coord (position)
// byte (radius)
// byte (count)
// byte (life in 0.1's)
#define TE_SPRITETRAIL 15 // line of moving glow sprites with gravity, fadeout, and collisions
// coord, coord, coord (start)
// coord, coord, coord (end)
// short (sprite index)
// byte (count)
// byte (life in 0.1's)
// byte (scale in 0.1's)
// byte (velocity along Vector in 10's)
// byte (randomness of velocity in 10's)
#define TE_BEAM 16 // obsolete
#define TE_SPRITE 17 // additive sprite, plays 1 cycle
// coord, coord, coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (brightness)
#define TE_BEAMSPRITE 18 // A beam with a sprite at the end
// coord, coord, coord (start position)
// coord, coord, coord (end position)
// short (beam sprite index)
// short (end sprite index)
#define TE_BEAMTORUS 19 // screen aligned beam ring, expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMDISK 20 // disk that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMCYLINDER 21 // cylinder that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMFOLLOW 22 // create a line of decaying beam segments until entity stops moving
// short (entity:attachment to follow)
// short (sprite index)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte,byte,byte (color)
// byte (brightness)
#define TE_GLOWSPRITE 23
// coord, coord, coord (pos) short (model index) byte (scale / 10)
#define TE_BEAMRING 24 // connect a beam ring to two entities
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_STREAK_SPLASH 25 // oriented shower of tracers
// coord coord coord (start position)
// coord coord coord (direction Vector)
// byte (color)
// short (count)
// short (base speed)
// short (ramdon velocity)
#define TE_BEAMHOSE 26 // obsolete
#define TE_DLIGHT 27 // dynamic light, effect world, minor entity effect
// coord, coord, coord (pos)
// byte (radius in 10's)
// byte byte byte (color)
// byte (brightness)
// byte (life in 10's)
// byte (decay rate in 10's)
#define TE_ELIGHT 28 // point entity light, no world effect
// short (entity:attachment to follow)
// coord coord coord (initial position)
// coord (radius)
// byte byte byte (color)
// byte (life in 0.1's)
// coord (decay rate)
#define TE_TEXTMESSAGE 29
// short 1.2.13 x (-1 = center)
// short 1.2.13 y (-1 = center)
// byte Effect 0 = fade in/fade out
// 1 is flickery credits
// 2 is write out (training room)
// 4 bytes r,g,b,a color1 (text color)
// 4 bytes r,g,b,a color2 (effect color)
// ushort 8.8 fadein time
// ushort 8.8 fadeout time
// ushort 8.8 hold time
// optional ushort 8.8 fxtime (time the highlight lags behing the leading text in effect 2)
// string text message (512 chars max sz string)
#define TE_LINE 30
// coord, coord, coord startpos
// coord, coord, coord endpos
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_BOX 31
// coord, coord, coord boxmins
// coord, coord, coord boxmaxs
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_KILLBEAM 99 // kill all beams attached to entity
// short (entity)
#define TE_LARGEFUNNEL 100
// coord coord coord (funnel position)
// short (sprite index)
// short (flags)
#define TE_BLOODSTREAM 101 // particle spray
// coord coord coord (start position)
// coord coord coord (spray Vector)
// byte (color)
// byte (speed)
#define TE_SHOWLINE 102 // line of particles every 5 units, dies in 30 seconds
// coord coord coord (start position)
// coord coord coord (end position)
#define TE_BLOOD 103 // particle spray
// coord coord coord (start position)
// coord coord coord (spray Vector)
// byte (color)
// byte (speed)
#define TE_DECAL 104 // Decal applied to a brush entity (not the world)
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
// short (entity index)
#define TE_FIZZ 105 // create alpha sprites inside of entity, float upwards
// short (entity)
// short (sprite index)
// byte (density)
#define TE_MODEL 106 // create a moving model that bounces and makes a sound when it hits
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// angle (initial yaw)
// short (model index)
// byte (bounce sound type)
// byte (life in 0.1's)
#define TE_EXPLODEMODEL 107 // spherical shower of models, picks from set
// coord, coord, coord (origin)
// coord (velocity)
// short (model index)
// short (count)
// byte (life in 0.1's)
#define TE_BREAKMODEL 108 // box of models or sprites
// coord, coord, coord (position)
// coord, coord, coord (size)
// coord, coord, coord (velocity)
// byte (random velocity in 10's)
// short (sprite or model index)
// byte (count)
// byte (life in 0.1 secs)
// byte (flags)
#define TE_GUNSHOTDECAL 109 // decal and ricochet sound
// coord, coord, coord (position)
// short (entity index???)
// byte (decal???)
#define TE_SPRITE_SPRAY 110 // spay of alpha sprites
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (sprite index)
// byte (count)
// byte (speed)
// byte (noise)
#define TE_ARMOR_RICOCHET 111 // quick spark sprite, client ricochet sound.
// coord, coord, coord (position)
// byte (scale in 0.1's)
#define TE_PLAYERDECAL 112 // ???
// byte (playerindex)
// coord, coord, coord (position)
// short (entity???)
// byte (decal number???)
// [optional] short (model index???)
#define TE_BUBBLES 113 // create alpha sprites inside of box, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BUBBLETRAIL 114 // create alpha sprites along a line, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BLOODSPRITE 115 // spray of opaque sprite1's that fall, single sprite2 for 1..2 secs (this is a high-priority tent)
// coord, coord, coord (position)
// short (sprite1 index)
// short (sprite2 index)
// byte (color)
// byte (scale)
#define TE_WORLDDECAL 116 // Decal applied to the world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
#define TE_WORLDDECALHIGH 117 // Decal (with texture index > 256) applied to world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
#define TE_DECALHIGH 118 // Same as TE_DECAL, but the texture index was greater than 256
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
// short (entity index)
#define TE_PROJECTILE 119 // Makes a projectile (like a nail) (this is a high-priority tent)
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (modelindex)
// byte (life)
// byte (owner) projectile won't collide with owner (if owner == 0, projectile will hit any client).
#define TE_SPRAY 120 // Throws a shower of sprites or models
// coord, coord, coord (position)
// coord, coord, coord (direction)
// short (modelindex)
// byte (count)
// byte (speed)
// byte (noise)
// byte (rendermode)
#define TE_PLAYERSPRITES 121 // sprites emit from a player's bounding box (ONLY use for players!)
// byte (playernum)
// short (sprite modelindex)
// byte (count)
// byte (variance) (0 = no variance in size) (10 = 10% variance in size)
#define TE_PARTICLEBURST 122 // very similar to lavasplash.
// coord (origin)
// short (radius)
// byte (particle color)
// byte (duration * 10) (will be randomized a bit)
#define TE_FIREFIELD 123 // makes a field of fire.
// coord (origin)
// short (radius) (fire is made in a square around origin. -radius, -radius to radius, radius)
// short (modelindex)
// byte (count)
// byte (flags)
// byte (duration (in seconds) * 10) (will be randomized a bit)
//
// to keep network traffic low, this message has associated flags that fit into a byte:
#define TEFIRE_FLAG_ALLFLOAT 1 // all sprites will drift upwards as they animate
#define TEFIRE_FLAG_SOMEFLOAT 2 // some of the sprites will drift upwards. (50% chance)
#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration.
#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque
#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube.
#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
// byte (entity index of player)
// coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset )
// short (model index)
// short (life * 10 );
#define TE_KILLPLAYERATTACHMENTS 125 // will expire all TENTS attached to a player.
// byte (entity index of player)
#define TE_MULTIGUNSHOT 126 // much more compact shotgun message
// This message is used to make a client approximate a 'spray' of gunfire.
// Any weapon that fires more than one bullet per frame and fires in a bit of a spread is
// a good candidate for MULTIGUNSHOT use. (shotguns)
//
// NOTE: This effect makes the client do traces for each bullet, these client traces ignore
// entities that have studio models.Traces are 4096 long.
//
// coord (origin)
// coord (origin)
// coord (origin)
// coord (direction)
// coord (direction)
// coord (direction)
// coord (x noise * 100)
// coord (y noise * 100)
// byte (count)
// byte (bullethole decal texture index)
#define TE_USERTRACER 127 // larger message than the standard tracer, but allows some customization.
// coord (origin)
// coord (origin)
// coord (origin)
// coord (velocity)
// coord (velocity)
// coord (velocity)
// byte ( life * 10 )
// byte ( color ) this is an index into an array of color vectors in the engine. (0 - )
// byte ( length * 10 )
#define MSG_BROADCAST 0 // unreliable to all
#define MSG_ONE 1 // reliable to one (msg_entity)
#define MSG_ALL 2 // reliable to all
#define MSG_INIT 3 // write to the init string
#define MSG_PVS 4 // Ents in PVS of org
#define MSG_PAS 5 // Ents in PAS of org
#define MSG_PVS_R 6 // Reliable to PVS
#define MSG_PAS_R 7 // Reliable to PAS
#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram ( could be dropped )
#define MSG_SPEC 9 // Sends to all spectator proxies
// contents of a spot in the world
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
#define CONTENTS_SLIME -4
#define CONTENTS_LAVA -5
#define CONTENTS_SKY -6
#define CONTENTS_LADDER -16
#define CONTENT_FLYFIELD -17
#define CONTENT_GRAVITY_FLYFIELD -18
#define CONTENT_FOG -19
#define CONTENT_EMPTY -1
#define CONTENT_SOLID -2
#define CONTENT_WATER -3
#define CONTENT_SLIME -4
#define CONTENT_LAVA -5
#define CONTENT_SKY -6
// channels
#define CHAN_AUTO 0
#define CHAN_WEAPON 1
#define CHAN_VOICE 2
#define CHAN_ITEM 3
#define CHAN_BODY 4
#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area
#define CHAN_STATIC 6 // allocate channel from the static area
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network
#define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END).
// attenuation values
#define ATTN_NONE 0.0f
#define ATTN_NORM 0.8f
#define ATTN_IDLE 2f
#define ATTN_STATIC 1.25f
// pitch values
#define PITCH_NORM 100 // non-pitch shifted
#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high
#define PITCH_HIGH 120
// volume values
#define VOL_NORM 1.0
// plats
#define PLAT_LOW_TRIGGER 1
// Trains
#define SF_TRAIN_WAIT_RETRIGGER 1
#define SF_TRAIN_START_ON 4 // Train is initially moving
#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains
// buttons
#define IN_ATTACK (1 << 0)
#define IN_JUMP (1 << 1)
#define IN_DUCK (1 << 2)
#define IN_FORWARD (1 << 3)
#define IN_BACK (1 << 4)
#define IN_USE (1 << 5)
#define IN_CANCEL (1 << 6)
#define IN_LEFT (1 << 7)
#define IN_RIGHT (1 << 8)
#define IN_MOVELEFT (1 << 9)
#define IN_MOVERIGHT (1 << 10)
#define IN_ATTACK2 (1 << 11)
#define IN_RUN (1 << 12)
#define IN_RELOAD (1 << 13)
#define IN_ALT1 (1 << 14)
#define IN_SCORE (1 << 15)
// Break Model Defines
#define BREAK_TYPEMASK 0x4F
#define BREAK_GLASS 0x01
#define BREAK_METAL 0x02
#define BREAK_FLESH 0x04
#define BREAK_WOOD 0x08
#define BREAK_SMOKE 0x10
#define BREAK_TRANS 0x20
#define BREAK_CONCRETE 0x40
#define BREAK_2 0x80
// Colliding temp entity sounds
#define BOUNCE_GLASS BREAK_GLASS
#define BOUNCE_METAL BREAK_METAL
#define BOUNCE_FLESH BREAK_FLESH
#define BOUNCE_WOOD BREAK_WOOD
#define BOUNCE_SHRAP 0x10
#define BOUNCE_SHELL 0x20
#define BOUNCE_CONCRETE BREAK_CONCRETE
#define BOUNCE_SHOTSHELL 0x80
// Temp entity bounce sound types
#define TE_BOUNCE_NULL 0
#define TE_BOUNCE_SHELL 1
#define TE_BOUNCE_SHOTSHELL 2
#define MAX_ENT_LEAFS 48
#define MAX_WEAPON_SLOTS 5 // hud item selection slots
#define MAX_ITEM_TYPES 6 // hud item selection slots
#define MAX_ITEMS 5 // hard coded item types
#define HIDEHUD_WEAPONS (1 << 0)
#define HIDEHUD_FLASHLIGHT (1 << 1)
#define HIDEHUD_ALL (1 << 2)
#define HIDEHUD_HEALTH (1 << 3)
#define MAX_AMMO_TYPES 32 // ???
#define MAX_AMMO_SLOTS 32 // not really slots
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define WEAPON_SUIT 31
#define VERTEXSIZE 7
#define MAXLIGHTMAPS 4
#define NUM_AMBIENTS 4
#define MAX_MAP_HULLS 4
#define MAX_PHYSINFO_STRING 256
#define MAX_PHYSENTS 600
#define MAX_MOVEENTS 64
#define MAX_LIGHTSTYLES 64
#define MAX_LIGHTSTYLEVALUE 256
#define SURF_DRAWTILED 0x20
#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation
#define AMBIENT_SOUND_EVERYWHERE 1
#define AMBIENT_SOUND_SMALLRADIUS 2
#define AMBIENT_SOUND_MEDIUMRADIUS 4
#define AMBIENT_SOUND_LARGERADIUS 8
#define AMBIENT_SOUND_START_SILENT 16
#define AMBIENT_SOUND_NOT_LOOPING 32
#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements
#define SND_SPAWNING (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients
#define SND_STOP (1 << 5) // duplicated in protocol.h stop sound
#define SND_CHANGE_VOL (1 << 6) // duplicated in protocol.h change sound vol
#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch
#define LFO_SQUARE 1
#define LFO_TRIANGLE 2
#define LFO_RANDOM 3
// func_rotating
#define SF_BRUSH_ROTATE_Y_AXIS 0
#define SF_BRUSH_ROTATE_INSTANT 1
#define SF_BRUSH_ROTATE_BACKWARDS 2
#define SF_BRUSH_ROTATE_Z_AXIS 4
#define SF_BRUSH_ROTATE_X_AXIS 8
#define SF_PENDULUM_AUTO_RETURN 16
#define SF_PENDULUM_PASSABLE 32
#define SF_BRUSH_ROTATE_SMALLRADIUS 128
#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256
#define SF_BRUSH_ROTATE_LARGERADIUS 512
#define PUSH_BLOCK_ONLY_X 1
#define PUSH_BLOCK_ONLY_Y 2
#define VEC_HULL_MIN Vector(-16, -16, -36)
#define VEC_HULL_MAX Vector(16, 16, 36)
#define VEC_HUMAN_HULL_MIN Vector(-16, -16, 0)
#define VEC_HUMAN_HULL_MAX Vector(16, 16, 72)
#define VEC_HUMAN_HULL_DUCK Vector(16, 16, 36)
#define VEC_VIEW Vector(0, 0, 28)
#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18)
#define VEC_DUCK_HULL_MAX Vector(16, 16, 18)
#define VEC_DUCK_VIEW Vector(0, 0, 12)
#define SVC_TEMPENTITY 23
#define SVC_CENTERPRINT 26
#define SVC_INTERMISSION 30
#define SVC_CDTRACK 32
#define SVC_WEAPONANIM 35
#define SVC_ROOMTYPE 37
#define SVC_DIRECTOR 51
// triggers
#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger
#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger
#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger
// func breakable
#define SF_BREAK_TRIGGER_ONLY 1 // may only be broken by trigger
#define SF_BREAK_TOUCH 2 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 4 // can be broken by a player standing on it
#define SF_BREAK_CROWBAR 256 // instant break if hit with crowbar
// func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 128
#define SF_LIGHT_START_OFF 1
#define SPAWNFLAG_NOMESSAGE 1
#define SPAWNFLAG_NOTOUCH 1
#define SPAWNFLAG_DROIDONLY 4
#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons)
#define TELE_PLAYER_ONLY 1
#define TELE_SILENT 2
#define SF_TRIG_PUSH_ONCE 1
// Rendering constants
enum {
kRenderNormal, // src
kRenderTransColor, // c*a+dest*(1-a)
kRenderTransTexture, // src*a+dest*(1-a)
kRenderGlow, // src*a+dest -- No Z buffer checks
kRenderTransAlpha, // src*srca+dest*(1-srca)
kRenderTransAdd // src*a+dest
};
enum {
kRenderFxNone = 0,
kRenderFxPulseSlow,
kRenderFxPulseFast,
kRenderFxPulseSlowWide,
kRenderFxPulseFastWide,
kRenderFxFadeSlow,
kRenderFxFadeFast,
kRenderFxSolidSlow,
kRenderFxSolidFast,
kRenderFxStrobeSlow,
kRenderFxStrobeFast,
kRenderFxStrobeFaster,
kRenderFxFlickerSlow,
kRenderFxFlickerFast,
kRenderFxNoDissipation,
kRenderFxDistort, // Distort/scale/translate flicker
kRenderFxHologram, // kRenderFxDistort + distance fade
kRenderFxDeadPlayer, // kRenderAmt is the player index
kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale // Keep this sprite from getting very small (SPRITES only!)
};
typedef enum {
ignore_monsters = 1,
dont_ignore_monsters = 0,
missile = 2
} IGNORE_MONSTERS;
typedef enum {
ignore_glass = 1,
dont_ignore_glass = 0
} IGNORE_GLASS;
typedef enum {
point_hull = 0,
human_hull = 1,
large_hull = 2,
head_hull = 3
} HULL;
typedef enum {
at_notice,
at_console, // same as at_notice, but forces a ConPrintf, not a message box
at_aiconsole, // same as at_console, but only shown if developer level is 2!
at_warning,
at_error,
at_logged // Server print to console ( only in multiplayer games ).
} ALERT_TYPE;
// 4-22-98 JOHN: added for use in pfnClientPrintf
typedef enum {
print_console,
print_center,
print_chat
} PRINT_TYPE;
// For integrity checking of content on clients
typedef enum {
force_exactfile, // File on client must exactly match server's file
force_model_samebounds, // For model files only, the geometry must fit in the same bbox
force_model_specifybounds // For model files only, the geometry must fit in the specified bbox
} FORCE_TYPE;
#endif

351
ext/hlsdk/eiface.h Normal file
View file

@ -0,0 +1,351 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#pragma once
struct cvar_t {
char *name;
char *string;
int flags;
float value;
cvar_t *next;
};
typedef struct hudtextparms_s {
float x;
float y;
int effect;
uint8 r1, g1, b1, a1;
uint8 r2, g2, b2, a2;
float fadeinTime;
float fadeoutTime;
float holdTime;
float fxTime;
int channel;
} hudtextparms_t;
// Returned by TraceLine
typedef struct {
int fAllSolid; // if true, plane is not valid
int fStartSolid; // if true, the initial point was in a solid area
int fInOpen;
int fInWater;
float flFraction; // time completed, 1.0 = didn't hit anything
vec3_t vecEndPos; // final position
float flPlaneDist;
vec3_t vecPlaneNormal; // surface normal at impact
edict_t *pHit; // entity the surface is on
int iHitgroup; // 0 == generic, non zero is specific body part
} TraceResult;
typedef struct usercmd_s {
short lerp_msec; // Interpolation time on client
byte msec; // Duration in ms of command
vec3_t viewangles; // Command view angles.
// intended velocities
float forwardmove; // Forward velocity.
float sidemove; // Sideways velocity.
float upmove; // Upward velocity.
byte lightlevel; // Light level at spot where we are standing.
unsigned short buttons; // Attack buttons
byte impulse; // Impulse command issued.
byte weaponselect; // Current weapon id
// Experimental player impact stuff.
int impact_index;
vec3_t impact_position;
} usercmd_t;
typedef uint32 CRC32_t;
// Engine hands this to DLLs for functionality callbacks
typedef struct enginefuncs_s {
int (*pfnPrecacheModel) (const char *s);
int (*pfnPrecacheSound) (const char *s);
void (*pfnSetModel) (edict_t *e, const char *m);
int (*pfnModelIndex) (const char *m);
int (*pfnModelFrames) (int modelIndex);
void (*pfnSetSize) (edict_t *e, const float *rgflMin, const float *rgflMax);
void (*pfnChangeLevel) (char *s1, char *s2);
void (*pfnGetSpawnParms) (edict_t *ent);
void (*pfnSaveSpawnParms) (edict_t *ent);
float (*pfnVecToYaw) (const float *rgflVector);
void (*pfnVecToAngles) (const float *rgflVectorIn, float *rgflVectorOut);
void (*pfnMoveToOrigin) (edict_t *ent, const float *pflGoal, float dist, int iMoveType);
void (*pfnChangeYaw) (edict_t *ent);
void (*pfnChangePitch) (edict_t *ent);
edict_t *(*pfnFindEntityByString) (edict_t *pentEdictStartSearchAfter, const char *pszField, const char *pszValue);
int (*pfnGetEntityIllum) (edict_t *pEnt);
edict_t *(*pfnFindEntityInSphere) (edict_t *pentEdictStartSearchAfter, const float *org, float rad);
edict_t *(*pfnFindClientInPVS) (edict_t *ent);
edict_t *(*pfnEntitiesInPVS) (edict_t *pplayer);
void (*pfnMakeVectors) (const float *rgflVector);
void (*pfnAngleVectors) (const float *rgflVector, float *forward, float *right, float *up);
edict_t *(*pfnCreateEntity) ();
void (*pfnRemoveEntity) (edict_t *e);
edict_t *(*pfnCreateNamedEntity) (int className);
void (*pfnMakeStatic) (edict_t *ent);
int (*pfnEntIsOnFloor) (edict_t *e);
int (*pfnDropToFloor) (edict_t *e);
int (*pfnWalkMove) (edict_t *ent, float yaw, float dist, int mode);
void (*pfnSetOrigin) (edict_t *e, const float *rgflOrigin);
void (*pfnEmitSound) (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch);
void (*pfnEmitAmbientSound) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
void (*pfnTraceLine) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceToss) (edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
int (*pfnTraceMonsterHull) (edict_t *ent, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceHull) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnTraceModel) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2);
void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
void (*pfnGetAimVector) (edict_t *ent, float speed, float *rgflReturn);
void (*pfnServerCommand) (char *str);
void (*pfnServerExecute) ();
void (*pfnClientCommand) (edict_t *ent, char const *szFmt, ...);
void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count);
void (*pfnLightStyle) (int style, char *val);
int (*pfnDecalIndex) (const char *name);
int (*pfnPointContents) (const float *rgflVector);
void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
void (*pfnMessageEnd) ();
void (*pfnWriteByte) (int value);
void (*pfnWriteChar) (int value);
void (*pfnWriteShort) (int value);
void (*pfnWriteLong) (int value);
void (*pfnWriteAngle) (float flValue);
void (*pfnWriteCoord) (float flValue);
void (*pfnWriteString) (const char *sz);
void (*pfnWriteEntity) (int value);
void (*pfnCVarRegister) (cvar_t *pCvar);
float (*pfnCVarGetFloat) (const char *szVarName);
const char *(*pfnCVarGetString) (const char *szVarName);
void (*pfnCVarSetFloat) (const char *szVarName, float flValue);
void (*pfnCVarSetString) (const char *szVarName, const char *szValue);
void (*pfnAlertMessage) (ALERT_TYPE atype, const char *szFmt, ...);
void (*pfnEngineFprintf) (void *pfile, char *szFmt, ...);
void *(*pfnPvAllocEntPrivateData) (edict_t *ent, int32 cb);
void *(*pfnPvEntPrivateData) (edict_t *ent);
void (*pfnFreeEntPrivateData) (edict_t *ent);
const char *(*pfnSzFromIndex) (int stingPtr);
int (*pfnAllocString) (const char *szValue);
struct entvars_s *(*pfnGetVarsOfEnt) (edict_t *ent);
edict_t *(*pfnPEntityOfEntOffset) (int iEntOffset);
int (*pfnEntOffsetOfPEntity) (const edict_t *ent);
int (*pfnIndexOfEdict) (const edict_t *ent);
edict_t *(*pfnPEntityOfEntIndex) (int entIndex);
edict_t *(*pfnFindEntityByVars) (struct entvars_s *pvars);
void *(*pfnGetModelPtr) (edict_t *ent);
int (*pfnRegUserMsg) (const char *pszName, int iSize);
void (*pfnAnimationAutomove) (const edict_t *ent, float flTime);
void (*pfnGetBonePosition) (const edict_t *ent, int iBone, float *rgflOrigin, float *rgflAngles);
uint32 (*pfnFunctionFromName) (const char *pName);
const char *(*pfnNameForFunction) (uint32 function);
void (*pfnClientPrintf) (edict_t *ent, PRINT_TYPE ptype, const char *szMsg); // JOHN: engine callbacks so game DLL can print messages to individual clients
void (*pfnServerPrint) (const char *szMsg);
const char *(*pfnCmd_Args) (); // these 3 added
const char *(*pfnCmd_Argv) (int argc); // so game DLL can easily
int (*pfnCmd_Argc) (); // access client 'cmd' strings
void (*pfnGetAttachment) (const edict_t *ent, int iAttachment, float *rgflOrigin, float *rgflAngles);
void (*pfnCRC32_Init) (CRC32_t *pulCRC);
void (*pfnCRC32_ProcessBuffer) (CRC32_t *pulCRC, void *p, int len);
void (*pfnCRC32_ProcessByte) (CRC32_t *pulCRC, uint8 ch);
CRC32_t (*pfnCRC32_Final) (CRC32_t pulCRC);
int32 (*pfnRandomLong) (int32 lLow, int32 lHigh);
float (*pfnRandomFloat) (float flLow, float flHigh);
void (*pfnSetView) (const edict_t *client, const edict_t *pViewent);
float (*pfnTime) ();
void (*pfnCrosshairAngle) (const edict_t *client, float pitch, float yaw);
uint8 *(*pfnLoadFileForMe) (char const *szFilename, int *pLength);
void (*pfnFreeFile) (void *buffer);
void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection
int (*pfnCompareFileTime) (char *filename1, char *filename2, int *compare);
void (*pfnGetGameDir) (char *szGetGameDir);
void (*pfnCvar_RegisterVariable) (cvar_t *variable);
void (*pfnFadeClientVolume) (const edict_t *ent, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
void (*pfnSetClientMaxspeed) (const edict_t *ent, float fNewMaxspeed);
edict_t *(*pfnCreateFakeClient) (const char *netname); // returns nullptr if fake client can't be created
void (*pfnRunPlayerMove) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, uint16 buttons, uint8 impulse, uint8 msec);
int (*pfnNumberOfEntities) ();
char *(*pfnGetInfoKeyBuffer) (edict_t *e); // passing in nullptr gets the serverinfo
char *(*pfnInfoKeyValue) (char *infobuffer, char const *key);
void (*pfnSetKeyValue) (char *infobuffer, char *key, char *value);
void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, char const *key, char const *value);
int (*pfnIsMapValid) (char *szFilename);
void (*pfnStaticDecal) (const float *origin, int decalIndex, int entityIndex, int modelIndex);
int (*pfnPrecacheGeneric) (char *s);
int (*pfnGetPlayerUserId) (edict_t *e); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
int (*pfnIsDedicatedServer) (); // is this a dedicated server?
cvar_t *(*pfnCVarGetPointer) (const char *szVarName);
unsigned int (*pfnGetPlayerWONId) (edict_t *e); // returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnInfo_RemoveKey) (char *s, const char *key);
const char *(*pfnGetPhysicsKeyValue) (const edict_t *client, const char *key);
void (*pfnSetPhysicsKeyValue) (const edict_t *client, const char *key, const char *value);
const char *(*pfnGetPhysicsInfoString) (const edict_t *client);
uint16 (*pfnPrecacheEvent) (int type, const char *psz);
void (*pfnPlaybackEvent) (int flags, const edict_t *pInvoker, uint16 evIndexOfEntity, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
uint8 *(*pfnSetFatPVS) (float *org);
uint8 *(*pfnSetFatPAS) (float *org);
int (*pfnCheckVisibility) (const edict_t *entity, uint8 *pset);
void (*pfnDeltaSetField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaUnsetField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaAddEncoder) (char *name, void (*conditionalencode) (struct delta_s *pFields, const uint8 *from, const uint8 *to));
int (*pfnGetCurrentPlayer) ();
int (*pfnCanSkipPlayer) (const edict_t *player);
int (*pfnDeltaFindField) (struct delta_s *pFields, const char *fieldname);
void (*pfnDeltaSetFieldByIndex) (struct delta_s *pFields, int fieldNumber);
void (*pfnDeltaUnsetFieldByIndex) (struct delta_s *pFields, int fieldNumber);
void (*pfnSetGroupMask) (int mask, int op);
int (*pfnCreateInstancedBaseline) (int classname, struct entity_state_s *baseline);
void (*pfnCvar_DirectSet) (struct cvar_t *var, char *value);
void (*pfnForceUnmodified) (FORCE_TYPE type, float *mins, float *maxs, const char *szFilename);
void (*pfnGetPlayerStats) (const edict_t *client, int *ping, int *packet_loss);
void (*pfnAddServerCommand) (const char *cmd_name, void (*function) ());
int (*pfnVoice_GetClientListening) (int iReceiver, int iSender);
int (*pfnVoice_SetClientListening) (int iReceiver, int iSender, int bListen);
const char *(*pfnGetPlayerAuthId) (edict_t *e);
struct sequenceEntry_s *(*pfnSequenceGet) (const char *fileName, const char *entryName);
struct sentenceEntry_s *(*pfnSequencePickSentence) (const char *groupName, int pickMethod, int *picked);
int (*pfnGetFileSize) (char *szFilename);
unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath);
int (*pfnIsCareerMatch) ();
int (*pfnGetLocalizedStringLength) (const char *label);
void (*pfnRegisterTutorMessageShown) (int mid);
int (*pfnGetTimesTutorMessageShown) (int mid);
void (*pfnProcessTutorMessageDecayBuffer) (int *buffer, int bufferLength);
void (*pfnConstructTutorMessageDecayBuffer) (int *buffer, int bufferLength);
void (*pfnResetTutorMessageDecayData) ();
void (*pfnQueryClientCVarValue) (const edict_t *player, const char *cvarName);
void (*pfnQueryClientCVarValue2) (const edict_t *player, const char *cvarName, int requestID);
int (*pfnCheckParm) (const char *pchCmdLineToken, char **ppnext);
#ifdef EIFACE_2019
edict_t *(*pfnPEntityOfEntIndexAllEntities) (int iEntIndex);
#endif
} enginefuncs_t;
// Passed to pfnKeyValue
typedef struct KeyValueData_s {
char *szClassName; // in: entity classname
char const *szKeyName; // in: name of key
char *szValue; // in: value of key
int32 fHandled; // out: DLL sets to true if key-value pair was understood
} KeyValueData;
typedef struct customization_s customization_t;
typedef struct {
// Initialize/shutdown the game (one-time call after loading of game .dll )
void (*pfnGameInit) ();
int (*pfnSpawn) (edict_t *pent);
void (*pfnThink) (edict_t *pent);
void (*pfnUse) (edict_t *pentUsed, edict_t *pentOther);
void (*pfnTouch) (edict_t *pentTouched, edict_t *pentOther);
void (*pfnBlocked) (edict_t *pentBlocked, edict_t *pentOther);
void (*pfnKeyValue) (edict_t *pentKeyvalue, KeyValueData *pkvd);
void (*pfnSave) (edict_t *pent, struct SAVERESTOREDATA *pSaveData);
int (*pfnRestore) (edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
void (*pfnSetAbsBox) (edict_t *pent);
void (*pfnSaveWriteFields) (SAVERESTOREDATA *, const char *, void *, struct TYPEDESCRIPTION *, int);
void (*pfnSaveReadFields) (SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int);
void (*pfnSaveGlobalState) (SAVERESTOREDATA *);
void (*pfnRestoreGlobalState) (SAVERESTOREDATA *);
void (*pfnResetGlobalState) ();
int (*pfnClientConnect) (edict_t *ent, const char *pszName, const char *pszAddress, char szRejectReason[128]);
void (*pfnClientDisconnect) (edict_t *ent);
void (*pfnClientKill) (edict_t *ent);
void (*pfnClientPutInServer) (edict_t *ent);
void (*pfnClientCommand) (edict_t *ent);
void (*pfnClientUserInfoChanged) (edict_t *ent, char *infobuffer);
void (*pfnServerActivate) (edict_t *edictList, int edictCount, int clientMax);
void (*pfnServerDeactivate) ();
void (*pfnPlayerPreThink) (edict_t *ent);
void (*pfnPlayerPostThink) (edict_t *ent);
void (*pfnStartFrame) ();
void (*pfnParmsNewLevel) ();
void (*pfnParmsChangeLevel) ();
// Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life
const char *(*pfnGetGameDescription) ();
// Notify dll about a player customization.
void (*pfnPlayerCustomization) (edict_t *ent, struct customization_s *pCustom);
// Spectator funcs
void (*pfnSpectatorConnect) (edict_t *ent);
void (*pfnSpectatorDisconnect) (edict_t *ent);
void (*pfnSpectatorThink) (edict_t *ent);
// Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint.
void (*pfnSys_Error) (const char *error_string);
void (*pfnPM_Move) (struct playermove_s *ppmove, int server);
void (*pfnPM_Init) (struct playermove_s *ppmove);
char (*pfnPM_FindTextureType) (char *name);
void (*pfnSetupVisibility) (struct edict_s *pViewEntity, struct edict_s *client, uint8 **pvs, uint8 **pas);
void (*pfnUpdateClientData) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
int (*pfnAddToFullPack) (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, uint8 *pSet);
void (*pfnCreateBaseline) (int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, float *player_mins, float *player_maxs);
void (*pfnRegisterEncoders) ();
int (*pfnGetWeaponData) (struct edict_s *player, struct weapon_data_s *info);
void (*pfnCmdStart) (const edict_t *player, usercmd_t *cmd, unsigned int random_seed);
void (*pfnCmdEnd) (const edict_t *player);
// Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max
// size of the response_buffer, so you must zero it out if you choose not to respond.
int (*pfnConnectionlessPacket) (const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
// Enumerates player hulls. Returns 0 if the hull number doesn't exist, 1 otherwise
int (*pfnGetHullBounds) (int hullnumber, float *mins, float *maxs);
// Create baselines for certain "unplaced" items.
void (*pfnCreateInstancedBaselines) ();
// One of the pfnForceUnmodified files failed the consistency check for the specified player
// Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters )
int (*pfnInconsistentFile) (const struct edict_s *player, const char *szFilename, char *disconnect_message);
// The game .dll should return 1 if lag compensation should be allowed ( could also just set
// the sv_unlag cvar.
// Most games right now should return 0, until client-side weapon prediction code is written
// and tested for them.
int (*pfnAllowLagCompensation) ();
} gamefuncs_t;
typedef struct {
// Called right before the object's memory is freed.
// Calls its destructor.
void (*pfnOnFreeEntPrivateData) (edict_t *pEnt);
void (*pfnGameShutdown) ();
int (*pfnShouldCollide) (edict_t *pentTouched, edict_t *pentOther);
void (*pfnCvarValue) (const edict_t *pEnt, const char *value);
void (*pfnCvarValue2) (const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
} newgamefuncs_t;

121
ext/hlsdk/extdll.h Normal file
View file

@ -0,0 +1,121 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef EXTDLL_H
#define EXTDLL_H
typedef int func_t; //
typedef float vec_t; // needed before including progdefs.h
typedef vec_t vec2_t[2];
typedef vec_t vec4_t[4];
typedef int qboolean;
typedef unsigned char byte;
#include <crlib/cr-vector.h>
#include <crlib/cr-string.h>
// idea from regamedll
class string_t final : public cr::DenyCopying {
private:
int offset;
public:
explicit string_t () : offset (0)
{ }
string_t (int offset) : offset (offset)
{ }
~string_t () = default;
public:
const char *chars (size_t shift = 0) const;
public:
operator int () const {
return offset;
}
string_t &operator = (const string_t &rhs) {
offset = rhs.offset;
return *this;
}
};
typedef cr::Vector vec3_t;
using namespace cr::types;
typedef struct edict_s edict_t;
#include "const.h"
#include "progdefs.h"
#include "model.h"
typedef struct link_s {
struct link_s *prev, *next;
} link_t;
typedef struct {
vec3_t normal;
float dist;
} plane_t;
struct edict_s {
int free;
int serialnumber;
link_t area; // linked to a division node or leaf
int headnode; // -1 to use normal leaf check
int num_leafs;
short leafnums[MAX_ENT_LEAFS];
float freetime; // sv.time when the object was freed
void *pvPrivateData; // Alloced and freed by engine, used by DLLs
entvars_t v; // C exported fields from progs
};
#include "eiface.h"
extern globalvars_t *globals;
extern enginefuncs_t engfuncs;
extern gamefuncs_t dllapi;
// Use this instead of ALLOC_STRING on constant strings
#define STRING(offset) (const char *)(globals->pStringBase + (int)offset)
// form fwgs-hlsdk
#if defined (CR_ARCH_X64)
static inline int MAKE_STRING (const char *val) {
long long ptrdiff = val - STRING (0);
if (ptrdiff > INT_MAX || ptrdiff < INT_MIN) {
return engfuncs.pfnAllocString (val);
}
return static_cast <int> (ptrdiff);
}
#else
#define MAKE_STRING(str) ((uint64)(str) - (uint64)(STRING(0)))
#endif
inline const char *string_t::chars (size_t shift) const {
auto result = STRING (offset);
return cr::strings.isEmpty (result) ? &cr::kNullChar : (result + shift);
}
enum HLBool : int32 {
HLFalse, HLTrue
};
#endif // EXTDLL_H

224
ext/hlsdk/meta_api.h Normal file
View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
*
* This file is part of Metamod.
*
* Metamod 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 2 of the License, or (at
* your option) any later version.
*
* Metamod 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.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
// Simplified version by Wei Mingzhi
#ifndef META_API_H
#define META_API_H
typedef int (*GETENTITYAPI_FN) (gamefuncs_t *pFunctionTable, int interfaceVersion);
typedef int (*GETENTITYAPI2_FN) (gamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GETNEWDLLFUNCTIONS_FN) (newgamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
#define META_INTERFACE_VERSION "5:13"
typedef enum { PT_NEVER = 0, PT_STARTUP, PT_CHANGELEVEL, PT_ANYTIME, PT_ANYPAUSE } PLUG_LOADTIME;
typedef struct {
char const *ifvers;
char const *name;
char const *version;
char const *date;
char const *author;
char const *url;
char const *logtag;
PLUG_LOADTIME loadable;
PLUG_LOADTIME unloadable;
} plugin_info_t;
extern plugin_info_t Plugin_info;
typedef plugin_info_t *plid_t;
#define PLID &Plugin_info
typedef enum { PNL_NULL = 0, PNL_INI_DELETED, PNL_FILE_NEWER, PNL_COMMAND, PNL_CMD_FORCED, PNL_DELAYED, PNL_PLUGIN, PNL_PLG_FORCED, PNL_RELOAD } PL_UNLOAD_REASON;
typedef enum { MRES_UNSET = 0, MRES_IGNORED, MRES_HANDLED, MRES_OVERRIDE, MRES_SUPERCEDE } META_RES;
typedef struct meta_globals_s {
META_RES mres;
META_RES prev_mres;
META_RES status;
void *orig_ret;
void *override_ret;
} meta_globals_t;
extern meta_globals_t *gpMetaGlobals;
#define SET_META_RESULT(result) gpMetaGlobals->mres = result
#define RETURN_META(result) \
{ \
gpMetaGlobals->mres = result; \
return; \
}
#define RETURN_META_VALUE(result, value) \
{ \
gpMetaGlobals->mres = result; \
return (value); \
}
#define META_RESULT_STATUS gpMetaGlobals->status
#define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres
#define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret
#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret
typedef struct {
GETENTITYAPI_FN pfnGetEntityAPI;
GETENTITYAPI_FN pfnGetEntityAPI_Post;
GETENTITYAPI2_FN pfnGetEntityAPI2;
GETENTITYAPI2_FN pfnGetEntityAPI2_Post;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post;
} metamod_funcs_t;
#include "util.h"
// max buffer size for printed messages
#define MAX_LOGMSG_LEN 1024
// for getgameinfo:
typedef enum { GINFO_NAME = 0, GINFO_DESC, GINFO_GAMEDIR, GINFO_DLL_FULLPATH, GINFO_DLL_FILENAME, GINFO_REALDLL_FULLPATH } ginfo_t;
// Meta Utility Function table type.
typedef struct meta_util_funcs_s {
void (*pfnLogConsole) (plid_t plid, const char *szFormat, ...);
void (*pfnLogMessage) (plid_t plid, const char *szFormat, ...);
void (*pfnLogError) (plid_t plid, const char *szFormat, ...);
void (*pfnLogDeveloper) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSay) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, const char *szFormat, ...);
void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, const char *szFormat, va_list ap);
int (*pfnCallGameEntity) (plid_t plid, const char *entStr, entvars_t *pev);
int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size);
const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size);
const char *(*pfnGetPluginPath) (plid_t plid);
const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag);
int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
const char *(*pfnIsQueryingClienCVar_t) (plid_t plid, const edict_t *player);
int (*pfnMakeRequestID) (plid_t plid);
void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, gamefuncs_t **pdll, newgamefuncs_t **pnewdll);
} mutil_funcs_t;
typedef struct {
gamefuncs_t *dllapi_table;
newgamefuncs_t *newapi_table;
} gamedll_funcs_t;
extern gamedll_funcs_t *gpGamedllFuncs;
extern mutil_funcs_t *gpMetaUtilFuncs;
extern metamod_funcs_t gMetaFunctionTable;
#define MDLL_FUNC gpGamedllFuncs->dllapi_table
#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit
#define MDLL_Spawn MDLL_FUNC->pfnSpawn
#define MDLL_Think MDLL_FUNC->pfnThink
#define MDLL_Use MDLL_FUNC->pfnUse
#define MDLL_Touch MDLL_FUNC->pfnTouch
#define MDLL_Blocked MDLL_FUNC->pfnBlocked
#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue
#define MDLL_Save MDLL_FUNC->pfnSave
#define MDLL_Restore MDLL_FUNC->pfnRestore
#define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox
#define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields
#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields
#define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState
#define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState
#define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState
#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect
#define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect
#define MDLL_ClientKill MDLL_FUNC->pfnClientKill
#define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer
#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand
#define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged
#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate
#define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate
#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink
#define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink
#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame
#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel
#define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel
#define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription
#define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization
#define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect
#define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect
#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink
#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error
#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move
#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init
#define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType
#define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility
#define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData
#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack
#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline
#define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders
#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData
#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart
#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd
#define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket
#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds
#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines
#define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile
#define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation
#define MNEW_FUNC gpGamedllFuncs->newapi_table
#define MNEW_OnFreeEntPrivateData MNEW_FUNC->pfnOnFreeEntPrivateData
#define MNEW_GameShutdown MNEW_FUNC->pfnGameShutdown
#define MNEW_ShouldCollide MNEW_FUNC->pfnShouldCollide
#define MNEW_CvarValue MNEW_FUNC->pfnCvarValue
#define MNEW_CvarValue2 MNEW_FUNC->pfnCvarValue2
// convenience macros for metautil functions
#define LOG_CONSOLE (*gpMetaUtilFuncs->pfnLogConsole)
#define LOG_MESSAGE (*gpMetaUtilFuncs->pfnLogMessage)
#define LOG_MMERROR (*gpMetaUtilFuncs->pfnLogError)
#define LOG_DEVELOPER (*gpMetaUtilFuncs->pfnLogDeveloper)
#define CENTER_SAY (*gpMetaUtilFuncs->pfnCenterSay)
#define CENTER_SAY_PARMS (*gpMetaUtilFuncs->pfnCenterSayParms)
#define CENTER_SAY_VARARGS (*gpMetaUtilFuncs->pfnCenterSayVarargs)
#define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity)
#define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID)
#define GET_USER_MSG_NAME (*gpMetaUtilFuncs->pfnGetUserMsgName)
#define GET_PLUGIN_PATH (*gpMetaUtilFuncs->pfnGetPluginPath)
#define GET_GAME_INFO (*gpMetaUtilFuncs->pfnGetGameInfo)
#define LOAD_PLUGIN (*gpMetaUtilFuncs->pfnLoadPlugin)
#define UNLOAD_PLUGIN (*gpMetaUtilFuncs->pfnUnloadPlugin)
#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle)
#define IS_QUERYING_CLIENT_CVAR (*gpMetaUtilFuncs->pfnIsQueryingClienCVar_t)
#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestID)
#define GET_HOOK_TABLES (*gpMetaUtilFuncs->pfnGetHookTables)
#endif

229
ext/hlsdk/metamod.h Normal file
View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
*
* This file is part of Metamod.
*
* Metamod 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 2 of the License, or (at
* your option) any later version.
*
* Metamod 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.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
// Simplified version by Wei Mingzhi
#ifndef METAMOD_H
#define METAMOD_H
typedef enum {
PNL_NULL = 0,
PNL_INI_DELETED,
PNL_FILE_NEWER,
PNL_COMMAND,
PNL_CMD_FORCED,
PNL_DELAYED,
PNL_PLUGIN,
PNL_PLG_FORCED,
PNL_RELOAD
} PL_UNLOAD_REASON;
typedef enum {
MRES_UNSET = 0,
MRES_IGNORED,
MRES_HANDLED,
MRES_OVERRIDE,
MRES_SUPERCEDE
} META_RES;
typedef enum {
PT_NEVER = 0,
PT_STARTUP,
PT_CHANGELEVEL,
PT_ANYTIME,
PT_ANYPAUSE
} PLUG_LOADTIME;
// for getgameinfo:
typedef enum {
GINFO_NAME = 0,
GINFO_DESC,
GINFO_GAMEDIR,
GINFO_DLL_FULLPATH,
GINFO_DLL_FILENAME,
GINFO_REALDLL_FULLPATH
} ginfo_t;
typedef int (*GETENTITYAPI_FN) (gamefuncs_t *pFunctionTable, int interfaceVersion);
typedef int (*GETENTITYAPI2_FN) (gamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GETNEWDLLFUNCTIONS_FN) (newgamefuncs_t *pFunctionTable, int *interfaceVersion);
typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
#define META_INTERFACE_VERSION "5:13"
typedef struct {
char const *ifvers;
char const *name;
char const *version;
char const *date;
char const *author;
char const *url;
char const *logtag;
PLUG_LOADTIME loadable;
PLUG_LOADTIME unloadable;
} plugin_info_t;
extern plugin_info_t Plugin_info;
typedef plugin_info_t *plid_t;
#define PLID &Plugin_info
typedef struct meta_globals_s {
META_RES mres;
META_RES prev_mres;
META_RES status;
void *orig_ret;
void *override_ret;
} meta_globals_t;
extern meta_globals_t *gpMetaGlobals;
#define RETURN_META(result) \
{ \
gpMetaGlobals->mres = result; \
return; \
}
#define RETURN_META_VALUE(result, value) \
{ \
gpMetaGlobals->mres = result; \
return (value); \
}
#define META_RESULT_STATUS gpMetaGlobals->status
#define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres
#define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret
#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret
typedef struct {
GETENTITYAPI_FN pfnGetEntityAPI;
GETENTITYAPI_FN pfnGetEntityAPI_Post;
GETENTITYAPI2_FN pfnGetEntityAPI2;
GETENTITYAPI2_FN pfnGetEntityAPI2_Post;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions;
GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions;
GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post;
} metamod_funcs_t;
// max buffer size for printed messages
#define MAX_LOGMSG_LEN 1024
// Meta Utility Function table type.
typedef struct meta_util_funcs_s {
void (*pfnLogConsole) (plid_t plid, const char *szFormat, ...);
void (*pfnLogMessage) (plid_t plid, const char *szFormat, ...);
void (*pfnLogError) (plid_t plid, const char *szFormat, ...);
void (*pfnLogDeveloper) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSay) (plid_t plid, const char *szFormat, ...);
void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, const char *szFormat, ...);
void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, const char *szFormat, va_list ap);
int (*pfnCallGameEntity) (plid_t plid, const char *entStr, entvars_t *pev);
int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size);
const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size);
const char *(*pfnGetPluginPath) (plid_t plid);
const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag);
int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
const char *(*pfnIsQueryingClienCVar_t) (plid_t plid, const edict_t *player);
int (*pfnMakeRequestID) (plid_t plid);
void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, gamefuncs_t **pdll, newgamefuncs_t **pnewdll);
} mutil_funcs_t;
typedef struct {
gamefuncs_t *dllapi_table;
newgamefuncs_t *newapi_table;
} gamedll_funcs_t;
extern gamedll_funcs_t *gpGamedllFuncs;
extern mutil_funcs_t *gpMetaUtilFuncs;
extern metamod_funcs_t gMetaFunctionTable;
#define MDLL_FUNC gpGamedllFuncs->dllapi_table
#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit
#define MDLL_Spawn MDLL_FUNC->pfnSpawn
#define MDLL_Think MDLL_FUNC->pfnThink
#define MDLL_Use MDLL_FUNC->pfnUse
#define MDLL_Touch MDLL_FUNC->pfnTouch
#define MDLL_Blocked MDLL_FUNC->pfnBlocked
#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue
#define MDLL_Save MDLL_FUNC->pfnSave
#define MDLL_Restore MDLL_FUNC->pfnRestore
#define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox
#define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields
#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields
#define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState
#define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState
#define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState
#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect
#define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect
#define MDLL_ClientKill MDLL_FUNC->pfnClientKill
#define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer
#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand
#define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged
#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate
#define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate
#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink
#define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink
#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame
#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel
#define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel
#define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription
#define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization
#define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect
#define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect
#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink
#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error
#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move
#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init
#define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType
#define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility
#define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData
#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack
#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline
#define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders
#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData
#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart
#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd
#define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket
#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds
#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines
#define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile
#define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation
#define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity)
#define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID)
#endif

229
ext/hlsdk/model.h Normal file
View file

@ -0,0 +1,229 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
// stripped down version of com_model.h & pm_info.h
#ifndef MODEL_H
#define MODEL_H
typedef struct mplane_s {
vec3_t normal;
float dist;
byte type; // for fast side tests
byte signbits; // signx + (signy<<1) + (signz<<1)
byte pad[2];
} mplane_t;
typedef struct {
vec3_t position;
} mvertex_t;
typedef struct {
float vecs[2][4]; // [s/t] unit vectors in world space [i][3] is the s/t offset relative to the origin s or t = dot( 3Dpoint, vecs[i] ) + vecs[i][3]
float mipadjust; // mipmap limits for very small surfaces
struct texture_t *texture;
int flags; // sky or slime, no lightmap or 256 subdivision
} mtexinfo_t;
typedef struct mnode_hw_s {
int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current
float minmaxs[6]; // for bounding box culling
struct mnode_s *parent;
mplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
} mnode_hw_t;
typedef struct mnode_s {
int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current
short minmaxs[6]; // for bounding box culling
struct mnode_s *parent;
mplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
} mnode_t;
typedef struct {
byte r, g, b;
} color24;
typedef struct msurface_hw_s {
int visframe; // should be drawn when node is crossed
mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
short texturemins[2];
short extents[2];
int light_s, light_t; // gl lightmap coordinates
struct glpoly_t *polys; // multiple if warped
struct msurface_s *texturechain;
mtexinfo_t *texinfo;
int dlightframe; // last frame the surface was checked by an animated light
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
int lightmaptexturenum;
byte styles[MAXLIGHTMAPS];
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
qboolean cached_dlight; // true if dynamic light in cache
color24 *samples; // note: this is the actual lightmap data for this surface
struct decal_t *pdecals;
} msurface_hw_t;
typedef struct msurface_s {
int visframe; // should be drawn when node is crossed
int dlightframe; // last frame the surface was checked by an animated light
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
struct surfcache_s *cachespots[4]; // surface generation data
short texturemins[2]; // smallest s/t position on the surface.
short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces
mtexinfo_t *texinfo;
byte styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights no one surface can be effected by more than 4 animated lights.
color24 *samples;
struct decal_t *pdecals;
} msurface_t;
typedef struct cache_user_s {
void* data; // extradata
} cache_user_t;
typedef struct hull_s {
struct dclipnode_t *clipnodes;
mplane_t *planes;
int firstclipnode;
int lastclipnode;
vec3_t clip_mins;
vec3_t clip_maxs;
} hull_t;
typedef struct model_s {
char name[64]; // model name
qboolean needload; // bmodels and sprites don't cache normally
int type; // model type
int numframes; // sprite's framecount
byte *mempool; // private mempool (was synctype)
int flags; // hl compatibility
vec3_t mins, maxs; // bounding box at angles '0 0 0'
float radius;
int firstmodelsurface;
int nummodelsurfaces;
int numsubmodels;
struct dmodel_t *submodels; // or studio animations
int numplanes;
mplane_t *planes;
int numleafs; // number of visible leafs, not counting 0
struct mleaf_t *leafs;
int numvertexes;
mvertex_t *vertexes;
int numedges;
struct medge_t *edges;
int numnodes;
mnode_t *nodes;
int numtexinfo;
mtexinfo_t *texinfo;
int numsurfaces;
msurface_t *surfaces;
int numsurfedges;
int *surfedges;
int numclipnodes;
struct dclipnode_t *clipnodes;
int nummarksurfaces;
msurface_t **marksurfaces;
hull_t hulls[MAX_MAP_HULLS];
int numtextures;
texture_t **textures;
byte *visdata;
color24 *lightdata;
char *entities;
cache_user_t cache; // only access through Mod_Extradata
} model_t;
struct lightstyle_t {
int length;
char map[MAX_LIGHTSTYLES];
};
typedef struct physent_s {
char name[32]; // name of model, or "player" or "world".
int player;
vec3_t origin; // model's origin in world coordinates.
struct model_s* model; // only for bsp models
} physent_t;
typedef struct playermove_s {
int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly.
qboolean server; // For debugging, are we running physics code on server side?
qboolean multiplayer; // 1 == multiplayer server
float time; // realtime on host, for reckoning duck timing
float frametime; // Duration of this frame
vec3_t forward, right, up; // Vectors for angles
vec3_t origin; // Movement origin.
vec3_t angles; // Movement view angles.
vec3_t oldangles; // Angles before movement view angles were looked at.
vec3_t velocity; // Current movement direction.
vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge.
vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g.
vec3_t view_ofs; // Our eye position.
float flDuckTime; // Time we started duck
qboolean bInDuck; // In process of ducking or ducked already?
int flTimeStepSound; // Next time we can play a step sound
int iStepLeft;
float flFallVelocity;
vec3_t punchangle;
float flSwimTime;
float flNextPrimaryAttack;
int effects; // MUZZLE FLASH, e.g.
int flags; // FL_ONGROUND, FL_DUCKING, etc.
int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull
float gravity; // Our current gravity and friction.
float friction;
int oldbuttons; // Buttons last usercmd
float waterjumptime; // Amount of time left in jumping out of water cycle.
qboolean dead; // Are we a dead player?
int deadflag;
int spectator; // Should we use spectator physics model?
int movetype; // Our movement type, NOCLIP, WALK, FLY
int onground;
int waterlevel;
int watertype;
int oldwaterlevel;
char sztexturename[256];
char chtexturetype;
float maxspeed;
float clientmaxspeed; // Player specific maxspeed
int iuser1;
int iuser2;
int iuser3;
int iuser4;
float fuser1;
float fuser2;
float fuser3;
float fuser4;
vec3_t vuser1;
vec3_t vuser2;
vec3_t vuser3;
vec3_t vuser4;
int numphysent;
physent_t physents[MAX_PHYSENTS];
} playermove_t;
#endif

214
ext/hlsdk/progdefs.h Normal file
View file

@ -0,0 +1,214 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#pragma once
typedef struct {
float time;
float frametime;
float force_retouch;
string_t mapname;
string_t startspot;
float deathmatch;
float coop;
float teamplay;
float serverflags;
float found_secrets;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
edict_t *trace_ent;
float trace_inopen;
float trace_inwater;
int trace_hitgroup;
int trace_flags;
int msg_entity;
int cdAudioTrack;
int maxClients;
int maxEntities;
const char *pStringBase;
void *pSaveData;
vec3_t vecLandmarkOffset;
} globalvars_t;
typedef struct entvars_s {
string_t classname;
string_t globalname;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t basevelocity;
vec3_t clbasevelocity; // Base velocity that was passed in to server physics so
// client can predict conveyors correctly. Server zeroes it, so we need to store here, too.
vec3_t movedir;
vec3_t angles; // Model angles
vec3_t avelocity; // angle velocity (degrees per second)
vec3_t punchangle; // auto-decaying view angle adjustment
vec3_t v_angle; // Viewing angle (player only)
// For parametric entities
vec3_t endpos;
vec3_t startpos;
float impacttime;
float starttime;
int fixangle; // 0:nothing, 1:force view angles, 2:add avelocity
float idealpitch;
float pitch_speed;
float ideal_yaw;
float yaw_speed;
int modelindex;
string_t model;
string_t viewmodel; // player's viewmodel
string_t weaponmodel; // what other players see
vec3_t absmin; // BB max translated to world coord
vec3_t absmax; // BB max translated to world coord
vec3_t mins; // local BB min
vec3_t maxs; // local BB max
vec3_t size; // maxs - mins
float ltime;
float nextthink;
int movetype;
int solid;
int skin;
int body; // sub-model selection for studiomodels
int effects;
float gravity; // % of "normal" gravity
float friction; // inverse elasticity of MOVETYPE_BOUNCE
int light_level;
int sequence; // animation sequence
int gaitsequence; // movement animation sequence for player (0 for none)
float frame; // % playback position in animation sequences (0..255)
float animtime; // world time when frame was set
float framerate; // animation playback rate (-8x to 8x)
uint8 controller[4]; // bone controller setting (0..255)
uint8 blending[2]; // blending amount between sub-sequences (0..255)
float scale; // sprite rendering scale (0..255)
int rendermode;
float renderamt;
vec3_t rendercolor;
int renderfx;
float health;
float frags;
int weapons; // bit mask for available weapons
float takedamage;
int deadflag;
vec3_t view_ofs; // eye position
int button;
int impulse;
edict_t *chain; // Entity pointer when linked into a linked list
edict_t *dmg_inflictor;
edict_t *enemy;
edict_t *aiment; // entity pointer when MOVETYPE_FOLLOW
edict_t *owner;
edict_t *groundentity;
int spawnflags;
int flags;
int colormap; // lowbyte topcolor, highbyte bottomcolor
int team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
int waterlevel;
int watertype;
string_t target;
string_t targetname;
string_t netname;
string_t message;
float dmg_take;
float dmg_save;
float dmg;
float dmgtime;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
float speed;
float air_finished;
float pain_finished;
float radsuit_finished;
edict_t *pContainingEntity;
int playerclass;
float maxspeed;
float fov;
int weaponanim;
int pushmsec;
int bInDuck;
int flTimeStepSound;
int flSwimTime;
int flDuckTime;
int iStepLeft;
float flFallVelocity;
int gamestate;
int oldbuttons;
int groupinfo;
// For mods
int iuser1;
int iuser2;
int iuser3;
int iuser4;
float fuser1;
float fuser2;
float fuser3;
float fuser4;
vec3_t vuser1;
vec3_t vuser2;
vec3_t vuser3;
vec3_t vuser4;
edict_t *euser1;
edict_t *euser2;
edict_t *euser3;
edict_t *euser4;
} entvars_t;

148
ext/hlsdk/util.h Normal file
View file

@ -0,0 +1,148 @@
/***
*
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef SDKUTIL_H
#define SDKUTIL_H
extern globalvars_t *globals;
extern enginefuncs_t engfuncs;
extern gamefuncs_t dllapi;
// Use this instead of ALLOC_STRING on constant strings
#define STRING(offset) (const char *)(globals->pStringBase + (int)offset)
// form fwgs-hlsdk
#if defined (CR_ARCH_X64)
static inline int MAKE_STRING (const char *val) {
long long ptrdiff = val - STRING (0);
if (ptrdiff > INT_MAX || ptrdiff < INT_MIN) {
return engfuncs.pfnAllocString (val);
}
return static_cast <int> (ptrdiff);
}
#else
#define MAKE_STRING(str) ((uint64)(str) - (uint64)(STRING(0)))
#endif
#define ENGINE_STR(str) (const_cast <char *> (STRING (engfuncs.pfnAllocString (str))))
// Dot products for view cone checking
#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
typedef enum { ignore_monsters = 1, dont_ignore_monsters = 0, missile = 2 } IGNORE_MONSTERS;
typedef enum { ignore_glass = 1, dont_ignore_glass = 0 } IGNORE_GLASS;
typedef enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 } HULL;
typedef struct hudtextparms_s {
float x;
float y;
int effect;
uint8 r1, g1, b1, a1;
uint8 r2, g2, b2, a2;
float fadeinTime;
float fadeoutTime;
float holdTime;
float fxTime;
int channel;
} hudtextparms_t;
#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation
#define AMBIENT_SOUND_EVERYWHERE 1
#define AMBIENT_SOUND_SMALLRADIUS 2
#define AMBIENT_SOUND_MEDIUMRADIUS 4
#define AMBIENT_SOUND_LARGERADIUS 8
#define AMBIENT_SOUND_START_SILENT 16
#define AMBIENT_SOUND_NOT_LOOPING 32
#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements
#define SND_SPAWNING (1 << 8) // duplicated in protocol.h we're spawing, used in some cases for ambients
#define SND_STOP (1 << 5) // duplicated in protocol.h stop sound
#define SND_CHANGE_VOL (1 << 6) // duplicated in protocol.h change sound vol
#define SND_CHANGE_PITCH (1 << 7) // duplicated in protocol.h change sound pitch
#define LFO_SQUARE 1
#define LFO_TRIANGLE 2
#define LFO_RANDOM 3
// func_rotating
#define SF_BRUSH_ROTATE_Y_AXIS 0
#define SF_BRUSH_ROTATE_INSTANT 1
#define SF_BRUSH_ROTATE_BACKWARDS 2
#define SF_BRUSH_ROTATE_Z_AXIS 4
#define SF_BRUSH_ROTATE_X_AXIS 8
#define SF_PENDULUM_AUTO_RETURN 16
#define SF_PENDULUM_PASSABLE 32
#define SF_BRUSH_ROTATE_SMALLRADIUS 128
#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256
#define SF_BRUSH_ROTATE_LARGERADIUS 512
#define PUSH_BLOCK_ONLY_X 1
#define PUSH_BLOCK_ONLY_Y 2
#define VEC_HULL_MIN Vector(-16, -16, -36)
#define VEC_HULL_MAX Vector(16, 16, 36)
#define VEC_HUMAN_HULL_MIN Vector(-16, -16, 0)
#define VEC_HUMAN_HULL_MAX Vector(16, 16, 72)
#define VEC_HUMAN_HULL_DUCK Vector(16, 16, 36)
#define VEC_VIEW Vector(0, 0, 28)
#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18)
#define VEC_DUCK_HULL_MAX Vector(16, 16, 18)
#define VEC_DUCK_VIEW Vector(0, 0, 12)
#define SVC_TEMPENTITY 23
#define SVC_CENTERPRINT 26
#define SVC_INTERMISSION 30
#define SVC_CDTRACK 32
#define SVC_WEAPONANIM 35
#define SVC_ROOMTYPE 37
#define SVC_DIRECTOR 51
// triggers
#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger
#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger
#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger
// func breakable
#define SF_BREAK_TRIGGER_ONLY 1 // may only be broken by trigger
#define SF_BREAK_TOUCH 2 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 4 // can be broken by a player standing on it
#define SF_BREAK_CROWBAR 256 // instant break if hit with crowbar
// func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 128
#define SF_LIGHT_START_OFF 1
#define SPAWNFLAG_NOMESSAGE 1
#define SPAWNFLAG_NOTOUCH 1
#define SPAWNFLAG_DROIDONLY 4
#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons)
#define TELE_PLAYER_ONLY 1
#define TELE_SILENT 2
#define SF_TRIG_PUSH_ONCE 1
#endif