File:  [RetroPC.NET] / mkfont32 / accessories / mkres.c
Revision 1.3: download - view: text, annotated - select for diffs
Thu Jun 10 12:11:46 2004 JST (21 years, 4 months ago) by yui
Branches: MAIN
CVS tags: HEAD
fix x68k fonts (T.Yui)

#include	"compiler.h"
#include	"bmpdata.h"
#include	"dosio.h"
#include	"textout.h"


typedef struct {
	int		width;
	int		height;
	int		align;
	BYTE	*ptr;
} BMPRES;

static BMPRES *bmpload(const char *filename) {

	FILEH	fh;
	BMPFILE	bf;
	BMPINFO	bi;
	BMPDATA	bd;
	long	fptr;
	UINT	align;
	UINT	size;
	BMPRES	*ret;
	BYTE	*p;
	int		step;
	int		height;

	fh = file_open_rb(filename);
	if (fh == FILEH_INVALID) {
		goto bl_err1;
	}
	if ((file_read(fh, &bf, sizeof(bf)) != sizeof(bf)) ||
		(bf.bfType[0] != 'B') || (bf.bfType[1] != 'M')) {
		goto bl_err2;
	}
	if ((file_read(fh, &bi, sizeof(bi)) != sizeof(bi)) ||
		(bmpdata_getinfo(&bi, &bd) != SUCCESS) || (bd.bpp != 1)) {
		goto bl_err2;
	}
	fptr = LOADINTELDWORD(bf.bfOffBits);
	if (file_seek(fh, fptr, FSEEK_SET) != fptr) {
		goto bl_err2;
	}
	align = bmpdata_getalign(&bi);
	size = sizeof(BMPRES) + bmpdata_getdatasize(&bi);
	ret = (BMPRES *)_MALLOC(size, filename);
	if (ret == NULL) {
		goto bl_err2;
	}
	p = (BYTE *)(ret + 1);
	step = align;
	ret->width = bd.width;
	ret->align = align;
	ret->ptr = p;
	if (bd.height < 0) {
		height = 0 - bd.height;
	}
	else {
		height = bd.height;
		step = 0 - align;
		p += (height - 1) * align;
	}
	ret->height = height;
	while(height) {
		height--;
		if (file_read(fh, p, align) != align) {
			goto bl_err3;
		}
		p += step;
	}
	file_close(fh);
	return(ret);

bl_err3:
	_MFREE(ret);

bl_err2:
	file_close(fh);

bl_err1:
	return(NULL);
}


// ----

static void dump(const char *dstfile, const char *sym,
												const BYTE *ptr, UINT size) {

	void	*dst;
	char	work[256];
	UINT	r;
	UINT	i;

	dst = textout_open(dstfile, 256);
	if (sym == NULL) {
		sym = dstfile;
	}
	SPRINTF(work, "const unsigned char %s[%d] = {\n", sym, size);
	textout_write(dst, work);

	while(1) {
		r = min(size, 12);
		if (r == 0) {
			break;
		}
		for (i=0; i<r; i++) {
			SPRINTF(work + i*5, "0x%02x,", ptr[i]);
		}
		textout_write(dst, "\t\t\t");
		textout_write(dst, work);
		textout_write(dst, "\n");
		ptr += r;
		size -= r;
	}
	textout_write(dst, "};\n");
	textout_close(dst);
}


// ----

enum {
	MKRES_SUCCESS		= 0,
	MKRES_ERRWIDTH		= 1,
	MKRES_ERRHEIGHT		= 2,
	MKRES_ERRBMP		= 3,
	MKRES_ERRMEMORY		= 4,

	MKRES_ERROR			= 255
};

static char *getval(const char *ptr, int *pval) {

	int		val;
	int		s;
	int		c;

	val = 0;
	s = 1;

	c = *ptr;
	if (c == '+') {
		ptr++;
	}
	else if (c == '-') {
		ptr++;
		s = -1;
	}
	while(1) {
		c = *ptr;
		c -= '0';
		if ((unsigned)c < 10) {
			val *= 10;
			val += c;
			ptr++;
		}
		else {
			break;
		}
	}
	if (pval) {
		*pval = val * s;
	}
	return((char *)ptr);
}

static int mkres(const char *dstfile, const char *sym,
									const char *srcname, UINT cx, UINT cy) {

	int		ret;
	BMPRES	*res;
	UINT	sx;
	UINT	sy;
	UINT	size;
	BYTE	*ptr;
	BYTE	*p;
	BYTE	*q;
	UINT	x;
	UINT	y;
	UINT	i;
	UINT	j;

	ret = MKRES_ERROR;

	if ((cx == 0) || ((cx & 7) != 0)) {
		ret = MKRES_ERRWIDTH;
		goto f_err1;
	}
	if (cy == 0) {
		ret = MKRES_ERRHEIGHT;
		goto f_err1;
	}

	res = bmpload(srcname);
	if (res == NULL) {
		ret = MKRES_ERRBMP;
		goto f_err1;
	}

	sx = res->width / cx;
	if ((int)(sx * cx) != res->width) {
		ret = MKRES_ERRWIDTH;
		goto f_err2;
	}
	sy = res->height / cy;
	if ((int)(sy * cy) != res->height) {
		ret = MKRES_ERRHEIGHT;
		goto f_err2;
	}
	cx >>= 3;

	size = sx * cx * sy * cy;
	ptr = (BYTE *)_MALLOC(size, srcname);
	if (ptr == NULL) {
		ret = MKRES_ERRMEMORY;
		goto f_err2;
	}
	q = ptr;
	for (y=0; y<sy; y++) {
		for (x=0; x<sx; x++) {
			p = res->ptr + (x * cx) + (y * cy * res->align);
			for (i=0; i<cy; i++) {
				for (j=0; j<cx; j++) {
					q[j] = p[j];
				}
				p += res->align;
				q += j;
			}
		}
	}
	dump(dstfile, sym, ptr, size);

	_MFREE(ptr);

	ret = MKRES_SUCCESS;

f_err2:
	_MFREE(res);

f_err1:
	return(ret);
}

int main(int argc, char **argv) {

	char	*p;
	int		cx;
	int		cy;

	if (argc < 5) {
		puts("usage: mkres resfile symbol bmpfile width.height");
		return(255);
	}
	p = getval(argv[4], &cx);
	if (p[0]) {
		p++;
	}
	p = getval(p, &cy);
	return(mkres(argv[1], argv[2], argv[3], cx, cy));
}


RetroPC.NET-CVS <cvs@retropc.net>