VOGONS


Tomb Raider 1 missing shadow issue

Topic actions

Reply 20 of 25, by Dege

User metadata
Rank l33t
Rank
l33t

😀 😀 😀

"prologue in heaven" in a discussion between you and Paul Gardiner in 2003 (you knew

Good old days... 😀

So, has this simple hack solved the shadow-glitch?

I don't really understand why you wanted to OR the constant colors coming from different calls, it won't give good results. By the way, reading back my previous post I must refine my words:

Also, the point is, GR_COLORCOMBINE_CCRGB is only used to draw the shadow AFAIR. Different mode is used for all other untextured polygons (because they are lightened, e.g. Lara's arms and legs, etc.).

GR_COLORCOMBINE_CCRGB might not be used only for the shadow and black text bkgnd, can't tell it by head by now 😀 , but as far as I remember, all pipeline config is done in guColorCombineFunction(GR_COLORCOMBINE_CCRGB), grConstantColorValue(color) order. Except for the magic 0x7f000000 value, because calling grConstantColorValue seems to be forgotten for that value. So when dgvoodoo set 0x7f000000 as the const color, it doesn't mess up anything because TR's subsequent grConstantColorValue call overwrites that. (It wouldn't work in reverse order.)
And, why is this working on a real voodoo after all without that hack? It's a mystery for me, maybe the case is as Paul said (and the document isn't precise), or a bug in the drivers, who knows... 😀

In TR Unfinished Business I saw (but only now that you explained I can see why) it changes, but eventually boils down to the same business via a call to grConstantColorValue4() taking four float's instead of an int.

One important thing about constant color to clarify: actually there are two different instances of constant colors maintained in voodoo driver's internals. They are for different purposes. One can be set with grConstantColorValue and the other can be set with grConstantColorValue4. They have nothing to do with each other, so that grConstantColorValue4 won't overwrite the constant color set with grConstantColorValue and vice-versa.

grConstantColorValue is used when the pixelpipeline refers to GR_COMBINE_xxxxx_CONSTANT.
grConstantColorValue4 is used when the pixelpipeline refers to GR_COMBINE_xxxxx_ITERATED and delta0 mode is enabled.

So that if I do a call like this:
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT, FXFALSE)
and enable delta0, then the color output turns to be grConstantColorValue4*grConstantColorValue. Of course, if delta0 is disabled then output is iteratedvertexcolor*grConstantColorValue.

dgVoodoo handles this one simply as well, if delta0 is enabled then it sets all triangle vertex colors to grConstantColorValue4 in place of the ones coming from the GrVertex strucs.

code snippet:

...
GrVertex *vertex;
...
actVertexPtr->specular = (actVertexPtr->diffuse = (astate.flags & STATE_DELTA0) ? astate.delta0Rgb : GetARGB(vertex)) ^ 0xFF000000;
...

EDIT:

I must correct myself, I'm silly.

So that if I do a call like this:
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT, FXFALSE)
and enable delta0,

Actually, this can't be done I think because delta0 can only be enabled via guColorCombineFunction by GR_COLORCOMBINE_ITRGB_DELTA0 and GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0. All other values disable delta0.
But there is a conundrum here: what happens on a real voodoo after the following call pattern:

guColorCombineFunction (GR_COLORCOMBINE_ITRGB_DELTA0);
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT, FXFALSE);

Whether delta0 mode remains enabled or not? 😁

Reply 21 of 25, by gidierre

User metadata
Rank Member
Rank
Member
Dege wrote:

So, has this simple hack solved the shadow-glitch?

I, uhm... so it would seem as long as noone disproves it... but nested in a smaller ring it sure appeared to make less damage

Dege wrote:

