Jump to content
The Dark Mod Forums

stgatilov

Active Developer
  • Posts

    6774
  • Joined

  • Last visited

  • Days Won

    232

Everything posted by stgatilov

  1. Well... the temporaries are called "registers" in the code. But since mappers don't see temporaries anyway, I don't think you have to worry. This is just some minor difference in terminology.
  2. Ok, the bug is fixed in the new dev build. Also, we have removed old-style frobstages from core materials.
  3. dev16650-10157 is available. P.S. Clipmodel bug is fixed in it too.
  4. No idea. There is some difference between window properties, but I don't think I fully understand the whole picture. I think there are three types: "nocursor", "font", "forceaspectwidth", etc. --- these are not properties at all. They are like flags: they are applied immediately at the moment of reading, and their parameters must be literal constants, no links/referenced from them and to them are allowed, so no auto-update, no possibility of changing them with Set, Transition. Some specific window types have specific flags, e.g. "stepsize"/"step" in SliderWindow. "backcolor", "rect", "notime", "visible", etc. --- these are builtin properties. They are hardcoded in Window code, and may probably have different behavior. Some specific types of windows have specific flags, like e.g. "cvar" in SliderWindow. Custom window properties, defined with "definefloat", "definevec4", "float". In my understanding, 2 and 3 work the same way and can be assigned expressions or constants. Maybe there is some difference which breaks initialization of one of these, I did not hit any myself. So I don't know. In the original engine, every property must be assigned some value/expression. Writing something like "float myvar;" was illegal by how the code was implemented, because it tried to read a value from semicolon. And since it could not find a variable/property with name ";", it introduced a new variable with such name and zero value, and you got zero initialization. Maybe I am wrong in some detail, but this zero-initialization feature was a lucky side effect from parsing unknown tokens. I legalized this practice: now you can add semicolon instead of value, and parser will just replace it with zero value. Otherwise you'd get a lot of warnings about it now. I don't understand why two keywords "float" and "definefloat" exist. In the code, there are two identical pieces of code for handling them. I found a commit where I changed one for the other, but it seems I did so merely because "float" was used in at least one more case, while "definefloat" was not used anywhere else. Revision: 16558 #5869. Use "float" keyword instead of "definefloat" for compass noshadows register. Note: I have no idea what's the difference. Looking at C++ code, both cases are the same... Yes, it should look like this, but semicolon here is illegal. Script command must end with semicolon, property definition must not end with semicolon. Except for the zero-initialization case noted above (which I'd be happy to not introduce, but too much existing code). Sorry, I did not notice the left side of Set. No, it is not possible to Set only one component of a vector variable.
  5. I noticed it but thought that's because of 400 FPS I have on a tiny map. I guess I broke collision model code during refactoring.
  6. If you look at page about C/C++, you'll see that comparison operators == and != have slightly higher priority than <= >= < >. In GUI code, all these 6 comparison operators have same priority. So if you write a lot of such operators one after the other without parentheses, GUI code will evaluate them left-to-right, while C/C++ will first evaluate == and !=. This is a minor deviation from C standard. I don't think this is ever important, since writing many comparisons in a row is a bit absurd by itself. This was never a correct form. It's just that previously GUI engine did not report any kind of issues to you. Also, that form was never common, I have seen it in exactly one place in our main menu GUI. It works in any expressions. So it covers a, c, d, e, g. But speaking of Set command, it will only work if you enclose right side in parentheses and thus switch it to expression mode. Without parentheses, right side does not support expressions. Transitions don't support expressions, and I don't see anything like indexation support in the code. Yes, it means top-level windows, you can nest as many as you want. When engine loads UI, it takes a single .gui file and parses it. There can be #includes inside, which would make preprocessor copy/paste other files too, but for the GUI parser itself it is single file. This file must contain exactly one GUI window and nothing more (it is usually called Desktop). Inside the top-level window, you can do whatever you did previously, it's just a limitation on what happens outside it.
  7. I can't reproduce it on Bakery Job. At which moment exactly should I press quickload?
  8. I think this is caused by SMP. When the game modes K-th frame, it displays (K-1)-th frame. This works great in steady gameplay, but when something radical happens (e.g. game load), first frame can be displayed with some stale data. Note that if com_smp is 0, then the game still renders previous frame. It would be great to change it back, but we faced some problems with it and it works as it works. So yes, there should be some code to mute such things, but I guess we have not tackled this problem yet.
  9. I refer to Doom 3 in general, at least the original game engine from 2003. All comparisons are operations which are part of expressions. In order to evaluate expression, you need to store temporaries somewhere, and combine them with each other through a sequence of operations. In case of GUI scripts, the temporaries are called "registers". These registers are floats, they simply cannot hold a string. Actually, I have just found the commit where I removed the comparison, and here is what it says: Revision: 16537 #5869. Removed incorrect comparisons with empty string ( == ""). The scripting language does NOT have string values, it only has float values. So when you reference some string variable in expression, it gets value 0.0 if string is empty and 1.0 otherwise. For this reason, there is no sense in comparing to "" (which is actually replaced with 0 because no variable with empty name is found). So the "!=" operator is just a weird way of writing != operator, doublequotes don't change anything. And a string value inside expression is immediately converted into float with 0 or 1 depending on whether it is empty or not. There is no string comparison, but there is checking for emptyness. Multiline macros work as they did, in fact the change is about fixing them! There are several different but related things, and they get into a confusing mix here: Token concatenation used for multiline macros, which comes directly from C/C++ language. String literal concatenation with backslash is optional feature of idLexer --- it does not exist in C/C++ language. String literal concatenation by writing them one after the other --- standard feature of C/C++, disabled in D3 GUI. Here is the full commit message: Revision: 10031 #5869. Don't enable string concatenation by backslash (\) in GUI code. GUI code uses doublequotes everywhere to make names like gui::my_var atomic, since otherwise parser would break them into many tokens. For this reason, string concatenation is disabled in lexer (that's when you can write "hello" " " "world", and C will treat it as single string "hello world"). However, ID enabled special string concatenation via backslash to substitute for it, like this: "hello" \ " " \ "world" The problem with such usage is that it breaks multiline macros. Due to limitations of GUI code, we have to write whole window (even with subwindows) into a macro in order to make it reusable. If any line in such macro ends with a string literal (that's very likely in GUI code), then parsing breaks and whole macro does not work. This can be worked around by moving the first token on the next line to the end of the current line, but it is very messy and totally not obvious. Better just forbid string concatenation altogether. Buy the way, the following way of concatentating string works (at least inside macro): "hello" ## " " ## "world" Note that ## is a standard C way of concatenating tokens, although in C it works on TOKENS, not on string literals --- but here they are mixed anyway. Also, it is even possible to do this: #define HELLO_MESSAGE(index) "Hello, " ## #idx ## "-th user!" Which is very useful to construct variable names inside macros =) The work is finished, although it might get some changes if any related bugs are reported e.g. during beta. I don't think we can give access to single thread. If you miss some info, just ask me and I can copy/paste or explain in my own words. The two references you gave here are about: expression evaluation order fix, expressions in Set command, change in register disabling behavior. They are described in this public post too:
  10. I did a few fixes in experimental (and probably dead) shaders which generated nontrivial warnings. All the remaining warnings fall into the same category: WARNING:Validation for program ambientInteraction failed: Validation Failed: Sampler error: Samplers of different types use the same texture image unit. - or - A sampler's texture unit is out of range (greater than max allowed or negative). I recall some stuff like that discussed: basically, OpenGL requires to bind correct textures in order to link shader (weird). Not sure I want to fix that. No ideas why new backend does not work though.
  11. And how fast does it work? The log shows OpenGL 3.3 and almost no extensions beyond that. Googling also confirms that 3.3 is the best Parallels VM can provide. I guess you are just above the minimum requirements in terms of GL feature support. I suppose Parallels VM was not preinstalled, you decided to use it yourself? P.S. So there are at least two VMs now that can run TDM without passthrough: VMWare and Parallels.
  12. Oh my god! This is Windows VM inside a goddamn M1 macbook! There are tons of shader errors BTW, most of them are probably false issues, but I guess I should review them.
  13. Whaat?! Anyway, that does not save you from posting a condump under broken settings (i.e. with r_useNewBackend 1)
  14. Here is some info: https://wiki.thedarkmod.com/index.php?title=Reporting_Problem
  15. Judging from the original state of GUI code, I suggest the following likely explanation. The GUI scripts and the docs were written by a person different from the one who implemented C++ GUI engine. He tried some stuff, and it worked, or appeared to work, so he decided it was correct. But it was not, but still worked (maybe always, maybe most of the time). Unfortunately, the original Doom 3 GUI engine is so bad that you cannot deduce what's correct way of doing things by merely experimenting with it. It could be e.g. the weird register deactivation rule, or the obscure "all expression are evaluated at some time before script handler" concept.
  16. That's not true. It is initialized to whatever you set as the next token (with semicolon meaning zero right here). These are the ones I know of. All of these are certainly errors. I just checked that if I set variable it 1, the condition that checks it == 1 works, but if I change the condition to != 1, then it does not work. So this is OK way to initialize to 1.
  17. Overally, this is veeery detailed documentation! I think I looked through most of it, except for various listDef, editDef and stuff like that. I definitely support the idea of putting it into its own wiki category, since it consists of like 20 articles! P.S. Maybe we should add support for: runScript command: It seems to be supported in source code. namedEvent: I got the same idea myself at some moment. ?
  18. Regarding ResetTime. I don't think I changed this code, so most likely value was mandatory from the very beginning. And if you omit it... something will happen. Crashing is a best-case scenario TDM 2.11 should warn about wrong usage, and hopefully not crash afterwards... I suppose this stopped working in TDM 2.11, hopefully with a warning. Regarding Set command. I think you should mention in a separate subsection that TDM 2.11 allows expressions on the right side of Set (6028). But please add the same ugly disclaimer that these expressions are actually evaluated before script handler starts executing. There is a page with BNF. I think when formal grammar is usually given only when it is 100% correct and ready to be put into a parser to parse code. I doubt anyone would do anything like that. So... what's the purpose then?
  19. I recommend going to changelog and roadmap in bugtracker and looking through issues that are about GUI scripting. I'm pretty sure there were some major changes which are worth taking into account when writing a tutorial. Maybe even give a list of these tickets somewhere, because if people come from other Doom 3 mods, they can get wrong impression, since stock Doom 3 engine has more bugs and some different behavior. Speaking of putting double-quotes vs not putting them: I think it is a good idea to enclose every item in double-quotes. Literal numeric values are perhaps the only exception. Internally, lexer breaks the text into tokens, and each token is treated as single item. Characters like colon, dot, or dollar break name into several tokens, so you have to enclose such items into double-quotes. In fact, adding double-quotes is never a problem since lexer always removes them, emitting their contents as single token of type "string". The only case where it is a problem is with literal numeric constants, since the GUI parser expects to see them as tokens of type "number". Regarding "initialization" and "updates" of properties. When you declare a property, you can write any expression on the right side, potentially referencing some non-constant things there. Normally, when some of these things change, the property is reevaluated automatically. However, this can get you into trouble is you assign something into the property using Set command... so there is a concept of "active" and "non-active" properties, or "enabled/disabled" properties (not sure about canonical terms). Some things disable/deactivate a property. The rules of original Doom 3 were weird in this regard (6028), but in upcoming TDM 2.11 I think the only way to deactivate a property is to Set something into it, or start a Transition of it. Deactivation happens in runtime, not statically, so the property will keep updating before the first Set is done. The section User Variable says this is OK syntax: float crouch_scale=0; I'm sure this is not correct, and hope that recent dev builds produces a warning on it. String comparison section says that there is some special "quoted comparison operator": if ("LSGSaveGameNameEntry::text" "!=" "") { I don't recall seeing anything specific regarding double-quotes around operators. Moreover, GUI parser cannot see double-quotes, since lexer will replace it with a single two-character token of string type, that won't work properly with GUI parser. Moreover, I don't see any occurance of quoted "!=" in current .gui files, so I guess it was a buggy code that got fixed. I think there is no string comparison, because all expressions and their intermediate values are floats, they simply cannot hold strings. In Precedence section, there is discussion about parentheses. Yes, you can put parentheses in GUI expressions, and rely on normal evaluation order otherwise. The discussion about macros here might be a bit confusing, because GUI engine has nothing to do with #defines, in fact it does not even see them. Just like in C language, all the directives starting with #sharp are handles by totally separate thing called preprocessor, the GUI parser will see all macro references replaced by whatever they point to, so for the GUI parser it would be just a gigantic expression with two levels of nested parentheses. I would probably be better to stress this in tutorial, because this understanding of preprocessor as an entirely separate step can help on many occasions. There is Multiple If section, which totally lacks the most important caveat of GUI ifs that usually kills all attempts of writing any complicated logic in GUI scripts! While you can write expressions inside If conditions (and now also on the right side of Set command), they are evaluated not when you normally expect it to! All the expressions are evaluated before script commands are executed. So if you Set the value of "gui::myvar" from 0 to 1, the following "if (gui::myvar)" will still be considered false. I believe all the expressions are evaluated at the same time, regardless of whether they are on the right side of property definition (aka 'visible "gui::LootIconVisible"') or inside script. This is very important to understand when you write expressions, since normal people assume that script commands are evaluated sequentally, and their changes are propagated immediately. And yes, you can write nested ifs, but with the caveat of early evaluation they probably won't give you much. UPDATE: I see it mentioned in Changing User Variables. And yes, it should apply to properties too, simply because the problem is on the other end: the change is applied immedately, but conditions and expressions are evaluated earlier. Perhaps correct this misconception here, and mention it in Multiple If section too (never too much). Regarding onTime event. You wrote there '"reset" command', perhaps change it to '"resetTime" command'. Regarding onTime 10 instead of onTime 0 in main menu. I think one reason of doing so is to ensure order of triggering handlers. Imagine that you have 50 "onTime 0" handlers, but you want to ensure that some of them are evaluated after the others. Adding small time offsets is the only way of hacking around it. Regarding vector components. The original Doom 3 code intended to make them accessible via indexation, like v[0], v[1], v[2], v[3]. But the code had a terrible bug, so it did not work. In TDM 2.11, it works (6028). UPDATE: also here
  20. Gui language has full-blown support for preprocessor macros. In fact, it is done via the same exact code as in game scripts. If something does not work with them, it's either some custom settings of GUI lexer, or just the GUI language not understanding what you pass to it. In fact, C preprocessor is the only way to implement reusable code in GUI scripts. But in order to use it properly, you need to be an expert in C, with stuff like #include and include guards, ## -- concatenation and # -- stringization, and know about single expansion rule, etc. Just look at tdm_objectives_core.gui and tdm_subtitles_common.gui in the latest dev build, and you'll know what I mean, This is not pointer for certain. It is a very specific hack to link to variable specifically in Transition command. The rules regarding what is considered a string and what can be turned in to a link are not obvious and consistent, as well as the rules about when engine evaluates all the expressions/conditions. Yes, macros don't have namespaces, so you should always prefix your stuff with your domain, or/and undef your macros when they are not needed. Actually, the GUI windows have no namespaces either, so you can get name collision here just as easily. You need a lot of discipline (like in pure C programming) in order to work with large codebase in D3 GUI. Even with the recent 2.11 improvements which add previously nonexistent error reporting. According to the code, dollar only works in Set and Transition right now. This is not a macro at all. Here you define a custom window register. And you reference it only in some locations, as far as I remember. They probably ignored the advanced GUI scripting because it did not work... or the vice versa: they did not use it, thus it did not work Doom 3 code had so many bugs in GUI handling, and lack of any error reporting. I am impressed that TDM guys managed to implement such a complicated main menu with this mess and maintain it for years. As for C preprocessor, I don't know. Maybe they did not reuse any of their GUI code, simply copypasted it around without any worries about future maintenance.
  21. @Havknorr, please post your config file (darkmod.cfg) and console dump. And screenshot, since most likely your case looks different from the 7-months old ones.
  22. You can try to use "g_testPostProcess rotoedge", then implement a similar material and shaders. The last time I checked, rotoedge worked properly. If it works, then you can get away without rebuild. You can also call reloadGLSLPrograms to reload modified shader without restarting TDM. And you can use reloadDecls to reload modified material.
  23. The ultimate goal of on-screen computer graphics is photorealistic rendering, in which case modelling the camera lens is the only option that makes sense. If you want to aim for eye-realistic rendering, it belongs to VR mod: there you can use eye tracking to detect focus distance for the eyes. Overall, I personally don't like the idea of Depth of Field effect in TDM, and I suppose most of people won't. But yeah, you can probably use g_testPostProcess cvar to add a full-screen effect, using _currentRender and _currentDepth as input texture, and writing custom shader.
  24. On the latest dev build, the wrong texture name is used. For instance, frobstage_diffuse often uses _white instead of diffuse texture, so things look "milky".
  25. I'm currently cleaning frobstages in core materials. I noticed that the macros I listed above are broken It is strange because I tested all this stuff... perhaps I reordered generates frobstages in the end, which triggered the bug. Just keep in mind that the macros don't work as intended... maybe implicit generation also.
×
×
  • Create New...