Dolphin, the GameCube and Wii emulator - Forums

Full Version: Is there a way to calculate hashes from original texture files?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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!

[Image: image.png]

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]