Working on Android version
This commit is contained in:
parent
0975f3b9cd
commit
e773b51985
@ -11,10 +11,10 @@ android {
|
|||||||
if (buildAsApplication) {
|
if (buildAsApplication) {
|
||||||
namespace "org.libsdl.app"
|
namespace "org.libsdl.app"
|
||||||
}
|
}
|
||||||
compileSdkVersion 34
|
compileSdkVersion 37
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 19
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 37
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
@ -23,8 +23,8 @@ android {
|
|||||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||||
}*/
|
}*/
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
|
arguments /*"-DANDROID_APP_PLATFORM=android-19",*/ "-DANDROID_STL=c++_static"
|
||||||
cppFlags "-std=c++11 -frtti -fexceptions"
|
cppFlags "-std=c++17 -frtti -fexceptions"
|
||||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ android {
|
|||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
|
|||||||
@ -21,7 +21,7 @@ set(TP_ROOT "${THIRDPARTY_DIR}")
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# --- ZLIB ---
|
# --- ZLIB ---
|
||||||
add_subdirectory("${TP_ROOT}/zlib-1.3.1" zlib-build)
|
#add_subdirectory("${TP_ROOT}/zlib-1.3.2" zlib-build)
|
||||||
|
|
||||||
# --- LIBPNG ---
|
# --- LIBPNG ---
|
||||||
set(PNG_STATIC ON CACHE BOOL "Build static library" FORCE)
|
set(PNG_STATIC ON CACHE BOOL "Build static library" FORCE)
|
||||||
@ -39,6 +39,9 @@ add_subdirectory("${TP_ROOT}/libpng-1.6.51" libpng-build)
|
|||||||
# --- SDL2 ---
|
# --- SDL2 ---
|
||||||
# Android-версия SDL требует специфичных настроек, но add_subdirectory обычно подхватывает их сама
|
# Android-версия SDL требует специфичных настроек, но add_subdirectory обычно подхватывает их сама
|
||||||
add_subdirectory("${TP_ROOT}/SDL-release-2.32.10" sdl-build)
|
add_subdirectory("${TP_ROOT}/SDL-release-2.32.10" sdl-build)
|
||||||
|
#add_subdirectory("${TP_ROOT}/SDL_mixer-release-2.8.0" sdl-mixer-build)
|
||||||
|
|
||||||
|
add_subdirectory("${TP_ROOT}/SDL_ttf-release-2.24.0" sdl-ttf-build)
|
||||||
|
|
||||||
# --- LIBZIP ---
|
# --- LIBZIP ---
|
||||||
# Отключаем поиск системных крипто-библиотек, так как в NDK их может не быть в стандартных путях
|
# Отключаем поиск системных крипто-библиотек, так как в NDK их может не быть в стандартных путях
|
||||||
|
|||||||
@ -33,62 +33,143 @@ endforeach()
|
|||||||
# Создаем кастомную цель, которая будет запускать процесс копирования
|
# Создаем кастомную цель, которая будет запускать процесс копирования
|
||||||
add_custom_target(sync_resources ALL DEPENDS ${RES_OUTPUTS})
|
add_custom_target(sync_resources ALL DEPENDS ${RES_OUTPUTS})
|
||||||
|
|
||||||
|
set(LUA_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/lua-5.4.8")
|
||||||
|
file(GLOB LUA_SOURCES "${LUA_SRC_DIR}/*.c")
|
||||||
|
list(REMOVE_ITEM LUA_SOURCES
|
||||||
|
"${LUA_SRC_DIR}/lua.c"
|
||||||
|
"${LUA_SRC_DIR}/luac.c"
|
||||||
|
"${LUA_SRC_DIR}/onelua.c"
|
||||||
|
)
|
||||||
|
add_library(lua_static STATIC ${LUA_SOURCES})
|
||||||
|
target_include_directories(lua_static PUBLIC "${LUA_SRC_DIR}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_library(main SHARED
|
add_library(main SHARED
|
||||||
SDL_android_main.c
|
SDL_android_main.c
|
||||||
../../../../src/BoneAnimatedModel.cpp
|
|
||||||
../../../../src/Environment.cpp
|
|
||||||
../../../../src/Game.cpp
|
|
||||||
../../../../src/main.cpp
|
../../../../src/main.cpp
|
||||||
../../../../src/Projectile.cpp
|
../../../../src/Game.cpp
|
||||||
../../../../src/SparkEmitter.cpp
|
../../../../src/Game.h
|
||||||
../../../../src/TextModel.cpp
|
../../../../src/Character.cpp
|
||||||
../../../../src/UiManager.cpp
|
../../../../src/Character.h
|
||||||
../../../../src/utils/Perlin.cpp
|
../../../../src/CharacterState.cpp
|
||||||
../../../../src/utils/TaskManager.cpp
|
../../../../src/CharacterState.h
|
||||||
../../../../src/utils/Utils.cpp
|
../../../../src/Environment.cpp
|
||||||
../../../../src/navigation/PathFinder.cpp
|
../../../../src/Environment.h
|
||||||
../../../../src/planet/PlanetData.cpp
|
../../../../src/Localization.cpp
|
||||||
../../../../src/planet/PlanetObject.cpp
|
../../../../src/Localization.h
|
||||||
../../../../src/planet/StoneObject.cpp
|
|
||||||
../../../../src/render/FrameBuffer.cpp
|
|
||||||
../../../../src/render/ShadowMap.cpp
|
|
||||||
../../../../src/render/Renderer.cpp
|
../../../../src/render/Renderer.cpp
|
||||||
|
../../../../src/render/Renderer.h
|
||||||
../../../../src/render/ShaderManager.cpp
|
../../../../src/render/ShaderManager.cpp
|
||||||
|
../../../../src/render/ShaderManager.h
|
||||||
../../../../src/render/TextureManager.cpp
|
../../../../src/render/TextureManager.cpp
|
||||||
|
../../../../src/render/TextureManager.h
|
||||||
|
../../../../src/TextModel.cpp
|
||||||
|
../../../../src/TextModel.h
|
||||||
|
../../../../src/AudioPlayerAsync.cpp
|
||||||
|
../../../../src/AudioPlayerAsync.h
|
||||||
|
../../../../src/BoneAnimatedModelNew.cpp
|
||||||
|
../../../../src/BoneAnimatedModelNew.h
|
||||||
../../../../src/render/OpenGlExtensions.cpp
|
../../../../src/render/OpenGlExtensions.cpp
|
||||||
)
|
../../../../src/render/OpenGlExtensions.h
|
||||||
|
../../../../src/utils/Utils.cpp
|
||||||
# Подключаем заголовки
|
../../../../src/utils/Utils.h
|
||||||
target_include_directories(main PRIVATE
|
../../../../src/SparkEmitter.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../SDL/include
|
../../../../src/SparkEmitter.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../zlib
|
../../../../src/TeleportZone.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libpng
|
../../../../src/TeleportZone.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/eigen-5.0.0
|
../../../../src/utils/TaskManager.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/boost_1_90_0
|
../../../../src/utils/TaskManager.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
|
../../../../src/render/FrameBuffer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libzip
|
../../../../src/render/FrameBuffer.h
|
||||||
)
|
../../../../src/render/ShadowMap.cpp
|
||||||
|
../../../../src/render/ShadowMap.h
|
||||||
# ВАЖНО: Линкуемся с png_static (статика) или png_shared (динамика)
|
../../../../src/UiManager.cpp
|
||||||
# Так как мы установили PNG_STATIC=ON и PNG_SHARED=OFF,
|
../../../../src/UiManager.h
|
||||||
# должна создаться цель png_static
|
../../../../src/render/TextRenderer.h
|
||||||
target_link_libraries(main
|
../../../../src/render/TextRenderer.cpp
|
||||||
png_static # ← ЭТО ПРАВИЛЬНОЕ ИМЯ ЦЕЛИ!
|
../../../../src/MenuManager.h
|
||||||
z
|
../../../../src/MenuManager.cpp
|
||||||
SDL2
|
../../../../src/Location.h
|
||||||
|
../../../../src/Location.cpp
|
||||||
|
../../../../src/LocationState.h
|
||||||
|
../../../../src/LocationState.cpp
|
||||||
|
../../../../src/LocationEditor.h
|
||||||
|
../../../../src/LocationEditor.cpp
|
||||||
|
../../../../src/NpcCar.h
|
||||||
|
../../../../src/NpcCar.cpp
|
||||||
|
../../../../src/GameConstants.h
|
||||||
|
../../../../src/GameConstants.cpp
|
||||||
|
../../../../src/GameState.h
|
||||||
|
../../../../src/GameState.cpp
|
||||||
|
../../../../src/ScriptEngine.h
|
||||||
|
../../../../src/ScriptEngine.cpp
|
||||||
|
../../../../src/navigation/PathFinder.h
|
||||||
|
../../../../src/navigation/PathFinder.cpp
|
||||||
|
../../../../src/items/GameObjectLoader.h
|
||||||
|
../../../../src/items/GameObjectLoader.cpp
|
||||||
|
../../../../src/items/Item.h
|
||||||
|
../../../../src/items/Item.cpp
|
||||||
|
../../../../src/items/ItemRegistry.h
|
||||||
|
../../../../src/items/ItemRegistry.cpp
|
||||||
|
../../../../src/items/InteractiveObject.h
|
||||||
|
../../../../src/items/InteractiveObject.cpp
|
||||||
|
../../../../src/items/InteractiveObjectState.h
|
||||||
|
../../../../src/dialogue/DialogueTypes.h
|
||||||
|
../../../../src/dialogue/DialogueDatabase.h
|
||||||
|
../../../../src/dialogue/DialogueDatabase.cpp
|
||||||
|
../../../../src/dialogue/DialogueRuntime.h
|
||||||
|
../../../../src/dialogue/DialogueRuntime.cpp
|
||||||
|
../../../../src/dialogue/DialogueOverlay.h
|
||||||
|
../../../../src/dialogue/DialogueOverlay.cpp
|
||||||
|
../../../../src/dialogue/DialogueSystem.h
|
||||||
|
../../../../src/dialogue/DialogueSystem.cpp
|
||||||
|
../../../../src/dialogue/TranslationDatabase.h
|
||||||
|
../../../../src/dialogue/TranslationDatabase.cpp
|
||||||
|
../../../../src/quest/QuestTypes.h
|
||||||
|
../../../../src/quest/QuestJournal.h
|
||||||
|
../../../../src/quest/QuestJournal.cpp
|
||||||
|
../../../../src/cutscene/CutsceneTypes.h
|
||||||
|
../../../../src/cutscene/CutsceneDatabase.h
|
||||||
|
../../../../src/cutscene/CutsceneDatabase.cpp
|
||||||
|
../../../../src/cutscene/CutsceneRuntime.h
|
||||||
|
../../../../src/cutscene/CutsceneRuntime.cpp
|
||||||
|
../../../../src/cutscene/CutsceneOverlay.h
|
||||||
|
../../../../src/cutscene/CutsceneOverlay.cpp
|
||||||
|
../../../../src/render/UiQuad.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
find_library(OPENGLES2_LIB GLESv2)
|
|
||||||
|
|
||||||
|
find_library(OPENGLES3_LIB GLESv3)
|
||||||
|
|
||||||
target_link_libraries(main
|
target_link_libraries(main
|
||||||
${OPENGLES2_LIB} # OpenGL ES 2.0/3.0
|
${OPENGLES3_LIB}
|
||||||
|
png_static
|
||||||
|
z
|
||||||
|
SDL2
|
||||||
|
SDL2_ttf
|
||||||
log
|
log
|
||||||
android
|
android
|
||||||
OpenSLES
|
OpenSLES
|
||||||
dl
|
dl
|
||||||
zip
|
zip
|
||||||
|
lua_static
|
||||||
|
#freetype
|
||||||
|
)
|
||||||
|
|
||||||
|
# Подключаем заголовки
|
||||||
|
target_include_directories(main PRIVATE
|
||||||
|
#${CMAKE_CURRENT_SOURCE_DIR}/../SDL/include
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/SDL_ttf-release-2.24.0/external/freetype/include
|
||||||
|
#${CMAKE_CURRENT_SOURCE_DIR}/../zlib
|
||||||
|
#${CMAKE_CURRENT_SOURCE_DIR}/../libpng
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/eigen-5.0.0
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/boost_1_90_0
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../thirdparty/sol2-3.3.0/include
|
||||||
|
#${CMAKE_CURRENT_SOURCE_DIR}/../libzip
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(main sync_resources)
|
add_dependencies(main sync_resources)
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
|
||||||
<!-- OpenGL ES 2.0 -->
|
<!-- OpenGL ES 2.0 -->
|
||||||
<uses-feature android:glEsVersion="0x00020000" />
|
<uses-feature android:glEsVersion="0x00030000" />
|
||||||
|
|
||||||
<!-- Touchscreen support -->
|
<!-- Touchscreen support -->
|
||||||
<uses-feature
|
<uses-feature
|
||||||
@ -68,7 +68,7 @@
|
|||||||
<!-- Example of setting SDL hints from AndroidManifest.xml:
|
<!-- Example of setting SDL hints from AndroidManifest.xml:
|
||||||
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
|
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<activity android:name="SDLActivity"
|
<activity android:name="SDLActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:alwaysRetainTaskState="true"
|
android:alwaysRetainTaskState="true"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ buildscript {
|
|||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
classpath 'com.android.tools.build:gradle:9.3.0'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|||||||
@ -9,6 +9,17 @@
|
|||||||
|
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
android.builtInKotlin=false
|
||||||
|
android.defaults.buildfeatures.resvalues=true
|
||||||
|
android.dependency.useConstraints=true
|
||||||
|
android.enableAppCompileTimeRClass=false
|
||||||
|
android.newDsl=false
|
||||||
|
android.r8.optimizedResourceShrinking=false
|
||||||
|
android.r8.strictFullModeForKeepRules=false
|
||||||
|
android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
|
||||||
|
android.uniquePackageNames=false
|
||||||
|
android.useAndroidX=false
|
||||||
|
android.usesSdkInManifest.disallowed=false
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#Sat Jan 10 10:31:05 MSK 2026
|
#Sat Jan 10 10:31:05 MSK 2026
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@ -22,7 +22,7 @@ AudioPlayerAsync::~AudioPlayerAsync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioPlayerAsync::init() {
|
bool AudioPlayerAsync::init() {
|
||||||
if (initialized) return true;
|
/*if (initialized) return true;
|
||||||
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||||
std::cerr << "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: " << SDL_GetError() << std::endl;
|
std::cerr << "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: " << SDL_GetError() << std::endl;
|
||||||
@ -37,13 +37,13 @@ bool AudioPlayerAsync::init() {
|
|||||||
Mix_AllocateChannels(16);
|
Mix_AllocateChannels(16);
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
FRG::logger() << "AudioPlayerAsync initialized with SDL2_mixer" << std::endl;
|
FRG::logger() << "AudioPlayerAsync initialized with SDL2_mixer" << std::endl;*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::shutdown() {
|
void AudioPlayerAsync::shutdown() {
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
|
/*
|
||||||
if (currentMusic_) {
|
if (currentMusic_) {
|
||||||
Mix_HaltMusic();
|
Mix_HaltMusic();
|
||||||
Mix_FreeMusic(currentMusic_);
|
Mix_FreeMusic(currentMusic_);
|
||||||
@ -61,11 +61,11 @@ void AudioPlayerAsync::shutdown() {
|
|||||||
Mix_CloseAudio();
|
Mix_CloseAudio();
|
||||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
initialized = false;
|
initialized = false;
|
||||||
FRG::logger() << "AudioPlayerAsync shutdown" << std::endl;
|
FRG::logger() << "AudioPlayerAsync shutdown" << std::endl;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, int channel) {
|
void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, int channel) {
|
||||||
if (!initialized) {
|
/*if (!initialized) {
|
||||||
std::cerr << "AudioPlayerAsync not initialized" << std::endl;
|
std::cerr << "AudioPlayerAsync not initialized" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -104,10 +104,11 @@ void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, in
|
|||||||
taskQueue.push(std::move(task));
|
taskQueue.push(std::move(task));
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
|
void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
|
|
||||||
if (filePath == currentTrack)
|
if (filePath == currentTrack)
|
||||||
return;
|
return;
|
||||||
@ -141,10 +142,11 @@ void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
|
|||||||
taskQueue.push(std::move(task));
|
taskQueue.push(std::move(task));
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::stopMusicAsync() {
|
void AudioPlayerAsync::stopMusicAsync() {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
|
|
||||||
currentTrack = "";
|
currentTrack = "";
|
||||||
|
|
||||||
@ -157,10 +159,11 @@ void AudioPlayerAsync::stopMusicAsync() {
|
|||||||
});
|
});
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::pauseMusicAsync() {
|
void AudioPlayerAsync::pauseMusicAsync() {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
Mix_PauseMusic();
|
Mix_PauseMusic();
|
||||||
#else
|
#else
|
||||||
@ -170,10 +173,11 @@ void AudioPlayerAsync::pauseMusicAsync() {
|
|||||||
});
|
});
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::resumeMusicAsync() {
|
void AudioPlayerAsync::resumeMusicAsync() {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
Mix_ResumeMusic();
|
Mix_ResumeMusic();
|
||||||
#else
|
#else
|
||||||
@ -183,9 +187,11 @@ void AudioPlayerAsync::resumeMusicAsync() {
|
|||||||
});
|
});
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::setMusicVolume(int volume) {
|
void AudioPlayerAsync::setMusicVolume(int volume) {
|
||||||
|
/*
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
volume = std::max(0, std::min(128, volume));
|
volume = std::max(0, std::min(128, volume));
|
||||||
musicVolume_ = volume;
|
musicVolume_ = volume;
|
||||||
@ -198,9 +204,11 @@ void AudioPlayerAsync::setMusicVolume(int volume) {
|
|||||||
});
|
});
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::setSoundVolume(int volume) {
|
void AudioPlayerAsync::setSoundVolume(int volume) {
|
||||||
|
/*
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
volume = std::max(0, std::min(128, volume));
|
volume = std::max(0, std::min(128, volume));
|
||||||
soundVolume_ = volume;
|
soundVolume_ = volume;
|
||||||
@ -213,10 +221,11 @@ void AudioPlayerAsync::setSoundVolume(int volume) {
|
|||||||
});
|
});
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::crossFadeMusicAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
void AudioPlayerAsync::crossFadeMusicAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
if (filePath == currentTrack) return;
|
if (filePath == currentTrack) return;
|
||||||
currentTrack = filePath;
|
currentTrack = filePath;
|
||||||
if (!musicEnabled_) return;
|
if (!musicEnabled_) return;
|
||||||
@ -253,10 +262,11 @@ void AudioPlayerAsync::crossFadeMusicAsync(const std::string& filePath, int fade
|
|||||||
taskQueue.push(std::move(task));
|
taskQueue.push(std::move(task));
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::crossFadeMusicFromPositionAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
void AudioPlayerAsync::crossFadeMusicFromPositionAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
||||||
if (!initialized) return;
|
/*if (!initialized) return;
|
||||||
if (filePath == currentTrack) return;
|
if (filePath == currentTrack) return;
|
||||||
currentTrack = filePath;
|
currentTrack = filePath;
|
||||||
if (!musicEnabled_) return;
|
if (!musicEnabled_) return;
|
||||||
@ -296,10 +306,11 @@ void AudioPlayerAsync::crossFadeMusicFromPositionAsync(const std::string& filePa
|
|||||||
taskQueue.push(std::move(task));
|
taskQueue.push(std::move(task));
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::setMusicEnabled(bool enabled) {
|
void AudioPlayerAsync::setMusicEnabled(bool enabled) {
|
||||||
if (musicEnabled_ == enabled) return;
|
/*if (musicEnabled_ == enabled) return;
|
||||||
musicEnabled_ = enabled;
|
musicEnabled_ = enabled;
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
|
|
||||||
@ -319,7 +330,7 @@ void AudioPlayerAsync::setMusicEnabled(bool enabled) {
|
|||||||
currentTrack = ""; // clear so crossFadeMusicAsync doesn't bail early
|
currentTrack = ""; // clear so crossFadeMusicAsync doesn't bail early
|
||||||
crossFadeMusicAsync(track);
|
crossFadeMusicAsync(track);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayerAsync::setSoundEnabled(bool enabled) {
|
void AudioPlayerAsync::setSoundEnabled(bool enabled) {
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if 0
|
||||||
#include <SDL2/SDL_mixer.h>
|
#include <SDL2/SDL_mixer.h>
|
||||||
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -51,17 +53,18 @@ private:
|
|||||||
std::queue<std::function<void()>> taskQueue;
|
std::queue<std::function<void()>> taskQueue;
|
||||||
#endif
|
#endif
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
|
#if 0
|
||||||
std::unordered_map<std::string, Mix_Chunk*> soundCache;
|
std::unordered_map<std::string, Mix_Chunk*> soundCache;
|
||||||
std::mutex soundCacheMutex;
|
std::mutex soundCacheMutex;
|
||||||
|
|
||||||
std::string currentTrack;
|
std::string currentTrack;
|
||||||
Mix_Music* currentMusic_ = nullptr;
|
|
||||||
|
|
||||||
|
Mix_Music* currentMusic_ = nullptr;
|
||||||
|
#endif
|
||||||
int musicVolume_ = 128;
|
int musicVolume_ = 128;
|
||||||
int soundVolume_ = 128;
|
int soundVolume_ = 128;
|
||||||
bool musicEnabled_ = true;
|
bool musicEnabled_ = true;
|
||||||
bool soundEnabled_ = true;
|
bool soundEnabled_ = true;
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -528,12 +528,14 @@ namespace FRG
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
std::ifstream f(fileName, std::ios::binary | std::ios::ate);
|
std::ifstream f(fileName, std::ios::binary | std::ios::ate);
|
||||||
if (!f.is_open()) throw std::runtime_error("Failed to open binary file: " + fileName);
|
if (!f.is_open()) throw std::runtime_error("Failed to open binary file: " + fileName);
|
||||||
std::streamsize fileSize = f.tellg();
|
std::streamsize fileSize = f.tellg();
|
||||||
f.seekg(0);
|
f.seekg(0);
|
||||||
fileData.resize(static_cast<size_t>(fileSize));
|
fileData.resize(static_cast<size_t>(fileSize));
|
||||||
f.read(fileData.data(), fileSize);
|
f.read(fileData.data(), fileSize);*/
|
||||||
|
fileData = readFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ptr = fileData.data();
|
const char* ptr = fileData.data();
|
||||||
|
|||||||
@ -23,7 +23,7 @@ int Environment::height = CONST_DEFAULT_HEIGHT;
|
|||||||
float Environment::zoom = DEFAULT_ZOOM;
|
float Environment::zoom = DEFAULT_ZOOM;
|
||||||
|
|
||||||
|
|
||||||
bool Environment::enableLogging = false;
|
bool Environment::enableLogging = true;
|
||||||
|
|
||||||
SDL_Window* Environment::window = nullptr;
|
SDL_Window* Environment::window = nullptr;
|
||||||
|
|
||||||
|
|||||||
221
src/Game.cpp
221
src/Game.cpp
@ -24,11 +24,16 @@
|
|||||||
|
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
extern bool isAppActive;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace FRG
|
namespace FRG
|
||||||
{
|
{
|
||||||
static const float zoomMin = 6.0f;
|
static const float zoomMin = 6.0f;
|
||||||
static const float zoomMax = 20.0f;
|
static const float zoomMax = 20.0f;
|
||||||
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
const char* CONST_ZIP_FILE = "resources.zip";
|
const char* CONST_ZIP_FILE = "resources.zip";
|
||||||
#else
|
#else
|
||||||
@ -81,8 +86,10 @@ namespace FRG
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Game::setup() {
|
void Game::setup() {
|
||||||
|
#ifndef __ANDROID__
|
||||||
Environment::width = Environment::CONST_DEFAULT_WIDTH;
|
Environment::width = Environment::CONST_DEFAULT_WIDTH;
|
||||||
Environment::height = Environment::CONST_DEFAULT_HEIGHT;
|
Environment::height = Environment::CONST_DEFAULT_HEIGHT;
|
||||||
|
#endif
|
||||||
Environment::computeProjectionDimensions();
|
Environment::computeProjectionDimensions();
|
||||||
|
|
||||||
FRG::BindOpenGlFunctions();
|
FRG::BindOpenGlFunctions();
|
||||||
@ -156,7 +163,9 @@ namespace FRG
|
|||||||
});
|
});
|
||||||
|
|
||||||
loadSteps.push([this]() {
|
loadSteps.push([this]() {
|
||||||
#if defined(EMSCRIPTEN)
|
|
||||||
|
|
||||||
|
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
|
||||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
||||||
@ -181,7 +190,14 @@ namespace FRG
|
|||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning_web.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning_web.vertex", "resources/shaders/night_fog_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow_web.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow_web.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow_web.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow_web.vertex", "resources/shaders/night_fog_shadow_web.fragment", CONST_ZIP_FILE);
|
||||||
/*#elif defined(__linux__)
|
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("text2d",
|
||||||
|
"resources/shaders/text2d.vertex",
|
||||||
|
"resources/shaders/text2d_web.fragment",
|
||||||
|
CONST_ZIP_FILE
|
||||||
|
);
|
||||||
|
|
||||||
|
/*#elif defined(__linux__)
|
||||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE);
|
||||||
@ -233,6 +249,12 @@ namespace FRG
|
|||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning", "resources/shaders/night_fog_skinning.vertex", "resources/shaders/night_fog_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_shadow", "resources/shaders/night_fog_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("night_fog_skinning_shadow", "resources/shaders/night_fog_skinning_shadow.vertex", "resources/shaders/night_fog_shadow_desktop.fragment", CONST_ZIP_FILE);
|
||||||
|
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("text2d",
|
||||||
|
"resources/shaders/text2d.vertex",
|
||||||
|
"resources/shaders/text2d_desktop.fragment",
|
||||||
|
CONST_ZIP_FILE
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1175,6 +1197,23 @@ namespace FRG
|
|||||||
Environment::exitGameLoop = true;
|
Environment::exitGameLoop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
if (event.type == SDL_APP_WILLENTERBACKGROUND) {
|
||||||
|
isAppActive = false;
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "App moving to background, suspending loop");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (event.type == SDL_APP_DIDENTERFOREGROUND) {
|
||||||
|
isAppActive = true;
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "App returned to foreground, resuming loop");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::update step 1 event type: %d", event.type);
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
const bool wasPortrait = Environment::width < Environment::height;
|
const bool wasPortrait = Environment::width < Environment::height;
|
||||||
@ -1211,7 +1250,12 @@ namespace FRG
|
|||||||
|
|
||||||
// Suppress all input while portrait overlay is shown
|
// Suppress all input while portrait overlay is shown
|
||||||
//if (mobileIsPortrait) continue;
|
//if (mobileIsPortrait) continue;
|
||||||
|
/*
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::update step 2 event type: %d", event.type);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
// Ignore pointer input until the initial loading screen has finished.
|
// Ignore pointer input until the initial loading screen has finished.
|
||||||
// Otherwise a click on the loading screen (e.g. at the spot where a
|
// Otherwise a click on the loading screen (e.g. at the spot where a
|
||||||
// main-menu button will later be) gets delivered to the menu UI as
|
// main-menu button will later be) gets delivered to the menu UI as
|
||||||
@ -1222,6 +1266,12 @@ namespace FRG
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::update step 3 event type: %d", event.type);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
|
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
|
||||||
Environment::exitGameLoop = true;
|
Environment::exitGameLoop = true;
|
||||||
@ -1232,6 +1282,12 @@ namespace FRG
|
|||||||
// SDL_HINT_TOUCH_MOUSE_EVENTS="0" is set in main.cpp so these do not
|
// SDL_HINT_TOUCH_MOUSE_EVENTS="0" is set in main.cpp so these do not
|
||||||
// also fire SDL_MOUSEBUTTONDOWN, preventing double-processing.
|
// also fire SDL_MOUSEBUTTONDOWN, preventing double-processing.
|
||||||
if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP || event.type == SDL_FINGERMOTION) {
|
if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP || event.type == SDL_FINGERMOTION) {
|
||||||
|
/*
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::update step 4 event type: %d", event.type);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
int eventX = static_cast<int>(event.tfinger.x * Environment::width);
|
int eventX = static_cast<int>(event.tfinger.x * Environment::width);
|
||||||
int eventY = static_cast<int>(event.tfinger.y * Environment::height);
|
int eventY = static_cast<int>(event.tfinger.y * Environment::height);
|
||||||
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
|
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
|
||||||
@ -1249,7 +1305,12 @@ namespace FRG
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::update step 5 event type: %d", event.type);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
// Mouse-left maps to a single virtual touch with MOUSE_FINGER_ID.
|
// Mouse-left maps to a single virtual touch with MOUSE_FINGER_ID.
|
||||||
// Right mouse is intentionally unused now — camera rotation is on hold-and-drag.
|
// Right mouse is intentionally unused now — camera rotation is on hold-and-drag.
|
||||||
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
|
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
|
||||||
@ -1304,136 +1365,6 @@ namespace FRG
|
|||||||
|
|
||||||
if (event.type == SDL_KEYDOWN && event.key.repeat == 0) {
|
if (event.type == SDL_KEYDOWN && event.key.repeat == 0) {
|
||||||
switch (event.key.keysym.sym) {
|
switch (event.key.keysym.sym) {
|
||||||
/*case SDLK_8:
|
|
||||||
if (editorMode == EditorMode::InteractiveObjects && currentLocation()) {
|
|
||||||
currentLocation()->editor.selectInteractiveObject(8);
|
|
||||||
} else {
|
|
||||||
gameState.isDawn = !gameState.isDawn;
|
|
||||||
if (gameState.isDawn) gameState.isNight = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDLK_9:
|
|
||||||
if (editorMode == EditorMode::InteractiveObjects && currentLocation()) {
|
|
||||||
currentLocation()->editor.selectInteractiveObject(9);
|
|
||||||
} else {
|
|
||||||
startNightTransition();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDLK_0:
|
|
||||||
|
|
||||||
if (editorMode == EditorMode::InteractiveObjects && currentLocation()) {
|
|
||||||
currentLocation()->editor.selectInteractiveObject(event.key.keysym.sym - SDLK_0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
currentLocation()->requestDarklandsTransition();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDLK_1:
|
|
||||||
case SDLK_2:
|
|
||||||
case SDLK_3:
|
|
||||||
case SDLK_4:
|
|
||||||
case SDLK_5:
|
|
||||||
case SDLK_6:
|
|
||||||
case SDLK_7:
|
|
||||||
|
|
||||||
if (editorMode == EditorMode::InteractiveObjects && currentLocation()) {
|
|
||||||
currentLocation()->editor.selectInteractiveObject(event.key.keysym.sym - SDLK_0);
|
|
||||||
} else {
|
|
||||||
currentLocation()->switchNavigation(event.key.keysym.sym - SDLK_0);
|
|
||||||
logger() << "Switched to nav mesh " << (event.key.keysym.sym - SDLK_0) << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDLK_f:
|
|
||||||
currentLocation()->dialogueSystem.startDialogue("phone_night_aiperi001");
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SDLK_e:
|
|
||||||
currentLocation()->dialogueSystem.startCutscene("computer_cutscene001"); //.startDialogue("test_cutscene_pan_dialogue");
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case SDLK_n:
|
|
||||||
if (editorMode == EditorMode::None)
|
|
||||||
editorMode = EditorMode::Navigation;
|
|
||||||
else if (editorMode == EditorMode::Navigation)
|
|
||||||
editorMode = EditorMode::InteractiveObjects;
|
|
||||||
else
|
|
||||||
editorMode = EditorMode::None;
|
|
||||||
if (currentLocation()) {
|
|
||||||
currentLocation()->editorMode = editorMode;
|
|
||||||
if (editorMode == EditorMode::Navigation)
|
|
||||||
currentLocation()->editor.buildNavMeshes();
|
|
||||||
else if (editorMode == EditorMode::InteractiveObjects)
|
|
||||||
currentLocation()->editor.buildInteractiveObjectBoundsMeshes();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const char* modeName = (editorMode == EditorMode::Navigation) ? "Navigation"
|
|
||||||
: (editorMode == EditorMode::InteractiveObjects) ? "InteractiveObjects"
|
|
||||||
: "None";
|
|
||||||
logger() << "[EDITOR] Mode: " << modeName << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_o:
|
|
||||||
x = x + 0.05;
|
|
||||||
logger() << "current x: " << x << std::endl;
|
|
||||||
//y = y + 0.002;
|
|
||||||
//currentLocation->player->hp = 200;
|
|
||||||
//currentLocation->npcs[0]->walkSpeed += 0.01f;
|
|
||||||
//logger() << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_k:
|
|
||||||
x = x - 0.05;
|
|
||||||
logger() << "current x: " << x << std::endl;
|
|
||||||
logger() << "Player pos: " << currentLocation()->player->state.position.transpose() << std::endl;
|
|
||||||
logger() << "Player rotation: " << currentLocation()->player->state.facingAngle*180.0/M_PI << std::endl;
|
|
||||||
//currentLocation->npcs[0]->walkSpeed -= 0.01f;
|
|
||||||
//logger() << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_p:
|
|
||||||
gameState.currentLocationName = "uni_interior";
|
|
||||||
currentLocation()->player->state.position = Eigen::Vector3f(-0.0189243, 0, -13.4314);
|
|
||||||
currentLocation()->player->setTarget(currentLocation()->player->state.position);
|
|
||||||
//logger() << "Switched to location " << ((currentLocation == locations["location1"]) ? "1" : "2") << std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_l:
|
|
||||||
//x = x - 1;
|
|
||||||
//logger() << "current x: " << x << std::endl;
|
|
||||||
logger() << "Azimuth: " << currentLocation()->state.cameraAzimuth << std::endl;
|
|
||||||
logger() << "Inclination: " << currentLocation()->state.cameraInclination << std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_c:
|
|
||||||
logger() << "SLOW-MO activated!" << std::endl;
|
|
||||||
activateSlowMoEffect();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_i:
|
|
||||||
y = y - 1;
|
|
||||||
logger() << "current y: " << y << std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_b:
|
|
||||||
if (editorMode != EditorMode::None && currentLocation()) {
|
|
||||||
currentLocation()->editor.saveAll();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_j:
|
|
||||||
currentLocation()->editor.placeTree();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_v:
|
|
||||||
if (editorMode != EditorMode::None && currentLocation()) {
|
|
||||||
currentLocation()->editor.saveObjects();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDLK_RETURN:*/
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1586,21 +1517,41 @@ namespace FRG
|
|||||||
|
|
||||||
const int uiX = mx;
|
const int uiX = mx;
|
||||||
const int uiY = Environment::projectionHeight - my;
|
const int uiY = Environment::projectionHeight - my;
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::onPointerDown step 1");
|
||||||
|
#endif
|
||||||
menuManager.topUiManager.onTouchDown(fingerId, uiX, uiY);
|
menuManager.topUiManager.onTouchDown(fingerId, uiX, uiY);
|
||||||
const bool capturedByTopUi = menuManager.topUiManager.isUiInteractionForFinger(fingerId);
|
const bool capturedByTopUi = menuManager.topUiManager.isUiInteractionForFinger(fingerId);
|
||||||
const bool dialogueActive = currentLocation() && currentLocation()->dialogueSystem.isActive();
|
const bool dialogueActive = currentLocation() && currentLocation()->dialogueSystem.isActive();
|
||||||
if (!dialogueActive && !capturedByTopUi) {
|
if (!dialogueActive && !capturedByTopUi) {
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::onPointerDown step 2");
|
||||||
|
#endif
|
||||||
menuManager.uiManager.onTouchDown(fingerId, uiX, uiY);
|
menuManager.uiManager.onTouchDown(fingerId, uiX, uiY);
|
||||||
}
|
}
|
||||||
st.capturedByUi = capturedByTopUi || (!dialogueActive && menuManager.uiManager.isUiInteractionForFinger(fingerId));
|
st.capturedByUi = capturedByTopUi || (!dialogueActive && menuManager.uiManager.isUiInteractionForFinger(fingerId));
|
||||||
|
|
||||||
activePointers[fingerId] = st;
|
activePointers[fingerId] = st;
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::onPointerDown step 3");
|
||||||
|
#endif
|
||||||
if (st.capturedByUi) {
|
if (st.capturedByUi) {
|
||||||
// UI button / slider / text-field grabbed this press; don't drive
|
// UI button / slider / text-field grabbed this press; don't drive
|
||||||
// gameplay or pinch from it.
|
// gameplay or pinch from it.
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::onPointerDown step 4");
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game",
|
||||||
|
"Game::onPointerDown step 5");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (countNonUiPointers() >= 2) {
|
if (countNonUiPointers() >= 2) {
|
||||||
// Second finger landed on the gameplay area: switch to pinch-zoom
|
// Second finger landed on the gameplay area: switch to pinch-zoom
|
||||||
|
|||||||
@ -861,7 +861,39 @@ namespace FRG {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
lua.script_file(scriptPath);
|
//lua.script_file(scriptPath);
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
// Читаем файл в строку через SDL_RWops
|
||||||
|
std::string scriptContent = readTextFile(scriptPath);
|
||||||
|
if (scriptContent.empty()) {
|
||||||
|
std::cerr << "[script] Failed to read script file or file is empty: " << scriptPath << "\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Загружаем (компилируем) строку скрипта. Вторым аргументом передаем имя для логов
|
||||||
|
auto loadResult = lua.load(scriptContent, scriptPath);
|
||||||
|
if (!loadResult.valid()) {
|
||||||
|
sol::error err = loadResult;
|
||||||
|
std::cerr << "[script] Lua compile error: " << err.what() << "\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Если компиляция успешна — вызываем функцию для выполнения кода скрипта
|
||||||
|
auto runResult = loadResult();
|
||||||
|
if (!runResult.valid()) {
|
||||||
|
sol::error err = runResult;
|
||||||
|
std::cerr << "[script] Lua runtime error: " << err.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// На остальных платформах оставляем стандартную загрузку из файла
|
||||||
|
auto result = lua.script_file(scriptPath, sol::script_pass_on_error);
|
||||||
|
if (!result.valid()) {
|
||||||
|
sol::error err = result;
|
||||||
|
std::cerr << "[script] Lua load error: " << err.what() << "\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::callNpcInteractCallback(int npcIndex) {
|
void ScriptEngine::callNpcInteractCallback(int npcIndex) {
|
||||||
@ -885,14 +917,14 @@ namespace FRG {
|
|||||||
std::cerr << "[SCRIPT] Lua function 'on_npc_interact' not found!" << std::endl;
|
std::cerr << "[SCRIPT] Lua function 'on_npc_interact' not found!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void ScriptEngine::runScript(const std::string& path) {
|
void ScriptEngine::runScript(const std::string& path) {
|
||||||
auto result = impl->lua.safe_script_file(path, sol::script_pass_on_error);
|
auto result = impl->lua.safe_script_file(path, sol::script_pass_on_error);
|
||||||
if (!result.valid()) {
|
if (!result.valid()) {
|
||||||
sol::error err = result;
|
sol::error err = result;
|
||||||
std::cerr << "[script] Error in " << path << ": " << err.what() << "\n";
|
std::cerr << "[script] Error in " << path << ": " << err.what() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void ScriptEngine::callActivateFunction(const std::string& functionName) {
|
void ScriptEngine::callActivateFunction(const std::string& functionName) {
|
||||||
if (!impl) {
|
if (!impl) {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public:
|
|||||||
void init(Location* game, Inventory* inventory, AudioPlayerAsync* audioPlayer, const std::string& scriptPath);
|
void init(Location* game, Inventory* inventory, AudioPlayerAsync* audioPlayer, const std::string& scriptPath);
|
||||||
|
|
||||||
// Execute a Lua script file. Logs errors to stderr.
|
// Execute a Lua script file. Logs errors to stderr.
|
||||||
void runScript(const std::string& path);
|
//void runScript(const std::string& path);
|
||||||
|
|
||||||
void callItemPickupCallback(const std::string& objectName);
|
void callItemPickupCallback(const std::string& objectName);
|
||||||
|
|
||||||
|
|||||||
137
src/main.cpp
137
src/main.cpp
@ -117,6 +117,8 @@ int main(int argc, char* argv[]) {
|
|||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
|
|
||||||
FRG::Environment::window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
FRG::Environment::window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
glContext_x = SDL_GL_CreateContext(FRG::Environment::window);
|
glContext_x = SDL_GL_CreateContext(FRG::Environment::window);
|
||||||
|
|
||||||
@ -149,40 +151,61 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
|
||||||
extern "C" int SDL_main(int argc, char* argv[]) {
|
#include <jni.h>
|
||||||
// Инициализация SDL перед получением информации о дисплее
|
#include <android/log.h>
|
||||||
|
|
||||||
|
void Android_InitTouchDevices() {
|
||||||
|
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
|
||||||
|
if (!env) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game", "[Android] Failed to get JNIEnv for touch init");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass activityClass = env->FindClass("org/libsdl/app/SDLActivity");
|
||||||
|
if (!activityClass) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game", "[Android] Failed to find SDLActivity class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID initTouchMethod = env->GetStaticMethodID(activityClass, "initTouch", "()V");
|
||||||
|
if (!initTouchMethod) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "Game", "[Android] Failed to find initTouch method");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->CallStaticVoidMethod(activityClass, initTouchMethod);
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "[Android] JNI initTouch() successfully invoked");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Переменная для отслеживания фокуса приложения на Android
|
||||||
|
bool isAppActive = true;
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL init failed: %s", SDL_GetError());
|
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL init failed: %s", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DisplayMode displayMode;
|
|
||||||
if (SDL_GetCurrentDisplayMode(0, &displayMode) != 0) {
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GetCurrentDisplayMode failed: %s", SDL_GetError());
|
|
||||||
SDL_Quit();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
FRG::Environment::width = displayMode.w;
|
|
||||||
FRG::Environment::height = displayMode.h;
|
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_INFO, "Game", "Display resolution: %dx%d",
|
|
||||||
FRG::Environment::width, FRG::Environment::height);
|
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
|
||||||
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||||
|
|
||||||
|
// Передаем 0, 0 — на Android SDL автоматически растянет окно
|
||||||
|
// на весь экран с учетом системной ориентации Активити
|
||||||
FRG::Environment::window = SDL_CreateWindow(
|
FRG::Environment::window = SDL_CreateWindow(
|
||||||
"Shadow Over Bishkek",
|
"Shadow Over Bishkek",
|
||||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
FRG::Environment::width, FRG::Environment::height,
|
0, 0,
|
||||||
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
|
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -208,32 +231,87 @@ extern "C" int SDL_main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Настройка VSync
|
// СТРОГО ТУТ: Запрашиваем у созданного окна реальный размер буфера
|
||||||
|
// Это исключит баг перевернутых координат ширины и высоты
|
||||||
|
int realWidth, realHeight;
|
||||||
|
SDL_GL_GetDrawableSize(FRG::Environment::window, &realWidth, &realHeight);
|
||||||
|
FRG::Environment::width = realWidth;
|
||||||
|
FRG::Environment::height = realHeight;
|
||||||
|
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "Actual Render Resolution: %dx%d",
|
||||||
|
FRG::Environment::width, FRG::Environment::height);
|
||||||
|
|
||||||
|
// Теперь, когда окно гарантированно создано в правильной ориентации,
|
||||||
|
// привязываем тач-устройства на стороне Java
|
||||||
|
Android_InitTouchDevices();
|
||||||
|
|
||||||
|
|
||||||
if (SDL_GL_SetSwapInterval(1) < 0) {
|
if (SDL_GL_SetSwapInterval(1) < 0) {
|
||||||
__android_log_print(ANDROID_LOG_WARN, "Game", "Unable to set VSync: %s", SDL_GetError());
|
__android_log_print(ANDROID_LOG_WARN, "Game", "Unable to set VSync: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Настройка игры
|
|
||||||
try {
|
try {
|
||||||
game.setup();
|
g_game = new FRG::Game();
|
||||||
|
g_game->setup();
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "Game setup failed: %s", e.what());
|
__android_log_print(ANDROID_LOG_ERROR, "Game", "Game setup failed: %s", e.what());
|
||||||
|
if (g_game) {
|
||||||
|
delete g_game;
|
||||||
|
g_game = nullptr;
|
||||||
|
}
|
||||||
|
SDL_GL_DeleteContext(ctx);
|
||||||
|
SDL_DestroyWindow(FRG::Environment::window);
|
||||||
|
SDL_Quit();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!game.shouldExit()) {
|
while (!g_game->shouldExit()) {
|
||||||
game.update();
|
SDL_Event event;
|
||||||
SDL_Delay(16);
|
// Обрабатываем системные события Android до обновления кадра
|
||||||
|
/*while (SDL_PollEvent(&event)) {
|
||||||
|
// Перенаправляем событие в игру, чтобы сработал ваш внутренний цикл (память, ресайз и т.д.)
|
||||||
|
// Примечание: внутри Game::update у вас тоже стоит PollEvent.
|
||||||
|
// Чтобы события не терялись, лучше обрабатывать их в одном месте,
|
||||||
|
// но жизненно важные для ОС флаги перехватываем здесь:
|
||||||
|
if (event.type == SDL_QUIT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сворачивание / Разворачивание приложения в Android
|
||||||
|
if (event.type == SDL_APP_WILLENTERBACKGROUND) {
|
||||||
|
isAppActive = false;
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "App moving to background, suspending loop");
|
||||||
|
}
|
||||||
|
if (event.type == SDL_APP_DIDENTERFOREGROUND) {
|
||||||
|
isAppActive = true;
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "Game", "App returned to foreground, resuming loop");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (isAppActive) {
|
||||||
|
g_game->update();
|
||||||
|
// На Android шаг кадров завязан на VSync (SwapInterval = 1).
|
||||||
|
// SDL_Delay(16) здесь не нужен, он будет вызывать микро-фризы (stuttering).
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Если игра свернута — спим, чтобы не нагружать CPU/GPU
|
||||||
|
SDL_Delay(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete g_game;
|
||||||
|
g_game = nullptr;
|
||||||
|
|
||||||
|
SDL_GL_DeleteContext(ctx);
|
||||||
|
SDL_DestroyWindow(FRG::Environment::window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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
|
// Read the persisted fullscreen preference (if any) before creating the
|
||||||
@ -417,3 +495,4 @@ int main(int argc, char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES3/gl3ext.h>
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
|||||||
@ -87,13 +87,13 @@ namespace FRG {
|
|||||||
GL_TEXTURE_2D, depthTexture, 0);
|
GL_TEXTURE_2D, depthTexture, 0);
|
||||||
|
|
||||||
// No color buffer for this FBO — depth only.
|
// No color buffer for this FBO — depth only.
|
||||||
#ifdef EMSCRIPTEN
|
//#ifdef EMSCRIPTEN
|
||||||
GLenum drawBuffers[] = { GL_NONE };
|
GLenum drawBuffers[] = { GL_NONE };
|
||||||
glDrawBuffers(1, drawBuffers);
|
glDrawBuffers(1, drawBuffers);
|
||||||
#else
|
/*#else
|
||||||
glDrawBuffer(GL_NONE);
|
glDrawBuffer(GL_NONE);
|
||||||
glReadBuffer(GL_NONE);
|
glReadBuffer(GL_NONE);
|
||||||
#endif
|
#endif*/
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#include "render/TextRenderer.h"
|
#include "render/TextRenderer.h"
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
//#include "freetype/freetype.h"
|
||||||
|
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include "render/OpenGlExtensions.h"
|
#include "render/OpenGlExtensions.h"
|
||||||
@ -50,27 +52,6 @@ bool TextRenderer::init(Renderer& renderer, const std::string& ttfPath, int pixe
|
|||||||
|
|
||||||
r = &renderer;
|
r = &renderer;
|
||||||
|
|
||||||
static bool shaderAlreadyAdded = false;
|
|
||||||
|
|
||||||
if (shaderAlreadyAdded == false)
|
|
||||||
{
|
|
||||||
shaderAlreadyAdded = true;
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
r->shaderManager.AddShaderFromFiles(shaderName,
|
|
||||||
"resources/shaders/text2d.vertex",
|
|
||||||
"resources/shaders/text2d_web.fragment",
|
|
||||||
zipfilename
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
r->shaderManager.AddShaderFromFiles(shaderName,
|
|
||||||
"resources/shaders/text2d.vertex",
|
|
||||||
"resources/shaders/text2d_desktop.fragment",
|
|
||||||
zipfilename
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
FRG::CheckGlError(__FILE__, __LINE__);
|
FRG::CheckGlError(__FILE__, __LINE__);
|
||||||
if (!loadGlyphs(ttfPath, pixelSize, zipfilename)) return false;
|
if (!loadGlyphs(ttfPath, pixelSize, zipfilename)) return false;
|
||||||
FRG::CheckGlError(__FILE__, __LINE__);
|
FRG::CheckGlError(__FILE__, __LINE__);
|
||||||
|
|||||||
@ -49,7 +49,7 @@ private:
|
|||||||
|
|
||||||
VertexRenderStruct textMesh;
|
VertexRenderStruct textMesh;
|
||||||
|
|
||||||
std::string shaderName = "text2d";
|
const std::string shaderName = "text2d";
|
||||||
|
|
||||||
// caching for static texts
|
// caching for static texts
|
||||||
struct CachedText {
|
struct CachedText {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user