Is there an easy way to calculate hashes (i.e. using the algorithm Dolphin uses for naming textures using the "Dump Textures" tool) for textures from original source files?
E.g. I have a bunch of
.tpl files containing RGB5A3-format images. It would be much easier to calculate hashes straight from the tpl files, as opposed to hunting for every texture to show up in-game.
The hashes are calculated after the textures have gone through a certain amount of processing by the game as not every game uses exactly the same representation of textures on-disk. The harder part of what you want is actually the part you can already do - getting the textures off the disk - so provided the game only does simple things before pushing them to the GPU, it should be feasible, but might be a considerable amount of work.
The stuff you'll need to do is:
- Figure out what the game does with the textures in between loading them from disk and putting them on the GPU. It might literally just copy them straight there in the format you can already extract, or it might pad them to be RGBA8, or it might change the endianness, or it might do something completely bonkers that will take you years to figure out.
- Write some code that can get a texture out of the TPL and apply this operation to it.
- Figure out what Dolphin's hashing operation is. I know it's a standard hash applied to the first n bytes of the texture (with n changing based on the texture cache accuracy setting if that's still a thing), but I don't know which standard hash it is or what values of n are used.
- Write some code that can take the output from your other code and apply this operation to it.
Depending on how good you are at things and how complicated the game's behaviour is, this might not be very much work at all, or might take you months or even years. The end result will probably only be valid for the one game you were working with, too. It's
probably not going to save you much effort over playing the game until you've manually dumped all the textures.
(10-05-2019, 01:14 AM)AnyOldName3 Wrote: [ -> ]Figure out what Dolphin's hashing operation is. I know it's a standard hash applied to the first n bytes of the texture (with n changing based on the texture cache accuracy setting if that's still a thing), but I don't know which standard hash it is or what values of n are used.
From January 2015 and on, we have been using the hash function xxhash64, and all bytes of the texture are hashed. (It was dependent on the texture cache accuracy setting before that, but not anymore.)
(10-05-2019, 01:22 AM)JosJuice Wrote: [ -> ]We have been using the hash function xxhash64, and all bytes of the texture are hashed.
Thank you. I might try doing some playing around to try and get a working implementation of xxhash64 to scan tpl files.
Upon trial and error, I've found that I can extract the raw image data from a TPL file (by manually copy/pasting the needed bytes from a hex editor).
When I feed this raw image data file into xxhash64 (via QuickHashGUI), it outputs the correct hash!
I'm gonna try creating a QuickBMS script to automate the process of extracting the image data from TPL files.
Update: I've created a functional QuickBMS script that can extract all image data from a TPL file.
This should (in theory) work for TPL files from any game.
Once extracted, you can put the .bin output files through QuickHashGUI (or another xxHash64 utility) to calculate the hash of the image data.
It might not be the most well-optimized script in the world, but it works.
Code:
endian big
idstring "\x00\x20\xAF\x30"
get filesize asize
get numberOfImages long
get imageTableOff long
if numberOfImages == 1
goto imageTableOff
get imageHeaderOff long
goto imageHeaderOff
get height short
get width short
get imageFormat long
get imageAddress long
set name string "tex1_"
string name + width
string name + "x"
string name + height
string name + "_"
string name + imageFormat
string name + ".bin"
math filesize - imageAddress
log name imageAddress filesize
else
for i = 1 < numberOfImages
goto imageTableOff
get imageHeaderOff long
get null long
get nexImageHeaderOff long
goto imageHeaderOff
get height short
get width short
get imageFormat long
get imageAddress long
goto nexImageHeaderOff
get null long
get null long
get nexImageAddress long
set imageSize long nexImageAddress
math imageSize - imageAddress
set name string "tex1_"
string name + width
string name + "x"
string name + height
string name + "_"
string name + imageFormat
string name + ".bin"
log name imageAddress imageSize
math imageTableOff + 0x08
next i
goto imageTableOff
get imageHeaderOff long
goto imageHeaderOff
get height short
get width short
get imageFormat long
get imageAddress long
set name string "tex1_"
string name + width
string name + "x"
string name + height
string name + "_"
string name + imageFormat
string name + ".bin"
math filesize - imageAddress
log name imageAddress filesize
endif
[
attachment=18358]