home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / foxbear / sprite.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  16KB  |  793 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *  Copyright (C) 1994-1995 ATI Technologies Inc. All Rights Reserved.
  5.  *
  6.  *  File:    sprite.c
  7.  *  Content:    sprite manipulation functions
  8.  *
  9.  ***************************************************************************/
  10. #include "foxbear.h"
  11.  
  12. /*
  13.  * CreateSprite
  14.  */
  15. HSPRITE *CreateSprite (
  16.     USHORT    bitmapCount,
  17.     LONG      x,
  18.     LONG      y,
  19.     USHORT    width,
  20.     USHORT    height,
  21.     USHORT    xmax,
  22.     USHORT    ymax,
  23.     SHORT     as,
  24.     BOOL      active )
  25. {
  26.     HSPRITE *hSprite;
  27.     USHORT   i;
  28.  
  29.     hSprite = MemAlloc( sizeof (HSPRITE) );
  30.     if( hSprite == NULL )
  31.     {
  32.         ErrorMessage( "hSprite in CreateSprite" );
  33.     }
  34.  
  35.     hSprite->hSBM = CMemAlloc( bitmapCount, sizeof (HSPRITE_BM) );
  36.     if( hSprite->hSBM == NULL )
  37.     {
  38.         MemFree( hSprite );
  39.         ErrorMessage( "hSprite->hSBM in CreateSprite" );
  40.     }
  41.     
  42.     hSprite->active        = active;
  43.     hSprite->bitmapCount   = bitmapCount;
  44.     hSprite->x             = x;
  45.     hSprite->y             = y;
  46.     hSprite->width         = width;
  47.     hSprite->height        = height;
  48.     hSprite->xv            = 0;
  49.     hSprite->yv            = 0;
  50.     hSprite->xa            = 0;
  51.     hSprite->ya            = 0;
  52.     hSprite->xmax          = xmax;
  53.     hSprite->ymax          = ymax;
  54.     hSprite->absSwitch     = as;
  55.     hSprite->relSwitch     = 0;
  56.     hSprite->switchType    = HOR;
  57.     hSprite->switchForward = TRUE;
  58.     hSprite->switchDone    = FALSE;
  59.  
  60.     for( i = 0; i < bitmapCount; ++i )
  61.     {
  62.         hSprite->hSBM[i].hBM = NULL;
  63.     }
  64.  
  65.     return hSprite;
  66.  
  67. } /* CreateSprite */
  68.  
  69. /*
  70.  * BitBltSprite
  71.  */
  72. BOOL BitBltSprite (
  73.     HSPRITE   *hSprite,
  74.     GFX_HBM    hBM,
  75.     ACTION     action,
  76.     DIRECTION  direction,
  77.     SHORT      x,
  78.     SHORT      y,
  79.     USHORT     w,
  80.     USHORT     h )
  81. {
  82.     USHORT count;
  83.  
  84.     if( hSprite == NULL )
  85.     {
  86.         ErrorMessage( "hSprite in BitBltSprite" );
  87.     }
  88.  
  89.     if( hBM == NULL )
  90.     {
  91.         ErrorMessage( "hBM in BitBltSprite" );
  92.     }
  93.  
  94.     if( (x >= hSprite->width) || (y >= hSprite->height) )
  95.     {
  96.         ErrorMessage( "x or y in BitBltSprite" );
  97.     }
  98.  
  99.     count = 0;
  100.     while( hSprite->hSBM[count].hBM != NULL )
  101.     {
  102.         count++;
  103.         if( count >= hSprite->bitmapCount )
  104.         {
  105.             ErrorMessage( "Bitmap overflow in BitBltSprite" );
  106.         }
  107.     }
  108.  
  109.     hSprite->hSBM[count].hBM       = hBM;
  110.     hSprite->hSBM[count].action    = action;
  111.     hSprite->hSBM[count].direction = direction;
  112.     hSprite->hSBM[count].x         = x;
  113.     hSprite->hSBM[count].y         = y;
  114.     hSprite->hSBM[count].width     = w; 
  115.     hSprite->hSBM[count].height    = h; 
  116.  
  117.     return TRUE;
  118.  
  119. } /* BitBltSprite */
  120.  
  121. /*
  122.  * SetSpriteAction
  123.  */
  124. BOOL SetSpriteAction ( HSPRITE *hSprite, ACTION action, DIRECTION direction )
  125. {
  126.     USHORT c;
  127.  
  128.     c = 0;
  129.  
  130.     if( direction == SAME )
  131.     {
  132.         direction = hSprite->currentDirection;
  133.     }
  134.  
  135.     while( (hSprite->hSBM[c].action != action) || (hSprite->hSBM[c].direction != direction) )
  136.     {
  137.         ++c;
  138.     }
  139.  
  140.     hSprite->currentAction    = action;
  141.     hSprite->currentDirection = direction;
  142.     hSprite->currentBitmap    = c;
  143.     hSprite->relSwitch        = 0;
  144.  
  145.     return TRUE;
  146.  
  147. } /* SetSpriteAction */
  148.  
  149. /*
  150.  * ChangeSpriteDirection
  151.  */
  152. BOOL ChangeSpriteDirection( HSPRITE *hSprite )
  153. {
  154.     DIRECTION direction;
  155.  
  156.     if( hSprite->currentDirection == RIGHT )
  157.     {
  158.         direction = LEFT;
  159.     }
  160.     else
  161.     {
  162.         direction = RIGHT;
  163.     }
  164.  
  165.     SetSpriteAction( hSprite, hSprite->currentAction, direction );
  166.  
  167.     return TRUE;
  168.  
  169. } /* ChangeSpriteDirection */
  170.  
  171. /*
  172.  * GetSpriteAction
  173.  */
  174. ACTION GetSpriteAction( HSPRITE *hSprite )
  175. {
  176.     return hSprite->currentAction;
  177.  
  178. } /* GetSpriteAction */
  179.  
  180.  
  181. /*
  182.  * GetSpriteDirection
  183.  */
  184. DIRECTION GetSpriteDirection( HSPRITE *hSprite )         
  185. {
  186.     return hSprite->currentDirection;
  187.  
  188. } /* GetSpriteDirection */
  189.  
  190. /*
  191.  * SetSpriteActive
  192.  */
  193. BOOL SetSpriteActive( HSPRITE *hSprite, BOOL active )
  194. {
  195.     hSprite->active = active;
  196.     
  197.     if( active == FALSE )
  198.     {
  199.         hSprite->xv = 0;
  200.         hSprite->yv = 0;
  201.         hSprite->xa = 0;
  202.         hSprite->ya = 0;
  203.     }
  204.  
  205.     return TRUE;
  206.  
  207. } /* SetSpriteActive */
  208.  
  209. /*
  210.  * GetSpriteActive
  211.  */
  212. BOOL GetSpriteActive( HSPRITE *hSprite )
  213. {
  214.     return hSprite->active;
  215.  
  216. } /* GetSpriteActive */
  217.  
  218. /*
  219.  * SetSpriteVelX
  220.  */
  221. BOOL SetSpriteVelX( HSPRITE *hSprite, LONG xv, POSITION position )
  222. {
  223.     if( hSprite->active == FALSE )
  224.     {
  225.         return FALSE;
  226.     }
  227.  
  228.     if( position == P_ABSOLUTE )
  229.     {
  230.         hSprite->xv = xv;
  231.     }
  232.     else if( position == P_RELATIVE )
  233.     {
  234.         hSprite->xv += xv;
  235.     }
  236.  
  237.     return TRUE;
  238.  
  239. } /* SetSpriteVelX */
  240.  
  241. /*
  242.  * GetSpriteVelX
  243.  */
  244. LONG GetSpriteVelX( HSPRITE *hSprite )
  245. {
  246.     return hSprite->xv;
  247.  
  248. } /* GetSpriteVelX */
  249.  
  250. /*
  251.  * SetSpriteVelY
  252.  */
  253. BOOL SetSpriteVelY( HSPRITE *hSprite, LONG  yv, POSITION position )
  254. {
  255.     if( hSprite->active == FALSE )
  256.     {
  257.         return FALSE;
  258.     }
  259.  
  260.     if( position == P_ABSOLUTE )
  261.     {
  262.         hSprite->yv = yv;
  263.     }
  264.     else if( position == P_RELATIVE )
  265.     {
  266.         hSprite->yv += yv;
  267.     }
  268.  
  269.     return TRUE;
  270.  
  271. } /* SetSpriteVelY */
  272.  
  273. /*
  274.  * GetSpriteVelY
  275.  */
  276. LONG GetSpriteVelY( HSPRITE *hSprite )
  277. {
  278.     return hSprite->yv;
  279.  
  280. } /* GetSpriteVelY */
  281.  
  282. /*
  283.  * SetSpriteAccX
  284.  */
  285. BOOL SetSpriteAccX ( HSPRITE *hSprite, LONG xa, POSITION position )
  286. {
  287.     if( position == P_ABSOLUTE )
  288.     {
  289.         hSprite->xa = xa;
  290.     }
  291.     else if( position == P_RELATIVE )
  292.     {
  293.         hSprite->xa += xa;
  294.     }
  295.     return TRUE;
  296.  
  297. } /* SetSpriteAccX */
  298.  
  299. /*
  300.  * GetSpriteAccX
  301.  */
  302. LONG GetSpriteAccX( HSPRITE *hSprite )
  303. {
  304.     return hSprite->xa;
  305.  
  306. } /* GetSpriteAccX */
  307.  
  308. /*
  309.  * SetSpriteAccY
  310.  */
  311. BOOL SetSpriteAccY ( HSPRITE *hSprite, LONG ya, POSITION position )
  312. {
  313.     if( position == P_ABSOLUTE )
  314.     {
  315.         hSprite->ya = ya;
  316.     }
  317.     else if( position == P_RELATIVE )
  318.     {
  319.         hSprite->ya += ya;
  320.     }
  321.     return TRUE;
  322.  
  323. } /* SetSpriteAccY */
  324.  
  325. /*
  326.  * GetSpriteAccY
  327.  */
  328. LONG GetSpriteAccY( HSPRITE *hSprite )
  329. {
  330.     return hSprite->ya;
  331.  
  332. } /* GetSpriteAccY */
  333.  
  334. /*
  335.  * SetSpriteX
  336.  */
  337. BOOL SetSpriteX( HSPRITE *hSprite, LONG x, POSITION position )
  338. {
  339.     if( hSprite->active == FALSE )
  340.     {
  341.         return FALSE;
  342.     }
  343.  
  344.     if( position == P_AUTOMATIC )
  345.     {
  346.         hSprite->xv += hSprite->xa;
  347.         hSprite->x  += hSprite->xv;
  348.     }
  349.     else if( position == P_ABSOLUTE )
  350.     {
  351.         hSprite->x = x;
  352.     }
  353.     else if( position == P_RELATIVE )
  354.     {
  355.         hSprite->x += x;
  356.     }
  357.  
  358.     if( hSprite->x < 0 )
  359.     {
  360.         hSprite->x += hSprite->xmax << 16;
  361.     }
  362.     else if( hSprite->x >= hSprite->xmax << 16 )
  363.     {
  364.         hSprite->x -= hSprite->xmax << 16;
  365.     }
  366.     return TRUE;
  367.  
  368. } /* SetSpriteX */
  369.  
  370. /*
  371.  * GetSpriteX
  372.  */
  373. LONG GetSpriteX( HSPRITE *hSprite )
  374. {
  375.     return hSprite->x;
  376.  
  377. } /* GetSpriteX */
  378.  
  379. /*
  380.  * SetSpriteY
  381.  */
  382. BOOL SetSpriteY ( HSPRITE *hSprite, LONG y, POSITION position )
  383. {
  384.     if( hSprite->active == FALSE )
  385.     {
  386.         return FALSE;
  387.     }
  388.  
  389.     if( position == P_AUTOMATIC )
  390.     {
  391.         hSprite->yv += hSprite->ya;
  392.         hSprite->y  += hSprite->yv;
  393.     }
  394.     else if( position == P_ABSOLUTE )
  395.     {
  396.         hSprite->y = y;
  397.     }
  398.     else if( position == P_RELATIVE )
  399.     {
  400.         hSprite->y += y;
  401.     }
  402.  
  403.     if( hSprite->y < 0 )
  404.     {
  405.         hSprite->y += hSprite->ymax << 16;
  406.     }
  407.     else if( hSprite->y >= hSprite->ymax << 16 )
  408.     {
  409.         hSprite->y -= hSprite->ymax << 16;
  410.     }
  411.  
  412.     return TRUE;
  413.  
  414. } /* SetSpriteY */
  415.  
  416. /*
  417.  * GetSpriteY
  418.  */
  419. LONG GetSpriteY( HSPRITE *hSprite )
  420. {
  421.     return hSprite->y;
  422.  
  423. } /* GetSpriteY */
  424.  
  425. /*
  426.  * SetSpriteSwitch
  427.  */
  428. BOOL SetSpriteSwitch ( HSPRITE *hSprite, LONG absSwitch, POSITION position )               
  429. {
  430.     if( position == P_ABSOLUTE )
  431.     {
  432.         hSprite->absSwitch = absSwitch;
  433.     }
  434.     else if( position == P_RELATIVE )
  435.     {
  436.         hSprite->absSwitch += absSwitch;
  437.     }
  438.     return TRUE;
  439.  
  440. } /* SetSpriteSwitch */
  441.  
  442.  
  443. /*
  444.  * IncrementSpriteSwitch
  445.  */
  446. BOOL IncrementSpriteSwitch ( HSPRITE *hSprite, LONG n )
  447. {
  448.     hSprite->relSwitch += n;
  449.     return TRUE;
  450.  
  451. } /* IncrementSpriteSwitch */
  452.  
  453. /*
  454.  * SetSpriteSwitchType
  455.  */
  456. BOOL SetSpriteSwitchType( HSPRITE *hSprite, SWITCHING switchType )
  457. {
  458.     hSprite->switchType = switchType;
  459.     hSprite->relSwitch  = 0;
  460.     return TRUE;
  461.  
  462. } /* SetSpriteSwitchType */
  463.  
  464.  
  465. /*
  466.  * GetSpriteSwitchType
  467.  */
  468. SWITCHING GetSpriteSwitchType ( HSPRITE *hSprite )
  469. {
  470.     return hSprite->switchType;
  471.  
  472. } /* GetSpriteSwitchType */
  473.  
  474. /*
  475.  * SetSpriteSwitchForward
  476.  */
  477. BOOL SetSpriteSwitchForward( HSPRITE *hSprite, BOOL switchForward )
  478. {
  479.     hSprite->switchForward = switchForward;
  480.  
  481.     return TRUE;
  482.  
  483. } /* SetSpriteSwitchForward */
  484.  
  485. /*
  486.  * GetSpriteSwitchForward
  487.  */
  488. BOOL GetSpriteSwitchForward( HSPRITE *hSprite )
  489. {
  490.     return hSprite->switchForward;
  491.  
  492. } /* GetSpriteSwitchForward */
  493.  
  494. /*
  495.  * SetSpriteSwitchDone
  496.  */
  497. BOOL SetSpriteSwitchDone( HSPRITE *hSprite, BOOL switchDone )
  498. {
  499.     hSprite->switchDone = switchDone;
  500.     return TRUE;
  501.  
  502. } /* SetSpriteSwitchDone */
  503.  
  504.  
  505. /*
  506.  * GetSpriteSwitchDone
  507.  */
  508. BOOL GetSpriteSwitchDone( HSPRITE *hSprite )
  509. {
  510.     return hSprite->switchDone;
  511.  
  512. } /* GetSpriteSwitchDone */
  513.  
  514. /*
  515.  * SetSpriteBitmap
  516.  */
  517. BOOL SetSpriteBitmap ( HSPRITE *hSprite, USHORT currentBitmap )
  518. {
  519.     USHORT c;
  520.  
  521.     c = 0;
  522.     while( (hSprite->currentAction != hSprite->hSBM[c].action) ||
  523.            (hSprite->currentDirection != hSprite->hSBM[c].direction) )
  524.     {
  525.         ++c;
  526.     }
  527.     hSprite->currentBitmap = c + currentBitmap;
  528.     return TRUE;
  529.  
  530. } /* SetSpriteBitmap */
  531.  
  532. /*
  533.  * GetSpriteBitmap
  534.  */
  535. USHORT GetSpriteBitmap( HSPRITE *hSprite )
  536. {
  537.     USHORT count;
  538.  
  539.     count = 0;
  540.     while( (hSprite->currentAction != hSprite->hSBM[count].action) ||
  541.            (hSprite->currentDirection != hSprite->hSBM[count].direction) )
  542.     {
  543.         ++count;
  544.     }
  545.     return hSprite->currentBitmap - count;
  546.  
  547. } /* GetSpriteBitmap */
  548.  
  549. /*
  550.  * advanceSpriteBitmap
  551.  */
  552. static BOOL advanceSpriteBitmap( HSPRITE *hSprite )
  553. {
  554.     SHORT    c;
  555.     SHORT    n;
  556.     ACTION    curAct;
  557.     ACTION    act;
  558.     DIRECTION    curDir;
  559.     DIRECTION    dir;
  560.  
  561.     curAct = hSprite->currentAction;
  562.     curDir = hSprite->currentDirection;
  563.  
  564.     //
  565.     // See if we're cycling forward or backward though the images.
  566.     //
  567.     if( hSprite->switchForward ) // Are we cycling forward?
  568.     {
  569.         c   = hSprite->currentBitmap + 1;
  570.  
  571.         // Does the next image exceed the number of images we have?
  572.         if( c >= hSprite->bitmapCount )
  573.         {
  574.             // if the next image is past the end of the list,
  575.             // we need to set it to the start of the series.
  576.             SetSpriteBitmap( hSprite, 0 );
  577.             c   = hSprite->currentBitmap;
  578.         }
  579.         else
  580.         {
  581.             act = hSprite->hSBM[c].action;
  582.             dir = hSprite->hSBM[c].direction;
  583.  
  584.             // By examining the action and direction fields we can tell
  585.             // if we've past the current series of images and entered 
  586.             // another series.
  587.             if( (curAct != act) || (curDir != dir) )
  588.             {
  589.                     SetSpriteBitmap( hSprite, 0 );
  590.             } 
  591.             else // We're still in the series, use the next image.
  592.             {
  593.                 hSprite->currentBitmap = c;
  594.             }
  595.         }
  596.     }
  597.     else //cycling backwards
  598.     {
  599.         c   = hSprite->currentBitmap - 1;
  600.  
  601.         if( c < 0 ) // Is the next image past the beginning of the list?
  602.         {
  603.             n = 0;
  604.             
  605.             // Find the last bitmap in the series
  606.             while( (n <= hSprite->bitmapCount) &&
  607.                    (curAct == hSprite->hSBM[n].action) &&
  608.                    (curDir == hSprite->hSBM[n].direction) )
  609.             {
  610.                 ++n;                
  611.             }
  612.  
  613.             hSprite->currentBitmap = n - 1;
  614.         }
  615.  
  616.         else
  617.         {
  618.             act = hSprite->hSBM[c].action;
  619.             dir = hSprite->hSBM[c].direction;
  620.             // Is the next image past the of the series
  621.             if( (curAct != act) || (curDir != dir) ) 
  622.             {
  623.                 n = c + 1;
  624.                 while( (n <= hSprite->bitmapCount) &&
  625.                        (curAct == hSprite->hSBM[n].action) &&
  626.                        (curDir == hSprite->hSBM[n].direction) )
  627.                 {
  628.                     ++n;                
  629.                 }
  630.  
  631.                 hSprite->currentBitmap = n - 1;
  632.             }
  633.             else  // The next image is fine, use it.
  634.             {
  635.                 hSprite->currentBitmap = c;
  636.             }
  637.         }
  638.     }
  639.     return TRUE;
  640.  
  641. } /* advanceSpriteBitmap */
  642.  
  643. /*
  644.  * DisplaySprite
  645.  */
  646. BOOL DisplaySprite ( GFX_HBM hBuffer, HSPRITE *hSprite, LONG xPlane )
  647. {
  648.     USHORT    count;
  649.     SHORT    left;
  650.     SHORT    right;
  651.     SHORT    shortx;
  652.     SHORT    shorty;
  653.     SHORT    planex;
  654.     POINT       src;
  655.     RECT        dst;
  656.  
  657.     if( hSprite->active == FALSE )
  658.     {
  659.         return FALSE;
  660.     }
  661.  
  662.     count = hSprite->currentBitmap;
  663.     shortx = (SHORT) (hSprite->x >> 16);
  664.     shorty = (SHORT) (hSprite->y >> 16);
  665.     planex = (SHORT) (xPlane >> 16);
  666.     src.x = 0;
  667.     src.y = 0;
  668.  
  669.     if( shortx < planex - C_SCREEN_W )
  670.     {
  671.         shortx += hSprite->xmax;
  672.     }
  673.     else if( shortx >= planex + C_SCREEN_W )
  674.     {
  675.         shortx -= hSprite->xmax;
  676.     }
  677.  
  678.     left = shortx - planex;
  679.     
  680.     if( hSprite->currentDirection == RIGHT )
  681.     {
  682.         left += hSprite->hSBM[count].x;
  683.     }
  684.     else
  685.     {
  686.         left += hSprite->width - hSprite->hSBM[count].x - hSprite->hSBM[count].width;
  687.     }
  688.  
  689.     right = left + hSprite->hSBM[count].width;
  690.  
  691.     if( left > C_SCREEN_W )
  692.     {
  693.         left = C_SCREEN_W;
  694.     }
  695.     else if( left < 0 )
  696.     {
  697.         src.x = -left;
  698.         left = 0;
  699.     }
  700.  
  701.     if( right > C_SCREEN_W )
  702.     {
  703.         right = C_SCREEN_W;
  704.     }
  705.     else if( right < 0 )
  706.     {
  707.         right = 0;
  708.     }
  709.  
  710.     dst.left   = left;
  711.     dst.right  = right;
  712.     dst.top    = shorty + hSprite->hSBM[count].y;
  713.     dst.bottom = dst.top + hSprite->hSBM[count].height;
  714.  
  715.     gfxBlt(&dst,hSprite->hSBM[count].hBM,&src);
  716.  
  717.     if( hSprite->switchType == HOR )
  718.     {
  719.         hSprite->relSwitch += abs(hSprite->xv);
  720.  
  721.         if( hSprite->relSwitch >= hSprite->absSwitch )
  722.     {
  723.             hSprite->relSwitch = 0;
  724.             advanceSpriteBitmap( hSprite );
  725.         }
  726.     }
  727.     else if( hSprite->switchType == VER )
  728.     {
  729.         hSprite->relSwitch += abs(hSprite->yv);
  730.  
  731.         if( hSprite->relSwitch >= hSprite->absSwitch )
  732.         {
  733.             hSprite->relSwitch = 0;
  734.             advanceSpriteBitmap( hSprite );
  735.  
  736.             if( GetSpriteBitmap( hSprite ) == 0 )
  737.             {
  738.                 SetSpriteSwitchDone( hSprite, TRUE );
  739.             }
  740.         }
  741.     }
  742.     else if( hSprite->switchType == TIME )
  743.     {
  744.         hSprite->relSwitch += C_UNIT;
  745.  
  746.         if( hSprite->relSwitch >= hSprite->absSwitch )
  747.         {
  748.             hSprite->relSwitch = 0;
  749.             advanceSpriteBitmap( hSprite );
  750.             
  751.             if( GetSpriteBitmap( hSprite ) == 0 )
  752.             {
  753.                 SetSpriteSwitchDone( hSprite, TRUE );
  754.             }
  755.         }
  756.     }
  757.  
  758.     return TRUE;
  759.  
  760. } /* DisplaySprite */
  761.  
  762. /*
  763.  * DestroySprite
  764.  */
  765. BOOL DestroySprite ( HSPRITE *hSprite )
  766. {
  767.     USHORT i;
  768.  
  769.     if( hSprite == NULL )
  770.     {
  771.         ErrorMessage( "hSprite in DestroySprite" );
  772.     }
  773.  
  774.     if( hSprite->hSBM == NULL )
  775.     {
  776.         ErrorMessage( "hSprite->hSBM in DestroySprite" );
  777.     }
  778.  
  779.     for( i = 0; i < hSprite->bitmapCount; ++i )
  780.     {
  781.         if( !gfxDestroyBitmap( hSprite->hSBM[i].hBM ) )
  782.         {
  783.             ErrorMessage( "gfxDestroyBitmap (hBM) in DestroySprite" );
  784.         }
  785.     }
  786.  
  787.     MemFree( hSprite->hSBM );
  788.     MemFree( hSprite );
  789.  
  790.     return TRUE;
  791.  
  792. } /* DestroySprite */
  793.