;;; Sly ;;; Copyright (C) 2013, 2014 David Thompson ;;; ;;; This program is free software: you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation, either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see ;;; . ;;; Commentary: ;; ;; Window management. ;; ;;; Code: (define-module (sly window) #:use-module (ice-9 match) #:use-module (srfi srfi-9) #:use-module ((sdl2) #:prefix sdl2:) #:use-module ((sdl2 events) #:prefix sdl2:) #:use-module ((sdl2 video) #:prefix sdl2:) #:use-module (sly event) #:use-module (sly signal) #:use-module (sly math transform) #:use-module (sly math vector) #:export (make-window window? window-title window-resolution window-fullscreen? window-width window-height window-size window-projection with-window window-resize-hook window-close-hook init-window swap-window)) (define-record-type (%make-window title resolution fullscreen?) window? (title window-title) (resolution window-resolution) (fullscreen? window-fullscreen?)) (define* (make-window #:optional #:key (title "Sly Window") (resolution (vector2 640 480)) (fullscreen? #f)) (%make-window title resolution fullscreen?)) (define window-resize-hook (make-hook 1)) (register-event-handler 'window-resize (lambda (e) (match (sdl2:window-event-vector e) ((width height) (run-hook window-resize-hook (vector2 width height)))))) (define-signal window-size (hook->signal window-resize-hook (vector2 0 0) identity)) (define-signal window-width (signal-map vx window-size)) (define-signal window-height (signal-map vy window-size)) (define-signal window-projection (signal-map (lambda (size) (if (or (zero? (vx size)) (zero? (vy size))) identity-transform (orthographic-projection 0 (vx size) 0 (vy size) -1 1))) window-size)) (define window-close-hook (make-hook)) (register-event-handler 'quit (lambda (e) (run-hook window-close-hook))) (define %sdl-window #f) (define %gl-context #f) (define (init-window) (set! %sdl-window (sdl2:make-window #:opengl? #t #:show? #t)) (sdl2:set-gl-attribute! 'context-major-version 3) (sdl2:set-gl-attribute! 'context-minor-version 2) (sdl2:set-gl-attribute! 'double-buffer 1) (sdl2:set-gl-attribute! 'depth-size 24) (set! %gl-context (sdl2:make-gl-context %sdl-window)) (sdl2:set-gl-swap-interval! 'vsync)) (define (open-window window) (sdl2:sdl-init) (init-window) (let ((res (window-resolution window))) (sdl2:set-window-title! %sdl-window (window-title window)) (sdl2:set-window-size! %sdl-window (map inexact->exact (list (vx res) (vy res)))) (sdl2:set-window-fullscreen! %sdl-window (window-fullscreen? window)) (sdl2:show-window! %sdl-window) (signal-set! window-size res))) (define (close-window) (sdl2:hide-window! %sdl-window) (sdl2:sdl-quit)) (define-syntax-rule (with-window window body ...) (dynamic-wind (lambda () (open-window window)) (lambda () body ...) close-window)) (define (swap-window) (sdl2:swap-gl-window %sdl-window))