Merge remote-tracking branch 'minetest/master'

master
Brandon 2017-07-01 12:11:57 -05:00
commit b41251ac77
220 changed files with 3350 additions and 3480 deletions

View File

@ -3,6 +3,7 @@ before_install: ./util/travis/before_install.sh
script: ./util/travis/script.sh script: ./util/travis/script.sh
sudo: required sudo: required
dist: trusty dist: trusty
group: edge
notifications: notifications:
email: false email: false
matrix: matrix:

View File

@ -138,7 +138,6 @@ LOCAL_SRC_FILES := \
jni/src/database.cpp \ jni/src/database.cpp \
jni/src/debug.cpp \ jni/src/debug.cpp \
jni/src/defaultsettings.cpp \ jni/src/defaultsettings.cpp \
jni/src/drawscene.cpp \
jni/src/dungeongen.cpp \ jni/src/dungeongen.cpp \
jni/src/emerge.cpp \ jni/src/emerge.cpp \
jni/src/environment.cpp \ jni/src/environment.cpp \
@ -270,6 +269,7 @@ LOCAL_SRC_FILES := \
jni/src/wieldmesh.cpp \ jni/src/wieldmesh.cpp \
jni/src/client/clientlauncher.cpp \ jni/src/client/clientlauncher.cpp \
jni/src/client/inputhandler.cpp \ jni/src/client/inputhandler.cpp \
jni/src/client/renderingengine.cpp \
jni/src/client/tile.cpp \ jni/src/client/tile.cpp \
jni/src/client/joystick_controller.cpp \ jni/src/client/joystick_controller.cpp \
jni/src/irrlicht_changes/static_text.cpp jni/src/irrlicht_changes/static_text.cpp

View File

@ -1,5 +1,5 @@
-- Minetest: builtin/client/init.lua -- Minetest: builtin/client/init.lua
local scriptpath = core.get_builtin_path()..DIR_DELIM local scriptpath = core.get_builtin_path()
local clientpath = scriptpath.."client"..DIR_DELIM local clientpath = scriptpath.."client"..DIR_DELIM
local commonpath = scriptpath.."common"..DIR_DELIM local commonpath = scriptpath.."common"..DIR_DELIM

View File

@ -511,6 +511,12 @@ function core.explode_scrollbar_event(evt)
return retval return retval
end end
--------------------------------------------------------------------------------
function core.rgba(r, g, b, a)
return a and string.format("#%02X%02X%02X%02X", r, g, b, a) or
string.format("#%02X%02X%02X", r, g, b)
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function core.pos_to_string(pos, decimal_places) function core.pos_to_string(pos, decimal_places)
local x = pos.x local x = pos.x

View File

@ -93,7 +93,7 @@ core.register_entity(":__builtin:falling_node", {
core.remove_node(np) core.remove_node(np)
if nd and nd.buildable_to == false then if nd and nd.buildable_to == false then
-- Add dropped items -- Add dropped items
local drops = core.get_node_drops(n2.name, "") local drops = core.get_node_drops(n2, "")
for _, dropped_item in pairs(drops) do for _, dropped_item in pairs(drops) do
core.add_item(np, dropped_item) core.add_item(np, dropped_item)
end end
@ -145,9 +145,9 @@ function core.spawn_falling_node(pos)
end end
local function drop_attached_node(p) local function drop_attached_node(p)
local nn = core.get_node(p).name local n = core.get_node(p)
core.remove_node(p) core.remove_node(p)
for _, item in pairs(core.get_node_drops(nn, "")) do for _, item in pairs(core.get_node_drops(n, "")) do
local pos = { local pos = {
x = p.x + math.random()/2 - 0.25, x = p.x + math.random()/2 - 0.25,
y = p.y + math.random()/2 - 0.25, y = p.y + math.random()/2 - 0.25,

View File

@ -1,5 +1,5 @@
local scriptpath = core.get_builtin_path()..DIR_DELIM local scriptpath = core.get_builtin_path()
local commonpath = scriptpath.."common"..DIR_DELIM local commonpath = scriptpath.."common"..DIR_DELIM
local gamepath = scriptpath.."game"..DIR_DELIM local gamepath = scriptpath.."game"..DIR_DELIM

View File

@ -155,12 +155,35 @@ function core.yaw_to_dir(yaw)
return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)} return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
end end
function core.get_node_drops(nodename, toolname) function core.get_node_drops(node, toolname)
-- Compatibility, if node is string
local nodename = node
local param2 = 0
-- New format, if node is table
if (type(node) == "table") then
nodename = node.name
param2 = node.param2
end
local def = core.registered_nodes[nodename] local def = core.registered_nodes[nodename]
local drop = def and def.drop local drop = def and def.drop
if drop == nil then if drop == nil then
-- default drop -- default drop
return {nodename} local stack = ItemStack(nodename)
if def then
local type = def.paramtype2
if (type == "color") or (type == "colorfacedir") or
(type == "colorwallmounted") then
local meta = stack:get_meta()
local color_part = param2
if (type == "colorfacedir") then
color_part = math.floor(color_part / 32) * 32;
elseif (type == "colorwallmounted") then
color_part = math.floor(color_part / 8) * 8;
end
meta:set_int("palette_index", color_part)
end
end
return {stack:to_string()}
elseif type(drop) == "string" then elseif type(drop) == "string" then
-- itemstring drop -- itemstring drop
return {drop} return {drop}
@ -258,7 +281,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
.. def.name .. " at " .. core.pos_to_string(place_to)) .. def.name .. " at " .. core.pos_to_string(place_to))
local oldnode = core.get_node(place_to) local oldnode = core.get_node(place_to)
local newnode = {name = def.name, param1 = 0, param2 = param2} local newnode = {name = def.name, param1 = 0, param2 = param2 or 0}
-- Calculate direction for wall mounted stuff like torches and signs -- Calculate direction for wall mounted stuff like torches and signs
if def.place_param2 ~= nil then if def.place_param2 ~= nil then
@ -286,6 +309,25 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
end end
end end
local metatable = itemstack:get_meta():to_table().fields
-- Transfer color information
if metatable.palette_index and not def.place_param2 then
local color_divisor = nil
if def.paramtype2 == "color" then
color_divisor = 1
elseif def.paramtype2 == "colorwallmounted" then
color_divisor = 8
elseif def.paramtype2 == "colorfacedir" then
color_divisor = 32
end
if color_divisor then
local color = math.floor(metatable.palette_index / color_divisor)
local other = newnode.param2 % color_divisor
newnode.param2 = color * color_divisor + other
end
end
-- Check if the node is attached and if it can be placed there -- Check if the node is attached and if it can be placed there
if core.get_item_group(def.name, "attached_node") ~= 0 and if core.get_item_group(def.name, "attached_node") ~= 0 and
not builtin_shared.check_attached_node(place_to, newnode) then not builtin_shared.check_attached_node(place_to, newnode) then
@ -474,7 +516,7 @@ function core.node_dig(pos, node, digger)
.. node.name .. " at " .. core.pos_to_string(pos)) .. node.name .. " at " .. core.pos_to_string(pos))
local wielded = digger:get_wielded_item() local wielded = digger:get_wielded_item()
local drops = core.get_node_drops(node.name, wielded:get_name()) local drops = core.get_node_drops(node, wielded:get_name())
local wdef = wielded:get_definition() local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities() local tp = wielded:get_tool_capabilities()
@ -530,6 +572,18 @@ function core.node_dig(pos, node, digger)
end end
end end
function core.itemstring_with_palette(item, palette_index)
local stack = ItemStack(item) -- convert to ItemStack
stack:get_meta():set_int("palette_index", palette_index)
return stack:to_string()
end
function core.itemstring_with_color(item, colorstring)
local stack = ItemStack(item) -- convert to ItemStack
stack:get_meta():set_string("color", colorstring)
return stack:to_string()
end
-- This is used to allow mods to redefine core.item_place and so on -- This is used to allow mods to redefine core.item_place and so on
-- NOTE: This is not the preferred way. Preferred way is to provide enough -- NOTE: This is not the preferred way. Preferred way is to provide enough
-- callbacks to not require redefining global functions. -celeron55 -- callbacks to not require redefining global functions. -celeron55

View File

@ -25,7 +25,7 @@ os.setlocale("C", "numeric")
minetest = core minetest = core
-- Load other files -- Load other files
local scriptdir = core.get_builtin_path() .. DIR_DELIM local scriptdir = core.get_builtin_path()
local gamepath = scriptdir .. "game" .. DIR_DELIM local gamepath = scriptdir .. "game" .. DIR_DELIM
local clientpath = scriptdir .. "client" .. DIR_DELIM local clientpath = scriptdir .. "client" .. DIR_DELIM
local commonpath = scriptdir .. "common" .. DIR_DELIM local commonpath = scriptdir .. "common" .. DIR_DELIM

View File

@ -264,7 +264,7 @@ end
-- read_all: whether to ignore certain setting types for GUI or not -- read_all: whether to ignore certain setting types for GUI or not
-- parse_mods: whether to parse settingtypes.txt in mods and games -- parse_mods: whether to parse settingtypes.txt in mods and games
local function parse_config_file(read_all, parse_mods) local function parse_config_file(read_all, parse_mods)
local builtin_path = core.get_builtin_path() .. DIR_DELIM .. FILENAME local builtin_path = core.get_builtin_path() .. FILENAME
local file = io.open(builtin_path, "r") local file = io.open(builtin_path, "r")
local settings = {} local settings = {}
if not file then if not file then
@ -775,4 +775,4 @@ end
-- Generate minetest.conf.example and settings_translation_file.cpp -- Generate minetest.conf.example and settings_translation_file.cpp
--assert(loadfile(core.get_builtin_path()..DIR_DELIM.."mainmenu"..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false)) --assert(loadfile(core.get_builtin_path().."mainmenu"..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))

View File

@ -27,12 +27,12 @@ local basepath = core.get_builtin_path()
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" .. defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM DIR_DELIM .. "pack" .. DIR_DELIM
dofile(basepath .. DIR_DELIM .. "common" .. DIR_DELIM .. "async_event.lua") dofile(basepath .. "common" .. DIR_DELIM .. "async_event.lua")
dofile(basepath .. DIR_DELIM .. "common" .. DIR_DELIM .. "filterlist.lua") dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "buttonbar.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "dialog.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "tabview.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "tabview.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua")
dofile(menupath .. DIR_DELIM .. "common.lua") dofile(menupath .. DIR_DELIM .. "common.lua")
dofile(menupath .. DIR_DELIM .. "gamemgr.lua") dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
dofile(menupath .. DIR_DELIM .. "modmgr.lua") dofile(menupath .. DIR_DELIM .. "modmgr.lua")

View File

@ -295,6 +295,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
local first_server = search_result[1] local first_server = search_result[1]
core.settings:set("address", first_server.address) core.settings:set("address", first_server.address)
core.settings:set("remote_port", first_server.port) core.settings:set("remote_port", first_server.port)
gamedata.serverdescription = first_server.description
end end
return true return true
end end

View File

@ -23,7 +23,7 @@ local function get_bool_default(name, default)
return val return val
end end
local profiler_path = core.get_builtin_path()..DIR_DELIM.."profiler"..DIR_DELIM local profiler_path = core.get_builtin_path().."profiler"..DIR_DELIM
local profiler = {} local profiler = {}
local sampler = assert(loadfile(profiler_path .. "sampling.lua"))(profiler) local sampler = assert(loadfile(profiler_path .. "sampling.lua"))(profiler)
local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler, get_bool_default) local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler, get_bool_default)

View File

@ -469,6 +469,10 @@ enable_waving_plants (Waving plants) bool false
[***Advanced] [***Advanced]
# Arm inertia, gives a more realistic movement of
# the arm when the camera moves.
arm_inertia (Arm inertia) bool true
# If FPS would go higher than this, limit it by sleeping # If FPS would go higher than this, limit it by sleeping
# to not waste CPU power for no benefit. # to not waste CPU power for no benefit.
fps_max (Maximum FPS) int 60 fps_max (Maximum FPS) int 60
@ -1028,6 +1032,12 @@ mgv5_spflags (Mapgen v5 specific flags) flags caverns caverns,nocaverns
# Controls width of tunnels, a smaller value creates wider tunnels. # Controls width of tunnels, a smaller value creates wider tunnels.
mgv5_cave_width (Cave width) float 0.125 mgv5_cave_width (Cave width) float 0.125
# Y of upper limit of large caves.
mgv5_large_cave_depth (Large cave depth) int -256
# Y of upper limit of lava in large caves.
mgv5_lava_depth (Lava depth) int -256
# Y-level of cavern upper limit. # Y-level of cavern upper limit.
mgv5_cavern_limit (Cavern limit) int -256 mgv5_cavern_limit (Cavern limit) int -256
@ -1134,6 +1144,12 @@ mgv7_spflags (Mapgen v7 specific flags) flags mountains,ridges,nofloatlands,cave
# Controls width of tunnels, a smaller value creates wider tunnels. # Controls width of tunnels, a smaller value creates wider tunnels.
mgv7_cave_width (Cave width) float 0.09 mgv7_cave_width (Cave width) float 0.09
# Y of upper limit of large caves.
mgv7_large_cave_depth (Large cave depth) int -33
# Y of upper limit of lava in large caves.
mgv7_lava_depth (Lava depth) int -256
# Controls the density of floatland mountain terrain. # Controls the density of floatland mountain terrain.
# Is an offset added to the 'np_mountain' noise value. # Is an offset added to the 'np_mountain' noise value.
mgv7_float_mount_density (Floatland mountain density) float 0.6 mgv7_float_mount_density (Floatland mountain density) float 0.6
@ -1212,9 +1228,12 @@ mgflat_spflags (Mapgen flat specific flags) flags nolakes,nohills lakes,hills,no
# Y of flat ground. # Y of flat ground.
mgflat_ground_level (Ground level) int 8 mgflat_ground_level (Ground level) int 8
# Y of upper limit of large pseudorandom caves. # Y of upper limit of large caves.
mgflat_large_cave_depth (Large cave depth) int -33 mgflat_large_cave_depth (Large cave depth) int -33
# Y of upper limit of lava in large caves.
mgflat_lava_depth (Lava depth) int -256
# Controls width of tunnels, a smaller value creates wider tunnels. # Controls width of tunnels, a smaller value creates wider tunnels.
mgflat_cave_width (Cave width) float 0.09 mgflat_cave_width (Cave width) float 0.09
@ -1251,6 +1270,12 @@ mgflat_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2
# Controls width of tunnels, a smaller value creates wider tunnels. # Controls width of tunnels, a smaller value creates wider tunnels.
mgfractal_cave_width (Cave width) float 0.09 mgfractal_cave_width (Cave width) float 0.09
# Y of upper limit of large caves.
mgfractal_large_cave_depth (Large cave depth) int -33
# Y of upper limit of lava in large caves.
mgfractal_lava_depth (Lava depth) int -256
# Choice of 18 fractals from 9 formulas. # Choice of 18 fractals from 9 formulas.
# 1 = 4D "Roundy" mandelbrot set. # 1 = 4D "Roundy" mandelbrot set.
# 2 = 4D "Roundy" julia set. # 2 = 4D "Roundy" julia set.

View File

@ -0,0 +1,2 @@
print("Loaded example file!, loading more examples")
dofile("preview:examples/first.lua")

View File

@ -0,0 +1 @@
print("loaded first.lua example file")

View File

@ -1,6 +1,7 @@
local modname = core.get_current_modname() or "??" local modname = core.get_current_modname() or "??"
local modstorage = core.get_mod_storage() local modstorage = core.get_mod_storage()
dofile("preview:example.lua")
-- This is an example function to ensure it's working properly, should be removed before merge -- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_shutdown(function() core.register_on_shutdown(function()
print("[PREVIEW] shutdown client") print("[PREVIEW] shutdown client")

View File

@ -794,6 +794,10 @@ Call these functions only at load time!
* See documentation on `minetest.compress()` for supported compression methods. * See documentation on `minetest.compress()` for supported compression methods.
* currently supported. * currently supported.
* `...` indicates method-specific arguments. Currently, no methods use this. * `...` indicates method-specific arguments. Currently, no methods use this.
* `minetest.rgba(red, green, blue[, alpha])`: returns a string
* Each argument is a 8 Bit unsigned integer
* Returns the ColorString from rgb or rgba values
* Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"`
* `minetest.encode_base64(string)`: returns string encoded in base64 * `minetest.encode_base64(string)`: returns string encoded in base64
* Encodes a string in base64. * Encodes a string in base64.
* `minetest.decode_base64(string)`: returns string * `minetest.decode_base64(string)`: returns string

View File

@ -531,18 +531,18 @@ for conversion.
If the `ItemStack`'s metadata contains the `color` field, it will be If the `ItemStack`'s metadata contains the `color` field, it will be
lost on placement, because nodes on the map can only use palettes. lost on placement, because nodes on the map can only use palettes.
If the `ItemStack`'s metadata contains the `palette_index` field, you If the `ItemStack`'s metadata contains the `palette_index` field, it is
currently must manually convert between it and the node's `param2` with automatically transferred between node and item forms by the engine,
custom `on_place` and `on_dig` callbacks. when a player digs or places a colored node.
You can disable this feature by setting the `drop` field of the node
to itself (without metadata).
### Colored items in craft recipes ### Colored items in craft recipes
Craft recipes only support item strings, but fortunately item strings Craft recipes only support item strings, but fortunately item strings
can also contain metadata. Example craft recipe registration: can also contain metadata. Example craft recipe registration:
local stack = ItemStack("wool:block")
dyed:get_meta():set_int("palette_index", 3) -- add index
minetest.register_craft({ minetest.register_craft({
output = dyed:to_string(), -- convert to string output = minetest.itemstring_with_palette("wool:block", 3),
type = "shapeless", type = "shapeless",
recipe = { recipe = {
"wool:block", "wool:block",
@ -550,6 +550,8 @@ can also contain metadata. Example craft recipe registration:
}, },
}) })
To set the `color` field, you can use `minetest.itemstring_with_color`.
Metadata field filtering in the `recipe` field are not supported yet, Metadata field filtering in the `recipe` field are not supported yet,
so the craft output is independent of the color of the ingredients. so the craft output is independent of the color of the ingredients.
@ -578,7 +580,7 @@ Example (colored grass block):
description = "Dirt with Grass", description = "Dirt with Grass",
-- Regular tiles, as usual -- Regular tiles, as usual
-- The dirt tile disables palette coloring -- The dirt tile disables palette coloring
tiles = {{name = "default_grass.png"}, tiles = {{name = "default_grass.png"},
{name = "default_dirt.png", color = "white"}}, {name = "default_dirt.png", color = "white"}},
-- Overlay tiles: define them in the same style -- Overlay tiles: define them in the same style
-- The top and bottom tile does not have overlay -- The top and bottom tile does not have overlay
@ -1074,12 +1076,7 @@ Ore attributes
See section "Flag Specifier Format". See section "Flag Specifier Format".
Currently supported flags: Currently supported flags:
`absheight`, `puff_cliffs`, `puff_additive_composition`. `puff_cliffs`, `puff_additive_composition`.
### `absheight`
Also produce this same ore between the height range of `-y_max` and `-y_min`.
Useful for having ore in sky realms without having to duplicate ore entries.
### `puff_cliffs` ### `puff_cliffs`
If set, puff ore generation will not taper down large differences in displacement If set, puff ore generation will not taper down large differences in displacement
@ -2465,12 +2462,13 @@ and `minetest.auth_reload` call the authetification handler.
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
* `search_center` is an optional boolean (default: `false`) * `search_center` is an optional boolean (default: `false`)
If true `pos` is also checked for the nodes If true `pos` is also checked for the nodes
* `minetest.find_nodes_in_area(minp, maxp, nodenames)`: returns a list of positions * `minetest.find_nodes_in_area(pos1, pos2, nodenames)`: returns a list of positions
* returns as second value a table with the count of the individual nodes found
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
* `minetest.find_nodes_in_area_under_air(minp, maxp, nodenames)`: returns a list of positions * First return value: Table with all node positions
* returned positions are nodes with a node air above * Second return value: Table with the count of each node with the node name as index
* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a list of positions
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
* Return value: Table with all node positions with a node air above
* `minetest.get_perlin(noiseparams)` * `minetest.get_perlin(noiseparams)`
* `minetest.get_perlin(seeddiff, octaves, persistence, scale)` * `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
* Return world-specific perlin noise (`int(worldseed)+seeddiff`) * Return world-specific perlin noise (`int(worldseed)+seeddiff`)
@ -2725,6 +2723,21 @@ and `minetest.auth_reload` call the authetification handler.
digger's inventory digger's inventory
* Can be overridden to get different functionality (e.g. dropping items on * Can be overridden to get different functionality (e.g. dropping items on
ground) ground)
* `minetest.itemstring_with_palette(item, palette_index)`: returns an item string
* Creates an item string which contains palette index information
for hardware colorization. You can use the returned string
as an output in a craft recipe.
* `item`: the item stack which becomes colored. Can be in string,
table and native form.
* `palette_index`: this index is added to the item stack
* `minetest.itemstring_with_color(item, colorstring)`: returns an item string
* Creates an item string which contains static color information
for hardware colorization. Use this method if you wish to colorize
an item that does not own a palette. You can use the returned string
as an output in a craft recipe.
* `item`: the item stack which becomes colored. Can be in string,
table and native form.
* `colorstring`: the new color of the item stack
### Rollback ### Rollback
* `minetest.rollback_get_node_actions(pos, range, seconds, limit)`: * `minetest.rollback_get_node_actions(pos, range, seconds, limit)`:
@ -2955,6 +2968,10 @@ These functions return the leftover itemstack.
* See documentation on `minetest.compress()` for supported compression methods. * See documentation on `minetest.compress()` for supported compression methods.
* currently supported. * currently supported.
* `...` indicates method-specific arguments. Currently, no methods use this. * `...` indicates method-specific arguments. Currently, no methods use this.
* `minetest.rgba(red, green, blue[, alpha])`: returns a string
* Each argument is a 8 Bit unsigned integer
* Returns the ColorString from rgb or rgba values
* Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"`
* `minetest.encode_base64(string)`: returns string encoded in base64 * `minetest.encode_base64(string)`: returns string encoded in base64
* Encodes a string in base64. * Encodes a string in base64.
* `minetest.decode_base64(string)`: returns string * `minetest.decode_base64(string)`: returns string
@ -3325,8 +3342,9 @@ An `InvRef` is a reference to an inventory.
* `add_item(listname, stack)`: add item somewhere in list, returns leftover `ItemStack` * `add_item(listname, stack)`: add item somewhere in list, returns leftover `ItemStack`
* `room_for_item(listname, stack):` returns `true` if the stack of items * `room_for_item(listname, stack):` returns `true` if the stack of items
can be fully added to the list can be fully added to the list
* `contains_item(listname, stack)`: returns `true` if the stack of items * `contains_item(listname, stack, [match_meta])`: returns `true` if
can be fully taken from the list the stack of items can be fully taken from the list.
If `match_meta` is false, only the items' names are compared (default: `false`).
* `remove_item(listname, stack)`: take as many items as specified from the list, * `remove_item(listname, stack)`: take as many items as specified from the list,
returns the items that were actually removed (as an `ItemStack`) -- note that returns the items that were actually removed (as an `ItemStack`) -- note that
any item metadata is ignored, so attempting to remove a specific unique any item metadata is ignored, so attempting to remove a specific unique

View File

@ -534,6 +534,11 @@
#### Advanced #### Advanced
# Arm inertia, gives a more realistic movement of
# the arm when the camera moves.
# type: bool
# arm_inertia = true
# If FPS would go higher than this, limit it by sleeping # If FPS would go higher than this, limit it by sleeping
# to not waste CPU power for no benefit. # to not waste CPU power for no benefit.
# type: int # type: int
@ -1256,6 +1261,14 @@
# type: float # type: float
# mgv5_cave_width = 0.125 # mgv5_cave_width = 0.125
# Y of upper limit of large caves.
# type: int
# mgv5_large_cave_depth = -256
# Y of upper limit of lava in large caves.
# type: int
# mgv5_lava_depth = -256
# Y-level of cavern upper limit. # Y-level of cavern upper limit.
# type: int # type: int
# mgv5_cavern_limit = -256 # mgv5_cavern_limit = -256
@ -1371,6 +1384,14 @@
# type: float # type: float
# mgv7_cave_width = 0.09 # mgv7_cave_width = 0.09
# Y of upper limit of large caves.
# type: int
# mgv7_large_cave_depth = -33
# Y of upper limit of lava in large caves.
# type: int
# mgv7_lava_depth = -256
# Controls the density of floatland mountain terrain. # Controls the density of floatland mountain terrain.
# Is an offset added to the 'np_mountain' noise value. # Is an offset added to the 'np_mountain' noise value.
# type: float # type: float
@ -1472,10 +1493,14 @@
# type: int # type: int
# mgflat_ground_level = 8 # mgflat_ground_level = 8
# Y of upper limit of large pseudorandom caves. # Y of upper limit of large caves.
# type: int # type: int
# mgflat_large_cave_depth = -33 # mgflat_large_cave_depth = -33
# Y of upper limit of lava in large caves.
# type: int
# mgflat_lava_depth = -256
# Controls width of tunnels, a smaller value creates wider tunnels. # Controls width of tunnels, a smaller value creates wider tunnels.
# type: float # type: float
# mgflat_cave_width = 0.09 # mgflat_cave_width = 0.09
@ -1522,6 +1547,14 @@
# type: float # type: float
# mgfractal_cave_width = 0.09 # mgfractal_cave_width = 0.09
# Y of upper limit of large caves.
# type: int
# mgfractal_large_cave_depth = -33
# Y of upper limit of lava in large caves.
# type: int
# mgfractal_lava_depth = -256
# Choice of 18 fractals from 9 formulas. # Choice of 18 fractals from 9 formulas.
# 1 = 4D "Roundy" mandelbrot set. # 1 = 4D "Roundy" mandelbrot set.
# 2 = 4D "Roundy" julia set. # 2 = 4D "Roundy" julia set.

View File

@ -1,7 +1,9 @@
#include <windows.h> #include <windows.h>
#include <commctrl.h> #include <commctrl.h>
#include <richedit.h> #include <richedit.h>
#ifndef USE_CMAKE_CONFIG_H
#define USE_CMAKE_CONFIG_H #define USE_CMAKE_CONFIG_H
#endif
#include "config.h" #include "config.h"
#undef USE_CMAKE_CONFIG_H #undef USE_CMAKE_CONFIG_H

View File

@ -151,8 +151,6 @@ if(ENABLE_FREETYPE)
if(FREETYPE_FOUND) if(FREETYPE_FOUND)
message(STATUS "Freetype enabled.") message(STATUS "Freetype enabled.")
set(USE_FREETYPE TRUE) set(USE_FREETYPE TRUE)
set(CGUITTFONT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cguittfont")
set(CGUITTFONT_LIBRARY cguittfont)
endif() endif()
endif(ENABLE_FREETYPE) endif(ENABLE_FREETYPE)
@ -503,7 +501,6 @@ set(client_SRCS
content_cso.cpp content_cso.cpp
content_mapblock.cpp content_mapblock.cpp
convert_json.cpp convert_json.cpp
drawscene.cpp
filecache.cpp filecache.cpp
fontengine.cpp fontengine.cpp
game.cpp game.cpp
@ -561,7 +558,7 @@ include_directories(
if(USE_FREETYPE) if(USE_FREETYPE)
include_directories(${FREETYPE_INCLUDE_DIRS} ${CGUITTFONT_INCLUDE_DIR}) include_directories(${FREETYPE_INCLUDE_DIRS})
endif() endif()
if(USE_CURL) if(USE_CURL)
@ -620,7 +617,6 @@ if(BUILD_CLIENT)
target_link_libraries( target_link_libraries(
${PROJECT_NAME} ${PROJECT_NAME}
${FREETYPE_LIBRARY} ${FREETYPE_LIBRARY}
${CGUITTFONT_LIBRARY}
) )
endif() endif()
if (USE_CURSES) if (USE_CURSES)
@ -708,9 +704,12 @@ include(CheckCXXCompilerFlag)
if(MSVC) if(MSVC)
# Visual Studio # Visual Studio
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D WIN32_LEAN_AND_MEAN /MP")
# EHa enables SEH exceptions (used for catching segfaults) # EHa enables SEH exceptions (used for catching segfaults)
set(CMAKE_CXX_FLAGS_RELEASE "/EHa /Ox /GL /FD /MT /GS- /Zi /arch:SSE /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0 /TP") set(CMAKE_CXX_FLAGS_RELEASE "/EHa /Ox /GL /FD /MT /GS- /Zi /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0 /TP")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:SSE")
endif()
#set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /NODEFAULTLIB:\"libcmtd.lib\" /NODEFAULTLIB:\"libcmt.lib\"") #set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /NODEFAULTLIB:\"libcmtd.lib\" /NODEFAULTLIB:\"libcmt.lib\"")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF")
@ -753,6 +752,7 @@ else()
if(MINGW) if(MINGW)
set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions") set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_LEAN_AND_MEAN")
endif() endif()
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -Wall -pipe -funroll-loops") set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -Wall -pipe -funroll-loops")
@ -879,10 +879,3 @@ if (USE_GETTEXT)
add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES}) add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES})
endif() endif()
# Subdirectories
if (BUILD_CLIENT AND USE_FREETYPE)
add_subdirectory(cguittfont)
endif()

View File

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientmap.h" // MapDrawControl #include "clientmap.h" // MapDrawControl
#include "player.h" #include "player.h"
#include <cmath> #include <cmath>
#include "client/renderingengine.h"
#include "settings.h" #include "settings.h"
#include "wieldmesh.h" #include "wieldmesh.h"
#include "noise.h" // easeCurve #include "noise.h" // easeCurve
@ -75,6 +76,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount"); m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount");
m_cache_fov = g_settings->getFloat("fov"); m_cache_fov = g_settings->getFloat("fov");
m_cache_zoom_fov = g_settings->getFloat("zoom_fov"); m_cache_zoom_fov = g_settings->getFloat("zoom_fov");
m_arm_inertia = g_settings->getBool("arm_inertia");
m_nametags.clear(); m_nametags.clear();
} }
@ -98,7 +100,7 @@ bool Camera::successfullyCreated(std::string &error_message)
} else { } else {
error_message.clear(); error_message.clear();
} }
if (g_settings->getBool("enable_client_modding")) { if (g_settings->getBool("enable_client_modding")) {
m_client->getScript()->on_camera_ready(this); m_client->getScript()->on_camera_ready(this);
} }
@ -193,6 +195,91 @@ void Camera::step(f32 dtime)
} }
} }
void Camera::addArmInertia(f32 player_yaw, f32 frametime)
{
if (m_timer.X == 0.0f) {
// In the limit case where timer is 0 set a static velocity (generic case divide by zero)
m_cam_vel.X = 1.0001f;
}
else
m_cam_vel.X = std::fabs((m_last_cam_pos.X - player_yaw) / m_timer.X) * 0.01f;
if (m_timer.Y == 0.0f) {
// In the limit case where timer is 0 set a static velocity (generic case divide by zero)
m_cam_vel.Y = 1.0001f;
}
else
m_cam_vel.Y = std::fabs((m_last_cam_pos.Y - m_camera_direction.Y) / m_timer.Y);
if (m_cam_vel.X > 1.0f || m_cam_vel.Y > 1.0f) {
/*
the arm moves when the camera moves fast enough.
*/
if (m_cam_vel.X > 1.0f) {
m_timer.X = frametime;
if (m_cam_vel.X > m_cam_vel_old.X)
m_cam_vel_old.X = m_cam_vel.X;
if (m_last_cam_pos.X > player_yaw)
// right
m_wieldmesh_offset.X -= (0.1f + frametime) * m_cam_vel.X;
else
// left
m_wieldmesh_offset.X += (0.1f + frametime) * m_cam_vel.X;
if (m_last_cam_pos.X != player_yaw)
m_last_cam_pos.X = player_yaw;
m_wieldmesh_offset.X = rangelim(m_wieldmesh_offset.X, 48.0f, 62.0f);
}
if (m_cam_vel.Y > 1.0f) {
m_timer.Y = frametime;
if (m_cam_vel.Y > m_cam_vel_old.Y)
m_cam_vel_old.Y = m_cam_vel.Y;
if (m_last_cam_pos.Y > m_camera_direction.Y)
// down
m_wieldmesh_offset.Y += (0.1f + frametime) * m_cam_vel.Y;
else
// up
m_wieldmesh_offset.Y -= (0.1f + frametime) * m_cam_vel.Y;
if (m_last_cam_pos.Y != m_camera_direction.Y)
m_last_cam_pos.Y = m_camera_direction.Y;
m_wieldmesh_offset.Y = rangelim(m_wieldmesh_offset.Y, -45.0f, -30.0f);
}
} else {
/*
the arm now gets back to its default position when the camera stops.
*/
if (floor(m_wieldmesh_offset.X) == 55.0f) {
m_cam_vel_old.X = 0.0f;
m_wieldmesh_offset.X = 55.0f;
}
if (m_wieldmesh_offset.X > 55.0f)
m_wieldmesh_offset.X -= (0.05f + frametime) * m_cam_vel_old.X;
if (m_wieldmesh_offset.X < 55.0f)
m_wieldmesh_offset.X += (0.05f + frametime) * m_cam_vel_old.X;
if (floor(m_wieldmesh_offset.Y) == -35.0f) {
m_cam_vel_old.Y = 0.0f;
m_wieldmesh_offset.Y = -35.0f;
}
if (m_wieldmesh_offset.Y > -35.0f)
m_wieldmesh_offset.Y -= (0.05f + frametime) * m_cam_vel_old.Y;
if (m_wieldmesh_offset.Y < -35.0f)
m_wieldmesh_offset.Y += (0.05f + frametime) * m_cam_vel_old.Y;
}
}
void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
f32 tool_reload_ratio, ClientEnvironment &c_env) f32 tool_reload_ratio, ClientEnvironment &c_env)
{ {
@ -372,7 +459,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
fov_degrees = rangelim(fov_degrees, 7.0, 160.0); fov_degrees = rangelim(fov_degrees, 7.0, 160.0);
// FOV and aspect ratio // FOV and aspect ratio
m_aspect = (f32) porting::getWindowSize().X / (f32) porting::getWindowSize().Y; const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
m_aspect = (f32) window_size.X / (f32) window_size.Y;
m_fov_y = fov_degrees * M_PI / 180.0; m_fov_y = fov_degrees * M_PI / 180.0;
// Increase vertical FOV on lower aspect ratios (<16:10) // Increase vertical FOV on lower aspect ratios (<16:10)
m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect))); m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect)));
@ -380,12 +468,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
m_cameranode->setAspectRatio(m_aspect); m_cameranode->setAspectRatio(m_aspect);
m_cameranode->setFOV(m_fov_y); m_cameranode->setFOV(m_fov_y);
float wieldmesh_offset_Y = -35 + player->getPitch() * 0.05; if (m_arm_inertia)
wieldmesh_offset_Y = rangelim(wieldmesh_offset_Y, -52, -32); addArmInertia(player->getYaw(), frametime);
// Position the wielded item // Position the wielded item
//v3f wield_position = v3f(45, -35, 65); //v3f wield_position = v3f(45, -35, 65);
v3f wield_position = v3f(55, wieldmesh_offset_Y, 65); v3f wield_position = v3f(m_wieldmesh_offset.X, m_wieldmesh_offset.Y, 65);
//v3f wield_rotation = v3f(-100, 120, -100); //v3f wield_rotation = v3f(-100, 120, -100);
v3f wield_rotation = v3f(-100, 120, -100); v3f wield_rotation = v3f(-100, 120, -100);
wield_position.Y += fabs(m_wield_change_timer)*320 - 40; wield_position.Y += fabs(m_wield_change_timer)*320 - 40;

