1#!/usr/bin/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
15source $(dirname "$0")/xmain.sh
16#==============================
17#MAKE IMAGE
18#This script masters, images,
19#and installs a specified RPX
20#onto the console.
21#
22#VERSION 1.12
23#==============================
24
25displayHelp(){
26  FIL=$(basename "$0")
27  echo "Master, Image, Install, Launch script
28Options (optional):
29	-t <hex digits>    : Replaces low digits of the current
30	                      title ID in the app.xml file
31	-b                 : RPX is a debug version (default: NDEBUG)
32	-s                 : Install from an SD card (default: PCFS)
33	-n                 : Install to NAND (default: USB)
34	-x                 : Skip running the RPX for mastering/imaging
35	-m                 : Launch title from sysconfig rather than debugger
36	-o                 : Specify an image output directory (default: MLC/install)
37	-i                 : Specify the image filename (default: RPX file name)
38	-NM                : Do not master/image title
39	-NI                : Do not install title
40	-NL                : Do not launch title
41	-r <path/filename> : location of RPX (not including .rpx)
42	--help
43	  -h
44	  --h
45	  -help            : Display help
46
47Options (last optional):
48	-a: <args>         : arguments to run the RPX with
49
50Usage:
51$FIL [optionals] [-a ...]
52
53Example:
54#Using first RPX in current working directory (NDEBUG)
55$FIL
56
57#---or---
58#Specify parameters (args = anything past -a)
59$FIL -a -x 30 -y 20
60
61#---or---
62#Specify a path to a DEBUG RPX
63$FIL -b -r \"\$CAFE_ROOT/system/bin/\$TOOLCHAIN/\$PLATFORM\"/demo/helloworld/DEBUG/helloworld"
64  exit $1
65}
66
67initFlags
68#LAUNCH_DBG=0   #launch in debug mode (default)
69LAUNCH_DEVM=16  #launch from sysconfig
70	 NO_IMG=32  #do not master/image
71 NO_INSTALL=64  #do not install the title
72  NO_LAUNCH=128 #do not launch the title
73     NO_RUN=256 #do not run initially (mastering)
74 INSTALL_SD=512 #install from the SD card
75
76LAUNCH_FLAG=$((NO_LAUNCH|LAUNCH_DEVM))
77
78
79#==============================
80#         PARSE INPUT
81#==============================
82
83ARG=("$@")
84for((i=0;i<$#;++i));do
85  case "${ARG[i]}" in
86
87	#set title ID
88	-t)if [ $((++i)) -ge $# ];then
89	  break
90	fi
91	TID="${ARG[i]}"
92	verifyTID;;
93
94	#debug build of RPX
95	-b)FLG=$((FLG|DBG_BUILD));;
96	#install to NAND
97	-n)FLG=$((FLG|TITLE_MLC));;
98	#install from SD card
99	-s)FLG=$((FLG|INSTALL_SD));;
100	#launch from sysconfig
101	-m)FLG=$((FLG|LAUNCH_DEVM));;
102	#do not run the RPX before mastering
103	-x)FLG=$((FLG|NO_RUN));;
104	#do not master/img
105	-NM)FLG=$((FLG|NO_IMG));;
106	#do not launch
107	-NL)FLG=$((FLG|NO_LAUNCH));;
108	#do not install title
109	-NI)FLG=$((FLG|NO_INSTALL));;
110
111
112	#path to RPX
113	-r)if [ $((++i)) -ge $# ];then
114	  break
115	fi
116	FIL="${ARG[i]}";;
117
118	#RPX arguments
119	-a)ARG="${ARG[@]:$((++i))}"
120	break;;
121
122	#image output path
123	-o)if [ $((++i)) -ge $# ];then
124	  break
125	fi
126	OUT="${ARG[i]}";;
127
128	#image filename
129	-i)if [ $((++i)) -ge $# ];then
130	  break
131	fi
132	APP="${ARG[i]}";;
133
134	#display help and exit
135	-h|--h|-help|--help)
136	displayHelp 0;;
137  esac
138done
139if [ $i -ge $# ];then
140  unset ARG
141fi
142i=
143
144#==============================
145#        VERIFY INPUT
146#==============================
147#cannot do an imaging and launch without installing
148if [ $((FLG&(NO_IMG|NO_INSTALL|NO_LAUNCH))) == $NO_INSTALL ];then
149  die Cannot specify only option '-NI'
150fi
151
152#cannot specify parameters when not launching
153if [[ $((FLG&NO_LAUNCH)) != 0 && ! -z "$ARG" ]];then
154  unset ARG
155  echo Ignoring arguments '(-a)' with option '-NL'
156fi
157
158#check image variable specification
159if [ $((FLG&NO_IMG)) != 0 ];then
160  if [ ! -z "$OUT" ];then
161	unset OUT
162	echo Ignoring output directory '(-o)' with option '-NM'
163  fi
164  if [ ! -z "$TID" ];then
165	unset TID
166	echo Ignoring Title ID '(-t)' with option '-NM'
167  fi
168fi
169
170getRPX
171
172#default to RPX name?
173if [ -z "$APP" ];then
174  APP=$(basename "$FIL")
175  APP="${APP:0:$((${#APP}-4))}"
176fi
177
178#
179# For right now, we are only installing from MLC/install directory
180#
181if [[ ! -z "$OUT" && $((FLG&NO_INSTALL)) != 0 ]];then
182  if [ $(toLower $(realpath "$OUT")) != $(toLower $(realpath "$CAFE_MLC_DIR"/install)) ];then
183	die You cannot install a title from anywhere but the default directory
184  fi
185  unset OUT
186fi
187
188#default to USB if not specified
189if [ $((FLG&TITLE_HINT)) == 0 ];then
190  FLG=$((FLG|TITLE_USB))
191fi
192
193#auto kill inconsistant launch
194if [ $((FLG&LAUNCH_FLAG)) == $LAUNCH_FLAG ];then
195  FLG=$((FLG&(~LAUNCH_DEVM)))
196  echo No Launch and sysconfig launch specified, ignoring sysconfig launch
197fi
198
199
200#==============================
201#   OBTAIN TITLE ID (app.xml)
202#==============================
203#sync session
204doSync
205
206if [ $((FLG&(NO_IMG|NO_RUN))) == 0 ];then
207  #
208  #REALLY SHOTTY WAY OF GETTING
209  #ALL THE REQUIRED FILES TO MASTER
210  # - Rethink later?
211  #
212  i=
213  if [ $((FLG&DBG_BUILD)) != 0 ];then
214	i='-b'
215  fi
216  echo -ne Running the RPX...
217  #run the rpx on a new thread
218  FLG=$((FLG|1))
219  bash caferun &>/dev/null -z $i "$FIL" $ARG &
220
221  #sleep for 30 and stop the execution
222  i=
223  sleep 30
224  cafestop
225  FLG=$((FLG&(~1)))
226  echo done!
227fi
228
229#make sure app.xml was copied over
230if [ "$SESSION_MANAGER" == 1 ];then
231  tmp=$(basename "$FIL")
232  tmp="$CAFE_DATA_TMP"/${tmp:0:$((${#tmp}-4))}
233else
234  tmp=$(dirname "$FIL")
235fi
236tmp="$tmp"/app.xml
237if [ ! -e "$tmp" ];then
238  echo "$tmp"
239  die app.xml is not present in the RPX directory
240fi
241
242echo -ne Reading the app.xml...
243#obtain app.xml data
244arr=$(cat "$tmp")
245if [ $? != 0 ];then
246  die '
247'Failed to read the app.xml contents
248fi
249var=${#arr}
250arr=$(echo "$arr" | awk '{gsub(/\\/,"\\\\");print}')
251beg=0
252
253#locates a string in the data (sequential searching)
254strFind(){
255  let x=var-beg
256  l=${#1}
257  #length of str < data?
258  if [ $l -le $x ];then
259	#gets a 1 based index from the data, 0 if not found
260	i=`awk -v a="${arr:beg}" -v b="$1" 'BEGIN{printf index(a,b)}'`
261	if [ $i != 0 ];then
262	  let i=i-1+beg;
263	  return
264	fi
265  fi
266  l=0
267}
268
269#sets the new beginning point
270setBeg(){
271  let beg=i+l
272}
273
274#app.xml error
275badApp(){
276  die '
277'Corrupted app.xml
278}
279
280#check if the last search was successful
281resCheck(){
282  if [ $l == 0 ];then
283	badApp
284  fi
285}
286
287#find title id tag
288strFind '<title_id '
289resCheck
290setBeg
291
292#find end bracket
293strFind '>'
294resCheck
295setBeg
296
297#find tag closing
298strFind '<'
299resCheck
300
301#free data
302x=
303var=
304
305#set TID length
306l=${#TID}
307
308#obtain the ID with the replaced characters
309TID="${arr:beg:i-beg-l}$TID"
310
311#make sure we have something...
312if [ -z "$((0x$TID))" ];then
313  badApp
314fi
315
316#are we replacing the title ID?
317if [ $l != 0 ];then
318  #write new data
319  echo "${arr:0:beg}$TID${arr:i}" > "$tmp"
320  #check if write was successful
321  if [ $? != 0 ];then
322	die '
323'Failed to rewrite app.xml
324  fi
325fi
326
327#free data
328i=
329l=
330tmp=
331unset arr beg var
332echo done!
333
334#==============================
335#      MASTER/IMAGE DATA
336#==============================
337
338if [ $((FLG&NO_IMG)) == 0 ];then
339
340  echo Mastering the RPX...
341  #make directory to hold mastered title
342  x="$CAFE_ROOT/mstr"
343  if [ ! -d "$x" ];then
344	mkdir "$x"
345	if [ $? != 0 ];then
346	  die Failed to create mastering directory
347	fi
348  fi
349
350  x="$x/$APP"
351  #master the title
352  makecfmaster.sh -r "$FIL" -o "$x"
353  if [ $? != 0 ];then
354	die Mastering returned error
355  fi
356
357  echo done!
358
359  #check if successful
360  x="$x".wumad
361  if [ ! -f "$x" ];then
362	die Mastering failed
363  fi
364
365  echo Creating download image...
366
367  #get custom output directory
368  if [ ! -z "$OUT" ];then
369	OUT="-o $OUT"
370  fi
371  #image the title
372  makecfdownloadimage.sh -i "$x" $OUT
373  if [ $? != 0 ];then
374	die Imaging returned error
375  fi
376  x=
377
378  #free memory
379  if [ ! -z "$OUT" ];then
380	unset OUT
381  fi
382
383  echo done!
384fi
385
386
387#==============================
388# INSTALL/SYSCONFIG LAUNCH IMAGE
389#==============================
390
391#are we doing anything with this?
392if [ $((FLG&(LAUNCH_DEVM|NO_INSTALL))) != $NO_INSTALL ];then
393
394  #if we are installing, check if image is there
395  i=$((FLG&NO_INSTALL))
396  if [ $i == 0 ];then
397	APP="$APP"_p01
398	if [ ! -d "$CAFE_MLC_DIR/install/$APP" ];then
399	  die This title is not imaged
400	fi
401  fi
402
403  echo -ne Writing the custom sysconfig scripts...
404  #make a custom script
405  openSCP
406
407  #modify data for installing
408  l=$((FLG&TITLE_MLC))
409  if [ $i == 0 ];then
410	if [ $l == 0 ];then
411	  tmp=usb
412	else
413	  tmp=mlc
414	fi
415
416	writeSCP "set_install_dev $tmp"
417
418    #where are we installing this from?
419    tmp=storage_hfiomlc01/install
420	if [ $((FLG&INSTALL_SD)) != 0 ];then
421	  tmp=app_sd
422	  i=2
423	fi
424	writeSCP "install /vol/$tmp/$APP"
425  fi
426
427  #are we launching it from sysconfig (without debug)?
428  if [ $((FLG&LAUNCH_DEVM)) != 0 ];then
429	if [ ! -z "$ARG" ];then
430	  #add a space
431	  ARG=" $ARG"
432	fi
433
434	#bug work-around
435	writeSCPDelay
436
437	writeSCP "launch $TID$ARG"
438  fi
439
440  echo done!
441
442  #make sure they copy the image to the SD Card
443  if [[ $i == 2 && $((FLG&NO_IMG)) == 0 ]];then
444	echo '
445Please copy the image to an SD Card
446and insert it into the CAT-DEV...
447Press enter to continue...'
448	read i
449	unset i
450  fi
451
452  echo Running custom sysconfig scripts...
453  #run the script
454  runSCP
455  echo '
456'done!
457fi
458unset tmp i l x
459
460#==============================
461#        LAUNCH DEBUG
462#==============================
463
464if [ $((FLG&LAUNCH_FLAG)) == 0 ];then
465  echo Launching game with debugger...
466  #launch game via debug
467  trap runTrap INT
468  runDBG
469  echo '
470'done!
471fi
472exit 0
473