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.
@@ -309,13 +309,13 @@ class PocketCameraWindow(QtWidgets.QDialog):
309
309
  draw.line([0, 112, 128, 0], fill=(255, 0, 0, 192), width=8)
310
310
  pic.paste(draw_bg, mask=draw_bg)
311
311
  self.lblPhoto[i].setToolTip("This picture was marked as “deleted” and may be overwritten when you take new pictures.")
312
- self.CUR_THUMBS[i] = ImageQt(pic.resize((47, 41), Image.HAMMING))
312
+ self.CUR_THUMBS[i] = ImageQt(pic.resize((47, 41), Image.Resampling.HAMMING))
313
313
  qpixmap = QtGui.QPixmap.fromImage(self.CUR_THUMBS[i])
314
314
  self.lblPhoto[i].setPixmap(qpixmap)
315
315
 
316
316
  def UpdateViewer(self, index):
317
- resampler = Image.NEAREST
318
- if self.CUR_BICUBIC: resampler = Image.BICUBIC
317
+ resampler = Image.Resampling.NEAREST
318
+ if self.CUR_BICUBIC: resampler = Image.Resampling.BICUBIC
319
319
  cam = self.CUR_PC
320
320
  if cam is None: return
321
321
 
@@ -323,7 +323,7 @@ class PocketCameraWindow(QtWidgets.QDialog):
323
323
  self.lblPhoto[i].setStyleSheet("border-top: 1px solid #adadad; border-left: 1px solid #adadad; border-bottom: 1px solid #ffffff; border-right: 1px solid #ffffff;")
324
324
 
325
325
  if index >= 30:
326
- self.CUR_PIC = ImageQt(cam.GetPicture(index).convert("RGBA").resize((256, 224), Image.BICUBIC if index == 31 else resampler))
326
+ self.CUR_PIC = ImageQt(cam.GetPicture(index).convert("RGBA").resize((256, 224), Image.Resampling.BICUBIC if index == 31 else resampler))
327
327
  else:
328
328
  self.CUR_PIC = ImageQt(cam.GetPicture(index).convert("RGBA").resize((256, 224), resampler))
329
329
  self.lblPhoto[index].setStyleSheet("border: 3px solid green; padding: 1px;")
FlashGBX/RomFileDMG.py CHANGED
@@ -431,6 +431,12 @@ class RomFileDMG:
431
431
  temp = self.LogoToImage(buffer[0x104:0x104+0x30])
432
432
  if temp is not False: data["logo_sachen"] = temp
433
433
 
434
+ # GBFlash MBCX
435
+ if data["game_title"] == "MBCX_MENU":
436
+ data["rom_size_raw"] = 0x0A
437
+ data["ram_size_raw"] = 0x03
438
+ data["mapper_raw"] = 0x206
439
+
434
440
  if data["mapper_raw"] in Util.DMG_Header_Mapper:
435
441
  data["mapper"] = Util.DMG_Header_Mapper[data["mapper_raw"]]
436
442
  elif data["logo_correct"]:
FlashGBX/Util.py CHANGED
@@ -2,15 +2,15 @@
2
2
  # FlashGBX
3
3
  # Author: Lesserkuma (github.com/lesserkuma)
4
4
 
5
- import math, time, datetime, copy, configparser, threading, os, platform, traceback, io, struct, re, statistics, random
5
+ import math, time, datetime, copy, configparser, threading, os, platform, traceback, io, struct, re, statistics, random, sys
6
6
  from io import StringIO
7
7
  from enum import Enum
8
8
 
9
9
  # Common constants
10
10
  APPNAME = "FlashGBX"
11
- VERSION_PEP440 = "4.1"
11
+ VERSION_PEP440 = "4.3"
12
12
  VERSION = "v{:s}".format(VERSION_PEP440)
13
- VERSION_TIMESTAMP = 1722759922
13
+ VERSION_TIMESTAMP = 1731015769
14
14
  DEBUG = False
15
15
  DEBUG_LOG = []
16
16
  APP_PATH = ""
