* Add support Android build for Visual Studio * Delete projects/VS2019-Android/raylib_android/ARM64/Debug directory * Delete projects/VS2019-Android/raylib_android/raylib_android/raylib_android.NativeActivity/ARM64/Debug directory * Delete projects/VS2019-Android/raylib_android/raylib_android/raylib_android.Packaging/ARM64/Debug directory * Delete projects/VS2019-Android/raylib_android/raylib_android/raylib_android.Packaging/ARM/Debug directory * Delete projects/VS2019-Android directory * Build Android App with Visual Studio 2019pull/2017/head
@ -0,0 +1,75 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio Version 16 | |||
VisualStudioVersion = 16.0.31702.278 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "raylib_android", "raylib_android", "{5C24BC76-8848-40EA-9BBB-A544648D8D5B}" | |||
EndProject | |||
Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "raylib_android.Packaging", "raylib_android\raylib_android.Packaging\raylib_android.Packaging.androidproj", "{B2231F0D-52DA-4C55-8998-5886F766553C}" | |||
EndProject | |||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib_android.NativeActivity", "raylib_android\raylib_android.NativeActivity\raylib_android.NativeActivity.vcxproj", "{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|ARM = Debug|ARM | |||
Debug|ARM64 = Debug|ARM64 | |||
Debug|x64 = Debug|x64 | |||
Debug|x86 = Debug|x86 | |||
Release|ARM = Release|ARM | |||
Release|ARM64 = Release|ARM64 | |||
Release|x64 = Release|x64 | |||
Release|x86 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.ActiveCfg = Debug|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Build.0 = Debug|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Deploy.0 = Debug|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.ActiveCfg = Debug|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Build.0 = Debug|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Deploy.0 = Debug|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.ActiveCfg = Debug|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Build.0 = Debug|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Deploy.0 = Debug|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.ActiveCfg = Debug|x86 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Build.0 = Debug|x86 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Deploy.0 = Debug|x86 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.ActiveCfg = Release|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Build.0 = Release|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Deploy.0 = Release|ARM | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.ActiveCfg = Release|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Build.0 = Release|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Deploy.0 = Release|ARM64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.ActiveCfg = Release|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Build.0 = Release|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Deploy.0 = Release|x64 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.ActiveCfg = Release|x86 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Build.0 = Release|x86 | |||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Deploy.0 = Release|x86 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.ActiveCfg = Debug|ARM | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.Build.0 = Debug|ARM | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.ActiveCfg = Debug|ARM64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.Build.0 = Debug|ARM64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.ActiveCfg = Debug|x64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.Build.0 = Debug|x64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.ActiveCfg = Debug|x86 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.Build.0 = Debug|x86 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.ActiveCfg = Release|ARM | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.Build.0 = Release|ARM | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.ActiveCfg = Release|ARM64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.Build.0 = Release|ARM64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.ActiveCfg = Release|x64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.Build.0 = Release|x64 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.ActiveCfg = Release|x86 | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.Build.0 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(NestedProjects) = preSolution | |||
{B2231F0D-52DA-4C55-8998-5886F766553C} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B} | |||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B} | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {B7ED0AA6-6B00-40AC-BF71-526D5BEEFC78} | |||
EndGlobalSection | |||
EndGlobal |
@ -0,0 +1,437 @@ | |||
/* | |||
* Copyright (C) 2010 The Android Open Source Project | |||
* | |||
* лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия"); | |||
*этот файл можно использовать только в соответствии с лицензией. | |||
*Копию лицензии можно получить на веб-сайте | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение | |||
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ", | |||
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых. | |||
* См. лицензию для получения информации об определенных разрешениях по использованию языка и | |||
* ограничениях в рамках лицензии. | |||
* | |||
*/ | |||
#include <jni.h> | |||
#include <errno.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <sys/resource.h> | |||
#include "android_native_app_glue.h" | |||
#include <android/log.h> | |||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) | |||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) | |||
/* Для отладочных построений необходимо всегда включать трассировку отладки в этой библиотеке*/ | |||
#ifndef NDEBUG | |||
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) | |||
#else | |||
# define LOGV(...) ((void)0) | |||
#endif | |||
static void free_saved_state(struct android_app* android_app) { | |||
pthread_mutex_lock(&android_app->mutex); | |||
if (android_app->savedState != NULL) { | |||
free(android_app->savedState); | |||
android_app->savedState = NULL; | |||
android_app->savedStateSize = 0; | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
} | |||
int8_t android_app_read_cmd(struct android_app* android_app) { | |||
int8_t cmd; | |||
if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { | |||
switch (cmd) { | |||
case APP_CMD_SAVE_STATE: | |||
free_saved_state(android_app); | |||
break; | |||
} | |||
return cmd; | |||
} else { | |||
LOGE("No data on command pipe!"); | |||
} | |||
return -1; | |||
} | |||
static void print_cur_config(struct android_app* android_app) { | |||
char lang[2], country[2]; | |||
AConfiguration_getLanguage(android_app->config, lang); | |||
AConfiguration_getCountry(android_app->config, country); | |||
LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " | |||
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " | |||
"modetype=%d modenight=%d", | |||
AConfiguration_getMcc(android_app->config), | |||
AConfiguration_getMnc(android_app->config), | |||
lang[0], lang[1], country[0], country[1], | |||
AConfiguration_getOrientation(android_app->config), | |||
AConfiguration_getTouchscreen(android_app->config), | |||
AConfiguration_getDensity(android_app->config), | |||
AConfiguration_getKeyboard(android_app->config), | |||
AConfiguration_getNavigation(android_app->config), | |||
AConfiguration_getKeysHidden(android_app->config), | |||
AConfiguration_getNavHidden(android_app->config), | |||
AConfiguration_getSdkVersion(android_app->config), | |||
AConfiguration_getScreenSize(android_app->config), | |||
AConfiguration_getScreenLong(android_app->config), | |||
AConfiguration_getUiModeType(android_app->config), | |||
AConfiguration_getUiModeNight(android_app->config)); | |||
} | |||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { | |||
switch (cmd) { | |||
case APP_CMD_INPUT_CHANGED: | |||
LOGV("APP_CMD_INPUT_CHANGED\n"); | |||
pthread_mutex_lock(&android_app->mutex); | |||
if (android_app->inputQueue != NULL) { | |||
AInputQueue_detachLooper(android_app->inputQueue); | |||
} | |||
android_app->inputQueue = android_app->pendingInputQueue; | |||
if (android_app->inputQueue != NULL) { | |||
LOGV("Attaching input queue to looper"); | |||
AInputQueue_attachLooper(android_app->inputQueue, | |||
android_app->looper, LOOPER_ID_INPUT, NULL, | |||
&android_app->inputPollSource); | |||
} | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
break; | |||
case APP_CMD_INIT_WINDOW: | |||
LOGV("APP_CMD_INIT_WINDOW\n"); | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->window = android_app->pendingWindow; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
break; | |||
case APP_CMD_TERM_WINDOW: | |||
LOGV("APP_CMD_TERM_WINDOW\n"); | |||
pthread_cond_broadcast(&android_app->cond); | |||
break; | |||
case APP_CMD_RESUME: | |||
case APP_CMD_START: | |||
case APP_CMD_PAUSE: | |||
case APP_CMD_STOP: | |||
LOGV("activityState=%d\n", cmd); | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->activityState = cmd; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
break; | |||
case APP_CMD_CONFIG_CHANGED: | |||
LOGV("APP_CMD_CONFIG_CHANGED\n"); | |||
AConfiguration_fromAssetManager(android_app->config, | |||
android_app->activity->assetManager); | |||
print_cur_config(android_app); | |||
break; | |||
case APP_CMD_DESTROY: | |||
LOGV("APP_CMD_DESTROY\n"); | |||
android_app->destroyRequested = 1; | |||
break; | |||
} | |||
} | |||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) { | |||
switch (cmd) { | |||
case APP_CMD_TERM_WINDOW: | |||
LOGV("APP_CMD_TERM_WINDOW\n"); | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->window = NULL; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
break; | |||
case APP_CMD_SAVE_STATE: | |||
LOGV("APP_CMD_SAVE_STATE\n"); | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->stateSaved = 1; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
break; | |||
case APP_CMD_RESUME: | |||
free_saved_state(android_app); | |||
break; | |||
} | |||
} | |||
static void android_app_destroy(struct android_app* android_app) { | |||
LOGV("android_app_destroy!"); | |||
free_saved_state(android_app); | |||
pthread_mutex_lock(&android_app->mutex); | |||
if (android_app->inputQueue != NULL) { | |||
AInputQueue_detachLooper(android_app->inputQueue); | |||
} | |||
AConfiguration_delete(android_app->config); | |||
android_app->destroyed = 1; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
// После этого нельзя изменять объект android_app. | |||
} | |||
static void process_input(struct android_app* app, struct android_poll_source* source) { | |||
AInputEvent* event = NULL; | |||
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { | |||
LOGV("New input event: type=%d\n", AInputEvent_getType(event)); | |||
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { | |||
continue; | |||
} | |||
int32_t handled = 0; | |||
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); | |||
AInputQueue_finishEvent(app->inputQueue, event, handled); | |||
} | |||
} | |||
static void process_cmd(struct android_app* app, struct android_poll_source* source) { | |||
int8_t cmd = android_app_read_cmd(app); | |||
android_app_pre_exec_cmd(app, cmd); | |||
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); | |||
android_app_post_exec_cmd(app, cmd); | |||
} | |||
static void* android_app_entry(void* param) { | |||
struct android_app* android_app = (struct android_app*)param; | |||
android_app->config = AConfiguration_new(); | |||
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); | |||
print_cur_config(android_app); | |||
android_app->cmdPollSource.id = LOOPER_ID_MAIN; | |||
android_app->cmdPollSource.app = android_app; | |||
android_app->cmdPollSource.process = process_cmd; | |||
android_app->inputPollSource.id = LOOPER_ID_INPUT; | |||
android_app->inputPollSource.app = android_app; | |||
android_app->inputPollSource.process = process_input; | |||
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); | |||
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, | |||
&android_app->cmdPollSource); | |||
android_app->looper = looper; | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->running = 1; | |||
pthread_cond_broadcast(&android_app->cond); | |||
pthread_mutex_unlock(&android_app->mutex); | |||
android_main(android_app); | |||
android_app_destroy(android_app); | |||
return NULL; | |||
} | |||
// -------------------------------------------------------------------- | |||
// Взаимодействие NativeАctivity (вызванное из основного потока) | |||
// -------------------------------------------------------------------- | |||
static struct android_app* android_app_create(ANativeActivity* activity, | |||
void* savedState, size_t savedStateSize) { | |||
struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); | |||
memset(android_app, 0, sizeof(struct android_app)); | |||
android_app->activity = activity; | |||
pthread_mutex_init(&android_app->mutex, NULL); | |||
pthread_cond_init(&android_app->cond, NULL); | |||
if (savedState != NULL) { | |||
android_app->savedState = malloc(savedStateSize); | |||
android_app->savedStateSize = savedStateSize; | |||
memcpy(android_app->savedState, savedState, savedStateSize); | |||
} | |||
int msgpipe[2]; | |||
if (pipe(msgpipe)) { | |||
LOGE("could not create pipe: %s", strerror(errno)); | |||
return NULL; | |||
} | |||
android_app->msgread = msgpipe[0]; | |||
android_app->msgwrite = msgpipe[1]; | |||
pthread_attr_t attr; | |||
pthread_attr_init(&attr); | |||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |||
pthread_create(&android_app->thread, &attr, android_app_entry, android_app); | |||
// Дождитесь запуска потока. | |||
pthread_mutex_lock(&android_app->mutex); | |||
while (!android_app->running) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
return android_app; | |||
} | |||
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { | |||
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { | |||
LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); | |||
} | |||
} | |||
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->pendingInputQueue = inputQueue; | |||
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); | |||
while (android_app->inputQueue != android_app->pendingInputQueue) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
} | |||
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { | |||
pthread_mutex_lock(&android_app->mutex); | |||
if (android_app->pendingWindow != NULL) { | |||
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); | |||
} | |||
android_app->pendingWindow = window; | |||
if (window != NULL) { | |||
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); | |||
} | |||
while (android_app->window != android_app->pendingWindow) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
} | |||
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app_write_cmd(android_app, cmd); | |||
while (android_app->activityState != cmd) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
} | |||
static void android_app_free(struct android_app* android_app) { | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app_write_cmd(android_app, APP_CMD_DESTROY); | |||
while (!android_app->destroyed) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
close(android_app->msgread); | |||
close(android_app->msgwrite); | |||
pthread_cond_destroy(&android_app->cond); | |||
pthread_mutex_destroy(&android_app->mutex); | |||
free(android_app); | |||
} | |||
static void onDestroy(ANativeActivity* activity) { | |||
LOGV("Destroy: %p\n", activity); | |||
android_app_free((struct android_app*)activity->instance); | |||
} | |||
static void onStart(ANativeActivity* activity) { | |||
LOGV("Start: %p\n", activity); | |||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); | |||
} | |||
static void onResume(ANativeActivity* activity) { | |||
LOGV("Resume: %p\n", activity); | |||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); | |||
} | |||
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { | |||
struct android_app* android_app = (struct android_app*)activity->instance; | |||
void* savedState = NULL; | |||
LOGV("SaveInstanceState: %p\n", activity); | |||
pthread_mutex_lock(&android_app->mutex); | |||
android_app->stateSaved = 0; | |||
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); | |||
while (!android_app->stateSaved) { | |||
pthread_cond_wait(&android_app->cond, &android_app->mutex); | |||
} | |||
if (android_app->savedState != NULL) { | |||
savedState = android_app->savedState; | |||
*outLen = android_app->savedStateSize; | |||
android_app->savedState = NULL; | |||
android_app->savedStateSize = 0; | |||
} | |||
pthread_mutex_unlock(&android_app->mutex); | |||
return savedState; | |||
} | |||
static void onPause(ANativeActivity* activity) { | |||
LOGV("Pause: %p\n", activity); | |||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); | |||
} | |||
static void onStop(ANativeActivity* activity) { | |||
LOGV("Stop: %p\n", activity); | |||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); | |||
} | |||
static void onConfigurationChanged(ANativeActivity* activity) { | |||
struct android_app* android_app = (struct android_app*)activity->instance; | |||
LOGV("ConfigurationChanged: %p\n", activity); | |||
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); | |||
} | |||
static void onLowMemory(ANativeActivity* activity) { | |||
struct android_app* android_app = (struct android_app*)activity->instance; | |||
LOGV("LowMemory: %p\n", activity); | |||
android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); | |||
} | |||
static void onWindowFocusChanged(ANativeActivity* activity, int focused) { | |||
LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); | |||
android_app_write_cmd((struct android_app*)activity->instance, | |||
focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); | |||
} | |||
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { | |||
LOGV("NativeWindowCreated: %p -- %p\n", activity, window); | |||
android_app_set_window((struct android_app*)activity->instance, window); | |||
} | |||
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { | |||
LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); | |||
android_app_set_window((struct android_app*)activity->instance, NULL); | |||
} | |||
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { | |||
LOGV("InputQueueCreated: %p -- %p\n", activity, queue); | |||
android_app_set_input((struct android_app*)activity->instance, queue); | |||
} | |||
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { | |||
LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); | |||
android_app_set_input((struct android_app*)activity->instance, NULL); | |||
} | |||
void ANativeActivity_onCreate(ANativeActivity* activity, | |||
void* savedState, size_t savedStateSize) { | |||
LOGV("Creating: %p\n", activity); | |||
activity->callbacks->onDestroy = onDestroy; | |||
activity->callbacks->onStart = onStart; | |||
activity->callbacks->onResume = onResume; | |||
activity->callbacks->onSaveInstanceState = onSaveInstanceState; | |||
activity->callbacks->onPause = onPause; | |||
activity->callbacks->onStop = onStop; | |||
activity->callbacks->onConfigurationChanged = onConfigurationChanged; | |||
activity->callbacks->onLowMemory = onLowMemory; | |||
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; | |||
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; | |||
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; | |||
activity->callbacks->onInputQueueCreated = onInputQueueCreated; | |||
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; | |||
activity->instance = android_app_create(activity, savedState, savedStateSize); | |||
} |
@ -0,0 +1,344 @@ | |||
/* | |||
* © 2010 The Android Open Source Project | |||
* | |||
* Лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия"); | |||
*этот файл можно использовать только в соответствии с лицензией. | |||
*Копию лицензии можно получить на веб-сайте | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение | |||
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ", | |||
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых. | |||
* См. лицензию для получения информации об определенных разрешениях по использованию языка и | |||
* ограничениях в рамках лицензии. | |||
* | |||
*/ | |||
#ifndef _ANDROID_NATIVE_APP_GLUE_H | |||
#define _ANDROID_NATIVE_APP_GLUE_H | |||
#include <poll.h> | |||
#include <pthread.h> | |||
#include <sched.h> | |||
#include <android/configuration.h> | |||
#include <android/looper.h> | |||
#include <android/native_activity.h> | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/** | |||
* Интерфейс NativeActivity, предоставленный <android/native_activity.h>, | |||
* основан на наборе предоставленных приложением обратных вызовов, которые вызываются | |||
*основным потоком действия при возникновении определенных событий. | |||
* | |||
* Это означает, что ни один из данных обратных вызовов _не_ _должен_ блокироваться, иначе | |||
* существует риск принудительного закрытия приложения системой. Эта модель программирования | |||
* прямая, простая, но имеет ограничения. | |||
* | |||
* Статическая библиотека threaded_native_app используется для обеспечения другой | |||
* модели выполнения, в которой приложение может реализовать свой собственный цикл главного события | |||
* в другом потоке вместо этого. Это работает так: | |||
* | |||
* 1/ Приложение должно предоставить функцию с именем android_main(), которая | |||
* будет вызываться при создании действия в новом потоке, | |||
* отличающемся от основного потока действия. | |||
* | |||
* 2/ android_main() получает указатель на допустимую структуру android_app, | |||
* которая содержит ссылки на другие важные объекты, например экземпляр объекта | |||
* ANativeActivity, где выполняется приложение. | |||
* | |||
* 3/ Объект android_app содержит экземпляр ALooper, который уже | |||
* ожидает две важных вещи: | |||
* | |||
* - событий жизненного цикла действия (например, "pause", "resume"). См. объявления APP_CMD_XXX | |||
* ниже. | |||
* | |||
* - входных событий, поступающих из очереди AInputQueue, присоединенной к действию. | |||
* | |||
* Каждое из этих событий соответствует идентификатору ALooper, возвращенному | |||
* ALooper_pollOnce со значениями LOOPER_ID_MAIN и LOOPER_ID_INPUT, | |||
*, соответственно. | |||
* | |||
* Ваше приложение может использовать тот же ALooper для прослушивания дополнительных | |||
* дескрипторов файла. Они могут быть основаны либо на обратных вызовах, либо поступают с идентификаторами возврата, | |||
* начинающимися с LOOPER_ID_USER. | |||
* | |||
* 4/ При получении события LOOPER_ID_MAIN или LOOPER_ID_INPUT | |||
* возвращенные данные будут указывать на структуру android_poll_source. Для нее | |||
* можно вызвать функцию process() и заполнить android_app->onAppCmd | |||
* и android_app->onInputEvent, для того чтобы они вызывались для вашей собственной обработки | |||
* события. | |||
* | |||
* Вместо этого можно вызвать функции нижнего уровня для чтения и обработки | |||
* данных непосредственно... посмотрите на реализации process_cmd() и process_input() | |||
* в приклеивании, чтобы выяснить, как это делается. | |||
* | |||
* См. пример "native-activity" в NDK с | |||
* полной демонстрацией использования. Также посмотрите JavaDoc в NativeActivity. | |||
*/ | |||
struct android_app; | |||
/** | |||
* Данные, связанные с ALooper fd, которые будут возвращаться как outData | |||
* при готовности данных в этом источнике. | |||
*/ | |||
struct android_poll_source { | |||
// Идентификатор данного источника. Может быть LOOPER_ID_MAIN или | |||
// LOOPER_ID_INPUT. | |||
int32_t id; | |||
// android_app, с которым связан данный идентификатор. | |||
struct android_app* app; | |||
// Функция, вызываемая для стандартной обработки данных из | |||
// этого источника. | |||
void (*process)(struct android_app* app, struct android_poll_source* source); | |||
}; | |||
/** | |||
* Это интерфейс стандартного кода приклеивания поточного | |||
* приложения. В этой модели код приложения выполняется | |||
* в своем собственном потоке, отдельном от основного потока процесса. | |||
* Не требуется связь данного потока с ВМ Java | |||
*, хотя это необходимо для выполнения вызовов JNI любых | |||
* объектов Java. | |||
*/ | |||
struct android_app { | |||
// Приложение может поместить указатель на свой собственный объект состояния | |||
// здесь, если нужно. | |||
void* userData; | |||
// Введите здесь код функции для обработки основных команд приложения (APP_CMD_*) | |||
void (*onAppCmd)(struct android_app* app, int32_t cmd); | |||
// Введите здесь код функции для обработки входных событий. Сейчас | |||
// событие уже было предварительно отправлено и будет завершено при | |||
// возврате. Верните 1, если событие обработано, 0 — для любой диспетчеризации | |||
// по умолчанию. | |||
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); | |||
// Экземпляр объекта ANativeActivity, в котором выполняется это приложение. | |||
ANativeActivity* activity; | |||
// Текущая конфигурация, в которой выполняется это приложение. | |||
AConfiguration* config; | |||
// Это последнее сохраненное состояние экземпляра, предоставленное во время создания. | |||
// Значение равно NULL, если состояния не было. Можно использовать это по мере необходимости; | |||
// память останется доступной до вызова android_app_exec_cmd() для | |||
// APP_CMD_RESUME, после чего она будет освобождена, а savedState получит значение NULL. | |||
// Эти переменные необходимо изменять только при обработке APP_CMD_SAVE_STATE, | |||
// когда их значения будут инициализироваться в NULL и можно будет выполнить malloc для | |||
// состояния и поместить здесь информацию. В этом случае память будет | |||
// освобождена позднее. | |||
void* savedState; | |||
size_t savedStateSize; | |||
// ALooper, связанный с потоком приложения. | |||
ALooper* looper; | |||
// Если значение не равно NULL, то это входная очередь, из которой приложение будет | |||
// получать входные события пользователя. | |||
AInputQueue* inputQueue; | |||
// Если значение не равно NULL, то это поверхность окна, в котором приложение может рисовать. | |||
ANativeWindow* window; | |||
// Текущий прямоугольник содержимого окна. Это область, в которой | |||
// должно помещаться содержимое окна, чтобы его видел пользователь. | |||
ARect contentRect; | |||
// Текущее состояние действия приложения. Может быть APP_CMD_START, | |||
// APP_CMD_RESUME, APP_CMD_PAUSE или APP_CMD_STOP; см. ниже. | |||
int activityState; | |||
// Значение не равно нулю, когда NativeActivity приложения | |||
// разрушается и ожидает завершения потока приложения. | |||
int destroyRequested; | |||
// ------------------------------------------------- | |||
// Ниже показан "частная" реализация кода прилипания. | |||
pthread_mutex_t mutex; | |||
pthread_cond_t cond; | |||
int msgread; | |||
int msgwrite; | |||
pthread_t thread; | |||
struct android_poll_source cmdPollSource; | |||
struct android_poll_source inputPollSource; | |||
int running; | |||
int stateSaved; | |||
int destroyed; | |||
int redrawNeeded; | |||
AInputQueue* pendingInputQueue; | |||
ANativeWindow* pendingWindow; | |||
ARect pendingContentRect; | |||
}; | |||
enum { | |||
/** | |||
* Идентификатор данных Looper команд, поступающих из основного потока приложения, который | |||
* возвращается как идентификатор от ALooper_pollOnce(). Данные для этого идентификатора | |||
* являются указателем на структуру android_poll_source. | |||
* Их можно извлечь и обработать с помощью android_app_read_cmd() | |||
* и android_app_exec_cmd(). | |||
*/ | |||
LOOPER_ID_MAIN = 1, | |||
/** | |||
* Идентификатор данных Looper событий, поступающий из AInputQueue окна | |||
* приложения, который возвращается как идентификатор из | |||
* ALooper_pollOnce(). Данные этого идентификатора являются указателем на структуру | |||
* android_poll_source. Их можно прочитать через объект inputQueue | |||
* приложения android_app. | |||
*/ | |||
LOOPER_ID_INPUT = 2, | |||
/** | |||
* Запуск определяемых пользователем идентификаторов ALooper. | |||
*/ | |||
LOOPER_ID_USER = 3, | |||
}; | |||
enum { | |||
/** | |||
* Команда из основного потока: AInputQueue изменена. После обработки | |||
* этой команды android_app->inputQueue будет обновлена в новую очередь | |||
* (или NULL). | |||
*/ | |||
APP_CMD_INPUT_CHANGED, | |||
/** | |||
* Команда из основного потока: новое окно ANativeWindow готово к использованию. После | |||
* получения этой команды окно android_app-> будет содержать новую поверхность | |||
*окна. | |||
*/ | |||
APP_CMD_INIT_WINDOW, | |||
/** | |||
* Команда из основного потока: существующее окно ANativeWindow необходимо | |||
* прекратить. После получения этой команды окно android_app->по-прежнему | |||
* содержит существующее окно; после вызова android_app_exec_cmd | |||
* оно получит значение NULL. | |||
*/ | |||
APP_CMD_TERM_WINDOW, | |||
/** | |||
* Команда из основного потока: текущее окно ANativeWindow изменило размер. | |||
* Перерисуйте согласно новом размеру. | |||
*/ | |||
APP_CMD_WINDOW_RESIZED, | |||
/** | |||
* Команда из основного потока: системе необходимо, чтобы текущее окно ANativeWindow | |||
* было перерисовано. Необходимо перерисовать окно перед ее передачей в | |||
* android_app_exec_cmd(), чтобы избежать переходных сбоев рисования. | |||
*/ | |||
APP_CMD_WINDOW_REDRAW_NEEDED, | |||
/** | |||
* Команда из основного потока: область содержимого окна изменена | |||
* таким образом, что из функционального ввода окно показывается или скрывается. Можно | |||
* найти новый прямоугольник содержимого в android_app::contentRect. | |||
*/ | |||
APP_CMD_CONTENT_RECT_CHANGED, | |||
/** | |||
* Команда из основного потока: окно действия приложения получило | |||
* фокус ввода. | |||
*/ | |||
APP_CMD_GAINED_FOCUS, | |||
/** | |||
* Команда из основного потока: окно действия приложения потеряло | |||
* фокус ввода. | |||
*/ | |||
APP_CMD_LOST_FOCUS, | |||
/** | |||
* Команда из основного потока: изменена текущая конфигурация устройства. | |||
*/ | |||
APP_CMD_CONFIG_CHANGED, | |||
/** | |||
* Команда из основного потока: системе не хватает памяти. | |||
* Попробуйте уменьшить использование памяти. | |||
*/ | |||
APP_CMD_LOW_MEMORY, | |||
/** | |||
* Команда из основного потока: действие приложения было запущено. | |||
*/ | |||
APP_CMD_START, | |||
/** | |||
* Команда из основного потока: действие приложения было возобновлено. | |||
*/ | |||
APP_CMD_RESUME, | |||
/** | |||
* Команда из основного потока: приложение должно создать новое сохраненное состояние | |||
* для себя, чтобы восстанавливаться из него позднее в случае необходимости. Если вы сохранили состояние, | |||
* выделите его с использованием malloc и поместите в android_app.savedState с | |||
* размером android_app.savedStateSize. Память будет освобождена | |||
* позднее. | |||
*/ | |||
APP_CMD_SAVE_STATE, | |||
/** | |||
* Команда из основного потока: пауза в действии приложения. | |||
*/ | |||
APP_CMD_PAUSE, | |||
/** | |||
* Команда из основного потока: действие приложения было остановлено. | |||
*/ | |||
APP_CMD_STOP, | |||
/** | |||
* Команда из основного потока: действие приложения уничтожается, | |||
* и ожидает очистки потока приложения и выхода перед обработкой. | |||
*/ | |||
APP_CMD_DESTROY, | |||
}; | |||
/** | |||
* Вызовите, когда ALooper_pollAll() возвращает LOOPER_ID_MAIN, при чтении следующего сообщения команды | |||
*приложения. | |||
*/ | |||
int8_t android_app_read_cmd(struct android_app* android_app); | |||
/** | |||
* Вызовите с помощью команды, возвращенной android_app_read_cmd() для выполнения | |||
* начальной предварительной обработки данной команды. Можно выполнить собственные | |||
* действия для команды после вызова этой функции. | |||
*/ | |||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); | |||
/** | |||
* Вызовите с помощью команды, возвращенной android_app_read_cmd(), для | |||
* окончательной предварительной обработки данной команды. Необходимо завершить собственные | |||
* действия с командой до вызова этой функции. | |||
*/ | |||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); | |||
/** | |||
* Это функция, которую должен реализовать код приложения, представляет собой | |||
* главный вход в приложение. | |||
*/ | |||
extern void android_main(struct android_app* app); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* _ANDROID_NATIVE_APP_GLUE_H */ |
@ -0,0 +1,64 @@ | |||
/******************************************************************************************* | |||
* | |||
* raylib [core] example - Basic window | |||
* | |||
* This example has been created using raylib 3.8 (www.raylib.com) | |||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |||
* | |||
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5) | |||
* | |||
* Copyright (c) 2021 <user_name> (@<user_github>) | |||
* Adapt for Visual Studio: Vadim Boev (Kronka Dev) | |||
* | |||
********************************************************************************************/ | |||
#include "android_native_app_glue.h" | |||
#include "../../../../src/raylib.h" | |||
int main(void) | |||
{ | |||
// Initialization | |||
//-------------------------------------------------------------------------------------- | |||
const int screenWidth = 800; | |||
const int screenHeight = 450; | |||
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); | |||
// TODO: Load resources / Initialize variables at this point | |||
SetTargetFPS(60); | |||
//-------------------------------------------------------------------------------------- | |||
// Main game loop | |||
while (!WindowShouldClose()) // Detect window close button or ESC key | |||
{ | |||
// Update | |||
//---------------------------------------------------------------------------------- | |||
// TODO: Update variables / Implement example logic at this point | |||
//---------------------------------------------------------------------------------- | |||
// Draw | |||
//---------------------------------------------------------------------------------- | |||
BeginDrawing(); | |||
ClearBackground(RAYWHITE); | |||
// TODO: Draw everything that requires to be drawn at this point: | |||
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); // Example | |||
EndDrawing(); | |||
//---------------------------------------------------------------------------------- | |||
} | |||
// De-Initialization | |||
//-------------------------------------------------------------------------------------- | |||
// TODO: Unload all loaded resources at this point | |||
CloseWindow(); // Close window and OpenGL context | |||
//-------------------------------------------------------------------------------------- | |||
return 0; | |||
} |
@ -0,0 +1,226 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup Label="ProjectConfigurations"> | |||
<ProjectConfiguration Include="Debug|ARM"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>ARM</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|ARM"> | |||
<Configuration>Release</Configuration> | |||
<Platform>ARM</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|ARM64"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>ARM64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|ARM64"> | |||
<Configuration>Release</Configuration> | |||
<Platform>ARM64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|x64"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>x64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|x64"> | |||
<Configuration>Release</Configuration> | |||
<Platform>x64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|x86"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>x86</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|x86"> | |||
<Configuration>Release</Configuration> | |||
<Platform>x86</Platform> | |||
</ProjectConfiguration> | |||
</ItemGroup> | |||
<PropertyGroup Label="Globals"> | |||
<ProjectGuid>{bfb31759-4fca-4503-bc7c-a97f705efdb2}</ProjectGuid> | |||
<Keyword>Android</Keyword> | |||
<RootNamespace>raylib_android</RootNamespace> | |||
<DefaultLanguage>en-US</DefaultLanguage> | |||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> | |||
<ApplicationType>Android</ApplicationType> | |||
<ApplicationTypeRevision>3.0</ApplicationTypeRevision> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
<AndroidAPILevel>android-29</AndroidAPILevel> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>Clang_5_0</PlatformToolset> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |||
<ImportGroup Label="ExtensionSettings"> | |||
</ImportGroup> | |||
<ImportGroup Label="Shared"> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x86'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x86'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<PropertyGroup Label="UserMacros" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> | |||
<TargetName>libmain</TargetName> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" /> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> | |||
<ClCompile> | |||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsC</CompileAs> | |||
<CLanguageStandard>c99</CLanguageStandard> | |||
<CppLanguageStandard>Default</CppLanguageStandard> | |||
<PrecompiledHeaderCompileAs>CompileAsC</PrecompiledHeaderCompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);EGL;GLESv2;log;android;c;m;raylib</LibraryDependencies> | |||
<AdditionalLibraryDirectories>../../../../src/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> | |||
<ClCompile> | |||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsC</CompileAs> | |||
<CLanguageStandard>c99</CLanguageStandard> | |||
<CppLanguageStandard>Default</CppLanguageStandard> | |||
<PrecompiledHeaderCompileAs>CompileAsC</PrecompiledHeaderCompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
<AdditionalLibraryDirectories>.;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'"> | |||
<ClCompile> | |||
<PrecompiledHeader>Use</PrecompiledHeader> | |||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | |||
<CompileAs>CompileAsCpp</CompileAs> | |||
</ClCompile> | |||
<Link> | |||
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClInclude Include="android_native_app_glue.h" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClCompile Include="android_native_app_glue.c" /> | |||
<ClCompile Include="main.c" /> | |||
</ItemGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||
<ImportGroup Label="ExtensionTargets"> | |||
</ImportGroup> | |||
</Project> |
@ -0,0 +1,10 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup> | |||
<ClInclude Include="android_native_app_glue.h" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClCompile Include="android_native_app_glue.c" /> | |||
<ClCompile Include="main.c" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<PropertyGroup /> | |||
</Project> |
@ -0,0 +1,22 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<!-- Changes made to Package Name should also be reflected in the Debugging - Package Name property, in the Property Pages --> | |||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.$(ApplicationName)" android:versionCode="1" android:versionName="1.0"> | |||
<!-- This is the platform API where NativeActivity was introduced. --> | |||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/> | |||
<!-- This .apk has no Java code itself, so set hasCode to false. --> | |||
<application android:label="@string/app_name" android:hasCode="false"> | |||
<!-- Our activity is the built-in NativeActivity framework class. | |||
This will take care of integrating with our NDK code. --> | |||
<activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="landscape"> | |||
<!-- Tell NativeActivity the name of our .so --> | |||
<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> |
@ -0,0 +1,90 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project name="$(projectname)" default="help"> | |||
<!-- The ant.properties file can be created by you. It is only edited by the | |||
'android' tool to add properties to it. | |||
This is the place to change some Ant specific build properties. | |||
Here are some properties you may want to change/update: | |||
source.dir | |||
The name of the source directory. Default is 'src'. | |||
out.dir | |||
The name of the output directory. Default is 'bin'. | |||
For other overridable properties, look at the beginning of the rules | |||
files in the SDK, at tools/ant/build.xml | |||
Properties related to the SDK location or the project target should | |||
be updated using the 'android' tool with the 'update' action. | |||
This file is an integral part of the build system for your | |||
application and should be checked into Version Control Systems. | |||
--> | |||
<property file="ant.properties" /> | |||
<!-- if sdk.dir was not set from one of the property file, then | |||
get it from the ANDROID_HOME env var. --> | |||
<property environment="env" /> | |||
<condition property="sdk.dir" value="${env.ANDROID_HOME}"> | |||
<isset property="env.ANDROID_HOME" /> | |||
</condition> | |||
<!-- The project.properties file contains project specific properties such as | |||
project target, and library dependencies. Lower level build properties are | |||
stored in ant.properties | |||
This file is an integral part of the build system for your | |||
application and should be checked into Version Control Systems. --> | |||
<loadproperties srcFile="project.properties" /> | |||
<!-- quick check on sdk.dir --> | |||
<fail | |||
message="sdk.dir is missing. Make sure ANDROID_HOME environment variable is correctly set." | |||
unless="sdk.dir" | |||
/> | |||
<!-- | |||
Import per project custom build rules if present at the root of the project. | |||
This is the place to put custom intermediary targets such as: | |||
-pre-build | |||
-pre-compile | |||
-post-compile (This is typically used for code obfuscation. | |||
Compiled code location: ${out.classes.absolute.dir} | |||
If this is not done in place, override ${out.dex.input.absolute.dir}) | |||
-post-package | |||
-post-build | |||
-pre-clean | |||
--> | |||
<import file="custom_rules.xml" optional="true" /> | |||
<!-- Import the actual build file. | |||
To customize existing targets, there are two options: | |||
- Customize only one target: | |||
- copy/paste the target into this file, *before* the | |||
<import> task. | |||
- customize it to your needs. | |||
- Customize the whole content of build.xml | |||
- copy/paste the content of the rules files (minus the top node) | |||
into this file, replacing the <import> task. | |||
- customize to your needs. | |||
*********************** | |||
****** IMPORTANT ****** | |||
*********************** | |||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer, | |||
in order to avoid having your file be overridden by tools such as "android update project" | |||
--> | |||
<!-- version-tag: 1 --> | |||
<import file="${sdk.dir}/tools/ant/build.xml" /> | |||
<target name="-pre-compile"> | |||
<path id="project.all.jars.path"> | |||
<path path="${toString:project.all.jars.path}"/> | |||
<fileset dir="${jar.libs.dir}"> | |||
<include name="*.jar"/> | |||
</fileset> | |||
</path> | |||
</target> | |||
</project> |
@ -0,0 +1,3 @@ | |||
# Project target | |||
target=$(androidapilevel) | |||
# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir= |
@ -0,0 +1,134 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup Label="ProjectConfigurations"> | |||
<ProjectConfiguration Include="Debug|ARM"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>ARM</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|ARM"> | |||
<Configuration>Release</Configuration> | |||
<Platform>ARM</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|ARM64"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>ARM64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|ARM64"> | |||
<Configuration>Release</Configuration> | |||
<Platform>ARM64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|x64"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>x64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|x64"> | |||
<Configuration>Release</Configuration> | |||
<Platform>x64</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Debug|x86"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>x86</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|x86"> | |||
<Configuration>Release</Configuration> | |||
<Platform>x86</Platform> | |||
</ProjectConfiguration> | |||
</ItemGroup> | |||
<PropertyGroup Label="Globals"> | |||
<RootNamespace>raylib_android</RootNamespace> | |||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> | |||
<ProjectVersion>1.0</ProjectVersion> | |||
<ProjectGuid>{b2231f0d-52da-4c55-8998-5886f766553c}</ProjectGuid> | |||
</PropertyGroup> | |||
<Import Project="$(AndroidTargetsPath)\Android.Default.props" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration"> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration"> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<ConfigurationType>Application</ConfigurationType> | |||
</PropertyGroup> | |||
<Import Project="$(AndroidTargetsPath)\Android.props" /> | |||
<ImportGroup Label="ExtensionSettings" /> | |||
<ImportGroup Label="Shared" /> | |||
<PropertyGroup Label="UserMacros" /> | |||
<PropertyGroup /> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'"> | |||
<AntPackage> | |||
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName> | |||
</AntPackage> | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<Content Include="res\values\strings.xml" /> | |||
<AntBuildXml Include="build.xml" /> | |||
<AndroidManifest Include="AndroidManifest.xml" /> | |||
<AntProjectPropertiesFile Include="project.properties" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\raylib_android.NativeActivity\raylib_android.NativeActivity.vcxproj"> | |||
<Project>{bfb31759-4fca-4503-bc7c-a97f705efdb2}</Project> | |||
</ProjectReference> | |||
</ItemGroup> | |||
<Import Project="$(AndroidTargetsPath)\Android.targets" /> | |||
<ImportGroup Label="ExtensionTargets" /> | |||
</Project> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<resources> | |||
<string name="app_name">raylib_android.Packaging</string> | |||
</resources> |