From 1838a3fd696782b1733a435bbb25accf3e40d1f3 Mon Sep 17 00:00:00 2001 From: sapier Date: Sat, 5 Apr 2014 14:12:36 +0200 Subject: [PATCH] Add support for dpi based HUD scaling Add support for (configurable) multiline hotbar Improved screensize handling Add userdefined gui scale by BlockMen --- doc/menu_lua_api.txt | 10 +- minetest.conf.example | 7 +- src/camera.cpp | 4 +- src/camera.h | 2 +- src/defaultsettings.cpp | 2 + src/game.cpp | 26 ++-- src/hud.cpp | 250 ++++++++++++++++-------------- src/hud.h | 27 ++-- src/main.cpp | 4 +- src/porting.cpp | 42 ++++- src/porting.h | 13 +- src/script/lua_api/l_mainmenu.cpp | 28 ++++ src/script/lua_api/l_mainmenu.h | 2 + 13 files changed, 266 insertions(+), 151 deletions(-) diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 87e37dd0d..321f74a8c 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -116,6 +116,14 @@ engine.file_open_dialog(formname,caption) ^ -if dialog was canceled "_cancelled" ^ will be added to fieldname value is set to formname itself ^ returns nil or selected file/folder +engine.get_screen_info() +^ returns { + density = , + display_width = , + display_height = , + window_width = , + window_height = + } Games: engine.get_game(index) @@ -198,7 +206,7 @@ engine.handle_async(async_job,parameters,finished) ^ execute a function asynchronously ^ async_job is a function receiving one parameter and returning one parameter ^ parameters parameter table passed to async_job -^ finished function to be called once async_job has finished +^ finished function to be called once async_job has finished ^ the result of async_job is passed to this function Limitations of Async operations diff --git a/minetest.conf.example b/minetest.conf.example index 548adccee..707aa675e 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -140,6 +140,8 @@ #crosshair_color = (255,255,255) # Cross alpha (opaqueness, between 0 and 255) #crosshair_alpha = 255 +# scale gui by a user specified value +#gui_scaling = 1.0 # Sensitivity multiplier #mouse_sensitivity = 0.2 # Sound settings @@ -147,6 +149,9 @@ #sound_volume = 0.7 # Whether node texture animations should be desynchronized per MapBlock #desynchronize_mapblock_texture_animation = true +# maximum percentage of current window to be used for hotbar +# (usefull if you've there's something to be displayed right or left of hotbar) +#hud_hotbar_max_width = 1.0 # Texture filtering settings #mip_map = false #anisotropic_filter = false @@ -165,7 +170,7 @@ #normalmaps_strength = 0.6 # Strength of generated normalmaps #normalmaps_smooth = 1 -# Defines sampling step of texture (0 - 2) +# Defines sampling step of texture (0 - 2) # Higher the value normal maps will be smoother #enable_parallax_occlusion = false # Scale of parallax occlusion effect diff --git a/src/camera.cpp b/src/camera.cpp index b49e8e748..254827803 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -249,7 +249,7 @@ void Camera::step(f32 dtime) } void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, - v2u32 screensize, f32 tool_reload_ratio, + f32 tool_reload_ratio, int current_camera_mode, ClientEnvironment &c_env) { // Get player position @@ -422,7 +422,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, fov_degrees = MYMIN(fov_degrees, 170.0); // FOV and aspect ratio - m_aspect = (f32)screensize.X / (f32) screensize.Y; + m_aspect = (f32) porting::getWindowSize().X / (f32) porting::getWindowSize().Y; m_fov_y = fov_degrees * M_PI / 180.0; // Increase vertical FOV on lower aspect ratios (<16:10) m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect))); diff --git a/src/camera.h b/src/camera.h index d1c3b59d4..63d109f1f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -117,7 +117,7 @@ public: // Update the camera from the local player's position. // busytime is used to adjust the viewing range. void update(LocalPlayer* player, f32 frametime, f32 busytime, - v2u32 screensize, f32 tool_reload_ratio, + f32 tool_reload_ratio, int current_camera_mode, ClientEnvironment &c_env); // Render distance feedback loop diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index ff3bf5b88..e245abb83 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -119,10 +119,12 @@ void set_default_settings(Settings *settings) settings->setDefault("selectionbox_color", "(0,0,0)"); settings->setDefault("crosshair_color", "(255,255,255)"); settings->setDefault("crosshair_alpha", "255"); + settings->setDefault("gui_scaling", "1.0"); settings->setDefault("mouse_sensitivity", "0.2"); settings->setDefault("enable_sound", "true"); settings->setDefault("sound_volume", "0.8"); settings->setDefault("desynchronize_mapblock_texture_animation", "true"); + settings->setDefault("hud_hotbar_max_width","1.0"); settings->setDefault("mip_map", "false"); settings->setDefault("anisotropic_filter", "false"); diff --git a/src/game.cpp b/src/game.cpp index 2d6205140..bcf59fb26 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1099,7 +1099,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, // Calculate text height using the font u32 text_height = font->getDimension(L"Random test string").Height; - v2u32 last_screensize(0,0); v2u32 screensize = driver->getScreenSize(); /* @@ -1842,15 +1841,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, /* Random calculations */ - last_screensize = screensize; - screensize = driver->getScreenSize(); - v2s32 displaycenter(screensize.X/2,screensize.Y/2); - //bool screensize_changed = screensize != last_screensize; - - - // Update HUD values - hud.screensize = screensize; - hud.displaycenter = displaycenter; hud.resizeHotbar(); // Hilight boxes collected during the loop and displayed @@ -2267,10 +2257,11 @@ void the_game(bool &kill, bool random_input, InputHandler *input, first_loop_after_window_activation = false; } else{ - s32 dx = input->getMousePos().X - displaycenter.X; - s32 dy = input->getMousePos().Y - displaycenter.Y; - if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT) + s32 dx = input->getMousePos().X - (driver->getScreenSize().Width/2); + s32 dy = input->getMousePos().Y - (driver->getScreenSize().Height/2); + if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT) { dy = -dy; + } //infostream<<"window active, pos difference "<setMousePos(displaycenter.X, displaycenter.Y); + input->setMousePos((driver->getScreenSize().Width/2), + (driver->getScreenSize().Height/2)); } else{ // Mac OSX gets upset if this is set every frame @@ -2657,7 +2649,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, } player->camera_mode = current_camera_mode; tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0); - camera.update(player, dtime, busytime, screensize, tool_reload_ratio, + camera.update(player, dtime, busytime, tool_reload_ratio, current_camera_mode, client.getEnv()); camera.step(dtime); @@ -3538,8 +3530,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input, */ if (show_hud) { - hud.drawHotbar(v2s32(displaycenter.X, screensize.Y), - client.getHP(), client.getPlayerItem(), client.getBreath()); + hud.drawHotbar(client.getHP(), client.getPlayerItem(), + client.getBreath()); } /* diff --git a/src/hud.cpp b/src/hud.cpp index 343b548e9..f5f959903 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include "localplayer.h" #include "camera.h" - +#include "porting.h" #include @@ -47,9 +47,15 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, this->player = player; this->inventory = inventory; - screensize = v2u32(0, 0); - displaycenter = v2s32(0, 0); - hotbar_imagesize = 48; + m_screensize = v2u32(0, 0); + m_displaycenter = v2s32(0, 0); + m_hotbar_imagesize = HOTBAR_IMAGE_SIZE * porting::getDisplayDensity(); + m_padding = m_hotbar_imagesize / 12; + + const video::SColor hbar_color(255, 255, 255, 255); + for (unsigned int i=0; i < 4; i++ ){ + hbar_colors[i] = hbar_color; + } tsrc = gamedef->getTextureSource(); @@ -74,92 +80,21 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, use_hotbar_selected_image = false; } +void Hud::drawItem(const ItemStack &item, const core::rect& rect, bool selected) { -//NOTE: selectitem = 0 -> no selected; selectitem 1-based -void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount, - InventoryList *mainlist, u16 selectitem, u16 direction) -{ - s32 padding = imgsize / 12; - s32 height = imgsize + padding * 2; - s32 width = itemcount * (imgsize + padding * 2); - if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) { - width = imgsize + padding * 2; - height = itemcount * (imgsize + padding * 2); - } - s32 fullimglen = imgsize + padding * 2; - - // Position of upper left corner of bar - v2s32 pos = upperleftpos; - - // Draw background color - /*core::rect barrect(0,0,width,height); - barrect += pos; - video::SColor bgcolor(255,128,128,128); - driver->draw2DRectangle(bgcolor, barrect, NULL);*/ - - core::rect imgrect(0, 0, imgsize, imgsize); - const video::SColor hbar_color(255, 255, 255, 255); - const video::SColor hbar_colors[] = {hbar_color, hbar_color, hbar_color, hbar_color}; - - if (hotbar_image != player->hotbar_image) { - hotbar_image = player->hotbar_image; - if (hotbar_image != "") - use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image); - else - use_hotbar_image = false; - } - - if (hotbar_selected_image != player->hotbar_selected_image) { - hotbar_selected_image = player->hotbar_selected_image; - if (hotbar_selected_image != "") - use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image); - else - use_hotbar_selected_image = false; - } - - if (use_hotbar_image) { - core::rect imgrect2(-padding/2, -padding/2, width+padding/2, height+padding/2); - core::rect rect2 = imgrect2 + pos; - video::ITexture *texture = tsrc->getTexture(hotbar_image); - core::dimension2di imgsize(texture->getOriginalSize()); - driver->draw2DImage(texture, rect2, - core::rect(core::position2d(0,0), imgsize), - NULL, hbar_colors, true); - } - - for (s32 i = 0; i < itemcount && (size_t)i < mainlist->getSize(); i++) - { - const ItemStack &item = mainlist->getItem(i); - - v2s32 steppos; - switch (direction) { - case HUD_DIR_RIGHT_LEFT: - steppos = v2s32(-(padding + i * fullimglen), padding); - break; - case HUD_DIR_TOP_BOTTOM: - steppos = v2s32(padding, padding + i * fullimglen); - break; - case HUD_DIR_BOTTOM_TOP: - steppos = v2s32(padding, -(padding + i * fullimglen)); - break; - default: - steppos = v2s32(padding + i * fullimglen, padding); - } - - core::rect rect = imgrect + pos + steppos; - - if (selectitem == i + 1) { + if (selected) { if (use_hotbar_selected_image) { - core::rect imgrect2(-padding*2, -padding*2, height, height); - rect = imgrect2 + pos + steppos; + core::rect imgrect2 = rect; + imgrect2.UpperLeftCorner.X -= m_padding; + imgrect2.UpperLeftCorner.Y -= m_padding; + imgrect2.LowerRightCorner.X += m_padding; + imgrect2.LowerRightCorner.Y += m_padding; video::ITexture *texture = tsrc->getTexture(hotbar_selected_image); core::dimension2di imgsize(texture->getOriginalSize()); - driver->draw2DImage(texture, rect, + driver->draw2DImage(texture, imgrect2, core::rect(core::position2d(0,0), imgsize), NULL, hbar_colors, true); - rect = imgrect + pos + steppos; } else { - rect = imgrect + pos + steppos; video::SColor c_outside(255,255,0,0); //video::SColor c_outside(255,0,0,0); //video::SColor c_inside(255,192,192,192); @@ -170,23 +105,23 @@ void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount, // Black base borders driver->draw2DRectangle(c_outside, core::rect( - v2s32(x1 - padding, y1 - padding), - v2s32(x2 + padding, y1) + v2s32(x1 - m_padding, y1 - m_padding), + v2s32(x2 + m_padding, y1) ), NULL); driver->draw2DRectangle(c_outside, core::rect( - v2s32(x1 - padding, y2), - v2s32(x2 + padding, y2 + padding) + v2s32(x1 - m_padding, y2), + v2s32(x2 + m_padding, y2 + m_padding) ), NULL); driver->draw2DRectangle(c_outside, core::rect( - v2s32(x1 - padding, y1), + v2s32(x1 - m_padding, y1), v2s32(x1, y2) ), NULL); driver->draw2DRectangle(c_outside, core::rect( v2s32(x2, y1), - v2s32(x2 + padding, y2) + v2s32(x2 + m_padding, y2) ), NULL); /*// Light inside borders driver->draw2DRectangle(c_inside, @@ -218,6 +153,72 @@ void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount, driver->draw2DRectangle(bgcolor2, rect, NULL); drawItemStack(driver, font, item, rect, NULL, gamedef); } + +//NOTE: selectitem = 0 -> no selected; selectitem 1-based +void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset, + InventoryList *mainlist, u16 selectitem, u16 direction) +{ + s32 height = m_hotbar_imagesize + m_padding * 2; + s32 width = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2); + + if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) { + width = m_hotbar_imagesize + m_padding * 2; + height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2); + } + + // Position of upper left corner of bar + v2s32 pos = upperleftpos; + + if (hotbar_image != player->hotbar_image) { + hotbar_image = player->hotbar_image; + if (hotbar_image != "") + use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image); + else + use_hotbar_image = false; + } + + if (hotbar_selected_image != player->hotbar_selected_image) { + hotbar_selected_image = player->hotbar_selected_image; + if (hotbar_selected_image != "") + use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image); + else + use_hotbar_selected_image = false; + } + + if (use_hotbar_image) { + core::rect imgrect2(-m_padding/2, -m_padding/2, width+m_padding/2, height+m_padding/2); + core::rect rect2 = imgrect2 + pos; + video::ITexture *texture = tsrc->getTexture(hotbar_image); + core::dimension2di imgsize(texture->getOriginalSize()); + driver->draw2DImage(texture, rect2, + core::rect(core::position2d(0,0), imgsize), + NULL, hbar_colors, true); + } + + for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) + { + v2s32 steppos; + s32 fullimglen = m_hotbar_imagesize + m_padding * 2; + + core::rect imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize); + + switch (direction) { + case HUD_DIR_RIGHT_LEFT: + steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding); + break; + case HUD_DIR_TOP_BOTTOM: + steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen); + break; + case HUD_DIR_BOTTOM_TOP: + steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen)); + break; + default: + steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding); + break; + } + + drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem ); + } } @@ -227,7 +228,7 @@ void Hud::drawLuaElements() { if (!e) continue; - v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y); + v2s32 pos(e->pos.X * m_screensize.X, e->pos.Y * m_screensize.Y); switch (e->type) { case HUD_ELEM_IMAGE: { video::ITexture *texture = tsrc->getTexture(e->text); @@ -240,9 +241,9 @@ void Hud::drawLuaElements() { v2s32 dstsize(imgsize.Width * e->scale.X, imgsize.Height * e->scale.Y); if (e->scale.X < 0) - dstsize.X = screensize.X * (e->scale.X * -0.01); + dstsize.X = m_screensize.X * (e->scale.X * -0.01); if (e->scale.Y < 0) - dstsize.Y = screensize.Y * (e->scale.Y * -0.01); + dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01); v2s32 offset((e->align.X - 1.0) * dstsize.X / 2, (e->align.Y - 1.0) * dstsize.Y / 2); core::rect rect(0, 0, dstsize.X, dstsize.Y); @@ -269,7 +270,7 @@ void Hud::drawLuaElements() { break; } case HUD_ELEM_INVENTORY: { InventoryList *inv = inventory->getList(e->text); - drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir); + drawItems(pos, e->number, 0, inv, e->item, e->dir); break; } case HUD_ELEM_WAYPOINT: { v3f p_pos = player->getPosition() / BS; @@ -284,8 +285,8 @@ void Hud::drawLuaElements() { break; f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : core::reciprocal(transformed_pos[3]); - pos.X = screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5); - pos.Y = screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5); + pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5); + pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5); video::SColor color(255, (e->number >> 16) & 0xFF, (e->number >> 8) & 0xFF, (e->number >> 0) & 0xFF); @@ -360,7 +361,10 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s } -void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s32 breath) { +void Hud::drawHotbar(s32 halfheartcount, u16 playeritem, s32 breath) { + + v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y); + InventoryList *mainlist = inventory->getList("main"); if (mainlist == NULL) { //silently ignore this we may not be initialized completely @@ -368,12 +372,27 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s } s32 hotbar_itemcount = player->hud_hotbar_itemcount; - s32 padding = hotbar_imagesize / 12; - s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2); - v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 3); - - if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) - drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0); + s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2); + v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3); + + if ( (float) width / (float) porting::getWindowSize().X <= + g_settings->getFloat("hud_hotbar_max_width")) { + if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) { + drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0); + } + } + else { + pos.X += width/4; + + v2s32 secondpos = pos; + pos = pos - v2s32(0, m_hotbar_imagesize + m_padding); + + if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) { + drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0); + drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0); + } + } + if (player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE) drawStatbar(pos - v2s32(0, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT, "heart.png", halfheartcount, v2s32(0, 0)); @@ -385,22 +404,23 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s void Hud::drawCrosshair() { if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) || - player->camera_mode == CAMERA_MODE_THIRD_FRONT) + (player->camera_mode == CAMERA_MODE_THIRD_FRONT)) { return; + } if (use_crosshair_image) { video::ITexture *crosshair = tsrc->getTexture("crosshair.png"); v2u32 size = crosshair->getOriginalSize(); - v2s32 lsize = v2s32(displaycenter.X - (size.X / 2), - displaycenter.Y - (size.Y / 2)); + v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2), + m_displaycenter.Y - (size.Y / 2)); driver->draw2DImage(crosshair, lsize, core::rect(0, 0, size.X, size.Y), 0, crosshair_argb, true); } else { - driver->draw2DLine(displaycenter - v2s32(10, 0), - displaycenter + v2s32(10, 0), crosshair_argb); - driver->draw2DLine(displaycenter - v2s32(0, 10), - displaycenter + v2s32(0, 10), crosshair_argb); + driver->draw2DLine(m_displaycenter - v2s32(10, 0), + m_displaycenter + v2s32(10, 0), crosshair_argb); + driver->draw2DLine(m_displaycenter - v2s32(0, 10), + m_displaycenter + v2s32(0, 10), crosshair_argb); } } @@ -415,12 +435,12 @@ void Hud::drawSelectionBoxes(std::vector &hilightboxes) { void Hud::resizeHotbar() { - if (screensize.Y <= 800) - hotbar_imagesize = 32; - else if (screensize.Y <= 1280) - hotbar_imagesize = 48; - else - hotbar_imagesize = 64; + if (m_screensize != porting::getWindowSize()) { + m_hotbar_imagesize = porting::getDisplayDensity() * HOTBAR_IMAGE_SIZE; + m_padding = m_hotbar_imagesize / 12; + m_screensize = porting::getWindowSize(); + m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2); + } } void drawItemStack(video::IVideoDriver *driver, diff --git a/src/hud.h b/src/hud.h index 1a24d0945..3897a850c 100644 --- a/src/hud.h +++ b/src/hud.h @@ -45,6 +45,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8 #define HUD_HOTBAR_ITEMCOUNT_MAX 23 + +#define HOTBAR_IMAGE_SIZE 48 + enum HudElementType { HUD_ELEM_IMAGE = 0, HUD_ELEM_TEXT = 1, @@ -105,10 +108,6 @@ public: Inventory *inventory; ITextureSource *tsrc; - v2u32 screensize; - v2s32 displaycenter; - s32 hotbar_imagesize; - video::SColor crosshair_argb; video::SColor selectionbox_argb; bool use_crosshair_image; @@ -122,17 +121,25 @@ public: u32 text_height, IGameDef *gamedef, LocalPlayer *player, Inventory *inventory); - void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount, - InventoryList *mainlist, u16 selectitem, u16 direction); + void drawHotbar(s32 halfheartcount, u16 playeritem, s32 breath); + void resizeHotbar(); + void drawCrosshair(); + void drawSelectionBoxes(std::vector &hilightboxes); void drawLuaElements(); +private: void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count, v2s32 offset); - void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s32 breath); - void resizeHotbar(); + void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset, + InventoryList *mainlist, u16 selectitem, u16 direction); + + void drawItem(const ItemStack &item, const core::rect& rect, bool selected); - void drawCrosshair(); - void drawSelectionBoxes(std::vector &hilightboxes); + v2u32 m_screensize; + v2s32 m_displaycenter; + s32 m_hotbar_imagesize; + s32 m_padding; + video::SColor hbar_colors[4]; }; void drawItemStack(video::IVideoDriver *driver, diff --git a/src/main.cpp b/src/main.cpp index ddd55d1a4..08e8c1ee2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1447,8 +1447,10 @@ int main(int argc, char *argv[]) device = createDeviceEx(params); - if (device == 0) + if (device == 0) { return 1; // could not create selected driver. + } + porting::initIrrlicht(device); /* Continue initialization diff --git a/src/porting.cpp b/src/porting.cpp index 53b3a3784..d1e3cdd70 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -44,6 +44,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "log.h" #include "util/string.h" +#include "main.h" +#include "settings.h" #include namespace porting @@ -470,8 +472,9 @@ void initializePaths() std::string static_sharedir = STATIC_SHAREDIR; if(static_sharedir != "" && static_sharedir != ".") trylist.push_back(static_sharedir); - trylist.push_back(bindir + "/../share/" + PROJECT_NAME); - trylist.push_back(bindir + "/.."); + trylist.push_back( + bindir + DIR_DELIM + ".." + DIR_DELIM + "share" + DIR_DELIM + PROJECT_NAME); + trylist.push_back(bindir + DIR_DELIM + ".."); for(std::list::const_iterator i = trylist.begin(); i != trylist.end(); i++) @@ -528,5 +531,40 @@ void initializePaths() #endif // RUN_IN_PLACE } +static irr::IrrlichtDevice* device; + +void initIrrlicht(irr::IrrlichtDevice * _device) { + device = _device; +} + +#ifndef SERVER +v2u32 getWindowSize() { + return device->getVideoDriver()->getScreenSize(); +} + + +float getDisplayDensity() { + float gui_scaling = g_settings->getFloat("gui_scaling"); + // using Y here feels like a bug, this needs to be discussed later! + if (getWindowSize().Y <= 800) { + return (2.0/3.0) * gui_scaling; + } + if (getWindowSize().Y <= 1280) { + return 1.0 * gui_scaling; + } + + return (4.0/3.0) * gui_scaling; +} + +v2u32 getDisplaySize() { + IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL); + + core::dimension2d deskres = nulldevice->getVideoModeList()->getDesktopResolution(); + nulldevice -> drop(); + + return deskres; +} +#endif + } //namespace porting diff --git a/src/porting.h b/src/porting.h index f19ff3a07..90bfa2502 100644 --- a/src/porting.h +++ b/src/porting.h @@ -28,12 +28,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif - #define _WIN32_WINNT 0x0501 // We need to do this before any other headers + #define _WIN32_WINNT 0x0501 // We need to do this before any other headers // because those might include sdkddkver.h which defines _WIN32_WINNT if not already set #endif #include +#include "irrlicht.h" #include "irrlichttypes.h" // u32 +#include "irrlichttypes_extrabloated.h" #include "debug.h" #include "constants.h" #include "gettime.h" @@ -178,6 +180,8 @@ bool threadSetPriority(threadid_t tid, int prio); */ std::string get_sysinfo(); +void initIrrlicht(irr::IrrlichtDevice * ); + /* Resolution is 10-20ms. Remember to check for overflows. @@ -318,6 +322,13 @@ inline u32 getTime(TimePrecision prec) inline void setThreadName(const char* name) {} #endif +#ifndef SERVER +float getDisplayDensity(); + +v2u32 getDisplaySize(); +v2u32 getWindowSize(); +#endif + } // namespace porting #endif // PORTING_HEADER diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index fbb70c389..5de1c77f0 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -1002,6 +1002,33 @@ int ModApiMainMenu::l_gettext(lua_State *L) return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_get_screen_info(lua_State *L) +{ + lua_newtable(L); + int top = lua_gettop(L); + lua_pushstring(L,"density"); + lua_pushnumber(L,porting::getDisplayDensity()); + lua_settable(L, top); + + lua_pushstring(L,"display_width"); + lua_pushnumber(L,porting::getDisplaySize().X); + lua_settable(L, top); + + lua_pushstring(L,"display_height"); + lua_pushnumber(L,porting::getDisplaySize().Y); + lua_settable(L, top); + + lua_pushstring(L,"window_width"); + lua_pushnumber(L,porting::getWindowSize().X); + lua_settable(L, top); + + lua_pushstring(L,"window_height"); + lua_pushnumber(L,porting::getWindowSize().Y); + lua_settable(L, top); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_do_async_callback(lua_State *L) { @@ -1060,6 +1087,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(sound_play); API_FCT(sound_stop); API_FCT(gettext); + API_FCT(get_screen_info); API_FCT(do_async_callback); } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 69011c7b5..b711f2f86 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -103,6 +103,8 @@ private: static int l_update_formspec(lua_State *L); + static int l_get_screen_info(lua_State *L); + //filesystem static int l_get_scriptdir(lua_State *L); -- 2.25.1