;;;; png-pixels.lisp
(defpackage png-pixels (:use cl cl-user) (:nicknames pp))
(in-package png-pixels)
(defclass surface ()
((path :initarg :path :accessor path)
(pointer :initform nil :accessor pointer)))
(defmethod (setf %pixel) (vals (obj surface) row col) "
(setf (%pixel (surface row col)) (r g b a)) -> nil
"
(ffi:c-inline ((pointer obj) row col
(first vals) (second vals)
(third vals) (fourth vals))
(:pointer-void :int :int :int :int :int :int)
(values :int) "
SDL_Surface *sfc;
unsigned char *pixels;
int pixbytes;
sfc = (SDL_Surface *)#0;
pixels = (unsigned char *)sfc->pixels;
pixbytes = sfc->format->BytesPerPixel;
pixels[(#1 * sfc->pitch + pixbytes * #2) + 2] = #3; /*r*/
pixels[(#1 * sfc->pitch + pixbytes * #2) + 1] = #4; /*g*/
pixels[(#1 * sfc->pitch + pixbytes * #2) + 0] = #5; /*b*/
pixels[(#1 * sfc->pitch + pixbytes * #2) + 3] = #6; /*a*/
")
(values (%pixel obj row col)))
(defmethod %pixel ((obj surface) row col) "
(%pixel (surface row col)) -> (values r g b a)
Cast to numbers.
"
(ffi:c-inline ((pointer obj) row col) (:pointer-void :int :int)
(values :int :int :int :int) "
SDL_Surface *sfc;
unsigned char *pixels;
int pixbytes;
sfc = (SDL_Surface *)#0;
pixels = (unsigned char *)sfc->pixels;
pixbytes = sfc->format->BytesPerPixel;
@(return 0) = pixels[(#1 * sfc->pitch + pixbytes * #2) + 2]; /*r*/
@(return 1) = pixels[(#1 * sfc->pitch + pixbytes * #2) + 1]; /*g*/
@(return 2) = pixels[(#1 * sfc->pitch + pixbytes * #2) + 0]; /*b*/
@(return 3) = pixels[(#1 * sfc->pitch + pixbytes * #2) + 3]; /*a*/
"))
(defmethod %free ((obj surface))
(ffi:c-inline ((pointer obj)) (:pointer-void) nil
"SDL_FreeSurface((SDL_Surface *)#0);")
(setf (slot-value obj 'pointer) nil)
(values))
(defmethod %load ((obj surface))
(setf (pointer obj)
(ffi:with-cstring (npath (path obj))
(ffi:c-inline (npath) (:cstring) :pointer-void "
SDL_Surface *sfc;
sfc = IMG_Load(#0);
if (sfc == NULL) {
printf(\"Failed to load png to surface\\n\");
exit(1);
}
@(return 0)=sfc;
")))
(values))
(defmethod %save ((obj surface))
(ffi:with-cstring (npath (path obj))
(ffi:c-inline ((pointer obj) npath) (:pointer-void :cstring) nil "
int result;
result = IMG_SavePNG((SDL_Surface *)#0, #1);
if (result<0) {
printf(\"Failed to save surface as png\\n\");
exit(1);
}"))
(values))
(defun %start-sdl2 ()
(ffi:clines "
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
")
(ffi:c-inline () () nil "
if (SDL_Init(0) < 0) {
printf(\"SDL failed to init\\n\");
exit(1);
}
")
(values))
(defun %stop-sdl2 ()
(ffi:c-inline () () nil "
SDL_Quit();")
(values))