Skip to content

Commit

Permalink
thanm: an option to extract images from multiple ANM files at once
Browse files Browse the repository at this point in the history
new test failures (that aren't related to previous ones)
09
Files /tmp/anmtemp/a/result00.anm and /tmp/anmtemp/i/result00.anm differ
12
Files /tmp/anmtemp/a/stgenm01.anm and /tmp/anmtemp/i/stgenm01.anm differ
128
Files /tmp/anmtemp/a/boss00.anm and /tmp/anmtemp/i/boss00.anm differ
14
Files /tmp/anmtemp/a/st07enm2.anm and /tmp/anmtemp/i/st07enm2.anm differ
16
Files /tmp/anmtemp/a/pl02sub.anm and /tmp/anmtemp/i/pl02sub.anm differ
165
Files /tmp/anmtemp/a/enm01.anm and /tmp/anmtemp/i/enm01.anm differ
18
Files /tmp/anmtemp/a/pl02.anm and /tmp/anmtemp/i/pl02.anm differ
  • Loading branch information
DankRank committed Sep 3, 2023
1 parent 25fa555 commit 8aece65
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 19 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ What's new in thtk master
- Support th143/bestshot.anm
- Two new options (-u and -uu) were added to help with rebuilding TH19 files
bit-perfectly. See documentation for more details.
- A new option (-X) to extract images from multiple ANM files at once.

#### thanm.old
- Will be removed in the next release.
Expand Down
30 changes: 21 additions & 9 deletions contrib/anmtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@
# - regular unpacking to separate dirs
# (one dir per anm file)
# - unpacking with -uu option
# - unpacking with -X option
#
# This doesn't test the most common way to extract ANM (no flags, everything in
# one dir), because that's clearly the wrong way to do it.
#
# Summary of directories being created:
# -uu |ZUN| separate
# flag| | dirs
# ----|---|----------
# g | a | c e | packed
# \ |/ \| / \ /
# \ / \ / \ /
# f| |b d | unpacked
# -X |-uu |ZUN| separate
# flag |flag| | dirs
# -----|----|---|----------
# i |g | a | c e | packed
# \ | \ |/|\| / \ /
# \ | \ / | \ / \ /
# h | f| | |b d | unpacked
# \ /
# \-----/
#
# Comparisions being done:
# a = c (rebuilding)
# b = d (consistency)
# c = e (consistency)
# a = g (rebuilding)
# The a = c comparision can't be practically done for th19... at least for now.
# a = i (rebuilding)
# The a = c and a = i comparisions can't be practically done for th19... at least for now.
script_dir=$(cd "$(dirname "$0")" || exit 1; pwd) || exit 1
: "${THDAT:=$script_dir/../build/thdat/thdat}"
: "${THANM:=$script_dir/../build/thanm/thanm}"
Expand Down Expand Up @@ -59,7 +63,7 @@ do
else
datfiles="$datfile"
fi
mkdir -p "$ANMTEMP/a" "$ANMTEMP/b" "$ANMTEMP/c" "$ANMTEMP/d" "$ANMTEMP/e" "$ANMTEMP/f" "$ANMTEMP/g"
mkdir -p "$ANMTEMP/a" "$ANMTEMP/b" "$ANMTEMP/c" "$ANMTEMP/d" "$ANMTEMP/e" "$ANMTEMP/f" "$ANMTEMP/g" "$ANMTEMP/h" "$ANMTEMP/i"
anmfiles=$(cd "$ANMTEMP/a" || exit 1; for i in $datfiles; do "$THDAT" -gx"$version" "$DATDIR/$i" "*anm" >/dev/null; done; ls) || exit 1
for i in $anmfiles; do
mkdir -p "$ANMTEMP/b/$i"
Expand All @@ -84,8 +88,16 @@ do
for i in $anmfiles; do
(cd "$ANMTEMP/f" || exit 1; "$THANM" $THANMFLAGS -uuc"$version" "$ANMTEMP/g/$i" "$ANMTEMP/f/$i.txt") || exit 1
done
for i in $anmfiles; do
"$THANM" $THANMFLAGS -l"$version" "$ANMTEMP/a/$i" >"$ANMTEMP/h/$i.txt"
done
(cd "$ANMTEMP/h" || exit 1; "$THANM" $THANMFLAGS -X"$version" "$ANMTEMP/a/"*.anm) || exit 1
for i in $anmfiles; do
(cd "$ANMTEMP/h" || exit 1; "$THANM" $THANMFLAGS -c"$version" "$ANMTEMP/i/$i" "$ANMTEMP/h/$i.txt") || exit 1
done
diff -rq "$ANMTEMP/a" "$ANMTEMP/c"
diff -rq "$ANMTEMP/b" "$ANMTEMP/d"
diff -rq "$ANMTEMP/c" "$ANMTEMP/e"
diff -rq "$ANMTEMP/a" "$ANMTEMP/g"
diff -rq "$ANMTEMP/a" "$ANMTEMP/i"
done
8 changes: 4 additions & 4 deletions thanm/thanm.1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl Vfouv
.Op Oo Fl l | x | r | c Oc Ar version
.Op Oo Fl l | x | X | r | c Oc Ar version
.Oo Fl m Ar anmmap Oc Ns Ar ...
.Oo Fl s Ar symbols Oc
.Op Ar archive Op Ar ...
Expand All @@ -48,6 +48,8 @@ Displays a specification of the archive.
.It Nm Fl x Ar version Oo Fl fouv Oc Ar archive Op Ar
Extracts image files.
If no files are specified, all files are extracted.
.It Nm Fl X Ar version Oo Fl fouv Oc Ar archives Ns Ar ...
Extracts all image files from multiple archives.
.It Nm Fl r Ar version Oo Fl fouv Oc Ar archive Ar name Ar file
Replaces an entry in the archive.
The name can be obtained by the
Expand Down Expand Up @@ -119,13 +121,11 @@ the appropriate format.
.It Composition when creating Po Fl c Pc or replacing Po Fl r Pc :
The source image is read from a file, decoded as PNG, cropped,
and encoded in the texture format.
.It Composition when extracting Po Fl x Pc :
.It Composition when extracting Po Fl x No and Fl X Pc :
Each texture is decoded into RGBA, and placed on a canvas.
The canvas is encoded as PNG and written to the destination file.
.El
.Pp
Currently there's no way to compose textures from multiple ANM files.
.Pp
The
.Fl u
option extracts each texture into its own file.
Expand Down
86 changes: 80 additions & 6 deletions thanm/thanm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,7 @@ util_entry_by_name(
}
return rv;
}

