scummvm/engines/simon/icons.cpp
2006-02-11 22:45:04 +00:00

230 lines
5.1 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/stdafx.h"
#include "common/file.h"
#include "simon/simon.h"
#include "simon/intern.h"
namespace Simon {
void SimonEngine::loadIconFile() {
Common::File in;
if (getPlatform() == Common::kPlatformAcorn)
in.open("ICONDATA");
else if (getPlatform() == Common::kPlatformAmiga)
in.open("icon.pkd");
else
in.open("ICON.DAT");
uint size;
if (in.isOpen() == false)
error("Can't open icons file 'ICON.DAT'");
size = in.size();
_iconFilePtr = (byte *)malloc(size);
if (_iconFilePtr == NULL)
error("Out of icon memory");
in.read(_iconFilePtr, size);
in.close();
}
// Thanks to Stuart Caie for providing the original
// C conversion upon which this function is based.
void decompress_icon_amiga (byte *dst, byte *src, byte base, uint pitch) {
byte icon_pln[288];
byte *i, *o, x, y;
// Decode RLE planar icon data
i = src;
o = icon_pln;
while (o < &icon_pln[288]) {
x = *i++;
if (x < 128) {
do {
*o++ = *i++;
*o++ = *i++;
*o++ = *i++;
} while (x-- > 0);
} else {
x = 256 - x;
do {
*o++ = i[0];
*o++ = i[1];
*o++ = i[2];
} while (x-- > 0);
i += 3;
}
}
// Translate planar data to chunky (very slow method)
for (y = 0; y < 24; y++) {
for (x = 0; x < 24; x++) {
byte pixel =
(icon_pln[(( y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 1 : 0)
| (icon_pln[((24 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 2 : 0)
| (icon_pln[((48 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 4 : 0)
| (icon_pln[((72 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 8 : 0);
if (pixel)
dst[x] = pixel | base;
}
dst += pitch;
}
}
static void decompress_icon(byte *dst, byte *src, uint w, uint h_org, byte base, uint pitch) {
int8 reps;
byte color_1, color_2;
byte *dst_org = dst;
uint h = h_org;
for (;;) {
reps = *src++;
if (reps < 0) {
reps--;
color_1 = *src >> 4;
if (color_1 != 0)
color_1 |= base;
color_2 = *src++ & 0xF;
if (color_2 != 0)
color_2 |= base;
do {
if (color_1 != 0)
*dst = color_1;
dst += pitch;
if (color_2 != 0)
*dst = color_2;
dst += pitch;
// reached bottom?
if (--h == 0) {
// reached right edge?
if (--w == 0)
return;
dst = ++dst_org;
h = h_org;
}
} while (++reps != 0);
} else {
do {
color_1 = *src >> 4;
if (color_1 != 0)
*dst = color_1 | base;
dst += pitch;
color_2 = *src++ & 0xF;
if (color_2 != 0)
*dst = color_2 | base;
dst += pitch;
// reached bottom?
if (--h == 0) {
// reached right edge?
if (--w == 0)
return;
dst = ++dst_org;
h = h_org;
}
} while (--reps >= 0);
}
}
}
void SimonEngine::draw_icon_c(FillOrCopyStruct *fcs, uint icon, uint x, uint y) {
byte *dst;
byte *src;
_lockWord |= 0x8000;
dst = dx_lock_2();
if (!(getGameType() == GType_SIMON2)) {
// Simon 1
dst += (x + fcs->x) * 8;
dst += (y * 25 + fcs->y) * _dxSurfacePitch;
if (getPlatform() == Common::kPlatformAmiga) {
src = _iconFilePtr;
src += READ_BE_UINT32(&((uint32 *)src)[icon]);
decompress_icon_amiga (dst, src, 0xE0, _dxSurfacePitch);
} else {
src = _iconFilePtr;
src += READ_LE_UINT16(&((uint16 *)src)[icon]);
decompress_icon(dst, src, 24, 12, 0xE0, _dxSurfacePitch);
}
} else {
// Simon 2
dst += 110;
dst += x;
dst += (y + fcs->y) * _dxSurfacePitch;
src = _iconFilePtr;
src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]);
decompress_icon(dst, src, 20, 10, 0xE0, _dxSurfacePitch);
src = _iconFilePtr;
src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]);
decompress_icon(dst, src, 20, 10, 0xD0, _dxSurfacePitch);
}
dx_unlock_2();
_lockWord &= ~0x8000;
}
uint SimonEngine::setup_icon_hit_area(FillOrCopyStruct *fcs, uint x, uint y, uint icon_number,
Item *item_ptr) {
HitArea *ha;
ha = findEmptyHitArea();
if (!(getGameType() == GType_SIMON2)) {
ha->x = (x + fcs->x) << 3;
ha->y = y * 25 + fcs->y;
ha->item_ptr = item_ptr;
ha->width = 24;
ha->height = 24;
ha->flags = 0xB0;
ha->id = 0x7FFD;
ha->layer = 100;
ha->unk3 = 0xD0;
} else {
ha->x = x + 110;
ha->y = fcs->y + y;
ha->item_ptr = item_ptr;
ha->width = 20;
ha->height = 20;
ha->flags = 0xB0;
ha->id = 0x7FFD;
ha->layer = 100;
ha->unk3 = 0xD0;
}
return ha - _hitAreas;
}
} // End of namespace Simon