Skip to content

Commit

Permalink
Add minetest.get_player_window_information() (luanti-org#12367)
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenwardy authored and appgurueu committed May 2, 2023
1 parent ecd881e commit 3609fe0
Show file tree
Hide file tree
Showing 23 changed files with 345 additions and 35 deletions.
2 changes: 1 addition & 1 deletion builtin/mainmenu/tab_about.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ return {
fs = fs .. "style[label_button2;border=false]" ..
"button[0.1,6;5.3,1;label_button2;" ..
fgettext("Active renderer:") .. "\n" ..
core.formspec_escape(core.get_screen_info().render_info) .. "]"
core.formspec_escape(core.get_active_renderer()) .. "]"

if PLATFORM == "Android" then
fs = fs .. "button[0.5,5.1;4.5,0.8;share_debug;" .. fgettext("Share debug log") .. "]"
Expand Down
37 changes: 37 additions & 0 deletions doc/lua_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4975,6 +4975,7 @@ Utilities
protocol_version = 32, -- protocol version used by client
formspec_version = 2, -- supported formspec version
lang_code = "fr" -- Language code used for translation

-- the following keys can be missing if no stats have been collected yet
min_rtt = 0.01, -- minimum round trip time
max_rtt = 0.2, -- maximum round trip time
Expand All @@ -4991,6 +4992,42 @@ Utilities
--vers_string = "0.4.9-git", -- full version string
--state = "Active" -- current client state
}
* `minetest.get_player_window_information(player_name)`:

-- Will only be present if the client sent this information (requires v5.7+)
--
-- Note that none of these things are constant, they are likely to change during a client
-- connection as the player resizes the window and moves it between monitors
--
-- real_gui_scaling and real_hud_scaling can be used instead of DPI.
-- OSes don't necessarily give the physical DPI, as they may allow user configuration.
-- real_*_scaling is just OS DPI / 96 but with another level of user configuration.
{
-- Current size of the in-game render target (pixels).
--
-- This is usually the window size, but may be smaller in certain situations,
-- such as side-by-side mode.
size = {
x = 1308,
y = 577,
},

-- Estimated maximum formspec size before Minetest will start shrinking the
-- formspec to fit. For a fullscreen formspec, use a size 10-20% larger than
-- this and `padding[-0.01,-0.01]`.
max_formspec_size = {
x = 20,
y = 11.25
},

-- GUI Scaling multiplier
-- Equal to the setting `gui_scaling` multiplied by `dpi / 96`
real_gui_scaling = 1,

-- HUD Scaling multiplier
-- Equal to the setting `hud_scaling` multiplied by `dpi / 96`
real_hud_scaling = 1,
}

* `minetest.mkdir(path)`: returns success.
* Creates a directory specified by `path`, creating parent directories
Expand Down
45 changes: 35 additions & 10 deletions doc/menu_lua_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,42 @@ GUI
will be added to fieldname value is set to formname itself
* if `is_file_select` is `true`, a file and not a folder will be selected
* returns nil or selected file/folder
* `core.get_screen_info()`
* returns
* `core.get_active_renderer()`: Ex: "OpenGL 4.6".
* `core.get_window_info()`: Same as server-side `get_player_window_information` API.

-- Note that none of these things are constant, they are likely to change
-- as the player resizes the window and moves it between monitors
--
-- real_gui_scaling and real_hud_scaling can be used instead of DPI.
-- OSes don't necessarily give the physical DPI, as they may allow user configuration.
-- real_*_scaling is just OS DPI / 96 but with another level of user configuration.
{
-- Current size of the in-game render target.
--
-- This is usually the window size, but may be smaller in certain situations,
-- such as side-by-side mode.
size = {
x = 1308,
y = 577,
},

-- Estimated maximum formspec size before Minetest will start shrinking the
-- formspec to fit. For a fullscreen formspec, use a size 10-20% larger than
-- this and `padding[-0.01,-0.01]`.
max_formspec_size = {
x = 20,
y = 11.25
},

-- GUI Scaling multiplier
-- Equal to the setting `gui_scaling` multiplied by `dpi / 96`
real_gui_scaling = 1,

-- HUD Scaling multiplier
-- Equal to the setting `hud_scaling` multiplied by `dpi / 96`
real_hud_scaling = 1,
}

{
density = <screen density 0.75,1.0,2.0,3.0 ... (dpi)>,
display_width = <width of display>,
display_height = <height of display>,
window_width = <current window width>,
window_height = <current window height>,
render_info = <active render information>
}


Content and Packages
Expand Down
29 changes: 29 additions & 0 deletions games/devtest/mods/testfullscreenfs/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local function show_fullscreen_fs(name)
local window = minetest.get_player_window_information(name)
if not window then
return false, "Unable to get window info"
end

print(dump(window))

local size = { x = window.max_formspec_size.x * 1.1, y = window.max_formspec_size.y * 1.1 }
local fs = {
"formspec_version[4]",
("size[%f,%f]"):format(size.x, size.y),
"padding[-0.01,-0.01]",
("button[%f,%f;1,1;%s;%s]"):format(0, 0, "tl", "TL"),
("button[%f,%f;1,1;%s;%s]"):format(size.x - 1, 0, "tr", "TR"),
("button[%f,%f;1,1;%s;%s]"):format(size.x - 1, size.y - 1, "br", "BR"),
("button[%f,%f;1,1;%s;%s]"):format(0, size.y - 1, "bl", "BL"),

("label[%f,%f;%s]"):format(size.x / 2, size.y / 2, "Fullscreen")
}

minetest.show_formspec(name, "testfullscreenfs:fs", table.concat(fs))
return true, ("Calculated size of %f, %f"):format(size.x, size.y)
end


minetest.register_chatcommand("testfullscreenfs", {
func = show_fullscreen_fs,
})
2 changes: 2 additions & 0 deletions games/devtest/mods/testfullscreenfs/mod.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = testfullscreenfs
description = Test mod to use minetest.get_player_window_information()
11 changes: 11 additions & 0 deletions src/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,17 @@ void Client::sendHaveMedia(const std::vector<u32> &tokens)
Send(&pkt);
}

