#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>