Wednesday, March 11, 2009

SDL fun

So I've been playing a little bit with the SDL egg for chicken scheme. Most of the commands are pretty much the same except they replace underscores with hyphens, everything is lower case and camlHump notation is split up by hyphens. There were a few things that were different however, like in the case of SDL_pollEvent(SDL_Event* e), it follows standard scheme notation and uses a bang "(sdl-poll-event! event)". Overall it was easy to find what I wanted by looking at the SDL API docs from libsdl.org. For the functions I knew the name in C and could not find in the egg, I either loaded up my program in "csi" (the scheme interpreter) and guessed or opened the sdl.so that chicken created and searched for parts of the function name.

I can't say that writing this code in scheme is any easier than writing it in C, however I also haven't gotten to anything complex yet. Anyways here is the code I wrote.

(use sdl)

;; makes the screen to draw on
(define (make-screen width height)
(sdl-set-video-mode width
height 0
(+ SDL_HWSURFACE
SDL_HWPALETTE
SDL_DOUBLEBUF)))


;; makes a rectangle that is the size of the surface
(define (rect-from-surface surface)
(make-sdl-rect 0
0
(sdl-surface-width surface)
(sdl-surface-height surface)))


;; draws a surface onto another surface given an x and y
(define (draw-surface src dst x y)
(sdl-blit-surface src
(rect-from-surface src)
dst
(make-sdl-rect x y 0 0)))


;; handles a game event, returns false if the user wants to quit
(define (handle-event event)
(define event-type (sdl-event-type event))

(cond
((= event-type SDL_QUIT) #f)
((= event-type SDL_KEYDOWN) #f)
(else #t)))


;; starts up the demo and doesn't quit until a key is pressed or the window is closed
(define (run-demo)
(define ryu (img-load "ryu.png"))
(define event (make-sdl-event))
(define screen (make-screen 1024 768))

;; draws the ryu sprite and then flips it to the main screen
(define (draw screen)
(begin
(draw-surface ryu screen 200 100)
(sdl-flip screen)))

;; polls all events
(define (update)
(if (sdl-poll-event! event)
(if (handle-event event)
(update)
0)
(begin
(draw screen)
(update))))

;; start the main loop and clean up afterwards
(begin (update)
(sdl-free-surface ryu)
(sdl-quit)))

(run-demo)



I tried to make it a bit more functional than just throwing everything in a big (begin ) statement but since drawing graphics requires side effects its not an easy thing to do. If you can't follow the code, all it is doing is loading up a picture of Ryu (guy from street fighter) and drawing it to the screen, upon pressing a keyboard key or the window close button the program exits.

When making this application I did most of the things I wanted from "csi" then pasted them into scite for the things that worked. This interactive level of development was nice however it is probably not possible anymore the way I am doing things. Since the update loop is being called infinitively many times until the program is quiting it won't reach the top level for more input. I have a few ideas of getting around this but none of them are really ideal, the best one being an in-game console that would act like csi. Another more complicated idea is to have a client/server architecture and the game would evaluate the code sent to it in a que like fashion.

The last thing I tried was to compile the code. The chicken scheme compiler is "csc" and it works much in the same way as gcc does. To compile the code all I has to do was "csc sdlDemo.scm" and it spit out "sdlDemo" which is a binary executable with no dependency on chicken. I do love the compiler, most notably it knows what libraries you have used so you don't have to tell it what to link to. The program runs just fine and the executable is only 25k (a lot less than I expected). I haven't tried doing any performance tests on the program but from looking at it in "top" (tells cpu and memory usage of all running programs) it looks to be about what I expected.

So far, so good. Nothing really new came from scheme but I didn't have to do as much memory management as a C version, I didn't have to deal with pointers and I feel the code is more concise and easier to follow. So now my goals are to start some work with OpenGL, look into what OOP means in scheme and see how multiple source files work together.

No comments:

Post a Comment