Game Development Community

Forcing a Canvas repaint in onLevelLoaded()

by John F · in iTorque 2D · 04/05/2009 (10:18 am) · 5 replies


I spend a lot of time initializing my application in onLevelLoaded() during launch. To make the launch more visually interesting I would like to push a full screen dialog when entering onLevelLoadad() and pop it when exiting. This works when run on Windows but on the iPhone hardware the dialog is never displayed. I am following the call to Canvas.push() with a call to Canvas.repaint() to try to force the dialog to be shown but this seems to have no effect. How can I cause the dialog to be displayed?

Thanks in advance for any suggestions.

John

#1
04/05/2009 (3:03 pm)
That works on PC, but not on iPhone because it is single-threaded and needs time after the main loop to "sleep", and allow the GL to process.

It should work if you sleep a little bit(one frame or so) after after you push the dialog.
#2
04/05/2009 (4:50 pm)

Thanks Mat,

I was thinking that that might be the case, though I would have expected the repaint() call to force an immediate repaint. I've looked for sleep/yield type calls but came up empty. Can you give me a hint as to how I can sleep for one frame?

I also tried using schedule() to yield the CPU and this seemed to work on Windows (which was already working in any case) but on the iPhone I get a blank white screen during the time that the dialog should be visible. I've already exec'd the dialog's gui file at that point. Is there some other initialization that doesn't happen until the onLevelLoaded() function returns? Am I trying to do something odd here or is it accepted practice to write to the display during the execution of this function?

John
#3
04/06/2009 (10:40 am)
Repaint() does force an immediate repaint, the problem on an embedded device like the iPhone is the graphics have to exist in video memory already. That's no problem on PC/Mac because it happens when you first load it, but on the iPhone, it goes after the main loop every frame.

So before the data is actually loaded (I'm not sure when exactly onlevelLoaded() is called, before, during or whatever), exec the GUI, push it, and then schedule() the loading and GUI updating to start later (I would set it a second or two for testing).
#4
04/06/2009 (7:20 pm)
What I did in my game was right after the call to onStart() in main.cs I slightly modified the code to do this:

// Get this up right away
showGGScreen();
schedule(2000,0,"continueFromhackToShowGG");

function continueFromHackToShowGG()
{
   // Initialized
   echo("nTorque Game Builder (" @ getT2DVersion() @ ") initialized...");

   if( !isFunction( "initializeProject" ) || !isFunction( "_initializeProject" ) )
   {
      messageBox( "Game Startup Error", "'initializeProject' function could not be found." @
                  "nThis could indicate a bad or corrupt common directory for your game." @
                  "nnThe Game will now shutdown because it cannot properly function", "Ok", "MIStop" );
      quit();

   }

   _initializeProject();

   // Startup the project
   initializeProject();
}

The canvas is created in the onStart() call which ends up calling initializeCommon() down in the common//gameScripts//common.cs file

Then my showGGScreen() currently looks like this:

function showGGScreen()
{
   exec("~/gui/garageGames.gui");
   Canvas.setContent(GarageGames);
   if( $platform $= "iphone" )
      Canvas.hideCursor();
//   Canvas.repaint();

   // Load audio stuff
   exec("~/data/audio/AudioProfiles.cs");

   // Start playing the title song
   if( $platform $= "iphone" )
   {
      if ($isLiteVersion)
         mp3DisallowMusic();

      mp3Play("game/data/audio/salsaLoco.mp3");
   }
   else
   {
      alxplay(songMusic6);
   }
}

I commented out the Canvas.repaint() because it doesn't seem to make any difference whether you call it or not on the device.

This not the optimal solution because of the 2 second delay. What I'd like to do is figure out a simple way to do all my exec(...) in the initialProject() function - one exec per frame so my I'm continuing to init stuff during the delay. I supposed I could just brute force a bunch of schedules to do that.

Any way, hope this is helpful.
#5
04/22/2009 (12:22 am)

Mat and Kevin,

Thanks for your help! Using your suggestions I was able to get it working the way I wanted.

John