Posted: Sat Dec 06, 2014 2:58 pm Post subject:
Absolute PrismSupportModifier= bug fix bug
On maps where the absolute PrismSupportModifier bug normally occurs (so maps which don't define their own PrismSupportModifier= but do have their own [General] section, note that the Ares documentation is wrong and there needs to be at least one keyword under [General] for the bug to occur) the Rulesmd.ini PSM value is rounded to floor(PSM/100) * 100 by the Ares fix for the original bug. So if RulesMD.ini PSM is 150% the game will round it to 100% and 250% will be rounded to 200%.
After the bugged fix is run the game code will immediately place RulesClass::PrismSupportModifier (which the Ares fix modifies by integer dividing by 100) into the floating point stack after which its placed in a s tack variable as arg for the IniClass::Get_Float call. The correct fix would change the current integer divide into a floating point divide and push the floating point divide result onto the floating point stack and skip the pushing of the PSM value.
[14:59:51] <Iran> hi I think there might be a bug with the absolute PrismSupportModifier code, it does an integer divide of values like 150 with 100, so if the RulesMD.ini value is 150% it will give you 1 (which it will use if the map doesn't define its own value) and it will multiple it by 100 after the IniClass::Get_Float() call
[15:00:10] <Iran> *the ares bug fix for the absolute PrismSupportModifier bug
[15:00:25] <Iran> what needs to be done is a float divide instead of integer divide
[15:01:28] <Iran> https://github.com/Ares-Developers/Ares/blob/master/src/Misc/Bugfixes.cpp#L145 it's this code
[15:04:40] * lh_mouse has quit (Quit: rebooting)
[15:06:36] <DCoder1337> the code you linked runs during the read of the rules into RulesClass, right?
[15:06:45] <Iran> yes
[15:06:55] <DCoder1337> RulesClass::PrismSupportModifier is an integer, right?
[15:07:01] <Iran> yes
[15:07:24] <Iran> and the generated ares code is integer math, using multiplication and shfit to divide
[15:07:52] <DCoder1337> what will happen if you write Rules->PrismSupportModifier = 1.5 ?
[15:08:00] <DCoder1337> instead of that line of division?
[15:08:25] <Iran> that's impossible as PrismSupportModifier is an integer
[15:08:51] <DCoder1337> you said "divide 150 with 100"
[15:09:05] <DCoder1337> what result do you expect to get from that?
[15:09:08] <DCoder1337> 1 or 1.5?
[15:09:12] <Iran> yeah, using integer division so the value is 1.5 and it gets rounded to 1
[15:09:36] <DCoder1337> and then 1 is stored into the ->PrismSupportModifier, right?
[15:09:39] <Iran> the code modifies PrismSupportModifier but that isn't needed as PrimSupportModifier is pushing onto the floating point stack as argument immediately afterwards (in the game code)
[15:10:25] <Iran> so what the Ares code can do is modify the hook slightly (the hooking address or the return address) and the push the floating point value calculated using floating point divide onto the stack instead of having the game code do it
[15:10:32] <Iran> DCoder1337: yes
[15:10:48] <Iran> *is pushed onto
[15:11:46] <DCoder1337> I don't have the game code in front of me, but it sounds reasonable
[15:11:50] <Iran> .text:00671152 fild dword ptr [esi+49Ch] <-- this is the hook address of the Ares code and the ares code returns to this instruction
[15:12:12] <Iran> esi+49Ch is the offset for PrismSupportModifier
[15:12:24] <DCoder1337> uh
[15:12:45] <Iran> the ares code for the hook is:
[15:12:46] <Iran> .text:1005CCE0 mov eax, [esp+arg_0]
[15:12:46] <Iran> .text:1005CCE4 mov ecx, [eax+0Ch]
[15:12:46] <Iran> .text:1005CCE7 mov eax, 51EB851Fh
[15:12:46] <Iran> .text:1005CCEC imul dword ptr [ecx+49Ch]
[15:12:46] <Iran> .text:1005CCF2 sar edx, 5
[15:12:46] <Iran> .text:1005CCF5 mov eax, edx
[15:12:46] 20<Iran>30 .text:1005CCF7 shr eax, 1Fh
[15:12:46] 20<Iran>30 .text:1005CCFA add eax, edx
[15:12:46] 20<Iran>30 .text:1005CCFC mov [ecx+49Ch], eax
[15:12:46] 20<Iran>30 .text:1005CD02 xor eax, eax
[15:12:46] 20<Iran>30 .text:1005CD04 retn
[15:12:54] 18<22DCoder133718> wait
[15:13:18] 18<22DCoder133718> thing is, as long as PSM is an int, all the code working with it expects an int
[15:13:38] 20<Iran>30 nope
[15:13:45] 20<Iran>30 IniClass::Get_Float is called
[15:13:57] 20<Iran>30 the result is multiplied by 100 then converted to int
[15:14:23] 20<Iran>30 and stored into PrismSupportModifier
[15:14:30] 18<22DCoder133718> if you want to store PSM as a float, you will need to create a new field in the RulesExt and patch all the PSM code to load that value instead
[15:14:37] 20<Iran>30 no I dont want to
[15:14:47] 18<22DCoder133718> ooooooor, you will need to hook all the existing PSM code to treat it as a float
[15:15:27] 20<Iran>30 PSM is an int which is read in as float for IniClass::Get_Float() default arg if the keyword is missing, then afterwards it's multiplied by 100 and converted to int
[15:15:42] 18<22DCoder133718> right, and then the game carries it around as an int
[15:15:54] 20<Iran>30 and the stored value when this is done is 150 for 150% etc
[15:16:00] 20<Iran>30 yeah
[15:16:18] 18<22DCoder133718> ah, now I think I get it
[15:16:39] 18<22DCoder133718> I can see a sequence of events where this fix doesn't work right
[15:17:13] 18<22DCoder133718> but meh, that's just a theory and I don't work on Ares anymore, so I can't comment :) wait for Alex
[15:17:17] 20<Iran>30 the rulesmd.ini value is 150%, which the fucntion reads at 1.5 float
[15:17:55] 20<Iran>30 *as
[15:19:33] 20<Iran>30 well to make it more simple...if the rulesmd.ini value is 150 and the map doesn't have the value defined it should read in 150 then after IniClass::Get_Float and the multiply it should read in back 150, instead it reads in back 100
[15:20:55] 18<22DCoder133718> I like the fact that nobody has noticed this so far
[15:22:33] 23* lh_mouse (~lh_mouse@unaffiliated/lh-mouse/x-398600723) has joined
[15:25:24] 20<Iran>30 I just reproduced it in the code I copy pasted from the compiled ares code, I'll try with my own fix using floating point now
[15:25:39] 20<Iran>30 that doesn't mean that Ares suffers from the bug, but it probably does
[15:26:23] 20<Iran>30 the bug doesn't occur when you have [General] with no keyswords under the section, even though the documentation implies it will
[15:44:46] 20<Iran>30 yeah my FP code fixes it
[15:48:54] 20<Iran>30 well it's pretty hard to notice the bug as I dont think a difference of 50% really matters
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum