diff --git a/demosplash/Makefile b/demosplash/Makefile index e7c504f3..4a9e71b3 100644 --- a/demosplash/Makefile +++ b/demosplash/Makefile @@ -3,6 +3,7 @@ include ../Makefile.inc DOS33 = ../dos33fs-utils/dos33 PNG2RLE = ../gr-utils/png2rle PNG2LZ4 = ../gr-utils/png2lz4 +PNG_TO_40x96 = ../gr-utils/png_to_40x96 all: demosplash.dsk @@ -27,12 +28,19 @@ DEMOSPLASH: demosplash.o demosplash.o: demosplash.s \ zp.inc hardware.inc \ + appleII_intro.s vapor_lock.s delay_a.s \ pt3_lib.s mockingboard_a.s pt3_setup.s interrupt_handler.s \ - dya_space_demo.pt3 + dya_space_demo.pt3 appleII_40_96.inc ca65 -o demosplash.o demosplash.s -l demosplash.lst ##### +appleII_40_96.inc: appleII_40_96.png + $(PNG_TO_40x96) asm appleII_40_96.png appleII > appleII_40_96.inc + + +##### + clean: rm -f *~ *.o *.lst *.lz4 HELLO \ DEMOSPLASH diff --git a/demosplash/appleII_40_96.png b/demosplash/appleII_40_96.png new file mode 100644 index 00000000..9aef78fa Binary files /dev/null and b/demosplash/appleII_40_96.png differ diff --git a/demosplash/appleII_intro.s b/demosplash/appleII_intro.s new file mode 100644 index 00000000..7a29899a --- /dev/null +++ b/demosplash/appleII_intro.s @@ -0,0 +1,185 @@ +; Display a 40x96 lo-res image + +; by deater (Vince Weaver) + + +appleII_intro: + + ;=================== + ; init screen + jsr TEXT + jsr HOME + bit KEYRESET + + ;=================== + ; init vars + + lda #0 + sta DRAW_PAGE + + ;============================= + ; Load graphic page0 + + lda #appleII_low + sta GBASH + lda #$c + 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 #appleII_high + sta GBASH + lda #$c + 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 + ;============================== + + jsr vapor_lock ; 6+ + + ; vapor lock returns with us at beginning of hsync in line + ; 114 (7410 cycles), so with 5070 lines to go + + ; GR part + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + jsr gr_copy_to_current ; 6+ 9292 + + ; now we have 322 left + + ; 322 - 12 = 310 + ; - 3 for jmp + ; 307 + + ; Try X=9 Y=6 cycles=307 + ldy #6 ; 2 +loopA: ldx #9 ; 2 +loopB: dex ; 2 + bne loopB ; 2nt/3 + dey ; 2 + bne loopA ; 2nt/3 + + jmp display_loop ; 3 + +.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 #48 ; 2 + +outer_loop: + + bit PAGE0 ; 4 + ldx #25 ; 130 cycles with PAGE0 ; 2 +page0_loop: ; delay 126+bit + dex ; 2 + bne page0_loop ; 2/3 + + + bit PAGE1 ; 4 + ldx #23 ; 130 cycles with PAGE1 ; 2 +page1_loop: ; delay 115+(7 loop)+4 (bit)+4(extra) + dex ; 2 + bne page1_loop ; 2/3 + + nop ; 2 + lda DRAW_PAGE ; 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 appleii_done +no_keypress: + + jmp display_loop ; 3 + +appleii_done: + rts + + + ;================================= + ; 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 + + + diff --git a/demosplash/delay_a.s b/demosplash/delay_a.s new file mode 100644 index 00000000..2d0802da --- /dev/null +++ b/demosplash/delay_a.s @@ -0,0 +1,25 @@ +; From http://6502org.wikidot.com/software-delay + +; 25+A cycles (including JSR), 19 bytes (excluding JSR) +; +; The branches must not cross page boundaries! +; + + ; Cycles Accumulator Carry flag + ; 0 1 2 3 4 5 6 (hex) 0 1 2 3 4 5 6 + +; jsr delay_a ; 6 6 6 6 6 6 6 00 01 02 03 04 05 06 + +dly0: sbc #7 +delay_a:cmp #7 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0 + bcs dly0 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0 + lsr ; 2 2 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 + bcs dly1 ; 2 3 2 3 2 3 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 +dly1: beq dly2 ; 3 3 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 + lsr ; 2 2 2 2 2 00 00 01 01 01 1 1 0 0 1 + beq dly3 ; 3 3 2 2 2 00 00 01 01 01 1 1 0 0 1 + bcc dly3 ; 3 3 2 01 01 01 0 0 1 +dly2: bne dly3 ; 2 2 3 00 00 01 0 1 0 +dly3: rts ; 6 6 6 6 6 6 6 00 00 00 00 01 01 01 0 1 1 1 0 0 1 + ; + ; Total cycles: 25 26 27 28 29 30 31 diff --git a/demosplash/demosplash.s b/demosplash/demosplash.s index 25b27c40..9544d2b5 100644 --- a/demosplash/demosplash.s +++ b/demosplash/demosplash.s @@ -6,16 +6,19 @@ ending: + + jsr appleII_intro + ;========================= ; set up sound ;========================= - jsr pt3_setup +; jsr pt3_setup - lda #1 - sta LOOP +; lda #1 +; sta LOOP - jsr wait_until_keypressed +; jsr wait_until_keypressed ;=========================== @@ -46,7 +49,7 @@ ending: ; start music - cli ; enable interrupts +; cli ; enable interrupts ; wait wait wait @@ -66,12 +69,18 @@ wait_until_keypressed: rts +; Apple II intro +.include "appleII_intro.s" +.include "appleII_40_96.inc" +.include "vapor_lock.s" +.include "delay_a.s" +.include "gr_unrle.s" +.include "gr_offsets.s" +.include "gr_copy.s" + ;.include "text_print.s" ;.include "gr_pageflip.s" -;.include "gr_unrle.s" ;.include "gr_fast_clear.s" -;.include "gr_copy.s" -;.include "gr_offsets.s" ;.include "gr_overlay.s" .include "pt3_setup.s" @@ -89,8 +98,3 @@ PT3_LOC = song .align 256 song: .incbin "dya_space_demo.pt3" - - - - - diff --git a/demosplash/gr_copy.s b/demosplash/gr_copy.s new file mode 100644 index 00000000..acd83f6f --- /dev/null +++ b/demosplash/gr_copy.s @@ -0,0 +1,58 @@ + ;========================================================= + ; gr_copy_to_current, 40x48 version + ;========================================================= + ; copy 0xc00 to DRAW_PAGE + ; + ; 45 + 2 + 120*(8*9 + 5) -1 + 6 = 9292 + +gr_copy_to_current: + + lda DRAW_PAGE ; 3 + clc ; 2 + adc #$4 ; 2 + sta gr_copy_line+5 ; 4 + sta gr_copy_line+11 ; 4 + adc #$1 ; 2 + sta gr_copy_line+17 ; 4 + sta gr_copy_line+23 ; 4 + adc #$1 ; 2 + sta gr_copy_line+29 ; 4 + sta gr_copy_line+35 ; 4 + adc #$1 ; 2 + sta gr_copy_line+41 ; 4 + sta gr_copy_line+47 ; 4 + ;=========== + ; 45 + + ldy #119 ; for early ones, copy 120 bytes ; 2 + +gr_copy_line: + lda $C00,Y ; load a byte (self modified) ; 4 + sta $400,Y ; store a byte (self modified) ; 5 + + lda $C80,Y ; load a byte (self modified) ; 4 + sta $480,Y ; store a byte (self modified) ; 5 + + lda $D00,Y ; load a byte (self modified) ; 4 + sta $500,Y ; store a byte (self modified) ; 5 + + lda $D80,Y ; load a byte (self modified) ; 4 + sta $580,Y ; store a byte (self modified) ; 5 + + lda $E00,Y ; load a byte (self modified) ; 4 + sta $600,Y ; store a byte (self modified) ; 5 + + lda $E80,Y ; load a byte (self modified) ; 4 + sta $680,Y ; store a byte (self modified) ; 5 + + lda $F00,Y ; load a byte (self modified) ; 4 + sta $700,Y ; store a byte (self modified) ; 5 + + lda $F80,Y ; load a byte (self modified) ; 4 + sta $780,Y ; store a byte (self modified) ; 5 + + dey ; decrement pointer ; 2 + bpl gr_copy_line ; ; 2nt/3 + + rts ; 6 + diff --git a/demosplash/gr_offsets.s b/demosplash/gr_offsets.s new file mode 100644 index 00000000..d3af91f7 --- /dev/null +++ b/demosplash/gr_offsets.s @@ -0,0 +1,5 @@ +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 + diff --git a/demosplash/gr_unrle.s b/demosplash/gr_unrle.s new file mode 100644 index 00000000..5e0b5dd5 --- /dev/null +++ b/demosplash/gr_unrle.s @@ -0,0 +1,112 @@ + ;================= + ; load RLE image + ;================= + ; Output is A:00 (assume page aligned) + ; Input is in GBASH/GBASL + + ; format: first byte=xsize + ; A0,X,Y means run of X bytes of Y color + ; A1 means end of file + ; A2-AF,X means run of low nibble, X color + ; if high nibble not A: just display color + + ; CV = current Y + ; CH = max xsize (usually 40) + ; TEMP = page + ; TEMPY= current X + + +load_rle_gr: + sec + sbc #4 ; adjust page to write to + ; to match gr_offsets + sta TEMP + + ldy #$0 ; init Y to 0 + sty CV + + jsr load_and_increment ; load xsize + sta CH + + jsr unrle_new_y + + +rle_loop: + jsr load_and_increment + + tax + + cmp #$A1 ; if 0xa1 + beq rle_done ; we are done + + and #$f0 ; mask + cmp #$a0 ; see if special AX + beq decompress_special + + ; not special, just color + + txa ; put color back in A + ldx #$1 ; only want to print 1 + bne decompress_run + +decompress_special: + txa ; put read value back in A + + and #$0f ; check if was A0 + + bne decompress_color ; if A0 need to read run, color + +decompress_large: + jsr load_and_increment ; run length now in A + +decompress_color: + tax ; put runlen into X + jsr load_and_increment ; get color into A + +decompress_run: +rle_run_loop: + sta (BASL),y ; write out the value + inc BASL + dec TEMPY + bne rle_not_eol ; if less then keep going + + ; if here, we are > max_X + + inc CV + inc CV + pha + jsr unrle_new_y + pla + +rle_not_eol: + dex + bne rle_run_loop ; if not zero, keep looping + + beq rle_loop ; and branch always + +rle_done: + lda #$15 ; move the cursor somewhere sane + sta CV + rts + + +load_and_increment: + lda (GBASL),Y + inc GBASL + bne lai_no_oflo + inc GBASH +lai_no_oflo: + rts + +unrle_new_y: + ldy CV + lda gr_offsets,Y + sta BASL + lda gr_offsets+1,Y + clc + adc TEMP ; adjust for page + sta BASH + lda CH + sta TEMPY + ldy #0 + rts diff --git a/demosplash/vapor_lock.s b/demosplash/vapor_lock.s new file mode 100644 index 00000000..5a8db3b1 --- /dev/null +++ b/demosplash/vapor_lock.s @@ -0,0 +1,274 @@ +; This took a while to track down +; On Apple II/II+ the horiz blanking addr are $1000 higher than on IIe +; So on II+ were outside video area, so unlikely to be our set value +; (unless I foolishly use $ff which some uninitialized mem is set to) +; Lots of this color fiddling is to make sure you don't accidentally +; get runs of colors on IIe due to the horiz blank + +; 0-5 aqua 6-12 = grey, 13 - 20 = yellow, 21-23 = aqua rainbow 14 +; +; +;16 0 YA +;17 1 YA +;18 2 YA +;19 3 YA +;20 4 YA +;21 5 AA +;22 6 AG +;23 7 AG +;0 8 AG +;1 9 AG +;2 10 AG +;3 11 AG +;4 12 AG +;5 13 AY **** +;6 14 GY RAINBOW +;7 15 GY +;8 16 GY +;9 17 GY +;10 18 GY +;11 19 GY +;12 20 GY +;13 21 YA +;14 22 YA +;15 23 YA + + + + ;============================== + ; setup graphics for vapor lock + ;============================== +vapor_lock: + + ; Clear Page0 + lda #$0 + sta DRAW_PAGE + lda #$ee ; full screen white $ff + jsr clear_gr + + lda #$dd + ldy #40 + jsr clear_page_loop ; make bottom half yellow $dd + + lda #$aa + ldy #24 + jsr clear_page_loop ; make middle grey2 $aa + + lda #$ee + ldy #10 + jsr clear_page_loop ; make top half aqua $ee + + ; set up a rainbow to aid in exact lock + + ldy #00 +rainbow_loop: + tya + sta $728+20,Y + iny + cpy #20 + bne rainbow_loop + +;btt: +; jmp btt + + + ;===================================================== + ; attempt vapor lock + ; by reading the "floating bus" we can see most recently + ; written value of the display + ;===================================================== + ; 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 a full line of $aa + + lda #$aa ; 2 +zxloop: + ldx #$04 ; 2 +wiloop: + cmp $C051 ; read the floating bus ; 4 + bne zxloop ; if not, start from scratch ; 2/3 + dex ; we were, dec ; 2 + bne wiloop ; if not 4 of them, restart ; 3/2 + + ; if we get here we read 4 proper pixels, 11 apart (2+4+2+2+3) + ; 0 11 22 33, clock at 34 + ; 1 12 23 34, clock at 35 + ; 2 13 24 35, clock at 36 + ; 3 14 25 36, clock at 37 + ; 4 15 26 37, clock at 38 + ; 5 16 27 38, clock at 39 + ; 6 17 28 39, clock at 40 + + +; X X X X +; X X X X +; X X X X +; X X X X +; X X X X +; X X X X +; X X X X +; 0123456789012345678901234 0123456789012345678901234567890123456789 +; 1 2 1 2 3 +; hsync pixels +; XXXXXXXXXXXXXXXXXXXXXXXXX 4444444444444444444444444444440123456789 + + ; now look for the color change that + ; happens at line 13*8 = 104 + + lda #$dd ; 2 +zloop: + ldx #$04 ; 2 +qloop: + cmp $C051 ; read floating bus ; 4 + bne zloop ; 2/3 + dex ; 2 + bne qloop ; 3/2 + ;============ + ; 11 + + ; Found it! + ; if we get here we read 4 proper pixels, 11 apart (2+4+2+2+3) + ; 0 11 22 33, clock at 34 + ; 1 12 23 34, clock at 35 + ; 2 13 24 35, clock at 36 + ; 3 14 25 36, clock at 37 + ; 4 15 26 37, clock at 38 + ; 5 16 27 38, clock at 39 + ; 6 17 28 39, clock at 40 + + + + +;btt: +; jmp btt + + ; In theory near end of line 104 + + ; now skip ahead 8 lines and read from the rainbow pattern we set + ; up to find our exact location + + ; delay 65 * 8 = 520 + ; we back off a few to make sure we're not in the horiz blank + ; try to delay 510 + + ; *NOTE* sometimes we end up going one (or rarely, two??) lines too far + ; so instead try going 7 lines ahead, and if still dd then one more + + ; so single step until we get a rainbow color + + ; go to next line, -10 + lda #28 ; 2 + jsr delay_a ; delay 25+28 = 53 + ; total delay = 55 + +vl_try_again: + lda #29 ; 2 + jsr delay_a ; delay 25+29 = 54 + ; total delay = 56 + + + + lda $C051 ; 4 + cmp #$dd ; 2 + beq vl_try_again ; 3 + ; -1 + + + ; now near end of line 112 + ;lda $0 ; nop to match old code ; 3 +; nop ; nop to match old code ; 2 + + lda $C051 ; 4 +;kbb: +; jmp kbb + + ; we are in theory on line $728 = 14*8 = 112 + ; so 112*65 = 7280 cycles from start + + ; we are actualy 25+20+A pixels in + ; 7325+A + + ; Our goal is line 114 at 7410 cycles + ; 7410 - 7325 = 85 + + ; so kill 85-A cycles + ; -6 to do subtraction + ; -6 for rts + ; -25 for delay_a overhead + + eor #$ff ; 2 + sec ; 2 + adc #48 ; 2 + + jsr delay_a ; should total 48 cycles + + +done_vapor_lock: + rts ; 6 + + + ;================================== + ; Vapor HLINE + ;================================== + ; FIXME: merge with generic hline code? + ; 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 + + + + ; Some random related work + ; Docs: + ; Lancaster + ; Bishop + ; Sather + + ; Vaguely relevant but no help with the Apple II+ issue + ; + ; Eamon: Screen display and timing synchronization + ; on the Apple IIe and Apple IIgs + ; + ; Adams: Visually presented verbal stimuli by assembly + ; language on the Apple II computer. + ; Cavanagh and Anstis: Visual psychophysics on the + ; Apple II: Getting started diff --git a/gr-utils/rle_common.c b/gr-utils/rle_common.c new file mode 100644 index 00000000..b1bf3a7b --- /dev/null +++ b/gr-utils/rle_common.c @@ -0,0 +1,337 @@ +#include +#include + +#include +#include +#include +#include +#include + +//#include "loadpng.h" + +#define OUTPUT_C 0 +#define OUTPUT_ASM 1 +#define OUTPUT_RAW 2 + + + +/*****************************************/ +/* \/ \/ */ +/* Converts a PNG to RLE compressed data */ +/*****************************************/ + + +static int print_run(int count, int out_type, int run, int last) { + + int size=0; + + if (count==0) { + if (out_type==OUTPUT_C) { + printf("\n\t"); + } + else if (out_type==OUTPUT_ASM) { + printf("\n\t.byte "); + } + } + else { + if (out_type==OUTPUT_C) { + } + else if (out_type==OUTPUT_ASM) { + printf(", "); + } + } + + if (run==1) { + if ((last&0xf0)==0xA0) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,0x%02X,",0xa0,1,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X,$%02X",0xa0,1,last); + } + else { + printf("%c%c%c",0xa0,1,last); + } + size+=3; + } + else { + if (out_type==OUTPUT_C) { + printf("0x%02X,",last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X",last); + } + else { + printf("%c",last); + } + size++; + } + } + if (run==2) { + if ((last&0xf0)==0xA0) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,0x%02X,",0xa0,2,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X,$%02X",0xa0,2,last); + } + else { + printf("%c%c%c",0xa0,2,last); + } + size+=3; + } + else { + + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,",last,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X",last,last); + } + else { + printf("%c",last); + printf("%c",last); + } + size+=2; + } + } + + if ((run>2) && (run<16)) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,",0xA0|run,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X",0xA0|run,last); + } + else { + printf("%c",0xA0|run); + printf("%c",last); + } + size+=2; + } + + if (run>=16) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X,0x%02X,",0xA0,run,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X,$%02X",0xA0,run,last); + } + else { + printf("%c",0xA0); + printf("%c",run); + printf("%c",last); + } + size+=3; + } + + return size; +} + + +int rle_smaller(int out_type, char *varname, + int xsize,int ysize, unsigned char *image) { + + 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[]={\n",varname); + fprintf(stdout,"\t0x%X, /* ysize=%d */",xsize,ysize); + } + else if (out_type==OUTPUT_ASM) { + fprintf(stdout,"%s:",varname); + fprintf(stdout,"\t.byte $%X ; ysize=%d",xsize,ysize); + } else { + fprintf(stdout,"%c",xsize); + } + + size+=1; + + /* 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 */ + 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 if (out_type==OUTPUT_ASM) { + fprintf(stdout,"\n\t.byte $A1\n"); + } else { + fprintf(stdout,"%c",0xA1); + } + + size+=1; + + return size; +} + + +/* Converts a PNG to RLE compressed data */ + +int rle_original(int out_type, char *varname, + int xsize,int ysize, unsigned char *image) { + + 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[]={\n",varname); + fprintf(stdout,"\t0x%X,0x%X,",xsize,ysize); + } + else if (out_type==OUTPUT_ASM) { + fprintf(stdout,"%s:",varname); + fprintf(stdout,"\t.byte $%X,$%X",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 color change (or too big) then output our run */ + /* Note 0xff for run length is special case meaning "finished" */ + if ((next!=last) || (run>253)) { + + /* handle new line */ + if (out_type==OUTPUT_C) { + if (count==0) { + printf("\n\t"); + } + } + else if (out_type==OUTPUT_ASM) { + if (count==0) { + printf("\n\t.byte "); + } + else { + printf(", "); + } + } + + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X, ",run,last); + } + else if (out_type==OUTPUT_ASM) { + printf("$%02X,$%02X",run,last); + } + else { + printf("%c",run); + printf("%c",last); + + } + size+=2; + + count++; + run=0; + last=next; + } + + x++; + + /* If we reach the end */ + if (x>=xsize*(ysize/2)) { + run++; + /* print tailing value */ + if (run!=0) { + if (out_type==OUTPUT_C) { + printf("0x%02X,0x%02X, ",run,last); + } + else if (out_type==OUTPUT_ASM) { + if (count==0) { + printf("\n\t.byte "); + } + else { + printf(", "); + } + printf("$%02X,$%02X\n",run,last); + } else { + printf("%c",run); + printf("%c",last); + } + size+=2; + } + break; + } + + run++; + if (count>6) count=0; + + } + + /* Print closing marker */ + + if (out_type==OUTPUT_C) { + fprintf(stdout,"0xFF,0xFF,"); + fprintf(stdout,"\t};\n"); + } else if (out_type==OUTPUT_ASM) { + fprintf(stdout,"\t.byte $FF,$FF\n"); + } + + size+=2; + + return size; +} diff --git a/gr-utils/rle_common.h b/gr-utils/rle_common.h new file mode 100644 index 00000000..36a2fc8c --- /dev/null +++ b/gr-utils/rle_common.h @@ -0,0 +1,7 @@ +#define OUTPUT_C 0 +#define OUTPUT_ASM 1 +#define OUTPUT_RAW 2 + +int rle_smaller(int out_type, char *varname, + int xsize,int ysize, unsigned char *image); +