mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-30 07:31:13 +00:00
c08a0aa139
try to appease msvc6, just because. update the downloads menu. now even betterer!... fix proquake server angle snapping precision issue. also accept _glow textures as an alternative to the more standard _luma. compat for dp_water shader terms. tcgen stuff is still fscked up. menu tooltip code can now properly deal with variable width etc stuff. add missing te_flamejet builtin. r_dynamic -1 can now cope with q3bsp for a small speedup. added -watch commandline arg, to make it easier to figure out where cvar changes are coming from. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5015 fc73d0e0-1445-4013-8a0c-d673dee63da5
1601 lines
38 KiB
C
1601 lines
38 KiB
C
#include "quakedef.h"
|
|
#include "shader.h"
|
|
|
|
#ifdef _WIN32
|
|
#include "winquake.h"
|
|
#endif
|
|
|
|
#ifdef HLCLIENT
|
|
extern unsigned int r2d_be_flags;
|
|
struct hlcvar_s *QDECL GHL_CVarGetPointer(char *varname);
|
|
|
|
|
|
|
|
#if defined(_MSC_VER)
|
|
# if _MSC_VER >= 1300
|
|
# define __func__ __FUNCTION__
|
|
# else
|
|
# define __func__ "unknown"
|
|
# endif
|
|
#else
|
|
//I hope you're c99 and have a __func__
|
|
#endif
|
|
|
|
//extern cvar_t temp1;
|
|
#define ignore(s) Con_Printf("Fixme: " s "\n")
|
|
#define notimpl(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l)
|
|
#define notimpf(f) Con_Printf("halflife cl builtin %s not implemented\n", f)
|
|
#define notimp() Con_Printf("halflife cl builtin %s not implemented\n", __func__)
|
|
#define bi_begin() //if (temp1.ival)Con_Printf("enter %s\n", __func__)
|
|
#define bi_end() //if (temp1.ival)Con_Printf("leave %s\n", __func__)
|
|
#define bi_trace() bi_begin(); bi_end()
|
|
|
|
#if HLCLIENT >= 1
|
|
#define HLCL_API_VERSION HLCLIENT
|
|
#else
|
|
#define HLCL_API_VERSION 7
|
|
#endif
|
|
|
|
|
|
|
|
void *vgui_panel;
|
|
void *(QDECL *vgui_init)(void);
|
|
void (QDECL *vgui_frame)(void);
|
|
void (QDECL *vgui_key)(int down, int scan);
|
|
void (QDECL *vgui_mouse)(int x, int y);
|
|
|
|
qboolean VGui_Setup(void)
|
|
{
|
|
void *vguidll;
|
|
|
|
dllfunction_t funcs[] =
|
|
{
|
|
{(void*)&vgui_init, "init"},
|
|
{(void*)&vgui_frame, "frame"},
|
|
{(void*)&vgui_key, "key"},
|
|
{(void*)&vgui_mouse, "mouse"},
|
|
{NULL}
|
|
};
|
|
|
|
vguidll = Sys_LoadLibrary("vguiwrap", funcs);
|
|
|
|
if (vguidll)
|
|
vgui_panel = vgui_init();
|
|
return !!vgui_panel;
|
|
}
|
|
|
|
|
|
|
|
#define HLPIC model_t*
|
|
|
|
typedef struct
|
|
{
|
|
int l;
|
|
int r;
|
|
int t;
|
|
int b;
|
|
} hlsubrect_t;
|
|
|
|
typedef struct
|
|
{
|
|
vec3_t origin;
|
|
|
|
#if HLCL_API_VERSION >= 7
|
|
vec3_t viewangles;
|
|
int weapons;
|
|
float fov;
|
|
#else
|
|
float viewheight;
|
|
float maxspeed;
|
|
vec3_t viewangles;
|
|
vec3_t punchangles;
|
|
int keys;
|
|
int weapons;
|
|
float fov;
|
|
float idlescale;
|
|
float mousesens;
|
|
#endif
|
|
} hllocalclientdata_t;
|
|
|
|
typedef struct
|
|
{
|
|
short lerpmsecs;
|
|
qbyte msec;
|
|
//pad1
|
|
vec3_t viewangles;
|
|
float forwardmove;
|
|
float sidemove;
|
|
float upmove;
|
|
qbyte lightlevel;
|
|
//pad1
|
|
unsigned short buttons;
|
|
qbyte impulse;
|
|
qbyte weaponselect;
|
|
//pad2
|
|
int impact_index;
|
|
vec3_t impact_position;
|
|
} hlusercmd_t;
|
|
|
|
typedef struct
|
|
{
|
|
char name[64];
|
|
char sprite[64];
|
|
int unk;
|
|
int forscrwidth;
|
|
hlsubrect_t rect;
|
|
} hlspriteinf_t;
|
|
|
|
typedef struct
|
|
{
|
|
char *name;
|
|
short ping;
|
|
qbyte isus;
|
|
qbyte isspec;
|
|
qbyte pl;
|
|
//pad3
|
|
char *model;
|
|
short tcolour;
|
|
short bcolour;
|
|
} hlplayerinfo_t;
|
|
|
|
typedef struct
|
|
{
|
|
int size;
|
|
int width;
|
|
int height;
|
|
int flags;
|
|
int charheight;
|
|
short charwidths[256];
|
|
} hlscreeninfo_t;
|
|
|
|
typedef struct
|
|
{
|
|
int effect;
|
|
byte_vec4_t c1;
|
|
byte_vec4_t c2;
|
|
float x;
|
|
float y;
|
|
float fadein;
|
|
float fadeout;
|
|
float holdtime;
|
|
float fxtime;
|
|
char *name;
|
|
char *message;
|
|
} hlmsginfo_t;
|
|
|
|
typedef struct
|
|
{
|
|
HLPIC (QDECL *pic_load) (char *picname);
|
|
int (QDECL *pic_getnumframes) (HLPIC pic);
|
|
int (QDECL *pic_getheight) (HLPIC pic, int frame);
|
|
int (QDECL *pic_getwidth) (HLPIC pic, int frame);
|
|
void (QDECL *pic_select) (HLPIC pic, int r, int g, int b);
|
|
void (QDECL *pic_drawcuropaque) (int frame, int x, int y, void *loc);
|
|
void (QDECL *pic_drawcuralphatest) (int frame, int x, int y, void *loc);
|
|
void (QDECL *pic_drawcuradditive) (int frame, int x, int y, void *loc);
|
|
void (QDECL *pic_enablescissor) (int x, int y, int width, int height);
|
|
void (QDECL *pic_disablescissor) (void);
|
|
hlspriteinf_t *(QDECL *pic_parsepiclist) (char *filename, int *numparsed);
|
|
|
|
void (QDECL *fillrgba) (int x, int y, int width, int height, int r, int g, int b, int a);
|
|
int (QDECL *getscreeninfo) (hlscreeninfo_t *info);
|
|
void (QDECL *setcrosshair) (HLPIC pic, hlsubrect_t rect, int r, int g, int b); //I worry about stuff like this
|
|
|
|
struct hlcvar_s *(QDECL *cvar_register) (char *name, char *defvalue, int flags);
|
|
float (QDECL *cvar_getfloat) (char *name);
|
|
char *(QDECL *cvar_getstring) (char *name);
|
|
|
|
void (QDECL *cmd_register) (char *name, void (*func) (void));
|
|
void (QDECL *hooknetmsg) (char *msgname, void *func);
|
|
void (QDECL *forwardcmd) (char *command);
|
|
void (QDECL *localcmd) (char *command);
|
|
|
|
void (QDECL *getplayerinfo) (int entnum, hlplayerinfo_t *result);
|
|
|
|
void (QDECL *startsound_name) (char *name, float vol);
|
|
void (QDECL *startsound_idx) (int idx, float vol);
|
|
|
|
void (QDECL *anglevectors) (float *ina, float *outf, float *outr, float *outu);
|
|
|
|
hlmsginfo_t *(QDECL *get_message_info) (char *name); //translated+scaled+etc intro stuff
|
|
int (QDECL *drawchar) (int x, int y, int charnum, int r, int g, int b);
|
|
int (QDECL *drawstring) (int x, int y, char *string);
|
|
#if HLCL_API_VERSION >= 7
|
|
void (QDECL *settextcolour) (float r, float b, float g);
|
|
#endif
|
|
void (QDECL *drawstring_getlen) (char *string, int *outlen, int *outheight);
|
|
void (QDECL *consoleprint) (char *str);
|
|
void (QDECL *centerprint) (char *str);
|
|
|
|
#if HLCL_API_VERSION >= 7
|
|
int (QDECL *getwindowcenterx)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function.
|
|
int (QDECL *getwindowcentery)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function.
|
|
void (QDECL *getviewnangles)(float*ang);
|
|
void (QDECL *setviewnangles)(float*ang);
|
|
void (QDECL *getmaxclients)(float*ang);
|
|
void (QDECL *cvar_setvalue)(char *cvarname, char *value);
|
|
|
|
int (QDECL *cmd_argc)(void);
|
|
char *(QDECL *cmd_argv)(int i);
|
|
void (QDECL *con_printf)(char *fmt, ...);
|
|
void (QDECL *con_dprintf)(char *fmt, ...);
|
|
void (QDECL *con_notificationprintf)(int pos, char *fmt, ...);
|
|
void (QDECL *con_notificationprintfex)(void *info, char *fmt, ...); //arg1 is of specific type
|
|
char *(QDECL *physkey)(char *key);
|
|
char *(QDECL *serverkey)(char *key);
|
|
float (QDECL *getclientmaxspeed)(void);
|
|
int (QDECL *checkparm)(char *str, char **next);
|
|
int (QDECL *keyevent)(int key, int down);
|
|
void (QDECL *getmousepos)(int *outx, int *outy);
|
|
int (QDECL *movetypeisnoclip)(void);
|
|
struct hlclent_s *(QDECL *getlocalplayer)(void);
|
|
struct hlclent_s *(QDECL *getviewent)(void);
|
|
struct hlclent_s *(QDECL *getentidx)(int idx);
|
|
float (QDECL *getlocaltime)(void);
|
|
void (QDECL *calcshake)(void);
|
|
void (QDECL *applyshake)(float *,float *,float);
|
|
int (QDECL *pointcontents)(float *point, float *truecon);
|
|
int (QDECL *waterentity)(float *point);
|
|
void (QDECL *traceline) (float *start, float *end, int flags, int hull, int forprediction);
|
|
|
|
model_t *(QDECL *loadmodel)(char *modelname, int *mdlindex);
|
|
int (QDECL *addrentity)(int type, void *ent);
|
|
|
|
model_t *(QDECL *modelfrompic) (HLPIC pic);
|
|
void (QDECL *soundatloc)(char*sound, float volume, float *org);
|
|
|
|
unsigned short (QDECL *precacheevent)(int evtype, char *name);
|
|
void (QDECL *playevent)(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2);
|
|
void (QDECL *weaponanimate)(int anim, int body);
|
|
float (QDECL *randfloat) (float minv, float maxv);
|
|
long (QDECL *randlong) (long minv, long maxv);
|
|
void (QDECL *hookevent) (char *name, void (*func)(struct hlevent_s *event));
|
|
int (QDECL *con_isshown) (void);
|
|
char *(QDECL *getgamedir) (void);
|
|
struct hlcvar_s *(QDECL *cvar_find) (char *name);
|
|
char *(QDECL *lookupbinding) (char *command);
|
|
char *(QDECL *getlevelname) (void);
|
|
void (QDECL *getscreenfade) (struct hlsfade_s *fade);
|
|
void (QDECL *setscreenfade) (struct hlsfade_s *fade);
|
|
void *(QDECL *vgui_getpanel) (void);
|
|
void (QDECL *vgui_paintback) (int extents[4]);
|
|
|
|
void *(QDECL *loadfile) (char *path, int onhunk, int *length);
|
|
char *(QDECL *parsefile) (char *data, char *token);
|
|
void (QDECL *freefile) (void *file);
|
|
|
|
struct hl_tri_api_s
|
|
{
|
|
int vers;
|
|
int sentinal;
|
|
} *triapi;
|
|
struct hl_sfx_api_s
|
|
{
|
|
int vers;
|
|
int sentinal;
|
|
} *efxapi;
|
|
struct hl_event_api_s
|
|
{
|
|
int vers;
|
|
int sentinal;
|
|
} *eventapi;
|
|
struct hl_demo_api_s
|
|
{
|
|
int (QDECL *isrecording)(void);
|
|
int (QDECL *isplaying)(void);
|
|
int (QDECL *istimedemo)(void);
|
|
void (QDECL *writedata)(int size, void *data);
|
|
|
|
int sentinal;
|
|
} *demoapi;
|
|
struct hl_net_api_s
|
|
{
|
|
int vers;
|
|
int sentinal;
|
|
} *netapi;
|
|
|
|
struct hl_voicetweek_s
|
|
{
|
|
int sentinal;
|
|
} *voiceapi;
|
|
|
|
int (QDECL *forcedspectator) (void);
|
|
model_t *(QDECL *loadmapsprite) (char *name);
|
|
|
|
void (QDECL *fs_addgamedir) (char *basedir, char *appname);
|
|
int (QDECL *expandfilename) (char *filename, char *outbuff, int outsize);
|
|
|
|
char *(QDECL *player_key) (int pnum, char *key);
|
|
void (QDECL *player_setkey) (char *key, char *value); //wait, no pnum?
|
|
|
|
qboolean (QDECL *getcdkey) (int playernum, char key[16]);
|
|
int (QDECL *trackerfromplayer) (int pl);
|
|
int (QDECL *playerfromtracker) (int tr);
|
|
int (QDECL *sendcmd_unreliable) (char *cmd);
|
|
void (QDECL *getsysmousepos) (long *xandy);
|
|
void (QDECL *setsysmousepos) (int x, int y);
|
|
void (QDECL *setmouseenable) (qboolean enable);
|
|
#endif
|
|
|
|
int sentinal;
|
|
} CLHL_enginecgamefuncs_t;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
int (QDECL *HUD_VidInit) (void);
|
|
int (QDECL *HUD_Init) (void);
|
|
int (QDECL *HUD_Shutdown) (void);
|
|
int (QDECL *HUD_Redraw) (float maptime, int inintermission);
|
|
int (QDECL *HUD_UpdateClientData) (hllocalclientdata_t *localclientdata, float maptime);
|
|
int (QDECL *HUD_Reset) (void);
|
|
#if HLCL_API_VERSION >= 7
|
|
void (QDECL *CL_CreateMove) (float frametime, hlusercmd_t *cmd, int isplaying);
|
|
void (QDECL *IN_ActivateMouse) (void);
|
|
void (QDECL *IN_DeactivateMouse) (void);
|
|
void (QDECL *IN_MouseEvent) (int buttonmask);
|
|
#endif
|
|
} CLHL_cgamefuncs_t;
|
|
|
|
|
|
|
|
//FIXME
|
|
typedef struct
|
|
{
|
|
vec3_t origin;
|
|
vec3_t oldorigin;
|
|
|
|
int firstframe;
|
|
int numframes;
|
|
|
|
int type;
|
|
vec3_t angles;
|
|
int flags;
|
|
float alpha;
|
|
float start;
|
|
float framerate;
|
|
model_t *model;
|
|
int skinnum;
|
|
} explosion_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
{
|
|
char name[64];
|
|
int (QDECL *hook) (char *name, int bufsize, void *bufdata);
|
|
} CLHL_UserMessages_t;
|
|
CLHL_UserMessages_t usermsgs[256];
|
|
|
|
int numnewhooks;
|
|
CLHL_UserMessages_t pendingusermsgs[256];
|
|
|
|
|
|
static HLPIC selectedpic;
|
|
|
|
float hl_viewmodelsequencetime;
|
|
int hl_viewmodelsequencecur;
|
|
int hl_viewmodelsequencebody;
|
|
|
|
|
|
|
|
|
|
|
|
HLPIC QDECL CLGHL_pic_load (char *picname)
|
|
{
|
|
void *ret;
|
|
bi_begin();
|
|
ret = Mod_ForName(picname, false);
|
|
bi_end();
|
|
return ret;
|
|
// return R2D_SafeCachePic(picname);
|
|
}
|
|
int QDECL CLGHL_pic_getnumframes (HLPIC pic)
|
|
{
|
|
bi_trace();
|
|
if (pic)
|
|
return pic->numframes;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static mspriteframe_t *getspriteframe(HLPIC pic, int frame)
|
|
{
|
|
msprite_t *psprite;
|
|
mspritegroup_t *pgroup;
|
|
bi_trace();
|
|
if (!pic)
|
|
return NULL;
|
|
psprite = pic->meshinfo;
|
|
if (!psprite)
|
|
return NULL;
|
|
|
|
if (psprite->frames[frame].type == SPR_SINGLE)
|
|
return psprite->frames[frame].frameptr;
|
|
else
|
|
{
|
|
pgroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
|
|
return pgroup->frames[0];
|
|
}
|
|
}
|
|
static mpic_t *getspritepic(HLPIC pic, int frame)
|
|
{
|
|
mspriteframe_t *f;
|
|
bi_trace();
|
|
f = getspriteframe(pic, frame);
|
|
if (f)
|
|
return f->shader;
|
|
return NULL;
|
|
}
|
|
|
|
int QDECL CLGHL_pic_getheight (HLPIC pic, int frame)
|
|
{
|
|
mspriteframe_t *pframe;
|
|
bi_trace();
|
|
|
|
pframe = getspriteframe(pic, frame);
|
|
if (!pframe)
|
|
return 0;
|
|
|
|
return pframe->shader->width;
|
|
}
|
|
int QDECL CLGHL_pic_getwidth (HLPIC pic, int frame)
|
|
{
|
|
mspriteframe_t *pframe;
|
|
bi_trace();
|
|
|
|
pframe = getspriteframe(pic, frame);
|
|
if (!pframe)
|
|
return 0;
|
|
|
|
return pframe->shader->height;
|
|
}
|
|
void QDECL CLGHL_pic_select (HLPIC pic, int r, int g, int b)
|
|
{
|
|
bi_trace();
|
|
selectedpic = pic;
|
|
R2D_ImageColours(r/255.0f, g/255.0f, b/255.0f, 1);
|
|
}
|
|
void QDECL CLGHL_pic_drawcuropaque (int frame, int x, int y, hlsubrect_t *loc)
|
|
{
|
|
mpic_t *pic = getspritepic(selectedpic, frame);
|
|
bi_trace();
|
|
if (!pic)
|
|
return;
|
|
|
|
//faster SW render: no blends/holes
|
|
pic->flags &= ~1;
|
|
|
|
R2D_Image(x, y,
|
|
loc->r-loc->l, loc->b-loc->t,
|
|
(float)loc->l/pic->width, (float)loc->t/pic->height,
|
|
(float)loc->r/pic->width, (float)loc->b/pic->height,
|
|
pic);
|
|
}
|
|
void QDECL CLGHL_pic_drawcuralphtest (int frame, int x, int y, hlsubrect_t *loc)
|
|
{
|
|
mpic_t *pic = getspritepic(selectedpic, frame);
|
|
bi_trace();
|
|
if (!pic)
|
|
return;
|
|
//use some kind of alpha
|
|
pic->flags |= 1;
|
|
|
|
R2D_Image(x, y,
|
|
loc->r-loc->l, loc->b-loc->t,
|
|
(float)loc->l/pic->width, (float)loc->t/pic->height,
|
|
(float)loc->r/pic->width, (float)loc->b/pic->height,
|
|
pic);
|
|
}
|
|
void QDECL CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc)
|
|
{
|
|
mpic_t *pic = getspritepic(selectedpic, frame);
|
|
|
|
bi_trace();
|
|
if (!pic)
|
|
return;
|
|
|
|
r2d_be_flags = BEF_FORCEADDITIVE;
|
|
|
|
//use some kind of alpha
|
|
pic->flags |= 1;
|
|
if (loc)
|
|
{
|
|
R2D_Image(x, y,
|
|
loc->r-loc->l, loc->b-loc->t,
|
|
(float)loc->l/pic->width, (float)loc->t/pic->height,
|
|
(float)loc->r/pic->width, (float)loc->b/pic->height,
|
|
pic);
|
|
}
|
|
else
|
|
{
|
|
R2D_Image(x, y,
|
|
pic->width, pic->height,
|
|
0, 0,
|
|
1, 1,
|
|
pic);
|
|
}
|
|
r2d_be_flags = 0;
|
|
}
|
|
void QDECL CLGHL_pic_enablescissor (int x, int y, int width, int height)
|
|
{
|
|
srect_t srect;
|
|
|
|
bi_trace();
|
|
|
|
srect.x = x / vid.width;
|
|
srect.y = y / vid.height;
|
|
srect.width = width / vid.width;
|
|
srect.height = height / vid.height;
|
|
srect.dmin = -99999;
|
|
srect.dmax = 99999;
|
|
srect.y = (1-srect.y) - srect.height;
|
|
BE_Scissor(&srect);
|
|
}
|
|
void QDECL CLGHL_pic_disablescissor (void)
|
|
{
|
|
bi_trace();
|
|
BE_Scissor(NULL);
|
|
}
|
|
hlspriteinf_t *QDECL CLGHL_pic_parsepiclist (char *filename, int *numparsed)
|
|
{
|
|
hlspriteinf_t *result;
|
|
int entry;
|
|
int entries;
|
|
void *file;
|
|
char *pos;
|
|
|
|
bi_trace();
|
|
|
|
*numparsed = 0;
|
|
|
|
FS_LoadFile(filename, &file);
|
|
if (!file)
|
|
return NULL;
|
|
pos = file;
|
|
|
|
pos = COM_Parse(pos);
|
|
entries = atoi(com_token);
|
|
|
|
//name, res, pic, x, y, w, h
|
|
|
|
result = Z_Malloc(sizeof(*result)*entries);
|
|
for (entry = 0; entry < entries; entry++)
|
|
{
|
|
pos = COM_Parse(pos);
|
|
Q_strncpyz(result[entry].name, com_token, sizeof(result[entry].name));
|
|
|
|
pos = COM_Parse(pos);
|
|
result[entry].forscrwidth = atoi(com_token);
|
|
|
|
pos = COM_Parse(pos);
|
|
Q_strncpyz(result[entry].sprite, com_token, sizeof(result[entry].name));
|
|
|
|
pos = COM_Parse(pos);
|
|
result[entry].rect.l = atoi(com_token);
|
|
|
|
pos = COM_Parse(pos);
|
|
result[entry].rect.t = atoi(com_token);
|
|
|
|
pos = COM_Parse(pos);
|
|
result[entry].rect.r = result[entry].rect.l+atoi(com_token);
|
|
|
|
pos = COM_Parse(pos);
|
|
result[entry].rect.b = result[entry].rect.t+atoi(com_token);
|
|
|
|
if (pos)
|
|
*numparsed = entry;
|
|
}
|
|
|
|
if (!pos || COM_Parse(pos))
|
|
Con_Printf("unexpected end of file\n");
|
|
|
|
FS_FreeFile(file);
|
|
|
|
return result;
|
|
}
|
|
|
|
void QDECL CLGHL_fillrgba (int x, int y, int width, int height, int r, int g, int b, int a)
|
|
{
|
|
bi_trace();
|
|
}
|
|
int QDECL CLGHL_getscreeninfo (hlscreeninfo_t *info)
|
|
{
|
|
int i;
|
|
bi_trace();
|
|
if (info->size != sizeof(*info))
|
|
return false;
|
|
|
|
info->width = vid.width;
|
|
info->height = vid.height;
|
|
info->flags = 0;
|
|
info->charheight = 8;
|
|
for (i = 0; i < 256; i++)
|
|
info->charwidths[i] = 8;
|
|
|
|
return true;
|
|
}
|
|
void QDECL CLGHL_setcrosshair (HLPIC pic, hlsubrect_t rect, int r, int g, int b)
|
|
{
|
|
bi_trace();
|
|
}
|
|
|
|
struct hlcvar_s *QDECL CLGHL_cvar_register (char *name, char *defvalue, int flags)
|
|
{
|
|
bi_trace();
|
|
if (Cvar_Get(name, defvalue, 0, "Halflife cvars"))
|
|
return GHL_CVarGetPointer(name);
|
|
else
|
|
return NULL;
|
|
}
|
|
float QDECL CLGHL_cvar_getfloat (char *name)
|
|
{
|
|
cvar_t *var = Cvar_FindVar(name);
|
|
bi_trace();
|
|
if (var)
|
|
return var->value;
|
|
return 0;
|
|
}
|
|
char *QDECL CLGHL_cvar_getstring (char *name)
|
|
{
|
|
cvar_t *var = Cvar_FindVar(name);
|
|
bi_trace();
|
|
if (var)
|
|
return var->string;
|
|
return "";
|
|
}
|
|
|
|
void QDECL CLGHL_cmd_register (char *name, xcommand_t func)
|
|
{
|
|
bi_trace();
|
|
Cmd_AddCommand(name, func);
|
|
}
|
|
void QDECL CLGHL_hooknetmsg (char *msgname, void *func)
|
|
{
|
|
int i;
|
|
bi_trace();
|
|
//update the current list now.
|
|
for (i = 0; i < sizeof(usermsgs)/sizeof(usermsgs[0]); i++)
|
|
{
|
|
if (!strcmp(usermsgs[i].name, msgname))
|
|
{
|
|
usermsgs[i].hook = func;
|
|
break; //one per name
|
|
}
|
|
}
|
|
|
|
//we already asked for it perhaps?
|
|
for (i = 0; i < numnewhooks; i++)
|
|
{
|
|
if (!strcmp(pendingusermsgs[i].name, msgname))
|
|
{
|
|
pendingusermsgs[i].hook = func;
|
|
return; //nothing to do
|
|
}
|
|
}
|
|
|
|
Q_strncpyz(pendingusermsgs[numnewhooks].name, msgname, sizeof(pendingusermsgs[i].name));
|
|
pendingusermsgs[numnewhooks].hook = func;
|
|
numnewhooks++;
|
|
}
|
|
void QDECL CLGHL_forwardcmd (char *command)
|
|
{
|
|
bi_trace();
|
|
CL_SendClientCommand(true, "%s", command);
|
|
}
|
|
void QDECL CLGHL_localcmd (char *command)
|
|
{
|
|
bi_trace();
|
|
Cbuf_AddText(command, RESTRICT_SERVER);
|
|
}
|
|
|
|
void QDECL CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result)
|
|
{
|
|
player_info_t *player;
|
|
bi_trace();
|
|
entnum--;
|
|
if (entnum < 0 || entnum >= MAX_CLIENTS)
|
|
return;
|
|
|
|
player = &cl.players[entnum];
|
|
result->name = player->name;
|
|
result->ping = player->ping;
|
|
result->tcolour = player->rtopcolor;
|
|
result->bcolour = player->rbottomcolor;
|
|
result->isus = true;
|
|
result->isspec = player->spectator;
|
|
result->pl = player->pl;
|
|
if (player->qwskin)
|
|
result->model = player->qwskin->name;
|
|
else
|
|
result->model = "";
|
|
}
|
|
|
|
void QDECL CLGHL_startsound_name (char *name, float vol)
|
|
{
|
|
sfx_t *sfx = S_PrecacheSound (name);
|
|
bi_trace();
|
|
if (!sfx)
|
|
{
|
|
Con_Printf ("CLGHL_startsound_name: can't cache %s\n", name);
|
|
return;
|
|
}
|
|
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1, 0, 0, 0);
|
|
}
|
|
void QDECL CLGHL_startsound_idx (int idx, float vol)
|
|
{
|
|
sfx_t *sfx = cl.sound_precache[idx];
|
|
bi_trace();
|
|
if (!sfx)
|
|
{
|
|
Con_Printf ("CLGHL_startsound_name: index not precached %s\n", name);
|
|
return;
|
|
}
|
|
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1, 0, 0, 0);
|
|
}
|
|
|
|
void QDECL CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu)
|
|
{
|
|
bi_trace();
|
|
AngleVectors(ina, outf, outr, outu);
|
|
}
|
|
|
|
hlmsginfo_t *QDECL CLGHL_get_message_info (char *name)
|
|
{
|
|
//fixme: add parser for titles.txt
|
|
hlmsginfo_t *ret;
|
|
bi_trace();
|
|
ret = Z_Malloc(sizeof(*ret));
|
|
memset(ret, 0, sizeof(*ret));
|
|
ret->name = name;
|
|
ret->message = name;
|
|
ret->x = -1;
|
|
ret->y = -1;
|
|
*(int*)&ret->c1 = 0xffffffff;
|
|
*(int*)&ret->c2 = 0xffffffff;
|
|
ret->effect = 0;
|
|
ret->fadein = 1;
|
|
ret->fadeout = 1.5;
|
|
ret->fxtime = 0;
|
|
ret->holdtime = 3;
|
|
return ret;
|
|
}
|
|
int QDECL CLGHL_drawchar (int x, int y, int charnum, int r, int g, int b)
|
|
{
|
|
bi_trace();
|
|
return 0;
|
|
}
|
|
int QDECL CLGHL_drawstring (int x, int y, char *string)
|
|
{
|
|
bi_trace();
|
|
return 0;
|
|
}
|
|
void QDECL CLGHL_settextcolour(float r, float g, float b)
|
|
{
|
|
bi_trace();
|
|
}
|
|
void QDECL CLGHL_drawstring_getlen (char *string, int *outlen, int *outheight)
|
|
{
|
|
bi_trace();
|
|
*outlen = strlen(string)*8;
|
|
*outheight = 8;
|
|
}
|
|
void QDECL CLGHL_consoleprint (char *str)
|
|
{
|
|
bi_trace();
|
|
Con_Printf("%s", str);
|
|
}
|
|
void QDECL CLGHL_centerprint (char *str)
|
|
{
|
|
bi_trace();
|
|
SCR_CenterPrint(0, str, true);
|
|
}
|
|
|
|
|
|
int QDECL CLGHL_getwindowcenterx(void)
|
|
{
|
|
bi_trace();
|
|
return window_center_x;
|
|
}
|
|
int QDECL CLGHL_getwindowcentery(void)
|
|
{
|
|
bi_trace();
|
|
return window_center_y;
|
|
}
|
|
void QDECL CLGHL_getviewnangles(float*ang)
|
|
{
|
|
bi_trace();
|
|
VectorCopy(cl.playerview[0].viewangles, ang);
|
|
}
|
|
void QDECL CLGHL_setviewnangles(float*ang)
|
|
{
|
|
bi_trace();
|
|
VectorCopy(ang, cl.playerview[0].viewangles);
|
|
}
|
|
void QDECL CLGHL_getmaxclients(float*ang){notimpf(__func__);}
|
|
void QDECL CLGHL_cvar_setvalue(char *cvarname, char *value){notimpf(__func__);}
|
|
|
|
int QDECL CLGHL_cmd_argc(void)
|
|
{
|
|
bi_trace();
|
|
return Cmd_Argc();
|
|
}
|
|
char *QDECL CLGHL_cmd_argv(int i)
|
|
{
|
|
bi_trace();
|
|
return Cmd_Argv(i);
|
|
}
|
|
#define CLGHL_con_printf Con_Printf
|
|
#define CLGHL_con_dprintf Con_DPrintf
|
|
void QDECL CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimpf(__func__);}
|
|
void QDECL CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimpf(__func__);}
|
|
char *QDECL CLGHL_physkey(char *key){notimpf(__func__);return NULL;}
|
|
char *QDECL CLGHL_serverkey(char *key){notimpf(__func__);return NULL;}
|
|
float QDECL CLGHL_getclientmaxspeed(void)
|
|
{
|
|
bi_trace();
|
|
return 320;
|
|
}
|
|
int QDECL CLGHL_checkparm(char *str, const char **next)
|
|
{
|
|
int i;
|
|
bi_trace();
|
|
i = COM_CheckParm(str);
|
|
if (next)
|
|
{
|
|
if (i && i+1<com_argc)
|
|
*next = com_argv[i+1];
|
|
else
|
|
*next = NULL;
|
|
}
|
|
return i;
|
|
}
|
|
int QDECL CLGHL_keyevent(int key, int down)
|
|
{
|
|
bi_trace();
|
|
if (key >= 241 && key <= 241+5)
|
|
Key_Event(0, K_MOUSE1+key-241, 0, down);
|
|
else
|
|
Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n");
|
|
return true; //fixme: check the return type
|
|
}
|
|
void QDECL CLGHL_getmousepos(int *outx, int *outy){notimpf(__func__);}
|
|
int QDECL CLGHL_movetypeisnoclip(void)
|
|
{
|
|
bi_trace();
|
|
if (cl.playerview[0].pmovetype == PM_SPECTATOR)
|
|
return true;
|
|
return false;
|
|
}
|
|
struct hlclent_s *QDECL CLGHL_getlocalplayer(void){notimpf(__func__);return NULL;}
|
|
struct hlclent_s *QDECL CLGHL_getviewent(void){notimpf(__func__);return NULL;}
|
|
struct hlclent_s *QDECL CLGHL_getentidx(int idx)
|
|
{
|
|
bi_trace();
|
|
notimpf(__func__);return NULL;
|
|
}
|
|
float QDECL CLGHL_getlocaltime(void){return cl.time;}
|
|
void QDECL CLGHL_calcshake(void){notimpf(__func__);}
|
|
void QDECL CLGHL_applyshake(float *origin, float *angles, float factor){notimpf(__func__);}
|
|
int QDECL CLGHL_pointcontents(float *point, float *truecon){notimpf(__func__);return 0;}
|
|
int QDECL CLGHL_entcontents(float *point){notimpf(__func__);return 0;}
|
|
void QDECL CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimpf(__func__);}
|
|
|
|
model_t *QDECL CLGHL_loadmodel(char *modelname, int *mdlindex){notimpf(__func__);return Mod_ForName(modelname, false);}
|
|
int QDECL CLGHL_addrentity(int type, void *ent){notimpf(__func__);return 0;}
|
|
|
|
model_t *QDECL CLGHL_modelfrompic(HLPIC pic){notimpf(__func__);return NULL;}
|
|
void QDECL CLGHL_soundatloc(char*sound, float volume, float *org){notimpf(__func__);}
|
|
|
|
unsigned short QDECL CLGHL_precacheevent(int evtype, char *name){notimpf(__func__);return 0;}
|
|
void QDECL CLGHL_playevent(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2){notimpf(__func__);}
|
|
void QDECL CLGHL_weaponanimate(int newsequence, int body)
|
|
{
|
|
bi_trace();
|
|
hl_viewmodelsequencetime = cl.time;
|
|
hl_viewmodelsequencecur = newsequence;
|
|
hl_viewmodelsequencebody = body;
|
|
}
|
|
float QDECL CLGHL_randfloat(float minv, float maxv){notimpf(__func__);return minv;}
|
|
long QDECL CLGHL_randlong(long minv, long maxv){notimpf(__func__);return minv;}
|
|
void QDECL CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event))
|
|
{
|
|
bi_trace();
|
|
Con_Printf("CLGHL_hookevent: not implemented. %s\n", name);
|
|
// notimpf(__func__);
|
|
}
|
|
int QDECL CLGHL_con_isshown(void)
|
|
{
|
|
bi_trace();
|
|
return scr_con_current > 0;
|
|
}
|
|
char *QDECL CLGHL_getgamedir(void)
|
|
{
|
|
extern char gamedirfile[];
|
|
bi_trace();
|
|
return gamedirfile;
|
|
}
|
|
struct hlcvar_s *QDECL CLGHL_cvar_find(char *name)
|
|
{
|
|
bi_trace();
|
|
return GHL_CVarGetPointer(name);
|
|
}
|
|
char *QDECL CLGHL_lookupbinding(char *command)
|
|
{
|
|
bi_trace();
|
|
return NULL;
|
|
}
|
|
char *QDECL CLGHL_getlevelname(void)
|
|
{
|
|
bi_trace();
|
|
if (!cl.worldmodel)
|
|
return "";
|
|
return cl.worldmodel->name;
|
|
}
|
|
void QDECL CLGHL_getscreenfade(struct hlsfade_s *fade){notimpf(__func__);}
|
|
void QDECL CLGHL_setscreenfade(struct hlsfade_s *fade){notimpf(__func__);}
|
|
void *QDECL CLGHL_vgui_getpanel(void)
|
|
{
|
|
bi_trace();
|
|
return vgui_panel;
|
|
}
|
|
void QDECL CLGHL_vgui_paintback(int extents[4])
|
|
{
|
|
bi_trace();
|
|
notimpf(__func__);
|
|
}
|
|
|
|
void *QDECL CLGHL_loadfile(char *path, int alloctype, int *length)
|
|
{
|
|
void *ptr = NULL;
|
|
int flen = -1;
|
|
bi_trace();
|
|
if (alloctype == 5)
|
|
{
|
|
flen = FS_LoadFile(path, &ptr);
|
|
}
|
|
else
|
|
notimpf(__func__); //don't leak, just fail
|
|
|
|
if (length)
|
|
*length = flen;
|
|
|
|
return ptr;
|
|
}
|
|
char *QDECL CLGHL_parsefile(char *data, char *token)
|
|
{
|
|
bi_trace();
|
|
return COM_ParseOut(data, token, 1024);
|
|
}
|
|
void QDECL CLGHL_freefile(void *file)
|
|
{
|
|
bi_trace();
|
|
//only valid for alloc type 5
|
|
FS_FreeFile(file);
|
|
}
|
|
|
|
|
|
int QDECL CLGHL_forcedspectator(void)
|
|
{
|
|
bi_trace();
|
|
return cls.demoplayback;
|
|
}
|
|
model_t *QDECL CLGHL_loadmapsprite(char *name)
|
|
{
|
|
bi_trace();
|
|
notimpf(__func__);return NULL;
|
|
}
|
|
|
|
void QDECL CLGHL_fs_addgamedir(char *basedir, char *appname){notimpf(__func__);}
|
|
int QDECL CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimpf(__func__);return false;}
|
|
|
|
char *QDECL CLGHL_player_key(int pnum, char *key){notimpf(__func__);return NULL;}
|
|
void QDECL CLGHL_player_setkey(char *key, char *value){notimpf(__func__);return;}
|
|
|
|
qboolean QDECL CLGHL_getcdkey(int playernum, char key[16]){notimpf(__func__);return false;}
|
|
int QDECL CLGHL_trackerfromplayer(int pslot){notimpf(__func__);return 0;}
|
|
int QDECL CLGHL_playerfromtracker(int tracker){notimpf(__func__);return 0;}
|
|
int QDECL CLGHL_sendcmd_unreliable(char *cmd){notimpf(__func__);return 0;}
|
|
void QDECL CLGHL_getsysmousepos(long *xandy)
|
|
{
|
|
bi_trace();
|
|
#ifdef _WIN32
|
|
GetCursorPos((LPPOINT)xandy);
|
|
#endif
|
|
}
|
|
void QDECL CLGHL_setsysmousepos(int x, int y)
|
|
{
|
|
bi_trace();
|
|
#ifdef _WIN32
|
|
SetCursorPos(x, y);
|
|
#endif
|
|
}
|
|
void QDECL CLGHL_setmouseenable(qboolean enable)
|
|
{
|
|
extern cvar_t _windowed_mouse;
|
|
bi_trace();
|
|
Cvar_Set(&_windowed_mouse, enable?"1":"0");
|
|
}
|
|
|
|
|
|
|
|
#if HLCL_API_VERSION >= 7
|
|
int QDECL CLGHL_demo_isrecording(void)
|
|
{
|
|
bi_trace();
|
|
return cls.demorecording;
|
|
}
|
|
int QDECL CLGHL_demo_isplaying(void)
|
|
{
|
|
bi_trace();
|
|
return cls.demoplayback;
|
|
}
|
|
int QDECL CLGHL_demo_istimedemo(void)
|
|
{
|
|
bi_trace();
|
|
return cls.timedemo;
|
|
}
|
|
void QDECL CLGHL_demo_writedata(int size, void *data)
|
|
{
|
|
bi_trace();
|
|
notimpf(__func__);
|
|
}
|
|
|
|
struct hl_demo_api_s hl_demo_api =
|
|
{
|
|
CLGHL_demo_isrecording,
|
|
CLGHL_demo_isplaying,
|
|
CLGHL_demo_istimedemo,
|
|
CLGHL_demo_writedata,
|
|
|
|
0xdeadbeef
|
|
};
|
|
#endif
|
|
|
|
CLHL_cgamefuncs_t CLHL_cgamefuncs;
|
|
CLHL_enginecgamefuncs_t CLHL_enginecgamefuncs =
|
|
{
|
|
CLGHL_pic_load,
|
|
CLGHL_pic_getnumframes,
|
|
CLGHL_pic_getheight,
|
|
CLGHL_pic_getwidth,
|
|
CLGHL_pic_select,
|
|
CLGHL_pic_drawcuropaque,
|
|
CLGHL_pic_drawcuralphtest,
|
|
CLGHL_pic_drawcuradditive,
|
|
CLGHL_pic_enablescissor,
|
|
CLGHL_pic_disablescissor,
|
|
CLGHL_pic_parsepiclist,
|
|
|
|
CLGHL_fillrgba,
|
|
CLGHL_getscreeninfo,
|
|
CLGHL_setcrosshair,
|
|
|
|
CLGHL_cvar_register,
|
|
CLGHL_cvar_getfloat,
|
|
CLGHL_cvar_getstring,
|
|
|
|
CLGHL_cmd_register,
|
|
CLGHL_hooknetmsg,
|
|
CLGHL_forwardcmd,
|
|
CLGHL_localcmd,
|
|
|
|
CLGHL_getplayerinfo,
|
|
|
|
CLGHL_startsound_name,
|
|
CLGHL_startsound_idx,
|
|
|
|
CLGHL_anglevectors,
|
|
|
|
CLGHL_get_message_info,
|
|
CLGHL_drawchar,
|
|
CLGHL_drawstring,
|
|
#if HLCL_API_VERSION >= 7
|
|
CLGHL_settextcolour,
|
|
#endif
|
|
CLGHL_drawstring_getlen,
|
|
CLGHL_consoleprint,
|
|
CLGHL_centerprint,
|
|
|
|
#if HLCL_API_VERSION >= 7
|
|
CLGHL_getwindowcenterx,
|
|
CLGHL_getwindowcentery,
|
|
CLGHL_getviewnangles,
|
|
CLGHL_setviewnangles,
|
|
CLGHL_getmaxclients,
|
|
CLGHL_cvar_setvalue,
|
|
|
|
CLGHL_cmd_argc,
|
|
CLGHL_cmd_argv,
|
|
CLGHL_con_printf,
|
|
CLGHL_con_dprintf,
|
|
CLGHL_con_notificationprintf,
|
|
CLGHL_con_notificationprintfex,
|
|
CLGHL_physkey,
|
|
CLGHL_serverkey,
|
|
CLGHL_getclientmaxspeed,
|
|
CLGHL_checkparm,
|
|
CLGHL_keyevent,
|
|
CLGHL_getmousepos,
|
|
CLGHL_movetypeisnoclip,
|
|
CLGHL_getlocalplayer,
|
|
CLGHL_getviewent,
|
|
CLGHL_getentidx,
|
|
CLGHL_getlocaltime,
|
|
CLGHL_calcshake,
|
|
CLGHL_applyshake,
|
|
CLGHL_pointcontents,
|
|
CLGHL_entcontents,
|
|
CLGHL_traceline,
|
|
|
|
CLGHL_loadmodel,
|
|
CLGHL_addrentity,
|
|
|
|
CLGHL_modelfrompic,
|
|
CLGHL_soundatloc,
|
|
|
|
CLGHL_precacheevent,
|
|
CLGHL_playevent,
|
|
CLGHL_weaponanimate,
|
|
CLGHL_randfloat,
|
|
CLGHL_randlong,
|
|
CLGHL_hookevent,
|
|
CLGHL_con_isshown,
|
|
CLGHL_getgamedir,
|
|
CLGHL_cvar_find,
|
|
CLGHL_lookupbinding,
|
|
CLGHL_getlevelname,
|
|
CLGHL_getscreenfade,
|
|
CLGHL_setscreenfade,
|
|
CLGHL_vgui_getpanel,
|
|
CLGHL_vgui_paintback,
|
|
|
|
CLGHL_loadfile,
|
|
CLGHL_parsefile,
|
|
CLGHL_freefile,
|
|
|
|
NULL, //triapi;
|
|
NULL, //efxapi;
|
|
NULL, //eventapi;
|
|
&hl_demo_api,
|
|
NULL, //netapi;
|
|
|
|
//sdk 2.3+
|
|
NULL, //voiceapi;
|
|
|
|
CLGHL_forcedspectator,
|
|
CLGHL_loadmapsprite,
|
|
|
|
CLGHL_fs_addgamedir,
|
|
CLGHL_expandfilename,
|
|
|
|
CLGHL_player_key,
|
|
CLGHL_player_setkey,
|
|
|
|
CLGHL_getcdkey,
|
|
CLGHL_trackerfromplayer,
|
|
CLGHL_playerfromtracker,
|
|
CLGHL_sendcmd_unreliable,
|
|
CLGHL_getsysmousepos,
|
|
CLGHL_setsysmousepos,
|
|
CLGHL_setmouseenable,
|
|
#endif
|
|
|
|
0xdeadbeef
|
|
};
|
|
|
|
dllhandle_t *clg;
|
|
|
|
int CLHL_GamecodeDoesMouse(void)
|
|
{
|
|
#if HLCL_API_VERSION >= 7
|
|
if (clg && CLHL_cgamefuncs.CL_CreateMove)
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
int CLHL_MouseEvent(unsigned int buttonmask)
|
|
{
|
|
#if HLCL_API_VERSION >= 7
|
|
if (!CLHL_GamecodeDoesMouse())
|
|
return false;
|
|
|
|
CLHL_cgamefuncs.IN_MouseEvent(buttonmask);
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
void CLHL_SetMouseActive(int activate)
|
|
{
|
|
#if HLCL_API_VERSION >= 7
|
|
static int oldactive;
|
|
if (!clg)
|
|
{
|
|
oldactive = false;
|
|
return;
|
|
}
|
|
if (activate == oldactive)
|
|
return;
|
|
oldactive = activate;
|
|
|
|
if (activate)
|
|
{
|
|
if (CLHL_cgamefuncs.IN_ActivateMouse)
|
|
CLHL_cgamefuncs.IN_ActivateMouse();
|
|
}
|
|
else
|
|
{
|
|
if (CLHL_cgamefuncs.IN_DeactivateMouse)
|
|
CLHL_cgamefuncs.IN_DeactivateMouse();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CLHL_UnloadClientGame(void)
|
|
{
|
|
if (!clg)
|
|
return;
|
|
|
|
CLHL_SetMouseActive(false);
|
|
if (CLHL_cgamefuncs.HUD_Shutdown)
|
|
CLHL_cgamefuncs.HUD_Shutdown();
|
|
Sys_CloseLibrary(clg);
|
|
memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs));
|
|
clg = NULL;
|
|
|
|
hl_viewmodelsequencetime = 0;
|
|
}
|
|
|
|
void CLHL_LoadClientGame(void)
|
|
{
|
|
char fullname[MAX_OSPATH];
|
|
char path[MAX_OSPATH];
|
|
void *iterator;
|
|
|
|
int (QDECL *initfunc)(CLHL_enginecgamefuncs_t *funcs, int version);
|
|
dllfunction_t funcs[] =
|
|
{
|
|
{(void*)&initfunc, "Initialize"},
|
|
{NULL}
|
|
};
|
|
|
|
CLHL_UnloadClientGame();
|
|
|
|
memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs));
|
|
|
|
clg = NULL;
|
|
iterator = NULL;
|
|
//FIXME: dlls in gamepaths is evil
|
|
while(COM_IteratePaths(&iterator, path, sizeof(path), NULL, 0))
|
|
{
|
|
snprintf (fullname, sizeof(fullname), "%s%s", path, "cl_dlls/client");
|
|
clg = Sys_LoadLibrary(fullname, funcs);
|
|
if (clg)
|
|
break;
|
|
}
|
|
|
|
if (!clg)
|
|
return;
|
|
|
|
if (!initfunc(&CLHL_enginecgamefuncs, HLCL_API_VERSION))
|
|
{
|
|
Con_Printf("HalfLife cldll is not version %i\n", HLCL_API_VERSION);
|
|
Sys_CloseLibrary(clg);
|
|
clg = NULL;
|
|
return;
|
|
}
|
|
|
|
CLHL_cgamefuncs.HUD_VidInit = (void*)Sys_GetAddressForName(clg, "HUD_VidInit");
|
|
CLHL_cgamefuncs.HUD_Init = (void*)Sys_GetAddressForName(clg, "HUD_Init");
|
|
CLHL_cgamefuncs.HUD_Shutdown = (void*)Sys_GetAddressForName(clg, "HUD_Shutdown");
|
|
CLHL_cgamefuncs.HUD_Redraw = (void*)Sys_GetAddressForName(clg, "HUD_Redraw");
|
|
CLHL_cgamefuncs.HUD_UpdateClientData = (void*)Sys_GetAddressForName(clg, "HUD_UpdateClientData");
|
|
CLHL_cgamefuncs.HUD_Reset = (void*)Sys_GetAddressForName(clg, "HUD_Reset");
|
|
#if HLCL_API_VERSION >= 7
|
|
CLHL_cgamefuncs.CL_CreateMove = (void*)Sys_GetAddressForName(clg, "CL_CreateMove");
|
|
CLHL_cgamefuncs.IN_ActivateMouse = (void*)Sys_GetAddressForName(clg, "IN_ActivateMouse");
|
|
CLHL_cgamefuncs.IN_DeactivateMouse = (void*)Sys_GetAddressForName(clg, "IN_DeactivateMouse");
|
|
CLHL_cgamefuncs.IN_MouseEvent = (void*)Sys_GetAddressForName(clg, "IN_MouseEvent");
|
|
#endif
|
|
|
|
VGui_Setup();
|
|
|
|
if (CLHL_cgamefuncs.HUD_Init)
|
|
CLHL_cgamefuncs.HUD_Init();
|
|
if (CLHL_cgamefuncs.HUD_VidInit)
|
|
CLHL_cgamefuncs.HUD_VidInit();
|
|
{
|
|
struct hlkbutton_s
|
|
{
|
|
int down[2]; // key nums holding it down
|
|
int state; // low bit is down state
|
|
} *but;
|
|
struct hlkbutton_s *(QDECL *pKB_Find) (const char *foo) = (void*)Sys_GetAddressForName(clg, "KB_Find");
|
|
if (pKB_Find)
|
|
{
|
|
but = pKB_Find("in_mlook");
|
|
if (but)
|
|
but->state |= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int CLHL_BuildUserInput(int msecs, usercmd_t *cmd)
|
|
{
|
|
#if HLCL_API_VERSION >= 7
|
|
hlusercmd_t hlcmd;
|
|
if (!clg || !CLHL_cgamefuncs.CL_CreateMove)
|
|
return false;
|
|
|
|
CLHL_cgamefuncs.CL_CreateMove(msecs/255.0f, &hlcmd, cls.state>=ca_active && !cls.demoplayback);
|
|
|
|
#define ANGLE2SHORT(x) (x) * (65536/360.0)
|
|
cmd->msec = msecs;
|
|
cmd->angles[0] = ANGLE2SHORT(hlcmd.viewangles[0]);
|
|
cmd->angles[1] = ANGLE2SHORT(hlcmd.viewangles[1]);
|
|
cmd->angles[2] = ANGLE2SHORT(hlcmd.viewangles[2]);
|
|
cmd->forwardmove = hlcmd.forwardmove;
|
|
cmd->sidemove = hlcmd.sidemove;
|
|
cmd->upmove = hlcmd.upmove;
|
|
cmd->weapon = hlcmd.weaponselect;
|
|
cmd->impulse = hlcmd.impulse;
|
|
cmd->buttons = hlcmd.buttons & 0xff; //FIXME: quake's protocols are more limited than this
|
|
cmd->lightlevel = hlcmd.lightlevel;
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
int CLHL_DrawHud(void)
|
|
{
|
|
extern kbutton_t in_attack;
|
|
hllocalclientdata_t state;
|
|
int ret;
|
|
|
|
if (!clg || !CLHL_cgamefuncs.HUD_Redraw)
|
|
return false;
|
|
|
|
memset(&state, 0, sizeof(state));
|
|
|
|
// state.origin;
|
|
// state.viewangles;
|
|
#if HLCL_API_VERSION < 7
|
|
// state.viewheight;
|
|
// state.maxspeed;
|
|
// state.punchangles;
|
|
state.idlescale = 0;
|
|
state.mousesens = 0;
|
|
state.keys = (in_attack.state[0]&3)?1:0;
|
|
#endif
|
|
state.weapons = cl.playerview[0].stats[STAT_ITEMS];
|
|
state.fov = 90;
|
|
|
|
V_StopPitchDrift(&cl.playerview[0]);
|
|
|
|
CLHL_cgamefuncs.HUD_UpdateClientData(&state, cl.time);
|
|
|
|
ret = CLHL_cgamefuncs.HUD_Redraw(cl.time, cl.intermissionmode != IM_NONE);
|
|
return ret;
|
|
}
|
|
|
|
int CLHL_AnimateViewEntity(entity_t *ent)
|
|
{
|
|
float time;
|
|
if (!hl_viewmodelsequencetime)
|
|
return false;
|
|
|
|
time = cl.time - hl_viewmodelsequencetime;
|
|
ent->framestate.g[FS_REG].frame[0] = hl_viewmodelsequencecur;
|
|
ent->framestate.g[FS_REG].frame[1] = hl_viewmodelsequencecur;
|
|
ent->framestate.g[FS_REG].frametime[0] = time;
|
|
ent->framestate.g[FS_REG].frametime[1] = time;
|
|
return true;
|
|
}
|
|
|
|
explosion_t *CL_AllocExplosion (vec3_t org);
|
|
|
|
int CLHL_ParseGamePacket(void)
|
|
{
|
|
int subcode;
|
|
char *end;
|
|
char *str;
|
|
int tempi;
|
|
|
|
end = net_message.data+msg_readcount+2+MSG_ReadShort();
|
|
|
|
if (end > net_message.data+net_message.cursize)
|
|
return false;
|
|
|
|
subcode = MSG_ReadByte();
|
|
|
|
if (usermsgs[subcode].hook)
|
|
if (usermsgs[subcode].hook(usermsgs[subcode].name, end - (net_message.data+msg_readcount), net_message.data+msg_readcount))
|
|
{
|
|
msg_readcount = end - net_message.data;
|
|
return true;
|
|
}
|
|
|
|
switch(subcode)
|
|
{
|
|
case 1:
|
|
//register the server-sent code.
|
|
tempi = MSG_ReadByte();
|
|
str = MSG_ReadString();
|
|
Q_strncpyz(usermsgs[tempi].name, str, sizeof(usermsgs[tempi].name));
|
|
|
|
//get the builtin to reregister its hooks.
|
|
for (tempi = 0; tempi < numnewhooks; tempi++)
|
|
CLGHL_hooknetmsg(pendingusermsgs[tempi].name, pendingusermsgs[tempi].hook);
|
|
break;
|
|
case svc_temp_entity:
|
|
{
|
|
vec3_t startp, endp, vel;
|
|
float ang;
|
|
int midx;
|
|
int mscale;
|
|
int mrate;
|
|
int flags;
|
|
int lifetime;
|
|
explosion_t *ef;
|
|
|
|
subcode = MSG_ReadByte();
|
|
|
|
switch(subcode)
|
|
{
|
|
case 3:
|
|
MSG_ReadPos(startp);
|
|
midx = MSG_ReadShort();
|
|
mscale = MSG_ReadByte();
|
|
mrate = MSG_ReadByte();
|
|
flags = MSG_ReadByte();
|
|
if (!(flags & 8))
|
|
P_RunParticleEffectType(startp, NULL, 1, pt_explosion);
|
|
if (!(flags & 4))
|
|
S_StartSound(0, 0, S_PrecacheSound("explosion"), startp, 1, 1, 0, 0, 0);
|
|
if (!(flags & 2))
|
|
CL_NewDlight(0, startp, 200, 1, 2.0,2.0,2.0);
|
|
|
|
ef = CL_AllocExplosion(startp);
|
|
ef->start = cl.time;
|
|
ef->model = cl.model_precache[midx];
|
|
ef->framerate = mrate;
|
|
ef->firstframe = 0;
|
|
ef->numframes = ef->model->numframes;
|
|
if (!(flags & 1))
|
|
ef->flags = RF_ADDITIVE;
|
|
else
|
|
ef->flags = 0;
|
|
break;
|
|
case 4:
|
|
MSG_ReadPos(startp);
|
|
P_RunParticleEffectType(startp, NULL, 1, pt_tarexplosion);
|
|
break;
|
|
case 5:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
break;
|
|
case 6:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadPos(endp);
|
|
break;
|
|
case 9:
|
|
MSG_ReadPos(startp);
|
|
P_RunParticleEffectType(startp, NULL, 1, ptdp_spark);
|
|
break;
|
|
case 22:
|
|
MSG_ReadShort();
|
|
MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
break;
|
|
case 23:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
break;
|
|
case 106:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadPos(vel);
|
|
ang = MSG_ReadAngle();
|
|
midx = MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
lifetime = MSG_ReadByte();
|
|
|
|
ef = CL_AllocExplosion(startp);
|
|
ef->start = cl.time;
|
|
ef->angles[1] = ang;
|
|
ef->model = cl.model_precache[midx];
|
|
ef->firstframe = 0;
|
|
ef->numframes = lifetime;
|
|
ef->flags = 0;
|
|
ef->framerate = 10;
|
|
break;
|
|
case 108:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadPos(endp);
|
|
MSG_ReadPos(vel);
|
|
MSG_ReadByte();
|
|
MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
MSG_ReadByte();
|
|
break;
|
|
case 109:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadShort();
|
|
MSG_ReadByte();
|
|
break;
|
|
case 116:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadByte();
|
|
break;
|
|
case 117:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadByte()+256;
|
|
break;
|
|
case 118:
|
|
MSG_ReadPos(startp);
|
|
MSG_ReadByte()+256;
|
|
break;
|
|
default:
|
|
Con_Printf("CLHL_ParseGamePacket: Unable to parse gamecode tempent %i\n", subcode);
|
|
msg_readcount = end - net_message.data;
|
|
break;
|
|
}
|
|
}
|
|
if (msg_readcount != end - net_message.data)
|
|
{
|
|
Con_Printf("CLHL_ParseGamePacket: Gamecode temp entity %i not parsed correctly read %i bytes too many\n", subcode, msg_readcount - (end - net_message.data));
|
|
msg_readcount = end - net_message.data;
|
|
}
|
|
break;
|
|
case svc_intermission:
|
|
//nothing.
|
|
cl.intermissionmode = IM_NQSCORES;
|
|
break;
|
|
case svc_cdtrack:
|
|
{
|
|
unsigned int firsttrack;
|
|
unsigned int looptrack;
|
|
firsttrack = MSG_ReadByte ();
|
|
looptrack = MSG_ReadByte ();
|
|
Media_NumberedTrack (firsttrack, looptrack);
|
|
}
|
|
break;
|
|
|
|
case 35: //svc_weaponanimation:
|
|
tempi = MSG_ReadByte();
|
|
CLGHL_weaponanimate(tempi, MSG_ReadByte());
|
|
break;
|
|
case 37: //svc_roomtype
|
|
tempi = MSG_ReadShort();
|
|
// S_SetUnderWater(tempi==14||tempi==15||tempi==16);
|
|
break;
|
|
default:
|
|
Con_Printf("Unrecognised gamecode packet %i (%s)\n", subcode, usermsgs[subcode].name);
|
|
msg_readcount = end - net_message.data;
|
|
break;
|
|
}
|
|
|
|
if (msg_readcount != end - net_message.data)
|
|
{
|
|
Con_Printf("CLHL_ParseGamePacket: Gamecode packet %i not parsed correctly read %i bytestoo many\n", subcode, msg_readcount - (end - net_message.data));
|
|
msg_readcount = end - net_message.data;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#endif
|