aboutsummaryrefslogtreecommitdiff
path: root/project/src/lib-ledis.h
diff options
context:
space:
mode:
authorWiimm <wiimm@wiimm.de>2022-07-09 11:48:24 +0200
committerWiimm <wiimm@wiimm.de>2022-07-09 11:48:24 +0200
commit06ff18cd020779c226f7c25d22016e06b898f303 (patch)
treeb5c12ca4c6b9b0c86e63d2b6a965b8bd74dd0d86 /project/src/lib-ledis.h
parentf30e94a61fdc9fb13fd1fbd8b75502fedf5a2f71 (diff)
SZS v2.28a.beta
Diffstat (limited to 'project/src/lib-ledis.h')
-rw-r--r--project/src/lib-ledis.h1059
1 files changed, 1059 insertions, 0 deletions
diff --git a/project/src/lib-ledis.h b/project/src/lib-ledis.h
new file mode 100644
index 0000000..b39d629
--- /dev/null
+++ b/project/src/lib-ledis.h
@@ -0,0 +1,1059 @@
+
+/***************************************************************************
+ * _______ _______ _______ *
+ * | ___ |____ | ___ | *
+ * | | |_| / /| | |_| *
+ * | |_____ / / | |_____ *
+ * |_____ | / / |_____ | *
+ * _ | | / / _ | | *
+ * | |___| |/ /____| |___| | *
+ * |_______|_______|_______| *
+ * *
+ * 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-2022 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_LEDIS_H
+#define SZS_LIB_LEDIS_H 1
+
+#include "lib-std.h"
+#include "lib-mkw.h"
+#include "lib-ctcode.h"
+#include "lib-lecode.h"
+
+#include "dclib-parser.h"
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// support options ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// If 1, then enable the string list 'le_track_t::str_list' with some
+// predifined string types.
+
+#define LE_STRING_LIST_ENABLED 1
+
+//-----------------------------------------------------------------------------
+
+// If 1, then enable the string set 'le_track_t::str_set'. It supports any
+// number of strings that can be accessed by '[name]'.
+
+#define LE_STRING_SET_ENABLED 1
+
+//-----------------------------------------------------------------------------
+
+// LE-DEF can set track-type markers in vars to remember the track type.
+// So [CUP-LIST] can be defined before [TRACK-LIST]. Anyway, because [TRACK-LIST]
+// is scanned in pass-1 and [CUP-LIST] in pass-2 this can be always set to 0.
+
+#define LE_TYPE_MARKERS_ENABLED 0
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// definitions ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#define LE_DEFINE_MAGIC8 "#LE-DEF1"
+#define LE_DEFINE_MAGIC8_NUM 0x234c452d44454631ull
+
+#define LE_DISTRIB_MAGIC8 "#LE-DIST"
+#define LE_DISTRIB_MAGIC8_NUM 0x234c452d44495354ull
+
+#define LE_REFERENCE_MAGIC8 "#LE-REF1"
+#define LE_REFERENCE_MAGIC8_NUM 0x234c452d52454631ull
+
+#define LE_STRINGS_MAGIC8 "#LE-STR1"
+#define LE_STRINGS_MAGIC8_NUM 0x234c452d53545231ull
+
+#define LE_SHA1REF_MAGIC8 "#SHA1REF"
+#define LE_SHA1REF_MAGIC8_NUM 0x2353484131524546ull
+
+#define LE_PREFIX_MAGIC8 "#PREFIX1"
+#define LE_PREFIX_MAGIC8_NUM 0x2350524546495831ull
+
+#define LE_MAX_TRACKS (MKW_MAX_TRACK_SLOT+1)
+#define LE_TRACK_STRING_MAX 500
+
+//-----------------------------------------------------------------------------
+
+typedef u16 le_group_t;
+
+typedef struct le_track_t le_track_t;
+typedef struct le_distrib_t le_distrib_t;
+typedef struct raw_data_t raw_data_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// global vars ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+extern ccp opt_create_dump; // NULL of filename
+extern le_distrib_t ledis_dump; // data collector for 'opt_create_dump'
+extern int ledis_dump_enabled; // -1:done, 0:disabled, 1:enabled
+
+extern ccp opt_le_define; // NULL or last defined filename
+extern StringField_t le_define_list; // list with all filenames
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// enum le_track_type_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_type_t]]
+
+typedef enum le_track_type_t
+{
+ LTTY_NONE = 0x00,
+ LTTY_ARENA = 0x01, // true: is a battle arena
+ LTTY_TRACK = 0x02, // true: is a versus track
+ LTTY_RANDOM = 0x04, // true: is a LE-CODE random slot
+ LTTY__NEXT = 0x08, // next free bit
+}
+__attribute__ ((packed)) le_track_type_t;
+
+//-----------------------------------------------------------------------------
+
+static inline bool IsArenaLTTY ( le_track_type_t track_type )
+ { return ( track_type & LTTY_ARENA ) > 0; }
+
+static inline bool IsTrackLTTY ( le_track_type_t track_type )
+ { return ( track_type & LTTY_TRACK ) > 0; }
+
+static inline bool IsRandomLTTY ( le_track_type_t track_type )
+ { return ( track_type & LTTY_RANDOM ) > 0; }
+
+ccp GetNameLTTY ( le_track_type_t track_type );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// enum le_track_status_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_status_t]]
+
+typedef enum le_track_status_t
+{
+ LTS_INVALID = 0, // record not initalized
+ LTS_VALID, // record initalized, but inactive
+ LTS_FAIL, // record initalized and inactive with any invalid settings
+ LTS_ACTIVE, // record initalized and active
+ LTS_FILL, // record initalized and active and used as fill-track
+ LTS_EXPORT, // record initalized and active and can be exported
+ LTS__N
+}
+__attribute__ ((packed)) le_track_status_t;
+
+ccp GetNameLTS ( le_track_status_t lts );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// enum le_track_text_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_text_t]]
+
+typedef enum le_track_text_t
+{
+ LTT_UNDEFINED = 0, // always NULL to support GetTextLEO()
+ LTT_SHA1, // access SHA1 checksum (standard)
+ LTT_SHA1_D, // access SHA1 checksum (_d file)
+ LTT_IDENT, // access identification (standard)
+ LTT_IDENT_D, // access identification (_d file)
+ LTT_FILE, // access file name
+ LTT_NAME, // access name
+ LTT_XNAME, // access xname
+ LTT_XNAME2, // access xname with fallback to name
+
+ #if LE_STRING_LIST_ENABLED
+ // part of string-list, accesses by 'str_list[index-LTT__LIST_BEG]'
+ LTT_TEMP1, // temporary string
+ LTT_TEMP2, // temporary string
+ #endif
+
+ #if LE_STRING_SET_ENABLED
+ LTT_STRSET, // access str_set[name]
+ #endif
+
+ LTT__N, // number of modes
+ LTT__DEFAULT = LTT_NAME,
+
+ #if LE_STRING_LIST_ENABLED
+ // pool range
+ LTT__LIST_BEG = LTT_TEMP1,
+ LTT__LIST_END = LTT_TEMP2+1,
+ LTT__LIST_SIZE = LTT__LIST_END - LTT__LIST_BEG,
+ #endif
+}
+le_track_text_t;
+
+//-----------------------------------------------------------------------------
+
+ccp GetUpperNameLTT ( le_track_text_t ltt ); // 'ltt' is masked by LEO_LTT_SELECTOR
+ccp GetLowerNameLTT ( le_track_text_t ltt ); // 'ltt' is masked by LEO_LTT_SELECTOR
+
+// returns 0:unknown ltt, 1:std string, 2:_d string, 3:both
+int GetDModeLTT ( le_track_text_t ltt );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// enum le_options_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_options_t]]
+
+typedef enum le_options_t
+{
+ //-- text selector
+
+ LEO_LTT_SELECTOR = 0x000000f, // mask to store le_track_text_t selector
+
+
+ //-- BMG input source selector. If none is set then use all
+
+ LEO_MKW1 = 0x0000010, // import track names from MKW set 1 (0x2454../0x24b8..)
+ LEO_MKW2 = 0x0000020, // import track names from MKW set 2 (0x2490../0x24cc..)
+ LEO_CTCODE = 0x0000040, // import track names from CT-CODE (0x4000..)
+ LEO_LECODE = 0x0000080, // import track names from LE-CODE (0x7000..)
+ LEO_MKW = LEO_MKW1 | LEO_MKW2,
+ LEO_M_BMG = LEO_MKW | LEO_CTCODE | LEO_LECODE,
+
+
+ //-- BMG input options
+
+ LEO_IN_EMPTY = 0x0000100, // accept empty strings as valid
+ LEO_IN_MINUS = 0x0000200, // accept minus strings as valid
+ LEO_IN_ALL = LEO_IN_EMPTY | LEO_IN_MINUS,
+
+
+ //-- BMG operator
+
+ LEO_INSERT = 0x0000400, // insert only new strings into the source.
+ LEO_REPLACE = 0x0000800, // replace only strings that are already defined.
+ LEO_OVERWRITE = 0x0000c00, // insert all valid strings
+ LEO_M_HOW = 0x0000c00,
+
+
+ //-- Output filter pairs. Only valid if exact 1 bit is set
+
+ LEO_VERSUS = 0x0001000, // use racing tracks only (!lt->arena)
+ LEO_BATTLE = 0x0002000, // use battle arenas only (lt->arena)
+ LEO_M_ARENA = LEO_VERSUS | LEO_BATTLE,
+
+ LEO_CUSTOM = 0x0004000, // use custom tracks only (!lt->original)
+ LEO_ORIGINAL = 0x0008000, // use original tracks only (lt->original)
+ LEO_M_ORIGINAL = LEO_CUSTOM | LEO_ORIGINAL,
+
+ LEO_NO_D_FILES = 0x0010000, // suppred info about _d files
+
+ LEO_M_OUTPUT = LEO_M_ARENA | LEO_M_ORIGINAL | LEO_NO_D_FILES,
+
+
+ //-- Output filter flags
+
+ LEO_OUT_EMPTY = 0x0020000, // accept empty strings as valid
+ LEO_OUT_MINUS = 0x0040000, // accept minus strings as valid
+ LEO_OUT_ALL = LEO_OUT_EMPTY | LEO_OUT_MINUS,
+
+
+ //-- more options
+
+ LEO_IN_LECODE = 0x0100000, // import lecode binary
+ LEO_BRIEF = 0x0200000, // suppress descriptions
+
+
+ //-- special signals
+
+ LEO_HELP = 0x1000000, // print help and exit
+
+ LEO_CUT_STD = 0x2000000, // cut for standard distribution.
+ LEO_CUT_CTCODE = 0x4000000, // cut for CT-CODE distribution.
+ LEO_M_CUT = LEO_CUT_STD | LEO_CUT_CTCODE,
+
+
+ //-- misc
+
+ LEO__ALL = 0x7ffffff,
+ LEO__DEFAULT = LTT__DEFAULT | LEO_OVERWRITE,
+ LEO__SRC = LEO_LTT_SELECTOR | LEO_IN_ALL,
+ LEO__DEST = LEO_LTT_SELECTOR | LEO_OUT_ALL | LEO_M_OUTPUT | LEO_M_HOW,
+}
+le_options_t;
+
+//-----------------------------------------------------------------------------
+
+extern le_options_t defaultLEO;
+le_options_t SetupDefaultLEO(void);
+
+le_options_t ScanLEO ( le_options_t current, ccp arg, ccp err_info );
+
+bool IsInputNameValidLEO ( ccp name, le_options_t opt ); // LEO_IN_EMPTY|LEO_IN_MINUS
+bool IsOutputNameValidLEO ( ccp name, le_options_t opt ); // LEO_OUT_EMPTY|LEO_OUT_MINUS
+
+// Options: LEO_M_HOW, LEO_IN_*, LEO_OUT_*
+bool IsAssignmentAllowedLEO ( ccp cur_name, ccp new_name, le_options_t opt );
+
+ccp GetTextLEO ( le_options_t opt );
+ccp GetInputFilterLEO ( le_options_t opt );
+ccp GetOutputFilterLEO ( le_options_t opt );
+
+// Options: LEO_IN_*, LEO_M_BMG
+bool GetBmgBySlotLEO
+ ( char *buf, uint bufsize, const bmg_t *bmg, int slot, le_options_t opt );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_strpar_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_strpar_t]]
+
+typedef struct le_strpar_t
+{
+ le_options_t opt; // string selector and options
+
+ bool use_d; // true: use _d variant if available
+ bool allow_d; // true: allow _d pointers
+ bool use_sha1; // true: get use_sha1 as fallback for ident
+ bool csum_only; // true: set sha1 only, but not an ident string.
+
+ #if LE_STRING_SET_ENABLED
+ ccp key; // NULL or key for LTT_STRSET, alloced, lower case
+ #endif
+}
+le_strpar_t;
+
+//-----------------------------------------------------------------------------
+
+extern const le_strpar_t NullLSP, DefaultLSP;
+
+static inline void InitializeLSP ( le_strpar_t *par, le_options_t opt )
+ { DASSERT(par); memset(par,0,sizeof(*par)); par->opt = opt; }
+void ResetLSP ( le_strpar_t *par );
+
+static inline void SetOptionsLSP ( le_strpar_t *par, le_options_t opt )
+ { if (par) par->opt = opt; }
+
+char * ScanLSP ( le_strpar_t *par, ccp arg, enumError *ret_err );
+ccp GetNameLSP ( const le_strpar_t *par );
+ccp GetOptionsLSP ( const le_strpar_t *par, le_options_t mask );
+enumError ScanOptionsLSP ( le_strpar_t *par, ccp arg, ccp err_info );
+
+//-----------------------------------------------------------------------------
+
+#if LE_STRING_SET_ENABLED
+
+ // key can be 'par->key' => don't change it
+ // if key_len < 0: use strlen(key)
+ void SetKeyNameLSP ( le_strpar_t *par, ccp key, int key_len );
+
+ static inline bool IsValidSetLSP ( const le_strpar_t *par )
+ { return par && ( par->opt & LEO_LTT_SELECTOR ) == LTT_STRSET && par->key; }
+
+#endif
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_cup_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_cup_ref_t]] [[le_cup_t]]
+
+typedef s16 le_cup_ref_t;
+
+typedef struct le_cup_t
+{
+ le_cup_ref_t *list; // list with tracks => list[size][tracks]
+ uint used; // used cups of 'list'
+ uint size; // alloced cups of 'list'
+ uint max; // max pssible cups of 'list'
+ uint tracks; // number of tracks of each cup
+
+ uint cur_cup; // current cup
+ uint cur_index; // current index
+
+ int fill_slot; // -1 or fill slot
+ int fill_src; // -1 or source of fill slot
+
+ bool dirty; // true: call UpdateCupsLD() to recalc cup-track relations
+ bool close_used; // true: CloseLECUP() (command NEW-CUP) used
+}
+le_cup_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+void InitializeLECUP ( le_cup_t *lc, uint max_cups, uint tracks_per_cup );
+void ResetLECUP ( le_cup_t *lc );
+
+le_cup_ref_t * GetLECUP ( const le_cup_t *lc, uint cup_index );
+le_cup_ref_t * DefineLECUP ( le_cup_t *lc, uint cup_index );
+
+// return 0 or cup slot like 21
+uint GetCupSlotLECUP ( const le_cup_t *lc, const le_cup_ref_t *ptr );
+
+void AppendLECUP ( le_cup_t *lc, le_cup_ref_t ref );
+void CloseLECUP ( le_cup_t *lc );
+void PackLECUP ( le_cup_t *lc );
+void EvenLECUP ( le_cup_t *lc );
+void FillLECUP ( le_cup_t *lc, le_cup_ref_t fallback );
+bool HaveInvalidLECUP ( le_cup_t *lc );
+
+static inline le_track_type_t GetLttyLECUP ( const le_cup_t *lc )
+ { return lc && lc->tracks == 5 ? LTTY_ARENA : LTTY_TRACK; }
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_track_id_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_id_t]]
+
+typedef struct le_track_id_t
+{
+ // keep it small!
+
+ bool have_sha1; // true: 'sha1bin' is valid
+ bool orig_sha1; // true: 'sha1bin' is original (or normed)
+ sha1_hash_t sha1bin; // sha1 of track, created from ident
+ ccp ident; // NULL or identfication, fallback 'sha1bin'
+}
+le_track_id_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_track_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_t]]
+
+typedef struct le_track_t
+{
+ // keep it small!
+
+ u16 track_slot; // index of le_distrib_t, 0..MKW_MAX_TRACK_SLOT
+ u16 cup_slot; // 0 or 'cup * 10 + tidx'
+
+ le_track_status_t track_status; // LTS_INVALID | LTS_VALID | LTS_ACTIVE | LTS_EXPORT
+ le_track_type_t track_type; // LTTY_NONE | LTTY_ARENA | LTTY_TRACK | LTTY_RANDOM
+ u8 is_original; // 0:is custom, 1:is original
+ u8 user_flags; // free usable flags
+
+ le_property_t property; // property
+ le_music_t music; // music slot
+ le_flags_t flags; // flags
+
+ le_track_id_t lti[2]; // index 0: normal, index 1:_d
+ ccp file; // NULL or filename of track
+ ccp name; // NULL or name of track
+ ccp xname; // NULL or extended name of track, fallback 'name'
+
+ #if LE_STRING_LIST_ENABLED
+ ccp str_list[LTT__LIST_SIZE];
+ // list of strings
+ #endif
+
+ #if LE_STRING_SET_ENABLED
+ ParamField_t str_set; // set of strings, accessed by '[name]'
+ #endif
+}
+le_track_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeLT ( le_track_t *lt );
+void ClearStringsLT ( le_track_t *lt );
+
+void ClearLT ( le_track_t *lt, le_track_type_t ltty ); // auto-ltty if 0
+void MoveLT ( le_track_t *dest, le_track_t *src );
+static inline void ResetLT ( le_track_t *lt ) { ClearLT(lt,0); }
+
+void SetupStandardArenaLT ( le_track_t *lt, uint setup_slot ); // slots 0..9 || 32..41
+void SetupStandardTrackLT ( le_track_t *lt, uint setup_slot ); // slots 0..31
+void SetupByTrackInfoLT ( le_track_t *lt, const TrackInfo_t *ti );
+
+void SetupLecodeRandomTrackLT ( le_track_t *lt, uint setup_slot ); // slots 62..65
+
+// -1:wrong slot or not a battle, 0:correct slots,
+// 1:wrong property, 2:wrong music, 3:both wrong
+int HaveUsualBattleSlots ( le_track_t *lt );
+
+void ClearIdentLT ( le_track_t *lt );
+
+//-----------------------------------------------------------------------------
+
+static inline bool IsActiveLT ( const le_track_t *lt )
+ { return lt && lt->track_status >= LTS_ACTIVE; }
+
+static inline bool IsExportLT ( const le_track_t *lt )
+ { return lt && lt->track_status >= LTS_EXPORT; }
+
+static inline bool IsVisibleLT ( const le_track_t *lt )
+ { return lt && lt->track_status >= LTS_ACTIVE && !IsHiddenLETF(lt->flags); }
+
+//-----------------------------------------------------------------------------
+// SetListLT(), SetText*LT(): use 'opt & LEO_LTT_SELECTOR' to select text
+// recognized options: LEO_M_HOW | LEO_IN_*
+
+void SetIdentLT ( le_track_t *lt, const le_strpar_t *par, ccp ident ); // par: opt, use_d, csum_only
+void SetFileLT ( le_track_t *lt, const le_strpar_t *par, ccp fname ); // par: opt
+void SetNameLT ( le_track_t *lt, const le_strpar_t *par, ccp name ); // par: opt
+void SetXNameLT ( le_track_t *lt, const le_strpar_t *par, ccp xname ); // par: opt
+#if LE_STRING_LIST_ENABLED
+void SetListLT ( le_track_t *lt, const le_strpar_t *par, ccp text ); // par: ltt, opt
+#endif
+#if LE_STRING_SET_ENABLED
+void SetSetLT ( le_track_t *lt, const le_strpar_t *par, ccp text ); // par: ltt, key, opt
+void SetByKeyLT ( le_track_t *lt, ccp key, ccp text );
+#endif
+void SetTextLT ( le_track_t *lt, const le_strpar_t *par, ccp text ); // par: ltt, *
+
+//-----------------------------------------------------------------------------
+// set with 'opt'
+
+void SetIdentOptLT ( le_track_t *lt, ccp ident, bool use_d, bool csum_only, le_options_t opt );
+void SetTextOptLT ( le_track_t *lt, ccp text, le_options_t opt );
+
+//-----------------------------------------------------------------------------
+// use 'opt & LEO_LTT_SELECTOR' to select text
+
+ccp * GetPtrLT ( const le_track_t *lt, const le_strpar_t *par );
+ccp * GetPtrOptLT ( const le_track_t *lt, le_options_t opt, bool allow_d );
+
+ccp GetSha1LT ( const le_track_t *lt, bool use_d, ccp return_on_empty );
+ccp GetIdentLT ( const le_track_t *lt, bool use_d, bool use_sha1, ccp return_on_empty );
+ccp GetFileLT ( const le_track_t *lt, ccp return_on_empty );
+ccp GetNameLT ( const le_track_t *lt, ccp return_on_empty );
+ccp GetXNameLT ( const le_track_t *lt, ccp return_on_empty );
+ccp GetXName2LT ( const le_track_t *lt, ccp return_on_empty );
+
+ccp GetTextLT ( const le_track_t *lt, const le_strpar_t *par, ccp return_on_empty );
+ccp GetTextOptLT ( const le_track_t *lt, le_options_t opt, ccp return_on_empty );
+
+ccp QuoteSha1LT ( const le_track_t *lt, bool use_d, ccp return_on_empty );
+ccp QuoteIdentLT ( const le_track_t *lt, bool use_d, bool use_sha1, ccp return_on_empty );
+ccp QuoteFileLT ( const le_track_t *lt, ccp return_on_empty );
+ccp QuoteNameLT ( const le_track_t *lt, ccp return_on_empty );
+ccp QuoteXNameLT ( const le_track_t *lt, ccp return_on_empty );
+ccp QuoteXName2LT ( const le_track_t *lt, ccp return_on_empty );
+
+ccp QuoteTextLT ( const le_track_t *lt, const le_strpar_t *par, ccp return_on_empty );
+ccp QuoteTextOptLT ( const le_track_t *lt, le_options_t opt, ccp return_on_empty );
+
+//-----------------------------------------------------------------------------
+
+#if LE_STRING_LIST_ENABLED
+
+ ccp GetListLT ( const le_track_t *lt, le_options_t opt, ccp return_on_empty );
+ ccp QuoteListLT ( const le_track_t *lt, le_options_t opt, ccp return_on_empty );
+
+#endif
+
+#if LE_STRING_SET_ENABLED
+
+ ccp GetSetLT ( const le_track_t *lt, const le_strpar_t *par, ccp return_on_empty );
+ ccp QuoteSetLT ( const le_track_t *lt, const le_strpar_t *par, ccp return_on_empty );
+
+#endif
+
+//-----------------------------------------------------------------------------
+
+ccp GetSlotNameLT ( const le_track_t *lt );
+
+ccp GetCupLT ( const le_track_t *lt, ccp return_on_empty );
+ccp GetCupAlignLT ( const le_track_t *lt );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_track_arch_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_track_arch_t]]
+
+typedef struct le_track_arch_t
+{
+ le_track_t lt; // usual track data
+ le_group_t group; // group id
+
+ // all string alloced
+
+ ccp name_order; // relevant name for order
+ ccp version; // version
+
+ // order := attr_order plus_order name_order game_order
+
+ s16 attr_order; // order by attribute, default=1000
+ uint plus_order; // order by plus prefix
+ uint game_order; // order by game prefix
+}
+le_track_arch_t;
+
+//-----------------------------------------------------------------------------
+
+void ResetLTA ( le_track_arch_t *ta, bool reset_lt );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// enum le_auto_setup_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_auto_setup_t]]
+
+typedef enum le_auto_setup_t
+{
+ LAS_OFF = 0,
+ LAS_ARENA = LTTY_ARENA, // true: setup original battle arenas automatically
+ LAS_TRACK = LTTY_TRACK, // true: setup original versus tracks automatically
+ LAS_RANDOM = LTTY_RANDOM, // true: setup LE-CODE random slots automatically
+ LAS_DEFAULT = LAS_ARENA | LAS_TRACK | LAS_RANDOM,
+
+ LAS_TEMPLATE = LTTY__NEXT // true: insert example tracks
+}
+__attribute__ ((packed)) le_auto_setup_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// le_type_settings_t + le_settings_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_type_settings_t]]
+
+typedef struct le_type_settings_t
+{
+ bool orig_tracks; // true: tracks are original
+ bool add_unused; // true: add unused arenas/tracks
+}
+__attribute__ ((packed)) le_type_settings_t;
+
+///////////////////////////////////////////////////////////////////////////////
+// [[le_settings_t]]
+
+typedef struct le_settings_t
+{
+ bool valid; // true if scan or analysis done
+ le_type_settings_t bt; // battle settings
+ le_type_settings_t vs; // versus settings
+}
+le_settings_t;
+
+///////////////////////////////////////////////////////////////////////////////
+// [[le_group_info_t]]
+
+typedef struct le_group_info_t
+{
+ uint group; // group number
+
+ u16 *list; // list of group members
+ uint used; // number of group members
+ uint size; // alloced elements of 'list'
+
+ uint n_head; // number of head members
+ uint n_group; // number of grp members
+ uint head1; // first head member, valid if 'n_head>0'
+}
+le_group_info_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct le_distrib_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[le_distrib_t]]
+
+typedef struct le_distrib_t
+{
+ //-- basic data
+
+ bool is_initialized; // true: data is InitializeLD()
+ le_auto_setup_t auto_setup; // bit files (LAS_*)
+ le_strpar_t spar; // current string param, incl. default 'opt'
+
+ le_track_t *tlist; // list of tracks
+ uint tlist_used; // used elements in 'tlist'
+ uint tlist_size; // alloced 'tlist' elements
+
+
+ //-- more data
+
+ ParamField_t dis_param; // parameter list for FF_DISTRIB
+ le_lpar_t *lpar; // NULL or LPAR settings
+ le_cup_t cup_battle; // track list for battle cups
+ le_cup_t cup_versus; // track list for versus cups
+ mem_t lecode[LEREG__N]; // LE-CODE data
+ bool lecode_alloced[LEREG__N];
+ // true, if 'lecode' is alloced
+ le_settings_t scan; // settings by ScanLeDefLD()
+ le_settings_t ana; // settings by AnalyzeLD()
+
+
+ //-- this is a reference list, setup by e.g. Sort*()
+ //-- the list is termianted by a NULL pointer.
+
+ le_track_t **reflist; // reference list, terminated by NULL
+ uint reflist_used; // used elements in 'tlist'
+ uint reflist_size; // alloced 'tlist' elements
+
+ //-- track archive
+
+ le_track_arch_t *arch; // list of tracks
+ uint arch_used; // used elements in 'arch'
+ uint arch_size; // alloced 'tlist' elements
+
+ exmem_list_t group; // group manager
+
+
+ //-- helper data
+
+ ctcode_t *ctcode; // NULL or temporary file
+
+
+ //-- scan helpers
+
+ bool is_pass2; // true on pass2
+ bool second_ledef; // true: don't clear tracks and cups
+}
+le_distrib_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeLD ( le_distrib_t *ld );
+void ResetLD ( le_distrib_t *ld );
+void ResetTracksAndCupsLD ( le_distrib_t *ld );
+void AutoSetupLD ( le_distrib_t *ld, le_auto_setup_t auto_setup );
+
+void AnalyzeLD ( le_distrib_t *ld, bool force_new_analysis );
+
+void CutLD ( le_distrib_t *ld, le_options_t opt ); // opt=LEO_M_CUT
+void ClearTracksLD ( le_distrib_t *ld, int from, int to );
+
+void SetupLparLD ( le_distrib_t *ld, bool load_lpar );
+
+//-----------------------------------------------------------------------------
+// trackhelpers
+
+uint PackTracksLD ( const le_distrib_t *ld );
+void CheckTracksLD ( const le_distrib_t *ld );
+
+le_track_t * GetTrackLD ( le_distrib_t *ld, int slot );
+le_track_t * DefineTrackLD ( le_distrib_t *ld, int slot, bool mark_export );
+le_track_t * DefineFreeTrackLD ( le_distrib_t *ld, le_track_type_t ltty, bool mark_export );
+le_track_t * DefineGroupTrackLD ( le_distrib_t *ld, le_track_type_t ltty, bool mark_export );
+
+le_track_t * FindFillTrackLD ( le_distrib_t *ld, le_cup_t *lc, bool allow_candidate );
+
+int FindFreeTracksLD ( le_distrib_t *ld, le_track_type_t ltty, int n );
+le_track_t * ReserveTracksLD ( le_distrib_t *ld, le_track_type_t ltty, int n, bool mark_export );
+
+//-----------------------------------------------------------------------------
+// cup helpers
+
+void ClearUserFlagsAndCupsLD ( le_distrib_t *ld );
+bool HaveWiimmCupLD ( const le_distrib_t *ld );
+
+void DirtyCupLD ( le_distrib_t *ld, le_track_type_t ltty );
+void UpdateCupsLD ( le_distrib_t *ld );
+
+bool PrintCupRefLD ( FILE *f, le_distrib_t *ld, le_cup_t *lc );
+
+//-----------------------------------------------------------------------------
+// manage archive [[track-arch]]
+
+void ResetArchLD ( le_distrib_t *ld );
+le_track_arch_t * GetNextArchLD ( le_distrib_t *ld );
+enumError AddToArchLD ( le_distrib_t *ld, raw_data_t *raw );
+bool CloseArchLD ( le_distrib_t *ld ); // return true on activity
+
+//-----------------------------------------------------------------------------
+
+typedef bool (*FilterFuncLD) ( const le_track_t *lt, le_options_t opt );
+
+int SetupReferenceList ( le_distrib_t *ld, FilterFuncLD filter, le_options_t opt );
+int SortByCupLD ( le_distrib_t *ld, FilterFuncLD filter, le_options_t opt );
+
+//-----------------------------------------------------------------------------
+
+void ScanDumpLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ const void * data, // data to scan
+ uint data_size // size of 'data'
+);
+
+void ScanDumpSTLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ ScanText_t *st // initialized source
+);
+
+//-----------------------------------------------------------------------------
+
+enumError ScanLeDefLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ const void * data, // data to scan
+ uint data_size, // size of 'data'
+ ccp fname, // NULL or filename for error messages
+ CopyMode_t cm_fname // copy mode of 'fname'
+);
+
+enumError ScanLeDefSTLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ ScanText_t *st // initialized source
+);
+
+//-----------------------------------------------------------------------------
+
+void ScanRefLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ const void * data, // data to scan
+ uint data_size // size of 'data'
+);
+
+void ScanRefSTLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ ScanText_t *st // initialized source
+);
+
+//-----------------------------------------------------------------------------
+
+void ScanStrLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ const void * data, // data to scan
+ uint data_size // size of 'data'
+);
+
+void ScanStrSTLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ ScanText_t *st // initialized source
+);
+
+//-----------------------------------------------------------------------------
+
+void ScanSha1LD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ const void * data, // data to scan
+ uint data_size // size of 'data'
+);
+
+void ScanSha1STLD
+(
+ le_distrib_t *ld, // valid structure
+ bool init_ld, // TRUE: initialze 'ld'
+ ScanText_t *st // initialized source
+);
+
+bool ScanSha1LineLD
+(
+ le_distrib_t *ld, // valid structure
+ ccp src, // NULL or start of line
+ ccp end, // end of line
+ bool ident_only // TRUE: SetIdent*LT() only
+);
+
+//-----------------------------------------------------------------------------
+
+enumError ImportRawDataLD
+(
+ le_distrib_t *ld, // destination
+ raw_data_t *raw // source
+);
+
+enumError ImportFileLD
+(
+ le_distrib_t *ld, // destination
+ ccp fname, // file name of source
+ bool use_wildcard, // true & file not exist: search files
+ bool support_options // support options (leading '+' and no slash )
+);
+
+void ImportOptionsLD ( le_distrib_t *ld );
+
+void ImportLD ( le_distrib_t *ld, const le_distrib_t *src );
+void ImportLparLD ( le_distrib_t *ld, const le_lpar_t *lpar );
+void ImportAnaLD ( le_distrib_t *ld, const le_analyse_t *ana );
+void ImportCtcodeLD ( le_distrib_t *ld, const ctcode_t *ctcode );
+void ImportBmgLD ( le_distrib_t *ld, const bmg_t *bmg, const le_strpar_t *par );
+
+//-----------------------------------------------------------------------------
+
+bool ExportAnaLD ( const le_distrib_t *ld, le_analyse_t *ana );
+bool ExportCtCodeLD ( const le_distrib_t *ld, ctcode_t *ctcode );
+
+//-----------------------------------------------------------------------------
+// create files
+
+enumError CreateDumpLD ( FILE *f, le_distrib_t *ld );
+enumError CreateRefLD ( FILE *f, le_distrib_t *ld, bool add_strings );
+enumError CreateStringsLD ( FILE *f, le_distrib_t *ld );
+enumError CreateNamesLD ( FILE *f, le_distrib_t *ld, bool use_xname );
+enumError CreateInfoLD ( FILE *f, le_distrib_t *ld, bool use_xname );
+enumError CreateSha1LD ( FILE *f, le_distrib_t *ld, bool use_xname, bool add_comments );
+enumError CreateCtDefLD ( FILE *f, le_distrib_t *ld );
+enumError CreateLeDefLD ( FILE *f, le_distrib_t *ld );
+enumError CreateLecodeLD ( FILE *f, le_distrib_t *ld, le_region_t region );
+enumError CreateLparLD ( FILE *f, le_distrib_t *ld, bool print_full );
+enumError CreateBmgLD ( FILE *f, le_distrib_t *ld, bool bmg_text );
+
+enumError CreateLeInfoLD ( FILE *f, const le_distrib_t *ld, bool list_only );
+enumError CreateDebugLD ( FILE *f, const le_distrib_t *ld );
+
+enumError CreateLecode4LD ( ccp fname, le_distrib_t *ld );
+
+//-----------------------------------------------------------------------------
+// special jobs
+
+enumError SubstLD ( le_distrib_t *ld, const le_strpar_t *dest, ccp arg );
+enumError CopyLD ( le_distrib_t *ld, const le_strpar_t *dest,
+ const le_strpar_t *src, int n_src );
+
+enumError TransferFilesLD ( le_distrib_t *ld, bool logit, bool testmode );
+
+//-----------------------------------------------------------------------------
+// distribution support
+
+void UpdateDistribLD ( le_distrib_t *ld, bool overwrite );
+bool AddDistribParamLD ( le_distrib_t *ld, ccp src, ccp end );
+
+enumError ImportDistribLD ( le_distrib_t *ld, cvp data, uint size );
+enumError ImportDistribSTLD ( le_distrib_t *ld, ScanText_t *st );
+
+enumError CreateDistribLD ( FILE *f, le_distrib_t *ld, bool use_xname );
+
+//-----------------------------------------------------------------------------
+// lecode support
+
+void FreeLecodeLD ( le_distrib_t *ld, le_region_t reg );
+mem_t AssignLecodeLD ( le_distrib_t *ld, le_region_t reg, cvp data, uint size );
+mem_t GetLecodeLD ( const le_distrib_t *ld, le_region_t reg );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// ledis_dump support ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+int EnableLDUMP ( ccp filename );
+enumError CloseLDUMP();
+
+void ImportAnaLDUMP ( const le_analyse_t *ana );
+void ImportCtcodeLDUMP ( const ctcode_t *ctcode );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// struct DistributionInfo_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#define DISTRIB_MAGIC8 "#DISTRIB"
+#define DISTRIB_MAGIC8_NUM 0x2344495354524942ull
+
+#define DISTRIBUTION_FILE_VERSION 1
+#define MIN_DISTRIBUTION_SLOT 10 // included
+#define MAX_DISTRIBUTION_TRACK 10000 // excluded
+#define MAX_DISTRIBUTION_ARENA 1000 // excluded
+#define DISTRIBUTION_ARENA_DELTA 100000
+
+#define DEFAULT_DISTIBUTION_FNAME "distribution.txt"
+
+//-----------------------------------------------------------------------------
+
+static inline bool IsValidDistribArena ( uint slot )
+{
+ return slot == DISTRIBUTION_ARENA_DELTA
+ || slot >= DISTRIBUTION_ARENA_DELTA+MIN_DISTRIBUTION_SLOT
+ && slot < DISTRIBUTION_ARENA_DELTA+MAX_DISTRIBUTION_ARENA;
+}
+
+static inline bool IsValidDistribTrack ( uint slot )
+{
+ return !slot
+ || slot >= MIN_DISTRIBUTION_SLOT && slot < MAX_DISTRIBUTION_TRACK;
+}
+
+static inline bool IsValidDistribSlot ( uint slot )
+{
+ return !slot
+ || slot >= MIN_DISTRIBUTION_SLOT
+ && slot < MAX_DISTRIBUTION_TRACK
+ || slot == DISTRIBUTION_ARENA_DELTA
+ || slot >= DISTRIBUTION_ARENA_DELTA+MIN_DISTRIBUTION_SLOT
+ && slot < DISTRIBUTION_ARENA_DELTA+MAX_DISTRIBUTION_ARENA;
+}
+
+//-----------------------------------------------------------------------------
+// [[DistributionInfo_t]]
+
+typedef struct DistributionInfo_t
+{
+ le_distrib_t ld;
+ ParamField_t translate;
+ ParamField_t arena[MAX_DISTRIBUTION_ARENA];
+ ParamField_t track[MAX_DISTRIBUTION_TRACK];
+}
+DistributionInfo_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeDistributionInfo
+ ( DistributionInfo_t * dinf, bool add_default_param );
+void ResetDistributionInfo ( DistributionInfo_t *dinf );
+void AddParamDistributionInfo ( DistributionInfo_t * dinf, bool overwrite );
+
+enumError ScanDistribFile
+ ( DistributionInfo_t *dinf, ccp fname, int ignore, bool assume_arena );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// slot translation ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+char * ScanSlot ( uint *res_slot, ccp source, bool need_point );
+
+void NormalizeSlotTranslation ( char *buf, uint bufsize, ccp name,
+ char ** p_first_para, char ** p_first_brack );
+
+uint DefineSlotTranslation
+ ( ParamField_t *translate, bool is_arena, uint slot, ccp name );
+
+// 'sha1' can be NULL
+int FindSlotByTranslation ( const ParamField_t *translate, ccp fname, ccp sha1 );
+
+// 'param' not NULL: Scan "@PARAM = VALUE" lines and store result.
+void ScanSlotTranslation
+ ( ParamField_t *translate, le_distrib_t *ld, ccp fname, bool ignore );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// misc ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void ScanOptLeDefine ( ccp arg );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// END ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#endif // SZS_LIB_LEDIS_H
+