summaryrefslogtreecommitdiffhomepage
path: root/src/rcore_android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rcore_android.c')
-rw-r--r--src/rcore_android.c279
1 files changed, 148 insertions, 131 deletions
diff --git a/src/rcore_android.c b/src/rcore_android.c
index 3d9fab06..3e3b8cd1 100644
--- a/src/rcore_android.c
+++ b/src/rcore_android.c
@@ -82,7 +82,8 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static void ClosePlatform(void); // Close platform
static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
@@ -172,88 +173,23 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
#endif
- // NOTE: Keep internal pointer to input title string (no copy)
+ // Initialize window data
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.eventWaiting = false;
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input));
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
- CORE.Window.eventWaiting = false;
-
-
- // Platform specific init window
- //--------------------------------------------------------------
- CORE.Window.screen.width = width;
- CORE.Window.screen.height = height;
- CORE.Window.currentFbo.width = width;
- CORE.Window.currentFbo.height = height;
-
- // Set desired windows flags before initializing anything
- ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
-
- int orientation = AConfiguration_getOrientation(platform.app->config);
-
- if (orientation == ACONFIGURATION_ORIENTATION_PORT) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as portrait");
- else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as landscape");
-
- // TODO: Automatic orientation doesn't seem to work
- if (width <= height)
- {
- AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
- TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
- }
- else
- {
- AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
- TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
- }
-
- //AConfiguration_getDensity(platform.app->config);
- //AConfiguration_getKeyboard(platform.app->config);
- //AConfiguration_getScreenSize(platform.app->config);
- //AConfiguration_getScreenLong(platform.app->config);
-
- // Initialize App command system
- // NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
- platform.app->onAppCmd = AndroidCommandCallback;
-
- // Initialize input events system
- platform.app->onInputEvent = AndroidInputCallback;
-
- // Initialize assets manager
- InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
-
- // Initialize base path for storage
- CORE.Storage.basePath = platform.app->activity->internalDataPath;
-
- // Set some default window flags
- CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
- CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
- CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
- CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
+ CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
- TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
-
- // Android ALooper_pollAll() variables
- int pollResult = 0;
- int pollEvents = 0;
-
- // Wait for window to be initialized (display and context)
- while (!CORE.Window.ready)
- {
- // Process events loop
- while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
- {
- // Process this event
- if (platform.source != NULL) platform.source->process(platform.app, platform.source);
-
- // NOTE: Never close window, native activity is controlled by the system!
- //if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
- }
- }
+ // Initialize platform
+ //--------------------------------------------------------------
+ InitPlatform();
//--------------------------------------------------------------
}
@@ -279,28 +215,9 @@ void CloseWindow(void)
timeEndPeriod(1); // Restore time period
#endif
- // Platform specific close window
- //--------------------------------------------------------------
- // Close surface, context and display
- if (platform.device != EGL_NO_DISPLAY)
- {
- eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- if (platform.surface != EGL_NO_SURFACE)
- {
- eglDestroySurface(platform.device, platform.surface);
- platform.surface = EGL_NO_SURFACE;
- }
-
- if (platform.context != EGL_NO_CONTEXT)
- {
- eglDestroyContext(platform.device, platform.context);
- platform.context = EGL_NO_CONTEXT;
- }
-
- eglTerminate(platform.device);
- platform.device = EGL_NO_DISPLAY;
- }
+ // De-initialize platform
+ //--------------------------------------------------------------
+ ClosePlatform();
//--------------------------------------------------------------
#if defined(SUPPORT_EVENTS_AUTOMATION)
@@ -690,25 +607,108 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
+{
+ CORE.Window.currentFbo.width = CORE.Window.screen.width;
+ CORE.Window.currentFbo.height = CORE.Window.screen.width;
+
+ // Set desired windows flags before initializing anything
+ ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
+
+ int orientation = AConfiguration_getOrientation(platform.app->config);
+
+ if (orientation == ACONFIGURATION_ORIENTATION_PORT) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as portrait");
+ else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as landscape");
+
+ // TODO: Automatic orientation doesn't seem to work
+ if (width <= height)
+ {
+ AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
+ }
+ else
+ {
+ AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
+ }
+
+ //AConfiguration_getDensity(platform.app->config);
+ //AConfiguration_getKeyboard(platform.app->config);
+ //AConfiguration_getScreenSize(platform.app->config);
+ //AConfiguration_getScreenLong(platform.app->config);
+
+ // Initialize App command system
+ // NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
+ platform.app->onAppCmd = AndroidCommandCallback;
+
+ // Initialize input events system
+ platform.app->onInputEvent = AndroidInputCallback;
+
+ // Initialize assets manager
+ InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
+
+ // Initialize base path for storage
+ CORE.Storage.basePath = platform.app->activity->internalDataPath;
+
+ // Set some default window flags
+ CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
+ CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
+ CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
+ CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
+
+ TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
+
+ // Android ALooper_pollAll() variables
+ int pollResult = 0;
+ int pollEvents = 0;
+
+ // Wait for window to be initialized (display and context)
+ while (!CORE.Window.ready)
+ {
+ // Process events loop
+ while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
+ {
+ // Process this event
+ if (platform.source != NULL) platform.source->process(platform.app, platform.source);
+
+ // NOTE: Never close window, native activity is controlled by the system!
+ //if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
+ }
+ }
+}
+
+// Close platform
+static void ClosePlatform(void)
+{
+ // Close surface, context and display
+ if (platform.device != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (platform.surface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(platform.device, platform.surface);
+ platform.surface = EGL_NO_SURFACE;
+ }
+
+ if (platform.context != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(platform.device, platform.context);
+ platform.context = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(platform.device);
+ platform.device = EGL_NO_DISPLAY;
+ }
+}
+
// Initialize display device and framebuffer
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
// If width or height are 0, default display size will be used for framebuffer size
// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+static bool InitGraphicsDevice(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the screen minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
-
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
-
CORE.Window.fullscreen = true;
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
@@ -748,7 +748,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.device == EGL_NO_DISPLAY)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
- return false;
+ return -1;
}
// Initialize the EGL device connection
@@ -756,7 +756,7 @@ static bool InitGraphicsDevice(int width, int height)
{
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
- return false;
+ return -1;
}
// Get an appropriate EGL framebuffer configuration
@@ -770,7 +770,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
- return false;
+ return -1;
}
// Create an EGL window surface
@@ -799,7 +799,7 @@ static bool InitGraphicsDevice(int width, int height)
if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
- return false;
+ return -1;
}
else
{
@@ -819,19 +819,11 @@ static bool InitGraphicsDevice(int width, int height)
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
CORE.Window.ready = true;
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
- return true;
+ return 0;
}
// ANDROID: Process activity lifecycle commands
@@ -874,24 +866,49 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
CORE.Window.display.height = ANativeWindow_getHeight(platform.app->window);
// Initialize graphics device (display device and OpenGL context)
- InitGraphicsDevice(CORE.Window.screen.width, CORE.Window.screen.height);
+ InitGraphicsDevice();
+
+ // Initialize OpenGL context (states and resources)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+
+ // Setup default viewport
+ // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
// Initialize hi-res timer
InitTimer();
- // Initialize random seed
- srand((unsigned int)time(NULL));
-
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
// WARNING: External function: Module required: rtext
LoadFontDefault();
+ #if defined(SUPPORT_MODULE_RSHAPES)
+ // Set font white rectangle for shapes drawing, so shapes and text can be batched together
+ // WARNING: rshapes module is required, if not available, default internal white rectangle is used
Rectangle rec = GetFontDefault().recs[95];
- // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
+ {
+ // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
+ }
+ else
+ {
+ // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
+ }
+ #endif
+ #else
#if defined(SUPPORT_MODULE_RSHAPES)
- SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes
+ // Set default texture and rectangle to be used for shapes drawing
+ // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
+ Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
+ SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
#endif
#endif
+
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
// TODO: GPU assets reload in case of lost focus (lost context)
// NOTE: This problem has been solved just unbinding and rebinding context from display