]> git.jsancho.org Git - lugaru.git/blob - Source/Menu.cpp
f3d9e0bf70a3a55ee5d657d67c6550cfb0c8b972
[lugaru.git] / Source / Menu.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <vector>
22 #include <string>
23 #include "gamegl.h"
24
25 #include "Menu.h"
26 using namespace Menu;
27
28 extern float multiplier;
29
30 struct MenuItem {
31     enum MenuItemType {NONE, LABEL, BUTTON, IMAGE, IMAGEBUTTON, MAPMARKER, MAPLINE, MAPLABEL} type;
32     int id;
33     string text;
34     Texture texture;
35     int x, y, w, h;
36     float r, g, b;
37     float effectfade;
38
39     float linestartsize;
40     float lineendsize;
41
42     void init(MenuItemType _type, int _id, const string& _text, Texture _texture,
43               int _x, int _y, int _w, int _h, float _r, float _g, float _b,
44               float _linestartsize = 1, float _lineendsize = 1) {
45         type = _type;
46         id = _id;
47         text = _text;
48         texture = _texture;
49         x = _x;
50         y = _y;
51         w = _w;
52         h = _h;
53         r = _r;
54         g = _g;
55         b = _b;
56         effectfade = 0;
57         linestartsize = _linestartsize;
58         lineendsize = _lineendsize;
59         if (type == MenuItem::BUTTON) {
60             if (w == -1)
61                 w = text.length() * 10;
62             if (h == -1)
63                 h = 20;
64         }
65     }
66 };
67
68 vector<MenuItem> items;
69
70
71
72
73 void Menu::clearMenu()
74 {
75     items.clear();
76 }
77
78 void Menu::addLabel(int id, const string& text, int x, int y, float r, float g, float b)
79 {
80     items.push_back(MenuItem());
81     items.back().init(MenuItem::LABEL, id, text, Texture(), x, y, -1, -1, r, g, b);
82 }
83 void Menu::addButton(int id, const string& text, int x, int y, float r, float g, float b)
84 {
85     items.push_back(MenuItem());
86     items.back().init(MenuItem::BUTTON, id, text, Texture(), x, y, -1, -1, r, g, b);
87 }
88 void Menu::addImage(int id, Texture texture, int x, int y, int w, int h, float r, float g, float b)
89 {
90     items.push_back(MenuItem());
91     items.back().init(MenuItem::IMAGE, id, "", texture, x, y, w, h, r, g, b);
92 }
93 void Menu::addButtonImage(int id, Texture texture, int x, int y, int w, int h, float r, float g, float b)
94 {
95     items.push_back(MenuItem());
96     items.back().init(MenuItem::IMAGEBUTTON, id, "", texture, x, y, w, h, r, g, b);
97 }
98 void Menu::addMapLine(int x, int y, int w, int h, float startsize, float endsize, float r, float g, float b)
99 {
100     items.push_back(MenuItem());
101     items.back().init(MenuItem::MAPLINE, -1, "", Texture(), x, y, w, h, r, g, b, startsize, endsize);
102 }
103 void Menu::addMapMarker(int id, Texture texture, int x, int y, int w, int h, float r, float g, float b)
104 {
105     items.push_back(MenuItem());
106     items.back().init(MenuItem::MAPMARKER, id, "", texture, x, y, w, h, r, g, b);
107 }
108 void Menu::addMapLabel(int id, const string& text, int x, int y, float r, float g, float b)
109 {
110     items.push_back(MenuItem());
111     items.back().init(MenuItem::MAPLABEL, id, text, Texture(), x, y, -1, -1, r, g, b);
112 }
113
114 void Menu::setText(int id, const string& text)
115 {
116     for (vector<MenuItem>::iterator it = items.begin(); it != items.end(); it++)
117         if (it->id == id) {
118             it->text = text;
119             it->w = it->text.length() * 10;
120             break;
121         }
122 }
123
124 void Menu::setText(int id, const string& text, int x, int y, int w, int h)
125 {
126     for (vector<MenuItem>::iterator it = items.begin(); it != items.end(); it++)
127         if (it->id == id) {
128             it->text = text;
129             it->x = x;
130             it->y = y;
131             if (w == -1)
132                 it->w = it->text.length() * 10;
133             if (h == -1)
134                 it->h = 20;
135             break;
136         }
137 }
138
139 int Menu::getSelected(int mousex, int mousey)
140 {
141     for (vector<MenuItem>::iterator it = items.begin(); it != items.end(); it++)
142         if (it->type == MenuItem::BUTTON || it->type == MenuItem::IMAGEBUTTON || it->type == MenuItem::MAPMARKER) {
143             int mx = mousex;
144             int my = mousey;
145             if (it->type == MenuItem::MAPMARKER) {
146                 mx -= 1;
147                 my += 2;
148             }
149             if (mx >= it->x && mx < it->x + it->w && my >= it->y && my < it->y + it->h)
150                 return it->id;
151         }
152     return -1;
153 }
154
155 void GUITick()
156 {
157     for (vector<MenuItem>::iterator it = items.begin(); it != items.end(); it++) {
158         if (it->id == Game::selected) {
159             it->effectfade += multiplier * 5;
160             if (it->effectfade > 1)
161                 it->effectfade = 1;
162         } else {
163             it->effectfade -= multiplier * 5;
164             if (it->effectfade < 0)
165                 it->effectfade = 0;
166         }
167     }
168 }
169
170 void Menu::drawItems()
171 {
172     GUITick();
173     glEnable(GL_TEXTURE_2D);
174     glEnable(GL_ALPHA_TEST);
175     glEnable(GL_BLEND);
176     for (vector<MenuItem>::iterator it = items.begin(); it != items.end(); it++) {
177         switch (it->type) {
178         case MenuItem::IMAGE:
179         case MenuItem::IMAGEBUTTON:
180         case MenuItem::MAPMARKER:
181             glColor4f(it->r, it->g, it->b, 1);
182             glPushMatrix();
183             if (it->type == MenuItem::MAPMARKER) {
184                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
185                 glTranslatef(2.5, -4.5, 0); //from old code
186             } else {
187                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
188             }
189             it->texture.bind();
190             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
191             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
192             glBegin(GL_QUADS);
193             glTexCoord2f(0, 0);
194             glVertex3f(it->x, it->y, 0);
195             glTexCoord2f(1, 0);
196             glVertex3f(it->x + it->w, it->y, 0);
197             glTexCoord2f(1, 1);
198             glVertex3f(it->x + it->w, it->y + it->h, 0);
199             glTexCoord2f(0, 1);
200             glVertex3f(it->x, it->y + it->h, 0);
201             glEnd();
202             if (it->type != MenuItem::IMAGE) {
203                 //mouseover highlight
204                 for (int i = 0; i < 10; i++) {
205                     if (1 - ((float)i) / 10 - (1 - it->effectfade) > 0) {
206                         glColor4f(it->r, it->g, it->b, (1 - ((float)i) / 10 - (1 - it->effectfade))*.25);
207                         glBegin(GL_QUADS);
208                         glTexCoord2f(0, 0);
209                         glVertex3f(it->x - ((float)i) * 1 / 2, it->y - ((float)i) * 1 / 2, 0);
210                         glTexCoord2f(1, 0);
211                         glVertex3f(it->x + it->w + ((float)i) * 1 / 2, it->y - ((float)i) * 1 / 2, 0);
212                         glTexCoord2f(1, 1);
213                         glVertex3f(it->x + it->w + ((float)i) * 1 / 2, it->y + it->h + ((float)i) * 1 / 2, 0);
214                         glTexCoord2f(0, 1);
215                         glVertex3f(it->x - ((float)i) * 1 / 2, it->y + it->h + ((float)i) * 1 / 2, 0);
216                         glEnd();
217                     }
218                 }
219             }
220             glPopMatrix();
221             break;
222         case MenuItem::LABEL:
223         case MenuItem::BUTTON:
224             glColor4f(it->r, it->g, it->b, 1);
225             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
226             Game::text->glPrint(it->x, it->y, it->text.c_str(), 0, 1, 640, 480);
227             if (it->type != MenuItem::LABEL) {
228                 //mouseover highlight
229                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
230                 for (int i = 0; i < 15; i++) {
231                     if (1 - ((float)i) / 15 - (1 - it->effectfade) > 0) {
232                         glColor4f(it->r, it->g, it->b, (1 - ((float)i) / 10 - (1 - it->effectfade))*.25);
233                         Game::text->glPrint(it->x - ((float)i), it->y, it->text.c_str(), 0, 1 + ((float)i) / 70, 640, 480);
234                     }
235                 }
236             }
237             break;
238         case MenuItem::MAPLABEL:
239             Game::text->glPrintOutlined(0.9, 0, 0, it->x, it->y, it->text.c_str(), 0, 0.6, 640, 480);
240             break;
241         case MenuItem::MAPLINE: {
242             XYZ linestart;
243             linestart.x = it->x;
244             linestart.y = it->y;
245             linestart.z = 0;
246             XYZ lineend;
247             lineend.x = it->x + it->w;
248             lineend.y = it->y + it->h;
249             lineend.z = 0;
250             XYZ offset = lineend - linestart;
251             XYZ fac = offset;
252             Normalise(&fac);
253             offset = DoRotation(offset, 0, 0, 90);
254             Normalise(&offset);
255
256             linestart += fac * 4 * it->linestartsize;
257             lineend -= fac * 4 * it->lineendsize;
258
259             glDisable(GL_TEXTURE_2D);
260             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
261             glColor4f(it->r, it->g, it->b, 1);
262             glPushMatrix();
263             glTranslatef(2, -5, 0); //from old code
264             glBegin(GL_QUADS);
265             glVertex3f(linestart.x - offset.x * it->linestartsize, linestart.y - offset.y * it->linestartsize, 0.0f);
266             glVertex3f(linestart.x + offset.x * it->linestartsize, linestart.y + offset.y * it->linestartsize, 0.0f);
267             glVertex3f(lineend.x + offset.x * it->lineendsize, lineend.y + offset.y * it->lineendsize, 0.0f);
268             glVertex3f(lineend.x - offset.x * it->lineendsize, lineend.y - offset.y * it->lineendsize, 0.0f);
269             glEnd();
270             glPopMatrix();
271             glEnable(GL_TEXTURE_2D);
272         }
273         break;
274         default:
275         case MenuItem::NONE:
276         break;
277         }
278     }
279 }
280