Page 1 of 1

SDL and Pointers [solved]

Posted: Wed Aug 29, 2007 7:35 am
by GBeebe
Ok, I'm hoping that some of you know alot about SDL, and maybe some C.
As a learning exercise, I tried to convert LazyFoo's lesson 2 found here:
http://lazyfoo.net/SDL_tutorials/lesson02/index.php Download at the bottom.

Here's what I got:

Code: Select all

; /*This source code copyrighted by Lazy Foo' Productions (2004-2007) and may not be redestributed without written permission.*/

; //The headers
; #include "SDL/SDL.h"
    ; including a function not already included in PB - found this in pb forum.
    libsdl = OpenLibrary(#PB_Any, "libSDL.so") 
        Procedure SDL_BlitSurface_( src, srcrect, dst, dstrect)
            ProcedureReturn CallCFunctionFast(GetFunction(libsdl, "SDL_BlitSurface"), src, srcrect, dst, dstrect)
        EndProcedure
; #include <string>

; //The attributes of the screen
; const int SCREEN_WIDTH = 640;
    #SCREEN_WIDTH = 640
; const int SCREEN_HEIGHT = 480;
    #SCREEN_HEIGHT = 480
; const int SCREEN_BPP = 32;
    #SCREEN_BPP = 32
    
; //The surfaces that will be used
; SDL_Surface *message = NULL;
    message.SDL_Surface
; SDL_Surface *background = NULL;
    background.SDL_Surface
; SDL_Surface *screen = NULL;
    screen.SDL_Surface
    
    
; SDL_Surface *load_image( std::string filename ) 
Procedure.l load_image(filename.s)
; {
    ; //Temporary storage For the image that's loaded
    ; SDL_Surface* loadedImage = NULL;
        loadedimage.SDL_Surface
        
    ; //The optimized image that will be used
    ; SDL_Surface* optimizedImage = NULL;
        loadedimage.SDL_Surface
        
    ; //Load the image
    ; loadedImage = SDL_LoadBMP( filename.c_str() );
        *loadedimage = SDL_LoadBMP_RW_(SDL_RWFromFile_(@filename.s,"rb"),1)
        
        
    ; //If nothing went wrong in loading the image
    ; If( loadedImage != NULL )
        If loadedimage <> #Null
    
    ; {
        ; //Create an optimized image
        ; optimizedImage = SDL_DisplayFormat( loadedImage );
            *optimizedImage = SDL_DisplayFormat_(*loadedimage)
        
        ; //Free the old image
        ; SDL_FreeSurface( loadedImage );
            SDL_FreeSurface_(*loadedImage)
    ; }
        EndIf
    
    ; //Return the optimized image
    ; Return optimizedImage;
        ProcedureReturn *optimizedImage
; }
    EndProcedure
    
; void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
    Procedure apply_surface(x, y, *source.SDL_Surface, *destination.SDL_Surface)
; {
    ; //Make a temporary rectangle To hold the offsets
    ; SDL_Rect offset;
        offset.SDL_Rect
        
    ; //Give the offsets To the rectangle
    ; offset.x = x;
        offset\x = x
    ; offset.y = y;
        offset\y = y
        
    ; //Blit the surface
    ; SDL_BlitSurface( source, NULL, destination, &offset );
        sdl_blitsurface_(*source, #Null, *destination, *offset)
; }
    EndProcedure
    
; int main( int argc, char* args[] )
Procedure.l Main()
; {
    ; //Initialize all SDL subsystems
    ; If( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )         
    ; {
     ;   Return 1;    
    ; }
        If SDL_Init_(#SDL_INIT_EVERYTHING)
            ProcedureReturn 1
        EndIf
        
    
    ; //Set up the screen
    ; screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
        *screen = SDL_SetVideoMode_(#SCREEN_WIDTH, #SCREEN_HEIGHT, #SCREEN_BPP, #SDL_SWSURFACE)
        
    ; //If there was an error in setting up the screen
    ; If( screen == NULL )
    ; {
    ;     Return 1;    
    ; }
        If *screen <> #Null
            ProcedureReturn 1
        EndIf   
    
    ; //Set the window caption
    ; SDL_WM_SetCaption( "Hello World", NULL );
        SDL_WM_SetCaption_("Hello World", #Null)
        
    ; //Load the images
    ; message = load_image( "hello_world.bmp" );
        *message = load_image("hello_world.bmp")
    ; background = load_image( "background.bmp" );
        *background = load_image("background.bmp")
    ; //Apply the background To the screen
    ; apply_surface( 0, 0, background, screen );
        apply_surface(0, 0, *background, *screen)
    
    ; //Apply the message To the screen
    ; apply_surface( 180, 140, message, screen );
        apply_surface(180, 140, *message, *screen)
                
    ; //Update the screen
    ; If( SDL_Flip( screen ) == -1 )
    ; {
    ;    Return 1;    
    ; } 
        If SDL_Flip_(*screen)
            ProcedureReturn 1
        EndIf
        
    ; //Wait 2 seconds
    ; SDL_Delay( 2000 );
        SDL_Delay_(2000)
        
    ; //Free the surfaces
    ; SDL_FreeSurface( message );
        SDL_FreeSurface_(*message)
    ; SDL_FreeSurface( background );
        SDL_FreeSurface_(*background)
        
    ; //Quit SDL
    ; SDL_Quit();
        SDL_Quit_()
    
    ; Return 0;    
    ProcedureReturn 0
    
; }
EndProcedure

main()
It runs without errors, but the window just comes up and immediately goes away, even if i try to add a Delay(100000). I have the images in the same directory as the .pb file.

I guess my problem is, I don't know when to use the * and @ for pointers. Can anyone tell me where and what i'm doing wrong?

Thanks.

SDL_BlitSurface

Posted: Wed Aug 29, 2007 7:59 pm
by GBeebe
Ok, i got most of it working, except it seems that PB is missing the SDL_BlitSurface function. I tried to fix that:

libsdl = OpenLibrary(#PB_Any, "libSDL.so")
Procedure SDL_BlitSurface_( src, srcrect, dst, dstrect)
ProcedureReturn CallCFunctionFast(GetFunction(libsdl, "SDL_BlitSurface"), src, srcrect, dst, dstrect)
EndProcedure


;ImportC "/usr/lib/libSDL.so"
; sdl_blitsurface_(src.l, srcRect.l, dst.l, dstRect.l) As "SDL_BlitSurface"
; EndImport

The 1st one gives me an Invalid Memory Access and the 2nd one gives me a Linker error. Any ideas?

Posted: Wed Aug 29, 2007 10:00 pm
by flaith
Hi GBeebe

i modified your code, now i got a "pointer is null" with the SDL_Rect structure inside the "apply_surface" proc. Here is the code :

Code: Select all

#SCREEN_WIDTH = 640
#SCREEN_HEIGHT = 480
#SCREEN_BPP = 32

Global *message.SDL_Surface, *background.SDL_Surface, *screen.SDL_Surface, *optimizedImage.SDL_Surface

If OpenLibrary(0, "libSDL.so")
Else
  MessageRequester("Error","Can't Open SDL Library",0)
  End
EndIf

Procedure SDL_BlitSurface_(src, srcrect, dst, dstrect)
  ProcedureReturn CallCFunctionFast(GetFunction(0, "SDL_BlitSurface"), src, srcrect, dst, dstrect)
EndProcedure

; SDL_Surface *load_image( std::string filename )
Procedure.l load_image(filename.s)
Protected *loadedimage.SDL_Surface

  *loadedimage = SDL_LoadBMP_RW_(SDL_RWFromFile_(@filename,"rb"),1)

  If *loadedimage
    *optimizedImage = SDL_DisplayFormat_(*loadedimage)
    SDL_FreeSurface_(*loadedImage)
  Else
    MessageRequester("ERROR", "loadedImage = NULL")
    End
  EndIf
  
  ProcedureReturn *optimizedImage
EndProcedure
   
; void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
Procedure apply_surface(x, y, *source.SDL_Surface, *destination.SDL_Surface)
Protected *offset.SDL_Rect

  *offset\x = x
  *offset\y = y
  sdl_blitsurface_(*source, 0, *destination, @offset)
EndProcedure
   
; int main( int argc, char* args[] )
Procedure.l Main()

  If SDL_Init_(#SDL_INIT_EVERYTHING) >= 0

    *screen = SDL_SetVideoMode_(#SCREEN_WIDTH, #SCREEN_HEIGHT, #SCREEN_BPP, #SDL_SWSURFACE)

    If *screen
      SDL_WM_SetCaption_("Hello World", #Null)
  
      *message = load_image("hello_world.bmp")
      Debug "Screen Height.......... = "+Str(*message\h)
      *background = load_image("background.bmp")
      Debug "Screen Height.......... = "+Str(*background\h)
      Debug "clip rect Width........ = "+Str(*background\clip_rect\w)
      
      apply_surface(0, 0, *background, *screen)
      apply_surface(180, 140, *message, *screen)

      SDL_Flip_(*screen)

      SDL_Delay_(2000)

      SDL_FreeSurface_(*message)
      SDL_FreeSurface_(*background)
    Else
      MessageRequester("error","")
    EndIf
    SDL_Quit_()
  Else
    MessageRequester("ERROR","Can't initialise SDL")
  EndIf
  ProcedureReturn 0
EndProcedure

main()

ok

Posted: Wed Aug 29, 2007 11:17 pm
by GBeebe
Thank you for your help, but i'm back to where i was above:

Saved your code to the dir where the images are located,
Had to change *offset to just offset or i got a pointer is null error,

I'm back to the error on:

ProcedureReturn CallCFunctionFast(GetFunction(0, "SDL_BlitSurface"), src, srcrect, dst, dstrect)

Invalid memory access.

With this:

Procedure SDL_BlitSurface_(src, srcrect, dst, dstrect)
*gf_SDL_BlitSurface = GetFunction(0, "SDL_BlitSurface")
If *gf_SDL_BlitSurface
ProcedureReturn CallCFunctionFast(*gf_SDL_BlitSurface, src, srcrect, dst, dstrect)
Else
MessageRequester("Error", "Can't Call requested function", 0)
End
EndIf

EndProcedure

I get the message box, so i suppose the SDL_BlitSurface function isn't in libSDL.so

[solved]

Posted: Thu Aug 30, 2007 12:21 am
by GBeebe
changed

Code: Select all

Procedure SDL_BlitSurface_(src, srcrect, dst, dstrect)
  ProcedureReturn CallCFunctionFast(GetFunction(0, "SDL_BlitSurface"), src, srcrect, dst, dstrect)
EndProcedure 
to

Code: Select all

Procedure SDL_BlitSurface_(src, srcrect, dst, dstrect)
  ProcedureReturn CallCFunctionFast(GetFunction(0, "SDL_UpperBlit"), src, srcrect, dst, dstrect)
EndProcedure 
(used SDL_UpperBlit instead) and it works fine now... I wonder why so many code examples out there use SDL_BlitSurface, when it doesn't seem to exist.

Thanks for the hand, flaith.

Posted: Thu Aug 30, 2007 11:48 am
by flaith
you're welcome :wink:

Posted: Thu Sep 20, 2007 8:13 pm
by byo
Hi.

Where can I find that SDL include file?
Is it part of any lib?

Thanks.

Posted: Mon Sep 24, 2007 3:19 am
by GBeebe
/usr/lib/libSDL.so is its location. I'm sure you have it, comes with most (if not all) versions of linux.

Posted: Wed Sep 26, 2007 9:33 pm
by byo
Thanks.
I'm new to Linux. :wink: