android: move to gradle

This commit is contained in:
Velaron 2023-10-26 14:25:18 +03:00
parent 4d7309b77d
commit 75e0eb8f7d
215 changed files with 4255 additions and 10450 deletions

44
.gitignore vendored
View file

@ -1,34 +1,14 @@
# Build data .gradle/
build/ build/
build-xash3d-fwgs .externalNativeBuild
build-hlsdk-xash3d .cxx/
libs/armeabi* .idea/
libs/x86
obj
bin
gen
# Private info
local.properties local.properties
.project
# Builds .classpath
*.apk .gradle
.settings
# VKontakte gives a shit when uploading APK release/
*.bin *.hprof
.vscode/
# Generated *.bak
android/assets/extras.pak
android/res/values/git-rev.xml
android/src/in/celest/xash3d/XashConfig.java
android/lib
# Waf
build_current
*waf-*/
*waf3-*/
.lock-waf*
*.lastbuildstate
*.unsuccessfulbuild
__pycache__
*.pyc

19
.gitmodules vendored
View file

@ -1,12 +1,11 @@
[submodule "xash-extras"] [submodule "hlsdk-portable"]
path = xash-extras path = app/src/main/cpp/hlsdk-portable
url = https://github.com/FWGS/xash-extras url = https://github.com/FWGS/hlsdk-portable
[submodule "jni/src/xash3d-fwgs"] branch = mobile_hacks
path = xash3d-fwgs
url = https://github.com/FWGS/xash3d-fwgs
[submodule "hlsdk-xash3d"]
path = hlsdk-xash3d
url = https://github.com/FWGS/hlsdk-xash3d
[submodule "xash3d-fwgs"] [submodule "xash3d-fwgs"]
path = xash3d-fwgs path = app/src/main/cpp/xash3d-fwgs
url = https://github.com/FWGS/xash3d-fwgs url = https://github.com/FWGS/xash3d-fwgs
[submodule "SDL"]
path = app/src/main/cpp/SDL
url = https://github.com/libsdl-org/SDL
branch = release-2.24.1

View file

@ -1,56 +0,0 @@
language: android
android:
components:
- platform-tools
- build-tools-21.1.1
- android-19
- extra-android-support
install: ant
addons:
apt:
packages:
- ant
jdk: oraclejdk8
notifications:
email: false
before_install:
- wget http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin > /dev/null 2>/dev/null
- chmod +x android-ndk-r10e-linux-x86_64.bin && ./android-ndk-r10e-linux-x86_64.bin > /dev/null
- mv android-ndk-r10e android-ndk
- export PATH=`pwd`/android-ndk:`pwd`/android-sdk-linux/tools:`pwd`/android-sdk-linux/platform-tools:$PATH
- git submodule update --init --recursive
script:
- cp debug.keystore ~/.android/debug.keystore
- sh gen-version.sh travis build
- sh gen-config.sh test
- python2 makepak.py xash-extras assets/extras.pak
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="armeabi-v7a-hard"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-armv7.apk
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 clean
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="armeabi-v7a-hard" CFLAGS_OPT_ARM="-mthumb -mfpu=neon-vfpv4 -mcpu=cortex-a15 -ffast-math -pipe -mvectorize-with-neon-quad -DVECTORIZE_SINCOS -fPIC -DHAVE_EFFICIENT_UNALIGNED_ACCESS"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-armv7-cortex-a7-a15.apk
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="armeabi"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-armv6.apk
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="x86"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-x86.apk
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 clean
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="armeabi-v7a-hard" CFLAGS_OPT_ARM="-mthumb -mfpu=vfpv3-d16 -mcpu=cortex-a9 -pipe -fPIC"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-armv7-tegra2.apk
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 clean
- ndk-build NDK_TOOLCHAIN_VERSION=4.8 -j2 APP_CFLAGS="-w" APP_ABI="armeabi" CFLAGS_OPT_ARMv5="-marm -march=armv5te -msoft-float -fPIC"
- ant debug -Dtest.version=1
- cp bin/xashdroid-debug.apk xashdroid-armv5.apk
after_script:
- sh travis-upload.sh *.apk
- sh travis-deploy.sh android-optimized *.apk

3
Gemfile Normal file
View file

@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "fastlane"

218
Gemfile.lock Normal file
View file

@ -0,0 +1,218 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.5)
rexml
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.666.0)
aws-sdk-core (3.168.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.59.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.117.1)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.2)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.94.0)
faraday (1.10.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.211.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.31.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-core (0.9.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.16.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-playcustomapp_v1 (0.12.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.0)
google-cloud-storage (1.44.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.19.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.3.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.6.2)
jwt (2.5.0)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.1.2)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
naturally (2.2.1)
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (5.0.0)
rake (13.0.6)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.5)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.17.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.8)
CFPropertyList
naturally
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2-x64-mingw-ucrt)
unicode-display_width (1.8.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
x64-mingw-ucrt
DEPENDENCIES
fastlane
BUNDLED WITH
2.3.26

View file

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="su.xash.engine"
android:versionCode="1710"
android:versionName="0.20.1"
android:installLocation="auto"
android:allowAudioPlaybackCapture="true">
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:roundIcon="@mipmap/ic_launcher"
android:allowBackup="false"
android:fullBackupOnly="false"
android:debuggable="false"
android:hardwareAccelerated="true"
android:supportsRtl="false"
android:usesCleartextTraffic="true">
<activity android:name="su.xash.engine.LauncherActivity"
android:label="@string/launcher_name"
android:icon="@mipmap/ic_launcher"
android:windowSoftInputMode="adjustResize"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize">
<intent-filter>
<action android:name="su.xash.engine.LauncherActivity"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="su.xash.engine.ShortcutActivity"
android:label="@string/text_shortcut"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="su.xash.engine.SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="su.xash.engine.XashActivity"
android:screenOrientation="sensorLandscape"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="su.xash.engine.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="su.xash.engine.FPicker"></activity>
<activity android:name="su.xash.engine.XashTutorialActivity">
</activity>
<service android:name="su.xash.engine.XashService" android:stopWithTask="false" />
<receiver android:name="su.xash.engine.XashService$ExitButtonListener" />
<receiver android:name="su.xash.engine.InstallReceiver">
<intent-filter android:priority="100">
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<!--<service android:name="su.xash.engine.SteamService" />-->
<meta-data android:name="android.max_aspect" android:value="10000.0" />
<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" /> <!-- don't pause engine on foldables -->
</application>
<!-- Some devices with Android 2.2 should support native activity, it was in unstable hidden API -->
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="29" />
<!-- OpenGL ES 1.1 -->
<uses-feature android:glEsVersion="0x00010000" />
<!-- Permissions -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
</manifest>

View file

@ -1,4 +0,0 @@
These PNG files are copyright to Emile Belanger.
They are permitted for use in SDLxash3D Android port, full copyright is owned by Emile Belanger.
Other use not permitted without permission from Emile Belanger.
emile.belanger@gmail.com

View file

@ -1,30 +0,0 @@
#!/bin/bash
git update-index --assume-unchanged $XASH_CONFIG
PKG_TEST=false
CHECK_SIGNATURES=false
RELEASE=false
GP_VERSION=false
XASH_CONFIG=$1src/su/xash/engine/XashConfig.java
shift
case "$*" in
*test*) export PKG_TEST=true;;
esac
case "$*" in
*sign*) export CHECK_SIGNATURES=true;
esac
case "$*" in
*release*) export RELEASE=true;;
esac
case "$*" in
*gp*) export GP_VERSION=true;;
esac
_V="public static final boolean"
echo package su.xash.engine\; >$XASH_CONFIG
echo public class XashConfig { >>$XASH_CONFIG
echo $_V PKG_TEST = $PKG_TEST\; >>$XASH_CONFIG
echo $_V CHECK_SIGNATURES = $CHECK_SIGNATURES\; >>$XASH_CONFIG
echo $_V RELEASE = $RELEASE\; >>$XASH_CONFIG
echo $_V GP_VERSION = $GP_VERSION\; >>$XASH_CONFIG
echo } >>$XASH_CONFIG
cat $XASH_CONFIG

View file

@ -1,19 +0,0 @@
#!/bin/bash
GIT_REV_XML=$1/res/values/git-rev.xml
mkdir -p $(dirname $GIT_REV_XML)
git update-index --assume-unchanged $GIT_REV_XML
echo '<?xml version="1.0" encoding="utf-8"?>' > $GIT_REV_XML
echo '<resources>' >> $GIT_REV_XML
echo -n '<string name="git_revisions">' >> $GIT_REV_XML
echo -n '<b>Version information:</b>\n' >> $GIT_REV_XML
git submodule --quiet foreach --recursive \
'echo -n \<b\>`basename $name`:\</b\>\ \
`git log --abbrev-commit --pretty=oneline -1 | sed "s/\&/\&amp;/g;s/>/\&gt;/g;s/</\&lt;/g"`\\\\n' \
| sed -e "s|'|\\\'|g" >> $GIT_REV_XML
echo -n $USER@$(hostname) $(date +%H:%M:%S-%d-%m-%y) >> $GIT_REV_XML
echo '</string>' >> $GIT_REV_XML
echo '</resources>' >> $GIT_REV_XML
cat $GIT_REV_XML

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/sunset_orange" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="12dp"
android:height="12dp" />
<solid android:color="#80000000" />
</shape>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="12dp"
android:height="12dp" />
<solid android:color="#FFF" />
</shape>

View file

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#805fd1e2"/>
<stroke
android:width="2dp" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="@mipmap/ic_launcher"/>

View file

@ -1,110 +0,0 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_layout"
android:weightSum="1">
<!--<ImageView
android:layout_width="89dp"
android:layout_height="89dp"
android:id="@+id/aboutIcon"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />-->
<include
android:layout_width="89dp"
android:layout_height="89dp"
android:layout_gravity="center_horizontal"
layout="@layout/logo" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/about_main"
android:id="@+id/textView"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="https://xash.su"
android:id="@+id/textView9"
android:autoText="false"
android:autoLink="web"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/version_string"
android:id="@+id/textView3"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/about_links"
android:id="@+id/textView6"
android:autoText="false" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/about_authors"
android:id="@+id/textView4"
android:layout_weight="1"
android:clickable="false"
android:enabled="true"
android:singleLine="false"
android:password="false"
android:longClickable="false"
android:autoText="false"
android:includeFontPadding="false"
android:layout_gravity="fill"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/git_revisions"
android:id="@+id/textView5"
android:autoText="false"
android:longClickable="false"
android:password="false"
android:enabled="true"
android:clickable="false"
android:singleLine="false"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_copyright"
android:singleLine="false"
android:id="@+id/textView2"
android:layout_weight="0.58" />
<Button
android:id="@+id/show_firstrun"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/firstrun"/>
<Button
android:id="@+id/button_about_ok"
android:text="@string/ok"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
</ScrollView>

View file

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#252525"
android:orientation="vertical">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/FileView"
android:layout_weight="1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/folder"
android:id="@+id/button_fpicker_select"
android:layout_centerHorizontal="true"
android:onClick="onFileClick" />
</LinearLayout>

View file

@ -1,420 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_shortcut"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#252525"
android:weightSum="1" >
<LinearLayout
android:orientation="horizontal"
android:background="#555555"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp" >
<!--<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:src="@drawable/ic_launcher"
android:id="@+id/launcherIcon" />-->
<include
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="2dp"
layout="@layout/logo" />
<TextView
android:id="@+id/textView_tittle"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="#555555"
android:text="@string/launcher_name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="25sp"
android:singleLine="true"
android:gravity="center_vertical" />
</LinearLayout>
<TabHost
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.20"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#555555"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:showDividers="middle" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scrollView2">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#333333"
android:orientation="vertical"
android:text="@string/text_tab1"
android:weightSum="0.6">
<TextView
android:id="@+id/textView_path1"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginBottom="2dp"
android:layout_marginLeft="10dp"
android:background="#444444"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:text="@string/text_res_tittle2"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="20sp"
android:gravity="center_vertical|center_horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#444444"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:text="@string/volume"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ToggleButton
android:id="@+id/useVolume"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:text="nothing"
android:textOff="@string/no_volume"
android:textOn="@string/use_volume" />
<TextView
android:id="@+id/textView_path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/text_res_path"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/button_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:onClick="selectFolder"
android:text="@string/select_folder" />
<Button
android:id="@+id/button_shortcut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:onClick="createShortcut"
android:text="@string/create_shortcut_button" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#333333"
android:orientation="vertical"
android:text="@string/text_tab2"
android:weightSum="0.6">
<TextView
android:id="@+id/textView_path2"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginBottom="2dp"
android:layout_marginLeft="10dp"
android:background="#444444"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:text="@string/text_res_tittle3"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="20sp"
android:gravity="center_vertical|center_horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#444444"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:id="@+id/textView_args"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:text="@string/cmd_args_text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/cmdArgs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/text_res_path"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:orientation="horizontal"
android:weightSum="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp" >
<EditText
android:id="@+id/cmd_path"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:inputType="text"
android:layout_gravity="center_vertical"
android:scrollHorizontally="true" />
<Button
android:id="@+id/cmd_path_select"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:text="..."
android:onClick="selectFolder" />
</LinearLayout>
<ToggleButton
android:id="@+id/use_rodir"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:textOff="@string/no_rodir"
android:textOn="@string/use_rodir" />
<LinearLayout
android:id="@+id/rodir_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_res_rw_path"
android:textAppearance="?android:attr/textAppearanceMedium" />
<CheckBox
android:id="@+id/use_rodir_auto"
android:text="@string/use_rodir_auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="5dp" />
<LinearLayout
android:orientation="horizontal"
android:weightSum="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<EditText
android:id="@+id/cmd_path_rw"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:inputType="text"
android:layout_gravity="center_vertical"
android:scrollHorizontally="true" />
<Button
android:id="@+id/cmd_path_rw_select"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:text="..."
android:onClick="selectRwFolder" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:weightSum="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="@string/pixel_format"
android:id="@+id/pixel_format"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner
android:layout_height="40dp"
android:layout_alignBaseline="@id/pixel_format"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="right|center_vertical"
android:id="@+id/pixelSpinner"/>
</LinearLayout>
<ToggleButton
android:id="@+id/enableResizeWorkaround"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="enableResizeWorkaround"
android:textOff="@string/resize_off"
android:textOn="@string/resize_on" />
<CheckBox
android:id="@+id/check_updates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/update_button" />
<!--<CheckBox
android:id="@+id/check_betas"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/update_to_beta" />-->
<CheckBox
android:id="@+id/immersive_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/immersive_mode" />
<CheckBox
android:id="@+id/resolution"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/resolution" />
<RadioGroup
android:id="@+id/scale_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/resolution_mod_warn"
android:textAppearance="@style/red_small_text" />
<TextView
android:id="@+id/resolution_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<RadioButton
android:id="@+id/resolution_scale_r"
android:text="@string/resolution_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/resolution_scale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="3dp"
android:numeric="decimal" />
<RadioButton
android:id="@+id/resolution_custom_r"
android:text="@string/resolution_custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<EditText
android:id="@+id/resolution_width"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:numeric="integer" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:text="x"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/resolution_height"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="5dp"
android:numeric="integer" />
</LinearLayout>
</RadioGroup>
<!--<TextView
android:id="@+id/textView7"
android:layout_marginBottom="10dp"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:clickable="false" />-->
</LinearLayout>
</LinearLayout>
</FrameLayout>
</ScrollView>
</LinearLayout>
</TabHost>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#444444"
android:layout_marginBottom="-20dp"
android:layout_gravity="bottom"
android:orientation="horizontal">
<Button
android:id="@+id/button_about"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:onClick="aboutXash"
android:text="@string/about_button" />
<Button
android:id="@+id/button_launch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="6"
android:layout_marginLeft="0dp"
android:layout_weight="0.87"
android:onClick="startXash"
android:text="@string/launch_button" />
</LinearLayout>
</LinearLayout>

View file

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:id="@+id/layout_shortcut">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shortcut_button_save"
android:id="@+id/shortcut_buttonOk"
android:layout_alignParentRight="true"
android:onClick="saveShortcut"
android:layout_below="@+id/shortcut_pkgname"/>
<EditText
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="@+id/shortcut_name"
android:layout_below="@+id/shortcut_name_text"
android:layout_alignParentRight="true"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/shortcut_name_text"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/shortcut_name"
/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/shortcut_cmdArgs"
android:layout_below="@+id/shortcut_textView_args"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/cmd_args_text"
android:id="@+id/shortcut_textView_args"
android:layout_alignParentRight="true"
android:layout_below="@+id/shortcut_name"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/shortcut_gamedir"
android:layout_below="@+id/shortcut_gamedir_text"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/gamedir"
android:id="@+id/shortcut_gamedir_text"
android:layout_below="@+id/shortcut_cmdArgs"
android:layout_alignParentRight="true"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/shortcut_pkgname"
android:layout_below="@+id/shortcut_pkgname_text"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/pkgname"
android:id="@+id/shortcut_pkgname_text"
android:layout_below="@+id/shortcut_gamedir"
android:layout_alignParentRight="true"/>
</RelativeLayout>

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#555"
android:clipToPadding="false"
android:fitsSystemWindows="true"
android:orientation="vertical">
<LinearLayout android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="60dp"/>
<RelativeLayout
android:id="@+id/buttonContainer"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
android:background="#444"
android:clipToPadding="false">
<!-- android:elevation="24dp" -->
<Button
android:id="@+id/prev"
style="@android:style/Widget.DeviceDefault.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/prev"
android:textColor="#FFF" />
<Button
android:id="@+id/next"
style="@android:style/Widget.DeviceDefault.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="@string/finish"
android:textColor="#FFF" />
<LinearLayout
android:id="@+id/indicatorLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="horizontal" />
</RelativeLayout>
</FrameLayout>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="@drawable/ic_launcher"/>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="64dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/status_image"
android:src="@drawable/ic_launcher"
android:layout_weight="0"
android:layout_gravity="center_vertical"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<TextView
android:id="@+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:singleLine="true"
android:layout_weight="90"
android:text="Xash3D"
android:layout_gravity="center_vertical" />
<Button
android:id="@+id/status_exit_button"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="@string/exit"
android:layout_weight="0"
android:layout_alignParentLeft="true"
android:layout_gravity="center_vertical"
android:layout_marginRight="8dp" />
</LinearLayout>

View file

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:background="#333333" android:orientation="vertical" android:layout_width="fill_parent">
<ImageView
android:id="@+id/fd_Icon1"
android:layout_width="40dip"
android:layout_height="40dip" >
</ImageView>
<TextView android:text="@+id/filename"
android:id="@+id/filename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textStyle="bold"
android:layout_toRightOf="@+id/fd_Icon1"
android:layout_marginTop="5dip"
android:layout_marginLeft="5dip">
</TextView>
<TextView android:text="@+id/fileitems"
android:id="@+id/fileitems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/fd_Icon1"
android:layout_below="@+id/filename"
android:layout_marginLeft="10dip">
</TextView>
<TextView android:text="@+id/filedate"
android:id="@+id/filedate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/filename"
android:layout_alignParentRight="true"
android:layout_marginLeft="5dip">
</TextView>
</RelativeLayout>

View file

@ -1,47 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="top"
android:layout_weight="1">
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="fill_horizontal|top"
android:layout_marginBottom="16dp"
android:layout_marginTop="0dp"
android:scaleType="fitStart"/>
</LinearLayout>
<TextView
android:id="@+id/title"
style="@android:style/TextAppearance.DeviceDefault.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:text="Lorem ipsum dolor sit amet"
android:textColor="#FFF" />
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="32dp"
android:gravity="center_horizontal"
android:paddingEnd="32dp"
android:paddingStart="32dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tempus elementum sem congue laoreet. Sed pulvinar at purus quis aliquet. Quisque feugiat sed leo nec aliquet. In hac habitasse platea dictumst. Vestibulum enim sapien, gravida et tempus vel, feugiat in turpis. Fusce interdum elit et libero rhoncus dapibus"
android:textColor="#FFF"
android:textSize="14sp"/>
</LinearLayout>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/sunset_orange" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="immersive_mode">Habilitar modo inmersivo (pantalla completa, Android 4.4 o superior)</string>
<string name="lollipop_request_permission_fail_msg">El test de escritura ha fallado dos veces.</string>
<string name="kitkat_write_fail_msg">Debido a las politicas de escritura de Android 4.4, no puedes utilizar este almacenamiento.</string>
<string name="resolution_mod_warn">Usalo con precaucion! Algunos juegos no soportan una resolucion muy baja, en caso de bugs, incrementa la resolucion a 640x480 o superior.
\nResoluciones menores a 320x240 son ignoradas.</string>
<string name="rodir_warning">Por favor ten en cuenta, que las configuraciones y saves seran almacenados en %s</string>
<string name="about_copyright">Flying With Gauss no está afiliada con Valve o alguno de sus partners. Todos los derechos de autor reservados a sus respectivos dueños.</string>
<string name="folder">Configurar carpeta actual</string>
<string name="ok">Ok</string>
<string name="next">Siguiente</string>
<string name="prev">Anterior</string>
<string name="skip">Saltar</string>
<string name="finish">Finalizar</string>
<string name="exit">Salir</string>
<string name="no_permissions">No hay permisos, saliendo…</string>
<string name="text_tab1">Normal</string>
<string name="use_volume">Accion predeterminada</string>
<string name="select_folder">Seleccionar ubicacion de los datos de juego</string>
<string name="create_shortcut_button">Crear acceso directo a mod</string>
<string name="cmd_args_text">Argumentos de consola (solo expertos)</string>
<string name="use_rodir_auto">Usar la carpeta de la aplicacion</string>
<string name="update_button">Verificar actualizaciones al inicio</string>
<string name="resolution_custom">Especifica ancho y altura de la pantalla</string>
<string name="resolution_result">Resolucion:</string>
<string name="about_button">Acerca de</string>
<string name="launch_button">Iniciar Xash3D FWGS!</string>
<string name="text_shortcut">Acceso directo a Xash3D FWGS</string>
<string name="text_shortcut_test">Acceso directo Xash3D FWGS Test</string>
<string name="shortcut_button_save">Guardar acceso directo</string>
<string name="gamedir">Directorio del mod</string>
<string name="pkgname">Nombre del paquete del mod (expertos solamente)</string>
<string name="shortcut_name">Nombre del atajo</string>
<string name="update">Actualizar</string>
<string name="checking_updates">Trabajando…</string>
<string name="write_failed">El test de escritura ha fallado</string>
<string name="lollipop_write_fail_msg">Debido a las politicas de escritura de las versiones mas nuevas de Android, no puedes utilizar este almacenamiento.</string>
<string name="readonly_fs_fail_msg">Al parecer tienes un sistema de archivos de solo-lectura.</string>
<string name="firstrun">Guia de instalacion</string>
<string name="parent_directory">Directorio raiz</string>
<string name="chosen_path">Ubicacion escojida:</string>
<plurals name="item_plurals">
<item quantity="one">No hay carpetas</item>
<item quantity="other">%d carpetas</item>
</plurals>
<string name="default_channel_name">Motor del juego</string>
<string name="default_channel_description">Notificaciones del motor de juego</string>
<string name="cancel">Cancelar</string>
<string name="update_message">%s esta disponible! Descargalo ahora!</string>
<string name="current_dir">Ubicacion actual:</string>
<string name="text_tab2">Avanzado</string>
<string name="no_updates">No se encontraron actualizaciones</string>
<string name="text_res_tittle2">Configuraciones normales</string>
<string name="text_res_tittle3">Configuraciones avanzadas</string>
<string name="ask_about_new_basedir_msg">Mueve los datos del juego a algun lugar, por ejemplo: Android/data/su.xash.engine o a la memoria interna. Al siguiente inicio te preguntara sobre tu carpeta de nuevo.</string>
</resources>

View file

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Annulla</string>
<string name="ok">Ok</string>
<string name="next">Successivo</string>
<string name="prev">Precedente</string>
<string name="skip">Salta</string>
<string name="finish">Fine</string>
<string name="exit">Esci</string>
<string name="text_tab2">Avanzate</string>
<string name="text_res_tittle2">Impostazioni base</string>
<string name="volume">Funzione tasti volume</string>
<string name="use_volume">Default</string>
<string name="text_res_tittle3">Impostazioni avanzate</string>
<string name="no_permissions">Nessun permesso concesso, chiusura in corso…</string>
<string name="text_tab1">Normale</string>
<string name="no_volume">Usa nel gioco</string>
<string name="create_shortcut_button">Crea collegamento per mod</string>
<string name="cmd_args_text">Prompt dei comandi (utenti esperti)</string>
<string name="no_rodir">Posizione dati di gioco</string>
<string name="use_rodir">Scrittura dati separati</string>
<string name="resolution_custom">Specifica altezza e larghezza dello schermo</string>
<string name="resolution_result">Risoluzione:</string>
<string name="use_rodir_auto">Usa la cartella dell\'applicazione</string>
<string name="update_button">Verifica aggiornamento all\'avvio</string>
<string name="resolution">Imposta risoluzione schermo (sperimentale)</string>
<string name="about_button">Informazioni</string>
<string name="launch_button">Avvia Xash3D FWGS!</string>
<string name="text_shortcut">Collegamento Xash3D FWGS</string>
<string name="pkgname">Nome cartella mod (utenti esperti)</string>
<string name="about_copyright">Flying With Gauss non è affiliata a Valve o ad alcun azienda partner. Tutti i diritti riservati ai rispettivi proprietari.</string>
<string name="update_message">E\' disponibile un aggiornamento! Scaricalo subito!</string>
<string name="update">Aggiornamento</string>
<string name="no_updates">Non è stato trovato nessun aggiornamento</string>
<string name="lollipop_write_fail_msg">Per via delle politiche relative all\'archiviazione nelle nuove versioni di Android, non potrai usare questa cartella.</string>
<string name="kitkat_write_fail_msg">Per via delle politiche relative all\'archiviazione in Android 4.4, non potrai usare questa cartella.</string>
<string name="firstrun">Consulta la guida all\'installazione</string>
<string name="folder">Imposta la cartella corrente</string>
<string name="chosen_path">Percorso scelto:</string>
<string name="current_dir">Cartella corrente:</string>
<plurals name="item_plurals">
<item quantity="one">Nessuna cartella</item>
<item quantity="other">%d cartelle</item>
</plurals>
<string name="default_channel_name">Motore di gioco</string>
<string name="default_channel_description">Notifica motore di gioco</string>
<string name="checking_updates">Attendi prego…</string>
<string name="write_failed">Il test di scrittura non è riuscito</string>
<string name="lollipop_request_permission_fail_msg">Test scrittura fallito per due volte.</string>
<string name="readonly_fs_fail_msg">Sembra che hai un filesystem di sola lettura.</string>
<string name="convert_to_rodir">Converti a RoDir</string>
<string name="text_res_path">Posizione file di gioco</string>
<string name="select_folder">Seleziona la posizione dei dati di gioco</string>
<string name="resolution_mod_warn">Usalo con cautela! Alcuni giochi non supportano risoluzioni troppo basse, in caso di problrmi o artefatti grafici aumentare la risoluzione a 640x480 o superiore.
\nUna risoluzione inferiore a 320x240 sarà ignorata.</string>
<string name="text_res_rw_path">Cartella file scrivibili (configurazione, salvataggi, etc.)</string>
<string name="text_shortcut_test">Collegamento Xash3D FWGS Test</string>
<string name="shortcut_button_save">Salva collegamento</string>
<string name="immersive_mode">Abilita la modalità a schermo pieno (Android 4.4 o superiore)</string>
<string name="gamedir">Cartella mod</string>
<string name="shortcut_name">Nome collegamento</string>
<string name="rodir_warning">Attenzione, le tue impostazioni e i tuoi salvataggi saranno salvate in %s</string>
<string name="ask_about_new_basedir_msg">Sposta i file di gioco in una cartella, per esempio in Android/data/su.xash.engine o nella memoria interna. Al prossimo avvio verrà di nuovo richiesto la posizione della cartella.</string>
<string name="resize_off">La tastiera ridimensiona lo schermo</string>
<string name="resize_on">La tastiera ridimensiona lo schermo</string>
<string name="resolution_scale">Ridimensiona lo schermo mantenendo le proporzioni</string>
</resources>

View file

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="text_res_tittle3">config. avançadas</string>
<string name="text_res_rw_path">caminho para armarzenar dados salvos (config, jogos salvos, etc)</string>
<string name="immersive_mode">Ligar o modo imersivo (tela cheia, android 4.4+)</string>
<string name="resolution_mod_warn">Use com cuidado! Alguns jogos não suportam uma resolução muito baixa! Resolução inferior a 320x240 é ignorada.</string>
<string name="volume">modo usando botões de volume</string>
<string name="use_volume">ação padrão</string>
<string name="no_volume">usar no jogo</string>
<string name="select_folder">selecionar localização de arquivos do jogo</string>
<string name="create_shortcut_button">criar um icone para iniciar o mod</string>
<string name="cmd_args_text">linha de comandos (somente espertos)</string>
<string name="no_rodir">classica colocação de dados do jogo</string>
<string name="use_rodir">armazene dados salvos separadamente</string>
<string name="use_rodir_auto">usar pasta de aplicativo</string>
<string name="resize_off">teclado não irá diminuir a tela</string>
<string name="resize_on">teclado irá diminuir a tela</string>
<string name="update_button">checar atualizações ao iniciar</string>
<string name="resolution">mudar a resolução da tela (em testes)</string>
<string name="resolution_scale">escala de tela mantendo a proporção</string>
<string name="resolution_custom">especifique o tamanho da tela</string>
<string name="resolution_result">resolução:</string>
<string name="about_button">Sobre</string>
<string name="ok">Ok</string>
<string name="next">Proximo</string>
<string name="skip">pular</string>
<string name="finish">terminar</string>
<string name="exit">sair</string>
<string name="text_res_path">caminho para os recursos do jogo</string>
<string name="no_permissions">Sem Permissões, fechando…</string>
<string name="text_tab1">normal</string>
<string name="text_tab2">avançado</string>
<string name="launch_button">Iniciar Jogo!</string>
<string name="text_shortcut">icone xash3d</string>
<string name="text_shortcut_test">icone de teste para xash3d</string>
<string name="pkgname">nome do pacote do mod (apenas espertos)</string>
<string name="shortcut_button_save">salvar icone</string>
<string name="gamedir">diretório do mod</string>
<string name="shortcut_name">nome do icone</string>
<string name="update_message">#s esta pronta! baixe agora!</string>
<string name="update">Atualizar</string>
<string name="no_updates">Nenhuma Atualização foi encontrada</string>
<string name="checking_updates">Trabalhando…</string>
<string name="write_failed">teste escrito falhou</string>
<string name="ask_about_new_basedir_msg">mova a pasta do jogo para algum lugar, exemplo Android/data/su.xash.engine ou memoria interna. quando der play vai pedir sobre a pasta novamente.</string>
<string name="lollipop_request_permission_fail_msg">teste escrito falhou duas vezes.</string>
<string name="kitkat_write_fail_msg">Devido à política de redação do Android 4.4, você não pode usar esse armazenamento.</string>
<string name="readonly_fs_fail_msg">Parece que você tem um sistema de arquivos que usa somente leitura.</string>
<string name="convert_to_rodir">Converta para RoDir</string>
<string name="rodir_warning">Observe que suas configurações e salvamentos do jogo serão armazenados em %s</string>
<string name="firstrun">Abrir guia de instalação</string>
<string name="folder">Escolher a pasta corrente</string>
<string name="chosen_path">Caminho Escolhido:</string>
<string name="current_dir">Diretório Corrente:</string>
<plurals name="item_plurals">
<item quantity="one">%d pasta</item>
<item quantity="other">%d pastas</item>
</plurals>
<string name="default_channel_name">Engine do jogo</string>
<string name="default_channel_description">Notificações da engine do jogo</string>
<string name="about_copyright">Flying With Gauss não é afiliado à Valve ou a qualquer um de seus parceiros. Todos os direitos autorais reservados aos seus respectivos proprietários.</string>
<string name="cancel">Cancelar</string>
<string name="prev">anterior</string>
<string name="lollipop_write_fail_msg">Devido à política de redação das versões mais recentes do Android, você não pode usar esse armazenamento.</string>
<string name="text_res_tittle2">config. normais</string>
<string name="parent_directory">Diretório Parental</string>
</resources>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="page_title0">Добро пожаловать!</string>
<string name="page_content0">Добро пожаловать в Xash3D FWGS! Перед тем как продолжить, мы предлагаем вам прочитать инструкцию по установке. Нажмите <b>Далее</b> чтобы продолжить или <b>Пропустить</b>, если вы уже установили игровые файлы.</string>
<string name="page_title1">Купите Half-Life в Steam</string>
<string name="page_content1">Чтобы играть, вам необходим купленный Half-Life на вашем аккаунте Steam. Установите Steam на ваш ПК. Купите игру, если у вас её нет. Нажмите <b>Установить</b>. Подождите пока установка закончится.</string>
<string name="page_title2">Откройте папку с файлами игры</string>
<string name="page_content2">Откройте свойства игры в Steam и перейдите во вкладку <b>Локальные файлы</b>. Нажмите кнопку <b>Просмотреть локальные файлы</b>. Появится окно файлового менеджера</string>
<string name="page_title3">Скопируйте игровые файлы на устройство</string>
<string name="page_content3">Подключите ваше устройство к ПК. Создайте папку <b>xash</b> во внутренней памяти и скопируйте в неё папку <b>valve</b> из файлов игры. Если у вас недостаточно памяти, вы можете использовать SD карту. Тогда вам надо скопировать в <b>Android/data/in.celest.xash3d.hl/files</b> на SD карте(создайте, если таких папок нет)</string>
<string name="page_title4">Настройка пути к файлам</string>
<string name="page_content4">После успешного копирования игровых файлов на устройство, вам надо настроить путь к папке, где расположена папка <b>valve</b>. <font color="yellow">Обратите внимание, что вы <b>НЕ ДОЛЖНЫ</b> указывать путь в саму папку <b>valve</b></font>. Теперь закройте этот диалог и выберите путь нажав на кнопку <b>Выбрать путь к игровым файлам</b>. Удачи и хорошо повеселиться.</string>
</resources>

View file

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Generic -->
<string name="cancel">Отмена</string>
<string name="ok">ОК</string>
<string name="next">Далее</string>
<string name="prev">Назад</string>
<string name="skip">Пропустить</string>
<string name="finish">Конец</string>
<string name="exit">Выход</string>
<string name="text_res_path">Путь к игровым ресурсам</string>
<string name="no_permissions">Нет разрешений, закрываюсь…</string>
<!-- Generic -->
<!-- Launcher(tabs) -->
<string name="text_tab1">Стандартный</string>
<string name="text_tab2">Продвинутый</string>
<!-- Launcher(tabs) -->
<!-- Launcher(normal) -->
<string name="text_res_tittle2">Стандартные настройки</string>
<string name="volume">Действие кнопок громкости</string>
<string name="use_volume">Регулировка громкости</string>
<string name="no_volume">Использовать в игре</string>
<string name="select_folder">Выбрать путь игровых файлов</string>
<string name="create_shortcut_button">Создать ярлык</string>
<!-- Launcher(normal) -->
<!-- Launcher(advanced) -->
<string name="text_res_tittle3">Продвинутые настройки</string>
<string name="cmd_args_text">Аргументы командной строки(только для экспертов)</string>
<string name="no_rodir">Классическое расположение игровых файлов</string>
<string name="use_rodir">Хранить записываемые данные отдельно</string>
<string name="text_res_rw_path">Путь для записываемых данных(конфиги, игровые сохранения и т.д.)</string>
<string name="use_rodir_auto">Использовать каталог приложения</string>
<string name="resize_off">Клавиатура не меняет размер экрана игры</string>
<string name="resize_on">Клавиатура меняет размер экрана игры</string>
<string name="update_button">Проверять обновления при запуске</string>
<!--<string name="update_to_beta">Обновлять до нестабильной версии, если доступно</string>-->
<string name="immersive_mode">Включить Immersive Mode(Полноэкранный режим, для Android 4.4 и старше)</string>
<string name="resolution">Установка разрешения игры</string>
<string name="resolution_scale">Масштабировать сохраняя соотношение сторон</string>
<string name="resolution_custom">Указать точный размер экрана</string>
<string name="resolution_result">Разрешение: </string>
<string name="resolution_mod_warn">Используйте с осторожностью! Некоторые игры не поддерживают слишком низкое разрешение. В случае ошибок, увеличьте разрешение до 640x480 или больше.\nРазрешения ниже 320x280 игнорируются.</string>
<!-- Launcher(advanced) -->
<!-- Launcher(buttons) -->
<string name="about_button">О Xash3D FWGS</string>
<string name="launch_button">Запустить Xash3D FWGS!</string>
<!-- Launcher(buttons) -->
<!-- Shorcut -->
<string name="text_shortcut">Ярлык Xash3D FWGS</string>
<string name="text_shortcut_test">Ярлык Xash3D FWGS Test</string>
<string name="shortcut_button_save">Сохранить ярлык</string>
<string name="gamedir">Каталог мода</string>
<string name="pkgname">Пакет мода (только для экспертов)</string>
<string name="shortcut_name">Название ярлыка</string>
<!-- Shorcut -->
<!-- About -->
<string name="about_copyright">Flying With Gauss не связан с Valve или с любыми из их партнеров. Все авторские права принадлежат их соответственным обладателям..</string>
<!-- About -->
<!-- Update -->
<string name="update_message">%s доступен! Скачай его сейчас!</string>
<string name="update">Обновить</string>
<string name="no_updates">Обновления не найдены</string>
<string name="checking_updates">Работаю…</string>
<!-- Update -->
<!-- Write check -->
<string name="write_failed">Тест чтения не удался</string>
<string name="ask_about_new_basedir_msg">Переместите файлы игры куда-нибудь ещё. Например, в Android/data/su.xash.engine/ или во внутренюю память. На следующий запуск я снова спрошу местоположение файлов игры.</string>
<string name="lollipop_request_permission_fail_msg">Тест записи не удался дважды. </string>
<string name="lollipop_write_fail_msg">Из-за политик записи в новых версиях Android, полноценно воспользоваться внешней памятью невозможно. </string>
<string name="kitkat_write_fail_msg">Из-за политик записи Android 4.4, вы не можете воспользоваться внешней памятью. </string>
<string name="readonly_fs_fail_msg">Похоже, ваша файловая система в режиме только для чтения. </string>
<string name="convert_to_rodir">Конвертировать в RoDir</string>
<string name="rodir_warning">Обратите внимание, что теперь ваши настройки будут сохранены в %s</string>
<!-- /Write check -->
<!-- Tutorial -->
<string name="firstrun">Открыть инструкцию по установке</string>
<!-- /Tutorial -->
<!-- FPicker -->
<string name="folder">Выбрать текущий каталог</string>
<string name="parent_directory">Родительский каталог</string>
<string name="chosen_path">Выбранный путь:</string>
<string name="current_dir">Текущий каталог:</string>
<plurals name="item_plurals">
<item quantity="zero">Нет папок</item>
<item quantity="one">%d папка</item>
<item quantity="few">%d папки</item>
<item quantity="other">%d папок</item>
</plurals>
<!-- /FPicker -->
<string name="default_channel_name">Игровой движок</string>
<string name="default_channel_description">Уведомления игрового движка</string>
</resources>

View file

@ -1,68 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ok">Tamam</string>
<string name="next">İleri</string>
<string name="prev">Önceki</string>
<string name="skip">Geç</string>
<string name="finish">Bitti</string>
<string name="exit">Çıkış</string>
<string name="text_res_path">Oyun dosyalarına giden yol</string>
<string name="text_tab1">Normal</string>
<string name="text_tab2">Gelişmiş</string>
<string name="text_res_tittle2">Normal Ayarlar</string>
<string name="volume">Ses Butonları modu</string>
<string name="use_volume">Varsayılan Aksiyon</string>
<string name="no_volume">Oyunda kullan</string>
<string name="select_folder">Oyun dizinini seç</string>
<string name="create_shortcut_button">Mod kısayolu oluştur</string>
<string name="cmd_args_text">Komut Argümanları (sadece uzmanlar için)</string>
<string name="no_rodir">Klasik oyun veri yerleşimi</string>
<string name="text_res_rw_path">Yazılabilir verileri saklama yolu (yapılandırmalar,kayıtlar vb.)</string>
<string name="use_rodir_auto">Uygulama klasörünü kullan</string>
<string name="resize_off">Klavye ekranı yeniden boyutlandırmasın</string>
<string name="resize_on">Klavye ekranı yeniden boyutlandırsın</string>
<string name="update_button">Başlatınca güncellemeleri denetle</string>
<string name="resolution">Ekran çözünürlüğünü düzelt (deneysel)</string>
<string name="resolution_scale">Ekran tutma en boy oranını ölçeklendirme</string>
<string name="resolution_custom">Ekran genişliğini ve yüksekliğini belirtme</string>
<string name="resolution_result">Çözünürlük:</string>
<string name="about_button">Hakkında</string>
<string name="launch_button">Xash3D FWGS\'yi Başlat!</string>
<string name="text_shortcut">Xash3D FWGS kısayolu</string>
<string name="text_shortcut_test">Xash3D FWGS Deneme kısayolu</string>
<string name="shortcut_button_save">Kısayolu kaydet</string>
<string name="gamedir">Mod dizini</string>
<string name="pkgname">Mod paket adı (yalnızca uzmanlar)</string>
<string name="shortcut_name">Kısayol Adı</string>
<string name="update_message">% s kullanılabilir! Şimdi indir!</string>
<string name="current_dir">Geçerli dizin:</string>
<plurals name="item_plurals">
<item quantity="one">Klasör yok</item>
<item quantity="other">%d Klasörler</item>
</plurals>
<string name="default_channel_name">Oyun motoru</string>
<string name="default_channel_description">Oyun motoru bildirimleri</string>
<string name="use_rodir">Yazılabilir verileri ayrı saklayın</string>
<string name="cancel">İptal</string>
<string name="no_permissions">Yetki yok, kapanıyor…</string>
<string name="text_res_tittle3">Gelişmiş Seçenekler</string>
<string name="immersive_mode">Sürükleyici Modu Etkinleştir (tam ekran, Android 4.4 veya üstü)</string>
<string name="resolution_mod_warn">Dikkatle kullanın! Bazı oyunlar çok düşük çözünürlüğü desteklemez, hataların çözünürlüğü 640x480 veya daha yüksek bir değere çıkarması durumunda.
\n320x240\'tan düşük çözünürlük yoksayılır.</string>
<string name="about_copyright">Flying With Gauss (FWGS) Valve veya ortaklarından hiçbiriyle bağlantılı değildir. Tüm telif hakları ilgili sahiplerine aittir.</string>
<string name="update">Güncelle</string>
<string name="no_updates">Güncelleme bulunamadı</string>
<string name="checking_updates">Çalışıyor…</string>
<string name="write_failed">Yazma testi başarısız oldu</string>
<string name="ask_about_new_basedir_msg">Oyun dosyalarınızı Android / data / su.xash.engine veya dahili bellek gibi başka bir yere taşıyın.Bir sonraki çalıştırmada size klasör hakkında tekrar sorulacak.</string>
<string name="lollipop_request_permission_fail_msg">Yazma testi iki kez başarısız oldu.</string>
<string name="lollipop_write_fail_msg">Daha yeni Android sürümlerinin politikaları yazıldığından, bu depolama alanını kullanamazsınız.</string>
<string name="kitkat_write_fail_msg">Android 4.4\'ün yazma politikaları nedeniyle bu depolama alanını kullanamazsınız.</string>
<string name="readonly_fs_fail_msg">Salt okunur dosya sisteminiz var gibi görünüyor.</string>
<string name="convert_to_rodir">RoDir\'e Dönüştür</string>
<string name="rodir_warning">Oyun ayarlarınızın ve kaydetmelerinizin% s içinde saklanacağını lütfen unutmayın</string>
<string name="firstrun">Kurulum kılavuzunu aç</string>
<string name="folder">Geçerli klasörü ayarla</string>
<string name="parent_directory">Ana Dizin</string>
<string name="chosen_path">Seçilmiş yol:</string>
</resources>

