diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 00000000..e9915a46
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/build-manual.sh b/android/build-manual.sh
new file mode 100644
index 00000000..db7f32a4
--- /dev/null
+++ b/android/build-manual.sh
@@ -0,0 +1,16 @@
+ANDROID_JAR=../android-13.jar
+AAPT=./../aapt
+DX=./../dx
+APKBUILDER=./../apkbuilder
+NAME=gravgun
+mkdir bin
+mkdir bin/classes
+mkdir assets/
+$AAPT package -M AndroidManifest.xml -m -S res -I $ANDROID_JAR
+$JAVA_HOME/bin/javac -d bin/classes -s bin/classes -cp $ANDROID_JAR src/in/celest/xash3d/*
+$DX --dex --output=bin/classes.dex bin/classes/
+$AAPT package -f -M AndroidManifest.xml -S res -I $ANDROID_JAR -F bin/$NAME.apk.unaligned
+python2 makepak.py pak/ assets/extras.pak
+zip -r bin/$NAME.apk.unaligned assets/
+$APKBUILDER bin/$NAME.apk -u -nf libs/ -rj libs -f bin/classes.dex -z bin/$NAME.apk.unaligned
+#java -jar /mnt/app/apktool/signapk.jar /mnt/app/apktool/testkey.x509.pem /mnt/app/apktool/testkey.pk8 bin/$NAME.apk bin/$NAME-signed.apk
diff --git a/android/build.sh b/android/build.sh
new file mode 100755
index 00000000..28b24e57
--- /dev/null
+++ b/android/build.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+ndk-build NDK_TOOLCHAIN_VERSION=4.8 NDK_DEBUG=1 V=1 -j5 APP_CFLAGS="-w"
+ant debug
+#jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../myks.keystore bin/mod-unsigned.apk xashdroid -tsa https://timestamp.geotrust.com/tsa
+#zipalign 4 bin/cs16-client-unsigned.apk bin/mod.apk
diff --git a/android/build.xml b/android/build.xml
new file mode 100644
index 00000000..88f6fb88
--- /dev/null
+++ b/android/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
new file mode 100644
index 00000000..79964494
--- /dev/null
+++ b/android/jni/Android.mk
@@ -0,0 +1,6 @@
+override TARGET_arm_release_CFLAGS :=
+override TARGET_thumb_release_CFLAGS :=
+override TARGET_arm_debug_CFLAGS :=
+override TARGET_thumb_debug_CFLAGS :=
+override TARGET_CFLAGS :=
+include $(call all-subdir-makefiles)
diff --git a/android/jni/Application.mk b/android/jni/Application.mk
new file mode 100644
index 00000000..7322d629
--- /dev/null
+++ b/android/jni/Application.mk
@@ -0,0 +1,11 @@
+CFLAGS_OPT := -O3 -fomit-frame-pointer -ggdb -funsafe-math-optimizations -ftree-vectorize -fgraphite-identity -floop-interchange -floop-block -funsafe-loop-optimizations -finline-limit=1024
+CFLAGS_OPT_ARM := -mthumb -mfpu=neon -mcpu=cortex-a9 -pipe -mvectorize-with-neon-quad -DVECTORIZE_SINCOS
+CFLAGS_OPT_ARMv5 :=-march=armv6 -mfpu=vfp -marm -pipe
+CFLAGS_OPT_X86 := -mtune=atom -march=atom -mssse3 -mfpmath=sse -funroll-loops -pipe -DVECTORIZE_SINCOS
+CFLAGS_HARDFP := -D_NDK_MATH_NO_SOFTFP=1 -mhard-float -mfloat-abi=hard -DLOAD_HARDFP -DSOFTFP_LINK
+APPLICATIONMK_PATH = $(call my-dir)
+
+XASH3D_CONFIG := $(APPLICATIONMK_PATH)/mod_config.mk
+
+APP_ABI := x86 armeabi-v7a-hard armeabi
+APP_MODULES := server
diff --git a/android/jni/mod_config.mk b/android/jni/mod_config.mk
new file mode 100644
index 00000000..5c0dc6bf
--- /dev/null
+++ b/android/jni/mod_config.mk
@@ -0,0 +1,14 @@
+LOCAL_CFLAGS += $(CFLAGS_OPT)
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a-hard)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARM) $(CFLAGS_HARDFP)
+endif
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARM) -mfloat-abi=softfp
+endif
+ifeq ($(TARGET_ARCH_ABI),armeabi)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARMv5)
+endif
+ifeq ($(TARGET_ARCH_ABI),x86)
+LOCAL_CFLAGS += $(CFLAGS_OPT_X86)
+endif
+
diff --git a/android/jni/server b/android/jni/server
new file mode 120000
index 00000000..e8dd6263
--- /dev/null
+++ b/android/jni/server
@@ -0,0 +1 @@
+../../dlls
\ No newline at end of file
diff --git a/android/pak/models/p_gravcannon.mdl b/android/pak/models/p_gravcannon.mdl
new file mode 100644
index 00000000..53ebfe0e
Binary files /dev/null and b/android/pak/models/p_gravcannon.mdl differ
diff --git a/android/pak/models/v_gravcannon.mdl b/android/pak/models/v_gravcannon.mdl
new file mode 100644
index 00000000..dd886c31
Binary files /dev/null and b/android/pak/models/v_gravcannon.mdl differ
diff --git a/android/pak/models/w_gravcannon.mdl b/android/pak/models/w_gravcannon.mdl
new file mode 100644
index 00000000..a024326e
Binary files /dev/null and b/android/pak/models/w_gravcannon.mdl differ
diff --git a/android/pak/models/w_gravcannont.mdl b/android/pak/models/w_gravcannont.mdl
new file mode 100644
index 00000000..c999697c
Binary files /dev/null and b/android/pak/models/w_gravcannont.mdl differ
diff --git a/android/pak/sprites/weapon_gravgun.txt b/android/pak/sprites/weapon_gravgun.txt
new file mode 100644
index 00000000..632ffa04
--- /dev/null
+++ b/android/pak/sprites/weapon_gravgun.txt
@@ -0,0 +1,9 @@
+8
+weapon 320 320hud1 80 120 80 20
+weapon_s 320 320hud1 80 140 80 20
+ammo 320 320hud2 0 34 18 18
+crosshair 320 crosshairs 72 48 24 24
+weapon 640 640hud2 0 135 170 45
+weapon_s 640 640hud5 0 135 170 45
+ammo 640 640hud7 0 96 24 24
+crosshair 640 crosshairs 72 48 24 24
\ No newline at end of file
diff --git a/android/project.properties b/android/project.properties
new file mode 100644
index 00000000..4513a1e4
--- /dev/null
+++ b/android/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-3
diff --git a/android/res/drawable/gravgun.png b/android/res/drawable/gravgun.png
new file mode 100644
index 00000000..184e83e9
Binary files /dev/null and b/android/res/drawable/gravgun.png differ
diff --git a/android/src/in/celest/xash3d/InstallReceiver.java b/android/src/in/celest/xash3d/InstallReceiver.java
new file mode 100644
index 00000000..7aee5cf3
--- /dev/null
+++ b/android/src/in/celest/xash3d/InstallReceiver.java
@@ -0,0 +1,14 @@
+package in.celest.xash3d;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class InstallReceiver extends BroadcastReceiver {
+private static final String TAG = "MOD_LAUNCHER";
+@Override
+public void onReceive(Context context, Intent arg1) {
+ Log.d( TAG, "Install received, extracting PAK" );
+ LauncherActivity.extractPAK( context, true );
+ }
+}
diff --git a/android/src/in/celest/xash3d/LauncherActivity.java b/android/src/in/celest/xash3d/LauncherActivity.java
new file mode 100644
index 00000000..2271a7c1
--- /dev/null
+++ b/android/src/in/celest/xash3d/LauncherActivity.java
@@ -0,0 +1,160 @@
+package in.celest.xash3d;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.content.Intent;
+import android.widget.EditText;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.Button;
+import android.widget.TextView;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.SharedPreferences;
+import java.lang.reflect.Method;
+import java.io.FileOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import android.content.Context;
+import android.util.Log;
+
+public class LauncherActivity extends Activity {
+ private static final int PAK_VERSION = 1;
+ static Boolean isExtracting = false;
+ static EditText cmdArgs;
+ static SharedPreferences mPref;
+ private static final String TAG = "MOD_LAUNCHER";
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Build layout
+ LinearLayout launcher = new LinearLayout(this);
+ launcher.setOrientation(LinearLayout.VERTICAL);
+ launcher.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
+ TextView titleView = new TextView(this);
+ titleView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+ titleView.setText("Command-line arguments");
+ titleView.setTextAppearance(this, android.R.attr.textAppearanceLarge);
+ cmdArgs = new EditText(this);
+ cmdArgs.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+ Button startButton = new Button(this);
+ // Set launch button title here
+ startButton.setText("Launch with gravgun!");
+ LayoutParams buttonParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ buttonParams.gravity = 5;
+ startButton.setLayoutParams(buttonParams);
+ startButton.setOnClickListener( new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startXash(v);
+ }
+ });
+ launcher.addView(titleView);
+ launcher.addView(cmdArgs);
+ // Add other options here
+ launcher.addView(startButton);
+ setContentView(launcher);
+ mPref = getSharedPreferences("mod", 0);
+ extractPAK(this, false);
+ cmdArgs.setText(mPref.getString("argv","-dev 3 -log"));
+ }
+
+ public void startXash(View view)
+ {
+ Intent intent = new Intent();
+ intent.setAction("in.celest.xash3d.START");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ SharedPreferences.Editor editor = mPref.edit();
+ editor.putString("argv", cmdArgs.getText().toString());
+ editor.commit();
+ editor.apply();
+ if(cmdArgs.length() != 0) intent.putExtra("argv", cmdArgs.getText().toString());
+ // Uncomment to set gamedir here
+ // intent.putExtra("gamedir", "mod" );
+ intent.putExtra("gamelibdir", getFilesDir().getAbsolutePath().replace("/files","/lib"));
+ intent.putExtra("pakfile", getFilesDir().getAbsolutePath() + "/extras.pak" );
+ startActivity(intent);
+ }
+ private static int chmod(String path, int mode) {
+ int ret = -1;
+ try
+ {
+ ret = Runtime.getRuntime().exec("chmod " + Integer.toOctalString(mode) + " " + path).waitFor();
+ Log.d(TAG, "chmod " + Integer.toOctalString(mode) + " " + path + ": " + ret );
+ }
+ catch(Exception e)
+ {
+ ret = -1;
+ Log.d(TAG, "chmod: Runtime not worked: " + e.toString() );
+ }
+ try
+ {
+ Class fileUtils = Class.forName("android.os.FileUtils");
+ Method setPermissions = fileUtils.getMethod("setPermissions",
+ String.class, int.class, int.class, int.class);
+ ret = (Integer) setPermissions.invoke(null, path,
+ mode, -1, -1);
+ }
+ catch(Exception e)
+ {
+ ret = -1;
+ Log.d(TAG, "chmod: FileUtils not worked: " + e.toString() );
+ }
+ return ret;
+ }
+
+ private static void extractFile(Context context, String path) {
+ try
+ {
+ InputStream is = null;
+ FileOutputStream os = null;
+ is = context.getAssets().open(path);
+ File out = new File(context.getFilesDir().getPath()+'/'+path);
+ out.getParentFile().mkdirs();
+ chmod( out.getParent(), 0777 );
+ os = new FileOutputStream(out);
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = is.read(buffer)) > 0) {
+ os.write(buffer, 0, length);
+ }
+ os.close();
+ is.close();
+ chmod( context.getFilesDir().getPath()+'/'+path, 0777 );
+ } catch( Exception e )
+ {
+ Log.e( TAG, "Failed to extract file:" + e.toString() );
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void extractPAK(Context context, Boolean force) {
+ if(isExtracting)
+ return;
+ isExtracting = true;
+ try {
+ if( mPref == null )
+ mPref = context.getSharedPreferences("mod", 0);
+ if( mPref.getInt( "pakversion", 0 ) == PAK_VERSION && !force )
+ return;
+ extractFile(context, "extras.pak");
+
+ SharedPreferences.Editor editor = mPref.edit();
+ editor.putInt( "pakversion", PAK_VERSION );
+ editor.commit();
+ editor.apply();
+ } catch( Exception e )
+ {
+ Log.e( TAG, "Failed to extract PAK:" + e.toString() );
+ }
+ isExtracting = false;
+ }
+
+}
diff --git a/dlls/gravgun.cpp b/dlls/gravgun.cpp
index e24022e7..5e3303ec 100644
--- a/dlls/gravgun.cpp
+++ b/dlls/gravgun.cpp
@@ -504,7 +504,7 @@ void CGrav::Pull(CBaseEntity* ent,float force)
ent->pev->velocity = (target - origin).Normalize()*550;
pev->velocity.z += 15;
}
- ent->pev->velocity = ent->pev->velocity + m_pPlayer->pev->velocity;
+ //ent->pev->velocity = ent->pev->velocity + m_pPlayer->pev->velocity;
/////
#ifdef BEAMS
CBeam* m_pBeam1 = CBeam::BeamCreate(GRAV_BEAM_SPRITE, 40);