;;; bad-sdl3 --- bad sdl3 -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: (require 'cl-lib) (cl-pushnew "." load-path :test #'string=) (require 'luki-lisp) (-> 'bad-alpha) (-> 'bad-ecs) (-> 'bad-mode) (defvar ecs-circles nil) (defvar ecs-triangles nil) (defvar ecs-overview) (defvar ecs-pause) (let ((dm (@f "bad-sdl%s" module-file-suffix))) (load dm nil t) (declare-function sdl_draw_circle dm) (declare-function sdl_draw_clear dm) (declare-function sdl_draw_frame dm) (declare-function sdl_draw_grid_toggle dm) (declare-function sdl_draw_init dm) (declare-function sdl_draw_quit dm) (declare-function sdl_draw_triangle dm) (declare-function sdl_draw_webp dm)) (defun bad-grid-string () (mapconcat #'concat ecs-grid "\n")) (defun bad-hz () (setq current-time-list nil) (cdr (time-convert nil nil))) (defun bad-ticks () (1st (time-convert nil nil))) (defun bad-sdl-fps () (setq inhibit-redisplay t) (ecs-grid-init) (bad-mode) (sdl_draw_init) (sdl_draw_grid_toggle) (cl-loop with hz = (bad-hz) with fps = 60 with delta = (// hz fps) with frames = (** 2 13) with slp = 0 with ahead = 0 with done = 0 with ver = (@f " GNU Emacs %d.%d on %s" emacs-major-version emacs-minor-version system-type) with set-to = (@f " fps (set to) %d" fps) with what = " Emacs Lisp C SDL3 dynamic module" with beg = (bad-ticks) with stops = (number-sequence (+ beg delta) (+ beg (* frames delta)) delta) for next in stops for frames-msg = (@f " frame %d of %d (%d%%)" done frames (* 100 (// done frames))) for actual-msg = (@f " fps (actual) %.1f" (// (* done hz) (- (bad-ticks) beg))) for ahead-msg = (@f " total sleep %.1f s -> avg. %.5f s/frame" ahead (// ahead done)) do (ecs-grid-clear 32) (aset ecs-grid 11 (make-string 64 32)) (aset ecs-grid 12 (make-string 64 32)) (aset ecs-grid 13 (string-pad ver 64)) (aset ecs-grid 14 (string-pad what 64)) (aset ecs-grid 15 (make-string 64 32)) (aset ecs-grid 16 (string-pad frames-msg 64)) (aset ecs-grid 17 (make-string 64 32)) (aset ecs-grid 18 (string-pad set-to 64)) (aset ecs-grid 19 (string-pad actual-msg 64)) (aset ecs-grid 20 (string-pad ahead-msg 64)) (aset ecs-grid 21 (make-string 64 32)) (aset ecs-grid 22 (make-string 64 32)) (sdl_draw_frame) (++ done) (setf slp (// (- next (bad-ticks)) hz)) (++ ahead slp) (sleep-for slp) finally (aset ecs-grid 18 (string-pad (@f " fps _actual_ %f" (// (* done hz) (- (bad-ticks) beg))) 64)) (sdl_draw_frame) (sleep-for 8) (sdl_draw_quit))) (defun ecs-interface-init () (bad-mode-settings) (set-face-attribute 'cursor nil :background "#326496" :foreground 'unspecified) (setq mode-line-format nil) (bad-alpha-4) (discard-input) (read-event nil nil 0.1) (set-frame-position nil 0 0) (set-frame-width nil 1 nil t) (set-frame-height nil 1 nil t)) (defun ecs-draw-triangles () (cl-loop for tri in ecs-triangles do (pcase-let* ((`[[ ,x0 ,y0 ,z0 ] [ ,x1 ,y1 ,z1 ] [ ,x2 ,y2 ,z2 ]] tri) (c0 [ .48 .56 1.0 ]) (c1 [ .24 .48 .96 ]) (c2 [ .16 .32 .88 ]) (`[ ,r0 ,g0 ,b0 ] c0) (`[ ,r1 ,g1 ,b1 ] c1) (`[ ,r2 ,g2 ,b2 ] c2)) (sdl_draw_triangle (* 1.0 x0) (* 1.0 y0) (* 1.0 z0) (* 1.0 x1) (* 1.0 y1) (* 1.0 z1) (* 1.0 x2) (* 1.0 y2) (* 1.0 z2) r0 g0 b0 r1 g1 b1 r2 g2 b2)) finally (setf ecs-triangles nil))) (defun ecs-draw-circles () (pcase-dolist (`[ ,x ,y ,rad ,red ,green ,blue ] ecs-circles) (sdl_draw_circle x y rad red green blue )) (setf ecs-circles nil)) (defun bad-sdl-solar () (ecs-init) (sdl_draw_init) (ecs-interface-init) (cl-loop with run = t with circles = t with triangles = t with hz = (bad-hz) with fps = 60 with delta = (// hz fps) with frames = (** 2 12) with beg = (bad-ticks) for fr from 0 below frames for next = (+ beg (* fr delta)) while run do (pcase (& (input-pending-p) (read-event)) ;; quit (?q (setf run nil)) (13 (kill-emacs)) (?Q (kill-emacs)) ;; modes (?0 (setf ecs-pause (! ecs-pause))) (?2 (setf ecs-overview (! ecs-overview))) (?3 (setf circles (! circles))) (?4 (setf triangles (! triangles))) (?5 (sdl_draw_grid_toggle)) ;; planets (?v (ecs-camera-look-at)) (?M (ecs-camera-look-at-mercury)) (?V (ecs-camera-look-at-venus )) (?e (ecs-camera-look-at-earth )) (?m (ecs-camera-look-at-mars )) (?J (ecs-camera-look-at-jupiter)) ;; coordinate system (?x (ecs-camera-look-at [1 0 0])) (?y (ecs-camera-look-at [0 1 0])) (?z (ecs-camera-look-at [0 0 1])) ;; you can (not) advance (?w (ecs-camera-move-forward)) (?s (ecs-camera-move-backward)) ;; roll (?u (ecs-camera-roll-left)) (?o (ecs-camera-roll-right)) ;; horizontal (?j (ecs-camera-move-left)) (?l (ecs-camera-move-right)) ;; vertical (?i (ecs-camera-move-up)) (?k (ecs-camera-move-down))) (sdl_draw_clear) (ecs-solar-update-and-render) (& circles (ecs-draw-circles)) (& triangles (ecs-draw-triangles)) (sleep-for (// (- next (bad-ticks)) hz)) (sdl_draw_frame) finally (sdl_draw_quit))) (defun bad-sdl-3d () (cl-loop with dist = (** 2 11) with beg = (** 2 2) with end = (** 2 7) with stp = (** 2 -5) with radius = (** 2 9) with diameter = (** 2 10) initially (ecs-init) (ecs-interface-init) (sdl_draw_init) (ecs-set-component-vector 'camera 'position 2 4 (- dist)) (ecs-camera-look-at) for i from beg to end by stp for tr = `[ ,(* 0.67 radius (cos i)) ,(* radius (sin i)) ,(- diameter) ] for W = (ecs-world-matrix 67 tr) do (sdl_draw_clear) (mapc (L (e) (push (ecs-screen-matrix e W) ecs-triangles)) ecs-cube) (ecs-draw-triangles) (sdl_draw_frame) (sleep-for 0.032) finally (sdl_draw_quit))) (<- 'bad-sdl3) ;;; bad-sdl3.el ends here