aboutsummaryrefslogtreecommitdiff
path: root/project/src/lib-std.h
diff options
context:
space:
mode:
authorroot <root@dc13.lemmi>2020-07-21 10:00:46 +0200
committerroot <root@dc13.lemmi>2020-07-21 10:00:46 +0200
commit1192c4575ea7afdf38e3fa0df4587a08620af11e (patch)
tree6910a62487c282d0840d2e668aa7eb40b7c8a3fd /project/src/lib-std.h
parent76de8a89f7c1d1b4522eb66e8f89d248e8c1781f (diff)
SZS v2.18a
Diffstat (limited to 'project/src/lib-std.h')
-rw-r--r--project/src/lib-std.h2234
1 files changed, 2234 insertions, 0 deletions
diff --git a/project/src/lib-std.h b/project/src/lib-std.h
new file mode 100644
index 0000000..28d1eaa
--- /dev/null
+++ b/project/src/lib-std.h
@@ -0,0 +1,2234 @@
+
+/***************************************************************************
+ * _______ _______ _______ *
+ * | ___ |____ | ___ | *
+ * | | |_| / /| | |_| *
+ * | |_____ / / | |_____ *
+ * |_____ | / / |_____ | *
+ * _ | | / / _ | | *
+ * | |___| |/ /____| |___| | *
+ * |_______|_______|_______| *
+ * *
+ * Wiimms SZS Tools *
+ * https://szs.wiimm.de/ *
+ * *
+ ***************************************************************************
+ * *
+ * This file is part of the SZS project. *
+ * Visit https://szs.wiimm.de/ for project details and sources. *
+ * *
+ * Copyright (c) 2011-2020 by Dirk Clemens <wiimm@wiimm.de> *
+ * *
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program 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 General Public License for more details. *
+ * *
+ * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
+ * *
+ ***************************************************************************/
+
+#ifndef SZS_LIB_STD_H
+#define SZS_LIB_STD_H 1
+
+#define _GNU_SOURCE 1
+
+#include "version.h"
+#include "dclib-types.h"
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef WIN_SZS_LIB
+ #include <sys/time.h>
+ #include <unistd.h>
+ #include <arpa/inet.h>
+#endif
+
+#include "system.h"
+#include "dclib-basics.h"
+#include "dclib-file.h"
+#include "dclib-debug.h"
+#include "lib-dol.h"
+#include "file-type.h"
+#include "lib-numeric.h"
+
+#if HAVE_XSRC
+ #include "xsrc/x-std.h"
+#endif
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// defines ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// also used by UI
+
+#define SZS_SETUP_FILE "wszst-setup.txt"
+#define CHECK_FILE_SIZE 0x800
+#define OPT_PNG_TYPE_CLASS 0x7fef0bff
+
+#define DEF_EPSILON_POS 0.01
+#define DEF_EPSILON_ROT 0.01
+#define DEF_EPSILON_SCALE 0.01
+#define DEF_EPSILON_SIZE 0.01
+#define DEF_EPSILON_VEL 0.01
+#define DEF_EPSILON_TIME 0.01
+
+#define M1(a) ( (typeof(a))~0 )
+#define IS_M1(a) ( (a) == (typeof(a))~0 )
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// Setup ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void SetupColors();
+void SetupLib ( int argc, char ** argv, ccp p_progname );
+void NormalizeOptions
+(
+ uint log_level // 0: no log
+ // 1: print PROGRAM_NAME
+ // 2: + print SHARE_PATH + SEARCH_PATH
+ // 3: + print AUTOADD_PATH
+);
+
+ccp GetCtLeInfo();
+
+const KeywordTab_t * CheckCommandHelper
+ ( int argc, char ** argv, const KeywordTab_t * key_tab );
+
+extern const char text_logo[];
+extern void (*print_title_func) ( FILE * f );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// error interface ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+enum
+{
+ ERR_CACHE_USED = ERU_SOURCE_FOUND,
+ ERR_ENCODING_WARN = ERR_SUBJOB_WARNING,
+
+ ERR_INVALID_IFORM = ERU_ERROR1_01,
+ ERR_INVALID_FFORM = ERU_ERROR1_02,
+
+ ERR_BZIP2 = ERU_ERROR2_01,
+ ERR_PNG = ERU_ERROR2_02,
+};
+
+//-----------------------------------------------------------------------------
+
+ccp LibGetErrorName ( int stat, ccp ret_not_found );
+ccp LibGetErrorText ( int stat, ccp ret_not_found );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// compatibility ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum compatible_t
+{
+ COMPAT_0, // legacy mode
+ COMPAT_1_23, // BMG colors => opt_bmg_colors = 0
+ COMPAT_1_39, // BMG inline support => opt_bmg_inline_attrib = false
+ COMPAT_1_44, // new BMG escapes + attributes => opt_bmg_old_escapes = true
+ COMPAT_1_46, // KMP flags => opt_kmp_flags = false;
+ COMPAT_2_08, // BMG slots and sections => opt_bmg_use_* = false
+ COMPAT_CURRENT, // current version
+
+ COMPAT__N // number of elements of 'compatible_info'
+}
+compatible_t;
+
+//-----------------------------------------------------------------------------
+
+typedef struct compatible_info_t
+{
+ compatible_t compatible; // selector
+ u32 revision; // revision number
+ char version[8]; // version string of format "1.23" of "1.23a"
+}
+compatible_info_t;
+
+//-----------------------------------------------------------------------------
+
+extern compatible_t compatible; // = COMPAT_CURRENT
+extern const compatible_info_t compatible_info[COMPAT__N];
+
+const compatible_info_t * ScanCompatible ( ccp arg );
+int ScanOptCompatible ( ccp arg );
+char * PrintOptCompatible(); // circ-buf
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// warn level ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[WarnLevel_t]] Same as CTW: WarnLevel
+
+typedef enum WarnLevel_t
+{
+ WLEVEL_UNKNOWN, // unknown
+ WLEVEL_NA, // not applicable
+ WLEVEL_OK, // ok
+ WLEVEL_FIXED, // fixed
+ WLEVEL_HINT, // hint
+ WLEVEL_WARN, // warning
+ WLEVEL_ERROR, // error
+ WLEVEL_FAIL, // failed
+ WLEVEL_FATAL, // fatal error
+ WLEVEL_INVALID, // invalid value
+
+ WLEVEL__N
+}
+__attribute__ ((packed)) WarnLevel_t;
+
+extern const char WarnLevelNameLo[WLEVEL__N][8]; // lower case
+extern const char WarnLevelNameUp[WLEVEL__N][8]; // upper case
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// sub file system ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[SubFile_t]]
+
+typedef struct SubFile_t
+{
+ ccp fname; // filename
+ u8 *data; // pointer to data
+ uint size; // file size
+ uint type; // file type (user data)
+
+ bool fname_alloced; // true: 'fname' is alloced
+ bool data_alloced; // true: 'data' is alloced
+}
+SubFile_t;
+
+//-----------------------------------------------------------------------------
+// [[SubFileList_t]]
+
+typedef struct SubFileList_t
+{
+ SubFile_t **list; // file list
+ uint used; // used elements of 'list'
+ uint size; // allooced elements of 'list'
+}
+SubFileList_t;
+
+///////////////////////////////////////////////////////////////////////////////
+// [[SubDirList_t]]
+
+struct SubDir_t;
+
+typedef struct SubDirList_t
+{
+ struct SubDir_t **list; // dir list
+ uint used; // used elements of 'list'
+ uint size; // allooced elements of 'list'
+}
+SubDirList_t;
+
+//-----------------------------------------------------------------------------
+// use [[SubDir_t]] as top level of a file system
+
+typedef struct SubDir_t
+{
+ ccp dname; // directory name
+ bool dname_alloced; // true: 'dname' is alloced
+ SubDirList_t dir; // sub-directories
+ SubFileList_t file; // sub-files
+}
+SubDir_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+static inline void InitializeSubDirList ( SubDirList_t *s )
+ { DASSERT(s); memset(s,0,sizeof(*s)); }
+static inline void InitializeSubDir ( SubDir_t *s )
+ { DASSERT(s); memset(s,0,sizeof(*s)); s->dname = EmptyString; }
+static inline void InitializeSubFileList ( SubFileList_t *s )
+ { DASSERT(s); memset(s,0,sizeof(*s)); }
+static inline void InitializeSubFile ( SubFile_t *s )
+ { DASSERT(s); memset(s,0,sizeof(*s)); }
+
+void ResetSubDirList ( SubDirList_t *sdl );
+void ResetSubDir ( SubDir_t *sd );
+void ResetSubFileList ( SubFileList_t *sfl );
+void ResetSubFile ( SubFile_t *sf );
+
+void DumpSubDir ( FILE *f, int indent, const SubDir_t *sd );
+void DumpSubDirList ( FILE *f, int indent, const SubDirList_t *sdl );
+void DumpSubFileList ( FILE *f, int indent, const SubFileList_t *sfl );
+
+///////////////////////////////////////////////////////////////////////////////
+
+SubDir_t * FindSubDir ( const SubDir_t *sd, mem_t path );
+SubFile_t * FindSubFile ( const SubDir_t *sd, mem_t path );
+
+SubDir_t * InsertSubDir ( SubDir_t *sd, mem_t path, bool *new_dir );
+SubFile_t * InsertSubFile ( SubDir_t *sd, mem_t path, bool *new_file );
+
+bool RemoveSubDir ( SubDir_t *sd, mem_t path );
+bool RemoveSubFile ( SubDir_t *sd, mem_t path );
+
+FILE * OpenSubFile ( const SubDir_t *sd, mem_t path );
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[SubFileFunc]]
+
+struct SubFileIterator_t;
+
+typedef int (*SubFileFunc)
+(
+ struct
+ SubFileIterator_t *sfi, // iterator data
+ uint mode, // 0:file, 1:open dir, 2:close dir
+ SubDir_t *dir, // current directory
+ SubFile_t *file // NULL or current file
+);
+
+///////////////////////////////////////////////////////////////////////////////
+// [[SubFileIterator_t]]
+
+typedef struct SubFileIterator_t
+{
+ SubFileFunc func; // function to call
+ int user_int; // user int
+ void *user_ptr; // user pointer
+
+ uint depth; // dir depth
+ char *path_ptr; // pointer to NULL term of 'fullpath'
+ char path[2000]; // full path
+}
+SubFileIterator_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+int IterateSubDir ( SubDir_t *sd, SubFileIterator_t *sfi );
+enumError SaveSubFiles ( SubDir_t *sd, ccp basepath );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// [[obsolete+]] old_container ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// old [[container]] will be replaced by Container_t & ContainerData_t
+// [[DataContainer_t]]
+
+#ifdef TEST // [[container]] [[obsolete+]]
+ #define USE_NEW_CONTAINER_MDL 1
+ #define USE_NEW_CONTAINER_PAT 1
+ #define USE_NEW_CONTAINER_CTC 1
+#elif HAVE_WIIMM_EXT
+ #define USE_NEW_CONTAINER_MDL 1
+ #define USE_NEW_CONTAINER_PAT 1
+ #define USE_NEW_CONTAINER_CTC 1
+#else // activated in 2020-01 -> [[obsilete]] at mid 2020
+ #define USE_NEW_CONTAINER_MDL 1
+ #define USE_NEW_CONTAINER_PAT 1
+ #define USE_NEW_CONTAINER_CTC 1
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct DataContainer_t
+{
+ Container_t container; // low level container
+
+ const u8 *data; // data
+ uint size; // size of 'data'
+ int ref_count; // reference counter
+ bool data_alloced; // true: free data
+ bool dc_alloced; // true: container itself is alloced
+
+} DataContainer_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if USE_NEW_CONTAINER_MDL
+ typedef ContainerData_t ContainerMDL_t;
+#else
+ typedef DataContainer_t ContainerMDL_t;
+#endif
+
+#if USE_NEW_CONTAINER_PAT
+ typedef ContainerData_t ContainerPAT_t;
+#else
+ typedef DataContainer_t ContainerPAT_t;
+#endif
+
+#if USE_NEW_CONTAINER_CTC
+ typedef ContainerData_t ContainerCTC_t;
+#else
+ typedef DataContainer_t ContainerCTC_t;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+DataContainer_t * UseSubContainer
+(
+ DataContainer_t *dc, // old_container to reuse, if
+ // InDataContainer(dc,data) && ref:count == 1
+ ContainerData_t *cdata_src // NULL or container data source
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+DataContainer_t * NewContainer
+(
+ DataContainer_t *dc, // old_container to reuse, if
+ // InDataContainer(dc,data) && ref:count == 1
+ const void *data, // data to copy/move/link
+ uint size, // size of 'data'
+ CopyMode_t mode // copy mode on creation
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+DataContainer_t * DupContainer
+(
+ DataContainer_t *dup_dc, // old_container to reuse, if
+ // InDataContainer(dc,data) && ref:count == 1
+ // => complete dc->data is copied
+ const void *data, // data to copy/move/link
+ uint size, // size of 'data'
+ bool include_behind, // on creation: include 'dc->data'
+ // behind 'data+size' if possible
+ const void **new_data // not NULL: store new data pointer here
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+DataContainer_t * AllocContainer
+(
+ // increments the reference counter and returns 'ct'
+
+ DataContainer_t *dc // NULL or valid old_container
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+DataContainer_t * FreeContainer
+(
+ // decrements the reference counter and returns 'NULL'
+ // if reference counter == 0: free data and/or ct
+
+ DataContainer_t *dc // NULL or valid old_container
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool InDataContainer
+(
+ // return true, if ptr is in old_container
+
+ const DataContainer_t *dc, // NULL or valid old_container
+ const void *ptr // NULL or pointer to test
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// string helpers ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+int NintendoCmp ( ccp path1, ccp path2 );
+
+void PrintNumF
+(
+ FILE *f, // output stream
+ const u8 *data, // valid pointer to data
+ uint size, // size of 'data'
+ ccp type_str // NULL or type string
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// word compare functions ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+uint CreateHaystackListWCMP
+(
+ char * buf, // valid pointer to output buffer
+ uint buf_size, // soue of 'buf'
+ ccp * source // NULL terminated list with source Strings
+);
+
+uint CreateHaystackWCMP
+(
+ char * buf, // valid pointer to output buffer
+ uint buf_size, // soue of 'buf'
+ ccp source // source String
+);
+
+uint CreateNeedleWCMP
+(
+ char * buf, // valid pointer to output buffer
+ uint buf_size, // soue of 'buf'
+ ccp source // NULL terminated list with source Strings
+);
+
+bool FindWCMP
+(
+ ccp haystack, // search in this string
+ ccp needle, // try to find this string
+ uint flags, // bit field:
+ // bit-0 set = 1: 'haystack' already in WCMP format
+ // bit-1 set = 2: 'needle' already in WCMP format
+ char * tempbuf, // NULL or fast buffer for temporary WCMP conversions
+ uint tempbuf_size // size of 'buf'
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct search_filter_t
+{
+ ccp string; // alloced wcmp string
+ int mode; // user defined mode
+
+} search_filter_t;
+
+search_filter_t * AllocSearchFilter ( uint n );
+void FreeSearchFilter ( search_filter_t *f );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// string substitutions ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct SubstString_t
+{
+ char c1, c2; // up to 2 codes (lower+upper case)
+ bool allow_slash; // true: allow slash in replacement
+ ccp str; // pointer to string
+
+} SubstString_t;
+
+//-----------------------------------------------------------------------------
+
+int ScanEscapeChar ( ccp arg );
+
+char * SubstString
+(
+ char * buf, // destination buffer
+ size_t bufsize, // size of 'buf'
+ SubstString_t * tab, // replacement table
+ ccp source, // source text
+ int * count, // not NULL: number of replacements
+ char escape_char // the escape character, usually '%'
+);
+
+int SubstDest
+(
+ char * buf, // destination buffer
+ size_t bufsize, // size of 'buf'
+ ccp source, // source text
+ ccp dest, // destination path
+ ccp dest_fname, // if 'dest' has no file part
+ // then extract filename from here or source
+ ccp default_ext, // NULL or default extension (e.g. '.ext')
+ bool dest_is_dir // destination is a directory
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// file support ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#undef CF_PALETTE // for windows
+
+typedef enum cmd_flags_t
+{
+ CF_IMAGE = 0x0001, // valid if scanning image type
+ CF_PALETTE = 0x0002, // img format has palette
+ CF_AUTO = 0x0004, // auto mode
+
+} cmd_flags_t;
+
+//-----------------------------------------------------------------------------
+
+#define PNG_MAGIC8_NUM 0x89504e470d0a1a0aull
+
+//-----------------------------------------------------------------------------
+
+ccp GetNameFF ( file_format_t ff1, file_format_t ff2 );
+ccp GetNameFFv ( file_format_t ff1, file_format_t ff2, int version );
+ccp GetExtFF ( file_format_t ff1, file_format_t ff2 );
+ccp GetBinExtFF ( file_format_t ff );
+ccp GetTextExtFF ( file_format_t ff );
+ccp GetMagicExtFF ( file_format_t ff1, file_format_t ff2 );
+ccp GetMagicStringFF ( file_format_t ff );
+
+file_format_t GetBinFF ( file_format_t ff );
+file_format_t GetTextFF ( file_format_t ff );
+file_format_t GetByNameFF ( ccp name );
+
+file_format_t GetByMagicFF
+(
+ const void *data, // pointer to data
+ uint data_size, // size of data
+ uint file_size // NULL or total size of file
+);
+
+const file_type_t * GetFileTypeByExt
+(
+ ccp ext, // NULL or file extension with optional preceeding point
+ bool need_magic // filter only file types with magic
+);
+
+const file_type_t * GetFileTypeBySubdir
+(
+ ccp path, // NULL or file extension with optional preceeding point
+ bool need_magic // filter only file types with magic
+);
+
+const file_type_t * GetFileTypeFF ( file_format_t ff );
+
+ff_attrib_t GetAttribFF ( file_format_t ff );
+ff_attrib_t GetAttribByMagicFF
+(
+ const void * data, // valid pointer to data
+ uint data_size, // size of 'data'
+ file_format_t *ff // not NULL: store file format here
+);
+
+int GetVersionFF
+(
+ // returns -1 for unknown, or the version number
+
+ file_format_t fform, // valid firl format
+ const void *data, // data pointer
+ uint data_size, // size of available data
+ char *res_suffix // not NULL: return 1 char as suffix, or 0
+);
+
+int GetVersionByMagic
+(
+ // returns -1 for unknown, or the version number
+
+ const void *data, // data pointer
+ uint data_size, // size of available data
+ char *res_suffix // not NULL: return 1 char as suffix, or 0
+);
+
+bool IsBRSUB ( file_format_t ff );
+bool IsByMagicBRSUB ( const void * data, uint data_size );
+
+bool IsArchiveFF ( file_format_t ff );
+bool IsTextFF ( file_format_t ff );
+bool IsGeoHitKartFF ( file_format_t ff );
+bool IsGeoHitObjFF ( file_format_t ff );
+
+bool IsYazFF ( file_format_t ff );
+int GetYazVersionFF ( file_format_t ff );
+bool IsCompressedFF ( file_format_t ff );
+file_format_t GetYazFF ( file_format_t ff );
+file_format_t GetCompressedFF ( file_format_t ff );
+
+void SetCompressionFF
+(
+ file_format_t ff_arch, // if >0: set 'opt_fform'
+ file_format_t ff_compr // if >0: set 'fform_compr'
+ // and 'fform_compr_force'
+);
+
+file_format_t IsImageFF
+(
+ // returns the normalized FF for a valid image or NULL (=FF_UNKNOWN)
+
+ file_format_t fform, // file format to check
+ bool allow_png // true: allow PNG
+);
+
+file_format_t GetImageFF
+(
+ file_format_t fform1, // if a valid image ff, use this one
+ file_format_t fform2, // if a valid image ff, use this one
+ ccp path, // not NULL and exists: use file format
+ file_format_t default_fform, // use this as default, if valid ff
+ bool allow_png, // true: allow PNG
+ file_format_t not_found // return this, if all other fails
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define BRSUB_MODE2(a,b) ( (a) << 24 | (b) << 5 )
+#define BRSUB_MODE3(a,b,c) ( (a) << 24 | (b) << 5 | (c) )
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+enumError OpenFILE
+(
+ File_t * f, // file structure
+ bool initialize, // true: initialize 'f'
+ ccp fname, // file to open
+ bool ignore_no_file, // ignore if file doeas not exists
+ // and return warning ERR_NOT_EXISTS
+ bool ignore_limit // ignore opt_max_file_size
+);
+
+enumError CreateFILE
+(
+ File_t * f, // file structure
+ bool initialize, // true: initialize 'f'
+ ccp fname, // file to open
+ bool testmode, // true: don't open
+ bool create_path, // create path if necessary
+ bool overwrite, // overwrite existing files without warning
+ bool remove_dest, // remove existing file before creating
+ bool update // don't create new files
+);
+
+FileMode_t GetFileModeByOpt
+(
+ int testmode, // test mode
+ ccp fname1, // NULL or dest filename
+ ccp fname2 // NULL or source filename
+);
+
+enumError CreateFileOpt
+(
+ File_t * f, // file structure
+ bool initialize, // true: initialize 'f'
+ ccp fname, // file to open
+ bool testmode, // true: don't open
+ ccp srcfile // NULL or src file name
+ // if fname == srcfile: overwrite enabled
+);
+
+enumError AppendFILE
+(
+ File_t * f, // file structure
+ bool initialize, // true: initialize 'f'
+ ccp fname, // file to open
+ bool testmode, // true: don't open
+ bool create_path // create path if necessary
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+FILE * CreateAnalyzeFile();
+void CloseAnalyzeFile();
+
+///////////////////////////////////////////////////////////////////////////////
+
+int ScanOptChdir ( ccp arg );
+
+char * SplitSubPath
+(
+ char * buf, // destination buffer
+ size_t buf_size, // size of 'buf'
+ ccp path // source path, if NULL: use 'buf'
+);
+
+enumError OpenReadFILE
+(
+ ccp path1, // NULL or part #1 of path
+ ccp path2, // NULL or part #2 of path
+ bool silent, // suppress all error messages
+ u8 ** res_data, // store alloced data here
+ uint * res_size, // not NULL: store data size
+ ccp * res_fname, // not NULL: store alloced filename
+ FileAttrib_t * res_fatt // not NULL: store file attributes
+);
+
+enumError LoadFILE
+(
+ ccp path1, // NULL or part #1 of path
+ ccp path2, // NULL or part #2 of path
+ size_t skip, // skip num of bytes before reading
+ void * data, // destination buffer, size = 'size'
+ size_t size, // size to read
+ int silent, // 0: print all error messages
+ // 1: suppress file size warning
+ // 2: suppress all error messages
+ FileAttrib_t * fatt, // not NULL: store file attributes
+ bool fatt_max // true: store *max* values to 'fatt'
+);
+
+enumError SaveFILE
+(
+ ccp path1, // NULL or part #1 of path
+ ccp path2, // NULL or part #2 of path
+ bool overwrite, // true: force overwriting
+ const void * data, // data to write
+ uint data_size, // size of 'data'
+ FileAttrib_t * fatt // not NULL: set timestamps using this attribs
+);
+
+uint IsolateFilename
+(
+ // return length of found and copied string
+
+ char * buf, // destination buffer
+ size_t bufsize, // size of 'buf'
+ ccp path, // path to analyze
+ file_format_t fform // not NULL: remove related file extension
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SetupAutoAdd();
+bool DefineAutoAddPath ( ccp path );
+s64 FindAutoAdd ( ccp fname, ccp ext, char *buf, uint buf_size );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// repair magic ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[repair_mode_t]]
+
+typedef enum repair_mode_t
+{
+ REPMD_OFF, // repair is OFF
+ REPMD_ANALYZE, // repair is ON, but only for analysis
+ REPMD_REPAIR, // repair is ON & replace correct magic
+
+ REPMD_F_FNAME_FIRST = 0x10, // flag: Use file extension first
+
+ REPMD_R_FALLBACK = 0x20, // result: 'ff_fallback' used
+ REPMD_R_FNAME = 0x40, // result: file extension used
+
+ REPMD_M_MODES = 0x07, // mask for modes
+ REPMD_M_FLAGS = 0x10, // mask for flags
+ REPMD_M_RESULTS = 0x60, // mask for flags
+}
+repair_mode_t;
+
+//-----------------------------------------------------------------------------
+
+extern repair_mode_t repair_magic;
+extern repair_mode_t repair_magic_flags;
+
+int ScanOptRepairMagic ( ccp arg );
+static inline bool IsRepairMagic() { return repair_magic > REPMD_OFF; }
+
+///////////////////////////////////////////////////////////////////////////////
+// [[repair_ff_t]]
+
+typedef struct repair_ff_t
+{
+ repair_mode_t mode; // repair mode without flags
+ repair_mode_t flags; // result flags
+ file_format_t fform; // file format, original or repaired
+ char magic[8]; // magic, original or repaired
+ uint magic_len; // length of 'magic'
+
+ char orig_magic[8]; // magig of original
+ char file_ext[8]; // relevant file extension
+}
+repair_ff_t;
+
+//-----------------------------------------------------------------------------
+
+repair_ff_t * ResetRepairMagic ( repair_ff_t * data, repair_ff_t * fallback );
+ccp GetRepairMagicInfo ( const repair_ff_t *rep );
+
+//-----------------------------------------------------------------------------
+
+file_format_t AnalyseMagic
+(
+ // returns rep->fform
+
+ repair_ff_t *rep, // not NULL: result, will be initalized
+ const void *data, // pointer to data
+ uint data_size, // size of data
+ uint file_size, // NULL or total size of file
+ file_format_t ff_fallback, // FF_UNKNOWN or fallback FF if GetByMagicFF() fails
+ ccp fname, // filename to analyse if GetByMagicFF() fails
+ bool fname_first // analyse the filename first.
+);
+
+//-----------------------------------------------------------------------------
+
+file_format_t RepairMagic
+(
+ // returns rep->fform
+
+ repair_ff_t *rep, // not NULL: result, will be initalized
+ void *data, // pointer to data, magic will be replaced
+ uint data_size, // size of data
+ uint file_size, // NULL or total size of file
+ file_format_t ff_fallback, // FF_UNKNOWN or fallback FF if GetByMagicFF() fails
+ ccp fname, // filename to analyse if GetByMagicFF() fails
+ bool fname_first // analyse the filename first.
+);
+
+//-----------------------------------------------------------------------------
+
+file_format_t AnalyseMagicByOpt
+(
+ // returns rep->fform
+ // mode & fname_first depends on --repair-magic, but is never REPMD_REPAIR
+
+ repair_ff_t *rep, // not NULL: result, will be initalized
+ const void *data, // pointer to data
+ uint data_size, // size of data
+ uint file_size, // NULL or total size of file
+ file_format_t ff_fallback, // FF_UNKNOWN or fallback FF if GetByMagicFF() fails
+ ccp fname // filename to analyse if GetByMagicFF() fails
+);
+
+//-----------------------------------------------------------------------------
+
+file_format_t RepairMagicByOpt
+(
+ // returns rep->fform
+ // mode & fname_first depends on --repair-magic
+
+ repair_ff_t *rep, // not NULL: result, will be initalized
+ void *data, // pointer to data, magic will be replaced
+ uint data_size, // size of data
+ uint file_size, // NULL or total size of file
+ file_format_t ff_fallback, // FF_UNKNOWN or fallback FF if GetByMagicFF() fails
+ ccp fname // filename to analyse if GetByMagicFF() fails
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// file class ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum patch_file_t
+{
+ PFILE_NO_FILENAME = 0x0001, // no filename or an empty filename specified
+ PFILE_UNKNOWN = 0x0002, // unknown (not supported) file type
+
+ //--- the following values are always >PFILE_UNKNOWN
+
+ PFILE_COURSE = 0x0010, // KMP file 'course.txt', unsure if KMP or KCL
+ PFILE_COURSE_KMP = 0x0020, // KMP file 'course.{kmp,kmp.txt,txt}'
+ PFILE_COURSE_KCL = 0x0040, // KCL file 'course.{kcl,kcl.txt,txt}'
+ PFILE_OTHER_KCL = 0x0080, // other KCL files
+
+ PFILE_MODEL = 0x0100, // BRRES file 'course_[d_]model.brres'
+ PFILE_MINIMAP = 0x0200, // BRRES file 'map_model.brres'
+ PFILE_VRCORN = 0x0400, // BRRES file 'vrcorn_model.brres'
+ PFILE_OTHER_BRRES = 0x0800, // other BRRES files
+
+
+ //--- flags
+
+ PFILE_F_DEFAULT = 0x1000, // flags for default settings
+ PFILE_F_LOG = 0x2000, // enable logging
+ PFILE_F_LOG_ALL = 0x4000, // enable logging -> inherit by KCP+KMP+MDL
+ PFILE_F_HIDE = 0x8000, // help flag to hide modes in PrintFileClassInfo()
+
+
+ //--- masks
+
+ PFILE_M_NONE = PFILE_UNKNOWN
+ | PFILE_NO_FILENAME,
+
+ PFILE_M_KCL = PFILE_COURSE_KCL
+ | PFILE_OTHER_KCL,
+
+ PFILE_M_BRRES = PFILE_MODEL
+ | PFILE_MINIMAP
+ | PFILE_VRCORN
+ | PFILE_OTHER_BRRES,
+
+ PFILE_M_TRACK = PFILE_COURSE_KMP // mask for 'TRACK' keyword
+ | PFILE_COURSE_KCL
+ | PFILE_MODEL
+ | PFILE_MINIMAP
+ | PFILE_VRCORN,
+
+ PFILE_M_ALL = PFILE_M_NONE
+ | PFILE_COURSE
+ | PFILE_COURSE_KMP
+ | PFILE_M_KCL
+ | PFILE_M_BRRES
+ | PFILE_F_LOG
+ | PFILE_F_LOG_ALL,
+ // not PFILE_F_HIDE
+
+ PFILE_M_SILENT = PFILE_M_TRACK,
+
+ PFILE_M_DEFAULT = PFILE_M_SILENT
+ | PFILE_F_LOG,
+
+} patch_file_t;
+
+//-----------------------------------------------------------------------------
+
+extern patch_file_t PATCH_FILE_MODE; // = PFILE_M_DEFAULT|PFILE_F_DEFAULT
+extern int disable_patch_on_load; // if >0: disable patching after loading
+
+int ScanOptPatchFile ( ccp arg );
+void SetPatchFileModeReadonly(); // switch to readonly default flags (silent),
+ // if not set by user
+
+uint PrintFileClassInfo ( char *buf, uint bufsize, patch_file_t mode );
+ccp GetFileClassInfo();
+
+patch_file_t GetFileClass
+(
+ file_format_t fform, // not FF_UNKNOWN: check file type
+ ccp fname // NULL or file name to check
+);
+
+bool PatchFileClass
+(
+ file_format_t fform, // not FF_UNKNOWN: check file type
+ ccp fname // NULL or file name to check
+);
+
+extern int patch_action_log_disabled;
+bool PATCH_ACTION_LOG ( ccp action, ccp object, ccp format, ... )
+ __attribute__ ((__format__(__printf__,3,4)));
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// image formats ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[image_format_t]]
+
+typedef enum image_format_t
+{
+ //--- nintendo formats
+
+ IMG_I4 = 0x00,
+ IMG_I8 = 0x01,
+ IMG_IA4 = 0x02,
+ IMG_IA8 = 0x03,
+ IMG_RGB565 = 0x04,
+ IMG_RGB5A3 = 0x05,
+ IMG_RGBA32 = 0x06,
+ IMG_C4 = 0x08,
+ IMG_C8 = 0x09,
+ IMG_C14X2 = 0x0a,
+ IMG_CMPR = 0x0e,
+
+ IMG_N_INTERN, // number intern formats
+
+
+ //--- non nintendo formats
+
+ IMG_X_AUTO = 0x7c00, // auto format (one of below)
+
+ IMG_X_GRAY, // 2 bytes: gray with alpha
+ IMG_X_RGB, // 4 bytes: RGB with alpha
+
+ // palette formats: 2 bytes index into 4 bytes palette
+ IMG_X_PAL4, // 4 bit index (max 16 palette entries)
+ IMG_X_PAL8, // 8 bit index (max 256 palette entries)
+ IMG_X_PAL14, // 14 bit index (max 16386 palette entries)
+ IMG_X_PAL, // one of above
+
+
+ //--- valid X formats as range
+
+ IMG_X__MIN = IMG_X_GRAY,
+ IMG_X__MAX = IMG_X_PAL,
+
+ IMG_X_PAL__MIN = IMG_X_PAL4,
+ IMG_X_PAL__MAX = IMG_X_PAL,
+
+
+ //--- special values
+
+ IMG_INVALID = -1, // no image
+
+} image_format_t;
+
+//-----------------------------------------------------------------------------
+
+extern const KeywordTab_t cmdtab_image_format[];
+int ScanImageFormat ( ccp arg );
+ccp GetImageFormatName ( image_format_t iform, ccp unknown_value );
+
+#define MAX_MIPMAPS 20
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// palette formats ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[palette_format_t]]
+
+typedef enum palette_format_t
+{
+ PAL_IA8 = 0x00,
+ PAL_RGB565 = 0x01,
+ PAL_RGB5A3 = 0x02,
+
+ PAL_X_RGB = 0x7c01,
+
+ PAL_N, // number of formats
+ PAL_AUTO = PAL_N, // auto format
+ PAL_DEFAULT = PAL_RGB5A3, // default value
+ PAL_INVALID = -1, // no image
+
+} palette_format_t;
+
+//-----------------------------------------------------------------------------
+
+extern const KeywordTab_t cmdtab_palette_format[];
+int ScanPaletteFormat ( ccp arg );
+ccp GetPaletteFormatName ( image_format_t iform, ccp unknown_value );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// sort mode ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[SortMode_t]]
+
+typedef enum SortMode_t
+{
+ SORT_NONE, // do not sort
+
+ SORT_INAME, // sort with strcasecmp()
+ SORT_OFFSET, // sort by offset and size
+
+ SORT_U8, // sort like Nintendo sort U8 archives
+ SORT_PACK, // sort like Nintendo sort U8 archives (inexact)
+ SORT_BRRES, // sort like Nintendo sort BRRES archives
+ SORT_BREFF, // sort like Nintendo sort BREFF and BREFT archives
+
+ SORT_AUTO // auto sorting, using 'fform_arch'
+
+} SortMode_t;
+
+//-----------------------------------------------------------------------------
+
+SortMode_t GetSortMode
+(
+ SortMode_t sort_mode, // wanted sort mode
+ file_format_t fform, // use it if 'sort_mode==SORT_AUTO'
+ SortMode_t default_mode // default if all other fails
+);
+
+//-----------------------------------------------------------------------------
+
+ccp GetSortName ( int id, ccp res_not_found );
+int ScanOptSort ( ccp arg );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// slot mode ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum SlotMode_t
+{
+ //--- no flag set
+
+ SLOTMD_NONE = 0,
+
+
+ //--- jobs
+
+ SLOTMD_RM_ICE = 0x0001, // rm ice.brres from SZS and KMP
+ SLOTMD_RM_SUNDS = 0x0002, // rm 'sunDS' and 'pylon01' from SZS and KMP
+ SLOTMD_RM_SHYGUY = 0x0004, // rm 'HeyhoShipGBA'+'HeyhoBallGBA' from SZS and KMP
+
+ SLOTMD_ADD_GICE = 0x0010, // add 'ice' to KMP/GOBJ
+ SLOTMD_ADD_BICE = 0x0020, // add 'ice.brres' to SZS
+ SLOTMD_ADD_SHYGUY = 0x0040, // add 'HeyhoShipGBA' to SZS and KMP
+
+ SLOTMD_ICE_TO_WATER = 0x0100, // change KCL flag 0x70 to 0x30
+ SLOTMD_WATER_TO_ICE = 0x0200, // change KCL flag 0x30 to 0x70
+
+
+ //--- job classes
+
+ SLOTMD_JOB_RM_SZS = SLOTMD_RM_ICE
+ | SLOTMD_RM_SUNDS
+ | SLOTMD_RM_SHYGUY,
+
+ SLOTMD_JOB_ADD_SZS = SLOTMD_ADD_BICE
+ | SLOTMD_ADD_SHYGUY,
+
+ SLOTMD_JOB_KCL = SLOTMD_ICE_TO_WATER
+ | SLOTMD_WATER_TO_ICE,
+
+ SLOTMD_JOB_KMP = SLOTMD_RM_ICE
+ | SLOTMD_RM_SUNDS
+ | SLOTMD_RM_SHYGUY
+ | SLOTMD_ADD_GICE
+ | SLOTMD_ADD_SHYGUY,
+
+
+ //--- mode for --slot
+
+ SLOTMD_M_DAISY = SLOTMD_RM_ICE
+ | SLOTMD_RM_SHYGUY
+ | SLOTMD_ICE_TO_WATER,
+
+ SLOTMD_M_SHERBET = SLOTMD_RM_SUNDS
+ | SLOTMD_RM_SHYGUY
+ | SLOTMD_ADD_GICE
+ | SLOTMD_ADD_BICE
+ | SLOTMD_WATER_TO_ICE,
+
+ SLOTMD_M_SHYGUY = SLOTMD_RM_ICE
+ | SLOTMD_RM_SUNDS
+ | SLOTMD_ADD_SHYGUY
+ | SLOTMD_ICE_TO_WATER,
+
+ SLOTMD_M_STANDARD = SLOTMD_RM_ICE
+ | SLOTMD_RM_SUNDS
+ | SLOTMD_RM_SHYGUY
+ | SLOTMD_ICE_TO_WATER,
+
+ SLOTMD_M_MOST = SLOTMD_RM_SUNDS
+ | SLOTMD_RM_SHYGUY
+ | SLOTMD_ADD_BICE
+ | SLOTMD_ICE_TO_WATER,
+}
+SlotMode_t;
+
+extern SlotMode_t opt_slot;
+int ScanOptSlot ( ccp arg );
+ccp PrintSlotMode ( SlotMode_t mode );
+
+///////////////////////////////////////////////////////////////////////////////
+/////////////// PatchImage_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[PatchImage_t]]
+
+typedef enum PatchImage_t
+{
+ PIM_VCENTER = 0x0000,
+ PIM_TOP = 0x0001,
+ PIM_BOTTOM = 0x0002,
+ PIM_INS_TOP = 0x0003,
+ PIM_INS_BOTTOM = 0x0004,
+ PIM_M_V = 0x0007,
+
+ PIM_HCENTER = 0x0000,
+ PIM_LEFT = 0x0010,
+ PIM_RIGHT = 0x0020,
+ PIM_INS_LEFT = 0x0030,
+ PIM_INS_RIGHT = 0x0040,
+ PIM_M_H = 0x0070,
+ PIM_SHIFT_V_H = 4, // shift value from vertical to horizontal values
+
+ PIM_CENTER = PIM_VCENTER | PIM_HCENTER,
+
+ PIM_MIX = 0x0000,
+ PIM_FOREGROUND = 0x0100,
+ PIM_BACKGROUND = 0x0200,
+ PIM_COPY = 0x0300,
+ PIM_M_COPY = 0x0300,
+
+ PIM_LEAVE = 0x0000,
+ PIM_SHRINK = 0x1000,
+ PIM_GROW = 0x2000,
+ PIM_M_SIZE = 0x3000,
+
+ PIM_MASK = PIM_M_V | PIM_M_H | PIM_M_COPY | PIM_M_SIZE
+
+} PatchImage_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct FormatField_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct FormatFieldItem_t
+{
+ ccp key; // string key of object
+ file_format_t fform; // -1 or file format
+ image_format_t iform; // -1 or image format
+ palette_format_t pform; // -1 or palette format
+ PatchImage_t patch_mode; // 0 or alignment
+ uint num; // free number, printed if >0
+
+} FormatFieldItem_t;
+
+//-----------------------------------------------------------------------------
+
+typedef struct FormatField_t
+{
+ FormatFieldItem_t * list; // pointer to the item list
+ uint used; // number of used elements of 'list'
+ uint size; // number of allocated elements of 'list'
+
+} FormatField_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeFormatField ( FormatField_t * ff );
+void ResetFormatField ( FormatField_t * ff );
+void MoveFormatField ( FormatField_t * dest, FormatField_t * src );
+
+int FindFormatFieldIndex ( const FormatField_t * ff, ccp key, int not_found_value );
+FormatFieldItem_t * FindFormatField ( const FormatField_t * ff, ccp key );
+
+// return first matching element
+FormatFieldItem_t * FindFormatFieldNC ( const FormatField_t * ff, ccp key );
+FormatFieldItem_t * MatchFormatField ( const FormatField_t * ff, ccp key );
+
+bool RemoveFormatField ( FormatField_t * ff, ccp key ); // return: true if item deleted
+
+FormatFieldItem_t * InsertFormatField
+(
+ FormatField_t * ff, // valid attrib field
+ ccp key, // key to insert
+ bool scan_form, // true: scan 'key' for FORM= prefix
+ bool move_key, // true: move string, false: strdup()
+ bool * found // not null: store found status
+);
+
+FormatFieldItem_t * InsertFormatFieldFF
+(
+ FormatField_t * ff, // valid attrib field
+ ccp key, // key to insert
+ file_format_t fform, // file format
+ bool scan_form, // true: scan 'key' for FORM= prefix
+ bool move_key, // true: move string, false: strdup()
+ bool * found // not null: store found status
+);
+
+FormatFieldItem_t * AppendFormatField
+(
+ FormatField_t * ff, // valid attrib field
+ ccp key, // key to insert
+ bool scan_form, // true: scan 'key' for FORM= prefix
+ bool move_key // true: move string, false: strdup()
+);
+
+#if 0 // [[not-needed]] not needed yet 2011-06
+enumError LoadFormatField
+(
+ FormatField_t * ff, // attrib field
+ bool init_ff, // true: initialize 'ff' first
+ bool sort, // true: sort 'ff'
+ ccp filename, // filename of source file
+ bool silent // true: don't print open/read errors
+);
+#endif
+
+enumError SaveFormatField
+(
+ FormatField_t * ff, // valid attrib field
+ ccp filename, // filename of dest file
+ bool rm_if_empty // true: rm dest file if 'ff' is empty
+);
+
+enumError WriteFormatField
+(
+ FILE * f, // open destination file
+ ccp filename, // NULL or filename (needed on write error)
+ FormatField_t * ff, // valid format field
+ ccp line_prefix, // not NULL: insert prefix before each line
+ ccp key_prefix, // not NULL: insert prefix before each key
+ ccp eol, // end of line text (if NULL: use LF)
+ uint hex_fw // if >0: print num as hex with field width
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// tiny support ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[tiny_param_t]]
+
+#define N_TINY_MODES 8
+
+typedef struct tiny_param_t
+{
+ // HINT: Value 0: function is off!
+
+ //--- KCL
+ int kcl_round; // positions: shift value for RoundF()/RoundD()
+ int kcl_mask; // normals: value for MaskF() and normals
+ // also condition for 'kcl_round'
+
+ //--- position calculations, 999==Off
+ int pos_round; // positions: shift value for RoundF()/RoundD()
+ int rot_round; // rotations: shift value for RoundF()/RoundD()
+ int scale_round; // scales: shift value for RoundF()/RoundD()
+
+ int route_round; // route positions: shift value for RoundF()/RoundD()
+ int cannon_round; // cannon direction: shift value for RoundF()/RoundD()
+}
+tiny_param_t;
+
+extern const tiny_param_t TinyParam[N_TINY_MODES];
+
+//-----------------------------------------------------------------------------
+
+int ScanOptTiny ( ccp arg );
+
+static inline float RoundF( float num, int shift )
+ { return ldexpf(roundf(ldexpf(num,shift)),-shift); }
+
+static inline double RoundD( double num, int shift )
+ { return ldexp(round(ldexp(num,shift)),-shift); }
+
+static inline float MaskF( float num, u32 mask )
+ { union { float f; u32 u; } x; x.f = num; x.u &= mask; return x.f; }
+
+static inline float RoundMaskF( float num, int shift, u32 mask )
+{
+ union { float f; u32 u; } x;
+ x.f = ldexpf(roundf(ldexpf(num,shift)),-shift);
+ x.u &= mask;
+ return x.f;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// string lists ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct ParamList_t
+{
+ char * arg;
+ bool is_expanded;
+ int count;
+ struct ParamList_t * next;
+
+} ParamList_t;
+
+extern uint n_param;
+extern ParamList_t * first_param;
+extern ParamList_t ** append_param;
+
+///////////////////////////////////////////////////////////////////////////////
+
+int AtFileHelper ( ccp arg, int (*func)(ccp arg) );
+
+int AddParam ( ccp arg );
+void AtExpandParam ( ParamList_t ** param );
+void AtExpandAllParam ( ParamList_t ** first_param );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// general list support ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[List_t]]
+
+typedef struct List_t
+{
+ u8 *list; // list of data
+ uint used; // used elements of 'list'
+ uint size; // alloced elements of 'list'
+ uint elem_size; // size of 1 element
+
+} List_t;
+
+void InitializeList ( List_t * list, uint elem_size );
+void ResetList ( List_t * list );
+void * InsertList ( List_t * list, int index );
+void * AppendList ( List_t * list );
+void * GrowList ( List_t * list, uint n );
+void * GrowListSize ( List_t * list, uint n, uint add_size );
+void * GetListElem
+ ( const List_t * list, int index, const void * return_not_found );
+
+///////////////////////////////////////////////////////////////////////////////
+// [[MemItem_t]]
+
+#define NAME_IDX_SIZE 10
+
+typedef struct MemItem_t
+{
+ int idx1; // first user index
+ int idx2; // second user index
+ int sort_idx; // a sorting index
+ ccp name; // NULL or pointer to name
+ u8 *data; // NULL or pointer to data
+ uint size; // size of 'data'
+
+ //--- string index support
+
+ u32 str_idx_buf[NAME_IDX_SIZE];
+ // standard buffer for 'str_idx'
+ u32 *str_idx; // NULL or pointer to alloced string index list
+ uint str_idx_size; // number of alloced elements of 'str_idx'
+
+ //--- flags
+
+ bool name_alloced; // true: 'name' is alloced
+ bool data_alloced; // true: 'data' is alloced
+
+} MemItem_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeMIL ( List_t * list );
+void ResetMIL ( List_t * list );
+void SortMIL ( List_t * list, bool use_sort_idx );
+
+MemItem_t * AppendMIL ( List_t * list );
+MemItem_t * GrowMIL ( List_t * list, uint n );
+MemItem_t * GetMemListElem
+ ( const List_t * list, int index, const MemItem_t * return_not_found );
+
+u32 * GetStrIdxMIL ( MemItem_t * mi, uint n_need );
+
+static inline const u32 * GetStrIdxListMIL ( const MemItem_t * mi )
+{
+ DASSERT(mi);
+ return mi->str_idx ? mi->str_idx : mi->str_idx_buf;
+}
+
+static inline uint GetStrIdxCountMIL ( const MemItem_t * mi )
+{
+ DASSERT(mi);
+ return mi->str_idx_size ? mi->str_idx_size
+ : sizeof(mi->str_idx_buf)/sizeof(*mi->str_idx_buf);
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// cygwin support ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __CYGWIN__
+
+ void NormalizeFilenameParam ( ParamList_t *param );
+ #define NORMALIZE_FILENAME_PARAM(p) NormalizeFilenameParam(p)
+
+#else
+
+ #define NORMALIZE_FILENAME_PARAM(p)
+
+#endif // __CYGWIN__
+
+//-----------------------------------------------------------------------------
+
+void SetSource ( ccp source );
+void SetDest ( ccp dest, bool mkdir );
+void CheckOptDest ( ccp default_dest, bool default_mkdir );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// modes and options ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+int ScanOptCompr ( ccp arg );
+int ScanOptTracks ( ccp arg );
+int ScanOptArenas ( ccp arg );
+ccp NormalizeTrackName ( char *buf, uint bufsize, ccp arg );
+
+void DumpTrackList
+(
+ FILE * f, // NULL(=stdout) or file
+ const u32 * tab, // NULL or list with track indices
+ int brief_mode // 0: full table
+ // 1: suppress header
+ // 2: file names only
+);
+
+void DumpArenaList
+(
+ FILE * f, // NULL(=stdout) or file
+ const u32 * tab, // NULL or list with arena indices
+ int brief_mode // 0: full table
+ // 1: suppress header
+ // 2: file names only
+);
+
+void DumpTrackFileList
+(
+ FILE * f, // NULL(=stdout) or file
+ const u32 * track_tab, // NULL or list with track indices
+ const u32 * arena_tab // NULL or list with arena indices
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// scan setup files ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct SetupDef_t
+{
+ ccp name; // name of parameter, NULL=list terminator
+ u32 factor; // alignment factor; 0: text param
+ ccp param; // alloced text param
+ u64 value; // numeric value of param
+
+} SetupDef_t;
+
+//-----------------------------------------------------------------------------
+
+typedef struct ListDef_t
+{
+ ccp name; // section name
+ bool append; // true: append string instead of insert
+ StringField_t *sf; // valid pointer to string field
+
+} ListDef_t;
+
+//-----------------------------------------------------------------------------
+
+size_t ResetSetup
+(
+ SetupDef_t * list // object list terminated with an element 'name=NULL'
+);
+
+enumError ScanSetupFile
+(
+ SetupDef_t * sdef, // object list terminated with an element 'name=NULL'
+ ListDef_t * ldef, // NULL or object list terminated
+ // with an element 'name=NULL'
+ ccp path1, // filename of text file, part 1
+ ccp path2, // filename of text file, part 2
+ SubDir_t * sdir, // not NULL: use it and ignore 'path1'
+ bool silent // true: suppress error message if file not found
+);
+
+///////////////////////////////////////////////////////////////////////////////
+// [[SetupParam_t]]
+
+typedef struct SetupParam_t
+{
+ ccp object_name; // name of object, alloced
+ u32 object_id; // id of object
+ bool object_id_used; // 'object_id' set and valid
+ file_format_t fform_file; // file format
+ file_format_t fform_arch; // archive format
+ int version; // a version number
+ int compr_mode; // -1:no compr, 0:auto, 1:compr
+ int have_pt_dir; // -1:no, 0:unknown, 1:yes
+ u32 min_data_off; // minimum found data offset
+ u32 max_data_off; // maximum found data offset
+ u32 data_align; // data alignment
+
+ StringField_t include_pattern;// include usually hidden files, pattern list
+ StringField_t include_name; // include usually hidden files, name list
+ StringField_t exclude_pattern;// exclude files, pattern list
+ StringField_t exclude_name; // exclude files, name list
+ FormatField_t encode_list; // encode before including
+ StringField_t create_list; // create sub file before including
+ FormatField_t order_list; // use this list as sorting reference
+
+} SetupParam_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeSetupParam ( SetupParam_t * sp );
+void ResetSetupParam ( SetupParam_t * sp );
+
+//-----------------------------------------------------------------------------
+
+enumError ScanSetupParam
+(
+ SetupParam_t * sp, // setup param to scan
+ bool use_options, // true: use options to override values
+ ccp path1, // NULL or part #1 of path
+ ccp path2, // NULL or part #2 of path
+ SubDir_t * sdir, // not NULL: use it and ignore 'path1'
+ bool silent // true: suppress printing of error messages
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// export keys ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum export_mode_t
+{
+ EXPORT_NONE,
+ EXPORT_C,
+ EXPORT_PHP,
+ EXPORT_MAKEDOC,
+ EXPORT_CMD_MASK = 0x00f,
+
+ EXPORT_F_FUNCTIONS = 0x100,
+ EXPORT_F_FILEATTRIB = 0x200,
+ EXPORT_F_TRACKS = 0x400,
+ EXPORT_FLAG_MASK = 0x700
+
+} export_mode_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+export_mode_t ScanExportMode(); // scan parameters
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// SZS file list ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum FileList_t
+{
+ FLT_STD = 0x01, // non '_d' files
+ FLT_D = 0x02, // '_d' files
+
+ FLT_TRACK = 0x10, // 32 track files
+ FLT_ARENA = 0x20, // 10 arena files
+ FLT_OTHER = 0x40, // 5 other files
+ FLT_OLD = 0x80, // 4 old files (old BRSUB formats)
+
+ FLT_M_CLASS = FLT_STD | FLT_D,
+ FLT_M_TYPE = FLT_TRACK | FLT_ARENA | FLT_OTHER | FLT_OLD,
+ FLT_M_ALL = FLT_M_CLASS | FLT_M_TYPE,
+
+} FileList_t;
+
+//-----------------------------------------------------------------------------
+
+typedef struct TrackInfo_t TrackInfo_t;
+
+typedef int (*IterateTrackFilesFunc)
+(
+ ccp fname, // name of current file without '.szs' extension
+ ccp id, // unique ID of current file
+ FileList_t mode, // mode of current file
+ const TrackInfo_t *ti, // NULL or related track info
+ void *param // user defined parameter
+);
+
+//-----------------------------------------------------------------------------
+
+int IterateTrackFiles
+(
+ FileList_t mode, // bit field with requested files
+ IterateTrackFilesFunc
+ func, // call back function
+ void *param // user defined parameter
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// file type validation ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[valid_t]]
+
+typedef enum valid_t
+{
+ VALID_OK, // validation success
+ VALID_NO_TEST, // no validation test available
+ VALID_WARNING, // warnings, repairable
+ VALID_ERROR, // error in data structures
+ VALID_WRONG_FF, // wrong file type
+ VALID_UNKNOWN_FF, // unknown file type
+
+ VALID__N // number of status modes
+
+} valid_t;
+
+extern ccp valid_text[VALID__N];
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct szs_file_t;
+
+valid_t IsValidSZS
+(
+ struct szs_file_t *szs, // valid szs archive
+ bool warnings // true: print warnings
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+valid_t IsValid
+(
+ const void *data, // valid data to test
+ uint data_size, // size of 'data'
+ uint file_size, // not NULL: size of complete file
+ struct szs_file_t *szs, // not NULL: base archive
+ file_format_t fform, // known file format
+ // if FF_UNKNOWN: call GetByMagicFF()
+ ccp fname // not NULL: print warnings with file ref
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+valid_t IsValidBRSUB
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ struct szs_file_t *szs, // not NULL: base archive
+ file_format_t fform, // known file format
+ // if FF_UNKNOWN: call GetByMagicFF()
+ bool check_fform, // true: confirm 'fform' by calling GetByMagicFF()
+ ccp fname, // not NULL: print warnings with file ref
+ const endian_func_t *endian // not NULL: use this endian functions
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+valid_t IsValidBTI
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+struct kcl_analyze_t;
+
+valid_t IsValidKCL
+(
+ struct
+ kcl_analyze_t * ka, // not NULL: init and store stats
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidKMP
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidLEX
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidMDL
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ struct szs_file_t *szs, // not NULL: base archive
+ ccp fname, // not NULL: print warnings with file ref
+ const endian_func_t *endian // not NULL: use this endian functions
+);
+
+//-----------------------------------------------------------------------------
+
+struct pat_analyse_t;
+
+valid_t IsValidPAT
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ struct szs_file_t *szs, // not NULL: base archive
+ ccp fname, // not NULL: print warnings with file ref
+ const endian_func_t *endian, // not NULL: use this endian functions
+ struct pat_analyse_t *ana // not NULL: store analysis data here
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidSTATICR
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidTEXCT
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ struct szs_file_t *szs, // not NULL: base archive
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//-----------------------------------------------------------------------------
+
+valid_t IsValidCTCODE
+(
+ const void * data, // data
+ uint data_size, // size of 'data'
+ uint file_size, // NULL or size of complete file
+ ccp fname // not NULL: print warnings with file ref
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// PrintScript ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[PrintScript_t]]
+
+typedef struct PrintScript_t
+{
+ File_t *fo; // pointer output file
+ bool add_index; // true: add index to varname
+ uint index; // index for array operations
+ char sep[2]; // separator for JSON
+ char prefix[100]; // varname prefix
+}
+PrintScript_t;
+
+static inline void InitializePrintScript ( PrintScript_t *ps )
+ { DASSERT(ps); memset(ps,0,sizeof(*ps)); }
+
+static inline void ResetPrintScript ( PrintScript_t *ps )
+ { DASSERT(ps); memset(ps,0,sizeof(*ps)); }
+
+///////////////////////////////////////////////////////////////////////////////
+
+void PrintScriptHeader ( PrintScript_t *ps );
+void PrintScriptFooter ( PrintScript_t *ps );
+
+int PutScriptVars
+(
+ PrintScript_t *ps, // valid control struct
+ uint mode, // bit field: 1=open var, 2:close var
+ ccp text // text with line of format NAME=VALUE
+);
+
+int PrintScriptVars
+(
+ PrintScript_t *ps, // valid control struct
+ uint mode, // bit field: 1=open var, 2:close var
+ ccp format, // format of message
+ ... // arguments
+)
+__attribute__ ((__format__(__printf__,3,4)));
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// misc ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[IsArena_t]]
+
+typedef enum IsArena_t
+{
+ ARENA_NONE = 0, // no arena found
+ ARENA_MAYBE, // maybe an arena (some hints detected)
+ ARENA_FOUND, // arena detected
+ ARENA_DISPATCH, // arena detected with ENPT dispatch points
+ ARENA__N
+}
+IsArena_t;
+
+extern const char is_arena_name[ARENA__N][9];
+
+///////////////////////////////////////////////////////////////////////////////
+// [[data_tab_t]]
+
+typedef struct data_tab_t
+{
+ ccp name; // name of data
+ uint mode; // bit filed:
+ // 1: source is bzip'ed
+ // 2: base data is bzip'ed
+
+ const void *data; // valid pointer to data
+ uint size; // size of 'data'
+
+ const u32 *patch; // not NULL: use this patch to get real data
+}
+data_tab_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+enumError cmd_argtest ( int argc, char ** argv );
+enumError cmd_error();
+enumError cmd_filetype();
+enumError cmd_fileattrib();
+enumError cmd_float();
+enumError cmd_vr_calc();
+enumError cmd_vr_race();
+enumError cmd_rawdump ( const data_tab_t *data_tab );
+
+void ExportFileAttribMakedoc ( FILE * f );
+
+extern uint opt_analyze_mode;
+int ScanOptAnalyzeMode ( ccp arg );
+
+struct szs_file_t;
+void AnalyzeBRSUB ( struct szs_file_t * szs, u8 * data, uint data_size, ccp name );
+void AnalyzeBREFF ( struct szs_file_t * szs, u8 * data, uint data_size, ccp name );
+void AnalyzeTPL ( struct szs_file_t * szs, u8 * data, uint data_size, ccp name );
+
+struct kmp_t;
+void AnalyzeKMP ( const struct kmp_t * kmp, ccp base_fname );
+
+struct kcl_t;
+void AnalyzeKCL ( const struct kcl_t * kcl );
+
+void SHA1_to_ID ( sha1_id_t id, const sha1_hash_t hash );
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool IsExtractEnabled(); // return true if enabled and mkdir() successful
+
+bool PrepareExtract
+(
+ // return FALSE on disabled or failure, otherwise return TRUE
+
+ File_t *f, // file structure, will be initialized
+ int mode, // convert filename: <0=to lower, >0=to upper
+ ccp format, // format of filename
+ ... // arguments
+)
+__attribute__ ((__format__(__printf__,3,4)));
+
+///////////////////////////////////////////////////////////////////////////////
+// [[CheckMode_t]]
+
+typedef enum CheckMode_t
+{
+ CMOD_HEADER = 0x01, // print header line before first message
+ CMOD_FOOTER = 0x02, // print footer line (summary) behind last message
+ CMOD_FORCE_HEADER = 0x04, // print header line always
+ CMOD_FORCE_FOOTER = 0x08, // print footer line always
+
+ CMOD_SILENT = 0, // print nothing
+ CMOD_WARNING = 0x10, // print warnings
+ CMOD_HINT = 0x20, // print hints
+ CMOD_SLOT = 0x40, // print slot infos
+ CMOD_INFO = 0x80, // simple info or statistic
+ CMOD_VERBOSE = 0x100, // be verbose
+ CMOD_LECODE = 0x200, // only relevant for LE-CODE
+
+ CMOD_GLOBAL_STAT = 0x100, // store global statistics
+
+ CMOD_PRINT = CMOD_WARNING | CMOD_HINT | CMOD_SLOT,
+ CMOD_DEFAULT = CMOD_HEADER | CMOD_FOOTER | CMOD_PRINT,
+ CMOD_FORCE = CMOD_FORCE_HEADER | CMOD_FORCE_FOOTER,
+
+} CheckMode_t;
+
+//-----------------------------------------------------------------------------
+
+CheckMode_t GetCheckMode
+(
+ bool no_head, // true: suppress header
+ bool no_hints, // true: suppress hints
+ bool quiet, // true: be quiet if no hint|warning is printed
+ bool verbose // true: print some more hints
+);
+
+CheckMode_t GetMainCheckMode ( CheckMode_t mode, bool reset_counter );
+CheckMode_t GetSubCheckMode ( CheckMode_t mode, bool reset_counter );
+
+extern const char check_bowl[]; // begin of 'warning' line, for checks
+extern const char check_bohl[]; // begin of 'hint' line, for checks
+extern const char check_bosl[]; // begin of 'slot' line, for checks
+extern const char check_boil[]; // begin of 'info' line, for checks
+extern const char check_bosugl[]; // begin of 'suggestion' line, for checks
+
+extern int global_warn_count;
+extern int global_hint_count;
+extern int global_info_count;
+
+extern const ColorSet_t *colset;
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern char *TableDecode64BySetup;
+extern const char *TableEncode64BySetup;
+
+int ScanOptCoding64 ( ccp arg );
+EncodeMode_t SetupCoding64 ( EncodeMode_t mode, EncodeMode_t fallback );
+
+///////////////////////////////////////////////////////////////////////////////
+
+uint GetMkwMusicSlot ( uint tid );
+
+//-----------------------------------------------------------------------------
+
+static inline ccp PrintU8M1 ( u8 num )
+{
+ return num == M1(num) ? "-1" : PrintCircBuf("%u",num);
+}
+
+static inline ccp PrintU16M1 ( u16 num )
+{
+ return num == M1(num) ? "-1" : PrintCircBuf("%u",num);
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// output_mode_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[output_mode_t]]
+
+typedef struct output_mode_t
+{
+ bool syntax; // true: print syntax infos
+ u8 mode; // 1:list, 2:ref, 3:full
+ bool cross_ref; // true: print cross reference infos
+ bool hex; // force hex out
+}
+output_mode_t;
+
+extern output_mode_t output_mode;
+void InitializeOutputMode ( output_mode_t * outmode );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// apple only ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __APPLE__
+
+ void * memmem ( const void *l, size_t l_len, const void *s, size_t s_len );
+
+#endif // __APPLE__
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// tables ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+extern const u8 CannonDataLEX[4+3*16];
+extern const u8 TestDataLEX[8*1];
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// vars ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+extern ccp tool_name;
+extern ccp progname;
+extern ccp share_path;
+extern ccp search_path[];
+extern ccp auto_add_path[6];
+extern volatile int SIGINT_level;
+extern volatile int verbose;
+extern volatile int logging;
+extern bool allow_all;
+extern char escape_char;
+extern bool use_utf8;
+extern bool use_de;
+extern bool ctcode_enabled;
+extern bool lecode_enabled;
+extern uint opt_ct_mode; // calculated by ctcode_enabled & lecode_enabled
+extern int testmode;
+extern int force_count;
+extern uint opt_tiny;
+extern bool force_kmp;
+extern OffOn_t opt_battle_mode;
+extern OffOn_t opt_export_flags;
+extern int opt_route_options;
+extern OffOn_t opt_wim0;
+extern ccp opt_source;
+extern StringField_t source_list;
+extern ccp opt_dest;
+extern bool opt_mkdir;
+extern bool opt_overwrite;
+extern bool opt_number;
+extern bool opt_remove_src;
+extern bool opt_remove_dest;
+extern bool opt_update;
+extern bool opt_preserve;
+extern ccp opt_extract;
+extern int opt_ignore;
+extern bool opt_ignore_setup;
+extern bool opt_purge;
+extern file_format_t opt_fform;
+extern file_format_t fform_compr;
+extern file_format_t fform_compr_force;
+extern file_format_t script_fform;
+extern ccp script_varname;
+extern int script_array;
+extern int opt_pt_dir;
+extern bool opt_links;
+extern bool opt_rm_aiparam;
+extern u32 opt_align;
+extern u32 opt_align_u8;
+extern u32 opt_align_pack;
+extern u32 opt_align_brres;
+extern u32 opt_align_breff;
+extern u32 opt_align_breft;
+extern bool print_header;
+extern bool print_param;
+extern int print_sections;
+extern double opt_tri_area;
+extern double opt_tri_height;
+extern bool opt_kmp_flags;
+extern bool opt_id;
+extern bool opt_base64;
+extern bool opt_db64;
+extern EncodeMode_t opt_coding64;
+extern bool opt_verify;
+extern ccp opt_cache;
+extern ccp opt_cname;
+extern bool opt_round;
+extern int brief_count;
+extern int long_count;
+//extern int full_count;
+extern int pipe_count;
+extern int delta_count;
+extern int diff_count;
+extern int minimize_level;
+extern int export_count;
+extern int all_count;
+extern bool raw_mode;
+extern SortMode_t opt_sort;
+extern u32 opt_max_file_size;
+extern int opt_compr_mode;
+extern u32 opt_compr;
+extern bool opt_norm;
+extern int need_norm; // enabled if > 0
+extern bool opt_fast;
+extern char *opt_basedir;
+extern int opt_recurse;
+extern int opt_ext;
+extern bool opt_decode;
+extern bool opt_cut;
+extern bool opt_cmpr_valid;
+extern u8 opt_cmpr_def[8];
+extern uint opt_n_images;
+extern uint opt_max_images;
+extern uint opt_min_mipmap_size; // minimal mipmap size
+extern int opt_mipmaps;
+extern bool opt_strip;
+extern bool opt_pre_convert;
+extern bool opt_encode_all;
+extern bool opt_encode_img;
+extern bool opt_no_encode;
+extern bool opt_no_recurse;
+extern bool opt_auto_add;
+extern bool opt_no_echo;
+extern bool opt_generic;
+extern bool opt_raw;
+extern bool opt_tracks;
+extern bool opt_arenas;
+extern bool opt_order_all;
+extern ccp opt_order_by;
+extern ccp opt_write_tracks;
+extern bool opt_no_check;
+extern CheckMode_t global_check_mode;
+extern ccp opt_flag_file;
+extern int opt_xtridata;
+extern int have_patch_count; // <=0: disable patching at all
+extern ParamField_t patch_bmg_list;
+extern FormatField_t patch_image_list;
+extern StringField_t ct_dir_list;
+
+extern double epsilon_pos; // 'p' Position
+extern double epsilon_rot; // 'r' Rotation
+extern double epsilon_scale; // 's' Scale
+extern double epsilon_time; // 't' Time
+
+extern ccp analyze_fname;
+extern FILE * analyze_file;
+
+extern char iobuf [0x400000]; // global io buffer
+//extern const char zerobuf[0x100]; // global zero buffer
+
+extern const char indent_msg[]; // N * "> " + NULL
+extern const char section_sep[];
+extern const char section_end[];
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// END ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#endif // SZS_LIB_STD_H