View file

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="use_rodir">Зберігати данні для запису окремо</string>
<string name="about_copyright">Flying With Gauss не повязані з Valve або жодними з їх партнерів. Всі права належать своїм відповідним власникам.</string>
<string name="launch_button">Запустити Xash3D FWGS!</string>
<string name="text_shortcut">Ярлик Xash3D FWGS</string>
<string name="ok">Ок</string>
<string name="next">Далі</string>
<string name="prev">Назад</string>
<string name="skip">Пропустити</string>
<string name="finish">Закінчити</string>
<string name="exit">Вихід</string>
<string name="no_permissions">Немає дозволів, закриття…</string>
<string name="text_res_tittle2">Звичайні налаштування</string>
<string name="volume">Режим клавіш гучності</string>
<string name="use_volume">Дія за замовчуванням</string>
<string name="text_tab2">Розширені</string>
<string name="shortcut_button_save">Зберегти ярлик</string>
<string name="shortcut_name">Назва ярлика</string>
<string name="lollipop_request_permission_fail_msg">Тест на запис провалено двічі.</string>
<string name="convert_to_rodir">Конвертувати в RoDir</string>
<string name="chosen_path">Обраний шлях:</string>
<string name="default_channel_name">Ігровий рушій</string>
<string name="kitkat_write_fail_msg">Зігдно політики запису Android 4.4, ви не можете використовувати це сховище.</string>
<string name="text_shortcut_test">Ярлик Xash3D FWGS Test</string>
<string name="resolution_result">Розширення:</string>
<string name="gamedir">Директорія модифікації</string>
<string name="pkgname">Назва пакету модифікації (тільки для досвідчених користувачів)</string>
<string name="update_message">%s доступний! Завантажте зараз!</string>
<string name="update">Оновити</string>
<string name="no_updates">Оновлень не знайдено</string>
<string name="checking_updates">Працюю…</string>
<string name="write_failed">Тест на запис провалено</string>
<string name="lollipop_write_fail_msg">Згідно політики запису нових версій Android, ви не можете використовувати це сховище.</string>
<string name="no_rodir">Класичне розміщення ігрових даних</string>
<string name="readonly_fs_fail_msg">Здається ваша файлова система тільки для читання.</string>
<string name="resize_on">Клавіатура змінює розмір екрану</string>
<string name="resize_off">Клавіатура не змінює розмір екрану</string>
<string name="update_button">Перевіряти наявність оновлень при запуску</string>
<string name="rodir_warning">Зверніть увагу, що ваші налаштування і збереження гри будуть зберігатися в %s</string>
<string name="firstrun">Відкрити інструкцію з встановлення</string>
<string name="immersive_mode">Ввімкнути Режим Занурення (повноекранний, Android 4.4 або вище)</string>
<string name="folder">Обрати поточну директорію</string>
<string name="parent_directory">Попередня директорія</string>
<string name="resolution">Повноекранне розширення (експериментально)</string>
<string name="resolution_custom">Задати ширину та висоту екрану</string>
<string name="current_dir">Поточна директорія:</string>
<string name="select_folder">Виберіть місце розташування ігрових даних</string>
<string name="about_button">Про програму</string>
<string name="cancel">Скасувати</string>
<string name="text_res_path">Шлях до ігрових ресурсів</string>
<string name="no_volume">Використовувати в грі</string>
<string name="create_shortcut_button">Створення ярлика модифікації</string>
<string name="text_res_tittle3">Розширені налаштування</string>
<string name="cmd_args_text">Аргументи командного рядка (лише для досвідчених користувачів)</string>
<string name="text_tab1">Звичайні</string>
<string name="text_res_rw_path">Шлях зберігання даних для запису (конфіги, збереження гри тощо)</string>
<string name="default_channel_description">Сповіщення ігрового рушія</string>
<string name="use_rodir_auto">Використовувати папку додатку</string>
<string name="resolution_scale">Масштабувати екран зі збереженням співвідношення сторін</string>
<string name="ask_about_new_basedir_msg">Перемістіть свої файли в інше місце, наприклад в Android/data/su.xash.engine або внутрішню память. При наступному запуску вас запитають про директорію знову.</string>
<plurals name="item_plurals">
<item quantity="one">Немає директорій</item>
<item quantity="few">%d директорія</item>
<item quantity="many">%d директорій</item>
<item quantity="other">%d директорій</item>
</plurals>
<string name="resolution_mod_warn">Використвуйте обачно! Деякі ігри не підтримують занадто низьке розширення, при наявності багів варто збільшити розширення до 640x480 або вищого.
\nРозширення нижчі ніж 320x240 ігноруються.</string>
</resources>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="sunset_orange">#f74843</color>
</resources>

View file

@ -1,5 +0,0 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="git_revisions">No git version information</string>
</resources>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="page_title0">Welcome!</string>
<string name="page_content0">Welcome to Xash3D FWGS! Before continue, we recommend you to read our installation guide. Press <b>Next</b> to continue. Press <b>Skip</b> to close this dialog, if you already have installed the game data files.</string>
<string name="page_title1">Purchase Half-Life in Steam</string>
<string name="page_content1">To play, you need to have Half-Life on your Steam account. Install Steam client on your PC. Purchase the game, if you still not. Press <b>Install</b> button. Wait until download finishes.</string>
<string name="page_title2">Get game files directory</string>
<string name="page_content2">Open game properties in Steam, move to <b>Local Files</b> tab and press <b>Browse local files...</b> button. File manager window will appear.</string>
<string name="page_title3">Copy game files to device</string>
<string name="page_content3">Connect your device to PC. Create <b>xash</b> folder in device\'s internal storage and copy <b>valve</b> folder from game local files into <b>xash</b> on your device. If you have not enough internal storage, you may use external SD. Then you need to use <b>Android/data/in.celest.xash3d.hl/files</b> folder on external SD(create these folders, if they does not exist).</string>
<string name="page_title4">Setting game path</string>
<string name="page_content4">After successfully copying game to device, you need to tell Xash3D FWGS where <b>valve</b> is located.<font color="yellow"> Note that you <b>MUST NOT</b> select <b>valve</b> folder itself.</font> Now close this dialog and select game folder by pressing <b>Select game data location</b> button. Good luck, have fun!</string>
</resources>

View file

@ -1,121 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Xash3D FWGS</string>
<string name="launcher_name" translatable="false">Xash3D FWGS</string>
<string name="launcher_name_test" translatable="false">Xash3D FWGS Test</string>
<string name="version_string" translatable="false">v0.20.1</string>
<!-- Generic -->
<string name="cancel">Cancel</string>
<string name="ok">Ok</string>
<string name="next">Next</string>
<string name="prev">Previous</string>
<string name="skip">Skip</string>
<string name="finish">Finish</string>
<string name="exit">Exit</string>
<string name="text_res_path">Path to game resources</string>
<string name="no_permissions">No permissions, closing…</string>
<!-- Generic -->
<!-- Launcher(tabs) -->
<string name="text_tab1">Normal</string>
<string name="text_tab2">Advanced</string>
<!-- Launcher(tabs) -->
<!-- Launcher(normal) -->
<string name="text_res_tittle2">Normal settings</string>
<string name="volume">Volume buttons mode</string>
<string name="use_volume">Default action</string>
<string name="no_volume">Use in game</string>
<string name="select_folder">Select game data location</string>
<string name="create_shortcut_button">Create mod shortcut</string>
<!-- Launcher(normal) -->
<!-- Launcher(advanced) -->
<string name="text_res_tittle3">Advanced settings</string>
<string name="cmd_args_text">Command line arguments(experts only)</string>
<string name="no_rodir">Classic game data placement</string>
<string name="use_rodir">Store writable data separately</string>
<string name="text_res_rw_path">Path to store writable data(configs, game saves, etc)</string>
<string name="use_rodir_auto">Use application folder</string>
<string name="pixel_format" translatable="false">Pixel format:</string>
<string name="resize_off">Keyboard does not resize screen</string>
<string name="resize_on">Keyboard resizes screen</string>
<string name="update_button">Check updates on start</string>
<!--<string name="update_to_beta">Update to unstable version if available</string>-->
<string name="immersive_mode">Enable Immersive Mode(fullscreen, Android 4.4 or higher)</string>
<string name="resolution">Fixed screen resolution (experimental)</string>
<string name="resolution_scale">Scale screen keeping aspect ratio</string>
<string name="resolution_custom">Specify screen width and height</string>
<string name="resolution_result">Resolution: </string>
<string name="resolution_mod_warn">Use with caution! Some games does not support too low resolution, in case of bugs increase resolution to 640x480 or higher.\nResolution lower than 320x240 is ignored.</string>
<!-- Launcher(advanced) -->
<!-- Launcher(buttons) -->
<string name="about_button">About</string>
<string name="launch_button">Launch Xash3D FWGS!</string>
<!-- Launcher(buttons) -->
<!-- Shorcut -->
<string name="text_shortcut">Xash3D FWGS shortcut</string>
<string name="text_shortcut_test">Xash3D FWGS Test shortcut</string>
<string name="shortcut_button_save">Save shortcut</string>
<string name="gamedir">Mod directory</string>
<string name="pkgname">Mod package name (experts only)</string>
<string name="shortcut_name">Shortcut name</string>
<!-- Shorcut -->
<!-- About -->
<string name="about_main" translatable="false">Xash3D FWGS</string>
<string name="about_copyright">Flying With Gauss is not affiliated with Valve or any of their partners. All copyrights reserved to their respective owners.</string>
<!-- Seems Android skips any line breaks and tabs here. -->
<string name="about_authors" translatable="false">
Port to Android by Flying With Gauss team: \n
• a1batross\n
• mittorn \n
• nicknekit\n
• nekonomicon.\n
Special thanks to:\n
• Beloko for some touch controls textures\n
• Uncle Mike for Xash3D engine\n
• Valve for Half-Life\n
• msayan for tutorial-view library\n
</string>
<string name="about_links" translatable="false">
<a href="https://vk.com/xashdroid">VK</a>\n
<a href="http://moddb.com/games/xash3d-android">ModDB</a>\n
<a href="http://discord.gg/WF7kdmz">Discord</a>\n
<a href="https://github.com/FWGS">GitHub</a>\n
<a href="http://xash.su/pp/privacy-policy-xash3d.html">Privacy Policy</a>
</string>
<!-- About -->
<!-- Update -->
<string name="update_message">%s is available! Download it now!</string>
<string name="update">Update</string>
<string name="no_updates">No updates was found</string>
<string name="checking_updates">Working…</string>
<!-- Update -->
<!-- Write check -->
<string name="write_failed">Write test has failed</string>
<string name="ask_about_new_basedir_msg">Move your game files somewhere else, for example Android/data/su.xash.engine or internal memory. At next run I will ask you about folder again.</string>
<!-- These strings must be concat with a "ask_about_new_basedir" string -->
<string name="lollipop_request_permission_fail_msg">Write test has been failed twice. </string>
<string name="lollipop_write_fail_msg">Due to writing politics of newer Android versions, you can\'t use this storage. </string>
<string name="kitkat_write_fail_msg">Due to writing politics of Android 4.4, you can\'t use this storage. </string>
<string name="readonly_fs_fail_msg">Seems you have read-only filesystem. </string>
<string name="convert_to_rodir">Convert to RoDir</string>
<string name="rodir_warning">Please note, that your game settings and saves will be stored in %s</string>
<!-- /Write check -->
<!-- Tutorial -->
<string name="firstrun">Open installation guide</string>
<!-- /Tutorial -->
<!-- FPicker -->
<string name="folder">Set current folder</string>
<string name="parent_directory">Parent directory</string>
<string name="chosen_path">Chosen path:</string>
<string name="current_dir">Current directory:</string>
<plurals name="item_plurals">
<item quantity="zero">No folders</item>
<item quantity="one">%d folder</item>
<item quantity="other">%d folders</item>
</plurals>
<!-- /FPicker -->
<!-- Notifications -->
<string name="default_channel_name">Game engine</string>
<string name="default_channel_description">Game engine notifications</string>
<!-- /Notifications -->
</resources>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="red_small_text" parent="@android:style/TextAppearance.Small">
<item name="android:textColor">#FF0000</item>
</style>
</resources>

View file

@ -1,259 +0,0 @@
package su.xash.engine;
//Created by Solexid
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Bundle;
import android.os.Build;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Button;
import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import su.xash.fwgslib.FWGSLib;
import su.xash.engine.R;
public class FPicker extends Activity {
private File currentDir;
private FileArrayAdapter adapter;
static ListView delta;
public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
static private Button mSelectBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ( sdk >= 21 )
super.setTheme( 0x01030224 );
else super.setTheme( 0x01030005 );
setContentView( R.layout.activity_fpicker );
String path = Environment.getExternalStorageDirectory().toString();
currentDir = new File( path );
mSelectBtn = ((Button)findViewById( R.id.button_fpicker_select ));
mSelectBtn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
onFileClick(v);
}
});
FWGSLib.changeButtonsStyle((ViewGroup)mSelectBtn.getParent());
fill(currentDir);
}
private void fill(File folder)
{
mSelectBtn.setEnabled( false );
new Fill(folder).execute();
}
private class Fill extends AsyncTask<Void, Void, List<Item>>
{
File folder;
public Fill(File f)
{
folder = f;
}
protected List<Item> doInBackground(Void... voids)
{
File[] dirs = folder.listFiles();
List<Item> dir = new ArrayList<Item>();
while( dirs == null )
{
String parent = folder.getParent();
folder = new File( parent != null ? parent : Environment.getExternalStorageDirectory().toString() );
dirs = folder.listFiles();
}
for( File ff: dirs )
{
Date lastModDate = new Date(ff.lastModified());
DateFormat formater = DateFormat.getDateTimeInstance();
String date_modify = formater.format(lastModDate);
if(ff.isDirectory())
{
boolean isXashDir = false;
File[] fbuf = ff.listFiles();
int buf = 0;
if( fbuf != null && fbuf.length < 20 )
{
buf = fbuf.length;
for (File valves: fbuf)
{
if (valves.isDirectory() && valves.getName().contains("valve"))
isXashDir=true;
}
}
String num_item = getResources().getQuantityString(R.plurals.item_plurals, buf, buf);
dir.add(new Item(ff.getName(), num_item, date_modify, ff.getAbsolutePath(), isXashDir ? R.drawable.ic_launcher : R.drawable.folder ));
}
}
Collections.sort(dir);
if(folder.getPath().length() > 1)
dir.add(0, new Item( "..", getString(R.string.parent_directory), "", folder.getParent(), R.drawable.folder));
return dir;
}
protected void onPostExecute(List<Item> dir)
{
setTitle(getString(R.string.current_dir) + " " +folder.getName());
adapter = new FileArrayAdapter(FPicker.this,R.layout.row,dir);
delta = (ListView)findViewById(R.id.FileView);
delta.setAdapter(adapter);
delta.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent , View v, int position, long id)
{
Item o = adapter.getItem(position);
currentDir = new File(o.getPath());
fill(currentDir);
}
});
FPicker.mSelectBtn.setEnabled( true );
}
}
public void onFileClick(View v)
{
Toast.makeText(this, getString(R.string.chosen_path) + " " + currentDir, Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("GetPath",currentDir.toString());
setResult(RESULT_OK, intent);
finish();
}
}
class FileArrayAdapter extends ArrayAdapter<Item>
{
private Context c;
private int id;
private List<Item>items;
public FileArrayAdapter(Context context, int textViewResourceId, List<Item> objects)
{
super(context, textViewResourceId, objects);
c = context;
id = textViewResourceId;
items = objects;
}
public Item getItem(int i)
{
return items.get(i);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null)
{
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, null);
}
final Item finstance = items.get(position);
if (finstance != null)
{
TextView filename = (TextView) v.findViewById(R.id.filename);
TextView fileitems = (TextView) v.findViewById(R.id.fileitems);
TextView filedate = (TextView) v.findViewById(R.id.filedate);
ImageView imageicon = (ImageView) v.findViewById(R.id.fd_Icon1);
Drawable image = c.getResources().getDrawable(finstance.getImage());
imageicon.setImageDrawable(image);
if(filename!=null)
filename.setText(finstance.getName());
if(fileitems!=null)
fileitems.setText(finstance.getData());
if(filedate!=null)
filedate.setText(finstance.getDate());
}
return v;
}
}
class Item implements Comparable<Item>
{
private String name;
private String data;
private String date;
private String path;
private int image;
public Item(String n,String d, String dt, String p, int img)
{
name = n;
data = d;
date = dt;
path = p;
image = img;
}
public String getName()
{
return name;
}
public String getData()
{
return data;
}
public String getDate()
{
return date;
}
public String getPath()
{
return path;
}
public int getImage()
{
return image;
}
public int compareTo(Item o)
{
if(this.name != null)
return this.name.toLowerCase().compareTo(o.getName().toLowerCase());
else
throw new IllegalArgumentException();
}
}

View file

@ -1,52 +0,0 @@
package su.xash.engine;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.content.SharedPreferences;
public class InstallReceiver extends BroadcastReceiver {
private static final String TAG = "XASH3D";
@Override
public void onReceive(Context context, Intent arg1) {
String pkgname = arg1.getData().getEncodedSchemeSpecificPart();
Log.d( TAG, "Install received, package " + pkgname );
if( context.getPackageName().equals(pkgname) )
extractPAK(context, true);
}
public static SharedPreferences mPref = null;
private static final int PAK_VERSION = 7;
public static synchronized void extractPAK(Context context, Boolean force) {
InputStream is = null;
FileOutputStream os = null;
try {
if( mPref == null )
mPref = context.getSharedPreferences("engine", 0);
synchronized( mPref )
{
if( mPref.getInt( "pakversion", 0 ) == PAK_VERSION && !force )
return;
String path = context.getFilesDir().getPath()+"/extras.pak";
is = context.getAssets().open("extras.pak");
os = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.close();
is.close();
SharedPreferences.Editor editor = mPref.edit();
editor.putInt( "pakversion", PAK_VERSION );
editor.commit();
}
} catch( Exception e )
{
Log.e( TAG, "Failed to extract PAK:" + e.toString() );
}
}
}

View file

