Build Android App with Visual Studio 2019 (#2013)

* 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 2019
This commit is contained in:
Vadim Boev 2021-09-27 18:57:06 +03:00 committed by GitHub
parent 2474d50dba
commit 92f6290dbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1413 additions and 0 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,3 @@
# Project target
target=$(androidapilevel)
# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir=

View File

@ -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>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">raylib_android.Packaging</string>
</resources>