#include "quakedef.h" #include "glquake.h" #ifdef HLCLIENT #define notimp(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l) //#define HLCL_API_VERSION 6 #define HLCL_API_VERSION 7 //make shared struct hlcvar_s *GHL_CVarGetPointer(char *varname); #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; vec3_t viewangles; float forwardmove; float sidemove; float upmove; qbyte lightlevel; unsigned short buttons; qbyte impulse; qbyte weaponselect; 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; 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 (*pic_load) (char *picname); int (*pic_getnumframes) (HLPIC pic); int (*pic_getheight) (HLPIC pic, int frame); int (*pic_getwidth) (HLPIC pic, int frame); void (*pic_select) (HLPIC pic, int r, int g, int b); void (*pic_drawcuropaque) (int frame, int x, int y, void *loc); void (*pic_drawcuralphatest) (int frame, int x, int y, void *loc); void (*pic_drawcuradditive) (int frame, int x, int y, void *loc); void (*pic_enablescissor) (int x, int y, int width, int height); void (*pic_disablescissor) (void); hlspriteinf_t *(*pic_parsepiclist) (char *filename, int *numparsed); void (*fillrgba) (int x, int y, int width, int height, int r, int g, int b, int a); int (*getscreeninfo) (hlscreeninfo_t *info); void (*setcrosshair) (HLPIC pic, hlsubrect_t rect, int r, int g, int b); //I worry about stuff like this int (*cvar_register) (char *name, char *defvalue, int flags); float (*cvar_getfloat) (char *name); char *(*cvar_getstring) (char *name); void (*cmd_register) (char *name, void (*func) (void)); void (*hooknetmsg) (char *msgname, void *func); void (*forwardcmd) (char *command); void (*localcmd) (char *command); void (*getplayerinfo) (int entnum, hlplayerinfo_t *result); void (*startsound_name) (char *name, float vol); void (*startsound_idx) (int idx, float vol); void (*anglevectors) (float *ina, float *outf, float *outr, float *outu); hlmsginfo_t *(*get_message_info) (char *name); //translated+scaled+etc intro stuff int (*drawchar) (int x, int y, int charnum, int r, int g, int b); int (*drawstring) (int x, int y, char *string); #if HLCL_API_VERSION >= 7 void (*settextcolour) (float r, float b, float g); #endif void (*drawstring_getlen) (char *string, int *outlen, int *outheight); void (*consoleprint) (char *str); void (*centerprint) (char *str); #if HLCL_API_VERSION >= 7 int (*getwindowcenterx)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. int (*getwindowcentery)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. void (*getviewnangles)(float*ang); void (*setviewnangles)(float*ang); void (*getmaxclients)(float*ang); void (*cvar_setvalue)(char *cvarname, char *value); int (*cmd_argc)(void); char *(*cmd_argv)(int i); void (*con_printf)(char *fmt, ...); void (*con_dprintf)(char *fmt, ...); void (*con_notificationprintf)(int pos, char *fmt, ...); void (*con_notificationprintfex)(void *info, char *fmt, ...); //arg1 is of specific type char *(*physkey)(char *key); char *(*serverkey)(char *key); float (*getclientmaxspeed)(void); int (*checkparm)(char *str, char **next); int (*keyevent)(int key, int down); void (*getmousepos)(int *outx, int *outy); int (*movetypeisnoclip)(void); struct hlclent_s *(*getlocalplayer)(void); struct hlclent_s *(*getviewent)(void); struct hlclent_s *(*getentidx)(void); float (*getlocaltime)(void); void (*calcshake)(void); void (*applyshake)(void); int (*pointcontents)(float *point, float *truecon); int (*waterentity)(float *point); void (*traceline) (float *start, float *end, int flags, int hull, int forprediction); model_t *(*loadmodel)(char *modelname, int *mdlindex); int (*addrentity)(int type, void *ent); model_t *(*modelfrompic) (HLPIC pic); void (*soundatloc)(char*sound, float volume, float *org); unsigned short (*precacheevent)(int evtype, char *name); void (*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 (*weaponanimate)(int anim, int body); float (*randfloat) (float minv, float maxv); long (*randlong) (long minv, long maxv); void (*hookevent) (char *name, void (*func)(struct hlevent_s *event)); int (*con_isshown) (void); char *(*getgamedir) (void); struct hlcvar_s *(*cvar_find) (char *name); char *(*lookupbinding) (char *command); char *(*getlevelname) (void); void (*getscreenfade) (struct hlsfade_s *fade); void (*setscreenfade) (struct hlsfade_s *fade); void *(*vgui_getpanel) (void); void (*vgui_paintback) (int extents[4]); void *(*loadfile) (char *path, int onhunk, int *length); char *(*parsefile) (char *data, char *token); void (*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 (*isrecording)(void); int (*isplaying)(void); int (*istimedemo)(void); void (*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 (*forcedspectator) (void); model_t *(*loadmapsprite) (char *name); void (*fs_addgamedir) (char *basedir, char *appname); int (*expandfilename) (char *filename, char *outbuff, int outsize); char *(*player_key) (int pnum, char *key); void (*player_setkey) (char *key, char *value); //wait, no pnum? qboolean (*getcdkey) (int playernum, char key[16]); int trackerfromplayer; int playerfromtracker; int (*sendcmd_unreliable) (char *cmd); void (*getsysmousepos) (long *xandy); void (*setsysmousepos) (int x, int y); void (*setmouseenable) (qboolean enable); #endif int sentinal; } CLHL_enginecgamefuncs_t; typedef struct { int (*HUD_VidInit) (void); int (*HUD_Init) (void); int (*HUD_Shutdown) (void); int (*HUD_Redraw) (float maptime, int inintermission); int (*HUD_UpdateClientData) (hllocalclientdata_t *localclientdata, float maptime); int (*HUD_Reset) (void); #if HLCL_API_VERSION >= 7 void (*CL_CreateMove) (float frametime, hlusercmd_t *cmd, int isplaying); void (*IN_ActivateMouse) (void); void (*IN_DeactivateMouse) (void); void (*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 (*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 CLGHL_pic_load (char *picname) { return Mod_ForName(picname, false); // return Draw_SafeCachePic(picname); } int CLGHL_pic_getnumframes (HLPIC pic) { if (pic) return pic->numframes; else return 0; } static mspriteframe_t *getspriteframe(HLPIC pic, int frame) { msprite_t *psprite; mspritegroup_t *pgroup; if (!pic) return NULL; psprite = pic->cache.data; 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; f = getspriteframe(pic, frame); if (f) return &f->p; return NULL; } int CLGHL_pic_getheight (HLPIC pic, int frame) { mspriteframe_t *pframe; pframe = getspriteframe(pic, frame); if (!pframe) return 0; return pframe->p.width; } int CLGHL_pic_getwidth (HLPIC pic, int frame) { mspriteframe_t *pframe; pframe = getspriteframe(pic, frame); if (!pframe) return 0; return pframe->p.height; } void CLGHL_pic_select (HLPIC pic, int r, int g, int b) { selectedpic = pic; Draw_ImageColours(r/255.0f, g/255.0f, b/255.0f, 1); } void CLGHL_pic_drawcuropaque (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) return; //faster SW render: no blends/holes pic->flags &= ~1; Draw_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 CLGHL_pic_drawcuralphtest (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) return; //use some kind of alpha pic->flags |= 1; Draw_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 CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) return; qglEnable (GL_BLEND); qglBlendFunc(GL_ONE, GL_ONE); //use some kind of alpha pic->flags |= 1; if (loc) { Draw_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 { Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic); } qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void CLGHL_pic_enablescissor (int x, int y, int width, int height) { } void CLGHL_pic_disablescissor (void) { } hlspriteinf_t *CLGHL_pic_parsepiclist (char *filename, int *numparsed) { hlspriteinf_t *result; int entry; int entries; void *file; char *pos; *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 CLGHL_fillrgba (int x, int y, int width, int height, int r, int g, int b, int a) { } int CLGHL_getscreeninfo (hlscreeninfo_t *info) { int i; 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 CLGHL_setcrosshair (HLPIC pic, hlsubrect_t rect, int r, int g, int b) { } struct hlcvar_s *CLGHL_cvar_register (char *name, char *defvalue, int flags) { if (Cvar_Get(name, defvalue, 0, "Halflife cvars")) return GHL_CVarGetPointer(name); else return NULL; } float CLGHL_cvar_getfloat (char *name) { cvar_t *var = Cvar_FindVar(name); if (var) return var->value; return 0; } char *CLGHL_cvar_getstring (char *name) { cvar_t *var = Cvar_FindVar(name); if (var) return var->string; return ""; } void CLGHL_cmd_register (char *name, xcommand_t func) { Cmd_AddRemCommand(name, func); } void CLGHL_hooknetmsg (char *msgname, void *func) { int i; //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 CLGHL_forwardcmd (char *command) { CL_SendClientCommand(true, "%s", command); } void CLGHL_localcmd (char *command) { Cbuf_AddText(command, RESTRICT_SERVER); } void CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result) { player_info_t *player; 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->skin) result->model = player->skin->name; else result->model = ""; } void CLGHL_startsound_name (char *name, float vol) { sfx_t *sfx = S_PrecacheSound (name); if (!sfx) { Con_Printf ("CLGHL_startsound_name: can't cache %s\n", name); return; } S_StartSound (-1, -1, sfx, vec3_origin, vol, 1); } void CLGHL_startsound_idx (int idx, float vol) { sfx_t *sfx = cl.sound_precache[idx]; if (!sfx) { Con_Printf ("CLGHL_startsound_name: index not precached %s\n", name); return; } S_StartSound (-1, -1, sfx, vec3_origin, vol, 1); } void CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu) { AngleVectors(ina, outf, outr, outu); } hlmsginfo_t *CLGHL_get_message_info (char *name) { //fixme: add parser hlmsginfo_t *ret; ret = Z_Malloc(sizeof(*ret)); memset(ret, 0, sizeof(*ret)); ret->name = name; ret->message = name; ret->x = 0; ret->y = 0; *(int*)&ret->c1 = 0xffffffff; *(int*)&ret->c2 = 0xffffffff; ret->effect = 0; ret->fadein = 0; ret->fadeout = 0; ret->fxtime = 0; ret->holdtime = 1000; return ret; } int CLGHL_drawchar (int x, int y, int charnum, int r, int g, int b) { return 0; } int CLGHL_drawstring (int x, int y, char *string) { return 0; } void CLGHL_settextcolour(float r, float g, float b) { } void CLGHL_drawstring_getlen (char *string, int *outlen, int *outheight) { *outlen = strlen(string)*8; *outheight = 8; } void CLGHL_consoleprint (char *str) { Con_Printf("%s", str); } void CLGHL_centerprint (char *str) { SCR_CenterPrint(0, str, true); } int CLGHL_getwindowcenterx(void) { return window_center_x; } int CLGHL_getwindowcentery(void) { return window_center_y; } void CLGHL_getviewnangles(float*ang) { VectorCopy(cl.viewangles[0], ang); } void CLGHL_setviewnangles(float*ang) { VectorCopy(ang, cl.viewangles[0]); } void CLGHL_getmaxclients(float*ang){notimp(__LINE__);} void CLGHL_cvar_setvalue(char *cvarname, char *value){notimp(__LINE__);} int CLGHL_cmd_argc(void) { return Cmd_Argc(); } char *CLGHL_cmd_argv(int i) { return Cmd_Argv(i); } #define CLGHL_con_printf Con_Printf//void CLGHL_con_printf(char *fmt, ...){notimp(__LINE__);} #define CLGHL_con_dprintf Con_DPrintf//void CLGHL_con_dprintf(char *fmt, ...){notimp(__LINE__);} void CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimp(__LINE__);} void CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimp(__LINE__);} char *CLGHL_physkey(char *key){notimp(__LINE__);return NULL;} char *CLGHL_serverkey(char *key){notimp(__LINE__);return NULL;} float CLGHL_getclientmaxspeed(void) { return 320; } int CLGHL_checkparm(char *str, const char **next) { int i; i = COM_CheckParm(str); if (next) { if (i && i+1= 241 && key <= 241+5) Key_Event(K_MOUSE1+key-241, down); else Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n"); return true; //fixme: check the return type } void CLGHL_getmousepos(int *outx, int *outy){notimp(__LINE__);} int CLGHL_movetypeisnoclip(void){notimp(__LINE__);return 0;} struct hlclent_s *CLGHL_getlocalplayer(void){notimp(__LINE__);return NULL;} struct hlclent_s *CLGHL_getviewent(void){notimp(__LINE__);return NULL;} struct hlclent_s *CLGHL_getentidx(void){notimp(__LINE__);return NULL;} float CLGHL_getlocaltime(void){return cl.time;} void CLGHL_calcshake(void){notimp(__LINE__);} void CLGHL_applyshake(float *origin, float *angles, float factor){notimp(__LINE__);} int CLGHL_pointcontents(float *point, float *truecon){notimp(__LINE__);return 0;} int CLGHL_entcontents(float *point){notimp(__LINE__);return 0;} void CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimp(__LINE__);} model_t *CLGHL_loadmodel(char *modelname, int *mdlindex){notimp(__LINE__);return Mod_ForName(modelname, false);} int CLGHL_addrentity(int type, void *ent){notimp(__LINE__);return 0;} model_t *CLGHL_modelfrompic(HLPIC pic){notimp(__LINE__);return NULL;} void CLGHL_soundatloc(char*sound, float volume, float *org){notimp(__LINE__);} unsigned short CLGHL_precacheevent(int evtype, char *name){notimp(__LINE__);return 0;} void 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){notimp(__LINE__);} void CLGHL_weaponanimate(int newsequence, int body) { hl_viewmodelsequencetime = cl.time; hl_viewmodelsequencecur = newsequence; hl_viewmodelsequencebody = body; } float CLGHL_randfloat(float minv, float maxv){notimp(__LINE__);return minv;} long CLGHL_randlong(long minv, long maxv){notimp(__LINE__);return minv;} void CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event)){notimp(__LINE__);} int CLGHL_con_isshown(void) { return scr_con_current > 0; } char *CLGHL_getgamedir(void) { extern char gamedirfile[]; return gamedirfile; } struct hlcvar_s *CLGHL_cvar_find(char *name) { return GHL_CVarGetPointer(name); } char *CLGHL_lookupbinding(char *command) { return NULL; } char *CLGHL_getlevelname(void) { return cl.levelname; } void CLGHL_getscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} void CLGHL_setscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} void *CLGHL_vgui_getpanel(void){notimp(__LINE__);return NULL;} void CLGHL_vgui_paintback(int extents[4]){notimp(__LINE__);} void *CLGHL_loadfile(char *path, int alloctype, int *length) { void *ptr = NULL; int flen = -1; if (alloctype == 5) { flen = FS_LoadFile(path, &ptr); } else notimp(__LINE__); //don't leak, just fail if (length) *length = flen; return ptr; } char *CLGHL_parsefile(char *data, char *token) { return COM_ParseOut(data, token, 1024); } void CLGHL_freefile(void *file) { //only valid for alloc type 5 FS_FreeFile(file); } int CLGHL_forcedspectator(void) { return cls.demoplayback; } model_t *CLGHL_loadmapsprite(char *name) { notimp(__LINE__);return NULL; } void CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);} int CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return false;} char *CLGHL_player_key(int pnum, char *key){notimp(__LINE__);return NULL;} void CLGHL_player_setkey(char *key, char *value){notimp(__LINE__);return NULL;} qboolean CLGHL_getcdkey(int playernum, char key[16]){notimp(__LINE__);return false;} int CLGHL_trackerfromplayer(int pslot){notimp(__LINE__);return 0;} int CLGHL_playerfromtracker(int tracker){notimp(__LINE__);return 0;} int CLGHL_sendcmd_unreliable(char *cmd){notimp(__LINE__);return 0;} void CLGHL_getsysmousepos(long *xandy) { #ifdef _WIN32 GetCursorPos((LPPOINT)xandy); #endif } void CLGHL_setsysmousepos(int x, int y) { #ifdef _WIN32 SetCursorPos(x, y); #endif } void CLGHL_setmouseenable(qboolean enable) { extern cvar_t _windowed_mouse; Cvar_Set(&_windowed_mouse, enable?"1":"0"); } #if HLCL_API_VERSION >= 7 int CLGHL_demo_isrecording(void) { return cls.demorecording; } int CLGHL_demo_isplaying(void) { return cls.demoplayback; } int CLGHL_demo_istimedemo(void) { return cls.timedemo; } void CLGHL_demo_writedata(int size, void *data) { notimp(__LINE__); } 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, (void*)0xdeaddead,//CLGHL_trackerfromplayer; (void*)0xdeaddead,//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; int (*initfunc)(CLHL_enginecgamefuncs_t *funcs, int version); dllfunction_t funcs[] = { {(void*)&initfunc, "Initialize"}, {NULL} }; CLHL_UnloadClientGame(); memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs)); path = NULL; while((path = COM_NextPath (path))) { if (!path) return NULL; // couldn't find one anywhere 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)) { 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 if (CLHL_cgamefuncs.HUD_Init) CLHL_cgamefuncs.HUD_Init(); if (CLHL_cgamefuncs.HUD_VidInit) CLHL_cgamefuncs.HUD_VidInit(); } 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; cmd->lightlevel = hlcmd.lightlevel; return true; #else return false; #endif } int CLHL_DrawHud(void) { extern kbutton_t in_attack; hllocalclientdata_t state; 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.stats[0][STAT_ITEMS]; state.fov = 90; V_StopPitchDrift(0); CLHL_cgamefuncs.HUD_UpdateClientData(&state, cl.time); return CLHL_cgamefuncs.HUD_Redraw(cl.time, cl.intermission); } 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; } 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; extern cvar_t temp1; subcode = MSG_ReadByte(); if (temp1.value) Con_Printf("Temp ent %i\n", subcode); 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); if (!(flags & 2)) CL_NewDlightRGB(0, startp[0], startp[1], startp[2], 200, 1, 0.2,0.2,0.2); ef = CL_AllocExplosion(); VectorCopy(startp, ef->origin); 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 = Q2RF_ADDATIVE; 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(); VectorCopy(startp, ef->origin); 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.intermission = true; break; case svc_cdtrack: cl.cdtrack = MSG_ReadByte(); MSG_ReadByte(); CDAudio_Play ((qbyte)cl.cdtrack, true); break; case 35: //svc_weaponanimation: tempi = MSG_ReadByte(); CLGHL_weaponanimate(tempi, MSG_ReadByte()); break; case 37: //svc_roomtype tempi = MSG_ReadShort(); SNDDMA_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