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(const 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.emplace_back(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 : }
|