Fixing minor stuff, working on Web version
This commit is contained in:
parent
5ecf5fb9d7
commit
7df68febca
BIN
audio/13925__adcbicycle__21.ogg
(Stored with Git LFS)
BIN
audio/13925__adcbicycle__21.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/255571__stradie__flipping-paper.ogg
(Stored with Git LFS)
BIN
audio/255571__stradie__flipping-paper.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/398751__anthousai__door-lock-01.ogg
(Stored with Git LFS)
BIN
audio/398751__anthousai__door-lock-01.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/459618__n-lerche__blow.ogg
(Stored with Git LFS)
BIN
audio/459618__n-lerche__blow.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/537061__imafoley__message-pop-sound.ogg
(Stored with Git LFS)
BIN
audio/537061__imafoley__message-pop-sound.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/547041__cogfirestudios__hit-swing-sword-small-3.ogg
(Stored with Git LFS)
BIN
audio/547041__cogfirestudios__hit-swing-sword-small-3.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/587036__antoineromo__bed-sheets.ogg
(Stored with Git LFS)
BIN
audio/587036__antoineromo__bed-sheets.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/656126__itsthegoodstuff__paging-through-book.ogg
(Stored with Git LFS)
BIN
audio/656126__itsthegoodstuff__paging-through-book.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/702171__foxfire__door-opening.ogg
(Stored with Git LFS)
BIN
audio/702171__foxfire__door-opening.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/751089__smallconfusion__mechanical-plastic-click-11.ogg
(Stored with Git LFS)
BIN
audio/751089__smallconfusion__mechanical-plastic-click-11.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/78564__joedeshon__alarm_clock_ticking_02.ogg
(Stored with Git LFS)
BIN
audio/78564__joedeshon__alarm_clock_ticking_02.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/831642__ienba__generic-game-pick-up.ogg
(Stored with Git LFS)
BIN
audio/831642__ienba__generic-game-pick-up.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/sound_bag001.ogg
(Stored with Git LFS)
BIN
audio/sound_bag001.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/sound_bag_close.ogg
(Stored with Git LFS)
BIN
audio/sound_bag_close.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
audio/sound_bag_open.ogg
(Stored with Git LFS)
BIN
audio/sound_bag_open.ogg
(Stored with Git LFS)
Binary file not shown.
@ -27,7 +27,18 @@ except ImportError:
|
|||||||
# Paths relative to the resources directory — these files are never resized.
|
# Paths relative to the resources directory — these files are never resized.
|
||||||
EXCEPTIONS = {
|
EXCEPTIONS = {
|
||||||
"loading.png",
|
"loading.png",
|
||||||
|
"loading_land003_en.png",
|
||||||
|
"loading_land003_ru.png",
|
||||||
"black.png",
|
"black.png",
|
||||||
|
"transparent.png",
|
||||||
|
"w/blue.png",
|
||||||
|
"w/red.png",
|
||||||
|
"w/spark.png",
|
||||||
|
"w/star.png",
|
||||||
|
"w/star_red.png",
|
||||||
|
"w/white.png",
|
||||||
|
"w/ui/img/main/aboutPage003android.png",
|
||||||
|
"w/ui_en/img/main/aboutPage003android.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Path prefixes (relative to resources root, forward-slash) that get 8x reduction.
|
# Path prefixes (relative to resources root, forward-slash) that get 8x reduction.
|
||||||
@ -35,13 +46,28 @@ HIGH_REDUCTION_PREFIXES = (
|
|||||||
"w/ui/img",
|
"w/ui/img",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
LOW_REDUCTION_POSTFIXES = (
|
||||||
|
"texAtlas002.png",
|
||||||
|
"Building_work014.png",
|
||||||
|
"Building_Floors_tex004.png",
|
||||||
|
"Building_Walls_tex006.png",
|
||||||
|
"asphalt003small.png",
|
||||||
|
"Ext_Building004.png",
|
||||||
|
"Plane3_tex002.png",
|
||||||
|
"darklands_building002.png",
|
||||||
|
"Staircase001.png",
|
||||||
|
"Staircase_Obj002.png"
|
||||||
|
)
|
||||||
|
|
||||||
def _resize_factor(rel: str) -> int:
|
def _resize_factor(rel: str) -> int:
|
||||||
norm = rel.replace("\\", "/")
|
norm = rel.replace("\\", "/")
|
||||||
for prefix in HIGH_REDUCTION_PREFIXES:
|
for prefix in HIGH_REDUCTION_PREFIXES:
|
||||||
if norm.startswith(prefix):
|
if norm.startswith(prefix):
|
||||||
return 8
|
return 8
|
||||||
return 4
|
for prefix in LOW_REDUCTION_POSTFIXES:
|
||||||
|
if norm.endswith(prefix):
|
||||||
|
return 2
|
||||||
|
return 8
|
||||||
|
|
||||||
|
|
||||||
def _next_pot(n: int) -> int:
|
def _next_pot(n: int) -> int:
|
||||||
|
|||||||
@ -15,6 +15,12 @@ option(OPTIMIZE_WEB_RESOURCES "Resize PNG images for web build (requires Python3
|
|||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
# Максимальная оптимизация кода и LTO (Link-Time Optimization)
|
||||||
|
add_compile_options(-O3 -flto)
|
||||||
|
add_link_options(-O3 -flto)
|
||||||
|
endif()
|
||||||
|
|
||||||
# --- АВТО-ЗАГРУЗКА ЗАВИСИМОСТЕЙ ---
|
# --- АВТО-ЗАГРУЗКА ЗАВИСИМОСТЕЙ ---
|
||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
|
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
|
||||||
# Теперь гарантированно есть папка ../thirdparty со всеми исходниками
|
# Теперь гарантированно есть папка ../thirdparty со всеми исходниками
|
||||||
@ -297,6 +303,10 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/index.html"
|
|||||||
DESTINATION .
|
DESTINATION .
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/favicon.ico"
|
||||||
|
DESTINATION .
|
||||||
|
)
|
||||||
|
|
||||||
# resources.zip is served separately and downloaded asynchronously at runtime
|
# resources.zip is served separately and downloaded asynchronously at runtime
|
||||||
install(FILES "${RESOURCES_ZIP}" DESTINATION .)
|
install(FILES "${RESOURCES_ZIP}" DESTINATION .)
|
||||||
install(FILES "${MUSIC_ZIP}" DESTINATION .)
|
install(FILES "${MUSIC_ZIP}" DESTINATION .)
|
||||||
|
|||||||
@ -37,3 +37,14 @@ Run:
|
|||||||
```
|
```
|
||||||
emrun --no_browser --port 8080 public
|
emrun --no_browser --port 8080 public
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Release build
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir build_release
|
||||||
|
cd build_release
|
||||||
|
emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
cmake --build . --config Release
|
||||||
|
cmake --install . --prefix ../dist
|
||||||
|
```
|
||||||
|
|||||||
BIN
proj-web/favicon.ico
Normal file
BIN
proj-web/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@ -2276,9 +2276,9 @@
|
|||||||
"en": "And maybe she will even give me some difficult assignment."
|
"en": "And maybe she will even give me some difficult assignment."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
"key": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||||
"ru": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
"ru": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||||
"en": "I'm even sure she's looking for me. She wants to give me some kind of assignment."
|
"en": "I'm sure she's looking for me. She wants to give me some kind of assignment."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "Пока ты не принесешь мне нож из учительской, никуда я тебя не выпущу. Ошо!",
|
"key": "Пока ты не принесешь мне нож из учительской, никуда я тебя не выпущу. Ошо!",
|
||||||
|
|||||||
@ -293,14 +293,6 @@
|
|||||||
"speaker": "Бекзат",
|
"speaker": "Бекзат",
|
||||||
"portrait": "resources/dialogue/portrait_hero_neutral.png",
|
"portrait": "resources/dialogue/portrait_hero_neutral.png",
|
||||||
"text": "Почему?",
|
"text": "Почему?",
|
||||||
"next": "line_30"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "line_30",
|
|
||||||
"type": "Line",
|
|
||||||
"speaker": "Айпери",
|
|
||||||
"portrait": "resources/dialogue/portrait_aiperi.png",
|
|
||||||
"text": "Она опять будет скафнить.",
|
|
||||||
"next": "line_25"
|
"next": "line_25"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -308,7 +300,7 @@
|
|||||||
"type": "Line",
|
"type": "Line",
|
||||||
"speaker": "Айпери",
|
"speaker": "Айпери",
|
||||||
"portrait": "resources/dialogue/portrait_aiperi.png",
|
"portrait": "resources/dialogue/portrait_aiperi.png",
|
||||||
"text": "Я даже уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
"text": "Я уверена, она меня ищет. Она хочет мне какое-то задание дать.",
|
||||||
"next": "line_26"
|
"next": "line_26"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,13 +24,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "websiteButton",
|
"name": "reviewButton",
|
||||||
"horizontal_gravity": "center",
|
"horizontal_gravity": "center",
|
||||||
"vertical_gravity": "center",
|
"vertical_gravity": "center",
|
||||||
"y": 200,
|
"y": 200,
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 60,
|
"height": 60,
|
||||||
"text": "Сайт игры Тень над Бишкеком",
|
"text": "Оставьте отзыв в Google Play",
|
||||||
"fontSize": 36,
|
"fontSize": 36,
|
||||||
"color": [0.55, 0.9, 1.0, 1.0],
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
"textCentered": true
|
"textCentered": true
|
||||||
|
|||||||
80
resources/w/ui/screen_about_web.json
Normal file
80
resources/w/ui/screen_about_web.json
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "FrameLayout",
|
||||||
|
"width": "match_parent",
|
||||||
|
"height": "match_parent",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "aboutBkg",
|
||||||
|
"width": 2992,
|
||||||
|
"height": 1632,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/MenuBkg001_v001.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "aboutPicture",
|
||||||
|
"width": 720,
|
||||||
|
"height": 720,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/aboutPage003android.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "websiteButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": 200,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Сайт игры Тень над Бишкеком",
|
||||||
|
"fontSize": 36,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "telegramButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": -240,
|
||||||
|
"x": -150,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Telegram-канал",
|
||||||
|
"fontSize": 40,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "discordButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": -240,
|
||||||
|
"x": 150,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Наш Discord",
|
||||||
|
"fontSize": 40,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "aboutBackButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"y": 40,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Назад",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Slider",
|
"type": "Slider",
|
||||||
@ -68,7 +68,7 @@
|
|||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Slider",
|
"type": "Slider",
|
||||||
|
|||||||
@ -38,31 +38,19 @@
|
|||||||
"name": "noMusicText1",
|
"name": "noMusicText1",
|
||||||
"width": 500,
|
"width": 500,
|
||||||
"height": 40,
|
"height": 40,
|
||||||
"text": "Настройки музыки отсутствуют.",
|
"text": "Музыка отсутствует.",
|
||||||
"fontSize": 32,
|
"fontSize": 32,
|
||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "TextView",
|
|
||||||
"name": "noMusicText2",
|
|
||||||
"width": 500,
|
|
||||||
"height": 40,
|
|
||||||
"text": "Пакет с музыкой не установлен.",
|
|
||||||
"fontSize": 32,
|
|
||||||
"textCentered": false,
|
|
||||||
"topAligned": true,
|
|
||||||
"paddingX": 10,
|
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "musicDownloadButton",
|
"name": "musicDownloadButton",
|
||||||
"width": 500,
|
"width": 500,
|
||||||
"height": 40,
|
"height": 40,
|
||||||
"text": "Нажмите сюда, чтобы скачать и установить музыку (30 MB).",
|
"text": "Скачать пакет с музыкой (27 MB).",
|
||||||
"fontSize": 32,
|
"fontSize": 32,
|
||||||
"textCentered": true,
|
"textCentered": true,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
@ -77,7 +65,7 @@
|
|||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Slider",
|
"type": "Slider",
|
||||||
|
|||||||
BIN
resources/w/ui_en/img/inv/Inventory001.png
(Stored with Git LFS)
Normal file
BIN
resources/w/ui_en/img/inv/Inventory001.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -24,13 +24,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "websiteButton",
|
"name": "reviewButton",
|
||||||
"horizontal_gravity": "center",
|
"horizontal_gravity": "center",
|
||||||
"vertical_gravity": "center",
|
"vertical_gravity": "center",
|
||||||
"y": 200,
|
"y": 200,
|
||||||
"width": 200,
|
"width": 200,
|
||||||
"height": 60,
|
"height": 60,
|
||||||
"text": "Shadow over Bishkek website",
|
"text": "Leave a review on Google Play",
|
||||||
"fontSize": 36,
|
"fontSize": 36,
|
||||||
"color": [0.55, 0.9, 1.0, 1.0],
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
"textCentered": true
|
"textCentered": true
|
||||||
|
|||||||
80
resources/w/ui_en/screen_about_web.json
Normal file
80
resources/w/ui_en/screen_about_web.json
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "FrameLayout",
|
||||||
|
"width": "match_parent",
|
||||||
|
"height": "match_parent",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "aboutBkg",
|
||||||
|
"width": 2992,
|
||||||
|
"height": 1632,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/MenuBkg001_v001.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "aboutPicture",
|
||||||
|
"width": 720,
|
||||||
|
"height": 720,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui_en/img/main/aboutPage003android.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "websiteButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": 200,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Shadow over Bishkek website",
|
||||||
|
"fontSize": 36,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "telegramButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": -240,
|
||||||
|
"x": -150,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Telegram channel",
|
||||||
|
"fontSize": 40,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "discordButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"y": -240,
|
||||||
|
"x": 150,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Our Discord",
|
||||||
|
"fontSize": 40,
|
||||||
|
"color": [0.55, 0.9, 1.0, 1.0],
|
||||||
|
"textCentered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "aboutBackButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"y": 40,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Back",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -43,16 +43,6 @@
|
|||||||
"width": "match_parent",
|
"width": "match_parent",
|
||||||
"height": "match_parent"
|
"height": "match_parent"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "StaticImage",
|
|
||||||
"name": "chatTopCover",
|
|
||||||
"width": 446.25,
|
|
||||||
"height": 70.82,
|
|
||||||
"x": 0,
|
|
||||||
"y": -50.82,
|
|
||||||
"horizontal_gravity": "center",
|
|
||||||
"texture": "resources/w/ui/img/phone/chat_top_cover001.png"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "chatTitleButton",
|
"name": "chatTitleButton",
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Slider",
|
"type": "Slider",
|
||||||
@ -68,7 +68,7 @@
|
|||||||
"textCentered": false,
|
"textCentered": false,
|
||||||
"topAligned": true,
|
"topAligned": true,
|
||||||
"paddingX": 10,
|
"paddingX": 10,
|
||||||
"color": [1.0, 1.0, 1.0, 1.0]
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Slider",
|
"type": "Slider",
|
||||||
|
|||||||
119
resources/w/ui_en/screen_settings_nomusic_web.json
Normal file
119
resources/w/ui_en/screen_settings_nomusic_web.json
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "FrameLayout",
|
||||||
|
"width": "match_parent",
|
||||||
|
"height": "match_parent",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "StaticImage",
|
||||||
|
"name": "settingsBkg",
|
||||||
|
"width": 2992,
|
||||||
|
"height": 1632,
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"texture": "resources/w/ui/img/main/MenuBkg001_v001.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "center",
|
||||||
|
"horizontal_align": "left",
|
||||||
|
"width": 500,
|
||||||
|
"height": 600,
|
||||||
|
"spacing": 20,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "settingsTitleText",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Settings",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "noMusicText1",
|
||||||
|
"width": 500,
|
||||||
|
"height": 40,
|
||||||
|
"text": "There is no music.",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": false,
|
||||||
|
"topAligned": true,
|
||||||
|
"paddingX": 10,
|
||||||
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "musicDownloadButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 40,
|
||||||
|
"text": "Download music package (27 MB).",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "soundVolumeText",
|
||||||
|
"width": 500,
|
||||||
|
"height": 40,
|
||||||
|
"text": "",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": false,
|
||||||
|
"topAligned": true,
|
||||||
|
"paddingX": 10,
|
||||||
|
"color": [0.7, 0.7, 0.7, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Slider",
|
||||||
|
"name": "soundVolumeSlider",
|
||||||
|
"width": 500,
|
||||||
|
"height": 40,
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"value": 0.625,
|
||||||
|
"interactive": true,
|
||||||
|
"textures": {
|
||||||
|
"track": "resources/loadingProgressBarFrame.png",
|
||||||
|
"knob": "resources/loadingProgressBar.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "soundToggleButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 40,
|
||||||
|
"text": "",
|
||||||
|
"fontSize": 32,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "graphicsButton",
|
||||||
|
"width": 500,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Graphics settings",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true,
|
||||||
|
"color": [1.0, 1.0, 1.0, 1.0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "settingsBackButton",
|
||||||
|
"horizontal_gravity": "center",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"y": 40,
|
||||||
|
"width": 200,
|
||||||
|
"height": 60,
|
||||||
|
"text": "Back",
|
||||||
|
"fontSize": 40,
|
||||||
|
"textCentered": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,7 +22,6 @@ int Environment::width = CONST_DEFAULT_WIDTH;
|
|||||||
int Environment::height = CONST_DEFAULT_HEIGHT;
|
int Environment::height = CONST_DEFAULT_HEIGHT;
|
||||||
float Environment::zoom = DEFAULT_ZOOM;
|
float Environment::zoom = DEFAULT_ZOOM;
|
||||||
|
|
||||||
|
|
||||||
bool Environment::enableLogging = true;
|
bool Environment::enableLogging = true;
|
||||||
|
|
||||||
SDL_Window* Environment::window = nullptr;
|
SDL_Window* Environment::window = nullptr;
|
||||||
|
|||||||
@ -1291,6 +1291,8 @@ namespace FRG
|
|||||||
menuManager.onOrientationChanged();
|
menuManager.onOrientationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menuManager.refreshFullScreenToggleButton();
|
||||||
|
|
||||||
logger() << "Window resized (Render Size): " << Environment::width << "x" << Environment::height << std::endl;
|
logger() << "Window resized (Render Size): " << Environment::width << "x" << Environment::height << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,9 +28,12 @@ namespace FRG {
|
|||||||
static const std::string BACK_TO_MAIN_MENU_EN = "Back to Main Menu";
|
static const std::string BACK_TO_MAIN_MENU_EN = "Back to Main Menu";
|
||||||
|
|
||||||
static const std::string MUSIC_DOWNLOAD_ERROR_RU = u8"Ошибка скачивания музыки";
|
static const std::string MUSIC_DOWNLOAD_ERROR_RU = u8"Ошибка скачивания музыки";
|
||||||
static const std::string MUSIC_DOWNLOAD_NOT_STARTED_RU = u8"Нажмите сюда, чтобы скачать и установить музыку (27 MB).";
|
static const std::string MUSIC_DOWNLOAD_NOT_STARTED_RU = u8"Скачать пакет с музыкой (27 MB).";
|
||||||
static const std::string MUSIC_DOWNLOAD_PROGRESS_PREFIX_RU = u8"Загрузка музыки: ";
|
static const std::string MUSIC_DOWNLOAD_PROGRESS_PREFIX_RU = u8"Загрузка музыки: ";
|
||||||
//static const std::string MUSIC_DOWNLOAD_COMPLETED_RU = u8"Музыка успешно загружена.";
|
|
||||||
|
static const std::string MUSIC_DOWNLOAD_ERROR_EN = u8"Music download error";
|
||||||
|
static const std::string MUSIC_DOWNLOAD_NOT_STARTED_EN = u8"Download music package (27 MB).";
|
||||||
|
static const std::string MUSIC_DOWNLOAD_PROGRESS_PREFIX_EN = u8"Music download: ";
|
||||||
|
|
||||||
|
|
||||||
static int questStatusPriority(Quest::QuestStatus status) {
|
static int questStatusPriority(Quest::QuestStatus status) {
|
||||||
@ -246,7 +249,7 @@ namespace FRG {
|
|||||||
void MenuManager::loadUiRoots(const std::string& zipFile) {
|
void MenuManager::loadUiRoots(const std::string& zipFile) {
|
||||||
hudRoot = loadLocalizedUi("resources/w/ui/hud_step0.json", zipFile);
|
hudRoot = loadLocalizedUi("resources/w/ui/hud_step0.json", zipFile);
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__)
|
||||||
hudStep1Root = loadLocalizedUi("resources/w/ui/hud_step1android.json", zipFile);
|
hudStep1Root = loadLocalizedUi("resources/w/ui/hud_step1android.json", zipFile);
|
||||||
hudStep2Root = loadLocalizedUi("resources/w/ui/hud_step2android.json", zipFile);
|
hudStep2Root = loadLocalizedUi("resources/w/ui/hud_step2android.json", zipFile);
|
||||||
#else
|
#else
|
||||||
@ -288,7 +291,10 @@ namespace FRG {
|
|||||||
hudUniIntDarkFullRoot = loadLocalizedUi("resources/w/ui/hud_uni_int_dark_full.json", zipFile);
|
hudUniIntDarkFullRoot = loadLocalizedUi("resources/w/ui/hud_uni_int_dark_full.json", zipFile);
|
||||||
hudUniExtDarkRoot = loadLocalizedUi("resources/w/ui/hud_uni_ext_dark.json", zipFile);
|
hudUniExtDarkRoot = loadLocalizedUi("resources/w/ui/hud_uni_ext_dark.json", zipFile);
|
||||||
|
|
||||||
hudCutsceneRoot_ = loadLocalizedUi("resources/w/ui/hud_cutscene.json", zipFile);
|
//hudCutsceneRoot_ = loadLocalizedUi("resources/w/ui/hud_cutscene.json", zipFile);
|
||||||
|
hudCutsceneRoot_ = loadUiFromFile("resources/w/ui/hud_cutscene.json", renderer, zipFile);
|
||||||
|
|
||||||
|
|
||||||
hudTopHintRoot_ = loadLocalizedUi("resources/w/ui/hud_top_hint01.json", zipFile);
|
hudTopHintRoot_ = loadLocalizedUi("resources/w/ui/hud_top_hint01.json", zipFile);
|
||||||
|
|
||||||
phoneMainRoot = loadLocalizedUi("resources/w/ui/screen_phone.json", zipFile);
|
phoneMainRoot = loadLocalizedUi("resources/w/ui/screen_phone.json", zipFile);
|
||||||
@ -329,12 +335,18 @@ namespace FRG {
|
|||||||
portraitQuestJournalListRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal.json", zipFile);
|
portraitQuestJournalListRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal.json", zipFile);
|
||||||
portraitQuestJournalItemRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal_item.json", zipFile);
|
portraitQuestJournalItemRoot = loadLocalizedUi("resources/w/ui/portrait_screen_journal_item.json", zipFile);
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
|
||||||
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu_android.json", zipFile);
|
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu_android.json", zipFile);
|
||||||
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about_android.json", zipFile);
|
|
||||||
#else
|
#else
|
||||||
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile);
|
mainMenuRoot = loadLocalizedUi("resources/w/ui/screen_main_menu.json", zipFile);
|
||||||
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.json", zipFile);
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about_android.json", zipFile);
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about_web.json", zipFile);
|
||||||
|
#else
|
||||||
|
aboutScreenRoot = loadLocalizedUi("resources/w/ui/screen_about.json", zipFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
creditsScreenRoot = loadLocalizedUi("resources/w/ui/screen_credits.json", zipFile);
|
creditsScreenRoot = loadLocalizedUi("resources/w/ui/screen_credits.json", zipFile);
|
||||||
@ -615,13 +627,19 @@ namespace FRG {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __EMSCRIPTEN__
|
||||||
uiManager.setTextButtonCallback("websiteButton", [this](const std::string&) {
|
uiManager.setTextButtonCallback("websiteButton", [this](const std::string&) {
|
||||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
SDL_OpenURL("https://shadowoverbishkek.com/");
|
SDL_OpenURL("https://shadowoverbishkek.com/");
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
uiManager.setTextButtonCallback("reviewButton", [this](const std::string&) {
|
||||||
|
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
SDL_OpenURL("https://play.google.com/store/apps/details?id=fishrungames.shadowoverbishkek");
|
||||||
|
});
|
||||||
|
#endif
|
||||||
uiManager.setTextButtonCallback("telegramButton", [this](const std::string&) {
|
uiManager.setTextButtonCallback("telegramButton", [this](const std::string&) {
|
||||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
SDL_OpenURL("https://telegram.me/fishrungames");
|
SDL_OpenURL("https://telegram.me/fishrungames");
|
||||||
@ -838,6 +856,23 @@ namespace FRG {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuManager::refreshFullScreenToggleButton()
|
||||||
|
{
|
||||||
|
// Localization
|
||||||
|
if (g_currentLanguage == Language::English)
|
||||||
|
{
|
||||||
|
fullScreenToggleOn = "Full Screen: ON";
|
||||||
|
fullScreenToggleOff = "Full Screen: OFF";
|
||||||
|
}
|
||||||
|
else if (g_currentLanguage == Language::Russian)
|
||||||
|
{
|
||||||
|
fullScreenToggleOn = u8"Полноэкранный режим: ВКЛ";
|
||||||
|
fullScreenToggleOff = u8"Полноэкранный режим: ВЫКЛ";
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool on = Environment::isFullscreen;
|
||||||
|
uiManager.setTextButtonText("fullScreenToggleButton", on ? fullScreenToggleOn : fullScreenToggleOff);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
void MenuManager::showSettingsNoMusicWebScreen()
|
void MenuManager::showSettingsNoMusicWebScreen()
|
||||||
@ -863,23 +898,30 @@ namespace FRG {
|
|||||||
const float soundFrac = audioPlayer_.getSoundVolume() / 128.0f;
|
const float soundFrac = audioPlayer_.getSoundVolume() / 128.0f;
|
||||||
uiManager.setSliderValue("soundVolumeSlider", soundFrac);
|
uiManager.setSliderValue("soundVolumeSlider", soundFrac);
|
||||||
|
|
||||||
|
static std::string musicDownloadErrorString;// = MUSIC_DOWNLOAD_ERROR_RU;
|
||||||
|
static std::string musicDownloadNotStartedString;// = MUSIC_DOWNLOAD_NOT_STARTED_RU;
|
||||||
|
static std::string musicDownloadProgressPrefix;// = MUSIC_DOWNLOAD_PROGRESS_PREFIX_RU;
|
||||||
|
|
||||||
// Localization
|
// Localization
|
||||||
if (g_currentLanguage == Language::English)
|
if (g_currentLanguage == Language::English)
|
||||||
{
|
{
|
||||||
soundVolumePrefix = "Sound volume: ";
|
soundVolumePrefix = "Sound volume: ";
|
||||||
soundToggleOn = "Sound: ON";
|
soundToggleOn = "Sound: ON";
|
||||||
soundToggleOff = "Sound: OFF";
|
soundToggleOff = "Sound: OFF";
|
||||||
|
musicDownloadErrorString = MUSIC_DOWNLOAD_ERROR_EN;
|
||||||
|
musicDownloadNotStartedString = MUSIC_DOWNLOAD_NOT_STARTED_EN;
|
||||||
|
musicDownloadProgressPrefix = MUSIC_DOWNLOAD_PROGRESS_PREFIX_EN;
|
||||||
}
|
}
|
||||||
else if (g_currentLanguage == Language::Russian)
|
else if (g_currentLanguage == Language::Russian)
|
||||||
{
|
{
|
||||||
soundVolumePrefix = u8"Громкость звука: ";
|
soundVolumePrefix = u8"Громкость звука: ";
|
||||||
soundToggleOn = u8"Звук: ВКЛ";
|
soundToggleOn = u8"Звук: ВКЛ";
|
||||||
soundToggleOff = u8"Звук: ВЫКЛ";
|
soundToggleOff = u8"Звук: ВЫКЛ";
|
||||||
|
musicDownloadErrorString = MUSIC_DOWNLOAD_ERROR_RU;
|
||||||
|
musicDownloadNotStartedString = MUSIC_DOWNLOAD_NOT_STARTED_RU;
|
||||||
|
musicDownloadProgressPrefix = MUSIC_DOWNLOAD_PROGRESS_PREFIX_RU;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string musicDownloadErrorString = u8"Ошибка скачивания музыки";
|
|
||||||
static std::string musicDownloadNotStartedString = u8"Нажмите сюда, чтобы скачать\nи установить музыку (27 MB).";
|
|
||||||
static std::string musicDownloadProgressPrefix = u8"Загрузка музыки: ";
|
|
||||||
|
|
||||||
// musicDownloadStarted = false;
|
// musicDownloadStarted = false;
|
||||||
//musicDownloadError = false;
|
//musicDownloadError = false;
|
||||||
@ -969,13 +1011,17 @@ namespace FRG {
|
|||||||
});
|
});
|
||||||
|
|
||||||
uiManager.setTextButtonCallback("languageRussianButton", [this](const std::string&) {
|
uiManager.setTextButtonCallback("languageRussianButton", [this](const std::string&) {
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
#endif
|
||||||
FRG::g_currentLanguage = FRG::Language::Russian;
|
FRG::g_currentLanguage = FRG::Language::Russian;
|
||||||
reloadLocalizedGameContent();
|
reloadLocalizedGameContent();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
});
|
});
|
||||||
uiManager.setTextButtonCallback("languageEnglishButton", [this](const std::string&) {
|
uiManager.setTextButtonCallback("languageEnglishButton", [this](const std::string&) {
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||||
|
#endif
|
||||||
FRG::g_currentLanguage = FRG::Language::English;
|
FRG::g_currentLanguage = FRG::Language::English;
|
||||||
reloadLocalizedGameContent();
|
reloadLocalizedGameContent();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|||||||
@ -129,7 +129,14 @@ namespace FRG {
|
|||||||
std::shared_ptr<Texture> languageLoadingRu;
|
std::shared_ptr<Texture> languageLoadingRu;
|
||||||
std::shared_ptr<Texture> languageLoadingEn;
|
std::shared_ptr<Texture> languageLoadingEn;
|
||||||
|
|
||||||
|
|
||||||
|
void refreshFullScreenToggleButton();
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
bool shadowsEnabled = false;
|
||||||
|
#else
|
||||||
bool shadowsEnabled = true;
|
bool shadowsEnabled = true;
|
||||||
|
#endif
|
||||||
std::string lastMusicTrack;
|
std::string lastMusicTrack;
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
@ -189,6 +196,7 @@ namespace FRG {
|
|||||||
void showCreditsScreen();
|
void showCreditsScreen();
|
||||||
void showSettingsScreen();
|
void showSettingsScreen();
|
||||||
void showSettingsGraphicsScreen();
|
void showSettingsGraphicsScreen();
|
||||||
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
void showSettingsNoMusicWebScreen();
|
void showSettingsNoMusicWebScreen();
|
||||||
|
|||||||
@ -798,14 +798,14 @@ namespace FRG {
|
|||||||
else {
|
else {
|
||||||
auto buf = readFileFromZIP(path, zipFile);
|
auto buf = readFileFromZIP(path, zipFile);
|
||||||
if (buf.empty()) {
|
if (buf.empty()) {
|
||||||
std::cerr << "UiManager: failed to read " << path << " from zip " << zipFile << std::endl;
|
logger() << "UiManager: failed to read " << path << " from zip " << zipFile << std::endl;
|
||||||
throw std::runtime_error("Failed to load UI file: " + path);
|
throw std::runtime_error("Failed to load UI file: " + path);
|
||||||
}
|
}
|
||||||
content.assign(buf.begin(), buf.end());
|
content.assign(buf.begin(), buf.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "UiManager: failed to open " << path << " : " << e.what() << std::endl;
|
logger() << "UiManager: failed to open " << path << " : " << e.what() << std::endl;
|
||||||
throw std::runtime_error("Failed to load UI file: " + path);
|
throw std::runtime_error("Failed to load UI file: " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,12 +814,12 @@ namespace FRG {
|
|||||||
j = json::parse(content);
|
j = json::parse(content);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "UiManager: json parse error: " << e.what() << std::endl;
|
logger() << "UiManager: json parse error: " << e.what() << std::endl;
|
||||||
throw std::runtime_error("Failed to load UI file: " + path);
|
throw std::runtime_error("Failed to load UI file: " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!j.contains("root") || !j["root"].is_object()) {
|
if (!j.contains("root") || !j["root"].is_object()) {
|
||||||
std::cerr << "UiManager: root node missing or invalid" << std::endl;
|
logger() << "UiManager: root node missing or invalid" << std::endl;
|
||||||
throw std::runtime_error("Failed to load UI file: " + path);
|
throw std::runtime_error("Failed to load UI file: " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
139
src/main.cpp
139
src/main.cpp
@ -20,15 +20,48 @@
|
|||||||
FRG::Game* g_game = nullptr;
|
FRG::Game* g_game = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
// Read the persisted fullscreen preference (if any) before creating the
|
||||||
|
// window, so it opens directly in the right mode instead of flashing
|
||||||
|
// windowed -> fullscreen once settings are loaded later during setupPart2().
|
||||||
|
|
||||||
|
void readSettings()
|
||||||
|
{
|
||||||
|
|
||||||
|
const std::string settingsContent = FRG::readSavedTextFile("settings.json");
|
||||||
|
if (!settingsContent.empty()) {
|
||||||
|
try {
|
||||||
|
const nlohmann::json settingsRoot = nlohmann::json::parse(settingsContent);
|
||||||
|
if (settingsRoot.contains("fullscreen")) {
|
||||||
|
FRG::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsRoot.contains("isHighDPIEnabled")) {
|
||||||
|
FRG::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsRoot.contains("enableLogging")) {
|
||||||
|
FRG::Environment::enableLogging = settingsRoot["enableLogging"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(EMSCRIPTEN)
|
#if defined(EMSCRIPTEN)
|
||||||
static SDL_GLContext glContext_x;
|
static SDL_GLContext glContext_x;
|
||||||
static bool g_isFsLoaded = false; // Флаг готовности
|
static bool g_isFsLoaded = false; // Флаг готовности
|
||||||
|
|
||||||
|
static bool g_pendingFullscreenResize = false;
|
||||||
|
|
||||||
// Макрос EMSCRIPTEN_KEEPALIVE экспортирует функцию в глобальный объект Module
|
// Макрос EMSCRIPTEN_KEEPALIVE экспортирует функцию в глобальный объект Module
|
||||||
extern "C" void EMSCRIPTEN_KEEPALIVE onFileSystemLoaded() {
|
extern "C" void EMSCRIPTEN_KEEPALIVE onFileSystemLoaded() {
|
||||||
// 1. Файлы загружены. Теперь можно читать настройки и логи
|
// 1. Файлы загружены. Теперь можно читать настройки и логи
|
||||||
// Если функции readSettings() нет для Emscripten, форсируем логгер:
|
// Если функции readSettings() нет для Emscripten, форсируем логгер:
|
||||||
FRG::Environment::enableLogging = true;
|
//FRG::Environment::enableLogging = true;
|
||||||
|
//readSettings();
|
||||||
FRG::initLogger();
|
FRG::initLogger();
|
||||||
|
|
||||||
FRG::logger() << "[boot] File system is ready. Setting up game..." << std::endl;
|
FRG::logger() << "[boot] File system is ready. Setting up game..." << std::endl;
|
||||||
@ -40,26 +73,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE onFileSystemLoaded() {
|
|||||||
// 3. Даем отмашку главному циклу
|
// 3. Даем отмашку главному циклу
|
||||||
g_isFsLoaded = true;
|
g_isFsLoaded = true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void MainLoop() {
|
|
||||||
#if defined(EMSCRIPTEN)
|
|
||||||
// Крутим цикл вхолостую, пока JS читает IndexedDB
|
|
||||||
if (!g_isFsLoaded) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_game->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
|
|
||||||
EM_BOOL onWebGLContextLost(int /*eventType*/, const void* /*reserved*/, void* /*userData*/) {
|
|
||||||
return EM_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
EM_BOOL onWebGLContextRestored(int /*eventType*/, const void* /*reserved*/, void* /*userData*/) {
|
|
||||||
return EM_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void applyResize(int logicalW, int logicalH) {
|
static void applyResize(int logicalW, int logicalH) {
|
||||||
// Получаем коэффициент плотности пикселей (например, 2.625 на Pixel или 3.0 на Samsung)
|
// Получаем коэффициент плотности пикселей (например, 2.625 на Pixel или 3.0 на Samsung)
|
||||||
@ -92,22 +106,59 @@ static void applyResize(int logicalW, int logicalH) {
|
|||||||
<< " (physical: " << physicalW << "x" << physicalH
|
<< " (physical: " << physicalW << "x" << physicalH
|
||||||
<< ", DPR: " << dpr << ")" << std::endl;
|
<< ", DPR: " << dpr << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MainLoop() {
|
||||||
|
#if defined(EMSCRIPTEN)
|
||||||
|
// Крутим цикл вхолостую, пока JS читает IndexedDB
|
||||||
|
if (!g_isFsLoaded) return;
|
||||||
|
|
||||||
|
if (g_pendingFullscreenResize) {
|
||||||
|
g_pendingFullscreenResize = false;
|
||||||
|
|
||||||
|
// Теперь DOM перестроен, можно забирать актуальные размеры.
|
||||||
|
// Если canvas должен занимать все окно браузера:
|
||||||
|
int canvasW = EM_ASM_INT({ return window.innerWidth; });
|
||||||
|
int canvasH = EM_ASM_INT({ return window.innerHeight; });
|
||||||
|
|
||||||
|
applyResize(canvasW, canvasH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_game->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
|
||||||
|
|
||||||
|
EM_BOOL onWebGLContextLost(int /*eventType*/, const void* /*reserved*/, void* /*userData*/) {
|
||||||
|
return EM_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL onWebGLContextRestored(int /*eventType*/, const void* /*reserved*/, void* /*userData*/) {
|
||||||
|
return EM_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EM_BOOL onWindowResized(int /*eventType*/, const EmscriptenUiEvent* e, void* /*userData*/) {
|
EM_BOOL onWindowResized(int /*eventType*/, const EmscriptenUiEvent* e, void* /*userData*/) {
|
||||||
// Use the event's window dimensions — querying the canvas element would
|
double w, h;
|
||||||
// return its old fixed size (e.g. 1280x720) before it has been resized.
|
emscripten_get_element_css_size("window", &w, &h);
|
||||||
applyResize(e->windowInnerWidth, e->windowInnerHeight);
|
|
||||||
|
// Если "window" не поддерживается вашей версией SDK, используем данные из e:
|
||||||
|
// int logicalW = e->windowInnerWidth;
|
||||||
|
// int logicalH = e->windowInnerHeight;
|
||||||
|
|
||||||
|
applyResize(static_cast<int>(w), static_cast<int>(h));
|
||||||
return EM_FALSE;
|
return EM_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EM_BOOL onFullscreenChanged(int /*eventType*/, const EmscriptenFullscreenChangeEvent* e, void* /*userData*/) {
|
EM_BOOL onFullscreenChanged(int /*eventType*/, const EmscriptenFullscreenChangeEvent* e, void* /*userData*/) {
|
||||||
FRG::Environment::isFullscreen = e->isFullscreen;
|
FRG::Environment::isFullscreen = e->isFullscreen;
|
||||||
|
FRG::logger() << "onFullscreenChanged: isFullscreen = " << e->isFullscreen << std::endl;
|
||||||
|
|
||||||
|
// Браузер еще не обновил DOM. Ставим флаг, чтобы применить размеры в следующем кадре.
|
||||||
|
g_pendingFullscreenResize = true;
|
||||||
|
|
||||||
// Вместо window.innerWidth, попробуйте запросить размер целевого элемента
|
|
||||||
// так как после перехода в FS именно он растягивается на весь экран.
|
|
||||||
double clientW, clientH;
|
|
||||||
emscripten_get_element_css_size("#canvas", &clientW, &clientH);
|
|
||||||
applyResize(clientW, clientH);
|
|
||||||
return EM_FALSE;
|
return EM_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +179,7 @@ int main(int argc, char* argv[]) {
|
|||||||
emscripten_set_webglcontextrestored_callback("#canvas", nullptr, EM_TRUE, onWebGLContextRestored);
|
emscripten_set_webglcontextrestored_callback("#canvas", nullptr, EM_TRUE, onWebGLContextRestored);
|
||||||
|
|
||||||
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, EM_FALSE, onWindowResized);
|
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, EM_FALSE, onWindowResized);
|
||||||
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, EM_FALSE, onFullscreenChanged);
|
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, EM_TRUE, onFullscreenChanged);
|
||||||
|
|
||||||
int canvasW = EM_ASM_INT({ return window.innerWidth; });
|
int canvasW = EM_ASM_INT({ return window.innerWidth; });
|
||||||
int canvasH = EM_ASM_INT({ return window.innerHeight; });
|
int canvasH = EM_ASM_INT({ return window.innerHeight; });
|
||||||
@ -289,36 +340,6 @@ int main(int argc, char* argv[]) {
|
|||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__linux__)
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__linux__)
|
||||||
|
|
||||||
// Read the persisted fullscreen preference (if any) before creating the
|
|
||||||
// window, so it opens directly in the right mode instead of flashing
|
|
||||||
// windowed -> fullscreen once settings are loaded later during setupPart2().
|
|
||||||
void readSettings()
|
|
||||||
{
|
|
||||||
|
|
||||||
const std::string settingsContent = FRG::readSavedTextFile("settings.json");
|
|
||||||
if (!settingsContent.empty()) {
|
|
||||||
try {
|
|
||||||
const nlohmann::json settingsRoot = nlohmann::json::parse(settingsContent);
|
|
||||||
if (settingsRoot.contains("fullscreen")) {
|
|
||||||
FRG::Environment::isFullscreen = settingsRoot["fullscreen"].get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingsRoot.contains("isHighDPIEnabled")) {
|
|
||||||
FRG::Environment::isHighDPIEnabled = settingsRoot["isHighDPIEnabled"].get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingsRoot.contains("enableLogging")) {
|
|
||||||
FRG::Environment::enableLogging = settingsRoot["enableLogging"].get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (const std::exception& e) {
|
|
||||||
std::cerr << "[settings] Failed to parse settings.json: " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
SDL_GLContext ctx = nullptr;
|
SDL_GLContext ctx = nullptr;
|
||||||
|
|||||||
@ -509,8 +509,13 @@ namespace FRG
|
|||||||
}
|
}
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
return g_androidStream;
|
return g_androidStream;
|
||||||
|
#else
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
return g_nullStream; //For web, remove all logging to browser console
|
||||||
#else
|
#else
|
||||||
return std::cout;
|
return std::cout;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user