FlashGBX 4.1__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 +177 -84
- FlashGBX/Flashcart.py +1 -0
- FlashGBX/LK_Device.py +194 -70
- 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 +7 -3
- FlashGBX/hw_JoeyJr.py +1 -1
- FlashGBX/res/Third Party Notices.md +21 -1
- FlashGBX/res/config.zip +0 -0
- FlashGBX/res/fw_GBFlash.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
- FlashGBX/res/fw_JoeyJr.zip +0 -0
- {FlashGBX-4.1.dist-info → FlashGBX-4.3.dist-info}/METADATA +32 -22
- FlashGBX-4.3.dist-info/RECORD +43 -0
- FlashGBX-4.1.dist-info/RECORD +0 -43
- {FlashGBX-4.1.dist-info → FlashGBX-4.3.dist-info}/LICENSE +0 -0
- {FlashGBX-4.1.dist-info → FlashGBX-4.3.dist-info}/WHEEL +0 -0
- {FlashGBX-4.1.dist-info → FlashGBX-4.3.dist-info}/entry_points.txt +0 -0
- {FlashGBX-4.1.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']
|
|
@@ -241,6 +243,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
241
243
|
|
|
242
244
|
self.mnuThirdParty = QtWidgets.QMenu("Third Party &Notices")
|
|
243
245
|
self.mnuThirdParty.addAction("About &Qt", lambda: [ QtWidgets.QMessageBox.aboutQt(None) ])
|
|
246
|
+
self.mnuThirdParty.addAction("About Game &Database", self.AboutGameDB)
|
|
244
247
|
self.mnuThirdParty.addAction("Licenses", lambda: [ self.OpenPath(Util.APP_PATH + "/res/Third Party Notices.md") ])
|
|
245
248
|
|
|
246
249
|
btnText = "&Options"
|
|
@@ -313,7 +316,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
313
316
|
self.lblDMGGameNameResult = QtWidgets.QLabel("")
|
|
314
317
|
rowDMGGameName.addWidget(self.lblDMGGameNameResult)
|
|
315
318
|
rowDMGGameName.setStretch(0, 9)
|
|
316
|
-
rowDMGGameName.setStretch(1,
|
|
319
|
+
rowDMGGameName.setStretch(1, 12)
|
|
317
320
|
group_layout.addLayout(rowDMGGameName)
|
|
318
321
|
|
|
319
322
|
rowDMGRomTitle = QtWidgets.QHBoxLayout()
|
|
@@ -323,7 +326,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
323
326
|
self.lblDMGRomTitleResult = QtWidgets.QLabel("")
|
|
324
327
|
rowDMGRomTitle.addWidget(self.lblDMGRomTitleResult)
|
|
325
328
|
rowDMGRomTitle.setStretch(0, 9)
|
|
326
|
-
rowDMGRomTitle.setStretch(1,
|
|
329
|
+
rowDMGRomTitle.setStretch(1, 12)
|
|
327
330
|
group_layout.addLayout(rowDMGRomTitle)
|
|
328
331
|
|
|
329
332
|
rowDMGGameCodeRevision = QtWidgets.QHBoxLayout()
|
|
@@ -333,7 +336,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
333
336
|
self.lblDMGGameCodeRevisionResult = QtWidgets.QLabel("")
|
|
334
337
|
rowDMGGameCodeRevision.addWidget(self.lblDMGGameCodeRevisionResult)
|
|
335
338
|
rowDMGGameCodeRevision.setStretch(0, 9)
|
|
336
|
-
rowDMGGameCodeRevision.setStretch(1,
|
|
339
|
+
rowDMGGameCodeRevision.setStretch(1, 12)
|
|
337
340
|
group_layout.addLayout(rowDMGGameCodeRevision)
|
|
338
341
|
|
|
339
342
|
rowDMGHeaderRtc = QtWidgets.QHBoxLayout()
|
|
@@ -344,7 +347,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
344
347
|
self.lblDMGHeaderRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
345
348
|
rowDMGHeaderRtc.addWidget(self.lblDMGHeaderRtcResult)
|
|
346
349
|
rowDMGHeaderRtc.setStretch(0, 9)
|
|
347
|
-
rowDMGHeaderRtc.setStretch(1,
|
|
350
|
+
rowDMGHeaderRtc.setStretch(1, 12)
|
|
348
351
|
group_layout.addLayout(rowDMGHeaderRtc)
|
|
349
352
|
|
|
350
353
|
rowDMGHeaderBootlogo = QtWidgets.QHBoxLayout()
|
|
@@ -354,7 +357,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
354
357
|
self.lblDMGHeaderBootlogoResult = QtWidgets.QLabel("")
|
|
355
358
|
rowDMGHeaderBootlogo.addWidget(self.lblDMGHeaderBootlogoResult)
|
|
356
359
|
rowDMGHeaderBootlogo.setStretch(0, 9)
|
|
357
|
-
rowDMGHeaderBootlogo.setStretch(1,
|
|
360
|
+
rowDMGHeaderBootlogo.setStretch(1, 12)
|
|
358
361
|
group_layout.addLayout(rowDMGHeaderBootlogo)
|
|
359
362
|
|
|
360
363
|
rowDMGHeaderROMChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -364,7 +367,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
364
367
|
self.lblDMGHeaderROMChecksumResult = QtWidgets.QLabel("")
|
|
365
368
|
rowDMGHeaderROMChecksum.addWidget(self.lblDMGHeaderROMChecksumResult)
|
|
366
369
|
rowDMGHeaderROMChecksum.setStretch(0, 9)
|
|
367
|
-
rowDMGHeaderROMChecksum.setStretch(1,
|
|
370
|
+
rowDMGHeaderROMChecksum.setStretch(1, 12)
|
|
368
371
|
group_layout.addLayout(rowDMGHeaderROMChecksum)
|
|
369
372
|
|
|
370
373
|
rowDMGHeaderROMSize = QtWidgets.QHBoxLayout()
|
|
@@ -375,7 +378,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
375
378
|
self.cmbDMGHeaderROMSizeResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
376
379
|
rowDMGHeaderROMSize.addWidget(self.cmbDMGHeaderROMSizeResult)
|
|
377
380
|
rowDMGHeaderROMSize.setStretch(0, 9)
|
|
378
|
-
rowDMGHeaderROMSize.setStretch(1,
|
|
381
|
+
rowDMGHeaderROMSize.setStretch(1, 12)
|
|
379
382
|
group_layout.addLayout(rowDMGHeaderROMSize)
|
|
380
383
|
|
|
381
384
|
rowDMGHeaderSaveType = QtWidgets.QHBoxLayout()
|
|
@@ -386,7 +389,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
386
389
|
self.cmbDMGHeaderSaveTypeResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
387
390
|
rowDMGHeaderSaveType.addWidget(self.cmbDMGHeaderSaveTypeResult)
|
|
388
391
|
rowDMGHeaderSaveType.setStretch(0, 9)
|
|
389
|
-
rowDMGHeaderSaveType.setStretch(1,
|
|
392
|
+
rowDMGHeaderSaveType.setStretch(1, 12)
|
|
390
393
|
group_layout.addLayout(rowDMGHeaderSaveType)
|
|
391
394
|
|
|
392
395
|
rowDMGHeaderMapper = QtWidgets.QHBoxLayout()
|
|
@@ -397,7 +400,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
397
400
|
self.cmbDMGHeaderMapperResult.view().setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
398
401
|
rowDMGHeaderMapper.addWidget(self.cmbDMGHeaderMapperResult)
|
|
399
402
|
rowDMGHeaderMapper.setStretch(0, 9)
|
|
400
|
-
rowDMGHeaderMapper.setStretch(1,
|
|
403
|
+
rowDMGHeaderMapper.setStretch(1, 12)
|
|
401
404
|
group_layout.addLayout(rowDMGHeaderMapper)
|
|
402
405
|
|
|
403
406
|
rowDMGCartridgeType = QtWidgets.QHBoxLayout()
|
|
@@ -427,7 +430,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
427
430
|
self.lblAGBGameNameResult = QtWidgets.QLabel("")
|
|
428
431
|
rowAGBGameName.addWidget(self.lblAGBGameNameResult)
|
|
429
432
|
rowAGBGameName.setStretch(0, 9)
|
|
430
|
-
rowAGBGameName.setStretch(1,
|
|
433
|
+
rowAGBGameName.setStretch(1, 12)
|
|
431
434
|
group_layout.addLayout(rowAGBGameName)
|
|
432
435
|
|
|
433
436
|
rowAGBRomTitle = QtWidgets.QHBoxLayout()
|
|
@@ -437,7 +440,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
437
440
|
self.lblAGBRomTitleResult = QtWidgets.QLabel("")
|
|
438
441
|
rowAGBRomTitle.addWidget(self.lblAGBRomTitleResult)
|
|
439
442
|
rowAGBRomTitle.setStretch(0, 9)
|
|
440
|
-
rowAGBRomTitle.setStretch(1,
|
|
443
|
+
rowAGBRomTitle.setStretch(1, 12)
|
|
441
444
|
group_layout.addLayout(rowAGBRomTitle)
|
|
442
445
|
|
|
443
446
|
rowAGBHeaderGameCodeRevision = QtWidgets.QHBoxLayout()
|
|
@@ -447,7 +450,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
447
450
|
self.lblAGBHeaderGameCodeRevisionResult = QtWidgets.QLabel("")
|
|
448
451
|
rowAGBHeaderGameCodeRevision.addWidget(self.lblAGBHeaderGameCodeRevisionResult)
|
|
449
452
|
rowAGBHeaderGameCodeRevision.setStretch(0, 9)
|
|
450
|
-
rowAGBHeaderGameCodeRevision.setStretch(1,
|
|
453
|
+
rowAGBHeaderGameCodeRevision.setStretch(1, 12)
|
|
451
454
|
group_layout.addLayout(rowAGBHeaderGameCodeRevision)
|
|
452
455
|
|
|
453
456
|
rowAGBGpioRtc = QtWidgets.QHBoxLayout()
|
|
@@ -458,7 +461,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
458
461
|
self.lblAGBGpioRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
459
462
|
rowAGBGpioRtc.addWidget(self.lblAGBGpioRtcResult)
|
|
460
463
|
rowAGBGpioRtc.setStretch(0, 9)
|
|
461
|
-
rowAGBGpioRtc.setStretch(1,
|
|
464
|
+
rowAGBGpioRtc.setStretch(1, 12)
|
|
462
465
|
group_layout.addLayout(rowAGBGpioRtc)
|
|
463
466
|
|
|
464
467
|
rowAGBHeaderBootlogo = QtWidgets.QHBoxLayout()
|
|
@@ -468,7 +471,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
468
471
|
self.lblAGBHeaderBootlogoResult = QtWidgets.QLabel("")
|
|
469
472
|
rowAGBHeaderBootlogo.addWidget(self.lblAGBHeaderBootlogoResult)
|
|
470
473
|
rowAGBHeaderBootlogo.setStretch(0, 9)
|
|
471
|
-
rowAGBHeaderBootlogo.setStretch(1,
|
|
474
|
+
rowAGBHeaderBootlogo.setStretch(1, 12)
|
|
472
475
|
group_layout.addLayout(rowAGBHeaderBootlogo)
|
|
473
476
|
|
|
474
477
|
rowAGBHeaderChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -478,7 +481,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
478
481
|
self.lblAGBHeaderChecksumResult = QtWidgets.QLabel("")
|
|
479
482
|
rowAGBHeaderChecksum.addWidget(self.lblAGBHeaderChecksumResult)
|
|
480
483
|
rowAGBHeaderChecksum.setStretch(0, 9)
|
|
481
|
-
rowAGBHeaderChecksum.setStretch(1,
|
|
484
|
+
rowAGBHeaderChecksum.setStretch(1, 12)
|
|
482
485
|
group_layout.addLayout(rowAGBHeaderChecksum)
|
|
483
486
|
|
|
484
487
|
rowAGBHeaderROMChecksum = QtWidgets.QHBoxLayout()
|
|
@@ -488,7 +491,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
488
491
|
self.lblAGBHeaderROMChecksumResult = QtWidgets.QLabel("")
|
|
489
492
|
rowAGBHeaderROMChecksum.addWidget(self.lblAGBHeaderROMChecksumResult)
|
|
490
493
|
rowAGBHeaderROMChecksum.setStretch(0, 9)
|
|
491
|
-
rowAGBHeaderROMChecksum.setStretch(1,
|
|
494
|
+
rowAGBHeaderROMChecksum.setStretch(1, 12)
|
|
492
495
|
group_layout.addLayout(rowAGBHeaderROMChecksum)
|
|
493
496
|
|
|
494
497
|
rowAGBHeaderROMSize = QtWidgets.QHBoxLayout()
|
|
@@ -501,7 +504,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
501
504
|
self.cmbAGBHeaderROMSizeResult.setCurrentIndex(self.cmbAGBHeaderROMSizeResult.count() - 1)
|
|
502
505
|
rowAGBHeaderROMSize.addWidget(self.cmbAGBHeaderROMSizeResult)
|
|
503
506
|
rowAGBHeaderROMSize.setStretch(0, 9)
|
|
504
|
-
rowAGBHeaderROMSize.setStretch(1,
|
|
507
|
+
rowAGBHeaderROMSize.setStretch(1, 12)
|
|
505
508
|
group_layout.addLayout(rowAGBHeaderROMSize)
|
|
506
509
|
|
|
507
510
|
rowAGBHeaderSaveType = QtWidgets.QHBoxLayout()
|
|
@@ -514,7 +517,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
514
517
|
self.cmbAGBSaveTypeResult.setCurrentIndex(self.cmbAGBSaveTypeResult.count() - 1)
|
|
515
518
|
rowAGBHeaderSaveType.addWidget(self.cmbAGBSaveTypeResult)
|
|
516
519
|
rowAGBHeaderSaveType.setStretch(0, 9)
|
|
517
|
-
rowAGBHeaderSaveType.setStretch(1,
|
|
520
|
+
rowAGBHeaderSaveType.setStretch(1, 12)
|
|
518
521
|
group_layout.addLayout(rowAGBHeaderSaveType)
|
|
519
522
|
|
|
520
523
|
rowAGBCartridgeType = QtWidgets.QHBoxLayout()
|
|
@@ -709,7 +712,13 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
709
712
|
msg = "This software is being developed by Lesserkuma as a hobby project. There is no affiliation with Nintendo or any other company. 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!<br><br>"
|
|
710
713
|
msg += f"© 2020–{datetime.datetime.now().year} Lesserkuma<br>"
|
|
711
714
|
msg += "• Website: <a href=\"https://github.com/lesserkuma/FlashGBX\">https://github.com/lesserkuma/FlashGBX</a><br><br>"
|
|
712
|
-
msg += "Acknowledgments and Contributors:<br>2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr"
|
|
715
|
+
msg += "Acknowledgments and Contributors:<br>2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr"
|
|
716
|
+
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
717
|
+
|
|
718
|
+
def AboutGameDB(self):
|
|
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>"
|
|
720
|
+
msg += f"No-Intro databases referenced for this version of {APPNAME}:<br>"
|
|
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
|
|
713
722
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
714
723
|
|
|
715
724
|
def OpenPath(self, path=None):
|
|
@@ -733,26 +742,19 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
733
742
|
if isinstance(event, QtGui.QMouseEvent):
|
|
734
743
|
if event.button() in (QtCore.Qt.MouseButton.MiddleButton, QtCore.Qt.MouseButton.RightButton): return
|
|
735
744
|
|
|
745
|
+
device = False
|
|
736
746
|
try:
|
|
737
|
-
|
|
738
|
-
Util.dprint("Platform: {:s}".format(platform.platform()))
|
|
739
|
-
if self.CONN is not None:
|
|
740
|
-
Util.dprint("Connected device: {:s}".format(self.CONN.GetFullNameExtended(more=True)))
|
|
741
|
-
else:
|
|
742
|
-
Util.dprint("No device connected")
|
|
743
|
-
Util.dprint("Now writing debug log file")
|
|
747
|
+
device = self.CONN.GetFullNameExtended(more=True)
|
|
744
748
|
except:
|
|
745
749
|
pass
|
|
750
|
+
|
|
751
|
+
Util.write_debug_log(device)
|
|
746
752
|
try:
|
|
747
|
-
fn = Util.CONFIG_PATH + "/debug.log"
|
|
748
|
-
with open(fn, "wb") as f:
|
|
749
|
-
f.write("\n".join(Util.DEBUG_LOG).encode("UTF-8-SIG"))
|
|
750
|
-
print("debug.log written")
|
|
751
753
|
if open_log is True:
|
|
754
|
+
fn = Util.CONFIG_PATH + "/debug.log"
|
|
752
755
|
self.OpenPath(fn)
|
|
753
|
-
return True
|
|
754
756
|
except:
|
|
755
|
-
|
|
757
|
+
pass
|
|
756
758
|
|
|
757
759
|
def ConnectDevice(self):
|
|
758
760
|
if self.CONN is not None:
|
|
@@ -865,6 +867,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
865
867
|
if dev.FirmwareUpdateAvailable():
|
|
866
868
|
dontShowAgain = str(self.SETTINGS.value("SkipFirmwareUpdate", default="disabled")).lower() == "enabled"
|
|
867
869
|
if not dontShowAgain or dev.FW_UPDATE_REQ:
|
|
870
|
+
cb = None
|
|
868
871
|
if dev.FW_UPDATE_REQ is True:
|
|
869
872
|
text = "A firmware update for your {:s} device is required to use this software. Do you want to update now?".format(dev.GetFullName())
|
|
870
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)
|
|
@@ -882,8 +885,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
882
885
|
if not Util.DEBUG:
|
|
883
886
|
self.DisconnectDevice()
|
|
884
887
|
else:
|
|
885
|
-
|
|
886
|
-
|
|
888
|
+
if cb is not None:
|
|
889
|
+
dontShowAgain = cb.isChecked()
|
|
890
|
+
if dontShowAgain: self.SETTINGS.setValue("SkipFirmwareUpdate", "enabled")
|
|
887
891
|
if answer == QtWidgets.QMessageBox.Yes:
|
|
888
892
|
self.ShowFirmwareUpdateWindow()
|
|
889
893
|
|
|
@@ -892,8 +896,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
892
896
|
if not Util.DEBUG:
|
|
893
897
|
self.DisconnectDevice()
|
|
894
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
|
|
895
906
|
|
|
896
907
|
return True
|
|
908
|
+
|
|
897
909
|
return False
|
|
898
910
|
|
|
899
911
|
def FindDevices(self, connectToFirst=False, port=None, mode=None, firstRun=False):
|
|
@@ -926,8 +938,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
926
938
|
msg = ret[i][1]
|
|
927
939
|
if msg in messages: # don’t show the same message twice
|
|
928
940
|
continue
|
|
929
|
-
else:
|
|
930
|
-
|
|
941
|
+
#else:
|
|
942
|
+
# last_msg = msg
|
|
931
943
|
if status == 3:
|
|
932
944
|
messages.append(msg)
|
|
933
945
|
self.CONN = None
|
|
@@ -939,7 +951,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
939
951
|
if dev.IsConnected():
|
|
940
952
|
self.DEVICES[dev.GetFullNameExtended()] = dev
|
|
941
953
|
if dev.GetPort() in ports: break
|
|
942
|
-
|
|
954
|
+
|
|
943
955
|
for dev in self.DEVICES.values():
|
|
944
956
|
dev.Close()
|
|
945
957
|
|
|
@@ -952,7 +964,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
952
964
|
msg += message + "\n\n"
|
|
953
965
|
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), msg[:-2], QtWidgets.QMessageBox.Ok)
|
|
954
966
|
elif not firstRun:
|
|
955
|
-
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()
|
|
956
968
|
|
|
957
969
|
self.lblDevice.setText("No devices found.")
|
|
958
970
|
self.lblDevice.setStyleSheet("")
|
|
@@ -1073,7 +1085,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1073
1085
|
else:
|
|
1074
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."
|
|
1075
1087
|
if self.CONN.GetMode() == "DMG" and self.cmbDMGHeaderMapperResult.currentText() == "MBC1":
|
|
1076
|
-
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."
|
|
1077
1089
|
button_gmmc1 = msgbox.addButton(" Retry as G-MMC1 ", QtWidgets.QMessageBox.ActionRole)
|
|
1078
1090
|
msgbox.setText(msg + msg_te)
|
|
1079
1091
|
msgbox.setIcon(QtWidgets.QMessageBox.Warning)
|
|
@@ -1237,6 +1249,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1237
1249
|
self.CONN.INFO["dump_info"]["batteryless_sram"] = temp3
|
|
1238
1250
|
else:
|
|
1239
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"])
|
|
1240
1257
|
|
|
1241
1258
|
else:
|
|
1242
1259
|
self.lblStatus4a.setText("Ready.")
|
|
@@ -1368,11 +1385,20 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1368
1385
|
return
|
|
1369
1386
|
|
|
1370
1387
|
if cart_type == 0:
|
|
1371
|
-
|
|
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
|
+
|
|
1372
1398
|
if cart_type is False: # clicked Cancel button
|
|
1373
1399
|
return
|
|
1374
1400
|
elif cart_type is None or cart_type == 0:
|
|
1375
|
-
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)
|
|
1376
1402
|
return
|
|
1377
1403
|
|
|
1378
1404
|
if self.CONN.GetMode() == "DMG":
|
|
@@ -1380,6 +1406,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1380
1406
|
elif self.CONN.GetMode() == "AGB":
|
|
1381
1407
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
1382
1408
|
|
|
1409
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1410
|
+
|
|
1383
1411
|
if self.CONN.GetMode() == "DMG":
|
|
1384
1412
|
self.SetDMGMapperResult(carts[cart_type])
|
|
1385
1413
|
mbc = Util.ConvertMapperTypeToMapper(self.cmbDMGHeaderMapperResult.currentIndex())
|
|
@@ -1460,7 +1488,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1460
1488
|
if not Util.compare_mbc(hdr["mapper_raw"], mbc):
|
|
1461
1489
|
mbc1 = Util.get_mbc_name(mbc)
|
|
1462
1490
|
mbc2 = Util.get_mbc_name(hdr["mapper_raw"])
|
|
1463
|
-
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" ]
|
|
1464
1492
|
if (mbc2 == "None") or (mbc1 == "G-MMC1" and mbc2 == "MBC1") or (mbc2 == "G-MMC1" and mbc1 == "MBC1"):
|
|
1465
1493
|
pass
|
|
1466
1494
|
elif mbc2 != "None" and not (mbc1 in compatible_mbc and mbc2 in compatible_mbc):
|
|
@@ -1633,14 +1661,25 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1633
1661
|
return
|
|
1634
1662
|
cart_type = self.cmbAGBCartridgeTypeResult.currentIndex()
|
|
1635
1663
|
if cart_type == 0 or ("dump_info" not in self.CONN.INFO or "batteryless_sram" not in self.CONN.INFO["dump_info"]):
|
|
1636
|
-
|
|
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
|
+
|
|
1637
1674
|
if cart_type is False: # clicked Cancel button
|
|
1638
1675
|
return
|
|
1639
1676
|
elif cart_type is None or cart_type == 0:
|
|
1640
|
-
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)
|
|
1641
1678
|
return
|
|
1642
1679
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
1643
1680
|
|
|
1681
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
1682
|
+
|
|
1644
1683
|
if "dump_info" in self.CONN.INFO and "batteryless_sram" in self.CONN.INFO["dump_info"]:
|
|
1645
1684
|
detected = self.CONN.INFO["dump_info"]["batteryless_sram"]
|
|
1646
1685
|
else:
|
|
@@ -1671,10 +1710,12 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1671
1710
|
self.STATUS["last_path"] = path
|
|
1672
1711
|
self.STATUS["args"] = args
|
|
1673
1712
|
|
|
1674
|
-
def WriteRAM(self, dpath="", erase=False, test=False):
|
|
1713
|
+
def WriteRAM(self, dpath="", erase=False, test=False, skip_warning=False):
|
|
1675
1714
|
if not self.CheckDeviceAlive(): return
|
|
1676
1715
|
mode = self.CONN.GetMode()
|
|
1677
1716
|
|
|
1717
|
+
if erase is True: dpath = ""
|
|
1718
|
+
|
|
1678
1719
|
if dpath == "":
|
|
1679
1720
|
path = Util.GenerateFileName(mode=mode, header=self.CONN.INFO, settings=self.SETTINGS)
|
|
1680
1721
|
path = os.path.splitext(path)[0]
|
|
@@ -1709,14 +1750,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
1709
1750
|
|
|
1710
1751
|
filesize = 0
|
|
1711
1752
|
if dpath != "":
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
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
|
|
1715
1757
|
path = dpath
|
|
1716
1758
|
self.SETTINGS.setValue(setting_name, os.path.dirname(path))
|
|
1717
1759
|
elif erase:
|
|
1718
|
-
|
|
1719
|
-
|
|
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
|
|
1720
1763
|
elif test:
|
|
1721
1764
|
path = None
|
|
1722
1765
|
if self.CONN.GetFWBuildDate() == "": # Legacy Mode
|
|
@@ -2013,14 +2056,25 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2013
2056
|
return
|
|
2014
2057
|
cart_type = self.cmbAGBCartridgeTypeResult.currentIndex()
|
|
2015
2058
|
if cart_type == 0 or ("dump_info" not in self.CONN.INFO or "batteryless_sram" not in self.CONN.INFO["dump_info"]):
|
|
2016
|
-
|
|
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
|
+
|
|
2017
2069
|
if cart_type is False: # clicked Cancel button
|
|
2018
2070
|
return
|
|
2019
2071
|
elif cart_type is None or cart_type == 0:
|
|
2020
|
-
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)
|
|
2021
2073
|
return
|
|
2022
2074
|
self.cmbAGBCartridgeTypeResult.setCurrentIndex(cart_type)
|
|
2023
2075
|
|
|
2076
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
2077
|
+
|
|
2024
2078
|
if "dump_info" in self.CONN.INFO and "batteryless_sram" in self.CONN.INFO["dump_info"]:
|
|
2025
2079
|
detected = self.CONN.INFO["dump_info"]["batteryless_sram"]
|
|
2026
2080
|
else:
|
|
@@ -2080,6 +2134,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2080
2134
|
except:
|
|
2081
2135
|
pass
|
|
2082
2136
|
|
|
2137
|
+
intro_msg = ""
|
|
2083
2138
|
if detected is not False:
|
|
2084
2139
|
try:
|
|
2085
2140
|
loc_index = locs.index(detected["bl_offset"])
|
|
@@ -2147,7 +2202,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2147
2202
|
|
|
2148
2203
|
if self.CONN.GetMode() == "DMG":
|
|
2149
2204
|
mbc = Util.get_mbc_name(Util.ConvertMapperTypeToMapper(self.cmbDMGHeaderMapperResult.currentIndex()))
|
|
2150
|
-
if mbc in ("MBC3", "MBC30"):
|
|
2205
|
+
if mbc in ("MBC3", "MBC30", "Unlicensed MBCX Mapper"):
|
|
2151
2206
|
dlg_args = {
|
|
2152
2207
|
"title":"MBC3/MBC30 Real Time Clock Editor",
|
|
2153
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.",
|
|
@@ -2372,10 +2427,16 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2372
2427
|
|
|
2373
2428
|
if not self.CheckDeviceAlive(setMode=setTo): return
|
|
2374
2429
|
|
|
2375
|
-
|
|
2376
|
-
self.
|
|
2377
|
-
|
|
2378
|
-
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
|
|
2379
2440
|
|
|
2380
2441
|
ok = self.ReadCartridge()
|
|
2381
2442
|
qt_app.processEvents()
|
|
@@ -2415,7 +2476,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2415
2476
|
return False
|
|
2416
2477
|
|
|
2417
2478
|
if self.CONN.CheckROMStable() is False and resetStatus:
|
|
2418
|
-
|
|
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
|
|
2419
2484
|
|
|
2420
2485
|
if self.CONN.GetMode() == "DMG":
|
|
2421
2486
|
self.cmbDMGHeaderMapperResult.clear()
|
|
@@ -2440,7 +2505,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2440
2505
|
self.lblDMGGameCodeRevisionResult.setText("{:s}-{:s}".format(data["db"]["gc"], str(data["version"])))
|
|
2441
2506
|
temp = data["db"]["gn"]
|
|
2442
2507
|
self.lblDMGGameNameResult.setText(temp)
|
|
2443
|
-
while self.lblDMGGameNameResult.fontMetrics().boundingRect(self.lblDMGGameNameResult.text()).width() >
|
|
2508
|
+
while self.lblDMGGameNameResult.fontMetrics().boundingRect(self.lblDMGGameNameResult.text()).width() > 240:
|
|
2444
2509
|
temp = temp[:-1]
|
|
2445
2510
|
self.lblDMGGameNameResult.setText(temp + "…")
|
|
2446
2511
|
if temp != data["db"]["gn"]:
|
|
@@ -2562,7 +2627,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2562
2627
|
self.lblAGBHeaderGameCodeRevisionResult.setText("{:s}-{:s}".format(data["db"]["gc"], str(data["version"])))
|
|
2563
2628
|
temp = data["db"]["gn"]
|
|
2564
2629
|
self.lblAGBGameNameResult.setText(temp)
|
|
2565
|
-
while self.lblAGBGameNameResult.fontMetrics().boundingRect(self.lblAGBGameNameResult.text()).width() >
|
|
2630
|
+
while self.lblAGBGameNameResult.fontMetrics().boundingRect(self.lblAGBGameNameResult.text()).width() > 240:
|
|
2566
2631
|
temp = temp[:-1]
|
|
2567
2632
|
self.lblAGBGameNameResult.setText(temp + "…")
|
|
2568
2633
|
if temp != data["db"]["gn"]:
|
|
@@ -2673,13 +2738,12 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2673
2738
|
self.btnRestoreRAM.setEnabled(True)
|
|
2674
2739
|
self.btnHeaderRefresh.setFocus()
|
|
2675
2740
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
2676
|
-
self.lblStatus4a.setText("Ready.")
|
|
2677
2741
|
qt_app.processEvents()
|
|
2678
2742
|
|
|
2679
2743
|
if data['game_title'][:11] == "YJencrypted" and resetStatus:
|
|
2680
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)
|
|
2681
2745
|
|
|
2682
|
-
def DetectCartridge(self,
|
|
2746
|
+
def DetectCartridge(self, checkSaveType=True):
|
|
2683
2747
|
if not self.CheckDeviceAlive(): return
|
|
2684
2748
|
if not self.CONN.CheckROMStable():
|
|
2685
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)
|
|
@@ -2695,12 +2759,20 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2695
2759
|
self.lblStatus2aResult.setText("–")
|
|
2696
2760
|
self.lblStatus3aResult.setText("–")
|
|
2697
2761
|
self.lblStatus4aResult.setText("")
|
|
2698
|
-
self.lblStatus4a.setText("Analyzing Cartridge...")
|
|
2762
|
+
# self.lblStatus4a.setText("Analyzing Cartridge...")
|
|
2699
2763
|
self.SetProgressBars(min=0, max=0, value=1)
|
|
2700
2764
|
qt_app.processEvents()
|
|
2701
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
|
+
|
|
2702
2775
|
limitVoltage = str(self.SETTINGS.value("AutoDetectLimitVoltage", default="disabled")).lower() == "enabled"
|
|
2703
|
-
ret = self.CONN.DetectCartridge(limitVoltage=limitVoltage, checkSaveType=not canSkipMessage)
|
|
2704
2776
|
if ret is False:
|
|
2705
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)
|
|
2706
2778
|
self.DisconnectDevice()
|
|
@@ -2709,7 +2781,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2709
2781
|
(header, save_size, save_type, save_chip, sram_unstable, cart_types, cart_type_id, cfi_s, _, flash_id, detected_size) = ret
|
|
2710
2782
|
|
|
2711
2783
|
# Save Type
|
|
2712
|
-
if not
|
|
2784
|
+
if not self.STATUS["can_skip_message"]:
|
|
2713
2785
|
try:
|
|
2714
2786
|
if save_type is not None and save_type is not False:
|
|
2715
2787
|
if self.CONN.GetMode() == "DMG":
|
|
@@ -2728,6 +2800,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2728
2800
|
supp_cart_types = self.CONN.GetSupportedCartridgesDMG()
|
|
2729
2801
|
elif self.CONN.GetMode() == "AGB":
|
|
2730
2802
|
supp_cart_types = self.CONN.GetSupportedCartridgesAGB()
|
|
2803
|
+
else:
|
|
2804
|
+
raise NotImplementedError
|
|
2731
2805
|
except Exception as e:
|
|
2732
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)
|
|
2733
2807
|
msgbox.exec()
|
|
@@ -2761,7 +2835,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2761
2835
|
# Save Type
|
|
2762
2836
|
msg_save_type_s = ""
|
|
2763
2837
|
temp = ""
|
|
2764
|
-
if not
|
|
2838
|
+
if not self.STATUS["can_skip_message"] and save_type is not False and save_type is not None:
|
|
2765
2839
|
if save_chip is not None:
|
|
2766
2840
|
temp = "{:s} ({:s})".format(Util.AGB_Header_Save_Types[save_type], save_chip)
|
|
2767
2841
|
else:
|
|
@@ -2909,7 +2983,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2909
2983
|
msg = "The following cartridge configuration was detected:<br><br>"
|
|
2910
2984
|
if found_supported:
|
|
2911
2985
|
dontShowAgain = str(self.SETTINGS.value("SkipAutodetectMessage", default="disabled")).lower() == "enabled"
|
|
2912
|
-
if not dontShowAgain or not
|
|
2986
|
+
if not dontShowAgain or not self.STATUS["can_skip_message"]:
|
|
2913
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)
|
|
2914
2988
|
temp = temp[:-4]
|
|
2915
2989
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=temp)
|
|
@@ -2919,7 +2993,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2919
2993
|
button_cancel = None
|
|
2920
2994
|
msgbox.setDefaultButton(button_ok)
|
|
2921
2995
|
cb = QtWidgets.QCheckBox("Always skip this message", checked=False)
|
|
2922
|
-
if
|
|
2996
|
+
if self.STATUS["can_skip_message"]:
|
|
2923
2997
|
button_cancel = msgbox.addButton("&Cancel", QtWidgets.QMessageBox.RejectRole)
|
|
2924
2998
|
msgbox.setEscapeButton(button_cancel)
|
|
2925
2999
|
msgbox.setCheckBox(cb)
|
|
@@ -2928,7 +3002,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2928
3002
|
|
|
2929
3003
|
msgbox.exec()
|
|
2930
3004
|
dontShowAgain = cb.isChecked()
|
|
2931
|
-
if dontShowAgain and
|
|
3005
|
+
if dontShowAgain and self.STATUS["can_skip_message"]: self.SETTINGS.setValue("SkipAutodetectMessage", "enabled")
|
|
2932
3006
|
|
|
2933
3007
|
if msgbox.clickedButton() == button_details:
|
|
2934
3008
|
show_details = True
|
|
@@ -2943,7 +3017,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2943
3017
|
self.btnHeaderRefresh.setFocus()
|
|
2944
3018
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
2945
3019
|
self.lblStatus4a.setText("Ready.")
|
|
2946
|
-
|
|
3020
|
+
self.STATUS["can_skip_message"] = False
|
|
3021
|
+
if "detected_cart_type" in self.STATUS: del(self.STATUS["detected_cart_type"])
|
|
3022
|
+
return
|
|
2947
3023
|
|
|
2948
3024
|
if not found_supported or show_details is True:
|
|
2949
3025
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="{:s} {:s}".format(APPNAME, VERSION))
|
|
@@ -2969,7 +3045,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2969
3045
|
if answer == QtWidgets.QMessageBox.Yes:
|
|
2970
3046
|
self.SETTINGS.setValue("AutoDetectLimitVoltage", "disabled")
|
|
2971
3047
|
self.mnuConfig.actions()[4].setChecked(False)
|
|
2972
|
-
|
|
3048
|
+
self.STATUS["can_skip_message"] = False
|
|
3049
|
+
self.DetectCartridge()
|
|
3050
|
+
return
|
|
2973
3051
|
|
|
2974
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)
|
|
2975
3053
|
temp = temp[:-4]
|
|
@@ -2999,7 +3077,27 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2999
3077
|
self.btnHeaderRefresh.setFocus()
|
|
3000
3078
|
self.SetProgressBars(min=0, max=100, value=0)
|
|
3001
3079
|
self.lblStatus4a.setText("Ready.")
|
|
3002
|
-
|
|
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()
|
|
3003
3101
|
|
|
3004
3102
|
def WaitProgress(self, args):
|
|
3005
3103
|
if args["user_action"] == "REINSERT_CART":
|
|
@@ -3030,6 +3128,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3030
3128
|
self.grpStatus.setTitle("Transfer Status (Write Save Data)")
|
|
3031
3129
|
elif args["method"] == "SAVE_WRITE_VERIFY":
|
|
3032
3130
|
self.grpStatus.setTitle("Transfer Status (Verify Save Data)")
|
|
3131
|
+
elif args["method"] == "DETECT_CART":
|
|
3132
|
+
self.grpStatus.setTitle("Transfer Status (Analyze Cartridge)")
|
|
3033
3133
|
|
|
3034
3134
|
if "error" in args:
|
|
3035
3135
|
self.lblStatus4a.setText("Failed!")
|
|
@@ -3113,6 +3213,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3113
3213
|
self.lblStatus4aResult.setText("")
|
|
3114
3214
|
self.btnCancel.setEnabled(args["abortable"])
|
|
3115
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)
|
|
3116
3221
|
elif args["action"] == "FINISHED":
|
|
3117
3222
|
if pos > 0:
|
|
3118
3223
|
self.lblStatus1aResult.setText(Util.formatFileSize(size=pos))
|
|
@@ -3331,18 +3436,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3331
3436
|
except:
|
|
3332
3437
|
pass
|
|
3333
3438
|
qt_app.exec()
|
|
3334
|
-
# # Taskbar Progress on Windows only
|
|
3335
|
-
# try:
|
|
3336
|
-
# from PySide6.QtWin import QtWinTaskbarButton, QtWin
|
|
3337
|
-
# myappid = 'lesserkuma.flashgbx'
|
|
3338
|
-
# QtWin.setAppUserModelId(myappid)
|
|
3339
|
-
# taskbar_button = QtWinTaskbarButton()
|
|
3340
|
-
# self.TBPROG = taskbar_button.progress()
|
|
3341
|
-
# self.TBPROG.setRange(0, 100)
|
|
3342
|
-
# taskbar_button.setWindow(self.windowHandle())
|
|
3343
|
-
# self.TBPROG.setVisible(False)
|
|
3344
|
-
# except ImportError:
|
|
3345
|
-
# pass
|
|
3346
3439
|
|
|
3347
3440
|
else: # PySide2
|
|
3348
3441
|
qt_app.exec_()
|