diff options
author | Thomas <doodrabbit@hotmail.com> | 2021-12-17 20:57:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-17 20:57:03 -0500 |
commit | af67eaffa7ab1a347a6f0e59ed7f1e107749d15a (patch) | |
tree | b9f90f7b047b3dc5a411dbf65117bf07b237a37d /tools | |
parent | 3ab18655ca1311019212b3a2a9dbe32e5fbee55d (diff) | |
parent | 44cd7753b5dde323d1e8274b2dc8a5599729e83f (diff) |
Real-match math_util.c
Diffstat (limited to 'tools')
-rw-r--r-- | tools/asmdiff/asmdiff.sh | 179 | ||||
-rw-r--r-- | tools/asmdiff/ntrextractfile.c | 153 | ||||
-rw-r--r-- | tools/asmdiff/ntruncompbw.c | 107 | ||||
-rw-r--r-- | tools/knarc/Narc.cpp | 4 | ||||
-rw-r--r-- | tools/knarc/Narc.h | 2 | ||||
-rw-r--r-- | tools/mwasmarm_patcher/Makefile | 5 | ||||
-rw-r--r-- | tools/nitrogfx/Makefile | 6 | ||||
-rw-r--r-- | tools/nitrogfx/gfx.c | 14 | ||||
-rw-r--r-- | tools/nitrogfx/gfx.h | 4 | ||||
-rw-r--r-- | tools/nitrogfx/main.c | 8 | ||||
-rw-r--r-- | tools/nitrogfx/options.h | 1 |
11 files changed, 467 insertions, 16 deletions
diff --git a/tools/asmdiff/asmdiff.sh b/tools/asmdiff/asmdiff.sh new file mode 100644 index 00000000..e134e2be --- /dev/null +++ b/tools/asmdiff/asmdiff.sh @@ -0,0 +1,179 @@ +#!/usr/bin/env bash + +MYDIR=$(dirname $0) + +mkdir -p ${MYDIR}/.bins + +DEFAULT_BASEROM=baserom.nds +DEFAULT_ARM9BUILDDIR=build/heartgold.us +DEFAULT_ARM7BUILDDIR=sub/build +DEFAULT_FSDIR=files + +# Build C utils on demand +[[ $MYDIR/ntruncompbw -nt $MYDIR/ntruncompbw.c ]] || gcc -O3 -g -o $MYDIR/ntruncompbw $MYDIR/ntruncompbw.c +[[ $MYDIR/ntrextractfile -nt $MYDIR/ntrextractfile.c ]] || gcc -O3 -g -o $MYDIR/ntrextractfile $MYDIR/ntrextractfile.c + +getword() { + od -j "$2" -N 4 -A n -t u "$1" | awk '{$1=$1};1' +} + +[[ -n "$DEVKITARM" ]] && export PATH=${DEVKITARM}/bin:${PATH} + +POSITIONAL=() + +usage () { + echo "Diff segments of a Nintendo DS ROM" + echo "Usage: $0 [-h] [-7] [-m OVERLAY] [-r BASEROM] [-d BUILDDIR] [START [END]]" + echo "" + echo "Arguments:" + echo " START, END Start and end virtual addresses to diff" + echo "" + echo "Options:" + echo " -7 Diff the ARM7 module (default: ARM9)" + echo " -m OVERLAY Diff the indicated overlay module (default: static module)" + echo " -r BASEROM Use the indicated baserom (default: baserom.nds)" + echo " -d BUILDDIR Look for compiled binaries in this directory (default: build/heartgold.us)" + echo " -f FILE Dump the indicated file, and use hexdump instead" + echo " -F FSDIR Filesystem path on the home system" + echo " -t Force THUMB instructions (default: ARM)" + echo " -h Show this message and exit" +} + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -h) + usage + exit 0 + ;; + -7) + proc=armv4t + builddir=${builddir:-$DEFAULT_ARM7BUILDDIR} + basestem=${basestem}.sub + shift + ;; + -m) + [[ -n $overlay ]] && { echo can only do one overlay at a time; exit 1; } + mode=overlay + overlay="$2" + basestem=${basestem}.o${overlay} + shift 2 + ;; + -r) + baserom="$2" + shift 2 + ;; + -t) + thumb=-Mforce-thumb + shift + ;; + -f) + mode=file + filepath="$2" + shift 2 + ;; + -F) + fsdir="$2" + shift 2 + ;; + -d) + builddir="$2" + shift 2 + ;; + -*) + usage + echo unrecognized option flag: "$1" >&2 + exit 1 + ;; + *) + POSITIONAL+=("$1") + shift + ;; + esac +done + +set -- "${POSITIONAL[@]}" + +mode=${mode:-static} +proc=${proc:-armv5te} +builddir=${builddir:-$DEFAULT_ARM9BUILDDIR} +baserom=${baserom:-$DEFAULT_BASEROM} +fsdir=${fsdir:-$DEFAULT_FSDIR} + +basefile=${MYDIR}/.bins/${baserom}${basestem}.sbin + +case "$mode" in + overlay) + case $proc in + armv4t) + ovt=88 + ;; + armv5te) + ovt=80 + ;; + esac + ovtoff=$(getword "$baserom" "$ovt") + vma=$(getword "$baserom" "$((ovtoff+32*overlay+4))") + size=$(getword "$baserom" "$((ovtoff+32*overlay+8))") + [[ -f $basefile ]] || { + fileid=$(getword "$baserom" "$((ovtoff+32*overlay+24))") + param=$(getword "$baserom" "$((ovtoff+32*overlay+28))") + fatoff=$(getword "$baserom" 72) + fileoff=$(getword "$baserom" "$((fatoff+8*fileid))") + filesize=$(($(getword "$baserom" "$((fatoff+8*fileid+4))")-fileoff)) + dd if="$baserom" of="$basefile" bs=1 skip="$fileoff" count="$filesize" 2>/dev/null + (( param & 16777216 )) && { + compsize=$((param & 16777215)) + $MYDIR/ntruncompbw $basefile $vma $((vma+compsize)) || { rm -f $basefile; exit 1; } + } + } + buildfile=$builddir/OVY_${overlay}.sbin + ;; + static) + case $proc in + armv4t) + romtab=48 + compname=ichneumon_sub + ;; + armv5te) + romtab=32 + compname=main + ;; + esac + + fileoff=$(getword "$baserom" "$romtab") + vma=$(getword "$baserom" "$((romtab+8))") + size=$(getword "$baserom" "$((romtab+12))") + + [[ -f $basefile ]] || { + dd if="$baserom" of="$basefile" bs=1 skip="$fileoff" count="$size" 2>/dev/null + [[ $proc == armv5te ]] && { + _start_ModuleParams=$(getword "$baserom" $((fileoff+size+4))) + compstatend=$(getword "$basefile" $((_start_ModuleParams+20))) + [[ $compstatend != "0" ]] && { + $MYDIR/ntruncompbw $basefile $vma $compstatend || { rm -f $basefile; exit 1; } + dd if=/dev/zero of="$basefile" bs=1 seek="$((_start_ModuleParams+20))" count=4 conv=notrunc 2>/dev/null + } + } + } + buildfile=${builddir}/${compname}.sbin + ;; + file) + buildfile=${fsdir}/${filepath} + [[ -f "${buildfile}" ]] || { echo file not found: "${buildfile}"; exit 1; } + basefile=${MYDIR}/.files/${filepath} + [[ -f "${basefile}" ]] || { + mkdir -p $(dirname "${basefile}") + ${MYDIR}/ntrextractfile ${baserom} ${filepath} >${basefile} + } + diff -u <(hexdump -Cv $basefile) <(hexdump -Cv $buildfile) + exit 0 + ;; +esac + +[[ -n "$1" ]] && start=$(($1)) || start=$vma +[[ -n "$2" ]] && size=$(($2)) || size=$(wc -c <$basefile) +do-objdump () { + arm-none-eabi-objdump -Drz -bbinary -m$proc $thumb --adjust-vma=$vma --start-address=$start --stop-address=$((start+size)) $1 +} +diff -u <(do-objdump $basefile) <(do-objdump $buildfile) diff --git a/tools/asmdiff/ntrextractfile.c b/tools/asmdiff/ntrextractfile.c new file mode 100644 index 00000000..19869a14 --- /dev/null +++ b/tools/asmdiff/ntrextractfile.c @@ -0,0 +1,153 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> + +#ifndef NDEBUG +#ifdef _MSC_VER +#define debug_printf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) +#else +#define debug_printf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) +#endif //_MSC_VER +#else +#define debug_printf(fmt, ...) ((void)0) +#endif //NDEBUG + +#define FIND_FAIL (-1u) + +struct NtrDirHeader { + unsigned offset; + unsigned short first_file; + unsigned short count_or_parent; +}; + +static char FILEBUF[BUFSIZ]; + +unsigned find_file(struct NtrDirHeader * fnt, const char * cfilename) { + unsigned file_id = fnt->first_file; + char * filename = strdup(cfilename); + char * tokenizer = filename; + int found = 0; + char * tree = (char *)fnt + fnt->offset; + char * token; + + while ((token = strtok(tokenizer, "/")) != NULL) { + tokenizer = NULL; + debug_printf("TOKEN: %s\n", token); + long toklen = strlen(token); + while (*tree) { + char flag = *tree++; +#ifndef NDEBUG + char *entname = malloc((flag & 0x7F) + 1); + *stpncpy(entname, tree, flag & 0x7F) = 0; + debug_printf("testing entry %s...", entname); + free(entname); +#endif //NDEBUG + if ((toklen != (flag & 0x7F)) || strncmp(tree, token, toklen) != 0) { + debug_printf("no; is %s\n", (flag & 0x80) ? "dir" : "file"); + // Next entry + tree += (flag & 0x7F); + if (flag & 0x80) { + tree += 2; // skip dir id + } + else { + file_id++; + } + } + else { + debug_printf("yes; is %s\n", (flag & 0x80) ? "dir" : "file"); + tree += (flag & 0x7F); + if (flag & 0x80) { + // navigate to next dir + unsigned short dir_id = (unsigned char) tree[0] | ((unsigned char) tree[1] << 8); + file_id = fnt[dir_id & 0xFFF].first_file; + tree = (char *)fnt + fnt[dir_id & 0xFFF].offset; + break; + } + else { + found = 1; + token = strtok(NULL, "/"); + goto done; + } + } + } + } + +done: + free(filename); + if (!found || token != NULL) { + file_id = FIND_FAIL; + } + return file_id; +} + +int main(int argc, char ** argv) { + if (argc < 3) { + fprintf(stderr, "missing required argument: %s\n", (argc == 1) ? "BASEROM" : "FILENAME"); + return 1; + } + FILE *baserom = fopen(argv[1], "rb"); + if (baserom == NULL) { + fprintf(stderr, "unable to open ROM %s for reading\n", argv[1]); + return 1; + } + debug_printf("opened baserom\n"); + + // fnt offset, fnt size, fat offset, fat size + unsigned offsets[4]; + fseek(baserom, 64, SEEK_SET); + if (fread(offsets, 4, 4, baserom) != 4) { + fprintf(stderr, "failed to read from baserom\n"); + fclose(baserom); + return 1; + } + debug_printf("read offsets\n"); + + // read fnt + struct NtrDirHeader *fnt = malloc(offsets[1]); + if (fnt == NULL) { + fprintf(stderr, "unable to allocate FNT buffer\n"); + fclose(baserom); + return 1; + } + fseek(baserom, offsets[0], SEEK_SET); + if (fread(fnt, 1, offsets[1], baserom) != offsets[1]) { + fprintf(stderr, "unable to read FNT\n"); + free(fnt); + fclose(baserom); + return 1; + } + debug_printf("read fnt\n"); + + unsigned file_id = find_file(fnt, argv[2]); + free(fnt); + if (file_id == FIND_FAIL) { + fprintf(stderr, "file not found"); + fclose(baserom); + return 1; + } + debug_printf("found file with id %u\n", file_id); + + // Extract the file to stdout + if (8 * file_id >= offsets[3]) { + fprintf(stderr, "nitrofs lookup failed"); + fclose(baserom); + return 1; + } + + FILE *out = fdopen(dup(fileno(stdout)), "wb"); + fseek(baserom, offsets[2] + 8 * file_id, SEEK_SET); + fread(offsets, 4, 2, baserom); + fseek(baserom, offsets[0], SEEK_SET); + while (offsets[1] - offsets[0] > BUFSIZ) { + fread(FILEBUF, 1, BUFSIZ, baserom); + fwrite(FILEBUF, 1, BUFSIZ, out); + offsets[0] += BUFSIZ; + } + fread(FILEBUF, 1, offsets[1] - offsets[0], baserom); + fwrite(FILEBUF, 1, offsets[1] - offsets[0], out); + fclose(out); + + fclose(baserom); + return 0; +} diff --git a/tools/asmdiff/ntruncompbw.c b/tools/asmdiff/ntruncompbw.c new file mode 100644 index 00000000..e97db925 --- /dev/null +++ b/tools/asmdiff/ntruncompbw.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +static inline uint32_t READ32(const unsigned char * ptr) +{ + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); +} + +static uint32_t MIi_UncompressBackwards(unsigned char ** out_p, size_t compsize) +{ + unsigned char * out = *out_p; + + // Read the pointer to the end of the compressed image + uint8_t * endptr = out + compsize - 8; + uint32_t size = READ32(endptr); + uint32_t offset = READ32(endptr + 4); + out = realloc(out, compsize + offset); + if (out == NULL) + return -1u; + endptr = out + compsize; + uint8_t * dest_p = endptr + offset; + uint8_t * end = endptr - ((uint8_t)(size >> 24)); + uint8_t * start = endptr - (size & ~0xFF000000); + while (end > start) { + uint8_t r5 = *--end; + for (int i = 0; i < 8; i++) { + if ((r5 & 0x80) == 0) + *--dest_p = *--end; + else { + int ip = *--end; + int r7 = *--end; + + + r7 = ((r7 | (ip << 8)) & ~0xF000) + 2; + ip += 0x20; + while (ip >= 0) { + dest_p[-1] = dest_p[r7]; + dest_p--; + ip -= 0x10; + } + } + if (end <= start) + break; + r5 <<= 1; + } + } + *out_p = out; + return compsize + offset; +} + +int main(int argc, char ** argv) +{ + if (argc < 4) { + fprintf(stderr, "usage: %s FILE VMA END\n\ninsufficient arguments\n", argv[0]); + return 1; + } + char * infname = argv[1]; + uint32_t vma = strtoul(argv[2], NULL, 0); + uint32_t end = strtoul(argv[3], NULL, 0); + if (end == 0) { + fprintf(stderr, "compressed size is 0, no action taken\n"); + return 0; + } + FILE * infile = fopen(infname, "r+b"); + if (infile == NULL) { + fclose(infile); + fprintf(stderr, "unable to open file %s for reading\n", infname); + return 1; + } + fseek(infile, 0, SEEK_END); + long infsize = ftell(infile); + fseek(infile, 0, SEEK_SET); + if (infsize != end - vma) { + fclose(infile); + fprintf(stderr, "compressed size does not match file size, I am cowardly doing nothing\n"); + return 0; + } + unsigned char * inbuf = malloc(infsize); + if (inbuf == NULL) { + fclose(infile); + fprintf(stderr, "error: malloc(%d)\n", (int)infsize); + return 1; + } + if (fread(inbuf, 1, infsize, infile) != infsize) { + fclose(infile); + free(inbuf); + fprintf(stderr, "error reading from %s\n", infname); + return 1; + } + uint32_t outsize = MIi_UncompressBackwards(&inbuf, end - vma); + if (outsize == -1u) { + fclose(infile); + fprintf(stderr, "fatal error reallocating for decompression\n"); + return 1; + } + fseek(infile, 0, SEEK_SET); + if (fwrite(inbuf, 1, outsize, infile) != outsize) { + fclose(infile); + free(inbuf); + fprintf(stderr, "error writing back to %s\n", infname); + return 1; + } + fclose(infile); + free(inbuf); + return 0; +} diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index cce7cdea..be00fb72 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -17,7 +17,7 @@ #include "fnmatch.h" -#if (__GNUC__ <= 7) && !defined _MSC_VER +#if (__cplusplus < 201703L) #include <experimental/filesystem> namespace fs = std::experimental::filesystem; #else @@ -340,7 +340,7 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) FileImages fi { .Id = 0x46494D47, // GMIF - .ChunkSize = static_cast<uint32_t>(sizeof(FileImages) + fatEntries.back().End) + .ChunkSize = static_cast<uint32_t>(sizeof(FileImages) + (fatEntries.empty() ? 0 : fatEntries.back().End)) }; if ((fi.ChunkSize % 4) != 0) diff --git a/tools/knarc/Narc.h b/tools/knarc/Narc.h index 7d9cc117..78c163c6 100644 --- a/tools/knarc/Narc.h +++ b/tools/knarc/Narc.h @@ -5,7 +5,7 @@ #include <string> #include <vector> -#if (__GNUC__ <= 7) && !defined _MSC_VER +#if (__cplusplus < 201703L) #include <experimental/filesystem> namespace fs = std::experimental::filesystem; #else diff --git a/tools/mwasmarm_patcher/Makefile b/tools/mwasmarm_patcher/Makefile index bff3a677..9765f713 100644 --- a/tools/mwasmarm_patcher/Makefile +++ b/tools/mwasmarm_patcher/Makefile @@ -1,11 +1,6 @@ .PHONY: all clean
-UNAME_S := $(shell uname -s)
-ifeq ($(UNAME_S),Darwin)
-CC := clang
-else
CC := gcc
-endif
CFLAGS := -O3
.PHONY: all clean
diff --git a/tools/nitrogfx/Makefile b/tools/nitrogfx/Makefile index 16b2632d..2ed6cf1e 100644 --- a/tools/nitrogfx/Makefile +++ b/tools/nitrogfx/Makefile @@ -1,5 +1,11 @@ CC = gcc +HAVE_LIBPNG := $(shell pkg-config libpng; echo $?) + +ifeq ($(HAVE_LIBPNG),1) +$(error No package 'libpng' found) +endif + CFLAGS = -Wall -Wextra -Werror -Wno-sign-compare -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK $(shell pkg-config --cflags libpng) LIBS = $(shell pkg-config --libs libpng) diff --git a/tools/nitrogfx/gfx.c b/tools/nitrogfx/gfx.c index ee7e0d6f..43e8f83c 100644 --- a/tools/nitrogfx/gfx.c +++ b/tools/nitrogfx/gfx.c @@ -433,7 +433,9 @@ void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int m free(buffer); } -void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned, uint32_t key) +void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, + bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned, + uint32_t key, bool wrongSize) { FILE *fp = fopen(path, "wb"); @@ -499,15 +501,15 @@ void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, in } } - WriteGenericNtrHeader(fp, "RGCN", bufferSize + (sopc ? 0x30 : 0x20), byteOrder, version101, sopc ? 2 : 1); + WriteGenericNtrHeader(fp, "RGCN", bufferSize + (sopc ? 0x30 : 0x20) + (wrongSize ? -8 : 0), byteOrder, version101, sopc ? 2 : 1); unsigned char charHeader[0x20] = { 0x52, 0x41, 0x48, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 }; - charHeader[4] = (bufferSize + 0x20) & 0xFF; - charHeader[5] = ((bufferSize + 0x20) >> 8) & 0xFF; - charHeader[6] = ((bufferSize + 0x20) >> 16) & 0xFF; - charHeader[7] = ((bufferSize + 0x20) >> 24) & 0xFF; + charHeader[4] = (bufferSize + 0x20 + (wrongSize ? -8 : 0)) & 0xFF; + charHeader[5] = ((bufferSize + 0x20 + (wrongSize ? -8 : 0)) >> 8) & 0xFF; + charHeader[6] = ((bufferSize + 0x20 + (wrongSize ? -8 : 0)) >> 16) & 0xFF; + charHeader[7] = ((bufferSize + 0x20 + (wrongSize ? -8 : 0)) >> 24) & 0xFF; if (!clobberSize) { diff --git a/tools/nitrogfx/gfx.h b/tools/nitrogfx/gfx.h index d0e6521a..389aec41 100644 --- a/tools/nitrogfx/gfx.h +++ b/tools/nitrogfx/gfx.h @@ -32,7 +32,9 @@ struct Image { void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); uint32_t ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); -void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned, uint32_t key); +void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, + bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned, + uint32_t key, bool wrongSize); void FreeImage(struct Image *image); void ReadGbaPalette(char *path, struct Palette *palette); void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIndex); diff --git a/tools/nitrogfx/main.c b/tools/nitrogfx/main.c index b2d3352a..5561e44e 100644 --- a/tools/nitrogfx/main.c +++ b/tools/nitrogfx/main.c @@ -116,7 +116,9 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions * free(string); } - WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101, options->sopc, options->scanned, key); + WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight, + &image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101, + options->sopc, options->scanned, key, options->wrongSize); FreeImage(&image); } @@ -360,6 +362,7 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a options.bitDepth = 4; options.metatileWidth = 1; options.metatileHeight = 1; + options.wrongSize = false; options.clobberSize = false; options.byteOrder = true; options.version101 = false; @@ -442,6 +445,9 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a { options.scanned = true; } + else if (strcmp(option, "-wrongsize") == 0) { + options.wrongSize = true; + } else { FATAL_ERROR("Unrecognized option \"%s\".\n", option); diff --git a/tools/nitrogfx/options.h b/tools/nitrogfx/options.h index 66e9895d..e6721766 100644 --- a/tools/nitrogfx/options.h +++ b/tools/nitrogfx/options.h @@ -32,6 +32,7 @@ struct PngToNtrOptions { bool version101; bool sopc; bool scanned; + bool wrongSize; }; struct Attr0 { |