Jump to content
  • Advertisement
Sign in to follow this  

my directdraw image loading and drawing class - comments please

This topic is 5055 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey all, i've just finished fixing up/recreating a class for ddraw offscreen surfaces. i had a smaller version of this setup until i *lost* my header file...dont ask, its very embarrasing. anyway, so i decided to remake it with improved functions and ease. please, take a look and let me know what you think (anything about optimizations or structure would be most appreciated, but feel free to comment on what it does). here it is:
/*Using this class you can create a surface, load an
  image and then use the Draw functions to copy all or
  sections of it to a surface.*/
class DDrawImage {
  int width, height, tilewidth, tileheight, animcount;
  ANIMVARS *animations;
  DDSURFACEDESC2 imagedesc;
  /*This loads a bitmap onto the surface "image" by filename.
    It can also initialise a transparent colour for the
    surface, and tile sizes if the image is tiled.*/
  bool CreateBMPSurface (LPDIRECTDRAW7 lpdd, char *filename,
              DWORD colourkey=RGB(255,255,255),
              int tilew=0, int tileh=0)
    HDC           hdcImage;
    HDC           hdc;
    BITMAP        bm;
    HBITMAP       hBitmap;
    DDCOLORKEY    ck;
    if (image)
    { image->Release();
      image = NULL; }
    tilewidth = tilew; tileheight = tileh;
    hBitmap = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0,
                        0, LR_LOADFROMFILE);
    hdcImage = CreateCompatibleDC(NULL);
    SelectObject(hdcImage, hBitmap);

    GetObject(hBitmap, sizeof(bm), &bm);
    width = bm.bmWidth;
    height = bm.bmHeight;
    ck.dwColorSpaceLowValue = colourkey;
    ck.dwColorSpaceHighValue = colourkey;
    ZeroMemory(&imagedesc, sizeof(imagedesc));
    imagedesc.dwSize = sizeof(imagedesc);
    imagedesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT |
    imagedesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    imagedesc.dwWidth = width;
    imagedesc.dwHeight = height;
    lpdd->CreateSurface(&imagedesc, &image, NULL);
    image->SetColorKey(DDCKEY_SRCBLT, &ck);
    if (image == NULL || hBitmap == NULL)
       return 0;

    BitBlt(hdc, 0, 0, width, height, hdcImage, 0, 0, SRCCOPY);
  /*Set Animation creates an animation based on the information
    given when the surface is created (tile sizes), and the
    parameters given in this function. All animations must be
    associated with the image that has been loaded by 
  bool SetAnimation (std::string name, int cols, int rows,
                     int cole, int rowe, int coledge)
    ANIMVARS *tempvars;

    if (animcount > 1)
    { tempvars = new ANIMVARS[animcount-1];
      for (int i = 0; i < animcount-1; ++i)
      { tempvars = animations; } }
    animations = new ANIMVARS[animcount];
    for (int i = 0; i < animcount-1; ++i)
    { animations = tempvars; }
    animations[animcount-1].animatename = name;
    animations[animcount-1].acolstart = cols;
    animations[animcount-1].arowstart = rows;
    animations[animcount-1].acolend = cole;
    animations[animcount-1].arowend = rowe;
    animations[animcount-1].acoledge = coledge;
    animations[animcount-1].currentframe = 0;
    animations[animcount-1].currentcol = cols;
    animations[animcount-1].currentrow = rows;
    animations[animcount-1].framecount = 0;
  //DRAW ALL//
  /*The DrawAll function copies the entire surface, "image",
    to the specified surface, at the specified location.*/
  bool DrawAll (LPDIRECTDRAWSURFACE7 dest, 
                int x=0, int y=0, float scale=1)
    RECT source, copyto;
    source.left = 0;
    source.top = 0;
    source.right = width;
    source.bottom = height;
    copyto.left = x;
    copyto.top = y;
    if (scale == 1)
    { copyto.right = x+width;
      copyto.bottom = y+height; }
    else if (scale == 0)
    { copyto.right = x;
      copyto.bottom = y; }
    { copyto.right = (int)(x+(width*scale));
      copyto.bottom = (int)(y+(height*scale)); }
  /*This function copies one cell of a templated image.
    The image must be initialised to have tilewidth and
    tileheight variables filled for this to work.
    Column = how many cells across, Row = how many cells down.*/
  bool DrawCell (LPDIRECTDRAWSURFACE7 dest, int column,
                int row, int x, int y, float scale=1)
    RECT from, to;
    from.left = 1+(tilewidth*column+column-1)-tilewidth;
    from.top = 1+(tileheight*row+row-1)-tileheight;
    from.right = from.left+tilewidth;
    from.bottom = from.top+tileheight;
    to.left = x;
    to.top = y;
    if (scale == 1)
    { to.right = x+tilewidth;
      to.bottom = y+tileheight; }
    else if (scale == 0)
    { to.right = x;
      to.bottom = y; }
    { to.right = (int)(x+(tilewidth*scale));
      to.bottom = (int)(y+(tileheight*scale)); }
  /*Draw Animate uses a user defined set of variables 
    to draw the next frame of animation to the specified
    surface. Framedelay tells it how long to wait between
    changing frames.*/
  int DrawAnimate (LPDIRECTDRAWSURFACE7 dest, 
                   std::string name, int x, int y,
                   int framedelay=0, float scale=1)
    int animnum = 0;
    for (int i = 0; i < animcount; ++i)
     if (name == animations.animatename)
     { animnum = i; 
       break; }
     else if (i == animcount-1)
     { return (-1); }
    RECT from, to;
    from.left = 1+(tilewidth*animations[animnum].currentcol+
    from.top = 1+(tileheight*animations[animnum].currentrow+
    from.right = from.left+tilewidth;
    from.bottom = from.top+tileheight;
    to.left = x;
    to.top = y;
    if (scale == 1)
    { to.right = x+tilewidth;
      to.bottom = y+tileheight; }
    else if (scale == 0)
    { to.right = x;
      to.bottom = y; }
    { to.right = (int)(x+(tilewidth*scale));
      to.bottom = (int)(y+(tileheight*scale)); }
    if (animations[animnum].framecount == framedelay)
     if ( ((animations[animnum].currentcol < 
            animations[animnum].acoledge) &&
           (animations[animnum].currentrow <
            animations[animnum].arowend)) ||
          ((animations[animnum].currentcol <
            animations[animnum].acolend) &&
           (animations[animnum].currentrow ==
            animations[animnum].arowend)) ) 
     { ++animations[animnum].currentcol; }
     else if (animations[animnum].currentrow < 
     { animations[animnum].currentcol = 
       ++animations[animnum].currentrow; }
      animations[animnum].currentframe = 0;
      animations[animnum].currentcol = 
      animations[animnum].currentrow = 
     animations[animnum].framecount = 0;
     return animations[animnum].currentframe;
    else { ++animations[animnum].framecount; }
  /*This frees all memory from the surface and animation
    array so that there are no memory problems.*/
  bool Free ()
   { if (image)
     { delete [] animations; animations = NULL;
       image = NULL; }

hope you think well of it :) if you want to try it out/keep it be my guest. i was kinda hoping this could be used to help some of the newer people a little too. thanks in advance for any comments [Edited by - the_moo on January 19, 2005 2:18:45 AM]

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!