aboutsummaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--project/Makefile7
-rw-r--r--project/dclib/dclib-basics.c18
-rw-r--r--project/dclib/dclib-basics.h25
-rw-r--r--project/dclib/dclib-debug.c1
-rw-r--r--project/dclib/dclib-file.c243
-rw-r--r--project/dclib/dclib-numeric.c35
-rw-r--r--[-rwxr-xr-x]project/dclib/lib-bmg.c63
-rw-r--r--[-rwxr-xr-x]project/dclib/lib-bmg.h2
-rw-r--r--[-rwxr-xr-x]project/gen-template.sh0
-rw-r--r--[-rwxr-xr-x]project/gen-text-file.sh0
-rw-r--r--project/makefiles-local/Makefile.local.mac23
-rw-r--r--project/revision.sh2
-rw-r--r--[-rwxr-xr-x]project/scripts/create-brres-lists.sh0
-rw-r--r--[-rwxr-xr-x]project/scripts/test-wszst.sh0
-rw-r--r--[-rwxr-xr-x]project/setup/cygwin-copy.sh0
-rw-r--r--[-rwxr-xr-x]project/setup/install.sh0
-rw-r--r--[-rwxr-xr-x]project/setup/windows-install.sh0
-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
-rw-r--r--project/templates/HISTORY.txt15
-rw-r--r--project/templates/module/last-history.txt12
-rw-r--r--[-rwxr-xr-x]project/text-files/distrib.inc/distrib-head-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/itemslot.inc/itemslot-head-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/itemslot.inc/itemslot-info-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/itemslot.inc/itemslot-param-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/itemslot.inc/itemslot-setup-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/itemslot.inc/itemslot-table-cr.inc0
-rw-r--r--project/text-files/kmp.inc/kmp-gobj-cr.inc6
-rw-r--r--project/text-files/kmp.inc/kmp-ktpt-cr.inc4
-rw-r--r--project/text-files/kmp.inc/kmp-pt-info-cr.inc12
-rw-r--r--project/text-files/kmp.inc/kmp-pt2-cr.inc4
-rw-r--r--[-rwxr-xr-x]project/text-files/lex.inc/lex-elem-hipt-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/lex.inc/lex-head-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/lex.inc/lex-hexdump-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/lex.inc/lex-setup-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/mdl.inc/mdl-hexdump-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-head-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-info-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-param-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-setup-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-table-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/minigame.inc/minigame-table-head-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/setup.inc/setup-create-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/setup.inc/setup-encode-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/setup.inc/setup-exclude-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/setup.inc/setup-header-cr.inc0
-rw-r--r--[-rwxr-xr-x]project/text-files/setup.inc/setup-include-cr.inc0
62 files changed, 1034 insertions, 285 deletions
diff --git a/project/Makefile b/project/Makefile
index d36fb5e..3b0061e 100644
--- a/project/Makefile
+++ b/project/Makefile
@@ -127,7 +127,7 @@ DIR_LIST =
RM_FILES = *.{a,o,d,tmp,bak,exe} edit-list/*.log
RM_FILES += */*.{tmp,bak} */*/*.{tmp,bak} */*/*/*.{tmp,bak}
-RM_FILES2 = templates.sed
+RM_FILES2 = templates.sed Makefile.setup
MODE_FILE = ./_mode.flag
MODE = $(shell test -s $(MODE_FILE) && cat $(MODE_FILE))
@@ -248,8 +248,9 @@ TOBJ_wlect = lib-lecode.o lib-ctcode.o lib-xbmg.o db-ctcode.o \
TOBJ_wmdlt = lib-mdl.o lib-transform.o $(XOBJ_PARSER) $(XOBJ_OBJECT)
TOBJ_wpatt = lib-pat.o $(XOBJ_PARSER) $(XOBJ_OBJECT)
TOBJ_wstrt = lib-staticr.o db-dol.o db-ctcode.o $(XOBJ_OBJECT)
-TOBJ_wtest = $(XOBJ_KMP) $(XOBJ_KCL) $(XOBJ_OBJECT) $(XOBJ_PARSER) $(XOBJ_IMAGE) \
- lib-mdl.o lib-transform.o
+TOBJ_wtest = lib-szs-create.o lib-xbmg.o lib-ctcode.o lib-lecode.o \
+ lib-mdl.o lib-pat.o lib-transform.o \
+ $(XOBJ_KMP) $(XOBJ_KCL) $(XOBJ_OBJECT) $(XOBJ_PARSER) $(XOBJ_IMAGE)
#-------------------------------------------------------------------------------
# sub libs
diff --git a/project/dclib/dclib-basics.c b/project/dclib/dclib-basics.c
index 74676d0..c46f5e2 100644
--- a/project/dclib/dclib-basics.c
+++ b/project/dclib/dclib-basics.c
@@ -1800,7 +1800,7 @@ void AppendInt64FastBuf ( FastBuf_t *fb, u64 val, IntMode_t mode )
///////////////////////////////////////////////////////////////////////////////
-char * WriteFastBuf ( FastBuf_t *fb, uint offset, cvp source, int size )
+char * WriteFastBuf ( FastBuf_t *fb, uint offset, cvp source, int size )
{
DASSERT(fb);
@@ -1847,6 +1847,22 @@ uint AssignFastBuf ( FastBuf_t *fb, cvp source, int size )
///////////////////////////////////////////////////////////////////////////////
+uint AlignFastBuf ( FastBuf_t *fb, uint align, u8 fill )
+{
+ DASSERT(fb);
+ const uint len = fb->ptr - fb->buf;
+ const uint append = ALIGN32(len,align) - len;
+ if ( append > 0 )
+ {
+ char *dest = GetSpaceFastBuf(fb,append);
+ memset(dest,fill,append);
+ }
+
+ return fb->ptr - fb->buf;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
uint DropFastBuf ( FastBuf_t *fb, int index, int size )
{
DASSERT(fb);
diff --git a/project/dclib/dclib-basics.h b/project/dclib/dclib-basics.h
index 7c6e7a2..eb4c40a 100644
--- a/project/dclib/dclib-basics.h
+++ b/project/dclib/dclib-basics.h
@@ -1531,6 +1531,7 @@ uint InsertFastBuf ( FastBuf_t *fb, int index, cvp source, int size );
char * AppendFastBuf ( FastBuf_t *fb, cvp source, int size );
char * WriteFastBuf ( FastBuf_t *fb, uint offset, cvp source, int size );
uint AssignFastBuf ( FastBuf_t *fb, cvp source, int size );
+uint AlignFastBuf ( FastBuf_t *fb, uint align, u8 fill );
uint DropFastBuf ( FastBuf_t *fb, int index, int size );
void CopyFastBuf ( FastBuf_t *dest, const FastBuf_t *src );
@@ -2134,6 +2135,10 @@ typedef enum EncodeMode_t // select encodig/decoding method
}
EncodeMode_t;
+// [[doxygen]]
+static inline bool NeedsQuotesByEncoding ( EncodeMode_t em )
+ { return em < ENCODE_BASE64 || em > ENCODE_BASE64XML; }
+
///////////////////////////////////////////////////////////////////////////////
// [[DecodeType_t]]
@@ -3355,6 +3360,7 @@ extern int timezone_adjust_isdst;
///////////////////////////////////////////////////////////////////////////////
void SetupTimezone ( bool force );
+int GetTimezoneAdjust ( time_t tim );
struct timeval GetTimeOfDay ( bool localtime );
DayTime_t GetDayTime ( bool localtime );
@@ -4891,9 +4897,12 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_STR_SIZE(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_SIZE,e)
#define DEF_SRT_STR_ALLOC(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_ALLOC,e)
#define DEF_SRT_MEM(v,n,e) DEF_SRT_VAR(v,1,n,SRT_MEM,e)
+
#define DEF_SRT_STRING_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_FIELD,e)
#define DEF_SRT_PARAM_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_PARAM_FIELD,e)
+//--- n elements
+
#define DEF_SRT_BOOL_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_BOOL,0)
#define DEF_SRT_UINT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_UINT,0)
#define DEF_SRT_HEX_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_HEX,0)
@@ -4901,6 +4910,14 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_FLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_FLOAT,0)
#define DEF_SRT_XFLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_XFLOAT,0)
+#if defined(TEST) || defined(DEBUG)
+#define DEF_SRT_STR_SIZE_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_SIZE,e)
+#define DEF_SRT_STR_ALLOC_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_ALLOC,e)
+#define DEF_SRT_MEM_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_MEM,e)
+#endif
+
+//--- auto array
+
#define DEF_SRT_ARRAY(v,n,t,e) \
{offsetof(SRT_NAME,v), sizeof(((SRT_NAME*)0)->v[0]), n, \
sizeof(((SRT_NAME*)0)->v)/sizeof(*((SRT_NAME*)0)->v), t, e }
@@ -4912,6 +4929,14 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_FLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_FLOAT,0)
#define DEF_SRT_XFLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_XFLOAT,0)
+#if defined(TEST) || defined(DEBUG)
+#define DEF_SRT_STR_SIZE_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_SIZE,e)
+#define DEF_SRT_STR_ALLOC_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_ALLOC,e)
+#define DEF_SRT_MEM_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_MEM,e)
+#endif
+
+//--- special
+
#define DEF_SRT_SEPARATOR() {0,0,0,0,SRT__IS_LIST,0}
#define DEF_SRT_COMMENT(c) {0,0,c,0,SRT__IS_LIST,0}
#define DEF_SRT_TERM() {0,0,0,0,SRT__TERM,0}
diff --git a/project/dclib/dclib-debug.c b/project/dclib/dclib-debug.c
index 506be18..fd51f17 100644
--- a/project/dclib/dclib-debug.c
+++ b/project/dclib/dclib-debug.c
@@ -579,6 +579,7 @@ bool mark_used ( ccp name, ... )
#if HAVE_PRINT
+ #undef PRINT_TIME
void PRINT_TIME ( time_t time, ccp title )
{
struct tm utc, loc;
diff --git a/project/dclib/dclib-file.c b/project/dclib/dclib-file.c
index 8a69370..b7f1702 100644
--- a/project/dclib/dclib-file.c
+++ b/project/dclib/dclib-file.c
@@ -4502,6 +4502,53 @@ static void print_scs_name ( FILE *f, int fw, int use_tab, ccp format, ... )
//-----------------------------------------------------------------------------
+static u64 SCS_get_uint ( const u8* data, int idx, const SaveRestoreTab_t *srt )
+{
+ DASSERT(srt);
+ DASSERT(srt->var);
+
+ switch(srt->size)
+ {
+ case 1: return ((u8*) (data+srt->offset))[idx];
+ case 2: return ((u16*)(data+srt->offset))[idx];
+ case 4: return ((u32*)(data+srt->offset))[idx];
+ case 8: return ((u64*)(data+srt->offset))[idx];
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+static s64 SCS_get_int ( const u8* data, int idx, const SaveRestoreTab_t *srt )
+{
+ DASSERT(srt);
+ DASSERT(srt->var);
+
+ switch(srt->size)
+ {
+ case 1: return ((s8*) (data+srt->offset))[idx];
+ case 2: return ((s16*)(data+srt->offset))[idx];
+ case 4: return ((s32*)(data+srt->offset))[idx];
+ case 8: return ((s64*)(data+srt->offset))[idx];
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+static void SCS_save_string ( FILE *f, ccp src, int slen, EncodeMode_t emode )
+{
+ char buf[4000];
+ mem_t res = EncodeByModeMem(buf,sizeof(buf),src,slen,emode);
+
+ fwrite(res.ptr,1,res.len,f);
+ fputc('\n',f);
+ if ( res.ptr != buf )
+ FreeMem(&res);
+}
+
+//-----------------------------------------------------------------------------
+
void SaveCurrentStateByTable
(
FILE *f, // valid output file
@@ -4548,53 +4595,6 @@ void SaveCurrentStateByTable
//-------------------------------------------------------------------------
- u64 get_uint ( const u8* data, int idx, const SaveRestoreTab_t *srt )
- {
- DASSERT(srt);
- DASSERT(srt->var);
-
- switch(srt->size)
- {
- case 1: return ((u8*) (data+srt->offset))[idx];
- case 2: return ((u16*)(data+srt->offset))[idx];
- case 4: return ((u32*)(data+srt->offset))[idx];
- case 8: return ((u64*)(data+srt->offset))[idx];
- }
- return 0;
- }
-
- //-------------------------------------------------------------------------
-
- s64 get_int ( const u8* data, int idx, const SaveRestoreTab_t *srt )
- {
- DASSERT(srt);
- DASSERT(srt->var);
-
- switch(srt->size)
- {
- case 1: return ((s8*) (data+srt->offset))[idx];
- case 2: return ((s16*)(data+srt->offset))[idx];
- case 4: return ((s32*)(data+srt->offset))[idx];
- case 8: return ((s64*)(data+srt->offset))[idx];
- }
- return 0;
- }
-
- //-------------------------------------------------------------------------
-
- void save_string ( FILE *f, ccp src, int slen, EncodeMode_t emode )
- {
- char buf[4000];
- mem_t res = EncodeByModeMem(buf,sizeof(buf),src,slen,emode);
-
- fwrite(res.ptr,1,res.len,f);
- fputc('\n',f);
- if ( res.ptr != buf )
- FreeMem(&res);
- }
-
- //-------------------------------------------------------------------------
-
const u8 *data = data0;
for ( ; srt->type != SRT__TERM; srt++ )
@@ -4614,54 +4614,51 @@ void SaveCurrentStateByTable
if ( srt->type < SRT__IS_LIST )
print_scs_name(f,fw_name,use_tab,"%s%s",prefix,srt->name);
+ uint i, offset;
switch(srt->type)
{
case SRT_BOOL:
if ( srt->n_elem > 1 )
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%u", i ? "," : "", get_uint(data,i,srt)!=0 );
+ fprintf(f,"%s%u", i ? "," : "", SCS_get_uint(data,i,srt)!=0 );
fputc('\n',f);
}
else
- fprintf(f,"%u\n",get_uint(data,0,srt)!=0);
+ fprintf(f,"%u\n",SCS_get_uint(data,0,srt)!=0);
break;
case SRT_UINT:
if ( srt->n_elem > 1 )
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%llu", i ? "," : "", get_uint(data,i,srt) );
+ fprintf(f,"%s%llu", i ? "," : "", SCS_get_uint(data,i,srt) );
fputc('\n',f);
}
else
- fprintf(f,"%llu\n",get_uint(data,0,srt));
+ fprintf(f,"%llu\n",SCS_get_uint(data,0,srt));
break;
case SRT_HEX:
if ( srt->n_elem > 1 )
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%#llx", i ? "," : "", get_uint(data,i,srt) );
+ fprintf(f,"%s%#llx", i ? "," : "", SCS_get_uint(data,i,srt) );
fputc('\n',f);
}
else
- fprintf(f,"%#llx\n",get_uint(data,0,srt));
+ fprintf(f,"%#llx\n",SCS_get_uint(data,0,srt));
break;
case SRT_INT:
if ( srt->n_elem > 1 )
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%lld", i ? "," : "", get_int(data,i,srt) );
+ fprintf(f,"%s%lld", i ? "," : "", SCS_get_int(data,i,srt) );
fputc('\n',f);
}
else
- fprintf(f,"%lld\n",get_int(data,0,srt));
+ fprintf(f,"%lld\n",SCS_get_int(data,0,srt));
break;
case SRT_FLOAT:
@@ -4669,7 +4666,6 @@ void SaveCurrentStateByTable
{
case sizeof(float):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%.8g", i ? "," : "",
((float*)(data+srt->offset))[i] );
@@ -4678,7 +4674,6 @@ void SaveCurrentStateByTable
case sizeof(double):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%.16g", i ? "," : "",
((double*)(data+srt->offset))[i] );
@@ -4687,7 +4682,6 @@ void SaveCurrentStateByTable
case sizeof(long double):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%.20Lg", i ? "," : "",
((long double*)(data+srt->offset))[i] );
@@ -4705,7 +4699,6 @@ void SaveCurrentStateByTable
{
case sizeof(float):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%a", i ? "," : "",
((float*)(data+srt->offset))[i] );
@@ -4714,7 +4707,6 @@ void SaveCurrentStateByTable
case sizeof(double):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%a", i ? "," : "",
((double*)(data+srt->offset))[i] );
@@ -4723,7 +4715,6 @@ void SaveCurrentStateByTable
case sizeof(long double):
{
- uint i;
for ( i = 0; i < srt->n_elem; i++ )
fprintf(f,"%s%La", i ? "," : "",
((long double*)(data+srt->offset))[i] );
@@ -4739,17 +4730,38 @@ void SaveCurrentStateByTable
//-----
case SRT_STRING_SIZE:
- save_string(f,(char*)(data+srt->offset),-1,srt->emode);
+ for ( i = 0, offset = srt->offset;; offset += srt->size )
+ {
+ SCS_save_string(f,(char*)(data+offset),-1,srt->emode);
+ if ( ++i == srt->n_elem )
+ break;
+ fputc(',',f);
+ }
+ fputc('\n',f);
break;
case SRT_STRING_ALLOC:
- save_string(f,*(ccp*)(data+srt->offset),-1,srt->emode);
+ for ( i = 0, offset = srt->offset;; offset += srt->size )
+ {
+ SCS_save_string(f,*(ccp*)(data+offset),-1,srt->emode);
+ if ( ++i == srt->n_elem )
+ break;
+ fputc(',',f);
+ }
+ fputc('\n',f);
break;
case SRT_MEM:
{
- mem_t *mem = (mem_t*)(data+srt->offset);
- save_string(f,mem->ptr,mem->len,srt->emode);
+ for ( i = 0, offset = srt->offset;; offset += srt->size )
+ {
+ mem_t *mem = (mem_t*)(data+offset);
+ SCS_save_string(f,mem->ptr,mem->len,srt->emode);
+ if ( ++i == srt->n_elem )
+ break;
+ fputc(',',f);
+ }
+ fputc('\n',f);
break;
}
@@ -4766,7 +4778,7 @@ void SaveCurrentStateByTable
for ( i = 0; i < sf->used; i++, ptr++ )
{
print_scs_name(f,fw_name,use_tab,"%s%s@%u",prefix,srt->name,i);
- save_string(f,*ptr,-1,srt->emode);
+ SCS_save_string(f,*ptr,-1,srt->emode);
}
break;
}
@@ -4783,7 +4795,7 @@ void SaveCurrentStateByTable
{
print_scs_name(f,fw_name,use_tab,"%s%s@%u",prefix,srt->name,i);
fprintf(f,"%d ",ptr->num);
- save_string(f,ptr->key,-1,srt->emode);
+ SCS_save_string(f,ptr->key,-1,srt->emode);
}
break;
}
@@ -4794,6 +4806,13 @@ void SaveCurrentStateByTable
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+#if defined(TEST) && 1
+ #define X_DEVELOP 1
+#else
+ #define X_DEVELOP 0
+#endif
+
+
void RestoreStateByTable
(
RestoreState_t *rs, // info data, can be modified (cleaned after call)
@@ -4805,6 +4824,71 @@ void RestoreStateByTable
DASSERT(rs);
DASSERT(srt);
+ //-------------------------------------------------------------------------
+
+#if X_DEVELOP
+
+ mem_t get_string
+ ( mem_t *param, ccp *p_ptr, char *buf, uint bufsize, EncodeMode_t emode )
+ {
+ DASSERT(param);
+ DASSERT(p_ptr);
+
+ ccp ptr;
+ if (!*p_ptr)
+ ptr = param->ptr;
+ else
+ {
+ ptr = *p_ptr;
+ if ( *ptr != ',' )
+ return NullMem;
+ ptr++;
+ }
+
+ if ( *ptr == '%' )
+ {
+ *p_ptr = ptr;
+ return NullMem;
+ }
+
+ uint len;
+ ccp start, end = param->ptr + param->len;
+ if ( *ptr == '"' )
+ {
+ start = ++ptr;
+ for (;;)
+ {
+ if ( ptr == end )
+ {
+ len = ptr - start;
+ break;
+ }
+
+ const char ch = *ptr++;
+ if ( ch == '\\' && ptr < end )
+ ptr++;
+ else if ( ch == '"' )
+ {
+ len = ptr-start-1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ start = ptr;
+ while ( ptr < end && *ptr != ',' )
+ ptr++;
+ len = ptr - start;
+ }
+
+ *p_ptr = ptr;
+ return MemByStringS(start,len);
+ }
+#endif
+
+ //-------------------------------------------------------------------------
+
char buf[4000];
if (!prefix)
prefix = EmptyString;
@@ -4909,6 +4993,22 @@ void RestoreStateByTable
//-----
case SRT_STRING_SIZE:
+#if X_DEVELOP
+ {
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_t param = it ? MemByString((ccp)it->data) : EmptyMem;
+ PRINT1("param: [%u] |%.*s|\n",param.len,param.len,param.ptr);
+ ccp ptr = 0;
+ uint i;
+ for ( i = 0; i < srt->n_elem; i++ )
+ {
+ mem_t str = get_string(&param,&ptr,buf,sizeof(buf),srt->emode);
+ PRINT1("str: [%d,%u] |%.*s|\n",str.ptr!=0,str.len,str.len,str.ptr);
+ //if ( str.ptr != buf ) FreeMem(&str);
+ }
+ break;
+ }
+#else
{
char *val = (char*)(data+srt->offset);
mem_t res = GetParamFieldMEM(buf,sizeof(buf),rs,buf,
@@ -4918,6 +5018,7 @@ void RestoreStateByTable
FreeString(res.ptr);
break;
}
+#endif
case SRT_STRING_ALLOC:
{
diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c
index 572211a..9ffa16c 100644
--- a/project/dclib/dclib-numeric.c
+++ b/project/dclib/dclib-numeric.c
@@ -1799,15 +1799,7 @@ void SetupTimezone ( bool force )
{
if ( force || timezone_adjust_sec == -1 )
{
- tzset();
- timezone_adjust_sec = timezone;
-
- time_t tim = GetTimeSec(false);
- struct tm *tm = localtime(&tim);
- timezone_adjust_isdst = tm->tm_isdst;
- if (tm->tm_isdst)
- timezone_adjust_sec -= 3600;
-
+ timezone_adjust_sec = GetTimezoneAdjust(GetTimeSec(false));
timezone_adjust_usec = 1000000ll * timezone_adjust_sec;
TRACE("TZ: %s,%s, %ld, %d => %lld %lld\n",
tzname[0], tzname[1], timezone, daylight,
@@ -1817,6 +1809,31 @@ void SetupTimezone ( bool force )
///////////////////////////////////////////////////////////////////////////////
+int GetTimezoneAdjust ( time_t 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;
+ }
+ }
+ return delta;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
struct timeval GetTimeOfDay ( bool localtime )
{
static uint last_hour = 0;
diff --git a/project/dclib/lib-bmg.c b/project/dclib/lib-bmg.c
index 4e42c9c..639d940 100755..100644
--- a/project/dclib/lib-bmg.c
+++ b/project/dclib/lib-bmg.c
@@ -2173,6 +2173,14 @@ enumError ScanRawBMG ( bmg_t * bmg )
DASSERT(!memcmp(bh->magic,BMG_MAGIC,sizeof(bh->magic)));
u32 data_size = ntohl(bh->size);
+ bmg->encoding = bh->encoding;
+ if ( !bmg->encoding && data_size*BMG_LEGACY_BLOCK_SIZE <= bmg->data_size )
+ {
+ bmg->legacy = true;
+ bmg->encoding = BMG_ENC_CP1252;
+ data_size *= BMG_LEGACY_BLOCK_SIZE;
+ }
+
if ( data_size > bmg->data_size )
{
ERROR0(ERR_WARNING,
@@ -2188,7 +2196,6 @@ enumError ScanRawBMG ( bmg_t * bmg )
//--- check encoding
- bmg->encoding = bh->encoding;
switch (bmg->encoding)
{
case BMG_ENC_CP1252:
@@ -2670,7 +2677,9 @@ enumError ScanTextBMG ( bmg_t * bmg )
continue;
noPRINT("PARAM: %s = |%.*s|\n",namebuf,(int)(ptr-start),start);
- if (!strcmp(namebuf,"ENCODING"))
+ if (!strcmp(namebuf,"LEGACY"))
+ bmg->legacy = str2l(start,0,10) > 0;
+ else if (!strcmp(namebuf,"ENCODING"))
AssignEncodingBMG(bmg,str2l(start,0,10));
else if (!strcmp(namebuf,"BMG-MID"))
bmg->have_mid = str2ul(start,0,10) > 0;
@@ -3371,7 +3380,9 @@ enumError CreateRawBMG
//--- check encoding
- const int encoding = CheckEncodingBMG(opt_bmg_encoding,bmg->encoding);
+ const int encoding = bmg->legacy
+ ? BMG_ENC_CP1252
+ : CheckEncodingBMG(opt_bmg_encoding,bmg->encoding);
switch (encoding)
{
case BMG_ENC_CP1252:
@@ -3398,19 +3409,6 @@ enumError CreateRawBMG
}
- //--- count messages
-
-#if 0
- bmg_item_t *bi, *bi_end = bmg->item + bmg->item_used;
- u32 n_msg = 0;
-
- for ( bi = bmg->item; bi < bi_end; bi++ )
- {
- if (bi->text)
- n_msg++;
- }
-#endif
-
//--- count size of raw sections
uint total_raw_size = 0, raw_count = 0;
@@ -3430,14 +3428,15 @@ enumError CreateRawBMG
//--- calculate sizes
- const mem_t inf = GetFastBufMem(&bc.inf);
- const mem_t mid = GetFastBufMem(&bc.mid);
- const mem_t dat = GetFastBufMem(&bc.dat);
+ const mem_t inf = GetFastBufMem(&bc.inf);
+ const mem_t mid = GetFastBufMem(&bc.mid);
+ const mem_t dat = GetFastBufMem(&bc.dat);
- const u32 inf_size = ALIGN32( sizeof(bmg_inf_t) + inf.len, opt_bmg_align );
- const u32 dat_size = ALIGN32( sizeof(bmg_dat_t) + dat.len, opt_bmg_align );
+ const int align = bmg->legacy ? BMG_LEGACY_BLOCK_SIZE : opt_bmg_align;
+ const u32 inf_size = ALIGN32( sizeof(bmg_inf_t) + inf.len, align );
+ const u32 dat_size = ALIGN32( sizeof(bmg_dat_t) + dat.len, align );
const u32 mid_size = bc.have_mid
- ? ALIGN32( sizeof(bmg_mid_t) + mid.len, opt_bmg_align ) : 0;
+ ? ALIGN32( sizeof(bmg_mid_t) + mid.len, align ) : 0;
const u32 total_size = sizeof(bmg_header_t)
+ inf_size + dat_size + mid_size
@@ -3458,9 +3457,9 @@ enumError CreateRawBMG
//---- setup bmg header
bmg_header_t *bh = (bmg_header_t*)bmg->raw_data;
- bh->size = htonl(total_size);
+ bh->size = htonl( bmg->legacy ? total_size/BMG_LEGACY_BLOCK_SIZE: total_size );
bh->n_sections = htonl( ( bc.have_mid ? 3 : 2 ) + raw_count );
- bh->encoding = encoding;
+ bh->encoding = bmg->legacy ? 0 : encoding;
memcpy(bh->magic,BMG_MAGIC,sizeof(bh->magic));
u8 *dest = (u8*)(bh+1);
@@ -3841,6 +3840,10 @@ enumError SaveTextBMG
{
"%s"
"\r\n"
+ "# If 1, then enable legacy (GameCube) mode for old binary BMG files.\r\n"
+ "# If enabled, ENCODING is always CP1252.\r\n"
+ "@LEGACY = %u\r\n"
+ "\r\n"
"# Define encoding of BMG: 1=CP1252, 2=UTF-16/be, 3=Shift-JIS, 4=UTF-8\r\n"
"@ENCODING = %u\r\n"
"\r\n"
@@ -3893,7 +3896,10 @@ enumError SaveTextBMG
fprintf(F.f,"%s\r\n\r\n",BMG_TEXT_MAGIC);
HavePredifinedSlots(bmg);
- const int encoding = CheckEncodingBMG(opt_bmg_encoding,bmg->encoding);
+ bmg->legacy = bmg->legacy != 0;
+ const int encoding = bmg->legacy
+ ? BMG_ENC_CP1252
+ : CheckEncodingBMG(opt_bmg_encoding,bmg->encoding);
const bool print_settings // print only, if unusual
= encoding != BMG_ENC__DEFAULT
@@ -3911,19 +3917,20 @@ enumError SaveTextBMG
{
fprintf(F.f,text_param,
param_announce,
- encoding, bmg->have_mid, bmg->inf_size, abuf,
+ bmg->legacy, encoding, bmg->have_mid, bmg->inf_size, abuf,
bmg->use_color_names, bmg->use_mkw_messages );
param_announce = "";
}
else if ( brief_count < BRIEF_NO_MAGIC )
- fprintf(F.f,"@ENCODING = %u\r\n"
+ fprintf(F.f,"@LEGACY = %u\r\n"
+ "@ENCODING = %u\r\n"
"@BMG-MID = %u\r\n"
"@INF-SIZE = 0x%02x\r\n"
"@DEFAULT-ATTRIBS = %s\r\n"
"@COLOR-NAMES = %u\r\n"
"@MKW-MESSAGES = %u\r\n"
"\r\n",
- encoding, bmg->have_mid, bmg->inf_size, abuf,
+ bmg->legacy, encoding, bmg->have_mid, bmg->inf_size, abuf,
bmg->use_color_names, bmg->use_mkw_messages );
}
diff --git a/project/dclib/lib-bmg.h b/project/dclib/lib-bmg.h
index 9ab5967..590d93b 100755..100644
--- a/project/dclib/lib-bmg.h
+++ b/project/dclib/lib-bmg.h
@@ -48,6 +48,7 @@
#define BMG_ATTRIB_BUF_SIZE (10+4*BMG_ATTRIB_SIZE) // good buf size for attrib string
#define BMG_INF_MAX_SIZE (4+BMG_ATTRIB_SIZE) // max supported inf size
#define BMG_INF_LIMIT 1000 // max allowed inf size
+#define BMG_LEGACY_BLOCK_SIZE 32 // block size for legacy files
// [[xbuf]]
#define BMG_MSG_BUF_SIZE 20050 // good buf size for messages
@@ -772,6 +773,7 @@ typedef struct bmg_t
bmg_encoding_t encoding; // type of encoding
uint inf_size; // size of each 'inf' element
bool have_mid; // TRUE: enable MID1 creation
+ bool legacy; // TRUE: legacy (GameCube) mode enabled
u8 attrib[BMG_ATTRIB_SIZE];// attribute buffer for defaults
u16 attrib_used; // used size of 'attrib', ALIGN(4)
u8 use_color_names; // 0:off, 1:auto, 2:on
diff --git a/project/gen-template.sh b/project/gen-template.sh
index 7e137dd..7e137dd 100755..100644
--- a/project/gen-template.sh
+++ b/project/gen-template.sh
diff --git a/project/gen-text-file.sh b/project/gen-text-file.sh
index 428a8a9..428a8a9 100755..100644
--- a/project/gen-text-file.sh
+++ b/project/gen-text-file.sh
diff --git a/project/makefiles-local/Makefile.local.mac b/project/makefiles-local/Makefile.local.mac
index 419dac2..22e82e5 100644
--- a/project/makefiles-local/Makefile.local.mac
+++ b/project/makefiles-local/Makefile.local.mac
@@ -3,17 +3,21 @@
#-----------------------------------------------------------------------------
-SDKROOT = $(shell ls -d /Developer/SDKs/MacOSX* | tail -n1 )
-SDKVERSION = $(shell echo "$(SDKROOT)" | sed -E 's/.*MacOSX//; s/([0-9]*\.[0-9*]).*/\1/g' )
+.PHONY : mac-distrib
+mac-distrib: mac1 doc $(INSTALL_SCRIPTS) gen-mac-distrib
-CC = "gcc-4.0"
-CFLAGS += -mmacosx-version-min=${SDKVERSION} -isysroot ${SDKROOT}
-LDFLAGS += -mmacosx-version-min=${SDKVERSION} -isysroot ${SDKROOT}
+.PHONY : mac1
+mac1: mac-x86_64
-#-----------------------------------------------------------------------------
+ @echo
+ @echo "----- building universal binaries -----"
-.PHONY : mac-distrib
-mac-distrib: mac2 doc $(INSTALL_SCRIPTS) gen-mac-distrib
+ @for i in $(MAIN_TOOLS); do \
+ lipo -create bin/x86_64/$${i} -output $${i}; \
+ ln -f $${i} bin/$${i}; \
+ done
+ @rm -rf bin/x86_64
+ @echo "done"
.PHONY : mac2
mac2: mac-i386 mac-x86_64
@@ -85,12 +89,11 @@ gen-mac-distrib:
@cp -p $(DISTRIB_FILES) $(DISTRIB_PATH)
@ln -f $(MAIN_TOOLS) $(WDF_LINKS) $(DISTRIB_PATH)/bin
cp -p $(DOC_FILES) $(DISTRIB_PATH)/doc
-# @cp -p $(SCRIPTS)/*.{sh,txt} $(DISTRIB_PATH)/scripts
@chmod -R 755 $(DISTRIB_PATH)
-# @chmod a+x $(DISTRIB_PATH)/*.sh $(DISTRIB_PATH)/scripts/*.sh $(DISTRIB_PATH)/bin*/*
@chmod a+x $(DISTRIB_PATH)/*.sh $(DISTRIB_PATH)/bin*/*
@chmod -R a+X $(DISTRIB_PATH)
@tar -czf $(DISTRIB_PATH).tar.gz $(DISTRIB_PATH)
+ @ln $(DISTRIB_PATH).tar.gz latest-mac.tar.gz
diff --git a/project/revision.sh b/project/revision.sh
index de473d0..b0cd35e 100644
--- a/project/revision.sh
+++ b/project/revision.sh
@@ -1 +1 @@
-revision=8217
+revision=8226
diff --git a/project/scripts/create-brres-lists.sh b/project/scripts/create-brres-lists.sh
index 2f6669a..2f6669a 100755..100644
--- a/project/scripts/create-brres-lists.sh
+++ b/project/scripts/create-brres-lists.sh
diff --git a/project/scripts/test-wszst.sh b/project/scripts/test-wszst.sh
index ca4a22e..ca4a22e 100755..100644
--- a/project/scripts/test-wszst.sh
+++ b/project/scripts/test-wszst.sh
diff --git a/project/setup/cygwin-copy.sh b/project/setup/cygwin-copy.sh
index 3ce6c46..3ce6c46 100755..100644
--- a/project/setup/cygwin-copy.sh
+++ b/project/setup/cygwin-copy.sh
diff --git a/project/setup/install.sh b/project/setup/install.sh
index d39e8f9..d39e8f9 100755..100644
--- a/project/setup/install.sh
+++ b/project/setup/install.sh
diff --git a/project/setup/windows-install.sh b/project/setup/windows-install.sh
index 4dbd1bf..4dbd1bf 100755..100644
--- a/project/setup/windows-install.sh
+++ b/project/setup/windows-install.sh
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();
diff --git a/project/templates/HISTORY.txt b/project/templates/HISTORY.txt
index d546ea2..381cc41 100644
--- a/project/templates/HISTORY.txt
+++ b/project/templates/HISTORY.txt
@@ -388,6 +388,21 @@ szs v2.17a r8204 - 2020-05-12
find missed files. This has impact to command CHECK and option --auto-add.
+szs v2.18a r8217 - 2020-06-28
+
+ - wszst/wkmpt CHECK: Hints about self linked item routes and item routes with
+ exact 1 point. A warning is printed when both events apply for same route.
+ - Bug fix: The number of tables is set to 6 if writing a short binary
+ item-slot file (without tables for battles).
+ - wszst TEXT/BINARY: New options to patch KMG files: --kmg-limit=seconds to
+ limit the run time of battles and --kmg-copy=id to copy one slot definition
+ to the 9 other slots.
+ - Leseratte and I analysed the MKW internal VR calculations and adapted the
+ results into the tools. So the calculations are 100% identical now.
+ - Command wszst VR-RACE supports now up to 30 players for the VR calculation.
+ - KMP/CAME type 6 and the related route is excluded from any transformation.
+
+
@@MODULE(last-history.txt)@@
diff --git a/project/templates/module/last-history.txt b/project/templates/module/last-history.txt
index 97a5e29..ed0658e 100644
--- a/project/templates/module/last-history.txt
+++ b/project/templates/module/last-history.txt
@@ -1,16 +1,6 @@
szs v@@VERSION@@ r@@REV-NEXT@@ - @@@@-@@-@@
- - wszst/wkmpt CHECK: Hints about self linked item routes and item routes with
- exact 1 point. A warning is printed when both events apply for same route.
- - Bug fix: The number of tables is set to 6 if writing a short binary
- item-slot file (without tables for battles).
- - wszst TEXT/BINARY: New options to patch KMG files: --kmg-limit=seconds to
- limit the run time of battles and --kmg-copy=id to copy one slot definition
- to the 9 other slots.
- - Leseratte and I analysed the MKW internal VR calculations and adapted the
- results into the tools. So the calculations are 100% identical now.
- - Command wszst VR-RACE supports now up to 30 players for the VR calculation.
- - KMP/CAME type 6 and the related route is excluded from any transformation.
+ - Support of an old GameCube BMG variant (internally named "legacy").
~ - MDL support: Scanning a MDL file and transferring the data into an internal
~ format was already implemented, but only used for analysis purposes. Now it
diff --git a/project/text-files/distrib.inc/distrib-head-cr.inc b/project/text-files/distrib.inc/distrib-head-cr.inc
index bdb3862..bdb3862 100755..100644
--- a/project/text-files/distrib.inc/distrib-head-cr.inc
+++ b/project/text-files/distrib.inc/distrib-head-cr.inc
diff --git a/project/text-files/itemslot.inc/itemslot-head-cr.inc b/project/text-files/itemslot.inc/itemslot-head-cr.inc
index dbea88a..dbea88a 100755..100644
--- a/project/text-files/itemslot.inc/itemslot-head-cr.inc
+++ b/project/text-files/itemslot.inc/itemslot-head-cr.inc
diff --git a/project/text-files/itemslot.inc/itemslot-info-cr.inc b/project/text-files/itemslot.inc/itemslot-info-cr.inc
index 1d6c2a7..1d6c2a7 100755..100644
--- a/project/text-files/itemslot.inc/itemslot-info-cr.inc
+++ b/project/text-files/itemslot.inc/itemslot-info-cr.inc
diff --git a/project/text-files/itemslot.inc/itemslot-param-cr.inc b/project/text-files/itemslot.inc/itemslot-param-cr.inc
index 6e16e0e..6e16e0e 100755..100644
--- a/project/text-files/itemslot.inc/itemslot-param-cr.inc
+++ b/project/text-files/itemslot.inc/itemslot-param-cr.inc
diff --git a/project/text-files/itemslot.inc/itemslot-setup-cr.inc b/project/text-files/itemslot.inc/itemslot-setup-cr.inc
index c8d5b7c..c8d5b7c 100755..100644
--- a/project/text-files/itemslot.inc/itemslot-setup-cr.inc
+++ b/project/text-files/itemslot.inc/itemslot-setup-cr.inc
diff --git a/project/text-files/itemslot.inc/itemslot-table-cr.inc b/project/text-files/itemslot.inc/itemslot-table-cr.inc
index d7fe18b..d7fe18b 100755..100644
--- a/project/text-files/itemslot.inc/itemslot-table-cr.inc
+++ b/project/text-files/itemslot.inc/itemslot-table-cr.inc
diff --git a/project/text-files/kmp.inc/kmp-gobj-cr.inc b/project/text-files/kmp.inc/kmp-gobj-cr.inc
index 86943aa..a70d536 100644
--- a/project/text-files/kmp.inc/kmp-gobj-cr.inc
+++ b/project/text-files/kmp.inc/kmp-gobj-cr.inc
@@ -10,6 +10,11 @@
@GOBJ-HEAD-VALUE = %#x
@AUTO-ENEMY-ITEM = 0 # mode$test ? <item$star,item$mega> : 0
@AUTO-OBJECT-NAME = 0
+@SORT-OBJECTS = SORT$OFF # SORT$GROUPING SORT$ANGLE SORT$TINY
+
+# KCL-FALL (automatic height correction)
+# Define the following values here or at any place between the objects.
+# They are valid until re-defined. Disable this feature by @KCL-FALL-WIDTH=0.
@KCL-FALL-WIDTH = 0 # set to a value >0 (e.g. 200) to enable KCL falling
@KCL-FALL-PRE-ADD = 0 # add this height or vector before falling
@KCL-FALL-POST-ADD = 0 # add this height or vector after success
@@ -17,7 +22,6 @@
# Best values are:
# - KCL$BORDER: All KCL types except effects.
# - KCL$DRIVE: All driveable types like road, boost, ramp, water, ...
-@SORT-OBJECTS = SORT$OFF # SORT$GROUPING SORT$ANGLE SORT$TINY
#------------------------------------------------------------------------------
# Definition objects and references
diff --git a/project/text-files/kmp.inc/kmp-ktpt-cr.inc b/project/text-files/kmp.inc/kmp-ktpt-cr.inc
index b19a0b7..ed36444 100644
--- a/project/text-files/kmp.inc/kmp-ktpt-cr.inc
+++ b/project/text-files/kmp.inc/kmp-ktpt-cr.inc
@@ -8,6 +8,10 @@
@REVISION = %u
@KTPT-HEAD-VALUE = %#x
+
+# KCL-FALL (automatic height correction)
+# Define the following values here or at any place between the points.
+# They are valid until re-defined. Disable this feature by @KCL-FALL-WIDTH=0.
@KCL-FALL-WIDTH = 0 # set to a value >0 (e.g. 200) to enable KCL falling
@KCL-FALL-PRE-ADD = 0 # add this height or vector before falling
@KCL-FALL-POST-ADD = 0 # add this height or vector after success
diff --git a/project/text-files/kmp.inc/kmp-pt-info-cr.inc b/project/text-files/kmp.inc/kmp-pt-info-cr.inc
index 8a06663..f11d5a8 100644
--- a/project/text-files/kmp.inc/kmp-pt-info-cr.inc
+++ b/project/text-files/kmp.inc/kmp-pt-info-cr.inc
@@ -5,6 +5,13 @@
@AUTO-FILL = 0.0 # >1 (e.g. 5000): create more points if distance is larger
@AUTO-GROUP-NAME = 0
@ROTATE-GROUP-LINKS = 0
+@ROUTE-OBJECT = mode$showrt & %u ? -1 : 0 # 0=off, -1=use default, >0=object id
+@ROUTE-OBJECT-SHIFT = $NONE # v3(0) # add vector to position
+@ROUTE-OBJECT-SCALE = $NONE # v3(1) # define vector scale
+
+# KCL-FALL (automatic height correction)
+# Define the following values here or at any place between the points.
+# They are valid until re-defined. Disable this feature by @KCL-FALL-WIDTH=0.
@KCL-FALL-WIDTH = 0 # set to a value >0 (e.g. 200) to enable KCL falling
@KCL-FALL-PRE-ADD = 0 # add this height or vector before falling
@KCL-FALL-POST-ADD = 0 # add this height or vector after success
@@ -12,11 +19,8 @@
# Best values are:
# - KCL$BORDER: All KCL types except effects.
# - KCL$DRIVE: All driveable types like road, boost, ramp, water, ...
-@ROUTE-OBJECT = mode$showrt & %u ? -1 : 0 # 0=off, -1=use default, >0=object id
-@ROUTE-OBJECT-SHIFT = $NONE # v3(0) # add vector to position
-@ROUTE-OBJECT-SCALE = $NONE # v3(1) # define vector scale
-# Column 'flag' is optional and ususally only used internally.
+# Column 'flag' is optional and usually only used internally.
# Syntax: FLAGS_STRING or '(' EXPRESSION ')'
# F (F$FALL): Point can be used for FALL-DOWN functionality.
# S (F$SNAP): Point can be used for SNAP functionality (ignored by ITPT).
diff --git a/project/text-files/kmp.inc/kmp-pt2-cr.inc b/project/text-files/kmp.inc/kmp-pt2-cr.inc
index e7ee696..677cb29 100644
--- a/project/text-files/kmp.inc/kmp-pt2-cr.inc
+++ b/project/text-files/kmp.inc/kmp-pt2-cr.inc
@@ -3,7 +3,9 @@
@%s-HEAD-VALUE = %#x
@AUTO-ID = %u
-# Activate automatic Y-correction (KCL fall)
+# KCL-FALL (automatic height correction)
+# Define the following values here or at any place between the points.
+# They are valid until re-defined. Disable this feature by @KCL-FALL-WIDTH=0.
@KCL-FALL-WIDTH = 0 # set to a value >0 (e.g. 200) to enable KCL falling
@KCL-FALL-PRE-ADD = 0 # add this height or vector before falling
@KCL-FALL-POST-ADD = 0 # add this height or vector after success
diff --git a/project/text-files/lex.inc/lex-elem-hipt-cr.inc b/project/text-files/lex.inc/lex-elem-hipt-cr.inc
index 479099e..479099e 100755..100644
--- a/project/text-files/lex.inc/lex-elem-hipt-cr.inc
+++ b/project/text-files/lex.inc/lex-elem-hipt-cr.inc
diff --git a/project/text-files/lex.inc/lex-head-cr.inc b/project/text-files/lex.inc/lex-head-cr.inc
index 5c94c39..5c94c39 100755..100644
--- a/project/text-files/lex.inc/lex-head-cr.inc
+++ b/project/text-files/lex.inc/lex-head-cr.inc
diff --git a/project/text-files/lex.inc/lex-hexdump-cr.inc b/project/text-files/lex.inc/lex-hexdump-cr.inc
index 156281f..156281f 100755..100644
--- a/project/text-files/lex.inc/lex-hexdump-cr.inc
+++ b/project/text-files/lex.inc/lex-hexdump-cr.inc
diff --git a/project/text-files/lex.inc/lex-setup-cr.inc b/project/text-files/lex.inc/lex-setup-cr.inc
index d56bfdb..d56bfdb 100755..100644
--- a/project/text-files/lex.inc/lex-setup-cr.inc
+++ b/project/text-files/lex.inc/lex-setup-cr.inc
diff --git a/project/text-files/mdl.inc/mdl-hexdump-cr.inc b/project/text-files/mdl.inc/mdl-hexdump-cr.inc
index caa6029..caa6029 100755..100644
--- a/project/text-files/mdl.inc/mdl-hexdump-cr.inc
+++ b/project/text-files/mdl.inc/mdl-hexdump-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-head-cr.inc b/project/text-files/minigame.inc/minigame-head-cr.inc
index 2cf6953..2cf6953 100755..100644
--- a/project/text-files/minigame.inc/minigame-head-cr.inc
+++ b/project/text-files/minigame.inc/minigame-head-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-info-cr.inc b/project/text-files/minigame.inc/minigame-info-cr.inc
index 20aa095..20aa095 100755..100644
--- a/project/text-files/minigame.inc/minigame-info-cr.inc
+++ b/project/text-files/minigame.inc/minigame-info-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-param-cr.inc b/project/text-files/minigame.inc/minigame-param-cr.inc
index 286c2e0..286c2e0 100755..100644
--- a/project/text-files/minigame.inc/minigame-param-cr.inc
+++ b/project/text-files/minigame.inc/minigame-param-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-setup-cr.inc b/project/text-files/minigame.inc/minigame-setup-cr.inc
index c8d5b7c..c8d5b7c 100755..100644
--- a/project/text-files/minigame.inc/minigame-setup-cr.inc
+++ b/project/text-files/minigame.inc/minigame-setup-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-table-cr.inc b/project/text-files/minigame.inc/minigame-table-cr.inc
index 80700c0..80700c0 100755..100644
--- a/project/text-files/minigame.inc/minigame-table-cr.inc
+++ b/project/text-files/minigame.inc/minigame-table-cr.inc
diff --git a/project/text-files/minigame.inc/minigame-table-head-cr.inc b/project/text-files/minigame.inc/minigame-table-head-cr.inc
index 5737e65..5737e65 100755..100644
--- a/project/text-files/minigame.inc/minigame-table-head-cr.inc
+++ b/project/text-files/minigame.inc/minigame-table-head-cr.inc
diff --git a/project/text-files/setup.inc/setup-create-cr.inc b/project/text-files/setup.inc/setup-create-cr.inc
index 1442584..1442584 100755..100644
--- a/project/text-files/setup.inc/setup-create-cr.inc
+++ b/project/text-files/setup.inc/setup-create-cr.inc
diff --git a/project/text-files/setup.inc/setup-encode-cr.inc b/project/text-files/setup.inc/setup-encode-cr.inc
index 9775867..9775867 100755..100644
--- a/project/text-files/setup.inc/setup-encode-cr.inc
+++ b/project/text-files/setup.inc/setup-encode-cr.inc
diff --git a/project/text-files/setup.inc/setup-exclude-cr.inc b/project/text-files/setup.inc/setup-exclude-cr.inc
index 3800343..3800343 100755..100644
--- a/project/text-files/setup.inc/setup-exclude-cr.inc
+++ b/project/text-files/setup.inc/setup-exclude-cr.inc
diff --git a/project/text-files/setup.inc/setup-header-cr.inc b/project/text-files/setup.inc/setup-header-cr.inc
index dac1238..dac1238 100755..100644
--- a/project/text-files/setup.inc/setup-header-cr.inc
+++ b/project/text-files/setup.inc/setup-header-cr.inc
diff --git a/project/text-files/setup.inc/setup-include-cr.inc b/project/text-files/setup.inc/setup-include-cr.inc
index 8edec87..8edec87 100755..100644
--- a/project/text-files/setup.inc/setup-include-cr.inc
+++ b/project/text-files/setup.inc/setup-include-cr.inc