|
13 | 13 | * - Improvement 01 |
14 | 14 | * - Improvement 02 |
15 | 15 | * |
16 | | -* ADDITIONAL NOTES: |
17 | | -* - TRACELOG() function is located in raylib [utils] module |
18 | | -* |
19 | 16 | * CONFIGURATION: |
20 | 17 | * #define RCORE_PLATFORM_CUSTOM_FLAG |
21 | 18 | * Custom flag for rcore on target platform -not used- |
|
48 | 45 |
|
49 | 46 | #include <android_native_app_glue.h> // Required for: android_app struct and activity management |
50 | 47 | #include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others |
| 48 | +#include <android/log.h> // Required for: Android log system: __android_log_vprint() |
| 49 | +#include <android/asset_manager.h> // Required for: AAssetManager |
51 | 50 | //#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...) |
| 51 | + |
| 52 | +#include <errno.h> // Required for: error types |
52 | 53 | #include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()] |
53 | 54 |
|
54 | 55 | #include <EGL/egl.h> // Native platform windowing system interface |
@@ -269,6 +270,17 @@ static GamepadButton AndroidTranslateGamepadButton(int button); |
269 | 270 |
|
270 | 271 | static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) |
271 | 272 |
|
| 273 | +static int android_read(void *cookie, char *buf, int size); |
| 274 | +static int android_write(void *cookie, const char *buf, int size); |
| 275 | +static fpos_t android_seek(void *cookie, fpos_t offset, int whence); |
| 276 | +static int android_close(void *cookie); |
| 277 | + |
| 278 | +FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only! |
| 279 | +FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int), |
| 280 | + fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *)); |
| 281 | + |
| 282 | +#define fopen(name, mode) android_fopen(name, mode) |
| 283 | + |
272 | 284 | //---------------------------------------------------------------------------------- |
273 | 285 | // Module Functions Declaration |
274 | 286 | //---------------------------------------------------------------------------------- |
@@ -819,8 +831,6 @@ int InitPlatform(void) |
819 | 831 |
|
820 | 832 | // Initialize storage system |
821 | 833 | //---------------------------------------------------------------------------- |
822 | | - InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); // Initialize assets manager |
823 | | - |
824 | 834 | CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage |
825 | 835 | //---------------------------------------------------------------------------- |
826 | 836 |
|
@@ -1514,4 +1524,66 @@ static void SetupFramebuffer(int width, int height) |
1514 | 1524 | } |
1515 | 1525 | } |
1516 | 1526 |
|
| 1527 | +// Replacement for fopen() |
| 1528 | +// REF: https://developer.android.com/ndk/reference/group/asset |
| 1529 | +FILE *android_fopen(const char *fileName, const char *mode) |
| 1530 | +{ |
| 1531 | + FILE *file = NULL; |
| 1532 | + |
| 1533 | + if (mode[0] == 'w') |
| 1534 | + { |
| 1535 | + // NOTE: fopen() is mapped to android_fopen() that only grants read access to |
| 1536 | + // assets directory through AAssetManager but we want to also be able to |
| 1537 | + // write data when required using the standard stdio FILE access functions |
| 1538 | + // REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only |
| 1539 | + #undef fopen |
| 1540 | + file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode); |
| 1541 | + #define fopen(name, mode) android_fopen(name, mode) |
| 1542 | + } |
| 1543 | + else |
| 1544 | + { |
| 1545 | + // NOTE: AAsset provides access to read-only asset |
| 1546 | + AAsset *asset = AAssetManager_open(platform.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN); |
| 1547 | + |
| 1548 | + if (asset != NULL) |
| 1549 | + { |
| 1550 | + // Get pointer to file in the assets |
| 1551 | + file = funopen(asset, android_read, android_write, android_seek, android_close); |
| 1552 | + } |
| 1553 | + else |
| 1554 | + { |
| 1555 | + #undef fopen |
| 1556 | + // Just do a regular open if file is not found in the assets |
| 1557 | + file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode); |
| 1558 | + if (file == NULL) file = fopen(fileName, mode); |
| 1559 | + #define fopen(name, mode) android_fopen(name, mode) |
| 1560 | + } |
| 1561 | + } |
| 1562 | + |
| 1563 | + return file; |
| 1564 | +} |
| 1565 | + |
| 1566 | +static int android_read(void *cookie, char *data, int dataSize) |
| 1567 | +{ |
| 1568 | + return AAsset_read((AAsset *)cookie, data, dataSize); |
| 1569 | +} |
| 1570 | + |
| 1571 | +static int android_write(void *cookie, const char *data, int dataSize) |
| 1572 | +{ |
| 1573 | + TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK"); |
| 1574 | + |
| 1575 | + return EACCES; |
| 1576 | +} |
| 1577 | + |
| 1578 | +static fpos_t android_seek(void *cookie, fpos_t offset, int whence) |
| 1579 | +{ |
| 1580 | + return AAsset_seek((AAsset *)cookie, offset, whence); |
| 1581 | +} |
| 1582 | + |
| 1583 | +static int android_close(void *cookie) |
| 1584 | +{ |
| 1585 | + AAsset_close((AAsset *)cookie); |
| 1586 | + return 0; |
| 1587 | +} |
| 1588 | + |
1517 | 1589 | // EOF |
0 commit comments