Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: ERA II - Source code - Help and discussion
Thread: ERA II - Source code - Help and discussion This thread is 11 pages long: 1 2 3 4 5 6 7 8 9 10 11 · «PREV / NEXT»
Bersy
Bersy


Honorable
Supreme Hero
posted January 03, 2020 10:29 PM

Quote:
I will make it just need some time to 2X check few code parts.

Ok.

Quote:
#21
Keep in mind that there is another overloaded version of "ErmCurrHero" in Era.pas with same problem as first one you fixed.


I know. Will fix both, thanks.

Quote:

#22
Keep in mind that few color constant are added to "Heroes.pas"
HEROES_GOLD_COLOR = '0FFFE794';
I am not sure if it is used, but also has one "F" more that it is needed.

Indeed.

Quote:
That, at least, will make debugging faster.
For now i will continue with examination.

Could you show your solution?
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 04, 2020 02:46 PM
Edited by gamemaster at 15:08, 04 Jan 2020.

I tried to make fast github. But i fail . I am new with that versioning stuff and should figure out how to get basic control over it (delate mid versions, keep it cleen ...). I will do that when come back in 5-6 days.

Here is link with port so far.
It should compile without problems and game should work.
Heroes3-20-01-04.zip
It is whole folder with all unnecessary files in it. Just grab-and-pack version.

Setup output directories to location you need. I set it directly to heroes folder to ease debug. Ignore all comments with "BYME" tag and in Serbian language .

Code that make colored dialog work is located only in Rainbow.pas below line 480.
It should not be hard to locate two additional functions and location where i hook them. I target patch location same as RoseCavalier did but with fix address. Note that i did some voodoo magic to alter eax at that address. But Core.HOOKTYPE_BRIDGE make backup of eax and i needed to override it in backup. That is why i override EBP-$38. If there is some elegant solution to alter eax based on some proxy function let me know.

Also you will notice that i used lot of unsafe code and bad practices (hard-coded index for dll retrieval, patching without checking HD dll version ...). For now it is in testing phase and it should be write better and safer later.

General note:
At begin of each file you will see some type conversion map.
// String --> myAStr
// Char   --> myChar
That was main idea of port. Just to replace type string with ansistring. But with some helper type that will make it easier to track and maintain. in PortSteps.txt you can find incomplete list of steps i did. For now it is around 90% accurate.

Any suggestion in this stage will be appreciated.

23#
Is there any chance to get latest source code of patcher_x86.dll?
I see some 2.8 versions on internet but link is expired. And if i am not wrong we now use 4.5.4 or something like that.
Perhape it can be ported also, and make it compatible with unicode so we can avoid casting to ansistring.
Core.p.WriteDataPatch(Ptr($4CAD91), [myAStr('E99701000090')]);
Main problem is that you don't get error if unicode is passed as parameter but patch is silently skipped. So that can be problem in D2009+.

24#
Note that this line don't work in delphi XE.
Link
result := SysUtils.WrapText(StrLib.ExtractFromPchar(StartPos, EndPos - StartPos), #10, [#0..#255], 100);
See line Erm.pas line 1778 what i did. If you find solution let me know.

and, Happy New Year to you

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 05, 2020 03:35 PM

Thank you very much. Downloaded and saved code for future. Yep, nice solution with type aliases for legacy types and Legacy.pas.

#23
patcher is written in C++ and must be compatible with all plugins. So no, only ansi zero-terminated string.

24#
Note that this line don't work in delphi XE.

Ok, thanks.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 11, 2020 03:02 PM
Edited by gamemaster at 15:09, 11 Jan 2020.

Hi,
Nice to see new version. 2.9.4.
Last version from github ported to be up to date.

23#
I hoped to port patcher.dll to delphi as-is and just added overload for unicode. It should automatically do unicode to ansi conversion and call regular function.
That is to avoid silence error with unicode string or need to manually cast them all to ansi. (I made that mistake 100x till now )
I give another try in delphi. Perhaps i can make that override before call patcher.dll so no port will be needed. All will be done in era "__MoveToDwordArgs" in PatchApi.pas.

25#
Is 2.9.4 at github? I can see some fixes and upgrade of LoadImageAsPcx16 you mentioned in changelog but "Gameext.pas" still has version string 2.9.3.
Anyway not a problem just to know what is status.

26#
In "Heroes.pas" i saw that heroes and towns list are declared as packed array [0..999].
THeroes = packed array [0..999] of THero;
TTowns = packed array [0..999] of TTown;

Just wondering why it is packed? Any problems with regular array?
And, is 999 safe for heroes list? should it be 0..155?

This is from ida pro structure and it is same as in wog source
...
00021620 Heroes _Hero_ 156 dup(?)
...

meaning that at offset $21620 is array of 156 _Hero_ elements. Where hero is equivalent to THero from "Heroes.pas"


 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 12, 2020 12:35 AM

25#
Yes, it's on github. Updating constantly.

26#
Just for ssfety. Currently there is no difference between packed and ordinary arrays. Can be removed.

Quote:
And, is 999 safe for heroes list? should it be 0..155?

Yes, it's safe. Array bounds are not determined by array declaration. Era or Lua or Plugin can extend the structure to hold 300 heroes, 500 creatures or 1000 heroes. We just need a pointer to "quite big" array.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 12, 2020 11:03 PM
Edited by gamemaster at 23:06, 12 Jan 2020.

Quote:
25#
Yes, it's on github. Updating constantly.

Ok. It is now 2.9.4. I ported it also. I probably downloaded 2.9.3 before you push newest version .

Quote:
26#
Just for ssfety. Currently there is no difference between packed and ordinary arrays. Can be removed.

No problem for now. I asked to be sure that there is no some hidden reason for it.

Quote:
Yes, it's safe. Array bounds are not determined by array declaration. Era or Lua or Plugin can extend the structure to hold 300 heroes, 500 creatures or 1000 heroes. We just need a pointer to "quite big" array.

Hmm in current state i am not quite sure. That heroes array is part of bigger structure  and it is located in the middle of it. Bigger size can overlap with rest of it.

This is part of structure:
00021610 Towns_Ref       db ?
00021611                 db ? ; undefined
00021612                 db ? ; undefined
00021613                 db ? ; undefined
00021614 Towns           dd ?                              
00021618 Towns_End       dd ?
0002161C Towns_MemEnd    dd ?
00021620 Heroes          _Hero_ 156 dup(?)                
0004DF18 HeroOwner       db 156 dup(?)
0004DFB4 HeroMayBeHiredBy dd 156 dup(?)
0004E224 field_4E224     db 144 dup(?)
0004E2B4 ArtAllowed      db 144 dup(?)

I agree that it can (and should be ) be extended in one point in future.

This i just to note that if hero index are not 0..155 we will have corrupted value, in current (not extended).

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
RoseKavalier
RoseKavalier


Admirable
Supreme Hero
posted January 12, 2020 11:19 PM
Edited by RoseKavalier at 23:20, 12 Jan 2020.

gamemaster said:

Quote:
Yes, it's safe. Array bounds are not determined by array declaration. Era or Lua or Plugin can extend the structure to hold 300 heroes, 500 creatures or 1000 heroes. We just need a pointer to "quite big" array.

Hmm in current state i am not quite sure. That heroes array is part of bigger structure  and it is located in the middle of it. Bigger size can overlap with rest of it.

[...]

This i just to note that if hero index are not 0..155 we will have corrupted value, in current (not extended).


In the few cases where there are more than 156 heroes, the Heroes table is moved outside this structure (or at its end, with a greater allocation value during loadup) and obtaining said table is done by other means.

I'm not up to date with ERA code but it may already be using the generic method, in which case this should be 'safe'.
____________
My Let's Plays: Metataxer's Revenge - The Empire of The World 2

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 12, 2020 11:42 PM

Era provides method RedirectMemoryBlock and GetRealAddr. GetRealAddr is used to get new structure address by the old one.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 13, 2020 03:18 PM
Edited by gamemaster at 15:19, 13 Jan 2020.

@RoseKavalier
Yeah, moving outside structure is only safe option.

@Bersy
I see. You used that for adding more commands, to have 200 maximum.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 13, 2020 09:48 PM

gamemaster, right. Moreover, I will use GetRealAddr for more and more addresses and smart plugins must use it too, not relying on constant array addresses. For instance, new towns code in Lua from WoG 3.59 relocates vast amount of resources. Plugins should not depend on them.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 15, 2020 04:18 PM
Edited by gamemaster at 16:19, 15 Jan 2020.

Anyone know for what stand "[a]" "[s]" "[t]" in "x86 patches.txt" log.
For example:
[a][s][ ] 2: (0043E8AE 05 Patch  0000001097 - WoG), (0043E8AF 04 Patch  0000001426 - WoG)

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 15, 2020 04:21 PM

Maybe "a" is active? Because Bara's patches can be deactivated. Anyway, it's not clear.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 15, 2020 05:48 PM
Edited by gamemaster at 18:42, 15 Jan 2020.

It seems that "a-s" combination is when patches overlaps
and "a-s-t" is same but when lohook is in combination.


27#
Just messing with log I found that era overpatch itself at one address.

That place is in AdvErm.pas (at the end of file)
(* Make !?SN use always new unique buffer *)
Core.p.WriteDataPatch(Ptr($59A893), [myAStr('A1E0926900')]);
ApiJack.StdSplice(Ptr($59A890), @Hook_PlaySound, ApiJack.CONV_FASTCALL, 3);

Third line should make 3 byte patch but it is actually 8 according to "x86 patches.txt"
[a][s][ ] 4: (0059A893 05 Patch  0000001081 - WoG), (0059A894 04 Patch  0000001354 - WoG), (0059A893 05 Patch  0000001571 - D:_GamesHeroes3era.dll), (0059A890 08 Patch  0000001573 - D:_GamesHeroes3era.dll)

Can you just confirm that final patch at $59A890 is what we need

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 15, 2020 10:36 PM

Yes. The first line erases WoG hook, restoring original code. The second line installs splice hook, which uses patched code. It's ok and is done intentionally, but thanks for great investigation!
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 16, 2020 09:58 PM
Edited by gamemaster at 18:18, 17 Jan 2020.

Any reason why not use undo patch:
Core.GlobalPatcher.GetInstance('WoG').UndoAllAt(Ptr($59A893));
instead of:
Core.p.WriteDataPatch(Ptr($59A893), ['A1E0926900']);

Pros can be that we don't need to know what was original bytes at that location and multiple patch can be removed at once.
Cons is that patch that is removed wont be logged in "x86 patches.txt" at all.

28#
This is definition of hero variables
TWVars = array [0..255, 1..200] of integer;
Is reason for 256 hero limit (instead of 156) increased same as we discussed before in #26.
Reason why i ask is same as before, its overlap with other memories blocks.
I can not find is W memory block moved to another location where space is no problem?
If it is no moved  then CM3_RES_ADDR:=$A6929C (Era.Hook_CM3) is overrided by hero variables if i did not miss something?


See image. W start at $A4AB10 and if it has 156 heros end at $A69290. CM3_RES_ADDR is at $A6929C. If 256 heroes at original address then CM3 will be overrided?
I don't know exact mechanic in background, this is just static analysis i can make based on addresses so perhaps that is not problem.


29#
Hmm.. Era.pas:
SecSkillNamesBack: Heroes.PSecSkillNames = Ptr($A89190);
SecSkillDescsBack: Heroes.PSecSkillDescs = Ptr($A46BC4);
SecSkillTextsBack: Heroes.PSecSkillTexts = Ptr($A490A8);


it seems to me that address $A46BC4 is empty and actual string data begin 4 bytes after. Also structure is 28x3x4 lond and last item is not in structure.
There can be two causes: structure may point 4 bytes earlier or data is populated 4 bytes late.

Anyway, check $A46BC4 address.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 17, 2020 06:48 PM

Quote:
Any reason why not use undo patch:

It's the most simple and reliable solution, not depending on WoG patches being registered as pacther_x86 patches.

28#
This is definition of hero variables
TWVars = array [0..255, 1..200] of integer;

Same as with any extendable structure, that may be extended by any plugin. Hero can be stored in byte, so I take the highest value possible (0..255). Array size is never used for detection of the highest hero index.

29#
Thank you very much, I will recheck it.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted January 26, 2020 03:22 PM
Edited by gamemaster at 15:26, 26 Jan 2020.

Hi

Any changes in B2 library in last release?

This is new overload of Concat i can not find.

AdvErm.pas line 901
StrLib.Concat(Buf, BufSize, Buf, -1, Param.Value.pc, -1);


Also "TypeWrappers.TString" seems to has override that is not present in old version of B2.

Am i correct? Can you upload last version of B2.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted January 26, 2020 07:01 PM

Hi! Seems, that I've forgotten to sync with git. Recheck now, please. Also new RandMt unit is on approach with Mersenne Twister PRNG.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
gamemaster
gamemaster


Adventuring Hero
posted February 01, 2020 08:43 PM
Edited by gamemaster at 20:53, 01 Feb 2020.

Hi

Ported to 2.9.7.

One thing i spot, but did not analyse in depth.
Count you know right answer

Regarding Erm.pas.
I know that constant TRIGGER_FU1 has value 0 in some old versions.
New value 1 is introduced few version ago.

In GetTriggerReadableName function in Erm.pas there is line 619
...
 case EventID of
   {*} Erm.TRIGGER_FU1..Erm.TRIGGER_FU30000:
     result := 'OnErmFunction ' + SysUtils.IntToStr(EventID - Erm.TRIGGER_FU1 + 1);
...


In old and in new version there is +1. Is that ok?
I would expect +0 in new version if it was +1 in old one.

Again, i did not check what that do, or is it ok, just pass this observation to you .

Cya

PS: I saw that you send me HCM 38 days ago. Did not notice that .

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Bersy
Bersy


Honorable
Supreme Hero
posted February 01, 2020 11:29 PM
Edited by Bersy at 23:31, 01 Feb 2020.

Look, FU1 ID is 1. FU1 - 1 = 0. But in text it should be 'OnErmFunction 1'. Thus it's ok.
____________
Heroes 3 Era and everything for it. Releases folder for releases.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 11 pages long: 1 2 3 4 5 6 7 8 9 10 11 · «PREV / NEXT»
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.0749 seconds