Skip to content

Commit

Permalink
Add bold, italic and monospace font styling for HUD text elements (#1…
Browse files Browse the repository at this point in the history
…1478)

Co-authored-by: Elias Fleckenstein <eliasfleckenstein@web.de>
  • Loading branch information
sfan5 and LizzyFleckenstein03 committed Jul 27, 2021
1 parent cf13691 commit 6e8aebf
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 24 deletions.
2 changes: 2 additions & 0 deletions doc/client_lua_api.txt
Expand Up @@ -1314,6 +1314,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
-- ^ See "HUD Element Types"
size = { x=100, y=100 }, -- default {x=0, y=0}
-- ^ Size of element in pixels
style = 0,
-- ^ For "text" elements sets font style: bitfield with 1 = bold, 2 = italic, 4 = monospace
}
```

Expand Down
3 changes: 3 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -8447,6 +8447,9 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`.

z_index = 0,
-- Z index : lower z-index HUDs are displayed behind higher z-index HUDs

style = 0,
-- For "text" elements sets font style: bitfield with 1 = bold, 2 = italic, 4 = monospace
}

Particle definition
Expand Down
81 changes: 81 additions & 0 deletions games/devtest/mods/testhud/init.lua
@@ -0,0 +1,81 @@
local player_huds = {}

local states = {
{0, "Normal font"},
{1, "Bold font"},
{2, "Italic font"},
{3, "Bold and italic font"},
{4, "Monospace font"},
{5, "Bold and monospace font"},
{7, "ZOMG all the font styles"},
}


local default_def = {
hud_elem_type = "text",
position = {x = 0.5, y = 0.5},
scale = {x = 2, y = 2},
alignment = { x = 0, y = 0 },
}

local function add_hud(player, state)
local def = table.copy(default_def)
local statetbl = states[state]
def.offset = {x = 0, y = 32 * state}
def.style = statetbl[1]
def.text = statetbl[2]
return player:hud_add(def)
end

minetest.register_on_leaveplayer(function(player)
player_huds[player:get_player_name()] = nil
end)

local etime = 0
local state = 0

minetest.register_globalstep(function(dtime)
etime = etime + dtime
if etime < 1 then
return
end
etime = 0
for _, player in ipairs(minetest.get_connected_players()) do
local huds = player_huds[player:get_player_name()]
if huds then
for i, hud_id in ipairs(huds) do
local statetbl = states[(state + i) % #states + 1]
player:hud_change(hud_id, "style", statetbl[1])
player:hud_change(hud_id, "text", statetbl[2])
end
end
end
state = state + 1
end)

minetest.register_chatcommand("hudfonts", {
params = "",
description = "Show/Hide some text on the HUD with various font options",
func = function(name, param)
local player = minetest.get_player_by_name(name)
local param = tonumber(param) or 0
param = math.min(math.max(param, 1), #states)
if player_huds[name] == nil then
player_huds[name] = {}
for i = 1, param do
table.insert(player_huds[name], add_hud(player, i))
end
minetest.chat_send_player(name, ("%d HUD element(s) added."):format(param))
else
local huds = player_huds[name]
if huds then
for _, hud_id in ipairs(huds) do
player:hud_remove(hud_id)
end
minetest.chat_send_player(name, "All HUD elements removed.")
end
player_huds[name] = nil
end
return true
end,
})
2 changes: 2 additions & 0 deletions games/devtest/mods/testhud/mod.conf
@@ -0,0 +1,2 @@
name = testhud
description = For testing HUD functionality
2 changes: 1 addition & 1 deletion src/client/clientevent.h
Expand Up @@ -59,7 +59,7 @@ struct ClientEventHudAdd
v2f pos, scale;
std::string name;
std::string text, text2;
u32 number, item, dir;
u32 number, item, dir, style;
v2f align, offset;
v3f world_pos;
v2s32 size;
Expand Down
3 changes: 3 additions & 0 deletions src/client/game.cpp
Expand Up @@ -2730,6 +2730,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
e->size = event->hudadd->size;
e->z_index = event->hudadd->z_index;
e->text2 = event->hudadd->text2;
e->style = event->hudadd->style;
m_hud_server_to_client[server_id] = player->addHud(e);

delete event->hudadd;
Expand Down Expand Up @@ -2795,6 +2796,8 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca
CASE_SET(HUD_STAT_Z_INDEX, z_index, data);

CASE_SET(HUD_STAT_TEXT2, text2, sdata);

CASE_SET(HUD_STAT_STYLE, style, data);
}

#undef CASE_SET
Expand Down
30 changes: 13 additions & 17 deletions src/client/hud.cpp
Expand Up @@ -331,8 +331,8 @@ bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *p

void Hud::drawLuaElements(const v3s16 &camera_offset)
{
u32 text_height = g_fontengine->getTextHeight();
irr::gui::IGUIFont* font = g_fontengine->getFont();
const u32 text_height = g_fontengine->getTextHeight();
gui::IGUIFont *const font = g_fontengine->getFont();

// Reorder elements by z_index
std::vector<HudElement*> elems;
Expand All @@ -356,38 +356,34 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
floor(e->pos.Y * (float) m_screensize.Y + 0.5));
switch (e->type) {
case HUD_ELEM_TEXT: {
irr::gui::IGUIFont *textfont = font;
unsigned int font_size = g_fontengine->getDefaultFontSize();

if (e->size.X > 0)
font_size *= e->size.X;

if (font_size != g_fontengine->getDefaultFontSize())
textfont = g_fontengine->getFont(font_size);
#ifdef __ANDROID__
// The text size on Android is not proportional with the actual scaling
// FIXME: why do we have such a weird unportable hack??
if (font_size > 3 && e->offset.X < -20)
font_size -= 3;
#endif
auto textfont = g_fontengine->getFont(FontSpec(font_size,
(e->style & HUD_STYLE_MONO) ? FM_Mono : FM_Unspecified,
e->style & HUD_STYLE_BOLD, e->style & HUD_STYLE_ITALIC));

video::SColor color(255, (e->number >> 16) & 0xFF,
(e->number >> 8) & 0xFF,
(e->number >> 0) & 0xFF);
std::wstring text = unescape_translate(utf8_to_wide(e->text));
core::dimension2d<u32> textsize = textfont->getDimension(text.c_str());
#ifdef __ANDROID__
// The text size on Android is not proportional with the actual scaling
irr::gui::IGUIFont *font_scaled = font_size <= 3 ?
textfont : g_fontengine->getFont(font_size - 3);
if (e->offset.X < -20)
textsize = font_scaled->getDimension(text.c_str());
#endif

v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
(e->align.Y - 1.0) * (textsize.Height / 2));
core::rect<s32> size(0, 0, e->scale.X * m_scale_factor,
text_height * e->scale.Y * m_scale_factor);
v2s32 offs(e->offset.X * m_scale_factor,
e->offset.Y * m_scale_factor);
#ifdef __ANDROID__
if (e->offset.X < -20)
font_scaled->draw(text.c_str(), size + pos + offset + offs, color);
else
#endif

{
textfont->draw(text.c_str(), size + pos + offset + offs, color);
}
Expand Down
1 change: 1 addition & 0 deletions src/hud.cpp
Expand Up @@ -50,6 +50,7 @@ const struct EnumString es_HudElementStat[] =
{HUD_STAT_SIZE, "size"},
{HUD_STAT_Z_INDEX, "z_index"},
{HUD_STAT_TEXT2, "text2"},
{HUD_STAT_STYLE, "style"},
{0, NULL},
};

Expand Down
6 changes: 6 additions & 0 deletions src/hud.h
Expand Up @@ -33,6 +33,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define HUD_CORNER_LOWER 1
#define HUD_CORNER_CENTER 2

#define HUD_STYLE_BOLD 1
#define HUD_STYLE_ITALIC 2
#define HUD_STYLE_MONO 4

// Note that these visibility flags do not determine if the hud items are
// actually drawn, but rather, whether to draw the item should the rest
// of the game state permit it.
Expand Down Expand Up @@ -78,6 +82,7 @@ enum HudElementStat {
HUD_STAT_SIZE,
HUD_STAT_Z_INDEX,
HUD_STAT_TEXT2,
HUD_STAT_STYLE,
};

enum HudCompassDir {
Expand All @@ -102,6 +107,7 @@ struct HudElement {
v2s32 size;
s16 z_index = 0;
std::string text2;
u32 style;
};

extern const EnumString es_HudElementType[];
Expand Down
5 changes: 4 additions & 1 deletion src/network/clientpackethandler.cpp
Expand Up @@ -1061,6 +1061,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
v2s32 size;
s16 z_index = 0;
std::string text2;
u32 style = 0;

*pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item
>> dir >> align >> offset;
Expand All @@ -1069,6 +1070,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
*pkt >> size;
*pkt >> z_index;
*pkt >> text2;
*pkt >> style;
} catch(PacketError &e) {};

ClientEvent *event = new ClientEvent();
Expand All @@ -1089,6 +1091,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
event->hudadd->size = size;
event->hudadd->z_index = z_index;
event->hudadd->text2 = text2;
event->hudadd->style = style;
m_client_event_queue.push(event);
}

