Merge branch 'relay_proxy' of ssh://xwords.git.sourceforge.net/gitroot/xwords/xwords into android_branch

This commit is contained in:
eehouse@eehouse.org 2010-11-06 14:43:57 -07:00 committed by Andy2
commit 8dad8750ba
17 changed files with 286 additions and 76 deletions

View file

@ -108,5 +108,7 @@
</intent-filter>
</activity>
<activity android:name="RelayGameActivity"/>
</application>
</manifest>

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- only one direct child possible -->
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:id="@+id/explain"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/explain_b1"
android:paddingLeft="8dp"
/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/explain_b2"
android:paddingLeft="8dp"
/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/explain_b3"
android:paddingLeft="8dp"
/>
<EditText android:id="@+id/room_edit"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:scrollHorizontally="false"
android:autoText="false"
android:capitalize="none"
android:singleLine="true"
android:selectAllOnFocus="true"
android:hint="@string/new_room_hint"
/>
<Button android:id="@+id/play_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/play"
/>
<Button android:id="@+id/config_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/advanced_config"
/>
</LinearLayout>
</ScrollView>

View file

@ -4,6 +4,9 @@
<item android:id="@+id/list_item_config"
android:title="@string/list_item_config"
/>
<!-- <item android:id="@+id/list_item_netconfig" -->
<!-- android:title="net (remove me)" -->
<!-- /> -->
<item android:id="@+id/list_item_copy"
android:title="@string/list_item_copy"
/>

View file

@ -472,4 +472,15 @@
game on the relay. You will be notified when the remaining
device[s] have joined your room and play can begin.</string>
<string name="relay_game_explainf">To start a basic networked two-player
game in %s over the network:</string>
<string name="explain_b1">• Agree on a room name with your friend</string>
<string name="explain_b2">• Put it in the box below and on
your friend\'s Android smartphone</string>
<string name="explain_b3">• Press the \"Play game\" button</string>
<string name="advanced_config">Advanced game settings</string>
</resources>

View file

