4
* Implementation of the X interface for GNU shogi (xshogi).
6
* ------------------------------------------------------------------------
7
* xshogi is based on XBoard -- an Xt/Athena user interface for GNU Chess.
9
* Original authors: Dan Sears, Chris Sears
10
* Enhancements (Version 2.0 and following): Tim Mann
11
* Modifications to XShogi (Version 1.0): Matthias Mutz
12
* Enhancements to XShogi (Version 1.1): Matthias Mutz
13
* Modified implementation of ISS mode for XShogi: Matthias Mutz
14
* Current maintainer: Michael C. Vanier
16
* XShogi borrows its piece bitmaps from CRANES Shogi.
18
* Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
19
* Enhancements Copyright 1992 Free Software Foundation, Inc.
20
* Enhancements for XShogi Copyright 1993, 1994, 1995 Matthias Mutz
21
* Copyright (c) 1999 Michael Vanier and the Free Software Foundation
23
* The following terms apply to Digital Equipment Corporation's copyright
25
* ------------------------------------------------------------------------
28
* Permission to use, copy, modify, and distribute this software and its
29
* documentation for any purpose and without fee is hereby granted,
30
* provided that the above copyright notice appear in all copies and that
31
* both that copyright notice and this permission notice appear in
32
* supporting documentation, and that the name of Digital not be
33
* used in advertising or publicity pertaining to distribution of the
34
* software without specific, written prior permission.
36
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
37
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
38
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
39
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
40
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
41
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43
* ------------------------------------------------------------------------
45
* This file is part of GNU shogi.
47
* GNU shogi is free software; you can redistribute it and/or modify
48
* it under the terms of the GNU General Public License as published by
49
* the Free Software Foundation.
51
* GNU shogi is distributed in the hope that it will be useful,
52
* but WITHOUT ANY WARRANTY; without even the implied warranty of
53
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54
* GNU General Public License for more details.
56
* You should have received a copy of the GNU General Public License
57
* along with GNU shogi; see the file COPYING. If not, write to
58
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
60
* ------------------------------------------------------------------------
66
#ifdef X_DISPLAY_MISSING
67
#error You cannot compile xshogi if X windows is unavailable!
72
#define XBOARD_VERSION "2.0/2.1"
77
#include <sys/ioctl.h>
82
#include <X11/Intrinsic.h>
83
#include <X11/StringDefs.h>
84
#include <X11/Shell.h>
85
#include <X11/Xaw/Dialog.h>
86
#include <X11/Xaw/Form.h>
87
#include <X11/Xaw/List.h>
88
#include <X11/Xaw/Label.h>
89
#include <X11/Xaw/SimpleMenu.h>
90
#include <X11/Xaw/SmeBSB.h>
91
#include <X11/Xaw/SmeLine.h>
92
#include <X11/cursorfont.h>
94
#include "../version.h"
101
#include "bitmaps.h" /* Piece bitmaps. */
102
#include "xshogifn.h" /* Forward declarations. */
104
#define off_board(x) (x < 2 || x > BOARD_SIZE + 1)
107
/**********************************************************************
109
* Global variables, structs etc.
111
**********************************************************************/
114
* NOTE: XShogi depends on Xt R4 or higher
117
int xtVersion = XtSpecificationRelease;
119
XtIntervalId firstProgramXID = 0, secondProgramXID = 0,
120
readGameXID = 0, timerXID = 0, blinkSquareXID = 0;
122
XtAppContext appContext;
124
Boolean (*fileProc) (char *name);
126
FILE *fromFirstProgFP, *toFirstProgFP, *fromSecondProgFP,
127
*toSecondProgFP, *gameFileFP, *lastMsgFP;
129
int currentMove = 0, forwardMostMove = 0, backwardMostMove = 0,
131
secondProgramPID = 0, fromX = -1,
132
fromY = -1, firstMove = True, flipView = False,
133
xshogiDebug = True, commentUp = False, filenameUp = False,
134
whitePlaysFirst = False, startedFromSetupPosition = False,
135
searchTime = 0, pmFromX = -1, pmFromY = -1,
136
blackFlag = False, whiteFlag = False, maybeThinking = False,
139
int at_least_gnushogi_1_2p03 = False;
141
int firstSendTime = 2, secondSendTime = 2; /* 0 = don't, 1 = do,
144
MatchMode matchMode = MatchFalse;
145
GameMode gameMode = BeginningOfGame;
146
GameMode lastGameMode = BeginningOfGame;
147
GameMode pausePreviousMode = BeginningOfGame;
149
char moveList[MAX_MOVES][MOVE_LEN], parseList[MAX_MOVES][MOVE_LEN * 2],
150
ptyname[24], *shogiDir, *programName;
152
char endMessage[MOVE_LEN * 4];
154
long blackTimeRemaining, whiteTimeRemaining, timeControl;
155
long timeRemaining[2][MAX_MOVES];
157
extern char currentMoveString[];
159
int updateRemotePlayer = False;
161
Catched catches[MAX_MOVES];
163
#define DIMENSION 100
165
Widget blackPieceMenu, whitePieceMenu, commentShell;
167
XSetWindowAttributes attr;
185
#define NO_SQUARES 81
190
char catchedIndexToChar[8] =
192
'P', 'L', 'N', 'S', 'G', 'B', 'R', 'K'
195
ShogiSquare catchedIndexToPiece[2][8] =
198
BlackPawn, BlackLance, BlackKnight, BlackSilver, BlackGold,
199
BlackBishop, BlackRook, BlackKing
202
WhitePawn, WhiteLance, WhiteKnight, WhiteSilver, WhiteGold,
203
WhiteBishop, WhiteRook, WhiteKing
208
int pieceToCatchedIndex[] =
210
pawn, lance, knight, silver, gold, bishop, rook,
211
pawn, lance, knight, silver, bishop, rook, king,
212
pawn, lance, knight, silver, gold, bishop, rook,
213
pawn, lance, knight, silver, bishop, rook, king,
219
Board boards[MAX_MOVES];
220
Board initialPosition =
222
{ BlackLance, BlackKnight, BlackSilver, BlackGold, BlackKing,
223
BlackGold, BlackSilver, BlackKnight, BlackLance },
224
{ EmptySquare, BlackBishop, EmptySquare, EmptySquare, EmptySquare,
225
EmptySquare, EmptySquare, BlackRook, EmptySquare },
226
{ BlackPawn, BlackPawn, BlackPawn, BlackPawn, BlackPawn,
227
BlackPawn, BlackPawn, BlackPawn, BlackPawn },
228
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
229
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
230
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
231
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
232
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
233
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
234
{ WhitePawn, WhitePawn, WhitePawn, WhitePawn, WhitePawn,
235
WhitePawn, WhitePawn, WhitePawn, WhitePawn },
236
{ EmptySquare, WhiteRook, EmptySquare, EmptySquare, EmptySquare,
237
EmptySquare, EmptySquare, WhiteBishop, EmptySquare },
238
{ WhiteLance, WhiteKnight, WhiteSilver, WhiteGold, WhiteKing,
239
WhiteGold, WhiteSilver, WhiteKnight, WhiteLance }
242
String gnuButtonStrings[] =
244
"Quit", "Load Game", "Machine White", "Forward",
245
"Reset", "Load Position", "Machine Black", "Backward",
246
"Flip View", "Save Game", "Force Moves", "Pause",
247
"Hint", "Save Position", "Two Machines", "Edit Position",
248
"Challenge", "Select Level", "Move NOW",
251
/* must be in same order as buttonStrings! */
252
XtActionProc gnuButtonProcs[] =
254
QuitProc, LoadGameProc, MachineWhiteProc, ForwardProc,
255
ResetProc, LoadPositionProc, MachineBlackProc, BackwardProc,
256
FlipViewProc, SaveGameProc, ForceProc, PauseProc,
257
HintProc, SavePositionProc, TwoMachinesProc, EditPositionProc,
258
ChallengeProc, SelectLevelProc, MoveNowProc,
263
String *buttonStrings;
264
XtActionProc *buttonProcs;
267
#define PIECE_MENU_SIZE 18
269
String pieceMenuStrings[PIECE_MENU_SIZE] =
271
"----", "Pawn", "Lance", "Knight", "Silver",
272
"Gold", "Bishop", "Rook",
273
"PPawn", "PLance", "PKnight", "PSilver",
274
"PBishop", "PRook", "King",
275
"----", "Empty square", "Clear board"
278
/* must be in same order as PieceMenuStrings! */
279
ShogiSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] =
282
(ShogiSquare) 0, BlackPawn, BlackLance, BlackKnight,
283
BlackSilver, BlackGold, BlackBishop, BlackRook,
284
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver,
285
BlackPBishop, BlackPRook, BlackKing,
286
(ShogiSquare) 0, EmptySquare, ClearBoard
289
(ShogiSquare) 0, WhitePawn, WhiteLance, WhiteKnight,
290
WhiteSilver, WhiteGold, WhiteBishop, WhiteRook,
291
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver,
292
WhitePBishop, WhitePRook, WhiteKing,
293
(ShogiSquare) 0, EmptySquare, ClearBoard
300
Pixel blackPieceColor;
301
Pixel whitePieceColor;
302
Pixel lightSquareColor;
303
Pixel darkSquareColor;
304
Pixel charPieceColor;
307
Boolean westernPieceSet;
312
String firstShogiProgram;
313
String secondShogiProgram;
314
Boolean noShogiProgram;
317
String reverseBigSolidBitmap;
318
String reverseSmallSolidBitmap;
319
String normalBigSolidBitmap;
320
String normalSmallSolidBitmap;
321
String reversePawnBitmap;
322
String reverseLanceBitmap;
323
String reverseKnightBitmap;
324
String reverseSilverBitmap;
325
String reverseGoldBitmap;
326
String reverseRookBitmap;
327
String reverseBishopBitmap;
328
String reversePPawnBitmap;
329
String reversePLanceBitmap;
330
String reversePKnightBitmap;
331
String reversePSilverBitmap;
332
String reversePBishopBitmap;
333
String reversePRookBitmap;
334
String reverseKingBitmap;
335
String normalPawnBitmap;
336
String normalLanceBitmap;
337
String normalKnightBitmap;
338
String normalSilverBitmap;
339
String normalGoldBitmap;
340
String normalRookBitmap;
341
String normalBishopBitmap;
342
String normalPPawnBitmap;
343
String normalPLanceBitmap;
344
String normalPKnightBitmap;
345
String normalPSilverBitmap;
346
String normalPBishopBitmap;
347
String normalPRookBitmap;
348
String normalKingBitmap;
354
Boolean autoSaveGames;
356
String loadPositionFile;
358
String savePositionFile;
360
String challengeDisplay;
371
Boolean ringBellAfterMoves;
372
Boolean autoCallFlag;
375
} AppData, *AppDataPtr;
378
XtResource clientResources[] =
381
"blackPieceColor", "BlackPieceColor", XtRPixel, sizeof(Pixel),
382
XtOffset(AppDataPtr, blackPieceColor), XtRString,
386
"whitePieceColor", "WhitePieceColor", XtRPixel, sizeof(Pixel),
387
XtOffset(AppDataPtr, whitePieceColor), XtRString,
391
"charPieceColor", "CharPieceColor", XtRPixel, sizeof(Pixel),
392
XtOffset(AppDataPtr, charPieceColor), XtRString,
396
"oneColor", "OneColor", XtRPixel, sizeof(Pixel),
397
XtOffset(AppDataPtr, oneColor), XtRString,
401
"zeroColor", "ZeroColor", XtRPixel, sizeof(Pixel),
402
XtOffset(AppDataPtr, zeroColor), XtRString,
406
"lightSquareColor", "LightSquareColor", XtRPixel,
407
sizeof(Pixel), XtOffset(AppDataPtr, lightSquareColor),
408
XtRString, LIGHT_SQUARE_COLOR
411
"darkSquareColor", "DarkSquareColor", XtRPixel, sizeof(Pixel),
412
XtOffset(AppDataPtr, darkSquareColor), XtRString,
416
"westernPieceSet", "WesternPieceSet", XtRBoolean, sizeof(Boolean),
417
XtOffset(AppDataPtr, westernPieceSet), XtRString,
421
"movesPerSession", "movesPerSession", XtRInt, sizeof(int),
422
XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
423
(XtPointer) MOVES_PER_SESSION
426
"initString", "initString", XtRString, sizeof(String),
427
XtOffset(AppDataPtr, initString), XtRString, INIT_STRING
430
"blackString", "blackString", XtRString, sizeof(String),
431
XtOffset(AppDataPtr, blackString), XtRString, BLACK_STRING
434
"whiteString", "whiteString", XtRString, sizeof(String),
435
XtOffset(AppDataPtr, whiteString), XtRString, WHITE_STRING
438
"firstShogiProgram", "firstShogiProgram", XtRString,
439
sizeof(String), XtOffset(AppDataPtr, firstShogiProgram),
440
XtRString, FIRST_SHOGI_PROGRAM
443
"secondShogiProgram", "secondShogiProgram", XtRString,
444
sizeof(String), XtOffset(AppDataPtr, secondShogiProgram),
445
XtRString, SECOND_SHOGI_PROGRAM
448
"noShogiProgram", "noShogiProgram", XtRBoolean,
449
sizeof(Boolean), XtOffset(AppDataPtr, noShogiProgram),
450
XtRImmediate, (XtPointer) False
453
"firstHost", "firstHost", XtRString, sizeof(String),
454
XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST
457
"secondHost", "secondHost", XtRString, sizeof(String),
458
XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST
461
"reversePawnBitmap", "reversePawnBitmap", XtRString,
462
sizeof(String), XtOffset(AppDataPtr, reversePawnBitmap),
466
"reverseLanceBitmap", "reverseLanceBitmap", XtRString,
467
sizeof(String), XtOffset(AppDataPtr, reverseLanceBitmap),
471
"reverseKnightBitmap", "reverseKnightBitmap", XtRString,
472
sizeof(String), XtOffset(AppDataPtr, reverseKnightBitmap),
476
"reverseSilverBitmap", "reverseSilverBitmap", XtRString,
477
sizeof(String), XtOffset(AppDataPtr, reverseSilverBitmap),
481
"reverseGoldBitmap", "reverseGoldBitmap", XtRString,
482
sizeof(String), XtOffset(AppDataPtr, reverseGoldBitmap),
486
"reverseRookBitmap", "reverseRookBitmap", XtRString,
487
sizeof(String), XtOffset(AppDataPtr, reverseRookBitmap),
491
"reverseBishopBitmap", "reverseBishopBitmap", XtRString,
492
sizeof(String), XtOffset(AppDataPtr, reverseBishopBitmap),
496
"reversePPawnBitmap", "reversePPawnBitmap", XtRString,
497
sizeof(String), XtOffset(AppDataPtr, reversePPawnBitmap),
501
"reversePLanceBitmap", "reversePLanceBitmap", XtRString,
502
sizeof(String), XtOffset(AppDataPtr, reversePLanceBitmap),
506
"reversePKnightBitmap", "reversePKnightBitmap", XtRString,
507
sizeof(String), XtOffset(AppDataPtr, reversePKnightBitmap),
511
"reversePSilverBitmap", "reversePSilverBitmap", XtRString,
512
sizeof(String), XtOffset(AppDataPtr, reversePSilverBitmap),
516
"reversePRookBitmap", "reversePRookBitmap", XtRString,
517
sizeof(String), XtOffset(AppDataPtr, reversePRookBitmap),
521
"reversePBishopBitmap", "reversePBishopBitmap", XtRString,
522
sizeof(String), XtOffset(AppDataPtr, reversePBishopBitmap),
526
"reverseKingBitmap", "reverseKingBitmap", XtRString,
527
sizeof(String), XtOffset(AppDataPtr, reverseKingBitmap),
531
"normalPawnBitmap", "normalPawnBitmap", XtRString,
532
sizeof(String), XtOffset(AppDataPtr, normalPawnBitmap),
536
"normalLanceBitmap", "normalLanceBitmap", XtRString,
537
sizeof(String), XtOffset(AppDataPtr, normalLanceBitmap),
541
"normalKnightBitmap", "normalKnightBitmap", XtRString,
542
sizeof(String), XtOffset(AppDataPtr, normalKnightBitmap),
546
"normalSilverBitmap", "normalSilverBitmap", XtRString,
547
sizeof(String), XtOffset(AppDataPtr, normalSilverBitmap),
551
"normalGoldBitmap", "normalGoldBitmap", XtRString,
552
sizeof(String), XtOffset(AppDataPtr, normalGoldBitmap),
556
"normalBishopBitmap", "normalBishopBitmap", XtRString,
557
sizeof(String), XtOffset(AppDataPtr, normalBishopBitmap),
561
"normalRookBitmap", "normalRookBitmap", XtRString,
562
sizeof(String), XtOffset(AppDataPtr, normalRookBitmap),
566
"normalPPawnBitmap", "normalPPawnBitmap", XtRString,
567
sizeof(String), XtOffset(AppDataPtr, normalPPawnBitmap),
571
"normalPLanceBitmap", "normalPLanceBitmap", XtRString,
572
sizeof(String), XtOffset(AppDataPtr, normalPLanceBitmap),
576
"normalPKnightBitmap", "normalPKnightBitmap", XtRString,
577
sizeof(String), XtOffset(AppDataPtr, normalPKnightBitmap),
581
"normalPSilverBitmap", "normalPSilverBitmap", XtRString,
582
sizeof(String), XtOffset(AppDataPtr, normalPSilverBitmap),
586
"normalPBishopBitmap", "normalPBishopBitmap", XtRString,
587
sizeof(String), XtOffset(AppDataPtr, normalPBishopBitmap),
591
"normalPRookBitmap", "normalPRookBitmap", XtRString,
592
sizeof(String), XtOffset(AppDataPtr, normalPRookBitmap),
596
"normalKingBitmap", "normalKingBitmap", XtRString,
597
sizeof(String), XtOffset(AppDataPtr, normalKingBitmap),
601
"remoteShell", "remoteShell", XtRString, sizeof(String),
602
XtOffset(AppDataPtr, remoteShell), XtRString, "rsh"
605
"timeDelay", "timeDelay", XtRFloat, sizeof(float),
606
XtOffset(AppDataPtr, timeDelay), XtRString,
607
(XtPointer) TIME_DELAY
610
"timeControl", "timeControl", XtRString, sizeof(String),
611
XtOffset(AppDataPtr, timeControl), XtRString,
612
(XtPointer) TIME_CONTROL
616
XtRBoolean, sizeof(Boolean),
617
XtOffset(AppDataPtr, gameIn), XtRImmediate,
621
"autoSaveGames", "autoSaveGames", XtRBoolean,
622
sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
623
XtRImmediate, (XtPointer) False
626
"loadGameFile", "loadGameFile", XtRString, sizeof(String),
627
XtOffset(AppDataPtr, loadGameFile), XtRString, NULL
630
"loadPositionFile", "loadPositionFile", XtRString,
631
sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
635
"saveGameFile", "saveGameFile", XtRString, sizeof(String),
636
XtOffset(AppDataPtr, saveGameFile), XtRString, ""
639
"savePositionFile", "savePositionFile", XtRString,
640
sizeof(String), XtOffset(AppDataPtr, savePositionFile),
644
"challengeDisplay", "challengeDisplay", XtRString,
645
sizeof(String), XtOffset(AppDataPtr, challengeDisplay),
649
"matchMode", "matchMode", XtRString, sizeof(String),
650
XtOffset(AppDataPtr, matchMode), XtRString, MATCH_MODE
653
"monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
654
XtOffset(AppDataPtr, monoMode), XtRImmediate,
658
"debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
659
XtOffset(AppDataPtr, debugMode), XtRImmediate,
663
"Iconic", "Iconic", XtRBoolean, sizeof(Boolean),
664
XtOffset(AppDataPtr, Iconic), XtRImmediate,
668
"clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
669
XtOffset(AppDataPtr, clockMode), XtRImmediate,
673
"autoCallFlag", "autoCallFlag", XtRBoolean,
674
sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
675
XtRImmediate, (XtPointer) False
678
"boardSize", "boardSize", XtRString, sizeof(String),
679
XtOffset(AppDataPtr, boardSize), XtRString, DEFAULT_SIZE
682
"searchTime", "searchTime", XtRString, sizeof(String),
683
XtOffset(AppDataPtr, searchTime), XtRString,
687
"searchDepth", "searchDepth", XtRInt, sizeof(int),
688
XtOffset(AppDataPtr, searchDepth), XtRImmediate,
692
"showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
693
XtOffset(AppDataPtr, showCoords), XtRImmediate,
697
"mainFont", "mainFont", XtRString, sizeof(String),
698
XtOffset(AppDataPtr, mainFont), XtRString, MAIN_FONT
701
"coordFont", "coordFont", XtRString, sizeof(String),
702
XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT
705
"ringBellAfterMoves", "ringBellAfterMoves",
706
XtRBoolean, sizeof(Boolean),
707
XtOffset(AppDataPtr, ringBellAfterMoves),
708
XtRImmediate, (XtPointer) False
711
"borderXoffset", "borderXoffset", XtRInt, sizeof(int),
712
XtOffset(AppDataPtr, borderXoffset), XtRImmediate,
713
(XtPointer) BORDER_X_OFFSET
716
"borderYoffset", "borderYOffset", XtRInt, sizeof(int),
717
XtOffset(AppDataPtr, borderYoffset), XtRImmediate,
718
(XtPointer) BORDER_Y_OFFSET
735
Pixmap reversePawnBitmap, reverseLanceBitmap, reverseKnightBitmap,
737
reverseGoldBitmap, reverseBishopBitmap, reverseRookBitmap,
738
reversePPawnBitmap, reversePLanceBitmap, reversePKnightBitmap,
739
reversePSilverBitmap, reversePBishopBitmap, reversePRookBitmap,
741
reverseBigSolidBitmap, reverseSmallSolidBitmap,
742
normalBigSolidBitmap, normalSmallSolidBitmap,
743
normalPawnBitmap, normalLanceBitmap, normalKnightBitmap,
744
normalSilverBitmap, normalGoldBitmap,
745
normalBishopBitmap, normalRookBitmap,
746
normalPPawnBitmap, normalPLanceBitmap, normalPKnightBitmap,
747
normalPSilverBitmap, normalPBishopBitmap, normalPRookBitmap,
755
GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
756
woPieceGC, boPieceGC, bdPieceGC, blPieceGC, wbPieceGC,
757
bwPieceGC, coordGC, dropPiece;
761
Font mainFontID, coordFontID;
762
XFontStruct *mainFontStruct, *coordFontStruct;
764
Widget shellWidget, formWidget, boardWidget,
765
commandsWidget, messageWidget,
766
blackTimerWidget, whiteTimerWidget,
767
titleWidget, widgetList[6],
769
filemodeShell, challengeWidget;
771
XSegment gridSegments[(BOARD_SIZE + 1) * 2];
773
Pixel timerForegroundPixel, timerBackgroundPixel;
777
int black_pixel_is_zero;
781
Boolean monoMode, showCoords, Iconic;
786
struct DisplayData localPlayer, remotePlayer;
795
static PromotionMoveInfo pmi; /* making this global is gross */
798
Pixmap *pieceToReverse[2][28] =
801
&localPlayer.reversePawnBitmap,
802
&localPlayer.reverseLanceBitmap,
803
&localPlayer.reverseKnightBitmap,
804
&localPlayer.reverseSilverBitmap,
805
&localPlayer.reverseGoldBitmap,
806
&localPlayer.reverseBishopBitmap,
807
&localPlayer.reverseRookBitmap,
808
&localPlayer.reversePPawnBitmap,
809
&localPlayer.reversePLanceBitmap,
810
&localPlayer.reversePKnightBitmap,
811
&localPlayer.reversePSilverBitmap,
812
&localPlayer.reversePBishopBitmap,
813
&localPlayer.reversePRookBitmap,
814
&localPlayer.reverseKingBitmap,
815
&localPlayer.reversePawnBitmap,
816
&localPlayer.reverseLanceBitmap,
817
&localPlayer.reverseKnightBitmap,
818
&localPlayer.reverseSilverBitmap,
819
&localPlayer.reverseGoldBitmap,
820
&localPlayer.reverseBishopBitmap,
821
&localPlayer.reverseRookBitmap,
822
&localPlayer.reversePPawnBitmap,
823
&localPlayer.reversePLanceBitmap,
824
&localPlayer.reversePKnightBitmap,
825
&localPlayer.reversePSilverBitmap,
826
&localPlayer.reversePBishopBitmap,
827
&localPlayer.reversePRookBitmap,
828
&localPlayer.reverseKingBitmap
831
&remotePlayer.reversePawnBitmap,
832
&remotePlayer.reverseLanceBitmap,
833
&remotePlayer.reverseKnightBitmap,
834
&remotePlayer.reverseSilverBitmap,
835
&remotePlayer.reverseGoldBitmap,
836
&remotePlayer.reverseBishopBitmap,
837
&remotePlayer.reverseRookBitmap,
838
&remotePlayer.reversePPawnBitmap,
839
&remotePlayer.reversePLanceBitmap,
840
&remotePlayer.reversePKnightBitmap,
841
&remotePlayer.reversePSilverBitmap,
842
&remotePlayer.reversePBishopBitmap,
843
&remotePlayer.reversePRookBitmap,
844
&remotePlayer.reverseKingBitmap,
845
&remotePlayer.reversePawnBitmap,
846
&remotePlayer.reverseLanceBitmap,
847
&remotePlayer.reverseKnightBitmap,
848
&remotePlayer.reverseSilverBitmap,
849
&remotePlayer.reverseGoldBitmap,
850
&remotePlayer.reverseBishopBitmap,
851
&remotePlayer.reverseRookBitmap,
852
&remotePlayer.reversePPawnBitmap,
853
&remotePlayer.reversePLanceBitmap,
854
&remotePlayer.reversePKnightBitmap,
855
&remotePlayer.reversePSilverBitmap,
856
&remotePlayer.reversePBishopBitmap,
857
&remotePlayer.reversePRookBitmap,
858
&remotePlayer.reverseKingBitmap
864
Pixmap *pieceToNormal[2][28] =
867
&localPlayer.normalPawnBitmap,
868
&localPlayer.normalLanceBitmap,
869
&localPlayer.normalKnightBitmap,
870
&localPlayer.normalSilverBitmap,
871
&localPlayer.normalGoldBitmap,
872
&localPlayer.normalBishopBitmap,
873
&localPlayer.normalRookBitmap,
874
&localPlayer.normalPPawnBitmap,
875
&localPlayer.normalPLanceBitmap,
876
&localPlayer.normalPKnightBitmap,
877
&localPlayer.normalPSilverBitmap,
878
&localPlayer.normalPBishopBitmap,
879
&localPlayer.normalPRookBitmap,
880
&localPlayer.normalKingBitmap,
881
&localPlayer.normalPawnBitmap,
882
&localPlayer.normalLanceBitmap,
883
&localPlayer.normalKnightBitmap,
884
&localPlayer.normalSilverBitmap,
885
&localPlayer.normalGoldBitmap,
886
&localPlayer.normalBishopBitmap,
887
&localPlayer.normalRookBitmap,
888
&localPlayer.normalPPawnBitmap,
889
&localPlayer.normalPLanceBitmap,
890
&localPlayer.normalPKnightBitmap,
891
&localPlayer.normalPSilverBitmap,
892
&localPlayer.normalPBishopBitmap,
893
&localPlayer.normalPRookBitmap,
894
&localPlayer.normalKingBitmap
897
&remotePlayer.normalPawnBitmap,
898
&remotePlayer.normalLanceBitmap,
899
&remotePlayer.normalKnightBitmap,
900
&remotePlayer.normalSilverBitmap,
901
&remotePlayer.normalGoldBitmap,
902
&remotePlayer.normalBishopBitmap,
903
&remotePlayer.normalRookBitmap,
904
&remotePlayer.normalPPawnBitmap,
905
&remotePlayer.normalPLanceBitmap,
906
&remotePlayer.normalPKnightBitmap,
907
&remotePlayer.normalPSilverBitmap,
908
&remotePlayer.normalPBishopBitmap,
909
&remotePlayer.normalPRookBitmap,
910
&remotePlayer.normalKingBitmap,
911
&remotePlayer.normalPawnBitmap,
912
&remotePlayer.normalLanceBitmap,
913
&remotePlayer.normalKnightBitmap,
914
&remotePlayer.normalSilverBitmap,
915
&remotePlayer.normalGoldBitmap,
916
&remotePlayer.normalBishopBitmap,
917
&remotePlayer.normalRookBitmap,
918
&remotePlayer.normalPPawnBitmap,
919
&remotePlayer.normalPLanceBitmap,
920
&remotePlayer.normalPKnightBitmap,
921
&remotePlayer.normalPSilverBitmap,
922
&remotePlayer.normalPBishopBitmap,
923
&remotePlayer.normalPRookBitmap,
924
&remotePlayer.normalKingBitmap
930
Pixmap *pieceToReverseSolid[2][28] =
933
&localPlayer.reverseSmallSolidBitmap,
934
&localPlayer.reverseSmallSolidBitmap,
935
&localPlayer.reverseSmallSolidBitmap,
936
&localPlayer.reverseBigSolidBitmap,
937
&localPlayer.reverseBigSolidBitmap,
938
&localPlayer.reverseBigSolidBitmap,
939
&localPlayer.reverseBigSolidBitmap,
940
&localPlayer.reverseSmallSolidBitmap,
941
&localPlayer.reverseSmallSolidBitmap,
942
&localPlayer.reverseSmallSolidBitmap,
943
&localPlayer.reverseBigSolidBitmap,
944
&localPlayer.reverseBigSolidBitmap,
945
&localPlayer.reverseBigSolidBitmap,
946
&localPlayer.reverseBigSolidBitmap,
947
&localPlayer.reverseSmallSolidBitmap,
948
&localPlayer.reverseSmallSolidBitmap,
949
&localPlayer.reverseSmallSolidBitmap,
950
&localPlayer.reverseBigSolidBitmap,
951
&localPlayer.reverseBigSolidBitmap,
952
&localPlayer.reverseBigSolidBitmap,
953
&localPlayer.reverseBigSolidBitmap,
954
&localPlayer.reverseSmallSolidBitmap,
955
&localPlayer.reverseSmallSolidBitmap,
956
&localPlayer.reverseSmallSolidBitmap,
957
&localPlayer.reverseBigSolidBitmap,
958
&localPlayer.reverseBigSolidBitmap,
959
&localPlayer.reverseBigSolidBitmap,
960
&localPlayer.reverseBigSolidBitmap
963
&remotePlayer.reverseSmallSolidBitmap,
964
&remotePlayer.reverseSmallSolidBitmap,
965
&remotePlayer.reverseSmallSolidBitmap,
966
&remotePlayer.reverseBigSolidBitmap,
967
&remotePlayer.reverseBigSolidBitmap,
968
&remotePlayer.reverseBigSolidBitmap,
969
&remotePlayer.reverseBigSolidBitmap,
970
&remotePlayer.reverseSmallSolidBitmap,
971
&remotePlayer.reverseSmallSolidBitmap,
972
&remotePlayer.reverseSmallSolidBitmap,
973
&remotePlayer.reverseBigSolidBitmap,
974
&remotePlayer.reverseBigSolidBitmap,
975
&remotePlayer.reverseBigSolidBitmap,
976
&remotePlayer.reverseBigSolidBitmap,
977
&remotePlayer.reverseSmallSolidBitmap,
978
&remotePlayer.reverseSmallSolidBitmap,
979
&remotePlayer.reverseSmallSolidBitmap,
980
&remotePlayer.reverseBigSolidBitmap,
981
&remotePlayer.reverseBigSolidBitmap,
982
&remotePlayer.reverseBigSolidBitmap,
983
&remotePlayer.reverseBigSolidBitmap,
984
&remotePlayer.reverseSmallSolidBitmap,
985
&remotePlayer.reverseSmallSolidBitmap,
986
&remotePlayer.reverseSmallSolidBitmap,
987
&remotePlayer.reverseBigSolidBitmap,
988
&remotePlayer.reverseBigSolidBitmap,
989
&remotePlayer.reverseBigSolidBitmap,
990
&remotePlayer.reverseBigSolidBitmap
996
Pixmap *pieceToNormalSolid[2][28] =
999
&localPlayer.normalSmallSolidBitmap,
1000
&localPlayer.normalSmallSolidBitmap,
1001
&localPlayer.normalSmallSolidBitmap,
1002
&localPlayer.normalBigSolidBitmap,
1003
&localPlayer.normalBigSolidBitmap,
1004
&localPlayer.normalBigSolidBitmap,
1005
&localPlayer.normalBigSolidBitmap,
1006
&localPlayer.normalSmallSolidBitmap,
1007
&localPlayer.normalSmallSolidBitmap,
1008
&localPlayer.normalSmallSolidBitmap,
1009
&localPlayer.normalBigSolidBitmap,
1010
&localPlayer.normalBigSolidBitmap,
1011
&localPlayer.normalBigSolidBitmap,
1012
&localPlayer.normalBigSolidBitmap,
1013
&localPlayer.normalSmallSolidBitmap,
1014
&localPlayer.normalSmallSolidBitmap,
1015
&localPlayer.normalSmallSolidBitmap,
1016
&localPlayer.normalBigSolidBitmap,
1017
&localPlayer.normalBigSolidBitmap,
1018
&localPlayer.normalBigSolidBitmap,
1019
&localPlayer.normalBigSolidBitmap,
1020
&localPlayer.normalSmallSolidBitmap,
1021
&localPlayer.normalSmallSolidBitmap,
1022
&localPlayer.normalSmallSolidBitmap,
1023
&localPlayer.normalBigSolidBitmap,
1024
&localPlayer.normalBigSolidBitmap,
1025
&localPlayer.normalBigSolidBitmap,
1026
&localPlayer.normalBigSolidBitmap
1029
&remotePlayer.normalSmallSolidBitmap,
1030
&remotePlayer.normalSmallSolidBitmap,
1031
&remotePlayer.normalSmallSolidBitmap,
1032
&remotePlayer.normalBigSolidBitmap,
1033
&remotePlayer.normalBigSolidBitmap,
1034
&remotePlayer.normalBigSolidBitmap,
1035
&remotePlayer.normalBigSolidBitmap,
1036
&remotePlayer.normalSmallSolidBitmap,
1037
&remotePlayer.normalSmallSolidBitmap,
1038
&remotePlayer.normalSmallSolidBitmap,
1039
&remotePlayer.normalBigSolidBitmap,
1040
&remotePlayer.normalBigSolidBitmap,
1041
&remotePlayer.normalBigSolidBitmap,
1042
&remotePlayer.normalBigSolidBitmap,
1043
&remotePlayer.normalSmallSolidBitmap,
1044
&remotePlayer.normalSmallSolidBitmap,
1045
&remotePlayer.normalSmallSolidBitmap,
1046
&remotePlayer.normalBigSolidBitmap,
1047
&remotePlayer.normalBigSolidBitmap,
1048
&remotePlayer.normalBigSolidBitmap,
1049
&remotePlayer.normalBigSolidBitmap,
1050
&remotePlayer.normalSmallSolidBitmap,
1051
&remotePlayer.normalSmallSolidBitmap,
1052
&remotePlayer.normalSmallSolidBitmap,
1053
&remotePlayer.normalBigSolidBitmap,
1054
&remotePlayer.normalBigSolidBitmap,
1055
&remotePlayer.normalBigSolidBitmap,
1056
&remotePlayer.normalBigSolidBitmap
1062
int pieceIsPromoted[] =
1064
False, False, False, False, False, False, False,
1065
True, True, True, True, True, True, False,
1066
False, False, False, False, False, False, False,
1067
True, True, True, True, True, True, False,
1072
int piecePromotable[] =
1074
True, True, True, True, False, True, True,
1075
False, False, False, False, False, False, False,
1076
True, True, True, True, False, True, True,
1077
False, False, False, False, False, False, False,
1082
char pieceToChar[] =
1084
'P', 'L', 'N', 'S', 'G', 'B', 'R', 'P', 'L', 'N', 'S', 'B', 'R', 'K',
1085
'p', 'l', 'n', 's', 'g', 'b', 'r', 'p', 'l', 'n', 's', 'b', 'r', 'k',
1090
int pieceisWhite[] =
1092
False, False, False, False, False, False, False,
1093
False, False, False, False, False, False, False,
1094
True, True, True, True, True, True, True,
1095
True, True, True, True, True, True, True,
1101
ShogiSquare pieceToPromoted[] =
1103
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver, BlackGold,
1104
BlackPBishop, BlackPRook,
1105
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver,
1106
BlackPBishop, BlackPRook, BlackKing,
1107
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver, WhiteGold,
1108
WhitePBishop, WhitePRook,
1109
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver,
1110
WhitePBishop, WhitePRook, WhiteKing
1115
XrmOptionDescRec shellOptions[] =
1117
{ "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
1118
{ "-bpc", "blackPieceColor", XrmoptionSepArg, NULL },
1119
{ "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
1120
{ "-wpc", "whitePieceColor", XrmoptionSepArg, NULL },
1121
{ "-charPieceColor", "charPieceColor", XrmoptionSepArg, NULL },
1122
{ "-cpc", "charPieceColor", XrmoptionSepArg, NULL },
1123
{ "-zeroColor", "zeroColor", XrmoptionSepArg, NULL },
1124
{ "-zc", "zeroColor", XrmoptionSepArg, NULL },
1125
{ "-oneColor", "oneColor", XrmoptionSepArg, NULL },
1126
{ "-oc", "oneColor", XrmoptionSepArg, NULL },
1127
{ "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
1128
{ "-lsc", "lightSquareColor", XrmoptionSepArg, NULL },
1129
{ "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
1130
{ "-dsc", "darkSquareColor", XrmoptionSepArg, NULL },
1131
{ "-westernPieceSet", "westernPieceSet", XrmoptionSepArg, NULL },
1132
{ "-wps", "westernPieceSet", XrmoptionSepArg, NULL },
1133
{ "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
1134
{ "-mps", "movesPerSession", XrmoptionSepArg, NULL },
1135
{ "-firstShogiProgram", "firstShogiProgram", XrmoptionSepArg, NULL },
1136
{ "-fsp", "firstShogiProgram", XrmoptionSepArg, NULL },
1137
{ "-secondShogiProgram", "secondShogiProgram", XrmoptionSepArg, NULL },
1138
{ "-ssp", "secondShogiProgram", XrmoptionSepArg, NULL },
1139
{ "-noShogiProgram", "noShogiProgram", XrmoptionSepArg, NULL },
1140
{ "-nsp", "noShogiProgram", XrmoptionSepArg, NULL },
1141
{ "-firstHost", "firstHost", XrmoptionSepArg, NULL },
1142
{ "-fh", "firstHost", XrmoptionSepArg, NULL },
1143
{ "-secondHost", "secondHost", XrmoptionSepArg, NULL },
1144
{ "-sh", "secondHost", XrmoptionSepArg, NULL },
1145
{ "-reversePawnBitmap", "reversePawnBitmap", XrmoptionSepArg, NULL },
1146
{ "-rpb", "reversePawnBitmap", XrmoptionSepArg, NULL },
1147
{ "-reverseLanceBitmap", "reverseLanceBitmap", XrmoptionSepArg, NULL },
1148
{ "-rlb", "reverseLanceBitmap", XrmoptionSepArg, NULL },
1149
{ "-reverseKnightBitmap", "reverseKnightBitmap", XrmoptionSepArg, NULL },
1150
{ "-rnb", "reverseKnightBitmap", XrmoptionSepArg, NULL },
1151
{ "-reverseSilverBitmap", "reverseSilverBitmap", XrmoptionSepArg, NULL },
1152
{ "-rsb", "reverseSilverBitmap", XrmoptionSepArg, NULL },
1153
{ "-reverseGoldBitmap", "reverseGoldBitmap", XrmoptionSepArg, NULL },
1154
{ "-rgb", "reverseGoldBitmap", XrmoptionSepArg, NULL },
1155
{ "-reverseRookBitmap", "reverseRookBitmap", XrmoptionSepArg, NULL },
1156
{ "-rrb", "reverseRookBitmap", XrmoptionSepArg, NULL },
1157
{ "-reverseBishopBitmap", "reverseBishopBitmap", XrmoptionSepArg, NULL },
1158
{ "-rbb", "reverseBishopBitmap", XrmoptionSepArg, NULL },
1159
{ "-reversePPawnBitmap", "reversePPawnBitmap",
1160
XrmoptionSepArg, NULL },
1161
{ "-rppb", "reversePPawnBitmap", XrmoptionSepArg, NULL },
1162
{ "-reversePLanceBitmap", "reversePLanceBitmap",
1163
XrmoptionSepArg, NULL },
1164
{ "-rplb", "reversePLanceBitmap", XrmoptionSepArg, NULL },
1165
{ "-reversePKnightBitmap", "reversePKnightBitmap",
1166
XrmoptionSepArg, NULL },
1167
{ "-rpnb", "reversePKnightBitmap", XrmoptionSepArg, NULL },
1168
{ "-reversePSilverBitmap", "reversePSilverBitmap",
1169
XrmoptionSepArg, NULL },
1170
{ "-rpsb", "reversePSilverBitmap", XrmoptionSepArg, NULL },
1171
{ "-reversePRookBitmap", "reversePRookBitmap",
1172
XrmoptionSepArg, NULL },
1173
{ "-rprb", "reversePRookBitmap", XrmoptionSepArg, NULL },
1174
{ "-reversePBishopBitmap", "reversePBishopBitmap",
1175
XrmoptionSepArg, NULL },
1176
{ "-rpbb", "reversePBishopBitmap", XrmoptionSepArg, NULL },
1177
{ "-reverseKingBitmap", "reverseKingBitmap", XrmoptionSepArg, NULL },
1178
{ "-rkb", "reverseKingBitmap", XrmoptionSepArg, NULL },
1179
{ "-outlinePawnBitmap", "outlinePawnBitmap", XrmoptionSepArg, NULL },
1180
{ "-opb", "normalPawnBitmap", XrmoptionSepArg, NULL },
1181
{ "-normalLanceBitmap", "normalLanceBitmap", XrmoptionSepArg, NULL },
1182
{ "-olb", "normalLanceBitmap", XrmoptionSepArg, NULL },
1183
{ "-normalKnightBitmap", "normalKnightBitmap", XrmoptionSepArg, NULL },
1184
{ "-onb", "normalKnightBitmap", XrmoptionSepArg, NULL },
1185
{ "-normalSilverBitmap", "normalSilverBitmap", XrmoptionSepArg, NULL },
1186
{ "-osb", "normalSilverBitmap", XrmoptionSepArg, NULL },
1187
{ "-normalGoldBitmap", "normalGoldBitmap", XrmoptionSepArg, NULL },
1188
{ "-ogb", "normalGoldBitmap", XrmoptionSepArg, NULL },
1189
{ "-normalRookBitmap", "normalRookBitmap", XrmoptionSepArg, NULL },
1190
{ "-orb", "normalRookBitmap", XrmoptionSepArg, NULL },
1191
{ "-normalBishopBitmap", "normalBishopBitmap", XrmoptionSepArg, NULL },
1192
{ "-obb", "normalBishopBitmap", XrmoptionSepArg, NULL },
1193
{ "-normalPPawnBitmap", "normalPPawnBitmap", XrmoptionSepArg, NULL },
1194
{ "-oppb", "normalPPawnBitmap", XrmoptionSepArg, NULL },
1195
{ "-normalPLanceBitmap", "normalPLanceBitmap", XrmoptionSepArg, NULL },
1196
{ "-oplb", "normalPLanceBitmap", XrmoptionSepArg, NULL },
1197
{ "-normalPKnightBitmap", "normalPKnightBitmap", XrmoptionSepArg, NULL },
1198
{ "-opnb", "normalPKnightBitmap", XrmoptionSepArg, NULL },
1199
{ "-normalPSilverBitmap", "normalPSilverBitmap", XrmoptionSepArg, NULL },
1200
{ "-opsb", "normalPSilverBitmap", XrmoptionSepArg, NULL },
1201
{ "-normalPRookBitmap", "normalPRookBitmap", XrmoptionSepArg, NULL },
1202
{ "-oprb", "normalPRookBitmap", XrmoptionSepArg, NULL },
1203
{ "-normalPBishopBitmap", "normalPBishopBitmap", XrmoptionSepArg, NULL },
1204
{ "-opbb", "normalPBishopBitmap", XrmoptionSepArg, NULL },
1205
{ "-normalKingBitmap", "normalKingBitmap", XrmoptionSepArg, NULL },
1206
{ "-okb", "outlineKingBitmap", XrmoptionSepArg, NULL },
1207
{ "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
1208
{ "-rsh", "remoteShell", XrmoptionSepArg, NULL },
1209
{ "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
1210
{ "-td", "timeDelay", XrmoptionSepArg, NULL },
1211
{ "-timeControl", "timeControl", XrmoptionSepArg, NULL },
1212
{ "-tc", "timeControl", XrmoptionSepArg, NULL },
1213
{ "-gameIn", "gameIn", XrmoptionSepArg, NULL },
1214
{ "-gi", "gameIn", XrmoptionSepArg, NULL },
1215
{ "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
1216
{ "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
1217
{ "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
1218
{ "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
1219
{ "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
1220
{ "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
1221
{ "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
1222
{ "-spf", "savePositionFile", XrmoptionSepArg, NULL },
1223
{ "-challengeDisplay", "challengeDisplay", XrmoptionSepArg, NULL },
1224
{ "-cd", "challengeDisplay", XrmoptionSepArg, NULL },
1225
{ "-matchMode", "matchMode", XrmoptionSepArg, NULL },
1226
{ "-mm", "matchMode", XrmoptionSepArg, NULL },
1227
{ "-monoMode", "monoMode", XrmoptionSepArg, NULL },
1228
{ "-mono", "monoMode", XrmoptionSepArg, NULL },
1229
{ "-debugMode", "debugMode", XrmoptionSepArg, NULL },
1230
{ "-debug", "debugMode", XrmoptionSepArg, NULL },
1231
{ "-clockMode", "clockMode", XrmoptionSepArg, NULL },
1232
{ "-clock", "clockMode", XrmoptionSepArg, NULL },
1233
{ "-boardSize", "boardSize", XrmoptionSepArg, NULL },
1234
{ "-size", "boardSize", XrmoptionSepArg, NULL },
1235
{ "-searchTime", "searchTime", XrmoptionSepArg, NULL },
1236
{ "-st", "searchTime", XrmoptionSepArg, NULL },
1237
{ "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
1238
{ "-sd", "searchDepth", XrmoptionSepArg, NULL },
1239
{ "-showCoords", "showCoords", XrmoptionSepArg, NULL },
1240
{ "-coords", "showCoords", XrmoptionSepArg, NULL },
1241
{ "-iconic", "Iconic", XrmoptionNoArg, "True" }
1246
XtActionsRec boardActions[] =
1248
{ "DrawPosition", (XtActionProc) DrawPosition },
1249
{ "HandleUserMove", (XtActionProc) HandleUserMove },
1250
{ "ResetProc", (XtActionProc) ResetProc },
1251
{ "ResetFileProc", (XtActionProc) ResetFileProc },
1252
{ "LoadGameProc", (XtActionProc) LoadGameProc },
1253
{ "QuitProc", (XtActionProc) QuitProc },
1254
{ "ForwardProc", (XtActionProc) ForwardProc },
1255
{ "BackwardProc", (XtActionProc) BackwardProc },
1256
{ "PauseProc", (XtActionProc) PauseProc },
1257
{ "Iconify", (XtActionProc) Iconify },
1258
{ "FileNameAction", (XtActionProc) FileNameAction },
1259
{ "PieceMenuPopup", (XtActionProc) PieceMenuPopup },
1260
{ "SetBlackToPlay", (XtActionProc) SetBlackToPlay },
1261
{ "SetWhiteToPlay", (XtActionProc) SetWhiteToPlay }
1265
char translationsTable[] =
1266
"<Expose>: DrawPosition() \n \
1267
<Btn1Down>: HandleUserMove() \n \
1268
<Btn1Up>: HandleUserMove() \n \
1269
<Btn2Down>: XawPositionSimpleMenu(menuW) PieceMenuPopup(menuW) \n \
1270
<Btn3Down>: XawPositionSimpleMenu(menuB) PieceMenuPopup(menuB) \n \
1271
<Key>r: ResetFileProc() ResetProc() \n \
1272
<Key>R: ResetFileProc() ResetProc() \n \
1273
<Key>g: LoadGameProc() \n \
1274
<Key>G: LoadGameProc() \n \
1275
<Key>q: QuitProc() \n \
1276
<Key>Q: QuitProc() \n \
1277
<Message>WM_PROTOCOLS: QuitProc() \n \
1278
<Key>f: ForwardProc() \n \
1279
<Key>F: ForwardProc() \n \
1280
<Key>b: BackwardProc() \n \
1281
<Key>B: BackwardProc() \n \
1282
<Key>p: PauseProc() \n \
1283
<Key>P: PauseProc() \n \
1284
<Key>i: Iconify() \n \
1285
<Key>I: Iconify() \n \
1286
<Key>c: Iconify() \n \
1287
<Key>C: Iconify() \n";
1290
char translationsTableReduced[] =
1291
"<Expose>: DrawPosition() \n \
1292
<Btn1Down>: HandleUserMove() \n \
1293
<Btn1Up>: HandleUserMove() \n \
1294
<Message>WM_PROTOCOLS: QuitProc() \n";
1297
char blackTranslations[] = "<BtnDown>: SetBlackToPlay()\n";
1298
char whiteTranslations[] = "<BtnDown>: SetWhiteToPlay()\n";
1300
String xshogiResources[] =
1303
"*Dialog*value.translations: #override "
1304
"\\n <Key>Return: FileNameAction()",
1309
int global_argc; /* number of command args */
1310
char *global_argv[10]; /* pointers to up to 10 command args */
1314
static struct DisplayData *player;
1323
static FileModeInfo fmi;
1326
/**********************************************************************
1330
**********************************************************************/
1334
CreatePlayerWindow(void)
1336
int mainFontPxlSize, coordFontPxlSize;
1337
int min, sec, matched;
1338
XSetWindowAttributes window_attributes;
1341
Dimension timerWidth, boardWidth, commandsWidth, w, h;
1343
int fromRemotePlayer = (player == &remotePlayer);
1345
player->monoMode = player->appData.monoMode;
1346
player->showCoords = player->appData.showCoords;
1349
* Parse timeControl resource.
1352
if (player->appData.timeControl != NULL)
1354
matched = sscanf(player->appData.timeControl, "%d:%d", &min, &sec);
1358
timeControl = min * 60 * 1000;
1360
else if (matched == 2)
1362
timeControl = (min * 60 + sec) * 1000;
1366
fprintf(stderr, "%s: bad timeControl option %s\n",
1367
programName, player->appData.timeControl);
1373
* Parse searchTime resource
1376
if (player->appData.searchTime != NULL)
1378
matched = sscanf(player->appData.searchTime, "%d:%d", &min, &sec);
1382
searchTime = min * 60;
1384
else if (matched == 2)
1386
searchTime = min * 60 + sec;
1390
fprintf(stderr, "%s: bad searchTime option %s\n",
1391
programName, player->appData.searchTime);
1396
if ((player->appData.searchTime != NULL)
1397
|| (player->appData.searchDepth > 0)
1398
|| player->appData.noShogiProgram)
1400
player->appData.clockMode = False;
1403
player->Iconic = False;
1404
player->boardSize = Small;
1405
player->squareSize = SMALL_SQUARE_SIZE;
1406
player->flipView = (player == &remotePlayer);
1407
player->promotionUp = False;
1410
* Determine boardSize.
1413
if (strcasecmp(player->appData.boardSize, "Large") == 0)
1415
player->boardSize = Large;
1417
else if (strcasecmp(player->appData.boardSize, "Medium") == 0)
1419
player->boardSize = Medium;
1421
else if (strcasecmp(player->appData.boardSize, "Small") == 0)
1423
player->boardSize = Small;
1427
fprintf(stderr, "%s: bad boardSize option %s\n",
1428
programName, player->appData.boardSize);
1432
if ((local = (player == &localPlayer)))
1434
player->xDisplay = XtDisplay(player->shellWidget);
1435
player->xScreen = DefaultScreen(player->xDisplay);
1438
if (((DisplayWidth(player->xDisplay, player->xScreen) < 800)
1439
|| (DisplayHeight(player->xDisplay, player->xScreen) < 800))
1440
&& (player->boardSize == Large))
1442
player->boardSize = Medium;
1445
switch (player->boardSize)
1448
player->squareSize = SMALL_SQUARE_SIZE;
1449
mainFontPxlSize = 11;
1450
coordFontPxlSize = 10;
1454
player->squareSize = MEDIUM_SQUARE_SIZE;
1455
mainFontPxlSize = 17;
1456
coordFontPxlSize = 12;
1461
player->squareSize = LARGE_SQUARE_SIZE;
1462
mainFontPxlSize = 17;
1463
coordFontPxlSize = 14;
1468
* Detect if there are not enough colors are available and adapt.
1471
if (DefaultDepth(player->xDisplay, player->xScreen) <= 2)
1472
player->monoMode = True;
1475
* Determine what fonts to use.
1478
player->appData.mainFont
1479
= FindFont(player->appData.mainFont, mainFontPxlSize);
1481
= XLoadFont(player->xDisplay, player->appData.mainFont);
1482
player->mainFontStruct
1483
= XQueryFont(player->xDisplay, player->mainFontID);
1484
player->appData.coordFont
1485
= FindFont(player->appData.coordFont, coordFontPxlSize);
1487
= XLoadFont(player->xDisplay, player->appData.coordFont);
1488
player->coordFontStruct
1489
= XQueryFont(player->xDisplay, player->coordFontID);
1492
* Set default arguments.
1495
XtSetArg(player->shellArgs[0], XtNwidth, 0);
1496
XtSetArg(player->shellArgs[1], XtNheight, 0);
1497
XtSetArg(player->shellArgs[2], XtNminWidth, 0);
1498
XtSetArg(player->shellArgs[3], XtNminHeight, 0);
1499
XtSetArg(player->shellArgs[4], XtNmaxWidth, 0);
1500
XtSetArg(player->shellArgs[5], XtNmaxHeight, 0);
1502
XtSetArg(player->boardArgs[0], XtNborderWidth, 0);
1503
XtSetArg(player->boardArgs[1], XtNwidth,
1504
LINE_GAP + (BOARD_SIZE + 4)
1505
* (SMALL_SQUARE_SIZE + LINE_GAP));
1506
XtSetArg(player->boardArgs[2], XtNheight,
1507
LINE_GAP + BOARD_SIZE
1508
* (SMALL_SQUARE_SIZE + LINE_GAP));
1510
XtSetArg(player->commandsArgs[0], XtNborderWidth, 0);
1511
XtSetArg(player->commandsArgs[1], XtNdefaultColumns, 4);
1512
XtSetArg(player->commandsArgs[2], XtNforceColumns, True);
1513
XtSetArg(player->commandsArgs[3], XtNcolumnSpacing, 12);
1514
XtSetArg(player->commandsArgs[4], XtNlist, (XtArgVal) buttonStrings);
1515
XtSetArg(player->commandsArgs[5], XtNnumberStrings, buttonCount);
1516
XtSetArg(player->commandsArgs[6], XtNfont, player->mainFontStruct);
1518
XtSetArg(player->messageArgs[0], XtNborderWidth, 0);
1519
XtSetArg(player->messageArgs[1], XtNjustify, (XtArgVal) XtJustifyLeft);
1520
XtSetArg(player->messageArgs[2], XtNlabel, (XtArgVal) "starting...");
1522
XtSetArg(player->timerArgs[0], XtNborderWidth, 0);
1523
XtSetArg(player->timerArgs[1], XtNjustify, (XtArgVal) XtJustifyLeft);
1525
XtSetArg(player->titleArgs[0], XtNborderWidth, 0);
1526
XtSetArg(player->titleArgs[1], XtNjustify, (XtArgVal) XtJustifyLeft);
1528
boardWidth = LINE_GAP
1529
+ (BOARD_SIZE + 4) * (player->squareSize + LINE_GAP);
1531
XtSetArg(player->boardArgs[1], XtNwidth, boardWidth);
1532
XtSetArg(player->boardArgs[2], XtNheight,
1533
LINE_GAP + BOARD_SIZE * (player->squareSize + LINE_GAP));
1539
player->formWidget = XtCreateManagedWidget("form",
1541
player->shellWidget, NULL, 0);
1543
player->widgetList[0] = player->blackTimerWidget
1544
= XtCreateWidget((local ? "black time:" : "rblack time:"),
1546
player->formWidget, player->timerArgs,
1547
XtNumber(player->timerArgs));
1549
XtSetArg(args[0], XtNfont, player->mainFontStruct);
1550
XtSetValues(player->blackTimerWidget, args, 1);
1552
player->widgetList[1] = player->whiteTimerWidget
1553
= XtCreateWidget((local ? "white time:" : "rwhite time:"),
1555
player->formWidget, player->timerArgs,
1556
XtNumber(player->timerArgs));
1558
XtSetArg(args[0], XtNfont, player->mainFontStruct);
1559
XtSetValues(player->whiteTimerWidget, args, 1);
1561
player->widgetList[2] = player->titleWidget
1562
= XtCreateWidget((local ? "" : "r"), labelWidgetClass,
1563
player->formWidget, player->titleArgs,
1564
XtNumber(player->titleArgs));
1566
XtSetArg(args[0], XtNfont, player->mainFontStruct);
1567
XtSetValues(player->titleWidget, args, 1);
1569
player->widgetList[3] = player->messageWidget
1570
= XtCreateWidget((local ? "message" : "rmessage"),
1571
labelWidgetClass, player->formWidget,
1572
player->messageArgs,
1573
XtNumber(player->messageArgs));
1575
XtSetArg(args[0], XtNfont, player->mainFontStruct);
1576
XtSetValues(player->messageWidget, args, 1);
1578
player->widgetList[4] = player->commandsWidget
1579
= XtCreateWidget((local ? "commands" : "rcommand"),
1580
listWidgetClass, player->formWidget,
1581
player->commandsArgs,
1582
XtNumber(player->commandsArgs));
1584
player->widgetList[5] = player->boardWidget
1585
= XtCreateWidget((local ? "board" : "rboard"),
1586
widgetClass, player->formWidget,
1588
XtNumber(player->boardArgs));
1590
XtManageChildren(player->widgetList, XtNumber(player->widgetList));
1593
* Calculate the width of the timer labels.
1596
XtSetArg(args[0], XtNfont, &player->mainFontStruct);
1597
XtGetValues(player->blackTimerWidget, args, 1);
1599
if (player->appData.clockMode)
1601
/* sprintf(buf, "Black: %s ", TimeString(timeControl));
1602
timerWidth = XTextWidth(player->mainFontStruct,
1603
buf, strlen(buf)); */
1604
timerWidth = XTextWidth(player->mainFontStruct,
1605
"Black: 8:88:88 ", 15);
1609
timerWidth = XTextWidth(player->mainFontStruct, "Black ", 7);
1612
XtSetArg(args[0], XtNwidth, timerWidth);
1613
XtSetValues(player->blackTimerWidget, args, 1);
1614
XtSetValues(player->whiteTimerWidget, args, 1);
1616
XtSetArg(args[0], XtNbackground, &player->timerForegroundPixel);
1617
XtSetArg(args[1], XtNforeground, &player->timerBackgroundPixel);
1618
XtGetValues(player->blackTimerWidget, args, 2);
1621
* Calculate the width of the name and message labels.
1624
XtSetArg(args[0], XtNwidth, &commandsWidth);
1625
XtGetValues(player->commandsWidget, args, 1);
1626
w = ((commandsWidth > boardWidth) ? commandsWidth : boardWidth);
1627
XtSetArg(args[0], XtNwidth, w - timerWidth*2 - 12);
1628
XtSetValues(player->titleWidget, args, 1);
1629
XtSetArg(args[0], XtNwidth, w - 8);
1630
XtSetValues(player->messageWidget, args, 1);
1633
* formWidget uses these constraints but they are stored
1637
XtSetArg(args[0], XtNfromHoriz, player->blackTimerWidget);
1638
XtSetValues(player->whiteTimerWidget, args, 1);
1639
XtSetArg(args[0], XtNfromHoriz, player->whiteTimerWidget);
1640
XtSetValues(player->titleWidget, args, 1);
1641
XtSetArg(args[0], XtNfromVert, player->blackTimerWidget);
1642
XtSetValues(player->messageWidget, args, 1);
1643
XtSetArg(args[0], XtNfromVert, player->messageWidget);
1644
XtSetValues(player->commandsWidget, args, 1);
1645
XtSetArg(args[0], XtNfromVert, player->commandsWidget);
1646
XtSetValues(player->boardWidget, args, 1);
1648
XtRealizeWidget(player->shellWidget);
1650
player->xBoardWindow = XtWindow(player->boardWidget);
1656
player->iconPixmap =
1657
XCreateBitmapFromData(player->xDisplay,
1658
XtWindow(player->shellWidget),
1659
icon_bits, icon_width, icon_height);
1661
XtSetArg(args[0], XtNiconPixmap, player->iconPixmap);
1662
XtSetValues(player->shellWidget, args, 1);
1665
* Create a cursor for the board widget.
1668
window_attributes.cursor = XCreateFontCursor(player->xDisplay, XC_hand2);
1669
XChangeWindowAttributes(player->xDisplay, player->xBoardWindow,
1670
CWCursor, &window_attributes);
1673
* Inhibit shell resizing.
1676
player->shellArgs[0].value = (XtArgVal) &w;
1677
player->shellArgs[1].value = (XtArgVal) &h;
1678
XtGetValues(player->shellWidget, player->shellArgs, 2);
1679
player->shellArgs[4].value = player->shellArgs[2].value = w;
1680
player->shellArgs[5].value = player->shellArgs[3].value = h;
1681
XtSetValues(player->shellWidget, &player->shellArgs[2], 4);
1684
* Determine value of black pixel.
1687
player->black_pixel_is_zero =
1688
(XBlackPixel(player->xDisplay, player->xScreen) == 0);
1694
if (!fromRemotePlayer)
1697
XtAddCallback(player->commandsWidget, XtNcallback, SelectCommand,
1698
(XtPointer)fromRemotePlayer);
1700
if (!fromRemotePlayer)
1701
XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
1703
if (fromRemotePlayer)
1705
XtSetArg(args[0], XtNtranslations,
1706
XtParseTranslationTable(translationsTableReduced));
1707
/* Disable key commands because often keys are pressed
1708
in the board window if using another talk window. */
1709
XtSetValues(player->boardWidget, &args[0], 1);
1710
XtSetValues(localPlayer.boardWidget, &args[0], 1);
1714
XtSetArg(args[0], XtNtranslations,
1715
XtParseTranslationTable(translationsTable));
1716
XtSetValues(player->boardWidget, &args[0], 1);
1717
XtSetArg(args[0], XtNtranslations,
1718
XtParseTranslationTable(blackTranslations));
1719
XtSetValues(player->blackTimerWidget, &args[0], 1);
1720
XtSetArg(args[0], XtNtranslations,
1721
XtParseTranslationTable(whiteTranslations));
1722
XtSetValues(player->whiteTimerWidget, &args[0], 1);
1725
XtAddEventHandler(player->boardWidget, ExposureMask | ButtonPressMask
1726
| ButtonReleaseMask | Button1MotionMask | KeyPressMask,
1727
False, (XtEventHandler)EventProc,
1728
(XtPointer)(player == &remotePlayer));
1730
sprintf(buf, "xshogi version %s, patchlevel %s based on "
1731
"xboard version %s",
1732
version, patchlevel, XBOARD_VERSION);
1735
* If there is to be a machine match, set it up.
1738
if (matchMode != MatchFalse && player != &remotePlayer)
1740
if (player->appData.noShogiProgram)
1743
"%s: can't have a match with no shogi programs!\n",
1748
DisplayMessage(buf, fromRemotePlayer);
1749
TwoMachinesProc(NULL, NULL, NULL, NULL);
1754
DisplayMessage(buf, fromRemotePlayer);
1762
main(int argc, char **argv)
1764
setbuf(stdout, NULL);
1765
setbuf(stderr, NULL);
1768
* Copy pointers to command line arguments and number of such pointers.
1769
* (argc, argv will be destroyed by XtAppInitialize)
1772
for (global_argc = 0; global_argc < argc; global_argc++)
1773
global_argv[global_argc] = argv[global_argc];
1775
programName = strrchr(argv[0], '/');
1777
if (programName == NULL)
1778
programName = argv[0];
1782
localPlayer.shellWidget
1783
= XtAppInitialize(&appContext, "XShogi", shellOptions,
1784
XtNumber(shellOptions), &argc, argv,
1785
xshogiResources, NULL, 0);
1790
if ((shogiDir = (char *)getenv("SHOGIDIR")) == NULL)
1796
if (chdir(shogiDir) != 0)
1798
fprintf(stderr, "%s: can't cd to SHOGIDIR\n",
1805
XtGetApplicationResources(localPlayer.shellWidget,
1806
&localPlayer.appData, clientResources,
1807
XtNumber(clientResources), NULL, 0);
1809
xshogiDebug = localPlayer.appData.debugMode;
1812
* Determine matchMode state -- poor man's resource converter
1815
if (strcasecmp(localPlayer.appData.matchMode, "Init") == 0)
1817
matchMode = MatchInit;
1819
else if (strcasecmp(localPlayer.appData.matchMode, "Position") == 0)
1821
matchMode = MatchPosition;
1823
else if (strcasecmp(localPlayer.appData.matchMode, "Opening") == 0)
1825
matchMode = MatchOpening;
1827
else if (strcasecmp(localPlayer.appData.matchMode, "False") == 0)
1829
matchMode = MatchFalse;
1833
fprintf(stderr, "%s: bad matchMode option %s\n",
1834
programName, localPlayer.appData.matchMode);
1838
buttonStrings = gnuButtonStrings;
1839
buttonProcs = gnuButtonProcs;
1840
buttonCount = XtNumber(gnuButtonStrings);
1842
player = &localPlayer;
1844
CreatePlayerWindow();
1846
XtAppMainLoop(appContext);
1854
* Find a font that matches "pattern" that is as close as
1855
* possible to the targetPxlSize. Prefer fonts that are k
1856
* pixels smaller to fonts that are k pixels larger. The
1857
* pattern must be in the X Consortium standard format,
1858
* e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
1859
* The return value should be freed with XtFree when no
1864
FindFont(char *pattern, int targetPxlSize)
1866
char **fonts, *p, *best;
1867
int i, j, nfonts, minerr, err, pxlSize;
1869
fonts = XListFonts(player->xDisplay, pattern, 999999, &nfonts);
1873
fprintf(stderr, "%s: No fonts match pattern %s\n",
1874
programName, pattern);
1881
for (i = 0; i < nfonts; i++)
1903
if (pxlSize == targetPxlSize)
1909
err = pxlSize - targetPxlSize;
1911
if (abs(err) < abs(minerr)
1912
|| ((minerr > 0) && (err < 0) && (-err == minerr)))
1919
p = (char *)XtMalloc(strlen(best) + 1);
1921
XFreeFontNames(fonts);
1931
XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
1932
| GCBackground | GCFunction | GCPlaneMask;
1933
XGCValues gc_values;
1935
gc_values.plane_mask = AllPlanes;
1936
gc_values.line_width = LINE_GAP;
1937
gc_values.line_style = LineSolid;
1938
gc_values.function = GXcopy;
1940
gc_values.foreground = XBlackPixel(player->xDisplay, player->xScreen);
1941
gc_values.background = XBlackPixel(player->xDisplay, player->xScreen);
1942
player->lineGC = XtGetGC(player->shellWidget, value_mask, &gc_values);
1944
gc_values.background = XWhitePixel(player->xDisplay, player->xScreen);
1945
player->coordGC = XtGetGC(player->shellWidget, value_mask, &gc_values);
1946
XSetFont(player->xDisplay, player->coordGC, player->coordFontID);
1948
if (player->monoMode)
1950
gc_values.foreground
1951
= XWhitePixel(player->xDisplay, player->xScreen);
1952
gc_values.background
1953
= XBlackPixel(player->xDisplay, player->xScreen);
1954
player->lightSquareGC = player->darkSquareGC = player->wbPieceGC
1955
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1956
gc_values.foreground
1957
= XBlackPixel(player->xDisplay, player->xScreen);
1958
gc_values.background
1959
= XWhitePixel(player->xDisplay, player->xScreen);
1961
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1965
/* white piece black background */
1966
gc_values.foreground
1967
= XWhitePixel(player->xDisplay, player->xScreen);
1968
gc_values.background
1969
= XBlackPixel(player->xDisplay, player->xScreen);
1971
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1973
/* black piece white background */
1974
gc_values.foreground
1975
= XBlackPixel(player->xDisplay, player->xScreen);
1976
gc_values.background
1977
= XWhitePixel(player->xDisplay, player->xScreen);
1979
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1981
/* light empty square */
1982
gc_values.foreground
1983
= player->appData.lightSquareColor;
1984
gc_values.background
1985
= player->appData.darkSquareColor;
1986
player->lightSquareGC
1987
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1989
/* dark empty square */
1990
gc_values.foreground
1991
= player->appData.darkSquareColor;
1992
gc_values.background
1993
= player->appData.lightSquareColor;
1994
player->darkSquareGC
1995
= XtGetGC(player->shellWidget, value_mask, &gc_values);
1997
/* black piece on dark square */
1998
gc_values.background
1999
= player->appData.blackPieceColor;
2000
gc_values.foreground
2001
= player->appData.darkSquareColor;
2003
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2005
/* black piece on light square */
2006
gc_values.background
2007
= player->appData.blackPieceColor;
2008
gc_values.foreground
2009
= player->appData.lightSquareColor;
2011
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2013
/* white piece on dark square */
2014
gc_values.background
2015
= player->appData.whitePieceColor;
2016
gc_values.foreground
2017
= player->appData.darkSquareColor;
2019
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2021
/* white piece on dark square */
2022
gc_values.background
2023
= player->appData.whitePieceColor;
2024
gc_values.foreground
2025
= player->appData.lightSquareColor;
2027
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2029
/* black piece off board */
2030
gc_values.background
2031
= player->appData.blackPieceColor;
2032
gc_values.foreground
2033
= XWhitePixel(player->xDisplay, player->xScreen);
2035
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2037
/* white piece off board */
2038
gc_values.background
2039
= player->appData.whitePieceColor;
2040
gc_values.foreground
2041
= XWhitePixel(player->xDisplay, player->xScreen);
2043
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2046
gc_values.function = (player->black_pixel_is_zero ? GXand : GXor);
2048
gc_values.foreground
2049
= XBlackPixel(player->xDisplay, player->xScreen);
2050
gc_values.background
2051
= XWhitePixel(player->xDisplay, player->xScreen);
2053
= XtGetGC(player->shellWidget, value_mask, &gc_values);
2063
XSynchronize(player->xDisplay, True); /* Work-around for xlib/xt
2066
if (player->appData.westernPieceSet)
2068
ReadBitmap(player->appData.reverseBigSolidBitmap,
2069
&player->reverseBigSolidBitmap,
2071
bigsolidR_bits, bigsolidR_bits, bigsolidR_bits);
2073
ReadBitmap(player->appData.reverseSmallSolidBitmap,
2074
&player->reverseSmallSolidBitmap,
2076
smallsolidR_bits, smallsolidR_bits, smallsolidR_bits);
2078
ReadBitmap(player->appData.normalBigSolidBitmap,
2079
&player->normalBigSolidBitmap,
2081
bigsolid_bits, bigsolid_bits, bigsolid_bits);
2083
ReadBitmap(player->appData.normalSmallSolidBitmap,
2084
&player->normalSmallSolidBitmap,
2086
smallsolid_bits, smallsolid_bits, smallsolid_bits);
2088
ReadBitmap(player->appData.reversePawnBitmap,
2089
&player->reversePawnBitmap,
2090
&player->reverseSmallSolidBitmap,
2091
pawnRW_bits, pawnRW_bits, pawnRW_bits);
2093
ReadBitmap(player->appData.reverseLanceBitmap,
2094
&player->reverseLanceBitmap,
2095
&player->reverseSmallSolidBitmap,
2096
lanceRW_bits, lanceRW_bits, lanceRW_bits);
2098
ReadBitmap(player->appData.reverseKnightBitmap,
2099
&player->reverseKnightBitmap,
2100
&player->reverseSmallSolidBitmap,
2101
knightRW_bits, knightRW_bits, knightRW_bits);
2103
ReadBitmap(player->appData.reverseSilverBitmap,
2104
&player->reverseSilverBitmap,
2105
&player->reverseBigSolidBitmap,
2106
silverRW_bits, silverRW_bits, silverRW_bits);
2108
ReadBitmap(player->appData.reverseGoldBitmap,
2109
&player->reverseGoldBitmap,
2110
&player->reverseBigSolidBitmap,
2111
goldRW_bits, goldRW_bits, goldRW_bits);
2113
ReadBitmap(player->appData.reverseRookBitmap,
2114
&player->reverseRookBitmap,
2115
&player->reverseBigSolidBitmap,
2116
rookRW_bits, rookRW_bits, rookRW_bits);
2118
ReadBitmap(player->appData.reverseBishopBitmap,
2119
&player->reverseBishopBitmap,
2120
&player->reverseBigSolidBitmap,
2121
bishopRW_bits, bishopRW_bits, bishopRW_bits);
2123
ReadBitmap(player->appData.reversePPawnBitmap,
2124
&player->reversePPawnBitmap,
2125
&player->reverseSmallSolidBitmap,
2126
pawnPRW_bits, pawnPRW_bits, pawnPRW_bits);
2128
ReadBitmap(player->appData.reversePLanceBitmap,
2129
&player->reversePLanceBitmap,
2130
&player->reverseSmallSolidBitmap,
2131
lancePRW_bits, lancePRW_bits, lancePRW_bits);
2133
ReadBitmap(player->appData.reversePKnightBitmap,
2134
&player->reversePKnightBitmap,
2135
&player->reverseSmallSolidBitmap,
2136
knightPRW_bits, knightPRW_bits, knightPRW_bits);
2138
ReadBitmap(player->appData.reversePSilverBitmap,
2139
&player->reversePSilverBitmap,
2140
&player->reverseBigSolidBitmap,
2141
silverPRW_bits, silverPRW_bits, silverPRW_bits);
2143
ReadBitmap(player->appData.reversePRookBitmap,
2144
&player->reversePRookBitmap,
2145
&player->reverseBigSolidBitmap,
2146
rookPRW_bits, rookPRW_bits, rookPRW_bits);
2148
ReadBitmap(player->appData.reversePBishopBitmap,
2149
&player->reversePBishopBitmap,
2150
&player->reverseBigSolidBitmap,
2151
bishopPRW_bits, bishopPRW_bits, bishopPRW_bits);
2153
ReadBitmap(player->appData.reverseKingBitmap,
2154
&player->reverseKingBitmap,
2155
&player->reverseBigSolidBitmap,
2156
kingRW_bits, kingRW_bits, kingRW_bits);
2158
ReadBitmap(player->appData.normalPawnBitmap,
2159
&player->normalPawnBitmap,
2160
&player->normalSmallSolidBitmap,
2161
pawnW_bits, pawnW_bits, pawnW_bits);
2163
ReadBitmap(player->appData.normalLanceBitmap,
2164
&player->normalLanceBitmap,
2165
&player->normalSmallSolidBitmap,
2166
lanceW_bits, lanceW_bits, lanceW_bits);
2168
ReadBitmap(player->appData.normalKnightBitmap,
2169
&player->normalKnightBitmap,
2170
&player->normalSmallSolidBitmap,
2171
knightW_bits, knightW_bits, knightW_bits);
2173
ReadBitmap(player->appData.normalSilverBitmap,
2174
&player->normalSilverBitmap,
2175
&player->normalBigSolidBitmap,
2176
silverW_bits, silverW_bits, silverW_bits);
2178
ReadBitmap(player->appData.normalGoldBitmap,
2179
&player->normalGoldBitmap,
2180
&player->normalBigSolidBitmap,
2181
goldW_bits, goldW_bits, goldW_bits);
2183
ReadBitmap(player->appData.normalRookBitmap,
2184
&player->normalRookBitmap,
2185
&player->normalBigSolidBitmap,
2186
rookW_bits, rookW_bits, rookW_bits);
2188
ReadBitmap(player->appData.normalBishopBitmap,
2189
&player->normalBishopBitmap,
2190
&player->normalBigSolidBitmap,
2191
bishopW_bits, bishopW_bits, bishopW_bits);
2193
ReadBitmap(player->appData.normalPPawnBitmap,
2194
&player->normalPPawnBitmap,
2195
&player->normalSmallSolidBitmap,
2196
pawnPW_bits, pawnPW_bits, pawnPW_bits);
2198
ReadBitmap(player->appData.normalPLanceBitmap,
2199
&player->normalPLanceBitmap,
2200
&player->normalSmallSolidBitmap,
2201
lancePW_bits, lancePW_bits, lancePW_bits);
2203
ReadBitmap(player->appData.normalPKnightBitmap,
2204
&player->normalPKnightBitmap,
2205
&player->normalSmallSolidBitmap,
2206
knightPW_bits, knightPW_bits, knightPW_bits);
2208
ReadBitmap(player->appData.normalPSilverBitmap,
2209
&player->normalPSilverBitmap,
2210
&player->normalBigSolidBitmap,
2211
silverPW_bits, silverPW_bits, silverPW_bits);
2213
ReadBitmap(player->appData.normalPRookBitmap,
2214
&player->normalPRookBitmap,
2215
&player->normalBigSolidBitmap,
2216
rookPW_bits, rookPW_bits, rookPW_bits);
2218
ReadBitmap(player->appData.normalPBishopBitmap,
2219
&player->normalPBishopBitmap,
2220
&player->normalBigSolidBitmap,
2221
bishopPW_bits, bishopPW_bits, bishopPW_bits);
2223
ReadBitmap(player->appData.normalKingBitmap,
2224
&player->normalKingBitmap,
2225
&player->normalBigSolidBitmap,
2226
kingW_bits, kingW_bits, kingW_bits);
2230
ReadBitmap(player->appData.reverseBigSolidBitmap,
2231
&player->reverseBigSolidBitmap,
2233
bigsolidR_bits, bigsolidR_m_bits, bigsolidR_l_bits);
2235
ReadBitmap(player->appData.reverseSmallSolidBitmap,
2236
&player->reverseSmallSolidBitmap,
2238
smallsolidR_bits, smallsolidR_m_bits, smallsolidR_l_bits);
2240
ReadBitmap(player->appData.normalBigSolidBitmap,
2241
&player->normalBigSolidBitmap,
2243
bigsolid_bits, bigsolid_m_bits, bigsolid_l_bits);
2245
ReadBitmap(player->appData.normalSmallSolidBitmap,
2246
&player->normalSmallSolidBitmap,
2248
smallsolid_bits, smallsolid_m_bits, smallsolid_l_bits);
2250
ReadBitmap(player->appData.reversePawnBitmap,
2251
&player->reversePawnBitmap,
2252
&player->reverseSmallSolidBitmap,
2253
pawnR_bits, pawnR_m_bits, pawnR_l_bits);
2255
ReadBitmap(player->appData.reverseLanceBitmap,
2256
&player->reverseLanceBitmap,
2257
&player->reverseSmallSolidBitmap,
2258
lanceR_bits, lanceR_m_bits, lanceR_l_bits);
2260
ReadBitmap(player->appData.reverseKnightBitmap,
2261
&player->reverseKnightBitmap,
2262
&player->reverseSmallSolidBitmap,
2263
knightR_bits, knightR_m_bits, knightR_l_bits);
2265
ReadBitmap(player->appData.reverseSilverBitmap,
2266
&player->reverseSilverBitmap,
2267
&player->reverseBigSolidBitmap,
2268
silverR_bits, silverR_m_bits, silverR_l_bits);
2270
ReadBitmap(player->appData.reverseGoldBitmap,
2271
&player->reverseGoldBitmap,
2272
&player->reverseBigSolidBitmap,
2273
goldR_bits, goldR_m_bits, goldR_l_bits);
2275
ReadBitmap(player->appData.reverseRookBitmap,
2276
&player->reverseRookBitmap,
2277
&player->reverseBigSolidBitmap,
2278
rookR_bits, rookR_m_bits, rookR_l_bits);
2280
ReadBitmap(player->appData.reverseBishopBitmap,
2281
&player->reverseBishopBitmap,
2282
&player->reverseBigSolidBitmap,
2283
bishopR_bits, bishopR_m_bits, bishopR_l_bits);
2285
ReadBitmap(player->appData.reversePPawnBitmap,
2286
&player->reversePPawnBitmap,
2287
&player->reverseSmallSolidBitmap,
2288
pawnPR_bits, pawnPR_m_bits, pawnPR_l_bits);
2290
ReadBitmap(player->appData.reversePLanceBitmap,
2291
&player->reversePLanceBitmap,
2292
&player->reverseSmallSolidBitmap,
2293
lancePR_bits, lancePR_m_bits, lancePR_l_bits);
2295
ReadBitmap(player->appData.reversePKnightBitmap,
2296
&player->reversePKnightBitmap,
2297
&player->reverseSmallSolidBitmap,
2298
knightPR_bits, knightPR_m_bits, knightPR_l_bits);
2300
ReadBitmap(player->appData.reversePSilverBitmap,
2301
&player->reversePSilverBitmap,
2302
&player->reverseBigSolidBitmap,
2303
silverPR_bits, silverPR_m_bits, silverPR_l_bits);
2305
ReadBitmap(player->appData.reversePRookBitmap,
2306
&player->reversePRookBitmap,
2307
&player->reverseBigSolidBitmap,
2308
rookPR_bits, rookPR_m_bits, rookPR_l_bits);
2310
ReadBitmap(player->appData.reversePBishopBitmap,
2311
&player->reversePBishopBitmap,
2312
&player->reverseBigSolidBitmap,
2313
bishopPR_bits, bishopPR_m_bits, bishopPR_l_bits);
2315
ReadBitmap(player->appData.reverseKingBitmap,
2316
&player->reverseKingBitmap,
2317
&player->reverseBigSolidBitmap,
2318
kingR_bits, kingR_m_bits, kingR_l_bits);
2320
ReadBitmap(player->appData.normalPawnBitmap,
2321
&player->normalPawnBitmap,
2322
&player->normalSmallSolidBitmap,
2323
pawn_bits, pawn_m_bits, pawn_l_bits);
2325
ReadBitmap(player->appData.normalLanceBitmap,
2326
&player->normalLanceBitmap,
2327
&player->normalSmallSolidBitmap,
2328
lance_bits, lance_m_bits, lance_l_bits);
2330
ReadBitmap(player->appData.normalKnightBitmap,
2331
&player->normalKnightBitmap,
2332
&player->normalSmallSolidBitmap,
2333
knight_bits, knight_m_bits, knight_l_bits);
2335
ReadBitmap(player->appData.normalSilverBitmap,
2336
&player->normalSilverBitmap,
2337
&player->normalBigSolidBitmap,
2338
silver_bits, silver_m_bits, silver_l_bits);
2340
ReadBitmap(player->appData.normalGoldBitmap,
2341
&player->normalGoldBitmap,
2342
&player->normalBigSolidBitmap,
2343
gold_bits, gold_m_bits, gold_l_bits);
2345
ReadBitmap(player->appData.normalRookBitmap,
2346
&player->normalRookBitmap,
2347
&player->normalBigSolidBitmap,
2348
rook_bits, rook_m_bits, rook_l_bits);
2350
ReadBitmap(player->appData.normalBishopBitmap,
2351
&player->normalBishopBitmap,
2352
&player->normalBigSolidBitmap,
2353
bishop_bits, bishop_m_bits, bishop_l_bits);
2355
ReadBitmap(player->appData.normalPPawnBitmap,
2356
&player->normalPPawnBitmap,
2357
&player->normalSmallSolidBitmap,
2358
pawnP_bits, pawnP_m_bits, pawnP_l_bits);
2360
ReadBitmap(player->appData.normalPLanceBitmap,
2361
&player->normalPLanceBitmap,
2362
&player->normalSmallSolidBitmap,
2363
lanceP_bits, lanceP_m_bits, lanceP_l_bits);
2365
ReadBitmap(player->appData.normalPKnightBitmap,
2366
&player->normalPKnightBitmap,
2367
&player->normalSmallSolidBitmap,
2368
knightP_bits, knightP_m_bits, knightP_l_bits);
2370
ReadBitmap(player->appData.normalPSilverBitmap,
2371
&player->normalPSilverBitmap,
2372
&player->normalBigSolidBitmap,
2373
silverP_bits, silverP_m_bits, silverP_l_bits);
2375
ReadBitmap(player->appData.normalPRookBitmap,
2376
&player->normalPRookBitmap,
2377
&player->normalBigSolidBitmap,
2378
rookP_bits, rookP_m_bits, rookP_l_bits);
2380
ReadBitmap(player->appData.normalPBishopBitmap,
2381
&player->normalPBishopBitmap,
2382
&player->normalBigSolidBitmap,
2383
bishopP_bits, bishopP_m_bits, bishopP_l_bits);
2385
ReadBitmap(player->appData.normalKingBitmap,
2386
&player->normalKingBitmap,
2387
&player->normalBigSolidBitmap,
2388
king_bits, king_m_bits, king_l_bits);
2392
XSynchronize(player->xDisplay, False); /* Work-around for xlib/xt
2400
ReadBitmapFile(Display *display, Drawable d, char *filename,
2401
unsigned int *width_return,
2402
unsigned int *height_return,
2403
Pixmap *bitmap_return,
2404
int *x_hot_return, int *y_hot_return)
2408
if ((n = XReadBitmapFile(display, d, filename,
2409
width_return, height_return,
2410
bitmap_return, x_hot_return, y_hot_return))
2417
/* transform a 1 plane pixmap to a k plane pixmap */
2418
return BitmapSuccess;
2426
* Create the X pixmap from .xbm file bitmap data. This may
2427
* have to be revised considerably.
2431
ReadBitmap(String name, Pixmap *pm, Pixmap *qm,
2432
char *small_bits, char *medium_bits, char *large_bits)
2438
|| (ReadBitmapFile(player->xDisplay, player->xBoardWindow, name,
2439
&w, &h, pm, &x_hot, &y_hot) != BitmapSuccess)
2440
|| (w != player->squareSize)
2441
|| (h != player->squareSize))
2443
unsigned long fg, bg;
2446
depth = DisplayPlanes(player->xDisplay, player->xScreen);
2448
if (player->monoMode)
2450
fg = XBlackPixel(player->xDisplay, player->xScreen);
2451
bg = XWhitePixel(player->xDisplay, player->xScreen);
2453
else if (qm == NULL)
2455
fg = player->appData.oneColor;
2456
bg = player->appData.zeroColor;
2460
fg = (player->black_pixel_is_zero ? 0 : ~0);
2461
bg = (player->black_pixel_is_zero ? ~0 : 0);
2464
switch (player->boardSize)
2467
*pm = XCreatePixmapFromBitmapData(player->xDisplay,
2468
player->xBoardWindow,
2476
*pm = XCreatePixmapFromBitmapData(player->xDisplay,
2477
player->xBoardWindow,
2485
*pm = XCreatePixmapFromBitmapData(player->xDisplay,
2486
player->xBoardWindow,
2504
offset = 2 * (player->squareSize + LINE_GAP);
2506
for (i = 0; i < BOARD_SIZE + 1; i++)
2508
player->gridSegments[i].x1 = offset;
2509
player->gridSegments[i + BOARD_SIZE + 1].y1 = 0;
2510
player->gridSegments[i].y1 = player->gridSegments[i].y2
2511
= LINE_GAP / 2 + (i * (player->squareSize + LINE_GAP));
2512
player->gridSegments[i].x2 = LINE_GAP + BOARD_SIZE *
2513
(player->squareSize + LINE_GAP) + offset;
2514
player->gridSegments[i + BOARD_SIZE + 1].x1
2515
= player->gridSegments[i + BOARD_SIZE + 1].x2 = LINE_GAP / 2
2516
+ (i * (player->squareSize + LINE_GAP)) + offset;
2517
player->gridSegments[i + BOARD_SIZE + 1].y2
2518
= BOARD_SIZE * (player->squareSize + LINE_GAP);
2526
CreatePieceMenus(void)
2531
ShogiSquare selection;
2533
XtSetArg(args[0], XtNlabel, "Black");
2534
blackPieceMenu = XtCreatePopupShell("menuW", simpleMenuWidgetClass,
2535
localPlayer.boardWidget, args, 1);
2537
for (i = 0; i < PIECE_MENU_SIZE; i++)
2539
String item = pieceMenuStrings[i];
2541
if (strcmp(item, "----") == 0)
2543
entry = XtCreateManagedWidget(item, smeLineObjectClass,
2544
blackPieceMenu, NULL, 0);
2548
entry = XtCreateManagedWidget(item, smeBSBObjectClass,
2549
blackPieceMenu, NULL, 0);
2550
selection = pieceMenuTranslation[0][i];
2551
XtAddCallback(entry, XtNcallback,
2552
(XtCallbackProc) PieceMenuSelect,
2553
(caddr_t)selection);
2555
if (selection == BlackPawn)
2557
XtSetArg(args[0], XtNpopupOnEntry, entry);
2558
XtSetValues(blackPieceMenu, args, 1);
2563
XtSetArg(args[0], XtNlabel, "White");
2564
whitePieceMenu = XtCreatePopupShell("menuB", simpleMenuWidgetClass,
2565
localPlayer.boardWidget, args, 1);
2567
for (i = 0; i < PIECE_MENU_SIZE; i++)
2569
String item = pieceMenuStrings[i];
2571
if (strcmp(item, "----") == 0)
2573
entry = XtCreateManagedWidget(item, smeLineObjectClass,
2574
whitePieceMenu, NULL, 0);
2578
entry = XtCreateManagedWidget(item, smeBSBObjectClass,
2579
whitePieceMenu, NULL, 0);
2580
selection = pieceMenuTranslation[1][i];
2581
XtAddCallback(entry, XtNcallback,
2582
(XtCallbackProc) PieceMenuSelect,
2583
(caddr_t)selection);
2585
if (selection == WhitePawn)
2587
XtSetArg(args[0], XtNpopupOnEntry, entry);
2588
XtSetValues(whitePieceMenu, args, 1);
2593
XtRegisterGrabAction(PieceMenuPopup, True,
2594
(unsigned)(ButtonPressMask|ButtonReleaseMask),
2595
GrabModeAsync, GrabModeAsync);
2602
PieceMenuPopup(Widget w, XEvent *event, String *params, Cardinal *num_params)
2604
if (event->type != ButtonPress)
2607
if (gameMode != EditPosition)
2610
if (((pmFromX = EventToXSquare(event->xbutton.x)) < 1)
2611
|| (pmFromX > BOARD_SIZE + 2)
2612
|| ((pmFromY = EventToSquare(event->xbutton.y)) < 0))
2614
pmFromX = pmFromY = -1;
2618
if (localPlayer.flipView)
2619
pmFromX = BOARD_SIZE + 3 - pmFromX;
2621
pmFromY = BOARD_SIZE - 1 - pmFromY;
2623
XtPopupSpringLoaded(XtNameToWidget(localPlayer.boardWidget, params[0]));
2630
PieceMenuSelect(Widget w, ShogiSquare piece, caddr_t junk)
2632
if ((pmFromX < 0) || (pmFromY < 0))
2635
if (off_board(pmFromX))
2650
i = pieceToCatchedIndex[piece];
2651
c = (piece >= WhitePawn);
2653
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
2654
XSync(localPlayer.xDisplay, False);
2664
for (pmFromY = 0; pmFromY < BOARD_SIZE; pmFromY++)
2665
for (pmFromX = 0; pmFromX < BOARD_SIZE; pmFromX++)
2666
boards[0][pmFromY][pmFromX] = EmptySquare;
2668
ClearCatches(catches[0]);
2669
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
2672
case BlackPlay: /* not currently on menu */
2676
case WhitePlay: /* not currently on menu */
2681
boards[0][pmFromY][pmFromX] = piece;
2682
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
2686
XSync(localPlayer.xDisplay, False);
2693
SetBlackToPlay(void)
2697
if (gameMode != EditPosition)
2700
whitePlaysFirst = False;
2701
saveCM = currentMove;
2702
currentMove = 0; /* kludge */
2703
DisplayClocks(ReDisplayTimers);
2704
currentMove = saveCM;
2711
SetWhiteToPlay(void)
2715
if (gameMode != EditPosition)
2718
whitePlaysFirst = True;
2719
saveCM = currentMove;
2720
currentMove = 1; /* kludge */
2721
DisplayClocks(ReDisplayTimers);
2722
currentMove = saveCM;
2729
* If the user selects on a border boundary or off the board, return failure.
2730
* Otherwise map the event coordinate to the square.
2734
EventToSquare(int x)
2741
if ((x % (player->squareSize + LINE_GAP)) >= player->squareSize)
2744
x /= (player->squareSize + LINE_GAP);
2746
if (x >= BOARD_SIZE)
2756
EventToXSquare(int x)
2763
if ((x % (player->squareSize + LINE_GAP)) >= player->squareSize)
2766
x /= (player->squareSize + LINE_GAP);
2768
if (x >= BOARD_SIZE + 4)
2778
CharToPiece(int c, int p)
2785
case '.': return EmptySquare;
2786
case 'P': return BlackPPawn;
2787
case 'L': return BlackPLance;
2788
case 'N': return BlackPKnight;
2789
case 'S': return BlackPSilver;
2790
case 'G': return BlackGold;
2791
case 'R': return BlackPRook;
2792
case 'B': return BlackPBishop;
2793
case 'K': return BlackKing;
2794
case 'p': return WhitePPawn;
2795
case 'l': return WhitePLance;
2796
case 'n': return WhitePKnight;
2797
case 's': return WhitePSilver;
2798
case 'g': return WhiteGold;
2799
case 'r': return WhitePRook;
2800
case 'b': return WhitePBishop;
2801
case 'k': return WhiteKing;
2809
case '.': return EmptySquare;
2810
case 'P': return BlackPawn;
2811
case 'L': return BlackLance;
2812
case 'N': return BlackKnight;
2813
case 'S': return BlackSilver;
2814
case 'G': return BlackGold;
2815
case 'R': return BlackRook;
2816
case 'B': return BlackBishop;
2817
case 'K': return BlackKing;
2818
case 'p': return WhitePawn;
2819
case 'l': return WhiteLance;
2820
case 'n': return WhiteKnight;
2821
case 's': return WhiteSilver;
2822
case 'g': return WhiteGold;
2823
case 'r': return WhiteRook;
2824
case 'b': return WhiteBishop;
2825
case 'k': return WhiteKing;
2834
* Convert coordinates to normal algebraic notation.
2835
* promoPiece must be NULLCHAR if not a promotion.
2839
MakeAlg(int fromX, int fromY, int toX, int toY,
2840
char promoPiece, int currentBoardIndex, char *out)
2847
piece = (fromX - 81);
2848
*outp++ = catchedIndexToChar[piece];
2850
*outp++ = '9' - toX;
2851
*outp++ = 'i' - toY;
2853
return (BlackOnMove(forwardMostMove) ? BlackDrop : WhiteDrop);
2857
*outp++ = '9' - fromX;
2858
*outp++ = 'i' - fromY;
2859
*outp++ = '9' - toX;
2860
*outp++ = 'i' - toY;
2861
*outp++ = promoPiece;
2864
if (promoPiece == NULLCHAR)
2870
return (BlackOnMove(forwardMostMove)
2871
? BlackPromotion : WhitePromotion);
2880
DrawSquare(int row, int column, ShogiSquare piece)
2882
int square_color, x, y, direction, font_ascent, font_descent;
2884
XCharStruct overall;
2885
struct DisplayData *player;
2887
for (player = &localPlayer; True; player = &remotePlayer)
2891
remote = (player == &remotePlayer);
2892
offset = 2 * (player->squareSize + LINE_GAP);
2894
if (player->flipView)
2896
x = LINE_GAP + ((BOARD_SIZE - 1) - column) *
2897
(player->squareSize + LINE_GAP) + offset;
2898
y = LINE_GAP + row * (player->squareSize + LINE_GAP);
2902
x = LINE_GAP + column * (player->squareSize + LINE_GAP) + offset;
2903
y = LINE_GAP + ((BOARD_SIZE - 1) - row) *
2904
(player->squareSize + LINE_GAP);
2907
square_color = (((column + row) % 2) ? LIGHT : DARK);
2909
if (piece == EmptySquare)
2911
if (column < 0 || column >= BOARD_SIZE)
2913
/* empty square off board */
2914
XFillRectangle(player->xDisplay, player->xBoardWindow,
2916
x, y, player->squareSize,
2917
player->squareSize);
2921
/* empty square on board */
2922
XFillRectangle(player->xDisplay, player->xBoardWindow,
2923
((square_color == LIGHT)
2924
? player->lightSquareGC
2925
: player->darkSquareGC),
2926
x, y, player->squareSize,
2927
player->squareSize);
2930
else if (player->monoMode)
2933
if (square_color == LIGHT)
2935
XCopyArea(player->xDisplay,
2936
((((((int)piece) < ((int)WhitePawn)))
2938
? *pieceToNormal[remote][(int)piece]
2939
: *pieceToReverse[remote][(int)piece]),
2940
player->xBoardWindow,
2943
: player->wlPieceGC),
2945
player->squareSize, player->squareSize, x, y);
2949
XCopyArea(player->xDisplay,
2950
((((((int)piece) < ((int)WhitePawn)))
2952
? *pieceToNormal[remote][(int)piece]
2953
: *pieceToReverse[remote][(int)piece]),
2954
player->xBoardWindow,
2957
: player->blPieceGC),
2959
player->squareSize, player->squareSize, x, y);
2965
if ((column < 0) || (column >= BOARD_SIZE))
2968
XCopyPlane(player->xDisplay,
2969
((((((int)piece) < ((int)WhitePawn)))
2971
? *pieceToNormalSolid[remote][(int)piece]
2972
: *pieceToReverseSolid[remote][(int)piece]),
2973
player->xBoardWindow,
2974
(pieceisWhite[(int)piece]
2976
: player->boPieceGC),
2978
player->squareSize, player->squareSize, x, y, 1);
2980
XCopyArea(player->xDisplay,
2981
((((((int)piece) < ((int)WhitePawn)))
2983
? *pieceToNormal[remote][(int)piece]
2984
: *pieceToReverse[remote][(int)piece]),
2985
player->xBoardWindow,
2986
player->charPieceGC,
2988
player->squareSize, player->squareSize, x, y);
2990
else if (square_color == LIGHT)
2992
/* on board, light square */
2993
XCopyPlane(player->xDisplay,
2994
((((((int)piece) < ((int)WhitePawn)))
2996
? *pieceToNormalSolid[remote][(int)piece]
2997
: *pieceToReverseSolid[remote][(int)piece]),
2998
player->xBoardWindow,
2999
pieceisWhite[(int)piece]
3001
: player->blPieceGC,
3003
player->squareSize, player->squareSize, x, y, 1);
3005
XCopyArea(player->xDisplay,
3006
((((((int)piece) < ((int)WhitePawn)))
3008
? *pieceToNormal[remote][(int)piece]
3009
: *pieceToReverse[remote][(int)piece]),
3010
player->xBoardWindow,
3011
player->charPieceGC,
3013
player->squareSize, player->squareSize, x, y);
3017
/* on board, dark square */
3018
XCopyPlane(player->xDisplay,
3019
((((((int)piece) < ((int)WhitePawn)))
3021
? *pieceToNormalSolid[remote][(int)piece]
3022
: *pieceToReverseSolid[remote][(int)piece]),
3023
player->xBoardWindow,
3024
(pieceisWhite[(int)piece]
3026
: player->bdPieceGC),
3028
player->squareSize, player->squareSize, x, y, 1);
3030
XCopyArea(player->xDisplay,
3031
((((((int)piece) < ((int)WhitePawn)))
3033
? *pieceToNormal[remote][(int)piece]
3034
: *pieceToReverse[remote][(int)piece]),
3035
player->xBoardWindow,
3036
player->charPieceGC,
3038
player->squareSize, player->squareSize, x, y);
3041
string[1] = NULLCHAR;
3043
if (player->showCoords
3044
&& (column >= 0) && (column < 9)
3045
&& (row == (player->flipView ? 8 : 0)))
3047
string[0] = '9' - column;
3048
XTextExtents(player->coordFontStruct, string, 1, &direction,
3049
&font_ascent, &font_descent, &overall);
3051
if (player->monoMode)
3053
XDrawImageString(player->xDisplay,
3054
player->xBoardWindow, player->coordGC,
3055
x + player->squareSize - overall.width - 2,
3056
y + player->squareSize - font_descent - 1,
3061
XDrawString(player->xDisplay, player->xBoardWindow,
3063
x + player->squareSize - overall.width - 2,
3064
y + player->squareSize - font_descent - 1,
3069
if (player->showCoords
3070
&& (row >= 0) && (row < 9)
3071
&& (column == (player->flipView ? 8 : 0)))
3073
string[0] = 'i' - row;
3074
XTextExtents(player->coordFontStruct, string, 1, &direction,
3075
&font_ascent, &font_descent, &overall);
3077
if (player->monoMode)
3079
XDrawImageString(player->xDisplay,
3080
player->xBoardWindow, player->coordGC,
3081
x + 2, y + font_ascent + 1, string, 1);
3085
XDrawString(player->xDisplay, player->xBoardWindow,
3087
x + 2, y + font_ascent + 1, string, 1);
3091
if (!updateRemotePlayer || (player == &remotePlayer))
3100
EventProc(Widget widget, caddr_t client_data, XEvent *event)
3102
if (event->type == MappingNotify)
3104
XRefreshKeyboardMapping((XMappingEvent *) event);
3108
if (!XtIsRealized(widget))
3111
if ((event->type == ButtonPress) || (event->type == ButtonRelease))
3113
if (event->xbutton.button != Button1)
3117
switch (event->type)
3120
DrawPosition(widget, event, NULL, NULL);
3132
* event handler for redrawing the board
3136
DrawPosition(Widget w, XEvent *event, String *prms, Cardinal *nprms)
3140
static Board lastBoard;
3141
static Catched lastCatches;
3142
static int lastBoardValid = 0;
3143
static int lastFlipView = 0, lastRemoteFlipView = 1;
3145
if (!player->Iconic)
3147
XtSetArg(args[0], XtNiconic, False);
3148
XtSetValues(localPlayer.shellWidget, args, 1);
3152
* It would be simpler to clear the window with XClearWindow()
3153
* but this causes a very distracting flicker.
3156
if ((w == localPlayer.boardWidget)
3159
&& (lastFlipView == localPlayer.flipView)
3160
&& (!updateRemotePlayer
3161
|| (lastRemoteFlipView == remotePlayer.flipView)))
3163
for (i = 0; i < BOARD_SIZE; i++)
3165
for (j = 0; j < BOARD_SIZE; j++)
3167
if (boards[currentMove][i][j] != lastBoard[i][j])
3168
DrawSquare(i, j, boards[currentMove][i][j]);
3172
for (i = 0; i < 2; i++)
3174
for (j = 0; j < 8; j++)
3176
if (catches[currentMove][i][j] != lastCatches[i][j])
3178
UpdateCatched(i, 0, False, True, currentMove);
3186
XDrawSegments(localPlayer.xDisplay,
3187
localPlayer.xBoardWindow, localPlayer.lineGC,
3188
localPlayer.gridSegments, (BOARD_SIZE + 1) * 2);
3190
if (updateRemotePlayer)
3192
XDrawSegments(remotePlayer.xDisplay,
3193
remotePlayer.xBoardWindow, remotePlayer.lineGC,
3194
remotePlayer.gridSegments, (BOARD_SIZE + 1) * 2);
3197
for (i = 0; i < BOARD_SIZE; i++)
3198
for (j = 0; j < BOARD_SIZE; j++)
3199
DrawSquare(i, j, boards[currentMove][i][j]);
3201
UpdateCatched(0, 0, False, True, currentMove);
3202
UpdateCatched(1, 0, False, True, currentMove);
3205
CopyBoard(lastBoard, boards[currentMove]);
3206
CopyCatches(lastCatches, catches[currentMove]);
3208
lastFlipView = localPlayer.flipView;
3210
if (updateRemotePlayer)
3211
lastRemoteFlipView = remotePlayer.flipView;
3213
XSync(localPlayer.xDisplay, False);
3215
if (updateRemotePlayer)
3216
XSync(remotePlayer.xDisplay, False);
3223
InitPosition(int redraw)
3225
currentMove = forwardMostMove = backwardMostMove = 0;
3226
CopyBoard(boards[0], initialPosition);
3227
ClearCatches(catches[0]);
3230
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
3237
CopyBoard(Board to, Board from)
3241
for (i = 0; i < BOARD_SIZE; i++)
3242
for (j = 0; j < BOARD_SIZE; j++)
3243
to[i][j] = from[i][j];
3250
CopyCatches(Catched to, Catched from)
3254
for (i = 0; i < 2; i++)
3255
for (j = 0; j < 8; j++)
3256
to[i][j] = from[i][j];
3263
SendCurrentBoard(FILE *fp)
3265
SendBoard(fp, boards[currentMove], catches[currentMove]);
3272
SendBoard(FILE *fp, Board board, Catched catches)
3274
char message[MSG_SIZ];
3278
SendToProgram("edit\n", fp);
3279
SendToProgram("#\n", fp);
3281
for (i = BOARD_SIZE - 1; i >= 0; i--)
3285
for (j = 0; j < BOARD_SIZE; j++, bp++)
3287
if (((int) *bp) < (int)WhitePawn)
3289
sprintf(message, "%c%c%c%s\n",
3290
pieceToChar[(int) *bp],
3292
(pieceIsPromoted[(int) *bp] ? "+" : ""));
3293
SendToProgram(message, fp);
3298
for (i = 0; i <= 7; i++)
3302
for (n = catches[0][i]; n > 0; n--)
3304
sprintf(message, "%c*\n",
3305
catchedIndexToChar[i]);
3306
SendToProgram(message, fp);
3310
SendToProgram("c\n", fp);
3312
for (i = BOARD_SIZE - 1; i >= 0; i--)
3316
for (j = 0; j < BOARD_SIZE; j++, bp++)
3318
if ((((int) *bp) != ((int)EmptySquare))
3319
&& (((int) *bp) >= ((int)WhitePawn)))
3321
sprintf(message, "%c%c%c%s\n",
3322
pieceToChar[((int) *bp) - ((int)WhitePawn)],
3324
(pieceIsPromoted[(int) *bp] ? "+" : ""));
3325
SendToProgram(message, fp);
3330
for (i = 0; i <= 7; i++)
3334
for (n = catches[1][i]; n > 0; n--)
3336
sprintf(message, "%c*\n",
3337
catchedIndexToChar[i]);
3338
SendToProgram(message, fp);
3342
SendToProgram(".\n", fp);
3349
PromotionPossible(int fromY, int toY, ShogiSquare piece)
3351
if (((int)piece) < ((int)WhitePawn))
3353
if ((fromY < 6) && (toY < 6))
3358
if ((fromY > 2) && (toY > 2))
3362
return piecePromotable[(int)piece];
3370
ShowCount(int row, int column, int n)
3372
int offset = 2 * (player->squareSize + LINE_GAP);
3373
int x, y, direction, font_ascent, font_descent;
3375
XCharStruct overall;
3376
struct DisplayData *player;
3378
DrawSquare(row, column, EmptySquare);
3383
for (player = &localPlayer; True; player = &remotePlayer)
3385
if (player->flipView)
3387
x = LINE_GAP + ((BOARD_SIZE - 1) - column) *
3388
(player->squareSize + LINE_GAP) + offset;
3389
y = LINE_GAP + row * (player->squareSize + LINE_GAP);
3393
x = LINE_GAP + column * (player->squareSize + LINE_GAP) + offset;
3394
y = LINE_GAP + ((BOARD_SIZE - 1) - row) *
3395
(player->squareSize + LINE_GAP);
3398
x -= player->squareSize / 2;
3400
string[1] = NULLCHAR;
3405
string[0] = '0' + n;
3407
XTextExtents(player->coordFontStruct, string, 1, &direction,
3408
&font_ascent, &font_descent, &overall);
3410
if (player->monoMode)
3412
XDrawImageString(player->xDisplay, player->xBoardWindow,
3414
x + player->squareSize - overall.width - 2,
3415
y + player->squareSize - font_descent - 1,
3420
XDrawString(player->xDisplay, player->xBoardWindow,
3422
x + player->squareSize - overall.width - 2,
3423
y + player->squareSize - font_descent - 1,
3427
if (!updateRemotePlayer || (player == &remotePlayer))
3436
UpdateCatched(int Color, int Figure, int Drop, int DropAll, int currentMove)
3441
/* Determine first row and column. */
3457
n = catches[currentMove][Color][Figure];
3459
/* Update the display for captured pieces
3460
if no piece of the dropped type is there (Drop && n==1)
3461
or if a piece type is removed (NOT Drop && n==0).
3462
In the other cases update only the count. */
3464
if (DropAll || (Drop && (n == 1)) || (!Drop && (n == 0)))
3466
/* show all captured pieces */
3469
for (F = pawn; F <= king; F++)
3473
if ((c = catches[currentMove][Color][F]) > 0)
3476
DrawSquare(y, x, catchedIndexToPiece[Color][F]);
3477
ShowCount(y, (Color ? (x - 1) : (x + 1)), c);
3490
DrawSquare(y, x, EmptySquare);
3491
ShowCount(y, (Color ? (x - 1) : (x + 1)), 0);
3501
/* remove one line! */
3502
DrawSquare(y, x, EmptySquare);
3503
ShowCount(y, (Color ? (x - 1) : (x + 1)), 0);
3508
/* show the actual count */
3509
for (F = pawn; F <= Figure - 1; F++)
3511
if (catches[currentMove][Color][F] > 0)
3520
ShowCount(y, (Color ? (x - 1) : (x + 1)), n);
3529
static int BlinkCount = 0;
3530
static int BlinkRow, BlinkCol;
3531
static ShogiSquare BlinkPiece;
3535
BlinkSquareProc(void)
3540
DrawSquare (BlinkRow, BlinkCol,
3541
((BlinkCount & 1) ? EmptySquare : BlinkPiece));
3546
= XtAppAddTimeOut(appContext,
3548
(XtTimerCallbackProc)BlinkSquareProc,
3562
BlinkSquare(int row, int col, ShogiSquare piece)
3564
BlinkCount = 2 * BLINK_COUNT + 1;
3572
#endif /* BLINK_COUNT */
3578
PieceOfCatched(int color, int x, int y, int currentMove)
3595
for (F = pawn, n = 0; F <= king; F++)
3597
if (catches[currentMove][color][F] > 0)
3613
* event handler for parsing user moves
3617
HandleUserMove(Widget w, XEvent *event)
3619
ShogiMove move_type;
3620
ShogiSquare from_piece;
3621
int to_x, to_y, fromRemotePlayer;
3623
if (updateRemotePlayer)
3625
if (((w != localPlayer.boardWidget)
3626
&& (w != remotePlayer.boardWidget))
3627
|| (matchMode != MatchFalse))
3632
fromRemotePlayer = (w == remotePlayer.boardWidget);
3636
if ((w != localPlayer.boardWidget) || (matchMode != MatchFalse))
3639
fromRemotePlayer = False;
3642
player = (fromRemotePlayer ? &remotePlayer : &localPlayer);
3644
if (player->promotionUp)
3646
XtPopdown(player->promotionShell);
3647
XtDestroyWidget(player->promotionShell);
3648
player->promotionUp = False;
3655
case PlayFromGameFile:
3656
case TwoMachinesPlay:
3659
case MachinePlaysBlack:
3660
if (BlackOnMove(forwardMostMove))
3662
DisplayMessage("It is not your turn", fromRemotePlayer);
3668
case MachinePlaysWhite:
3669
if (!BlackOnMove(forwardMostMove))
3671
DisplayMessage("It is not your turn", fromRemotePlayer);
3678
forwardMostMove = currentMove;
3685
if (currentMove != forwardMostMove)
3687
DisplayMessage("Displayed position is not current",
3692
switch (event->type)
3695
if ((fromX >= 0) || (fromY >= 0))
3698
if (((fromX = EventToXSquare(event->xbutton.x)) < 1)
3699
|| (fromX > BOARD_SIZE + 2)
3700
|| ((fromY = EventToSquare(event->xbutton.y)) < 0))
3706
if (player->flipView)
3707
fromX = BOARD_SIZE + 3 - fromX;
3709
fromY = BOARD_SIZE - 1 - fromY;
3714
if ((fromX < 0) || (fromY < 0))
3717
if (((to_x = EventToXSquare(event->xbutton.x)) < 1)
3718
|| (to_x > BOARD_SIZE + 2)
3719
|| ((to_y = EventToSquare(event->xbutton.y)) < 0))
3721
if (gameMode == EditPosition && !off_board(fromX))
3724
boards[0][fromY][fromX] = EmptySquare;
3725
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
3726
XSync(localPlayer.xDisplay, False);
3728
if (updateRemotePlayer)
3729
XSync(remotePlayer.xDisplay, False);
3736
if (player->flipView)
3737
to_x = BOARD_SIZE + 3 - to_x;
3739
to_y = BOARD_SIZE - 1 - to_y;
3741
if ((fromX == to_x) && (fromY == to_y))
3747
if (gameMode == EditPosition)
3751
if (off_board(fromX))
3753
/* Remove a catched piece */
3755
c = ((fromX < 5) ^ player->flipView);
3756
i = PieceOfCatched(c, fromX, fromY, 0);
3765
piece = catchedIndexToPiece[c][i];
3771
/* remove piece from board field */
3773
piece = boards[0][fromY][fromX];
3774
boards[0][fromY][fromX] = EmptySquare;
3777
if (!off_board(to_x))
3779
/* drop piece to board field */
3780
ShogiSquare catched_piece;
3782
catched_piece = boards[0][to_y][to_x];
3784
if (catched_piece != EmptySquare)
3786
/* put piece to catched pieces */
3787
int i = pieceToCatchedIndex[catched_piece];
3788
int c = (catched_piece < WhitePawn);
3792
/* place moved piece */
3793
boards[0][to_y][to_x] = piece;
3797
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
3798
XSync(localPlayer.xDisplay, False);
3800
if (updateRemotePlayer)
3801
XSync(remotePlayer.xDisplay, False);
3806
if (off_board(fromX))
3808
int c = (BlackOnMove(forwardMostMove) ? 0 : 1);
3809
int piece = PieceOfCatched(c, fromX, fromY, currentMove);
3811
if (piece == no_piece)
3818
if (updateRemotePlayer
3819
&& (BlackOnMove(forwardMostMove) == fromRemotePlayer))
3821
DisplayMessage("do not drop opponent pieces",
3827
fromX = fromY = piece + 81;
3829
move_type = (BlackOnMove(forwardMostMove)
3830
? BlackDrop : WhiteDrop);
3831
MakeMove(&move_type, fromX, fromY, to_x, to_y);
3834
if (updateRemotePlayer)
3835
BlinkSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
3838
FinishUserMove(move_type, to_x, to_y);
3842
else if (off_board(to_x))
3851
from_piece = boards[currentMove][fromY][fromX];
3853
if ((from_piece != EmptySquare)
3854
&& updateRemotePlayer
3855
&& ((from_piece < WhitePawn) == fromRemotePlayer))
3857
DisplayMessage("do not move opponent pieces",
3863
if (PromotionPossible(fromY, to_y, from_piece))
3865
PromotionPopUp(from_piece, to_x, to_y, fromRemotePlayer);
3869
move_type = NormalMove;
3870
MakeMove(&move_type, fromX, fromY, to_x, to_y);
3873
if (updateRemotePlayer)
3874
BlinkSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
3877
FinishUserMove(move_type, to_x, to_y);
3887
FinishUserMove(ShogiMove move_type, int to_x, int to_y)
3889
char user_move[MSG_SIZ];
3891
/* output move for gnushogi */
3894
case BlackPromotion:
3895
case WhitePromotion:
3896
sprintf(user_move, "%c%c%c%c+\n",
3897
'9' - fromX, 'i' - fromY, '9' - to_x, 'i' - to_y);
3902
sprintf(user_move, "%c*%c%c\n",
3903
catchedIndexToChar[fromX - 81], '9' - to_x, 'i' - to_y);
3907
sprintf(user_move, "%c%c%c%c\n",
3908
'9' - fromX, 'i' - fromY, '9' - to_x, 'i' - to_y);
3912
fprintf(stderr, "%s: internal error; bad move_type\n",
3913
(char *)programName);
3917
Attention(firstProgramPID);
3920
SendTimeRemaining(toFirstProgFP);
3922
SendToProgram(user_move, toFirstProgFP);
3923
strcpy(moveList[currentMove - 1], user_move);
3927
if (gameMode == PauseGame)
3929
/* a user move restarts a paused game*/
3930
PauseProc(NULL, NULL, NULL, NULL);
3938
case BeginningOfGame:
3939
if (localPlayer.appData.noShogiProgram)
3940
lastGameMode = gameMode = ForceMoves;
3942
lastGameMode = gameMode = MachinePlaysWhite;
3947
case MachinePlaysWhite:
3948
case MachinePlaysBlack:
3957
/* Simple parser for moves from gnushogi. */
3959
ParseMachineMove(char *machine_move, ShogiMove *move_type,
3960
int *from_x, int *from_y, int *to_x, int *to_y)
3962
#define no_digit(c) (c < '0' || c > '9')
3964
if (no_digit(machine_move[0]))
3966
switch (machine_move[0])
4005
*to_x = '9' - machine_move[2];
4006
*to_y = 'i' - machine_move[3];
4010
*from_x = '9' - machine_move[0] ;
4011
*from_y = 'i' - machine_move[1];
4012
*to_x = '9' - machine_move[2];
4013
*to_y = 'i' - machine_move[3];
4015
switch (machine_move[4])
4018
*move_type = (BlackOnMove(forwardMostMove)
4019
? BlackPromotion : WhitePromotion);
4023
*move_type = NormalMove;
4034
SkipString(char **mpr)
4036
while (**mpr == ' ')
4039
while ((**mpr != ' ') && (**mpr != NULLCHAR) && (**mpr != '\n'))
4042
while (**mpr == ' ')
4050
HandleMachineMove(char *message, FILE *fp)
4052
char machine_move[MSG_SIZ], buf1[MSG_SIZ], buf2[MSG_SIZ];
4053
int from_x, from_y, to_x, to_y;
4054
ShogiMove move_type;
4058
long time_remaining;
4061
maybeThinking = False;
4063
if (strncmp(message, "warning:", 8) == 0)
4065
DisplayMessage(message, False);
4067
if (updateRemotePlayer)
4068
DisplayMessage(message, True);
4074
* If shogi program startup fails, exit with an error message.
4075
* Attempts to recover here are futile.
4078
if ((strstr(message, "unknown host") != NULL)
4079
|| (strstr(message, "No remote directory") != NULL)
4080
|| (strstr(message, "not found") != NULL)
4081
|| (strstr(message, "No such file") != NULL)
4082
|| (strstr(message, "Permission denied") != NULL))
4085
"%s: failed to start shogi program %s on %s: %s\n",
4087
((fp == fromFirstProgFP)
4088
? localPlayer.appData.firstShogiProgram
4089
: localPlayer.appData.secondShogiProgram),
4090
((fp == fromFirstProgFP)
4091
? localPlayer.appData.firstHost
4092
: localPlayer.appData.secondHost),
4094
ShutdownShogiPrograms(message);
4099
* If the move is illegal, cancel it and redraw the board.
4102
if (strncmp(message, "Illegal move", 12) == 0)
4104
if (fp == fromFirstProgFP && firstSendTime == 2)
4106
/* First program doesn't have the "time" command */
4110
else if (fp == fromSecondProgFP && secondSendTime == 2)
4112
/* Second program doesn't have the "time" command */
4117
if (forwardMostMove <= backwardMostMove)
4120
if (gameMode == PauseGame)
4121
PauseProc(NULL, NULL, NULL, NULL);
4123
if (gameMode == PlayFromGameFile)
4125
/* Stop reading this game file */
4126
gameMode = ForceMoves;
4130
currentMove = --forwardMostMove;
4132
if ((gameMode == PlayFromGameFile)
4133
|| (gameMode == ForceMoves))
4134
DisplayClocks(ReDisplayTimers);
4136
DisplayClocks(SwitchTimers);
4138
sprintf(buf1, "Illegal move: %s", parseList[currentMove]);
4139
DisplayMessage(buf1, False);
4141
if (updateRemotePlayer)
4142
DisplayMessage(buf1, True);
4146
* Disable blinking of the target square.
4151
/* If BlinkCount is even, the piece is currently displayed. */
4152
if (!(BlinkCount & 1))
4153
DrawSquare (BlinkRow, BlinkCol, EmptySquare);
4155
/* BlinkCount = 0 will force the next blink timeout
4161
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
4163
XSync(localPlayer.xDisplay, False);
4165
if (updateRemotePlayer)
4166
XSync(remotePlayer.xDisplay, False);
4171
if (strstr(message, "GNU Shogi") != NULL)
4173
at_least_gnushogi_1_2p03 = True;
4177
if (strncmp(message, "Hint:", 5) == 0)
4180
sscanf(message, "Hint: %s", machine_move);
4181
ParseMachineMove(machine_move, &move_type,
4182
&from_x, &from_y, &to_x, &to_y);
4184
if (move_type == WhitePromotion || move_type == BlackPromotion)
4187
promoPiece = NULLCHAR;
4189
move_type = MakeAlg(from_x, from_y, to_x, to_y, promoPiece,
4191
sprintf(buf2, "Hint: %s", buf1);
4192
DisplayMessage(buf2, False);
4194
if (updateRemotePlayer)
4195
DisplayMessage(buf2, True);
4200
if (strncmp(message, "Clocks:", 7) == 0)
4202
sscanf(message, "Clocks: %ld %ld",
4203
&blackTimeRemaining, &whiteTimeRemaining);
4204
DisplayClocks(ReDisplayTimers);
4213
if (strncmp(message, "Black", 5) == 0)
4215
ShutdownShogiPrograms("Black wins");
4218
else if (strncmp(message, "White", 5) == 0)
4220
ShutdownShogiPrograms("White wins");
4223
else if (strncmp(message, "Repetition", 10) == 0)
4225
ShutdownShogiPrograms("Repetition");
4228
else if (strncmp(message, "opponent mates!", 15) == 0)
4230
switch ((gameMode == PauseGame) ? pausePreviousMode : gameMode)
4232
case MachinePlaysWhite:
4233
ShutdownShogiPrograms("Black wins");
4236
case MachinePlaysBlack:
4237
ShutdownShogiPrograms("White wins");
4240
case TwoMachinesPlay:
4241
ShutdownShogiPrograms((fp == fromFirstProgFP)
4242
? "Black wins" : "White wins");
4252
else if (strncmp(message, "computer mates!", 15) == 0)
4254
switch ((gameMode == PauseGame) ? pausePreviousMode : gameMode)
4256
case MachinePlaysWhite:
4257
ShutdownShogiPrograms("White wins");
4260
case MachinePlaysBlack:
4261
ShutdownShogiPrograms("Black wins");
4264
case TwoMachinesPlay:
4265
ShutdownShogiPrograms((fp == fromFirstProgFP)
4266
? "White wins" : "Black wins");
4276
else if (strncmp(message, "Draw", 4) == 0)
4278
ShutdownShogiPrograms("Draw");
4283
* normal machine reply move
4285
maybeThinking = True;
4287
if (strstr(message, "...") != NULL)
4289
sscanf(message, "%s %s %s", buf1, buf2, machine_move);
4293
SkipString(&mpr); /* skip move number */
4294
SkipString(&mpr); /* skip ... */
4295
SkipString(&mpr); /* skip move */
4297
if ((gameMode != TwoMachinesPlay) && (gameMode != ForceMoves)
4298
&& ((*mpr == '-') || ((*mpr >= '0') && (*mpr <= '9'))))
4300
/* synchronize with shogi program clock */
4301
sscanf(mpr, "%ld", &time_remaining);
4305
printf("from '%s' synchronize %s clock %ld\n",
4307
(BlackOnMove(forwardMostMove)
4313
if (BlackOnMove(forwardMostMove))
4314
blackTimeRemaining = time_remaining;
4316
whiteTimeRemaining = time_remaining;
4320
if (machine_move[0] == NULLCHAR)
4328
if (strstr(message, "time") == NULL)
4330
/* remaining time will be determined from move */
4331
SkipString(&mpr); /* skip move number */
4332
SkipString(&mpr); /* skip move */
4335
if ((gameMode != TwoMachinesPlay) && (gameMode != ForceMoves)
4336
&& ((*mpr == '-') || ((*mpr >= '0') && (*mpr <= '9'))))
4338
/* synchronize with shogi program clock */
4339
sscanf(mpr, "%ld", &time_remaining);
4343
printf("from '%s' synchronize %s clock %ld\n",
4345
((!BlackOnMove(forwardMostMove))
4346
? "Black's" : "White's"),
4350
if (!BlackOnMove(forwardMostMove))
4351
blackTimeRemaining = time_remaining;
4353
whiteTimeRemaining = time_remaining;
4359
printf("ignore noise: '%s'\n", message);
4361
return; /* ignore noise */
4364
strcpy(moveList[forwardMostMove], machine_move);
4366
ParseMachineMove(machine_move, &move_type, &from_x, &from_y,
4369
if (gameMode != PauseGame)
4370
currentMove = forwardMostMove; /* display latest move */
4372
MakeMove(&move_type, from_x, from_y, to_x, to_y);
4375
if (gameMode != TwoMachinesPlay)
4376
BlinkSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
4379
if ((gameMode != PauseGame) && localPlayer.appData.ringBellAfterMoves)
4380
putc(BELLCHAR, stderr);
4382
if ((gameMode == TwoMachinesPlay)
4383
|| ((gameMode == PauseGame)
4384
&& (pausePreviousMode == TwoMachinesPlay)))
4386
strcat(machine_move, "\n");
4388
if (BlackOnMove(forwardMostMove))
4390
Attention(secondProgramPID);
4393
SendTimeRemaining(toSecondProgFP);
4395
SendToProgram(machine_move, toSecondProgFP);
4400
SendToProgram(localPlayer.appData.blackString,
4406
Attention(firstProgramPID);
4409
SendTimeRemaining(toFirstProgFP);
4411
SendToProgram(machine_move, toFirstProgFP);
4416
SendToProgram(localPlayer.appData.blackString,
4431
if (!ReadGameFileProc())
4434
if (matchMode == MatchOpening)
4438
= XtAppAddTimeOut(appContext,
4439
(int)(1000 * localPlayer.appData.timeDelay),
4440
(XtTimerCallbackProc) ReadGameFile, NULL);
4448
* FIXME: there is a naming inconsistency: here ReadGameFileProc() is
4449
* called by ReadGameFile() while in other places XXXProc() calls XXX().
4453
ReadGameFileProc(void)
4455
ShogiMove move_type;
4456
char move[MSG_SIZ], buf[MSG_SIZ];
4458
if (gameFileFP == NULL)
4461
if (gameMode == PauseGame)
4464
if (gameMode != PlayFromGameFile)
4473
XtPopdown(commentShell);
4474
XtDestroyWidget(commentShell);
4478
fgets(move, MSG_SIZ, gameFileFP);
4479
move[strlen(move) - 1] = NULLCHAR;
4480
sprintf(buf, "# %s game file", programName);
4482
if (strncmp(move, buf, strlen(buf)))
4484
strcat(move, ": no xshogi game file");
4485
DisplayMessage(move, False);
4494
move_type = (ShogiMove)0;
4496
lastGameMode = gameMode;
4497
gameMode = ForceMoves;
4499
DisplayMessage("End of game file", False);
4501
if (readGameXID != 0)
4503
XtRemoveTimeOut(readGameXID);
4517
* Apply a move to the given board. Oddity: move_type is ignored on input
4518
* unless the move is seen to be a pawn promotion, in which case move_type
4519
* tells us what to promote to.
4523
ApplyMove(ShogiMove *move_type, int from_x, int from_y,
4524
int to_x, int to_y, int currentMove)
4526
ShogiSquare piece, cpiece;
4533
c = (BlackOnMove(currentMove) ? 1 : 0);
4534
cpiece = catchedIndexToPiece[c][i];
4535
boards[currentMove][to_y][to_x] = cpiece;
4536
catches[currentMove][c][i]--;
4538
else if (PromotionPossible(from_y, to_y,
4539
piece = boards[currentMove][from_y][from_x]))
4541
cpiece = boards[currentMove][to_y][to_x];
4543
if (cpiece != EmptySquare)
4545
i = pieceToCatchedIndex[cpiece];
4546
c = (cpiece < WhitePawn);
4547
catches[currentMove][c][i]++;
4550
if (*move_type == NormalMove)
4552
boards[currentMove][to_y][to_x] = piece;
4556
boards[currentMove][to_y][to_x] = piece = pieceToPromoted[piece];
4560
boards[currentMove][from_y][from_x] = EmptySquare;
4564
ShogiSquare piece = boards[currentMove][to_y][to_x];
4566
if (piece != EmptySquare)
4568
i = pieceToCatchedIndex[piece];
4569
c = (piece < WhitePawn);
4570
catches[currentMove][c][i]++;
4573
*move_type = NormalMove;
4574
boards[currentMove][to_y][to_x] =
4575
boards[currentMove][from_y][from_x];
4576
boards[currentMove][from_y][from_x] = EmptySquare;
4584
* MakeMove() displays moves. If they are illegal, GNU shogi will detect
4585
* this and send an Illegal move message. XShogi will then retract the move.
4586
* The clockMode False case is tricky because it displays the player on move.
4590
MakeMove(ShogiMove *move_type, int from_x, int from_y, int to_x, int to_y)
4592
char message[MSG_SIZ], movestr[MSG_SIZ];
4593
char promoPiece = NULLCHAR;
4597
CopyBoard(boards[forwardMostMove], boards[forwardMostMove - 1]);
4598
CopyCatches(catches[forwardMostMove], catches[forwardMostMove - 1]);
4600
ApplyMove(move_type, from_x, from_y, to_x, to_y, forwardMostMove);
4602
endMessage[0] = NULLCHAR;
4604
timeRemaining[0][forwardMostMove] = blackTimeRemaining;
4605
timeRemaining[1][forwardMostMove] = whiteTimeRemaining;
4607
if ((gameMode == PauseGame) && (pausePreviousMode != PlayFromGameFile))
4610
currentMove = forwardMostMove;
4612
if (gameMode == PlayFromGameFile)
4614
sprintf(message, "%d. %s%s",
4615
((currentMove + 1) / 2),
4616
(BlackOnMove(currentMove) ? "... " : ""),
4618
strcpy(parseList[currentMove - 1], currentMoveString);
4622
if ((*move_type == WhitePromotion) || (*move_type == BlackPromotion))
4625
promoPiece = NULLCHAR;
4627
MakeAlg(from_x, from_y, to_x, to_y, promoPiece,
4628
currentMove - 1, movestr);
4629
sprintf(message, "%d. %s%s",
4630
((currentMove + 1) / 2),
4631
(BlackOnMove(currentMove) ? "... " : ""),
4633
strcpy(parseList[currentMove - 1], movestr);
4636
DisplayMessage(message, False);
4638
if ((gameMode == PlayFromGameFile) || (gameMode == ForceMoves)
4639
|| ((gameMode == PauseGame)
4640
&& (pausePreviousMode == PlayFromGameFile)))
4642
DisplayClocks(ReDisplayTimers);
4646
DisplayClocks(SwitchTimers);
4649
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
4651
XSync(localPlayer.xDisplay, False);
4653
if (updateRemotePlayer)
4655
DisplayMessage(message, True);
4656
XSync(remotePlayer.xDisplay, False);
4664
InitShogiProgram(char *host_name, char *program_name, int *pid,
4665
FILE **to, FILE **from, XtIntervalId *xid, int *sendTime)
4669
int to_prog[2], from_prog[2];
4670
FILE *from_fp, *to_fp;
4674
if (localPlayer.appData.noShogiProgram)
4677
signal(SIGPIPE, CatchPipeSignal);
4681
if ((*pid = fork()) == 0)
4683
signal(SIGPIPE, CatchPipeSignal);
4685
dup2(to_prog[0], 0);
4686
dup2(from_prog[1], 1);
4689
close(from_prog[0]);
4690
close(from_prog[1]);
4691
dup2(1, fileno(stderr)); /* force stderr to the pipe */
4693
if (localPlayer.appData.searchTime != NULL)
4695
sprintf(arg_buf, "%d", searchTime);
4697
arg2 = (char *)NULL;
4699
else if (localPlayer.appData.searchDepth > 0)
4701
sprintf(arg_buf, "%d", localPlayer.appData.searchDepth);
4707
sprintf(arg_buf, "%d", localPlayer.appData.movesPerSession);
4709
arg2 = localPlayer.appData.timeControl;
4712
if (strcmp(host_name, "localhost") == 0)
4714
execlp(program_name, program_name, arg1, arg2,
4719
execlp(localPlayer.appData.remoteShell,
4720
localPlayer.appData.remoteShell,
4721
host_name, program_name, arg1, arg2,
4725
perror(program_name);
4730
close(from_prog[1]);
4732
*from = from_fp = fdopen(from_prog[0], "r");
4733
*to = to_fp = fdopen(to_prog[1], "w");
4734
setbuf(from_fp, NULL);
4735
setbuf(to_fp, NULL);
4737
ReceiveFromProgram(from_fp, &dummy_source, &dummy_id); /* "GNU Shogi"*/
4739
if (!at_least_gnushogi_1_2p03)
4741
fprintf(stderr, "you must have at least gnushogi-1.2p03\n");
4748
*xid = XtAppAddInput(appContext, fileno(from_fp),
4749
(XtPointer)XtInputReadMask,
4750
(XtInputCallbackProc)ReceiveFromProgram,
4751
(XtPointer)from_fp);
4753
SendToProgram(localPlayer.appData.initString, *to);
4755
if (localPlayer.appData.gameIn)
4756
SendToProgram("gamein\n", *to);
4758
SendSearchDepth(*to);
4762
/* Does program have "time" command? */
4765
sprintf(buf, "time %ld\n", blackTimeRemaining / 10);
4766
SendToProgram(buf, to_fp);
4767
ReceiveFromProgram(from_fp, &dummy_source, &dummy_id);
4771
*sendTime = 1; /* yes! */
4772
sprintf(buf, "otime %ld\n", whiteTimeRemaining / 10);
4773
SendToProgram(buf, to_fp);
4774
ReceiveFromProgram(from_fp, &dummy_source, &dummy_id);
4783
ShutdownShogiPrograms(char *why)
4785
lastGameMode = gameMode;
4786
gameMode = EndOfGame;
4788
CopyBoard(boards[currentMove + 1], boards[currentMove]);
4789
CopyCatches(catches[currentMove + 1], catches[currentMove]);
4790
strncpy(parseList[currentMove], why, MOVE_LEN);
4791
parseList[currentMove][MOVE_LEN - 1] = NULLCHAR;
4793
DisplayMessage(why, False);
4795
if (readGameXID != 0)
4796
XtRemoveTimeOut(readGameXID);
4800
if (firstProgramPID != 0)
4802
fclose(fromFirstProgFP);
4803
fclose(toFirstProgFP);
4804
fromFirstProgFP = toFirstProgFP = NULL;
4806
if (kill(firstProgramPID, SIGTERM) == 0)
4810
firstProgramPID = 0;
4812
if (firstProgramXID != 0)
4813
XtRemoveInput(firstProgramXID);
4815
firstProgramXID = 0;
4817
if (secondProgramPID != 0)
4819
fclose(fromSecondProgFP);
4820
fclose(toSecondProgFP);
4821
fromSecondProgFP = toSecondProgFP = NULL;
4823
if (kill(secondProgramPID, SIGTERM) == 0)
4827
secondProgramPID = 0;
4829
if (secondProgramXID != 0)
4830
XtRemoveInput(secondProgramXID);
4832
secondProgramXID = 0;
4834
DisplayClocks(StopTimers);
4836
if (matchMode != MatchFalse)
4838
if (localPlayer.appData.saveGameFile[0] != NULLCHAR)
4839
SaveGame(localPlayer.appData.saveGameFile);
4849
CommentPopUp(char *label)
4853
Dimension bw_width, pw_width;
4857
XtPopdown(commentShell);
4858
XtDestroyWidget(commentShell);
4862
DisplayMessage("Comment", False);
4864
XtSetArg(args[0], XtNwidth, &bw_width);
4865
XtGetValues(localPlayer.formWidget, args, 1);
4867
XtSetArg(args[0], XtNresizable, True);
4868
XtSetArg(args[1], XtNwidth, bw_width - 8);
4870
commentShell = XtCreatePopupShell("Comment",
4871
transientShellWidgetClass,
4872
localPlayer.commandsWidget, args, 2);
4874
XtSetArg(args[0], XtNlabel, label);
4876
(void)XtCreateManagedWidget("commentLabel", labelWidgetClass,
4877
commentShell, args, 1);
4879
XtRealizeWidget(commentShell);
4881
XtSetArg(args[0], XtNwidth, &pw_width);
4882
XtGetValues(commentShell, args, 1);
4884
XtTranslateCoords(localPlayer.shellWidget,
4885
(bw_width - pw_width) / 2, -50, &x, &y);
4887
XtSetArg(args[0], XtNx, x);
4888
XtSetArg(args[1], XtNy, y);
4889
XtSetValues(commentShell, args, 2);
4891
XtPopup(commentShell, XtGrabNone);
4899
FileNamePopUp(char *label, Boolean (*proc) (char *))
4902
Widget popup, dialog;
4904
Dimension bw_width, pw_width;
4908
XtSetArg(args[0], XtNwidth, &bw_width);
4909
XtGetValues(localPlayer.boardWidget, args, 1);
4911
XtSetArg(args[0], XtNresizable, True);
4912
XtSetArg(args[1], XtNwidth, DIALOG_SIZE);
4914
popup = XtCreatePopupShell("File Name Prompt",
4915
transientShellWidgetClass,
4916
localPlayer.commandsWidget, args, 2);
4918
XtSetArg(args[0], XtNlabel, label);
4919
XtSetArg(args[1], XtNvalue, "");
4921
dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
4924
XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);
4925
XawDialogAddButton(dialog, "cancel", FileNameCallback,
4926
(XtPointer) dialog);
4928
XtRealizeWidget(popup);
4930
XtSetArg(args[0], XtNwidth, &pw_width);
4931
XtGetValues(popup, args, 1);
4933
XtTranslateCoords(localPlayer.boardWidget,
4934
(bw_width - pw_width) / 2, 10, &x, &y);
4936
XtSetArg(args[0], XtNx, x);
4937
XtSetArg(args[1], XtNy, y);
4938
XtSetValues(popup, args, 2);
4940
XtPopup(popup, XtGrabExclusive);
4943
XtSetKeyboardFocus(localPlayer.shellWidget, popup);
4950
FileNameCallback(Widget w, XtPointer client_data, XtPointer call_data)
4955
XtSetArg(args[0], XtNlabel, &name);
4956
XtGetValues(w, args, 1);
4958
if (strcmp(name, "cancel") == 0)
4960
XtPopdown(w = XtParent(XtParent(w)));
4967
FileNameAction(w, NULL, NULL, NULL);
4974
FileNameAction(Widget w, XEvent *event, String *prms, Cardinal *nprms)
4979
name = XawDialogGetValueString(w = XtParent(w));
4981
if ((name != NULL) && (*name != NULLCHAR))
4984
XtPopdown(w = XtParent(w));
4987
(*fileProc)(buf); /* I can't see a way not
4988
to use a global here */
4993
XtPopdown(w = XtParent(w));
5003
PromotionPopUp(ShogiSquare piece, int to_x, int to_y, int fromRemotePlayer)
5008
Dimension bw_width, bw_height, pw_width, pw_height;
5010
player = (fromRemotePlayer ? &remotePlayer : &localPlayer);
5016
XtSetArg(args[0], XtNwidth, &bw_width);
5017
XtSetArg(args[1], XtNheight, &bw_height);
5018
XtGetValues(player->boardWidget, args, 2);
5020
XtSetArg(args[0], XtNresizable, True);
5022
player->promotionShell
5023
= XtCreatePopupShell("Promotion",
5024
transientShellWidgetClass,
5025
player->commandsWidget, args, 1);
5027
XtSetArg(args[0], XtNlabel, "Promote piece?");
5028
dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
5029
player->promotionShell, args, 1);
5031
XawDialogAddButton(dialog, "Yes", PromotionCallback,
5032
(XtPointer) dialog);
5033
XawDialogAddButton(dialog, "No", PromotionCallback,
5034
(XtPointer) dialog);
5035
XawDialogAddButton(dialog, "cancel", PromotionCallback,
5036
(XtPointer) dialog);
5038
XtRealizeWidget(player->promotionShell);
5040
XtSetArg(args[0], XtNwidth, &pw_width);
5041
XtSetArg(args[1], XtNheight, &pw_height);
5042
XtGetValues(player->promotionShell, args, 2);
5044
XtTranslateCoords(player->boardWidget,
5045
((bw_width - pw_width) / 2),
5047
+ player->squareSize / 3
5048
+ (((piece == BlackPawn) ^ (player->flipView))
5050
: (6 * (player->squareSize + LINE_GAP)))),
5053
XtSetArg(args[0], XtNx, x);
5054
XtSetArg(args[1], XtNy, y);
5055
XtSetValues(player->promotionShell, args, 2);
5057
XtPopup(player->promotionShell, XtGrabNone);
5059
player->promotionUp = True;
5066
PromotionCallback(Widget w, XtPointer client_data, XtPointer call_data)
5070
ShogiMove move_type;
5071
struct DisplayData *player;
5073
XtSetArg(args[0], XtNlabel, &name);
5074
XtGetValues(w, args, 1);
5076
w = XtParent(XtParent(w));
5077
player = ((w == remotePlayer.promotionShell)
5078
? &remotePlayer : &localPlayer);
5081
player->promotionUp = False;
5086
if (strcmp(name, "Yes") == 0)
5088
if ((int)pmi.piece < (int)WhitePawn)
5089
move_type = BlackPromotion;
5091
move_type = WhitePromotion;
5093
else if (strcmp(name, "No") == 0)
5095
move_type = NormalMove;
5097
else /* strcmp(name, "cancel") == 0 */
5103
MakeMove(&move_type, fromX, fromY, pmi.to_x, pmi.to_y);
5106
if (updateRemotePlayer)
5108
BlinkSquare(pmi.to_y, pmi.to_x,
5109
boards[currentMove][pmi.to_y][pmi.to_x]);
5113
FinishUserMove(move_type, pmi.to_x, pmi.to_y);
5120
FileModePopUp(char *name)
5125
Dimension bw_width, bw_height, pw_width, pw_height;
5127
struct DisplayData *player = &localPlayer;
5129
strcpy(fmi.name, name);
5131
XtSetArg(args[0], XtNwidth, &bw_width);
5132
XtSetArg(args[1], XtNheight, &bw_height);
5133
XtGetValues(player->boardWidget, args, 2);
5135
XtSetArg(args[0], XtNresizable, True);
5136
player->filemodeShell
5137
= XtCreatePopupShell("FileMode",
5138
transientShellWidgetClass,
5139
player->commandsWidget, args, 1);
5141
XtSetArg(args[0], XtNlabel, "Append to existing file?");
5142
dialog = XtCreateManagedWidget("filemode", dialogWidgetClass,
5143
player->filemodeShell, args, 1);
5145
XawDialogAddButton(dialog, "Yes", FileModeCallback,
5146
(XtPointer) dialog);
5147
XawDialogAddButton(dialog, "No", FileModeCallback,
5148
(XtPointer) dialog);
5149
XawDialogAddButton(dialog, "cancel", FileModeCallback,
5150
(XtPointer) dialog);
5152
XtRealizeWidget(player->filemodeShell);
5154
XtSetArg(args[0], XtNwidth, &pw_width);
5155
XtSetArg(args[1], XtNheight, &pw_height);
5156
XtGetValues(player->filemodeShell, args, 2);
5158
XtTranslateCoords(player->boardWidget, (bw_width - pw_width) / 2,
5159
LINE_GAP + player->squareSize/3 +
5160
(6*(player->squareSize + LINE_GAP)),
5163
XtSetArg(args[0], XtNx, x);
5164
XtSetArg(args[1], XtNy, y);
5165
XtSetValues(player->filemodeShell, args, 2);
5167
XtPopup(player->filemodeShell, XtGrabNone);
5176
FileModeCallback(Widget w, XtPointer client_data, XtPointer call_data)
5181
XtSetArg(args[0], XtNlabel, &name);
5182
XtGetValues(w, args, 1);
5184
XtPopdown(w = XtParent(XtParent(w)));
5187
if (strcmp(name, "Yes") == 0)
5189
strcpy(fmi.mode, "a");
5191
else if (strcmp(name, "No") == 0)
5193
strcpy(fmi.mode, "w");
5195
else /* strcmp(name, "cancel") == 0 */
5201
XtPopdown(localPlayer.filemodeShell);
5202
XtDestroyWidget(localPlayer.filemodeShell);
5213
SelectCommand(Widget w, XtPointer client_data, XtPointer call_data)
5215
Cardinal fromRemotePlayer = (Cardinal)client_data;
5217
XawListReturnStruct *list_return = XawListShowCurrent(w);
5219
player = fromRemotePlayer ? &remotePlayer : &localPlayer;
5223
if (player->promotionUp)
5225
XtPopdown(player->promotionShell);
5226
XtDestroyWidget(player->promotionShell);
5227
player->promotionUp = False;
5230
(*buttonProcs[list_return->list_index])
5231
(w, NULL, NULL, &fromRemotePlayer);
5241
HighlightProcButton(XtActionProc proc)
5247
XawListUnhighlight(localPlayer.commandsWidget);
5249
if (updateRemotePlayer)
5250
XawListUnhighlight(remotePlayer.commandsWidget);
5257
if (buttonProcs[i] == NULL)
5259
XawListUnhighlight(localPlayer.commandsWidget);
5261
if (updateRemotePlayer)
5262
XawListUnhighlight(remotePlayer.commandsWidget);
5267
if (buttonProcs[i] == proc)
5269
XawListHighlight(localPlayer.commandsWidget, i);
5271
if (updateRemotePlayer)
5272
XawListHighlight(remotePlayer.commandsWidget, i);
5289
case BeginningOfGame:
5290
if (localPlayer.appData.noShogiProgram)
5291
HighlightProcButton(ForceProc);
5293
HighlightProcButton(MachineBlackProc);
5297
case MachinePlaysBlack:
5298
HighlightProcButton(MachineBlackProc);
5301
case MachinePlaysWhite:
5302
HighlightProcButton(MachineWhiteProc);
5305
case TwoMachinesPlay:
5306
HighlightProcButton(TwoMachinesProc);
5310
HighlightProcButton(ForceProc);
5314
case PlayFromGameFile:
5315
HighlightProcButton(LoadGameProc);
5319
HighlightProcButton(PauseProc);
5323
HighlightProcButton(EditPositionProc);
5328
HighlightProcButton(NULL);
5341
QuitRemotePlayerProc(void)
5343
/* This should be modified... */
5344
XCloseDisplay(remotePlayer.xDisplay);
5345
/* XtDestroyWidget(remotePlayer.shellWidget); */
5346
updateRemotePlayer = False;
5347
DisplayMessage("Remote player has pressed Quit", False);
5354
QuitProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5356
if (updateRemotePlayer)
5357
QuitRemotePlayerProc();
5359
ShutdownShogiPrograms("Quitting");
5366
LoadGameProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5368
int fromRemotePlayer = *nprms;
5370
if (fromRemotePlayer)
5372
DisplayMessage("only opponent may load game", fromRemotePlayer);
5376
if (gameMode != BeginningOfGame)
5378
DisplayMessage("Press Reset first", False);
5382
if (localPlayer.appData.loadGameFile == NULL)
5383
FileNamePopUp("Game file name?", LoadGame);
5385
(void) LoadGame(localPlayer.appData.loadGameFile);
5392
LoadGame(char *name)
5396
if (gameMode != BeginningOfGame)
5398
DisplayMessage("Press Reset first", False);
5402
if (localPlayer.appData.loadGameFile != name)
5404
if (localPlayer.appData.loadGameFile)
5405
XtFree(localPlayer.appData.loadGameFile);
5407
localPlayer.appData.loadGameFile = XtMalloc(strlen(name) + 1);
5408
strcpy(localPlayer.appData.loadGameFile, name);
5411
if ((gameFileFP = fopen(name, "r")) == NULL)
5413
sprintf(buf, "Can't open %s", name);
5414
DisplayMessage(buf, False);
5415
XtFree(localPlayer.appData.loadGameFile);
5416
localPlayer.appData.loadGameFile = NULL;
5420
lastGameMode = gameMode = PlayFromGameFile;
5423
DisplayClocks(StopTimers);
5425
if (firstProgramXID == 0)
5427
InitShogiProgram(localPlayer.appData.firstHost,
5428
localPlayer.appData.firstShogiProgram,
5429
&firstProgramPID, &toFirstProgFP,
5430
&fromFirstProgFP, &firstProgramXID,
5434
SendToProgram(localPlayer.appData.initString, toFirstProgFP);
5435
SendSearchDepth(toFirstProgFP);
5436
SendToProgram("force\n", toFirstProgFP);
5438
currentMove = forwardMostMove = backwardMostMove = 0;
5449
* Restart the shogi program and feed it all the moves made so far.
5450
* Used when the user wants to back up from end of game, when gnushogi
5451
* has already exited. Assumes gameMode == EndOfGame.
5455
ResurrectShogiProgram(void)
5460
if (currentMove > 0)
5461
currentMove--; /* delete "Black wins" or the like */
5463
InitShogiProgram(localPlayer.appData.firstHost,
5464
localPlayer.appData.firstShogiProgram,
5465
&firstProgramPID, &toFirstProgFP, &fromFirstProgFP,
5466
&firstProgramXID, &firstSendTime);
5468
SendToProgram(localPlayer.appData.initString, toFirstProgFP);
5469
SendSearchDepth(toFirstProgFP);
5470
SendToProgram("force\n", toFirstProgFP);
5471
gameMode = lastGameMode = ForceMoves;
5474
i = (whitePlaysFirst ? 1 : 0);
5476
if (startedFromSetupPosition)
5477
SendBoard(toFirstProgFP, boards[i], catches[i]);
5479
for (; i < currentMove; i++)
5481
strcpy(buf, moveList[i]);
5482
SendToProgram(buf, toFirstProgFP);
5487
/* can't tell gnushogi what its clock should read,
5488
so we bow to its notion. */
5489
DisplayClocks(ResetTimers);
5490
timeRemaining[0][currentMove] = blackTimeRemaining;
5491
timeRemaining[1][currentMove] = whiteTimeRemaining;
5499
MachineWhiteProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5501
int fromRemotePlayer = *nprms;
5503
if (updateRemotePlayer)
5505
DisplayMessage("no machine moves in challenge mode",
5511
if (gameMode == PauseGame)
5512
PauseProc(w, event, prms, nprms);
5514
if (gameMode == PlayFromGameFile)
5515
ForceProc(w, event, prms, nprms);
5517
if (gameMode == EditPosition)
5520
if ((gameMode == EndOfGame)
5521
|| (gameMode == PlayFromGameFile)
5522
|| (gameMode == TwoMachinesPlay)
5523
|| localPlayer.appData.noShogiProgram
5524
|| (gameMode == MachinePlaysWhite))
5529
if (BlackOnMove((gameMode == ForceMoves)
5533
DisplayMessage("It is not White's turn", False);
5537
if (gameMode == ForceMoves)
5538
forwardMostMove = currentMove;
5540
lastGameMode = gameMode = MachinePlaysWhite;
5542
SendToProgram(localPlayer.appData.whiteString, toFirstProgFP);
5543
DisplayClocks(StartTimers);
5550
MachineBlackProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5552
int fromRemotePlayer = *nprms;
5554
if (updateRemotePlayer)
5556
DisplayMessage("no machine moves in challenge mode",
5561
if (gameMode == PauseGame)
5562
PauseProc(w, event, prms, nprms);
5564
if (gameMode == PlayFromGameFile)
5565
ForceProc(w, event, prms, nprms);
5567
if (gameMode == EditPosition)
5570
if ((gameMode == EndOfGame)
5571
|| (gameMode == PlayFromGameFile)
5572
|| (gameMode == TwoMachinesPlay)
5573
|| localPlayer.appData.noShogiProgram
5574
|| (gameMode == MachinePlaysBlack))
5579
if (!BlackOnMove((gameMode == ForceMoves)
5583
DisplayMessage("It is not Black's turn", False);
5587
if (gameMode == ForceMoves)
5588
forwardMostMove = currentMove;
5590
lastGameMode = gameMode = MachinePlaysBlack;
5592
SendToProgram(localPlayer.appData.blackString, toFirstProgFP);
5593
DisplayClocks(StartTimers);
5600
ForwardProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5606
int fromRemotePlayer = *nprms;
5608
if (updateRemotePlayer)
5610
DisplayMessage("Forward button disabled", fromRemotePlayer);
5614
if ((gameMode == EndOfGame) || (gameMode == EditPosition))
5617
if (gameMode == PlayFromGameFile)
5618
PauseProc(w, event, prms, nprms);
5620
if (currentMove >= forwardMostMove)
5629
XQueryPointer(localPlayer.xDisplay, localPlayer.xBoardWindow,
5630
&root, &child, &root_x, &root_y,
5631
&win_x, &win_y, &state);
5635
state = event->xkey.state;
5638
if (state & ShiftMask)
5639
target = forwardMostMove;
5641
target = currentMove + 1;
5643
if (gameMode == ForceMoves)
5645
while (currentMove < target)
5647
strcpy(buf, moveList[currentMove++]);
5648
SendToProgram(buf, toFirstProgFP);
5653
currentMove = target;
5656
if (gameMode == ForceMoves)
5658
blackTimeRemaining = timeRemaining[0][currentMove];
5659
whiteTimeRemaining = timeRemaining[1][currentMove];
5662
DisplayClocks(ReDisplayTimers);
5663
DisplayMove(currentMove - 1);
5664
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
5675
if (updateRemotePlayer)
5678
if (localPlayer.appData.loadGameFile)
5679
XtFree(localPlayer.appData.loadGameFile);
5681
if (localPlayer.appData.loadPositionFile)
5682
XtFree(localPlayer.appData.loadPositionFile);
5684
localPlayer.appData.loadGameFile
5685
= localPlayer.appData.loadPositionFile = NULL;
5688
if (gameFileFP != NULL)
5699
ResetChallenge(void)
5703
if (localPlayer.appData.challengeDisplay)
5704
XtFree(localPlayer.appData.challengeDisplay);
5706
localPlayer.appData.challengeDisplay = NULL;
5714
ResetProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5716
int fromRemotePlayer = *nprms;
5718
if (fromRemotePlayer)
5720
DisplayMessage("only your opponent may reset the game",
5732
Reset(int redraw) /* Boolean */
5737
localPlayer.flipView = False;
5738
remotePlayer.flipView = True;
5739
startedFromSetupPosition = whitePlaysFirst = False;
5740
matchMode = MatchFalse;
5742
blackFlag = whiteFlag = False;
5743
maybeThinking = False;
5745
endMessage[0] = NULLCHAR;
5747
ShutdownShogiPrograms("");
5748
lastGameMode = gameMode = BeginningOfGame;
5750
InitPosition(redraw);
5751
DisplayClocks(ResetTimers);
5752
timeRemaining[0][0] = blackTimeRemaining;
5753
timeRemaining[1][0] = whiteTimeRemaining;
5754
InitShogiProgram(localPlayer.appData.firstHost,
5755
localPlayer.appData.firstShogiProgram,
5756
&firstProgramPID, &toFirstProgFP,
5757
&fromFirstProgFP, &firstProgramXID,
5762
XtPopdown(commentShell);
5763
XtDestroyWidget(commentShell);
5767
if (localPlayer.promotionUp)
5769
XtPopdown(localPlayer.promotionShell);
5770
XtDestroyWidget(localPlayer.promotionShell);
5771
localPlayer.promotionUp = False;
5774
if (updateRemotePlayer && remotePlayer.promotionUp)
5776
XtPopdown(remotePlayer.promotionShell);
5777
XtDestroyWidget(remotePlayer.promotionShell);
5778
remotePlayer.promotionUp = False;
5786
ClearCatches(int (*catches)[8])
5790
for (c = 0; c <= 1; c++)
5791
for (p = 0; p <= 7; p++)
5799
Challenge(char *name)
5804
XrmDatabase database;
5806
if (gameMode != BeginningOfGame)
5808
DisplayMessage("Press Reset first", False);
5812
if (localPlayer.appData.challengeDisplay != name)
5814
if (localPlayer.appData.challengeDisplay)
5815
XtFree(localPlayer.appData.challengeDisplay);
5817
localPlayer.appData.challengeDisplay = XtMalloc(strlen(name) + 1);
5818
strcpy(localPlayer.appData.challengeDisplay, name);
5821
sprintf(buf, "trying to connect to %s.....", name);
5822
DisplayMessage(buf, False);
5827
if ((remotePlayer.xDisplay
5828
= XtOpenDisplay(appContext, name, "XShogi",
5829
"XShogi", 0, 0, &argc, argv)) == NULL)
5831
sprintf(buf, "Can't open display %s", name);
5832
DisplayMessage(buf, False);
5833
XtFree(localPlayer.appData.challengeDisplay);
5834
localPlayer.appData.challengeDisplay = NULL;
5838
DisplayMessage("connected! creating remote window...", False);
5840
remotePlayer.xScreen = DefaultScreen(remotePlayer.xDisplay);
5842
remotePlayer.shellWidget
5843
= XtAppCreateShell(NULL, "XShogi",
5844
applicationShellWidgetClass,
5845
remotePlayer.xDisplay, NULL, 0);
5847
database = XtDatabase(remotePlayer.xDisplay);
5849
XrmParseCommand(&database,
5850
shellOptions, XtNumber(shellOptions),
5851
"XShogi", &argc, argv);
5853
XtGetApplicationResources(remotePlayer.shellWidget,
5854
&remotePlayer.appData, clientResources,
5855
XtNumber(clientResources), NULL, 0);
5857
player = &remotePlayer;
5859
CreatePlayerWindow();
5861
updateRemotePlayer = True;
5863
DisplayName("REMOTE");
5864
DrawPosition(remotePlayer.boardWidget, NULL, NULL, NULL);
5865
DisplayClocks(ReDisplayTimers);
5867
DisplayMessage("ready to play", False);
5868
DisplayMessage("ready to play", True);
5877
ChallengeProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5879
int fromRemotePlayer = *nprms;
5881
if (updateRemotePlayer)
5883
DisplayMessage("you are already in challenge mode",
5888
if (gameMode != BeginningOfGame)
5890
DisplayMessage("Press Reset first", False);
5894
if (localPlayer.appData.challengeDisplay == NULL)
5895
FileNamePopUp("Challenge display?", Challenge);
5897
(void) Challenge(localPlayer.appData.challengeDisplay);
5904
SelectLevel(char *command)
5908
sprintf(buf, "level %s\n", command);
5909
SendToProgram(buf, toFirstProgFP);
5918
SelectLevelProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5920
if ((BlackOnMove(forwardMostMove) && (gameMode == MachinePlaysBlack))
5921
|| (!BlackOnMove(forwardMostMove) && (gameMode == MachinePlaysWhite)))
5923
DisplayMessage("Wait until your turn", False);
5927
FileNamePopUp("#moves #minutes", SelectLevel);
5935
MoveNowProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5937
if ((!BlackOnMove(forwardMostMove) && (gameMode == MachinePlaysBlack))
5938
|| (BlackOnMove(forwardMostMove) && (gameMode == MachinePlaysWhite)))
5940
DisplayMessage("Wait until machines turn", False);
5944
Attention(firstProgramPID);
5952
LoadPositionProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
5954
int fromRemotePlayer = *nprms;
5956
if (fromRemotePlayer)
5958
DisplayMessage("only opponent may load position", fromRemotePlayer);
5962
if (gameMode != BeginningOfGame)
5964
DisplayMessage("Press Reset first", False);
5968
FileNamePopUp("Position file name?", LoadPosition);
5975
LoadPosition(char *name)
5977
char *p, line[MSG_SIZ], buf[MSG_SIZ];
5978
Board initial_position;
5979
Catched initial_catches;
5983
if (gameMode != BeginningOfGame)
5985
DisplayMessage("Press Reset first", False);
5989
if (localPlayer.appData.loadPositionFile != name)
5991
if (localPlayer.appData.loadPositionFile)
5992
XtFree(localPlayer.appData.loadPositionFile);
5994
localPlayer.appData.loadPositionFile = XtMalloc(strlen(name) + 1);
5995
strcpy(localPlayer.appData.loadPositionFile, name);
5998
if ((fp = fopen(name, "r")) == NULL)
6000
sprintf(buf, "Can't open %s", name);
6001
DisplayMessage(buf, False);
6002
XtFree(localPlayer.appData.loadPositionFile);
6003
localPlayer.appData.loadPositionFile = NULL;
6007
lastGameMode = gameMode = ForceMoves;
6009
startedFromSetupPosition = True;
6011
if (firstProgramXID == 0)
6013
InitShogiProgram(localPlayer.appData.firstHost,
6014
localPlayer.appData.firstShogiProgram,
6015
&firstProgramPID, &toFirstProgFP,
6016
&fromFirstProgFP, &firstProgramXID,
6021
* Check and skip header information in position file.
6024
fgets(line, MSG_SIZ, fp);
6025
line[strlen(line) - 1] = NULLCHAR;
6026
sprintf(buf, "# %s position file", programName);
6028
if (strncmp(line, buf, strlen(buf)))
6030
strcat(line, ": no xshogi position file");
6031
DisplayMessage(line, False);
6036
fgets(line, MSG_SIZ, fp); /* skip opponents */
6038
for (i = BOARD_SIZE - 1; i >= 0; i--)
6040
fgets(line, MSG_SIZ, fp);
6042
for (p = line, j = 0; j < BOARD_SIZE; p++)
6044
int promoted = False; /* CHECKME: is this valid? */
6053
initial_position[i][j++] = CharToPiece(*p, promoted);
6060
for (color = 0; color <= 1; color++)
6062
fscanf(fp, "%i%i%i%i%i%i%i%i\n",
6063
&initial_catches[color][pawn],
6064
&initial_catches[color][lance],
6065
&initial_catches[color][knight],
6066
&initial_catches[color][silver],
6067
&initial_catches[color][gold],
6068
&initial_catches[color][bishop],
6069
&initial_catches[color][rook],
6070
&initial_catches[color][king]);
6074
whitePlaysFirst = False;
6078
fgets(line, MSG_SIZ, fp);
6080
if (strncmp(line, "white", strlen("white")) == 0)
6081
whitePlaysFirst = True;
6086
if (whitePlaysFirst)
6088
CopyBoard(boards[0], initial_position);
6089
CopyCatches(catches[0], initial_catches);
6090
strcpy(moveList[0], " ...\n");
6091
strcpy(parseList[0], " ...\n");
6092
currentMove = forwardMostMove = backwardMostMove = 1;
6093
CopyBoard(boards[1], initial_position);
6094
CopyCatches(catches[1], initial_catches);
6095
SendToProgram("white\n", toFirstProgFP);
6096
SendToProgram("force\n", toFirstProgFP);
6097
SendCurrentBoard(toFirstProgFP);
6098
DisplayMessage("White to play", False);
6102
currentMove = forwardMostMove = backwardMostMove = 0;
6103
CopyBoard(boards[0], initial_position);
6104
CopyCatches(catches[0], initial_catches);
6105
SendCurrentBoard(toFirstProgFP);
6106
SendToProgram("force\n", toFirstProgFP);
6107
DisplayMessage("Black to play", False);
6110
DisplayClocks(ResetTimers);
6111
timeRemaining[0][1] = blackTimeRemaining;
6112
timeRemaining[1][1] = whiteTimeRemaining;
6114
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
6122
EditPositionProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6124
int fromRemotePlayer = *nprms;
6126
if (updateRemotePlayer)
6128
DisplayMessage("Edit button disabled", fromRemotePlayer);
6132
if (gameMode == EditPosition)
6135
ForceProc(w, event, prms, nprms);
6137
if (gameMode != ForceMoves)
6140
DisplayName("<-- Press to set side to play next");
6141
DisplayMessage("Mouse: 1=drag, 2=black, 3=white", False);
6143
lastGameMode = gameMode = EditPosition;
6146
if (currentMove > 0)
6147
CopyBoard(boards[0], boards[currentMove]);
6149
whitePlaysFirst = !BlackOnMove(forwardMostMove);
6150
currentMove = forwardMostMove = backwardMostMove = 0;
6157
EditPositionDone(void)
6159
startedFromSetupPosition = True;
6160
SendToProgram(localPlayer.appData.initString, toFirstProgFP);
6161
SendSearchDepth(toFirstProgFP);
6163
if (whitePlaysFirst)
6165
strcpy(moveList[0], " ...\n");
6166
strcpy(parseList[0], " ...\n");
6167
currentMove = forwardMostMove = backwardMostMove = 1;
6168
CopyBoard(boards[1], boards[0]);
6169
CopyCatches(catches[1], catches[0]);
6170
SendToProgram("force\n", toFirstProgFP);
6171
SendCurrentBoard(toFirstProgFP);
6173
DisplayMessage("White to play", False);
6177
currentMove = forwardMostMove = backwardMostMove = 0;
6178
SendCurrentBoard(toFirstProgFP);
6179
SendToProgram("force\n", toFirstProgFP);
6181
DisplayMessage("Black to play", False);
6184
lastGameMode = gameMode = ForceMoves;
6194
* This function executes when undoing a move.
6195
* FIXME: this function is totally hosed!!!
6209
BackwardProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6214
int fromRemotePlayer = *nprms;
6216
if (updateRemotePlayer)
6218
DisplayMessage("Backward button disabled", fromRemotePlayer);
6223
* Why do we need this here?
6226
ForceProc(w, event, prms, nprms);
6228
if ((currentMove <= backwardMostMove) || (gameMode == EditPosition))
6231
if (gameMode == EndOfGame)
6232
ResurrectShogiProgram();
6234
if (gameMode == PlayFromGameFile)
6235
PauseProc(w, event, prms, nprms);
6244
XQueryPointer(localPlayer.xDisplay, localPlayer.xBoardWindow,
6245
&root, &child, &root_x, &root_y,
6246
&win_x, &win_y, &state);
6250
state = event->xkey.state;
6253
if (state & ShiftMask)
6255
target = backwardMostMove;
6259
target = currentMove - 1;
6262
if (gameMode == ForceMoves)
6264
Attention(firstProgramPID);
6266
while (currentMove > target)
6268
SendToProgram("undo\n", toFirstProgFP);
6274
currentMove = target;
6277
if (gameMode == ForceMoves)
6279
whiteTimeRemaining = timeRemaining[0][currentMove];
6280
blackTimeRemaining = timeRemaining[1][currentMove];
6283
DisplayClocks(ReDisplayTimers);
6284
DisplayMove(currentMove - 1);
6285
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
6292
FlipViewProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6294
struct DisplayData *player = (*nprms ? &remotePlayer : &localPlayer);
6296
player->flipView = !player->flipView;
6297
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
6304
SaveGameProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6308
int fromRemotePlayer = *nprms;
6310
if (fromRemotePlayer)
6312
DisplayMessage("only opponent may save game", fromRemotePlayer);
6318
FileNamePopUp("Filename for saved game?", SaveGame);
6325
SaveGame(char *name)
6328
int i, len, move = 0;
6331
if (!filemodeUp) /* if called via FileModeCallback avoid recursion */
6333
if ((gameFileFP = fopen(name, "r")) == NULL)
6335
strcpy(fmi.mode, "w");
6340
FileModePopUp(name);
6341
return False; /* CHECKME: what should the return value be? */
6345
if ((gameFileFP = fopen(name, fmi.mode)) == NULL)
6347
sprintf(buf, "Can't open %s (mode %s)", name, fmi.mode);
6348
DisplayMessage(buf, False);
6352
tm = time((time_t *) NULL);
6354
fprintf(gameFileFP, "# %s game file -- %s", programName, ctime(&tm));
6355
PrintOpponents(gameFileFP);
6357
for (i = 0; i < currentMove;)
6360
fprintf(gameFileFP, "\n");
6362
fprintf(gameFileFP, "%d. %s ", ++move, parseList[i++]);
6364
if (i >= currentMove)
6366
fprintf(gameFileFP, "\n");
6370
if ((len = strlen(parseList[i])) == 0)
6373
fprintf(gameFileFP, "%s ", parseList[i++]);
6376
fprintf(gameFileFP, "\n");
6388
SwitchProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6390
if (localPlayer.appData.noShogiProgram)
6398
case MachinePlaysBlack:
6399
if (BlackOnMove(forwardMostMove))
6401
DisplayMessage("Wait until your turn", False);
6405
lastGameMode = gameMode = MachinePlaysWhite;
6409
case BeginningOfGame:
6411
case MachinePlaysWhite:
6412
if (!BlackOnMove(forwardMostMove))
6414
DisplayMessage("Wait until your turn", False);
6418
if (forwardMostMove == 0)
6420
MachineBlackProc(w, event, prms, nprms);
6424
lastGameMode = gameMode = MachinePlaysBlack;
6429
Attention(firstProgramPID);
6430
SendToProgram("switch\n", toFirstProgFP);
6437
ForceProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6443
case MachinePlaysBlack:
6444
if (BlackOnMove(forwardMostMove))
6446
DisplayMessage("Wait until your turn", False);
6450
Attention(firstProgramPID);
6451
SendToProgram("force\n", toFirstProgFP);
6454
case MachinePlaysWhite:
6455
if (!BlackOnMove(forwardMostMove))
6457
DisplayMessage("Wait until your turn", False);
6461
Attention(firstProgramPID);
6462
SendToProgram("force\n", toFirstProgFP);
6465
case BeginningOfGame:
6466
SendToProgram("force\n", toFirstProgFP);
6469
case PlayFromGameFile:
6470
if (readGameXID != 0)
6472
XtRemoveTimeOut(readGameXID);
6476
if (gameFileFP != NULL)
6485
ResurrectShogiProgram();
6492
case TwoMachinesPlay:
6493
ShutdownShogiPrograms("");
6494
ResurrectShogiProgram();
6501
if ((gameMode == MachinePlaysWhite)
6502
|| (gameMode == MachinePlaysBlack)
6503
|| (gameMode == TwoMachinesPlay)
6504
|| (gameMode == PlayFromGameFile))
6506
i = forwardMostMove;
6508
while (i > currentMove)
6510
SendToProgram("undo\n", toFirstProgFP);
6514
blackTimeRemaining = timeRemaining[0][currentMove];
6515
whiteTimeRemaining = timeRemaining[1][currentMove];
6517
if (whiteFlag || blackFlag)
6519
whiteFlag = blackFlag = 0;
6525
lastGameMode = gameMode = ForceMoves;
6527
DisplayClocks(StopTimers);
6533
HintProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6535
int fromRemotePlayer = *nprms;
6537
if (updateRemotePlayer)
6539
DisplayMessage("no hints in challenge mode", fromRemotePlayer);
6543
if (localPlayer.appData.noShogiProgram)
6548
case MachinePlaysBlack:
6549
if (BlackOnMove(forwardMostMove))
6551
DisplayMessage("Wait until your turn", False);
6557
case BeginningOfGame:
6558
case MachinePlaysWhite:
6559
if (!BlackOnMove(forwardMostMove))
6561
DisplayMessage("Wait until your turn", False);
6568
DisplayMessage("No hint available", False);
6572
Attention(firstProgramPID);
6573
SendToProgram("hint\n", toFirstProgFP);
6580
PrintPosition(FILE *fp, int move)
6584
for (i = BOARD_SIZE - 1; i >= 0; i--)
6586
for (j = 0; j < BOARD_SIZE; j++)
6588
if (pieceIsPromoted[(int)boards[currentMove][i][j]])
6589
fprintf(fp, "%c", '+');
6591
fprintf(fp, "%c", ' ');
6594
pieceToChar[(int)boards[currentMove][i][j]]);
6596
if (j == BOARD_SIZE - 1)
6601
for (color = 0; color <= 1; color++)
6603
fprintf(fp, "%i %i %i %i %i %i %i %i\n",
6604
catches[currentMove][color][pawn],
6605
catches[currentMove][color][lance],
6606
catches[currentMove][color][knight],
6607
catches[currentMove][color][silver],
6608
catches[currentMove][color][gold],
6609
catches[currentMove][color][bishop],
6610
catches[currentMove][color][rook],
6611
catches[currentMove][color][king]);
6614
if ((gameMode == EditPosition)
6616
: BlackOnMove(forwardMostMove))
6618
fprintf(fp, "black to play\n");
6622
fprintf(fp, "white to play\n");
6630
PrintOpponents(FILE *fp)
6632
char host_name[MSG_SIZ];
6634
#ifdef HAVE_GETHOSTNAME
6635
gethostname(host_name, MSG_SIZ);
6637
strncpy(host_name, "hostname not available", MSG_SIZ);
6640
switch (lastGameMode)
6642
case MachinePlaysWhite:
6643
fprintf(fp, "# %s@%s vs. %s@%s\n",
6644
localPlayer.appData.firstShogiProgram,
6645
localPlayer.appData.firstHost,
6646
getpwuid(getuid())->pw_name,
6650
case MachinePlaysBlack:
6651
fprintf(fp, "# %s@%s vs. %s@%s\n",
6652
getpwuid(getuid())->pw_name,
6654
localPlayer.appData.firstShogiProgram,
6655
localPlayer.appData.firstHost);
6658
case TwoMachinesPlay:
6659
fprintf(fp, "# %s@%s vs. %s@%s\n",
6660
localPlayer.appData.secondShogiProgram,
6661
localPlayer.appData.secondHost,
6662
localPlayer.appData.firstShogiProgram,
6663
localPlayer.appData.firstHost);
6676
SavePositionProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6680
int fromRemotePlayer = *nprms;
6682
if (fromRemotePlayer)
6684
DisplayMessage("only opponent may save game", fromRemotePlayer);
6690
FileNamePopUp("Filename for saved position?", SavePosition);
6697
SavePosition(char *name)
6703
if ((fp = fopen(name, "w")) == NULL)
6705
sprintf(buf, "Can't open %s", name);
6706
DisplayMessage(buf, False);
6710
tm = time((time_t *) NULL);
6712
fprintf(fp, "# %s position file -- %s", programName, ctime(&tm));
6714
PrintPosition(fp, currentMove);
6724
TwoMachinesProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6727
MatchMode matchKind;
6729
int fromRemotePlayer = *nprms;
6731
if (updateRemotePlayer)
6733
DisplayMessage("no machine moves in challenge mode",
6738
if (gameMode == PauseGame)
6739
PauseProc(w, event, prms, nprms);
6741
if (gameMode == PlayFromGameFile)
6742
ForceProc(w, event, prms, nprms);
6744
if ((gameMode == EndOfGame)
6745
|| (gameMode == TwoMachinesPlay)
6746
|| localPlayer.appData.noShogiProgram)
6751
if (matchMode == MatchFalse)
6756
case PlayFromGameFile:
6759
case MachinePlaysBlack:
6760
case MachinePlaysWhite:
6761
ForceProc(w, event, prms, nprms);
6763
if (gameMode != ForceMoves)
6766
matchKind = MatchOpening;
6770
matchKind = MatchOpening;
6775
matchKind = MatchPosition;
6778
case BeginningOfGame:
6780
matchKind = MatchInit;
6786
matchKind = matchMode;
6789
forwardMostMove = currentMove;
6791
localPlayer.flipView = False;
6792
remotePlayer.flipView = True;
6794
DisplayClocks(ResetTimers);
6795
DisplayClocks(StartTimers);
6800
if (firstProgramXID == 0)
6802
if (localPlayer.appData.loadGameFile == NULL)
6804
DisplayMessage("Select game file first", False);
6808
InitShogiProgram(localPlayer.appData.firstHost,
6809
localPlayer.appData.firstShogiProgram,
6810
&firstProgramPID, &toFirstProgFP,
6811
&fromFirstProgFP, &firstProgramXID,
6814
if (!LoadGame(localPlayer.appData.loadGameFile))
6816
ShutdownShogiPrograms("Bad game file");
6820
DrawPosition(localPlayer.boardWidget, NULL, NULL, NULL);
6823
InitShogiProgram(localPlayer.appData.secondHost,
6824
localPlayer.appData.secondShogiProgram,
6825
&secondProgramPID, &toSecondProgFP,
6826
&fromSecondProgFP, &secondProgramXID,
6829
if (startedFromSetupPosition)
6831
if (whitePlaysFirst)
6834
SendToProgram("force\n", toSecondProgFP);
6835
SendBoard(toSecondProgFP, boards[i], catches[i]);
6840
SendBoard(toSecondProgFP, boards[i], catches[i]);
6841
SendToProgram("force\n", toSecondProgFP);
6847
SendToProgram("force\n", toSecondProgFP);
6850
for (i = backwardMostMove; i < forwardMostMove; i++)
6851
SendToProgram(moveList[i], toSecondProgFP);
6853
lastGameMode = gameMode = TwoMachinesPlay;
6857
if (BlackOnMove(forwardMostMove))
6858
SendToProgram(localPlayer.appData.blackString, toSecondProgFP);
6860
SendToProgram(localPlayer.appData.whiteString, toFirstProgFP);
6865
if (firstProgramXID == 0)
6867
if (localPlayer.appData.loadPositionFile == NULL)
6869
DisplayMessage("Select position file first", False);
6873
InitShogiProgram(localPlayer.appData.firstHost,
6874
localPlayer.appData.firstShogiProgram,
6875
&firstProgramPID, &toFirstProgFP,
6876
&fromFirstProgFP, &firstProgramXID,
6879
if (!LoadPosition(localPlayer.appData.loadPositionFile))
6883
InitShogiProgram(localPlayer.appData.secondHost,
6884
localPlayer.appData.secondShogiProgram,
6885
&secondProgramPID, &toSecondProgFP,
6886
&fromSecondProgFP, &secondProgramXID,
6889
if (whitePlaysFirst)
6890
SendToProgram("force\n", toSecondProgFP);
6892
SendCurrentBoard(toSecondProgFP);
6893
lastGameMode = gameMode = TwoMachinesPlay;
6897
if (BlackOnMove(forwardMostMove))
6898
SendToProgram(localPlayer.appData.blackString, toSecondProgFP);
6900
SendToProgram(localPlayer.appData.whiteString, toFirstProgFP);
6907
if (firstProgramXID == 0)
6909
InitShogiProgram(localPlayer.appData.firstHost,
6910
localPlayer.appData.firstShogiProgram,
6911
&firstProgramPID, &toFirstProgFP,
6912
&fromFirstProgFP, &firstProgramXID,
6916
InitShogiProgram(localPlayer.appData.secondHost,
6917
localPlayer.appData.secondShogiProgram,
6918
&secondProgramPID, &toSecondProgFP,
6919
&fromSecondProgFP, &secondProgramXID,
6922
lastGameMode = gameMode = TwoMachinesPlay;
6924
SendToProgram(localPlayer.appData.blackString, toSecondProgFP);
6930
if (!firstSendTime || !secondSendTime)
6932
DisplayClocks(ResetTimers);
6933
timeRemaining[0][forwardMostMove] = blackTimeRemaining;
6934
timeRemaining[1][forwardMostMove] = whiteTimeRemaining;
6937
DisplayClocks(StartTimers);
6944
PauseProc(Widget w, XEvent *event, String *prms, Cardinal *nprms)
6946
static GameMode previous_mode = PauseGame;
6957
gameMode = previous_mode;
6959
previous_mode = PauseGame;
6960
DisplayClocks(StartTimers);
6961
DisplayMessage("", False);
6963
if (updateRemotePlayer)
6964
DisplayMessage("", True);
6967
case PlayFromGameFile:
6968
if (readGameXID == 0)
6971
XtAppAddTimeOut(appContext,
6972
(int)(1000 * localPlayer.appData.timeDelay),
6973
(XtTimerCallbackProc) ReadGameFile, NULL);
6977
XtRemoveTimeOut(readGameXID);
6981
DisplayMessage("Pausing", False);
6983
if (updateRemotePlayer)
6984
DisplayMessage("Pausing", True);
6988
case BeginningOfGame:
6989
case MachinePlaysBlack:
6990
case MachinePlaysWhite:
6991
case TwoMachinesPlay:
6992
if (forwardMostMove == 0) /* Don't pause if no one has moved. */
6995
if (((gameMode == MachinePlaysWhite)
6996
&& !BlackOnMove(forwardMostMove))
6997
|| ((gameMode == MachinePlaysBlack) &&
6998
BlackOnMove(forwardMostMove)))
7000
DisplayClocks(StopTimers);
7003
previous_mode = gameMode;
7004
gameMode = PauseGame;
7006
DisplayClocks(StopTimers);
7007
DisplayMessage("Pausing", False);
7009
if (updateRemotePlayer)
7010
DisplayMessage("Pausing", True);
7020
Iconify(Widget w, XEvent *event, String *prms, Cardinal *nprms)
7026
XtSetArg(args[0], XtNiconic, True);
7027
XtSetValues(localPlayer.shellWidget, args, 1);
7034
SendToProgram(char *message, FILE *fp)
7043
fprintf(stderr, "Sending to %s: %s\n",
7044
((fp == toFirstProgFP) ? "first" : "second"), message);
7047
if (message[strlen(message) - 1] != '\n')
7048
fprintf(fp, "\n%s\n", message);
7059
ReceiveFromProgram(FILE *fp, int *source, XtInputId *id)
7061
char message[MSG_SIZ], *end_str, *number, *name;
7062
extern const char *const sys_errlist[];
7064
if (fgets(message, MSG_SIZ, fp) == NULL)
7066
if (fp == fromFirstProgFP)
7069
name = localPlayer.appData.firstShogiProgram;
7071
else if (fp == fromSecondProgFP)
7074
name = localPlayer.appData.secondShogiProgram;
7081
if (ferror(fp) == 0)
7083
sprintf(message, "%s shogi program (%s) exited unexpectedly",
7085
fprintf(stderr, "%s: %s\n", programName, message);
7090
"error reading from %s shogi program (%s): %s",
7091
number, name, sys_errlist[ferror(fp)]);
7092
fprintf(stderr, "%s: %s\n", programName, message);
7098
if ((end_str = (char *)strchr(message, '\r')) != NULL)
7099
*end_str = NULLCHAR;
7101
if ((end_str = (char *)strchr(message, '\n')) != NULL)
7102
*end_str = NULLCHAR;
7104
if (xshogiDebug || localPlayer.appData.debugMode)
7106
fprintf(stderr, "Received from %s: %s\n",
7107
((fp == fromFirstProgFP) ? "first" : "second"), message);
7110
HandleMachineMove(message, fp);
7117
SendSearchDepth(FILE *fp)
7119
char message[MSG_SIZ];
7121
if (localPlayer.appData.searchDepth <= 0)
7124
sprintf(message, "depth\n%d\nhelp\n", localPlayer.appData.searchDepth);
7125
/* Note kludge: "help" command forces gnushogi to print
7126
* out something that ends with a newline. */
7127
SendToProgram(message, fp);
7134
DisplayMessage(char *message, int toRemotePlayer)
7138
XtSetArg(arg, XtNlabel, message);
7140
if (!toRemotePlayer)
7141
XtSetValues(localPlayer.messageWidget, &arg, 1);
7143
if (updateRemotePlayer && toRemotePlayer)
7144
XtSetValues(remotePlayer.messageWidget, &arg, 1);
7151
DisplayName(char *name)
7155
XtSetArg(arg, XtNlabel, name);
7156
XtSetValues(localPlayer.titleWidget, &arg, 1);
7158
if (updateRemotePlayer)
7159
XtSetValues(remotePlayer.titleWidget, &arg, 1);
7165
void SendTimeRemaining(FILE *fp)
7167
char message[MSG_SIZ];
7168
long comtime, opptime;
7170
if (BlackOnMove(forwardMostMove) == (fp == toFirstProgFP))
7172
comtime = blackTimeRemaining;
7173
opptime = whiteTimeRemaining;
7177
comtime = whiteTimeRemaining;
7178
opptime = blackTimeRemaining;
7187
sprintf(message, "time %ld\n", comtime / 10);
7188
SendToProgram(message, fp);
7189
sprintf(message, "otime %ld\n", opptime / 10);
7190
SendToProgram(message, fp);
7196
void DisplayMove(int moveNumber)
7198
char message[MSG_SIZ];
7202
if (moveNumber == forwardMostMove - 1)
7203
DisplayMessage(endMessage, False);
7205
DisplayMessage("", False);
7209
sprintf(message, "%d. %s%s %s",
7210
(moveNumber / 2 + 1),
7211
(BlackOnMove(moveNumber) ? "" : "... "),
7212
parseList[moveNumber],
7213
(moveNumber == (forwardMostMove - 1)) ? endMessage : "");
7214
DisplayMessage(message, False);
7221
void DisplayTitle(char *title)
7225
XtSetArg(arg, XtNlabel, title);
7226
XtSetValues(localPlayer.titleWidget, &arg, 1);
7232
/* CHECKME: does this work?
7233
* This routine sends a SIGINT (^C interrupt) to gnushogi to awaken it
7234
* if it might be busy thinking on our time. This normally isn't needed,
7235
* but is useful on systems where the FIONREAD ioctl doesn't work since
7236
* on those systems the gnushogi feature that lets you interrupt its thinking
7237
* just by typing a command does not work.
7239
* In the future, similar code could be used to stop gnushogi and make
7240
* it move immediately when it is thinking about its own move; this could
7241
* be useful if we want to make Backward or ForceMoves work while gnushogi
7248
#if !defined(FIONREAD)
7249
if (localPlayer.appData.noShogiProgram || (pid == 0))
7254
case MachinePlaysBlack:
7255
case MachinePlaysWhite:
7256
case TwoMachinesPlay:
7257
if ((forwardMostMove > backwardMostMove + 1) && maybeThinking)
7259
if (xshogiDebug || localPlayer.appData.debugMode)
7261
fprintf(stderr, "Sending SIGINT to %s\n",
7262
((pid == firstProgramPID) ? "first" : "second"));
7265
(void)kill(pid, SIGINT); /* stop it thinking */
7270
break; /* CHECKME: is this OK? */
7272
#endif /* !defined(FIONREAD) */
7281
if (blackTimeRemaining <= 0)
7288
DisplayName(" Both flags have fallen");
7290
DisplayName(" Black's flag has fallen");
7294
if (whiteTimeRemaining <= 0)
7301
DisplayName(" Both flags have fallen");
7303
DisplayName(" White's flag has fallen");
7312
CheckTimeControl(void)
7314
if (!localPlayer.appData.clockMode)
7317
if (forwardMostMove == 0)
7321
* Add time to clocks when time control is achieved.
7324
if ((forwardMostMove % (localPlayer.appData.movesPerSession * 2)) == 0)
7326
blackTimeRemaining += timeControl;
7327
whiteTimeRemaining += timeControl;
7337
DisplayTimerLabel(localPlayer.blackTimerWidget, "Black",
7338
blackTimeRemaining);
7339
DisplayTimerLabel(localPlayer.whiteTimerWidget, "White",
7340
whiteTimeRemaining);
7342
if (updateRemotePlayer)
7344
DisplayTimerLabel(remotePlayer.blackTimerWidget, "Black",
7345
blackTimeRemaining);
7346
DisplayTimerLabel(remotePlayer.whiteTimerWidget, "White",
7347
whiteTimeRemaining);
7354
#ifdef HAVE_GETTIMEOFDAY
7355
static struct timeval tickStartTV;
7356
static int tickLength;
7359
PartialTickLength(void)
7365
gettimeofday(&tv, &tz);
7366
ptl = ((tv.tv_sec - tickStartTV.tv_sec) * 1000000 +
7367
(tv.tv_usec - tickStartTV.tv_usec) + 500) / 1000;
7369
if (ptl > tickLength)
7374
#else /* !HAVE_GETTIMEOFDAY */
7375
#define tickLength 1000
7376
#endif /* HAVE_GETTIMEOFDAY */
7382
* DisplayClocks manages the game clocks.
7384
* In tournament play, white starts the clock and then black makes a move.
7385
* We give the human user a slight advantage if he is playing black---the
7386
* clocks don't run until he makes his first move, so it takes zero time.
7387
* Also, DisplayClocks doesn't account for network lag so it could get out
7388
* of sync with GNU Shogi's clock -- but then, referees are always right.
7392
DisplayClocks(int clock_mode)
7394
#ifdef HAVE_GETTIMEOFDAY
7396
#endif /* HAVE_GETTIMEOFDAY */
7403
/* Stop clocks and reset to a fresh time control */
7406
XtRemoveTimeOut(timerXID);
7410
blackTimeRemaining = timeControl;
7411
whiteTimeRemaining = timeControl;
7413
if (blackFlag || whiteFlag)
7416
blackFlag = whiteFlag = False;
7422
case DecrementTimers:
7423
/* Decrement running clock to next 1-second boundary */
7424
if (gameMode == PauseGame)
7429
if (!localPlayer.appData.clockMode)
7432
if (BlackOnMove(forwardMostMove))
7434
timeRemaining = (blackTimeRemaining -= tickLength);
7438
timeRemaining = (whiteTimeRemaining -= tickLength);
7444
#ifdef HAVE_GETTIMEOFDAY
7445
tickLength = (((timeRemaining <= 1000) && (timeRemaining > 0))
7447
gettimeofday(&tickStartTV, &tz);
7448
#endif /* HAVE_GETTIMEOFDAY */
7451
XtAppAddTimeOut(appContext, tickLength,
7452
(XtTimerCallbackProc) DisplayClocks,
7453
(XtPointer) DecrementTimers);
7457
/* A player has just moved, so stop the previously running
7458
clock and start the other one. */
7462
XtRemoveTimeOut(timerXID);
7465
#ifdef HAVE_GETTIMEOFDAY
7466
if (localPlayer.appData.clockMode)
7468
if (BlackOnMove(forwardMostMove))
7469
whiteTimeRemaining -= PartialTickLength();
7471
blackTimeRemaining -= PartialTickLength();
7474
#endif /* HAVE_GETTIMEOFDAY */
7480
if (!localPlayer.appData.clockMode)
7483
if ((gameMode == PauseGame)
7484
&& ((pausePreviousMode == MachinePlaysBlack)
7485
|| (pausePreviousMode == MachinePlaysWhite)))
7490
timeRemaining = (BlackOnMove(forwardMostMove)
7491
? blackTimeRemaining : whiteTimeRemaining);
7493
#ifdef HAVE_GETTIMEOFDAY
7494
tickLength = (((timeRemaining <= 1000) && (timeRemaining > 0))
7495
? (((timeRemaining - 1) % 100) + 1)
7496
: (((timeRemaining - 1) % 1000) + 1));
7498
if (tickLength <= 0)
7501
gettimeofday(&tickStartTV, &tz);
7503
#endif /* HAVE_GETTIMEOFDAY */
7505
XtAppAddTimeOut(appContext, tickLength,
7506
(XtTimerCallbackProc) DisplayClocks,
7507
(XtPointer) DecrementTimers);
7510
case ReDisplayTimers:
7511
/* Display current clock values */
7516
/* Stop both clocks */
7520
XtRemoveTimeOut(timerXID);
7523
if (!localPlayer.appData.clockMode)
7526
#ifdef HAVE_GETTIMEOFDAY
7527
if (BlackOnMove(forwardMostMove))
7528
blackTimeRemaining -= PartialTickLength();
7530
whiteTimeRemaining -= PartialTickLength();
7533
#endif /* HAVE_GETTIMEOFDAY */
7537
/* Start clock of player on move, if not already running. */
7543
if (!localPlayer.appData.clockMode)
7546
timeRemaining = (BlackOnMove(forwardMostMove)
7547
? blackTimeRemaining : whiteTimeRemaining);
7549
if (timeRemaining == 0)
7552
#ifdef HAVE_GETTIMEOFDAY
7553
tickLength = (((timeRemaining <= 1000) && (timeRemaining > 0))
7554
? (((timeRemaining - 1) % 100) + 1)
7555
: (((timeRemaining - 1) % 1000) + 1));
7557
if (tickLength <= 0)
7560
gettimeofday(&tickStartTV, &tz);
7561
#endif /* HAVE_GETTIMEOFDAY */
7564
XtAppAddTimeOut(appContext, tickLength,
7565
(XtTimerCallbackProc) DisplayClocks,
7566
(XtPointer)DecrementTimers);
7575
DisplayTimerLabel(Widget w, char *color, long int timer)
7579
struct DisplayData *player;
7581
player = (((w == localPlayer.blackTimerWidget)
7582
|| (w == localPlayer.whiteTimerWidget))
7583
? &localPlayer : &remotePlayer);
7585
if (localPlayer.appData.clockMode)
7587
sprintf(buf, "%s: %s", color, TimeString(timer));
7588
XtSetArg(args[0], XtNlabel, buf);
7592
XtSetArg(args[0], XtNlabel, color);
7595
if (((color[0] == 'W') && BlackOnMove(forwardMostMove))
7596
|| ((color[0] == 'B') && !BlackOnMove(forwardMostMove)))
7598
XtSetArg(args[1], XtNbackground, player->timerForegroundPixel);
7599
XtSetArg(args[2], XtNforeground, player->timerBackgroundPixel);
7603
XtSetArg(args[1], XtNbackground, player->timerBackgroundPixel);
7604
XtSetArg(args[2], XtNforeground, player->timerForegroundPixel);
7607
XtSetValues(w, args, 3);
7616
int second, minute, hour, day;
7618
static char buf[32];
7620
if ((tm > 0) && (tm <= 900))
7622
/* convert milliseconds to tenths, rounding up */
7623
sprintf(buf, " 0.%1ld ", (tm + 99) / 100);
7627
/* convert milliseconds to seconds, rounding up */
7628
tm = (tm + 999) / 1000;
7636
if (tm >= (60 * 60 * 24))
7638
day = (int)(tm / (60 * 60 * 24));
7639
tm -= day * 60 * 60 * 24;
7646
if (tm >= (60 * 60))
7648
hour = (int)(tm / (60 * 60));
7649
tm -= hour * 60 * 60;
7658
minute = (int)(tm / 60);
7670
sprintf(buf, " %s%d:%02d:%02d:%02d ",
7671
sign, day, hour, minute, second);
7675
sprintf(buf, " %s%d:%02d:%02d ",
7676
sign, hour, minute, second);
7680
sprintf(buf, " %s%2d:%02d ",
7681
sign, minute, second);
7693
fprintf(stderr, "Usage: %s\n", programName);
7694
fprintf(stderr, "\tstandard Xt options\n");
7695
fprintf(stderr, "\t-iconic\n");
7696
fprintf(stderr, "\t-tc or -timeControl minutes[:seconds]\n");
7697
fprintf(stderr, "\t-gi or -gameIn (True | False)\n");
7698
fprintf(stderr, "\t-mps or -movesPerSession moves\n");
7699
fprintf(stderr, "\t-st or -searchTime minutes[:seconds]\n");
7700
fprintf(stderr, "\t-sd or -searchDepth number\n");
7701
fprintf(stderr, "\t-clock or -clockMode (True | False)\n");
7702
fprintf(stderr, "\t-td or -timeDelay seconds\n");
7704
fprintf(stderr, "\t-nsp or -noShogiProgram (True | False)\n");
7705
fprintf(stderr, "\t-fsp or -firstShogiProgram program_name\n");
7706
fprintf(stderr, "\t-ssp or -secondShogiProgram program_name\n");
7707
fprintf(stderr, "\t-fh or -firstHost host_name\n");
7708
fprintf(stderr, "\t-sh or -secondHost host_name\n");
7709
fprintf(stderr, "\t-rsh or -remoteShell shell_name\n");
7711
"\t-mm or -matchMode (False | Init | Position | Opening)\n");
7712
fprintf(stderr, "\t-lgf or -loadGameFile file_name\n");
7713
fprintf(stderr, "\t-lpf or -loadPositionFile file_name\n");
7714
fprintf(stderr, "\t-sgf or -saveGameFile file_name\n");
7715
fprintf(stderr, "\t-spf or -savePositionFile file_name\n");
7716
fprintf(stderr, "\t-size or -boardSize (Large | Medium | Small)\n");
7717
fprintf(stderr, "\t-coords or -showCoords (True | False)\n");
7718
fprintf(stderr, "\t-mono or -monoMode (True | False)\n");
7719
fprintf(stderr, "\t-bpc or -blackPieceColor color\n");
7720
fprintf(stderr, "\t-wpc or -whitePieceColor color\n");
7721
fprintf(stderr, "\t-lsc or -lightSquareColor color\n");
7722
fprintf(stderr, "\t-dsc or -darkSquareColor color\n");
7723
fprintf(stderr, "\t-wps or -westernPieceSet (True | False)\n");
7724
fprintf(stderr, "\t-debug or -debugMode (True | False)\n");
7731
CatchPipeSignal(int dummy)
7733
char message[MSG_SIZ];
7736
"%s shogi program (%s) exited unexpectedly",
7737
((lastMsgFP == toFirstProgFP) ? "first" : "second"),
7738
((lastMsgFP == toFirstProgFP)
7739
? localPlayer.appData.firstShogiProgram
7740
: localPlayer.appData.secondShogiProgram));
7741
fprintf(stderr, "%s: %s\n", programName, message);
7742
ShutdownShogiPrograms(message);