I don't really understand why you wanted to OR the constant colors coming from different calls, it won't give good results
...
all pipeline config is done in guColorCombineFunction(GR_COLORCOMBINE_CCRGB), grConstantColorValue(color) order. Except for the magic 0x7f000000 value, because calling grConstantColorValue seems to be forgotten for that value. So when dgvoodoo set 0x7f000000 as the const color, it doesn't mess up anything because TR's subsequent grConstantColorValue call overwrites that. (It wouldn't work in reverse order.)

don't want to abuse your patience, but the shaky rationale for that would be, with an OR I will do no harm to the 24 bit part, if I set bits 24 through 31 maybe I'll have a makeshift 7f value for a in argb. I saw storms of 24 bit color values coming, what if I sorta append 7f to them and enjoy the show ?

Dege wrote:
dgVoodoo handles this one simply as well, if delta0 is enabled then it sets all triangle vertex colors to grConstantColorValue4 […]
Show full quote

dgVoodoo handles this one simply as well, if delta0 is enabled then it sets all triangle vertex colors to grConstantColorValue4 in place of the ones coming from the GrVertex strucs.

code snippet:
GrVertex *vertex;
...
actVertexPtr->specular = (actVertexPtr->diffuse = (astate.flags & STATE_DELTA0) ? astate.delta0Rgb : GetARGB(vertex)) ^ 0xFF000000;

yes, but if I get the gist of it right, if enabled you will get

actVertexPtr->specular = (actVertexPtr->diffuse = astate.delta0Rgb) ^ 0xFF000000;

and then since by an XOr with 0xFF000000 you'll only invert most significant byte, what's that for ? Setting all its 8 bits ? Why not ^ 0x7F000000 here ?

Dege wrote:
But there is a conundrum here: what happens on a real voodoo after the following call pattern: […]
Show full quote

But there is a conundrum here: what happens on a real voodoo after the following call pattern:

guColorCombineFunction (GR_COLORCOMBINE_ITRGB_DELTA0);
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_CONSTANT, FXFALSE);

Whether delta0 mode remains enabled or not?

as far as that goes (I'm afraid you don't need me to pinpoint this)
when I was desperately in search of info about grConstantColorValue4(), I saw it commented as "obsolete routine, send values to hardware immediately", so by what I can make of that piece of info as follows :

(see http://www.koders.com/c/fid51F65F4A17CC79E3E5 … 3D3339F95B.aspx line 1365)

/*---------------------------------------------------------------------------
** grConstantColorValue4
** GMT: obsolete routine
** GMT: send values to hardware immediately
*/

GR_ENTRY(grConstantColorValue4, void, (float a, float r, float g, float b))
{
#define FN_NAME "grConstantColorValue4"
GR_BEGIN_NOFIFOCHECK("grConstantColorValue4",85);
GDBG_INFO_MORE(gc->myLevel,"(%d,%d,%d,%d)\n",a,r,g,b);
gc->state.a = a;
gc->state.r = r;
gc->state.g = g;
gc->state.b = b;

if (gc->state.cc_delta0mode) {
REG_GROUP_BEGIN(BROADCAST_ID, Fr, 3, 0x07);
{
REG_GROUP_SETF(hw, Fr, r);
REG_GROUP_SETF(hw, Fg, g);
REG_GROUP_SETF(hw, Fb, b);
}
REG_GROUP_END();
}

GR_END();
#undef FN_NAME
} /* grConstantColorValue4 */

I'd figure it would be gc->state.cc_delta0mode dependent,

Was grColorCombineDelta0Mode() involved too ?

(see http://csourcesearch.net/package/glide-v3/3.1 … de3/src/gdraw.c line 328)

Without quoting all of it, I saw a

gc->state.cc_delta0mode = delta0mode;

line there that could do it

(hoping I didn't lose all remaining benevolence from you at this point).

Reply 22 of 25, by Dege

User metadata
Rank l33t
Rank
l33t

but the shaky rationale for that would be, with an OR I will do no harm to the 24 bit part, if I set bits 24 through 31 maybe I'll have a makeshift 7f value for a in argb. I saw storms of 24 bit color values coming, what if I sorta append 7f to them and enjoy the show ?

Hmm, now I'm getting the hang of that... I think... So you suppose that constant alpha (0x7F) is set only once at the beginning, and it never gets updated by subsequent grConstantColorValue calls (which apply 0x00000000 instead of 0x7F000000) for some reasons (e.g. something is disabled in the alpha unit or whatever), and you try to recover 0x7F in MSB with ORing? If not, excuse me, i think it's too difficult to me.. 😀 😀

yes, but if I get the gist of it right, if enabled you will get

actVertexPtr->specular = (actVertexPtr->diffuse = astate.delta0Rgb) ^ 0xFF000000;

and then since by an XOr with 0xFF000000 you'll only invert most significant byte, what's that for ? Setting all its 8 bits ? Why not ^ 0x7F000000 here ?

No, this XORing has nothing to do with alpha. dgVoodoo doesn't use vertex shaders as it is feed by transformed&lightened vertices, it uses the classic (FF) vertex layout. This layout (can) contains two vertex color named diffuse (v0) and specular (v1) in my code (named after their classic role in builtin DX T&L engine).
diffuse contains the usual vertex color coming from Glide vertex (it's alpha isn't XORed!), and
specular contains fog intensity info. specular is only relevant when Glide uses alpha-fogging so that when fog intensity comes from the vertex alpha. DX expects it in the alpha component of the specular member.
XORing is needed because of the different meanings of intensity in Glide and DX (intensity of 0 means opaque fog color in DX and fully transparent fog in Glide).

when I was desperately in search of info about grConstantColorValue4(), I saw it commented as "obsolete routine, send values to hardware immediately", so by what I can make of that piece of info as follows :

Hmm, maybe I was inaccurate again and you're right, calling grConstantColorValue4 and grConstantColorValue might end up in updating the same physical register in the 3dfx chipset and the only difference is that grConstantColorValue4 is sent directly to the hw and not cached in the internal structures... 😀
But it's pointless in the respect of wrappers I think, I guess they are still different colors logically (or not 😁, but afair TRUB didn't work correctly when I used one instance of constant colors).
I should scrutinise the source of the 3dfx driver to understand what exactly is going on there (grColorCombineDelta0Mode() seems to be an internal function). 😀

(hoping I didn't lose all remaining benevolence from you at this point).

Now, now! I think we are having a cool conversation!! 😎

Reply 23 of 25, by gidierre

User metadata
Rank Member
Rank
Member

sorry for the delay, it wasn't really out of numbness, but I was doing a bit of reflecting and researching, going after, you know, that white rabbit or rather the famous knife without a blade, whose handle got lost...
you know, sometimes, the crazy heartbreaking feeling of being on Laputa, at the Grand Academy of Lagado (Gulliver's Travels, book III, chapter V), not that you are, don't get me wrong, but that I am a yahoo visitor over there

anyway

Dege wrote:

Hmm, now I'm getting the hang of that... I think... So you suppose that constant alpha (0x7F) is set only once at the beginning, and it never gets updated by subsequent grConstantColorValue calls (which apply 0x00000000 instead of 0x7F000000) for some reasons (e.g. something is disabled in the alpha unit or whatever), and you try to recover 0x7F in MSB with ORing?

exactly so. Btw when I speak of 24 bit color vaues, obviously I just intend the usual unsigned 32 bit int in 0x00xxxxxx format, that was just shorthand.

Yes, that's precisely my tempative conceptualisation of it as things were rolling along. Doesn't mean there must be something to it, of course, even if it should work it could be for a wrong reason.

I was just there in the flow trying to recognize "An Instance of the Fingerpost" to show the course, if I may quote Iain Pears' unsurpassable masterpiece.

A great favor you could do to me would be to redirect me to a better source of info about this guColorCombineFunction(), what I know of it, I understand it wasn't enough to get the whole picture, which gets even more complicated and frustrating than I expected 😵

And the less it's explicated the more it's frightening.
It's just too true to be good.

You know Dr. Watson once wrote (The Redheaded League) Sherklock Holmes told him :
"I begin to think, Watson," said Holmes, "That I make a mistake in explaining. 'Omne ignotum pro magnifico,' you know
that was a witty quote from Tacitus : whatever is unknown (or U.N. Owen ?) looks impressive (my translation).
But whoa, jump to previous page and look, after Holmes magically guessed all things about the man before him,
"How, in the name of good-fortune, did you know all that, Mr. Holmes?" he asked.
Holmes explains everything then gets the rebuke
Mr. Jabez Wilson laughed heavily. "Well, I never!" said he. "I thought at first that you had done something clever, but I see that there was nothing in it, after all."

No off topic, here. This might apply to me too 😦

So in the end what do you think of the OR act ?
Was that alpha tinkering ? 😖
Or is your explanation different ?
I'll tell you,I don't even care if it works, I'm in it just with a view to understanding, really.

Reply 24 of 25, by Dege

User metadata
Rank l33t
Rank
l33t

Sorry for the late respond, so:

So in the end what do you think of the OR act ?
Was that alpha tinkering ?
Or is your explanation different ?

Yes, I think it's a kind of tinkering. Maybe the original 3dfx hw worked in a similar way you tried for some reason (and it's not tinkering after all, but a try to find a good approximation so that reverse engineering), but I think it's worthless to invest so much work into that. It's only a particular problem with TR1 which can be workarounded simply. 😀

A great favor you could do to me would be to redirect me to a better source of info about this guColorCombineFunction(), what I know of it, I understand it wasn't enough to get the whole picture, which gets even more complicated and frustrating than I expected

Well, that function is not that evil. 😀 It calls grColorCombine with predefined parameters according to the selected mode. The only trick about it is the delta0 mode which cannot be accessed through lower level functions. Isn't it strange? Besides guColorCombineFunction is a higher lever utility function, delta0 can only be driven through that and there is no lower level counterparts, or they were removed and obsolete in a very early stage of the API. 😀