]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - clvm_cmds.c
CL_VM_GetLight: allow 2'nd optional parm which sets sampling mask: 1 lightmap (defaul...
[xonotic/darkplaces.git] / clvm_cmds.c
index 6779946e6c1b5b0cb56fa6fd902a9da49f08a0ef..f816eb35a7f6c1121fed8c2806fb11ee4bb1506a 100644 (file)
@@ -29,7 +29,6 @@ void Sbar_SortFrags (void);
 void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
 void CSQC_RelinkAllEntities (int drawmask);
 void CSQC_RelinkCSQCEntities (void);
-const char *Key_GetBind (int key);
 
 // #1 void(vector ang) makevectors
 static void VM_CL_makevectors (void)
@@ -668,24 +667,25 @@ static void VM_CL_ambientsound (void)
        S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64);
 }
 
-// #92 vector(vector org) getlight (DP_QC_GETLIGHT)
+// #92 vector(vector org[, float lpflag]) getlight (DP_QC_GETLIGHT)
 static void VM_CL_getlight (void)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
        vec_t *p;
 
-       VM_SAFEPARMCOUNT(1, VM_CL_getlight);
+       VM_SAFEPARMCOUNTRANGE(1, 2, VM_CL_getlight);
 
        p = PRVM_G_VECTOR(OFS_PARM0);
        VectorClear(ambientcolor);
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
-       if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
+       if (prog->argc >= 2)
+               R_CompleteLightPoint(ambientcolor, diffusecolor, diffusenormal, p, PRVM_G_FLOAT(OFS_PARM1));
+       else if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
                cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
        VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
 }
 
-
 //============================================================================
 //[515]: SCENE MANAGER builtins
 extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed, int edictnum);//csprogs.c
@@ -724,7 +724,7 @@ void VM_CL_R_ClearScene (void)
        r_refdef.view.isoverlay = false;
        // FIXME: restore cl.csqc_origin
        // FIXME: restore cl.csqc_angles
-       cl.csqc_vidvars.drawworld = r_drawworld.integer;
+       cl.csqc_vidvars.drawworld = r_drawworld.integer != 0;
        cl.csqc_vidvars.drawenginesbar = false;
        cl.csqc_vidvars.drawcrosshair = false;
 }
