02-02-2018, 09:45 AM
(This post was last modified: 02-02-2018, 12:59 PM by TheKillerVortex.)
O.K! SO! This is now where I'm at in my journey towards trying to understand how Diablo loads items and deals with that 'magic' item header (definitely 4-bytes in length) + 4-bytes for an alternate item header (appears to affect both magic items and unique items).
Upon loading a game in Diablo (minus normal routines; which I need to do more research on), the jist of program flow goes like this:
At this point: I am still completely lost as to how it's generating the affixes (prefixes/suffixes) for magical items.
I can definitively say that it is using some sort of linked-list structure of pointers to items (which are structures of pointers? with the item name (string) and respective static data for that type of item).
Hopefully I'll have an update later today.
The counter for these iterations is stored in the .data:
Beginning of epoch:
As far as I understand: An individual item is 76 bytes in size; This appears to be circumstantial.
Worn items seem to be 0x170 (368 bytes) apart from one another. I am not sure why.
This coincides between the "no item" value of 0xFF 0xFF 0xFF 0xFF (which comes after the ~8 byte item header).
EDIT: WOW! Is all I can say.
Diablo is INCREDIBLY[I] horrible with dealing with writing data. Horrendously inefficient in terms of senselessly, constantly rechecking the [I]same value, then writing over it, then changing it right back again without reason, only to move forward...
Also: It's been about ~11hrs consecutive hours since I made this post.
THAT is how long it took me to step through the generation of only one item from a saved character file.
What did I learn regarding the item header? It'd appear (from everything I saw) to be 100% random.
Which flings back to the idea of 'unique item ID' and not prefix/suffix setter.
I am confused, yet again!
Perhaps there were optional flag jumps that were skipped due to the item header being 0x00 0x00 0x00 0x00 and the 5th byte 0xCF ("of Crimson" suffix).
I did have some fun adding comments and documenting what these (inline, as far as I can tell) functions are though.
Upon loading a game in Diablo (minus normal routines; which I need to do more research on), the jist of program flow goes like this:
- Recursively call 'itemGeneration()' function 7-times (copying to a separate character/item buffer); "ActiveItems" (worn items)
- Recursively call 'itemGeneration()' function 40-times (copying to a separate character/item buffer) "InactiveItems" (inventory items)
- Recursively call 'itemGeneration()' function 8-times (copying to character/item buffer); "ActiveItems" (worn items) + belt(?)
- Recursively call 'itemGeneration()' function 40-times (copying to character/item buffer) "InactiveItems" (inventory items)
At this point: I am still completely lost as to how it's generating the affixes (prefixes/suffixes) for magical items.
I can definitively say that it is using some sort of linked-list structure of pointers to items (which are structures of pointers? with the item name (string) and respective static data for that type of item).
Hopefully I'll have an update later today.
The counter for these iterations is stored in the .data:
Code:
0018F7C4 = counter for looping
Beginning of epoch:
Code:
00448C44 | 8B 55 FC | mov edx,dword ptr ss:[ebp-0x4] | Pointer to empty data segment
00448C47 | 8B 4D 08 | mov ecx,dword ptr ss:[ebp+0x8] | Pointer to empty data segment (item???)
00448C4A | E8 F9 00 00 00 | call <diablo_copy.itemGenerationFromFile()> |
00448C4F | 83 45 08 13 | add dword ptr ss:[ebp+0x8],0x13 | Address of pointer to: ????
00448C53 | 01 5D FC | add dword ptr ss:[ebp-0x4],ebx | Address of pointer to: Item header (4 bytes)
00448C56 | FF 4D F8 | dec dword ptr ss:[ebp-0x8] |
00448C59 | 75 E9 | jne diablo_copy.448C44 |
...
00448D48 | 56 | push esi | itemGenerationFromFile()
As far as I understand: An individual item is 76 bytes in size; This appears to be circumstantial.
Worn items seem to be 0x170 (368 bytes) apart from one another. I am not sure why.
Code:
00448D48 | 56 | push esi | -- EBX = 0x170 (368 bytes)
Code:
0x00686934: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF ; No item in the character's helm(?) slot
EDIT: WOW! Is all I can say.
Diablo is INCREDIBLY[I] horrible with dealing with writing data. Horrendously inefficient in terms of senselessly, constantly rechecking the [I]same value, then writing over it, then changing it right back again without reason, only to move forward...
Also: It's been about ~11hrs consecutive hours since I made this post.
THAT is how long it took me to step through the generation of only one item from a saved character file.
What did I learn regarding the item header? It'd appear (from everything I saw) to be 100% random.
Which flings back to the idea of 'unique item ID' and not prefix/suffix setter.
I am confused, yet again!
Perhaps there were optional flag jumps that were skipped due to the item header being 0x00 0x00 0x00 0x00 and the 5th byte 0xCF ("of Crimson" suffix).
I did have some fun adding comments and documenting what these (inline, as far as I can tell) functions are though.
Code:
00469B10 | 83 EC 20 | sub esp,0x20 | ConvertTokensToStrings()
0046CF90 | 53 | push ebx | CopyPointerStringToBuffer()
0042084A | 55 | push ebp | SpawnItem()
0041FD98 | 53 | push ebx | CreateItem()
0042254A | 55 | push ebp | TempItemGeneration() (from player file)
0046B970 | 51 | push ecx | ConvertToAllLowercase()
00448D48 | 56 | push esi | ItemGenerationFromFile()
00405295 | 33 D2 | xor edx,edx | WriteStringToBuffer()
00469D80 | 57 | push edi | WriteString()