From 7e26adbad8c59773744ec5bfb66bcd4e1abca7ec Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 5 Nov 2024 13:57:51 -0500 Subject: [PATCH] driven: working on large font support --- demos/driven/part05_atrus/font/Makefile | 7 +- utils/hgr-utils/Makefile | 15 +- utils/hgr-utils/png2largefont.c | 434 ++++++++++++++++++++++++ 3 files changed, 451 insertions(+), 5 deletions(-) create mode 100644 utils/hgr-utils/png2largefont.c diff --git a/demos/driven/part05_atrus/font/Makefile b/demos/driven/part05_atrus/font/Makefile index 56975601..4567fe00 100644 --- a/demos/driven/part05_atrus/font/Makefile +++ b/demos/driven/part05_atrus/font/Makefile @@ -1,8 +1,11 @@ HGR_SPRITE = ../../../../utils/hgr-utils/hgr_make_sprite +HGR_LARGEFONT = ../../../../utils/hgr-utils/png2largefont -all: font.inc +all: font.inc large_font.inc +large_font.inc: a2_big_font.png + $(HGR_LARGEFONT) -r a2_big_font.png > large_font.inc font.inc: a2_big_font.png $(HGR_SPRITE) -l font_space a2_big_font.png 0 0 13 16 > font.inc @@ -42,4 +45,4 @@ font.inc: a2_big_font.png clean: rm -f *~ \ - font.inc + font.inc large_font.inc diff --git a/utils/hgr-utils/Makefile b/utils/hgr-utils/Makefile index 5d6986f5..e4bfb7e8 100644 --- a/utils/hgr-utils/Makefile +++ b/utils/hgr-utils/Makefile @@ -4,7 +4,7 @@ CFLAGS = -O2 -Wall -g all: pcx2hgr png2hgr png2dhgr shape_table dump_table \ hgr2png hgr_make_sprite png2font dhgr2png \ - png2tiles + png2tiles png2largefont ### @@ -51,6 +51,15 @@ png2font: png2font.o png2font.o: png2font.c $(CC) $(CFLAGS) -c png2font.c +### + +png2largefont: png2largefont.o + $(CC) -o png2largefont png2largefont.o $(LFLAGS) -lpng + +png2largefont.o: png2largefont.c + $(CC) $(CFLAGS) -c png2largefont.c + + ### @@ -89,8 +98,8 @@ png2dhgr.o: png2dhgr.c install: - cp pcx2hgr shape_table png2hgr hgr2png hgr_make_sprite png2font $(INSTALL_LOC) + cp pcx2hgr shape_table png2hgr hgr2png hgr_make_sprite png2font png2largefont $(INSTALL_LOC) clean: - rm -f *~ *.o pcx2hgr shape_table dump_table png2hgr png2dhgr hgr2png hgr_make_sprite png2font png2tiles + rm -f *~ *.o pcx2hgr shape_table dump_table png2hgr png2dhgr hgr2png hgr_make_sprite png2font png2tiles png2largefont dhgr2png diff --git a/utils/hgr-utils/png2largefont.c b/utils/hgr-utils/png2largefont.c new file mode 100644 index 00000000..bb6e2ced --- /dev/null +++ b/utils/hgr-utils/png2largefont.c @@ -0,0 +1,434 @@ +/* Converts 280x192 8-bit PNG file with correct palette to an HGR large font*/ + +/* Assume font is 14x16 in size */ +/* Two rows of font for 32 chars total */ +/* This is hardcoded now, maybe expand in future */ + +#define VERSION "0.0.1" + +#include /* For FILE I/O */ +#include /* For strncmp */ +#include /* for open() */ +#include /* for lseek() */ +#include /* for file modes */ +#include /* free() */ + +#include + +#define OUTPUT_ORIGINAL 0 +#define OUTPUT_ROWS 1 +#define OUTPUT_BINARY 2 + +static int debug=0; + +static int reverse_byte(int value) { + /* 0001 0111 -> X011 1010 */ + /* 7654 3210 -> 01 2345 */ + int reversed=0,i; + for(i=0;i<8;i++) { + reversed|=(1<<(i))*(!!(value&(1<<(7-i)))); + } +// printf("%x reversed is %x\n",value,reversed); + return reversed; +} + +static int print_fancy_bytes(int byte1,int byte2) { + + int i; + + printf(".byte $%02X,$%02X",byte1,byte2); +// (reverse_byte((byte2))), +// (reverse_byte((byte1)))); + printf("\t; "); + + for(i=0;i<8;i++) { + if (byte1&(1< X011 1010 */ + /* 7654 3210 -> 012 3456 */ + reversed=0; + for(i=0;i<8;i++) { + reversed|=(1<<(i-1))*(!!(value&(1<<(7-i)))); + } + + printf("\t.byte $%02X\t; ",reversed); + + for(i=0;i<5;i++) { + printf("%c",((1<<(4-i))&value)?'1':'0'); + } + printf(" X"); + for(i=0;i<7;i++) { + if (i==3) printf(" "); + printf("%c",((1<<(6-i))&reversed)?'1':'0'); + } +#endif + printf("\n"); + return 0; +} + +#if 0 +static int print_interleave_byte(int value,int y) { + + int i,reversed; + + /* 0001 0111 -> X011 1010 */ + /* 7654 3210 -> 01 2345 */ + reversed=0; + for(i=0;i<8;i++) { + reversed|=(1<<(i-1))*(!!(value&(1<<(7-i)))); + } + + printf("\t.byte $%02X\t ; ",reversed); + if ((y>0x20) && (y<0x7f)) printf("%c",y); + printf("\n"); + + return 0; + +} +#endif + +static int convert_color(int color) { + + int c=0; + + switch(color) { + + /* These use the questionable palette my older code used */ + /* Also handle the newer one */ + /* Bitflipped because HGR is backwards, woz is crazy */ + case 0x000000: c=0; break; /* black1 */ + case 0x1bcb01: c=2; break; /* bright green */ + case 0x14f53c: c=2; break; /* bright green */ + case 0xe434fe: c=1; break; /* magenta */ + case 0xe31e60: c=1; break; /* magenta */ + case 0xffffff: c=3; break; /* white1 */ + case 0xcd5b01: c=6; break; /* orange */ + case 0xff6a3c: c=6; break; /* orange */ + case 0x1b9afe: c=5; break; /* medium blue */ + case 0x14cffd: c=5; break; /* medium blue */ + + case 0x010101: c=4; break; /* black2 */ + case 0xfefefe: c=7; break; /* white2 */ + + default: + fprintf(stderr,"Unknown color %x\n",color); + break; + } + + return c; +} + + + +/* expects a PNG */ +static int loadpng(char *filename, + unsigned char **image_ptr, int *xsize, int *ysize) { + + int x,y; + int color; + FILE *infile; + unsigned char *image,*out_ptr; + int width, height; + int a2_color; + + png_byte bit_depth; + png_structp png_ptr; + png_infop info_ptr; + png_bytep *row_pointers; + png_byte color_type; + int row_bytes,bytes_per_pixel; + + unsigned char header[8]; + + /* open file and test for it being a png */ + infile = fopen(filename, "rb"); + if (infile==NULL) { + fprintf(stderr,"Error! Could not open %s\n",filename); + return -1; + } + + /* Check the header */ + fread(header, 1, 8, infile); + if (png_sig_cmp(header, 0, 8)) { + fprintf(stderr,"Error! %s is not a PNG file\n",filename); + return -1; + } + + /* initialize stuff */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + fprintf(stderr,"Error create_read_struct\n"); + exit(-1); + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + fprintf(stderr,"Error png_create_info_struct\n"); + exit(-1); + } + + png_init_io(png_ptr, infile); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + width = png_get_image_width(png_ptr, info_ptr); + height = png_get_image_height(png_ptr, info_ptr); + *xsize=width; + *ysize=height; + + color_type = png_get_color_type(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + + if (width!=280) { + fprintf(stderr,"Unknown width %d\n",width); + return -1; + } + + if (height!=192) { + fprintf(stderr,"Unknown height %d\n",height); + return -1; + } + + image=calloc(width*height,sizeof(unsigned char)); + if (image==NULL) { + fprintf(stderr,"Error allocating image\n"); + return -1; + } + + if (debug) { + fprintf(stderr,"PNG: width=%d height=%d depth=%d\n", + width,height,bit_depth); + if (color_type==PNG_COLOR_TYPE_RGB) { + fprintf(stderr,"Type RGB\n"); + } + else if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) { + fprintf(stderr,"Type RGBA\n"); + } + else if (color_type==PNG_COLOR_TYPE_PALETTE) { + fprintf(stderr,"Type palette\n"); + } + } + + /* If palette, expand to RGB automatically */ + if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_expand(png_ptr); + } + + png_read_update_info(png_ptr, info_ptr); + + + row_bytes = png_get_rowbytes(png_ptr, info_ptr); + // *pChannels = (int)png_get_channels(png_ptr, info_ptr); + bytes_per_pixel=row_bytes/width; + + if (debug) { + fprintf(stderr,"Rowbytes=%d bytes per pixel=%d\n", + row_bytes,row_bytes/width); + } + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (y=0; y=argc) { + printf("ERROR: Was expecting filename!\n"); + exit(1); + } + + filename=strdup(argv[optind]); + +// memset(apple2_image,0,8192); + + if (loadpng(filename,&image,&xsize,&ysize)<0) { + fprintf(stderr,"Error loading png!\n"); + exit(-1); + } + + fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize); + fprintf(stderr,"Using font offset of 0x%x\n",start_offset); + + int pal[2],color=0,byte1,byte2; + /* for now, assume 14x16 font starting at 0,0 */ + for(row=0;row<2;row++) { + for(col=0;col<16;col++) { + for(y=0;y<16;y++) { + temp=0; + pal[0]=0,pal[1]=0; + for(x=0;x<14;x+=2) { + color=image[ (((row*18)+y)*280)+(col*14)+x]; + switch(color){ + case 0: temp=temp<<2; break; + case 1: temp=temp<<2; temp|=2; break; + case 2: temp=temp<<2; temp|=1; break; + case 3: temp=temp<<2; temp|=3; break; + case 4: temp=temp<<2; break; + case 5: temp=temp<<2; temp|=2; + pal[x/7]=1; break; + case 6: temp=temp<<2; temp|=1; + pal[x/7]=1; break; + case 7: temp=temp<<2; temp|=3; + pal[x/7]=1; break; + } + } + byte1=(reverse_byte(temp>>6)&0x7f)|pal[0]<<7; + byte2=(reverse_byte(temp<<1)&0x7f)|pal[1]<<7; + + font_data[(row*16)+col][y][0]=byte1; + font_data[(row*16)+col][y][1]=byte2; + + } + } + } + +// fwrite(apple2_image,8192,sizeof(unsigned char),stdout); + + /* old-fashioned output */ + if (output_type==OUTPUT_ORIGINAL) { + printf("hgr_large_font:\n"); + for(c=0;c<32;c++) { + printf("; %c $%02X\n",c+64,c); + for(y=0;y<16;y++) { + print_fancy_bytes(font_data[c][y][0], + font_data[c][y][1]); + } + } + } + /* row based output */ + if (output_type==OUTPUT_ROWS) { + for(row=0;row<16;row++) { + printf("large_font_row%d:\n",row); + printf(".byte "); + for(c=0;c<32;c++) { + printf("$%02X,$%02X", + font_data[c][row][0], + font_data[c][row][1]); + if (c!=31) printf(","); + } + printf("\n"); + } + + } + else if (output_type==OUTPUT_BINARY) { + fprintf(stderr,"ERROR! Binary not implemented yet\n"); + } + else { + fprintf(stderr,"ERROR! Unknown output\n"); + } + return 0; +}