@@ -23,11 +23,11 @@ AGB_Header_Save_Sizes = [ 0, 512, 8192, 32768, 65536, 131072, 1048576, 65536, 13
23
23
  AGB_Flash_Save_Chips = { 0xBFD4:"SST 39VF512", 0x1F3D:"Atmel AT29LV512", 0xC21C:"Macronix MX29L512", 0x321B:"Panasonic MN63F805MNP", 0xC209:"Macronix MX29L010", 0x6213:"SANYO LE26FV10N1TS", 0xBF5B:"Unlicensed SST49LF080A", 0xFFFF:"Unlicensed 0xFFFF" }
24
24
  AGB_Flash_Save_Chips_Sizes = [ 0x10000, 0x10000, 0x10000, 0x10000, 0x20000, 0x20000, 0x20000, 0x20000 ]
25
25
 
26
- DMG_Header_Mapper = { 0x00:'None', 0x01:'MBC1', 0x02:'MBC1+SRAM', 0x03:'MBC1+SRAM+BATTERY', 0x06:'MBC2+SRAM+BATTERY', 0x0F:'MBC3+RTC+BATTERY', 0x10:'MBC3+RTC+SRAM+BATTERY', 0x110:'MBC30+RTC+SRAM+BATTERY', 0x12:'MBC3+SRAM', 0x13:'MBC3+SRAM+BATTERY', 0x19:'MBC5', 0x1A:'MBC5+SRAM', 0x1B:'MBC5+SRAM+BATTERY', 0x1C:'MBC5+RUMBLE', 0x1E:'MBC5+RUMBLE+SRAM+BATTERY', 0x20:'MBC6+SRAM+FLASH+BATTERY', 0x22:'MBC7+ACCELEROMETER+EEPROM', 0x101:'MBC1M', 0x103:'MBC1M+SRAM+BATTERY', 0x0B:'MMM01', 0x0D:'MMM01+SRAM+BATTERY', 0xFC:'MAC-GBD+SRAM+BATTERY', 0x105:'G-MMC1+SRAM+BATTERY', 0x104:'M161', 0xFF:'HuC-1+IR+SRAM+BATTERY', 0xFE:'HuC-3+RTC+SRAM+BATTERY', 0xFD:'TAMA5+RTC+EEPROM', 0x201:'Unlicensed 256M Mapper', 0x202:'Unlicensed Wisdom Tree Mapper', 0x203:'Unlicensed Xploder GB Mapper', 0x204:'Unlicensed Sachen Mapper', 0x205:'Unlicensed Datel Orbit V2 Mapper' }
27
- DMG_Mapper_Types = { "None":[ 0x00, 0x08, 0x09 ], "MBC1":[ 0x01, 0x02, 0x03 ], "MBC2":[ 0x05, 0x06 ], "MBC3":[ 0x0F, 0x10, 0x11, 0x12, 0x13 ], "MBC30":[ 0x110 ], "MBC5":[ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E ], "MBC6":[ 0x20 ], "MBC7":[ 0x22 ], "MBC1M":[ 0x101, 0x103 ], "MMM01":[ 0x0B, 0x0D ], "MAC-GBD":[ 0xFC ], "G-MMC1":[ 0x105 ], "M161":[ 0x104 ], "HuC-1":[ 0xFF ], "HuC-3":[ 0xFE ], "TAMA5":[ 0xFD ], "Unlicensed 256M Multi Cart Mapper":[ 0x201 ], "Unlicensed Wisdom Tree Mapper":[ 0x202 ], "Unlicensed Xploder GB Mapper":[ 0x203 ], "Unlicensed Sachen Mapper":[ 0x204 ], "Unlicensed Datel Orbit V2 Mapper":[ 0x205 ] }
28
- DMG_Header_ROM_Sizes = [ "32 KiB", "64 KiB", "128 KiB", "256 KiB", "512 KiB", "1 MiB", "2 MiB", "4 MiB", "8 MiB", "16 MiB", "32 MiB" ]
29
- DMG_Header_ROM_Sizes_Map = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A ]
30
- DMG_Header_ROM_Sizes_Flasher_Map = [ 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000 ]
26
+ DMG_Header_Mapper = { 0x00:'None', 0x01:'MBC1', 0x02:'MBC1+SRAM', 0x03:'MBC1+SRAM+BATTERY', 0x06:'MBC2+SRAM+BATTERY', 0x0F:'MBC3+RTC+BATTERY', 0x10:'MBC3+RTC+SRAM+BATTERY', 0x110:'MBC30+RTC+SRAM+BATTERY', 0x12:'MBC3+SRAM', 0x13:'MBC3+SRAM+BATTERY', 0x19:'MBC5', 0x1A:'MBC5+SRAM', 0x1B:'MBC5+SRAM+BATTERY', 0x1C:'MBC5+RUMBLE', 0x1E:'MBC5+RUMBLE+SRAM+BATTERY', 0x20:'MBC6+SRAM+FLASH+BATTERY', 0x22:'MBC7+ACCELEROMETER+EEPROM', 0x101:'MBC1M', 0x103:'MBC1M+SRAM+BATTERY', 0x0B:'MMM01', 0x0D:'MMM01+SRAM+BATTERY', 0xFC:'MAC-GBD+SRAM+BATTERY', 0x105:'G-MMC1+SRAM+BATTERY', 0x104:'M161', 0xFF:'HuC-1+IR+SRAM+BATTERY', 0xFE:'HuC-3+RTC+SRAM+BATTERY', 0xFD:'TAMA5+RTC+EEPROM', 0x201:'Unlicensed 256M Mapper', 0x202:'Unlicensed Wisdom Tree Mapper', 0x203:'Unlicensed Xploder GB Mapper', 0x204:'Unlicensed Sachen Mapper', 0x205:'Unlicensed Datel Orbit V2 Mapper', 0x206:'Unlicensed MBCX Mapper' }
27
+ DMG_Mapper_Types = { "None":[ 0x00, 0x08, 0x09 ], "MBC1":[ 0x01, 0x02, 0x03 ], "MBC2":[ 0x05, 0x06 ], "MBC3":[ 0x0F, 0x10, 0x11, 0x12, 0x13 ], "MBC30":[ 0x110 ], "MBC5":[ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E ], "MBC6":[ 0x20 ], "MBC7":[ 0x22 ], "MBC1M":[ 0x101, 0x103 ], "MMM01":[ 0x0B, 0x0D ], "MAC-GBD":[ 0xFC ], "G-MMC1":[ 0x105 ], "M161":[ 0x104 ], "HuC-1":[ 0xFF ], "HuC-3":[ 0xFE ], "TAMA5":[ 0xFD ], "Unlicensed 256M Multi Cart Mapper":[ 0x201 ], "Unlicensed Wisdom Tree Mapper":[ 0x202 ], "Unlicensed Xploder GB Mapper":[ 0x203 ], "Unlicensed Sachen Mapper":[ 0x204 ], "Unlicensed Datel Orbit V2 Mapper":[ 0x205 ], "Unlicensed MBCX Mapper":[ 0x206 ] }
28
+ DMG_Header_ROM_Sizes = [ "32 KiB", "64 KiB", "128 KiB", "256 KiB", "512 KiB", "1 MiB", "2 MiB", "4 MiB", "8 MiB", "16 MiB", "32 MiB", "64 MiB", "128 MiB" ]
29
+ DMG_Header_ROM_Sizes_Map = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C ]
30
+ DMG_Header_ROM_Sizes_Flasher_Map = [ 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000 ]
31
31
  DMG_Header_RAM_Sizes = [ "None", "4K SRAM (512 Bytes)", "16K SRAM (2 KiB)", "64K SRAM (8 KiB)", "256K SRAM (32 KiB)", "512K SRAM (64 KiB)", "1M SRAM (128 KiB)", "MBC6 SRAM+FLASH (1.03 MiB)", "MBC7 2K EEPROM (256 Bytes)", "MBC7 4K EEPROM (512 Bytes)", "TAMA5 EEPROM (32 Bytes)", "Unlicensed 4M SRAM (512 KiB)", "Unlicensed 1M EEPROM (128 KiB)" ]
