initial checkin of java source for android port

This commit is contained in:
eehouse 2010-01-02 19:30:20 +00:00
parent 1a5ae00777
commit d206aef266
28 changed files with 1781 additions and 0 deletions

View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project
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.
-->
<!-- Declare the contents of this Android application. The namespace
attribute brings in the Android platform namespace, and the package
supplies a unique name for the application. When writing your
own application, the package name must be changed from "com.example.*"
to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eehouse.android.xw4"
>
<application android:icon="@drawable/icon48x48"
android:label="@string/app_name"
>
<activity android:name="GamesList" android:label="@string/title_games_list">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.eehouse.org.game" />
</intent-filter>
</activity>
<activity android:name="GameConfig"
android:theme="@android:style/Theme.Light"
android:label="@string/title_game"
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation"
>
<!-- This filter says that we can view or edit the data of
a single note -->
<intent-filter android:label="@string/resolve_edit">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="org.eehouse.android.xw4.action.EDIT_GAME" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.eehouse.android.xw4.game" />
</intent-filter>
</activity>
<activity android:name="BoardActivity"
android:theme="@android:style/Theme.Light"
android:label="@string/title_game"
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation"
>
<!-- This filter says that we can edit the data of a game, i.e. play -->
<intent-filter android:label="@string/play">
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.org.eehouse.android.xw4.game" />
</intent-filter>
<!-- This filter says that we can create a new note inside
of a directory of notes. -->
<!--intent-filter>
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter-->
</activity>
</application>
</manifest>

Binary file not shown.

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="XWords4" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked in in Version
Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the default property values
used by the Ant rules.
Here are some properties you may want to change/update:
application.package
the name of your application package as defined in the manifest. Used by the
'uninstall' rule.
source.dir
the name of the source directory. Default is 'src'.
out.dir
the name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should be updated
using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android' tool, as well
as ADT.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- Execute the Android Setup task that will setup some properties specific to the target,
and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/templates/android_rules.xml
To customize some build steps for your project:
- copy the content of the main node <project> from android_rules.xml
- paste it in this build.xml below the <setup /> task.
- disable the import by changing the setup task below to <setup import="false" />
This will ensure that the properties are setup correctly but that your customized
build steps are used.
-->
<setup />
</project>

View file

@ -0,0 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-3

View file

@ -0,0 +1,10 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/andy/android-sdk-linux

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<org.eehouse.android.xw4.BoardView
android:id="@+id/board_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:clickable="true"
android:longClickable="true"
android:drawSelectorOnTop="false"/>
</LinearLayout>

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="4dip"
android:text="@string/player_label"
/>
<EditText
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:id="@+id/player_1_name"
/>
<TextView
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="4dip"
android:text="@string/player_label"
/>
<EditText
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:id="@+id/player_2_name"
/>
<Button android:id="@+id/game_config_open"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/game_config_open" />
<Button android:id="@+id/game_config_done"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/game_config_done" />
</LinearLayout>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<Button android:id="@+id/new_game"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/button_new_game" />
</LinearLayout>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/board_menu_done"
android:title="@string/board_menu_done" />
<item android:id="@+id/board_menu_juggle"
android:title="@string/board_menu_juggle" />
<item android:id="@+id/board_menu_flip"
android:title="@string/board_menu_flip" />
<item android:id="@+id/board_menu_trade"
android:title="@string/board_menu_trade" />
<item android:id="@+id/board_menu_tray"
android:title="@string/board_menu_tray" />
<item android:title="@string/board_submenu_undo">
<menu>
<item android:id="@+id/board_menu_undo_current"
android:title="@string/board_menu_undo_current" />
<item android:id="@+id/board_menu_undo_last"
android:title="@string/board_menu_undo_last" />
</menu>
</item>
<item android:title="@string/board_submenu_hint">
<menu>
<item android:id="@+id/board_menu_hint_next"
android:title="@string/board_menu_hint_next" />
<item android:id="@+id/board_menu_hint"
android:title="@string/board_menu_hint" />
</menu>
</item>
<item android:title="@string/board_submenu_game">
<menu>
<item android:id="@+id/board_menu_game_counts"
android:title="@string/board_menu_game_counts" />
<item android:id="@+id/board_menu_game_left"
android:title="@string/board_menu_game_left" />
<item android:id="@+id/board_menu_game_info"
android:title="@string/board_menu_game_info" />
<item android:id="@+id/board_menu_game_history"
android:title="@string/board_menu_game_history" />
<item android:id="@+id/board_menu_game_final"
android:title="@string/board_menu_game_final" />
<item android:id="@+id/board_menu_game_resend"
android:title="@string/board_menu_game_resend" />
</menu>
</item>
<item android:title="@string/board_submenu_file">
<menu>
<item android:id="@+id/board_menu_file_new"
android:title="@string/board_menu_file_new" />
<item android:id="@+id/board_menu_file_prefs"
android:title="@string/board_menu_file_prefs" />
<item android:id="@+id/board_menu_file_about"
android:title="@string/board_menu_file_about" />
</menu>
</item>
</menu>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/list_item_open"
android:title="@string/list_item_open" />
<item android:id="@+id/list_item_view"
android:title="@string/list_item_view" />
<item android:id="@+id/list_item_hide"
android:title="@string/list_item_hide" />
<item android:id="@+id/list_item_delete"
android:title="@string/list_item_delete" />
</menu>

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project
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.
-->
<resources>
<string name="menu_delete">Delete</string>
<string name="menu_insert">Add game</string>
<string name="button_new_game">Add game</string>
<string name="menu_revert">Revert</string>
<string name="menu_discard">Discard</string>
<string name="list_item_open">Open</string>
<string name="list_item_view">View</string>
<string name="list_item_hide">Hide</string>
<string name="list_item_delete">Delete</string>
<string name="resolve_edit">Edit note</string>
<string name="resolve_title">Edit title</string>
<string name="play">Play game</string>
<string name="title_create">Create game</string>
<string name="title_edit">Edit game</string>
<string name="title_games_list">Crosswords</string>
<string name="title_game">Game</string>
<string name="title_edit_title">Game name:</string>
<string name="app_name">Crosswords</string>
<string name="button_ok">OK</string>
<string name="player_label">Name:</string>
<string name="game_config_open">Open</string>
<string name="game_config_done">Done</string>
<string name="error_title">Error</string>
<string name="error_message">Error loading game</string>
<!-- system menu for main board view -->
<string name="board_menu_done">Turn done</string>
<string name="board_menu_juggle">Juggle</string>
<string name="board_menu_flip">Flip</string>
<string name="board_menu_trade">Trade</string>
<string name="board_menu_tray">Hide/Show</string>
<string name="board_submenu_undo">Undo</string>
<string name="board_menu_undo_current">Undo current</string>
<string name="board_menu_undo_last">Undo last</string>
<string name="board_submenu_hint">Hint</string>
<string name="board_menu_hint_next">Next hint</string>
<string name="board_menu_hint">Hint</string>
<string name="board_submenu_game">Game</string>
<string name="board_menu_game_counts">Counts and values</string>
<string name="board_menu_game_left">Tiles remaining</string>
<string name="board_menu_game_info">Game info</string>
<string name="board_menu_game_history">Game history</string>
<string name="board_menu_game_final">Final scores</string>
<string name="board_menu_game_resend">Resend messages</string>
<string name="board_submenu_file">File</string>
<string name="board_menu_file_new">New game</string>
<string name="board_menu_file_prefs">Preferences</string>
<string name="board_menu_file_about">About Crosswords</string>
</resources>

