XML talk:BINA/OBJC/TRGV: Difference between revisions
(re-sigh) |
mNo edit summary |
||
Line 40: | Line 40: | ||
I have confirmed in my own way that the strings coming from runtime events are (apparently) compared by pointer rather than by content. Suppose you define two global string vars, '''dead_name''' and '''dead_name_too'''. Then you kill '''A_t48''' twice (after force-spawning him), with '''t48_dead(string ai_name)''' performing the assignment '''dead_name = ai_name'''. Between the two deaths, do '''dead_name_too = dead_name''' from the console (this is now a redirect to the same string data, and '''dead_name_too eq dead_name''' evaluates to '''true'''). After the second A_t48 death, try '''dead_name_too eq dead_name''' again, and see that it evaluates to '''false''' now (there used to be one string, and now it's two identical strings at different addresses). --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) | I have confirmed in my own way that the strings coming from runtime events are (apparently) compared by pointer rather than by content. Suppose you define two global string vars, '''dead_name''' and '''dead_name_too'''. Then you kill '''A_t48''' twice (after force-spawning him), with '''t48_dead(string ai_name)''' performing the assignment '''dead_name = ai_name'''. Between the two deaths, do '''dead_name_too = dead_name''' from the console (this is now a redirect to the same string data, and '''dead_name_too eq dead_name''' evaluates to '''true'''). After the second A_t48 death, try '''dead_name_too eq dead_name''' again, and see that it evaluates to '''false''' now (there used to be one string, and now it's two identical strings at different addresses). --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) | ||
It should be noted, however, that "ordinary" string literals (the ones that are included in BSL scripts and allocated at level start) seem to be always compared by content even if they're changed to completely new literals at runtime (as long as it's from the console). If you have two global string vars '''testVar''' and '''testVar2''', you can set them both to "bla" from the console, and '''testVar eq testVar2''' will evaluate as '''true''' - so apparently the comparison becomes lazy (by pointer) if at least one of the strings (pointers) is in the dynamic range used by runtime events, but for new strings from the console (also dynamically allocated) it still uses the non-lazy comparison. --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) | It should be noted, however, that "ordinary" string literals (the ones that are included in BSL scripts and allocated at level start) seem to be always compared by content even if they're changed to completely new literals at runtime (as long as it's from the console and not from OBJC events). If you have two global string vars '''testVar''' and '''testVar2''', you can set them both to "bla" from the console, and '''testVar eq testVar2''' will evaluate as '''true''' - so apparently the comparison becomes lazy (by pointer) if at least one of the strings (pointers) is in the dynamic range used by runtime events, but for new strings from the console (also dynamically allocated) it still uses the non-lazy comparison. --[[User:Geyser|geyser]] ([[User talk:Geyser|talk]]) 13:10, 18 May 2020 (CEST) |
Revision as of 11:18, 18 May 2020
Failing string comparison
There is also a bug with DOOR textures. XML:BINA/OBJC/DOOR#tags
We could try to capitalize everything, maybe that helps. --paradox-01 (talk) 12:12, 14 May 2020 (CEST)
Can someone describe the bug in more detail so I can take a look? --geyser (talk) 14:39, 14 May 2020 (CEST)
- Oh, OK, silly me, I should have read the TRGV page to learn about the string comparison bug. However, I don't understand how the TRGV string comparison is related to DOOR textures (DOOR textures are a permanent level setting, nothing to do with BSL - right?) --geyser (talk) 16:20, 14 May 2020 (CEST)
This is what s10k wrote: https://wiki.oni2.net/w/index.php?title=XML%3ABINA%2FOBJC%2FTRGV&type=revision&diff=26530&oldid=26524
Basically "String" eq "String" returns false when one expression is delivered by TV and one expression delivered from a 'native' BSL variable.
Maybe the comparison fails because at some side (left or right) the string is made toUpper. We have seen a similar bug when the engine reads texture names.
So the idea is that "STRING" eq "STRING" might work, just maybe. --paradox-01 (talk) 16:25, 14 May 2020 (CEST)
The analogy to Doors would be that "String(fromCJBO)" eq "String(fromTextureFileName)" fails because of the bugged comparison. (The code for comparison might be used at both locations - BSL and Door.) --paradox-01 (talk) 16:26, 14 May 2020 (CEST)
To check the toUpper hypothesis, you don't need to change the game data, just test against "CHAR_0". Another thing to do (which I did) is set testVar = ai_name (similar to what is done with my_save_point = save_point in many of Bungie's scripts). I then print testVar (it displays as char_0, both with dmsg and at the dev console, i.e., with no uppercase) and finally check testVar eq "char_0" instead of ai_name eq "char_0" (it fails). I also quick-changed char_0 to KONOKO in Konoko's CHAR. And it still fails the same way: both strings display the same value KONOKO, but testVar eq "KONOKO" (or testVar eq KONOKO) evaluates to false (same as for "char_0" before the hack). However, testVar eq testVar, ai_name eq ai_name and testVar eq ai_name all evaluate to true. So I really think it's a non-printable char in the character name as sent from the runtime event (end-of-line most likely). -- geyser (talk) 19:41, 14 May 2020 (CEST)
Is there a way / "geyser hack" to count the signs a la length(string)? :D --'Dox
You mean something to count the symbols/characters/bytes? Well, none that I know of, at least not from within Oni's game/console and scripts. Neo or the Daodan folks would be able to help, but I have never had the patience to look at Oni's ASM myself. I am pretty sure that the problem is a trailing end-of-line, though. --geyser (talk) 22:37, 14 May 2020 (CEST)
One way to check would be to deliberately initialize a string variable with an end-of-line, and use it to check against the character name received from the TRGV event. Daodan DLL's sprintf would be the simplest way to create a string variable that includes an end-of-line. Or, if sprintf doesn't support \n for some reason, it should be possible to hex-edit a custom name for an AISA character, and then retrieve its name into a string variable using d_name. Then again, I guess it would be easy enough to implement strlen. --geyser (talk) 00:38, 15 May 2020 (CEST)
Hi guys,
I saw this page and got interested in the topic.
I tried to run some tests and did some runtime memory probing.
See BSL:String comparison for results.
--Loser (talk) 20:54, 17 May 2020 (CEST)
It doesn't resolve the current situation but it is a help nonetheless and kills some headache about bsl scripting.... If someone really needed to he can use your work as foundation. Thanks you Loser for looking into this. --paradox-01 (talk) 08:59, 18 May 2020 (CEST)
Thanks for checking the runtime ai_name and how it doesn't have any extra characters after all. I am not yet convinced that the comparison is by pointer and not by content, but if it is so, then it would mean that string arguments passed from runtime events (TRGV etc) are completely unusable - because they have their own unique pointer, which will never match anything you compare it with (unless you do something like BOB_string = ai_name, but then the two strings are in fact one and the same, and there's nothing left to compare). --geyser (talk) 11:05, 18 May 2020 (CEST)
I have confirmed in my own way that the strings coming from runtime events are (apparently) compared by pointer rather than by content. Suppose you define two global string vars, dead_name and dead_name_too. Then you kill A_t48 twice (after force-spawning him), with t48_dead(string ai_name) performing the assignment dead_name = ai_name. Between the two deaths, do dead_name_too = dead_name from the console (this is now a redirect to the same string data, and dead_name_too eq dead_name evaluates to true). After the second A_t48 death, try dead_name_too eq dead_name again, and see that it evaluates to false now (there used to be one string, and now it's two identical strings at different addresses). --geyser (talk) 13:10, 18 May 2020 (CEST)
It should be noted, however, that "ordinary" string literals (the ones that are included in BSL scripts and allocated at level start) seem to be always compared by content even if they're changed to completely new literals at runtime (as long as it's from the console and not from OBJC events). If you have two global string vars testVar and testVar2, you can set them both to "bla" from the console, and testVar eq testVar2 will evaluate as true - so apparently the comparison becomes lazy (by pointer) if at least one of the strings (pointers) is in the dynamic range used by runtime events, but for new strings from the console (also dynamically allocated) it still uses the non-lazy comparison. --geyser (talk) 13:10, 18 May 2020 (CEST)