// menus.cpp: ingame menu system (also used for scores and serverlist)
#include "engine.h"
#define GUI_TITLE_COLOR 0xFFDD88
#define GUI_BUTTON_COLOR 0xFFFFFF
#define GUI_TEXT_COLOR 0xDDFFDD
static vec menupos;
static int menustart = 0;
static g3d_gui *cgui = NULL;
VAR(guitabnum, 1, 0, 0);
struct menu : g3d_callback {
char *name, *header;
uint *contents, *init, *onclear;
bool showtab, keeptab;
int menutab;
menu() : name(NULL), header(NULL), contents(NULL), init(NULL), onclear(NULL), showtab(true), keeptab(false), menutab(1) {}
void gui(g3d_gui &g, bool firstpass) {
(void) firstpass;
cgui = &g;
guitabnum = menutab;
cgui->start(menustart, 0.03f, showtab ? &menutab : NULL);
if(showtab) cgui->tab(header ? header : name, GUI_TITLE_COLOR);
execute(contents);
cgui->end();
cgui = NULL;
guitabnum = 0;
}
virtual void clear() {
if(onclear) { freecode(onclear); onclear = NULL; }
}
};
struct delayedupdate {
enum {
INT,
FLOAT,
STRING,
ACTION
} type;
ident *id;
union {
int i;
float f;
char *s;
} val;
delayedupdate() : type(ACTION), id(NULL) { val.s = NULL; }
~delayedupdate() { if(type == STRING || type == ACTION) DELETEA(val.s); }
void schedule(const char *s) { type = ACTION; val.s = newstring(s); }
void schedule(ident *var, int i) { type = INT; id = var; val.i = i; }
void schedule(ident *var, float f) { type = FLOAT; id = var; val.f = f; }
void schedule(ident *var, char *s) { type = STRING; id = var; val.s = newstring(s); }
int getint() const {
switch(type) {
case INT: return val.i;
case FLOAT: return int(val.f);
case STRING: return int(strtol(val.s, NULL, 0));
default: return 0;
}
}
float getfloat() const {
switch(type) {
case INT: return float(val.i);
case FLOAT: return val.f;
case STRING: return float(parsefloat(val.s));
default: return 0;
}
}
const char *getstring() const {
switch(type) {
case INT: return intstr(val.i);
case FLOAT: return intstr(int(floor(val.f)));
case STRING: return val.s;
default: return "";
}
}
void run() {
if(type == ACTION) { if(val.s) execute(val.s); }
else if(id) switch(id->type) {
case ID_VAR: setvarchecked(id, getint()); break;
case ID_FVAR: setfvarchecked(id, getfloat()); break;
case ID_SVAR: setsvarchecked(id, getstring()); break;
case ID_ALIAS: alias(id->name, getstring()); break;
}
}
};
static hashnameset