Qbasicnews.com

Full Version: Using SDL to use a Bitmap from memory.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
In my program, I have a varaible:

DIM variable() as BYTE

This variable holds an entire bitmap file, so it's basically a bitmap in a variable. How can I get SDL to simply use this variable as a bitmap surface, rather than getting it from a file? My best bet seems to lie in SDL_RWops, however I can't seem to figure out how I should manipulate the variable I already have in order for it to be compatible with "SDL_RWFromMem". Thanks a lot in advance.
Simple. Use BLOAD. Tongue
I wanna BLOAD an image into a memory slot, then display it on screen when needed. I'm having trouble with the FB version of BLOAD. Any ideas?
Well, I can't use BLoad, because I'm getting the buffer from a
Custom Resource File(http://gpwiki.org/index.php/C:Custom_Resource_Files) rather than a standalone bitmap file. I've gotten to the point where the entire file it stored within a single array, now all I need to do is find a way to store it that will agree with SDL, and show it that what it wants is right in front of its face, rather than in another file.
I haven't messed with SDL much, but you might wanna look at this function.

Code:
declare function SDL_CreateRGBSurfaceFrom cdecl alias "SDL_CreateRGBSurfaceFrom" (byval pixels as any ptr, byval width as integer, byval height as integer, byval depth as integer, byval pitch as integer, byval Rmask as Uint32, byval Gmask as Uint32, byval Bmask as Uint32, byval Amask as Uint32) as SDL_Surface ptr

You should be able to do it something like...

Assuming Pixel_Data() is the array where you have stored the data.

Code:
Dim Image as sdl_surface ptr


Image = SDL_CreateRGBSurfaceFrom(@Pixel_Data(0), SDL_SWSURFACE, Width, Height, BPP, RMask, GMask, BMask, AMask)

Anonymous

Quote:I wanna BLOAD an image into a memory slot, then display it on screen when needed. I'm having trouble with the FB version of BLOAD. Any ideas?

Have you tested with multiple bmps? Could you post an example bmp that causes this error? Thanks.

There are some (non-standard) formats of .bmp that fb's bload won't handle, but it's rare. Also, what prog do you use to make the bmp? (If you made it anyways..)

Anonymous

I ported some c code from that site to fb, but I can't test it. Tell me if it works, please.

Code:
Function GetBufferFromResource(resourcefilename As String, resourcename As String, filesize As Integer )
  
  ''//Try To Open the resource file in question
  Dim As Integer ff = FreeFile
  If Open( resourcefilename, For Binary Access Read, As ff ) <> 0 Then
    
    ? "Error opening resource file"
    Sleep
    End 1
    
  End If
  
  
  ''//Read the first Int, which will tell us how many files are in this resource
  Dim As Integer numfiles
  Get #ff, , numfiles
  
  '' Get the pointers To the stored files
  Dim As Integer Ptr filestart = CAllocate( numfiles * Len( Integer ) )
  Get #ff, , *filestart, numfiles
  
  '' Loop through the files, looking For the file in question
  Dim As Integer filenamesize
  Dim As uByte Ptr buffer
  Dim As Integer i
  
  For i = 0 To numfiles - 1
  
    ''//Seek To the location
    Seek #ff, filestart[i] + 1
    ''//Get the filesize value
    Get #ff, , filesize
    ''//Get the size of the filename String
    Get #ff, , filenamesize
    ''//Size the buffer And Read the filename
    Dim As zString Ptr filename = CAllocate( filenamesize + 1 )
    Get #ff, , *filename, filenamesize
    ''//Remember To terminate the String properly!
    *(filename + filenamesize) = 0
    ''//Compare To the String we're looking for
    If UCase( *filename ) = resourcename Then
  
      ''//Get the contents of the file
      buffer = CAllocate( filesize )
      
      Get #ff, , *buffer, filesize
      
      Deallocate( filename )
  
      Exit For
      
    End If
    ''//Free the filename buffer
    Deallocate( filename )
  
  Next
  
  ''//Release memory
  Deallocate( filestart )
  
  ''//Close the resource file!
  Close #ff
  
  ''//Did we find the file within the resource that we were looking For?
  If ( buffer = 0 ) Then
  
    Print "Unable to find " & resourcename & " in the resource file!"
    Sleep
    End 1
  
  End If
  
  Return buffer

End Function


Function SDL_LoadBitmap( resourcefilename As String, bitmapfilename As String ) As SDL_Surface Ptr

''//Get the bitmap's buffer and size from the resource file
  Dim As Integer filesize
  
  Dim As uByte Ptr buffer = GetBufferFromResource( resourcefilename, bitmapfilename, filesize )
  
  ''//Load the buffer into a surface Using RWops
  Dim As SDL_RWops Ptr rw = SDL_RWFromMem( buffer, filesize )
  Dim As SDL_Surface Ptr temp = SDL_LoadBMP_RW( rw, 1 )
  
  ''//Release the bitmap buffer memory
  Deallocate( buffer )
  ''//Were we able To load the bitmap?
  
  If ( temp = 0 ) Then
  
    Print "Unable to load bitmap: " & SDL_GetError()
    Sleep
    End 1
    
  End If
  
  ''//Convert the image To optimal display format
  Dim As SDL_Surface Ptr image = SDL_DisplayFormat( temp )
  
  ''//Free the temporary surface
  SDL_FreeSurface( temp )
  
  ''//Return our loaded image
  Return image

End Function

Call it like: SDL_LoadBitmap( "myresourcefilename.whatever", "bmpwthintheresource.bmp" )

It returns an sdl surface pointer.
Cha0s, I'm trying to alter your code so that it works with my filetype, which I think is pretty much done, since ever variable is extracted perfectly fine, however, FB hates something about this line
Code:
Get #ff, , *filesize

Which causes it to deploy that stupid parachute. When I change "filesize" from a pointer to a regular variable for testing purposes, it works just fine, however, the "buffer" variable apparently returns zero afterwards, as it says the file wasn't found, even though I have evidence of it passing the "If UCase( *filename ) = resourcename Then" test.

Here is the code that I was originally working with.
Code:
SUB GetFromResource(resname$, file$, buffer() as BYTE)

OPEN resname$ for INPUT as #1

    DIM files as integer
    DIM headersize as integer
    DIM filechars as Integer
    DIM nameoffile$
    DIM filesize as integer
    DIM char as STRING * 1
    DIM filenum as integer
    
    GET #1, 1, headersize
    GET #1, 5, files
  
    REDIM startpoints(files)
   'Get each of the individual "start points".  

    FOR I = 1 to files
        GET #1, 5 + (I*4), startpoints(I)
        PRINT startpoints(I)        
    NEXT
    
    found = 0

   'Go through each file and find the one being looked for.
   'Once found, bail out.
    
    FOR A = 1 to files        
        GET #1,startpoints(A)+4,filechars

        FOR AA = 1 to filechars
            GET #1, startpoints(A)+7+AA, char
            nameoffile$ = nameoffile$+char            
        NEXT                
        IF nameoffile$ = file$ THEN
            found = 1
            filenum = A
            EXIT FOR            
        END IF
        nameoffile$ = ""
    NEXT

    'Is the file there?

    IF found = 1 THEN
        
        GET #1, startpoints(filenum), filesize        
        REDIM buffer(filesize)
        GET #1, startpoints(filenum)+8+LEN(nameoffile$), buffer()    
        Print "Found!"

    END IF
    
    

CLOSE #1
END SUB

It looks a little messy, but the code works just fine. Is there a way to "translate" the result of the code to be compatible with the SDL functions from before?
Anystandard Windows bitmap of resolution 640x480 and 65000 colours. The BLOAD code is as follows:

Code:
LoadBMP "d:\data\image\bftm.bmp", 1
DrawBMP 1,0,0

sub LoadBMP (filename$, BMPHandle)
    BLOAD filename$, VARPTR(image(BMPHandle))
end sub

sub DrawBMP (byval BMPHandle as integer, locx, locy)
    PUT (locx,locy), varptr(image(BMPHandle))
end sub

Of course this works.
But should I do the following using the same subs:

Code:
LoadBMP "d:\data\image\bftm.bmp", 1
LoadBMP "d:\data\image\blah.bmp", 2
DrawBMP 1,0,0
DrawBMP 2,20,20

...only the last image is drawn. It seems the exact same memory space is being used. Could this be improved upon?

Anonymous

Sorry dude, I see the error.

this line:

Code:
Dim As SDL_RWops Ptr rw = SDL_RWFromMem( buffer, filesize )

change it to

Code:
Dim As SDL_RWops Ptr rw = SDL_RWFromMem( buffer, varptr( filesize ) )

=)
Pages: 1 2