Aurebesh typing test for emacs

This entry is part 3 of 3 in the series Aurebesh

A few weeks ago, I posted the Aurebesh typing test. Since I’ve recently started learning elisp, I figured that I should implement the typing test as a feature for emacs.

The code below is terrible with bugs and problems, but heck, it’s my first elisp program after all. My goal is to improve the version over time and to add features such as logging results in a separate file and displaying a progress statistic. To use it, you’ll need to first install the Aurebesh font.

(setq correct 0)
(setq wrong 0)
(setq seconds-left 60)
(setq test-start t)

(require 'widget)

(defun aurebesh-typing-test ()
  "Aurebesh typing test"
  (interactive)
  (get-buffer-create "*Aurebesh typing test*")
  (custom/reset-aurebesh-typing-test-vars)
  (custom/aurebesh-typing-test))

(defun custom/reset-aurebesh-typing-test-vars()
  (setq test-start t)
  (setq correct 0)
  (setq wrong 0)
  (setq seconds-left 60))

(defun custom/aurebesh-typing-test()
  (with-current-buffer "*Aurebesh typing test*"
    (custom/setup-buffer)
    (custom/refresh-seconds)
    (custom/create-line-with-widget)
    (insert "Correct / wrong answers: " (number-to-string correct) " / " (number-to-string wrong) " \n")
    (custom/setup-widget)
    (custom/set-aurebesh)))

(defun custom/setup-buffer()
  (kill-all-local-variables)
  (let ((inhibit-read-only t))
    (erase-buffer))
  (remove-overlays))

(defun custom/refresh-seconds()
  (with-no-warnings
    (goto-line 1)
    (custom/delete-line)
    (insert "Seconds: " (number-to-string seconds-left) "\n")))

(defun custom/delete-line()
  (let ((beg (point)))
    (forward-line 1)
    (delete-region beg (point))))

(defun custom/create-line-with-widget()
  (if (> seconds-left 0)
      (setq randomChar (custom/get-random-char))
    (setq randomChar ""))
  (widget-insert randomChar)
  (widget-insert "\t")
  (widget-create 'editable-field
		 :size 15
		 :correct (string randomChar)
		 :notify 'custom/check-input-value)
  (widget-insert "\n"))

(defun custom/setup-widget()
  (use-local-map widget-keymap)
  (widget-setup)
  (widget-forward 1))

(defun custom/set-aurebesh()
  "Sets the aurebesh font in current buffer"
  (interactive)
  (setq buffer-face-mode-face '(:family "Aurebesh"))
  (buffer-face-mode))

(defun custom/check-input-value(widget &rest ignore)
  "Compare aurebesh input character with requested one."
  (cond
   ((string-match 
     (widget-get widget :correct)
     (widget-value widget))
    (custom/correct-input widget))
   ((not(= (length (widget-value widget)) 0))
    (custom/wrong-input))))

(defun custom/correct-input(widget)
  (if test-start
      (progn
	(custom/start-timer)
	(setq test-start nil)))
  (if (> seconds-left 0)
      (progn
	(setq correct (+ correct 1))
	(custom/next-character widget))))

(defun custom/start-timer()
  "Start Aurebesh test"
  (setq seconds-left 60)
  (setq timer (run-with-timer 0 1 'custom/decrement-seconds)))

(defun custom/decrement-seconds()
  (with-current-buffer "*Aurebesh typing test*"
    (if (> seconds-left 0)
;	(progn
	  (setq seconds-left (- seconds-left 1))
;	  (custom/refresh-seconds)
;	  (widget-forward 1))
      (custom/stop-aurebesh-typing-test))))

(defun custom/stop-aurebesh-typing-test()
  (with-current-buffer "*Aurebesh typing test*"
  (custom/refresh-seconds)
  (cancel-timer timer)
  (custom/set-arial)))

(defun custom/set-arial()
   "Sets the arial font in current buffer"
   (interactive)
   (setq buffer-face-mode-face '(:family "Arial"))
   (buffer-face-mode))

(defun custom/next-character(widget)
  (with-current-buffer "*Aurebesh typing test*"
    (custom/fill-random-character widget)
    (custom/fill-correct-wrong-answers)
    (custom/refresh-seconds)
    (widget-forward 1)
    ))

(defun custom/fill-random-character(widget)
  (with-no-warnings
    (goto-line 2))
  (delete-char 1)
  (if (> seconds-left 0)
      (setq randomChar (custom/get-random-char))
    (setq randomChar ""))
  (widget-insert randomChar)
  (widget-put widget :correct (string randomChar))
  (widget-value-set widget ""))

(defun custom/get-random-char ()
  "Insert a random alphanumeric character.."
  (let ((mycharset "abcdefghijklmnopqrstyvwxyz"))
    (elt mycharset (random (length mycharset)))))

(defun custom/fill-correct-wrong-answers()
  (with-no-warnings
    (goto-line 3))
  (kill-line)
  (insert "Correct / wrong answers: " (number-to-string correct) " / " (number-to-string wrong) " \n"))
  
(defun custom/wrong-input()
  (message "%s" (widget-get widget :correct))
  (widget-value-set widget "")
  (setq wrong (+ wrong 1)))

OpenGL glMapBuffer/glMapBufferRange

This entry is part 4 of 4 in the series Learning OpenGL

I’ve changed the last program a bit to use glMapBufferRange instead of glBufferSubData. For this specific example, there isn’t really any advantage in using glMapBufferRange over glBufferSubData, but in general, it has better performance than glBufferSubData.

I was actually going to change a bit more code, but I wasted quite a bit of time for a new laptop (from Santa) which turned out to have hardware issues (50% of laptops I’ve owned so far had defects when I got them – what a jinx I am).

You can find my latest OpenGL program as always on github.

Why glMapBuffer/glMapBufferRange?

The problem with glBufferData as well as with glBufferSubData is that you need to allocate some memory provided by your application before you can copy it to memory owned by OpenGL. Let’s assume you have a file with all vertex data. Wouldn’t it be nice to directly read that file into OpenGL memory? That’s exactly what glMapBuffer and glMapBufferRange is good for. You avoid wasting memory and copying operations. If you compare my code in ‘OpenGL – Beginner 4’ and ‘OpenGL – Beginner 5’, you’ll find that the usage of glMapBufferRange and glBufferSubData is very similar.

I suggest reading OpenGL’s wiki about mapping for a detailed explanation.

Morse code typing test

A week ago, I wrote a little Javascript to create a typing test for Aurebesh. I figured, since I had the basics, why not change the script a bit so that it’s also useable for other things. Morse code, in particular, came in mind. That’s why you can find at the end of this post a little Morse code typing test.

I’m not going to explain the details of Morse code here, since there are lots of good explanations on the net. For example, I used this page for a short memory refresh in Morse code.

Please be aware, that the following utility is a very basic version and has very limited functionality. I hope it’s useful to learn the alphabet as well as digits, but it is far from teaching you proper usage of Morse code. What’s wrong with it or better to say, what’s missing?

  • The length of dit (•) and dah (-) is only approximated. Let’s say you start your first dit with a duration of 1 second. Obviously, the pause between each dit/dah should be exactly one dit and the length of each dah should be 3 dit’s. The testing tool below only measures the first pause of the test and determines the duration of a dit and dah. The pause durations afterwards are completely ignored. Also, the test considers everything below 1.5 * dit duration as a dit and everything above as a dah. My goal for a future version of this tool is to add a nice realtime graph which shows how long the actual pauses, dit’s, and dah’s were. Such a graph should help to improve timing.
  • For beginners, it would be nice to narrow down the amount of letters/digits. E.g. only letters a to g are asked.
  • The test only measures your skill in coding letters. It doesn’t test for words or even sentences. Therefore, it also doesn’t test for comma, slash, period, and question mark. In a future version, I would like to include an additional test which does request words and sentences.
  • The current test only rates the amount of correct/wrong answers. It would definitely be nice to see the average speed value as well.
  • Currently you can’t test the other way around. That means, you can’t listen to a morse code sequence and then write what you heard.

Typing test:

Seconds left:

Correct/Wrong answers:
• – (a)    – • • • (b)    – • – • (c)    – • • (d)    • (e)
• • – • (f)    – – • (g)    • • • • (h)    • • (i)   • – – – (j)
– • – (k)    • – • • (l)    – – (m)    – • (n)    – – – (o)
• – – • (p)    – – • – (q)    • – • (r)    • • • (s)    – (t)    • • – (u)
• • • – (v)    • – – (w)    – • • – (x)    – • – – (y)    – – • • (z)
– – – – – (0)    • – – – – (1)    • • – – – (2)    • • • – – (3)
• • • • – (4)    • • • • • (5)    – • • • • (6)
– – • • • (7)    – – – • • (8)    – – – – • (9)

OpenGL glBufferSubData

This entry is part 3 of 4 in the series Learning OpenGL

I finally wrote the next beginner program which uses the OpenGL glBufferSubData function. The advantage with this function is that you don’t need to define a huge buffer upfront, but instead provide the graphics card small buffers piece by piece.

I added a little thread to my program and call the draw function every 200 milliseconds. The program is as the ones before fairly unspectacular. All you see is a moving rectangle.

For my next program, I’ll use the glMapBuffer function which is generally the better function to use. Why and how to use it will be described in my next post.

Aurebesh typing test

This entry is part 2 of 3 in the series Aurebesh

Just a bit more than a week ago, I wrote a post about me learning Aurebesh. I’m still far from proficient, but I continue practicing and, even more important, enjoying it. As mentioned in the one post, I’m using a few online tools to practice and after using Patrick Lambert’s timed translation tool for a bit, I felt like writing my own version with slight changes.

I really like Patrick’s little utility, since it gives you a nice and quick progress feedback. After using it for a bit, I could think of a few improvements. I, for example, don’t quite like that I have to press enter after each character. I consider that redundant and it makes my result count lower than it could be. Furthermore, his implementation continues with a new random character even if the user input was wrong. I prefer being stuck with an Aurebesh character till the correct input has been provided.

After writing my own little version and trying it out, I figured that it would be nice if I saw the number of wrong inputs as well. After all, a high number of correct inputs looks great, but if the number of incorrect inputs is high as well, it kind of diminishes the success.

I hope you find the little Aurebesh typing test feature useful. Please let me know if you can think of something to improve it even more.

Aurebesh typing test

Seconds left:

Correct/Wrong answers:
A(a) B(b) C(c) D(d) E(e) F(f) G(g) H(h) I(i)
J(j) K(k) L(l) M(m) N(n) O(o) P(p) Q(q) R(r)
S(s) T(t) U(u) V(v) W(w) X(x) Y(y) Z(z)