Custom graphics driver for FF7/FF8 [v.1-.7.6]

  • Thread starter Thread starter halkun
  • Start date Start date
Status
Not open for further replies.
H

halkun

Guest
can you list the external functions in the DLL and what the formats are?
 
That would be a *huge* list, but yes, I could compile everything I know right now into a C header file or some other suitable format if you want

There are still a lot of unknowns, I have names for half of the functions and there are only a few I truly understand what they do

In total, there's 60 functions, 40-50 or so that are actually different and not just stubs/duplicates in the other drivers

One thing that has me completely stumped is how the heap data structure used in FF7 works, apparently it's used to store the polygons/3d objects you have to draw and the graphics driver has to parse that
 
Here's a little teaser; APP.LOG after a run with my dummy driver that does nothing but print the name of the function called:

Code: [Select]
Code:
INITIALIZE DD/D3D START LOCK UNLOCK TEST dll_gfx: lockdll_gfx: initdll_gfx: setviewportdll_gfx: setbgdll_gfx: clear_alldll_gfx: flipdll_gfx: clear_alldll_gfx: blendmodedll_gfx: blendmodedll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: setmatrixdll_gfx: setmatrixdll_gfx: setmatrixMATRIX INITIALIZE INITIALIZE DD/D3D END initializing sound...creating dsound primary bufferreading audio fileloading static soundssound initializedINITIALIZING MIDI...selecting device 0:SB X-Fi Synth B [D000], mid=1, pid=102,midi data type: GENERAL MIDIusing midi data file: C:\Games\Final Fantasy VII\Data\midi\midi.lgpMULTIMEDIA ERROR: At least one parameter is invalid. in FILE C:\lib\src\sound\midi1.cpp LINE 356 midiOutGetVolume returned: ffffffffVolume control unsupportedMIDI INITIALIZEDdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodeset music volume: 127set music volume: 127MIDI set master volume: 100Entering MAINExiting MAINSTART OF CREDITS!!!dll_gfx: load_texturedll_gfx: setmatrixdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: load_texturedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: blendmodedll_gfx: setmatrixdll_gfx: blendmodedll_gfx: setbgdll_gfx: clear
After that it crashes because I haven't filled in the rest of the call table :-)
 
Wow, this is something I had never noticed before!
The FF7 PC model data files were almost identical to the PSX version, so they must have emulated some of the PSX's rendering requirements directly within the drivers.
Which is why it seems so strange (and confusing)

I am definitly interested
:-D
 
When FF7 was ported to the PC, Sony didn't allow the PC guys to use Psy-Q (The PSX development libs), so a psudo-Psy-Q emulation layer was created. There was a also a slight format shift to something a little more PC-centric, but the data pools were all designed with Psy-Q in mind. This meant that a call to "load_texture" would default to the loading of a TIM in the PSX version, but a TEX in the PC version. The accessors, (Looking up LBA addresses in the PSX version, and uncompressing the LZS,  verses the PC methods of opening an LGP and loading the data) are different, but the data pools that were the end result were the same functionally.. TIM files are optimized for the strange multi-depth surface of PSX vram, while TEX files are more sane palletted formats for PC video memory. In the end when the FF7 kernel makes the call, something is loaded and the program in none the wiser.

Does that make sense?
 
Well load_texture here just means that the graphics driver should prepare an image for use as a texture, the actual image is of course already loaded from disk.
The .tex format is basically a 1:1 image of what FF7 stores internally and is more like a specification of what kind of texture you want, FF7 then chooses the most compatible texture format supported by the driver and converts the image if necessary.
Oh and there is a .tim loader in the PC version as well, but it just converts the image to .tex format

Now that I have filled in all of the call table with stubs that do (almost) nothing, I can actually get all the way to the world map without crashing. Battles crash instantly though, probably because I'm not doing something I'm supposed to be doing :-)
 
If you ever wondered what FF7 with no background, no colors, no transforms and no textures looks like, it looks like this :-P

Wo rld map, outside Mt. Nibel/Rocket Town
ff7%202009-03-25%2016-57-56-62.png


In battle (fixed the crash, too, so you can actually finish the battle)
ff7%202009-03-25%2016-58-16-37.png


Field, inside Mt. Nibel this time
ff7%202009-03-25%2016-58-53-93.png


I know it looks like random crap, but I for one was happy to see *something* come out of it :-)

Next step: load textures, get menus working...
 
Last edited:
Holy crap, I just realized you could do texture injection...

We could.... Hi-res the field display with this!
 
Sure, if you want to take the time to re-render every area in the game...

Unless you meant something else...
 
Sure, if you want to take the time to re-render every area in the game...

Unless you meant something else...
You would use sketchup and use the old background as a material in photomatch.
 
Hadn't even thought of that, but yes, assuming you can detect which texture it is trying to load (the filename is not passed to the graphics driver AFAIK) you could just load something else instead :-)

Another thing that would be seriously badass is "injecting" pixel shaders to enhance the special effects

But I should probably get atleast some of the transforms working first, so you can actually see whats going on :-P

I did get vertex colouring working though (only reason it wasn't working before was because of a stupid typo), and you can actually see the enemies go red and fade out in battle :-)
 
This was really easier than I thought :-o

The very same scene outside Mt. Nibel:
ff7%202009-03-26%2013-58-18-53.png


Exp/AP screen after battle:
ff7%202009-03-26%2013-59-48-23.png


In battle (Hey, I know that haircut :-P):
ff7%202009-03-26%2014-00-46-82.png


Now you may have noticed that everything seems to be upside-down... still working on that :lol:
 
Last edited:
hmm i guess it's possible to write a custom driver that would dump geometry of each area into a file in a more useful format, then.
 
Possible, but it would be easier to just write a converter directly.

After all, the graphics driver interface is completely undocumented, reverse engineering the loader would be easier.
 
Amazing progress Aali!  :-D
With a custom driver, anything is possible. If you know how  :wink:
But I agree, dumping stuff would be far more practical from the files themselves.

With regards to FF7, to "inject" anything new would require some form of a custom referencing system, so the driver has some idea of what its rendering and can mess around with the data accordingly.

The ability to apply shaders would be... incredible.
Imagine taking the background images and using a fragment shader to filter the image. Or per-frag lighted models, maybe even normal-mapping or bloom or dynamic-shadows...
Multiple render-passes would always be possible, right?  :-D
 
Man this is progressing REALLY fast. This is a fascinating project.   The video hardware support in FF7 is terrible and still suspect even with the 1.02 patch.  Eidos really skimped on the port in some areas.  Still the better than the PSX version of FF7 though.
 
This is pretty cool. Some number of years ago I recall writing a fragment program for fake bloom for Pete's OpenGL GPU plugin for ePSXe and amusing myself with the glowing fires from the Sephiroth Nibelheim scene. :)

I'm guessing there's no concept of vertex buffers within the driver API, although if there were, it would be pretty sweet to do a CRC of the model data on load and then swap it out for high-res or even weighted versions of the models, using the existing modelview transform matrix as a bone matrix. It would be pretty hacky since you'd also have to keep track of the modelview matrices and number of transforms on draw to determine the correct bone matrix, and you'd have to weight your models to the original skeletons. But it would be doable.

You could do it without vertex buffers too, but verifying the data at draw time in any reliable manner would probably be pretty slow. Might still be doable though, given the size of FF7's vertex data once it hits the GPU. Although I'm sure this kind of functionality isn't even on your radar yet. :)
 
FF7 is based on DX5, which means no hardware T&L, what the driver recieves is only transformed through the camera matrix and the "per-entity" matrix, the driver knows nothing about animation so that must be done somewhere else.

Seems to me this would make it quite difficult to inject 3d models this way, since not only do you have to identify the model, you have to figure out how its animated and apply this to the new model.

However, I *think* the driver can get access to all the information from the .p file the model came from, which would make the identification part a breeze but then you still have to figure out the animation state.

Textures are much easier, you have access to both the .tex header and the raw image data since it is up to the graphics driver to convert it to a suitable format.
 
Double-posting again, with some new even more impressive results :-)

Managed to get more than just the haircut this time :-P
ff7%202009-03-27%2020-49-36-60.png


Outside rocket town (water is orange, haven't really got the palettes all figured out it seems)
ff7%202009-03-27%2020-51-30-40.png


Inside rocket town (field really needs correct textures to make any sense, but you can sort-of see the rocket :wink:)
ff7%202009-03-27%2020-51-40-35.png
 
Last edited:
Triple-posting :-P

Turns out I was just being an idiot, hadn't set the texture coordinates outside battles (and forgot to do a BGR to RGB conversion), I had it right all along;

Yes, I really like Mt. Nibel
ff7%202009-03-27%2021-47-52-04.png


Holy sh*t, you can actually read the text!
ff7%202009-03-27%2021-48-16-15.png


Even field is getting there :-)
ff7%202009-03-27%2021-48-56-34.png


No battle screenshots this time, it seems to be quite broken at the moment
 
Last edited:
Status
Not open for further replies.
Back
Top