Merge pull request #1 from xinrin/main
Fix hariai stuff and folder structure for popnhax v2 mods
This commit is contained in:
commit
97b3947f5f
@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```
|
```
|
||||||
usage: pms2bemani.py [-h] [--input-bp INPUT_BP] [--input-ep INPUT_EP]
|
usage: pms2bemani.py [-h] [--input-bp INPUT_BP] [--input-ep INPUT_EP] [--input-np INPUT_NP] [--input-hp INPUT_HP] [--input-op INPUT_OP] [--output OUTPUT] --name NAME
|
||||||
[--input-np INPUT_NP] [--input-hp INPUT_HP]
|
--musicid MUSICID --keysounds-folder KEYSOUNDS_FOLDER [--preview PREVIEW] [--new] --banner BANNER [--bg BG] [--hariai HARIAI]
|
||||||
[--input-op INPUT_OP] --name NAME --keysounds-folder
|
[--metadata-fw-title METADATA_FW_TITLE] [--metadata-fw-artist METADATA_FW_ARTIST] [--metadata-fw-genre METADATA_FW_GENRE]
|
||||||
KEYSOUNDS_FOLDER [--preview PREVIEW] [--new] [--ifs]
|
[--metadata-title METADATA_TITLE] [--metadata-artist METADATA_ARTIST] [--metadata-genre METADATA_GENRE] [--metadata-chara1 METADATA_CHARA1]
|
||||||
[--preview-offset PREVIEW_OFFSET]
|
[--metadata-chara2 METADATA_CHARA2] [--metadata-has-battle-hyper] [--metadata-hariai-is-jacket] [--metadata-folder METADATA_FOLDER]
|
||||||
[--preview-duration PREVIEW_DURATION]
|
[--metadata-categories METADATA_CATEGORIES] [--metadata-cs-version METADATA_CS_VERSION] [--metadata-mask METADATA_MASK]
|
||||||
|
[--metadata-chara-x METADATA_CHARA_X] [--metadata-chara-y METADATA_CHARA_Y] [--preview-offset PREVIEW_OFFSET] [--preview-duration PREVIEW_DURATION]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@ -19,28 +20,62 @@ optional arguments:
|
|||||||
--input-np INPUT_NP Input file (NP)
|
--input-np INPUT_NP Input file (NP)
|
||||||
--input-hp INPUT_HP Input file (HP)
|
--input-hp INPUT_HP Input file (HP)
|
||||||
--input-op INPUT_OP Input file (OP)
|
--input-op INPUT_OP Input file (OP)
|
||||||
--name NAME Base name used for output
|
--output OUTPUT Output folder
|
||||||
--keysounds-folder KEYSOUNDS_FOLDER
|
--preview PREVIEW Input preview file (overrides preview generation code)
|
||||||
Input folder containing keysounds
|
|
||||||
--preview PREVIEW Input preview file (optional, overrides preview
|
|
||||||
generation code)
|
|
||||||
--new New chart format which supports hold notes
|
--new New chart format which supports hold notes
|
||||||
--ifs Create IFS output instead of folder output (requires
|
--bg BG Background image (must be 128x256)
|
||||||
ifstools)
|
--hariai HARIAI Hariai image (must be 250x322 or 382x502)
|
||||||
|
--metadata-fw-title METADATA_FW_TITLE
|
||||||
|
Fullwidth music title for database
|
||||||
|
--metadata-fw-artist METADATA_FW_ARTIST
|
||||||
|
Fullwidth music artist for database
|
||||||
|
--metadata-fw-genre METADATA_FW_GENRE
|
||||||
|
Fullwidth music genre for database
|
||||||
|
--metadata-title METADATA_TITLE
|
||||||
|
Music title for database
|
||||||
|
--metadata-artist METADATA_ARTIST
|
||||||
|
Music artist for database
|
||||||
|
--metadata-genre METADATA_GENRE
|
||||||
|
Music genre for database
|
||||||
|
--metadata-chara1 METADATA_CHARA1
|
||||||
|
Chara1 for database
|
||||||
|
--metadata-chara2 METADATA_CHARA2
|
||||||
|
Chara2 for database
|
||||||
|
--metadata-has-battle-hyper
|
||||||
|
Battle Hyper flag for database
|
||||||
|
--metadata-hariai-is-jacket
|
||||||
|
Jacket mask flag for database
|
||||||
|
--metadata-folder METADATA_FOLDER
|
||||||
|
Folder entry for database
|
||||||
|
--metadata-categories METADATA_CATEGORIES
|
||||||
|
Categories entry for database
|
||||||
|
--metadata-cs-version METADATA_CS_VERSION
|
||||||
|
CS version entry for database
|
||||||
|
--metadata-mask METADATA_MASK
|
||||||
|
Base mask value for database
|
||||||
|
--metadata-chara-x METADATA_CHARA_X
|
||||||
|
Chara X entry for database
|
||||||
|
--metadata-chara-y METADATA_CHARA_Y
|
||||||
|
Chara Y entry for database
|
||||||
--preview-offset PREVIEW_OFFSET
|
--preview-offset PREVIEW_OFFSET
|
||||||
Offset from start in seconds (ex. 10.4 would be 10.4
|
Offset from start in seconds (ex. 10.4 would be 10.4 seconds)
|
||||||
seconds)
|
|
||||||
--preview-duration PREVIEW_DURATION
|
--preview-duration PREVIEW_DURATION
|
||||||
Length of preview in seconds
|
Length of preview in seconds
|
||||||
|
|
||||||
|
required arguments:
|
||||||
|
--name NAME Base name used for output
|
||||||
|
--musicid MUSICID Music ID used for the database file
|
||||||
|
--keysounds-folder KEYSOUNDS_FOLDER
|
||||||
|
Input folder containing keysounds
|
||||||
|
--banner BANNER Banner image (must be 244x58)
|
||||||
```
|
```
|
||||||
|
|
||||||
- Use `--new` to specify the new chart format (Usaneko and later) which supports hold notes.
|
- Use `--new` to specify the new chart format (Usaneko and later) which supports hold notes.
|
||||||
- Use `--ifs` to generate an `.ifs` file instead of a folder.
|
|
||||||
- If a preview sound file is not specified with --preview, a preview will be automatically generated.
|
- If a preview sound file is not specified with --preview, a preview will be automatically generated.
|
||||||
- Automatically generated previews default to 10 seconds at the mid point of the chart.
|
- Automatically generated previews default to 10 seconds at the mid point of the chart.
|
||||||
- The preview offset and duration can be customized using `--preview-offset` and `--preview-duration` respectively.
|
- The preview offset and duration can be customized using `--preview-offset` and `--preview-duration` respectively.
|
||||||
|
|
||||||
Example: `python3 pms2bemani.py --input-np wonderingbeats/01_kouunn-n.pms --input-hp wonderingbeats/02_kouunn-h.pms --input-op wonderingbeats/03_kouunn-ex.pms --keysounds-folder wonderingbeats --name wonderingbeats_convert --ifs --new --preview-offset 10.4 --preview-duration 15`
|
Example: `python3 pms2bemani.py --input-np wonderingbeats/01_kouunn-n.pms --input-hp wonderingbeats/02_kouunn-h.pms --input-op wonderingbeats/03_kouunn-ex.pms --keysounds-folder wonderingbeats --name wonderingbeats_convert --new --preview-offset 10.4 --preview-duration 15`
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
- ifstools (https://github.com/mon/ifstools)
|
- ifstools (https://github.com/mon/ifstools)
|
||||||
|
@ -692,8 +692,8 @@ def create_bg(output_path, musicid, bg_filename):
|
|||||||
def create_hariai(output_path, musicid, hariai_filename):
|
def create_hariai(output_path, musicid, hariai_filename):
|
||||||
hariai_image = Image.open(hariai_filename)
|
hariai_image = Image.open(hariai_filename)
|
||||||
|
|
||||||
if hariai_image.size != (248, 320):
|
if (hariai_image.size != (250, 322)) and (hariai_image.size != (382, 502)):
|
||||||
print("hariai must be 248x320! Found", hariai_image.size)
|
print("hariai must be (250, 322) or (382, 502)! Found", hariai_image.size)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
hariai_name = "ha_%04d" % (musicid)
|
hariai_name = "ha_%04d" % (musicid)
|
||||||
@ -702,20 +702,26 @@ def create_hariai(output_path, musicid, hariai_filename):
|
|||||||
|
|
||||||
open(os.path.join(hariai_output_folder, "magic"), "wb").write(b"NGPF")
|
open(os.path.join(hariai_output_folder, "magic"), "wb").write(b"NGPF")
|
||||||
open(os.path.join(hariai_output_folder, "cversion"), "wb").write(b"1.3.72\0")
|
open(os.path.join(hariai_output_folder, "cversion"), "wb").write(b"1.3.72\0")
|
||||||
|
#texture xml parameters depending on the size
|
||||||
|
xml_texture_data = [["256 512", "2 498 2 642", "0 500 0 644"], ["512 512", "2 762 2 1002", "0 764 0 1004"]]
|
||||||
|
image_type = 0
|
||||||
|
#in case our image is the second type will use that
|
||||||
|
if hariai_image.size == (382, 502):
|
||||||
|
image_type = 1
|
||||||
|
|
||||||
hariai_xml = E.texturelist(
|
hariai_xml = E.texturelist(
|
||||||
E.texture(
|
E.texture(
|
||||||
E.size(
|
E.size(
|
||||||
"256 512",
|
xml_texture_data[image_type][0],
|
||||||
__type="2u16",
|
__type="2u16",
|
||||||
),
|
),
|
||||||
E.image(
|
E.image(
|
||||||
E.uvrect(
|
E.uvrect(
|
||||||
"2 498 2 642",
|
xml_texture_data[image_type][1],
|
||||||
__type="4u16"
|
__type="4u16"
|
||||||
),
|
),
|
||||||
E.imgrect(
|
E.imgrect(
|
||||||
"0 500 0 644",
|
xml_texture_data[image_type][2],
|
||||||
__type="4u16"
|
__type="4u16"
|
||||||
),
|
),
|
||||||
name=hariai_name
|
name=hariai_name
|
||||||
@ -733,19 +739,6 @@ def create_hariai(output_path, musicid, hariai_filename):
|
|||||||
tex_path = os.path.join(hariai_output_folder, "tex")
|
tex_path = os.path.join(hariai_output_folder, "tex")
|
||||||
open(os.path.join(tex_path, "texturelist.xml"), "wb").write(tostring(hariai_xml, pretty_print=True, method='xml', encoding='utf-8', xml_declaration=True))
|
open(os.path.join(tex_path, "texturelist.xml"), "wb").write(tostring(hariai_xml, pretty_print=True, method='xml', encoding='utf-8', xml_declaration=True))
|
||||||
|
|
||||||
if hariai_image.size == (248, 320):
|
|
||||||
# Duplicate the edge pixels
|
|
||||||
new_hariai_image = Image.new('RGBA', (hariai_image.width + 2, hariai_image.height + 2))
|
|
||||||
new_hariai_image.paste(hariai_image, (1, 1))
|
|
||||||
new_hariai_image.paste(hariai_image.crop((0, 0, hariai_image.width, 1)), (1, 0)) # Top
|
|
||||||
new_hariai_image.paste(hariai_image.crop((0, hariai_image.height - 1, hariai_image.width, hariai_image.height)), (1, hariai_image.height + 1)) # Bottom
|
|
||||||
# new_hariai_image.paste(hariai_image.crop((1, 0, 2, hariai_image.height)), (0, 1)) # Left
|
|
||||||
new_hariai_image.paste(hariai_image.crop((hariai_image.width - 1, 0, hariai_image.width, hariai_image.height)), (hariai_image.width + 1, 1)) # Right
|
|
||||||
hariai_image = new_hariai_image
|
|
||||||
|
|
||||||
if hariai_image.size not in [(250, 322)]:
|
|
||||||
print("Unknown hariai size", hariai_filename, hariai_image.size)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
hariai_image.save(os.path.join(tex_path, hariai_name + ".png"))
|
hariai_image.save(os.path.join(tex_path, hariai_name + ".png"))
|
||||||
|
|
||||||
@ -760,15 +753,18 @@ if __name__ == "__main__":
|
|||||||
for difficulty in difficulties:
|
for difficulty in difficulties:
|
||||||
parser.add_argument('--input-%s' % difficulty, help='Input file (%s)' % difficulty.upper(), default=None)
|
parser.add_argument('--input-%s' % difficulty, help='Input file (%s)' % difficulty.upper(), default=None)
|
||||||
|
|
||||||
|
#Display required arguments on help
|
||||||
|
requiredNamed = parser.add_argument_group('required arguments')
|
||||||
|
#Arguments
|
||||||
parser.add_argument('--output', help='Output folder', default="output")
|
parser.add_argument('--output', help='Output folder', default="output")
|
||||||
parser.add_argument('--name', help='Base name used for output', default=None, required=True)
|
requiredNamed.add_argument('--name', help='Base name used for output', default=None, required=True)
|
||||||
parser.add_argument('--musicid', help='Music ID used for the database file', required=True, type=int)
|
requiredNamed.add_argument('--musicid', help='Music ID used for the database file', required=True, type=int)
|
||||||
parser.add_argument('--keysounds-folder', help='Input folder containing keysounds', default=None, required=True)
|
requiredNamed.add_argument('--keysounds-folder', help='Input folder containing keysounds', default=None, required=True)
|
||||||
parser.add_argument('--preview', help='Input preview file (optional, overrides preview generation code)', default=None)
|
parser.add_argument('--preview', help='Input preview file (overrides preview generation code)', default=None)
|
||||||
parser.add_argument('--new', help='New chart format which supports hold notes', default=False, action='store_true')
|
parser.add_argument('--new', help='New chart format which supports hold notes', default=False, action='store_true')
|
||||||
parser.add_argument('--banner', help='Banner image (optional, must be 244x58)', default=None)
|
requiredNamed.add_argument('--banner', help='Banner image (must be 244x58)', default=None, required=True)
|
||||||
parser.add_argument('--bg', help='Background image (optional, must be 128x256)', default=None)
|
parser.add_argument('--bg', help='Background image (must be 128x256)', default=None, required=False)
|
||||||
parser.add_argument('--hariai', help='Hariai image (optional, must be 248x320)', default=None)
|
parser.add_argument('--hariai', help='Hariai image (must be 250x322 or 382x502)', default=None)
|
||||||
parser.add_argument('--metadata-fw-title', help='Fullwidth music title for database', default=None)
|
parser.add_argument('--metadata-fw-title', help='Fullwidth music title for database', default=None)
|
||||||
parser.add_argument('--metadata-fw-artist', help='Fullwidth music artist for database', default=None)
|
parser.add_argument('--metadata-fw-artist', help='Fullwidth music artist for database', default=None)
|
||||||
parser.add_argument('--metadata-fw-genre', help='Fullwidth music genre for database', default=None)
|
parser.add_argument('--metadata-fw-genre', help='Fullwidth music genre for database', default=None)
|
||||||
@ -785,7 +781,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument('--metadata-mask', help='Base mask value for database', default=0, type=int)
|
parser.add_argument('--metadata-mask', help='Base mask value for database', default=0, type=int)
|
||||||
parser.add_argument('--metadata-chara-x', help='Chara X entry for database', default=0, type=int)
|
parser.add_argument('--metadata-chara-x', help='Chara X entry for database', default=0, type=int)
|
||||||
parser.add_argument('--metadata-chara-y', help='Chara Y entry for database', default=0, type=int)
|
parser.add_argument('--metadata-chara-y', help='Chara Y entry for database', default=0, type=int)
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists("bmx2wavc.exe"):
|
if os.path.exists("bmx2wavc.exe"):
|
||||||
parser.add_argument('--preview-offset', help='Offset from start in seconds (ex. 10.4 would be 10.4 seconds)', default=-1, type=float)
|
parser.add_argument('--preview-offset', help='Offset from start in seconds (ex. 10.4 would be 10.4 seconds)', default=-1, type=float)
|
||||||
parser.add_argument('--preview-duration', help='Length of preview in seconds', default=10, type=float)
|
parser.add_argument('--preview-duration', help='Length of preview in seconds', default=10, type=float)
|
||||||
@ -793,6 +790,8 @@ if __name__ == "__main__":
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
args_vars = vars(args)
|
args_vars = vars(args)
|
||||||
|
|
||||||
|
if args.bg is None:
|
||||||
|
print("warning: no background specified, will only work with usaneko and up")
|
||||||
if args.musicid < 4000:
|
if args.musicid < 4000:
|
||||||
print("Music ID must be >= 4000")
|
print("Music ID must be >= 4000")
|
||||||
exit(1)
|
exit(1)
|
||||||
@ -893,16 +892,16 @@ if __name__ == "__main__":
|
|||||||
tex_files = {}
|
tex_files = {}
|
||||||
if args.banner:
|
if args.banner:
|
||||||
# Create banner folder
|
# Create banner folder
|
||||||
tex_files['kc_mod'] = create_banner(output_path, args.musicid, args.banner)
|
tex_files['kc_diff_ifs'] = create_banner(output_path, args.musicid, args.banner)
|
||||||
|
|
||||||
if args.hariai:
|
if args.hariai:
|
||||||
# Create hariai folder
|
# Create hariai folder
|
||||||
tex_files['ha_mod'] = create_hariai(output_path, args.musicid, args.hariai)
|
tex_files['ha_merge_ifs'] = create_hariai(output_path, args.musicid, args.hariai)
|
||||||
mask |= 0x00800000 # Required for songs that show a hariai image on the music selection screen
|
mask |= 0x00800000 # Required for songs that show a hariai image on the music selection screen
|
||||||
|
|
||||||
if args.bg:
|
if args.bg:
|
||||||
# Create background folder
|
# Create background folder
|
||||||
tex_files['bg_mod'] = create_bg(output_path, args.musicid, args.bg)
|
tex_files['bg_diff_ifs'] = create_bg(output_path, args.musicid, args.bg)
|
||||||
|
|
||||||
if args.metadata_hariai_is_jacket:
|
if args.metadata_hariai_is_jacket:
|
||||||
mask |= 0x00000020 # The alternate hariai image (set by using 0x800000) is a song jacket instead of a character portrait
|
mask |= 0x00000020 # The alternate hariai image (set by using 0x800000) is a song jacket instead of a character portrait
|
||||||
@ -921,7 +920,7 @@ if __name__ == "__main__":
|
|||||||
E.cs_version(str(args.metadata_cs_version), __type="u32"),
|
E.cs_version(str(args.metadata_cs_version), __type="u32"),
|
||||||
E.categories(str(args.metadata_categories), __type="u32"),
|
E.categories(str(args.metadata_categories), __type="u32"),
|
||||||
E.charts(*charts_xml),
|
E.charts(*charts_xml),
|
||||||
E.ha(tex_files.get('ha_mod', ""), __type="str"),
|
E.ha(tex_files.get('ha_merge_ifs', ""), __type="str"),
|
||||||
E.chara_x(str(args.metadata_chara_x), __type="u32"),
|
E.chara_x(str(args.metadata_chara_x), __type="u32"),
|
||||||
E.chara_y(str(args.metadata_chara_y), __type="u32"),
|
E.chara_y(str(args.metadata_chara_y), __type="u32"),
|
||||||
E.unk1("0 0 0 0 0 0 36 0 0 59 77 0 0 0 0 134 0 0 68 67 222 0 0 0 0 0 0 0 0 0 0 0", __type="u16", __count="32"),
|
E.unk1("0 0 0 0 0 0 36 0 0 59 77 0 0 0 0 134 0 0 68 67 222 0 0 0 0 0 0 0 0 0 0 0", __type="u16", __count="32"),
|
||||||
|
Loading…
Reference in New Issue
Block a user