Bitmaps in SDL...

For the Compleat Fan
Locked
oofoe
Posts: 61
Joined: Wed Sep 28, 2005 7:13 pm
Contact:

Bitmaps in SDL...

Post by oofoe »

Hi!

I'm transliterating the SDL code from this page into a NewLisp program:
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

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:

Code: Select all

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

oofoe
Posts: 61
Joined: Wed Sep 28, 2005 7:13 pm
Contact:

More information...

Post by oofoe »

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:

Code: Select all

(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!

oofoe
Posts: 61
Joined: Wed Sep 28, 2005 7:13 pm
Contact:

OK, still more experiments...

Post by oofoe »

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:

Code: Select all

(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!

Code: Select all

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

oofoe
Posts: 61
Joined: Wed Sep 28, 2005 7:13 pm
Contact:

Solved! Sorta...

Post by oofoe »

Hi,

This should fix the above problem code:

Code: Select all

(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), 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 :

Code: Select all

(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

Ryon
Posts: 248
Joined: Thu Sep 26, 2002 12:57 am

Post by Ryon »

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.

oofoe
Posts: 61
Joined: Wed Sep 28, 2005 7:13 pm
Contact:

More fun with SDL...

Post by oofoe »

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.

Code: Select all

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

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

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

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

http://newlisp-on-noodles.org/wiki/inde ... 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
Posts: 248
Joined: Thu Sep 26, 2002 12:57 am

Post by Ryon »

Code: Select all

...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.
---

camperman
Posts: 12
Joined: Sat Jun 10, 2006 9:16 pm

Post by camperman »

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/

pjot
Posts: 733
Joined: Thu Feb 26, 2004 10:19 pm
Location: The Hague, The Netherlands
Contact:

Post by pjot »

This is cool stuff, thanks!

Peter

camperman
Posts: 12
Joined: Sat Jun 10, 2006 9:16 pm

Post by camperman »

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

Locked