Scid  4.7.0
inputengine.tcl
Go to the documentation of this file.
1 ###
2 ### inputengine.tcl
3 ###
4 ### This file adds input eninge protocol support to scid chess
5 ### database. It adds menu with subitems to the tools-menu and
6 ### additionally a button to enable the engine from within the GUI.
7 ### This module is selfcontained and can just be linked into the Scid
8 ### database upon built.
9 ###
10 ### $Id: inputengine.tcl,v 4.3 2011/02/13 18:12:02 arwagner Exp $
11 ### Last change: <Mon, 2010/11/15 13:00:39 arwagner agamemnon>
12 ### Author : Alexander Wagner
13 ### Language : TCL
14 ###
15 #----------------------------------------------------------------------
16 
17 namespace eval ExtHardware {
18 
19  set engine "dgtdrv2.i686";
20  set port "/dev/ttyUSB0"
21  set param "la"
22 
23  # the hardware configured by default:
24  # 1 : Novag Citrine
25  # 2 : Input Engine
26  set hardware 1
27 
28  set bindbutton "::novag::connect"
29  set showbutton 0
30 
31  #----------------------------------------------------------------------
32  # Save the hardware options
33  #----------------------------------------------------------------------
34  proc saveHardwareOptions {} {
35  set optionF ""
36  if {[catch {open [scidConfigFile ExtHardware] w} optionF]} {
37  tk_messageBox -title "Scid: Unable to write file" -type ok -icon warning \
38  -message "Unable to write options file: [scidConfigFile InputEngine]\n$optionF"
39  } else {
40  puts $optionF "# Scid options file"
41  puts $optionF "# Version: $::scidVersion, $::scidVersionDate"
42  puts $optionF "# This file contains commands in the Tcl language format."
43  puts $optionF "# If you edit this file, you must preserve valid Tcl"
44  puts $optionF "# format or it will not set your Scid options properly."
45  puts $optionF ""
46 
47  foreach i { ::ExtHardware::engine \
48  ::ExtHardware::port \
49  ::ExtHardware::param \
50  ::ExtHardware::hardware \
51  ::ExtHardware::showbutton \
52  ::ExtHardware::bindbutton } {
53  puts $optionF "set $i [list [set $i]]"
54  }
55 
56  }
57  close $optionF
58  set ::statusBar "External hardware options were saved to: [scidConfigFile correspondence]"
59 
60  # Check if the hw connect button exists already. If not, add it.
61  if { [winfo exists .main.fbutton.button.exthardware]} {
62  return
63  } else {
64  if { $::ExtHardware::showbutton == 1 } {
65 
66  ttk::frame .main.fbutton.button.space4 -width 15
67  button .main.fbutton.button.exthardware -image tb_eng_disconnected
68  .main.fbutton.button.exthardware configure -relief flat -border 1 -highlightthickness 0 \
69  -anchor n -takefocus 0
70  bind .main.fbutton.button.exthardware <Any-Enter> "+.main.fbutton.button.exthardware configure -relief groove"
71  bind .main.fbutton.button.exthardware <Any-Leave> "+.main.fbutton.button.exthardware configure -relief flat; break"
72  pack .main.fbutton.button.space4 .main.fbutton.button.exthardware -side left -pady 1 -padx 0 -ipadx 0 -pady 0 -ipady 0
73  pack .main.fbutton.button.exthardware -side left -pady 1 -padx 0 -ipadx 0 -pady 0 -ipady 0
74 
75  .main.fbutton.button.exthardware configure -command $::ExtHardware::bindbutton
76  }
77  }
78 
79  }
80 
81  #----------------------------------------------------------------------
82  # Set the hardware connect button image
83  #----------------------------------------------------------------------
84  proc HWbuttonImg {img} {
85 
86  if { $::ExtHardware::showbutton == 1 } {
87  .main.fbutton.button.exthardware configure -image $img -relief flat
88  }
89  }
90 
91  #----------------------------------------------------------------------
92  # Set the hardware connect button command binding
93  #----------------------------------------------------------------------
94  proc HWbuttonBind {cmd} {
95 
96  if { $::ExtHardware::showbutton == 1 } {
97  set ::ExtHardware::bindbutton $cmd
98  }
99  }
100 
101  #----------------------------------------------------------------------
102  # config:
103  # Opens the configuration dialog to input driver engines binary
104  # and parameters required to fire up the engine
105  #----------------------------------------------------------------------
106  proc config {} {
107  global ::ExtHardware::port ::ExtHardware::engine ::ExtHardware::param ::ExtHardware::hardware
108 
109  ::ExtHardware::HWbuttonImg tb_eng_query
110 
111  set w .exthardwareConfig
112  if { [winfo exists $w]} { return}
114 
115  wm title $w [::tr ExtHWConfigConnection]
116 
117  ttk::label $w.lport -text [::tr ExtHWPort]
118  ttk::entry $w.eport -width 50 -textvariable ::ExtHardware::port
119 
120  ttk::label $w.lengine -text [::tr ExtHWEngineCmd]
121  ttk::entry $w.eengine -width 50 -textvariable ::ExtHardware::engine
122 
123  ttk::label $w.lparam -text [::tr ExtHWEngineParam]
124  ttk::entry $w.eparam -width 50 -textvariable ::ExtHardware::param
125 
126  ttk::label $w.options -text [::tr ExtHWHardware]
127 
128  ttk::checkbutton $w.showbutton -text [::tr ExtHWShowButton] -variable ::ExtHardware::showbutton
129 
130  #--------------
131  # Add a new radio button for subsequent new hardware here:
132  ttk::radiobutton $w.novag -text [::tr ExtHWNovag] -variable ::ExtHardware::hardware -value 1 -command { \
133  set ::ExtHardware::bindbutton "::novag::connect"
134  .exthardwareConfig.eengine configure -state disabled
135  .exthardwareConfig.eparam configure -state disabled
136  }
137  ttk::radiobutton $w.inputeng -text [::tr ExtHWInputEngine] -variable ::ExtHardware::hardware -value 2 -command { \
138  set ::ExtHardware::bindbutton "::inputengine::connectdisconnect"
139  .exthardwareConfig.eengine configure -state normal
140  .exthardwareConfig.eparam configure -state normal
141  }
142  #--------------
143 
144  if { $::ExtHardware::hardware == 1 } {
145  .exthardwareConfig.eengine configure -state disabled
146  .exthardwareConfig.eparam configure -state disabled
147  }
148 
149  ttk::frame $w.buttons
150  ttk::button $w.bOk -text OK -command { ::ExtHardware::saveHardwareOptions
151  ::ExtHardware::HWbuttonBind $::ExtHardware::bindbutton
152  destroy .exthardwareConfig
153  $::ExtHardware::bindbutton
154  }
155  ttk::button $w.bCancel -text [::tr Cancel] -command "::ExtHardware::HWbuttonImg tb_eng_disconnected ; destroy $w"
156  packdlgbuttons $w.bCancel $w.bOk -in $w.buttons
157 
158  grid $w.options -stick ew -row 0 -column 0
159  grid $w.novag -stick w -row 0 -column 1
160  grid $w.inputeng -stick w -row 1 -column 1
161 
162  grid $w.lport -stick ew -row 2 -column 0
163  grid $w.eport -row 2 -column 1
164 
165  grid $w.lengine -stick ew -row 3 -column 0
166  grid $w.eengine -row 3 -column 1
167 
168  grid $w.lparam -stick ew -row 4 -column 0
169  grid $w.eparam -row 4 -column 1
170 
171  grid $w.showbutton -stick w -row 5 -column 1
172 
173  grid $w.buttons -sticky news -row 6 -column 0 -columnspan 2
174  bind $w <F1> { helpWindow HardwareConfig}
175 
176  }
177 
178 }
179  #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
180  # source the options file to overwrite the above setup
181  if {[catch {source [scidConfigFile ExtHardware]}]} {
182  #::splash::add "Unable to find the options file: [file tail $optionsFile]"
183  } else {
184 
185  # Add the button to connect the engine to the button bar
186  if { $::ExtHardware::showbutton == 1 } {
187 
188  ttk::frame .main.fbutton.button.space4 -width 15
189  button .main.fbutton.button.exthardware -image tb_eng_disconnected
190  .main.fbutton.button.exthardware configure -relief flat -border 1 -highlightthickness 0 \
191  -anchor n -takefocus 0
192  bind .main.fbutton.button.exthardware <Any-Enter> "+.main.fbutton.button.exthardware configure -relief groove"
193  bind .main.fbutton.button.exthardware <Any-Leave> "+.main.fbutton.button.exthardware configure -relief flat; break"
194  pack .main.fbutton.button.space4 .main.fbutton.button.exthardware -side left -pady 1 -padx 0 -ipadx 0 -pady 0 -ipady 0
195  pack .main.fbutton.button.exthardware -side left -pady 1 -padx 0 -ipadx 0 -pady 0 -ipady 0
196 
197  .main.fbutton.button.exthardware configure -command $::ExtHardware::bindbutton
198  }
199 
200  ::splash::add "External hardware configuration was found and loaded."
201  }
202 
203 
204 
205 #======================================================================
206 
207 namespace eval inputengine {
208  global ::ExtHardware::port ::ExtHardware::engine ::ExtHardware::param ::ExtHardware::hardware
209 
210  set engine $::ExtHardware::engine
211  set port $::ExtHardware::port
212  set param $::ExtHardware::param
213 
214  set InputEngine(pipe) ""
215  set InputEngine(log) ""
216  set InputEngine(logCount) 0
217  set InputEngine(init) 0
218  set connectimg tb_eng_ok
219  set MovingPieceImg $::board::letterToPiece(.)80
220  set MoveText " "
221 
222  set NoClockTime "--:--"
223  set StoreClock 0
224 
225  set WhiteClock $::inputengine::NoClockTime
226  set BlackClock $::inputengine::NoClockTime
227  set oldWhiteClock $::inputengine::NoClockTime
228  set oldBlackClock $::inputengine::NoClockTime
229  set toMove "White"
230 
231  font create moveFont -family Helvetica -size 56 -weight bold
232 
233  #----------------------------------------------------------------------
234  # Generate the console window also used for status display
235  #----------------------------------------------------------------------
236  proc consoleWindow {} {
237 
238  set w .inputengineconsole
239  if { [winfo exists $w]} {
241  return
242  }
243 
245  $w configure -background [ttk::style lookup . -background]
246  ::setTitle $w [::tr IEConsole]
247 
248  ttk::scrollbar $w.ysc -command { .inputengineconsole.console yview }
249  text $w.console -height 5 -width 80 -wrap word -yscrollcommand "$w.ysc set"
250 
251  ttk::label $w.lmode -text [::tr IESending]
252 
253  ::board::new $w.bd 25
254  $w.bd configure -relief solid -borderwidth 1
255 
256  ttk::label $w.engine -text "$::ExtHardware::engine $::ExtHardware::port $::ExtHardware::param"
257 
258  ttk::radiobutton $w.sendboth -text [::tr Both] -variable send -value 1 -command { ::inputengine::sendToEngine sendboth }
259  ttk::radiobutton $w.sendwhite -text [::tr White] -variable send -value 2 -command { ::inputengine::sendToEngine sendwhite }
260  ttk::radiobutton $w.sendblack -text [::tr Black] -variable send -value 3 -command { ::inputengine::sendToEngine sendblack }
261 
262  ttk::button $w.bInfo -text Info -command { ::inputengine::sysinfo }
263 
264  ###---### rotate does not work yet
265  ttk::button $w.bRotate -text [::tr IERotate] -command { ::inputengine::rotateboard }
266 
267  ttk::button $w.bSync -text [::tr IESynchronise] -command { ::inputengine::synchronise }
268  ttk::button $w.bClose -text [::tr Close] -command { ::inputengine::connectdisconnect }
269 
270  # Buttons for visual move announcement
271  button $w.bPiece -image $inputengine::MovingPieceImg
272  button $w.bMove -font moveFont -text $inputengine::MoveText
273  $w.bPiece configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
274  $w.bMove configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
275 
276  # Buttons for clock display
277  button $w.wClock -text $inputengine::WhiteClock
278  button $w.bClock -text $inputengine::BlackClock
279  $w.wClock configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
280  $w.bClock configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
281 
282 
283  # Store the time as comment
284  ttk::checkbutton $w.bStoreClock -text "Store Clock" -variable ::inputengine::StoreClock
285 
286  grid $w.console -stick ns -column 0 -row 0 -columnspan 12
287  grid $w.ysc -stick ns -column 12 -row 0
288 
289  grid $w.engine -stick ewns -column 0 -row 1 -columnspan 9
290 
291  grid $w.lmode -stick ew -column 0 -row 2
292  grid $w.sendboth -stick e -column 2 -row 2
293  grid $w.sendwhite -column 4 -row 2
294  grid $w.sendblack -stick w -column 6 -row 2
295 
296  grid $w.bInfo -stick ew -column 0 -row 3
297  ###---### grid $w.bRotate -stick ew -column 0 -row 4
298  grid $w.bSync -stick ew -column 0 -row 5
299  grid $w.bStoreClock -stick ew -column 0 -row 6
300  grid $w.bClose -stick ew -column 0 -row 11
301 
302  grid $w.bPiece -stick nwes -column 2 -row 3 -rowspan 9 -columnspan 3
303  grid $w.bMove -stick nwes -column 5 -row 3 -rowspan 9 -columnspan 3
304 
305  grid $w.wClock -stick nwes -column 9 -row 11 -columnspan 7
306  grid $w.bClock -stick nwes -column 9 -row 1 -columnspan 7
307 
308  grid $w.bd -stick nw -column 9 -row 2 -rowspan 9 -columnspan 7
309 
310  bind $w <Destroy> { catch ::inputengine::connectdisconnect }
311  bind $w <F1> { helpWindow InputEngine}
312 
314  }
315 
316  proc updateConsole {line} {
317  set t .inputengineconsole.console
318  $t insert end "$line\n"
319  $t yview moveto 1
320  }
321 
322  #----------------------------------------------------------------------
323  # connectdisconnect()
324  # Connects or disconnects depending on the current status of the
325  # external input engine
326  #----------------------------------------------------------------------
327  proc connectdisconnect {} {
328  global ::inputengine::InputEngine
329 
330  set connection $::inputengine::InputEngine(pipe)
331 
332  if {$connection == ""} {
335  } else {
337  }
338  }
339 
340  #----------------------------------------------------------------------
341  # connect():
342  # Fire upt the input engine and connect it to a local pipe.
343  # Also register the eventhandler
344  #----------------------------------------------------------------------
345  proc connect {} {
346  global ::inputengine::InputEngine ::inputengine::engine \
347  ::inputengine::port ::inputengine::param
348 
349  set ::inputengine::engine $::ExtHardware::engine
350  set ::inputengine::port $::ExtHardware::port
351  set ::inputengine::param $::ExtHardware::param
352 
353  ::ExtHardware::HWbuttonImg tb_eng_connecting
354 
355  if {[catch {set InputEngine(pipe) [open "| $engine $port $param" "r+"]} result]} {
356  ::ExtHardware::HWbuttonImg tb_eng_error
357  tk_messageBox -title "Scid: Input Engine" -icon warning -type ok \
358  -message "[::tr IEUnableToStart]\n$engine $port $param"
360  return
361  }
362 
364  }
365 
366  #----------------------------------------------------------------------
367  # disconneet()
368  # Disconnect and close the input engine
369  #----------------------------------------------------------------------
370  proc disconnect {} {
371  global ::inputengine::InputEngine
372  set pipe $::inputengine::InputEngine(pipe)
373 
374  set ::inputengine::connectimg tb_eng_connecting
375 
378  set ::inputengine::connectimg tb_eng_disconnected
379 
380  if { [winfo exists ::inputengine::.inputengineconsole]} {
381  destroy ::inputengine::.inputengineconsole
382  }
383  }
384 
385  #----------------------------------------------------------------------
386  # logEngine
387  # Simple log routine, ie. writing to stdout
388  #----------------------------------------------------------------------
389  proc logEngine {msg} {
390  updateConsole "$msg"
391  }
392 
393  #----------------------------------------------------------------------
394  # sendToEngine()
395  # Send a string to the engine and log it by means of logEngine
396  #----------------------------------------------------------------------
397  proc sendToEngine {msg} {
398  global ::inputengine::InputEngine
399  set pipe $::inputengine::InputEngine(pipe)
400 
401  ::inputengine::logEngine "> $msg"
402  puts $pipe $msg
403  flush $pipe
404  }
405 
406  #----------------------------------------------------------------------
407  # init()
408  # Initialises the engine and internal data
409  #----------------------------------------------------------------------
410  proc Init {} {
411  global ::inputengine::InputEngine
412  set pipe $::inputengine::InputEngine(pipe)
413 
414  # Configure the pipe and initiate the engine
415  set pipe $::inputengine::InputEngine(pipe)
416  fconfigure $pipe -buffering full -blocking 0
417  # register the eventhandler
418  fileevent $pipe readable "::inputengine::readFromEngine"
419 
421  }
422 
423  #----------------------------------------------------------------------
424  # resetEngine()
425  # Resets the engines global variables
426  #----------------------------------------------------------------------
427  proc resetEngine {} {
428  global ::inputengine::InputEngine
429 
430  ::ExtHardware::HWbuttonImg tb_eng_disconnected
431  destroy .inputengineconsole
432  set ::inputengine::InputEngine(pipe) ""
433  set ::inputengine::InputEngine(log) ""
434  set ::inputengine::InputEngine(logCount) 0
435  set ::inputengine::InputEngine(init) 0
436  }
437 
438 
439  #----------------------------------------------------------------------
440  # sysinfo()
441  # Initialises the engine and internal data
442  #----------------------------------------------------------------------
443  proc sysinfo {} {
444  global ::inputengine::InputEngine
445  set pipe $::inputengine::InputEngine(pipe)
446 
447  # call system information
449  }
450 
451  #----------------------------------------------------------------------
452  # rotateboard()
453  # Rotates the board, ie. exchanges a1 and h8
454  #----------------------------------------------------------------------
455  proc rotateboard {} {
456  global ::inputengine::InputEngine
457  set pipe $::inputengine::InputEngine(pipe)
458 
459  # rotate the graphical boards
460  ::board::flip .main.board
461  ::board::flip .inputengineconsole.bd
462 
464  # rotate the board for the input engine
465  ::inputengine::sendToEngine "rotateboard"
467  }
468 
469  #----------------------------------------------------------------------
470  # newgame()
471  # Handle NewGame event from board
472  #----------------------------------------------------------------------
473  proc newgame {} {
474 
475  # Ask the user to save the current game
477  sc_game tags set -event "InputEngine Input"
478  sc_game tags set -date [::utils::date::today]
479  }
480 
481  #----------------------------------------------------------------------
482  # endgame()
483  # Handle game ending (end game event + result)
484  #----------------------------------------------------------------------
485  proc endgame {result} {
486 
487  set filternum [sc_filter first]
488 
489  logEngine " info End Game $filternum: $result"
490 
491  sc_game tags set -result $result
492  gameAdd
493  }
494 
495  #----------------------------------------------------------------------
496  # synchronise()
497  # read board position and set scid's representation accordingly
498  #----------------------------------------------------------------------
499  proc synchronise {} {
500  global ::inputengine::InputEngine
501 
502  logEngine " info Sync called"
503  set InputEngine(init) 0
504 
505  ::inputengine::sendToEngine "getposition"
506  ::inputengine::sendToEngine "getclock"
507  }
508 
509  proc strreverse {str} {
510  set res {}
511  set i [string length $str]
512  while {$i > 0} {append res [string index $str [incr i -1]]}
513  set res
514  }
515 
516  #----------------------------------------------------------------------
517  # readFromEngine()
518  # Event Handler for commands and moves sent from the input
519  # engine, implements input engine protocol
520  #----------------------------------------------------------------------
521  proc readFromEngine {} {
522  global ::inputengine::InputEngine ::inputengine::connectimg
523  set pipe $::inputengine::InputEngine(pipe)
524 
525  set line [string trim [gets $pipe]]
526 
527  # Close the pipe in case the engine was stopped
528  if [eof $pipe] {
529  catch {close $pipe}
531  return
532  }
533 
534  switch -regexp -- $line \
535  "^move *" {
536  set m [string range $line 5 end]
537 
538  set s1 [string range $m 0 1]
539  set s2 [string range $m 2 end]
540  if {$s1 == "0-"} {
541  # castling must not be rewritten
542  set m "$s1$s2"
543  } else {
544  set m "$s1-$s2"
545  }
546 
547  logEngine "$line"
548 
549  if {[catch {sc_move addSan $m}]} {
550  ::utils::sound::PlaySound "sound_alert"
551  logEngine " info Illegal move detected!"
552  logEngine " info Ignoring: $m"
553  .inputengineconsole.bPiece configure -background red
554  .inputengineconsole.bMove configure -background red -text $m
555  } else {
556 
557  .inputengineconsole.bPiece configure -background green
558  .inputengineconsole.bMove configure -background green -text $m
559 
560  updateBoard -animate
561  updateBoard -pgn
562  ::inputengine::sendToEngine "getposition"
563  ::inputengine::sendToEngine "getclock"
564  }
565  } \
566  "info *" {
567  logEngine "< $line"
568  set event [string range $line 5 end]
569  switch -regexp -- $event \
570  "string ERROR *" {
571  set err [string range $event 7 end]
572  tk_messageBox -title "Scid: Input Engine" \
573  -icon warning -type ok -message "Engine $err"
574  catch {close $pipe}
575  ::ExtHardware::HWbuttonImg tb_eng_error
576  return
577  } \
578  "string Chessboard found and initialised*" {
579  # switch to xboard mode and disable move
580  # announcements by the driver engine
582  ::inputengine::sendToEngine "announce"
583  } \
584  "Engine mode : xboard*" {
585  ::inputengine::sendToEngine "getposition"
586  ::ExtHardware::HWbuttonImg $inputengine::connectimg
587  } \
588  "string FEN *" {
589  set InputEngine(init) 0
590  # The first FEN string is always sent as
591  # info string FEN ...
592  # as this is compatible with both UCI and xboard.
593  # At this stage the engine is not set to xboard mode
594  # yet, so this signals a new program startup
595  # accordingly.
596  } \
597  "FEN *" {
598  set fenstr [string range $event 4 end]
599  set fenstr [string trim $fenstr]
600  if { $::inputengine::InputEngine(init) == 0 } {
601  # Initialise scid's representation with the FEN
602  # delivered by the external board.
603  catch {sc_game startBoard $fenstr}
604  updateBoard -pgn
605  set InputEngine(init) 1
606  } else {
607  # Compare the internal representation to the
608  # board each time a FEN string arrives from the
609  # driver.
610  #
611  # Do not check the whole FEN, as the external
612  # board can not know anything about e.p. or O-O
613  # capabilities. Strip them off and compare just
614  # the piece settings.
615  set space [string first " " $fenstr]
616  set fen [string range $fenstr 0 $space]
617 
618  set space [string first " " [sc_pos fen]]
619  set int [string range [sc_pos fen] 0 $space]
620 
621  if {$fen != $int} {
622  ::utils::sound::PlaySound "sound_alert"
623  logEngine " info Wrong Position! $int (scid) != $fen (external)"
624  } else {
625  logEngine " info Board and internal position match."
626  }
627  # Generate a board position out of the FEN
628  # RNBQKBNRPPPP.PPP............P................n..pppppppprnbqkb.r w
629  # Something is in reverse here:
630  ###---### set extpos $fen
631  ###---### regsub -all {8} $extpos "........" extpos
632  ###---### regsub -all {7} $extpos "......." extpos
633  ###---### regsub -all {6} $extpos "......" extpos
634  ###---### regsub -all {5} $extpos "....." extpos
635  ###---### regsub -all {4} $extpos "...." extpos
636  ###---### regsub -all {3} $extpos "..." extpos
637  ###---### regsub -all {2} $extpos ".." extpos
638  ###---### regsub -all {1} $extpos "." extpos
639  ###---### regsub -all {/} $extpos "" extpos
640  ###---### puts stderr [sc_pos board]
641  ###---### puts stderr [strreverse "$extpos"]
642  ###---### set extpos "$extpos w"
643  ###---### ::board::update .inputengineconsole.bd "$extpos w"
644  }
645  } \
646  {moving piece: [A-Z] *} {
647  .inputengineconsole.bPiece configure -image $::board::letterToPiece([string range $event 14 end])80
648  }\
649  {moving piece: [a-z] *} {
650  .inputengineconsole.bPiece configure -image $::board::letterToPiece([string range $event 14 end])80
651  }\
652  "!new game!" {
654  .inputengineconsole.bPiece configure -background blue
655  .inputengineconsole.bMove configure -background blue -text "OK"
656  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
657  } \
658  "!move now!" {
659  logEngine "< info $event"
660  } \
661  "!end game 1-0!" {
662  logEngine "< info $event"
664  .inputengineconsole.bPiece configure -background white
665  .inputengineconsole.bMove configure -background white -text "1-0"
666  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
667  } \
668  "!end game 0-1!" {
669  logEngine "< info $event"
671  .inputengineconsole.bPiece configure -background gray
672  .inputengineconsole.bMove configure -background gray -text "0-1"
673  .inputengineconsole.bPiece configure -image $::board::letterToPiece(k)80
674  } \
675  "!end game 1/2-1/2!" {
676  logEngine "< info $event"
677  ::inputengine::endgame "1/2-1/2"
678  .inputengineconsole.bPiece configure -background black
679  .inputengineconsole.bMove configure -background white -text "1/2-1/2"
680  .inputengineconsole.bPiece configure -image $::board::letterToPiece(.)80
681  } \
682  "!enter setup mode!" {
683  .inputengineconsole.bPiece configure -background yellow
684  .inputengineconsole.bMove configure -background yellow -text "Setup"
685  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
686  logEngine "< info $event"
687  } \
688  "!end setup mode!" {
689  logEngine "< info $event"
691  .inputengineconsole.bPiece configure -background yellow
692  .inputengineconsole.bMove configure -background yellow -text "OK"
693  .inputengineconsole.bPiece configure -image $::board::letterToPiece(q)80
694  } \
695  "!white to move!" {
696  set ::inputengine::toMove "White"
697  .inputengineconsole.wClock configure -background white
698  .inputengineconsole.bClock configure -background gray -foreground black
699 
700  if {$::inputengine::StoreClock == 1} {
701  if { ($::inputengine::oldWhiteClock != $::inputengine::NoClockTime) && \
702  ($::inputengine::WhiteClock != $::inputengine::NoClockTime) } {
703  set wHrs [expr $::inputengine::WhiteClock / 60 / 60]
704  set wMin [expr ($::inputengine::WhiteClock - $wHrs*60*60) / 60]
705  set wSec [expr ($::inputengine::WhiteClock - $wHrs*60*60 - $wMin * 60)]
706  set timediff [expr $::inputengine::oldWhiteClock - $::inputengine::WhiteClock]
707  set ::inputengine::oldWhiteClock $::inputengine::WhiteClock
708  sc_pos setComment "\[%ct $wHrs:$wMin:$wSec\] \[%emt $timediff\]"
709  }
710  }
711  } \
712  "!black to move!" {
713  set ::inputengine::toMove "Black"
714  .inputengineconsole.wClock configure -background gray
715  .inputengineconsole.bClock configure -background black -foreground white
716 
717  if {$::inputengine::StoreClock == 1} {
718  if { ($::inputengine::oldBlackClock != $::inputengine::NoClockTime) && \
719  ($::inputengine::BlackClock != $::inputengine::NoClockTime) } {
720  set bHrs [expr $::inputengine::BlackClock / 60 / 60]
721  set bMin [expr ($::inputengine::BlackClock - $bHrs*60*60) / 60]
722  set bSec [expr ($::inputengine::BlackClock - $bHrs*60*60 - $bMin * 60)]
723  set timediff [expr $::inputengine::oldBlackClock - $::inputengine::BlackClock]
724  set ::inputengine::oldBlackClock $::inputengine::BlackClock
725  sc_pos setComment "\[%ct $bHrs:$bMin:$bSec\] \[%emt $timediff\]"
726  }
727  }
728  } \
729  "No Clock detected" {
730  set ::inputengine::WhiteClock $::inputengine::NoClockTime
731  set ::inputengine::BlackClock $::inputengine::NoClockTime
732  .inputengineconsole.wClock configure -text $::inputengine::WhiteClock
733  .inputengineconsole.bClock configure -text $::inputengine::BlackClock
734  } \
735  "Time White:" {
736  if { ($::inputengine::oldWhiteClock == $::inputengine::NoClockTime) } {
737  set ::inputengine::oldWhiteClock $::inputengine::WhiteClock
738  }
739  # Get the time in seconds
740  regsub -all {[A-Za-z:# ]} $event "" ::inputengine::WhiteClock
741 
742  # calculate a sensible format
743  set wHrs [expr $::inputengine::WhiteClock / 60 / 60]
744  set wMin [expr ($::inputengine::WhiteClock - $wHrs*60*60) / 60]
745  set wSec [expr ($::inputengine::WhiteClock - $wHrs*60*60 - $wMin * 60)]
746 
747  if {$wHrs > 0} {
748  .inputengineconsole.wClock configure -text "$wHrs:$wMin:$wSec (EXT)"
749  } else {
750  .inputengineconsole.wClock configure -text "$wMin:$wSec (EXT)"
751  }
752 
753  ###---### Is this enough to set game clocks for all possible occurrences?
754  catch { ::gameclock::setSec 1 [expr -1*$::inputengine::WhiteClock]}
755  } \
756  "Time Black:" {
757  if { ($::inputengine::oldBlackClock == $::inputengine::NoClockTime) } {
758  set ::inputengine::oldBlackClock $::inputengine::BlackClock
759  }
760  regsub -all {[A-Za-z:# ]} $event "" ::inputengine::BlackClock
761 
762  set bHrs [expr $::inputengine::BlackClock / 60 / 60]
763  set bMin [expr ($::inputengine::BlackClock - $bHrs*60*60) / 60]
764  set bSec [expr ($::inputengine::BlackClock - $bHrs*60*60 - $bMin * 60)]
765 
766  if {$bHrs > 0} {
767  .inputengineconsole.bClock configure -text "$bHrs:$bMin:$bSec (EXT)"
768  } else {
769  .inputengineconsole.bClock configure -text "$bMin:$bSec (EXT)"
770  }
771 
772  ###---### Is this enough to set game clocks for all possible occurrences?
773  catch { ::gameclock::setSec 2 [expr -1*$::inputengine::BlackClock]}
774  } \
775  "Wrong move performed:" {
776  # This event can only be used if there is a possibility to
777  # send the last move to the input engine for it to cross
778  # check. This however is not easy in Scid, therefore
779  # compare FEN.
780  #
781  # ::utils::sound::PlaySound "sound_alert"
782  # logEngine "< info $event"
783  } \
784  "DGT Projects - This DGT board" {
785  set ::inputengine::connectimg tb_eng_dgt
786  set txt [string range $event 7 end]
787  ## ::utils::tooltip::Set .button.exthardware "$::inputengine::port:\n$txt"
788  }} \
789  default {
790  logEngine "< $line"
791  }
792  # Should better show current wooden board position? Return value of
793  # sc_pos board is
794  # RNBQKBNRPPPP.PPP............P................n..pppppppprnbqkb.r w
795  ::board::update .inputengineconsole.bd [sc_pos board]
796  }
797 
798 
799 
800 }
801 
802 
803 ###
804 ### End of file: inputengine.tcl
805 ###