Remove NaCl code (#190)
* Remove the nacl dir * Remove nacl from ifdef checks shared with other platforms * Remove nacl from build bash scripts * More removal of nacl from bash scripts * Remove nacl-specific code from the engine * More removal of nacl-specific code from the engine * remove nacl-specific code from the Quake 3 plugin * Remove nacl from readme (also seems to have force LF line endings) * Remove nacl mention from browser.txt * Remove nacl from Makefile * Remove nacl from dotnet2005 solution file (lol) * Correcting an endif, this did not end nacl * Clarification for NaCL no longer needed * Left small todo for myself * Partially undo f44daef091bcc5917b0ddb2cbe41ebdd9738f770 the if preproc checking for `_DEBUG` was incorrectly removed
This commit is contained in:
parent
7f8b827cb8
commit
6d83a3218a
28 changed files with 115 additions and 2721 deletions
20
README.txt
20
README.txt
|
@ -23,7 +23,7 @@ Easy Build Bot System:
|
|||
If you want to set up a linux box that cross-compiles each target with your own private customisations, then you can run the build_setup.sh script to set up which targets you wish to support.
|
||||
You can then just run the build_wip.sh script any time your code changes to have it rebuild every target you previously picked.
|
||||
The script can also be run from cygwin, but does not support compiling for linux then.
|
||||
(The setup script will install android+emscripten+nacl dependancies for you, so you're likely to find this an easier way to deal with those special targets).
|
||||
(The setup script will install android+emscripten dependancies for you, so you're likely to find this an easier way to deal with those special targets).
|
||||
(note that the android sdk can be a big download, while installing emscripten may require several hours to compile clang and about 40gb of disk space if emscripten doesn't provide prebuilt stuff for your distro).
|
||||
|
||||
|
||||
|
@ -48,24 +48,6 @@ If given an 'npfte.txt' file that contains the line 'relexe foo', the plugin wil
|
|||
The following chunk of html can then be included on a web page to embed it. Yes. Two nested objects.
|
||||
<object name="ieplug" type="text/x-quaketvident" classid="clsid:7d676c9f-fb84-40b6-b3ff-e10831557eeb" width=100% height=100% ><param name="splash" value="http://127.0.0.1:27599/qtvsplash.jpg"><param name="game" value="q1"><param name="dataDownload" value=''><object name="npplug" type="text/x-quaketvident" width=100% height=100% ><param name="splash" value="http://127.0.0.1:27599/qtvsplash.jpg"><param name="game" value="q1"><param name="dataDownload" value=''>Plugin failed to load</object></object>
|
||||
|
||||
Nacl version of FTE:
|
||||
make gl-rel FTE_TARGET=nacl NACL_SDK_ROOT=SOMEVALIDPATHHERE BITS=32
|
||||
make gl-rel FTE_TARGET=nacl NACL_SDK_ROOT=SOMEVALIDPATHHERE BITS=64
|
||||
in windows compile with cygwin, not minsys.
|
||||
This will give you two 'nexe' files.
|
||||
You can then embed the 'fteqw.nmf' file (its entire contents can be found on the following line) with mime type 'application/x-nacl' on your page. Give it a sane width/height.
|
||||
{
|
||||
"program": {
|
||||
"x86-64": {"url": "fteqw_x86_64.nexe"},
|
||||
"x86-32": {"url": "fteqw_x86_32.nexe"}
|
||||
}
|
||||
}
|
||||
|
||||
You can object.postMessage("join foo") / qtvplay / map to tell it to switch server/map/stream.
|
||||
You can read console prints via listener.addEventListener('message', handleMessage, true);
|
||||
Your users will need to explicitly allow nacl use outside of google play (in about:config or whatever it is), or you will need to submit your port of fte to google play.
|
||||
|
||||
|
||||
|
||||
This stuff has separate directories
|
||||
engine: FTEQW game engine itself. Both client and dedicated server.
|
||||
|
|
|
@ -17,10 +17,6 @@ OSXCROSSROOT=$FTEROOT/osxcross
|
|||
#emscripten defaults
|
||||
EMSCRIPTENROOT=$FTEROOT/emsdk-portable
|
||||
|
||||
#nacl defaults
|
||||
NACLROOT=$FTEROOT/nacl_sdk
|
||||
NACLSDKVERSION=pepper_49
|
||||
|
||||
#android defaults
|
||||
ANDROIDROOT=$FTEROOT/android
|
||||
if [ ! -z "$(uname -o 2>&1 | grep Cygwin)" ]; then
|
||||
|
@ -187,7 +183,6 @@ if [ "$REUSE_CONFIG" != "y" ]; then
|
|||
else
|
||||
echo "Skipping mac option."
|
||||
fi
|
||||
read -n 1 -p "Build for NaCL? [y/N] " BUILD_NACL && echo
|
||||
fi
|
||||
|
||||
BUILD_CLEAN=${BUILD_CLEAN:-y}
|
||||
|
@ -205,7 +200,6 @@ BUILD_SDL=${BUILD_SDL:-n}
|
|||
BUILD_ANDROID=${BUILD_ANDROID:-n}
|
||||
BUILD_WEB=${BUILD_WEB:-n}
|
||||
BUILD_MAC=${BUILD_MAC:-n}
|
||||
BUILD_NACL=${BUILD_NACL:-n}
|
||||
|
||||
if [ "$UID" != "0" ]; then
|
||||
echo "#path config for fte build scripts" >$FTECONFIG
|
||||
|
@ -218,9 +212,6 @@ if [ "$UID" != "0" ]; then
|
|||
echo "export ANDROID_ZIPALIGN=\"$ANDROID_ZIPALIGN\"" >>$FTECONFIG
|
||||
echo "EMSCRIPTENROOT=\"$EMSCRIPTENROOT\"" >>$FTECONFIG
|
||||
echo "OSXCROSSROOT=\"$OSXCROSSROOT\"" >>$FTECONFIG
|
||||
echo "NACLROOT=\"$NACLROOT\"" >>$FTECONFIG
|
||||
echo "NACL_SDK_ROOT=\"$NACLROOT/nacl_sdk/$NACLSDKVERSION\"" >>$FTECONFIG
|
||||
echo "NACLSDKVERSION=\"$NACLSDKVERSION\"" >>$FTECONFIG
|
||||
|
||||
echo "BUILD_CLEAN=\"$BUILD_CLEAN\"" >>$FTECONFIG
|
||||
|
||||
|
@ -238,7 +229,6 @@ if [ "$UID" != "0" ]; then
|
|||
echo "BUILD_SDL=\"$BUILD_SDL\"" >>$FTECONFIG
|
||||
echo "BUILD_WEB=\"$BUILD_WEB\"" >>$FTECONFIG
|
||||
echo "BUILD_MAC=\"$BUILD_MAC\"" >>$FTECONFIG
|
||||
echo "BUILD_NACL=\"$BUILD_NACL\"" >>$FTECONFIG
|
||||
|
||||
echo "TARGETS_WINDOWS=\"$TARGETS_WINDOWS\"" >>$FTECONFIG
|
||||
echo "TARGETS_LINUX=\"$TARGETS_LINUX\"" >>$FTECONFIG
|
||||
|
@ -441,16 +431,6 @@ if [ "$BUILD_MAC" == "y" ] && [ $UID -ne 0 ] && [ $REBUILD_TOOLCHAINS == "y" ] &
|
|||
cd ~
|
||||
fi
|
||||
|
||||
if [ "$BUILD_NACL" == "y" ] && [ $UID -ne 0 ] && [ $REBUILD_TOOLCHAINS == "y" ]; then
|
||||
echo "Setting up NaCL..."
|
||||
mkdir -p $NACLROOT
|
||||
cd $NACLROOT/..
|
||||
wget -N https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/nacl_sdk.zip
|
||||
unzip -qn nacl_sdk.zip
|
||||
cd $NACLROOT
|
||||
./naclsdk update $NACLSDKVERSION
|
||||
fi
|
||||
|
||||
|
||||
if [ $UID -ne 0 ] && [ $REBUILD_TOOLCHAINS == "y" ]; then
|
||||
#initial checkout of fte's svn
|
||||
|
|
36
build_wip.sh
36
build_wip.sh
|
@ -31,8 +31,6 @@ TARGETS_LINUX="qcc-rel rel dbg vk-rel plugins-rel plugins-dbg"
|
|||
TARGETS_WINDOWS="sv-rel m-rel qcc-rel qccgui-scintilla qccgui-dbg m-dbg sv-dbg plugins-dbg plugins-rel"
|
||||
TARGETS_WEB="gl-rel"
|
||||
|
||||
########### NaCL stuff
|
||||
NACL_SDK_ROOT=/opt/nacl_sdk/pepper_31/
|
||||
|
||||
if [ -e $FTECONFIG ]; then
|
||||
. $FTECONFIG
|
||||
|
@ -106,7 +104,6 @@ done
|
|||
|
||||
MAKEARGS="$THREADS $TARGET"
|
||||
|
||||
export NACL_SDK_ROOT
|
||||
|
||||
########### Emscripten / Web Stuff
|
||||
export EMSDK=$EMSCRIPTENROOT
|
||||
|
@ -264,13 +261,6 @@ fi
|
|||
if [ "$BUILD_SDL_WIN64" == "y" ]; then
|
||||
build "Windows 64-bit (SDL)" win64_sdl FTE_TARGET=win64_SDL $TARGETS_SDL
|
||||
fi
|
||||
if [ "$BUILD_NACL" != "n" ]; then
|
||||
#non-pnacl is supported ONLY in chrome's store crap, but pnacl works anywhere.
|
||||
# build "Native Client 64-bit" nacl_amd64 FTE_TARGET=nacl NARCH=x86_64 gl-rel
|
||||
# build "Native Client 32-bit" nacl_x86 FTE_TARGET=nacl NARCH=x86_32 gl-rel
|
||||
#internal compiler error build "Native Client ARM" nacl_arm FTE_TARGET=nacl NARCH=arm gl-rel
|
||||
build "Native Client Portable" nacl_portable FTE_TARGET=nacl NARCH=pnacl gl-rel
|
||||
fi
|
||||
####build "MorphOS" morphos CFLAGS="-I$BASE/morphos/os-include/ -I$BASE/morphos/lib/ -L$BASE/morphos/lib/ -I$BASE/zlib/zlib-1.2.5 -L$BASE/zlib/zlib-1.2.5 -I./libs $WARNINGLEVEL" gl-rel mingl-rel sv-rel qcc-rel
|
||||
if [ "$BUILD_MAC" != "n" ]; then
|
||||
#build "MacOSX" macosx_tiger CFLAGS="-I$BASE/mac/x86/include/ -L$BASE/mac/x86/lib -I./libs" FTE_TARGET=macosx_x86 sv-rel gl-rel mingl-rel qcc-rel
|
||||
|
@ -279,6 +269,7 @@ if [ "$BUILD_MAC" != "n" ]; then
|
|||
build "MacOSX 64-bit" osx64 CC=o64-clang CXX=o64-clang++ FTE_TARGET=osx_x86_64 BITS=64 sv-rel gl-rel mingl-rel qcc-rel
|
||||
fi
|
||||
|
||||
|
||||
#third party stuff / misc crap
|
||||
if [ "$BUILD_WEB" != "n" ]; then
|
||||
cp $BASE/3rdparty/web/* $BUILDFOLDER/web/
|
||||
|
@ -358,31 +349,6 @@ fi
|
|||
#cp $BUILDFOLDER/macosx_tiger/fteqcc $QCCBUILDFOLDER/macosx_tiger-fteqcc
|
||||
cp $BUILDFOLDER/version.txt $QCCBUILDFOLDER/version.txt
|
||||
|
||||
if [ "$BUILD_NACL" != "n" ]; then
|
||||
mkdir -p $BUILDFOLDER/nacl
|
||||
NACL=$BUILDFOLDER/nacl/fteqw.nmf
|
||||
echo "{ \"program\":{" > $NACL
|
||||
if [ -e "$BUILDFOLDER/nacl_amd64/fteqw-x86_64.nexe" ]; then
|
||||
mv $BUILDFOLDER/nacl_amd64/fteqw-x86_64.nexe $BUILDFOLDER/nacl/fteqw-x86_64.nexe
|
||||
echo " \"x86-64\":{\"url\":\"fteqw-x86_64.nexe\"}," >> $NACL
|
||||
fi
|
||||
if [ -e "$BUILDFOLDER/nacl_x86/fteqw-x86_32.nexe" ]; then
|
||||
mv $BUILDFOLDER/nacl_x86/fteqw-x86_32.nexe $BUILDFOLDER/nacl/fteqw-x86_32.nexe
|
||||
echo " \"x86-32\":{\"url\":\"fteqw-x86_32.nexe\"}," >> $NACL
|
||||
fi
|
||||
if [ -e "$BUILDFOLDER/nacl_arm/fteqw-arm.nexe" ]; then
|
||||
mv $BUILDFOLDER/nacl_arm/fteqw-arm.nexe $BUILDFOLDER/nacl/fteqw-arm.nexe
|
||||
echo " \"arm\":{\"url\":\"fteqw-arm.nexe\"}" >> $NACL
|
||||
fi
|
||||
$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-finalize -o $BUILDFOLDER/nacl/fteqw.pexe $BUILDFOLDER/nacl_portable/fteqw.pexe
|
||||
echo " \"portable\":{\"pnacl-translate\":{\"url\":\"fteqw.pexe\"}}" >> $NACL
|
||||
echo "} }" >> $NACL
|
||||
rm -rf "$BUILDFOLDER/nacl_amd64"
|
||||
rm -rf "$BUILDFOLDER/nacl_x86"
|
||||
rm -rf "$BUILDFOLDER/nacl_arm"
|
||||
rm -rf "$BUILDFOLDER/nacl_portable"
|
||||
fi
|
||||
|
||||
if [ "$BUILD_WIN32" != "n" ] && [ "$BUILD_WIN64" != "n" ]; then
|
||||
echo Archiving output
|
||||
SVNVER=$(svnversion $SVNROOT)
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#linux->morphos (FTE_TARGET=morphos)
|
||||
#linux->macosx (FTE_TARGET=macosx) or (FTE_TARGET=macosx_x86)
|
||||
#linux->javascript (FTE_TARGET=web)
|
||||
#linux->nacl (FTE_TARGET=nacl NARCH=x86_64) deprecated.
|
||||
#win32->nacl
|
||||
#linux->droid (make droid)
|
||||
#win32->droid (make droid)
|
||||
#if you are cross compiling, you'll need to use FTE_TARGET=mytarget
|
||||
|
@ -574,7 +572,6 @@ HTTP_DIR=$(BASE_DIR)/http
|
|||
#LIBS_DIR=$(BASE_DIR)/libs
|
||||
LIBS_DIR?=.
|
||||
PROGS_DIR=$(BASE_DIR)/qclib
|
||||
NACL_DIR=$(BASE_DIR)/nacl
|
||||
|
||||
ifeq ($(NOCOMPAT),1)
|
||||
NCCFLAGS=-DNOLEGACY -DOMIT_QCC
|
||||
|
@ -717,7 +714,7 @@ ifeq ($(FTE_TARGET),SDL2)
|
|||
BASE_CFLAGS+=-DLIBJPEG_STATIC -DLIBJPEG_STATIC -DLIBPNG_STATIC -DOPUS_STATIC -DSPEEX_STATIC -DFREETYPE_STATIC -DLIBVORBISFILE_STATIC
|
||||
endif
|
||||
|
||||
VPATH := $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(SW_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BASE_DIR)/web
|
||||
VPATH := $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(SW_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(QUX_DIR) : $(PROGS_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BASE_DIR)/web
|
||||
|
||||
PROFILE_CFLAGS=-pg
|
||||
DX7SDK=-I./libs/dxsdk7/include/
|
||||
|
@ -1136,76 +1133,6 @@ endif
|
|||
|
||||
|
||||
#specific targets override those defaults as needed.
|
||||
#google native client
|
||||
ifeq ($(FTE_TARGET),nacl)
|
||||
CLIENTLDDEPS=
|
||||
SERVERLDDEPS=
|
||||
|
||||
NARCH ?= x86_32
|
||||
ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
|
||||
MYOS=linux
|
||||
else
|
||||
MYOS=win
|
||||
endif
|
||||
|
||||
CC=
|
||||
CXX=
|
||||
STRIP=@echo SKIP: strip
|
||||
NACLLIBC=glibc
|
||||
ifeq ($(NARCH),x86_32)
|
||||
CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-gcc -DNACL -m32
|
||||
CXX=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-g++ -DNACL -m32
|
||||
STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-strip
|
||||
BITS=
|
||||
NACLLIBS=$(NACLLIBC)_x86_32/Release
|
||||
endif
|
||||
ifeq ($(NARCH),x86_64)
|
||||
CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-gcc -DNACL -m64
|
||||
CXX=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-g++ -DNACL -m64
|
||||
STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-strip
|
||||
BITS=
|
||||
NACLLIBS=$(NACLLIBC)_x86_64/Release
|
||||
endif
|
||||
ifeq ($(NARCH),arm)
|
||||
CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_arm_$(NACLLIBC)/bin/arm-nacl-gcc -DNACL
|
||||
CXX=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_arm_$(NACLLIBC)/bin/arm-nacl-g++ -DNACL
|
||||
STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_arm_$(NACLLIBC)/bin/arm-nacl-strip
|
||||
BITS=
|
||||
NACLLIBS=$(NACLLIBC)_arm/Release
|
||||
endif
|
||||
ifeq ($(NARCH),pnacl)
|
||||
CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_pnacl/bin/pnacl-clang -DNACL
|
||||
CXX=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_pnacl/bin/pnacl-clang++ -DNACL
|
||||
STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_pnacl/bin/pnacl-strip
|
||||
STRIPFLAGS=
|
||||
BITS=
|
||||
NACLLIBS=pnacl/Release
|
||||
endif
|
||||
|
||||
BASELDFLAGS = -lm -lppapi_gles2 -lnosys -lppapi
|
||||
IMAGELDFLAGS =
|
||||
|
||||
GL_CFLAGS=$(GLCFLAGS)
|
||||
GL_CFLAGS+=-I$(realpath $(NACL_SDK_ROOT)/include)
|
||||
BASELDFLAGS+=-L$(realpath $(NACL_SDK_ROOT)/lib/$(NACLLIBS))
|
||||
|
||||
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o
|
||||
|
||||
GL_LDFLAGS=$(GLLDFLAGS)
|
||||
M_LDFLAGS=$(GLLDFLAGS)
|
||||
|
||||
GLB_DIR=gl_nacl_$(NARCH)
|
||||
MINGL_DIR=mingl_nacl_$(NARCH)
|
||||
ifeq ($(NARCH),pnacl)
|
||||
GL_EXE_NAME=../$(EXE_NAME).pexe
|
||||
GLCL_EXE_NAME=../$(EXE_NAME)-cl.pexe
|
||||
MINGL_EXE_NAME=../$(EXE_NAME)-mingl.pexe
|
||||
else
|
||||
GL_EXE_NAME=../$(EXE_NAME)-$(NARCH).nexe
|
||||
GLCL_EXE_NAME=../$(EXE_NAME)-cl-$(NARCH).nexe
|
||||
MINGL_EXE_NAME=../$(EXE_NAME)-mingl-$(NARCH).nexe
|
||||
endif
|
||||
endif
|
||||
|
||||
#FTE_TARGET=win32_SDL | FTE_TARGET=win64_SDL (MinGW32 + SDL | MinGW64 + SDL)
|
||||
ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
|
||||
|
@ -2211,14 +2138,13 @@ help:
|
|||
@-echo "'droid-???' (cross compiles Android package)"
|
||||
@-echo "'web-???' (compiles javascript/emscripten page)"
|
||||
@-echo "'npfte-???' (cross compiles QuakeTV Firefox/Netscape browser plugin)"
|
||||
@-echo "'nacl-???' (cross compiles QuakeTV Firefox/Netscape browser plugin)"
|
||||
@-echo ""
|
||||
@-echo "Cross targets can be specified with FTE_TARGET=blah"
|
||||
@-echo "linux32, linux64 specify specific x86 archs"
|
||||
@-echo "SDL - Attempt to use sdl for the current target"
|
||||
@-echo "win32 - Mingw compile for win32"
|
||||
@-echo "vc - Attempts to use msvc8+ to compile. Note: uses profile guided optimisations. You must build+run the relevent profile target before a release target will compile properly. Debug doesn't care."
|
||||
@-echo "android, npfte, nacl targets explicitly cross compile, and should generally not be given an FTE_TARGET."
|
||||
@-echo "android, npfte, targets explicitly cross compile, and should generally not be given an FTE_TARGET."
|
||||
|
||||
clean:
|
||||
-rm -f -r $(RELEASE_DIR)
|
||||
|
@ -2266,20 +2192,6 @@ npfte-profile:
|
|||
@$(MAKE) npfte-tmp TYPE=_npfte-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTEB_DIR)"
|
||||
|
||||
|
||||
#################################################
|
||||
#nacl shortcut
|
||||
|
||||
nacl-rel:
|
||||
@$(MAKE) gl-rel FTE_TARGET=nacl NARCH=x86_32
|
||||
@$(MAKE) gl-rel FTE_TARGET=nacl NARCH=x86_64
|
||||
@$(MAKE) gl-rel FTE_TARGET=nacl NARCH=arm
|
||||
@$(MAKE) gl-rel FTE_TARGET=nacl NARCH=pnacl
|
||||
nacl-dbg:
|
||||
@$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=x86_32
|
||||
@$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=x86_64
|
||||
@$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=arm
|
||||
@$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=pnacl
|
||||
|
||||
#################################################
|
||||
#webgl helpers
|
||||
|
||||
|
|
|
@ -4375,7 +4375,7 @@ static void Mods_Draw(int x, int y, struct menucustom_s *c, struct emenu_s *m)
|
|||
R_DrawTextField(0, y, vid.width, vid.height - y,
|
||||
va(
|
||||
"No games or mods known.\n"
|
||||
#if defined(FTE_TARGET_WEB) || defined(NACL)
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
"Connection issue or bad server config.\n"
|
||||
#else
|
||||
#ifndef ANDROID
|
||||
|
|
|
@ -1862,9 +1862,6 @@ sounddriver_t fte_weakstruct Droid_AudioOutput;
|
|||
#if defined(__MORPHOS__)
|
||||
sounddriver_t fte_weakstruct AHI_AudioOutput; //prefered on morphos
|
||||
#endif
|
||||
#ifdef NACL
|
||||
extern sounddriver_t PPAPI_AudioOutput; //nacl
|
||||
#endif
|
||||
sounddriver_t fte_weakstruct SNDIO_AudioOutput; //bsd
|
||||
|
||||
//in order of preference
|
||||
|
@ -1910,9 +1907,6 @@ static sounddriver_t *outputdrivers[] =
|
|||
#endif
|
||||
#if defined(__MORPHOS__)
|
||||
&AHI_AudioOutput, //prefered on morphos
|
||||
#endif
|
||||
#ifdef NACL
|
||||
&PPAPI_AudioOutput, //google's native client
|
||||
#endif
|
||||
&SNDIO_AudioOutput, //prefered on OpenBSD
|
||||
|
||||
|
|
|
@ -52,13 +52,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define HAVE_PACKET
|
||||
#endif
|
||||
|
||||
#ifdef NACL
|
||||
#define NO_PNG
|
||||
#define NO_JPEG
|
||||
#define NO_OGG
|
||||
#define NO_ZLIB
|
||||
#endif
|
||||
|
||||
#ifndef MULTITHREAD
|
||||
#if !defined(_WIN32) || defined(FTE_SDL) //win32 is annoying
|
||||
#define NO_MULTITHREAD
|
||||
|
@ -350,24 +343,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
#define NO_OPENAL
|
||||
#endif
|
||||
#if defined(NACL)
|
||||
//stuff is sandboxed.
|
||||
#undef HAVE_TCP //websockets are not true tcp
|
||||
#undef HAVE_PACKET //no udp support.
|
||||
|
||||
#undef SUPPORT_ICE
|
||||
#undef CL_MASTER //no sockets support
|
||||
#undef SV_MASTER //noone uses this anyway
|
||||
#undef WEBSERVER //http server
|
||||
#undef FTPSERVER //ftp server
|
||||
#undef FTPCLIENT //ftp client.
|
||||
#undef TCPCONNECT
|
||||
#undef IRCCONNECT
|
||||
#define GLSLONLY //pointless having the junk
|
||||
#define GLESONLY //should reduce the conditions a little
|
||||
#undef HEADLESSQUAKE
|
||||
#define NO_FREETYPE
|
||||
#endif
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1500)) || defined(FTE_SDL)
|
||||
#undef AVAIL_WASAPI //wasapi is available in the vista sdk, while that's compatible with earlier versions, its not really expected until 2008
|
||||
#endif
|
||||
|
@ -505,7 +480,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#undef WEBSERVER //http server
|
||||
#undef FTPSERVER //ftp server
|
||||
#undef FTPCLIENT //ftp client.
|
||||
#if !defined(FTE_TARGET_WEB) && !defined(NACL)
|
||||
#if !defined(FTE_TARGET_WEB)
|
||||
#undef WEBCLIENT
|
||||
#endif
|
||||
#endif
|
||||
|
@ -612,8 +587,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PLATFORM "Web"
|
||||
#define ARCH_CPU_POSTFIX "web"
|
||||
#define ARCH_DL_POSTFIX ".wasm"
|
||||
#elif defined(NACL)
|
||||
#define PLATFORM "Nacl"
|
||||
#elif defined(_WIN32_WCE)
|
||||
#define PLATFORM "WinCE"
|
||||
#define ARCH_DL_POSTFIX ".dll"
|
||||
|
|
|
@ -5422,7 +5422,7 @@ void COM_InitArgv (int argc, const char **argv) //not allowed to tprint
|
|||
qboolean safe;
|
||||
int i;
|
||||
|
||||
#if !defined(NACL) && !defined(FTE_TARGET_WEB)
|
||||
#if !defined(FTE_TARGET_WEB)
|
||||
FILE *f;
|
||||
|
||||
if (argv && argv[0])
|
||||
|
|
|
@ -529,7 +529,7 @@ extern char com_homepath[MAX_OSPATH];
|
|||
|
||||
//qofs_Make is used to 'construct' a variable of qofs_t type. this is so the code can merge two 32bit ints on old systems and use a long long type internally without generating warnings about bit shifts when qofs_t is only 32bit instead.
|
||||
//#if defined(__amd64__) || defined(_AMD64_) || __WORDSIZE == 64
|
||||
#if !defined(FTE_TARGET_WEB) && !defined(NACL)
|
||||
#if !defined(FTE_TARGET_WEB)
|
||||
#if !defined(_MSC_VER) || _MSC_VER > 1200
|
||||
#define FS_64BIT
|
||||
#endif
|
||||
|
|
|
@ -6303,7 +6303,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
|
|||
confpath[i] = NULL;
|
||||
}
|
||||
|
||||
#if defined(NACL) || defined(FTE_TARGET_WEB) || defined(ANDROID) || defined(WINRT)
|
||||
#if defined(FTE_TARGET_WEB) || defined(ANDROID) || defined(WINRT)
|
||||
//these targets are considered to be sandboxed already, and have their own app-based base directory which they will always use.
|
||||
Q_strncpyz (newbasedir, host_parms.basedir, sizeof(newbasedir));
|
||||
fixedbasedir = true;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if !defined(NACL) && !defined(FTE_TARGET_WEB) && (!defined(_WIN32) || defined(FTE_SDL))
|
||||
#if !defined(FTE_TARGET_WEB) && (!defined(_WIN32) || defined(FTE_SDL))
|
||||
|
||||
#ifdef WEBSVONLY
|
||||
#define Z_Free free
|
||||
|
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define PORT_ANY -1
|
||||
|
||||
#if defined(NACL) || defined(FTE_TARGET_WEB)
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
#define HAVE_WEBSOCKCL
|
||||
#endif
|
||||
|
||||
|
|
|
@ -278,8 +278,6 @@ void Netchan_Init (void)
|
|||
// pick a port value that should be nice and random
|
||||
#ifdef _WIN32
|
||||
port = (time(NULL)) & 0xffff;
|
||||
#elif defined(NACL)
|
||||
port = ((int)(getpid()) * time(NULL)) & 0xffff;
|
||||
#else
|
||||
port = ((int)(getpid()+getuid()*1000) * time(NULL)) & 0xffff;
|
||||
#endif
|
||||
|
|
|
@ -4319,7 +4319,7 @@ typedef struct ftenet_tcp_stream_s {
|
|||
//TCPC_QTV, //included for completeness. qtv handles the sockets itself, we just parse initial handshake and then pass it over (as either a tcp or tls vfsfile_t)
|
||||
TCPC_QIZMO, //'qizmo\n' handshake, followed by packets prefixed with a 16bit packet length.
|
||||
#ifdef HAVE_HTTPSV
|
||||
TCPC_WEBSOCKETU, //utf-8 encoded data.
|
||||
TCPC_WEBSOCKETU, //utf-8 encoded data. //TODO(fhomolka): Check if any targets use this, remove if not
|
||||
TCPC_WEBSOCKETB, //binary encoded data (subprotocol = 'binary')
|
||||
TCPC_WEBSOCKETNQ, //raw nq msg buffers with no encapsulation or handshake
|
||||
TCPC_HTTPCLIENT, //we're sending a file to this victim.
|
||||
|
@ -8062,300 +8062,6 @@ static ftenet_generic_connection_t *FTENET_WebRTC_EstablishConnection(ftenet_con
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NACL
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/pp_resource.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/ppb_websocket.h>
|
||||
#include <ppapi/c/ppb_var.h>
|
||||
#include <ppapi/c/ppb_var_array_buffer.h>
|
||||
#include <ppapi/c/ppb_instance.h>
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PPB_WebSocket *ppb_websocket_interface;
|
||||
extern PPB_Var *ppb_var_interface;
|
||||
extern PPB_VarArrayBuffer *ppb_vararraybuffer_interface;
|
||||
extern PP_Instance pp_instance;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ftenet_generic_connection_t generic;
|
||||
|
||||
PP_Resource sock;
|
||||
netadr_t remoteadr;
|
||||
|
||||
struct PP_Var incomingpacket;
|
||||
qboolean havepacket;
|
||||
|
||||
qboolean failed;
|
||||
int showerror;
|
||||
} ftenet_websocket_connection_t;
|
||||
|
||||
static void websocketgot(void *user_data, int32_t result)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = user_data;
|
||||
if (result == PP_OK)
|
||||
{
|
||||
wsc->havepacket = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Printf("%s: %i\n", __func__, result);
|
||||
wsc->failed = true;
|
||||
wsc->showerror = result;
|
||||
}
|
||||
}
|
||||
static void websocketconnected(void *user_data, int32_t result)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = user_data;
|
||||
if (result == PP_OK)
|
||||
{
|
||||
int res;
|
||||
//we got a successful connection, enable reception.
|
||||
struct PP_CompletionCallback ccb = {websocketgot, wsc, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
|
||||
res = ppb_websocket_interface->ReceiveMessage(wsc->sock, &wsc->incomingpacket, ccb);
|
||||
if (res != PP_OK_COMPLETIONPENDING)
|
||||
websocketgot(wsc, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Printf("%s: %i\n", __func__, result);
|
||||
//some sort of error connecting, make it timeout now
|
||||
wsc->failed = true;
|
||||
wsc->showerror = result;
|
||||
}
|
||||
}
|
||||
static void websocketclosed(void *user_data, int32_t result)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = user_data;
|
||||
if (wsc->havepacket)
|
||||
{
|
||||
wsc->havepacket = false;
|
||||
ppb_var_interface->Release(wsc->incomingpacket);
|
||||
}
|
||||
ppb_core->ReleaseResource(wsc->sock);
|
||||
// Z_Free(wsc);
|
||||
}
|
||||
|
||||
static void FTENET_NaClWebSocket_Close(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
int res;
|
||||
/*meant to free the memory too, in this case we get the callback to do it*/
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
|
||||
struct PP_CompletionCallback ccb = {websocketclosed, wsc, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
ppb_websocket_interface->Close(wsc->sock, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), ccb);
|
||||
}
|
||||
|
||||
static qboolean FTENET_NaClWebSocket_GetPacket(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
int res;
|
||||
int len = 0;
|
||||
if (wsc->havepacket)
|
||||
{
|
||||
if (wsc->incomingpacket.type == PP_VARTYPE_ARRAY_BUFFER)
|
||||
{
|
||||
uint32_t length;
|
||||
void *buf = ppb_vararraybuffer_interface->Map(wsc->incomingpacket);
|
||||
if (buf && ppb_vararraybuffer_interface->ByteLength(wsc->incomingpacket, &length))
|
||||
{
|
||||
net_message.cursize = length;
|
||||
memcpy(net_message_buffer, buf, length);
|
||||
ppb_vararraybuffer_interface->Unmap(wsc->incomingpacket);
|
||||
}
|
||||
else
|
||||
net_message.cursize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *utf8 = (unsigned char *)ppb_var_interface->VarToUtf8(wsc->incomingpacket, &len);
|
||||
unsigned char *out = (unsigned char *)net_message_buffer;
|
||||
|
||||
while(len && out < net_message_buffer + sizeof(net_message_buffer))
|
||||
{
|
||||
if ((*utf8 & 0xe0)==0xc0 && len > 1)
|
||||
{
|
||||
*out = ((utf8[0] & 0x1f)<<6) | ((utf8[1] & 0x3f)<<0);
|
||||
utf8+=2;
|
||||
len -= 2;
|
||||
}
|
||||
else if (*utf8 & 0x80)
|
||||
{
|
||||
*out = '?';
|
||||
utf8++;
|
||||
len -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = utf8[0];
|
||||
utf8++;
|
||||
len -= 1;
|
||||
}
|
||||
out++;
|
||||
}
|
||||
net_message.cursize = out - net_message_buffer;
|
||||
}
|
||||
memcpy(&net_from, &wsc->remoteadr, sizeof(net_from));
|
||||
wsc->havepacket = false;
|
||||
ppb_var_interface->Release(wsc->incomingpacket);
|
||||
|
||||
if (!wsc->failed)
|
||||
{
|
||||
//get the next one
|
||||
struct PP_CompletionCallback ccb = {websocketgot, wsc, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
|
||||
res = ppb_websocket_interface->ReceiveMessage(wsc->sock, &wsc->incomingpacket, ccb);
|
||||
if (res != PP_OK_COMPLETIONPENDING)
|
||||
websocketgot(wsc, res);
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
char adr[64];
|
||||
Con_TPrintf ("Warning: Oversize packet from %s\n", NET_AdrToString (adr, sizeof(adr), &net_from));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (wsc->showerror != PP_OK)
|
||||
{
|
||||
switch(wsc->showerror)
|
||||
{
|
||||
case PP_ERROR_FAILED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_FAILED\n");
|
||||
break;
|
||||
case PP_ERROR_ABORTED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ABORTED\n");
|
||||
break;
|
||||
case PP_ERROR_NOTSUPPORTED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_NOTSUPPORTED\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_CLOSED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_CLOSED\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_RESET:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_RESET\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_REFUSED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_REFUSED\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_ABORTED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_ABORTED\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_FAILED:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_FAILED\n");
|
||||
break;
|
||||
case PP_ERROR_CONNECTION_TIMEDOUT:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_TIMEDOUT\n");
|
||||
break;
|
||||
case PP_ERROR_ADDRESS_INVALID:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_INVALID\n");
|
||||
break;
|
||||
case PP_ERROR_ADDRESS_UNREACHABLE:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_UNREACHABLE\n");
|
||||
break;
|
||||
case PP_ERROR_ADDRESS_IN_USE:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_IN_USE\n");
|
||||
break;
|
||||
default:
|
||||
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: error %i\n", wsc->showerror);
|
||||
break;
|
||||
}
|
||||
wsc->showerror = PP_OK;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static neterr_t FTENET_NaClWebSocket_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
|
||||
{
|
||||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
int res;
|
||||
if (wsc->failed)
|
||||
return NETERR_DISCONNECTED;
|
||||
|
||||
#if 1
|
||||
struct PP_Var str = ppb_vararraybuffer_interface->Create(length);
|
||||
void *out = ppb_vararraybuffer_interface->Map(str);
|
||||
if (!out)
|
||||
return NETERR_MTU;
|
||||
memcpy(out, data, length);
|
||||
ppb_vararraybuffer_interface->Unmap(str);
|
||||
#else
|
||||
int outchars = 0;
|
||||
unsigned char outdata[length*2+1];
|
||||
unsigned char *out=outdata, *in=data;
|
||||
while(length-->0)
|
||||
{
|
||||
if (!*in)
|
||||
{
|
||||
//sends 256 instead of 0
|
||||
*out++ = 0xc0 | (0x100 >> 6);
|
||||
*out++ = 0x80 | (0x100 & 0x3f);
|
||||
}
|
||||
else if (*in >= 0x80)
|
||||
{
|
||||
*out++ = 0xc0 | (*in >> 6);
|
||||
*out++ = 0x80 | (*in & 0x3f);
|
||||
}
|
||||
else
|
||||
*out++ = *in;
|
||||
in++;
|
||||
outchars++;
|
||||
}
|
||||
*out = 0;
|
||||
struct PP_Var str = ppb_var_interface->VarFromUtf8(outdata, out - outdata);
|
||||
#endif
|
||||
res = ppb_websocket_interface->SendMessage(wsc->sock, str);
|
||||
// Sys_Printf("FTENET_WebSocket_SendPacket: result %i\n", res);
|
||||
ppb_var_interface->Release(str);
|
||||
return NETERR_SENT;
|
||||
}
|
||||
|
||||
/*nacl websockets implementation...*/
|
||||
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(ftenet_connections_t *col, const char *address, netadr_t adr)
|
||||
{
|
||||
qboolean isserver = col->islisten;
|
||||
ftenet_websocket_connection_t *newcon;
|
||||
|
||||
PP_Resource newsocket;
|
||||
|
||||
if (isserver || !ppb_websocket_interface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newcon = Z_Malloc(sizeof(*newcon));
|
||||
if (newcon)
|
||||
{
|
||||
#define WEBSOCKETPROTOCOL "fteqw"
|
||||
struct PP_CompletionCallback ccb = {websocketconnected, newcon, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
newsocket = ppb_websocket_interface->Create(pp_instance);
|
||||
struct PP_Var str = ppb_var_interface->VarFromUtf8(adr.address.websocketurl, strlen(adr.address.websocketurl));
|
||||
struct PP_Var protocols[1] = {ppb_var_interface->VarFromUtf8(WEBSOCKETPROTOCOL, strlen(WEBSOCKETPROTOCOL))};
|
||||
ppb_websocket_interface->Connect(newsocket, str, protocols, countof(protocols), ccb);
|
||||
ppb_var_interface->Release(str);
|
||||
ppb_var_interface->Release(protocols[0]);
|
||||
Q_strncpyz(newcon->generic.name, "WebSocket", sizeof(newcon->generic.name));
|
||||
newcon->generic.GetPacket = FTENET_NaClWebSocket_GetPacket;
|
||||
newcon->generic.SendPacket = FTENET_NaClWebSocket_SendPacket;
|
||||
newcon->generic.Close = FTENET_NaClWebSocket_Close;
|
||||
|
||||
newcon->generic.islisten = isserver;
|
||||
newcon->generic.addrtype[0] = NA_WEBSOCKET;
|
||||
newcon->generic.addrtype[1] = NA_INVALID;
|
||||
|
||||
newcon->generic.thesocket = INVALID_SOCKET;
|
||||
newcon->sock = newsocket;
|
||||
|
||||
newcon->remoteadr = adr;
|
||||
|
||||
return &newcon->generic;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
qboolean NET_GetRates(ftenet_connections_t *collection, float *pi, float *po, float *bi, float *bo)
|
||||
{
|
||||
int ctime;
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#define AF_UNSPEC 0
|
||||
// #define AF_INET 1
|
||||
|
||||
/*NaCl engines cannot host servers. Regular FTE servers can use the same listening tcpconnect socket to host a websocket connection*/
|
||||
|
||||
#define AF_WEBSOCK 342
|
||||
|
||||
struct sockaddr_websocket
|
||||
|
|
|
@ -6,8 +6,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fteqcc", "..\qclib\dotnet20
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\dotnet2005\qtvprox.vcproj", "{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj", "{4735677B-6D5A-4BE6-A945-CB32A7282F56}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "berkplug", "..\..\plugins\berkelium\berkelium.vcproj", "{4877586B-E85B-4DF8-BCCE-59D31514D240}"
|
||||
|
|
|
@ -1588,7 +1588,7 @@ void GLR_SetupFog (void)
|
|||
|
||||
static void R_RenderMotionBlur(void)
|
||||
{
|
||||
#if !defined(ANDROID) && !defined(NACL)
|
||||
#if !defined(ANDROID)
|
||||
int vwidth = 1, vheight = 1;
|
||||
float vs, vt, cs, ct;
|
||||
shader_t *shader;
|
||||
|
|
|
@ -282,9 +282,7 @@ FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
|||
|
||||
|
||||
#define GLchar char
|
||||
#ifdef NACL
|
||||
#undef DEBUG
|
||||
#elif defined(_DEBUG) && !defined(DEBUG)
|
||||
#if defined(_DEBUG) && !defined(DEBUG)
|
||||
#define DEBUG
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
|
@ -1191,7 +1189,6 @@ static qboolean GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
{ //gles has different TexImage2D arguments for specifying quality.
|
||||
gl_config.arb_depth_texture = gl_config.glversion >= 3.0
|
||||
|| GL_CheckExtension("GL_OES_depth_texture") //gles2
|
||||
|| GL_CheckExtension("GL_CHROMIUM_depth_texture") //nacl
|
||||
|| GL_CheckExtension("GL_WEBGL_depth_texture") //webgl. duh.
|
||||
|| GL_CheckExtension("GL_ANGLE_depth_texture"); //gah. should just use wildcards huh (no uploads)
|
||||
gl_config.arb_shadow = gl_config.glversion>=3.0;//||GL_CheckExtension("GL_EXT_shadow_samplers");
|
||||
|
|
|
@ -56,7 +56,7 @@ void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b); //data ===
|
|||
#endif
|
||||
#include <OpenGL/gl.h> //tuna says use this.
|
||||
//apple really do suck.
|
||||
#elif defined(NACL) || defined(FTE_TARGET_WEB)
|
||||
#elif defined(FTE_TARGET_WEB)
|
||||
#include <GLES2/gl2.h>
|
||||
#define GLclampd GLclampf
|
||||
#define GLdouble GLfloat
|
||||
|
@ -1079,7 +1079,7 @@ void GL_SelectProgram(int program);
|
|||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#if defined(__GNUC__) && !defined(NACL)
|
||||
#if defined(__GNUC__)
|
||||
#define checkglerror() do {int i=qglGetError(); if (i) Sys_Printf("GL Error %i detected at line %s:%i (caller %p)\n", i, __FILE__, __LINE__, __builtin_return_address(0));}while(0)
|
||||
#else
|
||||
#define checkglerror() do {int i=qglGetError(); if (i) Con_Printf("GL Error %i detected at line %s:%i\n", i, __FILE__, __LINE__);}while(0)
|
||||
|
|
|
@ -127,154 +127,6 @@ qboolean DL_Decide(struct dl_download *dl)
|
|||
|
||||
return true;
|
||||
}
|
||||
#elif defined(NACL)
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/pp_file_info.h>
|
||||
#include <ppapi/c/ppb_file_system.h>
|
||||
#include <ppapi/c/ppb_file_ref.h>
|
||||
#include <ppapi/c/ppb_url_request_info.h>
|
||||
#include <ppapi/c/ppb_url_response_info.h>
|
||||
#include <ppapi/c/pp_var.h>
|
||||
#include <ppapi/c/ppb_var.h>
|
||||
#include <ppapi/c/ppb_file_io.h>
|
||||
#include <ppapi/c/ppb_url_loader.h>
|
||||
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PPB_URLRequestInfo *urlrequestinfo;
|
||||
extern PPB_URLLoader *urlloader;
|
||||
extern PP_Instance pp_instance;
|
||||
extern PPB_Var *ppb_var_interface;
|
||||
|
||||
struct nacl_dl {
|
||||
char buffer[65536];
|
||||
PP_Resource req;
|
||||
};
|
||||
|
||||
static void readfinished(void* user_data, int32_t result)
|
||||
{
|
||||
struct dl_download *f = user_data;
|
||||
struct nacl_dl *ctx = f->ctx;
|
||||
struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
|
||||
//trying to clean up
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
// Sys_Printf("lastresult: %i\n", result);
|
||||
|
||||
if (result == PP_OK)
|
||||
{
|
||||
// Sys_Printf("%s completed\n", f->url);
|
||||
ppb_core->ReleaseResource(ctx->req);
|
||||
ctx->req = 0;
|
||||
|
||||
f->status = DL_FINISHED;
|
||||
return;
|
||||
}
|
||||
|
||||
for (; result > 0; result = urlloader->ReadResponseBody(ctx->req, ctx->buffer, sizeof(ctx->buffer), ccb))
|
||||
{
|
||||
//make sure the file is 'open'.
|
||||
if (!f->file)
|
||||
{
|
||||
if (*f->localname)
|
||||
{
|
||||
FS_CreatePath(f->localname, dl->fsroot);
|
||||
f->file = FS_OpenVFS(f->localname, "w+b", dl->fsroot);
|
||||
}
|
||||
else
|
||||
f->file = FS_OpenTemp();
|
||||
}
|
||||
|
||||
// Sys_Printf("write: %i\n", result);
|
||||
VFS_WRITE(f->file, ctx->buffer, result);
|
||||
|
||||
f->completed += result;
|
||||
}
|
||||
|
||||
// Sys_Printf("result: %i\n", result);
|
||||
if (result != PP_OK_COMPLETIONPENDING)
|
||||
{
|
||||
Sys_Printf("file %s failed or something\n", f->url);
|
||||
ppb_core->ReleaseResource(ctx->req);
|
||||
ctx->req = 0;
|
||||
f->status = DL_FAILED;
|
||||
}
|
||||
}
|
||||
//urloader->open completed
|
||||
static void dlstarted(void* user_data, int32_t result)
|
||||
{
|
||||
struct dl_download *f = user_data;
|
||||
struct nacl_dl *ctx = f->ctx;
|
||||
|
||||
struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
readfinished(user_data, urlloader->ReadResponseBody(ctx->req, ctx->buffer, sizeof(ctx->buffer), ccb));
|
||||
}
|
||||
|
||||
static void nadl_cleanup_cb(void* user_data, int32_t result)
|
||||
{
|
||||
struct nacl_dl *ctx = user_data;
|
||||
|
||||
if (ctx->req)
|
||||
ppb_core->ReleaseResource(ctx->req);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void NADL_Cleanup(struct dl_download *dl)
|
||||
{
|
||||
struct nacl_dl *ctx = dl->ctx;
|
||||
|
||||
//we can't free the ctx memory etc, in case the browser still has requests pending on it before it handles our close.
|
||||
//so set up a callback to do it later
|
||||
|
||||
dl->ctx = NULL; //orphan
|
||||
struct PP_CompletionCallback ccb = {nadl_cleanup_cb, ctx, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
ppb_core->CallOnMainThread(1000, ccb, 0);
|
||||
}
|
||||
|
||||
qboolean DL_Decide(struct dl_download *dl)
|
||||
{
|
||||
const char *url = dl->redir;
|
||||
struct nacl_dl *ctx;
|
||||
if (!*url)
|
||||
url = dl->url;
|
||||
|
||||
if (dl->postdata)
|
||||
{
|
||||
NADL_Cleanup(dl);
|
||||
return false; //safe to destroy it now
|
||||
}
|
||||
|
||||
if (dl->ctx)
|
||||
{
|
||||
if (dl->status == DL_FAILED || dl->status == DL_FINISHED)
|
||||
{
|
||||
NADL_Cleanup(dl);
|
||||
return false; //safe to destroy it now
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PP_Resource dlri;
|
||||
|
||||
dl->status = DL_ACTIVE;
|
||||
dl->abort = NADL_Cleanup;
|
||||
dl->ctx = ctx = Z_Malloc(sizeof(*ctx));
|
||||
|
||||
/*everything goes via nacl, so we might as well just init that here*/
|
||||
ctx->req = urlloader->Create(pp_instance);
|
||||
dlri = urlrequestinfo->Create(pp_instance);
|
||||
urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, ppb_var_interface->VarFromUtf8(url, strlen(url)));
|
||||
urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_URL, ppb_var_interface->VarFromUtf8(url, strlen(url)));
|
||||
|
||||
struct PP_CompletionCallback ccb = {dlstarted, dl, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
urlloader->Open(ctx->req, dlri, ccb);
|
||||
ppb_core->ReleaseResource(dlri);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
qboolean DL_Decide(struct dl_download *dl);
|
||||
|
||||
|
@ -1433,7 +1285,7 @@ qboolean DL_Decide(struct dl_download *dl)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif /*!defined(NACL)*/
|
||||
#endif /*!defined(FTE_TARGET_WEB)*/
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
static unsigned int dlthreads = 0;
|
||||
|
|
|
@ -1,834 +0,0 @@
|
|||
#include "quakedef.h"
|
||||
#include "fs.h"
|
||||
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/pp_file_info.h>
|
||||
#include <ppapi/c/ppb_file_system.h>
|
||||
#include <ppapi/c/ppb_file_ref.h>
|
||||
#include <ppapi/c/ppb_url_request_info.h>
|
||||
#include <ppapi/c/ppb_url_response_info.h>
|
||||
#include <ppapi/c/pp_var.h>
|
||||
#include <ppapi/c/ppb_var.h>
|
||||
#include <ppapi/c/ppb_file_io.h>
|
||||
#include <ppapi/c/ppb_url_loader.h>
|
||||
|
||||
extern PPB_FileIO *ppb_fileio;
|
||||
extern PPB_FileRef *ppb_fileref;
|
||||
extern PPB_FileSystem *ppb_filesystem;
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PPB_URLLoader *urlloader;
|
||||
extern PPB_URLRequestInfo *urlrequestinfo;
|
||||
extern PPB_URLResponseInfo *urlresponseinfo;
|
||||
extern PPB_Var *ppb_var_interface;
|
||||
extern PP_Instance pp_instance;
|
||||
|
||||
#define GOOGLE_DONT_KNOW_HOW_TO_CREATE_USABLE_APIS
|
||||
#ifdef GOOGLE_DONT_KNOW_HOW_TO_CREATE_USABLE_APIS
|
||||
//the pepper api is flawed. deeply flawed.
|
||||
//1: api calls (including various gl calls) may only be made on the main thread).
|
||||
//2: the main thread may not use non-asyncronous calls.
|
||||
//the recommendation to get around this is to run everything on a worker thread, but to make calls to the main thread to do the actual call, then signal the worker thread to wake up again in the main thread's callback.
|
||||
//which is impractical when you have 80+ different sorts of performance-dependant gl calls.
|
||||
//I can't easily put things requiring file access on another thread, if only because it would make alias/exec console commands non-synchronous
|
||||
//to get around this, I instead make my own memory-only 'filesystem', populating it at startup with downloads. I *really* hope your browser/server are set to enable file caching.
|
||||
//at some point I'll periodically write the data back to a persistant store/reload it at startup so saved games/configs can work
|
||||
|
||||
#define FSPPAPI_OpenTemp FS_OpenTemp
|
||||
#define VFSPPAPI_Open VFSOS_Open
|
||||
#define FSPPAPI_OpenPath VFSOS_OpenPath
|
||||
|
||||
typedef struct mfchunk_s
|
||||
{
|
||||
struct mfchunk_s *prev;
|
||||
struct mfchunk_s *next;
|
||||
unsigned long startpos;
|
||||
unsigned int len;
|
||||
char data[64];
|
||||
} mfchunk_t;
|
||||
typedef struct mfile_s
|
||||
{
|
||||
/*chunks can be trimmed only when there's no refs*/
|
||||
char name[MAX_QPATH];
|
||||
int refs;
|
||||
int unlinked:1;
|
||||
unsigned long length;
|
||||
|
||||
mfchunk_t *chunkhead;
|
||||
mfchunk_t *chunktail;
|
||||
|
||||
struct mfile_s *prev;
|
||||
struct mfile_s *next;
|
||||
} mfile_t;
|
||||
mfile_t *mfiles;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vfsfile_t funcs;
|
||||
|
||||
mfile_t *file;
|
||||
unsigned long offset;
|
||||
mfchunk_t *cchunk;
|
||||
} vfsmfile_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
searchpathfuncs_t pub;
|
||||
int depth;
|
||||
char rootpath[1];
|
||||
} pppath_t;
|
||||
|
||||
qboolean FSPPAPI_Init(int *fileid)
|
||||
{
|
||||
return true; /*engine has all the content it needs*/
|
||||
}
|
||||
|
||||
static int preparechunk(vfsmfile_t *f, int bytes, void **data)
|
||||
{
|
||||
int sz;
|
||||
mfchunk_t *cnk;
|
||||
if (!bytes)
|
||||
{
|
||||
*data = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!f->cchunk)
|
||||
cnk = f->file->chunkhead;
|
||||
else
|
||||
{
|
||||
cnk = f->cchunk;
|
||||
//rewind through the chunks
|
||||
while (cnk->startpos > f->offset)
|
||||
cnk = cnk->prev;
|
||||
}
|
||||
//find the chunk that contains our start offset
|
||||
while (!cnk || cnk->startpos+cnk->len <= f->offset)
|
||||
{
|
||||
if (!cnk)
|
||||
{
|
||||
sz = (bytes + sizeof(*cnk) - sizeof(cnk->data) + 4095) & ~4095;
|
||||
if (sz < 65536)
|
||||
sz = 65536;
|
||||
cnk = malloc(sz);
|
||||
memset(cnk, 0xcc, sz);
|
||||
if (!cnk)
|
||||
{
|
||||
*data = 0;
|
||||
return 0;
|
||||
}
|
||||
cnk->len = (sz + sizeof(cnk->data) - sizeof(*cnk));
|
||||
cnk->next = NULL;
|
||||
if (f->file->chunktail)
|
||||
{
|
||||
cnk->prev = f->file->chunktail;
|
||||
cnk->prev->next = cnk;
|
||||
cnk->startpos = cnk->prev->startpos + cnk->prev->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->file->chunkhead = cnk;
|
||||
cnk->prev = NULL;
|
||||
cnk->startpos = 0;
|
||||
}
|
||||
// Sys_Printf("Allocated chunk %p: %u-%u\n", cnk, cnk->startpos, cnk->startpos + cnk->len);
|
||||
f->file->chunktail = cnk;
|
||||
}
|
||||
else
|
||||
cnk = cnk->next;
|
||||
}
|
||||
|
||||
// Sys_Printf("Returning offset %p, %i\n", cnk, (f->offset - cnk->startpos));
|
||||
// Sys_Printf("%u %u\n", f->offset, cnk->startpos);
|
||||
|
||||
*data = cnk->data + (f->offset - cnk->startpos);
|
||||
f->cchunk = cnk;
|
||||
|
||||
sz = cnk->startpos + cnk->len - f->offset;
|
||||
if (sz > bytes)
|
||||
{
|
||||
// Sys_Printf("Returning len %u\n", bytes);
|
||||
return bytes;
|
||||
}
|
||||
// Sys_Printf("Returning len %u\n", sz);
|
||||
return sz;
|
||||
|
||||
}
|
||||
|
||||
static int VFSMEM_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
|
||||
{
|
||||
int total = 0;
|
||||
int chunklen;
|
||||
void *chunkdat;
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
|
||||
if (bytestoread > f->file->length - f->offset)
|
||||
bytestoread = f->file->length - f->offset;
|
||||
|
||||
while ((chunklen = preparechunk(f, bytestoread, &chunkdat)) > 0)
|
||||
{
|
||||
// Sys_Printf("Read %i at %u\n", chunklen, f->offset);
|
||||
memcpy(buffer, chunkdat, chunklen);
|
||||
buffer = (char*)buffer + chunklen;
|
||||
bytestoread -= chunklen;
|
||||
total += chunklen;
|
||||
f->offset += chunklen;
|
||||
}
|
||||
|
||||
// Sys_Printf("%s", (char*)buffer-total);
|
||||
return total;
|
||||
}
|
||||
static int VFSMEM_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
|
||||
{
|
||||
int total = 0;
|
||||
int chunklen;
|
||||
void *chunkdat;
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
|
||||
while ((chunklen = preparechunk(f, bytestoread, &chunkdat)) > 0)
|
||||
{
|
||||
// Sys_Printf("Write %i at %u\n", chunklen, f->offset);
|
||||
memcpy(chunkdat, buffer, chunklen);
|
||||
buffer = (char*)buffer + chunklen;
|
||||
bytestoread -= chunklen;
|
||||
total += chunklen;
|
||||
f->offset += chunklen;
|
||||
}
|
||||
|
||||
if (f->file->length < f->offset)
|
||||
f->file->length = f->offset;
|
||||
|
||||
// Sys_Printf("written: %i, file is now at %i\n", total, f->offset);
|
||||
return total;
|
||||
}
|
||||
static qboolean VFSMEM_Seek (struct vfsfile_s *file, qofs_t pos)
|
||||
{
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
f->offset = pos;
|
||||
return true;
|
||||
}
|
||||
static qofs_t VFSMEM_Tell (struct vfsfile_s *file)
|
||||
{
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
return f->offset;
|
||||
}
|
||||
static qofs_t VFSMEM_GetSize (struct vfsfile_s *file)
|
||||
{
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
return f->file->length;
|
||||
}
|
||||
static void FSPPAPI_DoUnlink(mfile_t *file)
|
||||
{
|
||||
mfchunk_t *cnk;
|
||||
//must have no lingering references.
|
||||
|
||||
//free any file chunks.
|
||||
while (file->chunkhead)
|
||||
{
|
||||
cnk = file->chunkhead->next;
|
||||
free(file->chunkhead);
|
||||
file->chunkhead = cnk;
|
||||
}
|
||||
//unlink the file so nothing else is harmed
|
||||
if (file->prev)
|
||||
file->prev->next = file->next;
|
||||
else if (file == mfiles)
|
||||
mfiles = file->next;
|
||||
if (file->next)
|
||||
file->next->prev = file->prev;
|
||||
//and finally free the last bit of memory.
|
||||
free(file);
|
||||
}
|
||||
static qboolean VFSMEM_Close(vfsfile_t *file)
|
||||
{
|
||||
vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
f->file->refs -= 1;
|
||||
if (!f->file->refs)
|
||||
if (f->file->unlinked)
|
||||
FSPPAPI_DoUnlink(f->file);
|
||||
free(f);
|
||||
return true;
|
||||
}
|
||||
static void VFSMEM_Flush(struct vfsfile_s *file)
|
||||
{
|
||||
// vfsmfile_t *f = (vfsmfile_t*)file;
|
||||
}
|
||||
|
||||
|
||||
vfsfile_t *FSPPAPI_OpenTemp(void)
|
||||
{
|
||||
/*create a file which is already unlinked*/
|
||||
mfile_t *f;
|
||||
vfsmfile_t *r;
|
||||
f = malloc(sizeof(*f));
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
strcpy(f->name, "some temp file");
|
||||
f->refs = 0;
|
||||
f->unlinked = true;
|
||||
f->length = 0;
|
||||
f->next = NULL;
|
||||
f->prev = NULL;
|
||||
f->chunkhead = NULL;
|
||||
f->chunktail = NULL;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
if (!r)
|
||||
return NULL;
|
||||
r->file = f;
|
||||
r->offset = 0;
|
||||
r->cchunk = NULL;
|
||||
f->refs++;
|
||||
|
||||
r->funcs.ReadBytes = VFSMEM_ReadBytes;
|
||||
r->funcs.WriteBytes = VFSMEM_WriteBytes;
|
||||
r->funcs.Seek = VFSMEM_Seek;
|
||||
r->funcs.Tell = VFSMEM_Tell;
|
||||
r->funcs.GetLen = VFSMEM_GetSize;
|
||||
r->funcs.Close = VFSMEM_Close;
|
||||
r->funcs.Flush = VFSMEM_Flush;
|
||||
|
||||
return &r->funcs;
|
||||
}
|
||||
|
||||
qboolean Sys_remove (const char *path)
|
||||
{
|
||||
mfile_t *f;
|
||||
for (f = mfiles; f; f = f->next)
|
||||
{
|
||||
if (!strcmp(f->name, path))
|
||||
{
|
||||
if (!f->refs)
|
||||
FSPPAPI_DoUnlink(f);
|
||||
else
|
||||
f->unlinked = true; //can't delete it yet, but we can orphan it so we can kill it later.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
qboolean Sys_Rename (const char *oldfname, const char *newfname)
|
||||
{
|
||||
mfile_t *f;
|
||||
for (f = mfiles; f; f = f->next)
|
||||
{
|
||||
if (!strcmp(f->name, oldfname))
|
||||
{
|
||||
Q_strncpyz(f->name, newfname, sizeof(f->name));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//no concept of directories.
|
||||
void Sys_mkdir (const char *path)
|
||||
{
|
||||
}
|
||||
qboolean Sys_rmdir (const char *path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vfsfile_t *VFSPPAPI_Open(const char *osname, const char *mode)
|
||||
{
|
||||
mfile_t *f;
|
||||
vfsmfile_t *r;
|
||||
|
||||
if (strlen(osname) >= sizeof(f->name)) //yay strcpy!
|
||||
return NULL;
|
||||
|
||||
for (f = mfiles; f; f = f->next)
|
||||
{
|
||||
if (!strcmp(f->name, osname))
|
||||
break;
|
||||
}
|
||||
if (!f && (*mode == 'w' || *mode == 'a'))
|
||||
{
|
||||
f = malloc(sizeof(*f));
|
||||
if (f)
|
||||
{
|
||||
strcpy(f->name, osname);
|
||||
f->refs = 0;
|
||||
f->unlinked = false;
|
||||
f->length = 0;
|
||||
f->next = mfiles;
|
||||
f->prev = NULL;
|
||||
if (mfiles)
|
||||
mfiles->prev = f;
|
||||
mfiles = f;
|
||||
f->chunkhead = NULL;
|
||||
f->chunktail = NULL;
|
||||
}
|
||||
}
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
if (!r)
|
||||
return NULL;
|
||||
r->file = f;
|
||||
r->offset = 0;
|
||||
r->cchunk = NULL;
|
||||
f->refs++;
|
||||
|
||||
r->funcs.ReadBytes = VFSMEM_ReadBytes;
|
||||
r->funcs.WriteBytes = VFSMEM_WriteBytes;
|
||||
r->funcs.Seek = VFSMEM_Seek;
|
||||
r->funcs.Tell = VFSMEM_Tell;
|
||||
r->funcs.GetLen = VFSMEM_GetSize;
|
||||
r->funcs.Close = VFSMEM_Close;
|
||||
r->funcs.Flush = VFSMEM_Flush;
|
||||
|
||||
return &r->funcs;
|
||||
}
|
||||
|
||||
static vfsfile_t *FSPPAPI_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode)
|
||||
{
|
||||
pppath_t *sp = (void*)handle;
|
||||
char diskname[MAX_OSPATH];
|
||||
|
||||
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
|
||||
|
||||
snprintf(diskname, sizeof(diskname), "%s/%s", sp->rootpath, loc->rawname);
|
||||
|
||||
return VFSPPAPI_Open(diskname, mode);
|
||||
}
|
||||
|
||||
static void FSPPAPI_ClosePath(searchpathfuncs_t *handle)
|
||||
{
|
||||
Z_Free(handle);
|
||||
}
|
||||
|
||||
int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
int rootlen = strlen(rootpath);
|
||||
char *sub;
|
||||
mfile_t *f;
|
||||
if (*match == '/')
|
||||
match++;
|
||||
for (f = mfiles; f; f = f->next)
|
||||
{
|
||||
sub = f->name;
|
||||
if (strncmp(sub, rootpath, rootlen))
|
||||
continue;
|
||||
sub += rootlen;
|
||||
if (*sub == '/')
|
||||
sub++;
|
||||
if (wildcmp(match, sub))
|
||||
{
|
||||
if (!func(sub, f->length, (time_t)0, parm, spath))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static int FSPPAPI_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (*func)(const char *, qofs_t, time_t, void *, searchpathfuncs_t *), void *parm)
|
||||
{
|
||||
pppath_t *sp = (void*)handle;
|
||||
return Sys_EnumerateFiles(sp->rootpath, match, func, parm, handle);
|
||||
}
|
||||
|
||||
static int FSPPAPI_RebuildFSHash(const char *filename, qofs_t filesize, time_t time, void *data, searchpathfuncs_t *handle)
|
||||
{
|
||||
pppath_t *sp = (void*)handle;
|
||||
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = data;
|
||||
if (filename[strlen(filename)-1] == '/')
|
||||
{ //this is actually a directory
|
||||
|
||||
char childpath[256];
|
||||
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
|
||||
Sys_EnumerateFiles(sp->rootpath, childpath, FSPPAPI_RebuildFSHash, data, handle);
|
||||
return true;
|
||||
}
|
||||
AddFileHash(0, filename, NULL, handle);
|
||||
return true;
|
||||
}
|
||||
static void FSPPAPI_BuildHash(searchpathfuncs_t *handle, int depth, void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle))
|
||||
{
|
||||
pppath_t *sp = (void*)handle;
|
||||
Sys_EnumerateFiles(sp->rootpath, "*", FSPPAPI_RebuildFSHash, AddFileHash, handle);
|
||||
}
|
||||
|
||||
static qboolean FSPPAPI_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
||||
{
|
||||
pppath_t *sp = (void*)handle;
|
||||
int len;
|
||||
char netpath[MAX_OSPATH];
|
||||
|
||||
if (hashedresult && (void *)hashedresult != handle)
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (!static_registered)
|
||||
{ // if not a registered version, don't ever go beyond base
|
||||
if ( strchr (filename, '/') || strchr (filename,'\\'))
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
// check a file in the directory tree
|
||||
snprintf (netpath, sizeof(netpath)-1, "%s/%s",sp->rootpath, filename);
|
||||
|
||||
{
|
||||
vfsfile_t *f = VFSPPAPI_Open(netpath, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
len = VFS_GETLEN(f);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
|
||||
if (loc)
|
||||
{
|
||||
loc->len = len;
|
||||
loc->offset = 0;
|
||||
loc->fhandle = 0;
|
||||
Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static void FSPPAPI_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
|
||||
{
|
||||
vfsfile_t *f;
|
||||
size_t result;
|
||||
|
||||
f = VFSPPAPI_Open(loc->rawname, "rb");
|
||||
if (!f) //err...
|
||||
return;
|
||||
VFS_SEEK(f, loc->offset);
|
||||
result = VFS_READ(f, buffer, loc->len);
|
||||
|
||||
if (result != loc->len)
|
||||
Con_Printf("FSPPAPI_ReadFile() fread: Filename: %s, expected %i, result was %u\n",loc->rawname,(int)loc->len,(unsigned int)result);
|
||||
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
|
||||
searchpathfuncs_t *QDECL FSPPAPI_OpenPath(vfsfile_t *mustbenull, const char *desc, const char *prefix)
|
||||
{
|
||||
pppath_t *np;
|
||||
int dlen = strlen(desc);
|
||||
if (mustbenull)
|
||||
return NULL;
|
||||
if (prefix && *prefix)
|
||||
return NULL; //don't try to support this. too risky with absolute paths etc.
|
||||
np = Z_Malloc(sizeof(*np) + dlen);
|
||||
if (np)
|
||||
{
|
||||
np->depth = 0;
|
||||
memcpy(np->rootpath, desc, dlen+1);
|
||||
}
|
||||
|
||||
np->pub.fsver = FSVER;
|
||||
np->pub.ClosePath = FSPPAPI_ClosePath;
|
||||
np->pub.BuildHash = FSPPAPI_BuildHash;
|
||||
np->pub.FindFile = FSPPAPI_FLocate;
|
||||
np->pub.ReadFile = FSPPAPI_ReadFile;
|
||||
np->pub.EnumerateFiles = FSPPAPI_EnumerateFiles;
|
||||
np->pub.OpenVFS = FSPPAPI_OpenVFS;
|
||||
//np->pub.PollChanges = FSPPAPI_PollChanges;
|
||||
return &np->pub;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//this code is old and won't work.
|
||||
|
||||
#define FSPPAPI_OpenTemp FS_OpenTemp
|
||||
#define VFSPPAPI_Open VFSOS_Open
|
||||
|
||||
extern PPB_FileIO *ppb_fileio;
|
||||
extern PPB_FileRef *ppb_fileref;
|
||||
extern PPB_FileSystem *ppb_filesystem;
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PP_Instance pp_instance;
|
||||
static PP_Resource mainfilesystem;
|
||||
|
||||
|
||||
struct PP_CompletionCallback nullccb;
|
||||
|
||||
void FSPPAPI_Init(void)
|
||||
{
|
||||
mainfilesystem = ppb_filesystem->Create(pp_instance, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
|
||||
ppb_filesystem->Open(mainfilesystem, 100*1024*1024, nullccb);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
vfsfile_t funcs;
|
||||
PP_Resource handle;
|
||||
int64_t offset;
|
||||
} vfsppapifile_t;
|
||||
static int VFSPPAPI_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
|
||||
{
|
||||
int res;
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
|
||||
res = ppb_fileio->Read(intfile->handle, intfile->offset, buffer, bytestoread, nullccb);
|
||||
if (res > 0)
|
||||
intfile->offset += res;
|
||||
return res;
|
||||
}
|
||||
static int VFSPPAPI_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
|
||||
{
|
||||
int res;
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
res = ppb_fileio->Write(intfile->handle, intfile->offset, buffer, bytestoread, nullccb);
|
||||
if (res > 0)
|
||||
intfile->offset += res;
|
||||
return res;
|
||||
}
|
||||
static qboolean VFSPPAPI_Seek (struct vfsfile_s *file, qofs_t pos)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
intfile->offset = pos;
|
||||
return true;
|
||||
}
|
||||
static qofs_t VFSPPAPI_Tell (struct vfsfile_s *file)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
return intfile->offset;
|
||||
}
|
||||
static void VFSPPAPI_Flush(struct vfsfile_s *file)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
ppb_fileio->Flush(intfile->handle, nullccb);
|
||||
}
|
||||
static qofs_t VFSPPAPI_GetSize (struct vfsfile_s *file)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
struct PP_FileInfo fileinfo;
|
||||
|
||||
fileinfo.size = 0;
|
||||
ppb_fileio->Query(intfile->handle, &fileinfo, nullccb);
|
||||
return fileinfo.size;
|
||||
}
|
||||
static void VFSPPAPI_Close(vfsfile_t *file)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
ppb_fileio->Close(intfile->handle);
|
||||
ppb_core->ReleaseResource(intfile->handle);
|
||||
Z_Free(file);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void VFSPPAPI_CloseTemp(vfsfile_t *file)
|
||||
{
|
||||
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
|
||||
char *fname = (char*)(intfile+1);
|
||||
ppb_fileio->Close(intfile->handle);
|
||||
ppb_core->ReleaseResource(intfile->handle);
|
||||
/*FIXME: add the remove somewhere*/
|
||||
// _unlink(fname);
|
||||
Z_Free(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
vfsfile_t *FSPPAPI_OpenTemp(void)
|
||||
{
|
||||
return NULL;
|
||||
#if 0
|
||||
FILE *f;
|
||||
vfsppapifile_t *file;
|
||||
|
||||
f = tmpfile();
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
file = Z_Malloc(sizeof(vfsppapifile_t));
|
||||
file->funcs.Close = VFSPPAPI_Close;
|
||||
file->funcs.ReadBytes = VFSPPAPI_ReadBytes;
|
||||
file->funcs.WriteBytes = VFSPPAPI_WriteBytes;
|
||||
file->funcs.Seek = VFSPPAPI_Seek;
|
||||
file->funcs.Tell = VFSPPAPI_Tell;
|
||||
file->funcs.GetLen = VFSPPAPI_GetSize;
|
||||
file->funcs.Flush = VFSPPAPI_Flush;
|
||||
file->handle = f;
|
||||
|
||||
return (vfsfile_t*)file;
|
||||
#endif
|
||||
}
|
||||
|
||||
vfsfile_t *VFSPPAPI_Open(const char *osname, const char *mode)
|
||||
{
|
||||
int e;
|
||||
PP_Resource f;
|
||||
PP_Resource fsf;
|
||||
vfsppapifile_t *file;
|
||||
qboolean read = !!strchr(mode, 'r');
|
||||
qboolean write = !!strchr(mode, 'w');
|
||||
qboolean append = !!strchr(mode, 'a');
|
||||
int newmode = 0;
|
||||
|
||||
if (read)
|
||||
newmode |= PP_FILEOPENFLAG_READ;
|
||||
if (write)
|
||||
newmode |= PP_FILEOPENFLAG_WRITE|PP_FILEOPENFLAG_TRUNCATE|PP_FILEOPENFLAG_CREATE;
|
||||
if (append)
|
||||
newmode |= PP_FILEOPENFLAG_WRITE|PP_FILEOPENFLAG_CREATE;
|
||||
|
||||
/*should we support w+ or r+ */
|
||||
|
||||
fsf = ppb_fileref->Create(mainfilesystem, osname);
|
||||
f = ppb_fileio->Create(pp_instance);
|
||||
e = ppb_fileio->Open(f, fsf, newmode, nullccb);
|
||||
ppb_core->ReleaseResource(fsf);
|
||||
|
||||
if (e != PP_OK)
|
||||
{
|
||||
Con_Printf("unable to open %s. error %i\n", osname, e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file = Z_Malloc(sizeof(vfsppapifile_t));
|
||||
file->funcs.ReadBytes = strchr(mode, 'r')?VFSPPAPI_ReadBytes:NULL;
|
||||
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSPPAPI_WriteBytes:NULL;
|
||||
file->funcs.Seek = VFSPPAPI_Seek;
|
||||
file->funcs.Tell = VFSPPAPI_Tell;
|
||||
file->funcs.GetLen = VFSPPAPI_GetSize;
|
||||
file->funcs.Close = VFSPPAPI_Close;
|
||||
file->funcs.Flush = VFSPPAPI_Flush;
|
||||
file->handle = f;
|
||||
|
||||
if (append)
|
||||
file->offset = VFSPPAPI_GetSize((vfsfile_t*)file);
|
||||
else
|
||||
file->offset = 0;
|
||||
|
||||
return (vfsfile_t*)file;
|
||||
}
|
||||
|
||||
static vfsfile_t *FSPPAPI_OpenVFS(void *handle, flocation_t *loc, const char *mode)
|
||||
{
|
||||
char diskname[MAX_OSPATH];
|
||||
|
||||
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
|
||||
|
||||
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
|
||||
|
||||
return VFSPPAPI_Open(diskname, mode);
|
||||
}
|
||||
|
||||
static void FSPPAPI_PrintPath(searchpathfuncs_t *handle)
|
||||
{
|
||||
Con_Printf("%s\n", (char*)handle);
|
||||
}
|
||||
static void FSPPAPI_ClosePath(searchpathfuncs_t *handle)
|
||||
{
|
||||
Z_Free(handle);
|
||||
}
|
||||
static int FSPPAPI_RebuildFSHash(const char *filename, qofs_t filesize, void *data)
|
||||
{
|
||||
if (filename[strlen(filename)-1] == '/')
|
||||
{ //this is actually a directory
|
||||
|
||||
char childpath[256];
|
||||
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
|
||||
Sys_EnumerateFiles((char*)data, childpath, FSPPAPI_RebuildFSHash, data);
|
||||
return true;
|
||||
}
|
||||
if (!Hash_GetInsensative(&filesystemhash, filename))
|
||||
{
|
||||
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
|
||||
strcpy((char *)(bucket+1), filename);
|
||||
//#ifdef _WIN32
|
||||
// Q_strlwr((char *)(bucket+1));
|
||||
//#endif
|
||||
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
|
||||
|
||||
fs_hash_files++;
|
||||
}
|
||||
else
|
||||
fs_hash_dups++;
|
||||
return true;
|
||||
}
|
||||
static void FSPPAPI_BuildHash(searchpathfuncs_t *handle)
|
||||
{
|
||||
Sys_EnumerateFiles(handle, "*", FSPPAPI_RebuildFSHash, handle);
|
||||
}
|
||||
static qboolean FSPPAPI_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
||||
{
|
||||
int len;
|
||||
char netpath[MAX_OSPATH];
|
||||
|
||||
Con_Printf("Locate %s\n", filename);
|
||||
|
||||
|
||||
if (hashedresult && (void *)hashedresult != handle)
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (!static_registered)
|
||||
{ // if not a registered version, don't ever go beyond base
|
||||
if ( strchr (filename, '/') || strchr (filename,'\\'))
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
// check a file in the directory tree
|
||||
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
|
||||
|
||||
{
|
||||
vfsfile_t *f = VFSPPAPI_Open(netpath, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
len = VFS_GETLEN(f);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
|
||||
if (loc)
|
||||
{
|
||||
loc->len = len;
|
||||
loc->offset = 0;
|
||||
loc->index = 0;
|
||||
Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static void FSPPAPI_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
|
||||
{
|
||||
vfsfile_t *f;
|
||||
size_t result;
|
||||
|
||||
f = VFSPPAPI_Open(loc->rawname, "rb");
|
||||
if (!f) //err...
|
||||
return;
|
||||
VFS_SEEK(f, loc->offset);
|
||||
result = VFS_READ(f, buffer, loc->len);
|
||||
|
||||
if (result != loc->len)
|
||||
Con_Printf("FSPPAPI_ReadFile() fread: Filename: %s, expected %i, result was %u\n",loc->rawname,loc->len,(unsigned int)result);
|
||||
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
static int FSPPAPI_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
|
||||
{
|
||||
return Sys_EnumerateFiles(handle, match, func, parm);
|
||||
}
|
||||
|
||||
searchpathfuncs_t *QDECL FSPPAPI_OpenPath(vfsfile_t *mustbenull, const char *desc)
|
||||
{
|
||||
stdiopath_t *np;
|
||||
int dlen = strlen(desc);
|
||||
if (mustbenull)
|
||||
return NULL;
|
||||
np = Z_Malloc(sizeof(*np) + dlen);
|
||||
if (np)
|
||||
{
|
||||
np->depth = 0;
|
||||
memcpy(np->rootpath, desc, dlen+1);
|
||||
}
|
||||
|
||||
np->pub.fsver = FSVER;
|
||||
np->pub.ClosePath = FSPPAPI_ClosePath;
|
||||
np->pub.BuildHash = FSPPAPI_BuildHash;
|
||||
np->pub.FindFile = FSPPAPI_FLocate;
|
||||
np->pub.ReadFile = FSPPAPI_ReadFile;
|
||||
np->pub.EnumerateFiles = FSPPAPI_EnumerateFiles;
|
||||
np->pub.OpenVFS = FSPPAPI_OpenVFS;
|
||||
//np->pub.PollChanges = FSPPAPI_PollChanges;
|
||||
return &np->pub;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,297 +0,0 @@
|
|||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/pp_completion_callback.h>
|
||||
#include <ppapi/gles2/gl2ext_ppapi.h>
|
||||
#include <ppapi/c/ppb_graphics_3d.h>
|
||||
#include <ppapi/c/ppb_instance.h>
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PPB_GetInterface sys_gbi;
|
||||
extern PPB_Graphics3D* graphics3d_interface;
|
||||
extern PP_Instance pp_instance;
|
||||
static PP_Resource glcontext;
|
||||
extern PPB_Instance* instance_interface;
|
||||
qboolean swappending;
|
||||
|
||||
extern cvar_t vid_vsync;
|
||||
|
||||
void FrameEvent(void* user_data, int32_t result);
|
||||
qboolean NAGL_SwapPending(void)
|
||||
{
|
||||
return swappending;
|
||||
}
|
||||
void swap_callback(void* user_data, int32_t result)
|
||||
{
|
||||
if (swappending)
|
||||
{
|
||||
swappending = false;
|
||||
|
||||
FrameEvent(NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GLVID_SwapBuffers(void)
|
||||
{
|
||||
qboolean vsync = vid_vsync.ival || !*vid_vsync.string;
|
||||
struct PP_CompletionCallback ccb = { swap_callback, NULL, vsync?PP_COMPLETIONCALLBACK_FLAG_NONE:PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
|
||||
glFlush();
|
||||
|
||||
switch(graphics3d_interface->SwapBuffers(glcontext, ccb))
|
||||
{
|
||||
case PP_OK_COMPLETIONPENDING:
|
||||
swappending |= vsync;
|
||||
break;
|
||||
case PP_OK:
|
||||
break;
|
||||
case PP_ERROR_INPROGRESS:
|
||||
Con_DPrintf("chrome still can't handle vid_wait 0. forcing vsync\n");
|
||||
vid_vsync.ival = 1;
|
||||
break;
|
||||
default:
|
||||
Con_DPrintf("unknown error on SwapBuffers call\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean GLVID_ApplyGammaRamps (unsigned int gammarampsize, unsigned short *ramps)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void *PPAPI_GetGLSymbol(char *symname)
|
||||
{
|
||||
int i;
|
||||
static struct {char *name; void *ptr;} funcs[] =
|
||||
{
|
||||
#define f(n) {#n , n},
|
||||
f(glActiveTexture)
|
||||
f(glAttachShader)
|
||||
f(glBindAttribLocation)
|
||||
f(glBindBuffer)
|
||||
f(glBindFramebuffer)
|
||||
f(glBindRenderbuffer)
|
||||
f(glBindTexture)
|
||||
f(glBlendColor)
|
||||
f(glBlendEquation)
|
||||
f(glBlendEquationSeparate)
|
||||
f(glBlendFunc)
|
||||
f(glBlendFuncSeparate)
|
||||
f(glBufferData)
|
||||
f(glBufferSubData)
|
||||
f(glCheckFramebufferStatus)
|
||||
f(glClear)
|
||||
f(glClearColor)
|
||||
f(glClearDepthf)
|
||||
f(glClearStencil)
|
||||
f(glColorMask)
|
||||
f(glCompileShader)
|
||||
f(glCompressedTexImage2D)
|
||||
f(glCompressedTexSubImage2D)
|
||||
f(glCopyTexImage2D)
|
||||
f(glCopyTexSubImage2D)
|
||||
f(glCreateProgram)
|
||||
f(glCreateShader)
|
||||
f(glCullFace)
|
||||
f(glDeleteBuffers)
|
||||
f(glDeleteFramebuffers)
|
||||
f(glDeleteProgram)
|
||||
f(glDeleteRenderbuffers)
|
||||
f(glDeleteShader)
|
||||
f(glDeleteTextures)
|
||||
f(glDepthFunc)
|
||||
f(glDepthMask)
|
||||
f(glDepthRangef)
|
||||
f(glDetachShader)
|
||||
f(glDisable)
|
||||
f(glDisableVertexAttribArray)
|
||||
f(glDrawArrays)
|
||||
f(glDrawElements)
|
||||
f(glEnable)
|
||||
f(glEnableVertexAttribArray)
|
||||
f(glFinish)
|
||||
f(glFlush)
|
||||
f(glFramebufferRenderbuffer)
|
||||
f(glFramebufferTexture2D)
|
||||
f(glFrontFace)
|
||||
f(glGenBuffers)
|
||||
f(glGenerateMipmap)
|
||||
f(glGenFramebuffers)
|
||||
f(glGenRenderbuffers)
|
||||
f(glGenTextures)
|
||||
f(glGetActiveAttrib)
|
||||
f(glGetActiveUniform)
|
||||
f(glGetAttachedShaders)
|
||||
f(glGetAttribLocation)
|
||||
f(glGetBooleanv)
|
||||
f(glGetBufferParameteriv)
|
||||
f(glGetError)
|
||||
f(glGetFloatv)
|
||||
f(glGetFramebufferAttachmentParameteriv)
|
||||
f(glGetIntegerv)
|
||||
f(glGetProgramiv)
|
||||
f(glGetProgramInfoLog)
|
||||
f(glGetRenderbufferParameteriv)
|
||||
f(glGetShaderiv)
|
||||
f(glGetShaderInfoLog)
|
||||
f(glGetShaderPrecisionFormat)
|
||||
f(glGetShaderSource)
|
||||
f(glGetString)
|
||||
f(glGetTexParameterfv)
|
||||
f(glGetTexParameteriv)
|
||||
f(glGetUniformfv)
|
||||
f(glGetUniformiv)
|
||||
f(glGetUniformLocation)
|
||||
f(glGetVertexAttribfv)
|
||||
f(glGetVertexAttribiv)
|
||||
f(glGetVertexAttribPointerv)
|
||||
f(glHint)
|
||||
f(glIsBuffer)
|
||||
f(glIsEnabled)
|
||||
f(glIsFramebuffer)
|
||||
f(glIsProgram)
|
||||
f(glIsRenderbuffer)
|
||||
f(glIsShader)
|
||||
f(glIsTexture)
|
||||
f(glLineWidth)
|
||||
f(glLinkProgram)
|
||||
f(glPixelStorei)
|
||||
f(glPolygonOffset)
|
||||
f(glReadPixels)
|
||||
f(glReleaseShaderCompiler)
|
||||
f(glRenderbufferStorage)
|
||||
f(glSampleCoverage)
|
||||
f(glScissor)
|
||||
f(glShaderBinary)
|
||||
f(glShaderSource)
|
||||
f(glStencilFunc)
|
||||
f(glStencilFuncSeparate)
|
||||
f(glStencilMask)
|
||||
f(glStencilMaskSeparate)
|
||||
f(glStencilOp)
|
||||
f(glStencilOpSeparate)
|
||||
f(glTexImage2D)
|
||||
f(glTexParameterf)
|
||||
f(glTexParameterfv)
|
||||
f(glTexParameteri)
|
||||
f(glTexParameteriv)
|
||||
f(glTexSubImage2D)
|
||||
f(glUniform1f)
|
||||
f(glUniform1fv)
|
||||
f(glUniform1i)
|
||||
f(glUniform1iv)
|
||||
f(glUniform2f)
|
||||
f(glUniform2fv)
|
||||
f(glUniform2i)
|
||||
f(glUniform2iv)
|
||||
f(glUniform3f)
|
||||
f(glUniform3fv)
|
||||
f(glUniform3i)
|
||||
f(glUniform3iv)
|
||||
f(glUniform4f)
|
||||
f(glUniform4fv)
|
||||
f(glUniform4i)
|
||||
f(glUniform4iv)
|
||||
f(glUniformMatrix2fv)
|
||||
f(glUniformMatrix3fv)
|
||||
f(glUniformMatrix4fv)
|
||||
f(glUseProgram)
|
||||
f(glValidateProgram)
|
||||
f(glVertexAttrib1f)
|
||||
f(glVertexAttrib1fv)
|
||||
f(glVertexAttrib2f)
|
||||
f(glVertexAttrib2fv)
|
||||
f(glVertexAttrib3f)
|
||||
f(glVertexAttrib3fv)
|
||||
f(glVertexAttrib4f)
|
||||
f(glVertexAttrib4fv)
|
||||
f(glVertexAttribPointer)
|
||||
f(glViewport)
|
||||
{NULL}
|
||||
};
|
||||
for (i = 0; funcs[i].name; i++)
|
||||
{
|
||||
if (!strcmp(funcs[i].name, symname))
|
||||
return funcs[i].ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void GL_Resized(int width, int height)
|
||||
{
|
||||
extern cvar_t vid_conautoscale, vid_conwidth;
|
||||
|
||||
vid.pixelwidth = width;
|
||||
vid.pixelheight = height;
|
||||
if (glcontext)
|
||||
{
|
||||
graphics3d_interface->ResizeBuffers(glcontext, width, height);
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
Cvar_ForceCallback(&vid_conwidth);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
||||
{
|
||||
if (!vid.pixelwidth)
|
||||
vid.pixelwidth = info->width;
|
||||
if (!vid.pixelheight)
|
||||
vid.pixelheight = info->height;
|
||||
if (vid.pixelwidth < 320)
|
||||
vid.pixelwidth = 320;
|
||||
if (vid.pixelheight < 200)
|
||||
vid.pixelheight = 200;
|
||||
|
||||
int32_t attribs[] = {PP_GRAPHICS3DATTRIB_WIDTH, vid.pixelwidth,
|
||||
PP_GRAPHICS3DATTRIB_HEIGHT, vid.pixelheight,
|
||||
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
|
||||
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
|
||||
PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR, PP_GRAPHICS3DATTRIB_BUFFER_DESTROYED,
|
||||
PP_GRAPHICS3DATTRIB_NONE};
|
||||
|
||||
glcontext = graphics3d_interface->Create(pp_instance, 0, attribs);
|
||||
|
||||
glSetCurrentContextPPAPI(glcontext);
|
||||
|
||||
if (!instance_interface->BindGraphics(pp_instance, glcontext))
|
||||
{
|
||||
Con_Printf("failed to bind context\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLVID_SwapBuffers();
|
||||
|
||||
// vid.pixelwidth = info->width;
|
||||
// vid.pixelheight = info->height;
|
||||
|
||||
return GL_Init(PPAPI_GetGLSymbol);
|
||||
}
|
||||
|
||||
void GLVID_Shutdown (void)
|
||||
{
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLVID_SwapBuffers();
|
||||
|
||||
ppb_core->ReleaseResource(glcontext);
|
||||
// glTerminatePPAPI();
|
||||
|
||||
GL_ForgetPointers();
|
||||
}
|
||||
void GLVID_DeInit (void)
|
||||
{
|
||||
GLVID_Shutdown();
|
||||
}
|
||||
|
||||
void GLVID_Crashed(void);
|
||||
|
||||
void GLVID_Update (vrect_t *rects);
|
||||
|
||||
void GLVID_SetCaption(const char *caption)
|
||||
{
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/ppb_audio.h>
|
||||
#include <ppapi/c/ppb_audio_config.h>
|
||||
extern PPB_Core *ppb_core;
|
||||
extern PPB_Audio *audio_interface;
|
||||
extern PPB_AudioConfig *audioconfig_interface;
|
||||
extern PP_Instance pp_instance;
|
||||
|
||||
extern int S_GetMixerTime(soundcardinfo_t *sc);
|
||||
|
||||
static void PPAPI_audio_callback(void *sample_buffer, uint32_t len,
|
||||
#ifdef PPB_AUDIO_INTERFACE_1_1
|
||||
PP_TimeDelta latency,
|
||||
#endif
|
||||
void *user_data)
|
||||
{
|
||||
soundcardinfo_t *sc = user_data;
|
||||
unsigned int framesz;
|
||||
if (sc)
|
||||
{
|
||||
int curtime = S_GetMixerTime(sc);
|
||||
framesz = sc->sn.numchannels * sc->sn.samplebytes;
|
||||
|
||||
//might as well dump it directly...
|
||||
sc->sn.buffer = sample_buffer;
|
||||
sc->sn.samples = len / sc->sn.samplebytes;
|
||||
S_PaintChannels (sc, curtime + (len / framesz));
|
||||
sc->sn.samples = 0;
|
||||
sc->sn.buffer = NULL;
|
||||
|
||||
sc->snd_sent += len;
|
||||
}
|
||||
}
|
||||
|
||||
static void PPAPI_Shutdown(soundcardinfo_t *sc)
|
||||
{
|
||||
audio_interface->StopPlayback((PP_Resource)sc->handle);
|
||||
ppb_core->ReleaseResource((PP_Resource)sc->handle);
|
||||
}
|
||||
|
||||
static unsigned int PPAPI_GetDMAPos(soundcardinfo_t *sc)
|
||||
{
|
||||
sc->sn.samplepos = sc->snd_sent / sc->sn.samplebytes;
|
||||
return sc->sn.samplepos;
|
||||
}
|
||||
|
||||
static void PPAPI_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
|
||||
{
|
||||
}
|
||||
|
||||
static void *PPAPI_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
|
||||
{
|
||||
*sampidx = 0;
|
||||
return sc->sn.buffer;
|
||||
}
|
||||
|
||||
static void PPAPI_Submit(soundcardinfo_t *sc, int start, int end)
|
||||
{
|
||||
}
|
||||
|
||||
static qboolean PPAPI_InitCard (soundcardinfo_t *sc, const char *cardname)
|
||||
{
|
||||
PP_Resource config;
|
||||
int framecount;
|
||||
|
||||
/*I'm not aware of any limits on the number of 'devices' we can create, but virtual devices on the same physical device are utterly pointless, so don't load more than one*/
|
||||
if (cardname && *cardname)
|
||||
return false; //only use the default device
|
||||
|
||||
/*the docs say only two sample rates are allowed*/
|
||||
if (sc->sn.speed <= 44100)
|
||||
sc->sn.speed = 44100;
|
||||
else
|
||||
sc->sn.speed = 48000;
|
||||
/*we can't choose these settings at all*/
|
||||
sc->sn.samplebytes = 2;
|
||||
sc->sn.sampleformat = QSF_S16;
|
||||
sc->sn.numchannels = 2;
|
||||
|
||||
#ifdef PPB_AUDIO_CONFIG_INTERFACE_1_1
|
||||
framecount = audioconfig_interface->RecommendSampleFrameCount(pp_instance, sc->sn.speed, 2048);
|
||||
#else
|
||||
framecount = audioconfig_interface->RecommendSampleFrameCount(sc->sn.speed, 2048);
|
||||
#endif
|
||||
|
||||
/*the callback paints directly into the caller's buffer, so we don't need a separate 'dma' buffer*/
|
||||
sc->selfpainting = true;
|
||||
sc->sn.samples = 0; /*framecount*/
|
||||
sc->sn.buffer = NULL;
|
||||
|
||||
sc->snd_sent = 0;
|
||||
sc->sn.samplepos = 0;
|
||||
|
||||
sc->Submit = PPAPI_Submit;
|
||||
sc->GetDMAPos = PPAPI_GetDMAPos;
|
||||
sc->Lock = PPAPI_LockBuffer;
|
||||
sc->Unlock = PPAPI_UnlockBuffer;
|
||||
sc->Shutdown = PPAPI_Shutdown;
|
||||
|
||||
|
||||
config = audioconfig_interface->CreateStereo16Bit(pp_instance, sc->sn.speed, framecount);
|
||||
if (config)
|
||||
{
|
||||
sc->handle = (void*)audio_interface->Create(pp_instance, config, PPAPI_audio_callback, sc);
|
||||
ppb_core->ReleaseResource(config);
|
||||
if (sc->handle)
|
||||
{
|
||||
if (audio_interface->StartPlayback((PP_Resource)sc->handle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sounddriver_t PPAPI_AudioOutput =
|
||||
{
|
||||
"Pepper",
|
||||
PPAPI_InitCard,
|
||||
NULL
|
||||
};
|
|
@ -1,697 +0,0 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#include <ppapi/c/pp_errors.h>
|
||||
#include <ppapi/c/ppb.h>
|
||||
#include <ppapi/c/ppb_core.h>
|
||||
#include <ppapi/c/ppb_graphics_3d.h>
|
||||
#include <ppapi/c/ppb_instance.h>
|
||||
#include <ppapi/c/ppp.h>
|
||||
#include <ppapi/c/ppp_instance.h>
|
||||
#include <ppapi/c/ppb_input_event.h>
|
||||
#include <ppapi/c/ppp_input_event.h>
|
||||
#include <ppapi/c/ppb_var.h>
|
||||
#include <ppapi/c/ppb_var_array_buffer.h>
|
||||
#include <ppapi/c/ppb_messaging.h>
|
||||
#include <ppapi/c/ppb_file_system.h>
|
||||
#include <ppapi/c/ppb_file_ref.h>
|
||||
#include <ppapi/c/ppb_file_io.h>
|
||||
#include <ppapi/c/ppb_url_loader.h>
|
||||
#include <ppapi/c/ppb_url_response_info.h>
|
||||
#include <ppapi/c/ppb_url_request_info.h>
|
||||
#include <ppapi/c/ppb_audio.h>
|
||||
#include <ppapi/c/ppb_audio_config.h>
|
||||
#include <ppapi/c/ppb_mouse_lock.h>
|
||||
#include <ppapi/c/ppp_mouse_lock.h>
|
||||
#include <ppapi/c/ppb_fullscreen.h>
|
||||
#include <ppapi/c/ppb_websocket.h>
|
||||
#include <ppapi/c/ppb_view.h>
|
||||
#include <ppapi/c/ppp_messaging.h>
|
||||
|
||||
#include <ppapi/c/pp_input_event.h>
|
||||
#include <ppapi/gles2/gl2ext_ppapi.h>
|
||||
|
||||
PPB_Core *ppb_core = NULL;
|
||||
PPB_Graphics3D *graphics3d_interface = NULL;
|
||||
PPB_Instance *instance_interface = NULL;
|
||||
PPB_Messaging *ppb_messaging_interface = NULL;
|
||||
PPB_Var *ppb_var_interface = NULL;
|
||||
PPB_VarArrayBuffer *ppb_vararraybuffer_interface = NULL;
|
||||
PPB_InputEvent *ppb_inputevent_interface = NULL;
|
||||
PPB_KeyboardInputEvent *ppb_keyboardinputevent_interface = NULL;
|
||||
PPB_MouseInputEvent *ppb_mouseinputevent_interface = NULL;
|
||||
PPB_WheelInputEvent *ppb_wheelinputevent_interface = NULL;
|
||||
PPB_FileIO *ppb_fileio = NULL;
|
||||
PPB_FileRef *ppb_fileref = NULL;
|
||||
PPB_FileSystem *ppb_filesystem = NULL;
|
||||
PPB_URLLoader *urlloader = NULL;
|
||||
PPB_URLRequestInfo *urlrequestinfo = NULL;
|
||||
PPB_URLResponseInfo *urlresponseinfo = NULL;
|
||||
PPB_Audio *audio_interface = NULL;
|
||||
PPB_AudioConfig *audioconfig_interface = NULL;
|
||||
PPB_MouseLock *ppb_mouselock_interface = NULL;
|
||||
PPB_Fullscreen *ppb_fullscreen_interface = NULL;
|
||||
PPB_WebSocket *ppb_websocket_interface = NULL;
|
||||
PPB_View *ppb_view_instance = NULL;
|
||||
PP_Instance pp_instance;
|
||||
PPB_GetInterface sys_gbi;
|
||||
static double lasttime;
|
||||
static qboolean mouselocked;
|
||||
static qboolean shuttingdown;
|
||||
|
||||
qboolean FSPPAPI_Init(int *filenocookie);
|
||||
qboolean NAGL_SwapPending(void);
|
||||
|
||||
unsigned short htons(unsigned short a)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char c[2];
|
||||
unsigned short s;
|
||||
} u;
|
||||
u.s = a;
|
||||
|
||||
return u.c[0] | (unsigned short)(u.c[1]<<8);
|
||||
}
|
||||
unsigned short ntohs(unsigned short a)
|
||||
{
|
||||
return htons(a);
|
||||
}
|
||||
unsigned int htonl(unsigned int a)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char c[4];
|
||||
unsigned int s;
|
||||
} u;
|
||||
u.s = a;
|
||||
|
||||
return u.c[0] | (unsigned int)(u.c[1]<<8) | (unsigned int)(u.c[2]<<16) | (unsigned int)(u.c[3]<<24);
|
||||
}
|
||||
unsigned long ntohl(unsigned long a)
|
||||
{
|
||||
return htonl(a);
|
||||
}
|
||||
|
||||
qboolean isDedicated = false;
|
||||
|
||||
|
||||
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void Sys_CloseLibrary(dllhandle_t *lib)
|
||||
{
|
||||
}
|
||||
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
char *Sys_GetNameForAddress(dllhandle_t *module, void *address)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qboolean Sys_RandomBytes(qbyte *string, int len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean Sys_InitTerminal (void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void Sys_CloseTerminal (void)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYS_CLIPBOARD_SIZE 256
|
||||
static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0};
|
||||
void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx)
|
||||
{
|
||||
callback(ctx, clipboard_buffer);
|
||||
}
|
||||
void Sys_SaveClipboard(clipboardtype_t cbt, char *text)
|
||||
{
|
||||
Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE);
|
||||
}
|
||||
void Sys_ServerActivity(void)
|
||||
{
|
||||
}
|
||||
|
||||
char *Sys_ConsoleInput (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void Sys_SendKeyEvents(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Sys_Init (void)
|
||||
{
|
||||
}
|
||||
void Sys_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//this is already done using the ppapi event callback. can't poll any of this stuff.
|
||||
void INS_Move(void)
|
||||
{
|
||||
}
|
||||
void INS_Commands(void)
|
||||
{
|
||||
}
|
||||
void INS_Init(void)
|
||||
{
|
||||
}
|
||||
void INS_ReInit(void)
|
||||
{
|
||||
}
|
||||
void INS_Shutdown(void)
|
||||
{
|
||||
}
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type, const char *devicename, unsigned int *qdevid))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
//nacl supposedly has no way to implement this (other than us writing a listfile in each directory)
|
||||
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *), void *parm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
|
||||
{
|
||||
*width = 1024;
|
||||
*height = 768;
|
||||
*bpp = 32;
|
||||
*refreshrate = 60;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sys_Sleep (double seconds)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = (time_t)seconds;
|
||||
seconds -= ts.tv_sec;
|
||||
ts.tv_nsec = seconds * 1000000000.0;
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
// an error will cause the entire program to exit
|
||||
NORETURN void VARGS 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);
|
||||
COM_WorkerAbort(string);
|
||||
|
||||
Sys_Printf("Sys_Error: %s", string);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static struct PP_Var CStrToVar(const char* str)
|
||||
{
|
||||
if (ppb_var_interface != NULL)
|
||||
{
|
||||
return ppb_var_interface->VarFromUtf8(str, strlen(str));
|
||||
}
|
||||
return PP_MakeUndefined();
|
||||
}
|
||||
void VARGS Sys_Printf (char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr, fmt);
|
||||
vsnprintf (string, sizeof(string)-1, fmt, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
//this stuff generally doesn't even get shown
|
||||
printf("%s", string);
|
||||
if (pp_instance)
|
||||
ppb_messaging_interface->PostMessage(pp_instance, CStrToVar(string));
|
||||
}
|
||||
void ppp_handlemessage(PP_Instance instance, struct PP_Var message)
|
||||
{
|
||||
char *clean;
|
||||
const char *msg;
|
||||
unsigned int len;
|
||||
msg = ppb_var_interface->VarToUtf8(message, &len);
|
||||
clean = malloc(len+2);
|
||||
clean[len+0] = '\n';
|
||||
clean[len+1] = 0;
|
||||
memcpy(clean, msg, len);
|
||||
Cbuf_AddText(clean, RESTRICT_INSECURE);
|
||||
free(clean);
|
||||
}
|
||||
|
||||
void Sys_Quit (void)
|
||||
{
|
||||
Sys_Printf("Sys_Quit\n");
|
||||
|
||||
shuttingdown = true;
|
||||
}
|
||||
void Sys_RecentServer(char *command, char *target, char *title, char *desc)
|
||||
{
|
||||
}
|
||||
|
||||
#include <sys/time.h>
|
||||
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)
|
||||
{
|
||||
return Sys_DoubleTime()*1000;
|
||||
}
|
||||
|
||||
void FrameEvent(void* user_data, int32_t result)
|
||||
{
|
||||
if (shuttingdown)
|
||||
{
|
||||
if (!mouselocked && ppb_mouselock_interface)
|
||||
ppb_mouselock_interface->UnlockMouse(pp_instance);
|
||||
if (ppb_fullscreen_interface)
|
||||
ppb_fullscreen_interface->SetFullscreen(pp_instance, PP_FALSE);
|
||||
Host_Shutdown ();
|
||||
ppb_inputevent_interface->RequestInputEvents(pp_instance, 0);
|
||||
shuttingdown = false;
|
||||
return;
|
||||
}
|
||||
if (pp_instance)
|
||||
{
|
||||
if (!NAGL_SwapPending())
|
||||
{
|
||||
double newtime = Sys_DoubleTime();
|
||||
// Sys_Printf("Frame %f\n", newtime);
|
||||
Host_Frame(newtime - lasttime);
|
||||
lasttime = newtime;
|
||||
}
|
||||
|
||||
if (!NAGL_SwapPending())
|
||||
{
|
||||
struct PP_CompletionCallback ccb = {FrameEvent, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
ppb_core->CallOnMainThread(0, ccb, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
void startquake(char *manif)
|
||||
{
|
||||
static const char *args[16];
|
||||
quakeparms_t parms;
|
||||
memset(&parms, 0, sizeof(parms));
|
||||
parms.basedir = ""; /*filled in later*/
|
||||
parms.argc = 0;
|
||||
parms.argv = args;
|
||||
|
||||
//FIXME: generate some sort of commandline properly.
|
||||
args[parms.argc++] = "ftedroid";
|
||||
if (manif)
|
||||
{
|
||||
args[parms.argc++] = "-manifest";
|
||||
args[parms.argc++] = manif;
|
||||
}
|
||||
|
||||
Sys_Printf("Starting up (Built "__DATE__ ", " __TIME__")\n");
|
||||
|
||||
COM_InitArgv(parms.argc, parms.argv);
|
||||
TL_InitLanguages("");
|
||||
#ifdef SERVERONLY
|
||||
SV_Init(&parms);
|
||||
#else
|
||||
Host_Init(&parms);
|
||||
#endif
|
||||
|
||||
lasttime = Sys_DoubleTime();
|
||||
|
||||
FrameEvent(NULL, 0);
|
||||
}
|
||||
|
||||
void trystartquake(void* user_data, int32_t result)
|
||||
{
|
||||
if (FSPPAPI_Init(&result))
|
||||
startquake(user_data);
|
||||
else
|
||||
{
|
||||
struct PP_CompletionCallback ccb = {trystartquake, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
ppb_core->CallOnMainThread(100, ccb, result);
|
||||
}
|
||||
}
|
||||
|
||||
static PP_Bool Instance_DidCreate(PP_Instance instance,
|
||||
uint32_t argc,
|
||||
const char* argn[],
|
||||
const char* argv[])
|
||||
{
|
||||
int i;
|
||||
pp_instance = instance;
|
||||
char *manif = NULL;
|
||||
|
||||
//FIXME: do something with the embed arguments
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (!strcasecmp(argn[i], "ftemanifest"))
|
||||
manif = strdup(argv[i]);
|
||||
}
|
||||
|
||||
ppb_inputevent_interface->RequestInputEvents(pp_instance, PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD | PP_INPUTEVENT_CLASS_WHEEL);
|
||||
|
||||
trystartquake(manif, 0);
|
||||
|
||||
return PP_TRUE;
|
||||
}
|
||||
|
||||
static void cb_mouselocked(void* user_data, int32_t result)
|
||||
{
|
||||
if (result == PP_OK)
|
||||
{
|
||||
mouselocked = true;
|
||||
}
|
||||
}
|
||||
static void ppp_mouseunlocked(PP_Instance instance)
|
||||
{
|
||||
mouselocked = false;
|
||||
}
|
||||
|
||||
unsigned int domkeytoquake(unsigned int code)
|
||||
{
|
||||
unsigned int tab[256] =
|
||||
{
|
||||
/* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0,
|
||||
/* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0, 0,0,0,K_ESCAPE,0,0,0,0,
|
||||
/* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0,
|
||||
/* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0,
|
||||
|
||||
/* 64*/ 0,'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o',
|
||||
/* 80*/ 'p','q','r','s','t','u','v','w', 'x','y','z',K_LWIN,K_RWIN,K_APP,0,0,
|
||||
/* 96*/ K_KP_INS,K_KP_END,K_KP_DOWNARROW,K_KP_PGDN,K_KP_LEFTARROW,K_KP_5,K_KP_RIGHTARROW,K_KP_HOME, K_KP_UPARROW,K_KP_PGDN,K_KP_STAR,K_KP_PLUS,0,K_KP_MINUS,K_KP_DEL,K_KP_SLASH,
|
||||
/*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8, K_F9,K_F10,K_F11,K_F12,0,0,0,0,
|
||||
/*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
/*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
/*160*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
/*176*/ 0,0,0,0,0,0,0,0, 0,0,';','=',',','-','.','/',
|
||||
/*192*/ '\'',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
/*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'[','\\',']','#','`',
|
||||
/*224*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
/*240*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
};
|
||||
if (code >= sizeof(tab)/sizeof(tab[0]))
|
||||
{
|
||||
Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code);
|
||||
return 0;
|
||||
}
|
||||
if (!tab[code])
|
||||
Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code);
|
||||
|
||||
Con_DPrintf("You just pressed dom key %u, which is quake key %u\n", code, tab[code]);
|
||||
return tab[code];
|
||||
}
|
||||
|
||||
static int QuakeButtonForNACLButton(int but)
|
||||
{
|
||||
switch(but)
|
||||
{
|
||||
case 1:
|
||||
return K_MOUSE3;
|
||||
case 2:
|
||||
return K_MOUSE2;
|
||||
default:
|
||||
return K_MOUSE1 + but;
|
||||
}
|
||||
}
|
||||
static PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource)
|
||||
{
|
||||
extern cvar_t vid_fullscreen;
|
||||
if (!pp_instance || !host_initialized)
|
||||
return PP_FALSE;
|
||||
|
||||
switch(ppb_inputevent_interface->GetType(resource))
|
||||
{
|
||||
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
|
||||
if (vid_fullscreen.ival)
|
||||
{
|
||||
if (ppb_fullscreen_interface)
|
||||
ppb_fullscreen_interface->SetFullscreen(pp_instance, PP_TRUE);
|
||||
|
||||
if (!mouselocked && ppb_mouselock_interface)
|
||||
{
|
||||
struct PP_CompletionCallback ccb = {cb_mouselocked, NULL, PP_COMPLETIONCALLBACK_FLAG_NONE};
|
||||
int res = ppb_mouselock_interface->LockMouse(pp_instance, ccb);
|
||||
if (res != PP_OK_COMPLETIONPENDING)
|
||||
cb_mouselocked(NULL, res);
|
||||
else
|
||||
return PP_TRUE;
|
||||
}
|
||||
}
|
||||
IN_KeyEvent(0, true, QuakeButtonForNACLButton(ppb_mouseinputevent_interface->GetButton(resource)), 0);
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_MOUSEUP:
|
||||
IN_KeyEvent(0, false, QuakeButtonForNACLButton(ppb_mouseinputevent_interface->GetButton(resource)), 0);
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
|
||||
{
|
||||
struct PP_Point p;
|
||||
if (mouselocked)
|
||||
{
|
||||
p = ppb_mouseinputevent_interface->GetMovement(resource);
|
||||
IN_MouseMove(0, false, p.x, p.y, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = ppb_mouseinputevent_interface->GetPosition(resource);
|
||||
IN_MouseMove(0, true, p.x, p.y, 0, 0);
|
||||
}
|
||||
}
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_MOUSEENTER:
|
||||
//we don't really care too much if it leave the window
|
||||
// Con_Printf("mouseenter\n");
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
|
||||
//we don't really care too much if it leave the window (should throttle framerates perhaps, but that's all)
|
||||
// Con_Printf("mouseleave\n");
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_WHEEL:
|
||||
{
|
||||
static float wheelticks;
|
||||
struct PP_FloatPoint p;
|
||||
p = ppb_wheelinputevent_interface->GetTicks(resource);
|
||||
|
||||
//the value is fractional, so we need some persistant value to track it on high-precision mice.
|
||||
wheelticks += p.y;
|
||||
while (wheelticks > 1)
|
||||
{
|
||||
IN_KeyEvent(0, 1, K_MWHEELUP, 0);
|
||||
IN_KeyEvent(0, 0, K_MWHEELUP, 0);
|
||||
wheelticks--;
|
||||
}
|
||||
while (wheelticks < 0)
|
||||
{
|
||||
IN_KeyEvent(0, 1, K_MWHEELDOWN, 0);
|
||||
IN_KeyEvent(0, 0, K_MWHEELDOWN, 0);
|
||||
wheelticks++;
|
||||
}
|
||||
}
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
|
||||
// Con_Printf("rawkeydown\n");
|
||||
return PP_FALSE;
|
||||
case PP_INPUTEVENT_TYPE_KEYDOWN:
|
||||
{
|
||||
int k = domkeytoquake(ppb_keyboardinputevent_interface->GetKeyCode(resource));
|
||||
int u = 0;
|
||||
if (k == K_TAB)
|
||||
u = '\t';
|
||||
if (k == K_ENTER)
|
||||
u = '\r';
|
||||
IN_KeyEvent(0, 1, k, u);
|
||||
}
|
||||
return PP_FALSE;
|
||||
case PP_INPUTEVENT_TYPE_KEYUP:
|
||||
IN_KeyEvent(0, 0, domkeytoquake(ppb_keyboardinputevent_interface->GetKeyCode(resource)), 0);
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_CHAR:
|
||||
{
|
||||
const unsigned char *s;
|
||||
unsigned int c;
|
||||
unsigned int len;
|
||||
len = 0;
|
||||
s = ppb_var_interface->VarToUtf8(ppb_keyboardinputevent_interface->GetCharacterText(resource), &len);
|
||||
while(len)
|
||||
{
|
||||
if (*s & 0x80)
|
||||
{
|
||||
if (!(*s & 0x40))
|
||||
{
|
||||
//illegal encoding
|
||||
c = '?';
|
||||
len -= 1;
|
||||
}
|
||||
else if (!(*s & 0x20) && (s[1] & 0xc0) == 0x80)
|
||||
{
|
||||
c = ((s[0] & 0x1f)<<6) | ((s[1] & 0x3f)<<0);
|
||||
if (c < (1<<7))
|
||||
c = '?';
|
||||
len -= 2;
|
||||
}
|
||||
else if (!(*s & 0x10) && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80)
|
||||
{
|
||||
c = ((s[0] & 0x0f)<<12) | ((s[1] & 0x3f)<<6) | ((s[2] & 0x3f)<<0);
|
||||
if (c < (1<<13))
|
||||
c = '?';
|
||||
len -= 3;
|
||||
}
|
||||
else if (!(*s & 0x08) && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
|
||||
{
|
||||
c = ((s[0] & 0x07)<<18) | ((s[1] & 0x3f)<<12) | ((s[2] & 0x3f)<<6) | ((s[3] & 0x3f)<<0);
|
||||
if (c < (1<<19))
|
||||
c = '?';
|
||||
len -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
//too lazy to handle that encoding
|
||||
c = '?';
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = *s;
|
||||
len--;
|
||||
}
|
||||
|
||||
//these keys are handled by actual proper keys
|
||||
if (c == '\t' || c == '\r')
|
||||
continue;
|
||||
|
||||
IN_KeyEvent(0, true, 0, c);
|
||||
IN_KeyEvent(0, false, 0, c);
|
||||
}
|
||||
}
|
||||
return PP_TRUE;
|
||||
case PP_INPUTEVENT_TYPE_CONTEXTMENU:
|
||||
//We don't care about the context menu, we just want to be able to right-click.
|
||||
return PP_TRUE;
|
||||
default:
|
||||
Con_Printf("Unknown input event type\n");
|
||||
break;
|
||||
}
|
||||
return PP_FALSE;
|
||||
}
|
||||
|
||||
static void Instance_DidDestroy(PP_Instance instance)
|
||||
{
|
||||
}
|
||||
void GL_Resized(int width, int height);
|
||||
static void Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource)
|
||||
{
|
||||
struct PP_Rect rect;
|
||||
ppb_view_instance->GetRect(view_resource, &rect);
|
||||
GL_Resized(rect.size.width, rect.size.height);
|
||||
}
|
||||
static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
|
||||
{
|
||||
// ActiveApp = has_focus;
|
||||
}
|
||||
static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
|
||||
{
|
||||
return PP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser)
|
||||
{
|
||||
ppb_core = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE));
|
||||
sys_gbi = get_browser;
|
||||
graphics3d_interface = (PPB_Graphics3D*)(get_browser(PPB_GRAPHICS_3D_INTERFACE));
|
||||
ppb_messaging_interface = (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
|
||||
ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
|
||||
instance_interface = (PPB_Instance*)(get_browser(PPB_INSTANCE_INTERFACE));
|
||||
ppb_inputevent_interface = (PPB_InputEvent*)(get_browser(PPB_INPUT_EVENT_INTERFACE));
|
||||
ppb_keyboardinputevent_interface = (PPB_KeyboardInputEvent*)(get_browser(PPB_KEYBOARD_INPUT_EVENT_INTERFACE));
|
||||
ppb_mouseinputevent_interface = (PPB_MouseInputEvent*)(get_browser(PPB_MOUSE_INPUT_EVENT_INTERFACE));
|
||||
ppb_wheelinputevent_interface = (PPB_WheelInputEvent*)(get_browser(PPB_WHEEL_INPUT_EVENT_INTERFACE));
|
||||
ppb_fileio = (PPB_FileIO*)(get_browser(PPB_FILEIO_INTERFACE));
|
||||
ppb_fileref = (PPB_FileRef*)(get_browser(PPB_FILEREF_INTERFACE));
|
||||
ppb_filesystem = (PPB_FileSystem*)(get_browser(PPB_FILESYSTEM_INTERFACE));
|
||||
urlloader = (PPB_URLLoader*)(get_browser(PPB_URLLOADER_INTERFACE ));
|
||||
urlrequestinfo = (PPB_URLRequestInfo*)(get_browser(PPB_URLREQUESTINFO_INTERFACE));
|
||||
urlresponseinfo = (PPB_URLResponseInfo*)(get_browser(PPB_URLRESPONSEINFO_INTERFACE));
|
||||
audio_interface = (PPB_Audio*)(get_browser(PPB_AUDIO_INTERFACE));
|
||||
audioconfig_interface = (PPB_AudioConfig*)(get_browser(PPB_AUDIO_CONFIG_INTERFACE));
|
||||
ppb_mouselock_interface = (PPB_MouseLock*)(get_browser(PPB_MOUSELOCK_INTERFACE));
|
||||
ppb_fullscreen_interface = (PPB_Fullscreen*)(get_browser(PPB_FULLSCREEN_INTERFACE));
|
||||
ppb_websocket_interface = (PPB_WebSocket*)(get_browser(PPB_WEBSOCKET_INTERFACE));
|
||||
ppb_view_instance = (PPB_View*)(get_browser(PPB_VIEW_INTERFACE));
|
||||
ppb_vararraybuffer_interface = (PPB_VarArrayBuffer*)(get_browser(PPB_VAR_ARRAY_BUFFER_INTERFACE));
|
||||
|
||||
glInitializePPAPI(sys_gbi);
|
||||
|
||||
return PP_OK;
|
||||
}
|
||||
PP_EXPORT const void* PPP_GetInterface(const char* interface_name)
|
||||
{
|
||||
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
|
||||
{
|
||||
static PPP_Instance instance_interface =
|
||||
{
|
||||
&Instance_DidCreate,
|
||||
&Instance_DidDestroy,
|
||||
&Instance_DidChangeView,
|
||||
&Instance_DidChangeFocus,
|
||||
&Instance_HandleDocumentLoad,
|
||||
};
|
||||
return &instance_interface;
|
||||
}
|
||||
if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)
|
||||
{
|
||||
static PPP_InputEvent input_event_interface =
|
||||
{
|
||||
&InputEvent_HandleEvent
|
||||
};
|
||||
return &input_event_interface;
|
||||
}
|
||||
if (strcmp(interface_name, PPP_MOUSELOCK_INTERFACE) == 0)
|
||||
{
|
||||
static PPP_MouseLock mouselock_interface =
|
||||
{
|
||||
&ppp_mouseunlocked
|
||||
};
|
||||
return &mouselock_interface;
|
||||
}
|
||||
if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0)
|
||||
{
|
||||
static PPP_Messaging messaging_interface =
|
||||
{
|
||||
ppp_handlemessage
|
||||
};
|
||||
return &messaging_interface;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
PP_EXPORT void PPP_ShutdownModule()
|
||||
{
|
||||
}
|
|
@ -1830,7 +1830,7 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum)
|
|||
{
|
||||
// if (pr_global_struct->self)
|
||||
// ED_Print (PROG_TO_EDICT(pr_global_struct->self));
|
||||
#if defined(__GNUC__) && !defined(FTE_TARGET_WEB) && !defined(NACL)
|
||||
#if defined(__GNUC__) && !defined(FTE_TARGET_WEB)
|
||||
externs->Printf("PR_ExecuteProgram: NULL function from exe (address %p)\n", __builtin_return_address(0));
|
||||
#else
|
||||
externs->Printf("PR_ExecuteProgram: NULL function from exe\n");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "progsint.h"
|
||||
#include "qcc.h"
|
||||
|
||||
#if !defined(FTE_TARGET_WEB) && !defined(NACL) && !defined(_XBOX)
|
||||
#if !defined(FTE_TARGET_WEB) && !defined(_XBOX)
|
||||
#ifndef AVAIL_ZLIB
|
||||
#define AVAIL_ZLIB
|
||||
#endif
|
||||
|
|
|
@ -363,18 +363,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define DLL_EXT ".so"
|
||||
#endif
|
||||
|
||||
#ifdef NACL
|
||||
#define OS_STRING "nacl"
|
||||
#define ID_INLINE static inline
|
||||
#define PATH_SEP '/'
|
||||
|
||||
#define ARCH_STRING "web"
|
||||
|
||||
#define Q3_LITTLE_ENDIAN
|
||||
|
||||
#define DLL_EXT ".so"
|
||||
#endif
|
||||
|
||||
//================================================================== Q3VM ===
|
||||
|
||||
#ifdef Q3_VM
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
There are multiple ways to embed a program into a browser. The 'web'/emscripten port, the nacl port, the npapi port, and the activex port.
|
||||
There are multiple ways to embed a program into a browser. The 'web'/emscripten port, the npapi port, and the activex port.
|
||||
|
||||
Quick start with browser-servers:
|
||||
(this uses webrtc, which should give low latency but is incompatible with native servers at this time.)
|
||||
|
|
Loading…
Reference in a new issue