Panda3D
 All Classes Functions Variables Enumerations
showBase.cxx
00001 // Filename: showBase.cxx
00002 // Created by:  shochet (02Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014          
00015 #ifdef __APPLE__
00016 // We have to include this before we include any Panda libraries,
00017 // because one of the things we pick up in Panda defines a macro for
00018 // TCP_NODELAY and friends, causing heartaches for the header files
00019 // picked up here.
00020 #include <Carbon/Carbon.h>
00021 extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); }
00022 #endif
00023 
00024 #include "showBase.h"
00025 
00026 #include "throw_event.h"
00027 #include "graphicsWindow.h"
00028 #include "renderBuffer.h"
00029 #include "camera.h"
00030 #include "graphicsPipeSelection.h"
00031 
00032 #ifdef WIN32
00033 #include <windows.h>  // For SystemParametersInfo()
00034 STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0};
00035 TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0};
00036 FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0};  
00037 #endif
00038 
00039 ConfigureDef(config_showbase);
00040 ConfigureFn(config_showbase) {
00041 }
00042 
00043 ConfigVariableSearchPath particle_path
00044 ("particle-path", 
00045  PRC_DESC("The directories to search for particle files to be loaded."));
00046 
00047 ConfigVariableSearchPath &
00048 get_particle_path() {
00049   return particle_path;
00050 }
00051 
00052 // Throw the "NewFrame" event in the C++ world.  Some of the lerp code
00053 // depends on receiving this.
00054 void 
00055 throw_new_frame() {
00056   throw_event("NewFrame");
00057 }
00058 
00059 // Returns the configure object for accessing config variables from a
00060 // scripting language.
00061 DConfig &
00062 get_config_showbase() {
00063   static DConfig config_showbase;
00064   return config_showbase;
00065 }
00066 
00067 // Initialize the application for making a Gui-based app, such as wx.
00068 // At the moment, this is a no-op except on Mac.
00069 void
00070 init_app_for_gui() {
00071 #ifdef IS_OSX
00072   // Rudely bring the application to the foreground.  This is
00073   // particularly important when running wx via the plugin, since the
00074   // plugin app is seen as separate from the browser app, even though
00075   // the user sees them as the same thing.  We need to bring the
00076   // plugin app to the foreground to make its wx windows visible.
00077   activate_osx_application();
00078 #endif
00079 
00080   // We don't appear need to do the following, however, if we launch
00081   // the plugin correctly from its own bundle.
00082   /*
00083   static bool initted_for_gui = false;
00084   if (!initted_for_gui) {
00085     initted_for_gui = true;
00086 #ifdef IS_OSX
00087     ProcessSerialNumber psn;
00088     
00089     GetCurrentProcess(&psn);
00090     CPSEnableForegroundOperation(&psn);
00091     SetFrontProcess(&psn);
00092 #endif  // IS_OSX
00093   }
00094   */
00095 }
00096 
00097 // klunky interface since we cant pass array from python->C++ to use verify_window_sizes directly
00098 static int num_fullscreen_testsizes = 0;
00099 #define MAX_FULLSCREEN_TESTS 10
00100 static int fullscreen_testsizes[MAX_FULLSCREEN_TESTS * 2];
00101 
00102 void
00103 add_fullscreen_testsize(int xsize, int ysize) {
00104   if ((xsize == 0) && (ysize == 0)) {
00105     num_fullscreen_testsizes = 0;
00106     return;
00107   }
00108 
00109   // silently fail if maxtests exceeded
00110   if (num_fullscreen_testsizes < MAX_FULLSCREEN_TESTS) {
00111     fullscreen_testsizes[num_fullscreen_testsizes * 2] = xsize;
00112     fullscreen_testsizes[num_fullscreen_testsizes * 2 + 1] = ysize;
00113     num_fullscreen_testsizes++;
00114   }
00115 }
00116 
00117 void
00118 runtest_fullscreen_sizes(GraphicsWindow *win) {
00119   win->verify_window_sizes(num_fullscreen_testsizes, fullscreen_testsizes);
00120 }
00121 
00122 bool
00123 query_fullscreen_testresult(int xsize, int ysize) {
00124   // stupid linear search that works ok as long as total tests are small
00125   int i;
00126   for (i=0; i < num_fullscreen_testsizes; i++) {
00127     if((fullscreen_testsizes[i * 2] == xsize) &&
00128        (fullscreen_testsizes[i * 2 + 1] == ysize))
00129       return true;
00130   }
00131   return false;
00132 }
00133 
00134 void
00135 store_accessibility_shortcut_keys() {
00136 #ifdef WIN32
00137   SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
00138   SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
00139   SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
00140 #endif
00141 }
00142 
00143 void
00144 allow_accessibility_shortcut_keys(bool allowKeys) {
00145 #ifdef WIN32
00146   if( allowKeys )
00147   {
00148     // Restore StickyKeys/etc to original state and enable Windows key      
00149     SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
00150     SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
00151     SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
00152   } else {
00153     // Disable StickyKeys/etc shortcuts but if the accessibility feature is on, 
00154     // then leave the settings alone as its probably being usefully used
00155  
00156     STICKYKEYS skOff = g_StartupStickyKeys;
00157     if( (skOff.dwFlags & SKF_STICKYKEYSON) == 0 )
00158     {
00159       // Disable the hotkey and the confirmation
00160       skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
00161       skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
00162  
00163       SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &skOff, 0);
00164     }
00165  
00166     TOGGLEKEYS tkOff = g_StartupToggleKeys;
00167     if( (tkOff.dwFlags & TKF_TOGGLEKEYSON) == 0 )
00168     {
00169       // Disable the hotkey and the confirmation
00170       tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
00171       tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
00172  
00173       SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tkOff, 0);
00174     }
00175  
00176     FILTERKEYS fkOff = g_StartupFilterKeys;
00177     if( (fkOff.dwFlags & FKF_FILTERKEYSON) == 0 )
00178     {
00179       // Disable the hotkey and the confirmation
00180       fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
00181       fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
00182  
00183       SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fkOff, 0);
00184     }
00185   }  
00186 #endif  
00187 }
00188 
00189 #if 0
00190 int TempGridZoneManager::
00191 add_grid_zone(unsigned int x, 
00192               unsigned int y, 
00193               unsigned int width, 
00194               unsigned int height, 
00195               unsigned int zoneBase, 
00196               unsigned int xZoneResolution,
00197               unsigned int yZoneResolution) {
00198   // zoneBase is the first zone in the grid (e.g. the upper left)
00199   // zoneResolution is the number of cells on each axsis.
00200   // returns the next available zoneBase (i.e. zoneBase+xZoneResolution*yZoneResolution)
00201   cerr<<"adding grid zone with a zoneBase of "<<zoneBase<<" and a zoneResolution of "<<zoneResolution;
00202   _grids.append(TempGridZoneManager::GridZone(x, y, width, height, zoneBase, xZoneResolution, yZoneResolution));
00203   return zoneBase+xZoneResolution*yZoneResolution;
00204 }
00205 
00206 void TempGridZoneManager::GridZone
00207 GridZone(unsigned int x, 
00208          unsigned int y, 
00209          unsigned int width, 
00210          unsigned int height, 
00211          unsigned int zoneBase, 
00212          unsigned int xZoneResolution,
00213          unsigned int yZoneResolution) {
00214   _x=x;
00215   _y=y;
00216   _width=width;
00217   _height=heigth; 
00218   _zoneBase=zoneBase;
00219   _xZoneResolution=xZoneResolution;
00220   _yZoneResolution=yZoneResolution;
00221   
00222   // The cellVis is the number of cells radius that can
00223   // be seen, including the center cell.  So, for a 5 x 5
00224   // visible area, the cellVis is 3.
00225   const float cellVis=3.0;
00226   unsigned int xMargine=(unsigned int)((float)width/(float)xZoneResolution*cellVis+0.5);
00227   unsigned int yMargine=(unsigned int)((float)height/(float)yZoneResolution*cellVis+0.5);
00228   _xMinVis=x-xMargine;
00229   _yMinVis=y-yMargine;
00230   _xMaxVis=x+width+xMargine;
00231   _yMaxVis=y+height+yMargine;
00232 }
00233 
00234 void TempGridZoneManager::
00235 get_grids(int x, int y) {
00236   TempGridZoneManager::ZoneSet canSee;
00237   TempGridZoneManager::GridSet::const_iterator i=_grids.begin();
00238   for (; i!=_grids.end(); ++i) {
00239     if (x >= i._xMinVis && x < i._xMaxVis && y >= i._yMinVis && y < i._yMaxVis) {
00240       add_to_zone_list(i, x, y, canSee);
00241     }
00242   }
00243 }
00244 
00245 void TempGridZoneManager::
00246 add_to_zone_list(const TempGridZoneManager::GridZone &gridZone, 
00247     unsigned int x,
00248     unsigned int y,
00249     TempGridZoneManager::ZoneSet &zoneSet) {
00250   unsigned int xRes=gridZone._xZoneResolution;
00251   unsigned int yRes=gridZone._yZoneResolution;
00252   float xP=((float)(x-gridZone._x))/gridZone._width;
00253   float yP=((float)(y-gridZone._y))/gridZone._height;
00254   int xCell=(int)(xP*xRes);
00255   int yCell=(int)(yP*yRes);
00256 
00257   // range is how many cells can be seen in each direction:
00258   const int range=2;
00259   int yBegin=max(0, yCell-range);
00260   int yEnd=min(yRes, yCell+range);
00261   int xBegin=max(0, xCell-range);
00262   int xEnd=min(xRes, xCell+range);
00263   unsigned int zone=gridZone._zoneBase+yBegin*xRes+xBegin;
00264 
00265   for (yCell=yBegin; yCell < yEnd; ++yCell) {
00266     for (xCell=xBegin; xCell < xEnd; ++xCell) {
00267       zoneSet.append(zone+xCell);
00268     }
00269     zone+=xRes;
00270   }
00271 }
00272 
00273 int TempGridZoneManager::
00274 get_zone_list(int x, int y, int resolution) {
00275   // x is a float in the range 0.0 to 1.0
00276   // y is a float in the range 0.0 to 1.0
00277   // resolution is the number of cells on each axsis.
00278   // returns a list of zone ids.
00279   // 
00280   // Create a box of cell numbers, while clipping
00281   // to the edges of the set of cells.
00282   if (x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0) {
00283     return 0;
00284   }
00285   cerr<<"resolution="<<resolution;
00286   xCell=min(int(x*resolution), resolution-1)
00287   yCell=min(int(y*resolution), resolution-1)
00288   cell=yCell*resolution+xCell
00289   print "cell", cell,
00290   zone=zoneBase+cell
00291   print "zone", zone
00292 
00293   zone=zone-2*resolution
00294   endZone=zone+5*resolution
00295   yCell=yCell-2
00296   while zone < endZone:
00297       if yCell >= 0 and yCell < resolution:
00298           if xCell > 1:
00299               zoneList.append(zone-2)
00300               zoneList.append(zone-1)
00301           elif xCell > 0:
00302               zoneList.append(zone-1)
00303           r.append(zone)
00304           if xCell < resolution-2:
00305               zoneList.append(zone+1)
00306               zoneList.append(zone+2)
00307           elif xCell < resolution-1:
00308               zoneList.append(zone+1)
00309       yCell+=1
00310       zone+=resolution
00311   return zoneList
00312   return 5;
00313 }
00314 #endif
00315 
 All Classes Functions Variables Enumerations