summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2002-04-14 19:52:56 +0000
committerJohn Wiegley <johnw@newartisans.com>2002-04-14 19:52:56 +0000
commitd5e9f0a3c531104936728c5a599dde77c67319b0 (patch)
tree0868b9db313b9f15ddd9e74050171237cd8b889f
parentd881274ead232567cf80f0057031b05f5b0551bc (diff)
*** no comment ***
-rw-r--r--chess-announce.el20
-rw-r--r--chess-display.el20
-rw-r--r--chess-engine.el29
-rw-r--r--chess-ics.el2
-rw-r--r--chess-ics1.el1
-rw-r--r--chess-images.el10
-rw-r--r--chess-irc.el2
-rw-r--r--chess-plain.el1
-rw-r--r--chess-sound.el34
-rw-r--r--chess-transport.el2
-rw-r--r--chess.el147
11 files changed, 148 insertions, 120 deletions
diff --git a/chess-announce.el b/chess-announce.el
index ff1a331..ca563e0 100644
--- a/chess-announce.el
+++ b/chess-announce.el
@@ -44,24 +44,24 @@ The first is called one start of the announcer. The second is called
with the string to announce each time. The third is called to
shutdown the announcer process, if necessary.")
-(defun chess-announce-available-p () t)
-
-(defun chess-announce-for-game (game)
- "Announce the opponent's moves in GAME."
- (funcall (nth 0 chess-announce-functions))
- (chess-game-add-hook game 'chess-announce-handler))
-
-(defun chess-announce-handler (game ignore event &rest args)
+(defun chess-announce-handler (event &rest args)
"This display module presents a standard chessboard.
See `chess-display-type' for the different kinds of displays."
(cond
+ ((eq event 'initialize)
+ (kill-buffer (current-buffer))
+ (set-buffer (generate-new-buffer " *chess-announce*"))
+ (funcall (nth 0 chess-announce-functions))
+ t)
+
((eq event 'shutdown)
(funcall (nth 2 chess-announce-functions)))
((eq event 'move)
- (let* ((ply (chess-game-ply game (1- (chess-game-index game))))
+ (let* ((ply (chess-game-ply chess-display-game
+ (1- (chess-game-index chess-display-game))))
(pos (chess-ply-pos ply)))
- (unless (eq (chess-game-data game 'my-color)
+ (unless (eq (chess-game-data chess-display-game 'my-color)
(chess-pos-side-to-move pos))
(let* ((source (chess-ply-source ply))
(target (chess-ply-target ply))
diff --git a/chess-display.el b/chess-display.el
index 266b2d1..4f1d004 100644
--- a/chess-display.el
+++ b/chess-display.el
@@ -79,15 +79,15 @@ makes moves, or any other changes to the underlying game."
(chess-error 'no-such-style name))
(with-current-buffer (generate-new-buffer "*Chessboard*")
(chess-display-mode read-only)
- (funcall handler 'initialize)
- (setq chess-display-style style
- chess-display-perspective perspective
- chess-display-event-handler handler)
- (if main
- (chess-display-set-main nil))
- (chess-display-set-game* nil game)
- (add-hook 'kill-buffer-hook 'chess-display-quit nil t)
- (current-buffer))))
+ (when (funcall handler 'initialize)
+ (setq chess-display-style style
+ chess-display-perspective perspective
+ chess-display-event-handler handler)
+ (if main
+ (chess-display-set-main nil))
+ (chess-display-set-game* nil game)
+ (add-hook 'kill-buffer-hook 'chess-display-quit nil t)
+ (current-buffer)))))
(defun chess-display-clone (display style perspective)
(let ((new-display (chess-display-create chess-display-game
@@ -314,6 +314,8 @@ called."
"This display module presents a standard chessboard.
See `chess-display-type' for the different kinds of displays."
(with-current-buffer display
+ (apply chess-display-event-handler event args)
+
(cond
((eq event 'shutdown)
(chess-display-destroy nil))
diff --git a/chess-engine.el b/chess-engine.el
index 3f2a8a0..d8299fa 100644
--- a/chess-engine.el
+++ b/chess-engine.el
@@ -264,20 +264,21 @@
(handler (intern-soft (concat (symbol-name module) "-handler"))))
(with-current-buffer (generate-new-buffer " *chess-engine*")
(let ((proc (apply handler 'initialize handler-ctor-args)))
- (setq chess-engine-regexp-alist (symbol-value regexp-alist)
- chess-engine-event-handler handler
- chess-engine-response-handler
- (or response-handler 'chess-engine-default-handler))
- (chess-engine-set-game* nil game t)
- (when (processp proc)
- (unless (memq (process-status proc) '(run open))
- (chess-error 'failed-engine-start))
- (setq chess-engine-process proc)
- (set-process-buffer proc (current-buffer))
- (set-process-filter proc 'chess-engine-filter))
- (setq chess-engine-current-marker (point-marker)))
- (add-hook 'kill-buffer-hook 'chess-engine-on-kill nil t)
- (current-buffer))))
+ (when proc ;must be a process or t
+ (setq chess-engine-regexp-alist (symbol-value regexp-alist)
+ chess-engine-event-handler handler
+ chess-engine-response-handler
+ (or response-handler 'chess-engine-default-handler))
+ (chess-engine-set-game* nil game t)
+ (when (processp proc)
+ (unless (memq (process-status proc) '(run open))
+ (chess-error 'failed-engine-start))
+ (setq chess-engine-process proc)
+ (set-process-buffer proc (current-buffer))
+ (set-process-filter proc 'chess-engine-filter))
+ (setq chess-engine-current-marker (point-marker))
+ (add-hook 'kill-buffer-hook 'chess-engine-on-kill nil t)
+ (current-buffer))))))
(defun chess-engine-on-kill ()
"Function called when the buffer is killed."
diff --git a/chess-ics.el b/chess-ics.el
index 2ca62a2..4b1284a 100644
--- a/chess-ics.el
+++ b/chess-ics.el
@@ -211,7 +211,7 @@ who is black."
;; name from the output
(comint-send-string "guest\n\n"))))
- nil)
+ t)
((eq event 'match)
(setq chess-engine-pending-offer 'match)
diff --git a/chess-ics1.el b/chess-ics1.el
index b53b2e2..f21c63e 100644
--- a/chess-ics1.el
+++ b/chess-ics1.el
@@ -39,6 +39,7 @@
(defun chess-ics1-handler (event &rest args)
(cond
+ ((eq event 'initialize) t)
((eq event 'popup)
(if chess-display-popup
(funcall chess-ics1-popup-function)))
diff --git a/chess-images.el b/chess-images.el
index d8dfba9..d2e2256 100644
--- a/chess-images.el
+++ b/chess-images.el
@@ -151,10 +151,18 @@ called."
(?p "pawn" 5))
"The names and index values of the different pieces.")
+(chess-message-catalog 'english
+ '((no-images-fallback . "Could not find suitable chess images; using ics1 display")))
+
(defun chess-images-handler (event &rest args)
(cond
((eq event 'initialize)
- (chess-images-initialize))
+ (when (display-graphic-p)
+ (chess-images-initialize)
+ (if chess-images-size
+ t
+ (chess-message 'no-images-fallback)
+ nil)))
((eq event 'popup)
(if chess-display-popup
(funcall chess-images-popup-function)))
diff --git a/chess-irc.el b/chess-irc.el
index 2f284cb..c5ae5d0 100644
--- a/chess-irc.el
+++ b/chess-irc.el
@@ -77,7 +77,7 @@
(set-marker (process-mark proc) (point))
(chess-message 'irc-waiting)))
(setq chess-irc-process proc))
- nil)
+ t)
((eq event 'match)
(setq chess-irc-opponent (read-string (chess-string 'irc-challenge)))
diff --git a/chess-plain.el b/chess-plain.el
index 2a2c545..693e5eb 100644
--- a/chess-plain.el
+++ b/chess-plain.el
@@ -70,6 +70,7 @@ modify `chess-plain-piece-chars' to avoid real confusion.)"
(defun chess-plain-handler (event &rest args)
(cond
+ ((eq event 'initialize) t)
((eq event 'popup)
(if chess-display-popup
(funcall chess-plain-popup-function)))
diff --git a/chess-sound.el b/chess-sound.el
index 7f2f4db..e5b0de3 100644
--- a/chess-sound.el
+++ b/chess-sound.el
@@ -42,33 +42,33 @@
:type 'boolean
:group 'chess-sound)
-(defun chess-sound-available-p ()
- (and (file-directory-p chess-sound-directory)
- (file-readable-p (expand-file-name "move.wav"
- chess-sound-directory))
- (or (eq chess-sound-play-function 'play-sound-file)
- (file-executable-p chess-sound-program))))
-
-(defun chess-sound-for-game (game)
- "Announce the opponent's moves in GAME."
- (chess-game-add-hook game 'chess-sound-handler))
-
(defsubst chess-sound (file)
(funcall chess-sound-play-function
(expand-file-name (concat file ".wav")
chess-sound-directory)))
-(defun chess-sound-play (file)
+(defsubst chess-sound-play (file)
(apply 'call-process chess-sound-program
nil nil nil (append chess-sound-args (list file))))
-(defun chess-sound-handler (game ignore event &rest args)
+(defun chess-sound-handler (event &rest args)
"This display module presents a standard chessboard.
See `chess-display-type' for the different kinds of displays."
- (when (eq event 'move)
- (let* ((ply (chess-game-ply game (1- (chess-game-index game))))
+ (cond
+ ((eq event 'initialize)
+ (kill-buffer (current-buffer))
+ (set-buffer (generate-new-buffer " *chess-sound*"))
+ (and (file-directory-p chess-sound-directory)
+ (file-readable-p (expand-file-name "move.wav"
+ chess-sound-directory))
+ (or (eq chess-sound-play-function 'play-sound-file)
+ (file-executable-p chess-sound-program))))
+
+ ((eq event 'move)
+ (let* ((ply (chess-game-ply chess-display-game
+ (1- (chess-game-index chess-display-game))))
(pos (chess-ply-pos ply)))
- (if (eq (chess-game-data game 'my-color)
+ (if (eq (chess-game-data chess-display-game 'my-color)
(chess-pos-side-to-move pos))
(if chess-sound-my-moves
(chess-sound "move"))
@@ -101,7 +101,7 @@ See `chess-display-type' for the different kinds of displays."
(if (chess-ply-keyword ply :checkmate)
(chess-sound "#_"))
(if (chess-ply-keyword ply :stalemate)
- (chess-sound "smate")))))))
+ (chess-sound "smate"))))))))
(provide 'chess-sound)
diff --git a/chess-transport.el b/chess-transport.el
index dcec224..3a1beba 100644
--- a/chess-transport.el
+++ b/chess-transport.el
@@ -24,7 +24,7 @@
;;
;; NOTE: Be sure not to return a process, or else chess-engine
;; will do all the transport work!
- )
+ t)
((eq event 'send)
;; Transmit the string given in `(car args)' to the outbound
diff --git a/chess.el b/chess.el
index b79bab5..0d765f8 100644
--- a/chess.el
+++ b/chess.el
@@ -85,25 +85,26 @@
(defconst chess-version "2.0a8"
"The version of the Emacs chess program.")
-(defcustom chess-default-display (if (display-graphic-p)
- 'chess-images 'chess-ics1)
- "Default module set to be used when starting a chess session."
- :type 'sexp
+(defcustom chess-default-displays
+ '((chess-images chess-ics1 chess-plain)
+ (chess-sound chess-announce))
+ "Default displays to be used when starting a chess session.
+This is a list of display modules, all of which will be invoked. If
+any entry is itself a list, then it specifies a series of alternatives
+if the first modules were not available.
+Note: The very first display is marked the 'main' display, which will
+popup on significant events (unless `chess-display-popup' in nil);
+also, killing this main display will cause all related chess buffers
+to be killed."
+ :type '(repeat (choice symbol (repeat symbol)))
:group 'chess)
-(defcustom chess-default-engine 'chess-gnuchess
- "Default engine to be used when starting a chess session."
- :type 'sexp
- :group 'chess)
-
-(defcustom chess-announce-moves t
- "If non-nil, announce when your opponent makes a move.
-This variable can also be a symbol which names a different announcing
-module to use. This happens verbally if 'festival' is installed, or
-if you have sound files installed and a sound play (see
-chess-sound.el). Otherwise it just prints a message in your
-minibuffer, which works well for Emacspeak users."
- :type 'boolean
+(defcustom chess-default-engine
+ '(chess-crafty chess-gnuchess chess-phalanx)
+ "Default engine to be used when starting a chess session.
+A list indicates a series of alternatives if the first engines are not
+available."
+ :type '(choice symbol (repeat symbol))
:group 'chess)
(defcustom chess-full-name (user-full-name)
@@ -111,8 +112,27 @@ minibuffer, which works well for Emacspeak users."
:type 'string
:group 'chess)
-(chess-message-catalog 'english
- '((no-images-fallback . "Could not find suitable chess images; using ics1 display")))
+(defun chess--create-display (module game my-color first disable-popup)
+ (if (require module nil t)
+ (let ((display (chess-display-create game module my-color first)))
+ (when display
+ (chess-game-set-data game 'my-color my-color)
+ (if disable-popup
+ (chess-display-disable-popup display))
+ (chess-display-update display t)
+ display))))
+
+(defun chess--create-engine (module game response-handler ctor-args)
+ (if (require module nil t)
+ (let ((engine (chess-engine-create game module
+ response-handler ctor-args)))
+ (when engine
+ ;; for the sake of engines which are ready to play now, and
+ ;; which don't need connect/accept negotiation (most
+ ;; computerized engines fall into this category), we need to
+ ;; let them know we're ready to begin
+ (chess-engine-command engine 'ready)
+ engine))))
;;;###autoload
(defun chess (&optional engine disable-popup engine-response-handler
@@ -129,53 +149,48 @@ minibuffer, which works well for Emacspeak users."
"none"))))
chess-default-engine)))
- (require chess-default-display)
- (let* ((my-color t) ; we start out as white always
- (game (chess-game-create))
- (display (chess-display-create game chess-default-display
- my-color)))
-
- (when (and (eq chess-default-display 'chess-images)
- (with-current-buffer display
- (null chess-images-size)))
- (chess-message 'no-images-fallback)
- (chess-display-destroy display)
- (require 'chess-ics1)
- (setq display (chess-display-create game 'chess-ics1 my-color)))
-
- (chess-game-set-data game 'my-color my-color)
- (if disable-popup
- (chess-display-disable-popup display))
- (chess-display-set-main display)
-
- (let ((engine-module (or engine chess-default-engine)))
- (when (and engine-module (require engine-module nil t))
- (let ((engine (apply 'chess-engine-create game engine-module nil
- engine-ctor-args)))
- ;; for the sake of engines which are ready to play now, and
- ;; which don't need connect/accept negotiation (most
- ;; computerized engines fall into this category), we need to
- ;; let them know we're ready to begin
- (chess-engine-command engine 'ready))
-
- (when (and (not (eq engine-module 'chess-none))
- chess-announce-moves)
- (if (and (not (eq chess-announce-moves t))
- (symbolp chess-announce-moves))
- (let ((name (symbol-name chess-announce-moves)))
- (require chess-announce-moves)
- (if (funcall (intern (concat name "-available-p")))
- (funcall (intern (concat name "-for-game")) game)))
- (require 'chess-sound)
- (if (chess-sound-available-p)
- (chess-sound-for-game game)
- (require 'chess-announce)
- (if (chess-announce-available-p)
- (chess-announce-for-game game)))))))
-
- (chess-display-update display t)
-
- (cons display engine)))
+ (let ((my-color t) ; we start out as white always
+ (game (chess-game-create))
+ (first t)
+ objects)
+
+ (dolist (module chess-default-displays)
+ (let (display)
+ (if (symbolp module)
+ (setq display (chess--create-display module game my-color
+ first disable-popup))
+ ;; this module is actually a list, which means keep trying
+ ;; until we find one that works
+ (while module
+ (if (setq display (chess--create-display (car module) game
+ my-color first
+ disable-popup))
+ (setq module nil)
+ (setq module (cdr module)))))
+ (if display
+ (push display objects)))
+ (setq first nil))
+
+ (let ((module (or engine chess-default-engine)))
+ (if (symbolp module)
+ (push (chess--create-engine module game
+ engine-response-handler
+ engine-ctor-args)
+ objects)
+ (let (engine)
+ (while module
+ (setq engine (chess--create-engine (car module) game
+ engine-response-handler
+ engine-ctor-args))
+ (if engine
+ (progn
+ (push engine objects)
+ (setq module nil))
+ (setq module (cdr module))))
+ (unless engine
+ (push nil objects)))))
+
+ objects))
(defalias 'chess-session 'chess)