Add secondry adapter command for UCCI or USI
[xboard.git] / winboard / wsettings.c
index 43fcd06..0c92fbc 100644 (file)
@@ -12,6 +12,7 @@
 #include "config.h"\r
 \r
 #include <windows.h>\r
+#include <Windowsx.h>\r
 #include <stdio.h>\r
 #include <string.h>\r
 #include "common.h"\r
@@ -33,7 +34,7 @@ int breaks[MAX_OPTIONS];
 int checks, combos, buttons, layout, groups;\r
 char title[MSG_SIZ];\r
 char *engineName, *engineDir, *engineChoice, *engineLine, *nickName, *params;\r
-Boolean isUCI, hasBook, storeVariant, v1, addToList;\r
+Boolean isUCI, hasBook, storeVariant, v1, addToList, useNick, isUCCI;\r
 extern Option installOptions[], matchOptions[];\r
 char *engineNr[] = { N_("First"), N_("Second"), NULL };\r
 char *engineList[1000] = {" "}, *engineMnemonic[1000] = {""};\r
@@ -42,6 +43,7 @@ ChessProgramState *activeCps;
 Option *activeList;\r
 void InstallOK P((void));\r
 typedef void ButtonCallback(HWND h);\r
+ButtonCallback *comboCallback;\r
 \r
 void\r
 PrintOpt(int i, int right, Option *optionList)\r
@@ -160,6 +162,10 @@ LayoutOptions(int firstOption, int endOption, char *groupName, Option *optionLis
            breaks[layout/2] = lastType == Button ? 0 : 100;\r
            layoutList[layout++] = -1;\r
            layoutList[layout++] = nextOption - 1;\r
+           for(i=optionList[nextOption-1].min; i>0; i--) { // extra high text edit\r
+               layoutList[layout++] = -1;\r
+               layoutList[layout++] = -1;\r
+           }\r
        } else if(nextType == Spin) {\r
            // A spin will go in the next available position (right to left!). If it had to be prefixed with\r
            // a check or combo, this next position must be to the right, and the prefix goes left to it.\r
@@ -320,8 +326,8 @@ GetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)
 // read out all controls, and if value is altered, remember it and send it to the engine\r
 {\r
     HANDLE hwndCombo;\r
-    int i, k, new=0, changed=0;\r
-    char **choices, newText[MSG_SIZ], buf[MSG_SIZ];\r
+    int i, k, new=0, changed=0, len;\r
+    char **choices, newText[MSG_SIZ], buf[MSG_SIZ], *text;\r
     BOOL success;\r
 \r
     for(i=0; i<layout; i++) {\r
@@ -340,11 +346,16 @@ GetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)
            case TextBox:\r
            case FileName:\r
            case PathName:\r
-               success = GetDlgItemText( hDlg, 2001+2*i, newText, MSG_SIZ - strlen(optionList[j].name) - 9 );\r
+               if(cps) len = MSG_SIZ - strlen(optionList[j].name) - 9, text = newText;\r
+               else    len = GetWindowTextLength(GetDlgItem(hDlg, 2001+2*i)) + 1, text = (char*) malloc(len);\r
+               success = GetDlgItemText( hDlg, 2001+2*i, text, len );\r
                if(!success) break;\r
                if(!cps) {\r
-                   if(*(char**)optionList[j].target) free(*(char**)optionList[j].target);\r
-                   *(char**)optionList[j].target = strdup(newText);\r
+                   char *p;\r
+                   p = (optionList[j].type != FileName ? strdup(text) : InterpretFileName(text, homeDir)); // all files relative to homeDir!\r
+                   FREE(*(char**)optionList[j].target); *(char**)optionList[j].target = p;
+                   free(text); text = p;\r
+                   while(*p++ = *text++) if(p[-1] == '\r') p--; // crush CR\r
                    break;\r
                }\r
                changed = strcmp(optionList[j].textValue, newText) != 0;\r
@@ -386,10 +397,12 @@ GetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)
     if(!cps && okFunc) ((ButtonCallback*) okFunc)(0);\r
 }\r
 \r
+char *defaultExt[] = { NULL, "pgn", "fen", "exe", "trn", "bin", "log", "ini" };\r
+\r
 LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
     char buf[MSG_SIZ];\r
-    int i, j;\r
+    int i, j, ext;\r
 \r
     switch( message )\r
     {\r
@@ -407,12 +420,12 @@ LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
         case IDOK:\r
            GetOptionValues(hDlg, activeCps, activeList);\r
             EndDialog( hDlg, 0 );\r
-           activeCps = NULL;\r
+           comboCallback = NULL; activeCps = NULL;\r
             return TRUE;\r
 \r
         case IDCANCEL:\r
             EndDialog( hDlg, 1 );\r
-           activeCps = NULL;\r
+           comboCallback = NULL; activeCps = NULL;\r
             return TRUE;\r
 \r
        default:\r
@@ -422,15 +435,9 @@ LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
                j = layoutList[(i - 2000)/2];\r
                if(j == -2) {\r
                          char filter[] =\r
-                               "All files\0*.*\0BIN Files\0*.bin\0LOG Files\0*.log\0INI Files\0*.ini\0\0";\r
-/*\r
-{\r
-                             'A','l','l',' ','F','i','l','e','s', 0,\r
-                             '*','.','*', 0,\r
-                             'B','I','N',' ','F','i','l','e','s', 0,\r
-                             '*','.','b','i','n', 0,\r
-                             0 };\r
-*/\r
+                               "All files\0*.*\0Game files\0*.pgn;*.gam\0Position files\0*.fen;*.epd;*.pos\0"\r
+                               "EXE files\0*.exe\0Tournament files (*.trn)\0*.trn\0"\r
+                               "BIN Files\0*.bin\0LOG Files\0*.log\0INI Files\0*.ini\0\0";\r
                          OPENFILENAME ofn;\r
 \r
                          safeStrCpy( buf, "" , sizeof( buf)/sizeof( buf[0]) );\r
@@ -441,6 +448,8 @@ LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
                          ofn.hwndOwner = hDlg;\r
                          ofn.hInstance = hInst;\r
                          ofn.lpstrFilter = filter;\r
+                         ofn.nFilterIndex      = 1L + (ext = activeCps ? 0 : activeList[layoutList[(i-2000)/2+1]].max);\r
+                         ofn.lpstrDefExt       = defaultExt[ext];\r
                          ofn.lpstrFile = buf;\r
                          ofn.nMaxFile = sizeof(buf);\r
                          ofn.lpstrTitle = _("Choose File");\r
@@ -456,6 +465,10 @@ LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
                    }\r
                }\r
                if(j < 0) break;\r
+               if(comboCallback && activeList[j].type == ComboBox && HIWORD(wParam) == CBN_SELCHANGE) {\r
+                   (*comboCallback)(hDlg);\r
+                   break;\r
+               } else\r
                if( activeList[j].type  == SaveButton)\r
                     GetOptionValues(hDlg, activeCps, activeList);\r
                else if( activeList[j].type  != Button) break;\r
