fteqw/quakec/csaddon/src/editor_lights.qc
Spoike 9e8bb446f4 implemented pm_stepdown.
attempt to implement 'simple csqc' api.
handle qw+nq gunshot+blood+lightning differently - they do actually have different particle spawn patterns (qw is a single point, so spreads wider).
fix q3ui logo mesh thing. work around q3ui player meshes on d3d.
split video and renderer latching, so vid_reload delatches more stuff.
fix autosprite+autosprite2 in 6 different renderers...
added fog volumes to d3d9 renderer.
using matrix hacks instead of glDepthRange, this should give more consistent behaviour, especially now that we have r_viewmodel_fov.
small cleanup for gl shadowmaps to make the interface more consistent with other renderers.
added patchDef2 parsing to fte's .map loader, doesn't actually use it though.
some fixes for q3's shaders, including to try to get overbright working better.
updated customskin api to give more control.
first attempt at a packager system for fteqccgui. probably useless, but whatever.
menusys changes to try to support QSS's csqc.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5200 fc73d0e0-1445-4013-8a0c-d673dee63da5
2018-01-22 19:18:04 +00:00

467 lines
15 KiB
C++

/*FTE has some special light editing builtins, I don't ever expect them to be standard or anything, but they're handy for this*/
/*you probably want to change this if you're running hexen2*/
var string autocvar_cg_editor_lightmodel = "progs/s_light.spr";
var float autocvar_r_editlights_import_ambient = 0;
var float autocvar_r_editlights_import_diffuse = 1;
var float autocvar_r_editlights_import_specular = 1;
static float selectedlight;
static float editfield;
static string editvalue;
static entity tempent;
static float helphidden;
void() editor_lights_addentities =
{
float l;
if (!tempent)
tempent = spawn();
l = (float)dynamiclight_get(-1, -1);
precache_model(autocvar_cg_editor_lightmodel); /*just to silence it*/
setmodel(tempent, autocvar_cg_editor_lightmodel);
while(l > 0)
{
l = l-1.0;
if (l == selectedlight)
{
if (gettime(0)*5f & 1)
continue;
tempent.effects |= 8192f;
}
else
tempent.effects &~= 8192f;
if (!(float)dynamiclight_get(l, LFIELD_RADIUS))
continue;
setorigin(tempent, dynamiclight_get(l, LFIELD_ORIGIN));
addentity(tempent);
}
};
#define NUMLFIELDS 15
#define NUMCMDS 7
static var string fldname[NUMLFIELDS+1+NUMCMDS] = { "bad",
" num",
" org",
" rgb",
" rad",
" flg",
" sty",
" ang",
" fov",
" cmp",
" cor",
" csc",
" amb",
" dif",
" spc",
" avl",
"Save",
"World Lights",
"Dynamic Lights",
"Toggle Help",
"Wipe All",
"Import",
"Reload"
};
static string(int fld, float foredit) readfield =
{
switch(fld)
{
case 1:
if (foredit)
return ftos(selectedlight);
return strcat(ftos(selectedlight), " / ", ftos(dynamiclight_get(-1f, -1f)));
case 2:
return sprintf("%v", (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN));
case 3:
return sprintf("%v", (vector)dynamiclight_get(selectedlight, LFIELD_COLOUR));
case 4:
return ftos(dynamiclight_get(selectedlight, LFIELD_RADIUS));
case 5:
float fl = (float)dynamiclight_get(selectedlight, LFIELD_FLAGS);
string ret;
ret = strcat(ret, (fl & LFLAG_NORMALMODE)?"d":"");
ret = strcat(ret, (fl & LFLAG_REALTIMEMODE)?"w":"");
ret = strcat(ret, (fl & LFLAG_LIGHTMAP)?"l":"");
ret = strcat(ret, (fl & LFLAG_FLASHBLEND)?"f":"");
ret = strcat(ret, (fl & LFLAG_NOSHADOWS)?"c":"");
ret = strcat(ret, (fl & LFLAG_SHADOWMAP)?"s":"");
ret = strcat(ret, (fl & LFLAG_CREPUSCULAR)?"r":"");
ret = strcat(ret, (fl & LFLAG_ORTHO)?"o":"");
return ret;
case 6:
return ftos(dynamiclight_get(selectedlight, LFIELD_STYLE));
case 7:
return sprintf("%v", (vector)dynamiclight_get(selectedlight, LFIELD_ANGLES));
case 8:
return ftos(dynamiclight_get(selectedlight, LFIELD_FOV));
case 9:
return (string)dynamiclight_get(selectedlight, LFIELD_CUBEMAPNAME);
case 10:
return ftos(dynamiclight_get(selectedlight, LFIELD_CORONA));
case 11:
return ftos(dynamiclight_get(selectedlight, LFIELD_CORONASCALE));
case 12:
return ftos(dynamiclight_get(selectedlight, LFIELD_AMBIENTSCALE));
case 13:
return ftos(dynamiclight_get(selectedlight, LFIELD_DIFFUSESCALE));
case 14:
return ftos(dynamiclight_get(selectedlight, LFIELD_SPECULARSCALE));
case 15:
return sprintf("%v", (vector)dynamiclight_get(selectedlight, LFIELD_ROTATION));
default:
return "";
}
};
static void(float fld, string newval) writefield =
{
switch(fld)
{
case 1:
selectedlight = stof(newval);
return;
case 2:
dynamiclight_set(selectedlight, LFIELD_ORIGIN, stov(newval));
return;
case 3:
dynamiclight_set(selectedlight, LFIELD_COLOUR, stov(newval));
return;
case 4:
dynamiclight_set(selectedlight, LFIELD_RADIUS, stof(newval));
return;
case 5:
var float fl = 0;
if (strstrofs(newval, "d")>=0) fl |= LFLAG_NORMALMODE;
if (strstrofs(newval, "w")>=0) fl |= LFLAG_REALTIMEMODE;
if (strstrofs(newval, "l")>=0) fl |= LFLAG_LIGHTMAP;
if (strstrofs(newval, "f")>=0) fl |= LFLAG_FLASHBLEND;
if (strstrofs(newval, "c")>=0) fl |= LFLAG_NOSHADOWS;
if (strstrofs(newval, "s")>=0) fl |= LFLAG_SHADOWMAP;
if (strstrofs(newval, "r")>=0) fl |= LFLAG_CREPUSCULAR;
if (strstrofs(newval, "o")>=0) fl |= LFLAG_ORTHO;
dynamiclight_set(selectedlight, LFIELD_FLAGS, (float)fl);
return;
case 6:
dynamiclight_set(selectedlight, LFIELD_STYLE, stof(newval));
return;
case 7:
dynamiclight_set(selectedlight, LFIELD_ANGLES, stov(newval));
return;
case 8:
dynamiclight_set(selectedlight, LFIELD_FOV, stof(newval));
return;
case 9:
dynamiclight_set(selectedlight, LFIELD_CUBEMAPNAME, newval);
return;
case 10:
dynamiclight_set(selectedlight, LFIELD_CORONA, stof(newval));
return;
case 11:
dynamiclight_set(selectedlight, LFIELD_CORONASCALE, stof(newval));
return;
case 12:
dynamiclight_set(selectedlight, LFIELD_AMBIENTSCALE, stof(newval));
return;
case 13:
dynamiclight_set(selectedlight, LFIELD_DIFFUSESCALE, stof(newval));
return;
case 14:
dynamiclight_set(selectedlight, LFIELD_SPECULARSCALE, stof(newval));
return;
case 15:
dynamiclight_set(selectedlight, LFIELD_ROTATION, stov(newval));
return;
default:
return;
}
};
void(vector m) editor_lights_overlay =
{
int i;
string s;
vector col;
m_y = floor((m_y - 32f) / 8f);
fldname[NUMLFIELDS+2] = strcat("realtime world: ", cvar("r_shadow_realtime_world")?"on":"off");
fldname[NUMLFIELDS+3] = strcat("realtime dlight: ", cvar("r_shadow_realtime_dlight")?"on":"off");
for (i = 1; i <= NUMLFIELDS; i++)
{
if (editfield == i)
s = editvalue;
else
s = readfield(i, 0);
s = strcat(ftos(i), " ", fldname[i], ": ", s);
if (editfield == i)
col = '1 0 0';
else if (m_y == i && m_x < 64)
col = '0 0 1';
else
col = '1 1 1';
drawrawstring('0 32 0' + '0 8 0' * (float)i, s, '8 8 0', col, 1);
}
for (i = NUMLFIELDS+1f; i <= NUMLFIELDS+NUMCMDS; i+=1)
{
s = strcat(ftos(i), " ", fldname[i]);
if (editfield == i)
col = '1 0 0';
else if (m_y == i && m_x < 64)
col = '0 0 1';
else
col = '1 1 1';
drawrawstring('0 32 0' + '0 8 0' * (float)i, s, '8 8 0', col, 1);
}
i+=1i;
if (helphidden)
return;
if (editfield == 5)
{
drawrawstring('0 32 0' + '0 8 0' * (float)i, "d: dynamic mode\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "w: realtime world lights mode\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "l: lightmap hack (not valid above index 32)\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "f: flashblend coronas\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "c: does not cast shadows\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "s: shadowmapped light\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "r: crepuscular rays\n", '8 8 0', '1 1 1', 1); i+=1i;
}
else
{
drawrawstring('0 32 0' + '0 8 0' * (float)i, "+/- change selected light\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "mouse also selects lights\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "m moves the light to the cursor\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "i inserts new light\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "@ sets the light's radius to the cursor\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "# changes the light's shadow flag\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "p points the light to aim at the cursor\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "[ and ] move the light towards/away from indicated plane\n", '8 8 0', '1 1 1', 1); i+=1i;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "don't forget to save\n", '8 8 0', '1 1 1', 1); i+=1i;
}
};
static void(vector fwd, vector vorg) selectbestlight =
{
float l, b=selectedlight, d, bd;
vector ldir;
l = (float)dynamiclight_get(-1f, -1f);
bd = 0;
while(l > 0)
{
l-=1;
ldir = (vector)dynamiclight_get(l, LFIELD_ORIGIN);
ldir = normalize(ldir - vorg);
d = fwd*ldir;
if (d > bd)
{
bd = d;
b = l;
}
}
selectedlight = b;
};
float(float keyc, float unic, vector m) editor_lights_key =
{
vector t = unproject(m + '0 0 8192');
vector o = unproject(m);
string ns;
if (keyc == 512 || (!editfield && unic == 13 && m_x < 64))
{
if (editfield)
{
writefield(editfield, editvalue);
strunzone(editvalue);
editfield = 0;
}
editfield = floor((m_y - 32f) / 8f);
if (editfield <= 0 || editfield > NUMLFIELDS+NUMCMDS || m_x >= 64)
{
editfield = 0;
selectbestlight(t - o, o);
}
else if (editfield > NUMLFIELDS)
{
switch(editfield - (NUMLFIELDS+1))
{
case 0:
localcmd("r_editlights_save\n");
break;
case 1:
localcmd("toggle r_shadow_realtime_world\n");
break;
case 2:
localcmd("toggle r_shadow_realtime_dlight\n");
break;
case 3:
helphidden = !helphidden;
break;
case 4:
localcmd("r_editlights_reload none\n");
break;
case 5:
localcmd("r_editlights_reload bsp\n");
break;
case 6:
localcmd("r_editlights_reload\n");
break;
}
editfield = 0;
}
else
editvalue = strzone(readfield(editfield, 1));
}
else if (editfield)
{
ns = strcat(editvalue);
if (keyc == 10 || keyc == 13)
{
writefield(editfield, ns);
editfield = 0;
}
else if (keyc == 127)
{
if (ns != "")
ns = substring(ns, 0, -2);
}
else if (keyc == 8)
{
ns = "";
}
else
ns = strcat(ns, chr2str(unic));
ns = strzone(ns);
strunzone(editvalue);
editvalue = ns;
writefield(editfield, ns);
}
else if (unic >= '0' && unic <= '9')
{
editfield = unic - '0';
editvalue = strzone(readfield(editfield, 1));
}
else if (unic == '=')
selectedlight++;
else if (unic == '-')
selectedlight-=1;
else if (unic == 'n' || unic == 'N')
localcmd("noclip\n");
// else if (unic == 's' || unic == 'S')
// {
// selectbestlight(t - o, o);
// }
else if (unic == 'm' || unic == 'M')
{
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4);
}
else if (unic == 'p' || unic == 'P')
{
traceline(o, t, TRUE, world);
vector ang = vectoangles((trace_endpos + trace_plane_normal*4f) - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN));
ang_x *= -1f;
dynamiclight_set(selectedlight, LFIELD_ANGLES, ang);
/*if we're pointing the light at something, it should probably have a fov*/
if (!(float)dynamiclight_get(selectedlight, LFIELD_FOV))
dynamiclight_set(selectedlight, LFIELD_FOV, 90f);
}
else if (unic == 'i' || unic == 'I')
{
float oldl = selectedlight;
for (selectedlight = 32; ; selectedlight+=1)
{
if (!(float)dynamiclight_get(selectedlight, LFIELD_RADIUS))
{
if (oldl >= 32 && (!((float)dynamiclight_get(selectedlight, LFIELD_RADIUS) > 50)))
{
/*dupe the current light*/
dynamiclight_set(selectedlight, LFIELD_RADIUS, dynamiclight_get(oldl, LFIELD_RADIUS));
dynamiclight_set(selectedlight, LFIELD_COLOUR, dynamiclight_get(oldl, LFIELD_COLOUR));
dynamiclight_set(selectedlight, LFIELD_FOV, dynamiclight_get(oldl, LFIELD_FOV));
dynamiclight_set(selectedlight, LFIELD_STYLE, dynamiclight_get(oldl, LFIELD_STYLE));
dynamiclight_set(selectedlight, LFIELD_ANGLES, dynamiclight_get(oldl, LFIELD_ANGLES));
dynamiclight_set(selectedlight, LFIELD_FLAGS, dynamiclight_get(oldl, LFIELD_FLAGS));
dynamiclight_set(selectedlight, LFIELD_AMBIENTSCALE, dynamiclight_get(oldl, LFIELD_AMBIENTSCALE));
dynamiclight_set(selectedlight, LFIELD_DIFFUSESCALE, dynamiclight_get(oldl, LFIELD_DIFFUSESCALE));
dynamiclight_set(selectedlight, LFIELD_SPECULARSCALE, dynamiclight_get(oldl, LFIELD_SPECULARSCALE));
dynamiclight_set(selectedlight, LFIELD_CUBEMAPNAME, dynamiclight_get(oldl, LFIELD_CUBEMAPNAME));
dynamiclight_set(selectedlight, LFIELD_CORONA, dynamiclight_get(oldl, LFIELD_CORONA));
dynamiclight_set(selectedlight, LFIELD_CORONASCALE, dynamiclight_get(oldl, LFIELD_CORONASCALE));
dynamiclight_set(selectedlight, LFIELD_ROTATION, dynamiclight_get(oldl, LFIELD_ROTATION));
}
else
{
/*reset the light's properties*/
dynamiclight_set(selectedlight, LFIELD_RADIUS, 300);
dynamiclight_set(selectedlight, LFIELD_COLOUR, '1 1 1');
dynamiclight_set(selectedlight, LFIELD_FOV, 0);
dynamiclight_set(selectedlight, LFIELD_STYLE, 0);
dynamiclight_set(selectedlight, LFIELD_ANGLES, '0 0 0');
dynamiclight_set(selectedlight, LFIELD_FLAGS, LFLAG_REALTIMEMODE);
dynamiclight_set(selectedlight, LFIELD_AMBIENTSCALE, autocvar_r_editlights_import_ambient);
dynamiclight_set(selectedlight, LFIELD_DIFFUSESCALE, autocvar_r_editlights_import_diffuse);
dynamiclight_set(selectedlight, LFIELD_SPECULARSCALE, autocvar_r_editlights_import_specular);
dynamiclight_set(selectedlight, LFIELD_CUBEMAPNAME, "");
dynamiclight_set(selectedlight, LFIELD_CORONA, 0);
dynamiclight_set(selectedlight, LFIELD_CORONASCALE, 1);
dynamiclight_set(selectedlight, LFIELD_ROTATION, '0 0 0');
}
/*place it at the pointed location*/
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4f);
break;
}
}
}
else if (unic == '[')
{
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN) - trace_plane_normal);
}
else if (unic == ']')
{
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN) + trace_plane_normal);
}
else if (unic == '\'' || unic == '@')
{
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_RADIUS, 1.5*vlen(trace_endpos - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN)));
}
else if (unic == '#')
{
float fl;
fl = (float)dynamiclight_get(selectedlight, LFIELD_FLAGS);
if (fl & LFLAG_NOSHADOWS)
fl -= LFLAG_NOSHADOWS;
else
fl += LFLAG_NOSHADOWS;
dynamiclight_set(selectedlight, LFIELD_FLAGS, (float)fl);
}
else if (unic == '{')
dynamiclight_set(selectedlight, LFIELD_RADIUS, dynamiclight_get(selectedlight, LFIELD_RADIUS) - 15);
else if (unic == '}')
dynamiclight_set(selectedlight, LFIELD_RADIUS, dynamiclight_get(selectedlight, LFIELD_RADIUS) + 15);
else if (keyc == 127)
dynamiclight_set(selectedlight, LFIELD_RADIUS, 0);
else
return FALSE;
return TRUE;
};