]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
use dynamic eye position-centered bouncegrid when rendering in dynamic
[xonotic/darkplaces.git] / common.c
index c8ee1ca66f34e76b4fce41858aab3beee581c0a3..11a350bfc2dba30daa9d4614657f0e9d873e7fb4 100644 (file)
--- a/common.c
+++ b/common.c
@@ -19,21 +19,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 // common.c -- misc functions used in client and server
 
-#include "quakedef.h"
-#include "utf8lib.h"
-
 #include <stdlib.h>
 #include <fcntl.h>
 #ifndef WIN32
 #include <unistd.h>
 #endif
 
+#include "quakedef.h"
+
 cvar_t registered = {0, "registered","0", "indicates if this is running registered quake (whether gfx/pop.lmp was found)"};
 cvar_t cmdline = {0, "cmdline","0", "contains commandline the engine was launched with"};
 
 char com_token[MAX_INPUTLINE];
 int com_argc;
 const char **com_argv;
+int com_selffd = -1;
 
 gamemode_t gamemode;
 const char *gamename;
@@ -105,6 +105,26 @@ void StoreBigLong (unsigned char *buffer, unsigned int i)
        buffer[3] = i         & 0xFF;
 }
 
+void StoreBigShort (unsigned char *buffer, unsigned short i)
+{
+       buffer[0] = (i >>  8) & 0xFF;
+       buffer[1] = i         & 0xFF;
+}
+
+void StoreLittleLong (unsigned char *buffer, unsigned int i)
+{
+       buffer[0] = i         & 0xFF;
+       buffer[1] = (i >>  8) & 0xFF;
+       buffer[2] = (i >> 16) & 0xFF;
+       buffer[3] = (i >> 24) & 0xFF;
+}
+
+void StoreLittleShort (unsigned char *buffer, unsigned short i)
+{
+       buffer[0] = i         & 0xFF;
+       buffer[1] = (i >>  8) & 0xFF;
+}
+
 /*
 ============================================================================
 
@@ -586,7 +606,7 @@ void SZ_Write (sizebuf_t *buf, const unsigned char *data, int length)
 // attention, it has been eradicated from here, its only (former) use in
 // all of darkplaces.
 
-static char *hexchar = "0123456789ABCDEF";
+static const char *hexchar = "0123456789ABCDEF";
 void Com_HexDumpToConsole(const unsigned char *data, int size)
 {
        int i, j, n;
@@ -671,6 +691,9 @@ would be good for any more. At the beginning of the string, it will be called
 for the char 0 to initialize a clean state, and then once with the string " "
 (a space) so the routine knows how long a space is.
 
+In case no single character fits into the given width, the wordWidth function
+must return the width of exactly one character.
+
 Wrapped lines get the isContinuation flag set and are continuationWidth less wide.
 
 The sum of the return values of the processLine function will be returned.
@@ -697,7 +720,6 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
        int result = 0;
        size_t wordLen;
        size_t dummy;
-       size_t wordChars;
 
        dummy = 0;
        wordWidth(passthroughCW, NULL, &dummy, -1);
@@ -710,12 +732,11 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
                switch(ch)
                {
                        case 0: // end of string
-                               result += processLine(passthroughPL, startOfLine, u8_strnlen(startOfLine, cursor - startOfLine), spaceUsedInLine, isContinuation);
+                               result += processLine(passthroughPL, startOfLine, cursor - startOfLine, spaceUsedInLine, isContinuation);
                                isContinuation = false;
                                goto out;
-                               break;
                        case '\n': // end of line
-                               result += processLine(passthroughPL, startOfLine, u8_strnlen(startOfLine, cursor - startOfLine), spaceUsedInLine, isContinuation);
+                               result += processLine(passthroughPL, startOfLine, cursor - startOfLine, spaceUsedInLine, isContinuation);
                                isContinuation = false;
                                ++cursor;
                                startOfLine = cursor;
@@ -740,13 +761,8 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
                                        }
                                }
                                out_inner:
-                               /*
-                               wordChars = strlen(cursor);
-                               if (wordChars > wordLen)
-                               */
-                               wordChars = wordLen;
-                               spaceUsedForWord = wordWidth(passthroughCW, cursor, &wordChars, maxWidth - continuationWidth); // this may have reduced wordLen when it won't fit - but this is GOOD. TODO fix words that do fit in a non-continuation line
-                               if(wordChars < 1)
+                               spaceUsedForWord = wordWidth(passthroughCW, cursor, &wordLen, maxWidth - continuationWidth); // this may have reduced wordLen when it won't fit - but this is GOOD. TODO fix words that do fit in a non-continuation line
+                               if(wordLen < 1) // cannot happen according to current spec of wordWidth
                                {
                                        wordLen = 1;
                                        spaceUsedForWord = maxWidth + 1; // too high, forces it in a line of itself
@@ -760,7 +776,7 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
                                else
                                {
                                        // output current line
-                                       result += processLine(passthroughPL, startOfLine, u8_strnlen(startOfLine, cursor - startOfLine), spaceUsedInLine, isContinuation);
+                                       result += processLine(passthroughPL, startOfLine, cursor - startOfLine, spaceUsedInLine, isContinuation);
                                        isContinuation = true;
                                        startOfLine = cursor;
                                        cursor += wordLen;
@@ -1297,7 +1313,7 @@ skipwhite:
        else
        {
                // regular word
-               for (;!ISWHITESPACE(*data) && *data != ',' && *data != ';' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++)
+               for (;!ISWHITESPACE(*data) && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++)
                        if (len < (int)sizeof(com_token) - 1)
                                com_token[len++] = *data;
                com_token[len] = 0;
@@ -1405,13 +1421,13 @@ int COM_CheckParm (const char *parm)
 
 typedef struct gamemode_info_s
 {
-       const char* prog_name;
-       const char* cmdline;
-       const char* gamename;
-       const char* gamedirname1;
-       const char* gamedirname2;
-       const char* gamescreenshotname;
-       const char* gameuserdirname;
+       const char* prog_name; // not null
+       const char* cmdline; // not null
+       const char* gamename; // not null
+       const char* gamedirname1; // not null
+       const char* gamedirname2; // null
+       const char* gamescreenshotname; // not nul
+       const char* gameuserdirname; // not null
 } gamemode_info_t;
 
 static const gamemode_info_t gamemode_info [GAME_COUNT] =
@@ -1432,6 +1448,9 @@ static const gamemode_info_t gamemode_info [GAME_COUNT] =
 // GAME_NEXUIZ
 // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
 { "nexuiz",                    "-nexuiz",              "Nexuiz",                               "data",         NULL,                   "nexuiz",               "nexuiz" },
+// GAME_XONOTIC
+// COMMANDLINEOPTION: Game: -xonotic runs the multiplayer game Xonotic
+{ "xonotic",                   "-xonotic",             "Xonotic",                              "data",         NULL,                   "xonotic",              "xonotic" },
 // GAME_TRANSFUSION
 // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
 { "transfusion",       "-transfusion", "Transfusion",                  "basetf",       NULL,                   "transfusion",  "transfusion" },
@@ -1483,21 +1502,28 @@ static const gamemode_info_t gamemode_info [GAME_COUNT] =
 // GAME_EDU2P
 // COMMANDLINEOPTION: Game: -edu2p runs the game Edu2 prototype
 { "edu2p", "-edu2p", "EDU2 Prototype", "id1", "edu2", "edu2_p", "edu2prototype" },
-// GAME_BLADEMASTER
-// COMMANDLINEOPTION: Game: -blademaster runs the game Prophecy: Return of the BladeMaster
-{ "blademaster", "-blademaster", "Prophecy: Return of the BladeMaster", "basebm", NULL, "blademaster", "blademaster" },
 // GAME_PROPHECY
-// COMMANDLINEOPTION: Game: -prophecy runs the game Quake (default)
+// COMMANDLINEOPTION: Game: -prophecy runs the game Prophecy
 { "prophecy",                          "-prophecy",            "Prophecy",             "data",         NULL,                   "prophecy",                     "prophecy" },
 // GAME_BLOODOMNICIDE
 // COMMANDLINEOPTION: Game: -omnicide runs the game Blood Omnicide
 { "omnicide", "-omnicide", "Blood Omnicide", "kain", NULL, "omnicide", "omnicide" },
+// GAME_STEELSTORM
+// COMMANDLINEOPTION: Game: -steelstorm runs the game Steel Storm
+{ "steelstorm",                                "-steelstorm",          "Steel-Storm",          "gamedata",             NULL,                   "ss",                   "steelstorm" },
+// GAME_STRAPBOMB
+// COMMANDLINEOPTION: Game: -strapbomb runs the game Strap-on-bomb Car
+{ "strapbomb",                         "-strapbomb",           "Strap-on-bomb Car",            "id1",          NULL,                   "strap",                        "strapbomb" },
+// GAME_MOONHELM
+// COMMANDLINEOPTION: Game: -moonhelm runs the game MoonHelm
+{ "moonhelm",                          "-moonhelm",            "MoonHelm",             "data",         NULL,                   "mh",                   "moonhelm" },
 };
 
 void COM_InitGameType (void)
 {
        char name [MAX_OSPATH];
        unsigned int i;
+       int t;
 
        FS_StripExtension (com_argv[0], name, sizeof (name));
        COM_ToLowerString (name, name, sizeof (name));
@@ -1524,6 +1550,17 @@ void COM_InitGameType (void)
        gamedirname2 = gamemode_info[gamemode].gamedirname2;
        gamescreenshotname = gamemode_info[gamemode].gamescreenshotname;
        gameuserdirname = gamemode_info[gamemode].gameuserdirname;
+
+       if((t = COM_CheckParm("-customgamename")) && t + 1 < com_argc)
+               gamename = com_argv[t+1];
+       if((t = COM_CheckParm("-customgamedirname1")) && t + 1 < com_argc)
+               gamedirname1 = com_argv[t+1];
+       if((t = COM_CheckParm("-customgamedirname2")) && t + 1 < com_argc)
+               gamedirname2 = *com_argv[t+1] ? com_argv[t+1] : NULL;
+       if((t = COM_CheckParm("-customgamescreenshotname")) && t + 1 < com_argc)
+               gamescreenshotname = com_argv[t+1];
+       if((t = COM_CheckParm("-customgameuserdirname")) && t + 1 < com_argc)
+               gameuserdirname = com_argv[t+1];
 }
 
 
@@ -1965,8 +2002,6 @@ void InfoString_GetValue(const char *buffer, const char *key, char *value, size_
        size_t keylength;
        if (!key)
                key = "";
-       if (!value)
-               value = "";
        keylength = strlen(key);
        if (valuelength < 1 || !value)
        {
@@ -2197,3 +2232,62 @@ void FindFraction(double val, int *num, int *denom, int denomMax)
                }
        }
 }
+
+// decodes an XPM from C syntax
+char **XPM_DecodeString(const char *in)
+{
+       static char *tokens[257];
+       static char lines[257][512];
+       size_t line = 0;
+
+       // skip until "{" token
+       while(COM_ParseToken_QuakeC(&in, false) && strcmp(com_token, "{"));
+
+       // now, read in succession: string, comma-or-}
+       while(COM_ParseToken_QuakeC(&in, false))
+       {
+               tokens[line] = lines[line];
+               strlcpy(lines[line++], com_token, sizeof(lines[0]));
+               if(!COM_ParseToken_QuakeC(&in, false))
+                       return NULL;
+               if(!strcmp(com_token, "}"))
+                       break;
+               if(strcmp(com_token, ","))
+                       return NULL;
+               if(line >= sizeof(tokens) / sizeof(tokens[0]))
+                       return NULL;
+       }
+
+       return tokens;
+}
+
+static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static void base64_3to4(const unsigned char *in, unsigned char *out, int bytes)
+{
+       unsigned char i0 = (bytes > 0) ? in[0] : 0;
+       unsigned char i1 = (bytes > 1) ? in[1] : 0;
+       unsigned char i2 = (bytes > 2) ? in[2] : 0;
+       unsigned char o0 = base64[i0 >> 2];
+       unsigned char o1 = base64[((i0 << 4) | (i1 >> 4)) & 077];
+       unsigned char o2 = base64[((i1 << 2) | (i2 >> 6)) & 077];
+       unsigned char o3 = base64[i2 & 077];
+       out[0] = (bytes > 0) ? o0 : '?';
+       out[1] = (bytes > 0) ? o1 : '?';
+       out[2] = (bytes > 1) ? o2 : '=';
+       out[3] = (bytes > 2) ? o3 : '=';
+}
+
+size_t base64_encode(unsigned char *buf, size_t buflen, size_t outbuflen)
+{
+       size_t blocks, i;
+       // expand the out-buffer
+       blocks = (buflen + 2) / 3;
+       if(blocks*4 > outbuflen)
+               return 0;
+       for(i = blocks; i > 0; )
+       {
+               --i;
+               base64_3to4(buf + 3*i, buf + 4*i, buflen - 3*i);
+       }
+       return blocks * 4;
+}