X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=e6dec36947a31929ef632db20a96cefecd7a95e4;hb=3a75b74c7fc03b543993c90f4a9ebdea9f03b759;hp=fcadd27f1984cfae3c312c49170838e7942e750e;hpb=9c7cb89d6ae88edc97bc99e51fb6779ddf6e33b8;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index fcadd27..e6dec36 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, 2010 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 @@ -99,8 +100,10 @@ extern int whiteFlag, blackFlag; Boolean flipClock = FALSE; extern HANDLE chatHandle[]; -extern int ics_type; +extern enum ICS_TYPE 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, @@ -123,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 */ @@ -160,7 +164,7 @@ BoardSize boardSize; Boolean chessProgram; //static int boardX, boardY; int minX, minY; // [HGM] placement: volatile limits on upper-left corner -int squareSize, lineGap, minorSize; +int squareSize, lineGap, minorSize, border; static int winW, winH; static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo static int logoHeight = 0; @@ -247,11 +251,12 @@ Boolean barbaric; // flag indicating if translation is needed #define ABOUTBOX -1 /* not sure why these are needed */ #define ABOUTBOX2 -1 -int dialogItems[][40] = { -{ ABOUTBOX, IDOK, 400 }, +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, 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 }, @@ -282,7 +287,7 @@ int dialogItems[][40] = { 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_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, @@ -299,7 +304,7 @@ int dialogItems[][40] = { 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 }, + 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, @@ -311,7 +316,8 @@ int dialogItems[][40] = { 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_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, @@ -330,11 +336,11 @@ int dialogItems[][40] = { { 0 } }; -static char languageBuf[50000], *foreign[1000], *english[1000], *languageFile[MSG_SIZ]; +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[][8]; +extern char * menuBarText[][10]; void LoadLanguageFile(char *name) @@ -345,6 +351,7 @@ LoadLanguageFile(char *name) 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) { @@ -383,11 +390,16 @@ 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; @@ -398,13 +410,11 @@ Translate(HWND hDlg, int dialogID) { // translate all text items in the given dialog int i=0, j, k; char buf[MSG_SIZ], *s; -//if(appData.debugMode) fprintf(debugFP, "Translate(%d)\n", dialogID); 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(appData.debugMode) fprintf(debugFP, "WindowText '%s' -> '%s'\n", buf, s); 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); @@ -414,33 +424,45 @@ Translate(HWND hDlg, int dialogID) } } +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, j; + int i; WIN32_FIND_DATA fileData; HANDLE hFind; -#define IDM_English 1895 +#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])); - for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ - char buf[MSG_SIZ]; - UINT k = GetMenuItemID(subMenu, j); - if(menuText[i][j]) - safeStrCpy(buf, menuText[i][j], sizeof(buf)/sizeof(buf[0]) ); else { - GetMenuString(subMenu, j, buf, MSG_SIZ, MF_BYPOSITION); - menuText[i][j] = strdup(buf); // remember original on first change - } - if(buf[0] == NULLCHAR) continue; -//fprintf(debugFP, "menu(%d,%d) = %s (%08x, %08x) %d\n", i, j, buf, mainMenu, subMenu, k); - ModifyMenu(subMenu, j, MF_STRING|MF_BYPOSITION - |CheckMenuItem(subMenu, j, MF_BYPOSITION) - |EnableMenuItem(subMenu, j, MF_BYPOSITION), k, T_(buf)); - } + TranslateOneMenu(i, subMenu); } DrawMenuBar(hwndMain); } @@ -472,6 +494,30 @@ TranslateMenus(int addLanguage) #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; @@ -507,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]; @@ -549,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] = { - { N_("&File"), N_("&Mode"), N_("&Action"), N_("&Step"), N_("&Options"), N_("&Help"), NULL }, - { N_("&F"), N_("&M"), N_("&A"), N_("&S"), N_("&O"), N_("&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 }, }; @@ -641,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); @@ -718,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 @@ -756,6 +802,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, } JAWS_INIT + TranslateMenus(1); // InitCommonControlsEx(&ex); InitCommonControls(); @@ -876,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)) { - snprintf(oldUserName, MSG_SIZ, "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 ); 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 */ } } } @@ -940,6 +992,62 @@ 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 + char *opponent = ""; + if(gameMode == IcsPlayingWhite) opponent = gameInfo.black; + if(gameMode == IcsPlayingBlack) opponent = gameInfo.white; + sprintf(buf, "logos\\%s\\%s.bmp", appData.icsHost, opponent); + if(!*opponent || !(cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ))) { + 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) { @@ -995,37 +1103,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]; - snprintf(buf, MSG_SIZ, "%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 - snprintf(buf, MSG_SIZ, "logos\\%s.bmp", appData.icsHost); - second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); - } else - if(appData.secondDirectory && appData.secondDirectory[0]) { - snprintf(buf, MSG_SIZ, "%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(); @@ -1048,30 +1127,12 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } InitDrawingSizes(boardSize, 0); - TranslateMenus(1); + 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) ); @@ -1111,15 +1172,6 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); #endif ShowWindow(hwndConsole, nCmdShow); - 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(hwndConsole); } if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE); @@ -1150,6 +1202,7 @@ InitMenuChecks() #define OPTCHAR "/" #define SEPCHAR "=" +#define TOPLEVEL 0 #include "args.h" @@ -1218,7 +1271,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; @@ -1227,12 +1280,12 @@ 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); @@ -1338,7 +1391,7 @@ ParseBoardSize(void *addr, char *name) } bs++; } - ExitArgError(_("Unrecognized board size value"), name); + ExitArgError(_("Unrecognized board size value"), name, TRUE); } void @@ -1959,7 +2012,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; } @@ -2059,9 +2113,15 @@ void CreatePiecesFromFont() HBITMAP DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix) { - char name[128]; + char name[128], buf[MSG_SIZ]; snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix); + if(appData.pieceDirectory[0]) { + HBITMAP res; + snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name); + res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + if(res) return res; + } if (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0 && strcmp(name, "k80s") == 0) { @@ -2188,12 +2248,28 @@ InitDrawingSizes(BoardSize boardSize, int flags) RECT crect, wrect, oldRect; int offby; LOGBRUSH logbrush; + VariantClass v = gameInfo.variant; int suppressVisibleEffects = 0; // [HGM] kludge to request updating sizeInfo only if((int)boardSize >= 1000 ) { boardSize -= 1000; suppressVisibleEffects = 1; } /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize; + oldBoardSize = boardSize; + + if(boardSize != SizeMiddling && boardSize != SizePetite && boardSize != SizeBulky && !appData.useFont) + { // correct board size to one where built-in pieces exist + if((v == VariantCapablanca || v == VariantGothic || v == VariantGrand || v == VariantCapaRandom || v == VariantJanus || v == VariantSuper) + && (boardSize < SizePetite || boardSize > SizeBulky) // Archbishop and Chancellor available in entire middle range + || (v == VariantShogi && boardSize != SizeModerate) // Japanese-style Shogi + || v == VariantKnightmate || v == VariantSChess || v == VariantXiangqi || v == VariantSpartan + || v == VariantShatranj || v == VariantMakruk || v == VariantGreat || v == VariantFairy ) { + if(boardSize < SizeMediocre) boardSize = SizePetite; else + if(boardSize > SizeModerate) boardSize = SizeBulky; else + boardSize = SizeMiddling; + } + } + if(!appData.useFont && boardSize == SizePetite && (v == VariantShogi || v == VariantKnightmate)) boardSize = SizeMiddling; // no Unicorn in Petite oldRect.left = wpMain.x; //[HGM] placement: remember previous window params oldRect.top = wpMain.y; @@ -2205,13 +2281,14 @@ InitDrawingSizes(BoardSize boardSize, int flags) squareSize = sizeInfo[boardSize].squareSize; lineGap = sizeInfo[boardSize].lineGap; minorSize = 0; /* [HGM] Kludge to see if demagnified pieces need to be shifted */ + border = appData.useBorder && appData.border[0] ? squareSize/2 : 0; if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) { lineGap = appData.overrideLineGap; } 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, @@ -2220,7 +2297,7 @@ 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, @@ -2229,8 +2306,8 @@ InitDrawingSizes(BoardSize boardSize, int flags) DrawMenuBar(hwndMain); } - boardWidth = BoardWidth(boardSize, BOARD_WIDTH); - boardHeight = BoardWidth(boardSize, BOARD_HEIGHT); + boardWidth = BoardWidth(boardSize, BOARD_WIDTH) + 2*border; + boardHeight = BoardWidth(boardSize, BOARD_HEIGHT) + 2*border; /* Get text area sizes */ hdc = GetDC(hwndMain); @@ -2302,7 +2379,6 @@ InitDrawingSizes(BoardSize boardSize, int flags) sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN; sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN; - oldBoardSize = boardSize; oldTinyLayout = tinyLayout; winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN; winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + @@ -2369,7 +2445,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, @@ -2378,7 +2454,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); @@ -2402,20 +2478,20 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* [HGM] Loop had to be split in part for vert. and hor. lines */ for (i = 0; i < BOARD_HEIGHT + 1; i++) { - gridEndpoints[i*2].x = boardRect.left + lineGap / 2; + gridEndpoints[i*2].x = boardRect.left + lineGap / 2 + border; gridEndpoints[i*2].y = gridEndpoints[i*2 + 1].y = - boardRect.top + lineGap / 2 + (i * (squareSize + lineGap)); + boardRect.top + lineGap / 2 + (i * (squareSize + lineGap)) + border; gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 + - BOARD_WIDTH * (squareSize + lineGap); + BOARD_WIDTH * (squareSize + lineGap) + border; gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2; } for (i = 0; i < BOARD_WIDTH + 1; i++) { - gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2; + gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2 + border; gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].x = gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].x = boardRect.left + - lineGap / 2 + (i * (squareSize + lineGap)); + lineGap / 2 + (i * (squareSize + lineGap)) + border; gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y = - boardRect.top + BOARD_HEIGHT * (squareSize + lineGap); + boardRect.top + BOARD_HEIGHT * (squareSize + lineGap) + border; gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2; } } @@ -2486,14 +2562,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"); @@ -2658,19 +2744,19 @@ VOID SquareToPos(int row, int column, int * x, int * y) { if (flipView) { - *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap); - *y = boardRect.top + lineGap + row * (squareSize + lineGap); + *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border; + *y = boardRect.top + lineGap + row * (squareSize + lineGap) + border; } else { - *x = boardRect.left + lineGap + column * (squareSize + lineGap); - *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap); + *x = boardRect.left + lineGap + column * (squareSize + lineGap) + border; + *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border; } } 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; @@ -2679,7 +2765,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)); @@ -2689,15 +2775,23 @@ DrawCoordsOnDC(HDC hdc) y = boardRect.top + lineGap; x = boardRect.left + lineGap + gameInfo.holdingsWidth*(squareSize + lineGap); + if(border) { + SetTextAlign(hdc, TA_RIGHT|TA_TOP); + x += border - lineGap - 4; y += squareSize - 6; + } else SetTextAlign(hdc, TA_LEFT|TA_TOP); for (i = 0; i < BOARD_HEIGHT; i++) { str[0] = files[start + i]; - ExtTextOut(hdc, x + 2, y + 1, 0, NULL, str, 1, NULL); + ExtTextOut(hdc, x + 2 - (border ? gameInfo.holdingsWidth * (squareSize + lineGap) : 0), y + 1, 0, NULL, str, 1, NULL); y += squareSize + lineGap; } - start = flipView ? 12-(BOARD_RGHT-BOARD_LEFT) : 12; + start = flipView ? 23-(BOARD_RGHT-BOARD_LEFT) : 23; + if(border) { + SetTextAlign(hdc, TA_LEFT|TA_TOP); + x += -border + 4; y += border - squareSize + 6; + } else SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM); for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) { str[0] = ranks[start + i]; @@ -2734,14 +2828,14 @@ DrawHighlightOnDC(HDC hdc, BOOLEAN on, int x, int y, int pen) if (lineGap == 0) return; if (flipView) { x1 = boardRect.left + - lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap); + lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap) + border; y1 = boardRect.top + - lineGap/2 + y * (squareSize + lineGap); + lineGap/2 + y * (squareSize + lineGap) + border; } else { x1 = boardRect.left + - lineGap/2 + x * (squareSize + lineGap); + lineGap/2 + x * (squareSize + lineGap) + border; y1 = boardRect.top + - lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap); + lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap) + border; } hPen = pen ? premovePen : highlightPen; oldPen = SelectObject(hdc, on ? hPen : gridPen); @@ -2819,7 +2913,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, sqcolor ? SRCCOPY : NOTSRCCOPY); } else { + HBRUSH xBrush = whitePieceBrush; tmpSize = squareSize; + if(appData.pieceDirectory[0]) xBrush = GetStockObject(WHITE_BRUSH); if(minorSize && ((piece >= (int)WhiteNightrider && piece <= WhiteGrasshopper) || (piece >= (int)BlackNightrider && piece <= BlackGrasshopper)) ) { @@ -2832,7 +2928,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, if (color || appData.allWhite ) { oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE)); if( color ) - oldBrush = SelectObject(hdc, whitePieceBrush); + oldBrush = SelectObject(hdc, xBrush); else oldBrush = SelectObject(hdc, blackPieceBrush); if(appData.upsideDown && color==flipView) StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); @@ -2844,6 +2940,18 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND); + } else if(appData.pieceDirectory[0]) { + oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE)); + oldBrush = SelectObject(hdc, xBrush); + if(appData.upsideDown && color==flipView) + StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); + else + BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); + SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE)); + if(appData.upsideDown && color==flipView) + StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND); + else + BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND); } else { /* Use square color for details of black pieces */ oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE)); @@ -2942,7 +3050,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 */ @@ -2966,50 +3074,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! :-) */ @@ -3026,8 +3134,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; @@ -3038,20 +3146,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[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(x + j*A_WIDTH_FACTOR); - arrow[3].y = Round(y - j*A_WIDTH_FACTOR*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 ); @@ -3076,20 +3186,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; @@ -3099,7 +3209,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; @@ -3229,6 +3339,38 @@ BOOL DrawPositionNeedsFullRepaint() return result; } +static HBITMAP borderBitmap; + +VOID +DrawBackgroundOnDC(HDC hdc) +{ + + BITMAP bi; + HDC tmphdc; + HBITMAP hbm; + static char oldBorder[MSG_SIZ]; + int w = 600, h = 600; + + if(strcmp(appData.border, oldBorder)) { // load new one when old one no longer valid + strncpy(oldBorder, appData.border, MSG_SIZ-1); + borderBitmap = LoadImage( 0, appData.border, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } + if(borderBitmap == NULL) { // loading failed, use white + FillRect( hdc, &boardRect, whitePieceBrush ); + return; + } + tmphdc = CreateCompatibleDC(hdc); + hbm = SelectObject(tmphdc, borderBitmap); + if( GetObject( borderBitmap, sizeof(bi), &bi ) > 0 ) { + w = bi.bmWidth; + h = bi.bmHeight; + } + StretchBlt(hdc, boardRect.left, boardRect.top, boardRect.right - boardRect.left, + boardRect.bottom - boardRect.top, tmphdc, 0, 0, w, h, SRCCOPY); + SelectObject(tmphdc, hbm); + DeleteDC(tmphdc); +} + VOID DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) { @@ -3296,7 +3438,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 @@ -3354,7 +3496,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); @@ -3370,6 +3515,57 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) DeleteDC(tmphdc); } +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 @@ -3426,6 +3622,14 @@ void DrawSeekDot(int x, int y, int color) SelectObject(hdcSeek, oldBrush); } +void DrawSeekOpen() +{ +} + +void DrawSeekClose() +{ +} + VOID HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) { @@ -3685,6 +3889,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); } else { + if(border) DrawBackgroundOnDC(hdcmem); DrawGridOnDC(hdcmem); if(nr == 0) { // [HGM] dual: decide which highlights to draw DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); @@ -3708,41 +3913,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) } } } - 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; - } - } - DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); - DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); - } if( appData.highlightMoveWithArrow ) { DrawArrowHighlight(hdcmem); @@ -3764,8 +3934,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); } @@ -3810,11 +3980,11 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) 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; @@ -3878,6 +4048,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) // write bitmap data for(i=0; i= squareSize) return -1; x /= (squareSize + lineGap); @@ -4024,12 +4193,14 @@ SetupDropMenu(HMENU hmenu) } } -void DragPieceBegin(int x, int y) +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); } @@ -4042,6 +4213,11 @@ void DragPieceEnd(int x, int y) 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) @@ -4080,23 +4256,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_LBUTTONDOWN: if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditPosition) { - SetWhiteToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(flipClock, -1); - } else if (gameMode == IcsPlayingBlack || - gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } + ClockClick(flipClock); break; } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditPosition) { - SetBlackToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(!flipClock, -1); - } else if (gameMode == IcsPlayingWhite || - gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } + ClockClick(!flipClock); break; } dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; @@ -4116,6 +4278,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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) @@ -4175,9 +4338,9 @@ 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 || GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); + if (GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); } break; } @@ -4203,7 +4366,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } break; case 2: - SetCapture(hwndMain); + SetCapture(hwndMain); break; case 1: hmenu = LoadMenu(hInst, "DropPieceMenu"); @@ -4222,7 +4385,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 */ @@ -4297,12 +4461,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); @@ -4319,31 +4482,30 @@ 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. */ UserMoveEvent(fromX, fromY, toX, toY, promoChar); fromX = fromY = -1; if (!appData.highlightLastMove) { @@ -4374,14 +4536,6 @@ PromotionPopUp() PromotionPopup(hwndMain); } -/* Toggle ShowThinking */ -VOID -ToggleShowThinking() -{ - appData.showThinking = !appData.showThinking; - ShowThinkingEvent(); -} - VOID LoadGameDialog(HWND hwnd, char* title) { @@ -4453,11 +4607,11 @@ void UpdateICSWidth(HWND hText) LONG old_width, new_width; new_width = get_term_width(hText, FALSE); - old_width = GetWindowLong(hText, GWL_USERDATA); + old_width = GetWindowLongPtr(hText, GWLP_USERDATA); if (new_width != old_width) { ics_update_width(new_width); - SetWindowLong(hText, GWL_USERDATA, new_width); + SetWindowLongPtr(hText, GWLP_USERDATA, new_width); } } @@ -4522,6 +4676,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) { @@ -4549,7 +4704,23 @@ 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: @@ -4563,7 +4734,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(); } @@ -4688,7 +4859,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); } @@ -4818,10 +4989,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games - if(gameMode != BeginningOfGame) break; // allow menu item to remain enabled for better mode highligting - matchMode = 2;// distinguish from command-line-triggered case (matchMode=1) - appData.matchGames = appData.defaultMatchGames; - matchGame = 1; + MatchEvent(2); // distinguish from command-line-triggered case (matchMode=1) + break; case IDM_TwoMachines: TwoMachinesEvent(); @@ -4838,52 +5007,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_AnalysisMode: - if (!first.analysisSupport) { - snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy); - DisplayError(buf, 0); - } else { + if(AnalyzeModeEvent()) { SAY("analyzing current position"); - /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */ - if (appData.icsActive) { - if (gameMode != IcsObserving) { - snprintf(buf, MSG_SIZ, "You are not observing a game"); - DisplayError(buf, 0); - /* secure check */ - if (appData.icsEngineAnalyze) { - if (appData.debugMode) - fprintf(debugFP, "Found unexpected active ICS engine analyze \n"); - ExitAnalyzeMode(); - ModeHighlight(); - break; - } - break; - } else { - /* if enable, user want disable icsEngineAnalyze */ - if (appData.icsEngineAnalyze) { - ExitAnalyzeMode(); - ModeHighlight(); - break; - } - appData.icsEngineAnalyze = TRUE; - if (appData.debugMode) fprintf(debugFP, "ICS engine analyze starting...\n"); - } - } - if (!appData.showThinking) ToggleShowThinking(); - AnalyzeModeEvent(); } break; case IDM_AnalyzeFile: - if (!first.analysisSupport) { - char buf[MSG_SIZ]; - 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")); - AnalysisPeriodicEvent(1); - } + AnalyzeFileEvent(); break; case IDM_IcsClient: @@ -4891,11 +5021,13 @@ 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("enter a FEN string or setup a position on the board using the control R pop up menu"); break; @@ -4908,11 +5040,33 @@ 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: + case IDM_Comment: if (commentUp && editComment) { CommentPopDown(); } else { @@ -4969,7 +5123,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_TypeInMove: - PopUpMoveDialog('\000'); + TypeInEvent('\000'); break; case IDM_TypeInName: @@ -4998,6 +5152,11 @@ 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(FALSE); break; @@ -5026,7 +5185,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FlipClock: flipClock = !flipClock; DisplayBothClocks(); - DrawPosition(FALSE, NULL); + DisplayLogos(); break; case IDM_MuteSounds: @@ -5054,7 +5213,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_Engine2Options: savedHwnd = hwnd; - if(WaitForSecond(SettingsMenuIfReady)) break; + if(WaitForEngine(&second, SettingsMenuIfReady)) break; EngineOptionsPopup(hwnd, &second); break; @@ -5062,6 +5221,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; @@ -5347,7 +5510,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_English: - barbaric = 0; + barbaric = 0; appData.language = ""; TranslateMenus(0); CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); CheckMenuItem(GetMenu(hwndMain), IDM_English, MF_BYCOMMAND|MF_CHECKED); @@ -5355,7 +5518,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; default: - if(wmId > IDM_English && wmId < IDM_English+5) { + 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); @@ -5563,7 +5729,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]) { @@ -5584,6 +5750,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; } @@ -5594,6 +5761,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; @@ -5775,6 +5943,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); @@ -6026,8 +6195,8 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 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); snprintf(buf, MSG_SIZ, "%s /icsport=%s", appData.icsHost, appData.icsPort); @@ -6063,11 +6232,14 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 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); - safeStrCpy(buf, "/scp=", sizeof(buf)/sizeof(buf[0]) ); + 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)) { @@ -6213,7 +6385,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) sizeY = newSizeY; } } - SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); + SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS ); return FALSE; case WM_COMMAND: /* message: received a command */ @@ -6262,13 +6434,19 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if( wParam == OPT_CommentText ) { MSGFILTER * lpMF = (MSGFILTER *) lParam; - if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) { + 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 @@ -6312,7 +6490,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); @@ -6353,9 +6531,6 @@ 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: @@ -6371,40 +6546,11 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: + 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 ) { - ToNrEvent(2*n-1); - EndDialog(hDlg, TRUE); - 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: @@ -6422,21 +6568,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); - } } /*---------------------------------------------------------------------------*\ @@ -6826,6 +6962,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); @@ -6859,7 +6996,8 @@ 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 + } // [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 */ @@ -6868,7 +7006,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM 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*/ + 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); } @@ -7145,10 +7283,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); @@ -7194,7 +7332,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 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; @@ -7374,7 +7512,7 @@ DisplayHoldingsCount(HDC hdc, int x, int y, int rightAlign, int copyNumber) HFONT oldFont; RECT rect; - if(copyNumber > 1) + if(copyNumber > 1) snprintf(buf, sizeof(buf)/sizeof(buf[0]),"%d", copyNumber); else buf[0] = 0; oldFg = SetTextColor(hdc, RGB(255, 255, 255)); /* white */ @@ -7406,6 +7544,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, COLORREF oldFg, oldBg; HFONT oldFont; + if (twoBoards && partnerUp) return; if (appData.clockMode) { if (tinyLayout) snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%c %s %s", color[0], TimeString(timeRemaining), flagFell); @@ -7432,7 +7571,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, rect, str, strlen(str), NULL); if(logoHeight > 0 && appData.clockMode) { RECT r; - snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s %s", buf+7, flagFell); + str += strlen(color)+2; r.top = rect->top + logoHeight/2; r.left = rect->left; r.right = rect->right; @@ -7737,6 +7876,22 @@ Enables gnuEnables[] = { { 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 } }; @@ -7754,10 +7909,13 @@ 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 } }; @@ -7793,11 +7951,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 }, @@ -7810,6 +7970,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 }, @@ -7846,7 +8007,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_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } @@ -7866,7 +8027,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_Match, MF_BYCOMMAND|MF_ENABLED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_ENABLED }, { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } @@ -7879,6 +8040,12 @@ Enables userThinkingEnables[] = { * \*---------------------------------------------------------------------------*/ VOID +CheckMark(UINT item, int state) +{ + if(item) CheckMenuItem(GetMenu(hwndMain), item, MF_BYCOMMAND|state); +} + +VOID ModeHighlight() { static UINT prevChecked = 0; @@ -7908,7 +8075,7 @@ ModeHighlight() nowChecked = IDM_MachineWhite; break; case TwoMachinesPlay: - nowChecked = matchMode ? IDM_Match : IDM_TwoMachines; // [HGM] match + nowChecked = IDM_TwoMachines; break; case AnalyzeMode: nowChecked = IDM_AnalysisMode; @@ -7939,12 +8106,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, @@ -7959,13 +8123,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 @@ -7973,8 +8136,8 @@ SetICSMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, icsEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), ICS_POS, - MF_BYPOSITION|MF_ENABLED); + EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), IDM_IcsOptions, + MF_BYCOMMAND|MF_ENABLED); #if ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); @@ -7996,8 +8159,6 @@ SetNCPMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, ncpEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), SOUNDS_POS, - MF_BYPOSITION|MF_GRAYED); DrawMenuBar(hwndMain); } @@ -8104,6 +8265,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; @@ -8463,7 +8625,19 @@ DisplayIcsInteractionTitle(char *str) char consoleTitle[MSG_SIZ]; snprintf(consoleTitle, MSG_SIZ, "%s: %s", szConsoleTitle, str); - SetWindowText(hwndConsole, consoleTitle); + 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 @@ -8507,7 +8681,7 @@ 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); } @@ -8553,6 +8727,12 @@ PlayAlarmSound() MyPlaySound(&sounds[(int)SoundAlarm]); } +VOID +PlayTellSound() +{ + MyPlaySound(&textAttribs[ColorTell].sound); +} + VOID EchoOn() @@ -8785,6 +8965,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". @@ -9044,6 +9255,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; @@ -9520,6 +9732,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) @@ -9709,11 +9927,11 @@ ScreenSquare(column, row, pt) int column; int row; POINT * pt; { if (flipView) { - pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap); - pt->y = lineGap + row * (squareSize + lineGap); + pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border; + pt->y = lineGap + row * (squareSize + lineGap) + border; } else { - pt->x = lineGap + column * (squareSize + lineGap); - pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap); + pt->x = lineGap + column * (squareSize + lineGap) + border; + pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border; } } @@ -9761,15 +9979,23 @@ Tween(start, mid, finish, factor, frames, nFrames) } void -HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current ) -{ - MoveHistorySet( movelist, first, last, current, pvInfoList ); - - EvalGraphSet( first, last, current, pvInfoList ); -} - -void SettingsPopUp(ChessProgramState *cps) { // [HGM] wrapper needed because handles must not be passed through back-end EngineOptionsPopup(savedHwnd, cps); } + +int flock(int fid, int code) +{ + HANDLE hFile = (HANDLE) _get_osfhandle(fid); + OVERLAPPED ov; + ov.hEvent = NULL; + ov.Offset = 0; + ov.OffsetHigh = 0; + switch(code) { + case 1: LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1024, 0, &ov); break; // LOCK_SH + case 2: LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1024, 0, &ov); break; // LOCK_EX + case 3: UnlockFileEx(hFile, 0, 1024, 0, &ov); break; // LOCK_UN + default: return -1; + } + return 0; +}