aboutsummaryrefslogtreecommitdiff
path: root/project/src/lib-lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'project/src/lib-lex.c')
-rw-r--r--project/src/lib-lex.c237
1 files changed, 228 insertions, 9 deletions
diff --git a/project/src/lib-lex.c b/project/src/lib-lex.c
index ed49f9b..5374d80 100644
--- a/project/src/lib-lex.c
+++ b/project/src/lib-lex.c
@@ -161,6 +161,7 @@ static const feature_var_t lex_section_list[] =
DEF_VAR( 0,HAVELEXS_DEV1, lex_sect_dev1, "LEX section DEV1" ),
DEF_VAR( 0,HAVELEXS_SET1, lex_sect_set1, "LEX section SET1" ),
DEF_VAR( 0,HAVELEXS_CANN, lex_sect_cann, "LEX section CANN" ),
+ DEF_VAR( 0,HAVELEXS_CTDN, lex_sect_ctdn, "LEX section CTDN" ),
DEF_VAR( 0,HAVELEXS_HIPT, lex_sect_hipt, "LEX section HIPT" ),
DEF_VAR( 0,HAVELEXS_RITP, lex_sect_ritp, "LEX section RITP" ),
@@ -573,6 +574,7 @@ const features_szs_t * GetFeaturesModes()
m.lex_sect_dev1 = FZM_SECTION;
m.lex_sect_set1 = FZM_GAMEPLAY | FZM_M_TYPE | FZM_ONLINE | FZM_SECTION;
m.lex_sect_cann = FZM_GAMEPLAY | FZM_M_TYPE | FZM_M_WHERE | FZM_SECTION;
+ m.lex_sect_ctdn = FZM_SECTION;
m.lex_sect_hipt = FZM_VISUAL | FZM_M_TYPE | no_timetrial | FZM_SECTION;
m.lex_sect_ritp = FZM_GAMEPLAY | FZM_M_TYPE | no_timetrial | FZM_SECTION;
@@ -916,6 +918,65 @@ static bool IsActiveLEXElement_SET1 ( const lex_set1_t *set1 )
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+static void FixLEXElement_CTDN ( lex_ctdn_t *ctdn )
+{
+ DASSERT(ctdn);
+
+ u16 tlimit[LEC__N];
+ be16n(tlimit,ctdn->time_limit_sec,LEC__N);
+
+ if (!tlimit[LEC_150CC])
+ tlimit[LEC_150CC] = 150;
+ for ( int i = LEC_150CC - 1; i >= 0; i-- )
+ if (!tlimit[i])
+ tlimit[i] = tlimit[i+1];
+ for ( int i = LEC_150CC+1; i < LEC__N; i++ )
+ if (!tlimit[i])
+ tlimit[i] = tlimit[i-1];
+
+ write_be16n(ctdn->time_limit_sec,tlimit,LEC__N);
+ // [[new-lex-ctdn]]
+}
+
+//-----------------------------------------------------------------------------
+
+static void FixLEXItem_CTDN
+(
+ lex_t * lex, // LEX data structure
+ lex_item_t * item // item to fix
+)
+{
+ DASSERT(lex);
+ DASSERT(item);
+ DASSERT( ntohl(item->elem.size) >= sizeof(lex_ctdn_t) );
+
+ lex_ctdn_t *ctdn = (lex_ctdn_t*)item->elem.data;
+ FixLEXElement_CTDN(ctdn);
+}
+
+//-----------------------------------------------------------------------------
+
+static void ClearLEXElement_CTDN ( lex_ctdn_t *ctdn )
+{
+ DASSERT(ctdn);
+ memset(ctdn,0,sizeof(*ctdn));
+ FixLEXElement_CTDN(ctdn);
+}
+
+//-----------------------------------------------------------------------------
+
+static bool IsActiveLEXElement_CTDN ( const lex_ctdn_t *ctdn )
+{
+ DASSERT(ctdn);
+ lex_ctdn_t empty, test = *ctdn;
+ ClearLEXElement_CTDN(&empty);
+ FixLEXElement_CTDN(&test);
+ return memcmp(&empty,&test,sizeof(empty)) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
// [[new-lex-sect]] upto 4 functions, see SET1 above
///////////////////////////////////////////////////////////////////////////////
@@ -1121,6 +1182,12 @@ static lex_item_t * AppendElementLEX
size4 = ALIGN32(sizeof(lex_set1_t),4);
break;
+ case LEXS_CTDN:
+ fix_func = FixLEXItem_CTDN;
+ if ( size4 < sizeof(lex_ctdn_t) )
+ size4 = ALIGN32(sizeof(lex_ctdn_t),4);
+ break;
+
// [[new-lex-sect]]
case LEXS_TEST:
@@ -1311,6 +1378,7 @@ uint GetLexFeatures ( const lex_element_t *elem, lex_t *lex )
//case LEXS_DEV1: return GetLexFeaturesDEV1(elem,lex); // will never have features
case LEXS_SET1: return GetLexFeaturesSET1(elem,lex);
case LEXS_CANN: return GetLexFeaturesCANN(elem);
+//X case LEXS_CTDN: return GetLexFeaturesCTDN(elem);
case LEXS_HIPT: return GetLexFeaturesHIPT(elem);
case LEXS_RITP: return GetLexFeaturesRITP(elem);
case LEXS_TEST: return GetLexFeaturesTEST(elem);
@@ -1371,6 +1439,7 @@ const have_lex_info_t have_lex_sect_info[HAVELEXS__N] =
{ LEXS_FEAT, "features", 2 }, // HAVELEXS_FEAT
{ LEXS_RITP, "rnditph", sizeof(lex_ritp_rule_t) }, // HAVELEXS_RITP
{ LEXS_DEV1, "dev1", 1 }, // HAVELEXS_DEV1
+ { LEXS_CTDN, "countdown", 0 }, // HAVELEXS_CTDN
//--- add new sections here (order is important)
// [[new-lex-sect]]
};
@@ -1453,6 +1522,9 @@ void UpdateLEX ( lex_t * lex, bool add_missing, bool add_test )
//--- CANN
AppendCannLEX(lex,false);
+ //--- CTDN
+ AppendCtdnLEX(lex,false);
+
//--- HIPT
AppendHiptLEX(lex,false);
@@ -1487,8 +1559,7 @@ lex_item_t * AppendFeatLEX
lex_item_t * AppendDev1LEX ( lex_t * lex, bool overwrite )
{
- lex_dev1_t dev1;
- memset(&dev1,0,sizeof(dev1));
+ lex_dev1_t dev1 = {0};
// AppendElementLEX() does call FixLEXItem_DEV1()
return AppendElementLEX(lex,LEXS_DEV1,&dev1,sizeof(dev1),overwrite);
}
@@ -1497,8 +1568,7 @@ lex_item_t * AppendDev1LEX ( lex_t * lex, bool overwrite )
lex_item_t * AppendSet1LEX ( lex_t * lex, bool overwrite )
{
- lex_set1_t set1;
- memset(&set1,0,sizeof(set1));
+ lex_set1_t set1 = {0};
// AppendElementLEX() does call FixLEXItem_SET1()
return AppendElementLEX(lex,LEXS_SET1,&set1,sizeof(set1),overwrite);
}
@@ -1513,6 +1583,15 @@ lex_item_t * AppendCannLEX ( lex_t * lex, bool overwrite )
//-----------------------------------------------------------------------------
+lex_item_t * AppendCtdnLEX ( lex_t * lex, bool overwrite )
+{
+ lex_ctdn_t ctdn = {0};
+ // AppendElementLEX() does call FixLEXItem_CTDN()
+ return AppendElementLEX(lex,LEXS_CTDN,&ctdn,sizeof(ctdn),overwrite);
+}
+
+//-----------------------------------------------------------------------------
+
lex_item_t * AppendHiptLEX ( lex_t * lex, bool overwrite )
{
return AppendElementLEX( lex, LEXS_HIPT, 0, 0, overwrite );
@@ -1734,6 +1813,7 @@ typedef enum lex_section_id
LID_DEVELOP1,
LID_SETTINGS1,
LID_CANNON,
+ LID_COUNTDOWN,
LID_HIDE_PT,
LID_RND_ITPH,
LID_TEST,
@@ -1757,6 +1837,7 @@ static const KeywordTab_t lex_section_name[] =
{ LID_DEVELOP1, "DEV1", "Developer settings", 0 },
{ LID_SETTINGS1, "SET1", "Primary settings", 0 },
{ LID_CANNON, "CANN", "Cannon settings", 0 },
+ { LID_COUNTDOWN, "CTDN", "Countdown settings", 0 },
{ LID_HIDE_PT, "HIPT", "Hide position tracker", 0 },
{ LID_RND_ITPH, "RITP", "Random next-links @KMP:ITPH", 0 },
{ LID_TEST, "TEST", "Test case", 0 },
@@ -2038,6 +2119,63 @@ static enumError ScanLEXElement_CANN
///////////////////////////////////////////////////////////////////////////////
+static enumError ScanLEXElement_CTDN
+(
+ lex_t * lex, // KMP data structure
+ ScanInfo_t * si // valid data
+)
+{
+ DASSERT(lex);
+ DASSERT(si);
+ TRACE("ScanLEXElement_CTDN()\n");
+
+
+ //--- setup data
+
+ lex_ctdn_t ctdn = {0};
+
+ ScanParam_t ptab[] =
+ {
+ { "TIME-LIMIT-BATTLE", SPM_U16_BE, ctdn.time_limit_sec + LEC_BATTLE },
+ { "TIME-LIMIT-50CC", SPM_U16_BE, ctdn.time_limit_sec + LEC_50CC },
+ { "TIME-LIMIT-100CC", SPM_U16_BE, ctdn.time_limit_sec + LEC_100CC },
+ { "TIME-LIMIT-150CC", SPM_U16_BE, ctdn.time_limit_sec + LEC_150CC },
+ { "TIME-LIMIT-200CC", SPM_U16_BE, ctdn.time_limit_sec + LEC_200CC },
+ { "TIME-LIMIT-300CC", SPM_U16_BE, ctdn.time_limit_sec + LEC_300CC },
+ {0}
+ };
+
+ char fb_buf[1000];
+ FastBuf_t *fb = InitializeFastBuf(fb_buf,sizeof(fb_buf));
+ AppendFastBuf(fb,&ctdn,sizeof(ctdn));
+
+
+ //--- main loop
+
+ for(;;)
+ {
+ char ch = NextCharSI(si,true);
+ if ( !ch || ch == '[' )
+ break;
+
+ if ( ch == '@' )
+ ScanParamSI(si,ptab);
+ else
+ ScanHexlineSI(si,fb,true);
+ }
+ CheckLevelSI(si);
+
+ FixLEXElement_CTDN(&ctdn);
+ memcpy(fb->buf,&ctdn,sizeof(ctdn));
+ //HexDump16(stderr,0,0,fb->buf,fb->ptr-fb->buf);
+ AppendElementLEX(lex,LEXS_CTDN,fb->buf,fb->ptr-fb->buf,true);
+
+ ResetFastBuf(fb);
+ return ERR_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
static enumError ScanLEXElement_HIPT
(
lex_t * lex, // KMP data structure
@@ -2284,6 +2422,10 @@ enumError ScanTextLEX
err = ScanLEXElement_CANN(lex,&si);
break;
+ case LID_COUNTDOWN:
+ err = ScanLEXElement_CTDN(lex,&si);
+ break;
+
case LID_HIDE_PT:
err = ScanLEXElement_HIPT(lex,&si);
break;
@@ -2693,6 +2835,73 @@ static enumError SaveTextLEX_SET1
///////////////////////////////////////////////////////////////////////////////
+static enumError SaveTextLEX_CTDN
+(
+ FILE * f, // file to write
+ const lex_t * lex, // pointer to valid LEX
+ lex_item_t * item // item to save
+)
+{
+ DASSERT(f);
+ DASSERT(lex);
+ DASSERT(item);
+
+ const uint size = ntohl(item->elem.size);
+ noPRINT("SaveTextLEX_CTDN(), size=%u\n",size);
+ DASSERT( size >= sizeof(lex_ctdn_t) );
+ if ( size < sizeof(lex_ctdn_t))
+ return ERR_OK;
+
+ const u8 *data = item->elem.data;
+ const lex_ctdn_t *ctdn = (lex_ctdn_t*)data;
+
+ const uint cc050 = be16( ctdn->time_limit_sec + LEC_50CC );
+ const uint cc100 = be16( ctdn->time_limit_sec + LEC_100CC );
+ const uint cc150 = be16( ctdn->time_limit_sec + LEC_150CC );
+ const uint cc200 = be16( ctdn->time_limit_sec + LEC_200CC );
+ const uint cc300 = be16( ctdn->time_limit_sec + LEC_300CC );
+
+ if ( brief_count || export_count )
+ fprintf(f,
+ "%s[CTDN]\r\n\r\n"
+ "@TIME-LIMIT-50CC = %3u\r\n"
+ "@TIME-LIMIT-100CC = %3u\r\n"
+ "@TIME-LIMIT-150CC = %3u\r\n"
+ "@TIME-LIMIT-200CC = %3u\r\n"
+ "@TIME-LIMIT-300CC = %3u\r\n"
+ "\r\n"
+ ,section_sep
+ ,cc050
+ ,cc100
+ ,cc150
+ ,cc200
+ ,cc300
+ // [[new-lex-ctdn]]
+ );
+ else
+ fprintf(f,text_lex_elem_ctdn_cr
+ ,item->sort_order
+ ,cc050, PrintHMS(0,0,cc050,1," # ","")
+ ,cc100, PrintHMS(0,0,cc100,1," # ","")
+ ,cc150, PrintHMS(0,0,cc150,1," # ","")
+ ,cc200, PrintHMS(0,0,cc200,1," # ","")
+ ,cc300, PrintHMS(0,0,cc300,1," # ","")
+ // [[new-lex-ctdn]]
+ );
+
+ if ( size > sizeof(lex_ctdn_t) )
+ {
+ fputs("\r\n# Hex dump for unknown settings:\r\n",f);
+ HexDump(f,0,sizeof(lex_ctdn_t),5,16,
+ item->elem.data + sizeof(lex_ctdn_t),
+ size - sizeof(lex_ctdn_t) );
+ }
+
+ return ERR_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
static enumError SaveTextLEX_CANN
(
FILE * f, // file to write
@@ -2994,6 +3203,7 @@ enumError SaveTextLEX
case LEXS_DEV1: err = SaveTextLEX_DEV1(F.f,lex,s); break;
case LEXS_SET1: err = SaveTextLEX_SET1(F.f,lex,s); break;
case LEXS_CANN: err = SaveTextLEX_CANN(F.f,lex,s); break;
+ case LEXS_CTDN: err = SaveTextLEX_CTDN(F.f,lex,s); break;
case LEXS_HIPT: err = SaveTextLEX_HIPT(F.f,lex,s); break;
case LEXS_RITP: err = SaveTextLEX_RITP(F.f,lex,s); break;
case LEXS_TEST: err = SaveTextLEX_TEST(F.f,lex,s); break;
@@ -3454,16 +3664,24 @@ bool PurgeLEX ( lex_t * lex )
break;
case LEXS_DEV1:
- remove = !IsActiveLEXElement_DEV1((lex_dev1_t*)data);
+ remove = size == sizeof(lex_dev1_t)
+ && !IsActiveLEXElement_DEV1((lex_dev1_t*)data);
break;
case LEXS_SET1:
- remove = !IsActiveLEXElement_SET1((lex_set1_t*)data);
+ remove = size == sizeof(lex_set1_t)
+ && !IsActiveLEXElement_SET1((lex_set1_t*)data);
break;
case LEXS_CANN:
- remove = size <= sizeof(CannonDataLEX)
- && !memcmp(data,&CannonDataLEX,size);
+ remove = size < sizeof(CannonDataLEX)
+ || size == sizeof(CannonDataLEX)
+ && !memcmp(data,&CannonDataLEX,sizeof(CannonDataLEX));
+ break;
+
+ case LEXS_CTDN:
+ remove = size == sizeof(lex_ctdn_t)
+ && !IsActiveLEXElement_CTDN((lex_ctdn_t*)data);
break;
case LEXS_HIPT:
@@ -3477,7 +3695,8 @@ bool PurgeLEX ( lex_t * lex )
// [[new-lex-sect]]
case LEXS_TEST:
- remove = !IsActiveLEXElement_TEST((lex_test_t*)data);
+ remove = size == sizeof(lex_test_t)
+ && !IsActiveLEXElement_TEST((lex_test_t*)data);
break;
default: