#include "include\sprite.h"

int InitSprite(struct Sprite *thisSpr, int w, int h,
               int numFrames, int dynamic, int drtyRect)
{
  int i, retVal = 1;

  if (w > 0) {
    thisSpr->width = w;
    if (h > 0) thisSpr->height = h;
  }

  thisSpr->imgDynamic = dynamic;
  if (numFrames > 0) {
    thisSpr->frames=(char far **)malloc(numFrames*sizeof(char far *));
    if (thisSpr->frames != NULL) {
      thisSpr->noOfFrames = numFrames;
      for (i=0; i 0 && h > 0) {
          thisSpr->frames[i]=(char far *)farmalloc(w*h*sizeof(char));
          if (thisSpr->frames[i] == NULL) retVal = 0;
        } else
          thisSpr->frames[i] = NULL;
    } else
      retVal = 0;
  } else
    thisSpr->frames = NULL;

  if (drtyRect) {
    thisSpr->background = (char far *)farmalloc(w * h * sizeof(char));
    if (thisSpr->background == NULL && w && h) retVal = 0;
    thisSpr->backTransparent = 1;
  } else
    thisSpr->background = NULL;

  thisSpr->maxX = ScreenWidth - 1;
  thisSpr->maxY = ScreenHeight - 1;

  thisSpr->lenXcopy = thisSpr->width;
  thisSpr->lenYcopy = thisSpr->height;

  thisSpr->displayMem = videoMem;

  thisSpr->X = thisSpr->Y = thisSpr->lastX = thisSpr->lastY =
  thisSpr->minX = thisSpr->minY = thisSpr->startXoff = thisSpr->startYoff =
  thisSpr->currFrame = thisSpr->status = thisSpr->visible = thisSpr->clock =
  thisSpr->animThreshold = thisSpr->moveThreshold = 0;

  thisSpr->otherData = NULL;
  if (!retVal) DestroySprite(thisSpr);
  return retVal;
}

void DestroySprite(struct Sprite *thisSpr)
{
    int i;

    if (thisSpr->background != NULL)
        farfree(thisSpr->background);

    if (thisSpr->frames != NULL) {
        for (i=0; inoOfFrames; i++)
            if (thisSpr->imgDynamic && thisSpr->frames[i] != NULL)
                farfree(thisSpr->frames[i]);
        free(thisSpr->frames);
    }
}

void SpriteShow(struct Sprite *thisSpr)
{
    char far *src, far *dest;
    int i, t;

    if (thisSpr->visible || thisSpr->frames == NULL ||
        thisSpr->frames[thisSpr->currFrame] == NULL) return;

    if (thisSpr->background != NULL && thisSpr->width && thisSpr->height) {
        /* Copy background before drawing sprite */
        src  = &thisSpr->displayMem[(thisSpr->Y<<8)+(thisSpr->Y<<6)+thisSpr->X];
        dest = thisSpr->background;
        for (i=0; iheight; i++) {
            _fmemcpy(dest, src, thisSpr->width);
            src  += ScreenWidth;
            dest += thisSpr->width;
        }
    }

    if (thisSpr->width && thisSpr->height) {
        /* Prepare to copy the sprite's image to the screen */
        src  = thisSpr->frames[thisSpr->currFrame];
        dest = &thisSpr->displayMem[(thisSpr->Y<<8)+(thisSpr->Y<<6)+thisSpr->X];
        if (thisSpr->backTransparent) {
            /* Copy the image, accounting for transparency */
            for (i=0; iheight; i++) {
                for (t=0; twidth; t++)
                     if (src[t]) dest[t] = src[t];
                src  += thisSpr->width;
                dest += ScreenWidth;
            }
        } else {
            /* Copy all pixels, even transparent ones */
            for (i=0; iheight; i++) {
                _fmemcpy(dest, src, thisSpr->width);
                src  += thisSpr->width;
                dest += ScreenWidth;
            }
        }
    }
    thisSpr->visible = 1;  /* Flag the sprite as visible */
}

void SpriteHide(struct Sprite *thisSpr)
{
    int i;
    char far *src, far *dest;

    /* If sprite is not visible, quit */
    if (!thisSpr->visible) return;

    /* If there is no background buffer, skip */
    if (thisSpr->background != NULL && thisSpr->width && thisSpr->height) {
        /* Start the copying */
        src  = thisSpr->background;
        dest = &thisSpr->displayMem[(thisSpr->Y<<8)+(thisSpr->Y<<6)+thisSpr->X];
        for (i=0; iheight; i++) {
            _fmemcpy(dest, src, thisSpr->width);
            src  += thisSpr->width;
            dest += ScreenWidth;
        }
    }
    /* Flag sprite as not visible */
    thisSpr->visible = 0;
}

void SpriteSetImage(struct Sprite *thisSpr, void far *bitmap, int fraNum)
{
    if (fraNum < 0) fraNum = thisSpr->currFrame;
    else fraNum %= thisSpr->noOfFrames;

    if (thisSpr->imgDynamic) {
        if (thisSpr->frames[fraNum] != NULL)
            _fmemcpy(thisSpr->frames[fraNum], bitmap, thisSpr->width * thisSpr->height);
    } else
        thisSpr->frames[fraNum] = (char far *)bitmap;

     if (thisSpr->visible && thisSpr->currFrame == fraNum) {
        SpriteHide(thisSpr);
        SpriteShow(thisSpr);
    }
}

int SpriteRedimension(struct Sprite *thisSpr, int w, int h, int drtyRect)
{
    int i, Success = 1;
    char far *temp;

    SpriteHide(thisSpr);  /* Hide, because we lose images */
    if (w < 0) w = 0;
    if (h < 0) h = 0;
    if (w && h) {
        if (drtyRect) {
            temp = (char far *)farmalloc(w * h * sizeof(char));
            if (temp != NULL) {
                if (thisSpr->background != NULL) farfree(thisSpr->background);
                thisSpr->background = temp;
            } else Success = 0;
        } else {
            if (thisSpr->background != NULL) farfree(thisSpr->background);
            thisSpr->background = NULL;
        }
        for (i=0; inoOfFrames; i++) {
          if (thisSpr->imgDynamic) {
            temp = (char far *)farmalloc(w * h * sizeof(char));
            if (temp != NULL) {
                if (thisSpr->frames[i] != NULL) farfree(thisSpr->frames[i]);
                thisSpr->frames[i] = temp;
            } else {
              thisSpr->frames[i] = NULL;
              Success = 0;
            }
          } else thisSpr->frames[i] = NULL;
        }
    } else {
        if (thisSpr->background != NULL) farfree(thisSpr->background);
        thisSpr->background = NULL;
        for (i=0; inoOfFrames; i++) {
            if (thisSpr->imgDynamic && thisSpr->frames[i] != NULL) farfree(thisSpr->frames[i]);
            thisSpr->frames[i] = NULL;
        }
    }
    if (Success) {thisSpr->width = w; thisSpr->height = h;}
    return Success;
}

int SpriteChangeNumFrames(struct Sprite *thisSpr, int numFrames)
{
    int i, Success = 1;
    char far **temp;

    /* Don't waste time */
    if (numFrames == thisSpr->noOfFrames || numFrames < 0) return Success;

    SpriteHide(thisSpr);  /* Hide incase we lose sprite images */
    thisSpr->currFrame = 0;

    /* Let's not lose pointers and waste memory */
    if (numFrames < thisSpr->noOfFrames) {
        for (i=numFrames; inoOfFrames; i++) {
            if (thisSpr->imgDynamic && thisSpr->frames[i] != NULL) farfree(thisSpr->frames[i]);
            thisSpr->frames[i] = NULL;
        }
    }
    temp = (char far **)realloc(thisSpr->frames, numFrames * sizeof(char far *));
    if (temp != NULL) {
        thisSpr->frames = temp;
        if (numFrames > thisSpr->noOfFrames)  /* What, more pointers??!! */
            for (i=thisSpr->noOfFrames; iimgDynamic && thisSpr->width > 0 && thisSpr->height > 0) {
                    thisSpr->frames[i]=(char far *)farmalloc(thisSpr->width*thisSpr->height*sizeof(char));
                    if (thisSpr->frames[i] == NULL) Success = 0;
                } else thisSpr->frames[i] = NULL;
            }
        thisSpr->noOfFrames = numFrames;
    } else Success = 0;

    return Success;
}

    Source: geocities.com/garyneal_71/OldPages

               ( geocities.com/garyneal_71)