Game Development Community

Vista and Unicode support in 1.7.2

by Adam Johnston · in Torque Game Builder · 05/05/2008 (1:36 pm) · 6 replies

Hi !

I have used TGB when it was T2D and I did a simple platform demo.
That time my main concerns where:
- buggy physics
- slugish preformance in demanding levels.
I remember me posting some memory bugs in T2D that nobody has noticed before because the crash only seemed to happen under stressing situations.

After that my focus went to another project.

I see TGB has done a great advance since that days, so I'm wondering if somebody knows the *real* situation about Vista support (I read forum posts about TGB crashing in fullscreen) and Unicode support. I need to do a game that supports English, French, German, Spanish and Japanese.

Sorry, I used the search box, but only found old posts.

Out of the stock I copy-pasted a french string in the console window of 1.7.2 and got undefined characters, if somebody has used Unicode, can please post some insights about this?

Thank you in advance.

#1
05/05/2008 (1:43 pm)
Your scripts will have to be saved as UTF-8 for Unicode to work.

There have been some changes in regards to the ALT-TAB crashes, but I am not sure if the root causes have been addressed in 1.7.2. Amanda Fitch's team submitted a good chunk and Alex Stone implemented a sweet fix in the Windows Platform code for TGE.
#2
05/05/2008 (1:51 pm)
Hi David

Are those Vista fixes on the 1.7.2 or 1.7.3.beta stock source?
If I'm understanding correctly this is for TGE but not TGB?
I have TGE access can you point me to the related threads?

Thank you,
#3
05/05/2008 (1:56 pm)
I'm not sure. And the problem wasn't just with Vista, I believe. It think it was a windows API issue that predated Vista.

Here is Alex's topic and his fix (I also posted the fix from Amanda's team there). He got that working in TGE. I do not know if it will solve the issues in TGB.
#4
05/16/2008 (2:40 pm)
We're working on a Unicode fix so our game can support multiple languages. I know I promised to put one up ages ago, but our code was a little messy. Bryce is starting from scratch this time, and we are going to carefully document our steps. My guestimate is that we will have code available by June 15th, when YDF is shipped.
#5
05/19/2008 (12:47 pm)
David, the link you gave is not viewable by TGB only users.... Can you copy the text in or something? I'm having a very annoying time trying to get unicode fonts to display also, but ALL the search results for the forum are not available to TGB only developers which really sucks.
#6
05/19/2008 (4:57 pm)
Yeah. It is on the TGE private forum. I had posted the information for the ALT-TAB fix here, but cannot remember where it is. I'll post it again. You have to have the Pro version to use any of these.

From Amanda's Team:
These changes were to WinWindow.CC in the function WindowProc in the WM_ACTIVATEAPP case. It did not help in Alex's case, so any help people can give would be very much appreciated!


case WM_ACTIVATEAPP:

         if ((bool) wParam)

         {

            Video::reactivate();

            ShowCursor(false);

            if ( Video::isFullScreen() )

               hideTheTaskbar();

 

            // HACK:  Windows 98 (after switching from fullscreen to windowed mode)

            SetForegroundWindow( winState.appWindow );

 

            // If our keyboard state is dirty, clear it

            if( sgKeyboardStateDirty == true )

            {

               sgKeyboardStateDirty = false;

               InitInput();

            }

 

            // Your code may not need this... it was simply a way to inform the script that we were restarting audio!

            Con::executef( 2, "playBGM", 0 );

         }

         else

         {

            // Window lost focus so set a dirty flag on the keyboard state

            if ( lParam == 0 )

               sgKeyboardStateDirty = true;

 

            Video::deactivate();

            restoreTheTaskbar();

 

            alxStopAll();

 

         }

         break;

From Alex Stone:
Yeah, so I totally fixed this. The problem turned out to be a fundamental flaw in the way torque processes WM_ACTIVATEAPP messages. Torque destroys and recreates the window when processing this message, while still in the message loop, which could easily cause the Win32 API to freak out. The solution is to move the actual work of reactivating the game into the next trip through Platform::process, outside the messaging loop.