32
32
  DMG_Header_RAM_Sizes_Map = [ 0x00, 0x100, 0x01, 0x02, 0x03, 0x05, 0x04, 0x104, 0x101, 0x102, 0x103, 0x201, 0x203, 0x204 ]
33
33
  DMG_Header_RAM_Sizes_Flasher_Map = [ 0, 0x200, 0x800, 0x2000, 0x8000, 0x10000, 0x20000, 0x108000, 0x100, 0x200, 0x20, 0x80000, 0x20000, 0x80000 ] # RAM size in bytes
@@ -169,6 +169,10 @@ class Progress():
169
169
  self.PROGRESS["time_start"] = args["time_start"]
170
170
  else:
171
171
  self.PROGRESS["time_start"] = now
172
+ if "abortable" in args:
173
+ self.PROGRESS["abortable"] = args["abortable"]
174
+ else:
175
+ self.PROGRESS["abortable"] = True
172
176
  self.PROGRESS["time_last_emit"] = now
173
177
  self.PROGRESS["time_last_update_speed"] = now
174
178
  self.PROGRESS["time_left"] = 0
@@ -218,7 +222,7 @@ class Progress():
218
222
  self.PROGRESS["sector_pos"] = args["sector_pos"]
219
223
  if "abortable" in args:
220
224
  self.PROGRESS["abortable"] = args["abortable"]
221
-
225
+
222
226
  if ((now - self.PROGRESS["time_last_emit"]) > 0.06) or "force_update" in args and args["force_update"] is True:
223
227
  self.PROGRESS["time_elapsed"] = now - self.PROGRESS["time_start"]
224
228
  time_delta = now - self.PROGRESS["time_last_update_speed"]
@@ -254,6 +258,11 @@ class Progress():
254
258
  self.UPDATER(self.PROGRESS)
255
259
  self.PROGRESS["time_last_emit"] = now
256
260
 
261
+ elif args["action"] == "UPDATE_INFO":
262
+ self.PROGRESS["text"] = args["text"]
263
+ self.PROGRESS["action"] = args["action"]
264
+ self.UPDATER(self.PROGRESS)
265
+
257
266
  elif args["action"] == "FINISHED":
258
267
  self.PROGRESS["pos"] = self.PROGRESS["size"]
259
268
  self.UPDATER(self.PROGRESS)
@@ -535,6 +544,8 @@ def GetDumpReport(di, device):
535
544
  di["rom_size"] = "{:s}".format(AGB_Header_ROM_Sizes[AGB_Header_ROM_Sizes_Map.index(di["rom_size"])])
536
545
  else:
537
546
  di["rom_size"] = "{:,} bytes".format(di["rom_size"])
547
+ else:
548
+ raise NotImplementedError
538
549
 
539
550
  di["cart_type"] = list(device.SUPPORTED_CARTS[mode].keys())[di["cart_type"]]
540
551
  if di["file_name"] is None:
@@ -795,7 +806,10 @@ def GetDumpReport(di, device):
795
806
  if "st" in db: s += "* Save Type: {:s}\n".format(AGB_Header_Save_Types[db["st"]])
796
807
  #if "ss" in db: s += "* Save Size: {:s}\n".format(formatFileSize(size=db["ss"], asInt=True))
797
808
 
798
- return s
809
+ if platform.system() == "Windows":
810
+ return s.replace("\n", "\r\n")
811
+ else:
812
+ return s
799
813
 
800
814
  def GenerateFileName(mode, header, settings=None):
801
815
  fe_ni = True
@@ -921,3 +935,37 @@ def dprint(*args, **kwargs):
921
935
  if DEBUG:
922
936
  msg = "{:s}{:s}".format(ANSI.CLEAR_LINE, msg)
923
937
  print(msg)
938
+
939
+ def write_debug_log(device=False):
940
+ dprint("{:s} version: {:s} ({:d})".format(APPNAME, VERSION_PEP440, VERSION_TIMESTAMP))
941
+ dprint("Platform: {:s}".format(platform.platform()))
942
+ if device is not False:
943
+ if device is not None:
944
+ dprint("Connected device: {:s}".format(device))
945
+ else:
946
+ dprint("No device connected")
947
+ dprint("Now writing debug log file")
948
+ try:
949
+ fn = CONFIG_PATH + "/debug.log"
950
+ with open(fn, "wb") as f:
951
+ if platform.system() == "Windows":
952
+ f.write("\r\n".join(DEBUG_LOG).encode("UTF-8-SIG"))
953
+ else:
954
+ f.write("\n".join(DEBUG_LOG).encode("UTF-8-SIG"))
955
+ print("debug.log written")
956
+ return True
957
+ except:
958
+ return False
959
+
960
+ def exception_hook(exc_type, exc_value, exc_traceback):
961
+ if issubclass(exc_type, KeyboardInterrupt):
962
+ sys.__excepthook__(exc_type, exc_value, exc_traceback)
963
+ return
964
+
965
+ s = "⚠️ EXCEPTION OCCURED ⚠️\n"
966
+ lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
967
+ for line in lines:
968
+ s += f"{line:s}"
969
+ print(s)
970
+ dprint(s)
971
+ write_debug_log()
FlashGBX/fw_GBFlash.py CHANGED
@@ -230,11 +230,6 @@ try:
230
230
  self.DEVICE = device
231
231
  else:
232
232
  self.APP.QT_APP.processEvents()
233
- text = "This Firmware Updater is for GBFlash devices only. Please only proceed if your device is a GBFlash."
234
- msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
235
- msgbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
236
- answer = msgbox.exec()
237
- if answer == QtWidgets.QMessageBox.Cancel: return
238
233
  self.FWUPD = FirmwareUpdater(app_path, None)
239
234
 
240
235
  self.layout = QtWidgets.QGridLayout()
@@ -110,11 +110,6 @@ try:
110
110
  self.DEVICE = device
111
111
  else:
112
112
  self.APP.QT_APP.processEvents()
113
- text = "This Firmware Updater is for insideGadgets GBxCart RW v1.4 devices only. Please only proceed if your device matches this hardware revision.\n\nOlder GBxCart RW revisions can be updated only after connecting to them first."
114
- msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
115
- msgbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
116
- answer = msgbox.exec()
117
- if answer == QtWidgets.QMessageBox.Cancel: return
118
113
  self.FWUPD = FirmwareUpdater(app_path, None)
119
114
 
120
115
  self.layout = QtWidgets.QGridLayout()
@@ -217,8 +212,10 @@ try:
217
212
  self.lblDeviceFWVerResult.setText(self.FW_VER)
218
213
  if self.PCB_VER == "v1.4":
219
214
  self.optDevicePCBVer14.setChecked(True)
215
+ self.optDevicePCBVer14a.setEnabled(False)
220
216
  elif self.PCB_VER == "v1.4a/b/c":
221
217
  self.optDevicePCBVer14a.setChecked(True)
218
+ self.optDevicePCBVer14.setEnabled(False)
222
219
  self.SetPCBVersion()
223
220
 
224
221
  def SetPCBVersion(self):
FlashGBX/fw_JoeyJr.py CHANGED
@@ -30,7 +30,9 @@ class FirmwareUpdater():
30
30
  path = os.path.dirname(path) + "/"
31
31
  fncSetStatus(text="Connecting... This may take a moment.")
32
32
 
