-- -- SDL_WRAP.LUA -- local m= {} -- public, application namespace local n= {} -- private, C module namespace if not Gluahost( "sdl_module", n ) then -- load the dll/so/dylib return nil -- module not compiled end USES 'lib.bitlib' local bor= ASSUME( lib.bitlib.bor ) local borX= function(...) -- pass through 'nil' if table.getn(arg)>0 then return bor( unpack(arg) ) end end m._info= ASSUME( n._info ) -- Copy stuff from C module to our namespace: -- for k,v in n do -- if type(v)=="function" then local new_k= string.gsub( k, "^SDL_", "" ) m[new_k]= v else if k=="SDL_VERSION" or k=="SDL_LINKED_VERSION" then m[string.sub(k,5)]= v -- "SDL_" stripped away else m[k]= v -- "SDL_" remains (if any) end end end --== Plain functions ==-- -- Use of 'bor(unpack(arg))' allows the use of many arguments: -- -- evbuf= sdl.Init( SDL_INIT_AUDIO, SDL_INIT_VIDEO ) -- m.Init= function( ... ) local err= n.SDL_Init( borX(unpack(arg)) ) return (err==0 and n.SDL_Event()) or nil end m.Quit= function( ... ) return n.SDL_Quit( borX(unpack(arg)) ) end -- Surface functions: -- local function SurfNew( ud ) -- wrap userdata into a Lua object (with methods) return ud and m.Surface_new(ud) or nil end function m.FreeSurface(h) if h._ud then n.SDL_FreeSurface(h._ud); h._ud=nil end end function m.DisplayFormat(h) return SurfNew( n.SDL_DisplayFormat(h._ud) ) end function m.DisplayFormatAlpha(h) return SurfNew( n.SDL_DisplayFormatAlpha(h._ud) ) end function m.SetVideoMode( w, h, bpp, flags ) return SurfNew( n.SDL_SetVideoMode( w,h, bpp, flags ) ) end function m.LoadBMP(fn) return SurfNew( n.SDL_LoadBMP( fn ) ) end function m.CreateRGBSurface(...) return SurfNew( n.SDL_CreateRGBSurface( unpack(arg) ) ) end function m.CreateRGBSurfaceFrom(...) return SurfNew( n.SDL_CreateRGBSurfaceFrom( unpack(arg) ) ) end -- Surface object template -- -- Preparing this template separately (and not at every 'Surface_new' call) -- makes things a bit faster (skipping ASSUMEs at object creation). Also, it -- is good to have only one (constant) metatable instead of new ones for -- each object. -- local _surf_template= { SetSurface= ASSUME( m.SetSurface ), UpdateRect= ASSUME( m.UpdateRect ), UpdateRects= ASSUME( m.UpdateRects ), Flip= ASSUME( m.Flip ), SetColors= ASSUME( m.SetColors ), SetPalette= ASSUME( m.SetPalette ), FreeSurface= ASSUME( m.FreeSurface ), LoadBMP= function(h,fn) local _ud= n.SDL_LoadBMP(fn) -- try first if it succeeds if _ud then -- yes, it did h:FreeSurface() h._ud= _ud return true end end, SaveBMP= ASSUME( m.SaveBMP ), SetColorKey= ASSUME( m.SetColorKey ), SetAlpha= ASSUME( m.SetAlpha ), SetClipRect= ASSUME( m.SetClipRect ), GetClipRect= ASSUME( m.GetClipRect ), ConvertSurface= ASSUME( m.ConvertSurface ), FillRect= ASSUME( m.FillRect ), DisplayFormat= ASSUME( m.DisplayFormat ), DisplayFormatAlpha= ASSUME( m.DisplayFormatAlpha ), SetIcon= ASSUME( m.WM_SetIcon ), ToggleFullScreen= ASSUME( m.WM_ToggleFullScreen ), } local _surf_metatable= { __gc= function(h) h:FreeSurface() end, __index= function(h,k) return (k=="_ud") and (h._ud) or (h._ud)[k] end, __newindex= function(h,k,v) (h._ud)[k]= v end, } ----- -- [obj]= Surface_new( [bmp_filename] [bitmap_tbl] [raw_ud] ) -- m.Surface_new= function( p1 ) -- local obj= {} local p1_str= type(p1)=="string" and p1 local p1_tbl= type(p1)=="table" and p1 local p1_ud= type(p1)=="userdata" and p1 if p1_str then -- filename obj._ud= n.SDL_LoadBMP( p1_str ) elseif p1_ud then -- raw userdata obj._ud= p1_ud else obj._ud= n.SDL_GetVideoSurface() -- empty surface end if not obj._ud then return nil; end -- if p1_tbl then -- fill with a predefined pattern n.SDL_SetSurface( obj._ud, p1_tbl ) end -- Member functions: -- for k,v in _surf_template do obj[k]= v end setmetatable( obj, ASSUME(_surf_metatable) ) return obj end ----- -- Cursor functions: -- -- Only C code can assign GC to userdata, so we have to wrap it in a table -- (even if we didn't use any member functions). -- m.Cursor_new= function( data_tbl, mask_tbl, w,h, hotx,hoty ) -- local ud= data_tbl and n.SDL_CreateCursor( data_tbl, mask_tbl, w,h, hotx, hoty ) or n.SDL_GetCursor() if not ud then return nil end local obj= { _ud= ud } table.setmetatable( obj, { __gc= function(h) m.FreeCursor(h) end } ) return obj end m.GetCursor= m.Cursor_new m.FreeCursor= function(obj) if obj._ud then n.SDL_FreeCursor(obj._ud) end obj._ud= nil end -- This is an additional userdata->table conversion, mainly for debugging -- purposes. -- m.EventDump= function(e) -- tbl= EventDump( event_ud ) -- local type= e.type local ret= {} local tmp if type==n.SDL_ACTIVEEVENT then ret.active= e.active tmp= "ACTIVEEVENT" -- elseif type==n.SDL_KEYDOWN or type==n.SDL_KEYUP then ret.key= e.key tmp= (type==n.SDL_KEYDOWN) and "KEYDOWN" or "KEYUP" -- elseif type==n.SDL_MOUSEMOTION then ret.motion= e.motion tmp= "MOUSEMOTION" -- elseif type==n.SDL_MOUSEBUTTONDOWN or type==n.SDL_MOUSEBUTTONUP then ret.button= e.button tmp= "MOUSEBUTTON".. ((type==n.SDL_MOUSEBUTTONDOWN) and "DOWN" or "UP") -- elseif type==n.SDL_JOYAXISMOTION then ret.jaxis= e.jaxis tmp= "JOYAXISMOTION" -- elseif type==n.SDL_JOYBALLMOTION then ret.jball= e.jball tmp= "JOYBALLMOTION" -- elseif type==n.SDL_JOYHATMOTION then ret.jhatype= e.jhat tmp= "JOYHATMOTION" -- elseif type==n.SDL_JOYBUTTONDOWN or type==n.SDL_JOYBUTTONUP then ret.jbutton= e.jbutton tmp= "JOYBUTTON".. ((type==n.SDL_JOYBUTTONDOWN) and "DOWN" or "UP") -- elseif type==n.SDL_VIDEORESIZE then ret.resize= e.resize tmp= "VIDEORESIZE" -- elseif type==n.SDL_VIDEOEXPOSE then ret.expose= e.expose -- (nil) tmp= "VIDEOEXPOSE" -- elseif type==n.SDL_QUIT then ret.quitype= e.quit -- (nil) tmp= "QUIT" -- elseif type==n.SDL_USEREVENT then ret.user= e.user tmp= "USEREVENT" -- elseif type==n.SDL_SYSWMEVENT then ret.syswm= e.syswm tmp= "SYSWMEVENT" -- else error( "Unknown SDL event type: "..type.."!" ) end ret.type= tmp.." ("..type..")" return ret end --== Module cleanup ==-- setmetatable( m, { __gc= function(tbl) n.SDL_Quit() end } ) -- atexit --== SDL_GFX submodule ==-- function m.rotozoomSurface(...) return SurfNew( n.rotozoomSurface( unpack(arg) ) ) end function m.zoomSurface(...) return SurfNew( n.zoomSurface( unpack(arg) ) ) end m.pixel= ASSUME( n.gfx_pixel ) m.hline= ASSUME( n.gfx_hline ) m.vline= ASSUME( n.gfx_vline ) m.rect= ASSUME( n.gfx_rect ) m.box= ASSUME( n.gfx_box ) m.line= ASSUME( n.gfx_line ) -- aaline m.circle= ASSUME( n.gfx_circle ) -- aacircle, filledCircle m.ellipse= ASSUME( n.gfx_ellipse ) -- aaellipse, filledEllipse m.pie= ASSUME( n.gfx_pie ) m.trigon= ASSUME( n.gfx_trigon ) -- aatrigon, filledTrigon m.polygon= ASSUME( n.gfx_polygon ) -- aapolygon, filledPolygon m.bezier= ASSUME( n.gfx_bezier ) m.string= ASSUME( n.gfx_string ) --== Globalize ==-- local function my_globalize( sdl ) -- for k,v in sdl do -- copy to global namespace if type(v)=="function" then -- if string.find(k,"^Gfx") then -- GfxPixel.. (skip) elseif string.find(k,"RGBA") and k~="MapRGBA" then -- pixelRGBA, ... rawset( _G, k, v ) -- as is else rawset( _G, "SDL_"..k, v ) end else rawset( _G, k, v ) end end rawset( _G, "SDL_NORMAL", ASSUME(sdl.GFX_NORMAL) ) rawset( _G, "SDL_FILLED", ASSUME(sdl.GFX_FILLED) ) rawset( _G, "SDL_SMOOTH", ASSUME(sdl.GFX_SMOOTH) ) --.. end return m, my_globalize