Boolean issues

Started by
3 comments, last by Psychopathetica 10 years, 5 months ago

I am terribly confused as to why something so simple on other programming languages could be total hell on C++. Ok heres the problem. I have a struct inside a header. And I made an extern variable declared as that structure.


#ifndef INTRO_H
#define INTRO_H

#include "DX.h"

struct Intro_Type
{
	bool Enabled;
	float Time;
	float Milliseconds;
	float Speed;
	LPDIRECT3DTEXTURE9 Texture;
	float Fade;
	CUSTOM_VERTEX Vertex_List[3];
};

void Load_Blizzard_Logo_Texture();
void Draw_Blizzard_Logo();
void Intro_Loop();

extern Intro_Type Blizzard_Logo;
extern Intro_Type Blizzard_Hold;
extern Intro_Type Blizzard_Fade;

#endif

Basically I'm trying to recreate the intro screen (which is shown before the actual title screen) to the game I was working on off another programming language and porting it to C++. Simple fade in, show a logo for a few seconds and fade out. Problem is, is that the boolean variable Enabled for Blizzard_Hold is not triggering even though the logic behind the code should trigger it. The only time it works is when I have Draw_Blizzard_Logo() commented out.


void Intro_Loop()
{
    Get_Elapsed_Time = (float)timeGetTime();
    if (Blizzard_Logo.Enabled == true)
    {
        Blizzard_Logo.Time = (Get_Elapsed_Time - Blizzard_Logo.Milliseconds) / 1000.0f;
        Fade = int(Blizzard_Fade.Speed * Blizzard_Logo.Time);
        if (Fade > 255)
        {
            Fade = 255;
            
            Blizzard_Logo.Enabled = false;
            Blizzard_Hold.Enabled = true;
            Blizzard_Hold.Milliseconds = Get_Elapsed_Time;
        }
    }
    if (Blizzard_Hold.Enabled == true)
    {
        Blizzard_Hold.Time = (Get_Elapsed_Time - Blizzard_Hold.Milliseconds) / 1000.0f;
        if (Blizzard_Hold.Time >= 5.0f)
        {
            Blizzard_Hold.Enabled = false;
            Blizzard_Fade.Enabled = true;
            Blizzard_Fade.Milliseconds = Get_Elapsed_Time;
        }
    }
    
    if (Blizzard_Fade.Enabled == true)
    {
        Blizzard_Fade.Time = (Get_Elapsed_Time - Blizzard_Fade.Milliseconds) / 1000.0f;
        Fade = 255 - (int)(Blizzard_Fade.Speed * Blizzard_Fade.Time);
        if (Fade <= 0.0f)
        {
            Fade = 0;
            Blizzard_Fade.Enabled = false;
        }
    }
    Draw_Blizzard_Logo(Fade);
}

Basically all the booleans trigger just fine when Draw_Blizzard_Logo(Fade); is commented out. But if its not commented out and I'm displaying the logo, it does the first if statement just fine, but doesn't trigger the next if statement because Blizzard_Hold.Enabled is still false even after Fade >= 255. The only code I got inside that sub routine Draw_Blizzard_Logo is this which shouldn't even effect the if statements at all:


void Draw_Blizzard_Logo(int Fade)
{
	if (Fullscreen_Enabled)
	{
		Blizzard_Logo.Vertex_List[0] = Create_Custom_Vertex(0, 0, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 0, 0);
		Blizzard_Logo.Vertex_List[1] = Create_Custom_Vertex((float)Screen.BackBufferWidth, 0, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 1, 0);
		Blizzard_Logo.Vertex_List[2] = Create_Custom_Vertex(0, (float)Screen.BackBufferHeight, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 0, 1);
		Blizzard_Logo.Vertex_List[3] = Create_Custom_Vertex((float)Screen.BackBufferWidth, (float)Screen.BackBufferHeight, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 1, 1);
	}
	else
	{
		Blizzard_Logo.Vertex_List[0] = Create_Custom_Vertex(0, 0, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 0, 0);
		Blizzard_Logo.Vertex_List[1] = Create_Custom_Vertex((float)Window_Width, 0, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 1, 0);
		Blizzard_Logo.Vertex_List[2] = Create_Custom_Vertex(0, (float)Window_Height, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 0, 1);
		Blizzard_Logo.Vertex_List[3] = Create_Custom_Vertex((float)Window_Width, (float)Window_Height, 0, 1, D3DCOLOR_RGBA(255, 255, 255, Fade), 1, 1);
	}
	Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	Device->SetTexture(0, Blizzard_Logo.Texture);
	Device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, Blizzard_Logo.Vertex_List, sizeof(CUSTOM_VERTEX));
}

Could anyone tell me what I'm doing wrong? I hope I was clear enough about everything. I'm stumpted o.O

Advertisement

The array Vertex_List is only length 3, but you are writing to the fourth element of it in Draw_Blizzard_Logo. You are writing off the end of the array and splatting the bool value that happens to be sat next to it in memory.

Edit: Bugs like this can be very tricky to track. The technique I'd recommend you learn is how to set hardware breakpoints in your IDE. It's possible to create a breakpoint that will fire when a variable changes. In this sort of situation you could have set a hardware breakpoint on 'Enabled' and that would have led you to the bug

Yep thats where I messed up. Thank you so much! Now it fades in and out like its suppose to. :D

In C++, basic variables like bools and ints aren't initialized automaticly. Your bools won't start off false, but they start off in a unpredictable state. I can't see in your code whether you are properly initializing them or not.

You can give the struct a non-default constructor to properly initialize the member variables:


struct Intro_Type
{ 
	Intro_Type() : Enabled(false), Time(0.0f), Milliseconds(0.0f), Speed(0.0f), Texture(...), Fade(0.0f)
	{
		Vertex_List[0] = {...};
		Vertex_List[1] = {...};
		Vertex_List[2] = {...};
	}

	bool Enabled;
	float Time;
	float Milliseconds;
	float Speed;
	LPDIRECT3DTEXTURE9 Texture;
	float Fade;
	CUSTOM_VERTEX Vertex_List[3];
};

Alternatively, if you use a compiler that supports the latest C++ standard (C++11), and have C++11 enabled, you can do this:


struct Intro_Type
{ 
	bool Enabled = false;
	float Time = 0.0f;
	float Milliseconds = 0.0f;
	float Speed = 0.0f;
	LPDIRECT3DTEXTURE9 Texture = ...;
	float Fade = 0.0f;
	CUSTOM_VERTEX Vertex_List[3] = {{...},{...},{...}};
};

With C++, uninitialized variables are kinda like playing russian roulette - you don't know what values are in the variables, so doing if (Blizzard_Logo.Enabled == true) might prove true some of the times your program is ran, and might prove false other times, unpredictably.

I actually initialized all of em when the program starts. Didnt show it cause it wasn't necessary but Blizzard_Logo.Enabled was true and the other 2 were false ;)

This topic is closed to new replies.

Advertisement