@ -1,570 +0,0 @@
package su.xash.engine;
import android.app.*;
import android.content.*;
import android.content.pm.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.net.*;
import android.os.*;
import android.text.*;
import android.text.method.*;
import android.text.style.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import su.xash.engine.*;
import java.io.*;
import java.net.*;
import org.json.*;
import android.preference.*;
import su.xash.fwgslib.*;
import android.Manifest;
public class LauncherActivity extends Activity
{
// public final static String ARGV = "su.xash.engine.MESSAGE";
public final static int sdk = FWGSLib.sdk;
public final static String UPDATE_LINK = "https://api.github.com/repos/FWGS/xash3d-fwgs/releases"; // releases/latest doesn't return prerelease and drafts
static SharedPreferences mPref;
static EditText cmdArgs, resPath, writePath, resScale, resWidth, resHeight;
static ToggleButton useVolume, resizeWorkaround, useRoDir;
static CheckBox checkUpdates, immersiveMode, useRoDirAuto;
static TextView tvResPath, resResult;
static RadioButton radioScale, radioCustom;
static RadioGroup scaleGroup;
static CheckBox resolution;
static Spinner pixelSpinner;
static LinearLayout rodirSettings; // to easy show/hide
static int mEngineWidth, mEngineHeight;
final static int REQUEST_PERMISSIONS = 42;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//super.setTheme( 0x01030005 );
if ( sdk >= 21 )
super.setTheme( 0x01030224 );
else super.setTheme( 0x01030005 );
if( sdk >= 8 && CertCheck.dumbAntiPDALifeCheck( this ) )
{
finish();
return;
}
setContentView(R.layout.activity_launcher);
/* if( sdk > 17 )
{
ImageView icon = (ImageView) findViewById(R.id.launcherIcon);
icon.setImageDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
}
*/
TabHost tabHost = (TabHost) findViewById(R.id.tabhost);
tabHost.setup();
TabHost.TabSpec tabSpec;
tabSpec = tabHost.newTabSpec("tabtag1");
tabSpec.setIndicator(getString(R.string.text_tab1));
tabSpec.setContent(R.id.tab1);
tabHost.addTab(tabSpec);
tabSpec = tabHost.newTabSpec("tabtag2");
tabSpec.setIndicator(getString(R.string.text_tab2));
tabSpec.setContent(R.id.tab2);
tabHost.addTab(tabSpec);
if( sdk < 21 )
{
try
{
tabHost.invalidate();
for(int i = 0; i < tabHost.getTabWidget().getChildCount(); i++)
{
tabHost.getTabWidget().getChildAt(i).getBackground().setAlpha(255);
tabHost.getTabWidget().getChildAt(i).getLayoutParams().height = (int) (40 * getResources().getDisplayMetrics().density);
}
}
catch(Exception e){}
}
mPref = getSharedPreferences("engine", 0);
cmdArgs = (EditText) findViewById(R.id.cmdArgs);
useVolume = (ToggleButton) findViewById( R.id.useVolume );
resPath = (EditText) findViewById( R.id.cmd_path );
checkUpdates = (CheckBox)findViewById( R.id.check_updates );
//updateToBeta = (CheckBox)findViewById( R.id.check_betas );
pixelSpinner = (Spinner) findViewById( R.id.pixelSpinner );
resizeWorkaround = (ToggleButton) findViewById( R.id.enableResizeWorkaround );
tvResPath = (TextView) findViewById( R.id.textView_path );
immersiveMode = (CheckBox) findViewById( R.id.immersive_mode );
resolution = (CheckBox) findViewById(R.id.resolution);
resWidth = (EditText) findViewById(R.id.resolution_width);
resHeight = (EditText) findViewById(R.id.resolution_height);
resScale = (EditText) findViewById(R.id.resolution_scale);
radioCustom = (RadioButton) findViewById(R.id.resolution_custom_r);
radioScale = (RadioButton) findViewById(R.id.resolution_scale_r);
scaleGroup = (RadioGroup) findViewById( R.id.scale_group );
resResult = (TextView) findViewById( R.id.resolution_result );
writePath = (EditText) findViewById( R.id.cmd_path_rw );
useRoDir = (ToggleButton) findViewById( R.id.use_rodir );
useRoDirAuto = (CheckBox) findViewById( R.id.use_rodir_auto );
rodirSettings = (LinearLayout) findViewById( R.id.rodir_settings );
final String[] list = {
"32 bit (RGBA8888)",
"16 bit (RGB565)",
"8 bit (RGB332)"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
pixelSpinner.setAdapter(adapter);
Button selectFolderButton = ( Button ) findViewById( R.id.button_select );
selectFolderButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
selectFolder(v);
}
});
((Button)findViewById( R.id.button_launch )).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
startXash(v);
}
});
((Button)findViewById( R.id.button_shortcut )).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
createShortcut(v);
}
});
((Button)findViewById( R.id.button_about )).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
aboutXash(v);
}
});
useVolume.setChecked(mPref.getBoolean("usevolume",true));
checkUpdates.setChecked(mPref.getBoolean("check_updates",true));
//updateToBeta.setChecked(mPref.getBoolean("check_betas", false));
updatePath(mPref.getString("basedir", FWGSLib.getDefaultXashPath() ) );
cmdArgs.setText(mPref.getString("argv","-dev 3 -log"));
pixelSpinner.setSelection(mPref.getInt("pixelformat", 0));
resizeWorkaround.setChecked(mPref.getBoolean("enableResizeWorkaround", true));
useRoDir.setChecked( mPref.getBoolean("use_rodir", false) );
useRoDirAuto.setChecked( mPref.getBoolean("use_rodir_auto", true) );
writePath.setText(mPref.getString("writedir", FWGSLib.getExternalFilesDir(this)));
resolution.setChecked( mPref.getBoolean("resolution_fixed", false ) );
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
// Swap resolution here, because engine is always(should be always) run in landscape mode
if( FWGSLib.isLandscapeOrientation( this ) )
{
mEngineWidth = metrics.widthPixels;
mEngineHeight = metrics.heightPixels;
}
else
{
mEngineWidth = metrics.heightPixels;
mEngineHeight = metrics.widthPixels;
}
resWidth.setText(String.valueOf(mPref.getInt("resolution_width", mEngineWidth )));
resHeight.setText(String.valueOf(mPref.getInt("resolution_height", mEngineHeight )));
resScale.setText(String.valueOf(mPref.getFloat("resolution_scale", 2.0f)));
resWidth.addTextChangedListener( resWidthTextChangeWatcher );
resHeight.addTextChangedListener( resTextChangeWatcher );
resScale.addTextChangedListener( resTextChangeWatcher );
if( mPref.getBoolean("resolution_custom", false) )
radioCustom.setChecked(true);
else radioScale.setChecked(true);
radioCustom.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged( CompoundButton v, boolean isChecked )
{
updateResolutionResult();
toggleResolutionFields();
}
} );
resolution.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged( CompoundButton v, boolean isChecked )
{
hideResolutionSettings( !isChecked );
}
});
useRoDir.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged( CompoundButton v, boolean isChecked )
{
hideRodirSettings( !isChecked );
}
});
if( sdk >= 19 )
{
immersiveMode.setChecked(mPref.getBoolean("immersive_mode", true));
}
else
{
immersiveMode.setVisibility(View.GONE); // not available
}
resPath.setOnFocusChangeListener( new View.OnFocusChangeListener()
{
@Override
public void onFocusChange(View v, boolean hasFocus)
{
updatePath( resPath.getText().toString() );
// I know what I am doing, so don't ask me about folder!
XashActivity.setFolderAsk( LauncherActivity.this, false );
}
} );
useRoDirAuto.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged( CompoundButton b, boolean isChecked )
{
if( isChecked )
{
writePath.setText( FWGSLib.getExternalFilesDir( LauncherActivity.this ) );
}
writePath.setEnabled( !isChecked );
}
});
// disable autoupdater for Google Play
if( !XashConfig.GP_VERSION && mPref.getBoolean("check_updates", true))
{
new CheckUpdate(getBaseContext(),true, false).execute(UPDATE_LINK);
}
FWGSLib.changeButtonsStyle((ViewGroup)tabHost.getParent());
hideResolutionSettings( !resolution.isChecked() );
hideRodirSettings( !useRoDir.isChecked() );
updateResolutionResult();
toggleResolutionFields();
FWGSLib.cmp.applyPermissions( this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS );
if( !mPref.getBoolean("successfulRun",false) )
showFirstRun();
}
public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults )
{
if( requestCode == REQUEST_PERMISSIONS )
{
if( grantResults[0] == PackageManager.PERMISSION_DENIED )
{
Toast.makeText( this, R.string.no_permissions, Toast.LENGTH_LONG ).show();
finish();
}
else
{
// open again?
}
}
}
@Override
public void onResume()
{
super.onResume();
useRoDir.setChecked( mPref.getBoolean("use_rodir", false) );
useRoDirAuto.setChecked( mPref.getBoolean("use_rodir_auto", true) );
writePath.setText(mPref.getString("writedir", FWGSLib.getExternalFilesDir(this)));
hideRodirSettings( !useRoDir.isChecked() );
}
void updatePath( String text )
{
tvResPath.setText(getString(R.string.text_res_path) + ":\n" + text );
resPath.setText(text);
}
void hideResolutionSettings( boolean hide )
{
scaleGroup.setVisibility( hide ? View.GONE : View.VISIBLE );
}
void hideRodirSettings( boolean hide )
{
rodirSettings.setVisibility( hide ? View.GONE : View.VISIBLE );
}
TextWatcher resWidthTextChangeWatcher = new TextWatcher()
{
@Override
public void afterTextChanged(Editable s){}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
int h = (int)((float)mEngineHeight / mEngineWidth * getCustomEngineWidth());
resHeight.setText(String.valueOf(h));
updateResolutionResult();
}
};
TextWatcher resTextChangeWatcher = new TextWatcher()
{
@Override
public void afterTextChanged(Editable s){}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
updateResolutionResult();
}
};
void updateResolutionResult( )
{
int w, h;
if( radioCustom.isChecked() )
{
w = getCustomEngineWidth();
h = getCustomEngineHeight();
// some fool-proof
if( Math.abs((float)w/(float)h - 4.0/3.0) < 0.001 )
{
w = (int)((float)mEngineWidth / mEngineHeight * h+0.5);
resWidth.setText(String.valueOf(w));
}
}
else
{
final float scale = getResolutionScale();
w = (int)((float)mEngineWidth / scale);
h = (int)((float)mEngineHeight / scale);
}
resResult.setText( getString( R.string.resolution_result ) + w + "x" + h );
}
void toggleResolutionFields()
{
boolean isChecked = radioCustom.isChecked();
resWidth.setEnabled( isChecked );
resHeight.setEnabled( isChecked );
resScale.setEnabled( !isChecked );
}
float getResolutionScale()
{
return FWGSLib.atof( resScale.getText().toString(), 1.0f );
}
int getCustomEngineHeight()
{
return FWGSLib.atoi( resHeight.getText().toString(), mEngineHeight );
}
int getCustomEngineWidth()
{
return FWGSLib.atoi( resWidth.getText().toString(), mEngineWidth );
}
public void startXash(View view)
{
Intent intent = new Intent(this, XashActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SharedPreferences.Editor editor = mPref.edit();
editor.putString("argv", cmdArgs.getText().toString());
editor.putBoolean("usevolume",useVolume.isChecked());
editor.putBoolean("use_rodir", useRoDir.isChecked() );
editor.putBoolean("use_rodir_auto", useRoDirAuto.isChecked() );
editor.putString("writedir", writePath.getText().toString());
editor.putString("basedir", resPath.getText().toString());
editor.putInt("pixelformat", pixelSpinner.getSelectedItemPosition());
editor.putBoolean("enableResizeWorkaround",resizeWorkaround.isChecked());
editor.putBoolean("check_updates", checkUpdates.isChecked());
editor.putBoolean("resolution_fixed", resolution.isChecked());
editor.putBoolean("resolution_custom", radioCustom.isChecked());
editor.putFloat("resolution_scale", getResolutionScale() );
editor.putInt("resolution_width", getCustomEngineWidth() );
editor.putInt("resolution_height", getCustomEngineHeight() );
if( sdk >= 19 )
editor.putBoolean("immersive_mode", immersiveMode.isChecked());
else
editor.putBoolean("immersive_mode", false); // just in case...
editor.commit();
startActivity(intent);
}
public void aboutXash(View view)
{
final Activity a = this;
this.runOnUiThread(new Runnable()
{
public void run()
{
final Dialog dialog = new Dialog(a);
dialog.setContentView(R.layout.about);
dialog.setCancelable(true);
dialog.show();
/* if( sdk > 17 )
{
ImageView icon = (ImageView) dialog.findViewById(R.id.aboutIcon);
icon.setImageDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
}
*/
TextView tView6 = (TextView) dialog.findViewById(R.id.textView6);
tView6.setMovementMethod(LinkMovementMethod.getInstance());
((Button)dialog.findViewById( R.id.button_about_ok )).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.cancel();
}
});
((Button)dialog.findViewById( R.id.show_firstrun )).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.cancel();
Intent intent = new Intent(a, XashTutorialActivity.class);
startActivity(intent);
}
});
FWGSLib.changeButtonsStyle((ViewGroup)dialog.findViewById( R.id.show_firstrun ).getParent());
}
});
}
int m_iFirstRunCounter = 0;
public void showFirstRun()
{
startActivity(new Intent(this, su.xash.engine.XashTutorialActivity.class));
}
public static final int ID_SELECT_FOLDER = 42, ID_SELECT_RW_FOLDER = 43;
public void selectFolder(View view)
{
Intent intent = new Intent(this, su.xash.engine.FPicker.class);
startActivityForResult(intent, ID_SELECT_FOLDER);
resPath.setEnabled(false);
XashActivity.setFolderAsk( this, false );
}
public void selectRwFolder(View view)
{
Intent intent = new Intent(this, su.xash.engine.FPicker.class);
startActivityForResult(intent, ID_SELECT_RW_FOLDER);
writePath.setEnabled(false);
XashActivity.setFolderAsk( this, false );
}
public void onActivityResult(int requestCode, int resultCode, Intent resultData)
{
switch(requestCode)
{
case ID_SELECT_FOLDER:
{
if (resultCode == RESULT_OK)
{
try
{
if( resPath == null )
return;
updatePath(resultData.getStringExtra("GetPath"));
resPath.setEnabled( true );
}
catch(Exception e)
{
e.printStackTrace();
}
}
resPath.setEnabled(true);
break;
}
case ID_SELECT_RW_FOLDER:
{
if (resultCode == RESULT_OK)
{
try
{
if( writePath == null )
return;
writePath.setText(resultData.getStringExtra("GetPath"));
writePath.setEnabled( true );
}
catch(Exception e)
{
e.printStackTrace();
}
}
writePath.setEnabled(true);
break;
}
}
}
public void createShortcut(View view)
{
Intent intent = new Intent(this, ShortcutActivity.class);
intent.putExtra( "basedir", resPath.getText().toString() );
intent.putExtra( "name", "Xash3D FWGS" );
intent.putExtra( "argv", cmdArgs.getText().toString() );
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_launcher, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
/*if (id == R.id.action_settings) {
return true;
}*/
return super.onOptionsItemSelected(item);
}
}

View file

