mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-28 07:58:08 +01:00
Merge branch 'android_branch' into android_thumbnail
Conflicts: xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
This commit is contained in:
commit
9c9a04025a
23 changed files with 664 additions and 237 deletions
|
@ -4,17 +4,17 @@ LOCAL_PATH := $(call my-dir)
|
|||
include $(CLEAR_VARS)
|
||||
|
||||
COMMON_PATH=../../../common
|
||||
local_C_INCLUDES+= \
|
||||
LOCAL_C_INCLUDES+= \
|
||||
-I$(LOCAL_PATH)/$(COMMON_PATH) \
|
||||
-I$(LOCAL_PATH)/../../../relay \
|
||||
|
||||
local_LDLIBS += -llog
|
||||
LOCAL_LDLIBS += -llog
|
||||
|
||||
ifeq ($(BUILD_TARGET),debug)
|
||||
local_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
|
||||
LOCAL_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
|
||||
endif
|
||||
local_DEFINES += \
|
||||
$(local_DEBUG) \
|
||||
LOCAL_DEFINES += \
|
||||
$(LOCAL_DEBUG) \
|
||||
-DXWFEATURE_RELAY \
|
||||
-DXWFEATURE_SMS \
|
||||
-DXWFEATURE_COMMSACK \
|
||||
|
@ -37,12 +37,14 @@ local_DEFINES += \
|
|||
-DHASH_STREAM \
|
||||
-DXWFEATURE_BASE64 \
|
||||
-DXWFEATURE_DEVID \
|
||||
-DCOMMON_LAYOUT \
|
||||
-DINITIAL_CLIENT_VERS=${INITIAL_CLIENT_VERS} \
|
||||
-DRELAY_ROOM_DEFAULT=\"\" \
|
||||
-D__LITTLE_ENDIAN \
|
||||
|
||||
ifeq ($(CHAT_ENABLED),true)
|
||||
local_DEFINES += -DXWFEATURE_CHAT
|
||||
|
||||
LOCAL_DEFINES += -DXWFEATURE_CHAT
|
||||
endif
|
||||
ifeq ($(THUMBNAIL_ENABLED),true)
|
||||
local_DEFINES += -DXWFEATURE_ACTIVERECT
|
||||
|
@ -50,7 +52,7 @@ endif
|
|||
|
||||
# -DXWFEATURE_SCOREONEPASS \
|
||||
|
||||
local_SRC_FILES += \
|
||||
LOCAL_SRC_FILES += \
|
||||
xwjni.c \
|
||||
utilwrapper.c \
|
||||
drawwrapper.c \
|
||||
|
@ -61,7 +63,7 @@ local_SRC_FILES += \
|
|||
|
||||
|
||||
COMMON_PATH=../../../common
|
||||
common_SRC_FILES += \
|
||||
COMMON_SRC_FILES += \
|
||||
$(COMMON_PATH)/boarddrw.c \
|
||||
$(COMMON_PATH)/scorebdp.c \
|
||||
$(COMMON_PATH)/dragdrpp.c \
|
||||
|
@ -84,9 +86,12 @@ common_SRC_FILES += \
|
|||
$(COMMON_PATH)/dbgutil.c \
|
||||
|
||||
|
||||
LOCAL_CFLAGS+=$(local_C_INCLUDES) $(local_DEFINES) -Wall
|
||||
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(local_SRC_FILES) $(common_SRC_FILES)
|
||||
LOCAL_CFLAGS+=$(LOCAL_C_INCLUDES) $(LOCAL_DEFINES)
|
||||
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(LOCAL_SRC_FILES) $(COMMON_SRC_FILES)
|
||||
LOCAL_MODULE := xwjni
|
||||
LOCAL_LDLIBS := -L${SYSROOT}/usr/lib -llog -lz
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
COMMON_SRC_FILES :=
|
||||
COMMON_PATH :=
|
||||
|
|
1
xwords4/android/XWords4/jni/Application.mk
Normal file
1
xwords4/android/XWords4/jni/Application.mk
Normal file
|
@ -0,0 +1 @@
|
|||
APP_ABI := armeabi x86
|
|
@ -88,6 +88,30 @@ getInt( JNIEnv* env, jobject obj, const char* name )
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
getInts( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
|
||||
int val = getInt( env, jobj, si->name );
|
||||
switch( si->siz ) {
|
||||
case 4:
|
||||
*(uint32_t*)ptr = val;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t*)ptr = val;
|
||||
break;
|
||||
case 1:
|
||||
*ptr = val;
|
||||
break;
|
||||
}
|
||||
/* XP_LOGF( "%s: wrote int %s of size %d with val %d at offset %d", */
|
||||
/* __func__, si->name, si->siz, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setInt( JNIEnv* env, jobject obj, const char* name, int value )
|
||||
{
|
||||
|
@ -99,6 +123,34 @@ setInt( JNIEnv* env, jobject obj, const char* name, int value )
|
|||
deleteLocalRef( env, cls );
|
||||
}
|
||||
|
||||
void
|
||||
setInts( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
|
||||
int val;
|
||||
switch( si->siz ) {
|
||||
case 4:
|
||||
val = *(uint32_t*)ptr;
|
||||
break;
|
||||
case 2:
|
||||
val = *(uint16_t*)ptr;
|
||||
break;
|
||||
case 1:
|
||||
val = *ptr;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
setInt( env, jobj, si->name, val );
|
||||
/* XP_LOGF( "%s: read int %s of size %d with val %d from offset %d", */
|
||||
/* __func__, si->name, si->siz, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
setBool( JNIEnv* env, jobject obj, const char* name, bool value )
|
||||
{
|
||||
|
@ -114,6 +166,19 @@ setBool( JNIEnv* env, jobject obj, const char* name, bool value )
|
|||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
setBools( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
XP_Bool val = *(XP_Bool*)(((uint8_t*)cobj)+si->offset);
|
||||
setBool( env, jobj, si->name, val );
|
||||
/* XP_LOGF( "%s: read bool %s with val %d from offset %d", __func__, */
|
||||
/* si->name, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value )
|
||||
{
|
||||
|
@ -210,6 +275,19 @@ getBool( JNIEnv* env, jobject obj, const char* name )
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
getBools( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
|
||||
{
|
||||
int ii;
|
||||
for ( ii = 0; ii < nSis; ++ii ) {
|
||||
const SetInfo* si = &sis[ii];
|
||||
XP_Bool val = getBool( env, jobj, si->name );
|
||||
*(XP_Bool*)(((uint8_t*)cobj)+si->offset) = val;
|
||||
/* XP_LOGF( "%s: wrote bool %s with val %d at offset %d", __func__, */
|
||||
/* si->name, val, si->offset ); */
|
||||
}
|
||||
}
|
||||
|
||||
jintArray
|
||||
makeIntArray( JNIEnv *env, int siz, const jint* vals )
|
||||
{
|
||||
|
|
|
@ -33,10 +33,28 @@
|
|||
void and_send_on_close( XWStreamCtxt* stream, void* closure );
|
||||
XWStreamCtxt* and_empty_stream( MPFORMAL AndGlobals* globals );
|
||||
|
||||
typedef struct _SetInfo {
|
||||
const char* name;
|
||||
int offset;
|
||||
int siz;
|
||||
} SetInfo;
|
||||
#define ARR_MEMBER(obj, fld) { .name = #fld, \
|
||||
.offset = OFFSET_OF(obj, fld), \
|
||||
.siz = sizeof(((obj *)0)->fld) \
|
||||
}
|
||||
|
||||
int getInt( JNIEnv* env, jobject obj, const char* name );
|
||||
void setInt( JNIEnv* env, jobject obj, const char* name, int value );
|
||||
void setInts( JNIEnv* env, jobject jobj, void* cobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
void getInts( JNIEnv* env, void* cobj, jobject jobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool getBool( JNIEnv* env, jobject obj, const char* name );
|
||||
void getBools( JNIEnv* env, void* cobj, jobject jobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool setBool( JNIEnv* env, jobject obj, const char* name, bool value );
|
||||
void setBools( JNIEnv* env, jobject jobj, void* cobj,
|
||||
const SetInfo* sis, XP_U16 nSis );
|
||||
bool setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value );
|
||||
void getString( JNIEnv* env, jobject jlp, const char* name, XP_UCHAR* buf,
|
||||
int bufLen );
|
||||
|
|
|
@ -39,47 +39,54 @@
|
|||
#include "jniutlswrapper.h"
|
||||
#include "paths.h"
|
||||
|
||||
static const SetInfo gi_ints[] = {
|
||||
ARR_MEMBER( CurGameInfo, nPlayers )
|
||||
,ARR_MEMBER( CurGameInfo, gameSeconds )
|
||||
,ARR_MEMBER( CurGameInfo, boardSize )
|
||||
,ARR_MEMBER( CurGameInfo, gameID )
|
||||
,ARR_MEMBER( CurGameInfo, dictLang )
|
||||
};
|
||||
|
||||
static const SetInfo gi_bools[] = {
|
||||
ARR_MEMBER( CurGameInfo, hintsNotAllowed )
|
||||
,ARR_MEMBER( CurGameInfo, timerEnabled )
|
||||
,ARR_MEMBER( CurGameInfo, allowPickTiles )
|
||||
,ARR_MEMBER( CurGameInfo, allowHintRect )
|
||||
};
|
||||
|
||||
static CurGameInfo*
|
||||
makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
|
||||
makeGI( MPFORMAL JNIEnv* env, jobject jgi )
|
||||
{
|
||||
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
|
||||
XP_UCHAR buf[256]; /* in case needs whole path */
|
||||
|
||||
gi->nPlayers = getInt( env, j_gi, "nPlayers");
|
||||
gi->gameSeconds = getInt( env, j_gi, "gameSeconds");
|
||||
gi->boardSize = getInt( env, j_gi, "boardSize" );
|
||||
getInts( env, (void*)gi, jgi, gi_ints, VSIZE(gi_ints) );
|
||||
getBools( env, (void*)gi, jgi, gi_bools, VSIZE(gi_bools) );
|
||||
|
||||
/* Unlike on other platforms, gi is created without a call to
|
||||
game_makeNewGame, which sets gameID. So check here if it's still unset
|
||||
and if necessary set it -- including back in the java world. */
|
||||
gi->gameID = getInt( env, j_gi, "gameID" );
|
||||
if ( 0 == gi->gameID ) {
|
||||
while ( 0 == gi->gameID ) {
|
||||
gi->gameID = getCurSeconds( env );
|
||||
}
|
||||
setInt( env, j_gi, "gameID", gi->gameID );
|
||||
setInt( env, jgi, "gameID", gi->gameID );
|
||||
}
|
||||
|
||||
gi->dictLang = getInt( env, j_gi, "dictLang" );
|
||||
gi->hintsNotAllowed = getBool( env, j_gi, "hintsNotAllowed" );
|
||||
gi->timerEnabled = getBool( env, j_gi, "timerEnabled" );
|
||||
gi->allowPickTiles = getBool( env, j_gi, "allowPickTiles" );
|
||||
gi->allowHintRect = getBool( env, j_gi, "allowHintRect" );
|
||||
|
||||
gi->phoniesAction =
|
||||
jenumFieldToInt( env, j_gi, "phoniesAction",
|
||||
jenumFieldToInt( env, jgi, "phoniesAction",
|
||||
PKG_PATH("jni/CurGameInfo$XWPhoniesChoice") );
|
||||
gi->serverRole =
|
||||
jenumFieldToInt( env, j_gi, "serverRole",
|
||||
jenumFieldToInt( env, jgi, "serverRole",
|
||||
PKG_PATH("jni/CurGameInfo$DeviceRole"));
|
||||
|
||||
getString( env, j_gi, "dictName", buf, VSIZE(buf) );
|
||||
getString( env, jgi, "dictName", buf, VSIZE(buf) );
|
||||
gi->dictName = copyString( mpool, buf );
|
||||
|
||||
XP_ASSERT( gi->nPlayers <= MAX_NUM_PLAYERS );
|
||||
|
||||
jobject jplayers;
|
||||
if ( getObject( env, j_gi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
|
||||
if ( getObject( env, jgi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
|
||||
&jplayers ) ) {
|
||||
int ii;
|
||||
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
|
||||
|
@ -114,14 +121,10 @@ static void
|
|||
setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
|
||||
{
|
||||
// set fields
|
||||
setInt( env, jgi, "nPlayers", gi->nPlayers );
|
||||
setInt( env, jgi, "gameSeconds", gi->gameSeconds );
|
||||
setInt( env, jgi, "boardSize", gi->boardSize );
|
||||
setInt( env, jgi, "gameID", gi->gameID );
|
||||
setInt( env, jgi, "dictLang", gi->dictLang );
|
||||
setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed );
|
||||
setBool( env, jgi, "timerEnabled", gi->timerEnabled );
|
||||
setBool( env, jgi, "allowPickTiles", gi->allowPickTiles );
|
||||
|
||||
setInts( env, jgi, (void*)gi, gi_ints, VSIZE(gi_ints) );
|
||||
setBools( env, jgi, (void*)gi, gi_bools, VSIZE(gi_bools) );
|
||||
|
||||
setString( env, jgi, "dictName", gi->dictName );
|
||||
|
||||
intToJenumField( env, jgi, gi->phoniesAction, "phoniesAction",
|
||||
|
@ -155,6 +158,36 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
|
|||
}
|
||||
} /* setJGI */
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
static const SetInfo bd_ints[] = {
|
||||
ARR_MEMBER( BoardDims, left )
|
||||
,ARR_MEMBER( BoardDims, top )
|
||||
,ARR_MEMBER( BoardDims, width )
|
||||
,ARR_MEMBER( BoardDims, height )
|
||||
,ARR_MEMBER( BoardDims, scoreHt )
|
||||
,ARR_MEMBER( BoardDims, boardHt )
|
||||
,ARR_MEMBER( BoardDims, trayTop )
|
||||
,ARR_MEMBER( BoardDims, trayHt )
|
||||
,ARR_MEMBER( BoardDims, cellSize )
|
||||
,ARR_MEMBER( BoardDims, maxCellSize )
|
||||
,ARR_MEMBER( BoardDims, timerWidth )
|
||||
};
|
||||
|
||||
static void
|
||||
dimsJToC( JNIEnv* env, BoardDims* out, jobject jdims )
|
||||
{
|
||||
getInts( env, (void*)out, jdims, bd_ints, VSIZE(bd_ints) );
|
||||
}
|
||||
|
||||
static void
|
||||
dimsCtoJ( JNIEnv* env, jobject jdims, const BoardDims* in )
|
||||
{
|
||||
LOG_FUNC();
|
||||
setInts( env, jdims, (void*)in, bd_ints, VSIZE(bd_ints) );
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
destroyGI( MPFORMAL CurGameInfo** gip )
|
||||
{
|
||||
|
@ -598,6 +631,47 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jgi, jint fontHt, jint fontWidth,
|
||||
jboolean squareTiles, jobject jbounds, jobject jdims )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWJNI_START();
|
||||
CurGameInfo* gi = makeGI( MPPARM(mpool) env, jgi );
|
||||
|
||||
XP_Rect bounds;
|
||||
bounds.left = getInt( env, jbounds, "left" );
|
||||
bounds.top = getInt( env, jbounds, "top" );
|
||||
bounds.width = getInt( env, jbounds, "right" ) - bounds.left;
|
||||
bounds.height = getInt( env, jbounds, "bottom" ) - bounds.top;
|
||||
|
||||
BoardDims dims;
|
||||
board_figureLayout( state->game.board, gi, 150, 200, fontHt, fontWidth,
|
||||
squareTiles, &bounds, ((!!jdims) ? &dims : NULL) );
|
||||
|
||||
destroyGI( MPPARM(mpool) &gi );
|
||||
|
||||
if ( !!jdims ) {
|
||||
dimsCtoJ( env, jdims, &dims );
|
||||
}
|
||||
XWJNI_END();
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jobject jdims )
|
||||
{
|
||||
XWJNI_START();
|
||||
BoardDims dims;
|
||||
dimsJToC( env, &dims, jdims );
|
||||
board_applyLayout( state->game.board, &dims );
|
||||
XWJNI_END();
|
||||
}
|
||||
#endif
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
|
||||
(JNIEnv *env, jclass C, jint gamePtr, jint left, jint top, jint width,
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<string name="key_na_browseall">key_na_browseall</string>
|
||||
<string name="key_na_values">key_na_values</string>
|
||||
<string name="key_enable_debug">key_enable_debug</string>
|
||||
<string name="key_enable_commlayt">key_enable_commlayt</string>
|
||||
<string name="key_download_path">key_download_path</string>
|
||||
|
||||
<!-- Nor is my email address -->
|
||||
|
|
|
@ -307,6 +307,11 @@
|
|||
android:summary="Menuitems etc."
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
<CheckBoxPreference android:key="@string/key_enable_commlayt"
|
||||
android:title="Use common layout"
|
||||
android:summary="(rather than android-specific)"
|
||||
android:defaultValue="false"
|
||||
/>
|
||||
|
||||
<!-- For broken devices like my Blaze 4G that report a download
|
||||
directory that doesn't exist, allow users to set it. Mine:
|
||||
|
|
|
@ -23,6 +23,7 @@ package org.eehouse.android.xw4;
|
|||
|
||||
// Why does this have to be its own class...
|
||||
public class BoardDims {
|
||||
public int left, top;
|
||||
public int width, height; // of the bitmap
|
||||
public int scoreHt;
|
||||
public int boardHt;
|
||||
|
|
|
@ -73,6 +73,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
private int m_lastSecsLeft;
|
||||
private int m_lastTimerPlayer;
|
||||
private int m_pendingScore;
|
||||
private boolean m_useCommon;
|
||||
private CommsAddrRec.CommsConnType m_connType =
|
||||
CommsAddrRec.CommsConnType.COMMS_CONN_NONE;
|
||||
|
||||
|
@ -188,6 +189,9 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
int heightMode = View.MeasureSpec.getMode( heightMeasureSpec );
|
||||
// printMode( "heightMode", heightMode );
|
||||
|
||||
m_useCommon =
|
||||
XWPrefs.getPrefsBoolean( m_context,
|
||||
R.string.key_enable_commlayt, false );
|
||||
BoardDims dims = figureBoardDims( width, height );
|
||||
// If I let the spec tell me whether I can reduce the width
|
||||
// then I don't change it on the second pass, but if I ignore
|
||||
|
@ -247,80 +251,91 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
private BoardDims figureBoardDims( int width, int height )
|
||||
{
|
||||
BoardDims result = new BoardDims();
|
||||
int nCells = m_gi.boardSize;
|
||||
int maxCellSize = 4 * m_defaultFontHt;
|
||||
int trayHt;
|
||||
int scoreHt;
|
||||
int wantHt;
|
||||
int nToScroll;
|
||||
boolean squareTiles = XWPrefs.getSquareTiles( m_context );
|
||||
|
||||
for ( boolean firstPass = true; ; ) {
|
||||
result.width = width;
|
||||
Paint paint = new Paint();
|
||||
paint.setTextSize( m_mediumFontHt );
|
||||
paint.getTextBounds( "-00:00", 0, 6, m_boundsScratch );
|
||||
int timerWidth = m_boundsScratch.width();
|
||||
|
||||
int cellSize = width / nCells;
|
||||
if ( cellSize > maxCellSize ) {
|
||||
cellSize = maxCellSize;
|
||||
if ( m_useCommon ) {
|
||||
Rect bounds = new Rect( 0, 0, width, height );
|
||||
int fontWidth = timerWidth / 6;
|
||||
XwJNI.board_figureLayout( m_jniGamePtr, m_gi, m_defaultFontHt,
|
||||
fontWidth, squareTiles, bounds, result );
|
||||
|
||||
} else {
|
||||
int nCells = m_gi.boardSize;
|
||||
int maxCellSize = 4 * m_defaultFontHt;
|
||||
int trayHt;
|
||||
int scoreHt;
|
||||
int wantHt;
|
||||
int nToScroll;
|
||||
|
||||
int boardWidth = nCells * cellSize;
|
||||
result.width = boardWidth;
|
||||
}
|
||||
result.maxCellSize = maxCellSize;
|
||||
for ( boolean firstPass = true; ; ) {
|
||||
result.width = width;
|
||||
|
||||
// Now determine if vertical scrolling will be necessary.
|
||||
// There's a minimum tray and scoreboard height. If we can
|
||||
// fit them and all cells no scrolling's needed. Otherwise
|
||||
// determine the minimum number that must be hidden to fit.
|
||||
// Finally grow scoreboard and tray to use whatever's left.
|
||||
trayHt = 2 * cellSize;
|
||||
scoreHt = (cellSize * 3) / 2;
|
||||
wantHt = trayHt + scoreHt + (cellSize * nCells);
|
||||
if ( wantHt <= height ) {
|
||||
nToScroll = 0;
|
||||
} else {
|
||||
// Scrolling's required if we use cell width sufficient to
|
||||
// fill the screen. But perhaps we don't need to.
|
||||
int cellWidth = 2 * (height / ( 4 + 3 + (2*nCells)));
|
||||
if ( firstPass && cellWidth >= m_defaultFontHt ) {
|
||||
firstPass = false;
|
||||
width = nCells * cellWidth;
|
||||
continue;
|
||||
int cellSize = width / nCells;
|
||||
if ( cellSize > maxCellSize ) {
|
||||
cellSize = maxCellSize;
|
||||
|
||||
int boardWidth = nCells * cellSize;
|
||||
result.width = boardWidth;
|
||||
}
|
||||
result.maxCellSize = maxCellSize;
|
||||
|
||||
// Now determine if vertical scrolling will be necessary.
|
||||
// There's a minimum tray and scoreboard height. If we can
|
||||
// fit them and all cells no scrolling's needed. Otherwise
|
||||
// determine the minimum number that must be hidden to fit.
|
||||
// Finally grow scoreboard and tray to use whatever's left.
|
||||
trayHt = 2 * cellSize;
|
||||
scoreHt = (cellSize * 3) / 2;
|
||||
wantHt = trayHt + scoreHt + (cellSize * nCells);
|
||||
if ( wantHt <= height ) {
|
||||
nToScroll = 0;
|
||||
} else {
|
||||
nToScroll = nCells - ((height - trayHt - scoreHt) / cellSize);
|
||||
// Scrolling's required if we use cell width sufficient to
|
||||
// fill the screen. But perhaps we don't need to.
|
||||
int cellWidth = 2 * (height / ( 4 + 3 + (2*nCells)));
|
||||
if ( firstPass && cellWidth >= m_defaultFontHt ) {
|
||||
firstPass = false;
|
||||
width = nCells * cellWidth;
|
||||
continue;
|
||||
} else {
|
||||
nToScroll = nCells - ((height - trayHt - scoreHt) / cellSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
|
||||
int heightLeft = height - heightUsed;
|
||||
if ( 0 < heightLeft ) {
|
||||
if ( heightLeft > (cellSize * 3 / 2) ) {
|
||||
heightLeft = cellSize * 3 / 2;
|
||||
int heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
|
||||
int heightLeft = height - heightUsed;
|
||||
if ( 0 < heightLeft ) {
|
||||
if ( heightLeft > (cellSize * 3 / 2) ) {
|
||||
heightLeft = cellSize * 3 / 2;
|
||||
}
|
||||
heightLeft /= 3;
|
||||
scoreHt += heightLeft;
|
||||
|
||||
trayHt += heightLeft * 2;
|
||||
if ( squareTiles && trayHt > (width / 7) ) {
|
||||
trayHt = width / 7;
|
||||
}
|
||||
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
|
||||
}
|
||||
heightLeft /= 3;
|
||||
scoreHt += heightLeft;
|
||||
|
||||
trayHt += heightLeft * 2;
|
||||
if ( XWPrefs.getSquareTiles( m_context )
|
||||
&& trayHt > (width / 7) ) {
|
||||
trayHt = width / 7;
|
||||
result.trayHt = trayHt;
|
||||
result.scoreHt = scoreHt;
|
||||
|
||||
result.boardHt = cellSize * nCells;
|
||||
result.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
|
||||
result.height = heightUsed;
|
||||
result.cellSize = cellSize;
|
||||
|
||||
if ( m_gi.timerEnabled ) {
|
||||
result.timerWidth = timerWidth;
|
||||
}
|
||||
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
|
||||
break;
|
||||
}
|
||||
|
||||
result.trayHt = trayHt;
|
||||
result.scoreHt = scoreHt;
|
||||
|
||||
result.boardHt = cellSize * nCells;
|
||||
result.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
|
||||
result.height = heightUsed;
|
||||
result.cellSize = cellSize;
|
||||
|
||||
if ( m_gi.timerEnabled ) {
|
||||
Paint paint = new Paint();
|
||||
paint.setTextSize( m_mediumFontHt );
|
||||
paint.getTextBounds( "-00:00", 0, 6, m_boundsScratch );
|
||||
result.timerWidth = m_boundsScratch.width();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -362,7 +377,8 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
XwJNI.board_setDraw( m_jniGamePtr, m_canvas );
|
||||
|
||||
// need to synchronize??
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_LAYOUT, dims );
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_LAYOUT, dims,
|
||||
m_useCommon );
|
||||
m_jniThread.handle( JNIThread.JNICmd.CMD_DRAW );
|
||||
layoutDone = true;
|
||||
}
|
||||
|
|
|
@ -233,32 +233,36 @@ public class JNIThread extends Thread {
|
|||
Message.obtain( m_handler, DIALOG, titleArg, 0, text ).sendToTarget();
|
||||
}
|
||||
|
||||
private void doLayout( BoardDims dims )
|
||||
private void doLayout( BoardDims dims, boolean useCommon )
|
||||
{
|
||||
int scoreWidth = dims.width - dims.cellSize;
|
||||
ConnStatusHandler.setRect( scoreWidth, 0, scoreWidth + dims.cellSize,
|
||||
dims.scoreHt );
|
||||
if ( useCommon ) {
|
||||
XwJNI.board_applyLayout( m_jniGamePtr, dims );
|
||||
} else {
|
||||
int scoreWidth = dims.width - dims.cellSize;
|
||||
ConnStatusHandler.setRect( scoreWidth, 0, scoreWidth + dims.cellSize,
|
||||
dims.scoreHt );
|
||||
|
||||
if ( m_gi.timerEnabled ) {
|
||||
scoreWidth -= dims.timerWidth;
|
||||
XwJNI.board_setTimerLoc( m_jniGamePtr, scoreWidth, 0,
|
||||
dims.timerWidth, dims.scoreHt );
|
||||
}
|
||||
XwJNI.board_setScoreboardLoc( m_jniGamePtr, 0, 0, scoreWidth,
|
||||
dims.scoreHt, true );
|
||||
if ( m_gi.timerEnabled ) {
|
||||
scoreWidth -= dims.timerWidth;
|
||||
XwJNI.board_setTimerLoc( m_jniGamePtr, scoreWidth, 0,
|
||||
dims.timerWidth, dims.scoreHt );
|
||||
}
|
||||
XwJNI.board_setScoreboardLoc( m_jniGamePtr, 0, 0, scoreWidth,
|
||||
dims.scoreHt, true );
|
||||
|
||||
// Have no idea why I was doing -1 below, but it breaks layout
|
||||
// for small (QVGA) boards. If it needs to be done, do it
|
||||
// early in figureBoardDims so the calculations that follow
|
||||
// are consistent.
|
||||
XwJNI.board_setPos( m_jniGamePtr, 0, dims.scoreHt,
|
||||
dims.width/*-1*/, dims.boardHt, dims.maxCellSize,
|
||||
false );
|
||||
// Have no idea why I was doing -1 below, but it breaks layout
|
||||
// for small (QVGA) boards. If it needs to be done, do it
|
||||
// early in figureBoardDims so the calculations that follow
|
||||
// are consistent.
|
||||
XwJNI.board_setPos( m_jniGamePtr, 0, dims.scoreHt,
|
||||
dims.width/*-1*/, dims.boardHt, dims.maxCellSize,
|
||||
false );
|
||||
|
||||
XwJNI.board_setTrayLoc( m_jniGamePtr, 0, dims.trayTop,
|
||||
dims.width/*-1*/, dims.trayHt, kMinDivWidth );
|
||||
XwJNI.board_setTrayLoc( m_jniGamePtr, 0, dims.trayTop,
|
||||
dims.width/*-1*/, dims.trayHt, kMinDivWidth );
|
||||
|
||||
XwJNI.board_invalAll( m_jniGamePtr );
|
||||
XwJNI.board_invalAll( m_jniGamePtr );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean nextSame( JNICmd cmd )
|
||||
|
@ -358,7 +362,7 @@ public class JNIThread extends Thread {
|
|||
break;
|
||||
|
||||
case CMD_LAYOUT:
|
||||
doLayout( (BoardDims)args[0] );
|
||||
doLayout( (BoardDims)args[0], (Boolean)args[1] );
|
||||
draw = true;
|
||||
// check and disable zoom button at limit
|
||||
handle( JNICmd.CMD_ZOOM, 0 );
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import org.eehouse.android.xw4.BoardDims;
|
||||
|
||||
// Collection of native methods
|
||||
public class XwJNI {
|
||||
|
@ -148,6 +148,15 @@ public class XwJNI {
|
|||
public static native void board_setDraw( int gamePtr, DrawCtx draw );
|
||||
public static native void board_invalAll( int gamePtr );
|
||||
public static native boolean board_draw( int gamePtr );
|
||||
|
||||
// Only if COMMON_LAYOUT defined
|
||||
public static native void board_figureLayout( int gamePtr, CurGameInfo gi,
|
||||
int fontHt, int fontWidth,
|
||||
boolean squareTiles,
|
||||
Rect bounds, BoardDims dims );
|
||||
// Only if COMMON_LAYOUT defined
|
||||
public static native void board_applyLayout( int gamePtr, BoardDims dims );
|
||||
|
||||
public static native void board_setPos( int gamePtr, int left, int top,
|
||||
int width, int height,
|
||||
int maxCellHt, boolean lefty );
|
||||
|
|
|
@ -389,6 +389,123 @@ board_reset( BoardCtxt* board )
|
|||
setTimerIf( board );
|
||||
} /* board_reset */
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
void
|
||||
board_figureLayout( BoardCtxt* board, const CurGameInfo* gi,
|
||||
XP_U16 scorePct, XP_U16 trayPct,
|
||||
XP_U16 fontHt, XP_U16 fontWidth, XP_Bool squareTiles,
|
||||
const XP_Rect* bounds, BoardDims* dimsp )
|
||||
{
|
||||
BoardDims ldims;
|
||||
XP_MEMSET( &ldims, 0, sizeof(ldims) );
|
||||
|
||||
XP_U16 nCells = gi->boardSize;
|
||||
XP_U16 maxCellSize = 4 * fontHt;
|
||||
XP_U16 trayHt;
|
||||
XP_U16 scoreHt;
|
||||
XP_U16 wantHt;
|
||||
XP_U16 nToScroll;
|
||||
XP_Bool firstPass;
|
||||
|
||||
ldims.left = bounds->left;
|
||||
ldims.top = bounds->top;
|
||||
|
||||
for ( firstPass = XP_TRUE; ; ) {
|
||||
ldims.width = bounds->width;
|
||||
|
||||
XP_U16 cellSize = bounds->width / nCells;
|
||||
if ( cellSize > maxCellSize ) {
|
||||
cellSize = maxCellSize;
|
||||
|
||||
XP_U16 boardWidth = nCells * cellSize;
|
||||
ldims.width = boardWidth;
|
||||
}
|
||||
ldims.maxCellSize = maxCellSize;
|
||||
|
||||
// Now determine if vertical scrolling will be necessary.
|
||||
// There's a minimum tray and scoreboard height. If we can
|
||||
// fit them and all cells no scrolling's needed. Otherwise
|
||||
// determine the minimum number that must be hidden to fit.
|
||||
// Finally grow scoreboard and tray to use whatever's left.
|
||||
scoreHt = (scorePct * cellSize) / 100;
|
||||
trayHt = (trayPct * cellSize) / 100;
|
||||
wantHt = trayHt + scoreHt + (cellSize * nCells);
|
||||
if ( wantHt <= bounds->height ) {
|
||||
nToScroll = 0;
|
||||
} else {
|
||||
// Scrolling's required if we use cell width sufficient to
|
||||
// fill the screen. But perhaps we don't need to.
|
||||
int cellWidth = 2 * (bounds->height / ( 4 + 3 + (2*nCells)));
|
||||
if ( firstPass && cellWidth >= fontHt ) {
|
||||
firstPass = XP_FALSE;
|
||||
ldims.width = nCells * cellWidth;
|
||||
continue;
|
||||
} else {
|
||||
nToScroll = nCells -
|
||||
((bounds->height - trayHt - scoreHt) / cellSize);
|
||||
}
|
||||
}
|
||||
|
||||
XP_U16 heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
|
||||
XP_U16 heightLeft = bounds->height - heightUsed;
|
||||
if ( 0 < heightLeft ) {
|
||||
if ( heightLeft > (cellSize * 3 / 2) ) {
|
||||
heightLeft = cellSize * 3 / 2;
|
||||
}
|
||||
heightLeft /= 3;
|
||||
if ( 0 < scorePct ) {
|
||||
scoreHt += heightLeft;
|
||||
}
|
||||
|
||||
if ( 0 < trayPct ) {
|
||||
trayHt += heightLeft * 2;
|
||||
}
|
||||
if ( squareTiles && trayHt > (bounds->width / 7) ) {
|
||||
trayHt = bounds->width / 7;
|
||||
}
|
||||
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
|
||||
}
|
||||
|
||||
ldims.trayHt = trayHt;
|
||||
ldims.scoreHt = scoreHt;
|
||||
|
||||
ldims.boardHt = cellSize * nCells;
|
||||
ldims.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
|
||||
ldims.height = heightUsed;
|
||||
ldims.cellSize = cellSize;
|
||||
|
||||
if ( gi->timerEnabled ) {
|
||||
ldims.timerWidth = fontWidth * XP_STRLEN("-00:00");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !!dimsp ) {
|
||||
XP_MEMCPY( dimsp, &ldims, sizeof(ldims) );
|
||||
} else {
|
||||
board_applyLayout( board, &ldims );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
board_applyLayout( BoardCtxt* board, const BoardDims* dims )
|
||||
{
|
||||
board_setPos( board, dims->left, dims->top + dims->scoreHt,
|
||||
dims->width, dims->top + dims->scoreHt + dims->boardHt,
|
||||
dims->maxCellSize, XP_FALSE );
|
||||
|
||||
board_setScoreboardLoc( board, dims->left, dims->top,
|
||||
dims->width - dims->timerWidth,
|
||||
dims->scoreHt, XP_TRUE );
|
||||
|
||||
board_setTimerLoc( board, dims->left + dims->width - dims->timerWidth,
|
||||
dims->top, dims->timerWidth, dims->scoreHt );
|
||||
|
||||
board_setTrayLoc( board, dims->left, dims->trayTop,
|
||||
dims->width, dims->trayHt, dims->width / 20 );
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
board_setPos( BoardCtxt* board, XP_U16 left, XP_U16 top,
|
||||
XP_U16 width, XP_U16 height, XP_U16 maxCellSz,
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "comtypes.h"
|
||||
#include "model.h"
|
||||
#include "gameinfo.h"
|
||||
#include "server.h"
|
||||
#include "draw.h"
|
||||
#include "xwstream.h"
|
||||
|
@ -57,7 +58,6 @@ typedef enum {
|
|||
|
||||
/* typedef struct BoardCtxt BoardCtxt; */
|
||||
|
||||
|
||||
BoardCtxt* board_make( MPFORMAL ModelCtxt* model, ServerCtxt* server,
|
||||
DrawCtx* draw, XW_UtilCtxt* util );
|
||||
BoardCtxt* board_makeFromStream( MPFORMAL XWStreamCtxt* stream,
|
||||
|
@ -70,10 +70,45 @@ void board_destroy( BoardCtxt* board );
|
|||
|
||||
void board_writeToStream( const BoardCtxt* board, XWStreamCtxt* stream );
|
||||
|
||||
void board_reset( BoardCtxt* board );
|
||||
|
||||
/* Layout. Either done internally or by client */
|
||||
#ifdef COMMON_LAYOUT
|
||||
|
||||
typedef struct _BoardDims {
|
||||
XP_U16 left, top;
|
||||
XP_U16 width, height;
|
||||
XP_U16 scoreHt;
|
||||
XP_U16 boardHt;
|
||||
XP_U16 trayTop, trayHt;
|
||||
XP_U16 cellSize, maxCellSize;
|
||||
XP_U16 timerWidth;
|
||||
} BoardDims;
|
||||
|
||||
void board_figureLayout( BoardCtxt* board, const CurGameInfo* gi,
|
||||
XP_U16 scorePct, XP_U16 trayPct,
|
||||
XP_U16 fontHt, XP_U16 fontWidth,
|
||||
XP_Bool squareTiles, const XP_Rect* bounds,
|
||||
/* out */ BoardDims* dims );
|
||||
void board_applyLayout( BoardCtxt* board, const BoardDims* dims );
|
||||
|
||||
#endif
|
||||
|
||||
/* These four aren't needed if COMMON_LAYOUT defined */
|
||||
void board_setPos( BoardCtxt* board, XP_U16 left, XP_U16 top,
|
||||
XP_U16 width, XP_U16 height, XP_U16 maxCellSize,
|
||||
XP_Bool leftHanded );
|
||||
void board_reset( BoardCtxt* board );
|
||||
void board_setScoreboardLoc( BoardCtxt* board,
|
||||
XP_U16 scoreLeft, XP_U16 scoreTop,
|
||||
XP_U16 scoreWidth, XP_U16 scoreHeight,
|
||||
XP_Bool divideHorizontally );
|
||||
void board_setTimerLoc( BoardCtxt* board,
|
||||
XP_U16 timerLeft, XP_U16 timerTop,
|
||||
XP_U16 timerWidth, XP_U16 timerHeight );
|
||||
void board_setTrayLoc( BoardCtxt* board, XP_U16 trayLeft, XP_U16 trayTop,
|
||||
XP_U16 trayWidth, XP_U16 trayHeight,
|
||||
XP_U16 minDividerWidth );
|
||||
|
||||
|
||||
/* Vertical scroll support; offset is in rows, not pixels */
|
||||
XP_Bool board_setYOffset( BoardCtxt* board, XP_U16 newOffset );
|
||||
|
@ -88,13 +123,6 @@ XP_Bool board_canHint( const BoardCtxt* board );
|
|||
/* zoomBy: >0: zoom in; < 0: zoom out; 0: query only */
|
||||
XP_Bool board_zoom( BoardCtxt* board, XP_S16 zoomBy, XP_Bool* canInOut );
|
||||
|
||||
void board_setScoreboardLoc( BoardCtxt* board,
|
||||
XP_U16 scoreLeft, XP_U16 scoreTop,
|
||||
XP_U16 scoreWidth, XP_U16 scoreHeight,
|
||||
XP_Bool divideHorizontally );
|
||||
void board_setTimerLoc( BoardCtxt* board,
|
||||
XP_U16 timerLeft, XP_U16 timerTop,
|
||||
XP_U16 timerWidth, XP_U16 timerHeight );
|
||||
void board_invalAll( BoardCtxt* board );
|
||||
void board_invalRect( BoardCtxt* board, XP_Rect* rect );
|
||||
#ifdef XWFEATURE_ACTIVERECT
|
||||
|
@ -124,7 +152,6 @@ BoardObjectType board_getFocusOwner( BoardCtxt* board );
|
|||
|
||||
void board_hiliteCellAt( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
||||
|
||||
|
||||
void board_resetEngine( BoardCtxt* board );
|
||||
|
||||
XP_Bool board_commitTurn( BoardCtxt* board );
|
||||
|
@ -156,9 +183,6 @@ XP_Bool board_focusChanged( BoardCtxt* board, BoardObjectType typ,
|
|||
/******************** Tray methods ********************/
|
||||
#define NO_TILES ((TileBit)0)
|
||||
|
||||
void board_setTrayLoc( BoardCtxt* board, XP_U16 trayLeft, XP_U16 trayTop,
|
||||
XP_U16 trayWidth, XP_U16 trayHeight,
|
||||
XP_U16 minDividerWidth );
|
||||
XP_Bool board_hideTray( BoardCtxt* board );
|
||||
XP_Bool board_showTray( BoardCtxt* board );
|
||||
XW_TrayVisState board_getTrayVisState( const BoardCtxt* board );
|
||||
|
|
|
@ -240,7 +240,7 @@ typedef struct _PlayerDicts {
|
|||
# define DEBUG_ASSIGN(a,b)
|
||||
#endif
|
||||
|
||||
#define OFFSET_OF(typ,var) ((XP_U16)&(((typ*) 0)->var))
|
||||
#define OFFSET_OF(typ,var) ((XP_U32)&(((typ*) 0)->var))
|
||||
|
||||
#ifndef RELAY_NAME_DEFAULT
|
||||
# define RELAY_NAME_DEFAULT "eehouse.org"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef _GAME_H_
|
||||
#define _GAME_H_
|
||||
|
||||
#include "gameinfo.h"
|
||||
#include "model.h"
|
||||
#include "board.h"
|
||||
#include "comms.h"
|
||||
|
@ -31,40 +32,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct LocalPlayer {
|
||||
XP_UCHAR* name;
|
||||
XP_UCHAR* password;
|
||||
XP_UCHAR* dictName;
|
||||
XP_U16 secondsUsed;
|
||||
XP_Bool isLocal;
|
||||
XP_U8 robotIQ; /* 0 means not a robot; 1-100 means how
|
||||
dumb is it with 1 meaning very smart */
|
||||
} LocalPlayer;
|
||||
|
||||
#define LP_IS_ROBOT(lp) ((lp)->robotIQ != 0)
|
||||
#define LP_IS_LOCAL(lp) ((lp)->isLocal)
|
||||
|
||||
#define DUMB_ROBOT 0
|
||||
#define SMART_ROBOT 1
|
||||
|
||||
typedef struct CurGameInfo {
|
||||
XP_UCHAR* dictName;
|
||||
LocalPlayer players[MAX_NUM_PLAYERS];
|
||||
XP_U32 gameID; /* uniquely identifies game */
|
||||
XP_U16 gameSeconds; /* for timer */
|
||||
XP_LangCode dictLang;
|
||||
XP_U8 nPlayers;
|
||||
XP_U8 boardSize;
|
||||
DeviceRole serverRole;
|
||||
|
||||
XP_Bool hintsNotAllowed;
|
||||
XP_Bool timerEnabled;
|
||||
XP_Bool allowPickTiles;
|
||||
XP_Bool allowHintRect;
|
||||
XWPhoniesChoice phoniesAction;
|
||||
XP_Bool confirmBTConnect; /* only used for BT */
|
||||
} CurGameInfo;
|
||||
|
||||
typedef struct _GameStateInfo {
|
||||
XP_U16 visTileCount;
|
||||
XW_TrayVisState trayVisState;
|
||||
|
|
68
xwords4/common/gameinfo.h
Normal file
68
xwords4/common/gameinfo.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
||||
/*
|
||||
* Copyright 2001-2013 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.
|
||||
*/
|
||||
|
||||
#ifndef _GAMEINFO_H_
|
||||
#define _GAMEINFO_H_
|
||||
|
||||
#include "server.h"
|
||||
|
||||
#ifdef CPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct LocalPlayer {
|
||||
XP_UCHAR* name;
|
||||
XP_UCHAR* password;
|
||||
XP_UCHAR* dictName;
|
||||
XP_U16 secondsUsed;
|
||||
XP_Bool isLocal;
|
||||
XP_U8 robotIQ; /* 0 means not a robot; 1-100 means how
|
||||
dumb is it with 1 meaning very smart */
|
||||
} LocalPlayer;
|
||||
|
||||
#define LP_IS_ROBOT(lp) ((lp)->robotIQ != 0)
|
||||
#define LP_IS_LOCAL(lp) ((lp)->isLocal)
|
||||
|
||||
#define DUMB_ROBOT 0
|
||||
#define SMART_ROBOT 1
|
||||
|
||||
typedef struct CurGameInfo {
|
||||
XP_UCHAR* dictName;
|
||||
LocalPlayer players[MAX_NUM_PLAYERS];
|
||||
XP_U32 gameID; /* uniquely identifies game */
|
||||
XP_U16 gameSeconds; /* for timer */
|
||||
XP_LangCode dictLang;
|
||||
XP_U8 nPlayers;
|
||||
XP_U8 boardSize;
|
||||
DeviceRole serverRole;
|
||||
|
||||
XP_Bool hintsNotAllowed;
|
||||
XP_Bool timerEnabled;
|
||||
XP_Bool allowPickTiles;
|
||||
XP_Bool allowHintRect;
|
||||
XWPhoniesChoice phoniesAction;
|
||||
XP_Bool confirmBTConnect; /* only used for BT */
|
||||
} CurGameInfo;
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -280,51 +280,55 @@ drawScoreBoard( BoardCtxt* board )
|
|||
totalDim += isVertical ? dp->height : dp->width;
|
||||
}
|
||||
|
||||
gotPct = (*adjustDim * 100) / totalDim;
|
||||
for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
|
||||
if ( isVertical ) {
|
||||
dp->height = (dp->height * gotPct) / 100;
|
||||
} else {
|
||||
dp->width = (dp->width * gotPct) / 100;
|
||||
if ( 0 < totalDim ) {
|
||||
gotPct = (*adjustDim * 100) / totalDim;
|
||||
for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
|
||||
if ( isVertical ) {
|
||||
dp->height = (dp->height * gotPct) / 100;
|
||||
} else {
|
||||
dp->width = (dp->width * gotPct) / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scoreRect = board->scoreBdBounds; /* reset */
|
||||
scoreRect = board->scoreBdBounds; /* reset */
|
||||
|
||||
/* at this point, the scoreRect should be anchored at the
|
||||
scoreboard rect's upper left. */
|
||||
/* at this point, the scoreRect should be anchored at the
|
||||
scoreboard rect's upper left. */
|
||||
|
||||
if ( remDim > 0 ) {
|
||||
XP_Rect innerRect;
|
||||
*adjustDim = remDim;
|
||||
centerIn( &innerRect, &scoreRect, remWidth, remHeight );
|
||||
draw_drawRemText( board->draw, &innerRect, &scoreRect,
|
||||
nTilesInPool, focusAll || remFocussed );
|
||||
*adjustPt += remDim;
|
||||
if ( remDim > 0 ) {
|
||||
XP_Rect innerRect;
|
||||
*adjustDim = remDim;
|
||||
centerIn( &innerRect, &scoreRect, remWidth, remHeight );
|
||||
draw_drawRemText( board->draw, &innerRect, &scoreRect,
|
||||
nTilesInPool,
|
||||
focusAll || remFocussed );
|
||||
*adjustPt += remDim;
|
||||
#ifdef KEYBOARD_NAV
|
||||
board->remRect = scoreRect;
|
||||
/* Hack: don't let the cursor disappear if Rem: goes
|
||||
away */
|
||||
} else if ( board->scoreCursorLoc == CURSOR_LOC_REM ) {
|
||||
board->scoreCursorLoc = selPlayer + 1;
|
||||
board->remRect = scoreRect;
|
||||
/* Hack: don't let the cursor disappear if Rem: goes
|
||||
away */
|
||||
} else if ( board->scoreCursorLoc == CURSOR_LOC_REM ) {
|
||||
board->scoreCursorLoc = selPlayer + 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
board->remDim = remDim;
|
||||
board->remDim = remDim;
|
||||
|
||||
for ( dp = datum, ii = 0; ii < nPlayers; ++dp, ++ii ) {
|
||||
XP_Rect innerRect;
|
||||
XP_U16 dim = isVertical? dp->height:dp->width;
|
||||
*adjustDim = board->pti[ii].scoreDims = dim;
|
||||
for ( dp = datum, ii = 0; ii < nPlayers; ++dp, ++ii ) {
|
||||
XP_Rect innerRect;
|
||||
XP_U16 dim = isVertical? dp->height:dp->width;
|
||||
*adjustDim = board->pti[ii].scoreDims = dim;
|
||||
|
||||
centerIn( &innerRect, &scoreRect, dp->width, dp->height );
|
||||
draw_score_drawPlayer( board->draw, &innerRect, &scoreRect,
|
||||
gotPct, &dp->dsi );
|
||||
centerIn( &innerRect, &scoreRect, dp->width,
|
||||
dp->height );
|
||||
draw_score_drawPlayer( board->draw, &innerRect,
|
||||
&scoreRect, gotPct, &dp->dsi );
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_MEMCPY( &board->pti[ii].scoreRects, &scoreRect,
|
||||
sizeof(scoreRect) );
|
||||
XP_MEMCPY( &board->pti[ii].scoreRects, &scoreRect,
|
||||
sizeof(scoreRect) );
|
||||
#endif
|
||||
*adjustPt += *adjustDim;
|
||||
*adjustPt += *adjustDim;
|
||||
}
|
||||
}
|
||||
|
||||
draw_objFinished( board->draw, OBJ_SCORE,
|
||||
|
|
|
@ -328,9 +328,11 @@ drawPendingScore( BoardCtxt* board, XP_S16 turnScore, XP_Bool hasCursor )
|
|||
XP_Rect lastTileR;
|
||||
|
||||
figureTrayTileRect( board, MAX_TRAY_TILES-1, &lastTileR );
|
||||
draw_score_pendingScore( board->draw, &lastTileR, turnScore,
|
||||
selPlayer, curTurn,
|
||||
hasCursor?CELL_ISCURSOR:CELL_NONE );
|
||||
if ( 0 < lastTileR.width && 0 < lastTileR.height ) {
|
||||
draw_score_pendingScore( board->draw, &lastTileR, turnScore,
|
||||
selPlayer, curTurn,
|
||||
hasCursor?CELL_ISCURSOR:CELL_NONE );
|
||||
}
|
||||
}
|
||||
} /* drawPendingScore */
|
||||
|
||||
|
@ -509,7 +511,9 @@ dividerMoved( BoardCtxt* board, XP_U8 newLoc )
|
|||
void
|
||||
board_invalTrayTiles( BoardCtxt* board, TileBit what )
|
||||
{
|
||||
board->trayInvalBits |= what;
|
||||
if ( 0 < board->trayBounds.width && 0 < board->trayBounds.height ) {
|
||||
board->trayInvalBits |= what;
|
||||
}
|
||||
} /* invalTrayTiles */
|
||||
|
||||
void
|
||||
|
|
|
@ -116,6 +116,7 @@ DEFINES += -DXWFEATURE_COMMSACK
|
|||
#DEFINES += -DXWFEATURE_ACTIVERECT
|
||||
DEFINES += -DCOMMS_XPORT_FLAGSPROC
|
||||
DEFINES += -DINITIAL_CLIENT_VERS=2
|
||||
DEFINES += -DCOMMON_LAYOUT
|
||||
|
||||
# MAX_ROWS controls STREAM_VERS_BIGBOARD and with it move hashing
|
||||
DEFINES += -DMAX_ROWS=32
|
||||
|
|
|
@ -1635,8 +1635,12 @@ passKeyToBoard( CursesAppGlobals* globals, char ch )
|
|||
static void
|
||||
positionSizeStuff( CursesAppGlobals* globals, int width, int height )
|
||||
{
|
||||
XP_U16 cellWidth, cellHt, scoreLeft, scoreWidth;
|
||||
BoardCtxt* board = globals->cGlobals.game.board;
|
||||
#ifdef COMMON_LAYOUT
|
||||
XP_USE( width );
|
||||
XP_USE( height );
|
||||
#else
|
||||
XP_U16 cellWidth, cellHt, scoreLeft, scoreWidth;
|
||||
int remWidth = width;
|
||||
int nRows = globals->cGlobals.gi->boardSize;
|
||||
|
||||
|
@ -1680,7 +1684,7 @@ positionSizeStuff( CursesAppGlobals* globals, int width, int height )
|
|||
|
||||
/* no divider -- yet */
|
||||
/* board_setTrayVisible( globals.board, XP_TRUE, XP_FALSE ); */
|
||||
|
||||
#endif
|
||||
board_invalAll( board );
|
||||
} /* positionSizeStuff */
|
||||
|
||||
|
|
|
@ -598,7 +598,36 @@ static gboolean
|
|||
configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
|
||||
GtkGameGlobals* globals )
|
||||
{
|
||||
short bdWidth, bdHeight;
|
||||
if ( globals->draw == NULL ) {
|
||||
createOrLoadObjects( globals );
|
||||
}
|
||||
|
||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||
BoardCtxt* board = cGlobals->game.board;
|
||||
|
||||
short bdWidth = widget->allocation.width - (GTK_RIGHT_MARGIN
|
||||
+ GTK_BOARD_LEFT_MARGIN);
|
||||
short bdHeight = widget->allocation.height - (GTK_TOP_MARGIN + GTK_BOTTOM_MARGIN)
|
||||
- GTK_MIN_TRAY_SCALEV - GTK_BOTTOM_MARGIN;
|
||||
|
||||
#ifdef COMMON_LAYOUT
|
||||
XP_ASSERT( !cGlobals->params->verticalScore ); /* not supported */
|
||||
|
||||
XP_Rect rect = { .left = GTK_BOARD_LEFT, .top = GTK_HOR_SCORE_TOP,
|
||||
.width = bdWidth, .height = bdHeight
|
||||
};
|
||||
BoardDims dims;
|
||||
board_figureLayout( board, cGlobals->gi,
|
||||
#if 1
|
||||
150, 200,
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
16, 16,
|
||||
XP_FALSE, &rect, &dims );
|
||||
board_applyLayout( board, &dims );
|
||||
|
||||
#else
|
||||
short timerLeft, timerTop;
|
||||
gint hscale, vscale;
|
||||
gint trayTop;
|
||||
|
@ -607,48 +636,39 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
|
|||
gint nCols;
|
||||
gint nRows;
|
||||
|
||||
if ( globals->draw == NULL ) {
|
||||
createOrLoadObjects( globals );
|
||||
}
|
||||
|
||||
nCols = globals->cGlobals.gi->boardSize;
|
||||
nCols = cGlobals->gi->boardSize;
|
||||
nRows = nCols;
|
||||
bdWidth = widget->allocation.width - (GTK_RIGHT_MARGIN
|
||||
+ GTK_BOARD_LEFT_MARGIN);
|
||||
if ( globals->cGlobals.params->verticalScore ) {
|
||||
if ( cGlobals->params->verticalScore ) {
|
||||
bdWidth -= GTK_VERT_SCORE_WIDTH;
|
||||
}
|
||||
bdHeight = widget->allocation.height - (GTK_TOP_MARGIN + GTK_BOTTOM_MARGIN)
|
||||
- GTK_MIN_TRAY_SCALEV - GTK_BOTTOM_MARGIN;
|
||||
|
||||
hscale = bdWidth / nCols;
|
||||
if ( 0 != globals->cGlobals.params->nHidden ) {
|
||||
if ( 0 != cGlobals->params->nHidden ) {
|
||||
vscale = hscale;
|
||||
} else {
|
||||
vscale = (bdHeight / (nCols + GTK_TRAY_HT_ROWS)); /* makd tray height
|
||||
3x cell height */
|
||||
}
|
||||
|
||||
if ( !globals->cGlobals.params->verticalScore ) {
|
||||
if ( !cGlobals->params->verticalScore ) {
|
||||
boardTop += GTK_HOR_SCORE_HEIGHT;
|
||||
}
|
||||
|
||||
trayTop = boardTop + (vscale * nRows);
|
||||
/* move tray up if part of board's meant to be hidden */
|
||||
trayTop -= vscale * globals->cGlobals.params->nHidden;
|
||||
board_setPos( globals->cGlobals.game.board, GTK_BOARD_LEFT, boardTop,
|
||||
trayTop -= vscale * cGlobals->params->nHidden;
|
||||
board_setPos( board, GTK_BOARD_LEFT, boardTop,
|
||||
hscale * nCols, vscale * nRows, hscale * 4, XP_FALSE );
|
||||
/* board_setScale( globals->cGlobals.game.board, hscale, vscale ); */
|
||||
globals->gridOn = XP_TRUE;
|
||||
/* board_setScale( board, hscale, vscale ); */
|
||||
|
||||
if ( !!globals->cGlobals.game.comms ) {
|
||||
if ( !!cGlobals->game.comms ) {
|
||||
netStatWidth = GTK_NETSTAT_WIDTH;
|
||||
}
|
||||
|
||||
timerTop = GTK_TIMER_TOP;
|
||||
if ( globals->cGlobals.params->verticalScore ) {
|
||||
if ( cGlobals->params->verticalScore ) {
|
||||
timerLeft = GTK_BOARD_LEFT + (hscale*nCols) + 1;
|
||||
board_setScoreboardLoc( globals->cGlobals.game.board,
|
||||
board_setScoreboardLoc( board,
|
||||
timerLeft,
|
||||
GTK_VERT_SCORE_TOP,
|
||||
GTK_VERT_SCORE_WIDTH,
|
||||
|
@ -658,7 +678,7 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
|
|||
} else {
|
||||
timerLeft = GTK_BOARD_LEFT + (hscale*nCols)
|
||||
- GTK_TIMER_WIDTH - netStatWidth;
|
||||
board_setScoreboardLoc( globals->cGlobals.game.board,
|
||||
board_setScoreboardLoc( board,
|
||||
GTK_BOARD_LEFT, GTK_HOR_SCORE_TOP,
|
||||
timerLeft-GTK_BOARD_LEFT,
|
||||
GTK_HOR_SCORE_HEIGHT,
|
||||
|
@ -667,24 +687,26 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
|
|||
}
|
||||
|
||||
/* Still pending: do this for the vertical score case */
|
||||
if ( globals->cGlobals.game.comms ) {
|
||||
if ( cGlobals->game.comms ) {
|
||||
globals->netStatLeft = timerLeft + GTK_TIMER_WIDTH;
|
||||
globals->netStatTop = 0;
|
||||
}
|
||||
|
||||
board_setTimerLoc( globals->cGlobals.game.board, timerLeft, timerTop,
|
||||
board_setTimerLoc( board, timerLeft, timerTop,
|
||||
GTK_TIMER_WIDTH, GTK_HOR_SCORE_HEIGHT );
|
||||
|
||||
board_setTrayLoc( globals->cGlobals.game.board, GTK_TRAY_LEFT, trayTop,
|
||||
board_setTrayLoc( board, GTK_TRAY_LEFT, trayTop,
|
||||
hscale * nCols, vscale * GTK_TRAY_HT_ROWS + 10,
|
||||
GTK_DIVIDER_WIDTH );
|
||||
|
||||
#endif
|
||||
globals->gridOn = XP_TRUE;
|
||||
|
||||
setCtrlsForTray( globals );
|
||||
|
||||
board_invalAll( globals->cGlobals.game.board );
|
||||
board_invalAll( board );
|
||||
|
||||
XP_Bool inOut[2];
|
||||
board_zoom( globals->cGlobals.game.board, 0, inOut );
|
||||
board_zoom( board, 0, inOut );
|
||||
setZoomButtons( globals, inOut );
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -56,6 +56,7 @@ gtkInsetRect( XP_Rect* r, short i )
|
|||
r->left += i;
|
||||
i *= 2;
|
||||
|
||||
XP_ASSERT( r->height >= i && r->width >= i );
|
||||
r->width -= i;
|
||||
r->height -= i;
|
||||
} /* gtkInsetRect */
|
||||
|
|
|
@ -989,7 +989,10 @@ send_or_close( CommonGlobals* cGlobals, const XP_U8* buf, size_t len )
|
|||
cGlobals->socket = -1;
|
||||
|
||||
/* delete all pending packets since the socket's bad */
|
||||
g_slist_free_full( cGlobals->packetQueue, free_elem_proc );
|
||||
for ( GSList* iter = cGlobals->packetQueue; !!iter; iter = iter->next ) {
|
||||
free_elem_proc( iter->data );
|
||||
}
|
||||
g_slist_free( cGlobals->packetQueue );
|
||||
cGlobals->packetQueue = NULL;
|
||||
}
|
||||
LOG_RETURNF( "%d", success );
|
||||
|
|
Loading…
Add table
Reference in a new issue