@@ -745,6 +745,8 @@ void VM_CL_R_AddEntities (void)
        prog->globals.client->time = cl.time;
        for(i=1;i<prog->num_edicts;i++)
        {
+               // so we can easily check if CSQC entity #edictnum is currently drawn
+               cl.csqcrenderentities[i].entitynumber = 0;
                ed = &prog->edicts[i];
                if(ed->priv.required->free)
                        continue;
@@ -888,22 +890,28 @@ void VM_CL_R_SetView (void)
        case VF_MIN:
                r_refdef.view.x = (int)(f[0]);
                r_refdef.view.y = (int)(f[1]);
+               DrawQ_RecalcView();
                break;
        case VF_MIN_X:
                r_refdef.view.x = (int)(k);
+               DrawQ_RecalcView();
                break;
        case VF_MIN_Y:
                r_refdef.view.y = (int)(k);
+               DrawQ_RecalcView();
                break;
        case VF_SIZE:
                r_refdef.view.width = (int)(f[0]);
                r_refdef.view.height = (int)(f[1]);
+               DrawQ_RecalcView();
                break;
        case VF_SIZE_X:
                r_refdef.view.width = (int)(k);
+               DrawQ_RecalcView();
                break;
        case VF_SIZE_Y:
                r_refdef.view.height = (int)(k);
+               DrawQ_RecalcView();
                break;
        case VF_VIEWPORT:
                r_refdef.view.x = (int)(f[0]);
@@ -911,6 +919,7 @@ void VM_CL_R_SetView (void)
                f = PRVM_G_VECTOR(OFS_PARM2);
                r_refdef.view.width = (int)(f[0]);
                r_refdef.view.height = (int)(f[1]);
+               DrawQ_RecalcView();
                break;
        case VF_FOV:
                r_refdef.view.frustum_x = tan(f[0] * M_PI / 360.0);r_refdef.view.ortho_x = f[0];
@@ -1052,12 +1061,12 @@ static void VM_CL_unproject (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       if(v_flipped.integer)
-               f[0] = (2 * r_refdef.view.x + r_refdef.view.width) * (vid_conwidth.integer / (float) vid.width) - f[0];
        VectorSet(temp,
                f[2],
-               (-1.0 + 2.0 * (f[0] / (vid_conwidth.integer / (float) vid.width) - r_refdef.view.x) / r_refdef.view.width) * f[2] * -r_refdef.view.frustum_x,
-               (-1.0 + 2.0 * (f[1] / (vid_conheight.integer / (float) vid.height) - r_refdef.view.y) / r_refdef.view.height) * f[2] * -r_refdef.view.frustum_y);
+               (-1.0 + 2.0 * (f[0] / vid_conwidth.integer)) * f[2] * -r_refdef.view.frustum_x,
+               (-1.0 + 2.0 * (f[1] / vid_conheight.integer)) * f[2] * -r_refdef.view.frustum_y);
+       if(v_flipped.integer)
+               temp[1] = -temp[1];
        Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
@@ -1075,9 +1084,12 @@ static void VM_CL_project (void)
        if(v_flipped.integer)
                v[1] = -v[1];
        VectorSet(PRVM_G_VECTOR(OFS_RETURN),
-               (vid_conwidth.integer / (float) vid.width) * (r_refdef.view.x + r_refdef.view.width*0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
-               (vid_conheight.integer / (float) vid.height) * (r_refdef.view.y + r_refdef.view.height*0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
+               vid_conwidth.integer * (0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
+               vid_conheight.integer * (0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
                v[0]);
+       // explanation:
+       // after transforming, relative position to viewport (0..1) = 0.5 * (1 + v[2]/v[0]/-frustum_{x \or y})
+       // as 2D drawing honors the viewport too, to get the same pixel, we simply multiply this by conwidth/height
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
@@ -1249,7 +1261,7 @@ static void VM_CL_pointparticles (void)
 static void VM_CL_boxparticles (void)
 {
        int effectnum;
-       prvm_edict_t *own;
+       // prvm_edict_t *own;
        float *origin_from, *origin_to, *dir_from, *dir_to;
        float count;
        int flags;
@@ -1258,7 +1270,7 @@ static void VM_CL_boxparticles (void)
        VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles);
 
        effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
-       own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
+       // own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
        origin_from = PRVM_G_VECTOR(OFS_PARM2);
        origin_to = PRVM_G_VECTOR(OFS_PARM3);
        dir_from = PRVM_G_VECTOR(OFS_PARM4);
@@ -1299,13 +1311,6 @@ static void VM_CL_setpause(void)
                cl.csqc_paused = false;
 }
 
-//#342 string(float keynum) getkeybind (EXT_CSQC)
-static void VM_CL_getkeybind (void)
-{
-       VM_SAFEPARMCOUNT(1, VM_CL_getkeybind);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0)));
-}
-
 //#343 void(float usecursor) setcursormode (EXT_CSQC)
 static void VM_CL_setcursormode (void)
 {
@@ -1548,7 +1553,7 @@ static void VM_CL_ReadPicture (void)
                        // use the attached jpeg as texture
                        buf = (unsigned char *) Mem_Alloc(tempmempool, size);
                        MSG_ReadBytes(size, buf);
-                       data = JPEG_LoadImage_BGRA(buf, size);
+                       data = JPEG_LoadImage_BGRA(buf, size, NULL);
                        Mem_Free(buf);
                        Draw_NewPic(name, image_width, image_height, false, data);
                        Mem_Free(data);
@@ -2620,8 +2625,8 @@ void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
 void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
 {
        theme->typeindex = (unsigned short)*vmpartspawner.particle_type;
-       theme->blendmode = (pblend_t)*vmpartspawner.particle_blendmode;
-       theme->orientation = (porientation_t)*vmpartspawner.particle_orientation;
+       theme->blendmode = (pblend_t)(int)*vmpartspawner.particle_blendmode;
+       theme->orientation = (porientation_t)(int)*vmpartspawner.particle_orientation;
        theme->color1 = ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]);
        theme->color2 = ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]);
        theme->tex = (int)*vmpartspawner.particle_tex;
@@ -2793,7 +2798,7 @@ void VM_CL_SpawnParticle (void)
        
        if (prog->argc < 3) // global-set particle
        {
-               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)*vmpartspawner.particle_blendmode, (porientation_t)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
                if (!part)
                {
                        PRVM_G_FLOAT(OFS_RETURN) = 0; 
@@ -2847,7 +2852,7 @@ void VM_CL_SpawnParticleDelayed (void)
        org = PRVM_G_VECTOR(OFS_PARM0);
        dir = PRVM_G_VECTOR(OFS_PARM1);
        if (prog->argc < 5) // global-set particle
-               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)*vmpartspawner.particle_blendmode, (porientation_t)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
        else // themed particle
        {
                themenum = (int)PRVM_G_FLOAT(OFS_PARM4);
@@ -2962,6 +2967,7 @@ typedef struct vmpolygons_triangle_s
 {
        rtexture_t              *texture;
        int                             drawflag;
+       qboolean hasalpha;
        unsigned short  elements[3];
 }vmpolygons_triangle_t;
 
@@ -2983,12 +2989,14 @@ typedef struct vmpolygons_s
        unsigned short  *data_sortedelement3s;
 
        qboolean                begin_active;
+       int     begin_draw2d;
        rtexture_t              *begin_texture;
        int                             begin_drawflag;
        int                             begin_vertices;
        float                   begin_vertex[VMPOLYGONS_MAXPOINTS][3];
        float                   begin_color[VMPOLYGONS_MAXPOINTS][4];
        float                   begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
+       qboolean                begin_texture_hasalpha;
 } vmpolygons_t;
 
 // FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