@ -1,131 +0,0 @@
package su.xash.engine;
import android.app.Activity;
import android.view.View;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;
import su.xash.engine.R;
import android.widget.EditText;
import android.widget.Button;
import java.io.File;
import java.io.FilenameFilter;
import android.os.*;
public class ShortcutActivity extends Activity
{
static EditText name, gamedir, pkgname, argv;
String [] env = null;
public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
@Override
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle);
//material dialog
if ( sdk >= 21 )
super.setTheme( 0x01030225 );
else super.setTheme( 0x0103000b );
setContentView(R.layout.activity_shortcut);
Intent intent=getIntent();
name = (EditText)findViewById(R.id.shortcut_name);
pkgname = (EditText)findViewById(R.id.shortcut_pkgname);
gamedir = (EditText)findViewById(R.id.shortcut_gamedir);
argv = (EditText)findViewById(R.id.shortcut_cmdArgs);
((Button)findViewById( R.id.shortcut_buttonOk )).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
saveShortcut(v);
}
});
String argvs = intent.getStringExtra("argv");
if( argvs != null )
argv.setText(argvs);
String pkgnames = intent.getStringExtra("pkgname");
if( pkgnames != null )
pkgname.setText(pkgnames);
String gamedirs = intent.getStringExtra("gamedir");
if( gamedirs != null )
gamedir.setText(gamedirs);
String names = intent.getStringExtra("name");
if( names != null )
name.setText(names);
env = intent.getStringArrayExtra("env");
//name.setText("Name");
}
public void saveShortcut(View view)
{
Intent intent = new Intent();
intent.setAction("su.xash.engine.START");
if(argv.length() != 0) intent.putExtra("argv",argv.getText().toString());
if(pkgname.length() != 0)
{
intent.putExtra("gamelibdir", "/data/data/"+pkgname.getText().toString().replace("!","in.celest.xash3d.")+"/lib/");
intent.putExtra("pakfile", "/data/data/"+pkgname.getText().toString().replace("!","in.celest.xash3d.")+"/files/extras.pak");
}
if(gamedir.length() != 0) intent.putExtra("gamedir",gamedir.getText().toString());
if(env != null)
intent.putExtra("env", env);
Intent wrapIntent = new Intent();
wrapIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
wrapIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name.getText().toString());
Bitmap icon = null;
// Try find icon
int size = (int) getResources().getDimension(android.R.dimen.app_icon_size);
String gamedirstring = getSharedPreferences("engine", 0).getString("basedir","/sdcard/xash/")+"/"+(gamedir.length()!=0?gamedir.getText().toString():"valve");
try
{
icon = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(gamedirstring+"/icon.png"), size, size, false);
}
catch(Exception e)
{
}
if(icon == null) try
{
icon = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(gamedirstring+"/game.ico"), size, size, false);
}
catch(Exception e)
{
}
if(icon == null) try
{
FilenameFilter icoFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if(name.endsWith(".ico") || name.endsWith(".ICO")) {
return true;
}
return false;
}
};
File gamedirfile = new File(gamedirstring);
String files[] = gamedirfile.list(icoFilter);
icon = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(gamedirstring+"/"+files[0]), size, size, false);
}
catch(Exception e)
{
// Android may not support ico loading, so fallback if something going wrong
icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
wrapIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
if(getIntent().getAction() == "android.intent.action.CREATE_SHORTCUT" ) // Called from launcher
{
setResult(RESULT_OK, wrapIntent);
finish();
}
else try
{
wrapIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(wrapIntent);
Toast.makeText(getApplicationContext(), "Shortcut created!", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), "Problem creating shortcut: " + e.toString() +
"\nTry create it manually from laucnher", Toast.LENGTH_LONG).show();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +0,0 @@
package su.xash.engine;
public class XashConfig {
public static final boolean PKG_TEST = false;
public static final boolean CHECK_SIGNATURES = false;
public static final boolean RELEASE = false;
public static final boolean GP_VERSION = false;
}

View file

@ -1,614 +0,0 @@
package su.xash.engine;
import java.lang.*;
import java.lang.reflect.*;
import java.util.*;
import android.app.*;
import android.content.*;
import android.view.*;
import android.os.*;
import android.util.*;
import android.graphics.*;
import android.text.method.*;
import android.text.*;
import android.media.*;
import android.hardware.*;
import android.content.*;
import android.widget.*;
import android.content.pm.*;
import android.net.Uri;
import android.provider.*;
import android.view.inputmethod.*;
import su.xash.fwgslib.*;
public class XashInput
{
public static JoystickHandler getJoystickHandler()
{
JoystickHandler handler;
if( FWGSLib.sdk >= 14 )
handler = new JoystickHandler_v14();
else if( FWGSLib.sdk >= 12 )
handler = new JoystickHandler_v12();
else
handler = new JoystickHandler();
handler.init();
return handler;
}
public static class JoystickHandler
{
public int getSource( KeyEvent event )
{
return InputDevice.SOURCE_UNKNOWN;
}
public int getSource( MotionEvent event )
{
return InputDevice.SOURCE_UNKNOWN;
}
public boolean handleAxis( MotionEvent event )
{
return false;
}
public boolean isGamepadButton( int keyCode )
{
return false;
}
public String keyCodeToString( int keyCode )
{
return String.valueOf( keyCode );
}
public void init()
{
}
public boolean hasVibrator()
{
return true;
}
public void showMouse( boolean show )
{
}
public int getButtonState( MotionEvent event )
{
return 0;
}
}
static class JoystickHandler_v12 extends JoystickHandler
{
private static float prevSide, prevFwd, prevYaw, prevPtch, prevLT, prevRT, prevHX, prevHY;
public static boolean mNVMouseExtensions = false;
static int mouseId;
static
{
try
{
Wrap_NVMouseExtensions.checkAvailable();
mNVMouseExtensions = true;
}
catch( Throwable t )
{
mNVMouseExtensions = false;
}
}
@Override
public void init()
{
XashActivity.mSurface.setOnGenericMotionListener( new MotionListener() );
Log.d( XashActivity.TAG, "mNVMouseExtensions = " + mNVMouseExtensions );
}
@Override
public int getSource( KeyEvent event )
{
return event.getSource();
}
@Override
public int getSource( MotionEvent event )
{
if( event.getDeviceId() == mouseId )
return InputDevice.SOURCE_MOUSE;
return event.getSource();
}
@Override
public boolean handleAxis( MotionEvent event )
{
// how event can be from null device, Android?
final InputDevice device = event.getDevice();
if( device == null )
return false;
// maybe I need to cache this...
for( InputDevice.MotionRange range: device.getMotionRanges() )
{
// normalize in -1.0..1.0 (copied from SDL2)
final float cur = ( event.getAxisValue( range.getAxis(), event.getActionIndex() ) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
final float dead = range.getFlat(); // get axis dead zone
switch( range.getAxis() )
{
// typical axes
// move
case MotionEvent.AXIS_X:
prevSide = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_SIDE, prevSide, dead );
break;
case MotionEvent.AXIS_Y:
prevFwd = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_FWD, prevFwd, dead );
break;
// rotate. Invert, so by default this works as it's should
case MotionEvent.AXIS_Z:
prevPtch = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_PITCH, prevPtch, dead );
break;
case MotionEvent.AXIS_RZ:
prevYaw = XashActivity.performEngineAxisEvent( -cur, XashActivity.JOY_AXIS_YAW, prevYaw, dead );
break;
// trigger
case MotionEvent.AXIS_RTRIGGER:
prevLT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_RT, prevLT, dead );
break;
case MotionEvent.AXIS_LTRIGGER:
prevRT = XashActivity.performEngineAxisEvent( cur, XashActivity.JOY_AXIS_LT, prevRT, dead );
break;
// hats
case MotionEvent.AXIS_HAT_X:
prevHX = XashActivity.performEngineHatEvent( cur, true, prevHX );
break;
case MotionEvent.AXIS_HAT_Y:
prevHY = XashActivity.performEngineHatEvent( cur, false, prevHY );
break;
}
}
return true;
}
@Override
public boolean isGamepadButton( int keyCode )
{
return KeyEvent.isGamepadButton( keyCode );
}
@Override
public String keyCodeToString( int keyCode )
{
return KeyEvent.keyCodeToString( keyCode );
}
class MotionListener implements View.OnGenericMotionListener
{
@Override
public boolean onGenericMotion( View view, MotionEvent event )
{
final int source = XashActivity.handler.getSource( event );
if( FWGSLib.FExactBitSet( source, InputDevice.SOURCE_GAMEPAD ) ||
FWGSLib.FExactBitSet( source, InputDevice.SOURCE_CLASS_JOYSTICK ) )
return XashActivity.handler.handleAxis( event );
if( mNVMouseExtensions )
{
float x = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeX(), 0 );
float y = event.getAxisValue( Wrap_NVMouseExtensions.getAxisRelativeY(), 0 );
if( !FWGSLib.FExactBitSet( source, InputDevice.SOURCE_MOUSE) && (x != 0 || y != 0 ))
mouseId = event.getDeviceId();
switch( event.getAction() )
{
case MotionEvent.ACTION_SCROLL:
if( event.getAxisValue( MotionEvent.AXIS_VSCROLL ) < 0.0f )
{
XashActivity.nativeKey( 1, -239 );
XashActivity.nativeKey( 0, -239 );
return true;
}
else
{
XashActivity.nativeKey( 1, -240 );
XashActivity.nativeKey( 0, -240 );
}
return true;
}
XashActivity.nativeMouseMove( x, y );
// Log.v("XashInput", "MouseMove: " +x + " " + y );
return true;
}
// TODO: Add it someday
// else if( (event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == InputDevice.SOURCE_CLASS_TRACKBALL )
// return XashActivity.handleBall( event );
//return super.onGenericMotion( view, event );
return false;
}
}
@Override
public boolean hasVibrator()
{
if( XashActivity.mVibrator != null )
return XashActivity.mVibrator.hasVibrator();
return false;
}
@Override
public void showMouse( boolean show )
{
if( mNVMouseExtensions )
Wrap_NVMouseExtensions.setCursorVisibility( show );
}
}
static class JoystickHandler_v14 extends JoystickHandler_v12
{
@Override
public int getButtonState( MotionEvent event )
{
return event.getButtonState();
}
}
public static View.OnTouchListener getTouchListener()
{
if( FWGSLib.sdk >= 5 )
return new EngineTouchListener_v5();
else
return new EngineTouchListener_v1();
}
}
class Wrap_NVMouseExtensions
{
private static Object inputManager;
private static Method mInputManager_setCursorVisibility;
private static Method mView_setPointerIcon;
private static Class mPointerIcon;
private static Object mEmptyIcon;
public static int nMotionEvent_AXIS_RELATIVE_X = 0;
public static int nMotionEvent_AXIS_RELATIVE_Y = 0;
//**************************************************************************
static
{
try
{
mInputManager_setCursorVisibility =
Class.forName( "android.hardware.input.InputManager" ).getMethod( "setCursorVisibility", boolean.class );
inputManager = XashActivity.mSingleton.getSystemService( "input" );
}
catch( Exception ex )
{
try
{
mPointerIcon=Class.forName("android.view.PointerIcon");
mEmptyIcon = mPointerIcon.getDeclaredMethod("getSystemIcon",android.content.Context.class, int.class).invoke(null,XashActivity.mSingleton.getContext(),0);
mView_setPointerIcon = View.class.getMethod("setPointerIcon",mPointerIcon);
}
catch( Exception ex1 )
{
ex1.printStackTrace();
}
}
/* DO THE SAME FOR RELATIVEY */
}
//*************************************************************************
public static void checkAvailable() throws Exception
{
Field fieldMotionEvent_AXIS_RELATIVE_X = MotionEvent.class.getField( "AXIS_RELATIVE_X" );
nMotionEvent_AXIS_RELATIVE_X = ( Integer )fieldMotionEvent_AXIS_RELATIVE_X.get( null );
Field fieldMotionEvent_AXIS_RELATIVE_Y = MotionEvent.class.getField( "AXIS_RELATIVE_Y" );
nMotionEvent_AXIS_RELATIVE_Y = ( Integer )fieldMotionEvent_AXIS_RELATIVE_Y.get( null );
}
static void setPointerIcon( View view, boolean fVisibility )
{
Log.v("XashInput", "SET CURSOR VISIBILITY " + fVisibility + " obj " + mEmptyIcon.toString() );
try
{
mView_setPointerIcon.invoke(view,fVisibility?null:mEmptyIcon);
}
catch( Exception e)
{
e.printStackTrace();
}
}
static void setGroupPointerIcon( ViewGroup parent, boolean fVisibility )
{
for( int i = parent.getChildCount() - 1; i >= 0; i-- )
{
try
{
final View child = parent.getChildAt(i);
if( child == null )
continue;
if( child instanceof ViewGroup )
{
setGroupPointerIcon((ViewGroup) child, fVisibility);
}
setPointerIcon( child, fVisibility);
}
catch( Exception ex )
{
ex.printStackTrace();
}
}
}
//**************************************************************************
public static void setCursorVisibility( boolean fVisibility )
{
try
{
mInputManager_setCursorVisibility.invoke( inputManager, fVisibility );
}
catch( Exception e )
{
try
{
ViewGroup rootViewGroup = (ViewGroup) XashActivity.mSingleton.getWindow().getDecorView();
setGroupPointerIcon(rootViewGroup, fVisibility);
setGroupPointerIcon((ViewGroup)XashActivity.mDecorView, fVisibility);
for (int i = 0; i < rootViewGroup.getChildCount(); i++) {
View view = rootViewGroup.getChildAt(i);
setPointerIcon(view, fVisibility);
}
}
catch( Exception ex)
{
ex.printStackTrace();
}
}
}
//**************************************************************************
public static int getAxisRelativeX()
{
return nMotionEvent_AXIS_RELATIVE_X;
}
public static int getAxisRelativeY()
{
return nMotionEvent_AXIS_RELATIVE_Y;
}
}
class EngineTouchListener_v1 implements View.OnTouchListener
{
// Touch events
public boolean onTouch( View v, MotionEvent event )
{
XashActivity.nativeTouch( 0, event.getAction(), event.getX(), event.getY() );
return true;
}
}
class EngineTouchListener_v5 implements View.OnTouchListener
{
float lx = 0, ly = 0;
boolean secondarypressed = false;
// Touch events
public boolean onTouch( View v, MotionEvent event )
{
//final int touchDevId = event.getDeviceId();
final int pointerCount = event.getPointerCount();
int action = event.getActionMasked();
int pointerFingerId, mouseButton, i = -1;
float x, y;
switch( action )
{
case MotionEvent.ACTION_MOVE:
if( ( !XashActivity.fMouseShown ) && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
{
x = event.getX();
y = event.getY();
XashActivity.nativeMouseMove( x - lx, y - ly );
lx = x;
ly = y;
return true;
}
for( i = 0; i < pointerCount; i++ )
{
pointerFingerId = event.getPointerId( i );
x = event.getX( i ) * XashActivity.mTouchScaleX;
y = event.getY( i ) * XashActivity.mTouchScaleY;
XashActivity.nativeTouch( pointerFingerId, 2, x, y );
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_DOWN:
if( !XashActivity.fMouseShown && ( ( XashActivity.handler.getSource( event ) & InputDevice.SOURCE_MOUSE ) == InputDevice.SOURCE_MOUSE ) )
{
lx = event.getX();
ly = event.getY();
boolean down = ( action == MotionEvent.ACTION_DOWN ) || ( action == MotionEvent.ACTION_POINTER_DOWN );
int buttonState = XashActivity.handler.getButtonState( event );
if( down && ( buttonState & MotionEvent.BUTTON_SECONDARY ) != 0 )
{
XashActivity.nativeKey( 1, -243 );
secondarypressed = true;
return true;
}
else if( !down && secondarypressed && ( buttonState & MotionEvent.BUTTON_SECONDARY ) == 0 )
{
secondarypressed = false;
XashActivity.nativeKey( 0, -243 );
return true;
}
XashActivity.nativeKey( down ? 1 : 0, -241 );
return true;
}
i = 0;
// fallthrough
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN:
// Non primary pointer up/down
if( i == -1 )
{
i = event.getActionIndex();
}
pointerFingerId = event.getPointerId( i );
x = event.getX( i ) * XashActivity.mTouchScaleX;
y = event.getY( i ) * XashActivity.mTouchScaleY;
if( action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP )
XashActivity.nativeTouch( pointerFingerId,1, x, y );
if( action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN )
XashActivity.nativeTouch( pointerFingerId,0, x, y );
break;
case MotionEvent.ACTION_CANCEL:
for( i = 0; i < pointerCount; i++ )
{
pointerFingerId = event.getPointerId( i );
x = event.getX( i ) * XashActivity.mTouchScaleX;
y = event.getY( i ) * XashActivity.mTouchScaleY;
XashActivity.nativeTouch( pointerFingerId, 1, x, y );
}
break;
default: break;
}
return true;
}
}
/* This is a fake invisible editor view that receives the input and defines the
* pan&scan region
*/
class DummyEdit extends View implements View.OnKeyListener
{
InputConnection ic;
public DummyEdit( Context context )
{
super( context );
setFocusableInTouchMode( true );
setFocusable( true );
setOnKeyListener( this );
}
@Override
public boolean onCheckIsTextEditor()
{
return true;
}
@Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
return XashActivity.handleKey( keyCode, event );
}
@Override
public InputConnection onCreateInputConnection( EditorInfo outAttrs )
{
ic = new XashInputConnection( this, true );
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
| 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
return ic;
}
}
class XashInputConnection extends BaseInputConnection
{
public XashInputConnection( View targetView, boolean fullEditor )
{
super( targetView, fullEditor );
}
@Override
public boolean sendKeyEvent( KeyEvent event )
{
if( XashActivity.handleKey( event.getKeyCode(), event ) )
return true;
return super.sendKeyEvent( event );
}
@Override
public boolean commitText( CharSequence text, int newCursorPosition )
{
// nativeCommitText(text.toString(), newCursorPosition);
if( text.toString().equals( "\n" ) )
{
XashActivity.nativeKey( 1, KeyEvent.KEYCODE_ENTER );
XashActivity.nativeKey( 0, KeyEvent.KEYCODE_ENTER );
}
XashActivity.nativeString( text.toString() );
return super.commitText( text, newCursorPosition );
}
@Override
public boolean setComposingText( CharSequence text, int newCursorPosition )
{
// a1batross:
// This method is intended to show composed text immediately
// that after will be replaced by text from "commitText" method
// Just leaving this unimplemented fixes "twice" input on T9/Swype-like keyboards
//ativeSetComposingText(text.toString(), newCursorPosition);
// XashActivity.nativeString( text.toString() );
return super.setComposingText( text, newCursorPosition );
}
public native void nativeSetComposingText( String text, int newCursorPosition );
@Override
public boolean deleteSurroundingText( int beforeLength, int afterLength )
{
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
if( beforeLength > 0 && afterLength == 0 )
{
boolean ret = true;
// backspace(s)
while( beforeLength-- > 0 )
{
boolean ret_key = sendKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL ) )
&& sendKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL ) );
ret = ret && ret_key;
}
return ret;
}
return super.deleteSurroundingText(beforeLength, afterLength);
}
}

View file

@ -1,244 +0,0 @@
package su.xash.engine;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.*;
import android.app.*;
import android.content.*;
import android.view.*;
import android.os.*;
import android.util.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.text.method.*;
import android.text.*;
import android.media.*;
import android.hardware.*;
import android.content.*;
import android.widget.*;
import android.content.pm.*;
import android.net.Uri;
import android.provider.*;
import android.database.*;
import android.view.inputmethod.*;
import java.lang.*;
import java.util.List;
import java.security.MessageDigest;
import su.xash.engine.R;
import su.xash.engine.XashConfig;
public class XashService extends Service
{
public static XashNotification not;
@Override
public IBinder onBind(Intent intent)
{
return null;
}
public static class ExitButtonListener extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
XashActivity.mEngineReady = false;
XashActivity.nativeUnPause();
XashActivity.nativeOnDestroy();
if( XashActivity.mSurface != null )
XashActivity.mSurface.engineThreadJoin();
System.exit(0);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("XashService", "Service Started");
not = XashNotification.getXashNotification();
startForeground(not.getId(), not.createNotification(this));
return START_NOT_STICKY;
}
@Override
public void onDestroy()
{
super.onDestroy();
Log.d("XashService", "Service Destroyed");
}
@Override
public void onCreate()
{
}
@Override
public void onTaskRemoved(Intent rootIntent)
{
Log.e("XashService", "OnTaskRemoved");
//if( XashActivity.mEngineReady )
{
XashActivity.mEngineReady = false;
XashActivity.nativeUnPause();
XashActivity.nativeOnDestroy();
if( XashActivity.mSurface != null )
XashActivity.mSurface.engineThreadJoin();
System.exit(0);
}
stopSelf();
}
public static class XashNotification
{
public Notification notification;
public final int notificationId = 100;
protected Context ctx;
public Notification createNotification(Context context)
{
ctx = context;
Intent engineIntent = new Intent(ctx, XashActivity.class);
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Intent exitIntent = new Intent(ctx, ExitButtonListener.class);
final PendingIntent pendingExitIntent = PendingIntent.getBroadcast(ctx, 0, exitIntent, 0);
notification = new Notification(R.drawable.ic_statusbar, ctx.getString(R.string.app_name), System.currentTimeMillis());
notification.contentView = new RemoteViews(ctx.getApplicationContext().getPackageName(), R.layout.notify);
notification.contentView.setTextViewText(R.id.status_text, ctx.getString(R.string.app_name));
notification.contentView.setOnClickPendingIntent(R.id.status_exit_button, pendingExitIntent);
notification.contentIntent = PendingIntent.getActivity(ctx.getApplicationContext(), 0, engineIntent, 0);
notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
return notification;
}
public void setIcon(Bitmap bmp)
{
notification.contentView.setImageViewBitmap( R.id.status_image, bmp );
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify( notificationId, notification );
}
public void setText(String title)
{
notification.contentView.setTextViewText( R.id.status_text, title );
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify( notificationId, notification );
}
public int getId()
{
return notificationId;
}
public static XashNotification getXashNotification()
{
if( XashActivity.sdk >= 26 )
return new XashNotification_v26();
else if( XashActivity.sdk >= 23 )
return new XashNotification_v23();
else
return new XashNotification();
}
}
private static class XashNotification_v23 extends XashNotification
{
protected Notification.Builder builder;
@Override
public Notification createNotification(Context context)
{
ctx = context;
Intent engineIntent = new Intent(ctx, XashActivity.class);
engineIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Intent exitIntent = new Intent(ctx, ExitButtonListener.class);
final PendingIntent pendingExitIntent = PendingIntent.getBroadcast(ctx, 0, exitIntent, 0);
if(builder == null)
builder = new Notification.Builder(ctx);
notification = builder.setSmallIcon(R.drawable.ic_statusbar)
.setLargeIcon(Icon.createWithResource(ctx, R.mipmap.ic_launcher))
.setContentTitle(ctx.getString(R.string.app_name))
.setContentText(ctx.getString(R.string.app_name))
.setContentIntent(PendingIntent.getActivity(ctx.getApplicationContext(), 0, engineIntent, 0))
.addAction(new Notification.Action.Builder(R.drawable.empty, ctx.getString(R.string.exit), pendingExitIntent).build())
.setOngoing(true)
.build();
return notification;
}
@Override
public void setIcon(Bitmap bmp)
{
notification = builder.setLargeIcon(bmp).build();
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify( notificationId, notification );
}
@Override
public void setText(String str)
{
notification = builder.setContentText(str).build();
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify( notificationId, notification );
}
}
private static class XashNotification_v26 extends XashNotification_v23
{
private static final String CHANNEL_ID = "XashServiceChannel";
private void createNotificationChannel()
{
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
final NotificationManager nm = ctx.getSystemService(NotificationManager.class);
if(nm.getNotificationChannel(CHANNEL_ID) == null)
{
CharSequence name = ctx.getString(R.string.default_channel_name);
String description = ctx.getString(R.string.default_channel_description);
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
nm.createNotificationChannel(channel);
}
}
@Override
public Notification createNotification(Context context)
{
ctx = context;
createNotificationChannel();
builder = new Notification.Builder(ctx);
builder.setChannelId(CHANNEL_ID);
return super.createNotification(ctx);
}
}
};

View file

@ -1,218 +0,0 @@
package su.xash.engine;
import android.animation.*;
import android.app.*;
import android.content.*;
import android.os.*;
import android.util.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import android.widget.TableRow.*;
import su.xash.engine.*;
import java.util.*;
import su.xash.fwgslib.*;
import android.view.View.MeasureSpec;
public class XashTutorialActivity extends Activity implements View.OnClickListener
{
private Button next, prev;
private LinearLayout indicatorLayout;
private FrameLayout containerLayout;
private RelativeLayout buttonContainer;
private int currentItem;
private int prevText, nextText, finishText, cancelText, numPages;
PagedView scroll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( FWGSLib.sdk >= 21 ) // material
setTheme(0x0103022e); // Theme_Material_NoActionBar
else
setTheme(0x01030006); // Theme_NoTitleBar
setContentView(R.layout.activity_tutorial);
initTexts();
initViews();
initPages();
changeFragment(0);
}
private void initTexts() {
prevText = R.string.prev;
cancelText = R.string.skip;
finishText = R.string.finish;
nextText = R.string.next;
}
private void initPages() {
LayoutInflater inflater;
inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup container = (ViewGroup)findViewById(R.id.container);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
scroll = new PagedView(this,metrics.widthPixels);
container.addView(scroll);
while( true )
{
int titleres = getResources().getIdentifier("page_title" + String.valueOf(numPages), "string", getPackageName());
if( titleres == 0 )
break;
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.tutorial_step , null);
TextView title = (TextView) layout.findViewById(R.id.title);
TextView text = (TextView) layout.findViewById(R.id.content);
ImageView drawable = (ImageView) layout.findViewById(R.id.image);
int contentres = getResources().getIdentifier("page_content" + String.valueOf(numPages), "string", getPackageName());
int drawableres = getResources().getIdentifier("page" + String.valueOf(numPages), "drawable", getPackageName());
if( drawableres == 0)
drawableres = getResources().getIdentifier("page" + String.valueOf(numPages) + "_" + Locale.getDefault().getLanguage(), "drawable", getPackageName());
if( drawableres == 0 )
drawableres = getResources().getIdentifier("page" + String.valueOf(numPages) + "_en", "drawable", getPackageName());
title.setText(titleres);
text.setText(contentres);
if( FWGSLib.isLandscapeOrientation(this) )
drawable.setScaleType(ImageView.ScaleType.FIT_CENTER);
drawable.setImageResource(drawableres);
scroll.addPage(layout);
numPages++;
}
scroll.setOnPageListener(new PagedView.OnPageListener(){
@Override
public void onPage(int page)
{
currentItem = page;
controlPosition();
}
});
if( FWGSLib.sdk < 14 ) // pre-ics does not apply buttons background
FWGSLib.changeButtonsStyle((ViewGroup)container.getParent());
}
private void controlPosition()
{
if( currentItem > numPages - 1 )
currentItem = numPages - 1;
notifyIndicator();
if (currentItem == numPages - 1) {
next.setText(finishText);
prev.setText(prevText);
} else if ( currentItem == 0) {
prev.setText(cancelText);
next.setText(nextText);
} else {
prev.setText(prevText);
next.setText(nextText);
}
}
private void initViews() {
currentItem = 0;
next = (Button) findViewById(R.id.next);
prev = (Button) findViewById(R.id.prev);
indicatorLayout = (LinearLayout) findViewById(R.id.indicatorLayout);
containerLayout = (FrameLayout) findViewById(R.id.containerLayout);
buttonContainer = (RelativeLayout) findViewById(R.id.buttonContainer);
next.setOnClickListener(this);
prev.setOnClickListener(this);
}
public void notifyIndicator() {
if (indicatorLayout.getChildCount() > 0)
indicatorLayout.removeAllViews();
for (int i = 0; i < 5; i++) {
ImageView imageView = new ImageView(this);
imageView.setPadding(8, 8, 8, 8);
int drawable = R.drawable.circle_black;
if (i == currentItem)
drawable = R.drawable.circle_white;
imageView.setImageResource(drawable);
final int finalI = i;
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeFragment(finalI);
}
});
indicatorLayout.addView(imageView);
}
}
@Override
public void onBackPressed() {
if (currentItem == 0) {
finish();
} else {
changeFragment(false);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.next) {
if( currentItem == numPages - 1 )
{
finish();
return;
}
changeFragment(true);
} else if (v.getId() == R.id.prev) {
if( currentItem == 0 )
{
finish();
return;
}
changeFragment(false);
}
}
private void changeFragment(int position) {
scroll.changePage(position);
}
private void changeFragment(boolean isNext) {
if (isNext) {
scroll.changePage(currentItem+1);
} else {
scroll.changePage(currentItem-1);
}
}
public void setPrevText(int text) {
prevText = text;
}
public void setNextText(int text) {
nextText = text;
}
public void setFinishText(int text) {
finishText = text;
}
public void setCancelText(int text) {
cancelText = text;
}
}

