/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 #include #include "icon.h" void Icon::create_vmicon(void *buffer) { unsigned short *pal = (unsigned short *)buffer; unsigned char *pix = ((unsigned char *)buffer)+32; for(int n = 0; n<16; n++) { int p = palette[n]; pal[n] = ((p>>16)&0xf000)| ((p>>12)&0x0f00)| ((p>> 8)&0x00f0)| ((p>> 4)&0x000f); } for(int line = 0; line < 32; line++) { memcpy(pix, &bitmap[32/2*(31-line)], 32/2); pix += 32/2; } } void Icon::create_texture() { static char tt[16] = { 0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84, 85 }; unsigned short *tex = (unsigned short *)ta_txalloc(512); unsigned short *linebase; unsigned char *src = bitmap+sizeof(bitmap)-17; for(int y=0; y<16; y++) { linebase = tex + (tt[y]<<1); for(int x=0; x<16; x++, --src) linebase[tt[x]] = src[16]|(src[0]<<8); src -= 16; } texture = tex; } void Icon::setPalette(int pal) { unsigned int (*hwpal)[64][16] = (unsigned int (*)[64][16])0xa05f9000; for(int n = 0; n<16; n++) (*hwpal)[pal][n] = palette[n]; } void Icon::draw(float x1, float y1, float x2, float y2, int pal, unsigned int argb) { struct polygon_list mypoly; struct packed_colour_vertex_list myvertex; mypoly.cmd = TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST| TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED; mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE; mypoly.mode2 = TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA| TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA| TA_POLYMODE2_TEXTURE_MODULATE_ALPHA|TA_POLYMODE2_U_SIZE_32| TA_POLYMODE2_V_SIZE_32; mypoly.texture = TA_TEXTUREMODE_CLUT4|TA_TEXTUREMODE_CLUTBANK4(pal)| TA_TEXTUREMODE_ADDRESS(texture); mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; ta_commit_list(&mypoly); myvertex.cmd = TA_CMD_VERTEX; myvertex.ocolour = 0; myvertex.colour = argb; myvertex.z = 0.5; myvertex.u = 0.0; myvertex.v = 1.0; myvertex.x = x1; myvertex.y = y1; ta_commit_list(&myvertex); myvertex.x = x2; myvertex.v = 0.0; ta_commit_list(&myvertex); myvertex.x = x1; myvertex.y = y2; myvertex.u = 1.0; myvertex.v = 1.0; ta_commit_list(&myvertex); myvertex.x = x2; myvertex.v = 0.0; myvertex.cmd |= TA_CMD_VERTEX_EOS; ta_commit_list(&myvertex); } int Icon::find_unused_pixel() { int use[16]; memset(use, 0, sizeof(use)); for(int n=0; n<32*32/2; n++) { unsigned char pix = bitmap[n]; use[pix&0xf]++; use[pix>>4]++; } for(int i=0; i<16; i++) if(!use[i]) return i; return -1; } bool Icon::load_image2(const void *data, int len) { struct { int size, w, h; short pla, bitcnt; int comp, sizeimg, xres, yres, used, imp; } hdr; if(len < 40) return false; memcpy(&hdr, data, 40); if(hdr.size != 40 || /* hdr.sizeimg<=0 || */ hdr.w<0 || hdr.h<0 || hdr.bitcnt<0 || hdr.used<0) return false; if(!hdr.used) hdr.used = 1<>= 1; /* Fix incorrect sizeimg (The Dig) */ if(hdr.sizeimg < ((hdr.w*hdr.h*(1+hdr.bitcnt)+7)>>3)) hdr.sizeimg = ((hdr.w*hdr.h*(1+hdr.bitcnt)+7)>>3); if(hdr.size + (hdr.used<<2) + hdr.sizeimg > len /* || hdr.sizeimg < ((hdr.w*hdr.h*(1+hdr.bitcnt)+7)>>3) */) return false; if(hdr.w != 32 || hdr.h != 32 || hdr.bitcnt != 4 || hdr.used > 16) return false; memcpy(palette, ((const char *)data)+hdr.size, hdr.used<<2); memcpy(bitmap, ((const char *)data)+hdr.size+(hdr.used<<2), 32*32/2); for(int i=0; i<16; i++) palette[i] |= 0xff000000; for(int i=hdr.used; i<16; i++) palette[i] = 0; int unused = find_unused_pixel(); if(unused >= 0) { const unsigned char *mask = ((const unsigned char *)data)+hdr.size+(hdr.used<<2)+32*32/2; unsigned char *pix = bitmap; for(int y=0; y<32; y++) for(int x=0; x<32/8; x++) { unsigned char mbits = *mask++; for(int z=0; z<4; z++) { unsigned char pbits = *pix; if(mbits & 64) pbits = (pbits & ~0xf) | unused; if(mbits & 128) pbits = (pbits & 0xf) | (unused << 4); *pix++ = pbits; mbits <<= 2; } } palette[unused] = 0; } return true; } bool Icon::load_image1(const void *data, int len, int offs) { struct { char w, h, colors, rsrv; short pla, bitcnt; int bytes, offs; } hdr; if(len < offs+16) return false; memcpy(&hdr, ((const char *)data)+offs, 16); if(hdr.bytes > 0 && hdr.offs >= 0 && hdr.offs+hdr.bytes <= len) return load_image2(((const char *)data)+hdr.offs, hdr.bytes); else return false; } bool Icon::load(const void *data, int len, int offs) { struct { short rsrv, type, cnt; } hdr; memset(bitmap, 0, sizeof(bitmap)); memset(palette, 0, sizeof(palette)); texture = NULL; if(len < offs+6) return false; memcpy(&hdr, ((const char *)data)+offs, 6); if(hdr.type != 1 || hdr.cnt < 1 || offs+6+(hdr.cnt<<4) > len) return false; for(int i=0; i=0) { int sz; sz = read(fd, buf, sizeof(buf)); close(fd); if(sz>0) return load(buf, sz); } return false; }