X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=csprogs.c;h=4b04475c81b0a10c56c2266affc8599921b6b2ba;hb=e948a0f3bad7d2b3f86175630c8e67a5f634c099;hp=fea2b60d7acf6a19845292cacc3d41fe7649fecc;hpb=68e4033b2e8393d2c2553382aa68c11fa4c80d49;p=xonotic%2Fdarkplaces.git diff --git a/csprogs.c b/csprogs.c index fea2b60d..4b04475c 100644 --- a/csprogs.c +++ b/csprogs.c @@ -3,6 +3,7 @@ #include "clprogdefs.h" #include "csprogs.h" #include "cl_collision.h" +#include "snd_main.h" //============================================================================ // Client prog handling @@ -20,7 +21,6 @@ static char *cl_required_func[] = "CSQC_InputEvent", "CSQC_UpdateView", "CSQC_ConsoleCommand", - "CSQC_Shutdown" }; static int cl_numrequiredfunc = sizeof(cl_required_func) / sizeof(char*); @@ -45,10 +45,32 @@ void CL_VM_Error (const char *format, ...) //[515]: hope it will be never execut // Host_AbortCurrentFrame(); //[515]: hmmm... if server says it needs csqc then client MUST disconnect Host_Error(va("CL_VM_Error: %s", errorstring)); } - +void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin) +{ + prvm_eval_t *val; + if(cl.csqc_loaded) + { + CSQC_BEGIN + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_take); + if(val) + val->_float = dmg_take; + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_save); + if(val) + val->_float = dmg_save; + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_origin); + if(val) + { + val->vector[0] = dmg_origin[0]; + val->vector[1] = dmg_origin[1]; + val->vector[2] = dmg_origin[2]; + } + CSQC_END + } +} //[515]: set globals before calling R_UpdateView, WEIRD CRAP static void CSQC_SetGlobals (void) { + prvm_eval_t *val; CSQC_BEGIN prog->globals.client->time = cl.time; prog->globals.client->frametime = max(0, cl.time - cl.oldtime); @@ -56,14 +78,21 @@ static void CSQC_SetGlobals (void) prog->globals.client->clientcommandframe = cl.movecmd[0].sequence; VectorCopy(cl.viewangles, prog->globals.client->input_angles); VectorCopy(cl.viewangles, cl.csqc_angles); + // // FIXME: this actually belongs into getinputstate().. [12/17/2007 Black] prog->globals.client->input_buttons = cl.movecmd[0].buttons; VectorSet(prog->globals.client->input_movevalues, cl.movecmd[0].forwardmove, cl.movecmd[0].sidemove, cl.movecmd[0].upmove); //VectorCopy(cl.movement_origin, cl.csqc_origin); Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, cl.csqc_origin); + + // LordHavoc: Spike says not to do this, but without pmove_org the + // CSQC is useless as it can't alter the view origin without + // completely replacing it VectorCopy(cl.csqc_origin, prog->globals.client->pmove_org); - prog->globals.client->maxclients = cl.maxclients; - //VectorCopy(cl.movement_velocity, prog->globals.client->pmove_vel); VectorCopy(cl.velocity, prog->globals.client->pmove_vel); + + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_angles))) + VectorCopy(cl.viewangles, val->vector); + prog->globals.client->maxclients = cl.maxclients; CSQC_END } @@ -96,6 +125,7 @@ extern cvar_t cl_noplayershadow; qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) { int renderflags; + int c; float scale; prvm_eval_t *val; entity_t *e; @@ -111,7 +141,6 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) return false; e->render.model = model; - e->render.colormap = (int)ed->fields.client->colormap; e->render.skinnum = (int)ed->fields.client->skin; e->render.effects |= e->render.model->effects; scale = 1; @@ -166,8 +195,6 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) // concat the matrices to make the entity relative to its tag Matrix4x4_Concat(&e->render.matrix, &tagmatrix, &matrix2); - // make the other useful stuff - CL_UpdateRenderEntity(&e->render); if(renderflags) { @@ -177,27 +204,13 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) if(renderflags & RF_ADDITIVE) e->render.effects |= EF_ADDITIVE; } - if ((e->render.colormap > 0 && e->render.colormap <= cl.maxclients) || e->render.colormap >= 1024) - { - int cb; - unsigned char *cbcolor; - int palcol; - if (e->render.colormap >= 1024) - palcol = (unsigned char)(e->render.colormap-1024); - else - palcol = cl.scores[e->render.colormap-1].colors; - - cb = (palcol & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12; - cbcolor = (unsigned char *) (&palette_complete[cb]); - e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f); - e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f); - e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f); - cb = (palcol & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12; - cbcolor = (unsigned char *) (&palette_complete[cb]); - e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f); - e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f); - e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f); - } + c = (int)ed->fields.client->colormap; + if (c <= 0) + CL_SetEntityColormapColors(&e->render, -1); + else if (c <= cl.maxclients && cl.scores != NULL) + CL_SetEntityColormapColors(&e->render, cl.scores[c-1].colors); + else + CL_SetEntityColormapColors(&e->render, c); // either fullbright or lit if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) @@ -211,26 +224,38 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) if (e->render.flags & RENDER_VIEWMODEL) e->render.flags |= RENDER_NOSELFSHADOW; + // make the other useful stuff + CL_UpdateRenderEntity(&e->render); + return true; } -qboolean CL_VM_InputEvent (qboolean pressed, int key) +qboolean CL_VM_InputEvent (qboolean down, int key) { qboolean r; if(!cl.csqc_loaded) return false; CSQC_BEGIN - prog->globals.client->time = cl.time; - PRVM_G_FLOAT(OFS_PARM0) = pressed; - PRVM_G_FLOAT(OFS_PARM1) = key; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_InputEvent, "QC function CSQC_InputEvent is missing"); - r = CSQC_RETURNVAL; + if (!prog->funcoffsets.CSQC_InputEvent) + r = false; + else + { + prog->globals.client->time = cl.time; + PRVM_G_FLOAT(OFS_PARM0) = !down; // 0 is down, 1 is up + PRVM_G_FLOAT(OFS_PARM1) = key; + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_InputEvent, "QC function CSQC_InputEvent is missing"); + r = CSQC_RETURNVAL; + } CSQC_END return r; } qboolean CL_VM_UpdateView (void) { + vec3_t emptyvector; + emptyvector[0] = 0; + emptyvector[1] = 0; + emptyvector[2] = 0; // vec3_t oldangles; if(!cl.csqc_loaded) return false; @@ -244,6 +269,8 @@ qboolean CL_VM_UpdateView (void) r_refdef.numlights = 0; PRVM_ExecuteProgram(prog->funcoffsets.CSQC_UpdateView, "QC function CSQC_UpdateView is missing"); //VectorCopy(oldangles, cl.viewangles); + // Dresk : Reset Dmg Globals Here + CL_VM_UpdateDmgGlobals(0, 0, emptyvector); CSQC_END return true; } @@ -252,16 +279,19 @@ extern sizebuf_t vm_tempstringsbuf; qboolean CL_VM_ConsoleCommand (const char *cmd) { int restorevm_tempstringsbuf_cursize; - qboolean r; + qboolean r = false; if(!cl.csqc_loaded) return false; CSQC_BEGIN + if (prog->funcoffsets.CSQC_ConsoleCommand) + { prog->globals.client->time = cl.time; restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(cmd); PRVM_ExecuteProgram(prog->funcoffsets.CSQC_ConsoleCommand, "QC function CSQC_ConsoleCommand is missing"); vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; r = CSQC_RETURNVAL; + } CSQC_END return r; } @@ -393,6 +423,90 @@ void CL_VM_Parse_CenterPrint (const char *msg) CSQC_END } +void CL_VM_UpdateIntermissionState (int intermission) +{ + prvm_eval_t *val; + if(cl.csqc_loaded) + { + CSQC_BEGIN + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.intermission); + if(val) + val->_float = intermission; + CSQC_END + } +} +void CL_VM_UpdateShowingScoresState (int showingscores) +{ + prvm_eval_t *val; + if(cl.csqc_loaded) + { + CSQC_BEGIN + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.sb_showscores); + if(val) + val->_float = showingscores; + CSQC_END + } +} +qboolean CL_VM_Event_Sound(int sound_num, int volume, int channel, float attenuation, int ent, vec3_t pos) +{ + qboolean r = false; + if(cl.csqc_loaded) + { + CSQC_BEGIN + if(prog->funcoffsets.CSQC_Event_Sound) + { + prog->globals.client->time = cl.time; + PRVM_G_FLOAT(OFS_PARM0) = ent; + PRVM_G_FLOAT(OFS_PARM1) = channel; + PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(cl.sound_name[sound_num] ); + PRVM_G_FLOAT(OFS_PARM3) = volume; + PRVM_G_FLOAT(OFS_PARM4) = attenuation; + VectorCopy(pos, PRVM_G_VECTOR(OFS_PARM5) ); + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Event_Sound, "QC function CSQC_Event_Sound is missing"); + r = CSQC_RETURNVAL; + } + CSQC_END + } + + return r; +} +void CL_VM_UpdateCoopDeathmatchGlobals (int gametype) +{ + // Avoid global names for clean(er) coding + int localcoop; + int localdeathmatch; + + prvm_eval_t *val; + if(cl.csqc_loaded) + { + if(gametype == GAME_COOP) + { + localcoop = 1; + localdeathmatch = 0; + } + else + if(gametype == GAME_DEATHMATCH) + { + localcoop = 0; + localdeathmatch = 1; + } + else + { + // How did the ServerInfo send an unknown gametype? + // Better just assign the globals as 0... + localcoop = 0; + localdeathmatch = 0; + } + CSQC_BEGIN + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.coop); + if(val) + val->_float = localcoop; + val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.deathmatch); + if(val) + val->_float = localdeathmatch; + CSQC_END + } +} float CL_VM_Event (float event) //[515]: needed ? I'd say "YES", but don't know for what :D { float r = 0; @@ -413,6 +527,12 @@ float CL_VM_Event (float event) //[515]: needed ? I'd say "YES", but don't know void CSQC_ReadEntities (void) { unsigned short entnum, oldself, realentnum; + if(!cl.csqc_loaded) + { + Host_Error ("CSQC_ReadEntities: CSQC is not loaded"); + return; + } + CSQC_BEGIN prog->globals.client->time = cl.time; oldself = prog->globals.client->self; @@ -526,6 +646,7 @@ void CL_VM_Init (void) fs_offset_t csprogsdatasize; int csprogsdatacrc, requiredcrc; int requiredsize; + prvm_eval_t *val; // reset csqc_progcrc after reading it, so that changing servers doesn't // expect csqc on the next server @@ -588,6 +709,7 @@ void CL_VM_Init (void) prog->limit_edicts = CL_MAX_EDICTS; prog->reserved_edicts = 0; prog->edictprivate_size = sizeof(edict_engineprivate_t); + // TODO: add a shared extension string #define and add real support for csqc extension strings [12/5/2007 Black] prog->extensionstring = vm_sv_extensions; prog->builtins = vm_cl_builtins; prog->numbuiltins = vm_cl_numbuiltins; @@ -623,6 +745,11 @@ void CL_VM_Init (void) prog->globals.client->mapname = PRVM_SetEngineString(cl.worldmodel->name); prog->globals.client->player_localentnum = cl.playerentity; + // set map description (use world entity 0) + val = PRVM_EDICTFIELDVALUE(prog->edicts, prog->fieldoffsets.message); + if(val) + val->string = PRVM_SetEngineString(cl.levelname); + // call the prog init PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Init, "QC function CSQC_Init is missing"); @@ -631,6 +758,9 @@ void CL_VM_Init (void) cl.csqc_vidvars.drawcrosshair = false; cl.csqc_vidvars.drawenginesbar = false; + + // Update Coop and Deathmatch Globals (at this point the client knows them from ServerInfo) + CL_VM_UpdateCoopDeathmatchGlobals(cl.gametype); } void CL_VM_ShutDown (void) @@ -642,7 +772,8 @@ void CL_VM_ShutDown (void) return; CSQC_BEGIN prog->globals.client->time = cl.time; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Shutdown, "QC function CSQC_Shutdown is missing"); + if (prog->funcoffsets.CSQC_Shutdown) + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Shutdown, "QC function CSQC_Shutdown is missing"); PRVM_ResetProg(); CSQC_END Con_Print("CSQC ^1unloaded\n");