View file

@ -0,0 +1,205 @@
package org.eehouse.android.xw4;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.content.res.AssetManager;
import java.io.InputStream;
import android.os.Handler;
import org.eehouse.android.xw4.jni.*;
public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
private BoardView m_view;
private int m_jniGamePtr;
private CurGameInfo m_gi;
private CommonPrefs m_prefs;
private Handler m_handler;
private TimerRunnable[] m_timers;
public class TimerRunnable implements Runnable {
private int m_gamePtr;
private int m_why;
private int m_when;
private int m_handle;
private TimerRunnable( int why, int when, int handle ) {
m_why = why;
m_when = when;
m_handle = handle;
}
public void run() {
Utils.logf( "TimerRunnable.run(); m_handle=" + m_handle );
m_timers[m_why] = null;
XwJNI.timerFired( m_jniGamePtr, m_why, m_when, m_handle );
}
}
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.board );
m_handler = new Handler();
m_timers = new TimerRunnable[4]; // needs to be in sync with XWTimerReason
m_prefs = new CommonPrefs();
m_gi = new CurGameInfo();
m_view = (BoardView)findViewById( R.id.board_view );
byte[] dictBytes = null;
InputStream dict = null;
AssetManager am = getAssets();
try {
dict = am.open( m_gi.dictName,
android.content.res.AssetManager.ACCESS_RANDOM );
Utils.logf( "opened dict" );
int len = dict.available();
Utils.logf( "dict size: " + len );
dictBytes = new byte[len];
int nRead = dict.read( dictBytes, 0, len );
if ( nRead != len ) {
Utils.logf( "**** warning ****; read only " + nRead + " of "
+ len + " bytes." );
}
} catch ( java.io.IOException ee ){
Utils.logf( "failed to open" );
}
// am.close(); don't close! won't work subsequently
Utils.logf( "calling game_makeNewGame; passing bytes: " + dictBytes.length );
m_jniGamePtr = XwJNI.game_makeNewGame( m_gi, this, m_view, 0,
m_prefs, null, dictBytes );
m_view.startHandling( m_jniGamePtr, m_gi );
XwJNI.server_do( m_jniGamePtr );
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.board_menu, menu );
return true;
}
private boolean toggleTray() {
boolean draw;
int state = XwJNI.board_getTrayVisState( m_jniGamePtr );
if ( state == XwJNI.TRAY_REVEALED ) {
draw = XwJNI.board_hideTray( m_jniGamePtr );
} else {
draw = XwJNI.board_showTray( m_jniGamePtr );
}
return draw;
}
public boolean onOptionsItemSelected(MenuItem item) {
boolean draw = false;
boolean handled = true;
switch (item.getItemId()) {
case R.id.board_menu_done:
draw = XwJNI.board_commitTurn( m_jniGamePtr );
break;
case R.id.board_menu_juggle:
draw = XwJNI.board_juggleTray( m_jniGamePtr );
break;
case R.id.board_menu_flip:
draw = XwJNI.board_flip( m_jniGamePtr );
break;
case R.id.board_menu_tray:
draw = toggleTray();
break;
case R.id.board_menu_undo_current:
draw = XwJNI.board_replaceTiles( m_jniGamePtr );
break;
case R.id.board_menu_undo_last:
XwJNI.server_handleUndo( m_jniGamePtr );
draw = true;
break;
case R.id.board_menu_hint:
XwJNI.board_resetEngine( m_jniGamePtr );
// fallthru
case R.id.board_menu_hint_next:
draw = XwJNI.board_requestHint( m_jniGamePtr, false, null );
break;
default:
Utils.logf( "menuitem " + item.getItemId() + " not handled" );
handled = false;
}
if ( draw ) {
m_view.invalidate();
}
return handled;
}
//////////////////////////////////////////
// XW_UtilCtxt interface implementation //
//////////////////////////////////////////
static final int[] s_buttsBoard = {
BONUS_TRIPLE_WORD, BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_WORD,
BONUS_NONE, BONUS_DOUBLE_WORD, BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE,
BONUS_NONE, BONUS_NONE, BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,
BONUS_DOUBLE_LETTER,BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER,
BONUS_NONE, BONUS_NONE, BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE,
BONUS_NONE, BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE,
BONUS_NONE, BONUS_NONE, BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,
BONUS_TRIPLE_WORD, BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_WORD,
}; /* buttsBoard */
public int getSquareBonus( int col, int row ) {
int bonus = BONUS_NONE;
if ( col > 7 ) { col = 14 - col; }
if ( row > 7 ) { row = 14 - row; }
int index = (row*8) + col;
if ( index < 8*8 ) {
bonus = s_buttsBoard[index];
}
return bonus;
}
public void run() {
Utils.logf( "run called" );
if ( XwJNI.server_do( m_jniGamePtr ) ) {
m_view.invalidate();
}
}
public void requestTime() {
m_handler.post( this );
}
public void setTimer( int why, int when, int handle )
{
Utils.logf( "setTimer called" );
if ( null != m_timers[why] ) {
m_handler.removeCallbacks( m_timers[why] );
}
m_timers[why] = new TimerRunnable( why, when, handle );
m_handler.postDelayed( m_timers[why], 500 );
}
public void clearTimer( int why )
{
Utils.logf( "clearTimer called" );
if ( null != m_timers[why] ) {
m_handler.removeCallbacks( m_timers[why] );
m_timers[why] = null;
}
}
}

View file

@ -0,0 +1,290 @@
package org.eehouse.android.xw4;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.content.Context;
import android.util.AttributeSet;
import org.eehouse.android.xw4.jni.*;
import android.view.MotionEvent;
public class BoardView extends View implements DrawCtx,
BoardHandler {
private Paint m_fillPaint;
private Paint m_strokePaint;
private int m_jniGamePtr;
private CurGameInfo m_gi;
private boolean m_boardSet = false;
private Canvas m_canvas;
private int m_trayOwner;
private Rect m_valRect;
private Rect m_letterRect;
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int TILE_BACK = 0xFFFFFF99;
private int [] m_bonusColors = { WHITE, // BONUS_NONE
0xFFAFAF00, /* bonus 1 */
0xFF00AFAF,
0xFFAF00AF,
0xFFAFAFAF };
private static final int[] m_playerColors = {
0xFF000000,
0xFFFF0000,
0xFF0000FF,
0xFF008F00,
};
public BoardView( Context context ) {
super( context );
init();
}
// called when inflating xml
public BoardView( Context context, AttributeSet attrs ) {
super( context, attrs );
init();
}
// public boolean onClick( View view ) {
// Utils.logf( "onClick called" );
// return view == this;
// }
public boolean onTouchEvent( MotionEvent event ) {
int action = event.getAction();
int xx = (int)event.getX();
int yy = (int)event.getY();
boolean draw = false;
switch ( action ) {
case MotionEvent.ACTION_DOWN:
boolean[] handled = new boolean[1];
draw = XwJNI.board_handlePenDown( m_jniGamePtr, xx, yy, handled );
break;
case MotionEvent.ACTION_MOVE:
draw = XwJNI.board_handlePenMove( m_jniGamePtr, xx, yy );
break;
case MotionEvent.ACTION_UP:
draw = XwJNI.board_handlePenUp( m_jniGamePtr, xx, yy );
break;
default:
Utils.logf( "unknown action: " + action );
Utils.logf( event.toString() );
}
if ( draw ) {
invalidate();
}
return true; // required to get subsequent events
}
protected void onDraw( Canvas canvas ) {
if ( layoutBoardOnce() ) {
m_canvas = canvas; // save for callbacks
XwJNI.board_invalAll( m_jniGamePtr ); // get rid of this!
if ( XwJNI.board_draw( m_jniGamePtr ) ) {
Utils.logf( "draw succeeded" );
}
m_canvas = null; // clear!
}
}
private void init() {
setFocusable(true);
setBackgroundDrawable( null );
m_fillPaint = new Paint();
m_fillPaint.setTextAlign( Paint.Align.CENTER ); // center horizontally
m_strokePaint = new Paint();
m_strokePaint.setStyle( Paint.Style.STROKE );
// Move this to finalize?
// XwJNI.game_dispose( jniGamePtr );
// Utils.logf( "game_dispose returned" );
// jniGamePtr = 0;
}
private boolean layoutBoardOnce() {
if ( !m_boardSet && null != m_gi ) {
m_boardSet = true;
// For now we're assuming vertical orientation. Fix way
// later.
int width = getWidth();
int height = getHeight();
int nCells = m_gi.boardSize;
int cellSize = width / nCells;
int border = (width % nCells) / 2;
int scoreHt = cellSize; // scoreboard ht same as cells for
// proportion
XwJNI.board_setPos( m_jniGamePtr, border, border+cellSize, false );
XwJNI.board_setScale( m_jniGamePtr, cellSize, cellSize );
XwJNI.board_setScoreboardLoc( m_jniGamePtr, border, border,
nCells * cellSize, // width
scoreHt, true );
XwJNI.board_setTrayLoc( m_jniGamePtr, border,
border + scoreHt + (nCells * cellSize),
nCells * cellSize, // width
cellSize * 2, // height
4 );
XwJNI.board_setShowColors( m_jniGamePtr, true );
XwJNI.board_invalAll( m_jniGamePtr );
}
return m_boardSet;
}
public void startHandling( int gamePtr, CurGameInfo gi ) {
m_jniGamePtr = gamePtr;
m_gi = gi;
}
// DrawCtxt interface implementation
public void measureRemText( Rect r, int nTilesLeft, int[] width, int[] height ) {
width[0] = 30;
height[0] = r.bottom - r.top;
}
public void measureScoreText( Rect r, DrawScoreInfo dsi, int[] width, int[] height )
{
width[0] = 60;
height[0] = r.bottom - r.top;
}
public void drawRemText( Rect rInner, Rect rOuter, int nTilesLeft, boolean focussed )
{
String text = String.format( "%d", nTilesLeft ); // should cache a formatter
m_fillPaint.setColor( TILE_BACK );
m_canvas.drawRect( rOuter, m_fillPaint );
m_fillPaint.setTextSize( rInner.bottom - rInner.top );
m_fillPaint.setColor( BLACK );
drawCentered( text, rInner );
}
public void score_drawPlayer( Rect rInner, Rect rOuter, DrawScoreInfo dsi )
{
String text = String.format( "%s:%d", dsi.name, dsi.totalScore );
m_fillPaint.setTextSize( rInner.bottom - rInner.top );
m_fillPaint.setColor( m_playerColors[dsi.playerNum] );
drawCentered( text, rInner );
}
public boolean drawCell( Rect rect, String text, Object[] bitmaps, int tile,
int owner, int bonus, int hintAtts, int flags )
{
int backColor;
int foreColor = WHITE; // must be initialized :-(
boolean empty = null == text && null == bitmaps;
boolean pending = 0 != (flags & CELL_HIGHLIGHT);
if ( empty ) {
backColor = m_bonusColors[bonus];
} else if ( pending ) {
backColor = BLACK;
} else {
backColor = TILE_BACK;
foreColor = m_playerColors[owner];
}
m_fillPaint.setColor( backColor );
m_canvas.drawRect( rect, m_fillPaint );
if ( !empty ) {
m_fillPaint.setTextSize( rect.bottom - rect.top );
if ( owner < 0 ) { // showColors option not turned on
owner = 0;
}
m_fillPaint.setColor( foreColor );
drawCentered( text, rect );
}
m_canvas.drawRect( rect, m_strokePaint );
return true;
}
public boolean trayBegin ( Rect rect, int owner, int dfs ) {
m_trayOwner = owner;
return true;
}
public void drawTile( Rect rect, String text, Object[] bitmaps, int val,
int flags ) {
boolean valHidden = (flags & CELL_VALHIDDEN) != 0;
boolean notEmpty = (flags & CELL_ISEMPTY) == 0;
boolean isCursor = (flags & CELL_ISCURSOR) != 0;
if ( isCursor || notEmpty ) {
m_fillPaint.setColor( TILE_BACK );
m_canvas.drawRect( rect, m_fillPaint );
if ( null != text ) {
m_fillPaint.setColor( m_playerColors[m_trayOwner] );
positionDrawTile( rect, text, val );
}
m_canvas.drawRect( rect, m_strokePaint ); // frame
}
}
public void drawTileMidDrag ( Rect rect, String text, Object[] bitmaps,
int val, int owner, int flags )
{
drawTile( rect, text, bitmaps, val, flags );
}
public void drawTileBack( Rect rect, int flags )
{
drawTile( rect, "?", null, 0, flags );
}
public void drawTrayDivider( Rect rect, int flags )
{
m_fillPaint.setColor( BLACK ); // black for now
m_canvas.drawRect( rect, m_fillPaint );
}
public void score_pendingScore( Rect rect, int score, int playerNum,
int flags )
{
String text = score >= 0? String.format( "%d", score ) : "??";
m_fillPaint.setColor( BLACK );
m_fillPaint.setTextSize( (rect.bottom - rect.top) / 2 );
drawCentered( text, rect );
}
private void drawCentered( String text, Rect rect ) {
int bottom = rect.bottom;
int center = rect.left + ( (rect.right - rect.left) / 2 );
m_canvas.drawText( text, center, bottom, m_fillPaint );
}
private void positionDrawTile( Rect rect, String text, int val )
{
if ( null == m_letterRect ) {
// assumes show values is on
m_letterRect = new Rect( 0, 0, rect.width() * 3 / 4, rect.height() * 3 / 4 );
}
m_letterRect.offsetTo( rect.left, rect.top );
m_fillPaint.setTextSize( m_letterRect.height() );
drawCentered( text, m_letterRect );
if ( null == m_valRect ) {
m_valRect = new Rect( 0, 0, rect.width() / 4, rect.height() / 4 );
}
m_valRect.offsetTo( rect.right - (rect.width() / 4),
rect.bottom - (rect.height() / 4) );
text = String.format( "%d", val );
m_fillPaint.setTextSize( m_valRect.height() );
drawCentered( text, m_valRect );
}
}

