Antal1987
Warlord
Last week I created a thread, describing an idea of making of patch framework for C3C. And now I'm glad to introduce my first release of this patch framework.
Patch framework_v1
I also published framework sources to github ...
with a bonus: Civ3Conquests.h. That huge (6K lines) header contains all data types I could determine and recognize. Some of them will be described in details soon.
First patch I impelemented in the Framework is the Science Age Patch (see thread)
Origin patch was placed in PE-header alignment space.
And the call code was:
Now, I encapsulated patch code into the patch framework. Here is how it looks like:
Convenient, huh?
And the call is now:
So now any complex patch can be easily written inside patch framework using predefined data structures and then it just should be called in proper place.
Patch framework_v1
I also published framework sources to github ...
with a bonus: Civ3Conquests.h. That huge (6K lines) header contains all data types I could determine and recognize. Some of them will be described in details soon.
First patch I impelemented in the Framework is the Science Age Patch (see thread)
Origin patch was placed in PE-header alignment space.
Code:
CPU Disasm
Address Hex dump Command Comments
00400200 83EC 04 SUB ESP,4
00400203 C704E4 000080 MOV DWORD PTR SS:[ESP],3F800000
0040020A D905 5C906600 FLD DWORD PTR DS:[Science_Age_Ratio] ; FLOAT 3.000000
00400210 D824E4 FSUB DWORD PTR SS:[ESP]
00400213 D91CE4 FSTP DWORD PTR SS:[ESP]
00400216 DB44E4 0C FILD DWORD PTR SS:[ESP+0C]
0040021A D80CE4 FMUL DWORD PTR SS:[ESP]
0040021D 83C4 04 ADD ESP,4
00400220 E8 4F9F2400 CALL __ftol
00400225 89C7 MOV EDI,EAX
00400227 0186 F8000000 ADD DWORD PTR DS:[ESI+0F8],EAX
0040022D E9 19201600 JMP 0056224B
Code:
CPU Disasm
Address Hex dump Command Comments
00562228 |. /74 21 JE SHORT 0056224B
0056222A |. |8B15 6C26A500 MOV EDX,DWORD PTR DS:[Current_Turn]
00562230 |. |8B86 D4150000 MOV EAX,DWORD PTR DS:[ESI+15D4] ; _this->Science_Age_End
00562236 |. |3BD0 CMP EDX,EAX
00562238 |. |7F 11 JG SHORT 0056224B
0056223A ^|E9 C1DFE9FF JMP 00400200
0056223F |90 NOP
00562240 |90 NOP
00562241 |90 NOP
00562242 |90 NOP
00562243 |90 NOP
00562244 |90 NOP ; _Total_Bulbs = (_Total_Bulbs * 1.25);
00562245 |90 NOP
00562246 |90 NOP
00562247 |90 NOP
00562248 |90 NOP
00562249 |90 NOP ; _Total_Bulbs = (_Total_Bulbs * 1.25);
0056224A |90 NOP
0056224B |> \85FF TEST EDI,EDI
Now, I encapsulated patch code into the patch framework. Here is how it looks like:
Code:
int CPatchFramework::CorrectScienceAgeBulbs(class_Leader * Civ, int Total_Bulbs)
{
float * p_Science_Age_Ratio = (float *)0x0066905C;
int D_Bulbs = (int)((float)Total_Bulbs * (*p_Science_Age_Ratio - 1.00));
Civ->Research_Bulbs += D_Bulbs;
return Civ->Research_Bulbs;
}
Convenient, huh?
And the call is now:
Code:
CPU Disasm
Address Hex dump Command Comments
00562238 |. /7F 11 JG SHORT 0056224B Comments
0056223A 56 PUSH ESI
0056223B 57 PUSH EDI
0056223C 56 PUSH ESI
0056223D A1 74967300 MOV EAX,DWORD PTR DS:[C3CPF_Object]
00562242 8B00 MOV EAX,DWORD PTR DS:[EAX]
00562244 FF50 08 CALL DWORD PTR DS:[EAX+8] ; call CPatchFramework::CorrectScienceAgeBulbs
00562247 89C7 MOV EDI,EAX
00562249 5E POP ESI
0056224A |90 NOP
0056224B |> \85FF TEST EDI,EDI
So now any complex patch can be easily written inside patch framework using predefined data structures and then it just should be called in proper place.