2003-11-16 20:23:48 +01:00
|
|
|
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
|
|
|
/*
|
2009-04-07 06:33:47 +02:00
|
|
|
* Copyright 1999 - 2009 by Eric House (xwords@eehouse.org). All rights
|
2006-06-22 06:57:08 +02:00
|
|
|
* reserved.
|
2003-11-16 20:23:48 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <PalmTypes.h>
|
|
|
|
#include <Form.h>
|
|
|
|
#include <List.h>
|
2008-06-07 16:47:55 +02:00
|
|
|
#include <Chars.h> /* for nextFieldChr */
|
2006-06-22 06:57:08 +02:00
|
|
|
#include <Graffiti.h> /* for GrfSetState */
|
2003-11-16 20:23:48 +01:00
|
|
|
#include <Event.h>
|
2006-10-28 16:48:08 +02:00
|
|
|
#ifdef XWFEATURE_FIVEWAY
|
2003-11-16 20:23:48 +01:00
|
|
|
# include <Hs.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "callback.h"
|
|
|
|
#include "comtypes.h"
|
|
|
|
#include "palmmain.h"
|
|
|
|
#include "comms.h"
|
|
|
|
#include "strutils.h"
|
|
|
|
#include "newgame.h"
|
|
|
|
#include "xwords4defines.h"
|
|
|
|
#include "dictui.h"
|
|
|
|
#include "palmdict.h"
|
|
|
|
#include "palmutil.h"
|
|
|
|
#include "palmir.h"
|
|
|
|
#include "prefsdlg.h"
|
|
|
|
#include "connsdlg.h"
|
2008-01-05 17:37:49 +01:00
|
|
|
#include "LocalizedStrIncludes.h"
|
2003-11-16 20:23:48 +01:00
|
|
|
|
|
|
|
static void handlePasswordTrigger( PalmAppGlobals* globals,
|
|
|
|
UInt16 controlID );
|
2008-01-05 17:37:49 +01:00
|
|
|
static XP_Bool updatePlayerInfo( PalmAppGlobals* globals );
|
2003-11-16 20:23:48 +01:00
|
|
|
static void loadNewGameState( PalmAppGlobals* globals );
|
|
|
|
static void unloadNewGameState( PalmAppGlobals* globals );
|
|
|
|
static void setNameThatFits( PalmNewGameState* state );
|
2006-09-24 19:56:14 +02:00
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
static void palmEnableColProc( void* closure, XP_U16 player,
|
2006-10-28 16:48:08 +02:00
|
|
|
NewGameColumn col, XP_TriEnable enable );
|
2006-06-22 06:57:08 +02:00
|
|
|
static void palmEnableAttrProc( void* closure, NewGameAttr attr,
|
2006-10-28 16:48:08 +02:00
|
|
|
XP_TriEnable enable );
|
2006-06-22 06:57:08 +02:00
|
|
|
static void palmGetColProc( void* closure, XP_U16 player, NewGameColumn col,
|
|
|
|
NgCpCallbk cpcb, const void* cbClosure );
|
|
|
|
static void palmSetColProc( void* closure, XP_U16 player, NewGameColumn col,
|
|
|
|
const NGValue value );
|
|
|
|
static void palmSetAttrProc( void* closure, NewGameAttr attr,
|
|
|
|
const NGValue value );
|
|
|
|
static void handleRobotChanged( PalmNewGameState* state, XP_U16 controlID,
|
|
|
|
XP_Bool on );
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
2006-06-22 06:57:08 +02:00
|
|
|
static void handleRemoteChanged( PalmNewGameState* state, XP_U16 controlID,
|
|
|
|
XP_Bool on );
|
2006-10-28 16:48:08 +02:00
|
|
|
static Boolean checkHiliteGadget(PalmAppGlobals* globals,
|
|
|
|
const EventType* event,
|
2003-11-16 20:23:48 +01:00
|
|
|
PalmNewGameState* state );
|
|
|
|
static void drawConnectGadgets( PalmAppGlobals* globals );
|
|
|
|
static void changeGadgetHilite( PalmAppGlobals* globals, UInt16 hiliteID );
|
|
|
|
|
|
|
|
#else
|
|
|
|
# define checkHiliteGadget(globals, event, state) XP_FALSE
|
|
|
|
# define drawConnectGadgets( globals )
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
Boolean
|
|
|
|
newGameHandleEvent( EventPtr event )
|
|
|
|
{
|
|
|
|
Boolean result = false;
|
|
|
|
PalmAppGlobals* globals;
|
|
|
|
FormPtr form;
|
|
|
|
CurGameInfo* gi;
|
|
|
|
PalmNewGameState* state;
|
|
|
|
Int16 chosen;
|
2006-10-29 18:41:14 +01:00
|
|
|
XP_S16 itemId;
|
2003-11-16 20:23:48 +01:00
|
|
|
Boolean on;
|
|
|
|
|
|
|
|
CALLBACK_PROLOGUE();
|
|
|
|
|
|
|
|
globals = getFormRefcon();
|
|
|
|
gi = &globals->gameInfo;
|
|
|
|
state = &globals->newGameState;
|
|
|
|
|
|
|
|
switch ( event->eType ) {
|
|
|
|
|
|
|
|
case frmOpenEvent:
|
|
|
|
|
|
|
|
GlobalPrefsToLocal( globals );
|
|
|
|
|
|
|
|
form = FrmGetActiveForm();
|
2006-06-22 06:57:08 +02:00
|
|
|
|
|
|
|
XP_ASSERT( !state->ngc );
|
|
|
|
XP_MEMSET( state, 0, sizeof(*state) );
|
|
|
|
|
|
|
|
state->form = form;
|
|
|
|
|
|
|
|
loadNewGameState( globals );
|
2006-09-24 19:56:14 +02:00
|
|
|
if ( !globals->isNewGame ) {
|
2006-10-28 16:48:08 +02:00
|
|
|
disOrEnableTri( form, XW_DICT_SELECTOR_ID, TRI_ENAB_DISABLED );
|
2006-09-24 19:56:14 +02:00
|
|
|
}
|
2003-11-16 20:23:48 +01:00
|
|
|
|
|
|
|
XP_ASSERT( !!state->dictName );
|
|
|
|
setNameThatFits( state );
|
|
|
|
|
|
|
|
XP_ASSERT( !!globals->game.server );
|
|
|
|
case frmUpdateEvent:
|
|
|
|
GrfSetState( false, false, false );
|
|
|
|
FrmDrawForm( FrmGetActiveForm() );
|
|
|
|
|
|
|
|
drawConnectGadgets( globals );
|
|
|
|
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
|
2006-10-28 16:48:08 +02:00
|
|
|
#ifdef XWFEATURE_FIVEWAY
|
|
|
|
/* docs say to return HANDLED for both take and lost if the right
|
|
|
|
object */
|
2003-11-16 20:23:48 +01:00
|
|
|
case frmObjectFocusTakeEvent:
|
|
|
|
case frmObjectFocusLostEvent:
|
2007-04-23 05:20:37 +02:00
|
|
|
result = considerGadgetFocus( globals, event, XW_SOLO_GADGET_ID,
|
2006-10-28 16:48:08 +02:00
|
|
|
XW_CLIENT_GADGET_ID );
|
2003-11-16 20:23:48 +01:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case penDownEvent:
|
|
|
|
result = checkHiliteGadget( globals, event, state );
|
|
|
|
break;
|
|
|
|
|
2006-10-28 16:48:08 +02:00
|
|
|
#ifdef XWFEATURE_FIVEWAY
|
2003-11-16 20:23:48 +01:00
|
|
|
case keyDownEvent:
|
2006-10-28 16:48:08 +02:00
|
|
|
itemId = getFocusOwner();
|
2006-10-29 18:41:14 +01:00
|
|
|
if ( itemId >= 0 ) {
|
|
|
|
result = tryRockerKey( event->data.keyDown.chr, itemId,
|
|
|
|
XW_SOLO_GADGET_ID, XW_CLIENT_GADGET_ID );
|
|
|
|
if ( result ) {
|
|
|
|
changeGadgetHilite( globals, itemId );
|
|
|
|
}
|
2006-10-28 16:48:08 +02:00
|
|
|
}
|
2003-11-16 20:23:48 +01:00
|
|
|
break;
|
2006-10-28 16:48:08 +02:00
|
|
|
#endif
|
2003-11-16 20:23:48 +01:00
|
|
|
|
|
|
|
case prefsChangedEvent:
|
|
|
|
state->forwardChange = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ctlSelectEvent:
|
|
|
|
result = true;
|
2006-10-28 16:48:08 +02:00
|
|
|
itemId = event->data.ctlSelect.controlID;
|
2003-11-16 20:23:48 +01:00
|
|
|
on = event->data.ctlSelect.on;
|
2006-10-28 16:48:08 +02:00
|
|
|
switch ( itemId ) {
|
2003-11-16 20:23:48 +01:00
|
|
|
|
|
|
|
case XW_ROBOT_1_CHECKBOX_ID:
|
|
|
|
case XW_ROBOT_2_CHECKBOX_ID:
|
|
|
|
case XW_ROBOT_3_CHECKBOX_ID:
|
|
|
|
case XW_ROBOT_4_CHECKBOX_ID:
|
2006-10-28 16:48:08 +02:00
|
|
|
handleRobotChanged( state, itemId, on );
|
2003-11-16 20:23:48 +01:00
|
|
|
break;
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case XW_REMOTE_1_CHECKBOX_ID:
|
|
|
|
case XW_REMOTE_2_CHECKBOX_ID:
|
|
|
|
case XW_REMOTE_3_CHECKBOX_ID:
|
|
|
|
case XW_REMOTE_4_CHECKBOX_ID:
|
2006-10-28 16:48:08 +02:00
|
|
|
handleRemoteChanged( state, itemId, on );
|
2003-11-16 20:23:48 +01:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case XW_NPLAYERS_SELECTOR_ID:
|
|
|
|
XP_ASSERT( globals->isNewGame );
|
|
|
|
chosen = LstPopupList( state->playerNumList );
|
|
|
|
if ( chosen >= 0 ) {
|
2006-06-22 06:57:08 +02:00
|
|
|
NGValue value;
|
|
|
|
setSelectorFromList( XW_NPLAYERS_SELECTOR_ID,
|
2003-11-16 20:23:48 +01:00
|
|
|
state->playerNumList,
|
|
|
|
chosen );
|
2006-06-22 06:57:08 +02:00
|
|
|
value.ng_u16 = chosen + 1;
|
|
|
|
newg_attrChanged( state->ngc, NG_ATTR_NPLAYERS, value );
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XW_DICT_SELECTOR_ID:
|
|
|
|
XP_ASSERT( globals->isNewGame );
|
|
|
|
globals->dictuiForBeaming = false;
|
|
|
|
FrmPopupForm( XW_DICTINFO_FORM );
|
|
|
|
|
|
|
|
/* popup dict selection dialog -- or maybe just a list if there
|
|
|
|
are no preferences to set. The results should all be
|
|
|
|
cancellable, so don't delete the existing dictionary (if
|
|
|
|
any) until OK is chosen */
|
|
|
|
break;
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
case XW_GINFO_JUGGLE_ID:
|
2006-07-01 16:18:00 +02:00
|
|
|
while ( !newg_juggle( state->ngc ) ) {
|
|
|
|
}
|
|
|
|
(void)newg_juggle( state->ngc );
|
2006-06-22 06:57:08 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
case XW_OK_BUTTON_ID:
|
2008-01-05 17:37:49 +01:00
|
|
|
if ( updatePlayerInfo( globals ) ) {
|
|
|
|
/* if we put up the prefs form from within this one and the user
|
|
|
|
clicked ok, we need to make sure the main form gets the
|
|
|
|
notification so it can make use of any changes. This event
|
|
|
|
needs to arrive before the newGame event so any changes will
|
|
|
|
be incorporated. */
|
|
|
|
if ( state->forwardChange ) {
|
|
|
|
postEmptyEvent( prefsChangedEvent );
|
|
|
|
state->forwardChange = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( globals->isNewGame ) {
|
|
|
|
postEmptyEvent( newGameOkEvent );
|
|
|
|
globals->postponeDraw = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
unloadNewGameState( globals );
|
|
|
|
|
|
|
|
FrmReturnToForm( 0 );
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XW_CANCEL_BUTTON_ID:
|
|
|
|
unloadNewGameState( globals );
|
2007-12-09 02:59:15 +01:00
|
|
|
postEmptyEvent( newGameCancelEvent );
|
2003-11-16 20:23:48 +01:00
|
|
|
FrmReturnToForm( 0 );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XW_PREFS_BUTTON_ID:
|
|
|
|
/* bring up with the this-game tab selected */
|
|
|
|
XP_ASSERT( !!globals->prefsDlgState );
|
|
|
|
globals->prefsDlgState->stateTypeIsGlobal = false;
|
|
|
|
FrmPopupForm( XW_PREFS_FORM );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XW_PLAYERPASSWD_1_TRIGGER_ID:
|
|
|
|
case XW_PLAYERPASSWD_2_TRIGGER_ID:
|
|
|
|
case XW_PLAYERPASSWD_3_TRIGGER_ID:
|
|
|
|
case XW_PLAYERPASSWD_4_TRIGGER_ID:
|
2006-10-28 16:48:08 +02:00
|
|
|
handlePasswordTrigger( globals, itemId );
|
2003-11-16 20:23:48 +01:00
|
|
|
break;
|
|
|
|
|
2008-06-07 16:47:55 +02:00
|
|
|
default: /* one of the password selectors? */
|
2003-11-16 20:23:48 +01:00
|
|
|
result = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dictSelectedEvent:
|
|
|
|
/* posted by the form we raise when user clicks Dictionary selector
|
|
|
|
above. */
|
|
|
|
if ( state->dictName != NULL ) {
|
|
|
|
XP_FREE( globals->mpool, state->dictName );
|
|
|
|
}
|
|
|
|
state->dictName =
|
|
|
|
((DictSelectedData*)&event->data.generic)->dictName;
|
|
|
|
setNameThatFits( state );
|
|
|
|
break;
|
|
|
|
|
2007-12-08 19:11:42 +01:00
|
|
|
case appStopEvent: /* I get these on older palms */
|
|
|
|
unloadNewGameState( globals );
|
|
|
|
result = false;
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CALLBACK_EPILOGUE();
|
|
|
|
return result;
|
|
|
|
} /* newGameHandleEvent */
|
|
|
|
|
|
|
|
static void
|
|
|
|
setNameThatFits( PalmNewGameState* state )
|
|
|
|
{
|
|
|
|
RectangleType rect;
|
|
|
|
XP_U16 width;
|
|
|
|
XP_U16 len = XP_STRLEN( (const char*)state->dictName );
|
|
|
|
|
|
|
|
XP_MEMCPY( state->shortDictName, state->dictName, len + 1 );
|
|
|
|
|
|
|
|
/* The width available is the cancel button's left minus ours */
|
|
|
|
getObjectBounds( XW_CANCEL_BUTTON_ID, &rect );
|
|
|
|
width = rect.topLeft.x;
|
|
|
|
getObjectBounds( XW_DICT_SELECTOR_ID, &rect );
|
|
|
|
width -= (rect.topLeft.x + 6);
|
|
|
|
|
|
|
|
for ( ; FntCharsWidth( (const char*)state->dictName, len ) > width; --len ) {
|
|
|
|
/* do nothing */
|
|
|
|
}
|
|
|
|
|
|
|
|
state->shortDictName[len] = '\0';
|
|
|
|
CtlSetLabel( getActiveObjectPtr( XW_DICT_SELECTOR_ID ),
|
|
|
|
(const char*)state->shortDictName );
|
|
|
|
} /* setNameThatFits */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy the local state into global state.
|
|
|
|
*/
|
2008-01-05 17:37:49 +01:00
|
|
|
static XP_Bool
|
2003-11-16 20:23:48 +01:00
|
|
|
updatePlayerInfo( PalmAppGlobals* globals )
|
|
|
|
{
|
|
|
|
CurGameInfo* gi;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
2008-01-05 17:37:49 +01:00
|
|
|
XP_Bool success;
|
2003-11-16 20:23:48 +01:00
|
|
|
|
|
|
|
gi = &globals->gameInfo;
|
2008-01-05 17:37:49 +01:00
|
|
|
success = newg_store( state->ngc, gi, XP_TRUE );
|
|
|
|
if ( success ) {
|
|
|
|
gi->boardSize = globals->prefsDlgState->curBdSize;
|
2003-11-16 20:23:48 +01:00
|
|
|
|
2008-01-05 17:37:49 +01:00
|
|
|
replaceStringIfDifferent( globals->mpool, &gi->dictName,
|
|
|
|
globals->newGameState.dictName );
|
|
|
|
}
|
|
|
|
return success;
|
2003-11-16 20:23:48 +01:00
|
|
|
} /* updatePlayerInfo */
|
|
|
|
|
|
|
|
/* Frame 'em, draw their text, and highlight the one that's selected
|
|
|
|
*/
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
|
|
|
|
static void
|
|
|
|
drawConnectGadgets( PalmAppGlobals* globals )
|
|
|
|
{
|
2006-10-28 16:48:08 +02:00
|
|
|
XP_U16 hiliteItem = globals->newGameState.curServerHilite
|
|
|
|
+ XW_SOLO_GADGET_ID ;
|
2003-11-16 20:23:48 +01:00
|
|
|
ListPtr list = getActiveObjectPtr( XW_SERVERTYPES_LIST_ID );
|
|
|
|
XP_ASSERT( !!list );
|
|
|
|
|
2006-10-28 16:48:08 +02:00
|
|
|
drawGadgetsFromList( list, XW_SOLO_GADGET_ID, XW_CLIENT_GADGET_ID,
|
|
|
|
hiliteItem );
|
|
|
|
#ifdef XWFEATURE_FIVEWAY
|
2007-04-23 05:20:37 +02:00
|
|
|
drawFocusRingOnGadget( globals, XW_SOLO_GADGET_ID, XW_CLIENT_GADGET_ID );
|
2003-11-16 20:23:48 +01:00
|
|
|
#endif
|
|
|
|
} /* drawConnectGadgets */
|
|
|
|
|
|
|
|
static void
|
|
|
|
changeGadgetHilite( PalmAppGlobals* globals, UInt16 hiliteID )
|
|
|
|
{
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
XP_Bool isNewGame = globals->isNewGame;
|
|
|
|
|
|
|
|
hiliteID -= XW_SOLO_GADGET_ID;
|
|
|
|
|
|
|
|
if ( hiliteID != state->curServerHilite ) {
|
|
|
|
/* if it's not a new game, don't recognize the change */
|
|
|
|
if ( isNewGame ) {
|
2006-06-22 06:57:08 +02:00
|
|
|
NGValue value;
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
state->curServerHilite = hiliteID;
|
|
|
|
drawConnectGadgets( globals );
|
2006-06-22 06:57:08 +02:00
|
|
|
|
|
|
|
value.ng_role = hiliteID;
|
|
|
|
newg_attrChanged( state->ngc, NG_ATTR_ROLE, value );
|
2003-11-16 20:23:48 +01:00
|
|
|
} else {
|
|
|
|
beep();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
|
2006-09-24 19:56:14 +02:00
|
|
|
/* Even if it didn't change, pop the connections form. It's only
|
|
|
|
informational in the non-new-game case; nothing can be changed. */
|
2009-02-17 06:54:28 +01:00
|
|
|
if ( hiliteID != SERVER_STANDALONE ) {
|
2007-12-08 19:11:42 +01:00
|
|
|
if ( isNewGame || (hiliteID==globals->newGameState.curServerHilite) ) {
|
2005-04-03 03:58:02 +02:00
|
|
|
PopupConnsForm( globals, hiliteID, &state->addr );
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} /* changeGadgetHilite */
|
|
|
|
|
|
|
|
static Boolean
|
2006-10-28 16:48:08 +02:00
|
|
|
checkHiliteGadget( PalmAppGlobals* globals, const EventType* event,
|
2006-08-16 15:44:44 +02:00
|
|
|
PalmNewGameState* XP_UNUSED_DBG(state) )
|
2003-11-16 20:23:48 +01:00
|
|
|
{
|
|
|
|
Boolean result = false;
|
|
|
|
UInt16 selGadget;
|
|
|
|
|
|
|
|
XP_ASSERT( &globals->newGameState == state );
|
|
|
|
|
|
|
|
result = penInGadget( event, &selGadget );
|
|
|
|
if ( result ) {
|
|
|
|
changeGadgetHilite( globals, selGadget );
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
} /* checkHiliteGadget */
|
|
|
|
#endif
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
static void
|
|
|
|
showMaskedPwd( XP_U16 objectID, XP_Bool set )
|
|
|
|
{
|
|
|
|
const char* label = set? "*" : " ";
|
|
|
|
/* control owns the string passed in */
|
|
|
|
CtlSetLabel( getActiveObjectPtr( objectID ), label );
|
|
|
|
}
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
/* If there's currently no password set, just let 'em set one. If there is
|
|
|
|
* one set, they need to know the old before setting the new.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
handlePasswordTrigger( PalmAppGlobals* globals, UInt16 controlID )
|
|
|
|
{
|
|
|
|
UInt16 playerNum;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
XP_UCHAR* name;
|
|
|
|
FieldPtr nameField;
|
|
|
|
XP_U16 len;
|
|
|
|
|
|
|
|
playerNum = (controlID - XW_PLAYERPASSWD_1_TRIGGER_ID) / NUM_PLAYER_COLS;
|
|
|
|
XP_ASSERT( playerNum < MAX_NUM_PLAYERS );
|
|
|
|
|
|
|
|
nameField = getActiveObjectPtr( XW_PLAYERNAME_1_FIELD_ID +
|
|
|
|
(NUM_PLAYER_COLS * playerNum) );
|
|
|
|
name = (XP_UCHAR*)FldGetTextPtr( nameField );
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
len = sizeof(state->passwds[playerNum]);
|
2007-06-18 15:21:36 +02:00
|
|
|
if ( askPassword( globals, name, true, state->passwds[playerNum], &len )) {
|
2006-06-22 06:57:08 +02:00
|
|
|
showMaskedPwd( controlID, len > 0 );
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
|
|
|
} /* handlePasswordTrigger */
|
|
|
|
|
|
|
|
static void
|
|
|
|
unloadNewGameState( PalmAppGlobals* globals )
|
|
|
|
{
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, state->dictName );
|
|
|
|
state->dictName = NULL;
|
2006-06-22 06:57:08 +02:00
|
|
|
|
|
|
|
newg_destroy( state->ngc );
|
|
|
|
state->ngc = NULL;
|
2003-11-16 20:23:48 +01:00
|
|
|
} /* unloadNewGameState */
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
static XP_U16
|
|
|
|
getBaseForCol( NewGameColumn col )
|
|
|
|
{
|
|
|
|
XP_U16 resID = 0;
|
|
|
|
switch ( col ) {
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case NG_COL_REMOTE:
|
|
|
|
resID = XW_REMOTE_1_CHECKBOX_ID;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case NG_COL_NAME:
|
|
|
|
resID = XW_PLAYERNAME_1_FIELD_ID;
|
|
|
|
break;
|
|
|
|
case NG_COL_ROBOT:
|
|
|
|
resID = XW_ROBOT_1_CHECKBOX_ID;
|
|
|
|
break;
|
|
|
|
case NG_COL_PASSWD:
|
|
|
|
resID = XW_PLAYERPASSWD_1_TRIGGER_ID;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
XP_ASSERT( XP_FALSE );
|
|
|
|
}
|
|
|
|
XP_ASSERT( !!resID );
|
|
|
|
return resID;
|
|
|
|
} /* getBaseForCol */
|
|
|
|
|
|
|
|
static XP_U16
|
|
|
|
objIDForCol( XP_U16 player, NewGameColumn col )
|
|
|
|
{
|
|
|
|
XP_U16 base = getBaseForCol( col );
|
|
|
|
return base + (NUM_PLAYER_COLS * player);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ControlPtr
|
|
|
|
getControlForCol( XP_U16 player, NewGameColumn col )
|
|
|
|
{
|
|
|
|
XP_U16 objID = objIDForCol( player, col );
|
|
|
|
ControlPtr ctrl = getActiveObjectPtr( objID );
|
|
|
|
return ctrl;
|
|
|
|
}
|
|
|
|
|
2003-11-16 20:23:48 +01:00
|
|
|
static void
|
2006-06-22 06:57:08 +02:00
|
|
|
palmEnableColProc( void* closure, XP_U16 player, NewGameColumn col,
|
2006-10-28 16:48:08 +02:00
|
|
|
XP_TriEnable enable )
|
2003-11-16 20:23:48 +01:00
|
|
|
{
|
2006-06-22 06:57:08 +02:00
|
|
|
PalmAppGlobals* globals = (PalmAppGlobals*)closure;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
2006-10-28 16:48:08 +02:00
|
|
|
XP_U16 objID;
|
|
|
|
|
|
|
|
/* If it's a field, there need to be three states */
|
|
|
|
objID = objIDForCol( player, col );
|
|
|
|
disOrEnableTri( state->form, objID, enable );
|
2006-06-22 06:57:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Palm doesn't really do "disabled." Things are visible or not. But we
|
|
|
|
* want the player count dropdown in particular visible since it give
|
|
|
|
* information. So different objects get treated differently. The code
|
|
|
|
* handling ctlEnterEvent can disable for non-newgame dialogs even if a
|
|
|
|
* control is technically enabled.
|
|
|
|
*/
|
|
|
|
static void
|
2006-10-28 16:48:08 +02:00
|
|
|
palmEnableAttrProc(void* closure, NewGameAttr attr, XP_TriEnable ngEnable )
|
2006-06-22 06:57:08 +02:00
|
|
|
{
|
|
|
|
PalmAppGlobals* globals = (PalmAppGlobals*)closure;
|
2003-11-16 20:23:48 +01:00
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
2006-06-22 06:57:08 +02:00
|
|
|
XP_U16 objID = 0;
|
2003-11-16 20:23:48 +01:00
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
switch ( attr ) {
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case NG_ATTR_ROLE:
|
|
|
|
/* always enabled */
|
|
|
|
break;
|
|
|
|
case NG_ATTR_REMHEADER:
|
|
|
|
objID = XW_LOCAL_LABEL_ID;
|
|
|
|
break;
|
2009-04-07 06:33:47 +02:00
|
|
|
case NG_ATTR_CANCONFIG: /* not needed on palm */
|
|
|
|
break;
|
2006-06-22 06:57:08 +02:00
|
|
|
#endif
|
|
|
|
case NG_ATTR_NPLAYERS:
|
|
|
|
objID = XW_NPLAYERS_SELECTOR_ID;
|
|
|
|
break;
|
|
|
|
case NG_ATTR_NPLAYHEADER:
|
|
|
|
break;
|
|
|
|
case NG_ATTR_CANJUGGLE:
|
|
|
|
objID = XW_GINFO_JUGGLE_ID;
|
|
|
|
break;
|
|
|
|
}
|
2003-11-16 20:23:48 +01:00
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
if ( objID != 0 ) {
|
2006-10-28 16:48:08 +02:00
|
|
|
disOrEnableTri( state->form, objID, ngEnable );
|
2006-06-22 06:57:08 +02:00
|
|
|
}
|
|
|
|
} /* palmEnableAttrProc */
|
2003-11-16 20:23:48 +01:00
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
static void
|
|
|
|
palmGetColProc( void* closure, XP_U16 player, NewGameColumn col,
|
|
|
|
NgCpCallbk cpcb, const void* cbClosure )
|
|
|
|
{
|
|
|
|
PalmAppGlobals* globals;
|
|
|
|
PalmNewGameState* state;
|
|
|
|
NGValue value;
|
|
|
|
XP_U16 objID = objIDForCol( player, col );
|
|
|
|
|
|
|
|
switch ( col ) {
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case NG_COL_REMOTE:
|
|
|
|
#endif
|
|
|
|
case NG_COL_ROBOT:
|
|
|
|
value.ng_bool = getBooleanCtrl( objID );
|
|
|
|
break;
|
|
|
|
case NG_COL_NAME:
|
|
|
|
value.ng_cp = FldGetTextPtr( getActiveObjectPtr( objID ) );
|
|
|
|
break;
|
|
|
|
case NG_COL_PASSWD:
|
|
|
|
globals = (PalmAppGlobals*)closure;
|
|
|
|
state = &globals->newGameState;
|
|
|
|
value.ng_cp = state->passwds[player];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
XP_ASSERT(0);
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
(*cpcb)( value, cbClosure );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
palmSetColProc( void* closure, XP_U16 player, NewGameColumn col,
|
|
|
|
const NGValue value )
|
|
|
|
{
|
|
|
|
PalmAppGlobals* globals = (PalmAppGlobals*)closure;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
ControlPtr ctrl;
|
|
|
|
XP_U16 objID = objIDForCol( player, col );
|
|
|
|
|
|
|
|
switch ( col ) {
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case NG_COL_REMOTE:
|
|
|
|
#endif
|
|
|
|
case NG_COL_ROBOT:
|
|
|
|
ctrl = getControlForCol( player, col );
|
|
|
|
CtlSetValue( ctrl, value.ng_bool );
|
|
|
|
break;
|
|
|
|
case NG_COL_NAME:
|
|
|
|
setFieldStr( objID, value.ng_cp );
|
|
|
|
break;
|
|
|
|
case NG_COL_PASSWD:
|
|
|
|
if ( !!value.ng_cp ) {
|
|
|
|
XP_SNPRINTF( state->passwds[player], sizeof(state->passwds[player]),
|
|
|
|
"%s", value.ng_cp );
|
|
|
|
showMaskedPwd( objID, *value.ng_cp != '\0' );
|
|
|
|
}
|
|
|
|
|
|
|
|
default: /* shut up compiler */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} /* palmSetColProc */
|
|
|
|
|
|
|
|
static void
|
|
|
|
palmSetAttrProc( void* closure, NewGameAttr attr, const NGValue value )
|
|
|
|
{
|
|
|
|
PalmAppGlobals* globals = (PalmAppGlobals*)closure;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
|
|
|
|
switch ( attr ) {
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case NG_ATTR_ROLE:
|
|
|
|
state->curServerHilite = value.ng_role;
|
|
|
|
break;
|
|
|
|
case NG_ATTR_REMHEADER:
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case NG_ATTR_NPLAYERS:
|
|
|
|
setSelectorFromList( XW_NPLAYERS_SELECTOR_ID,
|
|
|
|
state->playerNumList, value.ng_u16 - 1 );
|
|
|
|
break;
|
2006-07-28 10:03:33 +02:00
|
|
|
case NG_ATTR_NPLAYHEADER: {
|
|
|
|
FieldPtr field = getActiveObjectPtr( XW_TOTALP_FIELD_ID );
|
|
|
|
char* cur = FldGetTextPtr( field );
|
|
|
|
/* Need to update to get it drawn and that flashes the whole dialog.
|
|
|
|
So avoid if possible. */
|
|
|
|
if ( !cur || (0 != StrCompare( cur, value.ng_cp ) ) ) {
|
|
|
|
FldSetTextPtr( field, (char*)value.ng_cp );
|
|
|
|
FrmUpdateForm( 0, frmRedrawUpdateCode );
|
|
|
|
}
|
|
|
|
}
|
2006-06-22 06:57:08 +02:00
|
|
|
break;
|
|
|
|
case NG_ATTR_CANJUGGLE:
|
|
|
|
XP_ASSERT(0); /* doesn't make sense */
|
2009-04-07 06:33:47 +02:00
|
|
|
case NG_ATTR_CANCONFIG: /* not needed on palm */
|
2006-06-22 06:57:08 +02:00
|
|
|
break;
|
|
|
|
}
|
2006-07-28 10:03:33 +02:00
|
|
|
} /* palmSetAttrProc */
|
2006-06-22 06:57:08 +02:00
|
|
|
|
|
|
|
static XP_U16
|
|
|
|
palmPlayerFromID( XP_U16 id, XP_U16 base )
|
|
|
|
{
|
|
|
|
XP_U16 player;
|
|
|
|
player = (id - base) / NUM_PLAYER_COLS;
|
|
|
|
return player;
|
|
|
|
} /* palmPlayerFromID */
|
|
|
|
|
|
|
|
static void
|
|
|
|
handleRobotChanged( PalmNewGameState* state, XP_U16 controlID, XP_Bool on )
|
|
|
|
{
|
|
|
|
XP_U16 player;
|
|
|
|
NGValue value;
|
|
|
|
|
|
|
|
player = palmPlayerFromID( controlID, XW_ROBOT_1_CHECKBOX_ID );
|
|
|
|
value.ng_bool = on;
|
2006-08-16 15:44:44 +02:00
|
|
|
newg_colChanged( state->ngc, player );
|
2006-06-22 06:57:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
static void
|
|
|
|
handleRemoteChanged( PalmNewGameState* state, XP_U16 controlID, XP_Bool on )
|
|
|
|
{
|
|
|
|
XP_U16 player;
|
|
|
|
NGValue value;
|
|
|
|
|
2007-12-02 20:13:25 +01:00
|
|
|
XP_LOGF( "%s: controlID=%d", __func__, controlID );
|
2006-06-22 06:57:08 +02:00
|
|
|
|
|
|
|
player = palmPlayerFromID( controlID, XW_REMOTE_1_CHECKBOX_ID );
|
|
|
|
value.ng_bool = on;
|
2006-08-16 15:44:44 +02:00
|
|
|
newg_colChanged( state->ngc, player );
|
2006-06-22 06:57:08 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-12-08 19:11:42 +01:00
|
|
|
XP_U16
|
|
|
|
countXPorts( const PalmAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_U16 xports = 0;
|
|
|
|
#ifdef XWFEATURE_IR
|
|
|
|
++xports;
|
|
|
|
#endif
|
|
|
|
#ifdef XWFEATURE_BLUETOOTH
|
|
|
|
if ( globals->hasBTLib ) {
|
|
|
|
++xports;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef XWFEATURE_RELAY
|
|
|
|
++xports;
|
|
|
|
#endif
|
|
|
|
return xports;
|
|
|
|
}
|
|
|
|
|
2006-06-22 06:57:08 +02:00
|
|
|
static void
|
|
|
|
loadNewGameState( PalmAppGlobals* globals )
|
|
|
|
{
|
|
|
|
CurGameInfo* gi = &globals->gameInfo;
|
|
|
|
PalmNewGameState* state = &globals->newGameState;
|
|
|
|
|
2006-09-15 09:43:21 +02:00
|
|
|
state->dictName = copyString( globals->mpool, gi->dictName );
|
2006-06-22 06:57:08 +02:00
|
|
|
state->playerNumList = getActiveObjectPtr( XW_NPLAYERS_LIST_ID );
|
2007-12-08 19:11:42 +01:00
|
|
|
state->nXPorts = countXPorts( globals );
|
2006-06-22 06:57:08 +02:00
|
|
|
|
2007-12-08 19:11:42 +01:00
|
|
|
XP_ASSERT( !state->ngc );
|
2006-06-22 06:57:08 +02:00
|
|
|
state->ngc = newg_make( MPPARM(globals->mpool)
|
|
|
|
globals->isNewGame,
|
|
|
|
&globals->util,
|
|
|
|
palmEnableColProc,
|
|
|
|
palmEnableAttrProc,
|
|
|
|
palmGetColProc,
|
|
|
|
palmSetColProc,
|
|
|
|
palmSetAttrProc,
|
|
|
|
globals );
|
|
|
|
newg_load( state->ngc, gi );
|
2003-11-16 20:23:48 +01:00
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
|
2005-04-03 03:58:02 +02:00
|
|
|
if ( globals->game.comms ) {
|
|
|
|
comms_getAddr( globals->game.comms, &state->addr );
|
|
|
|
} else {
|
|
|
|
comms_getInitialAddr( &state->addr );
|
2003-11-16 20:23:48 +01:00
|
|
|
}
|
2007-01-06 17:46:45 +01:00
|
|
|
#elif defined XWFEATURE_IR
|
|
|
|
state->addr.conType = COMMS_CONN_IR;
|
2003-11-16 20:23:48 +01:00
|
|
|
#endif
|
|
|
|
} /* loadNewGameState */
|