Add dutch translation
[oweals/minetest.git] / src / hud.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu>
5 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This program 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 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <IGUIStaticText.h>
23
24 #include "guiFormSpecMenu.h"
25 #include "main.h"
26 #include "util/numeric.h"
27 #include "log.h"
28 #include "client.h"
29 #include "hud.h"
30
31
32 Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
33                 gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
34                 LocalPlayer *player, Inventory *inventory) {
35         this->driver      = driver;
36         this->guienv      = guienv;
37         this->font        = font;
38         this->text_height = text_height;
39         this->gamedef     = gamedef;
40         this->player      = player;
41         this->inventory   = inventory;
42         
43         screensize       = v2u32(0, 0);
44         displaycenter    = v2s32(0, 0);
45         hotbar_imagesize = 48;
46         hotbar_itemcount = 8;
47         
48         v3f crosshair_color = g_settings->getV3F("crosshair_color");
49         u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
50         u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
51         u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
52         u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
53         crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
54         
55         v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
56         u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
57         u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
58         u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
59         selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
60 }
61
62
63 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
64 void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
65                 InventoryList *mainlist, u16 selectitem, u16 direction)
66 {
67         s32 padding = imgsize / 12;
68         s32 height  = imgsize + padding * 2;
69         s32 width   = itemcount * (imgsize + padding * 2);
70         if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
71                 width  = imgsize + padding * 2;
72                 height = itemcount * (imgsize + padding * 2);
73         }
74         s32 fullimglen = imgsize + padding * 2;
75
76         // Position of upper left corner of bar
77         v2s32 pos = upperleftpos;
78
79         // Draw background color
80         /*core::rect<s32> barrect(0,0,width,height);
81         barrect += pos;
82         video::SColor bgcolor(255,128,128,128);
83         driver->draw2DRectangle(bgcolor, barrect, NULL);*/
84
85         core::rect<s32> imgrect(0, 0, imgsize, imgsize);
86
87         for (s32 i = 0; i < itemcount; i++)
88         {
89                 const ItemStack &item = mainlist->getItem(i);
90
91                 v2s32 steppos;
92                 switch (direction) {
93                         case HUD_DIR_RIGHT_LEFT:
94                                 steppos = v2s32(-(padding + i * fullimglen), padding);
95                                 break;
96                         case HUD_DIR_TOP_BOTTOM:
97                                 steppos = v2s32(padding, padding + i * fullimglen);
98                                 break;
99                         case HUD_DIR_BOTTOM_TOP:
100                                 steppos = v2s32(padding, -(padding + i * fullimglen));
101                                 break;
102                         default:
103                                 steppos = v2s32(padding + i * fullimglen, padding);     
104                 }
105                         
106                 core::rect<s32> rect = imgrect + pos + steppos;
107
108                 if (selectitem == i + 1)
109                 {
110                         video::SColor c_outside(255,255,0,0);
111                         //video::SColor c_outside(255,0,0,0);
112                         //video::SColor c_inside(255,192,192,192);
113                         s32 x1 = rect.UpperLeftCorner.X;
114                         s32 y1 = rect.UpperLeftCorner.Y;
115                         s32 x2 = rect.LowerRightCorner.X;
116                         s32 y2 = rect.LowerRightCorner.Y;
117                         // Black base borders
118                         driver->draw2DRectangle(c_outside,
119                                         core::rect<s32>(
120                                                 v2s32(x1 - padding, y1 - padding),
121                                                 v2s32(x2 + padding, y1)
122                                         ), NULL);
123                         driver->draw2DRectangle(c_outside,
124                                         core::rect<s32>(
125                                                 v2s32(x1 - padding, y2),
126                                                 v2s32(x2 + padding, y2 + padding)
127                                         ), NULL);
128                         driver->draw2DRectangle(c_outside,
129                                         core::rect<s32>(
130                                                 v2s32(x1 - padding, y1),
131                                                 v2s32(x1, y2)
132                                         ), NULL);
133                         driver->draw2DRectangle(c_outside,
134                                         core::rect<s32>(
135                                                 v2s32(x2, y1),
136                                                 v2s32(x2 + padding, y2)
137                                         ), NULL);
138                         /*// Light inside borders
139                         driver->draw2DRectangle(c_inside,
140                                         core::rect<s32>(
141                                                 v2s32(x1 - padding/2, y1 - padding/2),
142                                                 v2s32(x2 + padding/2, y1)
143                                         ), NULL);
144                         driver->draw2DRectangle(c_inside,
145                                         core::rect<s32>(
146                                                 v2s32(x1 - padding/2, y2),
147                                                 v2s32(x2 + padding/2, y2 + padding/2)
148                                         ), NULL);
149                         driver->draw2DRectangle(c_inside,
150                                         core::rect<s32>(
151                                                 v2s32(x1 - padding/2, y1),
152                                                 v2s32(x1, y2)
153                                         ), NULL);
154                         driver->draw2DRectangle(c_inside,
155                                         core::rect<s32>(
156                                                 v2s32(x2, y1),
157                                                 v2s32(x2 + padding/2, y2)
158                                         ), NULL);
159                         */
160                 }
161
162                 video::SColor bgcolor2(128, 0, 0, 0);
163                 driver->draw2DRectangle(bgcolor2, rect, NULL);
164                 drawItemStack(driver, font, item, rect, NULL, gamedef);
165         }
166 }
167
168
169 void Hud::drawLuaElements() {
170         for (size_t i = 0; i != player->hud.size(); i++) {
171                 HudElement *e = player->hud[i];
172                 if (!e)
173                         continue;
174                 
175                 v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y);
176                 switch (e->type) {
177                         case HUD_ELEM_IMAGE: {
178                                 video::ITexture *texture =
179                                         gamedef->getTextureSource()->getTextureRaw(e->text);
180                                 if (!texture)
181                                         continue;
182
183                                 const video::SColor color(255, 255, 255, 255);
184                                 const video::SColor colors[] = {color, color, color, color};
185                                 core::dimension2di imgsize(texture->getOriginalSize());
186                                 core::rect<s32> rect(0, 0, imgsize.Width  * e->scale.X,
187                                                                                imgsize.Height * e->scale.X);
188                                 rect += pos;
189                                 driver->draw2DImage(texture, rect,
190                                         core::rect<s32>(core::position2d<s32>(0,0), imgsize),
191                                         NULL, colors, true);
192                                 break; }
193                         case HUD_ELEM_TEXT: {
194                                 video::SColor color(255, (e->number >> 16) & 0xFF,
195                                                                                  (e->number >> 8)  & 0xFF,
196                                                                                  (e->number >> 0)  & 0xFF);
197                                 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
198                                 font->draw(narrow_to_wide(e->text).c_str(), size + pos, color);
199                                 break; }
200                         case HUD_ELEM_STATBAR:
201                                 drawStatbar(pos, e->text, e->number);
202                                 break;
203                         case HUD_ELEM_INVENTORY: {
204                                 InventoryList *inv = inventory->getList(e->text);
205                                 drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir);
206                                 break; }
207                         default:
208                                 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
209                                         "of hud element ID " << i << " due to unrecognized type" << std::endl;
210                 }
211         }
212 }
213
214
215 void Hud::drawStatbar(v2s32 upperleftpos, std::string texture, s32 count) {
216         video::ITexture *stat_texture =
217                 gamedef->getTextureSource()->getTextureRaw(texture);
218         if (!stat_texture)
219                 return;
220
221         v2s32 p = upperleftpos;
222         for (s32 i = 0; i < count / 2; i++)
223         {
224                 core::dimension2di srcd(stat_texture->getOriginalSize());
225                 const video::SColor color(255, 255, 255, 255);
226                 const video::SColor colors[] = {color, color, color, color};
227                 core::rect<s32> rect(0, 0, srcd.Width, srcd.Height);
228                 rect += p;
229                 driver->draw2DImage(stat_texture, rect,
230                         core::rect<s32>(core::position2d<s32>(0, 0), srcd),
231                         NULL, colors, true);
232                 p += v2s32(srcd.Width, 0);
233         }
234         
235         if (count % 2 == 1)
236         {
237                 core::dimension2di srcd(stat_texture->getOriginalSize());
238                 const video::SColor color(255, 255, 255, 255);
239                 const video::SColor colors[] = {color, color, color, color};
240                 core::rect<s32> rect(0, 0, srcd.Width / 2, srcd.Height);
241                 rect += p;
242                 srcd.Width /= 2;
243                 driver->draw2DImage(stat_texture, rect,
244                         core::rect<s32>(core::position2d<s32>(0, 0), srcd),
245                         NULL, colors, true);
246                 p += v2s32(srcd.Width * 2, 0);
247         }
248 }
249
250
251 void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
252         InventoryList *mainlist = inventory->getList("main");
253         if (mainlist == NULL) {
254                 errorstream << "draw_hotbar(): mainlist == NULL" << std::endl;
255                 return;
256         }
257         
258         s32 padding = hotbar_imagesize / 12;
259         s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2);
260         v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2);
261         
262         drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0);
263         drawStatbar(pos + v2s32(0, -20), "heart.png", halfheartcount);
264 }
265
266
267 void Hud::drawCrosshair() {
268         driver->draw2DLine(displaycenter - v2s32(10,0),
269                         displaycenter + v2s32(10, 0), crosshair_argb);
270         driver->draw2DLine(displaycenter - v2s32(0,10),
271                         displaycenter + v2s32(0, 10), crosshair_argb);
272 }
273
274
275 void Hud::drawSelectionBoxes(std::vector<aabb3f> &hilightboxes) {
276         for (std::vector<aabb3f>::const_iterator
277                         i = hilightboxes.begin();
278                         i != hilightboxes.end(); i++) {
279                 driver->draw3DBox(*i, selectionbox_argb);
280         }
281 }
282
283
284 void Hud::resizeHotbar() {
285         if (screensize.Y <= 800)
286                 hotbar_imagesize = 32;
287         else if (screensize.Y <= 1280)
288                 hotbar_imagesize = 48;
289         else
290                 hotbar_imagesize = 64;
291 }