diff options
| author | xolatile | 2025-08-06 22:54:55 +0200 |
|---|---|---|
| committer | xolatile | 2025-08-06 22:54:55 +0200 |
| commit | 0a1172b75f571685c264a8b9d8ee224bbf11381f (patch) | |
| tree | d041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/menus.cpp | |
| parent | affde05dc07a94643f1fd2751b2b441f57f73d7d (diff) | |
| download | xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst | |
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/menus.cpp')
| -rw-r--r-- | src/engine/menus.cpp | 357 |
1 files changed, 116 insertions, 241 deletions
diff --git a/src/engine/menus.cpp b/src/engine/menus.cpp index 805a79b..e2bd266 100644 --- a/src/engine/menus.cpp +++ b/src/engine/menus.cpp @@ -12,17 +12,13 @@ static g3d_gui *cgui = NULL; VAR(guitabnum, 1, 0, 0); -struct menu : g3d_callback -{ +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 gui(g3d_gui &g, bool firstpass) { cgui = &g; guitabnum = menutab; cgui->start(menustart, 0.03f, showtab ? &menutab : NULL); @@ -32,75 +28,57 @@ struct menu : g3d_callback cgui = NULL; guitabnum = 0; } - - virtual void clear() - { + virtual void clear() { if(onclear) { freecode(onclear); onclear = NULL; } } }; -struct delayedupdate -{ - enum - { +struct delayedupdate { + enum { INT, FLOAT, STRING, ACTION } type; ident *id; - union - { + 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) - { + 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) - { + 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) - { + 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() - { + void run() { if(type == ACTION) { if(val.s) execute(val.s); } - else if(id) switch(id->type) - { + 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; @@ -117,8 +95,7 @@ static bool shouldclearmenu = true, clearlater = false; VARP(menudistance, 16, 40, 256); VARP(menuautoclose, 32, 120, 4096); -vec menuinfrontofplayer() -{ +vec menuinfrontofplayer() { vec dir; vecfromyawpitch(camera1->yaw, 0, 1, 0, dir); dir.mul(menudistance).add(camera1->o); @@ -126,48 +103,40 @@ vec menuinfrontofplayer() return dir; } -void popgui() -{ +void popgui() { menu *m = guistack.pop(); m->clear(); } -void removegui(menu *m) -{ - loopv(guistack) if(guistack[i]==m) - { +void removegui(menu *m) { + loopv(guistack) if(guistack[i]==m) { guistack.remove(i); m->clear(); return; } } -void pushgui(menu *m, int pos = -1) -{ - if(guistack.empty()) - { +void pushgui(menu *m, int pos = -1) { + if(guistack.empty()) { menupos = menuinfrontofplayer(); g3d_resetcursor(); } if(pos < 0) guistack.add(m); else guistack.insert(pos, m); - if(pos < 0 || pos==guistack.length()-1) - { + if(pos < 0 || pos==guistack.length()-1) { if(!m->keeptab) m->menutab = 1; menustart = totalmillis; } if(m->init) execute(m->init); } -void restoregui(int pos) -{ +void restoregui(int pos) { int clear = guistack.length()-pos-1; loopi(clear) popgui(); menustart = totalmillis; } -void showgui(const char *name) -{ +void showgui(const char *name) { menu *m = guis.access(name); if(!m) return; int pos = guistack.find(m); @@ -175,17 +144,14 @@ void showgui(const char *name) else restoregui(pos); } -void hidegui(const char *name) -{ +void hidegui(const char *name) { menu *m = guis.access(name); if(m) removegui(m); } -int cleargui(int n) -{ +int cleargui(int n) { int clear = guistack.length(); - if(mainmenu && !isconnected(true) && clear > 0 && guistack[0]->name && !strcmp(guistack[0]->name, "main")) - { + if(mainmenu && !isconnected(true) && clear > 0 && guistack[0]->name && !strcmp(guistack[0]->name, "main")) { clear--; if(!clear) return 1; } @@ -195,14 +161,12 @@ int cleargui(int n) return clear; } -void clearguis(int level = -1) -{ +void clearguis(int level = -1) { if(level < 0) level = guistack.length(); - loopvrev(guistack) - { + loopvrev(guistack) { menu *m = guistack[i]; if(m->onclear) - { + { uint *action = m->onclear; m->onclear = NULL; execute(action); @@ -212,32 +176,28 @@ void clearguis(int level = -1) cleargui(level); } -void guionclear(char *action) -{ +void guionclear(char *action) { if(guistack.empty()) return; menu *m = guistack.last(); if(m->onclear) { freecode(m->onclear); m->onclear = NULL; } if(action[0]) m->onclear = compilecode(action); } -void guistayopen(uint *contents) -{ +void guistayopen(uint *contents) { bool oldclearmenu = shouldclearmenu; shouldclearmenu = false; execute(contents); shouldclearmenu = oldclearmenu; } -void guinoautotab(uint *contents) -{ +void guinoautotab(uint *contents) { if(!cgui) return; bool oldval = cgui->allowautotab(false); execute(contents); cgui->allowautotab(oldval); } -void guimerge(uint *contents) -{ +void guimerge(uint *contents) { if(!cgui) return; bool oldval = cgui->mergehits(true); execute(contents); @@ -245,114 +205,92 @@ void guimerge(uint *contents) } //@DOC name and icon are optional -void guibutton(char *name, char *action, char *icon) -{ +void guibutton(char *name, char *action, char *icon) { if(!cgui) return; bool hideicon = !strcmp(icon, "0"); int ret = cgui->button(name, GUI_BUTTON_COLOR, hideicon ? NULL : (icon[0] ? icon : (strstr(action, "showgui") ? "menu" : "action"))); - if(ret&G3D_UP) - { + if(ret&G3D_UP) { updatelater.add().schedule(action[0] ? action : name); if(shouldclearmenu) clearlater = true; } - else if(ret&G3D_ROLLOVER) - { + else if(ret&G3D_ROLLOVER) { alias("guirollovername", name); alias("guirolloveraction", action); } } -void guiimage(char *path, char *action, float *scale, int *overlaid, char *alt, char *title) -{ +void guiimage(char *path, char *action, float *scale, int *overlaid, char *alt, char *title) { if(!cgui) return; Texture *t = textureload(path, 0, true, false); - if(t==notexture) - { + if(t==notexture) { if(alt[0]) t = textureload(alt, 0, true, false); if(t==notexture) return; } int ret = cgui->image(t, *scale, *overlaid!=0 ? title : NULL); - if(ret&G3D_UP) - { - if(*action) - { + if(ret&G3D_UP) { + if(*action) { updatelater.add().schedule(action); if(shouldclearmenu) clearlater = true; } } - else if(ret&G3D_ROLLOVER) - { + else if(ret&G3D_ROLLOVER) { alias("guirolloverimgpath", path); alias("guirolloverimgaction", action); } } -void guicolor(int *color) -{ - if(cgui) - { +void guicolor(int *color) { + if(cgui) { defformatstring(desc, "0x%06X", *color); cgui->text(desc, *color, NULL); } } -void guitextbox(char *text, int *width, int *height, int *color) -{ +void guitextbox(char *text, int *width, int *height, int *color) { if(cgui && text[0]) cgui->textbox(text, *width ? *width : 12, *height ? *height : 1, *color ? *color : 0xFFFFFF); } -void guitext(char *name, char *icon) -{ +void guitext(char *name, char *icon) { bool hideicon = !strcmp(icon, "0"); if(cgui) cgui->text(name, !hideicon && icon[0] ? GUI_BUTTON_COLOR : GUI_TEXT_COLOR, hideicon ? NULL : (icon[0] ? icon : "info")); } -void guititle(char *name) -{ +void guititle(char *name) { if(cgui) cgui->title(name, GUI_TITLE_COLOR); } -void guitab(char *name) -{ +void guitab(char *name) { if(cgui) cgui->tab(name, GUI_TITLE_COLOR); } -void guibar() -{ +void guibar() { if(cgui) cgui->separator(); } -void guistrut(float *strut, int *alt) -{ - if(cgui) - { +void guistrut(float *strut, int *alt) { + if(cgui) { if(*alt) cgui->strut(*strut); else cgui->space(*strut); } } -void guispring(int *weight) -{ +void guispring(int *weight) { if(cgui) cgui->spring(max(*weight, 1)); } -void guicolumn(int *col) -{ +void guicolumn(int *col) { if(cgui) cgui->column(*col); } -template<class T> static void updateval(char *var, T val, char *onchange) -{ +template<class T> static void updateval(char *var, T val, char *onchange) { ident *id = writeident(var); updatelater.add().schedule(id, val); if(onchange[0]) updatelater.add().schedule(onchange); } -static int getval(char *var) -{ +static int getval(char *var) { ident *id = readident(var); if(!id) return 0; - switch(id->type) - { + switch(id->type) { case ID_VAR: return *id->storage.i; case ID_FVAR: return int(*id->storage.f); case ID_SVAR: return parseint(*id->storage.s); @@ -361,12 +299,10 @@ static int getval(char *var) } } -static float getfval(char *var) -{ +static float getfval(char *var) { ident *id = readident(var); if(!id) return 0; - switch(id->type) - { + switch(id->type) { case ID_VAR: return *id->storage.i; case ID_FVAR: return *id->storage.f; case ID_SVAR: return parsefloat(*id->storage.s); @@ -375,12 +311,10 @@ static float getfval(char *var) } } -static const char *getsval(char *var) -{ +static const char *getsval(char *var) { ident *id = readident(var); if(!id) return ""; - switch(id->type) - { + switch(id->type) { case ID_VAR: return intstr(*id->storage.i); case ID_FVAR: return floatstr(*id->storage.f); case ID_SVAR: return *id->storage.s; @@ -389,21 +323,18 @@ static const char *getsval(char *var) } } -void guislider(char *var, int *min, int *max, char *onchange) -{ +void guislider(char *var, int *min, int *max, char *onchange) { if(!cgui) return; int oldval = getval(var), val = oldval, vmin = *max > INT_MIN ? *min : getvarmin(var), vmax = *max > INT_MIN ? *max : getvarmax(var); cgui->slider(val, vmin, vmax, GUI_TITLE_COLOR); if(val != oldval) updateval(var, val, onchange); } -void guilistslider(char *var, char *list, char *onchange) -{ +void guilistslider(char *var, char *list, char *onchange) { if(!cgui) return; vector<int> vals; list += strspn(list, "\n\t "); - while(*list) - { + while(*list) { vals.add(parseint(list)); list += strcspn(list, "\n\t \0"); list += strspn(list, "\n\t "); @@ -415,13 +346,11 @@ void guilistslider(char *var, char *list, char *onchange) if(offset != oldoffset) updateval(var, vals[offset], onchange); } -void guinameslider(char *var, char *names, char *list, char *onchange) -{ +void guinameslider(char *var, char *names, char *list, char *onchange) { if(!cgui) return; vector<int> vals; list += strspn(list, "\n\t "); - while(*list) - { + while(*list) { vals.add(parseint(list)); list += strcspn(list, "\n\t \0"); list += strspn(list, "\n\t "); @@ -435,37 +364,30 @@ void guinameslider(char *var, char *names, char *list, char *onchange) delete[] label; } -void guicheckbox(char *name, char *var, float *on, float *off, char *onchange) -{ +void guicheckbox(char *name, char *var, float *on, float *off, char *onchange) { bool enabled = getfval(var)!=*off; - if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) - { + if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) { updateval(var, enabled ? *off : (*on || *off ? *on : 1.0f), onchange); } } -void guiradio(char *name, char *var, float *n, char *onchange) -{ +void guiradio(char *name, char *var, float *n, char *onchange) { bool enabled = getfval(var)==*n; - if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "radio_on" : "radio_off")&G3D_UP) - { + if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "radio_on" : "radio_off")&G3D_UP) { if(!enabled) updateval(var, *n, onchange); } } -void guibitfield(char *name, char *var, int *mask, char *onchange) -{ +void guibitfield(char *name, char *var, int *mask, char *onchange) { int val = getval(var); bool enabled = (val & *mask) != 0; - if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) - { + if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) { updateval(var, enabled ? val & ~*mask : val | *mask, onchange); } } //-ve length indicates a wrapped text field of any (approx 260 chars) length, |length| is the field width -void guifield(char *var, int *maxlength, char *onchange) -{ +void guifield(char *var, int *maxlength, char *onchange) { if(!cgui) return; const char *initval = getsval(var); char *result = cgui->field(var, GUI_BUTTON_COLOR, *maxlength ? *maxlength : 12, 0, initval); @@ -473,16 +395,14 @@ void guifield(char *var, int *maxlength, char *onchange) } //-ve maxlength indicates a wrapped text field of any (approx 260 chars) length, |maxlength| is the field width -void guieditor(char *name, int *maxlength, int *height, int *mode) -{ +void guieditor(char *name, int *maxlength, int *height, int *mode) { if(!cgui) return; cgui->field(name, GUI_BUTTON_COLOR, *maxlength ? *maxlength : 12, *height, NULL, *mode<=0 ? EDITORFOREVER : *mode); //returns a non-NULL pointer (the currentline) when the user commits, could then manipulate via text* commands } //-ve length indicates a wrapped text field of any (approx 260 chars) length, |length| is the field width -void guikeyfield(char *var, int *maxlength, char *onchange) -{ +void guikeyfield(char *var, int *maxlength, char *onchange) { if(!cgui) return; const char *initval = getsval(var); char *result = cgui->keyfield(var, GUI_BUTTON_COLOR, *maxlength ? *maxlength : -8, 0, initval); @@ -492,16 +412,14 @@ void guikeyfield(char *var, int *maxlength, char *onchange) //use text<action> to do more... -void guilist(uint *contents) -{ +void guilist(uint *contents) { if(!cgui) return; cgui->pushlist(); execute(contents); cgui->poplist(); } -void guialign(int *align, uint *contents) -{ +void guialign(int *align, uint *contents) { if(!cgui) return; cgui->pushlist(); if(*align >= 0) cgui->spring(); @@ -510,38 +428,31 @@ void guialign(int *align, uint *contents) cgui->poplist(); } -void newgui(char *name, char *contents, char *header, char *init) -{ +void newgui(char *name, char *contents, char *header, char *init) { menu *m = guis.access(name); - if(!m) - { + if(!m) { name = newstring(name); m = &guis[name]; m->name = name; } - else - { + else { DELETEA(m->header); freecode(m->contents); freecode(m->init); } - if(header && header[0]) - { + if(header && header[0]) { char *end = NULL; int val = strtol(header, &end, 0); - if(end && !*end) - { + if(end && !*end) { m->header = NULL; m->showtab = val != 0; } - else - { + else { m->header = newstring(header); m->showtab = true; } } - else - { + else { m->header = NULL; m->showtab = true; } @@ -551,14 +462,11 @@ void newgui(char *name, char *contents, char *header, char *init) menu *guiserversmenu = NULL; -void guiservers(uint *header, int *pagemin, int *pagemax) -{ +void guiservers(uint *header, int *pagemin, int *pagemax) { extern const char *showservers(g3d_gui *cgui, uint *header, int pagemin, int pagemax); - if(cgui) - { + if(cgui) { const char *command = showservers(cgui, header, *pagemin, *pagemax > 0 ? *pagemax : INT_MAX); - if(command) - { + if(command) { updatelater.add().schedule(command); if(shouldclearmenu) clearlater = true; guiserversmenu = clearlater || guistack.empty() ? NULL : guistack.last(); @@ -566,10 +474,8 @@ void guiservers(uint *header, int *pagemin, int *pagemax) } } -void notifywelcome() -{ - if(guiserversmenu) - { +void notifywelcome() { + if(guiserversmenu) { if(guistack.length() && guistack.last() == guiserversmenu) clearguis(); guiserversmenu = NULL; } @@ -608,14 +514,11 @@ COMMAND(guieditor, "siii"); COMMAND(guicolor, "i"); COMMAND(guitextbox, "siii"); -void guiplayerpreview(int *model, int *team, int *weap, char *action, float *scale, int *overlaid, char *title) -{ +void guiplayerpreview(int *model, int *team, int *weap, char *action, float *scale, int *overlaid, char *title) { if(!cgui) return; int ret = cgui->playerpreview(*model, *team, *weap, *scale, *overlaid!=0 ? title : NULL); - if(ret&G3D_UP) - { - if(*action) - { + if(ret&G3D_UP) { + if(*action) { updatelater.add().schedule(action); if(shouldclearmenu) clearlater = true; } @@ -623,84 +526,68 @@ void guiplayerpreview(int *model, int *team, int *weap, char *action, float *sca } COMMAND(guiplayerpreview, "iiisfis"); -void guimodelpreview(char *model, char *animspec, char *action, float *scale, int *overlaid, char *title, int *throttle) -{ +void guimodelpreview(char *model, char *animspec, char *action, float *scale, int *overlaid, char *title, int *throttle) { if(!cgui) return; int anim = ANIM_ALL; - if(animspec[0]) - { - if(isdigit(animspec[0])) - { + if(animspec[0]) { + if(isdigit(animspec[0])) { anim = parseint(animspec); if(anim >= 0) anim %= ANIM_INDEX; else anim = ANIM_ALL; } - else - { + else { vector<int> anims; findanims(animspec, anims); if(anims.length()) anim = anims[0]; } } int ret = cgui->modelpreview(model, anim|ANIM_LOOP, *scale, *overlaid!=0 ? title : NULL, *throttle!=0); - if(ret&G3D_UP) - { - if(*action) - { + if(ret&G3D_UP) { + if(*action) { updatelater.add().schedule(action); if(shouldclearmenu) clearlater = true; } } - else if(ret&G3D_ROLLOVER) - { + else if(ret&G3D_ROLLOVER) { alias("guirolloverpreviewname", model); alias("guirolloverpreviewaction", action); } } COMMAND(guimodelpreview, "sssfisi"); -void guiprefabpreview(char *prefab, int *color, char *action, float *scale, int *overlaid, char *title, int *throttle) -{ +void guiprefabpreview(char *prefab, int *color, char *action, float *scale, int *overlaid, char *title, int *throttle) { if(!cgui) return; int ret = cgui->prefabpreview(prefab, vec::hexcolor(*color), *scale, *overlaid!=0 ? title : NULL, *throttle!=0); - if(ret&G3D_UP) - { - if(*action) - { + if(ret&G3D_UP) { + if(*action) { updatelater.add().schedule(action); if(shouldclearmenu) clearlater = true; } } - else if(ret&G3D_ROLLOVER) - { + else if(ret&G3D_ROLLOVER) { alias("guirolloverpreviewname", prefab); alias("guirolloverpreviewaction", action); } } COMMAND(guiprefabpreview, "sisfisi"); -struct change -{ +struct change { int type; const char *desc; - change() {} change(int type, const char *desc) : type(type), desc(desc) {} }; static vector<change> needsapply; -static struct applymenu : menu -{ - void gui(g3d_gui &g, bool firstpass) - { +static struct applymenu : menu { + void gui(g3d_gui &g, bool firstpass) { if(guistack.empty()) return; g.start(menustart, 0.03f); g.text("the following settings have changed:", GUI_TEXT_COLOR, "info"); loopv(needsapply) g.text(needsapply[i].desc, GUI_TEXT_COLOR, "info"); g.separator(); g.text("apply changes now?", GUI_TEXT_COLOR, "info"); - if(g.button("yes", GUI_BUTTON_COLOR, "action")&G3D_UP) - { + if(g.button("yes", GUI_BUTTON_COLOR, "action")&G3D_UP) { int changetypes = 0; loopv(needsapply) changetypes |= needsapply[i].type; if(changetypes&CHANGE_GFX) updatelater.add().schedule("resetgl"); @@ -711,9 +598,7 @@ static struct applymenu : menu clearlater = true; g.end(); } - - void clear() - { + void clear() { menu::clear(); needsapply.shrink(0); } @@ -723,8 +608,7 @@ VARP(applydialog, 0, 1, 1); static bool processingmenu = false; -void addchange(const char *desc, int type) -{ +void addchange(const char *desc, int type) { if(!applydialog) return; loopv(needsapply) if(!strcmp(needsapply[i].desc, desc)) return; needsapply.add(change(type, desc)); @@ -732,12 +616,9 @@ void addchange(const char *desc, int type) pushgui(&applymenu, processingmenu ? max(guistack.length()-1, 0) : -1); } -void clearchanges(int type) -{ - loopv(needsapply) - { - if(needsapply[i].type&type) - { +void clearchanges(int type) { + loopv(needsapply) { + if(needsapply[i].type&type) { needsapply[i].type &= ~type; if(!needsapply[i].type) needsapply.remove(i--); } @@ -745,14 +626,12 @@ void clearchanges(int type) if(needsapply.empty()) removegui(&applymenu); } -void menuprocess() -{ +void menuprocess() { processingmenu = true; int wasmain = mainmenu, level = guistack.length(); loopv(updatelater) updatelater[i].run(); updatelater.shrink(0); - if(wasmain > mainmenu || clearlater) - { + if(wasmain > mainmenu || clearlater) { if(wasmain > mainmenu || level==guistack.length()) clearguis(level); clearlater = false; } @@ -762,19 +641,15 @@ void menuprocess() VAR(mainmenu, 1, 1, 0); -void clearmainmenu() -{ - if(mainmenu && isconnected()) - { +void clearmainmenu() { + if(mainmenu && isconnected()) { mainmenu = 0; if(!processingmenu) cleargui(); } } -void g3d_mainmenu() -{ - if(!guistack.empty()) - { +void g3d_mainmenu() { + if(!guistack.empty()) { extern int usegui2d; if(!mainmenu && !usegui2d && camera1->o.dist(menupos) > menuautoclose) cleargui(); else g3d_addgui(guistack.last(), menupos, GUI_2D | GUI_FOLLOW); |
