diff --git a/pms2bemani/README.md b/pms2bemani/README.md index 5b4b9f8..b28307f 100644 --- a/pms2bemani/README.md +++ b/pms2bemani/README.md @@ -5,12 +5,13 @@ ## Usage ``` -usage: pms2bemani.py [-h] [--input-bp INPUT_BP] [--input-ep INPUT_EP] - [--input-np INPUT_NP] [--input-hp INPUT_HP] - [--input-op INPUT_OP] --name NAME --keysounds-folder - KEYSOUNDS_FOLDER [--preview PREVIEW] [--new] [--ifs] - [--preview-offset PREVIEW_OFFSET] - [--preview-duration PREVIEW_DURATION] +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 + --musicid MUSICID --keysounds-folder KEYSOUNDS_FOLDER [--preview PREVIEW] [--new] --banner BANNER [--bg BG] [--hariai HARIAI] + [--metadata-fw-title METADATA_FW_TITLE] [--metadata-fw-artist METADATA_FW_ARTIST] [--metadata-fw-genre METADATA_FW_GENRE] + [--metadata-title METADATA_TITLE] [--metadata-artist METADATA_ARTIST] [--metadata-genre METADATA_GENRE] [--metadata-chara1 METADATA_CHARA1] + [--metadata-chara2 METADATA_CHARA2] [--metadata-has-battle-hyper] [--metadata-hariai-is-jacket] [--metadata-folder METADATA_FOLDER] + [--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: -h, --help show this help message and exit @@ -19,28 +20,62 @@ optional arguments: --input-np INPUT_NP Input file (NP) --input-hp INPUT_HP Input file (HP) --input-op INPUT_OP Input file (OP) - --name NAME Base name used for output - --keysounds-folder KEYSOUNDS_FOLDER - Input folder containing keysounds - --preview PREVIEW Input preview file (optional, overrides preview - generation code) + --output OUTPUT Output folder + --preview PREVIEW Input preview file (overrides preview generation code) --new New chart format which supports hold notes - --ifs Create IFS output instead of folder output (requires - ifstools) + --bg BG Background image (must be 128x256) + --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 - Offset from start in seconds (ex. 10.4 would be 10.4 - seconds) + Offset from start in seconds (ex. 10.4 would be 10.4 seconds) --preview-duration PREVIEW_DURATION 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 `--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. - 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. -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 - ifstools (https://github.com/mon/ifstools) diff --git a/pms2bemani/pms2bemani/pms2bemani.py b/pms2bemani/pms2bemani/pms2bemani.py index a373188..40b9e0d 100644 --- a/pms2bemani/pms2bemani/pms2bemani.py +++ b/pms2bemani/pms2bemani/pms2bemani.py @@ -692,8 +692,8 @@ def create_bg(output_path, musicid, bg_filename): def create_hariai(output_path, musicid, hariai_filename): hariai_image = Image.open(hariai_filename) - if hariai_image.size != (248, 320): - print("hariai must be 248x320! Found", hariai_image.size) + if (hariai_image.size != (250, 322)) and (hariai_image.size != (382, 502)): + print("hariai must be (250, 322) or (382, 502)! Found", hariai_image.size) exit(1) 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, "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( E.texture( E.size( - "256 512", + xml_texture_data[image_type][0], __type="2u16", ), E.image( E.uvrect( - "2 498 2 642", + xml_texture_data[image_type][1], __type="4u16" ), E.imgrect( - "0 500 0 644", + xml_texture_data[image_type][2], __type="4u16" ), name=hariai_name @@ -733,19 +739,6 @@ def create_hariai(output_path, musicid, hariai_filename): 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)) - 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")) @@ -760,15 +753,18 @@ if __name__ == "__main__": for difficulty in difficulties: 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('--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) - parser.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) + requiredNamed.add_argument('--name', help='Base name used for output', default=None, required=True) + requiredNamed.add_argument('--musicid', help='Music ID used for the database file', required=True, type=int) + requiredNamed.add_argument('--keysounds-folder', help='Input folder containing keysounds', default=None, required=True) + 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('--banner', help='Banner image (optional, must be 244x58)', default=None) - parser.add_argument('--bg', help='Background image (optional, must be 128x256)', default=None) - parser.add_argument('--hariai', help='Hariai image (optional, must be 248x320)', default=None) + requiredNamed.add_argument('--banner', help='Banner image (must be 244x58)', default=None, required=True) + parser.add_argument('--bg', help='Background image (must be 128x256)', default=None, required=False) + 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-artist', help='Fullwidth music artist 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-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) - + + 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-duration', help='Length of preview in seconds', default=10, type=float) @@ -793,6 +790,8 @@ if __name__ == "__main__": args = parser.parse_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: print("Music ID must be >= 4000") exit(1) @@ -893,16 +892,16 @@ if __name__ == "__main__": tex_files = {} if args.banner: # 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: # 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 if args.bg: # 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: 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.categories(str(args.metadata_categories), __type="u32"), 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_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"),