⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.c

📁 DC的SEGA_GG模拟器源代码
💻 C
字号:
/*
 * image.c -- funcs to use with GIMP C-Source dumps.
 *
 * (C)2000 Jordan DeLong & Dan Potter
 *
 * Adapted by Dan Potter to load PCXs from disk instead of using
 * source dumps.
 *
 * For copying information, please see main.c

./dc/image.c:267: warning: type mismatch with previous implicit declaration
./dc/image.c:258: warning: previous implicit declaration of `alphacombine'
./dc/image.c:267: warning: `alphacombine' was previously implicitly declared to
return `int'

 */

#include "dream.h"
//#include "cdfs.h"
#include "image.h"

/* Port of an OLD OLD PCX loading function =) */

struct pcx_hdr {
	char   Mfg;               /* manufacturer, always 0xa0         */
	char   Ver;               /* encoder version number (5)        */
	char   Enc;               /* encoding code, always 1           */
	char   Bpp;               /* bits per pixel, 8 in mode 0x13    */
	uint16 Xmin,Ymin;         /* image origin, usually 0,0         */
	uint16 Xmax,Ymax;         /* image dimensions                  */
	uint16 Hres;              /* horizontal resolution value       */
	uint16 Vres;              /* vertical resolution value         */
	char   Pal[48];           /* palette (not in mode 0x13)        */
	char   Reserved;          /* who knows?                        */
	char   ClrPlanes;         /* number of planes, 1 in mode 0x13  */
	uint16 Bpl;               /* bytes per line, 80 in mode 0x13   */
	uint16 plType;            /* Grey or Color palette flag        */
	char   Filler[58];        /* Zsoft wanted a 128 byte header    */
};

unsigned short alphacombine(unsigned short clr0, unsigned char a0, unsigned short clr1, unsigned char a1) {
	int r0 = (clr0 & 0xf800) >> 11;
	int g0 = (clr0 & 0x07c0) >> 5;
	int b0 = clr0 &0x001f;
	int r1 = (clr1 & 0xf800) >> 11;
	int g1 = (clr1 & 0x07c0) >> 5;
	int b1 = clr1 &0x001f;
	int r, g, b;
	
	r = (r0 * a0 / 256) + (r1 * a1 / 256);
	g = (g0 * a0 / 256) + (g1 * a1 / 256);
	b = (b0 * a0 / 256) + (b1 * a1 / 256);
	
	return (r << 11) | (g << 5) | b;
}

/* This function is now crufty beyond belief.. but whattadahell, it
   seems to work alright =) */
Image *load_pcx_ex(unsigned char *pcx, int x) {
	int	fd;
	int	bytes = 0;	/* counts unpacked bytes */
	char	c;		/* byte being processed  */
	int	runlen, i;	/* length of packet      */
	int	num_bytes;
	struct  pcx_hdr pcxh;
        unsigned char *pcxpal;
	Image	*rv;


        num_bytes=73814;

        /* Wastes memory right now: but we have 8 megs to blow, so whassaaa.. */
       // pcx = (unsigned char*)malloc(num_bytes);

	if (x) for (i=0; i<num_bytes; i++) pcx[i] ^= x;

	/* Load the PCX header */
//        memcpy(&pcxh, pcx, sizeof(pcxh)); pcx += sizeof(pcxh);
//        if (pcxh.Bpp!=8) {
//                serial_printf("PCX data is not 8bpp\r\n");
//                return 0;
//        }

	/* Allocate the output structure */
//        rv = (Image*)malloc(sizeof(Image));
	rv->width = pcxh.Xmax + 1;
	rv->height = pcxh.Ymax + 1;
	num_bytes = rv->width * rv->height;
//        serial_printf("Image %s is %dx%d (%d bytes)\r\n", fn, rv->width, rv->height, num_bytes);
//        rv->pixel_data = (unsigned short *)malloc(num_bytes * 2);

	/* Do the RLE decoding */
	serial_printf("Doing RLE decode\r\n");
	{
		unsigned char image[num_bytes];
	do {
		c = *pcx++;	/* Read one byte */

		if ((c & 0xc0) == 0xc0) {	/* high 2 bits set is packet */
			runlen = (c & 0x3f);	/* AND off the high bits */
			c = *pcx++;;
			while(runlen--)
				image[bytes++] = c;
		}
		else
			image[bytes++] = c;
	} while (bytes < num_bytes);

	/* Load the palette */
	serial_printf("Loading palette\r\n");
	pcx++;			/* This is a marker before the palette */
	pcxpal = pcx;
	
	/* Decode the image into RGB565 */
	serial_printf("Doing palette decode\r\n");
	for (i=0; i<num_bytes; i++) {
		int v = image[i];
		int r = pcxpal[v*3+0];
		int g = pcxpal[v*3+1];
		int b = pcxpal[v*3+2];
			
		v = (((r >> 3) & 0x1f) << 11)
			| (((g >> 2) & 0x3f) << 5)
			| (((b >> 3) & 0x1f) << 0);
		rv->pixel_data[i] = v;
	}
	}
	
	serial_printf("Done, returning %08x\r\n", rv);
	return rv;
}
Image *load_pcx(unsigned char *fn) { return load_pcx_ex(fn, 0); }

