This commit is contained in:
Lesserkuma
2021-01-01 01:59:05 +01:00
parent 9404d7e096
commit 365a671cba
11 changed files with 40 additions and 18 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -11,7 +11,7 @@ from . import hw_GBxCartRW
hw_devices = [hw_GBxCartRW]
APPNAME = "FlashGBX"
VERSION_PEP440 = "0.10"
VERSION_PEP440 = "1.0"
VERSION = "v{:s}".format(VERSION_PEP440)
class FlashGBX(QtWidgets.QWidget):
@@ -229,11 +229,10 @@ class FlashGBX(QtWidgets.QWidget):
# Read config, find devices and connect
self.InitConfig(args)
self.FindDevices()
# Show app window first, then do update check
qt_app.processEvents()
QtCore.QTimer.singleShot(1, lambda: [ self.UpdateCheck() ])
QtCore.QTimer.singleShot(1, lambda: [ self.UpdateCheck(), self.FindDevices() ])
def InitConfig(self, args):
app_path = args['app_path']
@@ -524,7 +523,7 @@ class FlashGBX(QtWidgets.QWidget):
def UpdateCheck(self):
update_check = self.SETTINGS.value("UpdateCheck")
if update_check is None:
answer = QtWidgets.QMessageBox.question(self, APPNAME, "Would you like to automatically check for new versions at application startup?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
answer = QtWidgets.QMessageBox.question(self, APPNAME, "Would you like to automatically check for new versions at application startup?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
if answer == QtWidgets.QMessageBox.Yes:
self.SETTINGS.setValue("UpdateCheck", "enabled")
self.mnuConfig.actions()[0].setChecked(True)
@@ -636,6 +635,7 @@ class FlashGBX(QtWidgets.QWidget):
if ret is False:
self.CONN = None
if self.cmbDevice.count() == 0: self.lblDevice.setText("No connection.")
return False
elif isinstance(ret, list):
@@ -699,6 +699,7 @@ class FlashGBX(QtWidgets.QWidget):
#self.btnScan.setEnabled(False)
self.btnConnect.setEnabled(False)
qt_app.processEvents()
time.sleep(0.05)
global hw_devices
for hw_device in hw_devices:
@@ -816,7 +817,7 @@ class FlashGBX(QtWidgets.QWidget):
if self.CONN.INFO["transferred"] == 131072: # 128 KB
with open(self.CONN.INFO["last_path"], "rb") as file: temp = file.read()
if temp[0x1FFB1:0x1FFB6] == b'Magic':
answer = QtWidgets.QMessageBox.question(self, APPNAME, "Game Boy Camera save data was detected.\nWould you like to load it with the GB Camera Viewer now?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
answer = QtWidgets.QMessageBox.question(self, APPNAME, "Game Boy Camera save data was detected.\nWould you like to load it with the GB Camera Viewer now?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
if answer == QtWidgets.QMessageBox.Yes:
self.CAMWIN = None
self.CAMWIN = PocketCameraWindow(self, icon=self.windowIcon(), file=self.CONN.INFO["last_path"])
@@ -862,7 +863,7 @@ class FlashGBX(QtWidgets.QWidget):
QtWidgets.QMessageBox.critical(self, APPNAME, "No flash cartridge type configuration files found. Try to restart the application with the “--reset” switch to reset the configuration.", QtWidgets.QMessageBox.Ok)
return 0
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="Would you like " + APPNAME + " to try and auto-detect the flash cartridge type?", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="Would you like " + APPNAME + " to try and auto-detect the flash cartridge type?", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
cb = QtWidgets.QCheckBox("Limit voltage to 3.3V", checked=True)
if self.CONN.GetMode() == "DMG":
msgbox.setCheckBox(cb)
@@ -873,7 +874,7 @@ class FlashGBX(QtWidgets.QWidget):
else:
detected = self.CONN.AutoDetectFlash(limitVoltage)
if len(detected) == 0:
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="No pre-configured flash cartridge type was detected. You can still try and manually select one from the list -- look for similar PCB text and/or flash chip markings. However, chances are this cartridge is currently not supported for flashing with " + APPNAME + ".\n\nWould you like " + APPNAME + " to run a flash chip query? This may help adding support for your flash cartridge in the future.", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="No pre-configured flash cartridge type was detected. You can still try and manually select one from the list -- look for similar PCB text and/or flash chip markings. However, chances are this cartridge is currently not supported for flashing with " + APPNAME + ".\n\nWould you like " + APPNAME + " to run a flash chip query? This may help adding support for your flash cartridge in the future.", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
if self.CONN.GetMode() == "DMG":
msgbox.setCheckBox(cb)
answer = msgbox.exec()
@@ -1013,7 +1014,7 @@ class FlashGBX(QtWidgets.QWidget):
path = ""
if dpath != "":
text = "The following ROM file will now be written to the flash cartridge:\n" + dpath
answer = QtWidgets.QMessageBox.question(self, APPNAME, text, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.question(self, APPNAME, text, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
if answer == QtWidgets.QMessageBox.Cancel: return
path = dpath
@@ -1058,7 +1059,7 @@ class FlashGBX(QtWidgets.QWidget):
with open(path, "rb") as file: buffer = file.read()
rom_size = len(buffer)
if rom_size > carts[cart_type]['flash_size']:
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "The selected flash cartridge type seems to support ROMs that are up to " + str(int(carts[cart_type]['flash_size'] / 1024 / 1024)) + " MB in size, but the file you selected is " + str(os.path.getsize(path)/1024/1024) + " MB. You can still give it a try, but its possible that its too large.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "The selected flash cartridge type seems to support ROMs that are up to " + str(int(carts[cart_type]['flash_size'] / 1024 / 1024)) + " MB in size, but the file you selected is " + str(os.path.getsize(path)/1024/1024) + " MB. You can still give it a try, but its possible that its too large.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
if answer == QtWidgets.QMessageBox.Cancel: return
override_voltage = False
@@ -1098,10 +1099,10 @@ class FlashGBX(QtWidgets.QWidget):
elif self.CONN.GetMode() == "AGB":
hdr = RomFileAGB(path).GetHeader()
if not hdr["logo_correct"]:
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "Warning: The ROM file you selected may not boot on actual hardware due to invalid logo data.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "Warning: The ROM file you selected will not boot on actual hardware due to invalid logo data.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
if answer == QtWidgets.QMessageBox.Cancel: return
if not hdr["header_checksum_correct"]:
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "Warning: The ROM file you selected may not boot on actual hardware due to an invalid header checksum (expected 0x{:02X} instead of 0x{:02X}).".format(hdr["header_checksum_calc"], hdr["header_checksum"]), QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "The ROM file you selected will not boot on actual hardware due to an invalid header checksum (expected 0x{:02X} instead of 0x{:02X}).".format(hdr["header_checksum_calc"], hdr["header_checksum"]), QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
if answer == QtWidgets.QMessageBox.Cancel: return
self.CONN.FlashROM(fncSetProgress=self.SetProgress, path=path, cart_type=cart_type, override_voltage=override_voltage, prefer_sector_erase=prefer_sector_erase, reverse_sectors=reverse_sectors)
@@ -1175,12 +1176,12 @@ class FlashGBX(QtWidgets.QWidget):
if dpath != "":
text = "The following save data file will now be written to the cartridge:\n" + dpath
answer = QtWidgets.QMessageBox.question(self, APPNAME, text, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.question(self, APPNAME, text, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
if answer == QtWidgets.QMessageBox.Cancel: return
path = dpath
self.SETTINGS.setValue(setting_name, os.path.dirname(path))
elif erase:
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "The save data on your cartridge will now be erased.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
answer = QtWidgets.QMessageBox.warning(self, APPNAME, "The save data on your cartridge will now be erased.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
if answer == QtWidgets.QMessageBox.Cancel: return
else:
path = path + ".sav"
@@ -1203,7 +1204,7 @@ class FlashGBX(QtWidgets.QWidget):
dontShowAgain = str(self.SETTINGS.value("AutoReconnect")).lower() == "enabled"
if not dontShowAgain:
cb = QtWidgets.QCheckBox("Always try to reconnect without asking", checked=False)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="The connection to the device was lost. Do you want to try and reconnect to the first device found? The cartridge information will also be reset and read again.", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle=APPNAME, text="The connection to the device was lost. Do you want to try and reconnect to the first device found? The cartridge information will also be reset and read again.", standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
msgbox.setCheckBox(cb)
answer = msgbox.exec()
dontShowAgain = cb.isChecked()
@@ -1248,7 +1249,7 @@ class FlashGBX(QtWidgets.QWidget):
if not dontShowAgain and mode is not None:
cb = QtWidgets.QCheckBox("Dont show this message again.", checked=False)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle=APPNAME, text="The mode will now be changed to " + {"DMG":"Game Boy", "AGB":"Game Boy Advance"}[setTo] + " mode. To be safe, cartridges should only be exchanged while the device is not powered on." + voltageWarning, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle=APPNAME, text="The mode will now be changed to " + {"DMG":"Game Boy", "AGB":"Game Boy Advance"}[setTo] + " mode. To be safe, cartridges should only be exchanged while the device is not powered on." + voltageWarning, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, defaultButton=QtWidgets.QMessageBox.Ok)
if self.CONN.CanSetVoltageAutomatically(): msgbox.setCheckBox(cb)
answer = msgbox.exec()
dontShowAgain = cb.isChecked()
@@ -1769,7 +1770,7 @@ def main(portableMode=False):
args = parser.parse_args()
config_path = cp[args.cfgdir]
print("\n{:s} {:s} by Lesserkuma".format(APPNAME, VERSION))
print("{:s} {:s} by Lesserkuma".format(APPNAME, VERSION))
print("\nDISCLAIMER: This software is provided as-is and the developer is not responsible for any damage that is caused by the use of it. Use at your own risk!")
print("\nFor troubleshooting please visit https://github.com/lesserkuma/FlashGBX")

View File

@@ -47,18 +47,25 @@ class PocketCameraWindow(QtWidgets.QDialog):
grpColorsLayout.setContentsMargins(-1, 3, -1, -1)
self.rowColors1 = QtWidgets.QHBoxLayout()
self.optColorBW = QtWidgets.QRadioButton("&Grayscale")
self.optColorBW.setToolTip("Generic grayscale palette")
self.connect(self.optColorBW, QtCore.SIGNAL("clicked()"), self.SetColors)
self.optColorDMG = QtWidgets.QRadioButton("&DMG")
self.optColorDMG.setToolTip("Original Game Boy screen palette")
self.connect(self.optColorDMG, QtCore.SIGNAL("clicked()"), self.SetColors)
#self.optColorMGB = QtWidgets.QRadioButton("&MGB")
#self.optColorMGB.setToolTip("Game Boy Pocket palette")
#self.connect(self.optColorMGB, QtCore.SIGNAL("clicked()"), self.SetColors)
self.optColorSGB = QtWidgets.QRadioButton("&SGB")
self.optColorSGB.setToolTip("Super Game Boy palette")
self.connect(self.optColorSGB, QtCore.SIGNAL("clicked()"), self.SetColors)
self.optColorCGB1 = QtWidgets.QRadioButton("CGB &1")
self.optColorCGB1.setToolTip("Japanese Pocket Camera palette")
self.connect(self.optColorCGB1, QtCore.SIGNAL("clicked()"), self.SetColors)
self.optColorCGB2 = QtWidgets.QRadioButton("CGB &2")
self.optColorCGB2.setToolTip("Golden Limited Edition Game Boy Camera palette")
self.connect(self.optColorCGB2, QtCore.SIGNAL("clicked()"), self.SetColors)
self.optColorCGB3 = QtWidgets.QRadioButton("CGB &3")
self.optColorCGB3.setToolTip("Non-Japanese Game Boy Camera palette")
self.connect(self.optColorCGB3, QtCore.SIGNAL("clicked()"), self.SetColors)
self.rowColors1.addWidget(self.optColorBW)
self.rowColors1.addWidget(self.optColorDMG)

View File

@@ -1,9 +1,11 @@
{
"type":"DMG",
"names":[
"BUNG Doctor GB Card 64M"
"BUNG Doctor GB Card 64M",
"Mr Flash 64M"
],
"flash_ids":[
[ 0x89, 0x89, 0x15, 0x15 ],
[ 0x89, 0x89, 0x15, 0x15 ]
],
"voltage":5,

View File

@@ -10,6 +10,7 @@
"flash_size":0x80000,
"start_addr":0,
"first_bank":1,
"flash_commands_on_bank_1":true,
"write_pin":"AUDIO",
"chip_erase_timeout":30,
"commands":{

View File

@@ -1203,6 +1203,11 @@ class GbxDevice:
# Reverse sectors if requested
if reverse_sectors: flashcart_meta['sector_size'].reverse()
# Firmware check R20+
if (int(self.FW[0]) < 20) and self.MODE == "AGB" and "buffer_write" in flashcart_meta["commands"] and flashcart_meta["commands"]["buffer_write"] == [[0xAAA, 0xAA], [0x555, 0x55], ['SA', 0x25], ['SA', 'BS'], ['PA', 'PD'], ['SA', 0x29]]:
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"A firmware update is required to write to this cartridge. Please update the firmware of your GBxCart RW device to version R20 or higher.", "abortable":False})
return False
# Firmware check R20+
# Firmware check R23+
if (int(self.FW[0]) < 23) and self.MODE == "AGB" and "buffer_write" in flashcart_meta["commands"] and flashcart_meta["commands"]["buffer_write"] == [[0xAAA, 0xA9], [0x555, 0x56], ['SA', 0x26], ['SA', 'BS'], ['PA', 'PD'], ['SA', 0x2A]]:
print("NOTE: Update your GBxCart RW firmware to version R23 or higher for a better transfer rate with this cartridge.")

Binary file not shown.

View File

@@ -36,6 +36,7 @@ by Lesserkuma
- insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM *(thanks AlexiG)*
- insideGadgets 4 MB, 128 KB SRAM/FRAM *(thanks AlexiG)*
- insideGadgets 4 MB, 32 KB FRAM, MBC3+RTC *(thanks AlexiG)*
- Mr Flash 64M
- Game Boy Advance
@@ -242,3 +243,8 @@ The author would like to thank the following very kind people for their help and
- Added support for BX2006_TSOPBGA_0106 with K8D6316UTM-PI07 *(thanks LucentW)*
- Added support for the currently available insideGadgets Game Boy Advance flash cartridges *(thanks AlexiG)*
- Added a Game Boy Camera (Pocket Camera) album viewer and picture extractor
### v1.0 (released 2021-01-01)
- Added a firmware check when writing to insideGadgets Game Boy Advance flash cartridges (requires GBxCart RW firmware R20 or higher)
- Confirmed support for Mr Flash 64M (rebranded BUNG Doctor GB Card 64M)
- Fixed a problem with writing to the insideGadgets 512 KB Game Boy flash cartridge

View File

@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read(
setuptools.setup(
name="FlashGBX",
version="0.10",
version="1.0",
author="Lesserkuma",
description="A GUI application that can read and write Game Boy and Game Boy Advance cartridge data. Currently supports the GBxCart RW hardware device by insideGadgets.",
url="https://github.com/lesserkuma/FlashGBX",