2005-02-28 07:16:19 +00:00
|
|
|
//read menu.h
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
#include "quakedef.h"
|
2009-11-04 21:16:50 +00:00
|
|
|
#include "shader.h"
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
void Draw_TextBox (int x, int y, int width, int lines)
|
|
|
|
{
|
2004-12-24 08:45:56 +00:00
|
|
|
mpic_t *p;
|
2004-08-23 00:15:46 +00:00
|
|
|
int cx, cy;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
// draw left side
|
|
|
|
cx = x;
|
|
|
|
cy = y;
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_tl.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
if (R_GetShaderSizes(p, NULL, NULL, false) != true) //assume none exist
|
2009-04-19 10:50:31 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
R2D_ImageColours(0.0, 0.0, 0.0, 0.5);
|
|
|
|
R2D_FillBlock(x, y, width*8 + 16, 8 * (2 + lines));
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ImageColours(1.0, 1.0, 1.0, 1.0);
|
2004-08-23 00:15:46 +00:00
|
|
|
return;
|
2009-04-19 10:50:31 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 8, 8, p);
|
|
|
|
p = R2D_SafeCachePic ("gfx/box_ml.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
for (n = 0; n < lines; n++)
|
|
|
|
{
|
|
|
|
cy += 8;
|
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 8, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_bl.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy+8, 8, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
// draw middle
|
|
|
|
cx += 8;
|
|
|
|
while (width > 0)
|
|
|
|
{
|
|
|
|
cy = y;
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_tm.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 16, 8, p);
|
|
|
|
p = R2D_SafeCachePic ("gfx/box_mm.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
for (n = 0; n < lines; n++)
|
|
|
|
{
|
|
|
|
cy += 8;
|
|
|
|
if (n == 1)
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_mm2.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 16, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_bm.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy+8, 16, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
width -= 2;
|
|
|
|
cx += 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw right side
|
|
|
|
cy = y;
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_tr.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 8, 8, p);
|
|
|
|
p = R2D_SafeCachePic ("gfx/box_mr.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
for (n = 0; n < lines; n++)
|
|
|
|
{
|
|
|
|
cy += 8;
|
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy, 8, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic ("gfx/box_br.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (p)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ScalePic (cx, cy+8, 8, 8, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2014-09-08 23:47:19 +00:00
|
|
|
#ifndef NOBUILTINMENUS
|
2014-09-02 02:44:43 +00:00
|
|
|
|
|
|
|
int omousex;
|
|
|
|
int omousey;
|
|
|
|
qboolean mousemoved;
|
|
|
|
qboolean bindingactive;
|
|
|
|
extern cvar_t cl_cursor;
|
|
|
|
extern cvar_t cl_cursorsize;
|
|
|
|
extern cvar_t cl_cursorbias;
|
|
|
|
extern cvar_t m_preset_chosen;
|
|
|
|
menu_t *currentmenu;
|
|
|
|
menu_t *firstmenu;
|
|
|
|
menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old);
|
|
|
|
|
2014-10-11 19:39:45 +00:00
|
|
|
#ifdef HEXEN2
|
|
|
|
//this function is so fucked up.
|
|
|
|
//firstly, the source image uses 0 for transparent instead of 255. this means we need special handling. *sigh*.
|
|
|
|
//secondly we have to avoid sampling too much of the image, because i chars seem to have stray white pixels in them
|
|
|
|
//thirdly, we hard-code (by eye) the space between chars, which should be different for any character pair.
|
|
|
|
//but we're lazy so we don't consider the next char. italic fonts are annoying like that. feel free to refudge it.
|
2006-03-06 01:41:09 +00:00
|
|
|
void Draw_Hexen2BigFontString(int x, int y, const char *text)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-11 19:39:45 +00:00
|
|
|
int c;
|
2004-08-23 00:15:46 +00:00
|
|
|
int sx, sy;
|
2004-12-24 08:45:56 +00:00
|
|
|
mpic_t *p;
|
2014-10-11 19:39:45 +00:00
|
|
|
p = R_RegisterShader ("gfx/menu/bigfont.lmp", SUF_2D,
|
|
|
|
"{\n"
|
|
|
|
"if $nofixed\n"
|
|
|
|
"program default2d\n"
|
|
|
|
"endif\n"
|
|
|
|
"affine\n"
|
|
|
|
"nomipmaps\n"
|
|
|
|
"{\n"
|
|
|
|
"clampmap $diffuse\n"
|
|
|
|
"rgbgen vertex\n"
|
|
|
|
"alphagen vertex\n"
|
|
|
|
"blendfunc gl_one gl_one_minus_src_alpha\n"
|
|
|
|
"}\n"
|
|
|
|
"sort additive\n"
|
|
|
|
"}\n");
|
2015-05-03 19:57:46 +00:00
|
|
|
if (!p->defaulttextures->base)
|
2014-10-11 19:39:45 +00:00
|
|
|
{
|
|
|
|
void *file;
|
|
|
|
qofs_t fsize = FS_LoadFile("gfx/menu/bigfont.lmp", &file);
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
unsigned int w = ((unsigned int*)file)[0];
|
|
|
|
unsigned int h = ((unsigned int*)file)[1];
|
2014-12-11 16:26:26 +00:00
|
|
|
if (8+w*h==fsize)
|
2015-05-03 19:57:46 +00:00
|
|
|
p->defaulttextures->base = R_LoadReplacementTexture("gfx/menu/bigfont.lmp", NULL, IF_NOPCX|IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP, (qbyte*)file+8, w, h, TF_H2_TRANS8_0);
|
2014-10-11 19:39:45 +00:00
|
|
|
FS_FreeFile(file); //got image data
|
|
|
|
}
|
2015-05-03 19:57:46 +00:00
|
|
|
if (!p->defaulttextures->base)
|
|
|
|
p->defaulttextures->base = R_LoadHiResTexture("gfx/menu/bigfont.lmp", NULL, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP);
|
2014-10-11 19:39:45 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
while(*text)
|
|
|
|
{
|
2014-10-11 19:39:45 +00:00
|
|
|
c = *text++;
|
|
|
|
if (c >= 'a' && c <= 'z')
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-11 19:39:45 +00:00
|
|
|
sx = ((c-'a')%8)*20;
|
|
|
|
sy = ((c-'a')/8)*20;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2014-10-11 19:39:45 +00:00
|
|
|
else if (c >= 'A' && c <= 'Z')
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-11 19:39:45 +00:00
|
|
|
c = c - 'A' + 'a';
|
|
|
|
sx = ((c-'a')%8)*20;
|
|
|
|
sy = ((c-'a')/8)*20;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
else// if (*text <= ' ')
|
|
|
|
{
|
|
|
|
sx=-1;
|
|
|
|
sy=-1;
|
|
|
|
}
|
|
|
|
if(sx>=0)
|
2014-10-11 19:39:45 +00:00
|
|
|
R2D_SubPic(x, y, 18, 20, p, sx, sy, 20*8, 20*4);
|
|
|
|
|
|
|
|
switch(c)
|
|
|
|
{
|
|
|
|
case 'a': x+=15; break;
|
|
|
|
case 'b': x+=15; break;
|
|
|
|
case 'c': x+=15; break;
|
|
|
|
case 'd': x+=15; break;
|
|
|
|
case 'e': x+=15; break;
|
|
|
|
case 'f': x+=15; break;
|
|
|
|
case 'g': x+=15; break;
|
|
|
|
case 'h': x+=15; break;
|
|
|
|
case 'i': x+=10; break;
|
|
|
|
case 'j': x+=15; break;
|
|
|
|
case 'k': x+=18; break;
|
|
|
|
case 'l': x+=15; break;
|
|
|
|
case 'm': x+=18; break;
|
|
|
|
case 'n': x+=15; break;
|
|
|
|
case 'o': x+=15; break;
|
|
|
|
case 'p': x+=15; break;
|
|
|
|
case 'q': x+=18; break;
|
|
|
|
case 'r': x+=18; break;
|
|
|
|
case 's': x+=13; break;
|
|
|
|
case 't': x+=15; break;
|
|
|
|
case 'u': x+=15; break;
|
|
|
|
case 'v': x+=12; break;
|
|
|
|
case 'w': x+=15; break;
|
|
|
|
case 'x': x+=18; break;
|
|
|
|
case 'y': x+=15; break;
|
|
|
|
case 'z': x+=18; break;
|
|
|
|
default: x+=20; break;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
}
|
2014-10-11 19:39:45 +00:00
|
|
|
#endif
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2006-03-06 01:41:09 +00:00
|
|
|
mpic_t *QBigFontWorks(void)
|
|
|
|
{
|
|
|
|
mpic_t *p;
|
2014-10-05 20:04:11 +00:00
|
|
|
int i;
|
|
|
|
char *names[] = {
|
|
|
|
"gfx/mcharset.lmp",
|
|
|
|
"mcharset.lmp",
|
|
|
|
"textures/gfx/mcharset.lmp",
|
|
|
|
"textures/mcharset.lmp",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
for (i = 0; names[i]; i++)
|
|
|
|
{
|
|
|
|
p = R2D_SafeCachePic (names[i]);
|
|
|
|
if (p && R_GetShaderSizes(p, NULL, NULL, true))
|
|
|
|
return p;
|
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void Draw_BigFontString(int x, int y, const char *text)
|
|
|
|
{
|
|
|
|
int sx, sy;
|
|
|
|
mpic_t *p;
|
|
|
|
p = QBigFontWorks();
|
|
|
|
if (!p)
|
2014-04-03 02:16:21 +00:00
|
|
|
{
|
|
|
|
Draw_FunString(x, y, text);
|
2006-03-06 01:41:09 +00:00
|
|
|
return;
|
2014-04-03 02:16:21 +00:00
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
|
|
|
|
{ //a hack for scaling
|
|
|
|
p->width = 20*8;
|
|
|
|
p->height = 20*8;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(*text)
|
|
|
|
{
|
|
|
|
if (*text >= 'A' && *text <= 'Z')
|
|
|
|
{
|
|
|
|
sx = ((*text-'A')%8)*(p->width>>3);
|
|
|
|
sy = ((*text-'A')/8)*(p->height>>3);
|
|
|
|
}
|
|
|
|
else if (*text >= 'a' && *text <= 'z')
|
|
|
|
{
|
|
|
|
sx = ((*text-'a'+26)%8)*(p->width>>3);
|
|
|
|
sy = ((*text-'a'+26)/8)*(p->height>>3);
|
|
|
|
}
|
|
|
|
else if (*text >= '0' && *text <= '1')
|
|
|
|
{
|
|
|
|
sx = ((*text-'0'+26*2)%8)*(p->width>>3);
|
|
|
|
sy = ((*text-'0'+26*2)/8)*(p->height>>3);
|
|
|
|
}
|
|
|
|
else if (*text == ':')
|
|
|
|
{
|
|
|
|
sx = ((*text-'0'+26*2+10)%8)*(p->width>>3);
|
|
|
|
sy = ((*text-'0'+26*2+10)/8)*(p->height>>3);
|
|
|
|
}
|
|
|
|
else if (*text == '/')
|
|
|
|
{
|
|
|
|
sx = ((*text-'0'+26*2+11)%8)*(p->width>>3);
|
|
|
|
sy = ((*text-'0'+26*2+11)/8)*(p->height>>3);
|
|
|
|
}
|
|
|
|
else// if (*text <= ' ')
|
|
|
|
{
|
|
|
|
sx=-1;
|
|
|
|
sy=-1;
|
|
|
|
}
|
|
|
|
if(sx>=0)
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*8);
|
2006-03-06 01:41:09 +00:00
|
|
|
x+=(p->width>>3);
|
|
|
|
text++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
char *menudotstyle;
|
|
|
|
int maxdots;
|
|
|
|
int mindot;
|
|
|
|
int dotofs;
|
|
|
|
|
2016-08-25 00:12:14 +00:00
|
|
|
static void MenuTooltipChange(menu_t *menu, const char *text)
|
2009-04-19 10:50:31 +00:00
|
|
|
{
|
2016-08-25 00:12:14 +00:00
|
|
|
unsigned int MAX_CHARS=1024;
|
2009-04-19 10:50:31 +00:00
|
|
|
menutooltip_t *mtt;
|
|
|
|
if (menu->tooltip)
|
|
|
|
{
|
|
|
|
Z_Free(menu->tooltip);
|
|
|
|
menu->tooltip = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!text || !text[0] || vid.width < 320 || vid.height < 200)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// allocate new tooltip structure, copy text to structure
|
2016-08-25 00:12:14 +00:00
|
|
|
mtt = (menutooltip_t *)Z_Malloc(sizeof(menutooltip_t) + sizeof(conchar_t)*MAX_CHARS);
|
|
|
|
mtt->end = COM_ParseFunString(CON_WHITEMASK, text, mtt->text, sizeof(conchar_t)*MAX_CHARS, false);
|
2009-04-19 10:50:31 +00:00
|
|
|
|
|
|
|
menu->tooltip = mtt;
|
|
|
|
}
|
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
static qboolean MI_Selectable(menuoption_t *op)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
|
|
|
switch(op->common.type)
|
|
|
|
{
|
|
|
|
case mt_text:
|
|
|
|
return false;
|
|
|
|
case mt_button:
|
|
|
|
return true;
|
2014-10-11 22:16:40 +00:00
|
|
|
#ifdef HEXEN2
|
2009-11-04 21:16:50 +00:00
|
|
|
case mt_hexen2buttonbigfont:
|
|
|
|
return true;
|
2014-10-11 22:16:40 +00:00
|
|
|
#endif
|
2009-11-04 21:16:50 +00:00
|
|
|
case mt_qbuttonbigfont:
|
|
|
|
return true;
|
|
|
|
case mt_menudot:
|
|
|
|
return false;
|
|
|
|
case mt_picturesel:
|
|
|
|
return true;
|
|
|
|
case mt_picture:
|
|
|
|
return false;
|
|
|
|
case mt_childwindow:
|
|
|
|
return true;
|
|
|
|
case mt_box:
|
|
|
|
return false;
|
|
|
|
case mt_slider:
|
|
|
|
return true;
|
|
|
|
case mt_checkbox:
|
|
|
|
return true;
|
|
|
|
case mt_edit:
|
|
|
|
return true;
|
|
|
|
case mt_bind:
|
|
|
|
return true;
|
|
|
|
case mt_combo:
|
|
|
|
return true;
|
|
|
|
case mt_custom:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
static void M_CheckMouseMove(void)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
qboolean foundexclusive = false;
|
|
|
|
menu_t *menu;
|
|
|
|
menuoption_t *option;
|
2010-01-16 04:59:13 +00:00
|
|
|
|
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
|
|
|
if (omousex != (int)mousecursor_x || omousey != (int)mousecursor_y)
|
2012-02-27 12:23:15 +00:00
|
|
|
mousemoved = true;
|
|
|
|
else
|
|
|
|
mousemoved = false;
|
|
|
|
omousex = mousecursor_x;
|
|
|
|
omousey = mousecursor_y;
|
2010-01-16 04:59:13 +00:00
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
if (mousemoved)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
for (menu = firstmenu; menu; menu = menu->parent)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (menu->exclusive)
|
2010-07-11 02:22:39 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (foundexclusive)
|
|
|
|
continue;
|
|
|
|
foundexclusive=true;
|
|
|
|
}
|
|
|
|
|
2013-03-12 22:47:42 +00:00
|
|
|
for(option = menu->options; option; option = option->common.next)
|
2012-02-27 12:23:15 +00:00
|
|
|
{
|
|
|
|
if (mousemoved && !bindingactive && !option->common.ishidden)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (mousecursor_x > menu->xpos+option->common.posx-option->common.extracollide && mousecursor_x < menu->xpos+option->common.posx+option->common.width)
|
2004-09-07 18:19:22 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (mousecursor_y > menu->ypos+option->common.posy && mousecursor_y < menu->ypos+option->common.posy+option->common.height)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (MI_Selectable(option))
|
2010-07-11 02:22:39 +00:00
|
|
|
{
|
2012-02-27 12:23:15 +00:00
|
|
|
if (menu->selecteditem != option)
|
|
|
|
{
|
2016-07-21 19:27:59 +00:00
|
|
|
if (!option->common.noselectionsound && vid.activeapp)
|
2012-02-27 12:23:15 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2012-02-27 12:23:15 +00:00
|
|
|
S_LocalSound ("raven/menu1.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2012-02-27 12:23:15 +00:00
|
|
|
S_LocalSound ("misc/menu1.wav");
|
|
|
|
}
|
|
|
|
|
|
|
|
menu->selecteditem = option;
|
|
|
|
menu->tooltiptime = realtime + 1;
|
2016-08-25 00:12:14 +00:00
|
|
|
MenuTooltipChange(menu, menu->selecteditem->common.tooltip);
|
2012-02-27 12:23:15 +00:00
|
|
|
}
|
|
|
|
if (menu->cursoritem)
|
|
|
|
menu->cursoritem->common.posy = menu->selecteditem->common.posy;
|
2010-07-11 02:22:39 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2004-09-07 18:19:22 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2012-02-27 12:23:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
mpic_t *p;
|
2014-10-05 20:04:11 +00:00
|
|
|
int pw,ph;
|
2012-02-27 12:23:15 +00:00
|
|
|
|
|
|
|
while (option)
|
|
|
|
{
|
2005-01-26 18:56:49 +00:00
|
|
|
if (!option->common.ishidden)
|
2004-08-23 00:15:46 +00:00
|
|
|
switch(option->common.type)
|
|
|
|
{
|
2014-08-17 03:18:43 +00:00
|
|
|
case mt_menucursor:
|
|
|
|
if ((int)(realtime*4)&1)
|
|
|
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
|
|
|
break;
|
2004-08-23 00:15:46 +00:00
|
|
|
case mt_text:
|
|
|
|
if (!option->text.text)
|
2014-08-17 03:18:43 +00:00
|
|
|
{ //blinking cursor image hack (FIXME)
|
2009-11-04 21:16:50 +00:00
|
|
|
if ((int)(realtime*4)&1)
|
|
|
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
|
|
|
}
|
2014-03-30 08:55:06 +00:00
|
|
|
else if (option->common.width)
|
|
|
|
Draw_FunStringWidth(xpos + option->common.posx, ypos+option->common.posy, option->text.text, option->common.width, true, option->text.isred);
|
2004-08-23 00:15:46 +00:00
|
|
|
else if (option->text.isred)
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_AltFunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text);
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_button:
|
2015-01-21 18:18:37 +00:00
|
|
|
Draw_FunStringWidth(xpos + option->common.posx, ypos+option->common.posy, option->button.text, option->common.width, option->button.rightalign, !menu->cursoritem && menu->selecteditem == option);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
2014-10-11 22:16:40 +00:00
|
|
|
#ifdef HEXEN2
|
2006-03-06 01:41:09 +00:00
|
|
|
case mt_hexen2buttonbigfont:
|
|
|
|
Draw_Hexen2BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
|
|
|
|
break;
|
2014-10-11 22:16:40 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
case mt_qbuttonbigfont:
|
2004-08-23 00:15:46 +00:00
|
|
|
Draw_BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
|
|
|
|
break;
|
|
|
|
case mt_menudot:
|
|
|
|
i = (int)(realtime * 10)%maxdots;
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic(va(menudotstyle, i+mindot ));
|
2014-10-05 20:04:11 +00:00
|
|
|
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, option->common.width, option->common.height, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
2006-05-11 00:41:47 +00:00
|
|
|
case mt_picturesel:
|
2004-08-23 00:15:46 +00:00
|
|
|
p = NULL;
|
|
|
|
if (menu->selecteditem && menu->selecteditem->common.posx == option->common.posx && menu->selecteditem->common.posy == option->common.posy)
|
2006-01-21 00:06:49 +00:00
|
|
|
{
|
|
|
|
char selname[MAX_QPATH];
|
|
|
|
Q_strncpyz(selname, option->picture.picturename, sizeof(selname));
|
2006-03-11 03:12:10 +00:00
|
|
|
COM_StripExtension(selname, selname, sizeof(selname));
|
2006-05-11 00:41:47 +00:00
|
|
|
Q_strncatz(selname, "_sel", sizeof(selname));
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic(selname);
|
2006-01-21 00:06:49 +00:00
|
|
|
}
|
2014-10-05 20:04:11 +00:00
|
|
|
if (!R_GetShaderSizes(p, &pw, &ph, false))
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic(option->picture.picturename);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2014-12-23 15:26:42 +00:00
|
|
|
if (R_GetShaderSizes(p, &pw, &ph, false)>0)
|
|
|
|
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width?option->common.width:pw, option->common.height?option->common.height:ph, p);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
2006-05-11 00:41:47 +00:00
|
|
|
case mt_picture:
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic(option->picture.picturename);
|
2014-12-23 15:26:42 +00:00
|
|
|
if (R_GetShaderSizes(p, NULL, NULL, false)>0) R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p);
|
2006-02-28 00:46:04 +00:00
|
|
|
break;
|
2004-08-23 00:15:46 +00:00
|
|
|
case mt_childwindow:
|
2013-03-12 22:47:42 +00:00
|
|
|
MenuDrawItems(xpos+option->common.posx, ypos+option->common.posy, ((menu_t *)option->custom.dptr)->options, (menu_t *)option->custom.dptr);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_box:
|
|
|
|
Draw_TextBox(xpos+option->common.posx, ypos+option->common.posy, option->box.width, option->box.height);
|
|
|
|
break;
|
|
|
|
case mt_slider:
|
|
|
|
if (option->slider.var)
|
|
|
|
{
|
|
|
|
#define SLIDER_RANGE 10
|
2004-09-07 23:15:19 +00:00
|
|
|
float range;
|
2004-08-23 00:15:46 +00:00
|
|
|
int i;
|
|
|
|
int x = xpos+option->common.posx;
|
|
|
|
int y = ypos+option->common.posy;
|
2009-11-04 21:16:50 +00:00
|
|
|
int s;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2004-09-07 23:15:19 +00:00
|
|
|
range = (option->slider.current - option->slider.min)/(option->slider.max-option->slider.min);
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (option->slider.text)
|
|
|
|
{
|
2013-10-29 17:38:22 +00:00
|
|
|
Draw_FunStringWidth(x, y, option->slider.text, option->slider.textwidth, true, !menu->cursoritem && menu->selecteditem == option);
|
|
|
|
x += option->slider.textwidth + 3*8;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (range < 0)
|
|
|
|
range = 0;
|
|
|
|
if (range > 1)
|
|
|
|
range = 1;
|
2013-07-26 17:19:06 +00:00
|
|
|
option->slider.vx = x;
|
2009-11-04 21:16:50 +00:00
|
|
|
x -= 8;
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_BeginString(font_default, x, y, &x, &y);
|
2015-07-14 14:47:00 +00:00
|
|
|
x = Font_DrawChar(x, y, CON_WHITEMASK, 0xe080);
|
2009-11-04 21:16:50 +00:00
|
|
|
s = x;
|
2004-08-23 00:15:46 +00:00
|
|
|
for (i=0 ; i<SLIDER_RANGE ; i++)
|
2015-07-14 14:47:00 +00:00
|
|
|
x = Font_DrawChar(x, y, CON_WHITEMASK, 0xe081);
|
|
|
|
Font_DrawChar(x, y, CON_WHITEMASK, 0xe082);
|
|
|
|
Font_DrawChar(s + (x-s) * range - Font_CharWidth(CON_WHITEMASK, 0xe083)/2, y, CON_WHITEMASK, 0xe083);
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_EndString(font_default);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_checkbox:
|
|
|
|
{
|
|
|
|
int x = xpos+option->common.posx;
|
|
|
|
int y = ypos+option->common.posy;
|
|
|
|
qboolean on;
|
|
|
|
if (option->check.func)
|
2006-02-28 00:46:04 +00:00
|
|
|
on = option->check.func(&option->check, menu, CHK_CHECKED);
|
2004-08-23 00:15:46 +00:00
|
|
|
else if (!option->check.var)
|
2004-09-13 03:10:10 +00:00
|
|
|
on = option->check.value;
|
|
|
|
else if (option->check.bits) //bits is a bitmask for use with cvars (users can be clumsy, so bittage of 0 uses non-zero as true, but sets only bit 1)
|
|
|
|
{
|
|
|
|
if (option->check.var->latched_string)
|
|
|
|
on = atoi(option->check.var->latched_string)&option->check.bits;
|
|
|
|
else
|
|
|
|
on = (int)(option->check.var->value)&option->check.bits;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2004-09-13 03:10:10 +00:00
|
|
|
{
|
|
|
|
if (option->check.var->latched_string)
|
|
|
|
on = !!atof(option->check.var->latched_string);
|
|
|
|
else
|
|
|
|
on = !!option->check.var->value;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
if (option->check.text)
|
|
|
|
{
|
2013-10-29 17:38:22 +00:00
|
|
|
Draw_FunStringWidth(x, y, option->check.text, option->check.textwidth, true, !menu->cursoritem && menu->selecteditem == option);
|
|
|
|
x += option->check.textwidth + 3*8;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
if (on)
|
|
|
|
Draw_Character (x, y, 131);
|
|
|
|
else
|
|
|
|
Draw_Character (x, y, 129);
|
|
|
|
#endif
|
2006-03-23 06:45:17 +00:00
|
|
|
if (!menu->cursoritem && menu->selecteditem == option)
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_AltFunString (x, y, on ? "on" : "off");
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString (x, y, on ? "on" : "off");
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_edit:
|
|
|
|
{
|
|
|
|
int x = xpos+option->common.posx;
|
|
|
|
int y = ypos+option->common.posy;
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
Draw_FunStringWidth(x, y, option->edit.caption, option->edit.captionwidth, true, !menu->cursoritem && menu->selecteditem == option);
|
|
|
|
x += option->edit.captionwidth + 3*8;
|
2011-06-07 23:54:58 +00:00
|
|
|
if (option->edit.slim)
|
|
|
|
x += 8; // more space for cursor
|
|
|
|
else
|
|
|
|
Draw_TextBox(x-8, y-8, 16, 1);
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString(x, y, option->edit.text);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
if (menu->selecteditem == option && (int)(realtime*4) & 1)
|
|
|
|
{
|
|
|
|
x += strlen(option->edit.text)*8;
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString(x, y, "^Ue00b");
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-09-07 18:19:22 +00:00
|
|
|
case mt_bind:
|
|
|
|
{
|
|
|
|
int x = xpos+option->common.posx;
|
|
|
|
int y = ypos+option->common.posy;
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
int keys[8], keymods[countof(keys)];
|
|
|
|
int keycount;
|
2004-09-07 18:19:22 +00:00
|
|
|
char *keyname;
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
int j;
|
2004-09-07 18:19:22 +00:00
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
Draw_FunStringWidth(x, y, option->bind.caption, option->bind.captionwidth, true, !menu->cursoritem && menu->selecteditem == option);
|
|
|
|
x += option->bind.captionwidth + 3*8;
|
|
|
|
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
keycount = M_FindKeysForCommand (0, cl_forceseat.ival, option->bind.command, keys, keymods, countof(keys));
|
2010-01-15 05:35:27 +00:00
|
|
|
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
if (bindingactive && menu->selecteditem == option)
|
|
|
|
Draw_FunString (x, y, "Press key");
|
|
|
|
else if (!keycount)
|
|
|
|
Draw_FunString (x, y, "???");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (j = 0; j < keycount; j++)
|
|
|
|
{ /*these offsets are wrong*/
|
|
|
|
if (j)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString (x + 8, y, "or");
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
x += 32;
|
2004-09-07 18:19:22 +00:00
|
|
|
}
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
keyname = Key_KeynumToString (keys[j], keymods[j]);
|
|
|
|
Draw_FunString (x, y, keyname);
|
|
|
|
x += strlen(keyname) * 8;
|
2004-09-07 18:19:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
case mt_combo:
|
|
|
|
{
|
|
|
|
int x = xpos+option->common.posx;
|
|
|
|
int y = ypos+option->common.posy;
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
Draw_FunStringWidth(x, y, option->combo.caption, option->combo.captionwidth, true, !menu->cursoritem && menu->selecteditem == option);
|
|
|
|
x += option->combo.captionwidth + 3*8;
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
if (option->combo.numoptions)
|
|
|
|
{
|
|
|
|
if (!menu->cursoritem && menu->selecteditem == option)
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_AltFunString(x, y, option->combo.options[option->combo.selectedoption]);
|
2007-01-08 03:13:03 +00:00
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
Draw_FunString(x, y, option->combo.options[option->combo.selectedoption]);
|
2007-01-08 03:13:03 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_custom:
|
|
|
|
option->custom.draw(xpos+option->common.posx, ypos+option->common.posy, &option->custom, menu);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Sys_Error("Bad item type\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
option = option->common.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
static void MenuDraw(menu_t *menu)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2006-02-28 00:46:04 +00:00
|
|
|
if (!menu->dontexpand)
|
|
|
|
menu->xpos = ((vid.width - 320)>>1);
|
2015-06-18 22:11:30 +00:00
|
|
|
if (menu->predraw)
|
|
|
|
menu->predraw(menu);
|
2004-08-23 00:15:46 +00:00
|
|
|
MenuDrawItems(menu->xpos, menu->ypos, menu->options, menu);
|
2009-04-19 10:50:31 +00:00
|
|
|
// draw tooltip
|
|
|
|
if (menu->selecteditem && menu->tooltip && realtime > menu->tooltiptime)
|
|
|
|
{
|
|
|
|
menuoption_t *option = menu->selecteditem;
|
|
|
|
if (omousex > menu->xpos+option->common.posx && omousex < menu->xpos+option->common.posx+option->common.width)
|
|
|
|
if (omousey > menu->ypos+option->common.posy && omousey < menu->ypos+option->common.posy+option->common.height)
|
|
|
|
{
|
2016-08-25 00:12:14 +00:00
|
|
|
int x = omousex+8;
|
2009-04-19 10:50:31 +00:00
|
|
|
int y = omousey;
|
2016-08-25 00:12:14 +00:00
|
|
|
int w;
|
|
|
|
int h;
|
2009-04-19 10:50:31 +00:00
|
|
|
int l, lines;
|
2016-08-25 00:12:14 +00:00
|
|
|
conchar_t *line_start[16];
|
|
|
|
conchar_t *line_end[countof(line_start)];
|
|
|
|
|
|
|
|
//figure out the line breaks
|
|
|
|
Font_BeginString(font_default, 0, 0, &l, &l);
|
|
|
|
lines = Font_LineBreaks(menu->tooltip->text, menu->tooltip->end, min(vid.pixelwidth/2, 30*8*vid.pixelwidth/vid.width), countof(line_start), line_start, line_end);
|
|
|
|
Font_EndString(font_default);
|
|
|
|
|
|
|
|
//figure out how wide that makes the tip
|
|
|
|
w = 16;
|
|
|
|
h = (lines+2)*8;
|
|
|
|
for (l = 0; l < lines; l++)
|
|
|
|
{
|
|
|
|
int lw = 16+Font_LineWidth(line_start[l], line_end[l])*vid.width/vid.pixelwidth;
|
|
|
|
if (w < lw)
|
|
|
|
w = lw;
|
|
|
|
}
|
2009-04-19 10:50:31 +00:00
|
|
|
|
|
|
|
// keep the tooltip within view
|
|
|
|
if (x + w >= vid.width)
|
|
|
|
x = vid.width - w - 1;
|
|
|
|
if (y + h >= vid.height)
|
|
|
|
y -= h;
|
|
|
|
|
2016-08-25 00:12:14 +00:00
|
|
|
// draw the background
|
|
|
|
Draw_TextBox(x, y, (w-16)/8, lines);
|
2009-04-19 10:50:31 +00:00
|
|
|
x += 8;
|
|
|
|
y += 8;
|
2016-08-25 00:12:14 +00:00
|
|
|
|
|
|
|
//draw the text
|
|
|
|
Font_BeginString(font_default, x, y, &x, &y);
|
2009-04-19 10:50:31 +00:00
|
|
|
for (l = 0; l < lines; l++)
|
|
|
|
{
|
2016-08-25 00:12:14 +00:00
|
|
|
Font_LineDraw(x, y, line_start[l], line_end[l]);
|
|
|
|
y += Font_CharHeight();
|
2009-04-19 10:50:31 +00:00
|
|
|
}
|
2016-08-25 00:12:14 +00:00
|
|
|
Font_EndString(font_default);
|
2009-04-19 10:50:31 +00:00
|
|
|
}
|
|
|
|
}
|
2015-06-18 22:11:30 +00:00
|
|
|
|
|
|
|
if (menu->postdraw)
|
|
|
|
menu->postdraw(menu);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-05-10 17:26:41 +00:00
|
|
|
menutext_t *n = Z_Malloc(sizeof(menutext_t) + (text?strlen(text):0)+1);
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_text;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.posx = lhs;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2014-05-10 17:26:41 +00:00
|
|
|
n->common.width = (rhs && rightalign)?rhs-lhs:0;
|
2014-05-16 17:45:37 +00:00
|
|
|
if (text)
|
|
|
|
{
|
|
|
|
n->text = (char*)(n+1);
|
|
|
|
strcpy((char*)(n+1), (text));
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign, qboolean red)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menutext_t *n = Z_Malloc(sizeof(menutext_t) + strlen(text)+1);
|
|
|
|
n->common.type = mt_text;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.posx = lhs;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.width = rhs?rhs-lhs:0;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->isred = red;
|
|
|
|
|
|
|
|
if (rightalign && text)
|
|
|
|
n->common.posx -= strlen(text)*8;
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *text, qboolean rightalign)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menutext_t *n;
|
2014-05-10 17:26:41 +00:00
|
|
|
n = MC_AddWhiteText(menu, lhs, rhs, y, text, rightalign);
|
2004-08-23 00:15:46 +00:00
|
|
|
n->isred = true;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-05-10 17:26:41 +00:00
|
|
|
menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption, char *command, char *tooltip)
|
2004-09-07 18:19:22 +00:00
|
|
|
{
|
2014-05-10 17:26:41 +00:00
|
|
|
menubind_t *n = Z_Malloc(sizeof(*n) + strlen(caption)+1 + strlen(command)+1 + (tooltip?strlen(tooltip)+1:0));
|
2004-09-07 18:19:22 +00:00
|
|
|
n->common.type = mt_bind;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = cx;
|
2004-09-07 18:19:22 +00:00
|
|
|
n->common.posy = y;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->captionwidth = bx-cx;
|
2004-09-07 18:19:22 +00:00
|
|
|
n->caption = (char *)(n+1);
|
|
|
|
strcpy(n->caption, caption);
|
|
|
|
n->command = n->caption+strlen(n->caption)+1;
|
|
|
|
strcpy(n->command, command);
|
2014-05-10 17:26:41 +00:00
|
|
|
if (tooltip)
|
|
|
|
{
|
2016-02-10 23:23:43 +00:00
|
|
|
char *tip = n->command+strlen(n->command)+1;
|
|
|
|
n->common.tooltip = tip;
|
|
|
|
strcpy(tip, tooltip);
|
2014-05-10 17:26:41 +00:00
|
|
|
}
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = n->captionwidth + 64;
|
2006-01-28 06:41:20 +00:00
|
|
|
n->common.height = 8;
|
2004-09-07 18:19:22 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2006-05-11 00:41:47 +00:00
|
|
|
menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname)
|
|
|
|
{
|
|
|
|
char selname[MAX_QPATH];
|
|
|
|
menupicture_t *n;
|
|
|
|
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-05-11 00:41:47 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
Q_strncpyz(selname, picname, sizeof(selname));
|
|
|
|
COM_StripExtension(selname, selname, sizeof(selname));
|
|
|
|
Q_strncatz(selname, "_sel", sizeof(selname));
|
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_SafeCachePic(picname);
|
|
|
|
R2D_SafeCachePic(selname);
|
2006-05-11 00:41:47 +00:00
|
|
|
|
|
|
|
n = Z_Malloc(sizeof(menupicture_t) + strlen(picname)+1);
|
|
|
|
n->common.type = mt_picturesel;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
|
|
|
n->picturename = (char *)(n+1);
|
|
|
|
strcpy(n->picturename, picname);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menupicture_t *n;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2004-08-23 00:15:46 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_SafeCachePic(picname);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n = Z_Malloc(sizeof(menupicture_t) + strlen(picname)+1);
|
|
|
|
n->common.type = mt_picture;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
2006-02-28 00:46:04 +00:00
|
|
|
n->common.width = width;
|
|
|
|
n->common.height = height;
|
|
|
|
n->picturename = (char *)(n+1);
|
|
|
|
strcpy(n->picturename, picname);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picname)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
int x;
|
2009-11-04 21:16:50 +00:00
|
|
|
int width;
|
2004-12-24 08:45:56 +00:00
|
|
|
mpic_t *p;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2004-08-23 00:15:46 +00:00
|
|
|
return NULL;
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic(picname);
|
2004-08-23 00:15:46 +00:00
|
|
|
if (!p)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
x = 320/2;
|
2009-11-04 21:16:50 +00:00
|
|
|
width = 64;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
int pwidth, pheight;
|
|
|
|
if (R_GetShaderSizes(p, &pwidth, &pheight, true))
|
|
|
|
width = (pwidth * (float)height) / pheight;
|
|
|
|
else
|
|
|
|
width = 64;
|
2009-11-04 21:16:50 +00:00
|
|
|
x = (320-(int)width)/2;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
return MC_AddPicture(menu, x, y, width, height, picname);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
menuoption_t *MC_AddCursorSmall(menu_t *menu, menuresel_t *reselection, int x, int y)
|
|
|
|
{
|
|
|
|
menuoption_t *n = Z_Malloc(sizeof(menucommon_t));
|
|
|
|
if (reselection)
|
|
|
|
menu->reselection = reselection;
|
|
|
|
n->common.type = mt_menucursor;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
|
|
|
|
|
|
|
|
if (menu->reselection)
|
|
|
|
{
|
|
|
|
menuoption_t *sel, *firstsel = M_NextSelectableItem(menu, NULL);
|
|
|
|
for (sel = firstsel; sel; )
|
|
|
|
{
|
|
|
|
if (sel->common.posx == menu->reselection->x && sel->common.posy == menu->reselection->y)
|
|
|
|
{
|
|
|
|
menu->selecteditem = sel;
|
|
|
|
n->common.posy = sel->common.posy;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sel = M_NextSelectableItem(menu, sel);
|
|
|
|
if (sel == firstsel)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
menupicture_t *MC_AddCursor(menu_t *menu, menuresel_t *reselection, int x, int y)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2016-07-12 00:40:13 +00:00
|
|
|
int i;
|
2004-08-23 00:15:46 +00:00
|
|
|
menupicture_t *n = Z_Malloc(sizeof(menupicture_t));
|
2014-08-17 03:18:43 +00:00
|
|
|
if (reselection)
|
|
|
|
menu->reselection = reselection;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_menudot;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
2014-10-05 20:04:11 +00:00
|
|
|
n->common.width = 20;
|
|
|
|
n->common.height = 20;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
|
2016-02-15 06:01:17 +00:00
|
|
|
switch(M_GameType())
|
2014-10-05 20:04:11 +00:00
|
|
|
{
|
|
|
|
#ifdef Q2CLIENT
|
|
|
|
case MGT_QUAKE2:
|
|
|
|
//AND QUAKE 2 WINS!!!
|
|
|
|
menudotstyle = "pics/m_cursor%i.pcx";
|
2004-08-23 00:15:46 +00:00
|
|
|
mindot = 0;
|
|
|
|
maxdots = 15;
|
|
|
|
dotofs=0;
|
2014-10-05 20:04:11 +00:00
|
|
|
|
|
|
|
//this is *obviously* the correct size... not.
|
|
|
|
n->common.width = 22;
|
|
|
|
n->common.height = 29;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HEXEN2
|
|
|
|
case MGT_HEXEN2:
|
|
|
|
//AND THE WINNER IS HEXEN 2!!!
|
2004-08-23 00:15:46 +00:00
|
|
|
menudotstyle = "gfx/menu/menudot%i.lmp";
|
|
|
|
mindot = 1;
|
|
|
|
maxdots = 8;
|
2010-08-12 00:48:05 +00:00
|
|
|
dotofs=-2;
|
2014-10-05 20:04:11 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
//QUAKE 1 WINS BY DEFAULT!
|
2004-08-23 00:15:46 +00:00
|
|
|
menudotstyle = "gfx/menudot%i.lmp";
|
|
|
|
mindot = 1;
|
|
|
|
maxdots = 6;
|
|
|
|
dotofs=0;
|
2014-10-05 20:04:11 +00:00
|
|
|
break;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2014-08-17 03:18:43 +00:00
|
|
|
|
2016-07-12 00:40:13 +00:00
|
|
|
//cache them all. this avoids weird flickering as things get dynamically loaded
|
|
|
|
for (i = 0; i < maxdots; i++)
|
|
|
|
R2D_SafeCachePic(va(menudotstyle, i+mindot));
|
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
if (menu->reselection)
|
|
|
|
{
|
|
|
|
menuoption_t *sel, *firstsel = M_NextSelectableItem(menu, NULL);
|
|
|
|
for (sel = firstsel; sel; )
|
|
|
|
{
|
|
|
|
if (sel->common.posx == menu->reselection->x && sel->common.posy == menu->reselection->y)
|
|
|
|
{
|
|
|
|
menu->selecteditem = sel;
|
|
|
|
n->common.posy = sel->common.posy;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sel = M_NextSelectableItem(menu, sel);
|
|
|
|
if (sel == firstsel)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
menuedit_t *MC_AddEdit(menu_t *menu, int cx, int ex, int y, char *text, char *def)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2013-10-29 17:38:22 +00:00
|
|
|
menuedit_t *n = Z_Malloc(sizeof(menuedit_t)+strlen(text)+1);
|
|
|
|
n->slim = false;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_edit;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = cx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = ex-cx+(17)*8;
|
|
|
|
n->common.height = n->slim?8:16;
|
2005-02-12 18:56:04 +00:00
|
|
|
n->modified = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->captionwidth = ex-cx;
|
|
|
|
n->caption = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
2004-08-23 00:15:46 +00:00
|
|
|
Q_strncpyz(n->text, def, sizeof(n->text));
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
menuedit_t *MC_AddEditCvar(menu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean isslim)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menuedit_t *n = Z_Malloc(sizeof(menuedit_t)+strlen(text)+1);
|
|
|
|
cvar_t *cvar;
|
|
|
|
cvar = Cvar_Get(name, "", CVAR_USERCREATED|CVAR_ARCHIVE, NULL); //well, this is a menu/
|
2013-10-29 17:38:22 +00:00
|
|
|
n->slim = isslim;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_edit;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = cx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = ex-cx+(17)*8;
|
|
|
|
n->common.height = n->slim?8:16;
|
2010-07-11 02:22:39 +00:00
|
|
|
n->common.tooltip = cvar->description;
|
2005-02-12 18:56:04 +00:00
|
|
|
n->modified = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->captionwidth = ex-cx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->caption = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->cvar = cvar;
|
2011-06-18 05:41:10 +00:00
|
|
|
#ifdef _DEBUG
|
2006-03-06 01:41:09 +00:00
|
|
|
if (!(cvar->flags & CVAR_ARCHIVE))
|
|
|
|
Con_Printf("Warning: %s is not set for archiving\n", cvar->name);
|
2011-06-18 05:41:10 +00:00
|
|
|
#endif
|
2004-08-23 00:15:46 +00:00
|
|
|
Q_strncpyz(n->text, cvar->string, sizeof(n->text));
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height)
|
|
|
|
{
|
2005-06-19 09:08:47 +00:00
|
|
|
menubox_t *n = Z_Malloc(sizeof(menubox_t));
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_box;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
|
|
|
n->width = width;
|
|
|
|
n->height = height;
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2013-03-12 22:47:42 +00:00
|
|
|
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *dptr, int dint)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menucustom_t *n = Z_Malloc(sizeof(menucustom_t));
|
|
|
|
n->common.type = mt_custom;
|
|
|
|
n->common.iszone = true;
|
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
2013-03-12 22:47:42 +00:00
|
|
|
n->dptr = dptr;
|
|
|
|
n->dint = dint;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
menucheck_t *MC_AddCheckBox(menu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int bits)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menucheck_t *n = Z_Malloc(sizeof(menucheck_t)+strlen(text)+1);
|
|
|
|
n->common.type = mt_checkbox;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = tx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
|
|
|
n->common.height = 8;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->textwidth = cx - tx;
|
|
|
|
n->common.width = cx-tx + 7*8;
|
2010-07-11 02:22:39 +00:00
|
|
|
n->common.tooltip = var?var->description:NULL;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->var = var;
|
2004-09-13 03:10:10 +00:00
|
|
|
n->bits = bits;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2011-06-18 05:41:10 +00:00
|
|
|
#ifdef _DEBUG
|
2006-03-06 01:41:09 +00:00
|
|
|
if (var)
|
|
|
|
if (!(var->flags & CVAR_ARCHIVE))
|
|
|
|
Con_Printf("Warning: %s is not set for archiving\n", var->name);
|
2010-01-15 05:35:27 +00:00
|
|
|
else if (var->flags & CVAR_RENDERERLATCH)
|
2009-12-29 14:00:56 +00:00
|
|
|
Con_Printf("Warning: %s requires a vid_restart\n", var->name);
|
2011-06-18 05:41:10 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
2013-10-29 17:38:22 +00:00
|
|
|
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits)
|
2006-02-28 00:46:04 +00:00
|
|
|
{
|
|
|
|
menucheck_t *n = Z_Malloc(sizeof(menucheck_t)+strlen(text)+1);
|
|
|
|
n->common.type = mt_checkbox;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = tx;
|
2006-02-28 00:46:04 +00:00
|
|
|
n->common.posy = y;
|
|
|
|
n->common.height = 8;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->textwidth = cx - tx;
|
|
|
|
n->common.width = cx-tx + 7*8;
|
2006-02-28 00:46:04 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->func = func;
|
|
|
|
n->bits = bits;
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2007-05-25 22:16:29 +00:00
|
|
|
//delta may be 0
|
2013-10-29 17:38:22 +00:00
|
|
|
menuslider_t *MC_AddSlider(menu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta)
|
2010-01-15 05:35:27 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
menuslider_t *n = Z_Malloc(sizeof(menuslider_t)+strlen(text)+1);
|
|
|
|
n->common.type = mt_slider;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = tx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
|
|
|
n->common.height = 8;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = sx-tx + (SLIDER_RANGE+5)*8;
|
2010-07-11 02:22:39 +00:00
|
|
|
n->common.tooltip = var->description;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->var = var;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->textwidth = sx-tx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
|
|
|
|
if (var)
|
2006-03-06 01:41:09 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
n->current = var->value;
|
|
|
|
|
2010-01-15 05:35:27 +00:00
|
|
|
#ifdef _DEBUG
|
2006-03-06 01:41:09 +00:00
|
|
|
if (!(var->flags & CVAR_ARCHIVE))
|
|
|
|
Con_Printf("Warning: %s is not set for archiving\n", var->name);
|
2010-01-15 05:35:27 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
}
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
n->min = min;
|
|
|
|
n->max = max;
|
2007-05-25 22:16:29 +00:00
|
|
|
n->smallchange = delta;
|
|
|
|
n->largechange = delta*5;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
menucombo_t *MC_AddCombo(menu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-01-08 03:13:03 +00:00
|
|
|
int numopts;
|
|
|
|
int optlen;
|
|
|
|
int maxoptlen;
|
|
|
|
int optbufsize;
|
|
|
|
menucombo_t *n;
|
|
|
|
char **newops;
|
|
|
|
char *optbuf;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
maxoptlen = 0;
|
|
|
|
optbufsize = sizeof(char*);
|
|
|
|
numopts = 0;
|
|
|
|
optlen = 0;
|
|
|
|
while(ops[numopts])
|
|
|
|
{
|
|
|
|
optlen = strlen(ops[numopts]);
|
|
|
|
if (maxoptlen < optlen)
|
|
|
|
maxoptlen = optlen;
|
|
|
|
optbufsize += optlen+1+sizeof(char*);
|
|
|
|
numopts++;
|
|
|
|
}
|
2010-01-15 05:35:27 +00:00
|
|
|
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
n = Z_Malloc(sizeof(*n) + optbufsize);
|
|
|
|
newops = (char **)(n+1);
|
|
|
|
optbuf = (char*)(newops + numopts+1);
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_combo;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = tx;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.posy = y;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.height = 8;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = cx-tx + maxoptlen*8;
|
|
|
|
n->captionwidth = cx-tx;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->caption = caption;
|
2007-08-20 02:13:51 +00:00
|
|
|
n->options = (const char **)newops;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
n->numoptions = numopts;
|
|
|
|
for (i = 0; i < numopts; i++)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-01-08 03:13:03 +00:00
|
|
|
strcpy(optbuf, ops[i]);
|
|
|
|
newops[i] = optbuf;
|
|
|
|
optbuf += strlen(optbuf)+1;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2007-01-08 03:13:03 +00:00
|
|
|
newops[i] = NULL;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2010-01-15 05:35:27 +00:00
|
|
|
if (initialvalue >= n->numoptions)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
Con_Printf("WARNING: Fixed initialvalue for %s\n", caption);
|
|
|
|
initialvalue = n->numoptions-1;
|
|
|
|
}
|
|
|
|
n->selectedoption = initialvalue;
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
2013-10-29 17:38:22 +00:00
|
|
|
menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-01-08 03:13:03 +00:00
|
|
|
int numopts;
|
|
|
|
int optlen;
|
|
|
|
int maxoptlen;
|
|
|
|
int optbufsize;
|
|
|
|
menucombo_t *n;
|
|
|
|
char **newops;
|
|
|
|
char **newvalues;
|
|
|
|
char *optbuf;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
maxoptlen = 0;
|
|
|
|
optbufsize = sizeof(char*)*2 + strlen(caption)+1;
|
|
|
|
numopts = 0;
|
|
|
|
optlen = 0;
|
|
|
|
while(ops[numopts])
|
|
|
|
{
|
|
|
|
optlen = strlen(ops[numopts]);
|
|
|
|
if (maxoptlen < optlen)
|
|
|
|
maxoptlen = optlen;
|
|
|
|
optbufsize += optlen+1+sizeof(char*);
|
|
|
|
optbufsize += strlen(values[numopts])+1+sizeof(char*);
|
|
|
|
numopts++;
|
|
|
|
}
|
2010-01-15 05:35:27 +00:00
|
|
|
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
|
|
|
|
n = Z_Malloc(sizeof(*n) + optbufsize);
|
|
|
|
newops = (char **)(n+1);
|
|
|
|
newvalues = (char**)(newops + numopts+1);
|
|
|
|
optbuf = (char*)(newvalues + numopts+1);
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.type = mt_combo;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.posx = tx;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.posy = y;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.height = 8;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->common.width = cx-tx + maxoptlen*8;
|
2010-07-11 02:22:39 +00:00
|
|
|
n->common.tooltip = cvar->description;
|
2013-10-29 17:38:22 +00:00
|
|
|
n->captionwidth = cx-tx;
|
2007-01-08 03:13:03 +00:00
|
|
|
|
|
|
|
strcpy(optbuf, caption);
|
|
|
|
n->caption = optbuf;
|
|
|
|
optbuf += strlen(optbuf)+1;
|
|
|
|
|
2007-08-20 02:13:51 +00:00
|
|
|
n->options = (const char **)newops;
|
|
|
|
n->values = (const char **)newvalues;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->cvar = cvar;
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
// if (!(cvar->flags & CVAR_ARCHIVE))
|
|
|
|
// Con_Printf("Warning: %s is not set for archiving\n", cvar->name);
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
n->selectedoption = 0;
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
|
2007-01-08 03:13:03 +00:00
|
|
|
n->numoptions = numopts;
|
|
|
|
for (i = 0; i < numopts; i++)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-01-08 03:13:03 +00:00
|
|
|
if (!strcmp(values[i], cvar->string))
|
|
|
|
n->selectedoption = i;
|
|
|
|
|
|
|
|
strcpy(optbuf, ops[i]);
|
|
|
|
newops[i] = optbuf;
|
|
|
|
optbuf += strlen(optbuf)+1;
|
|
|
|
|
|
|
|
strcpy(optbuf, values[i]);
|
|
|
|
newvalues[i] = optbuf;
|
|
|
|
optbuf += strlen(optbuf)+1;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2007-01-08 03:13:03 +00:00
|
|
|
newops[i] = NULL;
|
|
|
|
newvalues[i] = NULL;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const char *text, const char *command)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
|
|
|
|
n->common.type = mt_button;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.posx = lhs;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
|
|
|
n->common.height = 8;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.width = rhs?rhs - lhs:strlen(text)*8;
|
2015-01-21 18:18:37 +00:00
|
|
|
n->rightalign = true;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->command = n->text + strlen(n->text)+1;
|
|
|
|
strcpy((char *)n->command, command);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
|
|
|
|
menubutton_t *MC_AddConsoleCommandQBigFont(menu_t *menu, int x, int y, const char *text, const char *command)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
|
2006-03-06 01:41:09 +00:00
|
|
|
n->common.type = mt_qbuttonbigfont;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2006-03-06 01:41:09 +00:00
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
|
|
|
n->common.height = 20;
|
|
|
|
n->common.width = strlen(text)*20;
|
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->command = n->text + strlen(n->text)+1;
|
|
|
|
strcpy((char *)n->command, command);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
2014-10-11 22:16:40 +00:00
|
|
|
#ifdef HEXEN2
|
2006-03-06 01:41:09 +00:00
|
|
|
menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, const char *text, const char *command)
|
|
|
|
{
|
|
|
|
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
|
|
|
|
n->common.type = mt_hexen2buttonbigfont;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posx = x;
|
|
|
|
n->common.posy = y;
|
2010-08-28 17:14:38 +00:00
|
|
|
n->common.height = 20;
|
|
|
|
n->common.width = strlen(text)*20;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), text);
|
|
|
|
n->command = n->text + strlen(n->text)+1;
|
|
|
|
strcpy((char *)n->command, command);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
2014-10-11 22:16:40 +00:00
|
|
|
#endif
|
2014-03-30 08:55:06 +00:00
|
|
|
menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int))
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
menubutton_t *n = Z_Malloc(sizeof(menubutton_t));
|
|
|
|
n->common.type = mt_button;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.posx = lhs;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2015-01-21 18:18:37 +00:00
|
|
|
n->rightalign = true;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->text = text;
|
|
|
|
n->command = NULL;
|
|
|
|
n->key = command;
|
2006-01-28 06:41:20 +00:00
|
|
|
n->common.height = 8;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.width = rhs?rhs-lhs:strlen(text)*8;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2015-01-21 18:18:37 +00:00
|
|
|
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int lhs, int rhs, int y, qboolean rightalign, const char *text, char *command, ...)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
va_list argptr;
|
|
|
|
static char string[1024];
|
|
|
|
menubutton_t *n;
|
2010-01-15 05:35:27 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
va_start (argptr, command);
|
2006-03-06 01:41:09 +00:00
|
|
|
vsnprintf (string,sizeof(string)-1, command,argptr);
|
2010-01-15 05:35:27 +00:00
|
|
|
va_end (argptr);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
n = Z_Malloc(sizeof(menubutton_t) + strlen(string)+1);
|
|
|
|
n->common.type = mt_button;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->common.iszone = true;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.posx = lhs;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->common.posy = y;
|
2014-03-30 08:55:06 +00:00
|
|
|
n->common.width = rhs-lhs;
|
2015-01-21 18:18:37 +00:00
|
|
|
n->rightalign = rightalign;
|
2010-01-15 05:35:27 +00:00
|
|
|
n->text = text;
|
2004-08-23 00:15:46 +00:00
|
|
|
n->command = (char *)(n+1);
|
|
|
|
strcpy((char *)(n+1), string);
|
|
|
|
|
|
|
|
n->common.next = menu->options;
|
|
|
|
menu->options = (menuoption_t *)n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MC_Slider_Key(menuslider_t *option, int key)
|
|
|
|
{
|
2007-05-25 22:16:29 +00:00
|
|
|
float range = option->current;
|
|
|
|
float delta;
|
|
|
|
|
2013-07-26 17:19:06 +00:00
|
|
|
float ix = option->vx;
|
|
|
|
float ex = ix + 10*8;
|
|
|
|
|
2007-05-25 22:16:29 +00:00
|
|
|
if (option->smallchange)
|
|
|
|
delta = option->smallchange;
|
|
|
|
else
|
|
|
|
delta = 0.1;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2006-02-22 23:37:51 +00:00
|
|
|
if (key == K_LEFTARROW || key == K_MWHEELDOWN)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-05-25 22:16:29 +00:00
|
|
|
range -= delta;
|
2015-04-14 23:12:17 +00:00
|
|
|
if (option->min > option->max)
|
|
|
|
range = bound(option->max, range, option->min);
|
|
|
|
else
|
|
|
|
range = bound(option->min, range, option->max);
|
2007-05-25 22:16:29 +00:00
|
|
|
option->current = range;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2006-02-22 23:37:51 +00:00
|
|
|
else if (key == K_RIGHTARROW || key == K_MWHEELUP)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2007-05-25 22:16:29 +00:00
|
|
|
range += delta;
|
2015-04-14 23:12:17 +00:00
|
|
|
if (option->min > option->max)
|
|
|
|
range = bound(option->max, range, option->min);
|
|
|
|
else
|
|
|
|
range = bound(option->min, range, option->max);
|
2007-05-25 22:16:29 +00:00
|
|
|
option->current = range;
|
2013-07-26 17:19:06 +00:00
|
|
|
}
|
|
|
|
else if (key == K_MOUSE1 && mousecursor_x >= ix-8 && mousecursor_x < ex+8)
|
|
|
|
{
|
|
|
|
range = (mousecursor_x - ix) / (ex - ix);
|
|
|
|
range = option->min + range*(option->max-option->min);
|
2015-04-14 23:12:17 +00:00
|
|
|
if (option->min > option->max)
|
|
|
|
range = bound(option->max, range, option->min);
|
|
|
|
else
|
|
|
|
range = bound(option->min, range, option->max);
|
2013-07-26 17:19:06 +00:00
|
|
|
option->current = range;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2013-05-03 04:28:08 +00:00
|
|
|
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2015-04-14 23:12:17 +00:00
|
|
|
if (range == option->max)
|
2007-05-25 22:16:29 +00:00
|
|
|
range = option->min;
|
2015-04-14 23:12:17 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
range += delta;
|
|
|
|
if (option->min > option->max)
|
|
|
|
{
|
|
|
|
if (range < option->max-delta/2)
|
|
|
|
range = option->max;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (range > option->max-delta/2)
|
|
|
|
range = option->max;
|
|
|
|
}
|
2007-05-25 22:16:29 +00:00
|
|
|
option->current = range;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2004-09-07 18:19:22 +00:00
|
|
|
else
|
|
|
|
return;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2004-09-07 18:19:22 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
2013-07-26 17:19:06 +00:00
|
|
|
if (option->var)
|
|
|
|
Cvar_SetValue(option->var, option->current);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 00:46:04 +00:00
|
|
|
void MC_CheckBox_Key(menucheck_t *option, menu_t *menu, int key)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2013-05-03 04:28:08 +00:00
|
|
|
if (key != K_ENTER && key != K_KP_ENTER && key != K_LEFTARROW && key != K_RIGHTARROW && key != K_MOUSE1)
|
2004-08-23 00:15:46 +00:00
|
|
|
return;
|
|
|
|
if (option->func)
|
2006-02-28 00:46:04 +00:00
|
|
|
option->func(option, menu, CHK_TOGGLE);
|
2004-08-23 00:15:46 +00:00
|
|
|
else if (!option->var)
|
|
|
|
option->value = !option->value;
|
|
|
|
else
|
2004-09-07 18:19:22 +00:00
|
|
|
{
|
2004-09-13 03:10:10 +00:00
|
|
|
if (option->bits)
|
|
|
|
{
|
|
|
|
int old;
|
|
|
|
if (option->var->latched_string)
|
|
|
|
old = atoi(option->var->latched_string);
|
|
|
|
else
|
|
|
|
old = option->var->value;
|
|
|
|
|
|
|
|
if (old & option->bits)
|
|
|
|
Cvar_SetValue(option->var, old&~option->bits);
|
|
|
|
else
|
|
|
|
Cvar_SetValue(option->var, old|option->bits);
|
|
|
|
}
|
2004-09-07 23:15:19 +00:00
|
|
|
else
|
2004-09-13 03:10:10 +00:00
|
|
|
{
|
|
|
|
if (option->var->latched_string)
|
|
|
|
Cvar_SetValue(option->var, !atof(option->var->latched_string));
|
|
|
|
else
|
|
|
|
Cvar_SetValue(option->var, !option->var->value);
|
|
|
|
}
|
2004-09-07 18:19:22 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void MC_EditBox_Key(menuedit_t *edit, int key, unsigned int unicode)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
int len = strlen(edit->text);
|
|
|
|
if (key == K_DEL || key == K_BACKSPACE)
|
|
|
|
{
|
|
|
|
if (!len)
|
|
|
|
return;
|
|
|
|
edit->text[len-1] = '\0';
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!unicode)
|
2004-08-23 00:15:46 +00:00
|
|
|
return;
|
|
|
|
else
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (unicode < 128)
|
|
|
|
{
|
|
|
|
if (len < sizeof(edit->text))
|
|
|
|
{
|
|
|
|
edit->text[len] = unicode;
|
|
|
|
edit->text[len+1] = '\0';
|
|
|
|
}
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2005-02-12 18:56:04 +00:00
|
|
|
edit->modified = true;
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (edit->cvar)
|
2004-09-07 18:19:22 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
Cvar_Set(edit->cvar, edit->text);
|
2004-09-07 18:19:22 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MC_Combo_Key(menucombo_t *combo, int key)
|
|
|
|
{
|
2013-05-03 04:28:08 +00:00
|
|
|
if (key == K_ENTER || key == K_KP_ENTER || key == K_RIGHTARROW || key == K_MOUSE1)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
combo->selectedoption++;
|
|
|
|
if (combo->selectedoption >= combo->numoptions)
|
|
|
|
combo->selectedoption = 0;
|
|
|
|
|
|
|
|
changed:
|
2007-01-08 03:13:03 +00:00
|
|
|
if (combo->cvar && combo->numoptions)
|
2004-08-23 00:15:46 +00:00
|
|
|
Cvar_Set(combo->cvar, (char *)combo->values[combo->selectedoption]);
|
2013-07-26 17:19:06 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
else if (key == K_LEFTARROW)
|
|
|
|
{
|
|
|
|
combo->selectedoption--;
|
|
|
|
if (combo->selectedoption < 0)
|
|
|
|
combo->selectedoption = combo->numoptions-1;
|
|
|
|
goto changed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void M_AddMenuFront (menu_t *menu)
|
|
|
|
{
|
|
|
|
menu_t *pmenu;
|
|
|
|
m_state = m_complex;
|
|
|
|
if (!firstmenu)
|
|
|
|
{
|
|
|
|
M_AddMenu(menu);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pmenu = firstmenu;
|
|
|
|
while(pmenu->parent)
|
|
|
|
pmenu = pmenu->parent;
|
|
|
|
pmenu->parent = menu;
|
|
|
|
menu->child = pmenu;
|
|
|
|
menu->parent = NULL;
|
|
|
|
|
|
|
|
menu->exclusive = true;
|
|
|
|
|
|
|
|
menu->xpos = ((vid.width - 320)>>1);
|
|
|
|
|
|
|
|
currentmenu = menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void M_AddMenu (menu_t *menu)
|
|
|
|
{
|
|
|
|
m_state = m_complex;
|
|
|
|
menu->parent = firstmenu;
|
|
|
|
if (firstmenu)
|
|
|
|
firstmenu->child = menu;
|
|
|
|
menu->child = NULL;
|
|
|
|
firstmenu = menu;
|
|
|
|
|
|
|
|
menu->exclusive = true;
|
|
|
|
|
|
|
|
currentmenu = menu;
|
|
|
|
}
|
|
|
|
menu_t *M_CreateMenu (int extrasize)
|
|
|
|
{
|
|
|
|
menu_t *menu;
|
|
|
|
menu = Z_Malloc(sizeof(menu_t)+extrasize);
|
|
|
|
menu->iszone=true;
|
|
|
|
menu->data = menu+1;
|
|
|
|
|
|
|
|
M_AddMenu(menu);
|
|
|
|
|
|
|
|
return menu;
|
|
|
|
}
|
2012-04-24 07:59:11 +00:00
|
|
|
menu_t *M_CreateMenuInfront (int extrasize)
|
|
|
|
{
|
|
|
|
menu_t *menu;
|
|
|
|
menu = Z_Malloc(sizeof(menu_t)+extrasize);
|
|
|
|
menu->iszone=true;
|
|
|
|
menu->data = menu+1;
|
|
|
|
|
|
|
|
M_AddMenuFront(menu);
|
|
|
|
menu->exclusive = false;
|
|
|
|
|
|
|
|
return menu;
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
void M_HideMenu (menu_t *menu)
|
|
|
|
{
|
|
|
|
if (menu == firstmenu)
|
|
|
|
firstmenu = menu->parent;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
menu_t *prev;
|
|
|
|
prev = menu->child;
|
|
|
|
if (prev)
|
|
|
|
prev->parent = menu->parent;
|
|
|
|
if (menu->parent)
|
|
|
|
menu->parent->child = menu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void M_RemoveMenu (menu_t *menu)
|
2010-01-15 05:35:27 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
menuoption_t *op, *oop;
|
2014-08-17 03:18:43 +00:00
|
|
|
if (menu->reselection)
|
|
|
|
{
|
|
|
|
menu->reselection->x = menu->selecteditem->common.posx;
|
|
|
|
menu->reselection->y = menu->selecteditem->common.posy;
|
|
|
|
}
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (menu->remove)
|
|
|
|
menu->remove(menu);
|
|
|
|
if (menu == firstmenu)
|
|
|
|
firstmenu = menu->parent;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
menu_t *prev;
|
|
|
|
prev = menu->child;
|
|
|
|
if (prev)
|
|
|
|
prev->parent = menu->parent;
|
|
|
|
if (menu->parent)
|
|
|
|
menu->parent->child = menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
op = menu->options;
|
|
|
|
while(op)
|
|
|
|
{
|
|
|
|
oop = op;
|
|
|
|
op = op->common.next;
|
|
|
|
if (oop->common.iszone)
|
|
|
|
Z_Free(oop);
|
|
|
|
}
|
|
|
|
menu->options=NULL;
|
|
|
|
|
2009-04-19 10:50:31 +00:00
|
|
|
if (menu->tooltip)
|
2012-04-24 07:59:11 +00:00
|
|
|
{
|
2009-04-19 10:50:31 +00:00
|
|
|
Z_Free(menu->tooltip);
|
2012-04-24 07:59:11 +00:00
|
|
|
menu->tooltip = NULL;
|
|
|
|
}
|
2009-04-19 10:50:31 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (menu->iszone)
|
|
|
|
{
|
|
|
|
menu->iszone=false;
|
|
|
|
Z_Free(menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (menu == currentmenu)
|
|
|
|
currentmenu = firstmenu;
|
|
|
|
}
|
|
|
|
|
2016-07-12 00:40:13 +00:00
|
|
|
void M_ReloadMenus(void)
|
|
|
|
{
|
|
|
|
menu_t *m;
|
|
|
|
|
|
|
|
for (m = firstmenu; m; m = m->parent)
|
|
|
|
{
|
|
|
|
if (m->reset)
|
|
|
|
m->reset(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-14 14:47:00 +00:00
|
|
|
void M_RemoveAllMenus (qboolean leaveprompts)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2015-07-14 14:47:00 +00:00
|
|
|
menu_t **link, *m;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2015-07-14 14:47:00 +00:00
|
|
|
for (link = &firstmenu; *link; )
|
|
|
|
{
|
|
|
|
m = *link;
|
|
|
|
if (!m->exclusive && leaveprompts)
|
|
|
|
{
|
|
|
|
//this is WEIRD.
|
|
|
|
if (m == firstmenu)
|
|
|
|
link = &m->parent;
|
|
|
|
else
|
|
|
|
link = &m->child;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
M_RemoveMenu(m);
|
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
}
|
2012-04-24 07:59:11 +00:00
|
|
|
void M_MenuPop_f (void)
|
|
|
|
{
|
2013-03-12 22:41:34 +00:00
|
|
|
if (!currentmenu)
|
2012-04-24 07:59:11 +00:00
|
|
|
return;
|
2013-03-12 22:41:34 +00:00
|
|
|
M_RemoveMenu(currentmenu);
|
2012-04-24 07:59:11 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
void M_Complex_Draw(void)
|
|
|
|
{
|
|
|
|
menu_t *menu, *cmenu;
|
|
|
|
qboolean foundexclusive = false;
|
|
|
|
|
|
|
|
if (!firstmenu)
|
|
|
|
{
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Remove(kdm_emenu);
|
2004-08-23 00:15:46 +00:00
|
|
|
m_state = m_none;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
M_CheckMouseMove();
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
for (menu = firstmenu; menu; )
|
|
|
|
{
|
|
|
|
cmenu = menu;
|
|
|
|
menu = menu->parent; //this way we can remove the currently drawn menu easily (if needed)
|
|
|
|
|
|
|
|
if (cmenu->exclusive)
|
|
|
|
{
|
|
|
|
if (foundexclusive)
|
|
|
|
continue;
|
|
|
|
foundexclusive=true;
|
|
|
|
}
|
|
|
|
MenuDraw(cmenu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
menuoption_t *M_NextItem(menu_t *m, menuoption_t *old)
|
|
|
|
{
|
|
|
|
menuoption_t *op = m->options;
|
|
|
|
while(op->common.next)
|
|
|
|
{
|
|
|
|
if (op->common.next == old)
|
|
|
|
return op;
|
|
|
|
|
|
|
|
op = op->common.next;
|
|
|
|
}
|
|
|
|
return op;
|
|
|
|
}
|
|
|
|
menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old)
|
|
|
|
{
|
|
|
|
menuoption_t *op;
|
|
|
|
|
|
|
|
if (!old)
|
|
|
|
old = M_NextItem(m, old);
|
2010-01-15 05:35:27 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
op = old;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (!op)
|
|
|
|
op = currentmenu->options;
|
|
|
|
|
|
|
|
op = M_NextItem(m, op);
|
|
|
|
if (!op)
|
|
|
|
op = currentmenu->options;
|
|
|
|
|
|
|
|
if (op == old)
|
|
|
|
{
|
2010-08-12 00:48:05 +00:00
|
|
|
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_hexen2buttonbigfont || op->common.type == mt_qbuttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || (op->common.type == mt_custom && op->custom.key))
|
2004-08-23 00:15:46 +00:00
|
|
|
return op;
|
|
|
|
return NULL; //whoops.
|
|
|
|
}
|
|
|
|
|
2010-08-12 00:48:05 +00:00
|
|
|
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_hexen2buttonbigfont || op->common.type == mt_qbuttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || (op->common.type == mt_custom && op->custom.key))
|
2005-01-26 18:56:49 +00:00
|
|
|
if (!op->common.ishidden)
|
|
|
|
return op;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
menuoption_t *M_PrevSelectableItem(menu_t *m, menuoption_t *old)
|
|
|
|
{
|
2010-01-15 05:35:27 +00:00
|
|
|
menuoption_t *op;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
|
|
|
if (!old)
|
|
|
|
old = currentmenu->options;
|
2010-01-15 05:35:27 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
op = old;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (!op)
|
|
|
|
op = currentmenu->options;
|
|
|
|
|
|
|
|
op = op->common.next;
|
|
|
|
if (!op)
|
|
|
|
op = currentmenu->options;
|
|
|
|
|
|
|
|
if (op == old)
|
|
|
|
return old; //whoops.
|
|
|
|
|
2010-08-12 00:48:05 +00:00
|
|
|
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_hexen2buttonbigfont || op->common.type == mt_qbuttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || (op->common.type == mt_custom && op->custom.key))
|
2005-01-26 18:56:49 +00:00
|
|
|
if (!op->common.ishidden)
|
|
|
|
return op;
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void M_Complex_Key(int key, int unicode)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
|
|
|
if (!currentmenu)
|
|
|
|
return; //erm...
|
2010-01-15 05:35:27 +00:00
|
|
|
|
2012-02-27 12:23:15 +00:00
|
|
|
M_CheckMouseMove();
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (currentmenu->key)
|
|
|
|
if (currentmenu->key(key, currentmenu))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (currentmenu->selecteditem && currentmenu->selecteditem->common.type == mt_custom && (key == K_DOWNARROW || key == K_UPARROW || key == K_TAB))
|
2006-02-11 18:06:54 +00:00
|
|
|
if (currentmenu->selecteditem->custom.key)
|
2015-06-16 23:53:58 +00:00
|
|
|
if (currentmenu->selecteditem->custom.key(¤tmenu->selecteditem->custom, currentmenu, key, unicode))
|
2006-02-11 18:06:54 +00:00
|
|
|
return;
|
2004-09-07 18:19:22 +00:00
|
|
|
|
|
|
|
if (currentmenu->selecteditem && currentmenu->selecteditem->common.type == mt_bind)
|
|
|
|
{
|
|
|
|
if (bindingactive)
|
|
|
|
{
|
2013-03-12 23:09:25 +00:00
|
|
|
//don't let key 0 be bound here. unicode-only keys are also not bindable.
|
|
|
|
if (key == 0)
|
|
|
|
return;
|
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("raven/menu1.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("misc/menu1.wav");
|
2004-09-07 18:19:22 +00:00
|
|
|
|
|
|
|
if (key != K_ESCAPE && key != '`')
|
|
|
|
{
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
int modifiers = 0;
|
|
|
|
extern qboolean keydown[];
|
|
|
|
if (keydown[K_LSHIFT] && key != K_LSHIFT)
|
|
|
|
modifiers |= 1;
|
|
|
|
if (keydown[K_RSHIFT] && key != K_RSHIFT)
|
|
|
|
modifiers |= 1;
|
|
|
|
if (keydown[K_LALT] && key != K_LALT)
|
|
|
|
modifiers |= 2;
|
|
|
|
if (keydown[K_RALT] && key != K_RALT)
|
|
|
|
modifiers |= 2;
|
|
|
|
if (keydown[K_LCTRL] && key != K_LCTRL)
|
|
|
|
modifiers |= 4;
|
|
|
|
if (keydown[K_RCTRL] && key != K_RCTRL)
|
|
|
|
modifiers |= 4;
|
|
|
|
|
|
|
|
Cbuf_InsertText (va("bind \"%s\" \"%s\"\n", Key_KeynumToString (key, modifiers), currentmenu->selecteditem->bind.command), RESTRICT_LOCAL, false);
|
2004-09-07 18:19:22 +00:00
|
|
|
}
|
|
|
|
bindingactive = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-01-15 05:35:27 +00:00
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
switch(key)
|
|
|
|
{
|
2006-01-28 06:41:20 +00:00
|
|
|
case K_MOUSE2:
|
2004-08-23 00:15:46 +00:00
|
|
|
case K_ESCAPE:
|
|
|
|
//remove
|
|
|
|
M_RemoveMenu(currentmenu);
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("raven/menu3.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("misc/menu3.wav");
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case K_TAB:
|
|
|
|
case K_DOWNARROW:
|
|
|
|
currentmenu->selecteditem = M_NextSelectableItem(currentmenu, currentmenu->selecteditem);
|
|
|
|
|
2010-01-15 05:35:27 +00:00
|
|
|
if (currentmenu->selecteditem)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("raven/menu1.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("misc/menu1.wav");
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (currentmenu->cursoritem)
|
|
|
|
currentmenu->cursoritem->common.posy = currentmenu->selecteditem->common.posy;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case K_UPARROW:
|
|
|
|
currentmenu->selecteditem = M_PrevSelectableItem(currentmenu, currentmenu->selecteditem);
|
|
|
|
|
2010-01-15 05:35:27 +00:00
|
|
|
if (currentmenu->selecteditem)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("raven/menu1.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("misc/menu1.wav");
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
if (currentmenu->cursoritem)
|
|
|
|
currentmenu->cursoritem->common.posy = currentmenu->selecteditem->common.posy;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (!currentmenu->selecteditem)
|
|
|
|
{
|
|
|
|
if (!currentmenu->options)
|
|
|
|
return;
|
|
|
|
currentmenu->selecteditem = currentmenu->options;
|
|
|
|
}
|
|
|
|
switch(currentmenu->selecteditem->common.type)
|
|
|
|
{
|
|
|
|
case mt_slider:
|
|
|
|
MC_Slider_Key(¤tmenu->selecteditem->slider, key);
|
|
|
|
break;
|
|
|
|
case mt_checkbox:
|
2006-02-28 00:46:04 +00:00
|
|
|
MC_CheckBox_Key(¤tmenu->selecteditem->check, currentmenu, key);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_button:
|
2006-03-06 01:41:09 +00:00
|
|
|
case mt_hexen2buttonbigfont:
|
|
|
|
case mt_qbuttonbigfont:
|
2004-08-23 00:15:46 +00:00
|
|
|
if (!currentmenu->selecteditem->button.command)
|
|
|
|
currentmenu->selecteditem->button.key(currentmenu->selecteditem, currentmenu, key);
|
2013-05-03 04:28:08 +00:00
|
|
|
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1)
|
2004-09-07 18:19:22 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
Cbuf_AddText(currentmenu->selecteditem->button.command, RESTRICT_LOCAL);
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("raven/menu2.wav");
|
|
|
|
else
|
2014-10-05 20:04:11 +00:00
|
|
|
#endif
|
2010-01-16 04:59:13 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
2004-09-07 18:19:22 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_custom:
|
2006-02-11 18:06:54 +00:00
|
|
|
if (currentmenu->selecteditem->custom.key)
|
2015-06-16 23:53:58 +00:00
|
|
|
currentmenu->selecteditem->custom.key(¤tmenu->selecteditem->custom, currentmenu, key, unicode);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_edit:
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_EditBox_Key(¤tmenu->selecteditem->edit, key, unicode);
|
2004-08-23 00:15:46 +00:00
|
|
|
break;
|
|
|
|
case mt_combo:
|
|
|
|
MC_Combo_Key(¤tmenu->selecteditem->combo, key);
|
|
|
|
break;
|
2004-09-07 18:19:22 +00:00
|
|
|
case mt_bind:
|
2013-05-03 04:28:08 +00:00
|
|
|
if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1)
|
2004-09-07 18:19:22 +00:00
|
|
|
bindingactive = true;
|
|
|
|
else if (key == K_BACKSPACE || key == K_DEL)
|
|
|
|
M_UnbindCommand (currentmenu->selecteditem->bind.command);
|
2004-08-23 00:15:46 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-06-18 22:11:30 +00:00
|
|
|
extern int m_save_demonum;
|
2004-08-23 00:15:46 +00:00
|
|
|
qboolean MC_Main_Key (int key, menu_t *menu) //here purly to restart demos.
|
|
|
|
{
|
2014-08-27 08:41:31 +00:00
|
|
|
if (key == K_ESCAPE || key == K_MOUSE2)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2016-02-15 06:01:17 +00:00
|
|
|
extern cvar_t con_stayhidden;
|
2014-08-27 08:41:31 +00:00
|
|
|
|
|
|
|
//don't spam menu open+close events if we're not going to be allowing the console to appear
|
|
|
|
if (con_stayhidden.ival && cls.state == ca_disconnected)
|
|
|
|
if (!CL_TryingToConnect())
|
|
|
|
return true;
|
|
|
|
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Remove(kdm_emenu);
|
2004-08-23 00:15:46 +00:00
|
|
|
m_state = m_none;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void M_Menu_Main_f (void)
|
|
|
|
{
|
|
|
|
extern cvar_t m_helpismedia;
|
|
|
|
menubutton_t *b;
|
|
|
|
menu_t *mainm;
|
2004-12-24 08:45:56 +00:00
|
|
|
mpic_t *p;
|
2014-08-17 03:18:43 +00:00
|
|
|
static menuresel_t resel;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2013-03-12 22:53:23 +00:00
|
|
|
#ifdef CSQC_DAT
|
2013-03-12 22:57:40 +00:00
|
|
|
if (CSQC_ConsoleCommand(va("%s %s", Cmd_Argv(0), Cmd_Args())))
|
2013-03-12 22:53:23 +00:00
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
|
2015-06-18 22:11:30 +00:00
|
|
|
/* if (cls.demoplayback)
|
|
|
|
{
|
|
|
|
m_save_demonum = cls.demonum;
|
|
|
|
cls.demonum = -1;
|
|
|
|
}
|
|
|
|
*/
|
2004-08-23 00:15:46 +00:00
|
|
|
SCR_EndLoadingPlaque(); //just in case...
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
int x, i;
|
|
|
|
guiinfo_t *gui;
|
|
|
|
m_state = m_complex;
|
|
|
|
key_dest = key_menu;
|
|
|
|
m_entersound = true;
|
|
|
|
|
|
|
|
mainm = M_CreateMenu(sizeof(guiinfo_t));
|
|
|
|
mainm->key = MC_GuiKey;
|
|
|
|
mainm->xpos=0;
|
2010-01-15 05:35:27 +00:00
|
|
|
gui = (guiinfo_t *)mainm->data;
|
2004-08-23 00:15:46 +00:00
|
|
|
gui->text[0] = "Single";
|
|
|
|
gui->text[1] = "Multiplayer";
|
|
|
|
gui->text[2] = "Quit";
|
|
|
|
for (x = 0, i = 0; gui->text[i]; i++)
|
|
|
|
{
|
|
|
|
gui->op[i] = MC_AddRedText(mainm, x, 0, gui->text[i], false);
|
|
|
|
x+=(strlen(gui->text[i])+1)*8;
|
2010-01-15 05:35:27 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2006-01-01 09:01:15 +00:00
|
|
|
S_LocalSound ("misc/menu2.wav");
|
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
#ifdef Q2CLIENT
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_QUAKE2) //quake2 main menu.
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
if (R_GetShaderSizes(R2D_SafeCachePic("pics/m_main_quit"), NULL, NULL, true) > 0)
|
2010-01-15 05:35:27 +00:00
|
|
|
{
|
2004-08-23 00:15:46 +00:00
|
|
|
m_state = m_complex;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Add(kdm_emenu);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2010-01-15 05:35:27 +00:00
|
|
|
mainm = M_CreateMenu(0);
|
|
|
|
mainm->key = MC_Main_Key;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddPicture(mainm, 0, 4, 38, 166, "pics/m_main_plaque");
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic("pics/m_main_logo");
|
2004-08-23 00:15:46 +00:00
|
|
|
if (!p)
|
|
|
|
return;
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddPicture(mainm, 0, 173, 36, 42, "pics/m_main_logo");
|
2009-04-01 22:03:56 +00:00
|
|
|
#ifndef CLIENTONLY
|
2006-05-11 00:41:47 +00:00
|
|
|
MC_AddSelectablePicture(mainm, 68, 13, "pics/m_main_game");
|
2009-04-01 22:03:56 +00:00
|
|
|
#endif
|
2006-05-11 00:41:47 +00:00
|
|
|
MC_AddSelectablePicture(mainm, 68, 53, "pics/m_main_multiplayer");
|
|
|
|
MC_AddSelectablePicture(mainm, 68, 93, "pics/m_main_options");
|
|
|
|
MC_AddSelectablePicture(mainm, 68, 133, "pics/m_main_video");
|
|
|
|
MC_AddSelectablePicture(mainm, 68, 173, "pics/m_main_quit");
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2009-04-01 22:03:56 +00:00
|
|
|
#ifndef CLIENTONLY
|
2014-03-30 08:55:06 +00:00
|
|
|
b = MC_AddConsoleCommand (mainm, 68, 320, 13, "", "menu_single\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Singleplayer.";
|
2006-01-28 22:49:10 +00:00
|
|
|
mainm->selecteditem = (menuoption_t *)b;
|
2006-01-28 19:34:21 +00:00
|
|
|
b->common.width = 12*20;
|
2013-03-12 22:53:23 +00:00
|
|
|
b->common.height = 32;
|
2009-04-01 22:03:56 +00:00
|
|
|
#endif
|
2014-03-30 08:55:06 +00:00
|
|
|
b = MC_AddConsoleCommand (mainm, 68, 320, 53, "", "menu_multi\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Multiplayer.";
|
2009-04-01 22:03:56 +00:00
|
|
|
#ifdef CLIENTONLY
|
|
|
|
mainm->selecteditem = (menuoption_t *)b;
|
|
|
|
#endif
|
2006-01-28 19:34:21 +00:00
|
|
|
b->common.width = 12*20;
|
2013-03-12 22:53:23 +00:00
|
|
|
b->common.height = 32;
|
2014-03-30 08:55:06 +00:00
|
|
|
b = MC_AddConsoleCommand (mainm, 68, 320, 93, "", "menu_options\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Options.";
|
2006-01-28 19:34:21 +00:00
|
|
|
b->common.width = 12*20;
|
2013-03-12 22:53:23 +00:00
|
|
|
b->common.height = 32;
|
2014-03-30 08:55:06 +00:00
|
|
|
b = MC_AddConsoleCommand (mainm, 68, 320, 133, "", "menu_video\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Video Options.";
|
2006-01-28 19:34:21 +00:00
|
|
|
b->common.width = 12*20;
|
2013-03-12 22:53:23 +00:00
|
|
|
b->common.height = 32;
|
2014-03-30 08:55:06 +00:00
|
|
|
b = MC_AddConsoleCommand (mainm, 68, 320, 173, "", "menu_quit\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Quit to DOS.";
|
2006-01-28 19:34:21 +00:00
|
|
|
b->common.width = 12*20;
|
2013-03-12 22:53:23 +00:00
|
|
|
b->common.height = 32;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 42, mainm->selecteditem->common.posy);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
}
|
2014-10-05 20:04:11 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
#ifdef HEXEN2
|
2016-02-15 06:01:17 +00:00
|
|
|
if (M_GameType() == MGT_HEXEN2)
|
2004-08-23 00:15:46 +00:00
|
|
|
{
|
2014-09-17 03:04:08 +00:00
|
|
|
p = R2D_SafeCachePic("gfx/menu/title0.lmp");
|
2014-10-05 20:04:11 +00:00
|
|
|
if (R_GetShaderSizes(p, NULL, NULL, true) <= 0)
|
2014-09-17 03:04:08 +00:00
|
|
|
return;
|
|
|
|
|
2004-08-23 00:15:46 +00:00
|
|
|
m_state = m_complex;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Add(kdm_emenu);
|
2010-01-15 05:35:27 +00:00
|
|
|
mainm = M_CreateMenu(0);
|
|
|
|
mainm->key = MC_Main_Key;
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddPicture(mainm, 16, 0, 35, 176, "gfx/menu/hplaque.lmp");
|
|
|
|
MC_AddCenterPicture(mainm, 0, 60, "gfx/menu/title0.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2010-08-12 00:48:05 +00:00
|
|
|
#ifndef CLIENTONLY
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64, "Single Player", "menu_single\n");
|
2010-08-12 00:48:05 +00:00
|
|
|
mainm->selecteditem = (menuoption_t *)b;
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = 12*20;
|
|
|
|
b->common.height = 20;
|
2010-08-12 00:48:05 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+20, "MultiPlayer", "menu_multi\n");
|
2010-08-12 00:48:05 +00:00
|
|
|
#ifdef CLIENTONLY
|
|
|
|
mainm->selecteditem = (menuoption_t *)b;
|
|
|
|
#endif
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = 12*20;
|
|
|
|
b->common.height = 20;
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+40, "Options", "menu_options\n");
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = 12*20;
|
|
|
|
b->common.height = 20;
|
|
|
|
if (m_helpismedia.value)
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Media", "menu_media\n");
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Help", "help\n");
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = 12*20;
|
|
|
|
b->common.height = 20;
|
2006-03-06 01:41:09 +00:00
|
|
|
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+80, "Quit", "menu_quit\n");
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = 12*20;
|
|
|
|
b->common.height = 20;
|
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 56, mainm->selecteditem->common.posy);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2014-10-05 20:04:11 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if (QBigFontWorks())
|
2006-03-06 01:41:09 +00:00
|
|
|
{
|
2015-04-14 23:12:17 +00:00
|
|
|
int y;
|
2006-03-06 01:41:09 +00:00
|
|
|
m_state = m_complex;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Add(kdm_emenu);
|
2010-01-15 05:35:27 +00:00
|
|
|
mainm = M_CreateMenu(0);
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
|
2014-10-05 20:04:11 +00:00
|
|
|
if (R_GetShaderSizes(p, NULL, NULL, true) <= 0)
|
2006-03-06 01:41:09 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
|
2006-03-06 01:41:09 +00:00
|
|
|
|
|
|
|
mainm->selecteditem = (menuoption_t *)
|
2014-03-30 08:55:06 +00:00
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n");
|
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n");
|
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n");
|
2006-03-06 01:41:09 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
mainm->key = MC_Main_Key;
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp");
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
y = 32;
|
2006-03-06 01:41:09 +00:00
|
|
|
mainm->selecteditem = (menuoption_t *)
|
2016-07-12 00:40:13 +00:00
|
|
|
#ifndef CLIENTONLY
|
2016-09-01 14:31:24 +00:00
|
|
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Single ", "menu_single\n"); y += 20;
|
2016-07-12 00:40:13 +00:00
|
|
|
#endif
|
2016-09-01 14:31:24 +00:00
|
|
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20;
|
|
|
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20;
|
2006-03-06 01:41:09 +00:00
|
|
|
if (m_helpismedia.value)
|
2016-09-01 14:31:24 +00:00
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;}
|
2006-03-06 01:41:09 +00:00
|
|
|
else
|
2016-09-01 14:31:24 +00:00
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;}
|
2015-04-14 23:12:17 +00:00
|
|
|
if (Cmd_AliasExist("mod_menu", RESTRICT_LOCAL))
|
2016-09-01 14:31:24 +00:00
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, va("%-14s", Cvar_Get("mod_menu", "Mod Menu", 0, NULL)->string), "mod_menu\n"); y += 20;}
|
2015-04-14 23:12:17 +00:00
|
|
|
if (Cmd_Exists("xmpp"))
|
2016-09-01 14:31:24 +00:00
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Social ", "xmpp\n"); y += 20;}
|
2015-04-14 23:12:17 +00:00
|
|
|
if (Cmd_Exists("irc"))
|
2016-09-01 14:31:24 +00:00
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;}
|
|
|
|
if (Cmd_Exists("qi"))
|
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "qi\n"); y += 20;}
|
|
|
|
if (Cmd_Exists("menu_download"))
|
|
|
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;}
|
2014-08-27 08:41:31 +00:00
|
|
|
#ifdef FTE_TARGET_WEB
|
2016-09-01 14:31:24 +00:00
|
|
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings ", "menu_quit\n"); y += 20;
|
2014-08-27 08:41:31 +00:00
|
|
|
#else
|
2016-09-01 14:31:24 +00:00
|
|
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit ", "menu_quit\n"); y += 20;
|
2014-08-27 08:41:31 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
|
2006-03-06 01:41:09 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_state = m_complex;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Add(kdm_emenu);
|
2010-01-15 05:35:27 +00:00
|
|
|
mainm = M_CreateMenu(0);
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
|
2014-10-05 20:04:11 +00:00
|
|
|
if (R_GetShaderSizes(p, NULL, NULL, true) <= 0)
|
2004-12-15 19:39:21 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
|
2005-01-13 16:29:20 +00:00
|
|
|
|
|
|
|
mainm->selecteditem = (menuoption_t *)
|
2014-03-30 08:55:06 +00:00
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n");
|
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n");
|
|
|
|
MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n");
|
2004-08-23 00:15:46 +00:00
|
|
|
return;
|
2004-12-15 19:39:21 +00:00
|
|
|
}
|
2005-01-13 16:29:20 +00:00
|
|
|
mainm->key = MC_Main_Key;
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
2005-01-13 16:29:20 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp");
|
|
|
|
MC_AddPicture(mainm, 72, 32, 240, 112, "gfx/mainmenu.lmp");
|
2004-08-23 00:15:46 +00:00
|
|
|
|
2006-01-21 00:06:49 +00:00
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
p = R2D_SafeCachePic("gfx/mainmenu.lmp");
|
2006-01-21 00:06:49 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand (mainm, 72, 312, 32, "", "menu_single\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Start singleplayer Quake game.";
|
2004-08-23 00:15:46 +00:00
|
|
|
mainm->selecteditem = (menuoption_t *)b;
|
|
|
|
b->common.width = p->width;
|
|
|
|
b->common.height = 20;
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand (mainm, 72, 312, 52, "", "menu_multi\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Multiplayer menu.";
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = p->width;
|
|
|
|
b->common.height = 20;
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand (mainm, 72, 312, 72, "", "menu_options\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Options menu.";
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = p->width;
|
|
|
|
b->common.height = 20;
|
|
|
|
if (m_helpismedia.value)
|
2009-04-19 10:50:31 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "menu_media\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Media menu.";
|
2009-04-19 10:50:31 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
else
|
2009-04-19 10:50:31 +00:00
|
|
|
{
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "help\n");
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Help menu.";
|
2009-04-19 10:50:31 +00:00
|
|
|
}
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = p->width;
|
|
|
|
b->common.height = 20;
|
2014-03-30 08:55:06 +00:00
|
|
|
b=MC_AddConsoleCommand (mainm, 72, 312, 112, "", "menu_quit\n");
|
2014-08-27 08:41:31 +00:00
|
|
|
#ifdef FTE_TARGET_WEB
|
|
|
|
b->common.tooltip = "Save settings to local storage.";
|
|
|
|
#else
|
2011-07-22 15:05:40 +00:00
|
|
|
b->common.tooltip = "Exit to DOS.";
|
2014-08-27 08:41:31 +00:00
|
|
|
#endif
|
2004-08-23 00:15:46 +00:00
|
|
|
b->common.width = p->width;
|
|
|
|
b->common.height = 20;
|
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
2012-04-24 07:59:11 +00:00
|
|
|
|
|
|
|
if (!m_preset_chosen.ival)
|
|
|
|
M_Menu_Preset_f();
|
2004-08-23 00:15:46 +00:00
|
|
|
}
|
|
|
|
|
2014-08-17 03:18:43 +00:00
|
|
|
int MC_AddBulk(struct menu_s *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y)
|
2011-06-07 23:54:58 +00:00
|
|
|
{
|
|
|
|
int selectedy = y;
|
|
|
|
menuoption_t *selected = NULL;
|
|
|
|
|
|
|
|
while (bulk)
|
|
|
|
{
|
2011-06-16 21:41:05 +00:00
|
|
|
menuoption_t *control;
|
|
|
|
int x = xtextend;
|
|
|
|
int xleft;
|
2011-06-18 05:41:10 +00:00
|
|
|
int spacing = 8;
|
2011-07-22 15:05:40 +00:00
|
|
|
|
2011-06-16 21:41:05 +00:00
|
|
|
if (bulk->text)
|
2016-07-12 00:40:13 +00:00
|
|
|
{ //lots of fancy code just to figure out the correct width of the string. yay. :(
|
|
|
|
int px, py;
|
|
|
|
conchar_t buffer[2048], *end;
|
|
|
|
end = COM_ParseFunString(CON_WHITEMASK, bulk->text, buffer, sizeof(buffer), false);
|
|
|
|
Font_BeginString(font_default, 0, 0, &px, &py);
|
|
|
|
px = Font_LineWidth(buffer, end);
|
|
|
|
Font_EndString(NULL);
|
|
|
|
|
|
|
|
x -= ((float)px * vid.width) / vid.rotpixelwidth;
|
|
|
|
}
|
2011-06-16 21:41:05 +00:00
|
|
|
xleft = x - xstart;
|
|
|
|
|
2011-06-07 23:54:58 +00:00
|
|
|
switch (bulk->type)
|
|
|
|
{
|
|
|
|
case mt_text:
|
|
|
|
switch (bulk->variant)
|
|
|
|
{
|
|
|
|
case -1: // end of menu
|
2011-10-27 15:46:36 +00:00
|
|
|
default:
|
2011-06-07 23:54:58 +00:00
|
|
|
bulk = NULL;
|
2011-10-27 15:46:36 +00:00
|
|
|
control = NULL;
|
2011-06-07 23:54:58 +00:00
|
|
|
continue;
|
|
|
|
case 0: // white text
|
2014-03-30 08:55:06 +00:00
|
|
|
control = (union menuoption_s *)MC_AddWhiteText(menu, xleft, xtextend, y, bulk->text, bulk->rightalign);
|
2011-06-07 23:54:58 +00:00
|
|
|
break;
|
|
|
|
case 1: // red text
|
2014-03-30 08:55:06 +00:00
|
|
|
control = (union menuoption_s *)MC_AddRedText(menu, xleft, xtextend, y, bulk->text, bulk->rightalign);
|
2011-06-07 23:54:58 +00:00
|
|
|
break;
|
|
|
|
case 2: // spacing
|
2011-06-18 05:41:10 +00:00
|
|
|
spacing = bulk->spacing;
|
2011-10-27 15:46:36 +00:00
|
|
|
control = NULL;
|
2011-06-07 23:54:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_button:
|
2011-06-16 21:41:05 +00:00
|
|
|
switch (bulk->variant)
|
2011-06-07 23:54:58 +00:00
|
|
|
{
|
2011-06-16 21:41:05 +00:00
|
|
|
default:
|
|
|
|
case 0: // console command
|
2014-03-30 08:55:06 +00:00
|
|
|
control = (union menuoption_s *)MC_AddConsoleCommand(menu, xleft, xtextend, y, bulk->text, bulk->consolecmd);
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
|
|
|
case 1: // function command
|
2014-03-30 08:55:06 +00:00
|
|
|
control = (union menuoption_s *)MC_AddCommand(menu, xleft, xtextend, y, bulk->text, bulk->command);
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
2011-06-07 23:54:58 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_checkbox:
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddCheckBox(menu, xleft, xtextend, y, bulk->text, bulk->cvar, bulk->flags);
|
2011-06-16 21:41:05 +00:00
|
|
|
control->check.func = bulk->func;
|
2011-06-07 23:54:58 +00:00
|
|
|
break;
|
|
|
|
case mt_slider:
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddSlider(menu, xleft, xtextend, y, bulk->text, bulk->cvar, bulk->min, bulk->max, bulk->delta);
|
2011-06-07 23:54:58 +00:00
|
|
|
break;
|
|
|
|
case mt_combo:
|
2011-06-16 21:41:05 +00:00
|
|
|
switch (bulk->variant)
|
2011-06-07 23:54:58 +00:00
|
|
|
{
|
2011-06-16 21:41:05 +00:00
|
|
|
default:
|
|
|
|
case 0: // cvar combo
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddCvarCombo(menu, xleft, xtextend, y, bulk->text, bulk->cvar, bulk->options, bulk->values);
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
|
|
|
case 1: // combo with return value
|
2015-01-21 18:18:37 +00:00
|
|
|
if (bulk->selectedoption < 0)
|
|
|
|
{ //invalid...
|
|
|
|
control = NULL;
|
|
|
|
spacing = 0;
|
|
|
|
break;
|
|
|
|
}
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddCombo(menu, xleft, xtextend, y, bulk->text, bulk->options, bulk->selectedoption);
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
2011-06-07 23:54:58 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case mt_edit:
|
2011-06-16 21:41:05 +00:00
|
|
|
switch (bulk->variant)
|
2011-06-07 23:54:58 +00:00
|
|
|
{
|
2011-06-16 21:41:05 +00:00
|
|
|
default:
|
|
|
|
case 0:
|
|
|
|
y += 4;
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddEditCvar(menu, xleft, xtextend, y, bulk->text, bulk->cvarname, false);
|
2011-06-18 05:41:10 +00:00
|
|
|
spacing += 4;
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2013-10-29 17:38:22 +00:00
|
|
|
control = (union menuoption_s *)MC_AddEditCvar(menu, xleft, xtextend, y, bulk->text, bulk->cvarname, true);
|
2011-06-16 21:41:05 +00:00
|
|
|
break;
|
2011-06-07 23:54:58 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Con_Printf(CON_ERROR "Invalid type in bulk menu!\n");
|
|
|
|
bulk = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
2011-06-16 21:41:05 +00:00
|
|
|
|
|
|
|
if (bulk->ret)
|
|
|
|
*bulk->ret = control;
|
2011-10-27 15:46:36 +00:00
|
|
|
if (control && MI_Selectable(control) && !selected)
|
2011-06-16 21:41:05 +00:00
|
|
|
selected = control;
|
2011-10-27 15:46:36 +00:00
|
|
|
if (control && bulk->tooltip)
|
2011-06-16 21:41:05 +00:00
|
|
|
control->common.tooltip = bulk->tooltip;
|
2011-10-27 15:46:36 +00:00
|
|
|
if (control && xleft > 0)
|
2011-06-16 21:41:05 +00:00
|
|
|
control->common.extracollide = xleft;
|
2011-06-18 05:41:10 +00:00
|
|
|
y += spacing;
|
2011-06-16 21:41:05 +00:00
|
|
|
|
2011-06-07 23:54:58 +00:00
|
|
|
bulk++;
|
|
|
|
}
|
|
|
|
|
|
|
|
menu->selecteditem = selected;
|
|
|
|
if (selected)
|
|
|
|
selectedy = selected->common.posy;
|
2014-08-17 03:18:43 +00:00
|
|
|
menu->cursoritem = (menuoption_t*)MC_AddCursorSmall(menu, resel, xtextend + 8, selectedy);
|
2011-06-07 23:54:58 +00:00
|
|
|
return y;
|
|
|
|
}
|
2014-09-02 02:44:43 +00:00
|
|
|
#endif
|