istereo2
diff src/android/amain.c @ 23:7d795dade0bc
first pass at android port... compiles!
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 03 Oct 2015 06:10:30 +0300 |
parents | |
children | 9d53a4938ce8 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/android/amain.c Sat Oct 03 06:10:30 2015 +0300 1.3 @@ -0,0 +1,275 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <assert.h> 1.7 +#include <EGL/egl.h> 1.8 +#include <jni.h> 1.9 +#include "android_native_app_glue.h" 1.10 +#include <android/sensor.h> 1.11 +#include "logger.h" 1.12 +#include "istereo.h" 1.13 + 1.14 +struct android_app *app; 1.15 + 1.16 +static void handle_command(struct android_app *app, int32_t cmd); 1.17 +static int handle_input(struct android_app *app, AInputEvent *ev); 1.18 +static int handle_touch_input(struct android_app *app, AInputEvent *ev); 1.19 +static int init_gl(void); 1.20 +static void destroy_gl(void); 1.21 + 1.22 +static EGLDisplay dpy; 1.23 +static EGLSurface surf; 1.24 +static EGLContext ctx; 1.25 + 1.26 +static int redisp_pending = 1; /* TODO stop busy-looping */ 1.27 + 1.28 +static int width, height; 1.29 +static int init_done; 1.30 + 1.31 +void android_main(struct android_app *app_ptr) 1.32 +{ 1.33 + app_dummy(); 1.34 + app = app_ptr; 1.35 + 1.36 + app->onAppCmd = handle_command; 1.37 + app->onInputEvent = handle_input; 1.38 + 1.39 + start_logger(); 1.40 + 1.41 + for(;;) { 1.42 + int num_events; 1.43 + struct android_poll_source *pollsrc; 1.44 + 1.45 + while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) { 1.46 + if(pollsrc) { 1.47 + pollsrc->process(app, pollsrc); 1.48 + } 1.49 + } 1.50 + 1.51 + if(app->destroyRequested) { 1.52 + return; 1.53 + } 1.54 + 1.55 + if(init_done && redisp_pending) { 1.56 + redraw(); 1.57 + eglSwapBuffers(dpy, surf); 1.58 + } 1.59 + } 1.60 +} 1.61 + 1.62 +void set_mouse_pos(int x, int y) 1.63 +{ 1.64 +} 1.65 + 1.66 +void set_mouse_cursor(int enable) 1.67 +{ 1.68 +} 1.69 + 1.70 +/* TODO */ 1.71 +void ad_banner_show(void) 1.72 +{ 1.73 +} 1.74 + 1.75 +void ad_banner_hide(void) 1.76 +{ 1.77 +} 1.78 + 1.79 +static void handle_command(struct android_app *app, int32_t cmd) 1.80 +{ 1.81 + switch(cmd) { 1.82 + case APP_CMD_SAVE_STATE: 1.83 + /* save the application state to be reloaded on restart if needed */ 1.84 + break; 1.85 + 1.86 + case APP_CMD_INIT_WINDOW: 1.87 + if(init_gl() == -1) { 1.88 + exit(1); 1.89 + } 1.90 + /* initialize the application */ 1.91 + if(init() == -1) { 1.92 + exit(1); /* initialization failed, quit */ 1.93 + } 1.94 + init_done = 1; 1.95 + break; 1.96 + 1.97 + case APP_CMD_TERM_WINDOW: 1.98 + /* cleanup */ 1.99 + init_done = 0; 1.100 + cleanup(); 1.101 + destroy_gl(); 1.102 + break; 1.103 + 1.104 + case APP_CMD_GAINED_FOCUS: 1.105 + /* app focused */ 1.106 + break; 1.107 + 1.108 + case APP_CMD_LOST_FOCUS: 1.109 + /* app lost focus */ 1.110 + break; 1.111 + 1.112 + case APP_CMD_WINDOW_RESIZED: 1.113 + case APP_CMD_CONFIG_CHANGED: 1.114 + { 1.115 + int nx = ANativeWindow_getWidth(app->window); 1.116 + int ny = ANativeWindow_getHeight(app->window); 1.117 + if(nx != width || ny != height) { 1.118 + reshape(nx, ny); 1.119 + width = nx; 1.120 + height = ny; 1.121 + } 1.122 + } 1.123 + break; 1.124 + 1.125 + default: 1.126 + break; 1.127 + } 1.128 +} 1.129 + 1.130 +static int handle_input(struct android_app *app, AInputEvent *ev) 1.131 +{ 1.132 + int evtype = AInputEvent_getType(ev); 1.133 + 1.134 + switch(evtype) { 1.135 + case AINPUT_EVENT_TYPE_MOTION: 1.136 + return handle_touch_input(app, ev); 1.137 + 1.138 + default: 1.139 + break; 1.140 + } 1.141 + return 0; 1.142 +} 1.143 + 1.144 +#define MAX_TOUCH_IDS 32 1.145 + 1.146 +static int handle_touch_input(struct android_app *app, AInputEvent *ev) 1.147 +{ 1.148 + int x, y, idx, touch_id; 1.149 + unsigned int action; 1.150 + static int prev_pos[MAX_TOUCH_IDS][2]; 1.151 + 1.152 + action = AMotionEvent_getAction(ev); 1.153 + 1.154 + idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> 1.155 + AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 1.156 + touch_id = AMotionEvent_getPointerId(ev, idx); 1.157 + 1.158 + x = AMotionEvent_getX(ev, idx); 1.159 + y = AMotionEvent_getY(ev, idx); 1.160 + 1.161 + switch(action & AMOTION_EVENT_ACTION_MASK) { 1.162 + case AMOTION_EVENT_ACTION_DOWN: 1.163 + case AMOTION_EVENT_ACTION_POINTER_DOWN: 1.164 + if(touch_id == 0) { 1.165 + mouse_button(0, 1, x, y); 1.166 + } 1.167 + if(touch_id < MAX_TOUCH_IDS) { 1.168 + prev_pos[touch_id][0] = x; 1.169 + prev_pos[touch_id][1] = y; 1.170 + } 1.171 + break; 1.172 + 1.173 + case AMOTION_EVENT_ACTION_UP: 1.174 + case AMOTION_EVENT_ACTION_POINTER_UP: 1.175 + if(touch_id == 0) { 1.176 + mouse_button(0, 0, x, y); 1.177 + } 1.178 + if(touch_id < MAX_TOUCH_IDS) { 1.179 + prev_pos[touch_id][0] = x; 1.180 + prev_pos[touch_id][1] = y; 1.181 + } 1.182 + break; 1.183 + 1.184 + case AMOTION_EVENT_ACTION_MOVE: 1.185 + { 1.186 + int i, pcount = AMotionEvent_getPointerCount(ev); 1.187 + for(i=0; i<pcount; i++) { 1.188 + int id = AMotionEvent_getPointerId(ev, i); 1.189 + if(id < MAX_TOUCH_IDS && x != prev_pos[id][0] && y != prev_pos[id][1]) { 1.190 + if(id == 0) { 1.191 + mouse_motion(x, y); 1.192 + } 1.193 + prev_pos[id][0] = x; 1.194 + prev_pos[id][1] = y; 1.195 + } 1.196 + } 1.197 + } 1.198 + break; 1.199 + 1.200 + default: 1.201 + break; 1.202 + } 1.203 + 1.204 + return 1; 1.205 +} 1.206 + 1.207 + 1.208 +static int init_gl(void) 1.209 +{ 1.210 + static const int eglattr[] = { 1.211 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 1.212 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 1.213 + EGL_RED_SIZE, 5, 1.214 + EGL_GREEN_SIZE, 5, 1.215 + EGL_BLUE_SIZE, 5, 1.216 + EGL_DEPTH_SIZE, 16, 1.217 + EGL_NONE 1.218 + }; 1.219 + static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 1.220 + 1.221 + EGLConfig eglcfg; 1.222 + int count, vis; 1.223 + 1.224 + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1.225 + if(!dpy || !eglInitialize(dpy, 0, 0)) { 1.226 + fprintf(stderr, "failed to initialize EGL\n"); 1.227 + destroy_gl(); 1.228 + return -1; 1.229 + } 1.230 + 1.231 + if(!eglChooseConfig(dpy, eglattr, &eglcfg, 1, &count)) { 1.232 + fprintf(stderr, "no matching EGL config found\n"); 1.233 + destroy_gl(); 1.234 + return -1; 1.235 + } 1.236 + 1.237 + /* configure the native window visual according to the chosen EGL config */ 1.238 + eglGetConfigAttrib(dpy, &eglcfg, EGL_NATIVE_VISUAL_ID, &vis); 1.239 + ANativeWindow_setBuffersGeometry(app->window, 0, 0, vis); 1.240 + 1.241 + if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) { 1.242 + fprintf(stderr, "failed to create window\n"); 1.243 + destroy_gl(); 1.244 + return -1; 1.245 + } 1.246 + 1.247 + if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) { 1.248 + fprintf(stderr, "failed to create OpenGL ES context\n"); 1.249 + destroy_gl(); 1.250 + return -1; 1.251 + } 1.252 + eglMakeCurrent(dpy, surf, surf, ctx); 1.253 + 1.254 + eglQuerySurface(dpy, surf, EGL_WIDTH, &width); 1.255 + eglQuerySurface(dpy, surf, EGL_HEIGHT, &height); 1.256 + reshape(width, height); 1.257 + 1.258 + return 0; 1.259 +} 1.260 + 1.261 +static void destroy_gl(void) 1.262 +{ 1.263 + if(!dpy) return; 1.264 + 1.265 + eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 1.266 + 1.267 + if(ctx) { 1.268 + eglDestroyContext(dpy, ctx); 1.269 + ctx = 0; 1.270 + } 1.271 + if(surf) { 1.272 + eglDestroySurface(dpy, surf); 1.273 + surf = 0; 1.274 + } 1.275 + 1.276 + eglTerminate(dpy); 1.277 + dpy = 0; 1.278 +}