tja2fumen.py
: Convert tabs to spaces
This commit is contained in:
parent
7e7591e688
commit
9b1ee88510
@ -5,184 +5,184 @@ fumen2osu_version = "v1.4"
|
|||||||
branchNames = ("normal", "advanced", "master")
|
branchNames = ("normal", "advanced", "master")
|
||||||
|
|
||||||
def readFumen(inputFile, byteOrder=None, debug=False):
|
def readFumen(inputFile, byteOrder=None, debug=False):
|
||||||
if type(inputFile) is str:
|
if type(inputFile) is str:
|
||||||
file = open(inputFile, "rb")
|
file = open(inputFile, "rb")
|
||||||
else:
|
else:
|
||||||
file = inputFile
|
file = inputFile
|
||||||
size = os.fstat(file.fileno()).st_size
|
size = os.fstat(file.fileno()).st_size
|
||||||
|
|
||||||
noteTypes = {
|
noteTypes = {
|
||||||
0x1: "Don", # ドン
|
0x1: "Don", # ドン
|
||||||
0x2: "Don", # ド
|
0x2: "Don", # ド
|
||||||
0x3: "Don", # コ
|
0x3: "Don", # コ
|
||||||
0x4: "Ka", # カッ
|
0x4: "Ka", # カッ
|
||||||
0x5: "Ka", # カ
|
0x5: "Ka", # カ
|
||||||
0x6: "Drumroll",
|
0x6: "Drumroll",
|
||||||
0x7: "DON",
|
0x7: "DON",
|
||||||
0x8: "KA",
|
0x8: "KA",
|
||||||
0x9: "DRUMROLL",
|
0x9: "DRUMROLL",
|
||||||
0xa: "Balloon",
|
0xa: "Balloon",
|
||||||
0xb: "DON", # hands
|
0xb: "DON", # hands
|
||||||
0xc: "Kusudama",
|
0xc: "Kusudama",
|
||||||
0xd: "KA", # hands
|
0xd: "KA", # hands
|
||||||
0x62: "Drumroll" # ?
|
0x62: "Drumroll" # ?
|
||||||
}
|
}
|
||||||
song = {}
|
song = {}
|
||||||
|
|
||||||
def readStruct(format, seek=None):
|
def readStruct(format, seek=None):
|
||||||
if seek:
|
if seek:
|
||||||
file.seek(seek)
|
file.seek(seek)
|
||||||
return struct.unpack(order + format, file.read(struct.calcsize(order + format)))
|
return struct.unpack(order + format, file.read(struct.calcsize(order + format)))
|
||||||
|
|
||||||
if byteOrder:
|
if byteOrder:
|
||||||
order = ">" if byteOrder == "big" else "<"
|
order = ">" if byteOrder == "big" else "<"
|
||||||
totalMeasures = readStruct("I", 0x200)[0]
|
totalMeasures = readStruct("I", 0x200)[0]
|
||||||
else:
|
else:
|
||||||
order = ""
|
order = ""
|
||||||
measuresBig = readStruct(">I", 0x200)[0]
|
measuresBig = readStruct(">I", 0x200)[0]
|
||||||
measuresLittle = readStruct("<I", 0x200)[0]
|
measuresLittle = readStruct("<I", 0x200)[0]
|
||||||
if measuresBig < measuresLittle:
|
if measuresBig < measuresLittle:
|
||||||
order = ">"
|
order = ">"
|
||||||
totalMeasures = measuresBig
|
totalMeasures = measuresBig
|
||||||
else:
|
else:
|
||||||
order = "<"
|
order = "<"
|
||||||
totalMeasures = measuresLittle
|
totalMeasures = measuresLittle
|
||||||
|
|
||||||
hasBranches = getBool(readStruct("B", 0x1b0)[0])
|
hasBranches = getBool(readStruct("B", 0x1b0)[0])
|
||||||
song["branches"] = hasBranches
|
song["branches"] = hasBranches
|
||||||
if debug:
|
if debug:
|
||||||
debugPrint("Total measures: {0}, {1} branches, {2}-endian".format(
|
debugPrint("Total measures: {0}, {1} branches, {2}-endian".format(
|
||||||
totalMeasures,
|
totalMeasures,
|
||||||
"has" if hasBranches else "no",
|
"has" if hasBranches else "no",
|
||||||
"Big" if order == ">" else "Little"
|
"Big" if order == ">" else "Little"
|
||||||
))
|
))
|
||||||
|
|
||||||
file.seek(0x208)
|
file.seek(0x208)
|
||||||
for measureNumber in range(totalMeasures):
|
for measureNumber in range(totalMeasures):
|
||||||
measure = {}
|
measure = {}
|
||||||
# measureStruct: bpm 4, offset 4, gogo 1, hidden 1, dummy 2, branchInfo 4 * 6, dummy 4
|
# measureStruct: bpm 4, offset 4, gogo 1, hidden 1, dummy 2, branchInfo 4 * 6, dummy 4
|
||||||
measureStruct = readStruct("ffBBHiiiiiii")
|
measureStruct = readStruct("ffBBHiiiiiii")
|
||||||
measure["bpm"] = measureStruct[0]
|
measure["bpm"] = measureStruct[0]
|
||||||
measure["fumenOffset"] = measureStruct[1]
|
measure["fumenOffset"] = measureStruct[1]
|
||||||
if measureNumber == 0:
|
if measureNumber == 0:
|
||||||
measure["offset"] = measure["fumenOffset"] + 240000 / measure["bpm"]
|
measure["offset"] = measure["fumenOffset"] + 240000 / measure["bpm"]
|
||||||
else:
|
else:
|
||||||
prev = song[measureNumber - 1]
|
prev = song[measureNumber - 1]
|
||||||
measure["offset"] = prev["offset"] + measure["fumenOffset"] + 240000 / measure["bpm"] - prev["fumenOffset"] - 240000 / prev["bpm"]
|
measure["offset"] = prev["offset"] + measure["fumenOffset"] + 240000 / measure["bpm"] - prev["fumenOffset"] - 240000 / prev["bpm"]
|
||||||
measure["gogo"] = getBool(measureStruct[2])
|
measure["gogo"] = getBool(measureStruct[2])
|
||||||
measure["hidden"] = getBool(measureStruct[3])
|
measure["hidden"] = getBool(measureStruct[3])
|
||||||
|
|
||||||
for branchNumber in range(3):
|
for branchNumber in range(3):
|
||||||
branch = {}
|
branch = {}
|
||||||
# branchStruct: totalNotes 2, dummy 2, speed 4
|
# branchStruct: totalNotes 2, dummy 2, speed 4
|
||||||
branchStruct = readStruct("HHf")
|
branchStruct = readStruct("HHf")
|
||||||
totalNotes = branchStruct[0]
|
totalNotes = branchStruct[0]
|
||||||
branch["speed"] = branchStruct[2]
|
branch["speed"] = branchStruct[2]
|
||||||
|
|
||||||
if debug and (hasBranches or branchNumber == 0 or totalNotes != 0):
|
if debug and (hasBranches or branchNumber == 0 or totalNotes != 0):
|
||||||
branchName = " ({0})".format(
|
branchName = " ({0})".format(
|
||||||
branchNames[branchNumber]
|
branchNames[branchNumber]
|
||||||
) if hasBranches or branchNumber != 0 else ""
|
) if hasBranches or branchNumber != 0 else ""
|
||||||
fileOffset = file.tell()
|
fileOffset = file.tell()
|
||||||
debugPrint("")
|
debugPrint("")
|
||||||
debugPrint("Measure #{0}{1} at {2}-{3} ({4})".format(
|
debugPrint("Measure #{0}{1} at {2}-{3} ({4})".format(
|
||||||
measureNumber + 1,
|
measureNumber + 1,
|
||||||
branchName,
|
branchName,
|
||||||
shortHex(fileOffset - 0x8),
|
shortHex(fileOffset - 0x8),
|
||||||
shortHex(fileOffset + 0x18 * totalNotes),
|
shortHex(fileOffset + 0x18 * totalNotes),
|
||||||
nameValue(measure, branch)
|
nameValue(measure, branch)
|
||||||
))
|
))
|
||||||
debugPrint("Total notes: {0}".format(totalNotes))
|
debugPrint("Total notes: {0}".format(totalNotes))
|
||||||
|
|
||||||
for noteNumber in range(totalNotes):
|
for noteNumber in range(totalNotes):
|
||||||
if debug:
|
if debug:
|
||||||
fileOffset = file.tell()
|
fileOffset = file.tell()
|
||||||
debugPrint("Note #{0} at {1}-{2}".format(
|
debugPrint("Note #{0} at {1}-{2}".format(
|
||||||
noteNumber + 1,
|
noteNumber + 1,
|
||||||
shortHex(fileOffset),
|
shortHex(fileOffset),
|
||||||
shortHex(fileOffset + 0x17)
|
shortHex(fileOffset + 0x17)
|
||||||
), end="")
|
), end="")
|
||||||
|
|
||||||
note = {}
|
note = {}
|
||||||
# noteStruct: type 4, pos 4, item 4, dummy 4, init 2, diff 2, duration 4
|
# noteStruct: type 4, pos 4, item 4, dummy 4, init 2, diff 2, duration 4
|
||||||
noteStruct = readStruct("ififHHf")
|
noteStruct = readStruct("ififHHf")
|
||||||
noteType = noteStruct[0]
|
noteType = noteStruct[0]
|
||||||
|
|
||||||
if noteType not in noteTypes:
|
if noteType not in noteTypes:
|
||||||
if debug:
|
if debug:
|
||||||
debugPrint("")
|
debugPrint("")
|
||||||
debugPrint("Error: Unknown note type '{0}' at offset {1}".format(
|
debugPrint("Error: Unknown note type '{0}' at offset {1}".format(
|
||||||
shortHex(noteType).upper(),
|
shortHex(noteType).upper(),
|
||||||
hex(file.tell() - 0x18))
|
hex(file.tell() - 0x18))
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
note["type"] = noteTypes[noteType]
|
note["type"] = noteTypes[noteType]
|
||||||
note["pos"] = noteStruct[1]
|
note["pos"] = noteStruct[1]
|
||||||
|
|
||||||
if noteType == 0xa or noteType == 0xc:
|
if noteType == 0xa or noteType == 0xc:
|
||||||
# Balloon hits
|
# Balloon hits
|
||||||
note["hits"] = noteStruct[4]
|
note["hits"] = noteStruct[4]
|
||||||
elif "scoreInit" not in song:
|
elif "scoreInit" not in song:
|
||||||
song["scoreInit"] = noteStruct[4]
|
song["scoreInit"] = noteStruct[4]
|
||||||
song["scoreDiff"] = noteStruct[5] / 4.0
|
song["scoreDiff"] = noteStruct[5] / 4.0
|
||||||
|
|
||||||
if noteType == 0x6 or noteType == 0x9 or noteType == 0xa or noteType == 0xc:
|
if noteType == 0x6 or noteType == 0x9 or noteType == 0xa or noteType == 0xc:
|
||||||
# Drumroll and balloon duration in ms
|
# Drumroll and balloon duration in ms
|
||||||
note["duration"] = noteStruct[6]
|
note["duration"] = noteStruct[6]
|
||||||
branch[noteNumber] = note
|
branch[noteNumber] = note
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
debugPrint(" ({0})".format(nameValue(note)))
|
debugPrint(" ({0})".format(nameValue(note)))
|
||||||
|
|
||||||
if noteType == 0x6 or noteType == 0x9 or noteType == 0x62:
|
if noteType == 0x6 or noteType == 0x9 or noteType == 0x62:
|
||||||
# Drumrolls have 8 dummy bytes at the end
|
# Drumrolls have 8 dummy bytes at the end
|
||||||
file.seek(0x8, os.SEEK_CUR)
|
file.seek(0x8, os.SEEK_CUR)
|
||||||
|
|
||||||
branch["length"] = totalNotes
|
branch["length"] = totalNotes
|
||||||
measure[branchNames[branchNumber]] = branch
|
measure[branchNames[branchNumber]] = branch
|
||||||
|
|
||||||
song[measureNumber] = measure
|
song[measureNumber] = measure
|
||||||
if file.tell() >= size:
|
if file.tell() >= size:
|
||||||
break
|
break
|
||||||
|
|
||||||
song["length"] = totalMeasures
|
song["length"] = totalMeasures
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
return song
|
return song
|
||||||
|
|
||||||
def writeOsu(song, globalOffset=0, title=None, subtitle="", wave=None, selectedBranch=None, outputFile=None, inputFile=None):
|
def writeOsu(song, globalOffset=0, title=None, subtitle="", wave=None, selectedBranch=None, outputFile=None, inputFile=None):
|
||||||
if not song or len(song) == 0:
|
if not song or len(song) == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if inputFile:
|
if inputFile:
|
||||||
if type(inputFile) is str:
|
if type(inputFile) is str:
|
||||||
filename = inputFile
|
filename = inputFile
|
||||||
else:
|
else:
|
||||||
filename = inputFile.name
|
filename = inputFile.name
|
||||||
filenameNoExt = os.path.splitext(filename)[0]
|
filenameNoExt = os.path.splitext(filename)[0]
|
||||||
title = title or filenameNoExt
|
title = title or filenameNoExt
|
||||||
wave = wave or "SONG_{0}.wav".format(
|
wave = wave or "SONG_{0}.wav".format(
|
||||||
filenameNoExt.split("_")[0].upper()
|
filenameNoExt.split("_")[0].upper()
|
||||||
)
|
)
|
||||||
outputFile = outputFile or "{0}.osu".format(filenameNoExt)
|
outputFile = outputFile or "{0}.osu".format(filenameNoExt)
|
||||||
else:
|
else:
|
||||||
title = title or "Song Title"
|
title = title or "Song Title"
|
||||||
wave = wave or "song.wav"
|
wave = wave or "song.wav"
|
||||||
|
|
||||||
if song["branches"] == True:
|
if song["branches"] == True:
|
||||||
if selectedBranch not in branchNames:
|
if selectedBranch not in branchNames:
|
||||||
selectedBranch = branchNames[-1]
|
selectedBranch = branchNames[-1]
|
||||||
debugPrint("Warning: Using the {0} branch in a branched song.".format(selectedBranch))
|
debugPrint("Warning: Using the {0} branch in a branched song.".format(selectedBranch))
|
||||||
else:
|
else:
|
||||||
selectedBranch = branchNames[0]
|
selectedBranch = branchNames[0]
|
||||||
|
|
||||||
osu = []
|
osu = []
|
||||||
osu.append(b"""osu file format v14
|
osu.append(b"""osu file format v14
|
||||||
|
|
||||||
[General]""")
|
[General]""")
|
||||||
osu.append(b"AudioFilename: " + bytes(wave, "utf8"))
|
osu.append(b"AudioFilename: " + bytes(wave, "utf8"))
|
||||||
osu.append(b"""AudioLeadIn: 0
|
osu.append(b"""AudioLeadIn: 0
|
||||||
PreviewTime: 0
|
PreviewTime: 0
|
||||||
CountDown: 0
|
CountDown: 0
|
||||||
SampleSet: Normal
|
SampleSet: Normal
|
||||||
@ -198,11 +198,11 @@ GridSize: 4
|
|||||||
TimelineZoom: 1
|
TimelineZoom: 1
|
||||||
|
|
||||||
[Metadata]""")
|
[Metadata]""")
|
||||||
osu.append(b"Title:" + bytes(title, "utf8"))
|
osu.append(b"Title:" + bytes(title, "utf8"))
|
||||||
osu.append(b"TitleUnicode:" + bytes(title, "utf8"))
|
osu.append(b"TitleUnicode:" + bytes(title, "utf8"))
|
||||||
osu.append(b"Artist:" + bytes(subtitle, "utf8"))
|
osu.append(b"Artist:" + bytes(subtitle, "utf8"))
|
||||||
osu.append(b"ArtistUnicode:" + bytes(subtitle, "utf8"))
|
osu.append(b"ArtistUnicode:" + bytes(subtitle, "utf8"))
|
||||||
osu.append(b"""Creator:
|
osu.append(b"""Creator:
|
||||||
Version:
|
Version:
|
||||||
Source:
|
Source:
|
||||||
Tags:
|
Tags:
|
||||||
@ -216,180 +216,180 @@ SliderMultiplier:1.4
|
|||||||
SliderTickRate:4
|
SliderTickRate:4
|
||||||
|
|
||||||
[TimingPoints]""")
|
[TimingPoints]""")
|
||||||
globalOffset = globalOffset * 1000.0
|
globalOffset = globalOffset * 1000.0
|
||||||
for i in range(song["length"]):
|
for i in range(song["length"]):
|
||||||
prevMeasure = song[i - 1] if i != 0 else None
|
prevMeasure = song[i - 1] if i != 0 else None
|
||||||
prevBranch = prevMeasure[selectedBranch] if i != 0 else None
|
prevBranch = prevMeasure[selectedBranch] if i != 0 else None
|
||||||
measure = song[i]
|
measure = song[i]
|
||||||
branch = measure[selectedBranch]
|
branch = measure[selectedBranch]
|
||||||
if i == 0 or prevMeasure["bpm"] != measure["bpm"] or prevMeasure["gogo"] != measure["gogo"] or prevBranch["speed"] != branch["speed"]:
|
if i == 0 or prevMeasure["bpm"] != measure["bpm"] or prevMeasure["gogo"] != measure["gogo"] or prevBranch["speed"] != branch["speed"]:
|
||||||
offset = measure["offset"] - globalOffset
|
offset = measure["offset"] - globalOffset
|
||||||
gogo = 1 if measure["gogo"] else 0
|
gogo = 1 if measure["gogo"] else 0
|
||||||
if i == 0 or prevMeasure["bpm"] != measure["bpm"]:
|
if i == 0 or prevMeasure["bpm"] != measure["bpm"]:
|
||||||
msPerBeat = 1000 / measure["bpm"] * 60
|
msPerBeat = 1000 / measure["bpm"] * 60
|
||||||
osu.append(bytes("{0},{1},4,1,0,100,1,{2}".format(
|
osu.append(bytes("{0},{1},4,1,0,100,1,{2}".format(
|
||||||
int(offset),
|
int(offset),
|
||||||
msPerBeat,
|
msPerBeat,
|
||||||
gogo
|
gogo
|
||||||
), "ascii"))
|
), "ascii"))
|
||||||
if branch["speed"] != 1 or i != 0 and (prevBranch["speed"] != branch["speed"] or prevMeasure["bpm"] == measure["bpm"]):
|
if branch["speed"] != 1 or i != 0 and (prevBranch["speed"] != branch["speed"] or prevMeasure["bpm"] == measure["bpm"]):
|
||||||
msPerBeat = -100 / branch["speed"]
|
msPerBeat = -100 / branch["speed"]
|
||||||
osu.append(bytes("{0},{1},4,1,0,100,1,{2}".format(
|
osu.append(bytes("{0},{1},4,1,0,100,1,{2}".format(
|
||||||
int(offset),
|
int(offset),
|
||||||
msPerBeat,
|
msPerBeat,
|
||||||
gogo
|
gogo
|
||||||
), "ascii"))
|
), "ascii"))
|
||||||
osu.append(b"""
|
osu.append(b"""
|
||||||
|
|
||||||
[HitObjects]""")
|
[HitObjects]""")
|
||||||
osuSounds = {
|
osuSounds = {
|
||||||
"Don": 0,
|
"Don": 0,
|
||||||
"Ka": 8,
|
"Ka": 8,
|
||||||
"DON": 4,
|
"DON": 4,
|
||||||
"KA": 12,
|
"KA": 12,
|
||||||
"Drumroll": 0,
|
"Drumroll": 0,
|
||||||
"DRUMROLL": 4,
|
"DRUMROLL": 4,
|
||||||
"Balloon": 0,
|
"Balloon": 0,
|
||||||
"Kusudama": 0
|
"Kusudama": 0
|
||||||
}
|
}
|
||||||
for i in range(song["length"]):
|
for i in range(song["length"]):
|
||||||
measure = song[i]
|
measure = song[i]
|
||||||
branch = song[i][selectedBranch]
|
branch = song[i][selectedBranch]
|
||||||
for j in range(branch["length"]):
|
for j in range(branch["length"]):
|
||||||
note = branch[j]
|
note = branch[j]
|
||||||
noteType = note["type"]
|
noteType = note["type"]
|
||||||
offset = measure["offset"] + note["pos"] - globalOffset
|
offset = measure["offset"] + note["pos"] - globalOffset
|
||||||
if noteType == "Don" or noteType == "Ka" or noteType == "DON" or noteType == "KA":
|
if noteType == "Don" or noteType == "Ka" or noteType == "DON" or noteType == "KA":
|
||||||
sound = osuSounds[noteType]
|
sound = osuSounds[noteType]
|
||||||
osu.append(bytes("416,176,{0},1,{1},0:0:0:0:".format(
|
osu.append(bytes("416,176,{0},1,{1},0:0:0:0:".format(
|
||||||
int(offset),
|
int(offset),
|
||||||
sound
|
sound
|
||||||
), "ascii"))
|
), "ascii"))
|
||||||
elif noteType == "Drumroll" or noteType == "DRUMROLL":
|
elif noteType == "Drumroll" or noteType == "DRUMROLL":
|
||||||
sound = osuSounds[noteType]
|
sound = osuSounds[noteType]
|
||||||
velocity = 1.4 * branch["speed"] * 100 / (1000 / measure["bpm"] * 60)
|
velocity = 1.4 * branch["speed"] * 100 / (1000 / measure["bpm"] * 60)
|
||||||
pixelLength = note["duration"] * velocity
|
pixelLength = note["duration"] * velocity
|
||||||
osu.append(bytes("416,176,{0},2,{1},L|696:176,1,{2},0|0,0:0|0:0,0:0:0:0:".format(
|
osu.append(bytes("416,176,{0},2,{1},L|696:176,1,{2},0|0,0:0|0:0,0:0:0:0:".format(
|
||||||
int(offset),
|
int(offset),
|
||||||
sound,
|
sound,
|
||||||
int(pixelLength)
|
int(pixelLength)
|
||||||
), "ascii"))
|
), "ascii"))
|
||||||
elif noteType == "Balloon" or noteType == "Kusudama":
|
elif noteType == "Balloon" or noteType == "Kusudama":
|
||||||
sound = osuSounds[noteType]
|
sound = osuSounds[noteType]
|
||||||
endTime = offset + note["duration"]
|
endTime = offset + note["duration"]
|
||||||
osu.append(bytes("416,176,{0},12,0,{1},0:0:0:0:".format(
|
osu.append(bytes("416,176,{0},12,0,{1},0:0:0:0:".format(
|
||||||
int(offset),
|
int(offset),
|
||||||
int(endTime)
|
int(endTime)
|
||||||
), "ascii"))
|
), "ascii"))
|
||||||
osu.append(b"")
|
osu.append(b"")
|
||||||
osuContents = b"\n".join(osu)
|
osuContents = b"\n".join(osu)
|
||||||
|
|
||||||
if outputFile:
|
if outputFile:
|
||||||
if type(outputFile) is str:
|
if type(outputFile) is str:
|
||||||
file = open(outputFile, "bw+")
|
file = open(outputFile, "bw+")
|
||||||
else:
|
else:
|
||||||
file = outputFile
|
file = outputFile
|
||||||
if type(outputFile) is io.TextIOWrapper:
|
if type(outputFile) is io.TextIOWrapper:
|
||||||
osuContents = osuContents.decode("utf-8")
|
osuContents = osuContents.decode("utf-8")
|
||||||
try:
|
try:
|
||||||
file.write(osuContents)
|
file.write(osuContents)
|
||||||
except UnicodeEncodeError as e:
|
except UnicodeEncodeError as e:
|
||||||
print(e)
|
print(e)
|
||||||
file.close()
|
file.close()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return osuContents
|
return osuContents
|
||||||
|
|
||||||
def shortHex(number):
|
def shortHex(number):
|
||||||
return hex(number)[2:]
|
return hex(number)[2:]
|
||||||
|
|
||||||
def getBool(number):
|
def getBool(number):
|
||||||
return True if number == 0x1 else False if number == 0x0 else number
|
return True if number == 0x1 else False if number == 0x0 else number
|
||||||
|
|
||||||
def nameValue(*lists):
|
def nameValue(*lists):
|
||||||
string = []
|
string = []
|
||||||
for list in lists:
|
for list in lists:
|
||||||
for name in list:
|
for name in list:
|
||||||
if name == "type":
|
if name == "type":
|
||||||
string.append(list[name])
|
string.append(list[name])
|
||||||
elif name != "length" and type(name) is not int:
|
elif name != "length" and type(name) is not int:
|
||||||
value = list[name]
|
value = list[name]
|
||||||
if type(value) == float and value % 1 == 0.0:
|
if type(value) == float and value % 1 == 0.0:
|
||||||
value = int(value)
|
value = int(value)
|
||||||
string.append("{0}: {1}".format(name, value))
|
string.append("{0}: {1}".format(name, value))
|
||||||
return ", ".join(string)
|
return ", ".join(string)
|
||||||
|
|
||||||
def debugPrint(*args, **kwargs):
|
def debugPrint(*args, **kwargs):
|
||||||
print(*args, file=sys.stderr, **kwargs)
|
print(*args, file=sys.stderr, **kwargs)
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="fumen2osu {0}".format(fumen2osu_version)
|
description="fumen2osu {0}".format(fumen2osu_version)
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"file_m.bin",
|
"file_m.bin",
|
||||||
help="Path to a Taiko no Tatsujin fumen file.",
|
help="Path to a Taiko no Tatsujin fumen file.",
|
||||||
type=argparse.FileType("rb")
|
type=argparse.FileType("rb")
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"offset",
|
"offset",
|
||||||
help="Note offset in seconds, negative values will make the notes appear later. Example: -1.9",
|
help="Note offset in seconds, negative values will make the notes appear later. Example: -1.9",
|
||||||
nargs="?",
|
nargs="?",
|
||||||
type=float,
|
type=float,
|
||||||
default=0
|
default=0
|
||||||
)
|
)
|
||||||
group = parser.add_mutually_exclusive_group()
|
group = parser.add_mutually_exclusive_group()
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--big",
|
"--big",
|
||||||
help="Force big endian byte order for parsing.",
|
help="Force big endian byte order for parsing.",
|
||||||
action="store_const",
|
action="store_const",
|
||||||
dest="order",
|
dest="order",
|
||||||
const="big"
|
const="big"
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--little",
|
"--little",
|
||||||
help="Force little endian byte order for parsing.",
|
help="Force little endian byte order for parsing.",
|
||||||
action="store_const",
|
action="store_const",
|
||||||
dest="order",
|
dest="order",
|
||||||
const="little"
|
const="little"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-o",
|
"-o",
|
||||||
metavar="file.osu",
|
metavar="file.osu",
|
||||||
help="Set the filename of the output file.",
|
help="Set the filename of the output file.",
|
||||||
type=argparse.FileType("bw+")
|
type=argparse.FileType("bw+")
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--title",
|
"--title",
|
||||||
metavar="\"Title\"",
|
metavar="\"Title\"",
|
||||||
help="Set the title in the output file."
|
help="Set the title in the output file."
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--subtitle",
|
"--subtitle",
|
||||||
metavar="\"Subtitle\"",
|
metavar="\"Subtitle\"",
|
||||||
help="Set the subtitle (artist field) in the output file.",
|
help="Set the subtitle (artist field) in the output file.",
|
||||||
default=""
|
default=""
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--wave",
|
"--wave",
|
||||||
metavar="file.wav",
|
metavar="file.wav",
|
||||||
help="Set the audio filename in the output file."
|
help="Set the audio filename in the output file."
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--branch",
|
"--branch",
|
||||||
metavar="master",
|
metavar="master",
|
||||||
help="Select a branch from a branched song ({0}).".format(", ".join(branchNames)),
|
help="Select a branch from a branched song ({0}).".format(", ".join(branchNames)),
|
||||||
choices=branchNames
|
choices=branchNames
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-v", "--debug",
|
"-v", "--debug",
|
||||||
help="Print verbose debug information.",
|
help="Print verbose debug information.",
|
||||||
action="store_true"
|
action="store_true"
|
||||||
)
|
)
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
else:
|
else:
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
inputFile = getattr(args, "file_m.bin")
|
inputFile = getattr(args, "file_m.bin")
|
||||||
song = readFumen(inputFile, args.order, args.debug)
|
song = readFumen(inputFile, args.order, args.debug)
|
||||||
writeOsu(song, args.offset, args.title, args.subtitle, args.wave, args.branch, args.o, inputFile)
|
writeOsu(song, args.offset, args.title, args.subtitle, args.wave, args.branch, args.o, inputFile)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user