From 461b92653f2a8a67bcfe503f37adfed6f7d2ddf2 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 8 Dec 2020 19:19:23 -0500 Subject: [PATCH] duke: work on map editor --- appleiibot/convert_vmw.c | 4 + duke/Makefile | 2 + duke/draw_tilemap.s | 88 +++++++ duke/duke.s | 9 +- duke/level1_data.inc | 30 +++ duke/maps/Makefile | 27 +++ duke/maps/level1_map.inc | 34 +++ duke/maps/level1_map.png | Bin 0 -> 7825 bytes duke/maps/loadpng.c | 490 +++++++++++++++++++++++++++++++++++++++ duke/maps/loadpng.h | 9 + duke/maps/png2map.c | 64 +++++ 11 files changed, 755 insertions(+), 2 deletions(-) create mode 100644 duke/draw_tilemap.s create mode 100644 duke/level1_data.inc create mode 100644 duke/maps/Makefile create mode 100644 duke/maps/level1_map.inc create mode 100644 duke/maps/level1_map.png create mode 100644 duke/maps/loadpng.c create mode 100644 duke/maps/loadpng.h create mode 100644 duke/maps/png2map.c diff --git a/appleiibot/convert_vmw.c b/appleiibot/convert_vmw.c index 5d988c1f..e39f655e 100644 --- a/appleiibot/convert_vmw.c +++ b/appleiibot/convert_vmw.c @@ -91,5 +91,9 @@ int main(int argc, char **argv) { // note, peek/poke truncate? //2FORI=1013TO1141:C=(PEEK(1843+I/3)-32)/4^(I-INT(I/3)*3):POKEI,C+4*(PEEK(1041+I)-32-INT(C/4)):NEXT:& +// from Tom Greene @txgx42 +//1FORI=0TO141:POKE1013+I,4*PEEK(2126+I)-192+(PEEK(2267+I/3)-35)/4^(I-INT(I/3)*3):NEXT +//2&",clV5QfWo3NQegoQoX&VPYo8,kYf]J+Y_60T9jb`6dkio^o<\2g000000?0003600L100?H0,B6$-<$I1.I<-?0..?-?0:O@):1K0O):1I7033N30H3-0012345.699<>7<<998654321S4J@M$K$DJ;3%#,1E##'##&*3SS+5[5+F'F//#W##E+D+%# + return 0; } diff --git a/duke/Makefile b/duke/Makefile index 21d7556b..3fa60173 100644 --- a/duke/Makefile +++ b/duke/Makefile @@ -26,7 +26,9 @@ DUKE: duke.o duke.o: duke.s zp.inc hardware.inc duke.s \ graphics/duke_graphics.inc \ + level1_data.inc \ status_bar.s draw_duke.s gr_putsprite_crop.s \ + draw_tilemap.s \ keyboard.s handle_laser.s ca65 -o duke.o duke.s -l duke.lst diff --git a/duke/draw_tilemap.s b/duke/draw_tilemap.s new file mode 100644 index 00000000..0f7d1d94 --- /dev/null +++ b/duke/draw_tilemap.s @@ -0,0 +1,88 @@ + + +draw_tilemap: + ldy #0 ; Y on screen currently drawing + sty tiley ; we draw two at a time + + ldx #1 ; offset in current screen + stx tilemap_offset ; tilemap + + lda #0 ; init odd/even + sta tile_odd + +tilemap_outer_loop: + ldy tiley ; setup pointer to current Y + lda gr_offsets,Y + sta GBASL + lda gr_offsets+1,Y + clc + adc DRAW_PAGE + sta GBASH + + ldy #6 ; we draw in window 6->34 +tilemap_loop: + ldx tilemap_offset ; get actual tile + lda tilemap,X + + asl ; *4 ; get offset in tile + asl + tax + + lda tile_odd + beq not_odd_line + inx + inx +not_odd_line: + + lda tiles,X ; draw two tiles + cmp #$AA ; transparency + beq skip_tile1 + sta (GBASL),Y +skip_tile1: + + iny + lda tiles+1,X + cmp #$AA + beq skip_tile2 + sta (GBASL),Y +skip_tile2: + iny + + inc tilemap_offset + + cpy #34 ; until done + bne tilemap_loop + + ; move to next line + lda tile_odd ; toggle odd/even + eor #$1 ; (should we just add/mask?) + sta tile_odd + bne move_to_odd_line + +move_to_even_line: + lda tilemap_offset + clc + adc #2 + jmp done_move_to_line + +move_to_odd_line: + lda tilemap_offset + sec + sbc #14 + +done_move_to_line: + sta tilemap_offset + + ldy tiley ; move to next line + iny + iny + sty tiley + + cpy #40 ; check if at end + bne tilemap_outer_loop + + rts + +tilemap_offset: .byte $00 +tile_odd: .byte $00 +tiley: .byte $00 diff --git a/duke/duke.s b/duke/duke.s index 30e53af4..f5183e73 100644 --- a/duke/duke.s +++ b/duke/duke.s @@ -38,7 +38,7 @@ duke_start: lda #18 sta DUKE_X - lda #20 + lda #18 sta DUKE_Y lda #1 sta DUKE_DIRECTION @@ -67,6 +67,10 @@ duke_loop: jsr gr_copy_to_current + ; draw tilemap + + jsr draw_tilemap + ; draw laser jsr draw_laser @@ -132,5 +136,6 @@ done_with_duke: .include "draw_duke.s" .include "handle_laser.s" + .include "draw_tilemap.s" - + .include "level1_data.inc" diff --git a/duke/level1_data.inc b/duke/level1_data.inc new file mode 100644 index 00000000..968523aa --- /dev/null +++ b/duke/level1_data.inc @@ -0,0 +1,30 @@ +tiles: + tile00: .byte $AA,$AA,$AA,$AA + tile01: .byte $55,$55,$55,$55 + tile02: .byte $ff,$5f,$ff,$55 + tile03: .byte $5f,$5f,$55,$55 + tile04: .byte $5f,$ff,$5f,$ff + tile05: .byte $ff,$55,$ff,$f5 + tile06: .byte $55,$55,$f5,$f5 + tile07: .byte $55,$ff,$f5,$ff + tile08: .byte $55,$f5,$50,$f5 + tile09: .byte $ff,$55,$ff,$55 + tile0a: .byte $55,$ff,$55,$ff + tile0b: .byte $99,$99,$09,$09 + tile0c: .byte $99,$59,$99,$88 + tile0d: .byte $59,$99,$99,$99 + tile0e: .byte $8f,$99,$09,$09 + tile0f: .byte $00,$76,$f7,$05 + +tilemap: + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$08,$01,$01,$01,$01 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$05,$06,$06,$06,$06,$06 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0f,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$0c,$0d,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$00,$00,$00,$0b,$0e,$00,$00,$00,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$02,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03 + diff --git a/duke/maps/Makefile b/duke/maps/Makefile new file mode 100644 index 00000000..f4b5d961 --- /dev/null +++ b/duke/maps/Makefile @@ -0,0 +1,27 @@ +CC = gcc +CFLAGS = -g -Wall -O2 + +all: level1_map.inc png2map + +level1_map.inc: level1_map.png png2map + ./png2map level1_map.png level1_map.inc + +### + +loadpng.o: loadpng.c loadpng.h + $(CC) $(CFLAGS) -c loadpng.c + +rle_common.o: rle_common.c rle_common.h + $(CC) $(CFLAGS) -c rle_common.c +### + +png2map: png2map.o loadpng.o + $(CC) $(LFLAGS) -o png2map png2map.o loadpng.o -lpng + +png2map.o: png2map.c loadpng.h + $(CC) $(CFLAGS) -c png2map.c + +### + +clean: + rm -f *~ *.o *.inc png2map diff --git a/duke/maps/level1_map.inc b/duke/maps/level1_map.inc new file mode 100644 index 00000000..ff8a752d --- /dev/null +++ b/duke/maps/level1_map.inc @@ -0,0 +1,34 @@ +tiles: +tile00: .byte $00,$00,$00,$00 +tile01: .byte $00,$00,$00,$00 +tile02: .byte $00,$00,$00,$00 +tile03: .byte $00,$00,$00,$00 +tile04: .byte $00,$00,$00,$00 +tile05: .byte $00,$00,$00,$00 +tile06: .byte $00,$00,$00,$00 +tile07: .byte $00,$00,$00,$00 +tile08: .byte $00,$00,$00,$00 +tile09: .byte $00,$00,$00,$00 +tile0a: .byte $00,$00,$00,$00 +tile0b: .byte $00,$00,$00,$00 +tile0c: .byte $00,$00,$00,$00 +tile0d: .byte $00,$00,$00,$00 +tile0e: .byte $00,$00,$00,$00 +tile0f: .byte $00,$00,$00,$00 +tile10: .byte $00,$00,$00,$00 +tile11: .byte $00,$00,$00,$00 +tile12: .byte $00,$00,$00,$00 +tile13: .byte $00,$00,$00,$00 +tile14: .byte $00,$00,$00,$00 +tile15: .byte $00,$00,$00,$00 +tile16: .byte $00,$00,$00,$00 +tile17: .byte $00,$00,$00,$00 +tile18: .byte $00,$00,$00,$00 +tile19: .byte $00,$00,$00,$00 +tile1a: .byte $00,$00,$00,$00 +tile1b: .byte $00,$00,$00,$00 +tile1c: .byte $00,$00,$00,$00 +tile1d: .byte $00,$00,$00,$00 +tile1e: .byte $00,$00,$00,$00 +tile1f: .byte $00,$00,$00,$00 + diff --git a/duke/maps/level1_map.png b/duke/maps/level1_map.png new file mode 100644 index 0000000000000000000000000000000000000000..508d2b7ba7f7d80ca7b9d307602ffd8740b92a94 GIT binary patch literal 7825 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 literal 0 HcmV?d00001 diff --git a/duke/maps/loadpng.c b/duke/maps/loadpng.c new file mode 100644 index 00000000..fc1418a1 --- /dev/null +++ b/duke/maps/loadpng.c @@ -0,0 +1,490 @@ +/* Loads a 80x48 (or 40x48) PNG image into a 40x48 Apple II layout */ +/* It's not interleaved like an actual Apple II */ +/* But the top/bottom are pre-packed into a naive 40x24 array */ + + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "loadpng.h" + +static int convert_color(int color, char *filename) { + + int c=0; + + switch(color) { + case 0x000000: c=0; break; /* black */ + case 0xe31e60: c=1; break; /* magenta */ + case 0x604ebd: c=2; break; /* dark blue */ + case 0xff44fd: c=3; break; /* purple */ + case 0x00a360: c=4; break; /* dark green */ + case 0x9c9c9c: c=5; break; /* grey 1 */ + case 0x14cffd: c=6; break; /* medium blue */ + case 0xd0c3ff: c=7; break; /* light blue */ + case 0x607203: c=8; break; /* brown */ + case 0xff6a3c: c=9; break; /* orange */ + case 0x9d9d9d: c=10; break; /* grey 2 */ + case 0xffa0d0: c=11; break; /* pink */ + case 0x14f53c: c=12; break; /* bright green */ + case 0xd0dd8d: c=13; break; /* yellow */ + case 0x72ffd0: c=14; break; /* aqua */ + case 0xffffff: c=15; break; /* white */ + default: + fprintf(stderr,"Unknown color %x, file %s\n", + color,filename); + exit(-1); + break; + } + + return c; +} + +/* expects a PNG where the xsize is either 1280x200 */ + +int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize, + int png_type) { + + int x,y,ystart,yadd,xadd; + 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; + + 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); + + if (width==1280) { + *xsize=1280; + xadd=1; + } + else { + fprintf(stderr,"Unsupported width %d\n",width); + return -1; + } + + if (png_type==PNG_WHOLETHING) { + *ysize=height; + ystart=0; + yadd=2; + } + else if (png_type==PNG_ODDLINES) { + *ysize=height/2; + ystart=1; + yadd=4; + } + else if (png_type==PNG_EVENLINES) { + *ysize=height/2; + ystart=0; + yadd=4; + } + else { + fprintf(stderr,"Unknown PNG type\n"); + return -1; + } + + 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"); + printf("Generating output size %d x %d\n",*xsize,*ysize); + } + +// 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; y>4); + } + a2_color&=0xf; + + /* bottom color */ + color=row_pointers[y+(yadd/2)][x/2]; + if (x%2==0) { + color=(color>>4); + } + color&=0xf; + + a2_color|=(color<<4); + + if (debug) { + printf("%x ",a2_color); + } + + *out_ptr=a2_color; + out_ptr++; + + } + } + if (debug) printf("\n"); + } + } + else { + printf("Unknown color type\n"); + } + + /* Stripe test image */ +// for(x=0;x<40;x++) for(y=0;y<40;y++) image[(y*width)+x]=y%16; + +/* + Addr Row /80 %40 + $400 0 0 0 0 + $428 28 16 0 + $450 50 32 0 + $480 80 2 1 + $4A8 a8 18 1 + $4D0 d0 34 1 + $500 100 3 2 + 0,0 0,1 0,2....0,39 16,0 16,1 ....16,39 32,0..32,39, X X X X X X X X +*/ + + *image_ptr=image; + + return 0; +} + + + +/* for 80 column mode or double-lores */ +int loadpng80(char *filename, unsigned char **image_ptr, int *xsize, int *ysize, + int png_type) { + + int x,y,ystart,yadd,xadd; + 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; + + 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); + + if (width==80) { + *xsize=80; + xadd=1; + } + else { + fprintf(stderr,"Unsupported width %d\n",width); + return -1; + } + + if (png_type==PNG_WHOLETHING) { + *ysize=height; + ystart=0; + yadd=2; + } + else if (png_type==PNG_ODDLINES) { + *ysize=height/2; + ystart=1; + yadd=4; + } + else if (png_type==PNG_EVENLINES) { + *ysize=height/2; + ystart=0; + yadd=4; + } + else { + fprintf(stderr,"Unknown PNG type\n"); + return -1; + } + + 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"); + printf("Generating output size %d x %d\n",*xsize,*ysize); + } + +// 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; y>4); + } + a2_color&=0xf; + + /* bottom color */ + color=row_pointers[y+(yadd/2)][x/2]; + if (x%2==0) { + color=(color>>4); + } + color&=0xf; + + a2_color|=(color<<4); + + if (debug) { + printf("%x ",a2_color); + } + + *out_ptr=a2_color; + out_ptr++; + + } + } + if (debug) printf("\n"); + } + } + else { + printf("Unknown color type\n"); + } + + /* Stripe test image */ +// for(x=0;x<40;x++) for(y=0;y<40;y++) image[(y*width)+x]=y%16; + +/* + Addr Row /80 %40 + $400 0 0 0 0 + $428 28 16 0 + $450 50 32 0 + $480 80 2 1 + $4A8 a8 18 1 + $4D0 d0 34 1 + $500 100 3 2 + 0,0 0,1 0,2....0,39 16,0 16,1 ....16,39 32,0..32,39, X X X X X X X X +*/ + + *image_ptr=image; + + return 0; +} + + diff --git a/duke/maps/loadpng.h b/duke/maps/loadpng.h new file mode 100644 index 00000000..51882f61 --- /dev/null +++ b/duke/maps/loadpng.h @@ -0,0 +1,9 @@ +#define PNG_WHOLETHING 0 +#define PNG_ODDLINES 1 +#define PNG_EVENLINES 2 + +int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize, + int png_type); +int loadpng80(char *filename, unsigned char **image_ptr, int *xsize, int *ysize, + int png_type); + diff --git a/duke/maps/png2map.c b/duke/maps/png2map.c new file mode 100644 index 00000000..2707cc13 --- /dev/null +++ b/duke/maps/png2map.c @@ -0,0 +1,64 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "loadpng.h" + + +/* converts a png of map to format by our duke engine */ + +/* 1280x200 image */ +/* 256 sprites of size 2x4 in a 16x16 grid at 8,4 */ + + +static unsigned char tiles[256][2][4]; + +int main(int argc, char **argv) { + + int i,j; + int numtiles=32; + + unsigned char *image; + int xsize,ysize; + FILE *outfile; + + if (argc<3) { + fprintf(stderr,"Usage:\t%s INFILE OUTFILE\n\n",argv[0]); + exit(-1); + } + + outfile=fopen(argv[2],"w"); + if (outfile==NULL) { + fprintf(stderr,"Error! Could not open %s\n",argv[2]); + exit(-1); + } + + if (loadpng(argv[1],&image,&xsize,&ysize,PNG_WHOLETHING)<0) { + fprintf(stderr,"Error loading png!\n"); + exit(-1); + } + + fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize); + + + fprintf(outfile,"tiles:\n"); + for(i=0;i