Game Development Community

T3D 1.1 Preview - Assigning sounds to GuiProfiles with GuiEditor is prone to Failure & Crashes! - RESOLVED

by Michael Hall · in Torque 3D Professional · 05/19/2011 (3:35 am) · 6 replies

Build:
T3D 1.1 Preview.

Platform:
Any

Target:
GUI - Sounds

Issue:
GUI Profile Editor saves garbage values for button sounds in a profile. If these sound properties are manually added to a profile the game will crash upon selection of the profile in the GUI Profile Editor.

Repeat:
Create some audio profiles, exec'd with the client-side core scripts.
// core/scripts/client/audioProfiles.cs
singleton SFXProfile(AudioButtonOver)  
{  
    filename = "art/sound/orc_pain";  
    description = "AudioGui";  
    preload = false;  
};  
  
singleton SFXProfile(AudioButtonDown)  
{  
    filename = "art/sound/orc_death";  
    description = "AudioGui";  
    preload = false;  
};

  1. Start game.
  2. From the GUI Editor create a new profile: MainMenuButton.
  3. Scroll down to the sound settings and choose the buttonDown & buttonUp sounds previously created.
  4. From the GUI Editor make sure that the MainMenuGui is the active gui to be edited.
  5. select any (or all) button and change it's profile to MainMenuButton.
  6. Save MainMenuGui.
  7. Exit GUI editor to MainMenu.
  8. Notice that moving over or clicking on the buttons produces no sound.
Error in console reads:
GuiControlProfile::protectedSetSoundButtonOver - no SFXTrack '������¼T'
Looking at the saved profile in customProfiles I see that garbage is saved for the buttonOver sound, and nothing for the buttonDown sound:
singleton GuiControlProfile(MainMenuButton)
{
   soundButtonOver = "������¼T";
};

Manually fill in the button sound information (with text editor) and resave the profile/file:
singleton GuiControlProfile(MainMenuButton)
{
   soundButtonOver = "AudioButtonOver";
   soundButtonDown = "AudioButtonDown";
};

Restart game and the button sounds now work. But start the GUI editor and select the newly created Profile for further editing and Torque will crash!

Suggest:
Make it work... properly.

About the author

Been dabbling with game-programming since the age of 10 when I got my first computer, a Commodore. Got serious about game-development after modding Tribes for several years. Doesn't sleep much. Drinks rum. Teaches guitar. Plays cello.


#1
05/19/2011 (10:55 am)
@Michael Hall: I've been assigned to your issue that you are having. When I get to step three and add buttonDown & buttonUp Torque crashes. Where are you having audioProfiles.cs execute from? I'm executing it from core.cs

// Very basic functions used by everyone.
   exec("./audio.cs");
   exec("./canvas.cs");
   exec("./cursor.cs");
   exec("./persistenceManagerTest.cs");
   exec("~/scripts/client/audioProfiles.cs");
#2
05/19/2011 (11:39 am)
On a different project I was actually getting a crash at step 3 as well...

For this report I used the Full Template and exec'd the new audioProfiles.cs in core.cs - but after the other audio stuff since sound profiles require that sound descriptions be loaded beforehand.
exec( "./audioEnvironments.cs" );
exec( "./audioDescriptions.cs" );
exec( "./audioStates.cs" );
exec( "./audioAmbiences.cs" );
exec("./audioProfiles.cs");
#3
05/19/2011 (11:57 am)
Ok, think I found the reason. Other bugs have come from this and I suspect there are more to be found. Need to do a pass over the codebase to fish for those.

The problem is SimObjectPtr which has always been a source for crashes in relation to field getters/setters. The thing is that it has now changed in such a way that even for getters the field is not representation-compatible with a plain pointer anymore. This means that any default getter on a SimObjectPtr field will fetch garbage data from somewhere with subsequent bad memory accesses and crashes.
#4
05/19/2011 (12:23 pm)
Ok, here's the change that should fix all the issues listed here...

First, add the following two methods in guiTypes.cpp

const char* GuiControlProfile::protectedGetSoundButtonDown( void* object, const char* data )
{
   GuiControlProfile* profile = reinterpret_cast< GuiControlProfile* >( object );

   SFXTrack* track = profile->mSoundButtonDown;
   if( !track )
      return "";

   return track->getName();
}

const char* GuiControlProfile::protectedGetSoundButtonOver( void* object, const char* data )
{
   GuiControlProfile* profile = reinterpret_cast< GuiControlProfile* >( object );

   SFXTrack* track = profile->mSoundButtonOver;
   if( !track )
      return "";

   return track->getName();
}

And also their declarations to GuiControlProfile in guiTypes.h

static const char* protectedGetSoundButtonDown( void* object, const char* data );
   static const char* protectedGetSoundButtonOver( void* object, const char* data );

Finally, in GuiControlProfile::initPersistFields, change the two addProtectedField calls for 'soundButtonOver' and 'soundButtonDown' to

addProtectedField( "soundButtonDown", TypeSFXTrackName,  Offset(mSoundButtonDown, GuiControlProfile),
         &GuiControlProfile::protectedSetSoundButtonDown, &GuiControlProfile::protectedGetSoundButtonDown,
         "Sound to play when mouse has been pressed on control." );
      addProtectedField( "soundButtonOver", TypeSFXTrackName,  Offset(mSoundButtonOver, GuiControlProfile),
         &GuiControlProfile::protectedSetSoundButtonOver, &GuiControlProfile::protectedGetSoundButtonOver,
         "Sound to play when mouse is hovering over control." );
#5
05/19/2011 (3:35 pm)
Yep, that fixed 'er right up :)
#6
05/26/2011 (11:51 am)
Fixed in 1.1 Final.