View File

@ -166,6 +166,8 @@ public:
void drawNametags(); void drawNametags();
inline void addArmInertia(f32 player_yaw, f32 frametime);
private: private:
// Nodes // Nodes
scene::ISceneNode *m_playernode = nullptr; scene::ISceneNode *m_playernode = nullptr;
@ -188,6 +190,12 @@ private:
// Camera offset // Camera offset
v3s16 m_camera_offset; v3s16 m_camera_offset;
v2f m_wieldmesh_offset = v2f(55.0f, -35.0f);
v2f m_timer;
v2f m_cam_vel;
v2f m_cam_vel_old;
v2f m_last_cam_pos;
// Field of view and aspect ratio stuff // Field of view and aspect ratio stuff
f32 m_aspect = 1.0f; f32 m_aspect = 1.0f;
f32 m_fov_x = 1.0f; f32 m_fov_x = 1.0f;
@ -221,6 +229,7 @@ private:
f32 m_cache_view_bobbing_amount; f32 m_cache_view_bobbing_amount;
f32 m_cache_fov; f32 m_cache_fov;
f32 m_cache_zoom_fov; f32 m_cache_zoom_fov;
bool m_arm_inertia;
std::list<Nametag *> m_nametags; std::list<Nametag *> m_nametags;
}; };

View File

@ -258,7 +258,8 @@ CavesRandomWalk::CavesRandomWalk(
s32 seed, s32 seed,
int water_level, int water_level,
content_t water_source, content_t water_source,
content_t lava_source) content_t lava_source,
int lava_depth)
{ {
assert(ndef); assert(ndef);
@ -267,7 +268,7 @@ CavesRandomWalk::CavesRandomWalk(
this->seed = seed; this->seed = seed;
this->water_level = water_level; this->water_level = water_level;
this->np_caveliquids = &nparams_caveliquids; this->np_caveliquids = &nparams_caveliquids;
this->lava_depth = DEFAULT_LAVA_DEPTH; this->lava_depth = lava_depth;
c_water_source = water_source; c_water_source = water_source;
if (c_water_source == CONTENT_IGNORE) if (c_water_source == CONTENT_IGNORE)

View File

@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CAVEGEN_HEADER #define CAVEGEN_HEADER
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
#define DEFAULT_LAVA_DEPTH (-256)
class GenerateNotifier; class GenerateNotifier;
@ -157,7 +156,7 @@ public:
CavesRandomWalk(INodeDefManager *ndef, GenerateNotifier *gennotify = NULL, CavesRandomWalk(INodeDefManager *ndef, GenerateNotifier *gennotify = NULL,
s32 seed = 0, int water_level = 1, s32 seed = 0, int water_level = 1,
content_t water_source = CONTENT_IGNORE, content_t water_source = CONTENT_IGNORE,
content_t lava_source = CONTENT_IGNORE); content_t lava_source = CONTENT_IGNORE, int lava_depth = -256);
// vm and ps are mandatory parameters. // vm and ps are mandatory parameters.
// If heightmap is NULL, the surface level at all points is assumed to // If heightmap is NULL, the surface level at all points is assumed to

View File

@ -1,30 +0,0 @@
# CGUITTFont authors, y u no include headers you use?
# Do not add CGUITTFont.cpp to the line below.
# xCGUITTFont.cpp is a wrapper file that includes
# additional required headers.
add_library(cguittfont STATIC xCGUITTFont.cpp)
if(FREETYPE_PKGCONFIG_FOUND)
set_target_properties(cguittfont
PROPERTIES
COMPILE_FLAGS "${FREETYPE_CFLAGS_STR}"
LINK_FLAGS "${FREETYPE_LDFLAGS_STR}"
)
include_directories(
${IRRLICHT_INCLUDE_DIR}
)
else(FREETYPE_PKGCONFIG_FOUND)
include_directories(
${IRRLICHT_INCLUDE_DIR}
${FREETYPE_INCLUDE_DIRS}
)
endif(FREETYPE_PKGCONFIG_FOUND)
target_link_libraries(
cguittfont
${IRRLICHT_LIBRARY}
${FREETYPE_LIBRARY}
${ZLIB_LIBRARIES} # needed by freetype, repeated here for safety
)

View File

@ -1,5 +0,0 @@
// A wrapper source file to avoid hack with gcc and modifying
// the CGUITTFont files.
#include "xCGUITTFont.h"
#include "CGUITTFont.cpp"

View File

@ -1,7 +0,0 @@
// A wrapper header to avoid hack with gcc and modifying
// the CGUITTFont files.
#include <algorithm>
#include <stddef.h>
#include "irrUString.h"
#include "CGUITTFont.h"

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath> #include <cmath>
#include <IFileSystem.h> #include <IFileSystem.h>
#include "threading/mutex_auto_lock.h" #include "threading/mutex_auto_lock.h"
#include "client/renderingengine.h"
#include "util/auth.h" #include "util/auth.h"
#include "util/directiontables.h" #include "util/directiontables.h"
#include "util/pointedthing.h" #include "util/pointedthing.h"
@ -43,7 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientmap.h" #include "clientmap.h"
#include "clientmedia.h" #include "clientmedia.h"
#include "version.h" #include "version.h"
#include "drawscene.h"
#include "database-sqlite3.h" #include "database-sqlite3.h"
#include "serialization.h" #include "serialization.h"
#include "guiscalingfilter.h" #include "guiscalingfilter.h"
@ -58,7 +58,6 @@ extern gui::IGUIEnvironment* guienv;
*/ */
Client::Client( Client::Client(
IrrlichtDevice *device,
const char *playername, const char *playername,
const std::string &password, const std::string &password,
const std::string &address_name, const std::string &address_name,
@ -80,16 +79,12 @@ Client::Client(
m_event(event), m_event(event),
m_mesh_update_thread(this), m_mesh_update_thread(this),
m_env( m_env(
new ClientMap(this, control, new ClientMap(this, control, 666),
device->getSceneManager()->getRootSceneNode(), tsrc, this
device->getSceneManager(), 666),
device->getSceneManager(),
tsrc, this, device
), ),
m_particle_manager(&m_env), m_particle_manager(&m_env),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this),
m_address_name(address_name), m_address_name(address_name),
m_device(device),
m_server_ser_ver(SER_FMT_VER_INVALID), m_server_ser_ver(SER_FMT_VER_INVALID),
m_last_chat_message_sent(time(NULL)), m_last_chat_message_sent(time(NULL)),
m_password(password), m_password(password),
@ -102,7 +97,7 @@ Client::Client(
m_env.setLocalPlayer(new LocalPlayer(this, playername)); m_env.setLocalPlayer(new LocalPlayer(this, playername));
if (g_settings->getBool("enable_minimap")) { if (g_settings->getBool("enable_minimap")) {
m_minimap = new Minimap(device, this); m_minimap = new Minimap(this);
} }
m_cache_save_interval = g_settings->getU16("server_map_save_interval"); m_cache_save_interval = g_settings->getU16("server_map_save_interval");
@ -112,17 +107,17 @@ Client::Client(
m_script->setEnv(&m_env); m_script->setEnv(&m_env);
} }
void Client::initMods() void Client::loadMods()
{ {
m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME); // Load builtin
scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath());
// If modding is not enabled, don't load mods, just builtin // If modding is not enabled, don't load mods, just builtin
if (!m_modding_enabled) { if (!m_modding_enabled) {
return; return;
} }
ClientModConfiguration modconf(getClientModsLuaPath()); ClientModConfiguration modconf(getClientModsLuaPath());
std::vector<ModSpec> mods = modconf.getMods(); m_mods = modconf.getMods();
std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods(); std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
// complain about mods with unsatisfied dependencies // complain about mods with unsatisfied dependencies
if (!modconf.isConsistent()) { if (!modconf.isConsistent()) {
@ -131,28 +126,52 @@ void Client::initMods()
// Print mods // Print mods
infostream << "Client Loading mods: "; infostream << "Client Loading mods: ";
for (std::vector<ModSpec>::const_iterator i = mods.begin(); for (const ModSpec &mod : m_mods)
i != mods.end(); ++i) { infostream << mod.name << " ";
infostream << (*i).name << " ";
}
infostream << std::endl; infostream << std::endl;
// Load and run "mod" scripts // Load and run "mod" scripts
for (std::vector<ModSpec>::const_iterator it = mods.begin(); for (const ModSpec &mod : m_mods) {
it != mods.end(); ++it) {
const ModSpec &mod = *it;
if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) { if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
throw ModError("Error loading mod \"" + mod.name + throw ModError("Error loading mod \"" + mod.name +
"\": Mod name does not follow naming conventions: " "\": Mod name does not follow naming conventions: "
"Only characters [a-z0-9_] are allowed."); "Only characters [a-z0-9_] are allowed.");
} }
std::string script_path = mod.path + DIR_DELIM + "init.lua"; scanModIntoMemory(mod.name, mod.path);
infostream << " [" << padStringRight(mod.name, 12) << "] [\""
<< script_path << "\"]" << std::endl;
m_script->loadMod(script_path, mod.name);
} }
} }
void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
std::string mod_subpath)
{
std::string full_path = mod_path + DIR_DELIM + mod_subpath;
std::vector<fs::DirListNode> mod = fs::GetDirListing(full_path);
for (unsigned int j=0; j < mod.size(); j++){
std::string filename = mod[j].name;
if (mod[j].dir) {
scanModSubfolder(mod_name, mod_path, mod_subpath
+ filename + DIR_DELIM);
continue;
}
std::replace( mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/');
m_mod_files[mod_name + ":" + mod_subpath + filename] = full_path + filename;
}
}
void Client::initMods()
{
m_script->loadModFromMemory(BUILTIN_MOD_NAME);
// If modding is not enabled, don't load mods, just builtin
if (!m_modding_enabled) {
return;
}
// Load and run "mod" scripts
for (const ModSpec &mod : m_mods)
m_script->loadModFromMemory(mod.name);
}
const std::string &Client::getBuiltinLuaPath() const std::string &Client::getBuiltinLuaPath()
{ {
static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin"; static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin";
@ -220,12 +239,11 @@ Client::~Client()
} }
// cleanup 3d model meshes on client shutdown // cleanup 3d model meshes on client shutdown
while (m_device->getSceneManager()->getMeshCache()->getMeshCount() != 0) { while (RenderingEngine::get_mesh_cache()->getMeshCount() != 0) {
scene::IAnimatedMesh *mesh = scene::IAnimatedMesh *mesh = RenderingEngine::get_mesh_cache()->getMeshByIndex(0);
m_device->getSceneManager()->getMeshCache()->getMeshByIndex(0);
if (mesh) if (mesh)
m_device->getSceneManager()->getMeshCache()->removeMesh(mesh); RenderingEngine::get_mesh_cache()->removeMesh(mesh);
} }
delete m_minimap; delete m_minimap;
@ -621,8 +639,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
verbosestream<<"Client: Attempting to load image " verbosestream<<"Client: Attempting to load image "
<<"file \""<<filename<<"\""<<std::endl; <<"file \""<<filename<<"\""<<std::endl;
io::IFileSystem *irrfs = m_device->getFileSystem(); io::IFileSystem *irrfs = RenderingEngine::get_filesystem();
video::IVideoDriver *vdrv = m_device->getVideoDriver(); video::IVideoDriver *vdrv = RenderingEngine::get_video_driver();
// Create an irrlicht memory file // Create an irrlicht memory file
io::IReadFile *rfile = irrfs->createMemoryReadFile( io::IReadFile *rfile = irrfs->createMemoryReadFile(
@ -1635,7 +1653,6 @@ float Client::mediaReceiveProgress()
} }
typedef struct TextureUpdateArgs { typedef struct TextureUpdateArgs {
IrrlichtDevice *device;
gui::IGUIEnvironment *guienv; gui::IGUIEnvironment *guienv;
u64 last_time_ms; u64 last_time_ms;
u16 last_percent; u16 last_percent;
@ -1662,12 +1679,12 @@ void texture_update_progress(void *args, u32 progress, u32 max_progress)
targs->last_time_ms = time_ms; targs->last_time_ms = time_ms;
std::basic_stringstream<wchar_t> strm; std::basic_stringstream<wchar_t> strm;
strm << targs->text_base << " " << targs->last_percent << "%..."; strm << targs->text_base << " " << targs->last_percent << "%...";
draw_load_screen(strm.str(), targs->device, targs->guienv, targs->tsrc, 0, RenderingEngine::draw_load_screen(strm.str(), targs->guienv, targs->tsrc, 0,
72 + (u16) ((18. / 100.) * (double) targs->last_percent), true); 72 + (u16) ((18. / 100.) * (double) targs->last_percent), true);
} }
} }
void Client::afterContentReceived(IrrlichtDevice *device) void Client::afterContentReceived()
{ {
infostream<<"Client::afterContentReceived() started"<<std::endl; infostream<<"Client::afterContentReceived() started"<<std::endl;
assert(m_itemdef_received); // pre-condition assert(m_itemdef_received); // pre-condition
@ -1679,25 +1696,25 @@ void Client::afterContentReceived(IrrlichtDevice *device)
// Clear cached pre-scaled 2D GUI images, as this cache // Clear cached pre-scaled 2D GUI images, as this cache
// might have images with the same name but different // might have images with the same name but different
// content from previous sessions. // content from previous sessions.
guiScalingCacheClear(device->getVideoDriver()); guiScalingCacheClear();
// Rebuild inherited images and recreate textures // Rebuild inherited images and recreate textures
infostream<<"- Rebuilding images and textures"<<std::endl; infostream<<"- Rebuilding images and textures"<<std::endl;
draw_load_screen(text,device, guienv, m_tsrc, 0, 70); RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 70);
m_tsrc->rebuildImagesAndTextures(); m_tsrc->rebuildImagesAndTextures();
delete[] text; delete[] text;
// Rebuild shaders // Rebuild shaders
infostream<<"- Rebuilding shaders"<<std::endl; infostream<<"- Rebuilding shaders"<<std::endl;
text = wgettext("Rebuilding shaders..."); text = wgettext("Rebuilding shaders...");
draw_load_screen(text, device, guienv, m_tsrc, 0, 71); RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 71);
m_shsrc->rebuildShaders(); m_shsrc->rebuildShaders();
delete[] text; delete[] text;
// Update node aliases // Update node aliases
infostream<<"- Updating node aliases"<<std::endl; infostream<<"- Updating node aliases"<<std::endl;
text = wgettext("Initializing nodes..."); text = wgettext("Initializing nodes...");
draw_load_screen(text, device, guienv, m_tsrc, 0, 72); RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 72);
m_nodedef->updateAliases(m_itemdef); m_nodedef->updateAliases(m_itemdef);
std::string texture_path = g_settings->get("texture_path"); std::string texture_path = g_settings->get("texture_path");
if (texture_path != "" && fs::IsDir(texture_path)) if (texture_path != "" && fs::IsDir(texture_path))
@ -1709,7 +1726,6 @@ void Client::afterContentReceived(IrrlichtDevice *device)
// Update node textures and assign shaders to each tile // Update node textures and assign shaders to each tile
infostream<<"- Updating node textures"<<std::endl; infostream<<"- Updating node textures"<<std::endl;
TextureUpdateArgs tu_args; TextureUpdateArgs tu_args;
tu_args.device = device;
tu_args.guienv = guienv; tu_args.guienv = guienv;
tu_args.last_time_ms = porting::getTimeMs(); tu_args.last_time_ms = porting::getTimeMs();
tu_args.last_percent = 0; tu_args.last_percent = 0;
@ -1731,7 +1747,7 @@ void Client::afterContentReceived(IrrlichtDevice *device)
} }
text = wgettext("Done!"); text = wgettext("Done!");
draw_load_screen(text, device, guienv, m_tsrc, 0, 100); RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 100);
infostream<<"Client::afterContentReceived() done"<<std::endl; infostream<<"Client::afterContentReceived() done"<<std::endl;
delete[] text; delete[] text;
} }
@ -1747,9 +1763,9 @@ float Client::getCurRate()
m_con.getLocalStat(con::CUR_DL_RATE)); m_con.getLocalStat(con::CUR_DL_RATE));
} }
void Client::makeScreenshot(IrrlichtDevice *device) void Client::makeScreenshot()
{ {
irr::video::IVideoDriver *driver = device->getVideoDriver(); irr::video::IVideoDriver *driver = RenderingEngine::get_video_driver();
irr::video::IImage* const raw_image = driver->createScreenShot(); irr::video::IImage* const raw_image = driver->createScreenShot();
if (!raw_image) if (!raw_image)
@ -1864,10 +1880,7 @@ IShaderSource* Client::getShaderSource()
{ {
return m_shsrc; return m_shsrc;
} }
scene::ISceneManager* Client::getSceneManager()
{
return m_device->getSceneManager();
}
u16 Client::allocateUnknownNodeId(const std::string &name) u16 Client::allocateUnknownNodeId(const std::string &name)
{ {
errorstream << "Client::allocateUnknownNodeId(): " errorstream << "Client::allocateUnknownNodeId(): "
@ -1899,25 +1912,34 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename)
return NULL; return NULL;
} }
const std::string &data = it->second; const std::string &data = it->second;
scene::ISceneManager *smgr = m_device->getSceneManager();
// Create the mesh, remove it from cache and return it // Create the mesh, remove it from cache and return it
// This allows unique vertex colors and other properties for each instance // This allows unique vertex colors and other properties for each instance
Buffer<char> data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht Buffer<char> data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht
io::IFileSystem *irrfs = m_device->getFileSystem(); io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
io::IReadFile *rfile = irrfs->createMemoryReadFile(
*data_rw, data_rw.getSize(), filename.c_str()); *data_rw, data_rw.getSize(), filename.c_str());
FATAL_ERROR_IF(!rfile, "Could not create/open RAM file"); FATAL_ERROR_IF(!rfile, "Could not create/open RAM file");
scene::IAnimatedMesh *mesh = smgr->getMesh(rfile); scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile);
rfile->drop(); rfile->drop();
// NOTE: By playing with Irrlicht refcounts, maybe we could cache a bunch // NOTE: By playing with Irrlicht refcounts, maybe we could cache a bunch
// of uniquely named instances and re-use them // of uniquely named instances and re-use them
mesh->grab(); mesh->grab();
smgr->getMeshCache()->removeMesh(mesh); RenderingEngine::get_mesh_cache()->removeMesh(mesh);
return mesh; return mesh;
} }
const std::string* Client::getModFile(const std::string &filename)
{
StringMap::const_iterator it = m_mod_files.find(filename);
if (it == m_mod_files.end()) {
errorstream << "Client::getModFile(): File not found: \"" << filename
<< "\"" << std::endl;
return NULL;
}
return &it->second;
}
bool Client::registerModStorage(ModMetadata *storage) bool Client::registerModStorage(ModMetadata *storage)
{ {
if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) { if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {

View File

@ -39,6 +39,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h" #include "mapnode.h"
#include "tileanimation.h" #include "tileanimation.h"
#include "mesh_generator_thread.h" #include "mesh_generator_thread.h"
#include <fstream>
#include "filesys.h"
#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
@ -258,7 +260,6 @@ public:
*/ */
Client( Client(
IrrlichtDevice *device,
const char *playername, const char *playername,
const std::string &password, const std::string &password,
const std::string &address_name, const std::string &address_name,
@ -276,6 +277,16 @@ public:
~Client(); ~Client();
DISABLE_CLASS_COPY(Client); DISABLE_CLASS_COPY(Client);
// Load local mods into memory
void loadMods();
void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
std::string mod_subpath);
inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
{
scanModSubfolder(mod_name, mod_path, "");
}
// Initizle the mods
void initMods(); void initMods();
/* /*
@ -469,7 +480,7 @@ public:
float mediaReceiveProgress(); float mediaReceiveProgress();
void afterContentReceived(IrrlichtDevice *device); void afterContentReceived();
float getRTT(); float getRTT();
float getCurRate(); float getCurRate();
@ -488,7 +499,6 @@ public:
ITextureSource* getTextureSource(); ITextureSource* getTextureSource();
virtual IShaderSource* getShaderSource(); virtual IShaderSource* getShaderSource();
IShaderSource *shsrc() { return getShaderSource(); } IShaderSource *shsrc() { return getShaderSource(); }
scene::ISceneManager* getSceneManager();
virtual u16 allocateUnknownNodeId(const std::string &name); virtual u16 allocateUnknownNodeId(const std::string &name);
virtual ISoundManager* getSoundManager(); virtual ISoundManager* getSoundManager();
virtual MtEventManager* getEventManager(); virtual MtEventManager* getEventManager();
@ -496,6 +506,7 @@ public:
bool checkLocalPrivilege(const std::string &priv) bool checkLocalPrivilege(const std::string &priv)
{ return checkPrivilege(priv); } { return checkPrivilege(priv); }
virtual scene::IAnimatedMesh* getMesh(const std::string &filename); virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
const std::string* getModFile(const std::string &filename);
virtual std::string getModStoragePath() const; virtual std::string getModStoragePath() const;
virtual bool registerModStorage(ModMetadata *meta); virtual bool registerModStorage(ModMetadata *meta);
@ -509,7 +520,7 @@ public:
LocalClientState getState() { return m_state; } LocalClientState getState() { return m_state; }
void makeScreenshot(IrrlichtDevice *device); void makeScreenshot();
inline void pushToChatQueue(const std::wstring &input) inline void pushToChatQueue(const std::wstring &input)
{ {
@ -531,8 +542,6 @@ public:
void showGameFog(const bool show = true); void showGameFog(const bool show = true);
void showGameDebug(const bool show = true); void showGameDebug(const bool show = true);
IrrlichtDevice *getDevice() const { return m_device; }
const Address getServerAddress() const Address getServerAddress()
{ {
return m_con.GetPeerAddress(PEER_ID_SERVER); return m_con.GetPeerAddress(PEER_ID_SERVER);
@ -598,7 +607,6 @@ private:
ParticleManager m_particle_manager; ParticleManager m_particle_manager;
con::Connection m_con; con::Connection m_con;
std::string m_address_name; std::string m_address_name;
IrrlichtDevice *m_device;
Camera *m_camera = nullptr; Camera *m_camera = nullptr;
Minimap *m_minimap = nullptr; Minimap *m_minimap = nullptr;
bool m_minimap_disabled_by_server = false; bool m_minimap_disabled_by_server = false;
@ -680,6 +688,8 @@ private:
// Storage for mesh data for creating multiple instances of the same mesh // Storage for mesh data for creating multiple instances of the same mesh
StringMap m_mesh_data; StringMap m_mesh_data;
StringMap m_mod_files;
// own state // own state
LocalClientState m_state; LocalClientState m_state;
@ -692,6 +702,7 @@ private:
bool m_modding_enabled; bool m_modding_enabled;
std::unordered_map<std::string, ModMetadata *> m_mod_storages; std::unordered_map<std::string, ModMetadata *> m_mod_storages;
float m_mod_storage_save_timer = 10.0f; float m_mod_storage_save_timer = 10.0f;
std::vector<ModSpec> m_mods;
GameUIFlags *m_game_ui_flags; GameUIFlags *m_game_ui_flags;
bool m_shutdown = false; bool m_shutdown = false;

View File

@ -1,4 +1,5 @@
set(client_SRCS set(client_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/renderingengine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp ${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp
${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp

View File

@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "mainmenumanager.h" #include "mainmenumanager.h"
#include "debug.h"
#include "clouds.h" #include "clouds.h"
#include "server.h" #include "server.h"
#include "filesys.h" #include "filesys.h"
@ -27,19 +26,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "chat.h" #include "chat.h"
#include "gettext.h" #include "gettext.h"
#include "profiler.h" #include "profiler.h"
#include "log.h"
#include "serverlist.h" #include "serverlist.h"
#include "guiEngine.h" #include "guiEngine.h"
#include "player.h"
#include "fontengine.h" #include "fontengine.h"
#include "joystick_controller.h"
#include "clientlauncher.h" #include "clientlauncher.h"
#include "version.h" #include "version.h"
#include "renderingengine.h"
/* mainmenumanager.h /* mainmenumanager.h
*/ */
gui::IGUIEnvironment *guienv = NULL; gui::IGUIEnvironment *guienv = nullptr;
gui::IGUIStaticText *guiroot = NULL; gui::IGUIStaticText *guiroot = nullptr;
MainMenuManager g_menumgr; MainMenuManager g_menumgr;
bool isMenuActive() bool isMenuActive()
@ -48,7 +45,7 @@ bool isMenuActive()
} }
// Passed to menus to allow disconnecting and exiting // Passed to menus to allow disconnecting and exiting
MainGameCallback *g_gamecallback = NULL; MainGameCallback *g_gamecallback = nullptr;
ClientLauncher::~ClientLauncher() ClientLauncher::~ClientLauncher()
@ -58,9 +55,9 @@ ClientLauncher::~ClientLauncher()
delete input; delete input;
delete g_fontengine; delete g_fontengine;
delete g_gamecallback;
if (device) delete RenderingEngine::get_instance();
device->drop();
} }
@ -70,7 +67,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
// List video modes if requested // List video modes if requested
if (list_video_modes) if (list_video_modes)
return print_video_modes(); return RenderingEngine::print_video_modes();
if (!init_engine()) { if (!init_engine()) {
errorstream << "Could not initialize game engine." << std::endl; errorstream << "Could not initialize game engine." << std::endl;
@ -84,15 +81,14 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
return true; return true;
} }
video::IVideoDriver *video_driver = device->getVideoDriver(); video::IVideoDriver *video_driver = RenderingEngine::get_video_driver();
if (video_driver == NULL) { if (video_driver == NULL) {
errorstream << "Could not initialize video driver." << std::endl; errorstream << "Could not initialize video driver." << std::endl;
return false; return false;
} }
porting::setXorgClassHint(video_driver->getExposedVideoData(), PROJECT_NAME_C); RenderingEngine::setXorgClassHint(video_driver->getExposedVideoData(), PROJECT_NAME_C);
RenderingEngine::get_instance()->setWindowIcon();
porting::setWindowIcon(device);
/* /*
This changes the minimum allowed number of vertices in a VBO. This changes the minimum allowed number of vertices in a VBO.
@ -101,17 +97,17 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
//driver->setMinHardwareBufferVertexCount(50); //driver->setMinHardwareBufferVertexCount(50);
// Create game callback for menus // Create game callback for menus
g_gamecallback = new MainGameCallback(device); g_gamecallback = new MainGameCallback();
device->setResizable(true); RenderingEngine::get_instance()->setResizable(true);
init_input(); init_input();
smgr = device->getSceneManager(); RenderingEngine::get_scene_manager()->getParameters()->
smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
guienv = device->getGUIEnvironment(); guienv = RenderingEngine::get_gui_env();
skin = guienv->getSkin(); skin = RenderingEngine::get_gui_env()->getSkin();
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255)); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0)); skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
@ -130,10 +126,9 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
// Create the menu clouds // Create the menu clouds
if (!g_menucloudsmgr) if (!g_menucloudsmgr)
g_menucloudsmgr = smgr->createNewSceneManager(); g_menucloudsmgr = RenderingEngine::get_scene_manager()->createNewSceneManager();
if (!g_menuclouds) if (!g_menuclouds)
g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(), g_menuclouds = new Clouds(g_menucloudsmgr, -1, rand(), 100);
g_menucloudsmgr, -1, rand(), 100);
g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255)); g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255));
scene::ICameraSceneNode* camera; scene::ICameraSceneNode* camera;
camera = g_menucloudsmgr->addCameraSceneNode(0, camera = g_menucloudsmgr->addCameraSceneNode(0,
@ -159,25 +154,27 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
bool retval = true; bool retval = true;
bool *kill = porting::signal_handler_killstatus(); bool *kill = porting::signal_handler_killstatus();
while (device->run() && !*kill && !g_gamecallback->shutdown_requested) while (RenderingEngine::run() && !*kill &&
{ !g_gamecallback->shutdown_requested) {
// Set the window caption // Set the window caption
const wchar_t *text = wgettext("Main Menu"); const wchar_t *text = wgettext("Main Menu");
device->setWindowCaption((utf8_to_wide(PROJECT_NAME_C) + RenderingEngine::get_raw_device()->
setWindowCaption((utf8_to_wide(PROJECT_NAME_C) +
L" " + utf8_to_wide(g_version_hash) + L" " + utf8_to_wide(g_version_hash) +
L" [" + text + L"]").c_str()); L" [" + text + L"]").c_str());
delete[] text; delete[] text;
try { // This is used for catching disconnects try { // This is used for catching disconnects
guienv->clear(); RenderingEngine::get_gui_env()->clear();
/* /*
We need some kind of a root node to be able to add We need some kind of a root node to be able to add
custom gui elements directly on the screen. custom gui elements directly on the screen.
Otherwise they won't be automatically drawn. Otherwise they won't be automatically drawn.
*/ */
guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000)); guiroot = RenderingEngine::get_gui_env()->addStaticText(L"",
core::rect<s32>(0, 0, 10000, 10000));
bool game_has_run = launch_game(error_message, reconnect_requested, bool game_has_run = launch_game(error_message, reconnect_requested,
game_params, cmd_args); game_params, cmd_args);
@ -199,7 +196,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
} }
// Break out of menu-game loop to shut down cleanly // Break out of menu-game loop to shut down cleanly
if (!device->run() || *kill) { if (!RenderingEngine::get_raw_device()->run() || *kill) {
if (g_settings_path != "") if (g_settings_path != "")
g_settings->updateConfigFile(g_settings_path.c_str()); g_settings->updateConfigFile(g_settings_path.c_str());
break; break;
@ -212,7 +209,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
continue; continue;
} }
device->getVideoDriver()->setTextureCreationFlag( RenderingEngine::get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map")); video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
@ -224,7 +221,6 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
kill, kill,
random_input, random_input,
input, input,
device,
worldspec.path, worldspec.path,
current_playername, current_playername,
current_password, current_password,
@ -236,7 +232,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
gamespec, gamespec,
simple_singleplayer_mode simple_singleplayer_mode
); );
smgr->clear(); RenderingEngine::get_scene_manager()->clear();
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
delete g_touchscreengui; delete g_touchscreengui;
@ -308,8 +304,8 @@ void ClientLauncher::init_args(GameParams &game_params, const Settings &cmd_args
bool ClientLauncher::init_engine() bool ClientLauncher::init_engine()
{ {
receiver = new MyEventReceiver(); receiver = new MyEventReceiver();
create_engine_device(); new RenderingEngine(receiver);
return device != NULL; return RenderingEngine::get_raw_device() != nullptr;
} }
void ClientLauncher::init_input() void ClientLauncher::init_input()
@ -317,7 +313,7 @@ void ClientLauncher::init_input()
if (random_input) if (random_input)
input = new RandomInputHandler(); input = new RandomInputHandler();
else else
input = new RealInputHandler(device, receiver); input = new RealInputHandler(receiver);
if (g_settings->getBool("enable_joysticks")) { if (g_settings->getBool("enable_joysticks")) {
irr::core::array<irr::SJoystickInfo> infos; irr::core::array<irr::SJoystickInfo> infos;
@ -326,7 +322,7 @@ void ClientLauncher::init_input()
// Make sure this is called maximum once per // Make sure this is called maximum once per
// irrlicht device, otherwise it will give you // irrlicht device, otherwise it will give you
// multiple events for the same joystick. // multiple events for the same joystick.
if (device->activateJoysticks(infos)) { if (RenderingEngine::get_raw_device()->activateJoysticks(infos)) {
infostream << "Joystick support enabled" << std::endl; infostream << "Joystick support enabled" << std::endl;
joystick_infos.reserve(infos.size()); joystick_infos.reserve(infos.size());
for (u32 i = 0; i < infos.size(); i++) { for (u32 i = 0; i < infos.size(); i++) {
@ -487,14 +483,14 @@ bool ClientLauncher::launch_game(std::string &error_message,
void ClientLauncher::main_menu(MainMenuData *menudata) void ClientLauncher::main_menu(MainMenuData *menudata)
{ {
bool *kill = porting::signal_handler_killstatus(); bool *kill = porting::signal_handler_killstatus();
video::IVideoDriver *driver = device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
infostream << "Waiting for other menus" << std::endl; infostream << "Waiting for other menus" << std::endl;
while (device->run() && *kill == false) { while (RenderingEngine::get_raw_device()->run() && *kill == false) {
if (!isMenuActive()) if (!isMenuActive())
break; break;
driver->beginScene(true, true, video::SColor(255, 128, 128, 128)); driver->beginScene(true, true, video::SColor(255, 128, 128, 128));
guienv->drawAll(); RenderingEngine::get_gui_env()->drawAll();
driver->endScene(); driver->endScene();
// On some computers framerate doesn't seem to be automatically limited // On some computers framerate doesn't seem to be automatically limited
sleep_ms(25); sleep_ms(25);
@ -503,73 +499,14 @@ void ClientLauncher::main_menu(MainMenuData *menudata)
// Cursor can be non-visible when coming from the game // Cursor can be non-visible when coming from the game
#ifndef ANDROID #ifndef ANDROID
device->getCursorControl()->setVisible(true); RenderingEngine::get_raw_device()->getCursorControl()->setVisible(true);
#endif #endif
/* show main menu */ /* show main menu */
GUIEngine mymenu(device, &input->joystick, guiroot, GUIEngine mymenu(&input->joystick, guiroot, &g_menumgr, menudata, *kill);
&g_menumgr, smgr, menudata, *kill);
smgr->clear(); /* leave scene manager in a clean state */ /* leave scene manager in a clean state */
} RenderingEngine::get_scene_manager()->clear();
bool ClientLauncher::create_engine_device()
{
// Resolution selection
bool fullscreen = g_settings->getBool("fullscreen");
u16 screen_w = g_settings->getU16("screen_w");
u16 screen_h = g_settings->getU16("screen_h");
// bpp, fsaa, vsync
bool vsync = g_settings->getBool("vsync");
u16 bits = g_settings->getU16("fullscreen_bpp");
u16 fsaa = g_settings->getU16("fsaa");
// stereo buffer required for pageflip stereo
bool stereo_buffer = g_settings->get("3d_mode") == "pageflip";
// Determine driver
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
const std::string &driverstring = g_settings->get("video_driver");
std::vector<video::E_DRIVER_TYPE> drivers
= porting::getSupportedVideoDrivers();
u32 i;
for (i = 0; i != drivers.size(); i++) {
if (!strcasecmp(driverstring.c_str(),
porting::getVideoDriverName(drivers[i]))) {
driverType = drivers[i];
break;
}
}
if (i == drivers.size()) {
errorstream << "Invalid video_driver specified; "
"defaulting to opengl" << std::endl;
}
SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
params.DriverType = driverType;
params.WindowSize = core::dimension2d<u32>(screen_w, screen_h);
params.Bits = bits;
params.AntiAlias = fsaa;
params.Fullscreen = fullscreen;
params.Stencilbuffer = false;
params.Stereobuffer = stereo_buffer;
params.Vsync = vsync;
params.EventReceiver = receiver;
params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
params.ZBufferBits = 24;
#ifdef __ANDROID__
params.PrivateData = porting::app_global;
params.OGLES2ShaderPath = std::string(porting::path_user + DIR_DELIM +
"media" + DIR_DELIM + "Shaders" + DIR_DELIM).c_str();
#endif
device = createDeviceEx(params);
if (device)
porting::initIrrlicht(device);
return device != NULL;
} }
void ClientLauncher::speed_tests() void ClientLauncher::speed_tests()
@ -584,8 +521,8 @@ void ClientLauncher::speed_tests()
tempv3f1 = v3f(); tempv3f1 = v3f();
tempv3f2 = v3f(); tempv3f2 = v3f();
tempstring = std::string(); tempstring.clear();
tempstring2 = std::string(); tempstring2.clear();
{ {
infostream << "The following test should take around 20ms." << std::endl; infostream << "The following test should take around 20ms." << std::endl;
@ -670,58 +607,3 @@ void ClientLauncher::speed_tests()
infostream << "Done. " << dtime << "ms, " << per_ms << "/ms" << std::endl; infostream << "Done. " << dtime << "ms, " << per_ms << "/ms" << std::endl;
} }
} }
bool ClientLauncher::print_video_modes()
{
IrrlichtDevice *nulldevice;
bool vsync = g_settings->getBool("vsync");
u16 fsaa = g_settings->getU16("fsaa");
MyEventReceiver* receiver = new MyEventReceiver();
SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
params.DriverType = video::EDT_NULL;
params.WindowSize = core::dimension2d<u32>(640, 480);
params.Bits = 24;
params.AntiAlias = fsaa;
params.Fullscreen = false;
params.Stencilbuffer = false;
params.Vsync = vsync;
params.EventReceiver = receiver;
params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
nulldevice = createDeviceEx(params);
if (nulldevice == NULL) {
delete receiver;
return false;
}
std::cout << _("Available video modes (WxHxD):") << std::endl;
video::IVideoModeList *videomode_list = nulldevice->getVideoModeList();
if (videomode_list != NULL) {
s32 videomode_count = videomode_list->getVideoModeCount();
core::dimension2d<u32> videomode_res;
s32 videomode_depth;
for (s32 i = 0; i < videomode_count; ++i) {
videomode_res = videomode_list->getVideoModeResolution(i);
videomode_depth = videomode_list->getVideoModeDepth(i);
std::cout << videomode_res.Width << "x" << videomode_res.Height
<< "x" << videomode_depth << std::endl;
}
std::cout << _("Active video mode (WxHxD):") << std::endl;
videomode_res = videomode_list->getDesktopResolution();
videomode_depth = videomode_list->getDesktopDepth();
std::cout << videomode_res.Width << "x" << videomode_res.Height
<< "x" << videomode_depth << std::endl;
}
nulldevice->drop();
delete receiver;
return videomode_list != NULL;
}

View File

@ -24,29 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/inputhandler.h" #include "client/inputhandler.h"
#include "gameparams.h" #include "gameparams.h"
class RenderingEngine;
class ClientLauncher class ClientLauncher
{ {
public: public:
ClientLauncher() : ClientLauncher() {}
list_video_modes(false),
skip_main_menu(false),
use_freetype(false),
random_input(false),
address(""),
playername(""),
password(""),
device(NULL),
input(NULL),
receiver(NULL),
skin(NULL),
font(NULL),
simple_singleplayer_mode(false),
current_playername("inv£lid"),
current_password(""),
current_address("does-not-exist"),
current_port(0)
{}
~ClientLauncher(); ~ClientLauncher();
@ -61,34 +44,30 @@ protected:
GameParams &game_params, const Settings &cmd_args); GameParams &game_params, const Settings &cmd_args);
void main_menu(MainMenuData *menudata); void main_menu(MainMenuData *menudata);
bool create_engine_device();
void speed_tests(); void speed_tests();
bool print_video_modes();
bool list_video_modes; bool list_video_modes = false;
bool skip_main_menu; bool skip_main_menu = false;
bool use_freetype; bool use_freetype = false;
bool random_input; bool random_input = false;
std::string address; std::string address = "";
std::string playername; std::string playername = "";
std::string password; std::string password = "";
IrrlichtDevice *device; InputHandler *input = nullptr;
InputHandler *input; MyEventReceiver *receiver = nullptr;
MyEventReceiver *receiver; gui::IGUISkin *skin = nullptr;
gui::IGUISkin *skin; gui::IGUIFont *font = nullptr;
gui::IGUIFont *font;
scene::ISceneManager *smgr;
SubgameSpec gamespec; SubgameSpec gamespec;
WorldSpec worldspec; WorldSpec worldspec;
bool simple_singleplayer_mode; bool simple_singleplayer_mode;
// These are set up based on the menu and other things // These are set up based on the menu and other things
// TODO: Are these required since there's already playername, password, etc // TODO: Are these required since there's already playername, password, etc
std::string current_playername; std::string current_playername = "inv£lid";
std::string current_password; std::string current_password = "";
std::string current_address; std::string current_address = "does-not-exist";
int current_port; int current_port = 0;
}; };
#endif #endif

View File

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "joystick_controller.h" #include "joystick_controller.h"
#include <list> #include <list>
#include "keycode.h" #include "keycode.h"
#include "renderingengine.h"
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
#include "touchscreengui.h" #include "touchscreengui.h"
@ -141,24 +142,23 @@ public:
MyEventReceiver() MyEventReceiver()
{ {
clearInput();
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
m_touchscreengui = NULL; m_touchscreengui = NULL;
#endif #endif
} }
bool leftclicked; bool leftclicked = false;
bool rightclicked; bool rightclicked = false;
bool leftreleased; bool leftreleased = false;
bool rightreleased; bool rightreleased = false;
bool left_active; bool left_active = false;
bool middle_active; bool middle_active = false;
bool right_active; bool right_active = false;
s32 mouse_wheel; s32 mouse_wheel = 0;
JoystickController *joystick; JoystickController *joystick = nullptr;
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
TouchScreenGUI *m_touchscreengui; TouchScreenGUI *m_touchscreengui;
@ -220,8 +220,7 @@ public:
class RealInputHandler : public InputHandler class RealInputHandler : public InputHandler
{ {
public: public:
RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver) RealInputHandler(MyEventReceiver *receiver) : m_receiver(receiver)
: m_device(device), m_receiver(receiver), m_mousepos(0, 0)
{ {
m_receiver->joystick = &joystick; m_receiver->joystick = &joystick;
} }
@ -240,16 +239,20 @@ public:
virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); } virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); }
virtual v2s32 getMousePos() virtual v2s32 getMousePos()
{ {
if (m_device->getCursorControl()) { if (RenderingEngine::get_raw_device()->getCursorControl()) {
return m_device->getCursorControl()->getPosition(); return RenderingEngine::get_raw_device()
->getCursorControl()
->getPosition();
} else { } else {
return m_mousepos; return m_mousepos;
} }
} }
virtual void setMousePos(s32 x, s32 y) virtual void setMousePos(s32 x, s32 y)
{ {
if (m_device->getCursorControl()) { if (RenderingEngine::get_raw_device()->getCursorControl()) {
m_device->getCursorControl()->setPosition(x, y); RenderingEngine::get_raw_device()
->getCursorControl()
->setPosition(x, y);
} else { } else {
m_mousepos = v2s32(x, y); m_mousepos = v2s32(x, y);
} }
@ -277,24 +280,14 @@ public:
} }
private: private:
IrrlichtDevice *m_device; MyEventReceiver *m_receiver = nullptr;
MyEventReceiver *m_receiver;
v2s32 m_mousepos; v2s32 m_mousepos;
}; };
class RandomInputHandler : public InputHandler class RandomInputHandler : public InputHandler
{ {
public: public:
RandomInputHandler() RandomInputHandler() {}
{
leftdown = false;
rightdown = false;
leftclicked = false;
rightclicked = false;
leftreleased = false;
rightreleased = false;
keydown.clear();
}
virtual bool isKeyDown(const KeyPress &keyCode) { return keydown[keyCode]; } virtual bool isKeyDown(const KeyPress &keyCode) { return keydown[keyCode]; }
virtual bool wasKeyDown(const KeyPress &keyCode) { return false; } virtual bool wasKeyDown(const KeyPress &keyCode) { return false; }
virtual v2s32 getMousePos() { return mousepos; } virtual v2s32 getMousePos() { return mousepos; }
@ -390,12 +383,12 @@ private:
KeyList keydown; KeyList keydown;
v2s32 mousepos; v2s32 mousepos;
v2s32 mousespeed; v2s32 mousespeed;
bool leftdown; bool leftdown = false;
bool rightdown; bool rightdown = false;
bool leftclicked; bool leftclicked = false;
bool rightclicked; bool rightclicked = false;
bool leftreleased; bool leftreleased = false;
bool rightreleased; bool rightreleased = false;
}; };
#endif #endif

View File

@ -154,12 +154,9 @@ JoystickLayout create_xbox_layout()
return jlo; return jlo;
} }
JoystickController::JoystickController() JoystickController::JoystickController() :
doubling_dtime(g_settings->getFloat("repeat_joystick_button_time"))
{ {
m_joystick_id = 0;
doubling_dtime = g_settings->getFloat("repeat_joystick_button_time");
for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) { for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) {
m_past_pressed_time[i] = 0; m_past_pressed_time[i] = 0;
} }

