]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/util.qc
Merge remote-tracking branch 'origin' into terencehill/m_toggle_fix
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / util.qc
index fc86c3a842d07704be28ccc1445fcfeccfe782d6..10e4e345b28298ead91a5420e4c0c11da92dc36b 100644 (file)
@@ -41,8 +41,8 @@ void wordwrap_sprint(string s, float l)
 
 string unescape(string in)
 {
-       local float i, len;
-       local string str, s;
+       float i, len;
+       string str, s;
 
        // but it doesn't seem to be necessary in my tests at least
        in = strzone(in);
@@ -72,8 +72,8 @@ string unescape(string in)
 
 void wordwrap_cb(string s, float l, void(string) callback)
 {
-       local string c;
-       local float lleft, i, j, wlen;
+       string c;
+       float lleft, i, j, wlen;
 
        s = strzone(s);
        lleft = l;
@@ -236,6 +236,16 @@ string fstrunzone(string s)
        return sc;
 }
 
+float fexists(string f)
+{
+    float fh;
+    fh = fopen(f, FILE_READ);
+    if (fh < 0)
+        return FALSE;
+    fclose(fh);
+    return TRUE;
+}
+
 // Databases (hash tables)
 #define DB_BUCKETS 8192
 void db_save(float db, string pFilename)
@@ -1064,8 +1074,8 @@ vector rgb_to_hsv(vector rgb)
        float mi, ma;
        vector hsv;
 
-       mi = min3(rgb_x, rgb_y, rgb_z);
-       ma = max3(rgb_x, rgb_y, rgb_z);
+       mi = min(rgb_x, rgb_y, rgb_z);
+       ma = max(rgb_x, rgb_y, rgb_z);
 
        hsv_x = rgb_mi_ma_to_hue(rgb, mi, ma);
        hsv_z = ma;
@@ -1088,8 +1098,8 @@ vector rgb_to_hsl(vector rgb)
        float mi, ma;
        vector hsl;
 
-       mi = min3(rgb_x, rgb_y, rgb_z);
-       ma = max3(rgb_x, rgb_y, rgb_z);
+       mi = min(rgb_x, rgb_y, rgb_z);
+       ma = max(rgb_x, rgb_y, rgb_z);
 
        hsl_x = rgb_mi_ma_to_hue(rgb, mi, ma);
        
@@ -1133,21 +1143,16 @@ string rgb_to_hexcolor(vector rgb)
 }
 
 // requires that m2>m1 in all coordinates, and that m4>m3
-float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;};
+float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;}
 
 // requires the same, but is a stronger condition
-float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;};
+float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;}
 
 #ifndef MENUQC
 #endif
 
 float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
 {
-       float ICanHasKallerz;
-
-       // detect color codes support in the width function
-       ICanHasKallerz = (w("^7", theSize) == 0);
-
        // STOP.
        // The following function is SLOW.
        // For your safety and for the protection of those around you...
@@ -1171,7 +1176,7 @@ float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLe
        }
        while(left < right - 1);
 
-       if(ICanHasKallerz)
+       if(w("^7", theSize) == 0) // detect color codes support in the width function
        {
                // NOTE: when color codes are involved, this binary search is,
                // mathematically, BROKEN. However, it is obviously guaranteed to
@@ -1212,11 +1217,6 @@ float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLe
 
 float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t w)
 {
-       float ICanHasKallerz;
-
-       // detect color codes support in the width function
-       ICanHasKallerz = (w("^7") == 0);
-
        // STOP.
        // The following function is SLOW.
        // For your safety and for the protection of those around you...
@@ -1240,7 +1240,7 @@ float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_
        }
        while(left < right - 1);
 
-       if(ICanHasKallerz)
+       if(w("^7") == 0) // detect color codes support in the width function
        {
                // NOTE: when color codes are involved, this binary search is,
                // mathematically, BROKEN. However, it is obviously guaranteed to
@@ -1279,6 +1279,42 @@ float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_
        return left;
 }
 
+string find_last_color_code(string s)
+{
+       float start, len, i, carets;
+       start = strstrofs(s, "^", 0);
+       if (start == -1) // no caret found
+               return "";
+       len = strlen(s)-1;
+       for(i = len; i >= start; --i)
+       {
+               if(substring(s, i, 1) != "^")
+                       continue;
+
+               carets = 1;
+               while (i-carets >= start && substring(s, i-carets, 1) == "^")
+                       ++carets;
+
+               // check if carets aren't all escaped
+               if (carets == 1 || mod(carets, 2) == 1) // first check is just an optimization
+               {
+                       if(i+1 <= len)
+                       if(strstrofs("0123456789", substring(s, i+1, 1), 0) >= 0)
+                               return substring(s, i, 2);
+
+                       if(i+4 <= len)
+                       if(substring(s, i+1, 1) == "x")
+                       if(strstrofs("0123456789abcdefABCDEF", substring(s, i+2, 1), 0) >= 0)
+                       if(strstrofs("0123456789abcdefABCDEF", substring(s, i+3, 1), 0) >= 0)
+                       if(strstrofs("0123456789abcdefABCDEF", substring(s, i+4, 1), 0) >= 0)
+                               return substring(s, i, 5);
+               }
+               i -= carets; // this also skips one char before the carets
+       }
+
+       return "";
+}
+
 string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
 {
        float cantake;
@@ -1286,6 +1322,12 @@ string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunc
        string s;
 
        s = getWrappedLine_remaining;
+       
+       if(w <= 0)
+       {
+               getWrappedLine_remaining = string_null;
+               return s; // the line has no size ANYWAY, nothing would be displayed.
+       }
 
        cantake = textLengthUpToWidth(s, w, theFontSize, tw);
        if(cantake > 0 && cantake < strlen(s))
@@ -1298,6 +1340,8 @@ string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunc
                        getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
                        if(getWrappedLine_remaining == "")
                                getWrappedLine_remaining = string_null;
+                       else if (tw("^7", theFontSize) == 0)
+                               getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, cantake)), getWrappedLine_remaining);
                        return substring(s, 0, cantake);
                }
                else
@@ -1305,6 +1349,8 @@ string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunc
                        getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
                        if(getWrappedLine_remaining == "")
                                getWrappedLine_remaining = string_null;
+                       else if (tw("^7", theFontSize) == 0)
+                               getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take)), getWrappedLine_remaining);
                        return substring(s, 0, take);
                }
        }
@@ -1322,6 +1368,12 @@ string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw)
        string s;
 
        s = getWrappedLine_remaining;
+       
+       if(w <= 0)
+       {
+               getWrappedLine_remaining = string_null;
+               return s; // the line has no size ANYWAY, nothing would be displayed.
+       }
 
        cantake = textLengthUpToLength(s, w, tw);
        if(cantake > 0 && cantake < strlen(s))
@@ -1334,6 +1386,8 @@ string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw)
                        getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
                        if(getWrappedLine_remaining == "")
                                getWrappedLine_remaining = string_null;
+                       else if (tw("^7") == 0)
+                               getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, cantake)), getWrappedLine_remaining);
                        return substring(s, 0, cantake);
                }
                else
@@ -1341,6 +1395,8 @@ string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw)
                        getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
                        if(getWrappedLine_remaining == "")
                                getWrappedLine_remaining = string_null;
+                       else if (tw("^7") == 0)
+                               getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take)), getWrappedLine_remaining);
                        return substring(s, 0, take);
                }
        }
@@ -1524,12 +1580,6 @@ vector solve_quadratic(float a, float b, float c) // ax^2 + bx + c = 0
        return v;
 }
 
-
-float _unacceptable_compiler_bug_1_a(float b, float c) { return b == c; }
-float _unacceptable_compiler_bug_1_b() { return 1; }
-float _unacceptable_compiler_bug_1_c(float d) { return 2 * d; }
-float _unacceptable_compiler_bug_1_d() { return 1; }
-
 void check_unacceptable_compiler_bugs()
 {
        if(cvar("_allow_unacceptable_compiler_bugs"))
@@ -2013,3 +2063,47 @@ string CTX(string s)
                return s;
        return substring(s, p+1, -1);
 }
+
+// x-encoding (encoding as zero length invisible string)
+const string XENCODE_2  = "xX";
+const string XENCODE_22 = "0123456789abcdefABCDEF";
+string xencode(float f)
+{
+       float a, b, c, d;
+       d = mod(f, 22); f = floor(f / 22);
+       c = mod(f, 22); f = floor(f / 22);
+       b = mod(f, 22); f = floor(f / 22);
+       a = mod(f,  2); // f = floor(f /  2);
+       return strcat(
+               "^",
+               substring(XENCODE_2,  a, 1),
+               substring(XENCODE_22, b, 1),
+               substring(XENCODE_22, c, 1),
+               substring(XENCODE_22, d, 1)
+       );
+}
+float xdecode(string s)
+{
+       float a, b, c, d;
+       if(substring(s, 0, 1) != "^")
+               return -1;
+       if(strlen(s) < 5)
+               return -1;
+       a = strstrofs(XENCODE_2,  substring(s, 1, 1), 0);
+       b = strstrofs(XENCODE_22, substring(s, 2, 1), 0);
+       c = strstrofs(XENCODE_22, substring(s, 3, 1), 0);
+       d = strstrofs(XENCODE_22, substring(s, 4, 1), 0);
+       if(a < 0 || b < 0 || c < 0 || d < 0)
+               return -1;
+       return ((a * 22 + b) * 22 + c) * 22 + d;
+}
+
+float lowestbit(float f)
+{
+       f &~= f * 2;
+       f &~= f * 4;
+       f &~= f * 16;
+       f &~= f * 256;
+       f &~= f * 65536;
+       return f;
+}