@@ -3068,9 +3076,11 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
        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_ResetTextureState();
        R_EntityMatrix(&identitymatrix);
        GL_CullFace(GL_NONE);
+       GL_DepthTest(true); // polys in 3D space shall always have depth test
+       GL_DepthRange(0, 1);
        R_Mesh_PrepareVertices_Generic_Arrays(polys->num_vertices, polys->data_vertex3f, polys->data_color4f, polys->data_texcoord2f);
 
        for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
@@ -3078,18 +3088,7 @@ 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);
+               DrawQ_ProcessDrawFlag(drawflag, polys->data_triangles[surfacelist[surfacelistindex]].hasalpha);
                R_SetupShader_Generic(tex, NULL, GL_MODULATE, 1);
                numtriangles = 0;
                for (;surfacelistindex < numsurfaces;surfacelistindex++)
@@ -3105,7 +3104,16 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
 
 void VMPolygons_Store(vmpolygons_t *polys)
 {
-       if (r_refdef.draw2dstage)
+       qboolean hasalpha;
+       int i;
+
+       // detect if we have alpha
+       hasalpha = polys->begin_texture_hasalpha;
+       for(i = 0; !hasalpha && (i < polys->begin_vertices); ++i)
+               if(polys->begin_color[i][3] < 1)
+                       hasalpha = true;
+
+       if (polys->begin_draw2d)
        {
                // draw the polygon as 2D immediately
                drawqueuemesh_t mesh;
@@ -3117,7 +3125,7 @@ void VMPolygons_Store(vmpolygons_t *polys)
                mesh.data_vertex3f = polys->begin_vertex[0];
                mesh.data_color4f = polys->begin_color[0];
                mesh.data_texcoord2f = polys->begin_texcoord[0];
-               DrawQ_Mesh(&mesh, polys->begin_drawflag);
+               DrawQ_Mesh(&mesh, polys->begin_drawflag, hasalpha);
        }
        else
        {
@@ -3125,7 +3133,8 @@ void VMPolygons_Store(vmpolygons_t *polys)
                int i;
                if (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
                {
-                       polys->max_triangles *= 2;
+                       while (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
+                               polys->max_triangles *= 2;
                        VM_ResizePolygons(polys);
                }
                if (polys->num_vertices + polys->begin_vertices <= polys->max_vertices)
@@ -3144,6 +3153,7 @@ void VMPolygons_Store(vmpolygons_t *polys)
                                polys->data_triangles[polys->num_triangles].elements[0] = polys->num_vertices;
                                polys->data_triangles[polys->num_triangles].elements[1] = polys->num_vertices + i+1;
                                polys->data_triangles[polys->num_triangles].elements[2] = polys->num_vertices + i+2;
+                               polys->data_triangles[polys->num_triangles].hasalpha = hasalpha;
                                polys->num_triangles++;
                        }
                        polys->num_vertices += polys->begin_vertices;
@@ -3177,7 +3187,7 @@ void VM_CL_AddPolygonsToMeshQueue (void)
          polys->num_vertices = 0;  // otherwise it's not rendered at all and prints an error message --blub */
 }
 
-//void(string texturename, float flag) R_BeginPolygon
+//void(string texturename, float flag[, float is2d]) R_BeginPolygon
 void VM_CL_R_PolygonBegin (void)
 {
        const char              *picname;
@@ -3189,7 +3199,7 @@ void VM_CL_R_PolygonBegin (void)
        // better management of flags, and is more suited for 3D rendering), what
        // about supporting Q3 shaders?
 
-       VM_SAFEPARMCOUNT(2, VM_CL_R_PolygonBegin);
+       VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin);
 
        if (!polys->initialized)
                VM_InitPolygons(polys);
@@ -3227,9 +3237,11 @@ void VM_CL_R_PolygonBegin (void)
        }
 
        polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
+       polys->begin_texture_hasalpha = (sf && sf->base) ? sf->hasalpha : false;
        polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
        polys->begin_vertices = 0;
        polys->begin_active = true;
+       polys->begin_draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage);
 }
 
 //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
@@ -3292,7 +3304,7 @@ void Debug_PolygonBegin(const char *picname, int drawflag)
                Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
                return;
        }
-       debugPolys.begin_texture = picname[0] ? Draw_CachePic (picname)->tex : r_texture_white;
+       debugPolys.begin_texture = picname[0] ? Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT)->tex : r_texture_white;
        debugPolys.begin_drawflag = drawflag;
        debugPolys.begin_vertices = 0;
        debugPolys.begin_active = true;
@@ -3685,7 +3697,7 @@ static void VM_CL_skel_create(void)
                        break;
        if (i == MAX_EDICTS)
                return;
-       prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
+       prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
        PRVM_G_FLOAT(OFS_RETURN) = i + 1;
        skeleton->model = model;
        skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
@@ -4297,7 +4309,7 @@ VM_CL_R_AddEntity,                                // #302 void(entity ent) addentity (EXT_CSQC)
 VM_CL_R_SetView,                               // #303 float(float property, ...) setproperty (EXT_CSQC)
 VM_CL_R_RenderScene,                   // #304 void() renderscene (EXT_CSQC)
 VM_CL_R_AddDynamicLight,               // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-VM_CL_R_PolygonBegin,                  // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+VM_CL_R_PolygonBegin,                  // #306 void(string texturename, float flag, float is2d[NYI: , float lines]) R_BeginPolygon
 VM_CL_R_PolygonVertex,                 // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
 VM_CL_R_PolygonEnd,                            // #308 void() R_EndPolygon
 NULL /* R_LoadWorldModel in menu VM, should stay unassigned in client*/, // #309
@@ -4333,7 +4345,7 @@ VM_centerprint,                                   // #338 void(string s, ...) centerprint (EXT_CSQC)
 VM_print,                                              // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
 VM_keynumtostring,                             // #340 string(float keynum) keynumtostring (EXT_CSQC)
 VM_stringtokeynum,                             // #341 float(string keyname) stringtokeynum (EXT_CSQC)
-VM_CL_getkeybind,                              // #342 string(float keynum) getkeybind (EXT_CSQC)
+VM_getkeybind,                                 // #342 string(float keynum[, float bindmap]) getkeybind (EXT_CSQC)
 VM_CL_setcursormode,                   // #343 void(float usecursor) setcursormode (EXT_CSQC)
 VM_CL_getmousepos,                             // #344 vector() getmousepos (EXT_CSQC)
 VM_CL_getinputstate,                   // #345 float(float framenum) getinputstate (EXT_CSQC)
@@ -4513,7 +4525,7 @@ VM_buf_cvarlist,                                          // #517 void(float buf, string prefix, string antiprefix)
 VM_cvar_description,                                   // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
 VM_gettime,                                            // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
 VM_keynumtostring,                             // #520 string keynumtostring(float keynum)
-VM_findkeysforcommand,                 // #521 string findkeysforcommand(string command)
+VM_findkeysforcommand,                 // #521 string findkeysforcommand(string command[, float bindmap])
 VM_CL_InitParticleSpawner,             // #522 void(float max_themes) initparticlespawner (DP_CSQC_SPAWNPARTICLE)
 VM_CL_ResetParticle,                   // #523 void() resetparticle (DP_CSQC_SPAWNPARTICLE)
 VM_CL_ParticleTheme,                   // #524 void(float theme) particletheme (DP_CSQC_SPAWNPARTICLE)
@@ -4602,7 +4614,7 @@ VM_writetofile,                                   // #606
 VM_isfunction,                                 // #607
 NULL,                                                  // #608
 NULL,                                                  // #609
-NULL,                                                  // #610
+VM_findkeysforcommand,                 // #610 string findkeysforcommand(string command[, float bindmap])
 NULL,                                                  // #611
 NULL,                                                  // #612
 VM_parseentitydata,                            // #613
@@ -4622,7 +4634,10 @@ NULL,                                                    // #626
 VM_sprintf,                     // #627 string sprintf(string format, ...)
 VM_getsurfacenumtriangles,             // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
 VM_getsurfacetriangle,                 // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
-NULL,                                                  // #630
+VM_setkeybind,                                         // #630 float(float key, string bind[, float bindmap]) setkeybind
+VM_getbindmaps,                                                // #631 vector(void) getbindmap
+VM_setbindmaps,                                                // #632 float(vector bm) setbindmap
+NULL,                                                  // #633
 };
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);