Game Development Community

dev|Pro Game Development Curriculum

flexable GuiFadeCtrl

by Ron Yacketta · 02/03/2004 (7:53 pm) · 7 comments

Download Code File

The .zip file contains guiFade.cc, guiFade.h, Ice-Dragon.jpg, init.cs, StartupGui.gui and Install.txt.

To install, simply follow the instructions in Install.txt or follow along here. I had to make changes to GuiCanvas.cc to resolve a bug introduced in the latest head. Currently the onSleep() function is called 2 times which causes issues. This might not be a valid fix in the eyes of GG; I added it to my copy of TGE roughly a week after the release of 1.2 and have had no ill effects.

The zip file contains a .cc, .h, .gui and a install.txt file

To install just follow the .txt or

Please make a backup before you proceed

Replace your StartupGui.gui file with the one in the .zip file

Open up engine\gui\guiControl.cc and comment out line 487

void GuiControl::onSleep()
{
   AssertFatal(mAwake, "GuiControl::onSleep: control is not awake");
   if(!mAwake)
      return;

   //decrement the profile reference
   mProfile->decRefCount();
   clearFirstResponder();
   mouseUnlock();
      
   //set the flag
// RJY : This causes a double call to onSleep() which crashes the game
//   Con::executef(this, 1, "onSleep");
   mAwake = false;
}

and add the following around line 913 in function GuiCanvas::popDialogControl
if(didSleep)
		Con::executef(ctrl,1, "onSleep");

the function should look like

void GuiCanvas::popDialogControl(GuiControl *gui)
{
   if (size() < 1)
      return;
   
   //first, find the dialog, and call the "onDialogPop()" method
   GuiControl *ctrl = NULL;
   if (gui)
   {
      //make sure the gui really exists on the stack
      iterator i;
      bool found = false;
      for(i = begin(); i != end(); i++)
      {
         GuiControl *check = static_cast<GuiControl *>(*i);
         if (check == gui)
         {
            ctrl = check;
            found = true;
         }
      }
      if (! found)
         return;
   }
   else
      ctrl = static_cast<GuiControl*>(last());
   
   //call the "on pop" function   
   ctrl->onDialogPop();
   
   // sleep the object
   bool didSleep = ctrl->isAwake();
   
   //now pop the last child (will sleep if awake)
   removeObject(ctrl);
   
   // Save the old responder:
   GuiControl *oldResponder = mFirstResponder;

	if(didSleep)
		Con::executef(ctrl,1, "onSleep");

   Sim::getGuiGroup()->addObject(ctrl);
   
   if (size() > 0)
   {
      GuiControl *ctrl = static_cast<GuiControl *>(last());
      mFirstResponder = ctrl->mFirstResponder;
   }
   else
   {
      mFirstResponder = NULL;
   }
   
   if (oldResponder && oldResponder != mFirstResponder)
      oldResponder->onLoseFirstResponder();
         
   //refresh the entire gui
   resetUpdateRegions();
   
   //rebuild the accelerator map
   mAcceleratorMap.clear();
   if (size() > 0)
   {
      GuiControl *ctrl = static_cast<GuiControl*>(last());
      ctrl->buildAcceleratorMap();
   }
   refreshMouseControl();
}

place the Ice-Dragon.jpg in the client\ui directory

Open up client\init.cs
Change
if ($JoinGameAddress !$= "") {
      // If we are instantly connecting to an address, load the
      // main menu then attempt the connect.
      loadMainMenu();
      connect($JoinGameAddress, "", $Pref::Player::Name);
   }
   else {
      // Otherwise go to the splash screen.
      Canvas.setCursor("DefaultCursor");
      loadStartup();
   }
to
if ($JoinGameAddress !$= "") {
      // If we are instantly connecting to an address, load the
      // main menu then attempt the connect.
      loadMainMenu();
      connect($JoinGameAddress, "", $Pref::Player::Name);
   }
   else {
      // Otherwise go to the splash screen.
      Canvas.setCursor("DefaultCursor");
      loadFadeImages();
   }
replace
function loadMainMenu()
{
   // Startup the client with the Main menu...
   Canvas.setContent( MainMenuGui );
   // Make sure the audio initialized.
   if($Audio::initFailed) {
      MessageBoxOK("Audio Initialization Failed", 
         "The OpenAL audio system failed to initialize.  " @
         "You can get the most recent OpenAL drivers <a:www.garagegames.com/docs/torque/gstarted/openal.html>here</a>.");
   }

   Canvas.setCursor("DefaultCursor");
}
with
function loadMainMenu()
{
	echo("loadMainMenu()");
   // Startup the client with the Main menu...
		if( $currentMod $= "show" )
		{
			Canvas.setContent( TSShowGui );		 
		} else {
		  	Canvas.setContent( MainMenuGui );
		}
		if($Audio::initFailed) {
			MessageBoxOK("Audio Initialization Failed", 
			"The OpenAL audio system failed to initialize.  " @
			"You can get the most recent OpenAL drivers <a:www.garagegames.com/docs/torque/gstarted/openal.html>here</a>.");
		}
   Canvas.setCursor("DefaultCursor");
}
add the following after the loadMainMenu function
function StartupGui::onWake(%this)
{
   echo("onWake()");
}

function StartupInputCtrl::onInputEvent(%this, %dev, %evt, %make)
{
	echo("onInputEvent()");
	if(%make)
	{
		loadMainMenu();
	}
}

function loadFadeImages()
{
// Startup the client with the Main menu...
   echo("loadFadeImages()"); 
   Canvas.setContent( StartupGui );
}

function StartupGui::onSleep()
{
	echo("StartupGui::onSleep()");
	loadMainMenu();
}
function MainMenuGui::onWake(%this)
{
   if($missionArg !$= "") {
      %mis = $missionArg;
      $missionArg = "";
      SM_StartMission(%mis);
      return;
   }
}
;

I applied the above against a pull of the latest head and using the script files under starter.fps. If you find errors or that I have missed a step let me know.

-Ron

#1
02/04/2004 (10:37 am)
Just re-read the install instructions posted above, man oh man I must have been smokign some whacky stuff last night!

In any event, the install.txt and the instructions above should mirror each other

-Ron
#2
02/05/2004 (4:02 pm)
I don't mean to pop your bubble, but such a control already exists called GuiFadeinBitmapCtrl.
#3
02/05/2004 (7:37 pm)
Ugh! dbl post..
#4
02/05/2004 (7:37 pm)
Nathan,

Last time I checked (just now ;)) GuiFadeinBitmapCtrl did not take any images files. It just does a simple fade in/out. The control I posted can use up to 2 images, one will fade in while the other fades out.

-Ron
#5
02/05/2004 (8:16 pm)
Here is one method of using it:

//--- OBJECT WRITE BEGIN ---
new GuiFadeinBitmapCtrl(StartupGui) {
   profile = "GuiInputCtrlProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "640 480";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";
   bitmap = "./gg_logo";
   wrap = "0";
   fadeinTime = "325";
   waitTime   = "3000";
   fadeoutTime = "325";
};
//--- OBJECT WRITE END ---

function loadStartup()
{
   StartupGui.done = false;
   Canvas.setContent( StartupGui );
   schedule(250, 0, StartupDone );
   alxPlay(AudioStartup);
}
function StartupGui::click()
{
   StartupGui.done = true;
}
function StartupDone()
{
   if (StartupGui.done)
   {
      echo(StartupGui.bitmap);
      if(StartupGui.bitmap $= "again/client/ui/gg_logo")
      {
         StartupGui.bitmap = "./prg_again";
         loadStartup();
      } else
         loadMainMenu();
   } else
      schedule(250, 0, StartupDone );
}

That's using two images and yes it does use an image. :P
#6
02/06/2004 (5:35 am)
To each their own, I like setting both images in the control and letting the control handle everything for me. I only have to handle the input event to stop the fade effect.

Also, (might be wrong again) but the method you posted just fades two images separately correct? my control would fade two images at the same time.. one would fade in while the other is fading out. You get a kewl effect when they are both about %50 transparent.

-Ron
#7
02/21/2004 (4:17 am)
Very nice! Now I can go back to editing the GUI again ;)