2005-01-09 16:06:29 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
2004-10-15 06:06:47 +00:00
|
|
|
*
|
|
|
|
* 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$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "codecs.h"
|
|
|
|
|
|
|
|
#include "common/stream.h"
|
|
|
|
|
|
|
|
namespace Kyra {
|
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
struct CPSResource {
|
|
|
|
uint32 size;
|
|
|
|
uint16 width;
|
|
|
|
};
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
static const CPSResource CPSResourceTable[] = {
|
|
|
|
{ 64000, 320 }, { 7740, 180 }, { 46080, 320 }, { 0, 0 }
|
|
|
|
};
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
static int16 getWidthFromCPSRes(uint32 size) {
|
|
|
|
int16 c = 0;
|
|
|
|
|
|
|
|
for (; CPSResourceTable[c].size; ++c) {
|
|
|
|
if (CPSResourceTable[c].size == size)
|
|
|
|
return CPSResourceTable[c].width;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
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();
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
// lets check a bit
|
2005-05-08 21:49:52 +00:00
|
|
|
if (_cpsHeader._pal == 0x3000000) {
|
2004-11-14 20:11:22 +00:00
|
|
|
// if this was a compressed palette you should have strange graphics
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
uint8* palbuffer = new uint8[768];
|
|
|
|
assert(palbuffer);
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
bufferstream.read(palbuffer, 768 * sizeof(uint8));
|
|
|
|
|
|
|
|
_ownPalette = new Palette(palbuffer, 768);
|
|
|
|
assert(palbuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
_image = new uint8[_cpsHeader._imagesize];
|
|
|
|
assert(_image);
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
uint8* imagebuffer = &buffer[bufferstream.pos()];
|
|
|
|
assert(imagebuffer);
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2005-05-08 21:49:52 +00:00
|
|
|
if (_cpsHeader._format == 4) {
|
2004-11-14 20:11:22 +00:00
|
|
|
Compression::decode80(imagebuffer, _image);
|
2005-05-08 21:49:52 +00:00
|
|
|
} else if (_cpsHeader._format == 3) {
|
2004-11-14 20:11:22 +00:00
|
|
|
Compression::decode3(imagebuffer, _image, _cpsHeader._imagesize);
|
|
|
|
} else {
|
|
|
|
error("unknown CPS format %d", _cpsHeader._format);
|
|
|
|
}
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
int16 width = getWidthFromCPSRes(_cpsHeader._imagesize);
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2005-05-08 21:49:52 +00:00
|
|
|
if (width == -1) {
|
2004-11-14 20:11:22 +00:00
|
|
|
warning("unknown CPS width(imagesize: %d)", _cpsHeader._imagesize);
|
|
|
|
delete [] buffer;
|
|
|
|
return;
|
|
|
|
}
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
_width = (uint16)width;
|
|
|
|
_height = _cpsHeader._imagesize / _width;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
_transparency = -1;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
delete [] buffer;
|
|
|
|
}
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
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;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
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;
|
|
|
|
}
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
} else {
|
|
|
|
// oh no! we have transparency so we have a very slow copy :/
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
for (uint16 yadd = 0; yadd < _height; ++yadd) {
|
|
|
|
for (uint16 xadd = 0; xadd < copysize; ++xadd) {
|
|
|
|
if (*src == _transparency) {
|
|
|
|
++dst;
|
|
|
|
++src;
|
|
|
|
} else {
|
|
|
|
*dst++ = *src++;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
2004-11-14 20:11:22 +00:00
|
|
|
|
|
|
|
src += _width - copysize;
|
|
|
|
dst += planepitch - copysize;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
2004-11-14 20:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
if (srcwidth > _width)
|
|
|
|
srcwidth = _width;
|
|
|
|
|
|
|
|
if (copysize > srcwidth)
|
|
|
|
copysize = srcwidth;
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
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;
|
|
|
|
}
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
} else {
|
|
|
|
// oh no! we have transparency so we have a very slow copy :/
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2004-11-14 20:11:22 +00:00
|
|
|
for (uint16 yadd = 0; yadd < srcheight; ++yadd) {
|
|
|
|
for (uint16 xadd = 0; xadd < copysize; ++xadd) {
|
|
|
|
if (*src == _transparency) {
|
|
|
|
++dst;
|
|
|
|
++src;
|
|
|
|
} else {
|
|
|
|
*dst++ = *src++;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
2004-11-14 20:11:22 +00:00
|
|
|
|
|
|
|
dst += planepitch - copysize;
|
|
|
|
src += _width - copysize;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
2004-11-14 20:11:22 +00:00
|
|
|
}
|
2004-10-15 06:06:47 +00:00
|
|
|
} // end of namespace Kyra
|
|
|
|
|