View File

@ -155,7 +155,7 @@ private:
s16 m_axes_vals[JA_COUNT]; s16 m_axes_vals[JA_COUNT];
u8 m_joystick_id; u8 m_joystick_id = 0;
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_pressed_keys; std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_pressed_keys;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,185 @@
/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
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 <vector>
#include <string>
#include "irrlichttypes_extrabloated.h"
#include "debug.h"
class ITextureSource;
class Camera;
class Client;
class LocalPlayer;
class Hud;
class Minimap;
class RenderingEngine
{
public:
RenderingEngine(IEventReceiver *eventReceiver);
~RenderingEngine();
v2u32 getWindowSize() const;
void setResizable(bool resize);
video::IVideoDriver *getVideoDriver();
static const char *getVideoDriverName(irr::video::E_DRIVER_TYPE type);
static const char *getVideoDriverFriendlyName(irr::video::E_DRIVER_TYPE type);
static float getDisplayDensity();
static v2u32 getDisplaySize();
static void setXorgClassHint(const video::SExposedVideoData &video_data,
const std::string &name);
bool setWindowIcon();
bool setXorgWindowIconFromPath(const std::string &icon_file);
static bool print_video_modes();
static RenderingEngine *get_instance() { return s_singleton; }
static io::IFileSystem *get_filesystem()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->getFileSystem();
}
static video::IVideoDriver *get_video_driver()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->getVideoDriver();
}
static scene::IMeshCache *get_mesh_cache()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->getSceneManager()->getMeshCache();
}
static scene::ISceneManager *get_scene_manager()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->getSceneManager();
}
static irr::IrrlichtDevice *get_raw_device()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device;
}
static u32 get_timer_time()
{
sanity_check(s_singleton && s_singleton->m_device &&
s_singleton->m_device->getTimer());
return s_singleton->m_device->getTimer()->getTime();
}
static gui::IGUIEnvironment *get_gui_env()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->getGUIEnvironment();
}
inline static void draw_load_screen(const std::wstring &text,
gui::IGUIEnvironment *guienv, ITextureSource *tsrc,
float dtime = 0, int percent = 0, bool clouds = true)
{
s_singleton->_draw_load_screen(
text, guienv, tsrc, dtime, percent, clouds);
}
inline static void draw_scene(Camera *camera, Client *client, LocalPlayer *player,
Hud *hud, Minimap *mapper, gui::IGUIEnvironment *guienv,
const v2u32 &screensize, const video::SColor &skycolor,
bool show_hud, bool show_minimap)
{
s_singleton->_draw_scene(camera, client, player, hud, mapper, guienv,
screensize, skycolor, show_hud, show_minimap);
}
static bool run()
{
sanity_check(s_singleton && s_singleton->m_device);
return s_singleton->m_device->run();
}
static std::vector<core::vector3d<u32>> getSupportedVideoModes();
static std::vector<irr::video::E_DRIVER_TYPE> getSupportedVideoDrivers();
private:
enum parallax_sign
{
LEFT = -1,
RIGHT = 1,
EYECOUNT = 2
};
void _draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv,
ITextureSource *tsrc, float dtime = 0, int percent = 0,
bool clouds = true);
void _draw_scene(Camera *camera, Client *client, LocalPlayer *player, Hud *hud,
Minimap *mapper, gui::IGUIEnvironment *guienv,
const v2u32 &screensize, const video::SColor &skycolor,
bool show_hud, bool show_minimap);
void draw_anaglyph_3d_mode(Camera *camera, bool show_hud, Hud *hud,
bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv);
void draw_interlaced_3d_mode(Camera *camera, bool show_hud, Hud *hud,
const v2u32 &screensize, bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
void draw_sidebyside_3d_mode(Camera *camera, bool show_hud, Hud *hud,
const v2u32 &screensize, bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
void draw_top_bottom_3d_mode(Camera *camera, bool show_hud, Hud *hud,
const v2u32 &screensize, bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
void draw_pageflip_3d_mode(Camera *camera, bool show_hud, Hud *hud,
const v2u32 &screensize, bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
void draw_plain(Camera *camera, bool show_hud, Hud *hud, const v2u32 &screensize,
bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
void init_texture(const v2u32 &screensize, video::ITexture **texture,
const char *name);
video::ITexture *draw_image(const v2u32 &screensize, parallax_sign psign,
const irr::core::matrix4 &startMatrix,
const irr::core::vector3df &focusPoint, bool show_hud,
Camera *camera, Hud *hud, bool draw_wield_tool, Client *client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
video::ITexture *draw_hud(const v2u32 &screensize, bool show_hud, Hud *hud,
Client *client, bool draw_crosshair,
const video::SColor &skycolor, gui::IGUIEnvironment *guienv,
Camera *camera);
irr::IrrlichtDevice *m_device = nullptr;
static RenderingEngine *s_singleton;
};

View File

@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "imagefilters.h" #include "imagefilters.h"
#include "guiscalingfilter.h" #include "guiscalingfilter.h"
#include "nodedef.h" #include "nodedef.h"
#include "renderingengine.h"
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -198,8 +199,7 @@ public:
} }
m_images.clear(); m_images.clear();
} }
void insert(const std::string &name, video::IImage *img, void insert(const std::string &name, video::IImage *img, bool prefer_local)
bool prefer_local, video::IVideoDriver *driver)
{ {
assert(img); // Pre-condition assert(img); // Pre-condition
// Remove old image // Remove old image
@ -217,7 +217,8 @@ public:
if (prefer_local){ if (prefer_local){
std::string path = getTexturePath(name); std::string path = getTexturePath(name);
if (path != ""){ if (path != ""){
video::IImage *img2 = driver->createImageFromFile(path.c_str()); video::IImage *img2 = RenderingEngine::get_video_driver()->
createImageFromFile(path.c_str());
if (img2){ if (img2){
toadd = img2; toadd = img2;
need_to_grab = false; need_to_grab = false;
@ -238,7 +239,7 @@ public:
return NULL; return NULL;
} }
// Primarily fetches from cache, secondarily tries to read from filesystem // Primarily fetches from cache, secondarily tries to read from filesystem
video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device) video::IImage *getOrLoad(const std::string &name)
{ {
std::map<std::string, video::IImage*>::iterator n; std::map<std::string, video::IImage*>::iterator n;
n = m_images.find(name); n = m_images.find(name);
@ -246,7 +247,7 @@ public:
n->second->grab(); // Grab for caller n->second->grab(); // Grab for caller
return n->second; return n->second;
} }
video::IVideoDriver* driver = device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
std::string path = getTexturePath(name); std::string path = getTexturePath(name);
if (path == ""){ if (path == ""){
infostream<<"SourceImageCache::getOrLoad(): No path found for \"" infostream<<"SourceImageCache::getOrLoad(): No path found for \""
@ -274,7 +275,7 @@ private:
class TextureSource : public IWritableTextureSource class TextureSource : public IWritableTextureSource
{ {
public: public:
TextureSource(IrrlichtDevice *device); TextureSource();
virtual ~TextureSource(); virtual ~TextureSource();
/* /*
@ -343,12 +344,6 @@ public:
virtual Palette* getPalette(const std::string &name); virtual Palette* getPalette(const std::string &name);
// Returns a pointer to the irrlicht device
virtual IrrlichtDevice* getDevice()
{
return m_device;
}
bool isKnownSourceImage(const std::string &name) bool isKnownSourceImage(const std::string &name)
{ {
bool is_known = false; bool is_known = false;
@ -387,8 +382,6 @@ private:
// The id of the thread that is allowed to use irrlicht directly // The id of the thread that is allowed to use irrlicht directly
std::thread::id m_main_thread; std::thread::id m_main_thread;
// The irrlicht device
IrrlichtDevice *m_device;
// Cache of source images // Cache of source images
// This should be only accessed from the main thread // This should be only accessed from the main thread
@ -435,16 +428,13 @@ private:
bool m_setting_anisotropic_filter; bool m_setting_anisotropic_filter;
}; };
IWritableTextureSource* createTextureSource(IrrlichtDevice *device) IWritableTextureSource *createTextureSource()
{ {
return new TextureSource(device); return new TextureSource();
} }
TextureSource::TextureSource(IrrlichtDevice *device): TextureSource::TextureSource()
m_device(device)
{ {
assert(m_device); // Pre-condition
m_main_thread = std::this_thread::get_id(); m_main_thread = std::this_thread::get_id();
// Add a NULL TextureInfo as the first index, named "" // Add a NULL TextureInfo as the first index, named ""
@ -461,7 +451,7 @@ TextureSource::TextureSource(IrrlichtDevice *device):
TextureSource::~TextureSource() TextureSource::~TextureSource()
{ {
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
unsigned int textures_before = driver->getTextureCount(); unsigned int textures_before = driver->getTextureCount();
@ -622,7 +612,7 @@ u32 TextureSource::generateTexture(const std::string &name)
return 0; return 0;
} }
video::IVideoDriver *driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
sanity_check(driver); sanity_check(driver);
video::IImage *img = generateImage(name); video::IImage *img = generateImage(name);
@ -773,7 +763,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im
sanity_check(std::this_thread::get_id() == m_main_thread); sanity_check(std::this_thread::get_id() == m_main_thread);
m_sourcecache.insert(name, img, true, m_device->getVideoDriver()); m_sourcecache.insert(name, img, true);
m_source_image_existence.set(name, true); m_source_image_existence.set(name, true);
} }
@ -781,7 +771,7 @@ void TextureSource::rebuildImagesAndTextures()
{ {
MutexAutoLock lock(m_textureinfo_cache_mutex); MutexAutoLock lock(m_textureinfo_cache_mutex);
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
sanity_check(driver); sanity_check(driver);
// Recreate textures // Recreate textures
@ -810,7 +800,7 @@ void TextureSource::rebuildImagesAndTextures()
video::ITexture* TextureSource::generateTextureFromMesh( video::ITexture* TextureSource::generateTextureFromMesh(
const TextureFromMeshParams &params) const TextureFromMeshParams &params)
{ {
video::IVideoDriver *driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
sanity_check(driver); sanity_check(driver);
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -935,8 +925,7 @@ video::ITexture* TextureSource::generateTextureFromMesh(
} }
#endif #endif
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) {
{
static bool warned = false; static bool warned = false;
if (!warned) if (!warned)
{ {
@ -967,7 +956,7 @@ video::ITexture* TextureSource::generateTextureFromMesh(
} }
// Get a scene manager // Get a scene manager
scene::ISceneManager *smgr_main = m_device->getSceneManager(); scene::ISceneManager *smgr_main = RenderingEngine::get_scene_manager();
assert(smgr_main); assert(smgr_main);
scene::ISceneManager *smgr = smgr_main->createNewSceneManager(); scene::ISceneManager *smgr = smgr_main->createNewSceneManager();
assert(smgr); assert(smgr);
@ -1065,10 +1054,6 @@ video::IImage* TextureSource::generateImage(const std::string &name)
baseimg = generateImage(name.substr(0, last_separator_pos)); baseimg = generateImage(name.substr(0, last_separator_pos));
} }
video::IVideoDriver* driver = m_device->getVideoDriver();
sanity_check(driver);
/* /*
Parse out the last part of the name of the image and act Parse out the last part of the name of the image and act
according to it according to it
@ -1196,13 +1181,13 @@ bool TextureSource::generateImagePart(std::string part_of_name,
video::IImage *& baseimg) video::IImage *& baseimg)
{ {
const char escape = '\\'; // same as in generateImage() const char escape = '\\'; // same as in generateImage()
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
sanity_check(driver); sanity_check(driver);
// Stuff starting with [ are special commands // Stuff starting with [ are special commands
if (part_of_name.size() == 0 || part_of_name[0] != '[') if (part_of_name.size() == 0 || part_of_name[0] != '[')
{ {
video::IImage *image = m_sourcecache.getOrLoad(part_of_name, m_device); video::IImage *image = m_sourcecache.getOrLoad(part_of_name);
#ifdef __ANDROID__ #ifdef __ANDROID__
image = Align2Npot2(image, driver); image = Align2Npot2(image, driver);
#endif #endif
@ -1275,7 +1260,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
blit_with_alpha(image, baseimg, pos_from, pos_to, dim); blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
} else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) { } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) {
// Upscale overlying image // Upscale overlying image
video::IImage* scaled_image = m_device->getVideoDriver()-> video::IImage *scaled_image = RenderingEngine::get_video_driver()->
createImage(video::ECF_A8R8G8B8, dim_dst); createImage(video::ECF_A8R8G8B8, dim_dst);
image->copyToScaling(scaled_image); image->copyToScaling(scaled_image);
@ -1283,7 +1268,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
scaled_image->drop(); scaled_image->drop();
} else { } else {
// Upscale base image // Upscale base image
video::IImage* scaled_base = m_device->getVideoDriver()-> video::IImage *scaled_base = RenderingEngine::get_video_driver()->
createImage(video::ECF_A8R8G8B8, dim); createImage(video::ECF_A8R8G8B8, dim);
baseimg->copyToScaling(scaled_base); baseimg->copyToScaling(scaled_base);
baseimg->drop(); baseimg->drop();
@ -1333,7 +1318,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
horizontally tiled. horizontally tiled.
*/ */
video::IImage *img_crack = m_sourcecache.getOrLoad( video::IImage *img_crack = m_sourcecache.getOrLoad(
"crack_anylength.png", m_device); "crack_anylength.png");
if (img_crack) { if (img_crack) {
draw_crack(img_crack, baseimg, draw_crack(img_crack, baseimg,
@ -1855,7 +1840,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
u32 height = stoi(sf.next("")); u32 height = stoi(sf.next(""));
core::dimension2d<u32> dim(width, height); core::dimension2d<u32> dim(width, height);
video::IImage* image = m_device->getVideoDriver()-> video::IImage *image = RenderingEngine::get_video_driver()->
createImage(video::ECF_A8R8G8B8, dim); createImage(video::ECF_A8R8G8B8, dim);
baseimg->copyToScaling(image); baseimg->copyToScaling(image);
baseimg->drop(); baseimg->drop();
@ -2356,7 +2341,7 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
video::SColor TextureSource::getTextureAverageColor(const std::string &name) video::SColor TextureSource::getTextureAverageColor(const std::string &name)
{ {
video::IVideoDriver *driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
video::SColor c(0, 0, 0, 0); video::SColor c(0, 0, 0, 0);
video::ITexture *texture = getTexture(name); video::ITexture *texture = getTexture(name);
video::IImage *image = driver->createImage(texture, video::IImage *image = driver->createImage(texture,
@ -2400,7 +2385,7 @@ video::ITexture *TextureSource::getShaderFlagsTexture(bool normalmap_present)
if (isKnownSourceImage(tname)) { if (isKnownSourceImage(tname)) {
return getTexture(tname); return getTexture(tname);
} else { } else {
video::IVideoDriver *driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
video::IImage *flags_image = driver->createImage( video::IImage *flags_image = driver->createImage(
video::ECF_A8R8G8B8, core::dimension2d<u32>(1, 1)); video::ECF_A8R8G8B8, core::dimension2d<u32>(1, 1));
sanity_check(flags_image != NULL); sanity_check(flags_image != NULL);

View File

@ -69,7 +69,7 @@ void clearTextureNameCache();
namespace irr {namespace scene {class IMesh;}} namespace irr {namespace scene {class IMesh;}}
struct TextureFromMeshParams struct TextureFromMeshParams
{ {
scene::IMesh *mesh; scene::IMesh *mesh = nullptr;
core::dimension2d<u32> dim; core::dimension2d<u32> dim;
std::string rtt_texture_name; std::string rtt_texture_name;
bool delete_texture_on_shutdown; bool delete_texture_on_shutdown;
@ -92,7 +92,7 @@ public:
ISimpleTextureSource(){} ISimpleTextureSource(){}
virtual ~ISimpleTextureSource(){} virtual ~ISimpleTextureSource(){}
virtual video::ITexture* getTexture( virtual video::ITexture* getTexture(
const std::string &name, u32 *id = NULL) = 0; const std::string &name, u32 *id = nullptr) = 0;
}; };
class ITextureSource : public ISimpleTextureSource class ITextureSource : public ISimpleTextureSource
@ -104,9 +104,9 @@ public:
virtual std::string getTextureName(u32 id)=0; virtual std::string getTextureName(u32 id)=0;
virtual video::ITexture* getTexture(u32 id)=0; virtual video::ITexture* getTexture(u32 id)=0;
virtual video::ITexture* getTexture( virtual video::ITexture* getTexture(
const std::string &name, u32 *id = NULL)=0; const std::string &name, u32 *id = nullptr)=0;
virtual video::ITexture* getTextureForMesh( virtual video::ITexture* getTextureForMesh(
const std::string &name, u32 *id = NULL) = 0; const std::string &name, u32 *id = nullptr) = 0;
/*! /*!
* Returns a palette from the given texture name. * Returns a palette from the given texture name.
* The pointer is valid until the texture source is * The pointer is valid until the texture source is
@ -114,7 +114,6 @@ public:
* Should be called from the main thread. * Should be called from the main thread.
*/ */
virtual Palette* getPalette(const std::string &name) = 0; virtual Palette* getPalette(const std::string &name) = 0;
virtual IrrlichtDevice* getDevice()=0;
virtual bool isKnownSourceImage(const std::string &name)=0; virtual bool isKnownSourceImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh( virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0; const TextureFromMeshParams &params)=0;
@ -132,8 +131,7 @@ public:
virtual std::string getTextureName(u32 id)=0; virtual std::string getTextureName(u32 id)=0;
virtual video::ITexture* getTexture(u32 id)=0; virtual video::ITexture* getTexture(u32 id)=0;
virtual video::ITexture* getTexture( virtual video::ITexture* getTexture(
const std::string &name, u32 *id = NULL)=0; const std::string &name, u32 *id = nullptr)=0;
virtual IrrlichtDevice* getDevice()=0;
virtual bool isKnownSourceImage(const std::string &name)=0; virtual bool isKnownSourceImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh( virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0; const TextureFromMeshParams &params)=0;
@ -146,7 +144,7 @@ public:
virtual video::ITexture *getShaderFlagsTexture(bool normalmap_present)=0; virtual video::ITexture *getShaderFlagsTexture(bool normalmap_present)=0;
}; };
IWritableTextureSource* createTextureSource(IrrlichtDevice *device); IWritableTextureSource *createTextureSource();
#ifdef __ANDROID__ #ifdef __ANDROID__
video::IImage * Align2Npot2(video::IImage * image, video::IVideoDriver* driver); video::IImage * Align2Npot2(video::IImage * image, video::IVideoDriver* driver);
@ -158,7 +156,8 @@ enum MaterialType{
TILE_MATERIAL_LIQUID_TRANSPARENT, TILE_MATERIAL_LIQUID_TRANSPARENT,
TILE_MATERIAL_LIQUID_OPAQUE, TILE_MATERIAL_LIQUID_OPAQUE,
TILE_MATERIAL_WAVING_LEAVES, TILE_MATERIAL_WAVING_LEAVES,
TILE_MATERIAL_WAVING_PLANTS TILE_MATERIAL_WAVING_PLANTS,
TILE_MATERIAL_OPAQUE
}; };
// Material flags // Material flags
@ -180,17 +179,11 @@ enum MaterialType{
*/ */
struct FrameSpec struct FrameSpec
{ {
FrameSpec(): FrameSpec() {}
texture_id(0), u32 texture_id = 0;
texture(NULL), video::ITexture *texture = nullptr;
normal_texture(NULL), video::ITexture *normal_texture = nullptr;
flags_texture(NULL) video::ITexture *flags_texture = nullptr;
{
}
u32 texture_id;
video::ITexture *texture;
video::ITexture *normal_texture;
video::ITexture *flags_texture;
}; };
#define MAX_TILE_LAYERS 2 #define MAX_TILE_LAYERS 2
@ -198,25 +191,7 @@ struct FrameSpec
//! Defines a layer of a tile. //! Defines a layer of a tile.
struct TileLayer struct TileLayer
{ {
TileLayer(): TileLayer() {}
texture(NULL),
normal_texture(NULL),
flags_texture(NULL),
shader_id(0),
texture_id(0),
animation_frame_length_ms(0),
animation_frame_count(1),
material_type(TILE_MATERIAL_BASIC),
material_flags(
//0 // <- DEBUG, Use the one below
MATERIAL_FLAG_BACKFACE_CULLING |
MATERIAL_FLAG_TILEABLE_HORIZONTAL|
MATERIAL_FLAG_TILEABLE_VERTICAL
),
has_color(false),
color()
{
}
/*! /*!
* Two layers are equal if they can be merged. * Two layers are equal if they can be merged.
@ -242,6 +217,10 @@ struct TileLayer
void applyMaterialOptions(video::SMaterial &material) const void applyMaterialOptions(video::SMaterial &material) const
{ {
switch (material_type) { switch (material_type) {
case TILE_MATERIAL_OPAQUE:
case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID;
break;
case TILE_MATERIAL_BASIC: case TILE_MATERIAL_BASIC:
case TILE_MATERIAL_WAVING_LEAVES: case TILE_MATERIAL_WAVING_LEAVES:
case TILE_MATERIAL_WAVING_PLANTS: case TILE_MATERIAL_WAVING_PLANTS:
@ -251,9 +230,6 @@ struct TileLayer
case TILE_MATERIAL_LIQUID_TRANSPARENT: case TILE_MATERIAL_LIQUID_TRANSPARENT:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break; break;
case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID;
break;
} }
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING)
? true : false; ? true : false;
@ -287,22 +263,26 @@ struct TileLayer
// Ordered for size, please do not reorder // Ordered for size, please do not reorder
video::ITexture *texture; video::ITexture *texture = nullptr;
video::ITexture *normal_texture; video::ITexture *normal_texture = nullptr;
video::ITexture *flags_texture; video::ITexture *flags_texture = nullptr;
u32 shader_id; u32 shader_id = 0;
u32 texture_id; u32 texture_id = 0;
u16 animation_frame_length_ms; u16 animation_frame_length_ms = 0;
u8 animation_frame_count; u8 animation_frame_count = 1;
u8 material_type; u8 material_type = TILE_MATERIAL_BASIC;
u8 material_flags; u8 material_flags =
//0 // <- DEBUG, Use the one below
MATERIAL_FLAG_BACKFACE_CULLING |
MATERIAL_FLAG_TILEABLE_HORIZONTAL|
MATERIAL_FLAG_TILEABLE_VERTICAL;
//! If true, the tile has its own color. //! If true, the tile has its own color.
bool has_color; bool has_color = false;
std::vector<FrameSpec> frames; std::vector<FrameSpec> frames;
@ -318,14 +298,11 @@ struct TileLayer
*/ */
struct TileSpec struct TileSpec
{ {
TileSpec(): TileSpec() {
rotation(0),
emissive_light(0)
{
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) for (int layer = 0; layer < MAX_TILE_LAYERS; layer++)
layers[layer] = TileLayer(); layers[layer] = TileLayer();
} }
/*! /*!
* Returns true if this tile can be merged with the other tile. * Returns true if this tile can be merged with the other tile.
*/ */
@ -341,9 +318,9 @@ struct TileSpec
&& emissive_light == other.emissive_light; && emissive_light == other.emissive_light;
} }
u8 rotation; u8 rotation = 0;
//! This much light does the tile emit. //! This much light does the tile emit.
u8 emissive_light; u8 emissive_light = 0;
//! The first is base texture, the second is overlay. //! The first is base texture, the second is overlay.
TileLayer layers[MAX_TILE_LAYERS]; TileLayer layers[MAX_TILE_LAYERS];
}; };

View File

@ -31,20 +31,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "voxelalgorithms.h" #include "voxelalgorithms.h"
#include "settings.h" #include "settings.h"
#include <algorithm> #include <algorithm>
#include "client/renderingengine.h"
/* /*
ClientEnvironment ClientEnvironment
*/ */
ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, ClientEnvironment::ClientEnvironment(ClientMap *map,
ITextureSource *texturesource, Client *client, ITextureSource *texturesource, Client *client):
IrrlichtDevice *irr):
Environment(client), Environment(client),
m_map(map), m_map(map),
m_smgr(smgr),
m_texturesource(texturesource), m_texturesource(texturesource),
m_client(client), m_client(client)
m_irr(irr)
{ {
char zero = 0; char zero = 0;
memset(attachement_parent_ids, zero, sizeof(attachement_parent_ids)); memset(attachement_parent_ids, zero, sizeof(attachement_parent_ids));
@ -458,7 +456,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
infostream<<"ClientEnvironment::addActiveObject(): " infostream<<"ClientEnvironment::addActiveObject(): "
<<"added (id="<<object->getId()<<")"<<std::endl; <<"added (id="<<object->getId()<<")"<<std::endl;
m_active_objects[object->getId()] = object; m_active_objects[object->getId()] = object;
object->addToScene(m_smgr, m_texturesource, m_irr); object->addToScene(RenderingEngine::get_scene_manager(), m_texturesource);
{ // Update lighting immediately { // Update lighting immediately
u8 light = 0; u8 light = 0;
bool pos_ok; bool pos_ok;

View File

@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENT_ENVIRONMENT_HEADER #ifndef CLIENT_ENVIRONMENT_HEADER
#define CLIENT_ENVIRONMENT_HEADER #define CLIENT_ENVIRONMENT_HEADER
#include <IrrlichtDevice.h>
#include <ISceneManager.h> #include <ISceneManager.h>
#include "environment.h" #include "environment.h"
#include "clientobject.h" #include "clientobject.h"
@ -68,9 +67,7 @@ typedef std::unordered_map<u16, ClientActiveObject*> ClientActiveObjectMap;
class ClientEnvironment : public Environment class ClientEnvironment : public Environment
{ {
public: public:
ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, ClientEnvironment(ClientMap *map, ITextureSource *texturesource, Client *client);
ITextureSource *texturesource, Client *client,
IrrlichtDevice *device);
~ClientEnvironment(); ~ClientEnvironment();
Map & getMap(); Map & getMap();
@ -177,11 +174,9 @@ public:
private: private:
ClientMap *m_map; ClientMap *m_map;
LocalPlayer *m_local_player = nullptr; LocalPlayer *m_local_player = nullptr;
scene::ISceneManager *m_smgr;
ITextureSource *m_texturesource; ITextureSource *m_texturesource;
Client *m_client; Client *m_client;
ClientScripting *m_script = nullptr; ClientScripting *m_script = nullptr;
IrrlichtDevice *m_irr;
ClientActiveObjectMap m_active_objects; ClientActiveObjectMap m_active_objects;
std::vector<ClientSimpleObject*> m_simple_objects; std::vector<ClientSimpleObject*> m_simple_objects;
std::queue<ClientEnvEvent> m_client_event_queue; std::queue<ClientEnvEvent> m_client_event_queue;

View File

@ -31,16 +31,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "camera.h" // CameraModes #include "camera.h" // CameraModes
#include "util/basic_macros.h" #include "util/basic_macros.h"
#include <algorithm> #include <algorithm>
#include "client/renderingengine.h"
ClientMap::ClientMap( ClientMap::ClientMap(
Client *client, Client *client,
MapDrawControl &control, MapDrawControl &control,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id s32 id
): ):
Map(dout_client, client), Map(dout_client, client),
scene::ISceneNode(parent, mgr, id), scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
RenderingEngine::get_scene_manager(), id),
m_client(client), m_client(client),
m_control(control), m_control(control),
m_camera_position(0,0,0), m_camera_position(0,0,0),
@ -283,49 +283,45 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
struct MeshBufList struct MeshBufList
{ {
/*!
* Specifies in which layer the list is.
* All lists which are in a lower layer are rendered before this list.
*/
u8 layer;
video::SMaterial m; video::SMaterial m;
std::vector<scene::IMeshBuffer*> bufs; std::vector<scene::IMeshBuffer*> bufs;
}; };
struct MeshBufListList struct MeshBufListList
{ {
std::vector<MeshBufList> lists; /*!
* Stores the mesh buffers of the world.
* The array index is the material's layer.
* The vector part groups vertices by material.
*/
std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
void clear() void clear()
{ {
lists.clear(); for (int l = 0; l < MAX_TILE_LAYERS; l++)
lists[l].clear();
} }
void add(scene::IMeshBuffer *buf, u8 layer) void add(scene::IMeshBuffer *buf, u8 layer)
{ {
// Append to the correct layer
std::vector<MeshBufList> &list = lists[layer];
const video::SMaterial &m = buf->getMaterial(); const video::SMaterial &m = buf->getMaterial();
for(std::vector<MeshBufList>::iterator i = lists.begin(); for (MeshBufList &l : list) {
i != lists.end(); ++i){
MeshBufList &l = *i;
// comparing a full material is quite expensive so we don't do it if // comparing a full material is quite expensive so we don't do it if
// not even first texture is equal // not even first texture is equal
if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture) if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
continue; continue;
if(l.layer != layer)
continue;
if (l.m == m) { if (l.m == m) {
l.bufs.push_back(buf); l.bufs.push_back(buf);
return; return;
} }
} }
MeshBufList l; MeshBufList l;
l.layer = layer;
l.m = m; l.m = m;
l.bufs.push_back(buf); l.bufs.push_back(buf);
lists.push_back(l); list.push_back(l);
} }
}; };
@ -353,7 +349,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
Measuring time is very useful for long delays when the Measuring time is very useful for long delays when the
machine is swapping a lot. machine is swapping a lot.
*/ */
int time1 = time(0); std::time_t time1 = time(0);
/* /*
Get animation parameters Get animation parameters
@ -469,35 +465,32 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
} }
} }
std::vector<MeshBufList> &lists = drawbufs.lists; // Render all layers in order
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
std::vector<MeshBufList> &lists = drawbufs.lists[layer];
int timecheck_counter = 0; int timecheck_counter = 0;
for (std::vector<MeshBufList>::iterator i = lists.begin(); for (MeshBufList &list : lists) {
i != lists.end(); ++i) { timecheck_counter++;
timecheck_counter++; if (timecheck_counter > 50) {
if (timecheck_counter > 50) { timecheck_counter = 0;
timecheck_counter = 0; std::time_t time2 = time(0);
int time2 = time(0); if (time2 > time1 + 4) {
if (time2 > time1 + 4) { infostream << "ClientMap::renderMap(): "
infostream << "ClientMap::renderMap(): " "Rendering takes ages, returning."
"Rendering takes ages, returning." << std::endl;
<< std::endl; return;
return; }
}
driver->setMaterial(list.m);
for (scene::IMeshBuffer *buf : list.bufs) {
driver->drawMeshBuffer(buf);
vertex_count += buf->getVertexCount();
meshbuffer_count++;
} }
} }
MeshBufList &list = *i;
driver->setMaterial(list.m);
for (std::vector<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
j != list.bufs.end(); ++j) {
scene::IMeshBuffer *buf = *j;
driver->drawMeshBuffer(buf);
vertex_count += buf->getVertexCount();
meshbuffer_count++;
}
} }
} // ScopeProfiler } // ScopeProfiler

View File

@ -59,8 +59,6 @@ public:
ClientMap( ClientMap(
Client *client, Client *client,
MapDrawControl &control, MapDrawControl &control,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id s32 id
); );

View File

@ -39,9 +39,8 @@ public:
ClientActiveObject(u16 id, Client *client, ClientEnvironment *env); ClientActiveObject(u16 id, Client *client, ClientEnvironment *env);
virtual ~ClientActiveObject(); virtual ~ClientActiveObject();
virtual void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, virtual void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc) {};
IrrlichtDevice *irr){} virtual void removeFromScene(bool permanent) {}
virtual void removeFromScene(bool permanent){}
// 0 <= light_at_pos <= LIGHT_SUN // 0 <= light_at_pos <= LIGHT_SUN
virtual void updateLight(u8 light_at_pos){} virtual void updateLight(u8 light_at_pos){}
virtual void updateLightNoCheck(u8 light_at_pos){} virtual void updateLightNoCheck(u8 light_at_pos){}

View File

@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "client/renderingengine.h"
#include "clouds.h" #include "clouds.h"
#include "noise.h" #include "noise.h"
#include "constants.h" #include "constants.h"
@ -36,14 +37,12 @@ static void cloud_3d_setting_changed(const std::string &settingname, void *data)
((Clouds *)data)->readSettings(); ((Clouds *)data)->readSettings();
} }
Clouds::Clouds( Clouds::Clouds(scene::ISceneManager* mgr,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id, s32 id,
u32 seed, u32 seed,
s16 cloudheight s16 cloudheight
): ):
scene::ISceneNode(parent, mgr, id), scene::ISceneNode(mgr->getRootSceneNode(), mgr, id),
m_seed(seed) m_seed(seed)
{ {
m_material.setFlag(video::EMF_LIGHTING, false); m_material.setFlag(video::EMF_LIGHTING, false);
@ -101,22 +100,22 @@ void Clouds::render()
return; return;
ScopeProfiler sp(g_profiler, "Rendering of clouds, avg", SPT_AVG); ScopeProfiler sp(g_profiler, "Rendering of clouds, avg", SPT_AVG);
int num_faces_to_draw = m_enable_3d ? 6 : 1; int num_faces_to_draw = m_enable_3d ? 6 : 1;
m_material.setFlag(video::EMF_BACK_FACE_CULLING, m_enable_3d); m_material.setFlag(video::EMF_BACK_FACE_CULLING, m_enable_3d);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(m_material); driver->setMaterial(m_material);
/* /*
Clouds move from Z+ towards Z- Clouds move from Z+ towards Z-
*/ */
static const float cloud_size = BS * 64.0f; static const float cloud_size = BS * 64.0f;
const float cloud_full_radius = cloud_size * m_cloud_radius_i; const float cloud_full_radius = cloud_size * m_cloud_radius_i;
// Position of cloud noise origin from the camera // Position of cloud noise origin from the camera
v2f cloud_origin_from_camera_f = m_origin - m_camera_pos; v2f cloud_origin_from_camera_f = m_origin - m_camera_pos;
// The center point of drawing in the noise // The center point of drawing in the noise
@ -164,7 +163,7 @@ void Clouds::render()
bool fog_rangefog = false; bool fog_rangefog = false;
driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density, driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog); fog_pixelfog, fog_rangefog);
// Set our own fog // Set our own fog
driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5, driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5,
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog); cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
@ -340,7 +339,7 @@ void Clouds::render()
} }
delete[] grid; delete[] grid;
// Restore fog settings // Restore fog settings
driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density, driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog); fog_pixelfog, fog_rangefog);

View File

@ -36,9 +36,7 @@ extern irr::scene::ISceneManager *g_menucloudsmgr;
class Clouds : public scene::ISceneNode class Clouds : public scene::ISceneNode
{ {
public: public:
Clouds( Clouds(scene::ISceneManager* mgr,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id, s32 id,
u32 seed, u32 seed,
s16 cloudheight=0 s16 cloudheight=0

View File

@ -128,8 +128,7 @@ public:
static ClientActiveObject* create(Client *client, ClientEnvironment *env); static ClientActiveObject* create(Client *client, ClientEnvironment *env);
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc);
IrrlichtDevice *irr);
void removeFromScene(bool permanent); void removeFromScene(bool permanent);
void updateLight(u8 light_at_pos); void updateLight(u8 light_at_pos);
v3s16 getLightPosition(); v3s16 getLightPosition();
@ -165,8 +164,7 @@ ClientActiveObject* TestCAO::create(Client *client, ClientEnvironment *env)
return new TestCAO(client, env); return new TestCAO(client, env);
} }
void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
IrrlichtDevice *irr)
{ {
if(m_node != NULL) if(m_node != NULL)
return; return;
@ -272,8 +270,7 @@ public:
static ClientActiveObject* create(Client *client, ClientEnvironment *env); static ClientActiveObject* create(Client *client, ClientEnvironment *env);
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc);
IrrlichtDevice *irr);
void removeFromScene(bool permanent); void removeFromScene(bool permanent);
void updateLight(u8 light_at_pos); void updateLight(u8 light_at_pos);
v3s16 getLightPosition(); v3s16 getLightPosition();
@ -329,8 +326,7 @@ ClientActiveObject* ItemCAO::create(Client *client, ClientEnvironment *env)
return new ItemCAO(client, env); return new ItemCAO(client, env);
} }
void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
IrrlichtDevice *irr)
{ {
if(m_node != NULL) if(m_node != NULL)
return; return;
@ -721,11 +717,9 @@ void GenericCAO::removeFromScene(bool permanent)
} }
} }
void GenericCAO::addToScene(scene::ISceneManager *smgr, void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
ITextureSource *tsrc, IrrlichtDevice *irr)
{ {
m_smgr = smgr; m_smgr = smgr;
m_irr = irr;
if (getSceneNode() != NULL) { if (getSceneNode() != NULL) {
return; return;
@ -1034,7 +1028,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
} }
} }
if(m_visuals_expired && m_smgr && m_irr){ if (m_visuals_expired && m_smgr) {
m_visuals_expired = false; m_visuals_expired = false;
// Attachments, part 1: All attached objects must be unparented first, // Attachments, part 1: All attached objects must be unparented first,
@ -1056,7 +1050,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
} }
removeFromScene(false); removeFromScene(false);
addToScene(m_smgr, m_client->tsrc(), m_irr); addToScene(m_smgr, m_client->tsrc());
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back // Attachments, part 2: Now that the parent has been refreshed, put its attachments back
for (std::vector<u16>::size_type i = 0; i < m_children.size(); i++) { for (std::vector<u16>::size_type i = 0; i < m_children.size(); i++) {

View File

@ -65,7 +65,6 @@ private:
ObjectProperties m_prop; ObjectProperties m_prop;
// //
scene::ISceneManager *m_smgr = nullptr; scene::ISceneManager *m_smgr = nullptr;
IrrlichtDevice *m_irr = nullptr;
Client *m_client = nullptr; Client *m_client = nullptr;
aabb3f m_selection_box = aabb3f(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.); aabb3f m_selection_box = aabb3f(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.);
scene::IMeshSceneNode *m_meshnode = nullptr; scene::IMeshSceneNode *m_meshnode = nullptr;
@ -169,8 +168,7 @@ public:
void removeFromScene(bool permanent); void removeFromScene(bool permanent);
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc);
IrrlichtDevice *irr);
inline void expireVisuals() inline void expireVisuals()
{ {

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/tile.h" #include "client/tile.h"
#include "mesh.h" #include "mesh.h"
#include <IMeshManipulator.h> #include <IMeshManipulator.h>
#include "client/renderingengine.h"
#include "client.h" #include "client.h"
#include "log.h" #include "log.h"
#include "noise.h" #include "noise.h"
@ -64,8 +65,7 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
collector = output; collector = output;
nodedef = data->m_client->ndef(); nodedef = data->m_client->ndef();
smgr = data->m_client->getSceneManager(); meshmanip = RenderingEngine::get_scene_manager()->getMeshManipulator();
meshmanip = smgr->getMeshManipulator();
enable_mesh_cache = g_settings->getBool("enable_mesh_cache") && enable_mesh_cache = g_settings->getBool("enable_mesh_cache") &&
!data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting !data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting

View File

@ -39,7 +39,6 @@ public:
MeshCollector *collector; MeshCollector *collector;
INodeDefManager *nodedef; INodeDefManager *nodedef;
scene::ISceneManager *smgr;
scene::IMeshManipulator *meshmanip; scene::IMeshManipulator *meshmanip;
// options // options

View File

@ -23,9 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "database-postgresql.h" #include "database-postgresql.h"
#ifdef _WIN32 #ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// Without this some of the network functions are not found on mingw // Without this some of the network functions are not found on mingw
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0501
@ -584,7 +581,7 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
if (itemStr.length() > 0) { if (itemStr.length() > 0) {
ItemStack stack; ItemStack stack;
stack.deSerialize(itemStr); stack.deSerialize(itemStr);
invList->addItem(pg_to_uint(results2, row2, 0), stack); invList->changeItem(pg_to_uint(results2, row2, 0), stack);
} }
} }
PQclear(results2); PQclear(results2);

View File

@ -565,7 +565,7 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
if (itemStr.length() > 0) { if (itemStr.length() > 0) {
ItemStack stack; ItemStack stack;
stack.deSerialize(itemStr); stack.deSerialize(itemStr);
invList->addItem(sqlite_to_uint(m_stmt_player_load_inventory_items, 0), stack); invList->changeItem(sqlite_to_uint(m_stmt_player_load_inventory_items, 0), stack);
} }
} }
sqlite3_reset(m_stmt_player_load_inventory_items); sqlite3_reset(m_stmt_player_load_inventory_items);

View File

@ -26,8 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gettime.h" #include "gettime.h"
#include "log.h" #include "log.h"
#if (defined(WIN32) || defined(_WIN32_WCE)) #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0501
#endif #endif

View File

@ -172,6 +172,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("ambient_occlusion_gamma", "2.2"); settings->setDefault("ambient_occlusion_gamma", "2.2");
settings->setDefault("enable_shaders", "true"); settings->setDefault("enable_shaders", "true");
settings->setDefault("enable_particles", "true"); settings->setDefault("enable_particles", "true");
settings->setDefault("arm_inertia", "true");
settings->setDefault("enable_minimap", "true"); settings->setDefault("enable_minimap", "true");
settings->setDefault("minimap_shape_round", "true"); settings->setDefault("minimap_shape_round", "true");

View File

@ -1,674 +0,0 @@
/*
Minetest
Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
*/
#include "drawscene.h"
#include "settings.h"
#include "clouds.h"
#include "clientmap.h"
#include "util/timetaker.h"
#include "fontengine.h"
#include "guiscalingfilter.h"
#include "filesys.h"
typedef enum {
LEFT = -1,
RIGHT = 1,
EYECOUNT = 2
} paralax_sign;
void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud,
video::IVideoDriver* driver, scene::ISceneManager* smgr,
bool draw_wield_tool, Client& client,
gui::IGUIEnvironment* guienv )
{
/* preserve old setup*/
irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
irr::core::matrix4 startMatrix =
camera.getCameraNode()->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
- camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+ camera.getCameraNode()->getAbsolutePosition();
//Left eye...
irr::core::vector3df leftEye;
irr::core::matrix4 leftMove;
leftMove.setTranslation(
irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
0.0f, 0.0f));
leftEye = (startMatrix * leftMove).getTranslation();
//clear the depth buffer, and color
driver->beginScene( true, true, irr::video::SColor(0, 200, 200, 255));
driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
+ irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
+ irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
camera.getCameraNode()->setPosition(leftEye);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool)
camera.drawWieldedTool(&leftMove);
}
guienv->drawAll();
//Right eye...
irr::core::vector3df rightEye;
irr::core::matrix4 rightMove;
rightMove.setTranslation(
irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
0.0f, 0.0f));
rightEye = (startMatrix * rightMove).getTranslation();
//clear the depth buffer
driver->clearZBuffer();
driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN
+ irr::video::ECP_BLUE;
driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
+ irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
+ irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
camera.getCameraNode()->setPosition(rightEye);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool)
camera.drawWieldedTool(&rightMove);
}
guienv->drawAll();
driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL;
driver->getOverrideMaterial().EnableFlags = 0;
driver->getOverrideMaterial().EnablePasses = 0;
camera.getCameraNode()->setPosition(oldPosition);
camera.getCameraNode()->setTarget(oldTarget);
}
void init_texture(video::IVideoDriver* driver, const v2u32& screensize,
video::ITexture** texture, const char* name)
{
if (*texture != NULL)
{
driver->removeTexture(*texture);
}
*texture = driver->addRenderTargetTexture(
core::dimension2d<u32>(screensize.X, screensize.Y), name,
irr::video::ECF_A8R8G8B8);
}
video::ITexture* draw_image(const v2u32 &screensize,
paralax_sign psign, const irr::core::matrix4 &startMatrix,
const irr::core::vector3df &focusPoint, bool show_hud,
video::IVideoDriver *driver, Camera &camera, scene::ISceneManager *smgr,
Hud &hud, bool draw_wield_tool, Client &client,
gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
{
static video::ITexture* images[2] = { NULL, NULL };
static v2u32 last_screensize = v2u32(0, 0);
video::ITexture* image = NULL;
if (screensize != last_screensize) {
init_texture(driver, screensize, &images[1], "mt_drawimage_img1");
init_texture(driver, screensize, &images[0], "mt_drawimage_img2");
last_screensize = screensize;
}
if (psign == RIGHT)
image = images[1];
else
image = images[0];
driver->setRenderTarget(image, true, true,
irr::video::SColor(255,
skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
irr::core::vector3df eye_pos;
irr::core::matrix4 movement;
movement.setTranslation(
irr::core::vector3df((int) psign *
g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
eye_pos = (startMatrix * movement).getTranslation();
//clear the depth buffer
driver->clearZBuffer();
camera.getCameraNode()->setPosition(eye_pos);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool)
camera.drawWieldedTool(&movement);
}
guienv->drawAll();
/* switch back to real renderer */
driver->setRenderTarget(0, true, true,
irr::video::SColor(0,
skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
return image;
}
video::ITexture* draw_hud(video::IVideoDriver* driver, const v2u32& screensize,
bool show_hud, Hud& hud, Client& client, bool draw_crosshair,
video::SColor skycolor, gui::IGUIEnvironment* guienv, Camera& camera )
{
static video::ITexture* image = NULL;
init_texture(driver, screensize, &image, "mt_drawimage_hud");
driver->setRenderTarget(image, true, true,
irr::video::SColor(255,0,0,0));
if (show_hud)
{
if (draw_crosshair)
hud.drawCrosshair();
hud.drawHotbar(client.getPlayerItem());
hud.drawLuaElements(camera.getOffset());
camera.drawNametags();
guienv->drawAll();
}
driver->setRenderTarget(0, true, true,
irr::video::SColor(0,
skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
return image;
}
void draw_interlaced_3d_mode(Camera& camera, bool show_hud,
Hud& hud, video::IVideoDriver* driver,
scene::ISceneManager* smgr, const v2u32& screensize,
bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
video::SColor skycolor )
{
/* save current info */
irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
irr::core::matrix4 startMatrix =
camera.getCameraNode()->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
- camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+ camera.getCameraNode()->getAbsolutePosition();
/* create left view */
video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
focusPoint, show_hud, driver, camera, smgr, hud,
draw_wield_tool, client, guienv, skycolor);
//Right eye...
irr::core::vector3df rightEye;
irr::core::matrix4 rightMove;
rightMove.setTranslation(
irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
0.0f, 0.0f));
rightEye = (startMatrix * rightMove).getTranslation();
//clear the depth buffer
driver->clearZBuffer();
camera.getCameraNode()->setPosition(rightEye);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if(draw_wield_tool)
camera.drawWieldedTool(&rightMove);
}
guienv->drawAll();
for (unsigned int i = 0; i < screensize.Y; i+=2 ) {
#if (IRRLICHT_VERSION_MAJOR >= 1) && (IRRLICHT_VERSION_MINOR >= 8)
driver->draw2DImage(left_image, irr::core::position2d<s32>(0, i),
#else
driver->draw2DImage(left_image, irr::core::position2d<s32>(0, screensize.Y-i),
#endif
irr::core::rect<s32>(0, i,screensize.X, i+1), 0,
irr::video::SColor(255, 255, 255, 255),
false);
}
/* cleanup */
camera.getCameraNode()->setPosition(oldPosition);
camera.getCameraNode()->setTarget(oldTarget);
}
void draw_sidebyside_3d_mode(Camera& camera, bool show_hud,
Hud& hud, video::IVideoDriver* driver,
scene::ISceneManager* smgr, const v2u32& screensize,
bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
video::SColor skycolor )
{
/* save current info */
irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
irr::core::matrix4 startMatrix =
camera.getCameraNode()->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
- camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+ camera.getCameraNode()->getAbsolutePosition();
/* create left view */
video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
focusPoint, show_hud, driver, camera, smgr, hud,
draw_wield_tool, client, guienv, skycolor);
/* create right view */
video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
focusPoint, show_hud, driver, camera, smgr, hud,
draw_wield_tool, client, guienv, skycolor);
/* create hud overlay */
video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
false, skycolor, guienv, camera );
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
//makeColorKeyTexture mirrors texture so we do it twice to get it right again
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
draw2DImageFilterScaled(driver, left_image,
irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
draw2DImageFilterScaled(driver, right_image,
irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
left_image = NULL;
right_image = NULL;
/* cleanup */
camera.getCameraNode()->setPosition(oldPosition);
camera.getCameraNode()->setTarget(oldTarget);
}
void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
Hud& hud, video::IVideoDriver* driver,
scene::ISceneManager* smgr, const v2u32& screensize,
bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
video::SColor skycolor )
{
/* save current info */
irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
irr::core::matrix4 startMatrix =
camera.getCameraNode()->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
- camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+ camera.getCameraNode()->getAbsolutePosition();
/* create left view */
video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
focusPoint, show_hud, driver, camera, smgr, hud,
draw_wield_tool, client, guienv, skycolor);
/* create right view */
video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
focusPoint, show_hud, driver, camera, smgr, hud,
draw_wield_tool, client, guienv, skycolor);
/* create hud overlay */
video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
false, skycolor, guienv, camera );
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
//makeColorKeyTexture mirrors texture so we do it twice to get it right again
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
draw2DImageFilterScaled(driver, left_image,
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
draw2DImageFilterScaled(driver, right_image,
irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
left_image = NULL;
right_image = NULL;
/* cleanup */
camera.getCameraNode()->setPosition(oldPosition);
camera.getCameraNode()->setTarget(oldTarget);
}
void draw_pageflip_3d_mode(Camera& camera, bool show_hud,
Hud& hud, video::IVideoDriver* driver,
scene::ISceneManager* smgr, const v2u32& screensize,
bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
video::SColor skycolor)
{
#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
errorstream << "Pageflip 3D mode is not supported"
<< " with your Irrlicht version!" << std::endl;
#else
/* preserve old setup*/
irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
irr::core::matrix4 startMatrix =
camera.getCameraNode()->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
- camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+ camera.getCameraNode()->getAbsolutePosition();
//Left eye...
driver->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER);
irr::core::vector3df leftEye;
irr::core::matrix4 leftMove;
leftMove.setTranslation(
irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
0.0f, 0.0f));
leftEye = (startMatrix * leftMove).getTranslation();
//clear the depth buffer, and color
driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
camera.getCameraNode()->setPosition(leftEye);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool)
camera.drawWieldedTool(&leftMove);
hud.drawHotbar(client.getPlayerItem());
hud.drawLuaElements(camera.getOffset());
camera.drawNametags();
}
guienv->drawAll();
//Right eye...
driver->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER);
irr::core::vector3df rightEye;
irr::core::matrix4 rightMove;
rightMove.setTranslation(
irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
0.0f, 0.0f));
rightEye = (startMatrix * rightMove).getTranslation();
//clear the depth buffer, and color
driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
camera.getCameraNode()->setPosition(rightEye);
camera.getCameraNode()->setTarget(focusPoint);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool)
camera.drawWieldedTool(&rightMove);
hud.drawHotbar(client.getPlayerItem());
hud.drawLuaElements(camera.getOffset());
camera.drawNametags();
}
guienv->drawAll();
camera.getCameraNode()->setPosition(oldPosition);
camera.getCameraNode()->setTarget(oldTarget);
#endif
}
// returns (size / coef), rounded upwards
inline int scaledown(int coef, int size)
{
return (size + coef - 1) / coef;
}
void draw_plain(Camera &camera, bool show_hud,
Hud &hud, video::IVideoDriver *driver,
scene::ISceneManager *smgr, const v2u32 &screensize,
bool draw_wield_tool, Client &client, gui::IGUIEnvironment *guienv,
video::SColor skycolor)
{
// Undersampling-specific stuff
static video::ITexture *image = NULL;
static v2u32 last_pixelated_size = v2u32(0, 0);
static thread_local int undersampling = g_settings->getU16("undersampling");
v2u32 pixelated_size;
v2u32 dest_size;
if (undersampling > 0) {
pixelated_size = v2u32(scaledown(undersampling, screensize.X),
scaledown(undersampling, screensize.Y));
dest_size = v2u32(undersampling * pixelated_size.X, undersampling * pixelated_size.Y);
if (pixelated_size != last_pixelated_size) {
init_texture(driver, pixelated_size, &image, "mt_drawimage_img1");
last_pixelated_size = pixelated_size;
}
driver->setRenderTarget(image, true, true, skycolor);
}
// Render
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) {
hud.drawSelectionMesh();
if (draw_wield_tool) {
camera.drawWieldedTool();
}
}
// Upscale lowres render
if (undersampling > 0) {
driver->setRenderTarget(0, true, true);
driver->draw2DImage(image,
irr::core::rect<s32>(0, 0, dest_size.X, dest_size.Y),
irr::core::rect<s32>(0, 0, pixelated_size.X, pixelated_size.Y));
}
}
void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr,
Camera &camera, Client &client, LocalPlayer *player, Hud &hud,
Minimap *mapper, gui::IGUIEnvironment *guienv,
const v2u32 &screensize, const video::SColor &skycolor,
bool show_hud, bool show_minimap)
{
TimeTaker timer("smgr");
bool draw_wield_tool = (show_hud &&
(player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
camera.getCameraMode() < CAMERA_MODE_THIRD );
bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
(camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT));
#ifdef HAVE_TOUCHSCREENGUI
try {
draw_crosshair = !g_settings->getBool("touchtarget");
}
catch(SettingNotFoundException) {}
#endif
const std::string &draw_mode = g_settings->get("3d_mode");
if (draw_mode == "anaglyph")
{
draw_anaglyph_3d_mode(camera, show_hud, hud, driver,
smgr, draw_wield_tool, client, guienv);
draw_crosshair = false;
}
else if (draw_mode == "interlaced")
{
draw_interlaced_3d_mode(camera, show_hud, hud, driver,
smgr, screensize, draw_wield_tool, client, guienv, skycolor);
draw_crosshair = false;
}
else if (draw_mode == "sidebyside")
{
draw_sidebyside_3d_mode(camera, show_hud, hud, driver,
smgr, screensize, draw_wield_tool, client, guienv, skycolor);
show_hud = false;
}
else if (draw_mode == "topbottom")
{
draw_top_bottom_3d_mode(camera, show_hud, hud, driver,
smgr, screensize, draw_wield_tool, client, guienv, skycolor);
show_hud = false;
}
else if (draw_mode == "pageflip")
{
draw_pageflip_3d_mode(camera, show_hud, hud, driver,
smgr, screensize, draw_wield_tool, client, guienv, skycolor);
draw_crosshair = false;
show_hud = false;
}
else {
draw_plain(camera, show_hud, hud, driver,
smgr, screensize, draw_wield_tool, client, guienv, skycolor);
}
/*
Post effects
*/
{
client.getEnv().getClientMap().renderPostFx(camera.getCameraMode());
}
//TODO how to make those 3d too
if (show_hud)
{
if (draw_crosshair)
hud.drawCrosshair();
hud.drawHotbar(client.getPlayerItem());
hud.drawLuaElements(camera.getOffset());
camera.drawNametags();
if (mapper && show_minimap)
mapper->drawMinimap();
}
guienv->drawAll();
timer.stop(true);
}
/*
Draws a screen with a single text on it.
Text will be removed when the screen is drawn the next time.
Additionally, a progressbar can be drawn when percent is set between 0 and 100.
*/
void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
gui::IGUIEnvironment* guienv, ITextureSource *tsrc,
float dtime, int percent, bool clouds)
{
video::IVideoDriver* driver = device->getVideoDriver();
v2u32 screensize = porting::getWindowSize();
v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight());
v2s32 center(screensize.X / 2, screensize.Y / 2);
core::rect<s32> textrect(center - textsize / 2, center + textsize / 2);
gui::IGUIStaticText *guitext = guienv->addStaticText(
text.c_str(), textrect, false, false);
guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
if (cloud_menu_background)
{
g_menuclouds->step(dtime*3);
g_menuclouds->render();
driver->beginScene(true, true, video::SColor(255, 140, 186, 250));
g_menucloudsmgr->drawAll();
}
else
driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
// draw progress bar
if ((percent >= 0) && (percent <= 100)) {
video::ITexture *progress_img = tsrc->getTexture("progress_bar.png");
video::ITexture *progress_img_bg = tsrc->getTexture("progress_bar_bg.png");
if (progress_img && progress_img_bg) {
#ifndef __ANDROID__
const core::dimension2d<u32> &img_size = progress_img_bg->getSize();
u32 imgW = rangelim(img_size.Width, 200, 600);
u32 imgH = rangelim(img_size.Height, 24, 72);
#else
const core::dimension2d<u32> img_size(256, 48);
float imgRatio = (float) img_size.Height / img_size.Width;
u32 imgW = screensize.X / 2.2f;
u32 imgH = floor(imgW * imgRatio);
#endif
v2s32 img_pos((screensize.X - imgW) / 2, (screensize.Y - imgH) / 2);
draw2DImageFilterScaled(
driver, progress_img_bg,
core::rect<s32>(img_pos.X,
img_pos.Y,
img_pos.X + imgW,
img_pos.Y + imgH),
core::rect<s32>(0, 0,
img_size.Width,
img_size.Height),
0, 0, true);
draw2DImageFilterScaled(
driver, progress_img,
core::rect<s32>(img_pos.X,
img_pos.Y,
img_pos.X + (percent * imgW) / 100,
img_pos.Y + imgH),
core::rect<s32>(0, 0,
(percent * img_size.Width) / 100,
img_size.Height),
0, 0, true);
}
}
guienv->drawAll();
driver->endScene();
guitext->remove();
//return guitext;
}

