diff options
Diffstat (limited to 'src/build')
-rw-r--r-- | src/build/build.mak | 57 | ||||
-rw-r--r-- | src/build/file2str.c | 98 | ||||
-rw-r--r-- | src/build/png2bdc.c | 448 |
3 files changed, 603 insertions, 0 deletions
diff --git a/src/build/build.mak b/src/build/build.mak new file mode 100644 index 00000000000..6ec1bf6ae50 --- /dev/null +++ b/src/build/build.mak @@ -0,0 +1,57 @@ +########################################################################### +# +# build.mak +# +# MAME build tools makefile +# +# Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. +# Visit http://mamedev.org for licensing and usage restrictions. +# +########################################################################### + + +BUILDSRC = $(SRC)/build +BUILDOBJ = $(OBJ)/build +BUILDOUT = $(BUILDOBJ) + +OBJDIRS += \ + $(BUILDOBJ) \ + + + +#------------------------------------------------- +# set of build targets +#------------------------------------------------- + +FILE2STR = $(BUILDOUT)/file2str$(EXE) +PNG2BDC = $(BUILDOUT)/png2bdc$(EXE) + +BUILD += \ + $(FILE2STR) \ + $(PNG2BDC) \ + + + +#------------------------------------------------- +# file2str +#------------------------------------------------- + +FILE2STROBJS = \ + $(BUILDOBJ)/file2str.o \ + +$(FILE2STR): $(FILE2STROBJS) $(LIBOCORE) + @echo Linking $@... + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + + + +#------------------------------------------------- +# png2bdc +#------------------------------------------------- + +PNG2BDCOBJS = \ + $(BUILDOBJ)/png2bdc.o \ + +$(PNG2BDC): $(PNG2BDCOBJS) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT) + @echo Linking $@... + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ diff --git a/src/build/file2str.c b/src/build/file2str.c new file mode 100644 index 00000000000..d0332b01c87 --- /dev/null +++ b/src/build/file2str.c @@ -0,0 +1,98 @@ +/*************************************************************************** + + file2str.c + + Simple file to string converter. + + Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#include <stdio.h> +#include "osdcore.h" + + +/*------------------------------------------------- + main - primary entry point +-------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + const char *srcfile, *dstfile, *varname, *type; + FILE *src, *dst; + UINT8 *buffer; + int bytes, offs; + int terminate = 1; + + /* needs at least three arguments */ + if (argc < 4) + { + fprintf(stderr, + "Usage:\n" + " laytostr <source.lay> <output.h> <varname> [<type>]\n" + "\n" + "The default <type> is char, with an assumed NULL terminator\n" + ); + return 0; + } + + /* extract arguments */ + srcfile = argv[1]; + dstfile = argv[2]; + varname = argv[3]; + type = (argc >= 5) ? argv[4] : "char"; + if (argc >= 5) + terminate = 0; + + /* open source file */ + src = fopen(srcfile, "rb"); + if (src == NULL) + { + fprintf(stderr, "Unable to open source file '%s'\n", srcfile); + return 1; + } + + /* determine file size */ + fseek(src, 0, SEEK_END); + bytes = ftell(src); + fseek(src, 0, SEEK_SET); + + /* allocate memory */ + buffer = malloc(bytes + 1); + if (buffer == NULL) + { + fprintf(stderr, "Out of memory allocating %d byte buffer\n", bytes); + return 1; + } + + /* read the source file */ + fread(buffer, 1, bytes, src); + buffer[bytes] = 0; + fclose(src); + + /* open dest file */ + dst = fopen(dstfile, "w"); + if (dst == NULL) + { + fprintf(stderr, "Unable to open output file '%s'\n", dstfile); + return 1; + } + + /* write the initial header */ + fprintf(dst, "const %s %s[] =\n{\n\t", type, varname); + + /* write out the data */ + for (offs = 0; offs < bytes + terminate; offs++) + { + fprintf(dst, "0x%02x%s", buffer[offs], (offs != bytes + terminate - 1) ? "," : ""); + if (offs % 16 == 15) + fprintf(dst, "\n\t"); + } + fprintf(dst, "\n};\n"); + + /* close the files */ + free(buffer); + fclose(dst); + return 0; +} diff --git a/src/build/png2bdc.c b/src/build/png2bdc.c new file mode 100644 index 00000000000..4ac73453351 --- /dev/null +++ b/src/build/png2bdc.c @@ -0,0 +1,448 @@ +/*************************************************************************** + + Super-simple PNG to BDC file generator + + Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**************************************************************************** + + Format of PNG data: + + Multiple rows of characters. A black pixel means "on". All other colors + mean "off". Each row looks like this: + + * 8888 *** * + * 4444 * * ** + * 2222 * * * + * 1111 * * * + * * * * + ** *** *** + * + * + + ****** **** + + The column of pixels on the left-hand side (column 0) indicates the + character cell height. This column must be present on each row and + the height must be consistent for each row. + + Protruding one pixel into column 1 is the baseline indicator. There + should only be one row with a pixel in column 1 for each line, and + that pixel row index should be consistent for each row. + + In columns 2-5 are a 4-hex-digit starting character index number. This + is encoded as binary value. Each column is 4 pixels tall and represents + one binary digit. The character index number is the unicode character + number of the first character encoded in this row; subsequent + characters in the row are at increasing character indices. + + Starting in column 6 and beyond are the actual character bitmaps. + Below them, in the second row after the last row of the character, + is a solid line that indicates the width of the character, and also + where the character bitmap begins and ends. + +***************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "osdcore.h" +#include "png.h" + + +/*************************************************************************** + CONSTANTS & DEFINES +***************************************************************************/ + +#define CACHED_CHAR_SIZE 12 +#define CACHED_HEADER_SIZE 16 + + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +/* a render_font contains information about a single character in a font */ +typedef struct _render_font_char render_font_char; +struct _render_font_char +{ + INT32 width; /* width from this character to the next */ + INT32 xoffs, yoffs; /* X and Y offset from baseline to top,left of bitmap */ + INT32 bmwidth, bmheight; /* width and height of bitmap */ + bitmap_t * bitmap; /* pointer to the bitmap containing the raw data */ +}; + + +/* a render_font contains information about a font */ +typedef struct _render_font render_font; +struct _render_font +{ + int height; /* height of the font, from ascent to descent */ + int yoffs; /* y offset from baseline to descent */ + render_font_char chars[65536]; /* array of characters */ +}; + + + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +INLINE int pixel_is_set(bitmap_t *bitmap, int y, int x) +{ + return (*BITMAP_ADDR32(bitmap, y, x) & 0xffffff) == 0; +} + + + +/*************************************************************************** + MAIN +***************************************************************************/ + +static int render_font_save_cached(render_font *font, const char *filename, UINT32 hash) +{ + file_error filerr; + render_font_char *ch; + UINT32 bytes_written; + UINT8 *tempbuffer; + UINT8 *chartable; + core_file *file; + int numchars; + UINT8 *dest; + int tableindex; + int chnum; + + /* attempt to open the file */ + filerr = core_fopen(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file); + if (filerr != FILERR_NONE) + return 1; + + /* determine the number of characters */ + numchars = 0; + for (chnum = 0; chnum < 65536; chnum++) + if (font->chars[chnum].width > 0) + numchars++; + + /* allocate an array to hold the character data */ + chartable = malloc(numchars * CACHED_CHAR_SIZE); + + /* allocate a temp buffer to compress into */ + tempbuffer = malloc(65536); + if (chartable == NULL || tempbuffer == NULL) + goto error; + + memset(chartable, 0, numchars * CACHED_CHAR_SIZE); + + /* write the header */ + dest = tempbuffer; + *dest++ = 'f'; + *dest++ = 'o'; + *dest++ = 'n'; + *dest++ = 't'; + *dest++ = hash >> 24; + *dest++ = hash >> 16; + *dest++ = hash >> 8; + *dest++ = hash & 0xff; + *dest++ = font->height >> 8; + *dest++ = font->height & 0xff; + *dest++ = font->yoffs >> 8; + *dest++ = font->yoffs & 0xff; + *dest++ = numchars >> 24; + *dest++ = numchars >> 16; + *dest++ = numchars >> 8; + *dest++ = numchars & 0xff; + bytes_written = core_fwrite(file, tempbuffer, dest - tempbuffer); + if (bytes_written != dest - tempbuffer) + goto error; + + /* write the empty table to the beginning of the file */ + bytes_written = core_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE); + if (bytes_written != numchars * CACHED_CHAR_SIZE) + goto error; + + /* loop over all characters */ + tableindex = 0; + for (chnum = 0; chnum < 65536; chnum++) + { + ch = &font->chars[chnum]; + if (ch->width > 0) + { + UINT8 accum, accbit; + int x, y; + + /* write out a bit-compressed bitmap if we have one */ + if (ch->bitmap != NULL) + { + /* write the data to the tempbuffer */ + dest = tempbuffer; + accum = 0; + accbit = 7; + + /* bit-encode the character data */ + for (y = 0; y < ch->bmheight; y++) + { + int desty = y + font->height + font->yoffs - ch->yoffs - ch->bmheight; + const UINT32 *src = (desty >= 0 && desty < font->height) ? BITMAP_ADDR32(ch->bitmap, desty, 0) : NULL; + for (x = 0; x < ch->bmwidth; x++) + { + if (src != NULL && src[x] != 0) + accum |= 1 << accbit; + if (accbit-- == 0) + { + *dest++ = accum; + accum = 0; + accbit = 7; + } + } + } + + /* flush any extra */ + if (accbit != 7) + *dest++ = accum; + + /* write the data */ + bytes_written = core_fwrite(file, tempbuffer, dest - tempbuffer); + if (bytes_written != dest - tempbuffer) + goto error; + + /* free the bitmap and texture */ + bitmap_free(ch->bitmap); + ch->bitmap = NULL; + } + + /* compute the table entry */ + dest = &chartable[tableindex++ * CACHED_CHAR_SIZE]; + *dest++ = chnum >> 8; + *dest++ = chnum & 0xff; + *dest++ = ch->width >> 8; + *dest++ = ch->width & 0xff; + *dest++ = ch->xoffs >> 8; + *dest++ = ch->xoffs & 0xff; + *dest++ = ch->yoffs >> 8; + *dest++ = ch->yoffs & 0xff; + *dest++ = ch->bmwidth >> 8; + *dest++ = ch->bmwidth & 0xff; + *dest++ = ch->bmheight >> 8; + *dest++ = ch->bmheight & 0xff; + } + } + + /* seek back to the beginning and rewrite the table */ + core_fseek(file, CACHED_HEADER_SIZE, SEEK_SET); + bytes_written = core_fwrite(file, chartable, numchars * CACHED_CHAR_SIZE); + if (bytes_written != numchars * CACHED_CHAR_SIZE) + goto error; + + /* all done */ + core_fclose(file); + free(tempbuffer); + free(chartable); + return 0; + +error: + core_fclose(file); + osd_rmfile(filename); + free(tempbuffer); + free(chartable); + return 1; +} + + +/*------------------------------------------------- + bitmap_to_chars - convert a bitmap to + characters in the given font +-------------------------------------------------*/ + +static int bitmap_to_chars(bitmap_t *bitmap, render_font *font) +{ + int rowstart = 0; + int x, y; + + /* loop over rows */ + while (rowstart < bitmap->height) + { + int rowend, baseline, colstart; + int chstart; + + /* find the top of the row */ + for ( ; rowstart < bitmap->height; rowstart++) + if (pixel_is_set(bitmap, rowstart, 0)) + break; + if (rowstart >= bitmap->height) + break; + + /* find the bottom of the row */ + for (rowend = rowstart + 1; rowend < bitmap->height; rowend++) + if (!pixel_is_set(bitmap, rowend, 0)) + { + rowend--; + break; + } + + /* find the baseline */ + for (baseline = rowstart; baseline <= rowend; baseline++) + if (pixel_is_set(bitmap, baseline, 1)) + break; + if (baseline > rowend) + { + fprintf(stderr, "No baseline found between rows %d-%d\n", rowstart, rowend); + break; + } + + /* set or confirm the height */ + if (font->height == 0) + { + font->height = rowend - rowstart + 1; + font->yoffs = baseline - rowend; + } + else + { + if (font->height != rowend - rowstart + 1) + { + fprintf(stderr, "Inconsistent font height at rows %d-%d\n", rowstart, rowend); + break; + } + if (font->yoffs != baseline - rowend) + { + fprintf(stderr, "Inconsistent baseline at rows %d-%d\n", rowstart, rowend); + break; + } + } + + /* decode the starting character */ + chstart = 0; + for (x = 0; x < 4; x++) + for (y = 0; y < 4; y++) + chstart = (chstart << 1) | pixel_is_set(bitmap, rowstart + y, 2 + x); + + /* print info */ +// printf("Row %d-%d, baseline %d, character start %X\n", rowstart, rowend, baseline, chstart); + + /* scan the column to find characters */ + colstart = 0; + while (colstart < bitmap->width) + { + render_font_char *ch = &font->chars[chstart]; + int colend; + + /* find the start of the character */ + for ( ; colstart < bitmap->width; colstart++) + if (pixel_is_set(bitmap, rowend + 2, colstart)) + break; + if (colstart >= bitmap->width) + break; + + /* find the end of the character */ + for (colend = colstart + 1; colend < bitmap->width; colend++) + if (!pixel_is_set(bitmap, rowend + 2, colend)) + { + colend--; + break; + } + + /* print info */ +// printf(" Character %X - width = %d\n", chstart, colend - colstart + 1); + + /* allocate a bitmap */ + ch->bitmap = bitmap_alloc(colend - colstart + 1, font->height, BITMAP_FORMAT_ARGB32); + if (ch->bitmap == NULL) + { + fprintf(stderr, "Error allocating character bitmap (%dx%d)\n", colend - colstart + 1, font->height); + continue; + } + + /* plot the character */ + for (y = rowstart; y <= rowend; y++) + for (x = colstart; x <= colend; x++) + *BITMAP_ADDR32(ch->bitmap, y - rowstart, x - colstart) = pixel_is_set(bitmap, y, x) ? 0xffffffff : 0x00000000; + + /* set the character parameters */ + ch->width = colend - colstart + 1; + ch->xoffs = 0; + ch->yoffs = font->yoffs; + ch->bmwidth = ch->bitmap->width; + ch->bmheight = ch->bitmap->height; + + /* next character */ + chstart++; + colstart = colend + 1; + } + + /* next row */ + rowstart = rowend + 1; + } + + /* return non-zero (TRUE) if we errored */ + return (rowstart < bitmap->height); +} + + +/*------------------------------------------------- + main - main entry point +-------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + const char *bdcname; + render_font *font; + int error = FALSE; + int curarg; + + /* validate arguments */ + if (argc < 3) + { + fprintf(stderr, "Usage:\npng2bdf <input.png> [<input2.png> [...]] <output.bdc>\n"); + return 1; + } + bdcname = argv[argc - 1]; + + /* allocate a font */ + font = malloc(sizeof(*font)); + if (font == NULL) + return 1; + memset(font, 0, sizeof(*font)); + + /* iterate over input files */ + for (curarg = 1; curarg < argc - 1; curarg++) + { + const char *pngname = argv[curarg]; + file_error filerr; + png_error pngerr; + bitmap_t *bitmap; + core_file *file; + + /* load the png file */ + filerr = core_fopen(pngname, OPEN_FLAG_READ, &file); + if (filerr != FILERR_NONE) + { + fprintf(stderr, "Error %d attempting to open PNG file\n", filerr); + error = TRUE; + break; + } + pngerr = png_read_bitmap(file, &bitmap); + core_fclose(file); + if (pngerr != PNGERR_NONE) + { + fprintf(stderr, "Error %d reading PNG file\n", pngerr); + error = TRUE; + break; + } + + /* parse the PNG into characters */ + error = bitmap_to_chars(bitmap, font); + bitmap_free(bitmap); + if (error) + break; + } + + /* write out the resulting font */ + if (!error) + render_font_save_cached(font, bdcname, 0); + + /* cleanup after ourselves */ + free(font); + return error; +} |