]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - clvm_cmds.c
new tokenizer tokenize_console that matches the console tokenizing
[xonotic/darkplaces.git] / clvm_cmds.c
index 16c9ce81f4ad356534c7fd52bc372e907ec75917..8f72cc46bc7a393816426ca98471bfe2f68e747c 100644 (file)
@@ -20,6 +20,8 @@
 //4 feature darkplaces csqc: add builtin to clientside qc for reading triangles of model meshes (useful to orient a ui along a triangle of a model mesh)
 //4 feature darkplaces csqc: add builtins to clientside qc for gl calls
 
+extern cvar_t v_flipped;
+
 sfx_t *S_FindName(const char *name);
 int Sbar_GetSortedPlayerIndex (int index);
 void Sbar_SortFrags (void);
@@ -753,31 +755,31 @@ void VM_CL_R_SetView (void)
        switch(c)
        {
        case VF_MIN:
-               r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               r_refdef.view.x = (int)(f[0]);
+               r_refdef.view.y = (int)(f[1]);
                break;
        case VF_MIN_X:
-               r_refdef.view.x = (int)(k * vid.width / vid_conwidth.value);
+               r_refdef.view.x = (int)(k);
                break;
        case VF_MIN_Y:
-               r_refdef.view.y = (int)(k * vid.height / vid_conheight.value);
+               r_refdef.view.y = (int)(k);
                break;
        case VF_SIZE:
-               r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               r_refdef.view.width = (int)(f[0]);
+               r_refdef.view.height = (int)(f[1]);
                break;
        case VF_SIZE_X:
-               r_refdef.view.width = (int)(k * vid.width / vid_conwidth.value);
+               r_refdef.view.width = (int)(k);
                break;
        case VF_SIZE_Y:
-               r_refdef.view.height = (int)(k * vid.height / vid_conheight.value);
+               r_refdef.view.height = (int)(k);
                break;
        case VF_VIEWPORT:
-               r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               r_refdef.view.x = (int)(f[0]);
+               r_refdef.view.y = (int)(f[1]);
                f = PRVM_G_VECTOR(OFS_PARM2);
-               r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-               r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               r_refdef.view.width = (int)(f[0]);
+               r_refdef.view.height = (int)(f[1]);
                break;
        case VF_FOV:
                r_refdef.view.frustum_x = tan(f[0] * M_PI / 360.0);r_refdef.view.ortho_x = f[0];
@@ -916,7 +918,9 @@ static void VM_CL_unproject (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       VectorSet(temp, f[2], f[0] * f[2] * -r_refdef.view.frustum_x * 2.0 / r_refdef.view.width, f[1] * f[2] * -r_refdef.view.frustum_y * 2.0 / r_refdef.view.height);
+       if(v_flipped.integer)
+               f[0] = r_refdef.view.x + r_refdef.view.width - f[0];
+       VectorSet(temp, f[2], (-1.0 + 2.0 * (f[0] - r_refdef.view.x)) / r_refdef.view.width * f[2] * -r_refdef.view.frustum_x, (-1.0 + 2.0 * (f[1] - r_refdef.view.y))  / r_refdef.view.height * f[2] * -r_refdef.view.frustum_y);
        Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
@@ -931,7 +935,9 @@ static void VM_CL_project (void)
        f = PRVM_G_VECTOR(OFS_PARM0);
        Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix);
        Matrix4x4_Transform(&m, f, v);
-       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_refdef.view.frustum_x*0.5*r_refdef.view.width, v[2]/v[0]/-r_refdef.view.frustum_y*r_refdef.view.height*0.5, v[0]);
+       if(v_flipped.integer)
+               v[1] = -v[1];
+       VectorSet(PRVM_G_VECTOR(OFS_RETURN), r_refdef.view.x + r_refdef.view.width*0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x), r_refdef.view.y + r_refdef.view.height*0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y), v[0]);
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
@@ -2373,6 +2379,7 @@ typedef struct vmpolygons_s
 {
        mempool_t               *pool;
        qboolean                initialized;
+       double          progstarttime;
 
        int                             max_vertices;
        int                             num_vertices;
@@ -2412,6 +2419,7 @@ void VM_CL_R_RenderScene (void)
        R_RenderView();
 
        polys->num_vertices = polys->num_triangles = 0;
+       polys->progstarttime = prog->starttime;
 }
 
 static void VM_ResizePolygons(vmpolygons_t *polys)
