2006-02-06 05:41:14 +01:00
|
|
|
/* -*- fill-column: 77; c-basic-offset: 4; compile-command: "make TARGET_OS=wince"-*- */
|
2003-11-20 17:26:35 +01:00
|
|
|
/*
|
2006-01-08 02:25:02 +01:00
|
|
|
* Copyright 2002-2004 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>
|
|
|
|
#include <winuser.h>
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifndef CANT_DO_SHELL_THING
|
|
|
|
# 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"
|
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
|
|
|
|
|
|
|
#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
|
|
|
|
2005-02-06 07:56:06 +01:00
|
|
|
/* CE_DEBUG_SAVEOFTEN: Temporary hack to attempt to get a reproducible case
|
|
|
|
* of the lockup folks are seeing on WM 2003 SE devices.
|
|
|
|
*/
|
|
|
|
#define CE_DEBUG_SAVEOFTEN
|
|
|
|
|
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 */
|
2005-07-30 04:02:49 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
static XP_S16 ce_send_proc( XP_U8* buf, XP_U16 len,
|
|
|
|
const CommsAddrRec* addr,
|
2005-07-23 17:31:21 +02:00
|
|
|
void* closure );
|
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
|
|
|
|
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,
|
|
|
|
XW_TrayVisState newState );
|
2003-11-20 17:26:35 +01:00
|
|
|
static void ce_util_yOffsetChange( XW_UtilCtxt* uc, XP_U16 oldOffset,
|
|
|
|
XP_U16 newOffset );
|
|
|
|
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,
|
|
|
|
TimerProc 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 );
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
static XWStreamCtxt* ce_util_makeStreamFromAddr( XW_UtilCtxt* uc,
|
|
|
|
XP_U16 channelNo );
|
|
|
|
#endif
|
|
|
|
static XP_UCHAR* ce_util_getUserString( XW_UtilCtxt* uc, XP_U16 stringCode );
|
|
|
|
static XP_Bool ce_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
|
|
|
XP_U16 turn, XP_Bool turnLost );
|
2005-07-23 17:31:21 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
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 notImpl( CEAppGlobals* globals );
|
|
|
|
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-01-31 07:41:16 +01:00
|
|
|
static XP_Bool ceDoNewGame( CEAppGlobals* globals, XP_Bool silent );
|
2004-01-10 19:11:28 +01:00
|
|
|
static XP_Bool ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave );
|
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 );
|
|
|
|
static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
|
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);
|
|
|
|
LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);
|
|
|
|
|
|
|
|
int WINAPI
|
|
|
|
WinMain( HINSTANCE hInstance,
|
|
|
|
HINSTANCE hPrevInstance,
|
2005-11-27 21:16:43 +01:00
|
|
|
#if defined TARGET_OS_WINCE
|
|
|
|
LPWSTR lpCmdLine,
|
|
|
|
#elif defined TARGET_OS_WIN32
|
|
|
|
LPSTR lpCmdLine,
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
int nCmdShow)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
HACCEL hAccelTable;
|
|
|
|
|
|
|
|
// 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. */
|
|
|
|
|
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
|
|
|
XP_LOGF( "" );
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
#define N_TOOLBAR_BUTTONS 4
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
addButtonsToCmdBar( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
XP_Bool success;
|
|
|
|
XP_U16 i;
|
|
|
|
int index;
|
2006-02-06 05:41:14 +01:00
|
|
|
int cmds[] = { FLIP_BUTTON_ID, VALUE_BUTTON_ID,
|
|
|
|
HINT_BUTTON_ID, JUGGLE_BUTTON_ID };
|
|
|
|
int resIDs[] = { IDB_FLIPBUTTON, IDB_VALUESBUTTON,
|
|
|
|
IDB_HINTBUTTON, IDB_JUGGLEBUTTON };
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
TBBUTTON buttData = {
|
|
|
|
0, /*iBitmap; */
|
|
|
|
0, //FLIP_BUTTON_ID,
|
|
|
|
TBSTATE_ENABLED, /* state */
|
|
|
|
TBSTYLE_BUTTON,
|
|
|
|
0,
|
|
|
|
-1
|
|
|
|
};
|
|
|
|
|
2006-01-28 20:02:04 +01:00
|
|
|
#ifndef CANT_DO_CMDBAR
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifdef TARGET_OS_WINCE
|
2006-02-06 05:41:14 +01:00
|
|
|
for ( i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
index = CommandBar_AddBitmap(globals->hwndCB, globals->hInst,
|
|
|
|
resIDs[i], 1, 16, 16 );
|
|
|
|
buttData.iBitmap = index;
|
|
|
|
buttData.idCommand = cmds[i];
|
2006-02-06 05:41:14 +01:00
|
|
|
success = CommandBar_InsertButton( globals->hwndCB, -1,
|
|
|
|
(LPARAM)&buttData );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2006-01-28 20:02:04 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* addButtonsToCmdBar */
|
|
|
|
|
|
|
|
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;
|
|
|
|
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;
|
2005-07-23 17:31:21 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
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
|
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
|
|
|
{
|
|
|
|
if ( !globals->scrollHandle ) {
|
|
|
|
HWND hwndSB;
|
2005-06-13 16:29:49 +02:00
|
|
|
SCROLLINFO sinfo;
|
|
|
|
int ret;
|
|
|
|
|
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
|
|
|
|
|
2005-06-13 16:29:49 +02:00
|
|
|
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;
|
|
|
|
ret = SetScrollInfo( hwndSB, SB_CTL, &sinfo, TRUE );
|
|
|
|
|
|
|
|
EnableWindow( hwndSB, TRUE ); /* tray hidden */
|
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
|
|
|
|
|
|
|
|
#define MIN_CELL_WIDTH 12
|
|
|
|
#define MIN_CELL_HEIGHT 12
|
2005-11-27 23:06:04 +01:00
|
|
|
#if defined TARGET_OS_WINCE
|
|
|
|
# define MIN_TRAY_HEIGHT 20
|
|
|
|
#elif defined TARGET_OS_WIN32
|
|
|
|
# define MIN_TRAY_HEIGHT 40
|
|
|
|
#endif
|
2005-02-05 22:43:16 +01:00
|
|
|
#define TRAY_PADDING 1
|
|
|
|
|
|
|
|
typedef struct CEBoardParms {
|
|
|
|
XP_U16 boardHScale;
|
|
|
|
XP_U16 boardVScale;
|
|
|
|
XP_U16 trayTop;
|
2006-02-07 15:45:30 +01:00
|
|
|
XP_U16 trayVScale;
|
|
|
|
XP_U16 trayHScale;
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_U16 leftEdge;
|
|
|
|
XP_U16 scoreWidth;
|
|
|
|
XP_U16 scoreHeight;
|
|
|
|
XP_Bool needsScroller;
|
|
|
|
} CEBoardParms;
|
|
|
|
|
|
|
|
static void
|
|
|
|
figureBoardParms( CEAppGlobals* globals, XP_U16 nCols, CEBoardParms* bparms )
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
XP_U16 width, height;
|
2005-06-13 16:29:49 +02:00
|
|
|
XP_U16 trayVScale, leftEdge, scoreWidth;
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_U16 boardHt, boardWidth, visBoardHt, hScale, vScale, nHiddenRows;
|
|
|
|
XP_U16 boardHtLimit, trayTop;
|
|
|
|
XP_Bool needsScroller;
|
|
|
|
|
|
|
|
GetClientRect( globals->hWnd, &rc );
|
2005-06-30 03:48:07 +02:00
|
|
|
width = (XP_U16)(rc.right - rc.left);
|
|
|
|
height = (XP_U16)(rc.bottom - rc.top);
|
2005-02-05 22:43:16 +01:00
|
|
|
|
2005-06-13 16:29:49 +02:00
|
|
|
boardHt = height - CE_SCORE_HEIGHT - MIN_TRAY_HEIGHT;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
/* Try to make it fit without scrolling. But if necessary, reduce the
|
|
|
|
width for a scrollbar. */
|
|
|
|
vScale = boardHt / nCols;
|
|
|
|
needsScroller = vScale < MIN_CELL_HEIGHT;
|
|
|
|
if ( needsScroller ) {
|
|
|
|
vScale = MIN_CELL_HEIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
boardWidth = width;
|
|
|
|
if ( needsScroller ) {
|
|
|
|
boardWidth -= SCROLLBAR_WIDTH;
|
|
|
|
}
|
|
|
|
hScale = boardWidth / nCols;
|
|
|
|
|
|
|
|
/* Figure tray top. May overlap board. The tray's height must be at
|
|
|
|
least the minimum, plus whatever fraction of a row is left when
|
|
|
|
visible board height is determined. */
|
|
|
|
visBoardHt = vScale * nCols;
|
|
|
|
nHiddenRows = 0;
|
2005-06-13 16:29:49 +02:00
|
|
|
boardHtLimit = height - CE_SCORE_HEIGHT - MIN_TRAY_HEIGHT;
|
2005-02-05 22:43:16 +01:00
|
|
|
while ( visBoardHt > boardHtLimit ) {
|
|
|
|
visBoardHt -= vScale;
|
|
|
|
++nHiddenRows;
|
|
|
|
}
|
2005-06-13 16:29:49 +02:00
|
|
|
trayTop = CE_SCORE_HEIGHT + visBoardHt + TRAY_PADDING;
|
2005-02-05 22:43:16 +01:00
|
|
|
trayVScale = height - trayTop;
|
|
|
|
|
|
|
|
/* Center the board */
|
|
|
|
boardWidth = nCols * hScale;
|
|
|
|
if ( needsScroller ) {
|
|
|
|
boardWidth += SCROLLBAR_WIDTH;
|
|
|
|
}
|
|
|
|
leftEdge = (width - boardWidth) / 2; /* center it all */
|
|
|
|
|
|
|
|
scoreWidth = width;
|
|
|
|
if ( globals->gameInfo.timerEnabled ) {
|
|
|
|
scoreWidth -= CE_TIMER_WIDTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
bparms->boardHScale = hScale;
|
|
|
|
bparms->boardVScale = vScale;
|
|
|
|
bparms->trayTop = trayTop;
|
2006-02-07 15:45:30 +01:00
|
|
|
bparms->trayVScale = trayVScale;
|
2005-02-05 22:43:16 +01:00
|
|
|
bparms->trayHScale = CE_TRAY_SCALEH; /* unchanged so far... */
|
|
|
|
bparms->leftEdge = leftEdge;
|
|
|
|
bparms->scoreWidth = scoreWidth;
|
2005-06-13 16:29:49 +02:00
|
|
|
bparms->scoreHeight = CE_SCORE_HEIGHT;
|
2005-02-05 22:43:16 +01:00
|
|
|
|
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
bparms->needsScroller = needsScroller;
|
|
|
|
|
|
|
|
if ( needsScroller ) {
|
|
|
|
XP_U16 boardRight = leftEdge + (nCols * hScale);
|
2005-06-13 16:29:49 +02:00
|
|
|
showScroller( globals, nHiddenRows,
|
|
|
|
boardRight,
|
|
|
|
CE_SCORE_HEIGHT,
|
|
|
|
rc.right - boardRight, visBoardHt );
|
2005-02-05 22:43:16 +01:00
|
|
|
XP_LOGF( "NEEDING SCROLLBAR!!!!" );
|
|
|
|
XP_LOGF( "%d rows hidden", nHiddenRows );
|
|
|
|
} else {
|
|
|
|
hideScroller( globals );
|
|
|
|
}
|
|
|
|
globals->nHiddenRows = nHiddenRows;
|
|
|
|
#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
|
|
|
|
|
|
|
board_setTimerLoc( globals->game.board, CE_TIMER_LEFT,
|
|
|
|
CE_TIMER_TOP, CE_TIMER_WIDTH, CE_TIMER_HEIGHT );
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
board_setPos( globals->game.board, bparms.leftEdge,
|
|
|
|
bparms.scoreHeight, XP_FALSE );
|
|
|
|
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,
|
|
|
|
bparms.scoreHeight, XP_TRUE );
|
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 );
|
|
|
|
|
|
|
|
board_setTrayLoc( globals->game.board,
|
|
|
|
CE_TRAY_LEFT_RH,
|
2005-02-05 22:43:16 +01:00
|
|
|
bparms.trayTop,
|
|
|
|
bparms.trayHScale, bparms.trayVScale,
|
2003-11-20 17:26:35 +01:00
|
|
|
CE_DIVIDER_WIDTH );
|
|
|
|
|
|
|
|
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
|
2005-07-23 17:31:21 +02:00
|
|
|
ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame, CeGamePrefs* gp,
|
|
|
|
const CommsAddrRec* 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 ) {
|
|
|
|
XP_UCHAR* curDictName = dict_getName( dict );
|
|
|
|
if ( !!newDictName &&
|
|
|
|
( !curDictName || 0 != strcmp( curDictName, newDictName ) ) ) {
|
|
|
|
dict_destroy( dict );
|
|
|
|
dict = NULL;
|
|
|
|
} else {
|
|
|
|
replaceStringIfDifferent( MEMPOOL &globals->gameInfo.dictName,
|
|
|
|
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 );
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_DEBUGF( "calling ce_dictionary_make" );
|
|
|
|
dict = ce_dictionary_make( globals, copyString( MEMPOOL newDictName ));
|
|
|
|
#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,
|
2004-01-17 23:10:23 +01:00
|
|
|
globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
if ( !!gp ) {
|
|
|
|
globals->gameInfo.hintsNotAllowed = gp->hintsNotAllowed;
|
|
|
|
globals->gameInfo.robotSmartness = gp->robotSmartness;
|
|
|
|
}
|
2005-07-23 17:31:21 +02:00
|
|
|
|
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
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 );
|
|
|
|
(void)cePositionBoard( globals );
|
|
|
|
|
|
|
|
board_invalAll( globals->game.board );
|
|
|
|
InvalidateRect( globals->hWnd, NULL, TRUE /* erase */ );
|
|
|
|
|
2005-08-21 16:36:11 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
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
|
|
|
|
|
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-01-28 20:02:04 +01:00
|
|
|
sprintf( msg, "%s (err: %d): ", 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 );
|
|
|
|
XP_DEBUGF( "sizeof(appPrefs) => %ld", sizeof( globals->appPrefs ) );
|
|
|
|
|
|
|
|
WriteFile( fileH, &nameLen, sizeof(nameLen), &nWritten, NULL );
|
|
|
|
WriteFile( fileH, name, nameLen, &nWritten, NULL );
|
|
|
|
|
|
|
|
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 */
|
|
|
|
|
|
|
|
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 );
|
|
|
|
XP_DEBUGF( "ceLoadPrefs: prefs file found" );
|
|
|
|
if ( fileSize >= sizeof( CEAppPrefs ) ) {
|
|
|
|
CEAppPrefs tmpPrefs;
|
|
|
|
XP_U32 bytesRead;
|
|
|
|
XP_U16 nameLen;
|
|
|
|
XP_UCHAR* name;
|
|
|
|
|
|
|
|
if ( ReadFile( fileH, &tmpPrefs, sizeof(tmpPrefs),
|
|
|
|
&bytesRead, NULL ) ) {
|
|
|
|
|
|
|
|
if ( tmpPrefs.versionFlags == CUR_CE_PREFS_FLAGS ) {
|
|
|
|
|
|
|
|
XP_MEMCPY( &globals->appPrefs, &tmpPrefs,
|
|
|
|
sizeof(globals->appPrefs) );
|
|
|
|
result = XP_TRUE;
|
|
|
|
|
|
|
|
ReadFile( fileH, &nameLen, sizeof(nameLen), &bytesRead, NULL );
|
|
|
|
name = XP_MALLOC( globals->mpool, nameLen + 1 );
|
|
|
|
ReadFile( fileH, name, nameLen, &bytesRead, NULL );
|
|
|
|
name[nameLen] = '\0';
|
|
|
|
globals->curGameName = name;
|
|
|
|
|
|
|
|
XP_DEBUGF( "loaded saved name: %s", name );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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 */
|
|
|
|
|
2004-01-10 19:11:28 +01:00
|
|
|
static void
|
|
|
|
ceSaveGamePrefs( CEAppGlobals* globals, XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
} /* ceSaveGamePrefs */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ceLoadGamePrefs( CEAppGlobals* globals, XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
XP_DEBUGF( "ceLoadGamePrefs" );
|
|
|
|
} /* ceLoadGamePrefs */
|
|
|
|
|
|
|
|
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;
|
|
|
|
ceLoadGamePrefs( globals, stream );
|
|
|
|
|
|
|
|
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
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_UCHAR* name = stringFromStream( MPPARM(globals->mpool)
|
|
|
|
stream );
|
|
|
|
dict = ce_dictionary_make( globals, 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,
|
2005-07-30 04:02:49 +02:00
|
|
|
&globals->appPrefs.cp, CE_SEND_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
|
|
|
|
colorsFromRsrc( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
XP_LOGF( "setting colors in globals" );
|
|
|
|
|
|
|
|
for ( i = 0; i < NUM_COLORS; ++i ) {
|
|
|
|
XP_U8 r = (XP_U8)*ptr++;
|
|
|
|
XP_U8 g = (XP_U8)*ptr++;
|
|
|
|
XP_U8 b = (XP_U8)*ptr++;
|
|
|
|
globals->appPrefs.colors[i] = RGB( r, g, b );
|
|
|
|
}
|
|
|
|
|
|
|
|
DeleteObject( globH );
|
|
|
|
} /* colorsFromRsrc */
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
ceInitPrefs( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
globals->appPrefs.versionFlags = CUR_CE_PREFS_FLAGS;
|
2004-05-28 04:45:49 +02:00
|
|
|
globals->appPrefs.showColors = XP_TRUE;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
globals->appPrefs.cp.showBoardArrow = XP_TRUE;
|
|
|
|
globals->appPrefs.cp.showRobotScores = XP_FALSE;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
|
|
|
colorsFromRsrc( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ceInitPrefs */
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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-02-06 05:41:14 +01:00
|
|
|
#ifdef BEYOND_IR
|
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) );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
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) );
|
|
|
|
XP_DEBUGF( "" );
|
|
|
|
XP_DEBUGF( "globals created: 0x%lx", globals );
|
|
|
|
XP_MEMSET( globals, 0, sizeof(*globals) );
|
|
|
|
MPASSIGN( globals->mpool, mpool );
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (!hWnd) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
#ifdef _WIN32_WCE
|
2004-12-17 08:45:30 +01:00
|
|
|
if ( globals->hwndCB ) {
|
|
|
|
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 );
|
|
|
|
|
|
|
|
/* choose one. If none found it's an error. */
|
2004-01-17 23:10:23 +01:00
|
|
|
#ifndef STUBBED_DICT
|
2003-11-20 17:26:35 +01:00
|
|
|
globals->gameInfo.dictName = ceLocateNthDict( MPPARM(mpool) 0 );
|
|
|
|
result = globals->gameInfo.dictName != NULL;
|
2004-01-10 19:11:28 +01:00
|
|
|
if ( !result ) {
|
|
|
|
messageBoxChar( globals, "Please install at least one Crosswords "
|
|
|
|
"dictionary.", L"Fatal error" );
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-17 23:10:23 +01:00
|
|
|
#endif
|
2004-01-10 19:11:28 +01:00
|
|
|
|
|
|
|
gi_initPlayerInfo( MPPARM(mpool) &globals->gameInfo, "Player %d" );
|
|
|
|
|
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 ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
ceInitPrefs( globals );
|
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,
|
2005-07-30 04:02:49 +02:00
|
|
|
CE_SEND_PROC, globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
2006-01-31 07:41:16 +01:00
|
|
|
newDone = ceDoNewGame( globals, XP_TRUE ); /* 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-01-28 20:02:04 +01:00
|
|
|
#ifndef CANT_DO_CMDBAR
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifdef TARGET_OS_WINCE
|
2003-11-20 17:26:35 +01:00
|
|
|
if (globals->hwndCB) {
|
|
|
|
CommandBar_Show(globals->hwndCB, TRUE);
|
|
|
|
}
|
2006-01-28 20:02:04 +01:00
|
|
|
#endif
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-12-09 06:18:47 +01:00
|
|
|
if ( result && !newDone ) {
|
2005-07-23 17:31:21 +02:00
|
|
|
ceInitAndStartBoard( globals, !oldGameLoaded, NULL, NULL );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
} /* InitInstance */
|
|
|
|
|
|
|
|
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;
|
|
|
|
return draw;
|
|
|
|
} /* ceHandleHintRequest */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleTradeCmd( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
return board_beginTrade( globals->game.board );
|
|
|
|
} /* handleTradeCmd */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
handleJuggleCmd( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
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
|
|
|
|
drawInsidePaint( HWND hWnd, CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
|
2004-02-12 05:35:10 +01:00
|
|
|
hdc = GetDC( hWnd );
|
|
|
|
if ( !hdc ) {
|
2006-01-31 07:41:16 +01:00
|
|
|
logLastError( __FUNCTION__ );
|
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-01-31 07:41:16 +01:00
|
|
|
ceDoNewGame( CEAppGlobals* globals, XP_Bool silent )
|
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
|
|
|
|
&& ((XP_U16)XP_STRLEN(giState.newDictName) > 0)
|
|
|
|
#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
|
|
|
}
|
2005-07-23 17:31:21 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
if ( giState.addrChanged ) {
|
|
|
|
addr = &giState.prefsPrefs.addrRec;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ceInitAndStartBoard( globals, XP_TRUE, NULL, 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;
|
|
|
|
openFileStruct.nMaxFile = sizeof(path)/sizeof(path[0]);
|
|
|
|
|
|
|
|
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;
|
|
|
|
ceLoadSavedGame( globals );
|
2005-07-23 17:31:21 +02:00
|
|
|
ceInitAndStartBoard( globals, XP_FALSE, NULL, NULL );
|
2003-11-20 17:26:35 +01:00
|
|
|
ceSetTitleFromName( globals );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* ceChooseAndOpen */
|
|
|
|
|
2004-04-14 06:00:28 +02:00
|
|
|
static void
|
|
|
|
updateForColors( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
ce_drawctxt_update( globals->draw, globals );
|
|
|
|
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;
|
|
|
|
CEAppGlobals* globals = fwState->globals;
|
|
|
|
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
|
|
|
|
makeUniqueName( wchar_t* buf, XP_U16 bufLen )
|
|
|
|
{
|
|
|
|
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
|
|
|
|
2004-02-18 05:25:29 +01:00
|
|
|
makeUniqueName( nameBuf, sizeof(nameBuf)/sizeof(nameBuf[0]) );
|
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;
|
|
|
|
sfs.nMaxFile = sizeof(nameBuf)/sizeof(nameBuf[0]);
|
|
|
|
|
|
|
|
sfs.lpstrDefExt = L"xwg";
|
|
|
|
|
2004-02-14 07:13:18 +01:00
|
|
|
// sfs.lpstrTitle: doesn't work
|
|
|
|
// 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;
|
|
|
|
char* dictName;
|
|
|
|
|
|
|
|
fwState.path = globals->curGameName;
|
|
|
|
fwState.globals = globals;
|
2005-02-06 07:56:06 +01:00
|
|
|
#ifndef CE_DEBUG_SAVEOFTEN
|
2003-11-20 17:26:35 +01:00
|
|
|
board_hideTray( globals->game.board ); /* so won't be visible when
|
|
|
|
next opened */
|
2005-02-06 07:56:06 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
memStream = mem_stream_make( MEMPOOL globals->vtMgr, &fwState, 0,
|
|
|
|
ceWriteToFile );
|
|
|
|
stream_open( memStream );
|
|
|
|
|
|
|
|
ceSaveGamePrefs( globals, 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 */
|
|
|
|
|
2004-12-17 08:45:30 +01:00
|
|
|
static HWND
|
|
|
|
makeCommandBar( HWND hwnd, HINSTANCE hInst )
|
|
|
|
{
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifndef CANT_DO_SHELL_THING
|
2004-12-17 08:45:30 +01:00
|
|
|
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;
|
|
|
|
mbi.nToolBarId = IDM_MENU;
|
|
|
|
mbi.hInstRes = hInst;
|
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)) {
|
|
|
|
XP_LOGF( "SHCreateMenuBar failed" );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mbi.hwndMB;
|
2005-11-27 21:16:43 +01:00
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2004-12-17 08:45:30 +01:00
|
|
|
} /* makeCommandBar */
|
|
|
|
|
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:
|
|
|
|
XP_LOGF( "Got scroll message: %d", pos );
|
|
|
|
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-02-06 07:56:06 +01:00
|
|
|
#ifdef CE_DEBUG_SAVEOFTEN
|
|
|
|
static void
|
|
|
|
debug_saveCurState( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
ceSaveCurGame( globals, XP_TRUE );
|
|
|
|
ceSavePrefs( globals );
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# define debug_saveCurState(g)
|
|
|
|
#endif
|
|
|
|
|
2005-06-23 16:09:20 +02:00
|
|
|
static void
|
|
|
|
ceFireTimer( CEAppGlobals* globals, XWTimerReason why )
|
|
|
|
{
|
2005-08-21 16:07:29 +02:00
|
|
|
TimerProc proc;
|
|
|
|
void* closure;
|
|
|
|
|
|
|
|
proc = globals->timerProcs[why];
|
|
|
|
closure = globals->timerClosures[why];
|
2005-06-23 16:09:20 +02:00
|
|
|
(*proc)( closure, why );
|
2005-08-21 16:07:29 +02:00
|
|
|
} /* ceFireTimer */
|
2005-06-23 16:09:20 +02:00
|
|
|
|
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
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
LRESULT CALLBACK
|
|
|
|
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
int wmId, wmEvent;
|
|
|
|
RECT rt;
|
|
|
|
XP_Bool draw = XP_FALSE;
|
|
|
|
XWTimerReason why;
|
|
|
|
CEAppGlobals* globals;
|
2004-06-25 09:19:05 +02:00
|
|
|
XP_Bool handled;
|
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 );
|
2003-11-20 17:26:35 +01:00
|
|
|
addButtonsToCmdBar( globals );
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2005-06-13 16:29:49 +02:00
|
|
|
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifndef CANT_DO_SHELL_THING
|
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 {
|
|
|
|
globals = (CEAppGlobals*)GetWindowLong( hWnd, GWL_USERDATA );
|
|
|
|
|
|
|
|
switch (message) {
|
2004-12-17 08:45:30 +01:00
|
|
|
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifndef CANT_DO_SHELL_THING
|
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;
|
2006-02-06 05:41:14 +01:00
|
|
|
#endif
|
2004-12-17 08:45:30 +01:00
|
|
|
|
|
|
|
case WM_SETTINGCHANGE:
|
2006-02-06 05:41:14 +01:00
|
|
|
#ifndef CANT_DO_SHELL_THING
|
2004-12-17 08:45:30 +01:00
|
|
|
SHHandleWMSettingChange( hWnd, wParam, lParam, &globals->sai );
|
2006-02-06 05:41:14 +01:00
|
|
|
#endif
|
2005-06-13 16:29:49 +02:00
|
|
|
cePositionBoard( globals );
|
|
|
|
board_invalAll( globals->game.board );
|
|
|
|
draw = XP_TRUE;
|
2004-12-17 08:45:30 +01:00
|
|
|
break;
|
|
|
|
|
2005-02-05 22:43:16 +01:00
|
|
|
#ifdef CEFEATURE_CANSCROLL
|
|
|
|
case WM_VSCROLL:
|
|
|
|
draw = handleScroll( globals, (short int)HIWORD(wParam),
|
|
|
|
(short int)LOWORD(wParam),
|
|
|
|
(HWND)lParam );
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
case WM_COMMAND:
|
|
|
|
wmId = LOWORD(wParam);
|
|
|
|
wmEvent = HIWORD(wParam);
|
|
|
|
// Parse the menu selections:
|
|
|
|
switch (wmId) {
|
|
|
|
case ID_FILE_ABOUT:
|
2006-02-06 05:41:14 +01:00
|
|
|
DialogBoxParam(globals->hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd,
|
|
|
|
(DLGPROC)About, 0L );
|
2003-11-20 17:26:35 +01:00
|
|
|
break;
|
|
|
|
case ID_GAME_GAMEINFO: {
|
|
|
|
GameInfoState state;
|
|
|
|
|
|
|
|
XP_MEMSET( &state, 0, sizeof(state) );
|
|
|
|
state.globals = globals;
|
|
|
|
state.isNewGame = XP_FALSE;
|
|
|
|
|
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
|
|
|
|
|
|
|
if ( !state.userCancelled && state.prefsChanged ) {
|
|
|
|
/* need to update some prefs? */
|
2004-04-14 06:00:28 +02:00
|
|
|
/* if ( state.colorsChanged ) { */
|
|
|
|
updateForColors( globals );
|
|
|
|
/* } */
|
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-01-31 07:41:16 +01:00
|
|
|
draw = ceDoNewGame( globals, XP_FALSE );
|
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;
|
|
|
|
|
|
|
|
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:
|
2004-01-10 19:11:28 +01:00
|
|
|
case JUGGLE_BUTTON_ID:
|
2003-11-20 17:26:35 +01:00
|
|
|
draw = handleJuggleCmd( globals );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_MOVE_HIDETRAY:
|
|
|
|
draw = handleHidetrayCmd( globals );
|
|
|
|
break;
|
|
|
|
case ID_MOVE_TURNDONE:
|
|
|
|
draw = handleDoneCmd( globals);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FLIP_BUTTON_ID:
|
|
|
|
draw = board_flip( globals->game.board );
|
|
|
|
break;
|
|
|
|
case VALUE_BUTTON_ID:
|
|
|
|
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:
|
|
|
|
case HINT_BUTTON_ID:
|
|
|
|
draw = ceHandleHintRequest( globals );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IDM_FILE_EXIT:
|
|
|
|
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:
|
|
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2004-05-26 06:48:25 +02:00
|
|
|
drawInsidePaint( hWnd, globals );
|
|
|
|
}
|
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:
|
|
|
|
globals->penDown = XP_TRUE;
|
|
|
|
draw = board_handlePenDown( globals->game.board, LOWORD(lParam),
|
2005-07-14 04:54:47 +02:00
|
|
|
HIWORD(lParam), &handled );
|
2005-02-06 07:56:06 +01:00
|
|
|
debug_saveCurState( globals );
|
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) );
|
2005-02-06 07:56:06 +01:00
|
|
|
debug_saveCurState( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_LBUTTONUP:
|
|
|
|
if ( globals->penDown ) {
|
|
|
|
draw = board_handlePenUp( globals->game.board, LOWORD(lParam),
|
|
|
|
HIWORD(lParam), 0 );
|
|
|
|
globals->penDown = XP_FALSE;
|
2005-02-06 07:56:06 +01:00
|
|
|
debug_saveCurState( globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_CHAR:
|
|
|
|
if ( wParam == 0x08 ) {
|
|
|
|
wParam = XP_CURSOR_KEY_DEL;
|
|
|
|
}
|
|
|
|
draw = board_handleKey( globals->game.board, wParam )
|
|
|
|
|| board_handleKey( globals->game.board, wParam - ('a'-'A') );
|
2005-02-06 07:56:06 +01:00
|
|
|
debug_saveCurState( globals );
|
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
|
|
|
|
#ifdef BEYOND_IR
|
|
|
|
|| 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-01-28 20:02:04 +01:00
|
|
|
#ifndef CANT_DO_CMDBAR
|
2005-11-27 21:16:43 +01:00
|
|
|
#ifdef TARGET_OS_WINCE
|
2004-06-25 09:19:05 +02:00
|
|
|
CommandBar_Destroy(globals->hwndCB); /* supposedly not needed */
|
2006-01-28 20:02:04 +01:00
|
|
|
#endif
|
2005-11-27 21:16:43 +01:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
PostQuitMessage(0);
|
|
|
|
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:
|
|
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( draw ) {
|
|
|
|
/* 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
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
} /* WndProc */
|
|
|
|
|
|
|
|
// Mesage handler for the About box.
|
|
|
|
LRESULT CALLBACK
|
|
|
|
About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))
|
|
|
|
{
|
|
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
} /* About */
|
|
|
|
|
|
|
|
static void
|
|
|
|
notImpl( CEAppGlobals* globals )
|
|
|
|
{
|
|
|
|
messageBoxChar( globals, "feature not implemented", NULL );
|
|
|
|
} /* notImpl */
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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,
|
|
|
|
sizeof(widebuf)/sizeof(widebuf[0]) );
|
|
|
|
widebuf[len] = 0;
|
|
|
|
|
|
|
|
answer = MessageBox( globals->hWnd, widebuf, L"Question", MB_YESNO );
|
|
|
|
return answer == IDOK || answer == IDYES;
|
|
|
|
} /* queryBoxChar */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
queryBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream )
|
|
|
|
{
|
|
|
|
XP_UCHAR* buf = ceStreamToStrBuf( MPPARM(globals->mpool) stream );
|
|
|
|
XP_Bool result = queryBoxChar( globals, buf );
|
|
|
|
XP_FREE( globals->mpool, buf );
|
|
|
|
return result;
|
|
|
|
} /* queryBoxStream */
|
|
|
|
|
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
|
|
|
|
wince_assert( XP_UCHAR* s, int line, char* fileName )
|
|
|
|
{
|
|
|
|
XP_WARNF( "ASSERTION FAILED %s: file %s, line %d\n", s, fileName, line );
|
|
|
|
} /* wince_assert */
|
|
|
|
|
2005-08-21 16:54:49 +02:00
|
|
|
#ifdef DEBUG
|
2003-11-20 17:26:35 +01:00
|
|
|
static void
|
|
|
|
makeTimeStamp( XP_UCHAR* timeStamp, XP_U16 size )
|
|
|
|
{
|
|
|
|
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
|
|
|
|
wince_debugf(XP_UCHAR* format, ...)
|
|
|
|
{
|
2005-08-21 16:54:49 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
static HANDLE s_logMutex = NULL;
|
|
|
|
DWORD wres;
|
|
|
|
#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
|
|
|
|
2005-08-21 16:54:49 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
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 );
|
2005-08-21 16:54:49 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
ReleaseMutex( s_logMutex );
|
2003-11-20 17:26:35 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
} /* wince_debugf */
|
2005-08-21 16:54:49 +02:00
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
XP_U16
|
|
|
|
wince_snprintf( XP_UCHAR* buf, XP_U16 len, XP_UCHAR* format, ... )
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
|
2005-07-30 04:02:49 +02:00
|
|
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
|
|
|
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 */
|
|
|
|
|
2005-07-23 17:31:21 +02:00
|
|
|
static XP_S16
|
2005-07-30 04:02:49 +02:00
|
|
|
ce_send_proc( 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)
|
|
|
|
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
|
|
|
/* I can't believe the stupid compiler's making me implement this */
|
|
|
|
void p_ignore(XP_UCHAR* c, ...){}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2006-02-06 05:41:14 +01:00
|
|
|
#ifdef BEYOND_IR
|
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:
|
|
|
|
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;
|
|
|
|
char* info = NULL;
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
2004-02-17 06:00:13 +01:00
|
|
|
XP_Bool answer = XP_FALSE;
|
2003-11-20 17:26:35 +01:00
|
|
|
XP_Bool queryWithStream = XP_FALSE;
|
|
|
|
|
|
|
|
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
|
|
|
|
ce_util_getSquareBonus( XW_UtilCtxt* uc, ModelCtxt* model,
|
|
|
|
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
|
2005-11-27 21:16:43 +01:00
|
|
|
ce_util_trayHiddenChange( XW_UtilCtxt* uc, XW_TrayVisState newState )
|
2003-11-20 17:26:35 +01:00
|
|
|
{
|
2004-02-13 14:49:25 +01:00
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
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 */
|
|
|
|
if ( !!globals->scrollHandle ) {
|
2005-11-27 21:16:43 +01:00
|
|
|
EnableWindow( globals->scrollHandle, TRAY_HIDDEN != newState );
|
2005-02-05 22:43:16 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-02-13 14:49:25 +01:00
|
|
|
drawInsidePaint( globals->hWnd, globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
} /* ce_util_trayHiddenChange */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ce_util_yOffsetChange( XW_UtilCtxt* uc, XP_U16 oldOffset,
|
|
|
|
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 */
|
|
|
|
|
|
|
|
static void
|
|
|
|
ce_util_notifyGameOver( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
|
|
|
drawInsidePaint( globals->hWnd, globals );
|
|
|
|
ceDisplayFinalScores( globals );
|
|
|
|
} /* ce_util_notifyGameOver */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ce_util_hiliteCell( XW_UtilCtxt* uc, XP_U16 col, XP_U16 row )
|
|
|
|
{
|
|
|
|
return XP_TRUE;
|
|
|
|
} /* ce_util_hiliteCell */
|
|
|
|
|
|
|
|
static XP_Bool
|
|
|
|
ce_util_engineProgressCallback( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
return XP_TRUE;
|
|
|
|
} /* ce_util_engineProgressCallback */
|
|
|
|
|
|
|
|
static void
|
2005-06-23 16:09:20 +02:00
|
|
|
ce_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
|
|
|
TimerProc 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;
|
2005-07-13 14:35:38 +02:00
|
|
|
#ifdef BEYOND_IR
|
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
|
|
|
}
|
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
|
|
|
|
ce_util_getCurSeconds( XW_UtilCtxt* uc )
|
|
|
|
{
|
|
|
|
return 0L;
|
|
|
|
} /* 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 */
|
|
|
|
|
2005-08-21 16:36:11 +02:00
|
|
|
#ifdef BEYOND_IR
|
2003-11-20 17:26:35 +01:00
|
|
|
static XWStreamCtxt*
|
|
|
|
ce_util_makeStreamFromAddr( XW_UtilCtxt* uc, XP_U16 channelNo )
|
|
|
|
{
|
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
|
|
|
|
|
|
|
|
static XP_UCHAR*
|
|
|
|
ce_util_getUserString( XW_UtilCtxt* uc, XP_U16 stringCode )
|
|
|
|
{
|
|
|
|
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";
|
|
|
|
|
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,
|
|
|
|
XP_U16 turn, XP_Bool turnLost )
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
|
2005-07-23 17:31:21 +02:00
|
|
|
#ifdef BEYOND_IR
|
|
|
|
static void
|
|
|
|
ce_util_addrChange( XW_UtilCtxt* uc, const CommsAddrRec* oldAddr,
|
|
|
|
const CommsAddrRec* newAddr )
|
|
|
|
{
|
|
|
|
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
|