FBGfx#

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

FBGfx#

Post by vdecampo »

I have a project I am writing in C# where I thought it would be convenient to have the 2D Gfx capabilities of FB (which I know very well) rather than playing with native C#. To that end I have written a wrapper and DLL for C# which allows the use of most FB Gfx functions. Still in the works but if anyone has any interest in this I will post some source.

-Vince
chrowle
Posts: 47
Joined: Oct 21, 2013 23:32
Location: Alberta, Canada

Re: FBGfx#

Post by chrowle »

Hey there, you mind posting the source? I might be able to do something with it.
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: FBGfx#

Post by vdecampo »

FB DLL Source

Code: Select all

' FBGFX DLL Wrapper
'
#Include "fbgfx.bi"
#Include "crt.bi"

Using fb

Type RECT
   x  As Integer
   y  As Integer
   dx As Integer
   dy As Integer
End Type


Dim Shared As Double pi
Dim Shared As Double pi_180

Function _ScreenRes(dx As Integer, dy As Integer, depth As Integer, pages As Integer, flags As Integer) As Integer Export

   pi     = 3.1415926
   pi_180 = pi / 180

   Return ScreenRes(dx,dy,depth,pages,flags,0)

End Function

Function _ScreenSet(wpage As Integer, vpage As Integer) As Integer Export

   ScreenSet wpage, vpage
   Return 0

End Function

Function _SetWindowPos(x As Integer, y As Integer) As Integer Export

   ScreenControl(SET_WINDOW_POS,x,y)
   Return 0

End Function

Function _SetWindowTitle(title As Byte Ptr) As Integer Export
   Dim ttl As String * 255

   sprintf(ttl, title, 255)
   WindowTitle ttl
   Return 0

End Function

Function _GetWindowHwnd() As Integer Export
   Dim hWnd As Integer

   ScreenControl(GET_WINDOW_HANDLE,hWnd)
   Return hWnd

End Function

Function _Cls() As Integer Export

   Cls
   Return 0

End Function

Function _Window(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer Export

   Window Screen (x1,y1)-(x2,y2)
   Return 0

End Function

Function _ScreenLock() As Integer Export

   ScreenLock
   Return 0

End Function

Function _ScreenUnlock() As Integer Export

   ScreenUnLock
   Return 0

End Function

Function _PSet(dst As Any Ptr, x1 As Integer, y1 As Integer, clr As UInteger) As Integer Export

   PSet dst,(x1,y1),clr
   Return 0

End Function

Function _Line(dst As Any Ptr, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer, clr As UInteger) As Integer Export

   Line dst,(x1,y1)-(x2,y2),clr
   Return 0

End Function

Function _LineTo(dst As Any Ptr, x2 As Integer, y2 As Integer, clr As UInteger) As Integer Export

   Line dst,-(x2,y2),clr
   Return 0

End Function

Function _Box(dst As Any Ptr, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer, clr As UInteger) As Integer Export

   Line dst,(x1,y1)-(x2,y2),clr,B
   Return 0

End Function

Function _Block(dst As Any Ptr, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer, clr As UInteger) As Integer Export

   Line dst,(x1,y1)-(x2,y2),clr,BF
   Return 0

End Function

Function _Circle(dst As Any Ptr, x As Integer, y As Integer, radius As Integer, clr As UInteger) As Integer Export

   Circle dst,(x,y),radius,clr
   Return 0

End Function

Function _ImageCreate(dx As Integer, dy As Integer) As Any Ptr Export

   Return ImageCreate(dx,dy)

End Function

Function _ImageDestroy(himage As Any Ptr) As Integer Export

   ImageDestroy(himage)
   Return 0

End Function

Function _Bload(himage As Any Ptr, filename As Byte Ptr) As Integer Export
   Dim txt As String * 255

   sprintf(txt, filename, 255)
   Return BLoad(txt, himage)

End Function

Function _Put(dst As Any Ptr, x As Integer, y As Integer, himage As Any Ptr, mode As Integer) As Integer Export

   Select Case mode
      Case 0
         Put dst,(x,y),himage,PSet
      Case 1
         Put dst,(x,y),himage,PReset
      Case 2
         Put dst,(x,y),himage,Trans
      Case 3
         Put dst,(x,y),himage,And
      Case 4
         Put dst,(x,y),himage,Or
      Case 5
         Put dst,(x,y),himage,Xor
      Case 6
         Put dst,(x,y),himage,Alpha
   End Select

   Return 0

End Function

Function _PutFrame(dst As Any Ptr, x As Integer, y As Integer, himage As Any Ptr, src As RECT Ptr, mode As Integer) As Integer Export

   Select Case mode
      Case 0
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),PSet
      Case 1
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),PReset
      Case 2
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),Trans
      Case 3
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),And
      Case 4
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),Or
      Case 5
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),Xor
      Case 6
         Put dst,(x,y),himage,(src->x,src->y)-(src->dx,src->dy),Alpha
   End Select

   Return 0

