1#!/usr/bin/env bash
2
3###############################################################################
4#
5# Copyright (C) 2009-2013 Nintendo.  All rights reserved.
6#
7# These coded instructions, statements, and computer programs contain
8# proprietary information of Nintendo of America Inc. and/or Nintendo
9# Company Ltd., and are protected by Federal copyright law.  They may
10# not be disclosed to third parties or copied or duplicated in any form,
11# in whole or in part, without the prior written consent of Nintendo.
12#
13###############################################################################
14
15###############################################################################
16# extract_info_from_app_xml
17# $1 - Path to app.xml
18###############################################################################
19extract_info_from_app_xml()
20{
21    local APP_XML_FILE="$1"
22
23    # get title id
24    APP_TITLE_ID=`sed -n 's|.*<title_id .*>\(.*\)</.*>|\1|p' "$APP_XML_FILE"`
25    APP_GROUP_ID=`sed -n 's|.*<group_id .*>\(.*\)</.*>|\1|p' "$APP_XML_FILE"`
26    APP_TITLE_VERSION=`sed -n 's|.*<title_version .*>\(.*\)</.*>|\1|p' "$APP_XML_FILE"`
27
28    echo "App Title ID : $APP_TITLE_ID"
29    echo "App Group ID : $APP_GROUP_ID"
30    echo "App Title Version : $APP_TITLE_VERSION"
31}
32
33###############################################################################
34# checks if METARATING section exists int the individual ddf.
35# $1 Path to the ddf file (usualy individual ddf)
36# return 1 if METARATING exists, return 0 otherwise
37# (masteringfunctions.sh also has this function)
38###############################################################################
39readonly DDF_FILE_NOT_FOUND=100
40readonly DDF_METARATING_ON=1
41readonly DDF_METARATING_OFF=0
42ddf_has_metarating()
43{
44    local DDF_FILE="$1"
45    if [ ! -e $DDF_FILE ]; then
46        return $DDF_FILE_NOT_FOUND
47    fi
48    # use SectionParam, as it is easy to use because its parameters are fixed.
49    grep -q '^[[:space:]]*"METARATING"[[:space:]]*=[[:space:]]*0x0000000000000000,[[:space:]]*0x00000400,[[:space:]]*0x02[[:space:]]*$' "$DDF_FILE"
50    if [ $? -ne 0 ]; then
51        echo "METARATING setting in [SectionParam] does not exist."
52        return $DDF_METARATING_OFF
53    fi
54    echo "METARATING section exists in $DDF_FILE"
55    return $DDF_METARATING_ON
56}
57
58###############################################################################
59# main
60###############################################################################
61
62CAFEMAKEDLF="$CAFE_ROOT/system/bin/tool/mastering/cafemakedlf.exe"
63
64APP_TITLE_ID=0000000000000000
65APP_GROUP_ID=00000000
66APP_TITLE_VERSION=0000
67
68if [[ -z "$1" ]]; then
69	echo >&2 "cafedevrun.sh failed: image file required!" >&2
70	exit 50
71fi
72MAKE_PATCH="$2"
73CAFEMAKEDLF_OPTION="$3"
74KIOSK_DEFAULT_DDF="$4"
75METARATING_DISABLED="$5"
76
77CAFEDEVRUN_FILE=${1/\/*\//}
78CAFEDEVRUN_EXT=${CAFEDEVRUN_FILE##*.}
79CAFEDEVRUN_NAME=${CAFEDEVRUN_FILE%.*}
80CAFEDEVRUN_FILENAME=${CAFEDEVRUN_NAME##*\\}
81CAFEDEVRUN_DIR=${CAFEDEVRUN_FILE%\\*}
82
83if [ "$MAKE_PATCH" == "1" ]
84then
85	GAME_TYPE="GP"
86else
87	GAME_TYPE="GM"
88fi
89
90# Check temporary directory
91CAFEDEVRUN_WORK_DIR=`cygpath -w "${CAFEDEVRUN_NAME}_tmp"`
92mkdir -p "$CAFEDEVRUN_WORK_DIR"
93
94if [ -z "$INCLUDE_SYSTEM_DIR" ]
95then
96    INCLUDE_SYSTEM_DIR=0
97fi
98
99CAFE_BASEFILE_PATH="`cygpath -w "$CAFE_ROOT"/system/bin/tool/mastering/resources`"
100
101# Set individiaul ddf file and default ddf file
102if [ -e "${1%.*}.ddf" ]; then
103    INDIVIDUAL_DDF_FILE="${1%.*}.ddf"
104else
105    INDIVIDUAL_DDF_FILE=""
106fi
107
108if [ -z "$KIOSK_DEFAULT_DDF" ]; then
109    # makecfmaster.sh set $METARATING_DISABLED.
110    if [ -n "$METARATING_DISABLED" ]; then
111        if [ $METARATING_DISABLED -eq 1 ]; then
112            DEFAULT_DDF="$CAFE_BASEFILE_PATH\\default_nometarating.ddf"
113        else
114            DEFAULT_DDF="$CAFE_BASEFILE_PATH\\default.ddf"
115        fi
116    else
117        # code path for cafediscrun *.rpx.
118        if [ -e "$INDIVIDUAL_DDF_FILE" ]; then
119
120            SET_E=0
121            if [[ $- =~ e ]]; then
122                SET_E=1
123                set +e
124            fi
125
126            ddf_has_metarating $INDIVIDUAL_DDF_FILE
127
128            DDF_META=$?
129            if [[ SET_E -eq 1 ]]; then
130                set -e
131            fi
132
133            if [ $DDF_META -eq $DDF_METARATING_ON ]; then
134                DEFAULT_DDF="$CAFE_BASEFILE_PATH\\default.ddf"
135                METARATING_DISABLED=0
136            else
137                DEFAULT_DDF="$CAFE_BASEFILE_PATH\\default_nometarating.ddf"
138                METARATING_DISABLED=1
139            fi
140        else
141            DEFAULT_DDF="$CAFE_BASEFILE_PATH\\default_nometarating.ddf"
142            METARATING_DISABLED=1
143        fi
144    fi
145else
146    echo "Change default.ddf -> $KIOSK_DEFAULT_DDF"
147    DEFAULT_DDF=`cygpath -w -a "$KIOSK_DEFAULT_DDF"`
148    METARATING_DISABLED=1
149fi
150
151echo "Selected default ddf : $DEFAULT_DDF"
152
153COMMON_DDF_FILE="$CAFEDEVRUN_WORK_DIR\\common.ddf"
154# Use individual ddf file if exists
155if [ -e "$INDIVIDUAL_DDF_FILE" ]
156then
157    echo "Info: Found ddf file: $INDIVIDUAL_DDF_FILE"
158
159	echo "Change GameType to $GAME_TYPE"
160	sed -i -e "s|^ *\(GameType *= *\).*|\1$GAME_TYPE|" "$INDIVIDUAL_DDF_FILE"
161
162    # volume size, volume address check
163    INDIVIDUAL_DDF_VOLUME_SIZE=`sed -n 's|^ *VolumeSize *= *\([0-9x]*\)|\1|p' "$INDIVIDUAL_DDF_FILE"`
164    INDIVIDUAL_DDF_VOLUME_ADDR=`sed -n 's|^ *VolumeAddress *= *\([0-9x]*\)|\1|p' "$INDIVIDUAL_DDF_FILE"`
165    DEFAULT_DDF_VOLUME_SIZE=`sed -n 's|^ *VolumeSize *= *\([0-9x]*\)|\1|p' "$DEFAULT_DDF"`
166    DEFAULT_DDF_VOLUME_ADDR=`sed -n 's|^ *VolumeAddress *= *\([0-9x]*\)|\1|p' "$DEFAULT_DDF"`
167    DDF_VOLUME_SIZE=$INDIVIDUAL_DDF_VOLUME_SIZE
168    DDF_VOLUME_ADDR=$INDIVIDUAL_DDF_VOLUME_ADDR
169    if [ -z "$DDF_VOLUME_SIZE" ]; then
170        DDF_VOLUME_SIZE=$DEFAULT_DDF_VOLUME_SIZE
171    fi
172    if [ -z "$DDF_VOLUME_ADDR" ]; then
173        DDF_VOLUME_ADDR=$DEFAULT_DDF_VOLUME_ADDR
174    fi
175    # dummy partition
176    ((DUMMY_PARTITION_VOLUME_SIZE=0x40))
177    ((UPPERBOUND_VOLUME_ADDRESS=(0x00018000 + 0x000A2740 - DUMMY_PARTITION_VOLUME_SIZE)))
178    if ((UPPERBOUND_VOLUME_ADDRESS < (DDF_VOLUME_ADDR + DDF_VOLUME_SIZE)))
179    then
180        ((DDF_VOLUME_SIZE=(UPPERBOUND_VOLUME_ADDRESS - DDF_VOLUME_ADDR)))
181        DDF_VOLUME_SIZE=`printf "0x%08X" "${DDF_VOLUME_SIZE}"`
182        if [ -n "$INDIVIDUAL_DDF_VOLUME_SIZE" ]; then
183            sed -i -e "s|^ *VolumeSize *=.*$|VolumeSize = ${DDF_VOLUME_SIZE}|" "$INDIVIDUAL_DDF_FILE"
184            echo "Warning: reduced volume size in order to add a partition - old: $INDIVIDUAL_DDF_VOLUME_SIZE new: $DDF_VOLUME_SIZE"
185        else
186            echo "$(basename $0) failed: value of VolumeAddress + VolumeSize is out of range" >&2
187            exit 52
188        fi
189    fi
190fi
191
192# Extract Title ID, Group ID, Title Version from app.xml to put in common.ddf
193APP_XML_FILE="$CAFEDEVRUN_DIR/app.xml"
194if [ ! -f "$APP_XML_FILE" ]
195then
196    echo "$(basename $0) failed: Cannot find $APP_XML_FILE" >&2
197    exit 53
198fi
199extract_info_from_app_xml "$APP_XML_FILE"
200
201# Generate common.ddf
202echo ";
203; $CAFEDEVRUN_NAME.$CAFEDEVRUN_EXT
204;
205[Input]
206DiscHeaderBaseFileName=\"$CAFE_BASEFILE_PATH\\discheader_base.bin\"
207VolumeHeaderBaseFileName=\"$CAFE_BASEFILE_PATH\\volheader_base.bin\"
208[Output]
209LayoutFileName=\"$CAFEDEVRUN_NAME.dlf\"
210OutputDirectory=\"$CAFEDEVRUN_DIR\"
211AppName=\"$CAFEDEVRUN_FILENAME\"
212Mode=WU
213[DiscID]
214GameType=$GAME_TYPE
215TitleId=0x$APP_TITLE_ID
216GroupId=0x$APP_GROUP_ID
217DiskNumber=0
218GameVersion=`expr $(printf %d 0x$APP_TITLE_VERSION) / 16`
219[SectionParam]
220\"CONTENT\"=0x$APP_TITLE_ID,0x$APP_GROUP_ID,0x02
221[PathList]
222CODE_DIR_RPX=\"code\", \"\$(CAFE_CODE_DIR)\\$CAFEDEVRUN_FILENAME.rpx\"
223" > "$COMMON_DDF_FILE"
224
225if [ "$INCLUDE_SYSTEM_DIR" -eq 1 ]
226then
227	echo "
228[PathList]
229SYSTEM_DIR=\"sys\", \"\$(CAFE_SYSTEM_DIR)\"
230[SectionAssign]
2312147483647 = \"sys/*\", \"CONTENT\", 0x400
232[FileLayout]
233-6=\"sys/*\", -2147483648
234" >> "$COMMON_DDF_FILE"
235fi
236
237if [ $METARATING_DISABLED -eq 1 ]; then
238    echo "
239[LayoutOff]
240\"\$(CAFE_META_DIR)\\CERO_ja.jpg\"
241\"\$(CAFE_META_DIR)\\CGSRR_zh.jpg\"
242\"\$(CAFE_META_DIR)\\COB_en.jpg\"
243\"\$(CAFE_META_DIR)\\ESRB_en.jpg\"
244\"\$(CAFE_META_DIR)\\ESRB_fr.jpg\"
245\"\$(CAFE_META_DIR)\\GRB_ko.jpg\"
246\"\$(CAFE_META_DIR)\\OFLC_en.jpg\"
247\"\$(CAFE_META_DIR)\\PEGI_BBFC_en.jpg\"
248\"\$(CAFE_META_DIR)\\PEGI_de.jpg\"
249\"\$(CAFE_META_DIR)\\PEGI_en.jpg\"
250\"\$(CAFE_META_DIR)\\PEGI_es.jpg\"
251\"\$(CAFE_META_DIR)\\PEGI_fr.jpg\"
252\"\$(CAFE_META_DIR)\\PEGI_it.jpg\"
253\"\$(CAFE_META_DIR)\\PEGI_nl.jpg\"
254\"\$(CAFE_META_DIR)\\PEGI_Portugal_pt.jpg\"
255\"\$(CAFE_META_DIR)\\PEGI_pt.jpg\"
256\"\$(CAFE_META_DIR)\\PEGI_ru.jpg\"
257\"\$(CAFE_META_DIR)\\RAR_ru.jpg\"
258\"\$(CAFE_META_DIR)\\USK_de.jpg\"
259" >> "$COMMON_DDF_FILE"
260fi
261
262# Temporarily convert to windows format path for CafeMakeDlf.
263CAFE_CODE_DIR="$(cygpath -w "$CAFE_CODE_DIR")"
264CAFE_META_DIR="$(cygpath -w "$CAFE_META_DIR")"
265CAFE_CONTENT_DIR="$(cygpath -w "$CAFE_CONTENT_DIR")"
266if [ "$INCLUDE_SYSTEM_DIR" -eq 1 ]
267then
268	CAFE_SYSTEM_DIR="$(cygpath -w "$CAFE_SYSTEM_DIR")"
269fi
270
271"$CAFEMAKEDLF" -uf "$DEFAULT_DDF" "$COMMON_DDF_FILE" "$INDIVIDUAL_DDF_FILE" $CAFEMAKEDLF_OPTION
272rval=$?
273
274CAFE_CODE_DIR="$(cygpath -a "$CAFE_CODE_DIR")"
275CAFE_META_DIR="$(cygpath -a "$CAFE_META_DIR")"
276CAFE_CONTENT_DIR="$(cygpath -a "$CAFE_CONTENT_DIR")"
277if [ "$INCLUDE_SYSTEM_DIR" -eq 1 ]
278then
279	CAFE_SYSTEM_DIR="$(cygpath -a "$CAFE_SYSTEM_DIR")"
280fi
281
282if [ $rval -ne 0 ]
283then
284    exit 54
285fi
286
287# WORKAROUND for makedlf 0.27.0.*: Need empty line in the end of dlf file for block emulation mode by FSEmul.
288echo "0x00000005D3A00000,\"\"" >> "$CAFEDEVRUN_NAME.dlf"
289