fteqw/plugins/plugin.h

453 lines
16 KiB
C
Raw Normal View History

#ifndef __PLUGIN_H__
#define __PLUGIN_H__
#ifdef FTEENGINE
//included from fte itself, to borrow typedefs
#elif defined(FTEPLUGIN)
//plugin that needs fte internals
#include "quakedef.h"
#else
//moderately generic plugin
#ifdef __cplusplus
typedef enum {qfalse, qtrue} qboolean;
#else
typedef enum {qfalse, qtrue} qboolean;
#define false qfalse
#define true qtrue
#endif
typedef float vec3_t[3];
typedef unsigned char qbyte;
#include <stdint.h>
#define quint64_t uint64_t
typedef quint64_t qofs_t;
typedef struct cvar_s cvar_t;
typedef struct usercmd_s usercmd_t;
typedef struct vfsfile_s vfsfile_t;
typedef struct netadr_s netadr_t;
enum fs_relative;
struct searchpathfuncs_s;
#endif
#ifdef _WIN32
# ifndef strcasecmp
# define strcasecmp stricmp
# define strncasecmp strnicmp
# endif
# if defined(_MSC_VER) && _MSC_VER >= 1900
# define Q_vsnprintf vsnprintf
# define Q_snprintf snprintf
# endif
#else
# define stricmp strcasecmp
# define strnicmp strncasecmp
#endif
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <time.h>
#ifndef _VM_H
#if __STDC_VERSION__ >= 199901L || defined(__GNUC__)
//C99 has a stdint header which hopefully contains an intptr_t
//its optional... but if its not in there then its unlikely you'll actually be able to get the engine to a stage where it *can* load anything
#include <stdint.h>
#define qintptr_t intptr_t
#define quintptr_t uintptr_t
#else
#ifdef _WIN64
typedef long long qintptr_t;
typedef unsigned long long quintptr_t;
#else
#if !defined(_MSC_VER) || _MSC_VER < 1300
#define __w64
#endif
typedef long __w64 qintptr_t;
typedef unsigned long __w64 quintptr_t;
#endif
#endif
#endif
#ifndef NATIVEEXPORT
#ifdef _WIN32
#define NATIVEEXPORTPROTO __declspec(dllexport)
#define NATIVEEXPORT NATIVEEXPORTPROTO
#else
#define NATIVEEXPORTPROTO
#define NATIVEEXPORT __attribute__((visibility("default")))
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
//DLLs need a wrapper to add the extra parameter and call a boring function.
#ifndef QDECL
#ifdef _WIN32
#define QDECL __cdecl
#else
#define QDECL
#endif
#endif
#ifndef LIKEPRINTF
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
#else
#define LIKEPRINTF(x)
#endif
#endif
#ifndef NATIVEEXPORT
#define NATIVEEXPORT QDECL
#endif
typedef int qhandle_t;
typedef void* funcptr_t;
#define PLUGMAX_SCOREBOARDNAME 64
typedef struct {
int topcolour;
int bottomcolour;
int frags;
char name[PLUGMAX_SCOREBOARDNAME];
int ping;
int pl;
int activetime;
int userid;
int spectator;
char userinfo[2048];
char team[64];
} plugclientinfo_t;
typedef struct
{
unsigned int client;
unsigned int items;
float armor;
float health;
vec3_t org;
char nick[16];
} teamplayerinfo_t;
typedef struct {
size_t structsize;
int seats;
struct
{
float s_avg;
float s_mn;
float s_mx;
float ms_stddev; //calculated in milliseconds for more sane numbers
float fr_avg;
int fr_mn;
int fr_mx;
} ping;
struct
{ //decimals
float dropped;
float choked;
float invalid;
} loss;
float mlatency;
float mrate;
float vlatency;
float vrate;
vec3_t speed; //player speed
struct
{
float in_pps;
float in_bps;
float out_pps;
float out_bps;
} clrate;
struct
{
float in_pps;
float in_bps;
float out_pps;
float out_bps;
} svrate;
int capturing; //avi capturing
} plugnetinfo_t;
struct wstats_s;
#define F(t, n, args) t (QDECL *n) args
#define dllhandle_t void
struct dllfunction_s;
typedef struct //core stuff
{
//Basic builtins:
F(void*, GetEngineInterface, (const char *interfacename, size_t structsize)); //retrieve a named interface struct from the engine
F(qboolean, ExportFunction, (const char *funcname, funcptr_t funcptr)); //export a named function to the engine
F(qboolean, ExportInterface, (const char *interfacename, void *interfaceptr, size_t structsize)); //export a named interface struct to the engine
F(qboolean, GetPluginName, (int plugnum, char *buffer, size_t bufsize)); //query loaded plugin names. -1 == active plugin
F(void, Print, (const char *message)); //print on (main) console.
F(void, Error, (const char *message)); //abort the entire engine.
F(quintptr_t,GetMilliseconds, (void));
F(dllhandle_t*,LoadDLL, (const char *modulename, struct dllfunction_s *funcs));
F(void*, GetDLLSymbol, (dllhandle_t *handle, const char *symbolname));
F(void, CloseDLL, (dllhandle_t *handle)); //not guarenteed to actually do anything, of course.
//general memory (mallocs and frees over dll boundaries is not usable on windows)
F(void*, Malloc, (size_t size));
F(void*, Realloc, (void *memptr, size_t size)); //doesn't zero-fill, so faster (when memptr is NULL).
F(void, Free, (void *memptr));
//for lazy mallocs
F(void*, GMalloc, (struct zonegroup_s *ctx, size_t size));
F(void, GFreeAll, (struct zonegroup_s *ctx));
#define plugcorefuncs_name "Core"
} plugcorefuncs_t;
typedef struct //subconsole handling
{
F(qhandle_t,POpen, (const char *conname));
F(qboolean, SubPrint, (const char *subname, const char *text)); //on to sub console.
F(qboolean, RenameSub, (const char *oldname, const char *newname)); //rename a console.
F(qboolean, IsActive, (const char *conname));
F(qboolean, SetActive, (const char *conname));
F(qboolean, Destroy, (const char *conname));
F(qboolean, NameForNum, (qintptr_t connum, char *conname, size_t connamelen));
F(float, GetConsoleFloat, (const char *conname, const char *attribname));
F(qboolean, SetConsoleFloat, (const char *conname, const char *attribname, float newvalue));
F(qboolean, GetConsoleString, (const char *conname, const char *attribname, char *outvalue, size_t valuesize));
F(qboolean, SetConsoleString, (const char *conname, const char *attribname, const char *newvalue));
#define plugsubconsolefuncs_name "SubConsole"
} plugsubconsolefuncs_t;
enum com_tokentype_e;
typedef struct //console command/tokenizing/cbuf functions
{
F(const char *,QuotedString, (const char *string, char *buf, int buflen, qboolean omitquotes)); //generates a string with c-style markup and relevant quote types.
F(char *, ParseToken, (const char *data, char *token, size_t tokenlen, enum com_tokentype_e *tokentype)); //standard quake-style token parsing.
F(char *, ParsePunctuation, (const char *data, const char *punctuation, char *token, size_t tokenlen, enum com_tokentype_e *tokentype)); //use explicit punctuation.
F(void, TokenizeString, (const char *msg)); //tokenize a string.
F(void, Args, (char *buffer, int bufsize)); //Gets the extra args
F(void, Argv, (int argnum, char *buffer, size_t bufsize)); //Gets a 0-based token
F(int, Argc, (void)); //gets the number of tokens available.
F(qboolean, AddCommand, (const char *cmdname)); //Registers a console command.
F(void, AddText, (const char *text, qboolean insert));
#define plugcmdfuncs_name "Cmd"
} plugcmdfuncs_t;
typedef struct //console command and cbuf functions
{
F(void, SetString, (const char *name, const char *value));
F(void, SetFloat, (const char *name, float value));
F(qboolean, GetString, (const char *name, char *retstring, quintptr_t sizeofretstring));
F(float, GetFloat, (const char *name));
F(qhandle_t,Register, (const char *name, const char *defaultval, int flags, const char *grouphint));
F(qboolean, Update, (qhandle_t handle, int *modificationcount, char *outstringv, size_t stringsize, float *outfloatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
F(cvar_t*, GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname));
#define plugcvarfuncs_name "Cvar"
} plugcvarfuncs_t;
typedef struct
{
F(void, LocalSound, (const char *soundname, int channel, float volume));
F(void, RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume));
#define plugaudiofuncs_name "Audio"
} plugaudiofuncs_t;
typedef struct
{
F(void, BlockSizeForEncoding,(uploadfmt_t encoding, unsigned int *blockbytes, unsigned int *blockwidth, unsigned int *blockheight, unsigned int *blockdepth));
F(const char *,FormatName, (uploadfmt_t encoding));
#define plugimagefuncs_name "Image"
} plugimagefuncs_t;
typedef struct //q1 client/network info
{
F(int, GetStats, (int seat, unsigned int *stats, int maxstats));
F(void, GetPlayerInfo, (int seat, plugclientinfo_t *info));
F(size_t, GetNetworkInfo, (plugnetinfo_t *ni, size_t sizeofni));
F(size_t, GetLocalPlayerNumbers,(size_t firstseat, size_t numseats, int *playernums, int *spectracks));
F(void, GetLocationName, (const float *pos, char *outbuffer, size_t bufferlen));
F(qboolean, GetLastInputFrame, (int seat, usercmd_t *outcmd));
F(void, GetServerInfo, (char *info, size_t infolen));
F(void, SetUserInfo, (int seat, const char *key, const char *value));
//EBUILTIN(void, SCR_CenterPrint, (const char *s));
//FIXME: does this belong here?
F(qboolean, MapLog_Query, (const char *packagename, const char *mapname, float *stats));
F(size_t, GetTeamInfo, (teamplayerinfo_t *clients, size_t maxclients, qboolean showenemies, int seat));
F(int, GetWeaponStats, (int player, struct wstats_s *result, size_t maxresults));
F(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
fixed eztv md4 incompatibility. reimplemented qtvreverse command. fixed some stuffcmds being handled by the wrong splitscreen seats (was noticable in TF). rework smartjump to try to be more predictable... rework relighting to try to be more robust (and more self-contained). allow the csqc to actually use VF_PROJECTIONOFFSET. jump now moves upwards instead of trying to lock on to a nearby player when spectating. assume 32 fullbright pixels when running with a palette.lmp yet no colormap.lmp (happens with some total conversions). tweaked scoreboard for fainter backgrounds. rearranged autoid, to be smaller etc. hacked around dodgy conchars.lmp - don't treat 128*128 qpics as qpics to work around workarounds for buggy wad tools (with a warning). fixed missing fullbrights on h2holey models. avoided warning about mod_h2holey_bugged on dedicated servers. added net_ice_exchangeprivateips, for people worried about exposing lan IPs when using ICE. sv_public 2: implemented client support for our webrtc broker in order to use our own ICE implementation without needing to faff around with irc accounts or plugins etc. TODO: ensure at least one ephemerial udp port when using ice or come up with some better sv_port handling fixed multiple tls bugs (one could cause server problems). change net_enable_tls to disabled by default anyway (reenable for the server to be able to respond to https/wss/tls schemes again). don't colourmap when there appears to be a highres diffusemap on q1 models. imgtool now understands exporting from qpics in wads, as well as just mips. implemented speed-o-meter in ezhud. added removeinstant builtin to avoid the half-second rule. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5614 fc73d0e0-1445-4013-8a0c-d673dee63da5
2020-02-11 18:06:10 +00:00
F(void, GetPredInfo, (int seat, vec3_t outvel));
#define plugclientfuncs_name "Client"
} plugclientfuncs_t;
typedef struct //for menu-like stuff
{
//for menus
F(qboolean, SetMenuFocus, (qboolean wantkeyfocus, const char *cursorname, float hot_x, float hot_y, float scale)); //null cursorname=relmouse, set/empty cursorname=absmouse
F(qboolean, HasMenuFocus, (void));
//for menu input
F(int, GetKeyCode, (const char *keyname, int *out_modifier));
F(const char*,GetKeyName, (int keycode, int modifier));
F(int, FindKeysForCommand,(int bindmap, const char *command, int *out_keycodes, int *out_modifiers, int maxkeys));
F(const char*,GetKeyBind, (int bindmap, int keynum, int modifier));
F(void, SetKeyBind, (int bindmap, int keycode, int modifier, const char *newbinding));
unsigned int (*GetKeyDest) (void);
void (*KeyEvent) (unsigned int devid, int down, int keycode, int unicode);
void (*MouseMove) (unsigned int devid, int abs, float x, float y, float z, float size);
void (*JoystickAxisEvent) (unsigned int devid, int axis, float value);
void (*Accelerometer) (unsigned int devid, float x, float y, float z);
void (*Gyroscope) (unsigned int devid, float pitch, float yaw, float roll);
qboolean (*SetHandPosition) (const char *devname, vec3_t org, vec3_t ang, vec3_t vel, vec3_t avel); //for VR.
#define pluginputfuncs_name "Input"
} pluginputfuncs_t;
typedef struct //for huds and menus alike
{
//note: these use handles instead of shaders, to make them persistent over renderer restarts.
F(qhandle_t,LoadImageData, (const char *name, const char *mime, void *data, size_t datasize)); //load/replace a named texture
F(qhandle_t,LoadImageShader,(const char *name, const char *defaultshader)); //loads a shader.
F(qhandle_t,LoadImage, (const char *name, qboolean iswadimage)); //wad image is ONLY for loading out of q1 gfx.wad. loads a shader.
F(void, UnloadImage, (qhandle_t image));
F(int, Image, (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image));
F(int, ImageSize, (qhandle_t image, float *x, float *y));
F(void, Fill, (float x, float y, float w, float h));
F(void, Line, (float x1, float y1, float x2, float y2));
F(void, Character, (float x, float y, unsigned int character));
F(void, String, (float x, float y, const char *string));
F(void, CharacterH, (float x, float y, float h, unsigned int flags, unsigned int character));
F(void, StringH, (float x, float y, float h, unsigned int flags, const char *string)); //returns the vpixel width of the (coloured) string, in the current (variable-width) font.
F(float, StringWidth, (float h, unsigned int flags, const char *string));
F(void, Colourpa, (int palcol, float a)); //for legacy code
F(void, Colour4f, (float r, float g, float b, float a));
F(void, LocalSound, (const char *soundname, int channel, float volume));
#define plug2dfuncs_name "2D"
} plug2dfuncs_t;
typedef struct //for plugins that need to read/write files...
{
F(int, Open, (const char *name, qhandle_t *handle, int mode));
F(void, Close, (qhandle_t handle));
F(int, Write, (qhandle_t handle, void *data, int len));
F(int, Read, (qhandle_t handle, void *data, int len));
F(int, Seek, (qhandle_t handle, qofs_t offset));
F(qboolean, GetLen, (qhandle_t handle, qofs_t *outsize));
F(vfsfile_t*,OpenVFS, (const char *filename, const char *mode, enum fs_relative relativeto)); //opens a direct vfs file, without any access checks, and so can be used in threaded plugins
F(qboolean, NativePath, (const char *name, enum fs_relative relativeto, char *out, int outlen));
F(void, EnumerateFiles, (const char *match, int (QDECL *callback)(const char *fname, qofs_t fsize, time_t mtime, void *ctx, struct searchpathfuncs_s *package), void *ctx));
//helpers
F(int, WildCmp, (const char *wild, const char *string));
F(const char *,GetExtension,(const char *filename, const char *ignoreext));
F(void, FileBase, (const char *in, char *out, int outlen));
F(void, CleanUpPath, (char *str));
F(unsigned int,BlockChecksum,(const void *buffer, int length)); //mostly for pack hashes.
F(qbyte*, LoadFile, (const char *fname, size_t *fsize)); //plugfuncs->Free
#define plugfsfuncs_name "Filesystem"
} plugfsfuncs_t;
typedef struct //for when you need basic socket access, hopefully rare...
{
F(qhandle_t,TCPConnect, (const char *ip, int port));
F(qhandle_t,TCPListen, (const char *localip, int port, int maxcount));
F(qhandle_t,Accept, (qhandle_t socket, char *address, int addresssize));
F(int, Recv, (qhandle_t socket, void *buffer, int len));
F(int, Send, (qhandle_t socket, void *buffer, int len));
F(int, SendTo, (qhandle_t handle, void *data, int datasize, netadr_t *dest));
F(void, Close, (qhandle_t socket));
F(int, SetTLSClient, (qhandle_t sock, const char *certhostname)); //adds a tls layer to the socket (and specifies the peer's required hostname)
F(int, GetTLSBinding, (qhandle_t sock, char *outdata, int *datalen)); //to avoid MITM attacks with compromised cert authorities
#define N_WOULDBLOCK -1
#define N_FATALERROR -2
#define NET_CLIENTPORT -1
#define NET_SERVERPORT -2
#define plugnetfuncs_name "Net"
} plugnetfuncs_t;
#undef F
extern plugcorefuncs_t *plugfuncs;
extern plugcmdfuncs_t *cmdfuncs;
extern plugcvarfuncs_t *cvarfuncs;
#ifdef FTEENGINE
extern plugcorefuncs_t plugcorefuncs;
#else
void Q_strlncpy(char *d, const char *s, int sizeofd, int lenofs);
void Q_strlcpy(char *d, const char *s, int n);
void Q_strlcat(char *d, const char *s, int n);
qboolean VARGS Q_vsnprintfz (char *dest, size_t size, const char *fmt, va_list argptr);
qboolean VARGS Q_snprintfz (char *dest, size_t size, const char *fmt, ...) LIKEPRINTF(3);
#define Q_snprintf (void)Q_snprintfz
#define Q_vsnprintf (void)Q_vsnprintfz
char *va(const char *format, ...);
qboolean Plug_Init(void);
void Con_Printf(const char *format, ...);
void Con_DPrintf(const char *format, ...); //not a particuarly efficient implementation, so beware.
void Sys_Errorf(const char *format, ...);
void QDECL Q_strncpyz(char *d, const char *s, int n);
#define PLUG_SHARED_BEGIN(t,p,b) \
{ \
t *p; \
char inputbuffer[8192]; \
*(b) = ReadInputBuffer(inputbuffer, sizeof(inputbuffer)); \
if (*(b)) \
p = (t*)inputbuffer; \
else \
p = NULL;
#define PLUG_SHARED_END(p,b) UpdateInputBuffer(inputbuffer, b);}
typedef struct {
char *name;
char string[256];
char *group;
int flags;
float value;
qhandle_t handle;
int modificationcount;
} vmcvar_t;
#define VMCvar_Register(cv) (cv->handle=cvarfuncs->Register(cv->name, cv->string, cv->flags, cv->group))
#define VMCvar_Update(cv) cvarfuncs->Update(handle, &cv->modcount, cv->string, sizeof(cv->string), &cv->value)
#define VMCvar_SetString(c,v) \
do{ \
strcpy(c->string, v); \
c->value = (float)atof(v); \
Cvar_SetString(c->name, c->string); \
} while (0)
#define VMCvar_SetFloat(c,v) \
do { \
snprintf(c->string, sizeof(c->string), "%f", v);\
c->value = (float)(v); \
Cvar_SetFloat(c->name, c->value); \
} while(0) \
char *Plug_Info_ValueForKey (const char *s, const char *key, char *out, size_t outsize);
#endif
#ifdef __cplusplus
}
#endif
#endif