1###############################################################################
2#
3# Copyright (C) 2009-2013 Nintendo.  All rights reserved.
4#
5# These coded instructions, statements, and computer programs contain
6# proprietary information of Nintendo of America Inc. and/or Nintendo
7# Company Ltd., and are protected by Federal copyright law.  They may
8# not be disclosed to third parties or copied or duplicated in any form,
9# in whole or in part, without the prior written consent of Nintendo.
10#
11###############################################################################
12
13# Environment settings
14
15MAKEDLF="$CAFE_ROOT/system/bin/tool/mastering/cafemakedlf.exe"
16MAKEMASTER="$CAFE_ROOT/system/bin/tool/mastering/makemaster.exe"
17MAKEDISCIMAGE="$CAFE_ROOT/system/bin/tool/mastering/makediscimage.exe"
18MAKEDOWNLOADIMAGE="$CAFE_ROOT/system/bin/tool/makecfdownloadimage.sh"
19MAKEIDBE="$CAFE_ROOT/system/bin/tool/mastering/makeidbe.exe"
20MAKEAOC="$CAFE_ROOT/system/bin/tool/makeaoc.sh"
21MAKEPATCH="$CAFE_ROOT/system/bin/tool/mastering/makepatch.exe"
22EXTRACTFILE="$CAFE_ROOT/system/bin/tool/mastering/extractfile.exe"
23
24G_INFOMSG=""
25G_WARNMSG=""
26G_ERRMSG=""
27G_IGNORE_ERROR=0
28G_APP_BUILD_TYPE=""
29G_OS_VERSION=""
30
31
32###############################################################################
33# arg num check
34###############################################################################
35arg_num_check()
36{
37    if [ $# -ne 2 ]
38    then
39        echo "Internal Error: number of argument: $#"
40        exit 2
41    fi
42    if  [ $1 -ne $2 ]
43    then
44        echo "Internal Error: number of argument: $1 (expected: $2)"
45        exit 2
46    fi
47}
48
49
50###############################################################################
51# dir check
52###############################################################################
53dir_check ()
54{
55    arg_num_check $# 2
56    local DIR="$1"
57    local CLEAN_UP="$2"
58
59    if [ -e "$DIR" ]
60    then
61        if [ ! -d "$DIR" ]
62        then
63            echo "$(basename "$0") failed: $DIR is not a directory."
64            return 1
65        fi
66        if [ "$CLEAN_UP" -eq 1 ]
67        then
68            rm -Rf "$DIR"
69            mkdir "$DIR"
70        fi
71    else
72        mkdir "$DIR"
73    fi
74
75    return 0
76}
77
78
79###############################################################################
80# add_msg
81###############################################################################
82add_msg()
83{
84    arg_num_check $# 1
85    local MSG="$1"
86    set $MSG
87    local MSGTYPE="$1"
88
89    echo "$MSG"
90    MSG=${MSG//\\/\\\\}
91    if [ "$MSGTYPE" == "Warning:" ]; then
92        G_WARNMSG="$G_WARNMSG$MSG\n"
93    elif [ "$MSGTYPE" == "Error:" ]; then
94        if [ "$G_IGNORE_ERROR" -eq 1 ]; then
95            G_ERRMSG="$G_ERRMSG$MSG\n"
96        else
97            echo "Use -i option to ignore errors."
98            exit 14
99        fi
100    else
101        G_INFOMSG="$G_INFOMSG$MSG\n"
102    fi
103}
104
105
106###############################################################################
107# add_msg_if_match
108###############################################################################
109add_msg_if_match()
110{
111    arg_num_check $# 3
112    local TARGET_FILE="$1"
113    local TARGET_HASH="$2"
114    local MSG="$3"
115    echo "$TARGET_HASH *$TARGET_FILE" | md5sum -c --status
116    local RESULT=$?
117    if [ "$RESULT" -eq 0 ]; then
118        add_msg "$MSG"
119    fi
120}
121
122
123###############################################################################
124# add_msg_if_not_match
125###############################################################################
126add_msg_if_not_match()
127{
128    arg_num_check $# 3
129    local TARGET_FILE="$1"
130    local TARGET_HASH="$2"
131    local MSG="$3"
132    echo "$TARGET_HASH *$TARGET_FILE" | md5sum -c --status
133    local RESULT=$?
134    if [ "$RESULT" -ne 0 ]; then
135        add_msg "$MSG"
136    fi
137}
138
139
140###############################################################################
141# Show messages
142###############################################################################
143show_msg()
144{
145    if [ -n "$G_INFOMSG" ]; then
146        echo "***<Information>************************************************"
147        echo -e "$G_INFOMSG"
148    fi
149    if [ -n "$G_WARNMSG" ]; then
150        echo "***<Warning>****************************************************"
151        echo "The following warnings should be removed before wumad submission."
152        echo -e "$G_WARNMSG"
153    fi
154    if [ -n "$G_ERRMSG" ]; then
155        echo "***<Error>******************************************************"
156        echo "The following errors occured while generating wumad."
157        echo "The output wumad may be invalid."
158        echo -e "$G_ERRMSG"
159    fi
160}
161
162###############################################################################
163# Check the Unique ID in the app.xml file
164###############################################################################
165check_unique_id ()
166{
167    arg_num_check $# 1
168
169    local badRangeMaxA=0x000FF
170    local badRangeMinB=0xF7000
171    local badRangeMaxB=0xF7BFF
172    local warnRangeMinC=0xF7C00
173    local warnRangeMaxC=0xF7FFF
174
175    local APP_XML_FILE="$1"
176    local uniqueId=0x$(sed -n 's|.*<title_id.*>.........\(.*\)..</title_id>|\1|p' "$APP_XML_FILE")
177	## Check the Unique ID for the specified ranges.
178    if [[ $uniqueId -le $badRangeMaxA || $uniqueId -ge $badRangeMinB && $uniqueId -le $badRangeMaxB ]]; then
179	cat <<EOF
180
181The Unique ID in use is reserved. Please change your Unique ID.
182Your current Unique ID is set to: $uniqueId
183This value is part of the Title ID and is located in your app.xml
184file between the <title_id> tags.
185
186<Example Title ID>
187000500001XXXXX00 The five "X" hex values represent the Unique Id.
188
189<Reserved for System>
1900x00000 Through $badRangeMaxA
191$badRangeMinB Through $badRangeMaxB
192
193<Reserved for Development>
194$warnRangeMinC Through $warnRangeMaxC
195EOF
196		add_msg "Error: Reserved Unique ID is used."
197    elif [[ $uniqueId -ge $warnRangeMinC && $uniqueId -le $warnRangeMaxC ]]; then
198        add_msg "Warning: Unique ID for development is used."
199    else
200	echo "Unique ID OK!"
201    fi
202}
203
204
205###############################################################################
206# check embedded appconfig version
207###############################################################################
208check_appconf_version()
209{
210    arg_num_check $# 1
211    local XML_FILE=$1
212    local APPCONF_VER=`sed -n 's|.*<appconfig-create-version>\([^<]*\).*|\1|p' "$XML_FILE"`
213    if [ -z $APPCONF_VER ]
214    then
215        add_msg "Warning: old xml file '$XML_FILE' detected: exported with an old appconfig tool"
216    else
217        echo "Appconfig tool version: $APPCONF_VER"
218    fi
219}
220
221
222###############################################################################
223# check_xml_version
224#
225#   copy default xml if destination xml doesn't exist
226#   otherwise, compare version.  exit or copy default if mismatch
227###############################################################################
228check_xml_version()
229{
230    arg_num_check $# 3
231    local FILE_DEST="$1"
232    local FILE_DEFAULT="$2"
233    local FILE_OPTION="$3"
234
235    if [ ! -f "$FILE_DEST" ]
236    then
237        echo "$(basename "$0"): Copying default config file to $FILE_DEST"
238        if [ ! -f "$FILE_DEFAULT" ]
239        then
240            echo "$(basename "$0") failed: Cannot find default config file $FILE_DEFAULT"
241            exit 12
242        fi
243        install -Dp "$FILE_DEFAULT" "$FILE_DEST"
244    else
245        # extract version number of xml element in file of the form:
246        local VER_DEFAULT=`sed -n 's|.*<wup-master-info tool-version="\([^"]*\)" format-version="\([^"]*\)".*>|\1|p' "$FILE_DEFAULT"`
247        local VER_DEST=`sed -n 's|.*<wup-master-info tool-version="\([^"]*\)" format-version="\([^"]*\)".*>|\1|p' "$FILE_DEST"`
248
249        if [ -z "$VER_DEST" -o -z "$VER_DEFAULT" ]
250        then
251            echo "$(basename "$0") failed: Cannot get xml version numbers"
252            exit 12
253        fi
254
255        if [ ! "$VER_DEST" = "$VER_DEFAULT" ]
256        then
257            if [ "$FILE_OPTION" = "copy_default_if_mismatch" ]
258            then
259                echo "$(basename "$0"): Config file version mismatch detected: $VER_DEST vs. required $VER_DEFAULT"
260                echo "         Copying default config file to $FILE_DEST"
261                if [ ! -f "$FILE_DEFAULT" ]
262                then
263                    echo "$(basename "$0") failed: Cannot find default config file $FILE_DEFAULT"
264                    exit 12
265                fi
266                install -Dp "$FILE_DEFAULT" "$FILE_DEST"
267            else
268                echo "$(basename "$0") failed: Please update or delete config file: $FILE_DEST"
269                echo "                Version number mismatch: $VER_DEST vs. required $VER_DEFAULT"
270                exit 10
271            fi
272        fi
273    fi
274}
275
276
277###############################################################################
278# extract_info_from_app_rpx
279# $1 - Path to app.rpx
280# $2 - Path to app.xml
281###############################################################################
282extract_info_from_app_rpx()
283{
284    arg_num_check $# 2
285    local APP_RPX_FILE_DOS=`cygpath -m "$1"`
286    local APP_XML="$2"
287
288    # get title id
289    G_APP_BUILD_TYPE=`dumprpl -fileinfo "$APP_RPX_FILE_DOS" | sed -n 's|.*BUILD_TYPE.\+\"\([A-Z]\+\)\"|\1|p'`
290
291    if [ -z "$G_APP_BUILD_TYPE" ]
292    then
293        add_msg "Warning: G_APP_BUILD_TYPE is NULL"
294        # Not error if G_APP_BUILD_TYPE is NULL
295    elif [ "$G_APP_BUILD_TYPE" == "DEBUG" ]
296    then
297        echo "DEBUG modify"
298        G_OS_VERSION=`sed -n 's|.*<os_version .*>\(.*\)</os_version>|\1|p' "$APP_XML"`
299        G_OS_VERSION=`echo "$G_OS_VERSION" | sed -n 's|\(........\)\(.\).....\(..\)|\1\200080\3|p'`
300    elif [ "$G_APP_BUILD_TYPE" == "NDEBUG" ]
301    then
302        echo "NDEBUG modify"
303        G_OS_VERSION=`sed -n 's|.*<os_version .*>\(.*\)</os_version>|\1|p' "$APP_XML"`
304        G_OS_VERSION=`echo "$G_OS_VERSION" | sed -n 's|\(........\)\(.\).....\(..\)|\1\200040\3|p'`
305    fi
306
307    echo "APP Build Type  : $G_APP_BUILD_TYPE"
308    echo "OS_VERSION      : $G_OS_VERSION"
309}
310
311
312###############################################################################
313# update_app_xml
314###############################################################################
315update_app_xml()
316{
317    arg_num_check $# 1
318    local APP_XML="$1"
319
320    if [ ! -f "$APP_XML" ]
321    then
322        add_msg "Warning: Cannot find default file $APP_XML"
323        # Not error if app xml is not found
324    else
325        if [ -n "$G_OS_VERSION" ]
326        then
327            # insert os version
328            sed -i -e "s|\(<os_version .*>\).*\(<.*>\)|\1$G_OS_VERSION\2|" "$APP_XML"
329            echo update app.xml $G_OS_VERSION $APP_XML
330        fi
331    fi
332}
333
334###############################################################################
335# update meta.xml
336###############################################################################
337update_meta_xml ()
338{
339    arg_num_check $# 1
340    local META_XML="$1"
341
342    if [ ! -f "$META_XML" ]
343    then
344        add_msg "Warning: Cannot find default file $META_XML"
345        # Not error if meta xml is not found
346    else
347        if [ -n "$G_OS_VERSION" ]
348        then
349            # insert os version
350            sed -i -e "s|\(<os_version .*>\).*\(<.*>\)|\1$G_OS_VERSION\2|" "$META_XML"
351            echo update meta.xml $G_OS_VERSION $META_XML
352        fi
353
354        local RESERVED6=$(sed -n 's|.*<reserved_flag6.*>\([0-9a-fA-F]*\)</reserved_flag6>|\1|p' "$META_XML")
355        # lowering 'mastering DLL' bit (lower 1 bit) and 'rating image' bits (upper 19 bits).
356        RESERVED6=$(printf "%d" $((0x00001FFE & 0x$RESERVED6)))
357        # update rating image bits
358        local RESERVED6_RATING=0
359        if [ "$G_METARATING_DISABLED" -eq 0 ]; then
360            local SHIFT_VAL=31
361            for IMG_NAME in ${G_RATING_IMG_NAME_LIST[@]}
362            do
363                if [ -f "$CAFE_META_DIR/$IMG_NAME.jpg" ]; then
364                    is_dummy_rating_file "$CAFE_META_DIR/$IMG_NAME.jpg"
365                    if [ $? -eq 0 ]; then
366                        RESERVED6_RATING=$(( RESERVED6_RATING + (1 << SHIFT_VAL) ))
367                    fi
368                fi
369                SHIFT_VAL=$((SHIFT_VAL - 1))
370            done
371        fi
372        RESERVED6=$(printf "%08X" $(( RESERVED6_RATING + RESERVED6 )))
373        sed -i -e "s|\(<reserved_flag6.*>\)\(.*\)\(</reserved_flag6>\)|\1$RESERVED6\3|" "$META_XML"
374    fi
375}
376
377###############################################################################
378# update_cos_xml
379###############################################################################
380update_cos_xml() 
381{
382    arg_num_check $# 1
383    local COS_XML="$1"
384    local CMD_FLAGS=0
385
386    # insert OSFlags between <cmdFlags.> and </cmdFlags.> xml tags
387    sed -i -e "s|\(<cmdFlags.*>\).*\(<.*>\)|\1$CMD_FLAGS\2|" "$COS_XML"
388}
389
390###############################################################################
391# embed_sdk_version_to_masterinfo
392# $1 - Path to masterinfo.xml
393###############################################################################
394embed_sdk_version_to_masterinfo()
395{
396    arg_num_check $# 1
397    local DEST_MASTERINFO_XML="$1"
398    local RPL_FILE
399    local RPL_FILE_DOS
400    local RPL_FILE_BASENAME
401    local RPL_BUILD_TYPE
402    local RPL_SDK_VERSION
403    local RPL_SDK_REVISION
404    local BUILD_INFO_STRING="      <build-info-list>\n"
405    
406    for RPL_FILE in "$CAFE_CODE_DIR"/*.rp[xl]
407    do
408        RPL_FILE_DOS=`cygpath -w -a $RPL_FILE`
409        RPL_FILE_BASENAME=`basename $RPL_FILE`
410        RPL_BUILD_TYPE=`dumprpl -fileinfo "$RPL_FILE_DOS" | sed -n 's|.*BUILD_TYPE.\+\"\([A-Z]\+\)\"|\1|p'`
411        RPL_SDK_VERSION=`dumprpl -fileinfo "$RPL_FILE_DOS" | sed -n 's|.*CAFE_OS_SDK_VERSION.\+\"\([0-9A-Fa-f]\+\)\"|\1|p'`
412        RPL_SDK_REVISION=`dumprpl -fileinfo "$RPL_FILE_DOS" | sed -n 's|.*CAFE_OS_SDK_REVISION.\+\"\([0-9A-Fa-f]\+\)\"|\1|p'`
413        
414        echo "build-info of $RPL_FILE_BASENAME:"
415        echo "     build: $RPL_BUILD_TYPE"
416        echo "   version: $RPL_SDK_VERSION"
417        echo "  revision: $RPL_SDK_REVISION"
418        
419        if [ -z "$RPL_BUILD_TYPE" ]; then
420            add_msg "Info: $RPL_FILE_BASENAME: BUILD_TYPE is NULL"
421        fi
422        if [ -z "$RPL_SDK_VERSION" ]; then
423            add_msg "Info: $RPL_FILE_BASENAME: SDK_VERSION is NULL"
424        fi
425        if [ -z "$RPL_SDK_REVISION" ]; then
426            add_msg "Info: $RPL_FILE_BASENAME: SDK_REVISION is NULL"
427        fi
428        
429        BUILD_INFO_STRING="$BUILD_INFO_STRING        <build-info>\n"
430        BUILD_INFO_STRING="$BUILD_INFO_STRING          <rpx-name>$RPL_FILE_BASENAME</rpx-name>\n"
431        BUILD_INFO_STRING="$BUILD_INFO_STRING          <build-type>$RPL_BUILD_TYPE</build-type>\n"
432        BUILD_INFO_STRING="$BUILD_INFO_STRING          <build-sdk-version>$RPL_SDK_VERSION</build-sdk-version>\n"
433        BUILD_INFO_STRING="$BUILD_INFO_STRING          <build-sdk-revision>$RPL_SDK_REVISION</build-sdk-revision>\n"
434        BUILD_INFO_STRING="$BUILD_INFO_STRING        </build-info>\n"
435    done
436    BUILD_INFO_STRING="$BUILD_INFO_STRING      </build-info-list>"
437    
438    local CURRENT_BUILD_INFO_LIST=`sed -n "/.*<build-info-list.*>/{; :loop; N; /.*<\/build-info-list>/! b loop; p; d}" "$DEST_MASTERINFO_XML"`
439    if [ -z "$CURRENT_BUILD_INFO_LIST" ]
440    then
441        # add <build-info-list> in the tail of <partition>
442        sed -i -e "s|\(.*</partition>\)|$BUILD_INFO_STRING\n\1|" "$DEST_MASTERINFO_XML"
443    else
444        # replace current <build-info-list>
445        sed -i -e "/.*<build-info-list.*>/{; :loop; N; /.*<\/build-info-list>/! b loop;
446                   s|.*<build-info-list.*>.*</build-info-list>|$BUILD_INFO_STRING|}" "$DEST_MASTERINFO_XML"
447    fi
448}
449
450###############################################################################
451# embed_tool_version_to_masterinfo
452# $1 - Path to masterinfo.xml
453###############################################################################
454embed_tool_version_to_masterinfo()
455{
456    arg_num_check $# 1
457    local DEST_MASTERINFO_XML="$1"
458    local MAKEDLF_USAGE=`"$MAKEDLF" -h`
459    local MAKEDLF_VERSION=`echo "$MAKEDLF_USAGE" | sed -n 's|.*ver\.\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*|\1|p'`
460    echo "makedlf-version:$MAKEDLF_VERSION"
461    
462    local CURRENT_MAKEDLF_VERSION=`sed -n 's|.*\(<makedlf-version.*>.*</makedlf-version>\)|\1|p' "$DEST_MASTERINFO_XML"`
463    if [ -z "$CURRENT_MAKEDLF_VERSION" ]
464    then
465        # add <makedlf-version>
466        sed -i -e "s|\(.*</partition>\)|      <makedlf-version>$MAKEDLF_VERSION</makedlf-version>\n\1|" "$DEST_MASTERINFO_XML"
467    else
468        # replace current <makedlf-version>
469        sed -i -e "s|\(<makedlf-version.*>\)\(.*\)\(</makedlf-version.*>\)|\1$MAKEDLF_VERSION\3|" "$DEST_MASTERINFO_XML"
470    fi
471    
472    local MAKEMASTER_USAGE=`"$MAKEMASTER" -h`
473    local MAKEMASTER_VERSION=`echo "$MAKEMASTER_USAGE" | sed -n 's|.*ver\.\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*|\1|p'`
474    echo "makemaster-version:$MAKEMASTER_VERSION"
475    
476    local CURRENT_MAKEMASTER_VERSION=`sed -n 's|.*\(<makemaster-version.*>.*</makemaster-version>\)|\1|p' "$DEST_MASTERINFO_XML"`
477    if [ -z "$CURRENT_MAKEMASTER_VERSION" ]
478    then
479        # add <makemaster-version>
480        sed -i -e "s|\(.*</partition>\)|      <makemaster-version>$MAKEMASTER_VERSION</makemaster-version>\n\1|" "$DEST_MASTERINFO_XML"
481    else
482        # replace current <makemaster-version>
483        sed -i -e "s|\(<makemaster-version.*>\)\(.*\)\(</makemaster-version.*>\)|\1$MAKEMASTER_VERSION\3|" "$DEST_MASTERINFO_XML"
484    fi
485}
486
487###############################################################################
488# embed_os_version_to_masterinfo
489# $1 - Path to masterinfo.xml
490###############################################################################
491embed_os_version_to_masterinfo()
492{
493    arg_num_check $# 1
494    local DEST_MASTERINFO_XML="$1"
495
496    if [ ! -f "$DEST_MASTERINFO_XML" ]
497    then
498        add_msg "Warning: Cannot find $DEST_MASTERINFO_XML"
499    else
500        if [ -n "$G_OS_VERSION" ]
501        then
502            # insert os version
503            local RESULT=$(printf "0x%s" $G_OS_VERSION)
504            sed -i -e "s|\(<os-version.*>\)\(.*\)\(</os-version.*>\)|\1$RESULT\3|" "$DEST_MASTERINFO_XML"
505            echo update $G_OS_VERSION $DEST_MASTERINFO_XML
506        fi
507    fi
508}
509
510###############################################################################
511# embed_ddf_info_to_masterinfo
512# $1 - Path to individual ddf file
513# $2 - Path to masterinfo.xml
514###############################################################################
515embed_ddf_info_to_masterinfo()
516{
517    arg_num_check $# 2
518    local DDF_FILE="$1"
519    local DEST_MASTERINFO_XML="$2"
520
521    if [ ! -f "$DEST_MASTERINFO_XML" ]
522    then
523        add_msg "Warning: Cannot find $DEST_MASTERINFO_XML"
524    elif [ ! -f "$DDF_FILE" ]
525    then
526        add_msg "Warning: Cannot find $DDF_FILE"
527    else
528        local VOLUME_ADDR=$(sed -n 's| *VolumeAddress *= *\([0-9a-fA-F]\+.*\)|\1|p' "$DDF_FILE")
529        local VOLUME_SIZE=$(sed -n 's| *VolumeSize *= *\([0-9a-fA-F]\+.*\)|\1|p' "$DDF_FILE")
530        if [ -n "$VOLUME_SIZE" ] && [ -n "$VOLUME_ADDR" ]
531        then
532            # insert os version
533            sed -i -e "s|\(<VolumeSize.*>\)\(.*\)\(</VolumeSize.*>\)|\1$VOLUME_SIZE\3|" "$DEST_MASTERINFO_XML"
534            sed -i -e "s|\(<VolumeAddress.*>\)\(.*\)\(</VolumeAddress.*>\)|\1$VOLUME_ADDR\3|" "$DEST_MASTERINFO_XML"
535            echo "update ddf information" $VOLUME_ADDR $VOLUME_SIZE "$DEST_MASTERINFO_XML"
536        else
537            add_msg "Warning: failed to update ddf information"
538        fi
539    fi
540}
541
542###############################################################################
543# embed_mastering_sdk_version
544# $1 - Path to masterinfo.xml
545###############################################################################
546embed_mastering_sdk_version()
547{
548    arg_num_check $# 1
549    local DEST_MASTERINFO_XML="$1"
550
551    if [ ! -f "$DEST_MASTERINFO_XML" ]
552    then
553        add_msg "Warning: Cannot find $DEST_MASTERINFO_XML"
554    else
555        local SDK_VER_H="$CAFE_ROOT/system/include/sdk_ver.h"
556        local SDK_VER=$(sed -n 's|[ \t]*#define[ \t]\+CAFE_OS_SDK_VERSION[ \t]*\([0-9a-fA-F]\+\).*|\1|p' "$SDK_VER_H")
557        local SDK_REV=$(sed -n 's|[ \t]*#define[ \t]\+CAFE_OS_SDK_BUILD_VERSION[ \t]*\"\([0-9a-fA-F]\+\).*|\1|p' "$SDK_VER_H")
558        if [ -n "$SDK_VER" ]
559        then
560            echo "mastering SDK version: $SDK_VER"
561            local CURRENT_MASTERING_SDK_VERSION_TAGS=$(sed -n 's|.*\(<mastering-sdk-version.*>.*</mastering-sdk-version>\)|\1|p' "$DEST_MASTERINFO_XML")
562            if [ -z "$CURRENT_MASTERING_SDK_VERSION_TAGS" ]
563            then
564                # add <mastering-sdk-version>
565                sed -i -e "s|\(.*</sdk-version>\)|      <mastering-sdk-version>$SDK_VER</mastering-sdk-version>\n\1|" "$DEST_MASTERINFO_XML"
566            else
567                # replace current <mastering-sdk-version>
568                sed -i -e "s|\(<mastering-sdk-version.*>\)\(.*\)\(</mastering-sdk-version.*>\)|\1$SDK_VER\3|" "$DEST_MASTERINFO_XML"
569            fi
570            local CURRENT_MASTERING_SDK_REVISION_TAGS=$(sed -n 's|.*\(<mastering-sdk-revision.*>.*</mastering-sdk-revision>\)|\1|p' "$DEST_MASTERINFO_XML")
571            if [ -z "$CURRENT_MASTERING_SDK_REVISION_TAGS" ]
572            then
573                sed -i -e "s|\(.*</sdk-version>\)|      <mastering-sdk-revision>$SDK_REV</mastering-sdk-revision>\n\1|" "$DEST_MASTERINFO_XML"
574            else
575                sed -i -e "s|\(<mastering-sdk-revision.*>\)\(.*\)\(</mastering-sdk-revision.*>\)|\1$SDK_REV\3|" "$DEST_MASTERINFO_XML"
576            fi
577        else
578            add_msg "Warning: failed to get sdk version"
579        fi
580    fi
581}
582
583###############################################################################
584# reset_mastering_flag
585# $1 - Path to masterinfo.xml
586# $2 - Path to meta.xml
587###############################################################################
588reset_mastering_flag()
589{
590    arg_num_check $# 2
591    local DEST_MASTERINFO_XML="$1"
592    local DEST_META_XML="$2"
593
594    if [ ! -f "$DEST_MASTERINFO_XML" ]
595    then
596        add_msg "Warning: Cannot find $DEST_MASTERINFO_XML"
597    elif [ ! -f "$DEST_META_XML" ]
598    then
599        add_msg "Warning: Cannot find $DDF_FILE"
600    else
601        local RESERVED6=$(sed -n 's|.*<reserved_flag6.*>\([0-9a-fA-F]*\)</reserved_flag6>|\1|p' "$DEST_META_XML")
602        RESERVED6=$(printf "%08X" $((0xFFFFFFFE & 0x$RESERVED6)))
603        RESERVED6_MASTERINFO="0x$RESERVED6"
604        sed -i -e "s|\(<reserved-flag6.*>\)\(.*\)\(</reserved-flag6>\)|\1$RESERVED6_MASTERINFO\3|" "$DEST_MASTERINFO_XML"
605        echo "Initialized mastering flag"
606    fi
607}
608
609###############################################################################
610# check_patch_save_datasize (DRAFT : CURRENTLY NOT USED)
611# $1 - Path to meta.xml
612# $2 - Path to masterinfo.xml of previous wumad.
613###############################################################################
614check_patch_save_size()
615{
616    arg_num_check $# 1
617    local META_XML="$1"
618    local PAST_MASTERINFO="$2"
619
620    if [ ! -f "$META_XML" -o ! -f "$PAST_MASTERINFO" ]; then
621        add_msg "Error: unexpected error in check_patch_save_size. meta.xml or masterinfo.xml not found."
622    else
623        local PAST_COMMON_SAVE_SIZE=$(sed -n 's|.*<common-save-size.*>0x\(.*\)</common-save-size>|\1|p' "$PAST_MASTERINFO")
624        local PAST_ACCOUNT_SAVE_SIZE=$(sed -n 's|.*<account-save-size.*>0x\(.*\)</account-save-size>|\1|p' "$PAST_MASTERINFO")
625
626        local PATCH_COMMON_SAVE_SIZE=$(sed -n 's|.*<common_save_size.*>\(.*\)</common_save_size>|\1|p' "$META_XML")
627        local PATCH_ACCOUNT_SAVE_SIZE=$(sed -n 's|.*<account_save_size.*>\(.*\)</account_save_size>|\1|p' "$META_XML")
628
629        if [ \( $PAST_COMMON_SAVE_SIZE != "0000000000000000" -a $PAST_COMMON_SAVE_SIZE != $PATCH_COMMON_SAVE_SIZE \) -o \( $PAST_ACCOUNT_SAVE_SIZE != "0000000000000000" -a $PAST_ACCOUNT_SAVE_SIZE != $PATCH_ACCOUNT_SAVE_SIZE \) ]; then
630            echo "<common_save_size> : $PAST_COMMON_SAVE_SIZE -> $PATCH_COMMON_SAVE_SIZE"
631            echo "<account_save_size> : $PAST_ACCOUNT_SAVE_SIZE -> $PATCH_ACCOUNT_SAVE_SIZE"
632            add_msg "Error: Save data size changed from other than 0."
633        fi
634    fi
635}
636
637# METARATING related variables/functions
638G_METARATING_DISABLED=0
639
640G_RATING_IMG_DUMMY_FILE="$CAFE_ROOT/system/bin/tool/mastering/resources/rating_img_dummy"
641G_RATING_IMG_NAME_LIST=("CERO_ja" "CGSRR_zh" "COB_en" "ESRB_fr" "ESRB_en" "GRB_ko" "OFLC_en" \
642                      "PEGI_ru" "PEGI_BBFC_en" "PEGI_Portugal_pt" "PEGI_it" "PEGI_nl" \
643                      "PEGI_es" "PEGI_de" "PEGI_fr" "PEGI_pt" "PEGI_en" "RAR_ru" "USK_de")
644
645readonly G_READONLY_DDF_METARATING_OFF=0
646readonly G_READONLY_DDF_METARATING_ON=1
647
648readonly G_READONLY_MASTERINFO_METARATING_OFF=0
649readonly G_READONLY_MASTERINFO_METARATING_ON=1
650
651readonly G_READONLY_FILE_NOT_FOUND=100
652readonly G_READONLY_TAG_NOT_FOUND=101
653readonly G_READONLY_TAG_INVALID_VALUE=102
654###############################################################################
655# ddf_has_metarating
656# $1 Path to ddf file (usualy individual ddf)
657# return G_READONLY_DDF_METARATING_ON if METARATING section exists, return G_READONLY_DDF_METARATING_OFF if not,
658# return G_READONLY_FILE_NOT_FOUND if ddf is not found.
659# (cafedevrun.sh also has this function)
660###############################################################################
661ddf_has_metarating()
662{
663    arg_num_check $# 1
664    local DDF_FILE="$1"
665    if [ ! -e $DDF_FILE ]; then
666        return $G_READONLY_FILE_NOT_FOUND
667    fi
668    # use SectionParam, as it is easy to use because its parameters are fixed.
669    grep -q '^[[:space:]]*"METARATING"[[:space:]]*=[[:space:]]*0x0000000000000000,[[:space:]]*0x00000400,[[:space:]]*0x02[[:space:]]*$' "$DDF_FILE"
670    if [ $? -ne 0 ]; then
671        echo "METARATING setting in [SectionParam] does not exist."
672        return $G_READONLY_DDF_METARATING_OFF
673    fi
674    echo "METARATING section exists in $DDF_FILE"
675    return $G_READONLY_DDF_METARATING_ON
676}
677
678###############################################################################
679# masterinfo_get_metarating_flag
680# $1 Path to masterinfo.xml
681# return the value of <metarating-flag> tag if the tag exists and it is 0 or 1.
682# ($G_READONLY_MASTERINFO_METARATING_ON(OFF))
683# if masterinfo.xml is not found, return G_READONLY_FILE_NOT_FOUND
684# if <metarating-flag> tag is not found, return $G_READONLY_TAG_NOT_FOUND
685###############################################################################
686masterinfo_get_metarating_flag()
687{
688    arg_num_check $# 1
689    local MASTER_INFO="$1"
690    if [ ! -e "$MASTER_INFO" ]; then
691        echo "$1 not found."
692        return $G_READONLY_FILE_NOT_FOUND
693    fi
694    grep -q "^[[:space:]]*<metarating-flag>.*</metarating-flag>[[:space:]]*$" "$MASTER_INFO"
695    if [ $? -ne 0 ]; then
696        return $G_READONLY_TAG_NOT_FOUND # tag not found. the value itself is not used.
697    fi
698    local FLAG_VALUE=$(sed -n 's|.*<metarating-flag>\(.*\)</metarating-flag>|\1|p' "$MASTER_INFO")
699    if [ "$FLAG_VALUE" == "0" ]; then
700        return $G_READONLY_MASTERINFO_METARATING_OFF
701    elif [ "$FLAG_VALUE" == "1" ]; then
702        return $G_READONLY_MASTERINFO_METARATING_ON
703    else
704        return $G_READONLY_TAG_INVALID_VALUE
705    fi
706}
707
708###############################################################################
709# masterinfo_set_metarating_flag
710# if <metarating-flag> does not exist, add and set.
711# $1 Path to masterinfo.xml
712# $2 Value. Must be 0 (no METARATING section) or 1 (METARATING section)
713###############################################################################
714masterinfo_set_metarating_flag()
715{
716    arg_num_check $# 2
717
718    local MASTER_INFO="$1"
719    local VALUE="$2"
720
721    if [ ! -e "$MASTER_INFO" ]; then
722        echo "$1 not found."
723        return
724    fi
725
726    if [ "$VALUE" -ne 0 -a "$VALUE" -ne 1 ]; then
727        add_msg "Error: <metarating-flag> must be 0 or 1."
728    fi
729
730    grep -q "^[[:space:]]*<metarating-flag>.*</metarating-flag>[[:space:]]*$" "$MASTER_INFO"
731
732    if [ $? -ne 0 ]; then
733        # tag not found.
734        sed -i -e "/<\/sdk-info>/a\\
735      <metarating-flag>$VALUE<\/metarating-flag>" "$MASTER_INFO"
736    else
737        sed -i -e "s|\(<metarating-flag>\).*\(<.*>\)|\1$VALUE\2|" "$MASTER_INFO"
738    fi
739}
740
741###############################################################################
742# masterinfo_get_metarating_use
743# $1 Path to masterinfo.xml
744# return the value of <metarating-use> tag if the tag exists and it is 0 or 1.
745# ($G_READONLY_MASTERINFO_METARATING_ON(OFF))
746# if masterinfo.xml is not found, return G_READONLY_FILE_NOT_FOUND
747# if <metarating-use> tag is not found, return $G_READONLY_TAG_NOT_FOUND
748###############################################################################
749masterinfo_get_metarating_use()
750{
751    arg_num_check $# 1
752    local MASTER_INFO="$1"
753    if [ ! -e "$MASTER_INFO" ]; then
754        echo "$1 not found."
755        return $G_READONLY_FILE_NOT_FOUND
756    fi
757    grep -q "^[[:space:]]*<metarating-use>.*</metarating-use>[[:space:]]*$" "$MASTER_INFO"
758    if [ $? -ne 0 ]; then
759        return $G_READONLY_TAG_NOT_FOUND # tag not found. the value itself is not used.
760    fi
761    local FLAG_VALUE=$(sed -n 's|.*<metarating-use>\(.*\)</metarating-use>|\1|p' "$MASTER_INFO")
762    if [ "$FLAG_VALUE" == "0" ]; then
763        return $G_READONLY_MASTERINFO_METARATING_OFF
764    elif [ "$FLAG_VALUE" == "1" ]; then
765        return $G_READONLY_MASTERINFO_METARATING_ON
766    else
767        return $G_READONLY_TAG_INVALID_VALUE
768    fi
769}
770
771
772###############################################################################
773# Copy dummy rating image files into $CAFE_META_DIR
774###############################################################################
775copy_dummy_rating_files()
776{
777    local IMG_NAME
778    for IMG_NAME in ${G_RATING_IMG_NAME_LIST[@]}
779    do
780        if [ ! -f "$CAFE_META_DIR/$IMG_NAME.jpg" ]; then
781            cp -p $G_RATING_IMG_DUMMY_FILE "$CAFE_META_DIR/$IMG_NAME.jpg"
782            if [ $? -ne 0 ]; then
783                add_msg "Error: Failed to copy dummy rating image."
784            fi
785            echo "A dummy rating image is copied into meta/$IMG_NAME.jpg"
786        fi
787    done
788}
789
790###############################################################################
791# Copy rating image files from past wumad
792# $1 Path to past wumad (windows)
793# $2 Path to temp dir (windows)
794###############################################################################
795copy_past_rating_image_files()
796{
797    arg_num_check $# 2
798
799    local PAST_WUMAD_WIN="$1"
800    local TEMP_OUT_DIR_WIN="$2"
801    local IMG_NAME
802
803    for IMG_NAME in ${G_RATING_IMG_NAME_LIST[@]}
804    do
805        if [ ! -f "$CAFE_META_DIR/$IMG_NAME.jpg" ]; then
806            $EXTRACTFILE -v -nc "-od=$EXTRACTFILE_OUT_DIR" "$PAST_WUMAD_WIN" "p01.res.METARATING.${IMG_NAME}.jpg"
807            if [ $? -eq 0 ]; then
808                mv "$EXTRACTFILE_OUT_DIR\p01.res.METARATING.${IMG_NAME}.jpg" "$CAFE_META_DIR/${IMG_NAME}.jpg"
809                echo "${IMG_NAME}.jpg is extracted from the past wumad and copied into the meta directory."
810            else
811                add_msg "Warning: Failed to extract %IMG_NAME from the past wumad. The past wumad could be invalid."
812                cp -p $G_RATING_IMG_DUMMY_FILE "$CAFE_META_DIR/$IMG_NAME.jpg"
813                echo "A dummy rating image is copied into meta/$IMG_NAME.jpg"
814            fi
815        else
816            echo "$IMG_NAME.jpg exists in the meta directory. Not copied from the past wumad."
817        fi
818    done
819}
820
821###############################################################################
822# is_dummy_rating_file
823# $1 Path to the individual ddf file
824# return 1 if $1 is dummy. return 0 otherwise.
825###############################################################################
826is_dummy_rating_file()
827{
828    arg_num_check $# 1
829    local IMAGE_FILE=`cygpath -u -a $1`
830    local FILE_SIZE=`wc -c < "$IMAGE_FILE"`
831    if [ $FILE_SIZE == 1 ]; then
832        # dummy rating file is 1byte(00).
833        local md5=`md5sum "$IMAGE_FILE"`
834        if [ ${md5%[[:space:]]*} == "93b885adfe0da089cdf634904fd59f71" ]; then
835            return 1
836        fi
837    fi
838    return 0
839}
840
841###############################################################################
842# make_metarating_rl_args_for_mastering
843# make argments for makemaster(makepatch) to put raw image files in wumad.
844# usage : ARGS=`make_metarating_rl_args_for_mastering`
845###############################################################################
846make_metarating_rl_args_for_mastering()
847{
848    local META_RLS=""
849    if [ "$G_METARATING_DISABLED" -eq 0 ]; then
850        local IMG_NAME
851        for IMG_NAME in ${G_RATING_IMG_NAME_LIST[@]}
852        do
853            if [ -f "${CAFE_META_DIR}/${IMG_NAME}.jpg" ]; then
854                local IMG_FULL_PATH=`cygpath -w -a "${CAFE_META_DIR}/${IMG_NAME}.jpg"`
855                META_RLS="${META_RLS}-rl=${IMG_FULL_PATH}:METARATING.${IMG_NAME}.jpg "
856            else
857                echo "${IMG_NAME}.jpg not found."
858                add_msg "Error: There is(are) missing rating image(s) in meta directory."
859            fi
860        done
861    fi
862    echo $META_RLS
863}
864
865
866
867###############################################################################
868# remove_dummy_rating_files (CURRENTLKY NOT USED)
869###############################################################################
870remove_dummy_rating_files()
871{
872    echo "remove dummy rating image files in $CAFE_META_DIR"
873    local IMG_NAME
874    for IMG_NAME in ${G_RATING_IMG_NAME_LIST[@]}
875    do
876        if [ -f "$CAFE_META_DIR/$IMG_NAME.jpg" ]; then
877            is_dummy_rating_file "$CAFE_META_DIR/$IMG_NAME.jpg"
878            if [ $? -eq 1 ]; then
879                rm "$CAFE_META_DIR/$IMG_NAME.jpg"
880            fi
881        fi
882    done
883}
884
885###############################################################################
886# check_section_entry_hash()
887###############################################################################
888check_section_entry_hash()
889{
890    local MAKEMASTER_USAGE=`"$MAKEMASTER" -h`
891    local MAKEMASTER_VERSION=`echo "$MAKEMASTER_USAGE" | sed -n 's|.*ver\.\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*|\1|p'`
892    local MAKEMASTER_VER_FOR_COMPARE=`echo "$MAKEMASTER_VERSION" | sed "s:\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\):\1\2:p" -n`
893
894    # if "tool ver" > "1.5.x then Enable Section Entry Hash
895    if [ $MAKEMASTER_VER_FOR_COMPARE -lt 15 ]; then
896	SECTION_ENTRY_HASH_OPTION=""
897	add_msg "Section Entry Hash Disable. makemaster.exe version $MAKEMASTER_VERSION"
898    fi
899}
900
901###############################################################################
902# update_xml_flag_section_entry_hash()
903# $1 masterinfo.xml path
904# $2 meta.xml path
905###############################################################################
906update_xml_flag_section_entry_hash()
907{
908    arg_num_check $# 2
909    local DEST_MASTERINFO_XML="$1"
910    local DEST_META_XML="$2"
911
912    local META_XML_RESERVED_FLAG_6=`sed -e "s:[ \t]\+<reserved_flag6.*>\(.*\)</reserved_flag6>:\1:p" -n $DEST_META_XML`
913    local MASTERINFO_XML_RESERVED_FLAG_6=`sed -e "s:[ \t]\+<reserved-flag6>0x\(.*\)</reserved-flag6>:\1:p" -n $DEST_MASTERINFO_XML`
914    local SECTION_ENTRY_HASH_RESERVED_FLAG6="0x00000002"
915
916    # if Section Entry Hash Disable. Unset bit1 in reserved-flag6
917    if [ -z "$SECTION_ENTRY_HASH_OPTION" ]; then
918	RESERVED6=$(printf "%08X" $((~$SECTION_ENTRY_HASH_RESERVED_FLAG6 & 0x$META_XML_RESERVED_FLAG_6)))
919	META_XML_RESERVED_FLAG_6="$RESERVED6"
920	sed -i -e "s|\(<reserved_flag6.*>\)\(.*\)\(</reserved_flag6>\)|\1$META_XML_RESERVED_FLAG_6\3|" "$DEST_META_XML"
921	sed -i -e "s|\(<reserved-flag6.*>\)\(.*\)\(</reserved-flag6>\)|\10x$META_XML_RESERVED_FLAG_6\3|" "$DEST_MASTERINFO_XML"
922    # else if Section Entry Hash Enable. Set bit1 in reserved-flag6
923    else
924	RESERVED6=$(printf "%08X" $(($SECTION_ENTRY_HASH_RESERVED_FLAG6 | 0x$META_XML_RESERVED_FLAG_6)))
925	META_XML_RESERVED_FLAG_6="$RESERVED6"
926	sed -i -e "s|\(<reserved_flag6.*>\)\(.*\)\(</reserved_flag6>\)|\1$META_XML_RESERVED_FLAG_6\3|" "$DEST_META_XML"
927	sed -i -e "s|\(<reserved-flag6.*>\)\(.*\)\(</reserved-flag6>\)|\10x$META_XML_RESERVED_FLAG_6\3|" "$DEST_MASTERINFO_XML"
928    fi
929}
930