View file

@ -1,100 +0,0 @@
package su.xash.fwgslib;
import android.content.*;
import android.view.*;
import android.os.*;
import android.util.*;
import android.graphics.*;
import android.text.method.*;
import android.text.*;
import android.media.*;
import android.hardware.*;
import android.content.*;
import android.widget.*;
import android.content.pm.*;
import java.lang.*;
import java.util.List;
import java.security.MessageDigest;
import su.xash.engine.XashConfig; // change pkgname if needed
public class CertCheck
{
// Certificate checking
private static String SIG = "DMsE8f5hlR7211D8uehbFpbA0n8=";
private static String SIG_TEST = ""; // a1ba: mittorn, add your signature later
private static String TAG = "XASH3D:CertCheck";
public static boolean dumbAntiPDALifeCheck( Context context )
{
if( !XashConfig.CHECK_SIGNATURES /* || BuildConfig.DEBUG */ )
return false; // disable checking for debug builds
final String sig;
if( XashConfig.PKG_TEST )
{
sig = SIG_TEST;
}
else
{
sig = SIG;
}
if( dumbCertificateCheck( context, context.getPackageName(), sig, false ) )
{
Log.e(TAG, "Please, don't resign our public release builds!");
Log.e(TAG, "If you want to insert some features, rebuild package with ANOTHER package name from git repository.");
return true;
}
return false;
}
public static boolean dumbCertificateCheck( Context context, String pkgName, String sig, boolean failIfNoPkg )
{
if( sig == null )
sig = SIG;
Log.d( TAG, "pkgName = " + pkgName );
try
{
PackageInfo info = context.getPackageManager()
.getPackageInfo( pkgName, PackageManager.GET_SIGNATURES );
for( Signature signature: info.signatures )
{
Log.d( TAG, "found signature" );
MessageDigest md = MessageDigest.getInstance( "SHA" );
final byte[] signatureBytes = signature.toByteArray();
md.update( signatureBytes );
final String curSIG = Base64.encodeToString( md.digest(), Base64.NO_WRAP );
if( sig.equals(curSIG) )
{
Log.d( TAG, "Found valid cert" );
return false;
}
}
}
catch( PackageManager.NameNotFoundException e )
{
Log.d( TAG, "Package not found" );
e.printStackTrace();
if( !failIfNoPkg )
return false;
}
catch( Exception e )
{
e.printStackTrace();
}
return true;
}
}

View file

@ -1,142 +0,0 @@
package su.xash.fwgslib;
import android.app.*;
import android.content.*;
import android.net.*;
import android.os.*;
import android.util.*;
import android.widget.*;
import su.xash.engine.*;
import java.io.*;
import java.net.*;
import org.json.*;
public class CheckUpdate extends AsyncTask<String, Void, String> {
InputStream is = null;
ByteArrayOutputStream os = null;
boolean mSilent;
boolean mBeta;
Context mContext;
public CheckUpdate( Context context, boolean silent, boolean beta )
{
mSilent = silent;
mBeta = beta;
mContext = context;
}
protected String doInBackground(String... urls)
{
try
{
URL url = new URL(urls[0]);
is = url.openConnection().getInputStream();
os = new ByteArrayOutputStream();
byte[] buffer = new byte[8196];
int len;
while ((len = is.read(buffer)) > 0)
{
os.write(buffer, 0, len);
}
os.flush();
return os.toString();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
protected void onPostExecute(String result)
{
JSONArray releases = null;
try
{
if (is != null)
{
is.close();
is = null;
}
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
if (os != null)
{
releases = new JSONArray(os.toString());
os.close();
os = null;
}
}
catch(Exception e)
{
e.printStackTrace();
return;
}
if( releases == null )
return;
for( int i = 0; i < releases.length(); i++ )
{
final JSONObject obj;
try
{
obj = releases.getJSONObject(i);
final String version, url, name;
final boolean beta = obj.getBoolean("prerelease");
if( beta && !mBeta )
continue;
version = obj.getString("tag_name");
url = obj.getString("html_url");
name = obj.getString("name");
Log.d("Xash", "Found: " + version +
", I: " + mContext.getString(R.string.version_string));
// this is an update
if( mContext.getString(R.string.version_string).compareTo(version) < 0 )
{
String dialog_message = String.format(mContext.getString(R.string.update_message), name);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(dialog_message)
.setPositiveButton(R.string.update, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
final Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url));
mContext.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
{ public void onClick(DialogInterface dialog, int id) {} } );
builder.create().show();
}
else if( !mSilent )
{
Toast.makeText(mContext, R.string.no_updates, Toast.LENGTH_SHORT).show();
}
// No need to check other releases, so we will stop here.
break;
}
catch(Exception e)
{
e.printStackTrace();
continue;
}
}
}
}

View file

@ -1,339 +0,0 @@
package su.xash.fwgslib;
import android.Manifest;
import android.app.*;
import android.content.*;
import android.content.pm.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.net.*;
import android.os.*;
import android.text.*;
import android.text.method.*;
import android.text.style.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.net.*;
import java.lang.*;
import java.util.*;
import org.json.*;
import android.preference.*;
/*
* This utility class is intended to hide some Android and Java design-flaws and
* also just shortcuts
*/
public class FWGSLib
{
private static final String TAG = "FWGSLib";
static String externalFilesDir;
public static boolean FBitSet( final int bits, final int mask )
{
return ((bits & mask) != 0);
}
public static boolean FExactBitSet( final int bits, final int mask )
{
return ((bits & mask) == mask );
}
public static float atof( String str, float fallback )
{
float ret;
try
{
ret = Float.valueOf( str );
}
catch( Exception e )
{
ret = fallback;
}
return ret;
}
public static int atoi( String str, int fallback )
{
int ret;
try
{
ret = Integer.valueOf( str );
}
catch( Exception e )
{
ret = fallback;
}
return ret;
}
public static boolean checkGameLibDir( String gamelibdir, String allowed )
{
try
{
Log.d( TAG, " gamelibdir = " + gamelibdir + " allowed = " + allowed );
if( gamelibdir.contains( "/.." ))
return false;
File f = new File( gamelibdir );
if( !f.isDirectory() )
{
Log.d( TAG, "Not a directory" );
return false;
}
if( !f.exists() )
{
Log.d( TAG, "Does not exist" );
return false;
}
// add trailing / for simple regexp
if( gamelibdir.charAt(gamelibdir.length() - 1) != '/' )
gamelibdir = gamelibdir + "/";
final String regex = ".+\\/" + allowed.replace(".", "\\.") + "(|(-\\d))\\/(.+|)";
Log.d( TAG, regex );
final boolean ret = gamelibdir.matches( regex );
Log.d( TAG, "ret = " + ret );
return ret;
}
catch( Exception e )
{
e.printStackTrace();
}
return false;
}
public static String getDefaultXashPath()
{
File dir = Environment.getExternalStorageDirectory();
if( dir != null && dir.exists() )
return dir.getPath() + "/xash";
return "/sdcard/xash";
}
static class GetExternalFilesDir extends Thread
{
Context ctx;
GetExternalFilesDir( Context ctx1 )
{
ctx = ctx1;
}
@Override
public void run()
{
try
{
File f = ctx.getExternalFilesDir(null);
f.mkdirs();
externalFilesDir = f.getAbsolutePath();
Log.d(TAG, "getExternalFilesDir success");
}
catch( Exception e )
{
Log.e( TAG, e.toString(), e);
}
}
}
public static String getExternalFilesDir( Context ctx )
{
if( externalFilesDir != null )
return externalFilesDir;
try
{
if( sdk >= 8 )
{
Thread t = new GetExternalFilesDir(ctx);
t.start();
t.join(2000);
}
}
catch(Exception e)
{
Log.e( TAG, e.toString(), e);
externalFilesDir = getDefaultXashPath();
}
if( externalFilesDir == null )
externalFilesDir = getDefaultXashPath();
return externalFilesDir;
}
public static boolean isLandscapeOrientation( Activity act )
{
DisplayMetrics metrics = new DisplayMetrics();
act.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return (metrics.widthPixels > metrics.heightPixels);
}
public static String getStringExtraFromIntent( Intent intent, String extraString, String ifNotFound )
{
String ret = intent.getStringExtra( extraString );
if( ret == null )
{
ret = ifNotFound;
}
return ret;
}
public static void changeButtonsStyle( ViewGroup parent )
{
if( sdk >= 21 )
return;
for( int i = parent.getChildCount() - 1; i >= 0; i-- )
{
try
{
final View child = parent.getChildAt(i);
if( child == null )
continue;
if( child instanceof ViewGroup )
{
changeButtonsStyle((ViewGroup) child);
// DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
}
else if( child instanceof Button )
{
final Button b = (Button)child;
final Drawable bg = b.getBackground();
if(bg!= null)bg.setAlpha( 96 );
b.setTextColor( 0xFFFFFFFF );
b.setTextSize( 15f );
//b.setText(b.getText().toString().toUpperCase());
b.setTypeface( b.getTypeface(),Typeface.BOLD );
}
else if( child instanceof EditText )
{
final EditText b = ( EditText )child;
b.setBackgroundColor( 0xFF353535 );
b.setTextColor( 0xFFFFFFFF );
b.setTextSize( 15f );
}
}
catch( Exception e )
{
}
}
}
public static class Compat
{
public void applyPermissions( final Activity act, final String permissions[], final int code ) {}
public void applyImmersiveMode( boolean keyboardVisible, View decorView ) {}
public void startForegroundService( Context ctx, Intent intent ) {}
public String getNativeLibDir(Context ctx)
{
return ctx.getFilesDir().getParentFile().getPath() + "/lib";
}
}
static class Compat_9 extends Compat
{
public String getNativeLibDir(Context ctx)
{
try {
ApplicationInfo ai = getApplicationInfo(ctx, null, 0);
return ai.nativeLibraryDir;
}
catch(Exception e) {
return super.getNativeLibDir(ctx);
}
}
public void startForegroundService( Context ctx, Intent intent ) {
ctx.startService( intent );
}
}
static class Compat_19 extends Compat_9
{
public void applyImmersiveMode( boolean keyboardVisible, View decorView )
{
if( decorView == null )
return;
if( keyboardVisible )
decorView.setSystemUiVisibility(
0x00000100 // View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| 0x00000200 // View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| 0x00000400 // View.SYSTEM_UI_FLAG_LAYOUT_FULSCREEN
| 0x00000002 // View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| 0x00000004 // View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| 0x00001000 // View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
else
decorView.setSystemUiVisibility( 0 );
}
}
static class Compat_23 extends Compat_19
{
public void applyPermissions( final Activity act, final String permissions[], final int code )
{
List<String> requestPermissions = new ArrayList<String>();
for( int i = 0; i < permissions.length; i++ )
{
if( act.checkSelfPermission(permissions[i]) != PackageManager.PERMISSION_GRANTED )
{
requestPermissions.add(permissions[i]);
}
}
if( !requestPermissions.isEmpty() )
{
String[] requestPermissionsArray = new String[requestPermissions.size()];
for( int i = 0; i < requestPermissions.size(); i++ )
{
requestPermissionsArray[i] = requestPermissions.get(i);
}
act.requestPermissions(requestPermissionsArray, code);
}
}
}
static class Compat_26 extends Compat_23
{
public void startForegroundService(Context ctx, Intent intent){
ctx.startForegroundService(intent);
}
}
public static Compat cmp;
static {
int sdk1 = Integer.valueOf(Build.VERSION.SDK);
if( sdk1 >= 26 )
cmp = new Compat_26();
if( sdk1 >= 23 )
cmp = new Compat_23();
else if( sdk1 >= 9 )
cmp = new Compat_9();
else cmp = new Compat();
}
public static ApplicationInfo getApplicationInfo(Context ctx, String pkgName, int flags) throws PackageManager.NameNotFoundException
{
PackageManager pm = ctx.getPackageManager();
if( pkgName == null )
pkgName = ctx.getPackageName();
return pm.getApplicationInfo(pkgName, flags);
}
public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
}

View file

@ -1,137 +0,0 @@
package su.xash.fwgslib;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import android.content.Context;
public class PagedView extends HorizontalScrollView
{
boolean isDelayed, isInc, anim;
int lastScroll, pageWidth, currentPage, numPages, targetPage;
float firstx,lastx;
LinearLayout pageContainer;
ViewGroup.LayoutParams pageParams;
// allow detect animation end
public static abstract class OnPageListener
{
abstract public void onPage(int page);
}
OnPageListener listener;
public PagedView(Context ctx, int pagewidth)
{
super(ctx);
pageContainer = new LinearLayout(ctx);
pageContainer.setOrientation(LinearLayout.HORIZONTAL);
setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
setScrollBarStyle(SCROLLBARS_INSIDE_INSET);
addView(pageContainer);
pageWidth = pagewidth;
// this will be applied to every page
pageParams = new ViewGroup.LayoutParams(pagewidth, LayoutParams.FILL_PARENT);
}
private void animateScroll()
{
if( !anim )
{
// allow only correct position if anim disabled
scrollTo(pageWidth*currentPage,0);
return;
}
if( isInc && lastScroll >= pageWidth * targetPage || !isInc && lastScroll <= pageWidth * targetPage )
{
// got target page, stop now
anim = false;
currentPage = targetPage;
scrollTo(pageWidth*targetPage,0);
if( listener != null )
listener.onPage(currentPage);
return;
}
if( !isDelayed ) //semaphore
{
isDelayed = true;
postDelayed(new Runnable()
{
public void run()
{
isDelayed = false;
// animate to 1/50 of page every 10 ms
scrollBy(isInc?pageWidth/50:-pageWidth/50,0);
}
},10);
}
}
// add view and set layout
public void addPage(View view)
{
view.setLayoutParams(pageParams);
pageContainer.addView(view);
numPages++;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
{
// this called on every scrollTo/scrollBy and touch scroll
super.onScrollChanged(l,t,oldl,oldt);
lastScroll=l;
isInc = l>oldl;
animateScroll();
}
@Override
public boolean onTouchEvent(MotionEvent e)
{
switch( e.getAction() )
{
case MotionEvent.ACTION_DOWN:
// store swipe start
lastx = firstx = e.getX();
// animation will be started on next scroll event
anim = true;
break;
case MotionEvent.ACTION_MOVE:
// animation will start in supercall, so select direction now
isInc = e.getX() < lastx;
targetPage = isInc?currentPage+1:currentPage-1;
lastx = e.getX();
break;
case MotionEvent.ACTION_UP:
// detect misstouch (<100 pixels)
if( Math.abs(e.getX()-firstx) < 100)
{
/*
anim = false;
targetPage = currentPage;
scrollTo(currentPage*pageWidth,0);*/
targetPage = currentPage;
isInc = currentPage * pageWidth > lastScroll;
}
return false;
}
return super.onTouchEvent(e);
}
// set page number
public void changePage(int page)
{
targetPage = page;
anim = true;
isInc = targetPage > currentPage;
animateScroll();
}
// call when animation ends
public void setOnPageListener(OnPageListener listener1)
{
listener = listener1;
}
}

View file

@ -1,106 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace org.libsdl.app with the identifier of your game below, e.g.
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.celest.xash3d.hl.test"
android:versionCode="1"
android:versionName="0.19.1"
android:installLocation="auto">
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:allowBackup="true"
android:debuggable="false"
android:hardwareAccelerated="true">
<activity android:name="in.celest.xash3d.LauncherActivity"
android:label="@string/launcher_name"
android:windowSoftInputMode="adjustResize"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize">
<intent-filter>
<action android:name="in.celest.xash3d.LauncherActivity"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--<activity android:name="in.celest.xash3d.SteamActivity"
android:label="Steam"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask">
<intent-filter>
<action android:name="in.celest.xash3d.SteamActivity"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>-->
<activity android:name="in.celest.xash3d.ShortcutActivity"
android:label="@string/text_shortcut"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="in.celest.xash3d.SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!--
<activity android:name="org.libsdl.app.SDLActivity"
android:screenOrientation="sensorLandscape"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:taskAffinity="org.libsdl.app.SDLActivity" >
<intent-filter>
<action android:name="in.celest.xash3d.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
-->
<activity android:name="in.celest.xash3d.XashActivity"
android:screenOrientation="sensorLandscape"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="in.celest.xash3d.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="in.celest.xash3d.FPicker"></activity>
<activity android:name="in.celest.xash3d.XashTutorialActivity"></activity>
<service android:name="in.celest.xash3d.XashService" android:stopWithTask="false" />
<receiver android:name="in.celest.xash3d.XashService$exitButtonListener" />
<receiver android:name="in.celest.xash3d.InstallReceiver">
<intent-filter android:priority="100">
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<!--<service android:name="in.celest.xash3d.SteamService" />-->
</application>
<!-- Some devices with Android 2.2 should support native activity, it was in unstable hidden API -->
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="19" />
<!-- OpenGL ES 1.1 -->
<uses-feature android:glEsVersion="0x00010000" />
<!-- Permissions -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
</manifest>

View file

@ -1 +0,0 @@
../../res/drawable

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View file

@ -1 +0,0 @@
../../res/layout/

View file

@ -1 +0,0 @@
../../res/values/

View file

@ -1 +0,0 @@
../../res/values-ru/

View file

@ -1,231 +0,0 @@
package in.celest.xash3d;
import android.app.Activity;
import android.app.AlertDialog;
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.ScrollView;
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.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.util.Log;
//import android.content.Context;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.DialogInterface;
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.os.AsyncTask;
import java.util.List;
import java.util.ArrayList;
import android.text.method.*;
import android.widget.*;
public class SteamActivity extends Activity {
LinearLayout output;
ScrollView scroll;
boolean isScrolling;
static SteamActivity mSingleton = null;
static final int[] waitSwitch = new int[1];
ProgressBar progress;
TextView progressLine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSingleton = this;
// Build layout
LinearLayout launcher = new LinearLayout(this);
launcher.setOrientation(LinearLayout.VERTICAL);
launcher.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
output = new LinearLayout(this);
output.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
output.setOrientation(LinearLayout.VERTICAL);
scroll = new ScrollView(this);
// Set launch button title here
Button startButton = new Button(this);
startButton.setText("Start");
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) {
if( SteamService.mSingleton == null )
startService(new Intent(SteamActivity.this, SteamService.class));
}
});
Button stopButton = new Button(this);
stopButton.setText("Stop");
LayoutParams stopbuttonParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
stopbuttonParams.gravity = 5;
stopButton.setLayoutParams(stopbuttonParams);
stopButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if( SteamService.mSingleton != null )
SteamService.mSingleton.cancelThread();
}
});
LinearLayout buttons = new LinearLayout(this);
buttons.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
buttons.addView(startButton);
buttons.addView(stopButton);
LinearLayout progressLayout = new LinearLayout(this);
progressLayout.setOrientation(LinearLayout.VERTICAL);
progressLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
progress = new ProgressBar(this, null,
android.R.attr.progressBarStyleHorizontal);
progress.setMax(100);
progress.setVisibility(View.GONE);
progressLine = new TextView(this);
progressLine.setVisibility(View.GONE);
progressLine.setTextAppearance(this, android.R.style.TextAppearance_Medium);
progressLayout.addView( progressLine );
progressLayout.addView(progress);
buttons.addView(progressLayout);
launcher.addView(buttons);
scroll.addView(output);
launcher.addView(scroll);
setContentView(launcher);
try
{
synchronized( waitSwitch )
{
waitSwitch.notify();
}
}
catch( Exception e ) {}
}
public void progressUpdate( String str, int p)
{
runOnUiThread(new ProgressCallback( str, p ));
}
public void printText(String str)
{
runOnUiThread(new OutputCallback( str ));
}
String promptDialog(final String title, final String prompt, final boolean passwd)
{
final String[] result = new String[1];
runOnUiThread(new Runnable()
{
@Override
public void run()
{
final EditText edit = new EditText(mSingleton);
if( passwd )
edit.setTransformationMethod(new PasswordTransformationMethod());
new AlertDialog.Builder(mSingleton)
.setTitle(title)
.setMessage(prompt)
.setView(edit)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
synchronized(result)
{
result[0] = edit.getText().toString();
result.notify();
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
synchronized(result)
{
result[0] = null;
result.notify();
}
}
})
.setCancelable(false)
.show();
}
});
synchronized(result)
{
try{
result.wait();
return result[0];
}
catch(Exception e)
{
runOnUiThread(new OutputCallback(e.getMessage()));
return result[0];
}
}
}
// Callbacks to interact with UI from other threads
class OutputCallback implements Runnable {
String str;
OutputCallback(String s) { str = s; }
public void run() {
TextView line = new TextView(SteamActivity.this);
line.setText(str);
line.setTextAppearance(SteamActivity.this, android.R.style.TextAppearance_Small);
line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
progress.setVisibility(View.GONE);
progressLine.setVisibility(View.GONE);
if(output.getChildCount() > 256)
output.removeViewAt(0);
output.addView(line);
if( !isScrolling )
scroll.postDelayed(new Runnable() {
@Override
public void run() {
scroll.fullScroll(ScrollView.FOCUS_DOWN);
isScrolling = false;
}
}, 200);
isScrolling = true;
}
}
class ProgressCallback implements Runnable {
String str;
int p;
ProgressCallback(String s, int pr) { str = s; p = pr; }
public void run() {
progressLine.setText( str );
progressLine.setVisibility(View.VISIBLE);
progress.setProgress(p);
progress.setVisibility(View.VISIBLE);
}
}
@Override
protected void onDestroy()
{
mSingleton = null;
super.onDestroy();
}
}

