Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
omaLib SDL wrapper for FB, very perliminary alpha
#1
This is a set of routines I threw together because SDL routines have a lot of things that I don't need since I'm blitting to a 2d surface. It includes routines to create a window based on a configuration held in a file, load a masked bitmap from a file including changing the video mode to something usable, blit a bitmap, read any input from the keyboard, mouse, or joysticks, and do a couple other trivial things. Eventually, I want to take this lib and make it so you can choose between SDL and OpenGL, so I may add a #define for SDL_Surface ptr so I can keep that open.

This works best when popped into a .bi file and included into your program so you don't have to do anything else.

I'll have to do a LOT more work on it before it's useful to most people, but I'm posting the initial code here anyway, since it's a useful amalgamation of subs/functions for anyone who doesn't want to have to trudge through setting up APIs when they just want to get something coded.

Functions are:

declare sub omaSDL_Init()
Creates a window based on a configuration stored in config.cfg, an example of which is in Star Phalanx and Rambo vs. Kitty Cat. If there is no file, it will create a 640x480x16bit window. If there's a problem, it will exit gracefully, with an error message describing the problem.

declare sub omaQuit ()
This will exit SDL and FB.

declare sub omaGetScreenDimensions (byref w as integer,byref h as integer)
This will return the dimensions of the screen surface.

declare Sub omaPageFlip()
Will flip the page, and do all the things which need to be done when that happens. It currently won't clear the screen when you pageflip, for better or for worse.

declare function omaLoadMaskedGraphic(filename$) as sdl_Surface ptr
This function will load a BMP file from filename$ into a sdl_Surface ptr you declare. It will also apply masking to the colour magenta (255,255,0), and convert the bitmap to the ideal screen surface. If there's an error, it will quit everything gracefully with a text error message describing the problem.

Code:
Example:

dim mario as sdl_Surface ptr

mario = omaLoadMaskedGraphic("mario.bmp")

declare sub omaBlitImage(x as integer,y as integer,image as sdl_surface ptr)
There isn't much work involved in blitting with SDL, but this makes the job even easier.
Code:
Example:
omaBlitImage x, y, myBitmap
declare sub omaDebugEvent (Text$)
Add a debug event. This currently prints to the screen if DebugEvents are active

declare sub omaDebugEventsActive (status as integer)
Activates or deactivates DebugEvents. This will give extra information from inside each routine (which uses it), and will display any messages you've included in your own code using the omaDebugEvent sub.

declare FUNCTION omaMultiKey (x)
This is the UltimaInput function. Any key press, mouse movement/button press or joystick movement/button press will activate a certain multikey code, which can be polled for.

declare FUNCTION omagetSingleEvent as integer
Another function from UltimaInput, this will wait for any input event, then return that event. This is useful for configuration because there are too many code events to remember!!

Here's a sample program showing most of the elements in action:

Code:
'$include:'omalib.bi'

omaSDL_Init()

dim mario as SDL_Surface ptr
dim w, h
mario = omaLoadMaskedGraphic("mario.bmp")

while not omaMultiKey(27) 'while you don't press escape
  omaGetScreenDimensions w,h
  omaBlitImage int(rnd(1) * w), int(rnd(1) * h), mario
  omaPageFlip ()
wend

omaQuit ()

So without further talk, here it is.
Code:
'omaLib SDL wrapper library
'By Saint SJ



'$include: "SDL\SDL.bi"

'****WRAPPER FUNCTION DECLARATIONS
declare sub omaBlitImage(x as integer,y as integer,image as sdl_surface ptr)
declare Sub omaPageFlip()
declare sub omaSDL_Init()
declare FUNCTION omaMultiKey (x)
declare FUNCTION omagetSingleEvent as integer
declare sub omaDebugEvent (Text$)
declare sub omaDebugEventsActive (status as integer)
declare function omaLoadMaskedGraphic(filename$) as sdl_Surface ptr
declare sub omaQuit ()
declare sub omaGetScreenDimensions (byref w as integer,byref h as integer)


'******Pixel surface declarations
dim shared omaScreenSurface as SDL_Surface ptr

dim shared omaFramesPerSecond
dim shared omaFramePeriod
dim shared omaDebugEvents


sub omaQuit ()
   SDL_Quit()
   end
end sub



function omaLoadMaskedGraphic(filename as string) as sdl_Surface ptr
   dim LoadedFile as sdl_surface ptr
   dim ConvertedFile as sdl_surface ptr
   LoadedFile = SDL_LoadBMP(filename)
  
      if LoadedFile = 0 then
            omaDebugEvent Filename + ".bmp failed to load!"
            sleep
            omaQuit()
      end if
      
      SDL_SetColorKey LoadedFile, SDL_SrcColorKey, SDL_MapRGB(LoadedFile->Format, 255, 0, 255)
   ConvertedFile = SDL_DisplayFormat(LoadedFile)
   SDL_FreeSurface LoadedFile
   omaLoadMaskedGraphic = ConvertedFile
end function