Expand Down Expand Up @@ -1123,7 +1126,7 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
*pkt >> sdata;
else if (stat == HUD_STAT_WORLD_POS)
*pkt >> v3fdata;
else if (stat == HUD_STAT_SIZE )
else if (stat == HUD_STAT_SIZE)
*pkt >> v2s32data;
else
*pkt >> intdata;
Expand Down
9 changes: 9 additions & 0 deletions src/script/common/c_content.cpp
Expand Up @@ -1928,6 +1928,8 @@ void read_hud_element(lua_State *L, HudElement *elem)
elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
lua_pop(L, 1);

elem->style = getintfield_default(L, 2, "style", 0);

/* check for known deprecated element usage */
if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32()))
log_deprecated(L,"Deprecated usage of statbar without size!");
Expand Down Expand Up @@ -1982,6 +1984,9 @@ void push_hud_element(lua_State *L, HudElement *elem)

lua_pushstring(L, elem->text2.c_str());
lua_setfield(L, -2, "text2");

lua_pushinteger(L, elem->style);
lua_setfield(L, -2, "style");
}

HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
Expand Down Expand Up @@ -2050,6 +2055,10 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
elem->text2 = luaL_checkstring(L, 4);
*value = &elem->text2;
break;
case HUD_STAT_STYLE:
elem->style = luaL_checknumber(L, 4);
*value = &elem->style;
break;
}
return stat;
}
Expand Down
7 changes: 2 additions & 5 deletions src/server.cpp
Expand Up @@ -1638,7 +1638,7 @@ void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form)
pkt << id << (u8) form->type << form->pos << form->name << form->scale
<< form->text << form->number << form->item << form->dir
<< form->align << form->offset << form->world_pos << form->size
<< form->z_index << form->text2;
<< form->z_index << form->text2 << form->style;

Send(&pkt);
}
Expand Down Expand Up @@ -1673,10 +1673,7 @@ void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void
case HUD_STAT_SIZE:
pkt << *(v2s32 *) value;
break;
case HUD_STAT_NUMBER:
case HUD_STAT_ITEM:
case HUD_STAT_DIR:
default:
default: // all other types
pkt << *(u32 *) value;
break;
}
Expand Down

0 comments on commit 6e8aebf

Please sign in to comment.