static void
anm_build_name_lists(
const anm_archive_t *anm)
Expand All @@ -1457,6 +1458,30 @@ anm_build_name_lists(
}
}
}

static void
anm_build_name_lists_multiple(
list_t *anms)
{
const anm_archive_t *anm, *anm2;
const char *name;
anm_entry_t *entry, *tmp, **nextloc;
list_for_each(anms, anm)
list_for_each(&anm->names, name) {
nextloc = &tmp;
list_for_each(anms, anm2)
list_for_each(&anm2->entries, entry)
if (entry->name == name || !strcmp(name, entry->name)) {
name = entry->name;
if (entry->next_by_name)
goto next_name; /* we already did this name */
*nextloc = entry;
nextloc = &entry->next_by_name;
}
next_name:;
}
}

static void
util_total_entry_size(
anm_entry_t* entry,
Expand Down Expand Up @@ -1535,7 +1560,7 @@ anm_replace(
image = png_read(filename);
}

if (width != image->width || height != image->height) {
if (width > image->width || height > image->height) {
fprintf(stderr,
"%s:%s:%s: wrong image dimensions for %s: %u, %u instead of %u, %u\n",
argv0, current_input, entry_first->name, filename, image->width, image->height,
Expand Down Expand Up @@ -2286,6 +2311,7 @@ print_usage(void)
" -l VERSION ARCHIVE list archive\n"
#ifdef HAVE_LIBPNG
" -x VERSION ARCHIVE [FILE...] extract entries\n"
" -X VERSION ARCHIVE... extract all entries from multiple archives\n"
" -r VERSION ARCHIVE NAME FILE replace entry in archive\n"
" -c VERSION ARCHIVE SPEC create archive\n"
" -s SYMBOLS save symbol ids to the given file as globaldefs\n"
Expand Down Expand Up @@ -2318,7 +2344,7 @@ main(

const char commands[] = ":l:om:"
#ifdef HAVE_LIBPNG
"x:r:c:s:"
"x:X:r:c:s:"
#endif
"Vfuv";
int command = -1;
Expand Down Expand Up @@ -2349,6 +2375,7 @@ main(
/* fallthrough */
case 'l':
case 'x':
case 'X':
case 'r':
if(command != -1) {
fprintf(stderr,"%s: More than one mode specified\n",argv0);
Expand Down Expand Up @@ -2445,7 +2472,7 @@ main(
current_input = argv[0];
in = fopen(argv[0], "rb");
if (!in) {
fprintf(stderr, "%s: couldn't open %s for reading\n", argv[0], current_input);
fprintf(stderr, "%s: couldn't open %s for reading\n", argv0, current_input);
exit(1);
}
anm = anm_read_file(in, version);
Expand All @@ -2464,7 +2491,7 @@ main(
current_input = argv[0];
in = fopen(argv[0], "rb");
if (!in) {
fprintf(stderr, "%s: couldn't open %s for reading\n", argv[0], current_input);
fprintf(stderr, "%s: couldn't open %s for reading\n", argv0, current_input);
exit(1);
}
anm = anm_read_file(in, version);
Expand Down Expand Up @@ -2516,6 +2543,53 @@ main(

anm_free(anm);
exit(0);
case 'X': {
list_t anms;
list_init(&anms);

if (argc < 1) {
print_usage();
exit(1);
}

for (i = 0; i < argc; ++i) {
current_input = argv[i];
in = fopen(argv[i], "rb");
if (!in) {
fprintf(stderr, "%s: couldn't open %s for reading\n", argv0, current_input);
exit(1);
}
anm = anm_read_file(in, version);
list_append_new(&anms, anm);
fclose(in);
}

anm_build_name_lists_multiple(&anms);

i = 0;
list_for_each(&anms, anm) {
int j = 0;
list_for_each(&anm->entries, entry) {
if (!entry->processed) {
char *filename = 0;
current_output = entry->name;
if (option_verbose >= 1)
fprintf(stderr, "%s\n", entry->name);
if (option_unique_filenames)
filename = anm_make_unique_filename(entry->name, argv[i], j);
anm_extract(entry, filename ? filename : entry->name, version);
free(filename);
}
j++;
}
i++;
}

list_for_each(&anms, anm)
anm_free(anm);
list_free_nodes(&anms);
exit(0);
}
case 'r':
if (argc != 3) {
print_usage();
Expand All @@ -2524,15 +2598,15 @@ main(

if (version == 19) {
/* NEWHU: 19 */ /* FIXME: */
fprintf(stderr, "%s: -r doesn't work with th19\n", argv[0]);
fprintf(stderr, "%s: -r doesn't work with th19\n", argv0);
exit(1);
}

current_output = argv[2];
current_input = argv[0];
in = fopen(argv[0], "rb");
if (!in) {
fprintf(stderr, "%s: couldn't open %s for reading\n", argv[0], current_input);
fprintf(stderr, "%s: couldn't open %s for reading\n", argv0, current_input);
exit(1);
}
anm = anm_read_file(in, version);
Expand Down

0 comments on commit 8aece65

Please sign in to comment.