From af97f5583a202673d9379a74299600ea399dcdd5 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 25 Jul 2018 15:21:49 -0400 Subject: [PATCH] fancy_lores: add 4048d viewer --- fancy_lores/Makefile | 54 ++- fancy_lores/disp4048d.s | 352 ++++++++++++++++++ fancy_lores/fancy_lores_viewer.dsk | Bin 143360 -> 143360 bytes fancy_lores/genpal.c | 20 +- fancy_lores/png_to_40x48d.c | 571 +++++++++++++++++++++++++++++ 5 files changed, 988 insertions(+), 9 deletions(-) create mode 100644 fancy_lores/disp4048d.s create mode 100644 fancy_lores/png_to_40x48d.c diff --git a/fancy_lores/Makefile b/fancy_lores/Makefile index 7948fad3..ad13fc8e 100644 --- a/fancy_lores/Makefile +++ b/fancy_lores/Makefile @@ -2,24 +2,34 @@ include ../Makefile.inc DOS33 = ../dos33fs-utils/dos33 -all: fancy_lores_viewer.dsk png_to_40x96 katahdin_40_96.inc +all: fancy_lores_viewer.dsk png_to_40x96 png_to_40x48d -fancy_lores_viewer.dsk: DISP4096 +fancy_lores_viewer.dsk: DISP4096 DISP4048D $(DOS33) -y fancy_lores_viewer.dsk BSAVE -a 0x1000 DISP4096 + $(DOS33) -y fancy_lores_viewer.dsk BSAVE -a 0x1000 DISP4048D +# $(DOS33) -y fancy_lores_viewer.dsk BSAVE -a 0x2000 APPLE_ORIG.BIN +# $(DOS33) -y fancy_lores_viewer.dsk BSAVE -a 0x2000 KATAHDIN_ORIG.BIN + +#### DISP4096: disp4096.o ld65 -o DISP4096 disp4096.o -C ../linker_scripts/apple2_1000.inc - disp4096.o: disp4096.s gr_copy.s \ apple_40_96.inc katahdin_40_96.inc ca65 -o disp4096.o disp4096.s -l disp4096.lst -katahdin_40_96.inc: png_to_40x96 katahdin_40_96.png - ./png_to_40x96 asm katahdin_40_96.png katahdin > katahdin_40_96.inc +#### -apple_40_96.inc: png_to_40x96 apple_40_96.png - ./png_to_40x96 asm apple_40_96.png apple > apple_40_96.inc +DISP4048D: disp4048d.o + ld65 -o DISP4048D disp4048d.o -C ../linker_scripts/apple2_1000.inc + +disp4048d.o: disp4048d.s gr_copy.s \ + apple_40_48d.inc katahdin_40_48d.inc + ca65 -o disp4048d.o disp4048d.s -l disp4048d.lst + + +#### png_to_40x96: png_to_40x96.o $(CC) $(LFLAGS) -lpng -o png_to_40x96 png_to_40x96.o @@ -27,11 +37,39 @@ png_to_40x96: png_to_40x96.o png_to_40x96.o: png_to_40x96.c $(CC) $(CFLAGS) -c png_to_40x96.c +#### + +png_to_40x48d: png_to_40x48d.o + $(CC) $(LFLAGS) -lpng -o png_to_40x48d png_to_40x48d.o + +png_to_40x48d.o: png_to_40x48d.c + $(CC) $(CFLAGS) -g -c png_to_40x48d.c + +### + +katahdin_40_96.inc: png_to_40x96 katahdin_40_96.png + ./png_to_40x96 asm katahdin_40_96.png katahdin > katahdin_40_96.inc + +apple_40_96.inc: png_to_40x96 apple_40_96.png + ./png_to_40x96 asm apple_40_96.png apple > apple_40_96.inc + +### + +katahdin_40_48d.inc: png_to_40x48d katahdin_40_48d.png + ./png_to_40x48d asm katahdin_40_48d.png katahdin > katahdin_40_48d.inc + +apple_40_48d.inc: png_to_40x48d apple_40_48d.png + ./png_to_40x48d asm apple_40_48d.png apple > apple_40_48d.inc + + + +### + install: cp png_to_40x96 $(INSTALL_LOC) clean: - rm -f *~ *.o *.lst *.inc png_to_40x96 DISP4096 + rm -f *~ *.o *.lst *.inc png_to_40x96 png_to_40x48d DISP4096 DISP4048D diff --git a/fancy_lores/disp4048d.s b/fancy_lores/disp4048d.s new file mode 100644 index 00000000..dbe9792b --- /dev/null +++ b/fancy_lores/disp4048d.s @@ -0,0 +1,352 @@ +; Display a 40x48d lo-res image + +; Uses the 40x48d page1/page2 every-1-scanline pageflip mode + +; by deater (Vince Weaver) + +; Zero Page +FRAMEBUFFER = $00 ; $00 - $0F +YPOS = $10 +YPOS_SIN = $11 +CH = $24 +CV = $25 +GBASL = $26 +GBASH = $27 +BASL = $28 +BASH = $29 +FRAME = $60 +BLARGH = $69 +DRAW_PAGE = $EE +LASTKEY = $F1 +PADDLE_STATUS = $F2 +TEMP = $FA +WHICH = $FB + +; Soft Switches +KEYPRESS= $C000 +KEYRESET= $C010 +SET_GR = $C050 ; Enable graphics +FULLGR = $C052 ; Full screen, no text +PAGE0 = $C054 ; Page0 +PAGE1 = $C055 ; Page1 +LORES = $C056 ; Enable LORES graphics +PADDLE_BUTTON0 = $C061 +PADDL0 = $C064 +PTRIG = $C070 + +; ROM routines + +TEXT = $FB36 ;; Set text mode +HOME = $FC58 ;; Clear the text screen +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us + +MAX = 2 + + lda #$ff + sta WHICH + +start_over: + inc WHICH + lda WHICH + cmp #MAX + bne in_range + lda #0 + sta WHICH + +in_range: + + ;=================== + ; init screen + jsr TEXT + jsr HOME + bit KEYRESET + + ;=================== + ; init vars + + lda #0 + sta DRAW_PAGE + + ;============================= + ; Load graphic page0 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + + lda WHICH + asl + asl ; which*4 + tay + + lda pictures,Y + sta GBASL + lda pictures+1,Y + sta GBASH + jsr load_rle_gr + + lda #4 + sta DRAW_PAGE + + jsr gr_copy_to_current ; copy to page1 + + ; GR part + bit PAGE1 + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + jsr wait_until_keypressed + + + ;============================= + ; Load graphic page1 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + + lda WHICH + asl + asl ; which*4 + tay + + lda pictures+2,Y + sta GBASL + lda pictures+3,Y + sta GBASH + jsr load_rle_gr + + lda #0 + sta DRAW_PAGE + + jsr gr_copy_to_current + + ; GR part + bit PAGE0 + + jsr wait_until_keypressed + + + ;============================== + ; setup graphics for vapor lock + ;============================== + + ; Clear Page0 + lda #$0 + sta DRAW_PAGE + lda #$44 + jsr clear_gr + + ; Make screen half green + lda #$11 + ldy #24 + jsr clear_page_loop + + + ;===================================================== + ; attempt vapor lock + ; by reading the "floating bus" we can see most recently + ; written value of the display + ; we look for $55 (which is the grey line) + ;===================================================== + ; See: + ; Have an Apple Split by Bob Bishop + ; Softalk, October 1982 + + ; Challenges: each scan line scans 40 bytes. + ; The blanking happens at the *beginning* + ; So 65 bytes are scanned, starting at adress of the line - 25 + + ; the scan takes 8 cycles, look for 4 repeats of the value + ; to avoid false positive found if the horiz blanking is mirroring + ; the line (max 3 repeats in that case) + +vapor_lock_loop: ; first make sure we have all zeroes + LDA #$11 +zxloop: + LDX #$04 +wiloop: + CMP $C051 + BNE zxloop + DEX + BNE wiloop + + LDA #$44 ; now look for our border color (4 times) +zloop: + LDX #$04 +qloop: + CMP $C051 + BNE zloop + DEX + BNE qloop + + ; found first line of black after green, at up to line 26 on screen + ; so we want roughly 22 lines * 4 = 88*65 = 5720 + 4550 = 10270 + ; - 65 (for the scanline we missed) = 10205 - 12 = 10193 + + jsr gr_copy_to_current ; 6+ 9292 + ; 10193 - 9298 = 895 + ; Fudge factor (unknown) -30 = 865 + + ; GR part + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + ; Try X=88 Y=2 cycles=893 R2 + + nop + ldy #2 ; 2 +loopA: + ldx #88 ; 2 +loopB: + dex ; 2 + bne loopB ; 2nt/3 + + dey ; 2 + bne loopA ; 2nt/3 + + jmp display_loop +.align $100 + + + ;================================================ + ; Display Loop + ;================================================ + ; each scan line 65 cycles + ; 1 cycle each byte (40cycles) + 25 for horizontal + ; Total of 12480 cycles to draw screen + ; Vertical blank = 4550 cycles (70 scan lines) + ; Total of 17030 cycles to get back to where was + + ; We want to alternate between page1 and page2 every 65 cycles + ; vblank = 4550 cycles to do scrolling + + + ; 2 + 48*( (4+2+25*(2+3)) + (4+2+23*(2+3)+4+5)) + 9) + ; 48*[(6+125)-1] + [(6+115+10)-1] + +display_loop: + + ldy #96 ; 2 + +outer_loop: + + bit PAGE0 ; 4 + ldx #12 ; 65 cycles with PAGE0 ; 2 +page0_loop: ; delay 61+bit + dex ; 2 + bne page0_loop ; 2/3 + + + ; bit(4) -1(fallthrough) + loop*5 -1(fallthrouh)+4 extra = 61 + ; 5L = 55 + + bit PAGE1 ; 4 + ldx #11 ; 65 cycles with PAGE1 ; 2 + ; +page1_loop: ; delay 115+(7 loop)+4 (bit)+4(extra) + dex ; 2 + bne page1_loop ; 2/3 + + dey ; 2 + bne outer_loop ; 2/3 + + + + ;====================================================== + ; We have 4550 cycles in the vblank, use them wisely + ;====================================================== + ; do_nothing should be 4550+1 -2-9 -7= 4533 + + jsr do_nothing ; 6 + + lda KEYPRESS ; 4 + bpl no_keypress ; 3 + jmp start_over +no_keypress: + + jmp display_loop ; 3 + + + + ;================================= + ; do nothing + ;================================= + ; and take 4533-6 = 4527 cycles to do it +do_nothing: + + ; Try X=4 Y=174 cycles=4525 R2 + + nop ; 2 + + ldy #174 ; 2 +loop1: + ldx #4 ; 2 +loop2: + dex ; 2 + bne loop2 ; 2nt/3 + + dey ; 2 + bne loop1 ; 2nt/3 + + + rts ; 6 + + + + ;================================== + ; HLINE + ;================================== + + ; Color in A + ; Y has which line +hline: + pha ; 3 + ldx gr_offsets,y ; 4+ + stx hline_loop+1 ; 4 + lda gr_offsets+1,y ; 4+ + clc ; 2 + adc DRAW_PAGE ; 3 + sta hline_loop+2 ; 4 + pla ; 4 + ldx #39 ; 2 +hline_loop: + sta $5d0,X ; 38 ; 5 + dex ; 2 + bpl hline_loop ; 2nt/3 + rts ; 6 + + ;========================== + ; Clear gr screen + ;========================== + ; Color in A +clear_gr: + ldy #46 +clear_page_loop: + jsr hline + dey + dey + bpl clear_page_loop + rts + +gr_offsets: + .word $400,$480,$500,$580,$600,$680,$700,$780 + .word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8 + .word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0 + + +.include "../asm_routines/gr_unrle.s" +.include "../asm_routines/keypress.s" +.include "gr_copy.s" + +pictures: + .word apple_low,apple_high + .word katahdin_low,katahdin_high + +.include "apple_40_48d.inc" +.include "katahdin_40_48d.inc" + diff --git a/fancy_lores/fancy_lores_viewer.dsk b/fancy_lores/fancy_lores_viewer.dsk index 3469203442d34bf132f44c3e4bf4472408d6aa5d..95b65a5e6bd941ef5c5d7c76aa3dc9b72941acc5 100644 GIT binary patch literal 143360 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 aS5yKPpJf{17cpg*+3G;1EV$gufBqjIERswB literal 143360 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 Wjd2tvrhNOF@m1`<@Hc7(vi*OkUqhS# diff --git a/fancy_lores/genpal.c b/fancy_lores/genpal.c index 81bc0ee8..ce998318 100644 --- a/fancy_lores/genpal.c +++ b/fancy_lores/genpal.c @@ -48,11 +48,22 @@ void gen_color(int col1, int col2) { return; } +void hex_color(int col1, int col2) { + + if (col1>=col2) + printf("\t\tcase 0x%02x%02x%02x: hi=%d; low=%d; break;\n", + average(gr_colors[col1][0],gr_colors[col2][0]), + average(gr_colors[col1][1],gr_colors[col2][1]), + average(gr_colors[col1][2],gr_colors[col2][2]),col1,col2); + + return; +} + int main(int argc, char **argv) { int x,y; - +#if 1 printf("GIMP Palette\n"); printf("Name: Apple II Lores Dither.gpl\n"); printf("Columns: 16\n"); @@ -62,5 +73,12 @@ int main(int argc, char **argv) { gen_color(x,y); } } +#else + for(x=0;x<16;x++) { + for(y=0;y<16;y++) { + hex_color(x,y); + } + } +#endif return 0; } diff --git a/fancy_lores/png_to_40x48d.c b/fancy_lores/png_to_40x48d.c new file mode 100644 index 00000000..e065f01f --- /dev/null +++ b/fancy_lores/png_to_40x48d.c @@ -0,0 +1,571 @@ +/* Convert a 40x48d image into two, 40x48 images suitable of loading */ +/* with my kfest18 based code, inteleaving at one scanline resolution */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define OUTPUT_C 0 +#define OUTPUT_ASM 1 + + +static int convert_color(int color,int which) { + + int hi,low; + + switch(color) { + case 0x000000: hi=0; low=0; break; + case 0xa01543: hi=1; low=0; break; + case 0xe31e60: hi=1; low=1; break; + case 0x433785: hi=2; low=0; break; + case 0xae3b95: hi=2; low=1; break; + case 0x604ebd: hi=2; low=2; break; + case 0xb430b2: hi=3; low=0; break; + case 0xf134bf: hi=3; low=1; break; + case 0xc049df: hi=3; low=2; break; + case 0xff44fd: hi=3; low=3; break; + case 0x007343: hi=4; low=0; break; + case 0xa07560: hi=4; low=1; break; + case 0x437f95: hi=4; low=2; break; + case 0xb47cbf: hi=4; low=3; break; + case 0x00a360: hi=4; low=4; break; + case 0x6e6e6e: hi=5; low=0; break; + case 0xc27081: hi=5; low=1; break; + case 0x817bad: hi=5; low=2; break; + case 0xd378d2: hi=5; low=3; break; + case 0x6e9f81: hi=5; low=4; break; + case 0x9c9c9c: hi=5; low=5; break; + case 0x0e92b2: hi=6; low=0; break; + case 0xa193bf: hi=6; low=1; break; + case 0x459cdf: hi=6; low=2; break; + case 0xb49afd: hi=6; low=3; break; + case 0x0ebabf: hi=6; low=4; break; + case 0x6fb7d2: hi=6; low=5; break; + case 0x14cffd: hi=6; low=6; break; + case 0x9389b4: hi=7; low=0; break; + case 0xd98bc0: hi=7; low=1; break; + case 0xa194e0: hi=7; low=2; break; + case 0xe892fe: hi=7; low=3; break; + case 0x93b3c0: hi=7; low=4; break; + case 0xb7b0d3: hi=7; low=5; break; + case 0x93c9fe: hi=7; low=6; break; + case 0xd0c3ff: hi=7; low=7; break; + case 0x435002: hi=8; low=0; break; + case 0xae5343: hi=8; low=1; break; + case 0x606185: hi=8; low=2; break; + case 0xc05db2: hi=8; low=3; break; + case 0x438c43: hi=8; low=4; break; + case 0x81886e: hi=8; low=5; break; + case 0x45a7b2: hi=8; low=6; break; + case 0xa19fb4: hi=8; low=7; break; + case 0x607203: hi=8; low=8; break; + case 0xb44a2a: hi=9; low=0; break; + case 0xf14d50: hi=9; low=1; break; + case 0xc05d8c: hi=9; low=2; break; + case 0xff59b7: hi=9; low=3; break; + case 0xb48950: hi=9; low=4; break; + case 0xd38576: hi=9; low=5; break; + case 0xb4a4b7: hi=9; low=6; break; + case 0xe89cb9: hi=9; low=7; break; + case 0xc06e2a: hi=9; low=8; break; + case 0xff6a3c: hi=9; low=9; break; +#if 0 + case 0x6f6f6f: hi=10; low=0; break; + case 0xc37182: hi=10; low=1; break; + case 0x827bad: hi=10; low=2; break; + case 0xd378d2: hi=10; low=3; break; + case 0x6fa082: hi=10; low=4; break; + case 0x9c9c9c: hi=10; low=5; break; + case 0x6fb7d2: hi=10; low=6; break; + case 0xb8b1d3: hi=10; low=7; break; + case 0x82896f: hi=10; low=8; break; + case 0xd38576: hi=10; low=9; break; + case 0x9d9d9d: hi=10; low=10; break; +#endif + case 0xb47193: hi=11; low=0; break; + case 0xf173a1: hi=11; low=1; break; + case 0xc07dc6: hi=11; low=2; break; + case 0xff7ae7: hi=11; low=3; break; + case 0xb4a1a1: hi=11; low=4; break; + case 0xd39eb7: hi=11; low=5; break; + case 0xb4b8e7: hi=11; low=6; break; + case 0xe8b2e8: hi=11; low=7; break; + case 0xc08a93: hi=11; low=8; break; + case 0xff8799: hi=11; low=9; break; + case 0xd39eb8: hi=11; low=10; break; + case 0xffa0d0: hi=11; low=11; break; + case 0x0ead2a: hi=12; low=0; break; + case 0xa1ae50: hi=12; low=1; break; + case 0x45b58c: hi=12; low=2; break; + case 0xb4b3b7: hi=12; low=3; break; + case 0x0ed050: hi=12; low=4; break; + case 0x6fcd76: hi=12; low=5; break; + case 0x14e2b7: hi=12; low=6; break; + case 0x93ddb9: hi=12; low=7; break; + case 0x45bf2a: hi=12; low=8; break; + case 0xb4bc3c: hi=12; low=9; break; +// case 0x6fcd76: hi=12; low=10; break; + case 0xb4ce99: hi=12; low=11; break; + case 0x14f53c: hi=12; low=12; break; + case 0x939c63: hi=13; low=0; break; + case 0xd99d78: hi=13; low=1; break; + case 0xa1a5a6: hi=13; low=2; break; + case 0xe8a3cc: hi=13; low=3; break; + case 0x93c278: hi=13; low=4; break; + case 0xb7bf94: hi=13; low=5; break; + case 0x93d6cc: hi=13; low=6; break; + case 0xd0d0ce: hi=13; low=7; break; + case 0xa1af63: hi=13; low=8; break; + case 0xe8ad6c: hi=13; low=9; break; + case 0xb8bf95: hi=13; low=10; break; + case 0xe8c0b1: hi=13; low=11; break; + case 0x93e96c: hi=13; low=12; break; + case 0xd0dd8d: hi=13; low=13; break; + case 0x50b493: hi=14; low=0; break; + case 0xb3b5a1: hi=14; low=1; break; + case 0x69bcc6: hi=14; low=2; break; + case 0xc5bae7: hi=14; low=3; break; + case 0x50d6a1: hi=14; low=4; break; + case 0x88d3b7: hi=14; low=5; break; + case 0x51e8e7: hi=14; low=6; break; + case 0xa7e2e8: hi=14; low=7; break; + case 0x69c593: hi=14; low=8; break; + case 0xc5c399: hi=14; low=9; break; + case 0x89d3b8: hi=14; low=10; break; + case 0xc5d4d0: hi=14; low=11; break; + case 0x51fa99: hi=14; low=12; break; + case 0xa7eeb1: hi=14; low=13; break; + case 0x72ffd0: hi=14; low=14; break; + case 0xb4b4b4: hi=15; low=0; break; + case 0xf1b5c0: hi=15; low=1; break; + case 0xc0bce0: hi=15; low=2; break; + case 0xffbafe: hi=15; low=3; break; + case 0xb4d6c0: hi=15; low=4; break; + case 0xd3d3d3: hi=15; low=5; break; + case 0xb4e8fe: hi=15; low=6; break; + case 0xe8e2ff: hi=15; low=7; break; + case 0xc0c5b4: hi=15; low=8; break; + case 0xffc3b9: hi=15; low=9; break; +// case 0xd3d3d3: hi=15; low=10; break; + case 0xffd4e8: hi=15; low=11; break; + case 0xb4fab9: hi=15; low=12; break; + case 0xe8eece: hi=15; low=13; break; + case 0xc5ffe8: hi=15; low=14; break; + case 0xffffff: hi=15; low=15; break; + + + default: + printf("Unknown color %x\n",color); + break; + } + + if (which==0) return hi; + else return low; +} + + + +/* expects a PNG where the xsize is 40 */ +int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize, + int high) { + + int x,y; + int color; + FILE *infile; + int debug=0; + 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 number_of_passes; + + 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 (debug) { + printf("PNG: width=%d height=%d depth=%d\n",width,height,bit_depth); + if (color_type==PNG_COLOR_TYPE_RGB) printf("Type RGB\n"); + else if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) printf("Type RGBA\n"); + else if (color_type==PNG_COLOR_TYPE_PALETTE) printf("Type palette\n"); + } + +// number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (y=0; y2) && (run<16)) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,",0xA0|run,last); + } + else { + printf("$%02X,$%02X",0xA0|run,last); + } + size+=2; + } + + if (run>=16) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,0x%02X,",0xA0,run,last); + } + else { + printf("$%02X,$%02X,$%02X",0xA0,run,last); + } + size+=3; + } + + return size; +} + +int rle_smaller(int out_type, char *varname, + int xsize,int ysize, unsigned char *image,int high) { + + int run=0; + int x; + + int last=-1,next; + int size=0; + int count=0; + + x=0; + + /* Write out xsize and ysize */ + + if (out_type==OUTPUT_C) { + fprintf(stdout,"unsigned char %s_%s[]={\n",varname, + high?"high":"low"); + fprintf(stdout,"\t0x%X, /* ysize=%d */",xsize,ysize); + } + else { + fprintf(stdout,"%s_%s:",varname,high?"high":"low"); + fprintf(stdout,"\t.byte $%X ; ysize=%d",xsize,ysize); + } + + size+=2; + + /* Get first top/bottom color pair */ + last=image[x]; + run++; + x++; + + while(1) { + + /* get next top/bottom color pair */ + next=image[x]; + + if ((next&0xf0)==0xA0) { + fprintf(stderr,"Warning! Using color A (grey2)!\n"); + next&=~0xf0; + next|=0x50; // substitute grey1 + } + + /* If color change (or too big) then output our run */ + /* Note 0xff for run length is special case meaning "finished" */ + if ((next!=last) || (run>254)) { + + size+=print_run(count,out_type,run,last); + + count++; + run=0; + last=next; + } + + x++; + + /* If we reach the end */ + if (x>=xsize*(ysize/2)) { + run++; + + size+=print_run(count,out_type,run,last); + + break; + + } + + run++; + if (count>6) count=0; + + } + + /* Print closing marker */ + + if (out_type==OUTPUT_C) { + fprintf(stdout,"0xA1,"); + fprintf(stdout,"\t};\n"); + } else { + fprintf(stdout,"\n\t.byte $A1\n"); + } + + size+=1; + + return size; +} + + + +/* Converts a PNG to RLE compressed data */ + +int main(int argc, char **argv) { + + unsigned char *image; + int xsize,ysize; + int size=0; + int out_type=OUTPUT_C; + + if (argc<4) { + fprintf(stderr,"Usage:\t%s type INFILE varname\n\n",argv[0]); + fprintf(stderr,"\ttype: c or asm\n"); + fprintf(stderr,"\tvarname: label for graphic\n"); + fprintf(stderr,"\n"); + + exit(-1); + } + + if (!strcmp(argv[1],"c")) { + out_type=OUTPUT_C; + } + else if (!strcmp(argv[1],"asm")) { + out_type=OUTPUT_ASM; + } + + if (loadpng(argv[2],&image,&xsize,&ysize,1)<0) { + fprintf(stderr,"Error loading png!\n"); + exit(-1); + } + + fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize); + +// size=rle_original(out_type,argv[3], +// xsize,ysize,image); + + size=rle_smaller(out_type,argv[3], + xsize,ysize,image,0); + + fprintf(stderr,"Size %d bytes\n",size); + + if (loadpng(argv[2],&image,&xsize,&ysize,0)<0) { + fprintf(stderr,"Error loading png!\n"); + exit(-1); + } + + fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize); + +// size=rle_original(out_type,argv[3], +// xsize,ysize,image); + + size=rle_smaller(out_type,argv[3], + xsize,ysize,image,1); + + fprintf(stderr,"Size %d bytes\n",size); + + + return 0; +} + + + + + + +