diff --git a/README.md b/README.md index e4fbdc4..b146a86 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,12 @@ To use it just launch the executable file (if available for your os) or type "py If you have any issues, which is probable, make a gitlab issue. There may be bugs. ## Roadmap +* Add requirements.txt +* switch to using a config file (or database) for keeping track of which tracks have been changed, that way only having one original_music folder and being able to *show* the user which song you used to replace which file. * add selective mute, so that you mute every music except the boss music, or every song except menu music or both. * figure out the best way to add a setting for changing each of the level editor songs, menu music, or a specific level song. Maybe an extra popup window or a check box for "replace every one" "menu" and "levelBuild" * add a way to change boss music separate from level music and menu music * add a way to show the available nsf files in the selected folder, like a playlist. -* add a settings file for the last folder chosen, so if there is a path try to use that so that you don't have to choose it manually * Instead of duplicating a single file a lot of times, maybe I'll implement symlink support. * add autoupdater?? diff --git a/mmm-nsf-changer.py b/mmm-nsf-changer.py index 1deb956..1785e0b 100644 --- a/mmm-nsf-changer.py +++ b/mmm-nsf-changer.py @@ -22,7 +22,7 @@ def safelist(): #maybe add autoupdater through gitlab -app_version = "v1.1.2" +app_version = "v1.2" def check_if_new_version(): response = requests.get("https://gitlab.com/api/v4/projects/51771052/repository/tags") newest_version = response.json()[0]["name"] @@ -93,19 +93,57 @@ def copy_music_to_ogmusic(path): print("Cutman.nsf and Oilman.nsf match in Music folder.") return False -#this needs to check if original_music exists, and if it does restore_ogmusic before moving to og music. -def move_music_to_ogmusic(path): + +def filename_to_filepath(filename, path): path = os.path.abspath(path) original_filepaths = check_folder_structure(path) - if original_filepaths: - if not filecmp.cmp(os.path.join(path,"Music","MM1","Cutman.nsf"), os.path.join(path, "Music", "MM1", "Oilman.nsf"), shallow=False): - shutil.move(os.path.join(path, "Music"), os.path.join(path, "original_music")) - if not os.path.exists(os.path.join(path, "Music")): - os.makedirs(os.path.join(path, "Music")) - else: - print("Cutman.nsf and Oilman.nsf match in Music folder.") + if original_filepaths != False: + for file_path in original_filepaths: + if os.path.basename(file_path) == filename: + old_song_path = file_path + break + return old_song_path + else: + return False + + +def replace_song(new_song_path,old_song_name, megamaker_folder): + path = os.path.abspath(megamaker_folder) + old_song_path = filename_to_filepath(old_song_name, megamaker_folder) + subfolder = os.path.basename(os.path.dirname(old_song_path)) + backup_path = os.path.join(megamaker_folder, "original_specific_songs", subfolder, old_song_name) + ##backup_song + if old_song_name != False: + os.makedirs(os.path.dirname(backup_path), exist_ok=True) + try: + shutil.copy(old_song_path, backup_path) + shutil.copy(new_song_path, old_song_path) + except FileNotFoundError: + print("FILE NOT FOUND") +def restore_song(old_song_name, megamaker_folder): + path = os.path.abspath(megamaker_folder) + old_song_path = filename_to_filepath(old_song_name, megamaker_folder) + subfolder = os.path.basename(os.path.dirname(old_song_path)) + backup_path = os.path.join(megamaker_folder, "original_specific_songs", subfolder, old_song_name) + if old_song_name != False: + try: + shutil.move(backup_path, old_song_path) + except FileNotFoundError: return False +# #this needs to check if original_music exists, and if it does restore_ogmusic before moving to og music. +# def move_music_to_ogmusic(path): +# path = os.path.abspath(path) +# original_filepaths = check_folder_structure(path) +# if original_filepaths: +# if not filecmp.cmp(os.path.join(path,"Music","MM1","Cutman.nsf"), os.path.join(path, "Music", "MM1", "Oilman.nsf"), shallow=False): +# shutil.move(os.path.join(path, "Music"), os.path.join(path, "original_music")) +# if not os.path.exists(os.path.join(path, "Music")): +# os.makedirs(os.path.join(path, "Music")) +# else: +# print("Cutman.nsf and Oilman.nsf match in Music folder.") +# return False + def recreate_structure(new_nsf, original_paths_list): for path in original_paths_list: if not os.path.exists(os.path.dirname(path)): @@ -113,7 +151,6 @@ def recreate_structure(new_nsf, original_paths_list): print("recreate structure if not os.path.exists") try: shutil.copy(new_nsf, path) - print("recreate structure shutil.copy") except: print("continuing") continue @@ -153,6 +190,9 @@ def nsf_changer (nsf_path, megamaker_folder): #move_music_to_ogmusic(megamaker_folder) copy_music_to_ogmusic(megamaker_folder) recreate_structure(nsf_path, original_path) + if common == os.path.join(megamaker_folder, "Music"): + if os.path.dirname(nsf_path) == megamaker_folder: + os.remove(nsf_path) print("nsf changer returning true") return True else: @@ -178,23 +218,27 @@ layout = [ [sg.Text("Mega Man Maker NSF Music Changer | Made by Timothy GFO", justification="center")], [sg.Text("YouTube", enable_events = True, key="-YT-", text_color="red"), sg.Text("GitLab",enable_events = True,key="-GIT-", text_color="purple"), sg.Text("Blog",enable_events = True,key="-SITE-", text_color="blue")], [sg.Text(version_message, text_color=version_color)], - [sg.Text("Input NSF File:"), sg.Input(key="-IN-"),sg.FileBrowse(file_types=(("NSF Files", "*.nsf*"),("NSFe Files", "*.nsfe*"),("SNES Files", "*.spc*"),("Gameboy Files", "*.gbs*"), ("Sega Genesis VGM", "*.vgm*"),("Sega Genesis GYM", "*.gym*"), ("ZX Spectrum", "*.ay*"), ("TurboGrafx 16", "*.hes*"), ("MSX Home Computer", "*.kss*"), ("Atari Pokey", "*.sap*"),))], - [sg.Text("MegaMaker Folder:"), sg.Input(key="-OUT-"), sg.FolderBrowse()], - [sg.Button("Mute All")], - [sg.Exit(),sg.Button("About") , sg.Button("Replace NSF Music"), sg.Button("Restore Original Music"),sg.Image(data=gif, key='_IMAGE_')], + [sg.Text("Input NSF File:"), sg.Input(sg.user_settings_get_entry('-INPUT_NSF-', ''), key="-IN-"),sg.FileBrowse(file_types=(("Supported Formats",".nsf .spc .vgm .nsfe .gbs .gym .ay .hes .kss .sap"),("NSF Files", "*.nsf*"),("NSFe Files", "*.nsfe*"),("SNES Files", "*.spc*"),("Gameboy Files", "*.gbs*"), ("Sega Genesis VGM", "*.vgm*"),("Sega Genesis GYM", "*.gym*"), ("ZX Spectrum", "*.ay*"), ("TurboGrafx 16", "*.hes*"), ("MSX Home Computer", "*.kss*"), ("Atari Pokey", "*.sap*"),))], + [sg.Text("MegaMaker Folder:"), sg.Input(sg.user_settings_get_entry('-MEGAMAKER_FOLDER-', ''), key="-OUT-"), sg.FolderBrowse()], + [sg.Button("Mute All"), sg.Button("Replace All NSF Music"), sg.Button("Restore All Original Music"),sg.Image(data=gif, key='_IMAGE_')], + [sg.Text("Output NSF File:"),sg.Combo(safelist(),default_value="ClownMan.nsf", key="-DROPDOWN-")], + [sg.Button("Replace Song"), sg.Button("Restore Original Song")], + [sg.Exit(),sg.Button("About")], ] how_to_use = "I made this tool to be able to change the music for any Mega Man Maker level while playing the game. It works by replacing every nsf file with a custom one, but while preserving the original folders and file names.\n\nTo use it, just choose a nsf file and then tell the program where you store the *game* folder. That is where the .exe is, not the user folder.\n\nIf you find this useful, you can check out my YouTube Channel or my blog since I will keep making tools like this. Also, if you find any bugs or errors remember to notify me at GitLab by making an Issue." window = sg.Window(f"MMM NSF Music Changer {app_version}", layout) -disclaimer = sg.popup_yes_no('NSF Changer, by Timothy GFO', 'This program is not complete, there WILL be bugs. Use at your own risk.', 'Do you want to continue?') +#disclaimer = sg.popup_yes_no('NSF Changer, by Timothy GFO', 'This program is not complete, there WILL be bugs. Use at your own risk.', 'Do you want to continue?') if check_if_new_version(): sg.popup(f"There is a new update for MMM NSF Changer. Get it at the GitLab repo.") -while disclaimer == "Yes": +while True: event,values = window.read(timeout=50) window.set_icon(icon) if event in (sg.WINDOW_CLOSED,"Exit"): + sg.user_settings_set_entry('-INPUT_NSF-', values['-IN-']) + sg.user_settings_set_entry('-MEGAMAKER_FOLDER-', values['-OUT-']) break window.Element('_IMAGE_').UpdateAnimation(gif, time_between_frames=100) if event == "-YT-": @@ -211,12 +255,23 @@ while disclaimer == "Yes": restore_ogmusic(values["-OUT-"]) if not nsf_changer(os.path.join(os.path.dirname(__file__), "mmm_nsf_changer_mute.nsf"), values["-OUT-"]): sg.popup_error("MegaMaker folder is not valid or definitions are out of date.") - if event == "Replace NSF Music": + if event == "Replace Song": + if values["-DROPDOWN-"] == "": + sg.popup_error('Please select which Output NSF File to replace. If not, use "Replace *All* NSF Music".') + else: + replace_song(values["-IN-"], values["-DROPDOWN-"], values["-OUT-"]) + if event == "Restore Original Song": + if values["-DROPDOWN-"] == "": + sg.popup_error('Please select which Output NSF File to replace. If not, use "Replace *All* NSF Music".') + else: + if restore_song(values["-DROPDOWN-"], values["-OUT-"]) == False: + sg.popup_error("The selected song has not been changed, cannot restore.") + if event == "Replace All NSF Music": if not nsf_changer(values["-IN-"], values["-OUT-"]): restore_ogmusic(values["-OUT-"]) if not nsf_changer(values["-IN-"], values["-OUT-"]): sg.popup_error("MegaMaker folder is not valid or definitions out of date.") - if event == "Restore Original Music": + if event == "Restore All Original Music": # sg.popup_error("DOESNT WORK EITHER HAHAHAHAHAHAA") if not restore_ogmusic(values["-OUT-"]): sg.popup_error("Unexpected folder structure or differing files")