Sub omaPageFlip()
       static omaOldTimer
      
       SDL_Flip omaScreenSurface
      
        SDL_PumpEvents
  
  
    If omaOldTimer <= sdl_GetTicks () Then
    
        omaOldTimer = sdl_GetTicks () + omaFramePeriod
    
    Else
        SDL_Delay (omaOldTimer - sdl_GetTicks)
    End If
    
End Sub

sub omaBlitImage(x as integer,y as integer,image as sdl_surface ptr)
   Dim Rectangle As SDL_Rect

         Dim Rectangle2 As SDL_Rect

        
         Rectangle.x = 0
         Rectangle.y = 0
         rectangle.w = image->w
         rectangle.h = image->h
         Rectangle2.x = x
         Rectangle2.y = y

         SDL_BlitSurface image, @rectangle, omaScreenSurface, @rectangle2
      
End Sub

sub omaSDL_Init ()
  
    dim x               AS STRING
    dim Xres            AS INTEGER
    dim Yres            AS INTEGER
    dim depth           AS INTEGER
    dim ScreenOptions   AS INTEGER
    dim fileno          AS INTEGER
    
'Before we open the screen, we have the simplest possible config.cfg reader.
'Later versions will use GetParameter$(x,y) to make config options on one line.
   fileno = FreeFile
  Open "config.cfg" For Input As #fileno
   While Not EOF(fileno)
      Input #fileno, x$
      x$ = LCase$(LTrim$(RTrim$(x$)))

      Select Case x$
         Case "xres"
            Input #fileno, x$
            XRES = Val(LCase$(LTrim$(RTrim$(x$))))
         Case "yres"
            Input #fileno, x$
            YRES = Val(LCase$(LTrim$(RTrim$(x$))))
         Case "depth"
            Input #fileno, x$
            depth = Val(LCase$(LTrim$(RTrim$(x$))))
         Case "sdl_hwsurface"
            screenoptions = screenoptions OR SDL_HWSURFACE
         Case "sdl_swsurface"
            screenoptions = screenoptions OR SDL_SWSURFACE      
         Case "sdl_doublebuf"
            screenoptions = screenoptions OR SDL_DOUBLEBUF
         Case "sdl_fullscreen"
            screenoptions = screenoptions OR SDL_FULLSCREEN
         Case "sdl_hwaccel"
            screenoptions = screenoptions OR SDL_HWACCEL
         Case "sdl_hwpalette"
            screenoptions = screenoptions OR SDL_HWPALETTE
      End Select
  
   'SDL_DOUBLEBUF )'or SDL_FULLSCREEN
   Wend
  Close #fileno
  if XRES = 0 and YRES = 0 then
     omaDebugEvent "There was no configuration file! Using default resolution!"
     XRES = 640
     YRES = 480
     Depth = 16
     ScreenOptions = SDL_SWSurface AND SDL_Doublebuf
  end if
  
  SDL_Init (SDL_INIT_VIDEO)
  
  omaScreenSurface = SDL_SetVideoMode(XRES, YRES, depth, screenoptions)


If omaScreenSurface = 0 Then
      omaDebugEvent "There was an error initilizing with SDL!"
      omaDebugEvent "Parameters"
      omaDebugEvent "Resolution: "+str$(XRES)+" x "+str$(YRES)
      omaDebugEvent "Depth:"+str$(depth)
      omaDebugEvent "Screen Options: "+str$(screenoptions)+" <- this is supposed to be a number"
      omaDebugEvent ""
      omaDebugEvent "Press any key to continue"
      SDL_Quit
      sleep
      END 1
  End If
  
omaFramesPerSecond = 30
omaFramePeriod = (1! / omaFramesPerSecond) * 1000!
  
end sub

FUNCTION omaMultiKey (x)
static keys(0 to 1024) as short
dim event as SDL_Event
dim num
dim a, b

'HIGHEST = 319 LOWEST = 0
'So, keyflag protocol:
'0-320 will be keyflags
'320-330 will be mouseFlags
'350-370 will be Joystick 1
'380-400 will be Joystick 2

