I am currently building my own game and I've been studying the Quake source for ideas and inspiration. I'm current dealing with the command buffer and developer console. My game is written in Microsoft's C#, so I don't have as much control with creating and destroying strings as I would with C/C++. I've reinterpreted the code into the best way I could see it working with immutable strings and object-oriented programming. I'm not having a problem with any of this, but what I am wondering about is what is the best way to go about processing strings. I'm not trying to fix something that isn't broken: I have the opportunity and desire to write something possibly better.
I've been making some observations with GLQuake, Half-Life, Half-Life2, and Rage. I could check on idTech 2, 3, and 4, but since Rage is the latest I think it's fine already. All these games have the "echo" command.
Code: Select all
] echo this is a test
this is a testIncluding the command itself every token is separated by a single space and quotations are made into tokens that can have whitespace in them. The rules are actually different between games but that doesn't really matter when everyone follows convention. The tokenizing process was rewritten for Source engine and it was rewritten some time after idTech1, probably not by the same person so there had to be at least two people who felt it would be nice to change it.
The quake tokenizer is really greedy with words, so much that it will consume quotations ignoring any quotation rules.
Code: Select all
] echo foo bar
foo bar
] echo foo "bar"
foo bar
] echo foo"bar"
foo"bar"
] echo foo"bar
foo"barCode: Select all
] echo foo"bar"
foo bar
] echo"foo"
foo
] echo"foo"bar
foo bar
] "echo"foo"bar"
foo barCode: Select all
] echo testing "testing
testing testingCode: Select all
] echo testing "testing
testingCode: Select all
] echo start ;end
start
Unknown command "end"
] echo start"" ;end
start""
Unknown command "end"
] echo start" ;end
start" ;endSo I'm wondering now, is there a best way to do it, or a proper way, a standard? How do the operating systems do it, because I know that the entry point of a C program conventionally has an argument count and argument vector (int argc and char* argv). I don't even know who is in charge of creating the argument vector, or where code for doing that is ever defined. If there is some kind of manifesto on how argument vector is handled, I'd like to read it.
I tried my hand at creating a tokenizer function that works exactly like Quake and it does work except that it doesn't create single tokens out of these characters: "{ } ) ( \ :"
Code: Select all
int i = 0;
int j = 0;
_argc = 0;
while (j < text.Length)
{
if (!Char.IsWhiteSpace(text[j]))
{
if (text[j] == '"')
{
i = ++j;
while (j < text.Length && text[j] != '"') j++;
_argv[_argc++] = text.Substring(i, j - i);
}
else
{
if (text[j] == '/' && j + 1 < text.Length && text[j + 1] == '/')
return;
i = j++;
while (j < text.Length && !Char.IsWhiteSpace(text[j])) j++;
_argv[_argc++] = text.Substring(i, j - i);
}
}
j++;
}I think the reason this bug existed is because COM_Parse tokenized the colon away from the address, but I don't know for sure without looking at the changes. Half-Life's solution to this problem was not to read tokens, but instead read everything that written after "connect" as being the argument to connect.Fixed a bug with console parsing that existed in almost all versions of quake except quakeworld by switching to the qwcl COM_Parse for console parsing (in english: fixed connect commands involving a port, like 127.0.0.1:26000), thanks very much to Fuh for mentioning this bug.
Answer what you like: I am here with an open mind to learn.