Project Perfect Mod Forums
:: Home :: Get Hosted :: PPM FAQ :: Forum FAQ :: Privacy Policy :: Search :: Memberlist :: Usergroups :: Register :: Profile :: Log in to check your private messages :: Log in ::


The time now is Fri Apr 19, 2024 3:18 am
All times are UTC + 0
Absolute PrismSupportModifier= bug fix bug
Moderators: Ares Support Team at PPM, Global Moderators, Red Alert 2 Moderators
Post new topic   Reply to topic Page 1 of 1 [4 Posts] Mark the topic unread ::  View previous topic :: View next topic
Author Message
Iran
Pyro Sniper


Joined: 23 Mar 2011

PostPosted: Sat Dec 06, 2014 2:58 pm    Post subject:  Absolute PrismSupportModifier= bug fix bug Reply with quote  Mark this post and the followings unread

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%.

That's because the Ares fix does an integer divide by 100 instead of a floating point divide (because RulesClass::PrismSupportModifier is an integer in both YRpp and the game). The bugged fix is located here: https://github.com/Ares-Developers/Ares/blob/master/src/Misc/Bugfixes.cpp#L145

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.

The fix I'm using for the absolute PSM bug is:

Code:
@LJMP 0x00671152, _RulesClass__Read_General_Absolute_PrismSupportModifier_Bug_Fix

_100_FP: dd 100

_RulesClass__Read_General_Absolute_PrismSupportModifier_Bug_Fix:

   fild dword [esi+49Ch]
   fidiv dword [_100_FP]
   
   jmp 0x00671158


Code:
[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

Back to top
View user's profile Send private message
AlexB
Commander


Joined: 31 May 2010
Location: Germany

PostPosted: Tue Dec 09, 2014 4:39 pm    Post subject: Reply with quote  Mark this post and the followings unread

Absolutely correct. Thanks for pointing this out, Iran!

Will be fixed in the next Ares binary.

_________________

Back to top
View user's profile Send private message
Iran
Pyro Sniper


Joined: 23 Mar 2011

PostPosted: Tue Dec 09, 2014 7:00 pm    Post subject: Reply with quote  Mark this post and the followings unread

It's not a huge issue of course and the game code which is being fixed is pretty weird so it's a small, understandable oversight.

Back to top
View user's profile Send private message
Dutchygamer
President


Joined: 18 Jun 2005
Location: Dordrecht, the Netherlands

PostPosted: Thu Dec 11, 2014 8:09 pm    Post subject: Reply with quote  Mark this post and the followings unread

Quote:
[15:20:55] 18<22DCoder133718> I like the fact that nobody has noticed this so far

This is something that all developers will notice multiple times during a project xD

Back to top
View user's profile Send private message Send e-mail Skype Account
Display posts from previous:   
Post new topic   Reply to topic Page 1 of 1 [4 Posts] Mark the topic unread ::  View previous topic :: View next topic
 
Share on TwitterShare on FacebookShare on Google+Share on DiggShare on RedditShare on PInterestShare on Del.icio.usShare on Stumble Upon
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


Powered by phpBB © phpBB Group

[ Time: 0.1748s ][ Queries: 11 (0.0076s) ][ Debug on ]