This is my second camera mod for Torchlight. The first was for the original game. I made it because at the time the existing camera mod didn't work in Wine. And so when the second game came out, again with no camera controls, only this time no one else had yet made anything to fix that, I set about work on this mod.
The first problem I has was that I was unable to disassemble the Torchlight 2 executable. Not only beacuse both versions available had DRM that involved run time decryption but it was also too big for the disassembler I was using at the time. This caused me to look for a method that did not involve run time modifictaions of the executable itself.
The made me turn my attention to Ogre, the open-source graphics rendering engine that Torchlight uses. Because it is open-source I now had the source code and because it was shipped as a DLL I had all the symbolic information I needed. I then took the code I had written for my Titan Quest camera mod as a base and started experimenting.
Ogre has a conveniently named Camera class. This has two method that I was interesting in lookAt() and setPosition(). It has two variation of these methods one set that effectivly takes a pointer to a vector class (A C++ reference as an argument is effectivly a pointer) and another that takes three floats. I intecetpted the variation of these methods that the game code called by overwriting them with a jump instruction to my code and called the other variation from my code.
Every frame the game calls setPosition() and then lookAt() which makes sense since the behaviour of lookAt() is dependant upon the camera's position. While I only needed to change the position of the camera itself and not what it is looking at I needed both vectors to calculate the new position of the camera. I had considered taking control of the camera distance, which would have meant that I would only need the target vector passed to lookAt() but the game was calculating fog distance based upon the camera distance.
The next thing was which instance of the Camera object I wanted take control of. It turned out that the game used a single instance of the Camera object for the entire lifetime of its process. However it was using additional instances of the Camera object for portrait views. What I ended up doing was using taking the pointer to the first instance of the Camera object that I intercept and checking against that on subsequent calls.
With the Titan Quest camera mod I had had problems with not being able to call member functions via regular pointers. To avoid this problem I compiled my code as C++ and linked to the OgreMain.dll that the game used. This removed the need for any inline assembly but did introduce a runtime dependency on the DLL.
The last thing was that because this was being released at a time when other people would be interested in it I gave it a minimal GUI using Windows GDI that gave people an easy way to adjust the few settings it had and to stop it running.