@@ -492,6 +505,7 @@ void AddControl(int x, int y, int w, int h, int type, int style, int n)
 \r
 void AddOption(int x, int y, Control type, int i)\r
 {\r
+    int extra;\r
 \r
     switch(type) {\r
        case Slider:\r
@@ -501,7 +515,9 @@ void AddOption(int x, int y, Control type, int i)
            break;\r
        case TextBox:\r
            AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
-           AddControl(x+95, y, 200, 11, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
+           extra = 13*activeList[layoutList[i/2]].min;\r
+           AddControl(x+95, y, 200, 11+extra, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | \r
+                                                               (extra ? ES_MULTILINE | WS_VSCROLL :0), i+1);\r
            break;\r
        case Label:\r
            extra = activeList[layoutList[i/2]].value;\r
@@ -595,7 +611,8 @@ EngineOptionsPopup(HWND hwnd, ChessProgramState *cps)
 }\r
 \r
 void InstallOK()\r
-{\r
+{
+    if(isUCCI) isUCI = 2;\r
     if(engineChoice[0] == engineNr[0][0])  Load(&first, 0); else Load(&second, 1);\r
 }\r
 \r
@@ -603,11 +620,13 @@ Option installOptions[] = {
   {   0,  0,    0, NULL, (void*) &engineLine, (char*) engineMnemonic, engineList, ComboBox, N_("Select engine from list:") },\r
   {   0,  0,    0, NULL, NULL, NULL, NULL, Label, N_("or specify one below:") },\r
   {   0,  0,    0, NULL, (void*) &nickName, NULL, NULL, TextBox, N_("Nickname (optional):") },\r
-  {   0,  0,    3, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine Executable:") },\r
-  {   0,  0,    0, NULL, (void*) &params, NULL, NULL, TextBox, N_("Engine command-line Parameters:") },\r
-  {   0,  0,    0, NULL, (void*) &engineDir, NULL, NULL, PathName, N_("Engine Directory:") },\r
+  {   0,  0,    0, NULL, (void*) &useNick, NULL, NULL, CheckBox, N_("Use nickname in PGN tag") },\r
+  {   0,  0,    3, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine (*.exe):") },\r
+  {   0,  0,    0, NULL, (void*) &params, NULL, NULL, TextBox, N_("command-line parameters:") },\r
+  {   0,  0,    0, NULL, (void*) &engineDir, NULL, NULL, PathName, N_("directory:") },\r
   {  95,  0,    0, NULL, NULL, NULL, NULL, Label, N_("(Directory will be derived from engine path when empty)") },\r
   {   0,  0,    0, NULL, (void*) &isUCI, NULL, NULL, CheckBox, N_("UCI") },\r
+  {   0,  0,    0, NULL, (void*) &isUCCI, NULL, NULL, CheckBox, N_("UCCI / USI (uses specified /uxiAdapter)") },\r
   {   0,  0,    0, NULL, (void*) &v1, NULL, NULL, CheckBox, N_("WB protocol v1 (skip waiting for features)") },\r
   {   0,  0,    0, NULL, (void*) &addToList, NULL, NULL, CheckBox, N_("Add this engine to the list") },\r
   {   0,  0,    0, NULL, (void*) &hasBook, NULL, NULL, CheckBox, N_("Must not use GUI book") },\r
@@ -638,15 +657,73 @@ void LoadEnginePopUp(HWND hwnd)
 {\r
     int n=0;\r
 \r
-    isUCI = addToList = storeVariant = v1 = FALSE; hasBook = TRUE; // defaults\r
+    isUCI = isUCCI = storeVariant = v1 = useNick = FALSE; addToList = hasBook = TRUE; // defaults\r
     if(engineDir)    free(engineDir);    engineDir = strdup("");\r
     if(params)       free(params);       params = strdup("");\r
     if(nickName)     free(nickName);     nickName = strdup("");\r
     if(engineChoice) free(engineChoice); engineChoice = strdup(engineNr[0]);\r
     if(engineLine)   free(engineLine);   engineLine = strdup("");\r
+    if(engineName)   free(engineName);   engineName = strdup("");\r
     NamesToList(firstChessProgramNames, engineList, engineMnemonic);\r
     while(engineList[n]) n++; installOptions[0].max = n;\r
     snprintf(title, MSG_SIZ, _("Load Engine"));\r
 \r
     GenericPopup(hwnd, installOptions);\r
 }\r
+\r
+Boolean autoinc, twice;\r
+\r
+void MatchOK()\r
+{\r
+    if(autoinc) appData.loadGameIndex = appData.loadPositionIndex = -(twice + 1);\r
+    if(appData.participants) free(appData.participants);\r
+    appData.participants = strdup(engineName);\r
+    if(CreateTourney(appData.tourneyFile)) MatchEvent(2); \r
+//     ScheduleDelayedEvent(MatchEvent(2), 10); // start tourney\r
+}\r
+\r
+Option tourneyOptions[] = {\r
+  { 0,  0,          4, NULL, (void*) &appData.tourneyFile, "", NULL, FileName, N_("Tournament file:") },\r
+  { 0,  1,          0, NULL, (void*) &engineChoice, (char*) (engineMnemonic+1), (engineMnemonic+1), ComboBox, N_("Select Engine:") },\r
+  { 0xD, 7,         0, NULL, (void*) &engineName, "", NULL, TextBox, "Tourney participants:" },\r
+  { 0,  0,         10, NULL, (void*) &appData.tourneyType, "", NULL, Spin, N_("Tourney type (0=RR, 1=gauntlet):") },\r
+  { 0,  0,          0, NULL, (void*) &appData.cycleSync, "", NULL, CheckBox, N_("Sync after cycle") },\r
+  { 0,  1, 1000000000, NULL, (void*) &appData.tourneyCycles, "", NULL, Spin, N_("Number of tourney cycles:") },\r
+  { 0,  0,          0, NULL, (void*) &appData.roundSync, "", NULL, CheckBox, N_("Sync after round") },\r
+  { 0,  1, 1000000000, NULL, (void*) &appData.defaultMatchGames, "", NULL, Spin, N_("Games per Match / Pairing:") },\r
+  { 0,  0,          1, NULL, (void*) &appData.saveGameFile, "", NULL, FileName, N_("File for saving tourney games:") },\r
+  { 0,  0,          1, NULL, (void*) &appData.loadGameFile, "", NULL, FileName, N_("Game File with Opening Lines:") },\r
+  { 0, -2, 1000000000, NULL, (void*) &appData.loadGameIndex, "", NULL, Spin, N_("Game Number:") },\r
+  { 0,  0,          2, NULL, (void*) &appData.loadPositionFile, "", NULL, FileName, N_("File with Start Positions:") },\r
+  { 0, -2, 1000000000, NULL, (void*) &appData.loadPositionIndex, "", NULL, Spin, N_("Position Number:") },\r
+  { 0,  0,          0, NULL, (void*) &autoinc, "", NULL, CheckBox, N_("Step through lines/positions in file") },\r
+  { 0,  0, 1000000000, NULL, (void*) &appData.rewindIndex, "", NULL, Spin, N_("Rewind after (0 = never):") },\r
+  { 0,  0,          0, NULL, (void*) &twice, "", NULL, CheckBox, N_("Use each line/position twice") },\r
+  { 0,  0, 1000000000, NULL, (void*) &appData.matchPause, "", NULL, Spin, N_("Pause between Games (ms):") },\r
+  { 0, 0, 0, NULL, (void*) &MatchOK, "", NULL, EndMark , "" }\r
+};\r
+\r
+void AddToTourney(HWND hDlg)\r
+{\r
+    char buf[MSG_SIZ];\r
+//    GetDlgItemText( hDlg, 2001+2*3, buf, MSG_SIZ-3 ); // this gives the previous selection !!!\r
+//    strncat(buf, "\r\n", MSG_SIZ);\r
+    int i = ComboBox_GetCurSel(GetDlgItem(hDlg, 2001+2*3));\r
+    snprintf(buf, MSG_SIZ, "%s\r\n", engineMnemonic[i+1]);\r
+    SendMessage( GetDlgItem(hDlg, 2001+2*5), EM_SETSEL, 99999, 99999 );\r
+    SendMessage( GetDlgItem(hDlg, 2001+2*5), EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) buf );\r
+}\r
+\r
+void TourneyPopup(HWND hwnd)\r
+{\r
+    int n=0;\r
+\r
+    NamesToList(firstChessProgramNames, engineList, engineMnemonic);\r
+    comboCallback = &AddToTourney;\r
+    autoinc = appData.loadGameIndex < 0 || appData.loadPositionIndex < 0;\r
+    twice = TRUE;\r
+    while(engineList[n]) n++; tourneyOptions[1].max = n-1;\r
+    snprintf(title, MSG_SIZ, _("Tournament and Match Options"));\r
+\r
+    GenericPopup(hwnd, tourneyOptions);\r
+}\r