From cb637d4c055ddef0eab7c430cf6d3cf39b83655a Mon Sep 17 00:00:00 2001 From: EricGoldsteinNz <32555045+EricGoldsteinNz@users.noreply.github.com> Date: Sun, 25 Jun 2023 21:35:14 +1200 Subject: [PATCH] Added Features: + Refresh drives button + "ALL" systems rebuilding option + GBA BIOS Fix + Games List Displayed --- build.bat | 6 +- frogtool.py | 25 +++++--- tadpole.py | 140 ++++++++++++++++++++++++++++++++++++------- tadpole_functions.py | 28 +++++++++ versioninfo | 6 +- 5 files changed, 169 insertions(+), 36 deletions(-) create mode 100644 tadpole_functions.py diff --git a/build.bat b/build.bat index 0593832..da67aeb 100644 --- a/build.bat +++ b/build.bat @@ -10,11 +10,13 @@ if not exist "venv\Lib\site-packages\PyInstaller" ( if not exist "venv\Lib\site-packages\PIL" ( venv\Scripts\python -m pip install Pillow ) -pyinstaller.exe --onefile -F tadpole.py --icon frog.ico --clean --noconsole +pyinstaller.exe --onefile -F tadpole.py --icon frog.ico --clean --noconsole --version-file versioninfo copy README.md "dist\readme.md" copy LICENSE "dist\license.txt" copy tadpole.py "dist\tadpole.py" +copy frogtool.py "dist\frogtool.py" +copy tadpole_functions.py "dist\tadpole_functions.py" cd dist tar -a -cf tadpole-%ver%-win.zip tadpole.exe readme.txt license.txt -tar -a -cf tadpole-%ver%-py.zip tadpole.py readme.txt license.txt +tar -a -cf tadpole-%ver%-py.zip tadpole.py frogtool.py tadpole_functions.py readme.txt license.txt cd ../ diff --git a/frogtool.py b/frogtool.py index 2f64b43..a3264ca 100644 --- a/frogtool.py +++ b/frogtool.py @@ -85,14 +85,23 @@ def sort_without_file_ext(unsorted_list): return sorted(sort_map, key=sort_map.get) -def process_sys(drive, system, test_mode): - print(f"Processing {system}") - - roms_path = f"{drive}/{system}" +def getROMList(roms_path): if not os.path.isdir(roms_path): print(f"! Couldn't find folder {roms_path}") print(" Check the provided path points to an SF2000 SD card!") raise StopExecution + files = os.scandir(roms_path) + files = list(filter(check_rom, files)) + filenames = list(map(file_entry_to_name, files)) + return filenames +#TODO + +def process_sys(drive, system, test_mode): + print(f"Processing {system}") + + roms_path = f"{drive}/{system}" + filenames = getROMList(roms_path) + index_path_files = f"{drive}/Resources/{systems[system][0]}" index_path_cn = f"{drive}/Resources/{systems[system][1]}" @@ -106,9 +115,8 @@ def process_sys(drive, system, test_mode): if system != "ARCADE": convert_zip_image_pairs_to_zxx(roms_path, system) - files = os.scandir(roms_path) - files = list(filter(check_rom, files)) - no_files = len(files) + + no_files = len(filenames) if no_files == 0: print("No ROMs found! Type Y to confirm you want to save an empty game list, or anything else to cancel") conf = input() @@ -118,7 +126,7 @@ def process_sys(drive, system, test_mode): else: print(f"Found {no_files} ROMs") - filenames = list(map(file_entry_to_name, files)) + stripped_names = list(map(strip_file_extension, filenames)) # prepare maps of filenames to index name for the 3 index files @@ -146,7 +154,6 @@ def find_matching_file_diff_ext(target, files): def convert_zip_image_pairs_to_zxx(roms_path, system): - img_files = os.scandir(roms_path) img_files = list(filter(check_img, img_files)) zip_files = os.scandir(roms_path) diff --git a/tadpole.py b/tadpole.py index d6d941a..c2c07ac 100644 --- a/tadpole.py +++ b/tadpole.py @@ -1,17 +1,54 @@ -from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QMessageBox, QGridLayout, QLabel, QComboBox, QPushButton) +#GUI imports +from PyQt5.QtWidgets import * from PyQt5.QtGui import (QIcon) -import frogtool +#OS imports - these should probably be moved somewhere else import os import sys import string +#Feature imports +import frogtool +import tadpole_functions + def RunFrogTool(): drive = window.combobox_drive.currentText() console = window.combobox_console.currentText() - print(f"Running Frogtool with drive ({drive}) and console ({console})") - result = frogtool.process_sys(drive,console, False) - QMessageBox.about(window,"Result",result) + print(f"Running frogtool with drive ({drive}) and console ({console})") + try: + if(console =="ALL"): + for console in frogtool.systems.keys(): + result = frogtool.process_sys(drive,console, False) + QMessageBox.about(window,"Result",result) + + else: + result = frogtool.process_sys(drive,console, False) + QMessageBox.about(window,"Result",result) + except frogtool.StopExecution: + pass + +def reloadDriveList(): + available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)] + window.combobox_drive.clear() + for drive in available_drives: + window.combobox_drive.addItem(QIcon(),drive,drive) + +def loadROMsToTable(): + drive = window.combobox_drive.currentText() + system = window.combobox_console.currentText() + if drive == "???" or system == "???": + return + roms_path = f"{drive}/{system}" + try: + files = frogtool.getROMList(roms_path) + window.tbl_gamelist.setRowCount(len(files)) + for i, (name) in enumerate(files): + window.tbl_gamelist.setItem(i,0,QTableWidgetItem(f"{name}")) + except frogtool.StopExecution: + #Empty the table + window.tbl_gamelist.setRowCount(0) + + window.tbl_gamelist.show() #SubClass QMainWindow to create a Tadpole general interface class MainWindow (QMainWindow): @@ -20,29 +57,90 @@ def __init__(self): self.setWindowTitle("Tadpole - SF2000 Tool") widget = QWidget() self.setCentralWidget(widget) + + #Load the Menus + self.create_actions() + self.loadMenus() + layout = QGridLayout(widget) rowCounter = 0 - + colCounter = 0 #Drive Select Widgets self.lbl_drive = QLabel(text="Drive:") self.combobox_drive = QComboBox() - layout.addWidget(self.lbl_drive, rowCounter, 0) - layout.addWidget(self.combobox_drive, rowCounter, 1) - rowCounter += 1 - + self.combobox_drive.currentIndexChanged.connect(loadROMsToTable) + self.btn_refreshDrives = QPushButton() + self.btn_refreshDrives.setIcon(self.style().standardIcon(getattr(QStyle, "SP_BrowserReload"))) + self.btn_refreshDrives.clicked.connect(reloadDriveList) + layout.addWidget(self.lbl_drive, rowCounter, colCounter) + colCounter += 1 + layout.addWidget(self.combobox_drive, rowCounter, colCounter) + colCounter += 1 + layout.addWidget(self.btn_refreshDrives,rowCounter,colCounter) + colCounter += 1 + #Console Select Widgets self.lbl_console = QLabel(text="Console:") self.combobox_console = QComboBox() - layout.addWidget(self.lbl_console, rowCounter, 0) - layout.addWidget(self.combobox_console, rowCounter, 1) + self.combobox_console.currentIndexChanged.connect(loadROMsToTable) + layout.addWidget(self.lbl_console, rowCounter, colCounter) + colCounter += 1 + layout.addWidget(self.combobox_console, rowCounter, colCounter) + colCounter += 1 + + #Update Button Widget + self.btn_update = QPushButton("Update!") + layout.addWidget(self.btn_update, rowCounter, colCounter) + self.btn_update.clicked.connect(RunFrogTool) + colCounter += 1 + + self.lbl_fillerR1 = QLabel() + layout.addWidget(self.lbl_fillerR1, rowCounter, colCounter) + layout.setColumnStretch(colCounter,1) + colCounter += 1 + + #New Row rowCounter += 1 + colCounter = 0 + + #Game Table Widget + self.tbl_gamelist = QTableWidget() + self.tbl_gamelist.setColumnCount(4) + self.tbl_gamelist.setHorizontalHeaderLabels(["Name","Size","Thumbnail","Actions"]) + layout.addWidget(self.tbl_gamelist,rowCounter, 0, 1, -1) + + + def loadMenus(self): + self.menu_file = self.menuBar().addMenu("&File") + self.menu_file.addAction(self.about_action) + self.menu_file.addAction(self.exit_action) - #Update Widget - self.button = QPushButton("Update!") - layout.addWidget(self.button, rowCounter, 0) - + self.menu_os = self.menuBar().addMenu("&OS") + self.menu_os.addAction(self.GBABIOSFix_action) + + + def create_actions(self): + self.about_action = QAction("&About", self, triggered=self.about) + self.exit_action = QAction("E&xit", self, shortcut="Ctrl+Q",triggered=self.close) + self.GBABIOSFix_action = QAction("&GBA BIOS Fix", self, triggered=self.GBABIOSFix) + def about(self): + QMessageBox.about(self, "About Tadpole","Tadpole was created by EricGoldstein based on the original work from tzlion on frogtool") + + def GBABIOSFix(self): + drive = window.combobox_drive.currentText() + try: + tadpole_functions.GBABIOSFix(drive) + except tadpole_functions.Exception_InvalidPath: + QMessageBox.about(self, "GBA BIOS Fix","An error occurred. Please ensure that you have the right drive selected and gba_bios.bin exists in the bios folder") + return + QMessageBox.about(self, "GBA BIOS Fix","BIOS successfully copied") + + + def UnderDevelopmentPopup(self): + QMessageBox.about(self, "Developement","This feature is still under development") + #Initialise the Application app = QApplication(sys.argv) @@ -52,10 +150,7 @@ def __init__(self): #Update list of drives available_drives_placeholder = "???" window.combobox_drive.addItem(QIcon(),available_drives_placeholder,available_drives_placeholder) -available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)] -window.combobox_drive.clear() -for drive in available_drives: - window.combobox_drive.addItem(QIcon(),drive,drive) +reloadDriveList() #Update list of consoles @@ -64,10 +159,11 @@ def __init__(self): window.combobox_console.clear() for console in frogtool.systems.keys(): window.combobox_console.addItem(QIcon(),console,console) + +#Add ALL to the list to add this fucntionality from frogtool +window.combobox_console.addItem(QIcon(),"ALL","ALL") -window.button.clicked.connect(RunFrogTool) - window.show() app.exec() \ No newline at end of file diff --git a/tadpole_functions.py b/tadpole_functions.py new file mode 100644 index 0000000..b0d90b4 --- /dev/null +++ b/tadpole_functions.py @@ -0,0 +1,28 @@ +import os +import sys +import shutil + +def GBABIOSFix(drive): + if drive == "???": + raise Exception_InvalidPath + GBABIOSPath = f"{drive}/bios/gba_bios.bin" + if not os.path.exists(GBABIOSPath): + print(f"! Couldn't find game list file {GBABIOSPath}") + print(" Check the provided path points to an SF2000 SD card!") + raise Exception_InvalidPath + try: + GBAFolderPath = f"{drive}/GBA/mnt/sda1/bios/" + ROMSFolderPath = f"{drive}/ROMS/mnt/sda1/bios/" + os.makedirs(os.path.dirname(GBAFolderPath), exist_ok=True) + os.makedirs(os.path.dirname(ROMSFolderPath), exist_ok=True) + shutil.copyfile(GBABIOSPath, f"{GBAFolderPath}/gba_bios.bin") + shutil.copyfile(GBABIOSPath, f"{ROMSFolderPath}/gba_bios.bin") + except (OSError, IOError) as error: + print("! Failed to copy GBA BIOS.") + print(error) + raise Exception_InvalidPath + + + +class Exception_InvalidPath(Exception): + pass \ No newline at end of file diff --git a/versioninfo b/versioninfo index f4403bc..f819116 100644 --- a/versioninfo +++ b/versioninfo @@ -15,12 +15,12 @@ VSVersionInfo( u'080904B0', [StringStruct(u'CompanyName', u'EricGoldstein'), StringStruct(u'FileDescription', u'tadpole'), - StringStruct(u'FileVersion', u'0.1.1'), + StringStruct(u'FileVersion', u'0.2.1'), StringStruct(u'InternalName', u'tadpole'), - StringStruct(u'LegalCopyright', u'by taizou 2023'), + StringStruct(u'LegalCopyright', u'by EricGoldstein 2023'), StringStruct(u'OriginalFilename', u'tadpole.exe'), StringStruct(u'ProductName', u'tadpole'), - StringStruct(u'ProductVersion', u'0.1.1')]) + StringStruct(u'ProductVersion', u'0.2.1')]) ]), VarFileInfo([VarStruct(u'Translation', [2057, 1200])]) ]