fteqw/quakec/csaddon/src/menu.qc

441 lines
10 KiB
Plaintext

#define MF_DS_VALUE (1i << 0i)
typedef struct
{
float *currentf;
int *currenti;
float key;
vector *mousepos;
vector mousediff;
int flags;
} menu_t;
int (vector topleft, vector bottomright, vector cursor) cursor_in_widget
{
if (cursor_x <= bottomright_x && cursor_x >= topleft_x)
if (cursor_y <= bottomright_y && cursor_y >= topleft_y)
return 1;
return 0;
}
void(menu_t *menu, string fieldname, vector pos, float *value, float minv, float maxv) sliderf_widgit =
{
local vector rpos, spos, col;
local float f;
local int render_only;
local vector mousepos = *menu->mousepos;
local vector mp = *menu->mousepos;
local vector mousediff = menu->mousediff;
local float key = menu->key;
render_only = 0;
rpos = pos;
spos = rpos;
spos_x = pos_x + strlen(fieldname) * 8 + 4;
/*if they're dragging us, update*/
if (menu->currentf == value)
{
if (mousedown == 1)
{
*value = *value + mousediff_x/10;
*value = bound(minv, *value, maxv);
f = *value;
mp_y = spos_y + 4;
mp_x = spos_x + 9 * 8 * (f - minv) / (maxv - minv) + 4;
*menu->mousepos = mp;
}
else
{
menu->currentf = (float*)__NULL__;
}
}
else
if (mousedown == 1)
render_only = 1;
if (key == -1 || render_only == 1 )
{
if (mousepos_y >= pos_y && mousepos_y < pos_y + 8 && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
f = *value;
if (f < minv)
f = minv;
if (f > maxv)
f = maxv;
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
drawstring(spos, "^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", '8 8 0', '1 1 1', 1, 0);
if (!(menu->flags & MF_DS_VALUE))
drawstring(spos + '88 0', ftos(f), '8 8 0', col, 1, 0);
spos_x += 4 + 9*8*(f - minv) / (maxv - minv);
drawstring(spos, "^Ue083", '8 8 0', '1 1 1', 1, 0);
}
else if (mousepos_y >= pos_y && mousepos_y < pos_y + 8)
{
if (key == 512)
{
f = *value;
menu->currentf = value;
mp_x = spos_x + 9 * 8 * (f - minv) / (maxv - minv) + 4;
*menu->mousepos = mp;
}
else if (key == 515)
*value = bound(minv, *value + (maxv - minv) / 10, maxv);
else if (key == 516)
*value = bound(minv, *value - (maxv - minv) / 10, maxv);
}
};
void(menu_t *menu, string fieldname, vector pos, float *value) sliderf_fixed_widgit =
{
local vector rpos, spos, epos, col;
local float f;
local int render_only = 0;
local vector mousepos = *menu->mousepos;
local vector mp = *menu->mousepos;
local vector mousediff = menu->mousediff;
local vector *mpp = menu->mousepos;
local float key = menu->key;
rpos = pos;
spos = rpos;
spos_x = pos_x + strlen(fieldname) * 8 + 4;
epos = spos + '20 8';
if (!(menu->flags & MF_DS_VALUE))
epos_x += strlen(sprintf("%f", *value)) * 8;
/*if they're dragging us, update*/
if (menu->currentf == value)
{
if (mousedown == 1)
{
*value = *value + mousediff_x/10;
f = *value;
mp_y = spos_y + 4;
mp_x = spos_x + 4;
*menu->mousepos = mp;
}
else
{
menu->currentf = (float*)__NULL__;
}
}
else
if (mousedown == 1)
render_only = 1;
if (key == -1 || render_only == 1 )
{
if (cursor_in_widget(pos, epos, mousepos) && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
f = *value;
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
drawstring(spos, "^Ue080^Ue082", '8 8 0', '1 1 1', 1, 0);
if (!(menu->flags & MF_DS_VALUE))
drawstring(spos + '20 0', ftos(f), '8 8 0', col, 1, 0);
drawstring(spos + '4 0', "^Ue083", '8 8 0', '1 1 1', 1, 0);
}
else if (cursor_in_widget(pos, epos, mousepos))
{
if (key == 512)
{
f = *value;
menu->currentf = value;
mp_x = spos_x + 4;
*mpp = mp;
}
else if (key == 515)
*value = *value + 0.1;
else if (key == 516)
*value = *value - 0.1;
}
};
void(menu_t *menu, string fieldname, vector pos, int *value, int minv, int maxv) slideri_widgit =
{
local vector rpos, spos, epos, col;
local int f;
local int render_only;
local vector mousepos = *menu->mousepos;
local vector mp = *menu->mousepos;
local vector mousediff = menu->mousediff;
local float key;
key = menu->key;
render_only = 0;
rpos = pos;
spos = rpos;
spos_x = pos_x + strlen(fieldname) * 8 + 4;
epos = spos + '88 8';
if (!(menu->flags & MF_DS_VALUE))
epos_x = strlen(sprintf("%i", *value)) * 8;
/*if they're dragging us, update*/
if (menu->currenti == value)
{
if (mousedown == 1)
{
*value = *value + mousediff_x/10;
*value = bound(minv, *value, maxv);
f = *value;
mp_y = spos_y + 4;
mp_x = spos_x + 9 * 8 * (f - minv) / (maxv - minv) + 4;
*menu->mousepos = mp;
}
else
{
menu->currenti = (int*)__NULL__;
}
}
else
if (mousedown == 1)
render_only = 1;
if (key == -1 || render_only == 1 )
{
if (mousepos_y >= pos_y && mousepos_y < pos_y + 8 && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
f = *value;
if (f < minv)
f = minv;
if (f > maxv)
f = maxv;
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
drawstring(spos, "^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", '8 8 0', '1 1 1', 1, 0);
if (!(menu->flags & MF_DS_VALUE))
drawstring(spos + '88 0', ftos(f), '8 8 0', col, 1, 0);
spos_x += 9*8*(f - minv) / (maxv - minv);
drawstring(spos, "^Ue083", '8 8 0', '1 1 1', 1, 0);
}
else if (mousepos_y >= pos_y && mousepos_y < pos_y + 8)
{
if (key == 512)
{
f = *value;
menu->currenti = value;
mp_x = spos_x + 9 * 8 * (f - minv) / (maxv - minv) + 4;
*menu->mousepos = mp;
}
else if (key == 515)
*value = bound(minv, *value + 1i, maxv);
else if (key == 516)
*value = bound(minv, *value - 1i, maxv);
}
};
void(string fieldname, vector pos, vector *mousepos_in, float *value, float key) checkboxf_widgit =
{
local vector rpos, col;
local int render_only;
local vector mousepos = *mousepos_in;
rpos = pos + '132 0 0';
render_only = 0;
// fix this
if (mousedown == 1)
render_only = 1;
if (key == -1 || render_only == 1)
{
if (mousepos_y >= pos_y && mousepos_y < pos_y + 8 && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
rpos_x -= 4;
drawstring(rpos, "^Ue080^Ue082", '8 8 0', '1 1 1', 1, 0);
drawstring(rpos + '88 0', ((*value) ?"TRUE":"FALSE"), '8 8 0', col, 1, 0);
rpos_x += 4;
if (*value)
drawstring(rpos, "^Ue083", '8 8 0', '1 1 1', 1, 0);
}
else if (mousepos_y >= pos_y && mousepos_y < pos_y + 8)
{
if (key == 512)
*value = !*value;
else if (key == 515)
*value = !*value;
else if (key == 516)
*value = !*value;
}
};
void(menu_t *menu, string fieldname, vector pos, int *value) checkboxi_widgit =
{
local vector epos, spos, col;
local int render_only = 0;
local vector mousepos = *menu->mousepos;
local vector mousediff = menu->mousediff;
local float key = menu->key;
spos = pos;
spos_x += strlen(fieldname) * 8 + 4;
epos = spos;
epos_x += 16;
epos_y += 8;
if (!(menu->flags & MF_DS_VALUE))
epos_x += strlen((*value) ? "TRUE":"FALSE") *8;
render_only = 0;
if (key == -1)
{
if (cursor_in_widget(pos, epos, mousepos) && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
drawstring(spos, "^Ue080^Ue082", '8 8 0', '1 1 1', 1, 0);
if (!(menu->flags & MF_DS_VALUE))
drawstring(spos + '88 0', ((*value) ?"TRUE":"FALSE"), '8 8 0', col, 1, 0);
if (*value)
drawstring(spos + '4 0', "^Ue083", '8 8 0', '1 1 1', 1, 0);
}
if (cursor_in_widget(pos, epos, mousepos) && key != -1)
{
if (key == 512)
*value = !*value;
else if (key == 515)
*value = !*value;
else if (key == 516)
*value = !*value;
}
};
int (menu_t *menu, string fieldname, vector pos) button_widget =
{
local vector epos, spos, col;
local int render_only = 0;
local vector mousepos = *menu->mousepos;
local vector mousediff = menu->mousediff;
local float key = menu->key;
spos = pos;
spos_x += strlen(fieldname) * 8;
epos = spos;
epos_y += 8;
render_only = 0;
if (key == -1)
{
if (cursor_in_widget(pos, epos, mousepos) && render_only == 0)
{
col_x = (sin(cltime*3.14)+1) / 2;
col_y = col_x;
col_z = 1;
}
else
col = '1 1 1';
drawstring(pos, fieldname, '8 8 0', col, 1, 0);
return 0;
}
if (cursor_in_widget(pos, epos, mousepos) && key != -1)
{
if (key == 512)
return 1;
// else if (key == 515)
// else if (key == 516)
}
return 0;
};
void(string shader, vector org, vector s, vector t, string text, vector col, float alph) drawlame3dtext =
{
/*the shader must be a 16*16 grid of 256 chars*/
vector st = draw_getimagesize(shader);
vector pos = org;
float chr;
float idx = 0;
vector tc0,tc1,tc2,tc3;
//with GL_LINEAR sampling, the sample value is interpolated from the nearby two pixels
//this means that we must move the texture coord inwards by half of a pixel to avoid any bleed through into neighbouring chars
//(with nearest sampling, this isn't needed)
if (st != '0 0 0')
{
st_x = 0.5 / st_x;
st_y = 0.5 / st_y;
}
//precompute the st offset for each vertex
tc0_x = (0.0/16) + st_x;
tc1_x = (1.0/16) - st_x;
tc2_x = (1.0/16) - st_x;
tc3_x = (0.0/16) + st_x;
tc0_y = (0.0/16) + st_y;
tc1_y = (0.0/16) + st_y;
tc2_y = (1.0/16) - st_y;
tc3_y = (1.0/16) - st_y;
/*begin looks up the shader and is thus potentially expensive, fte requires it only once per batch of polygons.*/
R_BeginPolygon(shader);
while((chr = text[idx]))
{
idx+=1;
/*handle new lines*/
if (chr == '\n')
{
org += t;
pos = org;
continue;
}
/*skip spaces*/
if (chr != ' ')
{
/*its a grid, so the top-left texturecoord should be easy to calculate*/
/*weirdly though, qc has no (direct) modulo functionality, not even as a builtin, so this code is ugly*/
st_x = (chr & 15) / 16;
st_y = floor(chr/16) / 16;
/*plot the poly's point and emit the quad*/
R_PolygonVertex(pos , st + tc0, col, alph);
R_PolygonVertex(pos + s, st + tc1, col, alph);
R_PolygonVertex(pos+s+t, st + tc2, col, alph);
R_PolygonVertex(pos + t, st + tc3, col, alph);
R_EndPolygon();
}
pos += s;
}
};