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/LK_Device.py
CHANGED
|
@@ -116,7 +116,7 @@ class LK_Device(ABC):
|
|
|
116
116
|
"AGB_IRQ_ENABLED":[8, 0x10],
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
ACTIONS = {"ROM_READ":1, "SAVE_READ":2, "SAVE_WRITE":3, "ROM_WRITE":4, "ROM_WRITE_VERIFY":4, "SAVE_WRITE_VERIFY":3, "RTC_WRITE":5}
|
|
119
|
+
ACTIONS = {"ROM_READ":1, "SAVE_READ":2, "SAVE_WRITE":3, "ROM_WRITE":4, "ROM_WRITE_VERIFY":4, "SAVE_WRITE_VERIFY":3, "RTC_WRITE":5, "DETECT_CART":6}
|
|
120
120
|
SUPPORTED_CARTS = {}
|
|
121
121
|
|
|
122
122
|
FW = {}
|
|
@@ -229,8 +229,14 @@ class LK_Device(ABC):
|
|
|
229
229
|
#################################################################
|
|
230
230
|
|
|
231
231
|
def IsSupportedMbc(self, mbc):
|
|
232
|
-
return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x201, 0x202, 0x203, 0x204, 0x205 )
|
|
232
|
+
return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206 )
|
|
233
233
|
|
|
234
|
+
def IsUnregistered(self):
|
|
235
|
+
if "unregistered" in self.FW:
|
|
236
|
+
return self.FW["unregistered"]
|
|
237
|
+
else:
|
|
238
|
+
return False
|
|
239
|
+
|
|
234
240
|
def TryConnect(self, port, baudrate):
|
|
235
241
|
dprint("Trying to connect to {:s} at baud rate {:d} ({:s})".format(port, baudrate, type(self).__module__))
|
|
236
242
|
try:
|
|
@@ -635,11 +641,11 @@ class LK_Device(ABC):
|
|
|
635
641
|
ret = self._read(1)
|
|
636
642
|
if ret != 0x01:
|
|
637
643
|
if ret is False:
|
|
638
|
-
msg = "Error: No response while trying to
|
|
644
|
+
msg = "Error: No response while trying to communicate with the device."
|
|
639
645
|
time.sleep(0.5)
|
|
640
646
|
self.DEVICE.reset_input_buffer()
|
|
641
647
|
else:
|
|
642
|
-
msg = "Error: Bad response “{:s}” while trying to
|
|
648
|
+
msg = "Error: Bad response “{:s}” while trying to communicate with the device.".format(str(ret))
|
|
643
649
|
print(f"{ANSI.RED}{msg}{ANSI.RESET}")
|
|
644
650
|
dprint(msg)
|
|
645
651
|
#self.CANCEL_ARGS.update({"info_type":"msgbox_critical", "info_msg":"A critical communication error occured during a write. Please avoid passive USB hubs, try different USB ports/cables and re-connect the device."})
|
|
@@ -741,7 +747,7 @@ class LK_Device(ABC):
|
|
|
741
747
|
if self.DEVICE.in_waiting == 0:
|
|
742
748
|
dprint("Waiting for ACK...")
|
|
743
749
|
hp -= 1
|
|
744
|
-
time.sleep(0.
|
|
750
|
+
time.sleep(0.1)
|
|
745
751
|
continue
|
|
746
752
|
temp = self.DEVICE.read(self.DEVICE.in_waiting)
|
|
747
753
|
if len(temp) >= 1: temp = temp[len(temp) - 1]
|
|
@@ -751,6 +757,13 @@ class LK_Device(ABC):
|
|
|
751
757
|
self._write(self.DEVICE_CMD["QUERY_CART_PWR"])
|
|
752
758
|
time.sleep(0.05)
|
|
753
759
|
hp -= 1
|
|
760
|
+
|
|
761
|
+
if hp == 0:
|
|
762
|
+
self.DEVICE.close()
|
|
763
|
+
self.DEVICE = None
|
|
764
|
+
self.ERROR = True
|
|
765
|
+
raise BrokenPipeError("Couldn’t power on the cartridge.")
|
|
766
|
+
|
|
754
767
|
self.DEVICE.timeout = self.DEVICE_TIMEOUT
|
|
755
768
|
|
|
756
769
|
self._write(self.DEVICE_CMD["QUERY_CART_PWR"])
|
|
@@ -854,21 +867,25 @@ class LK_Device(ABC):
|
|
|
854
867
|
def GetSupportedCartridgesAGB(self):
|
|
855
868
|
return (list(self.SUPPORTED_CARTS['AGB'].keys()), list(self.SUPPORTED_CARTS['AGB'].values()))
|
|
856
869
|
|
|
857
|
-
def SetProgress(self, args):
|
|
870
|
+
def SetProgress(self, args, signal=None):
|
|
858
871
|
if self.CANCEL and args["action"] not in ("ABORT", "FINISHED", "ERROR"): return
|
|
859
872
|
if "pos" in args: self.POS = args["pos"]
|
|
860
873
|
if args["action"] == "UPDATE_POS": self.INFO["transferred"] = args["pos"]
|
|
874
|
+
if signal is None:
|
|
875
|
+
signal = self.SIGNAL
|
|
876
|
+
|
|
861
877
|
try:
|
|
862
|
-
|
|
878
|
+
signal.emit(args)
|
|
863
879
|
except AttributeError:
|
|
864
|
-
if
|
|
865
|
-
|
|
880
|
+
if signal is not None:
|
|
881
|
+
signal(args)
|
|
866
882
|
|
|
867
883
|
if args["action"] == "INITIALIZE":
|
|
868
884
|
if self.CanPowerCycleCart(): self.CartPowerOn() # Ensure cart is powered
|
|
869
885
|
self.POS = 0
|
|
870
886
|
elif args["action"] == "FINISHED":
|
|
871
887
|
self.POS = 0
|
|
888
|
+
signal = None
|
|
872
889
|
self.SIGNAL = None
|
|
873
890
|
|
|
874
891
|
def Debug(self):
|
|
@@ -905,7 +922,7 @@ class LK_Device(ABC):
|
|
|
905
922
|
header = self.ReadROM(0, 0x180)
|
|
906
923
|
|
|
907
924
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
908
|
-
with open("debug_header.bin", "wb") as f: f.write(header)
|
|
925
|
+
with open(Util.CONFIG_PATH + "/debug_header.bin", "wb") as f: f.write(header)
|
|
909
926
|
|
|
910
927
|
# Parse ROM header
|
|
911
928
|
if self.MODE == "DMG":
|
|
@@ -1069,7 +1086,19 @@ class LK_Device(ABC):
|
|
|
1069
1086
|
|
|
1070
1087
|
return data
|
|
1071
1088
|
|
|
1072
|
-
def
|
|
1089
|
+
def _DetectCartridge(self, args): # Wrapper for thread call
|
|
1090
|
+
self.SetProgress({"action":"INITIALIZE", "abortable":False, "method":"DETECT_CART"})
|
|
1091
|
+
signal = self.SIGNAL
|
|
1092
|
+
self.SIGNAL = None
|
|
1093
|
+
ret = self.DoDetectCartridge(mbc=None, limitVoltage=args["limitVoltage"], checkSaveType=args["checkSaveType"], signal=signal)
|
|
1094
|
+
self.INFO["detect_cart"] = ret
|
|
1095
|
+
self.INFO["last_action"] = self.ACTIONS["DETECT_CART"]
|
|
1096
|
+
self.INFO["action"] = None
|
|
1097
|
+
self.SIGNAL = signal
|
|
1098
|
+
self.SetProgress({"action":"FINISHED"})
|
|
1099
|
+
return True
|
|
1100
|
+
|
|
1101
|
+
def DoDetectCartridge(self, mbc=None, limitVoltage=False, checkSaveType=True, signal=None):
|
|
1073
1102
|
self.SIGNAL = None
|
|
1074
1103
|
self.CANCEL = False
|
|
1075
1104
|
self.ERROR = False
|
|
@@ -1079,8 +1108,10 @@ class LK_Device(ABC):
|
|
|
1079
1108
|
sram_unstable = None
|
|
1080
1109
|
save_size = None
|
|
1081
1110
|
checkBatterylessSRAM = False
|
|
1111
|
+
_apot = 0
|
|
1082
1112
|
|
|
1083
1113
|
# Header
|
|
1114
|
+
if signal is not None: self.SetProgress({"action":"UPDATE_INFO", "text":"Detecting ROM..."}, signal=signal)
|
|
1084
1115
|
info = self.ReadInfo(checkRtc=True)
|
|
1085
1116
|
if self.MODE == "DMG" and mbc is None:
|
|
1086
1117
|
mbc = info["mapper_raw"]
|
|
@@ -1097,6 +1128,7 @@ class LK_Device(ABC):
|
|
|
1097
1128
|
self._set_fw_variable("AUTO_POWEROFF_TIME", 5000)
|
|
1098
1129
|
|
|
1099
1130
|
# Detect Flash Cart
|
|
1131
|
+
if signal is not None: self.SetProgress({"action":"UPDATE_INFO", "text":"Detecting Flash..."}, signal=signal)
|
|
1100
1132
|
ret = self.DetectFlash(limitVoltage=limitVoltage)
|
|
1101
1133
|
if ret is False: return False
|
|
1102
1134
|
(cart_types, cart_type_id, flash_id, cfi_s, cfi, detected_size) = ret
|
|
@@ -1113,6 +1145,7 @@ class LK_Device(ABC):
|
|
|
1113
1145
|
elif self.MODE == "AGB" and "flash_bank_select_type" in cart_type and cart_type["flash_bank_select_type"] > 1:
|
|
1114
1146
|
checkSaveType = False
|
|
1115
1147
|
elif self.MODE == "DMG" and "mbc" in cart_type and cart_type["mbc"] == 0x105: # G-MMC1
|
|
1148
|
+
if signal is not None: self.SetProgress({"action":"UPDATE_INFO", "text":"Detecting GB-Memory..."}, signal=signal)
|
|
1116
1149
|
header = self.ReadROM(0, 0x180)
|
|
1117
1150
|
data = RomFileDMG(header).GetHeader()
|
|
1118
1151
|
_mbc = DMG_MBC().GetInstance(args={"mbc":cart_type["mbc"]}, cart_write_fncptr=self._cart_write, cart_read_fncptr=self._cart_read, cart_powercycle_fncptr=self.CartPowerCycleOrAskReconnect, clk_toggle_fncptr=self._clk_toggle)
|
|
@@ -1131,6 +1164,7 @@ class LK_Device(ABC):
|
|
|
1131
1164
|
|
|
1132
1165
|
# Save Type and Size
|
|
1133
1166
|
if checkSaveType:
|
|
1167
|
+
if signal is not None: self.SetProgress({"action":"UPDATE_INFO", "text":"Detecting save type..."}, signal=signal)
|
|
1134
1168
|
if self.MODE == "DMG":
|
|
1135
1169
|
save_size = 131072
|
|
1136
1170
|
save_type = 0x04
|
|
@@ -1148,6 +1182,8 @@ class LK_Device(ABC):
|
|
|
1148
1182
|
args = { 'mode':2, 'path':None, 'mbc':mbc, 'save_type':save_type, 'rtc':False, 'detect':True }
|
|
1149
1183
|
elif self.MODE == "AGB":
|
|
1150
1184
|
args = { 'mode':2, 'path':None, 'mbc':mbc, 'save_type':8, 'rtc':False, 'detect':True }
|
|
1185
|
+
else:
|
|
1186
|
+
return
|
|
1151
1187
|
|
|
1152
1188
|
ret = self._BackupRestoreRAM(args=args)
|
|
1153
1189
|
|
|
@@ -1175,6 +1211,10 @@ class LK_Device(ABC):
|
|
|
1175
1211
|
if self.INFO["data"][i:i+3] != bytearray([self.INFO["data"][i]] * 3):
|
|
1176
1212
|
check = False
|
|
1177
1213
|
break
|
|
1214
|
+
|
|
1215
|
+
if self.INFO["data"][0:0x8000] == self.INFO["data"][0x8000:0x10000]: # MBCX
|
|
1216
|
+
check = True
|
|
1217
|
+
|
|
1178
1218
|
if check:
|
|
1179
1219
|
save_size = 32768
|
|
1180
1220
|
save_type = 0x03
|
|
@@ -1201,7 +1241,13 @@ class LK_Device(ABC):
|
|
|
1201
1241
|
if flash_save_id != 0 and flash_save_id in Util.AGB_Flash_Save_Chips:
|
|
1202
1242
|
save_size = Util.AGB_Flash_Save_Chips_Sizes[list(Util.AGB_Flash_Save_Chips).index(flash_save_id)]
|
|
1203
1243
|
save_chip = Util.AGB_Flash_Save_Chips[flash_save_id]
|
|
1204
|
-
|
|
1244
|
+
|
|
1245
|
+
if flash_save_id in (0xBF5B, 0xFFFF): # Bootlegs
|
|
1246
|
+
if self.INFO["data"][0:0x10000] == self.INFO["data"][0x10000:0x20000]:
|
|
1247
|
+
save_type = 4
|
|
1248
|
+
else:
|
|
1249
|
+
save_type = 5
|
|
1250
|
+
elif save_size == 131072:
|
|
1205
1251
|
save_type = 5
|
|
1206
1252
|
elif save_size == 65536:
|
|
1207
1253
|
save_type = 4
|
|
@@ -1395,6 +1441,8 @@ class LK_Device(ABC):
|
|
|
1395
1441
|
command = "DMG_CART_READ"
|
|
1396
1442
|
elif self.MODE == "AGB":
|
|
1397
1443
|
command = "AGB_CART_READ"
|
|
1444
|
+
else:
|
|
1445
|
+
raise NotImplementedError
|
|
1398
1446
|
|
|
1399
1447
|
for n in range(0, num):
|
|
1400
1448
|
self._write(self.DEVICE_CMD[command])
|
|
@@ -1944,7 +1992,7 @@ class LK_Device(ABC):
|
|
|
1944
1992
|
chunk_len = max_length if left > max_length else left
|
|
1945
1993
|
chunk_from = offset + chunk_pos
|
|
1946
1994
|
chunk_to = offset + chunk_pos + chunk_len
|
|
1947
|
-
dprint(f"Running CRC32 verification, comparing between source 0x{chunk_from:
|
|
1995
|
+
dprint(f"Running CRC32 verification, comparing between source 0x{chunk_from:X}~0x{chunk_to:X} and target 0x{address+chunk_pos:X}~0x{address+chunk_pos+chunk_len:X}")
|
|
1948
1996
|
crc32_expected = zlib.crc32(buffer[chunk_from:chunk_to])
|
|
1949
1997
|
|
|
1950
1998
|
for i in range(0, 2 if (reset is True and flashcart is not None) else 1): # for retrying with reset
|
|
@@ -2008,6 +2056,9 @@ class LK_Device(ABC):
|
|
|
2008
2056
|
self.SetAGBReadMethod(0)
|
|
2009
2057
|
self._write(self.DEVICE_CMD["SET_MODE_AGB"], wait=self.FW["fw_ver"] >= 12)
|
|
2010
2058
|
|
|
2059
|
+
else:
|
|
2060
|
+
raise NotImplementedError
|
|
2061
|
+
|
|
2011
2062
|
rom = self._cart_read(0, 8)
|
|
2012
2063
|
|
|
2013
2064
|
dprint("Resetting and unlocking all cart types")
|
|
@@ -2182,7 +2233,7 @@ class LK_Device(ABC):
|
|
|
2182
2233
|
flash_id_methods.append([we - 1, i, list(cmp), cfi_buffer, flash_id_cmds[i]["read_identifier"]])
|
|
2183
2234
|
|
|
2184
2235
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2185
|
-
with open("debug_cfi.bin", "wb") as f: f.write(cfi_buffer)
|
|
2236
|
+
with open(Util.CONFIG_PATH + "/debug_cfi.bin", "wb") as f: f.write(cfi_buffer)
|
|
2186
2237
|
try:
|
|
2187
2238
|
magic = "{:s}{:s}{:s}".format(chr(cfi_buffer[0x20]), chr(cfi_buffer[0x22]), chr(cfi_buffer[0x24]))
|
|
2188
2239
|
d_swap = (0, 0)
|
|
@@ -2199,7 +2250,7 @@ class LK_Device(ABC):
|
|
|
2199
2250
|
for j in range(0, len(cfi_buffer)):
|
|
2200
2251
|
cfi_buffer[j] = bitswap(cfi_buffer[j], d_swap[j2])
|
|
2201
2252
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2202
|
-
with open("debug_cfi_d0d1+d6d7.bin", "wb") as f: f.write(cfi_buffer)
|
|
2253
|
+
with open(Util.CONFIG_PATH + "/debug_cfi_d0d1+d6d7.bin", "wb") as f: f.write(cfi_buffer)
|
|
2203
2254
|
else:
|
|
2204
2255
|
cfi_buffer = None
|
|
2205
2256
|
except:
|
|
@@ -2281,6 +2332,8 @@ class LK_Device(ABC):
|
|
|
2281
2332
|
supp_flash_types = self.GetSupportedCartridgesDMG()
|
|
2282
2333
|
elif self.MODE == "AGB":
|
|
2283
2334
|
supp_flash_types = self.GetSupportedCartridgesAGB()
|
|
2335
|
+
else:
|
|
2336
|
+
raise NotImplementedError
|
|
2284
2337
|
|
|
2285
2338
|
if "flash_size" in supp_flash_types[1][flash_types[0]]:
|
|
2286
2339
|
size = supp_flash_types[1][flash_types[0]]["flash_size"]
|
|
@@ -2381,6 +2434,9 @@ class LK_Device(ABC):
|
|
|
2381
2434
|
def FlashROM(self, fncSetProgress=None, args=None):
|
|
2382
2435
|
self.DoTransfer(4, fncSetProgress, args)
|
|
2383
2436
|
|
|
2437
|
+
def DetectCartridge(self, fncSetProgress=None, args=None):
|
|
2438
|
+
self.DoTransfer(5, fncSetProgress, args)
|
|
2439
|
+
|
|
2384
2440
|
#################################################################
|
|
2385
2441
|
|
|
2386
2442
|
def _BackupROM(self, args):
|
|
@@ -2416,8 +2472,10 @@ class LK_Device(ABC):
|
|
|
2416
2472
|
|
|
2417
2473
|
# Firmware check L8
|
|
2418
2474
|
if self.FW["fw_ver"] < 8 and flashcart and "enable_pullups" in cart_type:
|
|
2419
|
-
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L8.", "abortable":False})
|
|
2420
|
-
return False
|
|
2475
|
+
#self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L8.", "abortable":False})
|
|
2476
|
+
#return False
|
|
2477
|
+
print("{:s}Note: This cartridge may not be fully compatible with your {:s} device running an old or legacy firmware version.{:s}".format(ANSI.YELLOW, self.FW["pcb_name"], ANSI.RESET))
|
|
2478
|
+
del(cart_type["enable_pullups"])
|
|
2421
2479
|
# Firmware check L8
|
|
2422
2480
|
|
|
2423
2481
|
buffer_len = 0x4000
|
|
@@ -2712,12 +2770,11 @@ class LK_Device(ABC):
|
|
|
2712
2770
|
pos_total += len(temp)
|
|
2713
2771
|
|
|
2714
2772
|
if "verify_write" in args:
|
|
2715
|
-
#if pos_total >= len(args["verify_write"]): break
|
|
2716
2773
|
check = args["verify_write"][pos_total-len(temp):pos_total]
|
|
2717
2774
|
if temp[:len(check)] != check:
|
|
2718
2775
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2719
2776
|
dprint("Writing 0x{:X} bytes to debug_verify_0x{:X}.bin".format(len(temp), pos_total-len(temp)))
|
|
2720
|
-
with open("debug_verify_0x{:X}.bin".format(pos_total-len(temp)), "ab") as f: f.write(temp)
|
|
2777
|
+
with open(Util.CONFIG_PATH + "/debug_verify_0x{:X}.bin".format(pos_total-len(temp)), "ab") as f: f.write(temp)
|
|
2721
2778
|
|
|
2722
2779
|
for i in range(0, pos_total):
|
|
2723
2780
|
if (i < len(args["verify_write"]) - 1) and (i < pos_total - 1) and args["verify_write"][i] != buffer[i]:
|
|
@@ -2818,7 +2875,7 @@ class LK_Device(ABC):
|
|
|
2818
2875
|
|
|
2819
2876
|
# Check for ROM loops
|
|
2820
2877
|
self.INFO["loop_detected"] = False
|
|
2821
|
-
temp =
|
|
2878
|
+
temp = len(buffer)
|
|
2822
2879
|
while temp > 0x4000:
|
|
2823
2880
|
temp = temp >> 1
|
|
2824
2881
|
if (buffer[0:0x4000] == buffer[temp:temp+0x4000]):
|
|
@@ -2861,6 +2918,8 @@ class LK_Device(ABC):
|
|
|
2861
2918
|
_agb_gpio = AGB_GPIO(args={"rtc":True}, cart_write_fncptr=self._cart_write, cart_read_fncptr=self._cart_read, cart_powercycle_fncptr=self.CartPowerCycleOrAskReconnect, clk_toggle_fncptr=self._clk_toggle)
|
|
2862
2919
|
if _agb_gpio.HasRTC() is not True: return False
|
|
2863
2920
|
ret = _agb_gpio.WriteRTCDict(args["rtc_dict"])
|
|
2921
|
+
else:
|
|
2922
|
+
raise NotImplementedError
|
|
2864
2923
|
return ret
|
|
2865
2924
|
|
|
2866
2925
|
def _BackupRestoreRAM(self, args):
|
|
@@ -2872,6 +2931,12 @@ class LK_Device(ABC):
|
|
|
2872
2931
|
empty_data_byte = 0x00
|
|
2873
2932
|
extra_size = 0
|
|
2874
2933
|
audio_low = False
|
|
2934
|
+
|
|
2935
|
+
# Initialization
|
|
2936
|
+
ram_banks = 0
|
|
2937
|
+
buffer_len = 0
|
|
2938
|
+
sram_5 = 0
|
|
2939
|
+
temp = None
|
|
2875
2940
|
|
|
2876
2941
|
cart_type = None
|
|
2877
2942
|
if "cart_type" in args and args["cart_type"] >= 0:
|
|
@@ -3052,6 +3117,7 @@ class LK_Device(ABC):
|
|
|
3052
3117
|
if args["rtc"] is True:
|
|
3053
3118
|
extra_size = 0x10
|
|
3054
3119
|
|
|
3120
|
+
action = None
|
|
3055
3121
|
if args["mode"] == 2: # Backup
|
|
3056
3122
|
action = "SAVE_READ"
|
|
3057
3123
|
buffer = bytearray()
|
|
@@ -3467,7 +3533,14 @@ class LK_Device(ABC):
|
|
|
3467
3533
|
return True
|
|
3468
3534
|
|
|
3469
3535
|
def _FlashROM(self, args):
|
|
3536
|
+
# Initialization
|
|
3470
3537
|
self.FAST_READ = True
|
|
3538
|
+
temp = None
|
|
3539
|
+
rom_bank_size = 0
|
|
3540
|
+
end_bank = 0
|
|
3541
|
+
pos_from = 0
|
|
3542
|
+
verify_len = 0
|
|
3543
|
+
|
|
3471
3544
|
if "buffer" in args:
|
|
3472
3545
|
data_import = args["buffer"]
|
|
3473
3546
|
else:
|
|
@@ -3549,13 +3622,17 @@ class LK_Device(ABC):
|
|
|
3549
3622
|
# Firmware check L5
|
|
3550
3623
|
# Firmware check L8
|
|
3551
3624
|
if (self.FW["fw_ver"] < 8 and "enable_pullups" in cart_type and cart_type["enable_pullups"] is True):
|
|
3552
|
-
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L8.", "abortable":False})
|
|
3553
|
-
return False
|
|
3625
|
+
#self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L8.", "abortable":False})
|
|
3626
|
+
#return False
|
|
3627
|
+
print("{:s}Note: This cartridge may not be fully compatible with your {:s} device running an old or legacy firmware version.{:s}".format(ANSI.YELLOW, self.FW["pcb_name"], ANSI.RESET))
|
|
3628
|
+
del(cart_type["enable_pullups"])
|
|
3554
3629
|
# Firmware check L8
|
|
3555
3630
|
# Firmware check L12
|
|
3556
3631
|
if (self.FW["fw_ver"] < 12 and "set_irq_high" in cart_type and cart_type["set_irq_high"] is True):
|
|
3557
|
-
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3558
|
-
return False
|
|
3632
|
+
#self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3633
|
+
#return False
|
|
3634
|
+
print("{:s}Note: This cartridge may not be fully compatible with your {:s} device running an old or legacy firmware version.{:s}".format(ANSI.YELLOW, self.FW["pcb_name"], ANSI.RESET))
|
|
3635
|
+
del(cart_type["set_irq_high"])
|
|
3559
3636
|
if (self.FW["fw_ver"] < 12 and "status_register_mask" in cart_type):
|
|
3560
3637
|
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3561
3638
|
return False
|
|
@@ -3704,7 +3781,7 @@ class LK_Device(ABC):
|
|
|
3704
3781
|
else:
|
|
3705
3782
|
dprint("Hidden sector data:", args["buffer_map"])
|
|
3706
3783
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
3707
|
-
with open("debug_mmsa_map.bin", "wb") as f: f.write(args["buffer_map"])
|
|
3784
|
+
with open(Util.CONFIG_PATH + "/debug_mmsa_map.bin", "wb") as f: f.write(args["buffer_map"])
|
|
3708
3785
|
data_map_import = copy.copy(args["buffer_map"])
|
|
3709
3786
|
data_map_import = bytearray(data_map_import)
|
|
3710
3787
|
dprint("Hidden sector data loaded")
|
|
@@ -4030,9 +4107,6 @@ class LK_Device(ABC):
|
|
|
4030
4107
|
sector_pos = sector_offsets.index(sector[:2])
|
|
4031
4108
|
start_bank = math.floor(buffer_pos / rom_bank_size)
|
|
4032
4109
|
end_bank = math.ceil((buffer_pos + sector[1]) / rom_bank_size)
|
|
4033
|
-
# print(hex(start_address), hex(end_address), start_bank, end_bank)
|
|
4034
|
-
# print(hex(sector_offsets[sector_pos][0]), sector_pos)
|
|
4035
|
-
# print("")
|
|
4036
4110
|
elif self.MODE == "DMG":
|
|
4037
4111
|
dprint("Writing sector:", hex(sector[0]), hex(sector[1]))
|
|
4038
4112
|
buffer_pos = sector[0]
|
|
@@ -4043,12 +4117,88 @@ class LK_Device(ABC):
|
|
|
4043
4117
|
sector_pos = sector_offsets.index(sector[:2])
|
|
4044
4118
|
start_bank = math.floor(buffer_pos / rom_bank_size)
|
|
4045
4119
|
end_bank = math.ceil((buffer_pos + sector[1]) / rom_bank_size)
|
|
4046
|
-
# print(hex(start_address), hex(end_address), start_bank, end_bank)
|
|
4047
|
-
# print(hex(sector_offsets[sector_pos][0]), sector_pos)
|
|
4048
|
-
# print("")
|
|
4049
4120
|
|
|
4050
|
-
#for bank in range(start_bank, end_bank):
|
|
4051
4121
|
bank = start_bank
|
|
4122
|
+
|
|
4123
|
+
# ↓↓↓ Check if data matches already
|
|
4124
|
+
if self.FW["fw_ver"] >= 10 and not (flashcart and cart_type["command_set"] == "GBAMP"):
|
|
4125
|
+
if "verify_write" in args and args["verify_write"] is True:
|
|
4126
|
+
buffer_pos_matchcheck = buffer_pos
|
|
4127
|
+
verified = False
|
|
4128
|
+
ts_se_start = time.time()
|
|
4129
|
+
while bank < end_bank:
|
|
4130
|
+
status = None
|
|
4131
|
+
# ↓↓↓ Switch ROM bank
|
|
4132
|
+
if self.MODE == "DMG":
|
|
4133
|
+
if _mbc.ResetBeforeBankChange(bank) is True:
|
|
4134
|
+
dprint("Resetting the MBC")
|
|
4135
|
+
self._write(self.DEVICE_CMD["DMG_MBC_RESET"], wait=True)
|
|
4136
|
+
(start_address, bank_size) = _mbc.SelectBankROM(bank)
|
|
4137
|
+
if flashcart.PulseResetAfterWrite():
|
|
4138
|
+
if bank == 0:
|
|
4139
|
+
if self.FW["fw_ver"] < 2:
|
|
4140
|
+
self._write(self.DEVICE_CMD["OFW_GB_CART_MODE"])
|
|
4141
|
+
else:
|
|
4142
|
+
self._write(self.DEVICE_CMD["SET_MODE_DMG"], wait=self.FW["fw_ver"] >= 12)
|
|
4143
|
+
self._write(self.DEVICE_CMD["DMG_MBC_RESET"], wait=True)
|
|
4144
|
+
# else:
|
|
4145
|
+
# self._write(self.DEVICE_CMD["OFW_GB_FLASH_BANK_1_COMMAND_WRITES"])
|
|
4146
|
+
self._set_fw_variable("DMG_ROM_BANK", bank)
|
|
4147
|
+
|
|
4148
|
+
buffer_len = min(buffer_len, bank_size)
|
|
4149
|
+
if "start_addr" in flashcart.CONFIG and bank == 0: start_address = flashcart.CONFIG["start_addr"]
|
|
4150
|
+
end_address = start_address + bank_size
|
|
4151
|
+
start_address += (buffer_pos % rom_bank_size)
|
|
4152
|
+
if end_address > start_address + sector[1]:
|
|
4153
|
+
end_address = start_address + sector[1]
|
|
4154
|
+
|
|
4155
|
+
elif self.MODE == "AGB":
|
|
4156
|
+
if "flash_bank_select_type" in cart_type and cart_type["flash_bank_select_type"] > 0:
|
|
4157
|
+
if bank != current_bank:
|
|
4158
|
+
flashcart.Reset(full_reset=True)
|
|
4159
|
+
flashcart.SelectBankROM(bank)
|
|
4160
|
+
temp = end_address - start_address
|
|
4161
|
+
start_address %= cart_type["flash_bank_size"]
|
|
4162
|
+
end_address = min(cart_type["flash_bank_size"], start_address + temp)
|
|
4163
|
+
current_bank = bank
|
|
4164
|
+
# ↑↑↑ Switch ROM bank
|
|
4165
|
+
|
|
4166
|
+
pos = start_address
|
|
4167
|
+
#dprint("pos=0x{:X}, buffer_pos=0x{:X}, start_address=0x{:X}, end_address=0x{:X}".format(pos, buffer_pos_matchcheck, start_address, end_address))
|
|
4168
|
+
verified = self.CompareCRC32(buffer=data_import, offset=buffer_pos_matchcheck, length=end_address - pos, address=pos, flashcart=flashcart, reset=True)
|
|
4169
|
+
self.SetProgress({"action":"UPDATE_POS", "pos":buffer_pos_matchcheck})
|
|
4170
|
+
if verified is not True:
|
|
4171
|
+
break
|
|
4172
|
+
buffer_pos_matchcheck += (end_address - pos)
|
|
4173
|
+
bank += 1
|
|
4174
|
+
|
|
4175
|
+
if verified is True:
|
|
4176
|
+
dprint("Skipping sector #{:d}, because the CRC32 matched".format(sector_pos))
|
|
4177
|
+
if flashcart.FlashCommandsOnBank1(): _mbc.SelectBankROM(bank)
|
|
4178
|
+
self.NO_PROG_UPDATE = True
|
|
4179
|
+
se_ret = flashcart.SectorErase(pos=pos, buffer_pos=buffer_pos, skip=verified)
|
|
4180
|
+
self.NO_PROG_UPDATE = False
|
|
4181
|
+
|
|
4182
|
+
if self.CANCEL:
|
|
4183
|
+
cancel_args = {"action":"ABORT", "abortable":False}
|
|
4184
|
+
cancel_args.update(self.CANCEL_ARGS)
|
|
4185
|
+
self.CANCEL_ARGS = {}
|
|
4186
|
+
self.ERROR_ARGS = {}
|
|
4187
|
+
self.SetProgress(cancel_args)
|
|
4188
|
+
if self.CanPowerCycleCart(): self.CartPowerCycle()
|
|
4189
|
+
return
|
|
4190
|
+
|
|
4191
|
+
ts_se_elapsed = time.time() - ts_se_start
|
|
4192
|
+
if se_ret:
|
|
4193
|
+
sector_size = se_ret
|
|
4194
|
+
dprint("Next sector size: 0x{:X}".format(sector_size))
|
|
4195
|
+
buffer_pos += sector_size
|
|
4196
|
+
continue
|
|
4197
|
+
else:
|
|
4198
|
+
verified = False
|
|
4199
|
+
bank = start_bank
|
|
4200
|
+
# ↑↑↑ Check if data matches already
|
|
4201
|
+
|
|
4052
4202
|
while bank < end_bank:
|
|
4053
4203
|
if self.CANCEL:
|
|
4054
4204
|
cancel_args = {"action":"ABORT", "abortable":False}
|
|
@@ -4116,44 +4266,20 @@ class LK_Device(ABC):
|
|
|
4116
4266
|
se_ret = None
|
|
4117
4267
|
if chip_erase is False:
|
|
4118
4268
|
if sector_pos < len(sector_offsets) and buffer_pos == sector_offsets[sector_pos][0]:
|
|
4119
|
-
len_rest = end_address - pos
|
|
4120
|
-
skip_se = False
|
|
4121
4269
|
ts_se_start = time.time()
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
skip_se = True
|
|
4126
|
-
elif verified is not True and len(verified) == 2:
|
|
4127
|
-
dprint("Writing sector #{:d}, because the CRC32 didn’t match: 0x{:X} ≠ 0x{:X}".format(sector_pos, verified[0], verified[1]))
|
|
4128
|
-
verified = False
|
|
4129
|
-
skip_se = False
|
|
4130
|
-
|
|
4131
|
-
if self.CANCEL:
|
|
4132
|
-
cancel_args = {"action":"ABORT", "abortable":False}
|
|
4133
|
-
cancel_args.update(self.CANCEL_ARGS)
|
|
4134
|
-
self.CANCEL_ARGS = {}
|
|
4135
|
-
self.ERROR_ARGS = {}
|
|
4136
|
-
self.SetProgress(cancel_args)
|
|
4137
|
-
if self.CanPowerCycleCart(): self.CartPowerCycle()
|
|
4138
|
-
return
|
|
4139
|
-
|
|
4140
|
-
if skip_se is True:
|
|
4141
|
-
dprint("Skipping sector #{:d}, because the CRC32 matched".format(sector_pos))
|
|
4142
|
-
self.SetProgress({"action":"UPDATE_POS", "pos":buffer_pos, "sector_pos":sector_pos, "force_update":True})
|
|
4143
|
-
else:
|
|
4144
|
-
if sector not in verify_sectors:
|
|
4145
|
-
verify_sectors.append(sector)
|
|
4146
|
-
dprint("Erasing sector #{:d} at position 0x{:X} (0x{:X})".format(sector_pos, buffer_pos, pos))
|
|
4147
|
-
self.SetProgress({"action":"UPDATE_POS", "pos":buffer_pos, "force_update":True})
|
|
4148
|
-
if self.CanPowerCycleCart(): self.CartPowerOn()
|
|
4270
|
+
dprint("Erasing sector #{:d} at position 0x{:X} (0x{:X})".format(sector_pos, buffer_pos, pos))
|
|
4271
|
+
self.SetProgress({"action":"UPDATE_POS", "pos":buffer_pos, "force_update":True})
|
|
4272
|
+
if self.CanPowerCycleCart(): self.CartPowerOn()
|
|
4149
4273
|
|
|
4150
4274
|
sector_pos += 1
|
|
4151
4275
|
if flashcart.FlashCommandsOnBank1(): _mbc.SelectBankROM(bank)
|
|
4152
4276
|
self.NO_PROG_UPDATE = True
|
|
4153
|
-
se_ret = flashcart.SectorErase(pos=pos, buffer_pos=buffer_pos, skip=
|
|
4277
|
+
se_ret = flashcart.SectorErase(pos=pos, buffer_pos=buffer_pos, skip=False)
|
|
4154
4278
|
self.NO_PROG_UPDATE = False
|
|
4155
4279
|
if "from_user" in self.CANCEL_ARGS and self.CANCEL_ARGS["from_user"]:
|
|
4156
4280
|
continue
|
|
4281
|
+
if sector not in verify_sectors:
|
|
4282
|
+
verify_sectors.append(sector)
|
|
4157
4283
|
|
|
4158
4284
|
ts_se_elapsed = time.time() - ts_se_start
|
|
4159
4285
|
if se_ret:
|
|
@@ -4161,11 +4287,6 @@ class LK_Device(ABC):
|
|
|
4161
4287
|
sector_size = se_ret
|
|
4162
4288
|
dprint("Next sector size: 0x{:X}".format(sector_size))
|
|
4163
4289
|
skip_init = False
|
|
4164
|
-
|
|
4165
|
-
if skip_se:
|
|
4166
|
-
buffer_pos += sector_size
|
|
4167
|
-
pos += sector_size
|
|
4168
|
-
continue
|
|
4169
4290
|
# ↑↑↑ Sector erase
|
|
4170
4291
|
|
|
4171
4292
|
if se_ret is not False:
|
|
@@ -4313,7 +4434,7 @@ class LK_Device(ABC):
|
|
|
4313
4434
|
if "verify_write" in args and args["verify_write"] is True:
|
|
4314
4435
|
self.SetProgress({"action":"INITIALIZE", "method":"ROM_WRITE_VERIFY", "size":len(data_import), "flash_offset":flash_offset})
|
|
4315
4436
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
4316
|
-
with open("debug_verify.bin", "wb") as f: pass
|
|
4437
|
+
with open(Util.CONFIG_PATH + "/debug_verify.bin", "wb") as f: pass
|
|
4317
4438
|
|
|
4318
4439
|
current_bank = None
|
|
4319
4440
|
broken_sectors = []
|
|
@@ -4502,6 +4623,8 @@ class LK_Device(ABC):
|
|
|
4502
4623
|
self.CANCEL_ARGS = {}
|
|
4503
4624
|
self.READ_ERRORS = 0
|
|
4504
4625
|
self.WRITE_ERRORS = 0
|
|
4626
|
+
_apot = 0
|
|
4627
|
+
|
|
4505
4628
|
if self.IsConnected():
|
|
4506
4629
|
_apoe = False
|
|
4507
4630
|
if self.CanPowerCycleCart():
|
|
@@ -4524,6 +4647,7 @@ class LK_Device(ABC):
|
|
|
4524
4647
|
elif args['mode'] == 2: ret = self._BackupRestoreRAM(args)
|
|
4525
4648
|
elif args['mode'] == 3: ret = self._BackupRestoreRAM(args)
|
|
4526
4649
|
elif args['mode'] == 4: ret = self._FlashROM(args)
|
|
4650
|
+
elif args['mode'] == 5: ret = self._DetectCartridge(args)
|
|
4527
4651
|
elif args['mode'] == 0xFF: self.Debug()
|
|
4528
4652
|
if self.FW is None: return False
|
|
4529
4653
|
if self.FW["fw_ver"] >= 2 and self.FW["pcb_name"] == "GBxCart RW":
|
FlashGBX/Mapper.py
CHANGED
|
@@ -75,8 +75,8 @@ class DMG_MBC:
|
|
|
75
75
|
return DMG_Unlicensed_Sachen(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr)
|
|
76
76
|
elif mbc_id == 0x205: # 0x205:'Datel Orbit V2',
|
|
77
77
|
return DMG_Unlicensed_DatelOrbitV2(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr)
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
elif mbc_id == 0x206: # 0x206:'MBCX',
|
|
79
|
+
return DMG_Unlicensed_MBCX(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr)
|
|
80
80
|
else:
|
|
81
81
|
self.__init__(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr)
|
|
82
82
|
return self
|
|
@@ -269,7 +269,7 @@ class DMG_MBC3(DMG_MBC):
|
|
|
269
269
|
|
|
270
270
|
def HasRTC(self):
|
|
271
271
|
dprint("Checking for RTC")
|
|
272
|
-
if self.MBC_ID not in (0x0F, 0x10, 0x110):
|
|
272
|
+
if self.MBC_ID not in (0x0F, 0x10, 0x110, 0x206):
|
|
273
273
|
dprint("No RTC because mapper value is not used for RTC:", self.MBC_ID)
|
|
274
274
|
return False
|
|
275
275
|
self.EnableRAM(enable=False)
|
|
@@ -831,6 +831,7 @@ class DMG_GMMC1(DMG_MBC5):
|
|
|
831
831
|
def CalcChecksum(self, buffer):
|
|
832
832
|
header = RomFileDMG(buffer[:0x180]).GetHeader()
|
|
833
833
|
target_chk_value = 0
|
|
834
|
+
target_sha1_value = 0
|
|
834
835
|
if header["game_title"] == "NP M-MENU MENU":
|
|
835
836
|
target_sha1_value = "15f5d445c0b2fdf4221cf2a986a4a5cb8dfda131"
|
|
836
837
|
target_chk_value = 0x19E8
|
|
@@ -1531,6 +1532,44 @@ class DMG_Unlicensed_DatelOrbitV2(DMG_MBC):
|
|
|
1531
1532
|
def GetMaxROMSize(self):
|
|
1532
1533
|
return 128*1024
|
|
1533
1534
|
|
|
1535
|
+
class DMG_Unlicensed_MBCX(DMG_MBC3):
|
|
1536
|
+
def GetName(self):
|
|
1537
|
+
return "MBCX"
|
|
1538
|
+
|
|
1539
|
+
def HasFlashBanks(self):
|
|
1540
|
+
return True
|
|
1541
|
+
|
|
1542
|
+
def SelectBankFlash(self, index):
|
|
1543
|
+
dprint(self.GetName(), "|SelectBankFlash()|", index)
|
|
1544
|
+
|
|
1545
|
+
commands = [
|
|
1546
|
+
[ 0x0000, 0x05 ],
|
|
1547
|
+
[ 0x4000, 0x82 ],
|
|
1548
|
+
[ 0xA000, index ],
|
|
1549
|
+
[ 0x0000, 0x00 ]
|
|
1550
|
+
]
|
|
1551
|
+
self.CURRENT_FLASH_BANK = index
|
|
1552
|
+
self.CartWrite(commands, delay=0.1)
|
|
1553
|
+
|
|
1554
|
+
def SelectBankROM(self, index):
|
|
1555
|
+
dprint(self.GetName(), index)
|
|
1556
|
+
|
|
1557
|
+
if (index % 512 == 0) or (self.CURRENT_FLASH_BANK != math.floor(index / 512)):
|
|
1558
|
+
self.SelectBankFlash(math.floor(index / 512))
|
|
1559
|
+
self.CURRENT_ROM_BANK = index
|
|
1560
|
+
index = index % 512
|
|
1561
|
+
|
|
1562
|
+
commands = [
|
|
1563
|
+
[ 0x3000, ((index >> 8) & 0xFF) ],
|
|
1564
|
+
[ 0x2100, index & 0xFF ],
|
|
1565
|
+
]
|
|
1566
|
+
|
|
1567
|
+
self.CartWrite(commands)
|
|
1568
|
+
return (0x4000, self.ROM_BANK_SIZE)
|
|
1569
|
+
|
|
1570
|
+
def GetMaxROMSize(self):
|
|
1571
|
+
return 32*1024*1024
|
|
1572
|
+
|
|
1534
1573
|
|
|
1535
1574
|
class AGB_GPIO:
|
|
1536
1575
|
CART_WRITE_FNCPTR = None
|
FlashGBX/PocketCamera.py
CHANGED
|
@@ -110,7 +110,7 @@ class PocketCamera:
|
|
|
110
110
|
offset = 0x2000 + (index * 0x1000)
|
|
111
111
|
elif index == 30:
|
|
112
112
|
offset = 0x11FC
|
|
113
|
-
|
|
113
|
+
else:
|
|
114
114
|
offset = 0
|
|
115
115
|
imgbuffer = self.DATA[offset:offset+0x1000]
|
|
116
116
|
return self.ConvertPicture(imgbuffer)
|
|
@@ -138,7 +138,7 @@ class PocketCamera:
|
|
|
138
138
|
frame.paste(pic, (left, top))
|
|
139
139
|
pic = frame
|
|
140
140
|
|
|
141
|
-
pic = pic.resize((pic.width * scale, pic.height * scale), Image.NEAREST)
|
|
141
|
+
pic = pic.resize((pic.width * scale, pic.height * scale), Image.Resampling.NEAREST)
|
|
142
142
|
|
|
143
143
|
ext = os.path.splitext(path)[1]
|
|
144
144
|
if ext == "" or ext.lower() == ".png":
|
FlashGBX/PocketCameraWindow.py
CHANGED
|
@@ -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;")
|