Browse Source

Merge branch 'master' into deploy-ng

rdb 9 years ago
parent
commit
70386795f4
34 changed files with 621 additions and 382 deletions
  1. 36 1
      direct/src/showbase/PythonUtil.py
  2. 1 0
      doc/ReleaseNotes
  3. 6 3
      dtool/src/cppparser/cppFunctionType.cxx
  4. 1 1
      dtool/src/cppparser/cppFunctionType.h
  5. 32 1
      dtool/src/cppparser/cppPreprocessor.cxx
  6. 3 0
      dtool/src/cppparser/cppPreprocessor.h
  7. 1 0
      dtool/src/cppparser/cppScope.cxx
  8. 18 37
      dtool/src/cppparser/cppStructType.cxx
  9. 1 0
      dtool/src/cppparser/cppType.cxx
  10. 25 3
      makepanda/installer.nsi
  11. 125 70
      makepanda/makepanda.py
  12. 51 6
      makepanda/makepandacore.py
  13. 10 1
      panda/src/bullet/bulletBodyNode.cxx
  14. 1 1
      panda/src/bullet/bulletGhostNode.cxx
  15. 0 1
      panda/src/bullet/bulletRigidBodyNode.I
  16. 8 12
      panda/src/bullet/bulletRigidBodyNode.cxx
  17. 1 1
      panda/src/bullet/bulletRigidBodyNode.h
  18. 3 1
      panda/src/display/frameBufferProperties.cxx
  19. 92 33
      panda/src/display/graphicsStateGuardian.cxx
  20. 18 2
      panda/src/dxgsg9/wdxGraphicsPipe9.cxx
  21. 1 0
      panda/src/egg2pg/save_egg_file.cxx
  22. 0 2
      panda/src/ffmpeg/ffmpegAudioCursor.cxx
  23. 0 5
      panda/src/ffmpeg/ffmpegAudioCursor.h
  24. 39 16
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  25. 2 0
      panda/src/glstuff/glGraphicsStateGuardian_src.h
  26. 2 2
      panda/src/glstuff/glShaderContext_src.cxx
  27. 1 1
      panda/src/gobj/shader.cxx
  28. 19 0
      panda/src/gobj/texture.cxx
  29. 16 0
      panda/src/vision/openCVTexture.cxx
  30. 1 15
      panda/src/vision/openCVTexture.h
  31. 13 65
      panda/src/windisplay/winGraphicsPipe.cxx
  32. 0 11
      panda/src/windisplay/winGraphicsPipe.h
  33. 76 86
      panda/src/windisplay/winGraphicsWindow.cxx
  34. 18 5
      panda/src/windisplay/winGraphicsWindow.h

+ 36 - 1
direct/src/showbase/PythonUtil.py

@@ -38,7 +38,6 @@ import os
 import sys
 import sys
 import random
 import random
 import time
 import time
-import importlib
 
 
 __report_indent = 3
 __report_indent = 3
 
 
@@ -61,6 +60,42 @@ def Functor(function, *args, **kArgs):
     return functor
     return functor
 """
 """
 
 
+try:
+    import importlib
+except ImportError:
+    # Backward compatibility for Python 2.6.
+    def _resolve_name(name, package, level):
+        if not hasattr(package, 'rindex'):
+            raise ValueError("'package' not set to a string")
+        dot = len(package)
+        for x in xrange(level, 1, -1):
+            try:
+                dot = package.rindex('.', 0, dot)
+            except ValueError:
+                raise ValueError("attempted relative import beyond top-level "
+                                  "package")
+        return "%s.%s" % (package[:dot], name)
+
+    def import_module(name, package=None):
+        if name.startswith('.'):
+            if not package:
+                raise TypeError("relative imports require the 'package' argument")
+            level = 0
+            for character in name:
+                if character != '.':
+                    break
+                level += 1
+            name = _resolve_name(name[level:], package, level)
+        __import__(name)
+        return sys.modules[name]
+
+    imp = import_module('imp')
+    importlib = imp.new_module("importlib")
+    importlib._resolve_name = _resolve_name
+    importlib.import_module = import_module
+    sys.modules['importlib'] = importlib
+
+
 class Functor:
 class Functor:
     def __init__(self, function, *args, **kargs):
     def __init__(self, function, *args, **kargs):
         assert callable(function), "function should be a callable obj"
         assert callable(function), "function should be a callable obj"

+ 1 - 0
doc/ReleaseNotes

@@ -47,6 +47,7 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Fix compilation errors with Bullet 2.84
 * Fix compilation errors with Bullet 2.84
 * Fix exception when trying to pickle NodePathCollection objects
 * Fix exception when trying to pickle NodePathCollection objects
 * Fix error when trying to raise vectors to a power
 * Fix error when trying to raise vectors to a power
+* GLSL: fix error when legacy matrix generator inputs are mat3
 
 
 ------------------------  RELEASE 1.9.2  ------------------------
 ------------------------  RELEASE 1.9.2  ------------------------
 
 

+ 6 - 3
dtool/src/cppparser/cppFunctionType.cxx

@@ -326,14 +326,17 @@ as_function_type() {
  * This is similar to is_equal(), except it is more forgiving: it considers
  * This is similar to is_equal(), except it is more forgiving: it considers
  * the functions to be equivalent only if the return type and the types of all
  * the functions to be equivalent only if the return type and the types of all
  * parameters match.
  * parameters match.
+ *
+ * Note that this isn't symmetric to account for covariant return types.
  */
  */
 bool CPPFunctionType::
 bool CPPFunctionType::
-is_equivalent_function(const CPPFunctionType &other) const {
-  if (!_return_type->is_equivalent(*other._return_type)) {
+match_virtual_override(const CPPFunctionType &other) const {
+  if (!_return_type->is_equivalent(*other._return_type) &&
+      !_return_type->is_convertible_to(other._return_type)) {
     return false;
     return false;
   }
   }
 
 
-  if (_flags != other._flags) {
+  if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) {
     return false;
     return false;
   }
   }
 
 

+ 1 - 1
dtool/src/cppparser/cppFunctionType.h

@@ -84,7 +84,7 @@ public:
 
 
   virtual CPPFunctionType *as_function_type();
   virtual CPPFunctionType *as_function_type();
 
 
-  bool is_equivalent_function(const CPPFunctionType &other) const;
+  bool match_virtual_override(const CPPFunctionType &other) const;
 
 
   CPPIdentifier *_class_owner;
   CPPIdentifier *_class_owner;
 
 

+ 32 - 1
dtool/src/cppparser/cppPreprocessor.cxx

@@ -1461,7 +1461,6 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
       CPPManifest *other = result.first->second;
       CPPManifest *other = result.first->second;
       warning("redefinition of macro '" + manifest->_name + "'", loc);
       warning("redefinition of macro '" + manifest->_name + "'", loc);
       warning("previous definition is here", other->_loc);
       warning("previous definition is here", other->_loc);
-      delete other;
       result.first->second = manifest;
       result.first->second = manifest;
     }
     }
   }
   }
@@ -1679,6 +1678,38 @@ handle_pragma_directive(const string &args, const YYLTYPE &loc) {
     assert(it != _parsed_files.end());
     assert(it != _parsed_files.end());
     it->_pragma_once = true;
     it->_pragma_once = true;
   }
   }
+
+  char macro[64];
+  if (sscanf(args.c_str(), "push_macro ( \"%63[^\"]\" )", macro) == 1) {
+    // We just mark it as pushed for now, so that the next time someone tries
+    // to override it, we save the old value.
+    Manifests::iterator mi = _manifests.find(macro);
+    if (mi != _manifests.end()) {
+      _manifest_stack[macro].push_back(mi->second);
+    } else {
+      _manifest_stack[macro].push_back(NULL);
+    }
+
+  } else if (sscanf(args.c_str(), "pop_macro ( \"%63[^\"]\" )", macro) == 1) {
+    ManifestStack &stack = _manifest_stack[macro];
+    if (stack.size() > 0) {
+      CPPManifest *manifest = stack.back();
+      stack.pop_back();
+      Manifests::iterator mi = _manifests.find(macro);
+      if (manifest == NULL) {
+        // It was undefined when it was pushed, so make it undefined again.
+        if (mi != _manifests.end()) {
+          _manifests.erase(mi);
+        }
+      } else if (mi != _manifests.end()) {
+        mi->second = manifest;
+      } else {
+        _manifests.insert(Manifests::value_type(macro, manifest));
+      }
+    } else {
+      warning("pop_macro without matching push_macro", loc);
+    }
+  }
 }
 }
 
 
 /**
 /**

+ 3 - 0
dtool/src/cppparser/cppPreprocessor.h

@@ -72,6 +72,9 @@ public:
   typedef map<string, CPPManifest *> Manifests;
   typedef map<string, CPPManifest *> Manifests;
   Manifests _manifests;
   Manifests _manifests;
 
 
+  typedef pvector<CPPManifest *> ManifestStack;
+  map<string, ManifestStack> _manifest_stack;
+
   pvector<CPPFile::Source> _quote_include_kind;
   pvector<CPPFile::Source> _quote_include_kind;
   DSearchPath _quote_include_path;
   DSearchPath _quote_include_path;
   DSearchPath _angle_include_path;
   DSearchPath _angle_include_path;

+ 1 - 0
dtool/src/cppparser/cppScope.cxx

@@ -28,6 +28,7 @@
 #include "cppTemplateScope.h"
 #include "cppTemplateScope.h"
 #include "cppClassTemplateParameter.h"
 #include "cppClassTemplateParameter.h"
 #include "cppFunctionType.h"
 #include "cppFunctionType.h"
+#include "cppConstType.h"
 #include "cppUsing.h"
 #include "cppUsing.h"
 #include "cppBisonDefs.h"
 #include "cppBisonDefs.h"
 #include "indent.h"
 #include "indent.h"

+ 18 - 37
dtool/src/cppparser/cppStructType.cxx

@@ -13,6 +13,7 @@
 
 
 #include "cppStructType.h"
 #include "cppStructType.h"
 #include "cppTypedefType.h"
 #include "cppTypedefType.h"
+#include "cppReferenceType.h"
 #include "cppScope.h"
 #include "cppScope.h"
 #include "cppTypeProxy.h"
 #include "cppTypeProxy.h"
 #include "cppTemplateScope.h"
 #include "cppTemplateScope.h"
@@ -377,6 +378,10 @@ is_constructible(const CPPType *given_type) const {
     }
     }
   }
   }
 
 
+  if (is_abstract()) {
+    return false;
+  }
+
   // Check for a different constructor.
   // Check for a different constructor.
   CPPFunctionGroup *fgroup = get_constructor();
   CPPFunctionGroup *fgroup = get_constructor();
   if (fgroup != (CPPFunctionGroup *)NULL) {
   if (fgroup != (CPPFunctionGroup *)NULL) {
@@ -443,6 +448,10 @@ is_destructible() const {
  */
  */
 bool CPPStructType::
 bool CPPStructType::
 is_default_constructible(CPPVisibility min_vis) const {
 is_default_constructible(CPPVisibility min_vis) const {
+  if (is_abstract()) {
+    return false;
+  }
+
   CPPInstance *constructor = get_default_constructor();
   CPPInstance *constructor = get_default_constructor();
   if (constructor != (CPPInstance *)NULL) {
   if (constructor != (CPPInstance *)NULL) {
     // It has a default constructor.
     // It has a default constructor.
@@ -497,24 +506,6 @@ is_default_constructible(CPPVisibility min_vis) const {
     }
     }
   }
   }
 
 
-  // Check that we don't have pure virtual methods.
-  CPPScope::Functions::const_iterator fi;
-  for (fi = _scope->_functions.begin();
-       fi != _scope->_functions.end();
-       ++fi) {
-    CPPFunctionGroup *fgroup = (*fi).second;
-    CPPFunctionGroup::Instances::const_iterator ii;
-    for (ii = fgroup->_instances.begin();
-         ii != fgroup->_instances.end();
-         ++ii) {
-      CPPInstance *inst = (*ii);
-      if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
-        // Here's a pure virtual function.
-        return false;
-      }
-    }
-  }
-
   return true;
   return true;
 }
 }
 
 
@@ -523,6 +514,10 @@ is_default_constructible(CPPVisibility min_vis) const {
  */
  */
 bool CPPStructType::
 bool CPPStructType::
 is_copy_constructible(CPPVisibility min_vis) const {
 is_copy_constructible(CPPVisibility min_vis) const {
+  if (is_abstract()) {
+    return false;
+  }
+
   CPPInstance *constructor = get_copy_constructor();
   CPPInstance *constructor = get_copy_constructor();
   if (constructor != (CPPInstance *)NULL) {
   if (constructor != (CPPInstance *)NULL) {
     // It has a copy constructor.
     // It has a copy constructor.
@@ -580,24 +575,6 @@ is_copy_constructible(CPPVisibility min_vis) const {
     }
     }
   }
   }
 
 
-  // Check that we don't have pure virtual methods.
-  CPPScope::Functions::const_iterator fi;
-  for (fi = _scope->_functions.begin();
-       fi != _scope->_functions.end();
-       ++fi) {
-    CPPFunctionGroup *fgroup = (*fi).second;
-    CPPFunctionGroup::Instances::const_iterator ii;
-    for (ii = fgroup->_instances.begin();
-         ii != fgroup->_instances.end();
-         ++ii) {
-      CPPInstance *inst = (*ii);
-      if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
-        // Here's a pure virtual function.
-        return false;
-      }
-    }
-  }
-
   return true;
   return true;
 }
 }
 
 
@@ -619,6 +596,10 @@ is_move_constructible(CPPVisibility min_vis) const {
       return false;
       return false;
     }
     }
 
 
+    if (is_abstract()) {
+      return false;
+    }
+
     return true;
     return true;
   }
   }
 
 
@@ -1213,7 +1194,7 @@ get_virtual_funcs(VFunctions &funcs) const {
           CPPFunctionType *new_ftype = new_inst->_type->as_function_type();
           CPPFunctionType *new_ftype = new_inst->_type->as_function_type();
           assert(new_ftype != (CPPFunctionType *)NULL);
           assert(new_ftype != (CPPFunctionType *)NULL);
 
 
-          if (new_ftype->is_equivalent_function(*base_ftype)) {
+          if (new_ftype->match_virtual_override(*base_ftype)) {
             // It's a match!  We now know it's virtual.  Erase this function
             // It's a match!  We now know it's virtual.  Erase this function
             // from the list, so we can add it back in below.
             // from the list, so we can add it back in below.
             funcs.erase(vfi);
             funcs.erase(vfi);

+ 1 - 0
dtool/src/cppparser/cppType.cxx

@@ -16,6 +16,7 @@
 #include "cppPointerType.h"
 #include "cppPointerType.h"
 #include "cppReferenceType.h"
 #include "cppReferenceType.h"
 #include "cppStructType.h"
 #include "cppStructType.h"
+#include "cppTypedefType.h"
 #include "cppExtensionType.h"
 #include "cppExtensionType.h"
 #include <algorithm>
 #include <algorithm>
 
 

+ 25 - 3
makepanda/installer.nsi

@@ -31,6 +31,7 @@ SetCompressor ${COMPRESSOR}
 !include "Sections.nsh"
 !include "Sections.nsh"
 !include "WinMessages.nsh"
 !include "WinMessages.nsh"
 !include "WordFunc.nsh"
 !include "WordFunc.nsh"
+!include "x64.nsh"
 
 
 !define MUI_WELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
 !define MUI_WELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
 !define MUI_UNWELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
 !define MUI_UNWELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
@@ -120,6 +121,14 @@ Function runFunction
     ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
     ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
 FunctionEnd
 FunctionEnd
 
 
+Function .onInit
+    ${If} ${REGVIEW} = 64
+    ${AndIfNot} ${RunningX64}
+        MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows.  Please download and install the 32-bit version of Panda3D instead."
+        Abort
+    ${EndIf}
+FunctionEnd
+
 SectionGroup "Panda3D Libraries"
 SectionGroup "Panda3D Libraries"
     Section "Core Libraries" SecCore
     Section "Core Libraries" SecCore
         SectionIn 1 2 RO
         SectionIn 1 2 RO
@@ -134,12 +143,22 @@ SectionGroup "Panda3D Libraries"
         SetOutPath "$INSTDIR"
         SetOutPath "$INSTDIR"
         File "${BUILT}\LICENSE"
         File "${BUILT}\LICENSE"
         File /r /x CVS "${BUILT}\ReleaseNotes"
         File /r /x CVS "${BUILT}\ReleaseNotes"
-        SetOutPath $INSTDIR\bin
-        File /r /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
-        File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
+
         SetOutPath $INSTDIR\etc
         SetOutPath $INSTDIR\etc
         File /r "${BUILT}\etc\*"
         File /r "${BUILT}\etc\*"
 
 
+        SetOutPath $INSTDIR\bin
+        File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
+        File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
+
+        ; Before Windows 10, we need these stubs for the UCRT as well.
+        ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
+        ${If} $0 < 10
+            ClearErrors
+            File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
+            File /nonfatal "${BUILT}\bin\ucrtbase.dll"
+        ${Endif}
+
         SetDetailsPrint both
         SetDetailsPrint both
         DetailPrint "Installing models..."
         DetailPrint "Installing models..."
         SetDetailsPrint listonly
         SetDetailsPrint listonly
@@ -634,6 +653,9 @@ Section -post
     WriteRegStr HKCU "Software\Classes\.pz" "PerceivedType" "compressed"
     WriteRegStr HKCU "Software\Classes\.pz" "PerceivedType" "compressed"
     WriteRegStr HKCU "Software\Classes\.mf" "" "Panda3D.Multifile"
     WriteRegStr HKCU "Software\Classes\.mf" "" "Panda3D.Multifile"
     WriteRegStr HKCU "Software\Classes\.mf" "PerceivedType" "compressed"
     WriteRegStr HKCU "Software\Classes\.mf" "PerceivedType" "compressed"
+    WriteRegStr HKCU "Software\Classes\.prc" "" "inifile"
+    WriteRegStr HKCU "Software\Classes\.prc" "Content Type" "text/plain"
+    WriteRegStr HKCU "Software\Classes\.prc" "PerceivedType" "text"
 
 
     ; For convenience, if nobody registered .pyd, we will.
     ; For convenience, if nobody registered .pyd, we will.
     ReadRegStr $0 HKCR "Software\Classes\.pyd" ""
     ReadRegStr $0 HKCR "Software\Classes\.pyd" ""

+ 125 - 70
makepanda/makepanda.py

@@ -94,7 +94,6 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "PANDAPARTICLESYSTEM",                               # Built in particle system
   "PANDAPARTICLESYSTEM",                               # Built in particle system
   "CONTRIB",                                           # Experimental
   "CONTRIB",                                           # Experimental
   "SSE2", "NEON",                                      # Compiler features
   "SSE2", "NEON",                                      # Compiler features
-  "TOUCHINPUT",                                        # Touchinput interface (requires Windows 7)
 ])
 ])
 
 
 CheckPandaSourceTree()
 CheckPandaSourceTree()
@@ -170,7 +169,8 @@ def parseopts(args):
         "version=","lzma","no-python","threads=","outputdir=","override=",
         "version=","lzma","no-python","threads=","outputdir=","override=",
         "static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=",
         "static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=",
         "directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl",
         "directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl",
-        "universal", "target=", "arch=", "git-commit="]
+        "universal", "target=", "arch=", "git-commit=",
+        "use-touchinput", "no-touchinput"]
     anything = 0
     anything = 0
     optimize = ""
     optimize = ""
     target = None
     target = None
@@ -316,18 +316,6 @@ def parseopts(args):
             print("No Windows SDK version specified. Defaulting to '7.1'.")
             print("No Windows SDK version specified. Defaulting to '7.1'.")
             WINDOWS_SDK = '7.1'
             WINDOWS_SDK = '7.1'
 
 
-        is_win7 = False
-        if sys.platform == 'win32':
-            # Note: not available in cygwin.
-            winver = sys.getwindowsversion()
-            if winver[0] >= 6 and winver[1] >= 1:
-                is_win7 = True
-
-        if RUNTIME or not is_win7:
-            PkgDisable("TOUCHINPUT")
-    else:
-        PkgDisable("TOUCHINPUT")
-
     if clean_build and os.path.isdir(GetOutputDir()):
     if clean_build and os.path.isdir(GetOutputDir()):
         print("Deleting %s" % (GetOutputDir()))
         print("Deleting %s" % (GetOutputDir()))
         shutil.rmtree(GetOutputDir())
         shutil.rmtree(GetOutputDir())
@@ -1055,11 +1043,12 @@ def CompileCxx(obj,src,opts):
                 cmd += "/favor:blend "
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4273 "
             cmd += "/wd4996 /wd4275 /wd4273 "
 
 
-            # Enable Windows 7 interfaces if we need Touchinput.
-            if PkgSkip("TOUCHINPUT") == 0:
-                cmd += "/DWINVER=0x601 "
-            else:
-                cmd += "/DWINVER=0x501 "
+            # We still target Windows XP.
+            cmd += "/DWINVER=0x501 "
+            # Work around a WinXP/2003 bug when using VS 2015+.
+            if SDK.get("VISUALSTUDIO_VERSION") == '14.0':
+                cmd += "/Zc:threadSafeInit- "
+
             cmd += "/Fo" + obj + " /nologo /c"
             cmd += "/Fo" + obj + " /nologo /c"
             if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
             if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
                 cmd += " /arch:SSE2"
                 cmd += " /arch:SSE2"
@@ -1109,12 +1098,7 @@ def CompileCxx(obj,src,opts):
             if GetTargetArch() == 'x64':
             if GetTargetArch() == 'x64':
                 cmd += "/favor:blend "
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
             cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
-
-            # Enable Windows 7 interfaces if we need Touchinput.
-            if PkgSkip("TOUCHINPUT") == 0:
-                cmd += "/DWINVER=0x601 "
-            else:
-                cmd += "/DWINVER=0x501 "
+            cmd += "/DWINVER=0x501 "
             cmd += "/Fo" + obj + " /c"
             cmd += "/Fo" + obj + " /c"
             for x in ipath: cmd += " /I" + x
             for x in ipath: cmd += " /I" + x
             for (opt,dir) in INCDIRECTORIES:
             for (opt,dir) in INCDIRECTORIES:
@@ -1682,11 +1666,7 @@ def CompileLink(dll, obj, opts):
                 if 'NOARCH:' + arch.upper() not in opts:
                 if 'NOARCH:' + arch.upper() not in opts:
                     cmd += " -arch %s" % arch
                     cmd += " -arch %s" % arch
 
 
-        if "SYSROOT" in SDK:
-            cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
-
-        # Android-specific flags.
-        if GetTarget() == 'android':
+        elif GetTarget() == 'android':
             cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
             cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
             if GetTargetArch() == 'armv7a':
             if GetTargetArch() == 'armv7a':
                 cmd += " -march=armv7-a -Wl,--fix-cortex-a8"
                 cmd += " -march=armv7-a -Wl,--fix-cortex-a8"
@@ -1694,6 +1674,9 @@ def CompileLink(dll, obj, opts):
         else:
         else:
             cmd += " -pthread"
             cmd += " -pthread"
 
 
+        if "SYSROOT" in SDK:
+            cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
+
         if LDFLAGS != "":
         if LDFLAGS != "":
             cmd += " " + LDFLAGS
             cmd += " " + LDFLAGS
 
 
@@ -2126,7 +2109,6 @@ DTOOL_CONFIG=[
     ("REPORT_OPENSSL_ERRORS",          '1',                      '1'),
     ("REPORT_OPENSSL_ERRORS",          '1',                      '1'),
     ("USE_PANDAFILESTREAM",            '1',                      '1'),
     ("USE_PANDAFILESTREAM",            '1',                      '1'),
     ("USE_DELETED_CHAIN",              '1',                      '1'),
     ("USE_DELETED_CHAIN",              '1',                      '1'),
-    ("HAVE_WIN_TOUCHINPUT",            'UNDEF',                  'UNDEF'),
     ("HAVE_GLX",                       'UNDEF',                  '1'),
     ("HAVE_GLX",                       'UNDEF',                  '1'),
     ("HAVE_WGL",                       '1',                      'UNDEF'),
     ("HAVE_WGL",                       '1',                      'UNDEF'),
     ("HAVE_DX9",                       'UNDEF',                  'UNDEF'),
     ("HAVE_DX9",                       'UNDEF',                  'UNDEF'),
@@ -2233,11 +2215,7 @@ DTOOL_CONFIG=[
     ("HAVE_CG",                        'UNDEF',                  'UNDEF'),
     ("HAVE_CG",                        'UNDEF',                  'UNDEF'),
     ("HAVE_CGGL",                      'UNDEF',                  'UNDEF'),
     ("HAVE_CGGL",                      'UNDEF',                  'UNDEF'),
     ("HAVE_CGDX9",                     'UNDEF',                  'UNDEF'),
     ("HAVE_CGDX9",                     'UNDEF',                  'UNDEF'),
-    ("HAVE_FFMPEG",                    'UNDEF',                  'UNDEF'),
-    ("HAVE_SWSCALE",                   'UNDEF',                  'UNDEF'),
-    ("HAVE_SWRESAMPLE",                'UNDEF',                  'UNDEF'),
     ("HAVE_ARTOOLKIT",                 'UNDEF',                  'UNDEF'),
     ("HAVE_ARTOOLKIT",                 'UNDEF',                  'UNDEF'),
-    ("HAVE_OPENCV",                    'UNDEF',                  'UNDEF'),
     ("HAVE_DIRECTCAM",                 'UNDEF',                  'UNDEF'),
     ("HAVE_DIRECTCAM",                 'UNDEF',                  'UNDEF'),
     ("HAVE_SQUISH",                    'UNDEF',                  'UNDEF'),
     ("HAVE_SQUISH",                    'UNDEF',                  'UNDEF'),
     ("HAVE_CARBON",                    'UNDEF',                  'UNDEF'),
     ("HAVE_CARBON",                    'UNDEF',                  'UNDEF'),
@@ -2292,9 +2270,6 @@ def WriteConfigSettings():
             else:
             else:
                 dtool_config["HAVE_"+x] = 'UNDEF'
                 dtool_config["HAVE_"+x] = 'UNDEF'
 
 
-    if not PkgSkip("OPENCV"):
-        dtool_config["OPENCV_VER_23"] = '1' if OPENCV_VER_23 else 'UNDEF'
-
     dtool_config["HAVE_NET"] = '1'
     dtool_config["HAVE_NET"] = '1'
 
 
     if (PkgSkip("NVIDIACG")==0):
     if (PkgSkip("NVIDIACG")==0):
@@ -2351,9 +2326,6 @@ def WriteConfigSettings():
     if (PkgSkip("PYTHON") != 0):
     if (PkgSkip("PYTHON") != 0):
         dtool_config["HAVE_ROCKET_PYTHON"] = 'UNDEF'
         dtool_config["HAVE_ROCKET_PYTHON"] = 'UNDEF'
 
 
-    if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"):
-        dtool_config["HAVE_WIN_TOUCHINPUT"] = '1'
-
     if (GetOptimize() <= 3):
     if (GetOptimize() <= 3):
         dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
         dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
 
 
@@ -2781,8 +2753,13 @@ if (GetTarget() == 'darwin'):
     # OpenAL is not yet working well on OSX for us, so let's do this for now.
     # OpenAL is not yet working well on OSX for us, so let's do this for now.
     configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
     configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
 
 
-ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
-ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
+if GetTarget() == 'windows':
+    # Convert to Windows newlines.
+    ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc, newline='\r\n')
+    ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc, newline='\r\n')
+else:
+    ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
+    ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
 
 
 ##########################################################################################
 ##########################################################################################
 #
 #
@@ -2879,22 +2856,75 @@ if tp_dir is not None:
 
 
     if GetTarget() == 'windows':
     if GetTarget() == 'windows':
         CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
         CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
-        if not PkgSkip("PYTHON"):
-            pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
-            if (GetOptimize() <= 2): pydll += "_d.dll"
-            else: pydll += ".dll"
-            CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
-
-            for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
-                CopyFile(GetOutputDir() + "/bin/", fn)
-
-            if not RTDIST:
-                CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
-                if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
-                    CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
-                if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
-                    CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
-                ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
+
+        if not PkgSkip("PYTHON") and not RTDIST:
+            #XXX rdb I don't think we need to copy over the Python DLL, do we?
+            #pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
+            #if (GetOptimize() <= 2): pydll += "_d.dll"
+            #else: pydll += ".dll"
+            #CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
+
+            #for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
+            #    CopyFile(GetOutputDir() + "/bin/", fn)
+
+            # Copy the whole Python directory.
+            CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
+
+            # NB: Python does not always ship with the correct manifest/dll.
+            # Figure out the correct one to ship, and grab it from WinSxS dir.
+            manifest = GetOutputDir() + '/tmp/python.manifest'
+            if os.path.isfile(manifest):
+                os.unlink(manifest)
+            oscmd('mt -inputresource:"%s\\python.exe";#1 -out:"%s" -nologo' % (SDK["PYTHON"], manifest), True)
+
+            if os.path.isfile(manifest):
+                import xml.etree.ElementTree as ET
+                tree = ET.parse(manifest)
+                idents = tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity')
+            else:
+                idents = ()
+
+            for ident in tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity'):
+                sxs_name = '_'.join([
+                    ident.get('processorArchitecture'),
+                    ident.get('name').lower(),
+                    ident.get('publicKeyToken'),
+                    ident.get('version'),
+                ])
+
+                # Find the manifest matching these parameters.
+                pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', 'Manifests', sxs_name + '_*.manifest')
+                manifests = glob.glob(pattern)
+                if not manifests:
+                    print("%sWARNING:%s Could not locate manifest %s.  You may need to reinstall the Visual C++ Redistributable." % (GetColor("red"), GetColor(), pattern))
+                    continue
+
+                CopyFile(GetOutputDir() + "/python/" + ident.get('name') + ".manifest", manifests[0])
+
+                # Also copy the corresponding msvcr dll.
+                pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', sxs_name + '_*', 'msvcr*.dll')
+                for file in glob.glob(pattern):
+                    CopyFile(GetOutputDir() + "/python/", file)
+
+            # Copy python.exe to ppython.exe.
+            if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
+                CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
+            if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
+                CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
+            ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
+
+# Copy over the MSVC runtime.
+if GetTarget() == 'windows' and "VISUALSTUDIO" in SDK:
+    vcver = SDK["VISUALSTUDIO_VERSION"].replace('.', '')
+    crtname = "Microsoft.VC%s.CRT" % (vcver)
+    dir = os.path.join(SDK["VISUALSTUDIO"], "VC", "redist", GetTargetArch(), crtname)
+
+    if os.path.isfile(os.path.join(dir, "msvcr" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcr" + vcver + ".dll"))
+    if os.path.isfile(os.path.join(dir, "msvcp" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcp" + vcver + ".dll"))
+    if os.path.isfile(os.path.join(dir, "vcruntime" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "vcruntime" + vcver + ".dll"))
 
 
 ########################################################################
 ########################################################################
 ##
 ##
@@ -2902,8 +2932,14 @@ if tp_dir is not None:
 ##
 ##
 ########################################################################
 ########################################################################
 
 
-CopyFile(GetOutputDir()+"/", "doc/LICENSE")
-CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
+if GetTarget() == 'windows':
+    # Convert to Windows newlines so they can be opened by notepad.
+    WriteFile(GetOutputDir() + "/LICENSE", ReadFile("doc/LICENSE"), newline='\r\n')
+    WriteFile(GetOutputDir() + "/ReleaseNotes", ReadFile("doc/ReleaseNotes"), newline='\r\n')
+else:
+    CopyFile(GetOutputDir()+"/", "doc/LICENSE")
+    CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
+
 if (PkgSkip("PANDATOOL")==0):
 if (PkgSkip("PANDATOOL")==0):
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".mel")
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".mel")
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".ms")
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".ms")
@@ -4061,8 +4097,20 @@ if (not RUNTIME):
 #
 #
 
 
 if (PkgSkip("VISION") == 0) and (not RUNTIME):
 if (PkgSkip("VISION") == 0) and (not RUNTIME):
+  # We want to know whether we have ffmpeg so that we can override the .avi association.
+  if not PkgSkip("FFMPEG"):
+    DefSymbol("OPENCV", "HAVE_FFMPEG")
+  if not PkgSkip("OPENCV"):
+    DefSymbol("OPENCV", "HAVE_OPENCV")
+    if OPENCV_VER_23:
+        DefSymbol("OPENCV", "OPENCV_VER_23")
+
   OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS']
   OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS']
-  TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx')
+  TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx', dep=[
+    'dtool_have_ffmpeg.dat',
+    'dtool_have_opencv.dat',
+    'dtool_have_directcam.dat',
+  ])
 
 
   TargetAdd('libp3vision.dll', input='p3vision_composite1.obj')
   TargetAdd('libp3vision.dll', input='p3vision_composite1.obj')
   TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS)
@@ -4251,8 +4299,15 @@ if (PkgSkip("VRPN")==0 and not RUNTIME):
 # DIRECTORY: panda/src/ffmpeg
 # DIRECTORY: panda/src/ffmpeg
 #
 #
 if PkgSkip("FFMPEG") == 0 and not RUNTIME:
 if PkgSkip("FFMPEG") == 0 and not RUNTIME:
+  if not PkgSkip("SWSCALE"):
+    DefSymbol("FFMPEG", "HAVE_SWSCALE")
+  if not PkgSkip("SWRESAMPLE"):
+    DefSymbol("FFMPEG", "HAVE_SWRESAMPLE")
+
   OPTS=['DIR:panda/src/ffmpeg', 'BUILDING:FFMPEG', 'FFMPEG', 'SWSCALE', 'SWRESAMPLE']
   OPTS=['DIR:panda/src/ffmpeg', 'BUILDING:FFMPEG', 'FFMPEG', 'SWSCALE', 'SWRESAMPLE']
-  TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx')
+  TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx', dep=[
+    'dtool_have_swscale.dat', 'dtool_have_swresample.dat'])
+
   TargetAdd('libp3ffmpeg.dll', input='p3ffmpeg_composite1.obj')
   TargetAdd('libp3ffmpeg.dll', input='p3ffmpeg_composite1.obj')
   TargetAdd('libp3ffmpeg.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3ffmpeg.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3ffmpeg.dll', opts=OPTS)
   TargetAdd('libp3ffmpeg.dll', opts=OPTS)
@@ -4532,7 +4587,7 @@ if (GetTarget() == 'darwin' and PkgSkip("COCOA")==0 and PkgSkip("GL")==0 and not
   if (PkgSkip('PANDAFX')==0):
   if (PkgSkip('PANDAFX')==0):
     TargetAdd('libpandagl.dll', input='libpandafx.dll')
     TargetAdd('libpandagl.dll', input='libpandafx.dll')
   TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
-  TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA'])
+  TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA', 'CARBON'])
 
 
 #
 #
 # DIRECTORY: panda/src/osxdisplay/
 # DIRECTORY: panda/src/osxdisplay/
@@ -6792,9 +6847,9 @@ def MakeInstallerLinux():
         txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
         txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
         txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
         txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
         oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
         oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
-        oscmd("cd targetroot ; (find usr -type f -exec md5sum {} \;) >  DEBIAN/md5sums")
+        oscmd("cd targetroot && (find usr -type f -exec md5sum {} ;) > DEBIAN/md5sums")
         if (not RUNTIME):
         if (not RUNTIME):
-          oscmd("cd targetroot ; (find etc -type f -exec md5sum {} \;) >> DEBIAN/md5sums")
+          oscmd("cd targetroot && (find etc -type f -exec md5sum {} ;) >> DEBIAN/md5sums")
           WriteFile("targetroot/DEBIAN/conffiles","/etc/Config.prc\n")
           WriteFile("targetroot/DEBIAN/conffiles","/etc/Config.prc\n")
         WriteFile("targetroot/DEBIAN/postinst","#!/bin/sh\necho running ldconfig\nldconfig\n")
         WriteFile("targetroot/DEBIAN/postinst","#!/bin/sh\necho running ldconfig\nldconfig\n")
         oscmd("cp targetroot/DEBIAN/postinst targetroot/DEBIAN/postrm")
         oscmd("cp targetroot/DEBIAN/postinst targetroot/DEBIAN/postrm")
@@ -6822,7 +6877,7 @@ def MakeInstallerLinux():
 
 
         if RUNTIME:
         if RUNTIME:
             # The runtime doesn't export any useful symbols, so just query the dependencies.
             # The runtime doesn't export any useful symbols, so just query the dependencies.
-            oscmd("cd targetroot; %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
+            oscmd("cd targetroot && %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
             depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
             depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
             recommends = ""
             recommends = ""
         else:
         else:
@@ -6830,12 +6885,12 @@ def MakeInstallerLinux():
             pkg_dir = "debian/panda3d" + MAJOR_VERSION
             pkg_dir = "debian/panda3d" + MAJOR_VERSION
 
 
             # Generate a symbols file so that other packages can know which symbols we export.
             # Generate a symbols file so that other packages can know which symbols we export.
-            oscmd("cd targetroot; dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
+            oscmd("cd targetroot && dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
 
 
             # Library dependencies are required, binary dependencies are recommended.
             # Library dependencies are required, binary dependencies are recommended.
             # We explicitly exclude libphysx-extras since we don't want to depend on PhysX.
             # We explicitly exclude libphysx-extras since we don't want to depend on PhysX.
-            oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
-            oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
+            oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
+            oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
 
 
             # Parse the substvars files generated by dpkg-shlibdeps.
             # Parse the substvars files generated by dpkg-shlibdeps.
             depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()
             depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()

+ 51 - 6
makepanda/makepandacore.py

@@ -396,10 +396,16 @@ def CrossCompiling():
     return GetTarget() != GetHost()
     return GetTarget() != GetHost()
 
 
 def GetCC():
 def GetCC():
-    return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
+    if TARGET == 'darwin':
+        return os.environ.get('CC', TOOLCHAIN_PREFIX + 'clang')
+    else:
+        return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
 
 
 def GetCXX():
 def GetCXX():
-    return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
+    if TARGET == 'darwin':
+        return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'clang++')
+    else:
+        return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
 
 
 def GetStrip():
 def GetStrip():
     # Hack
     # Hack
@@ -512,6 +518,7 @@ def oscmd(cmd, ignoreError = False):
             exit("Cannot find "+exe+" on search path")
             exit("Cannot find "+exe+" on search path")
         res = os.spawnl(os.P_WAIT, exe_path, cmd)
         res = os.spawnl(os.P_WAIT, exe_path, cmd)
     else:
     else:
+        cmd = cmd.replace(';', '\\;')
         res = subprocess.call(cmd, shell=True)
         res = subprocess.call(cmd, shell=True)
         sig = res & 0x7F
         sig = res & 0x7F
         if (GetVerbose() and res != 0):
         if (GetVerbose() and res != 0):
@@ -966,7 +973,12 @@ def ReadBinaryFile(wfile):
         ex = sys.exc_info()[1]
         ex = sys.exc_info()[1]
         exit("Cannot read %s: %s" % (wfile, ex))
         exit("Cannot read %s: %s" % (wfile, ex))
 
 
-def WriteFile(wfile, data):
+def WriteFile(wfile, data, newline=None):
+    if newline is not None:
+        data = data.replace('\r\n', '\n')
+        data = data.replace('\r', '\n')
+        data = data.replace('\n', newline)
+
     try:
     try:
         dsthandle = open(wfile, "w")
         dsthandle = open(wfile, "w")
         dsthandle.write(data)
         dsthandle.write(data)
@@ -984,18 +996,24 @@ def WriteBinaryFile(wfile, data):
         ex = sys.exc_info()[1]
         ex = sys.exc_info()[1]
         exit("Cannot write to %s: %s" % (wfile, ex))
         exit("Cannot write to %s: %s" % (wfile, ex))
 
 
-def ConditionalWriteFile(dest, desiredcontents):
+def ConditionalWriteFile(dest, data, newline=None):
+    if newline is not None:
+        data = data.replace('\r\n', '\n')
+        data = data.replace('\r', '\n')
+        data = data.replace('\n', newline)
+
     try:
     try:
         rfile = open(dest, 'r')
         rfile = open(dest, 'r')
         contents = rfile.read(-1)
         contents = rfile.read(-1)
         rfile.close()
         rfile.close()
     except:
     except:
         contents = 0
         contents = 0
-    if contents != desiredcontents:
+
+    if contents != data:
         if VERBOSE:
         if VERBOSE:
             print("Writing %s" % (dest))
             print("Writing %s" % (dest))
         sys.stdout.flush()
         sys.stdout.flush()
-        WriteFile(dest, desiredcontents)
+        WriteFile(dest, data)
 
 
 def DeleteVCS(dir):
 def DeleteVCS(dir):
     if dir == "": dir = "."
     if dir == "": dir = "."
@@ -1984,6 +2002,11 @@ def SdkLocatePython(prefer_thirdparty_python=False):
          SDK["PYTHONVERSION"] = "python" + ver
          SDK["PYTHONVERSION"] = "python" + ver
          SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
          SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
 
 
+         # Avoid choosing the one in the thirdparty package dir.
+         PkgSetCustomLocation("PYTHON")
+         IncDirectory("PYTHON", py_fwx + "/include")
+         LibDirectory("PYTHON", "%s/usr/lib" % (SDK.get("MACOSX", "")))
+
          if sys.version[:3] != ver:
          if sys.version[:3] != ver:
              print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
              print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
 
 
@@ -2057,6 +2080,10 @@ def SdkLocateWindows(version = '7.1'):
         # Choose the latest version of the Windows 10 SDK.
         # Choose the latest version of the Windows 10 SDK.
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
 
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+
         if platsdk and os.path.isdir(platsdk):
         if platsdk and os.path.isdir(platsdk):
             incdirs = glob.glob(os.path.join(platsdk, 'Include', version + '.*.*'))
             incdirs = glob.glob(os.path.join(platsdk, 'Include', version + '.*.*'))
             max_version = ()
             max_version = ()
@@ -2089,6 +2116,10 @@ def SdkLocateWindows(version = '7.1'):
         # We chose a specific version of the Windows 10 SDK.  Verify it exists.
         # We chose a specific version of the Windows 10 SDK.  Verify it exists.
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
 
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+
         if version.count('.') == 2:
         if version.count('.') == 2:
             version += '.0'
             version += '.0'
 
 
@@ -2098,6 +2129,10 @@ def SdkLocateWindows(version = '7.1'):
     elif version == '8.1':
     elif version == '8.1':
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot81")
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot81")
 
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\8.1\\"
+
     elif version == '8.0':
     elif version == '8.0':
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot")
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot")
 
 
@@ -2403,9 +2438,19 @@ def SetupVisualStudioEnviron():
     # with Visual Studio 2015 requires use of the Universal CRT.
     # with Visual Studio 2015 requires use of the Universal CRT.
     if winsdk_ver == '7.1' and SDK["VISUALSTUDIO_VERSION"] == '14.0':
     if winsdk_ver == '7.1' and SDK["VISUALSTUDIO_VERSION"] == '14.0':
         win_kit = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
         win_kit = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
+
+        # Fallback in case we can't read the registry.
+        if not win_kit or not os.path.isdir(win_kit):
+            win_kit = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+        elif not win_kit.endswith('\\'):
+            win_kit += '\\'
+
         AddToPathEnv("LIB", win_kit + "Lib\\10.0.10150.0\\ucrt\\" + arch)
         AddToPathEnv("LIB", win_kit + "Lib\\10.0.10150.0\\ucrt\\" + arch)
         AddToPathEnv("INCLUDE", win_kit + "Include\\10.0.10150.0\\ucrt")
         AddToPathEnv("INCLUDE", win_kit + "Include\\10.0.10150.0\\ucrt")
 
 
+        # Copy the DLLs to the bin directory.
+        CopyAllFiles(GetOutputDir() + "/bin/", win_kit + "Redist\\ucrt\\DLLs\\" + arch + "\\")
+
 ########################################################################
 ########################################################################
 #
 #
 # Include and Lib directories.
 # Include and Lib directories.

+ 10 - 1
panda/src/bullet/bulletBodyNode.cxx

@@ -45,7 +45,16 @@ BulletBodyNode(const BulletBodyNode &copy) :
   _shapes(copy._shapes)
   _shapes(copy._shapes)
 {
 {
   if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
   if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
-    _shape = new btCompoundShape(copy._shape);
+    // btCompoundShape does not define a copy constructor.  Manually copy.
+    btCompoundShape *shape = new btCompoundShape;
+    _shape = shape;
+
+    btCompoundShape *copy_shape = (btCompoundShape *)copy._shape;
+    int num_children = copy_shape->getNumChildShapes();
+    for (int i = 0; i < num_children; ++i) {
+      shape->addChildShape(copy_shape->getChildTransform(i),
+                           copy_shape->getChildShape(i));
+    }
   }
   }
   else if (copy._shape && copy._shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
   else if (copy._shape && copy._shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
     _shape = new btEmptyShape();
     _shape = new btEmptyShape();

+ 1 - 1
panda/src/bullet/bulletGhostNode.cxx

@@ -55,7 +55,7 @@ void BulletGhostNode::
 parents_changed() {
 parents_changed() {
 
 
   Parents parents = get_parents();
   Parents parents = get_parents();
-  for (int i=0; i < parents.get_num_parents(); ++i) {
+  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
     PandaNode *parent = parents.get_parent(i);
     PandaNode *parent = parents.get_parent(i);
     TypeHandle type = parent->get_type();
     TypeHandle type = parent->get_type();
 
 

+ 0 - 1
panda/src/bullet/bulletRigidBodyNode.I

@@ -18,7 +18,6 @@ INLINE BulletRigidBodyNode::
 ~BulletRigidBodyNode() {
 ~BulletRigidBodyNode() {
 
 
   delete _rigid;
   delete _rigid;
-  delete _motion;
 }
 }
 
 
 /**
 /**

+ 8 - 12
panda/src/bullet/bulletRigidBodyNode.cxx

@@ -21,16 +21,12 @@ TypeHandle BulletRigidBodyNode::_type_handle;
  */
  */
 BulletRigidBodyNode::
 BulletRigidBodyNode::
 BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
 BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
-
-  // Motion state
-  _motion = new MotionState();
-
   // Mass properties
   // Mass properties
   btScalar mass(0.0);
   btScalar mass(0.0);
   btVector3 inertia(0, 0, 0);
   btVector3 inertia(0, 0, 0);
 
 
   // construction info
   // construction info
-  btRigidBody::btRigidBodyConstructionInfo ci(mass, _motion, _shape, inertia);
+  btRigidBody::btRigidBodyConstructionInfo ci(mass, &_motion, _shape, inertia);
 
 
   // Additional damping
   // Additional damping
   if (bullet_additional_damping) {
   if (bullet_additional_damping) {
@@ -52,13 +48,13 @@ BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
  */
  */
 BulletRigidBodyNode::
 BulletRigidBodyNode::
 BulletRigidBodyNode(const BulletRigidBodyNode &copy) :
 BulletRigidBodyNode(const BulletRigidBodyNode &copy) :
-  BulletBodyNode(copy)
+  BulletBodyNode(copy),
+  _motion(copy._motion)
 {
 {
-  _motion = new MotionState(*copy._motion);
   _rigid = new btRigidBody(*copy._rigid);
   _rigid = new btRigidBody(*copy._rigid);
   _rigid->setUserPointer(this);
   _rigid->setUserPointer(this);
   _rigid->setCollisionShape(_shape);
   _rigid->setCollisionShape(_shape);
-  _rigid->setMotionState(_motion);
+  _rigid->setMotionState(&_motion);
 }
 }
 
 
 /**
 /**
@@ -280,7 +276,7 @@ apply_central_impulse(const LVector3 &impulse) {
 void BulletRigidBodyNode::
 void BulletRigidBodyNode::
 transform_changed() {
 transform_changed() {
 
 
-  if (_motion->sync_disabled()) return;
+  if (_motion.sync_disabled()) return;
 
 
   NodePath np = NodePath::any_path((PandaNode *)this);
   NodePath np = NodePath::any_path((PandaNode *)this);
   CPT(TransformState) ts = np.get_net_transform();
   CPT(TransformState) ts = np.get_net_transform();
@@ -290,7 +286,7 @@ transform_changed() {
   // transform within the motion state.  For dynamic bodies we need to store
   // transform within the motion state.  For dynamic bodies we need to store
   // the net scale within the motion state, since Bullet might update the
   // the net scale within the motion state, since Bullet might update the
   // transform via MotionState::setWorldTransform.
   // transform via MotionState::setWorldTransform.
-  _motion->set_net_transform(ts);
+  _motion.set_net_transform(ts);
 
 
   // For dynamic or static bodies we directly apply the new transform.
   // For dynamic or static bodies we directly apply the new transform.
   if (!is_kinematic()) {
   if (!is_kinematic()) {
@@ -334,7 +330,7 @@ sync_p2b() {
 void BulletRigidBodyNode::
 void BulletRigidBodyNode::
 sync_b2p() {
 sync_b2p() {
 
 
-  _motion->sync_b2p((PandaNode *)this);
+  _motion.sync_b2p((PandaNode *)this);
 }
 }
 
 
 /**
 /**
@@ -589,7 +585,7 @@ pick_dirty_flag() {
 bool BulletRigidBodyNode::
 bool BulletRigidBodyNode::
 pick_dirty_flag() {
 pick_dirty_flag() {
 
 
-  return _motion->pick_dirty_flag();
+  return _motion.pick_dirty_flag();
 }
 }
 
 
 /**
 /**

+ 1 - 1
panda/src/bullet/bulletRigidBodyNode.h

@@ -124,7 +124,7 @@ private:
     bool _was_dirty;
     bool _was_dirty;
   };
   };
 
 
-  MotionState *_motion;
+  MotionState _motion;
   btRigidBody *_rigid;
   btRigidBody *_rigid;
 
 
 public:
 public:

+ 3 - 1
panda/src/display/frameBufferProperties.cxx

@@ -659,7 +659,7 @@ setup_color_texture(Texture *tex) const {
   // as the below one would be generated dynamically by the GSG to reflect the
   // as the below one would be generated dynamically by the GSG to reflect the
   // formats that are supported for render-to-texture.
   // formats that are supported for render-to-texture.
 
 
-  static const int num_formats = 15;
+  static const int num_formats = 17;
   static const struct {
   static const struct {
     unsigned char color_bits, red_bits, green_bits, blue_bits, alpha_bits;
     unsigned char color_bits, red_bits, green_bits, blue_bits, alpha_bits;
     bool has_float;
     bool has_float;
@@ -669,6 +669,8 @@ setup_color_texture(Texture *tex) const {
     {  1,  1,  1,  0,  0, false, Texture::F_rg },
     {  1,  1,  1,  0,  0, false, Texture::F_rg },
     {  1,  1,  1,  1,  0, false, Texture::F_rgb },
     {  1,  1,  1,  1,  0, false, Texture::F_rgb },
     {  1,  1,  1,  1,  1, false, Texture::F_rgba },
     {  1,  1,  1,  1,  1, false, Texture::F_rgba },
+    {  8,  8,  0,  0,  0, false, Texture::F_red },
+    { 16,  8,  8,  0,  0, false, Texture::F_rg },
     { 24,  8,  8,  8,  0, false, Texture::F_rgb8 },
     { 24,  8,  8,  8,  0, false, Texture::F_rgb8 },
     { 32,  8,  8,  8,  8, false, Texture::F_rgba8 },
     { 32,  8,  8,  8,  8, false, Texture::F_rgba8 },
     { 16, 16,  0,  0,  0,  true, Texture::F_r16 },
     { 16, 16,  0,  0,  0,  true, Texture::F_r16 },

+ 92 - 33
panda/src/display/graphicsStateGuardian.cxx

@@ -1363,8 +1363,18 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
       }
       }
     }
     }
 
 
-    // TODO: dummy light
-    nassertr(false, &LMatrix4::ident_mat());
+    // Apply the default OpenGL lights otherwise.
+    // Special exception for light 0, which defaults to white.
+    if (index == 0) {
+      string basename = name->get_basename();
+      if (basename == "color" || basename == "diffuse") {
+        t.set_row(3, _light_color_scale);
+        return &t;
+      } else if (basename == "specular") {
+        return &LMatrix4::ones_mat();
+      }
+    }
+    return fetch_specified_member(NodePath(), name, t);
   }
   }
   default:
   default:
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
@@ -1395,8 +1405,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
 
 
+  PandaNode *node = NULL;
+  if (!np.is_empty()) {
+    node = np.node();
+  }
+
   if (attrib == IN_color) {
   if (attrib == IN_color) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     LColor c = light->get_color();
     LColor c = light->get_color();
     c.componentwise_mult(_light_color_scale);
     c.componentwise_mult(_light_color_scale);
@@ -1404,9 +1422,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_ambient) {
   } else if (attrib == IN_ambient) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       LColor c = light->get_color();
       LColor c = light->get_color();
       c.componentwise_mult(_light_color_scale);
       c.componentwise_mult(_light_color_scale);
       t.set_row(3, c);
       t.set_row(3, c);
@@ -1417,9 +1438,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_diffuse) {
   } else if (attrib == IN_diffuse) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no diffuse color.
       // Ambient light has no diffuse color.
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
     } else {
     } else {
@@ -1430,19 +1454,25 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_specular) {
   } else if (attrib == IN_specular) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     t.set_row(3, light->get_specular_color());
     t.set_row(3, light->get_specular_color());
     return &t;
     return &t;
 
 
   } else if (attrib == IN_position) {
   } else if (attrib == IN_position) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no position.
       // Ambient light has no position.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1451,7 +1481,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1466,13 +1496,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_halfVector) {
   } else if (attrib == IN_halfVector) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no half-vector.
       // Ambient light has no half-vector.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1484,7 +1517,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1502,13 +1535,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotDirection) {
   } else if (attrib == IN_spotDirection) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node == (PandaNode *)NULL) {
+      t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no spot direction.
       // Ambient light has no spot direction.
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1523,9 +1559,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotCutoff) {
   } else if (attrib == IN_spotCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1539,9 +1576,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotCosCutoff) {
   } else if (attrib == IN_spotCosCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1553,51 +1591,72 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       t.set_row(3, LVecBase4(-1));
       t.set_row(3, LVecBase4(-1));
       return &t;
       return &t;
     }
     }
+
   } else if (attrib == IN_spotExponent) {
   } else if (attrib == IN_spotExponent) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_exponent()));
     t.set_row(3, LVecBase4(light->get_exponent()));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_attenuation) {
   } else if (attrib == IN_attenuation) {
-    Light *light = np.node()->as_light();
-    nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
+    if (node != (PandaNode *)NULL) {
+      Light *light = node->as_light();
+      nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
 
-    t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+      t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+    } else {
+      t.set_row(3, LVecBase4(1, 0, 0, 0));
+    }
     return &t;
     return &t;
 
 
   } else if (attrib == IN_constantAttenuation) {
   } else if (attrib == IN_constantAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ones_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_linearAttenuation) {
   } else if (attrib == IN_linearAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_quadraticAttenuation) {
   } else if (attrib == IN_quadraticAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_shadowMatrix) {
   } else if (attrib == IN_shadowMatrix) {
-    LensNode *lnode;
-    DCAST_INTO_R(lnode, np.node(), &LMatrix4::ident_mat());
-    Lens *lens = lnode->get_lens();
-
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.5f, 0.5f, 0.5f, 1.0f);
                                   0.5f, 0.5f, 0.5f, 1.0f);
 
 
+    if (node == (PandaNode *)NULL) {
+      return &biasmat;
+    }
+
+    LensNode *lnode;
+    DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
+    Lens *lens = lnode->get_lens();
+
     t = get_external_transform()->get_mat() *
     t = get_external_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *

+ 18 - 2
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -19,6 +19,16 @@
 
 
 TypeHandle wdxGraphicsPipe9::_type_handle;
 TypeHandle wdxGraphicsPipe9::_type_handle;
 
 
+static bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) {
+  *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName);
+  if (*pFn == NULL) {
+    wdxdisplay9_cat.error()
+      << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() <<endl;
+    return false;
+  }
+  return true;
+}
+
 #define LOWVIDMEMTHRESHOLD 5700000  // 4MB cards should fall below this
 #define LOWVIDMEMTHRESHOLD 5700000  // 4MB cards should fall below this
 #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000  // if # is > 1MB, card is lying and I cant tell what it is
 #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000  // if # is > 1MB, card is lying and I cant tell what it is
 #define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF
 #define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF
@@ -154,7 +164,10 @@ make_output(const string &name,
  */
  */
 bool wdxGraphicsPipe9::
 bool wdxGraphicsPipe9::
 init() {
 init() {
-  if (!MyLoadLib(_hDDrawDLL, "ddraw.dll")) {
+  _hDDrawDLL = LoadLibrary("ddraw.dll");
+  if (_hDDrawDLL == NULL) {
+    wdxdisplay9_cat.error()
+      << "LoadLibrary failed for ddraw.dll, error=" << GetLastError() <<endl;
     goto error;
     goto error;
   }
   }
 
 
@@ -166,7 +179,10 @@ init() {
     goto error;
     goto error;
   }
   }
 
 
-  if (!MyLoadLib(_hD3D9_DLL, "d3d9.dll")) {
+  _hD3D9_DLL = LoadLibrary("d3d9.dll");
+  if (_hD3D9_DLL == NULL) {
+    wdxdisplay9_cat.error()
+      << "LoadLibrary failed for d3d9.dll, error=" << GetLastError() <<endl;
     goto error;
     goto error;
   }
   }
 
 

+ 1 - 0
panda/src/egg2pg/save_egg_file.cxx

@@ -14,6 +14,7 @@
 #include "save_egg_file.h"
 #include "save_egg_file.h"
 #include "eggSaver.h"
 #include "eggSaver.h"
 #include "config_egg2pg.h"
 #include "config_egg2pg.h"
+#include "modelRoot.h"
 #include "sceneGraphReducer.h"
 #include "sceneGraphReducer.h"
 #include "virtualFileSystem.h"
 #include "virtualFileSystem.h"
 #include "config_util.h"
 #include "config_util.h"

+ 0 - 2
panda/src/ffmpeg/ffmpegAudioCursor.cxx

@@ -50,9 +50,7 @@ FfmpegAudioCursor(FfmpegAudio *src) :
   _packet_data(0),
   _packet_data(0),
   _format_ctx(0),
   _format_ctx(0),
   _audio_ctx(0),
   _audio_ctx(0),
-#ifdef HAVE_SWRESAMPLE
   _resample_ctx(0),
   _resample_ctx(0),
-#endif
   _buffer(0),
   _buffer(0),
   _buffer_alloc(0),
   _buffer_alloc(0),
   _frame(0)
   _frame(0)

+ 0 - 5
panda/src/ffmpeg/ffmpegAudioCursor.h

@@ -31,10 +31,7 @@ struct AVFormatContext;
 struct AVCodecContext;
 struct AVCodecContext;
 struct AVStream;
 struct AVStream;
 struct AVPacket;
 struct AVPacket;
-
-#ifdef HAVE_SWRESAMPLE
 struct SwrContext;
 struct SwrContext;
-#endif
 
 
 /**
 /**
  * A stream that generates a sequence of audio samples.
  * A stream that generates a sequence of audio samples.
@@ -72,9 +69,7 @@ protected:
   int       _buffer_head;
   int       _buffer_head;
   int       _buffer_tail;
   int       _buffer_tail;
 
 
-#ifdef HAVE_SWRESAMPLE
   SwrContext *_resample_ctx;
   SwrContext *_resample_ctx;
-#endif
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 39 - 16
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1356,6 +1356,8 @@ reset() {
       get_extension_func("glMapBuffer");
       get_extension_func("glMapBuffer");
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
       get_extension_func("glUnmapBuffer");
       get_extension_func("glUnmapBuffer");
+    _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
+      get_extension_func("glGetBufferSubData");
 #endif
 #endif
   }
   }
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
@@ -1376,6 +1378,8 @@ reset() {
       get_extension_func("glMapBufferARB");
       get_extension_func("glMapBufferARB");
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
       get_extension_func("glUnmapBufferARB");
       get_extension_func("glUnmapBufferARB");
+    _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
+      get_extension_func("glGetBufferSubDataARB");
   }
   }
 #endif  // OPENGLES_1
 #endif  // OPENGLES_1
 
 
@@ -12644,20 +12648,26 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   GLint minfilter, magfilter;
   GLint minfilter, magfilter;
   GLfloat border_color[4];
   GLfloat border_color[4];
 
 
-  glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
-  glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
-  wrap_w = GL_REPEAT;
+#ifdef OPENGLES
+  if (true) {
+#else
+  if (target != GL_TEXTURE_BUFFER) {
+#endif
+    glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
+    glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
+    wrap_w = GL_REPEAT;
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
-  if (_supports_3d_texture) {
-    glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
-  }
+    if (_supports_3d_texture) {
+      glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
+    }
 #endif
 #endif
-  glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
-  glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
+    glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
+    glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
 
 
 #ifndef OPENGLES
 #ifndef OPENGLES
-  glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
+    glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
 #endif
 #endif
+  }
 
 
   GLenum page_target = target;
   GLenum page_target = target;
   if (target == GL_TEXTURE_CUBE_MAP) {
   if (target == GL_TEXTURE_CUBE_MAP) {
@@ -13122,14 +13132,20 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   tex->set_component_type(type);
   tex->set_component_type(type);
   tex->set_format(format);
   tex->set_format(format);
 
 
-  tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
-  tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
-  tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
-  tex->set_border_color(LColor(border_color[0], border_color[1],
-                               border_color[2], border_color[3]));
+#ifdef OPENGLES
+  if (true) {
+#else
+  if (target != GL_TEXTURE_BUFFER) {
+#endif
+    tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
+    tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
+    tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
+    tex->set_border_color(LColor(border_color[0], border_color[1],
+                                 border_color[2], border_color[3]));
 
 
-  tex->set_minfilter(get_panda_filter_type(minfilter));
-  // tex->set_magfilter(get_panda_filter_type(magfilter));
+    tex->set_minfilter(get_panda_filter_type(minfilter));
+    //tex->set_magfilter(get_panda_filter_type(magfilter));
+  }
 
 
   PTA_uchar image;
   PTA_uchar image;
   size_t page_size = 0;
   size_t page_size = 0;
@@ -13216,6 +13232,13 @@ extract_texture_image(PTA_uchar &image, size_t &page_size,
       }
       }
     }
     }
 
 
+#ifndef OPENGLES
+  } else if (target == GL_TEXTURE_BUFFER) {
+    // In the case of a buffer texture, we need to get it from the buffer.
+    image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
+    _glGetBufferSubData(target, 0, image.size(), image.p());
+#endif
+
   } else if (compression == Texture::CM_off) {
   } else if (compression == Texture::CM_off) {
     // An uncompressed 1-d, 2-d, or 3-d texture.
     // An uncompressed 1-d, 2-d, or 3-d texture.
     image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
     image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));

+ 2 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -247,6 +247,7 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VPROC) (GLuint index, const GLuin
 typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
 typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
 typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
 typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
 typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
 typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data);
 #endif  // OPENGLES
 #endif  // OPENGLES
 #endif  // __EDG__
 #endif  // __EDG__
 
 
@@ -801,6 +802,7 @@ public:
 #ifndef OPENGLES
 #ifndef OPENGLES
   PFNGLMAPBUFFERPROC _glMapBuffer;
   PFNGLMAPBUFFERPROC _glMapBuffer;
   PFNGLUNMAPBUFFERPROC _glUnmapBuffer;
   PFNGLUNMAPBUFFERPROC _glUnmapBuffer;
+  PFNGLGETBUFFERSUBDATAPROC _glGetBufferSubData;
 #endif
 #endif
 
 
 #ifdef OPENGLES
 #ifdef OPENGLES

+ 2 - 2
panda/src/glstuff/glShaderContext_src.cxx

@@ -901,7 +901,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._func = Shader::SMF_first;
       bind._func = Shader::SMF_first;
       bind._part[0] = Shader::SMO_attr_material;
       bind._part[0] = Shader::SMO_attr_material;
       bind._arg[0] = NULL;
       bind._arg[0] = NULL;
-      bind._dep[0] = Shader::SSD_general | Shader::SSD_material;
+      bind._dep[0] = Shader::SSD_general | Shader::SSD_material | Shader::SSD_frame;
       bind._part[1] = Shader::SMO_identity;
       bind._part[1] = Shader::SMO_identity;
       bind._arg[1] = NULL;
       bind._arg[1] = NULL;
       bind._dep[1] = Shader::SSD_NONE;
       bind._dep[1] = Shader::SSD_NONE;
@@ -2446,8 +2446,8 @@ update_shader_texture_bindings(ShaderContext *prev) {
         if (gtc != (TextureContext*)NULL) {
         if (gtc != (TextureContext*)NULL) {
           input._gtc = gtc;
           input._gtc = gtc;
 
 
-          gl_tex = gtc->_index;
           _glgsg->update_texture(gtc, true);
           _glgsg->update_texture(gtc, true);
+          gl_tex = gtc->_index;
 
 
           if (gtc->needs_barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)) {
           if (gtc->needs_barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)) {
             barriers |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
             barriers |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;

+ 1 - 1
panda/src/gobj/shader.cxx

@@ -376,7 +376,7 @@ cp_dependency(ShaderMatInput inp) {
     return SSD_NONE;
     return SSD_NONE;
   }
   }
   if (inp == SMO_attr_material || inp == SMO_attr_material2) {
   if (inp == SMO_attr_material || inp == SMO_attr_material2) {
-    dep |= SSD_material;
+    dep |= SSD_material | SSD_frame;
   }
   }
   if (inp == SMO_attr_color) {
   if (inp == SMO_attr_color) {
     dep |= SSD_color;
     dep |= SSD_color;

+ 19 - 0
panda/src/gobj/texture.cxx

@@ -7411,6 +7411,9 @@ do_set_simple_ram_image(CData *cdata, CPTA_uchar image, int x_size, int y_size)
  */
  */
 int Texture::
 int Texture::
 do_get_expected_num_mipmap_levels(const CData *cdata) const {
 do_get_expected_num_mipmap_levels(const CData *cdata) const {
+  if (cdata->_texture_type == Texture::TT_buffer_texture) {
+    return 1;
+  }
   int size = max(cdata->_x_size, cdata->_y_size);
   int size = max(cdata->_x_size, cdata->_y_size);
   if (cdata->_texture_type == Texture::TT_3d_texture) {
   if (cdata->_texture_type == Texture::TT_3d_texture) {
     size = max(size, cdata->_z_size);
     size = max(size, cdata->_z_size);
@@ -10126,6 +10129,14 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
     cdata->_simple_image_date_generated = scan.get_int32();
     cdata->_simple_image_date_generated = scan.get_int32();
 
 
     size_t u_size = scan.get_uint32();
     size_t u_size = scan.get_uint32();
+
+    // Protect against large allocation.
+    if (u_size > scan.get_remaining_size()) {
+      gobj_cat.error()
+        << "simple RAM image extends past end of datagram, is texture corrupt?\n";
+      return;
+    }
+
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     scan.extract_bytes(image.p(), u_size);
     scan.extract_bytes(image.p(), u_size);
 
 
@@ -10180,6 +10191,14 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) {
 
 
     // fill the cdata->_image buffer with image data
     // fill the cdata->_image buffer with image data
     size_t u_size = scan.get_uint32();
     size_t u_size = scan.get_uint32();
+
+    // Protect against large allocation.
+    if (u_size > scan.get_remaining_size()) {
+      gobj_cat.error()
+        << "RAM image " << n << " extends past end of datagram, is texture corrupt?\n";
+      return;
+    }
+
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     scan.extract_bytes(image.p(), u_size);
     scan.extract_bytes(image.p(), u_size);
 
 

+ 16 - 0
panda/src/vision/openCVTexture.cxx

@@ -21,6 +21,22 @@
 #include "bamReader.h"
 #include "bamReader.h"
 #include "bamCacheRecord.h"
 #include "bamCacheRecord.h"
 
 
+// This symbol is predefined by the Panda3D build system to select whether we
+// are using the OpenCV 2.3 or later interface, or if it is not defined, we
+// are using the original interface.
+#ifdef OPENCV_VER_23
+
+#include <opencv2/core/core.hpp>
+// #include <opencv2videovideo.hpp>
+#include <opencv2/highgui/highgui.hpp>
+
+#else
+#include <cv.h>
+#include <cxcore.h>
+#include <highgui.h>
+
+#endif  // OPENCV_VER_23
+
 TypeHandle OpenCVTexture::_type_handle;
 TypeHandle OpenCVTexture::_type_handle;
 
 
 /**
 /**

+ 1 - 15
panda/src/vision/openCVTexture.h

@@ -19,21 +19,7 @@
 
 
 #include "videoTexture.h"
 #include "videoTexture.h"
 
 
-// This symbol is predefined by the Panda3D build system to select whether we
-// are using the OpenCV 2.3 or later interface, or if it is not defined, we
-// are using the original interface.
-#ifdef OPENCV_VER_23
-
-#include <opencv2/core/core.hpp>
-// #include <opencv2videovideo.hpp>
-#include <opencv2/highgui/highgui.hpp>
-
-#else
-#include <cv.h>
-#include <cxcore.h>
-#include <highgui.h>
-
-#endif  // OPENCV_VER_23
+struct CvCapture;
 
 
 /**
 /**
  * A specialization on VideoTexture that takes its input using the CV library,
  * A specialization on VideoTexture that takes its input using the CV library,

+ 13 - 65
panda/src/windisplay/winGraphicsPipe.cxx

@@ -47,15 +47,12 @@ typedef struct _PROCESSOR_POWER_INFORMATION {
 } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
 } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
 
 
 typedef BOOL (WINAPI *GetProcessMemoryInfoType) (HANDLE Process, PROCESS_MEMORY_COUNTERS *ppsmemCounters, DWORD cb);
 typedef BOOL (WINAPI *GetProcessMemoryInfoType) (HANDLE Process, PROCESS_MEMORY_COUNTERS *ppsmemCounters, DWORD cb);
-typedef BOOL (WINAPI *GlobalMemoryStatusExType) (LPMEMORYSTATUSEX lpBuffer);
 typedef long (__stdcall *CallNtPowerInformationType) (POWER_INFORMATION_LEVEL information_level, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength);
 typedef long (__stdcall *CallNtPowerInformationType) (POWER_INFORMATION_LEVEL information_level, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength);
 
 
 static int initialize = false;
 static int initialize = false;
 static HMODULE psapi_dll = 0;
 static HMODULE psapi_dll = 0;
-static HMODULE kernel32_dll = 0;
 static HMODULE power_dll = 0;
 static HMODULE power_dll = 0;
 static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0;
 static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0;
-static GlobalMemoryStatusExType GlobalMemoryStatusExFunction = 0;
 static CallNtPowerInformationType CallNtPowerInformationFunction = 0;
 static CallNtPowerInformationType CallNtPowerInformationFunction = 0;
 
 
 void get_memory_information (DisplayInformation *display_information) {
 void get_memory_information (DisplayInformation *display_information) {
@@ -65,39 +62,19 @@ void get_memory_information (DisplayInformation *display_information) {
       GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress(psapi_dll, "GetProcessMemoryInfo");
       GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress(psapi_dll, "GetProcessMemoryInfo");
     }
     }
 
 
-    kernel32_dll = LoadLibrary("kernel32.dll");
-    if (kernel32_dll) {
-      GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress(kernel32_dll, "GlobalMemoryStatusEx");
-    }
-
     initialize = true;
     initialize = true;
   }
   }
 
 
-  if (GlobalMemoryStatusExFunction) {
-    MEMORYSTATUSEX memory_status;
-
-    memory_status.dwLength = sizeof(MEMORYSTATUSEX);
-    if (GlobalMemoryStatusExFunction(&memory_status)) {
-      display_information->_physical_memory = memory_status.ullTotalPhys;
-      display_information->_available_physical_memory = memory_status.ullAvailPhys;
-      display_information->_page_file_size = memory_status.ullTotalPageFile;
-      display_information->_available_page_file_size = memory_status.ullAvailPageFile;
-      display_information->_process_virtual_memory = memory_status.ullTotalVirtual;
-      display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual;
-      display_information->_memory_load = memory_status.dwMemoryLoad;
-    }
-  } else {
-    MEMORYSTATUS memory_status;
-
-    memory_status.dwLength = sizeof(MEMORYSTATUS);
-    GlobalMemoryStatus (&memory_status);
-
-    display_information->_physical_memory = memory_status.dwTotalPhys;
-    display_information->_available_physical_memory = memory_status.dwAvailPhys;
-    display_information->_page_file_size = memory_status.dwTotalPageFile;
-    display_information->_available_page_file_size = memory_status.dwAvailPageFile;
-    display_information->_process_virtual_memory = memory_status.dwTotalVirtual;
-    display_information->_available_process_virtual_memory = memory_status.dwAvailVirtual;
+  MEMORYSTATUSEX memory_status;
+
+  memory_status.dwLength = sizeof(MEMORYSTATUSEX);
+  if (GlobalMemoryStatusEx(&memory_status)) {
+    display_information->_physical_memory = memory_status.ullTotalPhys;
+    display_information->_available_physical_memory = memory_status.ullAvailPhys;
+    display_information->_page_file_size = memory_status.ullTotalPageFile;
+    display_information->_available_page_file_size = memory_status.ullAvailPageFile;
+    display_information->_process_virtual_memory = memory_status.ullTotalVirtual;
+    display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual;
     display_information->_memory_load = memory_status.dwMemoryLoad;
     display_information->_memory_load = memory_status.dwMemoryLoad;
   }
   }
 
 
@@ -687,19 +664,12 @@ WinGraphicsPipe() {
 
 
   _supported_types = OT_window | OT_fullscreen_window;
   _supported_types = OT_window | OT_fullscreen_window;
 
 
-  // these fns arent defined on win95, so get dynamic ptrs to them to avoid
-  // ugly DLL loader failures on w95
-  _pfnTrackMouseEvent = NULL;
-
-  _hUser32 = (HINSTANCE)LoadLibrary("user32.dll");
-  if (_hUser32 != NULL) {
-    _pfnTrackMouseEvent =
-      (PFN_TRACKMOUSEEVENT)GetProcAddress(_hUser32, "TrackMouseEvent");
-
+  HMODULE user32 = GetModuleHandleA("user32.dll");
+  if (user32 != NULL) {
     if (dpi_aware) {
     if (dpi_aware) {
       typedef HRESULT (WINAPI *PFN_SETPROCESSDPIAWARENESS)(Process_DPI_Awareness);
       typedef HRESULT (WINAPI *PFN_SETPROCESSDPIAWARENESS)(Process_DPI_Awareness);
       PFN_SETPROCESSDPIAWARENESS pfnSetProcessDpiAwareness =
       PFN_SETPROCESSDPIAWARENESS pfnSetProcessDpiAwareness =
-        (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(_hUser32, "SetProcessDpiAwarenessInternal");
+        (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(user32, "SetProcessDpiAwarenessInternal");
 
 
       if (pfnSetProcessDpiAwareness == NULL) {
       if (pfnSetProcessDpiAwareness == NULL) {
         if (windisplay_cat.is_debug()) {
         if (windisplay_cat.is_debug()) {
@@ -908,26 +878,4 @@ lookup_cpu_data() {
  */
  */
 WinGraphicsPipe::
 WinGraphicsPipe::
 ~WinGraphicsPipe() {
 ~WinGraphicsPipe() {
-  if (_hUser32 != NULL) {
-    FreeLibrary(_hUser32);
-    _hUser32 = NULL;
-  }
-}
-
-bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) {
-  *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName);
-  if (*pFn == NULL) {
-    windisplay_cat.error() << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() <<endl;
-    return false;
-  }
-  return true;
-}
-
-bool MyLoadLib(HINSTANCE &hDLL, const char *DLLname) {
-  hDLL = LoadLibrary(DLLname);
-  if(hDLL == NULL) {
-    windisplay_cat.error() << "LoadLibrary failed for " << DLLname << ", error=" << GetLastError() <<endl;
-    return false;
-  }
-  return true;
 }
 }

+ 0 - 11
panda/src/windisplay/winGraphicsPipe.h

@@ -34,12 +34,6 @@ public:
 
 
   virtual void lookup_cpu_data();
   virtual void lookup_cpu_data();
 
 
-private:
-  HINSTANCE _hUser32;
-
-  typedef BOOL (WINAPI *PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT);
-  PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent;
-
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;
@@ -56,13 +50,8 @@ public:
 
 
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
-
-  friend class WinGraphicsWindow;
 };
 };
 
 
-extern EXPCL_PANDAWIN bool MyLoadLib(HINSTANCE &hDLL, const char *DLLname);
-extern EXPCL_PANDAWIN bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName);
-
 #include "winGraphicsPipe.I"
 #include "winGraphicsPipe.I"
 
 
 #endif
 #endif

+ 76 - 86
panda/src/windisplay/winGraphicsWindow.cxx

@@ -29,6 +29,17 @@
 #define WM_DPICHANGED 0x02E0
 #define WM_DPICHANGED 0x02E0
 #endif
 #endif
 
 
+#ifndef WM_TOUCH
+#define WM_TOUCH 0x0240
+#endif
+
+#if WINVER < 0x0601
+// Not used on Windows XP, but we still need to define it.
+#define TOUCH_COORD_TO_PIXEL(l) ((l) / 100)
+
+DECLARE_HANDLE(HTOUCHINPUT);
+#endif
+
 TypeHandle WinGraphicsWindow::_type_handle;
 TypeHandle WinGraphicsWindow::_type_handle;
 TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
 TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
 
 
@@ -56,22 +67,15 @@ int WinGraphicsWindow::_window_class_index = 0;
 
 
 static const char * const errorbox_title = "Panda3D Error";
 static const char * const errorbox_title = "Panda3D Error";
 
 
-// These static variables contain pointers to the Raw Input functions, which
+// These static variables contain pointers to the touch input functions, which
 // are dynamically extracted from USER32.DLL
 // are dynamically extracted from USER32.DLL
+typedef WINUSERAPI BOOL (WINAPI *PFN_REGISTERTOUCHWINDOW)(IN HWND hWnd, IN ULONG ulFlags);
+typedef WINUSERAPI BOOL (WINAPI *PFN_GETTOUCHINPUTINFO)(IN HTOUCHINPUT hTouchInput, IN UINT cInputs, OUT PTOUCHINPUT pInputs, IN int cbSize);
+typedef WINUSERAPI BOOL (WINAPI *PFN_CLOSETOUCHINPUTHANDLE)(IN HTOUCHINPUT hTouchInput);
 
 
-typedef WINUSERAPI UINT (WINAPI *tGetRawInputDeviceList)
-  (OUT PRAWINPUTDEVICELIST pRawInputDeviceList, IN OUT PUINT puiNumDevices, IN UINT cbSize);
-typedef WINUSERAPI UINT(WINAPI *tGetRawInputData)
-  (IN HRAWINPUT hRawInput, IN UINT uiCommand, OUT LPVOID pData, IN OUT PUINT pcbSize, IN UINT cbSizeHeader);
-typedef WINUSERAPI UINT(WINAPI *tGetRawInputDeviceInfoA)
-  (IN HANDLE hDevice, IN UINT uiCommand, OUT LPVOID pData, IN OUT PUINT pcbSize);
-typedef WINUSERAPI BOOL (WINAPI *tRegisterRawInputDevices)
-  (IN PCRAWINPUTDEVICE pRawInputDevices, IN UINT uiNumDevices, IN UINT cbSize);
-
-static tGetRawInputDeviceList    pGetRawInputDeviceList;
-static tGetRawInputData          pGetRawInputData;
-static tGetRawInputDeviceInfoA   pGetRawInputDeviceInfoA;
-static tRegisterRawInputDevices  pRegisterRawInputDevices;
+static PFN_REGISTERTOUCHWINDOW pRegisterTouchWindow = 0;
+static PFN_GETTOUCHINPUTINFO pGetTouchInputInfo = 0;
+static PFN_CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle = 0;
 
 
 /**
 /**
  *
  *
@@ -100,9 +104,7 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
   _lalt_down = false;
   _lalt_down = false;
   _ralt_down = false;
   _ralt_down = false;
   _hparent = NULL;
   _hparent = NULL;
-#ifdef HAVE_WIN_TOUCHINPUT
-  _numTouches = 0;
-#endif
+  _num_touches = 0;
 }
 }
 
 
 /**
 /**
@@ -512,13 +514,13 @@ open_window() {
   }
   }
 
 
   // Registers to receive the WM_INPUT messages
   // Registers to receive the WM_INPUT messages
-  if ((pRegisterRawInputDevices)&&(_input_devices.size() > 1)) {
+  if (_input_devices.size() > 1) {
     RAWINPUTDEVICE Rid;
     RAWINPUTDEVICE Rid;
     Rid.usUsagePage = 0x01;
     Rid.usUsagePage = 0x01;
     Rid.usUsage = 0x02;
     Rid.usUsage = 0x02;
     Rid.dwFlags = 0;// RIDEV_NOLEGACY;   // adds HID mouse and also ignores legacy mouse messages
     Rid.dwFlags = 0;// RIDEV_NOLEGACY;   // adds HID mouse and also ignores legacy mouse messages
     Rid.hwndTarget = _hWnd;
     Rid.hwndTarget = _hWnd;
-    pRegisterRawInputDevices(&Rid, 1, sizeof (Rid));
+    RegisterRawInputDevices(&Rid, 1, sizeof (Rid));
   }
   }
 
 
   // Create a WindowHandle for ourselves
   // Create a WindowHandle for ourselves
@@ -535,10 +537,23 @@ open_window() {
   // set us as the focus window for keyboard input
   // set us as the focus window for keyboard input
   set_focus();
   set_focus();
 
 
+  // Try initializing the touch function pointers.
+  static bool initialized = false;
+  if (!initialized) {
+    initialized = true;
+    HMODULE user32 = GetModuleHandleA("user32.dll");
+    if (user32) {
+      // Introduced in Windows 7.
+      pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32, "RegisterTouchWindow");
+      pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32, "GetTouchInputInfo");
+      pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32, "CloseTouchInputHandle");
+    }
+  }
+
   // Register for Win7 touch events.
   // Register for Win7 touch events.
-#ifdef HAVE_WIN_TOUCHINPUT
-  RegisterTouchWindow(_hWnd, 0);
-#endif
+  if (pRegisterTouchWindow != NULL) {
+    pRegisterTouchWindow(_hWnd, 0);
+  }
 
 
   return true;
   return true;
 }
 }
@@ -563,45 +578,35 @@ initialize_input_devices() {
     GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
     GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
   add_input_device(device);
   add_input_device(device);
 
 
-  // Try initializing the Raw Input function pointers.
-  if (pRegisterRawInputDevices==0) {
-    HMODULE user32 = LoadLibrary("user32.dll");
-    if (user32) {
-      pRegisterRawInputDevices = (tRegisterRawInputDevices)GetProcAddress(user32,"RegisterRawInputDevices");
-      pGetRawInputDeviceList   = (tGetRawInputDeviceList)  GetProcAddress(user32,"GetRawInputDeviceList");
-      pGetRawInputDeviceInfoA  = (tGetRawInputDeviceInfoA) GetProcAddress(user32,"GetRawInputDeviceInfoA");
-      pGetRawInputData         = (tGetRawInputData)        GetProcAddress(user32,"GetRawInputData");
-    }
-  }
-
-  if (pRegisterRawInputDevices==0) return;
-  if (pGetRawInputDeviceList==0) return;
-  if (pGetRawInputDeviceInfoA==0) return;
-  if (pGetRawInputData==0) return;
-
   // Get the number of devices.
   // Get the number of devices.
-  if (pGetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
+  if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) {
     return;
     return;
+  }
 
 
   // Allocate the array to hold the DeviceList
   // Allocate the array to hold the DeviceList
   pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(sizeof(RAWINPUTDEVICELIST) * nInputDevices);
   pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(sizeof(RAWINPUTDEVICELIST) * nInputDevices);
-  if (pRawInputDeviceList==0) return;
+  if (pRawInputDeviceList==0) {
+    return;
+  }
 
 
   // Fill the Array
   // Fill the Array
-  if (pGetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1)
+  if (GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1) {
     return;
     return;
+  }
 
 
   // Loop through all raw devices and find the raw mice
   // Loop through all raw devices and find the raw mice
   for (int i = 0; i < (int)nInputDevices; i++) {
   for (int i = 0; i < (int)nInputDevices; i++) {
     if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
     if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
       // Fetch information about specified mouse device.
       // Fetch information about specified mouse device.
       UINT nSize;
       UINT nSize;
-      if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0)
+      if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) {
         return;
         return;
+      }
       char *psName = (char*)alloca(sizeof(TCHAR) * nSize);
       char *psName = (char*)alloca(sizeof(TCHAR) * nSize);
       if (psName == 0) return;
       if (psName == 0) return;
-      if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0)
+      if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) {
         return;
         return;
+      }
 
 
       // If it's not an RDP mouse, add it to the list of raw mice.
       // If it's not an RDP mouse, add it to the list of raw mice.
       if (strncmp(psName,"\\??\\Root#RDP_MOU#0000#",22)!=0) {
       if (strncmp(psName,"\\??\\Root#RDP_MOU#0000#",22)!=0) {
@@ -1215,31 +1220,25 @@ adjust_z_order(WindowProperties::ZOrder last_z_order,
  */
  */
 void WinGraphicsWindow::
 void WinGraphicsWindow::
 track_mouse_leaving(HWND hwnd) {
 track_mouse_leaving(HWND hwnd) {
-  // Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which
-  // emulates TrackMouseEvent on w95, but that requires another 500K of memory
-  // to hold that DLL, which is lame just to support w95, which probably has
-  // other issues anyway
   WinGraphicsPipe *winpipe;
   WinGraphicsPipe *winpipe;
   DCAST_INTO_V(winpipe, _pipe);
   DCAST_INTO_V(winpipe, _pipe);
 
 
-  if (winpipe->_pfnTrackMouseEvent != NULL) {
-    TRACKMOUSEEVENT tme = {
-      sizeof(TRACKMOUSEEVENT),
-      TME_LEAVE,
-      hwnd,
-      0
-    };
-
-    // tell win32 to post WM_MOUSELEAVE msgs
-    BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme);
+  TRACKMOUSEEVENT tme = {
+    sizeof(TRACKMOUSEEVENT),
+    TME_LEAVE,
+    hwnd,
+    0
+  };
 
 
-    if ((!bSucceeded) && windisplay_cat.is_debug()) {
-      windisplay_cat.debug()
-        << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
-    }
+  // tell win32 to post WM_MOUSELEAVE msgs
+  BOOL bSucceeded = TrackMouseEvent(&tme);
 
 
-    _tracking_mouse_leaving = true;
+  if (!bSucceeded && windisplay_cat.is_debug()) {
+    windisplay_cat.debug()
+      << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
   }
   }
+
+  _tracking_mouse_leaving = true;
 }
 }
 
 
 /**
 /**
@@ -2067,15 +2066,16 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
     }
     }
     break;
     break;
 
 
-#ifdef HAVE_WIN_TOUCHINPUT
   case WM_TOUCH:
   case WM_TOUCH:
-        _numTouches = LOWORD(wparam);
-        if(_numTouches > MAX_TOUCHES)
-            _numTouches = MAX_TOUCHES;
-        GetTouchInputInfo((HTOUCHINPUT)lparam, _numTouches, _touches, sizeof(TOUCHINPUT));
-        CloseTouchInputHandle((HTOUCHINPUT)lparam);
+    _num_touches = LOWORD(wparam);
+    if (_num_touches > MAX_TOUCHES) {
+      _num_touches = MAX_TOUCHES;
+    }
+    if (pGetTouchInputInfo != 0) {
+      pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches, sizeof(TOUCHINPUT));
+      pCloseTouchInputHandle((HTOUCHINPUT)lparam);
+    }
     break;
     break;
-#endif
   }
   }
 
 
   // do custom messages processing if any has been set
   // do custom messages processing if any has been set
@@ -2607,7 +2607,7 @@ handle_raw_input(HRAWINPUT hraw) {
   if (hraw == 0) {
   if (hraw == 0) {
     return;
     return;
   }
   }
-  if (pGetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) {
+  if (GetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) {
     return;
     return;
   }
   }
 
 
@@ -2616,7 +2616,7 @@ handle_raw_input(HRAWINPUT hraw) {
     return;
     return;
   }
   }
 
 
-  if (pGetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {
+  if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {
     return;
     return;
   }
   }
 
 
@@ -2973,12 +2973,8 @@ bool WinGraphicsWindow::supports_window_procs() const{
  *
  *
  */
  */
 bool WinGraphicsWindow::
 bool WinGraphicsWindow::
-is_touch_event(GraphicsWindowProcCallbackData* callbackData){
-#ifdef HAVE_WIN_TOUCHINPUT
+is_touch_event(GraphicsWindowProcCallbackData *callbackData) {
   return callbackData->get_msg() == WM_TOUCH;
   return callbackData->get_msg() == WM_TOUCH;
-#else
-  return false;
-#endif
 }
 }
 
 
 /**
 /**
@@ -2987,11 +2983,7 @@ is_touch_event(GraphicsWindowProcCallbackData* callbackData){
  */
  */
 int WinGraphicsWindow::
 int WinGraphicsWindow::
 get_num_touches(){
 get_num_touches(){
-#ifdef HAVE_WIN_TOUCHINPUT
-  return _numTouches;
-#else
-  return 0;
-#endif
+  return _num_touches;
 }
 }
 
 
 /**
 /**
@@ -2999,8 +2991,9 @@ get_num_touches(){
  *
  *
  */
  */
 TouchInfo WinGraphicsWindow::
 TouchInfo WinGraphicsWindow::
-get_touch_info(int index){
-#ifdef HAVE_WIN_TOUCHINPUT
+get_touch_info(int index) {
+  nassertr(index >= 0 && index < MAX_TOUCHES, TouchInfo());
+
   TOUCHINPUT ti = _touches[index];
   TOUCHINPUT ti = _touches[index];
   POINT point;
   POINT point;
   point.x = TOUCH_COORD_TO_PIXEL(ti.x);
   point.x = TOUCH_COORD_TO_PIXEL(ti.x);
@@ -3013,7 +3006,4 @@ get_touch_info(int index){
   ret.set_id(ti.dwID);
   ret.set_id(ti.dwID);
   ret.set_flags(ti.dwFlags);
   ret.set_flags(ti.dwFlags);
   return ret;
   return ret;
-#else
-  return TouchInfo();
-#endif
 }
 }

+ 18 - 5
panda/src/windisplay/winGraphicsWindow.h

@@ -34,8 +34,23 @@ typedef struct {
   int y;
   int y;
   int width;
   int width;
   int height;
   int height;
-}
-WINDOW_METRICS;
+} WINDOW_METRICS;
+
+#if WINVER < 0x0601
+// Not used on Windows XP, but we still need to define it.
+typedef struct tagTOUCHINPUT {
+  LONG x;
+  LONG y;
+  HANDLE hSource;
+  DWORD dwID;
+  DWORD dwFlags;
+  DWORD dwMask;
+  DWORD dwTime;
+  ULONG_PTR dwExtraInfo;
+  DWORD cxContact;
+  DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+#endif
 
 
 /**
 /**
  * An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in
  * An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in
@@ -177,10 +192,8 @@ private:
   typedef pset<GraphicsWindowProc*> WinProcClasses;
   typedef pset<GraphicsWindowProc*> WinProcClasses;
   WinProcClasses _window_proc_classes;
   WinProcClasses _window_proc_classes;
 
 
-#ifdef HAVE_WIN_TOUCHINPUT
-  UINT _numTouches;
+  UINT _num_touches;
   TOUCHINPUT _touches[MAX_TOUCHES];
   TOUCHINPUT _touches[MAX_TOUCHES];
-#endif
 
 
 private:
 private:
   // We need this map to support per-window calls to window_proc().
   // We need this map to support per-window calls to window_proc().