home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / gchsrc31 / atarigui.cc next >
C/C++ Source or Header  |  1992-04-27  |  20KB  |  882 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is part of the Atari graphical interface for GNU Chess,
  4. //  and is Copyright 1992 by Warwick W. Allison.
  5. //
  6. //  You are free to copy and modify these sources, provided you acknowledge
  7. //  the origin by retaining this notice, and adhere to the conditions
  8. //  of the CHESS General Public License described in the main chess file
  9. //  gnuchess.cc.
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12.  
  13. #include <builtin.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <signal.h>
  18. #include <sys/param.h>
  19. #include <sys/types.h>
  20. #include <sys/file.h>
  21.  
  22. static char* ColorStr[2] = {"White", "Black"};
  23.  
  24. #include "gnuchess.h"
  25. #include "uisupport.h"
  26. #include "ui.h"
  27.  
  28. #define pxx " PNBRQK"
  29. #define qxx " pnbrqk"
  30.  
  31. #define RV(x) (WhiteFromTop ? 7-(x) : (x))
  32.  
  33. #include <osbind.h>
  34. #include <bool.h>
  35. #include <DoubleBuffer.h>
  36. #include <MousePosition.h>
  37. #include <EasySprite.h>
  38. #include <Screen.h>
  39. #include <Resolution.h>
  40.  
  41. #include "Cursor.h"
  42. #include "Buttons.h"
  43. #include "Piece.h"
  44. #include "Beeps.h"
  45. #include "Timer.h"
  46. #include "Help.h"
  47.  
  48. const int BoardX=127;
  49. const int BoardY=5;
  50. const int SquareWidth=24;
  51. const int SquareHeight=23;
  52.  
  53. const int FeatureX=0;
  54. const int FeatureY=95;
  55. const int FeatureW=8;
  56. const int FeatureH=15;
  57.  
  58. const int PiecesX=96;
  59. const int PiecesY=5;
  60. const int PiecesW=12;
  61. const int PiecesH=15;
  62.  
  63. static bool WhiteFromTop=FALSE;
  64. static char CurrentFilename[100]="gnuchess.sav";
  65. static int CurrentColour=white;
  66. static Sprite* SquareHighlight;
  67. static Sprite* FeatureLight;
  68. static bool DoShowLegalMoves=TRUE;
  69. static bool DoReverseTheArrow=TRUE;
  70. static bool DoAnimateComputerMoves=TRUE;
  71. static bool DoShowContextHelp=TRUE;
  72. static bool ComputerIsBlack=TRUE;
  73. static int CheckMate=0;
  74. char* const ConfigFile="gnuchess.cnf";
  75. char AlgebraicName[8][8][4];
  76.  
  77. void SetAlgebraicNames()
  78. {
  79.     for (int y=0; y<8; y++) {
  80.         for (int x=0; x<8; x++) {
  81.             AlgebraicName[x][y][0]=RV(x)+'a';
  82.             AlgebraicName[x][y][1]='8'-RV(y);
  83.             AlgebraicName[x][y][2]=0;
  84.         }
  85.     }
  86. }
  87.  
  88. void LoadCNF()
  89. {
  90.     FILE* fd=fopen(ConfigFile,"r");
  91.  
  92.     if (fd) {
  93.         fscanf(fd,"%d %d %d %d",
  94.             &DoShowLegalMoves,
  95.             &DoReverseTheArrow,
  96.             &DoAnimateComputerMoves,
  97.             &DoShowContextHelp);
  98.         fclose(fd);
  99.     }
  100. }
  101.  
  102. void SaveCNF()
  103. {
  104.     FILE* fd=fopen(ConfigFile,"w");
  105.  
  106.     if (fd) {
  107.         fprintf(fd,"%d %d %d %d (Show legal, Arrow rev, Move animate, Help)\n",
  108.             DoShowLegalMoves,
  109.             DoReverseTheArrow,
  110.             DoAnimateComputerMoves,
  111.             DoShowContextHelp);
  112.         fclose(fd);
  113.     }
  114. }
  115.  
  116. bool XYScreenToBoard(int X,int Y,int& x,int& y)
  117. {
  118.     x=X-BoardX;
  119.     y=Y-BoardY;
  120.     if (x<0 || y<0) return 0;
  121.  
  122.     x=x/SquareWidth;
  123.     y=7-y/SquareHeight;
  124.  
  125.     if (WhiteFromTop) { x=7-x; y=7-y; }
  126.  
  127.     return x<8 && y<8;
  128. }
  129.  
  130. bool XYCursorToBoard(int& x,int& y)
  131. {
  132.     x=Cursor->X();
  133.     y=Cursor->Y();
  134.     //CorrectForCursor(x,y);
  135.  
  136.     x-=BoardX;
  137.     y-=BoardY;
  138.     if (x<0 || y<0) return FALSE;
  139.  
  140.     x=x/SquareWidth;
  141.     y=y/SquareHeight;
  142.  
  143.     if (x>=8 && y>=8) return FALSE;
  144.  
  145.     y=7-y;
  146.  
  147.     if (WhiteFromTop) { x=7-x; y=7-y; }
  148.  
  149.     return TRUE;
  150. }
  151.  
  152. void XYBoardToScreen(int X,int Y,int& x,int& y,bool Rev)
  153. {
  154.     if (Rev) { X=7-X; Y=7-Y; }
  155.     x=BoardX+X*SquareWidth;
  156.     y=BoardY+(7-Y)*SquareHeight;
  157. }
  158.  
  159. void SetCursorShape(bool FromBottom)
  160. {
  161.     if (FromBottom || !DoReverseTheArrow) {
  162.         Cursor->ShapeTo(0);
  163.         Mouse.Bound(0,0,320-11,200-16);
  164.     } else {
  165.         Cursor->ShapeTo(1);
  166.         Mouse.Bound(11,15,320-16,200-16);
  167.     }
  168. }
  169.  
  170. void ShowFeatures()
  171. {
  172.     for (int x=0; x<4; x++) {
  173.         bool Now;
  174.  
  175.         switch (x) {
  176.          case 0:
  177.             Now=DoShowLegalMoves;
  178.         break; case 1:
  179.             Now=DoReverseTheArrow;
  180.         break; case 2:
  181.             Now=DoAnimateComputerMoves;
  182.         break; case 3:
  183.             Now=DoShowContextHelp;
  184.         break; default:
  185.             Now=FALSE;
  186.         }
  187.  
  188.         FeatureLight->ShapeTo(Now);
  189.         FeatureLight->MoveTo(x*FeatureW+FeatureX,FeatureY);
  190.         FeatureLight->Draw();
  191.         Pages->Flip();
  192.         FeatureLight->Draw();
  193.         Pages->Flop();
  194.     }
  195. }
  196.  
  197.  
  198. ResolutionChange *OriginalResolution;
  199. Screen *OriginalScreen;
  200.  
  201. void ui_Initialize()
  202. {
  203.     LoadCNF();
  204.  
  205.     Mouse.Bound(0,0,320-16,200-16);
  206.     Mouse.MoveTo(160,100);
  207.  
  208.     // Load images, sprites, etc.
  209.     OriginalResolution=new ResolutionChange(STLow);
  210.     OriginalScreen=new Screen(DESKSCREEN);
  211.  
  212.     // Set-up DoubleBuffer (must be done before all sprite stuff)
  213.     Screen *This=new Screen;
  214.     This->LoadCrackArt("pic\\scene.ca1");
  215.     Screen *That=new Screen(*This);
  216.     Pages=new DoubleBuffer(*This,*That);
  217.     This->ShowPalette();
  218.     Pages->Flop();
  219.  
  220.     Screen ImageBank;
  221.     ImageBank.LoadCrackArt("pic\\sprites.ca1");
  222.     InitPiece(ImageBank);
  223.     InitCursor(ImageBank);
  224.     InitClock(ImageBank);
  225.     InitButtons(ImageBank);
  226.  
  227.     // The following implemented with EasySprites
  228.     SquareHighlight=GetSprite(ImageBank,288,117,SquareHeight,SP_WIDE|SP_COLOUR);
  229.  
  230.     FeatureLight=GetSprite(ImageBank,304,158,4,SP_COLOUR,2,0,4);
  231.     ShowFeatures();
  232.  
  233.  
  234.     // Help
  235.     //  Edit pieces
  236.     AddHelp(PiecesX,PiecesY,PiecesW*2,PiecesH*6,"Pieces - for editing");
  237.     AddHelp(PiecesX,PiecesY+PiecesH*6,PiecesW,PiecesH,"Blank piece");
  238.     AddHelp(PiecesX+PiecesW,PiecesY+PiecesH*6,PiecesW,PiecesH,"Blank board");
  239.  
  240.     //  Features
  241.     AddHelp(FeatureX+FeatureW*0,FeatureY,FeatureW,FeatureH,"Show legal moves");
  242.     AddHelp(FeatureX+FeatureW*1,FeatureY,FeatureW,FeatureH,"Reversible arrow");
  243.     AddHelp(FeatureX+FeatureW*2,FeatureY,FeatureW,FeatureH,"Animate CPU moves");
  244.     AddHelp(FeatureX+FeatureW*3,FeatureY,FeatureW,FeatureH,"Show this help");
  245.  
  246.     //  Messages
  247.     AddHelp(37,126,13,15,"GNU's Not Unix");
  248.     AddHelp(66,176,57,5,"warwick@cs.uq.oz.au");
  249.  
  250.     //  Clock
  251.     AddHelp(32,95,64,15,"Play timer");
  252.  
  253.     //  Algebraic names
  254.     SetAlgebraicNames();
  255.     for (int y=0; y<8; y++) {
  256.         for (int x=0; x<8; x++) {
  257.             AddHelp(BoardX+x*SquareWidth,BoardY+y*SquareHeight,SquareWidth,SquareHeight,AlgebraicName[x][y]);
  258.         }
  259.     }
  260.  
  261.     //  Context-free help messages
  262.     AddHelp(9999,0,1,1,"Choose promotion");
  263. }
  264.  
  265. void ui_Finalize()
  266. {
  267.     // delete stuff, restore resources
  268.     OriginalScreen->ShowPalette();
  269.     OriginalScreen->Show();
  270.     delete OriginalScreen;
  271.     delete OriginalResolution;
  272. }
  273.  
  274. void ui_GiveHelp (int compiswhite,int level,int easy,int maxdep,int dither,int hash)
  275. {
  276.     OriginalScreen->Show();
  277.     OriginalScreen->ShowPalette();
  278.     ResolutionChange MediumForThisTextStuff(STMedium);
  279.  
  280.     while (1) {
  281.         printf("\033E");
  282.  
  283.         printf("GNU Chess v3.1 - Atari port (version 1) by Warwick Allison\n\n");
  284.         printf("Current filename: %s\n\n",CurrentFilename);
  285.         printf("\nInformation items:\n");
  286.         printf("W = Warranty information\n");
  287.         printf("C = Copying policy\n");
  288.         printf("L = Level descriptions\n");
  289.         printf("A = Acknowledgements\n");
  290.         printf("N = Notes\n");
  291.         printf("F = Current filename\n");
  292.         printf("\n\nChoose function, or click to return\n");
  293.  
  294.         while (!Mouse.LeftButton() && !Mouse.RightButton() && !Cconis());
  295.         printf("\033E");
  296.         if (Cconis()) {
  297.             char ch=Cnecin();
  298.             switch (toupper(ch)) {
  299.                 case 'F':
  300.                     char NewFilename[256];
  301.                     printf("Current filename = %s\n",CurrentFilename);
  302.                     printf("New filename: \033e"); // Cursor on
  303.                     gets(NewFilename);
  304.                     if (NewFilename[0]) strcpy(CurrentFilename,NewFilename);
  305.                     printf("\033f\n"); // Cursor off
  306.                     printf("Current filename = %s\n",CurrentFilename);
  307.             break; case 'C':
  308.                     printf("GNU Chess is Copyright 1992 by the Free Software Federation,\n");
  309.                     printf("         and Copyright 1992 by John Stanback.\n\n");
  310.                     printf("The Atari graphical interface sources are Copyright 1992\n");
  311.                     printf("         by Warwick W. Allison.\n\n");
  312.                     printf("GNU Chess, and this port, are licensed free of charge.  For full details,\n");
  313.                     printf("read the file COPYING, which should have been included with this program.\n\n");
  314.             break; case 'A':
  315.                     printf("You can thank these people:\n\n");
  316.                     printf("  John Stanback, and all the other GNUChess authors,\n");
  317.                     printf("  The GNU crowd for G++,\n");
  318.                     printf("  Jwahar Bammi for [repeatedly] porting G++ to the ST,\n");
  319.                     printf("  and the Beta Testers:\n");
  320.                     printf("    Mika Kukkonen, Joshua Kronengold, Doug Shaw, Clive Salvidge.\n");
  321.             break; case 'W':
  322.                     printf("                               NO WARRANTY\n\n");
  323.                     printf("BECAUSE GNU CHESS IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO\n");
  324.                     printf("WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.\n\n");
  325.                     printf("For full details, read the file called COPYING, which should have been with\n");
  326.                     printf("this program.\n");
  327.             break; case 'N':
  328.                     printf("Load & Save use the current filename.\n");
  329.                     printf("If the variable $HOME is set, it saves there rather than the current directory.\n\n");
  330.                     printf("Book disable stops the computer from using \"canned\" moves to start the game.\n");
  331.             break; case 'l': case 'L':
  332.                     printf(" 1.   60 moves in   5 minutes\n");
  333.                     printf(" 2.   60 moves in  15 minutes\n");
  334.                     printf(" 3.   60 moves in  30 minutes\n");
  335.                     printf(" 4.   40 moves in  30 minutes\n");
  336.                     printf(" 5.   40 moves in  60 minutes\n");
  337.                     printf(" 6.   40 moves in 120 minutes\n");
  338.                     printf(" 7.   40 moves in 240 minutes\n");
  339.                     printf(" 8.    1 move  in  15 minutes\n");
  340.                     printf(" 9.    1 move  in  60 minutes\n");
  341.                     printf("10.    1 move  in 600 minutes\n");
  342.             }
  343.             while (!Mouse.LeftButton() && !Mouse.RightButton() && !Cconis());
  344.             if (Cconis()) Cnecin();
  345.             else break;
  346.         } else break;
  347.     }
  348.     Pages->Current().ShowPalette();
  349.     Pages->Flip();
  350.     while (Mouse.LeftButton() || Mouse.RightButton());
  351.     if (Cconis()) Cnecin();
  352. }
  353.  
  354. void ui_ShowEditHelp()
  355. {
  356. }
  357.  
  358. static CurrentEditColour=0;
  359. void ui_ShowEditColor(int col)
  360. {
  361.     CurrentEditColour=col;
  362. }
  363.  
  364. int ChoosePiece(int& P)
  365. {
  366.     int x=Cursor->X();
  367.     int y=Cursor->Y();
  368.  
  369.     x-=PiecesX;
  370.     y-=PiecesY;
  371.  
  372.     if (x<0 || y<0) return 0;
  373.  
  374.     x/=PiecesW;
  375.     y/=PiecesH;
  376.  
  377.     if (y==6) {
  378.         switch (x) {
  379.          case 0: P=0; return 0;
  380.         break;    case 1: return 2;
  381.         }
  382.     } else if (x>=0 && x<=1 && y>=0 && y<=5) {
  383.         int NewCol;
  384.         if (y>=3) {
  385.             NewCol=black;
  386.             y-=3;
  387.         } else {
  388.             NewCol=white;
  389.         }
  390.         P=1+x+y*2;
  391.         int TmpColour=CurrentEditColour;
  392.         CurrentEditColour=NewCol;
  393.         return NewCol!=TmpColour;
  394.     }
  395.  
  396.     return 0;
  397. }
  398.  
  399. void ui_GetPieceAndLocation(char *s)
  400. {
  401.     static int CurrentPiece=0;
  402.     bool done=FALSE;
  403.     int x,y;
  404.  
  405.     while (!done) {
  406.         Cursor->Wipe();
  407.         Cursor->MoveTo(Mouse.X(),Mouse.Y());
  408.         if (DoShowContextHelp) ShowContextHelp(Cursor->X(), Cursor->Y());
  409.  
  410.         if (Mouse.LeftButton()) {
  411.             if (XYCursorToBoard(x,y)) {
  412.                 s[0]=pxx[CurrentPiece];
  413.                 s[1]='a'+x;
  414.                 s[2]='1'+y;
  415.                 s[3]=0;
  416.                 done=TRUE;
  417.             } else {
  418.                 switch (ChoosePiece(CurrentPiece)) {
  419.                     case 0:
  420.                 break;    case 1:
  421.                     s[0]='C';
  422.                     s[1]=0;
  423.                     done=TRUE;
  424.                 break;    case 2:
  425.                     s[0]='#';
  426.                     s[1]=0;
  427.                     done=TRUE;
  428.                 break;    case 3:
  429.                     s[0]='.';
  430.                     s[1]=0;
  431.                     done=TRUE;
  432.                 }
  433.             }
  434.             while (Mouse.LeftButton());
  435.         } else if (Mouse.RightButton()) {
  436.             s[0]='.';
  437.             s[1]=0;
  438.             done=TRUE;
  439.             while (Mouse.RightButton());
  440.         }
  441.  
  442.         if (!done) Cursor->Draw();
  443.         Pages->Flip();
  444.     }
  445.     Cursor->Wipe();
  446. }
  447.  
  448. bool OnBoard(int x, int y)
  449. {
  450.     return (x>=0 && x<=7 && y>=0 && y<=7);
  451. }
  452.  
  453. void AnimateMove(int Speed,int ifx,int ify,int itx,int ity)
  454. {
  455.     XYBoardToScreen(ifx,ify,ifx,ify,FALSE);
  456.     XYBoardToScreen(itx,ity,itx,ity,FALSE);
  457.  
  458.     double fx=ifx+SquareWidth/2;
  459.     double fy=ify+SquareHeight/2;
  460.     double tx=itx+SquareWidth/2;
  461.     double ty=ity+SquareHeight/2;
  462.  
  463.     double dx=(tx-fx)/Speed;
  464.     double dy=(ty-fy)/Speed;
  465.  
  466.     while (--Speed) {
  467.         Cursor->Wipe();
  468.         Cursor->MoveTo((int)fx,(int)fy);
  469.         Cursor->Draw();
  470.         Pages->Flip();
  471.         fx+=dx;
  472.         fy+=dy;
  473.     }
  474.     Cursor->Wipe();
  475.     Pages->Flop();
  476.     Cursor->Wipe();
  477. }
  478.  
  479. void ui_ShowComputerMove(char *move, int feature)
  480. {
  481.     if (DoAnimateComputerMoves) {
  482.         int ifx=move[0]-'a';
  483.         int ify=move[1]-'1';
  484.         int itx=move[2]-'a';
  485.         int ity=move[3]-'1';
  486.  
  487.         if (!OnBoard(ifx,ify) || !OnBoard(itx,ity)) return;
  488.  
  489.         Cursor->ShapeTo(RankAt(itx,ity) + (CurrentColour==white ? 3 : 9));
  490.  
  491.         if (WhiteFromTop) {
  492.             ifx=7-ifx; ify=7-ify;
  493.             itx=7-itx; ity=7-ity;
  494.         }
  495.  
  496.         ui_DrawPiece(FALSE,(ifx^ify)&2,ifx,ify,no_piece);
  497.         AnimateMove(45,ifx,ify,itx,ity);
  498.     }
  499.  
  500.     switch (feature) {
  501.      case 1:; // Draw
  502.     break; case 2:
  503.         CheckMate=1;
  504.     break; case 3:
  505.         CheckMate=2;
  506.     break; case 4:; // Near win
  507.     break; case 5:; // Near loss
  508.     }
  509. }
  510.  
  511. void ui_DrawPiece(bool used, bool isblack, int x, int y, int piece)
  512. {
  513.     //ui_DrawSquare(x,y,(x+y)%2);
  514.  
  515.     Piece->Colour((x+y)%2 ? FALSE : TRUE);
  516.  
  517.     XYBoardToScreen(x,y,x,y,FALSE);
  518.  
  519.     // Middle of square
  520.     x+=SquareWidth/2;
  521.     y+=SquareHeight/2;
  522.  
  523.     Piece->Rank(no_piece);
  524.     Pages->Flop();
  525.     Piece->Draw(x,y);
  526.     Pages->Flop();
  527.     Piece->Draw(x,y);
  528.  
  529.     if (used) {
  530.         Piece->Rank(piece);
  531.         Piece->Colour(isblack);
  532.         Pages->Flop();
  533.         Piece->Draw(x,y);
  534.         Pages->Flop();
  535.         Piece->Draw(x,y);
  536.     }
  537. }
  538.  
  539. void ui_DrawSquare(int x, int y, bool isblack)
  540. {
  541. }
  542.  
  543. void ui_GetFilename(char *prompt,char *name)
  544. {
  545.     strcpy(name,CurrentFilename);
  546. }
  547.  
  548. void ui_LoadDone()
  549. {
  550.     //Chime();
  551. }
  552.  
  553. void ui_LoadFailed()
  554. {
  555.     Raspberry();
  556. }
  557.  
  558. void ui_SaveDone()
  559. {
  560.     //Chime();
  561. }
  562.  
  563. void ui_SaveFailed()
  564. {
  565.     Raspberry();
  566. }
  567.  
  568. void ui_ChangeLevel(int *newlevel)
  569. {
  570.     *newlevel=MyLevel;
  571. }
  572.  
  573. bool ToggleFeature(int x,int y)
  574. {
  575.     x-=FeatureX;
  576.     y-=FeatureY;
  577.  
  578.     if (x<0 || y<0) return FALSE;
  579.  
  580.     x/=FeatureW;
  581.     y/=FeatureH;
  582.  
  583.     if (y) return FALSE;
  584.  
  585.     bool Now;
  586.  
  587.     switch (x) {
  588.      case 0:
  589.         Now=DoShowLegalMoves=!DoShowLegalMoves;
  590.     break; case 1:
  591.         Now=DoReverseTheArrow=!DoReverseTheArrow;
  592.         SetCursorShape(ComputerIsBlack^WhiteFromTop);
  593.     break; case 2:
  594.         Now=DoAnimateComputerMoves=!DoAnimateComputerMoves;
  595.     break; case 3:
  596.         Now=DoShowContextHelp=!DoShowContextHelp;
  597.     break; default:
  598.         return FALSE;
  599.     }
  600.  
  601.     FeatureLight->ShapeTo(Now);
  602.     FeatureLight->MoveTo(x*FeatureW+FeatureX,FeatureY);
  603.     FeatureLight->Draw();
  604.     Pages->Flip();
  605.     Cursor->Wipe();
  606.     FeatureLight->Draw();
  607.     Cursor->Draw();
  608.     Pages->Flop();
  609.  
  610.     return TRUE;
  611. }
  612.  
  613. int ChoosePromotion()
  614. {
  615.     int P=0;
  616.     bool done=FALSE;
  617.     int x,y;
  618.  
  619.     Mouse.MoveTo(108,50);
  620.  
  621.     while (Mouse.LeftButton());
  622.  
  623.     while (!done) {
  624.         Cursor->Wipe();
  625.         Cursor->MoveTo(Mouse.X(),Mouse.Y());
  626.         if (DoShowContextHelp) ShowContextHelp(9999,0);
  627.  
  628.         if (Mouse.LeftButton()) {
  629.             ChoosePiece(P);
  630.             done=TRUE;
  631.             while (Mouse.LeftButton());
  632.         }
  633.  
  634.         if (!done) Cursor->Draw();
  635.         Pages->Flip();
  636.     }
  637.     Cursor->Wipe();
  638.  
  639.     return P;
  640. }
  641.  
  642. void ui_GetMove(char *s)
  643. {
  644.     bool done=FALSE;
  645.     bool from=TRUE;
  646.     bool WaitingFor=TRUE;
  647.     bool Legal,Moved=FALSE;
  648.  
  649.     int fromx=0,fromy=0,tox,toy,FromMouseX,FromMouseY;
  650.  
  651.     if (Cconis()) Cnecin();
  652.     ReleaseButton();
  653.  
  654.     while (!done) {
  655.         Cursor->Wipe();
  656.         SquareHighlight->Wipe();
  657.         Cursor->MoveTo(Mouse.X(),Mouse.Y());
  658.  
  659.         if (DoShowContextHelp) ShowContextHelp(Cursor->X(), Cursor->Y());
  660.         else NoHelp();
  661.  
  662.         Legal=FALSE;
  663.         if (!CheckMate && XYCursorToBoard(tox,toy)) {
  664.             if (!from &&
  665.                abs(FromMouseX-Cursor->X())
  666.               +abs(FromMouseY-Cursor->Y()) > 4) {
  667.                 Moved = TRUE;
  668.             }
  669.             
  670.             if (!from && DoShowLegalMoves && (LegalMove(tox,toy) || tox==fromx && toy==fromy)) {
  671.                 int x,y;
  672.                 XYBoardToScreen(tox,toy,x,y,WhiteFromTop);
  673.                 SquareHighlight->MoveTo(x,y);
  674.                 Legal=TRUE;
  675.             }
  676.             if (Mouse.LeftButton()==WaitingFor) {
  677.                 if (from) {
  678.                     if (ColourAt(tox,toy)==CurrentColour) {
  679.                         FromMouseX=Cursor->X();
  680.                         FromMouseY=Cursor->Y();
  681.                         fromx=tox;
  682.                         fromy=toy;
  683.                         from=FALSE;
  684.                         Pages->Flop();
  685.                         Cursor->Wipe();
  686.                         SquareHighlight->Wipe();
  687.                         ui_DrawPiece(false,(fromx^fromy)%2,RV(fromx),RV(fromy),no_piece);
  688.                         Cursor->ShapeTo(RankAt(fromx,fromy) + (CurrentColour==white ? 3 : 9));
  689.                         Mouse.Bound(BoardX+6,BoardY+10,SquareWidth*8-11,SquareHeight*8-20);
  690.                         CalculateLegalMoves(fromx,fromy);
  691.                     }
  692.                     WaitingFor=!WaitingFor;
  693.                 } else {
  694.                     WaitingFor=TRUE;
  695.                     if (Moved) {
  696.                         if (tox==fromx && toy==fromy) {
  697.                             Pages->Flop();
  698.                             Cursor->Wipe();
  699.                             SquareHighlight->Wipe();
  700.                             ui_DrawPiece(TRUE,CurrentColour,RV(fromx),RV(fromy),RankAt(fromx,fromy));
  701.                             SetCursorShape(ComputerIsBlack^WhiteFromTop);
  702.                             from=TRUE;
  703.                         } else {
  704.                             if (LegalMove(tox,toy)) {
  705.                                 done=TRUE;
  706.                                 s[0]='a'+fromx;
  707.                                 s[1]='1'+fromy;
  708.                                 s[2]='a'+tox;
  709.                                 s[3]='1'+toy;
  710.                                 s[4]=0;
  711.                                 if (NeedPromotion(fromx,fromy)) {
  712.                                     SetCursorShape(ComputerIsBlack^WhiteFromTop);
  713.                                     s[4]=qxx[ChoosePromotion()];
  714.                                     s[5]=0;
  715.                                 }
  716.                             }
  717.                         }
  718.                     }
  719.                     Moved=TRUE;
  720.                 }
  721.             }
  722.         } else if (Mouse.LeftButton()) {
  723.             Pages->Flop();
  724.             SquareHighlight->Wipe();
  725.             Cursor->Wipe();
  726.             tox=Cursor->X();
  727.             toy=Cursor->Y();
  728.             //CorrectForCursor(tox,toy);
  729.             if (PressButton(tox,toy,s)) {
  730.                 done=TRUE;
  731.                 if (strcmp(s,"new")==0
  732.                 || strcmp(s,"undo")==0
  733.                 || strcmp(s,"remove")==0
  734.                 || strcmp(s,"save")==0
  735.                 || strcmp(s,"edit")==0
  736.                 || strcmp(s,"edit")==0
  737.                 ) CheckMate=0; // Should be ui_ callback
  738.                 if (strcmp(s,"savecnf")==0) {
  739.                     done=FALSE; // Local function
  740.                     SaveCNF();
  741.                     ReleaseButton();
  742.                 }
  743.             } else if (ToggleFeature(tox,toy)) {
  744.                 // So what.
  745.             }
  746.             while (Mouse.LeftButton());
  747.         }
  748.         if (!done) {
  749.             if (CheckMate) {
  750.                 if (XYCursorToBoard(tox,toy))
  751.                     Cursor->ShapeTo(CheckMate+1);
  752.                 else
  753.                     SetCursorShape(ComputerIsBlack^WhiteFromTop);
  754.             }
  755.         }
  756.  
  757.  
  758.         if (!done) {
  759.             if (Mouse.RightButton() && !from) {
  760.                 Pages->Flop();
  761.                 Cursor->Wipe();
  762.                 SquareHighlight->Wipe();
  763.                 ui_DrawPiece(TRUE,CurrentColour,RV(fromx),RV(fromy),RankAt(fromx,fromy));
  764.                 SetCursorShape(ComputerIsBlack^WhiteFromTop);
  765.                 from=TRUE;
  766.                 WaitingFor=TRUE;
  767.                 Moved=FALSE;
  768.                 while (Mouse.RightButton());
  769.             }
  770.             if (Legal) SquareHighlight->Draw();
  771.             Cursor->Draw();
  772.         }
  773.         Pages->Flip();
  774.     }
  775.     Cursor->Wipe();
  776.     SquareHighlight->Wipe();
  777.     Pages->Flop();
  778.     Cursor->Wipe();
  779.     SquareHighlight->Wipe();
  780. }
  781.  
  782. void ui_ShowHint(char *move)
  783. {
  784.     int ifx=move[0]-'a';
  785.     int ify=move[1]-'1';
  786.     int itx=move[2]-'a';
  787.     int ity=move[3]-'1';
  788.  
  789.     if (!OnBoard(ifx,ify) || !OnBoard(itx,ity)) return;
  790.  
  791.     Cursor->ShapeTo(RankAt(ifx,ify) + (CurrentColour==white ? 3 : 9));
  792.  
  793.     if (WhiteFromTop) {
  794.         ifx=7-ifx; ify=7-ify;
  795.         itx=7-itx; ity=7-ity;
  796.     }
  797.  
  798.     ui_DrawPiece(FALSE,(ifx^ify)&2,ifx,ify,no_piece);
  799.     AnimateMove(25,ifx,ify,itx,ity);
  800.     AnimateMove(25,itx,ity,ifx,ify);
  801.     ui_DrawPiece(TRUE,CurrentColour,ifx,ify,RankAt(RV(ifx),RV(ify)));
  802. }
  803.  
  804. void ui_ShowPlayers(bool Reverse,int CompIsBlack)
  805. {
  806.     WhiteFromTop=Reverse;
  807.     SetAlgebraicNames();
  808.     ComputerIsBlack=CompIsBlack;
  809. }
  810.  
  811. void ui_ShowSideToMove(int movenum, int who)
  812. {
  813.     CurrentColour=who;
  814.  
  815.     if ((who==white) == WhiteFromTop) {
  816.         SetCursorShape(FALSE);
  817.     } else {
  818.         SetCursorShape(TRUE);
  819.     }
  820. }
  821.  
  822. void ui_RejectMove(char *move)
  823. {
  824.     Raspberry();
  825.  
  826.     int ifx=move[0]-'a';
  827.     int ify=move[1]-'1';
  828.     int itx=move[2]-'a';
  829.     int ity=move[3]-'1';
  830.  
  831.     if (!OnBoard(ifx,ify) || !OnBoard(itx,ity)) return;
  832.  
  833.     ui_DrawPiece(TRUE,CurrentColour,RV(ifx),RV(ify),RankAt(ifx,ify));
  834. }
  835.  
  836. void ui_ShowClock(bool OnWhiteSide, int minutes, int seconds)
  837. {
  838.     Minutes->Set(minutes);
  839.     Seconds->Set(seconds);
  840.     Minutes->Draw();
  841.     Seconds->Draw();
  842.     Pages->Flop();
  843.     Minutes->Draw();
  844.     Seconds->Draw();
  845.     Pages->Flop();
  846.     if (Cconis()) TerminateSearch(0);
  847. }
  848.  
  849. void ui_ShowMessage(char *msg)
  850. {
  851.     
  852. }
  853.  
  854. // Unused interface hooks...
  855.  
  856. void ui_PromptForMove() {}
  857. void ui_ToggleRV() {}
  858. void ui_ToggleStars() {}
  859. void ui_ToggleShade() {}
  860. int ui_AskAbort() { return 0; }
  861. void ui_ClearEditHelp() {}
  862. void ui_RefreshEarly() {}
  863. void ui_ChoosePiece(char *s) {}
  864. void ui_ChangeSearchDepth(int *newdepth) {}
  865. void ui_ChangeContempt(int *newcontempt) {}
  866. void ui_ShowFileSaving(char *name) {}
  867. void ui_ShowFileLoading(char *name) {}
  868. void ui_DrawCoords() {}
  869. void ui_ShowPosnValue(short sq, int score) {}
  870. void ui_ShowMaxTree(int maxtree) {}
  871. void ui_ClrScreen() {}
  872. void ClrScreen() {}
  873. void ui_ShowDepth(int depth, char ch) {}
  874. void ui_ShowScore(int score) {}
  875. void ui_ClearMessage() {}
  876. void ui_ShowCurrentMove(int pnt, char *move) {}
  877. void ui_ShowTitle() {}
  878. void ui_ShowNodeCnt(long int NodeCnt, long int evrate) {}
  879. void ui_ShowPlyMove(int ply,char *move) {}
  880. void ui_NoMorePly(int ply) {}
  881. void ui_SearchStartStuff(int side) {}
  882.