View file

@ -1,791 +0,0 @@
package in.celest.xash3d;
import android.content.*;
import android.os.IBinder;
import android.util.Log;
import android.widget.*;
import android.app.*;
import android.view.View;
import java.io.*;
import java.util.*;
import java.net.URL;
import java.net.URLConnection;
import in.celest.xash3d.hl.R;
import android.widget.RemoteViews.*;
import android.util.*;
import java.util.concurrent.atomic.*;
enum ProcessState{ UNPACK, LAUNCH, COMMAND, WAIT, DOWNLOAD };
public class SteamService extends Service
{
final static String TAG = "SteamService";
public static SteamService mSingleton;
private Notification notification;
private NotificationManager notificationManager = null;
private String localPath;
private String filesDir;
class RestartException extends Exception {};
class CancelException extends Exception {};
static BackgroundThread mBgThread;
private SharedPreferences mPref;
public void onCreate() {
super.onCreate();
mSingleton = this;
mPref = getSharedPreferences("steam", 0);
synchronized(mPref)
{
// test
mPref.edit()
.putStringSet("pending_verify", new HashSet<String>(Arrays.asList("70")))
.putStringSet("pending_download", new HashSet<String>(Arrays.asList("70")))
.commit();
}
Log.d(TAG, "onCreate");
}
private void notificationInit()
{
// init notification and foreground service
Intent intent = new Intent(this, SteamActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(), 0, intent, 0);
notification = new Notification(R.drawable.ic_launcher,
"SteamCMD download", System.currentTimeMillis());
notification.flags = notification.flags
| Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
notification.contentView = new RemoteViews(getApplicationContext()
.getPackageName(), R.layout.notify);
notification.contentView.setViewVisibility( R.id.status_progress, View.GONE );
notification.contentIntent = pendingIntent;
if( notificationManager == null )
notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
startForeground(100, notification);
}
// Dont create too much notification intents, it may crash system
long lastNotify = 0;
private void progressUpdate( String text, int progress) {
if( SteamActivity.mSingleton != null )
SteamActivity.mSingleton.progressUpdate( text, progress );
if( notification == null )
notificationInit();
long notify = System.currentTimeMillis();
// allow 1s interval
if( notify - lastNotify < 999 )
return;
lastNotify = notify;
notification.contentView.setTextViewText(R.id.status_text, text);
notification.contentView.setProgressBar(R.id.status_progress, 100, progress, false);
notification.contentView.setViewVisibility( R.id.status_progress, View.VISIBLE );
notificationManager.notify(100, notification);
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
try
{
if( mBgThread != null )
{
// prevent running multiple instances
try
{
mBgThread.process.destroy();
synchronized(mBgThread)
{
mBgThread.wait(5000);
}
mBgThread = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
filesDir = getFilesDir().toString();
localPath = mPref.getString( "steam_path", "/sdcard/steam/" );
if( !localPath.endsWith("/") ) localPath += '/';
notificationInit();
mBgThread = new BackgroundThread();
mBgThread.start();
}
catch(Exception e)
{
printText(e.toString());
}
return super.onStartCommand(intent, flags, startId);
}
public void onDestroy() {
silentKillAll();
try
{
if( mBgThread != null )
mBgThread.interrupt();
mBgThread.process.destroy();
}catch( Exception e ){
e.printStackTrace();
}
mSingleton = null;
super.onDestroy();
Log.d(TAG, "onDestroy");
}
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return null;
}
private void printText(String text)
{
// register notification first
if( notification == null )
notificationInit();
long notify = System.currentTimeMillis();
if( notify - lastNotify >= 100 )
{
lastNotify = notify;
notification.contentView.setTextViewText(R.id.status_text,
text);
notificationManager.notify(100, notification);
}
// if activiy exist, print to it's screen
if( SteamActivity.mSingleton == null )
return;
try{
SteamActivity.mSingleton.printText( text );
}
catch( Exception e )
{
}
}
// block current thread and show dialog
private String promptDialog(String title, String message, boolean passwd)
{
Intent intent = new Intent(this, SteamActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(), 0, intent, 0);
// request user interaction
Notification n = new Notification(R.drawable.ic_launcher, message, System.currentTimeMillis());
n.flags |= Notification.FLAG_HIGH_PRIORITY;
//n.priority = Notification.PRIORITY_MAX;
n.contentIntent = pendingIntent;
n.contentView = new RemoteViews(getPackageName(), R.layout.notify);
n.contentView.setViewVisibility(R.id.status_progress, View.GONE);
n.contentView.setTextViewText( R.id.status_text, message );
if( notificationManager == null )
notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(101, n);
notification.contentView.setTextViewText(R.id.status_text, message);
notificationManager.notify(100, notification);
waitForActivity();
notificationManager.cancel(101);
if( SteamActivity.mSingleton == null )
return null;
try{
return SteamActivity.mSingleton.promptDialog(title, message, passwd);
}
catch( Exception e )
{
return null;
}
}
// return next AppID, requested to verify
private synchronized String getVerify()
{
synchronized(mPref)
{
Set<String> prefs = mPref.getStringSet("pending_verify",null);
if( prefs == null || prefs.isEmpty() )
return null;
try
{
return (String)prefs.toArray()[0];
}
catch(Exception e)
{
return null;
}
}
}
// move from pending verification to verified
private synchronized void setVerified(String id)
{
synchronized(mPref)
{
Set<String> prefs = mPref.getStringSet("pending_verify",(Set<String>)new HashSet<String>());
try
{
if( !prefs.isEmpty() && prefs.contains(id) )
prefs.remove(id);
}
catch(Exception e){
prefs = new HashSet<String>();
}
Set<String> verified = mPref.getStringSet("verified",new HashSet<String>());
verified.add( id );
mPref.edit()
.putStringSet("verified",verified)
.putStringSet("pending_verify", prefs)
.commit();
}
}
// just remove from pending set
private synchronized void verifyFail(String id)
{
synchronized(mPref)
{
Set<String> prefs = mPref.getStringSet("pending_verify",(Set<String>)new HashSet<String>());
try
{
if( !prefs.isEmpty() && prefs.contains(id) )
prefs.remove(id);
}
catch(Exception e){
prefs = new HashSet<String>();
}
mPref.edit()
.putStringSet("pending_verify", prefs)
.commit();
}
}
// return next AppID, scheduled to download
private synchronized String getDownload()
{
synchronized(mPref)
{
Set<String> prefs = mPref.getStringSet("pending_download",null);
if( prefs == null || prefs.isEmpty() )
return null;
try
{
return (String)prefs.toArray()[0];
}
catch(Exception e)
{
return null;
}
}
}
// remove from download set
private synchronized void clearDownload(String id)
{
synchronized(mPref)
{
Set<String> prefs = mPref.getStringSet("pending_download",(Set<String>)new HashSet<String>());
try
{
if( !prefs.isEmpty() && prefs.contains(id) )
prefs.remove(id);
}
catch(Exception e){
prefs = new HashSet<String>();
}
mPref.edit()
.putStringSet("pending_download", prefs)
.commit();
}
}
private void waitForActivity()
{
if( SteamActivity.mSingleton != null )
// Nothing to wait
return;
try
{
synchronized( SteamActivity.waitSwitch )
{
SteamActivity.waitSwitch.wait();
}
}
catch( Exception e )
{
Log.d( TAG, "waitForActivity failed: " + e.toString() );
}
}
// separate thread to control remote process
class BackgroundThread extends Thread {
OutputStream processInput = null;
ProcessState state;;
private boolean need_reset_config = false;
private boolean skipQemu = false;
private String lastID;
public Process process;
public AtomicBoolean needDestroy = new AtomicBoolean();
public InputStream httpInput = null;
private void downloadFile( String strurl, String path ) throws IOException, CancelException
{
URL url = new URL(strurl);
int count;
printText("Downloading " + path);
notification.contentView.setViewVisibility( R.id.status_progress, View.GONE );
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
httpInput = new BufferedInputStream(url.openStream(), 8192);
// Output stream
OutputStream output = new FileOutputStream(path);
byte data[] = new byte[1024];
long total = 0;
int lastprogress = 0;
while ( !needDestroy.get() && (count = httpInput.read(data)) != -1) {
total += count;
// publishing the progress....
try
{
if( (lenghtOfFile > 0) && ((int) ((total * 100) / lenghtOfFile) - lastprogress > 1) )
progressUpdate("Downloading " + path, lastprogress = (int) ((total * 100) / lenghtOfFile));
}
catch( Exception e ) {}
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
httpInput.close();
httpInput = null;
if(needDestroy.get())
throw new CancelException();
}
// called on every line, encef with \n
private void processLine( String str ) throws RestartException,IOException
{
// downloading game
if( str.startsWith( " Update state (") )
{
try
{
String statestr = str.substring(20).trim();
//printText(statestr);
String p = statestr.substring(statestr.indexOf('(')+1, statestr.indexOf(')'));
progressUpdate( statestr, (int)(100 * Float.valueOf(p.substring(0,p.indexOf('/')).trim())/Float.valueOf(p.substring(p.indexOf('/')+1).trim())));
return;
}
catch(Exception e)
{
//e.printStackTrace();
}
}
// downloading steam update
else if( !str.isEmpty() && (str.charAt(0) == '[') && str.contains( "] Downloading update ("))
{
try
{
progressUpdate(str, (int) (1*Float.valueOf( str.substring(1, str.indexOf('%')).trim())) );
return;
}
catch( Exception e )
{
e.printStackTrace();
}
}
// switch to command mode
else if( str.contains( "Logged in OK" ) )
{
state = ProcessState.WAIT;
printText("Successfully logged in, now starting to send commands");
}
// avoid steamcmd bug with permanent login failure
else if( str.contains( "FAILED with result code " ) )
{
// login failure, remove config and try again;
need_reset_config = true;
processInput.write("quit\n".getBytes());
processInput.flush();
// hack: process does not restart itself, try force restart it;
try
{
sleep(2000);
}
catch(Exception e){}
throw new RestartException();
}
// download completed
else if( str.contains("Success! App '") && ( str.contains("' fully installed." ) || str.contains("' already up to date." ) ) )
{
String id = str.substring(str.indexOf("'")+1);
id = id.substring(0, id.indexOf("'"));
printText("AppID " + id + " downloaded successfully!");
clearDownload( id );
}
// process hangs up
else if( str.contains("Fatal assert failed"))
throw new RestartException();
// ..AppID %d:\n
// - release state: ...
else if( str.contains("AppID ") )
{
lastID = str.substring( str.indexOf("AppID ")+ 6, str.indexOf(':'));
}
// license status
else if( str.startsWith(" - release state: ") )
{
if( str.contains("Subscribed" ) )
{
setVerified( lastID );
printText("AppID " + lastID + " confirmed");
}
else if( str.contains("No License" ) )
{
verifyFail( lastID );
printText("AppID " + lastID + " HAS NO LICENSE");
// do not try to download it
clearDownload( lastID );
}
}
notification.contentView.setViewVisibility( R.id.status_progress, View.GONE );
printText(str);
}
// called on every char in line until return true
private boolean processPartial( String str ) throws CancelException, IOException
{
//printText(str);
{
if( str.contains( "Steam>" ) )
{
// not logged in yet
if( state == ProcessState.LAUNCH )
{
String login = promptDialog("Login", "Please enter your login", false);
if( login == null )
{
processInput.write( ( "exit\n").getBytes() );
throw new CancelException();
}
else
processInput.write( ( "login " + login + "\n").getBytes() );
}
// already logged in, send commands
else
{
state = ProcessState.COMMAND;
String cmd = null;
if( getVerify() != null )
cmd = "app_status " + getVerify();
else if( getDownload() != null )
cmd = "app_update " + getDownload() + " verify";
else
cmd = "exit";
if( cmd != null )
{
processInput.write( ( cmd + '\n').getBytes());
processInput.flush();
printText("cmd: " + cmd);
state = ProcessState.WAIT;
}
}
return true;
}
// user interaction
if( str.startsWith("password:" ))
{
String passwd = promptDialog("Password", "Please enter your password", true);
if( passwd == null )
{
processInput.write( ( "\n").getBytes() );
throw new CancelException();
}
else
processInput.write( (passwd + '\n').getBytes() );
return true;
}
if( str.startsWith("Steam Guard code:" )|| str.startsWith("Two-factor code:") )
{
String passwd = promptDialog("Steam Guard code", "Please enter your SteamGuard code", true);
if( passwd == null )
{
processInput.write( ( "\n").getBytes() );
throw new CancelException();
}
else
processInput.write( (passwd + '\n').getBytes() );
return true;
}
}
return false;
}
// launch procesc and process all outout
private int launchProcess( String command ) throws Exception
{
int result = 255;
printText("process start: " + command);
process = Runtime.getRuntime().exec( command );
InputStream reader = process.getInputStream();
processInput = process.getOutputStream();
BufferedReader readererr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
int ch;
boolean processed = false;
String str = "";
while ( !needDestroy.get() && ((ch = reader.read()) >= 0) ) {
if( ch == '\n' )
{
processLine( str );
str = "";
processed = false;
}
else
str += (char)ch;
// performance: skip comparsions on Update state lines
if( str == " " )
processed = true;
if( !processed )
processed = processPartial( str );
}
if(needDestroy.get())
throw new CancelException();
processLine( str );
printText("process closed stdout");
// flush err buffer
while( (str = readererr.readLine()) != null && !str.isEmpty() )
printText(str);
reader.close();
processInput.close();
// Waits for the command to finish.
if( process != null )
result = process.waitFor();
printText("process end: " + result);
return result;
}
final private String repoUrl = "https://raw.githubusercontent.com/mittorn/steamcmd-deps/master/";
// download from github repo
private void downloadDep( String path ) throws IOException,CancelException
{
downloadFile( repoUrl + path, localPath + path );
}
// make directories for local path
private void mkdirs( String path )
{
new File( localPath + path ).mkdirs();
}
// download all files if not yet downloaded
private void downloadAll() throws IOException,CancelException
{
if( !skipQemu && !new File( filesDir + "/qemu.downloaded").exists() )
{
File qemu = new File( filesDir + "/qemu");
if( qemu.exists() ) qemu.delete();
downloadFile( repoUrl + "qemu-armeabi-v7a", filesDir + "/qemu" );
new File( filesDir + "/qemu.downloaded").createNewFile();
}
if( new File( localPath + ".downloaded").exists() )
return;
mkdirs( "" );
downloadDep("gzip");
mkdirs( "lib" );
downloadDep( "lib/libc.so.6" );
downloadDep( "lib/libdl.so.2" );
downloadDep( "lib/libgcc_s.so.1" );
downloadDep( "lib/libm.so.6" );
downloadDep( "lib/libnss_dns.so.2" );
downloadDep( "lib/libpthread.so.0" );
downloadDep( "lib/libresolv.so.2" );
downloadDep( "lib/librt.so.1" );
mkdirs( "linux32" );
downloadDep( "linux32/ld-linux.so.2" );
downloadDep( "preload.so" );
mkdirs( "sources" );
downloadDep( "sources/debian.txt" );
downloadDep( "sources/qemu.patch" );
downloadDep( "sources/qemu.txt" );
downloadDep( "sources/preload.c" );
downloadDep( "tar" );
downloadDep( "killall" );
if( skipQemu )
downloadDep( "start-x86.sh" );
else
downloadDep( "start-qemu.sh" );
downloadFile( "http://media.steampowered.com/client/installer/steamcmd_linux.tar.gz", localPath + "steamcmd_linux.tar.gz" );
new File( localPath + ".downloaded").createNewFile();
}
private int launchX86(String command) throws Exception
{
if( skipQemu )
return launchProcess( "sh " + localPath + "start-x86.sh " + localPath + ' ' + command );
else
return launchProcess( "sh " + localPath + "start-qemu.sh " + localPath + " "+ filesDir + "/qemu " + command );
}
private void unpackAll() throws Exception
{
launchProcess( "chmod 777 " + filesDir + "/qemu" );
if( new File( localPath + ".unpacked").exists() )
return;
launchX86( localPath + "gzip -d steamcmd_linux.tar.gz" );
launchX86( localPath + "tar xvf steamcmd_linux.tar" );
new File( localPath + "steamcmd_linux.tar" ).delete();
new File( localPath + ".unpacked").createNewFile();
}
@Override
public void run() {
super.run();
needDestroy.getAndSet(false);
try {
if( skipQemu = isX86() )
localPath = filesDir + '/';
state = ProcessState.UNPACK;
downloadAll();
unpackAll();
int result;
do{
state = ProcessState.LAUNCH;
killAll();
if( need_reset_config )
try{
new File( localPath + "Steam/config/config.vdf" ).delete();
}
catch( Exception e) {}
try
{
result = launchX86( localPath + "linux32/steamcmd" );
}
catch( RestartException e )
{
// 42 is restart magick in steam
result = 42;
}
needDestroy.getAndSet(false);
}
while( result == 42 || getVerify() != null || getDownload() != null ) ;
} catch (Exception e) {
printText("Fatal: " + e.toString() + ": "+ e.getMessage());
e.printStackTrace();
needDestroy.getAndSet(false);
killAll();
}
finally{}
printText("Background thread end!");
mBgThread = null;
needDestroy.getAndSet(false);
stopSelf();
//return null;
}
public void killAll()
{
// kill old processes, but only if they were running more
// than 2 seconds to keep killall itself
try
{
if( skipQemu )
launchX86( localPath + "killall -o5s -9 ld-linux.so.2" );
else
launchX86( localPath + "killall -o5s -9 qemu" );
}
catch( Exception e ){}
}
}
public void cancelThread()
{
if( mBgThread == null )
return;
try
{
silentKillAll();
mBgThread.needDestroy.getAndSet(true);
mBgThread.interrupt();
// destroy process
if( mBgThread.process != null )
mBgThread.process.destroy();
// cancel stalled download
if( mBgThread.httpInput != null )
mBgThread.httpInput.close();
}catch( Exception e ){
e.printStackTrace();
}
}
private boolean isX86()
{
String s = System.getProperty("ro.product.cpu.abi");
if( s != null && s.contains("x86"))
return true;
s = System.getProperty("ro.product.cpu.abi2");
if( s != null && s.contains("x86"))
return true;
s = System.getProperty("ro.product.cpu.abilist");
if( s != null && s.contains("x86"))
return true;
s = System.getProperty("ro.product.cpu.abilist32");
if( s != null && s.contains("x86"))
return true;
s = System.getProperty("ro.dalvik.vm.isa.arm");
if( s != null && s.contains("x86"))
return true;
return false;
}
public void silentKillAll()
{
try
{
if( isX86() )
Runtime.getRuntime().exec( "sh " + localPath + "start-x86.sh " + localPath + ' ' +
localPath + "killall -o5s -9 ld-linux.so.2" );
else
Runtime.getRuntime().exec( "sh " + localPath + "start-qemu.sh " + localPath + " " +
filesDir + "/qemu " + localPath + "killall -o5s -9 qemu" );
}
catch( Exception e ){
e.printStackTrace();
}
}
}

View file

@ -1,493 +0,0 @@
package in.celest.xash3d;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.*;
import android.app.*;
import android.content.*;
import android.view.*;
import android.os.*;
import android.util.Log;
import android.graphics.*;
import android.text.method.*;
import android.text.*;
import android.media.*;
import android.hardware.*;
import android.content.*;
import java.lang.*;
/**
SDL Activity
*/
public class XashActivity extends Activity {
// Main components
protected static XashActivity mSingleton;
private static EngineSurface mSurface;
private static String mArgv;
// Audio
private static Thread mAudioThread;
private static AudioTrack mAudioTrack;
// Load the .so
static {
System.loadLibrary("xash");
}
// Setup
protected void onCreate(Bundle savedInstanceState) {
//Log.v("SDL", "onCreate()");
super.onCreate(savedInstanceState);
// So we can call stuff from static callbacks
mSingleton = this;
Intent intent = getIntent();
// mArgv = intent.getStringExtra(in.celest.xash3d.LauncherActivity.ARGV);
// Set up the surface
mSurface = new EngineSurface(getApplication());
setContentView(mSurface);
SurfaceHolder holder = mSurface.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
// Events
protected void onPause() {
//Log.v("SDL", "onPause()");
super.onPause();
}
protected void onResume() {
//Log.v("SDL", "onResume()");
super.onResume();
}
// Messages from the SDLMain thread
static int COMMAND_CHANGE_TITLE = 1;
// Handler for the messages
Handler commandHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.arg1 == COMMAND_CHANGE_TITLE) {
setTitle((String)msg.obj);
}
}
};
// Send a message from the SDLMain thread
void sendCommand(int command, Object data) {
Message msg = commandHandler.obtainMessage();
msg.arg1 = command;
msg.obj = data;
commandHandler.sendMessage(msg);
}
public static String[] getArguments()
{
return mArgv.split(" ");
}
// C functions we call
public static native int nativeInit(Object arguments);
public static native void nativeQuit();
public static native void onNativeResize(int x, int y);
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
public static native void onNativeAccel(float x, float y, float z);
public static native void nativeRunAudioThread();
// Java functions called from C
public static boolean createGLContext() {
return mSurface.InitGL();
}
public static void swapBuffers() {
mSurface.SwapBuffers();
}
public static void setActivityTitle(String title) {
// Called from SDLMain() thread and can't directly affect the view
mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
}
public static Context getContext() {
return mSingleton;
}
// Audio
private static Object buf;
public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
// Let the user pick a larger buffer if they really want -- but ye
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
audioStartThread();
Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
if (is16Bit) {
buf = new short[desiredFrames * (isStereo ? 2 : 1)];
} else {
buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
}
return buf;
}
public static void audioStartThread() {
mAudioThread = new Thread(new Runnable() {
public void run() {
mAudioTrack.play();
nativeRunAudioThread();
}
});
// I'd take REALTIME if I could get it!
mAudioThread.setPriority(Thread.MAX_PRIORITY);
mAudioThread.start();
}
public static void audioWriteShortBuffer(short[] buffer) {
for (int i = 0; i < buffer.length; ) {
int result = mAudioTrack.write(buffer, i, buffer.length - i);
if (result > 0) {
i += result;
} else if (result == 0) {
try {
Thread.sleep(1);
} catch(InterruptedException e) {
// Nom nom
}
} else {
Log.w("SDL", "SDL audio: error return from write(short)");
return;
}
}
}
public static void audioWriteByteBuffer(byte[] buffer) {
for (int i = 0; i < buffer.length; ) {
int result = mAudioTrack.write(buffer, i, buffer.length - i);
if (result > 0) {
i += result;
} else if (result == 0) {
try {
Thread.sleep(1);
} catch(InterruptedException e) {
// Nom nom
}
} else {
Log.w("SDL", "SDL audio: error return from write(short)");
return;
}
}
}
public static void audioQuit() {
if (mAudioThread != null) {
try {
mAudioThread.join();
} catch(Exception e) {
Log.v("SDL", "Problem stopping audio thread: " + e);
}
mAudioThread = null;
//Log.v("SDL", "Finished waiting for audio thread");
}
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack = null;
}
}
}
/**
Simple nativeInit() runnable
*/
class XashMain implements Runnable {
public void run() {
// Runs SDL_main()
XashActivity.createGLContext();
XashActivity.nativeInit(XashActivity.getArguments());
//Log.v("SDL", "SDL thread terminated");
}
}
/**
SDLSurface. This is what we draw on, so we need to know when it's created
in order to do anything useful.
Because of this, that's where we set up the SDL thread
*/
class EngineSurface extends SurfaceView implements SurfaceHolder.Callback,
View.OnKeyListener, View.OnTouchListener {
// This is what SDL runs in. It invokes SDL_main(), eventually
private Thread mEngThread;
// EGL private objects
private EGLContext mEGLContext;
private EGLSurface mEGLSurface;
private EGLDisplay mEGLDisplay;
// Sensors
// Startup
public EngineSurface(Context context) {
super(context);
getHolder().addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
setOnKeyListener(this);
setOnTouchListener(this);
}
// Called when we have a valid drawing surface
public void surfaceCreated(SurfaceHolder holder) {
//Log.v("SDL", "surfaceCreated()");
}
// Called when we lose the surface
public void surfaceDestroyed(SurfaceHolder holder) {
//Log.v("SDL", "surfaceDestroyed()");
// Send a quit message to the application
XashActivity.nativeQuit();
// Now wait for the SDL thread to quit
if (mEngThread != null) {
try {
mEngThread.join();
} catch(Exception e) {
Log.v("SDL", "Problem stopping thread: " + e);
}
mEngThread = null;
//Log.v("SDL", "Finished waiting for SDL thread");
}
}
// Called when the surface is resized
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
//Log.v("SDL", "surfaceChanged()");
/*
int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) {
case PixelFormat.A_8:
Log.v("SDL", "pixel format A_8");
break;
case PixelFormat.LA_88:
Log.v("SDL", "pixel format LA_88");
break;
case PixelFormat.L_8:
Log.v("SDL", "pixel format L_8");
break;
case PixelFormat.RGBA_4444:
Log.v("SDL", "pixel format RGBA_4444");
sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
break;
case PixelFormat.RGBA_5551:
Log.v("SDL", "pixel format RGBA_5551");
sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
break;
case PixelFormat.RGBA_8888:
Log.v("SDL", "pixel format RGBA_8888");
sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
break;
case PixelFormat.RGBX_8888:
Log.v("SDL", "pixel format RGBX_8888");
sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
break;
case PixelFormat.RGB_332:
Log.v("SDL", "pixel format RGB_332");
sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
break;
case PixelFormat.RGB_565:
Log.v("SDL", "pixel format RGB_565");
sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
break;
case PixelFormat.RGB_888:
Log.v("SDL", "pixel format RGB_888");
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
break;
default:
Log.v("SDL", "pixel format unknown " + format);
break;
}*/
XashActivity.onNativeResize(width, height);
// Now start up the C app thread
if (mEngThread == null) {
mEngThread = new Thread(new XashMain(), "EngineThread");
mEngThread.start();
}
}
// unused
public void onDraw(Canvas canvas) {}
// EGL functions
public boolean InitGL() {
try {
EGL10 egl = (EGL10)EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
egl.eglInitialize(dpy, version);
int[] configSpec = {
EGL10.EGL_DEPTH_SIZE, 8,
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, 1,
EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) {
Log.e("SDL", "No EGL config available");
return false;
}
EGLConfig config = configs[0];
int EGL_CONTEXT_CLIENT_VERSION=0x3098;
int contextAttrs[] = new int[]
{
EGL_CONTEXT_CLIENT_VERSION, 1,
EGL10.EGL_NONE
};
EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, contextAttrs);
if (ctx == EGL10.EGL_NO_CONTEXT) {
Log.e("SDL", "Couldn't create context");
return false;
}
EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null);
if (surface == EGL10.EGL_NO_SURFACE) {
Log.e("SDL", "Couldn't create surface");
return false;
}
if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) {
Log.e("SDL", "Couldn't make context current");
return false;
}
mEGLContext = ctx;
mEGLDisplay = dpy;
mEGLSurface = surface;
} catch(Exception e) {
Log.v("SDL", e + "");
for (StackTraceElement s : e.getStackTrace()) {
Log.v("SDL", s.toString());
}
}
return true;
}
// EGL buffer flip
public void SwapBuffers() {
try {
EGL10 egl = (EGL10)EGLContext.getEGL();
egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
// drawing here
egl.eglWaitGL();
egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
} catch(Exception e) {
Log.v("SDL", "flipEGL(): " + e);
for (StackTraceElement s : e.getStackTrace()) {
Log.v("SDL", s.toString());
}
}
}
// Key events
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//Log.v("SDL", "key down: " + keyCode);
//XashActivity.controlInterp.onKeyDown(keyCode, event);
return true;
}
else if (event.getAction() == KeyEvent.ACTION_UP) {
//Log.v("SDL", "key up: " + keyCode);
// XashActivity.controlInterp.onKeyUp(keyCode, event);
return true;
}
return false;
}
// Touch events
public boolean onTouch(View v, MotionEvent event) {
/*
final int touchDevId = event.getDeviceId();
final int pointerCount = event.getPointerCount();
// touchId, pointerId, action, x, y, pressure
int actionPointerIndex = event.getActionIndex();
int pointerFingerId = event.getPointerId(actionPointerIndex);
int action = event.getActionMasked();
float x = event.getX(actionPointerIndex);
float y = event.getY(actionPointerIndex);
float p = event.getPressure(actionPointerIndex);
if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
// TODO send motion to every pointer if its position has
// changed since prev event.
for (int i = 0; i < pointerCount; i++) {
pointerFingerId = event.getPointerId(i);
x = event.getX(i);
y = event.getY(i);
p = event.getPressure(i);
XashActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
} else {
XashActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
}*/
//XashActivity.controlInterp.onTouchEvent(event);
return true;
}
}

