2
0
mirror of https://github.com/FWGS/xash3d-fwgs synced 2024-11-25 11:19:59 +01:00

Added Touchscreen control by Emile Belanger

This commit is contained in:
Emile Belanger 2015-05-19 10:42:14 +01:00
parent 69974c6bf9
commit c9c7c268d0
70 changed files with 3589 additions and 174 deletions

4
assets/License.txt Normal file
View File

@ -0,0 +1,4 @@
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

BIN
assets/arrow_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/arrow_left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/arrow_right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/arrow_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/bstone_ps_config Normal file

Binary file not shown.

BIN
assets/crouch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
assets/enter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
assets/gamma.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/jump.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/key_+.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/key_-.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
assets/key_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
assets/key_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/key_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/key_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
assets/key_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
assets/key_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/key_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/key_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/key_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
assets/key_9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/key_f1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
assets/key_f10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
assets/keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
assets/look_arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
assets/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/next_weap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
assets/prev_weap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
assets/red_cross.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
assets/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
assets/settings_bars.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/shoot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
assets/show_weapons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
assets/strafe_arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
assets/use.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,21 +1,29 @@
# Uncomment this if you're using STL in your project
# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
# APP_STL := stlport_static
APPLICATIONMK_PATH = $(call my-dir)
SDL_PATH := $(APPLICATIONMK_PATH)/src/SDL2
#SDL_IMAGE_PATH := $(APPLICATIONMK_PATH)/src/SDL2_image/
NANOGL_PATH := $(APPLICATIONMK_PATH)/src/NanoGL/nanogl
XASH3D_PATH := $(APPLICATIONMK_PATH)/src/Xash3D/xash3d
XASHXT_PATH := $(APPLICATIONMK_PATH)/src/XashXT/XashXT
HLSDK_PATH := $(APPLICATIONMK_PATH)/src/HLSDK/halflife/
APP_ABI := armeabi-v7a x86
APP_MODULES := SDL2 xash menu client server NanoGL
# Uncomment this if you're using STL in your project
# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
APP_STL := stlport_static
APPLICATIONMK_PATH = $(call my-dir)
ifeq ($(EMILE),1)
SDL_PATH := $(APPLICATIONMK_PATH)/src/SDL-mirror
else
SDL_PATH := $(APPLICATIONMK_PATH)/src/SDL2
endif
TOUCHCONTROLS_PATH := $(APPLICATIONMK_PATH)/src/MobileTouchControls
NANOGL_PATH := $(APPLICATIONMK_PATH)/src/NanoGL/nanogl
XASH3D_PATH := $(APPLICATIONMK_PATH)/src/Xash3D/xash3d
XASHXT_PATH := $(APPLICATIONMK_PATH)/src/XashXT/XashXT
HLSDK_PATH := $(APPLICATIONMK_PATH)/src/HLSDK/halflife/
APP_ABI := armeabi-v7a x86
APP_MODULES := SDL2 xash menu client server NanoGL

View File

@ -1 +0,0 @@
/home/a1ba/projects/Xash3D/halflife

@ -0,0 +1 @@
Subproject commit c3b365fe0831e68199bb39e9f565ca724c7cc430

View File

@ -1 +0,0 @@
/home/a1ba/projects/Xash3D/nanogl

1
jni/src/NanoGL/nanogl Submodule

@ -0,0 +1 @@
Subproject commit 63045ea16759232df455140efd8d5ed67986882d

View File

@ -1 +0,0 @@
/home/a1ba/projects/Xash3D/xash3d

1
jni/src/Xash3D/xash3d Submodule

@ -0,0 +1 @@
Subproject commit 215d7a35d99850dcbc38d37fb8fe9b4166fefcf3

View File

@ -1 +0,0 @@
/home/a1ba/projects/Xash3D/XashXT

1
jni/src/XashXT/XashXT Submodule

@ -0,0 +1 @@
Subproject commit 33130cade1af08c7ed12479f0e0ecab489851972

BIN
libs/com.bda.controller.jar Normal file

Binary file not shown.

BIN
res/drawable/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
res/drawable/cog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
res/drawable/gamepad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
res/drawable/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
res/drawable/joystick.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,17 @@
<?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"
android:color="@android:color/holo_blue_light" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>

View File

@ -0,0 +1,42 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/joystick" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_toRightOf="@+id/imageView"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/name_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/binding_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/tertiary_text_dark" />
</LinearLayout>
<ImageView
android:id="@+id/settings_imageview"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:background="@drawable/cog" />
</RelativeLayout>

View File

@ -0,0 +1,34 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/joystick" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@+id/imageView"
android:orientation="vertical" >
<TextView
android:id="@+id/name_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<ToggleButton
android:id="@+id/hidden_switch"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp" />
</RelativeLayout>

View File

@ -0,0 +1,49 @@
<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="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/gamepad_enable_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enable Game Pad" />
<CheckBox
android:id="@+id/gamepad_hide_touch_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hide Touch Controls" />
<Button
android:id="@+id/gamepad_help_button"
style="@android:style/Animation"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="10dp"
android:background="@drawable/help" />
<TextView
android:id="@+id/gamepad_info_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<ListView
android:id="@+id/gamepad_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dividerHeight="10dp" >
</ListView>
</LinearLayout>

View File

@ -0,0 +1,221 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="500dp"
android:orientation="vertical" >
<Button
android:id="@+id/add_remove_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add/remove buttons" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fwd/Back:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<SeekBar
android:id="@+id/fwd_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="100" />
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Strafe:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<SeekBar
android:id="@+id/strafe_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="100" />
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Look Up/Down:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<SeekBar
android:id="@+id/pitch_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="100" />
</TableRow>
<TableRow
android:id="@+id/tableRow4"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Turn:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<SeekBar
android:id="@+id/yaw_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="100" />
</TableRow>
<TableRow
android:id="@+id/tableRow5"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Transparency:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<SeekBar
android:id="@+id/alpha_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="100" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/mouse_turn_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="&apos;Mouse&apos; mode turning" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/invert_loop_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invert Look" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/precision_shoot_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Precision Shoot" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/show_next_weapon_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Next/Prev Weapon" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/show_sticks_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Movement arrows" />
</TableRow>
<TableRow>
<CheckBox
android:id="@+id/enable_weapon_wheel_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enable Weapon Wheel" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Double tap Move:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Spinner
android:id="@+id/move_dbl_tap_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Double tap Look:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Spinner
android:id="@+id/look_dbl_tap_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/save_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Save" />
<Button
android:id="@+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel" />
</LinearLayout>
</TableLayout>
</LinearLayout>
</ScrollView>

View File

@ -1,4 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Half-life</string>
<string-array name="double_tap_actions">
<item>None</item>
<item>Shoot</item>
<item>Jump</item>
<item>Use</item>
</string-array>
</resources>

View File

