]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - csprogs.c
Added a couple todo items related to pq_fullpitch
[xonotic/darkplaces.git] / csprogs.c
index f4ddce2cf5f27d3a65cf6ae6ad5eaf5b70ba273f..fa364ce7b1e00e8bfa861b2d55280665cb61d6cf 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -11,7 +11,7 @@
 // Client prog handling
 //[515]: omg !!! optimize it ! a lot of hacks here and there also :P
 
-#define CSQC_RETURNVAL prog->globals.generic[OFS_RETURN]
+#define CSQC_RETURNVAL prog->globals.fp[OFS_RETURN]
 #define CSQC_BEGIN
 #define CSQC_END
 
@@ -221,12 +221,14 @@ void CSQC_UpdateNetworkTimes(double newtime, double oldtime)
 }
 
 //[515]: set globals before calling R_UpdateView, WEIRD CRAP
-static void CSQC_SetGlobals (void)
+static void CSQC_SetGlobals (double frametime)
 {
+       vec3_t pmove_org;
        prvm_prog_t *prog = CLVM_prog;
        CSQC_BEGIN
                PRVM_clientglobalfloat(time) = cl.time;
-               PRVM_clientglobalfloat(frametime) = max(0, cl.time - cl.oldtime);
+               PRVM_clientglobalfloat(cltime) = realtime; // Spike named it that way.
+               PRVM_clientglobalfloat(frametime) = frametime;
                PRVM_clientglobalfloat(servercommandframe) = cls.servermovesequence;
                PRVM_clientglobalfloat(clientcommandframe) = cl.movecmd[0].sequence;
                VectorCopy(cl.viewangles, PRVM_clientglobalvector(input_angles));
@@ -239,7 +241,8 @@ static void CSQC_SetGlobals (void)
                // 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
-               Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, PRVM_clientglobalvector(pmove_org));
+               Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, pmove_org);
+               VectorCopy(pmove_org, PRVM_clientglobalvector(pmove_org));
                VectorCopy(cl.movement_velocity, PRVM_clientglobalvector(pmove_vel));
                PRVM_clientglobalfloat(pmove_onground) = cl.onground;
                PRVM_clientglobalfloat(pmove_inwater) = cl.inwater;
@@ -348,7 +351,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
 
        // set up the animation data
        VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed);
-       VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model, cl.time);
        VM_UpdateEdictSkeleton(prog, ed, model, ed->priv.server->frameblend);
        if (PRVM_clientedictfloat(ed, shadertime)) // hack for csprogs.dat files that do not set shadertime, leaves the value at entity spawn time
                entrender->shadertime = PRVM_clientedictfloat(ed, shadertime);
@@ -360,9 +363,9 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
        // model light
        if (renderflags & RF_MODELLIGHT)
        {
-               if(PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->modellight_ambient);
-               if(PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->modellight_diffuse);
-               if(PRVM_clientedictvector(ed, modellight_dir))     VectorCopy(PRVM_clientedictvector(ed, modellight_dir), entrender->modellight_lightdir);
+               if (PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->modellight_ambient); else VectorClear(entrender->modellight_ambient);
+               if (PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->modellight_diffuse); else VectorClear(entrender->modellight_diffuse);
+               if (PRVM_clientedictvector(ed, modellight_dir))     VectorCopy(PRVM_clientedictvector(ed, modellight_dir), entrender->modellight_lightdir);    else VectorClear(entrender->modellight_lightdir);
                entrender->flags |= RENDER_CUSTOMIZEDMODELLIGHT;
        }
 
@@ -373,6 +376,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
                if(renderflags & RF_WORLDOBJECT) entrender->flags |= RENDER_WORLDOBJECT;
                if(renderflags & RF_DEPTHHACK) entrender->flags |= RENDER_NODEPTHTEST;
                if(renderflags & RF_ADDITIVE) entrender->flags |= RENDER_ADDITIVE;
+               if(renderflags & RF_DYNAMICMODELLIGHT) entrender->flags |= RENDER_DYNAMICMODELLIGHT;
        }
 
        c = (int)PRVM_clientedictfloat(ed, colormap);