End Function

Function _DrawString(dst As Any Ptr, x As Integer, y As Integer, text As Byte Ptr, clr As UInteger) As Integer Export
   Dim txt As String * 255

   sprintf(txt, text, 255)
   Draw String dst,(x,y),txt, clr
   Return 0

End Function

'Rotozoom for 32-bit FB.Image by Dr_D(Dave Stanley) and yetifoot(Simon Nash)
'
Function _RotoZoom(  dst As FB.IMAGE Ptr, _
                     src As Const FB.IMAGE Ptr, _
                     positx As Integer, _
                     posity As Integer, _
                     angle As Integer, _
                     zoomx As Single, _
                     zoomy As Single, _
                     transcol As UInteger, _
                     offsetx As Integer, _
                     offsety As Integer) As Integer Export

   Static As Integer mx, my, col, nx, ny
   Static As Single nxtc, nxts, nytc, nyts
   Static As Single tcdzx, tcdzy, tsdzx, tsdzy
   Static As Integer sw2, sh2, dw, dh
   Static As Single tc, ts, _mx, _my
   Static As UInteger Ptr dstptr, srcptr, odstptr
   Static As Integer xput, yput, startx, endx, starty, endy
   Static As Integer x(3), y(3), xa, xb, ya, yb, lx, ly
   Static As UByte Ptr srcbyteptr, dstbyteptr
   Static As Integer dstpitch, srcpitch, srcbpp, dstbpp, srcwidth, srcheight

   If zoomx = 0 Then Return 1
   If zoomy = 0 Then zoomy = zoomx
   If src   = 0 Then Return 1

   If dst = 0 Then
      dstptr = ScreenPtr
      odstptr = dstptr
      ScreenInfo dw,dh,,,dstpitch
   Else
      dstptr = Cast( UInteger Ptr, dst + 1 )
      odstptr = Cast( UInteger Ptr, dst + 1 )
      dw = dst->Width
      dh = dst->height
      dstbpp = dst->bpp
      dstpitch = dst->pitch
   End If

   srcptr     = Cast( UInteger Ptr, src + 1 )
   srcbyteptr = Cast( UByte Ptr, srcptr )
   dstbyteptr = Cast( UByte Ptr, dstptr )

   sw2 = src->Width\2
   sh2 = src->height\2
   srcbpp = src->bpp
   srcpitch = src->pitch
   srcwidth = src->Width
   srcheight = src->height

   tc = Cos( angle * pi_180 )
   ts = Sin( angle * pi_180 )
   tcdzx = tc/zoomx
   tcdzy = tc/zoomy
   tsdzx = ts/zoomx
   tsdzy = ts/zoomy

   xa = sw2 * tc * zoomx + sh2  * ts * zoomx
   ya = sh2 * tc * zoomy - sw2  * ts * zoomy

   xb = sh2 * ts * zoomx - sw2  * tc * zoomx
   yb = sw2 * ts * zoomy + sh2  * tc * zoomy

   Dim As Integer centerx = -(offsetx*(tc*zoomx) + offsety*(ts*zoomx)) + offsetx
   Dim As Integer centery = -(offsety*(tc*zoomy) - offsetx*(ts*zoomy)) + offsety

   x(0) = sw2-xa
   x(1) = sw2+xa
   x(2) = sw2-xb
   x(3) = sw2+xb
   y(0) = sh2-ya
   y(1) = sh2+ya
   y(2) = sh2-yb
   y(3) = sh2+yb

   For i As Integer = 0 To 3
      For j As Integer = i To 3
         If x(i)>=x(j) Then
            Swap x(i), x(j)
         End If
      Next
   Next
   
   startx = x(0)
   endx = x(3)

   For i As Integer = 0 To 3
      For j As Integer = i To 3
         If y(i)>=y(j) Then
            Swap y(i), y(j)
         End If
      Next
   Next
   
   starty = y(0)
   endy = y(3)

   positx-=sw2
   posity-=sh2
   positx+=centerx
   posity+=centery
   If posity+starty<0 Then starty = -posity
   If positx+startx<0 Then startx = -positx
   If posity+endy<0 Then endy = -posity
   If positx+endx<0 Then endx = -positx

   If positx+startx>(dw-1) Then startx = (dw-1)-positx
   If posity+starty>(dh-1) Then starty = (dh-1)-posity
   If positx+endx>(dw-1) Then endx = (dw-1)-positx
   If posity+endy>(dh-1) Then endy = (dh-1)-posity
   If startx = endx Or starty = endy Then Return 2

   xput = (startx + positx) * 4
   yput = starty + posity
   ny = starty - sh2
   nx = startx - sw2
   nxtc = (nx * tcdzx)
   nxts = (nx * tsdzx)
   nytc = (ny * tcdzy)
   nyts = (ny * tsdzy)
   dstptr += dstpitch * yput \ 4

   Dim As Integer y_draw_len = (endy - starty) + 1
   Dim As Integer x_draw_len = (endx - startx) + 1

   Asm
      mov edx, dword Ptr [y_draw_len]

      test edx, edx ' 0?
      jz y_end      ' nothing to do here

      fld dword Ptr[tcdzy]
      fld dword Ptr[tsdzy]
      fld dword Ptr [tcdzx]
      fld dword Ptr [tsdzx]

      y_inner:

      fld dword Ptr[nxtc]     'st(0) = nxtc, st(1) = tsdzx, st(2) = tcdzx, st(3) = tsdzy, st(4) = tcdzy
      fsub dword Ptr[nyts]    'nxtc-nyts
      fiadd dword Ptr[sw2]    'nxtc-nyts+sw2

      fld dword Ptr[nxts]     'st(0) = nxts, st(1) = tsdzx, st(2) = tcdzx, st(3) = tsdzy, st(4) = tcdzy
      fadd dword Ptr[nytc]    'nytc+nxts
      fiadd dword Ptr[sh2]    'nxts+nytc+sh2
      'fpu stack returns to: st(0) = tsdzx, st(1) = tcdzx, st(2) = tsdzy, st(3) = tcdzy

      mov ebx, [xput]
      Add ebx, [dstptr]

      mov ecx, dword Ptr [x_draw_len]

      test ecx, ecx ' 0?
      jz x_end      ' nothing to do here

      x_inner:

      fist dword Ptr [my] ' my = _my

      fld st(1)           ' mx = _mx
      fistp dword Ptr [mx]

      mov esi, dword Ptr [mx]         ' esi = mx
      mov edi, dword Ptr [my]         ' edi = my

      ' bounds checking
      test esi, esi       'mx<0?
      js no_draw
      'mov esi, 0

      test edi, edi
      'mov edi, 0
      js no_draw          'my<0?

      cmp esi, dword Ptr [srcwidth]   ' mx >= width?
      jge no_draw
      cmp edi, dword Ptr [srcheight]  ' my >= height?
      jge no_draw

      ' calculate position in src buffer
      mov eax, dword Ptr [srcbyteptr] ' eax = srcbyteptr
      imul edi, dword Ptr [srcpitch]  ' edi = my * srcpitch
      Add eax, edi
      Shl esi, 2
      ' eax becomes src pixel color
      mov eax, dword Ptr [eax+esi]
      cmp eax, [transcol]
      je no_draw

      ' draw pixel
      mov dword Ptr [ebx], eax
      no_draw:

      fld st(3)
      faddp st(2), st(0) ' _mx += tcdzx
      fadd st(0), st(2) ' _my += tsdzx

      ' increment the output pointer
      Add ebx, 4

      ' increment the x loop
      dec ecx
      jnz x_inner

      x_end:

      fstp dword Ptr [_my]
      fstp dword Ptr [_mx]

      'st(0) = tsdzx, st(1) = tcdzx, st(2) = tsdzy, st(3) = tcdzy
      'nytc += tcdzy
      fld dword Ptr[nytc]
      fadd st(0), st(4)
      fstp dword Ptr[nytc]

      'st(0) = tsdzx, st(1) = tcdzx, st(2) = tsdzy, st(3) = tcdzy
      'nyts+=tsdzy
      fld dword Ptr[nyts]
      fadd st(0), st(3)
      fstp dword Ptr[nyts]

      'dstptr += dst->pitch
      mov eax, dword Ptr [dstpitch]
      Add dword Ptr [dstptr], eax

      dec edx
      jnz y_inner

      y_end:

      finit
   End Asm

   Return 0
   
