Bitmaps in SDL...

Started by oofoe, August 10, 2007, 12:57:08 PM

Previous topic - Next topic

oofoe

Hi!



I'm transliterating the SDL code from this page into a NewLisp program:

http://lazyfoo.net/SDL_tutorials/lesson02/index.php">http://lazyfoo.net/SDL_tutorials/lesson02/index.php

I'm using NewLisp 9.1.1, SDL 1.2.8 and the SDL.lsp import file from http://www.turtle.dds.nl/newlisp/SDL.lsp">http://www.turtle.dds.nl/newlisp/SDL.lsp



However, for whatever reason, I can't get the bitmaps to load. Before, when I had a "home-grown" SDL/gl mix (ripped from the teapot example), I could see the top half of the "hello_world.bmp", but no background image.



Note that I supplied two functions which are defined with C macros in the SDL include files -- SDL_LoadBMP and SDL_BlitSurface.



Any thoughts?



Thanks!



Here's the code:


; l002.lsp
; jrlf 2007-08-10
; Surface loading and blitting.
; http://lazyfoo.net/SDL_tutorials/lesson02/index.php


; Load SDL library.
(load "SDL.lsp")

(context 'SDL)
(define (SDL_LoadBMP filename)
  (SDL:SDL_LoadBMP_RW (SDL:SDL_RWFromFile filename "rb") 1))
(define (SDL_BlitSurface src srcrect dst dstrect)
  (SDL_UpperBlit src srcrect dst dstrect))
(context 'MAIN)


; Screen attributes.
(constant 'screen_width 640)
(constant 'screen_height 480)
(constant 'screen_bpp 32)


(define (load_image filename)
  (let ((loaded (SDL:SDL_LoadBMP filename))
        (optimized nil))
    (if loaded (begin
                (setq optimized (SDL:SDL_DisplayFormat loaded))
                (SDL:SDL_FreeSurface loaded)
                ))
    optimized))


(define (apply_surface x y from to)
  (SDL:SDL_BlitSurface from "" to (pack "u u lu lu" x y 0 0))
)


(if (< (SDL:SDL_Init SDL:SDL_INIT_EVERYTHING) 0)
    (begin  (println "Could not initialize SDL!")  (exit)))
(if (< (setq screen (SDL:SDL_SetVideoMode screen_width screen_height
                                          screen_bpp SDL:SDL_SWSURFACE)) 0)
    (begin  (println "Couldn't initialize the screen!") (exit)))
(SDL:SDL_WM_SetCaption "Hello World" "")

(setq message (load_image "hello_world.bmp")
      background (load_image "background.bmp")
)
(apply_surface 0 0 background screen)
(apply_surface 180 140 message screen)

(if (< (SDL:SDL_Flip screen) 0)
    (begin
     (println "Couldn't flip screen!") (exit)))

(SDL:SDL_Delay 2000)

(SDL:SDL_FreeSurface message)
(SDL:SDL_FreeSurface background)
(SDL:SDL_Quit)

(exit)
Testing can show the presence of bugs, but not their absence.

oofoe

#1
Hi,



On further investigation, it seems that the bmp files *are* loading, but either not completely, or not blitting completely. This change to the apply_surface function should show pieces of the bitmaps:


(define (apply_surface x y from to)
  (SDL:SDL_BlitSurface from nil to (pack "u u lu lu" x y 200 200))
)


Next thing to try (I think) is to see if I can get the loaded image information. However, the image data is stored in a dynamically allocated struct of type SDL_Surface (see SDL_video.h). I'm not quite sure how to get the information... Perhaps some combination of address and unpack...



Thanks!
Testing can show the presence of bugs, but not their absence.

oofoe

#2
Hi,



Been playing with it more. Revised version that shows chunks of the image at the bottom of this post



Seems that the way to get the SDL_Surface width and height is just using unpack, viz:

(setq info (unpack "lu lu lu lu" testi))
(println "Image size is " (info 2) "x" (info 3))


So, I modified the code to do the blit with the appropriate image size (see below), but you still just see pieces of the image. Is this perhaps some sort of memory problem?



Thanks!


; l002.lsp
; jrlf 2007-08-10
; Surface loading and blitting.
; http://lazyfoo.net/SDL_tutorials/lesson02/index.php


; Load SDL library.
(load "SDL.lsp")

(context 'SDL)
(define (SDL_LoadBMP filename)
  (SDL:SDL_LoadBMP_RW (SDL:SDL_RWFromFile filename "rb") 1))
(define (SDL_BlitSurface src srcrect dst dstrect)
  (SDL_UpperBlit src srcrect dst dstrect))
(context 'MAIN)


; Screen attributes.
(constant 'screen_width 640)
(constant 'screen_height 480)
(constant 'screen_bpp 32)


(define (load_image filename)
  (let ((loaded (SDL:SDL_LoadBMP filename))
        (optimized nil))
    (if loaded (begin
                (setq optimized (SDL:SDL_DisplayFormat loaded))
                (SDL:SDL_FreeSurface loaded)
                ))
    optimized))


(define (apply_surface x y from to)
  (letn ((info (unpack "lu lu lu lu" from))
         (width (info 2))
         (height (info 3)))
        (println "Image size is " width "x" height)
        (SDL:SDL_BlitSurface from nil to (pack "u u lu lu" x y width height))
        )
  )


(if (< (SDL:SDL_Init SDL:SDL_INIT_EVERYTHING) 0)
    (begin  (println "Could not initialize SDL!")  (exit)))
(if (< (setq screen (SDL:SDL_SetVideoMode screen_width screen_height
                                          screen_bpp SDL:SDL_SWSURFACE)) 0)
    (begin  (println "Couldn't initialize the screen!") (exit)))
(SDL:SDL_WM_SetCaption "Hello World" "")

(setq message (load_image "hello_world.bmp")
      background (load_image "background.bmp")
)
(apply_surface 0 0 background screen)
(apply_surface 180 140 message screen)

(if (< (SDL:SDL_Flip screen) 0)
   (begin
    (println "Couldn't flip screen!") (exit)))

(SDL:SDL_Delay 2000)

(SDL:SDL_FreeSurface message)
(SDL:SDL_FreeSurface background)
(SDL:SDL_Quit)

(exit)
Testing can show the presence of bugs, but not their absence.

oofoe

#3
Hi,



This should fix the above problem code:



(define (apply_surface x y from to)
  (letn ((info (unpack "lu lu lu lu" from))
         (width (info 2))
         (height (info 3)))
        (println "Image size is " width "x" height)
        (SDL:SDL_BlitSurface
; from (pack "d d u u" 0 0 width height) ; This works, but too explicit.
         from 0 ; This works like the C++ examples.
to (pack "d d u u" x y width height))
        )
  )


According to the example code I was working from (see http://lazyfoo.net/SDL_tutorials/lesson02/index.php">http://lazyfoo.net/SDL_tutorials/lesson02/index.php), I should be able to leave the source rectangle specification blank (set to NULL). However, my attempt to set this parameter to NULL using either NIL or "" (as I've seen in other NewLisp code that uses external libraries) didn't work.



I got it to work finally by explicitly setting the rectangle (as you can see in the first commented-out line). Then I realized that perhaps a straight zero might get passed as a NULL properly.



I now have a lovely blitted image that looks like the final one in the tutorial.



If you are keeping track, here are some additions to the SDL library from http://www.turtle.dds.nl/newlisp/SDL.lsp">http://www.turtle.dds.nl/newlisp/SDL.lsp :



(context 'SDL)
(define (SDL_LoadBMP filename)
  (SDL_LoadBMP_RW (SDL_RWFromFile filename "rb") 1))
(define (SDL_SaveBMP surface filename)
  (SDL_SaveBMP_RW surface (SDL_RWFromFile filename "wb") 1))
(define (SDL_BlitSurface src srcrect dst dstrect)
  (SDL_UpperBlit src srcrect dst dstrect))
(context 'MAIN)


Having the SDL_SaveBMP is particularly nice, since you can save screenshots easily.



Jos'h
Testing can show the presence of bugs, but not their absence.

Ryon

#4
It's nice to see pjot's SDL.lsp getting more recognition (and see his GTK-server and GL4newLISP too!).



Has anyone used the SDL sound features under newLISP? I want to tackle some of this after I get back from vacation.
\"Give me a Kaypro 64 and a dial tone, and I can do anything!\"

oofoe

#5
Hi,



If you do a search for SDL on this message board, there's a reference to someone's project using the SDL_mixer, including a music file player. Unfortunately, the site seems to be down, but you might be able to find it in the Google or Wayback Machine cache.



The following is a little load file for using the SDL_image functionality in your SDL program. SDL_image adds loading support for a number of major image formats (specifically png) to SDL. Just grab the SDL_image.dll and drop it in next to your SDL.dll and SDL.lsp.



The neatest thing about it is that instead of having to say something like "IMG:IMG_Load" in your program, you can just do an "IMG:Load". This makes the calls look a little different from their C usage, but (I feel) that it is much more elegant -- and easier to use.



; SDL_image.lsp
; jrlf 2007-08-12
; Library import for SDL_image 1.2.6.
; See http://www.libsdl.org/projects/SDL_image/.
; To be used in conjunction with SDL.lsp.

(context 'IMG)

# Determine which library to use first.
(if (= (last (sys-info)) 6)
(constant 'library "SDL_image.dll")
(constant 'library "????.so.0") ; I don't know what the Linux one is.
)
(define-macro (provide _symbol)
  (let ((truename (string "IMG_" _symbol)))
    (import library truename)
    (constant _symbol (eval (sym truename))))
  )

; Functions.
(provide LoadTyped_RW)
(provide Load)
(provide Load_RW)

(provide isBMP)
(provide isGIF)
(provide isJPG)
(provide isLBM)
(provide isPCX)
(provide isPNG)
(provide isPNM)
(provide isTIF)
(provide isXCF)
(provide isXPM)
(provide isXV)

; XXX Not including individual loading functions for simplicity.

; It is possible that these won't work right. Need to check.
(constant 'SetError SDL:SDL_SetError)
(constant 'GetError SDL:SDL_GetError)

(context 'MAIN)


Is there a better place to upload code like this? I don't have a personal website at the moment that allows for file uploads.
Testing can show the presence of bugs, but not their absence.

cormullion

#6
you could add your contributions to the newLISP fan club wiki or even to NewLISP on Noodles wiki:



http://alh.net/newlisp/wiki/">//http://alh.net/newlisp/wiki/



http://newlisp-on-noodles.org/wiki/index.php/NewLISP_on_Noodles">//http://newlisp-on-noodles.org/wiki/index.php/NewLISP_on_Noodles



Although I've noticed that my additions to the newlisp wiki seem to get lost occasionally... yesterday's addition appears to have disappeared today.

Ryon

#7
...my additions to the newlisp wiki seem to get lost occasionally... yesterday's addition appears to have disappeared today.
Sorry! I'll look into it right away.

---
\"Give me a Kaypro 64 and a dial tone, and I can do anything!\"

camperman

#8
Quote
If you do a search for SDL on this message board, there's a reference to someone's project using the SDL_mixer, including a music file player. Unfortunately, the site seems to be down, but you might be able to find it in the Google or Wayback Machine cache.


That would be mine - it's up again at http://www.77000rpm.com/newlisp/">http://www.77000rpm.com/newlisp/

pjot

#9
This is cool stuff, thanks!



Peter

camperman

#10
No problem! Work and personal stuff have got in the way of my newlisp learning curve for a year or so now (as you can probably tell from the timestamp in the mixer project sources) but I'm getting back into it as of this week :)



I still really want to do a small game - perhaps a platform type - with newLisp and SDL so I'm watching oofoe's work with great interest.





/cm