Announcement

Collapse
No announcement yet.

Would this be a useful addon for PB ?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Brice Manuel
    replied
    The problem appears when you want to use different ways of drawing the sprite. For example the docs (for the nameless Basic compiler) say that certain draw modes for sprites should store images in video memory and other modes in system memory.
    For specifics, the unnamed language is using DirectDraw for 2D. It uses a deprecated (but still supported and widely compatible) method of doing 2D.

    This is because things alpha-blending are not supported by DirectDraw and must be handled by the CPU and not the GPU. Hence they must be loaded into system memory.

    If we are talking about the same product, it actually uses the open-source 2D engine CD2X.

    Now when I store the sprites in system memory, rather than video memory, this is the frame rates I get:

    200 sprites - 6 FPS
    500 sprites - 2 FPS
    1000 sprites - barely 1 FPS
    That is a pretty normal since you are using the CPU instead of the GPU, especially "normal" if you are using a celery processor.

    Has anyone worked with DirectX ?
    Extensively, especially during my time at MicroProse and Shadow Realms 3D and NeXtGeN 3D.

    Why would DirectX (or at least the "nameless compiler") limit the drawing modes for sprites for some draw modes ?
    In this particular situation, it is a limit of DirectDraw. DirectDraw is still useful for 2D because it can run well on uber-budget systems like Eees.

    Modern 2D methods use the 3D capabilities of DirectX to emulate 2D. The drawback, is budget systems will often have some trouble running it.

    I have been working on a DirectX 9 based 2D engine for use with PB. Performance is awesome, but won't run on my Eee which is important to me to keep games Netbook-friendly.

    I know my sprite engine can not compare to hardware driven graphic engines, thats a given.
    Keep in mind that on Vista/7 DirectDraw is no longer supported and at runtime, the calls are translated to equivalent DX 9 3D methods, to take full advantage of hardware acceleration in 3D cards. So older DirectDraw based stuff will be much faster under Vista/7, but not necessarily the homespun alphablending, etc.

    I have to say that I am impressed with the speed of Powerbasic, since my sprite engine was written using PB 6.01.
    I agree 100%. I am using PB 8.04. If I could afford to upgrade I would for the OOP, but I can't, so I will keep plugging away with 8.04.
    Last edited by Brice Manuel; 9 Sep 2009, 10:30 PM. Reason: tags

    Leave a comment:


  • Chris Boss
    replied
    Doing some benchmarking using a "nameless" Basic compiler which supports DirectX and sprites.

    (done on my XP system, not Vista Home Premium)

    There is a big difference between doing stuff via hardware and software.

    When I create an app with 1000 penguin sprites (just one frame), the difference between storing a sprite (bitmap) in Video memory compared to System memory is like night and day.

    If the Sprite is stored in Video memory, I can get 24 FPS for 1000 sprites, which is amazing (both windowed mode or full screen). This is of course using DirectX.

    The problem appears when you want to use different ways of drawing the sprite. For example the docs (for the nameless Basic compiler) say that certain draw modes for sprites should store images in video memory and other modes in system memory.

    It appears the directX sprite drawing (at least in the nameless compiler) is limited to certain draw modes. For example to alphablend the sprite, flip the sprite and some other options the sprite should be stored in system memory.

    Now when I store the sprites in system memory, rather than video memory, this is the frame rates I get:

    200 sprites - 6 FPS
    500 sprites - 2 FPS
    1000 sprites - barely 1 FPS

    So when it comes to such sprite animation, the hardware is what does all the work. When you fall back to software based drawing (in System memory), its tough to get good frame rates.

    Mine can get (1000 sprites not anti-aliased)

    5.51 FPS

    Has anyone worked with DirectX ?

    Why would DirectX (or at least the "nameless compiler") limit the drawing modes for sprites for some draw modes ?

    For example the docs say the AlphaBlend should be done in system memory (won't benefit from the speed of the hardware).

    I know my sprite engine can not compare to hardware driven graphic engines, thats a given. The real question is how much speed can one get out of a software based sprite engine.

    I have to say that I am impressed with the speed of Powerbasic, since my sprite engine was written using PB 6.01. I am not sure if PB 9.0 would speed it, but maybe I ought to compile using it (bigger DLL though).
    Last edited by Chris Boss; 9 Sep 2009, 08:43 PM.

    Leave a comment:


  • Chris Boss
    replied
    I have add a few new commands which can access the sprites quicker (no need to search for their names, instead an index is used).

    It increases the speed by 15% to 20%.

    As far as the maximum number of sprites, at some point there becomes a bottleneck and only so many sprites can he handled. But for the sake of benchmarking, I increased the maximum number of sprites to 1000 (the release version, I haven't decided yet on the maximum).

    I created a couple sample projects using the penguin sprite again (from IceWalk) with different numbers of sprites and here are the frame rates:

    XP Home 2.5 ghz CPU, 768 meg Ram:

    200 sprites - 13.75 FPS
    500 sprites - 6.88 FPS
    1000 sprites - 4.2 FPS
    1000 sprites - 5.51 FPS (anti-alias off)

    Vista Home Premium, 2.2 ghz CPU, 2 gig Ram (rated 4.0 "Windows Experience Index"):

    200 sprites - 22 FPS
    500 sprites - 9.58 FPS
    1000 sprites - 5.86 FPS
    1000 sprites - 7.33 FPS (anti-alias off)
    Last edited by Chris Boss; 8 Sep 2009, 09:49 PM.

    Leave a comment:


  • Brice Manuel
    replied
    Chris: I spent much of the day in the E/R and I am beat. I will drop you an email sometime tomorrow.

    Leave a comment:


  • Chris Boss
    replied
    Brice,

    Please explain, I value your opinion ?

    To me its just an extra 5 KB to the DLL, but extra commands that will significantly the SDK portion of possible users (DDT has a much richer feature set when used with my sprite engine).

    Would two different versions be better then, one for DDT users, the other for SDK users ?

    Leave a comment:


  • Brice Manuel
    replied
    Originally posted by Chris Boss View Post
    Trust me, to get the most out of the sprite engine the extra PLUS command set is very valuable, especially the Frame commands.
    We will have to agree to disagree

    Leave a comment:


  • Chris Boss
    replied
    Brice,

    Trust me, to get the most out of the sprite engine the extra PLUS command set is very valuable, especially the Frame commands.

    The DLL is now 45 KB and believe this is it now , so there is no bloat by adding the extra commands. Also some commands benefit from simply exposing internal functions already in the sprite engine, so why now add them. For example the sprite engine uses 32 bit DIB's internally, so why not simply expose the function which creates them.

    Also I plan to market this to both DDT, as well SDK PB programmers and the extra commands are critical for its use with SDK style apps, since they don't have the benefit of the PB Graphic control.

    Also, one, even though using DDT, may have the desire to use the sprite engine with some other control types, so the extra commands will be useful there as well.

    Leave a comment:


  • Edwin Knoppert
    replied
    >The PLUS part of the tool will really benefit SDK style coders (ie. FireFly, PwrDev, Phoenix users).

    I had requests if EZGui worked with PwrDev and now this library may be handy for EZ-fokes..?

    I said that it should not be a problem but i never heard them back on this matter.
    Of course, EZGui is close to the same tasks as PwrDev, it's not a big deal i guess.

    But i am open for example projects, simple things/demos.
    If you have something i can prepare a project from, that's alright.
    You can send me trial versions and (simple demo) code to show these users if you like.

    PwrDev runs nearly everything directly so i don't think there is any/much rewriting required.

    Leave a comment:


  • Brice Manuel
    replied
    I added the following commands:

    EZ_DrawGradient (Draw a Gradient) (not based on API Gradient function)
    EZ_DrawBitmap (Draw a bitmap)
    EZ_DefDoEventCallback (define callback for frame timing feature)
    EZ_GetPTime (Get Precision timer)
    EZ_StartFrame (Start timing for a Frame)
    EZ_EndFrame (End timing for Frame and force fixed frame rate)
    EZ_GetFrameInfo (get info about last frame)
    EZ_DoEvents (special Do Events routine)
    EZ_UpdateClientAll (update entire client area)
    Is there any chance you would consider releasing a version that is strictly a sprite engine without these commands?
    Last edited by Brice Manuel; 6 Sep 2009, 02:03 PM. Reason: multiple typos

    Leave a comment:


  • Chris Boss
    replied
    Just about finished as far as the DLL coding.

    I added the following commands:

    EZ_DrawGradient (Draw a Gradient) (not based on API Gradient function)
    EZ_DrawBitmap (Draw a bitmap)
    EZ_DefDoEventCallback (define callback for frame timing feature)
    EZ_GetPTime (Get Precision timer)
    EZ_StartFrame (Start timing for a Frame)
    EZ_EndFrame (End timing for Frame and force fixed frame rate)
    EZ_GetFrameInfo (get info about last frame)
    EZ_DoEvents (special Do Events routine)
    EZ_UpdateClientAll (update entire client area)

    The sprite engine now has the precision timing frame engine from EZGUI 4.0 pro. Precision timers are not the same as TIMER. They are far more accurate.

    The gradient command is my own unique gradient command, which is much easier to use to draw gradients than the API and it can do 3D gradients for those nice 3D bars.

    The DrawBitmap command can stretch bitmaps to any size and uses the most efficient API's in Windows to do this.

    The PLUS part of this engine will be of benefit especially to the SDK style coders, for example those who user FireFly or PwrDev. You do not need a dedicated graphic control and not having access to the PB Graphic control (DDT) is no problem. The engine can conver any simple STATIC control into an advanced Graphic control , even with persistance.

    Want to see an SDK style example of using the sprite-plus engine ?



    Code:
    #COMPILE EXE
    #DIM ALL        '   This is helpful to prevent errors in coding
    #INCLUDE "win32api.inc"
    #INCLUDE "..\includes\ezsprite.inc"
    DECLARE SUB DrawGraphic(BYVAL N&)
    DECLARE SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
    ' ------------------------------------------------
    %FORM1_GRAPHIC1           = 110
    ' ------------------------------
    DECLARE SUB FORM1_Display()
    DECLARE SUB FORM1_Design(BYVAL hDlg&)
    GLOBAL hFORM1 AS LONG     ' Dialog Handle
    '
    DECLARE SUB DrawSprites()
    GLOBAL App_FixedFrame&
    GLOBAL App_GraphicCtrl&
    GLOBAL App_CurrentMsg&
    '
    '
    FUNCTION DVCallback(BYVAL TMLeft&) AS LONG
         EZ_DoEvents 5 TO App_CurrentMsg&
         IF TMLeft&>=1 THEN SLEEP TMLeft&
         FUNCTION=1
    END FUNCTION
    '
    '
    FUNCTION PBMAIN() AS LONG
        LOCAL RV&, Msg&
        FORM1_Display
        ' ---------------------------
        EZ_DefDoEventCallback CODEPTR(DVCallback)
        App_CurrentMsg&=0
        DO
            IF App_FixedFrame& THEN
                 EZ_StartFrame
            END IF
            SpriteDraw 0,0
            IF App_FixedFrame& THEN
                 EZ_EndFrame 15, 1
            ELSE
                 EZ_DoEvents 5 TO App_CurrentMsg&
            END IF
            IF App_CurrentMsg&=%WM_QUIT THEN EXIT DO
        LOOP
        ' ---------------------------
    END FUNCTION
    '
    %App_SizeW      = 800
    %App_SizeH      = 600
    %ButtonW        = 160
    %ButtonH        = 30
    '
    GLOBAL App_MaxX&, App_MaxY&, App_SWidth&, App_SHeight&
    GLOBAL App_MinX&, App_MinY&
    GLOBAL App_UpdateFlag&
    GLOBAL App_FixedFlag&
    GLOBAL App_AlphaFlag&
    GLOBAL App_FlipFlag&
    GLOBAL App_FrameNum&
    GLOBAL App_LastClick$
    GLOBAL App_Background&
    '
    %App_FormOffset     =    0
    %App_SpriteCount    =   24
    '
    '
    FUNCTION MyWndproc(BYVAL hWnd&, BYVAL Msg&, BYVAL wParam&, BYVAL lParam&) AS LONG
         SELECT CASE Msg&
              CASE %WM_CREATE
                   FORM1_Design hWnd&
                   MakeSprites
                   SpriteDraw 1,0
              CASE %WM_COMMAND
                   LOCAL ID&
                   ID&=LOWRD(wParam&)
                   SELECT CASE ID&
                        CASE 501 TO 509
                             IF HIWRD(wParam&)=%BN_CLICKED THEN
                                  SELECT CASE ID&-500
                                        CASE 1
                                            App_AlphaFlag&=1
                                        CASE 2
                                            App_AlphaFlag&=0
                                        CASE 3
                                            App_FlipFlag&=1
                                        CASE 4
                                            App_FlipFlag&=0
                                        CASE 5
                                            App_FrameNum&=1
                                        CASE 6
                                            App_FrameNum&=2
                                        CASE 7
                                            App_FixedFrame&=1
                                        CASE 8
                                            App_FixedFrame&=0
                                        CASE 9
                                             App_Background&=App_Background&+1
                                             IF App_Background&>7 THEN App_Background&=1
                                             EZ_UpdateBKGND App_GraphicCtrl&
                                        CASE ELSE
                                  END SELECT
                             END IF
                        CASE ELSE
                   END SELECT
              CASE %WM_DESTROY
                   PostQuitMessage 0
              CASE ELSE
         END SELECT
         FUNCTION=DefWindowProc(hWnd&, Msg&, wParam&, lParam&)
    END FUNCTION
    '
    '
    FUNCTION GetAppInstance() AS LONG
         STATIC RV&
         IF RV&=0 THEN RV&=GetModulehandle(BYVAL %NULL)
         FUNCTION=RV&
    END FUNCTION
    '
    '
    FUNCTION CreateW(BYVAL ExWS&, BYVAL MyClass$, BYVAL Caption$, BYVAL WS&, BYVAL X&, BYVAL Y&, BYVAL W&, BYVAL H&, BYVAL hParent&, BYVAL Menu_or_ID&) AS LONG
         FUNCTION=CreateWindowEx(ExWS&, BYVAL STRPTR(MyClass$), BYVAL STRPTR(Caption$), WS&, X&, Y&,W&, H&, hParent&, Menu_or_ID&,GetAppInstance, BYVAL %NULL)
    END FUNCTION
    '
    '
    SUB FORM1_Display()
         LOCAL T$, X&, Y&, W&, H&, WS&, EWS&, hDlg&
         LOCAL WN AS WNDCLASSEX, zName AS ASCIIZ*32
         WN.cbSize=SIZEOF(WN)
         WN.STYLE=%CS_HREDRAW OR %CS_VREDRAW OR %CS_DBLCLKS
         WN.lpfnWndProc=CODEPTR(MyWndproc)
         WN.cbClsExtra=0
         WN.cbWndExtra=0
         WN.hInstance=GetAppInstance
         WN.hIcon=%NULL
         WN.hCursor=LoadCursor(%NULL, BYVAL %IDC_ARROW)
         WN.hbrBackground=GetStockObject( %GRAY_BRUSH )
         WN.lpszMenuName=%NULL
         zName="MYClass"
         WN.lpszClassName=VARPTR(zName)
         WN.hIconSm=0
         RegisterClassEx WN
         T$ = "Sprite Demo"
         X& = 100
         Y& = 50
         W& =  %App_SizeW+%ButtonW+(GetSystemMetrics(%SM_CXEDGE)*2)
         H& =  %App_SizeH+(GetSystemMetrics(%SM_CYEDGE)*2)+GetSystemMetrics(%SM_CYCAPTION)
         WS& =%WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU OR %WS_VISIBLE OR %WS_CLIPCHILDREN
         EWS& =0
         hForm1=CreateW(EWS&,"MYClass", "Sprite Demo:", WS&, X&, Y&,W&, H&, %NULL, %NULL)
    END SUB
    '
    '
    SUB FORM1_Design(BYVAL hDlg&)
         LOCAL WS&, EWS&, hCtrl&, hTemp&, AW&, AH&, CText$
         App_Background&=1
         ' -----------------------------------------------
         ' [Graphic]
         WS& =  %SS_NOTIFY OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
         EWS& = 0
         App_GraphicCtrl&=CreateW(EWS&,"STATIC", "Label:", WS&,0, 0, %App_SizeW, %App_SizeH, hDlg&,%FORM1_GRAPHIC1)
         ' -----------------------------------------------
         LOCAL N&, T$
         FOR N&=1 TO 9
             SELECT CASE N&
                 CASE 1: T$="AlphaBlend ON"
                 CASE 2: T$="AlphaBlend OFF"
                 CASE 3: T$="Flip ON"
                 CASE 4: T$="Flip OFF"
                 CASE 5: T$="Use Sprite 1"
                 CASE 6: T$="Use Sprite 2"
                 CASE 7: T$="Speed 15 FPS"
                 CASE 8: T$="Speed unlimited"
                 CASE 9: T$="Change Background"
             END SELECT
             WS& =  %BS_PUSHBUTTON OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
             EWS& = 0
             hCtrl&=CreateW(EWS&,"BUTTON", T$, WS&,%App_SizeW+1, (N&-1)*%ButtonH, %ButtonW, %ButtonH, hDlg&,500+N&)
         NEXT N&
    END SUB
    '
    '
    SUB MyCustomControlDraw(BYVAL hWnd&, BYVAL hDC&, BYVAL X2&, BYVAL Y2&)
         LOCAL N&, F$, hBmp&, C&, C2&, C3&
         EZ_StartDCDraw hDC&
         N&=App_Background&
         SELECT CASE N&
              CASE 1 TO 5
                   F$=EXE.PATH$+"\graphics\bkgnd"+TRIM$(STR$(N&))+".bmp"
                   hBmp&=EZ_LoadBitmapFile(F$, X2&+1,Y2&+1)
                   EZ_BeginBmpBrush hBmp&
                   DeleteObject hBmp&
                   PatBlt hDC&, 0,0, X2&, Y2&, %PATCOPY
              CASE ELSE
                   C&=RGB(200,200,255)
                   C2&=RGB(128,128,255)
                   C3&=RGB(64,64,255)
                   IF N&=7 THEN C&=RGB(255,255,200):C2&=RGB(255,255,128):C3&=RGB(128,128,64)
                   EZ_BeginBrush C&
                   EZ_BeginPen C&,1
                   Rectangle hDC&, 0,0, X2&, Y2&
                   EZ_BeginBrush C2&
                   EZ_BeginPen C3&,1
                   ELLIPSE hDC&, 24,24, X2&-24, Y2&-24
                   EZ_BeginBrush -1    ' NULL brush
                   ELLIPSE hDC&, 20,20, X2&-20, Y2&-20
                   F$=EXE.PATH$+"\graphics\rose.bmp"
                   hBmp&=EZ_LoadBitmapFile(F$,0,0)    ' actual size
                   EZ_BeginBmpBrush hBmp&
                   EZ_BeginPen RGB(0,0,0), 2
                   ELLIPSE hDC&, 48,48, X2&-48, Y2&-48
                   DeleteObject hBmp&
         END SELECT
         EZ_EndDCDraw   ' automatically calls EZ_EndBrush and EZ_EndPen
    END SUB
    '
    '
    SUB MakeSprites()
        LOCAL SName$, N&, SNameAll$, P2$, hDC&, T$, hBmp&, hCtrl&, CW&, CH&, W&, H&, RegNum$, R AS RECT
        ' =========================
        ' Requires Registration code
        ' =========================
        EZ_InitSpriteBuffers %App_SpriteCount,-1,-1, $EZSPREGNUM
        GetClientRect App_GraphicCtrl&, R
        CW&=R.nRight-R.nLeft
        CH&=R.nBottom-R.nTop
        App_MaxX&=(CW&-1)+%App_FormOffset
        App_MaxY&=(CH&-1)+%App_FormOffset
        App_MinX&=0-%App_FormOffset
        App_MinY&=0-%App_FormOffset
        App_SWidth&=140
        App_SHeight&=140
        hBmp&=EZ_LoadBitmapFile(EXE.PATH$+"\graphics\ball3d.bmp" ,0,0)
        ' -------------------------------
        ' Prepare control for custom painting
        EZ_DefNextCustomPaint CODEPTR(MyCustomControlDraw)
        ' -------------------------------
        EZ_AttachSprites App_GraphicCtrl&
        ' -------------------------------
        FOR N&=1 TO %App_SpriteCount
            SName$="LOGO"+TRIM$(STR$(N&))
            IF SNameAll$="" THEN
                SNameAll$=SName$
            ELSE
                SNameAll$=SNameAll$+"|"+SName$
            END IF
            EZ_DefSpriteByPict SName$, hBmp&,3, -1, 50
        NEXT N&
        DeleteObject hBmp&
        EZ_AssignSprites App_GraphicCtrl&, SNameAll$
        EZ_SetSpritesEffect SNameAll$, 1,0
    END SUB
    '
    GLOBAL App_XY&()
    '
    FUNCTION GetX(BYVAL N&) AS LONG
        LOCAL X&
        X&=(N& MOD 8)+1
        IF App_XY&(N&,1)>=App_MaxX&-App_SWidth& THEN App_XY&(N&,3)=-1
        IF App_XY&(N&,1)<=App_MinX& THEN App_XY&(N&,3)=1
        X&=X&*App_XY&(N&,3)
        App_XY&(N&,1)=App_XY&(N&,1)+X&
        FUNCTION=App_XY&(N&,1)
    END FUNCTION
    '
    '
    FUNCTION GetY(BYVAL N&) AS LONG
        LOCAL Y&
        Y&=(N& MOD 10)+1
        IF App_XY&(N&,2)>=App_MaxY&-App_SHeight& THEN App_XY&(N&,4)=-1
        IF App_XY&(N&,2)<=App_MinY& THEN App_XY&(N&,4)=1
        Y&=Y&*App_XY&(N&,4)
        App_XY&(N&,2)=App_XY&(N&,2)+Y
        FUNCTION=App_XY&(N&,2)
    END FUNCTION
    '
    '
    SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
        LOCAL EF&, ToggleX&, ToggleY&
        LOCAL SName$, PW&, N&, T$
        STATIC FlipFlag&
        STATIC Count&, CT!
        STATIC TM!, FlipCT&, FrameOffset&
        IF Mode&=1 THEN
            App_FrameNum&=1
            FrameOffset&=0
            App_FlipFlag&=0
            App_AlphaFlag&=0
            Count&=0
            REDIM App_XY&(1 TO %App_SpriteCount, 1 TO 4)
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_MoveSprites SName$, N&,N&,0
                App_XY&(N&,1)=N&
                App_XY&(N&,2)=N&
                App_XY&(N&,3)=1
                App_XY&(N&,4)=1
                EZ_ShowSprites SName$,1
            NEXT N&
        ELSE
            IF FrameOffset&=0 THEN FrameOffset&=1 ELSE FrameOffset&=0
            IF Count&=0 THEN TM!=TIMER
            FlipCT&=FlipCT&+1
            IF FlipCT&>1 THEN
                 FlipFlag&=FlipFlag&+1
                 IF FlipFlag&>4 THEN FlipFlag&=1
                 FlipCT&=0
            END IF
            EF&=0
            IF App_AlphaFlag& THEN EF&=50
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_SetSpritesEffect SName$, EF&,0
                EZ_MoveSprites SName$, GetX(N&),GetY(N&),0
                IF App_FlipFlag& THEN
                    SELECT CASE FlipFlag&
                         CASE 1
                            EZ_SetSpritesFlip SName$, 0,0,0
                         CASE 2
                            EZ_SetSpritesFlip SName$, 1,0,0
                         CASE 3
                            EZ_SetSpritesFlip SName$, 1,1,0
                         CASE 4
                            EZ_SetSpritesFlip SName$, 0,1,0
                    END SELECT
                ELSE
                    EZ_SetSpritesFlip SName$, 0,0,0
                END IF
                IF App_FrameNum&=1 THEN
                    EZ_SetSpritesFrame SName$, 1,0,0
                ELSE
                    EZ_SetSpritesFrame SName$, 2 + FrameOffset&,0,0
                END IF
                IF App_UpdateFlag& THEN
                    EZ_UpdateClient App_GraphicCtrl&
                END IF
            NEXT N&
            IF App_UpdateFlag&=0 THEN
                EZ_UpdateClient App_GraphicCtrl&
            END IF
            Count&=Count&+1
            IF Count&>=100 THEN
                TM!=TIMER-TM!
                IF TM!<=0 THEN TM!=1
                TM!=INT((100/TM!)*100)/100
                T$="Sprite Demo:    "+STR$(%App_SpriteCount)+" Sprites (140 x 140 pixels) displaying at "+FORMAT$(TM!, "0000.00")+" Frames/sec"
                SetWindowText hForm1, BYVAL STRPTR(T$)
                Count&=0
            END IF
        END IF
    END SUB

    Leave a comment:


  • Chris Boss
    replied
    Some additional info:

    So far EZSpritePlus can convert the following window types to a Sprite ready window:

    - PB Graphic control (DDT)
    - PB Graphic window (DDT) (GRAPHIC WINDOW command used)
    (this may also apply to PBCC GRAPHIC WINDOW, but haven't tested it yet since I don't have PBCC)
    - LABEL control (DDT)
    - PICTURE control (DDT IMAGE control)
    - ICON control (DDT IMAGE control)

    SDK style window types:

    - STATIC (doesn't matter whether text based, bitmap or icon)
    - any static type custom window class you create, as long as you support WM_PRINTCLIENT should work

    If you would like me to test any custom window classes you currently are using, if you can send me an email with a simple DDT (or SDK) app that displays the control (control can be in a DLL if you prefer), I'll test it with my sprite engine to see if it works.

    Send emails to: [email protected]

    If you are curious about the software license that will be used with this product, you can download a draft of the software license (it may change slightly in final release version):
    http://cwsof.com/ezsplic.txt
    Last edited by Chris Boss; 3 Sep 2009, 02:01 PM.

    Leave a comment:


  • Chris Boss
    replied
    This is a real product soon to be released !

    For those interested, this is a real product soon to be released.

    I have named it (could change, but not likely):

    EZSpritePlus 1.0

    The Sprite command set contains the following commands:

    EZ_AttachSprites (make a control, PB Graphic, Static such a Picture or Label sprite ready)
    EZ_InitSpriteBuffers (Initialize and register sprite engine)
    EZ_FreeSprite (Free an existing sprite)
    EZ_SwapSpriteOrder (swap zorder between two sprites)
    EZ_AssignSprites (assign group of sprites to a control)
    EZ_MoveSprites (move a group of sprites)
    EZ_ShowSprites (show or hide a group of sprites)
    EZ_SetSpritesEffect (set alphablend effect for a group of sprites)
    EZ_SetSpritesFrame (set current frame for a group of sprites)
    EZ_SetSpritesFlip (set flip state for a group of sprites (vertical/horizontal))
    EZ_DefSpriteByPict (create a sprite using a Bitmap)
    EZ_UpdateClient (update sprite ready control to display changes)
    EZ_GetSpriteXY (get a sprite X,Y coordinates)
    EZ_GetSpriteWH (get a sprite width and height)
    EZ_GetSpriteFR (get a sprite current frame)
    EZ_GetSpriteST (get a sprite current state. ie. hidden/visible)
    EZ_TestSpriteColl (test for collisions of a sprite with other sprites)
    EZ_TestSpriteClick (test mouse position for click on which sprite)
    EZ_UpdateBKGND (update control background for sprite ready control - forces a redraw)
    EZ_CloneSprite (create a new sprite as a clone of another)

    The Plus command set (everything else other than sprite commands) :

    EZ_Create32BitDIB (Create a 32 Bit DIB Bitmap and get handle and pointer)
    EZ_GetBitmapSize (get width and height of a Bitmap)
    EZ_StartBitmapDraw (Start to draw on a Bitmap)
    EZ_EndBitmapDraw (End draw on to a Bitmap)
    EZ_StartDCDraw (Start draw on to a DC)
    EZ_EndDCDraw (End draw on to a DC)
    EZ_FreeBitmap (Free a Bitmap)
    EZ_DefStyles (Define current pen and brush styles)
    EZ_BeginBrush (Define current color brush)
    EZ_BeginBmpBrush (Define current brush as a bitmap brush)
    EZ_EndBrush (End use of current brush)
    EZ_BeginPen (Define current color pen)
    EZ_EndPen (End use of current pen)
    EZ_DefNextCustomPaint (Define a CustomPaint routine for next control made sprite ready)
    EZ_LoadBitmapFile (Load a Bitmap From a file)

    The EZ_DefNextCustomPaint command requires you pass a codeptr to a subroutine with the following syntax:

    SUB CustomX(BYVAL hWnd&, BYVAL hDC&, BYVAL X2&, BYVAL Y2&)

    This allows you to convert a simple control like a STATIC control to a Graphic ready control where you paint its background. SDK coders will appreciate this, since they do not have a PB Graphic control when coding. You can use a standard STATIC control and convert it into your own Graphic control with persistance.

    The PLUS part of the tool will really benefit SDK style coders (ie. FireFly, PwrDev, Phoenix users).


    The selling price will likely be around the $50 range.

    All of this in a 40 KB DLL, so its a very small footprint.

    The engine will support unlimited number of controls being made sprite ready. The maximum number of sprites will likely be 200 (still thinking about this one).

    My goal is to have it ready for release for retail sale within a week (not much more than that).

    Leave a comment:


  • Brice Manuel
    replied
    Is that a good Ouch or a bad Ouch ?
    It is a good ouch

    I can't vote in the poll, so here are my answers:

    I use Graphics a lot in my PB apps
    Yes

    I use higher end graphic engines
    I am working on my own DX9 based sprite engine, but I only use DX when I have to.

    I use the Windows GDI
    I addition to PB's graphics commands

    I use GDI+
    No

    I use DirectX
    Yes, but only when I have to.

    I use OpenGL
    Yes, but not for Windows

    I use PB Graphics commands a lot, rather than API
    I use PB's for the most part, but will use API when it will give me a speed boost.

    I use another style of graphic window (not PB graphic control)
    Only with DX

    My Graphic apps must be able to run on Windows 95/98/ME
    I do not support those versions of Windows.

    Windows XP is the minimum operating system my graphics apps need
    I support 2000/XP as the minimum

    I need fast animation speeds (at least 30 fps)
    It depends on the game.

    I need very fast animation speeds (at least 60 fps)
    It depends on the game.

    I need animation for games
    Yes

    I need animation for business style apps
    No

    I need "easy to use" more than just power
    I favor power because one can always wrap complexity with easier to use commands.

    Leave a comment:


  • Chris Boss
    replied
    If you haven't yet answered the POLL yet, please do. The more people who answer the POLL the more valuable it becomes. I am sure there must be hundreds of PB users who work with Graphics to some degree.

    Leave a comment:


  • Chris Boss
    replied
    So far I have written four sample (demo) apps using the sprite engine, using different styles of coding. To see how the code would look, download the attachedf zip file and it contains all four samples (just source code) so you can see how it would be when coding the different styles.

    Two of the sample code is DDT using a DDT Graphic control.

    One sample code is using a DDT Graphic Window instead of a control, so I think it would be applicable to both PBWin and PBCC (is PBCC Graphics windows the same as PBWin graphic windows ?)

    One sample is pure API (SDK style) code. Since SDK style code does not have its own Graphic control, the code uses a STATIC (Label) control. It also provides a custom paint routine using a feature built into the sprite engine just for this. In essence you are converting a STATIC control into a Graphic control. The Sprite engine provides persistance too, since when it takes control of the controls painting, it "requests" you draw the background (using the custom paint routine) and draws that into a Bitmap internally and uses that bitmap when it processes WM_PAINT. The sprite engine can be forced to request a new background drawing in two ways. One is to change the size of the control and it automatically requests it be redrawn. The second is to call the EZ_UpdateBKGND command which forces a redraw.
    Attached Files

    Leave a comment:


  • Barry Marks
    replied
    I'm not sure if I'm interested in sprites. Maybe. What I am very interested in is a simple way to use JPG and PNG files in the DDT graphic control.

    I'm only doing very light simple programming for fun and a lot of it involves images in one way or another. I live in a retirement home and much of what I do is make little toys for the other residents to use on our computers in the common area. Things like coloring book programs, a bingo caller, etc. I usually have to use BMP files, which are large and it also complicates the process of adding new graphics, since none of these people have any computer experience.

    A way to include other common graphic formats and still mostly use the DDT functions would work very nicely for me.

    If you just do sprites I may still be interested. I'll have to give that some thought. $50 is a pretty large purchase for me these days. If you include the loading of other formats for DDT I'll buy one.

    Barry

    Leave a comment:


  • Chris Boss
    replied
    Ouch!
    Is that a good Ouch or a bad Ouch ?

    Leave a comment:


  • Brice Manuel
    replied
    Originally posted by Chris Boss View Post
    The sprite DLL is now only 40 KB in size !
    Ouch!

    Leave a comment:


  • Chris Boss
    replied
    Added some new features today and did some benchmarking.

    First, I added a new command:

    EZ_CloneSprite

    This saves big time on memory when using multiple sprites based on the same bitmap.

    I borrowed the penguin sprite (12 frames of 100 x 100 pixel images) from Patrices IceWalk, since it was such a fun looking sprite and has a lot of frames to animate.

    I converted the penguin image (12 frames in one image) to a bitmap and got rid of the alpha pixels.

    I then loaded the image into a sample app and animated them using all the frames. The new clone feature sped up the creation of the sprites.

    I was able to display:

    200 sprites at 12 frames per second

    This ran at 100% CPU usage.

    If I added a 50 ms sleep per iteration, the frame rate dropped to 8 fps and only used 63% CPU usage. Not bad for a software based sprite engine.

    The sprite DLL is now only 40 KB in size !

    The compiled EXE came to 50 KB and heres the source code for it:

    Code:
    #COMPILE EXE
    #DIM ALL        '   This is helpful to prevent errors in coding
    #INCLUDE "win32api.inc"
    #INCLUDE "..\includes\ezsprite.inc"
    DECLARE SUB DrawGraphic(BYVAL N&)
    DECLARE SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
    ' ------------------------------------------------
    %FORM1_GRAPHIC1           = 110
    ' ------------------------------
    DECLARE SUB FORM1_Display()
    DECLARE SUB FORM1_Design(BYVAL hDlg&)
    GLOBAL hFORM1 AS LONG     ' Dialog Handle
    '
    DECLARE SUB DrawSprites()
    GLOBAL App_MsgLoopSleep&
    '
    FUNCTION PBMAIN() AS LONG
        LOCAL Count&
        DIALOG FONT "SYSTEM", 10    ' defines dialog unit size to System font default
        FORM1_Display
        ' ---------------------------
        DO
           DIALOG DOEVENTS 1 TO Count&           ' DDT Message Loop
           SpriteDraw 0,0
           IF App_MsgLoopSleep&>0 THEN SLEEP App_MsgLoopSleep&
        LOOP UNTIL Count&=0
        ' ---------------------------
    END FUNCTION
    %App_SizeW      = 400
    %App_SizeH      = 300
    %ButtonW        = 80
    %ButtonH        = 20
    SUB FORM1_Display()
         LOCAL T$, X&, Y&, W&, H&, WS&, EWS&, hDlg&
         T$ = "Sprite Demo"
         X& = 0
         Y& = 0
         W& =  %App_SizeW+%ButtonW
         H& =  %App_SizeH
         WS& =%WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU OR %WS_DLGFRAME OR %DS_CENTER OR %WS_CLIPCHILDREN
         EWS& =0
         DIALOG NEW UNITS, 0, T$, X&, Y&, W&, H&, WS&, EWS&, TO hDlg&
         hFORM1 = hDlg&
         DIALOG SET COLOR hDlg&, -1&, GetSysColor(%COLOR_ACTIVECAPTION)
         FORM1_Design hDlg&
         DIALOG SHOW MODELESS hDlg&, CALL FORM1_DlgProc
    END SUB
    SUB FORM1_Design(BYVAL hDlg&)
         LOCAL WS&, EWS&, hCtrl&, hTemp&, AW&, AH&, CText$
         ' -----------------------------------------------
         ' [Graphic]
         WS& =  %SS_OWNERDRAW OR %SS_NOTIFY OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
         EWS& = 0
         CONTROL ADD GRAPHIC , hDlg&,%FORM1_GRAPHIC1, "", 0, 0, %App_SizeW, %App_SizeH, WS&, EWS&
         CONTROL SET COLOR hDlg&,  %FORM1_GRAPHIC1, RGB(0,0,0), RGB(255,255,255)
         ' -----------------------------------------------
         LOCAL N&, T$
         FOR N&=1 TO 11
             SELECT CASE N&
                 CASE 1: T$="AlphaBlend ON"
                 CASE 2: T$="AlphaBlend OFF"
                 CASE 3: T$="Flip ON"
                 CASE 4: T$="Flip OFF"
                 CASE 5: T$="Use Sprite 1"
                 CASE 6: T$="Use Sprite 2"
                 CASE 7: T$="Sleep 50 ms per Cycle"
                 CASE 8: T$="Sleep OFF"
                 CASE 9: T$="Change Background"
                 CASE 10:T$="Delete Last Clone"
                 CASE 11:T$="Delete First Original"
             END SELECT
             WS& =  %BS_PUSHBUTTON OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
             EWS& = 0
             CONTROL ADD BUTTON, hDlg&,500+N&, T$, %App_SizeW+1, (N&-1)*%ButtonH, %ButtonW, %ButtonH, WS&, EWS& CALL FORM1_BUTTONS
         NEXT N&
         DrawGraphic 1
    END SUB
    GLOBAL App_MaxX&, App_MaxY&, App_SWidth&, App_SHeight&
    GLOBAL App_MinX&, App_MinY&
    GLOBAL App_UpdateFlag&
    GLOBAL App_FixedFlag&
    GLOBAL App_AlphaFlag&
    GLOBAL App_FlipFlag&
    GLOBAL App_FrameNum&
    GLOBAL App_LastClick$
    GLOBAL App_hCtrl&
    GLOBAL App_LastSprite&
    %App_FormOffset     =    0
    %App_SpriteCount    =   200
    %App_CheckBG       =    10
    %App_CheckFG       =    0
     
    SUB MakeSprites()
        LOCAL SName$, N&, SNameAll$, P2$, hDC&, T$, hBmp&, hCtrl&, CW&, CH&, W&, H&, RegNum$, OName$
        ' =========================
        ' Requires Registration code
        ' =========================
        EZ_InitSpriteBuffers %App_SpriteCount,-1,-1, $EZSPREGNUM
        CONTROL GET SIZE hForm1,%FORM1_GRAPHIC1 TO W&, H&
        DIALOG UNITS hForm1, W&, H& TO PIXELS CW&, CH&
        App_MaxX&=(CW&-1)+%App_FormOffset
        App_MaxY&=(CH&-1)+%App_FormOffset
        App_MinX&=0-%App_FormOffset
        App_MinY&=0-%App_FormOffset
        App_SWidth&=100
        App_SHeight&=100
        GRAPHIC BITMAP LOAD EXE.PATH$+"\graphics\penguin.bmp" ,0,0 TO hBmp&
        CONTROL HANDLE hForm1,%FORM1_GRAPHIC1 TO hCtrl&
        App_hCtrl&=hCtrl&
        EZ_AttachSprites hCtrl&
        App_LastSprite&=%App_SpriteCount
        FOR N&=1 TO %App_SpriteCount
            SName$="LOGO"+TRIM$(STR$(N&))
            IF SNameAll$="" THEN
                SNameAll$=SName$
            ELSE
                SNameAll$=SNameAll$+"|"+SName$
            END IF
            IF N&=1 THEN
                 OName$=SName$
                 EZ_DefSpriteByPict SName$, hBmp&,12, -1, 50
            ELSE
                 EZ_CloneSprite SName$, OName$
            END IF
        NEXT N&
        GRAPHIC ATTACH hBmp&,0
        GRAPHIC BITMAP END
        GRAPHIC DETACH
        EZ_AssignSprites hCtrl&, SNameAll$
        EZ_SetSpritesEffect SNameAll$, 1,0
    END SUB
    '
    GLOBAL App_XY&()
    '
    FUNCTION GetX(BYVAL N&) AS LONG
        LOCAL X&
        X&=(N& MOD 8)+1
        IF App_XY&(N&,1)>=App_MaxX&-App_SWidth& THEN App_XY&(N&,3)=-1
        IF App_XY&(N&,1)<=App_MinX& THEN App_XY&(N&,3)=1
        X&=X&*App_XY&(N&,3)
        App_XY&(N&,1)=App_XY&(N&,1)+X&
        FUNCTION=App_XY&(N&,1)
    END FUNCTION
    '
    FUNCTION GetY(BYVAL N&) AS LONG
        LOCAL Y&
        Y&=(N& MOD 10)+1
        IF App_XY&(N&,2)>=App_MaxY&-App_SHeight& THEN App_XY&(N&,4)=-1
        IF App_XY&(N&,2)<=App_MinY& THEN App_XY&(N&,4)=1
        Y&=Y&*App_XY&(N&,4)
        App_XY&(N&,2)=App_XY&(N&,2)+Y
        FUNCTION=App_XY&(N&,2)
    END FUNCTION
    '
    SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
        LOCAL EF&, ToggleX&, ToggleY&
        LOCAL SName$, PW&, N&, T$, FMS&, AFrame&
        STATIC FlipFlag&
        STATIC Count&, CT!
        STATIC TM!, FlipCT&, FrameOffset&
        STATIC IFrame&
        IF Mode&=1 THEN
            IFrame&=1
            App_FrameNum&=1
            FrameOffset&=0
            App_FlipFlag&=0
            App_AlphaFlag&=0
            Count&=0
            REDIM App_XY&(1 TO %App_SpriteCount, 1 TO 4)
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_MoveSprites SName$, N&,N&,0
                App_XY&(N&,1)=N&
                App_XY&(N&,2)=N&
                App_XY&(N&,3)=1
                App_XY&(N&,4)=1
                EZ_ShowSprites SName$,1
            NEXT N&
        ELSE
            IF FrameOffset&=0 THEN FrameOffset&=1 ELSE FrameOffset&=0
            IF Count&=0 THEN TM!=TIMER
            FlipCT&=FlipCT&+1
            IF FlipCT&>1 THEN
                 FlipFlag&=FlipFlag&+1
                 IF FlipFlag&>4 THEN FlipFlag&=1
                 FlipCT&=0
            END IF
            EF&=0
            IF App_AlphaFlag& THEN EF&=50
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_SetSpritesEffect SName$, EF&,0
                EZ_MoveSprites SName$, GetX(N&),GetY(N&),0
                IF App_FlipFlag& THEN
                    SELECT CASE FlipFlag&
                         CASE 1
                            EZ_SetSpritesFlip SName$, 0,0,0
                         CASE 2
                            EZ_SetSpritesFlip SName$, 1,0,0
                         CASE 3
                            EZ_SetSpritesFlip SName$, 1,1,0
                         CASE 4
                            EZ_SetSpritesFlip SName$, 0,1,0
                    END SELECT
                ELSE
                    EZ_SetSpritesFlip SName$, 0,0,0
                END IF
                AFrame&=IFrame&
                AFrame&=((AFrame&+N&) MOD 12) +1
                EZ_SetSpritesFrame SName$, AFrame&,0,0
                IF App_UpdateFlag& THEN
                    EZ_UpdateClient App_hCtrl&
                END IF
            NEXT N&
            IFrame&=IFrame&+1
            IF IFrame&>12 THEN IFrame&=1
            IF App_UpdateFlag&=0 THEN
                EZ_UpdateClient App_hCtrl&
            END IF
            Count&=Count&+1
            FMS&=25
            IF Count&>=FMS& THEN
                TM!=TIMER-TM!
                IF TM!<=0 THEN TM!=1
                TM!=INT((FMS&/TM!)*100)/100
                DIALOG SET TEXT hForm1, "Sprite Demo:    "+STR$(App_LastSprite&)+" Sprites (100 x 100 pixels) displaying at "+FORMAT$(TM!, "0000.00")+" Frames/sec"
                Count&=0
            END IF
        END IF
    END SUB
    CALLBACK FUNCTION FORM1_BUTTONS() AS LONG
        IF CB.MSG=%WM_COMMAND THEN
            IF CB.CTLMSG=%BN_CLICKED THEN
                SELECT CASE CB.CTL-500
                    CASE 1
                        App_AlphaFlag&=1
                    CASE 2
                        App_AlphaFlag&=0
                    CASE 3
                        App_FlipFlag&=1
                    CASE 4
                        App_FlipFlag&=0
                    CASE 5
                        App_FrameNum&=1
                    CASE 6
                        App_FrameNum&=2
                    CASE 7
                        App_MsgLoopSleep&=50
                    CASE 8
                        App_MsgLoopSleep&=0
                    CASE 9
                        LOCAL hCtrl&
                        CONTROL HANDLE hForm1, %FORM1_GRAPHIC1 TO hCtrl&
                        DrawGraphic -1
                        EZ_UpdateBKGND hCtrl&
                    CASE 10
                         IF App_LastSprite&>0 THEN
                             EZ_FreeSprite "LOGO"+TRIM$(STR$(App_LastSprite&))
                             App_LastSprite&=App_LastSprite&-1
                         END IF
                    CASE 11
                         IF App_LastSprite&>0 THEN
                              EZ_FreeSprite "LOGO1"
                              App_LastSprite&=0
                         END IF
                    CASE ELSE
                END SELECT
            END IF
        END IF
    END FUNCTION
     
    ' #################################################################
    '              Dialog Procedure for FORM1
    ' #################################################################
    CALLBACK FUNCTION FORM1_DlgProc
         SELECT CASE CBMSG
              CASE %WM_INITDIALOG
                  MakeSprites
                  SpriteDraw 1,0
              CASE %WM_DESTROY
              CASE ELSE
         END SELECT
    END FUNCTION
    SUB DrawGraphic(BYVAL N&)
        LOCAL D$, hDC&, AW!, AH!, F$
        STATIC LastN&
        IF LastN&<1 THEN LastN&=1
        IF N&=-1 THEN
            LastN&=LastN&+1
            IF LastN&>5 THEN LastN&=1
            N&=LastN&
        END IF
        F$="\graphics\bkgnd"+TRIM$(STR$(N&))+".bmp"
        GRAPHIC ATTACH hForm1, %FORM1_GRAPHIC1, REDRAW
        GRAPHIC SCALE PIXELS
        GRAPHIC GET CLIENT TO AW!, AH!
        GRAPHIC RENDER EXE.PATH$+F$, (0,0) - (AW!-1, AH!-1)
        GRAPHIC REDRAW
        LastN&=N&
    END SUB
    Last edited by Chris Boss; 2 Sep 2009, 09:36 PM.

    Leave a comment:


  • Chris Boss
    replied
    SDK supported

    Ok, this tool will be slightly more than just a Sprite engine so I can provide better support for SDK style coding.

    DDT has a rich Graphic command set, but using the API alone there is a little less to work with.

    One problem is there is no SDK version of the PB Graphic command.

    Problem solved though with EZSprite Plus (the new product name).

    A new command is provided:

    EZ_DefNextCustomPaint

    This command allows you to define your own Paint (draw) routine for an existing control which will be later defined sprite ready. Here is how it works:

    Let's say you create a normal STATIC control for the background for your sprites. To take control of that STATIC controls background drawing you would do the following:

    Code:
        EZ_DefNextCustomPaint CODEPTR(MyCustomControlDraw)
        EZ_AttachSprites hStaticCtrl&
    The subroutine pointer (codeptr) passed in EZ_DefNextCustomPaint must have the syntax as follows:

    Code:
    SUB MyCustomControlDraw(BYVAL hWnd&, BYVAL hDC&, BYVAL X2&, BYVAL Y2&)
    END SUB
    There are a number of commands provided to make drawing easier. You still use the GDI functions (ie. Rectangle, Ellipse) to draw, but a command set is provided which makes it easier to select pens and brushs. You don't have to worry about selecting the old pen or brush back into the DC and don't have to worry about deleting the last pen or brush used.

    Here is an example of such a drawing routine:

    Code:
    SUB MyCustomControlDraw(BYVAL hWnd&, BYVAL hDC&, BYVAL X2&, BYVAL Y2&)
         LOCAL N&, F$, hBmp&, C&, C2&, C3&
         EZ_StartDCDraw hDC&
         N&=App_Background&
         SELECT CASE N&
              CASE 1 TO 5
                   F$=EXE.PATH$+"\graphics\bkgnd"+TRIM$(STR$(N&))+".bmp"
                   hBmp&=EZ_LoadBitmapFile(F$, X2&+1,Y2&+1)
                   EZ_BeginBmpBrush hBmp&
                   DeleteObject hBmp&
                   PatBlt hDC&, 0,0, X2&, Y2&, %PATCOPY
              CASE ELSE
                   C&=RGB(200,200,255)
                   C2&=RGB(128,128,255)
                   C3&=RGB(64,64,255)
                   IF N&=7 THEN C&=RGB(255,255,200):C2&=RGB(255,255,128):C3&=RGB(128,128,64)
                   EZ_BeginBrush C&
                   EZ_BeginPen C&,1
                   Rectangle hDC&, 0,0, X2&, Y2&
                   EZ_BeginBrush C2&
                   EZ_BeginPen C3&,1
                   ELLIPSE hDC&, 24,24, X2&-24, Y2&-24
                   EZ_BeginBrush -1    ' NULL brush
                   ELLIPSE hDC&, 20,20, X2&-20, Y2&-20
                   F$=EXE.PATH$+"\graphics\rose.bmp"
                   hBmp&=EZ_LoadBitmapFile(F$,0,0)    ' actual size
                   EZ_BeginBmpBrush hBmp&
                   EZ_BeginPen RGB(0,0,0), 2
                   ELLIPSE hDC&, 48,48, X2&-48, Y2&-48
                   DeleteObject hBmp&
         END SELECT
         EZ_EndDCDraw   ' automatically calls EZ_EndBrush and EZ_EndPen
    END SUB
    Here is a list of the graphic support commands provided along with the Sprite commands:

    EZ_Create32BitDIB
    EZ_GetBitmapSize
    EZ_StartBitmapDraw
    EZ_EndBitmapDraw
    EZ_StartDCDraw
    EZ_EndDCDraw
    EZ_FreeBitmap
    EZ_DefStyles
    EZ_BeginBrush
    EZ_BeginBmpBrush
    EZ_EndBrush
    EZ_BeginPen
    EZ_EndPen
    EZ_DefNextCustomPaint
    EZ_LoadBitmapFile


    A screenshot of the SDK sprite app:



    Now heres the code SDk style:

    Code:
    #COMPILE EXE
    #DIM ALL        '   This is helpful to prevent errors in coding
    #INCLUDE "win32api.inc"
    #INCLUDE "..\includes\ezsprite.inc"
    DECLARE SUB DrawGraphic(BYVAL N&)
    DECLARE SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
    ' ------------------------------------------------
    %FORM1_GRAPHIC1           = 110
    ' ------------------------------
    DECLARE SUB FORM1_Display()
    DECLARE SUB FORM1_Design(BYVAL hDlg&)
    GLOBAL hFORM1 AS LONG     ' Dialog Handle
    '
    DECLARE SUB DrawSprites()
    GLOBAL App_MsgLoopSleep&
    '
    '
    FUNCTION PBMAIN() AS LONG
        LOCAL RV&, Msg AS tagMsg
        FORM1_Display
        ' ---------------------------
        DO
            RV&=PeekMessage(Msg, 0,0,0, %PM_REMOVE)
            IF RV&<>0 THEN
                IF IsDialogMessage(Msg.hwnd, Msg)=0 THEN
                    TranslateMessage Msg
                    DispatchMessage Msg
                END IF
            END IF
            IF Msg.message=%WM_QUIT THEN EXIT DO
            SpriteDraw 0,0
            IF App_MsgLoopSleep&>0 THEN SLEEP App_MsgLoopSleep&
        LOOP
        ' ---------------------------
    END FUNCTION
    '
    '
    %App_SizeW      = 800
    %App_SizeH      = 600
    %ButtonW        = 160
    %ButtonH        = 30
    GLOBAL App_MaxX&, App_MaxY&, App_SWidth&, App_SHeight&
    GLOBAL App_MinX&, App_MinY&
    GLOBAL App_UpdateFlag&
    GLOBAL App_FixedFlag&
    GLOBAL App_AlphaFlag&
    GLOBAL App_FlipFlag&
    GLOBAL App_FrameNum&
    GLOBAL App_LastClick$
    GLOBAL App_GraphicCtrl&
    GLOBAL App_Background&
     
    %App_FormOffset     =    0
    %App_SpriteCount    =   24
    '
    '
    FUNCTION MyWndproc(BYVAL hWnd&, BYVAL Msg&, BYVAL wParam&, BYVAL lParam&) AS LONG
         SELECT CASE Msg&
              CASE %WM_CREATE
                   FORM1_Design hWnd&
                   MakeSprites
                   SpriteDraw 1,0
              CASE %WM_COMMAND
                   LOCAL ID&
                   ID&=LOWRD(wParam&)
                   SELECT CASE ID&
                        CASE 501 TO 509
                             IF HIWRD(wParam&)=%BN_CLICKED THEN
                                  SELECT CASE ID&-500
                                        CASE 1
                                            App_AlphaFlag&=1
                                        CASE 2
                                            App_AlphaFlag&=0
                                        CASE 3
                                            App_FlipFlag&=1
                                        CASE 4
                                            App_FlipFlag&=0
                                        CASE 5
                                            App_FrameNum&=1
                                        CASE 6
                                            App_FrameNum&=2
                                        CASE 7
                                            App_MsgLoopSleep&=50
                                        CASE 8
                                            App_MsgLoopSleep&=0
                                        CASE 9
                                             App_Background&=App_Background&+1
                                             IF App_Background&>7 THEN App_Background&=1
                                             EZ_UpdateBKGND App_GraphicCtrl&
                                        CASE ELSE
                                  END SELECT
                             END IF
                        CASE ELSE
                   END SELECT
              CASE %WM_DESTROY
                   PostQuitMessage 0
              CASE ELSE
         END SELECT
         FUNCTION=DefWindowProc(hWnd&, Msg&, wParam&, lParam&)
    END FUNCTION
    '
    '
    FUNCTION GetAppInstance() AS LONG
         STATIC RV&
         IF RV&=0 THEN RV&=GetModulehandle(BYVAL %NULL)
         FUNCTION=RV&
    END FUNCTION
    '
    '
    FUNCTION CreateW(BYVAL ExWS&, BYVAL MyClass$, BYVAL Caption$, BYVAL WS&, BYVAL X&, BYVAL Y&, BYVAL W&, BYVAL H&, BYVAL hParent&, BYVAL Menu_or_ID&) AS LONG
         FUNCTION=CreateWindowEx(ExWS&, BYVAL STRPTR(MyClass$), BYVAL STRPTR(Caption$), WS&, X&, Y&,W&, H&, hParent&, Menu_or_ID&,GetAppInstance, BYVAL %NULL)
    END FUNCTION
    '
    '
    SUB FORM1_Display()
         LOCAL T$, X&, Y&, W&, H&, WS&, EWS&, hDlg&
         LOCAL WN AS WNDCLASSEX, zName AS ASCIIZ*32
         WN.cbSize=SIZEOF(WN)
         WN.STYLE=%CS_HREDRAW OR %CS_VREDRAW OR %CS_DBLCLKS
         WN.lpfnWndProc=CODEPTR(MyWndproc)
         WN.cbClsExtra=0
         WN.cbWndExtra=0
         WN.hInstance=GetAppInstance
         WN.hIcon=%NULL
         WN.hCursor=LoadCursor(%NULL, BYVAL %IDC_ARROW)
         WN.hbrBackground=GetStockObject( %GRAY_BRUSH )
         WN.lpszMenuName=%NULL
         zName="MYClass"
         WN.lpszClassName=VARPTR(zName)
         WN.hIconSm=0
         RegisterClassEx WN
         T$ = "Sprite Demo"
         X& = 100
         Y& = 50
         W& =  %App_SizeW+%ButtonW+(GetSystemMetrics(%SM_CXEDGE)*2)
         H& =  %App_SizeH+(GetSystemMetrics(%SM_CYEDGE)*2)+GetSystemMetrics(%SM_CYCAPTION)
         WS& =%WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU OR %WS_VISIBLE OR %WS_CLIPCHILDREN
         EWS& =0
         hForm1=CreateW(EWS&,"MYClass", "Sprite Demo:", WS&, X&, Y&,W&, H&, %NULL, %NULL)
    END SUB
    '
    '
    SUB FORM1_Design(BYVAL hDlg&)
         LOCAL WS&, EWS&, hCtrl&, hTemp&, AW&, AH&, CText$
         App_Background&=1
         ' -----------------------------------------------
         ' [Graphic]
         WS& =  %SS_NOTIFY OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
         EWS& = 0
         App_GraphicCtrl&=CreateW(EWS&,"STATIC", "Label:", WS&,0, 0, %App_SizeW, %App_SizeH, hDlg&,%FORM1_GRAPHIC1)
         ' -----------------------------------------------
         LOCAL N&, T$
         FOR N&=1 TO 9
             SELECT CASE N&
                 CASE 1: T$="AlphaBlend ON"
                 CASE 2: T$="AlphaBlend OFF"
                 CASE 3: T$="Flip ON"
                 CASE 4: T$="Flip OFF"
                 CASE 5: T$="Use Sprite 1"
                 CASE 6: T$="Use Sprite 2"
                 CASE 7: T$="Sleep 50 ms per Cycle"
                 CASE 8: T$="Sleep OFF"
                 CASE 9: T$="Change Background"
             END SELECT
             WS& =  %BS_PUSHBUTTON OR %WS_VISIBLE OR %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
             EWS& = 0
             hCtrl&=CreateW(EWS&,"BUTTON", T$, WS&,%App_SizeW+1, (N&-1)*%ButtonH, %ButtonW, %ButtonH, hDlg&,500+N&)
         NEXT N&
    END SUB
    '
    '
    SUB MyCustomControlDraw(BYVAL hWnd&, BYVAL hDC&, BYVAL X2&, BYVAL Y2&)
         LOCAL N&, F$, hBmp&, C&, C2&, C3&
         EZ_StartDCDraw hDC&
         N&=App_Background&
         SELECT CASE N&
              CASE 1 TO 5
                   F$=EXE.PATH$+"\graphics\bkgnd"+TRIM$(STR$(N&))+".bmp"
                   hBmp&=EZ_LoadBitmapFile(F$, X2&+1,Y2&+1)
                   EZ_BeginBmpBrush hBmp&
                   DeleteObject hBmp&
                   PatBlt hDC&, 0,0, X2&, Y2&, %PATCOPY
              CASE ELSE
                   C&=RGB(200,200,255)
                   C2&=RGB(128,128,255)
                   C3&=RGB(64,64,255)
                   IF N&=7 THEN C&=RGB(255,255,200):C2&=RGB(255,255,128):C3&=RGB(128,128,64)
                   EZ_BeginBrush C&
                   EZ_BeginPen C&,1
                   Rectangle hDC&, 0,0, X2&, Y2&
                   EZ_BeginBrush C2&
                   EZ_BeginPen C3&,1
                   ELLIPSE hDC&, 24,24, X2&-24, Y2&-24
                   EZ_BeginBrush -1    ' NULL brush
                   ELLIPSE hDC&, 20,20, X2&-20, Y2&-20
                   F$=EXE.PATH$+"\graphics\rose.bmp"
                   hBmp&=EZ_LoadBitmapFile(F$,0,0)    ' actual size
                   EZ_BeginBmpBrush hBmp&
                   EZ_BeginPen RGB(0,0,0), 2
                   ELLIPSE hDC&, 48,48, X2&-48, Y2&-48
                   DeleteObject hBmp&
         END SELECT
         EZ_EndDCDraw   ' automatically calls EZ_EndBrush and EZ_EndPen
    END SUB
    '
    '
    SUB MakeSprites()
        LOCAL SName$, N&, SNameAll$, P2$, hDC&, T$, hBmp&, hCtrl&, CW&, CH&, W&, H&, RegNum$, R AS RECT
        EZ_InitSpriteBuffers %App_SpriteCount,-1,-1, $EZSPREGNUM
        GetClientRect App_GraphicCtrl&, R
        CW&=R.nRight-R.nLeft
        CH&=R.nBottom-R.nTop
        App_MaxX&=(CW&-1)+%App_FormOffset
        App_MaxY&=(CH&-1)+%App_FormOffset
        App_MinX&=0-%App_FormOffset
        App_MinY&=0-%App_FormOffset
        App_SWidth&=140
        App_SHeight&=140
        hBmp&=EZ_LoadBitmapFile(EXE.PATH$+"\graphics\ball3d.bmp" ,0,0)
        ' -------------------------------
        ' Prepare control for custom painting
        EZ_DefNextCustomPaint CODEPTR(MyCustomControlDraw)
        ' -------------------------------
        EZ_AttachSprites App_GraphicCtrl&
        ' -------------------------------
        FOR N&=1 TO %App_SpriteCount
            SName$="LOGO"+TRIM$(STR$(N&))
            IF SNameAll$="" THEN
                SNameAll$=SName$
            ELSE
                SNameAll$=SNameAll$+"|"+SName$
            END IF
            EZ_DefSpriteByPict SName$, hBmp&,3, -1, 50
        NEXT N&
        DeleteObject hBmp&
        EZ_AssignSprites App_GraphicCtrl&, SNameAll$
        EZ_SetSpritesEffect SNameAll$, 1,0
    END SUB
    '
    '
    GLOBAL App_XY&()
    '
    '
    FUNCTION GetX(BYVAL N&) AS LONG
        LOCAL X&
        X&=(N& MOD 8)+1
        IF App_XY&(N&,1)>=App_MaxX&-App_SWidth& THEN App_XY&(N&,3)=-1
        IF App_XY&(N&,1)<=App_MinX& THEN App_XY&(N&,3)=1
        X&=X&*App_XY&(N&,3)
        App_XY&(N&,1)=App_XY&(N&,1)+X&
        FUNCTION=App_XY&(N&,1)
    END FUNCTION
    '
    '
    FUNCTION GetY(BYVAL N&) AS LONG
        LOCAL Y&
        Y&=(N& MOD 10)+1
        IF App_XY&(N&,2)>=App_MaxY&-App_SHeight& THEN App_XY&(N&,4)=-1
        IF App_XY&(N&,2)<=App_MinY& THEN App_XY&(N&,4)=1
        Y&=Y&*App_XY&(N&,4)
        App_XY&(N&,2)=App_XY&(N&,2)+Y
        FUNCTION=App_XY&(N&,2)
    END FUNCTION
    '
    '
    SUB SpriteDraw(BYVAL Mode&, BYVAL CVal&)
        LOCAL EF&, ToggleX&, ToggleY&
        LOCAL SName$, PW&, N&, T$
        STATIC FlipFlag&
        STATIC Count&, CT!
        STATIC TM!, FlipCT&, FrameOffset&
        IF Mode&=1 THEN
            App_FrameNum&=1
            FrameOffset&=0
            App_FlipFlag&=0
            App_AlphaFlag&=0
            Count&=0
            REDIM App_XY&(1 TO %App_SpriteCount, 1 TO 4)
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_MoveSprites SName$, N&,N&,0
                App_XY&(N&,1)=N&
                App_XY&(N&,2)=N&
                App_XY&(N&,3)=1
                App_XY&(N&,4)=1
                EZ_ShowSprites SName$,1
            NEXT N&
        ELSE
            IF FrameOffset&=0 THEN FrameOffset&=1 ELSE FrameOffset&=0
            IF Count&=0 THEN TM!=TIMER
            FlipCT&=FlipCT&+1
            IF FlipCT&>1 THEN
                 FlipFlag&=FlipFlag&+1
                 IF FlipFlag&>4 THEN FlipFlag&=1
                 FlipCT&=0
            END IF
            EF&=0
            IF App_AlphaFlag& THEN EF&=50
            FOR N&=1 TO %App_SpriteCount
                SName$="LOGO"+TRIM$(STR$(N&))
                EZ_SetSpritesEffect SName$, EF&,0
                EZ_MoveSprites SName$, GetX(N&),GetY(N&),0
                IF App_FlipFlag& THEN
                    SELECT CASE FlipFlag&
                         CASE 1
                            EZ_SetSpritesFlip SName$, 0,0,0
                         CASE 2
                            EZ_SetSpritesFlip SName$, 1,0,0
                         CASE 3
                            EZ_SetSpritesFlip SName$, 1,1,0
                         CASE 4
                            EZ_SetSpritesFlip SName$, 0,1,0
                    END SELECT
                ELSE
                    EZ_SetSpritesFlip SName$, 0,0,0
                END IF
                IF App_FrameNum&=1 THEN
                    EZ_SetSpritesFrame SName$, 1,0,0
                ELSE
                    EZ_SetSpritesFrame SName$, 2 + FrameOffset&,0,0
                END IF
                IF App_UpdateFlag& THEN
                    EZ_UpdateClient App_GraphicCtrl&
                END IF
            NEXT N&
            IF App_UpdateFlag&=0 THEN
                EZ_UpdateClient App_GraphicCtrl&
            END IF
            Count&=Count&+1
            IF Count&>=100 THEN
                TM!=TIMER-TM!
                IF TM!<=0 THEN TM!=1
                TM!=INT((100/TM!)*100)/100
                T$="Sprite Demo:    "+STR$(%App_SpriteCount)+" Sprites (140 x 140 pixels) displaying at "+FORMAT$(TM!, "0000.00")+" Frames/sec"
                SetWindowText hForm1, BYVAL STRPTR(T$)
                Count&=0
            END IF
        END IF
    END SUB
    All of this is a small 39 KB DLL !
    Last edited by Chris Boss; 1 Sep 2009, 08:07 PM.

    Leave a comment:

Working...
X