@ -0,0 +1,364 @@
/*
* Copyright (C) 2009 jeyries@yahoo.fr
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.beloko.games.hl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import org.libsdl.app.SDLActivity;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.StateEvent;
import com.beloko.idtech.AppSettings;
import com.beloko.idtech.BestEglChooser;
import com.beloko.idtech.CDAudioPlayer;
import com.beloko.idtech.MyGLSurfaceView;
import com.beloko.idtech.Utils;
import com.beloko.libsdl.SDLLib;
import com.beloko.touchcontrols.FPSLimit;
import com.beloko.touchcontrols.ControlInterpreter;
import com.beloko.touchcontrols.Settings;
import com.beloko.touchcontrols.QuakeCustomCommands;
import com.beloko.touchcontrols.TouchControlsSettings;
import com.beloko.touchcontrols.Settings.IDGame;
public class Game extends Activity
implements Handler.Callback
{
String LOG = "Quake2";
private ControlInterpreter controlInterp;
private final MogaControllerListener mogaListener = new MogaControllerListener();
Controller mogaController = null;
private String args;
private String gamePath;
private GameView mGLSurfaceView = null;
private QuakeRenderer mRenderer = new QuakeRenderer();
Activity act;
int surfaceWidth,surfaceHeight;
int useGL;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
act = this;
AppSettings.setGame(IDGame.Wolf3d);
AppSettings.reloadSettings(getApplication());
args = getIntent().getStringExtra("args");
gamePath = getIntent().getStringExtra("game_path");
useGL = getIntent().getIntExtra("use_gl", 0);
handlerUI = new Handler(this);
mogaController = Controller.getInstance(this);
mogaController.init();
mogaController.setListener(mogaListener,new Handler());
//Log.i( "Quake2", "version : " + getVersion());
// fullscreen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// keep screen on
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
start_quake2();
}
/// Handler for asynchronous message
/// => showDialog
private Handler handlerUI ;
public static final int MSG_SHOW_DIALOG = 1;
// implements Handler.Callback
@Override
public boolean handleMessage(Message msg) {
Log.i( "Quake2", String.format("handleMessage %d %d", msg.what, msg.arg1));
switch( msg.what ){
case MSG_SHOW_DIALOG:
showDialog(msg.arg1);
break;
}
return true;
}
/////////////////////////////
public void start_quake2() {
NativeLib.loadLibraries(useGL == 1);
NativeLib engine = new NativeLib();
NativeLib.loadLibraries(false);
controlInterp = new ControlInterpreter(engine,Settings.IDGame.Doom,AppSettings.gamePadControlsFile,AppSettings.gamePadEnabled);
TouchControlsSettings.setup(act, engine);
TouchControlsSettings.loadSettings(act);
TouchControlsSettings.sendToQuake();
QuakeCustomCommands.setup(act, engine,getIntent().getStringExtra("main_qc"),getIntent().getStringExtra("mod_qc"));
// Create our Preview view and set it as the content of our
// Activity
mGLSurfaceView = new GameView(this);
NativeLib.gv = mGLSurfaceView;
//if (renderType == NativeLib.REND_SOFT) //SDL software mode uses gles2
if (useGL == 1)
mGLSurfaceView.setEGLContextClientVersion(2); // enable OpenGL 2.0
//mGLSurfaceView.setGLWrapper( new MyWrapper());
//mGLSurfaceView.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS);
//setEGLConfigChooser (int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize)
//mGLSurfaceView.setEGLConfigChooser(8,8,8,0,16,0);
mGLSurfaceView.setEGLConfigChooser( new BestEglChooser(getApplicationContext()) );
mGLSurfaceView.setRenderer(mRenderer);
// This will keep the screen on, while your view is visible.
mGLSurfaceView.setKeepScreenOn(true);
setContentView(mGLSurfaceView);
mGLSurfaceView.requestFocus();
mGLSurfaceView.setFocusableInTouchMode(true);
}
@Override
protected void onPause() {
Log.i( "Quake2.java", "onPause" );
CDAudioPlayer.onPause();
SDLLib.onPause();
mogaController.onPause();
super.onPause();
}
@Override
protected void onResume() {
Log.i( "Quake2.java", "onResume" );
CDAudioPlayer.onResume();
SDLLib.onResume();
mogaController.onResume();
super.onResume();
mGLSurfaceView.onResume();
}
@Override
protected void onDestroy() {
Log.i( "Quake2.java", "onDestroy" );
super.onDestroy();
mogaController.exit();
System.exit(0);
}
class MogaControllerListener implements ControllerListener {
@Override
public void onKeyEvent(com.bda.controller.KeyEvent event) {
//Log.d(LOG,"onKeyEvent " + event.getKeyCode());
controlInterp.onMogaKeyEvent(event,mogaController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION));
}
@Override
public void onMotionEvent(com.bda.controller.MotionEvent event) {
// TODO Auto-generated method stub
Log.d(LOG,"onGenericMotionEvent " + event.toString());
controlInterp.onGenericMotionEvent(event);
}
@Override
public void onStateEvent(StateEvent event) {
Log.d(LOG,"onStateEvent " + event.getState());
}
}
class GameView extends MyGLSurfaceView {
/*--------------------
* Event handling
*--------------------*/
public GameView(Context context) {
super(context);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
return controlInterp.onGenericMotionEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
return controlInterp.onTouchEvent(event);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
return controlInterp.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
return controlInterp.onKeyUp(keyCode, event);
}
} // end of QuakeView
///////////// GLSurfaceView.Renderer implementation ///////////
class QuakeRenderer implements MyGLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.d("Renderer", "onSurfaceCreated");
}
private void init( int width, int height ){
Log.i( "Quake2", "screen size : " + width + "x"+ height);
NativeLib.setScreenSize(width,height);
Utils.copyPNGAssets(getApplicationContext(),AppSettings.graphicsDir);
if (useGL == 0)
args = "--ren soft";
String[] args_array = Utils.creatArgs(args);
int ret = NativeLib.init(AppSettings.graphicsDir,64,args_array,useGL,gamePath);
Log.i("Quake2", "Quake2Init done");
}
//// new Renderer interface
int notifiedflags;
FPSLimit fpsLimit;
boolean inited = false;
public void onDrawFrame(GL10 gl) {
if (!inited)
{
SDLActivity.nativeInit();
AppSettings.setIntOption(getApplicationContext(), "max_fps", 0);
inited = true;
init( surfaceWidth, surfaceHeight );
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.d("Renderer", String.format("onSurfaceChanged %dx%d", width,height) );
// SDLLib.nativeInit(false);
// SDLLib.surfaceChanged(PixelFormat.RGBA_8888, width, height);
SDLActivity.onNativeResize(width, height,PixelFormat.RGBA_8888);
//SDLLib.surfaceChanged(PixelFormat.RGBA_8888, 320, 240);
controlInterp.setScreenSize(width, height);
surfaceWidth = width;
surfaceHeight = height;
}
} // end of QuakeRenderer
}

View File

