/* NewROMs (C)2002 B Y T E THE BIG O N E * * This program examines the files listinfo_new.txt and listinfo_old.txt * (the output from a -listinfo from two versions of mame), compares the * two files, and generates a download list of roms that changed with the * new version of Mame. * * * Written Feb 9, 2002 - Feb 18, 2002 * By Darryl P. Hirschler * dphirschler@hotmail.com * * ChangedROMs Ver 1.00 - Initial release (beta) * - list changed roms * - list removed roms * - check for presence of changed rom file * * Ver 1.10 - bug fix * - fixed backwards colors on action items. * * Ver 1.50 - enhancements - trying to make it "front-end friendly" * - removed the -S arg. * - more filename options including: rfile_new, rfile_old, html_file (from command line). * - somehow add a meaningful title to the html file. * - should count roms not present better. * * Ver 2.00 - add more enhancements. heading towards whole enchilada * - add 1-byte flag to struct (new, removed, changed, present) * - keep database of both old (shortened to only changed roms) and new (shortened to only new roms) listinfo files. * - as a side effect of the new enchancements, the code got a little cleaner, the logic was spelled out better, and the discovery that previous versions' output was incomplete(!) * * NewROMs Ver 3.00 - the whole enchilada * - encompass NewROMs' duties and assume new name. Move to ver 3.00 to avoid confusion with existing NewROMs ver 2.00. * * Ver 3.10 - major bug fix * - bug fix. Was including good roms as "removed". I solved a major accounting problem and also removed the "removed roms" code. * * Ver 3.20 - minor enhancements * - need to add quick jumps to new and changed roms * - it was counting needed new roms wrong * - cosmetic changes, cleaned up text output. * * Future enhancements to consider * o should really have two directories to look into for existing roms * o I may put "removed roms" code back in as is seems removed roms are still getting counted. * o routine that searches for matching rominfo strings indicating a "renamed" rom. Is this even useful or desired? * o consider creating bat file for deleting and renaming. * o add the rom filesize information back to the structure to eventually show the romfile size in the html document. * * Program limitations: * NewROMs supports up to 20,000 games (defined as MAXGAMES). * Each game can have up to 100 rom files (defined in the struct temprom). * If temprom is ever increased or changed in any way, check the rominfo string length defined in the game struct * */ #define PROGNAME NewROMs #define PROGVER 3.20 #define MAXGAMES 20000 /* max number of games (increase this number if MAME ever supports more). */ #define BYTE unsigned char #define WORD unsigned int /*flags */ // #define RESOURCE 0x01 #define GAME 0x02 #define SHORT 0x04 #define PATH 0x10 /* rompath present in command line */ // flag |= GAME; /* turn flag on */ // flag &= ~GAME; /* turn flag off */ #define RESOURCE 0x01 #define NEW 0x02 #define CHANGED 0x04 #define PRESENT 0x10 #define RENAMED 0x20 #define REMOVED 0x40 #include #include #include #include #include #include #include void helpme(void); /* help screen */ void wr(int, BYTE[]); /* writes data to a file */ void dit(BYTE *, BYTE *, BYTE *, BYTE *); /* do it - this is the meat of the program */ void filereaderror(BYTE[]); int getachar(BYTE *, int); /* gets a char from a 4k buffer or from disk */ int getline(BYTE *, int); void perr(BYTE[]); /* print error message */ int match(BYTE[], BYTE[]); // string matching long int filesize(BYTE[]); // returns the filesize int pathexists(BYTE[]); // returns 1 if path exists int join(BYTE *, BYTE *, BYTE *, BYTE *, BYTE *); // joins 4 strings, returns length BYTE *readkey(BYTE *, BYTE, BYTE); /* reads what is between keyopen and keyclos */ int keyfits(BYTE *, BYTE *, BYTE *); /* checks line against key */ int subkeyfits(BYTE *, BYTE *, BYTE *); /* looks for subkey in line*/ // these functions not used // int str_count_to(BYTE *, BYTE); /* counts characters in line until character c occurs */ // int strfind(BYTE *, BYTE *); // finds a string within a line int ii=4096; // 4k buffer index int fh_read_new; // file handle for read file int fh_read_old; // file handle for read file BYTE flag=0x00; // flag byte BYTE keyopen='['; BYTE keyclos=']'; BYTE rompath[256] = ""; struct { BYTE dir[9]; BYTE name[50]; BYTE rominfo[3400]; // this number will need to be increased if anything in temprom ever increases. // long int romsize; BYTE flag; } game[MAXGAMES]; void main(BYTE argc, BYTE *argv[]) { int a; //counter BYTE rfile_new[256]="listinfo_new.txt"; // readfile - the default datafile (new mame -listinfo) BYTE rfile_old[256]="listinfo_old.txt"; // readfile - the default datafile (old mame -listinfo) BYTE html_file[256]="newroms.htm"; // the default output file newroms.htm printf("NewROMs start ('-?' for help)...\n"); printf("args: "); for(a=1; a"); wr(fh_write, ""); wr(fh_write, "NewROMs"); wr(fh_write, ""); wr(fh_write, ""); wr(fh_write, ""); wr(fh_write, "
MAME new and changed roms download list
"); // attempt to give some sort of meaningful identity to this html file join(line, "
File1: ", rfile_old, "   File2: ", rfile_new); join(line, line, "

", "", ""); wr(fh_write, line); // ChangedROMs section wr(fh_write, ""); wr(fh_write, "
Changed roms
"); wr(fh_write, "
"); wr(fh_write, ""); b=0; // counts total records printed. c=(counter_ogames+counter_ngames); for(a=0; a"); // make it black strcat(line, ltoa(b+1, integer, 10)); // the number (no color) strcat(line, ""); } else { strcpy(line, ""); // make it red (action item) strcat(line, ltoa(b+1, integer, 10)); // the number strcat(line, ""); // if(strcmp(game[a].rominfo,"") == 0) c++; } if(filesize(temp1)) // does the file exist? game[a].flag |= PRESENT; // on strcat(line, " "); strcat(line, game[a].name); if(game[a].flag&CHANGED) strcat(line, "!"); // testing to see if the flag works strcat(line, "
"); b++; wr(fh_write, line); if(b == (counter_changed >> 1)) // split into two columns { wr(fh_write, ""); wr(fh_write, "
"); wr(fh_write, ""); } } if(game[a].flag&RESOURCE) counter_resource++; if(game[a].flag&RENAMED) counter_renamed++; if(game[a].flag&PRESENT) counter_present++; } wr(fh_write, ""); wr(fh_write, "
\n"); // Changed and removed roms totals strset(line,0); wr(fh_write, "Totals"); wr(fh_write, ""); wr(fh_write, ""); strcpy(line, ""); wr(fh_write, line); strset(line,0); strcpy(line, ""); wr(fh_write, line); wr(fh_write, ""); strset(line,0); wr(fh_write, ""); strcpy(line, ""); wr(fh_write, line); wr(fh_write, ""); wr(fh_write, ""); wr(fh_write, "
Changed roms/resources: "); strcat(line, ltoa(counter_changed, integer, 10)); strcat(line, "Needed: "); if((counter_changed - counter_present) > 0) strcat(line, ""); else strcat(line,""); // strcat(line, ltoa(c, integer, 10)); strcat(line, ltoa(counter_changed - counter_present, integer, 10)); strcat(line, "
Removed roms/resources: "); strcat(line, ltoa(counter_removed, integer, 10)); strcat(line, " 

"); counter_present=0; // NewROMs section wr(fh_write, ""); wr(fh_write, "
New roms
"); // wr(fh_write, "

New roms
"); wr(fh_write, "
"); wr(fh_write, ""); b=0; for(a=0; a"); // make it black strcat(line, ltoa(b+1, integer, 10)); // the number (no color) strcat(line, ""); game[a].flag |= PRESENT; // on counter_present++; } else { strcpy(line, ""); // make it red (action item) strcat(line, ltoa(b+1, integer, 10)); // the number strcat(line, ""); // if(strcmp(game[a].rominfo,"") == 0) c++; } strcat(line, " "); strcat(line, game[a].name); if(game[a].flag&NEW) strcat(line, "!"); // testing to see if the flag works strcat(line, "
"); b++; wr(fh_write, line); if(b == (counter_ngames >> 1)) // split into two columns { wr(fh_write, ""); wr(fh_write, "
"); wr(fh_write, ""); } } // if(game[a].flag&NEW) counter_newgames++; } wr(fh_write, ""); wr(fh_write, "
\n"); // New roms totals strset(line,0); wr(fh_write, "Totals"); wr(fh_write, ""); wr(fh_write, ""); strcpy(line, ""); wr(fh_write, line); strset(line,0); strcpy(line, ""); wr(fh_write, line); wr(fh_write, ""); wr(fh_write, "
New roms/resources: "); strcat(line, ltoa(counter_newgames, integer, 10)); strcat(line, "Needed: "); if((counter_newgames - counter_present) > 0) // this number is wrong strcat(line, ""); else strcat(line,""); // strcat(line, ltoa(c, integer, 10)); strcat(line, ltoa(counter_newgames - counter_present, integer, 10)); // this number is wrong strcat(line, "
"); wr(fh_write, "
"); wr(fh_write, "
"); wr(fh_write, ""); wr(fh_write, ""); _close(fh_write); printf("\n"); } int subkeyfits(BYTE *line, BYTE *key, BYTE *subkey) { int llen; // length of line int a; int b=0; int c=0; llen=strlen(line); for(a=0; allen) return(0); } subkey[c]=0; } if(line[a] == key[b]) { b++; // a match } else { b=0; c=0; } } return(strlen(subkey)); } int keyfits(BYTE *line, BYTE *key, BYTE *string) /* checks line against key */ { int llen; // length of line int klen; // length of key int slen; // length of subkey int a; int b=0; int c=0; int d=0; BYTE subkey[1024]=""; llen=strlen(line); klen=strlen(key); strset(string,0); for(a=0; allen) return(0); } string[c]=0; } if(line[a] == key[b]) b++; // still a match else return(0); } if(strlen(subkey)) { subkeyfits(line, subkey, string); } return(strlen(string)); } BYTE *readkey(BYTE *cline, BYTE keyop, BYTE keycl) /* reads what is between keyopen and keyclos */ { BYTE key[1024]=""; int clen; int a; int b=0; int kread=0; //cline="[ name %s]"; // for testing clen=strlen(cline); for(a=0; a0) { strcpy(line,temp); free(temp); } else bdata=0; } else { temp[count++] = bdata; temp[count]=0; if(g==0) return(0); if(count == 4096) perr("getline failed: line too long"); } } return(count); } int getachar(BYTE *p, int fh) /* Loads data in 4k blocks and returns one byte at a time. This speeds up disk reads a lot. */ { static char buf[4096]; static int count; if(ii==4096) { // printf("-"); if((count= read(fh, buf, 4096))== -1) return(-1); ii=0; } if(ii == count) return(0); *p=buf[ii++]; return(1); } void wr(int fh_write, BYTE stuff[]) { /* printf("%s\n", stuff); */ _write(fh_write,stuff, strlen(stuff)); _write(fh_write,"\n",1); } void filereaderror(BYTE rfilename[]) { printf("file read error: %s", rfilename); exit(1); } void perr(BYTE er[]) { printf("%s\n",er); exit(1); } void helpme(void) { printf("NewROMs ver. 3.20\n" "---------------------\n" "\n" "Usage: NewROMs [options]\n" "where:\n" "\n" " options\n" " O=filename filename for input listinfo_old (default: listinfo_old.txt)\n" "\n" " N=filename filename for input listinfo_new (default: listinfo_new.txt)\n" "\n" " W=filename filename for output html_file (default: newroms.htm)\n" "\n" " R=filename the path where the roms are\n" "\n" "NewROMs looks for listinfo_new.txt and listinfo_old.txt (output from\n" "mame with -listinfo option) and outputs newroms.htm\n" "\n" "Warning! NewROMs will die after 20,000 games. Email\n" "dphirschler@hotmail.com for an update or for the C source code.\n"); exit(0); }