Skip to content

Instantly share code, notes, and snippets.

@iGlitch
Last active April 26, 2021 07:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iGlitch/e5f817986830c25c78f7 to your computer and use it in GitHub Desktop.
Save iGlitch/e5f817986830c25c78f7 to your computer and use it in GitHub Desktop.
Convert card1 3DS to card2
import os,sys,struct,subprocess
print("\ncard1to2\nby Glitch\nTrimming feature by Jdbye\n")
filename=sys.argv[1]
f=open(filename,"rb+")
MB=0x100000
def num2string(n,size):
ret=""
for i in range(size):
ret+=chr(n & 0xFF)
n>>=8
return ret
def string2list(n):
ret=[0x0]*len(n)
count=0
for i in n:
ret[count]=ord(n[count])
count+=1
return ret
def endianSwitch(n):
return n[::-1]
def hex2value(n):
return int(n.encode("hex"),16)
def grabData(off,size):
f.seek(off)
offset=f.read(size)
return offset
if hex2value(grabData(0x18D,1)) == 2:
choice=input("This game is already Card 2 type, but can be trimmed.\n\nW If you would like to adjust the save offset and trim the rom, type 1 then enter if you're ready (THIS WILL DELETE ANY EXISTING SAVE): ")
else:
choice=input("Card 1 type game detected.\n\nWould you like to convert it to a card 2 game that saves inside its the ROM?\nMake sure you backup any existing data before proceeding in case something goes wrong with the conversion. Enter 1 to convert: ")
if choice != 1:
print("Exiting...")
sys.exit()
if hex2value(grabData(0x18B,1)):
f.seek(0x18B)
f.write(chr(2))
f.seek(0x18D)
f.write(chr(2))
if hex2value(grabData(0x18F,1)):
f.seek(0x18F)
f.write(chr(2))
dataSize=0
dataSize=hex2value(endianSwitch(grabData(0x300,4)))
saveOffset=(dataSize / MB)*MB+MB
padOffset=saveOffset + (MB*16)
mediaUnitOffset=saveOffset / 0x200
f.seek(0x200)
f.write(num2string(mediaUnitOffset,4))
#print hex(dataSize),hex(saveOffset),hex(mediaUnitOffset)
print("\nDATASIZE: "+str(hex(dataSize)))
print("NEW CARD2 SAVE OFFSET: "+str(hex(saveOffset)))
print("NEW FILE SIZE: "+str(hex(padOffset)))
print
f.close()
print("Calling Trunc "+filename+" "+str(padOffset))
print(subprocess.check_output(['Trunc.exe', filename, str(padOffset)],stderr=subprocess.STDOUT,shell=True))
raw_input("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment