Logo Search packages:      
Sourcecode: scummvm version File versions

cpsimage.cpp

/* ScummVM - Kyrandia Interpreter
 * Copyright (C) 2003-2004 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/kyra/cpsimage.cpp,v 1.3 2004/11/14 20:11:22 sev Exp $
 *
 */

#include "stdafx.h"
#include "resource.h"
#include "codecs.h"

#include "common/stream.h"

namespace Kyra {

struct CPSResource {
      uint32 size;
      uint16 width;
};

static const CPSResource CPSResourceTable[] = {
      { 64000, 320 }, { 7740, 180 }, { 46080, 320 }, { 0, 0 }
};
      
static int16 getWidthFromCPSRes(uint32 size) {
      int16 c = 0;

      for (; CPSResourceTable[c].size; ++c) {
            if (CPSResourceTable[c].size == size)
                  return CPSResourceTable[c].width;
      }

      return -1;
}

CPSImage::CPSImage(uint8* buffer, uint32 size) {
      if (!buffer) {
            error("resource created without data");
      }
      _ownPalette = 0;
      Common::MemoryReadStream bufferstream(buffer, size);
      
      // reads in the Header
      _cpsHeader._filesize = bufferstream.readUint16LE() + 2;
      _cpsHeader._format = bufferstream.readUint16LE();
      _cpsHeader._imagesize = bufferstream.readUint16LE();
      _cpsHeader._pal = bufferstream.readUint32LE();
            
      // lets check a bit
      if(_cpsHeader._pal == 0x3000000) {
            // if this was a compressed palette you should have strange graphics
                  
            uint8* palbuffer = new uint8[768];
            assert(palbuffer);
            
            bufferstream.read(palbuffer, 768 * sizeof(uint8));
                  
            _ownPalette = new Palette(palbuffer, 768);
            assert(palbuffer);
      }
      
      _image = new uint8[_cpsHeader._imagesize];
      assert(_image);
            
      uint8* imagebuffer = &buffer[bufferstream.pos()];
      assert(imagebuffer);
            
      if(_cpsHeader._format == 4) {
            Compression::decode80(imagebuffer, _image);
      } else if(_cpsHeader._format == 3) {
            Compression::decode3(imagebuffer, _image, _cpsHeader._imagesize);
      } else {
            error("unknown CPS format %d", _cpsHeader._format);
      }
            
      int16 width = getWidthFromCPSRes(_cpsHeader._imagesize);
            
      if(width == -1) {
            warning("unknown CPS width(imagesize: %d)", _cpsHeader._imagesize);
            delete [] buffer;
            return;
      }
            
      _width = (uint16)width;
      _height = _cpsHeader._imagesize / _width;
            
      _transparency = -1;
            
      delete [] buffer;
}
      
CPSImage::~CPSImage() {
      delete [] _image;
      delete _ownPalette;
}
      
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y) {
      uint8* src = _image;
      uint8* dst = &plane[y * planepitch + x];
      uint32 copysize = planepitch - x;
      
      if (copysize > _width)
            copysize = _width;
      
      if (_transparency == -1) {
            // 'fast' blitting
            for (uint16 y_ = 0; y_ < _height && y + y_ < planeheight; ++y_) {
                  memcpy(dst, src, copysize * sizeof(uint8));
                  dst += planepitch;
                  src += _width;
            }
            
      } else {
            // oh no! we have transparency so we have a very slow copy :/
            
            for (uint16 yadd = 0; yadd < _height; ++yadd) {
                  for (uint16 xadd = 0; xadd < copysize; ++xadd) {
                        if (*src == _transparency) {
                              ++dst;
                              ++src;
                        } else {
                              *dst++ = *src++;
                        }
                  }
                  
                  src += _width - copysize;
                  dst += planepitch - copysize;
            }
      }
}
      
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
                                          uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight) {
      uint8* src = &_image[srcy * _width + srcx];
      uint8* dst = &plane[y * planepitch + x];
      uint32 copysize = planepitch - x;
      
      if (srcwidth > _width)
            srcwidth = _width;
      
      if (copysize > srcwidth)
            copysize = srcwidth;
            
      if (_transparency == -1) {
            // 'fast' blitting
            for (uint16 y_ = 0; y_ < srcheight && y + y_ < planeheight; ++y_) {
                  memcpy(dst, src, copysize * sizeof(uint8));
                  dst += planepitch;
                  src += _width;
            }
            
      } else {
            // oh no! we have transparency so we have a very slow copy :/
            
            for (uint16 yadd = 0; yadd < srcheight; ++yadd) {
                  for (uint16 xadd = 0; xadd < copysize; ++xadd) {
                        if (*src == _transparency) {
                              ++dst;
                              ++src;
                        } else {
                              *dst++ = *src++;
                        }
                  }
                  
                  dst += planepitch - copysize;
                  src += _width - copysize;
            }
      }
}
} // end of namespace Kyra


Generated by  Doxygen 1.6.0   Back to index