View file

@ -0,0 +1,183 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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 org.eehouse.android.xw4;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.PrintStream;
import java.io.FileOutputStream;
import android.text.Editable;
/**
* A generic activity for editing a note in a database. This can be used
* either to simply view a note {@link Intent#ACTION_VIEW}, view and edit a note
* {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.
*/
public class GameConfig extends Activity implements View.OnClickListener {
private static final String TAG = "Games";
/** The index of the note column */
private static final int COLUMN_INDEX_NOTE = 1;
// This is our state data that is stored when freezing.
private static final String ORIGINAL_CONTENT = "origContent";
// Identifiers for our menu items.
private static final int REVERT_ID = Menu.FIRST;
private static final int DISCARD_ID = Menu.FIRST + 1;
private static final int DELETE_ID = Menu.FIRST + 2;
// The different distinct states the activity can be run in.
private static final int STATE_EDIT = 0;
private static final int STATE_INSERT = 1;
private int mState;
private boolean mNoteOnly = false;
private Uri mUri;
private String mOriginalContent;
private Button mDoneB;
private Button mOpenB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
// Do some setup based on the action being performed.
final String action = intent.getAction();
Utils.logf( "action: " + action );
if (Intent.ACTION_EDIT.equals(action)) {
// Requested to edit: set that state, and the data being edited.
mState = STATE_EDIT;
mUri = intent.getData();
} else if (Intent.ACTION_INSERT.equals(action)) {
Utils.logf( "matches insert" );
// Requested to insert: set that state, and create a new entry
// in the container.
mState = STATE_INSERT;
// mUri = getContentResolver().insert(intent.getData(), null);
// Utils.logf( mUri.toString() );
// If we were unable to create a new note, then just finish
// this activity. A RESULT_CANCELED will be sent back to the
// original activity if they requested a result.
// if (mUri == null) {
// Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
// finish();
// return;
// }
// The new entry was created, so assume all will end well and
// set the result to be returned.
// setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
} else {
// Whoops, unknown action! Bail.
Utils.logf("Unknown action, exiting");
finish();
return;
}
setContentView(R.layout.game_config);
mOpenB = (Button)findViewById(R.id.game_config_open);
mOpenB.setOnClickListener( this );
mDoneB = (Button)findViewById(R.id.game_config_done);
mDoneB.setOnClickListener( this );
// If an instance of this activity had previously stopped, we can
// get the original text it started with.
// if (savedInstanceState != null) {
// mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
// }
} // onCreate
public void onClick( View view ) {
if ( mDoneB == view ) {
EditText et = (EditText)findViewById( R.id.player_1_name );
Editable text = et.getText();
String name1 = text.toString();
et = (EditText)findViewById( R.id.player_2_name );
text = et.getText();
String name2 = text.toString();
if ( name1.length() > 0 && name2.length() > 0 ) {
Integer num = 0;
int ii;
String[] files = fileList();
String name = null;
while ( name == null ) {
name = "game " + num.toString();
for ( ii = 0; ii < files.length; ++ii ) {
Utils.logf( "comparing " + name + " with " + files[ii] );
if ( files[ii].equals(name) ) {
++num;
name = null;
}
}
}
Utils.logf( "using name " + name );
FileOutputStream out;
try {
out = openFileOutput( name, MODE_PRIVATE );
PrintStream ps = new PrintStream( out );
ps.println( name1 );
ps.println( name2 );
ps.close();
try {
out.close();
} catch ( java.io.IOException ex ) {
Utils.logf( "got IOException: " + ex.toString() );
}
} catch ( java.io.FileNotFoundException ex ) {
Utils.logf( "got FileNotFoundException: " + ex.toString() );
}
}
finish();
} else if ( mOpenB == view ) {
// finish but after posting an intent that'll cause the
// list view to launch us -- however that's done.
Utils.logf( "got open" );
} else {
Utils.logf( "unknown v: " + view.toString() );
}
} // onClick
}

View file

@ -0,0 +1,93 @@
package org.eehouse.android.xw4;
import android.widget.Adapter;
import android.widget.ListAdapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.database.DataSetObserver;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.CharBuffer;
public class GameListAdapter implements ListAdapter {
Context m_context;
String[] m_files;
public GameListAdapter( Context context ) {
m_context = context;
m_files = context.fileList();
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled( int position ) {
return true;
}
public int getCount() {
return m_files.length;
}
public Object getItem( int position ) {
TextView view = new TextView(m_context);
try {
FileInputStream in = m_context.openFileInput( m_files[position] );
InputStreamReader reader = new InputStreamReader( in );
try {
int len = in.available();
CharBuffer buf = CharBuffer.allocate(len);
reader.read( buf.array(), 0, len );
reader.close();
view.setText( buf );
} catch ( java.io.IOException ex ) {
Utils.logf( "got IOException: " + ex.toString() );
}
try {
in.close();
} catch ( java.io.IOException ex ) {
Utils.logf( "got IOException: " + ex.toString() );
}
} catch ( java.io.FileNotFoundException ex ) {
Utils.logf( "got FileNotFoundException: " + ex.toString() );
}
return view;
}
public long getItemId( int position ) {
return position;
}
public int getItemViewType( int position ) {
return 0;
}
public View getView( int position, View convertView, ViewGroup parent ) {
return (View)getItem( position );
}
public int getViewTypeCount() {
return 1;
}
public boolean hasStableIds() {
return true;
}
public boolean isEmpty() {
return getCount() == 0;
}
public void registerDataSetObserver(DataSetObserver observer) {}
public void unregisterDataSetObserver(DataSetObserver observer) {}
}

View file

@ -0,0 +1,253 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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 org.eehouse.android.xw4;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.content.res.AssetManager;
import java.io.InputStream;
import android.widget.Button;
import android.view.MenuInflater;
import org.eehouse.android.xw4.XWords4.Games; // for constants
public class GamesList extends ListActivity implements View.OnClickListener {
private static final String TAG = "GamesList";
// private InputStream m_dict;
private GameListAdapter m_adapter;
// Menu item ids
public static final int MENU_ITEM_DELETE = Menu.FIRST;
public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_list);
// setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
// AssetManager am = getAssets();
// try {
// m_dict = am.open( "BasEnglish2to8.xwd",
// android.content.res.AssetManager.ACCESS_RANDOM );
// Utils.logf( "opened" );
// } catch ( java.io.IOException ee ){
// m_dict = null;
// Utils.logf( "failed to open" );
// }
m_adapter = new GameListAdapter( this );
setListAdapter( m_adapter );
registerForContextMenu( getListView() );
Button newGameB = (Button)findViewById(R.id.new_game);
newGameB.setOnClickListener( this );
Utils.logf( "got button" );
// If no data was given in the intent (because we were started
// as a MAIN activity), then use our default content provider.
Intent intent = getIntent();
Utils.logf( intent.toString() );
if (intent.getData() == null) {
intent.setData(Games.CONTENT_URI);
}
// Inform the list we provide context menus for items
// getListView().setOnCreateContextMenuListener(this);
// Perform a managed query. The Activity will handle closing
// and requerying the cursor when needed.
// Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
// Notes.DEFAULT_SORT_ORDER);
// Used to map notes entries from the database to views
// SimpleCursorAdapter adapter =
// new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
// new String[] { Notes.TITLE },
// new int[] { android.R.id.text1 });
// setListAdapter(adapter);
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// super.onCreateOptionsMenu(menu);
// // This is our one standard application action -- inserting a
// // new note into the list.
// menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
// .setShortcut('3', 'a')
// .setIcon(android.R.drawable.ic_menu_add);
// // Generate any additional actions that can be performed on the
// // overall list. In a normal install, there are no additional
// // actions found here, but this allows other applications to extend
// // our menu with their own actions.
// Intent intent = new Intent(null, getIntent().getData());
// intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
// menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
// new ComponentName(this, GamesList.class), null, intent, 0, null);
// return true;
// }
// @Override
// public boolean onPrepareOptionsMenu(Menu menu) {
// super.onPrepareOptionsMenu(menu);
// final boolean haveItems = getListAdapter().getCount() > 0;
// // If there are any notes in the list (which implies that one of
// // them is selected), then we need to generate the actions that
// // can be performed on the current selection. This will be a combination
// // of our own specific actions along with any extensions that can be
// // found.
// if (haveItems) {
// // This is the selected item.
// Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
// // Build menu... always starts with the EDIT action...
// Intent[] specifics = new Intent[1];
// specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
// MenuItem[] items = new MenuItem[1];
// // ... is followed by whatever other actions are available...
// Intent intent = new Intent(null, uri);
// intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
// menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
// items);
// // Give a shortcut to the edit action.
// if (items[0] != null) {
// items[0].setShortcut('1', 'e');
// }
// } else {
// menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
// }
// return true;
// }
// @Override
// public boolean onOptionsItemSelected(MenuItem item) {
// switch (item.getItemId()) {
// case MENU_ITEM_INSERT:
// // Launch activity to insert a new item
// startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
// return true;
// }
// return super.onOptionsItemSelected(item);
// }
@Override
public void onCreateContextMenu( ContextMenu menu, View view,
ContextMenuInfo menuInfo ) {
// AdapterView.AdapterContextMenuInfo info;
// try {
// info = (AdapterView.AdapterContextMenuInfo) menuInfo;
// } catch (ClassCastException e) {
// Log.e(TAG, "bad menuInfo", e);
// return;
// }
Utils.logf( "onCreateContextMenu called" );
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.games_list_item_menu, menu );
// Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
// if (cursor == null) {
// // For some reason the requested item isn't available, do nothing
// return;
// }
// Setup the menu header
// menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
}
private void doOpen() {
Intent intent = new Intent( Intent.ACTION_EDIT );
intent.setClassName( "org.eehouse.android.xw4",
"org.eehouse.android.xw4.BoardActivity");
startActivity( intent );
}
@Override
public boolean onContextItemSelected( MenuItem item ) {
boolean handled = false;
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
switch (item.getItemId()) {
case R.id.list_item_open:
doOpen();
handled = true;
break;
case R.id.list_item_view:
Utils.logf( "view" );
handled = true;
break;
case R.id.list_item_hide:
Utils.logf( "hide" );
handled = true;
break;
case R.id.list_item_delete:
Utils.logf( "delete" );
handled = true;
break;
}
return handled;
}
public void onClick( View v ) {
Intent intent = new Intent();
intent.setClassName( "org.eehouse.android.xw4",
"org.eehouse.android.xw4.GameConfig");
intent.setAction( Intent.ACTION_INSERT );
startActivity( intent );
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
doOpen();
}
static {
System.loadLibrary("xwjni");
}
}

