/* Creates an AppleSoft BASIC shape table */ /* See the AppleSoft manual for info on how this works */ /* Some online info (I'm looking at you, atariarchives.org) */ /* is inaccurate */ /* Format of table is: */ /* 1 byte -- num shapes */ /* 1 byte -- don't care */ /* offsets (repeats): 2 bytes (low/high) offset from start to each shape */ /* Data (repeats), 0 at end of each */ /* data packed in as XX YYY ZZZ */ /* ZZZ = first dir, YYY = next, XX = last, can only be no-draw as 2 bits */ /* note XX can't be NUP (00) */ /* */ /* NUP=0 UP=4 */ /* NRT=1 RT=5 */ /* NDN=2 DN=6 */ /* NLT=3 LT=7 */ #include #include #include #define MAX_SIZE 8192 /* not really, but anything larger would be crazy */ static int debug=0,line=1; static unsigned char table[MAX_SIZE]; static void set_offset(int current_shape,int current_offset) { table[2+(current_shape*2)]=current_offset&0xff; table[2+(current_shape*2)+1]=(current_offset>>8)&0xff; } #define LOC_A 0 #define LOC_B 1 #define LOC_C 2 static void warn_if_zero(unsigned char byte, int line) { /* Check to see if we're accidentally ignoring bytes */ if (byte==0) { fprintf(stderr, "Warning, all-0 byte will be ignored on line %d!\n", line); } if ((byte&0xf8)==0) { fprintf(stderr, "Warning, ignoring C and B due to 0 on line %d!\n", line); } } static void print_usage(char *exe) { printf("Usage:\t%s [-h] [-a] [-b] [-x]\n\n",exe); printf("\t-h\tprint this help message\n"); printf("\t-a\toutput shape table in applesoft BASIC format\n"); printf("\t-b\toutput shape table in binary format for appleiibot\n"); printf("\t-x\toutput shape table in hex format for assembly language\n"); printf("\n"); exit(1); } static int get_token(char *token, FILE *fff) { int ch; int ptr=0; /* skip leading spaces/comments */ while(1) { ch=fgetc(fff); if (ch<0) return -1; /* Skip comment to end of line */ if (ch=='#') { while(ch!='\n') ch=fgetc(fff); } if ((ch==' ') || (ch=='\t') || (ch=='\n')) { if (ch=='\n') line++; continue; } break; } while(1) { token[ptr]=ch; ptr++; ch=fgetc(fff); if (ch<0) return -1; if ((ch==' ') || (ch=='\t') || (ch=='\n')) { if (ch=='\n') line++; break; } } token[ptr]=0; return 0; } #define OUTPUT_BASIC 0 #define OUTPUT_BINARY 1 #define OUTPUT_HEX 2 int main(int argc, char **argv) { char string[BUFSIZ]; int result; int table_size=0; int num_shapes=0; int current_offset=0,current_shape=0; int i; int command=0,sub_pointer; int output_type=OUTPUT_BASIC; if (argc<2) { output_type=OUTPUT_BASIC; } else { if (argv[1][0]=='-') { switch(argv[1][1]) { case 'h': print_usage(argv[0]); break; case 'b': output_type=OUTPUT_BINARY; break; case 'a': output_type=OUTPUT_BASIC; break; case 'x': output_type=OUTPUT_HEX; break; case 'd': debug=1; break; default: printf("Unknown options %s\n",argv[1]); print_usage(argv[0]); } } } result=get_token(string,stdin); if (result<0) { fprintf(stderr,"Error getting number\n"); return -1; } num_shapes=atoi(string); if (num_shapes<1) { fprintf(stderr,"Error getting numshapes\n"); return -2; } if (debug) fprintf(stderr,"Number of shapes = %d\n",num_shapes); table[0]=num_shapes; table[1]=0; current_shape=0; current_offset=2+2*(num_shapes); for(current_shape=0;current_shape>8)&0xff; header[2]=table_size&0xff; header[3]=(table_size>>8)&0xff; fprintf(stderr,"Be sure to POKE 232,%d : POKE 233,%d\n" "\tto let applesoft know the location of the table\n", offset&0xff,(offset>>8)&0xff); fwrite(header,sizeof(unsigned char),4,stdout); fwrite(table,sizeof(unsigned char),table_size,stdout); } else if (output_type==OUTPUT_BASIC) { /* put near highmem */ int address=0x1ff0-table_size; printf("10 HIMEM:%d\n",address); printf("20 POKE 232,%d:POKE 233,%d\n",(address&0xff),(address>>8)&0xff); printf("30 FOR L=%d TO %d: READ B:POKE L,B:NEXT L\n", address,(address+table_size)-1); printf("35 HGR:ROT=0:SCALE=2\n"); printf("40 FOR I=1 TO %d: XDRAW I AT I*10,100:NEXT I\n", num_shapes); printf("90 END\n"); for(i=0;i