FlashGBX 4.2__py3-none-any.whl → 4.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- FlashGBX/DataTransfer.py +1 -2
- FlashGBX/FlashGBX.py +1 -1
- FlashGBX/FlashGBX_CLI.py +16 -12
- FlashGBX/FlashGBX_GUI.py +167 -81
- FlashGBX/Flashcart.py +1 -0
- FlashGBX/LK_Device.py +192 -68
- FlashGBX/Mapper.py +42 -3
- FlashGBX/PocketCamera.py +2 -2
- FlashGBX/PocketCameraWindow.py +4 -4
- FlashGBX/RomFileDMG.py +6 -0
- FlashGBX/Util.py +58 -10
- FlashGBX/fw_GBFlash.py +0 -5
- FlashGBX/fw_GBxCartRW_v1_4.py +2 -5
- FlashGBX/fw_JoeyJr.py +15 -7
- FlashGBX/hw_GBFlash.py +15 -6
- FlashGBX/hw_GBxCartRW.py +4 -2
- FlashGBX/res/Third Party Notices.md +21 -1
- FlashGBX/res/config.zip +0 -0
- FlashGBX/res/fw_GBFlash.zip +0 -0
- {FlashGBX-4.2.dist-info → FlashGBX-4.3.dist-info}/METADATA +32 -22
- FlashGBX-4.3.dist-info/RECORD +43 -0
- FlashGBX-4.2.dist-info/RECORD +0 -43
- {FlashGBX-4.2.dist-info → FlashGBX-4.3.dist-info}/LICENSE +0 -0
- {FlashGBX-4.2.dist-info → FlashGBX-4.3.dist-info}/WHEEL +0 -0
- {FlashGBX-4.2.dist-info → FlashGBX-4.3.dist-info}/entry_points.txt +0 -0
- {FlashGBX-4.2.dist-info → FlashGBX-4.3.dist-info}/top_level.txt +0 -0
FlashGBX/FlashGBX_GUI.py
CHANGED
|
@@ -30,6 +30,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
30
30
|
TEXT_COLOR = (0, 0, 0, 255)
|
|
31
31
|
|
|
32
32
|
def __init__(self, args):
|
|
33
|
+
sys.excepthook = Util.exception_hook
|
|
34
|
+
|
|
33
35
|
QtWidgets.QWidget.__init__(self)
|
|
34
36
|
Util.CONFIG_PATH = args['config_path']
|
|
35
37
|
Util.APP_PATH = args['app_path']
|
|
@@ -314,7 +316,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
314
316
|
self.lblDMGGameNameResult = QtWidgets.QLabel("")
|
|
315
317
|
rowDMGGameName.addWidget(self.lblDMGGameNameResult)
|
|
316
318
|
rowDMGGameName.setStretch(0, 9)
|
|
317
|
-
rowDMGGameName.setStretch(1,
|
|
319
|
+
rowDMGGameName.setStretch(1, 12)
|
|
318
320
|
group_layout.addLayout(rowDMGGameName)
|
|
319
321
|
|
|
320
322
|
rowDMGRomTitle = QtWidgets.QHBoxLayout()
|
|
@@ -324,7 +326,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
324
326
|
self.lblDMGRomTitleResult = QtWidgets.QLabel("")
|
|
325
327
|
rowDMGRomTitle.addWidget(self.lblDMGRomTitleResult)
|
|
326
328
|
rowDMGRomTitle.setStretch(0, 9)
|
|
327
|
-
rowDMGRomTitle.setStretch(1,
|
|
329
|
+
rowDMGRomTitle.setStretch(1, 12)
|
|
328
330
|
group_layout.addLayout(rowDMGRomTitle)
|
|
329
331
|
|
|
330
332
|
rowDMGGameCodeRevision = QtWidgets.QHBoxLayout()
|
|
@@ -334,7 +336,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
334
336
|
self.lblDMGGameCodeRevisionResult = QtWidgets.QLabel("")
|
|
335
337
|
rowDMGGameCodeRevision.addWidget(self.lblDMGGameCodeRevisionResult)
|
|
336
338
|
rowDMGGameCodeRevision.setStretch(0, 9)
|
|
337
|
-
rowDMGGameCodeRevision.setStretch(1,
|
|
339
|
+
rowDMGGameCodeRevision.setStretch(1, 12)
|
|
338
340
|
group_layout.addLayout(rowDMGGameCodeRevision)
|
|
339
341
|
|
|
340
342
|
rowDMGHeaderRtc = QtWidgets.QHBoxLayout()
|
|
@@ -345,7 +347,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
345
347
|
self.lblDMGHeaderRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
346
348
|
rowDMGHeaderRtc.addWidget(self.lblDMGHeaderRtcResult)
|
|
347
349
|
rowDMGHeaderRtc.setStretch(0, 9)
|
|
348
|
-
rowDMGHeaderRtc.setStretch(1,
|
|
350
|
+
rowDMGHeaderRtc.setStretch(1, 12)
|
|
349
351
|
group_layout.addLayout(rowDMGHeaderRtc)
|
|
350
352
|
|
|
351
353
|
rowDMGHeaderBootlogo = QtWidgets.QHBoxLayout()
|
|
@@ -355,7 +357,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
355
357
|
self.lblDMGHeaderBootlogoResult = QtWidgets.QLabel("")
|
|
356
358
|
rowDMGHeaderBootlogo.addWidget(self.lblDMGHeaderBootlogoResult)
|
|
357
359
|
rowDMGHeaderBootlogo.setStretch(0, 9)
|
|
358
|
-
rowDMGHeaderBootlogo.setStretch(1,
|
|
360
|
+
rowDMGHeaderBootlogo.setStretch(1, 12)
|
|
359
361
|
group_layout.addLayout(rowDMGHeaderBootlogo)
|
|
360
362
|
|
|
361
363
|
rowDMGHeaderROMChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -365,7 +367,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
365
367
|
self.lblDMGHeaderROMChecksumResult = QtWidgets.QLabel("")
|
|
366
368
|
rowDMGHeaderROMChecksum.addWidget(self.lblDMGHeaderROMChecksumResult)
|
|
367
369
|
rowDMGHeaderROMChecksum.setStretch(0, 9)
|
|
368
|
-
rowDMGHeaderROMChecksum.setStretch(1,
|
|
370
|
+
rowDMGHeaderROMChecksum.setStretch(1, 12)
|
|
369
371
|
group_layout.addLayout(rowDMGHeaderROMChecksum)
|
|
370
372
|
|
|
371
373
|
rowDMGHeaderROMSize = QtWidgets.QHBoxLayout()
|
|
@@ -376,7 +378,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
376
378
|
self.cmbDMGHeaderROMSizeResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
377
379
|
rowDMGHeaderROMSize.addWidget(self.cmbDMGHeaderROMSizeResult)
|
|
378
380
|
rowDMGHeaderROMSize.setStretch(0, 9)
|
|
379
|
-
rowDMGHeaderROMSize.setStretch(1,
|
|
381
|
+
rowDMGHeaderROMSize.setStretch(1, 12)
|
|
380
382
|
group_layout.addLayout(rowDMGHeaderROMSize)
|
|
381
383
|
|
|
382
384
|
rowDMGHeaderSaveType = QtWidgets.QHBoxLayout()
|
|
@@ -387,7 +389,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
387
389
|
self.cmbDMGHeaderSaveTypeResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
388
390
|
rowDMGHeaderSaveType.addWidget(self.cmbDMGHeaderSaveTypeResult)
|
|
389
391
|
rowDMGHeaderSaveType.setStretch(0, 9)
|
|
390
|
-
rowDMGHeaderSaveType.setStretch(1,
|
|
392
|
+
rowDMGHeaderSaveType.setStretch(1, 12)
|
|
391
393
|
group_layout.addLayout(rowDMGHeaderSaveType)
|
|
392
394
|
|
|
393
395
|
rowDMGHeaderMapper = QtWidgets.QHBoxLayout()
|
|
@@ -398,7 +400,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
398
400
|
self.cmbDMGHeaderMapperResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
399
401
|
rowDMGHeaderMapper.addWidget(self.cmbDMGHeaderMapperResult)
|
|
400
402
|
rowDMGHeaderMapper.setStretch(0, 9)
|
|
401
|
-
rowDMGHeaderMapper.setStretch(1,
|
|
403
|
+
rowDMGHeaderMapper.setStretch(1, 12)
|
|
402
404
|
group_layout.addLayout(rowDMGHeaderMapper)
|
|
403
405
|
|
|
404
406
|
rowDMGCartridgeType = QtWidgets.QHBoxLayout()
|
|
@@ -428,7 +430,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
428
430
|
self.lblAGBGameNameResult = QtWidgets.QLabel("")
|
|
429
431
|
rowAGBGameName.addWidget(self.lblAGBGameNameResult)
|
|
430
432
|
rowAGBGameName.setStretch(0, 9)
|
|
431
|
-
rowAGBGameName.setStretch(1,
|
|
433
|
+
rowAGBGameName.setStretch(1, 12)
|
|
432
434
|
group_layout.addLayout(rowAGBGameName)
|
|
433
435
|
|
|
434
436
|
rowAGBRomTitle = QtWidgets.QHBoxLayout()
|
|
@@ -438,7 +440,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
438
440
|
self.lblAGBRomTitleResult = QtWidgets.QLabel("")
|
|
439
441
|
rowAGBRomTitle.addWidget(self.lblAGBRomTitleResult)
|
|
440
442
|
rowAGBRomTitle.setStretch(0, 9)
|
|
441
|
-
rowAGBRomTitle.setStretch(1,
|
|
443
|
+
rowAGBRomTitle.setStretch(1, 12)
|
|
442
444
|
group_layout.addLayout(rowAGBRomTitle)
|
|
443
445
|
|
|
444
446
|
rowAGBHeaderGameCodeRevision = QtWidgets.QHBoxLayout()
|
|
@@ -448,7 +450,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
448
450
|
self.lblAGBHeaderGameCodeRevisionResult = QtWidgets.QLabel("")
|
|
449
451
|
rowAGBHeaderGameCodeRevision.addWidget(self.lblAGBHeaderGameCodeRevisionResult)
|
|
450
452
|
rowAGBHeaderGameCodeRevision.setStretch(0, 9)
|
|
451
|
-
rowAGBHeaderGameCodeRevision.setStretch(1,
|
|
453
|
+
rowAGBHeaderGameCodeRevision.setStretch(1, 12)
|
|
452
454
|
group_layout.addLayout(rowAGBHeaderGameCodeRevision)
|
|
453
455
|
|
|
454
456
|
rowAGBGpioRtc = QtWidgets.QHBoxLayout()
|
|
@@ -459,7 +461,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
459
461
|
self.lblAGBGpioRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
460
462
|
rowAGBGpioRtc.addWidget(self.lblAGBGpioRtcResult)
|
|
461
463
|
rowAGBGpioRtc.setStretch(0, 9)
|
|
462
|
-
rowAGBGpioRtc.setStretch(1,
|
|
464
|
+
rowAGBGpioRtc.setStretch(1, 12)
|
|
463
465
|
group_layout.addLayout(rowAGBGpioRtc)
|
|
464
466
|
|
|
465
467
|
rowAGBHeaderBootlogo = QtWidgets.QHBoxLayout()
|
|
@@ -469,7 +471,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
469
471
|
self.lblAGBHeaderBootlogoResult = QtWidgets.QLabel("")
|
|
470
472
|
rowAGBHeaderBootlogo.addWidget(self.lblAGBHeaderBootlogoResult)
|
|
471
473
|
rowAGBHeaderBootlogo.setStretch(0, 9)
|
|
472
|
-
rowAGBHeaderBootlogo.setStretch(1,
|
|
474
|
+
rowAGBHeaderBootlogo.setStretch(1, 12)
|
|
473
475
|
group_layout.addLayout(rowAGBHeaderBootlogo)
|
|
474
476
|
|
|
475
477
|
rowAGBHeaderChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -479,7 +481,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
479
481
|
self.lblAGBHeaderChecksumResult = QtWidgets.QLabel("")
|
|
480
482
|
rowAGBHeaderChecksum.addWidget(self.lblAGBHeaderChecksumResult)
|
|
481
483
|
rowAGBHeaderChecksum.setStretch(0, 9)
|
|
482
|
-
rowAGBHeaderChecksum.setStretch(1,
|
|
484
|
+
rowAGBHeaderChecksum.setStretch(1, 12)
|
|
483
485
|
group_layout.addLayout(rowAGBHeaderChecksum)
|
|
484
486
|
|
|
485
487
|
rowAGBHeaderROMChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -489,7 +491,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
489
491
|
self.lblAGBHeaderROMChecksumResult = QtWidgets.QLabel("")
|
|
490
492
|
rowAGBHeaderROMChecksum.addWidget(self.lblAGBHeaderROMChecksumResult)
|
|
491
493
|
rowAGBHeaderROMChecksum.setStretch(0, 9)
|
|
492
|
-
rowAGBHeaderROMChecksum.setStretch(1,
|
|
494
|
+
rowAGBHeaderROMChecksum.setStretch(1, 12)
|
|
493
495
|
group_layout.addLayout(rowAGBHeaderROMChecksum)
|
|
494
496
|
|
|
495
497
|
rowAGBHeaderROMSize = QtWidgets.QHBoxLayout()
|
|
@@ -502,7 +504,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
502
504
|
self.cmbAGBHeaderROMSizeResult.setCurrentIndex(self.cmbAGBHeaderROMSizeResult.count() - 1)
|
|
503
505
|
rowAGBHeaderROMSize.addWidget(self.cmbAGBHeaderROMSizeResult)
|
|
504
506
|
rowAGBHeaderROMSize.setStretch(0, 9)
|
|
505
|
-
rowAGBHeaderROMSize.setStretch(1,
|
|
507
|
+
rowAGBHeaderROMSize.setStretch(1, 12)
|
|
506
508
|
group_layout.addLayout(rowAGBHeaderROMSize)
|
|
507
509
|
|
|
508
510
|
rowAGBHeaderSaveType = QtWidgets.QHBoxLayout()
|
|
@@ -515,7 +517,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
515
517
|
self.cmbAGBSaveTypeResult.setCurrentIndex(self.cmbAGBSaveTypeResult.count() - 1)
|
|
516
518
|
rowAGBHeaderSaveType.addWidget(self.cmbAGBSaveTypeResult)
|
|
517
519
|
rowAGBHeaderSaveType.setStretch(0, 9)
|
|
518
|
-
rowAGBHeaderSaveType.setStretch(1,
|
|
520
|
+
rowAGBHeaderSaveType.setStretch(1, 12)
|
|
519
521
|
group_layout.addLayout(rowAGBHeaderSaveType)
|
|
520
522
|
|
|
521
523
|
rowAGBCartridgeType = QtWidgets.QHBoxLayout()
|
|
@@ -716,7 +718,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
716
718
|
def AboutGameDB(self):
|
|
717
719
|
msg = f"{APPNAME} uses a game database that is based on the ongoing efforts of the No-Intro project. Visit <a href=\"https://no-intro.org/\">https://no-intro.org/</a> for more information.<br><br>"
|
|
718
720
|
msg += f"No-Intro databases referenced for this version of {APPNAME}:<br>"
|
|
719
|
-
msg += "• Nintendo - Game Boy (
|
|
721
|
+
msg += "• Nintendo - Game Boy (20241003-140822)<br>• Nintendo - Game Boy Advance (20241102-092521)<br>• Nintendo - Game Boy Advance (Video) (20241021-195439)<br>• Nintendo - Game Boy Color (20241105-004534)" # No-Intro DBs
|
|
720
722
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
721
723
|
|
|
722
724
|
def OpenPath(self, path=None):
|
|
@@ -740,26 +742,19 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
740
742
|
if isinstance(event, QtGui.QMouseEvent):
|
|
741
743
|
if event.button() in (QtCore.Qt.MouseButton.MiddleButton, QtCore.Qt.MouseButton.RightButton): return
|
|
742
744
|
|
|
745
|
+
device = False
|
|
743
746
|
try:
|
|
744
|
-
|
|
745
|
-
Util.dprint("Platform: {:s}".format(platform.platform()))
|
|
746
|
-
if self.CONN is not None:
|
|
747
|
-
Util.dprint("Connected device: {:s}".format(self.CONN.GetFullNameExtended(more=True)))
|
|
748
|
-
else:
|
|
749
|
-
Util.dprint("No device connected")
|
|
750
|
-
Util.dprint("Now writing debug log file")
|
|
747
|
+
device = self.CONN.GetFullNameExtended(more=True)
|
|
751
748
|
except:
|
|
752
749
|
pass
|
|
750
|
+
|
|
751
|
+
Util.write_debug_log(device)
|
|
753
752
|
try:
|
|
754
|
-
fn = Util.CONFIG_PATH + "/debug.log"
|
|
755
|
-
with open(fn, "wb") as f:
|
|
756
|
-
f.write("\n".join(Util.DEBUG_LOG).encode("UTF-8-SIG"))
|
|
757
|
-
print("debug.log written")
|
|
758
753
|
if open_log is True:
|
|
754
|
+
fn = Util.CONFIG_PATH + "/debug.log"
|
|
759
755
|
self.OpenPath(fn)
|
|
760
|
-
return True
|
|
761
756
|
except:
|
|
762
|
-
|
|
757
|
+
pass
|
|
763
758
|
|
|
764
759
|
def ConnectDevice(self):
|
|
765
760
|
if self.CONN is not None:
|
|
@@ -872,6 +867,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
872
867
|
if dev.FirmwareUpdateAvailable():
|
|
873
868
|
dontShowAgain = str(self.SETTINGS.value("SkipFirmwareUpdate", default="disabled")).lower() == "enabled"
|
|
874
869
|
if not dontShowAgain or dev.FW_UPDATE_REQ:
|
|
870
|
+
cb = None
|
|
875
871
|
if dev.FW_UPDATE_REQ is True:
|
|
876
872
|
text = "A firmware update for your {:s} device is required to use this software. Do you want to update now?".format(dev.GetFullName())
|
|
877
873
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=text, standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
|
|
@@ -889,8 +885,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
889
885
|
if not Util.DEBUG:
|
|
890
886
|
self.DisconnectDevice()
|
|
891
887
|
else:
|
|
892
|
-
|
|
893
|
-
|
|
888
|
+
if cb is not None:
|
|
889
|
+
dontShowAgain = cb.isChecked()
|
|
890
|
+
if dontShowAgain: self.SETTINGS.setValue("SkipFirmwareUpdate", "enabled")
|
|
894
891
|
if answer == QtWidgets.QMessageBox.Yes:
|
|
895
892
|
self.ShowFirmwareUpdateWindow()
|
|
896
893
|
|
|
@@ -899,8 +896,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
899
896
|
if not Util.DEBUG:
|
|
900
897
|
self.DisconnectDevice()
|
|
901
898
|
QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), text, QtWidgets.QMessageBox.Ok)
|
|
899
|
+
|
|
900
|
+
if dev.IsUnregistered():
|
|
901
|
+
try:
|
|
902
|
+
text = dev.GetRegisterInformation()
|
|
903
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), text, QtWidgets.QMessageBox.Ok)
|
|
904
|
+
except:
|
|
905
|
+
pass
|
|
902
906
|
|
|
903
907
|
return True
|
|
908
|
+
|
|
904
909
|
return False
|
|
905
910
|
|
|
906
911
|
def FindDevices(self, connectToFirst=False, port=None, mode=None, firstRun=False):
|
|
@@ -959,7 +964,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
959
964
|
msg += message + "\n\n"
|
|
960
965
|
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), msg[:-2], QtWidgets.QMessageBox.Ok)
|
|
961
966
|
elif not firstRun:
|
|
962
|
-
QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="No compatible devices found. Please ensure the device is connected properly.\n\nTroubleshooting advice:\n- Reconnect the device, try different USB ports/cables, avoid passive USB hubs\n- Use a USB data cable (battery charging cables may not work)\n- Check if the operating system detects the device (if not, reboot your machine)\n- Ensure your user account has permissions to use the device\n- Refer to the device compatibility list on the <a href=\"https://github.com/lesserkuma/FlashGBX/#compatible-cartridge-readerwriter-hardware\">GitHub page</a
|
|
967
|
+
QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="No compatible devices found. Please ensure the device is connected properly.\n\nTroubleshooting advice:\n- Reconnect the device, try different USB ports/cables, avoid passive USB hubs\n- Use a USB data cable (battery charging cables may not work)\n- Check if the operating system detects the device (if not, reboot your machine)\n- Ensure your user account has permissions to use the device\n- Refer to the device compatibility list on the <a href=\"https://github.com/lesserkuma/FlashGBX/#compatible-cartridge-readerwriter-hardware\">GitHub page</a>\n- Update the firmware manually through Options → Tools → Firmware Updater".replace("\n", "<br>"), standardButtons=QtWidgets.QMessageBox.Ok).exec()
|
|
963
968
|
|
|
964
969
|
self.lblDevice.setText("No devices found.")
|
|
965
970
|
self.lblDevice.setStyleSheet("")
|
|
@@ -1080,7 +1085,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1080
1085
|
else:
|
|
1081
1086
|
msg += " This may indicate a bad dump, however this can be normal for some reproduction cartridges, unlicensed games, prototypes, patched games and intentional overdumps. You can also try to change the read mode in the options."
|
|
1082
1087
|
if self.CONN.GetMode() == "DMG" and self.cmbDMGHeaderMapperResult.currentText() == "MBC1":
|
|
1083
|
-
msg += "\n\nIf this is a NP GB-Memory Cartridge,
|
|
1088
|
+
msg += "\n\nIf this is a NP GB-Memory Cartridge, try the “Retry as G-MMC1” option."
|
|
1084
1089
|
button_gmmc1 = msgbox.addButton(" Retry as G-MMC1 ", QtWidgets.QMessageBox.ActionRole)
|
|
1085
1090
|
msgbox.setText(msg + msg_te)
|
|
1086
1091
|
msgbox.setIcon(QtWidgets.QMessageBox.Warning)
|
|
@@ -1244,6 +1249,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1244
1249
|
self.CONN.INFO["dump_info"]["batteryless_sram"] = temp3
|
|
1245
1250
|
else:
|
|
1246
1251
|
self.ReadCartridge(resetStatus=False)
|
|
1252
|
+
|
|
1253
|
+
elif self.CONN.INFO["last_action"] == 6: # Detect Cartridge
|
|
1254
|
+
self.lblStatus4a.setText("Ready.")
|
|
1255
|
+
self.CONN.INFO["last_action"] = 0
|
|
1256
|
+
self.FinishDetectCartridge(self.CONN.INFO["detect_cart"])
|
|
1247
1257
|
|
|
1248
1258
|
else:
|
|
1249
1259
|
self.lblStatus4a.setText("Ready.")
|
|
@@ -1375,11 +1385,20 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1375
1385
|
return
|
|
1376
1386
|
|
|
1377
1387
|
if cart_type == 0:
|
|
1378
|
-
|
|
1388
|
+
if "detected_cart_type" not in self.STATUS: self.STATUS["detected_cart_type"] = ""
|
|
1389
|
+
if self.STATUS["detected_cart_type"] == "":
|
|
1390
|
+
self.STATUS["detected_cart_type"] = "WAITING_FLASH"
|
|
1391
|
+
self.STATUS["detect_cartridge_args"] = { "dpath":path }
|
|
1392
|
+
self.STATUS["can_skip_message"] = True
|
|
1393
|
+
self.DetectCartridge(checkSaveType=False)
|
|
1394
|
+
return
|
|
1395
|
+
cart_type = self.STATUS["detected_cart_type"]
|
|
1396
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1397
|
+
|
|
1379
1398
|
if cart_type is False: # clicked Cancel button
|
|
1380
1399
|
return
|
|
1381
1400
|
elif cart_type is None or cart_type == 0:
|
|
1382
|
-
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge
|
|
1401
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge profile could not be auto-detected.", QtWidgets.QMessageBox.Ok)
|
|
1383
1402
|
return
|
|
1384
1403
|
|
|
1385
1404
|
if self.CONN.GetMode() == "DMG":
|
|
@@ -1387,6 +1406,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1387
1406
|
elif self.CONN.GetMode() == "AGB":
|
|
1388
1407
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
1389
1408
|
|
|
1409
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1410
|
+
|
|
1390
1411
|
if self.CONN.GetMode() == "DMG":
|
|
1391
1412
|
self.SetDMGMapperResult(carts[cart_type])
|
|
1392
1413
|
mbc = Util.ConvertMapperTypeToMapper(self.cmbDMGHeaderMapperResult.currentIndex())
|
|
@@ -1467,7 +1488,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1467
1488
|
if not Util.compare_mbc(hdr["mapper_raw"], mbc):
|
|
1468
1489
|
mbc1 = Util.get_mbc_name(mbc)
|
|
1469
1490
|
mbc2 = Util.get_mbc_name(hdr["mapper_raw"])
|
|
1470
|
-
compatible_mbc = [ "None", "MBC2", "MBC3", "MBC30", "MBC5", "MBC7", "MAC-GBD", "G-MMC1", "HuC-1", "HuC-3" ]
|
|
1491
|
+
compatible_mbc = [ "None", "MBC2", "MBC3", "MBC30", "MBC5", "MBC7", "MAC-GBD", "G-MMC1", "HuC-1", "HuC-3", "Unlicensed MBCX Mapper" ]
|
|
1471
1492
|
if (mbc2 == "None") or (mbc1 == "G-MMC1" and mbc2 == "MBC1") or (mbc2 == "G-MMC1" and mbc1 == "MBC1"):
|
|
1472
1493
|
pass
|
|
1473
1494
|
elif mbc2 != "None" and not (mbc1 in compatible_mbc and mbc2 in compatible_mbc):
|
|
@@ -1640,14 +1661,25 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1640
1661
|
return
|
|
1641
1662
|
cart_type = self.cmbAGBCartridgeTypeResult.currentIndex()
|
|
1642
1663
|
if cart_type == 0 or ("dump_info" not in self.CONN.INFO or "batteryless_sram" not in self.CONN.INFO["dump_info"]):
|
|
1643
|
-
|
|
1664
|
+
if "detected_cart_type" not in self.STATUS: self.STATUS["detected_cart_type"] = ""
|
|
1665
|
+
if self.STATUS["detected_cart_type"] == "":
|
|
1666
|
+
self.STATUS["detected_cart_type"] = "WAITING_SAVE_READ"
|
|
1667
|
+
self.STATUS["detect_cartridge_args"] = { "dpath":path }
|
|
1668
|
+
self.STATUS["can_skip_message"] = True
|
|
1669
|
+
self.DetectCartridge(checkSaveType=True)
|
|
1670
|
+
return
|
|
1671
|
+
cart_type = self.STATUS["detected_cart_type"]
|
|
1672
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1673
|
+
|
|
1644
1674
|
if cart_type is False: # clicked Cancel button
|
|
1645
1675
|
return
|
|
1646
1676
|
elif cart_type is None or cart_type == 0:
|
|
1647
|
-
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge
|
|
1677
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge profile could not be auto-detected.", QtWidgets.QMessageBox.Ok)
|
|
1648
1678
|
return
|
|
1649
1679
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
1650
1680
|
|
|
1681
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1682
|
+
|
|
1651
1683
|
if "dump_info" in self.CONN.INFO and "batteryless_sram" in self.CONN.INFO["dump_info"]:
|
|
1652
1684
|
detected = self.CONN.INFO["dump_info"]["batteryless_sram"]
|
|
1653
1685
|
else:
|
|
@@ -1678,10 +1710,12 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1678
1710
|
self.STATUS["last_path"] = path
|
|
1679
1711
|
self.STATUS["args"] = args
|
|
1680
1712
|
|
|
1681
|
-
def WriteRAM(self, dpath="", erase=False, test=False):
|
|
1713
|
+
def WriteRAM(self, dpath="", erase=False, test=False, skip_warning=False):
|
|
1682
1714
|
if not self.CheckDeviceAlive(): return
|
|
1683
1715
|
mode = self.CONN.GetMode()
|
|
1684
1716
|
|
|
1717
|
+
if erase is True: dpath = ""
|
|
1718
|
+
|
|
1685
1719
|
if dpath == "":
|
|
1686
1720
|
path = Util.GenerateFileName(mode=mode, header=self.CONN.INFO, settings=self.SETTINGS)
|
|
1687
1721
|
path = os.path.splitext(path)[0]
|
|
@@ -1716,14 +1750,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1716
1750
|
|
|
1717
1751
|
filesize = 0
|
|
1718
1752
|
if dpath != "":
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1753
|
+
if not skip_warning:
|
|
1754
|
+
text = "The following save data file will now be written to the cartridge:\n" + dpath
|
|
1755
|
+
answer = QtWidgets.QMessageBox.question(self, "{:s} {:s}".format(APPNAME, VERSION), text, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
|
|
1756
|
+
if answer == QtWidgets.QMessageBox.Cancel: return
|
|
1722
1757
|
path = dpath
|
|
1723
1758
|
self.SETTINGS.setValue(setting_name, os.path.dirname(path))
|
|
1724
1759
|
elif erase:
|
|
1725
|
-
|
|
1726
|
-
|
|
1760
|
+
if not skip_warning:
|
|
1761
|
+
answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "The save data on your cartridge will now be erased.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
|
|
1762
|
+
if answer == QtWidgets.QMessageBox.Cancel: return
|
|
1727
1763
|
elif test:
|
|
1728
1764
|
path = None
|
|
1729
1765
|
if self.CONN.GetFWBuildDate() == "": # Legacy Mode
|
|
@@ -2020,14 +2056,25 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2020
2056
|
return
|
|
2021
2057
|
cart_type = self.cmbAGBCartridgeTypeResult.currentIndex()
|
|
2022
2058
|
if cart_type == 0 or ("dump_info" not in self.CONN.INFO or "batteryless_sram" not in self.CONN.INFO["dump_info"]):
|
|
2023
|
-
|
|
2059
|
+
if "detected_cart_type" not in self.STATUS: self.STATUS["detected_cart_type"] = ""
|
|
2060
|
+
if self.STATUS["detected_cart_type"] == "":
|
|
2061
|
+
self.STATUS["detected_cart_type"] = "WAITING_SAVE_WRITE"
|
|
2062
|
+
self.STATUS["detect_cartridge_args"] = { "dpath":path, "erase":erase }
|
|
2063
|
+
self.STATUS["can_skip_message"] = True
|
|
2064
|
+
self.DetectCartridge(checkSaveType=True)
|
|
2065
|
+
return
|
|
2066
|
+
cart_type = self.STATUS["detected_cart_type"]
|
|
2067
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
2068
|
+
|
|
2024
2069
|
if cart_type is False: # clicked Cancel button
|
|
2025
2070
|
return
|
|
2026
2071
|
elif cart_type is None or cart_type == 0:
|
|
2027
|
-
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge
|
|
2072
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "A compatible flash cartridge profile could not be auto-detected.", QtWidgets.QMessageBox.Ok)
|
|
2028
2073
|
return
|
|
2029
2074
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
2030
2075
|
|
|
2076
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
2077
|
+
|
|
2031
2078
|
if "dump_info" in self.CONN.INFO and "batteryless_sram" in self.CONN.INFO["dump_info"]:
|
|
2032
2079
|
detected = self.CONN.INFO["dump_info"]["batteryless_sram"]
|
|
2033
2080
|
else:
|
|
@@ -2087,6 +2134,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2087
2134
|
except:
|
|
2088
2135
|
pass
|
|
2089
2136
|
|
|
2137
|
+
intro_msg = ""
|
|
2090
2138
|
if detected is not False:
|
|
2091
2139
|
try:
|
|
2092
2140
|
loc_index = locs.index(detected["bl_offset"])
|
|
@@ -2154,7 +2202,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2154
2202
|
|
|
2155
2203
|
if self.CONN.GetMode() == "DMG":
|
|
2156
2204
|
mbc = Util.get_mbc_name(Util.ConvertMapperTypeToMapper(self.cmbDMGHeaderMapperResult.currentIndex()))
|
|
2157
|
-
if mbc in ("MBC3", "MBC30"):
|
|
2205
|
+
if mbc in ("MBC3", "MBC30", "Unlicensed MBCX Mapper"):
|
|
2158
2206
|
dlg_args = {
|
|
2159
2207
|
"title":"MBC3/MBC30 Real Time Clock Editor",
|
|
2160
2208
|
"intro":"Enter the number of days, hours, minutes and seconds that passed since the RTC initially started.\n\nPlease note that all values are internal values. The game may use these only as a relative reference.",
|
|
@@ -2379,10 +2427,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2379
2427
|
|
|
2380
2428
|
if not self.CheckDeviceAlive(setMode=setTo): return
|
|
2381
2429
|
|
|
2382
|
-
|
|
2383
|
-
self.
|
|
2384
|
-
|
|
2385
|
-
self.
|
|
2430
|
+
try:
|
|
2431
|
+
if self.optDMG.isChecked() and (mode == "AGB" or mode == None):
|
|
2432
|
+
self.CONN.SetMode("DMG")
|
|
2433
|
+
elif self.optAGB.isChecked() and (mode == "DMG" or mode == None):
|
|
2434
|
+
self.CONN.SetMode("AGB")
|
|
2435
|
+
except BrokenPipeError:
|
|
2436
|
+
msg = "Failed to turn on the cartridge power.\n\nAs a workaround, try to disable the \"Automatic cartridge power off\" setting and then hotplug the cartridge after clicking \"Refresh\"."
|
|
2437
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
2438
|
+
self.DisconnectDevice()
|
|
2439
|
+
return False
|
|
2386
2440
|
|
|
2387
2441
|
ok = self.ReadCartridge()
|
|
2388
2442
|
qt_app.processEvents()
|
|
@@ -2422,7 +2476,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2422
2476
|
return False
|
|
2423
2477
|
|
|
2424
2478
|
if self.CONN.CheckROMStable() is False and resetStatus:
|
|
2425
|
-
|
|
2479
|
+
try:
|
|
2480
|
+
if data != bytearray(data[0] * len(data)):
|
|
2481
|
+
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "The cartridge connection is unstable!\nPlease clean the cartridge pins, carefully realign the cartridge and then try again.", QtWidgets.QMessageBox.Ok)
|
|
2482
|
+
except:
|
|
2483
|
+
pass
|
|
2426
2484
|
|
|
2427
2485
|
if self.CONN.GetMode() == "DMG":
|
|
2428
2486
|
self.cmbDMGHeaderMapperResult.clear()
|
|
@@ -2447,7 +2505,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2447
2505
|
self.lblDMGGameCodeRevisionResult.setText("{:s}-{:s}".format(data["db"]["gc"], str(data["version"])))
|
|
2448
2506
|
temp = data["db"]["gn"]
|
|
2449
2507
|
self.lblDMGGameNameResult.setText(temp)
|
|
2450
|
-
while self.lblDMGGameNameResult.fontMetrics().boundingRect(self.lblDMGGameNameResult.text()).width() >
|
|
2508
|
+
while self.lblDMGGameNameResult.fontMetrics().boundingRect(self.lblDMGGameNameResult.text()).width() > 240:
|
|
2451
2509
|
temp = temp[:-1]
|
|
2452
2510
|
self.lblDMGGameNameResult.setText(temp + "…")
|
|
2453
2511
|
if temp != data["db"]["gn"]:
|
|
@@ -2569,7 +2627,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2569
2627
|
self.lblAGBHeaderGameCodeRevisionResult.setText("{:s}-{:s}".format(data["db"]["gc"], str(data["version"])))
|
|
2570
2628
|
temp = data["db"]["gn"]
|
|
2571
2629
|
self.lblAGBGameNameResult.setText(temp)
|
|
2572
|
-
while self.lblAGBGameNameResult.fontMetrics().boundingRect(self.lblAGBGameNameResult.text()).width() >
|
|
2630
|
+
while self.lblAGBGameNameResult.fontMetrics().boundingRect(self.lblAGBGameNameResult.text()).width() > 240:
|
|
2573
2631
|
temp = temp[:-1]
|
|
2574
2632
|
self.lblAGBGameNameResult.setText(temp + "…")
|
|
2575
2633
|
if temp != data["db"]["gn"]:
|
|
@@ -2680,13 +2738,12 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2680
2738
|
self.btnRestoreRAM.setEnabled(True)
|
|
2681
2739
|
self.btnHeaderRefresh.setFocus()
|
|
2682
2740
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
2683
|
-
self.lblStatus4a.setText("Ready.")
|
|
2684
2741
|
qt_app.processEvents()
|
|
2685
2742
|
|
|
2686
2743
|
if data['game_title'][:11] == "YJencrypted" and resetStatus:
|
|
2687
2744
|
QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "This cartridge may be protected against reading or writing a ROM. If you don’t want to risk this cartridge to render itself unusable, please do not try to write a new ROM to it.", QtWidgets.QMessageBox.Ok)
|
|
2688
2745
|
|
|
2689
|
-
def DetectCartridge(self,
|
|
2746
|
+
def DetectCartridge(self, checkSaveType=True):
|
|
2690
2747
|
if not self.CheckDeviceAlive(): return
|
|
2691
2748
|
if not self.CONN.CheckROMStable():
|
|
2692
2749
|
answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "The cartridge connection is unstable!\nPlease clean the cartridge pins, carefully realign the cartridge for best results.\n\nContinue anyway?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
|
|
@@ -2702,12 +2759,20 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2702
2759
|
self.lblStatus2aResult.setText("–")
|
|
2703
2760
|
self.lblStatus3aResult.setText("–")
|
|
2704
2761
|
self.lblStatus4aResult.setText("")
|
|
2705
|
-
self.lblStatus4a.setText("Analyzing Cartridge...")
|
|
2762
|
+
# self.lblStatus4a.setText("Analyzing Cartridge...")
|
|
2706
2763
|
self.SetProgressBars(min=0, max=0, value=1)
|
|
2707
2764
|
qt_app.processEvents()
|
|
2708
2765
|
|
|
2766
|
+
if "can_skip_message" not in self.STATUS: self.STATUS["can_skip_message"] = False
|
|
2767
|
+
limitVoltage = str(self.SETTINGS.value("AutoDetectLimitVoltage", default="disabled")).lower() == "enabled"
|
|
2768
|
+
self.CONN.DetectCartridge(fncSetProgress=self.PROGRESS.SetProgress, args={"limitVoltage":limitVoltage, "checkSaveType":checkSaveType})
|
|
2769
|
+
|
|
2770
|
+
def FinishDetectCartridge(self, ret):
|
|
2771
|
+
self.lblStatus1aResult.setText("–")
|
|
2772
|
+
self.lblStatus2aResult.setText("–")
|
|
2773
|
+
self.lblStatus3aResult.setText("–")
|
|
2774
|
+
|
|
2709
2775
|
limitVoltage = str(self.SETTINGS.value("AutoDetectLimitVoltage", default="disabled")).lower() == "enabled"
|
|
2710
|
-
ret = self.CONN.DetectCartridge(limitVoltage=limitVoltage, checkSaveType=not canSkipMessage)
|
|
2711
2776
|
if ret is False:
|
|
2712
2777
|
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "An error occured while trying to analyze the cartridge and you may need to physically reconnect the device.\n\nThis cartridge may not be auto-detectable, please select the cartridge type manually.", QtWidgets.QMessageBox.Ok)
|
|
2713
2778
|
self.DisconnectDevice()
|
|
@@ -2716,7 +2781,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2716
2781
|
(header, save_size, save_type, save_chip, sram_unstable, cart_types, cart_type_id, cfi_s, _, flash_id, detected_size) = ret
|
|
2717
2782
|
|
|
2718
2783
|
# Save Type
|
|
2719
|
-
if not
|
|
2784
|
+
if not self.STATUS["can_skip_message"]:
|
|
2720
2785
|
try:
|
|
2721
2786
|
if save_type is not None and save_type is not False:
|
|
2722
2787
|
if self.CONN.GetMode() == "DMG":
|
|
@@ -2735,6 +2800,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2735
2800
|
supp_cart_types = self.CONN.GetSupportedCartridgesDMG()
|
|
2736
2801
|
elif self.CONN.GetMode() == "AGB":
|
|
2737
2802
|
supp_cart_types = self.CONN.GetSupportedCartridgesAGB()
|
|
2803
|
+
else:
|
|
2804
|
+
raise NotImplementedError
|
|
2738
2805
|
except Exception as e:
|
|
2739
2806
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="An unknown error occured. Please try again.\n\n" + str(e), standardButtons=QtWidgets.QMessageBox.Ok)
|
|
2740
2807
|
msgbox.exec()
|
|
@@ -2768,7 +2835,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2768
2835
|
# Save Type
|
|
2769
2836
|
msg_save_type_s = ""
|
|
2770
2837
|
temp = ""
|
|
2771
|
-
if not
|
|
2838
|
+
if not self.STATUS["can_skip_message"] and save_type is not False and save_type is not None:
|
|
2772
2839
|
if save_chip is not None:
|
|
2773
2840
|
temp = "{:s} ({:s})".format(Util.AGB_Header_Save_Types[save_type], save_chip)
|
|
2774
2841
|
else:
|
|
@@ -2916,7 +2983,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2916
2983
|
msg = "The following cartridge configuration was detected:<br><br>"
|
|
2917
2984
|
if found_supported:
|
|
2918
2985
|
dontShowAgain = str(self.SETTINGS.value("SkipAutodetectMessage", default="disabled")).lower() == "enabled"
|
|
2919
|
-
if not dontShowAgain or not
|
|
2986
|
+
if not dontShowAgain or not self.STATUS["can_skip_message"]:
|
|
2920
2987
|
temp = "{:s}{:s}{:s}{:s}{:s}{:s}".format(msg, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_cart_type_s, msg_gbmem)
|
|
2921
2988
|
temp = temp[:-4]
|
|
2922
2989
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=temp)
|
|
@@ -2926,7 +2993,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2926
2993
|
button_cancel = None
|
|
2927
2994
|
msgbox.setDefaultButton(button_ok)
|
|
2928
2995
|
cb = QtWidgets.QCheckBox("Always skip this message", checked=False)
|
|
2929
|
-
if
|
|
2996
|
+
if self.STATUS["can_skip_message"]:
|
|
2930
2997
|
button_cancel = msgbox.addButton("&Cancel", QtWidgets.QMessageBox.RejectRole)
|
|
2931
2998
|
msgbox.setEscapeButton(button_cancel)
|
|
2932
2999
|
msgbox.setCheckBox(cb)
|
|
@@ -2935,7 +3002,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2935
3002
|
|
|
2936
3003
|
msgbox.exec()
|
|
2937
3004
|
dontShowAgain = cb.isChecked()
|
|
2938
|
-
if dontShowAgain and
|
|
3005
|
+
if dontShowAgain and self.STATUS["can_skip_message"]: self.SETTINGS.setValue("SkipAutodetectMessage", "enabled")
|
|
2939
3006
|
|
|
2940
3007
|
if msgbox.clickedButton() == button_details:
|
|
2941
3008
|
show_details = True
|
|
@@ -2950,7 +3017,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2950
3017
|
self.btnHeaderRefresh.setFocus()
|
|
2951
3018
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
2952
3019
|
self.lblStatus4a.setText("Ready.")
|
|
2953
|
-
|
|
3020
|
+
self.STATUS["can_skip_message"] = False
|
|
3021
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
3022
|
+
return
|
|
2954
3023
|
|
|
2955
3024
|
if not found_supported or show_details is True:
|
|
2956
3025
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="{:s} {:s}".format(APPNAME, VERSION))
|
|
@@ -2976,7 +3045,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2976
3045
|
if answer == QtWidgets.QMessageBox.Yes:
|
|
2977
3046
|
self.SETTINGS.setValue("AutoDetectLimitVoltage", "disabled")
|
|
2978
3047
|
self.mnuConfig.actions()[4].setChecked(False)
|
|
2979
|
-
|
|
3048
|
+
self.STATUS["can_skip_message"] = False
|
|
3049
|
+
self.DetectCartridge()
|
|
3050
|
+
return
|
|
2980
3051
|
|
|
2981
3052
|
temp = "{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}".format(msg, msg_header_s, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_flash_id_s, msg_cfi_s, msg_cart_type_s_detail, msg_gbmem, msg_fw)
|
|
2982
3053
|
temp = temp[:-4]
|
|
@@ -3006,7 +3077,27 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3006
3077
|
self.btnHeaderRefresh.setFocus()
|
|
3007
3078
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
3008
3079
|
self.lblStatus4a.setText("Ready.")
|
|
3009
|
-
|
|
3080
|
+
|
|
3081
|
+
waiting = None
|
|
3082
|
+
if "detected_cart_type" in self.STATUS and self.STATUS["detected_cart_type"] in ("WAITING_FLASH", "WAITING_SAVE_READ", "WAITING_SAVE_WRITE"):
|
|
3083
|
+
waiting = self.STATUS["detected_cart_type"]
|
|
3084
|
+
self.STATUS["detected_cart_type"] = cart_type
|
|
3085
|
+
self.STATUS["can_skip_message"] = False
|
|
3086
|
+
|
|
3087
|
+
if waiting == "WAITING_FLASH":
|
|
3088
|
+
if "detect_cartridge_args" in self.STATUS:
|
|
3089
|
+
self.FlashROM(dpath=self.STATUS["detect_cartridge_args"]["dpath"])
|
|
3090
|
+
del(self.STATUS["detect_cartridge_args"])
|
|
3091
|
+
else:
|
|
3092
|
+
self.FlashROM()
|
|
3093
|
+
elif waiting == "WAITING_SAVE_READ":
|
|
3094
|
+
self.BackupRAM()
|
|
3095
|
+
elif waiting == "WAITING_SAVE_WRITE":
|
|
3096
|
+
if "detect_cartridge_args" in self.STATUS:
|
|
3097
|
+
self.WriteRAM(dpath=self.STATUS["detect_cartridge_args"]["dpath"], erase=self.STATUS["detect_cartridge_args"]["erase"], skip_warning=True)
|
|
3098
|
+
del(self.STATUS["detect_cartridge_args"])
|
|
3099
|
+
else:
|
|
3100
|
+
self.WriteRAM()
|
|
3010
3101
|
|
|
3011
3102
|
def WaitProgress(self, args):
|
|
3012
3103
|
if args["user_action"] == "REINSERT_CART":
|
|
@@ -3037,6 +3128,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3037
3128
|
self.grpStatus.setTitle("Transfer Status (Write Save Data)")
|
|
3038
3129
|
elif args["method"] == "SAVE_WRITE_VERIFY":
|
|
3039
3130
|
self.grpStatus.setTitle("Transfer Status (Verify Save Data)")
|
|
3131
|
+
elif args["method"] == "DETECT_CART":
|
|
3132
|
+
self.grpStatus.setTitle("Transfer Status (Analyze Cartridge)")
|
|
3040
3133
|
|
|
3041
3134
|
if "error" in args:
|
|
3042
3135
|
self.lblStatus4a.setText("Failed!")
|
|
@@ -3120,6 +3213,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3120
3213
|
self.lblStatus4aResult.setText("")
|
|
3121
3214
|
self.btnCancel.setEnabled(args["abortable"])
|
|
3122
3215
|
self.SetProgressBars(min=0, max=size, value=pos)
|
|
3216
|
+
elif args["action"] == "UPDATE_INFO":
|
|
3217
|
+
self.lblStatus4a.setText(args["text"])
|
|
3218
|
+
self.lblStatus4aResult.setText("")
|
|
3219
|
+
self.btnCancel.setEnabled(args["abortable"])
|
|
3220
|
+
self.SetProgressBars(min=0, max=size, value=pos)
|
|
3123
3221
|
elif args["action"] == "FINISHED":
|
|
3124
3222
|
if pos > 0:
|
|
3125
3223
|
self.lblStatus1aResult.setText(Util.formatFileSize(size=pos))
|
|
@@ -3338,18 +3436,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3338
3436
|
except:
|
|
3339
3437
|
pass
|
|
3340
3438
|
qt_app.exec()
|
|
3341
|
-
# # Taskbar Progress on Windows only
|
|
3342
|
-
# try:
|
|
3343
|
-
# from PySide6.QtWin import QtWinTaskbarButton, QtWin
|
|
3344
|
-
# myappid = 'lesserkuma.flashgbx'
|
|
3345
|
-
# QtWin.setAppUserModelId(myappid)
|
|
3346
|
-
# taskbar_button = QtWinTaskbarButton()
|
|
3347
|
-
# self.TBPROG = taskbar_button.progress()
|
|
3348
|
-
# self.TBPROG.setRange(0, 100)
|
|
3349
|
-
# taskbar_button.setWindow(self.windowHandle())
|
|
3350
|
-
# self.TBPROG.setVisible(False)
|
|
3351
|
-
# except ImportError:
|
|
3352
|
-
# pass
|
|
3353
3439
|
|
|
3354
3440
|
else: # PySide2
|
|
3355
3441
|
qt_app.exec_()
|
FlashGBX/Flashcart.py
CHANGED
|
@@ -708,6 +708,7 @@ class Flashcart_DMG_BUNG_16M(Flashcart):
|
|
|
708
708
|
self.CartWrite([[0x2000, 0x02]], fast_write=False)
|
|
709
709
|
self.CartWrite([[0x6AAA, 0x90]], fast_write=True)
|
|
710
710
|
cart_flash_id = list(self.CartRead(0, 4))
|
|
711
|
+
verified = False
|
|
711
712
|
if rom != cart_flash_id and cart_flash_id == self.CONFIG["flash_ids"][0]:
|
|
712
713
|
self.Reset()
|
|
713
714
|
verified = True
|