View File

@ -1,39 +0,0 @@
/*
Minetest
Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
*/
#ifndef DRAWSCENE_H_
#define DRAWSCENE_H_
#include "camera.h"
#include "hud.h"
#include "minimap.h"
#include "irrlichttypes_extrabloated.h"
void draw_load_screen(const std::wstring &text, IrrlichtDevice *device,
gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime = 0,
int percent = 0, bool clouds = true);
void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr,
Camera &camera, Client &client, LocalPlayer *player,
Hud &hud, Minimap *mapper, gui::IGUIEnvironment *guienv,
const v2u32 &screensize, const video::SColor &skycolor,
bool show_hud, bool show_minimap);
#endif /* DRAWSCENE_H_ */

View File

@ -16,16 +16,16 @@ 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., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "fontengine.h" #include "fontengine.h"
#include "log.h" #include "client/renderingengine.h"
#include "config.h" #include "config.h"
#include "porting.h" #include "porting.h"
#include "constants.h"
#include "filesys.h" #include "filesys.h"
#if USE_FREETYPE #if USE_FREETYPE
#include "gettext.h" #include "gettext.h"
#include "xCGUITTFont.h" #include "irrlicht_changes/CGUITTFont.h"
#endif #endif
/** maximum size distance for getting a "similar" font size */ /** maximum size distance for getting a "similar" font size */
@ -314,10 +314,8 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode)
if (! is_yes(m_settings->get("freetype"))) { if (! is_yes(m_settings->get("freetype"))) {
return; return;
} }
unsigned int size = floor( unsigned int size = floor(RenderingEngine::getDisplayDensity() *
porting::getDisplayDensity() * m_settings->getFloat("gui_scaling") * basesize);
m_settings->getFloat("gui_scaling") *
basesize);
u32 font_shadow = 0; u32 font_shadow = 0;
u32 font_shadow_alpha = 0; u32 font_shadow_alpha = 0;
@ -395,7 +393,7 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
basesize = DEFAULT_FONT_SIZE; basesize = DEFAULT_FONT_SIZE;
unsigned int size = floor( unsigned int size = floor(
porting::getDisplayDensity() * RenderingEngine::getDisplayDensity() *
m_settings->getFloat("gui_scaling") * m_settings->getFloat("gui_scaling") *
basesize); basesize);

View File

@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "game.h" #include "game.h"
#include <iomanip> #include <iomanip>
#include "client/renderingengine.h"
#include "camera.h" #include "camera.h"
#include "client.h" #include "client.h"
#include "client/inputhandler.h" #include "client/inputhandler.h"
@ -30,7 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clouds.h" #include "clouds.h"
#include "config.h" #include "config.h"
#include "content_cao.h" #include "content_cao.h"
#include "drawscene.h"
#include "event_manager.h" #include "event_manager.h"
#include "fontengine.h" #include "fontengine.h"
#include "itemdef.h" #include "itemdef.h"
@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiVolumeChange.h" #include "guiVolumeChange.h"
#include "mainmenumanager.h" #include "mainmenumanager.h"
#include "mapblock.h" #include "mapblock.h"
#include "minimap.h"
#include "nodedef.h" // Needed for determining pointing to nodes #include "nodedef.h" // Needed for determining pointing to nodes
#include "nodemetadata.h" #include "nodemetadata.h"
#include "particles.h" #include "particles.h"
@ -152,6 +153,9 @@ struct LocalFormspecHandler : public TextDest
if (fields.find("btn_exit_os") != fields.end()) { if (fields.find("btn_exit_os") != fields.end()) {
g_gamecallback->exitToOS(); g_gamecallback->exitToOS();
#ifndef __ANDROID__
RenderingEngine::get_raw_device()->closeDevice();
#endif
return; return;
} }
@ -726,7 +730,6 @@ public:
minimap_yaw.getAs3Values(minimap_yaw_array); minimap_yaw.getAs3Values(minimap_yaw_array);
#endif #endif
m_minimap_yaw.set(minimap_yaw_array, services); m_minimap_yaw.set(minimap_yaw_array, services);
} }
SamplerLayer_t base_tex = 0, SamplerLayer_t base_tex = 0,
@ -774,8 +777,8 @@ public:
}; };
bool nodePlacementPrediction(Client &client, bool nodePlacementPrediction(Client &client, const ItemDefinition &playeritem_def,
const ItemDefinition &playeritem_def, v3s16 nodepos, v3s16 neighbourpos) const ItemStack &playeritem, v3s16 nodepos, v3s16 neighbourpos)
{ {
std::string prediction = playeritem_def.node_placement_prediction; std::string prediction = playeritem_def.node_placement_prediction;
INodeDefManager *nodedef = client.ndef(); INodeDefManager *nodedef = client.ndef();
@ -818,11 +821,13 @@ bool nodePlacementPrediction(Client &client,
return false; return false;
} }
const ContentFeatures &predicted_f = nodedef->get(id);
// Predict param2 for facedir and wallmounted nodes // Predict param2 for facedir and wallmounted nodes
u8 param2 = 0; u8 param2 = 0;
if (nodedef->get(id).param_type_2 == CPT2_WALLMOUNTED || if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
nodedef->get(id).param_type_2 == CPT2_COLORED_WALLMOUNTED) { predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
v3s16 dir = nodepos - neighbourpos; v3s16 dir = nodepos - neighbourpos;
if (abs(dir.Y) > MYMAX(abs(dir.X), abs(dir.Z))) { if (abs(dir.Y) > MYMAX(abs(dir.X), abs(dir.Z))) {
@ -834,8 +839,8 @@ bool nodePlacementPrediction(Client &client,
} }
} }
if (nodedef->get(id).param_type_2 == CPT2_FACEDIR || if (predicted_f.param_type_2 == CPT2_FACEDIR ||
nodedef->get(id).param_type_2 == CPT2_COLORED_FACEDIR) { predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
v3s16 dir = nodepos - floatToInt(client.getEnv().getLocalPlayer()->getPosition(), BS); v3s16 dir = nodepos - floatToInt(client.getEnv().getLocalPlayer()->getPosition(), BS);
if (abs(dir.X) > abs(dir.Z)) { if (abs(dir.X) > abs(dir.Z)) {
@ -848,7 +853,7 @@ bool nodePlacementPrediction(Client &client,
assert(param2 <= 5); assert(param2 <= 5);
//Check attachment if node is in group attached_node //Check attachment if node is in group attached_node
if (((ItemGroupList) nodedef->get(id).groups)["attached_node"] != 0) { if (((ItemGroupList) predicted_f.groups)["attached_node"] != 0) {
static v3s16 wallmounted_dirs[8] = { static v3s16 wallmounted_dirs[8] = {
v3s16(0, 1, 0), v3s16(0, 1, 0),
v3s16(0, -1, 0), v3s16(0, -1, 0),
@ -859,8 +864,8 @@ bool nodePlacementPrediction(Client &client,
}; };
v3s16 pp; v3s16 pp;
if (nodedef->get(id).param_type_2 == CPT2_WALLMOUNTED || if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
nodedef->get(id).param_type_2 == CPT2_COLORED_WALLMOUNTED) predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)
pp = p + wallmounted_dirs[param2]; pp = p + wallmounted_dirs[param2];
else else
pp = p + v3s16(0, -1, 0); pp = p + v3s16(0, -1, 0);
@ -869,6 +874,28 @@ bool nodePlacementPrediction(Client &client,
return false; return false;
} }
// Apply color
if ((predicted_f.param_type_2 == CPT2_COLOR
|| predicted_f.param_type_2 == CPT2_COLORED_FACEDIR
|| predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
const std::string &indexstr = playeritem.metadata.getString(
"palette_index", 0);
if (!indexstr.empty()) {
s32 index = mystoi(indexstr);
if (predicted_f.param_type_2 == CPT2_COLOR) {
param2 = index;
} else if (predicted_f.param_type_2
== CPT2_COLORED_WALLMOUNTED) {
// param2 = pure palette index + other
param2 = (index & 0xf8) | (param2 & 0x07);
} else if (predicted_f.param_type_2
== CPT2_COLORED_FACEDIR) {
// param2 = pure palette index + other
param2 = (index & 0xe0) | (param2 & 0x1f);
}
}
}
// Add node to client map // Add node to client map
MapNode n(id, 0, param2); MapNode n(id, 0, param2);
@ -900,14 +927,13 @@ bool nodePlacementPrediction(Client &client,
} }
static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec, static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
Client *client, IrrlichtDevice *device, JoystickController *joystick, Client *client, JoystickController *joystick,
IFormSource *fs_src, TextDest *txt_dest) IFormSource *fs_src, TextDest *txt_dest)
{ {
if (*cur_formspec == 0) { if (*cur_formspec == 0) {
*cur_formspec = new GUIFormSpecMenu(device, joystick, *cur_formspec = new GUIFormSpecMenu(joystick, guiroot, -1, &g_menumgr,
guiroot, -1, &g_menumgr, client, client->getTextureSource(), client, client->getTextureSource(), fs_src, txt_dest);
fs_src, txt_dest);
(*cur_formspec)->doPause = false; (*cur_formspec)->doPause = false;
/* /*
@ -972,9 +998,10 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
chat_y += line_height; chat_y += line_height;
// first pass to calculate height of text to be set // first pass to calculate height of text to be set
const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
s32 width = std::min(g_fontengine->getTextWidth(recent_chat.c_str()) + 10, s32 width = std::min(g_fontengine->getTextWidth(recent_chat.c_str()) + 10,
porting::getWindowSize().X - 20); window_size.X - 20);
core::rect<s32> rect(10, chat_y, width, chat_y + porting::getWindowSize().Y); core::rect<s32> rect(10, chat_y, width, chat_y + window_size.Y);
guitext_chat->setRelativePosition(rect); guitext_chat->setRelativePosition(rect);
//now use real height of text and adjust rect according to this size //now use real height of text and adjust rect according to this size
@ -1176,7 +1203,6 @@ public:
bool startup(bool *kill, bool startup(bool *kill,
bool random_input, bool random_input,
InputHandler *input, InputHandler *input,
IrrlichtDevice *device,
const std::string &map_dir, const std::string &map_dir,
const std::string &playername, const std::string &playername,
const std::string &password, const std::string &password,
@ -1277,8 +1303,9 @@ protected:
const core::line3d<f32> &shootline, bool liquids_pointable, const core::line3d<f32> &shootline, bool liquids_pointable,
bool look_for_object, const v3s16 &camera_offset); bool look_for_object, const v3s16 &camera_offset);
void handlePointingAtNothing(const ItemStack &playerItem); void handlePointingAtNothing(const ItemStack &playerItem);
void handlePointingAtNode(const PointedThing &pointed, const ItemDefinition &playeritem_def, void handlePointingAtNode(const PointedThing &pointed,
const ToolCapabilities &playeritem_toolcap, f32 dtime); const ItemDefinition &playeritem_def, const ItemStack &playeritem,
const ToolCapabilities &playeritem_toolcap, f32 dtime);
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem, void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
const v3f &player_position, bool show_debug); const v3f &player_position, bool show_debug);
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos, void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
@ -1291,7 +1318,7 @@ protected:
// Misc // Misc
void limitFps(FpsControl *fps_timings, f32 *dtime); void limitFps(FpsControl *fps_timings, f32 *dtime);
void showOverlayMessage(const wchar_t *msg, float dtime, int percent, void showOverlayMessage(const char *msg, float dtime, int percent,
bool draw_clouds = true); bool draw_clouds = true);
static void settingChangedCallback(const std::string &setting_name, void *data); static void settingChangedCallback(const std::string &setting_name, void *data);
@ -1559,7 +1586,6 @@ Game::~Game()
bool Game::startup(bool *kill, bool Game::startup(bool *kill,
bool random_input, bool random_input,
InputHandler *input, InputHandler *input,
IrrlichtDevice *device,
const std::string &map_dir, const std::string &map_dir,
const std::string &playername, const std::string &playername,
const std::string &password, const std::string &password,
@ -1572,7 +1598,7 @@ bool Game::startup(bool *kill,
bool simple_singleplayer_mode) bool simple_singleplayer_mode)
{ {
// "cache" // "cache"
this->device = device; this->device = RenderingEngine::get_raw_device();
this->kill = kill; this->kill = kill;
this->error_message = &error_message; this->error_message = &error_message;
this->reconnect_requested = reconnect; this->reconnect_requested = reconnect;
@ -1584,10 +1610,11 @@ bool Game::startup(bool *kill,
keycache.handler = input; keycache.handler = input;
keycache.populate(); keycache.populate();
driver = device->getVideoDriver(); driver = device->getVideoDriver();
smgr = device->getSceneManager(); smgr = RenderingEngine::get_scene_manager();
smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true); RenderingEngine::get_scene_manager()->getParameters()->
setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
memset(&runData, 0, sizeof(runData)); memset(&runData, 0, sizeof(runData));
runData.time_from_last_punch = 10.0; runData.time_from_last_punch = 10.0;
@ -1624,7 +1651,7 @@ void Game::run()
Profiler::GraphValues dummyvalues; Profiler::GraphValues dummyvalues;
g_profiler->graphGet(dummyvalues); g_profiler->graphGet(dummyvalues);
draw_times.last_time = device->getTimer()->getTime(); draw_times.last_time = RenderingEngine::get_timer_time();
set_light_table(g_settings->getFloat("display_gamma")); set_light_table(g_settings->getFloat("display_gamma"));
@ -1636,12 +1663,12 @@ void Game::run()
irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"), irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"),
g_settings->getU16("screen_h")); g_settings->getU16("screen_h"));
while (device->run() while (RenderingEngine::run()
&& !(*kill || g_gamecallback->shutdown_requested && !(*kill || g_gamecallback->shutdown_requested
|| (server && server->getShutdownRequested()))) { || (server && server->getShutdownRequested()))) {
const irr::core::dimension2d<u32> &current_screen_size = const irr::core::dimension2d<u32> &current_screen_size =
device->getVideoDriver()->getScreenSize(); RenderingEngine::get_video_driver()->getScreenSize();
// Verify if window size has changed and save it if it's the case // Verify if window size has changed and save it if it's the case
// Ensure evaluating settings->getBool after verifying screensize // Ensure evaluating settings->getBool after verifying screensize
// First condition is cheaper // First condition is cheaper
@ -1704,7 +1731,7 @@ void Game::shutdown()
if (current_formspec) if (current_formspec)
current_formspec->quitMenu(); current_formspec->quitMenu();
showOverlayMessage(wgettext("Shutting down..."), 0, 0, false); showOverlayMessage("Shutting down...", 0, 0, false);
if (clouds) if (clouds)
clouds->drop(); clouds->drop();
@ -1754,11 +1781,11 @@ bool Game::init(
u16 port, u16 port,
const SubgameSpec &gamespec) const SubgameSpec &gamespec)
{ {
texture_src = createTextureSource(device); texture_src = createTextureSource();
showOverlayMessage(wgettext("Loading..."), 0, 0); showOverlayMessage("Loading...", 0, 0);
shader_src = createShaderSource(device); shader_src = createShaderSource();
itemdef_manager = createItemDefManager(); itemdef_manager = createItemDefManager();
nodedef_manager = createNodeDefManager(); nodedef_manager = createNodeDefManager();
@ -1812,7 +1839,7 @@ bool Game::initSound()
bool Game::createSingleplayerServer(const std::string &map_dir, bool Game::createSingleplayerServer(const std::string &map_dir,
const SubgameSpec &gamespec, u16 port, std::string *address) const SubgameSpec &gamespec, u16 port, std::string *address)
{ {
showOverlayMessage(wgettext("Creating server..."), 0, 5); showOverlayMessage("Creating server...", 0, 5);
std::string bind_str = g_settings->get("bind_address"); std::string bind_str = g_settings->get("bind_address");
Address bind_addr(0, 0, 0, 0, port); Address bind_addr(0, 0, 0, 0, port);
@ -1848,7 +1875,7 @@ bool Game::createSingleplayerServer(const std::string &map_dir,
bool Game::createClient(const std::string &playername, bool Game::createClient(const std::string &playername,
const std::string &password, std::string *address, u16 port) const std::string &password, std::string *address, u16 port)
{ {
showOverlayMessage(wgettext("Creating client..."), 0, 10); showOverlayMessage("Creating client...", 0, 10);
draw_control = new MapDrawControl; draw_control = new MapDrawControl;
if (!draw_control) if (!draw_control)
@ -1883,7 +1910,7 @@ bool Game::createClient(const std::string &playername,
shader_src->addShaderConstantSetterFactory(scsf); shader_src->addShaderConstantSetterFactory(scsf);
// Update cached textures, meshes and materials // Update cached textures, meshes and materials
client->afterContentReceived(device); client->afterContentReceived();
/* Camera /* Camera
*/ */
@ -1895,7 +1922,7 @@ bool Game::createClient(const std::string &playername,
/* Clouds /* Clouds
*/ */
if (m_cache_enable_clouds) { if (m_cache_enable_clouds) {
clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, time(0)); clouds = new Clouds(smgr, -1, time(0));
if (!clouds) { if (!clouds) {
*error_message = "Memory allocation error (clouds)"; *error_message = "Memory allocation error (clouds)";
errorstream << *error_message << std::endl; errorstream << *error_message << std::endl;
@ -1905,7 +1932,7 @@ bool Game::createClient(const std::string &playername,
/* Skybox /* Skybox
*/ */
sky = new Sky(smgr->getRootSceneNode(), smgr, -1, texture_src); sky = new Sky(-1, texture_src);
scsf->setSky(sky); scsf->setSky(sky);
skybox = NULL; // This is used/set later on in the main run loop skybox = NULL; // This is used/set later on in the main run loop
@ -2034,7 +2061,7 @@ bool Game::connectToServer(const std::string &playername,
*aborted = false; *aborted = false;
bool local_server_mode = false; bool local_server_mode = false;
showOverlayMessage(wgettext("Resolving address..."), 0, 15); showOverlayMessage("Resolving address...", 0, 15);
Address connect_address(0, 0, 0, 0, port); Address connect_address(0, 0, 0, 0, port);
@ -2066,8 +2093,7 @@ bool Game::connectToServer(const std::string &playername,
return false; return false;
} }
client = new Client(device, client = new Client(playername.c_str(), password, *address,
playername.c_str(), password, *address,
*draw_control, texture_src, shader_src, *draw_control, texture_src, shader_src,
itemdef_manager, nodedef_manager, sound, eventmgr, itemdef_manager, nodedef_manager, sound, eventmgr,
connect_address.isIPv6(), &flags); connect_address.isIPv6(), &flags);
@ -2093,11 +2119,12 @@ bool Game::connectToServer(const std::string &playername,
f32 dtime; f32 dtime;
f32 wait_time = 0; // in seconds f32 wait_time = 0; // in seconds
fps_control.last_time = device->getTimer()->getTime(); fps_control.last_time = RenderingEngine::get_timer_time();
client->loadMods();
client->initMods(); client->initMods();
while (device->run()) { while (RenderingEngine::run()) {
limitFps(&fps_control, &dtime); limitFps(&fps_control, &dtime);
@ -2156,7 +2183,7 @@ bool Game::connectToServer(const std::string &playername,
} }
// Update status // Update status
showOverlayMessage(wgettext("Connecting to server..."), dtime, 20); showOverlayMessage("Connecting to server...", dtime, 20);
} }
} catch (con::PeerNotFoundException &e) { } catch (con::PeerNotFoundException &e) {
// TODO: Should something be done here? At least an info/error // TODO: Should something be done here? At least an info/error
@ -2174,9 +2201,9 @@ bool Game::getServerContent(bool *aborted)
FpsControl fps_control = { 0 }; FpsControl fps_control = { 0 };
f32 dtime; // in seconds f32 dtime; // in seconds
fps_control.last_time = device->getTimer()->getTime(); fps_control.last_time = RenderingEngine::get_timer_time();
while (device->run()) { while (RenderingEngine::run()) {
limitFps(&fps_control, &dtime); limitFps(&fps_control, &dtime);
@ -2214,13 +2241,13 @@ bool Game::getServerContent(bool *aborted)
if (!client->itemdefReceived()) { if (!client->itemdefReceived()) {
const wchar_t *text = wgettext("Item definitions..."); const wchar_t *text = wgettext("Item definitions...");
progress = 25; progress = 25;
draw_load_screen(text, device, guienv, texture_src, RenderingEngine::draw_load_screen(text, guienv, texture_src,
dtime, progress); dtime, progress);
delete[] text; delete[] text;
} else if (!client->nodedefReceived()) { } else if (!client->nodedefReceived()) {
const wchar_t *text = wgettext("Node definitions..."); const wchar_t *text = wgettext("Node definitions...");
progress = 30; progress = 30;
draw_load_screen(text, device, guienv, texture_src, RenderingEngine::draw_load_screen(text, guienv, texture_src,
dtime, progress); dtime, progress);
delete[] text; delete[] text;
} else { } else {
@ -2244,8 +2271,8 @@ bool Game::getServerContent(bool *aborted)
} }
progress = 30 + client->mediaReceiveProgress() * 35 + 0.5; progress = 30 + client->mediaReceiveProgress() * 35 + 0.5;
draw_load_screen(utf8_to_wide(message.str()), device, RenderingEngine::draw_load_screen(utf8_to_wide(message.str()), guienv,
guienv, texture_src, dtime, progress); texture_src, dtime, progress);
} }
} }
@ -2524,7 +2551,7 @@ void Game::processKeyInput()
} else if (wasKeyDown(KeyType::CINEMATIC)) { } else if (wasKeyDown(KeyType::CINEMATIC)) {
toggleCinematic(); toggleCinematic();
} else if (wasKeyDown(KeyType::SCREENSHOT)) { } else if (wasKeyDown(KeyType::SCREENSHOT)) {
client->makeScreenshot(device); client->makeScreenshot();
} else if (wasKeyDown(KeyType::TOGGLE_HUD)) { } else if (wasKeyDown(KeyType::TOGGLE_HUD)) {
toggleHud(); toggleHud();
} else if (wasKeyDown(KeyType::MINIMAP)) { } else if (wasKeyDown(KeyType::MINIMAP)) {
@ -2698,7 +2725,7 @@ void Game::openInventory()
PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client); PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client);
TextDest *txt_dst = new TextDestPlayerInventory(client); TextDest *txt_dst = new TextDestPlayerInventory(client);
create_formspec_menu(&current_formspec, client, device, &input->joystick, fs_src, txt_dst); create_formspec_menu(&current_formspec, client, &input->joystick, fs_src, txt_dst);
cur_formname = ""; cur_formname = "";
InventoryLocation inventoryloc; InventoryLocation inventoryloc;
@ -3200,7 +3227,7 @@ void Game::processClientEvents(CameraOrientation *cam)
TextDestPlayerInventory *txt_dst = TextDestPlayerInventory *txt_dst =
new TextDestPlayerInventory(client, *(event.show_formspec.formname)); new TextDestPlayerInventory(client, *(event.show_formspec.formname));
create_formspec_menu(&current_formspec, client, device, &input->joystick, create_formspec_menu(&current_formspec, client, &input->joystick,
fs_src, txt_dst); fs_src, txt_dst);
cur_formname = *(event.show_formspec.formname); cur_formname = *(event.show_formspec.formname);
} }
@ -3213,7 +3240,7 @@ void Game::processClientEvents(CameraOrientation *cam)
{ {
FormspecFormSource *fs_src = new FormspecFormSource(*event.show_formspec.formspec); FormspecFormSource *fs_src = new FormspecFormSource(*event.show_formspec.formspec);
LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event.show_formspec.formname, client); LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event.show_formspec.formname, client);
create_formspec_menu(&current_formspec, client, device, &input->joystick, create_formspec_menu(&current_formspec, client, &input->joystick,
fs_src, txt_dst); fs_src, txt_dst);
} }
delete event.show_formspec.formspec; delete event.show_formspec.formspec;
@ -3223,8 +3250,7 @@ void Game::processClientEvents(CameraOrientation *cam)
case CE_SPAWN_PARTICLE: case CE_SPAWN_PARTICLE:
case CE_ADD_PARTICLESPAWNER: case CE_ADD_PARTICLESPAWNER:
case CE_DELETE_PARTICLESPAWNER: case CE_DELETE_PARTICLESPAWNER:
client->getParticleManager()->handleParticleEvent(&event, client, client->getParticleManager()->handleParticleEvent(&event, client, player);
smgr, player);
break; break;
case CE_HUDADD: case CE_HUDADD:
@ -3365,7 +3391,7 @@ void Game::processClientEvents(CameraOrientation *cam)
} else if (*event.set_sky.type == "skybox" && } else if (*event.set_sky.type == "skybox" &&
event.set_sky.params->size() == 6) { event.set_sky.params->size() == 6) {
sky->setFallbackBgColor(*event.set_sky.bgcolor); sky->setFallbackBgColor(*event.set_sky.bgcolor);
skybox = smgr->addSkyBoxSceneNode( skybox = RenderingEngine::get_scene_manager()->addSkyBoxSceneNode(
texture_src->getTextureForMesh((*event.set_sky.params)[0]), texture_src->getTextureForMesh((*event.set_sky.params)[0]),
texture_src->getTextureForMesh((*event.set_sky.params)[1]), texture_src->getTextureForMesh((*event.set_sky.params)[1]),
texture_src->getTextureForMesh((*event.set_sky.params)[2]), texture_src->getTextureForMesh((*event.set_sky.params)[2]),
@ -3655,7 +3681,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
if (playeritem.name.empty() && hand_def.tool_capabilities != NULL) { if (playeritem.name.empty() && hand_def.tool_capabilities != NULL) {
playeritem_toolcap = *hand_def.tool_capabilities; playeritem_toolcap = *hand_def.tool_capabilities;
} }
handlePointingAtNode(pointed, playeritem_def, playeritem_toolcap, dtime); handlePointingAtNode(pointed, playeritem_def, playeritem,
playeritem_toolcap, dtime);
} else if (pointed.type == POINTEDTHING_OBJECT) { } else if (pointed.type == POINTEDTHING_OBJECT) {
handlePointingAtObject(pointed, playeritem, player_position, show_debug); handlePointingAtObject(pointed, playeritem, player_position, show_debug);
} else if (isLeftPressed()) { } else if (isLeftPressed()) {
@ -3790,8 +3817,9 @@ void Game::handlePointingAtNothing(const ItemStack &playerItem)
} }
void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinition &playeritem_def, void Game::handlePointingAtNode(const PointedThing &pointed,
const ToolCapabilities &playeritem_toolcap, f32 dtime) const ItemDefinition &playeritem_def, const ItemStack &playeritem,
const ToolCapabilities &playeritem_toolcap, f32 dtime)
{ {
v3s16 nodepos = pointed.node_undersurface; v3s16 nodepos = pointed.node_undersurface;
v3s16 neighbourpos = pointed.node_abovesurface; v3s16 neighbourpos = pointed.node_abovesurface;
@ -3839,7 +3867,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinitio
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client); TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
create_formspec_menu(&current_formspec, client, create_formspec_menu(&current_formspec, client,
device, &input->joystick, fs_src, txt_dst); &input->joystick, fs_src, txt_dst);
cur_formname = ""; cur_formname = "";
current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc); current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
@ -3851,7 +3879,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed, const ItemDefinitio
// If the wielded item has node placement prediction, // If the wielded item has node placement prediction,
// make that happen // make that happen
bool placed = nodePlacementPrediction(*client, bool placed = nodePlacementPrediction(*client,
playeritem_def, playeritem_def, playeritem,
nodepos, neighbourpos); nodepos, neighbourpos);
if (placed) { if (placed) {
@ -3969,9 +3997,8 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
runData.dig_time_complete = params.time; runData.dig_time_complete = params.time;
if (m_cache_enable_particles) { if (m_cache_enable_particles) {
const ContentFeatures &features = const ContentFeatures &features = client->getNodeDefManager()->get(n);
client->getNodeDefManager()->get(n); client->getParticleManager()->addPunchingParticles(client,
client->getParticleManager()->addPunchingParticles(client, smgr,
player, nodepos, n, features); player, nodepos, n, features);
} }
} }
@ -4048,7 +4075,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
if (m_cache_enable_particles) { if (m_cache_enable_particles) {
const ContentFeatures &features = const ContentFeatures &features =
client->getNodeDefManager()->get(wasnode); client->getNodeDefManager()->get(wasnode);
client->getParticleManager()->addDiggingParticles(client, smgr, client->getParticleManager()->addDiggingParticles(client,
player, nodepos, wasnode, features); player, nodepos, wasnode, features);
} }
@ -4256,7 +4283,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
TimeTaker tt_draw("mainloop: draw"); TimeTaker tt_draw("mainloop: draw");
driver->beginScene(true, true, skycolor); driver->beginScene(true, true, skycolor);
draw_scene(driver, smgr, *camera, *client, player, *hud, mapper, RenderingEngine::draw_scene(camera, client, player, hud, mapper,
guienv, screensize, skycolor, flags.show_hud, guienv, screensize, skycolor, flags.show_hud,
flags.show_minimap); flags.show_minimap);
@ -4333,17 +4360,17 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
std::ostringstream os(std::ios_base::binary); std::ostringstream os(std::ios_base::binary);
os << std::fixed os << std::fixed
<< PROJECT_NAME_C " " << g_version_hash << PROJECT_NAME_C " " << g_version_hash
<< " FPS = " << fps << "; " << fps << " FPS"
<< " (R: range_all=" << draw_control->range_all << ")" << ", (R: range_all=" << draw_control->range_all << ")"
<< std::setprecision(0) << std::setprecision(0)
<< " drawtime = " << drawtime_avg << ", drawtime = " << drawtime_avg << " ms"
<< std::setprecision(1) << std::setprecision(1)
<< ", dtime_jitter = " << ", dtime_jitter = "
<< (stats.dtime_jitter.max_fraction * 100.0) << " %" << (stats.dtime_jitter.max_fraction * 100.0) << " %"
<< std::setprecision(1) << std::setprecision(1)
<< ", v_range = " << draw_control->wanted_range << ", v_range = " << draw_control->wanted_range
<< std::setprecision(3) << std::setprecision(3)
<< ", RTT = " << client->getRTT(); << ", RTT = " << client->getRTT() << " s";
setStaticText(guitext, utf8_to_wide(os.str()).c_str()); setStaticText(guitext, utf8_to_wide(os.str()).c_str());
guitext->setVisible(true); guitext->setVisible(true);
@ -4385,9 +4412,11 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
MapNode n = map.getNodeNoEx(runData.pointed_old.node_undersurface); MapNode n = map.getNodeNoEx(runData.pointed_old.node_undersurface);
if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") { if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
const ContentFeatures &features = nodedef->get(n); const ContentFeatures &features = nodedef->get(n);
os << " (pointing_at = " << nodedef->get(n).name os << " (pointing_at = \"" << nodedef->get(n).name
<< " - " << features.tiledef[0].name.c_str() << "\", param1 = " << (u64) n.getParam1()
<< ")"; << ", param2 = " << (u64) n.getParam2()
<< ", tiledef[0] = \"" << features.tiledef[0].name.c_str()
<< "\")";
} }
} }
@ -4504,15 +4533,12 @@ inline void Game::limitFps(FpsControl *fps_timings, f32 *dtime)
fps_timings->last_time = time; fps_timings->last_time = time;
} }
// Note: This will free (using delete[])! \p msg. If you want to use it later, void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds)
// pass a copy of it to this function
// Note: \p msg must be allocated using new (not malloc())
void Game::showOverlayMessage(const wchar_t *msg, float dtime,
int percent, bool draw_clouds)
{ {
draw_load_screen(msg, device, guienv, texture_src, dtime, percent, const wchar_t *wmsg = wgettext(msg);
RenderingEngine::draw_load_screen(wmsg, guienv, texture_src, dtime, percent,
draw_clouds); draw_clouds);
delete[] msg; delete[] wmsg;
} }
void Game::settingChangedCallback(const std::string &setting_name, void *data) void Game::settingChangedCallback(const std::string &setting_name, void *data)
@ -4559,7 +4585,7 @@ void Game::extendedResourceCleanup()
// Extended resource accounting // Extended resource accounting
infostream << "Irrlicht resources after cleanup:" << std::endl; infostream << "Irrlicht resources after cleanup:" << std::endl;
infostream << "\tRemaining meshes : " infostream << "\tRemaining meshes : "
<< device->getSceneManager()->getMeshCache()->getMeshCount() << std::endl; << RenderingEngine::get_mesh_cache()->getMeshCount() << std::endl;
infostream << "\tRemaining textures : " infostream << "\tRemaining textures : "
<< driver->getTextureCount() << std::endl; << driver->getTextureCount() << std::endl;
@ -4696,7 +4722,7 @@ void Game::showPauseMenu()
FormspecFormSource *fs_src = new FormspecFormSource(os.str()); FormspecFormSource *fs_src = new FormspecFormSource(os.str());
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
create_formspec_menu(&current_formspec, client, device, &input->joystick, fs_src, txt_dst); create_formspec_menu(&current_formspec, client, &input->joystick, fs_src, txt_dst);
current_formspec->setFocus("btn_continue"); current_formspec->setFocus("btn_continue");
current_formspec->doPause = true; current_formspec->doPause = true;
} }
@ -4710,8 +4736,6 @@ void Game::showPauseMenu()
void the_game(bool *kill, void the_game(bool *kill,
bool random_input, bool random_input,
InputHandler *input, InputHandler *input,
IrrlichtDevice *device,
const std::string &map_dir, const std::string &map_dir,
const std::string &playername, const std::string &playername,
const std::string &password, const std::string &password,
@ -4734,7 +4758,7 @@ void the_game(bool *kill,
try { try {
if (game.startup(kill, random_input, input, device, map_dir, if (game.startup(kill, random_input, input, map_dir,
playername, password, &server_address, port, error_message, playername, password, &server_address, port, error_message,
reconnect_requested, &chat_backend, gamespec, reconnect_requested, &chat_backend, gamespec,
simple_singleplayer_mode)) { simple_singleplayer_mode)) {

View File

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GAME_HEADER #ifndef GAME_HEADER
#define GAME_HEADER #define GAME_HEADER
#include "irrlichttypes_extrabloated.h" #include "irrlichttypes.h"
#include <string> #include <string>
class InputHandler; class InputHandler;
@ -42,7 +42,6 @@ struct GameUIFlags
void the_game(bool *kill, void the_game(bool *kill,
bool random_input, bool random_input,
InputHandler *input, InputHandler *input,
IrrlichtDevice *device,
const std::string &map_dir, const std::string &map_dir,
const std::string &playername, const std::string &playername,
const std::string &password, const std::string &password,

View File

@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#if USE_FREETYPE #if USE_FREETYPE
#include "xCGUITTFont.h" #include "irrlicht_changes/CGUITTFont.h"
#endif #endif
inline u32 clamp_u8(s32 value) inline u32 clamp_u8(s32 value)
@ -186,8 +186,8 @@ void GUIChatConsole::draw()
// scale current console height to new window size // scale current console height to new window size
if (m_screensize.Y != 0) if (m_screensize.Y != 0)
m_height = m_height * screensize.Y / m_screensize.Y; m_height = m_height * screensize.Y / m_screensize.Y;
m_desired_height = m_desired_height_fraction * m_screensize.Y;
m_screensize = screensize; m_screensize = screensize;
m_desired_height = m_desired_height_fraction * m_screensize.Y;
reformatConsole(); reformatConsole();
} }
@ -213,6 +213,7 @@ void GUIChatConsole::reformatConsole()
s32 rows = m_desired_height / m_fontsize.Y - 1; // make room for the input prompt s32 rows = m_desired_height / m_fontsize.Y - 1; // make room for the input prompt
if (cols <= 0 || rows <= 0) if (cols <= 0 || rows <= 0)
cols = rows = 0; cols = rows = 0;
recalculateConsolePosition();
m_chat_backend->reformat(cols, rows); m_chat_backend->reformat(cols, rows);
} }

View File

@ -19,9 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiEngine.h" #include "guiEngine.h"
#include <fstream>
#include <IGUIStaticText.h> #include <IGUIStaticText.h>
#include <ICameraSceneNode.h> #include <ICameraSceneNode.h>
#include "client/renderingengine.h"
#include "scripting_mainmenu.h" #include "scripting_mainmenu.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "config.h" #include "config.h"
@ -45,14 +45,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif #endif
/******************************************************************************/
/** TextDestGuiEngine */
/******************************************************************************/
TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
{
m_engine = engine;
}
/******************************************************************************/ /******************************************************************************/
void TextDestGuiEngine::gotText(const StringMap &fields) void TextDestGuiEngine::gotText(const StringMap &fields)
{ {
@ -65,14 +57,6 @@ void TextDestGuiEngine::gotText(const std::wstring &text)
m_engine->getScriptIface()->handleMainMenuEvent(wide_to_utf8(text)); m_engine->getScriptIface()->handleMainMenuEvent(wide_to_utf8(text));
} }
/******************************************************************************/
/** MenuTextureSource */
/******************************************************************************/
MenuTextureSource::MenuTextureSource(video::IVideoDriver *driver)
{
m_driver = driver;
}
/******************************************************************************/ /******************************************************************************/
MenuTextureSource::~MenuTextureSource() MenuTextureSource::~MenuTextureSource()
{ {
@ -85,7 +69,7 @@ MenuTextureSource::~MenuTextureSource()
} }
/******************************************************************************/ /******************************************************************************/
video::ITexture* MenuTextureSource::getTexture(const std::string &name, u32 *id) video::ITexture *MenuTextureSource::getTexture(const std::string &name, u32 *id)
{ {
if(id) if(id)
*id = 0; *id = 0;
@ -130,17 +114,14 @@ void MenuMusicFetcher::fetchSounds(const std::string &name,
/******************************************************************************/ /******************************************************************************/
/** GUIEngine */ /** GUIEngine */
/******************************************************************************/ /******************************************************************************/
GUIEngine::GUIEngine( irr::IrrlichtDevice* dev, GUIEngine::GUIEngine(JoystickController *joystick,
JoystickController *joystick, gui::IGUIElement *parent,
gui::IGUIElement* parent, IMenuManager *menumgr,
IMenuManager *menumgr, MainMenuData *data,
scene::ISceneManager* smgr, bool &kill) :
MainMenuData* data,
bool& kill) :
m_device(dev),
m_parent(parent), m_parent(parent),
m_menumanager(menumgr), m_menumanager(menumgr),
m_smgr(smgr), m_smgr(RenderingEngine::get_scene_manager()),
m_data(data), m_data(data),
m_kill(kill) m_kill(kill)
{ {
@ -152,7 +133,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
m_buttonhandler = new TextDestGuiEngine(this); m_buttonhandler = new TextDestGuiEngine(this);
//create texture source //create texture source
m_texture_source = new MenuTextureSource(m_device->getVideoDriver()); m_texture_source = new MenuTextureSource(RenderingEngine::get_video_driver());
//create soundmanager //create soundmanager
MenuMusicFetcher soundfetcher; MenuMusicFetcher soundfetcher;
@ -170,15 +151,14 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
rect += v2s32(4, 0); rect += v2s32(4, 0);
m_irr_toplefttext = m_irr_toplefttext =
addStaticText(m_device->getGUIEnvironment(), m_toplefttext, addStaticText(RenderingEngine::get_gui_env(), m_toplefttext,
rect, false, true, 0, -1); rect, false, true, 0, -1);
//create formspecsource //create formspecsource
m_formspecgui = new FormspecFormSource(""); m_formspecgui = new FormspecFormSource("");
/* Create menu */ /* Create menu */
m_menu = new GUIFormSpecMenu(m_device, m_menu = new GUIFormSpecMenu(joystick,
joystick,
m_parent, m_parent,
-1, -1,
m_menumanager, m_menumanager,
@ -245,7 +225,7 @@ void GUIEngine::run()
{ {
// Always create clouds because they may or may not be // Always create clouds because they may or may not be
// needed based on the game selected // needed based on the game selected
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
cloudInit(); cloudInit();
@ -254,10 +234,10 @@ void GUIEngine::run()
irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"), irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"),
g_settings->getU16("screen_h")); g_settings->getU16("screen_h"));
while (m_device->run() && (!m_startgame) && (!m_kill)) { while (RenderingEngine::run() && (!m_startgame) && (!m_kill)) {
const irr::core::dimension2d<u32> &current_screen_size = const irr::core::dimension2d<u32> &current_screen_size =
m_device->getVideoDriver()->getScreenSize(); RenderingEngine::get_video_driver()->getScreenSize();
// Verify if window size has changed and save it if it's the case // Verify if window size has changed and save it if it's the case
// Ensure evaluating settings->getBool after verifying screensize // Ensure evaluating settings->getBool after verifying screensize
// First condition is cheaper // First condition is cheaper
@ -288,7 +268,7 @@ void GUIEngine::run()
drawHeader(driver); drawHeader(driver);
drawFooter(driver); drawFooter(driver);
m_device->getGUIEnvironment()->drawAll(); RenderingEngine::get_gui_env()->drawAll();
driver->endScene(); driver->endScene();
@ -308,10 +288,7 @@ void GUIEngine::run()
/******************************************************************************/ /******************************************************************************/
GUIEngine::~GUIEngine() GUIEngine::~GUIEngine()
{ {
video::IVideoDriver* driver = m_device->getVideoDriver(); if (m_sound_manager != &dummySoundManager){
FATAL_ERROR_IF(driver == 0, "Could not get video driver");
if(m_sound_manager != &dummySoundManager){
delete m_sound_manager; delete m_sound_manager;
m_sound_manager = NULL; m_sound_manager = NULL;
} }
@ -324,7 +301,7 @@ GUIEngine::~GUIEngine()
//clean up texture pointers //clean up texture pointers
for (unsigned int i = 0; i < TEX_LAYER_MAX; i++) { for (unsigned int i = 0; i < TEX_LAYER_MAX; i++) {
if (m_textures[i].texture) if (m_textures[i].texture)
driver->removeTexture(m_textures[i].texture); RenderingEngine::get_video_driver()->removeTexture(m_textures[i].texture);
} }
delete m_texture_source; delete m_texture_source;
@ -336,21 +313,20 @@ GUIEngine::~GUIEngine()
/******************************************************************************/ /******************************************************************************/
void GUIEngine::cloudInit() void GUIEngine::cloudInit()
{ {
m_cloud.clouds = new Clouds(m_smgr->getRootSceneNode(), m_cloud.clouds = new Clouds(m_smgr, -1, rand(), 100);
m_smgr, -1, rand(), 100);
m_cloud.clouds->update(v2f(0, 0), video::SColor(255,200,200,255)); m_cloud.clouds->update(v2f(0, 0), video::SColor(255,200,200,255));
m_cloud.camera = m_smgr->addCameraSceneNode(0, m_cloud.camera = m_smgr->addCameraSceneNode(0,
v3f(0,0,0), v3f(0, 60, 100)); v3f(0,0,0), v3f(0, 60, 100));
m_cloud.camera->setFarValue(10000); m_cloud.camera->setFarValue(10000);
m_cloud.lasttime = m_device->getTimer()->getTime(); m_cloud.lasttime = RenderingEngine::get_timer_time();
} }
/******************************************************************************/ /******************************************************************************/
void GUIEngine::cloudPreProcess() void GUIEngine::cloudPreProcess()
{ {
u32 time = m_device->getTimer()->getTime(); u32 time = RenderingEngine::get_timer_time();
if(time > m_cloud.lasttime) if(time > m_cloud.lasttime)
m_cloud.dtime = (time - m_cloud.lasttime) / 1000.0; m_cloud.dtime = (time - m_cloud.lasttime) / 1000.0;
@ -372,7 +348,7 @@ void GUIEngine::cloudPostProcess()
u32 busytime_u32; u32 busytime_u32;
// not using getRealTime is necessary for wine // not using getRealTime is necessary for wine
u32 time = m_device->getTimer()->getTime(); u32 time = RenderingEngine::get_timer_time();
if(time > m_cloud.lasttime) if(time > m_cloud.lasttime)
busytime_u32 = time - m_cloud.lasttime; busytime_u32 = time - m_cloud.lasttime;
else else
@ -381,14 +357,14 @@ void GUIEngine::cloudPostProcess()
// FPS limiter // FPS limiter
u32 frametime_min = 1000./fps_max; u32 frametime_min = 1000./fps_max;
if(busytime_u32 < frametime_min) { if (busytime_u32 < frametime_min) {
u32 sleeptime = frametime_min - busytime_u32; u32 sleeptime = frametime_min - busytime_u32;
m_device->sleep(sleeptime); RenderingEngine::get_raw_device()->sleep(sleeptime);
} }
} }
/******************************************************************************/ /******************************************************************************/
void GUIEngine::drawBackground(video::IVideoDriver* driver) void GUIEngine::drawBackground(video::IVideoDriver *driver)
{ {
v2u32 screensize = driver->getScreenSize(); v2u32 screensize = driver->getScreenSize();
@ -430,7 +406,7 @@ void GUIEngine::drawBackground(video::IVideoDriver* driver)
} }
/******************************************************************************/ /******************************************************************************/
void GUIEngine::drawOverlay(video::IVideoDriver* driver) void GUIEngine::drawOverlay(video::IVideoDriver *driver)
{ {
v2u32 screensize = driver->getScreenSize(); v2u32 screensize = driver->getScreenSize();
@ -449,7 +425,7 @@ void GUIEngine::drawOverlay(video::IVideoDriver* driver)
} }
/******************************************************************************/ /******************************************************************************/
void GUIEngine::drawHeader(video::IVideoDriver* driver) void GUIEngine::drawHeader(video::IVideoDriver *driver)
{ {
core::dimension2d<u32> screensize = driver->getScreenSize(); core::dimension2d<u32> screensize = driver->getScreenSize();
@ -483,7 +459,7 @@ void GUIEngine::drawHeader(video::IVideoDriver* driver)
} }
/******************************************************************************/ /******************************************************************************/
void GUIEngine::drawFooter(video::IVideoDriver* driver) void GUIEngine::drawFooter(video::IVideoDriver *driver)
{ {
core::dimension2d<u32> screensize = driver->getScreenSize(); core::dimension2d<u32> screensize = driver->getScreenSize();
@ -518,17 +494,14 @@ void GUIEngine::drawFooter(video::IVideoDriver* driver)
bool GUIEngine::setTexture(texture_layer layer, std::string texturepath, bool GUIEngine::setTexture(texture_layer layer, std::string texturepath,
bool tile_image, unsigned int minsize) bool tile_image, unsigned int minsize)
{ {
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
FATAL_ERROR_IF(driver == 0, "Could not get video driver");
if (m_textures[layer].texture != NULL) if (m_textures[layer].texture) {
{
driver->removeTexture(m_textures[layer].texture); driver->removeTexture(m_textures[layer].texture);
m_textures[layer].texture = NULL; m_textures[layer].texture = NULL;
} }
if ((texturepath == "") || !fs::PathExists(texturepath)) if ((texturepath == "") || !fs::PathExists(texturepath)) {
{
return false; return false;
} }
@ -536,8 +509,7 @@ bool GUIEngine::setTexture(texture_layer layer, std::string texturepath,
m_textures[layer].tile = tile_image; m_textures[layer].tile = tile_image;
m_textures[layer].minsize = minsize; m_textures[layer].minsize = minsize;
if (m_textures[layer].texture == NULL) if (m_textures[layer].texture == NULL) {
{
return false; return false;
} }
@ -589,7 +561,7 @@ void GUIEngine::updateTopLeftTextSize()
m_irr_toplefttext->remove(); m_irr_toplefttext->remove();
m_irr_toplefttext = m_irr_toplefttext =
addStaticText(m_device->getGUIEnvironment(), m_toplefttext, addStaticText(RenderingEngine::get_gui_env(), m_toplefttext,
rect, false, true, 0, -1); rect, false, true, 0, -1);
} }

View File

@ -43,7 +43,7 @@ typedef enum {
} texture_layer; } texture_layer;
typedef struct { typedef struct {
video::ITexture* texture; video::ITexture *texture = nullptr;
bool tile; bool tile;
unsigned int minsize; unsigned int minsize;
} image_definition; } image_definition;
@ -68,7 +68,7 @@ public:
* default constructor * default constructor
* @param engine the engine data is transmitted for further processing * @param engine the engine data is transmitted for further processing
*/ */
TextDestGuiEngine(GUIEngine* engine); TextDestGuiEngine(GUIEngine* engine) : m_engine(engine) {};
/** /**
* receive fields transmitted by guiFormSpecMenu * receive fields transmitted by guiFormSpecMenu
@ -84,7 +84,7 @@ public:
private: private:
/** target to transmit data to */ /** target to transmit data to */
GUIEngine* m_engine; GUIEngine *m_engine = nullptr;
}; };
/** GUIEngine specific implementation of ISimpleTextureSource */ /** GUIEngine specific implementation of ISimpleTextureSource */
@ -95,7 +95,7 @@ public:
* default constructor * default constructor
* @param driver the video driver to load textures from * @param driver the video driver to load textures from
*/ */
MenuTextureSource(video::IVideoDriver *driver); MenuTextureSource(video::IVideoDriver *driver) : m_driver(driver) {};
/** /**
* destructor, removes all loaded textures * destructor, removes all loaded textures
@ -107,11 +107,11 @@ public:
* @param name path to the texture * @param name path to the texture
* @param id receives the texture ID, always 0 in this implementation * @param id receives the texture ID, always 0 in this implementation
*/ */
video::ITexture* getTexture(const std::string &name, u32 *id = NULL); video::ITexture *getTexture(const std::string &name, u32 *id = NULL);
private: private:
/** driver to get textures from */ /** driver to get textures from */
video::IVideoDriver *m_driver; video::IVideoDriver *m_driver = nullptr;
/** set of texture names to delete */ /** set of texture names to delete */
std::set<std::string> m_to_delete; std::set<std::string> m_to_delete;
}; };
@ -150,13 +150,11 @@ public:
* @param smgr scene manager to add scene elements to * @param smgr scene manager to add scene elements to
* @param data struct to transfer data to main game handling * @param data struct to transfer data to main game handling
*/ */
GUIEngine(irr::IrrlichtDevice* dev, GUIEngine(JoystickController *joystick,
JoystickController *joystick, gui::IGUIElement *parent,
gui::IGUIElement* parent,
IMenuManager *menumgr, IMenuManager *menumgr,
scene::ISceneManager* smgr, MainMenuData *data,
MainMenuData* data, bool &kill);
bool& kill);
/** default destructor */ /** default destructor */
virtual ~GUIEngine(); virtual ~GUIEngine();
@ -164,7 +162,7 @@ public:
/** /**
* return MainMenuScripting interface * return MainMenuScripting interface
*/ */
MainMenuScripting* getScriptIface() MainMenuScripting *getScriptIface()
{ {
return m_script; return m_script;
} }
@ -192,16 +190,14 @@ private:
/** update size of topleftext element */ /** update size of topleftext element */
void updateTopLeftTextSize(); void updateTopLeftTextSize();
/** device to draw at */
irr::IrrlichtDevice* m_device;
/** parent gui element */ /** parent gui element */
gui::IGUIElement* m_parent; gui::IGUIElement *m_parent = nullptr;
/** manager to add menus to */ /** manager to add menus to */
IMenuManager* m_menumanager; IMenuManager *m_menumanager = nullptr;
/** scene manager to add scene elements to */ /** scene manager to add scene elements to */
scene::ISceneManager* m_smgr; scene::ISceneManager *m_smgr = nullptr;
/** pointer to data beeing transfered back to main game handling */ /** pointer to data beeing transfered back to main game handling */
MainMenuData* m_data; MainMenuData *m_data = nullptr;
/** pointer to texture source */ /** pointer to texture source */
ISimpleTextureSource *m_texture_source = nullptr; ISimpleTextureSource *m_texture_source = nullptr;
/** pointer to soundmanager*/ /** pointer to soundmanager*/
@ -215,7 +211,7 @@ private:
GUIFormSpecMenu *m_menu = nullptr; GUIFormSpecMenu *m_menu = nullptr;
/** reference to kill variable managed by SIGINT handler */ /** reference to kill variable managed by SIGINT handler */
bool& m_kill; bool &m_kill;
/** variable used to abort menu and return back to main game handling */ /** variable used to abort menu and return back to main game handling */
bool m_startgame = false; bool m_startgame = false;
@ -230,22 +226,22 @@ private:
* draw background layer * draw background layer
* @param driver to use for drawing * @param driver to use for drawing
*/ */
void drawBackground(video::IVideoDriver* driver); void drawBackground(video::IVideoDriver *driver);
/** /**
* draw overlay layer * draw overlay layer
* @param driver to use for drawing * @param driver to use for drawing
*/ */
void drawOverlay(video::IVideoDriver* driver); void drawOverlay(video::IVideoDriver *driver);
/** /**
* draw header layer * draw header layer
* @param driver to use for drawing * @param driver to use for drawing
*/ */
void drawHeader(video::IVideoDriver* driver); void drawHeader(video::IVideoDriver *driver);
/** /**
* draw footer layer * draw footer layer
* @param driver to use for drawing * @param driver to use for drawing
*/ */
void drawFooter(video::IVideoDriver* driver); void drawFooter(video::IVideoDriver *driver);
/** /**
* load a texture for a specified layer * load a texture for a specified layer
@ -290,9 +286,9 @@ private:
/** absolute time of last cloud processing */ /** absolute time of last cloud processing */
u32 lasttime; u32 lasttime;
/** pointer to cloud class */ /** pointer to cloud class */
Clouds* clouds; Clouds *clouds = nullptr;
/** camera required for drawing clouds */ /** camera required for drawing clouds */
scene::ICameraSceneNode* camera; scene::ICameraSceneNode *camera = nullptr;
}; };
/** is drawing of clouds enabled atm */ /** is drawing of clouds enabled atm */

View File

@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIFont.h> #include <IGUIFont.h>
#include <IGUITabControl.h> #include <IGUITabControl.h>
#include <IGUIComboBox.h> #include <IGUIComboBox.h>
#include "client/renderingengine.h"
#include "log.h" #include "log.h"
#include "client/tile.h" // ITextureSource #include "client/tile.h" // ITextureSource
#include "hud.h" // drawItemStack #include "hud.h" // drawItemStack
@ -78,14 +79,11 @@ static unsigned int font_line_height(gui::IGUIFont *font)
return font->getDimension(L"Ay").Height + font->getKerningHeight(); return font->getDimension(L"Ay").Height + font->getKerningHeight();
} }
GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, GUIFormSpecMenu::GUIFormSpecMenu(JoystickController *joystick,
JoystickController *joystick, gui::IGUIElement *parent, s32 id, IMenuManager *menumgr,
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, Client *client, ISimpleTextureSource *tsrc, IFormSource *fsrc, TextDest *tdst,
Client *client,
ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst,
bool remap_dbl_click) : bool remap_dbl_click) :
GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr), GUIModalMenu(RenderingEngine::get_gui_env(), parent, id, menumgr),
m_device(dev),
m_invmgr(client), m_invmgr(client),
m_tsrc(tsrc), m_tsrc(tsrc),
m_client(client), m_client(client),
@ -2054,7 +2052,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
if (mydata.explicit_size) { if (mydata.explicit_size) {
// compute scaling for specified form size // compute scaling for specified form size
if (m_lock) { if (m_lock) {
v2u32 current_screensize = m_device->getVideoDriver()->getScreenSize(); v2u32 current_screensize = RenderingEngine::get_video_driver()->getScreenSize();
v2u32 delta = current_screensize - m_lockscreensize; v2u32 delta = current_screensize - m_lockscreensize;
if (current_screensize.Y > m_lockscreensize.Y) if (current_screensize.Y > m_lockscreensize.Y)
@ -2075,7 +2073,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
} }
double gui_scaling = g_settings->getFloat("gui_scaling"); double gui_scaling = g_settings->getFloat("gui_scaling");
double screen_dpi = porting::getDisplayDensity() * 96; double screen_dpi = RenderingEngine::getDisplayDensity() * 96;
double use_imgsize; double use_imgsize;
if (m_lock) { if (m_lock) {
@ -2108,7 +2106,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
((5.0/4.0) * (0.5 + mydata.invsize.X)); ((5.0/4.0) * (0.5 + mydata.invsize.X));
double fity_imgsize = mydata.screensize.Y / double fity_imgsize = mydata.screensize.Y /
((15.0/13.0) * (0.85 * mydata.invsize.Y)); ((15.0/13.0) * (0.85 * mydata.invsize.Y));
double screen_dpi = porting::getDisplayDensity() * 96; double screen_dpi = RenderingEngine::getDisplayDensity() * 96;
double min_imgsize = 0.3 * screen_dpi * gui_scaling; double min_imgsize = 0.3 * screen_dpi * gui_scaling;
use_imgsize = MYMAX(min_imgsize, MYMIN(prefer_imgsize, use_imgsize = MYMAX(min_imgsize, MYMIN(prefer_imgsize,
MYMIN(fitx_imgsize, fity_imgsize))); MYMIN(fitx_imgsize, fity_imgsize)));
@ -2579,7 +2577,7 @@ void GUIFormSpecMenu::drawMenu()
/* TODO find way to show tooltips on touchscreen */ /* TODO find way to show tooltips on touchscreen */
#ifndef HAVE_TOUCHSCREENGUI #ifndef HAVE_TOUCHSCREENGUI
m_pointer = m_device->getCursorControl()->getPosition(); m_pointer = RenderingEngine::get_raw_device()->getCursorControl()->getPosition();
#endif #endif
/* /*
@ -3282,7 +3280,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
return true; return true;
} else if (m_client != NULL && event.KeyInput.PressedDown && } else if (m_client != NULL && event.KeyInput.PressedDown &&
(kp == getKeySetting("keymap_screenshot"))) { (kp == getKeySetting("keymap_screenshot"))) {
m_client->makeScreenshot(m_device); m_client->makeScreenshot();
} }
if (event.KeyInput.PressedDown && if (event.KeyInput.PressedDown &&
(event.KeyInput.Key==KEY_RETURN || (event.KeyInput.Key==KEY_RETURN ||
@ -3528,7 +3526,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
// Possibly send inventory action to server // Possibly send inventory action to server
if (move_amount > 0) { if (move_amount > 0) {
// Send IACTION_MOVE // Send IAction::Move
assert(m_selected_item && m_selected_item->isValid()); assert(m_selected_item && m_selected_item->isValid());
assert(s.isValid()); assert(s.isValid());
@ -3565,7 +3563,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
m_selected_content_guess = ItemStack(); // Clear m_selected_content_guess = ItemStack(); // Clear
} }
infostream << "Handing IACTION_MOVE to manager" << std::endl; infostream << "Handing IAction::Move to manager" << std::endl;
IMoveAction *a = new IMoveAction(); IMoveAction *a = new IMoveAction();
a->count = move_amount; a->count = move_amount;
a->from_inv = m_selected_item->inventoryloc; a->from_inv = m_selected_item->inventoryloc;
@ -3601,7 +3599,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
ItemStack stack_from = list_from->getItem(s.i); ItemStack stack_from = list_from->getItem(s.i);
assert(shift_move_amount <= stack_from.count); assert(shift_move_amount <= stack_from.count);
if (m_client->getProtoVersion() >= 25) { if (m_client->getProtoVersion() >= 25) {
infostream << "Handing IACTION_MOVE to manager" << std::endl; infostream << "Handing IAction::Move to manager" << std::endl;
IMoveAction *a = new IMoveAction(); IMoveAction *a = new IMoveAction();
a->count = shift_move_amount; a->count = shift_move_amount;
a->from_inv = s.inventoryloc; a->from_inv = s.inventoryloc;
@ -3619,7 +3617,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
&& shift_move_amount > 0; slot_to++) { && shift_move_amount > 0; slot_to++) {
list_to->itemFits(slot_to, stack_from, &leftover); list_to->itemFits(slot_to, stack_from, &leftover);
if (leftover.count < stack_from.count) { if (leftover.count < stack_from.count) {
infostream << "Handing IACTION_MOVE to manager" << std::endl; infostream << "Handing IAction::Move to manager" << std::endl;
IMoveAction *a = new IMoveAction(); IMoveAction *a = new IMoveAction();
a->count = MYMIN(shift_move_amount, a->count = MYMIN(shift_move_amount,
(u32) (stack_from.count - leftover.count)); (u32) (stack_from.count - leftover.count));
@ -3639,7 +3637,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
} else if (drop_amount > 0) { } else if (drop_amount > 0) {
m_selected_content_guess = ItemStack(); // Clear m_selected_content_guess = ItemStack(); // Clear
// Send IACTION_DROP // Send IAction::Drop
assert(m_selected_item && m_selected_item->isValid()); assert(m_selected_item && m_selected_item->isValid());
assert(inv_selected); assert(inv_selected);
@ -3652,7 +3650,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
assert(drop_amount > 0 && drop_amount <= m_selected_amount); assert(drop_amount > 0 && drop_amount <= m_selected_amount);
m_selected_amount -= drop_amount; m_selected_amount -= drop_amount;
infostream << "Handing IACTION_DROP to manager" << std::endl; infostream << "Handing IAction::Drop to manager" << std::endl;
IDropAction *a = new IDropAction(); IDropAction *a = new IDropAction();
a->count = drop_amount; a->count = drop_amount;
a->from_inv = m_selected_item->inventoryloc; a->from_inv = m_selected_item->inventoryloc;
@ -3662,12 +3660,12 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
} else if (craft_amount > 0) { } else if (craft_amount > 0) {
m_selected_content_guess = ItemStack(); // Clear m_selected_content_guess = ItemStack(); // Clear
// Send IACTION_CRAFT // Send IAction::Craft
assert(s.isValid()); assert(s.isValid());
assert(inv_s); assert(inv_s);
infostream << "Handing IACTION_CRAFT to manager" << std::endl; infostream << "Handing IAction::Craft to manager" << std::endl;
ICraftAction *a = new ICraftAction(); ICraftAction *a = new ICraftAction();
a->count = craft_amount; a->count = craft_amount;
a->craft_inv = s.inventoryloc; a->craft_inv = s.inventoryloc;

View File

@ -287,8 +287,7 @@ class GUIFormSpecMenu : public GUIModalMenu
}; };
public: public:
GUIFormSpecMenu(irr::IrrlichtDevice* dev, GUIFormSpecMenu(JoystickController *joystick,
JoystickController *joystick,
gui::IGUIElement* parent, s32 id, gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, IMenuManager *menumgr,
Client *client, Client *client,
@ -378,7 +377,6 @@ protected:
v2s32 pos_offset; v2s32 pos_offset;
std::stack<v2s32> container_stack; std::stack<v2s32> container_stack;
irr::IrrlichtDevice* m_device;
InventoryManager *m_invmgr; InventoryManager *m_invmgr;
ISimpleTextureSource *m_tsrc; ISimpleTextureSource *m_tsrc;
Client *m_client; Client *m_client;
@ -386,7 +384,6 @@ protected:
std::string m_formspec_string; std::string m_formspec_string;
InventoryLocation m_current_inventory_location; InventoryLocation m_current_inventory_location;
std::vector<ListDrawSpec> m_inventorylists; std::vector<ListDrawSpec> m_inventorylists;
std::vector<ListRingSpec> m_inventory_rings; std::vector<ListRingSpec> m_inventory_rings;
std::vector<ImageDrawSpec> m_backgrounds; std::vector<ImageDrawSpec> m_backgrounds;

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUISkin.h> #include <IGUISkin.h>
#include <IGUIFont.h> #include <IGUIFont.h>
#include <IGUIScrollBar.h> #include <IGUIScrollBar.h>
#include "client/renderingengine.h"
#include "debug.h" #include "debug.h"
#include "log.h" #include "log.h"
#include "client/tile.h" #include "client/tile.h"
@ -79,7 +80,8 @@ GUITable::GUITable(gui::IGUIEnvironment *env,
updateAbsolutePosition(); updateAbsolutePosition();
core::rect<s32> relative_rect = m_scrollbar->getRelativePosition(); core::rect<s32> relative_rect = m_scrollbar->getRelativePosition();
s32 width = (relative_rect.getWidth()/(2.0/3.0)) * porting::getDisplayDensity() * s32 width = (relative_rect.getWidth()/(2.0/3.0)) *
RenderingEngine::getDisplayDensity() *
g_settings->getFloat("gui_scaling"); g_settings->getFloat("gui_scaling");
m_scrollbar->setRelativePosition(core::rect<s32>( m_scrollbar->setRelativePosition(core::rect<s32>(
relative_rect.LowerRightCorner.X-width,relative_rect.UpperLeftCorner.Y, relative_rect.LowerRightCorner.X-width,relative_rect.UpperLeftCorner.Y,

View File

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "util/numeric.h" #include "util/numeric.h"
#include <stdio.h> #include <stdio.h>
#include "client/renderingengine.h"
/* Maintain a static cache to store the images that correspond to textures /* Maintain a static cache to store the images that correspond to textures
* in a format that's manipulable by code. Some platforms exhibit issues * in a format that's manipulable by code. Some platforms exhibit issues
@ -48,18 +49,18 @@ void guiScalingCache(io::path key, video::IVideoDriver *driver, video::IImage *v
} }
// Manually clear the cache, e.g. when switching to different worlds. // Manually clear the cache, e.g. when switching to different worlds.
void guiScalingCacheClear(video::IVideoDriver *driver) void guiScalingCacheClear()
{ {
for (std::map<io::path, video::IImage *>::iterator it = g_imgCache.begin(); for (std::map<io::path, video::IImage *>::iterator it = g_imgCache.begin();
it != g_imgCache.end(); ++it) { it != g_imgCache.end(); ++it) {
if (it->second != NULL) if (it->second)
it->second->drop(); it->second->drop();
} }
g_imgCache.clear(); g_imgCache.clear();
for (std::map<io::path, video::ITexture *>::iterator it = g_txrCache.begin(); for (std::map<io::path, video::ITexture *>::iterator it = g_txrCache.begin();
it != g_txrCache.end(); ++it) { it != g_txrCache.end(); ++it) {
if (it->second != NULL) if (it->second)
driver->removeTexture(it->second); RenderingEngine::get_video_driver()->removeTexture(it->second);
} }
g_txrCache.clear(); g_txrCache.clear();
} }

View File

@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
void guiScalingCache(io::path key, video::IVideoDriver *driver, video::IImage *value); void guiScalingCache(io::path key, video::IVideoDriver *driver, video::IImage *value);
// Manually clear the cache, e.g. when switching to different worlds. // Manually clear the cache, e.g. when switching to different worlds.
void guiScalingCacheClear(video::IVideoDriver *driver); void guiScalingCacheClear();
/* Get a cached, high-quality pre-scaled texture for display purposes. If the /* Get a cached, high-quality pre-scaled texture for display purposes. If the
* texture is not already cached, attempt to create it. Returns a pre-scaled texture, * texture is not already cached, attempt to create it. Returns a pre-scaled texture,

View File

@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mesh.h" #include "mesh.h"
#include "wieldmesh.h" #include "wieldmesh.h"
#include <IGUIStaticText.h> #include <IGUIStaticText.h>
#include "client/renderingengine.h"
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
#include "touchscreengui.h" #include "touchscreengui.h"
@ -51,7 +52,8 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
this->inventory = inventory; this->inventory = inventory;
m_hud_scaling = g_settings->getFloat("hud_scaling"); m_hud_scaling = g_settings->getFloat("hud_scaling");
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5); m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE *
RenderingEngine::getDisplayDensity() + 0.5f);
m_hotbar_imagesize *= m_hud_scaling; m_hotbar_imagesize *= m_hud_scaling;
m_padding = m_hotbar_imagesize / 12; m_padding = m_hotbar_imagesize / 12;
@ -120,79 +122,79 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
bool selected) bool selected)
{ {
if (selected) { if (selected) {
/* draw hihlighting around selected item */ /* draw hihlighting around selected item */
if (use_hotbar_selected_image) { if (use_hotbar_selected_image) {
core::rect<s32> imgrect2 = rect; core::rect<s32> imgrect2 = rect;
imgrect2.UpperLeftCorner.X -= (m_padding*2); imgrect2.UpperLeftCorner.X -= (m_padding*2);
imgrect2.UpperLeftCorner.Y -= (m_padding*2); imgrect2.UpperLeftCorner.Y -= (m_padding*2);
imgrect2.LowerRightCorner.X += (m_padding*2); imgrect2.LowerRightCorner.X += (m_padding*2);
imgrect2.LowerRightCorner.Y += (m_padding*2); imgrect2.LowerRightCorner.Y += (m_padding*2);
video::ITexture *texture = tsrc->getTexture(hotbar_selected_image); video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
core::dimension2di imgsize(texture->getOriginalSize()); core::dimension2di imgsize(texture->getOriginalSize());
draw2DImageFilterScaled(driver, texture, imgrect2, draw2DImageFilterScaled(driver, texture, imgrect2,
core::rect<s32>(core::position2d<s32>(0,0), imgsize), core::rect<s32>(core::position2d<s32>(0,0), imgsize),
NULL, hbar_colors, true); NULL, hbar_colors, true);
} else { } else {
video::SColor c_outside(255,255,0,0); video::SColor c_outside(255,255,0,0);
//video::SColor c_outside(255,0,0,0); //video::SColor c_outside(255,0,0,0);
//video::SColor c_inside(255,192,192,192); //video::SColor c_inside(255,192,192,192);
s32 x1 = rect.UpperLeftCorner.X; s32 x1 = rect.UpperLeftCorner.X;
s32 y1 = rect.UpperLeftCorner.Y; s32 y1 = rect.UpperLeftCorner.Y;
s32 x2 = rect.LowerRightCorner.X; s32 x2 = rect.LowerRightCorner.X;
s32 y2 = rect.LowerRightCorner.Y; s32 y2 = rect.LowerRightCorner.Y;
// Black base borders // Black base borders
driver->draw2DRectangle(c_outside, driver->draw2DRectangle(c_outside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - m_padding, y1 - m_padding), v2s32(x1 - m_padding, y1 - m_padding),
v2s32(x2 + m_padding, y1) v2s32(x2 + m_padding, y1)
), NULL); ), NULL);
driver->draw2DRectangle(c_outside, driver->draw2DRectangle(c_outside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - m_padding, y2), v2s32(x1 - m_padding, y2),
v2s32(x2 + m_padding, y2 + m_padding) v2s32(x2 + m_padding, y2 + m_padding)
), NULL); ), NULL);
driver->draw2DRectangle(c_outside, driver->draw2DRectangle(c_outside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - m_padding, y1), v2s32(x1 - m_padding, y1),
v2s32(x1, y2) v2s32(x1, y2)
), NULL); ), NULL);
driver->draw2DRectangle(c_outside, driver->draw2DRectangle(c_outside,
core::rect<s32>( core::rect<s32>(
v2s32(x2, y1), v2s32(x2, y1),
v2s32(x2 + m_padding, y2) v2s32(x2 + m_padding, y2)
), NULL); ), NULL);
/*// Light inside borders /*// Light inside borders
driver->draw2DRectangle(c_inside, driver->draw2DRectangle(c_inside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - padding/2, y1 - padding/2), v2s32(x1 - padding/2, y1 - padding/2),
v2s32(x2 + padding/2, y1) v2s32(x2 + padding/2, y1)
), NULL); ), NULL);
driver->draw2DRectangle(c_inside, driver->draw2DRectangle(c_inside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - padding/2, y2), v2s32(x1 - padding/2, y2),
v2s32(x2 + padding/2, y2 + padding/2) v2s32(x2 + padding/2, y2 + padding/2)
), NULL); ), NULL);
driver->draw2DRectangle(c_inside, driver->draw2DRectangle(c_inside,
core::rect<s32>( core::rect<s32>(
v2s32(x1 - padding/2, y1), v2s32(x1 - padding/2, y1),
v2s32(x1, y2) v2s32(x1, y2)
), NULL); ), NULL);
driver->draw2DRectangle(c_inside, driver->draw2DRectangle(c_inside,
core::rect<s32>( core::rect<s32>(
v2s32(x2, y1), v2s32(x2, y1),
v2s32(x2 + padding/2, y2) v2s32(x2 + padding/2, y2)
), NULL); ), NULL);
*/ */
}
} }
video::SColor bgcolor2(128, 0, 0, 0);
if (!use_hotbar_image)
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
client, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
} }
video::SColor bgcolor2(128, 0, 0, 0);
if (!use_hotbar_image)
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
client, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
}
//NOTE: selectitem = 0 -> no selected; selectitem 1-based //NOTE: selectitem = 0 -> no selected; selectitem 1-based
void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount, void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction) s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
@ -213,8 +215,8 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
// Position of upper left corner of bar // Position of upper left corner of bar
v2s32 pos = screen_offset; v2s32 pos = screen_offset;
pos.X *= m_hud_scaling * porting::getDisplayDensity(); pos.X *= m_hud_scaling * RenderingEngine::getDisplayDensity();
pos.Y *= m_hud_scaling * porting::getDisplayDensity(); pos.Y *= m_hud_scaling * RenderingEngine::getDisplayDensity();
pos += upperleftpos; pos += upperleftpos;
// Store hotbar_image in member variable, used by drawItem() // Store hotbar_image in member variable, used by drawItem()
@ -384,7 +386,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
if (size == v2s32()) { if (size == v2s32()) {
dstd = srcd; dstd = srcd;
} else { } else {
float size_factor = m_hud_scaling * porting::getDisplayDensity(); float size_factor = m_hud_scaling * RenderingEngine::getDisplayDensity();
dstd.Height = size.Y * size_factor; dstd.Height = size.Y * size_factor;
dstd.Width = size.X * size_factor; dstd.Width = size.X * size_factor;
offset.X *= size_factor; offset.X *= size_factor;
@ -449,7 +451,8 @@ void Hud::drawHotbar(u16 playeritem) {
s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2); s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3); v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
if ( (float) width / (float) porting::getWindowSize().X <= const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
if ( (float) width / (float) window_size.X <=
g_settings->getFloat("hud_hotbar_max_width")) { g_settings->getFloat("hud_hotbar_max_width")) {
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) { if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0); drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
@ -607,11 +610,14 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
} }
void Hud::resizeHotbar() { void Hud::resizeHotbar() {
if (m_screensize != porting::getWindowSize()) { const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
if (m_screensize != window_size) {
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE *
RenderingEngine::getDisplayDensity() + 0.5);
m_hotbar_imagesize *= m_hud_scaling; m_hotbar_imagesize *= m_hud_scaling;
m_padding = m_hotbar_imagesize / 12; m_padding = m_hotbar_imagesize / 12;
m_screensize = porting::getWindowSize(); m_screensize = window_size;
m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2); m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
} }
} }

