X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=96bca01f0cb9c039e151cff4bb18a044ce4b2f76;hb=7c9ee0544821f7981792be03e90ba15e9a8aeada;hp=d9134d7d972b4f6b9ad3370612baa0ac9a9f60b6;hpb=b007f4ba1646094b75723e0a911321536ebe6918;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index d9134d7..a9d7454 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -73,6 +73,7 @@ #include #include #include +#include #if __GNUC__ #include @@ -80,13 +81,11 @@ #endif #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "moves.h" #include "wclipbrd.h" -#include "wgamelist.h" -#include "wedittags.h" #include "woptions.h" #include "wsockerr.h" #include "defaults.h" @@ -103,14 +102,15 @@ Boolean flipClock = FALSE; extern HANDLE chatHandle[]; extern int ics_type; +int MySearchPath P((char *installDir, char *name, char *fullname)); +int MyGetFullPathName P((char *name, char *fullname)); void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber); VOID NewVariantPopup(HWND hwnd); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, /*char*/int promoChar)); -void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames); void DisplayMove P((int moveNumber)); Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); -void ChatPopUp P(()); +void ChatPopUp P((char *s)); typedef struct { ChessSquare piece; POINT pos; /* window coordinates of current pos */ @@ -126,9 +126,10 @@ typedef struct { POINT pos; /* window coordinates of current pos */ POINT lastpos; /* window coordinates of last pos - used for clipping */ POINT from; /* board coordinates of the piece's orig pos */ + ChessSquare piece; } DragInfo; -static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1} }; +static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, EmptySquare }; typedef struct { POINT sq[2]; /* board coordinates of from, to squares */ @@ -136,6 +137,8 @@ typedef struct { static HighlightInfo highlightInfo = { {{-1, -1}, {-1, -1}} }; static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} }; +static HighlightInfo partnerHighlightInfo = { {{-1, -1}, {-1, -1}} }; +static HighlightInfo oldPartnerHighlight = { {{-1, -1}, {-1, -1}} }; typedef struct { // [HGM] atomic int fromX, fromY, toX, toY, radius; @@ -153,15 +156,16 @@ char szConsoleTitle[] = "I C S Interaction"; char *programName; char *settingsFileName; -BOOLEAN saveSettingsOnExit; +Boolean saveSettingsOnExit; char installDir[MSG_SIZ]; +int errorExitStatus; BoardSize boardSize; -BOOLEAN chessProgram; -static int boardX, boardY; +Boolean chessProgram; +//static int boardX, boardY; int minX, minY; // [HGM] placement: volatile limits on upper-left corner -static int squareSize, lineGap, minorSize; -static int winWidth, winHeight, winW, winH; +int squareSize, lineGap, minorSize; +static int winW, winH; static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo static int logoHeight = 0; static char messageText[MESSAGE_TEXT_MAX]; @@ -176,29 +180,27 @@ char *icsNames; char *firstChessProgramNames; char *secondChessProgramNames; -#define ARG_MAX 128*1024 /* [AS] For Roger Brown's very long list! */ - #define PALETTESIZE 256 HINSTANCE hInst; /* current instance */ -HWND hwndMain = NULL; /* root window*/ -HWND hwndConsole = NULL; -BOOLEAN alwaysOnTop = FALSE; +Boolean alwaysOnTop = FALSE; RECT boardRect; COLORREF lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor, highlightSquareColor, premoveHighlightColor; HPALETTE hPal; ColorClass currentColorClass; +static HWND savedHwnd; HWND hCommPort = NULL; /* currently open comm port */ static HWND hwndPause; /* pause button */ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */ static HBRUSH lightSquareBrush, darkSquareBrush, blackSquareBrush, /* [HGM] for band between board and holdings */ explodeBrush, /* [HGM] atomic */ + markerBrush, /* [HGM] markers */ whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/; -static POINT gridEndpoints[(BOARD_SIZE + 1) * 4]; -static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2]; +static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2]; +static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2]; static HPEN gridPen = NULL; static HPEN highlightPen = NULL; static HPEN premovePen = NULL; @@ -210,17 +212,12 @@ static int lastSizing = 0; static int prevStderrPort; static HBITMAP userLogo; -/* [AS] Support for background textures */ -#define BACK_TEXTURE_MODE_DISABLED 0 -#define BACK_TEXTURE_MODE_PLAIN 1 -#define BACK_TEXTURE_MODE_FULL_RANDOM 2 - static HBITMAP liteBackTexture = NULL; static HBITMAP darkBackTexture = NULL; static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN; static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN; static int backTextureSquareSize = 0; -static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE]; +static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOARD_FILES]; #if __GNUC__ && !defined(_winmajor) #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */ @@ -232,13 +229,295 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOAR #endif #endif -char *defaultTextAttribs[] = -{ - COLOR_SHOUT, COLOR_SSHOUT, COLOR_CHANNEL1, COLOR_CHANNEL, COLOR_KIBITZ, - COLOR_TELL, COLOR_CHALLENGE, COLOR_REQUEST, COLOR_SEEK, COLOR_NORMAL, - COLOR_NONE +#define INTERNATIONAL + +#ifdef INTERNATIONAL +# define _(s) T_(s) +# define N_(s) s +#else +# define _(s) s +# define N_(s) s +# define T_(s) s +# define Translate(x, y) +# define LoadLanguageFile(s) +#endif + +#ifdef INTERNATIONAL + +Boolean barbaric; // flag indicating if translation is needed + +// list of item numbers used in each dialog (used to alter language at run time) + +#define ABOUTBOX -1 /* not sure why these are needed */ +#define ABOUTBOX2 -1 + +int dialogItems[][42] = { +{ ABOUTBOX, IDOK, OPT_MESS, 400 }, +{ DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, + OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors, IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, +{ DLG_LoadOptions, OPT_Autostep, OPT_AStext1, OPT_Exact, OPT_Subset, OPT_Struct, OPT_Material, OPT_Range, OPT_Difference, + OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds, IDOK, IDCANCEL }, +{ DLG_SaveOptions, OPT_Autosave, OPT_AVPrompt, OPT_AVToFile, OPT_AVBrowse, + 801, OPT_PGN, OPT_Old, OPT_OutOfBookInfo, IDOK, IDCANCEL }, +{ 1536, 1090, IDC_Directories, 1089, 1091, IDOK, IDCANCEL, 1038, IDC_IndexNr, 1037 }, +{ DLG_CommPort, IDOK, IDCANCEL, IDC_Port, IDC_Rate, IDC_Bits, IDC_Parity, + IDC_Stop, IDC_Flow, OPT_SerialHelp }, +{ DLG_EditComment, IDOK, OPT_CancelComment, OPT_ClearComment, OPT_EditComment }, +{ DLG_PromotionKing, PB_Chancellor, PB_Archbishop, PB_Queen, PB_Rook, + PB_Bishop, PB_Knight, PB_King, IDCANCEL, IDC_Yes, IDC_No, IDC_Centaur }, +{ ABOUTBOX2, IDC_ChessBoard }, +{ DLG_GameList, OPT_GameListLoad, OPT_GameListPrev, OPT_GameListNext, + OPT_GameListClose, IDC_GameListDoFilter }, +{ DLG_EditTags, IDOK, OPT_TagsCancel, OPT_EditTags }, +{ DLG_Error, IDOK }, +{ DLG_Colorize, IDOK, IDCANCEL, OPT_ChooseColor, OPT_Bold, OPT_Italic, + OPT_Underline, OPT_Strikeout, OPT_Sample }, +{ DLG_Question, IDOK, IDCANCEL, OPT_QuestionText }, +{ DLG_Startup, IDC_Welcome, OPT_ChessEngine, OPT_ChessServer, OPT_View, + IDC_SPECIFY_ENG_STATIC, IDC_SPECIFY_SERVER_STATIC, OPT_AnyAdditional, + IDOK, IDCANCEL, IDM_HELPCONTENTS }, +{ DLG_IndexNumber, IDC_Index }, +{ DLG_TypeInMove, IDOK, IDCANCEL }, +{ DLG_TypeInName, IDOK, IDCANCEL }, +{ DLG_Sound, IDC_Event, OPT_NoSound, OPT_DefaultBeep, OPT_BuiltInSound, + OPT_WavFile, OPT_BrowseSound, OPT_DefaultSounds, IDOK, IDCANCEL, OPT_PlaySound }, +{ DLG_GeneralOptions, IDOK, IDCANCEL, OPT_AlwaysOnTop, OPT_HighlightLastMove, + OPT_AlwaysQueen, OPT_PeriodicUpdates, OPT_AnimateDragging, OPT_PonderNextMove, + OPT_AnimateMoving, OPT_PopupExitMessage, OPT_AutoFlag, OPT_PopupMoveErrors, + OPT_AutoFlipView, OPT_ShowButtonBar, OPT_AutoRaiseBoard, OPT_ShowCoordinates, + OPT_Blindfold, OPT_ShowThinking, OPT_HighlightDragging, OPT_TestLegality, + OPT_SaveExtPGN, OPT_HideThinkFromHuman, OPT_ExtraInfoInMoveHistory, + OPT_HighlightMoveArrow, OPT_AutoLogo ,OPT_SmartMove }, +{ DLG_IcsOptions, IDOK, IDCANCEL, OPT_AutoComment, OPT_AutoKibitz, OPT_AutoObserve, + OPT_GetMoveList, OPT_LocalLineEditing, OPT_QuietPlay, OPT_SeekGraph, OPT_AutoRefresh, + OPT_BgObserve, OPT_DualBoard, OPT_Premove, OPT_PremoveWhite, OPT_PremoveBlack, + OPT_SmartMove, OPT_IcsAlarm, IDC_Sec, OPT_ChooseShoutColor, OPT_ChooseSShoutColor, + OPT_ChooseChannel1Color, OPT_ChooseChannelColor, OPT_ChooseKibitzColor, + OPT_ChooseTellColor, OPT_ChooseChallengeColor, OPT_ChooseRequestColor, + OPT_ChooseSeekColor, OPT_ChooseNormalColor, OPT_ChooseBackgroundColor, + OPT_DefaultColors, OPT_DontColorize, IDC_Boxes, GPB_Colors, GPB_Premove, + GPB_General, GPB_Alarm }, +{ DLG_BoardOptions, IDOK, IDCANCEL, OPT_SizeTiny, OPT_SizeTeeny, OPT_SizeDinky, + OPT_SizePetite, OPT_SizeSlim, OPT_SizeSmall, OPT_SizeMediocre, OPT_SizeMiddling, + OPT_SizeAverage, OPT_SizeModerate, OPT_SizeMedium, OPT_SizeBulky, OPT_SizeLarge, + OPT_SizeBig, OPT_SizeHuge, OPT_SizeGiant, OPT_SizeColossal, OPT_SizeTitanic, + OPT_ChooseLightSquareColor, OPT_ChooseDarkSquareColor, OPT_ChooseWhitePieceColor, + OPT_ChooseBlackPieceColor, OPT_ChooseHighlightSquareColor, OPT_ChoosePremoveHighlightColor, + OPT_Monochrome, OPT_AllWhite, OPT_UpsideDown, OPT_DefaultBoardColors, GPB_Colors, + IDC_Light, IDC_Dark, IDC_White, IDC_Black, IDC_High, IDC_PreHigh, GPB_Size, OPT_Bitmaps, OPT_PieceFont, OPT_Grid }, +{ DLG_NewVariant, IDOK, IDCANCEL, OPT_VariantNormal, OPT_VariantFRC, OPT_VariantWildcastle, + OPT_VariantNocastle, OPT_VariantLosers, OPT_VariantGiveaway, OPT_VariantSuicide, + OPT_Variant3Check, OPT_VariantTwoKings, OPT_VariantAtomic, OPT_VariantCrazyhouse, + OPT_VariantBughouse, OPT_VariantTwilight, OPT_VariantShogi, OPT_VariantSuper, + OPT_VariantKnightmate, OPT_VariantBerolina, OPT_VariantCylinder, OPT_VariantFairy, + OPT_VariantMakruk, OPT_VariantGothic, OPT_VariantCapablanca, OPT_VariantJanus, + OPT_VariantCRC, OPT_VariantFalcon, OPT_VariantCourier, OPT_VariantGreat, OPT_VariantSChess, + OPT_VariantShatranj, OPT_VariantXiangqi, GPB_Variant, GPB_Board, IDC_Height, + IDC_Width, IDC_Hand, IDC_Pieces, IDC_Def }, +{ DLG_Fonts, IDOK, IDCANCEL, OPT_ChooseClockFont, OPT_ChooseMessageFont, + OPT_ChooseCoordFont, OPT_ChooseTagFont, OPT_ChooseCommentsFont, OPT_ChooseConsoleFont, OPT_ChooseMoveHistoryFont, OPT_DefaultFonts, + OPT_ClockFont, OPT_MessageFont, OPT_CoordFont, OPT_EditTagsFont, OPT_ChoosePieceFont, OPT_MessageFont8, + OPT_SampleGameListFont, OPT_ChooseGameListFont, OPT_MessageFont7, + OPT_CommentsFont, OPT_MessageFont5, GPB_Current, GPB_All, OPT_MessageFont6 }, +{ DLG_NewGameFRC, IDC_NFG_Label, IDC_NFG_Random, IDOK, IDCANCEL }, +{ DLG_GameListOptions, IDC_GLT, IDC_GLT_Up, IDC_GLT_Down, IDC_GLT_Restore, + IDC_GLT_Default, IDOK, IDCANCEL, IDC_GLT_RestoreTo }, +{ DLG_MoveHistory }, +{ DLG_EvalGraph }, +{ DLG_EngineOutput, IDC_EngineLabel1, IDC_Engine1_NPS, IDC_EngineLabel2, IDC_Engine2_NPS }, +{ DLG_Chat, IDC_Partner, IDC_Clear, IDC_Send, }, +{ DLG_EnginePlayOptions, IDC_EpPonder, IDC_EpShowThinking, IDC_EpHideThinkingHuman, + IDC_EpPeriodicUpdates, GPB_Adjudications, IDC_Draw, IDC_Moves, IDC_Threshold, + IDC_Centi, IDC_TestClaims, IDC_DetectMates, IDC_MaterialDraws, IDC_TrivialDraws, + GPB_Apply, IDC_Rule, IDC_Repeats, IDC_ScoreAbs1, IDC_ScoreAbs2, IDOK, IDCANCEL }, +{ DLG_OptionsUCI, IDC_PolyDir, IDC_BrowseForPolyglotDir, IDC_Hash, IDC_Path, + IDC_BrowseForEGTB, IDC_Cache, IDC_UseBook, IDC_BrowseForBook, IDC_CPU, IDC_OwnBook1, + IDC_OwnBook2, IDC_Depth, IDC_Variation, IDC_DefGames, IDOK, IDCANCEL }, +{ 0 } }; +static char languageBuf[70000], *foreign[1000], *english[1000], *languageFile[MSG_SIZ]; +static int lastChecked; +static char oldLanguage[MSG_SIZ], *menuText[10][30]; +extern int tinyLayout; +extern char * menuBarText[][10]; + +void +LoadLanguageFile(char *name) +{ //load the file with translations, and make a list of the strings to be translated, and their translations + FILE *f; + int i=0, j=0, n=0, k; + char buf[MSG_SIZ]; + + if(!name || name[0] == NULLCHAR) return; + snprintf(buf, MSG_SIZ, "%s%s", name, strchr(name, '.') ? "" : ".lng"); // auto-append lng extension + appData.language = oldLanguage; + if(!strcmp(buf, oldLanguage)) { barbaric = 1; return; } // this language already loaded; just switch on + if((f = fopen(buf, "r")) == NULL) return; + while((k = fgetc(f)) != EOF) { + if(i >= sizeof(languageBuf)) { DisplayError("Language file too big", 0); return; } + languageBuf[i] = k; + if(k == '\n') { + if(languageBuf[n] == '"' && languageBuf[i-1] == '"') { + char *p; + if(p = strstr(languageBuf + n + 1, "\" === \"")) { + if(p > languageBuf+n+2 && p+8 < languageBuf+i) { + if(j >= sizeof(english)) { DisplayError("Too many translated strings", 0); return; } + english[j] = languageBuf + n + 1; *p = 0; + foreign[j++] = p + 7; languageBuf[i-1] = 0; +//if(appData.debugMode) fprintf(debugFP, "translation: replace '%s' by '%s'\n", english[j-1], foreign[j-1]); + } + } + } + n = i + 1; + } else if(i > 0 && languageBuf[i-1] == '\\') { + switch(k) { + case 'n': k = '\n'; break; + case 'r': k = '\r'; break; + case 't': k = '\t'; break; + } + languageBuf[--i] = k; + } + i++; + } + fclose(f); + barbaric = (j != 0); + safeStrCpy(oldLanguage, buf, sizeof(oldLanguage)/sizeof(oldLanguage[0]) ); +} + +char * +T_(char *s) +{ // return the translation of the given string + // efficiency can be improved a lot... + int i=0; + static char buf[MSG_SIZ]; +//if(appData.debugMode) fprintf(debugFP, "T_(%s)\n", s); + if(!barbaric) return s; + if(!s) return ""; // sanity + while(english[i]) { + if(!strcmp(s, english[i])) return foreign[i]; + if(english[i][0] == '%' && strstr(s, english[i]+1) == s) { // allow translation of strings with variable ending + snprintf(buf, MSG_SIZ, "%s%s", foreign[i], s + strlen(english[i]+1)); // keep unmatched portion + return buf; + } + i++; + } + return s; +} + +void +Translate(HWND hDlg, int dialogID) +{ // translate all text items in the given dialog + int i=0, j, k; + char buf[MSG_SIZ], *s; + if(!barbaric) return; + while(dialogItems[i][0] && dialogItems[i][0] != dialogID) i++; // find the dialog description + if(dialogItems[i][0] != dialogID) return; // unknown dialog, should not happen + GetWindowText( hDlg, buf, MSG_SIZ ); + s = T_(buf); + if(strcmp(buf, s)) SetWindowText(hDlg, s); // replace by translated string (if different) + for(j=1; k=dialogItems[i][j]; j++) { // translate all listed dialog items + GetDlgItemText(hDlg, k, buf, MSG_SIZ); + if(strlen(buf) == 0) continue; + s = T_(buf); + if(strcmp(buf, s)) SetDlgItemText(hDlg, k, s); // replace by translated string (if different) + } +} + +HMENU +TranslateOneMenu(int i, HMENU subMenu) +{ + int j; + static MENUITEMINFO info; + + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STATE | MIIM_TYPE; + for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ + char buf[MSG_SIZ]; + info.dwTypeData = buf; + info.cch = sizeof(buf); + GetMenuItemInfo(subMenu, j, TRUE, &info); + if(i < 10) { + if(menuText[i][j]) safeStrCpy(buf, menuText[i][j], sizeof(buf)/sizeof(buf[0]) ); + else menuText[i][j] = strdup(buf); // remember original on first change + } + if(buf[0] == NULLCHAR) continue; + info.dwTypeData = T_(buf); + info.cch = strlen(buf)+1; + SetMenuItemInfo(subMenu, j, TRUE, &info); + } + return subMenu; +} + +void +TranslateMenus(int addLanguage) +{ + int i; + WIN32_FIND_DATA fileData; + HANDLE hFind; +#define IDM_English 1970 + if(1) { + HMENU mainMenu = GetMenu(hwndMain); + for (i=GetMenuItemCount(mainMenu)-1; i>=0; i--) { + HMENU subMenu = GetSubMenu(mainMenu, i); + ModifyMenu(mainMenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP|EnableMenuItem(mainMenu, i, MF_BYPOSITION), + (UINT) subMenu, T_(menuBarText[tinyLayout][i])); + TranslateOneMenu(i, subMenu); + } + DrawMenuBar(hwndMain); + } + + if(!addLanguage) return; + if((hFind = FindFirstFile("*.LNG", &fileData)) != INVALID_HANDLE_VALUE) { + HMENU mainMenu = GetMenu(hwndMain); + HMENU subMenu = GetSubMenu(mainMenu, GetMenuItemCount(mainMenu)-1); + AppendMenu(subMenu, MF_SEPARATOR, (UINT_PTR) 0, NULL); + AppendMenu(subMenu, MF_ENABLED|MF_STRING|(barbaric?MF_UNCHECKED:MF_CHECKED), (UINT_PTR) IDM_English, (LPCTSTR) "English"); + i = 0; lastChecked = IDM_English; + do { + char *p, *q = fileData.cFileName; + int checkFlag = MF_UNCHECKED; + languageFile[i] = strdup(q); + if(barbaric && !strcmp(oldLanguage, q)) { + checkFlag = MF_CHECKED; + lastChecked = IDM_English + i + 1; + CheckMenuItem(mainMenu, IDM_English, MF_BYCOMMAND|MF_UNCHECKED); + } + *q = ToUpper(*q); while(*++q) *q = ToLower(*q); + p = strstr(fileData.cFileName, ".lng"); + if(p) *p = 0; + AppendMenu(subMenu, MF_ENABLED|MF_STRING|checkFlag, (UINT_PTR) IDM_English + ++i, (LPCTSTR) fileData.cFileName); + } while(FindNextFile(hFind, &fileData)); + FindClose(hFind); + } +} + +#endif + +#define IDM_RecentEngines 3000 + +void +RecentEngineMenu (char *s) +{ + if(appData.icsActive) return; + if(appData.recentEngines > 0 && *s) { // feature is on, and list non-empty + HMENU mainMenu = GetMenu(hwndMain); + HMENU subMenu = GetSubMenu(mainMenu, 5); // Engine menu + int i=IDM_RecentEngines; + recentEngines = strdup(appData.recentEngineList); // remember them as they are in menu + AppendMenu(subMenu, MF_SEPARATOR, (UINT_PTR) 0, NULL); + while(*s) { + char *p = strchr(s, '\n'); + if(p == NULL) return; // malformed! + *p = NULLCHAR; + AppendMenu(subMenu, MF_ENABLED|MF_STRING|MF_UNCHECKED, (UINT_PTR) i++, (LPCTSTR) s); + *p = '\n'; + s = p+1; + } + } +} + + typedef struct { char *name; int squareSize; @@ -274,24 +553,24 @@ SizeInfo sizeInfo[] = #define MF(x) {x, {{0,}, 0. }, {0, }, 0} MyFont fontRec[NUM_SIZES][NUM_FONTS] = { - { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL) }, - { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL) }, + { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL), MF (GAMELIST_FONT_ALL) }, + { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL), MF(GAMELIST_FONT_ALL) }, }; MyFont *font[NUM_SIZES][NUM_FONTS]; @@ -316,10 +595,10 @@ MyButtonDesc buttonDesc[N_BUTTONS] = }; int tinyLayout = 0, smallLayout = 0; -#define MENU_BAR_ITEMS 7 +#define MENU_BAR_ITEMS 9 char *menuBarText[2][MENU_BAR_ITEMS+1] = { - { "&File", "&Mode", "&Action", "&Step", "&Options", "&Help", NULL }, - { "&F", "&M", "&A", "&S", "&O", "&H", NULL }, + { N_("&File"), N_("&Edit"), N_("&View"), N_("&Mode"), N_("&Action"), N_("E&ngine"), N_("&Options"), N_("&Help"), NULL }, + { N_("&F"), N_("&E"), N_("&V"), N_("&M"), N_("&A"), N_("&N"), N_("&O"), N_("&H"), NULL }, }; @@ -327,17 +606,17 @@ MySound sounds[(int)NSoundClasses]; MyTextAttribs textAttribs[(int)NColorClasses]; MyColorizeAttribs colorizeAttribs[] = { - { (COLORREF)0, 0, "Shout Text" }, - { (COLORREF)0, 0, "SShout/CShout" }, - { (COLORREF)0, 0, "Channel 1 Text" }, - { (COLORREF)0, 0, "Channel Text" }, - { (COLORREF)0, 0, "Kibitz Text" }, - { (COLORREF)0, 0, "Tell Text" }, - { (COLORREF)0, 0, "Challenge Text" }, - { (COLORREF)0, 0, "Request Text" }, - { (COLORREF)0, 0, "Seek Text" }, - { (COLORREF)0, 0, "Normal Text" }, - { (COLORREF)0, 0, "None" } + { (COLORREF)0, 0, N_("Shout Text") }, + { (COLORREF)0, 0, N_("SShout/CShout") }, + { (COLORREF)0, 0, N_("Channel 1 Text") }, + { (COLORREF)0, 0, N_("Channel Text") }, + { (COLORREF)0, 0, N_("Kibitz Text") }, + { (COLORREF)0, 0, N_("Tell Text") }, + { (COLORREF)0, 0, N_("Challenge Text") }, + { (COLORREF)0, 0, N_("Request Text") }, + { (COLORREF)0, 0, N_("Seek Text") }, + { (COLORREF)0, 0, N_("Normal Text") }, + { (COLORREF)0, 0, N_("None") } }; @@ -346,15 +625,7 @@ static char *commentTitle; static char *commentText; static int commentIndex; static Boolean editComment = FALSE; -HWND commentDialog = NULL; -BOOLEAN commentDialogUp = FALSE; -static int commentX, commentY, commentH, commentW; -static char *analysisTitle; -static char *analysisText; -HWND analysisDialog = NULL; -BOOLEAN analysisDialogUp = FALSE; -static int analysisX, analysisY, analysisH, analysisW; char errorTitle[MSG_SIZ]; char errorMessage[2*MSG_SIZ]; @@ -416,7 +687,6 @@ LRESULT CALLBACK StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); VOID APIENTRY MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def); void ParseIcsTextMenu(char *icsTextMenuString); -VOID PopUpMoveDialog(char firstchar); VOID PopUpNameDialog(char firstchar); VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca); @@ -424,37 +694,27 @@ VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca); int NewGameFRC(); int GameListOptions(); -HWND moveHistoryDialog = NULL; -BOOLEAN moveHistoryDialogUp = FALSE; - -WindowPlacement wpMoveHistory; +int dummy; // [HGM] for obsolete args +HWND hwndMain = NULL; /* root window*/ +HWND hwndConsole = NULL; +HWND commentDialog = NULL; +HWND moveHistoryDialog = NULL; HWND evalGraphDialog = NULL; -BOOLEAN evalGraphDialogUp = FALSE; - -WindowPlacement wpEvalGraph; - HWND engineOutputDialog = NULL; -BOOLEAN engineOutputDialogUp = FALSE; +HWND gameListDialog = NULL; +HWND editTagsDialog = NULL; +int commentUp = FALSE; + +WindowPlacement wpMain; +WindowPlacement wpConsole; +WindowPlacement wpComment; +WindowPlacement wpMoveHistory; +WindowPlacement wpEvalGraph; WindowPlacement wpEngineOutput; WindowPlacement wpGameList; -WindowPlacement wpConsole; - -VOID MoveHistoryPopUp(); -VOID MoveHistoryPopDown(); -VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo ); -BOOL MoveHistoryIsUp(); - -VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo ); -VOID EvalGraphPopUp(); -VOID EvalGraphPopDown(); -BOOL EvalGraphIsUp(); - -VOID EngineOutputPopUp(); -VOID EngineOutputPopDown(); -BOOL EngineOutputIsUp(); -VOID EngineOutputUpdate( FrontEndProgramStats * stats ); +WindowPlacement wpTags; VOID EngineOptionsPopup(); // [HGM] settings @@ -503,7 +763,8 @@ void ThawUI() #define JAWS_INIT #define JAWS_ARGS #define JAWS_ALT_INTERCEPT -#define JAWS_KB_NAVIGATION +#define JAWS_KBUP_NAVIGATION +#define JAWS_KBDOWN_NAVIGATION #define JAWS_MENU_ITEMS #define JAWS_SILENCE #define JAWS_REPLAY @@ -541,6 +802,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, } JAWS_INIT + TranslateMenus(1); // InitCommonControlsEx(&ex); InitCommonControls(); @@ -661,14 +923,19 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, void SetUserLogo() { // update user logo if necessary - static char oldUserName[MSG_SIZ], *curName; + static char oldUserName[MSG_SIZ], dir[MSG_SIZ], *curName; if(appData.autoLogo) { curName = UserName(); if(strcmp(curName, oldUserName)) { - sprintf(oldUserName, "logos\\%s.bmp", curName); + GetCurrentDirectory(MSG_SIZ, dir); + SetCurrentDirectory(installDir); + snprintf(oldUserName, MSG_SIZ, "logos\\%s.bmp", curName); userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - strcpy(oldUserName, curName); + safeStrCpy(oldUserName, curName, sizeof(oldUserName)/sizeof(oldUserName[0]) ); + if(userLogo == NULL) + userLogo = LoadImage( 0, "logos\\dummy.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + SetCurrentDirectory(dir); /* return to prev directory */ } } } @@ -725,6 +992,56 @@ EnsureOnScreen(int *x, int *y, int minX, int minY) if (*y < minY) *y = minY; } +VOID +LoadLogo(ChessProgramState *cps, int n, Boolean ics) +{ + char buf[MSG_SIZ], dir[MSG_SIZ]; + GetCurrentDirectory(MSG_SIZ, dir); + SetCurrentDirectory(installDir); + if( appData.logo[n] && appData.logo[n][0] != NULLCHAR) { + cps->programLogo = LoadImage( 0, appData.logo[n], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + + if (cps->programLogo == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.logo[n] ); + } + } else if(appData.autoLogo) { + if(ics) { // [HGM] logo: in ICS mode second can be used for ICS + sprintf(buf, "logos\\%s.bmp", appData.icsHost); + cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } else + if(appData.directory[n] && appData.directory[n][0]) { + SetCurrentDirectory(appData.directory[n]); + cps->programLogo = LoadImage( 0, "logo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } + } + SetCurrentDirectory(dir); /* return to prev directory */ +} + +VOID +InitTextures() +{ + ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) ); + backTextureSquareSize = 0; // kludge to force recalculation of texturemode + + if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) { + liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + liteBackTextureMode = appData.liteBackTextureMode; + + if (liteBackTexture == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile ); + } + } + + if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) { + darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + darkBackTextureMode = appData.darkBackTextureMode; + + if (darkBackTexture == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile ); + } + } +} + BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) { @@ -734,6 +1051,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) char *filepart; hInst = hInstance; /* Store instance handle in our global variable */ + programName = szAppName; if (SearchPath(NULL, "WinBoard.exe", NULL, MSG_SIZ, installDir, &filepart)) { *filepart = NULLCHAR; @@ -743,11 +1061,24 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] won't have open window otherwise screenWidth = screenHeight = 1000; // [HGM] placement: kludge to allow calling EnsureOnScreen from InitAppData InitAppData(lpCmdLine); /* Get run-time parameters */ + /* xboard, and older WinBoards, controlled the move sound with the + appData.ringBellAfterMoves option. In the current WinBoard, we + always turn the option on (so that the backend will call us), + then let the user turn the sound off by setting it to silence if + desired. To accommodate old winboard.ini files saved by old + versions of WinBoard, we also turn off the sound if the option + was initially set to false. [HGM] taken out of InitAppData */ + if (!appData.ringBellAfterMoves) { + sounds[(int)SoundMove].name = strdup(""); + appData.ringBellAfterMoves = TRUE; + } if (appData.debugMode) { debugFP = fopen(appData.nameOfDebugFile, "w"); setbuf(debugFP, NULL); } + LoadLanguageFile(appData.language); + InitBackEnd1(); // InitEngineUCI( installDir, &first ); // [HGM] incorporated in InitBackEnd1() @@ -766,37 +1097,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } /* [HGM] logo: Load logos if specified (must be done before InitDrawingSizes) */ - if( appData.firstLogo && appData.firstLogo[0] != NULLCHAR) { - first.programLogo = LoadImage( 0, appData.firstLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - - if (first.programLogo == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.firstLogo ); - } - } else if(appData.autoLogo) { - if(appData.firstDirectory && appData.firstDirectory[0]) { - char buf[MSG_SIZ]; - sprintf(buf, "%s/logo.bmp", appData.firstDirectory); - first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } - } - - if( appData.secondLogo && appData.secondLogo[0] != NULLCHAR) { - second.programLogo = LoadImage( 0, appData.secondLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - - if (second.programLogo == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo ); - } - } else if(appData.autoLogo) { - char buf[MSG_SIZ]; - if(appData.icsActive) { // [HGM] logo: in ICS mode second can be used for ICS - sprintf(buf, "logos\\%s.bmp", appData.icsHost); - second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } else - if(appData.secondDirectory && appData.secondDirectory[0]) { - sprintf(buf, "%s\\logo.bmp", appData.secondDirectory); - second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } - } + LoadLogo(&first, 0, FALSE); + LoadLogo(&second, 1, appData.icsActive); SetUserLogo(); @@ -819,29 +1121,12 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } InitDrawingSizes(boardSize, 0); + RecentEngineMenu(appData.recentEngineList); InitMenuChecks(); buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS); /* [AS] Load textures if specified */ - ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) ); - - if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) { - liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - liteBackTextureMode = appData.liteBackTextureMode; - - if (liteBackTexture == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile ); - } - } - - if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) { - darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - darkBackTextureMode = appData.darkBackTextureMode; - - if (darkBackTexture == NULL && appData.debugMode) { - fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile ); - } - } + InitTextures(); mysrandom( (unsigned) time(NULL) ); @@ -858,20 +1143,20 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) EngineOutputPopUp(); } - InitBackEnd2(); - /* Make the window visible; update its client area; and return "success" */ - EnsureOnScreen(&boardX, &boardY, minX, minY); + EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = nCmdShow; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = boardX; - wp.rcNormalPosition.right = boardX + winWidth; - wp.rcNormalPosition.top = boardY; - wp.rcNormalPosition.bottom = boardY + winHeight; + wp.rcNormalPosition.left = wpMain.x; + wp.rcNormalPosition.right = wpMain.x + wpMain.width; + wp.rcNormalPosition.top = wpMain.y; + wp.rcNormalPosition.bottom = wpMain.y + wpMain.height; SetWindowPlacement(hwndMain, &wp); + InitBackEnd2(); // [HGM] moved until after all windows placed, to save correct position if fatal error on engine start + if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); @@ -881,6 +1166,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); #endif ShowWindow(hwndConsole, nCmdShow); + SetActiveWindow(hwndConsole); } if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE); if(gameListDialog) SetFocus(gameListDialog); // [HGM] jaws: for if we clicked multi-game game file @@ -889,577 +1175,82 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } +VOID +InitMenuChecks() +{ + HMENU hmenu = GetMenu(hwndMain); -typedef enum { - ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone, - ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings, - ArgSettingsFilename, - ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window -} ArgType; + (void) EnableMenuItem(hmenu, IDM_CommPort, + MF_BYCOMMAND|((appData.icsActive && + *appData.icsCommPort != NULLCHAR) ? + MF_ENABLED : MF_GRAYED)); + (void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit, + MF_BYCOMMAND|(saveSettingsOnExit ? + MF_CHECKED : MF_UNCHECKED)); +} -typedef struct { - char *argName; - ArgType argType; - /*** - union { - String *pString; // ArgString - int *pInt; // ArgInt - float *pFloat; // ArgFloat - Boolean *pBoolean; // ArgBoolean - COLORREF *pColor; // ArgColor - ColorClass cc; // ArgAttribs - String *pFilename; // ArgFilename - BoardSize *pBoardSize; // ArgBoardSize - int whichFont; // ArgFont - DCB *pDCB; // ArgCommSettings - String *pFilename; // ArgSettingsFilename - } argLoc; - ***/ - LPVOID argLoc; - BOOL save; -} ArgDescriptor; - -int junk; -ArgDescriptor argDescriptors[] = { - /* positional arguments */ - { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "", ArgNone, NULL }, - /* keyword arguments */ - JAWS_ARGS - { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE }, - { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE }, - { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE }, - { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE }, - { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE }, - { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE }, - { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE }, - { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE }, - { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE }, - { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE }, - { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE }, - { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE }, - { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE }, - { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE }, - { "initString", ArgString, (LPVOID) &appData.initString, FALSE }, - { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE }, - { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE }, - { "firstComputerString", ArgString, (LPVOID) &appData.firstComputerString, - FALSE }, - { "secondComputerString", ArgString, (LPVOID) &appData.secondComputerString, - FALSE }, - { "firstChessProgram", ArgFilename, (LPVOID) &appData.firstChessProgram, - FALSE }, - { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE }, - { "secondChessProgram", ArgFilename, (LPVOID) &appData.secondChessProgram, - FALSE }, - { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE }, - { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE }, - { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE }, - { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE }, - { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE }, - { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE }, - { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE }, - { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE }, - { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE }, - { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE }, - { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE }, - { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE }, - { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE }, - /*!!bitmapDirectory?*/ - { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE }, - { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE }, - { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE }, - { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE }, - { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE }, - { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE }, - { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE }, - { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE }, - { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE }, - { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE }, - { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE }, - { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE }, - { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE }, - { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE }, - { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE }, - { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE }, - { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE }, - { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE }, - { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE }, - { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE }, - { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE }, - { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE }, - { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE }, - { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE }, - { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE }, - { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE }, - { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE }, - { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE }, - { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE }, - { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE }, - { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE }, - { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE }, - { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE }, - { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE }, - { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE }, - { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE }, - { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE }, - { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE }, - { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE }, - { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE }, - { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE }, - { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE }, - { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE }, - { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE }, - { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE }, - { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE }, - { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE }, - { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE }, - { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE }, - { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE }, - { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE }, - { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE }, - { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE }, - { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE }, - { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE }, - { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE }, - { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE }, - { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE }, - { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE }, - { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE }, - { "st", ArgString, (LPVOID) &appData.searchTime, FALSE }, - { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE }, - { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE }, - { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE }, - { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE }, - { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE }, - { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE }, - { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE }, - { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE }, - { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE }, - { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE }, - { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE }, - { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE }, - { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE }, - { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE }, - { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE }, - { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE }, - { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE }, - { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE }, - { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE }, - { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE }, - { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE }, - { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE }, - { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE }, - { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE }, - { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE }, - { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE }, - { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, - FALSE }, /* only so that old WinBoard.ini files from betas can be read */ - { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE }, - { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE }, - { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE }, - { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE }, - { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE }, - { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE }, - { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */ - { "boardSize", ArgBoardSize, (LPVOID) &boardSize, - TRUE }, /* must come after all fonts */ - { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE }, - { "ringBellAfterMoves", ArgBoolean, (LPVOID) &appData.ringBellAfterMoves, - FALSE }, /* historical; kept only so old winboard.ini files will parse */ - { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE }, - { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE }, - { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE }, - { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE }, - { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE }, - { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE }, - { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE }, - { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE }, - { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE }, - { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE }, - { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE }, - { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE }, - { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE }, - { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE }, - { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE }, - { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE }, - { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE }, - { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE }, - { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE }, - { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE }, - { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE }, - { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE }, - { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE }, - { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE }, - { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE }, - { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE }, - { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE }, - { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE }, - { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE }, - { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE }, - { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE }, - { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE }, - { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE }, - { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE }, - { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE }, - { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE }, - { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE }, - { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE }, - { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE }, - { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE }, - { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE }, - { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE }, - { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE }, - { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE }, - { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE }, - { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE }, - { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE }, - { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE }, - { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE }, - { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE }, - { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE }, - { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE }, - { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE }, - { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE}, - { "alarm", ArgTrue, (LPVOID) &appData.icsAlarm, FALSE}, - { "xalarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE}, - { "-alarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE}, - { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE}, - { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE}, - { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE}, - { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE }, - { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE }, - { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE }, - { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE }, - { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE }, - { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE }, - { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE }, - { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE }, - { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE }, - { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE }, - { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE }, - { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE }, - { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE }, - { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE }, - { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE }, - { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE }, - { "highlightLastMove", ArgBoolean, - (LPVOID) &appData.highlightLastMove, TRUE }, - { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE }, - { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE }, - { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE }, - { "highlightDragging", ArgBoolean, - (LPVOID) &appData.highlightDragging, TRUE }, - { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE }, - { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE }, - { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE }, - { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE }, - { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE }, - { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE }, - { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE }, - { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE }, - { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE }, - { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE }, - { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE }, - { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE }, - { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE }, - { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE }, - { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE }, - { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE }, - { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE }, - { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE }, - { "soundShout", ArgFilename, - (LPVOID) &textAttribs[ColorShout].sound.name, TRUE }, - { "soundSShout", ArgFilename, - (LPVOID) &textAttribs[ColorSShout].sound.name, TRUE }, - { "soundChannel1", ArgFilename, - (LPVOID) &textAttribs[ColorChannel1].sound.name, TRUE }, - { "soundChannel", ArgFilename, - (LPVOID) &textAttribs[ColorChannel].sound.name, TRUE }, - { "soundKibitz", ArgFilename, - (LPVOID) &textAttribs[ColorKibitz].sound.name, TRUE }, - { "soundTell", ArgFilename, - (LPVOID) &textAttribs[ColorTell].sound.name, TRUE }, - { "soundChallenge", ArgFilename, - (LPVOID) &textAttribs[ColorChallenge].sound.name, TRUE }, - { "soundRequest", ArgFilename, - (LPVOID) &textAttribs[ColorRequest].sound.name, TRUE }, - { "soundSeek", ArgFilename, - (LPVOID) &textAttribs[ColorSeek].sound.name, TRUE }, - { "soundMove", ArgFilename, (LPVOID) &sounds[(int)SoundMove].name, TRUE }, - { "soundBell", ArgFilename, (LPVOID) &sounds[(int)SoundBell].name, TRUE }, - { "soundIcsWin", ArgFilename, (LPVOID) &sounds[(int)SoundIcsWin].name,TRUE }, - { "soundIcsLoss", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsLoss].name, TRUE }, - { "soundIcsDraw", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsDraw].name, TRUE }, - { "soundIcsUnfinished", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsUnfinished].name, TRUE}, - { "soundIcsAlarm", ArgFilename, - (LPVOID) &sounds[(int)SoundAlarm].name, TRUE }, - { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE }, - { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE }, - { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE }, - { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE }, - { "reuseChessPrograms", ArgBoolean, - (LPVOID) &appData.reuseFirst, FALSE }, /* backward compat only */ - { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE }, - { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE }, - { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, - { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, - { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE }, - { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, - { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, - { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE }, - { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE }, - { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE }, - { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE }, - { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE }, - { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE }, - { "icsNames", ArgString, (LPVOID) &icsNames, TRUE }, - { "firstChessProgramNames", ArgString, (LPVOID) &firstChessProgramNames, - TRUE }, - { "secondChessProgramNames", ArgString, (LPVOID) &secondChessProgramNames, - TRUE }, - { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE }, - { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE }, - { "variant", ArgString, (LPVOID) &appData.variant, FALSE }, - { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE }, - { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE }, - { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE }, - { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE }, - { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE }, - { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE }, - /* [AS] New features */ - { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE }, - { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE }, - { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE }, - { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE }, - { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE }, - { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE }, - { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE }, - { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE }, - { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE }, - { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE }, - { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE }, - { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE }, - { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE }, - { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE }, - { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE }, - { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE }, - { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE }, - { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE }, - { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE }, - { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE }, - { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE }, - { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE }, - { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE }, - { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE }, - { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE }, - { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE }, - { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE }, - { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE }, - { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE }, - { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE }, - { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE }, - { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE }, - { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE }, - { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE }, - { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE }, - { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE }, - { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE }, - { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE }, - { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE }, - { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE }, - { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE }, - { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE }, - { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE }, - { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE }, - - /* [HGM] board-size, adjudication and misc. options */ - { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE }, - { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE }, - { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE }, - { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE }, - { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE }, - { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE }, - { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE }, - { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE }, - { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE }, - { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE }, - { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE }, - { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE }, - { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE }, - { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE }, - { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE }, - { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE }, - { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE }, - { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE }, - { "userName", ArgString, (LPVOID) &appData.userName, FALSE }, - { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE }, - { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE }, - { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE }, - { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE }, - { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE }, - { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE }, - { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE }, - { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE }, - { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE }, - { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE }, - { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE }, - { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE }, - { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE }, - { "icstype", ArgInt, (LPVOID) &ics_type, FALSE }, - { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE }, - -#ifdef ZIPPY - { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE }, - { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE }, - { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE }, - { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE }, - { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE }, - { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE }, - { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE }, - { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE }, - { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE }, - { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE }, - { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE }, - { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE }, - { "zippyWrongPassword", ArgString, (LPVOID) &appData.zippyWrongPassword, - FALSE }, - { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE }, - { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE }, - { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE }, - { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE }, - { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE }, - { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE }, - { "zippyNoplayCrafty", ArgBoolean, (LPVOID) &appData.zippyNoplayCrafty, - FALSE }, - { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE }, - { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE }, - { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE }, - { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE }, - { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE }, - { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE }, - { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE }, - { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE }, - { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE }, - { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE }, - /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */ - { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE }, -#endif - /* [HGM] options for broadcasting and time odds */ - { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE }, - { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE }, - { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE }, - { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE }, - { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE }, - { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE }, - { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE }, - { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE }, - { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE }, - { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE }, - { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE }, - { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE }, - - // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others - { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed - { "minY", ArgZ, (LPVOID) &minY, FALSE }, - { "winWidth", ArgInt, (LPVOID) &winWidth, TRUE }, // [HGM] placement: dummies to remember right & bottom - { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, // for attaching auxiliary windows to them - { "x", ArgInt, (LPVOID) &boardX, TRUE }, - { "y", ArgInt, (LPVOID) &boardY, TRUE }, - { "icsX", ArgX, (LPVOID) &wpConsole.x, TRUE }, - { "icsY", ArgY, (LPVOID) &wpConsole.y, TRUE }, - { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE }, - { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE }, - { "analysisX", ArgX, (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists - { "analysisY", ArgY, (LPVOID) &analysisY, FALSE }, // provided for compatibility with old ini files - { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE }, - { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE }, - { "commentX", ArgX, (LPVOID) &commentX, TRUE }, - { "commentY", ArgY, (LPVOID) &commentY, TRUE }, - { "commentW", ArgInt, (LPVOID) &commentW, TRUE }, - { "commentH", ArgInt, (LPVOID) &commentH, TRUE }, - { "tagsX", ArgX, (LPVOID) &editTagsX, TRUE }, - { "tagsY", ArgY, (LPVOID) &editTagsY, TRUE }, - { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE }, - { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE }, - { "gameListX", ArgX, (LPVOID) &wpGameList.x, TRUE }, - { "gameListY", ArgY, (LPVOID) &wpGameList.y, TRUE }, - { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE }, - { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE }, - /* [AS] Layout stuff */ - { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE }, - { "moveHistoryX", ArgX, (LPVOID) &wpMoveHistory.x, TRUE }, - { "moveHistoryY", ArgY, (LPVOID) &wpMoveHistory.y, TRUE }, - { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE }, - { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE }, - - { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE }, - { "evalGraphX", ArgX, (LPVOID) &wpEvalGraph.x, TRUE }, - { "evalGraphY", ArgY, (LPVOID) &wpEvalGraph.y, TRUE }, - { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE }, - { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE }, - - { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE }, - { "engineOutputX", ArgX, (LPVOID) &wpEngineOutput.x, TRUE }, - { "engineOutputY", ArgY, (LPVOID) &wpEngineOutput.y, TRUE }, - { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE }, - { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE }, - - { NULL, ArgNone, NULL, FALSE } -}; +//--------------------------------------------------------------------------------------------------------- + +#define ICS_TEXT_MENU_SIZE (IDM_CommandXLast - IDM_CommandX + 1) +#define XBOARD FALSE +#define OPTCHAR "/" +#define SEPCHAR "=" +#define TOPLEVEL 0 -/* Kludge for indirection files on command line */ -char* lastIndirectionFilename; -ArgDescriptor argDescriptorIndirection = -{ "", ArgSettingsFilename, (LPVOID) NULL, FALSE }; +#include "args.h" +// front-end part of option handling VOID -ExitArgError(char *msg, char *badArg) +LFfromMFP(LOGFONT* lf, MyFontParams *mfp) { - char buf[MSG_SIZ]; + HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); + lf->lfHeight = -(int)(mfp->pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72.0 + 0.5); + DeleteDC(hdc); + lf->lfWidth = 0; + lf->lfEscapement = 0; + lf->lfOrientation = 0; + lf->lfWeight = mfp->bold ? FW_BOLD : FW_NORMAL; + lf->lfItalic = mfp->italic; + lf->lfUnderline = mfp->underline; + lf->lfStrikeOut = mfp->strikeout; + lf->lfCharSet = mfp->charset; + lf->lfOutPrecision = OUT_DEFAULT_PRECIS; + lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf->lfQuality = DEFAULT_QUALITY; + lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; + safeStrCpy(lf->lfFaceName, mfp->faceName, sizeof(lf->lfFaceName)/sizeof(lf->lfFaceName[0]) ); +} - sprintf(buf, "%s %s", msg, badArg); - DisplayFatalError(buf, 0, 2); - exit(2); +void +CreateFontInMF(MyFont *mf) +{ + LFfromMFP(&mf->lf, &mf->mfp); + if (mf->hf) DeleteObject(mf->hf); + mf->hf = CreateFontIndirect(&mf->lf); } +// [HGM] This platform-dependent table provides the location for storing the color info +void * +colorVariable[] = { + &whitePieceColor, + &blackPieceColor, + &lightSquareColor, + &darkSquareColor, + &highlightSquareColor, + &premoveHighlightColor, + NULL, + &consoleBackgroundColor, + &appData.fontForeColorWhite, + &appData.fontBackColorWhite, + &appData.fontForeColorBlack, + &appData.fontBackColorBlack, + &appData.evalHistColorWhite, + &appData.evalHistColorBlack, + &appData.highlightArrowColor, +}; + /* Command line font name parser. NULL name means do nothing. Syntax like "Courier New:10.0 bi" or "Arial:10" or "Arial:10b" For backward compatibility, syntax without the colon is also @@ -1474,7 +1265,7 @@ ParseFontName(char *name, MyFontParams *mfp) q = strchr(p, ':'); if (q) { if (q - p >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name, TRUE); memcpy(mfp->faceName, p, q - p); mfp->faceName[q - p] = NULLCHAR; p = q + 1; @@ -1483,19 +1274,53 @@ ParseFontName(char *name, MyFontParams *mfp) while (*p && !isdigit(*p)) { *q++ = *p++; if (q - mfp->faceName >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name, TRUE); } while (q > mfp->faceName && q[-1] == ' ') q--; *q = NULLCHAR; } - if (!*p) ExitArgError("Font point size missing:", name); + if (!*p) ExitArgError(_("Font point size missing:"), name, TRUE); mfp->pointSize = (float) atof(p); mfp->bold = (strchr(p, 'b') != NULL); mfp->italic = (strchr(p, 'i') != NULL); mfp->underline = (strchr(p, 'u') != NULL); mfp->strikeout = (strchr(p, 's') != NULL); + mfp->charset = DEFAULT_CHARSET; + q = strchr(p, 'c'); + if (q) + mfp->charset = (BYTE) atoi(q+1); +} + +void +ParseFont(char *name, int number) +{ // wrapper to shield back-end from 'font' + ParseFontName(name, &font[boardSize][number]->mfp); } +void +SetFontDefaults() +{ // in WB we have a 2D array of fonts; this initializes their description + int i, j; + /* Point font array elements to structures and + parse default font names */ + for (i=0; idef, &font[j][i]->mfp); + } + } +} + +void +CreateFonts() +{ // here we create the actual fonts from the selected descriptions + int i, j; + for (i=0; iargName != NULL; ad++) - if (strcmp(ad->argName, argName + 1) == 0) break; - - if (ad->argName == NULL) - ExitArgError("Unrecognized argument", argName); - - } else if (ch == '@') { - /* Indirection file */ - ad = &argDescriptorIndirection; - ch = get(cl); - } else { - /* Positional argument */ - ad = &argDescriptors[posarg++]; - strcpy(argName, ad->argName); - } - - if (ad->argType == ArgTrue) { - *(Boolean *) ad->argLoc = TRUE; - continue; - } - if (ad->argType == ArgFalse) { - *(Boolean *) ad->argLoc = FALSE; - continue; - } - - while (ch == ' ' || ch == '=' || ch == ':' || ch == '\t') ch = get(cl); - if (ch == NULLCHAR || ch == '\n') { - ExitArgError("No value provided for argument", argName); - } - q = argValue; - if (ch == '{') { - // Quoting with { }. No characters have to (or can) be escaped. - // Thus the string cannot contain a '}' character. - start = ch; - ch = get(cl); - while (start) { - switch (ch) { - case NULLCHAR: - start = NULLCHAR; - break; - - case '}': - ch = get(cl); - start = NULLCHAR; - break; - - default: - *q++ = ch; - ch = get(cl); - break; - } - } - } else if (ch == '\'' || ch == '"') { - // Quoting with ' ' or " ", with \ as escape character. - // Inconvenient for long strings that may contain Windows filenames. - start = ch; - ch = get(cl); - while (start) { - switch (ch) { - case NULLCHAR: - start = NULLCHAR; - break; - - default: - not_special: - *q++ = ch; - ch = get(cl); - break; - - case '\'': - case '\"': - if (ch == start) { - ch = get(cl); - start = NULLCHAR; - break; - } else { - goto not_special; - } - - case '\\': - if (ad->argType == ArgFilename - || ad->argType == ArgSettingsFilename) { - goto not_special; - } - ch = get(cl); - switch (ch) { - case NULLCHAR: - ExitArgError("Incomplete \\ escape in value for", argName); - break; - case 'n': - *q++ = '\n'; - ch = get(cl); - break; - case 'r': - *q++ = '\r'; - ch = get(cl); - break; - case 't': - *q++ = '\t'; - ch = get(cl); - break; - case 'b': - *q++ = '\b'; - ch = get(cl); - break; - case 'f': - *q++ = '\f'; - ch = get(cl); - break; - default: - octval = 0; - for (i = 0; i < 3; i++) { - if (ch >= '0' && ch <= '7') { - octval = octval*8 + (ch - '0'); - ch = get(cl); - } else { - break; - } - } - if (i > 0) { - *q++ = (char) octval; - } else { - *q++ = ch; - ch = get(cl); - } - break; - } - break; - } - } - } else { - while (ch != ' ' && ch != NULLCHAR && ch != '\t' && ch != '\n') { - *q++ = ch; - ch = get(cl); - } - } - *q = NULLCHAR; - - switch (ad->argType) { - case ArgInt: - *(int *) ad->argLoc = atoi(argValue); - break; - - case ArgX: - *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute - break; - - case ArgY: - *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...) - break; - - case ArgZ: - *(int *) ad->argLoc = atoi(argValue); - EnsureOnScreen(&boardX, &boardY, minX, minY); - break; - - case ArgFloat: - *(float *) ad->argLoc = (float) atof(argValue); - break; - - case ArgString: - case ArgFilename: - *(char **) ad->argLoc = strdup(argValue); - break; - - case ArgSettingsFilename: - { - char fullname[MSG_SIZ]; - if (ParseSettingsFile(argValue, fullname)) { - if (ad->argLoc != NULL) { - *(char **) ad->argLoc = strdup(fullname); - } - } else { - if (ad->argLoc != NULL) { - } else { - ExitArgError("Failed to open indirection file", argValue); - } - } - } - break; - - case ArgBoolean: - switch (argValue[0]) { - case 't': - case 'T': - *(Boolean *) ad->argLoc = TRUE; - break; - case 'f': - case 'F': - *(Boolean *) ad->argLoc = FALSE; - break; - default: - ExitArgError("Unrecognized boolean argument value", argValue); - break; - } - break; - - case ArgColor: - *(COLORREF *)ad->argLoc = ParseColorName(argValue); - break; - - case ArgAttribs: { - ColorClass cc = (ColorClass)ad->argLoc; - ParseAttribs(&textAttribs[cc].color, &textAttribs[cc].effects, argValue); - } - break; - - case ArgBoardSize: - *(BoardSize *)ad->argLoc = ParseBoardSize(argValue); - break; - - case ArgFont: - ParseFontName(argValue, &font[boardSize][(int)ad->argLoc]->mfp); - break; - - case ArgCommSettings: - ParseCommSettings(argValue, &dcb); - break; - - case ArgNone: - ExitArgError("Unrecognized argument", argValue); - break; - case ArgTrue: - case ArgFalse: ; + if (StrCaseCmp(name, sizeInfo[bs].name) == 0) { + *(BoardSize *)addr = bs; + return; } + bs++; } + ExitArgError(_("Unrecognized board size value"), name, TRUE); } -VOID -LFfromMFP(LOGFONT* lf, MyFontParams *mfp) -{ - HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); - lf->lfHeight = -(int)(mfp->pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72.0 + 0.5); - DeleteDC(hdc); - lf->lfWidth = 0; - lf->lfEscapement = 0; - lf->lfOrientation = 0; - lf->lfWeight = mfp->bold ? FW_BOLD : FW_NORMAL; - lf->lfItalic = mfp->italic; - lf->lfUnderline = mfp->underline; - lf->lfStrikeOut = mfp->strikeout; - lf->lfCharSet = DEFAULT_CHARSET; - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; - strcpy(lf->lfFaceName, mfp->faceName); -} - -VOID -CreateFontInMF(MyFont *mf) -{ - LFfromMFP(&mf->lf, &mf->mfp); - if (mf->hf) DeleteObject(mf->hf); - mf->hf = CreateFontIndirect(&mf->lf); -} - -VOID -SetDefaultTextAttribs() -{ - ColorClass cc; - for (cc = (ColorClass)0; cc < NColorClasses; cc++) { - ParseAttribs(&textAttribs[cc].color, - &textAttribs[cc].effects, - defaultTextAttribs[cc]); - } -} - -VOID -SetDefaultSounds() -{ +void +LoadAllSounds() +{ // [HGM] import name from appData first ColorClass cc; SoundClass sc; - for (cc = (ColorClass)0; cc < NColorClasses; cc++) { + for (cc = (ColorClass)0; cc < ColorNormal; cc++) { + textAttribs[cc].sound.name = strdup((&appData.soundShout)[cc]); + textAttribs[cc].sound.data = NULL; + MyLoadSound(&textAttribs[cc].sound); + } + for (cc = ColorNormal; cc < NColorClasses; cc++) { textAttribs[cc].sound.name = strdup(""); textAttribs[cc].sound.data = NULL; } for (sc = (SoundClass)0; sc < NSoundClasses; sc++) { - sounds[sc].name = strdup(""); + sounds[sc].name = strdup((&appData.soundMove)[sc]); sounds[sc].data = NULL; - } - sounds[(int)SoundBell].name = strdup(SOUND_BELL); -} - -VOID -LoadAllSounds() -{ - ColorClass cc; - SoundClass sc; - for (cc = (ColorClass)0; cc < NColorClasses; cc++) { - MyLoadSound(&textAttribs[cc].sound); - } - for (sc = (SoundClass)0; sc < NSoundClasses; sc++) { MyLoadSound(&sounds[sc]); } } -VOID -InitAppData(LPSTR lpCmdLine) +void +SetCommPortDefaults() { - int i, j; - char buf[ARG_MAX], currDir[MSG_SIZ]; - char *dummy, *p; - - programName = szAppName; - - /* Initialize to defaults */ - lightSquareColor = ParseColorName(LIGHT_SQUARE_COLOR); - darkSquareColor = ParseColorName(DARK_SQUARE_COLOR); - whitePieceColor = ParseColorName(WHITE_PIECE_COLOR); - blackPieceColor = ParseColorName(BLACK_PIECE_COLOR); - highlightSquareColor = ParseColorName(HIGHLIGHT_SQUARE_COLOR); - premoveHighlightColor = ParseColorName(PREMOVE_HIGHLIGHT_COLOR); - consoleBackgroundColor = ParseColorName(COLOR_BKGD); - SetDefaultTextAttribs(); - SetDefaultSounds(); - appData.movesPerSession = MOVES_PER_SESSION; - appData.initString = INIT_STRING; - appData.secondInitString = INIT_STRING; - appData.firstComputerString = COMPUTER_STRING; - appData.secondComputerString = COMPUTER_STRING; - appData.firstChessProgram = FIRST_CHESS_PROGRAM; - appData.secondChessProgram = SECOND_CHESS_PROGRAM; - appData.firstPlaysBlack = FALSE; - appData.noChessProgram = FALSE; - chessProgram = FALSE; - appData.firstHost = FIRST_HOST; - appData.secondHost = SECOND_HOST; - appData.firstDirectory = FIRST_DIRECTORY; - appData.secondDirectory = SECOND_DIRECTORY; - appData.bitmapDirectory = ""; - appData.remoteShell = REMOTE_SHELL; - appData.remoteUser = ""; - appData.timeDelay = TIME_DELAY; - appData.timeControl = TIME_CONTROL; - appData.timeIncrement = TIME_INCREMENT; - appData.icsActive = FALSE; - appData.icsHost = ""; - appData.icsPort = ICS_PORT; - appData.icsCommPort = ICS_COMM_PORT; - appData.icsLogon = ICS_LOGON; - appData.icsHelper = ""; - appData.useTelnet = FALSE; - appData.telnetProgram = TELNET_PROGRAM; - appData.gateway = ""; - appData.loadGameFile = ""; - appData.loadGameIndex = 0; - appData.saveGameFile = ""; - appData.autoSaveGames = FALSE; - appData.loadPositionFile = ""; - appData.loadPositionIndex = 1; - appData.savePositionFile = ""; - appData.matchMode = FALSE; - appData.matchGames = 0; - appData.monoMode = FALSE; - appData.debugMode = FALSE; - appData.clockMode = TRUE; - boardSize = (BoardSize) -1; /* determine by screen size */ - appData.Iconic = FALSE; /*unused*/ - appData.searchTime = ""; - appData.searchDepth = 0; - appData.showCoords = FALSE; - appData.ringBellAfterMoves = TRUE; /*obsolete in WinBoard*/ - appData.autoCallFlag = FALSE; - appData.flipView = FALSE; - appData.autoFlipView = TRUE; - appData.cmailGameName = ""; - appData.alwaysPromoteToQueen = FALSE; - appData.oldSaveStyle = FALSE; - appData.quietPlay = FALSE; - appData.showThinking = FALSE; - appData.ponderNextMove = TRUE; - appData.periodicUpdates = TRUE; - appData.popupExitMessage = TRUE; - appData.popupMoveErrors = FALSE; - appData.autoObserve = FALSE; - appData.autoComment = FALSE; - appData.animate = TRUE; - appData.animSpeed = 10; - appData.animateDragging = TRUE; - appData.highlightLastMove = TRUE; - appData.getMoveList = TRUE; - appData.testLegality = TRUE; - appData.premove = TRUE; - appData.premoveWhite = FALSE; - appData.premoveWhiteText = ""; - appData.premoveBlack = FALSE; - appData.premoveBlackText = ""; - appData.icsAlarm = TRUE; - appData.icsAlarmTime = 5000; - appData.autoRaiseBoard = TRUE; - appData.localLineEditing = TRUE; - appData.colorize = TRUE; - appData.reuseFirst = TRUE; - appData.reuseSecond = TRUE; - appData.blindfold = FALSE; - appData.icsEngineAnalyze = FALSE; - memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 + + memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 + dcb.DCBlength = sizeof(DCB); dcb.BaudRate = 9600; dcb.fBinary = TRUE; @@ -2042,476 +1430,135 @@ InitAppData(LPSTR lpCmdLine) dcb.ByteSize = 7; dcb.Parity = SPACEPARITY; dcb.StopBits = ONESTOPBIT; - settingsFileName = SETTINGS_FILE; - saveSettingsOnExit = TRUE; - boardX = CW_USEDEFAULT; - boardY = CW_USEDEFAULT; - analysisX = CW_USEDEFAULT; - analysisY = CW_USEDEFAULT; - analysisW = CW_USEDEFAULT; - analysisH = CW_USEDEFAULT; - commentX = CW_USEDEFAULT; - commentY = CW_USEDEFAULT; - commentW = CW_USEDEFAULT; - commentH = CW_USEDEFAULT; - editTagsX = CW_USEDEFAULT; - editTagsY = CW_USEDEFAULT; - editTagsW = CW_USEDEFAULT; - editTagsH = CW_USEDEFAULT; - icsTextMenuString = ICS_TEXT_MENU_DEFAULT; - icsNames = ICS_NAMES; - firstChessProgramNames = FCP_NAMES; - secondChessProgramNames = SCP_NAMES; - appData.initialMode = ""; - appData.variant = "normal"; - appData.firstProtocolVersion = PROTOVER; - appData.secondProtocolVersion = PROTOVER; - appData.showButtonBar = TRUE; - - /* [AS] New properties (see comments in header file) */ - appData.firstScoreIsAbsolute = FALSE; - appData.secondScoreIsAbsolute = FALSE; - appData.saveExtendedInfoInPGN = FALSE; - appData.hideThinkingFromHuman = FALSE; - appData.liteBackTextureFile = ""; - appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN; - appData.darkBackTextureFile = ""; - appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN; - appData.renderPiecesWithFont = ""; - appData.fontToPieceTable = ""; - appData.fontBackColorWhite = 0; - appData.fontForeColorWhite = 0; - appData.fontBackColorBlack = 0; - appData.fontForeColorBlack = 0; - appData.fontPieceSize = 80; - appData.overrideLineGap = 1; - appData.adjudicateLossThreshold = 0; - appData.delayBeforeQuit = 0; - appData.delayAfterQuit = 0; - appData.nameOfDebugFile = "winboard.debug"; - appData.pgnEventHeader = "Computer Chess Game"; - appData.defaultFrcPosition = -1; - appData.gameListTags = GLT_DEFAULT_TAGS; - appData.saveOutOfBookInfo = TRUE; - appData.showEvalInMoveHistory = TRUE; - appData.evalHistColorWhite = ParseColorName( "#FFFFB0" ); - appData.evalHistColorBlack = ParseColorName( "#AD5D3D" ); - appData.highlightMoveWithArrow = FALSE; - appData.highlightArrowColor = ParseColorName( "#FFFF80" ); - appData.useStickyWindows = TRUE; - appData.adjudicateDrawMoves = 0; - appData.autoDisplayComment = TRUE; - appData.autoDisplayTags = TRUE; - appData.firstIsUCI = FALSE; - appData.secondIsUCI = FALSE; - appData.firstHasOwnBookUCI = TRUE; - appData.secondHasOwnBookUCI = TRUE; - appData.polyglotDir = ""; - appData.usePolyglotBook = FALSE; - appData.polyglotBook = ""; - appData.defaultHashSize = 64; - appData.defaultCacheSizeEGTB = 4; - appData.defaultPathEGTB = "c:\\egtb"; - appData.firstOptions = ""; - appData.secondOptions = ""; - - InitWindowPlacement( &wpGameList ); - InitWindowPlacement( &wpMoveHistory ); - InitWindowPlacement( &wpEvalGraph ); - InitWindowPlacement( &wpEngineOutput ); - InitWindowPlacement( &wpConsole ); - - /* [HGM] User-selectable board size, adjudication control, miscellaneous */ - appData.NrFiles = -1; - appData.NrRanks = -1; - appData.holdingsSize = -1; - appData.testClaims = FALSE; - appData.checkMates = FALSE; - appData.materialDraws= FALSE; - appData.trivialDraws = FALSE; - appData.ruleMoves = 51; - appData.drawRepeats = 6; - appData.matchPause = 10000; - appData.alphaRank = FALSE; - appData.allWhite = FALSE; - appData.upsideDown = FALSE; - appData.serverPause = 15; - appData.serverMovesName = NULL; - appData.suppressLoadMoves = FALSE; - appData.firstTimeOdds = 1; - appData.secondTimeOdds = 1; - appData.firstAccumulateTC = 1; // combine previous and current sessions - appData.secondAccumulateTC = 1; - appData.firstNPS = -1; // [HGM] nps: use wall-clock time - appData.secondNPS = -1; - appData.engineComments = 1; - appData.smpCores = 1; // [HGM] SMP: max nr of cores - appData.egtFormats = ""; - -#ifdef ZIPPY - appData.zippyTalk = ZIPPY_TALK; - appData.zippyPlay = ZIPPY_PLAY; - appData.zippyLines = ZIPPY_LINES; - appData.zippyPinhead = ZIPPY_PINHEAD; - appData.zippyPassword = ZIPPY_PASSWORD; - appData.zippyPassword2 = ZIPPY_PASSWORD2; - appData.zippyWrongPassword = ZIPPY_WRONG_PASSWORD; - appData.zippyAcceptOnly = ZIPPY_ACCEPT_ONLY; - appData.zippyUseI = ZIPPY_USE_I; - appData.zippyBughouse = ZIPPY_BUGHOUSE; - appData.zippyNoplayCrafty = ZIPPY_NOPLAY_CRAFTY; - appData.zippyGameEnd = ZIPPY_GAME_END; - appData.zippyGameStart = ZIPPY_GAME_START; - appData.zippyAdjourn = ZIPPY_ADJOURN; - appData.zippyAbort = ZIPPY_ABORT; - appData.zippyVariants = ZIPPY_VARIANTS; - appData.zippyMaxGames = ZIPPY_MAX_GAMES; - appData.zippyReplayTimeout = ZIPPY_REPLAY_TIMEOUT; -#endif - - /* Point font array elements to structures and - parse default font names */ - for (i=0; idef, &font[j][i]->mfp); - } - } - - /* Parse default settings file if any */ - if (ParseSettingsFile(settingsFileName, buf)) { - settingsFileName = strdup(buf); - } +} - /* Parse command line */ - ParseArgs(StringGet, &lpCmdLine); +// [HGM] args: these three cases taken out to stay in front-end +void +SaveFontArg(FILE *f, ArgDescriptor *ad) +{ // in WinBoard every board size has its own font, and the "argLoc" identifies the table, + // while the curent board size determines the element. This system should be ported to XBoard. + // What the table contains pointers to, and how to print the font description, remains platform-dependent + int bs; + for (bs=0; bsargLoc]->mfp; + fprintf(f, "/size=%s ", sizeInfo[bs].name); + fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n", + ad->argName, mfp->faceName, mfp->pointSize, + mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "", + mfp->bold ? "b" : "", + mfp->italic ? "i" : "", + mfp->underline ? "u" : "", + mfp->strikeout ? "s" : "", + (int)mfp->charset); + } + } - /* [HGM] make sure board size is acceptable */ - if(appData.NrFiles > BOARD_SIZE || - appData.NrRanks > BOARD_SIZE ) - DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2); +void +ExportSounds() +{ // [HGM] copy the names from the internal WB variables to appData + ColorClass cc; + SoundClass sc; + for (cc = (ColorClass)0; cc < ColorNormal; cc++) + (&appData.soundShout)[cc] = textAttribs[cc].sound.name; + for (sc = (SoundClass)0; sc < NSoundClasses; sc++) + (&appData.soundMove)[sc] = sounds[sc].name; +} - /* [HGM] After parsing the options from the .ini file, and overruling them - * with options from the command line, we now make an even higher priority - * overrule by WB options attached to the engine command line. This so that - * tournament managers can use WB options (such as /timeOdds) that follow - * the engines. - */ - if(appData.firstChessProgram != NULL) { - char *p = StrStr(appData.firstChessProgram, "WBopt"); - static char *f = "first"; - char buf[MSG_SIZ], *q = buf; - if(p != NULL) { // engine command line contains WinBoard options - sprintf(buf, p+6, f, f, f, f, f, f, f, f, f, f); // replace %s in them by "first" - ParseArgs(StringGet, &q); - p[-1] = 0; // cut them offengine command line - } - } - // now do same for second chess program - if(appData.secondChessProgram != NULL) { - char *p = StrStr(appData.secondChessProgram, "WBopt"); - static char *s = "second"; - char buf[MSG_SIZ], *q = buf; - if(p != NULL) { // engine command line contains WinBoard options - sprintf(buf, p+6, s, s, s, s, s, s, s, s, s, s); // replace %s in them by "first" - ParseArgs(StringGet, &q); - p[-1] = 0; // cut them offengine command line +void +SaveAttribsArg(FILE *f, ArgDescriptor *ad) +{ // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though + MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc]; + fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName, + (ta->effects & CFE_BOLD) ? "b" : "", + (ta->effects & CFE_ITALIC) ? "i" : "", + (ta->effects & CFE_UNDERLINE) ? "u" : "", + (ta->effects & CFE_STRIKEOUT) ? "s" : "", + (ta->effects) ? " " : "", + ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff); } - } +void +SaveColor(FILE *f, ArgDescriptor *ad) +{ // in WinBoard the color is an int and has to be converted to text. In X it would be a string already? + COLORREF color = *(COLORREF *)colorVariable[(int)ad->argLoc]; + fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, + color&0xff, (color>>8)&0xff, (color>>16)&0xff); +} - /* Propagate options that affect others */ - if (appData.matchMode || appData.matchGames) chessProgram = TRUE; - if (appData.icsActive || appData.noChessProgram) { - chessProgram = FALSE; /* not local chess program mode */ - } +void +SaveBoardSize(FILE *f, char *name, void *addr) +{ // wrapper to shield back-end from BoardSize & sizeInfo + fprintf(f, "/%s=%s\n", name, sizeInfo[*(BoardSize *)addr].name); +} - /* Open startup dialog if needed */ - if ((!appData.noChessProgram && !chessProgram && !appData.icsActive) || - (appData.icsActive && *appData.icsHost == NULLCHAR) || - (chessProgram && (*appData.firstChessProgram == NULLCHAR || - *appData.secondChessProgram == NULLCHAR))) { - FARPROC lpProc; - - lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst); - DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc); - FreeProcInstance(lpProc); - } +void +ParseCommPortSettings(char *s) +{ // wrapper to keep dcb from back-end + ParseCommSettings(s, &dcb); +} - /* Make sure save files land in the right (?) directory */ - if (GetFullPathName(appData.saveGameFile, MSG_SIZ, buf, &dummy)) { - appData.saveGameFile = strdup(buf); - } - if (GetFullPathName(appData.savePositionFile, MSG_SIZ, buf, &dummy)) { - appData.savePositionFile = strdup(buf); - } +void +GetWindowCoords() +{ // wrapper to shield use of window handles from back-end (make addressible by number?) + GetActualPlacement(hwndMain, &wpMain); + GetActualPlacement(hwndConsole, &wpConsole); + GetActualPlacement(commentDialog, &wpComment); + GetActualPlacement(editTagsDialog, &wpTags); + GetActualPlacement(gameListDialog, &wpGameList); + GetActualPlacement(moveHistoryDialog, &wpMoveHistory); + GetActualPlacement(evalGraphDialog, &wpEvalGraph); + GetActualPlacement(engineOutputDialog, &wpEngineOutput); +} - /* Finish initialization for fonts and sounds */ - for (i=0; iargName != NULL; ad++) { - if (!ad->save) continue; - switch (ad->argType) { - case ArgString: - { - char *p = *(char **)ad->argLoc; - if ((strchr(p, '\\') || strchr(p, '\n')) && !strchr(p, '}')) { - /* Quote multiline values or \-containing values - with { } if possible */ - fprintf(f, "/%s={%s}\n", ad->argName, p); - } else { - /* Else quote with " " */ - fprintf(f, "/%s=\"", ad->argName); - while (*p) { - if (*p == '\n') fprintf(f, "\n"); - else if (*p == '\r') fprintf(f, "\\r"); - else if (*p == '\t') fprintf(f, "\\t"); - else if (*p == '\b') fprintf(f, "\\b"); - else if (*p == '\f') fprintf(f, "\\f"); - else if (*p < ' ') fprintf(f, "\\%03o", *p); - else if (*p == '\"') fprintf(f, "\\\""); - else if (*p == '\\') fprintf(f, "\\\\"); - else putc(*p, f); - p++; - } - fprintf(f, "\"\n"); - } - } - break; - case ArgInt: - case ArgZ: - fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc); - break; - case ArgX: - fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value - break; - case ArgY: - fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY); - break; - case ArgFloat: - fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc); - break; - case ArgBoolean: - fprintf(f, "/%s=%s\n", ad->argName, - (*(Boolean *)ad->argLoc) ? "true" : "false"); - break; - case ArgTrue: - if (*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName); - break; - case ArgFalse: - if (!*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName); - break; - case ArgColor: - { - COLORREF color = *(COLORREF *)ad->argLoc; - fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, - color&0xff, (color>>8)&0xff, (color>>16)&0xff); - } - break; - case ArgAttribs: - { - MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc]; - fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName, - (ta->effects & CFE_BOLD) ? "b" : "", - (ta->effects & CFE_ITALIC) ? "i" : "", - (ta->effects & CFE_UNDERLINE) ? "u" : "", - (ta->effects & CFE_STRIKEOUT) ? "s" : "", - (ta->effects) ? " " : "", - ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff); - } - break; - case ArgFilename: - if (strchr(*(char **)ad->argLoc, '\"')) { - fprintf(f, "/%s='%s'\n", ad->argName, *(char **)ad->argLoc); - } else { - fprintf(f, "/%s=\"%s\"\n", ad->argName, *(char **)ad->argLoc); - } - break; - case ArgBoardSize: - fprintf(f, "/%s=%s\n", ad->argName, - sizeInfo[*(BoardSize *)ad->argLoc].name); - break; - case ArgFont: - { - int bs; - for (bs=0; bsargLoc]->mfp; - fprintf(f, "/size=%s ", sizeInfo[bs].name); - fprintf(f, "/%s=\"%s:%g%s%s%s%s%s\"\n", - ad->argName, mfp->faceName, mfp->pointSize, - mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "", - mfp->bold ? "b" : "", - mfp->italic ? "i" : "", - mfp->underline ? "u" : "", - mfp->strikeout ? "s" : ""); - } - } - break; - case ArgCommSettings: - PrintCommSettings(f, ad->argName, (DCB *)ad->argLoc); - case ArgNone: - case ArgSettingsFilename: ; - } - } - fclose(f); + FARPROC lpProc; + + LoadLanguageFile(appData.language); + lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst); + DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc); + FreeProcInstance(lpProc); } - - /*---------------------------------------------------------------------------*\ * * GDI board drawing routines @@ -2959,7 +2006,8 @@ void CreatePiecesFromFont() return; } - if( appData.renderPiecesWithFont == NULL || appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) { + if( !appData.useFont || appData.renderPiecesWithFont == NULL || + appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) { fontBitmapSquareSize = -1; return; } @@ -3025,7 +2073,7 @@ void CreatePiecesFromFont() } else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) { /* Good Companion (Some characters get warped as literal :-( */ - char s[] = "1cmWG0ñueOS¯®oYI23wgQU"; + char s[] = "1cmWG0??S??oYI23wgQU"; s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3; SetCharTable(pieceToFontChar, s); } @@ -3061,11 +2109,11 @@ DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix) { char name[128]; - sprintf(name, "%s%d%s", piece, squareSize, suffix); + snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix); if (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0 && strcmp(name, "k80s") == 0) { - strcpy(name, "tim"); + safeStrCpy(name, "tim", sizeof(name)/sizeof(name[0]) ); } return LoadBitmap(hinst, name); } @@ -3082,7 +2130,7 @@ InsertInPalette(COLORREF color) LPPALETTEENTRY pe = &(pLogPal->palPalEntry[pLogPal->palNumEntries]); if (pLogPal->palNumEntries++ >= PALETTESIZE) { - DisplayFatalError("Too many colors", 0, 1); + DisplayFatalError(_("Too many colors"), 0, 1); pLogPal->palNumEntries--; return; } @@ -3129,6 +2177,7 @@ InitDrawingColors() blackPieceBrush = CreateSolidBrush(blackPieceColor); iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND)); explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic + markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers /* [AS] Force rendering of the font-based pieces */ if( fontBitmapSquareSize > 0 ) { fontBitmapSquareSize = 0; @@ -3170,6 +2219,7 @@ ResizeBoard(int newSizeX, int newSizeY, int flags) } +extern Boolean twoBoards, partnerUp; // [HGM] dual VOID InitDrawingSizes(BoardSize boardSize, int flags) @@ -3193,10 +2243,10 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize; - oldRect.left = boardX; //[HGM] placement: remember previous window params - oldRect.top = boardY; - oldRect.right = boardX + winWidth; - oldRect.bottom = boardY + winHeight; + oldRect.left = wpMain.x; //[HGM] placement: remember previous window params + oldRect.top = wpMain.y; + oldRect.right = wpMain.x + wpMain.width; + oldRect.bottom = wpMain.y + wpMain.height; tinyLayout = sizeInfo[boardSize].tinyLayout; smallLayout = sizeInfo[boardSize].smallLayout; @@ -3209,7 +2259,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) } if (tinyLayout != oldTinyLayout) { - long style = GetWindowLong(hwndMain, GWL_STYLE); + long style = GetWindowLongPtr(hwndMain, GWL_STYLE); if (tinyLayout) { style &= ~WS_SYSMENU; InsertMenu(hmenu, IDM_Exit, MF_BYCOMMAND, IDM_Minimize, @@ -3218,11 +2268,11 @@ InitDrawingSizes(BoardSize boardSize, int flags) style |= WS_SYSMENU; RemoveMenu(hmenu, IDM_Minimize, MF_BYCOMMAND); } - SetWindowLong(hwndMain, GWL_STYLE, style); + SetWindowLongPtr(hwndMain, GWL_STYLE, style); for (i=0; menuBarText[tinyLayout][i]; i++) { ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, - (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]); + (UINT)GetSubMenu(hmenu, i), T_(menuBarText[tinyLayout][i])); } DrawMenuBar(hwndMain); } @@ -3233,14 +2283,14 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* Get text area sizes */ hdc = GetDC(hwndMain); if (appData.clockMode) { - sprintf(buf, "White: %s", TimeString(23*60*60*1000L)); + snprintf(buf, MSG_SIZ, _("White: %s"), TimeString(23*60*60*1000L)); } else { - sprintf(buf, "White"); + snprintf(buf, MSG_SIZ, _("White")); } oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf); GetTextExtentPoint(hdc, buf, strlen(buf), &clockSize); SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf); - str = "We only care about the height here"; + str = _("We only care about the height here"); GetTextExtentPoint(hdc, str, strlen(str), &messageSize); SelectObject(hdc, oldFont); ReleaseDC(hwndMain, hdc); @@ -3279,6 +2329,8 @@ InitDrawingSizes(BoardSize boardSize, int flags) blackRect.right = blackRect.left + boardWidth/2 - 1; blackRect.top = whiteRect.top; blackRect.bottom = whiteRect.bottom; + + logoHeight = 0; // [HGM] logo: suppress logo after change to tiny layout! } messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN; @@ -3303,50 +2355,51 @@ InitDrawingSizes(BoardSize boardSize, int flags) winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN; winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN; + winW *= 1 + twoBoards; if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only - winWidth = winW; // [HGM] placement: set through temporary which can used by initial sizing choice - winHeight = winH; // without disturbing window attachments + wpMain.width = winW; // [HGM] placement: set through temporary which can used by initial sizing choice + wpMain.height = winH; // without disturbing window attachments GetWindowRect(hwndMain, &wrect); - SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight, + SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE); // [HGM] placement: let attached windows follow size change. - ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory ); - ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph ); - ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput ); - ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList ); - ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, moveHistoryDialog, &wpMoveHistory ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, evalGraphDialog, &wpEvalGraph ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, engineOutputDialog, &wpEngineOutput ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, gameListDialog, &wpGameList ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, hwndConsole, &wpConsole ); /* compensate if menu bar wrapped */ GetClientRect(hwndMain, &crect); offby = boardRect.bottom + OUTER_MARGIN - crect.bottom; - winHeight += offby; + wpMain.height += offby; switch (flags) { case WMSZ_TOPLEFT: SetWindowPos(hwndMain, NULL, - wrect.right - winWidth, wrect.bottom - winHeight, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.right - wpMain.width, wrect.bottom - wpMain.height, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_TOPRIGHT: case WMSZ_TOP: SetWindowPos(hwndMain, NULL, - wrect.left, wrect.bottom - winHeight, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.left, wrect.bottom - wpMain.height, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_BOTTOMLEFT: case WMSZ_LEFT: SetWindowPos(hwndMain, NULL, - wrect.right - winWidth, wrect.top, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.right - wpMain.width, wrect.top, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_BOTTOMRIGHT: case WMSZ_BOTTOM: case WMSZ_RIGHT: default: - SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight, + SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE); break; } @@ -3364,7 +2417,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i), messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain, (HMENU) buttonDesc[i].id, - (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL); + (HINSTANCE) GetWindowLongPtr(hwndMain, GWLP_HINSTANCE), NULL); if (tinyLayout) { SendMessage(buttonDesc[i].hwnd, WM_SETFONT, (WPARAM)font[boardSize][MESSAGE_FONT]->hf, @@ -3373,7 +2426,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) if (buttonDesc[i].id == IDM_Pause) hwndPause = buttonDesc[i].hwnd; buttonDesc[i].wndproc = (WNDPROC) - SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc); + SetWindowLongPtr(buttonDesc[i].hwnd, GWLP_WNDPROC, (LONG_PTR) ButtonProc); } } if (gridPen != NULL) DeleteObject(gridPen); @@ -3454,7 +2507,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "w"); pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "w"); pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "w"); - if( !strcmp(appData.variant, "shogi") && (squareSize==72 || squareSize==49)) { + if( gameInfo.variant == VariantShogi && squareSize <= 72 && squareSize >= 33) { // in Shogi, Hijack the unused Queen for Lance pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "s"); pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "o"); @@ -3481,14 +2534,24 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o"); pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w"); } else { // Smirf-like - pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); - pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); - pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + if(gameInfo.variant == VariantSChess) { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "w"); + } else { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + } } if(gameInfo.variant == VariantGothic) { // Vortex-like pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "o"); pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "w"); + } else if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "s"); + pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "o"); + pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "w"); } else { // WinBoard standard pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "o"); @@ -3664,8 +2727,8 @@ SquareToPos(int row, int column, int * x, int * y) VOID DrawCoordsOnDC(HDC hdc) { - static char files[24] = {'0', '1','2','3','4','5','6','7','8','9','0','1','1','0','9','8','7','6','5','4','3','2','1','0'}; - static char ranks[24] = {'l', 'k','j','i','h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h','i','j','k','l'}; + static char files[] = "0123456789012345678901221098765432109876543210"; + static char ranks[] = "wvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvw"; char str[2] = { NULLCHAR, NULLCHAR }; int oldMode, oldAlign, x, y, start, i; HFONT oldFont; @@ -3674,7 +2737,7 @@ DrawCoordsOnDC(HDC hdc) if (!appData.showCoords) return; - start = flipView ? 1-(ONE!='1') : 23+(ONE!='1')-BOARD_HEIGHT; + start = flipView ? 1-(ONE!='1') : 45+(ONE!='1')-BOARD_HEIGHT; oldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH)); oldMode = SetBkMode(hdc, (appData.monoMode ? OPAQUE : TRANSPARENT)); @@ -3691,7 +2754,7 @@ DrawCoordsOnDC(HDC hdc) y += squareSize + lineGap; } - start = flipView ? 12-(BOARD_RGHT-BOARD_LEFT) : 12; + start = flipView ? 23-(BOARD_RGHT-BOARD_LEFT) : 23; SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM); for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) { @@ -3749,23 +2812,14 @@ DrawHighlightOnDC(HDC hdc, BOOLEAN on, int x, int y, int pen) } VOID -DrawHighlightsOnDC(HDC hdc) +DrawHighlightsOnDC(HDC hdc, HighlightInfo *h, int pen) { int i; for (i=0; i<2; i++) { - if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) + if (h->sq[i].x >= 0 && h->sq[i].y >= 0) DrawHighlightOnDC(hdc, TRUE, - highlightInfo.sq[i].x, highlightInfo.sq[i].y, - HIGHLIGHT_PEN); - } - for (i=0; i<2; i++) { - if (premoveHighlightInfo.sq[i].x >= 0 && - premoveHighlightInfo.sq[i].y >= 0) { - DrawHighlightOnDC(hdc, TRUE, - premoveHighlightInfo.sq[i].x, - premoveHighlightInfo.sq[i].y, - PREMOVE_PEN); - } + h->sq[i].x, h->sq[i].y, + pen); } } @@ -3782,7 +2836,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, if (appData.blindfold) return; /* [AS] Use font-based pieces if needed */ - if( fontBitmapSquareSize >= 0 && squareSize > 32 ) { + if( fontBitmapSquareSize >= 0 && (squareSize > 32 || gameInfo.variant >= VariantShogi)) { /* Create piece bitmaps, or do nothing if piece set is up to date */ CreatePiecesFromFont(); @@ -3791,6 +2845,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceMask[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCAND); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -3800,6 +2857,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceFace[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCPAINT); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -3909,7 +2969,13 @@ VOID RebuildTextureSquareInfo() if( (col + row) & 1 ) { /* Lite square */ if( lite_w >= squareSize && lite_h >= squareSize ) { + if( lite_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1)*lite_w/(2*BOARD_WIDTH) - squareSize/2; /* [HGM] cut out of center of virtual square */ + else backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / (BOARD_WIDTH-1); /* [HGM] divide by size-1 in stead of size! */ + if( lite_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1)*lite_h/(2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (lite_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode); } @@ -3917,7 +2983,13 @@ VOID RebuildTextureSquareInfo() else { /* Dark square */ if( dark_w >= squareSize && dark_h >= squareSize ) { + if( dark_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1) * dark_w / (2*BOARD_WIDTH) - squareSize/2; + else backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / (BOARD_WIDTH-1); + if( dark_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1) * dark_h / (2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (dark_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode); } @@ -3928,7 +3000,7 @@ VOID RebuildTextureSquareInfo() /* [AS] Arrow highlighting support */ -static int A_WIDTH = 5; /* Width of arrow body */ +static double A_WIDTH = 5; /* Width of arrow body */ #define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */ #define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */ @@ -3952,50 +3024,50 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) if( d_x == s_x ) { int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; - arrow[0].x = s_x + A_WIDTH; + arrow[0].x = s_x + A_WIDTH + 0.5; arrow[0].y = s_y; - arrow[1].x = s_x + A_WIDTH; + arrow[1].x = s_x + A_WIDTH + 0.5; arrow[1].y = d_y - h; - arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[2].y = d_y - h; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR; - arrow[4].y = d_y - h; - - arrow[5].x = s_x - A_WIDTH; + arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[5].y = d_y - h; - arrow[6].x = s_x - A_WIDTH; + arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[4].y = d_y - h; + + arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[6].y = s_y; } else if( d_y == s_y ) { int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; arrow[0].x = s_x; - arrow[0].y = s_y + A_WIDTH; + arrow[0].y = s_y + A_WIDTH + 0.5; arrow[1].x = d_x - w; - arrow[1].y = s_y + A_WIDTH; + arrow[1].y = s_y + A_WIDTH + 0.5; arrow[2].x = d_x - w; - arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = d_x - w; - arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR; - arrow[5].x = d_x - w; - arrow[5].y = s_y - A_WIDTH; + arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5; + + arrow[4].x = d_x - w; + arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[6].x = s_x; - arrow[6].y = s_y - A_WIDTH; + arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5; } else { /* [AS] Needed a lot of paper for this! :-) */ @@ -4012,8 +3084,8 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) arrow[0].x = Round(x - j); arrow[0].y = Round(y + j*dx); - arrow[1].x = Round(x + j); - arrow[1].y = Round(y - j*dx); + arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice + arrow[1].y = Round(arrow[0].y - 2*j*dx); if( d_x > s_x ) { x = (double) d_x - k; @@ -4024,20 +3096,22 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) y = (double) d_y + k*dy; } - arrow[2].x = Round(x + j); - arrow[2].y = Round(y - j*dx); + x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends - arrow[3].x = Round(x + j*A_WIDTH_FACTOR); - arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx); + arrow[6].x = Round(x - j); + arrow[6].y = Round(y + j*dx); + + arrow[2].x = Round(arrow[6].x + 2*j); + arrow[2].y = Round(arrow[6].y - 2*j*dx); + + arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1)); + arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx); arrow[4].x = d_x; arrow[4].y = d_y; - arrow[5].x = Round(x - j*A_WIDTH_FACTOR); - arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx); - - arrow[6].x = Round(x - j); - arrow[6].y = Round(y + j*dx); + arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1)); + arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx); } Polygon( hdc, arrow, 7 ); @@ -4062,20 +3136,20 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro SquareToPos( d_row, d_col, &d_x, &d_y); if( d_y > s_y ) { - d_y += squareSize / 4; + d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides! } else if( d_y < s_y ) { - d_y += 3 * squareSize / 4; + d_y += squareSize / 2 + squareSize / 4; } else { d_y += squareSize / 2; } if( d_x > s_x ) { - d_x += squareSize / 4; + d_x += squareSize / 2 - squareSize / 4; } else if( d_x < s_x ) { - d_x += 3 * squareSize / 4; + d_x += squareSize / 2 + squareSize / 4; } else { d_x += squareSize / 2; @@ -4085,7 +3159,7 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro s_y += squareSize / 2; /* Adjust width */ - A_WIDTH = squareSize / 14; + A_WIDTH = squareSize / 14.; //[HGM] make float /* Draw */ stLB.lbStyle = BS_SOLID; @@ -4207,7 +3281,7 @@ BOOL DrawPositionNeedsFullRepaint() but animation is fast enough that it's difficult to notice. */ if( animInfo.piece == EmptySquare ) { - if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() && HasHighlightInfo() ) { + if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() /*&& HasHighlightInfo()*/ ) { result = TRUE; } } @@ -4227,8 +3301,8 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) if( liteBackTexture != NULL || darkBackTexture != NULL ) { static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */ if( backTextureSquareSize != squareSize - || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) { - backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT; + || backTextureBoardSize != BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT) { + backTextureBoardSize = BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT; backTextureSquareSize = squareSize; RebuildTextureSquareInfo(); } @@ -4282,7 +3356,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) DrawPieceOnDC(hdc, piece, piece_color, square_color, x, y, tmphdc); } } - else if( backTextureSquareInfo[row][column].mode > 0 ) { + else if( appData.useBitmaps && backTextureSquareInfo[row][column].mode > 0 ) { /* [AS] Draw the square using a texture bitmap */ HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture ); int r = row, c = column; // [HGM] do not flip board in flipView @@ -4340,7 +3414,10 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) HBITMAP hbm; int w = 100, h = 50; - if(logo == NULL) return; + if(logo == NULL) { + if(!logoHeight) return; + FillRect( hdc, &logoRect, whitePieceBrush ); + } // GetClientRect(hwndMain, &Rect); // bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1, // Rect.bottom-Rect.top+1); @@ -4357,12 +3434,119 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) } VOID +DisplayLogos() +{ + if(logoHeight) { + HDC hdc = GetDC(hwndMain); + HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; + if(appData.autoLogo) { + + switch(gameMode) { // pick logos based on game mode + case IcsObserving: + whiteLogo = second.programLogo; // ICS logo + blackLogo = second.programLogo; + default: + break; + case IcsPlayingWhite: + if(!appData.zippyPlay) whiteLogo = userLogo; + blackLogo = second.programLogo; // ICS logo + break; + case IcsPlayingBlack: + whiteLogo = second.programLogo; // ICS logo + blackLogo = appData.zippyPlay ? first.programLogo : userLogo; + break; + case TwoMachinesPlay: + if(first.twoMachinesColor[0] == 'b') { + whiteLogo = second.programLogo; + blackLogo = first.programLogo; + } + break; + case MachinePlaysWhite: + blackLogo = userLogo; + break; + case MachinePlaysBlack: + whiteLogo = userLogo; + blackLogo = first.programLogo; + } + } + DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); + DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); + ReleaseDC(hwndMain, hdc); + } +} + +void +UpdateLogos(int display) +{ // called after loading new engine(s), in tourney or from menu + LoadLogo(&first, 0, FALSE); + LoadLogo(&second, 1, appData.icsActive); + InitDrawingSizes(-2, 0); // adapt layout of board window to presence/absence of logos + if(display) DisplayLogos(); +} + +static HDC hdcSeek; + +// [HGM] seekgraph +void DrawSeekAxis( int x, int y, int xTo, int yTo ) +{ + POINT stPt; + HPEN hp = SelectObject( hdcSeek, gridPen ); + MoveToEx( hdcSeek, boardRect.left+x, boardRect.top+y, &stPt ); + LineTo( hdcSeek, boardRect.left+xTo, boardRect.top+yTo ); + SelectObject( hdcSeek, hp ); +} + +// front-end wrapper for drawing functions to do rectangles +void DrawSeekBackground( int left, int top, int right, int bottom ) +{ + HPEN hp; + RECT rc; + + if (hdcSeek == NULL) { + hdcSeek = GetDC(hwndMain); + if (!appData.monoMode) { + SelectPalette(hdcSeek, hPal, FALSE); + RealizePalette(hdcSeek); + } + } + hp = SelectObject( hdcSeek, gridPen ); + rc.top = boardRect.top+top; rc.left = boardRect.left+left; + rc.bottom = boardRect.top+bottom; rc.right = boardRect.left+right; + FillRect( hdcSeek, &rc, lightSquareBrush ); + SelectObject( hdcSeek, hp ); +} + +// front-end wrapper for putting text in graph +void DrawSeekText(char *buf, int x, int y) +{ + SIZE stSize; + SetBkMode( hdcSeek, TRANSPARENT ); + GetTextExtentPoint32( hdcSeek, buf, strlen(buf), &stSize ); + TextOut( hdcSeek, boardRect.left+x-3, boardRect.top+y-stSize.cy/2, buf, strlen(buf) ); +} + +void DrawSeekDot(int x, int y, int color) +{ + int square = color & 0x80; + HBRUSH oldBrush = SelectObject(hdcSeek, + color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush); + color &= 0x7F; + if(square) + Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9, + boardRect.left+x + squareSize/9, boardRect.top+y + squareSize/9); + else + Ellipse(hdcSeek, boardRect.left+x - squareSize/8, boardRect.top+y - squareSize/8, + boardRect.left+x + squareSize/8, boardRect.top+y + squareSize/8); + SelectObject(hdcSeek, oldBrush); +} + +VOID HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) { - static Board lastReq, lastDrawn; + static Board lastReq[2], lastDrawn[2]; static HighlightInfo lastDrawnHighlight, lastDrawnPremove; static int lastDrawnFlipView = 0; - static int lastReqValid = 0, lastDrawnValid = 0; + static int lastReqValid[2] = {0, 0}, lastDrawnValid[2] = {0, 0}; int releaseDC, x, y, x2, y2, row, column, num_clips = 0, i; HDC tmphdc; HDC hdcmem; @@ -4371,6 +3555,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) RECT Rect; HRGN clips[MAX_CLIPS]; ChessSquare dragged_piece = EmptySquare; + int nr = twoBoards*partnerUp; /* I'm undecided on this - this function figures out whether a full * repaint is necessary on its own, so there's no real reason to have the @@ -4382,18 +3567,20 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) */ Boolean fullrepaint = repaint; + if(DrawSeekGraph()) return; // [HG} seekgraph: suppress printing board if seek graph up + if( DrawPositionNeedsFullRepaint() ) { fullrepaint = TRUE; } if (board == NULL) { - if (!lastReqValid) { + if (!lastReqValid[nr]) { return; } - board = lastReq; + board = lastReq[nr]; } else { - CopyBoard(lastReq, board); - lastReqValid = 1; + CopyBoard(lastReq[nr], board); + lastReqValid[nr] = 1; } if (doingSizing) { @@ -4432,23 +3619,24 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(--board[dragInfo.from.y][dragInfo.from.x-1] == 0 ) board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; } else - board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; + board[dragInfo.from.y][dragInfo.from.x] = gatingPiece; } /* Figure out which squares need updating by comparing the * newest board with the last drawn board and checking if * flipping has changed. */ - if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) { + if (!fullrepaint && lastDrawnValid[nr] && (nr == 1 || lastDrawnFlipView == flipView)) { for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */ for (column = 0; column < BOARD_WIDTH; column++) { - if (lastDrawn[row][column] != board[row][column]) { + if (lastDrawn[nr][row][column] != board[row][column]) { SquareToPos(row, column, &x, &y); clips[num_clips++] = CreateRectRgn(x, y, x + squareSize, y + squareSize); } } } + if(nr == 0) { // [HGM] dual: no highlights on second board for (i=0; i<2; i++) { if (lastDrawnHighlight.sq[i].x != highlightInfo.sq[i].x || lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) { @@ -4489,6 +3677,30 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) } } } + } else { // nr == 1 + partnerHighlightInfo.sq[0].y = board[EP_STATUS-4]; + partnerHighlightInfo.sq[0].x = board[EP_STATUS-3]; + partnerHighlightInfo.sq[1].y = board[EP_STATUS-2]; + partnerHighlightInfo.sq[1].x = board[EP_STATUS-1]; + for (i=0; i<2; i++) { + if (partnerHighlightInfo.sq[i].x >= 0 && + partnerHighlightInfo.sq[i].y >= 0) { + SquareToPos(partnerHighlightInfo.sq[i].y, + partnerHighlightInfo.sq[i].x, &x, &y); + clips[num_clips++] = + CreateRectRgn(x - lineGap, y - lineGap, + x + squareSize + lineGap, y + squareSize + lineGap); + } + if (oldPartnerHighlight.sq[i].x >= 0 && + oldPartnerHighlight.sq[i].y >= 0) { + SquareToPos(oldPartnerHighlight.sq[i].y, + oldPartnerHighlight.sq[i].x, &x, &y); + clips[num_clips++] = + CreateRectRgn(x - lineGap, y - lineGap, + x + squareSize + lineGap, y + squareSize + lineGap); + } + } + } } else { fullrepaint = TRUE; } @@ -4548,7 +3760,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) explodes. The old and new positions both had an empty square at the destination, but animation has drawn a piece there and we have to remember to erase it. [HGM] moved until after setting lastDrawn */ - lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece; + lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece; } } @@ -4569,6 +3781,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(explodeInfo.radius) { // [HGM] atomic HBRUSH oldBrush; int x, y, r=(explodeInfo.radius * squareSize)/100; + ChessSquare piece = board[explodeInfo.fromY][explodeInfo.fromX]; board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y); x += squareSize/2; @@ -4578,50 +3791,36 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR); } DrawGridOnDC(hdcmem); - DrawHighlightsOnDC(hdcmem); + DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); + DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); DrawBoardOnDC(hdcmem, board, tmphdc); + board[explodeInfo.fromY][explodeInfo.fromX] = piece; oldBrush = SelectObject(hdcmem, explodeBrush); Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); } else { DrawGridOnDC(hdcmem); - DrawHighlightsOnDC(hdcmem); + if(nr == 0) { // [HGM] dual: decide which highlights to draw + DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); + DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); + } else { + DrawHighlightsOnDC(hdcmem, &partnerHighlightInfo, HIGHLIGHT_PEN); + oldPartnerHighlight = partnerHighlightInfo; + } DrawBoardOnDC(hdcmem, board, tmphdc); } - if(logoHeight) { - HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; - if(appData.autoLogo) { - - switch(gameMode) { // pick logos based on game mode - case IcsObserving: - whiteLogo = second.programLogo; // ICS logo - blackLogo = second.programLogo; - default: - break; - case IcsPlayingWhite: - if(!appData.zippyPlay) whiteLogo = userLogo; - blackLogo = second.programLogo; // ICS logo - break; - case IcsPlayingBlack: - whiteLogo = second.programLogo; // ICS logo - blackLogo = appData.zippyPlay ? first.programLogo : userLogo; - break; - case TwoMachinesPlay: - if(first.twoMachinesColor[0] == 'b') { - whiteLogo = second.programLogo; - blackLogo = first.programLogo; - } - break; - case MachinePlaysWhite: - blackLogo = userLogo; - break; - case MachinePlaysBlack: - whiteLogo = userLogo; - blackLogo = first.programLogo; - } + if(nr == 0) // [HGM] dual: markers only on left board + for (row = 0; row < BOARD_HEIGHT; row++) { + for (column = 0; column < BOARD_WIDTH; column++) { + if (marker[row][column]) { // marker changes only occur with full repaint! + HBRUSH oldBrush = SelectObject(hdcmem, + marker[row][column] == 2 ? markerBrush : explodeBrush); + SquareToPos(row, column, &x, &y); + Ellipse(hdcmem, x + squareSize/4, y + squareSize/4, + x + 3*squareSize/4, y + 3*squareSize/4); + SelectObject(hdcmem, oldBrush); } - DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); - DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); + } } if( appData.highlightMoveWithArrow ) { @@ -4630,7 +3829,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawCoordsOnDC(hdcmem); - CopyBoard(lastDrawn, board); /* [HGM] Moved to here from end of routine, */ + CopyBoard(lastDrawn[nr], board); /* [HGM] Moved to here from end of routine, */ /* to make sure lastDrawn contains what is actually drawn */ /* Put the dragged piece back into place and draw it (out of place!) */ @@ -4644,8 +3843,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) board[dragInfo.from.y][dragInfo.from.x] = dragged_piece; x = dragInfo.pos.x - squareSize / 2; y = dragInfo.pos.y - squareSize / 2; - DrawPieceOnDC(hdcmem, dragged_piece, - ((int) dragged_piece < (int) BlackPawn), + DrawPieceOnDC(hdcmem, dragInfo.piece, + ((int) dragInfo.piece < (int) BlackPawn), (dragInfo.from.y + dragInfo.from.x) % 2, x, y, tmphdc); } @@ -4667,6 +3866,13 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) /* Set clipping on the target DC */ if (!fullrepaint) { + if(nr == 1) for (x = 0; x < num_clips; x++) { // [HGM] dual: translate clips + RECT rect; + GetRgnBox(clips[x], &rect); + DeleteObject(clips[x]); + clips[x] = CreateRectRgn(rect.left + wpMain.width/2, rect.top, + rect.right + wpMain.width/2, rect.bottom); + } SelectClipRgn(hdc, clips[0]); for (x = 1; x < num_clips; x++) { if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR) @@ -4678,16 +3884,16 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) * This way we avoid any flickering */ oldBitmap = SelectObject(tmphdc, bufferBitmap); - BitBlt(hdc, boardRect.left, boardRect.top, + BitBlt(hdc, boardRect.left + twoBoards*partnerUp*wpMain.width/2, boardRect.top, // [HGM] dual boardRect.right - boardRect.left, boardRect.bottom - boardRect.top, tmphdc, boardRect.left, boardRect.top, SRCCOPY); if(saveDiagFlag) { - BITMAP b; int i, j=0, m, w, wb, fac=0; char pData[1000000]; + BITMAP b; int i, j=0, m, w, wb, fac=0; char *pData; BITMAPINFOHEADER bih; int color[16], nrColors=0; GetObject(bufferBitmap, sizeof(b), &b); - if(b.bmWidthBytes*b.bmHeight <= 990000) { + if(pData = malloc(b.bmWidthBytes*b.bmHeight + 10000)) { bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = b.bmWidth; bih.biHeight = b.bmHeight; @@ -4751,6 +3957,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) // write bitmap data for(i=0; ihf); ExtTextOut(hdc, messageRect.left, messageRect.top, @@ -4825,6 +4034,7 @@ PaintProc(HWND hwnd) &messageRect, messageText, strlen(messageText), NULL); SelectObject(hdc, oldFont); DisplayBothClocks(); + DisplayLogos(); } EndPaint(hwnd,&ps); } @@ -4839,8 +4049,8 @@ PaintProc(HWND hwnd) * The offset boardRect.left or boardRect.top must already have been * subtracted from x. */ -int -EventToSquare(int x) +int EventToSquare(x, limit) + int x, limit; { if (x <= 0) return -2; @@ -4850,7 +4060,7 @@ EventToSquare(int x) if ((x % (squareSize + lineGap)) >= squareSize) return -1; x /= (squareSize + lineGap); - if (x >= BOARD_SIZE) + if (x >= limit) return -2; return x; } @@ -4862,11 +4072,11 @@ typedef struct { } DropEnable; DropEnable dropEnables[] = { - { 'P', DP_Pawn, "Pawn" }, - { 'N', DP_Knight, "Knight" }, - { 'B', DP_Bishop, "Bishop" }, - { 'R', DP_Rook, "Rook" }, - { 'Q', DP_Queen, "Queen" }, + { 'P', DP_Pawn, N_("Pawn") }, + { 'N', DP_Knight, N_("Knight") }, + { 'B', DP_Bishop, N_("Bishop") }, + { 'R', DP_Rook, N_("Rook") }, + { 'Q', DP_Queen, N_("Queen") }, }; VOID @@ -4882,7 +4092,7 @@ SetupDropMenu(HMENU hmenu) dropEnables[i].piece); count = 0; while (p && *p++ == dropEnables[i].piece) count++; - sprintf(item, "%s %d", dropEnables[i].name, count); + snprintf(item, MSG_SIZ, "%s %d", T_(dropEnables[i].name), count); enable = count > 0 || !appData.testLegality /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse && !appData.icsActive); @@ -4892,19 +4102,40 @@ SetupDropMenu(HMENU hmenu) } } +void DragPieceBegin(int x, int y, Boolean instantly) +{ + dragInfo.lastpos.x = boardRect.left + x; + dragInfo.lastpos.y = boardRect.top + y; + if(instantly) dragInfo.pos = dragInfo.lastpos; + dragInfo.from.x = fromX; + dragInfo.from.y = fromY; + dragInfo.piece = boards[currentMove][fromY][fromX]; + dragInfo.start = dragInfo.from; + SetCapture(hwndMain); +} + +void DragPieceEnd(int x, int y) +{ + ReleaseCapture(); + dragInfo.start.x = dragInfo.start.y = -1; + dragInfo.from = dragInfo.start; + dragInfo.pos = dragInfo.lastpos = dragInfo.start; +} + +void ChangeDragPiece(ChessSquare piece) +{ + dragInfo.piece = piece; +} + /* Event handler for mouse messages */ VOID MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - int x, y; + int x, y, menuNr; POINT pt; static int recursive = 0; HMENU hmenu; -// BOOLEAN needsRedraw = FALSE; - BOOLEAN saveAnimate; BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */ - static BOOLEAN sameAgain = FALSE, promotionChoice = FALSE; - ChessMove moveType; if (recursive) { if (message == WM_MBUTTONUP) { @@ -4920,8 +4151,8 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); - x = EventToSquare(pt.x - boardRect.left); - y = EventToSquare(pt.y - boardRect.top); + x = EventToSquare(pt.x - boardRect.left, BOARD_WIDTH); + y = EventToSquare(pt.y - boardRect.top, BOARD_HEIGHT); if (!flipView && y >= 0) { y = BOARD_HEIGHT - 1 - y; } @@ -4929,252 +4160,41 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) x = BOARD_WIDTH - 1 - x; } + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status + switch (message) { case WM_LBUTTONDOWN: - if(promotionChoice) { // we are waiting for a click to indicate promotion piece - promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel - if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y); - if(gameInfo.holdingsWidth && - (WhiteOnMove(currentMove) - ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0 - : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) { - // click in right holdings, for determining promotion piece - ChessSquare p = boards[currentMove][y][x]; - if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p); - if(p != EmptySquare) { - FinishMove(WhitePromotionQueen, fromX, fromY, toX, toY, ToLower(PieceToChar(p))); - fromX = fromY = -1; - break; - } - } - DrawPosition(FALSE, boards[currentMove]); - break; - } - ErrorPopDown(); - sameAgain = FALSE; - if (y == -2) { - /* Downclick vertically off board; check if on clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditPosition) { - SetWhiteToPlayEvent(); - } else if (gameMode == IcsPlayingBlack || - gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } else if (gameMode == EditGame) { - AdjustClock(flipClock, -1); - } + ClockClick(flipClock); break; } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditPosition) { - SetBlackToPlayEvent(); - } else if (gameMode == IcsPlayingWhite || - gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } else if (gameMode == EditGame) { - AdjustClock(!flipClock, -1); - } - } - if (!appData.highlightLastMove) { - ClearHighlights(); - DrawPosition((int) (forceFullRepaint || FALSE), NULL); + ClockClick(!flipClock); break; } - fromX = fromY = -1; dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; - break; - } else if (x < 0 || y < 0 - /* [HGM] block clicks between board and holdings */ - || x == BOARD_LEFT-1 || x == BOARD_RGHT - || (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize) - || (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) - /* EditPosition, empty square, or different color piece; - click-click move is possible */ - ) { - break; - } else if (fromX == x && fromY == y) { - /* Downclick on same square again */ - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - sameAgain = TRUE; - } else if (fromX != -1 && - x != BOARD_LEFT-2 && x != BOARD_RGHT+1 - ) { - /* Downclick on different square. */ - /* [HGM] if on holdings file, should count as new first click ! */ - /* [HGM] now always do UserMoveTest(), and check colors there */ - toX = x; - toY = y; - /* [HGM] UserMoveEvent requires two calls now, - to make sure move is legal before showing promotion popup */ - moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, FALSE); - if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ + if(fromX == -1 && frozen) { // not sure where this is for fromX = fromY = -1; - ClearHighlights(); - DrawPosition(FALSE, boards[currentMove]); - break; - } else - if(moveType != ImpossibleMove && moveType != Comment) { - /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */ - if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || - ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && - appData.alwaysPromoteToQueen)) { - FinishMove(moveType, fromX, fromY, toX, toY, 'q'); - if (!appData.highlightLastMove) { - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - } - } else - if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { - SetHighlights(fromX, fromY, toX, toY); - DrawPosition(forceFullRepaint || FALSE, NULL); - /* [HGM] Popup calls FinishMove now. - If promotion to Q is legal, all are legal! */ - if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) - { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; - // kludge to temporarily execute move on display, without promoting yet - promotionChoice = TRUE; - boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank - boards[currentMove][toY][toX] = p; - DrawPosition(FALSE, boards[currentMove]); - boards[currentMove][fromY][fromX] = p; // take back, but display stays - boards[currentMove][toY][toX] = q; - DisplayMessage("Select piece from holdings", ""); - } else - PromotionPopup(hwnd); - goto noClear; - } else { // not a promotion. Move can be illegal if testLegality off, and should be made then. - if (appData.animate || appData.highlightLastMove) { - SetHighlights(fromX, fromY, toX, toY); - } else { - ClearHighlights(); - } - FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); - if (appData.animate && !appData.highlightLastMove) { - ClearHighlights(); - DrawPosition(forceFullRepaint || FALSE, NULL); - } - } - fromX = fromY = -1; - noClear: - break; - } - if (gotPremove && moveType != Comment) { - SetPremoveHighlights(fromX, fromY, toX, toY); -// DrawPosition(forceFullRepaint || FALSE, NULL); - } else ClearHighlights(); - fromX = fromY = -1; - DrawPosition(forceFullRepaint || FALSE, NULL); - if(moveType != Comment) break; - } - /* First downclick, or restart on a square with same color piece */ - if (!frozen && OKToStartUserMove(x, y)) { - fromX = x; - fromY = y; - dragInfo.lastpos = pt; - dragInfo.from.x = fromX; - dragInfo.from.y = fromY; - dragInfo.start = dragInfo.from; - SetCapture(hwndMain); - } else { - fromX = fromY = -1; - dragInfo.start.x = dragInfo.start.y = -1; - dragInfo.from = dragInfo.start; DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */ + break; } + LeftClick(Press, pt.x - boardRect.left, pt.y - boardRect.top); + DrawPosition(TRUE, NULL); break; case WM_LBUTTONUP: - ReleaseCapture(); - if (fromX == -1) break; - if (x == fromX && y == fromY) { - dragInfo.from.x = dragInfo.from.y = -1; - /* Upclick on same square */ - if (sameAgain) { - /* Clicked same square twice: abort click-click move */ - fromX = fromY = -1; - gotPremove = 0; - ClearPremoveHighlights(); - } else { - /* First square clicked: start click-click move */ - SetHighlights(fromX, fromY, -1, -1); - } - DrawPosition(forceFullRepaint || FALSE, NULL); - } else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) { - /* Errant click; ignore */ - break; - } else { - /* Finish drag move. */ - if (appData.debugMode) { - fprintf(debugFP, "release\n"); - } - dragInfo.from.x = dragInfo.from.y = -1; - toX = x; - toY = y; - saveAnimate = appData.animate; /* sorry, Hawk :) */ - appData.animate = appData.animate && !appData.animateDragging; - moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, TRUE); - if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ - fromX = fromY = -1; - ClearHighlights(); - DrawPosition(FALSE, boards[currentMove]); - appData.animate = saveAnimate; - break; - } else - if(moveType != ImpossibleMove) { - /* [HGM] use move type to determine if move is promotion. - Knight is Shogi kludge for mandatory promotion, Queen means choice */ - if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || - ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && - appData.alwaysPromoteToQueen)) - FinishMove(moveType, fromX, fromY, toX, toY, 'q'); - else - if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { - DrawPosition(forceFullRepaint || FALSE, NULL); - if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) - { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; - // kludge to temporarily execute move on display, wthout promotng yet - promotionChoice = TRUE; - boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank - boards[currentMove][toY][toX] = p; - DrawPosition(FALSE, boards[currentMove]); - boards[currentMove][fromY][fromX] = p; // take back, but display stays - boards[currentMove][toY][toX] = q; - appData.animate = saveAnimate; - DisplayMessage("Select piece from holdings", ""); - break; - } else - PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */ - } else { - if(saveAnimate /* ^$!%@#$!$ */ && gameInfo.variant == VariantAtomic - && (boards[currentMove][toY][toX] != EmptySquare || - moveType == WhiteCapturesEnPassant || - moveType == BlackCapturesEnPassant ) ) - AnimateAtomicCapture(fromX, fromY, toX, toY, 20); - FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); - } - } - if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY); - appData.animate = saveAnimate; - fromX = fromY = -1; - if (appData.highlightDragging && !appData.highlightLastMove) { - ClearHighlights(); - } - if (appData.animate || appData.animateDragging || - appData.highlightDragging || gotPremove) { - DrawPosition(forceFullRepaint || FALSE, NULL); - } - } - dragInfo.start.x = dragInfo.start.y = -1; - dragInfo.pos = dragInfo.lastpos = dragInfo.start; + LeftClick(Release, pt.x - boardRect.left, pt.y - boardRect.top); + DrawPosition(TRUE, NULL); break; case WM_MOUSEMOVE: + if(SeekGraphClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, 1)) break; + if(PromoScroll(pt.x - boardRect.left, pt.y - boardRect.top)) break; + MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top); if ((appData.animateDragging || appData.highlightDragging) && (wParam & MK_LBUTTON) && dragInfo.from.x >= 0) { BOOL full_repaint = FALSE; - sameAgain = FALSE; /* [HGM] if we drag something around, do keep square selected */ if (appData.animateDragging) { dragInfo.pos = pt; } @@ -5196,16 +4216,22 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Mouse Wheel is being rolled forward * Play moves forward */ - if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove) + if((short)HIWORD(wParam) < 0 && currentMove < forwardMostMove) { if(lastDir == 1) ForwardEvent(); else lastDir = 1; } // [HGM] suppress first event in direction /* Mouse Wheel is being rolled backward * Play moves backward */ - if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove) + if((short)HIWORD(wParam) > 0 && currentMove > backwardMostMove) { if(lastDir == -1) BackwardEvent(); else lastDir = -1; } } break; + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); + RightClick(Release, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY); + break; + case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: ErrorPopDown(); @@ -5221,19 +4247,17 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(y == -2) { /* [HGM] right mouse button in clock area edit-game mode ups clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditGame) AdjustClock(flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame) AdjustClock(!flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); } + break; } DrawPosition(TRUE, NULL); - switch (gameMode) { - case EditPosition: - case IcsExamining: - if (x < 0 || y < 0) break; - fromX = x; - fromY = y; + menuNr = RightClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY); + switch (menuNr) { + case 0: if (message == WM_MBUTTONDOWN) { buttonCount = 3; /* even if system didn't think so */ if (wParam & MK_SHIFT) @@ -5250,21 +4274,13 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1); } break; - case IcsPlayingWhite: - case IcsPlayingBlack: - case EditGame: - case MachinePlaysWhite: - case MachinePlaysBlack: - if (appData.testLegality && - gameInfo.variant != VariantBughouse && - gameInfo.variant != VariantCrazyhouse) break; - if (x < 0 || y < 0) break; - fromX = x; - fromY = y; + case 2: + SetCapture(hwndMain); + break; + case 1: hmenu = LoadMenu(hInst, "DropPieceMenu"); SetupDropMenu(hmenu); MenuPopup(hwnd, pt, hmenu, -1); - break; default: break; } @@ -5278,7 +4294,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK ButtonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - int id = GetWindowLong(hwnd, GWL_ID); + int id = GetWindowLongPtr(hwnd, GWLP_ID); int i, dir; for (i=0; i= 'A' && + ((PieceToChar(WhiteAngel) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteAngel) != '~') || - (PieceToChar(BlackAngel) >= 'A' && + (PieceToChar(BlackAngel) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackAngel) != '~') ) ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, PB_Chancellor), - ((PieceToChar(WhiteMarshall) >= 'A' && + ((PieceToChar(WhiteMarshall) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteMarshall) != '~') || - (PieceToChar(BlackMarshall) >= 'A' && + (PieceToChar(BlackMarshall) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackMarshall) != '~') ) ? SW_SHOW : SW_HIDE); /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */ @@ -5352,12 +4370,11 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) ShowWindow(GetDlgItem(hDlg, PB_Bishop), gameInfo.variant != VariantShogi ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_Yes), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_No), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); + if(gameInfo.variant == VariantShogi) { + SetDlgItemText(hDlg, PB_Queen, "YES"); + SetDlgItemText(hDlg, PB_Knight, "NO"); + SetWindowText(hDlg, "Promote?"); + } ShowWindow(GetDlgItem(hDlg, IDC_Centaur), gameInfo.variant == VariantSuper ? SW_SHOW : SW_HIDE); @@ -5374,32 +4391,32 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing); break; case PB_Queen: - promoChar = gameInfo.variant == VariantShogi ? '+' : PieceToChar(BlackQueen); + promoChar = gameInfo.variant == VariantShogi ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen)); break; case PB_Rook: - promoChar = PieceToChar(BlackRook); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteRook : BlackRook)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackDragon); break; case PB_Bishop: - promoChar = PieceToChar(BlackBishop); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteBishop : BlackBishop)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackAlfil); break; case PB_Chancellor: - promoChar = PieceToChar(BlackMarshall); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteMarshall : BlackMarshall)); break; case PB_Archbishop: - promoChar = PieceToChar(BlackAngel); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteAngel : BlackAngel)); break; case PB_Knight: - promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(BlackKnight); + promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight); break; default: return FALSE; } + if(promoChar == '.') return FALSE; // invalid piece chosen EndDialog(hDlg, TRUE); /* Exit the dialog */ - /* [HGM] Call FinishMove rather than UserMoveEvent, as we - only show the popup when we are already sure the move is valid or - legal. We pass a faulty move type, but the kludge is that FinishMove - will figure out it is a promotion from the promoChar. */ - FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar); + UserMoveEvent(fromX, fromY, toX, toY, promoChar); + fromX = fromY = -1; if (!appData.highlightLastMove) { ClearHighlights(); DrawPosition(FALSE, NULL); @@ -5421,6 +4438,13 @@ PromotionPopup(HWND hwnd) FreeProcInstance(lpProc); } +void +PromotionPopUp() +{ + DrawPosition(TRUE, NULL); + PromotionPopup(hwndMain); +} + /* Toggle ShowThinking */ VOID ToggleShowThinking() @@ -5444,7 +4468,7 @@ LoadGameDialog(HWND hwnd, char* title) if (number == 0) { int error = GameListBuild(f); if (error) { - DisplayError("Cannot build game list", error); + DisplayError(_("Cannot build game list"), error); } else if (!ListEmpty(&gameList) && ((ListGame *) gameList.tailPred)->number > 1) { GameListPopUp(f, fileTitle); @@ -5457,34 +4481,55 @@ LoadGameDialog(HWND hwnd, char* title) } } +int get_term_width() +{ + HDC hdc; + TEXTMETRIC tm; + RECT rc; + HFONT hfont, hold_font; + LOGFONT lf; + HWND hText; + + if (hwndConsole) + hText = GetDlgItem(hwndConsole, OPT_ConsoleText); + else + return 79; + + // get the text metrics + hdc = GetDC(hText); + lf = font[boardSize][CONSOLE_FONT]->lf; + if (consoleCF.dwEffects & CFE_BOLD) + lf.lfWeight = FW_BOLD; + if (consoleCF.dwEffects & CFE_ITALIC) + lf.lfItalic = TRUE; + if (consoleCF.dwEffects & CFE_STRIKEOUT) + lf.lfStrikeOut = TRUE; + if (consoleCF.dwEffects & CFE_UNDERLINE) + lf.lfUnderline = TRUE; + hfont = CreateFontIndirect(&lf); + hold_font = SelectObject(hdc, hfont); + GetTextMetrics(hdc, &tm); + SelectObject(hdc, hold_font); + DeleteObject(hfont); + ReleaseDC(hText, hdc); + + // get the rectangle + SendMessage(hText, EM_GETRECT, 0, (LPARAM)&rc); + + return (rc.right-rc.left) / tm.tmAveCharWidth; +} + void UpdateICSWidth(HWND hText) { - HDC hdc; - TEXTMETRIC tm; - RECT rc; - HFONT hfont, hold_font; - LONG old_width, new_width; - - // get the text metrics - hdc = GetDC(hText); - hfont = CreateFontIndirect(&font[boardSize][CONSOLE_FONT]->lf); - hold_font = SelectObject(hdc, hfont); - GetTextMetrics(hdc, &tm); - SelectObject(hdc, hold_font); - DeleteObject(hfont); - ReleaseDC(hText, hdc); - - // get the rectangle - SendMessage(hText, EM_GETRECT, 0, (LPARAM)&rc); - - // update the width - new_width = (rc.right-rc.left) / tm.tmAveCharWidth; - old_width = GetWindowLong(hText, GWL_USERDATA); - if (new_width != old_width) - { - ics_update_width(new_width); - SetWindowLong(hText, GWL_USERDATA, new_width); - } + LONG old_width, new_width; + + new_width = get_term_width(hText, FALSE); + old_width = GetWindowLongPtr(hText, GWLP_USERDATA); + if (new_width != old_width) + { + ics_update_width(new_width); + SetWindowLongPtr(hText, GWLP_USERDATA, new_width); + } } VOID @@ -5499,7 +4544,8 @@ ChangedConsoleFont() cfmt.cbSize = sizeof(CHARFORMAT); cfmt.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET; - strcpy(cfmt.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName); + safeStrCpy(cfmt.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName, + sizeof(cfmt.szFaceName)/sizeof(cfmt.szFaceName[0]) ); /* yHeight is expressed in twips. A twip is 1/20 of a font's point * size. This was undocumented in the version of MSVC++ that I had * when I wrote the code, but is apparently documented now. @@ -5547,6 +4593,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) char fileTitle[MSG_SIZ]; char buf[MSG_SIZ]; static SnapData sd; + static int peek=0; switch (message) { @@ -5574,13 +4621,29 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MouseEvent(hwnd, message, wParam, lParam); break; - JAWS_KB_NAVIGATION + case WM_KEYUP: + if((char)wParam == '\b') { + ForwardEvent(); peek = 0; + } + + JAWS_KBUP_NAVIGATION + + break; + + case WM_KEYDOWN: + if((char)wParam == '\b') { + if(!peek) BackwardEvent(), peek = 1; + } + + JAWS_KBDOWN_NAVIGATION + + break; case WM_CHAR: JAWS_ALT_INTERCEPT - if (appData.icsActive && (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9')) { + if (appData.icsActive && ((char)wParam == '\r' || (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9'))) { // [HGM] movenum: for non-zero digits we always do type-in dialog HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput); if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE); @@ -5588,7 +4651,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(h, message, wParam, lParam); } else if(lParam != KF_REPEAT) { if (isalpha((char)wParam) || isdigit((char)wParam)) { - PopUpMoveDialog((char)wParam); + TypeInEvent((char)wParam); } else if((char)wParam == 003) CopyGameToClipboard(); else if((char)wParam == 026) PasteGameOrFENFromClipboard(); } @@ -5631,14 +4694,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wmId) { case IDM_NewGame: ResetGameEvent(); - EngineOutputPopDown(); SAY("new game enter a move to play against the computer with white"); break; case IDM_NewGameFRC: if( NewGameFRC() == 0 ) { ResetGameEvent(); - EngineOutputPopDown(); } break; @@ -5647,7 +4708,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_LoadGame: - LoadGameDialog(hwnd, "Load Game from File"); + LoadGameDialog(hwnd, _("Load Game from File")); break; case IDM_LoadNextGame: @@ -5670,7 +4731,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "rb", "", appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Load Position from File", &number, fileTitle, NULL); + _("Load Position from File"), &number, fileTitle, NULL); if (f != NULL) { LoadPosition(f, number, fileTitle); } @@ -5693,7 +4754,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); } @@ -5704,7 +4765,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Save Position to File", NULL, fileTitle, NULL); + _("Save Position to File"), NULL, fileTitle, NULL); if (f != NULL) { SavePosition(f, 0, ""); } @@ -5715,7 +4776,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "wb", defName, "bmp", DIAGRAM_FILT, - "Save Diagram to File", NULL, fileTitle, NULL); + _("Save Diagram to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveDiagram(f); } @@ -5788,7 +4849,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_NewChat: - ChatPopUp(); + ChatPopUp(NULL); break; case IDM_CopyPosition: @@ -5844,6 +4905,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SAY("computer starts playing black"); break; + case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games + MatchEvent(2); // distinguish from command-line-triggered case (matchMode=1) + break; + case IDM_TwoMachines: TwoMachinesEvent(); /* @@ -5855,19 +4920,19 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } - SAY("programs start playing each other"); + SAY("computer starts playing both sides"); break; case IDM_AnalysisMode: if (!first.analysisSupport) { - sprintf(buf, "%s does not support analysis", first.tidy); + snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { SAY("analyzing current position"); /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */ if (appData.icsActive) { if (gameMode != IcsObserving) { - sprintf(buf, "You are not observing a game"); + snprintf(buf, MSG_SIZ, "You are not observing a game"); DisplayError(buf, 0); /* secure check */ if (appData.icsEngineAnalyze) { @@ -5897,12 +4962,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_AnalyzeFile: if (!first.analysisSupport) { char buf[MSG_SIZ]; - sprintf(buf, "%s does not support analysis", first.tidy); + snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { if (!appData.showThinking) ToggleShowThinking(); AnalyzeFileEvent(); - LoadGameDialog(hwnd, "Analyze Game from File"); +// LoadGameDialog(hwnd, _("Analyze Game from File")); AnalysisPeriodicEvent(1); } break; @@ -5912,13 +4977,15 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_EditGame: + case IDM_EditGame2: EditGameEvent(); SAY("edit game"); break; case IDM_EditPosition: + case IDM_EditPosition2: EditPositionEvent(); - SAY("to set up a position type a FEN"); + SAY("enter a FEN string or setup a position on the board using the control R pop up menu"); break; case IDM_Training: @@ -5929,12 +4996,34 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ShowGameListProc(); break; + case IDM_EditProgs1: + EditTagsPopUp(firstChessProgramNames, &firstChessProgramNames); + break; + + case IDM_LoadProg1: + LoadEnginePopUp(hwndMain, 0); + break; + + case IDM_LoadProg2: + LoadEnginePopUp(hwndMain, 1); + break; + + case IDM_EditServers: + EditTagsPopUp(icsNames, &icsNames); + break; + case IDM_EditTags: + case IDM_Tags: EditTagsProc(); break; + case IDM_EditBook: + EditBookEvent(); + break; + case IDM_EditComment: - if (commentDialogUp && editComment) { + case IDM_Comment: + if (commentUp && editComment) { CommentPopDown(); } else { EditCommentEvent(); @@ -5985,8 +5074,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) StopExaminingEvent(); break; + case IDM_Upload: + UploadGameEvent(); + break; + case IDM_TypeInMove: - PopUpMoveDialog('\000'); + TypeInEvent('\000'); break; case IDM_TypeInName: @@ -6015,8 +5108,17 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetFocus(hwndMain); break; + case OPT_GameListNext: // [HGM] forward these two accelerators to Game List + case OPT_GameListPrev: + if(gameListDialog) SendMessage(gameListDialog, WM_COMMAND, wmId, 0); + break; + case IDM_Revert: - RevertEvent(); + RevertEvent(FALSE); + break; + + case IDM_Annotate: // [HGM] vari: revert with annotation + RevertEvent(TRUE); break; case IDM_TruncateGame: @@ -6039,7 +5141,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FlipClock: flipClock = !flipClock; DisplayBothClocks(); - DrawPosition(FALSE, NULL); + DisplayLogos(); break; case IDM_MuteSounds: @@ -6066,6 +5168,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Engine2Options: + savedHwnd = hwnd; + if(WaitForEngine(&second, SettingsMenuIfReady)) break; EngineOptionsPopup(hwnd, &second); break; @@ -6073,6 +5177,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) UciOptionsPopup(hwnd); break; + case IDM_Tourney: + TourneyPopup(hwnd); + break; + case IDM_IcsOptions: IcsOptionsPopup(hwnd); break; @@ -6143,7 +5251,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -6152,7 +5260,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -6160,7 +5268,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPHELP: if(!WinHelp(hwnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -6174,12 +5282,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_DirectCommand1: - AskQuestionEvent("Direct Command", - "Send to chess program:", "", "1"); + AskQuestionEvent(_("Direct Command"), + _("Send to chess program:"), "", "1"); break; case IDM_DirectCommand2: - AskQuestionEvent("Direct Command", - "Send to second chess program:", "", "2"); + AskQuestionEvent(_("Direct Command"), + _("Send to second chess program:"), "", "2"); break; case EP_WhitePawn: @@ -6357,7 +5465,26 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) fromX = fromY = -1; break; + case IDM_English: + barbaric = 0; appData.language = ""; + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_English, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + default: + if(wmId >= IDM_RecentEngines && wmId < IDM_RecentEngines + appData.recentEngines) + RecentEngineEvent(wmId - IDM_RecentEngines); + else + if(wmId > IDM_English && wmId < IDM_English+20) { + LoadLanguageFile(languageFile[wmId - IDM_English - 1]); + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), wmId, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + } return (DefWindowProc(hwnd, message, wParam, lParam)); } break; @@ -6406,18 +5533,18 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) RECT rcMain; // GetWindowRect( hwnd, &rcMain ); //[HGM] sticky: in XP this returned new position, not old - rcMain.left = boardX; // replace by these 4 lines to reconstruct old rect - rcMain.right = boardX + winWidth; - rcMain.top = boardY; - rcMain.bottom = boardY + winHeight; + rcMain.left = wpMain.x; // replace by these 4 lines to reconstruct old rect + rcMain.right = wpMain.x + wpMain.width; + rcMain.top = wpMain.y; + rcMain.bottom = wpMain.y + wpMain.height; ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole ); - boardX = lpwp->x; - boardY = lpwp->y; + wpMain.x = lpwp->x; + wpMain.y = lpwp->y; } } break; @@ -6558,7 +5685,7 @@ MyLoadSound(MySound *ms) struct stat st; FILE *f; - if (ms->data) free(ms->data); + if (ms->data && ms->flag) free(ms->data); ms->data = NULL; switch (ms->name[0]) { @@ -6579,6 +5706,7 @@ MyLoadSound(MySound *ms) HANDLE h = FindResource(hInst, ms->name + 1, "WAVE"); if (h == NULL) break; ms->data = (void *)LoadResource(hInst, h); + ms->flag = 0; // not maloced, so cannot be freed! if (h == NULL) break; ok = TRUE; } @@ -6589,6 +5717,7 @@ MyLoadSound(MySound *ms) if (f == NULL) break; if (fstat(fileno(f), &st) < 0) break; ms->data = malloc(st.st_size); + ms->flag = 1; if (fread(ms->data, st.st_size, 1, f) < 1) break; fclose(f); ok = TRUE; @@ -6596,7 +5725,7 @@ MyLoadSound(MySound *ms) } if (!ok) { char buf[MSG_SIZ]; - sprintf(buf, "Error loading sound %s", ms->name); + snprintf(buf, MSG_SIZ, _("Error loading sound %s"), ms->name); DisplayError(buf, GetLastError()); } return ok; @@ -6662,6 +5791,7 @@ OldOpenFileHook(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) number = NULL; } CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + Translate(hDlg, 1536); return FALSE; /* Allow for further processing */ case WM_COMMAND: @@ -6681,6 +5811,7 @@ OpenFileHook(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) OFNOTIFY *ofnot; switch (uiMsg) { case WM_INITDIALOG: + Translate(hdlg, DLG_IndexNumber); ofname = (OPENFILENAME *)lParam; number = (UINT *)(ofname->lCustData); break; @@ -6706,12 +5837,12 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia if (fileName == NULL) fileName = buf1; if (defName == NULL) { - strcpy(fileName, "*."); + safeStrCpy(fileName, "*.", 3 ); strcat(fileName, defExt); } else { - strcpy(fileName, defName); + safeStrCpy(fileName, defName, MSG_SIZ ); } - if (fileTitle) strcpy(fileTitle, ""); + if (fileTitle) safeStrCpy(fileTitle, "", MSG_SIZ ); if (number) *number = 0; openFileName.lStructSize = sizeof(OPENFILENAME); @@ -6744,13 +5875,13 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia /* open the file */ f = fopen(openFileName.lpstrFile, write); if (f == NULL) { - MessageBox(hwnd, "File open failed", NULL, + MessageBox(hwnd, _("File open failed"), NULL, MB_OK|MB_ICONEXCLAMATION); return NULL; } } else { int err = CommDlgExtendedError(); - if (err != 0) DisplayError("Internal error in file dialog box", err); + if (err != 0) DisplayError(_("Internal error in file dialog box"), err); return FALSE; } return f; @@ -6768,6 +5899,7 @@ MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def) * menu that TrackPopupMenu displays. */ hmenuTrackPopup = GetSubMenu(hmenu, 0); + TranslateOneMenu(10, hmenuTrackPopup); SetMenuDefaultItem(hmenuTrackPopup, def, FALSE); @@ -6910,7 +6042,7 @@ InitComboStrings(HANDLE hwndCombo, char **cd) SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0); while (*cd != NULL) { - SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) *cd); + SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) T_(*cd)); cd++; } } @@ -6918,7 +6050,7 @@ InitComboStrings(HANDLE hwndCombo, char **cd) void InitComboStringsFromOption(HANDLE hwndCombo, char *str) { - char buf1[ARG_MAX]; + char buf1[MAX_ARG_LEN]; int len; if (str[0] == '@') { @@ -6989,10 +6121,10 @@ InitEngineBox(HWND hDlg, HWND hwndCombo, char* nthcp, char* nthd, char* nthdir, InitComboStringsFromOption(hwndCombo, nthnames); q = QuoteForFilename(nthcp); - sprintf(buf, "%s%s%s", q, nthcp, q); + snprintf(buf, MSG_SIZ, "%s%s%s", q, nthcp, q); if (*nthdir != NULLCHAR) { q = QuoteForFilename(nthdir); - sprintf(buf + strlen(buf), " /%s=%s%s%s", nthd, q, nthdir, q); + snprintf(buf + strlen(buf), MSG_SIZ, " /%s=%s%s%s", nthd, q, nthdir, q); } if (*nthcp == NULLCHAR) { SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0); @@ -7013,16 +6145,17 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: /* Center the dialog */ CenterWindow (hDlg, GetDesktopWindow()); + Translate(hDlg, DLG_Startup); /* Initialize the dialog items */ InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_ChessEngineName), appData.firstChessProgram, "fd", appData.firstDirectory, firstChessProgramNames); InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_SecondChessEngineName), - appData.secondChessProgram, "sd", appData.secondDirectory, - secondChessProgramNames); + appData.secondChessProgram, singleList ? "fd" : "sd", appData.secondDirectory, + singleList ? firstChessProgramNames : secondChessProgramNames); //[HGM] single: use first list in second combo hwndCombo = GetDlgItem(hDlg, OPT_ChessServerName); InitComboStringsFromOption(hwndCombo, icsNames); - sprintf(buf, "%s /icsport=%s", appData.icsHost, appData.icsPort); + snprintf(buf, MSG_SIZ, "%s /icsport=%s", appData.icsHost, appData.icsPort); if (*appData.icsHelper != NULLCHAR) { char *q = QuoteForFilename(appData.icsHelper); sprintf(buf + strlen(buf), " /icshelper=%s%s%s", q, appData.icsHelper, q); @@ -7052,23 +6185,26 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam)) { case IDOK: if (IsDlgButtonChecked(hDlg, OPT_ChessEngine)) { - strcpy(buf, "/fcp="); + safeStrCpy(buf, "/fcp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; + comboLine = strdup(p+5); // [HGM] recent: remember complete line of first combobox ParseArgs(StringGet, &p); - strcpy(buf, "/scp="); + safeStrCpy(buf, singleList ? "/fcp=" : "/scp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; + SwapEngines(singleList); // temporarily swap first and second, to load a second 'first', ... ParseArgs(StringGet, &p); + SwapEngines(singleList); // ... and then make it 'second' appData.noChessProgram = FALSE; appData.icsActive = FALSE; } else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) { - strcpy(buf, "/ics /icshost="); + safeStrCpy(buf, "/ics /icshost=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; ParseArgs(StringGet, &p); if (appData.zippyPlay) { - strcpy(buf, "/fcp="); + safeStrCpy(buf, "/fcp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; ParseArgs(StringGet, &p); @@ -7077,8 +6213,8 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) appData.noChessProgram = TRUE; appData.icsActive = FALSE; } else { - MessageBox(hDlg, "Choose an option, or cancel to exit", - "Option Error", MB_OK|MB_ICONEXCLAMATION); + MessageBox(hDlg, _("Choose an option, or cancel to exit"), + _("Option Error"), MB_OK|MB_ICONEXCLAMATION); return TRUE; } if (IsDlgButtonChecked(hDlg, OPT_AnyAdditional)) { @@ -7096,7 +6232,7 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPCONTENTS: if (!WinHelp (hDlg, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -7125,6 +6261,7 @@ About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) /* Center the dialog over the application window */ CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); SetDlgItemText(hDlg, ABOUTBOX_Version, programVersion); + Translate(hDlg, ABOUTBOX); JAWS_COPYRIGHT return (TRUE); @@ -7158,6 +6295,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INITDIALOG: /* message: initialize dialog box */ /* Initialize the dialog items */ + Translate(hDlg, DLG_EditComment); hwndText = GetDlgItem(hDlg, OPT_CommentText); SetDlgItemText(hDlg, OPT_CommentText, commentText); EnableWindow(GetDlgItem(hDlg, OPT_CancelComment), editComment); @@ -7180,18 +6318,18 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetClientRect(hDlg, &rect); sizeX = rect.right; sizeY = rect.bottom; - if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT && - commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) { + if (wpComment.x != CW_USEDEFAULT && wpComment.y != CW_USEDEFAULT && + wpComment.width != CW_USEDEFAULT && wpComment.height != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&commentX, &commentY, 0, 0); + EnsureOnScreen(&wpComment.x, &wpComment.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = commentX; - wp.rcNormalPosition.right = commentX + commentW; - wp.rcNormalPosition.top = commentY; - wp.rcNormalPosition.bottom = commentY + commentH; + wp.rcNormalPosition.left = wpComment.x; + wp.rcNormalPosition.right = wpComment.x + wpComment.width; + wp.rcNormalPosition.top = wpComment.y; + wp.rcNormalPosition.bottom = wpComment.y + wpComment.height; SetWindowPlacement(hDlg, &wp); GetClientRect(hDlg, &rect); @@ -7203,6 +6341,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) sizeY = newSizeY; } } + SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS ); return FALSE; case WM_COMMAND: /* message: received a command */ @@ -7247,6 +6386,42 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } break; + case WM_NOTIFY: // [HGM] vari: cloned from whistory.c + if( wParam == OPT_CommentText ) { + MSGFILTER * lpMF = (MSGFILTER *) lParam; + + if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 || + lpMF->msg == WM_CHAR && lpMF->wParam == '\022' ) { + POINTL pt; + LRESULT index; + + pt.x = LOWORD( lpMF->lParam ); + pt.y = HIWORD( lpMF->lParam ); + + if(lpMF->msg == WM_CHAR) { + CHARRANGE sel; + SendDlgItemMessage( hDlg, OPT_CommentText, EM_EXGETSEL, 0, (LPARAM) &sel ); + index = sel.cpMin; + } else + index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt ); + + hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above + len = GetWindowTextLength(hwndText); + str = (char *) malloc(len + 1); + GetWindowText(hwndText, str, len + 1); + ReplaceComment(commentIndex, str); + if(commentIndex != currentMove) ToNrEvent(commentIndex); + LoadVariation( index, str ); // [HGM] also does the actual moving to it, now + free(str); + + /* Zap the message for good: apparently, returning non-zero is not enough */ + lpMF->msg = WM_USER; + + return TRUE; + } + } + break; + case WM_SIZE: newSizeX = LOWORD(lParam); newSizeY = HIWORD(lParam); @@ -7271,7 +6446,7 @@ EitherCommentPopUp(int index, char *title, char *str, BOOLEAN edit) FARPROC lpProc; char *p, *q; - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, edit ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, edit ? MF_CHECKED : MF_UNCHECKED); if (str == NULL) str = ""; p = (char *) malloc(2 * strlen(str) + 2); @@ -7290,14 +6465,14 @@ EitherCommentPopUp(int index, char *title, char *str, BOOLEAN edit) if (commentDialog) { SendMessage(commentDialog, WM_INITDIALOG, 0, 0); - if (!commentDialogUp) ShowWindow(commentDialog, SW_SHOW); + if (!commentUp) ShowWindow(commentDialog, SW_SHOW); } else { lpProc = MakeProcInstance((FARPROC)CommentDialog, hInst); CreateDialog(hInst, MAKEINTRESOURCE(DLG_EditComment), hwndMain, (DLGPROC)lpProc); FreeProcInstance(lpProc); } - commentDialogUp = TRUE; + commentUp = TRUE; } @@ -7312,15 +6487,13 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char move[MSG_SIZ]; HWND hInput; - ChessMove moveType; - int fromX, fromY, toX, toY; - char promoChar; switch (message) { case WM_INITDIALOG: move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInMove); hInput = GetDlgItem(hDlg, OPT_Move); SetWindowText(hInput, move); SetFocus(hInput); @@ -7330,43 +6503,10 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: + + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); - { int n; Board board; - // [HGM] FENedit - if(gameMode == EditPosition && ParseFEN(board, &n, move) ) { - EditPositionPasteFEN(move); - EndDialog(hDlg, TRUE); - return TRUE; - } - // [HGM] movenum: allow move number to be typed in any mode - if(sscanf(move, "%d", &n) == 1 && n != 0 ) { - currentMove = 2*n-1; - if(currentMove > forwardMostMove) currentMove = forwardMostMove; - if(currentMove < backwardMostMove) currentMove = backwardMostMove; - EndDialog(hDlg, TRUE); - DrawPosition(TRUE, boards[currentMove]); - if(currentMove > backwardMostMove) DisplayMove(currentMove - 1); - else DisplayMessage("", ""); - return TRUE; - } - } - if (gameMode != EditGame && currentMove != forwardMostMove && - gameMode != Training) { - DisplayMoveError("Displayed move is not current"); - } else { -// GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream - int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, - &moveType, &fromX, &fromY, &toX, &toY, &promoChar); - if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized - if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, - &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) { - if (gameMode != Training) - forwardMostMove = currentMove; - UserMoveEvent(fromX, fromY, toX, toY, promoChar); - } else { - DisplayMoveError("Could not parse move"); - } - } + TypeInDoneEvent(move); EndDialog(hDlg, TRUE); return TRUE; case IDCANCEL: @@ -7384,21 +6524,11 @@ VOID PopUpMoveDialog(char firstchar) { FARPROC lpProc; - - if ((gameMode == BeginningOfGame && !appData.icsActive) || - gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack || - gameMode == AnalyzeMode || gameMode == EditGame || - gameMode == EditPosition || gameMode == IcsExamining || - gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack || - isdigit(firstchar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes - ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile || - gameMode == IcsObserving || gameMode == TwoMachinesPlay ) || - gameMode == Training) { + lpProc = MakeProcInstance((FARPROC)TypeInMoveDialog, hInst); DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInMove), hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar); FreeProcInstance(lpProc); - } } /*---------------------------------------------------------------------------*\ @@ -7418,6 +6548,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInName); hInput = GetDlgItem(hDlg, OPT_Name); SetWindowText(hInput, move); SetFocus(hInput); @@ -7430,6 +6561,12 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetDlgItemText(hDlg, OPT_Name, move, sizeof(move)); appData.userName = strdup(move); SetUserLogo(); + SetGameInfo(); + if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) { + snprintf(move, MSG_SIZ, "%s vs. %s", gameInfo.white, gameInfo.black); + DisplayTitle(move); + } + EndDialog(hDlg, TRUE); return TRUE; @@ -7508,6 +6645,7 @@ ErrorPopDown() if (errorDialog == NULL) return; DestroyWindow(errorDialog); errorDialog = NULL; + if(errorExitStatus) ExitEvent(errorExitStatus); } LRESULT CALLBACK @@ -7533,6 +6671,7 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) For now, just give it a default position. */ SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE); + Translate(hDlg, DLG_Error); errorDialog = hDlg; SetWindowText(hDlg, errorTitle); @@ -7570,7 +6709,7 @@ GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: GetWindowRect(hDlg, &rChild); - SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height, + SetWindowPos(hDlg, NULL, wpMain.x, wpMain.y-height, wpMain.width, height, SWP_NOZORDER); /* @@ -7670,76 +6809,7 @@ NextInHistory() { if (histP == histIn) return NULL; histP = (histP + 1) % HISTORY_SIZE; - return history[histP]; -} - -typedef struct { - char *item; - char *command; - BOOLEAN getname; - BOOLEAN immediate; -} IcsTextMenuEntry; -#define ICS_TEXT_MENU_SIZE (IDM_CommandXLast - IDM_CommandX + 1) -IcsTextMenuEntry icsTextMenuEntry[ICS_TEXT_MENU_SIZE]; - -void -ParseIcsTextMenu(char *icsTextMenuString) -{ -// int flags = 0; - IcsTextMenuEntry *e = icsTextMenuEntry; - char *p = icsTextMenuString; - while (e->item != NULL && e < icsTextMenuEntry + ICS_TEXT_MENU_SIZE) { - free(e->item); - e->item = NULL; - if (e->command != NULL) { - free(e->command); - e->command = NULL; - } - e++; - } - e = icsTextMenuEntry; - while (*p && e < icsTextMenuEntry + ICS_TEXT_MENU_SIZE) { - if (*p == ';' || *p == '\n') { - e->item = strdup("-"); - e->command = NULL; - p++; - } else if (*p == '-') { - e->item = strdup("-"); - e->command = NULL; - p++; - if (*p) p++; - } else { - char *q, *r, *s, *t; - char c; - q = strchr(p, ','); - if (q == NULL) break; - *q = NULLCHAR; - r = strchr(q + 1, ','); - if (r == NULL) break; - *r = NULLCHAR; - s = strchr(r + 1, ','); - if (s == NULL) break; - *s = NULLCHAR; - c = ';'; - t = strchr(s + 1, c); - if (t == NULL) { - c = '\n'; - t = strchr(s + 1, c); - } - if (t != NULL) *t = NULLCHAR; - e->item = strdup(p); - e->command = strdup(q + 1); - e->getname = *(r + 1) != '0'; - e->immediate = *(s + 1) != '0'; - *q = ','; - *r = ','; - *s = ','; - if (t == NULL) break; - *t = c; - p = t + 1; - } - e++; - } + return history[histP]; } HMENU @@ -7752,13 +6822,14 @@ LoadIcsTextMenu(IcsTextMenuEntry *e) while (e->item) { if (strcmp(e->item, "-") == 0) { AppendMenu(h, MF_SEPARATOR, 0, 0); - } else { + } else { // [HGM] re-written a bit to use only one AppendMenu call for both cases (| or no |) + int flags = MF_STRING, j = 0; if (e->item[0] == '|') { - AppendMenu(h, MF_STRING|MF_MENUBARBREAK, - IDM_CommandX + i, &e->item[1]); - } else { - AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item); + flags |= MF_MENUBARBREAK; + j++; } + if(!strcmp(e->command, "none")) flags |= MF_GRAYED; // [HGM] chatclick: provide inactive dummy + AppendMenu(h, flags, IDM_CommandX + i, e->item + j); } e++; i++; @@ -7823,11 +6894,13 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate) SendMessage(hwnd, EM_GETSELTEXT, 0, (LPARAM) name); } if (immediate) { - sprintf(buf, "%s %s", command, name); + if(strstr(command, "%s")) snprintf(buf, MSG_SIZ, command, name); else + snprintf(buf, MSG_SIZ, "%s %s", command, name); SetWindowText(hInput, buf); SendMessage(hInput, WM_CHAR, '\r', 0); } else { - sprintf(buf, "%s %s ", command, name); /* trailing space */ + if(!strcmp(command, "chat")) { ChatPopUp(name); return; } + snprintf(buf, MSG_SIZ, "%s %s ", command, name); /* trailing space */ SetWindowText(hInput, buf); sel.cpMin = 999999; sel.cpMax = 999999; @@ -7845,6 +6918,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_KEYDOWN: if (!(GetKeyState(VK_CONTROL) & ~1)) break; + if(wParam=='R') return 0; switch (wParam) { case VK_PRIOR: SendMessage(hwnd, EM_LINESCROLL, 0, -999999); @@ -7878,12 +6952,22 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hInput, message, wParam, lParam); } return 0; - } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu - case WM_RBUTTONUP: - if (GetKeyState(VK_SHIFT) & ~1) { - SendDlgItemMessage(hwndConsole, OPT_ConsoleText, - WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); - } else { + } // [HGM] navigate: for Ctrl+R, flow into next case (moved up here) to summon up menu + lParam = -1; + case WM_RBUTTONDOWN: + if (!(GetKeyState(VK_SHIFT) & ~1)) { + /* Move selection here if it was empty */ + POINT pt; + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) { + if(lParam != -1) sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ + sel.cpMax = sel.cpMin; + SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); + } + SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE); +{ // [HGM] chatclick: code moved here from WM_RBUTTONUP case, to have menu appear on down-click POINT pt; HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry); SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); @@ -7894,9 +6978,17 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!IsClipboardFormatAvailable(CF_TEXT)) { EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED); } - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); + pt.x = LOWORD(lParam)-30; // [HGM] chatclick: make menu pop up with pointer above upper-right item + pt.y = HIWORD(lParam)-10; // make it appear as if mouse moved there, so it will be selected on up-click + PostMessage(hwnd, WM_MOUSEMOVE, wParam, lParam+5); MenuPopup(hwnd, pt, hmenu, -1); +} + } + return 0; + case WM_RBUTTONUP: + if (GetKeyState(VK_SHIFT) & ~1) { + SendDlgItemMessage(hwndConsole, OPT_ConsoleText, + WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); } return 0; case WM_PASTE: @@ -7905,21 +6997,6 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return SendMessage(hInput, message, wParam, lParam); case WM_MBUTTONDOWN: return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); - case WM_RBUTTONDOWN: - if (!(GetKeyState(VK_SHIFT) & ~1)) { - /* Move selection here if it was empty */ - POINT pt; - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ - sel.cpMax = sel.cpMin; - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); - } - SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE); - } - return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_QuickPaste: @@ -8162,10 +7239,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) hwndConsole = hDlg; SetFocus(hInput); consoleTextWindowProc = (WNDPROC) - SetWindowLong(hText, GWL_WNDPROC, (LONG) ConsoleTextSubclass); + SetWindowLongPtr(hText, GWLP_WNDPROC, (LONG_PTR) ConsoleTextSubclass); SendMessage(hText, EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor); consoleInputWindowProc = (WNDPROC) - SetWindowLong(hInput, GWL_WNDPROC, (LONG) ConsoleInputSubclass); + SetWindowLongPtr(hInput, GWLP_WNDPROC, (LONG_PTR) ConsoleInputSubclass); SendMessage(hInput, EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor); Colorize(ColorNormal, TRUE); SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &consoleCF); @@ -8191,10 +7268,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) // [HGM] Chessknight's change 2004-07-13 else { /* Determine Defaults */ WINDOWPLACEMENT wp; - wpConsole.x = winWidth + 1; - wpConsole.y = boardY; - wpConsole.width = screenWidth - winWidth; - wpConsole.height = winHeight; + wpConsole.x = wpMain.width + 1; + wpConsole.y = wpMain.y; + wpConsole.width = screenWidth - wpMain.width; + wpConsole.height = wpMain.height; EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; @@ -8208,10 +7285,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } // Allow hText to highlight URLs and send notifications on them - wMask = SendMessage(hText, EM_GETEVENTMASK, 0, 0L); + wMask = (WORD) SendMessage(hText, EM_GETEVENTMASK, 0, 0L); SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK); SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L); - SetWindowLong(hText, GWL_USERDATA, 79); // initialize the text window's width + SetWindowLongPtr(hText, GWLP_USERDATA, 79); // initialize the text window's width return FALSE; @@ -8391,7 +7468,8 @@ DisplayHoldingsCount(HDC hdc, int x, int y, int rightAlign, int copyNumber) HFONT oldFont; RECT rect; - if(copyNumber > 1) sprintf(buf, "%d", copyNumber); else buf[0] = 0; + if(copyNumber > 1) + snprintf(buf, sizeof(buf)/sizeof(buf[0]),"%d", copyNumber); else buf[0] = 0; oldFg = SetTextColor(hdc, RGB(255, 255, 255)); /* white */ oldBg = SetBkColor(hdc, RGB(0, 0, 0)); /* black */ @@ -8422,11 +7500,12 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, COLORREF oldFg, oldBg; HFONT oldFont; + if (twoBoards && partnerUp) return; if (appData.clockMode) { if (tinyLayout) - sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%c %s %s", color[0], TimeString(timeRemaining), flagFell); else - sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell); + snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell); str = buf; } else { str = color; @@ -8448,7 +7527,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, rect, str, strlen(str), NULL); if(logoHeight > 0 && appData.clockMode) { RECT r; - sprintf(buf, "%s %s", buf+7, flagFell); + str += strlen(color)+2; r.top = rect->top + logoHeight/2; r.left = rect->left; r.right = rect->right; @@ -8723,6 +7802,14 @@ typedef struct { } Enables; VOID +GreyRevert(Boolean grey) +{ // [HGM] vari: for retracting variations in local mode + HMENU hmenu = GetMenu(hwndMain); + EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED)); + EnableMenuItem(hmenu, IDM_Annotate, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED)); +} + +VOID SetMenuEnables(HMENU hmenu, Enables *enab) { while (enab->item > 0) { @@ -8741,8 +7828,26 @@ Enables gnuEnables[] = { { IDM_Adjourn, MF_BYCOMMAND|MF_GRAYED }, { IDM_StopExamining, MF_BYCOMMAND|MF_GRAYED }, { IDM_StopObserving, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Upload, MF_BYCOMMAND|MF_GRAYED }, { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, + + // Needed to switch from ncp to GNU mode on Engine Load + { ACTION_POS, MF_BYPOSITION|MF_ENABLED }, + { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, + { IDM_MachineBlack, MF_BYCOMMAND|MF_ENABLED }, + { IDM_TwoMachines, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Match, MF_BYCOMMAND|MF_ENABLED }, + { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, + { IDM_AnalyzeFile, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine1Options, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Engine2Options, MF_BYCOMMAND|MF_ENABLED }, + { IDM_TimeControl, MF_BYCOMMAND|MF_ENABLED }, + { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, + { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Book, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } }; @@ -8752,6 +7857,7 @@ Enables icsEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, @@ -8759,13 +7865,17 @@ Enables icsEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED }, { IDM_Hint, MF_BYCOMMAND|MF_GRAYED }, { IDM_Book, MF_BYCOMMAND|MF_GRAYED }, + { IDM_LoadProg1, MF_BYCOMMAND|MF_GRAYED }, + { IDM_LoadProg2, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Tourney, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; -#ifdef ZIPPY +#if ZIPPY Enables zippyEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, @@ -8781,11 +7891,13 @@ Enables ncpEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsClient, MF_BYCOMMAND|MF_GRAYED }, { ACTION_POS, MF_BYPOSITION|MF_GRAYED }, { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED }, @@ -8795,11 +7907,13 @@ Enables ncpEnables[] = { { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Sounds, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; Enables trainingOnEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Comment, MF_BYCOMMAND|MF_GRAYED }, { IDM_Pause, MF_BYCOMMAND|MF_GRAYED }, { IDM_Forward, MF_BYCOMMAND|MF_GRAYED }, { IDM_Backward, MF_BYCOMMAND|MF_GRAYED }, @@ -8812,6 +7926,7 @@ Enables trainingOnEnables[] = { Enables trainingOffEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Comment, MF_BYCOMMAND|MF_ENABLED }, { IDM_Pause, MF_BYCOMMAND|MF_ENABLED }, { IDM_Forward, MF_BYCOMMAND|MF_ENABLED }, { IDM_Backward, MF_BYCOMMAND|MF_ENABLED }, @@ -8848,6 +7963,7 @@ Enables machineThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, +// { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } @@ -8867,6 +7983,7 @@ Enables userThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_ENABLED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_ENABLED }, +// { IDM_Match, MF_BYCOMMAND|MF_ENABLED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_ENABLED }, { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } @@ -8879,6 +7996,12 @@ Enables userThinkingEnables[] = { * \*---------------------------------------------------------------------------*/ VOID +CheckMark(UINT item, int state) +{ + if(item) CheckMenuItem(GetMenu(hwndMain), item, MF_BYCOMMAND|state); +} + +VOID ModeHighlight() { static UINT prevChecked = 0; @@ -8939,12 +8062,9 @@ ModeHighlight() nowChecked = 0; break; } - if (prevChecked != 0) - (void) CheckMenuItem(GetMenu(hwndMain), - prevChecked, MF_BYCOMMAND|MF_UNCHECKED); - if (nowChecked != 0) - (void) CheckMenuItem(GetMenu(hwndMain), - nowChecked, MF_BYCOMMAND|MF_CHECKED); + CheckMark(prevChecked, MF_UNCHECKED); + CheckMark(nowChecked, MF_CHECKED); + CheckMark(IDM_Match, matchMode && matchGame < appData.matchGames ? MF_CHECKED : MF_UNCHECKED); if (nowChecked == IDM_LoadGame || nowChecked == IDM_Training) { (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training, @@ -8959,13 +8079,12 @@ ModeHighlight() /* [DM] icsEngineAnalyze - Do a sceure check too */ if (appData.icsActive) { if (appData.icsEngineAnalyze) { - (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, - MF_BYCOMMAND|MF_CHECKED); + CheckMark(IDM_AnalysisMode, MF_CHECKED); } else { - (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, - MF_BYCOMMAND|MF_UNCHECKED); + CheckMark(IDM_AnalysisMode, MF_UNCHECKED); } } + DisplayLogos(); // [HGM] logos: mode change could have altered logos } VOID @@ -8973,9 +8092,9 @@ SetICSMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, icsEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), ICS_POS, - MF_BYPOSITION|MF_ENABLED); -#ifdef ZIPPY + EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), IDM_IcsOptions, + MF_BYCOMMAND|MF_ENABLED); +#if ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); if (!appData.noChessProgram) /* [DM] icsEngineAnalyze */ @@ -8996,8 +8115,6 @@ SetNCPMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, ncpEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), SOUNDS_POS, - MF_BYPOSITION|MF_GRAYED); DrawMenuBar(hwndMain); } @@ -9049,7 +8166,7 @@ SetMachineThinkingEnables() } else if (gameMode == MachinePlaysWhite) { (void)EnableMenuItem(hMenu, IDM_MachineWhite, flags); } else if (gameMode == TwoMachinesPlay) { - (void)EnableMenuItem(hMenu, IDM_TwoMachines, flags); + (void)EnableMenuItem(hMenu, matchMode ? IDM_Match : IDM_TwoMachines, flags); // [HGM] match } } @@ -9059,17 +8176,17 @@ DisplayTitle(char *str) { char title[MSG_SIZ], *host; if (str[0] != NULLCHAR) { - strcpy(title, str); + safeStrCpy(title, str, sizeof(title)/sizeof(title[0]) ); } else if (appData.icsActive) { if (appData.icsCommPort[0] != NULLCHAR) host = "ICS"; else host = appData.icsHost; - sprintf(title, "%s: %s", szTitle, host); + snprintf(title, MSG_SIZ, "%s: %s", szTitle, host); } else if (appData.noChessProgram) { - strcpy(title, szTitle); + safeStrCpy(title, szTitle, sizeof(title)/sizeof(title[0]) ); } else { - strcpy(title, szTitle); + safeStrCpy(title, szTitle, sizeof(title)/sizeof(title[0]) ); strcat(title, ": "); strcat(title, first.tidy); } @@ -9104,6 +8221,7 @@ DisplayMessage(char *str1, char *str2) strncat(messageText, str2, len); } messageText[MESSAGE_TEXT_MAX - 1] = NULLCHAR; + safeStrCpy(lastMsg, messageText, MSG_SIZ); if (hwndMain == NULL || IsIconic(hwndMain)) return; @@ -9124,25 +8242,25 @@ DisplayError(char *str, int error) int len; if (error == 0) { - strcpy(buf, str); + safeStrCpy(buf, str, sizeof(buf)/sizeof(buf[0]) ); } else { len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, LANG_NEUTRAL, (LPSTR) buf2, MSG_SIZ, NULL); if (len > 0) { - sprintf(buf, "%s:\n%s", str, buf2); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, buf2); } else { ErrorMap *em = errmap; while (em->err != 0 && em->err != error) em++; if (em->err != 0) { - sprintf(buf, "%s:\n%s", str, em->msg); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, em->msg); } else { - sprintf(buf, "%s:\nError code %d", str, error); + snprintf(buf, 2*MSG_SIZ, "%s:\nError code %d", str, error); } } } - ErrorPopUp("Error", buf); + ErrorPopUp(_("Error"), buf); } @@ -9153,7 +8271,7 @@ DisplayMoveError(char *str) ClearHighlights(); DrawPosition(FALSE, NULL); if (appData.popupMoveErrors) { - ErrorPopUp("Error", str); + ErrorPopUp(_("Error"), str); } else { DisplayMessage(str, ""); moveErrorMessageUp = TRUE; @@ -9165,21 +8283,21 @@ DisplayFatalError(char *str, int error, int exitStatus) { char buf[2*MSG_SIZ], buf2[MSG_SIZ]; int len; - char *label = exitStatus ? "Fatal Error" : "Exiting"; + char *label = exitStatus ? _("Fatal Error") : _("Exiting"); if (error != 0) { len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, LANG_NEUTRAL, (LPSTR) buf2, MSG_SIZ, NULL); if (len > 0) { - sprintf(buf, "%s:\n%s", str, buf2); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, buf2); } else { ErrorMap *em = errmap; while (em->err != 0 && em->err != error) em++; if (em->err != 0) { - sprintf(buf, "%s:\n%s", str, em->msg); + snprintf(buf, 2*MSG_SIZ, "%s:\n%s", str, em->msg); } else { - sprintf(buf, "%s:\nError code %d", str, error); + snprintf(buf, 2*MSG_SIZ, "%s:\nError code %d", str, error); } } str = buf; @@ -9198,14 +8316,14 @@ DisplayFatalError(char *str, int error, int exitStatus) VOID DisplayInformation(char *str) { - (void) MessageBox(hwndMain, str, "Information", MB_OK|MB_ICONINFORMATION); + (void) MessageBox(hwndMain, str, _("Information"), MB_OK|MB_ICONINFORMATION); } VOID DisplayNote(char *str) { - ErrorPopUp("Note", str); + ErrorPopUp(_("Note"), str); } @@ -9225,6 +8343,7 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: qp = (QuestionParams *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_Question); SetWindowText(hDlg, qp->title); SetDlgItemText(hDlg, OPT_QuestionText, qp->question); SetFocus(GetDlgItem(hDlg, OPT_QuestionInput)); @@ -9233,14 +8352,14 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: - strcpy(reply, qp->replyPrefix); + safeStrCpy(reply, qp->replyPrefix, sizeof(reply)/sizeof(reply[0]) ); if (*reply) strcat(reply, " "); len = strlen(reply); GetDlgItemText(hDlg, OPT_QuestionInput, reply + len, sizeof(reply) - len); strcat(reply, "\n"); OutputToProcess(qp->pr, reply, strlen(reply), &err); EndDialog(hDlg, TRUE); - if (err) DisplayFatalError("Error writing to chess program", err, 1); + if (err) DisplayFatalError(_("Error writing to chess program"), err, 1); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); @@ -9282,6 +8401,7 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lpIndexFRC = (int *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_NewGameFRC); SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 ); SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE ); @@ -9308,7 +8428,7 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM } return TRUE; case IDC_NFG_Random: - sprintf( buf, "%d", myrandom() ); /* [HGM] shuffle: no longer limit to 960 */ + snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%d", myrandom() ); /* [HGM] shuffle: no longer limit to 960 */ SetDlgItemText(hDlg, IDC_NFG_Edit, buf ); return TRUE; } @@ -9334,104 +8454,42 @@ int NewGameFRC() return result; } -/* [AS] Game list options */ -typedef struct { - char id; - char * name; -} GLT_Item; - -static GLT_Item GLT_ItemInfo[] = { - { GLT_EVENT, "Event" }, - { GLT_SITE, "Site" }, - { GLT_DATE, "Date" }, - { GLT_ROUND, "Round" }, - { GLT_PLAYERS, "Players" }, - { GLT_RESULT, "Result" }, - { GLT_WHITE_ELO, "White Rating" }, - { GLT_BLACK_ELO, "Black Rating" }, - { GLT_TIME_CONTROL,"Time Control" }, - { GLT_VARIANT, "Variant" }, - { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK }, - { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom - { 0, 0 } -}; - -const char * GLT_FindItem( char id ) -{ - const char * result = 0; - - GLT_Item * list = GLT_ItemInfo; +/* [AS] Game list options. Refactored by HGM */ - while( list->id != 0 ) { - if( list->id == id ) { - result = list->name; - break; - } +HWND gameListOptionsDialog; - list++; - } - - return result; +// low-level front-end: clear text edit / list widget +void +GLT_ClearList() +{ + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 ); } -void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index ) +// low-level front-end: clear text edit / list widget +void +GLT_DeSelectList() { - const char * name = GLT_FindItem( id ); - - if( name != 0 ) { - if( index >= 0 ) { - SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name ); - } - else { - SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name ); - } - } + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_SETCURSEL, 0, 0 ); } -void GLT_TagsToList( HWND hDlg, char * tags ) +// low-level front-end: append line to text edit / list widget +void +GLT_AddToList( char *name ) { - char * pc = tags; - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 ); - - while( *pc ) { - GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 ); - pc++; - } - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" ); - - pc = GLT_ALL_TAGS; - - while( *pc ) { - if( strchr( tags, *pc ) == 0 ) { - GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 ); - } - pc++; + if( name != 0 ) { + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) name ); } - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 ); } -char GLT_ListItemToTag( HWND hDlg, int index ) +// low-level front-end: get line from text edit / list widget +Boolean +GLT_GetFromList( int index, char *name ) { - char result = '\0'; - char name[128]; - - GLT_Item * list = GLT_ItemInfo; - - if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) { - while( list->id != 0 ) { - if( strcmp( list->name, name ) == 0 ) { - result = list->id; - break; - } - - list++; - } + if( name != 0 ) { + if( SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) + return TRUE; } - - return result; + return FALSE; } void GLT_MoveSelection( HWND hDlg, int delta ) @@ -9452,20 +8510,16 @@ void GLT_MoveSelection( HWND hDlg, int delta ) LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - static char glt[64]; - static char * lpUserGLT; - switch( message ) { case WM_INITDIALOG: - lpUserGLT = (char *) lParam; + gameListOptionsDialog = hDlg; // [HGM] pass through global to keep out off back-end - strcpy( glt, lpUserGLT ); - CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_GameListOptions); /* Initialize list */ - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( lpUserGLT ); SetFocus( GetDlgItem(hDlg, IDC_GameListTags) ); @@ -9474,19 +8528,7 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: - { - char * pc = lpUserGLT; - int idx = 0; -// int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 ); - char id; - - do { - id = GLT_ListItemToTag( hDlg, idx ); - - *pc++ = id; - idx++; - } while( id != '\0' ); - } + GLT_ParseList(); EndDialog( hDlg, 0 ); return TRUE; case IDCANCEL: @@ -9494,13 +8536,11 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP return TRUE; case IDC_GLT_Default: - strcpy( glt, GLT_DEFAULT_TAGS ); - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( GLT_DEFAULT_TAGS ); return TRUE; case IDC_GLT_Restore: - strcpy( glt, lpUserGLT ); - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( appData.gameListTags ); return TRUE; case IDC_GLT_Up: @@ -9520,30 +8560,40 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP int GameListOptions() { - char glt[64]; int result; FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst ); - strcpy( glt, appData.gameListTags ); + safeStrCpy( lpUserGLT, appData.gameListTags ,LPUSERGLT_SIZE ); - result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt ); + result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT ); if( result == 0 ) { /* [AS] Memory leak here! */ - appData.gameListTags = strdup( glt ); + appData.gameListTags = strdup( lpUserGLT ); } return result; } - VOID DisplayIcsInteractionTitle(char *str) { char consoleTitle[MSG_SIZ]; - sprintf(consoleTitle, "%s: %s", szConsoleTitle, str); - SetWindowText(hwndConsole, consoleTitle); + snprintf(consoleTitle, MSG_SIZ, "%s: %s", szConsoleTitle, str); + SetWindowText(hwndConsole, consoleTitle); + + if(appData.chatBoxes) { // [HGM] chat: open chat boxes + char buf[MSG_SIZ], *p = buf, *q; + safeStrCpy(buf, appData.chatBoxes, sizeof(buf)/sizeof(buf[0]) ); + do { + q = strchr(p, ';'); + if(q) *q++ = 0; + if(*p) ChatPopUp(p); + } while(p=q); + } + + SetActiveWindow(hwndMain); } void @@ -9571,6 +8621,7 @@ ResetFrontEnd() ReleaseCapture(); DrawPosition(TRUE, NULL); } + TagsPopDown(); } @@ -9578,7 +8629,7 @@ VOID CommentPopUp(char *title, char *str) { HWND hwnd = GetActiveWindow(); - EitherCommentPopUp(0, title, str, FALSE); + EitherCommentPopUp(currentMove, title, str, FALSE); // [HGM] vari: fake move index, rather than 0 SAY(str); SetActiveWindow(hwnd); } @@ -9586,11 +8637,11 @@ CommentPopUp(char *title, char *str) VOID CommentPopDown(void) { - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, MF_UNCHECKED); if (commentDialog) { ShowWindow(commentDialog, SW_HIDE); } - commentDialogUp = FALSE; + commentUp = FALSE; } VOID @@ -9632,6 +8683,12 @@ PlayAlarmSound() MyPlaySound(&sounds[(int)SoundAlarm]); } +VOID +PlayTellSound() +{ + MyPlaySound(&textAttribs[ColorTell].sound); +} + VOID EchoOn() @@ -9680,7 +8737,7 @@ UserName() } if (!GetUserName(buf, &bufsiz)) { /*DisplayError("Error getting user name", GetLastError());*/ - strcpy(buf, "User"); + safeStrCpy(buf, _("User"), sizeof(buf)/sizeof(buf[0]) ); } return buf; } @@ -9693,7 +8750,7 @@ HostName() if (!GetComputerName(buf, &bufsiz)) { /*DisplayError("Error getting host name", GetLastError());*/ - strcpy(buf, "Unknown"); + safeStrCpy(buf, _("Unknown"), sizeof(buf)/sizeof(buf[0]) ); } return buf; } @@ -9731,7 +8788,7 @@ DisplayWhiteClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &blackRect : &whiteRect, "White", flag); + flipClock ? &blackRect : &whiteRect, _("White"), flag); } if (highlight && iconCurrent == iconBlack) { iconCurrent = iconWhite; @@ -9755,7 +8812,7 @@ DisplayBlackClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &whiteRect : &blackRect, "Black", flag); + flipClock ? &whiteRect : &blackRect, _("Black"), flag); } if (highlight && iconCurrent == iconWhite) { iconCurrent = iconBlack; @@ -9803,7 +8860,7 @@ AutoSaveGame() f = OpenFileDialog(hwndMain, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); fclose(f); @@ -9864,6 +8921,37 @@ IDLE_PRIORITY_CLASS 0x00000040 return 0x00000040; } +void RunCommand(char *cmdLine) +{ + /* Now create the child process. */ + STARTUPINFO siStartInfo; + PROCESS_INFORMATION piProcInfo; + + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.lpReserved = NULL; + siStartInfo.lpDesktop = NULL; + siStartInfo.lpTitle = NULL; + siStartInfo.dwFlags = STARTF_USESTDHANDLES; + siStartInfo.cbReserved2 = 0; + siStartInfo.lpReserved2 = NULL; + siStartInfo.hStdInput = NULL; + siStartInfo.hStdOutput = NULL; + siStartInfo.hStdError = NULL; + + CreateProcess(NULL, + cmdLine, /* command line */ + NULL, /* process security attributes */ + NULL, /* primary thread security attrs */ + TRUE, /* handles are inherited */ + DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP, + NULL, /* use parent's environment */ + NULL, + &siStartInfo, /* STARTUPINFO pointer */ + &piProcInfo); /* receives PROCESS_INFORMATION */ + + CloseHandle(piProcInfo.hThread); +} + /* Start a child process running the given program. The process's standard output can be read from "from", and its standard input can be written to "to". @@ -10107,9 +9195,9 @@ OpenTelnet(char *host, char *port, ProcRef *pr) char cmdLine[MSG_SIZ]; if (port[0] == NULLCHAR) { - sprintf(cmdLine, "%s %s", appData.telnetProgram, host); + snprintf(cmdLine, MSG_SIZ, "%s %s", appData.telnetProgram, host); } else { - sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port); + snprintf(cmdLine, MSG_SIZ, "%s %s %s", appData.telnetProgram, host, port); } return StartChildProcess(cmdLine, "", pr); } @@ -10123,6 +9211,7 @@ OpenTCP(char *host, char *port, ProcRef *pr) ChildProc *cp; int err; SOCKET s; + struct sockaddr_in sa, mysa; struct hostent FAR *hp; unsigned short uport; @@ -10208,9 +9297,9 @@ OpenCommPort(char *name, ProcRef *pr) char fullname[MSG_SIZ]; if (*name != '\\') - sprintf(fullname, "\\\\.\\%s", name); + snprintf(fullname, MSG_SIZ, "\\\\.\\%s", name); else - strcpy(fullname, name); + safeStrCpy(fullname, name, sizeof(fullname)/sizeof(fullname[0]) ); h = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); @@ -10242,7 +9331,7 @@ OpenCommPort(char *name, ProcRef *pr) int OpenLoopback(ProcRef *pr) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); return NO_ERROR; } @@ -10380,7 +9469,7 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr) break; } prevStderrPort = fromPort; // remember port used - sprintf(stderrPortStr, "%d", fromPort); + snprintf(stderrPortStr, MSG_SIZ, "%d", fromPort); if (send(s, stderrPortStr, strlen(stderrPortStr) + 1, 0) == SOCKET_ERROR) { err = WSAGetLastError(); @@ -10522,6 +9611,11 @@ RemoveInputSource(InputSourceRef isr) } } +int no_wrap(char *message, int count) +{ + ConsoleOutput(message, count, FALSE); + return count; +} int OutputToProcess(ProcRef pr, char *message, int count, int *outError) @@ -10530,11 +9624,32 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError) int outCount = SOCKET_ERROR; ChildProc *cp = (ChildProc *) pr; static OVERLAPPED ovl; + static int line = 0; - if (pr == NoProc) { - ConsoleOutput(message, count, FALSE); - return count; - } + if (pr == NoProc) + { + if (appData.noJoin || !appData.useInternalWrap) + return no_wrap(message, count); + else + { + int width = get_term_width(); + int len = wrap(NULL, message, count, width, &line); + char *msg = malloc(len); + int dbgchk; + + if (!msg) + return no_wrap(message, count); + else + { + dbgchk = wrap(msg, message, count, width, &line); + if (dbgchk != len && appData.debugMode) + fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); + ConsoleOutput(msg, len, FALSE); + free(msg); + return len; + } + } + } if (ovl.hEvent == NULL) { ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -10573,6 +9688,12 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError) return outCount; } +void +DoSleep(int n) +{ + if(n != 0) Sleep(n); +} + int OutputToProcessDelayed(ProcRef pr, char *message, int count, int *outError, long msdelay) @@ -10586,7 +9707,7 @@ void CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure, char *buf, int count, int error) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); } /* see wgamelist.c for Game List functions */ @@ -10618,86 +9739,6 @@ StartAnalysisClock() (UINT) 2000, NULL); } -LRESULT CALLBACK -AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - static HANDLE hwndText; - RECT rect; - static int sizeX, sizeY; - int newSizeX, newSizeY, flags; - MINMAXINFO *mmi; - - switch (message) { - case WM_INITDIALOG: /* message: initialize dialog box */ - /* Initialize the dialog items */ - hwndText = GetDlgItem(hDlg, OPT_AnalysisText); - SetWindowText(hDlg, analysisTitle); - SetDlgItemText(hDlg, OPT_AnalysisText, analysisText); - /* Size and position the dialog */ - if (!analysisDialog) { - analysisDialog = hDlg; - flags = SWP_NOZORDER; - GetClientRect(hDlg, &rect); - sizeX = rect.right; - sizeY = rect.bottom; - if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT && - analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) { - WINDOWPLACEMENT wp; - EnsureOnScreen(&analysisX, &analysisY, 0, 0); - wp.length = sizeof(WINDOWPLACEMENT); - wp.flags = 0; - wp.showCmd = SW_SHOW; - wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = analysisX; - wp.rcNormalPosition.right = analysisX + analysisW; - wp.rcNormalPosition.top = analysisY; - wp.rcNormalPosition.bottom = analysisY + analysisH; - SetWindowPlacement(hDlg, &wp); - - GetClientRect(hDlg, &rect); - newSizeX = rect.right; - newSizeY = rect.bottom; - ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, - newSizeX, newSizeY); - sizeX = newSizeX; - sizeY = newSizeY; - } - } - return FALSE; - - case WM_COMMAND: /* message: received a command */ - switch (LOWORD(wParam)) { - case IDCANCEL: - if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */ - ExitAnalyzeMode(); - ModeHighlight(); - return TRUE; - } - EditGameEvent(); - return TRUE; - default: - break; - } - break; - - case WM_SIZE: - newSizeX = LOWORD(lParam); - newSizeY = HIWORD(lParam); - ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, newSizeX, newSizeY); - sizeX = newSizeX; - sizeY = newSizeY; - break; - - case WM_GETMINMAXINFO: - /* Prevent resizing window too small */ - mmi = (MINMAXINFO *) lParam; - mmi->ptMinTrackSize.x = 100; - mmi->ptMinTrackSize.y = 100; - break; - } - return FALSE; -} - VOID SetHighlights(int fromX, int fromY, int toX, int toY) { @@ -10754,26 +9795,26 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor, POINT frames[], int * nFrames); +#define kFactor 4 + void -AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames) +AnimateAtomicCapture(Board board, int fromX, int fromY, int toX, int toY) { // [HGM] atomic: animate blast wave int i; -if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY); + explodeInfo.fromX = fromX; explodeInfo.fromY = fromY; explodeInfo.toX = toX; explodeInfo.toY = toY; - for(i=1; i