Line data Source code
1 : /* 2 : * menus.cpp 3 : * 4 : * automatic triggers for certain UIs in game 5 : * does not implement menus, just some low level bindings for main menu functionality 6 : */ 7 : 8 : #include "../libprimis-headers/cube.h" 9 : 10 : #include "control.h" 11 : #include "menus.h" 12 : #include "ui.h" 13 : 14 : #include "world/octaedit.h" 15 : 16 : //internally relevant functionality 17 : namespace 18 : { 19 : struct Change 20 : { 21 : int type; 22 : const char *desc; 23 : 24 : Change() {} 25 1 : Change(int type, const char *desc) : type(type), desc(desc) {} 26 : 27 0 : bool operator==(const Change & c) const 28 : { 29 0 : return type == c.type && std::strcmp(desc, c.desc) == 0; 30 : } 31 : }; 32 : std::vector<Change> needsapply; 33 : 34 : VARP(applydialog, 0, 1, 1); 35 : 36 : //when 1: change UI shows up whenever a pending change is added 37 : //when 0: change UI does not appear and applychanges must be used manually 38 : VAR(showchanges, 0, 1, 1); 39 : 40 : //goes through and applies changes that are enqueued 41 1 : void applychanges() 42 : { 43 1 : int changetypes = 0; 44 2 : for(const Change &i : needsapply) 45 : { 46 1 : changetypes |= i.type; 47 : } 48 1 : if(changetypes&Change_Graphics) 49 : { 50 1 : execident("resetgl"); 51 : } 52 0 : else if(changetypes&Change_Shaders) 53 : { 54 0 : execident("resetshaders"); 55 : } 56 1 : if(changetypes&Change_Sound) 57 : { 58 0 : execident("resetsound"); 59 : } 60 1 : } 61 : 62 : //returns if there are pending changes or not enqueued 63 1 : void pendingchanges(int *idx) 64 : { 65 1 : if(idx) 66 : { 67 1 : if((needsapply.size()) > static_cast<uint>(*idx)) 68 : { 69 0 : result(needsapply.at(*idx).desc); 70 : } 71 1 : else if(*idx < 0) 72 : { 73 1 : intret(needsapply.size()); 74 : } 75 : } 76 1 : } 77 : } 78 : 79 : //externally relevant functionality 80 : 81 : //toggles if the main menu is shown 82 : VAR(mainmenu, 1, 1, 0); 83 : 84 : //adds a change to the queue of settings changes, 85 : //if applydialog = 0 then this function does nothing 86 : //if showchanges = 1 then this function does not display changes UI at the end 87 1 : void addchange(const char *desc, int type) 88 : { 89 1 : if(!applydialog) 90 : { 91 0 : return; 92 : } 93 1 : for(const Change &i : needsapply) 94 : { 95 0 : if(!std::strcmp(i.desc, desc)) 96 : { 97 0 : return; 98 : } 99 : } 100 1 : needsapply.push_back(Change(type, desc)); 101 1 : if(showchanges) 102 : { 103 1 : UI::showui("changes"); 104 : } 105 : } 106 : 107 0 : void notifywelcome() 108 : { 109 0 : UI::hideui("servers"); 110 0 : } 111 : 112 : //clears out pending changes added by addchange() 113 0 : void clearchanges(int type) 114 : { 115 0 : for(int i = needsapply.size(); --i >=0;) //note reverse iteration 116 : { 117 0 : Change &c = needsapply[i]; 118 0 : if(c.type&type) 119 : { 120 0 : c.type &= ~type; 121 0 : if(!c.type) 122 : { 123 0 : auto it = std::find(needsapply.begin(), needsapply.end(), needsapply[i]); 124 0 : needsapply.erase(it); 125 : } 126 : } 127 : } 128 0 : if(needsapply.empty()) 129 : { 130 0 : UI::hideui("changes"); 131 : } 132 0 : } 133 : 134 0 : void clearmainmenu() 135 : { 136 0 : showchanges = 1; 137 0 : if(mainmenu && multiplayer) 138 : { 139 0 : mainmenu = 0; 140 0 : UI::hideui(nullptr); 141 : } 142 0 : } 143 : 144 1 : void initmenuscmds() 145 : { 146 1 : addcommand("applychanges", reinterpret_cast<identfun>(applychanges), "", Id_Command); 147 1 : addcommand("pendingchanges", reinterpret_cast<identfun>(pendingchanges), "b", Id_Command); 148 1 : }