@@ -409,10 +413,13 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
                entrender->flags |= RENDER_ADDITIVE;
        if (entrender->effects & EF_DOUBLESIDED)
                entrender->flags |= RENDER_DOUBLESIDED;
+       if (entrender->effects & EF_DYNAMICMODELLIGHT)
+               entrender->flags |= RENDER_DYNAMICMODELLIGHT;
 
        // make the other useful stuff
        memcpy(entrender->framegroupblend, ed->priv.server->framegroupblend, sizeof(ed->priv.server->framegroupblend));
        CL_UpdateRenderEntity(entrender);
+
        // override animation data with full control
        memcpy(entrender->frameblend, ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend));
        if (ed->priv.server->skeleton.relativetransforms)
@@ -427,7 +434,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
 // 1 = keyup, key, character (EXT_CSQC)
 // 2 = mousemove relative, x, y (EXT_CSQC)
 // 3 = mousemove absolute, x, y (DP_CSQC)
-qboolean CL_VM_InputEvent (int eventtype, int x, int y)
+qboolean CL_VM_InputEvent (int eventtype, float x, float y)
 {
        prvm_prog_t *prog = CLVM_prog;
        qboolean r;
@@ -454,7 +461,7 @@ qboolean CL_VM_InputEvent (int eventtype, int x, int y)
 
 extern r_refdef_view_t csqc_original_r_refdef_view;
 extern r_refdef_view_t csqc_main_r_refdef_view;
-qboolean CL_VM_UpdateView (void)
+qboolean CL_VM_UpdateView (double frametime)
 {
        prvm_prog_t *prog = CLVM_prog;
        vec3_t emptyvector;
@@ -472,7 +479,7 @@ qboolean CL_VM_UpdateView (void)
                //VectorCopy(cl.viewangles, oldangles);
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-               CSQC_SetGlobals();
+               CSQC_SetGlobals(frametime);
                // clear renderable entity and light lists to prevent crashes if the
                // CSQC_UpdateView function does not call R_ClearScene as it should
                r_refdef.scene.numentities = 0;
@@ -895,7 +902,7 @@ static void CLVM_free_edict(prvm_prog_t *prog, prvm_edict_t *ed)
        R_DecalSystem_Reset(&entrender->decalsystem);
        memset(entrender, 0, sizeof(*entrender));
        World_UnlinkEdict(ed);
-       memset(ed->fields.vp, 0, prog->entityfields * 4);
+       memset(ed->fields.fp, 0, prog->entityfields * sizeof(prvm_vec_t));
        VM_RemoveEdictSkeleton(prog, ed);
        World_Physics_RemoveFromEntity(&cl.world, ed);
        World_Physics_RemoveJointFromEntity(&cl.world, ed);
@@ -935,7 +942,7 @@ static qboolean CLVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
 qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t len, int crc, int cnt, sizebuf_t *buf, int protocol)
 {
        int packetsize = buf->maxsize - 7; // byte short long
-       int npackets = (len + packetsize - 1) / (packetsize);
+       int npackets = ((int)len + packetsize - 1) / (packetsize);
        char vabuf[1024];
 
        if(protocol == PROTOCOL_QUAKEWORLD)
@@ -951,7 +958,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t le
        else if(cnt >= 1 && cnt <= npackets)
        {
                unsigned long thispacketoffset = (cnt - 1) * packetsize;
-               int thispacketsize = len - thispacketoffset;
+               int thispacketsize = (int)len - thispacketoffset;
                if(thispacketsize > packetsize)
                        thispacketsize = packetsize;
 
@@ -994,11 +1001,22 @@ void CL_VM_Init (void)
                return;
 
        // see if the requested csprogs.dat file matches the requested crc
-       csprogsdatacrc = -1;
        if (!cls.demoplayback || csqc_usedemoprogs.integer)
        {
                csprogsfn = va(vabuf, sizeof(vabuf), "dlcache/%s.%i.%i", csqc_progname.string, requiredsize, requiredcrc);
-               csprogsdata = FS_LoadFile(csprogsfn, tempmempool, true, &csprogsdatasize);
+               if(cls.caughtcsprogsdata && cls.caughtcsprogsdatasize == requiredsize && CRC_Block(cls.caughtcsprogsdata, (size_t)cls.caughtcsprogsdatasize) == requiredcrc)
+               {
+                       Con_DPrintf("Using buffered \"%s\"\n", csprogsfn);
+                       csprogsdata = cls.caughtcsprogsdata;
+                       csprogsdatasize = cls.caughtcsprogsdatasize;
+                       cls.caughtcsprogsdata = NULL;
+                       cls.caughtcsprogsdatasize = 0;
+               }
+               else
+               {
+                       Con_DPrintf("Not using buffered \"%s\" (buffered: %p, %d)\n", csprogsfn, cls.caughtcsprogsdata, (int) cls.caughtcsprogsdatasize);
+                       csprogsdata = FS_LoadFile(csprogsfn, tempmempool, true, &csprogsdatasize);
+               }
        }
        if (!csprogsdata)
        {
@@ -1068,7 +1086,7 @@ void CL_VM_Init (void)
        prog->error_cmd             = Host_Error;
        prog->ExecuteProgram        = CLVM_ExecuteProgram;
 
-       PRVM_Prog_Load(prog, csprogsfn, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals);
+       PRVM_Prog_Load(prog, csprogsfn, csprogsdata, csprogsdatasize, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals);
 
        if (!prog->loaded)
        {
@@ -1121,10 +1139,15 @@ void CL_VM_Init (void)
        PRVM_clientedictstring(prog->edicts, message) = PRVM_SetEngineString(prog, cl.worldmessage);
        VectorCopy(cl.world.mins, PRVM_clientedictvector(prog->edicts, mins));
        VectorCopy(cl.world.maxs, PRVM_clientedictvector(prog->edicts, maxs));
+       VectorCopy(cl.world.mins, PRVM_clientedictvector(prog->edicts, absmin));
+       VectorCopy(cl.world.maxs, PRVM_clientedictvector(prog->edicts, absmax));
 
        // call the prog init
        prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Init), "QC function CSQC_Init is missing");
 
+       // Once CSQC_Init was called, we consider csqc code fully initialized.
+       prog->inittime = realtime;
+
        cl.csqc_loaded = true;
 
        cl.csqc_vidvars.drawcrosshair = false;
@@ -1143,10 +1166,13 @@ void CL_VM_ShutDown (void)
        if(!cl.csqc_loaded)
                return;
        CSQC_BEGIN
-               PRVM_clientglobalfloat(time) = cl.time;
-               PRVM_clientglobaledict(self) = 0;
-               if (PRVM_clientfunction(CSQC_Shutdown))
-                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Shutdown), "QC function CSQC_Shutdown is missing");
+               if (prog->loaded)
+               {
+                       PRVM_clientglobalfloat(time) = cl.time;
+                       PRVM_clientglobaledict(self) = 0;
+                       if (PRVM_clientfunction(CSQC_Shutdown))
+                               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Shutdown), "QC function CSQC_Shutdown is missing");
+               }
                PRVM_Prog_Reset(prog);
        CSQC_END
        Con_DPrint("CSQC ^1unloaded\n");
@@ -1198,7 +1224,7 @@ qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clip
                if(PRVM_clientedictfunction(ed, camera_transform))
                {
                        ret = true;
-                       if(viewmatrix || clipplane || visorigin)
+                       if(viewmatrix && clipplane && visorigin)
                        {
                                Matrix4x4_ToVectors(viewmatrix, forward, left, up, origin);
                                AnglesFromVectors(ang, forward, up, false);
@@ -1219,7 +1245,7 @@ qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clip
                                Matrix4x4_Invert_Full(&mat, viewmatrix);
                                Matrix4x4_FromVectors(viewmatrix, forward, left, up, origin);
                                Matrix4x4_Concat(&matq, viewmatrix, &mat);
-                               Matrix4x4_TransformPositivePlane(&matq, clipplane->normal[0], clipplane->normal[1], clipplane->normal[2], clipplane->dist, &clipplane->normal[0]);
+                               Matrix4x4_TransformPositivePlane(&matq, clipplane->normal[0], clipplane->normal[1], clipplane->normal[2], clipplane->dist, clipplane->normal_and_dist);
                        }
                }
        CSQC_END