I'm ready to test my new dictionary of hashes in-game but I need to gain a bit more d3d9 knowledge first. I'm planning on making use of a d3d9 interceptor DLL located here:
http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html. I'm trying to find out which files I absolutely need and which ones I can change to test texture replacement in-game. Basically I need to capture the SetTexture calls and replace them with any test texture. Any help/advice would be appreciated to help me go faster
Here's the hash dictionary using the algorithm described above. It adds a numerical suffix to the filenames for each 128x256 block of the texture. There are a total of 6245 blocks in the game.
FF8 Field Hash DictionaryEdit (note):
http://www.gamedev.net/topic/178004-idirect3dtexture9-and-manipulation-of-single-pixels/Update (preliminary):
I have verified that my hash function has been successful at identifying my first test case, bghall1, from the VRAM. At first I was a little worried, because the hash value showed up 3 times, but those were bghall1, bghall1a, bghall1b, which are all identical textures. More to come when I have time!
Update2:I've got the game successfully running the hash function on every texture that is called by D3D. First, I load my hash map from a file of all the known textures (described above). Then, I run the hash function whenever a SetTexture call is made. I then compare that hash value against the hash values in the hash map to find the closest match (the texture with the least different bits of comparison). I've done a test run from bghall1 (first save point) to the front gates of balamb garden and I've recorded these matches in a file to see if the correct textures were found. Here is that file, with a few annotations thrown in regarding where I was at each point in time:
http://pastebin.com/9UpAynEdExplanation of the results--
line structure: filename_blocknum,mismatchedbits,thistexturehashval,closestmatchedtexturehashval
I've only recorded 1/100 texture calls in the results because the file would be too long to navigate if I didn't.
Whenever a background is supposed to be set, the hash function correctly identifies the texture and spits out the file name. However, whenever a texture with mostly black or monotone pixels is called, like in intro screens, and some other screens, including some animations that have a lot of black but a few spots here and there like lights, the hash function fails, usually identifying another texture file that has mostly black or monotone pixels. Additionally, whenever a character sprite texture is called, the results show either NO_MATCH or may sometimes identify the wrong texture as a match.
Keep in mind, these are results of a completely untested hash function that has a ton of room for improvement. The number of pixels sampled, number of comparisons between those pixels, randomness of the pixels, and thresholds for matches and mismatches can be varied. Also, secondary hash functions can be used on textures that are mostly black, for example, and eventually special cases can be worked on separately.
Next step: test texture replacement in D3D
Update 3:
Successfully replaced textures in-game with a simple 256x256 fire texture. This slows the system down tremendously if the texture file is loaded from the disk every time a SetTexture is called. This is because SetTexture is called roughly 150 times per frame to render all the various parts of the scene. Since all of the parts of the scene, except the character and object sprites, are loaded from a single field texture file, this 1664x256 (or 1536x256) texture file should be loaded only on the first texture call of the scene and then referenced in memory for each SetTexture call. This should drastically improve framerate and reduce errors in hashing during the other 149 SetTexture calls in the scene to 13/6245 = 0.2% of the original error rate. This all hinges on the ability to detect the correct texture on the first call during the frame.
Update 4: I have now successfully replaced textures in-game with their appropriate textures, using the hash method. It is not perfect, but it reliable chooses the correct texture > 90% of the time so far. I've expanded the pixel selection from 16 to 64 pixels to make it more reliable. It needs some optimization to avoid lag and some other fixes, but I really need to work through the next huge hurdle: allowing resized textures in-game. This, I fear, will be very difficult, since there are many operations performed on the passed-in textures in order to render them to the frame buffer. These operations include drawing all of the geometry of characters/objects, etc, and I'm so far unsure how to resize only the field textures yet keep everything else unaffected. I'll be thinking on that...