View file

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<ImageView android:id="@+id/status_icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_marginRight="10dp"/>
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toRightOf="@id/status_icon">
<TextView android:id="@+id/status_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
<ProgressBar android:id="@+id/status_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/status_text"
android:indeterminate="false"
android:indeterminateOnly="false"
style="?android:attr/progressBarStyleHorizontal" />
</RelativeLayout>
</RelativeLayout>

File diff suppressed because it is too large Load diff

View file

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="launch_button">Xash3D starten!</string>
<string name="cmd_args_text">Command line arguments(experts only)</string>
<string name="use_controls">Touch Kontroller aktivieren</string>
<string name="use_volume">Lautstärketasten verwenden</string>
<string name="text_res_path">Pfad zu Spiele Ressourcen</string>
<string name="touch_set">Kontroller Einstellungen</string>
<string name="text_shortcut">Xash3D Kurzbefehl</string>
<string name="text_shortcut_test">Xash3D_test Kurzbefehl</string>
<string name="shortcut_button_save">Kurzbefehl speichern</string>
<string name="gamedir">Mod Verzeichnis</string>
<string name="pkgname">Mod Paketname (Expert)</string>
<string name="shortcut_name">Kurzbefehl Name</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="about_copyright">FWGS steht in keinem Zusammenhang zu Valve oder einem ihrer Partners. All copyrights reserved to their respective owners.</string>
<string name="about_authors">Portierung auf Android by FWGS team: \n
&#8226; a1batross\n
&#8226; mittorn \n
&#8226; nicknekit.\n
Spezieller Dank an:\n
&#8226; Uncle Mike für Xash3D engine\n
&#8226; Valve for Half-Life\n</string>
<string name="about_links">Folge uns auf:\n
&#8226; <a href="https://vk.com/xashdroid">VK</a>\n
&#8226; <a href="http://moddb.com/game/xash3d-android">ModDB</a>\n
&#8226; <a href="https://github.com/FWGS">GitHub</a></string>
<string name="about_button">Über Xash3D Android</string>
<string name="create_shortcut_button">mod Kurzbefehl ersellen</string>
<string name="select_folder">(auswahl)</string>
<string name="action_settings">Einstellungen</string>
</resources>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="launch_button">¡Iniciar Xash3D!</string>
<string name="cmd_args_text">Parámetros de línea de comandos(sólo expertos)</string>
<string name="use_controls">Activar controles táctiles</string>
<string name="use_volume">Usar botones de volumen</string>
<string name="text_res_path">Ruta de los archivos del juego</string>
<string name="touch_set">Configurar controles</string>
<string name="text_shortcut">Acceso directo Xash3D</string>
<string name="text_shortcut_test">Acceso directo Xash3D_test</string>
<string name="shortcut_button_save">Guardar acceso directo</string>
<string name="gamedir">Directorio del mod</string>
<string name="pkgname">Nombre del paquete del mod (sólo expertos)</string>
<string name="shortcut_name">Nombre del acceso directo</string>
<string name="about_copyright">FWGS no está afiliado con Valve o cualquiera de sus socios. Todos los derechos reservados a sus respectivos dueños.</string>
<string name="about_authors">Adaptación para Android por FWGS team: \n
&#8226; a1batross\n
&#8226; mittorn \n
&#8226; nicknekit.\n
Especial agradecimiento a:\n
&#8226; Uncle Mike por Xash3D engine\n
&#8226; Valve por Half-Life\n
</string>
<string name="about_links">Siguenos en: \n
&#8226; <a href="https://vk.com/xashdroid">VK</a>\n
&#8226; <a href="http://moddb.com/game/xash3d-android">ModDB</a>\n
&#8226; <a href="https://github.com/FWGS">GitHub</a></string>
<string name="about_button">Acerca de Xash3D Android</string>
<string name="create_shortcut_button">Crear acceso directo del mod</string>
<string name="select_folder">(seleccionar)</string>
</resources>

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="launch_button">!Xash3Dاجرای</string>
<string name="cmd_args_text">دستورات خط فرمان (فقط برای حرفه ای ها):</string>
<string name="use_controls">فعال کردن کنترل های لمسی</string>
<string name="use_volume">استفاده از دکمه های صدا</string>
<string name="text_res_path">مسیر منابع بازی:</string>
<string name="touch_set">تنظیمات کنترل:</string>
<string name="text_shortcut">Xash3D میانبر</string>
<string name="text_shortcut_test">Xash3D_test shortcut</string>
<string name="shortcut_button_save">ذخیره میانبر</string>
<string name="gamedir">مسیر مود</string>
<string name="pkgname">نام بسته مود (فقط برای حرفه ای ها):</string>
<string name="shortcut_name">نام میانبر</string>
<string name="about_copyright">یا شرکای آن ندارد. تمامی حقوق کپی برای صاحبان هر کدام محفوظ است. Valve هیچ نسبتی با FWGS</string>
<string name="about_authors">:FWGS پورت شده به اندروید توسط تیم \n • a1batross\n • mittorn \n • nicknekit.\n تشکر ویژه از:\n • Xash3Dبرای موتور Uncle Mike\n • Half-Life برای Valve\n</string>
<string name="about_links">ما را دنبال کنید در :\n •<a href="https://vk.com/xashdroid">VK</a>\n•<a href="http://moddb.com/game/xash3d-android">ModDB</a>\n•<a href="https://github.com/FWGS">GitHub</a></string>
<string name="about_button">Xash3D Android درباره</string>
<string name="create_shortcut_button">ایجاد میانبر مود</string>
<string name="select_folder">(انتخاب)</string>
</resources>

View file

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="common_google_play_services_notification_ticker">Google Play 서비스 오류</string>
<string name="common_google_play_services_install_title">Google Play 서비스 설치</string>
<string name="app_name">Xash3D</string>
<string name="launcher_name">Xash3D</string>
<string name="launcher_name_test">Xash3D (테스트)</string>
<string name="launch_button">Xash3D 실행!</string>
<string name="cmd_args_text">커멘드 라인 입력(고급설정)</string>
<string name="text_res_path">게임 리소스 경로</string>
<string name="touch_set">컨트롤 설정</string>
<string name="text_shortcut">Xash3D 바로가기</string>
<string name="text_shortcut_test">Xash3D_테스트 바로가기</string>
<string name="shortcut_button_save">바로가기 생성</string>
<string name="gamedir">모드 디렉토리</string>
<string name="pkgname">모드 패키지(고급설정)</string>
<string name="shortcut_name">바로가기 이름</string>
<string name="about_main">Xash3D 안드로이드</string>
<string name="about_copyright">FWGS는 밸브와 그와 관련된 상업적 관련이 없습니다. 모든 저작권은 그들 각각의 소유자에게 있습니다.</string>
<string name="about_authors">안드로이드 포팅 by FWGS team: \n • a1batross\n • mittorn \n • nicknekit.\n 특별히 감사드리는 분들:\n • Uncle Mike 의 Xash3D 엔진\n • Valve의 Half-Life\n •한글화 SJ Wilson from X3A NaverCafe</string>
<string name="about_links"> 공식 사이트: \n • VK\n • ModDB\n • GitHub \n • X3A</string>
<string name="about_button">정보</string>
<string name="create_shortcut_button">모드 바로가기 만들기</string>
<string name="select_folder">(찾기)</string>
<string name="text_tab1">일반</string>
<string name="text_tab2">고급</string>
<string name="text_res_tittle2">일반 설정</string>
<string name="text_res_tittle3">고급 설정</string>
<string name="volume">볼륨 버튼 모드</string>
<string name="use_volume">볼륨키 사용</string>
<string name="no_volume">인게임 설정</string>
<string name="folder">현재 폴더로 설정</string>
<string name="update_button">시작할때마다 업데이트 확인</string>
<string name="update_to_beta">가능하면 불완전한 버전으로 업데이트</string>
<string name="update_message">%s 버전으로 업데이트 했습니다! 지금 다운로드 하세요!</string>
<string name="update">업데이트</string>
<string name="cancel">취소</string>
<string name="no_updates">이미 최신버전을 사용하고 있습니다.</string>
<string name="checking_updates">구동...</string>
<string name="immersive_mode">몰입모드 허용(전체화면, 안드로이드 킷캣 이상)</string>
</resources>

View file

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="launch_button">Iniciar Xash3D!</string>
<string name="cmd_args_text">Argumentos de linha de comando(apenas expecialistas)</string>
<string name="use_controls">Habilitar controles de touch</string>
<string name="use_volume">Use as teclas de volume</string>
<string name="text_res_path">Diretório para recursos do jogo</string>
<string name="touch_set">Configurações de controle</string>
<string name="text_shortcut">Atalho Xash3D</string>
<string name="text_shortcut_test">Atalho Xash3D_test</string>
<string name="shortcut_button_save">Salvar atalho</string>
<string name="gamedir">Diretório do Mod</string>
<string name="pkgname">Nome do pacote de Mod (apenas expecialistas)</string>
<string name="shortcut_name">Nome do atalho</string>
<string name="about_copyright">FWGS não é afiliado com a Valve ou qualquer um dos seus parceiros. Todos os direitos autorais reservados aos respectivos proprietários.</string>
<string name="about_authors">Porta para android pelo time FWGS: \n
&#8226; a1batross\n
&#8226; mittorn \n
&#8226; nicknekit.\n
Agradecimentos especiais para:\n
&#8226; Uncle Mike pelo motor Xash3D\n
&#8226; Valve pelo Half-Life\n</string>
<string name="about_links">Siga-nos no:\n
&#8226; <a href="https://vk.com/xashdroid">VK</a>\n
&#8226; <a href="http://moddb.com/game/xash3d-android">ModDB</a>\n
&#8226; <a href="https://github.com/FWGS">GitHub</a></string>
<string name="about_button">Sobre Android Xash3D</string>
<string name="create_shortcut_button">Criar atalho para o mod</string>
<string name="select_folder">(selecionar)</string>
</resources>

View file

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="launch_button">Xash3D\'yi Başlat!</string>
<string name="cmd_args_text">Komut satırı parametreleri(uzmanlar için)</string>
<string name="use_controls">Dokunmatik kontrolleri etkinleştir</string>
<string name="use_volume">Ses ayarı tuşlarını kullan</string>
<string name="text_res_path">Oyun dosyalarının yolu</string>
<string name="touch_set">Kontrol ayarları</string>
<string name="text_shortcut">Xash3D kısayolu</string>
<string name="text_shortcut_test">Xash3D_test kısayolu</string>
<string name="shortcut_button_save">Kısayolu kaydet</string>
<string name="gamedir">Mod\'un dizini</string>
<string name="pkgname">Mod\'un paket adı (uzmanlar için)</string>
<string name="shortcut_name">Kısayol adı</string>
<string name="about_copyright">FWGS, Valve veya Valve\'ın herhangi bir partnerine bağlı değildir. Tüm telif hakları kendi sahiplerine aittir.</string>
<string name="about_authors">FWGS takımından Android Port\'u: \n
&#8226; a1batross\n
&#8226; mittorn \n
&#8226; nicknekit.\n
Özel teşekkürler:\n
&#8226; Uncle Mike for Xash3D engine\n
&#8226; Valve for Half-Life\n/
</string>
<string name="about_links">Bizi buralardan takip edin: \n
&#8226; <a href="https://vk.com/xashdroid">VK</a>\n
&#8226; <a href="http://moddb.com/game/xash3d-android">ModDB</a>\n
&#8226; <a href="https://github.com/FWGS">GitHub</a>\
</string>
<string name="about_button">Xash3D Android Hakkında</string>
<string name="create_shortcut_button">Mod kısayolu oluştur</string>
<string name="select_folder">(seç)</string>
</resources>

View file

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="launch_button">Запустити Xash3D</string>
<string name="cmd_args_text">Аргументи командного рядка(тільки для експертів)</string>
<string name="use_controls">Увімкнути наекранне керування</string>
<string name="use_volume">Використовувати клавіші гучності</string>
<string name="text_res_path">Каталог ресурсів гри</string>
<string name="touch_set">Налаштування керування</string>
<string name="text_shortcut">Ярлик Xash3D</string>
<string name="text_shortcut_test">Ярлик Xash3D_test</string>
<string name="shortcut_button_save">Зберегти ярлик</string>
<string name="gamedir">Каталог модифікації</string>
<string name="pkgname">Пакет модифікації(тільки для експертів)</string>
<string name="shortcut_name">Назва ярлика</string>
<string name="about_copyright">FWGS не пов\'язаний з Valve або з будь-якими з їх партнерів. Всі авторські права належать їх відповідним власникам.</string>
<string name="about_authors">Порт на Android здійснений командою FWGS:\n
&#8226; a1batross\n
&#8226; mittorn\n
&#8226; nicknekit\n
Особливі подяки:\n
&#8226; Дяде Мише за Xash3D\n
&#8226; Valve за Half-Life\n</string>
<string name="about_links">Слідкуйте за нами в:\n
&#8226; <a href="https://vk.com/xashdroid">VK</a>\n
&#8226; <a href="http://moddb.com/game/xash3d-android">ModDB</a>\n
&#8226; <a href="https://github.com/FWGS">GitHub</a></string>
<string name="about_button">Про Xash3D Android</string>
<string name="create_shortcut_button">Створити ярлик модифікації</string>
<string name="select_folder">(обрати)</string>
</resources>

Some files were not shown because too many files have changed in this diff Show more