summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--database/run.lisp6
-rw-r--r--lispruns.asd47
-rw-r--r--main.lisp46
-rw-r--r--ui.lisp24
-rw-r--r--util.lisp4
5 files changed, 70 insertions, 57 deletions
diff --git a/database/run.lisp b/database/run.lisp
index 739dc96..adee23a 100644
--- a/database/run.lisp
+++ b/database/run.lisp
@@ -24,12 +24,16 @@
(if start
(floor (* 100 (local-time:timestamp-difference end start))))))
-(defun format-elapsed-time (run-split)
+(defun run-split-format-elapsed-time (run-split)
(let ((elapsed (run-split-elapsed-time run-split)))
(if elapsed
(format-time (make-time-alist elapsed))
"-")))
+;;(defun best-split (category-split)
+;; (mito:select-dao 'run-split
+;; (sxql:order-by (:- V
+
;; Returns stuff like PB, best of each split, etc.
(defun run-statistics (category)
`((asdf . 1)))
diff --git a/lispruns.asd b/lispruns.asd
index 4f6b6d8..98faa3f 100644
--- a/lispruns.asd
+++ b/lispruns.asd
@@ -1,25 +1,24 @@
(asdf:defsystem "lispruns"
- :description "A speedrun timer using n-curses written in lisp"
- :version "0.1"
- :author "Simponic"
- :depends-on (:unix-opts
- :mito
- :sxql
- :cl-ppcre
- :croatoan
- :local-time)
- :components ((:file "util") ;; Miscellaneous helpers
- (:file "config") ;; For importing category configuration files
- (:file "digits") ;; Lisp file with cool ascii digits
- (:file "text" :depends-on ("digits")) ;; Helper functions for performing figlet-like actions and such
- (:file "time") ;; Custom time forms
- (:file "ui" :depends-on ("util" "text" "time")) ;; Functions to draw the UI
- (:file "speedrun" :depends-on ("util")) ;; The actual timer logic
- (:file "database/category") ;; Category DAO
- (:file "database/run") ;; Run DAO
- (:file "main" :depends-on ("database/category"
- "database/run"
- "util"
- "config"
- "ui"
- "speedrun"))))
+ :description "A speedrun timer using n-curses written in lisp"
+ :version "0.1"
+ :author "Simponic"
+ :depends-on (:mito
+ :sxql
+ :cl-ppcre
+ :croatoan
+ :local-time)
+ :components ((:file "util") ;; Miscellaneous helpers
+ (:file "config") ;; For importing category configuration files
+ (:file "digits") ;; Lisp file with cool ascii digits
+ (:file "text" :depends-on ("digits")) ;; Helper functions for performing figlet-like actions and such
+ (:file "time") ;; Custom time forms
+ (:file "ui" :depends-on ("util" "text" "time")) ;; Functions to draw the UI
+ (:file "speedrun" :depends-on ("util")) ;; The actual timer logic
+ (:file "database/category") ;; Category DAO
+ (:file "database/run") ;; Run DAO
+ (:file "main" :depends-on ("database/category"
+ "database/run"
+ "util"
+ "config"
+ "ui"
+ "speedrun"))))
diff --git a/main.lisp b/main.lisp
index cfe5d38..40823cd 100644
--- a/main.lisp
+++ b/main.lisp
@@ -20,7 +20,7 @@
(if (ignore-errors (funcall validator input))
input
(progn
- (format t "E: Invalid input. Try again.")
+ (format t "E: Invalid input. Try again.~%")
(get-input prompt validator)))))
;; Options is an alist with the prompt string as the car and the value as the cdr
@@ -53,6 +53,29 @@
(progn (format t "E: Could not find option that matched query.~%")
(select-option options)))))))
+(defun user-create-new-category ()
+ (let* ((name (get-input "Category Name (e.g. \"SM64\"): " 'empty-p))
+ (percentage (get-input "Percentage (e.g. \"16 Star\"): " 'empty-p))
+ (category (mito:insert-dao (make-instance 'category :name name :percentage percentage)))
+ (splits (do ((spliti 1 (1+ spliti))
+ (inputs '() (push (get-input (format nil "Split Name [~a]~a: " spliti (if (<= spliti 1) " (blank when done adding)" ""))) inputs)))
+ ((equal (car inputs) "")
+ (mapcar (lambda
+ (category-split-name)
+ (mito:insert-dao
+ (make-instance 'category-split
+ :name category-split-name
+ :category category)))
+ (reverse (cdr inputs)))))))))
+
+(defun with-selected-category (f)
+ (let* ((categories (mito:select-dao 'category))
+ (category-alist (mapcar (lambda (category) `(,(format nil "~a - ~a" (category-name category) (category-percentage category)) . ,category)) categories)))
+ (if categories
+ (funcall f (select-option category-alist))
+ (format t "E: There are no categories. Try creating one or importing one"))))
+
+
(defun main ()
(let ((choice (select-option '(("Help" . HELP)
("Import a category" . IMPORT-CATEGORY)
@@ -62,6 +85,7 @@
("Exit" . EXIT)))))
(case choice
('HELP
+ (format t "~%")
(mapcar #'(lambda (x) (format t "~a~%" x)) *lispruns-logo*))
('IMPORT-CATEGORY
(import-category (get-input
@@ -69,25 +93,9 @@
(uiop/os:getcwd))
'probe-file)))
('NEW-CATEGORY
- (let* ((name (get-input "Category Name (e.g. \"SM64\"): " 'not-empty-string))
- (percentage (get-input "Percentage (e.g. \"16 Star\"): " 'not-empty-string))
- (category (mito:insert-dao (make-instance 'category :name name :percentage percentage)))
- (splits (do ((spliti 1 (1+ spliti))
- (inputs '() (push (get-input (format nil "Split [~a]: " spliti)) inputs)))
- ((equal (car inputs) "")
- (mapcar (lambda
- (category-split-name)
- (mito:insert-dao
- (make-instance 'category-split
- :name category-split-name
- :category category)))
- (reverse (cdr inputs)))))))))
+ (user-create-new-category))
('START-SPEEDRUN
- (let* ((categories (mito:select-dao 'category))
- (category-alist (mapcar (lambda (category) `(,(format nil "~a - ~a" (category-name category) (category-percentage category)) . ,category)) categories)))
- (if categories
- (speedrun-ui (select-option category-alist))
- (format t "E: There are no categories. Try creating one or importing one"))))
+ (with-selected-category 'speedrun-ui))
('EXIT
(quit))))
(format t "~%")
diff --git a/ui.lisp b/ui.lisp
index e574767..39db207 100644
--- a/ui.lisp
+++ b/ui.lisp
@@ -18,6 +18,12 @@
(inc yi))
slices)))
+;; Formats a category split and a run split for the splits window
+(defun make-split-line (csplit speedrun-split)
+ `((,(category-split-name csplit) . ,(/ 4 12))
+ ("" . ,(/ 1 12))
+ (,(run-split-format-elapsed-time speedrun-split) . ,(/ 3 12))))
+
;; Creates a window with the total time and statistics
(defun timer-window (speedrun pos width height)
(let* ((timerglet (lispglet (format-time (make-time-alist (speedrun-elapsed speedrun)))))
@@ -82,6 +88,7 @@
(subseq elements (car elements-to-draw-subseq) (cadr elements-to-draw-subseq))))
highlight-menu))
+;; The big bad monolithic UI loop
(defun speedrun-ui (category)
(croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil)
(setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*))))
@@ -90,7 +97,9 @@
(state 'TITLE)
(redraws '(title-instance))
(speedrun (make-speedrun category))
- (csplits (category-splits category)))
+ (csplits (category-splits category))
+ ;; TODO
+ (pbs ()))
(flet ((render ()
(case state
('TITLE
@@ -124,16 +133,8 @@
:current-element-index (speedrun-current-split-index speedrun)
:height splits-height
:width max-width
- :elements (mapcar (lambda (csplit speedrun-split)
- `(
- (,(category-split-name csplit) . ,(/ 4 12))
- ("" . ,(/ 1 12))
- (,(format-elapsed-time speedrun-split) . ,(/ 3 12))
- ))
- csplits
- (speedrun-splits speedrun))))
-;; :elements (mapcar #'category-split-name csplits)))
-;; :elements `((("FIRST SPLIT IS EPIC" . ,(/ 4 12)) ("" . ,(/ 1 12)) ("10:10:00.22" . ,(/ 3 12)) ("" . ,(/ 1 12)) ("20:00.00" . ,(/ 3 12))))))
+ ;; Todo: add personal bests to elements
+ :elements (mapcar 'make-split-line csplits (speedrun-splits speedrun))))
(splits-instance (highlight-list-window split-list `(0 ,centered-x)))
(timer-instance (timer-window speedrun `(,splits-height ,centered-x) max-width timer-height)))
(croatoan:refresh splits-instance)
@@ -143,6 +144,7 @@
(if (zerop (mod frame 30))
(inc scroll))
(sleep (/ 1 60))))
+
(croatoan:event-case (scr event)
(#\q (return-from croatoan:event-case))
(#\space
diff --git a/util.lisp b/util.lisp
index 3369a03..fe2cb69 100644
--- a/util.lisp
+++ b/util.lisp
@@ -10,5 +10,5 @@
(defun max-length (lists)
(reduce (lambda (a x) (max a x)) (mapcar #'length lists)))
-(defun not-empty-string (str)
- (not (zerop (length str))))
+(defun empty-p (s)
+ (not (zerop (length s))))