Working on Android version

This commit is contained in:
Vladislav Khorev committed 2026-07-18 13:19:08 +03:00
1 parent 0975f3b9cd
commit e773b51985
19 files changed
+418 -264

No files matched your search

+86 -135
View File
@@ -24,11 +24,16 @@
#include "GameConstants.h"
#ifdef __ANDROID__
extern bool isAppActive;
#endif
namespace FRG
{
static const float zoomMin = 6.0f;
static const float zoomMax = 20.0f;
#ifdef EMSCRIPTEN
const char* CONST_ZIP_FILE = "resources.zip";
#else
@@ -81,8 +86,10 @@ namespace FRG
}
void Game::setup() {
#ifndef __ANDROID__
Environment::width = Environment::CONST_DEFAULT_WIDTH;
Environment::height = Environment::CONST_DEFAULT_HEIGHT;
#endif
Environment::computeProjectionDimensions();
FRG::BindOpenGlFunctions();
@@ -156,7 +163,9 @@ namespace FRG
});
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("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);
@@ -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_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);
/*#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("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);
@@ -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_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("text2d",
"resources/shaders/text2d.vertex",
"resources/shaders/text2d_desktop.fragment",
CONST_ZIP_FILE
);
#endif
});
@@ -1175,6 +1197,23 @@ namespace FRG
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) {
const bool wasPortrait = Environment::width < Environment::height;
@@ -1211,7 +1250,12 @@ namespace FRG
// Suppress all input while portrait overlay is shown
//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.
// 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
@@ -1222,6 +1266,12 @@ namespace FRG
continue;
}
/*
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game",
"Game::update step 3 event type: %d", event.type);
#endif
*/
#ifdef __ANDROID__
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
Environment::exitGameLoop = true;
@@ -1232,6 +1282,12 @@ namespace FRG
// SDL_HINT_TOUCH_MOUSE_EVENTS="0" is set in main.cpp so these do not
// also fire SDL_MOUSEBUTTONDOWN, preventing double-processing.
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 eventY = static_cast<int>(event.tfinger.y * Environment::height);
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
@@ -1249,7 +1305,12 @@ namespace FRG
}
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.
// Right mouse is intentionally unused now — camera rotation is on hold-and-drag.
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
@@ -1304,136 +1365,6 @@ namespace FRG
if (event.type == SDL_KEYDOWN && event.key.repeat == 0) {
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:
break;
}
@@ -1586,21 +1517,41 @@ namespace FRG
const int uiX = mx;
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);
const bool capturedByTopUi = menuManager.topUiManager.isUiInteractionForFinger(fingerId);
const bool dialogueActive = currentLocation() && currentLocation()->dialogueSystem.isActive();
if (!dialogueActive && !capturedByTopUi) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game",
"Game::onPointerDown step 2");
#endif
menuManager.uiManager.onTouchDown(fingerId, uiX, uiY);
}
st.capturedByUi = capturedByTopUi || (!dialogueActive && menuManager.uiManager.isUiInteractionForFinger(fingerId));
activePointers[fingerId] = st;
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game",
"Game::onPointerDown step 3");
#endif
if (st.capturedByUi) {
// UI button / slider / text-field grabbed this press; don't drive
// gameplay or pinch from it.
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game",
"Game::onPointerDown step 4");
#endif
return;
}
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game",
"Game::onPointerDown step 5");
#endif
if (countNonUiPointers() >= 2) {
// Second finger landed on the gameplay area: switch to pinch-zoom