@ -62,7 +62,7 @@ public class DictLangCache {
return code;
}
private static String getLangName( Context context, String name )
public static String getLangName( Context context, String name )
{
int code = getLangCode( context, name );
return getNamesArray(context)[code];

View file

@ -869,52 +869,12 @@ public class GameConfig extends XWActivity
private void applyChanges( boolean forceNew )
{
// This should be a separate function, commitChanges() or
// somesuch. But: do we have a way to save changes to a gi
// that don't reset the game, e.g. player name for standalone
// games?
byte[] dictBytes = GameUtils.openDict( this, m_gi.dictName );
int gamePtr = XwJNI.initJNI();
boolean madeGame = false;
if ( !forceNew ) {
byte[] stream = GameUtils.savedGame( this, m_path );
// Will fail if there's nothing in the stream but a gi.
madeGame = XwJNI.game_makeFromStream( gamePtr, stream,
JNIUtilsImpl.get(),
new CurGameInfo(this),
dictBytes, m_gi.dictName,
m_cp );
}
if ( forceNew || !madeGame ) {
m_gi.setInProgress( false );
m_gi.fixup();
XwJNI.game_makeNewGame( gamePtr, m_gi, JNIUtilsImpl.get(),
m_cp, dictBytes, m_gi.dictName );
}
if ( null != m_car ) {
XwJNI.comms_setAddr( gamePtr, m_car );
}
GameUtils.saveGame( this, gamePtr, m_gi, m_path );
GameSummary summary = new GameSummary();
XwJNI.game_summarize( gamePtr, m_gi.nPlayers, summary );
DBUtils.saveSummary( this, m_path, summary );
XwJNI.game_dispose( gamePtr );
GameUtils.applyChanges( this, m_gi, m_car, m_path, forceNew );
}
private void launchGame()
{
File file = new File( m_path );
Uri uri = Uri.fromFile( file );
Intent intent = new Intent( Intent.ACTION_EDIT, uri,
this, BoardActivity.class );
startActivity( intent );
finish();
GameUtils.launchGame( this, m_path );
}
private void refreshNames()

View file

@ -20,10 +20,14 @@
package org.eehouse.android.xw4;
import android.app.Activity;
import android.content.Context;
import java.io.InputStream;
import android.content.Intent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.net.Uri;
import java.util.ArrayList;
import android.content.res.AssetManager;
@ -357,6 +361,65 @@ public class GameUtils {
return path.substring( 0, path.lastIndexOf( XWConstants.GAME_EXTN ) );
}
public static void launchGame( Activity activity, String path )
{
File file = new File( path );
Uri uri = Uri.fromFile( file );
Intent intent = new Intent( Intent.ACTION_EDIT, uri,
activity, BoardActivity.class );
activity.startActivity( intent );
activity.finish();
}
public static void applyChanges( Context context, CurGameInfo gi,
CommsAddrRec car, String path,
boolean forceNew )
{
// This should be a separate function, commitChanges() or
// somesuch. But: do we have a way to save changes to a gi
// that don't reset the game, e.g. player name for standalone
// games?
byte[] dictBytes = GameUtils.openDict( context, gi.dictName );
int gamePtr = XwJNI.initJNI();
boolean madeGame = false;
CommonPrefs cp = CommonPrefs.get( context );
if ( !forceNew ) {
byte[] stream = GameUtils.savedGame( context, path );
// Will fail if there's nothing in the stream but a gi.
madeGame = XwJNI.game_makeFromStream( gamePtr, stream,
JNIUtilsImpl.get(),
new CurGameInfo(context),
dictBytes, gi.dictName, cp );
}
if ( forceNew || !madeGame ) {
gi.setInProgress( false );
gi.fixup();
XwJNI.game_makeNewGame( gamePtr, gi, JNIUtilsImpl.get(),
cp, dictBytes, gi.dictName );
}
if ( null != car ) {
XwJNI.comms_setAddr( gamePtr, car );
}
GameUtils.saveGame( context, gamePtr, gi, path );
GameSummary summary = new GameSummary();
XwJNI.game_summarize( gamePtr, gi.nPlayers, summary );
DBUtils.saveSummary( context, path, summary );
XwJNI.game_dispose( gamePtr );
}
public static void doConfig( Activity activity, String path, Class clazz )
{
Uri uri = Uri.fromFile( new File(path) );
Intent intent = new Intent( Intent.ACTION_EDIT, uri, activity, clazz );
activity.startActivity( intent );
}
private static String removeExtn( String str )
{
if ( str.endsWith( XWConstants.DICT_EXTN ) ) {

View file

@ -86,9 +86,12 @@ public class GamesList extends XWListActivity
newGameB.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
addGame( true );
String path = addGame( true );
showNotAgainDlgThen( R.string.not_again_newgamenet,
R.string.key_notagain_newgamenet, null );
GameUtils.doConfig( GamesList.this, path,
RelayGameActivity.class );
}
});
@ -308,7 +311,7 @@ public class GamesList extends XWListActivity
} else {
switch ( menuID ) {
case R.id.list_item_config:
doConfig( path );
GameUtils.doConfig( this, path, GameConfig.class );
m_invalPath = path;
break;
@ -354,15 +357,6 @@ public class GamesList extends XWListActivity
return handled;
} // handleMenuItem
private void doConfig( String path )
{
Uri uri = Uri.fromFile( new File(path) );
Intent intent = new Intent( Intent.ACTION_EDIT, uri,
this, GameConfig.class );
startActivity( intent );
}
private String saveNew( CurGameInfo gi )
{
String path = null;
@ -373,11 +367,12 @@ public class GamesList extends XWListActivity
return path;
}
private void addGame( boolean networked )
private String addGame( boolean networked )
{
String path = saveNew( new CurGameInfo( this, networked ) );
GameUtils.resetGame( this, path, path );
onContentChanged();
return path;
}
}

View file

@ -0,0 +1,101 @@
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
/*
* Copyright 2009-2010 by Eric House (xwords@eehouse.org). All
* rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// This activity is for newbies. Bring it up when network game
// created. It explains they need only a room name -- that everything
// else is derived from defaults and configurable via the main config
// dialog (which offer to launch)
package org.eehouse.android.xw4;
import android.app.Activity;
import java.io.File;
import android.os.Bundle;
import android.net.Uri;
import android.widget.Button;
import android.widget.TextView;
import android.view.View;
import android.content.Intent;
import junit.framework.Assert;
import org.eehouse.android.xw4.jni.*;
public class RelayGameActivity extends XWActivity
implements View.OnClickListener {
private String m_path;
private CurGameInfo m_gi;
private CommsAddrRec m_car;
private Button m_playButton;
private Button m_configButton;
@Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.relay_game_config );
Uri uri = getIntent().getData();
m_path = uri.getPath();
if ( m_path.charAt(0) == '/' ) {
m_path = m_path.substring( 1 );
}
int gamePtr = XwJNI.initJNI();
m_gi = new CurGameInfo( this );
GameUtils.loadMakeGame( this, gamePtr, m_gi, m_path );
m_car = new CommsAddrRec( this );
if ( XwJNI.game_hasComms( gamePtr ) ) {
XwJNI.comms_getAddr( gamePtr, m_car );
} else {
Assert.fail();
// String relayName = CommonPrefs.getDefaultRelayHost( this );
// int relayPort = CommonPrefs.getDefaultRelayPort( this );
// XwJNI.comms_getInitialAddr( m_carOrig, relayName, relayPort );
}
XwJNI.game_dispose( gamePtr );
String lang = DictLangCache.getLangName( this, m_gi.dictName );
String fmt = getString( R.string.relay_game_explainf );
TextView text = (TextView)findViewById( R.id.explain );
text.setText( String.format( fmt, lang ) );
m_playButton = (Button)findViewById( R.id.play_button );
m_playButton.setOnClickListener( this );
m_configButton = (Button)findViewById( R.id.config_button );
m_configButton.setOnClickListener( this );
} // onCreate
@Override
public void onClick( View view )
{
if ( view == m_playButton ) {
m_car.ip_relay_invite = Utils.getText( this, R.id.room_edit ).trim();
GameUtils.applyChanges( this, m_gi, m_car, m_path, false );
GameUtils.launchGame( this, m_path );
} else if ( view == m_configButton ) {
GameUtils.doConfig( this, m_path, GameConfig.class );
finish();
}
}
} // class RelayGameActivity

View file

@ -84,7 +84,8 @@ static XP_S16 ce_send_proc( const XP_U8* buf, XP_U16 len,
void* closure );
static void ce_relay_status( void* closure,
CommsRelayState newState );
static void ce_relay_connd( void* closure, XP_Bool allHere,
static void ce_relay_connd( void* closure, XP_UCHAR* const room,
XP_U16 devOrder, XP_Bool allHere,
XP_U16 nMissing );
static void ce_relay_error( void* closure, XWREASON relayErr );
@ -1569,7 +1570,7 @@ ceSetDictName( const wchar_t* XP_UNUSED(wPath), XP_U16 XP_UNUSED_DBG(index),
} /* ceSetDictName */
static XP_Bool
ceHandleHintRequest( CEAppGlobals* globals )
ceHandleHintRequest( CEAppGlobals* globals, int wmId )
{
XP_Bool notDone;
XP_Bool draw;
@ -1579,10 +1580,10 @@ ceHandleHintRequest( CEAppGlobals* globals )
#ifdef XWFEATURE_SEARCHLIMIT
globals->askTrayLimits,
#endif
&notDone );
wmId == ID_MOVE_PREVHINT, &notDone );
globals->hintPending = notDone;
if ( draw ) { /* don't turn on if disallowed */
ceSetLeftSoftkey( globals, ID_MOVE_NEXTHINT );
ceSetLeftSoftkey( globals, wmId );
}
return draw;
} /* ceHandleHintRequest */
@ -2640,7 +2641,8 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
board_resetEngine( globals->game.board );
/* fallthru */
case ID_MOVE_NEXTHINT:
draw = ceHandleHintRequest( globals );
case ID_MOVE_PREVHINT:
draw = ceHandleHintRequest( globals, wmId );
break;
case ID_FILE_EXIT:
@ -3179,7 +3181,10 @@ ce_relay_status( void* closure, CommsRelayState newState )
}
static void
ce_relay_connd( void* closure, XP_Bool allHere, XP_U16 nMissing )
ce_relay_connd( void* closure, XP_UCHAR* const XP_UNUSED(room),
XP_U16 XP_UNUSED(devOrder), /* 1 means created room, etc. */
XP_Bool allHere,
XP_U16 nMissing )
{
CEAppGlobals* globals = (CEAppGlobals*)closure;
XP_U16 strID = 0;

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "HINT" // <- translate
BEGIN
MENUITEM "NEXT HINT", ID_MOVE_NEXTHINT // <- translate
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "HINT", ID_MOVE_HINT // <- translate
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "LIMITED HINT...", ID_MOVE_LIMITEDHINT // <- translate

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "Pista"
BEGIN
MENUITEM "Pista següent", ID_MOVE_NEXTHINT
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "Pista", ID_MOVE_HINT
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "Límits de pistes...", ID_MOVE_LIMITEDHINT

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "Nápověda"
BEGIN
MENUITEM "Další nápověda", ID_MOVE_NEXTHINT
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "Nápověda", ID_MOVE_HINT
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "Omezená nápověda...", ID_MOVE_LIMITEDHINT

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "Hint"
BEGIN
MENUITEM "Next hint", ID_MOVE_NEXTHINT
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "Hint", ID_MOVE_HINT
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "Limited hint...", ID_MOVE_LIMITEDHINT

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "Conseil"
BEGIN
MENUITEM "Conseil suivant", ID_MOVE_NEXTHINT
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "Conseil", ID_MOVE_HINT
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "Conseil limité...", ID_MOVE_LIMITEDHINT

View file

@ -83,6 +83,7 @@ BEGIN
POPUP "Podpowiedź"
BEGIN
MENUITEM "Następna podp.", ID_MOVE_NEXTHINT
MENUITEM "Previous hint", ID_MOVE_PREVHINT
MENUITEM "Podpowiedź", ID_MOVE_HINT
#ifdef XWFEATURE_SEARCHLIMIT
MENUITEM "Podp. ograniczona...", ID_MOVE_LIMITEDHINT

View file

@ -244,20 +244,21 @@
# define ID_MOVE_LIMITEDHINT 40011
#endif
#define ID_MOVE_NEXTHINT 40012
#define ID_MOVE_UNDOCURRENT 40013
#define ID_MOVE_UNDOLAST 40014
#define ID_MOVE_TRADE 40015
#define ID_MOVE_JUGGLE 40016
#define ID_MOVE_HIDETRAY 40017
#define ID_MOVE_TURNDONE 40018
#define ID_MOVE_FLIP 40019
#define ID_MOVE_VALUES 40027
#define ID_FILE_NEWGAME 40020
#define ID_FILE_SAVEDGAMES 40021
#define ID_EDITTEXT 40022
#define ID_FILE_PREFERENCES 40023
#define ID_GAME_RESENDMSGS 40025
#define ID_FILE_FULLSCREEN 40026
#define ID_MOVE_PREVHINT 40013
#define ID_MOVE_UNDOCURRENT 40014
#define ID_MOVE_UNDOLAST 40015
#define ID_MOVE_TRADE 40016
#define ID_MOVE_JUGGLE 40017
#define ID_MOVE_HIDETRAY 40018
#define ID_MOVE_TURNDONE 40019
#define ID_MOVE_FLIP 40020
#define ID_MOVE_VALUES 40021
#define ID_FILE_NEWGAME 40022
#define ID_FILE_SAVEDGAMES 40023
#define ID_EDITTEXT 40024
#define ID_FILE_PREFERENCES 40025
#define ID_GAME_RESENDMSGS 40026
#define ID_FILE_FULLSCREEN 40027
#define ID_INITIAL_SOFTID ID_MOVE_TURNDONE