char *load_misc(char *fn) {
	int	fd, num_bytes;
	char	*rv;

	/* Open the file (or die trying!! =) */
	fd = iso_open(fn, O_RDONLY);
	if (fd < 0) {
		serial_printf("Couldn't open misc file %s\r\n", fn);
		return NULL;
	}

	/* Assess the size of the file and make a temp buffer; thankfully
	   this old crufty hack still works =) */
	iso_seek(fd, 0, SEEK_END);
	num_bytes = iso_tell(fd);
	iso_seek(fd, 0, SEEK_SET);
	serial_printf("%s: loading %d bytes\r\n", fn, num_bytes);

	/* Wastes memory right now: but we have 8 megs to blow, so whassaaa.. */
	rv = (char*)malloc(num_bytes);

	/* Load the PCX file */
	iso_read(fd, rv, num_bytes);
	iso_close(fd);

	return rv;
}



void cpyrect(int width, int height, unsigned short *img, unsigned short *vptr) {
	short x, y;
	
	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			*vptr++ = *img++;
		}
		vptr += 640 - width;
		img += 640 - width;
	}
}

void putimage(int xpos, int ypos, Image *img, unsigned short *vptr) {
	unsigned long width;
	unsigned long height;
	unsigned short *imgdata;
	short x, y;

	width = img->width;
	height = img->height;
	imgdata = img->pixel_data;

	vptr += xpos + ypos * 640;

	for (y = ypos; y < height + ypos; y++) {
		for (x = xpos; x < width + xpos; x++) {
			*vptr++ = *imgdata++;
		}
		vptr += 640 - width;
	}
}

void eraseimage(int xpos, int ypos, Image *img, unsigned short *vptr) {
	unsigned long width;
	unsigned long height;
	short x, y;

	width = img->width;
	height = img->height;

	vptr += xpos + ypos * 640;

	for (y = ypos; y < height + ypos; y++) {
		for (x = xpos; x < width + xpos; x++) {
			*vptr++ = 0x0000;
		}
		vptr += 640 - width;
	}
}

void putimagetrans(int xpos, int ypos, Image *img, unsigned short *vptr) {
	unsigned long width;
	unsigned long height;
	unsigned short *imgdata;
	short x, y;

	width = img->width;
	height = img->height;
	imgdata = img->pixel_data;

	vptr += xpos + ypos * 640;

	for (y = ypos; y < height + ypos; y++) {
		for (x = xpos; x < width + xpos; x++) {
			if (*imgdata != 0xf01e) {
				*vptr = *imgdata;
			}
			vptr++;
			imgdata++;
		}
		vptr += 640 - width;
	}
}

/* put the shad using the aformentioned transparency shieBe in *img */
/* also do some clippage to prevent wrappage */
void putalphashadow(int xpos, int ypos, Image *img, unsigned short *vptr, unsigned char alpha) {
	unsigned long width;
	unsigned long height;
	unsigned short *imgdata;
	short x, y;

	width = img->width;
	height = img->height;
	imgdata = img->pixel_data;
	
	/* clipping, only neccessary on the left and right.  so don't make negative shadowdirs */
	if (xpos >= 640)
		return;
	if (ypos >= 480)
		return;
	if (xpos + width >= 640)
		width = 639 - xpos;
	if (ypos + height >= 480)
		height = 479 - ypos;

	vptr += xpos + ypos * 640;

	for (y = ypos; y < height + ypos; y++) {
		for (x = xpos; x < width + xpos; x++) {
			if (*imgdata != 0xf01e) {
				*vptr = alphacombine(0x0000, alpha, *vptr, 256 - alpha);
			}
			vptr++;
			imgdata++;
		}
		vptr += 640 - width;
	}	
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -