static void id3tag_ausgabe(struct id3tag *tag) { printf( "Titel: %s\n" "Künstler: %s\n" "Album: %s\n" "Jahr: %s\n" "Kommentar: %s\n" "Nummer: %d\n" "Genre: %s\n\n", tag->title, tag->artist, tag->album, tag->year, tag->comment, tag->tracknumber, get_genre(tag->genre) ); }
//writes out a tbg file int Ctbg::ExportFile(int filetype, CString outfilepath, int type) { CString outfilename; CString tmpstr; int count,maxcount; int i,j; int idx; int esize; int fhandle; int ret; idx=determinetype(filetype&0xfff); if(idx>NUM_OBJTYPE) return -99; //filetype not supported if(!tbgext[idx]) return -99; if(filetype&TBG_ALT) { outfilename.Format("%s%s#%c",outfilepath,itemname,tbgext[idx]); } else { if(tbgext[idx]=='-') outfilename.Format("%s%s",bgfolder,itemname); else outfilename.Format("%s%s-%c",outfilepath,itemname,tbgext[idx]); } if(type) { outfilename+=".tp2"; } else { outfilename+=".tbg"; } new_iap(); //clears headers & counters switch(filetype) { case REF_CRE|TBG_ALT: //soundrefs header.filelength=SND_SLOT_COUNT*sizeof(long); ret=collect_creaturerefs(TBG_ALT); break; case REF_ITM: header.filelength=the_item.WriteItemToFile(0,1); ret=collect_itemrefs(); break; case REF_SPL: header.filelength=the_spell.WriteSpellToFile(0,1); ret=collect_spellrefs(); break; case REF_STO: header.filelength=the_store.WriteStoreToFile(0,1); ret=collect_storerefs(); break; case REF_EFF: header.filelength=the_effect.WriteEffectToFile(0,1); ret=collect_effectrefs(); break; case REF_ARE: header.filelength=the_area.WriteAreaToFile(0,1); ret=collect_arearefs(); break; case REF_CRE: header.filelength=the_creature.WriteCreatureToFile(0,1); ret=collect_creaturerefs(0); break; case REF_WMP: header.filelength=the_map.WriteMapToFile(0,1); ret=collect_worldmaprefs(); break; case REF_CHU: header.filelength=the_chui.WriteChuiToFile(0,1); ret=collect_chuirefs(); break; case REF_SRC: header.filelength=the_src.WriteStringToFile(0,1); ret=collect_srcrefs(); break; case REF_DLG: header.filelength=the_dialog.WriteDialogToFile(0,1); ret=collect_dlgrefs(); break; case REF_PRO: header.filelength=the_projectile.WriteProjectileToFile(0,1); ret=collect_prorefs(); break; default: ret=-99; } if(ret<0) return ret; if (type) { return OutputTP2(outfilename); } memcpy(header.signature,"TBG4",4); if(filetype&TBG_ALT) header.signature[3]=(char) toupper(tbgext[idx]); maxcount=header.strrefcount=header.tlkentrycount; for(count=0;count<maxcount;count++) tlkentries[count].strrefoffset=count; for(count=0;count<header.tlkentrycount;count++) { for(i=0;i<count;i++) { //now we use this offset as strref (it will be used differently elsewhere) if(tlkentries[count].offset==tlkentries[i].offset) { //moving the strrref of the same type forward SwapPalette(strrefs, tlkentries[i].strrefoffset, tlkentries[count].strrefoffset); //removing the tlk header of the same type (# is in count) memmove(tlkentries+count, tlkentries+count+1, (maxcount-count-1)*sizeof(tbg_tlk_reference)); memset(tlkentries+maxcount-1,-1,sizeof(tbg_tlk_reference) ); //incrementing the ref. count of the previous entry tlkentries[i].strrefcount++; //adjusting the other entries for(j=i+1;j<count;j++) { tlkentries[j].strrefoffset++; } header.tlkentrycount--; count--; break; } } } tmpstr.Format("%s%s",itemname,objexts[idx]); strncpy(header.filename,tmpstr,sizeof(header.filename) ); header.genre=get_genre(); header.tlkentryoffset=sizeof(tbg4_header); header.strrefoffset=header.tlkentryoffset+header.tlkentrycount*sizeof(tbg_tlk_reference); header.asciioffset=header.strrefoffset+header.strrefcount*sizeof(unsigned long); header.fileoffset=header.asciioffset+header.asciicount*sizeof(unsigned long); header.textentryoffset=header.fileoffset+header.filelength; //adjusting strref offsets //setting string offsets (we used this as pointer offset) m_tbgnames=new CString[maxcount]; if(!m_tbgnames) return -3; count=0; for(i=0;i<header.tlkentrycount;i++) { m_tbgnames[i]=tlk_entries[0][tlkentries[i].offset].text; tlkentries[i].offset=count; count+=m_tbgnames[i].GetLength(); } fhandle=open(outfilename, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,S_IREAD|S_IWRITE); if(fhandle<1) return -2; if(write(fhandle,&header,sizeof(header) )!=sizeof(header) ) { ret=-2; goto endofquest; } esize=header.tlkentrycount*sizeof(tbg_tlk_reference); if(write(fhandle,tlkentries,esize )!=esize) { ret=-2; goto endofquest; } esize=header.strrefcount*sizeof(unsigned long); if(write(fhandle,strrefs,esize)!=esize) { ret=-2; goto endofquest; } switch(filetype) { case REF_CRE|TBG_ALT: write(fhandle,the_creature.header.strrefs,header.filelength); break; case REF_ITM: the_item.WriteItemToFile(fhandle,0); break; case REF_SPL: the_spell.WriteSpellToFile(fhandle,0); break; case REF_STO: the_store.WriteStoreToFile(fhandle,0); break; case REF_EFF: the_effect.WriteEffectToFile(fhandle,0); break; case REF_ARE: the_area.WriteAreaToFile(fhandle,0); break; case REF_CRE: the_creature.WriteCreatureToFile(fhandle,0); break; case REF_WMP: the_map.WriteMapToFile(fhandle,0); break; case REF_CHU: the_chui.WriteChuiToFile(fhandle,0); break; case REF_SRC: the_src.WriteStringToFile(fhandle,0); break; case REF_DLG: the_dialog.WriteDialogToFile(fhandle,0); break; case REF_PRO: the_projectile.WriteProjectileToFile(fhandle,0); break; default: ret=-99; } for(i=0;i<header.tlkentrycount;i++) { if(write(fhandle,m_tbgnames[i].GetBuffer(0),tlkentries[i].length)!=tlkentries[i].length) { ret=-2; goto endofquest; } } endofquest: close(fhandle); return ret; }
int Ctbg::WriteIap(int fhandle) { CString tmpstr; CString *tbgnames, *othernames; int esize; int i; int ret; ret=0; memcpy(iapheader.signature,"IAP",4); iapheader.genre=(unsigned char) get_genre(); othernames=tbgnames=NULL; esize=iapfilecount*sizeof(iap_file_header); iapheader.totallen=sizeof(iap_header)+esize; if(tbgnamecount!=iapheader.tbgcount) return -1; if(othernamecount!=iapheader.othercount) return -1; tbgnames=new CString[iapheader.tbgcount]; if(!tbgnames) { return -3; //no need of quest } othernames=new CString[iapheader.othercount]; if(!othernames) { ret=-3; goto endofquest; } for(i=0;i<iapheader.tbgcount;i++) { if(AddTbgFile(i,tbgnames[i])) { ret=-2; goto endofquest; } } for(i=0;i<iapheader.othercount;i++) { if(AddOtherFile(i,othernames[i])) { ret=-2; goto endofquest; } } for(i=0;i<iapfilecount;i++) { iapfileheaders[i].nameoffset=iapheader.totallen; if(i<tbgnamecount) { iapfileheaders[i].namelength=tbgnames[i].GetLength(); } else { iapfileheaders[i].namelength=othernames[i-tbgnamecount].GetLength(); } iapheader.totallen+=iapfileheaders[i].namelength; iapfileheaders[i].fileoffset=iapheader.totallen; iapheader.totallen+=iapfileheaders[i].filelength; } if(write(fhandle,&iapheader,sizeof(iapheader) )!=sizeof(iapheader) ) { ret=-2; goto endofquest; } esize=iapfilecount*sizeof(iap_file_header); if(write(fhandle,iapfileheaders,esize)!=esize) { ret=-2; goto endofquest; } for(i=0;i<iapheader.tbgcount;i++) { ret=AddToFile(fhandle, m_tbgnames[i], tbgnames[i], iapfileheaders[i].filelength); if(ret<0) goto endofquest; } for(i=0;i<iapheader.othercount;i++) { ret=AddToFile(fhandle,m_othernames[i], othernames[i], iapfileheaders[i+iapheader.tbgcount].filelength); if(ret<0) goto endofquest; } endofquest: if(tbgnames) delete [] tbgnames; if(othernames) delete [] othernames; return ret; }
int main(int argc, char *argv[]) { FILE *fp; int c, i, interactive = 0, view_only=1,delete_tag=0,file_open,retcode=0; int want_id3=1,scantype=SCAN_NONE,fullscan_vbr=0; int show_techinfo=0,force_mode=0,quickscan=1; int new_track=0,new_genre=0,firstfilearg; id3tag new_tag; char *print_format=NULL; char error_msg[256]; unsigned int g,n; int vbr_report=VBR_VARIABLE; mp3info mp3; new_tag.title[0]=new_tag.artist[0]=new_tag.album[0]=new_tag.year[0]= new_tag.comment[0]=new_tag.track[0]=new_tag.genre[0]=1; /* use something REALLY unlikely... -- so we could clear the tag... */ if (argc < 2 ) /* Only command is given. Short help */ { printf("%s %s\n"\ "\n MP3Info comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"\ " you are welcome to redistribute it under certain conditions.\n"\ " See the file 'LICENSE' for more information.\n"\ "\nUse 'mp3info -h' for a usage summary or see the mp3info man page for a\n"\ "complete description.\n",VERSION,COPYRIGHT); return 0; } while ((c=getopt(argc,argv,"vhGidfxFt:a:l:y:c:n:g:p:r:"))!=-1) { switch(c) { case 'v': /* View mode is now automatic when no changes are made to the ID3 tag. This switch is accepted only for backward compatibility */ break; case 'h': display_help(); return 0; break; case 'G': display_genres(alphagenreindex,typegenre); return 0; break; case 'i': view_only=0; interactive = 1; break; case 'd': view_only=0; delete_tag=1; break; case 'p': print_format=optarg; translate_escapes(print_format); want_id3=0; break; case 'f': force_mode=1; break; case 'x': show_techinfo=1; break; case 't': strncpy(new_tag.title,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'a': strncpy(new_tag.artist,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'l': strncpy(new_tag.album,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'y': strncpy(new_tag.year,optarg,INT_FIELD_LEN); view_only=0; break; case 'c': strncpy(new_tag.comment,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'n': n=atoi(optarg); if(n <= 255) { new_tag.track[0] = (unsigned char) n; new_track=1; view_only=0; } else { fprintf(stderr,"Error: '%s' is not a valid track number.\n",optarg); fprintf(stderr,"Valid track numbers are integers from 0 to 255.\n"); fprintf(stderr,"Use a value of '0' to remove the track number field\n"); retcode |= 6; return retcode; } break; case 'g': g=get_genre(optarg); if(g <= 255) { new_tag.genre[0] = (unsigned char) g; new_genre=1; view_only=0; } else { fprintf(stderr,"Error: '%s' is not a recognized genre name or number.\n",optarg); fprintf(stderr,"Use the '-G' option to see a list of valid genre names and numbers\n"); retcode |= 6; return retcode; } sscanf(optarg,"%u",&g); break; case 'r': switch(optarg[0]) { case 'a': vbr_report=VBR_AVERAGE; break; case 'm': vbr_report=VBR_MEDIAN; break; case 'v': vbr_report=VBR_VARIABLE; break; default: fprintf(stderr,"Error: %s is not a valid option to the VBR reporting switch (-r)\n",optarg); fprintf(stderr,"Valid options are 'a', 'm' and 'v'. Run '%s -h' for more info.\n",argv[0]); retcode |= 6; return retcode; } break; case 'F': quickscan=0; break; } } if(!view_only) scantype=SCAN_QUICK; if(print_format) { determine_tasks(print_format,&want_id3,&scantype,&fullscan_vbr,vbr_report); } else if(view_only) { determine_tasks(ID3_FORMAT_STRING,&want_id3,&scantype,&fullscan_vbr,vbr_report); if(show_techinfo) determine_tasks(TECH_FORMAT_STRING,&want_id3,&scantype,&fullscan_vbr,vbr_report); } if(!quickscan && (scantype == SCAN_QUICK)) scantype=SCAN_FULL; firstfilearg=optind; for(i=optind;i < argc; i++) { /* Iterate over all filenames */ file_open=0; if (view_only == 1) { if ( !( fp=fopen(argv[i],"rb") ) ) { sprintf(error_msg,"Error opening MP3: %s",argv[i]); perror(error_msg); retcode |= 1; } else { file_open=1; } } else { if ( !( fp=fopen(argv[i],"rb+") ) ) { sprintf(error_msg,"Error opening MP3: %s",argv[i]); perror(error_msg); retcode |= 1; } else { file_open=1; } } if(file_open == 1) { memset(&mp3,0,sizeof(mp3info)); mp3.filename=argv[i]; mp3.file=fp; get_mp3_info(&mp3,scantype,fullscan_vbr); if((scantype != SCAN_NONE) && !mp3.header_isvalid && !force_mode) { fprintf(stderr,"%s is corrupt or is not a standard MP3 file.\n",mp3.filename); retcode |= 2; } if(view_only) { if(want_id3 && !mp3.id3_isvalid) fprintf(stderr,"%s does not have an ID3 1.x tag.\n",mp3.filename); if(print_format) { format_output(print_format,&mp3,vbr_report); } else { if(mp3.id3_isvalid || (show_techinfo && mp3.header_isvalid)) format_output(FILENAME_FORMAT_STRING,&mp3,vbr_report); if(mp3.id3_isvalid) format_output(ID3_FORMAT_STRING,&mp3,vbr_report); if(show_techinfo && mp3.header_isvalid) format_output(TECH_FORMAT_STRING,&mp3,vbr_report); printf("\n"); } } else if(mp3.header_isvalid || force_mode) { if(new_tag.title[0]!=1) { strncpy(mp3.id3.title,new_tag.title,TEXT_FIELD_LEN); } if(new_tag.artist[0]!=1) { strncpy(mp3.id3.artist,new_tag.artist,TEXT_FIELD_LEN); } if(new_tag.album[0]!=1) { strncpy(mp3.id3.album,new_tag.album,TEXT_FIELD_LEN); } if(new_tag.comment[0]!=1) { strncpy(mp3.id3.comment,new_tag.comment,TEXT_FIELD_LEN); } if(new_track) { mp3.id3.track[0]=new_tag.track[0]; if(new_tag.track[0] == '\0') { pad(mp3.id3.comment,TEXT_FIELD_LEN); } } if(new_tag.year[0]!=1) { strncpy(mp3.id3.year,new_tag.year,INT_FIELD_LEN); } if(new_genre) { mp3.id3.genre[0]=new_tag.genre[0]; } if( interactive ) { tagedit_curs(mp3.filename,i-firstfilearg+1,argc-firstfilearg,&(mp3.id3)); } /* Finally! Get it done! */ if(!delete_tag) { write_tag(&mp3); } } else { fprintf(stderr,"Use the -f switch to add ID3 info to this file anyway.\n"); } fclose(mp3.file); if(delete_tag && mp3.id3_isvalid) { truncate(mp3.filename,mp3.datasize); } } } if(optind == argc) { fprintf(stderr,"No MP3 files specified!\n"); retcode |= 8; } return retcode; }