Others should do the code commits if they want to...
Quote
PyDAT correction: portdata.dat fidget animation fields are mislabeled
While investigating why the Dropship portrait would only ever play fid00 and fid01, I traced the portrait-selection code in StarCraft 1.16.1.
The result is that this is primarily a PyDAT field-labeling problem.
PyDAT currently presents the portrait entry approximately as:
The last four fields are misleadingly named.
They are not separate "idle change", "talking change", and unknown parameters.
For the portrait fidget selector, StarCraft reads all four of those byte fields consecutively as the probability weights for:
In other words, the current PyDAT labels:
A more accurate PyDAT representation would therefore be something like:
or:
This distinction is important because the existing labels strongly suggest that:
That is not how StarCraft actually uses them.
The executable's portrait fidget routine is around 0x44EB90.
It obtains a random value, then processes these four portdata.dat bytes cumulatively. Each byte contributes the probability range belonging to one of the four possible fidget animations.
Conceptually, the logic is approximately:
The corresponding runtime portdata.dat arrays are at:
So the ordering in the DAT is unambiguously:
This explains the Dropship behavior.
If one edits the portrait in PyDAT according to the current field descriptions, it is natural to modify only "Idle SMK Change" and perhaps "Talking SMK Change".
Doing that only gives probability to:
If the two "Unknown" values remain zero, then:
and those animations will consequently never be selected.
This can easily look like a StarCraft hardcoded limitation to two fidget animations, but it is not.
StarCraft 1.16.1 explicitly supports four portrait fidget animations:
The filename-generation/loading code is also capable of requesting all four.
There is additionally a fallback mechanism: if a requested fidXX file cannot be opened, StarCraft tries lower-numbered fidget files. So a missing fid02/fid03 can also make the problem less obvious by causing an earlier animation to appear instead.
For example, to give all four fidget animations approximately equal probability, the portdata.dat entry can use:
Which, using PyDAT's current labels, means:
The important correction for PyDAT is therefore:
Current:
Should represent:
The words "Idle" and "Talking" in the current four field names are especially problematic, because all four values participate in selection of the idle/fidget fidXX portrait animations.
The talking portrait SMKs are handled separately and should not be inferred from these labels.
So this is not merely a case where two fields are still unknown: all four fields have a coherent known function, and PyDAT's current descriptions are incorrect.
While investigating why the Dropship portrait would only ever play fid00 and fid01, I traced the portrait-selection code in StarCraft 1.16.1.
The result is that this is primarily a PyDAT field-labeling problem.
PyDAT currently presents the portrait entry approximately as:
Code
Idle Portrait
Talking Portrait
Idle SMK Change
Talking SMK Change
Idle Unknown
Talking Unknown
Talking Portrait
Idle SMK Change
Talking SMK Change
Idle Unknown
Talking Unknown
The last four fields are misleadingly named.
They are not separate "idle change", "talking change", and unknown parameters.
For the portrait fidget selector, StarCraft reads all four of those byte fields consecutively as the probability weights for:
Code
fid00
fid01
fid02
fid03
fid01
fid02
fid03
In other words, the current PyDAT labels:
Code
Idle SMK Change -> probability/weight of fid00
Talking SMK Change -> probability/weight of fid01
Idle Unknown -> probability/weight of fid02
Talking Unknown -> probability/weight of fid03
Talking SMK Change -> probability/weight of fid01
Idle Unknown -> probability/weight of fid02
Talking Unknown -> probability/weight of fid03
A more accurate PyDAT representation would therefore be something like:
Code
Fidget 0 Chance
Fidget 1 Chance
Fidget 2 Chance
Fidget 3 Chance
Fidget 1 Chance
Fidget 2 Chance
Fidget 3 Chance
or:
Code
fid00 Weight
fid01 Weight
fid02 Weight
fid03 Weight
fid01 Weight
fid02 Weight
fid03 Weight
This distinction is important because the existing labels strongly suggest that:
- "Idle SMK Change" controls idle portrait changes.
- "Talking SMK Change" controls talking portrait changes.
- The last two bytes are unidentified values.
That is not how StarCraft actually uses them.
The executable's portrait fidget routine is around 0x44EB90.
It obtains a random value, then processes these four portdata.dat bytes cumulatively. Each byte contributes the probability range belonging to one of the four possible fidget animations.
Conceptually, the logic is approximately:
Code
roll random value
if roll falls inside weight 0:
use fid00
else if roll falls inside weight 0 + weight 1:
use fid01
else if roll falls inside weight 0 + weight 1 + weight 2:
use fid02
else if roll falls inside weight 0 + weight 1 + weight 2 + weight 3:
use fid03
if roll falls inside weight 0:
use fid00
else if roll falls inside weight 0 + weight 1:
use fid01
else if roll falls inside weight 0 + weight 1 + weight 2:
use fid02
else if roll falls inside weight 0 + weight 1 + weight 2 + weight 3:
use fid03
The corresponding runtime portdata.dat arrays are at:
Code
0x655E10
0x6560A8
0x656038
0x656118
0x6560A8
0x656038
0x656118
So the ordering in the DAT is unambiguously:
Code
byte 0 -> fid00
byte 1 -> fid01
byte 2 -> fid02
byte 3 -> fid03
byte 1 -> fid01
byte 2 -> fid02
byte 3 -> fid03
This explains the Dropship behavior.
If one edits the portrait in PyDAT according to the current field descriptions, it is natural to modify only "Idle SMK Change" and perhaps "Talking SMK Change".
Doing that only gives probability to:
Code
fid00
fid01
fid01
If the two "Unknown" values remain zero, then:
Code
fid02 = 0 chance
fid03 = 0 chance
fid03 = 0 chance
and those animations will consequently never be selected.
This can easily look like a StarCraft hardcoded limitation to two fidget animations, but it is not.
StarCraft 1.16.1 explicitly supports four portrait fidget animations:
Code
fid00.smk
fid01.smk
fid02.smk
fid03.smk
fid01.smk
fid02.smk
fid03.smk
The filename-generation/loading code is also capable of requesting all four.
There is additionally a fallback mechanism: if a requested fidXX file cannot be opened, StarCraft tries lower-numbered fidget files. So a missing fid02/fid03 can also make the problem less obvious by causing an earlier animation to appear instead.
For example, to give all four fidget animations approximately equal probability, the portdata.dat entry can use:
Code
fid00 Weight = 25
fid01 Weight = 25
fid02 Weight = 25
fid03 Weight = 25
fid01 Weight = 25
fid02 Weight = 25
fid03 Weight = 25
Which, using PyDAT's current labels, means:
Code
Idle SMK Change = 25
Talking SMK Change = 25
Idle Unknown = 25
Talking Unknown = 25
Talking SMK Change = 25
Idle Unknown = 25
Talking Unknown = 25
The important correction for PyDAT is therefore:
Current:
Code
Idle SMK Change
Talking SMK Change
Idle Unknown
Talking Unknown
Talking SMK Change
Idle Unknown
Talking Unknown
Should represent:
Code
fid00 Weight
fid01 Weight
fid02 Weight
fid03 Weight
fid01 Weight
fid02 Weight
fid03 Weight
The words "Idle" and "Talking" in the current four field names are especially problematic, because all four values participate in selection of the idle/fidget fidXX portrait animations.
The talking portrait SMKs are handled separately and should not be inferred from these labels.
So this is not merely a case where two fields are still unknown: all four fields have a coherent known function, and PyDAT's current descriptions are incorrect.
Ultimate StarCraft: Age of Darkness stand-alone no-cd download (no false positives)






