2006-05-12 09:54:59 +02:00
|
|
|
/* -*- fill-column: 77; c-basic-offset: 4; compile-command: "make TARGET_OS=wince DEBUG=TRUE" -*- */
|
2003-11-20 17:26:35 +01:00
|
|
|
/*
|
2007-01-19 07:43:52 +01:00
|
|
|
* Copyright 2002-2007 by Eric House (xwords@eehouse.org). All rights reserved.
|
2003-11-20 17:26:35 +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.
|
|
|
|
*
|
2004-01-30 06:48:24 +01:00
|
|
|
* Derived from code generated by M$'s eVC++.
|
2003-11-20 17:26:35 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "xwords4.h"
|
|
|
|
#include <commctrl.h>
|
|
|
|
#include <commdlg.h>
|
|
|
|
#include <stdio.h>
|
2006-05-12 09:17:35 +02:00
|
|
|
#include <time.h> /* time() */
|
2003-11-20 17:26:35 +01:00
|
|
|
#include <winuser.h>
|
2006-02-17 08:30:54 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2005-11-27 21:16:43 +01:00
|
|
|
# include <aygshell.h>
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
#include "strutils.h"
|
|
|
|
|
|
|
|
#include "memstream.h"
|
|
|
|
|
|
|
|
#include "cemain.h"
|
|
|
|
#include "cedefines.h"
|
|
|
|
|
|
|
|
#include "ceginfo.h"
|
|
|
|
#include "cestrbx.h"
|
|
|
|
#include "cedict.h"
|
|
|
|
#include "ceblank.h"
|
|
|
|
#include "ceprefs.h"
|
|
|
|
#include "ceaskpwd.h"
|
|
|
|
#include "ceutil.h"
|
|
|
|
#include "ceir.h"
|
2004-03-28 03:14:34 +02:00
|
|
|
#include "ceclrsel.h"
|
2004-07-10 19:46:36 +02:00
|
|
|
#include "cehntlim.h"
|
2008-02-16 18:36:46 +01:00
|
|
|
#include "cedebug.h"
|
2003-11-20 17:26:35 +01:00
|
|
|
#include "LocalizedStrIncludes.h"
|
2006-01-28 20:02:04 +01:00
|
|
|
#include "debhacks.h"
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
#include "dbgutil.h"
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
#define MAX_LOADSTRING 100
|
2006-02-15 14:09:36 +01:00
|
|
|
|
|
|
|
#ifdef _WIN32_WCE
|
|
|
|
# define DEFAULT_DIR_NAME L"\\My Documents\\Crosswords"
|
|
|
|
# define PREFSFILENAME L"\\My Documents\\Crosswords\\xwprefs"
|
|
|
|
# define UNSAVEDGAMEFILENAME "\\My Documents\\Crosswords\\_newgame"
|
|
|
|
#else
|
|
|
|
# define DEFAULT_DIR_NAME L"."
|
|
|
|
# define PREFSFILENAME L".\\xwprefs"
|
|
|
|
# define UNSAVEDGAMEFILENAME ".\\_newgame"
|
|
|
|
#endif
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
#define SCROLLBAR_WIDTH 12
|
|
|
|
#define SCROLLBARID 0x4321 /* needs to be unique! */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
#ifdef MEM_DEBUG
|
|
|
|
# define MEMPOOL globals->mpool,
|
|
|
|
#else
|
|
|
|
# define MEMPOOL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct FileWriteState {
|
|
|
|
CEAppGlobals* globals;
|
|
|
|
XP_UCHAR* path;
|
|
|
|
} FileWriteState;
|
|
|
|
|
|
|
|
/* forward util function decls */
|
2006-10-28 16:56:04 +02:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2006-09-15 09:39:57 +02:00
|
|
|
static XP_S16 ce_send_proc( const XP_U8* buf, XP_U16 len,
|
2005-07-30 04:02:49 +02:00
|
|
|
const CommsAddrRec* addr,
|
2005-07-23 17:31:21 +02:00
|
|
|
void* closure );
|
2007-12-03 02:18:13 +01:00
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
#define CE_SEND_PROC ce_send_proc
|
|
|
|
#else
|
|
|
|
#define CE_SEND_PROC NULL
|
|
|
|
#endif
|
2005-07-23 17:31:21 +02:00
|
|
|
|
2007-12-03 02:18:13 +01:00
|
|
|
#ifdef COMMS_HEARTBEAT
|
|
|
|
static void ce_reset_proc( void* closure );
|
|
|
|
# define CE_RESET_PROC ce_send_proc,
|
|
|
|
#else
|
|
|
|
# define CE_RESET_PROC
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static VTableMgr* ce_util_getVTManager( XW_UtilCtxt* uc );
|
|
|
|
static void ce_util_userError( XW_UtilCtxt* uc, UtilErrID id );
|
2004-02-17 06:00:13 +01:00
|
|
|
static XP_Bool ce_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id,
|
|
|
|
XWStreamCtxt* stream );
|
2003-11-20 17:26:35 +01:00
|
|
|
static XWBonusType ce_util_getSquareBonus( XW_UtilCtxt* uc,
|
|
|
|
ModelCtxt* model,
|
|
|
|
XP_U16 col, XP_U16 row );
|
2005-02-05 22:43:16 +01:00
|
|
|
static XP_S16 ce_util_userPickTile( XW_UtilCtxt* uc, const PickInfo* pi,
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_U16 playerNum,
|
2005-02-05 22:43:16 +01:00
|
|
|
const XP_UCHAR4* texts, XP_U16 nTiles );
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool ce_util_askPassword( XW_UtilCtxt* uc, const XP_UCHAR* name,
|
|
|
|
XP_UCHAR* buf, XP_U16* len );
|
2005-11-27 21:16:43 +01:00
|
|
|
static void ce_util_trayHiddenChange( XW_UtilCtxt* uc,
|
2006-05-19 15:44:05 +02:00
|
|
|
XW_TrayVisState newState,
|
|
|
|
XP_U16 nVisibleRows );
|
2003-11-20 17:26:35 +01:00
|
|
|
static void ce_util_yOffsetChange( XW_UtilCtxt* uc, XP_U16 oldOffset,
|
|
|
|
XP_U16 newOffset );
|
2008-02-26 14:49:41 +01:00
|
|
|
static void ce_util_turnChanged( XW_UtilCtxt* uc );
|
2003-11-20 17:26:35 +01:00
|
|
|
static void ce_util_notifyGameOver( XW_UtilCtxt* uc );
|
|
|
|
static XP_Bool ce_util_hiliteCell( XW_UtilCtxt* uc, XP_U16 col,
|
|
|
|
XP_U16 row );
|
|
|
|
static XP_Bool ce_util_engineProgressCallback( XW_UtilCtxt* uc );
|
2005-06-23 16:09:20 +02:00
|
|
|
static void ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
2007-05-26 16:14:01 +02:00
|
|
|
XWTimerProc proc, void* closure);
|
2003-11-20 17:26:35 +01:00
|
|
|
static void ce_util_requestTime( XW_UtilCtxt* uc );
|
|
|
|
static XP_U32 ce_util_getCurSeconds( XW_UtilCtxt* uc );
|
|
|
|
static DictionaryCtxt* ce_util_makeEmptyDict( XW_UtilCtxt* uc );
|
2006-10-28 16:56:04 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2003-11-20 17:26:35 +01:00
|
|
|
static XWStreamCtxt* ce_util_makeStreamFromAddr( XW_UtilCtxt* uc,
|
2008-01-05 17:37:49 +01:00
|
|
|
XP_PlayerAddr channelNo );
|
2003-11-20 17:26:35 +01:00
|
|
|
#endif
|
2007-02-03 18:54:20 +01:00
|
|
|
static const XP_UCHAR* ce_util_getUserString( XW_UtilCtxt* uc,
|
|
|
|
XP_U16 stringCode );
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool ce_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
|
|
|
XP_U16 turn, XP_Bool turnLost );
|
2006-10-10 03:34:37 +02:00
|
|
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
|
2005-07-23 17:31:21 +02:00
|
|
|
static void ce_util_addrChange( XW_UtilCtxt* uc, const CommsAddrRec* oldAddr,
|
|
|
|
const CommsAddrRec* newAddr );
|
|
|
|
#endif
|
|
|
|
|
2004-07-10 19:46:36 +02:00
|
|
|
#ifdef XWFEATURE_SEARCHLIMIT
|
|
|
|
static XP_Bool ce_util_getTraySearchLimits( XW_UtilCtxt* uc, XP_U16* min,
|
|
|
|
XP_U16* max );
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
#ifdef SHOW_PROGRESS
|
|
|
|
static void ce_util_engineStarting( XW_UtilCtxt* uc );
|
|
|
|
static void ce_util_engineStopping( XW_UtilCtxt* uc );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void messageBoxChar( CEAppGlobals* globals, XP_UCHAR* str,
|
|
|
|
wchar_t* title );
|
|
|
|
static XP_Bool queryBoxChar( CEAppGlobals* globals, XP_UCHAR* msg );
|
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
static XP_Bool ceMsgFromStream( CEAppGlobals* globals, XWStreamCtxt* stream,
|
|
|
|
wchar_t* title, XP_Bool isQuery,
|
|
|
|
XP_Bool destroy );
|
2003-11-20 17:26:35 +01:00
|
|
|
static void RECTtoXPR( XP_Rect* dest, RECT* src );
|
2006-08-16 15:44:44 +02:00
|
|
|
static XP_Bool ceDoNewGame( CEAppGlobals* globals );
|
2004-01-10 19:11:28 +01:00
|
|
|
static XP_Bool ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave );
|
2008-02-23 23:06:05 +01:00
|
|
|
static void ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs );
|
2004-05-26 06:48:25 +02:00
|
|
|
static void updateForColors( CEAppGlobals* globals );
|
2005-08-21 16:36:11 +02:00
|
|
|
static XWStreamCtxt* make_generic_stream( CEAppGlobals* globals );
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-08-21 16:36:11 +02:00
|
|
|
static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
|
2006-05-28 16:53:02 +02:00
|
|
|
#endif
|
2006-04-19 06:56:00 +02:00
|
|
|
static XP_Bool ceSetDictName( const wchar_t* wPath, XP_U16 index, void* ctxt );
|
2006-04-24 06:34:42 +02:00
|
|
|
static void messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream,
|
|
|
|
wchar_t* title );
|
2006-05-05 14:51:08 +02:00
|
|
|
static XP_Bool ceQueryFromStream( CEAppGlobals* globals, XWStreamCtxt* stream);
|
2008-02-16 18:36:46 +01:00
|
|
|
|
2006-04-19 06:56:00 +02:00
|
|
|
|
2006-05-12 09:54:59 +02:00
|
|
|
#if defined DEBUG && ! defined _WIN32_WCE
|
|
|
|
/* Very basic cmdline args meant at first to let me vary the size of the
|
|
|
|
* screen. Form is of arg=digits, with no spaces and digits having to be an
|
|
|
|
* integer. Right now only width and height work: e.g.
|
|
|
|
* "wine obj_win32_dbg/xwords4.exe height=240 width=320"
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int g_dbWidth = 0;
|
|
|
|
static int g_dbHeight = 0;
|
|
|
|
|
|
|
|
static void
|
|
|
|
doCmd( const char* cmd )
|
|
|
|
{
|
|
|
|
struct { char* p; int* v; } params[] = {
|
|
|
|
{ "width", &g_dbWidth },
|
|
|
|
{ "height", &g_dbHeight }
|
|
|
|
};
|
|
|
|
int i;
|
|
|
|
|
2007-05-26 16:03:07 +02:00
|
|
|
for ( i = 0; i < VSIZE(params); ++i ) {
|
2006-05-12 09:54:59 +02:00
|
|
|
char* p = params[i].p;
|
|
|
|
int len = strlen(p);
|
|
|
|
if ( 0 == strncmp( p, cmd, len ) ) {
|
|
|
|
cmd += len;
|
|
|
|
if ( *cmd == '=' ) {
|
|
|
|
++cmd;
|
|
|
|
*(params[i].v) = atoi(cmd);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-26 16:03:07 +02:00
|
|
|
if ( i == VSIZE(params) ) {
|
2006-05-12 09:54:59 +02:00
|
|
|
XP_LOGF( "failed to match cmdline arg \"%s\"", cmd );
|
|
|
|
}
|
|
|
|
} /* doCmd */
|
|
|
|
|
|
|
|
static void
|
|
|
|
parseCmdLine( const char* cmdline )
|
|
|
|
{
|
|
|
|
for ( ; ; ) {
|
|
|
|
const char* cmd;
|
|
|
|
char ch;
|
|
|
|
char buf[64];
|
|
|
|
int len;
|
|
|
|
for ( cmd = cmdline ; ; ++cmd ) {
|
|
|
|
ch = *cmd;
|
|
|
|
if ( ch == '\0' || ch == ' ' ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
len = cmd - cmdline;
|
|
|
|
memcpy( buf, cmdline, cmd - cmdline );
|
|
|
|
buf[len] = '\0';
|
|
|
|
doCmd( buf );
|
|
|
|
if ( ch == '\0' ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cmdline = ++cmd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
// Forward declarations of functions included in this code module:
|
|
|
|
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
|
|
|
|
BOOL InitInstance (HINSTANCE, int);
|
|
|
|
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
|
2008-02-16 18:36:46 +01:00
|
|
|
LRESULT CALLBACK ceAbout (HWND, UINT, WPARAM, LPARAM);
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
int WINAPI
|
|
|
|
WinMain( HINSTANCE hInstance,
|
2006-08-16 15:44:44 +02:00
|
|
|
HINSTANCE XP_UNUSED(hPrevInstance),
|
2005-11-27 21:16:43 +01:00
|
|
|
#if defined TARGET_OS_WINCE
|
2008-02-16 18:36:46 +01:00
|
|
|
LPWSTR XP_UNUSED_CE(lpCmdLine),
|
2005-11-27 21:16:43 +01:00
|
|
|
#elif defined TARGET_OS_WIN32
|
2006-08-16 15:44:44 +02:00
|
|
|
LPSTR XP_UNUSED_DBG(lpCmdLine),
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
int nCmdShow)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
HACCEL hAccelTable;
|
|
|
|
|
2006-05-12 09:54:59 +02:00
|
|
|
#if defined DEBUG && ! defined _WIN32_WCE
|
|
|
|
parseCmdLine( lpCmdLine );
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
// Perform application initialization:
|
|
|
|
if (!InitInstance (hInstance, nCmdShow)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_XWORDS4);
|
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
// Main message loop. Return of 0 indicates quit message. Return of -1
|
|
|
|
// indicates major error (so we just bail.)
|
|
|
|
while ( 0 < GetMessage(&msg, NULL, 0, 0) ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
/* This would be a good place to free up memory, close sockets, etc. */
|
|
|
|
|
2006-05-30 07:12:02 +02:00
|
|
|
LOG_RETURNF( "%d", msg.wParam );
|
2003-11-20 17:26:35 +01:00
|
|
|
return msg.wParam;
|
|
|
|
}
|
|
|
|
|
2006-01-28 20:02:04 +01:00
|
|
|
#ifdef __GNUC__
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
2006-01-31 07:41:16 +01:00
|
|
|
LOG_FUNC();
|
2006-01-28 20:02:04 +01:00
|
|
|
|
|
|
|
return WinMain( GetModuleHandle(NULL), 0,
|
|
|
|
#if defined TARGET_OS_WINCE
|
|
|
|
GetCommandLineW(),
|
|
|
|
#elif defined TARGET_OS_WIN32
|
|
|
|
GetCommandLineA(),
|
|
|
|
#endif
|
2006-01-31 07:41:16 +01:00
|
|
|
SW_SHOWDEFAULT );
|
2006-01-28 20:02:04 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
//
|
|
|
|
// FUNCTION: MyRegisterClass()
|
|
|
|
//
|
|
|
|
// PURPOSE: Registers the window class.
|
|
|
|
//
|
|
|
|
// COMMENTS:
|
|
|
|
//
|
|
|
|
// It is important to call this function so that the application
|
|
|
|
// will get 'well formed' small icons associated with it.
|
|
|
|
//
|
|
|
|
ATOM
|
|
|
|
MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
|
|
|
|
{
|
|
|
|
WNDCLASS wc;
|
|
|
|
|
2005-11-27 23:06:04 +01:00
|
|
|
XP_MEMSET( &wc, 0, sizeof(wc) );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
wc.lpfnWndProc = (WNDPROC) WndProc;
|
|
|
|
wc.cbWndExtra = sizeof(CEAppGlobals*);
|
|
|
|
wc.hInstance = hInstance;
|
|
|
|
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_XWORDS4));
|
|
|
|
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
|
2005-11-27 23:06:04 +01:00
|
|
|
#if defined TARGET_OS_WIN32
|
|
|
|
wc.lpszMenuName = (LPCTSTR)IDM_MENU;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
wc.lpszClassName = szWindowClass;
|
|
|
|
|
|
|
|
return RegisterClass(&wc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ceInitUtilFuncs( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
UtilVtable* vtable = globals->util.vtable =
|
|
|
|
XP_MALLOC( globals->mpool, sizeof( UtilVtable ) );
|
|
|
|
globals->util.closure = (void*)globals;
|
|
|
|
globals->util.gameInfo = &globals->gameInfo;
|
|
|
|
|
|
|
|
MPASSIGN( globals->util.mpool, globals->mpool );
|
|
|
|
|
|
|
|
vtable->m_util_getVTManager = ce_util_getVTManager;
|
|
|
|
vtable->m_util_userError = ce_util_userError;
|
|
|
|
vtable->m_util_getSquareBonus = ce_util_getSquareBonus;
|
|
|
|
vtable->m_util_userQuery = ce_util_userQuery;
|
|
|
|
vtable->m_util_userPickTile = ce_util_userPickTile;
|
|
|
|
vtable->m_util_askPassword = ce_util_askPassword;
|
|
|
|
vtable->m_util_trayHiddenChange = ce_util_trayHiddenChange;
|
|
|
|
vtable->m_util_yOffsetChange = ce_util_yOffsetChange;
|
2008-02-26 14:49:41 +01:00
|
|
|
vtable->m_util_turnChanged = ce_util_turnChanged;
|
2003-11-20 17:26:35 +01:00
|
|
|
vtable->m_util_notifyGameOver = ce_util_notifyGameOver;
|
|
|
|
vtable->m_util_hiliteCell = ce_util_hiliteCell;
|
|
|
|
vtable->m_util_engineProgressCallback = ce_util_engineProgressCallback;
|
|
|
|
vtable->m_util_setTimer = ce_util_setTimer;
|
|
|
|
vtable->m_util_requestTime = ce_util_requestTime;
|
|
|
|
vtable->m_util_getCurSeconds = ce_util_getCurSeconds;
|
|
|
|
vtable->m_util_makeEmptyDict = ce_util_makeEmptyDict;
|
|
|
|
vtable->m_util_getUserString = ce_util_getUserString;
|
|
|
|
vtable->m_util_warnIllegalWord = ce_util_warnIllegalWord;
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-07-23 17:31:21 +02:00
|
|
|
vtable->m_util_addrChange = ce_util_addrChange;
|
2005-08-21 16:36:11 +02:00
|
|
|
vtable->m_util_makeStreamFromAddr = ce_util_makeStreamFromAddr;
|
2005-07-23 17:31:21 +02:00
|
|
|
#endif
|
2004-07-10 19:46:36 +02:00
|
|
|
#ifdef XWFEATURE_SEARCHLIMIT
|
|
|
|
vtable->m_util_getTraySearchLimits = ce_util_getTraySearchLimits;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
#ifdef SHOW_PROGRESS
|
|
|
|
vtable->m_util_engineStarting = ce_util_engineStarting;
|
|
|
|
vtable->m_util_engineStopping = ce_util_engineStopping;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} /* ceInitUtilFuncs */
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
2005-06-13 16:29:49 +02:00
|
|
|
# define SCROLL_SHRINK 1
|
2006-05-14 17:28:57 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
updateScrollInfo( HWND hwnd, XP_U16 nHidden )
|
|
|
|
{
|
|
|
|
SCROLLINFO sinfo;
|
|
|
|
|
|
|
|
XP_MEMSET( &sinfo, 0, sizeof(sinfo) );
|
|
|
|
sinfo.cbSize = sizeof(sinfo);
|
|
|
|
sinfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
|
|
|
|
sinfo.nPos = 0;
|
|
|
|
sinfo.nMin = 0;
|
|
|
|
sinfo.nMax = nHidden;
|
|
|
|
sinfo.nPage = 1;
|
|
|
|
|
|
|
|
(void)SetScrollInfo( hwnd, SB_CTL, &sinfo, TRUE );
|
|
|
|
}
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
static void
|
2005-06-13 16:29:49 +02:00
|
|
|
showScroller( CEAppGlobals* globals, XP_U16 nHidden, XP_U16 x, XP_U16 y,
|
|
|
|
XP_U16 width, XP_U16 height )
|
2005-02-05 22:43:16 +01:00
|
|
|
{
|
2006-05-14 17:28:57 +02:00
|
|
|
if ( !!globals->scrollHandle ) {
|
|
|
|
DestroyWindow( globals->scrollHandle );
|
|
|
|
globals->scrollHandle = NULL;
|
|
|
|
}
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
if ( !globals->scrollHandle ) {
|
|
|
|
HWND hwndSB;
|
2005-06-13 16:29:49 +02:00
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
hwndSB = CreateWindow( TEXT("SCROLLBAR"), // Class name
|
|
|
|
NULL, // Window text
|
|
|
|
// Window style
|
|
|
|
SBS_VERT|WS_VISIBLE|WS_CHILD,
|
2005-06-13 16:29:49 +02:00
|
|
|
x + SCROLL_SHRINK, y,
|
|
|
|
width - SCROLL_SHRINK, height + 1,
|
2005-02-05 22:43:16 +01:00
|
|
|
globals->hWnd,
|
|
|
|
(HMENU)SCROLLBARID,// The control identifier
|
|
|
|
globals->hInst, // The instance handle
|
|
|
|
NULL ); // s'pposed to be NULL
|
|
|
|
|
2006-05-14 17:28:57 +02:00
|
|
|
updateScrollInfo( hwndSB, nHidden );
|
2005-06-13 16:29:49 +02:00
|
|
|
|
2006-05-14 17:28:57 +02:00
|
|
|
EnableWindow( hwndSB, nHidden > 0 );
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
globals->scrollHandle = hwndSB;
|
|
|
|
}
|
2005-06-13 16:29:49 +02:00
|
|
|
|
|
|
|
ShowWindow( globals->scrollHandle, SW_SHOW );
|
|
|
|
} /* showScroller */
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
hideScroller( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
if ( !!globals->scrollHandle ) {
|
|
|
|
ShowWindow( globals->scrollHandle, SW_HIDE );
|
|
|
|
}
|
|
|
|
/* else there's nothing to do */
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct CEBoardParms {
|
|
|
|
XP_U16 boardHScale;
|
|
|
|
XP_U16 boardVScale;
|
2006-05-09 04:01:27 +02:00
|
|
|
XP_U16 boardTop;
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_U16 trayTop;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
XP_U16 trayHeight;
|
|
|
|
XP_U16 trayWidth;
|
|
|
|
|
|
|
|
XP_U16 timerLeft, timerTop, timerWidth, timerHeight;
|
|
|
|
|
|
|
|
XP_U16 boardLeft, trayLeft;
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_U16 scoreWidth;
|
|
|
|
XP_U16 scoreHeight;
|
|
|
|
XP_Bool needsScroller;
|
2006-05-09 04:01:27 +02:00
|
|
|
XP_Bool horiz;
|
2005-02-05 22:43:16 +01:00
|
|
|
} CEBoardParms;
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
static XP_U16
|
|
|
|
sizeBoard( XP_U16* bdHeightP, /* INOUT */
|
|
|
|
XP_U16* nRowsP, /* INOUT: on OUT, gives nRowsVisible */
|
|
|
|
XP_U16* scrollWidthP )
|
|
|
|
{
|
|
|
|
/* given the initial max board height, figure how many rows are visible
|
|
|
|
and the adjusted heights of the board and tray. */
|
|
|
|
XP_U16 bdHeight = *bdHeightP;
|
|
|
|
XP_U16 nVisibleRows = *nRowsP;
|
|
|
|
XP_U16 vScale;
|
|
|
|
XP_U16 boardHtLimit;
|
|
|
|
|
|
|
|
*scrollWidthP = 0;
|
|
|
|
|
|
|
|
vScale = bdHeight / nVisibleRows;
|
|
|
|
if ( vScale < MIN_CELL_HEIGHT ) {
|
|
|
|
vScale = MIN_CELL_HEIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now adjust tray height to make board height a multiple */
|
|
|
|
boardHtLimit = nVisibleRows * vScale;
|
|
|
|
while ( boardHtLimit > bdHeight ) {
|
|
|
|
boardHtLimit -= vScale;
|
|
|
|
--nVisibleRows;
|
|
|
|
*scrollWidthP = SCROLLBAR_WIDTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
*bdHeightP = boardHtLimit;
|
|
|
|
*nRowsP = nVisibleRows;
|
|
|
|
return vScale;
|
|
|
|
} /* sizeBoard */
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
static void
|
2006-05-09 04:01:27 +02:00
|
|
|
figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
2005-02-05 22:43:16 +01:00
|
|
|
{
|
|
|
|
RECT rc;
|
2006-05-09 04:01:27 +02:00
|
|
|
XP_U16 scrnWidth, scrnHeight;
|
|
|
|
XP_U16 trayVScale, boardLeft, scoreWidth, scoreHeight;
|
2006-05-11 05:01:39 +02:00
|
|
|
XP_U16 boardHt, boardWidth, hScale, vScale, nVisibleRows;
|
2006-05-12 09:17:35 +02:00
|
|
|
XP_U16 trayTop, boardTop;
|
2006-05-09 04:01:27 +02:00
|
|
|
XP_Bool horiz;
|
|
|
|
XP_U16 trayWidth;
|
|
|
|
XP_U16 scrollWidth = 0;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
GetClientRect( globals->hWnd, &rc );
|
2006-05-09 04:01:27 +02:00
|
|
|
#ifndef _WIN32_WCE
|
2008-01-20 16:36:17 +01:00
|
|
|
# if defined FORCE_HEIGHT && defined FORCE_WIDTH
|
2006-05-12 09:54:59 +02:00
|
|
|
rc.right = rc.left + FORCE_WIDTH;
|
|
|
|
rc.bottom = rc.top + FORCE_HEIGHT;
|
2008-01-20 16:36:17 +01:00
|
|
|
# else
|
|
|
|
# if defined DEBUG
|
2006-06-11 22:12:20 +02:00
|
|
|
|
2006-05-12 09:54:59 +02:00
|
|
|
if ( g_dbWidth != 0 ) {
|
|
|
|
rc.right = rc.left + g_dbWidth;
|
|
|
|
}
|
|
|
|
if ( g_dbHeight != 0 ) {
|
|
|
|
rc.bottom = rc.top + g_dbHeight;
|
2006-05-09 04:01:27 +02:00
|
|
|
}
|
2008-01-20 16:36:17 +01:00
|
|
|
# endif
|
|
|
|
# endif
|
|
|
|
#endif /* #ifndef _WIN32_WCE */
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
scrnWidth = (XP_U16)(rc.right - rc.left);
|
|
|
|
scrnHeight = (XP_U16)(rc.bottom - rc.top);
|
|
|
|
|
|
|
|
horiz = (scrnHeight - CE_SCORE_HEIGHT) >= (scrnWidth - CE_MIN_SCORE_WIDTH);
|
|
|
|
nVisibleRows = nRows;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
2006-05-11 05:01:39 +02:00
|
|
|
scoreHeight = horiz? CE_SCORE_HEIGHT : 0;
|
2006-05-09 04:01:27 +02:00
|
|
|
boardTop = scoreHeight;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
/* Try to make it fit without scrolling. But if necessary, reduce the
|
|
|
|
width for a scrollbar. */
|
2006-05-09 04:01:27 +02:00
|
|
|
boardHt = scrnHeight - scoreHeight - MIN_TRAY_HEIGHT;
|
|
|
|
vScale = sizeBoard( &boardHt, &nVisibleRows, &scrollWidth );
|
|
|
|
|
|
|
|
boardWidth = scrnWidth - scrollWidth;
|
|
|
|
if ( horiz ) {
|
|
|
|
scoreWidth = scrnWidth;
|
|
|
|
hScale = boardWidth / nRows;
|
2006-05-12 09:54:59 +02:00
|
|
|
boardWidth = nRows * hScale;
|
2006-05-09 04:01:27 +02:00
|
|
|
/* center the board */
|
|
|
|
boardWidth += scrollWidth;
|
|
|
|
boardLeft = (scrnWidth - boardWidth) / 2; /* center it all */
|
|
|
|
} else {
|
|
|
|
/* move extra pixels into scoreboard */
|
|
|
|
hScale = (boardWidth - CE_MIN_SCORE_WIDTH) / nRows;
|
|
|
|
boardWidth = hScale * nRows;
|
|
|
|
scoreWidth = scrnWidth - boardWidth - scrollWidth;
|
|
|
|
boardLeft = scoreWidth;
|
2005-02-05 22:43:16 +01:00
|
|
|
}
|
2006-05-11 05:01:39 +02:00
|
|
|
trayWidth = boardWidth + scrollWidth;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
2006-05-20 08:22:33 +02:00
|
|
|
trayTop = boardHt + scoreHeight + 1;
|
2006-05-09 04:01:27 +02:00
|
|
|
trayVScale = scrnHeight - trayTop;
|
|
|
|
|
|
|
|
if ( !horiz ) {
|
|
|
|
scoreHeight = scrnHeight;
|
2005-02-05 22:43:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( globals->gameInfo.timerEnabled ) {
|
2006-05-09 04:01:27 +02:00
|
|
|
if ( horiz ) {
|
|
|
|
scoreWidth -= CE_TIMER_WIDTH;
|
|
|
|
bparms->timerLeft = scoreWidth;
|
|
|
|
bparms->timerTop = 0;
|
|
|
|
bparms->timerWidth = CE_TIMER_WIDTH;
|
|
|
|
bparms->timerHeight = CE_SCORE_HEIGHT;
|
|
|
|
} else {
|
|
|
|
bparms->timerLeft = 0;
|
|
|
|
bparms->timerHeight = CE_SCORE_HEIGHT * 2;
|
|
|
|
bparms->timerTop = scrnHeight - bparms->timerHeight;
|
|
|
|
bparms->timerWidth = scoreWidth;
|
|
|
|
|
|
|
|
scoreHeight -= bparms->timerHeight;
|
|
|
|
}
|
2005-02-05 22:43:16 +01:00
|
|
|
}
|
2006-05-09 04:01:27 +02:00
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
bparms->boardHScale = hScale;
|
|
|
|
bparms->boardVScale = vScale;
|
2006-05-09 04:01:27 +02:00
|
|
|
bparms->boardTop = boardTop;
|
2005-02-05 22:43:16 +01:00
|
|
|
bparms->trayTop = trayTop;
|
2006-05-09 04:01:27 +02:00
|
|
|
bparms->trayHeight = trayVScale;
|
|
|
|
bparms->trayWidth = trayWidth;
|
|
|
|
bparms->boardLeft = boardLeft;
|
|
|
|
bparms->trayLeft = boardLeft;
|
2005-02-05 22:43:16 +01:00
|
|
|
bparms->scoreWidth = scoreWidth;
|
2006-05-09 04:01:27 +02:00
|
|
|
bparms->scoreHeight = scoreHeight;
|
|
|
|
bparms->horiz = horiz;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
2006-05-11 05:01:39 +02:00
|
|
|
globals->nHiddenRows = nRows - nVisibleRows;
|
2006-05-09 04:01:27 +02:00
|
|
|
bparms->needsScroller = nVisibleRows < nRows;
|
|
|
|
if ( bparms->needsScroller ) {
|
|
|
|
XP_U16 boardRight = boardLeft + (nRows * hScale);
|
2006-05-11 05:01:39 +02:00
|
|
|
showScroller( globals, globals->nHiddenRows,
|
|
|
|
boardRight, boardTop,
|
|
|
|
scrollWidth, boardHt );
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_LOGF( "NEEDING SCROLLBAR!!!!" );
|
2006-05-11 05:01:39 +02:00
|
|
|
XP_LOGF( "%d rows hidden", globals->nHiddenRows );
|
2005-02-05 22:43:16 +01:00
|
|
|
} else {
|
|
|
|
hideScroller( globals );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} /* figureBoardParms */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool
|
|
|
|
cePositionBoard( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool erase = XP_FALSE;
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_U16 nCols;
|
|
|
|
CEBoardParms bparms;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
XP_ASSERT( !!globals->game.model );
|
|
|
|
nCols = model_numCols( globals->game.model );
|
|
|
|
XP_ASSERT( nCols <= CE_MAX_ROWS );
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
figureBoardParms( globals, nCols, &bparms );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
if ( globals->gameInfo.timerEnabled ) {
|
|
|
|
board_setTimerLoc( globals->game.board, bparms.timerLeft,
|
|
|
|
bparms.timerTop, bparms.timerWidth,
|
|
|
|
bparms.timerHeight );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
board_setPos( globals->game.board, bparms.boardLeft,
|
|
|
|
bparms.boardTop, XP_FALSE );
|
2006-05-11 05:01:39 +02:00
|
|
|
board_setScale( globals->game.board, bparms.boardHScale,
|
|
|
|
bparms.boardVScale );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
board_setScoreboardLoc( globals->game.board, CE_SCORE_LEFT,
|
2005-02-05 22:43:16 +01:00
|
|
|
CE_SCORE_TOP, bparms.scoreWidth,
|
2006-05-09 04:01:27 +02:00
|
|
|
bparms.scoreHeight, bparms.horiz );
|
2003-11-20 17:26:35 +01:00
|
|
|
board_setShowColors( globals->game.board, globals->appPrefs.showColors );
|
2005-01-23 09:15:29 +01:00
|
|
|
board_setYOffset( globals->game.board, 0 );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
board_prefsChanged( globals->game.board, &globals->appPrefs.cp );
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
board_setTrayLoc( globals->game.board, bparms.trayLeft, bparms.trayTop,
|
|
|
|
bparms.trayWidth, bparms.trayHeight, CE_DIVIDER_WIDTH );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
server_prefsChanged( globals->game.server, &globals->appPrefs.cp );
|
|
|
|
|
|
|
|
return erase;
|
|
|
|
} /* cePositionBoard */
|
|
|
|
|
|
|
|
/* Set the title to be app-name COLON file-name. If there's no colon there
|
|
|
|
* now append colon and game name. Else if there is a color replace what
|
|
|
|
* follows it with the new name.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ceSetTitleFromName( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
wchar_t widebuf[256];
|
|
|
|
wchar_t* colonPos;
|
|
|
|
XP_UCHAR* baseStart;
|
|
|
|
XP_UCHAR* gameName;
|
|
|
|
|
|
|
|
XP_U16 len = (XP_U16)SendMessage( globals->hWnd, WM_GETTEXT,
|
|
|
|
sizeof(widebuf), (long)widebuf );
|
|
|
|
colonPos = wcsstr( widebuf, L":" );
|
|
|
|
|
|
|
|
if ( colonPos == NULL ) {
|
|
|
|
wcscat( widebuf, L":" );
|
|
|
|
colonPos = widebuf + len; /* we'll write at the end */
|
|
|
|
}
|
|
|
|
++colonPos; /* skip the colon */
|
|
|
|
|
|
|
|
gameName = globals->curGameName;
|
|
|
|
baseStart = strrchr( gameName, '\\' );
|
|
|
|
++baseStart;
|
|
|
|
len = (XP_U16)XP_STRLEN( baseStart );
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, baseStart, len + 1,
|
|
|
|
colonPos, len + 1 );
|
|
|
|
|
|
|
|
/* now get rid of the ".xwg" */
|
|
|
|
colonPos = wcsrchr( widebuf, '.' );
|
|
|
|
if ( colonPos != NULL ) {
|
|
|
|
*colonPos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SendMessage( globals->hWnd, WM_SETTEXT, 0, (long)widebuf );
|
|
|
|
} /* ceSetTitleFromName */
|
|
|
|
|
|
|
|
static void
|
2008-02-16 17:02:49 +01:00
|
|
|
ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame,
|
|
|
|
const CommsAddrRec* XP_UNUSED_STANDALONE(addr) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
DictionaryCtxt* dict;
|
|
|
|
XP_UCHAR* newDictName = globals->gameInfo.dictName;
|
|
|
|
|
|
|
|
/* This needs to happen even when !newGame because it's how the dict
|
|
|
|
slots in PlayerInfo get loaded. That really ought to happen earlier,
|
|
|
|
though. */
|
|
|
|
XP_ASSERT( !!globals->game.model );
|
|
|
|
dict = model_getDictionary( globals->game.model );
|
|
|
|
|
|
|
|
if ( !!dict ) {
|
2006-10-22 21:44:30 +02:00
|
|
|
const XP_UCHAR* curDictName = dict_getName( dict );
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( !!newDictName &&
|
|
|
|
( !curDictName || 0 != strcmp( curDictName, newDictName ) ) ) {
|
|
|
|
dict_destroy( dict );
|
|
|
|
dict = NULL;
|
|
|
|
} else {
|
2006-09-15 09:39:57 +02:00
|
|
|
replaceStringIfDifferent( globals->mpool,
|
|
|
|
&globals->gameInfo.dictName,
|
2003-11-20 17:26:35 +01:00
|
|
|
curDictName );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !dict ) {
|
|
|
|
#ifdef STUBBED_DICT
|
|
|
|
dict = make_stubbed_dict( MPPARM_NOCOMMA(globals->mpool) );
|
|
|
|
#else
|
2004-01-17 23:10:23 +01:00
|
|
|
XP_ASSERT( !!newDictName );
|
2006-05-30 07:12:02 +02:00
|
|
|
XP_LOGF( "calling ce_dictionary_make" );
|
2006-04-25 06:25:08 +02:00
|
|
|
dict = ce_dictionary_make( globals, newDictName);
|
2003-11-20 17:26:35 +01:00
|
|
|
#endif
|
|
|
|
XP_ASSERT( !!dict );
|
|
|
|
model_setDictionary( globals->game.model, dict );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( newGame ) {
|
|
|
|
XP_U16 newGameID = 0;
|
2005-06-13 16:29:49 +02:00
|
|
|
game_reset( MEMPOOL &globals->game, &globals->gameInfo, &globals->util,
|
2005-07-30 04:02:49 +02:00
|
|
|
newGameID, &globals->appPrefs.cp, CE_SEND_PROC,
|
2007-12-03 02:18:13 +01:00
|
|
|
CE_RESET_PROC globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-10-28 16:56:04 +02:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2005-07-23 17:31:21 +02:00
|
|
|
if ( !!addr ) {
|
2005-08-21 16:07:29 +02:00
|
|
|
XP_ASSERT( globals->game.comms != NULL );
|
2005-07-23 17:31:21 +02:00
|
|
|
comms_setAddr( globals->game.comms, addr );
|
|
|
|
}
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
XP_ASSERT( !!globals->game.board );
|
2008-03-15 16:39:58 +01:00
|
|
|
ceSizeIfFullscreen( globals, globals->hWnd );
|
2003-11-20 17:26:35 +01:00
|
|
|
(void)cePositionBoard( globals );
|
|
|
|
|
|
|
|
board_invalAll( globals->game.board );
|
|
|
|
InvalidateRect( globals->hWnd, NULL, TRUE /* erase */ );
|
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-08-21 16:36:11 +02:00
|
|
|
if ( newGame && globals->gameInfo.serverRole == SERVER_ISCLIENT ) {
|
|
|
|
XWStreamCtxt* stream;
|
|
|
|
XP_ASSERT( !!globals->game.comms );
|
|
|
|
stream = make_generic_stream( globals );
|
|
|
|
stream_setOnCloseProc( stream, ce_send_on_close );
|
|
|
|
server_initClientConnection( globals->game.server, stream );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-03-10 02:47:46 +01:00
|
|
|
ceSetLeftSoftkey( globals, ID_MOVE_TURNDONE );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
server_do( globals->game.server );
|
|
|
|
|
|
|
|
globals->isNewGame = FALSE;
|
|
|
|
} /* ceInitAndStartBoard */
|
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
void
|
2006-01-31 07:41:16 +01:00
|
|
|
logLastError( const char* comment )
|
2004-01-30 06:48:24 +01:00
|
|
|
{
|
|
|
|
LPVOID lpMsgBuf;
|
|
|
|
DWORD lastErr = GetLastError();
|
|
|
|
XP_UCHAR msg[256];
|
|
|
|
XP_U16 len;
|
|
|
|
XP_U16 lenSoFar;
|
|
|
|
|
2006-05-12 09:17:35 +02:00
|
|
|
sprintf( msg, "%s (err: %ld): ", comment, lastErr );
|
2004-01-30 06:48:24 +01:00
|
|
|
lenSoFar = strlen( msg );
|
|
|
|
|
|
|
|
FormatMessage(
|
|
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
NULL,
|
|
|
|
lastErr,
|
|
|
|
0, // Default language
|
|
|
|
(LPTSTR) &lpMsgBuf,
|
|
|
|
0,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
len = wcslen( lpMsgBuf );
|
|
|
|
if ( len >= sizeof(msg)-lenSoFar ) {
|
|
|
|
len = sizeof(msg) - lenSoFar - 1;
|
|
|
|
}
|
|
|
|
WideCharToMultiByte( CP_ACP, 0, lpMsgBuf, len + 1,
|
|
|
|
msg + lenSoFar, len + 1, NULL, NULL );
|
|
|
|
LocalFree( lpMsgBuf );
|
|
|
|
|
|
|
|
XP_LOGF( "system error: %s", msg );
|
|
|
|
} /* logLastError */
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ceSavePrefs( CEAppGlobals* globals )
|
|
|
|
{
|
2004-01-30 06:48:24 +01:00
|
|
|
HANDLE fileH;
|
|
|
|
|
|
|
|
fileH = CreateFile( PREFSFILENAME, GENERIC_WRITE, 0, NULL,
|
|
|
|
OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL );
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( fileH != INVALID_HANDLE_VALUE ) {
|
|
|
|
XP_U32 nWritten;
|
|
|
|
XP_U16 nameLen = 0;
|
|
|
|
XP_UCHAR* name = globals->curGameName;
|
|
|
|
|
|
|
|
if ( name != NULL ) {
|
|
|
|
nameLen = (XP_U16)XP_STRLEN( name );
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFilePointer( fileH, 0, 0, FILE_BEGIN );
|
|
|
|
/* write prefs, including version num */
|
|
|
|
WriteFile( fileH, &globals->appPrefs, sizeof(globals->appPrefs),
|
|
|
|
&nWritten, NULL );
|
2008-03-15 16:39:58 +01:00
|
|
|
XP_DEBUGF( "sizeof(appPrefs) => %d", sizeof( globals->appPrefs ) );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
WriteFile( fileH, &nameLen, sizeof(nameLen), &nWritten, NULL );
|
|
|
|
WriteFile( fileH, name, nameLen, &nWritten, NULL );
|
|
|
|
|
2006-05-05 14:51:08 +02:00
|
|
|
WriteFile( fileH, &globals->flags, sizeof(globals->flags), &nWritten,
|
|
|
|
NULL );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
SetEndOfFile( fileH ); /* truncate anything previously there */
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
CloseHandle( fileH ); /* am I not supposed to do this? PENDING */
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_DEBUGF( "ceSavePrefs: prefs file written" );
|
2004-01-30 06:48:24 +01:00
|
|
|
} else {
|
2005-06-13 16:29:49 +02:00
|
|
|
logLastError( "failed to create prefs file" );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
} /* ceSavePrefs */
|
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
static XP_Bool
|
|
|
|
peekVersion( HANDLE fileH, XP_U16* version )
|
|
|
|
{
|
|
|
|
XP_Bool success = XP_FALSE;
|
|
|
|
XP_U32 nRead;
|
|
|
|
success = ReadFile( fileH, version, sizeof(*version), &nRead, NULL );
|
|
|
|
if ( success ) {
|
|
|
|
SetFilePointer( fileH, -nRead, 0, FILE_CURRENT );
|
|
|
|
}
|
|
|
|
return success;
|
|
|
|
} /* peekVersion */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
canUpdatePrefs( CEAppGlobals* globals, HANDLE fileH, XP_U16 curVersion,
|
|
|
|
CEAppPrefs* prefs )
|
|
|
|
{
|
|
|
|
XP_Bool success = XP_FALSE;
|
|
|
|
LOG_FUNC();
|
|
|
|
if ( (curVersion == 0x0002) && (CUR_CE_PREFS_FLAGS == 0x0003) ) {
|
|
|
|
CEAppPrefs0002 oldPrefs;
|
|
|
|
XP_U32 nRead;
|
|
|
|
if ( ReadFile( fileH, &oldPrefs, sizeof(oldPrefs), &nRead, NULL ) ) {
|
|
|
|
ceInitPrefs( globals, prefs );
|
|
|
|
|
|
|
|
XP_MEMCPY( &prefs->cp, &oldPrefs.cp, sizeof(prefs->cp) );
|
|
|
|
prefs->showColors = oldPrefs.showColors;
|
|
|
|
|
|
|
|
XP_MEMCPY( &prefs->colors[0], &oldPrefs.colors[0],
|
|
|
|
CE_FOCUS_COLOR*sizeof(prefs->colors[0]));
|
|
|
|
XP_ASSERT( CE_USER_COLOR1 - 1 == CE_FOCUS_COLOR );
|
|
|
|
XP_MEMCPY( &prefs->colors[CE_USER_COLOR1],
|
|
|
|
&oldPrefs.colors[CE_FOCUS_COLOR],
|
|
|
|
(CE_NUM_COLORS-CE_USER_COLOR1)
|
|
|
|
* sizeof(prefs->colors[0]));
|
|
|
|
success = XP_TRUE;
|
|
|
|
} else {
|
|
|
|
XP_LOGF( "%s: ReadFile bad", __func__ );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
XP_LOGF( "%s: can't convert from %d to %d", __func__,
|
|
|
|
curVersion, CUR_CE_PREFS_FLAGS );
|
|
|
|
}
|
|
|
|
LOG_RETURNF( "%d", (int)success );
|
|
|
|
return success;
|
|
|
|
} /* canUpdatePrefs */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool
|
|
|
|
ceLoadPrefs( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool result = XP_FALSE;
|
2004-01-30 06:48:24 +01:00
|
|
|
HANDLE fileH;
|
|
|
|
|
|
|
|
fileH = CreateFile( PREFSFILENAME, GENERIC_READ, 0, NULL,
|
|
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( fileH != INVALID_HANDLE_VALUE ) {
|
|
|
|
XP_U32 fileSize = GetFileSize( fileH, NULL );
|
2008-02-23 23:06:05 +01:00
|
|
|
XP_U16 curVersion;
|
|
|
|
if ( fileSize >= sizeof(curVersion) && peekVersion( fileH, &curVersion ) ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
CEAppPrefs tmpPrefs;
|
2008-02-23 23:06:05 +01:00
|
|
|
if ( curVersion == CUR_CE_PREFS_FLAGS ) {
|
|
|
|
if ( fileSize >= sizeof( CEAppPrefs ) ) {
|
|
|
|
XP_U32 bytesRead;
|
|
|
|
if ( ReadFile( fileH, &tmpPrefs, sizeof(tmpPrefs),
|
|
|
|
&bytesRead, NULL ) ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
XP_ASSERT( tmpPrefs.versionFlags == CUR_CE_PREFS_FLAGS ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
result = XP_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( canUpdatePrefs( globals, fileH, curVersion, &tmpPrefs ) ) {
|
|
|
|
result = XP_TRUE;
|
|
|
|
} else {
|
|
|
|
XP_LOGF( "%s: old prefs; cannot read.", __func__ );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
if ( result ) {
|
|
|
|
XP_U16 flags;
|
|
|
|
XP_U16 nameLen;
|
|
|
|
XP_UCHAR* name;
|
|
|
|
XP_U32 nRead;
|
|
|
|
|
|
|
|
XP_MEMCPY( &globals->appPrefs, &tmpPrefs,
|
2003-11-20 17:26:35 +01:00
|
|
|
sizeof(globals->appPrefs) );
|
2006-05-05 14:51:08 +02:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
ReadFile( fileH, &nameLen, sizeof(nameLen), &nRead,
|
|
|
|
NULL );
|
|
|
|
name = XP_MALLOC( globals->mpool, nameLen + 1 );
|
|
|
|
ReadFile( fileH, name, nameLen, &nRead, NULL );
|
|
|
|
name[nameLen] = '\0';
|
|
|
|
globals->curGameName = name;
|
|
|
|
|
|
|
|
if ( ReadFile( fileH, &flags, sizeof(flags), &nRead,
|
|
|
|
NULL )
|
|
|
|
&& nRead == sizeof(flags) ) {
|
|
|
|
} else {
|
|
|
|
flags = 0;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2008-02-23 23:06:05 +01:00
|
|
|
globals->flags = flags;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CloseHandle( fileH );
|
2004-01-30 06:48:24 +01:00
|
|
|
} else {
|
|
|
|
XP_LOGF( "ceLoadPrefs: prefs file not found" );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
return result; /* none found */
|
|
|
|
} /* ceLoadPrefs */
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
static XWStreamCtxt*
|
|
|
|
make_generic_stream( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
return mem_stream_make( MPPARM(globals->mpool) globals->vtMgr,
|
|
|
|
globals, 0, NULL );
|
|
|
|
} /* make_generic_stream */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static XWStreamCtxt*
|
|
|
|
fileToStream( CEAppGlobals* globals, XP_UCHAR* path )
|
|
|
|
{
|
|
|
|
XWStreamCtxt* stream = NULL;
|
|
|
|
HANDLE fileH;
|
|
|
|
wchar_t widebuf[257];
|
|
|
|
XP_U16 len;
|
|
|
|
|
|
|
|
len = (XP_U16)XP_STRLEN( path );
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, path, len + 1,
|
|
|
|
widebuf, len + 1 );
|
|
|
|
|
|
|
|
fileH = CreateFile( widebuf, GENERIC_READ, 0, NULL,
|
|
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
|
|
|
|
|
|
if ( fileH != INVALID_HANDLE_VALUE ) {
|
|
|
|
XP_U32 len = GetFileSize( fileH, NULL );
|
|
|
|
XP_U32 nRead;
|
|
|
|
XP_UCHAR* buf = XP_MALLOC( globals->mpool, len );
|
|
|
|
|
|
|
|
XP_DEBUGF( "fileSize = %ld", len );
|
|
|
|
|
|
|
|
ReadFile( fileH, buf, len, &nRead, NULL );
|
|
|
|
CloseHandle( fileH );
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
stream = make_generic_stream( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
stream_open( stream );
|
|
|
|
stream_putBytes( stream, buf, (XP_U16)nRead );
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, buf );
|
|
|
|
}
|
|
|
|
|
|
|
|
XP_DEBUGF( "fileToStream => 0x%lx", (unsigned long)stream );
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
} /* fileToStream */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ceLoadSavedGame( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool success = XP_FALSE;
|
|
|
|
XWStreamCtxt* stream;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
LOG_FUNC();
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
stream = fileToStream( globals, globals->curGameName );
|
|
|
|
success = stream != NULL;
|
|
|
|
if ( success ) {
|
|
|
|
DictionaryCtxt* dict;
|
|
|
|
XP_Bool hasDict;
|
|
|
|
|
|
|
|
hasDict = stream_getU8( stream );
|
|
|
|
if ( hasDict ) {
|
2004-01-17 23:10:23 +01:00
|
|
|
#ifdef STUBBED_DICT
|
|
|
|
XP_ASSERT(0); /* just don't do this!!!! */
|
|
|
|
#else
|
2007-03-19 00:31:51 +01:00
|
|
|
XP_UCHAR* name = stringFromStream( globals->mpool, stream );
|
2003-11-20 17:26:35 +01:00
|
|
|
dict = ce_dictionary_make( globals, name );
|
2006-05-30 07:12:02 +02:00
|
|
|
XP_FREE( globals->mpool, name );
|
2005-06-30 03:48:07 +02:00
|
|
|
success = dict != NULL;
|
2004-01-17 23:10:23 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} else {
|
|
|
|
dict = NULL;
|
|
|
|
}
|
|
|
|
|
2005-06-30 03:48:07 +02:00
|
|
|
if ( success ) {
|
|
|
|
XP_DEBUGF( "calling game_makeFromStream" );
|
|
|
|
game_makeFromStream( MEMPOOL stream, &globals->game,
|
|
|
|
&globals->gameInfo,
|
|
|
|
dict, &globals->util, globals->draw,
|
2007-12-03 02:18:13 +01:00
|
|
|
&globals->appPrefs.cp, CE_SEND_PROC,
|
|
|
|
CE_RESET_PROC globals );
|
2005-06-30 03:48:07 +02:00
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
stream_destroy( stream );
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
} /* ceLoadSavedGame */
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
static void
|
2008-02-23 23:06:05 +01:00
|
|
|
colorsFromRsrc( const CEAppGlobals* globals, CEAppPrefs* prefs )
|
2004-03-28 03:14:34 +02:00
|
|
|
{
|
|
|
|
XP_U16 i;
|
|
|
|
HGLOBAL globH;
|
|
|
|
HRSRC rsrcH;
|
|
|
|
XP_U16* ptr;
|
|
|
|
|
|
|
|
rsrcH = FindResource( globals->hInst, MAKEINTRESOURCE(ID_COLORS_RES),
|
|
|
|
TEXT("CLRS") );
|
|
|
|
globH = LoadResource( globals->hInst, rsrcH );
|
|
|
|
ptr = (XP_U16*)globH;
|
|
|
|
|
2007-01-19 07:43:52 +01:00
|
|
|
for ( i = 0; i < CE_NUM_COLORS; ++i ) {
|
2004-03-28 03:14:34 +02:00
|
|
|
XP_U8 r = (XP_U8)*ptr++;
|
|
|
|
XP_U8 g = (XP_U8)*ptr++;
|
|
|
|
XP_U8 b = (XP_U8)*ptr++;
|
2008-02-23 23:06:05 +01:00
|
|
|
prefs->colors[i] = RGB( r, g, b );
|
2004-03-28 03:14:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DeleteObject( globH );
|
|
|
|
} /* colorsFromRsrc */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
2008-02-23 23:06:05 +01:00
|
|
|
ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2008-02-23 23:06:05 +01:00
|
|
|
prefs->versionFlags = CUR_CE_PREFS_FLAGS;
|
|
|
|
prefs->showColors = XP_TRUE;
|
|
|
|
prefs->fullScreen = XP_FALSE;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
prefs->cp.showBoardArrow = XP_TRUE;
|
|
|
|
prefs->cp.showRobotScores = XP_FALSE;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
2008-02-23 23:06:05 +01:00
|
|
|
colorsFromRsrc( globals, prefs );
|
2006-05-05 14:51:08 +02:00
|
|
|
|
|
|
|
#ifdef DICTS_MOVED_ALERT
|
|
|
|
/* The assumption is that if you didn't have prefs already you don't need
|
|
|
|
to be told to move dicts. */
|
|
|
|
globals->flags = FLAGS_BIT_SHOWN_NEWDICTLOC;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ceInitPrefs */
|
|
|
|
|
2006-05-05 14:51:08 +02:00
|
|
|
#ifdef DICTS_MOVED_ALERT
|
|
|
|
static void
|
|
|
|
doDictsMovedAlert( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool hide;
|
|
|
|
|
|
|
|
XWStreamCtxt* stream = make_generic_stream( globals );
|
|
|
|
|
|
|
|
stream_putString( stream,
|
|
|
|
"Please be aware that starting with this version "
|
|
|
|
"Crosswords will not find dictionaries unless they "
|
|
|
|
"are located in one of these directories: " );
|
|
|
|
ceFormatDictDirs( stream, globals->hInst );
|
|
|
|
stream_putString( stream, ". From now on, dictionaries will be "
|
|
|
|
"available as .cab files which will put them in the "
|
|
|
|
"right place."
|
|
|
|
XP_CR
|
|
|
|
XP_CR
|
|
|
|
"Do you want to disable this warning?" );
|
|
|
|
|
|
|
|
hide = ceMsgFromStream( globals, stream, L"Warning", XP_TRUE, XP_TRUE );
|
|
|
|
|
|
|
|
if ( hide ) {
|
|
|
|
globals->flags |= FLAGS_BIT_SHOWN_NEWDICTLOC;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
#ifdef _WIN32_WCE
|
|
|
|
static void
|
|
|
|
getOSInfo( CEAppGlobals* globals )
|
|
|
|
{
|
2008-03-15 16:39:58 +01:00
|
|
|
OSVERSIONINFO ver = {0};
|
2008-02-16 18:36:46 +01:00
|
|
|
TCHAR buf[128];
|
2008-03-15 16:39:58 +01:00
|
|
|
XW_WinceVersion winceVersion = WINCE_UNKNOWN;
|
2008-02-16 18:36:46 +01:00
|
|
|
|
2008-03-15 16:39:58 +01:00
|
|
|
if ( GetVersionEx( &ver )) {
|
|
|
|
XP_LOGF( "version = %ld.%ld", ver.dwMajorVersion, ver.dwMinorVersion );
|
|
|
|
} else {
|
|
|
|
XP_WARNF( "GetVersionEx failed" );
|
|
|
|
}
|
2008-02-16 18:36:46 +01:00
|
|
|
|
|
|
|
if ( SystemParametersInfo( SPI_GETPLATFORMTYPE, sizeof(buf), buf, FALSE ) ) {
|
2008-03-15 16:39:58 +01:00
|
|
|
if ( 0 == lstrcmp( buf, L"PocketPC") ) {
|
2008-02-16 18:36:46 +01:00
|
|
|
// We are on a Pocket PC, so check the OS version,
|
|
|
|
// Pocket PC 2003 used WinCE 4.2
|
2008-03-15 16:39:58 +01:00
|
|
|
if ( ver.dwMajorVersion < 4 ) {
|
|
|
|
winceVersion = WINCE_PPC_V1;
|
|
|
|
} else if ( ver.dwMajorVersion == 4 ) {
|
|
|
|
winceVersion = WINCE_PPC_2003;
|
2008-02-16 18:36:46 +01:00
|
|
|
} else if ( ver.dwMajorVersion > 4 ) {
|
2008-03-15 16:39:58 +01:00
|
|
|
winceVersion = WINCE_PPC_2005;
|
|
|
|
}
|
|
|
|
} else if ( 0 == lstrcmp( buf, L"SmartPhone") ) {
|
|
|
|
if ( ver.dwMajorVersion < 4 ) {
|
|
|
|
winceVersion = WINCE_SMARTPHONE_V1;
|
|
|
|
} else if ( ver.dwMajorVersion == 4 ) {
|
|
|
|
winceVersion = WINCE_SMARTPHONE_2003;
|
|
|
|
} else if ( ver.dwMajorVersion > 4 ) {
|
|
|
|
winceVersion = WINCE_SMARTPHONE_2005;
|
2008-02-16 18:36:46 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
XP_LOGW( "unknown OS type", buf );
|
|
|
|
}
|
2008-03-15 16:39:58 +01:00
|
|
|
} else if ( GetLastError() == ERROR_ACCESS_DENIED ) {
|
|
|
|
if ( ver.dwMajorVersion < 4 ) {
|
|
|
|
winceVersion = WINCE_SMARTPHONE_V1;
|
|
|
|
} else {
|
|
|
|
winceVersion = WINCE_SMARTPHONE_2003;
|
|
|
|
}
|
2008-02-16 18:36:46 +01:00
|
|
|
}
|
2008-03-15 16:39:58 +01:00
|
|
|
|
|
|
|
XP_ASSERT( winceVersion != WINCE_UNKNOWN );
|
|
|
|
globals->winceVersion = winceVersion;
|
|
|
|
XP_LOGF( "%s: set version to %d", __func__, winceVersion );
|
|
|
|
} /* getOSInfo */
|
2008-02-16 18:36:46 +01:00
|
|
|
#else
|
|
|
|
#define getOSInfo( g )
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
//
|
|
|
|
// FUNCTION: InitInstance(HANDLE, int)
|
|
|
|
//
|
|
|
|
// PURPOSE: Saves instance handle and creates main window
|
|
|
|
//
|
|
|
|
// COMMENTS:
|
|
|
|
//
|
|
|
|
// In this function, we save the instance handle in a global variable and
|
|
|
|
// create and display the main program window.
|
|
|
|
//
|
|
|
|
BOOL
|
|
|
|
InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|
|
|
{
|
|
|
|
HWND hWnd;
|
|
|
|
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
|
|
|
|
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
|
|
|
|
CEAppGlobals* globals;
|
|
|
|
BOOL result = TRUE;
|
2003-12-09 06:18:47 +01:00
|
|
|
XP_Bool oldGameLoaded;
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_Bool prevStateExists;
|
2003-12-09 06:18:47 +01:00
|
|
|
XP_Bool newDone = XP_FALSE;
|
2004-01-30 06:48:24 +01:00
|
|
|
XP_U16 len;
|
2003-11-20 17:26:35 +01:00
|
|
|
MPSLOT;
|
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-11-27 21:16:43 +01:00
|
|
|
{
|
|
|
|
WORD wVersionRequested;
|
|
|
|
WSADATA wsaData;
|
|
|
|
int err;
|
|
|
|
wVersionRequested = MAKEWORD( 2, 2 );
|
|
|
|
err = WSAStartup( wVersionRequested, &wsaData );
|
|
|
|
if ( err != 0 ) {
|
|
|
|
/* Tell the user that we could not find a usable */
|
|
|
|
/* WinSock DLL. */
|
2006-02-06 05:41:14 +01:00
|
|
|
XP_LOGF( "unable to load winsock" );
|
2005-11-27 21:16:43 +01:00
|
|
|
}
|
|
|
|
}
|
2006-02-06 05:41:14 +01:00
|
|
|
#endif
|
2005-11-27 21:16:43 +01:00
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
|
|
|
|
LoadString(hInstance, IDC_XWORDS4, szWindowClass, MAX_LOADSTRING);
|
|
|
|
|
|
|
|
//If it is already running, then focus on the window
|
|
|
|
hWnd = FindWindow( szWindowClass, szTitle);
|
|
|
|
if ( hWnd ) {
|
|
|
|
SetForegroundWindow( (HWND)((ULONG) hWnd | 0x00000001) );
|
2008-02-16 17:02:49 +01:00
|
|
|
result = FALSE;
|
|
|
|
goto exit;
|
2004-01-10 19:11:28 +01:00
|
|
|
}
|
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
(void)CreateDirectory( DEFAULT_DIR_NAME, 0 );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
#ifdef MEM_DEBUG
|
|
|
|
mpool = mpool_make();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
globals = (CEAppGlobals*)XP_MALLOC( mpool, sizeof(*globals) );
|
2008-03-15 16:39:58 +01:00
|
|
|
XP_DEBUGF( "globals created: 0x%p", globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_MEMSET( globals, 0, sizeof(*globals) );
|
|
|
|
MPASSIGN( globals->mpool, mpool );
|
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
getOSInfo( globals );
|
|
|
|
|
2006-05-27 19:18:42 +02:00
|
|
|
#if defined DEBUG && !defined _WIN32_WCE
|
|
|
|
globals->dbWidth = g_dbWidth;
|
|
|
|
globals->dbHeight = g_dbHeight;
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->vtMgr = make_vtablemgr( MPPARM_NOCOMMA(mpool) );
|
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
len = wcslen( DEFAULT_DIR_NAME );
|
|
|
|
len = (len + 1) * sizeof(globals->lastDefaultDir[0]);
|
|
|
|
globals->lastDefaultDir = XP_MALLOC( mpool, len );
|
|
|
|
XP_MEMCPY( globals->lastDefaultDir, DEFAULT_DIR_NAME, len );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->hInst = hInstance;
|
|
|
|
// Initialize global strings
|
|
|
|
MyRegisterClass(hInstance, szWindowClass);
|
|
|
|
|
|
|
|
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
|
|
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT, NULL, NULL, hInstance, globals);
|
|
|
|
globals->hWnd = hWnd;
|
|
|
|
|
2008-02-16 17:02:49 +01:00
|
|
|
if (!hWnd) {
|
|
|
|
result = FALSE;
|
|
|
|
goto exit;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2008-03-15 19:32:22 +01:00
|
|
|
if ( globals->hwndCB && !IS_SMARTPHONE(globals) ) {
|
2004-12-17 08:45:30 +01:00
|
|
|
RECT rc, rcmb;
|
|
|
|
|
|
|
|
GetWindowRect( hWnd, &rc );
|
|
|
|
GetWindowRect( globals->hwndCB, &rcmb );
|
|
|
|
rc.bottom -= (rcmb.bottom - rcmb.top);
|
|
|
|
|
|
|
|
MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left,
|
|
|
|
rc.bottom-rc.top, FALSE);
|
|
|
|
}
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2005-11-28 00:11:05 +01:00
|
|
|
|
|
|
|
#ifdef TARGET_OS_WIN32
|
|
|
|
srand( time(NULL) );
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
ceInitUtilFuncs( globals );
|
|
|
|
|
2006-05-30 07:12:02 +02:00
|
|
|
gi_initPlayerInfo( MPPARM(mpool) &globals->gameInfo, "Player %d" );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
/* choose one. If none found it's an error. */
|
2004-01-17 23:10:23 +01:00
|
|
|
#ifndef STUBBED_DICT
|
2006-04-22 16:05:09 +02:00
|
|
|
result = 1 == ceLocateNDicts( MPPARM(mpool) hInstance, 1, ceSetDictName,
|
|
|
|
globals );
|
2004-01-10 19:11:28 +01:00
|
|
|
if ( !result ) {
|
2006-04-24 06:34:42 +02:00
|
|
|
XWStreamCtxt* stream = make_generic_stream( globals );
|
2006-04-25 15:31:15 +02:00
|
|
|
stream_putString( stream, "Please install a Crosswords dictionary "
|
|
|
|
"in one of these directories: " );
|
2006-04-24 06:34:42 +02:00
|
|
|
ceFormatDictDirs( stream, hInstance );
|
2006-04-25 15:31:15 +02:00
|
|
|
stream_putString( stream, ". Download dictionaries from "
|
|
|
|
"http://xwords.sf.net." );
|
2006-04-24 06:34:42 +02:00
|
|
|
messageBoxStream( globals, stream, L"Dictionary Not Found" );
|
|
|
|
stream_destroy( stream );
|
2008-02-16 17:02:49 +01:00
|
|
|
result = FALSE;
|
|
|
|
goto exit;
|
2004-01-10 19:11:28 +01:00
|
|
|
}
|
2004-01-17 23:10:23 +01:00
|
|
|
#endif
|
2004-01-10 19:11:28 +01:00
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
/* here's where we want to behave differently if there's saved state.
|
|
|
|
But that's a long ways off. */
|
|
|
|
prevStateExists = ceLoadPrefs( globals );
|
2004-04-03 18:39:18 +02:00
|
|
|
if ( !prevStateExists ) {
|
2008-02-23 23:06:05 +01:00
|
|
|
ceInitPrefs( globals, &globals->appPrefs );
|
2006-05-05 14:51:08 +02:00
|
|
|
#ifdef DICTS_MOVED_ALERT
|
|
|
|
} else if ( (globals->flags & FLAGS_BIT_SHOWN_NEWDICTLOC) == 0 ) {
|
|
|
|
doDictsMovedAlert( globals );
|
|
|
|
#endif
|
2004-03-28 03:14:34 +02:00
|
|
|
}
|
2004-04-03 18:39:18 +02:00
|
|
|
/* must load prefs before creating draw ctxt */
|
2004-03-28 03:14:34 +02:00
|
|
|
globals->draw = ce_drawctxt_make( MPPARM(globals->mpool)
|
|
|
|
hWnd, globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-04-03 18:39:18 +02:00
|
|
|
oldGameLoaded = prevStateExists && ceLoadSavedGame( globals );
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
if ( !oldGameLoaded ) {
|
2005-01-21 09:26:32 +01:00
|
|
|
XP_U16 gameID = 0; /* good enough until I get networking going */
|
2003-11-20 17:26:35 +01:00
|
|
|
game_makeNewGame( MPPARM(mpool) &globals->game, &globals->gameInfo,
|
2005-01-21 09:26:32 +01:00
|
|
|
&globals->util, globals->draw, gameID,
|
|
|
|
&globals->appPrefs.cp,
|
2007-12-03 02:18:13 +01:00
|
|
|
CE_SEND_PROC, CE_RESET_PROC globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-08-16 15:44:44 +02:00
|
|
|
newDone = ceDoNewGame( globals ); /* calls ceInitAndStartBoard */
|
2004-01-10 19:11:28 +01:00
|
|
|
if ( !newDone ) {
|
|
|
|
result = FALSE;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowWindow(hWnd, nCmdShow);
|
|
|
|
UpdateWindow(hWnd);
|
2006-02-17 08:30:54 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2003-11-20 17:26:35 +01:00
|
|
|
if (globals->hwndCB) {
|
|
|
|
CommandBar_Show(globals->hwndCB, TRUE);
|
|
|
|
}
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-12-09 06:18:47 +01:00
|
|
|
if ( result && !newDone ) {
|
2008-02-16 17:02:49 +01:00
|
|
|
ceInitAndStartBoard( globals, !oldGameLoaded, NULL );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
2008-02-16 17:02:49 +01:00
|
|
|
exit:
|
2003-11-20 17:26:35 +01:00
|
|
|
return result;
|
|
|
|
} /* InitInstance */
|
|
|
|
|
2006-04-19 06:56:00 +02:00
|
|
|
static XP_Bool
|
2006-08-16 15:44:44 +02:00
|
|
|
ceSetDictName( const wchar_t* XP_UNUSED(wPath), XP_U16 XP_UNUSED_DBG(index),
|
|
|
|
void* XP_UNUSED(ctxt) )
|
2006-04-19 06:56:00 +02:00
|
|
|
{
|
2006-05-30 07:12:02 +02:00
|
|
|
/* CEAppGlobals* globals = (CEAppGlobals*)ctxt; */
|
|
|
|
/* XP_UCHAR* str; */
|
|
|
|
/* XP_UCHAR buf[CE_MAX_PATH_LEN]; */
|
2006-04-19 06:56:00 +02:00
|
|
|
XP_ASSERT( index == 0 ); /* we said one only! */
|
|
|
|
|
2006-05-30 07:12:02 +02:00
|
|
|
/* WideCharToMultiByte( CP_ACP, 0, wPath, -1, */
|
|
|
|
/* buf, sizeof(buf)-1, NULL, NULL ); */
|
2006-04-19 06:56:00 +02:00
|
|
|
|
2007-12-02 20:13:25 +01:00
|
|
|
/* XP_LOGF( "%s: got path \"%s\"", __func__, buf ); */
|
2006-05-30 07:12:02 +02:00
|
|
|
/* str = copyString( MPPARM(globals->mpool) buf ); */
|
2007-12-02 20:13:25 +01:00
|
|
|
/* XP_LOGF( "%s: got %p", __func__, str ); /\* this is leaking *\/ */
|
2006-05-30 07:12:02 +02:00
|
|
|
/* XP_ASSERT( NULL == globals->gameInfo.dictName ); */
|
|
|
|
/* globals->gameInfo.dictName = str; */
|
2006-04-25 06:25:08 +02:00
|
|
|
return XP_FALSE;
|
2006-04-19 06:56:00 +02:00
|
|
|
} /* ceSetDictName */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool
|
|
|
|
ceHandleHintRequest( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool notDone;
|
|
|
|
XP_Bool draw;
|
|
|
|
XP_ASSERT( !!globals->game.board );
|
|
|
|
|
2004-12-11 05:25:45 +01:00
|
|
|
draw = board_requestHint( globals->game.board,
|
|
|
|
#ifdef XWFEATURE_SEARCHLIMIT
|
|
|
|
globals->askTrayLimits,
|
|
|
|
#endif
|
2004-07-10 19:46:36 +02:00
|
|
|
¬Done );
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->hintPending = notDone;
|
2008-02-26 14:49:41 +01:00
|
|
|
if ( draw ) { /* don't turn on if disallowed */
|
|
|
|
ceSetLeftSoftkey( globals, ID_MOVE_NEXTHINT );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
return draw;
|
|
|
|
} /* ceHandleHintRequest */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleTradeCmd( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
return board_beginTrade( globals->game.board );
|
|
|
|
} /* handleTradeCmd */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleJuggleCmd( CEAppGlobals* globals )
|
|
|
|
{
|
2008-03-10 02:47:46 +01:00
|
|
|
ceSetLeftSoftkey( globals, ID_MOVE_JUGGLE );
|
2003-11-20 17:26:35 +01:00
|
|
|
return board_juggleTray( globals->game.board );
|
|
|
|
} /* handleJuggleCmd */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleHidetrayCmd( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XW_TrayVisState curState = board_getTrayVisState( globals->game.board );
|
|
|
|
if ( curState == TRAY_REVEALED ) {
|
|
|
|
return board_hideTray( globals->game.board );
|
|
|
|
} else {
|
|
|
|
return board_showTray( globals->game.board );
|
|
|
|
}
|
|
|
|
} /* handleHidetrayCmd */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleDoneCmd( CEAppGlobals* globals)
|
|
|
|
{
|
|
|
|
return board_commitTurn( globals->game.board );
|
|
|
|
} /* handleDoneCmd */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ceCountsAndValues( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
if ( !!globals->game.server ) {
|
2004-11-09 03:40:36 +01:00
|
|
|
XWStreamCtxt* stream = make_generic_stream( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-12-18 02:03:26 +01:00
|
|
|
server_formatDictCounts( globals->game.server, stream, 3 );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
(void)ceMsgFromStream( globals, stream, L"Tile Counts and Values",
|
|
|
|
XP_FALSE, XP_TRUE );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
} /* ceCountsAndValues */
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
static void
|
|
|
|
ceTilesLeft( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
if ( !!globals->game.board ) {
|
|
|
|
XWStreamCtxt* stream = make_generic_stream( globals );
|
|
|
|
board_formatRemainingTiles( globals->game.board, stream );
|
|
|
|
|
|
|
|
(void)ceMsgFromStream( globals, stream, L"Remaining tiles",
|
|
|
|
XP_FALSE, XP_TRUE );
|
|
|
|
}
|
|
|
|
} /* ceTilesLeft */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ceDoHistory( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool gameOver = server_getGameIsOver(globals->game.server);
|
|
|
|
XWStreamCtxt* stream;
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
stream = make_generic_stream( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
model_writeGameHistory( globals->game.model, stream,
|
|
|
|
globals->game.server, gameOver );
|
2004-02-17 06:00:13 +01:00
|
|
|
(void)ceMsgFromStream( globals, stream, L"Game history",
|
|
|
|
XP_FALSE, XP_TRUE );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ceDoHistory */
|
|
|
|
|
|
|
|
static void
|
2006-05-14 17:28:57 +02:00
|
|
|
drawInsidePaint( CEAppGlobals* globals )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
|
2006-05-14 17:28:57 +02:00
|
|
|
hdc = GetDC( globals->hWnd );
|
2004-02-12 05:35:10 +01:00
|
|
|
if ( !hdc ) {
|
2007-12-02 20:13:25 +01:00
|
|
|
logLastError( __func__ );
|
2004-02-12 05:35:10 +01:00
|
|
|
} else {
|
2004-02-13 14:49:25 +01:00
|
|
|
HDC prevHDC = globals->hdc;
|
2004-02-12 05:35:10 +01:00
|
|
|
globals->hdc = hdc;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-02-12 05:35:10 +01:00
|
|
|
board_draw( globals->game.board );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-02-13 14:49:25 +01:00
|
|
|
globals->hdc = prevHDC;
|
2004-02-12 05:35:10 +01:00
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* drawInsidePaint */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ceDisplayFinalScores( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XWStreamCtxt* stream;
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
stream = make_generic_stream( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
server_writeFinalScores( globals->game.server, stream );
|
|
|
|
stream_putU8( stream, '\0' );
|
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
(void)ceMsgFromStream( globals, stream, L"Final scores",
|
|
|
|
XP_FALSE, XP_TRUE );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ceDisplayFinalScores */
|
|
|
|
|
|
|
|
static XP_Bool
|
2006-08-16 15:44:44 +02:00
|
|
|
ceDoNewGame( CEAppGlobals* globals )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
GameInfoState giState;
|
2005-07-23 17:31:21 +02:00
|
|
|
CommsAddrRec* addr = NULL;
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_Bool changed = XP_FALSE;
|
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
/* What happens if user cancels below? I'm hosed without a name, no?
|
|
|
|
PENDING */
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( globals->curGameName != NULL ) {
|
|
|
|
XP_FREE( globals->mpool, globals->curGameName );
|
|
|
|
globals->curGameName = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
XP_MEMSET( &giState, 0, sizeof(giState) );
|
|
|
|
giState.globals = globals;
|
|
|
|
giState.isNewGame = XP_TRUE;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_GAMEINFO, globals->hWnd,
|
|
|
|
(DLGPROC)GameInfo, (long)&giState );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-01-17 23:10:23 +01:00
|
|
|
if ( !giState.userCancelled
|
|
|
|
#ifndef STUBBED_DICT
|
2006-04-25 06:25:08 +02:00
|
|
|
&& ( giState.newDictName[0] != '\0' )
|
2004-01-17 23:10:23 +01:00
|
|
|
#endif
|
|
|
|
) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( giState.prefsChanged ) {
|
2005-07-23 17:31:21 +02:00
|
|
|
loadCurPrefsFromState( globals, &globals->appPrefs,
|
|
|
|
&globals->gameInfo, &giState.prefsPrefs );
|
2004-05-26 06:48:25 +02:00
|
|
|
if ( giState.colorsChanged ) {
|
|
|
|
updateForColors( globals );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2006-10-28 16:56:04 +02:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2005-07-23 17:31:21 +02:00
|
|
|
if ( giState.addrChanged ) {
|
|
|
|
addr = &giState.prefsPrefs.addrRec;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-02-16 17:02:49 +01:00
|
|
|
ceInitAndStartBoard( globals, XP_TRUE, addr );
|
2003-11-20 17:26:35 +01:00
|
|
|
changed = XP_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return changed;
|
2006-01-31 07:41:16 +01:00
|
|
|
} /* ceDoNewGame */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
ceChooseAndOpen( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
wchar_t path[256];
|
|
|
|
OPENFILENAME openFileStruct;
|
|
|
|
|
|
|
|
XP_MEMSET( &openFileStruct, 0, sizeof(openFileStruct) );
|
|
|
|
XP_MEMSET( path, 0, sizeof(path) );
|
|
|
|
|
|
|
|
openFileStruct.lStructSize = sizeof(openFileStruct);
|
|
|
|
openFileStruct.hwndOwner = globals->hWnd;
|
|
|
|
openFileStruct.lpstrFilter = L"Crosswords games" L"\0"
|
|
|
|
L"*.xwg" L"\0\0";
|
|
|
|
openFileStruct.Flags = OFN_FILEMUSTEXIST
|
|
|
|
| OFN_HIDEREADONLY
|
|
|
|
| OFN_PATHMUSTEXIST;
|
|
|
|
|
|
|
|
openFileStruct.lpstrFile = path;
|
2007-05-26 16:03:07 +02:00
|
|
|
openFileStruct.nMaxFile = VSIZE(path);
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( GetOpenFileName( &openFileStruct ) ) {
|
|
|
|
XP_UCHAR* name;
|
|
|
|
XP_U16 len;
|
|
|
|
|
|
|
|
len = wcslen(path);
|
|
|
|
name = XP_MALLOC( globals->mpool, len + 1 );
|
|
|
|
|
|
|
|
WideCharToMultiByte( CP_ACP, 0, path, len + 1,
|
|
|
|
name, len + 1, NULL, NULL );
|
|
|
|
|
|
|
|
if ( globals->curGameName != NULL
|
|
|
|
&& 0 == XP_STRCMP( name, globals->curGameName ) ){ /*already open*/
|
|
|
|
XP_FREE( globals->mpool, name );
|
2004-01-30 06:48:24 +01:00
|
|
|
} else if ( ceSaveCurGame( globals, XP_FALSE )
|
|
|
|
|| queryBoxChar( globals, "Do you really want to "
|
|
|
|
"overwrite the current game?" ) ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( globals->curGameName != NULL ) {
|
|
|
|
XP_FREE( globals->mpool, globals->curGameName );
|
|
|
|
}
|
|
|
|
|
|
|
|
globals->curGameName = name;
|
2006-04-25 06:25:08 +02:00
|
|
|
if ( ceLoadSavedGame( globals ) ) {
|
2008-02-16 17:02:49 +01:00
|
|
|
ceInitAndStartBoard( globals, XP_FALSE, NULL );
|
2006-04-25 06:25:08 +02:00
|
|
|
ceSetTitleFromName( globals );
|
|
|
|
} else {
|
|
|
|
XP_LOGF( "failed to open chosen game" );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2008-03-10 02:47:46 +01:00
|
|
|
} else {
|
|
|
|
XP_LOGF( "GetOpenFileName() failed" );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
} /* ceChooseAndOpen */
|
|
|
|
|
2004-04-14 06:00:28 +02:00
|
|
|
static void
|
|
|
|
updateForColors( CEAppGlobals* globals )
|
|
|
|
{
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_drawctxt_update( globals->draw );
|
2004-04-14 06:00:28 +02:00
|
|
|
if ( !!globals->game.board ) {
|
|
|
|
board_invalAll( globals->game.board );
|
|
|
|
}
|
|
|
|
} /* updateForColors */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ceDoPrefsDlg( CEAppGlobals* globals )
|
|
|
|
{
|
2004-04-14 06:00:28 +02:00
|
|
|
CePrefsDlgState state;
|
|
|
|
CePrefsPrefs prefsPrefs;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
XP_MEMSET( &state, 0, sizeof(state) );
|
|
|
|
|
2005-07-23 17:31:21 +02:00
|
|
|
loadStateFromCurPrefs( globals, &globals->appPrefs, &globals->gameInfo,
|
2003-11-20 17:26:35 +01:00
|
|
|
&prefsPrefs );
|
|
|
|
|
|
|
|
(void)WrapPrefsDialog( globals->hWnd, globals, &state, &prefsPrefs,
|
|
|
|
XP_FALSE );
|
|
|
|
|
|
|
|
if ( !state.userCancelled ) {
|
|
|
|
|
2005-07-23 17:31:21 +02:00
|
|
|
loadCurPrefsFromState( globals, &globals->appPrefs, &globals->gameInfo,
|
2003-11-20 17:26:35 +01:00
|
|
|
&prefsPrefs );
|
|
|
|
|
|
|
|
(void)cePositionBoard( globals );
|
|
|
|
|
2004-04-14 06:00:28 +02:00
|
|
|
if ( state.colorsChanged ) {
|
|
|
|
updateForColors( globals );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
/* need to reflect vars set in state into globals, and update/inval
|
|
|
|
as appropriate. */
|
|
|
|
}
|
|
|
|
} /* ceDoPrefsDlg */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ceWriteToFile( XWStreamCtxt* stream, void* closure )
|
|
|
|
{
|
|
|
|
FileWriteState* fwState = (FileWriteState*)closure;
|
2006-05-28 16:53:02 +02:00
|
|
|
#ifdef MEM_DEBUG
|
2003-11-20 17:26:35 +01:00
|
|
|
CEAppGlobals* globals = fwState->globals;
|
2006-05-28 16:53:02 +02:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_UCHAR* path = fwState->path;
|
|
|
|
wchar_t widebuf[257];
|
|
|
|
XP_U16 len = (XP_U16)XP_STRLEN( path );
|
|
|
|
HANDLE fileH;
|
|
|
|
|
|
|
|
len = (XP_U16)XP_STRLEN( path );
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, path, len + 1,
|
|
|
|
widebuf, len + 1 );
|
|
|
|
|
|
|
|
fileH = CreateFile( widebuf, GENERIC_WRITE, 0, NULL,
|
|
|
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
|
|
|
|
|
|
if ( fileH != INVALID_HANDLE_VALUE ) {
|
|
|
|
|
|
|
|
XP_U16 len = stream_getSize( stream );
|
|
|
|
XP_UCHAR* buf = XP_MALLOC( globals->mpool, len );
|
|
|
|
XP_U32 nWritten;
|
|
|
|
|
|
|
|
stream_getBytes( stream, buf, len );
|
|
|
|
|
|
|
|
WriteFile( fileH, buf, len, &nWritten, NULL );
|
|
|
|
SetEndOfFile( fileH );
|
|
|
|
CloseHandle( fileH );
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, buf );
|
|
|
|
}
|
|
|
|
} /* ceWriteToFile */
|
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
static XP_Bool
|
|
|
|
isDefaultName( XP_UCHAR* name )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2005-11-27 21:16:43 +01:00
|
|
|
return 0 == XP_STRCMP( UNSAVEDGAMEFILENAME, name );
|
2004-01-10 19:11:28 +01:00
|
|
|
} /* isDefaultName */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-02-18 05:25:29 +01:00
|
|
|
static void
|
2006-08-16 15:44:44 +02:00
|
|
|
makeUniqueName( wchar_t* buf, XP_U16 XP_UNUSED_DBG(bufLen) )
|
2004-02-18 05:25:29 +01:00
|
|
|
{
|
|
|
|
XP_U16 i;
|
|
|
|
DWORD attributes;
|
|
|
|
|
|
|
|
for ( i = 1; i < 100; ++i ) {
|
|
|
|
swprintf( buf, DEFAULT_DIR_NAME L"\\Untitled%d.xwg", i );
|
|
|
|
XP_ASSERT( wcslen(buf) < bufLen );
|
|
|
|
|
|
|
|
attributes = GetFileAttributes( buf );
|
|
|
|
if ( attributes == 0xFFFFFFFF ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If we fall out of the loop, the user will be asked to confirm delete
|
|
|
|
of Untitled99 or somesuch. That's ok.... */
|
|
|
|
} /* makeUniqueName */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static XP_Bool
|
2004-01-10 19:11:28 +01:00
|
|
|
ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
XP_Bool confirmed = XP_FALSE;
|
|
|
|
/* If it doesn't yet have a name, get a path at which to save it. User
|
|
|
|
has a chance to cancel this. But if there is a name go ahead and save
|
|
|
|
using it and don't bother giving cancel chance -- since there's no
|
|
|
|
harm in making 'em restart. Not sure how this changes when IR's
|
|
|
|
involved. */
|
|
|
|
XP_UCHAR* name = globals->curGameName;
|
2004-01-10 19:11:28 +01:00
|
|
|
if ( name == NULL || isDefaultName(name) ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
wchar_t nameBuf[256];
|
2004-01-10 19:11:28 +01:00
|
|
|
XP_UCHAR* newName = NULL;
|
|
|
|
|
|
|
|
if ( autoSave ) {
|
|
|
|
XP_U16 len = XP_STRLEN(UNSAVEDGAMEFILENAME) + 1;
|
|
|
|
newName = XP_MALLOC( globals->mpool, len );
|
|
|
|
XP_MEMCPY( newName, UNSAVEDGAMEFILENAME, len );
|
2004-01-30 06:48:24 +01:00
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
confirmed = XP_TRUE;
|
|
|
|
} else {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
OPENFILENAME sfs;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
XP_MEMSET( &sfs, 0, sizeof(sfs) );
|
2004-01-10 19:11:28 +01:00
|
|
|
XP_MEMSET( nameBuf, 0, sizeof(nameBuf) );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2007-05-26 16:03:07 +02:00
|
|
|
makeUniqueName( nameBuf, VSIZE(nameBuf) );
|
2004-02-14 07:13:18 +01:00
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
sfs.lStructSize = sizeof(sfs);
|
2004-02-14 07:13:18 +01:00
|
|
|
sfs.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
|
2004-01-30 06:48:24 +01:00
|
|
|
sfs.hwndOwner = globals->hWnd;
|
|
|
|
sfs.lpstrFile = nameBuf;
|
2007-05-26 16:03:07 +02:00
|
|
|
sfs.nMaxFile = VSIZE(nameBuf);
|
2004-01-30 06:48:24 +01:00
|
|
|
|
|
|
|
sfs.lpstrDefExt = L"xwg";
|
|
|
|
|
2006-06-11 07:27:16 +02:00
|
|
|
// sfs.lpstrTitle didn't work in earlier PPC OSes, but does now
|
|
|
|
sfs.lpstrTitle = L"Save current game as";
|
2004-02-14 07:13:18 +01:00
|
|
|
// sfs.lpstrInitialDir: doesn't either
|
2004-01-10 19:11:28 +01:00
|
|
|
|
2004-01-30 06:48:24 +01:00
|
|
|
confirmed = GetSaveFileName( &sfs );
|
2004-01-10 19:11:28 +01:00
|
|
|
|
|
|
|
if ( confirmed ) {
|
|
|
|
XP_U16 len = wcslen(nameBuf);
|
|
|
|
XP_DEBUGF( "len(nameBuf) = %d", len );
|
|
|
|
newName = XP_MALLOC( globals->mpool, len + 1 );
|
|
|
|
WideCharToMultiByte( CP_ACP, 0, nameBuf, len + 1,
|
2004-01-29 05:49:34 +01:00
|
|
|
newName, len + 1, NULL, NULL );
|
2004-01-30 06:48:24 +01:00
|
|
|
|
|
|
|
/* If user picked from a different directory, remember it
|
|
|
|
as the new starting point. */
|
|
|
|
nameBuf[sfs.nFileOffset] = 0;
|
|
|
|
if ( wcscmp( nameBuf, globals->lastDefaultDir ) != 0 ) {
|
|
|
|
XP_FREE( globals->mpool, globals->lastDefaultDir );
|
|
|
|
globals->lastDefaultDir =
|
|
|
|
XP_MALLOC( globals->mpool,
|
|
|
|
(sfs.nFileOffset + 1) * 2 );
|
|
|
|
wcscpy( globals->lastDefaultDir, nameBuf );
|
|
|
|
}
|
2004-01-10 19:11:28 +01:00
|
|
|
}
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( confirmed ) {
|
2004-01-10 19:11:28 +01:00
|
|
|
XP_ASSERT( !!newName );
|
|
|
|
if ( !!globals->curGameName ) {
|
|
|
|
XP_FREE( globals->mpool, globals->curGameName );
|
|
|
|
}
|
|
|
|
globals->curGameName = newName;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
confirmed = XP_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( confirmed ) {
|
|
|
|
if ( !!globals->game.server ) {
|
|
|
|
XWStreamCtxt* memStream;
|
|
|
|
DictionaryCtxt* dict;
|
|
|
|
FileWriteState fwState;
|
2006-10-22 21:44:30 +02:00
|
|
|
const char* dictName;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
fwState.path = globals->curGameName;
|
|
|
|
fwState.globals = globals;
|
|
|
|
board_hideTray( globals->game.board ); /* so won't be visible when
|
|
|
|
next opened */
|
|
|
|
memStream = mem_stream_make( MEMPOOL globals->vtMgr, &fwState, 0,
|
|
|
|
ceWriteToFile );
|
|
|
|
stream_open( memStream );
|
|
|
|
|
|
|
|
/* the dictionary */
|
|
|
|
dict = model_getDictionary( globals->game.model );
|
2004-01-22 04:21:19 +01:00
|
|
|
#ifdef STUBBED_DICT /* don't check this in!!! */
|
|
|
|
dictName = NULL;
|
|
|
|
#else
|
2003-11-20 17:26:35 +01:00
|
|
|
dictName = !!dict? dict_getName( dict ) : NULL;
|
2004-01-22 04:21:19 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
stream_putU8( memStream, (XP_U8)!!dictName );
|
|
|
|
if ( !!dictName ) {
|
|
|
|
stringToStream( memStream, dictName );
|
|
|
|
}
|
|
|
|
|
|
|
|
game_saveToStream( &globals->game, &globals->gameInfo, memStream );
|
|
|
|
|
|
|
|
stream_destroy( memStream );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return confirmed;
|
|
|
|
} /* ceSaveCurGame */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ceConfirmAndSave( CEAppGlobals* globals )
|
|
|
|
{
|
2004-01-10 19:11:28 +01:00
|
|
|
XP_Bool confirmed = ceSaveCurGame( globals, XP_TRUE );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( confirmed ) {
|
|
|
|
ceSavePrefs( globals );
|
|
|
|
}
|
|
|
|
|
|
|
|
return confirmed;
|
|
|
|
} /* ceConfirmAndSave */
|
|
|
|
|
2006-05-30 07:12:02 +02:00
|
|
|
static void
|
|
|
|
freeGlobals( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
MPSLOT;
|
|
|
|
|
|
|
|
MPASSIGN( mpool, globals->mpool );
|
|
|
|
|
|
|
|
draw_destroyCtxt( globals->draw );
|
|
|
|
|
|
|
|
game_dispose( &globals->game );
|
|
|
|
gi_disposePlayerInfo( MPPARM(mpool) &globals->gameInfo );
|
|
|
|
|
|
|
|
if ( globals->curGameName ) {
|
|
|
|
XP_FREE( mpool, globals->curGameName );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !!globals->vtMgr ) {
|
|
|
|
vtmgr_destroy( MPPARM(mpool) globals->vtMgr );
|
|
|
|
}
|
|
|
|
if ( !!globals->util.vtable ) {
|
|
|
|
XP_FREE( mpool, globals->util.vtable );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !!globals->lastDefaultDir ) {
|
|
|
|
XP_FREE( mpool, globals->lastDefaultDir );
|
|
|
|
}
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, globals );
|
|
|
|
mpool_destroy( mpool );
|
|
|
|
|
|
|
|
LOG_RETURN_VOID();
|
|
|
|
} /* freeGlobals */
|
|
|
|
|
2006-05-12 09:17:35 +02:00
|
|
|
#ifdef _WIN32_WCE
|
2004-12-17 08:45:30 +01:00
|
|
|
static HWND
|
|
|
|
makeCommandBar( HWND hwnd, HINSTANCE hInst )
|
|
|
|
{
|
|
|
|
SHMENUBARINFO mbi;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
XP_MEMSET( &mbi, 0, sizeof(mbi) );
|
|
|
|
mbi.cbSize = sizeof(mbi);
|
2004-12-17 08:45:30 +01:00
|
|
|
mbi.hwndParent = hwnd;
|
2008-02-05 05:57:58 +01:00
|
|
|
mbi.nToolBarId = IDM_MAIN_MENUBAR;
|
2004-12-17 08:45:30 +01:00
|
|
|
mbi.hInstRes = hInst;
|
2008-02-05 05:57:58 +01:00
|
|
|
/* Don't set dwFlags if you want the Wince5 two-button softkey menu. */
|
|
|
|
/* mbi.dwFlags = SHCMBF_HMENU; */
|
2008-01-20 16:36:17 +01:00
|
|
|
|
2005-06-13 16:29:49 +02:00
|
|
|
//mbi.dwFlags = SHCMBF_HIDESIPBUTTON; /* eeh added. Why??? */
|
2004-12-17 08:45:30 +01:00
|
|
|
|
|
|
|
if (!SHCreateMenuBar(&mbi)) {
|
2008-01-20 16:36:17 +01:00
|
|
|
/* will want to use this to change menubar: SHEnableSoftkey? */
|
2004-12-17 08:45:30 +01:00
|
|
|
XP_LOGF( "SHCreateMenuBar failed" );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mbi.hwndMB;
|
|
|
|
} /* makeCommandBar */
|
2006-05-12 09:17:35 +02:00
|
|
|
#endif
|
2004-12-17 08:45:30 +01:00
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
static XP_Bool
|
|
|
|
handleScroll( CEAppGlobals* globals, XP_S16 pos, /* only valid for THUMB* */
|
|
|
|
XP_S16 code, HWND wnd )
|
|
|
|
{
|
|
|
|
XP_Bool result = XP_FALSE;
|
|
|
|
|
|
|
|
if ( wnd == globals->scrollHandle ) {
|
|
|
|
XP_S16 newOffset;
|
|
|
|
XP_U16 curYOffset = board_getYOffset( globals->game.board );
|
|
|
|
|
|
|
|
XP_ASSERT( !!globals->game.board );
|
|
|
|
|
|
|
|
switch ( code ) {
|
|
|
|
/* case SB_BOTTOM: // Scrolls to the lower right */
|
|
|
|
/* case SB_ENDSCROLL: // Ends scroll */
|
|
|
|
|
|
|
|
case SB_LINEUP: // Scrolls one line up
|
|
|
|
case SB_PAGEUP: //
|
|
|
|
newOffset = curYOffset - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SB_LINEDOWN: // Scrolls one line down
|
|
|
|
case SB_PAGEDOWN: // Scrolls one page down
|
|
|
|
newOffset = curYOffset + 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SB_THUMBTRACK: /* still dragging; don't redraw */
|
|
|
|
case SB_THUMBPOSITION:
|
|
|
|
newOffset = pos;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
newOffset = -1;
|
|
|
|
/* do nothing */
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( newOffset >= 0 && newOffset <= globals->nHiddenRows ) {
|
|
|
|
result = curYOffset != newOffset;
|
|
|
|
if ( result ) {
|
|
|
|
result = board_setYOffset( globals->game.board, newOffset );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} /* handleScroll */
|
|
|
|
#endif
|
|
|
|
|
2005-06-23 16:09:20 +02:00
|
|
|
static void
|
|
|
|
ceFireTimer( CEAppGlobals* globals, XWTimerReason why )
|
|
|
|
{
|
2007-05-26 16:14:01 +02:00
|
|
|
XWTimerProc proc;
|
2005-08-21 16:07:29 +02:00
|
|
|
void* closure;
|
|
|
|
|
|
|
|
proc = globals->timerProcs[why];
|
2008-02-16 18:36:46 +01:00
|
|
|
if ( !!proc ) {
|
|
|
|
globals->timerProcs[why] = NULL;
|
|
|
|
closure = globals->timerClosures[why];
|
|
|
|
(*proc)( closure, why );
|
|
|
|
} else {
|
|
|
|
XP_LOGF( "skipped timer; alread fired?" );
|
|
|
|
}
|
2005-08-21 16:07:29 +02:00
|
|
|
} /* ceFireTimer */
|
2005-06-23 16:09:20 +02:00
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
/* WM_TIMER messages are low-priority. Hold a key down and key events will
|
|
|
|
* crowd it out of the queue so that the app doesn't see it until the key is
|
|
|
|
* released. There are more reliable timers, but they seem to require
|
|
|
|
* advanced techniques like semaphores. At least one article recommends
|
|
|
|
* polling over going to those lengths. This is better that polling. I hope
|
|
|
|
* it's enough.
|
|
|
|
*/
|
|
|
|
static XP_Bool
|
|
|
|
checkFireLateKeyTimer( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool drop = XP_FALSE;
|
|
|
|
XWTimerReason whys[] = { TIMER_PENDOWN, TIMER_TIMERTICK
|
|
|
|
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
|
|
|
, TIMER_HEARTBEAT
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
XP_U32 now = GetCurrentTime();
|
|
|
|
XP_U16 i;
|
|
|
|
|
|
|
|
for ( i = 0; i < sizeof(whys)/sizeof(whys[0]); ++i ) {
|
|
|
|
XWTimerReason why = whys[i];
|
|
|
|
if ( !!globals->timerProcs[why] ) {
|
|
|
|
if ( now >= globals->timerWhens[why] ) {
|
|
|
|
ceFireTimer( globals, why );
|
|
|
|
drop = XP_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return drop;
|
|
|
|
} /* checkFireLateKeyTimer */
|
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
static XP_Bool
|
|
|
|
processPacket( CEAppGlobals* globals, XWStreamCtxt* instream )
|
|
|
|
{
|
|
|
|
XP_Bool draw = XP_FALSE;
|
|
|
|
|
|
|
|
XP_ASSERT( globals->game.comms != NULL );
|
|
|
|
|
|
|
|
if ( comms_checkIncomingStream( globals->game.comms,
|
|
|
|
instream, NULL ) ) {
|
|
|
|
draw = server_receiveMessage( globals->game.server, instream );
|
|
|
|
}
|
|
|
|
stream_destroy( instream );
|
|
|
|
ce_util_requestTime( &globals->util );
|
|
|
|
|
|
|
|
return draw;
|
|
|
|
} /* processPacket */
|
|
|
|
#endif
|
|
|
|
|
2006-07-07 10:39:31 +02:00
|
|
|
static XP_Bool
|
|
|
|
checkPenDown( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool draw = globals->penDown;
|
|
|
|
if ( draw ) {
|
|
|
|
draw = board_handlePenUp( globals->game.board, 0x7FFF, 0x7FFF );
|
|
|
|
globals->penDown = XP_FALSE;
|
|
|
|
}
|
|
|
|
return draw;
|
|
|
|
} /* checkPenDown */
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
#ifdef KEYBOARD_NAV
|
|
|
|
|
|
|
|
static XP_Bool
|
2008-02-16 18:36:46 +01:00
|
|
|
ceCheckHandleFocusKey( CEAppGlobals* globals, WPARAM wParam, LPARAM lParam,
|
|
|
|
XP_Bool keyDown, XP_Bool* handledP )
|
2007-01-19 09:24:02 +01:00
|
|
|
{
|
2008-02-16 18:36:46 +01:00
|
|
|
XP_Bool isRepeat = keyDown && ((HIWORD(lParam) & KF_REPEAT) != 0);
|
2007-01-19 09:24:02 +01:00
|
|
|
XP_Key key;
|
|
|
|
XP_S16 incr = 0;
|
2008-02-16 18:36:46 +01:00
|
|
|
XP_Bool draw = XP_FALSE;
|
2007-01-19 09:24:02 +01:00
|
|
|
|
|
|
|
switch ( wParam ) {
|
2008-01-20 16:36:17 +01:00
|
|
|
case VK_UP:
|
2007-01-19 09:24:02 +01:00
|
|
|
key = XP_CURSOR_KEY_UP;
|
|
|
|
incr = -1;
|
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
case VK_RIGHT:
|
2007-01-19 09:24:02 +01:00
|
|
|
key = XP_CURSOR_KEY_RIGHT;
|
|
|
|
incr = 1;
|
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
case VK_DOWN:
|
2007-01-19 09:24:02 +01:00
|
|
|
key = XP_CURSOR_KEY_DOWN;
|
|
|
|
incr = 1;
|
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
case VK_LEFT:
|
2007-01-19 09:24:02 +01:00
|
|
|
key = XP_CURSOR_KEY_LEFT;
|
|
|
|
incr = -1;
|
|
|
|
break;
|
|
|
|
case 0x0d:
|
2008-02-16 18:36:46 +01:00
|
|
|
case 0x5d: /* center key on WinMo5 Treo (at least) -- but also ']'*/
|
2008-01-20 16:36:17 +01:00
|
|
|
case VK_HOME:
|
|
|
|
key = XP_RETURN_KEY;
|
2008-02-16 18:36:46 +01:00
|
|
|
if ( isRepeat ) {
|
|
|
|
(void)checkFireLateKeyTimer( globals );
|
|
|
|
}
|
2008-01-20 16:36:17 +01:00
|
|
|
XP_LOGF( "%s: XP_RETURN_KEY", __func__ );
|
|
|
|
break;
|
2007-01-19 09:24:02 +01:00
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
/* Still need to produce these somehow */
|
2007-01-19 09:24:02 +01:00
|
|
|
/* XP_CURSOR_KEY_ALTRIGHT, */
|
|
|
|
/* XP_CURSOR_KEY_ALTUP, */
|
|
|
|
/* XP_CURSOR_KEY_ALTLEFT, */
|
|
|
|
/* XP_CURSOR_KEY_ALTDOWN, */
|
|
|
|
|
|
|
|
default:
|
|
|
|
key = XP_KEY_NONE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( key != XP_KEY_NONE ) {
|
|
|
|
BoardCtxt* board = globals->game.board;
|
2008-02-16 18:36:46 +01:00
|
|
|
|
|
|
|
if ( isRepeat ) {
|
|
|
|
draw = board_handleKeyRepeat( board, key, handledP );
|
|
|
|
} else if ( keyDown ) {
|
|
|
|
draw = board_handleKeyDown( board, key, handledP );
|
|
|
|
} else {
|
|
|
|
draw = board_handleKeyUp( board, key, handledP );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !*handledP && incr != 0 && !keyDown ) {
|
2007-01-19 09:24:02 +01:00
|
|
|
BoardObjectType order[] = { OBJ_SCORE, OBJ_BOARD, OBJ_TRAY };
|
|
|
|
BoardObjectType cur = board_getFocusOwner( board );
|
|
|
|
XP_U16 index = 0;
|
|
|
|
XP_LOGF( "here" );
|
|
|
|
if ( cur != OBJ_NONE ) {
|
|
|
|
for ( ; ; ) {
|
|
|
|
if ( order[index] == cur ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++index;
|
|
|
|
XP_ASSERT( index < 3 );
|
|
|
|
}
|
|
|
|
index = (index + 3 + incr) % 3;
|
|
|
|
}
|
2008-01-20 16:36:17 +01:00
|
|
|
XP_LOGF( "%s: calling board_focusChanged", __func__ );
|
2007-01-19 09:24:02 +01:00
|
|
|
draw = board_focusChanged( board, order[index], XP_TRUE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return draw;
|
2008-02-16 18:36:46 +01:00
|
|
|
} /* ceCheckHandleFocusKey */
|
2007-01-19 09:24:02 +01:00
|
|
|
#endif /* KEYBOARD_NAV */
|
|
|
|
|
2008-01-20 16:36:17 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2008-02-16 18:36:46 +01:00
|
|
|
static void
|
|
|
|
ceToggleFullScreen( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
globals->appPrefs.fullScreen = !globals->appPrefs.fullScreen;
|
|
|
|
|
2008-03-15 16:39:58 +01:00
|
|
|
ceSizeIfFullscreen( globals, globals->hWnd );
|
2008-01-20 16:36:17 +01:00
|
|
|
|
|
|
|
(void)cePositionBoard( globals );
|
|
|
|
} /* ceToggleFullScreen */
|
|
|
|
#endif
|
|
|
|
|
2008-03-15 20:24:59 +01:00
|
|
|
static void
|
|
|
|
doAbout( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
wchar_t* buf[1024];
|
|
|
|
LPTSTR lpBuffer = (LPTSTR)buf;
|
|
|
|
(void)LoadString( globals->hInst, (UINT)IDS_ABOUT, lpBuffer, VSIZE(buf) );
|
|
|
|
MessageBox( globals->hWnd, lpBuffer, L"About", MB_OK );
|
|
|
|
}
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
LRESULT CALLBACK
|
|
|
|
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2008-02-16 18:36:46 +01:00
|
|
|
LRESULT result = 0;
|
2006-07-07 10:39:31 +02:00
|
|
|
int wmId;
|
2003-11-20 17:26:35 +01:00
|
|
|
RECT rt;
|
|
|
|
XP_Bool draw = XP_FALSE;
|
|
|
|
XWTimerReason why;
|
|
|
|
CEAppGlobals* globals;
|
2004-06-25 09:19:05 +02:00
|
|
|
XP_Bool handled;
|
2008-02-16 18:36:46 +01:00
|
|
|
XP_Bool callDefault = XP_FALSE;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( message == WM_CREATE ) {
|
|
|
|
globals = ((CREATESTRUCT*)lParam)->lpCreateParams;
|
|
|
|
SetWindowLong( hWnd, GWL_USERDATA, (long)globals );
|
2006-02-06 05:41:14 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2004-12-17 08:45:30 +01:00
|
|
|
globals->hwndCB = makeCommandBar( hWnd, globals->hInst );
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2005-06-13 16:29:49 +02:00
|
|
|
|
2006-02-17 08:30:54 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2005-06-13 16:29:49 +02:00
|
|
|
globals->sai.cbSize = sizeof(globals->sai);
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} else {
|
2008-02-16 18:36:46 +01:00
|
|
|
/* XP_LOGF( "%s: event=%s (%d)", __func__, messageToStr(message), message ); */
|
2003-11-20 17:26:35 +01:00
|
|
|
globals = (CEAppGlobals*)GetWindowLong( hWnd, GWL_USERDATA );
|
|
|
|
|
|
|
|
switch (message) {
|
2004-12-17 08:45:30 +01:00
|
|
|
|
2006-02-17 08:30:54 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2004-12-17 08:45:30 +01:00
|
|
|
case WM_ACTIVATE:
|
|
|
|
// Notify shell of our activate message
|
|
|
|
SHHandleWMActivate( hWnd, wParam, lParam, &globals->sai, FALSE );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_SETTINGCHANGE:
|
|
|
|
SHHandleWMSettingChange( hWnd, wParam, lParam, &globals->sai );
|
2006-04-02 23:52:15 +02:00
|
|
|
if ( !!globals && !!globals->game.model ) {
|
|
|
|
cePositionBoard( globals );
|
|
|
|
board_invalAll( globals->game.board );
|
|
|
|
draw = XP_TRUE;
|
|
|
|
}
|
2004-12-17 08:45:30 +01:00
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
#endif
|
2004-12-17 08:45:30 +01:00
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
case WM_VSCROLL:
|
2006-07-07 10:39:31 +02:00
|
|
|
draw = checkPenDown( globals );
|
2005-02-05 22:43:16 +01:00
|
|
|
draw = handleScroll( globals, (short int)HIWORD(wParam),
|
|
|
|
(short int)LOWORD(wParam),
|
2006-07-07 10:39:31 +02:00
|
|
|
(HWND)lParam ) || draw;
|
2005-02-05 22:43:16 +01:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
case WM_COMMAND:
|
2006-07-07 10:39:31 +02:00
|
|
|
(void)checkPenDown( globals );
|
|
|
|
wmId = LOWORD(wParam);
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
// Parse the menu selections:
|
|
|
|
switch (wmId) {
|
|
|
|
case ID_FILE_ABOUT:
|
2008-03-15 20:24:59 +01:00
|
|
|
doAbout( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
case ID_GAME_GAMEINFO: {
|
|
|
|
GameInfoState state;
|
|
|
|
|
|
|
|
XP_MEMSET( &state, 0, sizeof(state) );
|
|
|
|
state.globals = globals;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam(globals->hInst, (LPCTSTR)IDD_GAMEINFO, hWnd,
|
|
|
|
(DLGPROC)GameInfo, (long)&state );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-06-15 14:39:54 +02:00
|
|
|
if ( !state.userCancelled ) {
|
|
|
|
if ( state.prefsChanged ) {
|
2004-04-14 06:00:28 +02:00
|
|
|
updateForColors( globals );
|
2006-06-15 14:39:54 +02:00
|
|
|
}
|
|
|
|
draw = server_do( globals->game.server );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2004-04-14 06:00:28 +02:00
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_FILE_NEWGAME:
|
2004-01-10 19:11:28 +01:00
|
|
|
XP_LOGF( "ID_FILE_NEWGAME" );
|
|
|
|
if ( ceSaveCurGame( globals, XP_FALSE )
|
|
|
|
|| queryBoxChar( globals, "Do you really want to "
|
|
|
|
"overwrite the current game?" ) ) {
|
2006-08-16 15:44:44 +02:00
|
|
|
draw = ceDoNewGame( globals );
|
2004-01-10 19:11:28 +01:00
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_FILE_SAVEDGAMES:
|
|
|
|
ceChooseAndOpen( globals );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_FILE_PREFERENCES:
|
|
|
|
ceDoPrefsDlg( globals );
|
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
#ifdef _WIN32_WCE
|
|
|
|
case ID_FILE_FULLSCREEN:
|
|
|
|
ceToggleFullScreen( globals );
|
|
|
|
break;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
case ID_GAME_FINALSCORES:
|
|
|
|
if ( server_getGameIsOver( globals->game.server ) ) {
|
|
|
|
ceDisplayFinalScores( globals );
|
|
|
|
} else if ( queryBoxChar( globals,
|
|
|
|
"Are you sure you want to end "
|
|
|
|
"the game now?" ) ) {
|
|
|
|
server_endGame( globals->game.server );
|
|
|
|
draw = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_GAME_TILECOUNTSANDVALUES:
|
|
|
|
ceCountsAndValues( globals );
|
|
|
|
break;
|
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
case ID_GAME_TILESLEFT:
|
|
|
|
ceTilesLeft( globals );
|
|
|
|
break;
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
case ID_GAME_HISTORY:
|
|
|
|
ceDoHistory( globals );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_TRADE:
|
|
|
|
draw = handleTradeCmd( globals );
|
|
|
|
break;
|
|
|
|
case ID_MOVE_JUGGLE:
|
|
|
|
draw = handleJuggleCmd( globals );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_HIDETRAY:
|
|
|
|
draw = handleHidetrayCmd( globals );
|
|
|
|
break;
|
|
|
|
case ID_MOVE_TURNDONE:
|
|
|
|
draw = handleDoneCmd( globals);
|
|
|
|
break;
|
|
|
|
|
2006-07-07 10:39:31 +02:00
|
|
|
case ID_MOVE_FLIP:
|
2003-11-20 17:26:35 +01:00
|
|
|
draw = board_flip( globals->game.board );
|
|
|
|
break;
|
2008-01-20 16:36:17 +01:00
|
|
|
case ID_MOVE_VALUES:
|
2003-11-20 17:26:35 +01:00
|
|
|
draw = board_toggle_showValues( globals->game.board );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_HINT:
|
2004-07-10 19:46:36 +02:00
|
|
|
#ifdef XWFEATURE_SEARCHLIMIT
|
|
|
|
case ID_MOVE_LIMITEDHINT:
|
|
|
|
globals->askTrayLimits = wmId == ID_MOVE_LIMITEDHINT;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
board_resetEngine( globals->game.board );
|
2004-07-10 19:46:36 +02:00
|
|
|
/* fallthru */
|
2003-11-20 17:26:35 +01:00
|
|
|
case ID_MOVE_NEXTHINT:
|
|
|
|
draw = ceHandleHintRequest( globals );
|
|
|
|
break;
|
|
|
|
|
2008-02-05 05:57:58 +01:00
|
|
|
case ID_FILE_EXIT:
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( ceConfirmAndSave( globals ) ) { /* user may cancel... */
|
|
|
|
DestroyWindow(hWnd);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_UNDOCURRENT:
|
|
|
|
draw = board_replaceTiles( globals->game.board );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_UNDOLAST:
|
|
|
|
draw = server_handleUndo( globals->game.server );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2008-02-16 18:36:46 +01:00
|
|
|
callDefault = XP_TRUE;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
|
|
if ( !!globals && GetUpdateRect( hWnd, &rt, FALSE ) ) {
|
|
|
|
XP_Rect rect;
|
|
|
|
|
2004-05-26 06:48:25 +02:00
|
|
|
if ( !!globals->game.board ) {
|
|
|
|
/* When an obscuring window goes away, the update region
|
|
|
|
needs to be redrawn. This allows invalidating it. */
|
|
|
|
RECTtoXPR( &rect, &rt );
|
|
|
|
board_invalRect( globals->game.board, &rect );
|
2004-02-12 05:35:10 +01:00
|
|
|
|
2006-05-14 17:28:57 +02:00
|
|
|
XP_ASSERT( globals->hWnd == hWnd );
|
|
|
|
drawInsidePaint( globals );
|
2004-05-26 06:48:25 +02:00
|
|
|
}
|
2004-02-12 05:35:10 +01:00
|
|
|
if ( !ValidateRect( hWnd, &rt ) ) {
|
|
|
|
logLastError( "WM_PAINT:ValidateRect" );
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_LBUTTONDOWN:
|
2006-07-07 10:39:31 +02:00
|
|
|
draw = checkPenDown( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->penDown = XP_TRUE;
|
|
|
|
draw = board_handlePenDown( globals->game.board, LOWORD(lParam),
|
2006-07-07 10:39:31 +02:00
|
|
|
HIWORD(lParam), &handled )
|
|
|
|
|| draw;
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_MOUSEMOVE:
|
|
|
|
if ( globals->penDown ) {
|
|
|
|
draw = board_handlePenMove( globals->game.board,
|
|
|
|
LOWORD(lParam),
|
|
|
|
HIWORD(lParam) );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_LBUTTONUP:
|
|
|
|
if ( globals->penDown ) {
|
|
|
|
draw = board_handlePenUp( globals->game.board, LOWORD(lParam),
|
2006-07-01 16:22:09 +02:00
|
|
|
HIWORD(lParam) );
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->penDown = XP_FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
#ifdef KEYBOARD_NAV
|
2008-01-20 16:36:17 +01:00
|
|
|
case WM_KEYDOWN:
|
2007-01-19 09:24:02 +01:00
|
|
|
case WM_KEYUP:
|
2008-02-16 18:36:46 +01:00
|
|
|
draw = ceCheckHandleFocusKey( globals, wParam, lParam,
|
|
|
|
message==WM_KEYDOWN, &handled );
|
2007-01-19 09:24:02 +01:00
|
|
|
break;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
case WM_CHAR:
|
|
|
|
if ( wParam == 0x08 ) {
|
|
|
|
wParam = XP_CURSOR_KEY_DEL;
|
2007-01-19 09:24:02 +01:00
|
|
|
#ifdef KEYBOARD_NAV
|
|
|
|
} else if ( wParam == ' ' ) {
|
|
|
|
wParam = XP_RAISEFOCUS_KEY;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2007-01-19 09:24:02 +01:00
|
|
|
draw = board_handleKey( globals->game.board, wParam, &handled )
|
|
|
|
|| board_handleKey( globals->game.board, wParam - ('a'-'A'),
|
|
|
|
&handled );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_TIMER:
|
|
|
|
why = (XWTimerReason)wParam;
|
2005-07-13 14:35:38 +02:00
|
|
|
if ( why == TIMER_PENDOWN || why == TIMER_TIMERTICK
|
2007-12-03 02:18:13 +01:00
|
|
|
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
2005-07-13 14:35:38 +02:00
|
|
|
|| why == TIMER_HEARTBEAT
|
|
|
|
#endif
|
|
|
|
) {
|
2005-08-21 16:07:29 +02:00
|
|
|
XP_ASSERT( why < NUM_TIMERS_PLUS_ONE );
|
2005-06-23 16:09:20 +02:00
|
|
|
|
|
|
|
/* Kill since they otherwise repeat, but kill before firing
|
|
|
|
as fired proc may set another. */
|
2005-08-21 16:07:29 +02:00
|
|
|
(void)KillTimer( hWnd, globals->timerIDs[why] );
|
2005-06-23 16:09:20 +02:00
|
|
|
|
|
|
|
ceFireTimer( globals, why );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
2006-02-17 08:30:54 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2004-06-25 09:19:05 +02:00
|
|
|
CommandBar_Destroy(globals->hwndCB); /* supposedly not needed */
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
PostQuitMessage(0);
|
2006-05-30 07:12:02 +02:00
|
|
|
freeGlobals( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case XWWM_TIME_RQST:
|
2004-01-22 04:21:19 +01:00
|
|
|
draw = server_do( globals->game.server );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case XWWM_PACKET_ARRIVED:
|
|
|
|
draw = processPacket( globals, (XWStreamCtxt*)lParam );
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
default:
|
2008-02-16 18:36:46 +01:00
|
|
|
callDefault = XP_TRUE;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
if ( callDefault ) {
|
|
|
|
result = DefWindowProc(hWnd, message, wParam, lParam );
|
|
|
|
} else if ( draw ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
/* This is stupid. We can't just say "draw" because windoze clips
|
|
|
|
drawing to the inval rect, and the board isn't set up to tell us
|
|
|
|
what its inval rect is. So we inval everything, and then when the
|
|
|
|
WM_PAINT message comes we inval the whole board because there's a
|
|
|
|
huge inval rect. Dumb. Need to figure out how to have the
|
|
|
|
methods in cedraw.c set the clip region to encompass the object
|
|
|
|
being drawn -- taking board's word for it -- or the intersection
|
|
|
|
of that with the actual clip rgn in the case where some window's
|
|
|
|
gone away and revealed a large rect board didn't know about. That
|
|
|
|
was the source of some trouble on Palm, and CE's so fast this
|
|
|
|
works. But it's stupid. */
|
2004-02-12 05:35:10 +01:00
|
|
|
RECT r = { 100, 100, 102, 102 };
|
|
|
|
InvalidateRect( globals->hWnd, &r, FALSE /* erase */ );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
2008-02-16 18:36:46 +01:00
|
|
|
return result;
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* WndProc */
|
|
|
|
|
|
|
|
// Mesage handler for the About box.
|
|
|
|
LRESULT CALLBACK
|
2008-02-16 18:36:46 +01:00
|
|
|
ceAbout(HWND hDlg, UINT message, WPARAM wParam, LPARAM XP_UNUSED(lParam))
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
2008-02-16 18:36:46 +01:00
|
|
|
if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) {
|
|
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
2008-02-16 18:36:46 +01:00
|
|
|
} /* ceAbout */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
static XP_Bool
|
2003-11-20 17:26:35 +01:00
|
|
|
ceMsgFromStream( CEAppGlobals* globals, XWStreamCtxt* stream,
|
2004-02-14 07:13:18 +01:00
|
|
|
wchar_t* title, XP_Bool isQuery, XP_Bool destroy )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
StrBoxInit init;
|
|
|
|
|
2006-05-27 19:18:42 +02:00
|
|
|
XP_MEMSET( &init, 0, sizeof(init) );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
init.title = title;
|
|
|
|
init.stream = stream;
|
2004-02-14 07:13:18 +01:00
|
|
|
init.isQuery = isQuery;
|
2003-11-20 17:26:35 +01:00
|
|
|
init.globals = globals;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_STRBOX, globals->hWnd,
|
|
|
|
(DLGPROC)StrBox, (long)&init );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( destroy ) {
|
|
|
|
stream_destroy( stream );
|
|
|
|
}
|
2004-02-14 07:13:18 +01:00
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
return init.result == IDOK;
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ceMsgFromStream */
|
|
|
|
|
|
|
|
static void
|
|
|
|
messageBoxChar( CEAppGlobals* globals, XP_UCHAR* str, wchar_t* title )
|
|
|
|
{
|
|
|
|
wchar_t* widebuf;
|
|
|
|
XP_U32 len, wsize;
|
|
|
|
|
|
|
|
/* first get the length required, then alloc and go */
|
|
|
|
len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, strlen(str),
|
|
|
|
NULL, 0 );
|
|
|
|
wsize = (len+1) * sizeof( wchar_t );
|
|
|
|
|
|
|
|
widebuf = XP_MALLOC( globals->mpool, wsize );
|
|
|
|
|
|
|
|
XP_MEMSET( widebuf, 0, wsize );
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, strlen(str),
|
|
|
|
widebuf, len );
|
|
|
|
|
|
|
|
MessageBox( globals->hWnd, widebuf, title, MB_OK );
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, widebuf );
|
|
|
|
} /* messageBoxChar */
|
|
|
|
|
|
|
|
static XP_UCHAR*
|
|
|
|
ceStreamToStrBuf( MPFORMAL XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
XP_U16 len = stream_getSize( stream );
|
|
|
|
XP_UCHAR* buf = XP_MALLOC( mpool, len + 1 );
|
|
|
|
stream_getBytes( stream, buf, len );
|
|
|
|
buf[len] = '\0';
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
} /* ceStreamToStrBuf */
|
|
|
|
|
|
|
|
static void
|
|
|
|
messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream, wchar_t* title )
|
|
|
|
{
|
|
|
|
XP_UCHAR* buf = ceStreamToStrBuf( MPPARM(globals->mpool) stream );
|
|
|
|
|
|
|
|
messageBoxChar( globals, buf, title );
|
|
|
|
|
|
|
|
XP_FREE( globals->mpool, buf );
|
|
|
|
} /* messageBoxStream */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
queryBoxChar( CEAppGlobals* globals, XP_UCHAR* msg )
|
|
|
|
{
|
|
|
|
wchar_t widebuf[128];
|
|
|
|
XP_U16 answer;
|
|
|
|
|
|
|
|
XP_U16 len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, msg, strlen(msg),
|
|
|
|
widebuf,
|
2007-05-26 16:03:07 +02:00
|
|
|
VSIZE(widebuf) );
|
2003-11-20 17:26:35 +01:00
|
|
|
widebuf[len] = 0;
|
|
|
|
|
|
|
|
answer = MessageBox( globals->hWnd, widebuf, L"Question", MB_YESNO );
|
|
|
|
return answer == IDOK || answer == IDYES;
|
|
|
|
} /* queryBoxChar */
|
|
|
|
|
2004-02-14 07:13:18 +01:00
|
|
|
static XP_Bool
|
|
|
|
ceQueryFromStream( CEAppGlobals* globals, XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
return ceMsgFromStream( globals, stream, L"Question", XP_TRUE,
|
|
|
|
XP_FALSE );
|
|
|
|
} /* ceQueryFromStream */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
RECTtoXPR( XP_Rect* dest, RECT* src )
|
|
|
|
{
|
|
|
|
dest->top = (short)src->top;
|
|
|
|
dest->left = (short)src->left;
|
|
|
|
dest->width = (short)(src->right - src->left);
|
|
|
|
dest->height = (short)(src->bottom - src->top);
|
|
|
|
} /* RECTtoXPR */
|
|
|
|
|
|
|
|
void
|
2008-02-17 22:48:48 +01:00
|
|
|
wince_assert( XP_UCHAR* XP_UNUSED_LOG(s), int XP_UNUSED_LOG(line),
|
|
|
|
char* XP_UNUSED_LOG(fileName) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
XP_WARNF( "ASSERTION FAILED %s: file %s, line %d\n", s, fileName, line );
|
|
|
|
} /* wince_assert */
|
|
|
|
|
2008-02-17 22:48:48 +01:00
|
|
|
#ifdef ENABLE_LOGGING
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
2008-02-17 22:48:48 +01:00
|
|
|
makeTimeStamp( XP_UCHAR* timeStamp, XP_U16 XP_UNUSED_DBG(size) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
SYSTEMTIME st;
|
2005-07-30 04:02:49 +02:00
|
|
|
DWORD tid;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
tid = GetCurrentThreadId();
|
2005-07-30 04:02:49 +02:00
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
GetLocalTime( &st );
|
2005-07-30 04:02:49 +02:00
|
|
|
sprintf( timeStamp, "<%lx>%d:%.2d:%.2d ", tid, st.wHour, st.wMinute,
|
|
|
|
st.wSecond );
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_ASSERT( size > strlen(timeStamp) );
|
|
|
|
} /* makeTimeStamp */
|
|
|
|
|
|
|
|
void
|
2008-03-15 16:39:58 +01:00
|
|
|
wince_debugf(const XP_UCHAR* format, ...)
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-08-21 16:54:49 +02:00
|
|
|
static HANDLE s_logMutex = NULL;
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_UCHAR buf[256];
|
2005-08-21 16:54:49 +02:00
|
|
|
XP_UCHAR timeStamp[32];
|
|
|
|
XP_U16 nBytes;
|
|
|
|
XP_U32 nWritten;
|
|
|
|
HANDLE fileH;
|
2003-11-20 17:26:35 +01:00
|
|
|
va_list ap;
|
2005-11-27 21:16:43 +01:00
|
|
|
wchar_t* logFileName;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
va_start( ap, format );
|
|
|
|
vsprintf( buf, format, ap );
|
|
|
|
va_end(ap);
|
|
|
|
|
2005-08-21 16:54:49 +02:00
|
|
|
/* Create logfile if necessary and write to it in ascii. If there are
|
|
|
|
multiple threads, protect with mutex. */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-08-21 16:54:49 +02:00
|
|
|
if ( s_logMutex == NULL ) {
|
|
|
|
s_logMutex = CreateMutex( NULL, FALSE, NULL );
|
|
|
|
}
|
|
|
|
if ( WaitForSingleObject( s_logMutex, 200L ) == WAIT_OBJECT_0 ) {
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
makeTimeStamp(timeStamp, sizeof(timeStamp));
|
|
|
|
|
2005-11-27 21:16:43 +01:00
|
|
|
#if defined TARGET_OS_WINCE
|
|
|
|
logFileName = L"\\My Documents\\Crosswords\\xwDbgLog.txt";
|
|
|
|
#elif defined TARGET_OS_WIN32
|
|
|
|
logFileName = L"xwDbgLog.txt";
|
|
|
|
#endif
|
|
|
|
fileH = CreateFile( logFileName,
|
2004-01-10 19:11:28 +01:00
|
|
|
GENERIC_WRITE, 0, NULL,
|
2003-11-20 17:26:35 +01:00
|
|
|
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
|
|
|
|
|
|
#ifdef _WIN32_WCE_EMULATION
|
|
|
|
strcat( buf, "\n" );
|
|
|
|
#else
|
|
|
|
strcat( buf, XP_CR );
|
|
|
|
#endif
|
|
|
|
SetFilePointer( fileH, 0, 0, FILE_END );
|
2006-01-31 07:41:16 +01:00
|
|
|
#ifdef DEBUG_TS
|
2003-11-20 17:26:35 +01:00
|
|
|
nBytes = strlen( timeStamp );
|
|
|
|
WriteFile( fileH, timeStamp, nBytes, &nWritten, NULL );
|
2006-01-31 07:41:16 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
nBytes = strlen( buf );
|
|
|
|
WriteFile( fileH, buf, nBytes, &nWritten, NULL );
|
|
|
|
CloseHandle( fileH );
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-08-21 16:54:49 +02:00
|
|
|
ReleaseMutex( s_logMutex );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} /* wince_debugf */
|
2006-07-02 02:42:41 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
messageToBuf( UINT message, char* buf, int bufSize )
|
|
|
|
{
|
|
|
|
char* str = NULL;
|
|
|
|
#define STRCASE(s) case s : str = #s; break
|
|
|
|
switch( message ) {
|
|
|
|
STRCASE(WM_TIMER);
|
|
|
|
STRCASE(WM_SETCURSOR);
|
|
|
|
STRCASE(WM_NCHITTEST);
|
|
|
|
STRCASE(WM_MOUSEMOVE);
|
|
|
|
STRCASE(WM_SYSKEYDOWN);
|
|
|
|
STRCASE(WM_SYSKEYUP);
|
|
|
|
STRCASE(WM_SYSCHAR);
|
|
|
|
STRCASE(WM_SYSCOMMAND);
|
|
|
|
STRCASE(WM_ENTERMENULOOP);
|
|
|
|
STRCASE(WM_INITMENU);
|
|
|
|
STRCASE(WM_MENUSELECT);
|
|
|
|
STRCASE(WM_COMMAND);
|
|
|
|
STRCASE(WM_SETTEXT);
|
|
|
|
STRCASE(WM_QUERYNEWPALETTE);
|
|
|
|
STRCASE(WM_NCACTIVATE);
|
|
|
|
STRCASE(WM_ACTIVATE);
|
|
|
|
STRCASE(WM_SHOWWINDOW);
|
|
|
|
STRCASE(WM_CTLCOLOREDIT);
|
|
|
|
STRCASE(WM_MOUSEACTIVATE);
|
|
|
|
STRCASE(WM_CTLCOLORBTN);
|
|
|
|
STRCASE(WM_PASTE);
|
|
|
|
STRCASE(WM_WINDOWPOSCHANGING);
|
|
|
|
STRCASE(WM_SETFOCUS);
|
|
|
|
STRCASE(WM_WINDOWPOSCHANGED);
|
2006-07-04 00:32:29 +02:00
|
|
|
STRCASE(WM_PAINT);
|
|
|
|
STRCASE(WM_VSCROLL);
|
|
|
|
STRCASE(WM_LBUTTONDOWN);
|
|
|
|
STRCASE(WM_LBUTTONUP);
|
|
|
|
STRCASE(WM_INITMENUPOPUP);
|
|
|
|
STRCASE(WM_CANCELMODE);
|
|
|
|
STRCASE(WM_EXITMENULOOP);
|
|
|
|
STRCASE(WM_KILLFOCUS);
|
|
|
|
STRCASE(WM_ERASEBKGND);
|
2006-07-02 02:42:41 +02:00
|
|
|
default:
|
|
|
|
snprintf( buf, bufSize, "%d", message );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#undef STRCASE
|
|
|
|
if ( !!str ) {
|
|
|
|
snprintf( buf, bufSize, "%s", str );
|
|
|
|
}
|
2006-07-04 00:32:29 +02:00
|
|
|
} /* messageToBuf */
|
2008-02-17 22:48:48 +01:00
|
|
|
#endif /* ENABLE_LOGGING */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
XP_U16
|
2007-02-03 18:54:20 +01:00
|
|
|
wince_snprintf( XP_UCHAR* buf, XP_U16 len, const XP_UCHAR* format, ... )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start( ap, format );
|
|
|
|
|
2004-12-18 02:03:26 +01:00
|
|
|
_vsnprintf( buf, len, format, ap );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
/* FormatMessage( */
|
|
|
|
/* FORMAT_MESSAGE_FROM_STRING, */
|
|
|
|
/* format, */
|
|
|
|
/* 0, */
|
|
|
|
/* 0, // Default language */
|
|
|
|
/* (LPTSTR)buf, */
|
|
|
|
/* len, &ap ); */
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
return strlen(buf);
|
|
|
|
} /* wince_snprintf */
|
|
|
|
|
2007-12-03 02:18:13 +01:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2005-07-30 04:02:49 +02:00
|
|
|
static void
|
|
|
|
got_data_proc( XP_U8* data, XP_U16 len, void* closure )
|
|
|
|
{
|
|
|
|
/* Remember that this gets called by the reader thread, not by the one
|
|
|
|
running the window loop. */
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)closure;
|
|
|
|
BOOL posted;
|
|
|
|
XWStreamCtxt* stream;
|
|
|
|
|
|
|
|
stream = make_generic_stream( globals );
|
|
|
|
stream_putBytes( stream, data, len );
|
|
|
|
|
|
|
|
posted = PostMessage( globals->hWnd, XWWM_PACKET_ARRIVED,
|
|
|
|
0, (DWORD)stream );
|
|
|
|
XP_ASSERT( posted );
|
|
|
|
} /* got_data_proc */
|
2006-10-28 16:56:04 +02:00
|
|
|
#endif
|
2005-07-30 04:02:49 +02:00
|
|
|
|
2007-12-03 02:18:13 +01:00
|
|
|
#ifdef COMMS_HEARTBEAT
|
|
|
|
static void
|
|
|
|
ce_reset_proc( void* closure )
|
|
|
|
{
|
|
|
|
LOG_FUNC();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-10-28 16:56:04 +02:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2005-07-23 17:31:21 +02:00
|
|
|
static XP_S16
|
2006-09-15 09:39:57 +02:00
|
|
|
ce_send_proc( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr,
|
|
|
|
void* closure )
|
2005-07-23 17:31:21 +02:00
|
|
|
{
|
2005-07-30 04:02:49 +02:00
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)closure;
|
2005-07-23 17:31:21 +02:00
|
|
|
XP_LOGF( "ce_send_proc called" );
|
2005-07-30 04:02:49 +02:00
|
|
|
|
|
|
|
if ( !globals->socketWrap ) {
|
|
|
|
globals->socketWrap = ce_sockwrap_new( MPPARM(globals->mpool)
|
2006-10-28 16:56:04 +02:00
|
|
|
addr->conType,
|
2005-07-30 04:02:49 +02:00
|
|
|
got_data_proc, globals );
|
|
|
|
}
|
|
|
|
|
|
|
|
return ce_sockwrap_send( globals->socketWrap, buf, len, addr );
|
2005-07-23 17:31:21 +02:00
|
|
|
} /* ce_send_proc */
|
2005-08-21 16:36:11 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
ce_send_on_close( XWStreamCtxt* stream, void* closure )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)closure;
|
|
|
|
|
|
|
|
XP_ASSERT( !!globals->game.comms );
|
|
|
|
comms_send( globals->game.comms, stream );
|
|
|
|
}
|
2005-07-30 04:02:49 +02:00
|
|
|
#endif
|
2005-07-23 17:31:21 +02:00
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static VTableMgr*
|
|
|
|
ce_util_getVTManager( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
return globals->vtMgr;
|
|
|
|
} /* ce_util_getVTManager */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ce_util_userError( XW_UtilCtxt* uc, UtilErrID id )
|
|
|
|
{
|
|
|
|
XP_UCHAR* message;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
|
|
|
|
switch( id ) {
|
|
|
|
case ERR_TILES_NOT_IN_LINE:
|
|
|
|
message = "All tiles played must be in a line.";
|
|
|
|
break;
|
|
|
|
case ERR_NO_EMPTIES_IN_TURN:
|
|
|
|
message = "Empty squares cannot separate tiles played.";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ERR_TWO_TILES_FIRST_MOVE:
|
|
|
|
message = "Must play two or more pieces on the first move.";
|
|
|
|
break;
|
|
|
|
case ERR_TILES_MUST_CONTACT:
|
|
|
|
message = "New pieces must contact others already in place (or "
|
|
|
|
"the middle square on the first move).";
|
|
|
|
break;
|
|
|
|
case ERR_NOT_YOUR_TURN:
|
|
|
|
message = "You can't do that; it's not your turn!";
|
|
|
|
break;
|
|
|
|
case ERR_NO_PEEK_ROBOT_TILES:
|
|
|
|
message = "No peeking at the robot's tiles!";
|
|
|
|
break;
|
|
|
|
case ERR_CANT_TRADE_MID_MOVE:
|
|
|
|
message = "Remove played tiles before trading.";
|
|
|
|
break;
|
|
|
|
case ERR_TOO_FEW_TILES_LEFT_TO_TRADE:
|
|
|
|
message = "Too few tiles left to trade.";
|
|
|
|
break;
|
2004-05-15 03:07:34 +02:00
|
|
|
case ERR_CANT_UNDO_TILEASSIGN:
|
|
|
|
message = "Tile assignment can't be undone.";
|
|
|
|
break;
|
|
|
|
|
2008-01-05 17:37:49 +01:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case ERR_NO_PEEK_REMOTE_TILES:
|
|
|
|
message = "No peeking at remote players' tiles!";
|
|
|
|
break;
|
|
|
|
case ERR_REG_UNEXPECTED_USER:
|
|
|
|
message = "Refused attempt to register unexpected user[s].";
|
|
|
|
break;
|
|
|
|
case ERR_SERVER_DICT_WINS:
|
|
|
|
message = "Conflict between Host and Guest dictionaries; Host wins.";
|
|
|
|
XP_WARNF( "GTK may have problems here." );
|
|
|
|
break;
|
|
|
|
case ERR_REG_SERVER_SANS_REMOTE:
|
|
|
|
message = "At least one player must be marked remote for a game "
|
|
|
|
"started as Host.";
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2005-09-07 14:31:32 +02:00
|
|
|
case ERR_RELAY_BASE + XWRELAY_ERROR_TIMEOUT:
|
|
|
|
message = "The relay timed you out; usually that means "
|
|
|
|
"the other players didn't show.";
|
|
|
|
break;
|
|
|
|
case ERR_RELAY_BASE + XWRELAY_ERROR_HEART_YOU:
|
|
|
|
message = "You were disconnected from relay because it didn't "
|
|
|
|
"hear from you in too long.";
|
|
|
|
break;
|
|
|
|
case ERR_RELAY_BASE + XWRELAY_ERROR_HEART_OTHER:
|
|
|
|
case ERR_RELAY_BASE + XWRELAY_ERROR_LOST_OTHER:
|
|
|
|
message = "The relay has lost contact with a device in this game.";
|
|
|
|
break;
|
2006-02-06 05:41:14 +01:00
|
|
|
#endif
|
2005-09-07 14:31:32 +02:00
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
default:
|
2007-12-02 20:13:25 +01:00
|
|
|
XP_LOGF( "%s(%d)", __func__, id );
|
2003-11-20 17:26:35 +01:00
|
|
|
message = "unknown errorcode ID!!!";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
messageBoxChar( globals, message, L"Oops!" );
|
|
|
|
|
|
|
|
} /* ce_util_userError */
|
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
static XP_Bool
|
2003-11-20 17:26:35 +01:00
|
|
|
ce_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
char* query = NULL;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
|
|
|
|
switch( id ) {
|
|
|
|
case QUERY_COMMIT_TURN:
|
2004-02-17 06:00:13 +01:00
|
|
|
return ceQueryFromStream( globals, stream );
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
case QUERY_COMMIT_TRADE:
|
|
|
|
query = "Are you sure you want to spend this move trading tiles?";
|
2004-02-17 06:00:13 +01:00
|
|
|
return queryBoxChar( globals, query );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
case QUERY_ROBOT_MOVE:
|
2004-02-17 06:00:13 +01:00
|
|
|
return ceMsgFromStream( globals, stream, L"FYI", XP_FALSE,
|
|
|
|
XP_FALSE );
|
|
|
|
|
|
|
|
case QUERY_ROBOT_TRADE:
|
|
|
|
messageBoxStream( globals, stream, L"FYI" );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
XP_ASSERT(0);
|
|
|
|
}
|
|
|
|
|
2004-02-17 06:00:13 +01:00
|
|
|
return XP_FALSE;
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_userQuery */
|
|
|
|
|
|
|
|
static XWBonusType
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_getSquareBonus( XW_UtilCtxt* uc, ModelCtxt* XP_UNUSED(model),
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_U16 col, XP_U16 row )
|
|
|
|
{
|
|
|
|
XP_U16 index;
|
2004-01-29 05:49:34 +01:00
|
|
|
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
|
|
|
|
if ( !globals->bonusInfo ) {
|
|
|
|
HRSRC rsrcH;
|
|
|
|
HGLOBAL globH;
|
|
|
|
|
|
|
|
rsrcH = FindResource( globals->hInst, MAKEINTRESOURCE(ID_BONUS_RES),
|
|
|
|
TEXT("BONS") );
|
|
|
|
if ( !!rsrcH ) {
|
|
|
|
globH = LoadResource( globals->hInst, rsrcH );
|
|
|
|
|
|
|
|
if ( !!globH ) {
|
|
|
|
globals->bonusInfo = (XP_U16*)globH;
|
|
|
|
/* We don't want to call DeleteObject here, but should when
|
|
|
|
the app closes. Or does Wince free up all memory
|
|
|
|
associated with a process when it closes? PENDING(eeh) */
|
|
|
|
// DeleteObject( globH );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( col > 7 ) col = 14 - col;
|
|
|
|
if ( row > 7 ) row = 14 - row;
|
|
|
|
index = (row*8) + col;
|
2004-01-30 06:48:24 +01:00
|
|
|
|
2004-01-29 05:49:34 +01:00
|
|
|
if ( !globals->bonusInfo || (index >= 8*8) ) {
|
|
|
|
XP_ASSERT( 0 );
|
|
|
|
return (XWBonusType)BONUS_NONE;
|
2003-11-20 17:26:35 +01:00
|
|
|
} else {
|
2004-01-29 05:49:34 +01:00
|
|
|
/* This is probably a bit slow. Consider caching the resource in
|
|
|
|
memory with one bonus value per byte. */
|
|
|
|
XP_U16 value = globals->bonusInfo[index/4];
|
|
|
|
value >>= ((3 - (index % 4)) * 4);
|
|
|
|
return value & 0x0F;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
} /* ce_util_getSquareBonus */
|
|
|
|
|
|
|
|
static XP_S16
|
2005-02-05 22:43:16 +01:00
|
|
|
ce_util_userPickTile( XW_UtilCtxt* uc, const PickInfo* pi,
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_U16 playerNum,
|
2005-02-05 22:43:16 +01:00
|
|
|
const XP_UCHAR4* texts, XP_U16 nTiles )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
BlankDialogState state;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
XP_MEMSET( &state, 0, sizeof(state) );
|
|
|
|
|
2003-12-09 06:18:47 +01:00
|
|
|
state.globals = globals;
|
2003-11-20 17:26:35 +01:00
|
|
|
state.texts = texts;
|
|
|
|
state.nTiles = nTiles;
|
|
|
|
state.playerNum = playerNum;
|
|
|
|
state.pi = pi;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_ASKBLANK, globals->hWnd,
|
|
|
|
(DLGPROC)BlankDlg, (long)&state );
|
2003-11-20 17:26:35 +01:00
|
|
|
return state.result;
|
|
|
|
} /* ce_util_userPickTile */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ce_util_askPassword( XW_UtilCtxt* uc, const XP_UCHAR* name,
|
|
|
|
XP_UCHAR* buf, XP_U16* len )
|
|
|
|
{
|
|
|
|
PasswdDialogState state;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
XP_MEMSET( &state, 0, sizeof(state) );
|
|
|
|
|
|
|
|
state.name = name;
|
|
|
|
state.buf = buf;
|
|
|
|
state.lenp = len;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_ASKPASS, globals->hWnd,
|
|
|
|
(DLGPROC)PasswdDlg, (long)&state );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
return !state.userCancelled;
|
|
|
|
} /* ce_util_askPassword */
|
|
|
|
|
|
|
|
static void
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_trayHiddenChange( XW_UtilCtxt* uc, XW_TrayVisState XP_UNUSED(newState),
|
2006-05-19 15:44:05 +02:00
|
|
|
XP_U16 nVisibleRows )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2004-02-13 14:49:25 +01:00
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
2006-05-20 08:22:33 +02:00
|
|
|
XP_U16 nHiddenRows;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
/* If there's a scrollbar, hide/show it. It wants to be
|
|
|
|
active/visible only when the tray is NOT hidden */
|
2006-05-19 15:44:05 +02:00
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
if ( !!globals->scrollHandle ) {
|
2006-05-20 08:22:33 +02:00
|
|
|
nHiddenRows = model_numRows( globals->game.model ) - nVisibleRows;
|
|
|
|
updateScrollInfo( globals->scrollHandle, nHiddenRows );
|
|
|
|
globals->nHiddenRows = nHiddenRows;
|
2005-02-05 22:43:16 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-05-14 17:28:57 +02:00
|
|
|
drawInsidePaint( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_trayHiddenChange */
|
|
|
|
|
|
|
|
static void
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_yOffsetChange( XW_UtilCtxt* uc, XP_U16 XP_UNUSED(oldOffset),
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_U16 newOffset )
|
|
|
|
{
|
2005-02-05 22:43:16 +01:00
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
(void)SetScrollPos( globals->scrollHandle, SB_CTL, newOffset, XP_TRUE );
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_yOffsetChange */
|
|
|
|
|
2008-02-26 14:49:41 +01:00
|
|
|
static void
|
|
|
|
ce_util_turnChanged( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
ceSetLeftSoftkey( globals, ID_MOVE_TURNDONE );
|
|
|
|
}
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ce_util_notifyGameOver( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
2006-05-14 17:28:57 +02:00
|
|
|
drawInsidePaint( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
ceDisplayFinalScores( globals );
|
2008-02-26 14:49:41 +01:00
|
|
|
|
|
|
|
ceSetLeftSoftkey( globals, ID_FILE_NEWGAME );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_notifyGameOver */
|
|
|
|
|
|
|
|
static XP_Bool
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_hiliteCell( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 XP_UNUSED(col),
|
|
|
|
XP_U16 XP_UNUSED(row) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
return XP_TRUE;
|
|
|
|
} /* ce_util_hiliteCell */
|
|
|
|
|
|
|
|
static XP_Bool
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_engineProgressCallback( XW_UtilCtxt* XP_UNUSED(uc) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
return XP_TRUE;
|
|
|
|
} /* ce_util_engineProgressCallback */
|
|
|
|
|
|
|
|
static void
|
2006-10-28 16:56:04 +02:00
|
|
|
ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
2008-02-16 17:02:49 +01:00
|
|
|
XP_U16 XP_UNUSED_STANDALONE(when), XWTimerProc proc,
|
|
|
|
void* closure )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
2004-06-16 06:16:22 +02:00
|
|
|
XP_U32 timerID;
|
2004-06-25 09:19:05 +02:00
|
|
|
XP_U32 howLong;
|
|
|
|
|
2005-08-21 16:07:29 +02:00
|
|
|
XP_ASSERT( why < NUM_TIMERS_PLUS_ONE );
|
|
|
|
globals->timerProcs[why] = proc;
|
|
|
|
globals->timerClosures[why] = closure;
|
2005-06-23 16:09:20 +02:00
|
|
|
|
|
|
|
switch ( why ) {
|
|
|
|
case TIMER_PENDOWN:
|
2004-06-25 09:19:05 +02:00
|
|
|
howLong = 400;
|
2005-06-23 16:09:20 +02:00
|
|
|
break;
|
|
|
|
case TIMER_TIMERTICK:
|
2004-06-25 09:19:05 +02:00
|
|
|
howLong = 1000; /* 1 second */
|
2005-06-23 16:09:20 +02:00
|
|
|
break;
|
2007-12-03 02:18:13 +01:00
|
|
|
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
2005-06-23 16:09:20 +02:00
|
|
|
case TIMER_HEARTBEAT:
|
|
|
|
howLong = when * 1000;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
2004-06-16 06:16:22 +02:00
|
|
|
XP_ASSERT(0);
|
2004-06-25 09:19:05 +02:00
|
|
|
return;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2008-02-16 18:36:46 +01:00
|
|
|
|
|
|
|
globals->timerWhens[why] = GetCurrentTime() + howLong;
|
|
|
|
|
2004-06-25 09:19:05 +02:00
|
|
|
timerID = SetTimer( globals->hWnd, why, howLong, NULL);
|
|
|
|
|
2005-08-21 16:07:29 +02:00
|
|
|
globals->timerIDs[why] = timerID;
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_setTimer */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ce_util_requestTime( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
|
|
|
|
PostMessage( globals->hWnd, XWWM_TIME_RQST, 0, 0 );
|
|
|
|
} /* palm_util_requestTime */
|
|
|
|
|
|
|
|
static XP_U32
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_getCurSeconds( XW_UtilCtxt* XP_UNUSED(uc) )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2008-02-16 18:36:46 +01:00
|
|
|
/* This function is never called! */
|
|
|
|
XP_U32 ticks = GetCurrentTime();
|
|
|
|
ticks /= 1000;
|
|
|
|
LOG_RETURNF( "%ld", ticks );
|
|
|
|
return ticks;
|
|
|
|
/* return 0L; */
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_getCurSeconds */
|
|
|
|
|
|
|
|
static DictionaryCtxt*
|
|
|
|
ce_util_makeEmptyDict( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
2004-01-17 23:10:23 +01:00
|
|
|
#ifdef STUBBED_DICT
|
|
|
|
return make_stubbed_dict( MPPARM_NOCOMMA(globals->mpool) );
|
|
|
|
#else
|
2005-06-30 03:48:07 +02:00
|
|
|
return ce_dictionary_make_empty( globals );
|
2004-01-17 23:10:23 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_makeEmptyDict */
|
|
|
|
|
2006-10-10 03:34:37 +02:00
|
|
|
#ifdef XWFEATURE_RELAY
|
2003-11-20 17:26:35 +01:00
|
|
|
static XWStreamCtxt*
|
2008-01-05 17:37:49 +01:00
|
|
|
ce_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_PlayerAddr channelNo )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2005-07-30 04:02:49 +02:00
|
|
|
XWStreamCtxt* stream;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
|
|
|
|
stream = make_generic_stream( globals );
|
2005-08-21 16:36:11 +02:00
|
|
|
stream_setOnCloseProc( stream, ce_send_on_close );
|
2005-07-30 04:02:49 +02:00
|
|
|
stream_setAddress( stream, channelNo );
|
|
|
|
|
|
|
|
return stream;
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_makeStreamFromAddr */
|
|
|
|
#endif
|
|
|
|
|
2007-02-03 18:54:20 +01:00
|
|
|
static const XP_UCHAR*
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_getUserString( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 stringCode )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
switch( stringCode ) {
|
|
|
|
case STRD_REMAINING_TILES_ADD:
|
|
|
|
return (XP_UCHAR*)"+ %d [all remaining tiles]";
|
|
|
|
case STRD_UNUSED_TILES_SUB:
|
|
|
|
return (XP_UCHAR*)"- %d [unused tiles]";
|
|
|
|
case STR_BONUS_ALL:
|
|
|
|
return (XP_UCHAR*)"Bonus for using all tiles: 50" XP_CR;
|
|
|
|
case STRD_TURN_SCORE:
|
|
|
|
return (XP_UCHAR*)"Score for turn: %d" XP_CR;
|
|
|
|
case STR_COMMIT_CONFIRM:
|
|
|
|
return (XP_UCHAR*)"Commit the current move?" XP_CR;
|
2004-05-01 16:30:34 +02:00
|
|
|
case STR_LOCAL_NAME:
|
|
|
|
return (XP_UCHAR*)"%s";
|
2003-11-20 17:26:35 +01:00
|
|
|
case STR_NONLOCAL_NAME:
|
|
|
|
return (XP_UCHAR*)"%s (remote)";
|
|
|
|
case STRD_TIME_PENALTY_SUB:
|
|
|
|
return (XP_UCHAR*)" - %d [time]";
|
|
|
|
|
|
|
|
case STRD_CUMULATIVE_SCORE:
|
|
|
|
return (XP_UCHAR*)"Cumulative score: %d" XP_CR;
|
|
|
|
case STRS_MOVE_ACROSS:
|
|
|
|
return (XP_UCHAR*)"move (from %s across)" XP_CR;
|
|
|
|
case STRS_MOVE_DOWN:
|
|
|
|
return (XP_UCHAR*)"move (from %s down)" XP_CR;
|
|
|
|
case STRS_TRAY_AT_START:
|
|
|
|
return (XP_UCHAR*)"Tray at start: %s" XP_CR;
|
|
|
|
|
|
|
|
case STRS_NEW_TILES:
|
|
|
|
return (XP_UCHAR*)"New tiles: %s" XP_CR;
|
|
|
|
case STRSS_TRADED_FOR:
|
|
|
|
return (XP_UCHAR*)"Traded %s for %s.";
|
|
|
|
case STR_PASS:
|
|
|
|
return (XP_UCHAR*)"pass" XP_CR;
|
|
|
|
case STR_PHONY_REJECTED:
|
|
|
|
return (XP_UCHAR*)"Illegal word in move; turn lost!" XP_CR;
|
|
|
|
|
|
|
|
case STRD_ROBOT_TRADED:
|
|
|
|
return (XP_UCHAR*)"Robot traded tiles %d this turn.";
|
|
|
|
case STR_ROBOT_MOVED:
|
|
|
|
return (XP_UCHAR*)"The robot made this move:" XP_CR;
|
|
|
|
case STR_REMOTE_MOVED:
|
|
|
|
return (XP_UCHAR*)"Remote player made this move:" XP_CR;
|
|
|
|
|
2004-05-13 04:13:48 +02:00
|
|
|
case STR_PASSED:
|
|
|
|
return (XP_UCHAR*)"Passed";
|
|
|
|
case STRSD_SUMMARYSCORED:
|
|
|
|
return (XP_UCHAR*)"%s:%d";
|
|
|
|
case STRD_TRADED:
|
|
|
|
return (XP_UCHAR*)"Traded %d";
|
|
|
|
case STR_LOSTTURN:
|
|
|
|
return (XP_UCHAR*)"Lost turn";
|
|
|
|
|
2006-06-10 18:15:31 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
case STR_LOCALPLAYERS:
|
2006-07-02 02:42:41 +02:00
|
|
|
return (XP_UCHAR*)"Locl playrs:";
|
2006-06-10 18:15:31 +02:00
|
|
|
#endif
|
|
|
|
case STR_TOTALPLAYERS:
|
2006-07-02 02:42:41 +02:00
|
|
|
return (XP_UCHAR*)"Player count:";
|
2006-06-10 18:15:31 +02:00
|
|
|
|
2004-11-09 03:40:36 +01:00
|
|
|
case STRS_VALUES_HEADER:
|
|
|
|
return (XP_UCHAR*)"%s counts/values:" XP_CR;
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
default:
|
2004-05-01 16:30:34 +02:00
|
|
|
XP_LOGF( "stringCode=%d", stringCode );
|
2003-11-20 17:26:35 +01:00
|
|
|
return (XP_UCHAR*)"unknown code";
|
|
|
|
}
|
|
|
|
} /* ce_util_getUserString */
|
|
|
|
|
|
|
|
static void
|
2004-01-29 05:49:34 +01:00
|
|
|
ce_formatBadWords( BadWordInfo* bwi, XP_UCHAR buf[], XP_U16 bufsiz )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
XP_U16 i;
|
|
|
|
|
|
|
|
for ( i = 0, buf[0] = '\0'; ; ) {
|
|
|
|
XP_UCHAR wordBuf[18];
|
|
|
|
sprintf( wordBuf, "\"%s\"", bwi->words[i] );
|
2004-01-29 05:49:34 +01:00
|
|
|
XP_ASSERT( strlen(wordBuf) < sizeof(wordBuf)-1 );
|
|
|
|
strncat( buf, wordBuf, bufsiz - 1 );
|
2003-11-20 17:26:35 +01:00
|
|
|
if ( ++i == bwi->nWords ) {
|
|
|
|
break;
|
|
|
|
}
|
2004-01-29 05:49:34 +01:00
|
|
|
bufsiz -= strlen( wordBuf );
|
|
|
|
strncat( buf, ", ", bufsiz - 1 );
|
|
|
|
bufsiz -= 2;
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
} /* ce_formatBadWords */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ce_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
2006-08-16 15:44:44 +02:00
|
|
|
XP_U16 XP_UNUSED(turn), XP_Bool turnLost )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
XP_UCHAR wordsBuf[256];
|
|
|
|
XP_UCHAR msgBuf[256];
|
|
|
|
XP_Bool isOk;
|
|
|
|
|
2004-01-29 05:49:34 +01:00
|
|
|
ce_formatBadWords( bwi, wordsBuf, sizeof(wordsBuf) );
|
2003-11-20 17:26:35 +01:00
|
|
|
sprintf( msgBuf, "Word[s] %s not found in dictionary.", wordsBuf );
|
|
|
|
|
|
|
|
if ( turnLost ) {
|
|
|
|
messageBoxChar( globals, msgBuf, L"Illegal word" );
|
|
|
|
isOk = XP_TRUE;
|
|
|
|
} else {
|
|
|
|
strcat( msgBuf, " Use it anyway?" );
|
|
|
|
isOk = queryBoxChar( globals, msgBuf );
|
|
|
|
}
|
|
|
|
|
|
|
|
return isOk;
|
|
|
|
} /* ce_util_warnIllegalWord */
|
|
|
|
|
2006-10-28 16:56:04 +02:00
|
|
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
2005-07-23 17:31:21 +02:00
|
|
|
static void
|
2006-08-16 15:44:44 +02:00
|
|
|
ce_util_addrChange( XW_UtilCtxt* XP_UNUSED(uc),
|
|
|
|
const CommsAddrRec* XP_UNUSED(oldAddr),
|
|
|
|
const CommsAddrRec* XP_UNUSED(newAddr) )
|
2005-07-23 17:31:21 +02:00
|
|
|
{
|
|
|
|
XP_LOGF( "ce_util_addrChange called; DO SOMETHING." );
|
|
|
|
} /* ce_util_addrChange */
|
|
|
|
#endif
|
|
|
|
|
2004-07-10 19:46:36 +02:00
|
|
|
#ifdef XWFEATURE_SEARCHLIMIT
|
|
|
|
static XP_Bool
|
|
|
|
ce_util_getTraySearchLimits( XW_UtilCtxt* uc, XP_U16* min, XP_U16* max )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
HintLimitsState hls;
|
|
|
|
|
|
|
|
XP_MEMSET( &hls, 0, sizeof(hls) );
|
|
|
|
|
|
|
|
hls.globals = globals;
|
|
|
|
hls.min = *min;
|
|
|
|
hls.max = *max;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_ASKHINTLIMTS, globals->hWnd,
|
|
|
|
(DLGPROC)HintLimitsDlg, (long)&hls );
|
2004-07-10 19:46:36 +02:00
|
|
|
|
|
|
|
if ( !hls.cancelled ) {
|
|
|
|
*min = hls.min;
|
|
|
|
*max = hls.max;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !hls.cancelled;
|
|
|
|
} /* ce_util_getTraySearchLimits */
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
#ifdef SHOW_PROGRESS
|
|
|
|
static void
|
|
|
|
ce_util_engineStarting( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
} /* ce_util_engineStarting */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ce_util_engineStopping( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
} /* ce_util_engineStopping */
|
|
|
|
#endif
|