Scid  4.6.5
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  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}
113  toplevel $w
114  wm title $w [::tr ExtHWConfigConnection]
115 
116  label $w.lport -text [::tr ExtHWPort]
117  entry $w.eport -width 50 -textvariable ::ExtHardware::port
118 
119  label $w.lengine -text [::tr ExtHWEngineCmd]
120  entry $w.eengine -width 50 -textvariable ::ExtHardware::engine
121 
122  label $w.lparam -text [::tr ExtHWEngineParam]
123  entry $w.eparam -width 50 -textvariable ::ExtHardware::param
124 
125  label $w.options -text [::tr ExtHWHardware]
126 
127  checkbutton $w.showbutton -text [::tr ExtHWShowButton] -variable ::ExtHardware::showbutton
128 
129  #--------------
130  # Add a new radio button for subsequent new hardware here:
131  radiobutton $w.novag -text [::tr ExtHWNovag] -variable ::ExtHardware::hardware -value 1 -command { \
132  set ::ExtHardware::bindbutton "::novag::connect"
133  .exthardwareConfig.eengine configure -state disabled
134  .exthardwareConfig.eparam configure -state disabled
135  }
136  radiobutton $w.inputeng -text [::tr ExtHWInputEngine] -variable ::ExtHardware::hardware -value 2 -command { \
137  set ::ExtHardware::bindbutton "::inputengine::connectdisconnect"
138  .exthardwareConfig.eengine configure -state normal
139  .exthardwareConfig.eparam configure -state normal
140  }
141  #--------------
142 
143  if { $::ExtHardware::hardware == 1 } {
144  .exthardwareConfig.eengine configure -state disabled
145  .exthardwareConfig.eparam configure -state disabled
146  }
147 
148  button $w.bOk -text OK -command { ::ExtHardware::saveHardwareOptions
149  ::ExtHardware::HWbuttonBind $::ExtHardware::bindbutton
150  destroy .exthardwareConfig
151  $::ExtHardware::bindbutton
152  }
153  button $w.bCancel -text [::tr Cancel] -command "::ExtHardware::HWbuttonImg tb_eng_disconnected ; destroy $w"
154 
155 
156  grid $w.options -stick ew -row 0 -column 0
157  grid $w.novag -stick w -row 0 -column 1
158  grid $w.inputeng -stick w -row 1 -column 1
159 
160  grid $w.lport -stick ew -row 2 -column 0
161  grid $w.eport -row 2 -column 1
162 
163  grid $w.lengine -stick ew -row 3 -column 0
164  grid $w.eengine -row 3 -column 1
165 
166  grid $w.lparam -stick ew -row 4 -column 0
167  grid $w.eparam -row 4 -column 1
168 
169  grid $w.showbutton -stick w -row 5 -column 1
170 
171  grid $w.bOk -stick e -row 6 -column 0
172  grid $w.bCancel -stick w -row 6 -column 1
173 
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  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  if {$::tcl_version >= 8.5} {
245  ::setTitle $w [::tr IEConsole]
246  } else {
247  toplevel $w
248  wm title $w [::tr IEConsole]
249  }
250 
251  recordWinSize $w
252 
253  scrollbar $w.ysc -command { .inputengineconsole.console yview }
254  text $w.console -height 5 -width 80 -wrap word -yscrollcommand "$w.ysc set"
255 
256  label $w.lmode -text [::tr IESending]
257 
258  ::board::new $w.bd 25
259  $w.bd configure -relief solid -borderwidth 1
260 
261  label $w.engine -text "$::ExtHardware::engine $::ExtHardware::port $::ExtHardware::param"
262 
263  radiobutton $w.sendboth -text [::tr Both] -variable send -value 1 -command { ::inputengine::sendToEngine sendboth }
264  radiobutton $w.sendwhite -text [::tr White] -variable send -value 2 -command { ::inputengine::sendToEngine sendwhite }
265  radiobutton $w.sendblack -text [::tr Black] -variable send -value 3 -command { ::inputengine::sendToEngine sendblack }
266 
267  button $w.bInfo -text Info -command { ::inputengine::sysinfo }
268 
269  ###---### rotate does not work yet
270  button $w.bRotate -text [::tr IERotate] -command { ::inputengine::rotateboard }
271 
272  button $w.bSync -text [::tr IESynchronise] -command { ::inputengine::synchronise }
273  button $w.bClose -text [::tr Close] -command { ::inputengine::connectdisconnect }
274 
275  # Buttons for visual move announcement
276  button $w.bPiece -image $inputengine::MovingPieceImg
277  button $w.bMove -font moveFont -text $inputengine::MoveText
278  $w.bPiece configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
279  $w.bMove configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
280 
281  # Buttons for clock display
282  button $w.wClock -text $inputengine::WhiteClock
283  button $w.bClock -text $inputengine::BlackClock
284  $w.wClock configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
285  $w.bClock configure -relief flat -border 0 -highlightthickness 0 -takefocus 0
286 
287 
288  # Store the time as comment
289  checkbutton $w.bStoreClock -text "Store Clock" -variable ::inputengine::StoreClock
290 
291  grid $w.console -stick ns -column 0 -row 0 -columnspan 12
292  grid $w.ysc -stick ns -column 12 -row 0
293 
294  grid $w.engine -stick ewns -column 0 -row 1 -columnspan 9
295 
296  grid $w.lmode -stick ew -column 0 -row 2
297  grid $w.sendboth -stick e -column 2 -row 2
298  grid $w.sendwhite -column 4 -row 2
299  grid $w.sendblack -stick w -column 6 -row 2
300 
301  grid $w.bInfo -stick ew -column 0 -row 3
302  ###---### grid $w.bRotate -stick ew -column 0 -row 4
303  grid $w.bSync -stick ew -column 0 -row 5
304  grid $w.bStoreClock -stick ew -column 0 -row 6
305  grid $w.bClose -stick ew -column 0 -row 11
306 
307  grid $w.bPiece -stick nwes -column 2 -row 3 -rowspan 9 -columnspan 3
308  grid $w.bMove -stick nwes -column 5 -row 3 -rowspan 9 -columnspan 3
309 
310  grid $w.wClock -stick nwes -column 9 -row 11 -columnspan 7
311  grid $w.bClock -stick nwes -column 9 -row 1 -columnspan 7
312 
313  grid $w.bd -stick nw -column 9 -row 2 -rowspan 9 -columnspan 7
314 
315  bind $w <Destroy> { catch ::inputengine::connectdisconnect }
316  bind $w <F1> { helpWindow InputEngine}
317 
319  }
320 
321  proc updateConsole {line} {
322  set t .inputengineconsole.console
323  $t insert end "$line\n"
324  $t yview moveto 1
325  }
326 
327  #----------------------------------------------------------------------
328  # connectdisconnect()
329  # Connects or disconnects depending on the current status of the
330  # external input engine
331  #----------------------------------------------------------------------
332  proc connectdisconnect {} {
333  global ::inputengine::InputEngine
334 
335  set connection $::inputengine::InputEngine(pipe)
336 
337  if {$connection == ""} {
340  } else {
342  }
343  }
344 
345  #----------------------------------------------------------------------
346  # connect():
347  # Fire upt the input engine and connect it to a local pipe.
348  # Also register the eventhandler
349  #----------------------------------------------------------------------
350  proc connect {} {
351  global ::inputengine::InputEngine ::inputengine::engine \
352  ::inputengine::port ::inputengine::param
353 
354  set ::inputengine::engine $::ExtHardware::engine
355  set ::inputengine::port $::ExtHardware::port
356  set ::inputengine::param $::ExtHardware::param
357 
358  ::ExtHardware::HWbuttonImg tb_eng_connecting
359 
360  if {[catch {set InputEngine(pipe) [open "| $engine $port $param" "r+"]} result]} {
361  ::ExtHardware::HWbuttonImg tb_eng_error
362  tk_messageBox -title "Scid: Input Engine" -icon warning -type ok \
363  -message "[::tr IEUnableToStart]\n$engine $port $param"
365  return
366  }
367 
369  }
370 
371  #----------------------------------------------------------------------
372  # disconneet()
373  # Disconnect and close the input engine
374  #----------------------------------------------------------------------
375  proc disconnect {} {
376  global ::inputengine::InputEngine
377  set pipe $::inputengine::InputEngine(pipe)
378 
379  set ::inputengine::connectimg tb_eng_connecting
380 
383  set ::inputengine::connectimg tb_eng_disconnected
384 
385  if { [winfo exists ::inputengine::.inputengineconsole]} {
386  destroy ::inputengine::.inputengineconsole
387  }
388  }
389 
390  #----------------------------------------------------------------------
391  # logEngine
392  # Simple log routine, ie. writing to stdout
393  #----------------------------------------------------------------------
394  proc logEngine {msg} {
395  updateConsole "$msg"
396  }
397 
398  #----------------------------------------------------------------------
399  # sendToEngine()
400  # Send a string to the engine and log it by means of logEngine
401  #----------------------------------------------------------------------
402  proc sendToEngine {msg} {
403  global ::inputengine::InputEngine
404  set pipe $::inputengine::InputEngine(pipe)
405 
406  ::inputengine::logEngine "> $msg"
407  puts $pipe $msg
408  flush $pipe
409  }
410 
411  #----------------------------------------------------------------------
412  # init()
413  # Initialises the engine and internal data
414  #----------------------------------------------------------------------
415  proc Init {} {
416  global ::inputengine::InputEngine
417  set pipe $::inputengine::InputEngine(pipe)
418 
419  # Configure the pipe and initiate the engine
420  set pipe $::inputengine::InputEngine(pipe)
421  fconfigure $pipe -buffering full -blocking 0
422  # register the eventhandler
423  fileevent $pipe readable "::inputengine::readFromEngine"
424 
426  }
427 
428  #----------------------------------------------------------------------
429  # resetEngine()
430  # Resets the engines global variables
431  #----------------------------------------------------------------------
432  proc resetEngine {} {
433  global ::inputengine::InputEngine
434 
435  ::ExtHardware::HWbuttonImg tb_eng_disconnected
436  destroy .inputengineconsole
437  set ::inputengine::InputEngine(pipe) ""
438  set ::inputengine::InputEngine(log) ""
439  set ::inputengine::InputEngine(logCount) 0
440  set ::inputengine::InputEngine(init) 0
441  }
442 
443 
444  #----------------------------------------------------------------------
445  # sysinfo()
446  # Initialises the engine and internal data
447  #----------------------------------------------------------------------
448  proc sysinfo {} {
449  global ::inputengine::InputEngine
450  set pipe $::inputengine::InputEngine(pipe)
451 
452  # call system information
454  }
455 
456  #----------------------------------------------------------------------
457  # rotateboard()
458  # Rotates the board, ie. exchanges a1 and h8
459  #----------------------------------------------------------------------
460  proc rotateboard {} {
461  global ::inputengine::InputEngine
462  set pipe $::inputengine::InputEngine(pipe)
463 
464  # rotate the graphical boards
465  ::board::flip .main.board
466  ::board::flip .inputengineconsole.bd
467 
469  # rotate the board for the input engine
470  ::inputengine::sendToEngine "rotateboard"
472  }
473 
474  #----------------------------------------------------------------------
475  # newgame()
476  # Handle NewGame event from board
477  #----------------------------------------------------------------------
478  proc newgame {} {
479 
480  # Ask the user to save the current game
482  sc_game tags set -event "InputEngine Input"
483  sc_game tags set -date [::utils::date::today]
484  }
485 
486  #----------------------------------------------------------------------
487  # endgame()
488  # Handle game ending (end game event + result)
489  #----------------------------------------------------------------------
490  proc endgame {result} {
491 
492  set filternum [sc_filter first]
493 
494  logEngine " info End Game $filternum: $result"
495 
496  sc_game tags set -result $result
497  gameAdd
498  }
499 
500  #----------------------------------------------------------------------
501  # synchronise()
502  # read board position and set scid's representation accordingly
503  #----------------------------------------------------------------------
504  proc synchronise {} {
505  global ::inputengine::InputEngine
506 
507  logEngine " info Sync called"
508  set InputEngine(init) 0
509 
510  ::inputengine::sendToEngine "getposition"
511  ::inputengine::sendToEngine "getclock"
512  }
513 
514  proc strreverse {str} {
515  set res {}
516  set i [string length $str]
517  while {$i > 0} {append res [string index $str [incr i -1]]}
518  set res
519  }
520 
521  #----------------------------------------------------------------------
522  # readFromEngine()
523  # Event Handler for commands and moves sent from the input
524  # engine, implements input engine protocol
525  #----------------------------------------------------------------------
526  proc readFromEngine {} {
527  global ::inputengine::InputEngine ::inputengine::connectimg
528  set pipe $::inputengine::InputEngine(pipe)
529 
530  set line [string trim [gets $pipe]]
531 
532  # Close the pipe in case the engine was stopped
533  if [eof $pipe] {
534  catch {close $pipe}
536  return
537  }
538 
539  switch -regexp -- $line \
540  "^move *" {
541  set m [string range $line 5 end]
542 
543  set s1 [string range $m 0 1]
544  set s2 [string range $m 2 end]
545  if {$s1 == "0-"} {
546  # castling must not be rewritten
547  set m "$s1$s2"
548  } else {
549  set m "$s1-$s2"
550  }
551 
552  logEngine "$line"
553 
554  if {[catch {sc_move addSan $m}]} {
555  ::utils::sound::PlaySound "sound_alert"
556  logEngine " info Illegal move detected!"
557  logEngine " info Ignoring: $m"
558  .inputengineconsole.bPiece configure -background red
559  .inputengineconsole.bMove configure -background red -text $m
560  } else {
561 
562  .inputengineconsole.bPiece configure -background green
563  .inputengineconsole.bMove configure -background green -text $m
564 
565  updateBoard -animate
566  updateBoard -pgn
567  ::inputengine::sendToEngine "getposition"
568  ::inputengine::sendToEngine "getclock"
569  }
570  } \
571  "info *" {
572  logEngine "< $line"
573  set event [string range $line 5 end]
574  switch -regexp -- $event \
575  "string ERROR *" {
576  set err [string range $event 7 end]
577  tk_messageBox -title "Scid: Input Engine" \
578  -icon warning -type ok -message "Engine $err"
579  catch {close $pipe}
580  ::ExtHardware::HWbuttonImg tb_eng_error
581  return
582  } \
583  "string Chessboard found and initialised*" {
584  # switch to xboard mode and disable move
585  # announcements by the driver engine
587  ::inputengine::sendToEngine "announce"
588  } \
589  "Engine mode : xboard*" {
590  ::inputengine::sendToEngine "getposition"
591  ::ExtHardware::HWbuttonImg $inputengine::connectimg
592  } \
593  "string FEN *" {
594  set InputEngine(init) 0
595  # The first FEN string is always sent as
596  # info string FEN ...
597  # as this is compatible with both UCI and xboard.
598  # At this stage the engine is not set to xboard mode
599  # yet, so this signals a new program startup
600  # accordingly.
601  } \
602  "FEN *" {
603  set fenstr [string range $event 4 end]
604  set fenstr [string trim $fenstr]
605  if { $::inputengine::InputEngine(init) == 0 } {
606  # Initialise scid's representation with the FEN
607  # delivered by the external board.
608  catch {sc_game startBoard $fenstr}
609  updateBoard -pgn
610  set InputEngine(init) 1
611  } else {
612  # Compare the internal representation to the
613  # board each time a FEN string arrives from the
614  # driver.
615  #
616  # Do not check the whole FEN, as the external
617  # board can not know anything about e.p. or O-O
618  # capabilities. Strip them off and compare just
619  # the piece settings.
620  set space [string first " " $fenstr]
621  set fen [string range $fenstr 0 $space]
622 
623  set space [string first " " [sc_pos fen]]
624  set int [string range [sc_pos fen] 0 $space]
625 
626  if {$fen != $int} {
627  ::utils::sound::PlaySound "sound_alert"
628  logEngine " info Wrong Position! $int (scid) != $fen (external)"
629  } else {
630  logEngine " info Board and internal position match."
631  }
632  # Generate a board position out of the FEN
633  # RNBQKBNRPPPP.PPP............P................n..pppppppprnbqkb.r w
634  # Something is in reverse here:
635  ###---### set extpos $fen
636  ###---### regsub -all {8} $extpos "........" extpos
637  ###---### regsub -all {7} $extpos "......." extpos
638  ###---### regsub -all {6} $extpos "......" extpos
639  ###---### regsub -all {5} $extpos "....." extpos
640  ###---### regsub -all {4} $extpos "...." extpos
641  ###---### regsub -all {3} $extpos "..." extpos
642  ###---### regsub -all {2} $extpos ".." extpos
643  ###---### regsub -all {1} $extpos "." extpos
644  ###---### regsub -all {/} $extpos "" extpos
645  ###---### puts stderr [sc_pos board]
646  ###---### puts stderr [strreverse "$extpos"]
647  ###---### set extpos "$extpos w"
648  ###---### ::board::update .inputengineconsole.bd "$extpos w"
649  }
650  } \
651  {moving piece: [A-Z] *} {
652  .inputengineconsole.bPiece configure -image $::board::letterToPiece([string range $event 14 end])80
653  }\
654  {moving piece: [a-z] *} {
655  .inputengineconsole.bPiece configure -image $::board::letterToPiece([string range $event 14 end])80
656  }\
657  "!new game!" {
659  .inputengineconsole.bPiece configure -background blue
660  .inputengineconsole.bMove configure -background blue -text "OK"
661  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
662  } \
663  "!move now!" {
664  logEngine "< info $event"
665  } \
666  "!end game 1-0!" {
667  logEngine "< info $event"
669  .inputengineconsole.bPiece configure -background white
670  .inputengineconsole.bMove configure -background white -text "1-0"
671  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
672  } \
673  "!end game 0-1!" {
674  logEngine "< info $event"
676  .inputengineconsole.bPiece configure -background gray
677  .inputengineconsole.bMove configure -background gray -text "0-1"
678  .inputengineconsole.bPiece configure -image $::board::letterToPiece(k)80
679  } \
680  "!end game 1/2-1/2!" {
681  logEngine "< info $event"
682  ::inputengine::endgame "1/2-1/2"
683  .inputengineconsole.bPiece configure -background black
684  .inputengineconsole.bMove configure -background white -text "1/2-1/2"
685  .inputengineconsole.bPiece configure -image $::board::letterToPiece(.)80
686  } \
687  "!enter setup mode!" {
688  .inputengineconsole.bPiece configure -background yellow
689  .inputengineconsole.bMove configure -background yellow -text "Setup"
690  .inputengineconsole.bPiece configure -image $::board::letterToPiece(K)80
691  logEngine "< info $event"
692  } \
693  "!end setup mode!" {
694  logEngine "< info $event"
696  .inputengineconsole.bPiece configure -background yellow
697  .inputengineconsole.bMove configure -background yellow -text "OK"
698  .inputengineconsole.bPiece configure -image $::board::letterToPiece(q)80
699  } \
700  "!white to move!" {
701  set ::inputengine::toMove "White"
702  .inputengineconsole.wClock configure -background white
703  .inputengineconsole.bClock configure -background gray -foreground black
704 
705  if {$::inputengine::StoreClock == 1} {
706  if { ($::inputengine::oldWhiteClock != $::inputengine::NoClockTime) && \
707  ($::inputengine::WhiteClock != $::inputengine::NoClockTime) } {
708  set wHrs [expr $::inputengine::WhiteClock / 60 / 60]
709  set wMin [expr ($::inputengine::WhiteClock - $wHrs*60*60) / 60]
710  set wSec [expr ($::inputengine::WhiteClock - $wHrs*60*60 - $wMin * 60)]
711  set timediff [expr $::inputengine::oldWhiteClock - $::inputengine::WhiteClock]
712  set ::inputengine::oldWhiteClock $::inputengine::WhiteClock
713  sc_pos setComment "\[%ct $wHrs:$wMin:$wSec\] \[%emt $timediff\]"
714  }
715  }
716  } \
717  "!black to move!" {
718  set ::inputengine::toMove "Black"
719  .inputengineconsole.wClock configure -background gray
720  .inputengineconsole.bClock configure -background black -foreground white
721 
722  if {$::inputengine::StoreClock == 1} {
723  if { ($::inputengine::oldBlackClock != $::inputengine::NoClockTime) && \
724  ($::inputengine::BlackClock != $::inputengine::NoClockTime) } {
725  set bHrs [expr $::inputengine::BlackClock / 60 / 60]
726  set bMin [expr ($::inputengine::BlackClock - $bHrs*60*60) / 60]
727  set bSec [expr ($::inputengine::BlackClock - $bHrs*60*60 - $bMin * 60)]
728  set timediff [expr $::inputengine::oldBlackClock - $::inputengine::BlackClock]
729  set ::inputengine::oldBlackClock $::inputengine::BlackClock
730  sc_pos setComment "\[%ct $bHrs:$bMin:$bSec\] \[%emt $timediff\]"
731  }
732  }
733  } \
734  "No Clock detected" {
735  set ::inputengine::WhiteClock $::inputengine::NoClockTime
736  set ::inputengine::BlackClock $::inputengine::NoClockTime
737  .inputengineconsole.wClock configure -text $::inputengine::WhiteClock
738  .inputengineconsole.bClock configure -text $::inputengine::BlackClock
739  } \
740  "Time White:" {
741  if { ($::inputengine::oldWhiteClock == $::inputengine::NoClockTime) } {
742  set ::inputengine::oldWhiteClock $::inputengine::WhiteClock
743  }
744  # Get the time in seconds
745  regsub -all {[A-Za-z:# ]} $event "" ::inputengine::WhiteClock
746 
747  # calculate a sensible format
748  set wHrs [expr $::inputengine::WhiteClock / 60 / 60]
749  set wMin [expr ($::inputengine::WhiteClock - $wHrs*60*60) / 60]
750  set wSec [expr ($::inputengine::WhiteClock - $wHrs*60*60 - $wMin * 60)]
751 
752  if {$wHrs > 0} {
753  .inputengineconsole.wClock configure -text "$wHrs:$wMin:$wSec (EXT)"
754  } else {
755  .inputengineconsole.wClock configure -text "$wMin:$wSec (EXT)"
756  }
757 
758  ###---### Is this enough to set game clocks for all possible occurrences?
759  catch { ::gameclock::setSec 1 [expr -1*$::inputengine::WhiteClock]}
760  } \
761  "Time Black:" {
762  if { ($::inputengine::oldBlackClock == $::inputengine::NoClockTime) } {
763  set ::inputengine::oldBlackClock $::inputengine::BlackClock
764  }
765  regsub -all {[A-Za-z:# ]} $event "" ::inputengine::BlackClock
766 
767  set bHrs [expr $::inputengine::BlackClock / 60 / 60]
768  set bMin [expr ($::inputengine::BlackClock - $bHrs*60*60) / 60]
769  set bSec [expr ($::inputengine::BlackClock - $bHrs*60*60 - $bMin * 60)]
770 
771  if {$bHrs > 0} {
772  .inputengineconsole.bClock configure -text "$bHrs:$bMin:$bSec (EXT)"
773  } else {
774  .inputengineconsole.bClock configure -text "$bMin:$bSec (EXT)"
775  }
776 
777  ###---### Is this enough to set game clocks for all possible occurrences?
778  catch { ::gameclock::setSec 2 [expr -1*$::inputengine::BlackClock]}
779  } \
780  "Wrong move performed:" {
781  # This event can only be used if there is a possibility to
782  # send the last move to the input engine for it to cross
783  # check. This however is not easy in Scid, therefore
784  # compare FEN.
785  #
786  # ::utils::sound::PlaySound "sound_alert"
787  # logEngine "< info $event"
788  } \
789  "DGT Projects - This DGT board" {
790  set ::inputengine::connectimg tb_eng_dgt
791  set txt [string range $event 7 end]
792  ## ::utils::tooltip::Set .button.exthardware "$::inputengine::port:\n$txt"
793  }} \
794  default {
795  logEngine "< $line"
796  }
797  # Should better show current wooden board position? Return value of
798  # sc_pos board is
799  # RNBQKBNRPPPP.PPP............P................n..pppppppprnbqkb.r w
800  ::board::update .inputengineconsole.bd [sc_pos board]
801  }
802 
803 
804 
805 }
806 
807 
808 ###
809 ### End of file: inputengine.tcl
810 ###