Merge branch 'MihailRis:main' into main
This commit is contained in:
commit
4c4a6e08b8
215
CHANGELOG.md
215
CHANGELOG.md
@ -1,96 +1,153 @@
|
|||||||
# 0.25 - 2024.12.01
|
# 0.26 - 2025.01.27
|
||||||
|
|
||||||
[Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/tree/release-0.25/doc/en/main-page.md) for 0.25
|
[Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/tree/release-0.26/doc/en/main-page.md) for 0.26
|
||||||
|
|
||||||
Table of contents:
|
Table of contents:
|
||||||
|
|
||||||
- [Added](#added)
|
- [Added](#added)
|
||||||
|
- [Changes](#changes)
|
||||||
- [Functions](#functions)
|
- [Functions](#functions)
|
||||||
- [Fixes](#fixes)
|
- [Fixes](#fixes)
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- 3dtext
|
- headless mode `--headless`
|
||||||
- blockwraps
|
- script execution mode `--headless --script filename`
|
||||||
- network (http requests and sockets)
|
- test execution mode `--headless --test filename`
|
||||||
|
- vctest console application
|
||||||
- libraries:
|
- libraries:
|
||||||
- base64
|
- app
|
||||||
- gfx.text3d
|
- byteutil
|
||||||
- gfx.blockwraps
|
- in-game chat
|
||||||
- network
|
- text markup: Markdown
|
||||||
|
- syntax-highlighting: Lua
|
||||||
|
- http post requests
|
||||||
|
- `Scripts` menu page for app scripts
|
||||||
|
- binding `hud.chat`
|
||||||
|
- user-defined console.submit
|
||||||
- events:
|
- events:
|
||||||
- on_replaced
|
- on_chunk_present
|
||||||
- on_block_replaced
|
- on_chunk_remove
|
||||||
- on_player_tick
|
- on_inventory_open
|
||||||
- structures 'lowering' property
|
- on_inventory_closed
|
||||||
- add 'hint' property to textbox
|
- [canvas](https://github.com/MihailRis/VoxelEngine-Cpp/pull/444) ui node
|
||||||
- add 'taking' and 'placing' properties to slot and slotsgrid
|
- settings:
|
||||||
- add 'scroll-step' property to container
|
- `graphics.dense-render`
|
||||||
- add 'line-numbers' and 'text-color' to textbox
|
- block properties:
|
||||||
- modules:
|
- `culling`
|
||||||
- base:util
|
- particles properties:
|
||||||
- uinode property 'id'
|
- `angle_spread`
|
||||||
- block.materials table
|
- `min_angular_vel`, `max_angular_vel`
|
||||||
- block.properties table
|
- bytearray support in serializers
|
||||||
- item.properties table
|
- ui properties:
|
||||||
- add version to world info table
|
- uinode: `cursor`
|
||||||
- add 'sizeSpread' particles property
|
- textbox: `markup`, `syntax`, `text-color`
|
||||||
- add user properties
|
- label: `markup`
|
||||||
|
- base pack:
|
||||||
|
- add transparent leaves render mode
|
||||||
|
- add falling leaves particles
|
||||||
|
- 'states' parameter in base:falling_block
|
||||||
|
- added/updated sounds
|
||||||
|
- nameless worlds
|
||||||
|
- SIGTERM handler
|
||||||
|
- project:
|
||||||
|
- clang Windows workflow
|
||||||
|
- engine tests
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
- moved `devtools.console` binding handler to Lua
|
||||||
|
- move `key:escape` binding handler to Lua
|
||||||
|
- upgrade dead emitters garbage collection
|
||||||
|
- reserved player entity ids: `0` - none (example: dead), `-1` - auto (spawns new one)
|
||||||
|
- input.add_callback("key:name") support and add optional `owner` argument
|
||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
- player.is_infinite_items
|
- app.tick
|
||||||
- player.set_infinite_items
|
- app.sleep
|
||||||
- player.is_instant_destruction
|
- app.sleep_until
|
||||||
- player.set_instant_destruction
|
- app.new_world
|
||||||
- player.get_name
|
- app.open_world
|
||||||
- player.set_name
|
- app.save_world
|
||||||
- hud.open
|
- app.close_world
|
||||||
- base64.encode
|
- app.reopen_world
|
||||||
- base64.decode
|
- app.delete_world
|
||||||
- utf8.escape
|
- app.config_packs
|
||||||
- string.escape
|
- app.reconfig_packs
|
||||||
- textbox:lineAt
|
- app.get_setting
|
||||||
- textbox:linePos
|
- app.set_setting
|
||||||
- network.get
|
- app.get_version
|
||||||
- network.get_binary
|
- app.get_setting_info
|
||||||
- network.tcp_connect
|
- app.load_content
|
||||||
- network.tcp_open
|
- app.reset_content
|
||||||
- network.get_total_upload
|
- app.is_content_loaded
|
||||||
- network.get_total_download
|
- app.quit
|
||||||
- gfx.text3d.show
|
- entity:get_player
|
||||||
- gfx.text3d.hide
|
- start_coroutine
|
||||||
- gfx.text3d.get_text
|
- gui.clear_markup
|
||||||
- gfx.text3d.set_text
|
- gui.escape_markup
|
||||||
- gfx.text3d.get_pos
|
- gui.alert
|
||||||
- gfx.text3d.set_pos
|
- gui.confirm
|
||||||
- gfx.text3d.get_axis_x
|
- gui.load_document
|
||||||
- gfx.text3d.set_axis_x
|
- console.get
|
||||||
- gfx.text3d.get_axis_y
|
- world.get_chunk_data
|
||||||
- gfx.text3d.set_axis_y
|
- world.set_chunk_data
|
||||||
- gfx.text3d.set_rotation
|
- world.save_chunk_data
|
||||||
- gfx.text3d.update_settings
|
- world.count_chunks
|
||||||
|
- player.create
|
||||||
|
- player.delete
|
||||||
|
- player.is_suspended
|
||||||
|
- player.set_suspended
|
||||||
|
- player.is_loaded_chunks
|
||||||
|
- player.set_loading_chunks
|
||||||
|
- network.post
|
||||||
|
- table.shuffle
|
||||||
|
- table.deep_copy
|
||||||
|
- math.normalize
|
||||||
|
- math.round
|
||||||
|
- byteutil.pack
|
||||||
|
- byteutil.unpack
|
||||||
|
- file.name
|
||||||
|
- file.stem
|
||||||
|
- file.ext
|
||||||
|
- file.prefix
|
||||||
|
- hud.set_allow_pause
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- uinode:reposition
|
||||||
|
- socket:available
|
||||||
|
|
||||||
|
New overloads:
|
||||||
|
- block.get_X, block.get_Y, block.get_Z
|
||||||
|
- player.get_rot
|
||||||
|
- Bytearray:append
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
- [fix on_block_interact & fix segfault after engine finished](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d1f92c21d0bbdf2df0eb3b31c5637bdf7110444c)
|
||||||
- [fix translucent blocks render](https://github.com/MihailRis/VoxelEngine-Cpp/pull/370)
|
- [fix item.properties](https://github.com/MihailRis/VoxelEngine-Cpp/commit/92fb19ba5e2307fdbcbf5d0e55f9c0712be45f72)
|
||||||
- [fix blocks selection with semi-transparent blocks](https://github.com/MihailRis/VoxelEngine-Cpp/commit/171cbb48d099032d7e78c51a46c374104f96f0d1)
|
- [fix base:bazalt durability](https://github.com/MihailRis/VoxelEngine-Cpp/commit/a036c5e383135dc0f9b086e244188d1ceb3f0bf2)
|
||||||
- [fix: commands repository not reset before world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1a00a91b604399f3108aa995422d371e573e650b)
|
- [fix camera-related bugs](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0d071ab0141edbf087f3ec03505792740023c01e)
|
||||||
- [mip-mapping related fixes](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d9277e1b31714632bd7f5f601b8362a9e7cb8819)
|
- [fix: grabbed item is deleted on inventory close](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2787f2fc5495004f6029644ed5221f3abfc0c68f)
|
||||||
- [fix disabled slots display](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e8ee3e04b1398a3ada8445591267525304410571)
|
- [fix block overriding](https://github.com/MihailRis/VoxelEngine-Cpp/commit/cda34e3975a42696ea31a1b0018731e746cd13bb)
|
||||||
- [fix attack](https://github.com/MihailRis/VoxelEngine-Cpp/commit/bc17abc8b3ee7ff9027f7e3c375ca0330bb8e7bc)
|
- [fix faces culling when 'light-passing' is false](https://github.com/MihailRis/VoxelEngine-Cpp/commit/954724c8378da525fc7349c018e9351c5bdfdf8f)
|
||||||
- [fix: commands repository not reset before world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1a00a91b604399f3108aa995422d371e573e650b)
|
- [fix particles lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6be640458d6b4ae46866b342ca0f26e561ead125)
|
||||||
- [fix stdlib.lua](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6ec33ab98c78523eaececf40f113f2323d25a33a)
|
- [fix non-skipping particles](https://github.com/MihailRis/VoxelEngine-Cpp/pull/421/commits/f1c7317c5ab2a148e5188e091cd1aa3490dc8b4d)
|
||||||
- [fix file.write_bytes](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0fec17a8b69ac81255b77022f3af5addf8fcc8f8)
|
- [fix content stats](https://github.com/MihailRis/VoxelEngine-Cpp/commit/97eef3ef1900157a9648bade8e06b203b99ee6f6)
|
||||||
- [fix World::nextInventoryId](https://github.com/MihailRis/VoxelEngine-Cpp/commit/371fdaedcef2c163edd226160f388068b2bf5e83)
|
- [fix byte manipulation functions](https://github.com/MihailRis/VoxelEngine-Cpp/commit/9490d1f7eacb00f56112dfdd1ea12bb9c3ca528d)
|
||||||
- [fix block inventory unbinding](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6f6c2a916afd6b9b79221111fc72b1a86109be13)
|
- [fix error handling in events and runnables](https://github.com/MihailRis/VoxelEngine-Cpp/commit/03a3062940ebfc4e8f0b3efc5930c71f8d07b604)
|
||||||
- [fix xml text escapes handling](https://github.com/MihailRis/VoxelEngine-Cpp/commit/53c54dc91d132c221ff5fea2f7e9fb4568db9a0f)
|
- [fix small dumb legacy memory leak](https://github.com/MihailRis/VoxelEngine-Cpp/commit/4d0b9f049b79322959e4aefd95eedc665e87d087)
|
||||||
- [fix `\'` escape parsing](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2bc6cbda2e809b14fa6cffe09161b53c1636675f)
|
- [fix grass lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/9d7816a286fb3a7269b5220502354720e4d2726b)
|
||||||
- [fix crosshair look](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e034bda477c35efe96548e78ecc722966a7a2197)
|
- [small fixes in translation.](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d25452784d68be19821dc917ad15bc0a92d81bd9)
|
||||||
- [fix: actual block inventory size not updating on inventory-size property update](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1ba5b0ce33103e539ccb199ee1cd52095e286a1f)
|
- [fix errors handling in event handlers](https://github.com/MihailRis/VoxelEngine-Cpp/commit/f62fc5a039dca70219fb2b38f61fc53a2542adf7)
|
||||||
- [fix falling block hitbox](https://github.com/MihailRis/VoxelEngine-Cpp/commit/352ef6485a4b796d1cdc8dd0e00ab1a1d72a2c0a)
|
- [fix lua stack manipulations](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e7555448cf0df86995b40d67fa58de1ca78f8105)
|
||||||
- [fix console position](https://github.com/MihailRis/VoxelEngine-Cpp/commit/3ea213e8d3cee7be55ec39ffb18dc557dec7557b)
|
- [fix lua::create_lambda](https://github.com/MihailRis/VoxelEngine-Cpp/commit/40cdebb175014736e35bc31ecc93ae72fb00a6e9)
|
||||||
- [fix: fatal error on pack removal when no world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/78d5ab02c2ba8a3d05cf5639eb10a49c9ca14ec3)
|
- [fix some UB](https://github.com/MihailRis/VoxelEngine-Cpp/commit/b5999fe36420d116674abc353ed3dad739ac5f70)
|
||||||
- [fix custom model lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/a333cadfcaeb485a30833343d55faf01b28a5c5f)
|
- [fix rigidbody:is_enabled](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2adfbdb19226b2685848131073a56b354706433d)
|
||||||
- [fix: emitter does not skip particles](https://github.com/MihailRis/VoxelEngine-Cpp/commit/983e516fb4ebc1f2def592f2b7f3195d968deed2)
|
- [fix panel elements removal](https://github.com/MihailRis/VoxelEngine-Cpp/commit/c6951e09651149463528bdffbc2cba4ea41de4a4)
|
||||||
- [fix old custom models render](https://github.com/MihailRis/VoxelEngine-Cpp/commit/82733d38011b52a426cb74560521949c1cd43cc1)
|
- [fix infinite block fields conversion requests](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0494db91872abff500cfc153a32035ee3f2745ae)
|
||||||
|
- [fix data_buffer:put_number](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e247902cc6ffdaa6beab391fcfdaea7f021ab063)
|
||||||
|
- [fix textbox horizontal scroll & fix console log width](https://github.com/MihailRis/VoxelEngine-Cpp/commit/13fde2116d095b9393c4f5804ba23071e5f56ad6)
|
||||||
|
- [fix is_array](https://github.com/MihailRis/VoxelEngine-Cpp/pull/420)
|
||||||
|
- [fix neighbour chunk update](https://github.com/MihailRis/VoxelEngine-Cpp/pull/404)
|
||||||
|
- [fix lamp material](https://github.com/MihailRis/VoxelEngine-Cpp/commit/57356e1d64d6d9d7e8d59b078543b290e998ad00)
|
||||||
|
|||||||
@ -29,7 +29,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
|||||||
# Install EnTT
|
# Install EnTT
|
||||||
RUN git clone https://github.com/skypjack/entt.git && \
|
RUN git clone https://github.com/skypjack/entt.git && \
|
||||||
cd entt/build && \
|
cd entt/build && \
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release .. && \
|
cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on .. && \
|
||||||
make install && \
|
make install && \
|
||||||
cd ../.. && rm -rf entt
|
cd ../.. && rm -rf entt
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
## Latest release
|
## Latest release
|
||||||
|
|
||||||
- [Download](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest)
|
- [Download](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest)
|
||||||
- [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/ru/main-page.md)
|
- [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.26/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.26/doc/ru/main-page.md)
|
||||||
|
|
||||||
## Build project in Linux
|
## Build project in Linux
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
Documentation for in-development version 0.26.
|
Documentation for release 0.26.
|
||||||
|
|
||||||
[Documentation for stable release 0.25.x.](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/en/main-page.md)
|
|
||||||
|
|
||||||
## Sections
|
## Sections
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,17 @@ gui.escape_markup(
|
|||||||
|
|
||||||
Escapes markup in text.
|
Escapes markup in text.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
gui.alert(
|
||||||
|
-- message (not automatically translated, use gui.str(...))
|
||||||
|
message: str,
|
||||||
|
-- function called on close
|
||||||
|
on_ok: function() -> nil
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Displays a message box. **Non-blocking**.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
gui.confirm(
|
gui.confirm(
|
||||||
-- message (does not translate automatically, use gui.str(...))
|
-- message (does not translate automatically, use gui.str(...))
|
||||||
@ -78,7 +89,7 @@ gui.confirm(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Requests confirmation from the user for an action. **Does not** stop code execution.
|
Requests confirmation from the user for an action. **Non-blocking**.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
gui.load_document(
|
gui.load_document(
|
||||||
|
|||||||
@ -96,6 +96,15 @@ player.get_spawnpoint(playerid: int) -> number, number, number
|
|||||||
|
|
||||||
Spawn point setter and getter
|
Spawn point setter and getter
|
||||||
|
|
||||||
|
```lua
|
||||||
|
player.is_suspended(pid: int) -> bool
|
||||||
|
player.set_suspended(pid: int, suspended: bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
Setter and getter for the player's suspended status.
|
||||||
|
|
||||||
|
When suspended, the entity is deleted and the player is disabled from the world simulation.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
player.set_name(playerid: int, name: str)
|
player.set_name(playerid: int, name: str)
|
||||||
player.get_name(playerid: int) -> str
|
player.get_name(playerid: int) -> str
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
# Документация
|
# Документация
|
||||||
|
|
||||||
Документация разрабатываемой версии 0.26.
|
Документация версии 0.26.
|
||||||
|
|
||||||
[Документация стабильной версии 0.25.x.](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/ru/main-page.md)
|
|
||||||
|
|
||||||
## Разделы
|
## Разделы
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,17 @@ gui.escape_markup(
|
|||||||
|
|
||||||
Экранирует разметку в тексте.
|
Экранирует разметку в тексте.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
gui.alert(
|
||||||
|
-- сообщение (не переводится автоматически, используйте gui.str(...))
|
||||||
|
message: str,
|
||||||
|
-- функция, вызываемая при закрытии
|
||||||
|
on_ok: function() -> nil
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Выводит окно с сообщением. **Не** останавливает выполнение кода.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
gui.confirm(
|
gui.confirm(
|
||||||
-- сообщение (не переводится автоматически, используйте gui.str(...))
|
-- сообщение (не переводится автоматически, используйте gui.str(...))
|
||||||
|
|||||||
@ -96,6 +96,15 @@ player.get_spawnpoint(playerid: int) -> number, number, number
|
|||||||
|
|
||||||
Сеттер и геттер точки спавна игрока
|
Сеттер и геттер точки спавна игрока
|
||||||
|
|
||||||
|
```lua
|
||||||
|
player.is_suspended(pid: int) -> bool
|
||||||
|
player.set_suspended(pid: int, suspended: bool)
|
||||||
|
```
|
||||||
|
|
||||||
|
Сеттер и геттер статуса "заморозки" игрока.
|
||||||
|
|
||||||
|
При "заморозке" удаляется сущность, а игрок выключается из симуляции мира.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
player.set_name(playerid: int, name: str)
|
player.set_name(playerid: int, name: str)
|
||||||
player.get_name(playerid: int) -> str
|
player.get_name(playerid: int) -> str
|
||||||
|
|||||||
5
res/content/base/block_materials/snow.json
Normal file
5
res/content/base/block_materials/snow.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"steps-sound": "steps/snow",
|
||||||
|
"place-sound": "blocks/snow_place",
|
||||||
|
"break-sound": "blocks/snow_break"
|
||||||
|
}
|
||||||
@ -19,7 +19,7 @@ function on_render()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local rx, ry, rz = player.get_rot(pid, true)
|
local rx, ry, rz = player.get_rot(pid, pid ~= hud.get_player())
|
||||||
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
|
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
|
||||||
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))
|
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))
|
||||||
|
|
||||||
|
|||||||
BIN
res/content/base/sounds/blocks/snow_3.ogg
Normal file
BIN
res/content/base/sounds/blocks/snow_3.ogg
Normal file
Binary file not shown.
BIN
res/content/base/sounds/blocks/snow_break.ogg
Normal file
BIN
res/content/base/sounds/blocks/snow_break.ogg
Normal file
Binary file not shown.
BIN
res/content/base/sounds/blocks/snow_place.ogg
Normal file
BIN
res/content/base/sounds/blocks/snow_place.ogg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -194,8 +194,8 @@ function gui.template(name, params)
|
|||||||
text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''")
|
text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''")
|
||||||
text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"")
|
text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"")
|
||||||
-- remove unsolved properties: attr='%{var}'
|
-- remove unsolved properties: attr='%{var}'
|
||||||
text = text:gsub("%w+%s*=%s*'%%{%w+}'%s?", "")
|
text = text:gsub("%s*%S+='%%{[^}]+}'%s*", " ")
|
||||||
text = text:gsub("%w+%s*=%s*\"%%{%w+}\"%s?", "")
|
text = text:gsub('%s*%S+="%%{[^}]+}"%s*', " ")
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#include "lighting/Lightmap.hpp"
|
#include "lighting/Lightmap.hpp"
|
||||||
#include "frontend/ContentGfxCache.hpp"
|
#include "frontend/ContentGfxCache.hpp"
|
||||||
|
|
||||||
const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f);
|
const glm::vec3 BlocksRenderer::SUN_VECTOR (0.2275f,0.9388f,-0.1005f);
|
||||||
|
|
||||||
BlocksRenderer::BlocksRenderer(
|
BlocksRenderer::BlocksRenderer(
|
||||||
size_t capacity,
|
size_t capacity,
|
||||||
@ -129,7 +129,7 @@ void BlocksRenderer::faceAO(
|
|||||||
float s = 0.5f;
|
float s = 0.5f;
|
||||||
if (lights) {
|
if (lights) {
|
||||||
float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
|
float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
|
||||||
d = 0.8f + d * 0.2f;
|
d = 0.7f + d * 0.3f;
|
||||||
|
|
||||||
auto axisX = glm::normalize(X);
|
auto axisX = glm::normalize(X);
|
||||||
auto axisY = glm::normalize(Y);
|
auto axisY = glm::normalize(Y);
|
||||||
@ -167,7 +167,7 @@ void BlocksRenderer::face(
|
|||||||
float s = 0.5f;
|
float s = 0.5f;
|
||||||
if (lights) {
|
if (lights) {
|
||||||
float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
|
float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
|
||||||
d = 0.8f + d * 0.2f;
|
d = 0.7f + d * 0.3f;
|
||||||
tint *= d;
|
tint *= d;
|
||||||
}
|
}
|
||||||
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);
|
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "elements/UINode.hpp"
|
#include "elements/UINode.hpp"
|
||||||
#include "elements/Label.hpp"
|
#include "elements/Label.hpp"
|
||||||
#include "elements/Menu.hpp"
|
#include "elements/Menu.hpp"
|
||||||
|
#include "elements/Panel.hpp"
|
||||||
|
|
||||||
#include "assets/Assets.hpp"
|
#include "assets/Assets.hpp"
|
||||||
#include "frontend/UiDocument.hpp"
|
#include "frontend/UiDocument.hpp"
|
||||||
@ -23,8 +24,10 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
GUI::GUI() : batch2D(std::make_unique<Batch2D>(1024)) {
|
GUI::GUI()
|
||||||
container = std::make_shared<Container>(glm::vec2(1000));
|
: batch2D(std::make_unique<Batch2D>(1024)),
|
||||||
|
container(std::make_shared<Container>(glm::vec2(1000))) {
|
||||||
|
container->setId("root");
|
||||||
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
|
||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
@ -214,6 +217,14 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
auto& viewport = ctx.getViewport();
|
auto& viewport = ctx.getViewport();
|
||||||
glm::vec2 wsize = viewport.size();
|
glm::vec2 wsize = viewport.size();
|
||||||
|
|
||||||
|
auto& page = menu->getCurrent();
|
||||||
|
if (page.panel) {
|
||||||
|
menu->setSize(page.panel->getSize());
|
||||||
|
page.panel->refresh();
|
||||||
|
if (auto panel = std::dynamic_pointer_cast<gui::Panel>(page.panel)) {
|
||||||
|
panel->cropToContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
menu->setPos((wsize - menu->getSize()) / 2.0f);
|
menu->setPos((wsize - menu->getSize()) / 2.0f);
|
||||||
uicamera->setFov(wsize.y);
|
uicamera->setFov(wsize.y);
|
||||||
|
|
||||||
|
|||||||
@ -65,9 +65,10 @@ void Menu::setPage(Page page, bool history) {
|
|||||||
setSize(current.panel->getSize());
|
setSize(current.panel->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::back() {
|
bool Menu::back() {
|
||||||
if (pageStack.empty())
|
if (pageStack.empty()) {
|
||||||
return;
|
return false;
|
||||||
|
}
|
||||||
Page page = pageStack.top();
|
Page page = pageStack.top();
|
||||||
pageStack.pop();
|
pageStack.pop();
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ void Menu::back() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPage(page, false);
|
setPage(page, false);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::setPageLoader(PageLoaderFunc loader) {
|
void Menu::setPageLoader(PageLoaderFunc loader) {
|
||||||
|
|||||||
@ -54,7 +54,7 @@ namespace gui {
|
|||||||
PageLoaderFunc getPageLoader();
|
PageLoaderFunc getPageLoader();
|
||||||
|
|
||||||
/// @brief Set page to previous saved in history
|
/// @brief Set page to previous saved in history
|
||||||
void back();
|
bool back();
|
||||||
|
|
||||||
/// @brief Clear pages history
|
/// @brief Clear pages history
|
||||||
void clearHistory();
|
void clearHistory();
|
||||||
|
|||||||
@ -70,9 +70,6 @@ void Panel::remove(const std::shared_ptr<UINode> &node) {
|
|||||||
|
|
||||||
void Panel::refresh() {
|
void Panel::refresh() {
|
||||||
UINode::refresh();
|
UINode::refresh();
|
||||||
std::stable_sort(nodes.begin(), nodes.end(), [](auto a, auto b) {
|
|
||||||
return a->getZIndex() < b->getZIndex();
|
|
||||||
});
|
|
||||||
|
|
||||||
float x = padding.x;
|
float x = padding.x;
|
||||||
float y = padding.y;
|
float y = padding.y;
|
||||||
@ -80,20 +77,21 @@ void Panel::refresh() {
|
|||||||
if (orientation == Orientation::vertical) {
|
if (orientation == Orientation::vertical) {
|
||||||
float maxw = size.x;
|
float maxw = size.x;
|
||||||
for (auto& node : nodes) {
|
for (auto& node : nodes) {
|
||||||
glm::vec2 nodesize = node->getSize();
|
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
y += margin.y;
|
y += margin.y;
|
||||||
|
|
||||||
float ex = x + margin.x;
|
float ex = x + margin.x;
|
||||||
node->setPos(glm::vec2(ex, y));
|
node->setPos(glm::vec2(ex, y));
|
||||||
y += nodesize.y + margin.w + interval;
|
|
||||||
|
|
||||||
float width = size.x - padding.x - padding.z - margin.x - margin.z;
|
float width = size.x - padding.x - padding.z - margin.x - margin.z;
|
||||||
if (node->isResizing()) {
|
if (node->isResizing()) {
|
||||||
node->setSize(glm::vec2(width, nodesize.y));
|
node->setMaxSize({width, node->getMaxSize().y});
|
||||||
|
node->setSize(glm::vec2(width, node->getSize().y));
|
||||||
}
|
}
|
||||||
node->refresh();
|
node->refresh();
|
||||||
maxw = fmax(maxw, ex+node->getSize().x+margin.z+padding.z);
|
glm::vec2 nodeSize = node->getSize();
|
||||||
|
y += nodeSize.y + margin.w + interval;
|
||||||
|
maxw = fmax(maxw, ex+nodeSize.x+margin.z+padding.z);
|
||||||
}
|
}
|
||||||
actualLength = y + padding.w;
|
actualLength = y + padding.w;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -195,7 +195,8 @@ glm::vec2 UINode::getSize() const {
|
|||||||
|
|
||||||
void UINode::setSize(glm::vec2 size) {
|
void UINode::setSize(glm::vec2 size) {
|
||||||
this->size = glm::vec2(
|
this->size = glm::vec2(
|
||||||
glm::max(minSize.x, size.x), glm::max(minSize.y, size.y)
|
glm::max(minSize.x, glm::min(maxSize.x, size.x)),
|
||||||
|
glm::max(minSize.y, glm::min(maxSize.y, size.y))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +209,15 @@ void UINode::setMinSize(glm::vec2 minSize) {
|
|||||||
setSize(getSize());
|
setSize(getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec2 UINode::getMaxSize() const {
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::setMaxSize(glm::vec2 maxSize) {
|
||||||
|
this->maxSize = maxSize;
|
||||||
|
setSize(getSize());
|
||||||
|
}
|
||||||
|
|
||||||
void UINode::setColor(glm::vec4 color) {
|
void UINode::setColor(glm::vec4 color) {
|
||||||
this->color = color;
|
this->color = color;
|
||||||
this->hoverColor = color;
|
this->hoverColor = color;
|
||||||
|
|||||||
@ -75,6 +75,8 @@ namespace gui {
|
|||||||
glm::vec2 size;
|
glm::vec2 size;
|
||||||
/// @brief minimal element size
|
/// @brief minimal element size
|
||||||
glm::vec2 minSize {1.0f};
|
glm::vec2 minSize {1.0f};
|
||||||
|
/// @brief maximal element size
|
||||||
|
glm::vec2 maxSize {1e6f};
|
||||||
/// @brief element primary color (background-color or text-color if label)
|
/// @brief element primary color (background-color or text-color if label)
|
||||||
glm::vec4 color {1.0f};
|
glm::vec4 color {1.0f};
|
||||||
/// @brief element color when mouse is over it
|
/// @brief element color when mouse is over it
|
||||||
@ -224,6 +226,8 @@ namespace gui {
|
|||||||
virtual void setSize(glm::vec2 size);
|
virtual void setSize(glm::vec2 size);
|
||||||
virtual glm::vec2 getMinSize() const;
|
virtual glm::vec2 getMinSize() const;
|
||||||
virtual void setMinSize(glm::vec2 size);
|
virtual void setMinSize(glm::vec2 size);
|
||||||
|
virtual glm::vec2 getMaxSize() const;
|
||||||
|
virtual void setMaxSize(glm::vec2 size);
|
||||||
/// @brief Called in containers when new element added
|
/// @brief Called in containers when new element added
|
||||||
virtual void refresh() {};
|
virtual void refresh() {};
|
||||||
virtual void fullRefresh() {
|
virtual void fullRefresh() {
|
||||||
|
|||||||
@ -31,7 +31,17 @@ void guiutil::alert(
|
|||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
const runnable& on_hidden
|
const runnable& on_hidden
|
||||||
) {
|
) {
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(500, 300), glm::vec4(4.0f), 4.0f);
|
auto panel = std::make_shared<Panel>(
|
||||||
|
glm::vec2(
|
||||||
|
glm::min(
|
||||||
|
static_cast<size_t>(650),
|
||||||
|
glm::max(text.length() * 10, static_cast<size_t>(200))
|
||||||
|
),
|
||||||
|
300
|
||||||
|
),
|
||||||
|
glm::vec4(4.0f),
|
||||||
|
4.0f
|
||||||
|
);
|
||||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
|
|
||||||
auto menuPtr = engine.getGUI()->getMenu();
|
auto menuPtr = engine.getGUI()->getMenu();
|
||||||
@ -40,14 +50,15 @@ void guiutil::alert(
|
|||||||
menu.removePage("<alert>");
|
menu.removePage("<alert>");
|
||||||
if (on_hidden) {
|
if (on_hidden) {
|
||||||
on_hidden();
|
on_hidden();
|
||||||
} else {
|
} else if (!menu.back()) {
|
||||||
menu.back();
|
menu.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto label = std::make_shared<Label>(text);
|
auto label = std::make_shared<Label>(text);
|
||||||
label->setMultiline(true);
|
label->setMultiline(true);
|
||||||
label->setSize(glm::vec2(1, 24));
|
label->setSize(glm::vec2(1, 24));
|
||||||
|
label->setAutoResize(true);
|
||||||
panel->add(label);
|
panel->add(label);
|
||||||
panel->add(std::make_shared<Button>(
|
panel->add(std::make_shared<Button>(
|
||||||
langs::get(L"Ok"), glm::vec4(10.f),
|
langs::get(L"Ok"), glm::vec4(10.f),
|
||||||
@ -56,6 +67,7 @@ void guiutil::alert(
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
panel->refresh();
|
panel->refresh();
|
||||||
|
|
||||||
panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([on_hidden_final](){
|
panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([on_hidden_final](){
|
||||||
on_hidden_final();
|
on_hidden_final();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -148,7 +148,13 @@ static int l_reconfig_packs(lua::State* L) {
|
|||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
}
|
}
|
||||||
auto engineController = engine->getController();
|
auto engineController = engine->getController();
|
||||||
engineController->reconfigPacks(controller, addPacks, remPacks);
|
try {
|
||||||
|
engineController->reconfigPacks(controller, addPacks, remPacks);
|
||||||
|
} catch (const contentpack_error& err) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(err.what()) + " [" + err.getPackId() + " ]"
|
||||||
|
);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -231,7 +231,13 @@ static int l_pack_assemble(lua::State* L) {
|
|||||||
}
|
}
|
||||||
auto manager = engine->createPacksManager(worldFolder);
|
auto manager = engine->createPacksManager(worldFolder);
|
||||||
manager.scan();
|
manager.scan();
|
||||||
ids = std::move(manager.assemble(ids));
|
try {
|
||||||
|
ids = std::move(manager.assemble(ids));
|
||||||
|
} catch (const contentpack_error& err) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(err.what()) + " [" + err.getPackId() + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
lua::createtable(L, ids.size(), 0);
|
lua::createtable(L, ids.size(), 0);
|
||||||
for (size_t i = 0; i < ids.size(); i++) {
|
for (size_t i = 0; i < ids.size(); i++) {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ static int l_get_list(lua::State* L) {
|
|||||||
|
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
std::string icon = "world#" + name + ".icon";
|
std::string icon = "world#" + name + ".icon";
|
||||||
if (!AssetsLoader::loadExternalTexture(
|
if (!engine->isHeadless() && !AssetsLoader::loadExternalTexture(
|
||||||
assets,
|
assets,
|
||||||
icon,
|
icon,
|
||||||
{worlds[i] / fs::path("icon.png"),
|
{worlds[i] / fs::path("icon.png"),
|
||||||
|
|||||||
@ -23,6 +23,7 @@ namespace lua {
|
|||||||
public:
|
public:
|
||||||
LuaBytearray(size_t capacity);
|
LuaBytearray(size_t capacity);
|
||||||
LuaBytearray(std::vector<ubyte> buffer);
|
LuaBytearray(std::vector<ubyte> buffer);
|
||||||
|
LuaBytearray(const ubyte* data, size_t size);
|
||||||
virtual ~LuaBytearray();
|
virtual ~LuaBytearray();
|
||||||
|
|
||||||
const std::string& getTypeName() const override {
|
const std::string& getTypeName() const override {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "lua_util.hpp"
|
#include "lua_util.hpp"
|
||||||
|
#include "lua_engine.hpp"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -60,13 +61,7 @@ int lua::pushvalue(State* L, const dv::value& value) {
|
|||||||
break;
|
break;
|
||||||
case value_type::bytes: {
|
case value_type::bytes: {
|
||||||
const auto& bytes = value.asBytes();
|
const auto& bytes = value.asBytes();
|
||||||
createtable(L, 0, bytes.size());
|
newuserdata<LuaBytearray>(L, bytes.data(), bytes.size());
|
||||||
size_t size = bytes.size();
|
|
||||||
for (size_t i = 0; i < size;) {
|
|
||||||
pushinteger(L, bytes[i]);
|
|
||||||
i++;
|
|
||||||
rawseti(L, i);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,6 +229,7 @@ static std::shared_ptr<std::string> create_lambda_handler(State* L) {
|
|||||||
return std::shared_ptr<std::string>(
|
return std::shared_ptr<std::string>(
|
||||||
new std::string(name),
|
new std::string(name),
|
||||||
[=](std::string* name) {
|
[=](std::string* name) {
|
||||||
|
auto L = lua::get_main_state();
|
||||||
requireglobal(L, LAMBDAS_TABLE);
|
requireglobal(L, LAMBDAS_TABLE);
|
||||||
pushnil(L);
|
pushnil(L);
|
||||||
setfield(L, *name);
|
setfield(L, *name);
|
||||||
@ -246,6 +242,7 @@ static std::shared_ptr<std::string> create_lambda_handler(State* L) {
|
|||||||
runnable lua::create_runnable(State* L) {
|
runnable lua::create_runnable(State* L) {
|
||||||
auto funcptr = create_lambda_handler(L);
|
auto funcptr = create_lambda_handler(L);
|
||||||
return [=]() {
|
return [=]() {
|
||||||
|
auto L = lua::get_main_state();
|
||||||
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
||||||
return;
|
return;
|
||||||
call_nothrow(L, 0, 0);
|
call_nothrow(L, 0, 0);
|
||||||
|
|||||||
@ -14,6 +14,9 @@ LuaBytearray::LuaBytearray(size_t capacity) : buffer(capacity) {
|
|||||||
LuaBytearray::LuaBytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
|
LuaBytearray::LuaBytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LuaBytearray::LuaBytearray(const ubyte* data, size_t size) : buffer(data, data + size) {
|
||||||
|
}
|
||||||
|
|
||||||
LuaBytearray::~LuaBytearray() {
|
LuaBytearray::~LuaBytearray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -319,7 +319,6 @@ public:
|
|||||||
~SocketConnection() {
|
~SocketConnection() {
|
||||||
if (state != ConnectionState::CLOSED) {
|
if (state != ConnectionState::CLOSED) {
|
||||||
shutdown(descriptor, 2);
|
shutdown(descriptor, 2);
|
||||||
closesocket(descriptor);
|
|
||||||
}
|
}
|
||||||
if (thread) {
|
if (thread) {
|
||||||
thread->join();
|
thread->join();
|
||||||
@ -382,6 +381,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int send(const char* buffer, size_t length) override {
|
int send(const char* buffer, size_t length) override {
|
||||||
|
if (state == ConnectionState::CLOSED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int len = sendsocket(descriptor, buffer, length, 0);
|
int len = sendsocket(descriptor, buffer, length, 0);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
int err = errno;
|
int err = errno;
|
||||||
@ -444,7 +446,7 @@ public:
|
|||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
addrinfo* addrinfo;
|
addrinfo* addrinfo = nullptr;
|
||||||
if (int res = getaddrinfo(
|
if (int res = getaddrinfo(
|
||||||
address.c_str(), nullptr, &hints, &addrinfo
|
address.c_str(), nullptr, &hints, &addrinfo
|
||||||
)) {
|
)) {
|
||||||
@ -452,12 +454,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in serverAddress = *(sockaddr_in*)addrinfo->ai_addr;
|
sockaddr_in serverAddress = *(sockaddr_in*)addrinfo->ai_addr;
|
||||||
freeaddrinfo(addrinfo);
|
|
||||||
serverAddress.sin_port = htons(port);
|
serverAddress.sin_port = htons(port);
|
||||||
|
freeaddrinfo(addrinfo);
|
||||||
|
|
||||||
SOCKET descriptor = socket(AF_INET, SOCK_STREAM, 0);
|
SOCKET descriptor = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (descriptor == -1) {
|
if (descriptor == -1) {
|
||||||
freeaddrinfo(addrinfo);
|
|
||||||
throw std::runtime_error("Could not create socket");
|
throw std::runtime_error("Could not create socket");
|
||||||
}
|
}
|
||||||
auto socket = std::make_shared<SocketConnection>(descriptor, std::move(serverAddress));
|
auto socket = std::make_shared<SocketConnection>(descriptor, std::move(serverAddress));
|
||||||
|
|||||||
@ -65,17 +65,21 @@ int platform::get_process_id() {
|
|||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "frontend/locale.hpp"
|
||||||
|
|
||||||
void platform::configure_encoding() {
|
void platform::configure_encoding() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string platform::detect_locale() {
|
std::string platform::detect_locale() {
|
||||||
std::string programLocaleName = setlocale(LC_ALL, nullptr);
|
const char* const programLocaleName = setlocale(LC_ALL, nullptr);
|
||||||
std::string preferredLocaleName =
|
const char* const preferredLocaleName =
|
||||||
setlocale(LC_ALL, ""); // locale name format: ll_CC.encoding
|
setlocale(LC_ALL, ""); // locale name format: ll_CC.encoding
|
||||||
setlocale(LC_ALL, programLocaleName.c_str());
|
if (programLocaleName && preferredLocaleName) {
|
||||||
|
setlocale(LC_ALL, programLocaleName);
|
||||||
|
|
||||||
return preferredLocaleName.substr(0, 5);
|
return std::string(preferredLocaleName, 5);
|
||||||
|
}
|
||||||
|
return langs::FALLBACK_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform::sleep(size_t millis) {
|
void platform::sleep(size_t millis) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user