home *** CD-ROM | disk | FTP | other *** search
- /*==========================================================================
- *
- * Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
- * Copyright (C) 1994-1995 ATI Technologies Inc. All Rights Reserved.
- *
- * File: sprite.c
- * Content: sprite manipulation functions
- *
- ***************************************************************************/
- #include "foxbear.h"
-
- /*
- * CreateSprite
- */
- HSPRITE *CreateSprite (
- USHORT bitmapCount,
- LONG x,
- LONG y,
- USHORT width,
- USHORT height,
- USHORT xmax,
- USHORT ymax,
- SHORT as,
- BOOL active )
- {
- HSPRITE *hSprite;
- USHORT i;
-
- hSprite = MemAlloc( sizeof (HSPRITE) );
- if( hSprite == NULL )
- {
- ErrorMessage( "hSprite in CreateSprite" );
- }
-
- hSprite->hSBM = CMemAlloc( bitmapCount, sizeof (HSPRITE_BM) );
- if( hSprite->hSBM == NULL )
- {
- MemFree( hSprite );
- ErrorMessage( "hSprite->hSBM in CreateSprite" );
- }
-
- hSprite->active = active;
- hSprite->bitmapCount = bitmapCount;
- hSprite->x = x;
- hSprite->y = y;
- hSprite->width = width;
- hSprite->height = height;
- hSprite->xv = 0;
- hSprite->yv = 0;
- hSprite->xa = 0;
- hSprite->ya = 0;
- hSprite->xmax = xmax;
- hSprite->ymax = ymax;
- hSprite->absSwitch = as;
- hSprite->relSwitch = 0;
- hSprite->switchType = HOR;
- hSprite->switchForward = TRUE;
- hSprite->switchDone = FALSE;
-
- for( i = 0; i < bitmapCount; ++i )
- {
- hSprite->hSBM[i].hBM = NULL;
- }
-
- return hSprite;
-
- } /* CreateSprite */
-
- /*
- * BitBltSprite
- */
- BOOL BitBltSprite (
- HSPRITE *hSprite,
- GFX_HBM hBM,
- ACTION action,
- DIRECTION direction,
- SHORT x,
- SHORT y,
- USHORT w,
- USHORT h )
- {
- USHORT count;
-
- if( hSprite == NULL )
- {
- ErrorMessage( "hSprite in BitBltSprite" );
- }
-
- if( hBM == NULL )
- {
- ErrorMessage( "hBM in BitBltSprite" );
- }
-
- if( (x >= hSprite->width) || (y >= hSprite->height) )
- {
- ErrorMessage( "x or y in BitBltSprite" );
- }
-
- count = 0;
- while( hSprite->hSBM[count].hBM != NULL )
- {
- count++;
- if( count >= hSprite->bitmapCount )
- {
- ErrorMessage( "Bitmap overflow in BitBltSprite" );
- }
- }
-
- hSprite->hSBM[count].hBM = hBM;
- hSprite->hSBM[count].action = action;
- hSprite->hSBM[count].direction = direction;
- hSprite->hSBM[count].x = x;
- hSprite->hSBM[count].y = y;
- hSprite->hSBM[count].width = w;
- hSprite->hSBM[count].height = h;
-
- return TRUE;
-
- } /* BitBltSprite */
-
- /*
- * SetSpriteAction
- */
- BOOL SetSpriteAction ( HSPRITE *hSprite, ACTION action, DIRECTION direction )
- {
- USHORT c;
-
- c = 0;
-
- if( direction == SAME )
- {
- direction = hSprite->currentDirection;
- }
-
- while( (hSprite->hSBM[c].action != action) || (hSprite->hSBM[c].direction != direction) )
- {
- ++c;
- }
-
- hSprite->currentAction = action;
- hSprite->currentDirection = direction;
- hSprite->currentBitmap = c;
- hSprite->relSwitch = 0;
-
- return TRUE;
-
- } /* SetSpriteAction */
-
- /*
- * ChangeSpriteDirection
- */
- BOOL ChangeSpriteDirection( HSPRITE *hSprite )
- {
- DIRECTION direction;
-
- if( hSprite->currentDirection == RIGHT )
- {
- direction = LEFT;
- }
- else
- {
- direction = RIGHT;
- }
-
- SetSpriteAction( hSprite, hSprite->currentAction, direction );
-
- return TRUE;
-
- } /* ChangeSpriteDirection */
-
- /*
- * GetSpriteAction
- */
- ACTION GetSpriteAction( HSPRITE *hSprite )
- {
- return hSprite->currentAction;
-
- } /* GetSpriteAction */
-
-
- /*
- * GetSpriteDirection
- */
- DIRECTION GetSpriteDirection( HSPRITE *hSprite )
- {
- return hSprite->currentDirection;
-
- } /* GetSpriteDirection */
-
- /*
- * SetSpriteActive
- */
- BOOL SetSpriteActive( HSPRITE *hSprite, BOOL active )
- {
- hSprite->active = active;
-
- if( active == FALSE )
- {
- hSprite->xv = 0;
- hSprite->yv = 0;
- hSprite->xa = 0;
- hSprite->ya = 0;
- }
-
- return TRUE;
-
- } /* SetSpriteActive */
-
- /*
- * GetSpriteActive
- */
- BOOL GetSpriteActive( HSPRITE *hSprite )
- {
- return hSprite->active;
-
- } /* GetSpriteActive */
-
- /*
- * SetSpriteVelX
- */
- BOOL SetSpriteVelX( HSPRITE *hSprite, LONG xv, POSITION position )
- {
- if( hSprite->active == FALSE )
- {
- return FALSE;
- }
-
- if( position == P_ABSOLUTE )
- {
- hSprite->xv = xv;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->xv += xv;
- }
-
- return TRUE;
-
- } /* SetSpriteVelX */
-
- /*
- * GetSpriteVelX
- */
- LONG GetSpriteVelX( HSPRITE *hSprite )
- {
- return hSprite->xv;
-
- } /* GetSpriteVelX */
-
- /*
- * SetSpriteVelY
- */
- BOOL SetSpriteVelY( HSPRITE *hSprite, LONG yv, POSITION position )
- {
- if( hSprite->active == FALSE )
- {
- return FALSE;
- }
-
- if( position == P_ABSOLUTE )
- {
- hSprite->yv = yv;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->yv += yv;
- }
-
- return TRUE;
-
- } /* SetSpriteVelY */
-
- /*
- * GetSpriteVelY
- */
- LONG GetSpriteVelY( HSPRITE *hSprite )
- {
- return hSprite->yv;
-
- } /* GetSpriteVelY */
-
- /*
- * SetSpriteAccX
- */
- BOOL SetSpriteAccX ( HSPRITE *hSprite, LONG xa, POSITION position )
- {
- if( position == P_ABSOLUTE )
- {
- hSprite->xa = xa;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->xa += xa;
- }
- return TRUE;
-
- } /* SetSpriteAccX */
-
- /*
- * GetSpriteAccX
- */
- LONG GetSpriteAccX( HSPRITE *hSprite )
- {
- return hSprite->xa;
-
- } /* GetSpriteAccX */
-
- /*
- * SetSpriteAccY
- */
- BOOL SetSpriteAccY ( HSPRITE *hSprite, LONG ya, POSITION position )
- {
- if( position == P_ABSOLUTE )
- {
- hSprite->ya = ya;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->ya += ya;
- }
- return TRUE;
-
- } /* SetSpriteAccY */
-
- /*
- * GetSpriteAccY
- */
- LONG GetSpriteAccY( HSPRITE *hSprite )
- {
- return hSprite->ya;
-
- } /* GetSpriteAccY */
-
- /*
- * SetSpriteX
- */
- BOOL SetSpriteX( HSPRITE *hSprite, LONG x, POSITION position )
- {
- if( hSprite->active == FALSE )
- {
- return FALSE;
- }
-
- if( position == P_AUTOMATIC )
- {
- hSprite->xv += hSprite->xa;
- hSprite->x += hSprite->xv;
- }
- else if( position == P_ABSOLUTE )
- {
- hSprite->x = x;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->x += x;
- }
-
- if( hSprite->x < 0 )
- {
- hSprite->x += hSprite->xmax << 16;
- }
- else if( hSprite->x >= hSprite->xmax << 16 )
- {
- hSprite->x -= hSprite->xmax << 16;
- }
- return TRUE;
-
- } /* SetSpriteX */
-
- /*
- * GetSpriteX
- */
- LONG GetSpriteX( HSPRITE *hSprite )
- {
- return hSprite->x;
-
- } /* GetSpriteX */
-
- /*
- * SetSpriteY
- */
- BOOL SetSpriteY ( HSPRITE *hSprite, LONG y, POSITION position )
- {
- if( hSprite->active == FALSE )
- {
- return FALSE;
- }
-
- if( position == P_AUTOMATIC )
- {
- hSprite->yv += hSprite->ya;
- hSprite->y += hSprite->yv;
- }
- else if( position == P_ABSOLUTE )
- {
- hSprite->y = y;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->y += y;
- }
-
- if( hSprite->y < 0 )
- {
- hSprite->y += hSprite->ymax << 16;
- }
- else if( hSprite->y >= hSprite->ymax << 16 )
- {
- hSprite->y -= hSprite->ymax << 16;
- }
-
- return TRUE;
-
- } /* SetSpriteY */
-
- /*
- * GetSpriteY
- */
- LONG GetSpriteY( HSPRITE *hSprite )
- {
- return hSprite->y;
-
- } /* GetSpriteY */
-
- /*
- * SetSpriteSwitch
- */
- BOOL SetSpriteSwitch ( HSPRITE *hSprite, LONG absSwitch, POSITION position )
- {
- if( position == P_ABSOLUTE )
- {
- hSprite->absSwitch = absSwitch;
- }
- else if( position == P_RELATIVE )
- {
- hSprite->absSwitch += absSwitch;
- }
- return TRUE;
-
- } /* SetSpriteSwitch */
-
-
- /*
- * IncrementSpriteSwitch
- */
- BOOL IncrementSpriteSwitch ( HSPRITE *hSprite, LONG n )
- {
- hSprite->relSwitch += n;
- return TRUE;
-
- } /* IncrementSpriteSwitch */
-
- /*
- * SetSpriteSwitchType
- */
- BOOL SetSpriteSwitchType( HSPRITE *hSprite, SWITCHING switchType )
- {
- hSprite->switchType = switchType;
- hSprite->relSwitch = 0;
- return TRUE;
-
- } /* SetSpriteSwitchType */
-
-
- /*
- * GetSpriteSwitchType
- */
- SWITCHING GetSpriteSwitchType ( HSPRITE *hSprite )
- {
- return hSprite->switchType;
-
- } /* GetSpriteSwitchType */
-
- /*
- * SetSpriteSwitchForward
- */
- BOOL SetSpriteSwitchForward( HSPRITE *hSprite, BOOL switchForward )
- {
- hSprite->switchForward = switchForward;
-
- return TRUE;
-
- } /* SetSpriteSwitchForward */
-
- /*
- * GetSpriteSwitchForward
- */
- BOOL GetSpriteSwitchForward( HSPRITE *hSprite )
- {
- return hSprite->switchForward;
-
- } /* GetSpriteSwitchForward */
-
- /*
- * SetSpriteSwitchDone
- */
- BOOL SetSpriteSwitchDone( HSPRITE *hSprite, BOOL switchDone )
- {
- hSprite->switchDone = switchDone;
- return TRUE;
-
- } /* SetSpriteSwitchDone */
-
-
- /*
- * GetSpriteSwitchDone
- */
- BOOL GetSpriteSwitchDone( HSPRITE *hSprite )
- {
- return hSprite->switchDone;
-
- } /* GetSpriteSwitchDone */
-
- /*
- * SetSpriteBitmap
- */
- BOOL SetSpriteBitmap ( HSPRITE *hSprite, USHORT currentBitmap )
- {
- USHORT c;
-
- c = 0;
- while( (hSprite->currentAction != hSprite->hSBM[c].action) ||
- (hSprite->currentDirection != hSprite->hSBM[c].direction) )
- {
- ++c;
- }
- hSprite->currentBitmap = c + currentBitmap;
- return TRUE;
-
- } /* SetSpriteBitmap */
-
- /*
- * GetSpriteBitmap
- */
- USHORT GetSpriteBitmap( HSPRITE *hSprite )
- {
- USHORT count;
-
- count = 0;
- while( (hSprite->currentAction != hSprite->hSBM[count].action) ||
- (hSprite->currentDirection != hSprite->hSBM[count].direction) )
- {
- ++count;
- }
- return hSprite->currentBitmap - count;
-
- } /* GetSpriteBitmap */
-
- /*
- * advanceSpriteBitmap
- */
- static BOOL advanceSpriteBitmap( HSPRITE *hSprite )
- {
- SHORT c;
- SHORT n;
- ACTION curAct;
- ACTION act;
- DIRECTION curDir;
- DIRECTION dir;
-
- curAct = hSprite->currentAction;
- curDir = hSprite->currentDirection;
-
- //
- // See if we're cycling forward or backward though the images.
- //
- if( hSprite->switchForward ) // Are we cycling forward?
- {
- c = hSprite->currentBitmap + 1;
-
- // Does the next image exceed the number of images we have?
- if( c >= hSprite->bitmapCount )
- {
- // if the next image is past the end of the list,
- // we need to set it to the start of the series.
- SetSpriteBitmap( hSprite, 0 );
- c = hSprite->currentBitmap;
- }
- else
- {
- act = hSprite->hSBM[c].action;
- dir = hSprite->hSBM[c].direction;
-
- // By examining the action and direction fields we can tell
- // if we've past the current series of images and entered
- // another series.
- if( (curAct != act) || (curDir != dir) )
- {
- SetSpriteBitmap( hSprite, 0 );
- }
- else // We're still in the series, use the next image.
- {
- hSprite->currentBitmap = c;
- }
- }
- }
- else //cycling backwards
- {
- c = hSprite->currentBitmap - 1;
-
- if( c < 0 ) // Is the next image past the beginning of the list?
- {
- n = 0;
-
- // Find the last bitmap in the series
- while( (n <= hSprite->bitmapCount) &&
- (curAct == hSprite->hSBM[n].action) &&
- (curDir == hSprite->hSBM[n].direction) )
- {
- ++n;
- }
-
- hSprite->currentBitmap = n - 1;
- }
-
- else
- {
- act = hSprite->hSBM[c].action;
- dir = hSprite->hSBM[c].direction;
- // Is the next image past the of the series
- if( (curAct != act) || (curDir != dir) )
- {
- n = c + 1;
- while( (n <= hSprite->bitmapCount) &&
- (curAct == hSprite->hSBM[n].action) &&
- (curDir == hSprite->hSBM[n].direction) )
- {
- ++n;
- }
-
- hSprite->currentBitmap = n - 1;
- }
- else // The next image is fine, use it.
- {
- hSprite->currentBitmap = c;
- }
- }
- }
- return TRUE;
-
- } /* advanceSpriteBitmap */
-
- /*
- * DisplaySprite
- */
- BOOL DisplaySprite ( GFX_HBM hBuffer, HSPRITE *hSprite, LONG xPlane )
- {
- USHORT count;
- SHORT left;
- SHORT right;
- SHORT shortx;
- SHORT shorty;
- SHORT planex;
- POINT src;
- RECT dst;
-
- if( hSprite->active == FALSE )
- {
- return FALSE;
- }
-
- count = hSprite->currentBitmap;
- shortx = (SHORT) (hSprite->x >> 16);
- shorty = (SHORT) (hSprite->y >> 16);
- planex = (SHORT) (xPlane >> 16);
- src.x = 0;
- src.y = 0;
-
- if( shortx < planex - C_SCREEN_W )
- {
- shortx += hSprite->xmax;
- }
- else if( shortx >= planex + C_SCREEN_W )
- {
- shortx -= hSprite->xmax;
- }
-
- left = shortx - planex;
-
- if( hSprite->currentDirection == RIGHT )
- {
- left += hSprite->hSBM[count].x;
- }
- else
- {
- left += hSprite->width - hSprite->hSBM[count].x - hSprite->hSBM[count].width;
- }
-
- right = left + hSprite->hSBM[count].width;
-
- if( left > C_SCREEN_W )
- {
- left = C_SCREEN_W;
- }
- else if( left < 0 )
- {
- src.x = -left;
- left = 0;
- }
-
- if( right > C_SCREEN_W )
- {
- right = C_SCREEN_W;
- }
- else if( right < 0 )
- {
- right = 0;
- }
-
- dst.left = left;
- dst.right = right;
- dst.top = shorty + hSprite->hSBM[count].y;
- dst.bottom = dst.top + hSprite->hSBM[count].height;
-
- gfxBlt(&dst,hSprite->hSBM[count].hBM,&src);
-
- if( hSprite->switchType == HOR )
- {
- hSprite->relSwitch += abs(hSprite->xv);
-
- if( hSprite->relSwitch >= hSprite->absSwitch )
- {
- hSprite->relSwitch = 0;
- advanceSpriteBitmap( hSprite );
- }
- }
- else if( hSprite->switchType == VER )
- {
- hSprite->relSwitch += abs(hSprite->yv);
-
- if( hSprite->relSwitch >= hSprite->absSwitch )
- {
- hSprite->relSwitch = 0;
- advanceSpriteBitmap( hSprite );
-
- if( GetSpriteBitmap( hSprite ) == 0 )
- {
- SetSpriteSwitchDone( hSprite, TRUE );
- }
- }
- }
- else if( hSprite->switchType == TIME )
- {
- hSprite->relSwitch += C_UNIT;
-
- if( hSprite->relSwitch >= hSprite->absSwitch )
- {
- hSprite->relSwitch = 0;
- advanceSpriteBitmap( hSprite );
-
- if( GetSpriteBitmap( hSprite ) == 0 )
- {
- SetSpriteSwitchDone( hSprite, TRUE );
- }
- }
- }
-
- return TRUE;
-
- } /* DisplaySprite */
-
- /*
- * DestroySprite
- */
- BOOL DestroySprite ( HSPRITE *hSprite )
- {
- USHORT i;
-
- if( hSprite == NULL )
- {
- ErrorMessage( "hSprite in DestroySprite" );
- }
-
- if( hSprite->hSBM == NULL )
- {
- ErrorMessage( "hSprite->hSBM in DestroySprite" );
- }
-
- for( i = 0; i < hSprite->bitmapCount; ++i )
- {
- if( !gfxDestroyBitmap( hSprite->hSBM[i].hBM ) )
- {
- ErrorMessage( "gfxDestroyBitmap (hBM) in DestroySprite" );
- }
- }
-
- MemFree( hSprite->hSBM );
- MemFree( hSprite );
-
- return TRUE;
-
- } /* DestroySprite */
-