nds2rm/nds2rm
agibert 43dc7297d4 - Add .xml file loading support,
- Remove obsolete .dat file loading support,
- Now nds2rm is independant and nds-gen useless !
- Redirect processing messages to stderr.
2009-03-30 22:57:13 +00:00

1422 lines
29 KiB
Bash

#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
# NDS2RM: NDS Simple Rom Manager
#
# (C) 2009 Arnaud G. Gibert
#-----------------------------------------------------------------------------------------------------------------------------------
# $RCSfile: nds2rm,v $
# $Revision: 1.9 $
# $Name: $
# $Date: 2009/03/30 22:57:13 $
# $Author: agibert $
#-----------------------------------------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------------------------------------
# This file is part of NDS2RM
#
# NDS2RM is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public Licence as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# NDS2RM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NDS2RM; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#-----------------------------------------------------------------------------------------------------------------------------------
# User Config
#-----------------------------------------------------------------------------------------------------------------------------------
#NDS_REPOSITORY_IN=/opt/public/nds
NDS_REPOSITORY_IN=/opt/public/nds.new
#NDS_REPOSITORY_IN=/opt/public/nds.new/nds.old
#NDS_REPOSITORY_IN=/opt/public/nds.new/nds.new
NDS_REPOSITORY_OUT=/opt/public/nds.new
#NDS_REPOSITORY_OUT=/opt/public/nds.new/nds.new
NDS_ROMS_IN=${NDS_REPOSITORY_IN}/roms
NDS_ROMS_OUT=${NDS_REPOSITORY_OUT}/roms
NDS_XML=${NDS_REPOSITORY_IN}/misc/dsrom.xml
# System Constants
#-----------------------------------------------------------------------------------------------------------------------------------
STATS_FILE="stats.txt"
TMP_DIR=$(mktemp -d)
JOB_NB=8
NDS_VERSION="$Name: $"
RNFH_REGEX=".... - .* \(.*:.*\) \[..\] \{.*\} <.*>[-]*[0-9]*\.zip$"
reg_tab[0]="E"; # Europe
reg_tab[1]="U"; # USA
reg_tab[2]="G"; # Germany
reg_tab[3]="C"; # China
reg_tab[4]="S"; # Spain
reg_tab[5]="F"; # France
reg_tab[6]="I"; # Italy
reg_tab[7]="J"; # Japan
reg_tab[8]="Nl"; # Nederland
reg_tab[9]="En"; # England
reg_tab[10]="Dn"; # Denmark
reg_tab[11]="Fi"; # Finland
reg_tab[12]="No"; # Norway
reg_tab[13]="Pl"; # Poland
reg_tab[14]="Pr"; # Portugal
reg_tab[15]="Sw"; # Sweden
reg_tab[16]="UE"; # USA and Europe
reg_tab[17]="JUE"; # Japan, USA and Europe
reg_tab[18]="JU"; # Japan and USA
reg_tab[19]="Au"; # Australia
reg_tab[20]="nK"; # North Korea
reg_tab[21]="Br"; # Brazil
reg_tab[22]="K"; # South Korea
reg_tab[23]="EB"; # Europe and Brazil
reg_tab[24]="EUB"; # Europe, USA and Brazil
reg_tab[25]="UB"; # USA and Brazil
reg_tab[26]="R"; # Russia
reg_tab[27]="R"; # Russia
reg_tab[28]="Gr"; # Greece
lang_tab[1]="Fr"; # French
lang_tab[2]="En"; # English
lang_tab[4]="Zh"; # Chinese
lang_tab[8]="da"; # Danish
lang_tab[16]="Nl"; # Dutch
lang_tab[32]="Fi"; # Finnish
lang_tab[64]="De"; # German
lang_tab[128]="It"; # Italian
lang_tab[256]="Ja"; # Japanese
lang_tab[512]="Nn"; # Norwegian
lang_tab[1024]="Pl"; # Polish
lang_tab[2048]="Pt"; # Portuguese
lang_tab[4096]="Es"; # Spanish
lang_tab[8192]="Sv"; # Swedish
lang_tab[16384]="En"; # English
lang_tab[32768]="Pt"; # Portuguese
lang_tab[65536]="Ko"; # Korean
lang_tab[131072]="Ru"; # Russian
lang_tab[262144]="El"; # Greek
# Print Version
#-----------------------------------------------------------------------------------------------------------------------------------
function version_print()
{
echo ${NDS_VERSION} | sed -e 's/.*: //' -e 's/-/ /' -e 's/_/\./g' -e 's/\$$//'
}
# Prin Help
#-----------------------------------------------------------------------------------------------------------------------------------
function help_print()
{
echo "-C|--correct: output repository will be corrected"
echo "-T|--test: input repository will be tested (default)"
echo "-D|--dsrom: dsrom.lst will be dumped"
echo "-h|--help: print this help and exit"
echo "-V|--version: print the version and exit"
echo "-r|--rebuild: don't trust archive file name (test & correct mode)"
echo " rebuild archives (correct mode)"
echo "-m|--max <id>: maximum rom id to load from dat file"
echo "-n|--renum: try to renumber archives"
echo " --list_ok: list roms with ok status"
echo " --list_ko: list roms with ko status"
echo " --list_miss: list missing roms"
echo "-v|--verbose: switch on verbosity"
}
# Parse Args
#-----------------------------------------------------------------------------------------------------------------------------------
function args_parse()
{
mode="test"
rebuild="no"
renum="no"
lok="no"
lko="no"
lmiss="no"
verbose="no"
max_idx=9999
tmp_args=$(getopt -o CTDhVrm:nv --long correct,test,dsrom,help,version,rebuild,max:,renum,list_ok,list_ko,list_miss,verbose -n 'nds_rom_mng' -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "${tmp_args}"
while true ; do
case "$1" in
-C|--correct) mode="correct"; shift;;
-T|--test) mode="test"; shift;;
-D|--dsrom) mode="dsrom"; shift;;
-h|--help) mode="exit"; help_print; shift;;
-V|--version) mode="exit"; version_print; shift;;
-r|--rebuild) rebuild="yes"; shift;;
-m|--max) shift; max_idx="$1"; shift;;
-n|--renum) renum="yes"; shift;;
--list_ok) lok="yes"; shift;;
--list_ko) lko="yes"; shift;;
--list_miss) lmiss="yes"; shift;;
-v|--verbose) verbose="yes"; shift;;
--) shift; break;;
*) echo "args_parse internal error [$1] !"; exit 1;;
esac
done
}
# Print Counter
#-----------------------------------------------------------------------------------------------------------------------------------
function count_print
{
idx=${1}
printf "%4d" ${idx} 1>&2
if [[ "${verbose}" == "yes" ]]
then
echo 1>&2
else
printf "\r" 1>&2
fi
}
# Convert Language to Lang
#-----------------------------------------------------------------------------------------------------------------------------------
function lang_conv
{
language=${1}
i=0
lang=""
while [[ ${i} -le 20 ]]
do
bit=$(( 2 ** i ))
if [[ $(( ${language} & ${bit} )) != 0 ]]
then
if [[ "${lang}" != "" ]]
then
lang="${lang}-"
fi
lang="${lang}${lang_tab[${bit}]}"
fi
i=$(( ${i} + 1 ))
done
echo "${lang}"
}
# Load XML File
#-----------------------------------------------------------------------------------------------------------------------------------
function xml_load()
{
echo "loading dsrom.xml..." 1>&2
loaded_cnt=0
IFS='>'
while read line
do
if [[ "${line}" != "" ]]
then
set ${line}
tag=${1/*</}
value=${2/<*/}
case "${tag}" in
("releaseNumber")
rn=${value}
;;
("title")
title=${value}
title=${title//&amp;/&}
title=${title//&lt;/<}
title=${title//&gt;/>}
;;
("saveType")
save_type=${value}
;;
("location")
location=${value}
;;
("language")
language=${value}
;;
("romCRC extension=\".nds\"")
crc=${value}
;;
("comment")
id=${value}
;;
("/game")
idx=${id/*(0)/}
if [[ "${idx}" != "xxxx" ]]
then
count_print ${idx}
dat_rn[${idx}]="${rn}"
dat_id[${idx}]="${id}"
dat_title[${idx}]="${title}"
dat_region[${idx}]="${reg_tab[${location}]}"
dat_lang[${idx}]=$(lang_conv "${language}")
dat_save_type[${idx}]="${save_type}"
dat_crc[${idx}]="${crc}"
dat_fp[${idx}]="????"
dat_status[${idx}]="?"
dat_dup[${idx}]="0"
loaded_cnt=$((${loaded_cnt} + 1))
if [[ ${loaded_cnt} -ge ${max_idx} ]]
then
echo "max rom id reached: skipping loading !" 1>&2
break;
fi
fi
;;
esac
fi
done < ${NDS_XML}
}
# Initialize Job Control
#-----------------------------------------------------------------------------------------------------------------------------------
function job_init()
{
job_id=0
while [[ ${job_id} -lt ${JOB_NB} ]]
do
job_pid[${job_id}]="0"
job_dir[${job_id}]="${TMP_DIR}/nds2rom-$$-${job_id}"
mkdir "${job_dir[${job_id}]}"
> "${job_dir[${job_id}]}/${STATS_FILE}"
job_id=$((${job_id} + 1))
done
}
# DeInitialize Job Control
#-----------------------------------------------------------------------------------------------------------------------------------
function job_deinit()
{
job_id=0
while [[ ${job_id} -lt ${JOB_NB} ]]
do
rm -R "${job_dir[${job_id}]}"
job_id=$((${job_id} + 1))
done
}
# Switch Job
#-----------------------------------------------------------------------------------------------------------------------------------
function job_switch()
{
job_id=$((${job_id} + 1))
if [[ ${job_id} -ge ${JOB_NB} ]]
then
job_id=0
fi
cd "${job_dir[${job_id}]}"
if [[ "${job_pid[${job_id}]}" != "0" ]]
then
wait "${job_pid[${job_id}]}"
fi
}
# Lookup CRC
#-----------------------------------------------------------------------------------------------------------------------------------
function crc_lookup()
{
idx_ptr=${1}
crc=${2}
i=1
while [[ ( ${i} -le ${loaded_cnt} ) && ( ${dat_crc[${i}]} != ${crc} ) ]]
do
i=$(( ${i} + 1 ))
done
if [[ ${i} -le ${loaded_cnt} ]]
then
eval ${idx_ptr}=${i}
else
eval ${idx_ptr}=""
fi
}
# Verbose Print
#-----------------------------------------------------------------------------------------------------------------------------------
function print_verbose()
{
text=${1}
if [[ "${verbose}" == "yes" ]]
then
echo "${text}" 1>&2
fi
}
# Dump Rom List
#-----------------------------------------------------------------------------------------------------------------------------------
function rom_list_dump()
{
status=${1}
i=1
while [[ ${i} -le ${loaded_cnt} ]]
do
if [[ ${dat_status[${i}]} == "${status}" ]]
then
echo "${dat_id[${i}]} - ${dat_title[${i}]} (${dat_region[${i}]}:${dat_lang[${i}]}) {${dat_crc[${i}]}} <${dat_fp[${i}]}>"
fi
i=$(( ${i} + 1 ))
done
}
# Get Save Type Mask
#-----------------------------------------------------------------------------------------------------------------------------------
function mask_get()
{
save_type=${1}
case "${save_type}"
in
("None") echo "000000000";;
("Eeprom - 4 kbit") echo "100000000";;
("Eeprom - 64 kbit") echo "200000000";;
("Eeprom - 512 kbit") echo "500000000";;
("Flash - 2 Mbit") echo "300000000";;
("Flash - 4 Mbit") echo "400000000";;
("Flash - 64 Mbit") echo "600000000";;
("TBC") echo "F00000000";;
esac
}
# Dump DSROM List
#-----------------------------------------------------------------------------------------------------------------------------------
function dsrom_dump()
{
i=1
while [[ ${i} -le ${loaded_cnt} ]]
do
if [[ ${dat_status[${i}]} != "?" ]]
then
mask=$(mask_get "${dat_save_type[${i}]}")
echo "${dat_id[${i}]} ${dat_fp[${i}]}-0 $mask ${dat_title[${i}]} (${dat_region[${i}]}:${dat_lang[${i}]}) [${dat_status[${i}]}] {${dat_crc[${i}]}}"
fi
i=$(( ${i} + 1 ))
done
}
# Dump OK ROMs
#-----------------------------------------------------------------------------------------------------------------------------------
function ok_dump()
{
echo "OK ROMs List:"
rom_list_dump "OK"
echo
}
# Dump KO Roms
#-----------------------------------------------------------------------------------------------------------------------------------
function ko_dump()
{
echo "KO ROMs List:"
rom_list_dump "KO"
echo
}
# Dump Missing ROMs
#-----------------------------------------------------------------------------------------------------------------------------------
function missing_dump()
{
echo "Missing ROMs List:"
rom_list_dump "?"
echo
}
# Make Arc FileName
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_mkfn()
{
file_name_ptr=${1}
id=${2}
title=${3}
reg=${4}
lang=${5}
crc=${6}
fp=${7}
status=${8}
dup_id=${9}
file_prefix="${id} - ${title} (${reg}:${lang}) [${status}] {${crc}} <${fp}>"
if [[ ${dup_id} == "" ]]
then
dup_name=""
else
dup_name="-${dup_id}"
fi
eval ${file_name_ptr}=\"${file_prefix}${dup_name}${file_suffix}\"
}
# Build Arc
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_build()
{
file_name=${1}
rom=${2}
file=${3}
mode=${4}
idx=${5}
if [[ "${mode}" == "correct" ]]
then
if [[ ${in_place} == "yes" ]]
then
print_verbose "removing ${file}"
\rm -f "${NDS_ROMS_IN}/${file}"
fi
print_verbose "zipping ${rom} into ${file_name}"
zip -m9 "${NDS_ROMS_OUT}/${file_name}" "${rom}" >/dev/null 1>&2
else
print_verbose "removing ${rom}"
\rm -f "${rom}"
fi
}
# Rename Arc
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_rename()
{
file_name=${1}
file=${2}
action=${3}
mode=${4}
if [[ "${mode}" == "correct" ]]
then
# if [[ ${action} != "keep_status" ]]
# then
if [[ ${in_place} == "yes" ]]
then
print_verbose "moving ${file} to ${file_name}"
mv "${NDS_ROMS_IN}/${file}" "${NDS_ROMS_OUT}/${file_name}"
else
print_verbose "copying ${file} to ${file_name}"
cp "${NDS_ROMS_IN}/${file}" "${NDS_ROMS_OUT}/${file_name}"
fi
# fi
fi
}
# Move Duplicate
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_mv()
{
file_name_trg=${1}
file_name_src=${2}
mode=${3}
if [[ "${mode}" == "correct" ]]
then
print_verbose "moving ${file_name_src} to ${file_name_trg}"
mv "${file_name_src}" "${file_name_trg}"
fi
}
# Extract ROM
#-----------------------------------------------------------------------------------------------------------------------------------
function rom_extract()
{
rom=$1
file=$2
case "${file}"
in
(*.nds)
print_verbose "copying ${file} to ${rom}"
cp "${NDS_ROMS_IN}/${file}" "${rom}"
;;
(*.rar)
print_verbose "extracting ${rom} from ${file}"
unrar p "${NDS_ROMS_IN}/${file}" > "${rom}"
;;
(*.zip)
print_verbose "extracting ${rom} from ${file}"
unzip -p "${NDS_ROMS_IN}/${file}" > "${rom}"
;;
(*)
echo "rom_extract internal error [$1] !" 1>&2
exit 1
;;
esac
}
# Remove .tmp suffix
#-----------------------------------------------------------------------------------------------------------------------------------
function tmp_mv()
{
echo "removing .tmp suffix..." 1>&2
IFS=' '
mv_cnt=0
for file_src in ${NDS_ROMS_OUT}/*.tmp
do
if [[ "${file_src}" != "${NDS_ROMS_OUT}/*.tmp" ]]
then
file_trg=${file_src/.zip.tmp/.zip}
print_verbose "move ${file_src} to ${file_trg}"
mv "${file_src}" "${file_trg}"
mv_cnt=$((${mv_cnt} + 1))
printf "moved: %4d\r" "${mv_cnt}"
fi
done
}
# Identify Arc
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_ident()
{
arc_type_ptr=${1}
extract_ptr=${2}
file=${3}
# Type of archive ?
if [[ ${file} =~ ${RNFH_REGEX} ]]
then
eval ${arc_type_ptr}="rx3"
else
eval ${arc_type_ptr}="unknown"
fi
# Extract ROM if needed
if [[ ( "${arc_type}" != "rx3" ) || ( "${rebuild}" == "yes" ) ]]
then
eval ${extract_ptr}="yes"
else
eval ${extract_ptr}="no"
fi
}
# Proceed Arc
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_proceed()
{
file=${1}
arc_type=${2}
extract=${3}
found_cnt=${4}
set ${file:0:4}
id=$1
idx=${id/*(0)/}
if [[ ${idx} -gt ${loaded_cnt} ]]
then
echo "max rom id reached: skipping processing !" 1>&2
break;
fi
# Get info from dat
title=${dat_title[${idx}]}
reg=${dat_region[${idx}]}
lang=${dat_lang[${idx}]}
crc=${dat_crc[${idx}]}
# Extract ROM if needed
if [[ "${extract}" == "yes" ]]
then
rom="${id} - ${title} (${reg}:${lang}).nds"
rom_extract "${rom}" "${file}"
crc2=$(check -n <"${rom}" 2>&1 | sed -e 's/,.*//' -e 's/.*= //' | tr [:lower:] [:upper:])
fp=$(dd skip=12 count=4 bs=1 <"${rom}" 2>/dev/null)
else
crc2=${file/*\{/}; crc2=${crc2/\}*/}
fp=${file/*\} \</}; fp=${fp/\>*/}
fi
# Extract info
if [[ "${arc_type}" == "rx3" ]]
then
status=${file/* \[/}; status=${status/\] {*/}
if [[ "${crc}" != "${crc2}" ]]
then
if [[ "${status}" == "OK" ]]
then
action="change_status"
status="KO"
else
action="keep_status"
fi
else
if [[ "${status}" == "OK" ]]
then
action="keep_status"
else
action="change_status"
status="OK"
fi
fi
else
action="set_status"
if [[ "${crc}" != "${crc2}" ]]
then
status="KO"
else
status="OK"
fi
fi
# Try to Renumber if KO
renumed="no"
if [[ ( ${status} == "KO" ) && ( "${renum}" == "yes" ) ]]
then
crc_lookup "idx2" "${crc2}"
if [[ "${idx2}" != "" ]]
then
idx=${idx2}
id=${dat_id[${idx}]}
title=${dat_title[${idx}]}
reg=${dat_region[${idx}]}
lang=${dat_lang[${idx}]}
crc=${dat_crc[${idx}]}
status2="OK"
# Rename the ROM file
rom2="${id} - ${title} (${reg}:${lang}) [${status2}].nds"
print_verbose "moving ${rom} to ${rom2}"
mv "${rom}" "${rom2}"
rom=${rom2}
if [[ "${arc_type}" == "rx3" ]]
then
status=${file/* \[/}; status=${status/\] {*/}
if [[ "${status}" == "${status2}" ]]
then
action="keep_status"
else
action="change_status"
status=${status2}
fi
else
action="set_status"
status=${status2}
fi
renumed="yes"
fi
fi
# Rename ROM if needed
if [[ ( "${renumed}" != "yes") && ( ( "${arc_type}" != "rx3" ) || ( "${rebuild}" == "yes" ) ) ]]
then
rom2="${id} - ${title} (${reg}:${lang}) [${status}].nds"
print_verbose "moving ${rom} to ${rom2}"
mv "${rom}" "${rom2}"
rom=${rom2}
fi
# Make File Name
arc_mkfn "file_name" "${id}" "${title}" "${reg}" "${lang}" "${crc2}" "${fp}" "${status}" "${found_cnt}"
# Make / Rename Archive
if [[ ( "${arc_type}" != "rx3" ) || ( ${rebuild} == "yes" ) ]]
then
arc_build "${file_name}" "${rom}" "${file}" "${mode}" "${idx}"
else
arc_rename "${file_name}" "${file}" "${action}" "${mode}"
fi
# Updates Stats
echo "${renumed}" "${action}" "${status}" >>"${STATS_FILE}"
}
# Manage Archives
#-----------------------------------------------------------------------------------------------------------------------------------
function arc_mng()
{
# Initialize Job Control
job_init
echo "processing rom repository..." 1>&2
IFS=' '
found_cnt=0
tmp_file=$(mktemp)
ls ${NDS_ROMS_IN} > ${tmp_file}
while read file
do
arc_ident "arc_type" "extract" "${file}"
if [[ "${extract}" == "no" ]]
then
arc_proceed "${file}" "${arc_type}" "${extract}" "${found_cnt}"
else
job_switch "${job_id}"
arc_proceed "${file}" "${arc_type}" "${extract}" "${found_cnt}" &
job_pid[${job_id}]=$!
fi
# Update stats
found_cnt=$((${found_cnt} + 1))
count_print ${found_cnt}
done < ${tmp_file}
\rm -f ${tmp_file}
# Wait all Jobs
wait
# Collect Stats"
cd "${TMP_DIR}"
cat *"/${STATS_FILE}" >> "${STATS_FILE}"
# DeInitialize Job Control
job_deinit
}
# Manage Arc Suffix
#-----------------------------------------------------------------------------------------------------------------------------------
function suffix_mng()
{
echo "managing duplicate archives..." 1>&2
IFS=' '
found_cnt=0
ok_cnt=0
ko_cnt=0
dup_cnt=0
ignored_cnt=0
idx_old=0
status_old=""
tmp_file=$(mktemp)
ls ${NDS_ROMS_OUT} > ${tmp_file}
while read file
do
set ${file:0:4}
id=$1
idx=${id/*(0)/}
if [[ ${idx} -gt ${loaded_cnt} ]]
then
ignored_cnt=$((${ignored_cnt} + 1))
else
status=${file/* \[/}; status=${status/\] \{*/}
crc=${file/*\] \{/}; crc=${crc/\} \<*/}
fp=${file/*\} \</}; fp=${fp/\>-*/}
dat_dup[${idx}]="${dup_id}"
if [[ ( ${idx} != ${idx_old} ) || ( "${status}" != "${status_old}" ) ]]
then
idx_old=${idx}
status_old=${status}
dup_id=0
file_name="${file/) \[*/}) [${status}] {${crc}} <${fp}>.zip"
dat_fp[${idx}]="${fp}"
dat_status[${idx}]="${status}"
if [[ "${status}" == "OK" ]]
then
ok_cnt=$((${ok_cnt} + 1))
else
ko_cnt=$((${ko_cnt} + 1))
fi
else
dup_id=$((${dup_id} + 1))
file_name="${file/) \[*/}) [${status}] {${crc}} <${fp}>-${dup_id}.zip"
dup_cnt=$((${dup_cnt} + 1))
fi
print_verbose "moving ${file} to ${file_name}"
arc_mv "${NDS_ROMS_OUT}/${file_name}" "${NDS_ROMS_OUT}/${file}" "${mode}"
fi
found_cnt=$((${found_cnt} + 1))
count_print ${found_cnt}
done < ${tmp_file}
\rm -f ${tmp_file}
}
# Update Statistics
#-----------------------------------------------------------------------------------------------------------------------------------
function stats_update()
{
renumed=${1}
action=${2}
status=${3}
mode=${4}
if [[ "${renumed}" == "yes" ]]
then
renum_cnt=$((${renum_cnt} + 1))
fi
case ${action} in
("set_status")
if [[ ${status} == "OK" ]]
then
ss_ok_cnt=$((${ss_ok_cnt} + 1))
else
ss_ko_cnt=$((${ss_ko_cnt} + 1))
fi
;;
("change_status")
if [[ ${status} == "OK" ]]
then
cs_ok_cnt=$((${cs_ok_cnt} + 1))
else
cs_ko_cnt=$((${cs_ko_cnt} + 1))
fi
;;
("keep_status")
if [[ ${status} == "OK" ]]
then
ks_ok_cnt=$((${ks_ok_cnt} + 1))
else
ks_ko_cnt=$((${ks_ko_cnt} + 1))
fi
;;
*)
echo "stats_update internal error [$1] !" 1>&2
exit 1
;;
esac
}
# Proceed Stats
#-----------------------------------------------------------------------------------------------------------------------------------
function stats_proceed()
{
ss_ok_cnt=0
ss_ko_cnt=0
cs_ok_cnt=0
cs_ko_cnt=0
ks_ok_cnt=0
ks_ko_cnt=0
proceeded_cnt=0
missing_cnt=0
while read file
do
set ${file}
renumed=${1}
action=${2}
status=${3}
stats_update "${renumed}" "${action}" "${status}"
done < "${STATS_FILE}"
\rm -f "${STATS_FILE}"
found_cnt=$((${ok_cnt} + ${ko_cnt} + ${dup_cnt} + ${ignored_cnt}))
proceeded_cnt=$((${found_cnt} - ${ignored_cnt}))
i=1
while [[ ${i} -le ${loaded_cnt} ]]
do
if [[ ${dat_status[${i}]} == "?" ]]
then
missing_cnt=$((${missing_cnt} + 1))
fi
i=$(( ${i} + 1 ))
done
}
# Print Stats
#-----------------------------------------------------------------------------------------------------------------------------------
function stats_print()
{
echo " " 1>&2
echo 1>&2
printf "%4d roms set to OK\n" ${ss_ok_cnt} 1>&2
printf "%4d roms changed to OK\n" ${cs_ok_cnt} 1>&2
printf "%4d roms kept to OK\n" ${ks_ok_cnt} 1>&2
printf "%4d roms are OK\n" ${ok_cnt} 1>&2
echo
printf "%4d roms set to KO\n" ${ss_ko_cnt} 1>&2
printf "%4d roms changed to KO\n" ${cs_ko_cnt} 1>&2
printf "%4d roms kept to KO\n" ${ks_ko_cnt} 1>&2
printf "%4d roms are KO\n" ${ko_cnt} 1>&2
echo
printf "%4d roms are in dsrom.dat\n" ${loaded_cnt} 1>&2
printf "%4d roms are found\n" ${found_cnt} 1>&2
printf "%4d roms are ignored\n" ${ignored_cnt} 1>&2
printf "%4d roms are proceeded\n" ${proceeded_cnt} 1>&2
printf "%4d roms are renumbered\n" ${renum_cnt} 1>&2
printf "%4d roms are duplicated\n" ${dup_cnt} 1>&2
printf "%4d roms are missing\n" ${missing_cnt} 1>&2
}
# DSROM Mode
#-----------------------------------------------------------------------------------------------------------------------------------
function dsrom_mode()
{
echo "scanning rom repository..." 1>&2
IFS=' '
found_cnt=0
tmp_file=$(mktemp)
ls ${NDS_ROMS_IN} > ${tmp_file}
while read file
do
set ${file:0:4}
id=$1
idx=${id/*(0)/}
if [[ ${idx} -gt ${loaded_cnt} ]]
then
break;
fi
# Get info from dat
title=${dat_title[${idx}]}
reg=${dat_region[${idx}]}
lang=${dat_lang[${idx}]}
crc=${dat_crc[${idx}]}
# Type of archive ?
if [[ ${file} =~ ${RNFH_REGEX} ]]
then
fp=${file/*\} \</}; fp=${fp/\>*/}
status=${file/* \[/}; status=${status/\] \{*/}
dat_fp[${idx}]=${fp}
dat_status[${idx}]=${status}
fi
found_cnt=$((${found_cnt} + 1))
count_print ${found_cnt}
done < ${tmp_file}
\rm -f ${tmp_file}
# Dump it !
dsrom_dump
}
# Test and Correct Mode
#-----------------------------------------------------------------------------------------------------------------------------------
function test_correct_mode()
{
if [[ ${in_place} == "yes" ]]
then
file_suffix=".zip.tmp"
else
file_suffix=".zip"
fi
# Remove .tmp suffix
tmp_mv
# Process Archives
arc_mng
# Suffix Management
suffix_mng
# Dump ROMs List
#-----------------------------------------------------------------------------------------------------------------------------------
if [[ ${lok} == "yes" ]]
then
ok_dump
fi
if [[ ${lko} == "yes" ]]
then
ko_dump
fi
if [[ ${lmiss} == "yes" ]]
then
missing_dump
fi
# Collect and Proceed Stats
stats_proceed
# Print statistics
stats_print
}
# Main
#-----------------------------------------------------------------------------------------------------------------------------------
cd ${TMP_DIR}
# Initialise stats variables
ok_cnt=0
ko_cnt=0
found_cnt=0
missing_cnt=0
renum_cnt=0
shopt -s extglob
args_parse "$@"
if [[ ${mode} == "exit" ]]
then
exit 0
fi
if [[ ${NDS_REPOSITORY_IN} == ${NDS_REPOSITORY_OUT} ]]
then
in_place=yes
else
in_place=no
fi
if [[ ! -f ${NDS_DAT} ]]
then
echo "error: dsrom.dat not found !" 1>&2
exit 1
fi
#-----------------------------------------------------------------------------------------------------------------------------------
#dat_load
xml_load
#-----------------------------------------------------------------------------------------------------------------------------------
if [[ "${mode}" == "dsrom" ]]
then
dsrom_mode
else
test_correct_mode
fi
#-----------------------------------------------------------------------------------------------------------------------------------
# Final Cleanup
cd /tmp
rmdir ${TMP_DIR}
exit 0