Part 1: Setting up some extra Video tracking state

In platformVideo.h, after


   static bool smCritical;



insert


   static bool smActive;
   static bool smActivating;
   static bool smReactivating;
   static bool smInactive;



after


   static void setVideo(const char * gapi, const char * vendor, const char * renderer, const char * platform, const char * os, const char * arch);



insert


   static bool isActive() { return smActive; }
   static bool isActivating() { return smActivating; }
   static bool isReactivating() { return smReactivating; }
   static bool isInactive() { return smInactive; }



In platformVideo.cc, after


bool					Video::smCritical = false;
bool					Video::smNeedResurrect = false;



insert


bool                    Video::smActive = false;
bool                    Video::smActivating = false;
bool                    Video::smReactivating = false;
bool                    Video::smInactive = false;



In Video::setDevice, after


      Con::printf( "Activating the %s display device...", renderName );
      smCurrentDevice = smDeviceList[deviceIndex];

      smCritical = true;



insert


	  smActivating = true;



and after


      bool result = smCurrentDevice->activate( width, height, bpp, fullScreen );



insert


	  smActivating = false;
	  smActive = true;
	  smInactive = false;



In Video::deactivate, after


      Platform::minimizeWindow();
      smCritical = false;
   }



insert


   smInactive = true;
   smActive = false;



in Video::reactivate, after


	   Resolution res = DisplayDevice::getResolution();

      smCritical = true;



insert


	  smReactivating = true;



and after


      smCurrentDevice->activate(res.w,res.h,res.bpp,DisplayDevice::isFullScreen());



insert


	  smReactivating = false;
	  smInactive = false;
	  smActive = true;



Ok, now for Part Deux, rearranging the reactivation code in winWindow.cc:

After:


static bool gWindowCreated = false;

static bool windowNotActive = false;



Insert:


static bool gDoReactivate = false;



In Platform::process, after:


void Platform::process()
{



Insert:


   if(gDoReactivate)
   {
            Video::reactivate();
            ShowCursor(false);
            if ( Video::isFullScreen() )
               hideTheTaskbar();

            // HACK:  Windows 98 (after switching from fullscreen to windowed mode)
            SetForegroundWindow( winState.appWindow );

            // If our keyboard state is dirty, clear it
            if( sgKeyboardStateDirty == true )
            {
               sgKeyboardStateDirty = false;
               InitInput();
            }

			gDoReactivate = false;
   }



In WindowProc, after


      case WM_ACTIVATEAPP:
         if ((bool) wParam)
         {



REPLACE THE CODE UP TO THE CLOSURE OF THE IF STATEMENT WITH:


			 if(Video::isInactive() && !Video::isReactivating())
			 {
				gDoReactivate = true;
			 }



So it should look like...


      case WM_ACTIVATEAPP:
         if ((bool) wParam)
         {
			 //>NEW CODE
			 if(Video::isInactive() && !Video::isReactivating())
			 {
				gDoReactivate = true;
			 }
			 //<NEW CODE
         }



NOTE: THIS IS A TENTATIVE FIX, it has not been tested on any other platforms except my own machine, but it no longer crashes when you alt-tab back into the game while it is in fullscreen. I'm actually a little suprised that GG didn't catch this in their QA process, as it seems to be a hardware independant bug in the windows platform code.

From Nelson A. K. Gonsalves:
his worked for me as well! No more nasty crashes.

And here is a little change I made to make it minimize the game window when you alt-tab out of full screen mode(or else all you will see is the task bar as the game window will stay on top of everything else):

After

case WM_ACTIVATEAPP:
   if ((bool) wParam)
   {
      if(Video::isInactive() && !Video::isReactivating())
      {
         gDoReactivate = true;
      }
   }


which was added by the changes above, add

   else if(Video::isFullScreen())
      Platform::minimizeWindow();


so that the case block looks like:

case WM_ACTIVATEAPP:
   if ((bool) wParam)
   {
      if(Video::isInactive() && !Video::isReactivating())
      {
         gDoReactivate = true;
      }
   }
   else if(Video::isFullScreen())
      Platform::minimizeWindow();
   break;