Page 1 of 2

OpenGL translucent texture over other texture

Posted: Mon Mar 17, 2014 11:22 pm
by ezee
Hi .
Don't know if it's a bug or a dev choice , but i noticed that the com display transparency
is not working ( we have a black background instead of the background ) .

Check the tutorial mission ( in Atlantis ) to verify that point .
I want to make cockpits parts , with 3d screen instead of nothing ( example llama cockpit ).
But the free space around the 3dscreen picture drawn in the texture will appear Black ,
instead of transparent .
My 3dscreen is :
Image

Can you fix that ?
I made a search in the source code , and found that in vdu.cpp :
void VDU::DrawComm()
{
if (comm_ani != NULL) {
GFXDisable( TEXTURE1 ); // ??
GFXEnable( TEXTURE0 );
GFXDisable( LIGHTING ); // i understand why
...
...
comm_ani->DrawAsVSSprite( this ); // problem is here ?
...
The problem may be in the DrawAsVSSprite() , i don't know enough gl stuff to identify
the cause , but you certainly will :

in animation.cpp

Code: Select all

void Animation::DrawAsVSSprite( VSSprite *spr )
{
    if (!spr)
        return;
    if (g_game.use_animations != 0 || g_game.use_textures != 0) {
        //unsigned char alphamaps=ani_alpha;
        GFXPushBlendMode();
        if (options&ani_alpha)
            GFXBlendMode( SRCALPHA, INVSRCALPHA );
        else
            GFXBlendMode( ONE, ZERO );
        size_t lyr;
        size_t numlayers = numLayers();
        bool multitex = (numlayers > 1);
        size_t numpasses = numPasses();
        float     ms = mintcoord.i, Ms = maxtcoord.i;
        float     mt = mintcoord.j, Mt = maxtcoord.j;
        GFXDisable( CULLFACE );
        Vector    ll, lr, ur, ul;
        spr->DrawHere( ll, lr, ur, ul );
        BLENDFUNC src, dst;
        GFXGetBlendMode( src, dst );
        for (lyr = 0; (lyr < gl_options.Multitexture) || (lyr < numlayers); lyr++) {
            GFXToggleTexture( (lyr < numlayers), lyr );
            if (lyr < numlayers) GFXTextureCoordGenMode( lyr, NO_GEN, NULL, NULL );
        }
        for (size_t pass = 0; pass < numpasses; pass++)
            if ( SetupPass( pass, 0, src, dst ) ) {
                MakeActive( 0, pass );
                GFXTextureEnv( 0, GFXMODULATETEXTURE );
                GFXBegin( GFXQUAD );
                if (!multitex) GFXTexCoord2f( ms, Mt );

                else GFXTexCoord4f( ms, Mt, ms, Mt );
                GFXVertexf( ll );
                if (!multitex) GFXTexCoord2f( Ms, Mt );

                else GFXTexCoord4f( Ms, Mt, Ms, Mt );
                GFXVertexf( lr );
                if (!multitex) GFXTexCoord2f( Ms, mt );

                else GFXTexCoord4f( Ms, mt, Ms, mt );
                GFXVertexf( ur );
                if (!multitex) GFXTexCoord2f( ms, mt );

                else GFXTexCoord4f( ms, mt, ms, mt );
                GFXVertexf( ul );
                GFXEnd();
            }
        SetupPass( -1, 0, src, dst );
        for (lyr = 0; lyr < numlayers; lyr++)
            GFXToggleTexture( false, lyr );
        GFXEnable( CULLFACE );
        GFXPopBlendMode();
    }
}
Thank you .

Re: OpenGL translucent texture over other texture

Posted: Mon Mar 17, 2014 11:26 pm
by klauss
Nah, it's the detail level.

Those settings are ominously outdated, when you lower detail level past some level I don't remember, alpha blending of VDU sprites is disabled.

It certainly should be removed, no moderately modern or even obscenely old GPU now gives a f**k about blending.

Re: OpenGL translucent texture over other texture

Posted: Mon Mar 17, 2014 11:58 pm
by ezee
ok thank you , that make sense .
I will try to tweak the settings .
That is good to have this information for users in the future .
I will add that recommandation in my cockpits releases .

:)

Re: OpenGL translucent texture over other texture

Posted: Tue Mar 18, 2014 12:28 am
by ezee
Fail .
I have tried the max settings , no change , black screen instead of transparency .

in my conf file , in display i have :
<var name="detail_texture_blankout" value="3"/>
<var name="detail_texture_full_color" value="1"/>
<var name="bitmap_alphamap" value="0"/>

Re: OpenGL translucent texture over other texture

Posted: Tue Mar 18, 2014 9:14 pm
by klauss
I think the name of the variable was something like high quality cockpits or similar.

Re: OpenGL translucent texture over other texture

Posted: Wed Mar 19, 2014 2:32 pm
by ezee
I am proceeding some tests with the default cockpit .
I have tried to change the default blank area with my 3d screen .
( same format technic i used for the Aera ani )
The transparecy is ok , but the com display is still black .
Look :
Image
and with the com :
Image

I have found in the texture folder textures called " blank256" " blank512" that are black ,
and specially designed i guess to cover the textures\cockpits\disabled\vdu_panel.image

That is quite logical as the original idea was to cover the text area with animation .
I think that if the animation is transparent , the vdu_panel image will appear in the background .

WE SHOULD VERIFY THAT POINT ( in the code ).
EDIT : Wrong , after verification there is a switch and no coverig operation, the alpha component is a flag in the code , see below .

Also , i think we should create multiple vdu textures , instead of one single :
_ We could implement different kind of vdu ( damaged , bought in the market etc ... )
_ You have seen in the pictures what happens when i replace vdu_panel.image by
my 3d screen . We need to have separate textures per VDU .
And so rewrite how vdu works ( as units in the cockpit )

From there , each modification done in the shipdealer coulb be reflected in the cockpit !
And moreover , we could make damage animation !
Interested ?
:?:



EDIT : mmm... something sounds like you said :
( alpha flag for animation )
static const unsigned char ani_alpha = 0x04;

used here :
void Animation::DrawAsVSSprite( VSSprite *spr )
{
if (!spr)
return;
if (g_game.use_animations != 0 || g_game.use_textures != 0) {
//unsigned char alphamaps=ani_alpha;
GFXPushBlendMode();
if (options&ani_alpha)
GFXBlendMode( SRCALPHA, INVSRCALPHA );
else
GFXBlendMode( ONE, ZERO );
FIXED ! ( well by a rude boy ... single bypass here :mrgreen: )
if (g_game.use_animations != 0 || g_game.use_textures != 0) {
//unsigned char alphamaps=ani_alpha;
GFXPushBlendMode();
/*
if (options&ani_alpha)
GFXBlendMode( SRCALPHA, INVSRCALPHA );
else
GFXBlendMode( ONE, ZERO );
*/ // ezee ....
GFXBlendMode( SRCALPHA, INVSRCALPHA );
Result :
Image

Would be better to find the right option in the .cfg yeah .
I wonder how many players have the black background in anims ?

Re: OpenGL translucent texture over other texture

Posted: Wed Mar 19, 2014 8:07 pm
by klauss
That fix is no good. The proper fix is to make sure ani_alpha is true (which I guess it involves flagging it as such in the .ani file)

Re: OpenGL translucent texture over other texture

Posted: Wed Mar 19, 2014 11:35 pm
by ezee
ani_alpha is true
ani_alpha is not a boolean .
static const unsigned char ani_alpha = 0x04;
(which I guess it involves flagging it as such in the .ani file)
No , it's a bit that must be set somewhere in the options of the animation .
class Animation : public AnimatedTexture
{
GFXColor mycolor;

Matrix local_transformation;

float height; //half the height so you can do fancy vector translatons to campspace

float width;

unsigned char options;
But where this bit must be set , i don't know .
Probably in the func that read the engine caps in the config file if what you said is true .

I don't have time to fix definitivly all the problems i encounter , as i need to go further in my project
and tweak what i can tweak .
I stopped the bleeding , but that's all i can do right now .
If this problem is only local ( my problem ) , that is good enough for me .
( i'm using the 0.5.1 rc1 source code for windows)

If others have this 'problem' ( it's a problem when you need background transparency for a goal ) ,
perhaps they will report it and you will know what to do .
You are the maintainer , i don't .
:D

When i will have more experience with that source code i will probably find the right fix easily .
But as nothing is documented , i progress like a blind .
8)

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 12:02 am
by klauss
The bit is set in animation.cpp, responding to the contents of the .ani file.

Honestly I don't remember exactly how it works (the code is quite obscure there), I'd have to check it out more thoroughly. But most decidedly, the fix involves writing the proper header in the .ani file.

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 12:43 am
by ezee
(the code is quite obscure there)
ah ah ah

Yeah man , i feel like a jedi that bring transparency where there was darkness ,
using slashs and stars !
:lol:
But most decidedly, the fix involves writing the proper header in the .ani file.
good .
Where is the fonction that reads this header ?
Because there we'll learn all the possible options that we could use with the .ani system .
And thus make a doc about it , to make the things less obscure by giving :idea: by the knowledge .
And make these things easier to work with , for you and me .
:)

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 6:27 pm
by klauss
I think it's done in cooperation between ani_texture.cpp and animation.cpp

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 6:30 pm
by ezee
I have found the place where the flag is not set ...
in animation.cpp
Animation::Animation( const char *FileName,
bool Rep,
float priority,
enum FILTER ismipmapped,
bool camorient,
bool appear_near_by_radius,
const GFXColor &c ) : mycolor( c )
{
Identity( local_transformation );
VSCONSTRUCT2( 'a' )
//repeat = Rep;
options = 0;
if (Rep)
options |= ani_repeat;
if (camorient)
options |= ani_up;
if (appear_near_by_radius)
options |= ani_close;
SetLoop( Rep ); //setup AnimatedTexture's loop flag - NOTE: Load() will leave it like this unless a force(No)Loop option is present
SetLoopInterp( Rep ); //Default interpolation method == looping method
VSFile f;
VSError err = f.OpenReadOnly( FileName, AnimFile );
if (err > Ok) {
//load success already set false
} else {
f.Fscanf( "%f %f", &width, &height );
if (width > 0)
options |= ani_alpha;
width = fabs( width*0.5F );
height = height*0.5F;
Load( f, 0, ismipmapped );
f.Close();
}
//VSFileSystem::ResetCurrentPath();
I don't understand the way it is coded , with that err>OK .
enum VSError
{
Shared, Ok, SocketError, FileNotFound, LocalPermissionDenied, RemotePermissionDenied, DownloadInterrupted,
IncompleteWrite, IncompleteRead, EndOfFile, IsDirectory, BadFormat, Unspecified
};
Would be simplier to say err==OK .
Perhaps the bug is here , err IS NEVER > OK , and so the alpha bit is never set .
:roll:

mmm , well no , as it is NEVER > OK , the else is working .
But that design is awful ...

the bug should be here :
else {
f.Fscanf( "%f %f", &width, &height );
if (width > 0)
options |= ani_alpha;
i will use printf to debug
:lol:

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 7:09 pm
by ezee
i did it :
if (width > 0)
{options |= ani_alpha;
printf( "options |= ani_alpha;\n" );
}
and stout say :
options |= ani_alpha;

so the flag must be set .
:?:

Edit :

The problem is the bit check here .
I have changed that with a boolean , and that is working now

change 1
static const unsigned char ani_up = 0x01;
static const unsigned char ani_close = 0x02;
//static const unsigned char ani_alpha = 0x04;
bool ani_alpha = false;
static const unsigned char ani_repeat = 0x08;
change 2
Animation::Animation( const char *FileName,
bool Rep,
float priority,
enum FILTER ismipmapped,
bool camorient,
bool appear_near_by_radius,
const GFXColor &c ) : mycolor( c )
{
Identity( local_transformation );
VSCONSTRUCT2( 'a' )
//repeat = Rep;
options = 0;
if (Rep)
options |= ani_repeat;
if (camorient)
options |= ani_up;
if (appear_near_by_radius)
options |= ani_close;
SetLoop( Rep ); //setup AnimatedTexture's loop flag - NOTE: Load() will leave it like this unless a force(No)Loop option is present
SetLoopInterp( Rep ); //Default interpolation method == looping method
VSFile f;
VSError err = f.OpenReadOnly( FileName, AnimFile );
if (err > Ok) {
//load success already set false
} else {
f.Fscanf( "%f %f", &width, &height );
if (width > 0)
{//options |= ani_alpha;
ani_alpha=true;

}
change 3
void Animation::DrawAsVSSprite( VSSprite *spr )
{
if (!spr)
return;
if (g_game.use_animations != 0 || g_game.use_textures != 0) {
//unsigned char alphamaps=ani_alpha;
GFXPushBlendMode();

if (ani_alpha)
GFXBlendMode( SRCALPHA, INVSRCALPHA );
else
GFXBlendMode( ONE, ZERO );
No more using bit flag for transparency now , but boolean .
( i still don't know how options&ani_alpha was evaluated ... )

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 7:35 pm
by klauss
Yeah, but for which ani is that output?

err > Ok is "there was an error", so it's ok not setting the flag when there's an error (since there's been an error and we're failing).

I think you just have to make sure width > 0.

What's your .ani file like?

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 7:48 pm
by ezee
ezee wrote:i did it :
if (width > 0)
{options |= ani_alpha;
printf( "options |= ani_alpha;\n" );
}
and stout say :
options |= ani_alpha;

so the flag must be set .
:?:

Edit :

The problem is the bit check here .
I have changed that with a boolean , and that is working now

change 1
static const unsigned char ani_up = 0x01;
static const unsigned char ani_close = 0x02;
//static const unsigned char ani_alpha = 0x04;
bool ani_alpha = false;
static const unsigned char ani_repeat = 0x08;
change 2
Animation::Animation( const char *FileName,
bool Rep,
float priority,
enum FILTER ismipmapped,
bool camorient,
bool appear_near_by_radius,
const GFXColor &c ) : mycolor( c )
{
Identity( local_transformation );
VSCONSTRUCT2( 'a' )
//repeat = Rep;
options = 0;
if (Rep)
options |= ani_repeat;
if (camorient)
options |= ani_up;
if (appear_near_by_radius)
options |= ani_close;
SetLoop( Rep ); //setup AnimatedTexture's loop flag - NOTE: Load() will leave it like this unless a force(No)Loop option is present
SetLoopInterp( Rep ); //Default interpolation method == looping method
VSFile f;
VSError err = f.OpenReadOnly( FileName, AnimFile );
if (err > Ok) {
//load success already set false
} else {
f.Fscanf( "%f %f", &width, &height );
if (width > 0)
{//options |= ani_alpha;
ani_alpha=true;

}
change 3
void Animation::DrawAsVSSprite( VSSprite *spr )
{
if (!spr)
return;
if (g_game.use_animations != 0 || g_game.use_textures != 0) {
//unsigned char alphamaps=ani_alpha;
GFXPushBlendMode();

if (ani_alpha)
GFXBlendMode( SRCALPHA, INVSRCALPHA );
else
GFXBlendMode( ONE, ZERO );
No more using bit flag for transparency now , but boolean .
( i still don't know how options&ani_alpha was evaluated ... )
the .ani is the oswald's one :
-10 10
20 .10
01.image
02.image
01.image
03.image
01.image
02.image
01.image
08.image
01.image
03.image
01.image
02.image
01.image
02.image
01.image
03.image
01.image
02.image
01.image
01.image
02.image
That is just a sequencer . ( i guess :lol: )
DO YOU HAVE THE TRANSPARENCY IN OSWALD TUTORIAL :?:
I have it now :D

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 7:53 pm
by klauss
There's your problem.

Width -10 means it's opaque (see? width < 0).

You need "10 10" if you want transparency.

That certainly needs to be in the wiki AND code comments.

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 8:50 pm
by ezee
Cool . thx
Please tell everything you know about the .ani format .
Why 10 10 ?
if W=alpha what is H ?
I will put that in the wiki .
:wink:

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 9:18 pm
by ezee
wait ....

if (width>0) worked with my fprints test !
And with -10 10 in the file !
But the bit check no
if( options&ani_alpha) { //be transparent }
So the problem is still there
:lol:

edit : I mean , the -10 10 change nothing , i have a transparency now with just a
boolean test that replace a bit test ) .

Or alpha= H in the .ani ?
that's crazy ...
:lol:
This part of the code should be modified , and let say a cat is a cat ?
And Alpha is not width !!!
:lol:
who is the alpha and omega ?

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 9:28 pm
by klauss
No, there's no problem. Your changes are equivalent to hardcoding transparency, so it's not good even if it happens to work.

W and H are the sprite's width and height in 3D units (roughly meters). It's not alpha or not. For anything intended for the screen, they don't matter at all. Any value (with the right positiveness) will work.

I'm sure you dislike the abuse of the sign as alpha, I also dislike it. Abhor it more accurately. But that's how all assets are now, and it's not trivial to fix (though doable).

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 9:48 pm
by ezee
I need to fully undertand the .ani format .
I will then write a Animation2 class with my logical vision .
And some additions :

do you know how to paint a texture over an animation ?
I'm searching a way to do that in an other thread about 2d cockpit .
There is also there a lack of information i want to fix ( for the cause of the Art :wink: )

Edit :
Your changes are equivalent to hardcoding transparency
NO !
:lol:

i just replace a bit flag test
if( options&ani_alpha) { //be transparent }
by a boolean flag .
if (ani_alpha){ //be transparent }[/b]

and the flag is set here BY THE PROGRAM

Code: Select all

if (width > 0)
{//options |= ani_alpha;
ani_alpha=true;
You don't understand that it's the test of the bit that sucks .
HAVE YOU GOT ANIMATION TRANSPARENCY WORKING IN YOUR VERSION ?
:?: :?: :?: :?:

i've found a bit's bible here :
http://graphics.stanford.edu/~seander/bithacks.html

Re: OpenGL translucent texture over other texture

Posted: Thu Mar 20, 2014 11:07 pm
by klauss
ezee wrote:I need to fully undertand the .ani format .
I will then write a Animation2 class with my logical vision .
Not recommendable. Switching all code to use said animation will be a PITA.
ezee wrote:do you know how to paint a texture over an animation ?
Not sure what you mean.
ezee wrote:There is also there a lack of information i want to fix ( for the cause of the Art :wink: )
Indeed, and said fixing would be greatly appreciated.

Edit :
ezee wrote:
Your changes are equivalent to hardcoding transparency
NO !
:lol:

i just replace a bit flag test
if( options&ani_alpha) { //be transparent }
by a boolean flag .
if (ani_alpha){ //be transparent }[/b]
...
You don't understand that it's the test of the bit that sucks .
HAVE YOU GOT ANIMATION TRANSPARENCY WORKING IN YOUR VERSION ?
Well, then I misunderstood your patch in your comment above. I'd need a diff-formatted patch. But it's moot, as the flags and the boolean are the same concept, if implemented correctly. I don't believe the current code has any bug, there's lots of transparent sprites all over the place, and the fact that they work is a sign that it's correct as is (even if ugly).

Re: OpenGL translucent texture over other texture

Posted: Fri Mar 21, 2014 12:17 am
by ezee
Not recommendable. Switching all code to use said animation will be a PITA.
I am not recommendable ( who wants a wookie to dinner with ?) . :wink:
But anyway , there will be no switch , only DEPRECATED class when the class Animation2 : Animation
will be in use .

Like for directx versions , Dx8 supersedes dx7 , but there was backward compatibility .
Dx9 starts to break the rule with shaders , and old D3DRM objects disapeared .
Idirect3D3 was Idirect3D8 with that kind of maintainance .

Animation2 could provide the same stuff than the one , but the fonctions will be reader friendly .
And if we can use shader in post effect for animations , we will have holo display too ...
Not sure Animation is used the same way in all the render engine , i will check that yeah .

So that is the way to evolve , you create new Objects based over olds , that will be less and less used , then
disapear . That is c++ power , no ?

But if you tweak the same old baby , it's not a baby that you play with after a decade , but an old man .
And don't ask to an old man to run .
:lol:

Re: OpenGL translucent texture over other texture

Posted: Fri Mar 21, 2014 12:35 am
by klauss
What?

No... the way to evolve, is you make Animation handle both formats. File formats aren't object-oriented things. The PITA is switching data to the new format in that way.

Backwards-compatible changes or wholesale refactorings are the two ways.

Re: OpenGL translucent texture over other texture

Posted: Fri Mar 21, 2014 12:55 am
by ezee
The PITA is switching data to the new format in that way.
WHAT !!!
:lol:

you mean " data " , the folder in svn ?
The textures are the same , the .sprite , .ani , .image don't change .

It's just a class that is using for example
struct S_Options
{
bool animation_Up; // everybody understand that , even a french
bool animation_Close;// everybody understand that , even a french
bool animation_Alpha;// everybody understand that , even a french
}options ;
to replace
static const unsigned char ani_up = 0x01;
static const unsigned char ani_close = 0x02;
//static const unsigned char ani_alpha = 0x04; don't works
bool ani_alpha = false;// works
static const unsigned char ani_repeat = 0x08;
and you say the rewrite will be a pita ?
Just look to the low number of fonctions members :

Code: Select all

class Animation : public AnimatedTexture
{
    GFXColor mycolor;

    Matrix   local_transformation;

    float    height; //half the height so you can do fancy vector translatons to campspace

    float    width;

    unsigned char options;

    void InitAnimation();

public: Animation();

    Animation( VSFileSystem::VSFile *f, bool Rep = 0, float priority = .1, enum FILTER ismipmapped = MIPMAP, bool camorient =
                  false, bool appear_near_by_radius = false, const GFXColor &col = GFXColor( 1, 1, 1,
                                                                                             1 ) );
    Animation( const char*, bool Rep = 0, float priority = .1, enum FILTER ismipmapped = MIPMAP, bool camorient = false,
              bool appear_near_by_radius = false, const GFXColor &col = GFXColor( 1, 1, 1,
                                                                                  1 ) );

    ~Animation();

    void Draw();
    void SetFaceCam( bool face );
    void SetInterpolate( bool interp );
    bool CalculateOrientation( Matrix &result );

    void DrawNow( const Matrix &final_orientation );

    void DrawNoTransform( bool cross = true, bool blendoption = false );

    void DrawAsVSSprite( class VSSprite*spr );

    static void ProcessDrawQueue( std::vector< Animation* >&, float );

    static void ProcessDrawQueue();

    static bool NeedsProcessDrawQueue();

    static void ProcessFarDrawQueue( float );
    
    static bool NeedsProcessFarDrawQueue();

    void SetDimensions( float wid, float hei );

    void GetDimensions( float &wid, float &hei );

    QVector Position();

    void SetPosition( const QVector& );

    void SetOrientation( const Vector &p, const Vector &q, const Vector &r );
};
If we modify some Animation::fonction to be virtual , we keep the name only the body changes .
In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature. This concept is an important part of the polymorphism portion of object-oriented programming (OOP).
src : http://en.wikipedia.org/wiki/Virtual_function

Actually , how many percent of the code is c ?
The c code is the root part of the VS gameengine .

But Animation is already a c++ class
And really when the draw func() will be virtual in animation .
:D

Re: OpenGL translucent texture over other texture

Posted: Fri Mar 21, 2014 1:01 am
by klauss
ezee wrote:
The PITA is switching data to the new format in that way.
WHAT !!!
:lol:

you mean " data " , the folder in svn ?
The textures are the same , the .sprite , .ani , .image don't change .

It's just a class that is using for example
struct S_Options
{
bool animation_Up; // everybody understand that , even a french
bool animation_Close;// everybody understand that , even a french
bool animation_Alpha;// everybody understand that , even a french
}options ;
Ah :(

I thought you were going to get rid of the negative widths (which are the really horrible thing if you ask me).

ps: make that struct a bitfield by using:

bool up : 1

(notice also the animation_ prefix is quite redundant since it's a field inside the animation object after all)

That retains the memory efficienty of the original code, and adds the clarity of the new code.