Hello again,

I've been playing around with lispbuilder-SDL a bit over the holiday
weekend and started writing a simple jigsaw puzzle-like game.  I'm
very happy with what I have so far but I'm running into a bit of
slowness when doing direct pixel manipulation, specifically, rotating
images.

I've looked at rotozoom in the gfx package and I could not get it to
work (that's another issue altogether).  Rotating an image seemed like
such a simple thing anyway, so I wrote my own
likely-over-complicated-and-bug-ridden function to do it:

(defun rotate-surface(surf degrees)
  "rotates a surface 0, 90, 180, or 270 degrees"
  (let ((degrees (normalize-degrees degrees)))
    (if (= 0 degrees)
        ;; in the case of 0 degrees, just copy surface
        (copy-and-blit-surface surf)
        ;; else do rotation
        (let* ((w (surf-w surf))
               (h (surf-h surf))
               (new-w (if (or (= 90 degrees)
                              (= 270 degrees)) h w))
               (new-h (if (or (= 90 degrees)
                              (= 270 degrees)) w h))
               (new-surf (create-surface new-w new-h :surface surf))
               (new-x (case degrees
                        (90  #'(lambda (x y)(declare (ignore x))(+ (1-
new-w) (- 0 y))))
                        (180 #'(lambda (x y)(declare (ignore y))(+ (1-
new-w) (- 0 x))))
                        (270 #'(lambda (x y)(declare (ignore x))y))))
               (new-y (case degrees
                        (90  #'(lambda (x y)(declare (ignore y))x))
                        (180 #'(lambda (x y)(declare (ignore x))(+ (1-
new-h) (- 0 y))))
                        (270 #'(lambda (x y)(declare (ignore y))(+ (1-
new-h) (- 0 x)))))))
          (loop :for x :from 0 :to (1- w)
             :do (loop :for y :from 0 :to (1- h)
                    :do (let ((pixel (get-pixel :position (point x y)
                                                      :surface surf)))
                          (draw-pixel (funcall new-x x y)
                                      (funcall new-y x y) :surface new-surf
                                      :color (sdl:sdl_maprgb
(sdl:pixelformat sdl:*default-surface*)
                                                             (color-r pixel)
                                                             (color-g pixel)
                                                             (color-b pixel)))
                          #+nil(draw-point :position (point (funcall new-x x y)
                                                     (funcall new-y x y))
                                      :surface new-surf
                                      :color pixel))))
          new-surf))))

The function works but the pixel access is very slow.  It seems like I
need some way to directly access the surface memory, perhaps with a 2d
byte array?  Maybe this is not possible with CFFI, or maybe the
solution is right under my nose and I'm not seeing it.

Any suggestions?

Thanks,

Anthony
_______________________________________________
application-builder mailing list
application-builder@lispniks.com
http://www.lispniks.com/mailman/listinfo/application-builder

Reply via email to