labyrinth
changeset 3:45b91185b298
android port
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 01 May 2015 04:36:50 +0300 |
parents | e3b9707504df |
children | f35596f110bc |
files | Makefile android/AndroidManifest.xml android/Makefile proj.mk src/android/amain.c src/android/logger.c src/android/logger.h src/game.c src/game.h src/gles/sanegl.c src/gles/sanegl.h src/glut/main.c src/main.c src/mesh.c src/opengl.h src/timer.c src/timer.h |
diffstat | 17 files changed, 1282 insertions(+), 400 deletions(-) [+] |
line diff
1.1 --- a/Makefile Mon Apr 27 05:37:17 2015 +0300 1.2 +++ b/Makefile Fri May 01 04:36:50 2015 +0300 1.3 @@ -1,14 +1,15 @@ 1.4 -src = $(wildcard src/*.c) 1.5 +include proj.mk 1.6 +src += src/glut/main.c 1.7 + 1.8 obj = $(src:.c=.o) 1.9 -bin = lab 1.10 1.11 sys = $(shell uname -s) 1.12 1.13 -libgl_Linux = -lGL -lGLU -lglut 1.14 -libgl_Darwin = -framework OpenGL -framework GLUT 1.15 +libgl_Linux = -lGL -lGLU -lglut -lGLEW 1.16 +libgl_Darwin = -framework OpenGL -framework GLUT -lGLEW 1.17 1.18 -CFLAGS = -pedantic -Wall -g 1.19 -LDFLAGS = $(libgl_$(sys)) -lm 1.20 +CFLAGS = -pedantic -Wall -g $(incpaths) 1.21 +LDFLAGS = $(libpaths) $(libgl_$(sys)) -lm 1.22 1.23 $(bin): $(obj) 1.24 $(CC) -o $@ $(obj) $(LDFLAGS)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/android/AndroidManifest.xml Fri May 01 04:36:50 2015 +0300 2.3 @@ -0,0 +1,22 @@ 2.4 +<?xml version="1.0" encoding="utf-8"?> 2.5 +<manifest xmlns:android="http://schemas.android.com/apk/res/android" 2.6 + package="com.mutantstargoat.labyrinth" 2.7 + android:versionCode="1" 2.8 + android:versionName="1.0"> 2.9 + 2.10 + <uses-sdk android:minSdkVersion="9"/> 2.11 + 2.12 + <application android:label="labyrinth" 2.13 + android:hasCode="false" 2.14 + android:debuggable="true"> 2.15 + 2.16 + <activity android:name="android.app.NativeActivity" android:label="Labyrinth"> 2.17 + <meta-data android:name="android.app.lib_name" android:value="labyrinth"/> 2.18 + 2.19 + <intent-filter> 2.20 + <action android:name="android.intent.action.MAIN"/> 2.21 + <action android:name="android.intent.category.LAUNCHER"/> 2.22 + </intent-filter> 2.23 + </activity> 2.24 + </application> 2.25 +</manifest>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/android/Makefile Fri May 01 04:36:50 2015 +0300 3.3 @@ -0,0 +1,78 @@ 3.4 +root = .. 3.5 +include $(root)/proj.mk 3.6 + 3.7 +# --- android settings --- 3.8 +android_platform = android-22 3.9 +name = $(bin) 3.10 +pkgprefix = com.mutantstargoat 3.11 +# ------------------------ 3.12 +native_app_glue_dir = $(NDK)/sources/android/native_app_glue 3.13 + 3.14 +src += $(wildcard $(root)/src/android/*.c) \ 3.15 + $(wildcard $(root)/src/gles/*.c) \ 3.16 + $(native_app_glue_dir)/android_native_app_glue.c 3.17 + 3.18 +obj = $(src:.c=.o) $(ccsrc:.cc=.o) 3.19 +lib = libs/armeabi/lib$(name).so 3.20 +apk-release = bin/$(name).apk 3.21 +apk-debug = bin/$(name)-debug.apk 3.22 + 3.23 +pkg = $(pkgprefix).$(name) 3.24 +act = android.app.NativeActivity 3.25 + 3.26 +CC = arm-linux-androideabi-gcc 3.27 +CXX = arm-linux-androideabi-g++ 3.28 + 3.29 +android_usr = $(NDK)/platforms/$(android_platform)/arch-arm/usr 3.30 +android_inc = -I$(android_usr)/include -I$(native_app_glue_dir) 3.31 +android_libs = -L$(android_usr)/lib -llog -landroid -lEGL -lGLESv1_CM 3.32 + 3.33 +CFLAGS = -std=c99 -Wall -g -DAPP_NAME=\"$(name)\" \ 3.34 + $(android_inc) -I$(root)/src/android -I$(root)/src/gles $(incpaths) 3.35 +LDFLAGS = -Wl,--fix-cortex-a8 $(android_libs) $(libpaths) 3.36 + 3.37 +.PHONY: debug 3.38 +debug: $(apk-debug) 3.39 + 3.40 +.PHONY: release 3.41 +release: $(apk-release) 3.42 + 3.43 +$(apk-debug): $(lib) AndroidManifest.xml 3.44 + ant debug 3.45 + 3.46 +$(apk-release): $(lib) AndroidManifest.xml 3.47 + ant release 3.48 + 3.49 +.PHONY: lib 3.50 +lib: $(lib) 3.51 + 3.52 +$(lib): $(obj) 3.53 + @mkdir -p libs/armeabi 3.54 + $(CC) -o $@ -shared $(obj) $(LDFLAGS) 3.55 + 3.56 +.PHONY: clean 3.57 +clean: 3.58 + rm -f $(obj) $(lib) $(apk-release) $(apk-debug) 3.59 + 3.60 +.PHONY: install 3.61 +install: install-debug 3.62 + 3.63 +.PHONY: install-debug 3.64 +install-debug: 3.65 + adb install -r $(apk-debug) 3.66 + 3.67 +.PHONY: install-release 3.68 +install-release: 3.69 + adb install -r $(apk-release) 3.70 + 3.71 +.PHONY: run 3.72 +run: 3.73 + adb shell am start -n $(pkg)/$(act) 3.74 + 3.75 +.PHONY: stop 3.76 +stop: 3.77 + adb shell am force-stop $(pkg) 3.78 + 3.79 +.PHONY: update-project 3.80 +update-project: build.xml 3.81 + android update project --path . --target $(android_platform)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/proj.mk Fri May 01 04:36:50 2015 +0300 4.3 @@ -0,0 +1,7 @@ 4.4 +root ?= $(shell pwd) 4.5 + 4.6 +src = $(wildcard $(root)/src/*.c) 4.7 +bin = labyrinth 4.8 + 4.9 +incpaths = -I$(root)/src 4.10 +libpaths =
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/android/amain.c Fri May 01 04:36:50 2015 +0300 5.3 @@ -0,0 +1,251 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdlib.h> 5.6 +#include <EGL/egl.h> 5.7 +#include <android_native_app_glue.h> 5.8 +#include "logger.h" 5.9 +#include "game.h" 5.10 +#include "timer.h" 5.11 + 5.12 + 5.13 +static void handle_command(struct android_app *app, int32_t cmd); 5.14 +static int handle_input(struct android_app *app, AInputEvent *ev); 5.15 +static int handle_touch_input(struct android_app *app, AInputEvent *ev); 5.16 +static int init_gl(void); 5.17 +static void destroy_gl(void); 5.18 + 5.19 +static EGLDisplay dpy; 5.20 +static EGLSurface surf; 5.21 +static EGLContext ctx; 5.22 + 5.23 +static struct android_app *app; 5.24 +static int win_width, win_height; 5.25 + 5.26 +void android_main(struct android_app *app_ptr) 5.27 +{ 5.28 + app_dummy(); 5.29 + app = app_ptr; 5.30 + 5.31 + app->onAppCmd = handle_command; 5.32 + app->onInputEvent = handle_input; 5.33 + 5.34 + start_logger(); 5.35 + 5.36 + for(;;) { 5.37 + int num_events; 5.38 + struct android_poll_source *pollsrc; 5.39 + 5.40 + while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) { 5.41 + if(pollsrc) { 5.42 + pollsrc->process(app, pollsrc); 5.43 + } 5.44 + } 5.45 + 5.46 + if(app->destroyRequested) { 5.47 + return; 5.48 + } 5.49 + 5.50 + game_display(get_time_msec()); 5.51 + } 5.52 +} 5.53 + 5.54 +void set_mouse_pos(int x, int y) 5.55 +{ 5.56 +} 5.57 + 5.58 +void set_mouse_cursor(int enable) 5.59 +{ 5.60 +} 5.61 + 5.62 +static void handle_command(struct android_app *app, int32_t cmd) 5.63 +{ 5.64 + switch(cmd) { 5.65 + case APP_CMD_SAVE_STATE: 5.66 + /* save the application state to be reloaded on restart if needed */ 5.67 + break; 5.68 + 5.69 + case APP_CMD_INIT_WINDOW: 5.70 + if(init_gl() == -1) { 5.71 + exit(1); 5.72 + } 5.73 + /* initialize the application */ 5.74 + if(game_init() == -1) { 5.75 + exit(1); /* initialization failed, quit */ 5.76 + } 5.77 + break; 5.78 + 5.79 + case APP_CMD_TERM_WINDOW: 5.80 + /* cleanup */ 5.81 + game_shutdown(); 5.82 + destroy_gl(); 5.83 + break; 5.84 + 5.85 + case APP_CMD_GAINED_FOCUS: 5.86 + /* app focused */ 5.87 + break; 5.88 + 5.89 + case APP_CMD_LOST_FOCUS: 5.90 + /* app lost focus */ 5.91 + break; 5.92 + 5.93 + case APP_CMD_WINDOW_RESIZED: 5.94 + case APP_CMD_CONFIG_CHANGED: 5.95 + { 5.96 + int nx = ANativeWindow_getWidth(app->window); 5.97 + int ny = ANativeWindow_getHeight(app->window); 5.98 + if(nx != win_width || ny != win_height) { 5.99 + game_reshape(nx, ny); 5.100 + win_width = nx; 5.101 + win_height = ny; 5.102 + } 5.103 + } 5.104 + break; 5.105 + 5.106 + default: 5.107 + break; 5.108 + } 5.109 +} 5.110 + 5.111 +static int handle_input(struct android_app *app, AInputEvent *ev) 5.112 +{ 5.113 + int evtype = AInputEvent_getType(ev); 5.114 + 5.115 + switch(evtype) { 5.116 + case AINPUT_EVENT_TYPE_MOTION: 5.117 + return handle_touch_input(app, ev); 5.118 + 5.119 + default: 5.120 + break; 5.121 + } 5.122 + return 0; 5.123 +} 5.124 + 5.125 +#define MAX_TOUCH_IDS 32 5.126 + 5.127 +static int handle_touch_input(struct android_app *app, AInputEvent *ev) 5.128 +{ 5.129 + int x, y, idx, touch_id; 5.130 + unsigned int action; 5.131 + static int prev_pos[MAX_TOUCH_IDS][2]; 5.132 + 5.133 + action = AMotionEvent_getAction(ev); 5.134 + 5.135 + idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> 5.136 + AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 5.137 + touch_id = AMotionEvent_getPointerId(ev, idx); 5.138 + 5.139 + x = AMotionEvent_getX(ev, idx); 5.140 + y = AMotionEvent_getY(ev, idx); 5.141 + 5.142 + switch(action & AMOTION_EVENT_ACTION_MASK) { 5.143 + case AMOTION_EVENT_ACTION_DOWN: 5.144 + case AMOTION_EVENT_ACTION_POINTER_DOWN: 5.145 + game_mouse_button(touch_id, 0, 1, x, y); 5.146 + if(touch_id < MAX_TOUCH_IDS) { 5.147 + prev_pos[touch_id][0] = x; 5.148 + prev_pos[touch_id][1] = y; 5.149 + } 5.150 + break; 5.151 + 5.152 + case AMOTION_EVENT_ACTION_UP: 5.153 + case AMOTION_EVENT_ACTION_POINTER_UP: 5.154 + game_mouse_button(touch_id, 0, 0, x, y); 5.155 + if(touch_id < MAX_TOUCH_IDS) { 5.156 + prev_pos[touch_id][0] = x; 5.157 + prev_pos[touch_id][1] = y; 5.158 + } 5.159 + break; 5.160 + 5.161 + case AMOTION_EVENT_ACTION_MOVE: 5.162 + { 5.163 + int i, pcount = AMotionEvent_getPointerCount(ev); 5.164 + for(i=0; i<pcount; i++) { 5.165 + int id = AMotionEvent_getPointerId(ev, i); 5.166 + if(id < MAX_TOUCH_IDS && x != prev_pos[id][0] && y != prev_pos[id][1]) { 5.167 + game_mouse_motion(id, x, y); 5.168 + prev_pos[id][0] = x; 5.169 + prev_pos[id][1] = y; 5.170 + } 5.171 + } 5.172 + } 5.173 + break; 5.174 + 5.175 + default: 5.176 + break; 5.177 + } 5.178 + 5.179 + return 1; 5.180 +} 5.181 + 5.182 + 5.183 +static int init_gl(void) 5.184 +{ 5.185 + static const int eglattr[] = { 5.186 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 5.187 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, 5.188 + EGL_RED_SIZE, 5, 5.189 + EGL_GREEN_SIZE, 5, 5.190 + EGL_BLUE_SIZE, 5, 5.191 + EGL_DEPTH_SIZE, 16, 5.192 + EGL_NONE 5.193 + }; 5.194 + static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; 5.195 + 5.196 + EGLConfig eglcfg; 5.197 + int count, vis; 5.198 + 5.199 + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 5.200 + if(!dpy || !eglInitialize(dpy, 0, 0)) { 5.201 + fprintf(stderr, "failed to initialize EGL\n"); 5.202 + destroy_gl(); 5.203 + return -1; 5.204 + } 5.205 + 5.206 + if(!eglChooseConfig(dpy, eglattr, &eglcfg, 1, &count)) { 5.207 + fprintf(stderr, "no matching EGL config found\n"); 5.208 + destroy_gl(); 5.209 + return -1; 5.210 + } 5.211 + 5.212 + /* configure the native window visual according to the chosen EGL config */ 5.213 + eglGetConfigAttrib(dpy, &eglcfg, EGL_NATIVE_VISUAL_ID, &vis); 5.214 + ANativeWindow_setBuffersGeometry(app->window, 0, 0, vis); 5.215 + 5.216 + if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) { 5.217 + fprintf(stderr, "failed to create window\n"); 5.218 + destroy_gl(); 5.219 + return -1; 5.220 + } 5.221 + 5.222 + if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) { 5.223 + fprintf(stderr, "failed to create OpenGL ES context\n"); 5.224 + destroy_gl(); 5.225 + return -1; 5.226 + } 5.227 + eglMakeCurrent(dpy, surf, surf, ctx); 5.228 + 5.229 + eglQuerySurface(dpy, surf, EGL_WIDTH, &win_width); 5.230 + eglQuerySurface(dpy, surf, EGL_HEIGHT, &win_height); 5.231 + game_reshape(win_width, win_height); 5.232 + 5.233 + return 0; 5.234 +} 5.235 + 5.236 +static void destroy_gl(void) 5.237 +{ 5.238 + if(!dpy) return; 5.239 + 5.240 + eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 5.241 + 5.242 + if(ctx) { 5.243 + eglDestroyContext(dpy, ctx); 5.244 + ctx = 0; 5.245 + } 5.246 + if(surf) { 5.247 + eglDestroySurface(dpy, surf); 5.248 + surf = 0; 5.249 + } 5.250 + 5.251 + eglTerminate(dpy); 5.252 + dpy = 0; 5.253 +} 5.254 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/android/logger.c Fri May 01 04:36:50 2015 +0300 6.3 @@ -0,0 +1,60 @@ 6.4 +#include <stdio.h> 6.5 +#include <assert.h> 6.6 +#include <unistd.h> 6.7 +#include <pthread.h> 6.8 +#include <android/log.h> 6.9 +#include "logger.h" 6.10 + 6.11 +static void *thread_func(void *arg); 6.12 + 6.13 +static int pfd[2]; 6.14 +static pthread_t thr; 6.15 +static int initialized; 6.16 + 6.17 +int start_logger(void) 6.18 +{ 6.19 + if(initialized) { 6.20 + return 1; 6.21 + } 6.22 + 6.23 + /* set stdout to line-buffered, and stderr to unbuffered */ 6.24 + setvbuf(stdout, 0, _IOLBF, 0); 6.25 + setvbuf(stderr, 0, _IONBF, 0); 6.26 + 6.27 + if(pipe(pfd) == -1) { 6.28 + perror("failed to create logging pipe"); 6.29 + return -1; 6.30 + } 6.31 + assert(pfd[0] > 2 && pfd[1] > 2); 6.32 + 6.33 + /* redirect stdout & stderr to the write-end of the pipe */ 6.34 + dup2(pfd[1], 1); 6.35 + dup2(pfd[1], 2); 6.36 + 6.37 + /* start the logging thread */ 6.38 + if(pthread_create(&thr, 0, thread_func, 0) == -1) { 6.39 + perror("failed to spawn logging thread"); 6.40 + return -1; 6.41 + } 6.42 + pthread_detach(thr); 6.43 + return 0; 6.44 +} 6.45 + 6.46 +static void *thread_func(void *arg) 6.47 +{ 6.48 + ssize_t rdsz; 6.49 + char buf[257]; 6.50 + 6.51 + __android_log_print(ANDROID_LOG_DEBUG, APP_NAME, "logger starting up..."); 6.52 + 6.53 + while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) { 6.54 + if(buf[rdsz - 1] == '\n') { 6.55 + --rdsz; 6.56 + } 6.57 + buf[rdsz] = 0; 6.58 + __android_log_write(ANDROID_LOG_DEBUG, APP_NAME, buf); 6.59 + } 6.60 + 6.61 + __android_log_print(ANDROID_LOG_DEBUG, APP_NAME, "logger shutting down..."); 6.62 + return 0; 6.63 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/android/logger.h Fri May 01 04:36:50 2015 +0300 7.3 @@ -0,0 +1,6 @@ 7.4 +#ifndef LOGGER_H_ 7.5 +#define LOGGER_H_ 7.6 + 7.7 +int start_logger(void); 7.8 + 7.9 +#endif /* LOGGER_H_ */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/game.c Fri May 01 04:36:50 2015 +0300 8.3 @@ -0,0 +1,356 @@ 8.4 +#include <stdio.h> 8.5 +#include <stdlib.h> 8.6 +#include <math.h> 8.7 +#include "opengl.h" 8.8 +#include "game.h" 8.9 +#include "player.h" 8.10 +#include "level.h" 8.11 +#include "noise.h" 8.12 +#include "texture.h" 8.13 +#include "mesh.h" 8.14 + 8.15 +#define PLAYER_EYE_HEIGHT 1.65 8.16 + 8.17 +static void draw_scene(unsigned long msec); 8.18 + 8.19 +static int win_width, win_height; 8.20 +static struct level level; 8.21 +static struct player player; 8.22 +static int mouselook, freelook = 1; 8.23 +static char keystate[256]; 8.24 + 8.25 +static struct mesh *monkey_mesh; 8.26 +static unsigned int envmap; 8.27 +static unsigned int win_tex; 8.28 + 8.29 +static int game_won; 8.30 + 8.31 +static float dbg_cam_dist = 0.0; 8.32 + 8.33 + 8.34 +int game_init(void) 8.35 +{ 8.36 + glEnable(GL_DEPTH_TEST); 8.37 + glEnable(GL_CULL_FACE); 8.38 + glEnable(GL_LIGHTING); 8.39 + glEnable(GL_NORMALIZE); 8.40 + 8.41 + glEnable(GL_LIGHT0); 8.42 + glEnable(GL_LIGHT1); 8.43 + 8.44 + /* set a slightly bluish cold ambient light */ 8.45 + { 8.46 + float ambient[] = {0.08, 0.1, 0.3, 1.0}; 8.47 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); 8.48 + } 8.49 + 8.50 + level_init(&level); 8.51 + if(level_load(&level, "data/0.level") == -1) { 8.52 + fprintf(stderr, "level loading failed\n"); 8.53 + return -1; 8.54 + } 8.55 + 8.56 + if(!(level.wall_tex = load_texture("data/wall.ppm"))) { 8.57 + return -1; 8.58 + } 8.59 + if(!(level.floor_tex = load_texture("data/floor.ppm"))) { 8.60 + return -1; 8.61 + } 8.62 + level.floor_tex_scale = 1.0; 8.63 + if(!(level.ceil_tex = load_texture("data/ceil.ppm"))) { 8.64 + return -1; 8.65 + } 8.66 + level.ceil_tex_scale = 2.0; 8.67 + 8.68 + 8.69 + if(!(monkey_mesh = load_mesh("data/monkey.obj"))) { 8.70 + return -1; 8.71 + } 8.72 + if(!(envmap = load_texture("data/refmap.ppm"))) { 8.73 + return -1; 8.74 + } 8.75 + 8.76 + if(!(win_tex = load_texture("data/done.ppm"))) { 8.77 + return -1; 8.78 + } 8.79 + 8.80 + player_init(&player, &level); 8.81 + return 0; 8.82 +} 8.83 + 8.84 +void game_shutdown(void) 8.85 +{ 8.86 +} 8.87 + 8.88 +static void update(unsigned long msec) 8.89 +{ 8.90 + static unsigned long prev_upd; 8.91 + float dfwd = 0.0f; 8.92 + float dright = 0.0f; 8.93 + float walk_speed = 8.0; 8.94 + 8.95 + float dt = (float)(msec - prev_upd) / 1000.0f; 8.96 + prev_upd = msec; 8.97 + 8.98 + if(game_won) return; 8.99 + 8.100 + if(freelook) { 8.101 + if(keystate['w'] || keystate['W']) { 8.102 + dfwd += walk_speed * dt; 8.103 + } 8.104 + if(keystate['s'] || keystate['S']) { 8.105 + dfwd -= walk_speed * dt; 8.106 + } 8.107 + if(keystate['d'] || keystate['D']) { 8.108 + dright += walk_speed * dt * 0.6; 8.109 + } 8.110 + if(keystate['a'] || keystate['A']) { 8.111 + dright -= walk_speed * dt * 0.6; 8.112 + } 8.113 + 8.114 + player_move(&player, dfwd, dright); 8.115 + } 8.116 + 8.117 + if(level_cell_at(&level, player.x, player.y) == 'x') { 8.118 + game_won = 1; 8.119 + } 8.120 +} 8.121 + 8.122 +void game_display(unsigned long msec) 8.123 +{ 8.124 + float flicker = 1.0f; 8.125 + 8.126 + update(msec); 8.127 + 8.128 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 8.129 + 8.130 + glMatrixMode(GL_MODELVIEW); 8.131 + glLoadIdentity(); 8.132 + glTranslatef(0, 0, -dbg_cam_dist); 8.133 + /* set view matrix according to player pos/rot */ 8.134 + player_setup_view_matrix(&player); 8.135 + glTranslatef(0, -PLAYER_EYE_HEIGHT, 0); 8.136 + 8.137 + /* setup lights */ 8.138 + flicker = fbm1((float)msec / 500.0f, 2) * 0.4 + 0.6; 8.139 + set_light_position(0, player.x, PLAYER_EYE_HEIGHT + 0.2, player.y); 8.140 + set_light_color(0, 1.0 * flicker, 0.6 * flicker, 0.3 * flicker); 8.141 + set_light_attenuation(0, 0.5, 0, 0.04); 8.142 + 8.143 + set_light_position(1, level.goal_pos[0], 0.8, level.goal_pos[1]); 8.144 + set_light_color(1, 0.955, 0.75, 0.06); 8.145 + set_light_attenuation(1, 0.9, 0, 0.05); 8.146 + 8.147 + /* draw the scene */ 8.148 + draw_scene(msec); 8.149 +} 8.150 + 8.151 +void game_reshape(int x, int y) 8.152 +{ 8.153 + win_width = x; 8.154 + win_height = y; 8.155 + glViewport(0, 0, x, y); 8.156 + glMatrixMode(GL_PROJECTION); 8.157 + glLoadIdentity(); 8.158 + gluPerspective(55.0, (float)x / (float)y, 0.5, 500.0); 8.159 +} 8.160 + 8.161 + 8.162 +static void draw_scene(unsigned long msec) 8.163 +{ 8.164 + float x, y; 8.165 + float tsec = (float)msec / 1000.0f; 8.166 + 8.167 + level_draw(&level); 8.168 + 8.169 + /* draw the golden monkey */ 8.170 + if(level_obj_pos(&level, 'x', &x, &y)) { 8.171 + /* TODO: GLES doesn't have tex-gen... recalc manually */ 8.172 +#ifndef GL_MOBILE 8.173 + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 8.174 + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 8.175 + glEnable(GL_TEXTURE_GEN_S); 8.176 + glEnable(GL_TEXTURE_GEN_T); 8.177 + 8.178 + glBindTexture(GL_TEXTURE_2D, envmap); 8.179 + glEnable(GL_TEXTURE_2D); 8.180 +#endif 8.181 + 8.182 + set_mtl_diffuse(0.1, 0.1, 0.1, 1); 8.183 + set_mtl_specular(0.955, 0.75, 0.06); 8.184 + set_mtl_shininess(80.0); 8.185 + set_mtl_emission(0.955, 0.75 * 0.7, 0.06 * 0.1); 8.186 + 8.187 + glMatrixMode(GL_MODELVIEW); 8.188 + glPushMatrix(); 8.189 + glTranslatef(x, 0.8 + sin(tsec * 2.0) * 0.1, y); 8.190 + glRotatef(tsec * 100.0, 0, 1, 0); 8.191 + glRotatef(sin(tsec * 3.0) * 10.0, 1, 0, 0); 8.192 + glScalef(0.3, 0.3, 0.3); 8.193 + 8.194 + render_mesh(monkey_mesh); 8.195 + 8.196 + glPopMatrix(); 8.197 + 8.198 + set_mtl_emission(0, 0, 0); 8.199 + 8.200 +#ifndef GL_MOBILE 8.201 + glDisable(GL_TEXTURE_2D); 8.202 + 8.203 + glDisable(GL_TEXTURE_GEN_S); 8.204 + glDisable(GL_TEXTURE_GEN_T); 8.205 +#endif 8.206 + } 8.207 + 8.208 + /* draw the win text */ 8.209 + if(game_won) { 8.210 + glMatrixMode(GL_MODELVIEW); 8.211 + glPushMatrix(); 8.212 + glLoadIdentity(); 8.213 + glMatrixMode(GL_PROJECTION); 8.214 + glPushMatrix(); 8.215 + glLoadIdentity(); 8.216 + glScalef((float)win_height / (float)win_width, 1, 1); 8.217 + 8.218 + glBindTexture(GL_TEXTURE_2D, win_tex); 8.219 + glEnable(GL_TEXTURE_2D); 8.220 + 8.221 + glEnable(GL_BLEND); 8.222 + glBlendFunc(GL_ONE, GL_ONE); 8.223 + glDisable(GL_LIGHTING); 8.224 + 8.225 + glBegin(GL_QUADS); 8.226 + glTexCoord2f(0, 1); glVertex2f(-1, -1); 8.227 + glTexCoord2f(1, 1); glVertex2f(1, -1); 8.228 + glTexCoord2f(1, 0); glVertex2f(1, 1); 8.229 + glTexCoord2f(0, 0); glVertex2f(-1, 1); 8.230 + glEnd(); 8.231 + 8.232 + glDisable(GL_BLEND); 8.233 + glDisable(GL_TEXTURE_2D); 8.234 + glEnable(GL_LIGHTING); 8.235 + 8.236 + glPopMatrix(); 8.237 + glMatrixMode(GL_MODELVIEW); 8.238 + glPopMatrix(); 8.239 + } 8.240 +} 8.241 + 8.242 +static int warping_mouse; 8.243 + 8.244 +void game_keyboard(int key, int pressed) 8.245 +{ 8.246 + keystate[key] = pressed; 8.247 + 8.248 + if(!pressed) return; 8.249 + 8.250 + switch(key) { 8.251 + case 27: 8.252 + exit(0); 8.253 + 8.254 + case 'a': 8.255 + if(!freelook && !game_won) { 8.256 + player_turn(&player, -90, 0); 8.257 + } 8.258 + break; 8.259 + 8.260 + case 'd': 8.261 + if(!freelook && !game_won) { 8.262 + player_turn(&player, 90, 0); 8.263 + } 8.264 + break; 8.265 + 8.266 + case 'w': 8.267 + case 's': 8.268 + if(!freelook && !game_won) { 8.269 + float prev_x = player.x; 8.270 + float prev_y = player.y; 8.271 + float sign = key == 'w' ? 1.0 : -1.0; 8.272 + 8.273 + if(!player_move(&player, level.cell_size * sign, 0)) { 8.274 + player.x = prev_x; 8.275 + player.y = prev_y; 8.276 + } 8.277 + } 8.278 + break; 8.279 + 8.280 + case '`': 8.281 + case '~': 8.282 + mouselook = !mouselook; 8.283 + if(mouselook) { 8.284 + warping_mouse = 1; 8.285 + set_mouse_pos(win_width / 2, win_height / 2); 8.286 + set_mouse_cursor(0); 8.287 + } else { 8.288 + set_mouse_cursor(1); 8.289 + } 8.290 + break; 8.291 + 8.292 + case 'b': 8.293 + case 'B': 8.294 + freelook = !freelook; 8.295 + break; 8.296 + 8.297 + case 'r': 8.298 + case 'R': 8.299 + game_won = 0; 8.300 + player_init(&player, &level); 8.301 + break; 8.302 + 8.303 + default: 8.304 + break; 8.305 + } 8.306 +} 8.307 + 8.308 +#define MAX_TOUCH_IDS 16 8.309 +static struct { 8.310 + int bnstate[8]; 8.311 + int prev_x, prev_y; 8.312 +} mstate[MAX_TOUCH_IDS]; 8.313 + 8.314 +void game_mouse_button(int id, int bn, int pressed, int x, int y) 8.315 +{ 8.316 + if(id >= MAX_TOUCH_IDS) return; 8.317 + 8.318 + mstate[id].prev_x = x; 8.319 + mstate[id].prev_y = y; 8.320 + mstate[id].bnstate[bn] = pressed; 8.321 +} 8.322 + 8.323 +void game_mouse_motion(int id, int x, int y) 8.324 +{ 8.325 + int dx, dy, cx, cy; 8.326 + 8.327 + if(id >= MAX_TOUCH_IDS) return; 8.328 + 8.329 + cx = win_width / 2; 8.330 + cy = win_height / 2; 8.331 + 8.332 + if(warping_mouse) { 8.333 + warping_mouse = 0; 8.334 + return; 8.335 + } 8.336 + 8.337 + dx = x - (mouselook ? cx : mstate[id].prev_x); 8.338 + dy = y - (mouselook ? cy : mstate[id].prev_y); 8.339 + mstate[id].prev_x = x; 8.340 + mstate[id].prev_y = y; 8.341 + 8.342 + if(!dx && !dy) return; 8.343 + 8.344 + if(mouselook || mstate[id].bnstate[0]) { 8.345 + player_turn(&player, dx * 0.5, dy * 0.5); 8.346 + } 8.347 + if(mstate[id].bnstate[2]) { 8.348 + dbg_cam_dist += 0.1 * dy; 8.349 + if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; 8.350 + } 8.351 + 8.352 + if(mouselook) { 8.353 + warping_mouse = 1; 8.354 + set_mouse_pos(cx, cy); 8.355 + mstate[id].prev_x = cx; 8.356 + mstate[id].prev_y = cy; 8.357 + } 8.358 +} 8.359 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/game.h Fri May 01 04:36:50 2015 +0300 9.3 @@ -0,0 +1,19 @@ 9.4 +#ifndef GAME_H_ 9.5 +#define GAME_H_ 9.6 + 9.7 +int game_init(void); 9.8 +void game_shutdown(void); 9.9 + 9.10 +void game_display(unsigned long msec); 9.11 +void game_reshape(int x, int y); 9.12 + 9.13 +void game_keyboard(int key, int press); 9.14 +void game_mouse_button(int id, int bn, int press, int x, int y); 9.15 +void game_mouse_motion(int id, int x, int y); 9.16 + 9.17 +/* provided by the system frontend */ 9.18 +void set_mouse_pos(int x, int y); 9.19 +void set_mouse_cursor(int enable); 9.20 + 9.21 +#endif /* GAME_H_ */ 9.22 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/gles/sanegl.c Fri May 01 04:36:50 2015 +0300 10.3 @@ -0,0 +1,185 @@ 10.4 +/* 10.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x 10.6 +Copyright (C) 2011-2013 John Tsiombikas <nuclear@member.fsf.org> 10.7 + 10.8 +This program is free software: you can redistribute it and/or modify 10.9 +it under the terms of the GNU General Public License as published by 10.10 +the Free Software Foundation, either version 3 of the License, or 10.11 +(at your option) any later version. 10.12 + 10.13 +This program is distributed in the hope that it will be useful, 10.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 10.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.16 +GNU General Public License for more details. 10.17 + 10.18 +You should have received a copy of the GNU General Public License 10.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 10.20 +*/ 10.21 + 10.22 +#include <stdio.h> 10.23 +#include <stdlib.h> 10.24 +#include <string.h> 10.25 +#include <math.h> 10.26 +#include <assert.h> 10.27 +#include "sanegl.h" 10.28 + 10.29 +#define MAX_VERTS 512 10.30 + 10.31 +static void gl_draw_immediate(void); 10.32 + 10.33 +typedef struct { float x, y; } vec2_t; 10.34 +typedef struct { float x, y, z; } vec3_t; 10.35 +typedef struct { float x, y, z, w; } vec4_t; 10.36 + 10.37 +static int prim = -1; 10.38 + 10.39 +static vec3_t cur_normal; 10.40 +static vec4_t cur_color; 10.41 +static vec2_t cur_texcoord; 10.42 + 10.43 +static vec4_t *vert_arr, *col_arr; 10.44 +static vec3_t *norm_arr; 10.45 +static vec2_t *texc_arr; 10.46 + 10.47 +static int num_verts, vert_calls; 10.48 + 10.49 +/* immediate mode rendering */ 10.50 +void gl_begin(int p) 10.51 +{ 10.52 + if(!vert_arr) { 10.53 + vert_arr = malloc(MAX_VERTS * sizeof *vert_arr); 10.54 + norm_arr = malloc(MAX_VERTS * sizeof *norm_arr); 10.55 + texc_arr = malloc(MAX_VERTS * sizeof *texc_arr); 10.56 + col_arr = malloc(MAX_VERTS * sizeof *col_arr); 10.57 + assert(vert_arr && norm_arr && texc_arr && col_arr); 10.58 + } 10.59 + 10.60 + prim = p; 10.61 + num_verts = vert_calls = 0; 10.62 +} 10.63 + 10.64 +void gl_end(void) 10.65 +{ 10.66 + if(num_verts > 0) { 10.67 + gl_draw_immediate(); 10.68 + } 10.69 +} 10.70 + 10.71 +static void gl_draw_immediate(void) 10.72 +{ 10.73 + int glprim; 10.74 + 10.75 + glprim = prim == GL_QUADS ? GL_TRIANGLES : prim; 10.76 + 10.77 + glEnableClientState(GL_VERTEX_ARRAY); 10.78 + glEnableClientState(GL_NORMAL_ARRAY); 10.79 + glEnableClientState(GL_COLOR_ARRAY); 10.80 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 10.81 + 10.82 + glVertexPointer(4, GL_FLOAT, 0, vert_arr); 10.83 + glNormalPointer(GL_FLOAT, 0, norm_arr); 10.84 + glColorPointer(4, GL_FLOAT, 0, col_arr); 10.85 + glTexCoordPointer(2, GL_FLOAT, 0, texc_arr); 10.86 + 10.87 + glDrawArrays(glprim, 0, num_verts); 10.88 + 10.89 + glDisableClientState(GL_VERTEX_ARRAY); 10.90 + glDisableClientState(GL_NORMAL_ARRAY); 10.91 + glDisableClientState(GL_COLOR_ARRAY); 10.92 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 10.93 +} 10.94 + 10.95 +void gl_vertex2f(float x, float y) 10.96 +{ 10.97 + gl_vertex4f(x, y, 0.0f, 1.0f); 10.98 +} 10.99 + 10.100 +void gl_vertex3f(float x, float y, float z) 10.101 +{ 10.102 + gl_vertex4f(x, y, z, 1.0f); 10.103 +} 10.104 + 10.105 +void gl_vertex4f(float x, float y, float z, float w) 10.106 +{ 10.107 + int i, buffer_full; 10.108 + 10.109 + if(prim == GL_QUADS && vert_calls % 4 == 3) { 10.110 + for(i=0; i<2; i++) { 10.111 + col_arr[num_verts] = col_arr[num_verts - 3 + i]; 10.112 + texc_arr[num_verts] = texc_arr[num_verts - 3 + i]; 10.113 + norm_arr[num_verts] = norm_arr[num_verts - 3 + i]; 10.114 + vert_arr[num_verts] = vert_arr[num_verts - 3 + i]; 10.115 + num_verts++; 10.116 + } 10.117 + } 10.118 + 10.119 + vert_arr[num_verts].x = x; 10.120 + vert_arr[num_verts].y = y; 10.121 + vert_arr[num_verts].z = z; 10.122 + vert_arr[num_verts].w = w; 10.123 + 10.124 + col_arr[num_verts] = cur_color; 10.125 + norm_arr[num_verts] = cur_normal; 10.126 + texc_arr[num_verts] = cur_texcoord; 10.127 + 10.128 + vert_calls++; 10.129 + num_verts++; 10.130 + 10.131 + if(prim == GL_QUADS) { 10.132 + /* leave space for 6 more worst-case and don't allow flushes mid-quad */ 10.133 + buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0; 10.134 + } else { 10.135 + buffer_full = num_verts >= MAX_VERTS - prim; 10.136 + } 10.137 + 10.138 + if(buffer_full) { 10.139 + gl_draw_immediate(); 10.140 + gl_begin(prim); /* reset everything */ 10.141 + } 10.142 +} 10.143 + 10.144 + 10.145 +void gl_normal3f(float x, float y, float z) 10.146 +{ 10.147 + cur_normal.x = x; 10.148 + cur_normal.y = y; 10.149 + cur_normal.z = z; 10.150 +} 10.151 + 10.152 + 10.153 +void gl_color3f(float r, float g, float b) 10.154 +{ 10.155 + cur_color.x = r; 10.156 + cur_color.y = g; 10.157 + cur_color.z = b; 10.158 + cur_color.w = 1.0f; 10.159 +} 10.160 + 10.161 +void gl_color4f(float r, float g, float b, float a) 10.162 +{ 10.163 + cur_color.x = r; 10.164 + cur_color.y = g; 10.165 + cur_color.z = b; 10.166 + cur_color.w = a; 10.167 +} 10.168 + 10.169 + 10.170 +void gl_texcoord1f(float s) 10.171 +{ 10.172 + cur_texcoord.x = s; 10.173 + cur_texcoord.y = 0.0f; 10.174 +} 10.175 + 10.176 +void gl_texcoord2f(float s, float t) 10.177 +{ 10.178 + cur_texcoord.x = s; 10.179 + cur_texcoord.y = t; 10.180 +} 10.181 + 10.182 +void glu_perspective(float fov, float aspect, float nearz, float farz) 10.183 +{ 10.184 + float fovrad = M_PI * fov / 180.0; 10.185 + float halfsz = tan(fovrad) * nearz; 10.186 + 10.187 + glFrustumf(-halfsz * aspect, halfsz * aspect, -halfsz, halfsz, nearz, farz); 10.188 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/gles/sanegl.h Fri May 01 04:36:50 2015 +0300 11.3 @@ -0,0 +1,96 @@ 11.4 +/* 11.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x 11.6 +Copyright (C) 2011-2013 John Tsiombikas <nuclear@member.fsf.org> 11.7 + 11.8 +This program is free software: you can redistribute it and/or modify 11.9 +it under the terms of the GNU General Public License as published by 11.10 +the Free Software Foundation, either version 3 of the License, or 11.11 +(at your option) any later version. 11.12 + 11.13 +This program is distributed in the hope that it will be useful, 11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.16 +GNU General Public License for more details. 11.17 + 11.18 +You should have received a copy of the GNU General Public License 11.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 11.20 +*/ 11.21 + 11.22 +#ifndef SANEGL_H_ 11.23 +#define SANEGL_H_ 11.24 + 11.25 +#include "opengl.h" 11.26 + 11.27 +#ifndef GL_POINTS 11.28 +#define GL_POINTS 0 11.29 +#endif 11.30 +#ifndef GL_LINES 11.31 +#define GL_LINES 1 11.32 +#endif 11.33 +#ifndef GL_TRIANGLES 11.34 +#define GL_TRIANGLES 4 11.35 +#endif 11.36 +#ifndef GL_QUADS 11.37 +#define GL_QUADS 7 11.38 +#endif 11.39 + 11.40 +/* glGet stuff */ 11.41 +#ifndef GL_VIEWPORT 11.42 +#define GL_VIEWPORT 0x0BA2 11.43 +#endif 11.44 +#ifndef GL_MODELVIEW_MATRIX 11.45 +#define GL_MODELVIEW_MATRIX 0x0BA6 11.46 +#endif 11.47 +#ifndef GL_PROJECTION_MATRIX 11.48 +#define GL_PROJECTION_MATRIX 0x0BA7 11.49 +#endif 11.50 + 11.51 +#ifdef GLDEF 11.52 + 11.53 +#define glBegin gl_begin 11.54 +#define glEnd gl_end 11.55 +#define glVertex2f gl_vertex2f 11.56 +#define glVertex3f gl_vertex3f 11.57 +#define glVertex4f gl_vertex4f 11.58 +#define glNormal3f gl_normal3f 11.59 +#define glColor3f gl_color3f 11.60 +#define glColor4f gl_color4f 11.61 +#define glTexCoord1f gl_texcoord1f 11.62 +#define glTexCoord2f gl_texcoord2f 11.63 +#define glVertexAttrib2f gl_vertex_attrib2f 11.64 +#define glVertexAttrib3f gl_vertex_attrib3f 11.65 +#define glVertexAttrib4f gl_vertex_attrib4f 11.66 + 11.67 +#define gluPerspective glu_perspective 11.68 + 11.69 +#endif /* GLDEF */ 11.70 + 11.71 +#ifdef __cplusplus 11.72 +extern "C" { 11.73 +#endif 11.74 + 11.75 +/* immediate mode rendering */ 11.76 +void gl_begin(int prim); 11.77 +void gl_end(void); 11.78 + 11.79 +void gl_vertex2f(float x, float y); 11.80 +void gl_vertex3f(float x, float y, float z); 11.81 +void gl_vertex4f(float x, float y, float z, float w); 11.82 + 11.83 +void gl_normal3f(float x, float y, float z); 11.84 + 11.85 +void gl_color3f(float r, float g, float b); 11.86 +void gl_color4f(float r, float g, float b, float a); 11.87 + 11.88 +void gl_texcoord1f(float s); 11.89 +void gl_texcoord2f(float s, float t); 11.90 + 11.91 +/* GLU */ 11.92 + 11.93 +void glu_perspective(float fov, float aspect, float nearz, float farz); 11.94 + 11.95 +#ifdef __cplusplus 11.96 +} 11.97 +#endif 11.98 + 11.99 +#endif /* SANEGL_H_ */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/glut/main.c Fri May 01 04:36:50 2015 +0300 12.3 @@ -0,0 +1,94 @@ 12.4 +#include <stdio.h> 12.5 +#include <stdlib.h> 12.6 +#include <math.h> 12.7 +#include <assert.h> 12.8 +#include "opengl.h" 12.9 + 12.10 +#ifdef __APPLE__ 12.11 +#include <GLUT/glut.h> 12.12 +#else 12.13 +#include <GL/glut.h> 12.14 +#endif 12.15 + 12.16 +#include "game.h" 12.17 + 12.18 +static void display(void); 12.19 +static void idle(void); 12.20 +static void reshape(int x, int y); 12.21 +static void key_down(unsigned char key, int x, int y); 12.22 +static void key_up(unsigned char key, int x, int y); 12.23 +static void mouse(int bn, int state, int x, int y); 12.24 +static void motion(int x, int y); 12.25 + 12.26 +int main(int argc, char **argv) 12.27 +{ 12.28 + glutInit(&argc, argv); 12.29 + glutInitWindowSize(1280, 800); 12.30 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 12.31 + glutCreateWindow("labyrinth game example"); 12.32 + 12.33 + glutDisplayFunc(display); 12.34 + glutIdleFunc(idle); 12.35 + glutReshapeFunc(reshape); 12.36 + glutKeyboardFunc(key_down); 12.37 + glutKeyboardUpFunc(key_up); 12.38 + glutMouseFunc(mouse); 12.39 + glutMotionFunc(motion); 12.40 + glutPassiveMotionFunc(motion); 12.41 + 12.42 + glewInit(); 12.43 + 12.44 + if(game_init() == -1) { 12.45 + return 1; 12.46 + } 12.47 + glutMainLoop(); 12.48 + return 0; 12.49 +} 12.50 + 12.51 +void set_mouse_pos(int x, int y) 12.52 +{ 12.53 + glutWarpPointer(x, y); 12.54 +} 12.55 + 12.56 +void set_mouse_cursor(int enable) 12.57 +{ 12.58 + glutSetCursor(enable ? GLUT_CURSOR_INHERIT : GLUT_CURSOR_NONE); 12.59 +} 12.60 + 12.61 +static void display(void) 12.62 +{ 12.63 + game_display(glutGet(GLUT_ELAPSED_TIME)); 12.64 + 12.65 + glutSwapBuffers(); 12.66 + assert(glGetError() == GL_NO_ERROR); 12.67 +} 12.68 + 12.69 +static void idle(void) 12.70 +{ 12.71 + glutPostRedisplay(); 12.72 +} 12.73 + 12.74 +static void reshape(int x, int y) 12.75 +{ 12.76 + game_reshape(x, y); 12.77 +} 12.78 + 12.79 +static void key_down(unsigned char key, int x, int y) 12.80 +{ 12.81 + game_keyboard(key, 1); 12.82 +} 12.83 + 12.84 +static void key_up(unsigned char key, int x, int y) 12.85 +{ 12.86 + game_keyboard(key, 0); 12.87 +} 12.88 + 12.89 +static void mouse(int bn, int state, int x, int y) 12.90 +{ 12.91 + game_mouse_button(0, bn - GLUT_LEFT_BUTTON, state == GLUT_DOWN ? 1 : 0, x, y); 12.92 +} 12.93 + 12.94 +static void motion(int x, int y) 12.95 +{ 12.96 + game_mouse_motion(0, x, y); 12.97 +}
13.1 --- a/src/main.c Mon Apr 27 05:37:17 2015 +0300 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,382 +0,0 @@ 13.4 -#include <stdio.h> 13.5 -#include <stdlib.h> 13.6 -#include <math.h> 13.7 -#include <assert.h> 13.8 -#include "opengl.h" 13.9 -#include "player.h" 13.10 -#include "level.h" 13.11 -#include "noise.h" 13.12 -#include "texture.h" 13.13 -#include "mesh.h" 13.14 - 13.15 -#define PLAYER_EYE_HEIGHT 1.65 13.16 - 13.17 -static int init(void); 13.18 -static void update(unsigned int msec); 13.19 -static void display(void); 13.20 -static void draw_scene(unsigned int msec); 13.21 -static void idle(void); 13.22 -static void reshape(int x, int y); 13.23 -static void key_down(unsigned char key, int x, int y); 13.24 -static void key_up(unsigned char key, int x, int y); 13.25 -static void mouse(int bn, int state, int x, int y); 13.26 -static void motion(int x, int y); 13.27 - 13.28 -static int win_width, win_height; 13.29 -static struct level level; 13.30 -static struct player player; 13.31 -static int mouselook, freelook = 1; 13.32 -static char keystate[256]; 13.33 - 13.34 -static struct mesh *monkey_mesh; 13.35 -static unsigned int envmap; 13.36 -static unsigned int win_tex; 13.37 - 13.38 -static int game_won; 13.39 - 13.40 -static float dbg_cam_dist = 0.0; 13.41 - 13.42 -int main(int argc, char **argv) 13.43 -{ 13.44 - glutInit(&argc, argv); 13.45 - glutInitWindowSize(1280, 800); 13.46 - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 13.47 - glutCreateWindow("labyrinth game example"); 13.48 - 13.49 - glutDisplayFunc(display); 13.50 - glutIdleFunc(idle); 13.51 - glutReshapeFunc(reshape); 13.52 - glutKeyboardFunc(key_down); 13.53 - glutKeyboardUpFunc(key_up); 13.54 - glutMouseFunc(mouse); 13.55 - glutMotionFunc(motion); 13.56 - 13.57 - if(init() == -1) { 13.58 - return 1; 13.59 - } 13.60 - glutMainLoop(); 13.61 - return 0; 13.62 -} 13.63 - 13.64 - 13.65 -static int init(void) 13.66 -{ 13.67 - glEnable(GL_DEPTH_TEST); 13.68 - glEnable(GL_CULL_FACE); 13.69 - glEnable(GL_LIGHTING); 13.70 - glEnable(GL_NORMALIZE); 13.71 - 13.72 - glEnable(GL_LIGHT0); 13.73 - glEnable(GL_LIGHT1); 13.74 - 13.75 - /* set a slightly bluish cold ambient light */ 13.76 - { 13.77 - float ambient[] = {0.08, 0.1, 0.3, 1.0}; 13.78 - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); 13.79 - } 13.80 - 13.81 - level_init(&level); 13.82 - if(level_load(&level, "data/0.level") == -1) { 13.83 - fprintf(stderr, "level loading failed\n"); 13.84 - return -1; 13.85 - } 13.86 - 13.87 - if(!(level.wall_tex = load_texture("data/wall.ppm"))) { 13.88 - return -1; 13.89 - } 13.90 - if(!(level.floor_tex = load_texture("data/floor.ppm"))) { 13.91 - return -1; 13.92 - } 13.93 - level.floor_tex_scale = 1.0; 13.94 - if(!(level.ceil_tex = load_texture("data/ceil.ppm"))) { 13.95 - return -1; 13.96 - } 13.97 - level.ceil_tex_scale = 2.0; 13.98 - 13.99 - 13.100 - if(!(monkey_mesh = load_mesh("data/monkey.obj"))) { 13.101 - return -1; 13.102 - } 13.103 - if(!(envmap = load_texture("data/refmap.ppm"))) { 13.104 - return -1; 13.105 - } 13.106 - 13.107 - if(!(win_tex = load_texture("data/done.ppm"))) { 13.108 - return -1; 13.109 - } 13.110 - 13.111 - player_init(&player, &level); 13.112 - return 0; 13.113 -} 13.114 - 13.115 -static void update(unsigned int msec) 13.116 -{ 13.117 - static unsigned int prev_upd; 13.118 - float dfwd = 0.0f; 13.119 - float dright = 0.0f; 13.120 - float walk_speed = 8.0; 13.121 - 13.122 - float dt = (float)(msec - prev_upd) / 1000.0f; 13.123 - prev_upd = msec; 13.124 - 13.125 - if(game_won) return; 13.126 - 13.127 - if(freelook) { 13.128 - if(keystate['w'] || keystate['W']) { 13.129 - dfwd += walk_speed * dt; 13.130 - } 13.131 - if(keystate['s'] || keystate['S']) { 13.132 - dfwd -= walk_speed * dt; 13.133 - } 13.134 - if(keystate['d'] || keystate['D']) { 13.135 - dright += walk_speed * dt * 0.6; 13.136 - } 13.137 - if(keystate['a'] || keystate['A']) { 13.138 - dright -= walk_speed * dt * 0.6; 13.139 - } 13.140 - 13.141 - player_move(&player, dfwd, dright); 13.142 - } 13.143 - 13.144 - if(level_cell_at(&level, player.x, player.y) == 'x') { 13.145 - game_won = 1; 13.146 - } 13.147 -} 13.148 - 13.149 -static void display(void) 13.150 -{ 13.151 - float flicker = 1.0f; 13.152 - unsigned int msec = glutGet(GLUT_ELAPSED_TIME); 13.153 - 13.154 - update(msec); 13.155 - 13.156 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 13.157 - 13.158 - glMatrixMode(GL_MODELVIEW); 13.159 - glLoadIdentity(); 13.160 - glTranslatef(0, 0, -dbg_cam_dist); 13.161 - /* set view matrix according to player pos/rot */ 13.162 - player_setup_view_matrix(&player); 13.163 - glTranslatef(0, -PLAYER_EYE_HEIGHT, 0); 13.164 - 13.165 - /* setup lights */ 13.166 - flicker = fbm1((float)msec / 500.0f, 2) * 0.4 + 0.6; 13.167 - set_light_position(0, player.x, PLAYER_EYE_HEIGHT + 0.2, player.y); 13.168 - set_light_color(0, 1.0 * flicker, 0.6 * flicker, 0.3 * flicker); 13.169 - set_light_attenuation(0, 0.5, 0, 0.04); 13.170 - 13.171 - set_light_position(1, level.goal_pos[0], 0.8, level.goal_pos[1]); 13.172 - set_light_color(1, 0.955, 0.75, 0.06); 13.173 - set_light_attenuation(1, 0.9, 0, 0.05); 13.174 - 13.175 - /* draw the scene */ 13.176 - draw_scene(msec); 13.177 - 13.178 - glutSwapBuffers(); 13.179 - assert(glGetError() == GL_NO_ERROR); 13.180 -} 13.181 - 13.182 -static void draw_scene(unsigned int msec) 13.183 -{ 13.184 - float x, y; 13.185 - float tsec = (float)msec / 1000.0f; 13.186 - 13.187 - level_draw(&level); 13.188 - 13.189 - /* draw the golden monkey */ 13.190 - if(level_obj_pos(&level, 'x', &x, &y)) { 13.191 - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 13.192 - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 13.193 - glEnable(GL_TEXTURE_GEN_S); 13.194 - glEnable(GL_TEXTURE_GEN_T); 13.195 - 13.196 - glBindTexture(GL_TEXTURE_2D, envmap); 13.197 - glEnable(GL_TEXTURE_2D); 13.198 - 13.199 - set_mtl_diffuse(0.1, 0.1, 0.1, 1); 13.200 - set_mtl_specular(0.955, 0.75, 0.06); 13.201 - set_mtl_shininess(80.0); 13.202 - set_mtl_emission(0.955, 0.75 * 0.7, 0.06 * 0.1); 13.203 - 13.204 - glMatrixMode(GL_MODELVIEW); 13.205 - glPushMatrix(); 13.206 - glTranslatef(x, 0.8 + sin(tsec * 2.0) * 0.1, y); 13.207 - glRotatef(tsec * 100.0, 0, 1, 0); 13.208 - glRotatef(sin(tsec * 3.0) * 10.0, 1, 0, 0); 13.209 - glScalef(0.3, 0.3, 0.3); 13.210 - 13.211 - render_mesh(monkey_mesh); 13.212 - 13.213 - glPopMatrix(); 13.214 - 13.215 - set_mtl_emission(0, 0, 0); 13.216 - 13.217 - glDisable(GL_TEXTURE_2D); 13.218 - 13.219 - glDisable(GL_TEXTURE_GEN_S); 13.220 - glDisable(GL_TEXTURE_GEN_T); 13.221 - } 13.222 - 13.223 - /* draw the win text */ 13.224 - if(game_won) { 13.225 - glMatrixMode(GL_MODELVIEW); 13.226 - glPushMatrix(); 13.227 - glLoadIdentity(); 13.228 - glMatrixMode(GL_PROJECTION); 13.229 - glPushMatrix(); 13.230 - glLoadIdentity(); 13.231 - glScalef((float)win_height / (float)win_width, 1, 1); 13.232 - 13.233 - glBindTexture(GL_TEXTURE_2D, win_tex); 13.234 - glEnable(GL_TEXTURE_2D); 13.235 - 13.236 - glEnable(GL_BLEND); 13.237 - glBlendFunc(GL_ONE, GL_ONE); 13.238 - glDisable(GL_LIGHTING); 13.239 - 13.240 - glBegin(GL_QUADS); 13.241 - glTexCoord2f(0, 1); glVertex2f(-1, -1); 13.242 - glTexCoord2f(1, 1); glVertex2f(1, -1); 13.243 - glTexCoord2f(1, 0); glVertex2f(1, 1); 13.244 - glTexCoord2f(0, 0); glVertex2f(-1, 1); 13.245 - glEnd(); 13.246 - 13.247 - glDisable(GL_BLEND); 13.248 - glDisable(GL_TEXTURE_2D); 13.249 - glEnable(GL_LIGHTING); 13.250 - 13.251 - glPopMatrix(); 13.252 - glMatrixMode(GL_MODELVIEW); 13.253 - glPopMatrix(); 13.254 - } 13.255 -} 13.256 - 13.257 -static void idle(void) 13.258 -{ 13.259 - glutPostRedisplay(); 13.260 -} 13.261 - 13.262 -static void reshape(int x, int y) 13.263 -{ 13.264 - win_width = x; 13.265 - win_height = y; 13.266 - glViewport(0, 0, x, y); 13.267 - glMatrixMode(GL_PROJECTION); 13.268 - glLoadIdentity(); 13.269 - gluPerspective(55.0, (float)x / (float)y, 0.5, 500.0); 13.270 -} 13.271 - 13.272 -static int warping_mouse; 13.273 - 13.274 -static void key_down(unsigned char key, int x, int y) 13.275 -{ 13.276 - keystate[key] = 1; 13.277 - 13.278 - switch(key) { 13.279 - case 27: 13.280 - exit(0); 13.281 - 13.282 - case 'a': 13.283 - if(!freelook && !game_won) { 13.284 - player_turn(&player, -90, 0); 13.285 - } 13.286 - break; 13.287 - 13.288 - case 'd': 13.289 - if(!freelook && !game_won) { 13.290 - player_turn(&player, 90, 0); 13.291 - } 13.292 - break; 13.293 - 13.294 - case 'w': 13.295 - case 's': 13.296 - if(!freelook && !game_won) { 13.297 - float prev_x = player.x; 13.298 - float prev_y = player.y; 13.299 - float sign = key == 'w' ? 1.0 : -1.0; 13.300 - 13.301 - if(!player_move(&player, level.cell_size * sign, 0)) { 13.302 - player.x = prev_x; 13.303 - player.y = prev_y; 13.304 - } 13.305 - } 13.306 - break; 13.307 - 13.308 - case '`': 13.309 - case '~': 13.310 - mouselook = !mouselook; 13.311 - if(mouselook) { 13.312 - warping_mouse = 1; 13.313 - glutWarpPointer(win_width / 2, win_height / 2); 13.314 - glutPassiveMotionFunc(motion); 13.315 - glutSetCursor(GLUT_CURSOR_NONE); 13.316 - } else { 13.317 - glutPassiveMotionFunc(0); 13.318 - glutSetCursor(GLUT_CURSOR_INHERIT); 13.319 - } 13.320 - break; 13.321 - 13.322 - case 'b': 13.323 - case 'B': 13.324 - freelook = !freelook; 13.325 - break; 13.326 - 13.327 - case 'r': 13.328 - case 'R': 13.329 - game_won = 0; 13.330 - player_init(&player, &level); 13.331 - break; 13.332 - 13.333 - default: 13.334 - break; 13.335 - } 13.336 -} 13.337 - 13.338 -static void key_up(unsigned char key, int x, int y) 13.339 -{ 13.340 - keystate[key] = 0; 13.341 -} 13.342 - 13.343 -static int bnstate[16]; 13.344 -static int prev_x, prev_y; 13.345 - 13.346 -static void mouse(int bn, int state, int x, int y) 13.347 -{ 13.348 - prev_x = x; 13.349 - prev_y = y; 13.350 - bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN ? 1 : 0; 13.351 -} 13.352 - 13.353 -static void motion(int x, int y) 13.354 -{ 13.355 - int dx, dy; 13.356 - int cx = win_width / 2; 13.357 - int cy = win_height / 2; 13.358 - 13.359 - if(warping_mouse) { 13.360 - warping_mouse = 0; 13.361 - return; 13.362 - } 13.363 - 13.364 - dx = x - (mouselook ? cx : prev_x); 13.365 - dy = y - (mouselook ? cy : prev_y); 13.366 - prev_x = x; 13.367 - prev_y = y; 13.368 - 13.369 - if(!dx && !dy) return; 13.370 - 13.371 - if(mouselook || bnstate[0]) { 13.372 - player_turn(&player, dx * 0.5, dy * 0.5); 13.373 - } 13.374 - if(bnstate[2]) { 13.375 - dbg_cam_dist += 0.1 * dy; 13.376 - if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; 13.377 - } 13.378 - 13.379 - if(mouselook) { 13.380 - warping_mouse = 1; 13.381 - glutWarpPointer(cx, cy); 13.382 - prev_x = cx; 13.383 - prev_y = cy; 13.384 - } 13.385 -}
14.1 --- a/src/mesh.c Mon Apr 27 05:37:17 2015 +0300 14.2 +++ b/src/mesh.c Fri May 01 04:36:50 2015 +0300 14.3 @@ -1,11 +1,5 @@ 14.4 -#ifdef __APPLE__ 14.5 -#include <GLUT/glut.h> 14.6 -#elif defined(WIN32) 14.7 -#include <glut.h> 14.8 -#else 14.9 -#include <GL/glut.h> 14.10 -#endif 14.11 - 14.12 +#include <stdlib.h> 14.13 +#include "opengl.h" 14.14 #include "mesh.h" 14.15 #include "objfile.h" 14.16
15.1 --- a/src/opengl.h Mon Apr 27 05:37:17 2015 +0300 15.2 +++ b/src/opengl.h Fri May 01 04:36:50 2015 +0300 15.3 @@ -1,11 +1,20 @@ 15.4 #ifndef OPENGL_H_ 15.5 #define OPENGL_H_ 15.6 15.7 -#ifdef __APPLE__ 15.8 -#include <GLUT/glut.h> 15.9 +#ifdef __ANDROID__ 15.10 +#include <GLES/gl.h> 15.11 +#include <GLES/glext.h> 15.12 +#include <EGL/egl.h> 15.13 + 15.14 +#define GL_MOBILE 15.15 + 15.16 #else 15.17 -#include <GL/glut.h> 15.18 -#endif 15.19 + 15.20 +#include <GL/glew.h> 15.21 + 15.22 +#define GL_DESKTOP 15.23 + 15.24 +#endif /* not __ANDROID__ */ 15.25 15.26 /* some helpers */ 15.27 15.28 @@ -18,4 +27,9 @@ 15.29 void set_mtl_shininess(float shin); 15.30 void set_mtl_emission(float r, float g, float b); 15.31 15.32 +#ifdef GL_MOBILE 15.33 +#define GLDEF 15.34 +#include "sanegl.h" 15.35 +#endif 15.36 + 15.37 #endif /* OPENGL_H_ */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/timer.c Fri May 01 04:36:50 2015 +0300 16.3 @@ -0,0 +1,71 @@ 16.4 +#include "timer.h" 16.5 + 16.6 +#if defined(__APPLE__) && !defined(__unix__) 16.7 +#define __unix__ 16.8 +#endif 16.9 + 16.10 +#ifdef __unix__ 16.11 +#include <time.h> 16.12 +#include <unistd.h> 16.13 +#include <sys/time.h> 16.14 + 16.15 +#ifdef CLOCK_MONOTONIC 16.16 +unsigned long get_time_msec(void) 16.17 +{ 16.18 + struct timespec ts; 16.19 + static struct timespec ts0; 16.20 + 16.21 + clock_gettime(CLOCK_MONOTONIC, &ts); 16.22 + if(ts0.tv_sec == 0 && ts0.tv_nsec == 0) { 16.23 + ts0 = ts; 16.24 + return 0; 16.25 + } 16.26 + return (ts.tv_sec - ts0.tv_sec) * 1000 + (ts.tv_nsec - ts0.tv_nsec) / 1000000; 16.27 +} 16.28 +#else /* no fancy POSIX clocks, fallback to good'ol gettimeofday */ 16.29 +unsigned long get_time_msec(void) 16.30 +{ 16.31 + struct timeval tv; 16.32 + static struct timeval tv0; 16.33 + 16.34 + gettimeofday(&tv, 0); 16.35 + if(tv0.tv_sec == 0 && tv0.tv_usec == 0) { 16.36 + tv0 = tv; 16.37 + return 0; 16.38 + } 16.39 + return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; 16.40 +} 16.41 +#endif /* !posix clock */ 16.42 + 16.43 +void sleep_msec(unsigned long msec) 16.44 +{ 16.45 + usleep(msec * 1000); 16.46 +} 16.47 +#endif 16.48 + 16.49 +#ifdef WIN32 16.50 +#include <windows.h> 16.51 +#pragma comment(lib, "winmm.lib") 16.52 + 16.53 +unsigned long get_time_msec(void) 16.54 +{ 16.55 + return timeGetTime(); 16.56 +} 16.57 + 16.58 +void sleep_msec(unsigned long msec) 16.59 +{ 16.60 + Sleep(msec); 16.61 +} 16.62 +#endif 16.63 + 16.64 +double get_time_sec(void) 16.65 +{ 16.66 + return get_time_msec() / 1000.0f; 16.67 +} 16.68 + 16.69 +void sleep_sec(double sec) 16.70 +{ 16.71 + if(sec > 0.0f) { 16.72 + sleep_msec(sec * 1000.0f); 16.73 + } 16.74 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/timer.h Fri May 01 04:36:50 2015 +0300 17.3 @@ -0,0 +1,10 @@ 17.4 +#ifndef TIMER_H_ 17.5 +#define TIMER_H_ 17.6 + 17.7 +unsigned long get_time_msec(void); 17.8 +void sleep_msec(unsigned long msec); 17.9 + 17.10 +double get_time_sec(void); 17.11 +void sleep_sec(double sec); 17.12 + 17.13 +#endif // TIMER_H_