#!/usr/bin/bash

ZELDA_TOOL_BIN=$ZELDA_ROOT/tool/bin
#PATH=$ZELDA_TOOL_BIN:$PATH
PATH=/usr/bin

ROMFILL=$ZELDA_TOOL_BIN/romfill
ROMADDRESS=$ZELDA_TOOL_BIN/romaddress
ROMALIGN=$ZELDA_TOOL_BIN/romalign
ROMDIVIDE=$ZELDA_TOOL_BIN/romdivide
ROMMAP=$ZELDA_TOOL_BIN/rommap
ROMMAP_NEW=$ZELDA_TOOL_BIN/rommap_new
SLICNV=$ZELDA_TOOL_BIN/slicnv
SLIENC=$ZELDA_TOOL_BIN/sliencV11
SLIDEC=$ZELDA_TOOL_BIN/slidec
MAKEMASK=/usr/sbin/makemask
GZIP=/usr/sbin/gzip

echo -n "Tool checking ..."
for tool in $ROMADDRESS $ROMALIGN $ROMDIVIDE $ROMMAP $SLICNV $SLIENC $SLIDEC $ROMFILL
do
  echo -n "$(basename $tool) "
  if [ ! -x $tool ]; then
    echo $tool not exist
    exit 1
  fi
done
echo "ok"

#
#
#
date_HMS() {
    date +%H:%M:%S
}

#
# 行を消去し、カーソルを復帰する
#
clearline() {
  echo -n -e "\r\033[K" >&2
}

#
# *.d を連結する。
# *.szpが存在すれば、*.dの代わりに連結する
# *.szsが存在すれば、*.szpの代わりに連結する
#
szpcat() {
  for dfile in $*
  do
    szpfile=${dfile%.d}.szp
    szsfile=${dfile%.d}.szs
    clearline
    if [ -f $szsfile ]; then
      echo -n "$szsfile" >&2
      cat $szsfile
    elif [ -f $szpfile ]; then
      echo -n "$szpfile" >&2
      cat $szpfile
    else
      echo -n "$dfile" >&2
      cat $dfile
    fi
  done
  echo >&2
}

#
# 引数の拡張子を .d に変更し、_DECL_(ファイル名.d) として表示する
#
echodecl() {
  for segment in $*
  do
    echo "_DECL_(${segment%.d})"
  done
}

#
# .d ファイルを圧縮し、 .szp ファイルを作成する
# 既に正当な .szp ファイルが存在している場合は圧縮しません
#  .szp ファイルは１６の倍数になります。
# 引数は一つだけ
#
d2szp1() {

  dfile=$1
  ddfile=${dfile%.d}.dd
  szpfile=${dfile%.d}.szp
  
  if [ ! -f $dfile ]; then
    echo " $dfile は存在しません" >&2
    return 1;
  fi
  if [ -f $szpfile ]; then
    if [ $cflag = 1 ]; then return 0; fi
    echo -n " 解凍 "
    $SLIDEC $szpfile $ddfile
    echo -n " 比較 "
    cmp $dfile $ddfile
    r=$?
    rm -f ${ddfile}
    if [ $r = 0 ]; then 
      echo -n " 一致 "
      return 0;
    fi
  fi
  echo -n " 圧縮 "
  $SLIENC $dfile > /dev/null 2>&1
  $ROMALIGN 16 $szpfile
}

#
# .d ファイルを圧縮し、 .szs ファイルを作成する
# 既に正当な .szs .szp ファイルが存在している場合は圧縮しません
#  .szs ファイルは１６の倍数になります。
# 引数は一つだけ
#
d2szs1() {

  dfile=$1
  szsfile=${dfile%.d}.szs

  if [ ! -f $dfile ]; then
    echo "$dfile は存在しません" >&2
    return 1;
  fi
  $GZIP -9 -c -n $dfile | dd bs=10 skip=1 of=$szsfile
  $ROMALIGN 16 $szsfile
}

rmv() {
  for file in $*
  do
    if [ -f $file ]; then
      echo " $file を削除します " >&2
      rm -f $file
    fi
  done
}

#
# *.d を圧縮する。
#
sli() {
  no=1
  for dfile in $*
  do
    clearline
    echo -n "$no/$#:$dfile" >&2
    szpfile=${dfile%.d}.szp
    szsfile=${dfile%.d}.szs
    ddfile=${dfile%.d}.dd
    case ${dfile} in
      makerom.d | boot.d | dmadata.d | soundBankData.d | soundSequanceData.d | soundWaveData.d)
        echo " 圧縮しません（対象外） " >&2
        rmv $szpfile $szsfile
        ;;
        UC_object_*.d | _sound*.d | *test*.d | sm_ephrase_static.d | sm_letter_static.d)
        echo " 圧縮しません（分割ＤＭＡ） " >&2
        rmv $szpfile $szsfile
        ;;
      test01_*.d )
        echo " 圧縮しません（ツールテスト用） " >&2
        rmv $szpfile $szsfile
        ;;
      d2_*_pal_static.d)
        echo " 圧縮しません（非効率） " >&2
        rmv $szpfile $szsfile
        ;;
      code.d | ovl_*.d )
        if [ $pflag = 2 -o $pflag = 1 ]; then
          d2szs1 $dfile
        else
          echo " 圧縮しません（高速化） " >&2
          rmv $szpfile $szsfile
        fi
        ;;
      * )
        if [ $pflag = 2 ]; then
          d2szs1 $dfile
        else
          echo " 圧縮しません（高速化） " >&2
          rmv $szpfile $szsfile
        fi
        ;;
    esac
    if [ -f $szpfile -a ! -f $szsfile ]; then
      echo "$szpfile があるのに $szsfile がない" >&2
    fi
        #echo " ベリファイ省略！ " >&2
    no=$((no+1))
  done
  echo >&2
}

