diff options
Diffstat (limited to 'tests/projects/android')
32 files changed, 809 insertions, 0 deletions
diff --git a/tests/projects/android/native_app/lvgl_basic/android/AndroidManifest.xml b/tests/projects/android/native_app/lvgl_basic/android/AndroidManifest.xml new file mode 100644 index 000000000..98c3d3795 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.lvgl.basic" + + android:versionCode="15" + android:versionName="1.5"> + + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> + + <uses-permission android:name="android.permission.SET_RELEASE_APP"/> + + <application + android:label="LvglBasic" android:debuggable="true" android:hasCode="false" + tools:replace="android:icon,android:theme,android:allowBackup,label" + android:icon="@mipmap/icon"> + + <activity android:name="android.app.NativeActivity" + android:label="LvglBasic" + android:configChanges="orientation|keyboardHidden|screenSize|screenLayout" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> + <meta-data android:name="android.app.lib_name" + android:value="main" /> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_basic/android/debug.jks b/tests/projects/android/native_app/lvgl_basic/android/debug.jks Binary files differnew file mode 100644 index 000000000..0a18aa012 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/debug.jks diff --git a/tests/projects/android/native_app/lvgl_basic/android/res/mipmap-mdpi/icon.png b/tests/projects/android/native_app/lvgl_basic/android/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/res/mipmap-mdpi/icon.png diff --git a/tests/projects/android/native_app/lvgl_basic/android/res/mipmap/icon.png b/tests/projects/android/native_app/lvgl_basic/android/res/mipmap/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/res/mipmap/icon.png diff --git a/tests/projects/android/native_app/lvgl_basic/android/res/values/strings.xml b/tests/projects/android/native_app/lvgl_basic/android/res/values/strings.xml new file mode 100644 index 000000000..7dc865540 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Lvgl Basic</string> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_basic/android/res/values/styles.xml b/tests/projects/android/native_app/lvgl_basic/android/res/values/styles.xml new file mode 100644 index 000000000..621547380 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/android/res/values/styles.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen"> + <item name="android:windowBackground">@android:color/black</item> + <item name="android:colorPrimary">#FF6200EE</item> + <item name="android:colorPrimaryDark">#FF3700B3</item> + <item name="android:colorAccent">#FF03DAC5</item> + </style> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_basic/src/main.c b/tests/projects/android/native_app/lvgl_basic/src/main.c new file mode 100644 index 000000000..f07036e9b --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/src/main.c @@ -0,0 +1,169 @@ +#include <lvgl/lvgl.h> +#include <android/native_window.h> +#include <android/log.h> +#include <android_native_app_glue.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> + +#define LOG_TAG "lvgl_basic" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) + +static lv_display_t * display = NULL; +static lv_indev_t * indev = NULL; +static void * disp_buf = NULL; +static ANativeWindow * native_window = NULL; +static int32_t window_width = 0; +static int32_t window_height = 0; +static lv_obj_t * label_fps = NULL; + +static bool touch_down = false; +static int32_t touch_x = 0; +static int32_t touch_y = 0; + +static void my_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { + if (!native_window) { + lv_display_flush_ready(disp); + return; + } + + ANativeWindow_Buffer buffer; + if (ANativeWindow_lock(native_window, &buffer, NULL) < 0) { + lv_display_flush_ready(disp); + return; + } + + int32_t width = lv_area_get_width(area); + int32_t height = lv_area_get_height(area); + + // Assume 32-bit RGBA + uint32_t * dst_base = (uint32_t *)buffer.bits; + uint32_t * src = (uint32_t *)px_map; + int stride = buffer.stride; + + for (int y = 0; y < height; y++) { + uint32_t * dst_line = dst_base + (area->y1 + y) * stride + area->x1; + memcpy(dst_line, src + y * width, width * sizeof(uint32_t)); + } + + ANativeWindow_unlockAndPost(native_window); + lv_display_flush_ready(disp); +} + +static void my_input_read(lv_indev_t * indev, lv_indev_data_t * data) { + data->point.x = touch_x; + data->point.y = touch_y; + data->state = touch_down ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; +} + +static void create_ui(void) { + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "Hello Xmake + LVGL!"); + lv_obj_set_style_text_font(label, &lv_font_montserrat_14, 0); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 50); + + // FPS label + label_fps = lv_label_create(lv_screen_active()); + lv_label_set_text(label_fps, "FPS: 0"); + lv_obj_set_style_text_font(label_fps, &lv_font_montserrat_14, 0); + lv_obj_align(label_fps, LV_ALIGN_TOP_MID, 0, 100); +} + +static void handle_cmd(struct android_app* app, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: + LOGI("Init Window"); + native_window = app->window; + window_width = ANativeWindow_getWidth(native_window); + window_height = ANativeWindow_getHeight(native_window); + ANativeWindow_setBuffersGeometry(native_window, window_width, window_height, WINDOW_FORMAT_RGBA_8888); + + if (!display) { + display = lv_display_create(window_width, window_height); + lv_display_set_color_format(display, LV_COLOR_FORMAT_ARGB8888); + lv_display_set_flush_cb(display, my_flush_cb); + + size_t buf_size = window_width * window_height * 4; + disp_buf = malloc(buf_size); + lv_display_set_buffers(display, disp_buf, NULL, buf_size, LV_DISPLAY_RENDER_MODE_FULL); + + indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, my_input_read); + + create_ui(); + } else { + lv_display_set_resolution(display, window_width, window_height); + lv_obj_invalidate(lv_scr_act()); + } + break; + case APP_CMD_TERM_WINDOW: + native_window = NULL; + break; + case APP_CMD_DESTROY: + if (display) { + lv_display_delete(display); + display = NULL; + } + if (indev) { + lv_indev_delete(indev); + indev = NULL; + } + if (disp_buf) { + free(disp_buf); + disp_buf = NULL; + } + break; + } +} + +static int32_t handle_input(struct android_app* app, AInputEvent* event) { + if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { + int action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK; + touch_x = AMotionEvent_getX(event, 0); + touch_y = AMotionEvent_getY(event, 0); + if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_MOVE) { + touch_down = true; + } else { + touch_down = false; + } + return 1; + } + return 0; +} + +void android_main(struct android_app* app) { + lv_init(); + + app->onAppCmd = handle_cmd; + app->onInputEvent = handle_input; + + int frame_count = 0; + time_t last_time = time(NULL); + + while (1) { + int ident; + int events; + struct android_poll_source* source; + + uint32_t timeout = lv_timer_handler(); + if (timeout > 50) timeout = 50; + + while ((ident = ALooper_pollAll(timeout, NULL, &events, (void**)&source)) >= 0) { + if (source != NULL) source->process(app, source); + if (app->destroyRequested != 0) return; + } + + lv_tick_inc(timeout); + + frame_count++; + time_t current_time = time(NULL); + if (current_time - last_time >= 1) { + if (label_fps) { + lv_label_set_text_fmt(label_fps, "FPS: %d", frame_count); + } + frame_count = 0; + last_time = current_time; + } + } +} diff --git a/tests/projects/android/native_app/lvgl_basic/xmake.lua b/tests/projects/android/native_app/lvgl_basic/xmake.lua new file mode 100644 index 000000000..659d04f45 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_basic/xmake.lua @@ -0,0 +1,23 @@ +add_rules("mode.debug", "mode.release") + +add_requires("lvgl 9.1.0") + +target("lvgl_basic") + set_kind("binary") + set_languages("c99") + add_files("src/main.c") + add_syslinks("log", "android", "EGL", "GLESv2") + add_packages("lvgl") + + -- define LV_CONF_INCLUDE_SIMPLE to include lv_conf.h + add_defines("LV_CONF_INCLUDE_SIMPLE") + + add_rules("android.native_app", { + android_sdk_version = "35", + android_manifest = "android/AndroidManifest.xml", + android_res = "android/res", + keystore = "android/debug.jks", + keystore_pass = "123456", + package_name = "com.lvgl.basic", + logcat_filters = {"lvgl_basic", "lvgl"} + }) diff --git a/tests/projects/android/native_app/lvgl_particles/android/AndroidManifest.xml b/tests/projects/android/native_app/lvgl_particles/android/AndroidManifest.xml new file mode 100644 index 000000000..16d614e95 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.lvgl.particles" + + android:versionCode="15" + android:versionName="1.5"> + + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> + + <uses-permission android:name="android.permission.SET_RELEASE_APP"/> + + <application + android:label="LvglParticles" android:debuggable="true" android:hasCode="false" + tools:replace="android:icon,android:theme,android:allowBackup,label" + android:icon="@mipmap/icon"> + + <activity android:name="android.app.NativeActivity" + android:label="LvglParticles" + android:configChanges="orientation|keyboardHidden|screenSize|screenLayout" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> + <meta-data android:name="android.app.lib_name" + android:value="main" /> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_particles/android/debug.jks b/tests/projects/android/native_app/lvgl_particles/android/debug.jks Binary files differnew file mode 100644 index 000000000..0a18aa012 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/debug.jks diff --git a/tests/projects/android/native_app/lvgl_particles/android/res/mipmap-mdpi/icon.png b/tests/projects/android/native_app/lvgl_particles/android/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/res/mipmap-mdpi/icon.png diff --git a/tests/projects/android/native_app/lvgl_particles/android/res/mipmap/icon.png b/tests/projects/android/native_app/lvgl_particles/android/res/mipmap/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/res/mipmap/icon.png diff --git a/tests/projects/android/native_app/lvgl_particles/android/res/values/strings.xml b/tests/projects/android/native_app/lvgl_particles/android/res/values/strings.xml new file mode 100644 index 000000000..0c86996ef --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Lvgl Particles</string> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_particles/android/res/values/styles.xml b/tests/projects/android/native_app/lvgl_particles/android/res/values/styles.xml new file mode 100644 index 000000000..621547380 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/android/res/values/styles.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen"> + <item name="android:windowBackground">@android:color/black</item> + <item name="android:colorPrimary">#FF6200EE</item> + <item name="android:colorPrimaryDark">#FF3700B3</item> + <item name="android:colorAccent">#FF03DAC5</item> + </style> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/lvgl_particles/src/main.c b/tests/projects/android/native_app/lvgl_particles/src/main.c new file mode 100644 index 000000000..1db849fc1 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/src/main.c @@ -0,0 +1,261 @@ +#include <lvgl/lvgl.h> +#include <android/native_window.h> +#include <android/log.h> +#include <android_native_app_glue.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> + +#define LOG_TAG "lvgl_particles" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) + +static lv_display_t * display = NULL; +static lv_indev_t * indev = NULL; +static void * disp_buf = NULL; +static ANativeWindow * native_window = NULL; +static int32_t window_width = 0; +static int32_t window_height = 0; +static lv_obj_t * label_fps = NULL; + +static bool touch_down = false; +static int32_t touch_x = 0; +static int32_t touch_y = 0; + +static void my_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { + if (!native_window) { + lv_display_flush_ready(disp); + return; + } + + ANativeWindow_Buffer buffer; + if (ANativeWindow_lock(native_window, &buffer, NULL) < 0) { + lv_display_flush_ready(disp); + return; + } + + int32_t width = lv_area_get_width(area); + int32_t height = lv_area_get_height(area); + + // Assume 32-bit RGBA + uint32_t * dst_base = (uint32_t *)buffer.bits; + uint32_t * src = (uint32_t *)px_map; + int stride = buffer.stride; + + for (int y = 0; y < height; y++) { + uint32_t * dst_line = dst_base + (area->y1 + y) * stride + area->x1; + memcpy(dst_line, src + y * width, width * sizeof(uint32_t)); + } + + ANativeWindow_unlockAndPost(native_window); + lv_display_flush_ready(disp); +} + +static void my_input_read(lv_indev_t * indev, lv_indev_data_t * data) { + data->point.x = touch_x; + data->point.y = touch_y; + data->state = touch_down ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; +} + +#include <math.h> + +typedef struct { + int32_t x; + int32_t y; + int32_t vx; + int32_t vy; + lv_color_t color; + int32_t size; + int32_t life; +} Particle; + +#define MAX_PARTICLES 100 +static Particle particles[MAX_PARTICLES]; +static int particle_count = 0; + +static void create_particle(int32_t x, int32_t y) { + if (particle_count < MAX_PARTICLES) { + Particle *p = &particles[particle_count++]; + p->x = x; + p->y = y; + p->vx = (rand() % 10) - 5; + p->vy = (rand() % 10) - 5; + p->color = lv_color_make(rand() % 255, rand() % 255, rand() % 255); + p->size = (rand() % 15) + 5; + p->life = 100; + } +} + +static void update_particles(void) { + for (int i = 0; i < particle_count; i++) { + Particle *p = &particles[i]; + p->x += p->vx; + p->y += p->vy; + p->life--; + + if (p->life <= 0 || p->x < 0 || p->x > window_width || p->y < 0 || p->y > window_height) { + *p = particles[--particle_count]; + i--; + } + } +} + +static void draw_particles(lv_layer_t * layer) { + lv_draw_rect_dsc_t draw_dsc; + lv_draw_rect_dsc_init(&draw_dsc); + draw_dsc.radius = LV_RADIUS_CIRCLE; + + for (int i = 0; i < particle_count; i++) { + Particle *p = &particles[i]; + draw_dsc.bg_color = p->color; + draw_dsc.bg_opa = (p->life * 255) / 100; + + lv_area_t area; + area.x1 = p->x - p->size / 2; + area.y1 = p->y - p->size / 2; + area.x2 = area.x1 + p->size; + area.y2 = area.y1 + p->size; + + lv_draw_rect(layer, &draw_dsc, &area); + } +} + +static void particle_timer_cb(lv_timer_t * timer) { + if (touch_down) { + for (int i = 0; i < 5; i++) { + create_particle(touch_x, touch_y); + } + } else { + // Auto emit + static float t = 0; + t += 0.1f; + int cx = window_width / 2 + cos(t) * (window_width / 4); + int cy = window_height / 2 + sin(t) * (window_height / 4); + create_particle(cx, cy); + } + + update_particles(); + lv_obj_invalidate(lv_scr_act()); // Force redraw +} + +static void canvas_draw_event_cb(lv_event_t * e) { + lv_layer_t * layer = lv_event_get_layer(e); + draw_particles(layer); +} + +static void create_ui(void) { + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "Touch to create particles!"); + lv_obj_set_style_text_font(label, &lv_font_montserrat_14, 0); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 50); + + // FPS label + label_fps = lv_label_create(lv_screen_active()); + lv_label_set_text(label_fps, "FPS: 0"); + lv_obj_set_style_text_font(label_fps, &lv_font_montserrat_14, 0); + lv_obj_align(label_fps, LV_ALIGN_TOP_MID, 0, 100); + + // Add draw event to screen for particles + lv_obj_add_event_cb(lv_screen_active(), canvas_draw_event_cb, LV_EVENT_DRAW_POST, NULL); + + lv_timer_create(particle_timer_cb, 16, NULL); +} + +static void handle_cmd(struct android_app* app, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: + LOGI("Init Window"); + native_window = app->window; + window_width = ANativeWindow_getWidth(native_window); + window_height = ANativeWindow_getHeight(native_window); + ANativeWindow_setBuffersGeometry(native_window, window_width, window_height, WINDOW_FORMAT_RGBA_8888); + + if (!display) { + display = lv_display_create(window_width, window_height); + lv_display_set_color_format(display, LV_COLOR_FORMAT_ARGB8888); + lv_display_set_flush_cb(display, my_flush_cb); + + size_t buf_size = window_width * window_height * 4; + disp_buf = malloc(buf_size); + lv_display_set_buffers(display, disp_buf, NULL, buf_size, LV_DISPLAY_RENDER_MODE_FULL); + + indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, my_input_read); + + create_ui(); + } else { + lv_display_set_resolution(display, window_width, window_height); + lv_obj_invalidate(lv_scr_act()); + } + break; + case APP_CMD_TERM_WINDOW: + native_window = NULL; + break; + case APP_CMD_DESTROY: + if (display) { + lv_display_delete(display); + display = NULL; + } + if (indev) { + lv_indev_delete(indev); + indev = NULL; + } + if (disp_buf) { + free(disp_buf); + disp_buf = NULL; + } + break; + } +} + +static int32_t handle_input(struct android_app* app, AInputEvent* event) { + if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { + int action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK; + touch_x = AMotionEvent_getX(event, 0); + touch_y = AMotionEvent_getY(event, 0); + if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_MOVE) { + touch_down = true; + } else { + touch_down = false; + } + return 1; + } + return 0; +} + +void android_main(struct android_app* app) { + srand(time(NULL)); + lv_init(); + + app->onAppCmd = handle_cmd; + app->onInputEvent = handle_input; + + int frame_count = 0; + time_t last_time = time(NULL); + + while (1) { + int ident; + int events; + struct android_poll_source* source; + + uint32_t timeout = lv_timer_handler(); + if (timeout > 50) timeout = 50; + + while ((ident = ALooper_pollAll(timeout, NULL, &events, (void**)&source)) >= 0) { + if (source != NULL) source->process(app, source); + if (app->destroyRequested != 0) return; + } + + lv_tick_inc(timeout); + + frame_count++; + time_t current_time = time(NULL); + if (current_time - last_time >= 1) { + if (label_fps) { + lv_label_set_text_fmt(label_fps, "FPS: %d", frame_count); + } + frame_count = 0; + last_time = current_time; + } + } +} diff --git a/tests/projects/android/native_app/lvgl_particles/xmake.lua b/tests/projects/android/native_app/lvgl_particles/xmake.lua new file mode 100644 index 000000000..3a74e8439 --- /dev/null +++ b/tests/projects/android/native_app/lvgl_particles/xmake.lua @@ -0,0 +1,23 @@ +add_rules("mode.debug", "mode.release") + +add_requires("lvgl 9.1.0") + +target("lvgl_particles") + set_kind("binary") + set_languages("c99") + add_files("src/main.c") + add_syslinks("log", "android", "EGL", "GLESv2") + add_packages("lvgl") + + -- define LV_CONF_INCLUDE_SIMPLE to include lv_conf.h + add_defines("LV_CONF_INCLUDE_SIMPLE") + + add_rules("android.native_app", { + android_sdk_version = "35", + android_manifest = "android/AndroidManifest.xml", + android_res = "android/res", + keystore = "android/debug.jks", + keystore_pass = "123456", + package_name = "com.lvgl.particles", + logcat_filters = {"lvgl_particles", "lvgl"} + }) diff --git a/tests/projects/android/native_app/raylib_basic/android/AndroidManifest.xml b/tests/projects/android/native_app/raylib_basic/android/AndroidManifest.xml new file mode 100644 index 000000000..2d6b2d67c --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.raylib.basic" + + android:versionCode="15" + android:versionName="1.5"> + + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> + + <uses-permission android:name="android.permission.SET_RELEASE_APP"/> + + <application + android:label="RaylibBasic" android:debuggable="true" android:hasCode="false" + tools:replace="android:icon,android:theme,android:allowBackup,label" + android:icon="@mipmap/icon"> + + <activity android:name="android.app.NativeActivity" + android:label="RaylibBasic" + android:configChanges="orientation|keyboardHidden|screenSize|screenLayout" + android:screenOrientation="portrait" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> + <meta-data android:name="android.app.lib_name" + android:value="main" /> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_basic/android/debug.jks b/tests/projects/android/native_app/raylib_basic/android/debug.jks Binary files differnew file mode 100644 index 000000000..0a18aa012 --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/debug.jks diff --git a/tests/projects/android/native_app/raylib_basic/android/res/mipmap-mdpi/icon.png b/tests/projects/android/native_app/raylib_basic/android/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/res/mipmap-mdpi/icon.png diff --git a/tests/projects/android/native_app/raylib_basic/android/res/mipmap/icon.png b/tests/projects/android/native_app/raylib_basic/android/res/mipmap/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/res/mipmap/icon.png diff --git a/tests/projects/android/native_app/raylib_basic/android/res/values/strings.xml b/tests/projects/android/native_app/raylib_basic/android/res/values/strings.xml new file mode 100644 index 000000000..bc0a9bfbf --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Raylib Basic</string> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_basic/android/res/values/styles.xml b/tests/projects/android/native_app/raylib_basic/android/res/values/styles.xml new file mode 100644 index 000000000..621547380 --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/android/res/values/styles.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen"> + <item name="android:windowBackground">@android:color/black</item> + <item name="android:colorPrimary">#FF6200EE</item> + <item name="android:colorPrimaryDark">#FF3700B3</item> + <item name="android:colorAccent">#FF03DAC5</item> + </style> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_basic/src/main.cpp b/tests/projects/android/native_app/raylib_basic/src/main.cpp new file mode 100644 index 000000000..0094d9e3c --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/src/main.cpp @@ -0,0 +1,32 @@ +#include <raylib.h> +#include <android/log.h> + +#define LOG_TAG "raydemo_basic" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) + +int main(int argc, char** argv) { + InitWindow(0, 0, "Hello, xmake for raylib android!"); + SetTargetFPS(60); + LOGI("raylib application is running!"); + + while (!WindowShouldClose()) { + BeginDrawing(); + ClearBackground(BLACK); + + // Draw FPS + const char* fpsText = TextFormat("%2i FPS", GetFPS()); + int fpsWidth = MeasureText(fpsText, 40); + DrawText(fpsText, GetScreenWidth() / 2 - fpsWidth / 2, 30, 40, GREEN); + + // Draw centered text + int fontSize = 50; + const char* text = "Hello, xmake for raylib android!"; + int textWidth = MeasureText(text, fontSize); + DrawText(text, GetScreenWidth() / 2 - textWidth / 2, 100, fontSize, BLUE); + + EndDrawing(); + } + + CloseWindow(); + return 0; +} diff --git a/tests/projects/android/native_app/raylib_basic/xmake.lua b/tests/projects/android/native_app/raylib_basic/xmake.lua new file mode 100644 index 000000000..50886764d --- /dev/null +++ b/tests/projects/android/native_app/raylib_basic/xmake.lua @@ -0,0 +1,19 @@ +add_rules("mode.debug", "mode.release") + +add_requires("raylib 5.5.0") + +target("raydemo_basic") + set_kind("binary") + set_languages("c++17") + add_files("src/main.cpp") + add_syslinks("log") + add_packages("raylib") + add_rules("android.native_app", { + android_sdk_version = "35", + android_manifest = "android/AndroidManifest.xml", + android_res = "android/res", + keystore = "android/debug.jks", + keystore_pass = "123456", + package_name = "com.raylib.basic", + logcat_filters = {"raydemo_basic", "raylib"} + }) diff --git a/tests/projects/android/native_app/raylib_particles/android/AndroidManifest.xml b/tests/projects/android/native_app/raylib_particles/android/AndroidManifest.xml new file mode 100644 index 000000000..70dd36933 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.raylib.particles" + + android:versionCode="15" + android:versionName="1.5"> + + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> + + <uses-permission android:name="android.permission.SET_RELEASE_APP"/> + + <application + android:label="RaylibParticles" android:debuggable="true" android:hasCode="false" + tools:replace="android:icon,android:theme,android:allowBackup,label" + android:icon="@mipmap/icon"> + + <activity android:name="android.app.NativeActivity" + android:label="RaylibParticles" + android:configChanges="orientation|keyboardHidden|screenSize|screenLayout" + android:screenOrientation="portrait" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> + <meta-data android:name="android.app.lib_name" + android:value="main" /> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_particles/android/debug.jks b/tests/projects/android/native_app/raylib_particles/android/debug.jks Binary files differnew file mode 100644 index 000000000..0a18aa012 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/debug.jks diff --git a/tests/projects/android/native_app/raylib_particles/android/res/mipmap-mdpi/icon.png b/tests/projects/android/native_app/raylib_particles/android/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/res/mipmap-mdpi/icon.png diff --git a/tests/projects/android/native_app/raylib_particles/android/res/mipmap/icon.png b/tests/projects/android/native_app/raylib_particles/android/res/mipmap/icon.png Binary files differnew file mode 100644 index 000000000..743413831 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/res/mipmap/icon.png diff --git a/tests/projects/android/native_app/raylib_particles/android/res/values/strings.xml b/tests/projects/android/native_app/raylib_particles/android/res/values/strings.xml new file mode 100644 index 000000000..3967cc312 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Raylib Particles</string> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_particles/android/res/values/styles.xml b/tests/projects/android/native_app/raylib_particles/android/res/values/styles.xml new file mode 100644 index 000000000..621547380 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/android/res/values/styles.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen"> + <item name="android:windowBackground">@android:color/black</item> + <item name="android:colorPrimary">#FF6200EE</item> + <item name="android:colorPrimaryDark">#FF3700B3</item> + <item name="android:colorAccent">#FF03DAC5</item> + </style> +</resources>
\ No newline at end of file diff --git a/tests/projects/android/native_app/raylib_particles/src/main.cpp b/tests/projects/android/native_app/raylib_particles/src/main.cpp new file mode 100644 index 000000000..5bbfc90e8 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/src/main.cpp @@ -0,0 +1,89 @@ +#include <raylib.h> +#include <android/log.h> +#include <vector> +#include <cmath> + +#define LOG_TAG "raydemo_particles" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) + +struct Particle { + Vector2 position; + Vector2 velocity; + Color color; + float size; + float life; +}; + +int main(int argc, char** argv) { + InitWindow(0, 0, "Raylib Particles"); + SetTargetFPS(60); + LOGD("raylib particles starting!"); + + std::vector<Particle> particles; + + while (!WindowShouldClose()) { + // Update + bool inputActive = IsMouseButtonDown(MOUSE_BUTTON_LEFT) || GetTouchPointCount() > 0; + Vector2 pos; + + if (inputActive) { + pos = GetMousePosition(); + if (GetTouchPointCount() > 0) pos = GetTouchPosition(0); + } else { + // Auto emit when idle + double time = GetTime(); + pos.x = GetScreenWidth() / 2.0f + cos(time * 3.0f) * (GetScreenWidth() / 4.0f); + pos.y = GetScreenHeight() / 2.0f + sin(time * 2.0f) * (GetScreenHeight() / 4.0f); + } + + if (inputActive || GetRandomValue(0, 100) < 50) { + int count = inputActive ? 5 : 2; + for (int i = 0; i < count; i++) { + Particle p; + p.position = pos; + p.velocity = {(float)GetRandomValue(-200, 200) / 100.0f, (float)GetRandomValue(-200, 200) / 100.0f}; + p.color = (Color){(unsigned char)GetRandomValue(0, 255), (unsigned char)GetRandomValue(0, 255), (unsigned char)GetRandomValue(0, 255), 255}; + p.size = (float)GetRandomValue(5, 20); + p.life = 1.0f; + particles.push_back(p); + } + } + + for (auto it = particles.begin(); it != particles.end();) { + it->position.x += it->velocity.x * 5.0f; + it->position.y += it->velocity.y * 5.0f; + it->life -= 0.02f; + it->size *= 0.99f; + + if (it->life <= 0) { + it = particles.erase(it); + } else { + ++it; + } + } + + // Draw + BeginDrawing(); + ClearBackground(BLACK); + + for (const auto& p : particles) { + DrawCircleV(p.position, p.size, Fade(p.color, p.life)); + } + + // Draw FPS + const char* fpsText = TextFormat("%2i FPS", GetFPS()); + int fpsWidth = MeasureText(fpsText, 40); + DrawText(fpsText, GetScreenWidth() / 2 - fpsWidth / 2, 30, 40, GREEN); + + // Draw centered instructions + int fontSize = 40; + const char* text = "Touch to create particles!"; + int textWidth = MeasureText(text, fontSize); + DrawText(text, GetScreenWidth() / 2 - textWidth / 2, 80, fontSize, WHITE); + + EndDrawing(); + } + + CloseWindow(); + return 0; +} diff --git a/tests/projects/android/native_app/raylib_particles/xmake.lua b/tests/projects/android/native_app/raylib_particles/xmake.lua new file mode 100644 index 000000000..c6d9a6217 --- /dev/null +++ b/tests/projects/android/native_app/raylib_particles/xmake.lua @@ -0,0 +1,19 @@ +add_rules("mode.debug", "mode.release") + +add_requires("raylib 5.5.0") + +target("raydemo_particles") + set_kind("binary") + set_languages("c++17") + add_files("src/main.cpp") + add_syslinks("log") + add_packages("raylib") + add_rules("android.native_app", { + android_sdk_version = "35", + android_manifest = "android/AndroidManifest.xml", + android_res = "android/res", + keystore = "android/debug.jks", + keystore_pass = "123456", + package_name = "com.raylib.particles", + logcat_filters = {"raydemo_particles", "raylib"} + }) |
