;;;; 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))