mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
checked in from personal archive
This commit is contained in:
parent
b3d53f1bd8
commit
7f17376766
13 changed files with 2739 additions and 0 deletions
226
palm/Makefile
Normal file
226
palm/Makefile
Normal file
|
@ -0,0 +1,226 @@
|
|||
# -*- mode: Makefile; -*-
|
||||
# Copyright 2002 by Eric House (fixin@peak.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.
|
||||
|
||||
PLATFORM=palm
|
||||
LANG=en_US
|
||||
TARGET=$(PLATFORM)/xwords4.prc
|
||||
ROOTNAME = Crosswords
|
||||
BITMAPS = ./bmps
|
||||
NAME = "Crosswords"
|
||||
TYPE = appl
|
||||
ICONTEXT = "Crosswords"
|
||||
APPID = Xwr4
|
||||
MLPREFIX = /usr
|
||||
DICT = $(shell echo $$BASENG_PATH)
|
||||
|
||||
#OWNERNAME = "Eric House"
|
||||
NO_REG_REQUIRED = -DNO_REG_REQUIRED
|
||||
|
||||
PALM_TOOLS_PREFIX = $(shell echo $$PALM_TOOLS_PREFIX)
|
||||
|
||||
ifeq (x$(PALM_TOOLS_PREFIX)x, xx)
|
||||
PALM_TOOLS_PREFIX = m68k-palmos-
|
||||
endif
|
||||
#PALM_TOOLS_PREFIX=m68k-palmos-coff-
|
||||
|
||||
CC = $(PALM_TOOLS_PREFIX)gcc
|
||||
AR = $(PALM_TOOLS_PREFIX)ar
|
||||
MULTILINK = $(PALM_TOOLS_PREFIX)multilink
|
||||
PAR = par
|
||||
PILRC = pilrc
|
||||
|
||||
MULTILINK_OPTIONS = -basename $(ROOTNAME) -segmentsize 27k -g \
|
||||
-deadstrip -verbose -gdb-script app.gdb
|
||||
|
||||
ifneq (x$(OWNERNAME)x,xx)
|
||||
HASHDEF = -DOWNER_HASH=$$(./namehash $(OWNERNAME))
|
||||
endif
|
||||
|
||||
MYDEFINES = -DXW_FEATURE_UTILS -DPOINTER_SUPPORT -DKEY_SUPPORT \
|
||||
-DOVERRIDE_EDGE_FOR_INDEX -DDIRECT_PALMOS_CALLS -DCOLOR_SUPPORT \
|
||||
-DSHOW_PROGRESS \
|
||||
$(HASHDEF) $(NO_REG_REQUIRED)
|
||||
|
||||
# turn on letting users pick tiles "face-up"
|
||||
# MYDEFINES += -DFEATURE_TRAY_EDIT
|
||||
|
||||
MYDEFINES += -DBEYOND_IR
|
||||
|
||||
ifdef XWFEATURE_STANDALONE_ONLY
|
||||
MYDEFINES += -DXWFEATURE_STANDALONE_ONLY
|
||||
else
|
||||
MYDEFINES += -DIR_SUPPORT -DIR_EXCHMGR
|
||||
endif
|
||||
# -DEIGHT_TILES
|
||||
# -DSUPPORT_SONY_JOGDIAL
|
||||
|
||||
# HS_DUO_SUPPORT = 1
|
||||
|
||||
DEFINES += -DPLATFORM_PALM -D__BIG_ENDIAN $(MYDEFINES)
|
||||
|
||||
BITMAP_RSRCS = \
|
||||
$(BITMAPS)/rightarrow.pbitm \
|
||||
$(BITMAPS)/downarrow.pbitm \
|
||||
$(BITMAPS)/flipbutton.pbitm \
|
||||
$(BITMAPS)/valuebutton.pbitm \
|
||||
$(BITMAPS)/lightbulb.pbitm \
|
||||
$(BITMAPS)/traybuttons.pbitm \
|
||||
$(BITMAPS)/showtray.pbitm \
|
||||
$(BITMAPS)/xwords4.pbitm \
|
||||
$(BITMAPS)/xwcoloricon.ppm \
|
||||
$(BITMAPS)/xwords4small.pbitm \
|
||||
|
||||
INCLUDES += -I/usr/local/share/palmdev/sdk-4.0/Extensions/ExpansionMgr
|
||||
|
||||
ifneq (x$(HS_DUO_SUPPORT)x, xx)
|
||||
INCLUDES += -I/usr/local/share/palmdev/duoIncs
|
||||
INCLUDES += -I/usr/local/share/palmdev/duoIncs/68K
|
||||
INCLUDES += -I/usr/local/share/palmdev/duoIncs/68K/System
|
||||
INCLUDES += -I/usr/local/share/palmdev/duoIncs/Common/System
|
||||
|
||||
MYDEFINES += -DHS_DUO_SUPPORT
|
||||
|
||||
FNAVS = ./fnav03e9.bin
|
||||
endif
|
||||
|
||||
|
||||
CSFLAGS = -O2 -g -S -Wall -DAPPID=\'$(APPID)\' $(DEFINES) $(INCLUDES)
|
||||
#CFLAGS = -O2 -g -Wall -DAPPID=\'$(APPID)\' $(DEFINES) $(INCLUDES) -palmos3.5
|
||||
CFLAGS = -O2 -g -Wall -DAPPID=\'$(APPID)\' $(DEFINES) $(INCLUDES)
|
||||
|
||||
|
||||
# In the non-debug mode (for which DONT_OMIT is undefined) build without
|
||||
# the frame pointer.
|
||||
ifneq ($(DONT_OMIT), true)
|
||||
CSFLAGS += -fomit-frame-pointer
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
include ../common/config.mk
|
||||
|
||||
|
||||
OBJS = $(PLATFORM)/palmmain.o \
|
||||
$(PLATFORM)/palmsavg.o \
|
||||
$(PLATFORM)/gameutil.o \
|
||||
$(PLATFORM)/newgame.o \
|
||||
$(PLATFORM)/palmdict.o \
|
||||
$(PLATFORM)/palmdraw.o \
|
||||
$(PLATFORM)/palmutil.o \
|
||||
$(PLATFORM)/dictui.o \
|
||||
$(PLATFORM)/dictlist.o \
|
||||
$(PLATFORM)/palmir.o \
|
||||
$(PLATFORM)/prefsdlg.o \
|
||||
$(PLATFORM)/connsdlg.o \
|
||||
$(COMMONOBJ)
|
||||
|
||||
include ../common/rules.mk
|
||||
|
||||
$(TARGET): $(PLATFORM)/objs.prc $(PLATFORM)/res.prc
|
||||
$(PAR) -c -a 'resource|backup' $@ $(NAME) $(TYPE) $(APPID) $^
|
||||
if [ x$(shell echo $$XW_UPLOAD_DIR) != x ]; then \
|
||||
zip -j xw4.zip $@; \
|
||||
mv xw4.zip $(shell echo $$XW_UPLOAD_DIR); \
|
||||
cp $@ $(shell echo $$XW_UPLOAD_DIR); \
|
||||
fi
|
||||
|
||||
solo:
|
||||
$(MAKE) XWFEATURE_STANDALONE_ONLY=1
|
||||
|
||||
debug:
|
||||
$(MAKE) MYDEFINES="$(MYDEFINES) -DDEBUG" DONT_OMIT=true
|
||||
|
||||
memdebug:
|
||||
$(MAKE) MYDEFINES="$(MYDEFINES) -DDEBUG -DMEM_DEBUG" DONT_OMIT=true
|
||||
|
||||
gremlins:
|
||||
$(MAKE) MYDEFINES="$(MYDEFINES) -DDEBUG -DMEM_DEBUG -DFOR_GREMLINS" DONT_OMIT=true
|
||||
|
||||
#
|
||||
REL=405
|
||||
REL_PATH=public_html/xwords/4.0.5
|
||||
ship-all:
|
||||
make clean; make; \
|
||||
make; (cd xwconfig && make); \
|
||||
for l in fr_FR en_US es_ES es_CT sv_SE de_DE ; do \
|
||||
make clean; \
|
||||
make LANG=$$l; \
|
||||
zip -j xw$(REL)_$$l.zip xwconfig/xwconfig.prc $(TARGET); \
|
||||
done
|
||||
|
||||
.S.o:
|
||||
$(CC) $(TARGETFLAGS) -c $<
|
||||
|
||||
.c.s:
|
||||
$(CC) $(CSFLAGS) $<
|
||||
|
||||
$(BITMAPS)/%.pbitm: $(BITMAPS)/%.bmp
|
||||
bmtoa $< > $@
|
||||
|
||||
$(PLATFORM)/objs.prc: LocalizedStrIncludes.h $(OBJS) gdbload
|
||||
@rm -f *.grc *.bin
|
||||
$(MULTILINK) $(MULTILINK_OPTIONS) $(OBJS)
|
||||
$(PAR) -c -a resource $(PLATFORM)/objs.prc Code rsrc rsrc *.grc
|
||||
@rm -f *.grc *.bin
|
||||
|
||||
$(PLATFORM)/res.prc: xwords4.rcp $(HEADERS) $(CODESEG) StrL03e8.bin $(FNAVS)
|
||||
$(PILRC) $< >/dev/null
|
||||
$(PAR) -c -a 'resource' $@ Rsrc rsrc rsrc *.bin
|
||||
rm -f $< *.bin
|
||||
|
||||
xwords4.rcp: l10n/xwords4_$(LANG).rcp.pre xwords4defines.h $(BITMAP_RSRCS)
|
||||
gcc -x c -E -P $(INCLUDES) $(MYDEFINES) \
|
||||
-DICONTEXT=\"$(ICONTEXT)\" $< > $@
|
||||
|
||||
LocalizedStrIncludes.h StrL03e8.bin: ./l10n/StrRes_$(LANG).pre ./l10n/mkstrsres.c
|
||||
gcc $(CFLAGS) $(FORMATDEFINES) \
|
||||
-DLANGSTRFILE=\"$<\" ./l10n/mkstrsres.c \
|
||||
-o mkstrsres
|
||||
./mkstrsres StrL03e8.bin LocalizedStrIncludes.h
|
||||
rm -f mkstrsres
|
||||
|
||||
namehash: namehash.c ownerhash.h
|
||||
fnavgen: fnavgen.c
|
||||
gcc $< -o $@
|
||||
|
||||
$(FNAVS): ./fnavgen
|
||||
./$<
|
||||
|
||||
# GDB seems confused by relative paths these days. So generate the
|
||||
# file rather than trying to keep in in cvs.
|
||||
gdbload:
|
||||
echo "source app.gdb" > $@
|
||||
echo "load-segments" >> $@
|
||||
echo "dir $(shell pwd)" >> $@
|
||||
echo "dir $(shell pwd)/../common" >> $@
|
||||
|
||||
clean:
|
||||
cd ../common && $(MAKE) PLATFORM=$(PLATFORM) $@
|
||||
rm -rf $(PLATFORM)/*.[oa] xwords4 *.bin *.stamp *.[pg]rc \
|
||||
xwords4.rcp *.btxt $(PLATFORM)/* $(CODESEG) \
|
||||
LocalizedStrIncludes.h gdbload
|
||||
|
||||
#cmod03E8.bin: palmdraw.c Makefile
|
||||
# $(CC) -O2 -nostartfiles $(INCLUDES) $(MYDEFINES) -o tmp $<
|
||||
# $(OBJRES) tmp
|
||||
# mv code0001.tmp.grc $@ ; rm *.tmp.grc
|
||||
|
||||
help:
|
||||
@echo make memdebug OR
|
||||
@echo make LANG=en_US OR
|
||||
@echo make ship-all OR
|
||||
@echo make gremlins OR
|
||||
@echo make clean
|
21
palm/callback.h
Normal file
21
palm/callback.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* copied from _Palm Programming_ p. 79*/
|
||||
|
||||
#ifndef __CALLBACK__
|
||||
#define __CALLBACK__
|
||||
|
||||
#ifdef MW_COMPILER
|
||||
/* these are no-ops for MW as I understand it */
|
||||
# define CALLBACK_PROLOGUE()
|
||||
# define CALLBACK_EPILOGUE()
|
||||
#else
|
||||
|
||||
register void *reg_a4 asm("%a4");
|
||||
|
||||
#define CALLBACK_PROLOGUE() \
|
||||
{ void* __save_a4 = reg_a4; asm("move.l %%a5,%%a4; sub.l #edata,%%a4" : :);
|
||||
|
||||
#define CALLBACK_EPILOGUE() reg_a4 = __save_a4;}
|
||||
|
||||
#endif /* MW_COMPILER */
|
||||
|
||||
#endif
|
320
palm/connsdlg.c
Normal file
320
palm/connsdlg.c
Normal file
|
@ -0,0 +1,320 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2003 by Eric House (fixin@peak.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.
|
||||
*/
|
||||
|
||||
#ifdef BEYOND_IR
|
||||
|
||||
#include <NetMgr.h>
|
||||
|
||||
#include "callback.h"
|
||||
|
||||
#include "connsdlg.h"
|
||||
#include "palmmain.h"
|
||||
#include "palmutil.h"
|
||||
#include "palmir.h"
|
||||
|
||||
/* When user pops up via Host gadget, we want to get the port to listen on.
|
||||
* When pops up via the Guest gadget, we want to get the port and IP address
|
||||
* of the host AS WELL AS the local port that we'll tell it we're listening
|
||||
* on. We need local state for both, since user can switch between them and
|
||||
* expect state to live as long as the parent dialog isn't exited.
|
||||
*/
|
||||
|
||||
typedef struct ConnsDlgState {
|
||||
ListPtr connTypesList;
|
||||
XP_U16 serverRole;
|
||||
XP_Bool isNewGame;
|
||||
ConnDlgAddrs* addrState;
|
||||
XP_UCHAR localIPStr[16];
|
||||
} ConnsDlgState;
|
||||
|
||||
static void
|
||||
fieldFromStr( XP_U16 id, XP_UCHAR* buf, XP_Bool editable )
|
||||
{
|
||||
FieldPtr field = getActiveObjectPtr( id );
|
||||
UInt16 len = FldGetTextLength( field );
|
||||
FldSetSelection( field, 0, len );
|
||||
FldInsert( field, buf, XP_STRLEN(buf) );
|
||||
setFieldEditable( field, editable );
|
||||
} /* fieldFromStr */
|
||||
|
||||
static void
|
||||
strFromField( XP_U16 id, XP_UCHAR* buf, XP_U16 max )
|
||||
{
|
||||
FieldPtr field = getActiveObjectPtr( id );
|
||||
XP_UCHAR* str = FldGetTextPtr( field );
|
||||
XP_U16 len = FldGetTextLength( field );
|
||||
if ( len > max-1 ) {
|
||||
len = max - 1;
|
||||
}
|
||||
XP_MEMCPY( buf, str, len );
|
||||
buf[len] = '\0';
|
||||
} /* strFromField */
|
||||
|
||||
#if 0
|
||||
static void
|
||||
stateFromGlobals( PalmAppGlobals* globals, ConnsDlgState* state )
|
||||
{
|
||||
comms_getAddr( globals->game.comms, &state->targetAddr,
|
||||
&state->myPort );
|
||||
|
||||
state->isNewGame = globals->isNewGame;
|
||||
} /* stateFromGlobals */
|
||||
|
||||
static void
|
||||
globalsFromState( PalmAppGlobals* globals, ConnsDlgState* state )
|
||||
{
|
||||
comms_setAddr( globals->game.comms, &state->targetAddr,
|
||||
state->myPort );
|
||||
} /* globalsFromState */
|
||||
#endif
|
||||
|
||||
static void
|
||||
ctlsFromState( PalmAppGlobals* globals, FormPtr form, ConnsDlgState* state )
|
||||
{
|
||||
XP_Bool isNewGame = state->isNewGame;
|
||||
XP_UCHAR buf[16];
|
||||
ConnDlgAddrs* addrState = state->addrState;
|
||||
|
||||
NetLibAddrINToA( globals->nlStuff.netLibRef,
|
||||
addrState->remoteIP, buf );
|
||||
fieldFromStr( XW_CONNS_TARGET_FIELD_ID, buf, isNewGame );
|
||||
|
||||
StrPrintF( buf, "%d", addrState->remotePort );
|
||||
fieldFromStr( XW_CONNS_TPORT_FIELD_ID, buf, isNewGame );
|
||||
|
||||
StrPrintF( buf, "%d", addrState->localPort );
|
||||
fieldFromStr( XW_CONNS_MYPORT_FIELD_ID, buf, isNewGame );
|
||||
|
||||
fieldFromStr( XW_CONNS_HOSTIP_FIELD_ID, state->localIPStr, XP_FALSE );
|
||||
} /* ctlsFromState */
|
||||
|
||||
static XP_Bool
|
||||
stateFromCtls( PalmAppGlobals* globals, ConnsDlgState* state )
|
||||
{
|
||||
XP_Bool ok = XP_TRUE;
|
||||
XP_UCHAR buf[16];
|
||||
XP_U32 tmpAddr;
|
||||
ConnDlgAddrs* addrState = state->addrState;
|
||||
XP_Bool rejectBadIP = addrState->conType == COMMS_CONN_IP;
|
||||
|
||||
strFromField( XW_CONNS_TARGET_FIELD_ID, buf, sizeof(buf) );
|
||||
tmpAddr = NetLibAddrAToIN( globals->nlStuff.netLibRef, buf );
|
||||
if ( tmpAddr != -1L ) {
|
||||
addrState->remoteIP = tmpAddr;
|
||||
} else if ( rejectBadIP ) {
|
||||
NetLibAddrINToA( globals->nlStuff.netLibRef, addrState->remoteIP,
|
||||
buf );
|
||||
fieldFromStr( XW_CONNS_TARGET_FIELD_ID, buf, state->isNewGame );
|
||||
ok = XP_FALSE;
|
||||
}
|
||||
|
||||
strFromField( XW_CONNS_TPORT_FIELD_ID, buf, sizeof(buf) );
|
||||
addrState->remotePort = StrAToI( buf );
|
||||
|
||||
strFromField( XW_CONNS_MYPORT_FIELD_ID, buf, sizeof(buf) );
|
||||
addrState->localPort = StrAToI( buf );
|
||||
|
||||
return ok;
|
||||
} /* stateFromCtls */
|
||||
|
||||
/* Adjust the set of visible form controls based on state. There are two
|
||||
* variables here: whether we're showing for a Host or a Guest, and whether
|
||||
* the connection method is IR or IP. Currently IR means no controls needed,
|
||||
* either way. IP means on set if launched from host button, another if
|
||||
* launched from Guest.
|
||||
*/
|
||||
static void
|
||||
updateFormCtls( FormPtr form, ConnsDlgState* state )
|
||||
{
|
||||
const XP_U16 ipCtlsBoth[] = {
|
||||
XW_CONNS_MYPORT_LABEL_ID,
|
||||
XW_CONNS_MYPORT_FIELD_ID,
|
||||
XW_CONNS_HOSTIP_LABEL_ID,
|
||||
XW_CONNS_HOSTIP_FIELD_ID,
|
||||
0
|
||||
};
|
||||
const XP_U16 ipCtlsGuest[] = {
|
||||
XW_CONNS_TARGET_LABEL_ID,
|
||||
XW_CONNS_TARGET_FIELD_ID,
|
||||
XW_CONNS_TPORT_LABEL_ID,
|
||||
XW_CONNS_TPORT_FIELD_ID,
|
||||
0
|
||||
};
|
||||
|
||||
if ( state->addrState->conType == COMMS_CONN_IR ) {
|
||||
disOrEnableSet( form, ipCtlsBoth, XP_FALSE );
|
||||
disOrEnableSet( form, ipCtlsGuest, XP_FALSE );
|
||||
} else {
|
||||
disOrEnableSet( form, ipCtlsBoth, XP_TRUE );
|
||||
disOrEnableSet( form, ipCtlsGuest,
|
||||
state->serverRole == SERVER_ISCLIENT );
|
||||
setFieldEditable( getActiveObjectPtr(XW_CONNS_HOSTIP_FIELD_ID),
|
||||
XP_FALSE );
|
||||
}
|
||||
|
||||
} /* updateFormCtls */
|
||||
|
||||
static void
|
||||
cleanupExit( PalmAppGlobals* globals )
|
||||
{
|
||||
XP_FREE( globals->mpool, globals->connState );
|
||||
globals->connState = NULL;
|
||||
FrmReturnToForm( 0 );
|
||||
} /* cleanupExit */
|
||||
|
||||
static XP_U32
|
||||
figureLocalIP( PalmAppGlobals* globals, XP_UCHAR* buf )
|
||||
{
|
||||
Err err;
|
||||
XP_U32 ipAddr = 0L;
|
||||
XP_U16 netLibRef = globals->nlStuff.netLibRef;
|
||||
XP_U16 index;
|
||||
|
||||
for ( index = 0; ; ++index ) {
|
||||
UInt32 creator;
|
||||
UInt16 instance;
|
||||
err = NetLibIFGet( netLibRef, index,
|
||||
&creator, &instance );
|
||||
|
||||
/* Docs say to iterate until get netErrInvalidInterface, but I'm
|
||||
never getting that, getting netErrInterfaceNotFound instead */
|
||||
if ( (err == netErrInvalidInterface) ||
|
||||
(err == netErrInterfaceNotFound) ) {
|
||||
break; /* we're done */
|
||||
} else if ( err == errNone ) {
|
||||
XP_U8 up;
|
||||
UInt16 siz = sizeof(up);
|
||||
err = NetLibIFSettingGet( netLibRef, creator, instance,
|
||||
netIFSettingUp, &up, &siz );
|
||||
if ( (err == errNone) && (up != 0) ) {
|
||||
|
||||
siz = sizeof(ipAddr);
|
||||
/* use this interface?? */
|
||||
err = NetLibIFSettingGet( netLibRef, creator, instance,
|
||||
netIFSettingReqIPAddr,
|
||||
&ipAddr, &siz );
|
||||
XP_ASSERT( siz == 4 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !!buf ) {
|
||||
NetLibAddrINToA( globals->nlStuff.netLibRef, ipAddr, buf );
|
||||
XP_LOGF( "got local addr: %s", buf );
|
||||
}
|
||||
return ipAddr;
|
||||
} /* figureLocalIP */
|
||||
|
||||
Boolean
|
||||
ConnsFormHandleEvent( EventPtr event )
|
||||
{
|
||||
Boolean result;
|
||||
PalmAppGlobals* globals;
|
||||
ConnsDlgState* state;
|
||||
FormPtr form;
|
||||
XP_S16 chosen;
|
||||
|
||||
CALLBACK_PROLOGUE();
|
||||
|
||||
globals = getFormRefcon();
|
||||
state = globals->connState;
|
||||
if ( !state ) {
|
||||
state = globals->connState = XP_MALLOC( globals->mpool,
|
||||
sizeof(*state) );
|
||||
XP_MEMSET( state, 0, sizeof(*state) );
|
||||
}
|
||||
|
||||
form = FrmGetActiveForm();
|
||||
|
||||
switch ( event->eType ) {
|
||||
case frmOpenEvent:
|
||||
|
||||
if ( !openNetLibIfNot( globals ) ) {
|
||||
beep();
|
||||
cleanupExit( globals );
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
state->serverRole =
|
||||
(Connectedness)globals->dlgParams[CONNS_PARAM_ROLE_INDEX];
|
||||
state->addrState =
|
||||
(ConnDlgAddrs*)globals->dlgParams[CONNS_PARAM_ADDR_INDEX];
|
||||
state->isNewGame = globals->isNewGame;
|
||||
(void)figureLocalIP( globals, state->localIPStr );
|
||||
|
||||
/* setup connection popup */
|
||||
state->connTypesList = getActiveObjectPtr( XW_CONNS_TYPE_LIST_ID );
|
||||
XP_ASSERT( state->addrState->conType == COMMS_CONN_IR
|
||||
|| state->addrState->conType == COMMS_CONN_IP );
|
||||
setSelectorFromList( XW_CONNS_TYPE_TRIGGER_ID, state->connTypesList,
|
||||
state->addrState->conType == COMMS_CONN_IR? 0:1 );
|
||||
|
||||
ctlsFromState( globals, form, state );
|
||||
|
||||
updateFormCtls( form, state );
|
||||
|
||||
case frmUpdateEvent:
|
||||
FrmDrawForm( form );
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case ctlSelectEvent:
|
||||
result = true;
|
||||
switch ( event->data.ctlSelect.controlID ) {
|
||||
|
||||
case XW_CONNS_TYPE_TRIGGER_ID:
|
||||
if ( state->isNewGame ) {
|
||||
chosen = LstPopupList( state->connTypesList );
|
||||
if ( chosen >= 0 ) {
|
||||
setSelectorFromList( XW_CONNS_TYPE_TRIGGER_ID,
|
||||
state->connTypesList, chosen );
|
||||
state->addrState->conType =
|
||||
chosen == 0? COMMS_CONN_IR : COMMS_CONN_IP;
|
||||
updateFormCtls( form, state );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XW_CONNS_OK_BUTTON_ID:
|
||||
if ( !state->isNewGame ) {
|
||||
/* do nothing; same as cancel */
|
||||
} else if ( !stateFromCtls( globals, state ) ) {
|
||||
beep();
|
||||
break;
|
||||
} else {
|
||||
EventType eventToPost;
|
||||
eventToPost.eType = connsSettingChgEvent;
|
||||
EvtAddEventToQueue( &eventToPost );
|
||||
}
|
||||
|
||||
case XW_CONNS_CANCEL_BUTTON_ID:
|
||||
cleanupExit( globals );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
|
||||
CALLBACK_EPILOGUE();
|
||||
return result;
|
||||
} /* ConnsFormHandleEvent */
|
||||
|
||||
#endif /* BEYOND_IR */
|
37
palm/connsdlg.h
Normal file
37
palm/connsdlg.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2003 by Eric House (fixin@peak.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 _CONNSDLG_H_
|
||||
#define _CONNSDLG_H_
|
||||
|
||||
#include <Event.h>
|
||||
|
||||
|
||||
Boolean ConnsFormHandleEvent( EventPtr event );
|
||||
|
||||
#define CONNS_PARAM_ROLE_INDEX 0
|
||||
#define CONNS_PARAM_ADDR_INDEX 1
|
||||
|
||||
#define PopupConnsForm( g, h, addrP ) { \
|
||||
(g)->dlgParams[CONNS_PARAM_ROLE_INDEX] = (XP_U32)(h); \
|
||||
(g)->dlgParams[CONNS_PARAM_ADDR_INDEX] = (XP_U32)(addrP); \
|
||||
FrmPopupForm( XW_CONNS_FORM ); \
|
||||
}
|
||||
|
||||
#endif
|
346
palm/dictlist.c
Normal file
346
palm/dictlist.c
Normal file
|
@ -0,0 +1,346 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright 1999 - 2003 by Eric House (fixin@peak.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.
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include <PalmTypes.h>
|
||||
#include <Form.h>
|
||||
#include <VFSMgr.h>
|
||||
#include <FeatureMgr.h>
|
||||
|
||||
#include "callback.h"
|
||||
#include "dictlist.h"
|
||||
#include "palmmain.h"
|
||||
#include "palmutil.h"
|
||||
#include "palmdict.h"
|
||||
#include "strutils.h"
|
||||
#include "xwords4defines.h"
|
||||
|
||||
#define TYPE_DAWG 'DAWG'
|
||||
#define TYPE_XWR3 'Xwr3'
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// typedef and #defines
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PalmDictList {
|
||||
XP_U16 nDicts;
|
||||
DictListEntry dictArray[1];
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Prototypes
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
XP_Bool
|
||||
getNthDict( const PalmDictList* dl, short n, DictListEntry** dle )
|
||||
{
|
||||
XP_Bool exists = !!dl && (dl->nDicts > n);
|
||||
if ( exists ) {
|
||||
*dle = (DictListEntry*)&dl->dictArray[n];
|
||||
}
|
||||
return exists;
|
||||
} /* getNthDict */
|
||||
|
||||
XP_Bool
|
||||
getDictWithName( const PalmDictList* dl, XP_UCHAR* name,
|
||||
DictListEntry** dlep )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
|
||||
if ( !!dl ) {
|
||||
XP_U16 i;
|
||||
XP_UCHAR* extName;
|
||||
XP_UCHAR oldChName = '\0'; /* shut compiler up */
|
||||
DictListEntry* dle = (DictListEntry*)dl->dictArray;
|
||||
|
||||
extName = (XP_UCHAR*)StrStr((const char*)name,
|
||||
(const char*)".pdb" );
|
||||
|
||||
if ( !!extName ) {
|
||||
oldChName = *extName;
|
||||
*extName = '\0';
|
||||
}
|
||||
|
||||
for ( i = 0; !result && i < dl->nDicts; ++i ) {
|
||||
XP_UCHAR* extCand;
|
||||
XP_UCHAR oldChCand = '\0';
|
||||
|
||||
extCand = (XP_UCHAR*)StrStr((const char*)dle->baseName, ".pdb" );
|
||||
if ( !!extCand ) {
|
||||
oldChCand = *extCand;
|
||||
*extCand = '\0';
|
||||
}
|
||||
|
||||
if ( 0 == XP_STRCMP( (const char*)name,
|
||||
(const char*)dle->baseName ) ) {
|
||||
|
||||
*dlep = dle;
|
||||
result = XP_TRUE;
|
||||
}
|
||||
|
||||
if ( !!extCand ) {
|
||||
*extCand = oldChCand;
|
||||
}
|
||||
|
||||
++dle;
|
||||
}
|
||||
|
||||
if ( !!extName ) {
|
||||
*extName = oldChName;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
} /* getDictWithName */
|
||||
|
||||
void
|
||||
cacheDictForName( PalmDictList* dl, XP_UCHAR* dictName,
|
||||
DictionaryCtxt* dict )
|
||||
{
|
||||
DictListEntry* dle;
|
||||
(void)getDictWithName(dl, dictName, &dle );
|
||||
XP_ASSERT( getDictWithName(dl, dictName, &dle ) );
|
||||
XP_ASSERT( !dle->dict );
|
||||
|
||||
dle->dict = dict;
|
||||
} /* cacheDictForName */
|
||||
|
||||
void
|
||||
removeFromDictCache( PalmDictList* dl, XP_UCHAR* dictName,
|
||||
DictionaryCtxt* dict )
|
||||
{
|
||||
DictListEntry* dle;
|
||||
(void)getDictWithName( dl, dictName, &dle );
|
||||
XP_ASSERT( getDictWithName( dl, dictName, &dle ) );
|
||||
XP_ASSERT( !!dle->dict );
|
||||
XP_ASSERT( dle->dict == dict );
|
||||
|
||||
dle->dict = NULL;
|
||||
} /* removeFromDictCache */
|
||||
|
||||
static void
|
||||
addEntry( MPFORMAL PalmDictList** dlp, DictListEntry* dle )
|
||||
{
|
||||
PalmDictList* dl = *dlp;
|
||||
DictListEntry* ignore;
|
||||
|
||||
if ( !dl ) {
|
||||
dl = (PalmDictList*)XP_MALLOC( mpool, sizeof(*dl) );
|
||||
XP_MEMSET( dl, 0, sizeof(*dl) );
|
||||
}
|
||||
|
||||
if ( !getDictWithName( dl, dle->baseName, &ignore ) ) {
|
||||
XP_U16 size = sizeof(*dl);
|
||||
size += dl->nDicts * sizeof( dl->dictArray[0] );
|
||||
|
||||
dl = (PalmDictList*)XP_REALLOC( mpool, (XP_U8*)dl, size );
|
||||
|
||||
dle->dict = NULL;
|
||||
XP_MEMCPY( &dl->dictArray[dl->nDicts++], dle,
|
||||
sizeof( dl->dictArray[0] ) );
|
||||
}
|
||||
|
||||
*dlp = dl;
|
||||
} /* addEntry */
|
||||
|
||||
static void
|
||||
searchDir( MPFORMAL PalmDictList** dlp, UInt16 volNum, unsigned char separator,
|
||||
unsigned char* path, XP_U16 pathSize )
|
||||
{
|
||||
Err err;
|
||||
FileRef dirRef;
|
||||
XP_U16 pathLen = XP_STRLEN( (const char*)path );
|
||||
|
||||
err = VFSFileOpen( volNum, (const char*)path, vfsModeRead, &dirRef );
|
||||
if ( err == errNone ) {
|
||||
UInt32 dEnum = vfsIteratorStart;
|
||||
FileInfoType fit;
|
||||
|
||||
fit.nameP = (char*)path + pathLen;
|
||||
|
||||
while ( dEnum != vfsIteratorStop ) {
|
||||
XP_UCHAR* ext;
|
||||
fit.nameBufLen = pathSize - pathLen;
|
||||
err = VFSDirEntryEnumerate( dirRef, &dEnum, &fit );
|
||||
|
||||
if ( err != errNone ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (fit.attributes & vfsFileAttrDirectory) != 0 ) {
|
||||
XP_U16 len = XP_STRLEN((const char*)path);
|
||||
path[len] = separator;
|
||||
path[len+1] = '\0';
|
||||
searchDir( MPPARM(mpool) dlp, volNum, separator,
|
||||
path, pathSize );
|
||||
} else if ( (ext = (XP_UCHAR*)StrStr( (const char*)path, ".pdb" ))
|
||||
!= NULL ) {
|
||||
|
||||
/* find out if it's a crosswords dict. */
|
||||
FileRef fileRef;
|
||||
UInt32 type, creator;
|
||||
|
||||
err = VFSFileOpen( volNum, (const char*)path, vfsModeRead,
|
||||
&fileRef );
|
||||
if ( err == errNone ) {
|
||||
err = VFSFileDBInfo( fileRef, NULL, /* name */
|
||||
NULL, /* attributes */
|
||||
NULL, /* versionP */
|
||||
NULL, /* crDateP */
|
||||
NULL, NULL, /*UInt32 *modDateP, UInt32 *bckUpDateP,*/
|
||||
NULL, NULL, /*UInt32 *modNumP, MemHandle *appInfoHP,*/
|
||||
NULL, /*MemHandle *sortInfoHP, */
|
||||
&type, &creator,
|
||||
NULL ); /* nRecords */
|
||||
VFSFileClose( fileRef );
|
||||
|
||||
if ( (err == errNone) && (type == TYPE_DAWG) &&
|
||||
(creator == TYPE_XWR3) ) {
|
||||
DictListEntry dl;
|
||||
|
||||
dl.path = copyString( MPPARM(mpool) path );
|
||||
dl.location = DL_VFS;
|
||||
dl.u.vfsData.volNum = volNum;
|
||||
dl.baseName = dl.path + pathLen;
|
||||
|
||||
addEntry( MPPARM(mpool) dlp, &dl );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path[pathLen] = '\0';
|
||||
VFSFileClose( dirRef );
|
||||
}
|
||||
|
||||
} /* searchDir */
|
||||
|
||||
static void
|
||||
tryVFSSearch( MPFORMAL PalmDictList** dlp )
|
||||
{
|
||||
Err err;
|
||||
UInt16 volNum;
|
||||
UInt32 vEnum;
|
||||
|
||||
vEnum = vfsIteratorStart;
|
||||
while ( vEnum != vfsIteratorStop ) {
|
||||
unsigned char pathStr[265];
|
||||
UInt16 bufLen;
|
||||
|
||||
err = VFSVolumeEnumerate( &volNum, &vEnum );
|
||||
if ( err != errNone ) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufLen = sizeof(pathStr);
|
||||
err = VFSGetDefaultDirectory( volNum, ".pdb", (char*)pathStr,
|
||||
&bufLen );
|
||||
|
||||
if ( err == errNone ) {
|
||||
pathStr[1] = '\0';
|
||||
searchDir( MPPARM(mpool) dlp, volNum, pathStr[0],
|
||||
pathStr, sizeof(pathStr) );
|
||||
}
|
||||
}
|
||||
|
||||
} /* tryVFSSearch */
|
||||
|
||||
/* if we've allocated extra space in the array as an optimization now's when
|
||||
* we pull back */
|
||||
static void
|
||||
cleanList( PalmDictList** dl )
|
||||
{
|
||||
} /* cleanList */
|
||||
|
||||
PalmDictList*
|
||||
DictListMake( MPFORMAL_NOCOMMA )
|
||||
{
|
||||
Err err;
|
||||
DmSearchStateType stateType;
|
||||
UInt32 vers;
|
||||
PalmDictList* dl = NULL;
|
||||
UInt16 cardNo;
|
||||
LocalID dbID;
|
||||
Boolean newSearch = true;
|
||||
XP_Bool found = false;
|
||||
|
||||
/* first the DM case */
|
||||
while ( !found ) {
|
||||
err = DmGetNextDatabaseByTypeCreator( newSearch, &stateType, TYPE_DAWG,
|
||||
TYPE_XWR3/* APPID */,
|
||||
false,// onlyLatestVers,
|
||||
&cardNo, &dbID );
|
||||
if ( err != 0 ) {
|
||||
break;
|
||||
} else {
|
||||
XP_UCHAR nameBuf[33];
|
||||
XP_U16 nameLen;
|
||||
DictListEntry dle;
|
||||
|
||||
err = DmDatabaseInfo( cardNo, dbID, (char*)nameBuf, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
||||
nameLen = XP_STRLEN( (const char*)nameBuf ) + 1;
|
||||
|
||||
dle.location = DL_STORAGE;
|
||||
dle.u.dmData.cardNo = cardNo;
|
||||
dle.u.dmData.dbID = dbID;
|
||||
dle.path = dle.baseName = XP_MALLOC( mpool, nameLen );
|
||||
XP_MEMCPY( dle.path, nameBuf, nameLen );
|
||||
|
||||
addEntry( MPPARM(mpool) &dl, &dle );
|
||||
}
|
||||
|
||||
newSearch = false;
|
||||
}
|
||||
|
||||
/* then the VFS case */
|
||||
err = FtrGet( sysFileCVFSMgr, vfsFtrIDVersion, &vers );
|
||||
if ( err == errNone ) {
|
||||
tryVFSSearch( MPPARM(mpool) &dl );
|
||||
}
|
||||
|
||||
cleanList( &dl );
|
||||
|
||||
return dl;
|
||||
} /* DictListMake */
|
||||
|
||||
void
|
||||
DictListFree( MPFORMAL PalmDictList* dl )
|
||||
{
|
||||
if ( !!dl ) {
|
||||
DictListEntry* dle = dl->dictArray;
|
||||
XP_U16 i;
|
||||
|
||||
for ( i = 0; i < dl->nDicts; ++i, ++dle ) {
|
||||
XP_FREE( mpool, dle->path );
|
||||
}
|
||||
|
||||
XP_FREE( mpool, dl );
|
||||
}
|
||||
} /* dictListFree */
|
||||
|
||||
XP_U16
|
||||
DictListCount( PalmDictList* dl )
|
||||
{
|
||||
if ( !dl ) {
|
||||
return 0;
|
||||
} else {
|
||||
return dl->nDicts;
|
||||
}
|
||||
} /* dictListCount */
|
56
palm/dictlist.h
Normal file
56
palm/dictlist.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1999 - 2001 by Eric House (fixin@peak.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 _DICTLIST_H_
|
||||
#define _DICTLIST_H_
|
||||
|
||||
#include "palmmain.h"
|
||||
#include "palmdict.h"
|
||||
|
||||
enum { DL_STORAGE, DL_VFS };
|
||||
|
||||
typedef struct DictListEntry {
|
||||
XP_UCHAR* path;
|
||||
XP_UCHAR* baseName; /* points into, or ==, path */
|
||||
DictionaryCtxt* dict; /* cache so can refcount */
|
||||
XP_UCHAR location; /* Storage RAM or VFS */
|
||||
union {
|
||||
struct {
|
||||
UInt16 cardNo;
|
||||
LocalID dbID;
|
||||
} dmData;
|
||||
struct {
|
||||
UInt16 volNum;
|
||||
} vfsData;
|
||||
} u;
|
||||
} DictListEntry;
|
||||
|
||||
PalmDictList* DictListMake( MPFORMAL_NOCOMMA );
|
||||
void DictListFree( MPFORMAL PalmDictList* dl );
|
||||
XP_U16 DictListCount( PalmDictList* dl );
|
||||
|
||||
XP_Bool getDictWithName( const PalmDictList* dl, unsigned char* name,
|
||||
DictListEntry** dle );
|
||||
void cacheDictForName( PalmDictList* dl, XP_UCHAR* dictName,
|
||||
DictionaryCtxt* ctxt );
|
||||
void removeFromDictCache( PalmDictList* dl, XP_UCHAR* dictName,
|
||||
DictionaryCtxt* dict );
|
||||
|
||||
XP_Bool getNthDict( const PalmDictList* dl, short n, DictListEntry** dle );
|
||||
|
||||
#endif
|
286
palm/dictui.c
Normal file
286
palm/dictui.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright 1999 - 2003 by Eric House (fixin@peak.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.
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include <PalmTypes.h>
|
||||
#include <Form.h>
|
||||
#include <VFSMgr.h>
|
||||
#include <FeatureMgr.h>
|
||||
|
||||
#include "callback.h"
|
||||
#include "dictui.h"
|
||||
#include "palmmain.h"
|
||||
#include "palmutil.h"
|
||||
#include "palmdict.h"
|
||||
#include "dictlist.h"
|
||||
#include "strutils.h"
|
||||
#include "xwords4defines.h"
|
||||
|
||||
#define TYPE_DAWG 'DAWG'
|
||||
#define TYPE_XWR3 'Xwr3'
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Prototypes
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
static XP_U16 populateDictionaryList( MPFORMAL ListData* sLd,
|
||||
XP_UCHAR* curDictName,
|
||||
ListPtr list, Int16 triggerID,
|
||||
PalmDictList* dl );
|
||||
static Boolean beamDict( const PalmDictList* dl, XP_UCHAR* dictName );
|
||||
|
||||
/*****************************************************************************
|
||||
* Handler for dictionary info form.
|
||||
****************************************************************************/
|
||||
#define USE_POPULATE 1
|
||||
Boolean
|
||||
dictFormHandleEvent( EventPtr event )
|
||||
{
|
||||
FormPtr form;
|
||||
Boolean result;
|
||||
Int16 chosen;
|
||||
DictionaryCtxt* dict;
|
||||
PalmAppGlobals* globals;
|
||||
XP_UCHAR* dictName;
|
||||
|
||||
CALLBACK_PROLOGUE();
|
||||
|
||||
result = false;
|
||||
globals = getFormRefcon();
|
||||
|
||||
switch ( event->eType ) {
|
||||
case frmOpenEvent: {
|
||||
XP_UCHAR* curName;
|
||||
XP_U16 width;
|
||||
RectangleType rect;
|
||||
|
||||
form = FrmGetActiveForm();
|
||||
|
||||
/* we're either a beam dlg or a dict picker; disable a button here. */
|
||||
disOrEnable( form,
|
||||
globals->dictuiForBeaming ?
|
||||
XW_DICTINFO_DONE_BUTTON_ID:XW_DICTINFO_BEAM_BUTTON_ID,
|
||||
false );
|
||||
|
||||
/* dictionary list setup */
|
||||
globals->dictState.dictList =
|
||||
getActiveObjectPtr( XW_DICTINFO_LIST_ID );
|
||||
|
||||
dict = !!globals->game.model?
|
||||
model_getDictionary(globals->game.model) : NULL;
|
||||
if ( dict ) {
|
||||
curName = dict_getName( dict );
|
||||
} else {
|
||||
curName = NULL;
|
||||
}
|
||||
width = populateDictionaryList( MPPARM(globals->mpool)
|
||||
&globals->dictState.sLd,
|
||||
curName, globals->dictState.dictList,
|
||||
XW_DICTINFO_TRIGGER_ID,
|
||||
globals->dictList );
|
||||
getObjectBounds( XW_DICTINFO_LIST_ID, &rect );
|
||||
rect.extent.x = width;
|
||||
setObjectBounds( XW_DICTINFO_LIST_ID, &rect );
|
||||
|
||||
FrmDrawForm( form );
|
||||
break;
|
||||
}
|
||||
|
||||
case ctlSelectEvent:
|
||||
switch ( event->data.ctlEnter.controlID ) {
|
||||
|
||||
case XW_DICTINFO_TRIGGER_ID:
|
||||
// don't let change dict except first time
|
||||
if ( globals->dictuiForBeaming || globals->isNewGame ) {
|
||||
chosen = LstPopupList( globals->dictState.dictList );
|
||||
if ( chosen >= 0 ) {
|
||||
setSelectorFromList( XW_DICTINFO_TRIGGER_ID,
|
||||
globals->dictState.dictList,
|
||||
chosen );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
/* case XW_PHONIES_TRIGGER_ID: */
|
||||
/* chosen = LstPopupList( sPhoniesList ); */
|
||||
/* if ( chosen >= 0 ) { */
|
||||
/* setTriggerFromList( XW_PHONIES_TRIGGER_ID, sPhoniesList, */
|
||||
/* chosen ); */
|
||||
/* } */
|
||||
/* result = true; */
|
||||
/* break; */
|
||||
|
||||
case XW_DICTINFO_DONE_BUTTON_ID:
|
||||
case XW_DICTINFO_BEAM_BUTTON_ID:
|
||||
/* discard the const */
|
||||
dictName = (XP_UCHAR*)CtlGetLabel(
|
||||
getActiveObjectPtr( XW_DICTINFO_TRIGGER_ID) );
|
||||
|
||||
if ( globals->dictuiForBeaming ) {
|
||||
if ( !beamDict( globals->dictList, dictName ) ) {
|
||||
break; /* don't cancel dialog yet */
|
||||
}
|
||||
} else {
|
||||
EventType eventToPost;
|
||||
|
||||
XP_ASSERT( dictName != NULL );
|
||||
|
||||
eventToPost.eType = dictSelectedEvent;
|
||||
((DictSelectedData*)&eventToPost.data.generic)->dictName
|
||||
= copyString( MEMPOOL dictName );
|
||||
EvtAddEventToQueue( &eventToPost );
|
||||
}
|
||||
|
||||
case XW_DICTINFO_CANCEL_BUTTON_ID:
|
||||
result = true;
|
||||
freeListData( MPPARM(globals->mpool) &globals->dictState.sLd );
|
||||
FrmReturnToForm( 0 );
|
||||
break;
|
||||
|
||||
} // switch ( event->data.ctlEnter.controlID )
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
|
||||
CALLBACK_EPILOGUE();
|
||||
return result;
|
||||
} /* dictFormHandleEvent */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
****************************************************************************/
|
||||
static XP_U16
|
||||
populateDictionaryList( MPFORMAL ListData* sLd, XP_UCHAR* curDictName,
|
||||
ListPtr list, Int16 triggerID, PalmDictList* dl )
|
||||
{
|
||||
XP_U16 i;
|
||||
XP_U16 maxWidth = 0;
|
||||
XP_U16 nDicts;
|
||||
|
||||
initListData( MPPARM(mpool) sLd, 16 ); /* PENDING: MAX_DICTS or count */
|
||||
nDicts = DictListCount( dl );
|
||||
|
||||
for ( i = 0; i < nDicts; ++i ) {
|
||||
DictListEntry* dle;
|
||||
XP_UCHAR* name;
|
||||
XP_U16 width;
|
||||
|
||||
getNthDict( dl, i, &dle );
|
||||
name = dle->baseName;
|
||||
|
||||
addListTextItem( MPPARM(mpool) sLd, name );
|
||||
width = FntCharsWidth( (const char*)name, XP_STRLEN((const char*)name) );
|
||||
if ( width > maxWidth ) {
|
||||
maxWidth = width;
|
||||
}
|
||||
}
|
||||
|
||||
sortList( sLd );
|
||||
setListSelection( sLd, (char*)curDictName );
|
||||
setListChoices( sLd, list, NULL );
|
||||
|
||||
setSelectorFromList( triggerID, list, LstGetSelection(list) );
|
||||
|
||||
return maxWidth + 3; /* 3: for white space */
|
||||
} /* populateDictionaryList */
|
||||
|
||||
/***********************************************************************
|
||||
* The rest of this file mostly stolen from palmos.com. I've only modified
|
||||
* beamDict
|
||||
************************************************************************/
|
||||
static Err
|
||||
WriteDBData(const void* dataP, UInt32* sizeP, void* userDataP)
|
||||
{
|
||||
Err err;
|
||||
|
||||
/* Try to send as many bytes as were requested by the caller */
|
||||
*sizeP = ExgSend((ExgSocketPtr)userDataP, (void*)dataP, *sizeP, &err);
|
||||
return err;
|
||||
} /* WriteDBData */
|
||||
|
||||
Err
|
||||
sendDatabase( UInt16 cardNo, LocalID dbID, XP_UCHAR* nameP,
|
||||
XP_UCHAR* descriptionP )
|
||||
{
|
||||
ExgSocketType exgSocket;
|
||||
Err err;
|
||||
|
||||
/* Create exgSocket structure */
|
||||
XP_MEMSET( &exgSocket, 0, sizeof(exgSocket) );
|
||||
exgSocket.description = (char*)descriptionP;
|
||||
exgSocket.name = (char*)nameP;
|
||||
|
||||
/* Start an exchange put operation */
|
||||
err = ExgPut(&exgSocket);
|
||||
if ( !err ) {
|
||||
err = ExgDBWrite( WriteDBData, &exgSocket, NULL, dbID, cardNo );
|
||||
/* Disconnect Exg and pass error */
|
||||
err = ExgDisconnect(&exgSocket, err);
|
||||
}
|
||||
return err;
|
||||
} /* sendDatabase */
|
||||
|
||||
static Boolean
|
||||
beamDict( const PalmDictList* dl, XP_UCHAR* dictName )
|
||||
{
|
||||
Err err;
|
||||
UInt16 cardNo;
|
||||
LocalID dbID;
|
||||
Boolean found;
|
||||
XP_Bool shouldDispose = XP_FALSE;
|
||||
DictListEntry* dle;
|
||||
|
||||
found = getDictWithName( dl, dictName, &dle );
|
||||
|
||||
/* Find our app using its internal name */
|
||||
XP_ASSERT( found );
|
||||
|
||||
if ( found ) {
|
||||
if ( dle->location == DL_VFS ) {
|
||||
err = VFSImportDatabaseFromFile( dle->u.vfsData.volNum,
|
||||
(const char*)dle->path,
|
||||
&cardNo, &dbID );
|
||||
if ( err == dmErrAlreadyExists ) {
|
||||
} else if ( err == errNone ) {
|
||||
shouldDispose = XP_TRUE;
|
||||
} else {
|
||||
found = XP_FALSE;
|
||||
}
|
||||
} else {
|
||||
cardNo = dle->u.dmData.cardNo;
|
||||
dbID = dle->u.dmData.dbID;
|
||||
}
|
||||
}
|
||||
|
||||
if ( found ) { /* send it giving external name and description */
|
||||
XP_UCHAR prcName[40];
|
||||
XP_SNPRINTF( prcName, sizeof(prcName), (XP_UCHAR*)"%s.pdb", dictName );
|
||||
err = sendDatabase( cardNo, dbID, prcName, dictName );
|
||||
found = err == 0;
|
||||
|
||||
if ( shouldDispose ) {
|
||||
DmDeleteDatabase( cardNo, dbID );
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
} /* beamDict */
|
||||
|
34
palm/dictui.h
Normal file
34
palm/dictui.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1999 - 2001 by Eric House (fixin@peak.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 _DICTUI_H_
|
||||
#define _DICTUI_H_
|
||||
|
||||
#include "palmmain.h"
|
||||
#include "palmdict.h"
|
||||
|
||||
typedef struct DictSelectedData {
|
||||
MemPtr dictName;
|
||||
} DictSelectedData;
|
||||
|
||||
Boolean dictFormHandleEvent( EventPtr event );
|
||||
|
||||
/* export for beamBoard */
|
||||
Err sendDatabase( UInt16 cardNo, LocalID dbID, XP_UCHAR* nameP,
|
||||
XP_UCHAR* descriptionP );
|
||||
#endif
|
186
palm/fnavgen.c
Normal file
186
palm/fnavgen.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/* -*- mode: c; -*- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "xwords4defines.h"
|
||||
|
||||
typedef struct fnavElem {
|
||||
unsigned short objectID;
|
||||
unsigned short objectFlags;
|
||||
unsigned short objectAbove;
|
||||
unsigned short objectBelow;
|
||||
} fnavElem;
|
||||
|
||||
typedef struct fnavHeader {
|
||||
unsigned short formID; /* not part of resource!!!! */
|
||||
|
||||
unsigned short version; /* always 1 */
|
||||
unsigned short objcount;
|
||||
unsigned short headerSizeInBytes; /* always 20 */
|
||||
unsigned short listSizeInBytes; /* always 8 */
|
||||
unsigned short navflags;
|
||||
unsigned short initialHint;
|
||||
unsigned short jumpToHint;
|
||||
unsigned short bottomLeftHint;
|
||||
} fnavHeader;
|
||||
|
||||
|
||||
fnavHeader gamesHeader = {
|
||||
XW_NEWGAMES_FORM,
|
||||
0, /* fill this in */
|
||||
0, /* fill this in */
|
||||
0, /* fill this in */
|
||||
0, /* fill this in */
|
||||
0x0001, /* force obj focus mode */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
fnavElem gamesElems[] = {
|
||||
{ XW_ROBOT_1_CHECKBOX_ID, 0, 0, XW_ROBOT_2_CHECKBOX_ID },
|
||||
{ XW_ROBOT_2_CHECKBOX_ID, 0, XW_ROBOT_1_CHECKBOX_ID, XW_ROBOT_3_CHECKBOX_ID },
|
||||
{ XW_ROBOT_3_CHECKBOX_ID, 0, XW_ROBOT_2_CHECKBOX_ID, XW_ROBOT_4_CHECKBOX_ID },
|
||||
{ XW_ROBOT_4_CHECKBOX_ID, 0, XW_ROBOT_3_CHECKBOX_ID, XW_SOLO_GADGET_ID },
|
||||
|
||||
{ XW_SOLO_GADGET_ID, 0, XW_ROBOT_4_CHECKBOX_ID, XW_SERVER_GADGET_ID },
|
||||
{ XW_SERVER_GADGET_ID, 0, XW_SOLO_GADGET_ID, XW_CLIENT_GADGET_ID },
|
||||
{ XW_CLIENT_GADGET_ID, 0, XW_SERVER_GADGET_ID, 0 }
|
||||
};
|
||||
|
||||
unsigned short gamesElemsShort[] = {
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
XW_SOLO_GADGET_ID,
|
||||
XW_SERVER_GADGET_ID,
|
||||
XW_CLIENT_GADGET_ID,
|
||||
#endif
|
||||
|
||||
XW_NPLAYERS_SELECTOR_ID,
|
||||
XW_PREFS_BUTTON_ID,
|
||||
|
||||
XW_REMOTE_1_CHECKBOX_ID,
|
||||
XW_PLAYERNAME_1_FIELD_ID,
|
||||
XW_ROBOT_1_CHECKBOX_ID,
|
||||
XW_PLAYERPASSWD_1_TRIGGER_ID,
|
||||
|
||||
XW_REMOTE_2_CHECKBOX_ID,
|
||||
XW_PLAYERNAME_2_FIELD_ID,
|
||||
XW_ROBOT_2_CHECKBOX_ID,
|
||||
XW_PLAYERPASSWD_2_TRIGGER_ID,
|
||||
|
||||
XW_REMOTE_3_CHECKBOX_ID,
|
||||
XW_PLAYERNAME_3_FIELD_ID,
|
||||
XW_ROBOT_3_CHECKBOX_ID,
|
||||
XW_PLAYERPASSWD_3_TRIGGER_ID,
|
||||
|
||||
XW_REMOTE_4_CHECKBOX_ID,
|
||||
XW_PLAYERNAME_4_FIELD_ID,
|
||||
XW_ROBOT_4_CHECKBOX_ID,
|
||||
XW_PLAYERPASSWD_4_TRIGGER_ID,
|
||||
|
||||
XW_DICT_SELECTOR_ID,
|
||||
XW_CANCEL_BUTTON_ID,
|
||||
XW_OK_BUTTON_ID
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
usage( char* name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s outfile\n", name );
|
||||
exit( 1 );
|
||||
} /* */
|
||||
|
||||
static void
|
||||
write_network_short( FILE* fil, unsigned short s )
|
||||
{
|
||||
unsigned short tmp = htons( s );
|
||||
fwrite( &tmp, sizeof(tmp), 1, fil );
|
||||
} /* write_network_short */
|
||||
|
||||
write_fnav( fnavHeader* header, unsigned short* idArray,
|
||||
fnavElem* elems, int count )
|
||||
{
|
||||
char nameBuf[32];
|
||||
FILE* fil;
|
||||
int i;
|
||||
|
||||
assert( !idArray || !elems );
|
||||
|
||||
sprintf( nameBuf, "fnav%.4x.bin", header->formID );
|
||||
fil = fopen( nameBuf, "w" );
|
||||
fprintf( stderr, "created file %s\n", nameBuf );
|
||||
|
||||
write_network_short( fil, 1 );
|
||||
write_network_short( fil, count );
|
||||
write_network_short( fil, 20 );
|
||||
write_network_short( fil, 8 );
|
||||
write_network_short( fil, header->navflags );
|
||||
write_network_short( fil, header->initialHint );
|
||||
write_network_short( fil, header->jumpToHint );
|
||||
write_network_short( fil, header->bottomLeftHint );
|
||||
|
||||
/* Two words of padding. Docs disagree, but Blazer's resources have
|
||||
'em */
|
||||
write_network_short( fil, 0 );
|
||||
write_network_short( fil, 0 );
|
||||
|
||||
if ( !!elems ) {
|
||||
|
||||
for ( i = 0; i < count; ++i ) {
|
||||
write_network_short( fil, elems->objectID );
|
||||
write_network_short( fil, elems->objectFlags );
|
||||
write_network_short( fil, elems->objectAbove );
|
||||
write_network_short( fil, elems->objectBelow );
|
||||
|
||||
++elems;
|
||||
}
|
||||
|
||||
} else {
|
||||
unsigned short prevID = 0;
|
||||
unsigned short id = *idArray++;
|
||||
|
||||
while ( count-- ) {
|
||||
unsigned short nextID;
|
||||
|
||||
if ( count == 0 ) {
|
||||
nextID = 0;
|
||||
} else {
|
||||
nextID = *idArray++;
|
||||
}
|
||||
|
||||
write_network_short( fil, id );
|
||||
write_network_short( fil, 0 );
|
||||
write_network_short( fil, prevID );
|
||||
write_network_short( fil, nextID );
|
||||
|
||||
if ( !nextID ) {
|
||||
break;
|
||||
}
|
||||
|
||||
prevID = id;
|
||||
id = nextID;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fil);
|
||||
} /* write_fnav */
|
||||
|
||||
int
|
||||
main( int argc, char** argv )
|
||||
{
|
||||
int i;
|
||||
char* outFName;
|
||||
|
||||
if ( argc != 1 ) {
|
||||
usage( argv[0] );
|
||||
}
|
||||
|
||||
write_fnav( &gamesHeader, gamesElemsShort, NULL,
|
||||
sizeof(gamesElemsShort)/sizeof(gamesElemsShort[0]) );
|
||||
/* sizeof(gamesElems)/sizeof(gamesElems[0]) ); */
|
||||
|
||||
|
||||
} /* main */
|
208
palm/gameutil.c
Normal file
208
palm/gameutil.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1999 - 2001 by Eric House (fixin@peak.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.
|
||||
*/
|
||||
|
||||
#include <DataMgr.h>
|
||||
#include <TimeMgr.h>
|
||||
|
||||
#include "comtypes.h"
|
||||
#include "comms.h"
|
||||
#include "strutils.h"
|
||||
#include "gameutil.h"
|
||||
#include "xwords4defines.h"
|
||||
#include "xwstream.h"
|
||||
#include "palmmain.h"
|
||||
|
||||
XP_U16
|
||||
countGameRecords( PalmAppGlobals* globals )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
UInt16 numRecs;
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
numRecs = DmNumRecords( dbP );
|
||||
DMCLOSEDATABASE( dbP );
|
||||
return numRecs;
|
||||
}
|
||||
|
||||
#if defined OWNER_HASH || defined NO_REG_REQUIRED
|
||||
void
|
||||
deleteGameRecord( PalmAppGlobals* globals, XP_S16 index )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
DmRemoveRecord( dbP, index );
|
||||
DMCLOSEDATABASE( dbP );
|
||||
} /* deleteGameRecord */
|
||||
|
||||
XP_S16
|
||||
duplicateGameRecord( PalmAppGlobals* globals, XP_S16 fromIndex )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
MemHandle newRecord, curRecord;
|
||||
XP_U16 size;
|
||||
XP_S16 newIndex = fromIndex + 1;
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
XP_ASSERT( fromIndex < countGameRecords(globals) );
|
||||
curRecord = DmQueryRecord( dbP, fromIndex );
|
||||
size = MemHandleSize( curRecord );
|
||||
newRecord = DmNewRecord( dbP, (XP_U16*)&newIndex, size );
|
||||
|
||||
DmWrite( MemHandleLock(newRecord), 0, MemHandleLock(curRecord), size );
|
||||
|
||||
MemHandleUnlock( curRecord );
|
||||
MemHandleUnlock( newRecord );
|
||||
|
||||
DmReleaseRecord( dbP, newIndex, true );
|
||||
|
||||
DMCLOSEDATABASE( dbP );
|
||||
|
||||
return newIndex;
|
||||
} /* duplicateGameRecord */
|
||||
#endif
|
||||
|
||||
void
|
||||
streamToGameRecord( PalmAppGlobals* globals, XWStreamCtxt* stream,
|
||||
XP_S16 index )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
MemHandle handle;
|
||||
MemPtr tmpPtr, ptr;
|
||||
Err err;
|
||||
|
||||
XP_U32 size = stream_getSize( stream );
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
XP_ASSERT( !!dbP );
|
||||
|
||||
if ( index == DmNumRecords(dbP) ) {
|
||||
handle = DmNewRecord( dbP, (XP_U16*)&index, size );
|
||||
} else {
|
||||
XP_ASSERT( index < countGameRecords(globals) );
|
||||
handle = DmGetRecord( dbP, index );
|
||||
MemHandleResize( handle, size );
|
||||
}
|
||||
|
||||
tmpPtr = MemPtrNew(size);
|
||||
stream_getBytes( stream, tmpPtr, size );
|
||||
ptr = MemHandleLock( handle );
|
||||
err = DmWrite( ptr, 0, tmpPtr, size );
|
||||
XP_ASSERT( err == 0 );
|
||||
MemPtrFree( tmpPtr );
|
||||
|
||||
MemHandleUnlock(handle);
|
||||
err = DmReleaseRecord( dbP, index, true );
|
||||
XP_ASSERT( err == 0 );
|
||||
DMCLOSEDATABASE( dbP );
|
||||
} /* streamToGameRecord */
|
||||
|
||||
void
|
||||
writeNameToGameRecord( PalmAppGlobals* globals, XP_S16 index,
|
||||
char* newName, XP_U16 len )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
MemHandle handle;
|
||||
char name[MAX_GAMENAME_LENGTH];
|
||||
|
||||
XP_ASSERT( len == XP_STRLEN(newName) );
|
||||
XP_ASSERT( len > 0 );
|
||||
XP_MEMSET( name, 0, sizeof(name) );
|
||||
if ( len >= MAX_GAMENAME_LENGTH ) {
|
||||
len = MAX_GAMENAME_LENGTH - 1;
|
||||
}
|
||||
XP_MEMCPY( name, newName, len+1 );
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
|
||||
if ( index == DmNumRecords(dbP) ) {
|
||||
handle = DmNewRecord(dbP, (XP_U16*)&index, MAX_GAMENAME_LENGTH);
|
||||
} else {
|
||||
XP_ASSERT( index < DmNumRecords(dbP) );
|
||||
handle = DmGetRecord( dbP, index );
|
||||
}
|
||||
XP_ASSERT( !!handle );
|
||||
DmWrite( MemHandleLock(handle), 0, name, MAX_GAMENAME_LENGTH );
|
||||
MemHandleUnlock( handle );
|
||||
(void)DmReleaseRecord( dbP, index, true );
|
||||
DMCLOSEDATABASE( dbP );
|
||||
} /* writeNameToGameRecord */
|
||||
|
||||
void
|
||||
nameFromRecord( PalmAppGlobals* globals, XP_S16 index, char* buf )
|
||||
{
|
||||
LocalID id;
|
||||
DmOpenRef dbP;
|
||||
MemHandle handle;
|
||||
|
||||
buf[0] = '\0'; /* init to empty string */
|
||||
|
||||
if ( index < countGameRecords(globals) ) {
|
||||
|
||||
id = DMFINDDATABASE( globals, CARD_0, XW_GAMES_DBNAME );
|
||||
if ( id != 0 ) {
|
||||
dbP = DMOPENDATABASE( globals, CARD_0, id, dmModeWrite );
|
||||
if ( dbP != 0 ) {
|
||||
handle = DmQueryRecord( dbP, index );
|
||||
|
||||
XP_MEMCPY( buf, MemHandleLock(handle), MAX_GAMENAME_LENGTH );
|
||||
buf[MAX_GAMENAME_LENGTH-1] = '\0';
|
||||
|
||||
MemHandleUnlock( handle );
|
||||
DMCLOSEDATABASE( dbP );
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* nameFromRecord */
|
||||
|
||||
/*****************************************************************************
|
||||
* Later this will provide a default name based on a timestamp.
|
||||
*****************************************************************************/
|
||||
#ifndef TIME_FORMAT
|
||||
#define TIME_FORMAT tfColonAMPM
|
||||
#endif
|
||||
#ifndef DATE_FORMAT
|
||||
#define DATE_FORMAT dfMDYLongWithComma
|
||||
#endif
|
||||
void
|
||||
makeDefaultGameName( char* buf )
|
||||
{
|
||||
char timeBuf[timeStringLength+1]; /* add 1 to be safe */
|
||||
char dateBuf[longDateStrLength+1];
|
||||
DateTimeType timeType;
|
||||
|
||||
TimSecondsToDateTime( TimGetSeconds(), &timeType );
|
||||
TimeToAscii( timeType.hour, timeType.minute, TIME_FORMAT, timeBuf );
|
||||
|
||||
DateToAscii( timeType.month, timeType.day, timeType.year,
|
||||
DATE_FORMAT, dateBuf );
|
||||
|
||||
StrPrintF( buf, "%s, %s", dateBuf, timeBuf );
|
||||
} /* makeDefaultGameName */
|
||||
|
35
palm/gameutil.h
Normal file
35
palm/gameutil.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1999 - 2001 by Eric House (fixin@peak.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 _GAMEUTIL_H_
|
||||
#define _GAMEUTIL_H_
|
||||
|
||||
#include "comtypes.h"
|
||||
#include "memstream.h"
|
||||
#include "palmmain.h"
|
||||
|
||||
XP_U16 countGameRecords( PalmAppGlobals* globals );
|
||||
void deleteGameRecord( PalmAppGlobals* globals, XP_S16 index );
|
||||
XP_S16 duplicateGameRecord( PalmAppGlobals* globals, XP_S16 fromIndex );
|
||||
void nameFromRecord( PalmAppGlobals* globals, XP_S16 index, char* buf );
|
||||
void streamToGameRecord( PalmAppGlobals* globals, XWStreamCtxt* stream,
|
||||
XP_S16 index );
|
||||
void makeDefaultGameName( char* buf );
|
||||
|
||||
#endif
|
952
palm/newgame.c
Normal file
952
palm/newgame.c
Normal file
|
@ -0,0 +1,952 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1999 - 2001 by Eric House (fixin@peak.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.
|
||||
*/
|
||||
|
||||
#include <PalmTypes.h>
|
||||
#include <Form.h>
|
||||
#include <List.h>
|
||||
#include <Chars.h> /* for nextFieldChr */
|
||||
#include <Graffiti.h> /* for GrfSetState */
|
||||
#include <Event.h>
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
# 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"
|
||||
|
||||
static void handlePasswordTrigger( PalmAppGlobals* globals,
|
||||
UInt16 controlID );
|
||||
static void adjustVisibility( PalmAppGlobals* globals, XP_Bool canDraw );
|
||||
static void setNPlayersAndAdjust( PalmAppGlobals* globals, Int16 chosen );
|
||||
static void updatePlayerInfo( PalmAppGlobals* globals );
|
||||
static XP_Bool tryFieldNavigationKey( XP_U16 key );
|
||||
static void loadNewGameState( PalmAppGlobals* globals );
|
||||
static void unloadNewGameState( PalmAppGlobals* globals );
|
||||
static void setNameThatFits( PalmNewGameState* state );
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
static XP_Bool tryDuoRockerKey( PalmAppGlobals* globals,XP_U16 key );
|
||||
static XP_Bool considerGadgetFocus( PalmNewGameState* state, EventType* event );
|
||||
#else
|
||||
# define tryDuoRockerKey(g,key) XP_FALSE
|
||||
#endif
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
static Boolean checkHiliteGadget(PalmAppGlobals* globals, EventType* event,
|
||||
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
|
||||
|
||||
#define IS_SERVER_GADGET(id) \
|
||||
((id) >= XW_SOLO_GADGET_ID && (id) <= XW_CLIENT_GADGET_ID)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
****************************************************************************/
|
||||
Boolean
|
||||
newGameHandleEvent( EventPtr event )
|
||||
{
|
||||
Boolean result = false;
|
||||
EventType eventToPost; /* used only with OK button */
|
||||
PalmAppGlobals* globals;
|
||||
FormPtr form;
|
||||
LocalPlayer* lp;
|
||||
CurGameInfo* gi;
|
||||
PalmNewGameState* state;
|
||||
Int16 chosen;
|
||||
XP_U16 i;
|
||||
XP_U16 controlID;
|
||||
XP_U16 index;
|
||||
Boolean on;
|
||||
Boolean canEdit;
|
||||
|
||||
CALLBACK_PROLOGUE();
|
||||
|
||||
globals = getFormRefcon();
|
||||
gi = &globals->gameInfo;
|
||||
state = &globals->newGameState;
|
||||
|
||||
switch ( event->eType ) {
|
||||
|
||||
case frmOpenEvent:
|
||||
|
||||
GlobalPrefsToLocal( globals );
|
||||
|
||||
loadNewGameState( globals );
|
||||
|
||||
form = FrmGetActiveForm();
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
sizeGadgetsForStrings( form,
|
||||
getActiveObjectPtr( XW_SERVERTYPES_LIST_ID ),
|
||||
XW_SOLO_GADGET_ID );
|
||||
#endif
|
||||
state->playerNumList =
|
||||
getActiveObjectPtr( XW_NPLAYERS_LIST_ID );
|
||||
XP_ASSERT( state->playerNumList != NULL );
|
||||
|
||||
setSelectorFromList( XW_NPLAYERS_SELECTOR_ID,
|
||||
state->playerNumList,
|
||||
gi->nPlayers - 1 );
|
||||
|
||||
XP_ASSERT( !!state->dictName );
|
||||
setNameThatFits( state );
|
||||
|
||||
XP_ASSERT( !!globals->game.server );
|
||||
|
||||
canEdit = state->curServerHilite == SERVER_STANDALONE
|
||||
|| globals->isNewGame;
|
||||
|
||||
/* load the fields from what we already have */
|
||||
for ( lp = gi->players, i = 0; i < MAX_NUM_PLAYERS; ++lp, ++i ) {
|
||||
XP_U16 offset = i * NUM_PLAYER_COLS;
|
||||
ControlPtr check;
|
||||
XP_UCHAR* name;
|
||||
FieldPtr nameField;
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
Boolean isLocal = lp->isLocal;
|
||||
check = getActiveObjectPtr(XW_REMOTE_1_CHECKBOX_ID + offset);
|
||||
CtlSetValue( check, !isLocal );
|
||||
#endif
|
||||
check = getActiveObjectPtr(XW_ROBOT_1_CHECKBOX_ID+offset);
|
||||
CtlSetValue( check, lp->isRobot );
|
||||
|
||||
nameField = getActiveObjectPtr(XW_PLAYERNAME_1_FIELD_ID+offset);
|
||||
name = lp->name;
|
||||
if ( !!name && !!*name ) {
|
||||
FldInsert( nameField, (const char*)name,
|
||||
XP_STRLEN((const char*)name) );
|
||||
}
|
||||
setFieldEditable( nameField, canEdit );
|
||||
|
||||
/* set up the password */
|
||||
if ( !!lp->password ) {
|
||||
CtlSetLabel( getActiveObjectPtr(
|
||||
XW_PLAYERPASSWD_1_TRIGGER_ID+offset ),
|
||||
"*" );
|
||||
}
|
||||
}
|
||||
/* form = FrmGetActiveForm(); */
|
||||
FrmSetFocus(form, FrmGetObjectIndex(form, XW_PLAYERNAME_1_FIELD_ID));
|
||||
|
||||
case frmUpdateEvent:
|
||||
adjustVisibility( globals, XP_FALSE );
|
||||
|
||||
GrfSetState( false, false, false );
|
||||
FrmDrawForm( FrmGetActiveForm() );
|
||||
|
||||
drawConnectGadgets( globals );
|
||||
|
||||
result = true;
|
||||
break;
|
||||
|
||||
#ifdef BEYOND_IR
|
||||
case connsSettingChgEvent:
|
||||
XP_ASSERT( globals->isNewGame );
|
||||
state->connsSettingChanged = XP_TRUE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
case frmObjectFocusTakeEvent:
|
||||
case frmObjectFocusLostEvent:
|
||||
result = considerGadgetFocus( state, event );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case penDownEvent:
|
||||
result = checkHiliteGadget( globals, event, state );
|
||||
break;
|
||||
|
||||
case keyDownEvent:
|
||||
result = tryFieldNavigationKey( event->data.keyDown.chr )
|
||||
|| tryDuoRockerKey( globals, event->data.keyDown.chr );
|
||||
break;
|
||||
|
||||
case prefsChangedEvent:
|
||||
state->forwardChange = true;
|
||||
break;
|
||||
|
||||
case ctlEnterEvent:
|
||||
switch ( event->data.ctlEnter.controlID ) {
|
||||
#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:
|
||||
#endif
|
||||
case XW_DICT_SELECTOR_ID:
|
||||
case XW_NPLAYERS_SELECTOR_ID:
|
||||
if ( !globals->isNewGame ) {
|
||||
result = true;
|
||||
beep();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctlSelectEvent:
|
||||
result = true;
|
||||
controlID = event->data.ctlSelect.controlID;
|
||||
on = event->data.ctlSelect.on;
|
||||
switch ( controlID ) {
|
||||
|
||||
case XW_ROBOT_1_CHECKBOX_ID:
|
||||
case XW_ROBOT_2_CHECKBOX_ID:
|
||||
case XW_ROBOT_3_CHECKBOX_ID:
|
||||
case XW_ROBOT_4_CHECKBOX_ID:
|
||||
index = (controlID - XW_ROBOT_1_CHECKBOX_ID) / NUM_PLAYER_COLS;
|
||||
state->isRobot[index] = on;
|
||||
adjustVisibility( globals, XP_TRUE );
|
||||
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:
|
||||
XP_ASSERT( state->curServerHilite == SERVER_ISSERVER );
|
||||
index = (controlID - XW_REMOTE_1_CHECKBOX_ID) / NUM_PLAYER_COLS;
|
||||
state->isLocal[index] = !on;
|
||||
state->curNPlayersLocal += on? -1:1;
|
||||
adjustVisibility( globals, XP_TRUE );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case XW_NPLAYERS_SELECTOR_ID:
|
||||
XP_ASSERT( globals->isNewGame );
|
||||
chosen = LstPopupList( state->playerNumList );
|
||||
if ( chosen >= 0 ) {
|
||||
setSelectorFromList( XW_NPLAYERS_SELECTOR_ID,
|
||||
state->playerNumList,
|
||||
chosen );
|
||||
++chosen; /* chosen is 0-based */
|
||||
if (state->curServerHilite==SERVER_ISCLIENT) {
|
||||
state->curNPlayersLocal = chosen;
|
||||
XP_ASSERT( state->curNPlayersLocal <= MAX_NUM_PLAYERS );
|
||||
} else {
|
||||
state->curNPlayersTotal = chosen;
|
||||
}
|
||||
setNPlayersAndAdjust( globals, chosen );
|
||||
}
|
||||
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;
|
||||
|
||||
case XW_OK_BUTTON_ID:
|
||||
|
||||
/* 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. */
|
||||
if ( globals->isNewGame ) {
|
||||
|
||||
updatePlayerInfo( globals );
|
||||
|
||||
eventToPost.eType = newGameOkEvent;
|
||||
EvtAddEventToQueue( &eventToPost );
|
||||
globals->postponeDraw = true;
|
||||
|
||||
} else if ( state->curServerHilite
|
||||
== SERVER_STANDALONE ) {
|
||||
updatePlayerInfo( globals );
|
||||
}
|
||||
|
||||
if ( state->forwardChange ) {
|
||||
eventToPost.eType = prefsChangedEvent;
|
||||
EvtAddEventToQueue( &eventToPost );
|
||||
state->forwardChange = false;
|
||||
}
|
||||
|
||||
unloadNewGameState( globals );
|
||||
|
||||
FrmReturnToForm( 0 );
|
||||
break;
|
||||
|
||||
case XW_CANCEL_BUTTON_ID:
|
||||
unloadNewGameState( globals );
|
||||
eventToPost.eType = newGameCancelEvent;
|
||||
EvtAddEventToQueue( &eventToPost );
|
||||
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:
|
||||
handlePasswordTrigger( globals, controlID );
|
||||
break;
|
||||
|
||||
default: /* one of the password selectors? */
|
||||
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;
|
||||
|
||||
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 */
|
||||
|
||||
static XP_U16
|
||||
countLocalIn( PalmNewGameState* state, XP_U16 nPlayers )
|
||||
{
|
||||
XP_U16 nLocal = 0;
|
||||
XP_U16 i;
|
||||
|
||||
for ( i = 0; i < nPlayers; ++i ) {
|
||||
if ( state->isLocal[i] ) {
|
||||
++nLocal;
|
||||
}
|
||||
}
|
||||
|
||||
return nLocal;
|
||||
} /* countLocalIn */
|
||||
|
||||
/* If we're in GUEST mode, only local players are visible, and so this means
|
||||
* an increase in the number of local players. If we're in a different mode
|
||||
* then it means a simple increase in all players. Only the first case is
|
||||
* difficult, because if the number's getting larger we need to confirm that
|
||||
* there's another local player to show, and if there's not we need to
|
||||
* convert the first non-local player.
|
||||
*/
|
||||
static void
|
||||
setNPlayersAndAdjust( PalmAppGlobals* globals, Int16 chosen )
|
||||
{
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
PalmNewGameState* state = &globals->newGameState;
|
||||
|
||||
if ( state->curServerHilite == SERVER_ISCLIENT ) {
|
||||
XP_U16 i;
|
||||
XP_S16 nRemote = 0;
|
||||
XP_S16 nLocal = 0;
|
||||
|
||||
/* find the first non-local player */
|
||||
for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
|
||||
if ( state->isLocal[i] ) {
|
||||
++nLocal;
|
||||
} else {
|
||||
++nRemote;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make as many local as necessary */
|
||||
for ( i = 0; nLocal < chosen && i < MAX_NUM_PLAYERS; ++i ) {
|
||||
if ( !state->isLocal[i] ) {
|
||||
state->isLocal[i] = true;
|
||||
setBooleanCtrl( XW_REMOTE_1_CHECKBOX_ID +
|
||||
(i * NUM_PLAYER_COLS), false );
|
||||
++nLocal;
|
||||
--nRemote;
|
||||
}
|
||||
}
|
||||
|
||||
state->curNPlayersLocal = chosen;
|
||||
XP_ASSERT( state->curNPlayersLocal <= MAX_NUM_PLAYERS );
|
||||
state->curNPlayersTotal = chosen + nRemote;
|
||||
XP_ASSERT( state->curNPlayersTotal <= MAX_NUM_PLAYERS );
|
||||
} else {
|
||||
state->curNPlayersTotal = chosen;
|
||||
state->curNPlayersLocal = countLocalIn( state, chosen );
|
||||
XP_ASSERT( state->curNPlayersLocal <= MAX_NUM_PLAYERS );
|
||||
}
|
||||
#endif
|
||||
|
||||
adjustVisibility( globals, XP_TRUE );
|
||||
} /* setNPlayersAndAdjust */
|
||||
|
||||
static Boolean
|
||||
tryFieldNavigationKey( XP_U16 key )
|
||||
{
|
||||
FormPtr form;
|
||||
Int16 curFocus, nextFocus, change;
|
||||
UInt16 nObjects;
|
||||
|
||||
if ( key == prevFieldChr ) {
|
||||
change = -1;
|
||||
} else if ( key == nextFieldChr ) {
|
||||
change = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
form = FrmGetActiveForm();
|
||||
curFocus = nextFocus = FrmGetFocus( form );
|
||||
nObjects = FrmGetNumberOfObjects(form);
|
||||
|
||||
/* find the next (in either direction) usable field */
|
||||
for ( ; ; ) {
|
||||
nextFocus += change;
|
||||
|
||||
if ( nextFocus == nObjects ) {
|
||||
nextFocus = 0;
|
||||
} else if ( nextFocus < 0 ) {
|
||||
nextFocus = nObjects-1;
|
||||
}
|
||||
|
||||
if ( nextFocus == curFocus ) {
|
||||
break;
|
||||
} else if ( FrmGetObjectType(form, nextFocus) != frmFieldObj ) {
|
||||
continue;
|
||||
} else {
|
||||
FieldPtr field = FrmGetObjectPtr( form, nextFocus );
|
||||
FieldAttrType attrs;
|
||||
FldGetAttributes( field, &attrs );
|
||||
if ( attrs.usable ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FrmSetFocus( form, nextFocus );
|
||||
return true;
|
||||
} /* tryFieldNavigationKey */
|
||||
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
#ifdef DEBUG
|
||||
static XP_UCHAR*
|
||||
keyToStr( XP_U16 key )
|
||||
{
|
||||
#define keyCase(k) case (k): return #k
|
||||
switch( key ) {
|
||||
keyCase(vchrRockerUp);
|
||||
keyCase(vchrRockerDown);
|
||||
keyCase(vchrRockerLeft);
|
||||
keyCase(vchrRockerRight);
|
||||
keyCase(vchrRockerCenter);
|
||||
default:
|
||||
return "huh?";
|
||||
}
|
||||
#undef keyCase
|
||||
}
|
||||
#endif
|
||||
|
||||
static XP_Bool
|
||||
tryDuoRockerKey( PalmAppGlobals* globals, XP_U16 key )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_U16 focusID;
|
||||
FormPtr form;
|
||||
|
||||
switch( key ) {
|
||||
case vchrRockerUp:
|
||||
case vchrRockerDown:
|
||||
case vchrRockerLeft:
|
||||
case vchrRockerRight:
|
||||
XP_LOGF( "got rocker key: %s", keyToStr(key) );
|
||||
result = XP_FALSE;
|
||||
break;
|
||||
case vchrRockerCenter:
|
||||
/* if one of the gadgets is focussed, "tap" it. */
|
||||
XP_LOGF( "got rocker key: %s", keyToStr(key) );
|
||||
form = FrmGetActiveForm();
|
||||
focusID = FrmGetObjectId( form, FrmGetFocus( form ) );
|
||||
if ( IS_SERVER_GADGET( focusID ) ) {
|
||||
changeGadgetHilite( globals, focusID );
|
||||
result = XP_TRUE;
|
||||
} else {
|
||||
XP_LOGF( "%d not server gadget", focusID );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
} /* tryDuoRockerKey */
|
||||
#endif
|
||||
|
||||
static void
|
||||
adjustVisibility( PalmAppGlobals* globals, XP_Bool canDraw )
|
||||
{
|
||||
FormPtr form = FrmGetActiveForm();
|
||||
short i;
|
||||
PalmNewGameState* state = &globals->newGameState;
|
||||
XP_Bool isNewGame = globals->isNewGame;
|
||||
|
||||
Connectedness curServerHilite = state->curServerHilite;
|
||||
Boolean canShowRemote = curServerHilite != SERVER_STANDALONE;
|
||||
Boolean isClient = curServerHilite == SERVER_ISCLIENT;
|
||||
XP_U16 nShown = 0;
|
||||
Boolean canEdit = (curServerHilite == SERVER_STANDALONE) || isNewGame;
|
||||
XP_U16 nToShow = (isClient && isNewGame)?
|
||||
state->curNPlayersLocal:state->curNPlayersTotal;
|
||||
|
||||
/* It's illegal for there to be 0 players selected. So if that ever
|
||||
happens, make the first player local. And beep? */
|
||||
if ( nToShow == 0 ) {
|
||||
XP_ASSERT( isClient ); /* the only way this can happen is if someone
|
||||
sets type to SERVER_ISCLIENT when there
|
||||
are no local players. */
|
||||
state->isLocal[0] = true;
|
||||
nToShow = state->curNPlayersLocal = 1;
|
||||
setBooleanCtrl( XW_REMOTE_1_CHECKBOX_ID, false );
|
||||
}
|
||||
|
||||
if ( canShowRemote && isClient ) {
|
||||
canShowRemote = !isNewGame;
|
||||
}
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
disOrEnable( form, XW_LOCAL_LABEL_ID, canShowRemote );
|
||||
if ( canShowRemote ) {
|
||||
disOrEnable( form, XW_TOTALP_LABEL_ID, XP_TRUE );
|
||||
} else {
|
||||
disOrEnable( form, XW_LOCALP_LABEL_ID, XP_TRUE );
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
|
||||
short offset = NUM_PLAYER_COLS * i;
|
||||
Boolean lineVisible = nShown < nToShow;
|
||||
Boolean isLocal;
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
Boolean showRemote;
|
||||
Boolean remoteChecked = !state->isLocal[i];
|
||||
|
||||
if ( isClient && lineVisible && remoteChecked && isNewGame ) {
|
||||
lineVisible = false;
|
||||
}
|
||||
#endif
|
||||
/* Since the user of a device can change at will whether a local
|
||||
player is a robot, we don't show that attribute except when it's
|
||||
for a local player; don't keep track of what's going on on the
|
||||
other device. */
|
||||
isLocal = lineVisible;
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
showRemote = lineVisible && canShowRemote;
|
||||
isLocal = isLocal &&
|
||||
(curServerHilite == SERVER_STANDALONE
|
||||
|| (showRemote && !remoteChecked)
|
||||
|| (isClient && isNewGame) );
|
||||
|
||||
/* show local/remote checkbox if not standalone */
|
||||
disOrEnable( form, XW_REMOTE_1_CHECKBOX_ID + offset,
|
||||
lineVisible && showRemote );
|
||||
#endif
|
||||
/* show name no matter what (if line's showing) */
|
||||
disOrEnable( form, XW_PLAYERNAME_1_FIELD_ID + offset,
|
||||
lineVisible && (isLocal || !isNewGame) );
|
||||
|
||||
if ( lineVisible ) {
|
||||
FieldPtr nameField =
|
||||
getActiveObjectPtr(XW_PLAYERNAME_1_FIELD_ID + offset);
|
||||
setFieldEditable( nameField, canEdit );
|
||||
if ( canDraw ) {
|
||||
FldDrawField( nameField );
|
||||
}
|
||||
}
|
||||
|
||||
/* show robot checkbox if player is local */
|
||||
disOrEnable( form, XW_ROBOT_1_CHECKBOX_ID + offset, isLocal );
|
||||
|
||||
/* and show password if not a robot (and if local) */
|
||||
disOrEnable( form, XW_PLAYERPASSWD_1_TRIGGER_ID + offset,
|
||||
isLocal && !state->isRobot[i] );
|
||||
|
||||
if ( lineVisible ) {
|
||||
++nShown;
|
||||
}
|
||||
XP_ASSERT( nShown <= MAX_NUM_PLAYERS );
|
||||
}
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
XP_ASSERT( nShown > 0 );
|
||||
setSelectorFromList( XW_NPLAYERS_SELECTOR_ID,
|
||||
state->playerNumList, nShown - 1 );
|
||||
#endif
|
||||
} /* adjustVisibility */
|
||||
|
||||
/*
|
||||
* Copy the local state into global state.
|
||||
*/
|
||||
static void
|
||||
updatePlayerInfo( PalmAppGlobals* globals )
|
||||
{
|
||||
UInt16 i;
|
||||
CurGameInfo* gi;
|
||||
LocalPlayer* lp;
|
||||
PalmNewGameState* state = &globals->newGameState;
|
||||
Connectedness curServerHilite = globals->newGameState.curServerHilite;
|
||||
|
||||
gi = &globals->gameInfo;
|
||||
|
||||
gi->nPlayers = curServerHilite == SERVER_ISCLIENT?
|
||||
state->curNPlayersLocal: state->curNPlayersTotal;
|
||||
XP_ASSERT( gi->nPlayers <= MAX_NUM_PLAYERS );
|
||||
|
||||
gi->boardSize = globals->prefsDlgState->curBdSize;
|
||||
gi->serverRole = curServerHilite;
|
||||
|
||||
replaceStringIfDifferent( MPPARM(globals->mpool) &gi->dictName,
|
||||
globals->newGameState.dictName );
|
||||
|
||||
for ( i = 0, lp = gi->players; i < MAX_NUM_PLAYERS; ++i, ++lp ) {
|
||||
XP_UCHAR* name = NULL;
|
||||
XP_UCHAR* passwd = NULL;
|
||||
short offset = NUM_PLAYER_COLS * i;
|
||||
XP_Bool isLocal = state->isLocal[i];
|
||||
|
||||
if ( isLocal ) {
|
||||
MemPtr p = getActiveObjectPtr( offset +
|
||||
XW_PLAYERNAME_1_FIELD_ID );
|
||||
name = (XP_UCHAR*)FldGetTextPtr( p );
|
||||
|
||||
if ( name == NULL ) {
|
||||
name = (XP_UCHAR*)"";
|
||||
}
|
||||
passwd = globals->newGameState.passwds[i];
|
||||
}
|
||||
|
||||
lp->isRobot = state->isRobot[i];
|
||||
lp->isLocal = isLocal;
|
||||
|
||||
replaceStringIfDifferent(MPPARM(globals->mpool) &lp->name, name);
|
||||
replaceStringIfDifferent(MPPARM(globals->mpool) &lp->password, passwd);
|
||||
}
|
||||
|
||||
#ifdef BEYOND_IR
|
||||
if ( state->connsSettingChanged ) {
|
||||
CommsAddrRec addr;
|
||||
XP_U16 localPort;
|
||||
|
||||
comms_getAddr( globals->game.comms, &addr, &localPort );
|
||||
|
||||
addr.conType = state->connAddrs.conType;
|
||||
if ( addr.conType == COMMS_CONN_IP ) {
|
||||
addr.u.ip.port = state->connAddrs.remotePort;
|
||||
addr.u.ip.ipAddr = state->connAddrs.remoteIP;
|
||||
localPort = state->connAddrs.localPort;
|
||||
}
|
||||
comms_setAddr( globals->game.comms, &addr, localPort );
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* updatePlayerInfo */
|
||||
|
||||
void
|
||||
drawOneGadget( UInt16 id, char* text, Boolean hilite )
|
||||
{
|
||||
RectangleType divRect;
|
||||
XP_U16 len = StrLen(text);
|
||||
XP_U16 width = FntCharsWidth( text, len );
|
||||
XP_U16 left;
|
||||
|
||||
getObjectBounds( id, &divRect );
|
||||
WinDrawRectangleFrame( rectangleFrame, &divRect );
|
||||
WinEraseRectangle( &divRect, 0 );
|
||||
left = divRect.topLeft.x;
|
||||
left += (divRect.extent.x - width) / 2;
|
||||
WinDrawChars( text, len, left, divRect.topLeft.y );
|
||||
if ( hilite ) {
|
||||
WinInvertRectangle( &divRect, 0 );
|
||||
}
|
||||
} /* drawOneGadget */
|
||||
|
||||
/* Frame 'em, draw their text, and highlight the one that's selected
|
||||
*/
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
static void
|
||||
drawFocusRingOnGadget()
|
||||
{
|
||||
FormPtr form = FrmGetActiveForm();
|
||||
XP_U16 focusID = FrmGetObjectId( form, FrmGetFocus(form) );
|
||||
if ( IS_SERVER_GADGET(focusID) ) {
|
||||
Err err;
|
||||
RectangleType rect;
|
||||
|
||||
getObjectBounds( focusID, &rect );
|
||||
|
||||
err = HsNavDrawFocusRing( form, focusID, 0, &rect,
|
||||
hsNavFocusRingStyleObjectTypeDefault,
|
||||
false );
|
||||
XP_ASSERT( err == errNone );
|
||||
}
|
||||
} /* drawFocusRingOnGadget */
|
||||
#endif
|
||||
|
||||
static void
|
||||
drawConnectGadgets( PalmAppGlobals* globals )
|
||||
{
|
||||
UInt16 i;
|
||||
ListPtr list = getActiveObjectPtr( XW_SERVERTYPES_LIST_ID );
|
||||
XP_ASSERT( !!list );
|
||||
|
||||
for ( i = 0; i < 3; ++i ) {
|
||||
char* text = LstGetSelectionText( list, i );
|
||||
Boolean hilite = i == globals->newGameState.curServerHilite;
|
||||
drawOneGadget( i + XW_SOLO_GADGET_ID, text, hilite );
|
||||
}
|
||||
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
drawFocusRingOnGadget();
|
||||
#endif
|
||||
|
||||
} /* drawConnectGadgets */
|
||||
|
||||
#ifdef HS_DUO_SUPPORT
|
||||
static XP_Bool
|
||||
considerGadgetFocus( PalmNewGameState* state, EventType* event )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
XP_Bool isTake;
|
||||
XP_U16 eType = event->eType;
|
||||
FormPtr form = FrmGetActiveForm();
|
||||
XP_U16 objectID;
|
||||
|
||||
XP_ASSERT( eType == frmObjectFocusTakeEvent
|
||||
|| eType == frmObjectFocusLostEvent );
|
||||
XP_ASSERT( event->data.frmObjectFocusTake.formID == FrmGetActiveFormID() );
|
||||
|
||||
|
||||
isTake = eType == frmObjectFocusTakeEvent;
|
||||
if ( isTake ) {
|
||||
objectID = event->data.frmObjectFocusTake.objectID;
|
||||
} else {
|
||||
objectID = event->data.frmObjectFocusLost.objectID;
|
||||
}
|
||||
|
||||
/* docs say to return HANDLED for both take and lost */
|
||||
result = IS_SERVER_GADGET( objectID );
|
||||
|
||||
if ( result ) {
|
||||
Err err;
|
||||
if ( isTake ) {
|
||||
|
||||
FrmSetFocus(form, FrmGetObjectIndex(form, objectID));
|
||||
drawFocusRingOnGadget();
|
||||
result = XP_TRUE;
|
||||
/* } else { */
|
||||
/* err = HsNavRemoveFocusRing( form ); */
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} /* considerGadgetFocus */
|
||||
#endif
|
||||
|
||||
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 ) {
|
||||
state->curServerHilite = hiliteID;
|
||||
drawConnectGadgets( globals );
|
||||
adjustVisibility( globals, XP_TRUE );
|
||||
} else {
|
||||
beep();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BEYOND_IR
|
||||
/* Even if it didn't change, pop the connections form */
|
||||
if ( hiliteID != SERVER_STANDALONE ) {
|
||||
if ( isNewGame || hiliteID==globals->newGameState.curServerHilite ) {
|
||||
PopupConnsForm( globals, hiliteID, &state->connAddrs );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} /* changeGadgetHilite */
|
||||
|
||||
static Boolean
|
||||
checkHiliteGadget( PalmAppGlobals* globals, EventType* event,
|
||||
PalmNewGameState* state )
|
||||
{
|
||||
Boolean result = false;
|
||||
UInt16 selGadget;
|
||||
|
||||
XP_ASSERT( &globals->newGameState == state );
|
||||
|
||||
result = penInGadget( event, &selGadget );
|
||||
if ( result ) {
|
||||
changeGadgetHilite( globals, selGadget );
|
||||
}
|
||||
|
||||
return result;
|
||||
} /* checkHiliteGadget */
|
||||
#endif
|
||||
|
||||
/* 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** password;
|
||||
XP_UCHAR* name;
|
||||
FieldPtr nameField;
|
||||
XP_U16 len;
|
||||
XP_UCHAR buf[32];
|
||||
char* label;
|
||||
|
||||
playerNum = (controlID - XW_PLAYERPASSWD_1_TRIGGER_ID) / NUM_PLAYER_COLS;
|
||||
XP_ASSERT( playerNum < MAX_NUM_PLAYERS );
|
||||
|
||||
password = &state->passwds[playerNum];
|
||||
nameField = getActiveObjectPtr( XW_PLAYERNAME_1_FIELD_ID +
|
||||
(NUM_PLAYER_COLS * playerNum) );
|
||||
name = (XP_UCHAR*)FldGetTextPtr( nameField );
|
||||
|
||||
len = sizeof(buf);
|
||||
if ( askPassword( globals, name, true, buf, &len ) ) {
|
||||
|
||||
if ( len == 0 ) {
|
||||
buf[0] = '\0';
|
||||
label = " ";
|
||||
} else {
|
||||
label = "*";
|
||||
}
|
||||
replaceStringIfDifferent(MPPARM(globals->mpool) password,
|
||||
(unsigned char*)buf);
|
||||
|
||||
/* control owns the string passed in */
|
||||
CtlSetLabel( getActiveObjectPtr( controlID ), label );
|
||||
}
|
||||
} /* handlePasswordTrigger */
|
||||
|
||||
static void
|
||||
unloadNewGameState( PalmAppGlobals* globals )
|
||||
{
|
||||
XP_U16 i;
|
||||
XP_UCHAR** passwd;
|
||||
PalmNewGameState* state = &globals->newGameState;
|
||||
|
||||
for ( passwd = state->passwds, i = 0;
|
||||
i < MAX_NUM_PLAYERS; ++i, ++passwd ) {
|
||||
if ( !!*passwd ) {
|
||||
XP_FREE( globals->mpool, *passwd );
|
||||
*passwd = NULL;
|
||||
}
|
||||
}
|
||||
/* XP_WARNF( "freeing string 0x%lx", state->dictName ); */
|
||||
XP_FREE( globals->mpool, state->dictName );
|
||||
state->dictName = NULL;
|
||||
} /* unloadNewGameState */
|
||||
|
||||
static void
|
||||
loadNewGameState( PalmAppGlobals* globals )
|
||||
{
|
||||
CurGameInfo* gi = &globals->gameInfo;
|
||||
PalmNewGameState* state = &globals->newGameState;
|
||||
XP_U16 i;
|
||||
LocalPlayer* lp;
|
||||
|
||||
XP_MEMSET( state, 0, sizeof(*state) );
|
||||
|
||||
state->dictName = copyString( MPPARM(globals->mpool) gi->dictName );
|
||||
state->curServerHilite = gi->serverRole;
|
||||
|
||||
for ( i = 0, lp=gi->players; i < MAX_NUM_PLAYERS; ++i, ++lp ) {
|
||||
state->isLocal[i] = lp->isLocal;
|
||||
state->isRobot[i] = lp->isRobot;
|
||||
state->passwds[i] = copyString( MPPARM(globals->mpool)
|
||||
lp->password );
|
||||
}
|
||||
|
||||
state->curNPlayersTotal = gi->nPlayers;
|
||||
state->curNPlayersLocal = countLocalIn( state, gi->nPlayers );
|
||||
XP_ASSERT( state->curNPlayersLocal <= MAX_NUM_PLAYERS );
|
||||
|
||||
#ifdef BEYOND_IR
|
||||
{
|
||||
CommsAddrRec addr;
|
||||
comms_getAddr( globals->game.comms, &addr,
|
||||
&state->connAddrs.localPort );
|
||||
state->connAddrs.remotePort = addr.u.ip.port;
|
||||
state->connAddrs.remoteIP = addr.u.ip.ipAddr;
|
||||
state->connAddrs.conType = addr.conType;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* loadNewGameState */
|
32
palm/newgame.h
Normal file
32
palm/newgame.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2001-2002 by Eric House (fixin@peak.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 NEWGAME_H
|
||||
#define NEWGAME_H
|
||||
|
||||
#include <Event.h>
|
||||
|
||||
#include "palmmain.h"
|
||||
|
||||
|
||||
Boolean newGameHandleEvent( EventPtr event );
|
||||
|
||||
void drawOneGadget( UInt16 id, char* text, Boolean hilite );
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue