Browse Source

Merge branch 'master' into input-overhaul

rdb 8 years ago
parent
commit
8e6cf2a60b
100 changed files with 696 additions and 1633 deletions
  1. 10 1
      .gitignore
  2. 18 3
      .travis.yml
  3. 62 9
      README.md
  4. 1 1
      contrib/src/ai/aiCharacter.h
  5. 1 1
      contrib/src/ai/aiNode.h
  6. 1 1
      contrib/src/ai/flock.h
  7. 0 10
      direct/metalibs/direct/direct.cxx
  8. 95 1
      direct/src/actor/Actor.py
  9. 7 0
      direct/src/actor/__init__.py
  10. 13 0
      direct/src/controls/InputState.py
  11. 4 0
      direct/src/controls/__init__.py
  12. 1 1
      direct/src/dcparser/dcPacker.cxx
  13. 16 1
      direct/src/directbase/DirectStart.py
  14. 12 0
      direct/src/directbase/__init__.py
  15. 0 106
      direct/src/directbase/ppython.cxx
  16. 51 28
      direct/src/directdevices/DirectDeviceManager.py
  17. 1 1
      direct/src/directdevices/DirectRadamec.py
  18. 5 0
      direct/src/directdevices/__init__.py
  19. 3 0
      direct/src/directnotify/__init__.py
  20. 8 3
      direct/src/directscripts/eggcacher.py
  21. 0 831
      direct/src/directscripts/packpanda.nsi
  22. 0 424
      direct/src/directscripts/packpanda.py
  23. 1 1
      direct/src/directtools/DirectCameraControl.py
  24. 3 3
      direct/src/directtools/DirectManipulation.py
  25. 1 1
      direct/src/directtools/DirectSession.py
  26. 8 0
      direct/src/directtools/__init__.py
  27. 3 0
      direct/src/directutil/__init__.py
  28. 4 2
      direct/src/distributed/DistributedObject.py
  29. 8 6
      direct/src/distributed/DistributedSmoothNode.py
  30. 0 1
      direct/src/distributed/DoCollectionManager.py
  31. 0 7
      direct/src/distributed/StagedObject.py
  32. 5 0
      direct/src/distributed/__init__.py
  33. 2 2
      direct/src/distributed/cConnectionRepository.h
  34. 4 1
      direct/src/extensions_native/__init__.py
  35. 21 0
      direct/src/filter/CommonFilters.py
  36. 12 0
      direct/src/filter/FilterManager.py
  37. 11 0
      direct/src/filter/__init__.py
  38. 3 2
      direct/src/filter/filter-bloomx.sha
  39. 3 2
      direct/src/filter/filter-bloomy.sha
  40. 6 4
      direct/src/filter/filter-blurx.sha
  41. 6 4
      direct/src/filter/filter-blury.sha
  42. 6 6
      direct/src/fsm/ClassicFSM.py
  43. 1 1
      direct/src/fsm/FSM.py
  44. 19 21
      direct/src/fsm/FourState.py
  45. 25 27
      direct/src/fsm/FourStateAI.py
  46. 6 0
      direct/src/fsm/__init__.py
  47. 1 1
      direct/src/gui/DirectButton.py
  48. 3 1
      direct/src/gui/DirectCheckButton.py
  49. 1 1
      direct/src/gui/DirectDialog.py
  50. 2 1
      direct/src/gui/DirectEntry.py
  51. 14 9
      direct/src/gui/DirectFrame.py
  52. 24 25
      direct/src/gui/DirectGuiBase.py
  53. 3 5
      direct/src/gui/DirectGuiGlobals.py
  54. 1 1
      direct/src/gui/DirectLabel.py
  55. 1 1
      direct/src/gui/DirectOptionMenu.py
  56. 4 1
      direct/src/gui/DirectRadioButton.py
  57. 1 1
      direct/src/gui/DirectScrollBar.py
  58. 1 1
      direct/src/gui/DirectScrolledFrame.py
  59. 1 1
      direct/src/gui/DirectScrolledList.py
  60. 1 1
      direct/src/gui/DirectSlider.py
  61. 1 1
      direct/src/gui/DirectWaitBar.py
  62. 16 1
      direct/src/gui/OnscreenText.py
  63. 12 0
      direct/src/gui/__init__.py
  64. 1 1
      direct/src/interval/ActorInterval.py
  65. 3 1
      direct/src/interval/Interval.py
  66. 4 1
      direct/src/interval/IntervalGlobal.py
  67. 3 3
      direct/src/interval/IntervalManager.py
  68. 4 1
      direct/src/interval/MetaInterval.py
  69. 2 4
      direct/src/interval/ParticleInterval.py
  70. 3 5
      direct/src/interval/TestInterval.py
  71. 12 0
      direct/src/interval/__init__.py
  72. 3 3
      direct/src/interval/cConstrainHprInterval.h
  73. 4 4
      direct/src/interval/cConstrainPosHprInterval.h
  74. 3 3
      direct/src/interval/cConstrainPosInterval.h
  75. 3 3
      direct/src/interval/cConstrainTransformInterval.h
  76. 2 2
      direct/src/interval/cLerpAnimEffectInterval.h
  77. 4 4
      direct/src/interval/cLerpNodePathInterval.h
  78. 1 1
      direct/src/interval/cMetaInterval.h
  79. 1 1
      direct/src/interval/hideInterval.h
  80. 1 1
      direct/src/interval/showInterval.h
  81. 1 1
      direct/src/interval/waitInterval.h
  82. 3 0
      direct/src/motiontrail/__init__.py
  83. 5 2
      direct/src/p3d/AppRunner.py
  84. 4 0
      direct/src/p3d/__init__.py
  85. 7 0
      direct/src/particles/__init__.py
  86. 4 4
      direct/src/plugin/p3dInstance.cxx
  87. 8 8
      direct/src/plugin/p3dOsxSplashWindow.cxx
  88. 2 0
      direct/src/showbase/AppRunnerGlobal.py
  89. 25 1
      direct/src/showbase/Audio3DManager.py
  90. 3 1
      direct/src/showbase/BufferViewer.py
  91. 1 1
      direct/src/showbase/BulletinBoard.py
  92. 1 1
      direct/src/showbase/BulletinBoardWatcher.py
  93. 14 1
      direct/src/showbase/DirectObject.py
  94. 1 1
      direct/src/showbase/EventGroup.py
  95. 2 1
      direct/src/showbase/EventManager.py
  96. 2 1
      direct/src/showbase/EventManagerGlobal.py
  97. 1 1
      direct/src/showbase/Factory.py
  98. 2 4
      direct/src/showbase/FindCtaPaths.py
  99. 1 1
      direct/src/showbase/Finder.py
  100. 1 1
      direct/src/showbase/GarbageReport.py

+ 10 - 1
.gitignore

@@ -8,6 +8,7 @@
 core
 core
 core.*
 core.*
 vgcore.*
 vgcore.*
+*.core
 
 
 # Editor files/directories
 # Editor files/directories
 *.save
 *.save
@@ -22,6 +23,9 @@ vgcore.*
 *.o
 *.o
 *.gch
 *.gch
 *.pch
 *.pch
+/+DESC
+/+MANIFEST
+/pkg-plist
 
 
 # Produced installer/executables
 # Produced installer/executables
 /*.exe
 /*.exe
@@ -31,6 +35,7 @@ vgcore.*
 /*.pkg
 /*.pkg
 /*.dmg
 /*.dmg
 /*.whl
 /*.whl
+/*.txz
 
 
 # CMake
 # CMake
 /build/
 /build/
@@ -47,6 +52,10 @@ Thumbs.db
 ehthumbs.db
 ehthumbs.db
 
 
 # Python
 # Python
-__pycache__
+__pycache__/
 *.pyc
 *.pyc
 *.pyo
 *.pyo
+
+# Test tool cache directories
+.tox/
+.cache/

+ 18 - 3
.travis.yml

@@ -2,15 +2,22 @@ language: cpp
 sudo: false
 sudo: false
 matrix:
 matrix:
   include:
   include:
-    - compiler: gcc
-      env: PYTHONV=python2.7 FLAGS=--optimize=4
     - compiler: clang
     - compiler: clang
       env: PYTHONV=python3 FLAGS=--installer
       env: PYTHONV=python3 FLAGS=--installer
     - compiler: clang
     - compiler: clang
       env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
       env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
+    - compiler: gcc
+      env: PYTHONV=python2.7 FLAGS=--optimize=4
+      before_install:
+        - export CC=gcc-4.7
+        - export CXX=g++-4.7
 addons:
 addons:
   apt:
   apt:
+    sources:
+    - ubuntu-toolchain-r-test
     packages:
     packages:
+    - gcc-4.7
+    - g++-4.7
     - bison
     - bison
     - flex
     - flex
     - libfreetype6-dev
     - libfreetype6-dev
@@ -27,8 +34,16 @@ addons:
     - nvidia-cg-toolkit
     - nvidia-cg-toolkit
     - python-dev
     - python-dev
     - python3-dev
     - python3-dev
+    - python-virtualenv
     - zlib1g-dev
     - zlib1g-dev
-script: $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4 && LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
+    - fakeroot
+install:
+    - virtualenv --python=$PYTHONV venv && source venv/bin/activate
+    - $PYTHONV -m pip install pytest
+script:
+    - $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4
+    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
+    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest tests
 notifications:
 notifications:
   irc:
   irc:
     channels:
     channels:

+ 62 - 9
README.md

@@ -18,6 +18,23 @@ resources. If you get stuck, ask for help from our active
 Panda3D is licensed under the Modified BSD License.  See the LICENSE file for
 Panda3D is licensed under the Modified BSD License.  See the LICENSE file for
 more details.
 more details.
 
 
+Installing Panda3D
+==================
+
+By far, the easiest way to install the latest development build of Panda3D
+into an existing Python installation is using the following command:
+
+```bash
+pip install --pre --extra-index-url https://archive.panda3d.org/ panda3d
+```
+
+If you prefer to install the full SDK with all tools, the latest development
+builds can be obtained from this page:
+
+https://www.panda3d.org/download.php?sdk&version=devel
+
+These are automatically kept up-to-date with the latest GitHub version of Panda.
+
 Building Panda3D
 Building Panda3D
 ================
 ================
 
 
@@ -31,8 +48,8 @@ are included as part of the Windows 7.1 SDK.
 You will also need to have the third-party dependency libraries available for
 You will also need to have the third-party dependency libraries available for
 the build scripts to use.  These are available from one of these two URLs,
 the build scripts to use.  These are available from one of these two URLs,
 depending on whether you are on a 32-bit or 64-bit system:
 depending on whether you are on a 32-bit or 64-bit system:
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win32.zip
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win64.zip
+https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win32.zip
+https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win64.zip
 
 
 After acquiring these dependencies, you may simply build Panda3D from the
 After acquiring these dependencies, you may simply build Panda3D from the
 command prompt using the following command:
 command prompt using the following command:
@@ -64,7 +81,7 @@ for you to install, depending on your distribution).
 The following command illustrates how to build Panda3D with some common
 The following command illustrates how to build Panda3D with some common
 options:
 options:
 ```bash
 ```bash
-python2.7 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
+python makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2 --no-opencv
 ```
 ```
 
 
 You will probably see some warnings saying that it's unable to find several
 You will probably see some warnings saying that it's unable to find several
@@ -93,11 +110,14 @@ may have to use the installpanda.py script instead, which will directly copy the
 files into the appropriate locations on your computer.  You may have to run the
 files into the appropriate locations on your computer.  You may have to run the
 `ldconfig` tool in order to update your library cache after installing Panda3D.
 `ldconfig` tool in order to update your library cache after installing Panda3D.
 
 
-Mac OS X
---------
+Alternatively, you can add the `--wheel` option, which will produce a .whl
+file that can be installed into a Python installation using `pip`.
+
+macOS
+-----
 
 
-On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
-compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-mac.tar.gz).
+On macOS, you will need to download a set of precompiled thirdparty packages in order to
+compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-mac.tar.gz).
 
 
 After placing the thirdparty directory inside the panda3d source directory,
 After placing the thirdparty directory inside the panda3d source directory,
 you may build Panda3D using a command like the following:
 you may build Panda3D using a command like the following:
@@ -107,20 +127,53 @@ python makepanda/makepanda.py --everything --installer
 ```
 ```
 
 
 In order to make a universal build, pass the --universal flag.  You may also
 In order to make a universal build, pass the --universal flag.  You may also
-target a specific minimum Mac OS X version using the --osxtarget flag followed
+target a specific minimum macOS version using the --osxtarget flag followed
 by the release number, eg. 10.6 or 10.7.
 by the release number, eg. 10.6 or 10.7.
 
 
 If the build was successful, makepanda will have generated a .dmg file in
 If the build was successful, makepanda will have generated a .dmg file in
 the source directory containing the installer.  Simply open it and run the
 the source directory containing the installer.  Simply open it and run the
 package file in order to install the SDK onto your system.
 package file in order to install the SDK onto your system.
 
 
+FreeBSD
+-------
+
+Building on FreeBSD is very similar to building on Linux.  You will need to
+install the requisite packages using the system package manager.  To install
+the recommended set of dependencies, you can use this command:
+
+```bash
+pkg install pkgconf png jpeg-turbo tiff freetype2 eigen squish openal opusfile libvorbis libX11 libGL ode bullet assimp openexr
+```
+
+You will also need to choose which version of Python you want to use.
+Install the appropriate package for it (such as `python2` or `python36`) and
+run the makepanda script with your chosen Python version:
+
+```bash
+python3.6 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
+```
+
+If successful, this will produce a .pkg file in the root of the source
+directory which you can install using `pkg install`.
+
+Running Tests
+=============
+
+Install [PyTest](https://docs.pytest.org/en/latest/getting-started.html#installation)
+and run the `pytest` command.  If you have not installed Panda3D, you will
+need to configure your enviroment by pointing the `PYTHONPATH` variable at
+the `built` directory.  On Linux, you will also need to point the
+`LD_LIBRARY_PATH` variable at the `built/lib` directory.
+
+As a convenience, you can alternatively pass the `--tests` option to makepanda.
+
 Reporting Issues
 Reporting Issues
 ================
 ================
 
 
 If you encounter any bugs when using Panda3D, please report them in the bug
 If you encounter any bugs when using Panda3D, please report them in the bug
 tracker.  This is hosted at:
 tracker.  This is hosted at:
 
 
-  https://bugs.launchpad.net/panda3d
+  https://github.com/panda3d/panda3d/issues
 
 
 Make sure to first use the search function to see if the bug has already been
 Make sure to first use the search function to see if the bug has already been
 reported.  When filling out a bug report, make sure that you include as much
 reported.  When filling out a bug report, make sure that you include as much

+ 1 - 1
contrib/src/ai/aiCharacter.h

@@ -62,7 +62,7 @@ PUBLISHED:
     // This function is used to enable or disable the guides for path finding.
     // This function is used to enable or disable the guides for path finding.
     void set_pf_guide(bool pf_guide);
     void set_pf_guide(bool pf_guide);
 
 
-    AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force);
+    explicit AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force);
     ~AICharacter();
     ~AICharacter();
 };
 };
 
 

+ 1 - 1
contrib/src/ai/aiNode.h

@@ -66,7 +66,7 @@ public:
   AINode *_next;
   AINode *_next;
 
 
 PUBLISHED:
 PUBLISHED:
-  AINode(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h);
+  explicit AINode(int grid_x, int grid_y, LVecBase3 pos, float w, float l, float h);
   ~AINode();
   ~AINode();
 
 
   bool contains(float x, float y);
   bool contains(float x, float y);

+ 1 - 1
contrib/src/ai/flock.h

@@ -44,7 +44,7 @@ public:
   AICharList _ai_char_list;
   AICharList _ai_char_list;
 
 
 PUBLISHED:
 PUBLISHED:
-  Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2,
+  explicit Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2,
     unsigned int cohesion_wt = 4, unsigned int alignment_wt = 1);
     unsigned int cohesion_wt = 4, unsigned int alignment_wt = 1);
   ~Flock();
   ~Flock();
 
 

+ 0 - 10
direct/metalibs/direct/direct.cxx

@@ -1,10 +0,0 @@
-/**
- * @file direct.cxx
- * @author drose
- * @date 2000-05-18
- */
-
-// This is a dummy file whose sole purpose is to give the compiler something
-// to compile when making libdirect.so in NO_DEFER mode, which generates an
-// empty library that itself links with all the other shared libraries that
-// make up libdirect.

+ 95 - 1
direct/src/actor/Actor.py

@@ -50,6 +50,10 @@ class Actor(DirectObject, NodePath):
         def __repr__(self):
         def __repr__(self):
             return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
             return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
 
 
+
+        #snake_case alias:
+        get_bundle = getBundle
+
     class AnimDef:
     class AnimDef:
 
 
         """Instances of this class are stored within the
         """Instances of this class are stored within the
@@ -72,6 +76,10 @@ class Actor(DirectObject, NodePath):
         def __repr__(self):
         def __repr__(self):
             return 'Actor.AnimDef(%s)' % (repr(self.filename))
             return 'Actor.AnimDef(%s)' % (repr(self.filename))
 
 
+
+        #snake_case alias:
+        make_copy = makeCopy
+
     class SubpartDef:
     class SubpartDef:
 
 
         """Instances of this class are stored within the SubpartDict
         """Instances of this class are stored within the SubpartDict
@@ -889,7 +897,7 @@ class Actor(DirectObject, NodePath):
         return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
         return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
 
 
     def getNumFrames(self, animName=None, partName=None):
     def getNumFrames(self, animName=None, partName=None):
-        lodName = next(iter(self.__animControlDict))
+        #lodName = next(iter(self.__animControlDict))
         controls = self.getAnimControls(animName, partName)
         controls = self.getAnimControls(animName, partName)
         if len(controls) == 0:
         if len(controls) == 0:
             return None
             return None
@@ -2549,3 +2557,89 @@ class Actor(DirectObject, NodePath):
         for partBundleDict in self.__partBundleDict.values():
         for partBundleDict in self.__partBundleDict.values():
             partDef = partBundleDict.get(subpartDef.truePartName)
             partDef = partBundleDict.get(subpartDef.truePartName)
             partDef.getBundle().setName(newBundleName)
             partDef.getBundle().setName(newBundleName)
+
+    #snake_case alias:
+    control_joint = controlJoint
+    set_lod_animation = setLODAnimation
+    get_anim_control_dict = getAnimControlDict
+    get_actor_info = getActorInfo
+    clear_lod_animation = clearLODAnimation
+    reset_lod = resetLOD
+    fix_bounds = fixBounds
+    get_anim_filename = getAnimFilename
+    get_subparts_complete = getSubpartsComplete
+    verify_subparts_complete = verifySubpartsComplete
+    get_play_rate = getPlayRate
+    clear_python_data = clearPythonData
+    load_anims = loadAnims
+    set_subparts_complete = setSubpartsComplete
+    draw_in_front = drawInFront
+    get_lod_node = getLODNode
+    hide_part = hidePart
+    get_joint_transform_state = getJointTransformState
+    set_control_effect = setControlEffect
+    get_anim_controls = getAnimControls
+    release_joint = releaseJoint
+    print_anim_blends = printAnimBlends
+    get_lod = getLOD
+    disable_blend = disableBlend
+    show_part = showPart
+    get_joint_transform = getJointTransform
+    face_away_from_viewer = faceAwayFromViewer
+    set_lod = setLOD
+    osd_anim_blends = osdAnimBlends
+    get_current_frame = getCurrentFrame
+    set_play_rate = setPlayRate
+    bind_all_anims = bindAllAnims
+    unload_anims = unloadAnims
+    remove_part = removePart
+    use_lod = useLOD
+    get_anim_blends = getAnimBlends
+    get_lod_index = getLODIndex
+    get_num_frames = getNumFrames
+    post_flatten = postFlatten
+    get_lod_names = getLODNames
+    list_joints = listJoints
+    make_subpart = makeSubpart
+    get_anim_control = getAnimControl
+    get_part_bundle = getPartBundle
+    get_part_bundle_dict = getPartBundleDict
+    get_duration = getDuration
+    has_lod = hasLOD
+    print_lod = printLOD
+    fix_bounds_old = fixBounds_old
+    get_anim_names = getAnimNames
+    get_part_bundles = getPartBundles
+    anim_panel = animPanel
+    stop_joint = stopJoint
+    actor_interval = actorInterval
+    hide_all_bounds = hideAllBounds
+    show_all_bounds = showAllBounds
+    init_anims_on_all_lods = initAnimsOnAllLODs
+    get_part = getPart
+    add_lod = addLOD
+    show_all_parts = showAllParts
+    get_joints = getJoints
+    get_overlapping_joints = getOverlappingJoints
+    enable_blend = enableBlend
+    face_towards_viewer = faceTowardsViewer
+    bind_anim = bindAnim
+    set_blend = setBlend
+    get_frame_time = getFrameTime
+    remove_node = removeNode
+    wait_pending = waitPending
+    expose_joint = exposeJoint
+    set_lod_node = setLODNode
+    get_frame_rate = getFrameRate
+    get_current_anim = getCurrentAnim
+    get_part_names = getPartNames
+    freeze_joint = freezeJoint
+    set_center = setCenter
+    rename_part_bundles = renamePartBundles
+    get_geom_node = getGeomNode
+    set_geom_node = setGeomNode
+    load_model = loadModel
+    copy_actor = copyActor
+    get_base_frame_rate = getBaseFrameRate
+    remove_anim_control_dict = removeAnimControlDict
+    load_anims_on_all_lods = loadAnimsOnAllLODs

+ 7 - 0
direct/src/actor/__init__.py

@@ -0,0 +1,7 @@
+"""
+This package contains the :class:`.Actor` class as well as a
+distributed variant thereof.  Actor is a high-level interface around
+the lower-level :class:`panda3d.core.Character` implementation.
+It loads and controls an animated character and manages the animations
+playing on it.
+"""

+ 13 - 0
direct/src/controls/InputState.py

@@ -21,6 +21,9 @@ class InputStateToken:
     def __hash__(self):
     def __hash__(self):
         return self._hash
         return self._hash
 
 
+    #snake_case alias:
+    is_valid = isValid
+
 class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
 class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
     def release(self):
     def release(self):
         self._inputState._ignore(self)
         self._inputState._ignore(self)
@@ -39,6 +42,9 @@ class InputStateTokenGroup:
             token.release()
             token.release()
         self._tokens = []
         self._tokens = []
 
 
+    #snake_case alias:
+    add_token = addToken
+
 class InputState(DirectObject.DirectObject):
 class InputState(DirectObject.DirectObject):
     """
     """
     InputState is for tracking the on/off state of some events.
     InputState is for tracking the on/off state of some events.
@@ -235,3 +241,10 @@ class InputState(DirectObject.DirectObject):
         """for debugging"""
         """for debugging"""
         return self.notify.debug(
         return self.notify.debug(
             "%s (%s) %s"%(id(self), len(self._state), message))
             "%s (%s) %s"%(id(self), len(self._state), message))
+
+    #snake_case alias:
+    watch_with_modifiers = watchWithModifiers
+    is_set = isSet
+    get_event_name = getEventName
+    debug_print = debugPrint
+    release_inputs = releaseInputs

+ 4 - 0
direct/src/controls/__init__.py

@@ -0,0 +1,4 @@
+"""
+This package contains various types of character controllers, handling basic
+control mechanics and setting up collisions for them.
+"""

+ 1 - 1
direct/src/dcparser/dcPacker.cxx

@@ -708,7 +708,7 @@ pack_object(PyObject *object) {
     pack_int64(PyLong_AsLongLong(object));
     pack_int64(PyLong_AsLongLong(object));
 #if PY_MAJOR_VERSION >= 3
 #if PY_MAJOR_VERSION >= 3
   } else if (PyUnicode_Check(object)) {
   } else if (PyUnicode_Check(object)) {
-    char *buffer;
+    const char *buffer;
     Py_ssize_t length;
     Py_ssize_t length;
     buffer = PyUnicode_AsUTF8AndSize(object, &length);
     buffer = PyUnicode_AsUTF8AndSize(object, &length);
     if (buffer) {
     if (buffer) {

+ 16 - 1
direct/src/directbase/DirectStart.py

@@ -1,4 +1,19 @@
-""" This is a deprecated module that creates a global instance of ShowBase. """
+"""
+This is a shortcut that instantiates ShowBase automatically on import,
+opening a graphical window and setting up the scene graph.
+This example demonstrates its use:
+
+   import direct.directbase.DirectStart
+   run()
+
+While it may be considered useful for quick prototyping in the interactive
+Python shell, using it in applications is not considered good style.
+As such, it has been deprecated starting with Panda3D 1.9.  It is equivalent
+to and may be replaced by the following code:
+
+   from direct.showbase.ShowBase import ShowBase
+   base = ShowBase()
+"""
 
 
 __all__ = []
 __all__ = []
 
 

+ 12 - 0
direct/src/directbase/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains modules to quickly set up a Panda environment for
+quick prototyping in the interactive Python shell.  Merely importing
+one of these modules will create a :class:`.ShowBase` instance, opening
+a graphical window and setting up the scene graph.
+
+The most commonly used module from this package is :mod:`.DirectStart`,
+importing which executes the following code::
+
+   from direct.showbase.ShowBase import ShowBase
+   base = ShowBase()
+"""

+ 0 - 106
direct/src/directbase/ppython.cxx

@@ -1,106 +0,0 @@
-// This is a little wrapper to make it easy to run a python program from the
-// command line.  Basically, it just interfaces to the Python API and imports
-// the module that was specified by the IMPORT_MODULE preprocessor definition
-// when it was compiled.
-
-#include "dtoolbase.h"
-
-#undef _POSIX_C_SOURCE
-#undef _XOPEN_SOURCE
-#include <Python.h>
-#if PY_MAJOR_VERSION >= 3
-#include <wchar.h>
-#endif
-
-#ifndef IMPORT_MODULE
-#error IMPORT_MODULE must be defined when compiling ppython.cxx !
-#endif
-
-#define _STRINGIFY(s) #s
-#define STRINGIFY(s) _STRINGIFY(s)
-#define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE)
-
-#if defined(_WIN32) && PY_MAJOR_VERSION >= 3
-// As Py_SetProgramName expects a wchar_t*, it's easiest to just use the wmain
-// entry point.
-int wmain(int argc, wchar_t *argv[]) {
-  Py_SetProgramName(argv[0]);
-
-#elif PY_MAJOR_VERSION >= 3
-// Convert from UTF-8 to wchar_t*.
-int main(int argc, char *mb_argv[]) {
-  wchar_t **argv = new wchar_t*[argc + 1];
-  for (int i = 0; i < argc; ++i) {
-    size_t len = mbstowcs(NULL, mb_argv[i], 0);
-    argv[i] = new wchar_t[len + 1];
-    mbstowcs(argv[i], mb_argv[i], len);
-    argv[i][len] = 0;
-  }
-  // Just for good measure
-  argv[argc] = NULL;
-
-  Py_SetProgramName(argv[0]);
-
-#else
-// Python 2.
-int main(int argc, char *argv[]) {
-  Py_SetProgramName(argv[0]);
-#endif
-
-  // On Windows, we need to set pythonhome correctly.  We'll try to find
-  // ppython.exe on the path and set pythonhome to its location.
-#ifdef _WIN32
-#if PY_MAJOR_VERSION >= 3
-  // Py_SetPythonHome expects a wchar_t in Python 3.
-  wchar_t *path = _wgetenv(L"PATH");
-  wchar_t *result = wcstok(path, L";");
-  while (result != NULL) {
-    struct _stat st;
-    wchar_t *ppython = (wchar_t*) malloc(wcslen(result) * 2 + 26);
-    wcscpy(ppython, result);
-    wcscat(ppython, L"\\python.exe");
-    if (_wstat(ppython, &st) == 0) {
-      Py_SetPythonHome(result);
-      free(ppython);
-      break;
-    }
-    result = wcstok(NULL, L";");
-    free(ppython);
-  }
-#else
-  char *path = getenv("PATH");
-  char *result = strtok(path, ";");
-  while (result != NULL) {
-    struct stat st;
-    char *ppython = (char*) malloc(strlen(result) + 13);
-    strcpy(ppython, result);
-    strcat(ppython, "\\ppython.exe");
-    if (stat(ppython, &st) == 0) {
-      Py_SetPythonHome(result);
-      free(ppython);
-      break;
-    }
-    result = strtok(NULL, ";");
-    free(ppython);
-  }
-#endif
-#endif
-
-  Py_Initialize();
-
-  if (Py_VerboseFlag) {
-    fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright());
-  }
-
-  PySys_SetArgv(argc, argv);
-
-  int sts = 0;
-  PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR);
-  if (m <= 0) {
-    PyErr_Print();
-    sts = 1;
-  }
-
-  Py_Finalize();
-  return sts;
-}

+ 51 - 28
direct/src/directdevices/DirectDeviceManager.py

@@ -9,10 +9,6 @@ ANALOG_MAX = 0.95
 ANALOG_DEADBAND = 0.125
 ANALOG_DEADBAND = 0.125
 ANALOG_CENTER = 0.0
 ANALOG_CENTER = 0.0
 
 
-try:
-    myBase = base
-except:
-    myBase = simbase
 
 
 class DirectDeviceManager(VrpnClient, DirectObject):
 class DirectDeviceManager(VrpnClient, DirectObject):
     def __init__(self, server = None):
     def __init__(self, server = None):
@@ -52,8 +48,13 @@ class DirectButtons(ButtonNode, DirectObject):
         ButtonNode.__init__(self, vrpnClient, device)
         ButtonNode.__init__(self, vrpnClient, device)
         # Create a unique name for this button object
         # Create a unique name for this button object
         self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
         self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def __getitem__(self, index):
     def __getitem__(self, index):
         if (index < 0) or (index >= self.getNumButtons()):
         if (index < 0) or (index >= self.getNumButtons()):
@@ -64,10 +65,10 @@ class DirectButtons(ButtonNode, DirectObject):
         return self.getNumButtons()
         return self.getNumButtons()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -83,6 +84,12 @@ class DirectButtons(ButtonNode, DirectObject):
 
 
 class DirectAnalogs(AnalogNode, DirectObject):
 class DirectAnalogs(AnalogNode, DirectObject):
     analogCount = 0
     analogCount = 0
+
+    _analogDeadband = ConfigVariableDouble('vrpn-analog-deadband', ANALOG_DEADBAND)
+    _analogMin = ConfigVariableDouble('vrpn-analog-min', ANALOG_MIN)
+    _analogMax = ConfigVariableDouble('vrpn-analog-max', ANALOG_MAX)
+    _analogCenter = ConfigVariableDouble('vrpn-analog-center', ANALOG_CENTER)
+
     def __init__(self, vrpnClient, device):
     def __init__(self, vrpnClient, device):
         # Keep track of number of analogs created
         # Keep track of number of analogs created
         DirectAnalogs.analogCount += 1
         DirectAnalogs.analogCount += 1
@@ -90,20 +97,21 @@ class DirectAnalogs(AnalogNode, DirectObject):
         AnalogNode.__init__(self, vrpnClient, device)
         AnalogNode.__init__(self, vrpnClient, device)
         # Create a unique name for this analog object
         # Create a unique name for this analog object
         self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
         self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
+
         # See if any of the general analog parameters are dconfig'd
         # See if any of the general analog parameters are dconfig'd
-        self.analogDeadband = myBase.config.GetFloat('vrpn-analog-deadband',
-                                                     ANALOG_DEADBAND)
-        self.analogMin = myBase.config.GetFloat('vrpn-analog-min',
-                                                ANALOG_MIN)
-        self.analogMax = myBase.config.GetFloat('vrpn-analog-max',
-                                                ANALOG_MAX)
-        self.analogCenter = myBase.config.GetFloat('vrpn-analog-center',
-                                                   ANALOG_CENTER)
+        self.analogDeadband = self._analogDeadband.getValue()
+        self.analogMin = self._analogMin.getValue()
+        self.analogMax = self._analogMax.getValue()
+        self.analogCenter = self._analogCenter.getValue()
         self.analogRange = self.analogMax - self.analogMin
         self.analogRange = self.analogMax - self.analogMin
 
 
-
     def __getitem__(self, index):
     def __getitem__(self, index):
         if (index < 0) or (index >= self.getNumControls()):
         if (index < 0) or (index >= self.getNumControls()):
             raise IndexError
             raise IndexError
@@ -113,10 +121,10 @@ class DirectAnalogs(AnalogNode, DirectObject):
         return self.getNumControls()
         return self.getNumControls()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
     def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
         #
         #
@@ -186,14 +194,19 @@ class DirectTracker(TrackerNode, DirectObject):
         TrackerNode.__init__(self, vrpnClient, device)
         TrackerNode.__init__(self, vrpnClient, device)
         # Create a unique name for this tracker object
         # Create a unique name for this tracker object
         self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
         self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -213,8 +226,13 @@ class DirectDials(DialNode, DirectObject):
         DialNode.__init__(self, vrpnClient, device)
         DialNode.__init__(self, vrpnClient, device)
         # Create a unique name for this dial object
         # Create a unique name for this dial object
         self.name = 'DirectDials-' + repr(DirectDials.dialCount)
         self.name = 'DirectDials-' + repr(DirectDials.dialCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def __getitem__(self, index):
     def __getitem__(self, index):
         """
         """
@@ -227,10 +245,10 @@ class DirectDials(DialNode, DirectObject):
         return self.getNumDials()
         return self.getNumDials()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -259,14 +277,19 @@ class DirectTimecodeReader(AnalogNode, DirectObject):
         self.seconds = 0
         self.seconds = 0
         self.minutes = 0
         self.minutes = 0
         self.hours = 0
         self.hours = 0
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name

+ 1 - 1
direct/src/directdevices/DirectRadamec.py

@@ -21,7 +21,7 @@ class DirectRadamec(DirectObject):
     radamecCount = 0
     radamecCount = 0
     notify = DirectNotifyGlobal.directNotify.newCategory('DirectRadamec')
     notify = DirectNotifyGlobal.directNotify.newCategory('DirectRadamec')
 
 
-    def __init__(self, device = 'Analog0', nodePath = base.direct.camera):
+    def __init__(self, device = 'Analog0', nodePath = None):
         # See if device manager has been initialized
         # See if device manager has been initialized
         if base.direct.deviceManager == None:
         if base.direct.deviceManager == None:
             base.direct.deviceManager = DirectDeviceManager()
             base.direct.deviceManager = DirectDeviceManager()

+ 5 - 0
direct/src/directdevices/__init__.py

@@ -0,0 +1,5 @@
+"""
+This package contains a high-level interface for VRPN devices.
+
+Also see the :mod:`panda3d.vprn` module.
+"""

+ 3 - 0
direct/src/directnotify/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains notification and logging utilities for Python code.
+"""

+ 8 - 3
direct/src/directscripts/eggcacher.py

@@ -87,8 +87,13 @@ class EggCacher:
             TexturePool.releaseAllTextures()
             TexturePool.releaseAllTextures()
             progress += size
             progress += size
 
 
-cacher = EggCacher(sys.argv[1:])
 
 
-# Dummy main function so this can be added to console_scripts.
-def main():
+def main(args=None):
+    if args is None:
+        args = sys.argv[1:]
+
+    cacher = EggCacher(args)
     return 0
     return 0
+
+if __name__ == '__main__':
+    sys.exit(main())

+ 0 - 831
direct/src/directscripts/packpanda.nsi

@@ -1,831 +0,0 @@
-; Panda3D installation script for the Nullsoft Installation System (NSIS).
-; Jon Parise <[email protected]>
-; with Ben Johnson <[email protected]>
-; with Jason Pratt <[email protected]>
-; mangled by Josh Yelon <[email protected]>
-
-; Caller needs to define these variables:
-;
-;   COMPRESSOR    - either zlib or lzma
-;   NAME          - name of what we're building                 (ie, "Panda3D" or "Airblade")
-;   SMDIRECTORY   - where to put this in the start menu         (ie, "Panda3D 1.1.0" or "Airblade 1.1.0")
-;   INSTALLDIR    - where to install the program                (ie, "C:\Program Files\Panda3D-1.1.0")
-;   OUTFILE       - where to put the output file                (ie, "..\nsis-output.exe")
-;   LICENSE       - location of the license file                (ie, "C:\Airblade\LICENSE.TXT")
-;   LANGUAGE      - name of the Language file to use            (ie, "English" or "Panda3DEnglish")
-;   RUNTEXT       - text for run-box at end of installation     (ie, "Run the Panda Greeting Card")
-;   IBITMAP       - name of installer bitmap                    (ie, "C:\Airblade\Airblade.bmp")
-;   UBITMAP       - name of uninstaller bitmap                  (ie, "C:\Airblade\Airblade.bmp")
-;
-;   PANDA         - location of panda install tree.
-;   PYVER         - version of Python that Panda was built with (ie, "2.7")
-;   PANDACONF     - name of panda config directory - usually $PANDA\etc 
-;   PSOURCE       - location of the panda source-tree if available, OR location of panda install tree.
-;   PYEXTRAS      - directory containing python extras, if any.
-;   REGVIEW       - either 32 or 64, depending on the build architecture.
-;
-;   PPGAME      - directory containing prepagaged game, if any        (ie, "C:\My Games\Airblade")
-;   PPMAIN      - python program containing prepackaged game, if any  (ie, "Airblade.py")
-;   PPICON      - file containing icon of prepackaged game.
-;
-
-!include "MUI.nsh"
-!include "WinMessages.nsh"
-Name "${NAME}"
-InstallDir "${INSTALLDIR}"
-OutFile "${OUTFILE}"
-
-SetCompress auto
-SetCompressor ${COMPRESSOR}
-
-!define MUI_WELCOMEFINISHPAGE_BITMAP "${IBITMAP}"
-!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${UBITMAP}"
-
-!define MUI_ABORTWARNING
-!define MUI_FINISHPAGE_NOREBOOTSUPPORT
-!define MUI_FINISHPAGE_RUN
-!define MUI_FINISHPAGE_RUN_FUNCTION runFunction
-!define MUI_FINISHPAGE_RUN_TEXT "${RUNTEXT}"
-
-!insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_LICENSE "${LICENSE}"
-!insertmacro MUI_PAGE_DIRECTORY
-!insertmacro MUI_PAGE_INSTFILES
-!insertmacro MUI_PAGE_FINISH
-
-!insertmacro MUI_UNPAGE_WELCOME
-!insertmacro MUI_UNPAGE_CONFIRM
-!insertmacro MUI_UNPAGE_INSTFILES
-!insertmacro MUI_UNPAGE_FINISH
-
-!insertmacro MUI_LANGUAGE "${LANGUAGE}"
-
-ShowInstDetails nevershow
-ShowUninstDetails nevershow
-
-LicenseData "${LICENSE}"
-
-InstType "Typical"
-
-!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
-
-var READABLE
-var MANPAGE
-var TUTNAME
-
-Function runFunction
-        !ifdef PPGAME
-        ExecShell "open" "$SMPROGRAMS\${SMDIRECTORY}\Play ${NAME}.lnk"
-        !else
-        ExecShell "open" "$SMPROGRAMS\${SMDIRECTORY}\Panda Manual.lnk"
-        !endif
-FunctionEnd
-
-Section "${SMDIRECTORY}" SecCore
-        SectionIn 1 2 3 RO
-
-        SetDetailsPrint none
-        SetOutPath $INSTDIR
-        SetOverwrite try
-
-        SetOutPath $INSTDIR
-        File "${PANDA}\LICENSE"
-        SetOutPath $INSTDIR\bin
-        File /r "${PANDA}\bin\*.dll"
-        File /nonfatal /r "${PANDA}\bin\*.pyd"
-        File /nonfatal /r "${PANDA}\bin\Microsoft.*.manifest"
-        SetOutPath $INSTDIR\etc
-        File /r "${PANDACONF}\*"
-        SetOutPath $INSTDIR\direct\directscripts
-        File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\directscripts\*"
-        SetOutPath $INSTDIR\direct\filter
-        File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\filter\*.sha"
-        SetOutPath $INSTDIR\direct
-        File /r /x CVS /x Opt?-Win32 "${PANDA}\direct\*.py"
-        Delete "$INSTDIR\panda3d.py"
-        Delete "$INSTDIR\panda3d.pyc"
-        Delete "$INSTDIR\panda3d.pyo"
-        SetOutPath $INSTDIR\pandac
-        File /r "${PANDA}\pandac\*.py"
-        SetOutPath $INSTDIR\panda3d
-        File /r "${PANDA}\panda3d\*.py"
-        File /r "${PANDA}\panda3d\*.pyd"
-        SetOutPath $INSTDIR\python
-        File /r "${PANDA}\python\*"
-        RMDir /r "$SMPROGRAMS\${SMDIRECTORY}"
-        CreateDirectory "$SMPROGRAMS\${SMDIRECTORY}"
-
-        !ifdef PPGAME
-
-            SetOutPath $INSTDIR\models
-            File /r /x CVS "${PANDA}\models\*"
-            SetOutPath $INSTDIR\bin
-            File /r "${PANDA}\bin\eggcacher.exe"
-            SetOutpath $INSTDIR\game
-            File /r "${PPGAME}\*"
-            CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Play ${NAME}.lnk" "$INSTDIR\python\ppython.exe" "-E ${PPMAIN}" "$INSTDIR\${PPICON}" 0 SW_SHOWMINIMIZED "" "Play ${NAME}"
-            # Preload all EGG files into the model-cache
-            SetOutPath $INSTDIR
-            SetDetailsPrint textonly
-            SetDetailsView show
-            nsExec::ExecToLog '"$INSTDIR\bin\eggcacher.exe" --concise game'
-            SetDetailsPrint none
-            SetDetailsView hide
-
-        !else
-
-            SetOutPath $INSTDIR\plugins
-            File /nonfatal /r "${PANDA}\plugins\*.dle"
-            File /nonfatal /r "${PANDA}\plugins\*.dlo"
-            File /nonfatal /r "${PANDA}\plugins\*.mll"
-            File /nonfatal /r "${PANDA}\plugins\*.mel"
-            File /nonfatal /r "${PANDA}\plugins\*.ms"
-            File "${PSOURCE}\doc\INSTALLING-PLUGINS.TXT"
-            SetOutPath $INSTDIR\pandac\input
-            File /r "${PANDA}\pandac\input\*"
-            SetOutPath $INSTDIR\bin
-            File /r "${PANDA}\bin\*.exe"
-            File /nonfatal /r "${PANDA}\bin\*.p3d"
-            SetOutPath $INSTDIR\lib
-            File /r /x *.exp "${PANDA}\lib\*"
-            SetOutPath $INSTDIR\include
-            File /r /x *.exp "${PANDA}\include\*"
-            SetOutPath $INSTDIR\Pmw
-            File /r /x CVS "${PANDA}\Pmw\*"
-            SetOutPath $INSTDIR\NSIS
-            File /r /x CVS "${NSISDIR}\*"
-            SetOutPath $INSTDIR
-            File /r /x CVS "${PANDA}\ReleaseNotes"
-            !ifdef PYEXTRAS
-            SetOutPath $INSTDIR\python\lib
-            File /nonfatal /r "${PYEXTRAS}\*"
-            !endif
-            SetOutPath $INSTDIR\models
-            File /r /x CVS "${PANDA}\models\*"
-            SetOutPath $INSTDIR\samples
-            File /nonfatal /r /x CVS "${PSOURCE}\samples\*"
-            MessageBox MB_YESNO|MB_ICONQUESTION \
-               "EGG caching is about to begin.$\nThis process may take a couple minute and approximately 270 MB of RAM.$\nWARNING : It might stuck if your computer resources are low.$\n$\nDo you really want to do this optional step ?" \
-               IDNO SkipCaching
-            # Preload all EGG files into the model-cache
-            SetOutPath $INSTDIR
-            SetDetailsPrint both
-            SetDetailsView show
-            nsExec::ExecToLog '"$INSTDIR\bin\eggcacher.exe" --concise models samples'
-            SetDetailsPrint none
-            SetDetailsView hide
-            SkipCaching:
-
-            SetOutPath $INSTDIR
-            WriteINIStr $INSTDIR\Website.url "InternetShortcut" "URL" "http://panda3d.org/"
-            WriteINIStr $INSTDIR\Manual.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php"
-            WriteINIStr $INSTDIR\Samples.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php/Sample_Programs_in_the_Distribution"
-            SetOutPath $INSTDIR
-            CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Panda Manual.lnk" "$INSTDIR\Manual.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda Manual"
-            CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Panda Website.lnk" "$INSTDIR\Website.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda Website"
-            CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Program Manual.lnk" "$INSTDIR\Samples.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Sample Program Manual"
-
-            FindFirst $0 $1 $INSTDIR\samples\*
-            loop:
-                StrCmp $1 "" done
-                StrCmp $1 "." next
-                StrCmp $1 ".." next
-    Push $1
-          Push "-"
-                Push " "
-                Call StrRep
-                Pop $R0
-                StrCpy $READABLE $R0
-    Push $1
-          Push "-"
-                Push "_"
-                Call StrRep
-                Pop $R0
-                StrCpy $MANPAGE $R0
-                CreateDirectory "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE"
-                SetOutPath $INSTDIR\samples\$1
-                WriteINIStr $INSTDIR\samples\$1\ManualPage.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php/Sample_Programs:_$MANPAGE"
-                CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\Manual Page.lnk" "$INSTDIR\samples\$1\ManualPage.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Manual Entry on this Sample Program"
-                CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\View Source Code.lnk" "$INSTDIR\samples\$1"
-                FindFirst $2 $3 $INSTDIR\samples\$1\Tut-*.py
-                iloop:
-                    StrCmp $3 "" idone
-                    StrCpy $TUTNAME $3 -3 4
-                    Push $TUTNAME
-                    Push "-"
-                    Push " "
-                    Call StrRep
-                    Pop $R0
-                    StrCpy $TUTNAME $R0
-                    CreateShortCut "$SMPROGRAMS\${SMDIRECTORY}\Sample Programs\$READABLE\Run $TUTNAME.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $TUTNAME"
-                    CreateShortCut "$INSTDIR\samples\$1\Run $TUTNAME.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $TUTNAME"
-                    FindNext $2 $3
-                    goto iloop
-                idone:
-            next:
-                FindNext $0 $1
-                Goto loop
-            done:
-
-        !endif
-
-SectionEnd
-
-
-Section -post
-
-        !ifdef REGVIEW
-        SetRegView ${REGVIEW}
-        !endif
-
-        !ifndef PPGAME
-
-        # Add the "bin" directory to the PATH.
-        Push "$INSTDIR\python"
-        Call RemoveFromPath
-        Push "$INSTDIR\python\Scripts"
-        Call RemoveFromPath
-        Push "$INSTDIR\bin"
-        Call RemoveFromPath
-        Push "$INSTDIR\python"
-        Call AddToPath
-        Push "$INSTDIR\python\Scripts"
-        Call AddToPath
-        Push "$INSTDIR\bin"
-        Call AddToPath
-
-        ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
-        StrCmp $0 "$INSTDIR\python" RegPath 0
-        StrCmp $0 "" RegPath 0
-
-        MessageBox MB_YESNO|MB_ICONQUESTION \
-                "Your system already has a copy of Python installed. Panda3D installs its own copy of Python ${PYVER}, which will install alongside your existing copy. Would you like to make Panda's copy the default Python? If you choose 'No', you will have to configure your existing copy of Python to use the Panda3D libraries, keeping in mind that this version of Panda3D can only run with Python ${PYVER}." \
-                IDNO SkipRegPath
-
-        RegPath:
-        DetailPrint "Adding registry keys for python..."
-        WriteRegStr HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" "" "$INSTDIR\python"
-        SkipRegPath:
-        !endif
-
-        DetailPrint "Adding the uninstaller ..."
-        Delete "$INSTDIR\uninst.exe"
-        WriteUninstaller "$INSTDIR\uninst.exe"
-        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}" "DisplayName" "${SMDIRECTORY}"
-        WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}" "UninstallString" '"$INSTDIR\uninst.exe"'
-        SetOutPath $INSTDIR
-        CreateShortcut "$SMPROGRAMS\${SMDIRECTORY}\Uninstall ${NAME}.lnk" "$INSTDIR\uninst.exe" ""
-
-SectionEnd
-
-Section Uninstall
-
-        !ifdef REGVIEW
-        SetRegView ${REGVIEW}
-        !endif
-
-        !ifndef PPGAME
-        Push "$INSTDIR\python"
-        Call un.RemoveFromPath
-        Push "$INSTDIR\python\Scripts"
-        Call un.RemoveFromPath
-        Push "$INSTDIR\bin"
-        Call un.RemoveFromPath
-
-        ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
-        StrCmp $0 "$INSTDIR\python" 0 SkipUnReg
-        DeleteRegKey HKLM "Software\Python\PythonCore\${PYVER}"
-        SkipUnReg:
-        !endif
-
-        Delete "$INSTDIR\uninst.exe"
-        RMDir /r "$SMPROGRAMS\${SMDIRECTORY}"
-        RMDir /r "$INSTDIR"
-        DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${SMDIRECTORY}"
-
-SectionEnd
-
-# --[ Utility Functions ]------------------------------------------------------
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function IsNT
-        Push $0
-        ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
-        StrCmp $0 "" 0 IsNT_yes
-        ; we are not NT.
-        Pop $0
-        Push 0
-        Return
-        IsNT_yes:
-                ; NT!!!
-                Pop $0
-                Push 1
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function un.IsNT
-        Push $0
-        ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
-        StrCmp $0 "" 0 unIsNT_yes
-        ; we are not NT.
-        Pop $0
-        Push 0
-        Return
-        unIsNT_yes:
-                ; NT!!!
-                Pop $0
-                Push 1
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function StrStr
-        Push $0
-        Exch
-        Pop $0 ; $0 now have the string to find
-        Push $1
-        Exch 2
-        Pop $1 ; $1 now have the string to find in
-        Exch
-        Push $2
-        Push $3
-        Push $4
-        Push $5
-        StrCpy $2 -1
-        StrLen $3 $0
-        StrLen $4 $1
-        IntOp $4 $4 - $3
-        unStrStr_loop:
-                IntOp $2 $2 + 1
-                IntCmp $2 $4 0 0 unStrStrReturn_notFound
-                StrCpy $5 $1 $3 $2
-                StrCmp $5 $0 unStrStr_done unStrStr_loop
-        unStrStrReturn_notFound:
-                StrCpy $2 -1
-        unStrStr_done:
-                Pop $5
-                Pop $4
-                Pop $3
-                Exch $2
-                Exch 2
-                Pop $0
-                Pop $1
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function un.StrStr
-        Push $0
-        Exch
-        Pop $0 ; $0 now have the string to find
-        Push $1
-        Exch 2
-        Pop $1 ; $1 now have the string to find in
-        Exch
-        Push $2
-        Push $3
-        Push $4
-        Push $5
-        StrCpy $2 -1
-        StrLen $3 $0
-        StrLen $4 $1
-        IntOp $4 $4 - $3
-        unStrStr_loop:
-                IntOp $2 $2 + 1
-                IntCmp $2 $4 0 0 unStrStrReturn_notFound
-                StrCpy $5 $1 $3 $2
-                StrCmp $5 $0 unStrStr_done unStrStr_loop
-        unStrStrReturn_notFound:
-                StrCpy $2 -1
-        unStrStr_done:
-                Pop $5
-                Pop $4
-                Pop $3
-                Exch $2
-                Exch 2
-                Pop $0
-                Pop $1
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-; Commentary and smarter ';' checking by Jon Parise <[email protected]>
-Function AddToPath
-        Exch $0
-        Push $1
-        Push $2
-        Push $3
-        Call IsNT
-        Pop $1
-
-        StrCmp $1 1 AddToPath_NT
-                ; We're not on NT, so modify the AUTOEXEC.BAT file.
-                StrCpy $1 $WINDIR 2
-                FileOpen $1 "$1\autoexec.bat" a
-                FileSeek $1 0 END
-                GetFullPathName /SHORT $0 $0
-                FileWrite $1 "$\r$\nSET PATH=%PATH%;$0$\r$\n"
-                FileClose $1
-                Goto AddToPath_done
-        
-        AddToPath_NT:
-                ReadRegStr $1 HKCU "Environment" "PATH"
-                Call IsUserAdmin
-                Pop $3
-                ; If this is an Admin user, use the System env. variable instead of the user's env. variable
-                StrCmp $3 1 0 +2
-                        ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
-
-                ; If the PATH string is empty, jump over the mangling routines.
-                StrCmp $1 "" AddToPath_NTdoIt
-
-                ; Pull off the last character of the PATH string.  If it's a semicolon,
-                ; we don't need to add another one, so jump to the section where we
-                ; append the new PATH component(s).
-                StrCpy $2 $1 1 -1
-                StrCmp $2 ";" AddToPath_NTAddPath AddToPath_NTAddSemi
-
-                AddToPath_NTAddSemi:
-                        StrCpy $1 "$1;"
-                        Goto AddToPath_NTAddPath
-                AddToPath_NTAddPath:
-                        StrCpy $0 "$1$0"
-                        Goto AddToPath_NTdoIt
-                AddToPath_NTdoIt:
-                        Call IsUserAdmin
-                        Pop $3
-                        StrCmp $3 1 0 NotAdmin
-                                WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0
-                                Goto AddToPath_done
-                        
-                        NotAdmin:
-                                WriteRegExpandStr HKCU "Environment" "PATH" $0
-        AddToPath_done:
-                SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-                Pop $3
-                Pop $2
-                Pop $1
-                Pop $0
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function RemoveFromPath
-        Exch $0
-        Push $1
-        Push $2
-        Push $3
-        Push $4
-        Push $5
-        Call IsNT
-        Pop $1
-        StrCmp $1 1 unRemoveFromPath_NT
-                ; Not on NT
-                StrCpy $1 $WINDIR 2
-                FileOpen $1 "$1\autoexec.bat" r
-                GetTempFileName $4
-                FileOpen $2 $4 w
-                GetFullPathName /SHORT $0 $0
-                StrCpy $0 "SET PATH=%PATH%;$0"
-                SetRebootFlag true
-                Goto unRemoveFromPath_dosLoop
-
-                unRemoveFromPath_dosLoop:
-                        FileRead $1 $3
-                        StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
-                        StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
-                        StrCmp $3 "$0" unRemoveFromPath_dosLoop
-                        StrCmp $3 "" unRemoveFromPath_dosLoopEnd
-                        FileWrite $2 $3
-                        Goto unRemoveFromPath_dosLoop
-
-                unRemoveFromPath_dosLoopEnd:
-                        FileClose $2
-                        FileClose $1
-                        StrCpy $1 $WINDIR 2
-                        Delete "$1\autoexec.bat"
-                        CopyFiles /SILENT $4 "$1\autoexec.bat"
-                        Delete $4
-                        Goto unRemoveFromPath_done
-
-                unRemoveFromPath_NT:
-                        StrLen $2 $0
-                        Call IsUserAdmin
-                        Pop $5
-                        StrCmp $5 1 0 NotAdmin
-                                ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
-                                Push $1
-                                Push $0
-                                Call StrStr ; Find $0 in $1
-                                Pop $0 ; pos of our dir
-                                IntCmp $0 -1 unRemoveFromPath_done
-                                        ; else, it is in path
-                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
-                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
-                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
-                                        StrLen $0 $1
-                                        StrCpy $1 $1 $0 $2
-                                        StrCpy $3 "$3$1"
-                                        WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
-                                        SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-                                        Goto unRemoveFromPath_done
-                        
-                        
-                        NotAdmin:               
-                                ReadRegStr $1 HKCU "Environment" "PATH"
-                                Push $1
-                                Push $0
-                                Call StrStr ; Find $0 in $1
-                                Pop $0 ; pos of our dir
-                                IntCmp $0 -1 unRemoveFromPath_done
-                                        ; else, it is in path
-                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
-                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
-                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
-                                        StrLen $0 $1
-                                        StrCpy $1 $1 $0 $2
-                                        StrCpy $3 "$3$1"
-                                        WriteRegExpandStr HKCU "Environment" "PATH" $3
-                                        SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-
-                unRemoveFromPath_done:
-                        Pop $5
-                        Pop $4
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
-Function un.RemoveFromPath
-        Exch $0
-        Push $1
-        Push $2
-        Push $3
-        Push $4
-        Push $5
-        Call un.IsNT
-        Pop $1
-        StrCmp $1 1 unRemoveFromPath_NT
-                ; Not on NT
-                StrCpy $1 $WINDIR 2
-                FileOpen $1 "$1\autoexec.bat" r
-                GetTempFileName $4
-                FileOpen $2 $4 w
-                GetFullPathName /SHORT $0 $0
-                StrCpy $0 "SET PATH=%PATH%;$0"
-                SetRebootFlag true
-                Goto unRemoveFromPath_dosLoop
-
-                unRemoveFromPath_dosLoop:
-                        FileRead $1 $3
-                        StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
-                        StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
-                        StrCmp $3 "$0" unRemoveFromPath_dosLoop
-                        StrCmp $3 "" unRemoveFromPath_dosLoopEnd
-                        FileWrite $2 $3
-                        Goto unRemoveFromPath_dosLoop
-
-                unRemoveFromPath_dosLoopEnd:
-                        FileClose $2
-                        FileClose $1
-                        StrCpy $1 $WINDIR 2
-                        Delete "$1\autoexec.bat"
-                        CopyFiles /SILENT $4 "$1\autoexec.bat"
-                        Delete $4
-                        Goto unRemoveFromPath_done
-
-                unRemoveFromPath_NT:
-                        StrLen $2 $0
-                        Call un.IsUserAdmin
-                        Pop $5
-                        StrCmp $5 1 0 NotAdmin
-                                ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
-                                Push $1
-                                Push $0
-                                Call un.StrStr ; Find $0 in $1
-                                Pop $0 ; pos of our dir
-                                IntCmp $0 -1 unRemoveFromPath_done
-                                        ; else, it is in path
-                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
-                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
-                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
-                                        StrLen $0 $1
-                                        StrCpy $1 $1 $0 $2
-                                        StrCpy $3 "$3$1"
-                                        WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
-                                        SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-                                        Goto unRemoveFromPath_done
-                        
-                        
-                        NotAdmin:               
-                                ReadRegStr $1 HKCU "Environment" "PATH"
-                                Push $1
-                                Push $0
-                                Call un.StrStr ; Find $0 in $1
-                                Pop $0 ; pos of our dir
-                                IntCmp $0 -1 unRemoveFromPath_done
-                                        ; else, it is in path
-                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
-                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
-                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
-                                        StrLen $0 $1
-                                        StrCpy $1 $1 $0 $2
-                                        StrCpy $3 "$3$1"
-                                        WriteRegExpandStr HKCU "Environment" "PATH" $3
-                                        SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
-
-                unRemoveFromPath_done:
-                        Pop $5
-                        Pop $4
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-FunctionEnd
-
-; From: http://nsis.sourceforge.net/archive/nsisweb.php?page=329&instances=0,11
-; Localized by Ben Johnson ([email protected])
-Function IsUserAdmin
-        Push $0
-        Push $1
-        Push $2
-        Push $3
-        Call IsNT
-        Pop $1
-
-        ClearErrors
-        UserInfo::GetName
-        ;IfErrors Win9x
-        Pop $2
-        UserInfo::GetAccountType
-        Pop $3
-
-        ; Compare results of IsNT with "1"
-        StrCmp $1 1 0 NotNT
-                ;This is NT
-                
-
-                StrCmp $3 "Admin" 0 NotAdmin
-                        ; Observation: I get here when running Win98SE. (Lilla)
-                        ; The functions UserInfo.dll looks for are there on Win98 too, 
-                        ; but just don't work. So UserInfo.dll, knowing that admin isn't required
-                        ; on Win98, returns admin anyway. (per kichik)
-                        ; MessageBox MB_OK 'User "$R1" is in the Administrators group'
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-
-                        Push 1
-                        Return
-
-                NotAdmin:
-                        ; You should still check for an empty string because the functions
-                        ; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
-                
-                        #StrCmp $2 "" Win9x
-                        #StrCpy $0 0
-                        ;MessageBox MB_OK 'User "$2" is in the "$3" group'
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-
-                        Push 0
-                        Return
-
-        ;Because we use IsNT, this is redundant.
-        #Win9x:
-        #       ; comment/message below is by UserInfo.nsi author:
-        #       ; This one means you don't need to care about admin or
-        #       ; not admin because Windows 9x doesn't either
-        #       ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
-        #       StrCpy $0 0
-
-        NotNT:
-                ;We are not NT
-                ;Win9x doesn't have "admin" users.
-                ;Let the user do whatever.
-                Pop $3
-                Pop $2
-                Pop $1
-                Pop $0
-
-                Push 1
-
-FunctionEnd
-
-Function un.IsUserAdmin
-        Push $0
-        Push $1
-        Push $2
-        Push $3
-        Call un.IsNT
-        Pop $1
-
-        ClearErrors
-        UserInfo::GetName
-        ;IfErrors Win9x
-        Pop $2
-        UserInfo::GetAccountType
-        Pop $3
-
-        ; Compare results of IsNT with "1"
-        StrCmp $1 1 0 NotNT
-                ;This is NT
-                
-
-                StrCmp $3 "Admin" 0 NotAdmin
-                        ; Observation: I get here when running Win98SE. (Lilla)
-                        ; The functions UserInfo.dll looks for are there on Win98 too, 
-                        ; but just don't work. So UserInfo.dll, knowing that admin isn't required
-                        ; on Win98, returns admin anyway. (per kichik)
-                        ; MessageBox MB_OK 'User "$R1" is in the Administrators group'
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-
-                        Push 1
-                        Return
-
-                NotAdmin:
-                        ; You should still check for an empty string because the functions
-                        ; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
-                
-                        #StrCmp $2 "" Win9x
-                        #StrCpy $0 0
-                        ;MessageBox MB_OK 'User "$2" is in the "$3" group'
-                        Pop $3
-                        Pop $2
-                        Pop $1
-                        Pop $0
-
-                        Push 0
-                        Return
-
-        ;Because we use IsNT, this is redundant.
-        #Win9x:
-        #       ; comment/message below is by UserInfo.nsi author:
-        #       ; This one means you don't need to care about admin or
-        #       ; not admin because Windows 9x doesn't either
-        #       ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
-        #       StrCpy $0 0
-
-        NotNT:
-                ;We are not NT
-                ;Win9x doesn't have "admin" users.
-                ;Let the user do whatever.
-                Pop $3
-                Pop $2
-                Pop $1
-                Pop $0
-
-                Push 1
-
-FunctionEnd
-
-Function StrRep
-
-  ;Written by dirtydingus 2003-02-20 04:30:09 
-  ; USAGE
-  ;Push String to do replacement in (haystack)
-  ;Push String to replace (needle)
-  ;Push Replacement
-  ;Call StrRep
-  ;Pop $R0 result
-  ;StrCpy $Result STR $R0
-
-  Exch $R4 ; $R4 = Replacement String
-  Exch
-  Exch $R3 ; $R3 = String to replace (needle)
-  Exch 2
-  Exch $R1 ; $R1 = String to do replacement in (haystack)
-  Push $R2 ; Replaced haystack
-  Push $R5 ; Len (needle)
-  Push $R6 ; len (haystack)
-  Push $R7 ; Scratch reg
-  StrCpy $R2 ""
-  StrLen $R5 $R3
-  StrLen $R6 $R1
-loop:
-  StrCpy $R7 $R1 $R5
-  StrCmp $R7 $R3 found
-  StrCpy $R7 $R1 1 ; - optimization can be removed if U know len needle=1
-  StrCpy $R2 "$R2$R7"
-  StrCpy $R1 $R1 $R6 1
-  StrCmp $R1 "" done loop
-found:
-  StrCpy $R2 "$R2$R4"
-  StrCpy $R1 $R1 $R6 $R5
-  StrCmp $R1 "" done loop
-done:
-  StrCpy $R3 $R2
-  Pop $R7
-  Pop $R6
-  Pop $R5
-  Pop $R2
-  Pop $R1
-  Pop $R4
-  Exch $R3
-  
-FunctionEnd
-

+ 0 - 424
direct/src/directscripts/packpanda.py

@@ -1,424 +0,0 @@
-#############################################################################
-#
-# packpanda - this is a tool that packages up a panda game into a
-# convenient, easily-downloaded windows executable.  Packpanda runs on linux
-# and windows - on linux, it builds .debs and .rpms, on windows it relies on
-# NSIS, the nullsoft scriptable install system, to do the hard work.
-#
-# This is intentionally a very simplistic game-packer with very
-# limited options.  The goal is simplicity, not feature richness.
-# There are dozens of complex, powerful packaging tools already out
-# there.  This one is for people who just want to do it quick and
-# easy.
-#
-##############################################################################
-
-import sys, os, getopt, shutil, py_compile, subprocess
-
-OPTIONLIST = [
-("dir",       1, "Name of directory containing game"),
-("name",      1, "Human-readable name of the game"),
-("version",   1, "Version number to add to game name"),
-("rmdir",     2, "Delete all directories with given name"),
-("rmext",     2, "Delete all files with given extension"),
-("fast",      0, "Use fast compression instead of good compression"),
-("bam",       0, "Generate BAM files, change default-model-extension to BAM"),
-("pyc",       0, "Generate PYC files"),
-]
-
-def ParseFailure():
-  print("")
-  print("packpanda usage:")
-  print("")
-  for (opt, hasval, explanation) in OPTIONLIST:
-    if (hasval):
-      print("  --%-10s    %s"%(opt+" x", explanation))
-    else:
-      print("  --%-10s    %s"%(opt+"  ", explanation))
-  sys.exit(1)
-
-def ParseOptions(args):
-  try:
-    options = {}
-    longopts = []
-    for (opt, hasval, explanation) in OPTIONLIST:
-      if (hasval==2):
-        longopts.append(opt+"=")
-        options[opt] = []
-      elif (hasval==1):
-        longopts.append(opt+"=")
-        options[opt] = ""
-      else:
-        longopts.append(opt)
-        options[opt] = 0
-    opts, extras = getopt.getopt(args, "", longopts)
-    for option, value in opts:
-      for (opt, hasval, explanation) in OPTIONLIST:
-        if (option == "--"+opt):
-          if (hasval==2): options[opt].append(value)
-          elif (hasval==1): options[opt] = value
-          else: options[opt] = 1
-    return options
-  except: ParseFailure();
-
-OPTIONS = ParseOptions(sys.argv[1:])
-
-##############################################################################
-#
-# Locate the relevant trees.
-#
-##############################################################################
-
-PANDA=None
-for dir in sys.path:
-    if (dir != "") and os.path.exists(os.path.join(dir,"direct")) and os.path.exists(os.path.join(dir,"pandac")):
-        PANDA=os.path.abspath(dir)
-if (PANDA is None):
-  sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).")
-print("PANDA located at "+PANDA)
-
-if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))):
-  PSOURCE=os.path.abspath(os.path.join(PANDA,".."))
-  if (sys.platform == "win32"):
-    NSIS=os.path.abspath(os.path.join(PANDA,"..","thirdparty","win-nsis"))
-else:
-  PSOURCE=PANDA
-  if (sys.platform == "win32"):
-    NSIS=os.path.join(PANDA,"nsis")
-
-##############################################################################
-#
-# Identify the main parts of the game: DIR, NAME, MAIN, ICON, BITMAP, etc
-#
-##############################################################################
-
-VER=OPTIONS["version"]
-DIR=OPTIONS["dir"]
-if (DIR==""):
-  print("You must specify the --dir option.")
-  ParseFailure()
-DIR=os.path.abspath(DIR)
-MYDIR=os.path.abspath(os.getcwd())
-BASENAME=os.path.basename(DIR)
-if (OPTIONS["name"] != ""):
-  NAME=OPTIONS["name"]
-else:
-  NAME=BASENAME
-SMDIRECTORY=NAME
-if (VER!=""): SMDIRECTORY=SMDIRECTORY+" "+VER
-PYTHONV="python"+sys.version[:3]
-LICENSE=os.path.join(DIR, "license.txt")
-OUTFILE=os.path.basename(DIR)
-if (VER!=""): OUTFILE=OUTFILE+"-"+VER
-if (sys.platform == "win32"):
-  ICON=os.path.join(DIR, "icon.ico")
-  BITMAP=os.path.join(DIR, "installer.bmp")
-  OUTFILE=os.path.abspath(OUTFILE+".exe")
-  INSTALLDIR='C:\\'+os.path.basename(DIR)
-  if (VER!=""): INSTALLDIR=INSTALLDIR+"-"+VER
-  COMPRESS="lzma"
-  if (OPTIONS["fast"]): COMPRESS="zlib"
-if (OPTIONS["pyc"]): MAIN="main.pyc"
-else: MAIN="main.py"
-
-def PrintFileStatus(label, file):
-  if (os.path.exists(file)):
-    print("%-15s: %s"%(label, file))
-  else:
-    print("%-15s: %s (MISSING)"%(label, file))
-
-PrintFileStatus("Dir", DIR)
-print("%-15s: %s"%("Name", NAME))
-print("%-15s: %s"%("Start Menu", SMDIRECTORY))
-PrintFileStatus("Main", os.path.join(DIR, MAIN))
-if (sys.platform == "win32"):
-  PrintFileStatus("Icon", ICON)
-  PrintFileStatus("Bitmap", BITMAP)
-PrintFileStatus("License", LICENSE)
-print("%-15s: %s"%("Output", OUTFILE))
-if (sys.platform == "win32"):
-  print("%-15s: %s"%("Install Dir", INSTALLDIR))
-
-if (os.path.isdir(DIR)==0):
-  sys.exit("Difficulty reading "+DIR+". Cannot continue.")
-
-if (os.path.isfile(os.path.join(DIR, "main.py"))==0):
-  sys.exit("Difficulty reading main.py. Cannot continue.")
-
-if (os.path.isfile(LICENSE)==0):
-  LICENSE=os.path.join(PANDA,"LICENSE")
-
-if (sys.platform == "win32") and (os.path.isfile(BITMAP)==0):
-  BITMAP=os.path.join(NSIS,"Contrib","Graphics","Wizard","nsis.bmp")
-
-if (sys.platform == "win32"):
-  if (os.path.isfile(ICON)==0):
-    PPICON="bin\\ppython.exe"
-  else:
-    PPICON="game\\icon.ico"
-
-##############################################################################
-#
-# Copy the game to a temporary directory, so we can modify it safely.
-#
-##############################################################################
-
-def limitedCopyTree(src, dst, rmdir):
-    if (os.path.isdir(src)):
-        if (os.path.basename(src) in rmdir):
-            return
-        if (not os.path.isdir(dst)): os.mkdir(dst)
-        for x in os.listdir(src):
-            limitedCopyTree(os.path.join(src,x), os.path.join(dst,x), rmdir)
-    else:
-        shutil.copyfile(src, dst)
-
-
-TMPDIR=os.path.abspath("packpanda-TMP")
-if (sys.platform == "win32"):
-  TMPGAME=os.path.join(TMPDIR,"game")
-  TMPETC=os.path.join(TMPDIR,"etc")
-else:
-  TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game")
-  TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc")
-print("")
-print("Copying the game to "+TMPDIR+"...")
-if (os.path.exists(TMPDIR)):
-    try: shutil.rmtree(TMPDIR)
-    except: sys.exit("Cannot delete "+TMPDIR)
-try:
-    os.mkdir(TMPDIR)
-    rmdir = {}
-    for x in OPTIONS["rmdir"]:
-        rmdir[x] = 1
-    if not os.path.isdir( TMPGAME ):
-        os.makedirs(TMPGAME)
-    limitedCopyTree(DIR, TMPGAME, rmdir)
-    if not os.path.isdir( TMPETC ):
-        os.makedirs(TMPETC)
-    if sys.platform == "win32":
-      limitedCopyTree(os.path.join(PANDA, "etc"), TMPETC, {})
-    else:
-      shutil.copyfile("/etc/Config.prc", os.path.join(TMPETC, "Config.prc"))
-      shutil.copyfile("/etc/Confauto.prc", os.path.join(TMPETC, "Confauto.prc"))
-except: sys.exit("Cannot copy game to "+TMPDIR)
-
-##############################################################################
-#
-# If --bam requested, change default-model-extension .egg to bam.
-#
-##############################################################################
-
-def ReadFile(wfile):
-    try:
-        srchandle = open(wfile, "rb")
-        data = srchandle.read()
-        srchandle.close()
-        return data
-    except: exit("Cannot read "+wfile)
-
-def WriteFile(wfile,data):
-    try:
-        dsthandle = open(wfile, "wb")
-        dsthandle.write(data)
-        dsthandle.close()
-    except: exit("Cannot write "+wfile)
-
-if OPTIONS["bam"]:
-    CONF=ReadFile(os.path.join(TMPETC,"Confauto.prc"))
-    CONF=CONF.replace("default-model-extension .egg","default-model-extension .bam")
-    WriteFile(os.path.join(TMPETC,"Confauto.prc"), CONF)
-
-##############################################################################
-#
-# Compile all py files, convert all egg files.
-#
-# We do this as a sanity check, even if the user
-# hasn't requested that his files be compiled.
-#
-##############################################################################
-
-if (sys.platform == "win32"):
-  EGG2BAM=os.path.join(PANDA,"bin","egg2bam.exe")
-else:
-  EGG2BAM=os.path.join(PANDA,"bin","egg2bam")
-
-def egg2bam(file,bam):
-    present = os.path.exists(bam)
-    if (present): bam = "packpanda-TMP.bam";
-    cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"'
-    print("Executing: "+cmd)
-    if (sys.platform == "win32"):
-      res = os.spawnl(os.P_WAIT, EGG2BAM, cmd)
-    else:
-      res = os.system(cmd)
-    if (res != 0): sys.exit("Problem in egg file: "+file)
-    if (present) or (OPTIONS["bam"]==0):
-        os.unlink(bam)
-
-def py2pyc(file):
-    print("Compiling python "+file)
-    pyc = file[:-3]+'.pyc'
-    pyo = file[:-3]+'.pyo'
-    if (os.path.exists(pyc)): os.unlink(pyc)
-    if (os.path.exists(pyo)): os.unlink(pyo)
-    try: py_compile.compile(file)
-    except: sys.exit("Cannot compile "+file)
-    if (OPTIONS["pyc"]==0):
-        if (os.path.exists(pyc)):
-            os.unlink(pyc)
-        if (os.path.exists(pyo)):
-            os.unlink(pyo)
-
-def CompileFiles(file):
-    if (os.path.isfile(file)):
-        if (file.endswith(".egg")):
-            egg2bam(file, file[:-4]+'.bam')
-        elif (file.endswith(".egg.pz") or file.endswith(".egg.gz")):
-            egg2bam(file, file[:-7]+'.bam')
-        elif (file.endswith(".py")):
-            py2pyc(file)
-        else: pass
-    elif (os.path.isdir(file)):
-        for x in os.listdir(file):
-            CompileFiles(os.path.join(file, x))
-
-def DeleteFiles(file):
-    base = os.path.basename(file).lower()
-    if (os.path.isdir(file)):
-        for pattern in OPTIONS["rmdir"]:
-            if pattern.lower() == base:
-                print("Deleting "+file)
-                shutil.rmtree(file)
-                return
-        for x in os.listdir(file):
-            DeleteFiles(os.path.join(file, x))
-    else:
-        for ext in OPTIONS["rmext"]:
-            if base[-(len(ext) + 1):] == ("." + ext).lower():
-                print("Deleting "+file)
-                os.unlink(file)
-                return
-
-print("")
-print("Compiling BAM and PYC files...")
-os.chdir(TMPGAME)
-CompileFiles(".")
-DeleteFiles(".")
-
-##############################################################################
-#
-# Now make the installer. Yay!
-#
-##############################################################################
-
-INSTALLER_DEB_FILE="""
-Package: BASENAME
-Version: VERSION
-Section: games
-Priority: optional
-Architecture: ARCH
-Essential: no
-Depends: PYTHONV
-Provides: BASENAME
-Description: NAME
-Maintainer: Unknown
-"""
-
-INSTALLER_SPEC_FILE="""
-Summary: NAME
-Name: BASENAME
-Version: VERSION
-Release: 1
-Group: Amusement/Games
-License: See license file
-BuildRoot: TMPDIR
-BuildRequires: PYTHONV
-%description
-NAME
-%files
-%defattr(-,root,root)
-/usr/bin/BASENAME
-/usr/lib/games/BASENAME
-/usr/share/games/BASENAME
-"""
-
-RUN_SCRIPT="""
-#!/bin/sh
-cd /usr/share/games/BASENAME/game
-PYTHONPATH=/usr/lib/games/BASENAME:/usr/share/games/BASENAME
-LD_LIBRARY_PATH=/usr/lib/games/BASENAME
-PYTHONV MAIN
-"""
-
-if (sys.platform == "win32"):
-    CMD="\""+NSIS+"\\makensis.exe\" /V2 "
-    CMD=CMD+'/DCOMPRESSOR="'+COMPRESS+'" '
-    CMD=CMD+'/DNAME="'+NAME+'" '
-    CMD=CMD+'/DSMDIRECTORY="'+SMDIRECTORY+'" '
-    CMD=CMD+'/DINSTALLDIR="'+INSTALLDIR+'" '
-    CMD=CMD+'/DOUTFILE="'+OUTFILE+'" '
-    CMD=CMD+'/DLICENSE="'+LICENSE+'" '
-    CMD=CMD+'/DLANGUAGE="English" '
-    CMD=CMD+'/DRUNTEXT="Play '+NAME+'" '
-    CMD=CMD+'/DIBITMAP="'+BITMAP+'" '
-    CMD=CMD+'/DUBITMAP="'+BITMAP+'" '
-    CMD=CMD+'/DPANDA="'+PANDA+'" '
-    CMD=CMD+'/DPANDACONF="'+TMPETC+'" '
-    CMD=CMD+'/DPSOURCE="'+PSOURCE+'" '
-    CMD=CMD+'/DPPGAME="'+TMPGAME+'" '
-    CMD=CMD+'/DPPMAIN="'+MAIN+'" '
-    CMD=CMD+'/DPPICON="'+PPICON+'" '
-    CMD=CMD+'"'+PSOURCE+'\\direct\\directscripts\\packpanda.nsi"'
-
-    print("")
-    print(CMD)
-    print("packing...")
-    subprocess.call(CMD)
-else:
-    os.chdir(MYDIR)
-    os.system("mkdir -p %s/usr/bin" % TMPDIR)
-    os.system("mkdir -p %s/usr/share/games/%s" % (TMPDIR, BASENAME))
-    os.system("mkdir -p %s/usr/lib/games/%s" % (TMPDIR, BASENAME))
-    os.system("cp --recursive %s/direct          %s/usr/share/games/%s/direct" % (PANDA, TMPDIR, BASENAME))
-    os.system("cp --recursive %s/pandac          %s/usr/share/games/%s/pandac" % (PANDA, TMPDIR, BASENAME))
-    os.system("cp --recursive %s/models          %s/usr/share/games/%s/models" % (PANDA, TMPDIR, BASENAME))
-    os.system("cp --recursive %s/Pmw             %s/usr/share/games/%s/Pmw" % (PANDA, TMPDIR, BASENAME))
-    os.system("cp %s                             %s/usr/share/games/%s/LICENSE" % (LICENSE, TMPDIR, BASENAME))
-    os.system("cp --recursive /usr/lib/panda3d/* %s/usr/lib/games/%s/" % (TMPDIR, BASENAME))
-
-    # Make the script to run the game
-    txt = RUN_SCRIPT[1:].replace("BASENAME",BASENAME).replace("PYTHONV",PYTHONV).replace("MAIN",MAIN)
-    WriteFile(TMPDIR+"/usr/bin/"+BASENAME, txt)
-    os.system("chmod +x "+TMPDIR+"/usr/bin/"+BASENAME)
-
-    if (os.path.exists("/usr/bin/rpmbuild")):
-        os.system("rm -rf %s/DEBIAN" % TMPDIR)
-        os.system("rpm -E '%_target_cpu' > packpanda-TMP.txt")
-        ARCH=ReadFile("packpanda-TMP.txt").strip()
-        os.remove("packpanda-TMP.txt")
-        txt = INSTALLER_SPEC_FILE[1:].replace("VERSION",VER).replace("TMPDIR",TMPDIR)
-        txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("PYTHONV",PYTHONV)
-        WriteFile("packpanda-TMP.spec", txt)
-        os.system("rpmbuild --define '_rpmdir "+TMPDIR+"' -bb packpanda-TMP.spec")
-        os.system("mv "+ARCH+"/"+BASENAME+"-"+VER+"-1."+ARCH+".rpm .")
-        os.rmdir(ARCH)
-        os.remove("packpanda-TMP.spec")
-
-    if (os.path.exists("/usr/bin/dpkg-deb")):
-        os.system("dpkg --print-architecture > packpanda-TMP.txt")
-        ARCH=ReadFile("packpanda-TMP.txt").strip()
-        os.remove("packpanda-TMP.txt")
-        txt = INSTALLER_DEB_FILE[1:].replace("VERSION",str(VER)).replace("PYTHONV",PYTHONV)
-        txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("ARCH",ARCH)
-        os.system("mkdir -p %s/DEBIAN" % TMPDIR)
-        os.system("cd %s ; (find usr -type f -exec md5sum {} \;) >  DEBIAN/md5sums" % TMPDIR)
-        WriteFile(TMPDIR+"/DEBIAN/control",txt)
-        os.system("dpkg-deb -b "+TMPDIR+" "+BASENAME+"_"+VER+"_"+ARCH+".deb")
-
-    if not(os.path.exists("/usr/bin/rpmbuild") or os.path.exists("/usr/bin/dpkg-deb")):
-        exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")
-
-# Dummy main function so this can be added to console_scripts.
-def main():
-    return 0

+ 1 - 1
direct/src/directtools/DirectCameraControl.py

@@ -413,7 +413,7 @@ class DirectCameraControl(DirectObject):
                 np = NodePath('temp')
                 np = NodePath('temp')
                 np.setPos(base.direct.camera, hitPt)
                 np.setPos(base.direct.camera, hitPt)
                 self.coaMarkerPos = np.getPos()
                 self.coaMarkerPos = np.getPos()
-                np.remove()
+                np.removeNode()
                 self.coaMarker.setPos(self.coaMarkerPos)
                 self.coaMarker.setPos(self.coaMarkerPos)
 
 
             iRay.collisionNodePath.removeNode()
             iRay.collisionNodePath.removeNode()

+ 3 - 3
direct/src/directtools/DirectManipulation.py

@@ -186,7 +186,7 @@ class DirectManipulationControl(DirectObject):
 
 
     def drawMarquee(self, startX, startY):
     def drawMarquee(self, startX, startY):
         if self.marquee:
         if self.marquee:
-            self.marquee.remove()
+            self.marquee.removeNode()
             self.marquee = None
             self.marquee = None
 
 
         if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
         if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
@@ -228,7 +228,7 @@ class DirectManipulationControl(DirectObject):
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
 
 
             if self.marquee:
             if self.marquee:
-                self.marquee.remove()
+                self.marquee.removeNode()
                 self.marquee = None
                 self.marquee = None
                 base.direct.deselectAll()
                 base.direct.deselectAll()
 
 
@@ -1691,7 +1691,7 @@ class ObjectHandles(NodePath, DirectObject):
         np.setPos(base.direct.camera, hitPt)
         np.setPos(base.direct.camera, hitPt)
         resultPt = Point3(0)
         resultPt = Point3(0)
         resultPt.assign(np.getPos())
         resultPt.assign(np.getPos())
-        np.remove()
+        np.removeNode()
         del iRay
         del iRay
         return resultPt
         return resultPt
 
 

+ 1 - 1
direct/src/directtools/DirectSession.py

@@ -900,7 +900,7 @@ class DirectSession(DirectObject):
             # If nothing specified, try selected node path
             # If nothing specified, try selected node path
             nodePath = self.selected.last
             nodePath = self.selected.last
         if nodePath:
         if nodePath:
-            nodePath.remove()
+            nodePath.removeNode()
 
 
     def removeAllSelected(self):
     def removeAllSelected(self):
         self.selected.removeAll()
         self.selected.removeAll()

+ 8 - 0
direct/src/directtools/__init__.py

@@ -0,0 +1,8 @@
+"""
+This package contains the DIRECT tools, a set of tkinter tools for exploring
+and manipulating the Panda3D scene graph.  By default, these are disabled,
+but they can be explicitly enabled using the following PRC configuration::
+
+   want-directtools true
+   want-tk true
+"""

+ 3 - 0
direct/src/directutil/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains assorted utility classes.
+"""

+ 4 - 2
direct/src/distributed/DistributedObject.py

@@ -4,7 +4,6 @@ from panda3d.core import *
 from panda3d.direct import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
-from direct.showbase.PythonUtil import StackTrace
 #from PyDatagram import PyDatagram
 #from PyDatagram import PyDatagram
 #from PyDatagramIterator import PyDatagramIterator
 #from PyDatagramIterator import PyDatagramIterator
 
 
@@ -259,7 +258,10 @@ class DistributedObject(DistributedObjectBase):
     def _destroyDO(self):
     def _destroyDO(self):
         # after this is called, the object is no longer a DistributedObject
         # after this is called, the object is no longer a DistributedObject
         # but may still be used as a DelayDeleted object
         # but may still be used as a DelayDeleted object
-        self.destroyDoStackTrace = StackTrace()
+        if __debug__:
+            # StackTrace is omitted in packed versions
+            from direct.showbase.PythonUtil import StackTrace
+            self.destroyDoStackTrace = StackTrace()
         # check for leftover cached data that was not retrieved or flushed by this object
         # check for leftover cached data that was not retrieved or flushed by this object
         # this will catch typos in the data name in calls to get/setCachedData
         # this will catch typos in the data name in calls to get/setCachedData
         if hasattr(self, '_cachedData'):
         if hasattr(self, '_cachedData'):

+ 8 - 6
direct/src/distributed/DistributedSmoothNode.py

@@ -7,19 +7,21 @@ from . import DistributedNode
 from . import DistributedSmoothNodeBase
 from . import DistributedSmoothNodeBase
 from direct.task.Task import cont
 from direct.task.Task import cont
 
 
+config = get_config_showbase()
+
 # This number defines our tolerance for out-of-sync telemetry packets.
 # This number defines our tolerance for out-of-sync telemetry packets.
 # If a packet appears to have originated from more than MaxFuture
 # If a packet appears to have originated from more than MaxFuture
 # seconds in the future, assume we're out of sync with the other
 # seconds in the future, assume we're out of sync with the other
 # avatar and suggest a resync for both.
 # avatar and suggest a resync for both.
-MaxFuture = base.config.GetFloat("smooth-max-future", 0.2)
+MaxFuture = config.GetFloat("smooth-max-future", 0.2)
 
 
 # How frequently can we suggest a resynchronize with another client?
 # How frequently can we suggest a resynchronize with another client?
-MinSuggestResync = base.config.GetFloat("smooth-min-suggest-resync", 15)
+MinSuggestResync = config.GetFloat("smooth-min-suggest-resync", 15)
 
 
 # These flags indicate whether global smoothing and/or prediction is
 # These flags indicate whether global smoothing and/or prediction is
 # allowed or disallowed.
 # allowed or disallowed.
-EnableSmoothing = base.config.GetBool("smooth-enable-smoothing", 1)
-EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
+EnableSmoothing = config.GetBool("smooth-enable-smoothing", 1)
+EnablePrediction = config.GetBool("smooth-enable-prediction", 1)
 
 
 # These values represent the amount of time, in seconds, to delay the
 # These values represent the amount of time, in seconds, to delay the
 # apparent position of other avatars, when non-predictive and
 # apparent position of other avatars, when non-predictive and
@@ -27,8 +29,8 @@ EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
 # addition to the automatic delay of the observed average latency from
 # addition to the automatic delay of the observed average latency from
 # each avatar, which is intended to compensate for relative clock
 # each avatar, which is intended to compensate for relative clock
 # skew.
 # skew.
-Lag = base.config.GetDouble("smooth-lag", 0.2)
-PredictionLag = base.config.GetDouble("smooth-prediction-lag", 0.0)
+Lag = config.GetDouble("smooth-lag", 0.2)
+PredictionLag = config.GetDouble("smooth-prediction-lag", 0.0)
 
 
 
 
 GlobalSmoothing = 0
 GlobalSmoothing = 0

+ 0 - 1
direct/src/distributed/DoCollectionManager.py

@@ -312,7 +312,6 @@ class DoCollectionManager:
         else:
         else:
             self.notify.warning('handleSetLocation: object %s not present' % self.getMsgChannel())
             self.notify.warning('handleSetLocation: object %s not present' % self.getMsgChannel())
 
 
-    @exceptionLogged()
     def storeObjectLocation(self, object, parentId, zoneId):
     def storeObjectLocation(self, object, parentId, zoneId):
         oldParentId = object.parentId
         oldParentId = object.parentId
         oldZoneId = object.zoneId
         oldZoneId = object.zoneId

+ 0 - 7
direct/src/distributed/StagedObject.py

@@ -17,7 +17,6 @@ class StagedObject:
         call any "handle" functions.
         call any "handle" functions.
         """
         """
         self.__state = initState
         self.__state = initState
-        pass
 
 
     def goOnStage(self, *args, **kw):
     def goOnStage(self, *args, **kw):
         """
         """
@@ -29,8 +28,6 @@ class StagedObject:
 
 
         if not self.isOnStage():
         if not self.isOnStage():
             self.handleOnStage(*args, **kw)
             self.handleOnStage(*args, **kw)
-            pass
-        pass
 
 
     def handleOnStage(self):
     def handleOnStage(self):
         """
         """
@@ -39,7 +36,6 @@ class StagedObject:
         Don't forget to call down to this one, though.
         Don't forget to call down to this one, though.
         """
         """
         self.__state = StagedObject.ON
         self.__state = StagedObject.ON
-        pass
 
 
     def goOffStage(self, *args, **kw):
     def goOffStage(self, *args, **kw):
         """
         """
@@ -51,8 +47,6 @@ class StagedObject:
 
 
         if not self.isOffStage():
         if not self.isOffStage():
             self.handleOffStage(*args, **kw)
             self.handleOffStage(*args, **kw)
-            pass
-        pass
 
 
     def handleOffStage(self):
     def handleOffStage(self):
         """
         """
@@ -61,7 +55,6 @@ class StagedObject:
         Don't forget to call down to this one, though.
         Don't forget to call down to this one, though.
         """
         """
         self.__state = StagedObject.OFF
         self.__state = StagedObject.OFF
-        pass
 
 
     def isOnStage(self):
     def isOnStage(self):
         return self.__state == StagedObject.ON
         return self.__state == StagedObject.ON

+ 5 - 0
direct/src/distributed/__init__.py

@@ -0,0 +1,5 @@
+"""
+This package contains an implementation of the Distributed Networking
+API, a high-level networking system that automatically propagates
+changes made on distributed objects to interested clients.
+"""

+ 2 - 2
direct/src/distributed/cConnectionRepository.h

@@ -55,8 +55,8 @@ class SocketStream;
  */
  */
 class EXPCL_DIRECT CConnectionRepository {
 class EXPCL_DIRECT CConnectionRepository {
 PUBLISHED:
 PUBLISHED:
-  CConnectionRepository(bool has_owner_view = false,
-                        bool threaded_net = false);
+  explicit CConnectionRepository(bool has_owner_view = false,
+                                 bool threaded_net = false);
   ~CConnectionRepository();
   ~CConnectionRepository();
 
 
 /*
 /*

+ 4 - 1
direct/src/extensions_native/__init__.py

@@ -1 +1,4 @@
-
+"""
+This package contains various Python methods that extend some of Panda's
+underlying C++ classes.
+"""

+ 21 - 0
direct/src/filter/CommonFilters.py

@@ -536,3 +536,24 @@ class CommonFilters:
             del self.configuration["GammaAdjust"]
             del self.configuration["GammaAdjust"]
             return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
             return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
         return True
         return True
+
+    #snake_case alias:
+    del_cartoon_ink = delCartoonInk
+    set_half_pixel_shift = setHalfPixelShift
+    del_half_pixel_shift = delHalfPixelShift
+    set_inverted = setInverted
+    del_inverted = delInverted
+    del_view_glow = delViewGlow
+    set_volumetric_lighting = setVolumetricLighting
+    del_gamma_adjust = delGammaAdjust
+    set_bloom = setBloom
+    set_view_glow = setViewGlow
+    set_ambient_occlusion = setAmbientOcclusion
+    set_cartoon_ink = setCartoonInk
+    del_bloom = delBloom
+    del_ambient_occlusion = delAmbientOcclusion
+    load_shader = loadShader
+    set_blur_sharpen = setBlurSharpen
+    del_blur_sharpen = delBlurSharpen
+    del_volumetric_lighting = delVolumetricLighting
+    set_gamma_adjust = setGammaAdjust

+ 12 - 0
direct/src/filter/FilterManager.py

@@ -349,3 +349,15 @@ class FilterManager(DirectObject):
         self.nextsort = self.win.getSort() - 1000
         self.nextsort = self.win.getSort() - 1000
         self.basex = 0
         self.basex = 0
         self.basey = 0
         self.basey = 0
+
+    #snake_case alias:
+    is_fullscreen = isFullscreen
+    resize_buffers = resizeBuffers
+    set_stacked_clears = setStackedClears
+    render_scene_into = renderSceneInto
+    get_scaled_size = getScaledSize
+    render_quad_into = renderQuadInto
+    get_clears = getClears
+    set_clears = setClears
+    create_buffer = createBuffer
+    window_event = windowEvent

+ 11 - 0
direct/src/filter/__init__.py

@@ -0,0 +1,11 @@
+"""
+This package contains functionality for applying post-processing
+filters to the result of rendering a 3-D scene.  This is done by
+rendering the scene to an off-screen buffer, and then applying this to
+a full-screen card that has a shader applied which manipulates the
+texture values as desired.
+
+The :class:`.CommonFilters` class contains various filters that are
+provided out of the box, whereas the :class:`.FilterManager` class
+is a lower-level class that allows you to set up your own filters.
+"""

+ 3 - 2
direct/src/filter/filter-bloomx.sha

@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
   l_position=mul(mat_modelproj, vtx_position);
   l_position=mul(mat_modelproj, vtx_position);
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float offset = texpix_src.x;
   float offset = texpix_src.x;
-  l_texcoord0 = float4(c.x-offset* -4, c.x-offset* -3, c.x-offset* -2, c.y);
-  l_texcoord1 = float4(c.x-offset* -1, c.x-offset*  0, c.x-offset*  1, c.y);
+  float pad = texpad_src.x * 2;
+  l_texcoord0 = float4(min(c.x-offset* -4, pad), min(c.x-offset* -3, pad), min(c.x-offset* -2, pad), c.y);
+  l_texcoord1 = float4(min(c.x-offset* -1, pad), c.x-offset*  0, c.x-offset*  1, c.y);
   l_texcoord2 = float4(c.x-offset*  2, c.x-offset*  3, c.x-offset*  4, c.y);
   l_texcoord2 = float4(c.x-offset*  2, c.x-offset*  3, c.x-offset*  4, c.y);
 }
 }
 
 

+ 3 - 2
direct/src/filter/filter-bloomy.sha

@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
   l_position=mul(mat_modelproj, vtx_position);
   l_position=mul(mat_modelproj, vtx_position);
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float offset = texpix_src.y;
   float offset = texpix_src.y;
-  l_texcoord0 = float4(c.y-offset* -4, c.y-offset* -3, c.y-offset* -2, c.x);
-  l_texcoord1 = float4(c.y-offset* -1, c.y-offset*  0, c.y-offset*  1, c.x);
+  float pad = texpad_src.y * 2;
+  l_texcoord0 = float4(min(c.y-offset* -4, pad), min(c.y-offset* -3, pad), min(c.y-offset* -2, pad), c.x);
+  l_texcoord1 = float4(min(c.y-offset* -1, pad), c.y-offset*  0, c.y-offset*  1, c.x);
   l_texcoord2 = float4(c.y-offset*  2, c.y-offset*  3, c.y-offset*  4, c.x);
   l_texcoord2 = float4(c.y-offset*  2, c.y-offset*  3, c.y-offset*  4, c.x);
 }
 }
 
 

+ 6 - 4
direct/src/filter/filter-blurx.sha

@@ -2,7 +2,7 @@
 //
 //
 //Cg profile arbvp1 arbfp1
 //Cg profile arbvp1 arbfp1
 
 
-void vshader(float4 vtx_position : POSITION, 
+void vshader(float4 vtx_position : POSITION,
              float2 vtx_texcoord0 : TEXCOORD0,
              float2 vtx_texcoord0 : TEXCOORD0,
              out float4 l_position : POSITION,
              out float4 l_position : POSITION,
       	     out float2 l_texcoord0 : TEXCOORD0,
       	     out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
              out float4 o_color : COLOR,
              out float4 o_color : COLOR,
              uniform float2 texpix_src,
              uniform float2 texpix_src,
+             uniform float4 texpad_src,
              uniform sampler2D k_src : TEXUNIT0)
              uniform sampler2D k_src : TEXUNIT0)
 {
 {
+  float pad = texpad_src.x * 2;
   float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
   float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.x, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.y, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.z, l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.x, pad), l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.y, pad), l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.z, pad), l_texcoord0.y));
   o_color /= 7;
   o_color /= 7;
   o_color.w = 1;
   o_color.w = 1;
 }
 }

+ 6 - 4
direct/src/filter/filter-blury.sha

@@ -2,7 +2,7 @@
 //
 //
 //Cg profile arbvp1 arbfp1
 //Cg profile arbvp1 arbfp1
 
 
-void vshader(float4 vtx_position : POSITION, 
+void vshader(float4 vtx_position : POSITION,
              float2 vtx_texcoord0 : TEXCOORD0,
              float2 vtx_texcoord0 : TEXCOORD0,
              out float4 l_position : POSITION,
              out float4 l_position : POSITION,
       	     out float2 l_texcoord0 : TEXCOORD0,
       	     out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
              out float4 o_color : COLOR,
              out float4 o_color : COLOR,
              uniform float2 texpix_src,
              uniform float2 texpix_src,
+             uniform float4 texpad_src,
              uniform sampler2D k_src : TEXUNIT0)
              uniform sampler2D k_src : TEXUNIT0)
 {
 {
+  float pad = texpad_src.y * 2;
   float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
   float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.x));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.z));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.x, pad)));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.y, pad)));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.z, pad)));
   o_color /= 7;
   o_color /= 7;
   o_color.w = 1;
   o_color.w = 1;
 }
 }

+ 6 - 6
direct/src/fsm/ClassicFSM.py

@@ -1,13 +1,13 @@
-"""Undocumented Module"""
-
-__all__ = ['ClassicFSM']
-
 """Finite State Machine module: contains the ClassicFSM class.
 """Finite State Machine module: contains the ClassicFSM class.
 
 
-This module and class exist only for backward compatibility with
-existing code.  New code should use the FSM module instead.
+.. note::
+
+   This module and class exist only for backward compatibility with
+   existing code.  New code should use the :mod:`.FSM` module instead.
 """
 """
 
 
+__all__ = ['ClassicFSM']
+
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 import weakref
 import weakref

+ 1 - 1
direct/src/fsm/FSM.py

@@ -1,5 +1,5 @@
 """The new Finite State Machine module. This replaces the module
 """The new Finite State Machine module. This replaces the module
-previously called FSM.py (now called ClassicFSM.py).
+previously called FSM (now called :mod:`.ClassicFSM`).
 """
 """
 
 
 __all__ = ['FSMException', 'FSM']
 __all__ = ['FSMException', 'FSM']

+ 19 - 21
direct/src/fsm/FourState.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourState class."""
 
 
 __all__ = ['FourState']
 __all__ = ['FourState']
 
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObject
 #import DistributedObject
 from . import ClassicFSM
 from . import ClassicFSM
@@ -20,7 +18,7 @@ class FourState:
     Inherit from FourStateFSM and pass in your states.  Two of
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
 
                     +--------+
                     +--------+
                  -->| closed | --
                  -->| closed | --
@@ -90,7 +88,8 @@ class FourState:
         off (and so is state 2 which is oposite of 4 and therefore
         off (and so is state 2 which is oposite of 4 and therefore
         oposite of 'on').
         oposite of 'on').
         """
         """
-        assert self.debugPrint("FourState(names=%s)"%(names))
+        self.stateIndex = 0
+        assert self.__debugPrint("FourState(names=%s)"%(names))
         self.track = None
         self.track = None
         self.stateTime = 0.0
         self.stateTime = 0.0
         self.names = names
         self.names = names
@@ -120,7 +119,6 @@ class FourState:
                            self.exitState4,
                            self.exitState4,
                            [names[1]]),
                            [names[1]]),
             }
             }
-        self.stateIndex = 0
         self.fsm = ClassicFSM.ClassicFSM('FourState',
         self.fsm = ClassicFSM.ClassicFSM('FourState',
                            list(self.states.values()),
                            list(self.states.values()),
                            # Initial State
                            # Initial State
@@ -131,7 +129,7 @@ class FourState:
         self.fsm.enterInitialState()
         self.fsm.enterInitialState()
 
 
     def setTrack(self, track):
     def setTrack(self, track):
-        assert self.debugPrint("setTrack(track=%s)"%(track,))
+        assert self.__debugPrint("setTrack(track=%s)"%(track,))
         if self.track is not None:
         if self.track is not None:
             self.track.pause()
             self.track.pause()
             self.track = None
             self.track = None
@@ -147,27 +145,27 @@ class FourState:
     # If the client wants the state changed it needs to
     # If the client wants the state changed it needs to
     # send a request to the AI.
     # send a request to the AI.
     #def setIsOn(self, isOn):
     #def setIsOn(self, isOn):
-    #    assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
+    #    assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
     #    pass
     #    pass
 
 
     def isOn(self):
     def isOn(self):
-        assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
+        assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
         return self.stateIndex==4
         return self.stateIndex==4
 
 
     def changedOnState(self, isOn):
     def changedOnState(self, isOn):
         """
         """
         Allow derived classes to overide this.
         Allow derived classes to overide this.
         """
         """
-        assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
 
 
     ##### state 0 #####
     ##### state 0 #####
 
 
     def enterState0(self):
     def enterState0(self):
-        assert self.debugPrint("enter0()")
+        assert self.__debugPrint("enter0()")
         self.enterStateN(0)
         self.enterStateN(0)
 
 
     def exitState0(self):
     def exitState0(self):
-        assert self.debugPrint("exit0()")
+        assert self.__debugPrint("exit0()")
         # It's important for FourStates to broadcast their state
         # It's important for FourStates to broadcast their state
         # when they are generated on the client. Before I put this in,
         # when they are generated on the client. Before I put this in,
         # if a door was generated and went directly to an 'open' state,
         # if a door was generated and went directly to an 'open' state,
@@ -177,43 +175,43 @@ class FourState:
     ##### state 1 #####
     ##### state 1 #####
 
 
     def enterState1(self):
     def enterState1(self):
-        assert self.debugPrint("enterState1()")
+        assert self.__debugPrint("enterState1()")
         self.enterStateN(1)
         self.enterStateN(1)
 
 
     def exitState1(self):
     def exitState1(self):
-        assert self.debugPrint("exitState1()")
+        assert self.__debugPrint("exitState1()")
 
 
     ##### state 2 #####
     ##### state 2 #####
 
 
     def enterState2(self):
     def enterState2(self):
-        assert self.debugPrint("enterState2()")
+        assert self.__debugPrint("enterState2()")
         self.enterStateN(2)
         self.enterStateN(2)
 
 
     def exitState2(self):
     def exitState2(self):
-        assert self.debugPrint("exitState2()")
+        assert self.__debugPrint("exitState2()")
 
 
     ##### state 3 #####
     ##### state 3 #####
 
 
     def enterState3(self):
     def enterState3(self):
-        assert self.debugPrint("enterState3()")
+        assert self.__debugPrint("enterState3()")
         self.enterStateN(3)
         self.enterStateN(3)
 
 
     def exitState3(self):
     def exitState3(self):
-        assert self.debugPrint("exitState3()")
+        assert self.__debugPrint("exitState3()")
 
 
     ##### state 4 #####
     ##### state 4 #####
 
 
     def enterState4(self):
     def enterState4(self):
-        assert self.debugPrint("enterState4()")
+        assert self.__debugPrint("enterState4()")
         self.enterStateN(4)
         self.enterStateN(4)
         self.changedOnState(1)
         self.changedOnState(1)
 
 
     def exitState4(self):
     def exitState4(self):
-        assert self.debugPrint("exitState4()")
+        assert self.__debugPrint("exitState4()")
         self.changedOnState(0)
         self.changedOnState(0)
 
 
     if __debug__:
     if __debug__:
-        def debugPrint(self, message):
+        def __debugPrint(self, message):
             """for debugging"""
             """for debugging"""
             return self.notify.debug("%d (%d) %s"%(
             return self.notify.debug("%d (%d) %s"%(
                     id(self), self.stateIndex==4, message))
                     id(self), self.stateIndex==4, message))

+ 25 - 27
direct/src/fsm/FourStateAI.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourStateAI class.  See also :mod:`.FourState`."""
 
 
 __all__ = ['FourStateAI']
 __all__ = ['FourStateAI']
 
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObjectAI
 #import DistributedObjectAI
 from . import ClassicFSM
 from . import ClassicFSM
@@ -21,7 +19,7 @@ class FourStateAI:
     Inherit from FourStateFSM and pass in your states.  Two of
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
 
                     +--------+
                     +--------+
                  -->| closed | --
                  -->| closed | --
@@ -93,11 +91,11 @@ class FourStateAI:
         off (and so is state 2 which is oposite of state 4 and therefore
         off (and so is state 2 which is oposite of state 4 and therefore
         oposite of 'on').
         oposite of 'on').
         """
         """
-        assert self.debugPrint(
+        self.stateIndex = 0
+        assert self.__debugPrint(
                 "FourStateAI(names=%s, durations=%s)"
                 "FourStateAI(names=%s, durations=%s)"
                 %(names, durations))
                 %(names, durations))
         self.doLaterTask = None
         self.doLaterTask = None
-        self.stateIndex = 0
         assert len(names) == 5
         assert len(names) == 5
         assert len(names) == len(durations)
         assert len(names) == len(durations)
         self.names = names
         self.names = names
@@ -137,7 +135,7 @@ class FourStateAI:
         self.fsm.enterInitialState()
         self.fsm.enterInitialState()
 
 
     def delete(self):
     def delete(self):
-        assert self.debugPrint("delete()")
+        assert self.__debugPrint("delete()")
         if self.doLaterTask is not None:
         if self.doLaterTask is not None:
             self.doLaterTask.remove()
             self.doLaterTask.remove()
             del self.doLaterTask
             del self.doLaterTask
@@ -145,15 +143,15 @@ class FourStateAI:
         del self.fsm
         del self.fsm
 
 
     def getState(self):
     def getState(self):
-        assert self.debugPrint("getState() returning %s"%(self.stateIndex,))
+        assert self.__debugPrint("getState() returning %s"%(self.stateIndex,))
         return [self.stateIndex]
         return [self.stateIndex]
 
 
     def sendState(self):
     def sendState(self):
-        assert self.debugPrint("sendState()")
+        assert self.__debugPrint("sendState()")
         self.sendUpdate('setState', self.getState())
         self.sendUpdate('setState', self.getState())
 
 
     def setIsOn(self, isOn):
     def setIsOn(self, isOn):
-        assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
         if isOn:
         if isOn:
             if self.stateIndex != 4:
             if self.stateIndex != 4:
                 # ...if it's not On; request turning on:
                 # ...if it's not On; request turning on:
@@ -170,7 +168,7 @@ class FourStateAI:
         #    self.fsm.request(self.states[nextState])
         #    self.fsm.request(self.states[nextState])
 
 
     def isOn(self):
     def isOn(self):
-        assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
+        assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
         return self.stateIndex==4
         return self.stateIndex==4
 
 
     def changedOnState(self, isOn):
     def changedOnState(self, isOn):
@@ -179,12 +177,12 @@ class FourStateAI:
         The self.isOn value has toggled.  Call getIsOn() to
         The self.isOn value has toggled.  Call getIsOn() to
         get the current state.
         get the current state.
         """
         """
-        assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
 
 
     ##### states #####
     ##### states #####
 
 
     def switchToNextStateTask(self, task):
     def switchToNextStateTask(self, task):
-        assert self.debugPrint("switchToNextStateTask()")
+        assert self.__debugPrint("switchToNextStateTask()")
         self.fsm.request(self.states[self.nextStateIndex])
         self.fsm.request(self.states[self.nextStateIndex])
         return Task.done
         return Task.done
 
 
@@ -193,11 +191,11 @@ class FourStateAI:
         This function is intentionaly simple so that derived classes
         This function is intentionaly simple so that derived classes
         may easily alter the network message.
         may easily alter the network message.
         """
         """
-        assert self.debugPrint("distributeStateChange()")
+        assert self.__debugPrint("distributeStateChange()")
         self.sendState()
         self.sendState()
 
 
     def enterStateN(self, stateIndex, nextStateIndex):
     def enterStateN(self, stateIndex, nextStateIndex):
-        assert self.debugPrint(
+        assert self.__debugPrint(
             "enterStateN(stateIndex=%s, nextStateIndex=%s)"%
             "enterStateN(stateIndex=%s, nextStateIndex=%s)"%
             (stateIndex, nextStateIndex))
             (stateIndex, nextStateIndex))
         self.stateIndex = stateIndex
         self.stateIndex = stateIndex
@@ -211,7 +209,7 @@ class FourStateAI:
                 "enterStateN-timer-%s"%id(self))
                 "enterStateN-timer-%s"%id(self))
 
 
     def exitStateN(self):
     def exitStateN(self):
-        assert self.debugPrint("exitStateN()")
+        assert self.__debugPrint("exitStateN()")
         if self.doLaterTask:
         if self.doLaterTask:
             taskMgr.remove(self.doLaterTask)
             taskMgr.remove(self.doLaterTask)
             self.doLaterTask=None
             self.doLaterTask=None
@@ -219,56 +217,56 @@ class FourStateAI:
     ##### state 0 #####
     ##### state 0 #####
 
 
     def enterState0(self):
     def enterState0(self):
-        assert self.debugPrint("enter0()")
+        assert self.__debugPrint("enter0()")
         self.enterStateN(0, 0)
         self.enterStateN(0, 0)
 
 
     def exitState0(self):
     def exitState0(self):
-        assert self.debugPrint("exit0()")
+        assert self.__debugPrint("exit0()")
 
 
     ##### state 1 #####
     ##### state 1 #####
 
 
     def enterState1(self):
     def enterState1(self):
-        #assert self.debugPrint("enterState1()")
+        #assert self.__debugPrint("enterState1()")
         self.enterStateN(1, 2)
         self.enterStateN(1, 2)
 
 
     def exitState1(self):
     def exitState1(self):
-        assert self.debugPrint("exitState1()")
+        assert self.__debugPrint("exitState1()")
         self.exitStateN()
         self.exitStateN()
 
 
     ##### state 2 #####
     ##### state 2 #####
 
 
     def enterState2(self):
     def enterState2(self):
-        #assert self.debugPrint("enterState2()")
+        #assert self.__debugPrint("enterState2()")
         self.enterStateN(2, 3)
         self.enterStateN(2, 3)
 
 
     def exitState2(self):
     def exitState2(self):
-        assert self.debugPrint("exitState2()")
+        assert self.__debugPrint("exitState2()")
         self.exitStateN()
         self.exitStateN()
 
 
     ##### state 3 #####
     ##### state 3 #####
 
 
     def enterState3(self):
     def enterState3(self):
-        #assert self.debugPrint("enterState3()")
+        #assert self.__debugPrint("enterState3()")
         self.enterStateN(3, 4)
         self.enterStateN(3, 4)
 
 
     def exitState3(self):
     def exitState3(self):
-        assert self.debugPrint("exitState3()")
+        assert self.__debugPrint("exitState3()")
         self.exitStateN()
         self.exitStateN()
 
 
     ##### state 4 #####
     ##### state 4 #####
 
 
     def enterState4(self):
     def enterState4(self):
-        assert self.debugPrint("enterState4()")
+        assert self.__debugPrint("enterState4()")
         self.enterStateN(4, 1)
         self.enterStateN(4, 1)
         self.changedOnState(1)
         self.changedOnState(1)
 
 
     def exitState4(self):
     def exitState4(self):
-        assert self.debugPrint("exitState4()")
+        assert self.__debugPrint("exitState4()")
         self.exitStateN()
         self.exitStateN()
         self.changedOnState(0)
         self.changedOnState(0)
 
 
     if __debug__:
     if __debug__:
-        def debugPrint(self, message):
+        def __debugPrint(self, message):
             """for debugging"""
             """for debugging"""
             return self.notify.debug("%d (%d) %s"%(
             return self.notify.debug("%d (%d) %s"%(
                     id(self), self.stateIndex==4, message))
                     id(self), self.stateIndex==4, message))

+ 6 - 0
direct/src/fsm/__init__.py

@@ -0,0 +1,6 @@
+"""
+This package contains implementations of a Finite State Machine, an
+abstract construct that holds a particular state and can transition
+between several defined states.  These are useful for a range of logic
+programming tasks.
+"""

+ 1 - 1
direct/src/gui/DirectButton.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module contains the DirectButton class."""
 
 
 __all__ = ['DirectButton']
 __all__ = ['DirectButton']
 
 

+ 3 - 1
direct/src/gui/DirectCheckButton.py

@@ -1,4 +1,6 @@
-"""Undocumented Module"""
+"""A DirectCheckButton is a type of button that toggles between two states
+when clicked.  It also has a separate indicator that can be modified
+separately."""
 
 
 __all__ = ['DirectCheckButton']
 __all__ = ['DirectCheckButton']
 
 

+ 1 - 1
direct/src/gui/DirectDialog.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module defines various dialog windows for the DirectGUI system."""
 
 
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 
 

+ 2 - 1
direct/src/gui/DirectEntry.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Contains the DirectEntry class, a type of DirectGUI widget that accepts
+text entered using the keyboard."""
 
 
 __all__ = ['DirectEntry']
 __all__ = ['DirectEntry']
 
 

+ 14 - 9
direct/src/gui/DirectFrame.py

@@ -1,4 +1,17 @@
-"""Undocumented Module"""
+"""A DirectFrame is a basic DirectGUI component that acts as the base
+class for various other components, and can also serve as a basic
+container to hold other DirectGUI components.
+
+A DirectFrame can have:
+
+* A background texture (pass in path to image, or Texture Card)
+* A midground geometry item (pass in geometry)
+* A foreground text Node (pass in text string or OnscreenText)
+
+Each of these has 1 or more states.  The same object can be used for
+all states or each state can have a different text/geom/image (for
+radio button and check button indicators, for example).
+"""
 
 
 __all__ = ['DirectFrame']
 __all__ = ['DirectFrame']
 
 
@@ -19,14 +32,6 @@ class DirectFrame(DirectGuiWidget):
     DefDynGroups = ('text', 'geom', 'image')
     DefDynGroups = ('text', 'geom', 'image')
     def __init__(self, parent = None, **kw):
     def __init__(self, parent = None, **kw):
         # Inherits from DirectGuiWidget
         # Inherits from DirectGuiWidget
-        # A Direct Frame can have:
-        # - A background texture (pass in path to image, or Texture Card)
-        # - A midground geometry item (pass in geometry)
-        # - A foreground text Node (pass in text string or Onscreen Text)
-        # Each of these has 1 or more states
-        # The same object can be used for all states or each
-        # state can have a different text/geom/image (for radio button
-        # and check button indicators, for example).
         optiondefs = (
         optiondefs = (
             # Define type of DirectGuiWidget
             # Define type of DirectGuiWidget
             ('pgFunc',          PGItem,     None),
             ('pgFunc',          PGItem,     None),

+ 24 - 25
direct/src/gui/DirectGuiBase.py

@@ -1,32 +1,7 @@
-"""Undocumented Module"""
-
-__all__ = ['DirectGuiBase', 'DirectGuiWidget']
-
-
-from panda3d.core import *
-from panda3d.direct import get_config_showbase
-from . import DirectGuiGlobals as DGG
-from .OnscreenText import *
-from .OnscreenGeom import *
-from .OnscreenImage import *
-from direct.directtools.DirectUtil import ROUND_TO
-from direct.showbase import DirectObject
-from direct.task import Task
-import sys
-
-if sys.version_info >= (3, 0):
-    stringType = str
-else:
-    stringType = basestring
-
-guiObjectCollector = PStatCollector("Client::GuiObjects")
-
 """
 """
 Base class for all Direct Gui items.  Handles composite widgets and
 Base class for all Direct Gui items.  Handles composite widgets and
 command line argument parsing.
 command line argument parsing.
-"""
 
 
-"""
 Code Overview:
 Code Overview:
 
 
 1   Each widget defines a set of options (optiondefs) as a list of tuples
 1   Each widget defines a set of options (optiondefs) as a list of tuples
@@ -101,7 +76,31 @@ Code Overview:
     are left unused.  If so, an error is raised.
     are left unused.  If so, an error is raised.
 """
 """
 
 
+__all__ = ['DirectGuiBase', 'DirectGuiWidget']
+
+
+from panda3d.core import *
+from panda3d.direct import get_config_showbase
+from . import DirectGuiGlobals as DGG
+from .OnscreenText import *
+from .OnscreenGeom import *
+from .OnscreenImage import *
+from direct.directtools.DirectUtil import ROUND_TO
+from direct.showbase import DirectObject
+from direct.task import Task
+import sys
+
+if sys.version_info >= (3, 0):
+    stringType = str
+else:
+    stringType = basestring
+
+guiObjectCollector = PStatCollector("Client::GuiObjects")
+
+
 class DirectGuiBase(DirectObject.DirectObject):
 class DirectGuiBase(DirectObject.DirectObject):
+    """Base class of all DirectGUI widgets."""
+
     def __init__(self):
     def __init__(self):
         # Default id of all gui object, subclasses should override this
         # Default id of all gui object, subclasses should override this
         self.guiId = 'guiObject'
         self.guiId = 'guiObject'

+ 3 - 5
direct/src/gui/DirectGuiGlobals.py

@@ -1,12 +1,10 @@
-"""Undocumented Module"""
-
-__all__ = []
-
-
 """
 """
 Global definitions used by Direct Gui Classes and handy constants
 Global definitions used by Direct Gui Classes and handy constants
 that can be used during widget construction
 that can be used during widget construction
 """
 """
+
+__all__ = []
+
 from panda3d.core import *
 from panda3d.core import *
 
 
 defaultFont = None
 defaultFont = None

+ 1 - 1
direct/src/gui/DirectLabel.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectLabel class."""
 
 
 __all__ = ['DirectLabel']
 __all__ = ['DirectLabel']
 
 

+ 1 - 1
direct/src/gui/DirectOptionMenu.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Implements a pop-up menu containing multiple clickable options."""
 
 
 __all__ = ['DirectOptionMenu']
 __all__ = ['DirectOptionMenu']
 
 

+ 4 - 1
direct/src/gui/DirectRadioButton.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""A DirectRadioButton is a type of button that, similar to a
+DirectCheckButton, has a separate indicator and can be toggled between
+two states.  However, only one DirectRadioButton in a group can be enabled
+at a particular time."""
 
 
 __all__ = ['DirectRadioButton']
 __all__ = ['DirectRadioButton']
 
 

+ 1 - 1
direct/src/gui/DirectScrollBar.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines the DirectScrollBar class."""
 
 
 __all__ = ['DirectScrollBar']
 __all__ = ['DirectScrollBar']
 
 

+ 1 - 1
direct/src/gui/DirectScrolledFrame.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectScrolledFrame class."""
 
 
 __all__ = ['DirectScrolledFrame']
 __all__ = ['DirectScrolledFrame']
 
 

+ 1 - 1
direct/src/gui/DirectScrolledList.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectScrolledList class."""
 
 
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 
 

+ 1 - 1
direct/src/gui/DirectSlider.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines the DirectSlider class."""
 
 
 __all__ = ['DirectSlider']
 __all__ = ['DirectSlider']
 
 

+ 1 - 1
direct/src/gui/DirectWaitBar.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectWaitBar class, a progress bar widget."""
 
 
 __all__ = ['DirectWaitBar']
 __all__ = ['DirectWaitBar']
 
 

+ 16 - 1
direct/src/gui/OnscreenText.py

@@ -35,7 +35,8 @@ class OnscreenText(NodePath):
                  font = None,
                  font = None,
                  parent = None,
                  parent = None,
                  sort = 0,
                  sort = 0,
-                 mayChange = True):
+                 mayChange = True,
+                 direction = None):
         """
         """
         Make a text node from string, put it into the 2d sg and set it
         Make a text node from string, put it into the 2d sg and set it
         up with all the indicated parameters.
         up with all the indicated parameters.
@@ -95,6 +96,9 @@ class OnscreenText(NodePath):
           mayChange: pass true if the text or its properties may need
           mayChange: pass true if the text or its properties may need
               to be changed at runtime, false if it is static once
               to be changed at runtime, false if it is static once
               created (which leads to better memory optimization).
               created (which leads to better memory optimization).
+
+          direction: this can be set to 'ltr' or 'rtl' to override the
+              direction of the text.
         """
         """
         if parent == None:
         if parent == None:
             parent = aspect2d
             parent = aspect2d
@@ -192,6 +196,17 @@ class OnscreenText(NodePath):
             textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
             textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
             textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
             textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
 
 
+        if direction is not None:
+            if isinstance(direction, str):
+                direction = direction.lower()
+                if direction == 'rtl':
+                    direction = TextProperties.D_rtl
+                elif direction == 'ltr':
+                    direction = TextProperties.D_ltr
+                else:
+                    raise ValueError('invalid direction')
+            textNode.setDirection(direction)
+
         # Create a transform for the text for our scale and position.
         # Create a transform for the text for our scale and position.
         # We'd rather do it here, on the text itself, rather than on
         # We'd rather do it here, on the text itself, rather than on
         # our NodePath, so we have one fewer transforms in the scene
         # our NodePath, so we have one fewer transforms in the scene

+ 12 - 0
direct/src/gui/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains the DirectGui system, a set of classes
+responsible for drawing graphical widgets to the 2-D scene graph.
+
+It is based on the lower-level PGui system, which is implemented in
+C++.
+
+For convenience, all of the DirectGui widgets may be imported from a
+single module as follows::
+
+   from direct.gui.DirectGui import *
+"""

+ 1 - 1
direct/src/interval/ActorInterval.py

@@ -83,7 +83,7 @@ class ActorInterval(Interval.Interval):
                 if startTime == None:
                 if startTime == None:
                     startTime = float(self.startFrame) / float(self.frameRate)
                     startTime = float(self.startFrame) / float(self.frameRate)
                 endTime = startTime + duration
                 endTime = startTime + duration
-                self.endFrame = duration * self.frameRate
+                self.endFrame = endTime * self.frameRate
             else:
             else:
                 # No end frame specified.  Choose the maximum of all
                 # No end frame specified.  Choose the maximum of all
                 # of the controls' numbers of frames.
                 # of the controls' numbers of frames.

+ 3 - 1
direct/src/interval/Interval.py

@@ -116,8 +116,9 @@ class Interval(DirectObject):
         return self.currT
         return self.currT
 
 
     def start(self, startT = 0.0, endT = -1.0, playRate = 1.0):
     def start(self, startT = 0.0, endT = -1.0, playRate = 1.0):
+        """ Starts the interval.  Returns an awaitable. """
         self.setupPlay(startT, endT, playRate, 0)
         self.setupPlay(startT, endT, playRate, 0)
-        self.__spawnTask()
+        return self.__spawnTask()
 
 
     def loop(self, startT = 0.0, endT = -1.0, playRate = 1.0):
     def loop(self, startT = 0.0, endT = -1.0, playRate = 1.0):
         self.setupPlay(startT, endT, playRate, 1)
         self.setupPlay(startT, endT, playRate, 1)
@@ -427,6 +428,7 @@ class Interval(DirectObject):
         task = Task(self.__playTask)
         task = Task(self.__playTask)
         task.interval = self
         task.interval = self
         taskMgr.add(task, taskName)
         taskMgr.add(task, taskName)
+        return task
 
 
     def __removeTask(self):
     def __removeTask(self):
         # Kill old task(s), including those from a similarly-named but
         # Kill old task(s), including those from a similarly-named but

+ 4 - 1
direct/src/interval/IntervalGlobal.py

@@ -1,4 +1,7 @@
-"""IntervalGlobal module"""
+"""
+This module imports all of the other interval modules, to provide a
+single convenient module from which all interval types can be imported.
+"""
 
 
 # In this unusual case, I'm not going to declare __all__,
 # In this unusual case, I'm not going to declare __all__,
 # since the purpose of this module is to add up the contributions
 # since the purpose of this module is to add up the contributions

+ 3 - 3
direct/src/interval/IntervalManager.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Defines the IntervalManager class as well as the global instance of
+this class, ivalMgr."""
 
 
 __all__ = ['IntervalManager', 'ivalMgr']
 __all__ = ['IntervalManager', 'ivalMgr']
 
 
@@ -136,6 +137,5 @@ class IntervalManager(CIntervalManager):
         assert self.ivals[index] == None or self.ivals[index] == interval
         assert self.ivals[index] == None or self.ivals[index] == interval
         self.ivals[index] = interval
         self.ivals[index] = interval
 
 
-# The global IntervalManager object.
+#: The global IntervalManager object.
 ivalMgr = IntervalManager(1)
 ivalMgr = IntervalManager(1)
-

+ 4 - 1
direct/src/interval/MetaInterval.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""
+This module defines the various "meta intervals", which execute other
+intervals either in parallel or in a specified sequential order.
+"""
 
 
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 
 

+ 2 - 4
direct/src/interval/ParticleInterval.py

@@ -1,11 +1,9 @@
-"""Undocumented Module"""
-
-__all__ = ['ParticleInterval']
-
 """
 """
 Contains the ParticleInterval class
 Contains the ParticleInterval class
 """
 """
 
 
+__all__ = ['ParticleInterval']
+
 from panda3d.core import *
 from panda3d.core import *
 from panda3d.direct import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify

+ 3 - 5
direct/src/interval/TestInterval.py

@@ -1,11 +1,9 @@
-"""Undocumented Module"""
-
-__all__ = ['TestInterval']
-
 """
 """
-Contains the ParticleInterval class
+Contains the TestInterval class
 """
 """
 
 
+__all__ = ['TestInterval']
+
 from panda3d.core import *
 from panda3d.core import *
 from panda3d.direct import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify

+ 12 - 0
direct/src/interval/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains the Python implementation of the interval system,
+which is a mechanism for playing back scripted actions.  A range of
+interval types has been defined to automate motion, animation, sounds,
+color, function calls, as well as other intervals and arbitrary
+properties.
+
+All interval types can be conveniently imported from the
+:mod:`.IntervalGlobal` module::
+
+   from direct.interval.IntervalGlobal import *
+"""

+ 3 - 3
direct/src/interval/cConstrainHprInterval.h

@@ -26,9 +26,9 @@
  */
  */
 class EXPCL_DIRECT CConstrainHprInterval : public CConstraintInterval {
 class EXPCL_DIRECT CConstrainHprInterval : public CConstraintInterval {
 PUBLISHED:
 PUBLISHED:
-  CConstrainHprInterval(const string &name, double duration,
-                        const NodePath &node, const NodePath &target,
-                        bool wrt, const LVecBase3 hprOffset=LVector3::zero());
+  explicit CConstrainHprInterval(const string &name, double duration,
+                                 const NodePath &node, const NodePath &target,
+                                 bool wrt, const LVecBase3 hprOffset=LVector3::zero());
 
 
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_target() const;
   INLINE const NodePath &get_target() const;

+ 4 - 4
direct/src/interval/cConstrainPosHprInterval.h

@@ -26,10 +26,10 @@
  */
  */
 class EXPCL_DIRECT CConstrainPosHprInterval : public CConstraintInterval {
 class EXPCL_DIRECT CConstrainPosHprInterval : public CConstraintInterval {
 PUBLISHED:
 PUBLISHED:
-  CConstrainPosHprInterval(const string &name, double duration,
-                           const NodePath &node, const NodePath &target,
-                           bool wrt, const LVecBase3 posOffset=LVector3::zero(),
-                           const LVecBase3 hprOffset=LVector3::zero());
+  explicit CConstrainPosHprInterval(const string &name, double duration,
+                                    const NodePath &node, const NodePath &target,
+                                    bool wrt, const LVecBase3 posOffset=LVector3::zero(),
+                                    const LVecBase3 hprOffset=LVector3::zero());
 
 
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_target() const;
   INLINE const NodePath &get_target() const;

+ 3 - 3
direct/src/interval/cConstrainPosInterval.h

@@ -25,9 +25,9 @@
  */
  */
 class EXPCL_DIRECT CConstrainPosInterval : public CConstraintInterval {
 class EXPCL_DIRECT CConstrainPosInterval : public CConstraintInterval {
 PUBLISHED:
 PUBLISHED:
-  CConstrainPosInterval(const string &name, double duration,
-                        const NodePath &node, const NodePath &target,
-                        bool wrt, const LVecBase3 posOffset=LVector3::zero());
+  explicit CConstrainPosInterval(const string &name, double duration,
+                                 const NodePath &node, const NodePath &target,
+                                 bool wrt, const LVecBase3 posOffset=LVector3::zero());
 
 
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_target() const;
   INLINE const NodePath &get_target() const;

+ 3 - 3
direct/src/interval/cConstrainTransformInterval.h

@@ -24,9 +24,9 @@
  */
  */
 class EXPCL_DIRECT CConstrainTransformInterval : public CConstraintInterval {
 class EXPCL_DIRECT CConstrainTransformInterval : public CConstraintInterval {
 PUBLISHED:
 PUBLISHED:
-  CConstrainTransformInterval(const string &name, double duration,
-                              const NodePath &node, const NodePath &target,
-                              bool wrt);
+  explicit CConstrainTransformInterval(const string &name, double duration,
+                                       const NodePath &node,
+                                       const NodePath &target, bool wrt);
 
 
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_target() const;
   INLINE const NodePath &get_target() const;

+ 2 - 2
direct/src/interval/cLerpAnimEffectInterval.h

@@ -31,8 +31,8 @@
  */
  */
 class EXPCL_DIRECT CLerpAnimEffectInterval : public CLerpInterval {
 class EXPCL_DIRECT CLerpAnimEffectInterval : public CLerpInterval {
 PUBLISHED:
 PUBLISHED:
-  INLINE CLerpAnimEffectInterval(const string &name, double duration,
-                                 BlendType blend_type);
+  INLINE explicit CLerpAnimEffectInterval(const string &name, double duration,
+                                          BlendType blend_type);
 
 
   INLINE void add_control(AnimControl *control, const string &name,
   INLINE void add_control(AnimControl *control, const string &name,
                           float begin_effect, float end_effect);
                           float begin_effect, float end_effect);

+ 4 - 4
direct/src/interval/cLerpNodePathInterval.h

@@ -25,10 +25,10 @@
  */
  */
 class EXPCL_DIRECT CLerpNodePathInterval : public CLerpInterval {
 class EXPCL_DIRECT CLerpNodePathInterval : public CLerpInterval {
 PUBLISHED:
 PUBLISHED:
-  CLerpNodePathInterval(const string &name, double duration,
-                        BlendType blend_type, bool bake_in_start,
-                        bool fluid,
-                        const NodePath &node, const NodePath &other);
+  explicit CLerpNodePathInterval(const string &name, double duration,
+                                 BlendType blend_type, bool bake_in_start,
+                                 bool fluid,
+                                 const NodePath &node, const NodePath &other);
 
 
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_node() const;
   INLINE const NodePath &get_other() const;
   INLINE const NodePath &get_other() const;

+ 1 - 1
direct/src/interval/cMetaInterval.h

@@ -31,7 +31,7 @@
  */
  */
 class EXPCL_DIRECT CMetaInterval : public CInterval {
 class EXPCL_DIRECT CMetaInterval : public CInterval {
 PUBLISHED:
 PUBLISHED:
-  CMetaInterval(const string &name);
+  explicit CMetaInterval(const string &name);
   virtual ~CMetaInterval();
   virtual ~CMetaInterval();
 
 
   enum RelativeStart {
   enum RelativeStart {

+ 1 - 1
direct/src/interval/hideInterval.h

@@ -23,7 +23,7 @@
  */
  */
 class EXPCL_DIRECT HideInterval : public CInterval {
 class EXPCL_DIRECT HideInterval : public CInterval {
 PUBLISHED:
 PUBLISHED:
-  HideInterval(const NodePath &node, const string &name = string());
+  explicit HideInterval(const NodePath &node, const string &name = string());
 
 
   virtual void priv_instant();
   virtual void priv_instant();
   virtual void priv_reverse_instant();
   virtual void priv_reverse_instant();

+ 1 - 1
direct/src/interval/showInterval.h

@@ -23,7 +23,7 @@
  */
  */
 class EXPCL_DIRECT ShowInterval : public CInterval {
 class EXPCL_DIRECT ShowInterval : public CInterval {
 PUBLISHED:
 PUBLISHED:
-  ShowInterval(const NodePath &node, const string &name = string());
+  explicit ShowInterval(const NodePath &node, const string &name = string());
 
 
   virtual void priv_instant();
   virtual void priv_instant();
   virtual void priv_reverse_instant();
   virtual void priv_reverse_instant();

+ 1 - 1
direct/src/interval/waitInterval.h

@@ -23,7 +23,7 @@
  */
  */
 class EXPCL_DIRECT WaitInterval : public CInterval {
 class EXPCL_DIRECT WaitInterval : public CInterval {
 PUBLISHED:
 PUBLISHED:
-  INLINE WaitInterval(double duration);
+  INLINE explicit WaitInterval(double duration);
 
 
   virtual void priv_step(double t);
   virtual void priv_step(double t);
 
 

+ 3 - 0
direct/src/motiontrail/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains only the :class:`.MotionTrail` class.
+"""

+ 5 - 2
direct/src/p3d/AppRunner.py

@@ -1,12 +1,15 @@
-
 """
 """
-
 This module is intended to be compiled into the Panda3D runtime
 This module is intended to be compiled into the Panda3D runtime
 distributable, to execute a packaged p3d application, but it can also
 distributable, to execute a packaged p3d application, but it can also
 be run directly via the Python interpreter (if the current Panda3D and
 be run directly via the Python interpreter (if the current Panda3D and
 Python versions match the version expected by the application).  See
 Python versions match the version expected by the application).  See
 runp3d.py for a command-line tool to invoke this module.
 runp3d.py for a command-line tool to invoke this module.
 
 
+The global AppRunner instance may be imported as follows::
+
+   from direct.showbase.AppRunnerGlobal import appRunner
+
+This will be None if Panda was not run from the runtime environment.
 """
 """
 
 
 __all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]
 __all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]

+ 4 - 0
direct/src/p3d/__init__.py

@@ -0,0 +1,4 @@
+"""
+This package provides the Python interface to functionality relating to
+the Panda3D Runtime environment.
+"""

+ 7 - 0
direct/src/particles/__init__.py

@@ -0,0 +1,7 @@
+"""
+This package contains the high-level Python interface to the particle
+system.
+
+Also see the :mod:`panda3d.physics` module, which contains the C++
+implementation of the particle system.
+"""

+ 4 - 4
direct/src/plugin/p3dInstance.cxx

@@ -3450,8 +3450,8 @@ paint_window_osx_port() {
   int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
   int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
   size_t rowsize = _swbuffer->get_row_size();
   size_t rowsize = _swbuffer->get_row_size();
 
 
-  Rect src_rect = {0, 0, y_size, x_size};
-  Rect ddrc_rect = {0, 0, y_size, x_size};
+  Rect src_rect = {0, 0, (short)y_size, (short)x_size};
+  Rect ddrc_rect = {0, 0, (short)y_size, (short)x_size};
 
 
   QDErr err;
   QDErr err;
 
 
@@ -3502,7 +3502,7 @@ paint_window_osx_cgcontext(CGContextRef context) {
   int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
   int y_size = min(_wparams.get_win_height(), _swbuffer->get_y_size());
 
 
   if (_buffer_image != NULL) {
   if (_buffer_image != NULL) {
-    CGRect region = { { 0, 0 }, { x_size, y_size } };
+    CGRect region = { { 0, 0 }, { (CGFloat)x_size, (CGFloat)y_size } };
     CGContextDrawImage(context, region, _buffer_image);
     CGContextDrawImage(context, region, _buffer_image);
   }
   }
 }
 }
@@ -3538,7 +3538,7 @@ handle_event_osx_event_record(const P3D_event_data &event) {
     // First, convert the coordinates from screen coordinates to browser
     // First, convert the coordinates from screen coordinates to browser
     // window coordinates.
     // window coordinates.
     WindowRef window = handle._handle._osx_cgcontext._window;
     WindowRef window = handle._handle._osx_cgcontext._window;
-    CGPoint cgpt = { pt.h, pt.v };
+    CGPoint cgpt = { (CGFloat)pt.h, (CGFloat)pt.v };
     HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
     HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
                    kHICoordSpaceWindow, window);
                    kHICoordSpaceWindow, window);
 
 

+ 8 - 8
direct/src/plugin/p3dOsxSplashWindow.cxx

@@ -267,7 +267,7 @@ refresh() {
     return;
     return;
   }
   }
   if (_toplevel_window != NULL) {
   if (_toplevel_window != NULL) {
-    Rect r = { 0, 0, _win_height, _win_width };
+    Rect r = { 0, 0, (short)_win_height, (short)_win_width };
     InvalWindowRect(_toplevel_window, &r);
     InvalWindowRect(_toplevel_window, &r);
 
 
   } else {
   } else {
@@ -345,7 +345,7 @@ paint_window_osx_cgcontext(CGContextRef context) {
   CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
   CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
   CGColorRef bg = CGColorCreate(rgb_space, bg_components);
   CGColorRef bg = CGColorCreate(rgb_space, bg_components);
 
 
-  CGRect region = { { 0, 0 }, { _win_width, _win_height } };
+  CGRect region = { { 0, 0 }, { (CGFloat)_win_width, (CGFloat)_win_height } };
   CGContextSetFillColorWithColor(context, bg);
   CGContextSetFillColorWithColor(context, bg);
   CGContextFillRect(context, region);
   CGContextFillRect(context, region);
 
 
@@ -407,7 +407,7 @@ handle_event_osx_event_record(const P3D_event_data &event) {
     // First, convert the coordinates from screen coordinates to browser
     // First, convert the coordinates from screen coordinates to browser
     // window coordinates.
     // window coordinates.
     WindowRef window = handle._handle._osx_cgcontext._window;
     WindowRef window = handle._handle._osx_cgcontext._window;
-    CGPoint cgpt = { pt.h, pt.v };
+    CGPoint cgpt = { (CGFloat)pt.h, (CGFloat)pt.v };
     HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
     HIPointConvert(&cgpt, kHICoordSpaceScreenPixel, NULL,
                    kHICoordSpaceWindow, window);
                    kHICoordSpaceWindow, window);
 
 
@@ -617,7 +617,7 @@ paint_progress_bar(CGContextRef context) {
   int bar_x, bar_y, bar_width, bar_height;
   int bar_x, bar_y, bar_width, bar_height;
   get_bar_placement(bar_x, bar_y, bar_width, bar_height);
   get_bar_placement(bar_x, bar_y, bar_width, bar_height);
 
 
-  CGRect bar_rect = { { bar_x, bar_y }, { bar_width, bar_height } };
+  CGRect bar_rect = { { (CGFloat)bar_x, (CGFloat)bar_y }, { (CGFloat)bar_width, (CGFloat)bar_height } };
 
 
   // Clear the entire progress bar to white (or the background color).
   // Clear the entire progress bar to white (or the background color).
   CGContextSetFillColorWithColor(context, bar_bg);
   CGContextSetFillColorWithColor(context, bar_bg);
@@ -627,7 +627,7 @@ paint_progress_bar(CGContextRef context) {
   if (_progress_known) {
   if (_progress_known) {
     int progress_width = (int)(bar_width * _install_progress + 0.5);
     int progress_width = (int)(bar_width * _install_progress + 0.5);
     if (progress_width != 0) {
     if (progress_width != 0) {
-      CGRect prog = { { bar_x, bar_y }, { progress_width, bar_height } };
+      CGRect prog = { { (CGFloat)bar_x, (CGFloat)bar_y }, { (CGFloat)progress_width, (CGFloat)bar_height } };
       CGContextSetFillColorWithColor(context, bar);
       CGContextSetFillColorWithColor(context, bar);
       CGContextFillRect(context, prog);
       CGContextFillRect(context, prog);
     }
     }
@@ -642,7 +642,7 @@ paint_progress_bar(CGContextRef context) {
       progress = block_travel * 2 - progress;
       progress = block_travel * 2 - progress;
     }
     }
 
 
-    CGRect prog = { { bar_x + progress, bar_y }, { block_width, bar_height } };
+    CGRect prog = { { (CGFloat)(bar_x + progress), (CGFloat)bar_y }, { (CGFloat)block_width, (CGFloat)bar_height } };
     CGContextSetFillColorWithColor(context, bar);
     CGContextSetFillColorWithColor(context, bar);
     CGContextFillRect(context, prog);
     CGContextFillRect(context, prog);
   }
   }
@@ -652,8 +652,8 @@ paint_progress_bar(CGContextRef context) {
     // We offset the border by half a pixel, so we'll be drawing the one-pixel
     // We offset the border by half a pixel, so we'll be drawing the one-pixel
     // line through the middle of a pixel, and it won't try to antialias
     // line through the middle of a pixel, and it won't try to antialias
     // itself into a half-black two-pixel line.
     // itself into a half-black two-pixel line.
-    CGRect border_rect = { { bar_x - 0.5, bar_y - 0.5 },
-                           { bar_width + 1, bar_height + 1 } };
+    CGRect border_rect = { { (CGFloat)(bar_x - 0.5), (CGFloat)(bar_y - 0.5) },
+                           { (CGFloat)(bar_width + 1), (CGFloat)(bar_height + 1) } };
 
 
     CGContextBeginPath(context);
     CGContextBeginPath(context);
     CGContextSetLineWidth(context, 1);
     CGContextSetLineWidth(context, 1);

+ 2 - 0
direct/src/showbase/AppRunnerGlobal.py

@@ -6,4 +6,6 @@ This is needed for apps that start themselves by importing
 DirectStart; it provides a place for these apps to look for
 DirectStart; it provides a place for these apps to look for
 the AppRunner at startup. """
 the AppRunner at startup. """
 
 
+#: Contains the global AppRunner instance, or None if this application
+#: was not run from the runtime environment.
 appRunner = None
 appRunner = None

+ 25 - 1
direct/src/showbase/Audio3DManager.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Audio3DManager class."""
 
 
 __all__ = ['Audio3DManager']
 __all__ = ['Audio3DManager']
 
 
@@ -289,3 +289,27 @@ class Audio3DManager:
             for sound in self.sound_dict[object]:
             for sound in self.sound_dict[object]:
                 self.detachSound(sound)
                 self.detachSound(sound)
 
 
+    #snake_case alias:
+    get_doppler_factor = getDopplerFactor
+    set_listener_velocity_auto = setListenerVelocityAuto
+    attach_listener = attachListener
+    set_distance_factor = setDistanceFactor
+    attach_sound_to_object = attachSoundToObject
+    get_drop_off_factor = getDropOffFactor
+    set_doppler_factor = setDopplerFactor
+    get_sounds_on_object = getSoundsOnObject
+    set_sound_velocity_auto = setSoundVelocityAuto
+    get_sound_max_distance = getSoundMaxDistance
+    load_sfx = loadSfx
+    get_distance_factor = getDistanceFactor
+    set_listener_velocity = setListenerVelocity
+    set_sound_max_distance = setSoundMaxDistance
+    get_sound_velocity = getSoundVelocity
+    get_listener_velocity = getListenerVelocity
+    set_sound_velocity = setSoundVelocity
+    set_sound_min_distance = setSoundMinDistance
+    get_sound_min_distance = getSoundMinDistance
+    detach_listener = detachListener
+    set_drop_off_factor = setDropOffFactor
+    detach_sound = detachSound
+

+ 3 - 1
direct/src/showbase/BufferViewer.py

@@ -1,4 +1,6 @@
-"""Undocumented Module"""
+"""Contains the BufferViewer class, which is used as a debugging aid
+when debugging render-to-texture effects.  It shows different views at
+the bottom of the screen showing the various render targets."""
 
 
 __all__ = ['BufferViewer']
 __all__ = ['BufferViewer']
 
 

+ 1 - 1
direct/src/showbase/BulletinBoard.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the BulletinBoard class."""
 
 
 __all__ = ['BulletinBoard']
 __all__ = ['BulletinBoard']
 
 

+ 1 - 1
direct/src/showbase/BulletinBoardWatcher.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the BulletinBoardWatcher class."""
 
 
 __all__ = ['BulletinBoardWatcher']
 __all__ = ['BulletinBoardWatcher']
 
 

+ 14 - 1
direct/src/showbase/DirectObject.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Defines the DirectObject class, a convenient class to inherit from if the
+object needs to be able to respond to events."""
 
 
 __all__ = ['DirectObject']
 __all__ = ['DirectObject']
 
 
@@ -100,3 +101,15 @@ class DirectObject:
             func = choice(getRepository()._crashOnProactiveLeakDetect,
             func = choice(getRepository()._crashOnProactiveLeakDetect,
                           self.notify.error, self.notify.warning)
                           self.notify.error, self.notify.warning)
             func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
             func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
+
+    #snake_case alias:
+    add_task = addTask
+    do_method_later = doMethodLater
+    detect_leaks = detectLeaks
+    accept_once = acceptOnce
+    ignore_all = ignoreAll
+    get_all_accepting = getAllAccepting
+    is_ignoring = isIgnoring
+    remove_all_tasks = removeAllTasks
+    remove_task = removeTask
+    is_accepting = isAccepting

+ 1 - 1
direct/src/showbase/EventGroup.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module defines the EventGroup class."""
 
 
 __all__ = ['EventGroup']
 __all__ = ['EventGroup']
 
 

+ 2 - 1
direct/src/showbase/EventManager.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Contains the EventManager class.  See :mod:`.EventManagerGlobal` for the
+global eventMgr instance."""
 
 
 __all__ = ['EventManager']
 __all__ = ['EventManager']
 
 

+ 2 - 1
direct/src/showbase/EventManagerGlobal.py

@@ -1,7 +1,8 @@
-"""Undocumented Module"""
+"""Contains the global :class:`.EventManager` instance."""
 
 
 __all__ = ['eventMgr']
 __all__ = ['eventMgr']
 
 
 from . import EventManager
 from . import EventManager
 
 
+#: The global event manager.
 eventMgr = EventManager.EventManager()
 eventMgr = EventManager.EventManager()

+ 1 - 1
direct/src/showbase/Factory.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Factory class."""
 
 
 __all__ = ['Factory']
 __all__ = ['Factory']
 
 

+ 2 - 4
direct/src/showbase/FindCtaPaths.py

@@ -1,7 +1,3 @@
-"""Undocumented Module"""
-
-__all__ = ['deCygwinify', 'getPaths']
-
 """This module is used only by the VR Studio programmers who are using
 """This module is used only by the VR Studio programmers who are using
 the ctattach tools.  It is imported before any other package, and its
 the ctattach tools.  It is imported before any other package, and its
 job is to figure out the correct paths to each of the packages.
 job is to figure out the correct paths to each of the packages.
@@ -10,6 +6,8 @@ This module is not needed if you are not using ctattach; in this case
 all of the Panda packages will be collected under a common directory,
 all of the Panda packages will be collected under a common directory,
 which you will presumably have already on your PYTHONPATH. """
 which you will presumably have already on your PYTHONPATH. """
 
 
+__all__ = ['deCygwinify', 'getPaths']
+
 import os
 import os
 import sys
 import sys
 
 

+ 1 - 1
direct/src/showbase/Finder.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains various utility functions."""
 
 
 __all__ = ['findClass', 'rebindClass', 'copyFuncs', 'replaceMessengerFunc', 'replaceTaskMgrFunc', 'replaceStateFunc', 'replaceCRFunc', 'replaceAIRFunc', 'replaceIvalFunc']
 __all__ = ['findClass', 'rebindClass', 'copyFuncs', 'replaceMessengerFunc', 'replaceTaskMgrFunc', 'replaceStateFunc', 'replaceCRFunc', 'replaceAIRFunc', 'replaceIvalFunc']
 
 

+ 1 - 1
direct/src/showbase/GarbageReport.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains utility classes for debugging memory leaks."""
 
 
 __all__ = ['FakeObject', '_createGarbage', 'GarbageReport', 'GarbageLogger']
 __all__ = ['FakeObject', '_createGarbage', 'GarbageReport', 'GarbageLogger']
 
 

Some files were not shown because too many files changed in this diff