33
- with open(file, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
33
+ filename = os.path.split(file)[1]
34
+ filepath = os.path.split(file)[0]
35
+ with open(filepath + "/" + filename, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
34
36
  if not temp.startswith("UPDATE"):
35
37
  with open(file, "wb") as f:
36
38
  temp = bytearray(b"UPDATE")
@@ -46,10 +48,16 @@ class FirmwareUpdater():
46
48
  return 2
47
49
 
48
50
  try:
49
- with open(file, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
50
- except FileNotFoundError:
51
- fncSetStatus(text="Couldn’t access MODE.TXT. Remove cartridge and try again.")
52
- return 2
51
+ with open(filepath + "/" + filename, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
52
+ except FileNotFoundError as e:
53
+ try:
54
+ if filename == "MODE.TXT":
55
+ with open(filepath + "/" + "MODE!.TXT", "rb") as f: temp = f.read().decode("UTF-8", "ignore")
56
+ else:
57
+ raise FileNotFoundError from e
58
+ except FileNotFoundError:
59
+ fncSetStatus(text="Couldn’t access MODE.TXT. Remove cartridge and try again.")
60
+ return 2
53
61
 
54
62
  if not temp.startswith("UPDATE"):
55
63
  fncSetStatus(text="Couldn’t enter UPDATE mode, please try again.")
@@ -272,7 +280,7 @@ try:
272
280
  self.rowUpdate.addStretch()
273
281
 
274
282
  self.rowUpdate2 = QtWidgets.QHBoxLayout()
275
- self.lblUpdateDisclaimer = QtWidgets.QLabel("Please note that FlashGBX is not officially supported by BennVenn, so please use this firmware updater at your own risk.")
283
+ self.lblUpdateDisclaimer = QtWidgets.QLabel("Please note that FlashGBX is not officially supported by BennVenn.")
276
284
  self.lblUpdateDisclaimer.setWordWrap(True)
277
285
  self.lblUpdateDisclaimer.setAlignment(QtGui.Qt.AlignmentFlag.AlignCenter)
278
286
  self.rowUpdate2.addWidget(self.lblUpdateDisclaimer)
@@ -467,7 +475,7 @@ try:
467
475
  msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
468
476
  answer = msgbox.exec()
469
477
  return False
470
- answer = QtWidgets.QMessageBox.information(self, "FlashGBX", "If your Joey Jr device is currently running the Drag'n'Drop firmware, please continue and choose its <b>MODE.TXT</b> file.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
478
+ answer = QtWidgets.QMessageBox.information(self, "FlashGBX", "If your Joey Jr device is currently running the Drag'n'Drop firmware, please continue and choose its <b>MODE.TXT</b> (or <b>MODE!.TXT</b>) file.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
471
479
  if answer == QtWidgets.QMessageBox.Cancel:
472
480
  self.SetStatus("No device found.", enableUI=True)
473
481
  return False
FlashGBX/hw_GBFlash.py CHANGED
@@ -9,7 +9,7 @@ class GbxDevice(LK_Device):
9
9
  DEVICE_NAME = "GBFlash"
10
10
  DEVICE_MIN_FW = 1
11
11
  DEVICE_MAX_FW = 12
12
- DEVICE_LATEST_FW_TS = { 5:1722759904, 10:1722759904, 11:1722759904, 12:1722759904, 13:1722759904 }
12
+ DEVICE_LATEST_FW_TS = { 5:1730731680, 10:1730731680, 11:1730731680, 12:1730731680, 13:1730731680 }
13
13
  PCB_VERSIONS = { 5:'', 12:'v1.2', 13:'v1.3' }
14
14
 
15
15
  def __init__(self):
@@ -111,8 +111,10 @@ class GbxDevice(LK_Device):
111
111
  self.FW["cart_power_ctrl"] = True if self._read(1) == 1 else False
112
112
 
113
113
  # Reset to bootloader support
114
- self.FW["bootloader_reset"] = True if self._read(1) == 1 else False
115
-
114
+ temp = self._read(1)
115
+ self.FW["bootloader_reset"] = True if temp & 1 == 1 else False
116
+ self.FW["unregistered"] = True if temp >> 7 == 1 else False
117
+
116
118
  return True
117
119
 
118
120
  except Exception as e:
@@ -192,7 +194,7 @@ class GbxDevice(LK_Device):
192
194
  return True
193
195
 
194
196
  def FirmwareUpdateAvailable(self):
195
- if self.FW["pcb_ver"] == 5: # unofficial firmware
197
+ if self.FW["pcb_ver"] == 5 or self.FW["fw_ts"] < 1730592000: # unofficial firmware
196
198
  self.FW_UPDATE_REQ = True
197
199
  return True
198
200
  if self.FW["fw_ts"] < self.DEVICE_LATEST_FW_TS[self.FW["pcb_ver"]]:
@@ -239,6 +241,13 @@ class GbxDevice(LK_Device):
239
241
 
240
242
  def GetFullName(self):
241
243
  if self.FW["pcb_ver"] < 13 and self.CanPowerCycleCart():
242
- return "{:s} {:s} + PLUGIN 01".format(self.GetName(), self.GetPCBVersion())
244
+ s = "{:s} {:s} + PLUGIN 01".format(self.GetName(), self.GetPCBVersion())
243
245
  else:
244
- return "{:s} {:s}".format(self.GetName(), self.GetPCBVersion())
246
+ s = "{:s} {:s}".format(self.GetName(), self.GetPCBVersion())
247
+ if self.IsUnregistered():
248
+ s += " (unregistered)"
249
+ return s
250
+
251
+ def GetRegisterInformation(self):
252
+ text = f"Your GBFlash device reported a registration error, which means it may be an illegitimate clone.\n\nThe device’s integrated piracy detection may limit the device in performance and functionality until proper registration. The {Util.APPNAME:s} software has no control over this.\n\nPlease visit <a href=\"https://gbflash.geeksimon.com/\">https://gbflash.geeksimon.com/</a> for more information.".replace("\n", "<br>")
253
+ return text
FlashGBX/hw_GBxCartRW.py CHANGED
@@ -9,13 +9,13 @@ class GbxDevice(LK_Device):
9
9
  DEVICE_NAME = "GBxCart RW"
10
10
  DEVICE_MIN_FW = 1
11
11
  DEVICE_MAX_FW = 1
12
- DEVICE_LATEST_FW_TS = { 4:1709317610, 5:1722759904, 6:1722759904, 2:0, 90:0, 100:0 }
12
+ DEVICE_LATEST_FW_TS = { 4:1709317610, 5:1722774120, 6:1722774120, 2:0, 90:0, 100:0 }
13
13
  PCB_VERSIONS = { 5:'v1.4', 6:'v1.4a/b/c', 2:'v1.1/v1.2', 4:'v1.3', 90:'XMAS v1.0', 100:'Mini v1.0' }
14
14
  BAUDRATE = 1000000
15
15
  MAX_BUFFER_READ = 0x1000
16
16
  MAX_BUFFER_WRITE = 0x400
17
17
 
18
- def Initialize(self, flashcarts, port=None, max_baud=2000000):
18
+ def Initialize(self, flashcarts=None, port=None, max_baud=2000000):
19
19
  if self.IsConnected(): self.DEVICE.close()
20
20
  if platform.system() == "Darwin": max_baud = 1000000
21
21
 
@@ -74,12 +74,15 @@ class GbxDevice(LK_Device):
74
74
  self.MAX_BUFFER_WRITE = 0x100
75
75
 
76
76
  conn_msg.append([0, "For help with your GBxCart RW device, please visit the insideGadgets Discord: https://gbxcart.com/discord"])
77
+ if self.FW["pcb_ver"] == 4:
78
+ conn_msg.append([0, "Note: Your GBxCart RW hardware revision does not fully support the latest features due to technical limitations. Please consider upgrading to a newer device."])
77
79
 
78
80
  self.PORT = ports[i]
79
81
  self.DEVICE.timeout = self.DEVICE_TIMEOUT
80
82
 
81
83
  # Load Flash Cartridge Handlers
82
- self.UpdateFlashCarts(flashcarts)
84
+ if flashcarts is not None:
85
+ self.UpdateFlashCarts(flashcarts)
83
86
 
84
87
  # Stop after first found device
85
88
  break
@@ -175,6 +178,7 @@ class GbxDevice(LK_Device):
175
178
  elif baudrate == 1000000:
176
179
  self._write(self.DEVICE_CMD["OFW_USART_1_0M_SPEED"])
177
180
  self.BAUDRATE = baudrate
181
+ self.DEVICE.close()
178
182
 
179
183
  def CheckActive(self):
180
184
  if time.time() < self.LAST_CHECK_ACTIVE + 1: return True
FlashGBX/hw_JoeyJr.py CHANGED
@@ -9,7 +9,7 @@ class GbxDevice(LK_Device):
9
9
  DEVICE_NAME = "Joey Jr"
10
10
  DEVICE_MIN_FW = 1
11
11
  DEVICE_MAX_FW = 12
12
- DEVICE_LATEST_FW_TS = 1722759904
12
+ DEVICE_LATEST_FW_TS = 1722774120
13
13
  PCB_VERSIONS = { -1:"", 0x01:"V2", 0x81:"V2", 0x02:"V2C", 0x82:"V2C", 0x03:"V2CC", 0x83:"V2CC/V2++" }
14
14
 
15
15
  def __init__(self):
@@ -11,6 +11,27 @@
11
11
  <p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>
12
12
  <p>Qt is The Qt Company Ltd product developed as an open source project. See <a href="https://qt.io/">qt.io</a> for more information.</p>
13
13
 
14
+ # Python
15
+
16
+ PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
17
+ --------------------------------------------
18
+
19
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using Python software in source or binary form and its associated documentation.
20
+
21
+ 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright © 2001-2021 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.
22
+
23
+ 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.
24
+
25
+ 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
26
+
27
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
28
+
29
+ 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.
30
+
31
+ 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.
32
+
33
+ 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement.
34
+
14
35
  # Pillow
15
36
 
16
37
  The Python Imaging Library (PIL) is
@@ -108,7 +129,6 @@ IN THE SOFTWARE.
108
129
 
109
130
  # requests
110
131
 
111
-
112
132
  Apache License
113
133
  Version 2.0, January 2004
114
134
  http://www.apache.org/licenses/
FlashGBX/res/config.zip CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FlashGBX
3
- Version: 4.1
3
+ Version: 4.3
4
4
  Summary: Reads and writes Game Boy and Game Boy Advance cartridge data
5
5
  Home-page: https://github.com/lesserkuma/FlashGBX
6
6
  Author: Lesserkuma
@@ -29,7 +29,7 @@ Requires-Dist: PySide6 ; extra == 'qt6'
29
29
 
30
30
  # FlashGBX (by Lesserkuma)
31
31
 
32
- for [Windows](https://github.com/lesserkuma/FlashGBX/releases), [Linux](https://github.com/lesserkuma/FlashGBX#run-using-python-linux-macos-windows), [macOS](https://github.com/lesserkuma/FlashGBX#run-using-python-linux-macos-windows)
32
+ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX/releases))
33
33
 
34
34
  <img src="https://raw.githubusercontent.com/lesserkuma/FlashGBX/master/.github/01.png" alt="FlashGBX on Windows 11" width="500"><br><img src="https://raw.githubusercontent.com/lesserkuma/FlashGBX/master/.github/02.png" alt="GB Camera Album Viewer" width="500">
35
35
 
@@ -44,37 +44,44 @@ for [Windows](https://github.com/lesserkuma/FlashGBX/releases), [Linux](https://
44
44
  - A flash chip query (including Common Flash Interface information) can be performed for flash cartridges
45
45
  - Decode and extract Game Boy Camera photos from save data
46
46
  - Generate ROM dump reports for game preservation purposes
47
- - Delta flashing support, useful for development by writing only differences between two ROMs (if named `rom.gba` and `rom.delta.gba`)
48
47
 
49
48
  ### Compatible cartridge reader/writer hardware
50
49
 
51
- - [GBxCart RW](https://www.gbxcart.com/) (tested with v1.3, v1.4, v1.4a and v1.4c)
50
+ - [GBxCart RW](https://www.gbxcart.com/) (tested with v1.4, v1.4a and v1.4c)
52
51
  - [GBFlash](https://github.com/simonkwng/GBFlash) (tested with v1.2 and v1.3)
53
52
  - [Joey Jr](https://bennvenn.myshopify.com/collections/game-cart-to-pc-interface/products/usb-gb-c-cart-dumper-the-joey-jr) (tested with V2++)
54
53
 
55
54
  ## Installing and running
56
55
 
57
- ### Windows Packages
56
+ ### Pre-compiled binaries and packages
58
57
 
59
- Available in the GitHub [Releases](https://github.com/lesserkuma/FlashGBX/releases) section:
58
+ Available in the GitHub [Releases](https://github.com/lesserkuma/FlashGBX/releases) section are pre-compiled downloads available for:
60
59
 
61
- * Windows Setup: An installer that will add the application to the start menu and optionally create a desktop icon
62
- * Windows Portable: Have everything in one place including the config files
60
+ * **Windows (64-bit)**
61
+ * Setup: An installer that will add the application to the start menu and optionally create a desktop icon
62
+ * Portable: Have everything in one place including the config files
63
+
64
+ *(For users of Windows 7, legacy “Qt5” versions are provided as well.)*
63
65
 
64
- These work for installing fresh and upgrading from an older version.
66
+ * **Linux**
67
+ * Ubuntu (.deb file): Install using `dpkg -i /path/to/FlashGBX_x.x_Ubuntu-all.deb`.<br>*(Based on a contribution by [JJ-Fox](https://github.com/JJ-Fox))*
68
+ * Other distributions: Pre-made packages are contributed by JJ-Fox [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
65
69
 
66
- ### Run using Python (Linux, macOS, Windows)
70
+ * **macOS**
71
+ * x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined during download. Run the following command in a Terminal window to unquarantine it: `xattr -d com.apple.quarantine /path/to/FlashGBX.app`.<br>*(Based on a contribution by [Cliffback](https://github.com/Cliffback))*
67
72
 
68
- #### Installing
73
+ *(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/lesserkuma/JoeyJr_FWUpdater) before using FlashGBX.)*
74
+
75
+ ### Run via Python
76
+
77
+ FlashGBX can also be run in a Python environment like so:
69
78
 
70
79
  1. Download and install [Python](https://www.python.org/downloads/) (version 3.10.11 is recommended)
71
80
  2. Open a Terminal or Command Prompt window
72
81
  3. Install FlashGBX with this command:<br>`pip3 install "FlashGBX[qt6]"`
73
82
  * If installation fails, try this command instead:<br>`pip3 install "FlashGBX[qt5]"`
74
83
  * If installation still fails, you can install the minimal version (command line interface) with this command:<br>`pip3 install FlashGBX`
75
-
76
- * Pre-made Linux packages and instructions for select distributions are available [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest), contributed by JJ-Fox.
77
- * Pre-made macOS packages and instructions are available [here](https://github.com/Cliffback/FlashGBX-macOS) (in the “Releases” section), contributed by Cliffback.
84
+ * Update to the latest version by replacing `install` with `install -U`.
78
85
 
79
86
  #### Running
80
87
  Use this command in a Terminal or Command Prompt window to launch the installed FlashGBX application:
@@ -85,11 +92,6 @@ Use this command in a Terminal or Command Prompt window to launch the installed
85
92
 
86
93
  *Note: On Linux systems, the `brltty` module may render serial communication devices non-accessible. See the troubleshooting section for details.*
87
94
 
88
- #### Upgrading from an older version
89
-
90
- 1. Open a Terminal or Command Prompt window
91
- 2. Enter this command:<br>`pip3 install -U FlashGBX`
92
-
93
95
  ## Cartridge Compatibility
94
96
  ### Supported cartridge memory mappers
95
97
  - Game Boy
@@ -114,6 +116,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
114
116
  - Unlicensed Xploder GB Mapper
115
117
  - Unlicensed Sachen Mapper
116
118
  - Unlicensed Datel Orbit V2 Mapper
119
+ - Unlicensed MBCX Mapper
117
120
 
118
121
  - Game Boy Advance
119
122
  - All cartridges without memory mapping
@@ -156,6 +159,8 @@ Use this command in a Terminal or Command Prompt window to launch the installed
156
159
  - GameShark Pro
157
160
  - GB-CART32K-A with SST39SF020A
158
161
  - GB Smart 32M
162
+ - GBFlash MBCX (8 MiB)
163
+ - GBFlash MBCX (32 MiB)
159
164
  - GBFlash RTC with MX29LV320EB
160
165
  - HDR Game Boy Camera Flashcart
161
166
  - insideGadgets 32 KiB
@@ -168,6 +173,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
168
173
  - insideGadgets 4 MiB, 128 KiB SRAM/FRAM
169
174
  - insideGadgets 4 MiB, 32 KiB FRAM, MBC3+RTC
170
175
  - insideGadgets 4 MiB (2× 2 MiB), 32 KiB FRAM, MBC5
176
+ - insideGadgets MegaDuck 32K
171
177
  - Mr Flash 64M
172
178
  - Sillyhatday MBC5-DUAL-FLASH-4/8MB
173
179
  - Squareboi 4 MiB (2× 2 MiB)
@@ -192,6 +198,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
192
198
  - FunnyPlaying MidnightTrace 32 MiB Flash Cart
193
199
  - GBA Movie Player v2 CF (with SST39VF400A)¹
194
200
  - GBFlash 1M FLASH RTC (AGB-R1M-02V3)
201
+ - GBFlash 1M FLASH RTC (AGB-R1M-02V4)
195
202
  - insideGadgets 16 MiB, 64K EEPROM with Solar Sensor and RTC options
196
203
  - insideGadgets 32 MiB, 1M FLASH with RTC option
197
204
  - insideGadgets 32 MiB, 512K FLASH
@@ -214,6 +221,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
214
221
  - DRV with AM29LV160DB and ALTERA CPLD
215
222
  - DRV with AM29LV160DT and ALTERA CPLD
216
223
  - DVP DRV with MX29LV320CB
224
+ - DVP DRV with MX29LV320CT
217
225
  - ES29LV160_DRV with 29DL32TF-70
218
226
  - GB-M968 with 29LV160DB
219
227
  - GB-M968 with M29W160EB
@@ -357,21 +365,23 @@ Many different reproduction cartridges share their flash chip command set, so ev
357
365
 
358
366
  * On some Linux systems like Fedora, you may need to install the `python3-pillow-qt` package manually in order for the GUI mode to work.
359
367
 
360
- * On some Linux systems you may see the message “No devices found.” with the GBxCart RW hardware device, even though you’re using a USB cable capable of data transfers. This may be caused by a module called `brltty` (a driver for refreshable braille displays) that is erroneously interfering and taking over control of any connected USB device that uses the CH340/341 chipset. The solution would be to uninstall or blacklist the `brltty` driver and then reboot the system.
368
+ * On some Linux systems you may see the message “No devices found.” with the GBxCart RW or GBFlash hardware device, even though you’re using a USB cable capable of data transfers. This may be caused by a module called `brltty` (a driver for refreshable braille displays) that is erroneously interfering and taking over control of any connected USB device that uses the CH340/341 chipset. The solution would be to uninstall or blacklist the `brltty` driver and then reboot the system. This is not an issue with Joey Jr devices.
361
369
 
362
370
  * If you’re using macOS version 10.13 or older, there may be no driver for serial communication devices installed on your system. You can either upgrade your macOS version to 10.14+ or manually install a driver which is available [here](https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver).
363
371
 
364
- * If you’re using macOS and get a “Segmentation Fault: 11.” error, try uninstalling Python, reinstalling Python version 3.10.11 and then try again.
372
+ * If you’re using macOS and get a “Segmentation Fault: 11.” error, try the “Run using Python method with Python version 3.10.11.
365
373
 
366
374
  ## Miscellaneous
367
375
 
368
376
  * To use your own frame around extracted Game Boy Camera pictures, place a file called `pc_frame.png` (must be at least 160×144 pixels) into the configuration directory. (GUI mode only)
369
377
 
378
+ * To write only the differences between two ROMs, name the original one `<name>.gba` and the edited one `<name>.delta.gba`.
379
+
370
380
  ## Contributors
371
381
 
372
382
  The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
373
383
 
374
- 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
384
+ 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, Mufsta, 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
375
385
 
376
386
  ## Third Party Notices and Licenses
377
387
 
@@ -0,0 +1,43 @@
1
+ FlashGBX/DataTransfer.py,sha256=bE4ZW3iQNceGMgS_SyDQKrXTZcdQxeRSni8GkxBtXIY,1750
2
+ FlashGBX/FlashGBX.py,sha256=3pwnNHEsNKKqL_039xZ1hh72XL6-zpe9MrqmkxQtZfA,12753
3
+ FlashGBX/FlashGBX_CLI.py,sha256=F_-xP28H--R589404wpJUZCeH0M-9FedfJDwMjojmDs,64718
4
+ FlashGBX/FlashGBX_GUI.py,sha256=R6lKNEs7FLfebfbasSYRQk06w0WlmmpJzK9RhdYHtiI,175565
5
+ FlashGBX/Flashcart.py,sha256=E1xKPm7j2Z2WQ0NnecGtia4DLNDTRcFbb8jOE3f5bKM,36416
6
+ FlashGBX/GBMemory.py,sha256=c1AMjW-TCtKfyexFLCS0pUA7dNmWyUXqUikN_QUf0MU,13320
7
+ FlashGBX/LK_Device.py,sha256=3xWNt-xsw9xqnD6osEHPc5r_B8PBA_97wt0vPCXcv8w,192955
8
+ FlashGBX/Mapper.py,sha256=IJxYjFqC8qlK2lNem3nhg_OkBPibJdiAsJLbwmjVW2A,57851
9
+ FlashGBX/PocketCamera.py,sha256=zLspGfQcX_fjplI54VPJXWk9dHP_3Ix99a4tqFU3Vf4,4898
10
+ FlashGBX/PocketCameraWindow.py,sha256=yVdc71JC55k42qynMpdyUSs6YjCz2EqBefY3Wiu9ERA,16229
11
+ FlashGBX/RomFileAGB.py,sha256=ad9WBGnPbW6a2y7B5R3rwizhocPFANMAwKCXJYBPQdA,8908
12
+ FlashGBX/RomFileDMG.py,sha256=H51C9ZmkS81j_7LuDE1TDVhsxKOBdZcXGPYM7oPh7NI,21627
13
+ FlashGBX/UserInputDialog.py,sha256=aYe3CeYlzQoCLI4DQulL5K9euB0HcMpcKZCFZfIJzqE,2911
14
+ FlashGBX/Util.py,sha256=X-fOeOOcensb2xoMjDPVDKVz3hJJY04gUZUTYSTo-mY,41718
15
+ FlashGBX/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ FlashGBX/__main__.py,sha256=L3ibKoTXOlTCepGzrgcktk_Jwp25xBCmGpNQO7W8Bbc,120
17
+ FlashGBX/fw_GBFlash.py,sha256=aNn8_jjGGWeDaRCSnXPbQ-e_JN98cn9-22Nv_waY3wA,15184
18
+ FlashGBX/fw_GBxCartRW_v1_3.py,sha256=qiYReJi1C-UDTjJVY0VujIsM5wPolnUrl_3TQYV-Drw,21498
19
+ FlashGBX/fw_GBxCartRW_v1_4.py,sha256=wVjjjdxY0ugg6B9e4QA_ErySdZCYHL3ljoQzWnheL6A,14259
20
+ FlashGBX/fw_JoeyJr.py,sha256=rLSz-LCVpl3a2Fheuynltx2D66KGwfwm-lrtTgriHmg,20999
21
+ FlashGBX/hw_GBFlash.py,sha256=oEuJfIury-HdT6EhZcDimd-IwWwKCGrFTsOL-UzPPFk,8335
22
+ FlashGBX/hw_GBxCartRW.py,sha256=9WQO6_WJQGWveN5qDvXja0aOYZ2Dh5U7NHKO0rWXB9I,11253
23
+ FlashGBX/hw_JoeyJr.py,sha256=1Bv9AD5cTGqIYgnjuPMW9BBLrLx59jMnyqVUv6H11jM,9334
24
+ FlashGBX/pyside.py,sha256=hlvYbV29AFJ1Epv0R41Sz-wuo4I9-gH8hgS8sfwJyCk,1662
25
+ FlashGBX/res/Third Party Notices.md,sha256=hTl66zRJfRgj20L6d4HxiFrBUXS0osI1cQIalJ1F_KY,21380
26
+ FlashGBX/res/config.zip,sha256=Mvmvyqv6E2xQzr7xISvmUwn3TFSBHyhUWH7EYwz2518,381599
27
+ FlashGBX/res/fw_GBFlash.zip,sha256=MFoqt6pLA5ZxGu8gwFN15COIB9-2JUpTnj2c2fAuqN0,18424
28
+ FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip,sha256=-QpHSw2JsjPG2WQ7E6mRqre4D3VThau2U7bFZYPY6r0,4774
29
+ FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip,sha256=ai6ithbSsEst22lCcDyJhr8KIlixqhg3HF4XV16Fdto,8093
30
+ FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip,sha256=H9tTjRMovpRkR89tUCsMMpwPslCoRml_cEWu8oYfMLs,8137
31
+ FlashGBX/res/fw_GBxCart_RW_v1_3.zip,sha256=zi2f7fdulQcSATuiIFMaCrpz3mCF5RGftVpbZNVedq0,15681
32
+ FlashGBX/res/fw_GBxCart_RW_v1_4.zip,sha256=5H2ZSDaxhJCzeYshKwj8CBDQPsxS30hJKuYbPEVYYtg,36772
33
+ FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=skp6LC3qvEyVZf7Txs8chSqsT-JoeZt0ZbvoqMb_3Lk,36260
34
+ FlashGBX/res/fw_JoeyJr.zip,sha256=quBrdbe3Kbr30_eP3nqix-ye4v8H5C3fvOZ7m-dxwes,69078
35
+ FlashGBX/res/icon.ico,sha256=2FNNCkh2W0IFQNYNdy8cmodh69NC0gYfpw81GZtr9rU,129959
36
+ FlashGBX/res/icon.png,sha256=WtE7XqPKr2538lw4gVbm6slWvMLJpwYjre8_z1q70GY,19286
37
+ FlashGBX/res/pc_frame.png,sha256=Hp8cUT_e7kc3-nrTD9ekB8gNVgKNEZRr75ggNDihJOg,653
38
+ FlashGBX-4.3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
39
+ FlashGBX-4.3.dist-info/METADATA,sha256=xJ7kIMkmMfX_kiVNEnLMhdEMqfFHg4zzGGYooHzMpEQ,19912
40
+ FlashGBX-4.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
41
+ FlashGBX-4.3.dist-info/entry_points.txt,sha256=lsg7RmPUIvEI_Q8bA3jIRh8MLF1qIBzUX_yEjD4lJ-g,52
42
+ FlashGBX-4.3.dist-info/top_level.txt,sha256=y6Ssb3YnEYYHNJIPsG_b5ifITM1STAyQXMpjtNOtyzA,9
43
+ FlashGBX-4.3.dist-info/RECORD,,