End Function
C# Wrapper Class

Code: Select all

using System;
using System.Runtime.InteropServices;

namespace FBGFX
{
    class FbGfx
    {
        public enum RasterOp
        {
            PSet    = 0,
            PReset  = 1,
            Trans   = 2,
            And     = 3,
            Or      = 4,
            Xor     = 5,
            Alpha   = 6
        }

        public const int GFX_NULL               = -1; 
		public const int GFX_WINDOWED			= 0x00; 
		public const int GFX_FULLSCREEN			= 0x01; 
		public const int GFX_OPENGL				= 0x02; 
		public const int GFX_NO_SWITCH			= 0x04; 
		public const int GFX_NO_FRAME			= 0x08; 
		public const int GFX_SHAPED_WINDOW		= 0x10; 
		public const int GFX_ALWAYS_ON_TOP		= 0x20; 
		public const int GFX_ALPHA_PRIMITIVES	= 0x40;
        public const int GFX_HIGH_PRIORITY      = 0x80;

        [StructLayout(LayoutKind.Explicit)]
        public struct Rect
        {
            [FieldOffset(0)]
            public int left;
            [FieldOffset(4)]
            public int top;
            [FieldOffset(8)]
            public int right;
            [FieldOffset(12)]
            public int bottom;
        }   

        [DllImport("FBGFX32.DLL", EntryPoint = "_SCREENRES@20")]
        public static extern int ScreenRes(Int32 dx, Int32 dy, Int32 depth = 32, Int32 pages = 0, Int32 flags = 0);

        [DllImport("FBGFX32.DLL", EntryPoint = "_SETWINDOWTITLE@4")]
        public static extern int SetWindowTitle([MarshalAs(UnmanagedType.LPStr)]string title);

        [DllImport("FBGFX32.DLL", EntryPoint = "_DRAWSTRING@20")]
        public static extern int DrawString(IntPtr dst, Int32 x, Int32 y, [MarshalAs(UnmanagedType.LPStr)]string text, UInt32 clr = 0xFFFFFF);

        [DllImport("FBGFX32.DLL", EntryPoint = "_SCREENSET@8")]
        public static extern int ScreenSet(Int32 work_page, Int32 visible_page);

        [DllImport("FBGFX32.DLL", EntryPoint = "_SETWINDOWPOS@8")]
        public static extern int SetWindowPos(Int32 x, Int32 y);

        [DllImport("FBGFX32.DLL", EntryPoint = "_GETWINDOWHWND@0")]
        public static extern IntPtr GetWindowhWnd();

        [DllImport("FBGFX32.DLL", EntryPoint = "_CLS@0")]
        public static extern IntPtr Cls();
        