while( SDL_PollEvent ( @event ) )                    
      select case event.type
         case SDL_KeyDOWN:
           keys(event.key.keysym.sym) = -1
         case SDL_KeyUP:
            keys(event.key.keysym.sym) = 0
         case SDL_MOUSEMOTION:
            '326,327,328,329 are mouse movement events
            keys(326) = (event.motion.xrel < 0)                
            keys(327) = (event.motion.xrel > 0)                  
            keys(328) = (event.motion.yrel < 0)
            keys(329) = (event.motion.yrel > 0)
         case SDL_MOUSEBUTTONDown:
         'SDL mouse buttons 321->325
         num = 320+event.button.button
         keys(num) = -1              
         case SDL_MOUSEBUTTONUP:
            num = 320+event.button.button
         keys(num) = 0
            
         case SDL_JOYAXISMOTION
            'axis events on
            '400 + (Joysticknumber * 100) + (axis * 2)
            'There won't be more than 5 axises on a joystick, so x00-x20 are
            'reserved...
            num = 400 + (event.jaxis.which * 100) + (event.jaxis.axis * 2)
            keys(num) = (event.jaxis.value < 0)                
            keys(num + 1) = (event.jaxis.value > 0)
          
      case SDL_JoyBallMotion
                      
            'jball
            'x20-x40 are Ball events. 20 is room for 5 balls.
            'There's something @£$£ up if 5 balls isn't enough for you.
            'num=420 + (event.jaxis.which * 100) + (which * 4)
            num = 420 + (event.jball.which * 100) + (event.jaxis.axis * 2)
            keys(num) = (event.jball.xrel < 0)                
            keys(num+1) = (event.jball.xrel > 0)                  
            keys(num+2) = (event.jball.yrel < 0)
            keys(num+3) = (event.jball.yrel > 0)

         case SDL_JoyHatMotion
            'jhat
            'x40-x80 are Hat events.40 is room for 5 hats.
            'If you need 5 hats, I suggest surgery.
            num = 440 + (event.jhat.which * 100) + (event.jhat.hat * 8)
            for a = 1 to 8
               keys(num + a) = 0
            next a
            keys(num + event.jhat.value) = -1
            
         case SDL_JoyButtonDown
            
            'button events are x80-x99
            num = 40 + (event.jbutton.which * 100) + (event.jbutton.button)
            keys(num) = -1
         case SDL_JoyButtonUp
            
            num = 40 + (event.jbutton.which * 100) + (event.jbutton.button)
            keys(num) = 0

         end select
    
      wend
   omaMultiKey = keys(x)

END FUNCTION

FUNCTION omaGetSingleEvent as integer
  
   dim event as SDL_Event
   dim num
   dim a, b
'This function will return 0 if no event is in the queue, otherwise it'll return
'the keyflag protocol number.

'So, keyflag protocol:
'0-320 will be keyflags
'321-329 will be mouseFlags
'400-500 will be Joystick 1
'500-600 will be Joystick 2
'600-700 will be Joystick 3
'700-800 will be Joystick 4
'900-1000 will be Joystick 5
while( SDL_PollEvent ( @event ) )                    
      select case event.type
         case SDL_KeyDOWN:
           omagetSingleEvent = event.key.keysym.sym
           exit function

         case SDL_MOUSEMOTION:
            '326,327,328,329 are mouse movement events
            if (event.motion.xrel < 0) then omagetSingleEvent = 326:exit function
            if (event.motion.xrel > 0) then omagetSingleEvent = 327:exit function
            if (event.motion.yrel < 0) then omagetSingleEvent = 328:exit function
            if (event.motion.yrel > 0) then omagetSingleEvent = 329:exit function

          
         case SDL_MOUSEBUTTONDown:
         'SDL mouse buttons 321->325
         omagetSingleEvent = 320+event.button.button
         exit function
            
         case SDL_JOYAXISMOTION
            num = 400 + (event.jaxis.which * 100) + (event.jaxis.axis * 2)
            omagetSingleEvent = num
            exit function
      case SDL_JoyBallMotion
                      
            'jball
            'x20-x40 are Ball events. 20 is room for 5 balls.
            'There's something @£$£ up if 5 balls isn't enough for you.
            'num=420 + (event.jaxis.which * 100) + (which * 4)
            num = 420 + (event.jball.which * 100) + (event.jaxis.axis * 2)
            if (event.jball.xrel < 0) then omagetSingleEvent = num                
            if (event.jball.xrel > 0) then omagetSingleEvent = num + 1
            if (event.jball.yrel < 0) then omagetSingleEvent = num + 2
            if (event.jball.yrel > 0) then omagetSingleEvent = num + 3
            
            exit function

         case SDL_JoyHatMotion
            'jhat
            'x40-x80 are Hat events.40 is room for 5 hats.
            'If you need 5 hats, I suggest surgery.
            num = 440 + (event.jhat.which * 100) + (event.jhat.hat * 8)

            omagetSingleEvent = num + event.jhat.value
            exit function            
         case SDL_JoyButtonDown
            
            'button events are x80-x99
            num = 40 + (event.jbutton.which * 100) + (event.jbutton.button)
            omagetSingleEvent = num
            exit function
         end select
    
   wend
   omaGetSingleEvent = 0
   exit function

END FUNCTION

SUB omaDebugEvent (Text$)
   if omaDebugEvents then print text$
end sub

sub omaDebugEventsActive(status as integer)
   omaDebugEvents = status
end sub

sub omaGetScreenDimensions (byref w as integer,byref h as integer)
    w = omaScreenSurface->w
    h = omaScreenSurface->h
end sub
Reply
#2
Did anyone find this at all useful?
Reply
#3
I've grabbed it and saved it away for future reference; not doing any SDL coding right now, but I'm sure it will come in handy when I try to learn it. Smile
Reply
#4
Nice!!!
y smiley is 24 bit.
[Image: anya2.jpg]

Genso's Junkyard:
http://rel.betterwebber.com/
Reply
#5
Not using SDL ATM.
Any wrapper making it easier is useful...
Antoni
Reply
#6
Me and nath are going to find this very useful.

Excellent work.
·~¹'°¨°'¹i|¡~æthérFòx~¡|i¹'°¨°'¹~·-
avinash.vora - http://www.avinashv.net
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)