@ -0,0 +1,81 @@
package com.beloko.games.hl;
import com.beloko.touchcontrols.ControlInterface;
public class NativeLib implements ControlInterface{
public static native int init(String graphics_dir,int mem,String[] args,int game,String path);
public static native int initTouchControls(String graphics_dir,int width,int height);
public static native void setScreenSize( int width, int height );
public static native boolean touchEvent( int action, int pid, float x, float y);
public static native void keypress(int down, int qkey, int unicode);
public static native void doAction(int state, int action);
public static native void analogFwd(float v);
public static native void analogSide(float v);
public static native void analogPitch(int mode,float v);
public static native void analogYaw(int mode,float v);
public static native void setTouchSettings(float alpha,float strafe,float fwd,float pitch,float yaw,int other);
public static native void quickCommand(String command);
@Override
public void initTouchControls_if(String pngPath,int width,int height) {
initTouchControls(pngPath,width,height);
}
@Override
public void quickCommand_if(String command){
quickCommand(command);
}
@Override
public boolean touchEvent_if(int action, int pid, float x, float y) {
return touchEvent( action, pid, x, y);
}
@Override
public void keyPress_if(int down, int qkey, int unicode) {
keypress(down,qkey,unicode);
}
@Override
public void doAction_if(int state, int action) {
doAction(state,action);
}
@Override
public void analogFwd_if(float v) {
analogFwd(v);
}
@Override
public void analogSide_if(float v) {
analogSide(v);
}
@Override
public void analogPitch_if(int mode,float v)
{
analogPitch(mode,v);
}
@Override
public void analogYaw_if(int mode,float v)
{
analogYaw(mode,v);
}
@Override
public void setTouchSettings_if(float alpha,float strafe, float fwd, float pitch,
float yaw, int other) {
setTouchSettings(alpha,strafe, fwd, pitch, yaw, other);
}
@Override
public int mapKey(int acode, int unicode) {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -0,0 +1,37 @@
package com.beloko.touchcontrols;
import java.io.Serializable;
import com.beloko.touchcontrols.ControlConfig.Type;
public class ActionInput implements Serializable
{
private static final long serialVersionUID = 1L;
public String tag;
public String description;
public boolean invert;
public float scale = 1; //senstivty for analog
public int source = -1;
public Type sourceType;
public boolean sourcePositive=true; //Used when using analog as a button
public int actionCode;
public Type actionType;
public ActionInput(String t,String n,int action,Type actiontype)
{
tag = t;
description = n;
actionCode = action;
actionType = actiontype;
}
public String toString()
{
return description + ":" + sourceType.toString() + " source: " + source + " sourcePositive: " + sourcePositive;
}
}

View File

@ -0,0 +1,699 @@
package com.beloko.touchcontrols;
import in.celest.xash3d.hl.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.beloko.touchcontrols.Settings.IDGame;
public class ControlConfig implements Serializable{
final String LOG = "QuakeControlConfig";
/**
*
*/
private static final long serialVersionUID = 1L;
enum Type {ANALOG,BUTTON,MENU};
public static final int LOOK_MODE_MOUSE =0;
public static final int LOOK_MODE_ABSOLUTE =1;
public static final int LOOK_MODE_JOYSTICK =2;
public static final int ACTION_ANALOG_FWD = 0x100;
public static final int ACTION_ANALOG_STRAFE = 0x101;
public static final int ACTION_ANALOG_PITCH = 0x102;
public static final int ACTION_ANALOG_YAW = 0x103;
public static final int PORT_ACT_LEFT =1;
public static final int PORT_ACT_RIGHT =2;
public static final int PORT_ACT_FWD =3;
public static final int PORT_ACT_BACK =4;
public static final int PORT_ACT_LOOK_UP =5;
public static final int PORT_ACT_LOOK_DOWN =6;
public static final int PORT_ACT_MOVE_LEFT =7;
public static final int PORT_ACT_MOVE_RIGHT =8;
public static final int PORT_ACT_STRAFE =9;
public static final int PORT_ACT_SPEED =10;
public static final int PORT_ACT_USE =11;
public static final int PORT_ACT_JUMP =12;
public static final int PORT_ACT_ATTACK =13;
public static final int PORT_ACT_UP =14;
public static final int PORT_ACT_DOWN =15;
public static final int PORT_ACT_NEXT_WEP =16;
public static final int PORT_ACT_PREV_WEP =17;
//Quake 2
public static final int PORT_ACT_INVEN = 18;
public static final int PORT_ACT_INVUSE = 19;
public static final int PORT_ACT_INVDROP = 20;
public static final int PORT_ACT_INVPREV = 21;
public static final int PORT_ACT_INVNEXT = 22;
public static final int PORT_ACT_HELPCOMP = 23;
//Doom
public static final int PORT_ACT_MAP = 30;
public static final int PORT_ACT_MAP_UP = 31;
public static final int PORT_ACT_MAP_DOWN = 32;
public static final int PORT_ACT_MAP_LEFT = 33;
public static final int PORT_ACT_MAP_RIGHT = 34;
public static final int PORT_ACT_MAP_ZOOM_IN = 35;
public static final int PORT_ACT_MAP_ZOOM_OUT = 36;
//RTCW
public static final int PORT_ACT_ZOOM_IN = 50;
public static final int PORT_ACT_ALT_FIRE = 51;
public static final int PORT_ACT_RELOAD = 52;
public static final int PORT_ACT_QUICKSAVE = 53;
public static final int PORT_ACT_QUICKLOAD = 54;
public static final int PORT_ACT_KICK = 56;
public static final int PORT_ACT_LEAN_LEFT = 57;
public static final int PORT_ACT_LEAN_RIGHT = 58;
//JK2
//public static final int PORT_ACT_FORCE_LIGHTNING = 60;
//public static final int PORT_ACT_SABER_BLOCK = 62;
//public static final int PORT_ACT_FORCE_GRIP = 63;
public static final int PORT_ACT_ALT_ATTACK = 64;
public static final int PORT_ACT_NEXT_FORCE = 65;
public static final int PORT_ACT_PREV_FORCE = 66;
public static final int PORT_ACT_FORCE_USE = 67;
public static final int PORT_ACT_DATAPAD = 68;
public static final int PORT_ACT_FORCE_SELECT = 69;
public static final int PORT_ACT_WEAPON_SELECT = 70;
public static final int PORT_ACT_SABER_STYLE = 71;
public static final int PORT_ACT_FORCE_PULL = 75;
public static final int PORT_ACT_FORCE_MIND = 76;
public static final int PORT_ACT_FORCE_LIGHT = 77;
public static final int PORT_ACT_FORCE_HEAL = 78;
public static final int PORT_ACT_FORCE_GRIP = 79;
public static final int PORT_ACT_FORCE_SPEED = 80;
public static final int PORT_ACT_FORCE_PUSH = 81;
public static final int PORT_ACT_SABER_SEL = 87; //Just chooses weapon 1 so show/hide saber.
//Choloate
public static final int PORT_ACT_GAMMA = 90;
public static final int PORT_ACT_SHOW_WEAPONS = 91;
public static final int PORT_ACT_SHOW_KEYS = 92;
public static final int PORT_ACT_FLY_UP = 93;
public static final int PORT_ACT_FLY_DOWN = 94;
//Custom
public static final int PORT_ACT_CUSTOM_0 = 150;
public static final int PORT_ACT_CUSTOM_1 = 151;
public static final int PORT_ACT_CUSTOM_2 = 152;
public static final int PORT_ACT_CUSTOM_3 = 153;
public static final int PORT_ACT_CUSTOM_4 = 154;
public static final int PORT_ACT_CUSTOM_5 = 155;
public static final int PORT_ACT_CUSTOM_6 = 156;
public static final int PORT_ACT_CUSTOM_7 = 157;
//Menu
public static final int MENU_UP = 0x200;
public static final int MENU_DOWN = 0x201;
public static final int MENU_LEFT = 0x202;
public static final int MENU_RIGHT = 0x203;
public static final int MENU_SELECT = 0x204;
public static final int MENU_BACK = 0x205;
Context ctx;
TextView infoTextView;
String filename;
boolean ignoreDirectionFromJoystick;
public ControlConfig(String file,IDGame game)
{
actions.add(new ActionInput("analog_move_fwd","Forward/Back",ACTION_ANALOG_FWD,Type.ANALOG));
actions.add(new ActionInput("analog_move_strafe","Strafe",ACTION_ANALOG_STRAFE,Type.ANALOG));
if (game != IDGame.Wolf3d)
actions.add(new ActionInput("analog_look_pitch","Look Up/Look Down",ACTION_ANALOG_PITCH,Type.ANALOG));
actions.add(new ActionInput("analog_look_yaw","Look Left/Look Right",ACTION_ANALOG_YAW,Type.ANALOG));
actions.add(new ActionInput("attack","Attack",PORT_ACT_ATTACK,Type.BUTTON));
if ((game == IDGame.Doom) || (game == IDGame.Wolf3d)|| (game == IDGame.Hexen)|| (game == IDGame.Strife)|| (game == IDGame.Heretic))
actions.add(new ActionInput("use","Use/Open",PORT_ACT_USE,Type.BUTTON));
if (game == IDGame.RTCW)
{
actions.add(new ActionInput("use","Use/Open",PORT_ACT_USE,Type.BUTTON));
actions.add(new ActionInput("reload","Reload",PORT_ACT_RELOAD,Type.BUTTON));
actions.add(new ActionInput("alt_fire","Alt Weapon",PORT_ACT_ALT_FIRE,Type.BUTTON));
actions.add(new ActionInput("binocular","Binocuar",PORT_ACT_ZOOM_IN,Type.BUTTON));
actions.add(new ActionInput("quick_kick","Kick",PORT_ACT_KICK,Type.BUTTON));
actions.add(new ActionInput("lean_left","Lean Left",PORT_ACT_LEAN_LEFT,Type.BUTTON));
actions.add(new ActionInput("lean_right","Lean Right",PORT_ACT_LEAN_RIGHT,Type.BUTTON));
}
if (game == IDGame.Quake3)
{
actions.add(new ActionInput("zoomin","Zoom in/out",PORT_ACT_ZOOM_IN,Type.BUTTON));
actions.add(new ActionInput("custom_0","Custom F1",PORT_ACT_CUSTOM_0,Type.BUTTON));
actions.add(new ActionInput("custom_1","Custom F2",PORT_ACT_CUSTOM_1,Type.BUTTON));
actions.add(new ActionInput("custom_2","Custom F3",PORT_ACT_CUSTOM_2,Type.BUTTON));
actions.add(new ActionInput("custom_3","Custom F4",PORT_ACT_CUSTOM_3,Type.BUTTON));
}
if ((game == IDGame.JK2) || (game == IDGame.JK3))
{
actions.add(new ActionInput("attack_alt","Alt Attack",PORT_ACT_ALT_ATTACK,Type.BUTTON));
actions.add(new ActionInput("use_force","Use Force",PORT_ACT_FORCE_USE,Type.BUTTON));
actions.add(new ActionInput("saber_style","Saber Style",PORT_ACT_SABER_STYLE,Type.BUTTON));
actions.add(new ActionInput("saber_show_hide","Saber Sheath/Unsheath",PORT_ACT_SABER_SEL,Type.BUTTON));
actions.add(new ActionInput("use","Use/Open",PORT_ACT_USE,Type.BUTTON));
}
if ((game != IDGame.Doom) && (game != IDGame.Wolf3d))
actions.add(new ActionInput("jump","Jump",PORT_ACT_JUMP,Type.BUTTON));
if ((game == IDGame.Quake2) || (game == IDGame.Quake3)|| (game == IDGame.Hexen2)|| (game == IDGame.RTCW)|| (game == IDGame.JK2) || (game == IDGame.JK3))
actions.add(new ActionInput("crouch","Crouch",PORT_ACT_DOWN,Type.BUTTON));
//Add GZDoom specific actions
if (game == IDGame.Doom)
{
actions.add(new ActionInput("attack_alt","Alt Attack (GZ)",PORT_ACT_ALT_ATTACK,Type.BUTTON));
actions.add(new ActionInput("jump","Jump (GZ)",PORT_ACT_JUMP,Type.BUTTON));
actions.add(new ActionInput("crouch","Crouch (GZ)",PORT_ACT_DOWN,Type.BUTTON));
actions.add(new ActionInput("custom_0","Custom A (GZ)",PORT_ACT_CUSTOM_0,Type.BUTTON));
actions.add(new ActionInput("custom_1","Custom B (GZ)",PORT_ACT_CUSTOM_1,Type.BUTTON));
actions.add(new ActionInput("custom_2","Custom C (GZ)",PORT_ACT_CUSTOM_2,Type.BUTTON));
actions.add(new ActionInput("custom_3","Custom D (GZ)",PORT_ACT_CUSTOM_3,Type.BUTTON));
actions.add(new ActionInput("custom_4","Custom E (GZ)",PORT_ACT_CUSTOM_4,Type.BUTTON));
actions.add(new ActionInput("custom_5","Custom F (GZ)",PORT_ACT_CUSTOM_5,Type.BUTTON));
actions.add(new ActionInput("quick_save","Quick Save (GZ)",PORT_ACT_QUICKSAVE,Type.BUTTON));
actions.add(new ActionInput("quick_load","Quick Load (GZ)",PORT_ACT_QUICKLOAD,Type.BUTTON));
}
actions.add(new ActionInput("fwd","Move Forward",PORT_ACT_FWD,Type.BUTTON));
actions.add(new ActionInput("back","Move Backwards",PORT_ACT_BACK,Type.BUTTON));
actions.add(new ActionInput("left","Strafe Left",PORT_ACT_MOVE_LEFT,Type.BUTTON));
actions.add(new ActionInput("right","Strafe Right",PORT_ACT_MOVE_RIGHT,Type.BUTTON));
if ((game != IDGame.Doom) && (game != IDGame.Wolf3d))
{
actions.add(new ActionInput("look_up","Look Up",PORT_ACT_LOOK_UP,Type.BUTTON));
actions.add(new ActionInput("look_down","Look Down",PORT_ACT_LOOK_DOWN,Type.BUTTON));
}
actions.add(new ActionInput("look_left","Look Left",PORT_ACT_LEFT,Type.BUTTON));
actions.add(new ActionInput("look_right","Look Right",PORT_ACT_RIGHT,Type.BUTTON));
if ((game != IDGame.Wolf3d) && (game != IDGame.JK2) || (game != IDGame.JK3))
{
actions.add(new ActionInput("strafe_on","Strafe On",PORT_ACT_STRAFE,Type.BUTTON));
actions.add(new ActionInput("speed","Run On",PORT_ACT_SPEED,Type.BUTTON));
}
actions.add(new ActionInput("next_weapon","Next Weapon",PORT_ACT_NEXT_WEP,Type.BUTTON));
actions.add(new ActionInput("prev_weapon","Previous Weapon",PORT_ACT_PREV_WEP,Type.BUTTON));
if ((game == IDGame.JK2)|| (game == IDGame.JK3))
{
actions.add(new ActionInput("next_force","Next Force",PORT_ACT_NEXT_FORCE,Type.BUTTON));
actions.add(new ActionInput("prev_force","Previous Force",PORT_ACT_PREV_FORCE,Type.BUTTON));
actions.add(new ActionInput("force_pull","Force Pull",PORT_ACT_FORCE_PULL,Type.BUTTON));
actions.add(new ActionInput("force_push","Force Push",PORT_ACT_FORCE_PUSH,Type.BUTTON));
actions.add(new ActionInput("force_speed","Force Speed",PORT_ACT_FORCE_SPEED,Type.BUTTON));
actions.add(new ActionInput("force_heal","Force Heal",PORT_ACT_FORCE_HEAL,Type.BUTTON));
actions.add(new ActionInput("force_mind","Force Mind",PORT_ACT_FORCE_MIND,Type.BUTTON));
actions.add(new ActionInput("force_grip","Force Grip",PORT_ACT_FORCE_GRIP,Type.BUTTON));
actions.add(new ActionInput("force_lightning","Force Lightning",PORT_ACT_FORCE_LIGHT,Type.BUTTON));
}
if ((game == IDGame.Quake2) || (game == IDGame.Hexen2)|| (game == IDGame.RTCW))
{
actions.add(new ActionInput("help_comp","Show Objectives",PORT_ACT_HELPCOMP,Type.BUTTON));
actions.add(new ActionInput("inv_show","Show Inventory",PORT_ACT_INVEN,Type.BUTTON));
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_INVUSE,Type.BUTTON));
actions.add(new ActionInput("inv_next","Next Item",PORT_ACT_INVNEXT,Type.BUTTON));
actions.add(new ActionInput("inv_prev","Prev Item",PORT_ACT_INVPREV,Type.BUTTON));
}
if (game == IDGame.JK2)
{
actions.add(new ActionInput("help_comp","Show Data Pad",PORT_ACT_DATAPAD,Type.BUTTON));
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_INVUSE,Type.BUTTON));
actions.add(new ActionInput("inv_next","Next Item",PORT_ACT_INVNEXT,Type.BUTTON));
actions.add(new ActionInput("inv_prev","Prev Item",PORT_ACT_INVPREV,Type.BUTTON));
}
if (game == IDGame.Hexen)
{
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_INVUSE,Type.BUTTON));
actions.add(new ActionInput("inv_next","Next Item",PORT_ACT_INVNEXT,Type.BUTTON));
actions.add(new ActionInput("inv_prev","Prev Item",PORT_ACT_INVPREV,Type.BUTTON));
actions.add(new ActionInput("fly_up","Fly Up",PORT_ACT_FLY_UP,Type.BUTTON));
actions.add(new ActionInput("fly_down","Fly Down",PORT_ACT_FLY_DOWN,Type.BUTTON));
}
if (game == IDGame.Strife)
{
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_INVUSE,Type.BUTTON));
actions.add(new ActionInput("inv_drop","Drop Item",PORT_ACT_INVDROP,Type.BUTTON));
actions.add(new ActionInput("inv_next","Next Item",PORT_ACT_INVNEXT,Type.BUTTON));
actions.add(new ActionInput("inv_prev","Prev Item",PORT_ACT_INVPREV,Type.BUTTON));
actions.add(new ActionInput("show_weap","Show Stats/Weapons",PORT_ACT_SHOW_WEAPONS,Type.BUTTON));
actions.add(new ActionInput("show_keys","Show Keys",PORT_ACT_SHOW_KEYS,Type.BUTTON));
}
if (game == IDGame.Heretic)
{
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_INVUSE,Type.BUTTON));
actions.add(new ActionInput("inv_next","Next Item",PORT_ACT_INVNEXT,Type.BUTTON));
actions.add(new ActionInput("inv_prev","Prev Item",PORT_ACT_INVPREV,Type.BUTTON));
actions.add(new ActionInput("fly_up","Fly Up",PORT_ACT_FLY_UP,Type.BUTTON));
actions.add(new ActionInput("fly_down","Fly Down",PORT_ACT_FLY_DOWN,Type.BUTTON));
}
if (game == IDGame.Quake3)
{
actions.add(new ActionInput("inv_use","Use Item",PORT_ACT_USE,Type.BUTTON));
}
if (game == IDGame.Doom)
{
actions.add(new ActionInput("map_show","Show Automap",PORT_ACT_MAP,Type.BUTTON));
actions.add(new ActionInput("map_up","Automap Up",PORT_ACT_MAP_UP,Type.BUTTON));
actions.add(new ActionInput("map_down","Automap Down",PORT_ACT_MAP_DOWN,Type.BUTTON));
actions.add(new ActionInput("map_left","Automap Left",PORT_ACT_MAP_LEFT,Type.BUTTON));
actions.add(new ActionInput("map_right","Automap Right",PORT_ACT_MAP_RIGHT,Type.BUTTON));
actions.add(new ActionInput("map_zoomin","Automap Zoomin",PORT_ACT_MAP_ZOOM_IN,Type.BUTTON));
actions.add(new ActionInput("map_zoomout","Automap Zoomout",PORT_ACT_MAP_ZOOM_OUT,Type.BUTTON));
}
if ((game == IDGame.RTCW) || (game == IDGame.JK2) || (game == IDGame.JK3))
{
actions.add(new ActionInput("quick_save","Quick Save",PORT_ACT_QUICKSAVE,Type.BUTTON));
actions.add(new ActionInput("quick_load","Quick Load",PORT_ACT_QUICKLOAD,Type.BUTTON));
}
if ((game == IDGame.Doom) || (game == IDGame.Heretic) || (game == IDGame.Hexen)
|| (game == IDGame.Strife)|| (game == IDGame.Quake)|| (game == IDGame.Quake2)
|| (game == IDGame.Hexen2)
|| (game == IDGame.JK2) || (game == IDGame.JK3))
{
actions.add(new ActionInput("menu_up","Menu Up",MENU_UP,Type.MENU));
actions.add(new ActionInput("menu_down","Menu Down",MENU_DOWN,Type.MENU));
actions.add(new ActionInput("menu_left","Menu Left",MENU_LEFT,Type.MENU));
actions.add(new ActionInput("menu_right","Menu Right",MENU_RIGHT,Type.MENU));
actions.add(new ActionInput("menu_select","Menu Select",MENU_SELECT,Type.MENU));
actions.add(new ActionInput("menu_back","Menu Back",MENU_BACK,Type.MENU));
}
filename = file;
}
public void setTextView(Context c,TextView tv)
{
ctx = c;
infoTextView = tv;
}
void saveControls(File file) throws IOException
{
if (Settings.DEBUG) Log.d(LOG,"saveControls, file = " + file.toString());
FileOutputStream fos = null;
ObjectOutputStream out = null;
fos = new FileOutputStream(file);
out = new ObjectOutputStream(fos);
out.writeObject(actions);
out.close();
}
public void loadControls() throws IOException, ClassNotFoundException
{
loadControls(new File(filename));
}
public void loadControls(File file) throws IOException, ClassNotFoundException
{
if (Settings.DEBUG) Log.d(LOG,"loadControls, file = " + file.toString());
InputStream fis = null;
ObjectInputStream in = null;
fis = new FileInputStream(file);
in = new ObjectInputStream(fis);
ArrayList<ActionInput> cd = (ArrayList<ActionInput> )in.readObject();
if (Settings.DEBUG) Log.d(LOG,"loadControls, file loaded OK");
in.close();
for (ActionInput d: cd)
{
for (ActionInput a: actions)
{
if (d.tag.contentEquals(a.tag))
{
a.invert = d.invert;
a.source = d.source;
a.sourceType = d.sourceType;
a.sourcePositive = d.sourcePositive;
a.scale = d.scale;
if (a.scale == 0) a.scale = 1;
}
}
}
//Now check no buttons are also assigned to analog, if it is, clear the buttons
//This is because n00bs keep assigning movment analog AND buttons!
for (ActionInput a: actions)
{
if ((a.source != -1) && (a.sourceType == Type.ANALOG) && (a.actionType == Type.BUTTON))
{
for (ActionInput a_check: actions)
{
if ((a_check.sourceType == Type.ANALOG) && (a_check.actionType == Type.ANALOG))
{
if (a.source == a_check.source)
{
a.source = -1;
break;
}
}
}
}
}
fis.close();
}
void updated()
{
try {
saveControls(new File (filename));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ArrayList<ActionInput> actions = new ArrayList<ActionInput>();
ActionInput actionMontor=null;
boolean monitoring = false;
public boolean showExtraOptions(Activity act,int pos)
{
final ActionInput in = actions.get(pos);
if (in.actionType == Type.ANALOG)
{
Dialog dialog = new Dialog(act);
dialog.setTitle("Axis Sensitivity Setting");
dialog.setCancelable(true);
final LinearLayout l = new LinearLayout(act);
l.setOrientation(LinearLayout.VERTICAL);
final SeekBar sb = new SeekBar(act);
l.addView(sb);
sb.setMax(100);
sb.setProgress((int)(in.scale * 50));
final CheckBox invert = new CheckBox(act);
invert.setText("Invert");
invert.setChecked(in.invert);
l.addView(invert);
dialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
in.scale = (float)sb.getProgress()/(float)50;
in.invert = invert.isChecked();
updated();
}
});
dialog.setContentView(l);
dialog.show();
return true;
}
return false;
}
public void startMonitor(Activity act,int pos)
{
actionMontor = actions.get(pos);
monitoring = true;
if (actionMontor.actionType == Type.ANALOG)
infoTextView.setText("Move Stick for: " + actionMontor.description);
else
infoTextView.setText("Press Button for: " + actionMontor.description);
infoTextView.setTextColor(ctx.getResources().getColor(android.R.color.holo_green_light));
}
int[] axisTest = {
/*
MotionEvent.AXIS_GENERIC_1,
MotionEvent.AXIS_GENERIC_2,
MotionEvent.AXIS_GENERIC_3,
MotionEvent.AXIS_GENERIC_4,
MotionEvent.AXIS_GENERIC_5,
MotionEvent.AXIS_GENERIC_6,
MotionEvent.AXIS_GENERIC_7,
MotionEvent.AXIS_GENERIC_8,
MotionEvent.AXIS_GENERIC_9,
MotionEvent.AXIS_GENERIC_10,
MotionEvent.AXIS_GENERIC_11,
MotionEvent.AXIS_GENERIC_12,
MotionEvent.AXIS_GENERIC_13,
MotionEvent.AXIS_GENERIC_14,
MotionEvent.AXIS_GENERIC_15,
MotionEvent.AXIS_GENERIC_16,
*/
MotionEvent.AXIS_HAT_X,
MotionEvent.AXIS_HAT_Y,
MotionEvent.AXIS_LTRIGGER,
MotionEvent.AXIS_RTRIGGER,
MotionEvent.AXIS_RUDDER,
MotionEvent.AXIS_RX,
MotionEvent.AXIS_RY,
MotionEvent.AXIS_RZ,
MotionEvent.AXIS_THROTTLE,
MotionEvent.AXIS_X,
MotionEvent.AXIS_Y,
MotionEvent.AXIS_Z,
MotionEvent.AXIS_BRAKE,
MotionEvent.AXIS_GAS,
};
public boolean onGenericMotionEvent(GenericAxisValues event)
{
Log.d(LOG,"onGenericMotionEvent");
if (monitoring)
{
if (actionMontor != null)
{
for (int a: axisTest)
{
if (Math.abs(event.getAxisValue(a)) > 0.6)
{
actionMontor.source = a;
actionMontor.sourceType = Type.ANALOG;
//Used for button actions
if (event.getAxisValue(a) > 0)
actionMontor.sourcePositive = true;
else
actionMontor.sourcePositive = false;
monitoring = false;
if (Settings.DEBUG) Log.d(LOG,actionMontor.description + " = Analog (" + actionMontor.source + ")");
infoTextView.setText("Select Action");
infoTextView.setTextColor(ctx.getResources().getColor(android.R.color.holo_blue_light));
updated();
return true;
}
}
}
}
return false;
}
public boolean isMonitoring()
{
return monitoring;
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
Log.d(LOG,"onKeyDown " + keyCode);
if (monitoring)
{
if (keyCode == KeyEvent.KEYCODE_BACK) //Cancel and clear button assignment
{
actionMontor.source = -1;
actionMontor.sourceType = Type.BUTTON;
monitoring = false;
infoTextView.setText("CANCELED");
infoTextView.setTextColor(ctx.getResources().getColor(android.R.color.holo_red_light));
updated();
return true;
}
else
{
if (actionMontor != null)
{
if (actionMontor.actionType != Type.ANALOG)
{
actionMontor.source = keyCode;
actionMontor.sourceType = Type.BUTTON;
monitoring = false;
infoTextView.setText("Select Action");
infoTextView.setTextColor(ctx.getResources().getColor(android.R.color.holo_blue_light));
updated();
return true;
}
}
}
}
return false;
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
return false;
}
public int getSize()
{
return actions.size();
}
public View getView(final Activity ctx,final int nbr)
{
View view = ctx.getLayoutInflater().inflate(R.layout.controls_listview_item, null);
ImageView image = (ImageView)view.findViewById(R.id.imageView);
TextView name = (TextView)view.findViewById(R.id.name_textview);
TextView binding = (TextView)view.findViewById(R.id.binding_textview);
ImageView setting_image = (ImageView)view.findViewById(R.id.settings_imageview);
ActionInput ai = actions.get(nbr);
if ((ai.actionType == Type.BUTTON) || (ai.actionType == Type.MENU))
{
if (ai.sourceType == Type.ANALOG)
binding.setText(MotionEvent.axisToString(ai.source));
else
binding.setText(KeyEvent.keyCodeToString(ai.source));
setting_image.setVisibility(View.GONE);
if ( (ai.actionType == Type.MENU))
{
name.setTextColor(0xFF00aeef); //BLUEY
image.setImageResource(R.drawable.gamepad_menu);
}
else
{
image.setImageResource(R.drawable.gamepad);
}
}
else if (ai.actionType == Type.ANALOG)
{
binding.setText(MotionEvent.axisToString(ai.source));
setting_image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showExtraOptions(ctx,nbr);
}
});
name.setTextColor(0xFFf7941d); //ORANGE
}
/*
if (ai.actionType == Type.BUTTON)
{
image.setImageResource(R.drawable.gamepad);
if (ai.sourceType == Type.ANALOG)
binding.setText(MotionEvent.axisToString(ai.source));
else
binding.setText(KeyEvent.keyCodeToString(ai.source));
setting_image.setVisibility(View.GONE);
}
else //Analog
{
binding.setText(MotionEvent.axisToString(ai.source));
setting_image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showExtraOptions(ctx,nbr);
}
});
name.setTextColor(0xFFf7941d);
}
*/
name.setText(ai.description);
return view;
}
}

View File

@ -0,0 +1,22 @@
package com.beloko.touchcontrols;
import android.view.KeyEvent;
public interface ControlInterface {
public void initTouchControls_if(String pngPath,int width,int height);
public boolean touchEvent_if( int action, int pid, float x, float y);
public void keyPress_if(int down, int qkey, int unicode);
public void doAction_if(int state, int action);
public void analogFwd_if(float v);
public void analogSide_if(float v);
public void analogPitch_if(int mode,float v);
public void analogYaw_if(int mode,float v);
public void setTouchSettings_if(float alpha,float strafe,float fwd,float pitch,float yaw,int other);
public void quickCommand_if(String command);
public int mapKey(int acode,int unicode);
}

View File

@ -0,0 +1,304 @@
package com.beloko.touchcontrols;
import java.io.IOException;
import java.util.HashMap;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.bda.controller.Controller;
import com.beloko.touchcontrols.ControlConfig.Type;
import com.beloko.touchcontrols.Settings.IDGame;
public class ControlInterpreter {
String LOG = "QuakeControlInterpreter";
ControlInterface quakeIf;
ControlConfig config;
boolean gamePadEnabled;
float screenWidth, screenHeight;
HashMap<Integer, Boolean> analogButtonState = new HashMap<Integer, Boolean>(); //Saves current state of analog buttons so all sent each time
public ControlInterpreter(ControlInterface qif,IDGame game,String controlfile,boolean ctrlEn)
{
Log.d("QuakeControlInterpreter", "file = " + controlfile);
gamePadEnabled = ctrlEn;
config = new ControlConfig(controlfile,game);
try {
config.loadControls();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
for (ActionInput ai: config.actions)
{
if ((ai.sourceType == Type.ANALOG) && ((ai.actionType == Type.MENU) || (ai.actionType == Type.BUTTON)))
{
analogButtonState.put(ai.actionCode, false);
}
}
quakeIf = qif;
}
public void setScreenSize(int w,int h)
{
screenWidth = w;
screenHeight = h;
}
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
if (actionCode == MotionEvent.ACTION_MOVE)
{
for (int i = 0; i < event.getPointerCount(); i++) {
float x = event.getX(i)/screenWidth;
float y = event.getY(i)/screenHeight;
int pid = event.getPointerId(i);
quakeIf.touchEvent_if(3, pid, x, y);
}
}
else if (actionCode == MotionEvent.ACTION_DOWN)
{
float x = event.getX()/screenWidth;
float y = event.getY()/screenHeight;
quakeIf.touchEvent_if(1, 0, x, y);
}
else if (actionCode == MotionEvent.ACTION_POINTER_DOWN)
{
int index = event.getActionIndex();
if (index != -1)
{
float x = event.getX(index)/screenWidth;
float y = event.getY(index)/screenHeight;
int pid = event.getPointerId(index);
quakeIf.touchEvent_if(1, pid, x, y);
}
}
else if (actionCode == MotionEvent.ACTION_POINTER_UP)
{
int index = event.getActionIndex();
if (index != -1)
{
float x = event.getX(index)/screenWidth;
float y = event.getY(index)/screenHeight;
int pid = event.getPointerId(index);
quakeIf.touchEvent_if(2, pid, x, y);
}
}
else if (actionCode == MotionEvent.ACTION_UP)
{
float x = event.getX()/screenWidth;
float y = event.getY()/screenHeight;
int index = event.getActionIndex();
int pid = event.getPointerId(index);
quakeIf.touchEvent_if(2, pid, x, y);
}
return true;
}
public void onMogaKeyEvent(com.bda.controller.KeyEvent event,int pad_version)
{
int keycode = event.getKeyCode();
if (pad_version == Controller.ACTION_VERSION_MOGA)
{
//Log.d(LOG,"removed");
if ((keycode == com.bda.controller.KeyEvent.KEYCODE_DPAD_DOWN) ||
(keycode == com.bda.controller.KeyEvent.KEYCODE_DPAD_UP) ||
(keycode == com.bda.controller.KeyEvent.KEYCODE_DPAD_LEFT) ||
(keycode == com.bda.controller.KeyEvent.KEYCODE_DPAD_RIGHT))
return;
}
if (event.getAction() == com.bda.controller.KeyEvent.ACTION_DOWN)
onKeyDown(keycode, null);
else if (event.getAction() == com.bda.controller.KeyEvent.ACTION_UP)
onKeyUp(keycode, null);
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
boolean used = false;;
if (gamePadEnabled)
{
for (ActionInput ai: config.actions)
{
if (((ai.sourceType == Type.BUTTON)||(ai.sourceType == Type.MENU)) && (ai.source == keyCode))
{
quakeIf.doAction_if(1, ai.actionCode);
Log.d(LOG,"key down intercept");
used = true;
}
}
}
if (used)
return true;
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || //If these were mapped it would have already returned
(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
return false;
else
{
int uc = 0;
if (event !=null)
uc = event.getUnicodeChar();
quakeIf.keyPress_if(1, quakeIf.mapKey(keyCode, uc), uc);
return true;
}
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
boolean used = false;
if (gamePadEnabled)
{
for (ActionInput ai: config.actions)
{
if (((ai.sourceType == Type.BUTTON) || (ai.sourceType == Type.MENU)) && (ai.source == keyCode))
{
quakeIf.doAction_if(0, ai.actionCode);
used = true;
}
}
}
if (used)
return true;
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || //If these were mapped it would have already returned
(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN))
return false;
else
{
int uc = 0;
if (event !=null)
uc = event.getUnicodeChar();
quakeIf.keyPress_if(0, quakeIf.mapKey(keyCode, uc), uc);
return true;
}
}
float deadRegion = 0.2f;
private float analogCalibrate(float v)
{
if ((v < deadRegion) && (v > -deadRegion))
return 0;
else
{
if (v > 0)
return(v-deadRegion) / (1-deadRegion);
else
return(v+deadRegion) / (1-deadRegion);
//return v;
}
}
GenericAxisValues genericAxisValues = new GenericAxisValues();
//This is for normal Android motioon event
public boolean onGenericMotionEvent(MotionEvent event) {
genericAxisValues.setAndroidValues(event);
return onGenericMotionEvent(genericAxisValues);
}
//This is for Moga event
public boolean onGenericMotionEvent(com.bda.controller.MotionEvent event) {
genericAxisValues.setMogaValues(event);
return onGenericMotionEvent(genericAxisValues);
}
public boolean onGenericMotionEvent(GenericAxisValues event) {
if (Settings.DEBUG) Log.d(LOG,"onGenericMotionEvent" );
boolean used = false;
if (gamePadEnabled)
{
for (ActionInput ai: config.actions)
{
if ((ai.sourceType == Type.ANALOG) && (ai.source != -1))
{
int invert;
invert = ai.invert?-1:1;
if (ai.actionCode == ControlConfig.ACTION_ANALOG_PITCH)
quakeIf.analogPitch_if(ControlConfig.LOOK_MODE_JOYSTICK, analogCalibrate(event.getAxisValue(ai.source)) * invert * ai.scale);
else if (ai.actionCode == ControlConfig.ACTION_ANALOG_YAW)
quakeIf.analogYaw_if(ControlConfig.LOOK_MODE_JOYSTICK, -analogCalibrate(event.getAxisValue(ai.source)) * invert * ai.scale);
else if (ai.actionCode == ControlConfig.ACTION_ANALOG_FWD)
quakeIf.analogFwd_if(-analogCalibrate(event.getAxisValue(ai.source)) * invert * ai.scale);
else if (ai.actionCode == ControlConfig.ACTION_ANALOG_STRAFE)
quakeIf.analogSide_if(analogCalibrate(event.getAxisValue(ai.source)) * invert * ai.scale);
else //Must be using analog as a button
{
if (Settings.DEBUG) Log.d(LOG,"Analog as button" );
if (Settings.DEBUG) Log.d(LOG,ai.toString());
if (((ai.sourcePositive) && (event.getAxisValue(ai.source)) > 0.5) ||
((!ai.sourcePositive) && (event.getAxisValue(ai.source)) < -0.5) )
{
if (!analogButtonState.get(ai.actionCode)) //Check internal state, only send if different
{
quakeIf.doAction_if(1, ai.actionCode); //press
analogButtonState.put(ai.actionCode, true);
}
}
else
{
if (analogButtonState.get(ai.actionCode)) //Check internal state, only send if different
{
quakeIf.doAction_if(0, ai.actionCode); //un-press
analogButtonState.put(ai.actionCode, false);
}
}
}
used = true;
}
/*
//Menu buttons
if ((ai.sourceType == Type.ANALOG) && (ai.actionType == Type.MENU) && (ai.source != -1))
{
if (GD.DEBUG) Log.d(LOG,"Analog as MENU button" );
if (GD.DEBUG) Log.d(LOG,ai.toString());
if (((ai.sourcePositive) && (event.getAxisValue(ai.source)) > 0.5) ||
((!ai.sourcePositive) && (event.getAxisValue(ai.source)) < -0.5) )
quakeIf.doAction_if(1, ai.actionCode); //press
else
quakeIf.doAction_if(0, ai.actionCode); //un-press
}
*/
}
}
return used;
}
}

View File

@ -0,0 +1,289 @@
package com.beloko.touchcontrols;
import in.celest.xash3d.hl.R;
import java.io.IOException;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.StateEvent;
public class GamePadFragment extends Fragment{
final String LOG = "GamePadFragment";
ListView listView;
ControlListAdapter adapter;
TextView info;
ControlConfig config;
GenericAxisValues genericAxisValues = new GenericAxisValues();
Controller mogaController = null;
final MogaControllerListener mListener = new MogaControllerListener();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
config = new ControlConfig(Settings.gamePadControlsFile,Settings.game);
try {
config.loadControls();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
mogaController = Controller.getInstance(getActivity());
mogaController.init();
mogaController.setListener(mListener,new Handler());
}
boolean isHidden = true;
@Override
public void onHiddenChanged(boolean hidden) {
isHidden = hidden;
super.onHiddenChanged(hidden);
}
@Override
public void onPause()
{
super.onPause();
mogaController.onPause();
}
@Override
public void onResume()
{
super.onResume();
mogaController.onResume();
}
@Override
public void onDestroy()
{
super.onDestroy();
mogaController.exit();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.fragment_gamepad, null);
CheckBox enableCb = (CheckBox)mainView.findViewById(R.id.gamepad_enable_checkbox);
enableCb.setChecked(Settings.gamePadEnabled);
enableCb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Settings.setBoolOption(getActivity(), "gamepad_enabled", isChecked);
Settings.gamePadEnabled = isChecked;
setListViewEnabled(Settings.gamePadEnabled);
}
});
CheckBox hideCtrlCb = (CheckBox)mainView.findViewById(R.id.gamepad_hide_touch_checkbox);
hideCtrlCb.setChecked(Settings.hideTouchControls);
hideCtrlCb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Settings.setBoolOption(getActivity(), "hide_touch_controls", isChecked);
Settings.hideTouchControls = isChecked;
}
});
Button help = (Button)mainView.findViewById(R.id.gamepad_help_button);
help.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//NoticeDialog.show(getActivity(),"Gamepad Help", R.raw.gamepad);
}
});
listView = (ListView)mainView.findViewById(R.id.gamepad_listview);
adapter = new ControlListAdapter(getActivity());
listView.setAdapter(adapter);
setListViewEnabled(Settings.gamePadEnabled);
listView.setSelector(R.drawable.layout_sel_background);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int pos,
long id) {
config.startMonitor(getActivity(), pos);
}
});
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View v, int pos,
long id) {
return config.showExtraOptions(getActivity(), pos);
}
});
adapter.notifyDataSetChanged();
info = (TextView)mainView.findViewById(R.id.gamepad_info_textview);
info.setText("Select Action");
info.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
config.setTextView(getActivity(),info);
return mainView;
}
private void setListViewEnabled(boolean v)
{
listView.setEnabled(v);
if (v)
{
listView.setAlpha(1);
}
else
{
listView.setAlpha(0.3f);
//listView.setBackgroundColor(Color.GRAY);
}
}
public boolean onGenericMotionEvent(MotionEvent event)
{
genericAxisValues.setAndroidValues(event);
if (config.onGenericMotionEvent(genericAxisValues))
adapter.notifyDataSetChanged();
//return config.isMonitoring(); //This does not work, mouse appears anyway
return !isHidden; //If gamepas tab visible always steal
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (config.onKeyDown(keyCode, event))
{
adapter.notifyDataSetChanged();
return true;
}
return false;
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if(config.onKeyUp(keyCode, event))
{
adapter.notifyDataSetChanged();
return true;
}
return false;
}
class ControlListAdapter extends BaseAdapter{
private Activity context;
public ControlListAdapter(Activity context){
this.context=context;
}
public void add(String string){
}
public int getCount() {
return config.getSize();
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public View getView (int position, View convertView, ViewGroup list) {
View v = config.getView(getActivity(), position);
return v;
}
}
class MogaControllerListener implements ControllerListener {
@Override
public void onKeyEvent(com.bda.controller.KeyEvent event) {
//Log.d(LOG,"onKeyEvent " + event.getKeyCode());
if (event.getAction() == com.bda.controller.KeyEvent.ACTION_DOWN)
onKeyDown(event.getKeyCode(),null);
else if (event.getAction() == com.bda.controller.KeyEvent.ACTION_UP)
onKeyUp(event.getKeyCode(),null);
}
@Override
public void onMotionEvent(com.bda.controller.MotionEvent event) {
//Log.d(LOG,"onGenericMotionEvent " + event.toString());
genericAxisValues.setMogaValues(event);
if (config.onGenericMotionEvent(genericAxisValues))
adapter.notifyDataSetChanged();
}
@Override
public void onStateEvent(StateEvent event) {
Log.d(LOG,"onStateEvent " + event.getState());
}
}
}

