Working on Android version
This commit is contained in:
1 parent
0975f3b9cd
commit
e773b51985
19 files changed
+418
-264
No files matched your search
+108
-29
@@ -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_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);
|
||||
glContext_x = SDL_GL_CreateContext(FRG::Environment::window);
|
||||
|
||||
@@ -149,40 +151,61 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
extern "C" int SDL_main(int argc, char* argv[]) {
|
||||
// Инициализация SDL перед получением информации о дисплее
|
||||
#include <jni.h>
|
||||
#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) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL init failed: %s", SDL_GetError());
|
||||
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_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_RED_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
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(
|
||||
"Shadow Over Bishkek",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
FRG::Environment::width, FRG::Environment::height,
|
||||
0, 0,
|
||||
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
|
||||
);
|
||||
|
||||
@@ -208,32 +231,87 @@ extern "C" int SDL_main(int argc, char* argv[]) {
|
||||
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) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Game", "Unable to set VSync: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Настройка игры
|
||||
try {
|
||||
game.setup();
|
||||
g_game = new FRG::Game();
|
||||
g_game->setup();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
__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;
|
||||
}
|
||||
|
||||
while (!game.shouldExit()) {
|
||||
game.update();
|
||||
SDL_Delay(16);
|
||||
while (!g_game->shouldExit()) {
|
||||
SDL_Event event;
|
||||
// Обрабатываем системные события 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ANDROID__
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__linux__)
|
||||
|
||||
// Read the persisted fullscreen preference (if any) before creating the
|
||||
@@ -417,3 +495,4 @@ int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Reference in new issue
Block a user