From 4b27934867e00b541f31f65e04e5392bdba5d732 Mon Sep 17 00:00:00 2001 From: Spoike Date: Fri, 16 Sep 2011 05:56:54 +0000 Subject: [PATCH] Basic Android support. Icon resources still need to be replaced. No sound, no accelerometer. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3901 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 112 +++-- engine/client/cl_main.c | 4 +- engine/client/pr_csqc.c | 4 +- engine/client/pr_menu.c | 4 +- engine/client/sys_droid.c | 444 ++++++++++++++++++ engine/client/sys_win.c | 6 +- engine/common/bothdefs.h | 6 +- engine/common/fs.c | 6 +- engine/common/fs_stdio.c | 4 +- engine/common/sys.h | 2 +- engine/droid/AndroidManifest.xml | 20 + engine/droid/res/drawable-hdpi/icon.png | Bin 0 -> 4147 bytes engine/droid/res/drawable-ldpi/icon.png | Bin 0 -> 1723 bytes engine/droid/res/drawable-mdpi/icon.png | Bin 0 -> 2574 bytes engine/droid/res/values/strings.xml | 4 + .../droid/src/com/fteqw/FTEDroidActivity.java | 226 +++++++++ .../droid/src/com/fteqw/FTEDroidEngine.java | 14 + engine/gl/gl_backend.c | 5 + engine/gl/gl_draw.c | 107 ++++- engine/gl/gl_viddroid.c | 327 +++++++++++++ engine/gl/gl_vidnt.c | 6 +- engine/gl/glsupp.h | 11 + engine/server/sv_move.c | 2 +- 23 files changed, 1253 insertions(+), 61 deletions(-) create mode 100644 engine/client/sys_droid.c create mode 100644 engine/droid/AndroidManifest.xml create mode 100644 engine/droid/res/drawable-hdpi/icon.png create mode 100644 engine/droid/res/drawable-ldpi/icon.png create mode 100644 engine/droid/res/drawable-mdpi/icon.png create mode 100644 engine/droid/res/values/strings.xml create mode 100644 engine/droid/src/com/fteqw/FTEDroidActivity.java create mode 100644 engine/droid/src/com/fteqw/FTEDroidEngine.java create mode 100644 engine/gl/gl_viddroid.c diff --git a/engine/Makefile b/engine/Makefile index 48c07a71e..1aec84dcb 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -53,12 +53,16 @@ ifeq ($(FTE_TARGET),win32_sdl) FTE_TARGET=win32_SDL endif +DROID_NDK_PATH?=~/droid/android-ndk-r6b +DROID_SDK_PATH?=~/droid/android-sdk-linux_x86 ifeq ($(FTE_TARGET),droid) - - CC=~/droid/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -I ~/droid/android-ndk-r6b/platforms/android-9/arch-arm/usr/include/ -I ~/droid/android-ndk-r6b/sources/android/native_app_glue/ -DANDROID - STRIP=~/droid/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip - DO_LD=~/droid/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar -r $@ + NDK_PATH:=$(shell echo $(DROID_NDK_PATH)) + SDK_PATH:=$(shell echo $(DROID_SDK_PATH)) + + STRIP=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip + CC=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -I$(NDK_PATH)/platforms/android-8/arch-arm/usr/include/ -DANDROID + DO_LD=$(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack --sysroot=$(NDK_PATH)/platforms/android-8/arch-arm -L$(NDK_PATH)/platforms/android-8/arch-arm/usr/lib -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) -llog -lc -lz -lm endif #correct the gcc build when cross compiling @@ -293,7 +297,7 @@ DX7SDK=-I./libs/dxsdk7/include/ GLCFLAGS=-DGLQUAKE D3DCFLAGS=-DD3DQUAKE -NPQTVCFLAGS=-DNPQTV +NPFTECFLAGS=-DNPFTE CLIENT_OBJS = \ textedit.o \ @@ -499,18 +503,18 @@ else GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) `sdl-config --libs` endif GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags` -GLB_DIR=gl_sdl$(BITS) -GLCL_DIR=glcl_sdl$(BITS) +GLB_DIR=gl_sdl$(FTE_TARGET)$(BITS) +GLCL_DIR=glcl_sdl$(FTE_TARGET)$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) SV_EXE_NAME=../fteqw_sdl.sv$(BITS) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) SV_LDFLAGS=-lz -MINGL_DIR=mingl_sdl$(BITS) +MINGL_DIR=mingl_sdl$(FTE_TARGET)$(BITS) MINGL_EXE_NAME=../fteqw_sdl.mingl$(BITS) -MB_DIR=m_sdl$(BITS) +MB_DIR=m_sdl$(FTE_TARGET)$(BITS) M_EXE_NAME=../fteqw_sdl$(BITS) MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o M_CFLAGS=$(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL @@ -549,15 +553,15 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win(32|64)_sdl$$"),) GL_CFLAGS+= -D_MINGW_VFPRINTF endif - GLB_DIR=sdl_gl_mgw_sdl$(BITS) - GLCL_DIR=sdl_glcl_mgw_sdl$(BITS) + GLB_DIR=gl_mgw_sdl$(BITS) + GLCL_DIR=glcl_mgw_sdl$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(LTO_END) resources.o $(LTO_START) SV_EXE_NAME=../fteqw_sdl_sv$(BITS).exe SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -D_SDL SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm - MINGL_DIR=mingl_sdl$(BITS) + MINGL_DIR=mingl_sdlwin$(BITS) MINGL_EXE_NAME=../fteqw_sdl_mingl$(BITS).exe MB_DIR=m_mgw_sdl$(BITS) @@ -651,13 +655,13 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -E -v "win(32|64)$$"),) GLB_DIR=gl_mgw$(BITS) GLCL_DIR=glcl_mgw$(BITS) - NPQTVCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_npqtv.o sys_plugfte.o $(LTO_END) npplug.o ../../ftequake/npapi.def $(LTO_START) - NPQTV_DLL_NAME=../npqtv$(BITS).dll - NPQTVCL_DLL_NAME=../npqtvcl$(BITS).dll - NPQTV_LDFLAGS=--enable-stdcall-fixup $(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -shared - NPQTV_CFLAGS=$(NPQTVCFLAGS) $(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK) - NPQTVB_DIR=npqtv_mgw$(BITS) - NPQTVCL_DIR=npqtvcl_mgw$(BITS) + NPFTECL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_npqtv.o sys_plugfte.o $(LTO_END) npplug.o ../../ftequake/npapi.def $(LTO_START) + NPFTE_DLL_NAME=../npfte$(BITS).dll + NPFTECL_DLL_NAME=../npftecl$(BITS).dll + NPFTE_LDFLAGS=--enable-stdcall-fixup $(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -shared + NPFTE_CFLAGS=$(NPFTECFLAGS) $(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD + NPFTEB_DIR=npfte_mgw$(BITS) + NPFTECL_DIR=npqtvcl_mgw$(BITS) MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o $(LTO_END) resources.o $(LTO_START) M_EXE_NAME=../fteqw$(BITS).exe @@ -837,14 +841,14 @@ ifeq ($(FTE_TARGET),droid) SV_DIR=sv_droid SV_LDFLAGS=-lz SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) svmodel.o sys_droid.o - SV_EXE_NAME=../fteqw.a$(BITS) + SV_EXE_NAME=../libftedroid.so SV_LDFLAGS= GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_viddroid.o sys_droid.o cd_null.o GL_LDFLAGS=$(GLLDFLAGS) GLB_DIR=gl_droid - GL_EXE_NAME=../fteqw.a$(BITS) + GL_EXE_NAME=../libftedroid.so endif SV_DIR?=sv_sdl @@ -870,6 +874,8 @@ releases: # -$(MAKE) FTE_TARGET=linux32 relcl # -$(MAKE) FTE_TARGET=linux64 relcl # -$(MAKE) FTE_TARGET=win32 relcl + -$(MAKE) droid-rel + -$(MAKE) FTE_TARGET=win32 npfte-rel autoconfig: clean /bin/bash makeconfig.sh y @@ -1000,22 +1006,24 @@ d3d-profile: npqtvcl-tmp: - $(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(NPQTVCL_DLL_NAME)" WCFLAGS="$(NPQTV_CFLAGS)" LDFLAGS="$(NPQTV_LDFLAGS) $(LDFLAGS)" SOBJS="$(NPQTVCL_OBJS)" -npqtv-tmp: - $(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(NPQTV_DLL_NAME)" WCFLAGS="$(NPQTV_CFLAGS)" LDFLAGS="$(NPQTV_LDFLAGS) $(LDFLAGS)" SOBJS="$(NPQTVCL_OBJS)" + $(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(NPFTECL_DLL_NAME)" WCFLAGS="$(NPFTE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS)" SOBJS="$(NPFTECL_OBJS)" +npfte-tmp: + $(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(NPFTE_DLL_NAME)" WCFLAGS="$(NPFTE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS)" SOBJS="$(NPFTECL_OBJS)" npqtvcl-rel: - $(MAKE) npqtvcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPQTVCL_DIR)" + $(MAKE) npqtvcl-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPFTECL_DIR)" npqtvcl-dbg: - $(MAKE) npqtvcl-tmp TYPE=_cl-dbg OUT_DIR="$(DEBUG_DIR)/$(NPQTVCL_DIR)" + $(MAKE) npqtvcl-tmp TYPE=_cl-dbg OUT_DIR="$(DEBUG_DIR)/$(NPFTECL_DIR)" npqtvcl-profile: - $(MAKE) npqtvcl-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPQTVCL_DIR)" -npqtv-rel: - $(MAKE) npqtv-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPQTVB_DIR)" -npqtv-dbg: - $(MAKE) npqtv-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(NPQTVB_DIR)" -npqtv-profile: - $(MAKE) npqtv-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPQTVB_DIR)" + $(MAKE) npqtvcl-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTECL_DIR)" +npfte-rel: + $(MAKE) npfte-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)" + cp $(RELEASE_DIR)/npfte.dll npfte/plugins + cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) * plugins/* +npfte-dbg: + $(MAKE) npfte-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)" +npfte-profile: + $(MAKE) npfte-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTEB_DIR)" glcl-tmp: $(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GLCL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)" @@ -1100,10 +1108,11 @@ help: @-echo "'gl-???' (OpenGL rendering + Built-in Server)" @-echo "'m-???' (Merged client, OpenGL & D3D rendering + Dedicated server)" @-echo "'mingl-???' (Minimal featured OpenGL render)" - @-echo "'npqtv-???' (FTE_TARGET=win32 only, for now) (QuakeTV Firefox/Netscape browser plugin)" + @-echo "'npfte-???' (FTE_TARGET=win32 only, for now) (QuakeTV Firefox/Netscape browser plugin)" @-echo "'d3d-???' (for windows builds)" @-echo "'mcl-???' (currently broken)" @-echo "'glcl-???' (currently broken)" + @-echo "'droid-???' (build Android package)" @-echo "" @-echo "Cross targets can be specified with FTE_TARGET=blah" @-echo "linux32, linux64 specify specific x86 archs" @@ -1120,4 +1129,39 @@ clean: -rm -f -r $(RELEASE_DIR) -rm -f -r $(DEBUG_DIR) -rm -f -r $(PROFILE_DIR) + -rm -f -r droid/bin + -rm -f -r droid/gen + -rm -f -r droid/libs + -rm -f droid/default.properties + -rm -f droid/local.properties + -rm -f droid/proguard.cfg + -rm -f droid/build.xml + + +#building for android will require: +#download android sdk+ndk +#ant installed +#DROID_NDK_PATH and DROID_SDK_PATH set, if they don't match the paths on my system. + +#droid-dbg will install it on 'the current device', if you've got a device plugged in or an emulator running, it should just work. + +#makes an ant project for us +droid/build.xml: + cd droid && PATH=$$PATH:$(DROID_SDK_PATH)/tools:$(DROID_NDK_PATH) android update project -t 1 -p . -n FTEDroid + +#build FTE as a library, then build the java+package (release) +droid-rel: droid/build.xml + $(MAKE) FTE_TARGET=droid gl-rel + mkdir -p droid/libs/armeabi + @cp $(RELEASE_DIR)/libftedroid.so droid/libs/armeabi/ + @cd droid && ant release + cp droid/bin/FTEDroid-unsigned.apk $(RELEASE_DIR)/FTEDroid.apk + +#build FTE as a library, then build the java+package (release). also installs it onto the 'current' device. +droid-dbg: droid/build.xml + $(MAKE) FTE_TARGET=droid gl-dbg + @mkdir -p droid/libs/armeabi + @cp $(DEBUG_DIR)/libftedroid.so droid/libs/armeabi/ + @cd droid && ant debug && ant install + cp droid/bin/FTEDroid-debug.apk $(DEBUG_DIR)/FTEDroid.apk diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 718235308..a553dd37d 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -3703,7 +3703,7 @@ Host_Init */ void Host_Init (quakeparms_t *parms) { -#ifndef NPQTV +#ifndef NPFTE int i; int qrc, hrc, def; #endif @@ -3787,7 +3787,7 @@ void Host_Init (quakeparms_t *parms) host_initialized = true; -#ifdef NPQTV +#ifdef NPFTE } void Host_FinishInit(void) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 53a1261fa..c4c540648 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -5651,8 +5651,8 @@ void CSQC_Breakpoint_f(void) Con_Printf("CSQC not running\n"); return; } - wasset = svprogfuncs->ToggleBreak(csqcprogs, filename, line, 3); - isset = svprogfuncs->ToggleBreak(csqcprogs, filename, line, 2); + wasset = csqcprogs->ToggleBreak(csqcprogs, filename, line, 3); + isset = csqcprogs->ToggleBreak(csqcprogs, filename, line, 2); if (wasset == isset) Con_Printf("Breakpoint was not valid\n"); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 742a5fdd2..909cdd461 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -1863,9 +1863,9 @@ void VARGS Menu_Abort (char *format, ...) void MP_CvarChanged(cvar_t *var) { - if (svprogfuncs) + if (menuprogs) { - PR_AutoCvar(svprogfuncs, var); + PR_AutoCvar(menuprogs, var); } } diff --git a/engine/client/sys_droid.c b/engine/client/sys_droid.c new file mode 100644 index 000000000..403755c41 --- /dev/null +++ b/engine/client/sys_droid.c @@ -0,0 +1,444 @@ +#include +#include + +#include + +#include "quakedef.h" +#include +#include +#include +#include +#include + +#ifndef isDedicated +#ifdef SERVERONLY +qboolean isDedicated = true; +#else +qboolean isDedicated = false; +#endif +#endif +void *sys_window; /*public so the renderer can attach to the correct place*/ +static qboolean sys_running = false; + + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DISTRIBUTION"Droid", __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, DISTRIBUTION"Droid", __VA_ARGS__)) + +static void *sys_memheap; +static unsigned int sys_lastframe; +JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject obj) +{ + #ifdef SERVERONLY + SV_Frame(); + #else + unsigned int now = Sys_Milliseconds(); + double tdelta = (now - sys_lastframe) * 0.001; + Host_Frame(tdelta); + sys_lastframe = now; + #endif +} + +JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj, + jint width, jint height) +{ + vid.pixelwidth = width; + vid.pixelheight = height; + if (!sys_running) + { + quakeparms_t parms; + parms.basedir = "/sdcard"; + parms.argc = 0; + parms.argv = NULL; + parms.memsize = sys_memheap = 8*1024*1024; + parms.membase = malloc(parms.memsize); + if (!parms.membase) + { + Sys_Printf("Unable to alloc heap\n"); + return; + } + + Sys_Printf("Starting up\n"); + + COM_InitArgv(parms.argc, parms.argv); + TL_InitLanguages(); + #ifdef SERVERONLY + SV_Init(&parms); + #else + Host_Init(&parms); + #endif + sys_running = true; + sys_lastframe = Sys_Milliseconds(); + } +} +JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_keypress(JNIEnv *env, jobject obj, + jint down, jint keycode, jint unicode) +{ + Key_Event(0, keycode, unicode, down); +} + +float mousecursor_x, mousecursor_y; +float mouse_x, mouse_y; +JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject obj, + jint act, jfloat x, jfloat y) +{ + static float totalmoved; + static qboolean down; + float dx, dy; + + dx = x - mousecursor_x; + dy = y - mousecursor_y; + mousecursor_x = x; + mousecursor_y = y; + + if (down) + { + mouse_x += dx; + mouse_y += dy; + totalmoved += fabs(dx) + fabs(dy); + } + + switch(act) + { + case 0: /*move*/ + break; + case 1: /*down*/ + totalmoved = 0; + down = true; + break; + case 2: /*up*/ + down = false; + /*if it didn't move far, treat it as a regular click, if it did move a little then sorry if you just wanted a small turn!*/ + if (totalmoved < 3) + { + Key_Event(0, K_MOUSE1, 0, 1); + Key_Event(0, K_MOUSE1, 0, 0); + } + break; + } +} +JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_accelerometer(JNIEnv *env, jobject obj, + jfloat x, jfloat y, jfloat z) +{ +// Con_Printf("Accelerometer: %f %f %f\n", x, y, z); +} + +static int secbase; +double Sys_DoubleTime(void) +{ + struct timeval tp; + struct timezone tzp; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000000.0; + } + + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; +} +unsigned int Sys_Milliseconds(void) +{ + struct timeval tp; + struct timezone tzp; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000; + } + + return (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000; +} + +void Sys_Shutdown(void) +{ + free(sys_memheap); +} +void Sys_Quit(void) +{ +#ifndef SERVERONLY + Host_Shutdown (); +#else + SV_Shutdown(); +#endif + + exit (0); +} +void Sys_Error (const char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, error); + vsnprintf (string,sizeof(string)-1, error,argptr); + va_end (argptr); + + LOGW("%s", string); + + exit(1); +} +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, fmt); + vsnprintf (string,sizeof(string)-1, fmt,argptr); + va_end (argptr); + + LOGI("%s", string); +} +void Sys_Warn (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, fmt); + vsnprintf (string,sizeof(string)-1, fmt,argptr); + va_end (argptr); + + LOGW("%s", string); +} + +void Sys_CloseLibrary(dllhandle_t *lib) +{ + dlclose(lib); +} +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) +{ + dllhandle_t *h; + h = dlopen(name, RTLD_LAZY); + return h; +} +void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) +{ + return dlsym(module, exportname); +} +void *Sys_GetGameAPI (void *parms) +{ + return NULL; +} +void Sys_UnloadGame(void) +{ +} +char *Sys_ConsoleInput (void) +{ + return NULL; +} +void Sys_mkdir (char *path) //not all pre-unix systems have directories (including dos 1) +{ +} +qboolean Sys_remove (char *path) +{ + return false; +} +void Sys_Init(void) +{ +} + +qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) +{ + *width = 320; + *height = 240; + *bpp = 16; + *refreshrate = 60; + return false; +} +qboolean Sys_RandomBytes(qbyte *string, int len) +{ + qboolean res = false; + int fd = open("/dev/urandom", 0); + if (fd >= 0) + { + res = (read(fd, string, len) == len); + close(fd); + } + + return res; +} + +void Sys_ServerActivity(void) +{ + /*FIXME: flash window*/ +} + +qboolean Sys_InitTerminal(void) +{ + /*switching to dedicated mode, show text window*/ + return false; +} +void Sys_CloseTerminal(void) +{ +} + +char *Sys_GetClipboard(void) +{ + return NULL; +} +void Sys_CloseClipboard(char *buf) +{ +} +void Sys_SaveClipboard(char *text) +{ +} + +int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) +{ + DIR *dir; + char apath[MAX_OSPATH]; + char file[MAX_OSPATH]; + char truepath[MAX_OSPATH]; + char *s; + struct dirent *ent; + struct stat st; + +//printf("path = %s\n", gpath); +//printf("match = %s\n", match); + + if (!gpath) + gpath = ""; + *apath = '\0'; + + Q_strncpyz(apath, match, sizeof(apath)); + for (s = apath+strlen(apath)-1; s >= apath; s--) + { + if (*s == '/') + { + s[1] = '\0'; + match += s - apath+1; + break; + } + } + if (s < apath) //didn't find a '/' + *apath = '\0'; + + Q_snprintfz(truepath, sizeof(truepath), "%s/%s", gpath, apath); + + +//printf("truepath = %s\n", truepath); +//printf("gamepath = %s\n", gpath); +//printf("apppath = %s\n", apath); +//printf("match = %s\n", match); + dir = opendir(truepath); + if (!dir) + { + Con_DPrintf("Failed to open dir %s\n", truepath); + return true; + } + do + { + ent = readdir(dir); + if (!ent) + break; + if (*ent->d_name != '.') + { + if (wildcmp(match, ent->d_name)) + { + Q_snprintfz(file, sizeof(file), "%s/%s", truepath, ent->d_name); + + if (stat(file, &st) == 0) + { + Q_snprintfz(file, sizeof(file), "%s%s%s", apath, ent->d_name, S_ISDIR(st.st_mode)?"/":""); + + if (!func(file, st.st_size, parm)) + { + closedir(dir); + return false; + } + } + else + printf("Stat failed for \"%s\"\n", file); + } + } + } while(1); + closedir(dir); + + return true; +} + +/* +int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) +{ + qboolean go = true; + const char *f; + + struct AAssetDir *ad; + ad = AAssetManager_openDir(assetmgr, gpath); + + while(go && (f = AAssetDir_getNextFileName(ad))) + { + if (wildcmp(match, f)) + { +Sys_Printf("Found %s\n", f); + go = func(f, 0, parm); + } + } + + AAssetDir_close(ad); + return 0; +} +typedef struct +{ + vfsfile_t funcs; + AAsset *handle; +} assetfile_t; +static int AF_ReadBytes(vfsfile_t *h, void *buf, int len) +{ + assetfile_t *f = (assetfile_t*)h; + return AAsset_read(f->handle, buf, len); +} +static qboolean AF_Seek(vfsfile_t *h, unsigned long offs) +{ + assetfile_t *f = (assetfile_t*)h; + AAsset_seek(f->handle, offs, SEEK_SET); + return true; +} +static unsigned long AF_Tell(vfsfile_t *h) +{ + assetfile_t *f = (assetfile_t*)h; + return AAsset_seek(f->handle, 0, SEEK_CUR); +} +static unsigned long AF_GetSize(vfsfile_t *h) +{ + assetfile_t *f = (assetfile_t*)h; + return AAsset_getLength(f->handle); +} + +static void AF_Close(vfsfile_t *h) +{ + assetfile_t *f = (assetfile_t*)h; + AAsset_close(f->handle); + Z_Free(f); +} +static void AF_Flush(vfsfile_t *h) +{ +} +vfsfile_t *Sys_OpenAsset(char *fname) +{ + assetfile_t *file; + AAsset *a; + a = AAssetManager_open(assetmgr, fname, AASSET_MODE_UNKNOWN); + if (!a) + { + Sys_Printf("Unable to open asset %s\n", fname); + return NULL; + } + Sys_Printf("opened asset %s\n", fname); + + file = Z_Malloc(sizeof(assetfile_t)); + file->funcs.ReadBytes = AF_ReadBytes; + file->funcs.WriteBytes = NULL; + file->funcs.Seek = AF_Seek; + file->funcs.Tell = AF_Tell; + file->funcs.GetLen = AF_GetSize; + file->funcs.Close = AF_Close; + file->funcs.Flush = AF_Flush; + file->handle = a; + + return (vfsfile_t*)file; +} +*/ diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 790367c74..37b72d3ed 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -750,7 +750,7 @@ void VARGS Sys_Error (const char *error, ...) SetHookState(false); #endif -#ifdef NPQTV +#ifdef NPFTE { extern jmp_buf host_abort; /*jump to start of main loop (which exits the main loop)*/ @@ -800,7 +800,7 @@ void Sys_Quit (void) SV_Shutdown(); #endif -#ifdef NPQTV +#ifdef NPFTE { extern jmp_buf host_abort; /*jump to start of main loop (which exits the main loop)*/ @@ -1211,7 +1211,7 @@ qboolean Sys_Startup_CheckMem(quakeparms_t *parms) return true; } -#ifdef NPQTV +#ifdef NPFTE static quakeparms_t parms; double lastlooptime; qboolean NPQTV_Sys_Startup(int argc, char *argv[]) diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 4922fcc7a..40d38e5be 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -234,6 +234,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //fix things a little... #ifdef NPQTV + #define NPFTE + #undef NPQTV +#endif +#ifdef NPFTE /*plugins require threads and stuff now, and http download support*/ #ifndef MULTITHREAD #define MULTITHREAD @@ -254,7 +258,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #endif -#ifdef NPQTV +#ifdef NPFTE #undef TEXTEDITOR #undef WEBSERVER #endif diff --git a/engine/common/fs.c b/engine/common/fs.c index ef23a7a7c..a513a712b 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2060,7 +2060,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base return true; } -#if !defined(NPQTV) && !defined(SERVERONLY) //this is *really* unfortunate, but doing this crashes the browser +#if !defined(NPFTE) && !defined(SERVERONLY) //this is *really* unfortunate, but doing this crashes the browser if (poshname) { char resultpath[MAX_PATH]; @@ -2388,7 +2388,7 @@ void COM_InitFilesystem (void) Q_snprintfz(com_homedir, sizeof(com_homedir), "%s/My Documents/My Games/%s/", ev, FULLENGINENAME); } -#ifdef NPQTV +#ifdef NPFTE if (!*com_homedir) Q_snprintfz(com_homedir, sizeof(com_homedir), "/%s/", FULLENGINENAME); //as a browser plugin, always use their home directory @@ -2484,7 +2484,7 @@ extern searchpathfuncs_t doomwadfilefuncs; void FS_RegisterDefaultFileSystems(void) { FS_RegisterFileSystemType("pak", &packfilefuncs); -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(ANDROID) /*for systems that have case sensitive paths, also include *.PAK */ FS_RegisterFileSystemType("PAK", &packfilefuncs); #endif diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index 0d6883e2f..22a4ee7b7 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -84,7 +84,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void) return (vfsfile_t*)file; } -#ifdef ANDROID +#if 0//def ANDROID vfsfile_t *Sys_OpenAsset(const char *fname); #endif @@ -99,7 +99,7 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode) char newmode[3]; int modec = 0; -#ifdef ANDROID +#if 0//def ANDROID // if (!strncmp("asset/", osname, 6)) { if (append || write) diff --git a/engine/common/sys.h b/engine/common/sys.h index e0b220d17..a9ad338d5 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -112,7 +112,7 @@ void Sys_DestroyConditional(void *condv); void Sys_Sleep(double seconds); -#ifdef NPQTV +#ifdef NPFTE qboolean NPQTV_Sys_Startup(int argc, char *argv[]); void NPQTV_Sys_MainLoop(void); #endif diff --git a/engine/droid/AndroidManifest.xml b/engine/droid/AndroidManifest.xml new file mode 100644 index 000000000..d5d98d155 --- /dev/null +++ b/engine/droid/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/engine/droid/res/drawable-hdpi/icon.png b/engine/droid/res/drawable-hdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8074c4c571b8cd19e27f4ee5545df367420686d7 GIT binary patch literal 4147 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 literal 0 HcmV?d00001 diff --git a/engine/droid/res/drawable-ldpi/icon.png b/engine/droid/res/drawable-ldpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1095584ec21f71cd0afc9e0993aa2209671b590c GIT binary patch literal 1723 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 + + FTEDroid + diff --git a/engine/droid/src/com/fteqw/FTEDroidActivity.java b/engine/droid/src/com/fteqw/FTEDroidActivity.java new file mode 100644 index 000000000..4da78abfb --- /dev/null +++ b/engine/droid/src/com/fteqw/FTEDroidActivity.java @@ -0,0 +1,226 @@ +package com.fteqw; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.Window; +import android.view.WindowManager; + +import android.opengl.GLSurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import android.hardware.SensorManager; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; + +public class FTEDroidActivity extends Activity +{ + private SensorManager sensorman; + private Sensor sensoracc; + private FTEView view; + + private class FTERenderer implements GLSurfaceView.Renderer + { + private boolean inited; + @Override + public void onDrawFrame(GL10 gl) + { + if (inited == true) + { + FTEDroidEngine.frame(); + } + } + @Override + public void onSurfaceChanged(GL10 gl, int width, int height) + { + FTEDroidEngine.init(width, height); + inited = true; + } + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + } + } + private class FTEView extends GLSurfaceView implements SensorEventListener + { + private final FTERenderer rndr; + + public FTEView(Context context) + { + super(context); + + rndr = new FTERenderer(); + setRenderer(rndr); + setFocusable(true); + setFocusableInTouchMode(true); + } + + private void sendKey(final boolean presseddown, final int qcode, final int unicode) + { + queueEvent(new Runnable() + { + public void run() + { + FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode); + } + }); + } + private void sendAccelerometer(final float x, final float y, final float z) + { + queueEvent(new Runnable() + { + public void run() + { + FTEDroidEngine.accelerometer(x, y, z); + } + }); + } + @Override + public boolean onTouchEvent(MotionEvent event) + { + final int act = event.getAction(); + final float x = event.getX(); + final float y = event.getY(); + //float p = event.getPressure(); + + queueEvent(new Runnable() + { + public void run() + { + switch(act) + { + case MotionEvent.ACTION_DOWN: + FTEDroidEngine.motion(1, x, y); + break; + case MotionEvent.ACTION_UP: + FTEDroidEngine.motion(2, x, y); + break; + case MotionEvent.ACTION_MOVE: + FTEDroidEngine.motion(0, x, y); + break; + } + } + }); + return true; + } + /* + @Override + public boolean onTrackballEvent(MotionEvent event) + { + int act = event.getAction(); + float x = event.getX(); + float y = event.getY(); + } + */ + private static final int K_UPARROW = 132; + private static final int K_DOWNARROW = 133; + private static final int K_LEFTARROW = 134; + private static final int K_RIGHTARROW = 135; + private int mapKey(int acode, int unicode) + { + switch(acode) + { + case KeyEvent.KEYCODE_DPAD_UP: + return K_UPARROW; + case KeyEvent.KEYCODE_DPAD_DOWN: + return K_DOWNARROW; + case KeyEvent.KEYCODE_DPAD_LEFT: + return K_LEFTARROW; + case KeyEvent.KEYCODE_DPAD_RIGHT: + return K_RIGHTARROW; + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_ENTER: + return '\r'; + case KeyEvent.KEYCODE_BACK: + return 27; + case KeyEvent.KEYCODE_DEL: + return 127; + default: + if (unicode < 128) + return Character.toLowerCase(unicode); + } + return 0; + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + int uc = event.getUnicodeChar(); + sendKey(true, mapKey(keyCode, uc), uc); + return true; + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) + { + int uc = event.getUnicodeChar(); + sendKey(false, mapKey(keyCode, uc), uc); + return true; + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) + { + } + + private float gx,gy,gz; + public void onSensorChanged(final SensorEvent event) + { + // alpha is calculated as t / (t + dT) + // with t, the low-pass filter's time-constant + // and dT, the event delivery rate + + final float alpha = 0.8f; + + gx = alpha * gx + (1 - alpha) * event.values[0]; + gy = alpha * gy + (1 - alpha) * event.values[1]; + gz = alpha * gz + (1 - alpha) * event.values[2]; + + sendAccelerometer(event.values[0] - gx, event.values[1] - gy, event.values[2] - gz); + + } + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + //go full-screen + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + requestWindowFeature(Window.FEATURE_NO_TITLE); + + super.onCreate(savedInstanceState); + + view = new FTEView(this); + setContentView(view); + // setContentView(R.layout.main); + + + sensorman = (SensorManager)getSystemService(SENSOR_SERVICE); + sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + } + + @Override + protected void onResume() + { + super.onResume(); + sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME); + } + + @Override + protected void onStop() + { + sensorman.unregisterListener(view); + super.onStop(); + } + + @Override + protected void onPause() + { + sensorman.unregisterListener(view); + super.onPause(); + } +} diff --git a/engine/droid/src/com/fteqw/FTEDroidEngine.java b/engine/droid/src/com/fteqw/FTEDroidEngine.java new file mode 100644 index 000000000..17dc282fc --- /dev/null +++ b/engine/droid/src/com/fteqw/FTEDroidEngine.java @@ -0,0 +1,14 @@ +package com.fteqw; + +public class FTEDroidEngine +{ + public static native void init(int w, int h); /* init/reinit */ + public static native void frame(); + public static native void keypress(int down, int qkey, int unicode); + public static native void motion(int act, float x, float y); + public static native void accelerometer(float x, float y, float z); + static + { + System.loadLibrary("ftedroid"); + } +} diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 2a5249a72..c4aefb788 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1,6 +1,11 @@ #include "quakedef.h" +#ifdef ANDROID +//FIXME: this shouldn't be defined +#define FORCESTATE +#else //#define FORCESTATE +#endif //#define WIREFRAME #ifdef GLQUAKE diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 66f30dad6..54f0405b9 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -336,10 +336,20 @@ void GLDraw_ReInit (void) maxtexsize = gl_max_size.value; - if (maxtexsize < 2048) //this needs to be able to hold the image in unscaled form. - sizeofuploadmemorybufferintermediate = 2048*2048*4; //make sure we can load 2048*2048 images whatever happens. + if (gl_config.gles) + { + if (maxtexsize < 512) //this needs to be able to hold the image in unscaled form. + sizeofuploadmemorybufferintermediate = 512*512*4; //make sure we can load 512*512 images whatever happens. + else + sizeofuploadmemorybufferintermediate = maxtexsize*maxtexsize*4; //gl supports huge images, so so shall we. + } else - sizeofuploadmemorybufferintermediate = maxtexsize*maxtexsize*4; //gl supports huge images, so so shall we. + { + if (maxtexsize < 2048) //this needs to be able to hold the image in unscaled form. + sizeofuploadmemorybufferintermediate = 2048*2048*4; //make sure we can load 2048*2048 images whatever happens. + else + sizeofuploadmemorybufferintermediate = maxtexsize*maxtexsize*4; //gl supports huge images, so so shall we. + } //required to hold the image after scaling has occured sizeofuploadmemorybuffer = maxtexsize*maxtexsize*4; @@ -936,6 +946,15 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap) ; for (*scaled_height = 1 ; *scaled_height < height ; *scaled_height<<=1) ; + + /*round npot textures down if we're running on an embedded system*/ + if (gl_config.gles) + { + if (*scaled_width != width) + *scaled_width >>= 1; + if (*scaled_height != height) + *scaled_height >>= 1; + } } if (mipmap) @@ -964,6 +983,41 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap) if (*scaled_height < 1) *scaled_height = 1; } + +void GL_8888to565(unsigned char *in, unsigned short *out, unsigned int mip, unsigned int w, unsigned int h) +{ + unsigned int p = w*h; + unsigned short tmp; + void *iout = out; + + while(p-->0) + { + tmp = ((*in++>>3) << 11); + tmp |= ((*in++>>2) << 5); + tmp |= ((*in++>>3) << 0); + in++; + *out++ = tmp; + } + qglTexImage2D (GL_TEXTURE_2D, mip, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, iout); +} + +void GL_8888to4444(unsigned char *in, unsigned short *out, unsigned int mip, unsigned int w, unsigned int h) +{ + unsigned int p = w*h; + unsigned short tmp; + void *iout = out; + + while(p-->0) + { + tmp = ((*in++>>4) << 12); + tmp |= ((*in++>>4) << 8); + tmp |= ((*in++>>4) << 4); + tmp |= ((*in++>>4) << 0); + *out++ = tmp; + } + qglTexImage2D (GL_TEXTURE_2D, mip, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, iout); +} + /* =============== GL_Upload32 @@ -975,6 +1029,7 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne int samples; unsigned *scaled = (unsigned *)uploadmemorybuffer; int scaled_width, scaled_height; + int type; TRACE(("dbg: GL_Upload32: %s %i %i\n", name, width, height)); @@ -1001,9 +1056,31 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne Sys_Error ("GL_LoadTexture: too big"); if (gl_config.gles) - glcolormode = samples = GL_RGBA; /* GL ES doesn't allow for format conversion */ + { + glcolormode = GL_RGBA; /*our input is RGBA or RGBX, with the internal format restriction, we must therefore always have an alpha value*/ + type = GL_UNSIGNED_BYTE; + + if (flags & IF_NOALPHA) + { + /*no alpha there, yay*/ + type = GL_UNSIGNED_SHORT_5_6_5; + glcolormode = GL_RGB; + } + else + { + /*we need an alpha channel, sorry for any banding*/ + type = GL_UNSIGNED_SHORT_4_4_4_4; + glcolormode = GL_RGBA; + } + + /*GLES requires that the internal format match the format*/ + samples = glcolormode; + } else + { samples = (flags&IF_NOALPHA) ? GL_RGB : GL_RGBA; + type = GL_UNSIGNED_BYTE; + } if (gl_config.arb_texture_compression && gl_compress.value && name && !(flags&IF_NOMIPMAP)) samples = (flags&IF_NOALPHA) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB; @@ -1041,7 +1118,12 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne if ((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :) { TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n")); - qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data); + if (type == GL_UNSIGNED_SHORT_5_6_5) + GL_8888to565((unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height); + else if (type == GL_UNSIGNED_SHORT_4_4_4_4) + GL_8888to4444((unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height); + else + qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data); goto done; } memcpy (scaled, data, width*height*4); @@ -1050,7 +1132,12 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height); TRACE(("dbg: GL_Upload32: recaled\n")); - qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled); + if (type == GL_UNSIGNED_SHORT_5_6_5) + GL_8888to565((unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height); + else if (type == GL_UNSIGNED_SHORT_4_4_4_4) + GL_8888to4444((unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height); + else + qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled); if (!(flags&IF_NOMIPMAP) && !gl_config.sgis_generate_mipmap) { miplevel = 0; @@ -1065,9 +1152,15 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne if (scaled_height < 1) scaled_height = 1; miplevel++; - qglTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled); + if (type == GL_UNSIGNED_SHORT_5_6_5) + GL_8888to565((unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height); + else if (type == GL_UNSIGNED_SHORT_4_4_4_4) + GL_8888to4444((unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height); + else + qglTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled); } } + if (gl_config.arb_texture_compression && gl_compress.value && gl_savecompressedtex.value && name && !(flags&IF_NOMIPMAP)) { vfsfile_t *out; diff --git a/engine/gl/gl_viddroid.c b/engine/gl/gl_viddroid.c new file mode 100644 index 000000000..d2f54a737 --- /dev/null +++ b/engine/gl/gl_viddroid.c @@ -0,0 +1,327 @@ +/* +Copyright (C) 2006-2007 Mark Olsen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "quakedef.h" +#include "glquake.h" + +#ifdef GL_ES_VERSION_2_0 +qboolean gles2 = true; +#else +qboolean gles2 = false; +#endif + +static dllhandle_t *sys_gl_module = NULL; + +void *GLES_GetSymbol(char *symname) +{ + void *ret; + + ret = Sys_GetAddressForName(sys_gl_module, symname); + + if (!ret) + Sys_Warn("GLES_GetSymbol: couldn't find %s\n", symname); + return ret; +} + +void GLVID_SetPalette (unsigned char *palette) +{ + qbyte *pal; + unsigned int r,g,b; + int i; + unsigned *table1; + extern qbyte gammatable[256]; + + pal = palette; + table1 = d_8to24rgbtable; + for (i=0 ; i<256 ; i++) + { + r = gammatable[pal[0]]; + g = gammatable[pal[1]]; + b = gammatable[pal[2]]; + pal += 3; + + *table1++ = LittleLong((255<<24) + (r<<0) + (g<<8) + (b<<16)); + } + d_8to24rgbtable[255] &= LittleLong(0xffffff); // 255 is transparent +} + +#if 1 +void GL_BeginRendering(void) +{ +} +void GL_EndRendering (void) +{ +} +void GLVID_DeInit(void) +{ + if (sys_gl_module) + Sys_CloseLibrary(sys_gl_module); + sys_gl_module = NULL; +} +qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) +{ + /* + Android 2.2 does not provide EGL headers, thus the context was already created within java code. + This means that we cannot change width/height/bpp/etc. + But we still initialize everything as if we did. + + Pros: Works on android 2.2, which reportedly is 50% of all androids right now. + Cons: vid_restart cannot change width/height/bpp/rate/etc. + Mneh: you probably couldn't change width/height/rate anyway. + Cons: any gl objects which were not destroyed properly will leak. + Mneh: we should have cleaned them up properly in the first place. + Cons: GL_EndRendering call will not swap buffers. Buffers will be swapped on return to java. + */ + + sys_gl_module = Sys_LoadLibrary(gles2?"libGLESv2.so":"libGLESv1_CM.so", NULL); + if (!sys_gl_module) + { + GLVID_DeInit(); + return false; + } + + GLVID_SetPalette (palette); + GL_Init(GLES_GetSymbol); + vid.recalc_refdef = 1; + return true; +} +#else + +#include + +extern void *sys_window; +static EGLDisplay sys_display = EGL_NO_DISPLAY; +static EGLSurface sys_surface = EGL_NO_SURFACE; +static EGLContext sys_context = EGL_NO_CONTEXT; + +void GLVID_DeInit(void) +{ + if (sys_display != EGL_NO_DISPLAY) + { + eglMakeCurrent(sys_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (sys_context != EGL_NO_CONTEXT) + eglDestroyContext(sys_display, sys_context); + if (sys_surface != EGL_NO_SURFACE) + eglDestroySurface(sys_display, sys_surface); + eglTerminate(sys_display); + sys_context = EGL_NO_CONTEXT; + sys_surface = EGL_NO_SURFACE; + sys_display = EGL_NO_DISPLAY; + } + if (sys_gl_module != NULL) + { + Sys_CloseLibrary(sys_gl_module); + sys_gl_module = NULL; + } +} + +qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) +{ + vid.pixelwidth = info->width; + vid.pixelheight = info->height; + vid.numpages = 3; + gl_canstencil = 0; + + const EGLint attribs[] = { + EGL_RENDERABLE_TYPE, gles2?EGL_OPENGL_ES2_BIT:EGL_OPENGL_ES_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BLUE_SIZE, (info->bpp==16)?5:8, + EGL_GREEN_SIZE, (info->bpp==16)?6:8, + EGL_RED_SIZE, (info->bpp==16)?5:8, + EGL_DEPTH_SIZE, 16, +// EGL_STENCIL_SIZE, 8, + EGL_NONE + }; + EGLint ctxattribs[] = {EGL_CONTEXT_CLIENT_VERSION, gles2?2:1, EGL_NONE}; + EGLint w, h, dummy, format; + EGLint numConfigs; + EGLConfig config; + + sys_gl_module = Sys_LoadLibrary(gles2?"libGLESv2.so":"libGLESv1_CM.so", NULL); + if (!sys_gl_module) + { + GLVID_DeInit(); + return false; + } + + sys_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (sys_display == EGL_NO_DISPLAY) + { + GLVID_DeInit(); + return false; + } + if (!eglInitialize(sys_display, NULL, NULL)) + { + GLVID_DeInit(); + return false; + } + eglChooseConfig(sys_display, attribs, &config, 1, &numConfigs); + + eglGetConfigAttrib(sys_display, config, EGL_NATIVE_VISUAL_ID, &format); + + ANativeWindow_setBuffersGeometry(sys_window, 0, 0, format); + + sys_surface = eglCreateWindowSurface(sys_display, config, sys_window, NULL); + sys_context = eglCreateContext(sys_display, config, NULL, ctxattribs); + + + if (eglMakeCurrent(sys_display, sys_surface, sys_surface, sys_context) == EGL_FALSE) + return false; + + eglQuerySurface(sys_display, sys_surface, EGL_WIDTH, &w); + eglQuerySurface(sys_display, sys_surface, EGL_HEIGHT, &h); + vid.pixelwidth = w; + vid.pixelheight = h; + + GLVID_SetPalette (palette); + GL_Init(GLES_GetSymbol); + vid.recalc_refdef = 1; + return true; +} + +void GL_BeginRendering(void) +{ +} + +void GL_EndRendering (void) +{ + eglSwapBuffers(sys_display, sys_surface); +} +#endif + +void GL_DoSwap(void) +{ +} + +void GLVID_ShiftPalette (unsigned char *palette) +{ +// if (gammaworks) + { + } +} + +void Sys_SendKeyEvents(void) +{ +} + +void GLVID_SetCaption(char *caption) +{ +} + +extern qboolean mouse_active; + +cvar_t m_filter = CVARF("m_filter", "1", CVAR_ARCHIVE); + +extern cvar_t _windowed_mouse; + +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; + +void IN_Shutdown(void) +{ +} + +void IN_ReInit() +{ + Cvar_Register (&m_filter, "input controls"); +} + +void IN_Init(void) +{ + IN_ReInit(); +} + +void IN_Commands(void) +{ +} + +void IN_Move (float *movements, int pnum) +{ + extern int mousecursor_x, mousecursor_y; + extern int mousemove_x, mousemove_y; + + if (pnum != 0) + return; //we're lazy today. + + if (m_filter.value) + { + mouse_x = (mouse_x + old_mouse_x) * 0.5; + mouse_y = (mouse_y + old_mouse_y) * 0.5; + } + + old_mouse_x = mouse_x; + old_mouse_y = mouse_y; + + if(in_xflip.value) mouse_x *= -1; + + if (Key_MouseShouldBeFree()) + { + mousemove_x += mouse_x; + mousemove_y += mouse_y; + + if (mousecursor_y<0) + mousecursor_y=0; + if (mousecursor_x<0) + mousecursor_x=0; + + if (mousecursor_x >= vid.width) + mousecursor_x = vid.width - 1; + + if (mousecursor_y >= vid.height) + mousecursor_y = vid.height - 1; + + mouse_x = mouse_y = 0; +#ifdef VM_UI + UI_MousePosition(mousecursor_x, mousecursor_y); +#endif + } + + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + + if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) )) + { + if (movements) + movements[1] += m_side.value * mouse_x; + } + else + { + cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x; + } + if (in_mlook.state[pnum] & 1) + V_StopPitchDrift (pnum); + + if ( (in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1)) { + cl.viewangles[pnum][PITCH] += m_pitch.value * mouse_y; + CL_ClampPitch(pnum); + } + else + { + if (movements) + { + if ((in_strafe.state[pnum] & 1) && noclip_anglehack) + movements[2] -= m_forward.value * mouse_y; + else + movements[0] -= m_forward.value * mouse_y; + } + } + mouse_x = mouse_y = 0.0; +} + diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 5837e3996..4abdb6f2c 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -672,7 +672,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette) { int temp; qboolean stat; -#ifndef NPQTV +#ifndef NPFTE MSG msg; #endif // HDC hdc; @@ -747,7 +747,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette) SetForegroundWindow (mainwindow); VID_SetPalette (palette); -#ifndef NPQTV +#ifndef NPFTE /*I don't like this, but if we */ while (PeekMessage (&msg, mainwindow, 0, 0, PM_REMOVE)) { @@ -1666,7 +1666,7 @@ LONG WINAPI GLMainWndProc ( if (wParam & MK_LBUTTON) { temp |= 1; -#ifdef NPQTV +#ifdef NPFTE SetFocus(hWnd); #endif } diff --git a/engine/gl/glsupp.h b/engine/gl/glsupp.h index 829427987..3d9dd365c 100644 --- a/engine/gl/glsupp.h +++ b/engine/gl/glsupp.h @@ -48,6 +48,17 @@ extern qlpMTex2FUNC qglMultiTexCoord2fARB; #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 /*opengl 1.2*/ #endif +#ifndef GL_UNSIGNED_SHORT_4_4_4_4 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#endif +#ifndef GL_UNSIGNED_SHORT_5_5_5_1 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#endif +#ifndef GL_UNSIGNED_SHORT_5_6_5 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#endif + + #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #define GL_TEXTURE0_ARB 0x84C0 diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index 4beb3630c..553c94ce3 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -453,7 +453,7 @@ qboolean World_MoveToGoal (world_t *world, wedict_t *ent, float dist) { wedict_t *goal; - ent = (wedict_t*)PROG_TO_EDICT(world->progs, pr_global_struct->self); + ent = (wedict_t*)PROG_TO_EDICT(world->progs, *world->g.self); goal = (wedict_t*)PROG_TO_EDICT(world->progs, ent->v->goalentity); if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )