Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minetest.get_player_window_information() #12367

Merged
merged 14 commits into from
Feb 27, 2023
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 @@ -4972,6 +4972,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 @@ -4988,6 +4989,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.
--
-- This is usually the window size, but may be smaller in certain situations,
-- such as side-by-side mode.
size = {
x = 1308,
y = 577,
},
rubenwardy marked this conversation as resolved.
Show resolved Hide resolved

-- 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
46 changes: 36 additions & 10 deletions doc/menu_lua_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,43 @@ 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_screen_info()`: DEPRECATED, use below 2 functions instead.
rubenwardy marked this conversation as resolved.
Show resolved Hide resolved
* `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 @@ -1381,6 +1381,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*4);
rubenwardy marked this conversation as resolved.
Show resolved Hide resolved
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>

#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
Expand Down Expand Up @@ -250,6 +251,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 @@ -1191,31 +1196,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;
sfan5 marked this conversation as resolved.
Show resolved Hide resolved
}

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 @@ -2587,6 +2605,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
32 changes: 32 additions & 0 deletions src/clientdynamicinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once
rubenwardy marked this conversation as resolved.
Show resolved Hide resolved

#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) {
rubenwardy marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -1061,7 +1061,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
1 change: 1 addition & 0 deletions src/network/serveropcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] =
{ "TOSERVER_FIRST_SRP", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_FirstSrp }, // 0x50
{ "TOSERVER_SRP_BYTES_A", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_SrpBytesA }, // 0x51
{ "TOSERVER_SRP_BYTES_M", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_SrpBytesM }, // 0x52
{ "TOSERVER_UPDATE_CLIENT_INFO", TOSERVER_STATE_INGAME, &Server::handleCommand_UpdateClientInfo }, // 0x53
};

const static ClientCommandFactory null_command_factory = { "TOCLIENT_NULL", 0, false };
Expand Down
Loading