@@ -2463,6 +2471,8 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
 {
        int surfacelistindex;
        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       if(polys->progstarttime != prog->starttime) // from other progs? won't draw these (this can cause crashes!)
+               return;
        R_Mesh_ResetTextureState();
        R_Mesh_Matrix(&identitymatrix);
        GL_CullFace(GL_NONE);
@@ -2476,12 +2486,16 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
                int numtriangles = 0;
                rtexture_t *tex = polys->data_triangles[surfacelist[surfacelistindex]].texture;
                int drawflag = polys->data_triangles[surfacelist[surfacelistindex]].drawflag;
+               // this can't call _DrawQ_ProcessDrawFlag, but should be in sync with it
+               // FIXME factor this out
                if(drawflag == DRAWFLAG_ADDITIVE)
                        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
                else if(drawflag == DRAWFLAG_MODULATE)
                        GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
                else if(drawflag == DRAWFLAG_2XMODULATE)
                        GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
+               else if(drawflag == DRAWFLAG_SCREEN)
+                       GL_BlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);
                else
                        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                R_Mesh_TexBind(0, R_GetTexture(tex));
@@ -2574,20 +2588,53 @@ void VM_CL_AddPolygonsToMeshQueue (void)
 void VM_CL_R_PolygonBegin (void)
 {
        const char              *picname;
+       skinframe_t     *sf;
        vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       int tf;
+
+       // TODO instead of using skinframes here (which provides the benefit of
+       // better management of flags, and is more suited for 3D rendering), what
+       // about supporting Q3 shaders?
 
        VM_SAFEPARMCOUNT(2, VM_CL_R_PolygonBegin);
 
        if (!polys->initialized)
                VM_InitPolygons(polys);
+       if(polys->progstarttime != prog->starttime)
+       {
+               // from another progs? then reset the polys first (fixes crashes on map change, because that can make skinframe textures invalid)
+               polys->num_vertices = polys->num_triangles = 0;
+               polys->progstarttime = prog->starttime;
+       }
        if (polys->begin_active)
        {
                VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
                return;
        }
        picname = PRVM_G_STRING(OFS_PARM0);
-       polys->begin_texture = picname[0] ? Draw_CachePic_Flags (picname, CACHEPICFLAG_NOCLAMP)->tex : r_texture_white;
-       polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1);
+
+       sf = NULL;
+       if(*picname)
+       {
+               tf = TEXF_ALPHA;
+               if((int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MIPMAP)
+                       tf |= TEXF_MIPMAP;
+
+               do
+               {
+                       sf = R_SkinFrame_FindNextByName(sf, picname);
+               }
+               while(sf && sf->textureflags != tf);
+
+               if(!sf || !sf->base)
+                       sf = R_SkinFrame_LoadExternal(picname, tf, true);
+
+               if(sf)
+                       R_SkinFrame_MarkUsed(sf);
+       }
+
+       polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
+       polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
        polys->begin_vertices = 0;
        polys->begin_active = true;
 }
@@ -3487,13 +3534,15 @@ NULL,                                                   // #509
 VM_uri_escape,                                 // #510 string(string in) uri_escape = #510;
 VM_uri_unescape,                               // #511 string(string in) uri_unescape = #511;
 VM_etof,                                       // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
-NULL,                                                  // #513
-NULL,                                                  // #514
-NULL,                                                  // #515
-NULL,                                                  // #516
+VM_uri_get,                                            // #513 float(string uril, float id) uri_get = #512; (DP_QC_URI_GET)
+VM_tokenize_console,                                   // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_start_index,                                   // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_end_index,                                             // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
 NULL,                                                  // #517
 NULL,                                                  // #518
 NULL,                                                  // #519
+VM_keynumtostring,                             // #520 string keynumtostring(float keynum)
+VM_findkeysforcommand,         // #521 string findkeysforcommand(string command)
 };
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);