#
# *.d を連結する。
# *.szpが存在すれば、*.dの代わりに連結する
#
sli_scene() {
  for scene in $*
  do
    sli ${scene}_scene.d ${scene}_room_*.d
  done
}

#
# ファイルのチェック
#
read_check() {
  for file in $*
  do
    if [ ! -f $file ]; then
      echo $file がありません
      exit 1
    elif [ ! -r $file ]; then
      echo $file が読めません
      exit 1
    fi
  done
}

#
# オプション解析
#
optana() {
  pflag=0 # 動作モード
  cflag=0 # 1:圧縮キャッシュの整合性をチェックしない
  bflag=1 # 1:ベリファイしない
  while getopts ":p:c:b:" opt; do
    case $opt in
      p ) pflag=$OPTARG ;;
      c ) cflag=$OPTARG ;;
      b ) bflag=$OPTARG ;;
      \? ) echo 'usage: zelda_press [-p #] [-c #] [-b #]'
           echo '-p0 : *圧縮せずにテーブルだけをつくる'
           echo '-p1 : 高速に圧縮する'
           echo '-p2 : 完全に圧縮する'
           echo '-p3 : 分割だけを行う'
           echo '-c1 : 圧縮キャッシュの整合性をチェックしない'
           echo '-c0 : *圧縮キャッシュの整合性をチェックする'
           echo '-b1 : *ベリファイしない'
           echo '-b0 : ベリファイする'
           return 1 ;;
    esac
  done
}

optana $* || exit 1

ZELDA_INFO=forest_makerom.stdout
ROMIMG=rom
ROMPAK=romP
ROMPAK16=romPP
##ROMPAK32=romPP

echo $(date_HMS) "7 $ZELDA_INFO を解析し、rom.map を作成"
read_check $ZELDA_INFO
work=$(grep "Creating segment symbol source file in" $ZELDA_INFO)
work=${work#"Creating segment symbol source file in "}
read_check $work
$ROMMAP_NEW $work > rom.map
if [ $? != 0 ]; then echo "ERROR!!";exit 1; fi

SEGDCL=m_segment.decl
SEGBAK=m_segment.decl.bak
SEGTMP=m_segment.decl.tmp
echo $(date_HMS) "6 rom.map を解析し $SEGDCL を作成"
dfiles=$(tail +2 rom.map|cut -d" " -f1)
#(echo "/* Don't check in this file!! */"; echodecl $dfiles) > $SEGTMP
echodecl $dfiles > $SEGTMP

if ! cmp $SEGDCL $SEGTMP
then
  echo 
  echo "＊圧縮に必要なテーブルを更新しました"
  echo "＊圧縮ROMをつくるためにはこのテーブルを組み込む必要があります"
  echo "＊もう一度 make し直してください＊"
  echo 
  mv $SEGDCL $SEGBAK
  mv $SEGTMP $SEGDCL
  exit 1
fi

if [ $pflag = 0 ]; then exit 0; fi

echo $(date_HMS) '5 $ROMIMG を分割し、*.d を作成'
read_check $ROMIMG
$ROMDIVIDE rom.map $ROMIMG
if [ $? != 0 ]; then echo "ERROR!!";exit 1; fi

if [ $pflag = 3 ]; then exit 0; fi

echo $(date_HMS) '4 *.d を圧縮し、 *.szp を作成'
sli *.d

echo $(date_HMS) '3 *.d *.szp のサイズを調べ、dmadata.d を作成'
read_check dmadata.d
cp dmadata.d dmadata.d.bak
echo "dmadata のマップ情報は dmadata.map に出力されます"
$ROMADDRESS rom.map dmadata.d > dmadata.map
if [ $? != 0 ]; then echo "ERROR!!";exit 1; fi
#ls -l dmadata.d dmadata.d.bak

echo $(date_HMS) '2 *.d *.szp を連結して 圧縮 $ROMIMG を作成'
read_check makerom.d
szpcat makerom.d $dfiles > $ROMPAK

echo " makemaskは省略します "
##echo " makemaskするとgloadできなくなる "
##$MAKEMASK $ROMPAK
if [ $? != 0 ]; then echo "ERROR!!";exit 1; fi

# ７−１ マスタデータのターゲット容量への切り上げ（ランクＡ）
#
##echo $(date_HMS) "1 ロムサイズ調整＆結果表示 (32M=33554432)"
##$ROMFILL $ROMPAK $ROMPAK32 33554432
##ls -l $ROMIMG $ROMPAK $ROMPAK32
echo $(date_HMS) "1 ロムサイズ調整＆結果表示 (16M=16777216)"
$ROMFILL $ROMPAK $ROMPAK16 16777216
ls -l $ROMIMG $ROMPAK $ROMPAK16

echo $(date_HMS) "0 後始末"
#\rm $ROMPAK *.d *.dd *.szp