void Client::sendUpdateClientInfo(const ClientDynamicInfo& info)
{
NetworkPacket pkt(TOSERVER_UPDATE_CLIENT_INFO, 4*2 + 4 + 4 + 4*2);
pkt << (u32)info.render_target_size.X << (u32)info.render_target_size.Y;
pkt << info.real_gui_scaling;
pkt << info.real_hud_scaling;
pkt << (f32)info.max_fs_size.X << (f32)info.max_fs_size.Y;

Send(&pkt);
}

void Client::removeNode(v3s16 p)
{
std::map<v3s16, MapBlock*> modified_blocks;
Expand Down
2 changes: 2 additions & 0 deletions src/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "network/address.h"
#include "network/peerhandler.h"
#include "gameparams.h"
#include "clientdynamicinfo.h"
#include <fstream>
#include "util/numeric.h"

Expand Down Expand Up @@ -251,6 +252,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
void sendRespawn();
void sendReady();
void sendHaveMedia(const std::vector<u32> &tokens);
void sendUpdateClientInfo(const ClientDynamicInfo &info);

ClientEnvironment& getEnv() { return m_env; }
ITextureSource *tsrc() { return getTextureSource(); }
Expand Down
51 changes: 41 additions & 10 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "version.h"
#include "script/scripting_client.h"
#include "hud.h"
#include "clientdynamicinfo.h"

#if USE_SOUND
#include "client/sound_openal.h"
Expand Down Expand Up @@ -917,12 +918,16 @@ class Game {
static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];

f32 getSensitivityScaleFactor() const;
ClientDynamicInfo getCurrentDynamicInfo() const;

InputHandler *input = nullptr;

Client *client = nullptr;
Server *server = nullptr;

ClientDynamicInfo client_display_info{};
float dynamic_info_send_timer = 0;

IWritableTextureSource *texture_src = nullptr;
IWritableShaderSource *shader_src = nullptr;

Expand Down Expand Up @@ -1187,31 +1192,44 @@ void Game::run()
&& client->checkPrivilege("fast");
#endif

irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"),
v2u32 previous_screen_size(g_settings->getU16("screen_w"),
g_settings->getU16("screen_h"));

while (m_rendering_engine->run()
&& !(*kill || g_gamecallback->shutdown_requested
|| (server && server->isShutdownRequested()))) {

const irr::core::dimension2d<u32> &current_screen_size =
m_rendering_engine->get_video_driver()->getScreenSize();
// Calculate dtime =
// m_rendering_engine->run() from this iteration
// + Sleep time until the wanted FPS are reached
draw_times.limit(device, &dtime);

const auto current_dynamic_info = getCurrentDynamicInfo();
if (!current_dynamic_info.equal(client_display_info)) {
client_display_info = current_dynamic_info;
dynamic_info_send_timer = 0.2f;
}

if (dynamic_info_send_timer > 0) {
dynamic_info_send_timer -= dtime;
if (dynamic_info_send_timer <= 0) {
client->sendUpdateClientInfo(current_dynamic_info);
}
}

const auto &current_screen_size = current_dynamic_info.render_target_size;

// Verify if window size has changed and save it if it's the case
// Ensure evaluating settings->getBool after verifying screensize
// First condition is cheaper
if (previous_screen_size != current_screen_size &&
current_screen_size != irr::core::dimension2d<u32>(0,0) &&
g_settings->getBool("autosave_screensize")) {
g_settings->setU16("screen_w", current_screen_size.Width);
g_settings->setU16("screen_h", current_screen_size.Height);
g_settings->setU16("screen_w", current_screen_size.X);
g_settings->setU16("screen_h", current_screen_size.Y);
previous_screen_size = current_screen_size;
}

// Calculate dtime =
// m_rendering_engine->run() from this iteration
// + Sleep time until the wanted FPS are reached
draw_times.limit(device, &dtime);

// Prepare render data for next iteration

updateStats(&stats, draw_times, dtime);
Expand Down Expand Up @@ -2583,6 +2601,19 @@ f32 Game::getSensitivityScaleFactor() const
return tan(fov_y / 2.0f) * 1.3763818698f;
}

ClientDynamicInfo Game::getCurrentDynamicInfo() const
{
v2u32 screen_size = RenderingEngine::getWindowSize();
f32 density = RenderingEngine::getDisplayDensity();
f32 gui_scaling = g_settings->getFloat("gui_scaling") * density;
f32 hud_scaling = g_settings->getFloat("hud_scaling") * density;

return {
screen_size, gui_scaling, hud_scaling,
ClientDynamicInfo::calculateMaxFSSize(screen_size)
};
}

void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
{
#ifdef HAVE_TOUCHSCREENGUI
Expand Down
6 changes: 6 additions & 0 deletions src/client/renderingengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ class RenderingEngine

void removeMesh(const scene::IMesh* mesh);

/**
* This takes 3d_mode into account - side-by-side will return a
* halved horizontal size.
*
* @return "window" size
*/
static v2u32 getWindowSize()
{
sanity_check(s_singleton);
Expand Down
51 changes: 51 additions & 0 deletions src/clientdynamicinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Minetest
Copyright (C) 2022-3 rubenwardy <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include "irrTypes.h"


struct ClientDynamicInfo
{
v2u32 render_target_size;
f32 real_gui_scaling;
f32 real_hud_scaling;
v2f32 max_fs_size;

bool equal(const ClientDynamicInfo &other) const {
return render_target_size == other.render_target_size &&
abs(real_gui_scaling - other.real_gui_scaling) < 0.001f &&
abs(real_hud_scaling - other.real_hud_scaling) < 0.001f;
}

static v2f32 calculateMaxFSSize(v2u32 render_target_size) {
f32 factor =
#ifdef HAVE_TOUCHSCREENGUI
10;
#else
15;
#endif
f32 ratio = (f32)render_target_size.X / (f32)render_target_size.Y;
if (ratio < 1)
return { factor, factor / ratio };
else
return { factor * ratio, factor };
}
};
9 changes: 8 additions & 1 deletion src/clientiface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "network/address.h"
#include "porting.h"
#include "threading/mutex_auto_lock.h"
#include "clientdynamicinfo.h"

#include <list>
#include <vector>
Expand Down Expand Up @@ -350,6 +351,9 @@ class RemoteClient
void setCachedAddress(const Address &addr) { m_addr = addr; }
const Address &getAddress() const { return m_addr; }

void setDynamicInfo(const ClientDynamicInfo &info) { m_dynamic_info = info; }
const ClientDynamicInfo &getDynamicInfo() const { return m_dynamic_info; }

private:
// Version is stored in here after INIT before INIT2
u8 m_pending_serialization_version = SER_FMT_VER_INVALID;
Expand All @@ -360,9 +364,12 @@ class RemoteClient
// Cached here so retrieval doesn't have to go to connection API
Address m_addr;

// Client sent language code
// Client-sent language code
std::string m_lang_code;

// Client-sent dynamic info
ClientDynamicInfo m_dynamic_info{};

/*
Blocks that have been sent to client.
- These don't have to be sent again.
Expand Down
1 change: 1 addition & 0 deletions src/network/clientopcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,5 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] =
{ "TOSERVER_FIRST_SRP", 1, true }, // 0x50
{ "TOSERVER_SRP_BYTES_A", 1, true }, // 0x51
{ "TOSERVER_SRP_BYTES_M", 1, true }, // 0x52
{ "TOSERVER_UPDATE_CLIENT_INFO", 1, true }, // 0x53
};
10 changes: 9 additions & 1 deletion src/network/networkprotocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,15 @@ enum ToServerCommand
std::string bytes_M
*/

TOSERVER_NUM_MSG_TYPES = 0x53,
TOSERVER_UPDATE_CLIENT_INFO = 0x53,
/*
v2s16 render_target_size
f32 gui_scaling
f32 hud_scaling
v2f32 max_fs_info
*/

TOSERVER_NUM_MSG_TYPES = 0x54,
};

enum AuthMechanism
Expand Down
Loading

0 comments on commit 3609fe0

Please sign in to comment.