duke: actually use big tilemap

This commit is contained in:
Vince Weaver 2020-12-08 23:41:53 -05:00
parent 21669bbec9
commit d5d84a58d5
8 changed files with 247 additions and 314 deletions

View File

@ -26,7 +26,7 @@ DUKE: duke.o
duke.o: duke.s zp.inc hardware.inc duke.s \
graphics/duke_graphics.inc \
level1_data.inc \
maps/level1_map.lzsa \
status_bar.s draw_duke.s gr_putsprite_crop.s \
draw_tilemap.s \
keyboard.s handle_laser.s
@ -37,10 +37,14 @@ duke.o: duke.s zp.inc hardware.inc duke.s \
graphics/duke_graphics.inc:
cd graphics && make
maps/level1_map.lzsa:
cd maps && make
####
clean:
rm -f *~ *.o *.lst HELLO DUKE
cd graphics && make clean
cd maps && make clean

10
duke/NOTES Normal file
View File

@ -0,0 +1,10 @@
Memory Map:
$2000 -- code
$9000 -- tiles
$9400 -- global tilemap
$BC00 -- local tilemap subset
$BD00 -- unused
$C000 -- ROM

View File

@ -1,4 +1,6 @@
;================================
; draw local tilemap to screen
;================================
draw_tilemap:
ldy #0 ; Y on screen currently drawing
@ -22,7 +24,7 @@ tilemap_outer_loop:
ldy #6 ; we draw in window 6->34
tilemap_loop:
ldx tilemap_offset ; get actual tile
lda tilemap,X
lda TILEMAP,X
asl ; *4 ; get offset in tile
asl
@ -34,14 +36,14 @@ tilemap_loop:
inx
not_odd_line:
lda tiles,X ; draw two tiles
lda TILES,X ; draw two tiles
cmp #$AA ; transparency
beq skip_tile1
sta (GBASL),Y
skip_tile1:
iny
lda tiles+1,X
lda TILES+1,X
cmp #$AA
beq skip_tile2
sta (GBASL),Y
@ -83,6 +85,59 @@ done_move_to_line:
rts
; these should probably be in the zero page
tilemap_offset: .byte $00
tile_odd: .byte $00
tiley: .byte $00
;===================================
; copy tilemap
;===================================
; want to copy a 16x10 area from global tileset to local
; default at first we want to start at 128,88
; which is 13, 20???
copy_tilemap_subset:
; set start
lda #20
clc
adc #>BIG_TILEMAP
sta cptl1_smc+2 ; set proper row in big tilemap
adc #$10
sta cptl3_smc+1 ; set loop limit
; reset row
lda #<TILEMAP
sta cptl2_smc+1 ; set small tilemap to row0
cp_tilemap_outer_loop:
ldx #13
ldy #0
cp_tilemap_inner_loop:
cptl1_smc:
lda $9400,X
cptl2_smc:
sta $BC00,Y
iny
inx
cpy #16
bne cp_tilemap_inner_loop
; next line
inc cptl1_smc+2 ; incremement page
clc
lda cptl2_smc+1 ; increment row
adc #$10
sta cptl2_smc+1
lda cptl1_smc+2
cptl3_smc:
cmp #$a
bne cp_tilemap_outer_loop
rts

View File

@ -6,6 +6,11 @@
.include "zp.inc"
.include "hardware.inc"
TILES = $9000
BIG_TILEMAP = $9400
TILEMAP = $BC00
duke_start:
;===================
; init screen
@ -45,7 +50,7 @@ duke_start:
;====================================
; load duke bg
; load level1 background
;====================================
lda #<duke1_bg_lzsa
@ -55,6 +60,23 @@ duke_start:
lda #$c ; load to page $c00
jsr decompress_lzsa2_fast
;====================================
; load level1 tilemap
;====================================
lda #<level1_data_lzsa
sta LZSA_SRC_LO
lda #>level1_data_lzsa
sta LZSA_SRC_HI
lda #$90 ; load to page $9000
jsr decompress_lzsa2_fast
;====================================
; copy in tilemap subset
;====================================
jsr copy_tilemap_subset
;====================================
;====================================
; Main LOGO loop
@ -138,4 +160,5 @@ done_with_duke:
.include "handle_laser.s"
.include "draw_tilemap.s"
.include "level1_data.inc"
level1_data_lzsa:
.incbin "maps/level1_map.lzsa"

View File

@ -1,7 +1,9 @@
CC = gcc
CFLAGS = -g -Wall -O2
all: level1_map.inc png2map
LZSA = ~/research/lzsa/lzsa/lzsa
all: level1_map.lzsa png2map
level1_map.inc: level1_map.png png2map
./png2map level1_map.png level1_map.inc
@ -23,5 +25,8 @@ png2map.o: png2map.c loadpng.h
###
%.lzsa: %.inc
$(LZSA) -r -f2 $< $@
clean:
rm -f *~ *.o *.inc png2map

View File

@ -1,34 +0,0 @@
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

View File

@ -114,20 +114,10 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
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;
yadd=1;
}
else {
fprintf(stderr,"Unknown PNG type\n");
fprintf(stderr,"Unknown type\n");
return -1;
}
@ -155,7 +145,6 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
fclose(infile);
/* FIXME: this should be 40x24 max??? */
image=calloc(width*height,sizeof(unsigned char));
if (image==NULL) {
fprintf(stderr,"Memory error!\n");
@ -177,16 +166,6 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
a2_color=convert_color(color,filename);
/* bottom color */
color= (row_pointers[y+1][x*xadd*4]<<16)+
(row_pointers[y+1][x*xadd*4+1]<<8)+
(row_pointers[y+1][x*xadd*4+2]);
if (debug) {
printf("%x ",color);
}
a2_color|=(convert_color(color,filename)<<4);
*out_ptr=a2_color;
out_ptr++;
}
@ -202,9 +181,9 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
a2_color=row_pointers[y][x];
/* bottom color */
color=row_pointers[y+(yadd/2)][x];
// color=row_pointers[y+(yadd/2)][x];
a2_color|=(color<<4);
// a2_color|=(color<<4);
if (debug) {
printf("%x ",a2_color);
@ -221,14 +200,14 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
}
a2_color&=0xf;
/* bottom color */
color=row_pointers[y+(yadd/2)][x/2];
if (x%2==0) {
color=(color>>4);
}
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);
// a2_color|=(color<<4);
if (debug) {
printf("%x ",a2_color);
@ -246,21 +225,6 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
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;
@ -268,223 +232,5 @@ int loadpng(char *filename, unsigned char **image_ptr, int *xsize, int *ysize,
/* 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<height; y++) {
/* FIXME: do we ever free these? */
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
}
png_read_image(png_ptr, row_pointers);
fclose(infile);
/* FIXME: this should be 40x24 max??? */
image=calloc(width*height,sizeof(unsigned char));
if (image==NULL) {
fprintf(stderr,"Memory error!\n");
return -1;
}
out_ptr=image;
if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
for(y=ystart;y<height;y+=yadd) {
for(x=0;x<width;x+=xadd) {
/* top color */
color= (row_pointers[y][x*xadd*4]<<16)+
(row_pointers[y][x*xadd*4+1]<<8)+
(row_pointers[y][x*xadd*4+2]);
if (debug) {
printf("%x ",color);
}
a2_color=convert_color(color,filename);
/* bottom color */
color= (row_pointers[y+1][x*xadd*4]<<16)+
(row_pointers[y+1][x*xadd*4+1]<<8)+
(row_pointers[y+1][x*xadd*4+2]);
if (debug) {
printf("%x ",color);
}
a2_color|=(convert_color(color,filename)<<4);
*out_ptr=a2_color;
out_ptr++;
}
if (debug) printf("\n");
}
}
else if (color_type==PNG_COLOR_TYPE_PALETTE) {
for(y=ystart;y<height;y+=yadd) {
for(x=0;x<width;x+=xadd) {
if (bit_depth==8) {
/* top color */
a2_color=row_pointers[y][x];
/* bottom color */
color=row_pointers[y+(yadd/2)][x];
a2_color|=(color<<4);
if (debug) {
printf("%x ",a2_color);
}
*out_ptr=a2_color;
out_ptr++;
}
else if (bit_depth==4) {
/* top color */
a2_color=row_pointers[y][x/2];
if (x%2==0) {
a2_color=(a2_color>>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;
}

View File

@ -17,11 +17,15 @@
static unsigned char tiles[256][2][4];
static unsigned char tilemap[256][40];
static unsigned char temp_tile[2][4];
static int ascii_output=0;
int main(int argc, char **argv) {
int i,j;
int numtiles=32;
int i,j,x,y;
int numtiles=0,found_tile;
unsigned char *image;
int xsize,ysize;
@ -45,19 +49,139 @@ int main(int argc, char **argv) {
fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize);
// for(x=0;x<128;x++) {
// for(y=0;y<64;y++) {
// printf("%02X,",image[(y*xsize)+x]);
// }
// printf("\n");
// }
/* loading tiles */
for(x=0;x<16;x++) {
for(y=0;y<16;y++) {
tiles[(y*16)+x][0][0]=image[((y*4+4)*xsize)+8+(x*4)];
tiles[(y*16)+x][1][0]=image[((y*4+4)*xsize)+8+(x*4)+2];
tiles[(y*16)+x][0][1]=image[((y*4+5)*xsize)+8+(x*4)];
tiles[(y*16)+x][1][1]=image[((y*4+5)*xsize)+8+(x*4)+2];
tiles[(y*16)+x][0][2]=image[((y*4+6)*xsize)+8+(x*4)];
tiles[(y*16)+x][1][2]=image[((y*4+6)*xsize)+8+(x*4)+2];
tiles[(y*16)+x][0][3]=image[((y*4+7)*xsize)+8+(x*4)];
tiles[(y*16)+x][1][3]=image[((y*4+7)*xsize)+8+(x*4)+2];
}
}
i=0;
for(j=0;j<256;j++) {
if ((tiles[j][0][0]!=0) ||
(tiles[j][1][0]!=0) ||
(tiles[j][0][1]!=0) ||
(tiles[j][1][1]!=0) ||
(tiles[j][0][2]!=0) ||
(tiles[j][1][2]!=0) ||
(tiles[j][0][3]!=0) ||
(tiles[j][1][3]!=0)) {
numtiles=j+1;
}
}
printf("Found %d tiles\n",numtiles);
if (ascii_output) {
fprintf(outfile,"tiles:\n");
for(i=0;i<numtiles;i++) {
fprintf(outfile,"tile%02x:\t.byte ",i);
for(j=0;j<4;j++) {
fprintf(outfile,"$%02x",tiles[i][0][0]);
if (j!=3) fprintf(outfile,",");
}
fprintf(outfile,"$%02x,",tiles[i][0][0]+(tiles[i][0][1]<<4));
fprintf(outfile,"$%02x,",tiles[i][1][0]+(tiles[i][1][1]<<4));
fprintf(outfile,"$%02x,",tiles[i][0][2]+(tiles[i][0][3]<<4));
fprintf(outfile,"$%02x" ,tiles[i][1][2]+(tiles[i][1][3]<<4));
fprintf(outfile,"\n");
}
}
else {
for(i=0;i<256;i++) {
fputc(tiles[i][0][0]+(tiles[i][0][1]<<4),outfile);
fputc(tiles[i][1][0]+(tiles[i][1][1]<<4),outfile);
fputc(tiles[i][0][2]+(tiles[i][0][3]<<4),outfile);
fputc(tiles[i][1][2]+(tiles[i][1][3]<<4),outfile);
}
}
fprintf(outfile,"\n");
if (ascii_output) fprintf(outfile,"\n");
/* loading tilemap */
/* starts at 80,12 */
for(x=0;x<256;x++) {
for(y=0;y<40;y++) {
/* get temp tile */
temp_tile[0][0]=image[((y*4+12)*xsize)+80+(x*4)];
temp_tile[1][0]=image[((y*4+12)*xsize)+80+(x*4)+2];
temp_tile[0][1]=image[((y*4+13)*xsize)+80+(x*4)];
temp_tile[1][1]=image[((y*4+13)*xsize)+80+(x*4)+2];
temp_tile[0][2]=image[((y*4+14)*xsize)+80+(x*4)];
temp_tile[1][2]=image[((y*4+14)*xsize)+80+(x*4)+2];
temp_tile[0][3]=image[((y*4+15)*xsize)+80+(x*4)];
temp_tile[1][3]=image[((y*4+15)*xsize)+80+(x*4)+2];
/* find tile */
found_tile=-1;
/* if all black, assume transparent */
if ((temp_tile[0][0]==0) &&
(temp_tile[1][0]==0) &&
(temp_tile[0][1]==0) &&
(temp_tile[1][1]==0) &&
(temp_tile[0][2]==0) &&
(temp_tile[1][2]==0) &&
(temp_tile[0][3]==0) &&
(temp_tile[1][3]==0)) {
found_tile=0;
}
else for(i=0;i<numtiles;i++) {
if ((temp_tile[0][0]==tiles[i][0][0]) &&
(temp_tile[1][0]==tiles[i][1][0]) &&
(temp_tile[0][1]==tiles[i][0][1]) &&
(temp_tile[1][1]==tiles[i][1][1]) &&
(temp_tile[0][2]==tiles[i][0][2]) &&
(temp_tile[1][2]==tiles[i][1][2]) &&
(temp_tile[0][3]==tiles[i][0][3]) &&
(temp_tile[1][3]==tiles[i][1][3])) {
found_tile=i;
break;
}
}
tilemap[x][y]=found_tile;
if (found_tile==-1) {
printf("Error! Unknown tile at %d,%d\n",
80+(x*4),12+(y*4));
}
}
}
if (ascii_output) {
fprintf(outfile,"tilemap:\n");
for(j=0;j<40;j++) {
fprintf(outfile,"\t.byte ");
for(i=0;i<256;i++) {
fprintf(outfile,"$%02x",tilemap[i][j]);
if (i!=255) fprintf(outfile,",");
}
fprintf(outfile,"\n");
}
fprintf(outfile,"\n");
}
else {
for(j=0;j<40;j++) {
for(i=0;i<256;i++) {
fputc(tilemap[i][j],outfile);
}
}
}
fclose(outfile);
return 0;