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:
Spoike 2011-09-16 05:56:54 +00:00
parent 6236971e48
commit 4b27934867
23 changed files with 1253 additions and 61 deletions

View File

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

View File

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

View File

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

View File

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

444
engine/client/sys_droid.c Normal file
View 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;
}
*/

View File

@ -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[])

View File

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

View File

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

View File

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

View File

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

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

View 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();
}
}

View 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");
}
}

View File

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

View File

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

327
engine/gl/gl_viddroid.c Normal file
View 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;
}

View File

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

View File

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

View File

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