PDA

View Full Version : How to implement "emulate clear". Answer and Question



Gonetz
August 26th, 2003, 08:12
AFAIK, nobody but Jabo knows how to implement low level framebuffer clears for special effects like flame's corona or the lens flare from the sun in Zelda. Now I will open this little secret for you (be sure you are sitting safe)

In rdp_fillrect
if (rdp.colorimg_addr == rdp.depthimg_addr)
{
fill depthimage area in RDRAM with rdp.fillcolor
return;
}

Thats all! Easy, eh? I was speechless when I found it. It's too obvious. :D

But one problem remains. Depth compare is set off for flame's corona. Corona uses the same texture as for fairy. For fairy depth compare must be set off and it is so, but for corona depth compare must be enabled, otherwise it will be drawn over all objects. I have implemented this clear for Icepir8's plugin to be sure it's not the Glide64 only problem. As you can see on the screenshot, TR64Ogl has the same depth problem. I haven't VC.net to check it with newest plugins, so I ask other plugins authors to check it. May be you haven't this depth problem or you will be able to find good solution. Currently I have added a hack to solve this.

Good luck!

Sceen shot: TR64 OGL 0.7.8 + GF4mx

Clements
August 26th, 2003, 18:55
Excellent work, Gonetz! This is one of those features that Jabo's plugin had that all others did not. It's especially good that this is known now because Emulate Clear solves the camera jumping in Donkey Kong 64, and with the new 1964 on the horizon, we'll have a choice of plugins each equipped with their own emulate clear ready for it. Also, with Zelda being my favourite game, I won't have to rely on Jabo's plugin for good accuracy with the game! :)

Rice
August 26th, 2003, 21:28
Gonetz

Nice job. And thanks very much to share it.

Tagrineth
August 27th, 2003, 01:55
IIRC the coronas are in fact visible behind walls for a few seconds before disappearing. At least, they were when I was playing Master Quest on my friend's GC the other week.

Federelli
August 27th, 2003, 02:24
great job gonetz, let's see other plugins implementing it :D

nephalim
August 27th, 2003, 02:57
Great Gonetz...your plugin is definetely one of, if not the, best. It really needs framebuffer emulation, though. Any plans to implement it?

Clements
August 27th, 2003, 03:24
Gonetz has added framebuffer emulation :) Go here! (http://www.emuxhaven.net/forum/index.php?showtopic=3173)

Shin_Gouki
August 27th, 2003, 14:11
itīs nice to see that you share such ideas with other emu/plugin authors!!
*Gonetzgetsbigcreditsforthisone* :satisfied
wbr Shin Gouki

The Khan Artist
August 27th, 2003, 14:45
And thanks very much to share it.

Ditto. You pwn.

:party:

nephalim
August 27th, 2003, 23:43
Wow, those are some excellent pics in that other thread. Great work Gonetz.

Orkin
August 28th, 2003, 19:22
Thanks for sharing Gonetz! You da man! :D

So, if clearing the RDRAM depth buffer is what it takes, then it would appear that the ROM is doing some kind of occlusion culling. It's probably trying to do something like this:

If the corona's center is visible (determined by checking the value in the depth buffer at the corona's location), draw the corona over everthing. If the corona's center isn't visible, don't draw the corona.

If this is the case, the only way to completely emulate it would be to either copy the depth buffer out of video ram (extremely slow), or render polygons to the depth buffer in RDRAM (faster, but not easy to implement)...

Gonetz
August 29th, 2003, 08:11
Orkin, may be you are right. But if you are right, it will be hard to emulate. However, the problem with corona can be solved by forcing depth compare for it. The only difficulty is fast detection of corona using. Jabo solved this somehow.

decription
September 21st, 2003, 17:02
Jabo's skill is becoming even more apparent. Have you guys tried to contact him for the answer? Either way it is great to see this problem solved.

Zilla
November 15th, 2003, 03:05
Wow, too obvious. :)

Orkin
February 28th, 2004, 02:07
I was right! The Zelda games do check the depth buffer before drawing coronas and lens flares. How do I know this? I implemented a software depth buffer renderer that draws the depth buffer to RDRAM, and it works properly now! :w00t:

Orkin

Gonetz
March 1st, 2004, 06:09
I was right! The Zelda games do check the depth buffer before drawing coronas and lens flares. How do I know this? I implemented a software depth buffer renderer that draws the depth buffer to RDRAM, and it works properly now! :w00t:
Orkin
software depth buffer renderer? is it fast enough to be playable? may be it is - you need to do calculations only for 320x240 area, and depth calculation is much simpler then color one. please tell me, which format you have used for RDRAM depth buffer values?

Orkin
March 2nd, 2004, 01:22
software depth buffer renderer? is it fast enough to be playable? may be it is - you need to do calculations only for 320x240 area, and depth calculation is much simpler then color one. please tell me, which format you have used for RDRAM depth buffer values?

It does cause a significant slowdown, but not enough to bring it below 60 VI/s on my system. My current renderer also has room for optimization...

The Z format used in RDRAM is described in the N64 Programming Manual in section "15.5 Blender", near the bottom under the heading "Z Image Format". It took reading over it a few times, but I finally got it worked out. The RDP takes 18-bit depth values from the RSP, interpolates them, and then encodes them before writing them to RDRAM. The format it encodes to is sort of a floating point format. Here's the code I wrote to encode the depth value from a float (clamped from 0.0f to 1.0f) to the encoding used in RDRAM:



u32 steppedZ = z * 0x3ffff; // Convert to 18-bit

// Calculate the exponent
u32 exponent = 0;
u32 testbit = 1 << 17;
while ((steppedZ & testbit) && (exp < 7))
{
exponent++;
testbit = 1 << (17 - exp);
}

// Calculate the 11-bit mantissa
u16 mantissa = (steppedZ >> (6 - min( 6, exp ))) & 0x7ff;

// Encoded Z
u16 encodedZ = (exp << 11) | mantissa;


I actually ended up making a look-up table for speed, but this is the algorithm I used.

Orkin

Gonetz
March 2nd, 2004, 06:33
Thanks!

Cyberman
March 4th, 2004, 00:02
So the values are stored in a 32 bit value 64bit size in RDRAM

There might be a more efficient way of converting them especially if you have support for MMX on your machine (most people do). You might be able to convert 2 values at a time (very useful).

Are your FP values single or double precision?
What's the format that's stored in RDRAM?
How often does the depth buffer creation have to happen, onces per frame?

Cyb