mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-18 22:41:47 +00:00
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
This commit is contained in:
parent
6236971e48
commit
4b27934867
23 changed files with 1253 additions and 61 deletions
112
engine/Makefile
112
engine/Makefile
|
@ -53,12 +53,16 @@ ifeq ($(FTE_TARGET),win32_sdl)
|
||||||
FTE_TARGET=win32_SDL
|
FTE_TARGET=win32_SDL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
DROID_NDK_PATH?=~/droid/android-ndk-r6b
|
||||||
|
DROID_SDK_PATH?=~/droid/android-sdk-linux_x86
|
||||||
ifeq ($(FTE_TARGET),droid)
|
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
|
endif
|
||||||
|
|
||||||
#correct the gcc build when cross compiling
|
#correct the gcc build when cross compiling
|
||||||
|
@ -293,7 +297,7 @@ DX7SDK=-I./libs/dxsdk7/include/
|
||||||
|
|
||||||
GLCFLAGS=-DGLQUAKE
|
GLCFLAGS=-DGLQUAKE
|
||||||
D3DCFLAGS=-DD3DQUAKE
|
D3DCFLAGS=-DD3DQUAKE
|
||||||
NPQTVCFLAGS=-DNPQTV
|
NPFTECFLAGS=-DNPFTE
|
||||||
|
|
||||||
CLIENT_OBJS = \
|
CLIENT_OBJS = \
|
||||||
textedit.o \
|
textedit.o \
|
||||||
|
@ -499,18 +503,18 @@ else
|
||||||
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) `sdl-config --libs`
|
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) `sdl-config --libs`
|
||||||
endif
|
endif
|
||||||
GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags`
|
GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags`
|
||||||
GLB_DIR=gl_sdl$(BITS)
|
GLB_DIR=gl_sdl$(FTE_TARGET)$(BITS)
|
||||||
GLCL_DIR=glcl_sdl$(BITS)
|
GLCL_DIR=glcl_sdl$(FTE_TARGET)$(BITS)
|
||||||
|
|
||||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
|
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
|
||||||
SV_EXE_NAME=../fteqw_sdl.sv$(BITS)
|
SV_EXE_NAME=../fteqw_sdl.sv$(BITS)
|
||||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
|
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
|
||||||
SV_LDFLAGS=-lz
|
SV_LDFLAGS=-lz
|
||||||
|
|
||||||
MINGL_DIR=mingl_sdl$(BITS)
|
MINGL_DIR=mingl_sdl$(FTE_TARGET)$(BITS)
|
||||||
MINGL_EXE_NAME=../fteqw_sdl.mingl$(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)
|
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
|
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
|
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
|
GL_CFLAGS+= -D_MINGW_VFPRINTF
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GLB_DIR=sdl_gl_mgw_sdl$(BITS)
|
GLB_DIR=gl_mgw_sdl$(BITS)
|
||||||
GLCL_DIR=sdl_glcl_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_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(LTO_END) resources.o $(LTO_START)
|
||||||
SV_EXE_NAME=../fteqw_sdl_sv$(BITS).exe
|
SV_EXE_NAME=../fteqw_sdl_sv$(BITS).exe
|
||||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -D_SDL
|
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -D_SDL
|
||||||
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm
|
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
|
MINGL_EXE_NAME=../fteqw_sdl_mingl$(BITS).exe
|
||||||
|
|
||||||
MB_DIR=m_mgw_sdl$(BITS)
|
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)
|
GLB_DIR=gl_mgw$(BITS)
|
||||||
GLCL_DIR=glcl_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)
|
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)
|
||||||
NPQTV_DLL_NAME=../npqtv$(BITS).dll
|
NPFTE_DLL_NAME=../npfte$(BITS).dll
|
||||||
NPQTVCL_DLL_NAME=../npqtvcl$(BITS).dll
|
NPFTECL_DLL_NAME=../npftecl$(BITS).dll
|
||||||
NPQTV_LDFLAGS=--enable-stdcall-fixup $(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -shared
|
NPFTE_LDFLAGS=--enable-stdcall-fixup $(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -shared
|
||||||
NPQTV_CFLAGS=$(NPQTVCFLAGS) $(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK)
|
NPFTE_CFLAGS=$(NPFTECFLAGS) $(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD
|
||||||
NPQTVB_DIR=npqtv_mgw$(BITS)
|
NPFTEB_DIR=npfte_mgw$(BITS)
|
||||||
NPQTVCL_DIR=npqtvcl_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)
|
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
|
M_EXE_NAME=../fteqw$(BITS).exe
|
||||||
|
@ -837,14 +841,14 @@ ifeq ($(FTE_TARGET),droid)
|
||||||
SV_DIR=sv_droid
|
SV_DIR=sv_droid
|
||||||
SV_LDFLAGS=-lz
|
SV_LDFLAGS=-lz
|
||||||
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) svmodel.o sys_droid.o
|
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=
|
SV_LDFLAGS=
|
||||||
|
|
||||||
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_viddroid.o sys_droid.o cd_null.o
|
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_viddroid.o sys_droid.o cd_null.o
|
||||||
GL_LDFLAGS=$(GLLDFLAGS)
|
GL_LDFLAGS=$(GLLDFLAGS)
|
||||||
GLB_DIR=gl_droid
|
GLB_DIR=gl_droid
|
||||||
GL_EXE_NAME=../fteqw.a$(BITS)
|
GL_EXE_NAME=../libftedroid.so
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SV_DIR?=sv_sdl
|
SV_DIR?=sv_sdl
|
||||||
|
@ -870,6 +874,8 @@ releases:
|
||||||
# -$(MAKE) FTE_TARGET=linux32 relcl
|
# -$(MAKE) FTE_TARGET=linux32 relcl
|
||||||
# -$(MAKE) FTE_TARGET=linux64 relcl
|
# -$(MAKE) FTE_TARGET=linux64 relcl
|
||||||
# -$(MAKE) FTE_TARGET=win32 relcl
|
# -$(MAKE) FTE_TARGET=win32 relcl
|
||||||
|
-$(MAKE) droid-rel
|
||||||
|
-$(MAKE) FTE_TARGET=win32 npfte-rel
|
||||||
|
|
||||||
autoconfig: clean
|
autoconfig: clean
|
||||||
/bin/bash makeconfig.sh y
|
/bin/bash makeconfig.sh y
|
||||||
|
@ -1000,22 +1006,24 @@ d3d-profile:
|
||||||
|
|
||||||
|
|
||||||
npqtvcl-tmp:
|
npqtvcl-tmp:
|
||||||
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(NPQTVCL_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)"
|
||||||
npqtv-tmp:
|
npfte-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="$(NPFTE_DLL_NAME)" WCFLAGS="$(NPFTE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS)" SOBJS="$(NPFTECL_OBJS)"
|
||||||
|
|
||||||
npqtvcl-rel:
|
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:
|
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:
|
npqtvcl-profile:
|
||||||
$(MAKE) npqtvcl-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPQTVCL_DIR)"
|
$(MAKE) npqtvcl-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTECL_DIR)"
|
||||||
npqtv-rel:
|
npfte-rel:
|
||||||
$(MAKE) npqtv-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPQTVB_DIR)"
|
$(MAKE) npfte-tmp TYPE=_cl-rel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)"
|
||||||
npqtv-dbg:
|
cp $(RELEASE_DIR)/npfte.dll npfte/plugins
|
||||||
$(MAKE) npqtv-tmp TYPE=_clsv-dbg OUT_DIR="$(DEBUG_DIR)/$(NPQTVB_DIR)"
|
cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) * plugins/*
|
||||||
npqtv-profile:
|
npfte-dbg:
|
||||||
$(MAKE) npqtv-tmp TYPE=_cl-profile OUT_DIR="$(PROFILE_DIR)/$(NPQTVB_DIR)"
|
$(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:
|
glcl-tmp:
|
||||||
$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GLCL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)"
|
$(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 "'gl-???' (OpenGL rendering + Built-in Server)"
|
||||||
@-echo "'m-???' (Merged client, OpenGL & D3D rendering + Dedicated server)"
|
@-echo "'m-???' (Merged client, OpenGL & D3D rendering + Dedicated server)"
|
||||||
@-echo "'mingl-???' (Minimal featured OpenGL render)"
|
@-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 "'d3d-???' (for windows builds)"
|
||||||
@-echo "'mcl-???' (currently broken)"
|
@-echo "'mcl-???' (currently broken)"
|
||||||
@-echo "'glcl-???' (currently broken)"
|
@-echo "'glcl-???' (currently broken)"
|
||||||
|
@-echo "'droid-???' (build Android package)"
|
||||||
@-echo ""
|
@-echo ""
|
||||||
@-echo "Cross targets can be specified with FTE_TARGET=blah"
|
@-echo "Cross targets can be specified with FTE_TARGET=blah"
|
||||||
@-echo "linux32, linux64 specify specific x86 archs"
|
@-echo "linux32, linux64 specify specific x86 archs"
|
||||||
|
@ -1120,4 +1129,39 @@ clean:
|
||||||
-rm -f -r $(RELEASE_DIR)
|
-rm -f -r $(RELEASE_DIR)
|
||||||
-rm -f -r $(DEBUG_DIR)
|
-rm -f -r $(DEBUG_DIR)
|
||||||
-rm -f -r $(PROFILE_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
|
||||||
|
|
||||||
|
|
|
@ -3703,7 +3703,7 @@ Host_Init
|
||||||
*/
|
*/
|
||||||
void Host_Init (quakeparms_t *parms)
|
void Host_Init (quakeparms_t *parms)
|
||||||
{
|
{
|
||||||
#ifndef NPQTV
|
#ifndef NPFTE
|
||||||
int i;
|
int i;
|
||||||
int qrc, hrc, def;
|
int qrc, hrc, def;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3787,7 +3787,7 @@ void Host_Init (quakeparms_t *parms)
|
||||||
|
|
||||||
host_initialized = true;
|
host_initialized = true;
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host_FinishInit(void)
|
void Host_FinishInit(void)
|
||||||
|
|
|
@ -5651,8 +5651,8 @@ void CSQC_Breakpoint_f(void)
|
||||||
Con_Printf("CSQC not running\n");
|
Con_Printf("CSQC not running\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wasset = svprogfuncs->ToggleBreak(csqcprogs, filename, line, 3);
|
wasset = csqcprogs->ToggleBreak(csqcprogs, filename, line, 3);
|
||||||
isset = svprogfuncs->ToggleBreak(csqcprogs, filename, line, 2);
|
isset = csqcprogs->ToggleBreak(csqcprogs, filename, line, 2);
|
||||||
|
|
||||||
if (wasset == isset)
|
if (wasset == isset)
|
||||||
Con_Printf("Breakpoint was not valid\n");
|
Con_Printf("Breakpoint was not valid\n");
|
||||||
|
|
|
@ -1863,9 +1863,9 @@ void VARGS Menu_Abort (char *format, ...)
|
||||||
|
|
||||||
void MP_CvarChanged(cvar_t *var)
|
void MP_CvarChanged(cvar_t *var)
|
||||||
{
|
{
|
||||||
if (svprogfuncs)
|
if (menuprogs)
|
||||||
{
|
{
|
||||||
PR_AutoCvar(svprogfuncs, var);
|
PR_AutoCvar(menuprogs, var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
444
engine/client/sys_droid.c
Normal file
444
engine/client/sys_droid.c
Normal file
|
@ -0,0 +1,444 @@
|
||||||
|
#include <jni.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
*/
|
|
@ -750,7 +750,7 @@ void VARGS Sys_Error (const char *error, ...)
|
||||||
SetHookState(false);
|
SetHookState(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
{
|
{
|
||||||
extern jmp_buf host_abort;
|
extern jmp_buf host_abort;
|
||||||
/*jump to start of main loop (which exits the main loop)*/
|
/*jump to start of main loop (which exits the main loop)*/
|
||||||
|
@ -800,7 +800,7 @@ void Sys_Quit (void)
|
||||||
SV_Shutdown();
|
SV_Shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
{
|
{
|
||||||
extern jmp_buf host_abort;
|
extern jmp_buf host_abort;
|
||||||
/*jump to start of main loop (which exits the main loop)*/
|
/*jump to start of main loop (which exits the main loop)*/
|
||||||
|
@ -1211,7 +1211,7 @@ qboolean Sys_Startup_CheckMem(quakeparms_t *parms)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
static quakeparms_t parms;
|
static quakeparms_t parms;
|
||||||
double lastlooptime;
|
double lastlooptime;
|
||||||
qboolean NPQTV_Sys_Startup(int argc, char *argv[])
|
qboolean NPQTV_Sys_Startup(int argc, char *argv[])
|
||||||
|
|
|
@ -234,6 +234,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
//fix things a little...
|
//fix things a little...
|
||||||
#ifdef NPQTV
|
#ifdef NPQTV
|
||||||
|
#define NPFTE
|
||||||
|
#undef NPQTV
|
||||||
|
#endif
|
||||||
|
#ifdef NPFTE
|
||||||
/*plugins require threads and stuff now, and http download support*/
|
/*plugins require threads and stuff now, and http download support*/
|
||||||
#ifndef MULTITHREAD
|
#ifndef MULTITHREAD
|
||||||
#define MULTITHREAD
|
#define MULTITHREAD
|
||||||
|
@ -254,7 +258,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
#undef TEXTEDITOR
|
#undef TEXTEDITOR
|
||||||
#undef WEBSERVER
|
#undef WEBSERVER
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2060,7 +2060,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
|
||||||
return true;
|
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)
|
if (poshname)
|
||||||
{
|
{
|
||||||
char resultpath[MAX_PATH];
|
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);
|
Q_snprintfz(com_homedir, sizeof(com_homedir), "%s/My Documents/My Games/%s/", ev, FULLENGINENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
if (!*com_homedir)
|
if (!*com_homedir)
|
||||||
Q_snprintfz(com_homedir, sizeof(com_homedir), "/%s/", FULLENGINENAME);
|
Q_snprintfz(com_homedir, sizeof(com_homedir), "/%s/", FULLENGINENAME);
|
||||||
//as a browser plugin, always use their home directory
|
//as a browser plugin, always use their home directory
|
||||||
|
@ -2484,7 +2484,7 @@ extern searchpathfuncs_t doomwadfilefuncs;
|
||||||
void FS_RegisterDefaultFileSystems(void)
|
void FS_RegisterDefaultFileSystems(void)
|
||||||
{
|
{
|
||||||
FS_RegisterFileSystemType("pak", &packfilefuncs);
|
FS_RegisterFileSystemType("pak", &packfilefuncs);
|
||||||
#ifndef _WIN32
|
#if !defined(_WIN32) && !defined(ANDROID)
|
||||||
/*for systems that have case sensitive paths, also include *.PAK */
|
/*for systems that have case sensitive paths, also include *.PAK */
|
||||||
FS_RegisterFileSystemType("PAK", &packfilefuncs);
|
FS_RegisterFileSystemType("PAK", &packfilefuncs);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -84,7 +84,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
|
||||||
return (vfsfile_t*)file;
|
return (vfsfile_t*)file;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID
|
#if 0//def ANDROID
|
||||||
vfsfile_t *Sys_OpenAsset(const char *fname);
|
vfsfile_t *Sys_OpenAsset(const char *fname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
|
||||||
char newmode[3];
|
char newmode[3];
|
||||||
int modec = 0;
|
int modec = 0;
|
||||||
|
|
||||||
#ifdef ANDROID
|
#if 0//def ANDROID
|
||||||
// if (!strncmp("asset/", osname, 6))
|
// if (!strncmp("asset/", osname, 6))
|
||||||
{
|
{
|
||||||
if (append || write)
|
if (append || write)
|
||||||
|
|
|
@ -112,7 +112,7 @@ void Sys_DestroyConditional(void *condv);
|
||||||
|
|
||||||
void Sys_Sleep(double seconds);
|
void Sys_Sleep(double seconds);
|
||||||
|
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
qboolean NPQTV_Sys_Startup(int argc, char *argv[]);
|
qboolean NPQTV_Sys_Startup(int argc, char *argv[]);
|
||||||
void NPQTV_Sys_MainLoop(void);
|
void NPQTV_Sys_MainLoop(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
20
engine/droid/AndroidManifest.xml
Normal file
20
engine/droid/AndroidManifest.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.fteqw"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
<uses-sdk android:minSdkVersion="8" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||||
|
|
||||||
|
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||||
|
<activity android:name=".FTEDroidActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</manifest>
|
BIN
engine/droid/res/drawable-hdpi/icon.png
Normal file
BIN
engine/droid/res/drawable-hdpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4 KiB |
BIN
engine/droid/res/drawable-ldpi/icon.png
Normal file
BIN
engine/droid/res/drawable-ldpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
engine/droid/res/drawable-mdpi/icon.png
Normal file
BIN
engine/droid/res/drawable-mdpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
4
engine/droid/res/values/strings.xml
Normal file
4
engine/droid/res/values/strings.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">FTEDroid</string>
|
||||||
|
</resources>
|
226
engine/droid/src/com/fteqw/FTEDroidActivity.java
Normal file
226
engine/droid/src/com/fteqw/FTEDroidActivity.java
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
14
engine/droid/src/com/fteqw/FTEDroidEngine.java
Normal file
14
engine/droid/src/com/fteqw/FTEDroidEngine.java
Normal file
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
//FIXME: this shouldn't be defined
|
||||||
|
#define FORCESTATE
|
||||||
|
#else
|
||||||
//#define FORCESTATE
|
//#define FORCESTATE
|
||||||
|
#endif
|
||||||
//#define WIREFRAME
|
//#define WIREFRAME
|
||||||
|
|
||||||
#ifdef GLQUAKE
|
#ifdef GLQUAKE
|
||||||
|
|
|
@ -336,10 +336,20 @@ void GLDraw_ReInit (void)
|
||||||
|
|
||||||
maxtexsize = gl_max_size.value;
|
maxtexsize = gl_max_size.value;
|
||||||
|
|
||||||
if (maxtexsize < 2048) //this needs to be able to hold the image in unscaled form.
|
if (gl_config.gles)
|
||||||
sizeofuploadmemorybufferintermediate = 2048*2048*4; //make sure we can load 2048*2048 images whatever happens.
|
{
|
||||||
|
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
|
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
|
//required to hold the image after scaling has occured
|
||||||
sizeofuploadmemorybuffer = maxtexsize*maxtexsize*4;
|
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)
|
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)
|
if (mipmap)
|
||||||
|
@ -964,6 +983,41 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap)
|
||||||
if (*scaled_height < 1)
|
if (*scaled_height < 1)
|
||||||
*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
|
GL_Upload32
|
||||||
|
@ -975,6 +1029,7 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
||||||
int samples;
|
int samples;
|
||||||
unsigned *scaled = (unsigned *)uploadmemorybuffer;
|
unsigned *scaled = (unsigned *)uploadmemorybuffer;
|
||||||
int scaled_width, scaled_height;
|
int scaled_width, scaled_height;
|
||||||
|
int type;
|
||||||
|
|
||||||
TRACE(("dbg: GL_Upload32: %s %i %i\n", name, width, height));
|
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");
|
Sys_Error ("GL_LoadTexture: too big");
|
||||||
|
|
||||||
if (gl_config.gles)
|
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
|
else
|
||||||
|
{
|
||||||
samples = (flags&IF_NOALPHA) ? GL_RGB : GL_RGBA;
|
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))
|
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;
|
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... :)
|
if ((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :)
|
||||||
{
|
{
|
||||||
TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n"));
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
memcpy (scaled, data, width*height*4);
|
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);
|
GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
|
||||||
|
|
||||||
TRACE(("dbg: GL_Upload32: recaled\n"));
|
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)
|
if (!(flags&IF_NOMIPMAP) && !gl_config.sgis_generate_mipmap)
|
||||||
{
|
{
|
||||||
miplevel = 0;
|
miplevel = 0;
|
||||||
|
@ -1065,9 +1152,15 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
||||||
if (scaled_height < 1)
|
if (scaled_height < 1)
|
||||||
scaled_height = 1;
|
scaled_height = 1;
|
||||||
miplevel++;
|
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))
|
if (gl_config.arb_texture_compression && gl_compress.value && gl_savecompressedtex.value && name && !(flags&IF_NOMIPMAP))
|
||||||
{
|
{
|
||||||
vfsfile_t *out;
|
vfsfile_t *out;
|
||||||
|
|
327
engine/gl/gl_viddroid.c
Normal file
327
engine/gl/gl_viddroid.c
Normal file
|
@ -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 <EGL/egl.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -672,7 +672,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
qboolean stat;
|
qboolean stat;
|
||||||
#ifndef NPQTV
|
#ifndef NPFTE
|
||||||
MSG msg;
|
MSG msg;
|
||||||
#endif
|
#endif
|
||||||
// HDC hdc;
|
// HDC hdc;
|
||||||
|
@ -747,7 +747,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
|
||||||
SetForegroundWindow (mainwindow);
|
SetForegroundWindow (mainwindow);
|
||||||
VID_SetPalette (palette);
|
VID_SetPalette (palette);
|
||||||
|
|
||||||
#ifndef NPQTV
|
#ifndef NPFTE
|
||||||
/*I don't like this, but if we */
|
/*I don't like this, but if we */
|
||||||
while (PeekMessage (&msg, mainwindow, 0, 0, PM_REMOVE))
|
while (PeekMessage (&msg, mainwindow, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
|
@ -1666,7 +1666,7 @@ LONG WINAPI GLMainWndProc (
|
||||||
if (wParam & MK_LBUTTON)
|
if (wParam & MK_LBUTTON)
|
||||||
{
|
{
|
||||||
temp |= 1;
|
temp |= 1;
|
||||||
#ifdef NPQTV
|
#ifdef NPFTE
|
||||||
SetFocus(hWnd);
|
SetFocus(hWnd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,17 @@ extern qlpMTex2FUNC qglMultiTexCoord2fARB;
|
||||||
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 /*opengl 1.2*/
|
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 /*opengl 1.2*/
|
||||||
#endif
|
#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
|
#ifndef GL_ARB_multitexture
|
||||||
#define GL_ARB_multitexture 1
|
#define GL_ARB_multitexture 1
|
||||||
#define GL_TEXTURE0_ARB 0x84C0
|
#define GL_TEXTURE0_ARB 0x84C0
|
||||||
|
|
|
@ -453,7 +453,7 @@ qboolean World_MoveToGoal (world_t *world, wedict_t *ent, float dist)
|
||||||
{
|
{
|
||||||
wedict_t *goal;
|
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);
|
goal = (wedict_t*)PROG_TO_EDICT(world->progs, ent->v->goalentity);
|
||||||
|
|
||||||
if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
|
if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
|
||||||
|
|
Loading…
Reference in a new issue