        [DllImport("FBGFX32.DLL", EntryPoint = "_WINDOW@16")]
        public static extern int Window(Int32 x, Int32 y, Int32 dx, Int32 dy);

        [DllImport("FBGFX32.DLL", EntryPoint = "_SCREENLOCK@0")]
        public static extern IntPtr ScreenLock();

        [DllImport("FBGFX32.DLL", EntryPoint = "_SCREENUNLOCK@0")]
        public static extern IntPtr ScreenUnlock();

        [DllImport("FBGFX32.DLL", EntryPoint = "_PSET@16")] 
        public static extern int PSet(IntPtr dst, Int32 x, Int32 y, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_LINE@24")]
        public static extern int Line(IntPtr dst, Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_LINETO@16")]
        public static extern int LineTo(IntPtr dst, Int32 x2, Int32 y2, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_BOX@24")]
        public static extern int Box(IntPtr dst, Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_BLOCK@24")]
        public static extern int Block(IntPtr dst, Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_CIRCLE@20")]
        public static extern int Circle(IntPtr dst, Int32 x, Int32 y, Int32 radius, UInt32 clr);

        [DllImport("FBGFX32.DLL", EntryPoint = "_IMAGECREATE@8")]
        public static extern IntPtr ImageCreate(Int32 dx, Int32 dy);

        [DllImport("FBGFX32.DLL", EntryPoint = "_IMAGEDESTROY@4")]
        public static extern int ImageDestroy(IntPtr hImage);

        [DllImport("FBGFX32.DLL", EntryPoint = "_BLOAD@8")]
        public static extern int Bload(IntPtr hImage, [MarshalAs(UnmanagedType.LPStr)]string filename);
        
        [DllImport("FBGFX32.DLL", EntryPoint = "_PUT@20")]
        public static extern int Put(IntPtr dst, Int32 x, Int32 y, IntPtr hImage, RasterOp mode=0);

        [DllImport("FBGFX32.DLL", EntryPoint = "_PUTFRAME@24")]
        public static extern int PutFrame(IntPtr dst, Int32 x, Int32 y, IntPtr hImage, [MarshalAs(UnmanagedType.Struct)] out Rect src, RasterOp mode = 0);

        [DllImport("FBGFX32.DLL", EntryPoint = "_ROTOZOOM@40")]
        public static extern int RotoZoom(  IntPtr dst,
                                            IntPtr src, 
                                            Int32  positx,
                                            Int32  posity, 
                                            Int32  angle, 
                                            Single zoomx,
                                            Single zoomy, 
                                            UInt32 transcol, 
                                            Int32  offsetx,
                                            Int32  offsety);

    }

}
Enjoy.

-Vince
chrowle
Posts: 47
Joined: Oct 21, 2013 23:32
Location: Alberta, Canada

Re: FBGfx#

Post by chrowle »

Mind if I use the dll and make a C/C++ wrapper?
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: FBGfx#

Post by vdecampo »

I officially release my source under LGPL.
chrowle
Posts: 47
Joined: Oct 21, 2013 23:32
Location: Alberta, Canada

Re: FBGfx#

Post by chrowle »

Okey doke.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Re: FBGfx#

Post by anonymous1337 »

I think this is cool. Just an FYI, you can now script in C# using Chocolatey and ScriptCS. A syntax package exists for Sublime Text.
Post Reply