#!/usr/bin/env bash ############################################################################### # # Copyright (C) 2009-2013 Nintendo. All rights reserved. # # These coded instructions, statements, and computer programs contain # proprietary information of Nintendo of America Inc. and/or Nintendo # Company Ltd., and are protected by Federal copyright law. They may # not be disclosed to third parties or copied or duplicated in any form, # in whole or in part, without the prior written consent of Nintendo. # ############################################################################### ############################################################################### # main ############################################################################### # Check arg if [ "$#" -ne 2 ]; then echo "Usage: $0 AOC_ROOT_DIR AOC_NAME" exit 1 fi if [[ ! -d "$1" ]]; then echo "[ERROR] $1 is not a directory!" exit 1 fi # Set variables AOC_ROOT_DIR=`cygpath -w -a "$1"` OUT_DIR="`cygpath -w -a "$AOC_ROOT_DIR"/outdir`" AOC_NAME="$2" APP_TITLE_ID=0005000C10000000 APP_GROUP_ID=00000000 APP_TITLE_VERSION=0000 CAFE_BASEFILE_PATH="`cygpath -w "$CAFE_ROOT"/system/bin/tool/mastering/resources`" TOOL_DIR=`dirname "$0"` TOOL_DIR=`cygpath -w -a "$TOOL_DIR"` DEFAULT_DDF="`cygpath -w "$CAFE_ROOT"/system/bin/tool/mastering/resources/default_aoc.ddf`" COMMON_DDF_FILE="`cygpath -w "$OUT_DIR"/common_aoc.ddf`" INDIVIDUAL_DDF_FILE="`cygpath -w "$AOC_ROOT_DIR"/code/$AOC_NAME.ddf`" SECTION_ENTRY_HASH_OPTION="-filename_addhash" AOC_APP_XML="$AOC_ROOT_DIR/code/app.xml" AOC_COS_XML="$AOC_ROOT_DIR/code/cos.xml" AOC_META_XML="$AOC_ROOT_DIR/meta/meta.xml" META_DEFAULT_XML="$CAFE_ROOT/system/bin/ghs/cafe/boot/meta_default.xml" # Source function library. source "$TOOL_DIR/masteringfunctions.sh" ############################################################################### # extract_info_from_app_xml # $1 - Path to app.xml ############################################################################### extract_info_from_app_xml() { arg_num_check $# 1 local APP_XML_FILE="$1" # get title id APP_TITLE_ID=`sed -n 's|.*\(.*\)|\1|p' "$APP_XML_FILE"` APP_GROUP_ID=`sed -n 's|.*\(.*\)|\1|p' "$APP_XML_FILE"` APP_TITLE_VERSION=`sed -n 's|.*\(.*\)|\1|p' "$APP_XML_FILE"` echo "App Title ID : $APP_TITLE_ID" echo "App Group ID : $APP_GROUP_ID" echo "App Title Version : $APP_TITLE_VERSION" } # Create directories, if not exist if [[ ! -e "$AOC_ROOT_DIR/code" ]]; then mkdir "$AOC_ROOT_DIR/code" fi if [[ ! -e "$AOC_ROOT_DIR/meta" ]]; then mkdir "$AOC_ROOT_DIR/meta" fi if [[ ! -e "$OUT_DIR" ]]; then mkdir "$OUT_DIR" fi # Copy default xml files, if not exist if [[ ! -e "$AOC_APP_XML" ]]; then cp $CAFE_ROOT/system/bin/ghs/cafe/boot/app_default.xml $AOC_APP_XML # Replace the value in : 80000000 -> 0800000E sed -i -e "s|\(\)\(.*\)\(\)|\10800000E\3|" $AOC_APP_XML # Replace the value in : XXXXXXXXXXXXXXXX -> XXXXXXXCXXXXXXXX sed -i -e "s|\(\)\(.\{7\}\)\(.\)\(.\{8\}\)\(\)|\1\2C\4\5|" $AOC_APP_XML # sed -i -e "s|\(\)\(.*\)\(\)|\1XXXXXXXCXXXXXXXX\3|" $AOC_APP_XML fi if [[ ! -e "$AOC_COS_XML" ]]; then cp $CAFE_ROOT/system/bin/ghs/cafe/boot/cos_default.xml $AOC_COS_XML fi if [[ ! -e "$AOC_META_XML" ]]; then cp $CAFE_ROOT/system/bin/ghs/cafe/boot/meta_default.xml $AOC_META_XML fi # Copy default masterinfo.xml, if not exist DEFAULT_MASTERINFO_XML="$CAFE_ROOT/system/bin/tool/mastering/resources/masterinfo_aoc.xml" DEST_MASTERINFO_XML="$AOC_ROOT_DIR/code/masterinfo.xml" if [[ ! -e "$DEST_MASTERINFO_XML" ]]; then cp -u "$DEFAULT_MASTERINFO_XML" "$DEST_MASTERINFO_XML" fi # Replace the GameType with "GA" (Game Add-on contents) sed -i -e "s|\(\)\(.*\)\(\)|\1GA\3|" "$DEST_MASTERINFO_XML" # Copy default iconTex.tga, if not exist DEFAULT_ICON_TEX_TGA="$CAFE_ROOT/system/bin/ghs/cafe/meta/iconTex.tga" DEST_ICON_TEX_TGA="$AOC_ROOT_DIR/meta/iconTex.tga" if [ ! -f "$DEST_ICON_TEX_TGA" ]; then cp -u "$DEFAULT_ICON_TEX_TGA" "$DEST_ICON_TEX_TGA" fi # Call extract_info_from_app_xml extract_info_from_app_xml $AOC_APP_XML # set NDEBUG OS version G_OS_VERSION=`sed -n 's|.*\(.*\)|\1|p' "$META_DEFAULT_XML"` G_OS_VERSION=`echo $G_OS_VERSION | grep -Eo "[0-9a-fA-F]+"` if [ "${G_OS_VERSION:12:1}" == "8" ]; then G_OS_VERSION="${G_OS_VERSION::12}4${G_OS_VERSION:13}" fi update_app_xml "$AOC_APP_XML" update_meta_xml "$AOC_META_XML" update_cos_xml "$AOC_COS_XML" check_appconf_version "$DEST_MASTERINFO_XML" # embed info # embed_sdk_version_to_masterinfo "$DEST_MASTERINFO_XML" embed_tool_version_to_masterinfo "$DEST_MASTERINFO_XML" embed_os_version_to_masterinfo "$DEST_MASTERINFO_XML" embed_mastering_sdk_version "$DEST_MASTERINFO_XML" reset_mastering_flag "$DEST_MASTERINFO_XML" "$AOC_META_XML" # Generate common_aoc.ddf echo " [Input] DiscHeaderBaseFileName=\"$CAFE_BASEFILE_PATH\\discheader_base.bin\" VolumeHeaderBaseFileName=\"$CAFE_BASEFILE_PATH\\volheader_base.bin\" [Output] LayoutFileName=\"$OUT_DIR\\$AOC_NAME.dlf\" OutputDirectory=\"$OUT_DIR\" AppName=\"$AOC_NAME\" [DiscID] GameType=GA TitleId=0x$APP_TITLE_ID GroupId=0x$APP_GROUP_ID GameVersion=`expr $(printf %d 0x$APP_TITLE_VERSION) / 16` [PathList] CODE_DIR=\"code\", \"$AOC_ROOT_DIR\\code\" META_DIR=\"meta\", \"$AOC_ROOT_DIR\\meta\" CONTENT_DIR=\"content\", \"$AOC_ROOT_DIR\\content\" " > "$COMMON_DDF_FILE" # Generate individual ddf file, if not exist if [[ ! -e $INDIVIDUAL_DDF_FILE ]]; then echo "Generate individual_aoc.ddf" # Get max section number NUM_CONTENT_SUBDIR=`ls -1 "$AOC_ROOT_DIR/content" | wc -l` (( MAX_SECTION = NUM_CONTENT_SUBDIR + 15 )) if [[ ! -d "$AOC_ROOT_DIR/content/"`printf %04x $MAX_SECTION` ]]; then echo "Error: $AOC_ROOT_DIR/content/`printf %04x $MAX_SECTION` not found" exit 3 fi echo "MAX_SECTION: `printf %04x $MAX_SECTION`" if [[ $MAX_SECTION -ge 2016 ]]; then echo "Error: Too many contents" exit 4 fi # Use hex number array instead of using printf, since printf is too slow HEX_CHAR=(0 1 2 3 4 5 6 7 8 9 a b c d e f) for (( i=0; i < 256; i++ )) { (( hi = i / 16 )) (( lo = i % 16 )) HEX_STR[$i]="${HEX_CHAR[$hi]}${HEX_CHAR[$lo]}" } echo "Writing [SectionList]..." { echo "[SectionList]" for (( i=0x0010; i<=MAX_SECTION; i++ )) { (( hi = i / 256 )) (( lo = i % 256 )) SUBDIR_NAME="${HEX_STR[$hi]}${HEX_STR[$lo]}" (( seclist_param = 100000 + 0x0010 - i )) echo "\"ADDONCONTENT$SUBDIR_NAME\" = -$seclist_param" } echo "" } >> "$INDIVIDUAL_DDF_FILE" echo "Writing [SectionAssign]..." { echo "[SectionAssign]" for (( i=0x0010; i<=MAX_SECTION; i++ )) { (( hi = i / 256 )) (( lo = i % 256 )) SUBDIR_NAME="${HEX_STR[$hi]}${HEX_STR[$lo]}" (( seclist_param = 100000 + 0x0010 - i )) echo "-$seclist_param = \"content/$SUBDIR_NAME/*\", \"ADDONCONTENT$SUBDIR_NAME\", 0x040" } echo "" } >> "$INDIVIDUAL_DDF_FILE" echo "Writing [SectionParam]..." { echo "[SectionParam]" echo "\"CONTENTDIR\" = 0x0000000000000000, 0x$APP_GROUP_ID, 0x02" for (( i=0x0010; i<=MAX_SECTION; i++ )) { (( hi = i / 256 )) (( lo = i % 256 )) SUBDIR_NAME="${HEX_STR[$hi]}${HEX_STR[$lo]}" echo "\"ADDONCONTENT$SUBDIR_NAME\" = 0x0000000000000000, 0x$APP_GROUP_ID, 0x02" } echo "" } >> "$INDIVIDUAL_DDF_FILE" else cd $AOC_ROOT_DIR # Force replace the GameType with "GA" (Game Add-on contents) sed -i -e "s|\(GameType *= *\).*|\1GA|" "$INDIVIDUAL_DDF_FILE" # Force replace the permission of ADDONCONTENT section with 0x040 sed -i -e "s|\(-[0-9]* *= *\"content/[0-9A-Fa-f]\{4\}/\*\", *\"ADDONCONTENT[0-9A-Fa-f]\{4\}\", *0x\)[0-9]\{3\}|\1040|" "$INDIVIDUAL_DDF_FILE" # Force replace the OwnerId of ADDONCONTENT section with 0x0000000000000000 APP_GROUP_ID=`sed -n 's|\"ADDONCONTENT0010\" *= *0x[0-9A-Fa-f]*, *0x\([0-9A-Fa-f]*\), *0x[0-9A-Fa-f]*|\1|p' "$INDIVIDUAL_DDF_FILE"` sed -i -e "/\"CONTENTDIR\" *= *0x[0-9A-Fa-f]*, *0x[0-9A-Fa-f]*, *0x[0-9A-Fa-f]*/d" "$INDIVIDUAL_DDF_FILE" sed -i -e "s|\[SectionParam\]|\[SectionParam\]\n\"CONTENTDIR\" = 0x0000000000000000, 0x$APP_GROUP_ID, 0x02|" "$INDIVIDUAL_DDF_FILE" sed -i -e "s|\(\"ADDONCONTENT[0-9A-Fa-f]\{4\}\" *= *\)0x[0-9A-Fa-f]*\(, *0x[0-9A-Fa-f]*, *0x[0-9A-Fa-f]*\)|\10x0000000000000000\2|" "$INDIVIDUAL_DDF_FILE" cd - fi embed_ddf_info_to_masterinfo "$INDIVIDUAL_DDF_FILE" "$DEST_MASTERINFO_XML" check_section_entry_hash update_xml_flag_section_entry_hash "$DEST_MASTERINFO_XML" "$AOC_META_XML" "$MAKEDLF" -uf -mss=4024 -mi="$DEST_MASTERINFO_XML" "$DEFAULT_DDF" "$COMMON_DDF_FILE" "$INDIVIDUAL_DDF_FILE" "$SECTION_ENTRY_HASH_OPTION" "$MAKEIDBE" "$AOC_ROOT_DIR\\code\\masterinfo.xml" "$AOC_ROOT_DIR\\meta\\iconTex.tga" "$OUT_DIR\\icon.db" "$MAKEMASTER" -v -nc "-wd=./workdir" "$OUT_DIR\\$AOC_NAME.dlf" "$CAFE_BASEFILE_PATH\\masterheader_base.bin" "$AOC_ROOT_DIR\\code\\masterinfo.xml" "$OUT_DIR\\$AOC_NAME.wumad" "-rl=$OUT_DIR\\icon.db" "$SECTION_ENTRY_HASH_OPTION" # Show messages show_msg rm -Rf "./workdir" exit 0