View File

@ -0,0 +1,29 @@
package com.beloko.touchcontrols;
import android.view.MotionEvent;
public class GenericAxisValues {
float[] values = new float[64];
public float getAxisValue(int a)
{
return values[a];
}
public void setAxisValue(int a,float v)
{
values[a] = v;
}
public void setAndroidValues(MotionEvent event){
for (int n=0;n<64;n++)
values[n] = event.getAxisValue(n);
}
public void setMogaValues(com.bda.controller.MotionEvent event){
values[MotionEvent.AXIS_X] = event.getAxisValue(MotionEvent.AXIS_X);
values[MotionEvent.AXIS_Y] = event.getAxisValue(MotionEvent.AXIS_Y);
values[MotionEvent.AXIS_Z] = event.getAxisValue(MotionEvent.AXIS_Z);
values[MotionEvent.AXIS_RZ] = event.getAxisValue(MotionEvent.AXIS_RZ);
}
}

View File

@ -0,0 +1,36 @@
package com.beloko.touchcontrols;
import java.io.Serializable;
public class QuickCommand implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
String title;
String command;
QuickCommand(String title, String command)
{
this.title = title;
this.command = command;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}

View File

@ -0,0 +1,144 @@
package com.beloko.touchcontrols;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.util.Log;
public class Settings {
public static boolean DEBUG = false;
public static String gamePadControlsFile = "gamepadSettings.dat";
public static String graphicsDir = "";
public static boolean gamePadEnabled;
public static boolean hideTouchControls;
public enum IDGame{Quake,Quake2,Doom,Duke3d,Quake3,Hexen2,RTCW,Wolf3d,JK2,JK3,Heretic,Hexen,Strife,AVP,Shadow,Gish,Descent1,Descent2,Homeworld,BlakeStone,Noah,Doom3};
public static IDGame game;
public static float getFloatOption(Context ctx,String name, float def)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
return settings.getFloat(name, def);
}
public static void setFloatOption(Context ctx,String name, float value)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putFloat(name, value);
editor.commit();
}
public static boolean getBoolOption(Context ctx,String name, boolean def)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
return settings.getBoolean(name, def);
}
public static void setBoolOption(Context ctx,String name, boolean value)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(name, value);
editor.commit();
}
public static int getIntOption(Context ctx,String name, int def)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
return settings.getInt(name, def);
}
public static void setIntOption(Context ctx,String name, int value)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(name, value);
editor.commit();
}
public static long getLongOption(Context ctx,String name, long def)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
return settings.getLong(name, def);
}
public static void setLongOption(Context ctx,String name, long value)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putLong(name, value);
editor.commit();
}
public static String getStringOption(Context ctx,String name, String def)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
return settings.getString(name, def);
}
public static void setStringOption(Context ctx,String name, String value)
{
SharedPreferences settings = ctx.getSharedPreferences("OPTIONS", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putString(name, value);
editor.commit();
}
static public void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
out.close();
}
static public void copyPNGAssets(Context ctx,String dir,String prefix) {
if (prefix == null)
prefix = "";
File d = new File(dir);
if (!d.exists())
d.mkdirs();
AssetManager assetManager = ctx.getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
if (filename.endsWith("png") && filename.startsWith(prefix)){
InputStream in = null;
OutputStream out = null;
//Log.d("test","file = " + filename);
try {
in = assetManager.open(filename);
out = new FileOutputStream(dir + "/" + filename.substring(prefix.length()));
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
}
}
}

View File

@ -0,0 +1,68 @@
package com.beloko.touchcontrols;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
public class ShowKeyboard {
static Activity activity;
static View view;;
public static void setup(Activity a,View v)
{
activity = a;
view = v;
}
public static void toggleKeyboard()
{
Log.d("ShowKeyboard","toggleKeyboard");
InputMethodManager im = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (im != null)
{
Log.d("ShowKeyboard","toggleKeyboard...");
im.toggleSoftInput(0, 0);
}
}
public static void showKeyboard(int show)
{
Log.d("ShowKeyboard","showKeyboard " + show);
InputMethodManager im = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (im != null)
{
if (show == 0)
{
im.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
if (show == 1)
if (!im.isAcceptingText())
toggleKeyboard();
if (show == 2)
toggleKeyboard();
}
/*
InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (show == 1)
imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
else
imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
*/
}
public static boolean hasHardwareKeyboard()
{
if(activity == null)
return false;
return activity.getApplicationContext().getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY;
}
}

View File

@ -0,0 +1,145 @@
package com.beloko.touchcontrols;
import in.celest.xash3d.hl.R;
import android.app.Activity;
import android.app.Dialog;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ToggleButton;
public class TouchControlsEditing {
static String TAG = "TouchControlsEditing";
static class ControlInfo
{
String tag;
String image;
boolean enabled;
boolean hidden;
}
static ListAdapter adapter;
static Activity activity;
public static native void JNIGetControlInfo(int pos,ControlInfo info);
public static native int JNIGetNbrControls();
public static native void JNISetHidden(int pos, boolean hidden);
public static void setup(Activity a)
{
activity = a;
}
public static void show()
{
show(activity);
}
public static void show(Activity act)
{
Log.d(TAG,"showSettings");
if (act != null)
activity = act;
activity.runOnUiThread(new Runnable(){
public void run() {
final Dialog dialog = new Dialog(activity);
ListView listView = new ListView(activity);
dialog.setContentView(listView);
dialog.setTitle("Add/remove buttons");
dialog.setCancelable(true);
adapter = new ListAdapter(activity);
listView.setAdapter(adapter);
dialog.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
dialog.show();
}
});
}
static class ListAdapter extends BaseAdapter{
private Activity context;
public ListAdapter(Activity context){
this.context=context;
}
public void add(String string){
}
public int getCount() {
return TouchControlsEditing.JNIGetNbrControls();
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public View getView (int position, View convertView, ViewGroup list) {
//if (convertView == null) dont reuse view otherwise check change get called
convertView = activity.getLayoutInflater().inflate(R.layout.edit_controls_listview_item, null);
final int my_pos = position;
ImageView image = (ImageView)convertView.findViewById(R.id.imageView);
TextView name = (TextView)convertView.findViewById(R.id.name_textview);
ToggleButton hidden = (ToggleButton)convertView.findViewById(R.id.hidden_switch);
TouchControlsEditing.ControlInfo ci = new TouchControlsEditing.ControlInfo();
TouchControlsEditing.JNIGetControlInfo(position, ci);
name.setText(ci.tag);
hidden.setChecked(!ci.hidden);
hidden.setTag(new Integer(position));
hidden.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Integer pos = (Integer)buttonView.getTag();
TouchControlsEditing.JNISetHidden(pos, !isChecked);
adapter.notifyDataSetChanged();
}
});
String png = activity.getFilesDir() + "/" + ci.image + ".png";
Log.d(TAG,"png = " + png);
BitmapDrawable bm = new BitmapDrawable(png);
image.setImageDrawable(bm);
return convertView;
}
}
}

View File

@ -0,0 +1,265 @@
package com.beloko.touchcontrols;
import in.celest.xash3d.hl.R;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.Spinner;
public class TouchControlsSettings {
static Activity activity;
static ControlInterface quakeIf;
static int alpha,fwdSens,strafeSens,pitchSens,yawSens;
static boolean mouseMode,showWeaponCycle,showSticks,enableWeaponWheel;
static boolean invertLook,precisionShoot;
static int doubleTapMove,doubleTapLook;
public static void setup(Activity a,ControlInterface qif)
{
activity = a;
quakeIf = qif;
}
public static void showSettings()
{
Log.d("settings","showSettings");
activity.runOnUiThread(new Runnable(){
public void run() {
final Dialog dialog = new Dialog(activity);
dialog.setContentView(R.layout.touch_controls_settings);
dialog.setTitle("Touch Control Sensitivity Settings");
dialog.setCancelable(true);
final SeekBar alphaSeek = (SeekBar)dialog.findViewById(R.id.alpha_seekbar);
final SeekBar fwdSeek = (SeekBar)dialog.findViewById(R.id.fwd_seekbar);
final SeekBar strafeSeek = (SeekBar)dialog.findViewById(R.id.strafe_seekbar);
final SeekBar pitchSeek = (SeekBar)dialog.findViewById(R.id.pitch_seekbar);
final SeekBar yawSeek = (SeekBar)dialog.findViewById(R.id.yaw_seekbar);
final CheckBox mouseModeCheck = (CheckBox)dialog.findViewById(R.id.mouse_turn_checkbox);
final CheckBox showWeaponCycleCheckBox = (CheckBox)dialog.findViewById(R.id.show_next_weapon_checkbox);
final CheckBox invertLookCheckBox = (CheckBox)dialog.findViewById(R.id.invert_loop_checkbox);
final CheckBox precisionShootCheckBox = (CheckBox)dialog.findViewById(R.id.precision_shoot_checkbox);
final CheckBox showSticksCheckBox = (CheckBox)dialog.findViewById(R.id.show_sticks_checkbox);
final CheckBox enableWeaponWheelCheckBox = (CheckBox)dialog.findViewById(R.id.enable_weapon_wheel_checkbox);
/*
//Hide controls for lookup/down
if (Settings.game == IDGame.Doom)
{
//pitchSeek.setVisibility(View.GONE);
invertLookCheckBox.setVisibility(View.GONE);
}
*/
Button add_rem_button = (Button)dialog.findViewById(R.id.add_remove_button);
add_rem_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TouchControlsEditing.show(activity);
}
});
alphaSeek.setProgress(alpha);
fwdSeek.setProgress(fwdSens);
strafeSeek.setProgress(strafeSens);
pitchSeek.setProgress(pitchSens);
yawSeek.setProgress(yawSens);
mouseModeCheck.setChecked(mouseMode);
showWeaponCycleCheckBox.setChecked(showWeaponCycle);
invertLookCheckBox.setChecked(invertLook);
precisionShootCheckBox.setChecked(precisionShoot);
showSticksCheckBox.setChecked(showSticks);
enableWeaponWheelCheckBox.setChecked(enableWeaponWheel);
Spinner move_spinner = (Spinner) dialog.findViewById(R.id.move_dbl_tap_spinner);
ArrayAdapter<CharSequence> adapterm;
adapterm = ArrayAdapter.createFromResource(activity,
R.array.double_tap_actions, android.R.layout.simple_spinner_item);
adapterm.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
move_spinner.setAdapter(adapterm);
move_spinner.setSelection(doubleTapMove);
move_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
doubleTapMove = pos;
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Spinner look_spinner = (Spinner) dialog.findViewById(R.id.look_dbl_tap_spinner);
ArrayAdapter<CharSequence> adapterl = ArrayAdapter.createFromResource(activity,
R.array.double_tap_actions, android.R.layout.simple_spinner_item);
adapterl.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
look_spinner.setAdapter(adapterl);
look_spinner.setSelection(doubleTapLook);
look_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
doubleTapLook = pos;
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
dialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
alpha = alphaSeek.getProgress();
fwdSens = fwdSeek.getProgress();
strafeSens = strafeSeek.getProgress();
pitchSens = pitchSeek.getProgress();
yawSens = yawSeek.getProgress();
mouseMode = mouseModeCheck.isChecked();
showWeaponCycle = showWeaponCycleCheckBox.isChecked();
invertLook = invertLookCheckBox.isChecked();
precisionShoot = precisionShootCheckBox.isChecked();
showSticks = showSticksCheckBox.isChecked();
enableWeaponWheel = enableWeaponWheelCheckBox.isChecked();
saveSettings(activity);
sendToQuake();
}
});
Button save = (Button)dialog.findViewById(R.id.save_button);
save.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
alpha = alphaSeek.getProgress();
fwdSens = fwdSeek.getProgress();
strafeSens = strafeSeek.getProgress();
pitchSens = pitchSeek.getProgress();
yawSens = yawSeek.getProgress();
mouseMode = mouseModeCheck.isChecked();
showWeaponCycle = showWeaponCycleCheckBox.isChecked();
invertLook = invertLookCheckBox.isChecked();
precisionShoot = precisionShootCheckBox.isChecked();
showSticks = showSticksCheckBox.isChecked();
enableWeaponWheel = enableWeaponWheelCheckBox.isChecked();
saveSettings(activity);
sendToQuake();
dialog.dismiss();
}
});
Button cancel = (Button)dialog.findViewById(R.id.cancel_button);
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
});
}
public static void sendToQuake()
{
int other = 0;
other += showWeaponCycle?0x1:0;
other += mouseMode?0x2:0;
other += invertLook?0x4:0;
other += precisionShoot?0x8:0;
other += (doubleTapMove << 4) & 0xF0;
other += (doubleTapLook << 8) & 0xF00;
other += showSticks?0x1000:0;
other += enableWeaponWheel?0x2000:0;
other += Settings.hideTouchControls?0x80000000:0;
quakeIf.setTouchSettings_if(
(float)alpha/(float)100,
(strafeSens)/(float)50,
(fwdSens)/(float)50,
(pitchSens)/(float)50,
(yawSens)/(float)50,
other);
}
public static void loadSettings(Context ctx)
{
alpha = Settings.getIntOption(ctx, "alpha", 50);
fwdSens = Settings.getIntOption(ctx, "fwdSens", 50);
strafeSens = Settings.getIntOption(ctx, "strafeSens", 50);
pitchSens = Settings.getIntOption(ctx, "pitchSens", 50);
yawSens = Settings.getIntOption(ctx, "yawSens", 50);
showWeaponCycle = Settings.getBoolOption(ctx, "show_weapon_cycle", true);
mouseMode = Settings.getBoolOption(ctx, "mouse_mode", true);
invertLook = Settings.getBoolOption(ctx, "invert_look", false);
precisionShoot = Settings.getBoolOption(ctx, "precision_shoot", false);
showSticks = Settings.getBoolOption(ctx, "show_sticks", false);
enableWeaponWheel = Settings.getBoolOption(ctx, "enable_ww", true);
doubleTapMove = Settings.getIntOption(ctx, "double_tap_move", 0);
doubleTapLook = Settings.getIntOption(ctx, "double_tap_look", 0);
}
public static void saveSettings(Context ctx)
{
Settings.setIntOption(ctx, "alpha", alpha);
Settings.setIntOption(ctx, "fwdSens", fwdSens);
Settings.setIntOption(ctx, "strafeSens", strafeSens);
Settings.setIntOption(ctx, "pitchSens", pitchSens);
Settings.setIntOption(ctx, "yawSens", yawSens);
Settings.setBoolOption(ctx, "show_weapon_cycle", showWeaponCycle);
Settings.setBoolOption(ctx, "invert_look", invertLook);
Settings.setBoolOption(ctx, "precision_shoot", precisionShoot);
Settings.setBoolOption(ctx, "show_sticks", showSticks);
Settings.setBoolOption(ctx, "enable_ww", enableWeaponWheel);
Settings.setIntOption(ctx, "double_tap_move", doubleTapMove);
Settings.setIntOption(ctx, "double_tap_look", doubleTapLook);
}
}

File diff suppressed because it is too large Load Diff