aboutsummaryrefslogtreecommitdiff
path: root/project/src
diff options
context:
space:
mode:
Diffstat (limited to 'project/src')
-rw-r--r--project/src/db-kcl.c71
-rw-r--r--project/src/db-kcl.h51
-rw-r--r--project/src/db-mkw.c48
-rw-r--r--project/src/db-mkw.h1
-rw-r--r--[-rwxr-xr-x]project/src/lib-checksum.c0
-rw-r--r--[-rwxr-xr-x]project/src/lib-checksum.h0
-rw-r--r--project/src/lib-common.h2
-rw-r--r--project/src/lib-file.c251
-rw-r--r--[-rwxr-xr-x]project/src/lib-itemslot.c0
-rw-r--r--[-rwxr-xr-x]project/src/lib-kmp-diff.c0
-rw-r--r--[-rwxr-xr-x]project/src/lib-minigame.c38
-rw-r--r--project/src/lib-std.h61
-rw-r--r--project/src/lib-szs-create.c90
-rw-r--r--project/src/lib-szs.c2
-rw-r--r--project/src/lib-szs.h24
-rw-r--r--project/src/wszst.c40
-rw-r--r--project/src/wtest.c168
17 files changed, 702 insertions, 145 deletions
diff --git a/project/src/db-kcl.c b/project/src/db-kcl.c
index 220a8b1..1e6d399 100644
--- a/project/src/db-kcl.c
+++ b/project/src/db-kcl.c
@@ -33,6 +33,9 @@ const kcl_attrib_name_t kcl_attrib_name[N_KCL_ATTRIB+1] =
{ KCLT_SOUND, "SOUND" },
{ KCLT_ITEM, "ITEM" },
{ KCLT_UNKNOWN, "UNKNOWN" },
+ { KCLT_VARIANT_X, "VARIANT_X" },
+ { KCLT_VARIANT_A, "VARIANT_A" },
+ { KCLT_VARIANT_B, "VARIANT_B" },
{0,0}
};
@@ -375,100 +378,100 @@ const u8 kcl_color[N_KCL_COLORS][4] =
const kcl_type_t kcl_type[N_KCL_TYPE+1] =
{
{ 0x00, 0, "Road",
- KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
- { 0x01, 1, "Slippery Road 1",
- KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE },
+ { 0x01, 1, "Slippery Road",
+ KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x02, 1, "Weak Off-road",
- KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x03, 1, "Off-road",
- KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x04, 1, "Heavy Off-road",
- KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
- { 0x05, 1, "Slippery Road 2",
- KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE },
+ { 0x05, 1, "Slippery Road",
+ KCLT_C_OFFROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x06, 2, "Boost Pad",
- KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_BOOST },
+ KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A | KCLT_BOOST },
{ 0x07, 2, "Boost Ramp",
- KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_BOOST | KCLT_TRICK },
+ KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A | KCLT_BOOST | KCLT_TRICK },
{ 0x08, 2, "Jump Pad",
- KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_TRICK },
+ KCLT_C_FAST | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A | KCLT_TRICK },
{ 0x09, 10, "Item Road",
- KCLT_C_ITEM | KCLT_ITEM },
+ KCLT_C_ITEM | KCLT_ITEM | KCLT_VARIANT_A },
{ 0x0a, 8, "Solid Fall",
- KCLT_C_FALL },
+ KCLT_C_FALL | KCLT_VARIANT_A },
{ 0x0b, 5, "Moving Water",
- KCLT_C_WATER | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_WATER | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_B },
{ 0x0c, 7, "Wall",
- KCLT_C_WALL | KCLT_BORDER },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X },
{ 0x0d, 7, "Invisible Wall",
- KCLT_C_WALL | KCLT_BORDER | KCLT_ITEM },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X | KCLT_ITEM },
{ 0x0e, 10, "Item Wall",
- KCLT_C_ITEM | KCLT_ITEM },
+ KCLT_C_ITEM | KCLT_ITEM | KCLT_VARIANT_X },
{ 0x0f, 7, "Wall",
- KCLT_C_WALL | KCLT_BORDER },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X },
{ 0x10, 8, "Fall Boundary",
- KCLT_C_FALL },
+ KCLT_C_FALL | KCLT_VARIANT_X },
{ 0x11, 6, "Cannon Activator",
- KCLT_C_CANNON },
+ KCLT_C_CANNON | KCLT_VARIANT_B },
{ 0x12, 9, "Recalculation",
- KCLT_C_EFFECT },
+ KCLT_C_EFFECT | KCLT_VARIANT_X },
{ 0x13, 3, "Half-pipe Ramp",
- KCLT_C_HALFPIPE | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_HALFPIPE | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_X },
{ 0x14, 7, "Wall",
- KCLT_C_WALL | KCLT_BORDER },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X },
{ 0x15, 4, "Moving Road",
- KCLT_C_MOVING | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_MOVING | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_B },
{ 0x16, 0, "Gravity Road",
- KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x17, 0, "Road",
- KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x18, 9, "Sound Trigger",
- KCLT_C_EFFECT | KCLT_SOUND },
+ KCLT_C_EFFECT | KCLT_VARIANT_X | KCLT_SOUND },
{ 0x19, 11, "Unknown",
- KCLT_C_UNKNOWN | KCLT_UNKNOWN },
+ KCLT_C_UNKNOWN | KCLT_VARIANT_X | KCLT_UNKNOWN },
{ 0x1a, 9, "Effect Trigger",
- KCLT_C_EFFECT },
+ KCLT_C_EFFECT | KCLT_VARIANT_X },
{ 0x1b, 11, "Unknown",
- KCLT_C_UNKNOWN | KCLT_UNKNOWN },
+ KCLT_C_UNKNOWN | KCLT_VARIANT_X | KCLT_UNKNOWN },
{ 0x1c, 11, "Unknown",
- KCLT_C_UNKNOWN | KCLT_UNKNOWN },
+ KCLT_C_UNKNOWN | KCLT_VARIANT_X | KCLT_UNKNOWN },
{ 0x1d, 0, "Moving Road",
- KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE },
+ KCLT_C_ROAD | KCLT_BORDER | KCLT_DRIVE | KCLT_VARIANT_A },
{ 0x1e, 7, "Special Wall",
- KCLT_C_WALL | KCLT_BORDER },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X },
{ 0x1f, 7, "Wall",
- KCLT_C_WALL | KCLT_BORDER },
+ KCLT_C_WALL | KCLT_BORDER | KCLT_VARIANT_X },
{0,0,0,0}
};
diff --git a/project/src/db-kcl.h b/project/src/db-kcl.h
index ff8f7ff..9108d3d 100644
--- a/project/src/db-kcl.h
+++ b/project/src/db-kcl.h
@@ -18,31 +18,34 @@
typedef enum kcl_attrib_t
{
- KCLT_C_ROAD = 0x00001, // normal road
- KCLT_C_OFFROAD = 0x00002, // offroad
- KCLT_C_FAST = 0x00004, // boost and trick
- KCLT_C_HALFPIPE = 0x00008, // halfpipe
- KCLT_C_MOVING = 0x00010, // moving terrain
- KCLT_C_WATER = 0x00020, // shallow water
- KCLT_C_CANNON = 0x00040, // cannon activator
- KCLT_C_WALL = 0x00080, // wall
- KCLT_C_FALL = 0x00100, // fall or out of bounds
- KCLT_C_EFFECT = 0x00200, // sound trigger and other effects
- KCLT_C_ITEM = 0x00400, // for items only
- KCLT_C_UNKNOWN = 0x00800, // unknown type
- KCLT_M_CLASS = 0x00fff, // mask of classes
+ KCLT_C_ROAD = 0x000001, // normal road
+ KCLT_C_OFFROAD = 0x000002, // offroad
+ KCLT_C_FAST = 0x000004, // boost and trick
+ KCLT_C_HALFPIPE = 0x000008, // halfpipe
+ KCLT_C_MOVING = 0x000010, // moving terrain
+ KCLT_C_WATER = 0x000020, // shallow water
+ KCLT_C_CANNON = 0x000040, // cannon activator
+ KCLT_C_WALL = 0x000080, // wall
+ KCLT_C_FALL = 0x000100, // fall or out of bounds
+ KCLT_C_EFFECT = 0x000200, // sound trigger and other effects
+ KCLT_C_ITEM = 0x000400, // for items only
+ KCLT_C_UNKNOWN = 0x000800, // unknown type
+ KCLT_M_CLASS = 0x000fff, // mask of classes
- KCLT_BORDER = 0x01000, // road or wall
- KCLT_DRIVE = 0x02000, // is driveable
- KCLT_BOOST = 0x04000, // boost
- KCLT_TRICK = 0x08000, // trickable
- KCLT_SOUND = 0x10000, // sound effect
- KCLT_ITEM = 0x20000, // special for items
- KCLT_UNKNOWN = 0x40000, // unknown
- KCLT_M_FEATURES = 0x7f000, // mask of base features
+ KCLT_BORDER = 0x001000, // road or wall
+ KCLT_DRIVE = 0x002000, // is driveable
+ KCLT_BOOST = 0x004000, // boost
+ KCLT_TRICK = 0x008000, // trickable
+ KCLT_SOUND = 0x010000, // sound effect
+ KCLT_ITEM = 0x020000, // special for items
+ KCLT_UNKNOWN = 0x040000, // unknown
+ KCLT_VARIANT_X = 0x080000, // unknown variant
+ KCLT_VARIANT_A = 0x100000, // variant A
+ KCLT_VARIANT_B = 0x200000, // variant B
+ KCLT_M_FEATURES = 0x3ff000, // mask of base features
- KCLT_NONE = 0x00000, // none set
- KCLT_M_ALL = 0x7ffff // all flags of above
+ KCLT_NONE = 0x000000, // none set
+ KCLT_M_ALL = 0x3fffff // all flags of above
} kcl_attrib_t;
@@ -50,7 +53,7 @@ typedef enum kcl_attrib_t
#define N_KCL_CLASS 12
#define N_KCL_TYPE 0x20
-#define N_KCL_ATTRIB 19
+#define N_KCL_ATTRIB 22
#define N_KCL_FLAG 0x10000
#define N_KCL_AUTO_FLAGS 200
#define N_KCL_USER_FLAGS 200
diff --git a/project/src/db-mkw.c b/project/src/db-mkw.c
index 7c7c519..6fd6b9c 100644
--- a/project/src/db-mkw.c
+++ b/project/src/db-mkw.c
@@ -910,6 +910,54 @@ const MusicInfo_t music_info[MKW_N_MUSIC+1] =
{0,0,-1,""}
};
+const KeywordTab_t music_keyword_tab[] =
+{
+ { 0x75, "MLC", "XLC", -1 },
+ { 0x77, "M12", "MMM", 1 },
+ { 0x79, "M13", "MG", 2 },
+ { 0x7b, "M14", "TF", 4 },
+ { 0x7d, "M21", "MC", 0 },
+ { 0x7d, "M11", "LC", 8 },
+ { 0x7f, "M22", "CM", 5 },
+ { 0x81, "M23", "DKS", 6 },
+ { 0x83, "M24", "WGM", 7 },
+ { 0x85, "M32", "KC", 15 },
+ { 0x87, "M31", "DC", 9 },
+ { 0x89, "M41", "DDR", 14 },
+ { 0x8b, "M34", "GV", 3 },
+ { 0x8d, "M42", "MH", 10 },
+ { 0x8f, "M33", "MT", 11 },
+ { 0x91, "M43", "BC", 12 },
+ { 0x93, "M44", "RR", 13 },
+ { 0x95, "M62", "GSGB", 31 },
+ { 0x97, "M53", "SGV2", 25 },
+ { 0x99, "M81", "SMC3", 24 },
+ { 0x9b, "M72", "GBC3", 30 },
+ { 0x9d, "M61", "NSL", 27 },
+ { 0x9f, "M54", "NMR", 26 },
+ { 0xa1, "M73", "NDKJP", 29 },
+ { 0xa3, "M84", "NBC", 28 },
+ { 0xa5, "M51", "GPB", 16 },
+ { 0xa7, "M74", "GMC", 17 },
+ { 0xa9, "M64", "GWS", 18 },
+ { 0xab, "M83", "GDKM", 19 },
+ { 0xad, "M52", "DYF", 20 },
+ { 0xaf, "M63", "DDS", 23 },
+ { 0xb1, "M71", "DDH", 21 },
+ { 0xb3, "M82", "DPG", 22 },
+ { 0xb5, "MA12", "ADP", 32 },
+ { 0xb7, "MA11", "ABP", 33 },
+ { 0xb9, "MA13", "AFS", 35 },
+ { 0xbb, "MA14", "ACCW", 34 },
+ { 0xbd, "MA15", "ATD", 36 },
+ { 0xbf, "MA24", "AGCL", 37 },
+ { 0xc1, "MA25", "ADTH", 38 },
+ { 0xc3, "MA21", "ASBC4", 39 },
+ { 0xc5, "MA22", "AGBC3", 40 },
+ { 0xc7, "MA23", "ANSS", 41 },
+ {0,0,0,0}
+};
+
//
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////// E N D //////////////////////////////////
diff --git a/project/src/db-mkw.h b/project/src/db-mkw.h
index 6c49f91..41153c2 100644
--- a/project/src/db-mkw.h
+++ b/project/src/db-mkw.h
@@ -117,6 +117,7 @@ typedef struct MusicInfo_t
} MusicInfo_t;
extern const MusicInfo_t music_info[MKW_N_MUSIC+1];
+extern const KeywordTab_t music_keyword_tab[];
//
diff --git a/project/src/lib-checksum.c b/project/src/lib-checksum.c
index 990fa7f..990fa7f 100755..100644
--- a/project/src/lib-checksum.c
+++ b/project/src/lib-checksum.c
diff --git a/project/src/lib-checksum.h b/project/src/lib-checksum.h
index 088b2a1..088b2a1 100755..100644
--- a/project/src/lib-checksum.h
+++ b/project/src/lib-checksum.h
diff --git a/project/src/lib-common.h b/project/src/lib-common.h
index 2f72c56..5da9043 100644
--- a/project/src/lib-common.h
+++ b/project/src/lib-common.h
@@ -611,6 +611,8 @@ enumError SaveTextMINIGAME
int ScanOptKmgLimit ( ccp arg );
int ScanOptKmgCopy ( ccp arg );
+extern const KeywordTab_t arena_attrib_tab[];
+
//
///////////////////////////////////////////////////////////////////////////////
/////////////// ObjFlow.bin ///////////////
diff --git a/project/src/lib-file.c b/project/src/lib-file.c
index 5a1cc44..635baaf 100644
--- a/project/src/lib-file.c
+++ b/project/src/lib-file.c
@@ -35,8 +35,11 @@
* *
***************************************************************************/
+#define _GNU_SOURCE 1
+
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <utime.h>
@@ -1985,7 +1988,7 @@ int GetVersionFF
break;
#endif
- case FF_BMG: // use encoding
+ case FF_BMG: // use n_sections & encoding
if ( data_size >= sizeof(bmg_header_t) )
{
const bmg_header_t *bh = (bmg_header_t*)data;
@@ -3431,5 +3434,251 @@ EncodeMode_t SetupCoding64 ( EncodeMode_t mode, EncodeMode_t fallback )
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// slot by attribute ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void DumpSlotInfo
+(
+ FILE *f, // valid output stream
+ int indent, // robust indention of dump
+ const slot_info_t *si, // data to dump
+ bool src_valid // FALSE: si.source if definitly invalid
+)
+{
+ if ( !f || !si )
+ return;
+
+ indent = NormalizeIndent(indent);
+ if ( src_valid && si->source.ptr && si->source.len )
+ fprintf(f,"%*s" "Source: %.*s\n",
+ indent,"", si->source.len, si->source.ptr );
+
+ fprintf(f,
+ "%*s" "Slot attrib: %s\n"
+ "%*s" "Race info: %4u [%u] %s\n"
+ "%*s" "Arena info: %4u [%u] %s\n"
+ "%*s" "Music info: %#4x [%u] %s\n"
+ ,indent,"" ,si->slot_attrib
+ ,indent,"" ,si->race_slot ,si->race_mode ,si->race_info
+ ,indent,"" ,si->arena_slot ,si->arena_mode ,si->arena_info
+ ,indent,"" ,si->music_index ,si->music_mode ,si->music_info
+ );
+}
+
+//-----------------------------------------------------------------------------
+
+void AnalyzeSlotAttrib ( slot_info_t *si, bool reset_si, mem_t attrib )
+{
+ DASSERT(si);
+ PRINT("AnalyzeSlotAttrib(,%d,\"%.*s\")\n",reset_si,attrib.len,attrib.ptr);
+
+ if (reset_si)
+ memset(si,0,sizeof(*si));
+ si->source = attrib;
+
+ const uint MAX_ATTRIB = 100;
+ mem_t list[MAX_ATTRIB];
+ const uint n_attrib = SplitByCharMem(list,MAX_ATTRIB,attrib,',');
+
+ uint i;
+ for ( i = 0; i < n_attrib; i++ )
+ {
+ ccp src = list[i].ptr;
+ uint len = list[i].len;
+ PRINT0("%3u: |%.*s|\n",i,len,src);
+
+ switch(len)
+ {
+ case 2:
+ if ( src[0] >= '1' && src[0] <= '8' && src[1] >= '1' && src[1] <= '4' )
+ {
+ si->race_mode = SIT_MANDATORY;
+ si->race_slot = strtoul(src,0,10);
+ StringCopySM(si->race_info,sizeof(si->race_info),src,2);
+ }
+ break;
+
+ case 3:
+ if ( src[0]=='r' && src[1]>='1' && src[1]<='8' && src[2]>='1' && src[2]<='4' )
+ {
+ const u16 slot = strtoul(src+1,0,10);
+ if (!si->have_31_71)
+ {
+ si->race_mode = SIT_RECOMMEND;
+ si->race_slot = slot;
+ StringCopySM(si->race_info,sizeof(si->race_info),src,3);
+ }
+ else if ( slot == 31 || slot == 71 )
+ {
+ si->race_mode = SIT_MANDATORY;
+ si->race_slot = slot;
+ snprintf(si->race_info,sizeof(si->race_info),"%u",slot);
+ }
+ // else ignore
+ }
+ else if ( src[0]=='a' && src[1]>='1' && src[1]<='2' && src[2]>='1' && src[2]<='5' )
+ {
+ si->arena_mode = SIT_RECOMMEND;
+ si->arena_slot = strtoul(src+1,0,10);
+ StringCopySM(si->arena_info,sizeof(si->arena_info),src,3);
+ }
+ else if ( src[0]=='m' && src[1]>='1' && src[1]<='8' && src[2]>='1' && src[2]<='4' )
+ {
+ si->music_mode = SIT_RECOMMEND;
+ StringCopySM(si->music_info,sizeof(si->music_info),src,3);
+ }
+ else if (!memcmp(src,"mlc",3))
+ {
+ si->music_mode = SIT_MANDATORY;
+ StringCopySM(si->music_info,sizeof(si->music_info),src,3);
+ }
+ break;
+
+ case 4:
+ if ( src[0] == 'm' && src[1] == 'a'
+ && src[2] >= '1' && src[2] <= '2' && src[3] >= '1' && src[3] <= '5' )
+ {
+ si->music_mode = SIT_MANDATORY;
+ StringCopySM(si->music_info,sizeof(si->music_info),src,4);
+ }
+ else if ( src[0] == 'm' && src[1] == 't'
+ && src[2] >= '1' && src[2] <= '8' && src[3] >= '1' && src[3] <= '4' )
+ {
+ si->music_mode = SIT_MANDATORY;
+ StringCopySM(si->music_info,sizeof(si->music_info),src+1,3);
+ si->music_info[0] = 'm';
+ }
+ break;
+
+ case 5:
+ if (!memcmp(src,"31+71",5))
+ {
+ si->have_31_71 = true;
+ if ( si->race_slot == 31 || si->race_slot == 71 )
+ {
+ si->race_mode = SIT_MANDATORY;
+ snprintf(si->race_info,sizeof(si->race_info),"%u",si->race_slot);
+ }
+ else
+ {
+ si->race_mode = SIT_MANDATORY2;
+ si->race_slot = 31;
+ StringCopySM(si->race_info,sizeof(si->race_info),src,5);
+ }
+ }
+ else if ( !si->arena_mode && !memcmp(src,"arena",5) )
+ {
+ si->arena_mode = SIT_GENERIC;
+ si->arena_slot = 0;
+ StringCopySM(si->arena_info,sizeof(si->arena_info),src,5);
+ }
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void AnalyzeSlotByName ( slot_info_t *si, bool reset_si, mem_t name )
+{
+ DASSERT(si);
+
+ if (reset_si)
+ memset(si,0,sizeof(*si));
+
+ ccp src = name.ptr;
+ ccp slash = memrchr(src,'/',name.len);
+ if (slash)
+ src = slash+1;
+
+ ccp end = name.ptr + name.len;
+ ccp brack1 = memrchr(src,'[',end-src);
+ if (brack1)
+ {
+ ccp brack2 = memchr(brack1,']',end-brack1);
+ if (brack2)
+ AnalyzeSlotAttrib(si,false,MemByE(brack1+1,brack2));
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void FinalizeSlotInfo ( slot_info_t *si, bool minus_for_empty )
+{
+ DASSERT(si);
+
+ //--- generic music support
+
+ char music_info[8];
+ if (si->race_slot)
+ snprintf(music_info,sizeof(music_info),"m%u",(u8)si->race_slot);
+ else if (si->arena_slot)
+ snprintf(music_info,sizeof(music_info),"ma%u",(u8)si->arena_slot);
+ else
+ *music_info = 0;
+
+ if ( !si->music_mode && *music_info )
+ {
+ si->music_mode = SIT_GENERIC;
+ StringCopyS(si->music_info,sizeof(si->music_info),music_info);
+ }
+
+ if (si->music_info[0])
+ {
+ const KeywordTab_t *kt = ScanKeyword(0,si->music_info,music_keyword_tab);
+ if (kt)
+ si->music_index = kt->id;
+ }
+
+
+ //--- create slot info
+
+ char slot_attrib[20], *dest = slot_attrib, *end = slot_attrib + sizeof(slot_attrib);
+ if (si->race_info[0])
+ dest = StringCat2E(dest,end,",",si->race_info);
+ if (si->arena_info[0])
+ dest = StringCat2E(dest,end,",",si->arena_info);
+ if ( si->music_info[0] && strcmp(si->music_info,music_info) )
+ dest = StringCat2E(dest,end,",",si->music_info);
+ if ( dest > slot_attrib )
+ StringCopyS(si->slot_attrib,sizeof(si->slot_attrib),slot_attrib+1);
+
+
+ //--- options
+
+ if (minus_for_empty)
+ {
+ if (!*si->race_info) si->race_info[0] = '-', si->race_info[1] = 0;
+ if (!*si->arena_info) si->arena_info[0] = '-', si->arena_info[1] = 0;
+ if (!*si->music_info) si->music_info[0] = '-', si->music_info[1] = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+slot_info_t GetSlotByAttrib ( mem_t attrib, bool minus_for_empty )
+{
+ PRINT("GetSlotByAttrib(\"%.*s\")\n",attrib.len,attrib.ptr);
+
+ slot_info_t si = {{0,0}};
+ AnalyzeSlotAttrib(&si,false,attrib);
+ FinalizeSlotInfo(&si,minus_for_empty);
+ return si;
+}
+
+//-----------------------------------------------------------------------------
+
+slot_info_t GetSlotByName ( mem_t name, bool minus_for_empty )
+{
+ PRINT("GetSlotByName(\"%.*s\")\n",name.len,name.ptr);
+
+ slot_info_t si = {{0,0}};
+ AnalyzeSlotByName(&si,false,name);
+ FinalizeSlotInfo(&si,minus_for_empty);
+ return si;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// END ///////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-itemslot.c b/project/src/lib-itemslot.c
index 20d0060..20d0060 100755..100644
--- a/project/src/lib-itemslot.c
+++ b/project/src/lib-itemslot.c
diff --git a/project/src/lib-kmp-diff.c b/project/src/lib-kmp-diff.c
index b242bf9..b242bf9 100755..100644
--- a/project/src/lib-kmp-diff.c
+++ b/project/src/lib-kmp-diff.c
diff --git a/project/src/lib-minigame.c b/project/src/lib-minigame.c
index b97e086..d13fe21 100755..100644
--- a/project/src/lib-minigame.c
+++ b/project/src/lib-minigame.c
@@ -850,24 +850,26 @@ int ScanOptKmgLimit ( ccp arg )
///////////////////////////////////////////////////////////////////////////////
-int ScanOptKmgCopy ( ccp arg )
+const KeywordTab_t arena_attrib_tab[] =
{
- static const KeywordTab_t keytab[] =
- {
- { 0, "0", "A12", 0 },
- { 1, "1", "A11", 0 },
- { 2, "2", "A14", 0 },
- { 3, "3", "A13", 0 },
- { 4, "4", "A15", 0 },
- { 5, "5", "A24", 0 },
- { 6, "6", "A25", 0 },
- { 7, "7", "A21", 0 },
- { 8, "8", "A22", 0 },
- { 9, "9", "A23", 0 },
- { -1, "-1", "OFF", 0 },
+ { 0, "0", "A12", 12 },
+ { 1, "1", "A11", 11 },
+ { 2, "2", "A14", 14 },
+ { 3, "3", "A13", 13 },
+ { 4, "4", "A15", 15 },
+ { 5, "5", "A24", 24 },
+ { 6, "6", "A25", 25 },
+ { 7, "7", "A21", 21 },
+ { 8, "8", "A22", 22 },
+ { 9, "9", "A23", 23 },
+ { -1, "-1", "OFF", 0 },
{0,0,0,0}
- };
+};
+//-----------------------------------------------------------------------------
+
+int ScanOptKmgCopy ( ccp arg )
+{
if ( !arg || !*arg )
{
opt_kmg_arena = -1;
@@ -891,7 +893,7 @@ int ScanOptKmgCopy ( ccp arg )
{
memcpy(name,p1,len);
name[len] = 0;
- const KeywordTab_t *key = ScanKeyword(0,name,keytab);
+ const KeywordTab_t *key = ScanKeyword(0,name,arena_attrib_tab);
if (key)
{
opt_kmg_arena = key->id;
@@ -905,10 +907,10 @@ int ScanOptKmgCopy ( ccp arg )
}
int abbrev;
- const KeywordTab_t *key = ScanKeyword(&abbrev,arg,keytab);
+ const KeywordTab_t *key = ScanKeyword(&abbrev,arg,arena_attrib_tab);
if (!key)
{
- PrintKeywordError(keytab,arg,abbrev,0,
+ PrintKeywordError(arena_attrib_tab,arg,abbrev,0,
"keyword for option --kmg-arena");
return 1;
}
diff --git a/project/src/lib-std.h b/project/src/lib-std.h
index 28d1eaa..615a038 100644
--- a/project/src/lib-std.h
+++ b/project/src/lib-std.h
@@ -1233,6 +1233,67 @@ typedef enum PatchImage_t
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// slot by attribute ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[slot_info_type_t]]
+
+typedef enum slot_info_type_t
+{
+ SIT_NOT, // not defined
+ SIT_GENERIC, // generic slot: "arena" or music by race/arena slot
+ SIT_RECOMMEND, // recommended slot: "r##" | "a##" | "m*"
+ SIT_MANDATORY2, // mandatory alternative: "31+71"
+ SIT_MANDATORY, // mandatory slot: "##"
+}
+__attribute__ ((packed)) slot_info_type_t;
+
+//-------------------------------------------------------------------------
+// [[slot_info_t]]
+
+typedef struct slot_info_t
+{
+ mem_t source; // reference to last source of analysis
+ // becomes invalid when source becomes invalid
+
+ u16 race_slot; // 0 or 11..84
+ u16 arena_slot; // 0 or 11..25
+ u16 music_index; // 0 or 0x75..
+
+ slot_info_type_t race_mode; // 0:not, 2:"r##", 3:"##"
+ slot_info_type_t arena_mode; // 0:not, 1:"arena", 2:"a##"
+ slot_info_type_t music_mode; // 0:not, 1:generic, 2:"m*"
+ bool have_31_71; // true: "31+71" found!
+
+ char race_info[6]; // race slot as text: "##" | "r##" | "31+71"
+ char arena_info[6]; // arena slot as text: "arena" | "a##"
+ char music_info[5]; // music slot as text: "m##" | "ma##"
+ char slot_attrib[17];// normalized slot atribute, combi of race+arena+music
+
+}
+slot_info_t;
+
+//-----------------------------------------------------------------------------
+
+void DumpSlotInfo
+(
+ FILE *f, // valid output stream
+ int indent, // robust indention of dump
+ const slot_info_t *si, // data to dump
+ bool src_valid // FALSE: si.source if definitly invalid
+);
+
+
+//-----------------------------------------------------------------------------
+
+void AnalyzeSlotAttrib ( slot_info_t *si, bool reset_si, mem_t attrib );
+void AnalyzeSlotByName ( slot_info_t *si, bool reset_si, mem_t name );
+void FinalizeSlotInfo ( slot_info_t *si, bool minus_for_empty );
+
+slot_info_t GetSlotByAttrib ( mem_t attrib, bool minus_for_empty );
+slot_info_t GetSlotByName ( mem_t name, bool minus_for_empty );
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// struct FormatField_t ///////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-szs-create.c b/project/src/lib-szs-create.c
index 8301400..bcddfd4 100644
--- a/project/src/lib-szs-create.c
+++ b/project/src/lib-szs-create.c
@@ -3719,8 +3719,8 @@ int FindSlotsSZS
// -1: slot not possible
// 0: unknown
// +1: slot possible
- bool *res_special // not NULL: return TRUE, if an other slot
- // than 4.2|6.1|6.2 is needed
+ int *required_slot // if not NULL: return 0|31|61|62
+ // 31 is an alias for "31+71"
)
{
DASSERT(szs);
@@ -3773,8 +3773,8 @@ int FindSlotsSZS
SLOT(6,1) = 0;
SLOT(6,2) = 0;
- if (res_special)
- *res_special = false;
+ if (required_slot)
+ *required_slot = 0;
//uint pos_count = MKW_N_TRACKS - 3;
//uint neg_count = 0;
@@ -3788,8 +3788,8 @@ int FindSlotsSZS
{
set_required_slot(slot,ISLOT(3,1),ISLOT(7,1));
stat = -1;
- if (res_special)
- *res_special = true;
+ if (required_slot)
+ *required_slot = 31;
}
@@ -3808,18 +3808,24 @@ int FindSlotsSZS
set_required_slot(slot,ISLOT(6,1),ISLOT(6,1));
if (!szs->have_ice_brres)
SLOT(6,1) = -1;
- stat = -1;
+ else
+ {
+ stat = -1;
+ if (required_slot)
+ *required_slot = 61;
+ }
}
else if ( !SLOT(6,1) && szs->have_ice_brres )
SLOT(6,1) = 1;
-
//--- analyze slot 6.2
if (szs->slot_62)
{
- set_required_slot(slot,ISLOT(6,2),ISLOT(6,2));
stat = -1;
+ set_required_slot(slot,ISLOT(6,2),ISLOT(6,2));
+ if (required_slot)
+ *required_slot = 62;
}
@@ -3837,66 +3843,88 @@ int FindSlotsSZS
///////////////////////////////////////////////////////////////////////////////
-ccp CreateSlotInfo ( szs_file_t * szs )
+void AnalyzeSlot ( slot_ana_t *sa, szs_file_t *szs )
{
+ DASSERT(sa);
DASSERT(szs);
- int slot[MKW_N_TRACKS];
- bool need_special;
- const int stat = FindSlotsSZS(szs,slot,&need_special);
+ memset(sa,0,sizeof(*sa));
+ sa->stat = FindSlotsSZS(szs,sa->slot,&sa->required_slot);
if ( szs->is_arena >= ARENA_FOUND )
- return "arena";
+ {
+ StringCopyS(sa->mandatory_slot,sizeof(sa->mandatory_slot),"arena");
+ StringCopyS(sa->slot_info,sizeof(sa->slot_info),"arena");
+ return;
+ }
static char buf[500];
char *dest = buf;
uint i;
for ( i = 0; i < MKW_N_TRACKS; i++ )
- if ( slot[i] != stat )
+ {
+ const int slot = sa->slot[i];
+ if ( slot != sa->stat )
{
if ( dest > buf )
*dest++ = ',';
dest = snprintfE(dest,buf+sizeof(buf),"%c%u.%u",
- slot[i] < 0 ? '-' : slot[i] > 0 ? '+' : '?' ,
+ slot < 0 ? '-' : slot > 0 ? '+' : '?' ,
i/4+1, i%4+1 );
}
+ }
if ( dest == buf )
*dest++ = '%';
- *dest++ = 0;
- const uint size = dest - buf;
- char *res = GetCircBuf(size);
- memcpy(res,buf,size);
- return res;
+ *dest = 0;
+
+ StringCopyS(sa->slot_info,sizeof(sa->slot_info),buf);
+
+ if ( sa->required_slot == 31 )
+ StringCopyS(sa->mandatory_slot,sizeof(sa->mandatory_slot),"31+71");
+ else if ( sa->required_slot )
+ snprintf(sa->mandatory_slot,sizeof(sa->mandatory_slot),"%u",sa->required_slot);
}
///////////////////////////////////////////////////////////////////////////////
-ccp CreateBriefSlotInfo ( szs_file_t * szs )
+ccp CreateSlotInfo ( szs_file_t *szs )
{
DASSERT(szs);
+ #if 1
+ slot_ana_t sa;
+ AnalyzeSlot(&sa,szs);
+ return CopyCircBuf(sa.slot_info,strlen(sa.slot_info)+1);
+ #else
int slot[MKW_N_TRACKS];
- bool need_special;
- const int stat = FindSlotsSZS(szs,slot,&need_special);
+ int required_slot;
+ const int stat = FindSlotsSZS(szs,slot,&required_slot);
- static char buf[500], *dest = buf;
+ if ( szs->is_arena >= ARENA_FOUND )
+ return "arena";
- uint i, count = 0;
- const char sign = stat < 0 ? '+' : '-';
+ static char buf[500];
+ char *dest = buf;
+ uint i;
for ( i = 0; i < MKW_N_TRACKS; i++ )
- if ( slot[i] && slot[i] != stat )
+ if ( slot[i] != stat )
{
- dest = snprintfE(dest,buf+sizeof(buf),"%c%u%u",
- count ? ',' : sign, i/4+1, i%4+1 );
- count++;
+ if ( dest > buf )
+ *dest++ = ',';
+ dest = snprintfE(dest,buf+sizeof(buf),"%c%u.%u",
+ slot[i] < 0 ? '-' : slot[i] > 0 ? '+' : '?' ,
+ i/4+1, i%4+1 );
}
+ if ( dest == buf )
+ *dest++ = '%';
*dest++ = 0;
const uint size = dest - buf;
char *res = GetCircBuf(size);
memcpy(res,buf,size);
return res;
+ #endif
}
//
diff --git a/project/src/lib-szs.c b/project/src/lib-szs.c
index 4347e51..43b9268 100644
--- a/project/src/lib-szs.c
+++ b/project/src/lib-szs.c
@@ -35,6 +35,8 @@
* *
***************************************************************************/
+#define _GNU_SOURCE 1
+
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/project/src/lib-szs.h b/project/src/lib-szs.h
index fbdad30..a9561c4 100644
--- a/project/src/lib-szs.h
+++ b/project/src/lib-szs.h
@@ -708,6 +708,20 @@ static inline ccp GetNameFF_SZScurrent ( const szs_file_t *szs )
}
//-----------------------------------------------------------------------------
+// [[slot_ana_t]]
+
+typedef struct slot_ana_t
+{
+ int stat; // result of FindSlotsSZS() : -1, 0 or +1
+ int slot[MKW_N_TRACKS]; // set by FindSlotsSZS()
+ int required_slot; // set by FindSlotsSZS()
+
+ char mandatory_slot[6]; // empty | "arena" | "31+71" | "61" | "62"
+ char slot_info[30]; // slot info text
+}
+slot_ana_t;
+
+//-----------------------------------------------------------------------------
int FindSlotsSZS
(
@@ -718,12 +732,14 @@ int FindSlotsSZS
// -1: slot not possible
// 0: unknown
// +1: slot possible
- bool *res_special // not NULL: return TRUE, if an other slot
- // than 4.2|6.1|6.2 is needed
+ int *required_slot // if not NULL: return 0|31|61|62
+ // 31 is an alias for "31+71"
);
-ccp CreateSlotInfo ( szs_file_t * szs );
-ccp CreateBriefSlotInfo ( szs_file_t * szs );
+void AnalyzeSlot ( slot_ana_t *sa, szs_file_t *szs );
+
+// return temporary string by GetCircBuf()
+ccp CreateSlotInfo ( szs_file_t *szs );
//-----------------------------------------------------------------------------
diff --git a/project/src/wszst.c b/project/src/wszst.c
index 21923e4..b7892bc 100644
--- a/project/src/wszst.c
+++ b/project/src/wszst.c
@@ -1961,18 +1961,15 @@ static enumError cmd_analyze()
int lap_count = 3; // STGI lap counter
float speed_factor = 1.0; // STGI speed factor
- ccp slot_info = CreateSlotInfo(&szs);
- if (szs.is_arena)
- ct_dest = StringCopyE(ct_dest,ct_end,",arena");
- else
- {
- if (!strcmp(slot_info,"+6.1"))
- ct_dest = StringCopyE(ct_dest,ct_end,",61");
- else if (!strcmp(slot_info,"+6.2"))
- ct_dest = StringCopyE(ct_dest,ct_end,",62");
- else if (!strcmp(slot_info,"+3.1,+7.1"))
- ct_dest = StringCopyE(ct_dest,ct_end,",31+71");
- }
+ slot_ana_t slotana;
+ AnalyzeSlot(&slotana,&szs);
+ slot_info_t slotinfo;
+ AnalyzeSlotByName(&slotinfo,true,MemByString(param->arg));
+ if (slotana.mandatory_slot[0])
+ AnalyzeSlotAttrib(&slotinfo,false,MemByString(slotana.mandatory_slot));
+ FinalizeSlotInfo(&slotinfo,true);
+ if (*slotinfo.slot_attrib)
+ ct_dest = StringCat2E(ct_dest,ct_end,",",slotinfo.slot_attrib);
kmp_finish_t kf;
InitializeFinishLine(&kf);
@@ -2215,12 +2212,15 @@ static enumError cmd_analyze()
"sha1_course=\"%s\"\n"
"sha1_vrcorn=\"%s\"\n"
"sha1_minimap=\"%s\"\n"
- "is_arena=%u\n"
- "is_arena_name=\"%s\"\n"
+ "is_arena=\"%u %s\"\n"
"n_ckpt0=%d\n"
"lap_count=%d\n"
"speed_factor=%5.3f\n"
"slot_info=\"%s\"\n"
+ "slot_attributes=\"%s\"\n"
+ "race_slot=\"%u %s\"\n"
+ "arena_slot=\"%u %s\"\n"
+ "music_index=\"%u %s\"\n"
"used_x_pos=\"%u=%s %3.2f %3.2f %3.2f %3.2f\"\n"
"used_y_pos=\"%u=%s %3.2f %3.2f %3.2f %3.2f\"\n"
"used_z_pos=\"%u=%s %3.2f %3.2f %3.2f %3.2f\"\n"
@@ -2248,7 +2248,11 @@ static enumError cmd_analyze()
,ckpt0_count
,lap_count
,speed_factor
- ,slot_info
+ ,slotana.slot_info
+ ,slotinfo.slot_attrib
+ ,slotinfo.race_slot,slotinfo.race_info
+ ,slotinfo.arena_slot,slotinfo.arena_info
+ ,slotinfo.music_index,slotinfo.music_info
,up.orig.rating[0],WarnLevelNameLo[up.orig.rating[0]]
,up.orig.min.x,up.orig.max.x
,fabsf(up.orig.max.x-up.orig.min.x)
@@ -3012,8 +3016,8 @@ static enumError cmd_slots()
//PatchSZS(&szs);
int slot[MKW_N_TRACKS];
- bool need_special;
- const int stat = FindSlotsSZS(&szs,slot,&need_special);
+ int required_slot;
+ const int stat = FindSlotsSZS(&szs,slot,&required_slot);
noPRINT("IS_ARENA=%d\n",szs.is_arena);
if ( szs.is_arena >= ARENA_FOUND )
@@ -3055,7 +3059,7 @@ static enumError cmd_slots()
i/4+1, i%4+1 );
count++;
}
- else if ( !need_special && ( i == 13 || i == 20 || i == 21 ))
+ else if ( required_slot != 31 && ( i == 13 || i == 20 || i == 21 ))
{
fputs(" ",stdout);
count++;
diff --git a/project/src/wtest.c b/project/src/wtest.c
index 7d94158..5f146ac 100644
--- a/project/src/wtest.c
+++ b/project/src/wtest.c
@@ -2735,20 +2735,20 @@ int GetVr1DiffByTab ( int diff ) // diff = VR(winner) - VR(loser)
static const s16 vr2_diff_tab[112] =
{
- 6598, 4999, 3963, 3233, 2671, 2212, 1819, 1476, // 0 .. 7
- 1168, 889, 633, 395, 174, -34, -231, -418, // 8 .. 15
- -596, -767, -931, -1090, -1243, -1392, -1536, -1676, // 16 .. 23
- -1813, -1946, -2076, -2203, -2328, -2450, -2569, -2687, // 24 .. 31
- -2802, -2915, -3026, -3136, -3243, -3349, -3454, -3557, // 32 .. 39
- -3658, -3759, -3857, -3955, -4051, -4147, -4241, -4334, // 40 .. 47
- -4425, -4516, -4606, -4695, -4783, -4870, -4957, -5042, // 48 .. 55
- -5127, -5211, -5294, -5377, -5459, -5540, -5622, -5702, // 56 .. 63
- -5783, -5863, -5942, -6022, -6101, -6180, -6259, -6338, // 64 .. 71
- -6417, -6495, -6574, -6653, -6731, -6810, -6889, -6968, // 72 .. 79
- -7048, -7127, -7207, -7287, -7367, -7448, -7530, -7611, // 80 .. 87
- -7693, -7776, -7860, -7944, -8029, -8114, -8201, -8288, // 88 .. 95
- -8377, -8466, -8557, -8649, -8743, -8838, -8935, -9034, // 96 .. 103
- -9135, -9239, -9345, -9455, -9568, -9684, -9806, -9933, // 104 .. 111
+ 6598, 4999, 3963, 3233, 2671, 2212, 1819, 1476, // 0 .. 7
+ 1168, 889, 633, 395, 174, -34, -231, -418, // 8 .. 15
+ -596, -767, -931, -1090, -1243, -1392, -1536, -1676, // 16 .. 23
+ -1813, -1946, -2076, -2203, -2328, -2450, -2569, -2687, // 24 .. 31
+ -2802, -2915, -3026, -3136, -3243, -3349, -3454, -3557, // 32 .. 39
+ -3658, -3759, -3857, -3955, -4051, -4147, -4241, -4334, // 40 .. 47
+ -4425, -4516, -4606, -4695, -4783, -4870, -4957, -5042, // 48 .. 55
+ -5127, -5211, -5294, -5377, -5459, -5540, -5622, -5702, // 56 .. 63
+ -5783, -5863, -5942, -6022, -6101, -6180, -6259, -6338, // 64 .. 71
+ -6417, -6495, -6574, -6653, -6731, -6810, -6889, -6968, // 72 .. 79
+ -7048, -7127, -7207, -7287, -7367, -7448, -7530, -7611, // 80 .. 87
+ -7693, -7776, -7860, -7944, -8029, -8114, -8201, -8288, // 88 .. 95
+ -8377, -8466, -8557, -8649, -8743, -8838, -8935, -9034, // 96 .. 103
+ -9135, -9239, -9345, -9455, -9568, -9684, -9806, -9933, // 104 .. 111
};
///////////////////////////////////////////////////////////////////////////////
@@ -2762,7 +2762,7 @@ int GetVr2DiffByTab ( int diff ) // diff = VR(winner) - VR(loser)
const s16 search = diff;
int i = 0, j = sizeof(vr2_diff_tab) / sizeof(*vr2_diff_tab) - 1;
-
+
while ( i < j )
{
const int k = (i+j)/2;
@@ -3370,6 +3370,87 @@ static enumError test_timezone ( int argc, char ** argv )
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// test_timeadjust() ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+
+static enumError test_timeadjust ( int argc, char ** argv )
+{
+ SetupTimezone(true);
+ printf("timezone_adjust_sec=%lld, _usec=%lld\n",
+ timezone_adjust_sec, timezone_adjust_usec );
+
+ time_t gmt = time(0);
+ struct tm tm1;
+ gmtime_r(&gmt,&tm1);
+ printf("> %02d:%02d\n",tm1.tm_hour,tm1.tm_min);
+ struct tm *tm2 = gmtime(&gmt);
+ printf("> %02d:%02d\n",tm2->tm_hour,tm2->tm_min);
+
+ static ccp tztab[] =
+ {
+ "UTC",
+ "Europe/Berlin",
+ "America/Detroit",
+ 0
+ };
+
+ ccp *tzptr;
+ for ( tzptr = tztab; *tzptr; tzptr++ )
+ {
+ printf("----- TZ: %s -----\n",*tzptr);
+ setenv("TZ",*tzptr,1);
+ tzset();
+
+ int prev_delta = -1;
+ time_t tim;
+ for ( tim = 1577664030; tim < 1609545600; tim++ )
+ {
+ struct tm gmt, loc;
+ gmtime_r(&tim,&gmt);
+ localtime_r(&tim,&loc);
+ int delta = ( gmt.tm_hour - loc.tm_hour ) * 3600
+ + ( gmt.tm_min - loc.tm_min ) * 60
+ + ( gmt.tm_sec - loc.tm_sec );
+ if ( gmt.tm_yday != loc.tm_yday )
+ {
+ if ( gmt.tm_year < loc.tm_year
+ || gmt.tm_year == loc.tm_year && gmt.tm_yday < loc.tm_yday )
+ {
+ delta -= 24*3600;
+ }
+ else
+ {
+ delta += 24*3600;
+ }
+ }
+
+ const int adj = GetTimezoneAdjust(tim);
+ if ( delta != prev_delta || delta != adj )
+ {
+ prev_delta = delta;
+ printf("%6d | %03u %04u-%02u-%02u %2u:%02u:%02u |"
+ " %03u %04u-%02u-%02u %2u:%02u:%02u",
+ delta,
+ gmt.tm_yday,
+ gmt.tm_year+1900, gmt.tm_mon+1, gmt.tm_mday,
+ gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
+ loc.tm_yday,
+ loc.tm_year+1900, loc.tm_mon+1, loc.tm_mday,
+ loc.tm_hour, loc.tm_min, loc.tm_sec );
+ if ( delta != adj )
+ printf(" | %6d\n",adj);
+ else
+ putchar('\n');
+ }
+ }
+ }
+ return ERR_OK;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// test_condition() ///////////////
///////////////////////////////////////////////////////////////////////////////
@@ -3528,6 +3609,54 @@ static enumError test_in_arch ( int argc, char ** argv )
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// test_slot_attrib() ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+static enumError test_slot_attrib ( int argc, char ** argv )
+{
+ int i;
+ for ( i = 1; i < argc; i++ )
+ {
+ printf("\n\e[1;33;44m %s \e[0m\n",argv[i]);
+ slot_info_t si = GetSlotByName(MemByString(argv[i]),true);
+ DumpSlotInfo(stdout,2,&si,true);
+ }
+ return 0;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// test_slot_info() ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+static enumError test_slot_info ( int argc, char ** argv )
+{
+ int i;
+ for ( i = 1; i < argc; i++ )
+ {
+ printf("\n> %s\n",argv[i]);
+
+ szs_file_t szs;
+ InitializeSZS(&szs);
+ enumError err = LoadCreateSZS(&szs,argv[i],true,false,true);
+ if (err)
+ return err;
+
+ slot_ana_t sa;
+ AnalyzeSlot(&sa,&szs);
+ ccp slot_info = CreateSlotInfo(&szs);
+ printf("stat=%d, req=%d: %s\n\t%s\n\t%s%s\n",
+ sa.stat, sa.required_slot, sa.mandatory_slot,
+ sa.slot_info, slot_info,
+ strcmp(sa.slot_info,slot_info) ? " \e[31;1mFAIL!\e[0m" : "" );
+
+ ResetSZS(&szs);
+ }
+ return 0;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// develop() ///////////////
///////////////////////////////////////////////////////////////////////////////
@@ -3741,9 +3870,12 @@ enum
CMD_ITEMSLOT, // test_item_slot(argc,argv)
CMD_SINCE2001, // test_since2001(argc,argv)
CMD_TIMEZONE, // test_timezone(argc,argv)
+ CMD_TIMEADJUST, // test_timeadjust(argc,argv)
CMD_CONDITION, // test_condition(argc,argv)
CMD_XBIT, // test_xbit(argc,argv)
CMD_IN_ARCH, // test_in_arch(argc,argv)
+ CMD_SLOT_ATTRIB, // test_slot_attrib(argc,argv)
+ CMD_SLOT_INFO, // test_slot_info(argc,argv)
CMD__N
};
@@ -3794,9 +3926,12 @@ static const KeywordTab_t CommandTab[] =
{ CMD_ITEMSLOT, "ITEM-SLOT", "IS", 0 },
{ CMD_SINCE2001, "SINCE2001", "S2", 0 },
{ CMD_TIMEZONE, "TIMEZONE", "TZ", 0 },
+ { CMD_TIMEADJUST, "TIMEADJUST", "TA", 0 },
{ CMD_CONDITION, "CONDITION", "CO", 0 },
{ CMD_XBIT, "XBIT", 0, 0 },
{ CMD_IN_ARCH, "IN-ARCH", "INARCH", 0 },
+ { CMD_SLOT_ATTRIB, "SLOT-ATTRIB", "SA", 0 },
+ { CMD_SLOT_INFO, "SLOT-INFO", "SI", 0 },
{ CMD__N,0,0,0 }
};
@@ -3918,9 +4053,12 @@ int main ( int argc, char ** argv )
case CMD_ITEMSLOT: test_item_slot(argc,argv); break;
case CMD_SINCE2001: test_since2001(argc,argv); break;
case CMD_TIMEZONE: test_timezone(argc,argv); break;
+ case CMD_TIMEADJUST: test_timeadjust(argc,argv); break;
case CMD_CONDITION: test_condition(argc,argv); break;
case CMD_XBIT: test_xbit(argc,argv); break;
case CMD_IN_ARCH: test_in_arch(argc,argv); break;
+ case CMD_SLOT_ATTRIB: test_slot_attrib(argc,argv); break;
+ case CMD_SLOT_INFO: test_slot_info(argc,argv); break;
//case CMD_HELP:
default:
help_exit();