View File

@ -118,7 +118,7 @@ public:
std::string hotbar_image = ""; std::string hotbar_image = "";
bool use_hotbar_image = false; bool use_hotbar_image = false;
std::string hotbar_selected_image = ""; std::string hotbar_selected_image = "";
bool use_hotbar_selected_image; bool use_hotbar_selected_image = false;
Hud(video::IVideoDriver *driver,scene::ISceneManager* smgr, Hud(video::IVideoDriver *driver,scene::ISceneManager* smgr,
gui::IGUIEnvironment* guienv, Client *client, LocalPlayer *player, gui::IGUIEnvironment* guienv, Client *client, LocalPlayer *player,

View File

@ -254,11 +254,8 @@ std::string ItemStack::getItemString() const
} }
ItemStack ItemStack::addItem(const ItemStack &newitem_, ItemStack ItemStack::addItem(ItemStack newitem, IItemDefManager *itemdef)
IItemDefManager *itemdef)
{ {
ItemStack newitem = newitem_;
// If the item is empty or the position invalid, bail out // If the item is empty or the position invalid, bail out
if(newitem.empty()) if(newitem.empty())
{ {
@ -267,8 +264,17 @@ ItemStack ItemStack::addItem(const ItemStack &newitem_,
// If this is an empty item, it's an easy job. // If this is an empty item, it's an easy job.
else if(empty()) else if(empty())
{ {
const u16 stackMax = newitem.getStackMax(itemdef);
*this = newitem; *this = newitem;
newitem.clear();
// If the item fits fully, delete it
if (count <= stackMax) {
newitem.clear();
} else { // Else the item does not fit fully. Return the rest.
count = stackMax;
newitem.remove(count);
}
} }
// If item name or metadata differs, bail out // If item name or metadata differs, bail out
else if (name != newitem.name else if (name != newitem.name
@ -294,11 +300,10 @@ ItemStack ItemStack::addItem(const ItemStack &newitem_,
return newitem; return newitem;
} }
bool ItemStack::itemFits(const ItemStack &newitem_, bool ItemStack::itemFits(ItemStack newitem,
ItemStack *restitem, ItemStack *restitem,
IItemDefManager *itemdef) const IItemDefManager *itemdef) const
{ {
ItemStack newitem = newitem_;
// If the item is empty or the position invalid, bail out // If the item is empty or the position invalid, bail out
if(newitem.empty()) if(newitem.empty())
@ -308,7 +313,14 @@ bool ItemStack::itemFits(const ItemStack &newitem_,
// If this is an empty item, it's an easy job. // If this is an empty item, it's an easy job.
else if(empty()) else if(empty())
{ {
newitem.clear(); const u16 stackMax = newitem.getStackMax(itemdef);
// If the item fits fully, delete it
if (newitem.count <= stackMax) {
newitem.clear();
} else { // Else the item does not fit fully. Return the rest.
newitem.remove(stackMax);
}
} }
// If item name or metadata differs, bail out // If item name or metadata differs, bail out
else if (name != newitem.name else if (name != newitem.name
@ -322,7 +334,6 @@ bool ItemStack::itemFits(const ItemStack &newitem_,
newitem.clear(); newitem.clear();
} }
// Else the item does not fit fully. Return the rest. // Else the item does not fit fully. Return the rest.
// the rest.
else else
{ {
u16 freespace = freeSpace(itemdef); u16 freespace = freeSpace(itemdef);
@ -658,7 +669,7 @@ bool InventoryList::roomForItem(const ItemStack &item_) const
return false; return false;
} }
bool InventoryList::containsItem(const ItemStack &item) const bool InventoryList::containsItem(const ItemStack &item, bool match_meta) const
{ {
u32 count = item.count; u32 count = item.count;
if(count == 0) if(count == 0)
@ -669,9 +680,9 @@ bool InventoryList::containsItem(const ItemStack &item) const
{ {
if(count == 0) if(count == 0)
break; break;
if(i->name == item.name) if (i->name == item.name
{ && (!match_meta || (i->metadata == item.metadata))) {
if(i->count >= count) if (i->count >= count)
return true; return true;
else else
count -= i->count; count -= i->count;

View File

@ -146,13 +146,12 @@ struct ItemStack
// If cannot be added at all, returns the item back. // If cannot be added at all, returns the item back.
// If can be added partly, decremented item is returned back. // If can be added partly, decremented item is returned back.
// If can be added fully, empty item is returned. // If can be added fully, empty item is returned.
ItemStack addItem(const ItemStack &newitem, ItemStack addItem(ItemStack newitem, IItemDefManager *itemdef);
IItemDefManager *itemdef);
// Checks whether newitem could be added. // Checks whether newitem could be added.
// If restitem is non-NULL, it receives the part of newitem that // If restitem is non-NULL, it receives the part of newitem that
// would be left over after adding. // would be left over after adding.
bool itemFits(const ItemStack &newitem, bool itemFits(ItemStack newitem,
ItemStack *restitem, // may be NULL ItemStack *restitem, // may be NULL
IItemDefManager *itemdef) const; IItemDefManager *itemdef) const;
@ -226,9 +225,10 @@ public:
// Checks whether there is room for a given item // Checks whether there is room for a given item
bool roomForItem(const ItemStack &item) const; bool roomForItem(const ItemStack &item) const;
// Checks whether the given count of the given item name // Checks whether the given count of the given item
// exists in this inventory list. // exists in this inventory list.
bool containsItem(const ItemStack &item) const; // If match_meta is false, only the items' names are compared.
bool containsItem(const ItemStack &item, bool match_meta) const;
// Removes the given count of the given item name from // Removes the given count of the given item name from
// this inventory list. Walks the list in reverse order. // this inventory list. Walks the list in reverse order.

View File

@ -43,7 +43,7 @@ std::string InventoryLocation::dump() const
void InventoryLocation::serialize(std::ostream &os) const void InventoryLocation::serialize(std::ostream &os) const
{ {
switch(type){ switch (type) {
case InventoryLocation::UNDEFINED: case InventoryLocation::UNDEFINED:
os<<"undefined"; os<<"undefined";
break; break;
@ -68,21 +68,14 @@ void InventoryLocation::deSerialize(std::istream &is)
{ {
std::string tname; std::string tname;
std::getline(is, tname, ':'); std::getline(is, tname, ':');
if(tname == "undefined") if (tname == "undefined") {
{
type = InventoryLocation::UNDEFINED; type = InventoryLocation::UNDEFINED;
} } else if (tname == "current_player") {
else if(tname == "current_player")
{
type = InventoryLocation::CURRENT_PLAYER; type = InventoryLocation::CURRENT_PLAYER;
} } else if (tname == "player") {
else if(tname == "player")
{
type = InventoryLocation::PLAYER; type = InventoryLocation::PLAYER;
std::getline(is, name, '\n'); std::getline(is, name, '\n');
} } else if (tname == "nodemeta") {
else if(tname == "nodemeta")
{
type = InventoryLocation::NODEMETA; type = InventoryLocation::NODEMETA;
std::string pos; std::string pos;
std::getline(is, pos, '\n'); std::getline(is, pos, '\n');
@ -90,14 +83,10 @@ void InventoryLocation::deSerialize(std::istream &is)
p.X = stoi(fn.next(",")); p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(",")); p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(",")); p.Z = stoi(fn.next(","));
} } else if (tname == "detached") {
else if(tname == "detached")
{
type = InventoryLocation::DETACHED; type = InventoryLocation::DETACHED;
std::getline(is, name, '\n'); std::getline(is, name, '\n');
} } else {
else
{
infostream<<"Unknown InventoryLocation type=\""<<tname<<"\""<<std::endl; infostream<<"Unknown InventoryLocation type=\""<<tname<<"\""<<std::endl;
throw SerializationError("Unknown InventoryLocation type"); throw SerializationError("Unknown InventoryLocation type");
} }
@ -113,12 +102,12 @@ void InventoryLocation::deSerialize(std::string s)
InventoryAction InventoryAction
*/ */
InventoryAction * InventoryAction::deSerialize(std::istream &is) InventoryAction *InventoryAction::deSerialize(std::istream &is)
{ {
std::string type; std::string type;
std::getline(is, type, ' '); std::getline(is, type, ' ');
InventoryAction *a = NULL; InventoryAction *a = nullptr;
if (type == "Move") { if (type == "Move") {
a = new IMoveAction(is, false); a = new IMoveAction(is, false);
@ -126,7 +115,7 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
a = new IMoveAction(is, true); a = new IMoveAction(is, true);
} else if (type == "Drop") { } else if (type == "Drop") {
a = new IDropAction(is); a = new IDropAction(is);
} else if(type == "Craft") { } else if (type == "Craft") {
a = new ICraftAction(is); a = new ICraftAction(is);
} }
@ -137,12 +126,10 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
IMoveAction IMoveAction
*/ */
IMoveAction::IMoveAction(std::istream &is, bool somewhere) IMoveAction::IMoveAction(std::istream &is, bool somewhere) :
move_somewhere(somewhere)
{ {
std::string ts; std::string ts;
move_somewhere = somewhere;
caused_by_move_somewhere = false;
move_count = 0;
std::getline(is, ts, ' '); std::getline(is, ts, ' ');
count = stoi(ts); count = stoi(ts);
@ -265,7 +252,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
*/ */
int try_take_count = count; int try_take_count = count;
if(try_take_count == 0) if (try_take_count == 0)
try_take_count = list_from->getItem(from_i).count; try_take_count = list_from->getItem(from_i).count;
int src_can_take_count = 0xffff; int src_can_take_count = 0xffff;
@ -274,28 +261,23 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* Query detached inventories */ /* Query detached inventories */
// Move occurs in the same detached inventory // Move occurs in the same detached inventory
if(from_inv.type == InventoryLocation::DETACHED && if (from_inv.type == InventoryLocation::DETACHED &&
to_inv.type == InventoryLocation::DETACHED && to_inv.type == InventoryLocation::DETACHED &&
from_inv.name == to_inv.name) from_inv.name == to_inv.name) {
{
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowMove( src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowMove(
from_inv.name, from_list, from_i, from_inv.name, from_list, from_i,
to_list, to_i, try_take_count, player); to_list, to_i, try_take_count, player);
dst_can_put_count = src_can_take_count; dst_can_put_count = src_can_take_count;
} } else {
else
{
// Destination is detached // Destination is detached
if(to_inv.type == InventoryLocation::DETACHED) if (to_inv.type == InventoryLocation::DETACHED) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = try_take_count; src_item.count = try_take_count;
dst_can_put_count = PLAYER_TO_SA(player)->detached_inventory_AllowPut( dst_can_put_count = PLAYER_TO_SA(player)->detached_inventory_AllowPut(
to_inv.name, to_list, to_i, src_item, player); to_inv.name, to_list, to_i, src_item, player);
} }
// Source is detached // Source is detached
if(from_inv.type == InventoryLocation::DETACHED) if (from_inv.type == InventoryLocation::DETACHED) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = try_take_count; src_item.count = try_take_count;
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake( src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake(
@ -307,28 +289,23 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
// Both endpoints are nodemeta // Both endpoints are nodemeta
// Move occurs in the same nodemeta inventory // Move occurs in the same nodemeta inventory
if(from_inv.type == InventoryLocation::NODEMETA && if (from_inv.type == InventoryLocation::NODEMETA &&
to_inv.type == InventoryLocation::NODEMETA && to_inv.type == InventoryLocation::NODEMETA &&
from_inv.p == to_inv.p) from_inv.p == to_inv.p) {
{
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowMove( src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowMove(
from_inv.p, from_list, from_i, from_inv.p, from_list, from_i,
to_list, to_i, try_take_count, player); to_list, to_i, try_take_count, player);
dst_can_put_count = src_can_take_count; dst_can_put_count = src_can_take_count;
} } else {
else
{
// Destination is nodemeta // Destination is nodemeta
if(to_inv.type == InventoryLocation::NODEMETA) if (to_inv.type == InventoryLocation::NODEMETA) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = try_take_count; src_item.count = try_take_count;
dst_can_put_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowPut( dst_can_put_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowPut(
to_inv.p, to_list, to_i, src_item, player); to_inv.p, to_list, to_i, src_item, player);
} }
// Source is nodemeta // Source is nodemeta
if(from_inv.type == InventoryLocation::NODEMETA) if (from_inv.type == InventoryLocation::NODEMETA) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = try_take_count; src_item.count = try_take_count;
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake( src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake(
@ -340,17 +317,16 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* Modify count according to collected data */ /* Modify count according to collected data */
count = try_take_count; count = try_take_count;
if(src_can_take_count != -1 && count > src_can_take_count) if (src_can_take_count != -1 && count > src_can_take_count)
count = src_can_take_count; count = src_can_take_count;
if(dst_can_put_count != -1 && count > dst_can_put_count) if (dst_can_put_count != -1 && count > dst_can_put_count)
count = dst_can_put_count; count = dst_can_put_count;
/* Limit according to source item count */ /* Limit according to source item count */
if(count > list_from->getItem(from_i).count) if (count > list_from->getItem(from_i).count)
count = list_from->getItem(from_i).count; count = list_from->getItem(from_i).count;
/* If no items will be moved, don't go further */ /* If no items will be moved, don't go further */
if(count == 0) if (count == 0) {
{
infostream<<"IMoveAction::apply(): move was completely disallowed:" infostream<<"IMoveAction::apply(): move was completely disallowed:"
<<" count="<<old_count <<" count="<<old_count
<<" from inv=\""<<from_inv.dump()<<"\"" <<" from inv=\""<<from_inv.dump()<<"\""
@ -403,7 +379,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
} }
} }
// If destination is infinite, reset it's stack and take count from source // If destination is infinite, reset it's stack and take count from source
if(dst_can_put_count == -1){ if (dst_can_put_count == -1) {
list_to->deleteItem(to_i); list_to->deleteItem(to_i);
list_to->addItem(to_i, to_stack_was); list_to->addItem(to_i, to_stack_was);
list_from->deleteItem(from_i); list_from->deleteItem(from_i);
@ -426,19 +402,17 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
// If we are inside the move somewhere loop, we don't need to report // If we are inside the move somewhere loop, we don't need to report
// anything if nothing happened (perhaps we don't need to report // anything if nothing happened (perhaps we don't need to report
// anything for caused_by_move_somewhere == true, but this way its safer) // anything for caused_by_move_somewhere == true, but this way its safer)
if (caused_by_move_somewhere && move_count == 0) { if (caused_by_move_somewhere && move_count == 0)
return; return;
}
/* /*
Record rollback information Record rollback information
*/ */
if(!ignore_rollback && gamedef->rollback()) if (!ignore_rollback && gamedef->rollback()) {
{
IRollbackManager *rollback = gamedef->rollback(); IRollbackManager *rollback = gamedef->rollback();
// If source is not infinite, record item take // If source is not infinite, record item take
if(src_can_take_count != -1){ if (src_can_take_count != -1) {
RollbackAction action; RollbackAction action;
std::string loc; std::string loc;
{ {
@ -451,7 +425,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
rollback->reportAction(action); rollback->reportAction(action);
} }
// If destination is not infinite, record item put // If destination is not infinite, record item put
if(dst_can_put_count != -1){ if (dst_can_put_count != -1) {
RollbackAction action; RollbackAction action;
std::string loc; std::string loc;
{ {
@ -472,25 +446,20 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* Detached inventories */ /* Detached inventories */
// Both endpoints are same detached // Both endpoints are same detached
if(from_inv.type == InventoryLocation::DETACHED && if (from_inv.type == InventoryLocation::DETACHED &&
to_inv.type == InventoryLocation::DETACHED && to_inv.type == InventoryLocation::DETACHED &&
from_inv.name == to_inv.name) from_inv.name == to_inv.name) {
{
PLAYER_TO_SA(player)->detached_inventory_OnMove( PLAYER_TO_SA(player)->detached_inventory_OnMove(
from_inv.name, from_list, from_i, from_inv.name, from_list, from_i,
to_list, to_i, count, player); to_list, to_i, count, player);
} } else {
else
{
// Destination is detached // Destination is detached
if(to_inv.type == InventoryLocation::DETACHED) if (to_inv.type == InventoryLocation::DETACHED) {
{
PLAYER_TO_SA(player)->detached_inventory_OnPut( PLAYER_TO_SA(player)->detached_inventory_OnPut(
to_inv.name, to_list, to_i, src_item, player); to_inv.name, to_list, to_i, src_item, player);
} }
// Source is detached // Source is detached
if(from_inv.type == InventoryLocation::DETACHED) if (from_inv.type == InventoryLocation::DETACHED) {
{
PLAYER_TO_SA(player)->detached_inventory_OnTake( PLAYER_TO_SA(player)->detached_inventory_OnTake(
from_inv.name, from_list, from_i, src_item, player); from_inv.name, from_list, from_i, src_item, player);
} }
@ -499,31 +468,27 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* Node metadata inventories */ /* Node metadata inventories */
// Both endpoints are same nodemeta // Both endpoints are same nodemeta
if(from_inv.type == InventoryLocation::NODEMETA && if (from_inv.type == InventoryLocation::NODEMETA &&
to_inv.type == InventoryLocation::NODEMETA && to_inv.type == InventoryLocation::NODEMETA &&
from_inv.p == to_inv.p) from_inv.p == to_inv.p) {
{
PLAYER_TO_SA(player)->nodemeta_inventory_OnMove( PLAYER_TO_SA(player)->nodemeta_inventory_OnMove(
from_inv.p, from_list, from_i, from_inv.p, from_list, from_i,
to_list, to_i, count, player); to_list, to_i, count, player);
} } else {
else{
// Destination is nodemeta // Destination is nodemeta
if(to_inv.type == InventoryLocation::NODEMETA) if (to_inv.type == InventoryLocation::NODEMETA) {
{
PLAYER_TO_SA(player)->nodemeta_inventory_OnPut( PLAYER_TO_SA(player)->nodemeta_inventory_OnPut(
to_inv.p, to_list, to_i, src_item, player); to_inv.p, to_list, to_i, src_item, player);
} }
// Source is nodemeta // Source is nodemeta
else if(from_inv.type == InventoryLocation::NODEMETA) else if (from_inv.type == InventoryLocation::NODEMETA) {
{
PLAYER_TO_SA(player)->nodemeta_inventory_OnTake( PLAYER_TO_SA(player)->nodemeta_inventory_OnTake(
from_inv.p, from_list, from_i, src_item, player); from_inv.p, from_list, from_i, src_item, player);
} }
} }
mgr->setInventoryModified(from_inv, false); mgr->setInventoryModified(from_inv, false);
if(inv_from != inv_to) if (inv_from != inv_to)
mgr->setInventoryModified(to_inv, false); mgr->setInventoryModified(to_inv, false);
} }
@ -534,18 +499,18 @@ void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
Inventory *inv_from = mgr->getInventory(from_inv); Inventory *inv_from = mgr->getInventory(from_inv);
Inventory *inv_to = mgr->getInventory(to_inv); Inventory *inv_to = mgr->getInventory(to_inv);
if(!inv_from || !inv_to) if (!inv_from || !inv_to)
return; return;
InventoryLocation current_player; InventoryLocation current_player;
current_player.setCurrentPlayer(); current_player.setCurrentPlayer();
Inventory *inv_player = mgr->getInventory(current_player); Inventory *inv_player = mgr->getInventory(current_player);
if(inv_from != inv_player || inv_to != inv_player) if (inv_from != inv_player || inv_to != inv_player)
return; return;
InventoryList *list_from = inv_from->getList(from_list); InventoryList *list_from = inv_from->getList(from_list);
InventoryList *list_to = inv_to->getList(to_list); InventoryList *list_to = inv_to->getList(to_list);
if(!list_from || !list_to) if (!list_from || !list_to)
return; return;
if (!move_somewhere) if (!move_somewhere)
@ -554,7 +519,7 @@ void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
list_from->moveItemSomewhere(from_i, list_to, count); list_from->moveItemSomewhere(from_i, list_to, count);
mgr->setInventoryModified(from_inv); mgr->setInventoryModified(from_inv);
if(inv_from != inv_to) if (inv_from != inv_to)
mgr->setInventoryModified(to_inv); mgr->setInventoryModified(to_inv);
} }
@ -582,7 +547,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
{ {
Inventory *inv_from = mgr->getInventory(from_inv); Inventory *inv_from = mgr->getInventory(from_inv);
if(!inv_from){ if (!inv_from) {
infostream<<"IDropAction::apply(): FAIL: source inventory not found: " infostream<<"IDropAction::apply(): FAIL: source inventory not found: "
<<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl; <<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl;
return; return;
@ -593,13 +558,12 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* /*
If a list doesn't exist or the source item doesn't exist If a list doesn't exist or the source item doesn't exist
*/ */
if(!list_from){ if (!list_from) {
infostream<<"IDropAction::apply(): FAIL: source list not found: " infostream<<"IDropAction::apply(): FAIL: source list not found: "
<<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl; <<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl;
return; return;
} }
if(list_from->getItem(from_i).empty()) if (list_from->getItem(from_i).empty()) {
{
infostream<<"IDropAction::apply(): FAIL: source item not found: " infostream<<"IDropAction::apply(): FAIL: source item not found: "
<<"from_inv=\""<<from_inv.dump()<<"\"" <<"from_inv=\""<<from_inv.dump()<<"\""
<<", from_list=\""<<from_list<<"\"" <<", from_list=\""<<from_list<<"\""
@ -617,13 +581,12 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
*/ */
int take_count = list_from->getItem(from_i).count; int take_count = list_from->getItem(from_i).count;
if(count != 0 && count < take_count) if (count != 0 && count < take_count)
take_count = count; take_count = count;
int src_can_take_count = take_count; int src_can_take_count = take_count;
// Source is detached // Source is detached
if(from_inv.type == InventoryLocation::DETACHED) if (from_inv.type == InventoryLocation::DETACHED) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = take_count; src_item.count = take_count;
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake( src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake(
@ -631,15 +594,14 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
} }
// Source is nodemeta // Source is nodemeta
if(from_inv.type == InventoryLocation::NODEMETA) if (from_inv.type == InventoryLocation::NODEMETA) {
{
ItemStack src_item = list_from->getItem(from_i); ItemStack src_item = list_from->getItem(from_i);
src_item.count = take_count; src_item.count = take_count;
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake( src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake(
from_inv.p, from_list, from_i, src_item, player); from_inv.p, from_list, from_i, src_item, player);
} }
if(src_can_take_count != -1 && src_can_take_count < take_count) if (src_can_take_count != -1 && src_can_take_count < take_count)
take_count = src_can_take_count; take_count = src_can_take_count;
int actually_dropped_count = 0; int actually_dropped_count = 0;
@ -649,22 +611,21 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
// Drop the item // Drop the item
ItemStack item1 = list_from->getItem(from_i); ItemStack item1 = list_from->getItem(from_i);
item1.count = take_count; item1.count = take_count;
if(PLAYER_TO_SA(player)->item_OnDrop(item1, player, if (PLAYER_TO_SA(player)->item_OnDrop(item1, player,
player->getBasePosition() + v3f(0,1,0))) player->getBasePosition() + v3f(0,1,0))) {
{
actually_dropped_count = take_count - item1.count; actually_dropped_count = take_count - item1.count;
if(actually_dropped_count == 0){ if (actually_dropped_count == 0) {
infostream<<"Actually dropped no items"<<std::endl; infostream<<"Actually dropped no items"<<std::endl;
return; return;
} }
// If source isn't infinite // If source isn't infinite
if(src_can_take_count != -1){ if (src_can_take_count != -1) {
// Take item from source list // Take item from source list
ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count); ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count);
if(item2.count != actually_dropped_count) if (item2.count != actually_dropped_count)
errorstream<<"Could not take dropped count of items"<<std::endl; errorstream<<"Could not take dropped count of items"<<std::endl;
mgr->setInventoryModified(from_inv, false); mgr->setInventoryModified(from_inv, false);
@ -684,15 +645,13 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
*/ */
// Source is detached // Source is detached
if(from_inv.type == InventoryLocation::DETACHED) if (from_inv.type == InventoryLocation::DETACHED) {
{
PLAYER_TO_SA(player)->detached_inventory_OnTake( PLAYER_TO_SA(player)->detached_inventory_OnTake(
from_inv.name, from_list, from_i, src_item, player); from_inv.name, from_list, from_i, src_item, player);
} }
// Source is nodemeta // Source is nodemeta
if(from_inv.type == InventoryLocation::NODEMETA) if (from_inv.type == InventoryLocation::NODEMETA) {
{
PLAYER_TO_SA(player)->nodemeta_inventory_OnTake( PLAYER_TO_SA(player)->nodemeta_inventory_OnTake(
from_inv.p, from_list, from_i, src_item, player); from_inv.p, from_list, from_i, src_item, player);
} }
@ -700,12 +659,11 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
/* /*
Record rollback information Record rollback information
*/ */
if(!ignore_src_rollback && gamedef->rollback()) if (!ignore_src_rollback && gamedef->rollback()) {
{
IRollbackManager *rollback = gamedef->rollback(); IRollbackManager *rollback = gamedef->rollback();
// If source is not infinite, record item take // If source is not infinite, record item take
if(src_can_take_count != -1){ if (src_can_take_count != -1) {
RollbackAction action; RollbackAction action;
std::string loc; std::string loc;
{ {
@ -726,20 +684,20 @@ void IDropAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
// to make lag less apparent. // to make lag less apparent.
Inventory *inv_from = mgr->getInventory(from_inv); Inventory *inv_from = mgr->getInventory(from_inv);
if(!inv_from) if (!inv_from)
return; return;
InventoryLocation current_player; InventoryLocation current_player;
current_player.setCurrentPlayer(); current_player.setCurrentPlayer();
Inventory *inv_player = mgr->getInventory(current_player); Inventory *inv_player = mgr->getInventory(current_player);
if(inv_from != inv_player) if (inv_from != inv_player)
return; return;
InventoryList *list_from = inv_from->getList(from_list); InventoryList *list_from = inv_from->getList(from_list);
if(!list_from) if (!list_from)
return; return;
if(count == 0) if (count == 0)
list_from->changeItem(from_i, ItemStack()); list_from->changeItem(from_i, ItemStack());
else else
list_from->takeItem(from_i, count); list_from->takeItem(from_i, count);
@ -881,7 +839,7 @@ void ICraftAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
// Crafting helper // Crafting helper
bool getCraftingResult(Inventory *inv, ItemStack& result, bool getCraftingResult(Inventory *inv, ItemStack &result,
std::vector<ItemStack> &output_replacements, std::vector<ItemStack> &output_replacements,
bool decrementInput, IGameDef *gamedef) bool decrementInput, IGameDef *gamedef)
{ {
@ -891,28 +849,26 @@ bool getCraftingResult(Inventory *inv, ItemStack& result,
// Get the InventoryList in which we will operate // Get the InventoryList in which we will operate
InventoryList *clist = inv->getList("craft"); InventoryList *clist = inv->getList("craft");
if(!clist) if (!clist)
return false; return false;
// Mangle crafting grid to an another format // Mangle crafting grid to an another format
CraftInput ci; CraftInput ci;
ci.method = CRAFT_METHOD_NORMAL; ci.method = CRAFT_METHOD_NORMAL;
ci.width = clist->getWidth() ? clist->getWidth() : 3; ci.width = clist->getWidth() ? clist->getWidth() : 3;
for(u16 i=0; i<clist->getSize(); i++) for (u16 i=0; i < clist->getSize(); i++)
ci.items.push_back(clist->getItem(i)); ci.items.push_back(clist->getItem(i));
// Find out what is crafted and add it to result item slot // Find out what is crafted and add it to result item slot
CraftOutput co; CraftOutput co;
bool found = gamedef->getCraftDefManager()->getCraftResult( bool found = gamedef->getCraftDefManager()->getCraftResult(
ci, co, output_replacements, decrementInput, gamedef); ci, co, output_replacements, decrementInput, gamedef);
if(found) if (found)
result.deSerialize(co.item, gamedef->getItemDefManager()); result.deSerialize(co.item, gamedef->getItemDefManager());
if(found && decrementInput) if (found && decrementInput) {
{
// CraftInput has been changed, apply changes in clist // CraftInput has been changed, apply changes in clist
for(u16 i=0; i<clist->getSize(); i++) for (u16 i=0; i < clist->getSize(); i++) {
{
clist->changeItem(i, ci.items[i]); clist->changeItem(i, ci.items[i]);
} }
} }

View File

@ -117,15 +117,17 @@ public:
virtual void inventoryAction(InventoryAction *a){} virtual void inventoryAction(InventoryAction *a){}
}; };
#define IACTION_MOVE 0 enum class IAction : u16 {
#define IACTION_DROP 1 Move,
#define IACTION_CRAFT 2 Drop,
Craft
};
struct InventoryAction struct InventoryAction
{ {
static InventoryAction * deSerialize(std::istream &is); static InventoryAction *deSerialize(std::istream &is);
virtual u16 getType() const = 0; virtual IAction getType() const = 0;
virtual void serialize(std::ostream &os) const = 0; virtual void serialize(std::ostream &os) const = 0;
virtual void apply(InventoryManager *mgr, ServerActiveObject *player, virtual void apply(InventoryManager *mgr, ServerActiveObject *player,
IGameDef *gamedef) = 0; IGameDef *gamedef) = 0;
@ -136,35 +138,27 @@ struct InventoryAction
struct IMoveAction : public InventoryAction struct IMoveAction : public InventoryAction
{ {
// count=0 means "everything" // count=0 means "everything"
u16 count; u16 count = 0;
InventoryLocation from_inv; InventoryLocation from_inv;
std::string from_list; std::string from_list;
s16 from_i; s16 from_i = -1;
InventoryLocation to_inv; InventoryLocation to_inv;
std::string to_list; std::string to_list;
s16 to_i; s16 to_i = -1;
bool move_somewhere; bool move_somewhere = false;
// treat these as private // treat these as private
// related to movement to somewhere // related to movement to somewhere
bool caused_by_move_somewhere; bool caused_by_move_somewhere = false;
u32 move_count; u32 move_count = 0;
IMoveAction() IMoveAction() {}
{
count = 0;
from_i = -1;
to_i = -1;
move_somewhere = false;
caused_by_move_somewhere = false;
move_count = 0;
}
IMoveAction(std::istream &is, bool somewhere); IMoveAction(std::istream &is, bool somewhere);
u16 getType() const IAction getType() const
{ {
return IACTION_MOVE; return IAction::Move;
} }
void serialize(std::ostream &os) const void serialize(std::ostream &os) const
@ -191,22 +185,18 @@ struct IMoveAction : public InventoryAction
struct IDropAction : public InventoryAction struct IDropAction : public InventoryAction
{ {
// count=0 means "everything" // count=0 means "everything"
u16 count; u16 count = 0;
InventoryLocation from_inv; InventoryLocation from_inv;
std::string from_list; std::string from_list;
s16 from_i; s16 from_i = -1;
IDropAction() IDropAction() {}
{
count = 0;
from_i = -1;
}
IDropAction(std::istream &is); IDropAction(std::istream &is);
u16 getType() const IAction getType() const
{ {
return IACTION_DROP; return IAction::Drop;
} }
void serialize(std::ostream &os) const void serialize(std::ostream &os) const
@ -226,19 +216,16 @@ struct IDropAction : public InventoryAction
struct ICraftAction : public InventoryAction struct ICraftAction : public InventoryAction
{ {
// count=0 means "everything" // count=0 means "everything"
u16 count; u16 count = 0;
InventoryLocation craft_inv; InventoryLocation craft_inv;
ICraftAction() ICraftAction() {}
{
count = 0;
}
ICraftAction(std::istream &is); ICraftAction(std::istream &is);
u16 getType() const IAction getType() const
{ {
return IACTION_CRAFT; return IAction::Craft;
} }
void serialize(std::ostream &os) const void serialize(std::ostream &os) const
@ -254,7 +241,7 @@ struct ICraftAction : public InventoryAction
}; };
// Crafting helper // Crafting helper
bool getCraftingResult(Inventory *inv, ItemStack& result, bool getCraftingResult(Inventory *inv, ItemStack &result,
std::vector<ItemStack> &output_replacements, std::vector<ItemStack> &output_replacements,
bool decrementInput, IGameDef *gamedef); bool decrementInput, IGameDef *gamedef);

View File

@ -35,6 +35,7 @@
#include <irrlicht.h> #include <irrlicht.h>
#include <ft2build.h> #include <ft2build.h>
#include <vector> #include <vector>
#include "irrUString.h"
#include "util/enriched_string.h" #include "util/enriched_string.h"
#include FT_FREETYPE_H #include FT_FREETYPE_H
@ -268,7 +269,7 @@ namespace gui
virtual void draw(const core::stringw& text, const core::rect<s32>& position, virtual void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter=false, bool vcenter=false, video::SColor color, bool hcenter=false, bool vcenter=false,
const core::rect<s32>* clip=0); const core::rect<s32>* clip=0);
virtual void draw(const EnrichedString& text, const core::rect<s32>& position, virtual void draw(const EnrichedString& text, const core::rect<s32>& position,
video::SColor color, bool hcenter=false, bool vcenter=false, video::SColor color, bool hcenter=false, bool vcenter=false,
const core::rect<s32>* clip=0); const core::rect<s32>* clip=0);

View File

@ -1,7 +1,16 @@
if (BUILD_CLIENT) if (BUILD_CLIENT)
set(client_irrlicht_changes_SRCS set(client_irrlicht_changes_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/static_text.cpp ${CMAKE_CURRENT_SOURCE_DIR}/static_text.cpp
PARENT_SCOPE
) )
if (ENABLE_FREETYPE)
set(client_irrlicht_changes_SRCS ${client_irrlicht_changes_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/CGUITTFont.cpp
)
endif()
# CMake require us to set a local scope and then parent scope
# Else the last set win in parent scope
set(client_irrlicht_changes_SRCS ${client_irrlicht_changes_SRCS} PARENT_SCOPE)
endif() endif()

View File

@ -41,6 +41,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <cstddef>
#ifdef _WIN32 #ifdef _WIN32
#define __BYTE_ORDER 0 #define __BYTE_ORDER 0
#define __LITTLE_ENDIAN 0 #define __LITTLE_ENDIAN 0

View File

@ -7,18 +7,13 @@
#include "static_text.h" #include "static_text.h"
#ifdef _IRR_COMPILE_WITH_GUI_ #ifdef _IRR_COMPILE_WITH_GUI_
#include <vector>
#include <string>
#include <iostream>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include <IGUIFont.h> #include <IGUIFont.h>
#include <IVideoDriver.h> #include <IVideoDriver.h>
#include <rect.h> #include <rect.h>
#include <SColor.h> #include <SColor.h>
#if USE_FREETYPE #if USE_FREETYPE
#include "cguittfont/xCGUITTFont.h" #include "CGUITTFont.h"
#endif #endif
#ifndef _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX #ifndef _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
// newer Irrlicht versions no longer have this // newer Irrlicht versions no longer have this

View File

@ -28,16 +28,18 @@ void ItemStackMetadata::deSerialize(std::istream &is)
m_stringvars.clear(); m_stringvars.clear();
if (!in.empty() && in[0] == DESERIALIZE_START) { if (!in.empty()) {
Strfnd fnd(in); if (in[0] == DESERIALIZE_START) {
fnd.to(1); Strfnd fnd(in);
while (!fnd.at_end()) { fnd.to(1);
std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR); while (!fnd.at_end()) {
std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR); std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR);
m_stringvars[name] = var; std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR);
m_stringvars[name] = var;
}
} else {
// BACKWARDS COMPATIBILITY
m_stringvars[""] = in;
} }
} else {
// BACKWARDS COMPATIBILITY
m_stringvars[""] = in;
} }
} }

View File

@ -723,6 +723,9 @@ v3s16 LocalPlayer::getStandingNodePos()
v3s16 LocalPlayer::getFootstepNodePos() v3s16 LocalPlayer::getFootstepNodePos()
{ {
if (in_liquid_stable)
// Emit swimming sound if the player is in liquid
return floatToInt(getPosition(), BS);
if (touching_ground) if (touching_ground)
// BS * 0.05 below the player's feet ensures a 1/16th height // BS * 0.05 below the player's feet ensures a 1/16th height
// nodebox is detected instead of the node below it. // nodebox is detected instead of the node below it.

View File

@ -124,17 +124,12 @@ extern bool isMenuActive();
class MainGameCallback : public IGameCallback class MainGameCallback : public IGameCallback
{ {
public: public:
MainGameCallback(IrrlichtDevice *a_device): MainGameCallback() {}
device(a_device) virtual ~MainGameCallback() {}
{
}
virtual void exitToOS() virtual void exitToOS()
{ {
shutdown_requested = true; shutdown_requested = true;
#ifndef __ANDROID__
device->closeDevice();
#endif
} }
virtual void disconnect() virtual void disconnect()
@ -170,8 +165,6 @@ public:
bool shutdown_requested = false; bool shutdown_requested = false;
bool keyconfig_changed = false; bool keyconfig_changed = false;
IrrlichtDevice *device;
}; };
extern MainGameCallback *g_gamecallback; extern MainGameCallback *g_gamecallback;

View File

@ -971,8 +971,8 @@ std::string analyze_block(MapBlock *block)
std::ostringstream desc; std::ostringstream desc;
v3s16 p = block->getPos(); v3s16 p = block->getPos();
char spos[20]; char spos[25];
snprintf(spos, 20, "(%2d,%2d,%2d), ", p.X, p.Y, p.Z); snprintf(spos, sizeof(spos), "(%2d,%2d,%2d), ", p.X, p.Y, p.Z);
desc<<spos; desc<<spos;
switch(block->getModified()) switch(block->getModified())

View File

@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "shader.h" #include "shader.h"
#include "settings.h" #include "settings.h"
#include "util/directiontables.h" #include "util/directiontables.h"
#include <IMeshManipulator.h> #include "client/renderingengine.h"
/* /*
MeshMakeData MeshMakeData
@ -1008,15 +1008,11 @@ static void updateAllFastFaceRows(MeshMakeData *data,
MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_minimap_mapblock(NULL), m_minimap_mapblock(NULL),
m_client(data->m_client), m_tsrc(data->m_client->getTextureSource()),
m_driver(m_client->tsrc()->getDevice()->getVideoDriver()), m_shdrsrc(data->m_client->getShaderSource()),
m_tsrc(m_client->getTextureSource()),
m_shdrsrc(m_client->getShaderSource()),
m_animation_force_timer(0), // force initial animation m_animation_force_timer(0), // force initial animation
m_last_crack(-1), m_last_crack(-1),
m_crack_materials(), m_last_daynight_ratio((u32) -1)
m_last_daynight_ratio((u32) -1),
m_daynight_diffs()
{ {
for (int m = 0; m < MAX_TILE_LAYERS; m++) for (int m = 0; m < MAX_TILE_LAYERS; m++)
m_mesh[m] = new scene::SMesh(); m_mesh[m] = new scene::SMesh();
@ -1219,7 +1215,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
if (m_use_tangent_vertices) { if (m_use_tangent_vertices) {
scene::IMeshManipulator* meshmanip = scene::IMeshManipulator* meshmanip =
m_client->getSceneManager()->getMeshManipulator(); RenderingEngine::get_scene_manager()->getMeshManipulator();
meshmanip->recalculateTangents(m_mesh[layer], true, false, false); meshmanip->recalculateTangents(m_mesh[layer], true, false, false);
} }
@ -1254,7 +1250,7 @@ MapBlockMesh::~MapBlockMesh()
if (m_enable_vbo && m_mesh[m]) if (m_enable_vbo && m_mesh[m])
for (u32 i = 0; i < m_mesh[m]->getMeshBufferCount(); i++) { for (u32 i = 0; i < m_mesh[m]->getMeshBufferCount(); i++) {
scene::IMeshBuffer *buf = m_mesh[m]->getMeshBuffer(i); scene::IMeshBuffer *buf = m_mesh[m]->getMeshBuffer(i);
m_driver->removeHardwareBuffer(buf); RenderingEngine::get_video_driver()->removeHardwareBuffer(buf);
} }
m_mesh[m]->drop(); m_mesh[m]->drop();
m_mesh[m] = NULL; m_mesh[m] = NULL;

View File

@ -42,7 +42,6 @@ struct MeshMakeData
v3s16 m_blockpos = v3s16(-1337,-1337,-1337); v3s16 m_blockpos = v3s16(-1337,-1337,-1337);
v3s16 m_crack_pos_relative = v3s16(-1337,-1337,-1337); v3s16 m_crack_pos_relative = v3s16(-1337,-1337,-1337);
bool m_smooth_lighting = false; bool m_smooth_lighting = false;
bool m_show_hud = false;
Client *m_client; Client *m_client;
bool m_use_shaders; bool m_use_shaders;
@ -138,8 +137,6 @@ public:
private: private:
scene::IMesh *m_mesh[MAX_TILE_LAYERS]; scene::IMesh *m_mesh[MAX_TILE_LAYERS];
MinimapMapblock *m_minimap_mapblock; MinimapMapblock *m_minimap_mapblock;
Client *m_client;
video::IVideoDriver *m_driver;
ITextureSource *m_tsrc; ITextureSource *m_tsrc;
IShaderSource *m_shdrsrc; IShaderSource *m_shdrsrc;

View File

@ -817,7 +817,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
u32 bruises_count = ps.range(0, 2); u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) { for (u32 i = 0; i < bruises_count; i++) {
CavesRandomWalk cave(ndef, &gennotify, seed, water_level, CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
c_water_source, CONTENT_IGNORE); c_water_source, CONTENT_IGNORE, lava_depth);
cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap); cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap);
} }

View File

@ -294,6 +294,7 @@ protected:
float cavern_limit; float cavern_limit;
float cavern_taper; float cavern_taper;
float cavern_threshold; float cavern_threshold;
int lava_depth;
}; };
#endif #endif

View File

@ -51,14 +51,15 @@ FlagDesc flagdesc_mapgen_flat[] = {
MapgenFlat::MapgenFlat(int mapgenid, MapgenFlatParams *params, EmergeManager *emerge) MapgenFlat::MapgenFlat(int mapgenid, MapgenFlatParams *params, EmergeManager *emerge)
: MapgenBasic(mapgenid, params, emerge) : MapgenBasic(mapgenid, params, emerge)
{ {
this->spflags = params->spflags; spflags = params->spflags;
this->ground_level = params->ground_level; ground_level = params->ground_level;
this->large_cave_depth = params->large_cave_depth; large_cave_depth = params->large_cave_depth;
this->cave_width = params->cave_width; lava_depth = params->lava_depth;
this->lake_threshold = params->lake_threshold; cave_width = params->cave_width;
this->lake_steepness = params->lake_steepness; lake_threshold = params->lake_threshold;
this->hill_threshold = params->hill_threshold; lake_steepness = params->lake_steepness;
this->hill_steepness = params->hill_steepness; hill_threshold = params->hill_threshold;
hill_steepness = params->hill_steepness;
// 2D noise // 2D noise
noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z); noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
@ -94,6 +95,7 @@ void MapgenFlatParams::readParams(const Settings *settings)
settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat); settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat);
settings->getS16NoEx("mgflat_ground_level", ground_level); settings->getS16NoEx("mgflat_ground_level", ground_level);
settings->getS16NoEx("mgflat_large_cave_depth", large_cave_depth); settings->getS16NoEx("mgflat_large_cave_depth", large_cave_depth);
settings->getS16NoEx("mgflat_lava_depth", lava_depth);
settings->getFloatNoEx("mgflat_cave_width", cave_width); settings->getFloatNoEx("mgflat_cave_width", cave_width);
settings->getFloatNoEx("mgflat_lake_threshold", lake_threshold); settings->getFloatNoEx("mgflat_lake_threshold", lake_threshold);
settings->getFloatNoEx("mgflat_lake_steepness", lake_steepness); settings->getFloatNoEx("mgflat_lake_steepness", lake_steepness);
@ -112,6 +114,7 @@ void MapgenFlatParams::writeParams(Settings *settings) const
settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat, U32_MAX); settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat, U32_MAX);
settings->setS16("mgflat_ground_level", ground_level); settings->setS16("mgflat_ground_level", ground_level);
settings->setS16("mgflat_large_cave_depth", large_cave_depth); settings->setS16("mgflat_large_cave_depth", large_cave_depth);
settings->setS16("mgflat_lava_depth", lava_depth);
settings->setFloat("mgflat_cave_width", cave_width); settings->setFloat("mgflat_cave_width", cave_width);
settings->setFloat("mgflat_lake_threshold", lake_threshold); settings->setFloat("mgflat_lake_threshold", lake_threshold);
settings->setFloat("mgflat_lake_steepness", lake_steepness); settings->setFloat("mgflat_lake_steepness", lake_steepness);

View File

@ -36,6 +36,7 @@ struct MapgenFlatParams : public MapgenParams
u32 spflags = 0; u32 spflags = 0;
s16 ground_level = 8; s16 ground_level = 8;
s16 large_cave_depth = -33; s16 large_cave_depth = -33;
s16 lava_depth = -256;
float cave_width = 0.09f; float cave_width = 0.09f;
float lake_threshold = -0.45f; float lake_threshold = -0.45f;
float lake_steepness = 48.0f; float lake_steepness = 48.0f;

View File

@ -49,17 +49,19 @@ FlagDesc flagdesc_mapgen_fractal[] = {
MapgenFractal::MapgenFractal(int mapgenid, MapgenFractalParams *params, EmergeManager *emerge) MapgenFractal::MapgenFractal(int mapgenid, MapgenFractalParams *params, EmergeManager *emerge)
: MapgenBasic(mapgenid, params, emerge) : MapgenBasic(mapgenid, params, emerge)
{ {
this->spflags = params->spflags; spflags = params->spflags;
this->cave_width = params->cave_width; cave_width = params->cave_width;
this->fractal = params->fractal; large_cave_depth = params->large_cave_depth;
this->iterations = params->iterations; lava_depth = params->lava_depth;
this->scale = params->scale; fractal = params->fractal;
this->offset = params->offset; iterations = params->iterations;
this->slice_w = params->slice_w; scale = params->scale;
this->julia_x = params->julia_x; offset = params->offset;
this->julia_y = params->julia_y; slice_w = params->slice_w;
this->julia_z = params->julia_z; julia_x = params->julia_x;
this->julia_w = params->julia_w; julia_y = params->julia_y;
julia_z = params->julia_z;
julia_w = params->julia_w;
//// 2D terrain noise //// 2D terrain noise
noise_seabed = new Noise(&params->np_seabed, seed, csize.X, csize.Z); noise_seabed = new Noise(&params->np_seabed, seed, csize.X, csize.Z);
@ -68,8 +70,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenFractalParams *params, EmergeMa
MapgenBasic::np_cave1 = params->np_cave1; MapgenBasic::np_cave1 = params->np_cave1;
MapgenBasic::np_cave2 = params->np_cave2; MapgenBasic::np_cave2 = params->np_cave2;
this->formula = fractal / 2 + fractal % 2; formula = fractal / 2 + fractal % 2;
this->julia = fractal % 2 == 0; julia = fractal % 2 == 0;
} }
@ -91,17 +93,19 @@ MapgenFractalParams::MapgenFractalParams()
void MapgenFractalParams::readParams(const Settings *settings) void MapgenFractalParams::readParams(const Settings *settings)
{ {
settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal);
settings->getFloatNoEx("mgfractal_cave_width", cave_width); settings->getFloatNoEx("mgfractal_cave_width", cave_width);
settings->getU16NoEx("mgfractal_fractal", fractal); settings->getS16NoEx("mgfractal_large_cave_depth", large_cave_depth);
settings->getU16NoEx("mgfractal_iterations", iterations); settings->getS16NoEx("mgfractal_lava_depth", lava_depth);
settings->getV3FNoEx("mgfractal_scale", scale); settings->getU16NoEx("mgfractal_fractal", fractal);
settings->getV3FNoEx("mgfractal_offset", offset); settings->getU16NoEx("mgfractal_iterations", iterations);
settings->getFloatNoEx("mgfractal_slice_w", slice_w); settings->getV3FNoEx("mgfractal_scale", scale);
settings->getFloatNoEx("mgfractal_julia_x", julia_x); settings->getV3FNoEx("mgfractal_offset", offset);
settings->getFloatNoEx("mgfractal_julia_y", julia_y); settings->getFloatNoEx("mgfractal_slice_w", slice_w);
settings->getFloatNoEx("mgfractal_julia_z", julia_z); settings->getFloatNoEx("mgfractal_julia_x", julia_x);
settings->getFloatNoEx("mgfractal_julia_w", julia_w); settings->getFloatNoEx("mgfractal_julia_y", julia_y);
settings->getFloatNoEx("mgfractal_julia_z", julia_z);
settings->getFloatNoEx("mgfractal_julia_w", julia_w);
settings->getNoiseParams("mgfractal_np_seabed", np_seabed); settings->getNoiseParams("mgfractal_np_seabed", np_seabed);
settings->getNoiseParams("mgfractal_np_filler_depth", np_filler_depth); settings->getNoiseParams("mgfractal_np_filler_depth", np_filler_depth);
@ -112,17 +116,19 @@ void MapgenFractalParams::readParams(const Settings *settings)
void MapgenFractalParams::writeParams(Settings *settings) const void MapgenFractalParams::writeParams(Settings *settings) const
{ {
settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX); settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX);
settings->setFloat("mgfractal_cave_width", cave_width); settings->setFloat("mgfractal_cave_width", cave_width);
settings->setU16("mgfractal_fractal", fractal); settings->setS16("mgfractal_large_cave_depth", large_cave_depth);
settings->setU16("mgfractal_iterations", iterations); settings->setS16("mgfractal_lava_depth", lava_depth);
settings->setV3F("mgfractal_scale", scale); settings->setU16("mgfractal_fractal", fractal);
settings->setV3F("mgfractal_offset", offset); settings->setU16("mgfractal_iterations", iterations);
settings->setFloat("mgfractal_slice_w", slice_w); settings->setV3F("mgfractal_scale", scale);
settings->setFloat("mgfractal_julia_x", julia_x); settings->setV3F("mgfractal_offset", offset);
settings->setFloat("mgfractal_julia_y", julia_y); settings->setFloat("mgfractal_slice_w", slice_w);
settings->setFloat("mgfractal_julia_z", julia_z); settings->setFloat("mgfractal_julia_x", julia_x);
settings->setFloat("mgfractal_julia_w", julia_w); settings->setFloat("mgfractal_julia_y", julia_y);
settings->setFloat("mgfractal_julia_z", julia_z);
settings->setFloat("mgfractal_julia_w", julia_w);
settings->setNoiseParams("mgfractal_np_seabed", np_seabed); settings->setNoiseParams("mgfractal_np_seabed", np_seabed);
settings->setNoiseParams("mgfractal_np_filler_depth", np_filler_depth); settings->setNoiseParams("mgfractal_np_filler_depth", np_filler_depth);
@ -196,7 +202,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
MgStoneType stone_type = generateBiomes(); MgStoneType stone_type = generateBiomes();
if (flags & MG_CAVES) if (flags & MG_CAVES)
generateCaves(stone_surface_max_y, MGFRACTAL_LARGE_CAVE_DEPTH); generateCaves(stone_surface_max_y, large_cave_depth);
if (flags & MG_DUNGEONS) if (flags & MG_DUNGEONS)
generateDungeons(stone_surface_max_y, stone_type); generateDungeons(stone_surface_max_y, stone_type);

View File

@ -26,8 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen.h" #include "mapgen.h"
#define MGFRACTAL_LARGE_CAVE_DEPTH -33
class BiomeManager; class BiomeManager;
extern FlagDesc flagdesc_mapgen_fractal[]; extern FlagDesc flagdesc_mapgen_fractal[];
@ -36,6 +34,8 @@ struct MapgenFractalParams : public MapgenParams
{ {
u32 spflags = 0; u32 spflags = 0;
float cave_width = 0.09f; float cave_width = 0.09f;
s16 large_cave_depth = -33;
s16 lava_depth = -256;
u16 fractal = 1; u16 fractal = 1;
u16 iterations = 11; u16 iterations = 11;
v3f scale = v3f(4096.0, 1024.0, 4096.0); v3f scale = v3f(4096.0, 1024.0, 4096.0);
@ -74,6 +74,7 @@ private:
u16 formula; u16 formula;
bool julia; bool julia;
s16 large_cave_depth;
u16 fractal; u16 fractal;
u16 iterations; u16 iterations;
v3f scale; v3f scale;

View File

@ -48,11 +48,13 @@ FlagDesc flagdesc_mapgen_v5[] = {
MapgenV5::MapgenV5(int mapgenid, MapgenV5Params *params, EmergeManager *emerge) MapgenV5::MapgenV5(int mapgenid, MapgenV5Params *params, EmergeManager *emerge)
: MapgenBasic(mapgenid, params, emerge) : MapgenBasic(mapgenid, params, emerge)
{ {
this->spflags = params->spflags; spflags = params->spflags;
this->cave_width = params->cave_width; cave_width = params->cave_width;
this->cavern_limit = params->cavern_limit; large_cave_depth = params->large_cave_depth;
this->cavern_taper = params->cavern_taper; lava_depth = params->lava_depth;
this->cavern_threshold = params->cavern_threshold; cavern_limit = params->cavern_limit;
cavern_taper = params->cavern_taper;
cavern_threshold = params->cavern_threshold;
// Terrain noise // Terrain noise
noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z); noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
@ -94,6 +96,8 @@ void MapgenV5Params::readParams(const Settings *settings)
{ {
settings->getFlagStrNoEx("mgv5_spflags", spflags, flagdesc_mapgen_v5); settings->getFlagStrNoEx("mgv5_spflags", spflags, flagdesc_mapgen_v5);
settings->getFloatNoEx("mgv5_cave_width", cave_width); settings->getFloatNoEx("mgv5_cave_width", cave_width);
settings->getS16NoEx("mgv5_large_cave_depth", large_cave_depth);
settings->getS16NoEx("mgv5_lava_depth", lava_depth);
settings->getS16NoEx("mgv5_cavern_limit", cavern_limit); settings->getS16NoEx("mgv5_cavern_limit", cavern_limit);
settings->getS16NoEx("mgv5_cavern_taper", cavern_taper); settings->getS16NoEx("mgv5_cavern_taper", cavern_taper);
settings->getFloatNoEx("mgv5_cavern_threshold", cavern_threshold); settings->getFloatNoEx("mgv5_cavern_threshold", cavern_threshold);
@ -112,6 +116,8 @@ void MapgenV5Params::writeParams(Settings *settings) const
{ {
settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5, U32_MAX); settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5, U32_MAX);
settings->setFloat("mgv5_cave_width", cave_width); settings->setFloat("mgv5_cave_width", cave_width);
settings->setS16("mgv5_large_cave_depth", large_cave_depth);
settings->setS16("mgv5_lava_depth", lava_depth);
settings->setS16("mgv5_cavern_limit", cavern_limit); settings->setS16("mgv5_cavern_limit", cavern_limit);
settings->setS16("mgv5_cavern_taper", cavern_taper); settings->setS16("mgv5_cavern_taper", cavern_taper);
settings->setFloat("mgv5_cavern_threshold", cavern_threshold); settings->setFloat("mgv5_cavern_threshold", cavern_threshold);
@ -209,7 +215,7 @@ void MapgenV5::makeChunk(BlockMakeData *data)
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, MGV5_LARGE_CAVE_DEPTH); generateCaves(stone_surface_max_y, large_cave_depth);
} }
// Generate dungeons and desert temples // Generate dungeons and desert temples

View File

@ -23,8 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen.h" #include "mapgen.h"
#define MGV5_LARGE_CAVE_DEPTH -256
///////// Mapgen V5 flags ///////// Mapgen V5 flags
#define MGV5_CAVERNS 0x01 #define MGV5_CAVERNS 0x01
@ -36,6 +34,8 @@ struct MapgenV5Params : public MapgenParams
{ {
u32 spflags = MGV5_CAVERNS; u32 spflags = MGV5_CAVERNS;
float cave_width = 0.125f; float cave_width = 0.125f;
s16 large_cave_depth = -256;
s16 lava_depth = -256;
s16 cavern_limit = -256; s16 cavern_limit = -256;
s16 cavern_taper = 256; s16 cavern_taper = 256;
float cavern_threshold = 0.7f; float cavern_threshold = 0.7f;
@ -68,6 +68,7 @@ public:
int generateBaseTerrain(); int generateBaseTerrain();
private: private:
s16 large_cave_depth;
Noise *noise_factor; Noise *noise_factor;
Noise *noise_height; Noise *noise_height;
Noise *noise_ground; Noise *noise_ground;

View File

@ -58,14 +58,14 @@ FlagDesc flagdesc_mapgen_v6[] = {
MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge) MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge)
: Mapgen(mapgenid, params, emerge) : Mapgen(mapgenid, params, emerge)
{ {
this->m_emerge = emerge; m_emerge = emerge;
this->ystride = csize.X; //////fix this ystride = csize.X; //////fix this
this->heightmap = new s16[csize.X * csize.Z]; heightmap = new s16[csize.X * csize.Z];
this->spflags = params->spflags; spflags = params->spflags;
this->freq_desert = params->freq_desert; freq_desert = params->freq_desert;
this->freq_beach = params->freq_beach; freq_beach = params->freq_beach;
np_cave = &params->np_cave; np_cave = &params->np_cave;
np_humidity = &params->np_humidity; np_humidity = &params->np_humidity;

View File

@ -54,15 +54,21 @@ FlagDesc flagdesc_mapgen_v7[] = {
MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge) MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
: MapgenBasic(mapgenid, params, emerge) : MapgenBasic(mapgenid, params, emerge)
{ {
this->spflags = params->spflags; spflags = params->spflags;
this->cave_width = params->cave_width; cave_width = params->cave_width;
this->float_mount_density = params->float_mount_density; large_cave_depth = params->large_cave_depth;
this->float_mount_height = params->float_mount_height; lava_depth = params->lava_depth;
this->floatland_level = params->floatland_level; float_mount_density = params->float_mount_density;
this->shadow_limit = params->shadow_limit; floatland_level = params->floatland_level;
this->cavern_limit = params->cavern_limit; shadow_limit = params->shadow_limit;
this->cavern_taper = params->cavern_taper; cavern_limit = params->cavern_limit;
this->cavern_threshold = params->cavern_threshold; cavern_taper = params->cavern_taper;
cavern_threshold = params->cavern_threshold;
// This is to avoid a divide-by-zero.
// Parameter will be saved to map_meta.txt in limited form.
params->float_mount_height = MYMAX(params->float_mount_height, 1.0f);
float_mount_height = params->float_mount_height;
// 2D noise // 2D noise
noise_terrain_base = new Noise(&params->np_terrain_base, seed, csize.X, csize.Z); noise_terrain_base = new Noise(&params->np_terrain_base, seed, csize.X, csize.Z);
@ -143,6 +149,8 @@ void MapgenV7Params::readParams(const Settings *settings)
{ {
settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7);
settings->getFloatNoEx("mgv7_cave_width", cave_width); settings->getFloatNoEx("mgv7_cave_width", cave_width);
settings->getS16NoEx("mgv7_large_cave_depth", large_cave_depth);
settings->getS16NoEx("mgv7_lava_depth", lava_depth);
settings->getFloatNoEx("mgv7_float_mount_density", float_mount_density); settings->getFloatNoEx("mgv7_float_mount_density", float_mount_density);
settings->getFloatNoEx("mgv7_float_mount_height", float_mount_height); settings->getFloatNoEx("mgv7_float_mount_height", float_mount_height);
settings->getS16NoEx("mgv7_floatland_level", floatland_level); settings->getS16NoEx("mgv7_floatland_level", floatland_level);
@ -172,6 +180,8 @@ void MapgenV7Params::writeParams(Settings *settings) const
{ {
settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX); settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX);
settings->setFloat("mgv7_cave_width", cave_width); settings->setFloat("mgv7_cave_width", cave_width);
settings->setS16("mgv7_large_cave_depth", large_cave_depth);
settings->setS16("mgv7_lava_depth", lava_depth);
settings->setFloat("mgv7_float_mount_density", float_mount_density); settings->setFloat("mgv7_float_mount_density", float_mount_density);
settings->setFloat("mgv7_float_mount_height", float_mount_height); settings->setFloat("mgv7_float_mount_height", float_mount_height);
settings->setS16("mgv7_floatland_level", floatland_level); settings->setS16("mgv7_floatland_level", floatland_level);
@ -202,10 +212,7 @@ void MapgenV7Params::writeParams(Settings *settings) const
int MapgenV7::getSpawnLevelAtPoint(v2s16 p) int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
{ {
// Base terrain calculation // If rivers are enabled, first check if in a river
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
// If enabled, check if inside a river
if (spflags & MGV7_RIDGES) { if (spflags & MGV7_RIDGES) {
float width = 0.2; float width = 0.2;
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2; float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
@ -213,28 +220,41 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
} }
// If mountains are disabled, terrain level is base terrain level // Terrain noise 'offset' is the average level of that terrain.
// Avoids spawn on non-existant mountain terrain // At least 50% of terrain will be below the higher of base and alt terrain
// 'offset's.
// Raising the maximum spawn level above 'water_level + 16' is necessary
// for when terrain 'offset's are set much higher than water_level.
s16 max_spawn_y = MYMAX(MYMAX(noise_terrain_alt->np.offset,
noise_terrain_base->np.offset),
water_level + 16);
// Base terrain calculation
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
// If mountains are disabled, terrain level is base terrain level.
// Avoids mid-air spawn where mountain terrain would have been.
if (!(spflags & MGV7_MOUNTAINS)) { if (!(spflags & MGV7_MOUNTAINS)) {
if (y <= water_level || y > water_level + 16) if (y <= water_level || y > max_spawn_y)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
else else
return y; // + 1 to not be half-buried in a potential node-deep biome 'dust'
return y + 1;
} }
// Mountain terrain calculation // Search upwards for first node without mountain terrain
int iters = 128; int iters = 256;
while (iters--) { while (iters > 0 && y <= max_spawn_y) {
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // If air above if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // If air above
if (y <= water_level || y > water_level + 16) if (y <= water_level || y > max_spawn_y)
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
else else
return y; return y + 1;
} }
y++; y++;
iters--;
} }
// Unsuitable spawn point, no mountain surface found // Unsuitable spawn point
return MAX_MAP_GENERATION_LIMIT; return MAX_MAP_GENERATION_LIMIT;
} }
@ -293,7 +313,7 @@ void MapgenV7::makeChunk(BlockMakeData *data)
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, water_level); generateCaves(stone_surface_max_y, large_cave_depth);
} }
// Generate dungeons // Generate dungeons
@ -366,7 +386,8 @@ float MapgenV7::baseTerrainLevelFromMap(int index)
bool MapgenV7::getMountainTerrainAtPoint(s16 x, s16 y, s16 z) bool MapgenV7::getMountainTerrainAtPoint(s16 x, s16 y, s16 z)
{ {
float mnt_h_n = NoisePerlin2D(&noise_mount_height->np, x, z, seed); float mnt_h_n =
MYMAX(NoisePerlin2D(&noise_mount_height->np, x, z, seed), 1.0f);
float density_gradient = -((float)y / mnt_h_n); float density_gradient = -((float)y / mnt_h_n);
float mnt_n = NoisePerlin3D(&noise_mountain->np, x, y, z, seed); float mnt_n = NoisePerlin3D(&noise_mountain->np, x, y, z, seed);
@ -376,7 +397,7 @@ bool MapgenV7::getMountainTerrainAtPoint(s16 x, s16 y, s16 z)
bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y) bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y)
{ {
float mounthn = noise_mount_height->result[idx_xz]; float mounthn = MYMAX(noise_mount_height->result[idx_xz], 1.0f);
float density_gradient = -((float)y / mounthn); float density_gradient = -((float)y / mounthn);
float mountn = noise_mountain->result[idx_xyz]; float mountn = noise_mountain->result[idx_xyz];
@ -405,7 +426,8 @@ void MapgenV7::floatBaseExtentFromMap(s16 *float_base_min, s16 *float_base_max,
float n_base = noise_floatland_base->result[idx_xz]; float n_base = noise_floatland_base->result[idx_xz];
if (n_base > 0.0f) { if (n_base > 0.0f) {
float n_base_height = noise_float_base_height->result[idx_xz]; float n_base_height =
MYMAX(noise_float_base_height->result[idx_xz], 1.0f);
float amp = n_base * n_base_height; float amp = n_base * n_base_height;
float ridge = n_base_height / 3.0f; float ridge = n_base_height / 3.0f;
base_min = floatland_level - amp / 1.5f; base_min = floatland_level - amp / 1.5f;
@ -509,7 +531,8 @@ int MapgenV7::generateTerrain()
void MapgenV7::generateRidgeTerrain() void MapgenV7::generateRidgeTerrain()
{ {
if ((node_max.Y < water_level - 16) || (node_max.Y > shadow_limit)) if (node_max.Y < water_level - 16 ||
((spflags & MGV7_FLOATLANDS) && node_max.Y > shadow_limit))
return; return;
noise_ridge->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); noise_ridge->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);

View File

@ -37,6 +37,8 @@ extern FlagDesc flagdesc_mapgen_v7[];
struct MapgenV7Params : public MapgenParams { struct MapgenV7Params : public MapgenParams {
u32 spflags = MGV7_MOUNTAINS | MGV7_RIDGES | MGV7_CAVERNS; u32 spflags = MGV7_MOUNTAINS | MGV7_RIDGES | MGV7_CAVERNS;
float cave_width = 0.09f; float cave_width = 0.09f;
s16 large_cave_depth = -33;
s16 lava_depth = -256;
float float_mount_density = 0.6f; float float_mount_density = 0.6f;
float float_mount_height = 128.0f; float float_mount_height = 128.0f;
s16 floatland_level = 1280; s16 floatland_level = 1280;
@ -88,6 +90,7 @@ public:
void generateRidgeTerrain(); void generateRidgeTerrain();
private: private:
s16 large_cave_depth;
float float_mount_density; float float_mount_density;
float float_mount_height; float float_mount_height;
s16 floatland_level; s16 floatland_level;

View File

@ -66,19 +66,19 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeMa
: MapgenBasic(mapgenid, params, emerge) : MapgenBasic(mapgenid, params, emerge)
{ {
// NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal // NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal
this->m_bgen = (BiomeGenOriginal *)biomegen; m_bgen = (BiomeGenOriginal *)biomegen;
BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams; BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams;
this->spflags = params->spflags; spflags = params->spflags;
this->altitude_chill = params->altitude_chill; altitude_chill = params->altitude_chill;
this->large_cave_depth = params->large_cave_depth; large_cave_depth = params->large_cave_depth;
this->lava_features_lim = rangelim(params->lava_features, 0, 10); lava_features_lim = rangelim(params->lava_features, 0, 10);
this->massive_cave_depth = params->massive_cave_depth; massive_cave_depth = params->massive_cave_depth;
this->river_depth_bed = params->river_depth + 1.f; river_depth_bed = params->river_depth + 1.f;
this->river_size_factor = params->river_size / 100.f; river_size_factor = params->river_size / 100.f;
this->water_features_lim = rangelim(params->water_features, 0, 10); water_features_lim = rangelim(params->water_features, 0, 10);
this->cave_width = params->cave_width; cave_width = params->cave_width;
//// 2D Terrain noise //// 2D Terrain noise
noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z); noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
@ -96,13 +96,13 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeMa
noise_cave2 = new Noise(&params->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); noise_cave2 = new Noise(&params->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
noise_massive_caves = new Noise(&params->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z); noise_massive_caves = new Noise(&params->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS);
this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
this->humidity_adjust = bp->np_humidity.offset - 50.f; humidity_adjust = bp->np_humidity.offset - 50.f;
// a small chance of overflows if the settings are very high // a small chance of overflows if the settings are very high
this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50; cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50;
this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50; lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50;
tcave_cache = new float[csize.Y + 2]; tcave_cache = new float[csize.Y + 2];
} }
@ -733,7 +733,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth)
u32 bruises_count = ps.range(0, 2); u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) { for (u32 i = 0; i < bruises_count; i++) {
CavesRandomWalk cave(ndef, &gennotify, seed, water_level, CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
c_water_source, c_lava_source); c_water_source, c_lava_source, lava_max_height);
cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap); cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap);
} }

View File

@ -28,14 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
CachedMapBlockData CachedMapBlockData
*/ */
CachedMapBlockData::CachedMapBlockData():
p(-1337,-1337,-1337),
data(NULL),
refcount_from_queue(0),
last_used_timestamp(time(0))
{
}
CachedMapBlockData::~CachedMapBlockData() CachedMapBlockData::~CachedMapBlockData()
{ {
assert(refcount_from_queue == 0); assert(refcount_from_queue == 0);
@ -47,16 +39,6 @@ CachedMapBlockData::~CachedMapBlockData()
QueuedMeshUpdate QueuedMeshUpdate
*/ */
QueuedMeshUpdate::QueuedMeshUpdate():
p(-1337,-1337,-1337),
ack_block_to_server(false),
urgent(false),
crack_level(-1),
crack_pos(0,0,0),
data(NULL)
{
}
QueuedMeshUpdate::~QueuedMeshUpdate() QueuedMeshUpdate::~QueuedMeshUpdate()
{ {
delete data; delete data;
@ -241,7 +223,7 @@ void MeshUpdateQueue::fillDataFromMapBlockCache(QueuedMeshUpdate *q)
data->fillBlockDataBegin(q->p); data->fillBlockDataBegin(q->p);
int t_now = time(0); std::time_t t_now = std::time(0);
// Collect data for 3*3*3 blocks from cache // Collect data for 3*3*3 blocks from cache
v3s16 dp; v3s16 dp;

View File

@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MESH_GENERATOR_THREAD_HEADER #ifndef MESH_GENERATOR_THREAD_HEADER
#define MESH_GENERATOR_THREAD_HEADER #define MESH_GENERATOR_THREAD_HEADER
#include <ctime>
#include <mutex> #include <mutex>
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#include "threading/mutex_auto_lock.h" #include "threading/mutex_auto_lock.h"
@ -27,25 +28,25 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct CachedMapBlockData struct CachedMapBlockData
{ {
v3s16 p; v3s16 p = v3s16(-1337, -1337, -1337);
MapNode *data; // A copy of the MapBlock's data member MapNode *data = nullptr; // A copy of the MapBlock's data member
int refcount_from_queue; int refcount_from_queue = 0;
int last_used_timestamp; std::time_t last_used_timestamp = std::time(0);
CachedMapBlockData(); CachedMapBlockData() {}
~CachedMapBlockData(); ~CachedMapBlockData();
}; };
struct QueuedMeshUpdate struct QueuedMeshUpdate
{ {
v3s16 p; v3s16 p = v3s16(-1337, -1337, -1337);
bool ack_block_to_server; bool ack_block_to_server = false;
bool urgent; bool urgent = false;
int crack_level; int crack_level = -1;
v3s16 crack_pos; v3s16 crack_pos;
MeshMakeData *data; // This is generated in MeshUpdateQueue::pop() MeshMakeData *data = nullptr; // This is generated in MeshUpdateQueue::pop()
QueuedMeshUpdate(); QueuedMeshUpdate(){};
~QueuedMeshUpdate(); ~QueuedMeshUpdate();
}; };
@ -101,14 +102,11 @@ private:
struct MeshUpdateResult struct MeshUpdateResult
{ {
v3s16 p; v3s16 p = v3s16(-1338, -1338, -1338);
MapBlockMesh *mesh; MapBlockMesh *mesh = nullptr;
bool ack_block_to_server; bool ack_block_to_server = false;
MeshUpdateResult() MeshUpdateResult() {}
: p(-1338, -1338, -1338), mesh(NULL), ack_block_to_server(false)
{
}
}; };
class MeshUpdateThread : public UpdateThread class MeshUpdateThread : public UpdateThread

View File

@ -117,10 +117,10 @@ public:
virtual Biome *getBiomeAtIndex(size_t index, s16 y) const = 0; virtual Biome *getBiomeAtIndex(size_t index, s16 y) const = 0;
// Result of calcBiomes bulk computation. // Result of calcBiomes bulk computation.
biome_t *biomemap; biome_t *biomemap = nullptr;
protected: protected:
BiomeManager *m_bmgr; BiomeManager *m_bmgr = nullptr;
v3s16 m_pmin; v3s16 m_pmin;
v3s16 m_csize; v3s16 m_csize;
}; };

Some files were not shown because too many files have changed in this diff Show More