Incorrect .exe data offsets
Closed this issue · 6 comments
I've noticed that there seem to be some mistakes in the locations for .exe data in the aExeStrings.txt file and the acdExeStrings.txt file.
aExeStrings.txt contains:
MaleMainRaceAttributes=0x35FC3
FemaleMainRaceAttributes=0x35FCB
GuardAttributes=0x35FD3
but I've found that this GuardAttributes value actually points at the data for male Redguards. It should be GuardAttributes=0x36043. Same issue in acdExeStrings.txt: the value there reads GuardAttributes=0x361D3, but it should be GuardAttributes=0x36243.
Also, aExeStrings.txt contains CreatureAttributes=0x35FDC, but this points into the attribute array for the Redguard female (starting at index 1, not 0, so it's also off by 1 in that regard). It should be CreatureAttributes=0x3608B. For acdExeStrings.txt it should be CreatureAttributes=0x3628B.
The data in that area of the executable looks like this (from the decompressed A.EXE file (1.06)), starting from 0x39CF3 (0x35FC3 in aExeStrings.txt (a difference of 0x3D30)).
MaleBretonAttributes
4d 80 80 db[8]
66 66 4d
66 66
FemaleBretonAttributes
4d 80 80 db[8]
66 66 4d
66 66
MaleRedguardAttributes (`GuardAttributes` currently points here)
66 4d 4d db[8]
66 80 80
66 66
FemaleRedguardAttributes (`CreatureAttributes` currently points here, at index 1)
4d 4d 4d db[8]
80 80 80
66 66
MaleNordAttributes
80 4d 4d db[8]
4d 66 80
66 66
FemaleNordAttributes
66 4d 66 db[8]
66 66 66
66 80
MaleDarkElfAttributes
80 80 4d db[8]
80 80 66
66 66
FemaleDarkElfAttributes
66 80 4d db[8]
66 66 66
66 66
MaleHighElfAttributes
4d 80 80 db[8]
66 66 4d
66 66
FemaleHighElfAttributes
4d 80 66 db[8]
66 66 4d
80 66
MaleWoodElfAttributes
66 66 66 db[8]
80 80 4d
66 4d
FemaleWoodElfAttributes
66 66 66 db[8]
66 66 66
66 66
MaleKhajiitAttributes
66 66 4d db[8]
80 66 4d
66 80
FemaleKhajiitAttributes
66 66 4d db[8]
66 80 4d
66 80
MaleArgonianAttributes
66 66 66 db[8]
80 80 4d
66 4d
FemaleArgonianAttributes
66 66 66 db[8]
66 66 66
66 66
GuardAttributes0 (I'm suggesting pointing `GuardAttributes` here)
b3 80 80 db[8]
99 99 b3
80 80
GuardAttributes1
cc 80 80 db[8]
b3 b3 cc
80 80
GuardAttributes2
e6 80 80 db[8]
cc cc e6
80 80
GuardAttributes3
99 80 80 db[8]
80 80 99
80 80
GuardAttributes4
b3 80 80 db[8]
99 99 b3
80 80
GuardAttributes5
cc 80 80 db[8]
b3 b3 cc
80 80
GuardAttributes6
80 80 80 db[8]
66 66 80
80 80
GuardAttributes7
99 80 80 db[8]
80 80 99
80 80
GuardAttributes8
b3 80 80 db[8]
99 99 b3
80 80
RatAttributes (I'm suggesting pointing `CreatureAttributes` here)
33 19 19 db[8]
5a 4c 4c
66 80
(Continues with GoblinAttributes, etc.)
Thanks @Allofich. I fixed the attribute offsets and printed the values after converting them to 0-100. These look correct to me, so I'll commit the changes.
Rat: 20, 10, 10, 35, 30, 30, 40, 50
Goblin: 30, 20, 30, 40, 30, 30, 30, 50
Lizard Man: 70, 30, 40, 60, 70, 60, 30, 50
...
Vampire: 80, 33, 90, 95, 70, 90, 80, 70
Lich: 90, 90, 90, 90, 80, 90, 20, 80
Jagar Tharn: 60, 100, 90, 95, 85, 90, 60, 75Male 0: 30, 50, 50, 40, 40, 30, 40, 40
Male 1: 30, 50, 50, 40, 40, 30, 40, 40
...
Male 6: 50, 50, 30, 50, 50, 40, 40, 40
Male 7: 40, 50, 30, 40, 40, 40, 40, 40Female 0: 30, 50, 50, 40, 40, 30, 40, 40
Female 1: 40, 30, 30, 40, 50, 50, 40, 40
...
Female 6: 40, 50, 30, 40, 40, 40, 40, 40
Female 7: 30, 50, 50, 40, 40, 30, 40, 40Guard 0: 70, 50, 50, 60, 60, 70, 50, 50
Guard 1: 80, 50, 50, 70, 70, 80, 50, 50
...
Guard 7: 60, 50, 50, 50, 50, 60, 50, 50
Guard 8: 70, 50, 50, 60, 60, 70, 50, 50It seems the formula for conversion is
uint8_t oldValue = ...;
double percent = (double)oldValue / 256.0;
int newValue = (int)round(percent * 100.0);Edit: actually I think I messed up, the Redguard ones don't seem to match. Maybe I should've left them in hex format :/
@afritz1, if those values in your comment above are what are being loaded then the loading function probably needs adjustment. It looks like for male and female attributes you started at MaleMainRaceAttributes and FemaleMainRaceAttributes, respectively, and then loaded in the next 8 contiguous byte arrays, but if you want to load all of them you should be reading an array, then skipping the next array (because it is for the other gender), then reading the next, then skipping the next, etc. because they go in the pattern Male, Female, Male, Female.
The original game gets the position for the needed array like:
if male
arrayPosition = MaleMainRaceAttributes + 16 bytes * RaceID
if female
arrayPosition = FemaleMainRaceAttributes + 16 bytes * RaceID
I will fix it now.
These are my new results:
Male 0: 4d, 80, 80, 66, 66, 4d, 66, 66
Female 0: 4d, 80, 80, 66, 66, 4d, 66, 66
Male 1: 66, 4d, 4d, 66, 80, 80, 66, 66
Female 1: 4d, 4d, 4d, 80, 80, 80, 66, 66
Male 2: 80, 4d, 4d, 4d, 66, 80, 66, 66
Female 2: 66, 4d, 66, 66, 66, 66, 66, 80
Male 3: 80, 80, 4d, 80, 80, 66, 66, 66
Female 3: 66, 80, 4d, 66, 66, 66, 66, 66
Male 4: 4d, 80, 80, 66, 66, 4d, 66, 66
Female 4: 4d, 80, 66, 66, 66, 4d, 80, 66
Male 5: 66, 66, 66, 80, 80, 4d, 66, 4d
Female 5: 66, 66, 66, 66, 66, 66, 66, 66
Male 6: 66, 66, 4d, 80, 66, 4d, 66, 80
Female 6: 66, 66, 4d, 66, 80, 4d, 66, 80
Male 7: 66, 66, 66, 80, 80, 4d, 66, 4d
Female 7: 66, 66, 66, 66, 66, 66, 66, 66Looks correct!