View file

@ -0,0 +1,20 @@
package org.eehouse.android.xw4;
import android.util.Log;
import java.text.MessageFormat;
public class Utils {
static final String TAG = "EJAVA";
private Utils() {}
public static void logf( String format ) {
Log.d( TAG, format );
} // logf
public static void logf( String format, Object[] args ) {
MessageFormat mfmt = new MessageFormat( format );
logf( mfmt.format( args ) );
} // logf
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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 org.eehouse.android.xw4;
import android.net.Uri;
import android.provider.BaseColumns;
/**
* Convenience definitions
*/
public final class XWords4 {
public static final String AUTHORITY = "org.eehouse.android.xw4";
// This class cannot be instantiated
private XWords4() {}
/**
* Notes table
*/
public static final class Games implements BaseColumns {
// This class cannot be instantiated
private Games() {}
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/games");
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of notes.
*/
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.eehouse.org.xwgamesdir";
/**
* The MIME type of a {@link #CONTENT_URI} sub-directory of a single note.
*/
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.eehouse.org.xwgame";
/**
* The default sort order for this table
*/
public static final String DEFAULT_SORT_ORDER = "modified DESC";
/**
* The title of the note
* <P>Type: TEXT</P>
*/
//public static final String TITLE = "title";
/**
* The note itself
* <P>Type: binary</P>
*/
public static final String DATA = "data";
/**
* The timestamp for when the game was created
* <P>Type: INTEGER (long from System.curentTimeMillis())</P>
*/
public static final String CREATED_DATE = "created";
/**
* The timestamp for when the game was last modified
* <P>Type: INTEGER (long from System.curentTimeMillis())</P>
*/
public static final String MODIFIED_DATE = "modified";
}
}

View file

@ -0,0 +1,8 @@
package org.eehouse.android.xw4.jni;
public interface BoardHandler {
void startHandling( int gamePtr, CurGameInfo gi );
}

View file

@ -0,0 +1,15 @@
package org.eehouse.android.xw4.jni;
public class CommonPrefs {
public boolean showBoardArrow;
public boolean showRobotScores;
public boolean hideTileValues;
public boolean skipCommitConfirm;
public CommonPrefs() {
showBoardArrow = true;
showRobotScores = false;
hideTileValues = false;
skipCommitConfirm = true;
}
}

View file

@ -0,0 +1,40 @@
package org.eehouse.android.xw4.jni;
public class CurGameInfo {
private static final String BUILTIN_DICT = "OWL2_2to9.xwd";
public enum XWPhoniesChoice { PHONIES_IGNORE, PHONIES_WARN, PHONIES_DISALLOW };
public enum DeviceRole { SERVER_STANDALONE, SERVER_ISSERVER, SERVER_ISCLIENT };
public String dictName;
public LocalPlayer[] players;
public int gameID;
public int gameSeconds; /* for timer */
public int nPlayers;
public int boardSize;
public DeviceRole serverRole;
public boolean hintsNotAllowed;
public boolean timerEnabled;
public boolean allowPickTiles;
public boolean allowHintRect;
public int robotSmartness;
public XWPhoniesChoice phoniesAction;
public boolean confirmBTConnect; /* only used for BT */
public CurGameInfo() {
nPlayers = 3;
boardSize = 15;
players = new LocalPlayer[nPlayers];
serverRole = DeviceRole.SERVER_STANDALONE;
dictName = BUILTIN_DICT;
hintsNotAllowed = false;
players[0] = new LocalPlayer( "Eric", true );
players[1] = new LocalPlayer( "Kati" );
players[2] = new LocalPlayer( "Brynn", true );
}
}

View file

@ -0,0 +1,34 @@
package org.eehouse.android.xw4.jni;
import android.graphics.Rect;
public interface DrawCtx {
static final int CELL_NONE = 0x00;
static final int CELL_ISBLANK = 0x01;
static final int CELL_HIGHLIGHT = 0x02;
static final int CELL_ISSTAR = 0x04;
static final int CELL_ISCURSOR = 0x08;
static final int CELL_ISEMPTY = 0x10; /* of a tray tile slot */
static final int CELL_VALHIDDEN = 0x20; /* show letter only, not value */
static final int CELL_DRAGSRC = 0x40; /* where drag originated */
static final int CELL_DRAGCUR = 0x80; /* where drag is now */
static final int CELL_ALL = 0xFF;
void measureRemText( Rect r, int nTilesLeft, int[] width, int[] height );
void measureScoreText( Rect r, DrawScoreInfo dsi, int[] width, int[] height );
void drawRemText( Rect rInner,Rect rOuter, int nTilesLeft, boolean focussed );
void score_drawPlayer( Rect rInner, Rect rOuter, DrawScoreInfo dsi );
boolean drawCell( Rect rect, String text, Object[] bitmaps, int tile,
int owner, int bonus, int hintAtts, int flags );
boolean trayBegin ( Rect rect, int owner, int dfs );
void drawTile( Rect rect, String text, Object[] bitmaps, int val, int flags );
void drawTileMidDrag ( Rect rect, String text, Object[] bitmaps,
int val, int owner, int flags );
void drawTileBack( Rect rect, int flags );
void drawTrayDivider( Rect rect, int flags );
void score_pendingScore( Rect rect, int score, int playerNum, int flags );
}

View file

@ -0,0 +1,28 @@
package org.eehouse.android.xw4.jni;
public class DrawScoreInfo {
public static final int CELL_NONE = 0x00;
public static final int CELL_ISBLANK = 0x01;
public static final int CELL_HIGHLIGHT = 0x02;
public static final int CELL_ISSTAR = 0x04;
public static final int CELL_ISCURSOR = 0x08;
public static final int CELL_ISEMPTY = 0x10; /* of a tray tile slot */
public static final int CELL_VALHIDDEN = 0x20; /* show letter only, not value */
public static final int CELL_DRAGSRC = 0x40; /* where drag originated */
public static final int CELL_DRAGCUR = 0x80; /* where drag is now */
public static final int CELL_ALL = 0xFF;
// LastScoreCallback lsc;
// void* lscClosure;
public String name;
public int playerNum;
public int totalScore;
public int nTilesLeft; /* < 0 means don't use */
public int flags; // was CellFlags; use CELL_ constants above
public boolean isTurn;
public boolean selected;
public boolean isRemote;
public boolean isRobot;
};

View file

@ -0,0 +1,23 @@
package org.eehouse.android.xw4.jni;
public class LocalPlayer {
public String name;
public String password;
public int secondsUsed;
public boolean isRobot;
public boolean isLocal;
public LocalPlayer( String nm ) {
isLocal = true;
isRobot = false;
name = nm;
password = "";
}
public LocalPlayer( String nm, boolean robot ) {
this( nm );
isRobot = robot;
}
}

View file

@ -0,0 +1,5 @@
package org.eehouse.android.xw4.jni;
public interface TransportProcs {
}

View file

@ -0,0 +1,17 @@
package org.eehouse.android.xw4.jni;
public interface XW_UtilCtxt {
static final int BONUS_NONE = 0;
static final int BONUS_DOUBLE_LETTER = 1;
static final int BONUS_DOUBLE_WORD = 2;
static final int BONUS_TRIPLE_LETTER = 3;
static final int BONUS_TRIPLE_WORD = 4;
int getSquareBonus( int col, int row );
void setTimer( int why, int when, int handle );
void clearTimer( int why );
void requestTime();
}

View file

@ -0,0 +1,60 @@
package org.eehouse.android.xw4.jni;
// Collection of native methods
public class XwJNI {
/* XW_TrayVisState enum */
public static final int TRAY_HIDDEN = 0;
public static final int TRAY_REVERSED = 1;
public static final int TRAY_REVEALED = 2;
// Methods not part of the common interface but necessitated by
// how java/jni work (or perhaps my limited understanding of it.)
// callback into jni from java when timer set here fires.
public static native boolean timerFired( int gamePtr, int why,
int when, int handle );
// Game methods
public static native int game_makeNewGame( CurGameInfo gi, XW_UtilCtxt util,
DrawCtx draw, int gameID, CommonPrefs cp,
TransportProcs procs, byte[] dict );
public static native void game_dispose( int gamePtr );
// Board methods
public static native void board_invalAll( int gamePtr );
public static native boolean board_draw( int gamePtr );
public static native void board_setPos( int gamePtr, int left, int top,
boolean lefty );
public static native void board_setScale( int gamePtr, int hscale, int vscale );
public static native boolean board_setShowColors( int gamePtr, boolean on );
public static native void board_setScoreboardLoc( int gamePtr, int left,
int top, int width,
int height,
boolean divideHorizontally );
public static native void board_setTrayLoc( int gamePtr, int left,
int top, int width,
int height, int minDividerWidth );
public static native boolean board_handlePenDown( int gamePtr, int xx, int yy,
boolean[] handled );
public static native boolean board_handlePenMove( int gamePtr, int xx, int yy );
public static native boolean board_handlePenUp( int gamePtr, int xx, int yy );
public static native boolean board_juggleTray( int gamePtr );
public static native int board_getTrayVisState( int gamePtr );
public static native boolean board_hideTray( int gamePtr );
public static native boolean board_showTray( int gamePtr );
public static native boolean board_commitTurn( int gamePtr );
public static native boolean board_flip( int gamePtr );
public static native boolean board_replaceTiles( int gamePtr );
public static native void board_resetEngine( int gamePtr );
public static native boolean board_requestHint( int gamePtr, boolean useTileLimits,
boolean[] workRemains );
public static native void server_handleUndo( int gamePtr );
public static native boolean server_do( int gamePtr );
}