OSDN Git Service

layers/screens.lisp: created render and getscreen functions
authorGiulio De Stasio <giuliodestasio98@gmail.com>
Sun, 11 Jun 2023 09:31:10 +0000 (11:31 +0200)
committerGiulio De Stasio <giuliodestasio98@gmail.com>
Sun, 11 Jun 2023 09:31:10 +0000 (11:31 +0200)
layers/screens.lisp
render/package.lisp
render/render.lisp
rulp.asd

index a251f93..1cccb83 100644 (file)
@@ -28,6 +28,9 @@
 (defgeneric height (s)
   (:documentation "returns the height of the screen, the optional plane provide a grid"))
 
+(defgeneric display (s)
+  (:documentation "display the screen by using the defined coordinates and size"))
+
 (defgeneric texture (s))
 (defgeneric surface (s))
 (defgeneric screen-source (s))
@@ -42,21 +45,21 @@ where the screen should be displayed"))
 ;; set into a grid, which will be provided by the something itself.
 (defclass screen ()
   ((coordinate :accessor coordinate
-              :initarg :coordinate
-              :initform '(0 . 0)
-              :documentation "the position of the object in the space, space dependent"
-              :type list)
+               :initarg :coordinate
+               :initform '(0 . 0)
+               :documentation "the position of the object in the space, space dependent"
+               :type list)
    (size :accessor size
-        :initarg :size
-        :initform '(50 . 50)
-        :documentation "the size of the object, by default 50x50, space dependent"
-        :type list)
+         :initarg :size
+         :initform '(50 . 50)
+         :documentation "the size of the object, by default 50x50, space dependent"
+         :type list)
    (texture :initform nil
-           :accessor texture)
+            :accessor texture)
    (rotation :accessor rotation)
    (surface :initform nil
-           :accessor surface)
-   (path :accessor image-path
+            :accessor surface)
+   (path :reader image-path
          :initarg :image
          :initform (merge-pathnames rulp.parameters:*rulp-share* "test.png"))
    (s-rect :initform nil
@@ -99,13 +102,12 @@ interact directly with this but use screen-destination instead")
 (defmethod (setf height) (value (s screen))
   (setf (cdr (slot-value s 'size)) value))
 
-;; FIXME: entities use size as a simple integer, change to make it work better
 (defmethod initialize-instance :after ((s screen) &rest args)
   (declare (ignore args))
-  (setf (surface s) (sdl2-image:load-image (slot-value s 'path)))
-  (setf (width s) (sdl2:surface-width (surface s))
-        (height s) (sdl2:surface-height (surface s)))
-  (setf (slot-value s 's-rect) (sdl2:make-rect 0 0 (width s) (height s))))
+  (setf (slot-value s 'texture) (rulp.render:load-texture (slot-value s 'path)))
+  (setf (width s) (rulp.render:texture-width (texture s)))
+  (setf (height s) (rulp.render:texture-height (texture s)))
+  )
 
 (defmethod screen-source ((s screen))
   "return the source rectangle, the portion of texture to display (standard all)"
@@ -129,6 +131,10 @@ interact directly with this but use screen-destination instead")
 ;;         ))
 ;;   )
 
+(defmethod render ((s screen) x y width height)
+  (render-texture nil `(,x ,y ,width ,height) (texture s))
+  )
+
 ;; FIXME: find a way to store rectangles to later use
 (defmethod screen-destination ((s screen) (p t))
   "without a plane of reference, a screen is just printed full size from the
@@ -141,3 +147,18 @@ top left of the window"
   (sdl2:destroy-texture (texture s))
   (when (surface s)
     (sdl2:free-surface (surface s))))
+
+;; Flyweight zone, screens should be accessed only from the function get screen
+(defparameter *screen-list* nil)
+
+(defun path-equal (value screen)
+  (equal value (image-path screen)))
+
+(defun get-screen (path)
+  "A flyweight for screens. Given a path this function return an existing
+texture or, if no other exists, create a new one and return it."
+  (if (member path *screen-list* :test #'path-equal)
+      (car (member path *screen-list* :test #'path-equal))
+      (car (push (make-instance 'screen :path image)
+                 *screen-list*))))
index 7fea389..5b6f7ca 100644 (file)
 
 (defpackage :rulp.render
   (:use :cl)
-  (:export *renderer* render-line render-text color))
+  (:export *renderer* ;; TODO: remove when api is done
+           color
+           render-line render-text render-texture
+           load-texture texture-width texture-height
+           intersect-point intersect-square
+           make-rectangle))
 
index c7e0075..f708040 100644 (file)
@@ -41,6 +41,9 @@ used by itself, the functions in this package will use it for you.")
   necessary without creating and destroying rectangles. Use this with
 the rectangle function.")
 
+(defun make-rectangle (x y width height)
+  (sdl2:make-rect x y width height))
+
 (defun move-rectangle (x y width height rectangle)
   "setup a rectangle and return it"
   (setf (sdl2:rect-x rectangle) x)
@@ -66,14 +69,29 @@ the rectangle function.")
   "These rectangles are cache used by render-texture to renderize without
   creating and destroying them every time")
 
-(defun render-texture (source-x source-y source-width source-height
-                       dest-x dest-y dest-width dest-height
+(defun render-texture (source-list
+                       destination-list
                        texture)
-  (move-rectangle source-x source-y source-width source-height (car *texture-cache-rectangles*))
-  (move-rectangle dest-x dest-y dest-width dest-height (cdr *texture-cache-rectangles*))
-  (sdl2:render-copy *renderer* texture
-                    (car *texture-cache-rectangles*)
+  "Given two list of four numbers (x y width height) or empty lists it render
+them on screen. When given an empty list it uses the whole source or destination
+to print the result. If source-list is nil then the whole texture is displayed,
+if destination-list is nil then the selected texture is displayed on the whole
+window or destination screen buffer."
+  (when source-list
+    (move-rectangle (nth 0 source-list) (nth 1 source-list)
+                    (nth 2 source-list) (nth 3 source-list)
+                    (car *texture-cache-rectangles*)))
+  (when destination-list
+    (move-rectangle (nth 0 destination-list) (nth 1 destination-list)
+                    (nth 2 destination-list) (nth 3 destination-list)
                     (cdr *texture-cache-rectangles*)))
+  (sdl2:render-copy *renderer* texture
+                    :source-rect (if source-list
+                                     (car *texture-cache-rectangles*)
+                                     nil)
+                    :dest-rect (if destination-list
+                                   (cdr *texture-cache-rectangles*)
+                                   nil)))
 
 ;; collision detection
 (defun intersect-square (source-x source-y source-width source-height
@@ -85,3 +103,18 @@ the rectangle function.")
 (defun intersect-point (source-x source-y source-width source-height
                         point-x point-y)
   (intersect-square source-x source-y source-width source-height point-x point-y 10 10))
+
+(defun load-texture (path)
+  (let* ((temporary-surface nil))
+    (setf temporary-surface (sdl2-image:load-image path))
+    (prog1
+        (sdl2:create-texture-from-surface *renderer* temporary-surface)
+      (sdl2:free-surface temporary-surface))
+    )
+  )
+
+(defun texture-width (texture)
+  (sdl2:texture-width texture))
+
+(defun texture-height (texture)
+  (sdl2:texture-height texture))
index bb928e7..682262b 100644 (file)
--- a/rulp.asd
+++ b/rulp.asd
   :entry-point "rulp.core:main"
   :depends-on ("sdl2" "sdl2-image" "sdl2-ttf" "alexandria" "clingon" "cl-json")
   :components ((:file "parameters")
+               (:module "render"
+                :serial t
+                :components ((:file "package")
+                             (:file "render")
+                             (:file "text-rendering")))
                (:module "layers"
                 :serial t
                 :depends-on ("parameters")
                              (:file "inputs")
                              (:file "grid")
                              (:file "view")))
-;               (:module "gui"
-;                :serial t
-;                :depends-on ("parameters")
-;                :components ((:file "package")
-;                             (:file "skeleton")))
                (:file "package" :depends-on ("graphics"))
                (:file "script" :depends-on ("graphics"))
                (:file "data" :depends-on ("package" "parameters"))