Browse Source

Improve runtime installer, add 64-bit support

rdb 11 years ago
parent
commit
43805f47bb

+ 64 - 29
direct/src/p3d/p3dWrapper.c

@@ -23,12 +23,21 @@
 #include <windows.h>
 #include <process.h>
 #include <assert.h>
+#include <malloc.h>
 
 #define BUFFER_SIZE 1024
 
+/* It makes sense to use "App Paths\panda3d.exe".  However, Microsoft
+   decided in their infinite wisdom to disable Redirection for that
+   key from Windows 7 onward, so we can't rely on it producing a
+   result appropriate to the right architecture when both the 32-bit
+   and 64-bit versions of the runtime are installed.  Beh. */
+
+#define UNINST_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Panda3D Game Engine"
+
 int main (int argc, char* argv[]) {
   int i;
-  char buffer [BUFFER_SIZE];
+  char buffer[BUFFER_SIZE];
   char* p3dfile;
   char* runtime = NULL;
   DWORD size;
@@ -37,56 +46,82 @@ int main (int argc, char* argv[]) {
   char *cmd;
   char *newcmd;
   HKEY hKey = 0;
-  char buf [1024] = {0};
-  DWORD dwType = 0;
+  char buf[1024] = {0};
+  DWORD dwType = REG_SZ;
   DWORD dwBufSize = sizeof(buf);
-  size = GetModuleFileName (NULL, buffer, BUFFER_SIZE);
+  size = GetModuleFileName(NULL, buffer, BUFFER_SIZE);
   assert (size > 0);
 
   /* Chop off the .exe and replace it by .p3d. */
-  p3dfile = (char*) malloc (size + 1);
-  memcpy (p3dfile, buffer, size);
-  p3dfile [size] = 0;
-  memcpy (p3dfile + size - 3, "p3d", 3);
+  p3dfile = (char*) _alloca(size + 1);
+  memcpy(p3dfile, buffer, size);
+  p3dfile[size] = 0;
+  memcpy(p3dfile + size - 3, "p3d", 3);
 
-  /* Find the Panda3D applet\DefaultIcon key and extract the path to the runtime from there. */
-  if (RegOpenKey (HKEY_CLASSES_ROOT, "Panda3D applet\\DefaultIcon", &hKey) == ERROR_SUCCESS) {
-    dwType = REG_SZ;
-    if (RegQueryValueEx(hKey, 0, 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
-      for (i = dwBufSize - 1; i >= 0; --i) {
-        if (buf [i] == '/' || buf [i] == '\\') {
-          runtime = (char*) malloc (i + 13);
-          memcpy (runtime, buf, i);
-          runtime [i] = 0;         
-          strcat (runtime, "\\panda3d.exe");      
-          break;
+  /* Find the location of panda3d.exe using the registry path. */
+#ifdef _WIN64
+  /* If we're on 64-bit Windows, try the 64-bit registry first. */
+  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINST_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) {
+    if (RegQueryValueEx(hKey, "DisplayIcon", 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
+      char *slash = strrchr(buf, '\\');
+      if (slash != NULL) {
+        strcpy(slash, "\\panda3d.exe");
+        runtime = buf;
+      }
+    }
+    RegCloseKey(hKey);
+  }
+#endif
+
+  /* On 32-bit Windows, or no 64-bit Runtime installed.  Try 32-bit registry. */
+  if (runtime == NULL) {
+    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINST_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) {
+      if (RegQueryValueEx(hKey, "DisplayIcon", 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
+        char *slash = strrchr(buf, '\\');
+        if (slash != NULL) {
+          strcpy(slash, "\\panda3d.exe");
+          runtime = buf;
         }
       }
+      RegCloseKey(hKey);
+    }
+  }
+
+  /* Backward compatibility: Runtime 1.0.4 and below looked for the below key, even though the
+     above keys should work fine, but let's just be certain.
+     Find the Panda3D applet\DefaultIcon key and extract the path to the runtime from there.  */
+  if (runtime == NULL) {
+    if (RegOpenKey(HKEY_CLASSES_ROOT, "Panda3D applet\\DefaultIcon", &hKey) == ERROR_SUCCESS) {
+      if (RegQueryValueEx(hKey, 0, 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
+        char *slash = strrchr(buf, '\\');
+        if (slash != NULL) {
+          strcpy(slash, "\\panda3d.exe");
+          runtime = buf;
+        }
+      } else {
+        fprintf(stderr, "Failed to read registry key. Try reinstalling the Panda3D Runtime.\n");
+        return 1;
+      }
+      RegCloseKey(hKey);
     } else {
-      fprintf (stderr, "Failed to read registry key. Try reinstalling the Panda3D Runtime.\n");
+      fprintf(stderr, "The Panda3D Runtime does not appear to be installed!\n");
       return 1;
     }
-    RegCloseKey(hKey);
-  } else {
-    fprintf (stderr, "The Panda3D Runtime does not appear to be installed!\n");
-    return 1;
   }
 
   if (runtime == NULL) {
-    fprintf (stderr, "Failed to find panda3d.exe in registry. Try reinstalling the Panda3D Runtime.\n");
+    fprintf(stderr, "Failed to find panda3d.exe in registry. Try reinstalling the Panda3D Runtime.\n");
     return 1;
   }
 
   /* Build the command-line and run panda3d.exe. */
   cmd = GetCommandLine();
-  newcmd = (char*) malloc (strlen(runtime) + strlen(p3dfile) + strlen (cmd) - strlen (argv[0]) + 7);
-  sprintf (newcmd, "\"%s\" \"%s\" %s", runtime, p3dfile, cmd + strlen (argv[0]));
+  newcmd = (char*) _alloca(strlen(runtime) + strlen(p3dfile) + strlen(cmd) - strlen (argv[0]) + 7);
+  sprintf(newcmd, "\"%s\" \"%s\" %s", runtime, p3dfile, cmd + strlen(argv[0]));
   memset(&si, 0, sizeof(si));
   si.cb = sizeof(STARTUPINFO);
   if (CreateProcess(runtime, newcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
     WaitForSingleObject(pi.hProcess, INFINITE);
   }
-  free (newcmd);
   return 0;
 }
-

+ 14 - 5
direct/src/plugin_installer/make_installer.py

@@ -40,7 +40,7 @@ parser.add_option('-l', '--license', dest = 'license',
                   default = None)
 parser.add_option('-w', '--website', dest = 'website',
                   help = 'The product website',
-                  default = 'http://www.panda3d.org')
+                  default = 'https://www.panda3d.org')
 parser.add_option('', '--start', dest = 'start',
                   help = 'Specify this option to add a start menu',
                   action = 'store_true', default = False)
@@ -65,6 +65,9 @@ parser.add_option('', '--pvk', dest = 'pvk',
 parser.add_option('', '--mssdk', dest = 'mssdk',
                   help = 'The path to the MS Platform SDK directory (Windows only).  mssdk/bin should contain cabarc.exe and signcode.exe.',
                   default = None)
+parser.add_option('', '--regview', dest = 'regview',
+                  help = 'Which registry view to use, 64 or 32.',
+                  default = None)
 
 (options, args) = parser.parse_args()
 
@@ -221,7 +224,7 @@ def parseDependenciesUnix(tempFile):
         filenames.append(l.strip().split(' ', 1)[0])
     return filenames
 
-def addDependencies(path, pathname, file, pluginDependencies, dependentFiles):
+def addDependencies(path, pathname, file, pluginDependencies, dependentFiles, required=True):
     """ Checks the named file for DLL dependencies, and adds any
     appropriate dependencies found into pluginDependencies and
     dependentFiles. """
@@ -271,7 +274,10 @@ def addDependencies(path, pathname, file, pluginDependencies, dependentFiles):
                         break
                     pathname = None
                 if not pathname:
-                    sys.exit("Couldn't find %s." % (dfile))
+                    if required:
+                        sys.exit("Couldn't find %s." % (dfile))
+                    sys.stderr.write("Warning: couldn't find %s." % (dfile))
+                    continue
                 pathname = os.path.abspath(pathname)
                 dependentFiles[dfilelower] = pathname
 
@@ -380,7 +386,7 @@ def makeInstaller():
         npapi = 'nppanda3d.dll'
         panda3d = 'panda3d.exe'
         panda3dw = 'panda3dw.exe'
-        baseFiles = [ocx, npapi, panda3d, panda3dw]
+        baseFiles = [npapi, panda3d, panda3dw]
     else:
         baseFiles = []
 
@@ -545,7 +551,7 @@ def makeInstaller():
         CMD += '/DINSTALL_DIR="' + options.install_dir + '" '
         CMD += '/DLICENSE_FILE="' + options.license + '" '
         CMD += '/DOCX="' + ocx + '" '
-        CMD += '/DOCX_PATH="' + pluginFiles[ocx] + '" '
+        #CMD += '/DOCX_PATH="' + pluginFiles[ocx] + '" '
         CMD += '/DNPAPI="' + npapi + '" '
         CMD += '/DNPAPI_PATH="' + pluginFiles[npapi] + '" '
         CMD += '/DPANDA3D="' + panda3d + '" '
@@ -553,6 +559,9 @@ def makeInstaller():
         CMD += '/DPANDA3DW="' + panda3dw + '" '
         CMD += '/DPANDA3DW_PATH="' + pluginFiles[panda3dw] + '" '
 
+        if options.regview:
+            CMD += '/DREGVIEW=%s ' % (options.regview)
+
         dependencies = dependentFiles.items()
         for i in range(len(dependencies)):
             CMD += '/DDEP%s="%s" ' % (i, dependencies[i][0])

+ 76 - 21
direct/src/plugin_installer/p3d_installer.nsi

@@ -1,6 +1,5 @@
 !include "MUI.nsh"
 !include LogicLib.nsh
-!include FileAssociation.nsh
 
 ; Several variables are assumed to be pre-defined by the caller.  See
 ; make_installer.py in this directory.
@@ -9,18 +8,18 @@
 !define UNINSTALL_CONFIRM "Are you sure you want to completely remove $(^Name) and all of its components?"
 !define UNINSTALL_LINK_NAME "Uninstall"
 !define WEBSITE_LINK_NAME "Website"
-!define PLID "@panda3d.org/Panda3D Runtime,version=0.0"
+!define PLID "@panda3d.org/Panda3D Runtime"
 
 ; HM NIS Edit Wizard helper defines
 !define APP_INTERNAL_NAME "Panda3D"
 
-!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${OCX}"
+!define PRODUCT_DIR_REGKEY_PANDA3D "Software\Microsoft\Windows\CurrentVersion\App Paths\${PANDA3D}"
+!define PRODUCT_DIR_REGKEY_PANDA3DW "Software\Microsoft\Windows\CurrentVersion\App Paths\${PANDA3DW}"
+!define PRODUCT_DIR_REGKEY_OCX "Software\Microsoft\Windows\CurrentVersion\App Paths\${OCX}"
 !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
 !define PRODUCT_UNINST_ROOT_KEY "HKLM"
 !define PROG_GROUPNAME "${PRODUCT_NAME}"
 
-!define FIREFOX_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe"
-
 SetCompressor lzma
 
 ; MUI Settings
@@ -60,16 +59,32 @@ InstallDir "${INSTALL_DIR}"
   UninstallIcon "${INSTALL_ICON}"
 !endif
 WindowIcon on
-InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+
 ShowInstDetails show
 ShowUnInstDetails show
 
+Function .onInit
+!ifdef REGVIEW
+  SetRegView ${REGVIEW}
+!endif
+
+  ClearErrors
+
+  ReadRegStr $0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation"
+
+  IfErrors +2 0
+  StrCpy $INSTDIR $0
+
+FunctionEnd
+
 Section "MainSection" SEC01
   SetShellVarContext all
   SetOutPath "$INSTDIR"
   SetOverwrite ifdiff
 
+!ifdef OCX_PATH
   File "${OCX_PATH}"
+!endif
   File "${NPAPI_PATH}"
   File "${PANDA3D_PATH}"
   File "${PANDA3DW_PATH}"
@@ -100,8 +115,6 @@ Section "MainSection" SEC01
 !ifdef DEP7P
   File "${DEP7P}"
 !endif
-
-  ${registerExtension} "$INSTDIR\${PANDA3DW}" ".p3d" "Panda3D applet"
  
 !ifdef ADD_START_MENU
 ; Start->Programs links
@@ -127,14 +140,41 @@ Section -AdditionalIcons
 SectionEnd
 
 Section -Post
+!ifdef REGVIEW
+  SetRegView ${REGVIEW}
+!endif
+
   WriteUninstaller "$INSTDIR\uninst.exe"
-  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\${OCX}"
+
+  WriteRegStr HKCR ".p3d" "" "Panda3D applet"
+  WriteRegStr HKCR ".p3d" "Content Type" "application/x-panda3d"
+  WriteRegStr HKCR ".p3d" "PerceivedType" "application"
+  WriteRegStr HKCR "Panda3D applet" "" "Panda3D applet"
+  WriteRegStr HKCR "Panda3D applet\DefaultIcon" "" "$INSTDIR\${PANDA3DW}"
+  WriteRegStr HKCR "Panda3D applet\shell" "" "open"
+  WriteRegStr HKCR "Panda3D applet\shell\open\command" "" '"$INSTDIR\${PANDA3DW}" "%1"'
+  WriteRegExpandStr HKCR "Panda3D applet\shell\open2" "" "Open &with Command Prompt"
+  ;WriteRegExpandStr HKCR "Panda3D applet\shell\open2" "MUIVerb" "@%SystemRoot%\System32\wshext.dll,-4511"
+  WriteRegExpandStr HKCR "Panda3D applet\shell\open2\command" "" '"$INSTDIR\${PANDA3D}" "%1"'
+
+  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY_PANDA3D}" "" "$INSTDIR\${PANDA3D}"
+  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY_PANDA3DW}" "" "$INSTDIR\${PANDA3DW}"
   WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
   WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${OCX}"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PANDA3D}"
   WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
   WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
   WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
+  WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoModify" 1
+  WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoRepair" 1
+
+  SectionGetSize SEC01 $0
+  WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "EstimatedSize" $0
+
+  # Delete keys we used in older versions
+  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_OCX}"
+  DeleteRegKey HKCR "Panda3D applet\shell\edit"
 SectionEnd
 
 
@@ -149,16 +189,23 @@ Function un.onInit
 FunctionEnd
 
 Function .onInstSuccess
- # Register ActiveX
- ExecWait 'regsvr32 /s "$INSTDIR/${OCX}"'
+  # Register ActiveX
+  ExecWait 'regsvr32 /s "$INSTDIR/${OCX}"'
 
- # Register Mozilla Plugin
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Description" "Runs 3-D games and interactive applets"
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Path" "$INSTDIR\${NPAPI}"
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "ProductName" "${PRODUCT_NAME_SHORT}"
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Vendor" "${PRODUCT_PUBLISHER}"
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Version" "${PRODUCT_VERSION}"
- WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}\MimeTypes" "application/x-panda3d" ""
+!ifdef REGVIEW
+  SetRegView ${REGVIEW}
+!endif
+
+  # Register Mozilla Plugin
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Description" "Runs 3-D games and interactive applets"
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Path" "$INSTDIR\${NPAPI}"
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "ProductName" "${PRODUCT_NAME_SHORT}"
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Vendor" "${PRODUCT_PUBLISHER}"
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Version" "${PRODUCT_VERSION}"
+  WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}\MimeTypes\application/x-panda3d" "Description" "Panda3D applet"
+
+  # Remove old stuff
+  DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID},version=0.0"
 
 FunctionEnd
 
@@ -196,6 +243,10 @@ Section Uninstall
   Delete "$INSTDIR\${DEP7}"
 !endif
 
+!ifdef REGVIEW
+  SetRegView ${REGVIEW}
+!endif
+
 # The following loop uninstalls the plugin where it may have been
 # copied into one of the Mozilla Extensions dirs.  Older versions of
 # the installer would have done this, but now we just update the
@@ -215,8 +266,10 @@ Mozilla-Uninstall-Loop:
 Mozilla-Uninstall-End:
 
   DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID}"
+  DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID},version=0.0"
 
-  ${unregisterExtension} ".p3d" "Panda3D applet"
+  DeleteRegKey HKCR ".p3d"
+  DeleteRegKey HKCR "Panda3D applet"
 
   # Remove the user's "Panda3D" directory, where all of the downloaded
   # contents are installed.  Too bad we can't do this for every system
@@ -239,7 +292,9 @@ Mozilla-Uninstall-End:
   RMDir "$INSTDIR"
 
   DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
-  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_PANDA3D}"
+  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_PANDA3DW}"
+  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_OCX}"
   SetAutoClose true
 SectionEnd
 

+ 45 - 32
makepanda/makepanda.py

@@ -30,8 +30,8 @@ import time
 import os
 import sys
 
-## jGenPyCode tries to get the directory for Direct from the sys.path. This only works if you 
-## have installed the sdk using a installer. This would not work if the installer was 
+## jGenPyCode tries to get the directory for Direct from the sys.path. This only works if you
+## have installed the sdk using a installer. This would not work if the installer was
 ## never used and everything was grabbed into a virgin environment using cvs.
 sys.path.append(os.getcwd())
 
@@ -88,14 +88,14 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "VRPN", "OPENSSL",                                   # Transport
   "FFTW",                                              # Algorithm helpers
   "ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION",        # Augmented Reality
-  "NPAPI", "AWESOMIUM",                                # Browser embedding
-  "GTK2", "WX", "FLTK",                                # Toolkit support
-  "ROCKET",                                            # GUI libraries
+  "GTK2",                                              # GTK2 is used for PStats on Unix
+  "NPAPI", "MFC", "WX", "FLTK",                        # Used for web plug-in only
+  "ROCKET", "AWESOMIUM",                               # GUI libraries
   "CARBON", "COCOA",                                   # Mac OS X toolkits
   "X11", "XF86DGA", "XRANDR", "XCURSOR",               # Unix platform support
   "PANDATOOL", "PVIEW", "DEPLOYTOOLS",                 # Toolchain
   "SKEL",                                              # Example SKEL project
-  "PANDAFX",                                           # Some distortion special lenses 
+  "PANDAFX",                                           # Some distortion special lenses
   "PANDAPARTICLESYSTEM",                               # Built in particle system
   "CONTRIB",                                           # Experimental
   "SSE2", "NEON",                                      # Compiler features
@@ -216,7 +216,7 @@ def parseopts(args):
                 if STRDXSDKVERSION == '':
                     print("No DirectX SDK version specified. Using 'default' DirectX SDK search")
                     STRDXSDKVERSION = 'default'
-            elif (option=="--platform-sdk"): 
+            elif (option=="--platform-sdk"):
                 STRMSPLATFORMVERSION = value.strip().lower()
                 if STRMSPLATFORMVERSION == '':
                     print("No MS Platform SDK version specified. Using 'default' MS Platform SDK search")
@@ -234,7 +234,7 @@ def parseopts(args):
             if  (option=="--everything" or option.startswith("--use-")
               or option=="--nothing" or option.startswith("--no-")):
               anything = 1
-    except: 
+    except:
         usage(0)
         print("Exception while parsing commandline:", sys.exc_info()[0])
     if (anything==0): usage(0)
@@ -536,7 +536,6 @@ if (COMPILER == "MSVC"):
     if (PkgSkip("FFTW")==0):     LibName("FFTW",     GetThirdpartyDir() + "fftw/lib/fftw.lib")
     if (PkgSkip("ARTOOLKIT")==0):LibName("ARTOOLKIT",GetThirdpartyDir() + "artoolkit/lib/libAR.lib")
     if (PkgSkip("FCOLLADA")==0): LibName("FCOLLADA", GetThirdpartyDir() + "fcollada/lib/FCollada.lib")
-    if (PkgSkip("SQUISH")==0):   LibName("SQUISH",   GetThirdpartyDir() + "squish/lib/squish.lib")
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/cv.lib")
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/highgui.lib")
     if (PkgSkip("OPENCV")==0):   LibName("OPENCV",   GetThirdpartyDir() + "opencv/lib/cvaux.lib")
@@ -548,6 +547,11 @@ if (COMPILER == "MSVC"):
     if (PkgSkip("FFMPEG")==0):   LibName("FFMPEG",   GetThirdpartyDir() + "ffmpeg/lib/avutil.lib")
     if (PkgSkip("SWSCALE")==0):  LibName("SWSCALE",  GetThirdpartyDir() + "ffmpeg/lib/swscale.lib")
     if (PkgSkip("SWRESAMPLE")==0):LibName("SWRESAMPLE",GetThirdpartyDir() + "ffmpeg/lib/swresample.lib")
+    if (PkgSkip("SQUISH")==0):
+        if GetOptimize() <= 2:
+            LibName("SQUISH",   GetThirdpartyDir() + "squish/lib/squishd.lib")
+        else:
+            LibName("SQUISH",   GetThirdpartyDir() + "squish/lib/squish.lib")
     if (PkgSkip("ROCKET")==0):
         LibName("ROCKET", GetThirdpartyDir() + "rocket/lib/RocketCore.lib")
         LibName("ROCKET", GetThirdpartyDir() + "rocket/lib/RocketControls.lib")
@@ -925,7 +929,7 @@ def CompileCxx(obj,src,opts):
                 cmd += "/DWINVER=0x601 "
             cmd += "/Fo" + obj + " /nologo /c"
             if (GetTargetArch() != 'x64' and PkgSkip("SSE2") == 0):
-                cmd += " /arch:SSE2"            
+                cmd += " /arch:SSE2"
             for x in ipath: cmd += " /I" + x
             for (opt,dir) in INCDIRECTORIES:
                 if (opt=="ALWAYS") or (opt in opts): cmd += " /I" + BracketNameWithQuotes(dir)
@@ -937,7 +941,7 @@ def CompileCxx(obj,src,opts):
             if (optlevel==1): cmd += " /MDd /Zi /RTCs /GS"
             if (optlevel==2): cmd += " /MDd /Zi"
             if (optlevel==3): cmd += " /MD /Zi /O2 /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING"
-            if (optlevel==4): 
+            if (optlevel==4):
                cmd += " /MD /Zi /Ox /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING /DNDEBUG /GL"
                cmd += " /Oy /Zp16"      # jean-claude add /Zp16 insures correct static alignment for SSEx
 
@@ -983,11 +987,11 @@ def CompileCxx(obj,src,opts):
             if (optlevel==3):
                 cmd += " /MD /Zi /O2 /Oi /Ot /arch:SSE3"
                 cmd += " /Ob0"
-                cmd += " /Qipo-"                            # beware of IPO !!!  
+                cmd += " /Qipo-"                            # beware of IPO !!!
             ##      Lesson learned: Don't use /GL flag -> end result is MESSY
             ## ----------------------------------------------------------------
             if (optlevel==4):
-                cmd += " /MD /Zi /O3 /Oi /Ot /Ob0 /Yc /DNDEBUG"  # /Ob0 a ete rajoute en cours de route a 47%                
+                cmd += " /MD /Zi /O3 /Oi /Ot /Ob0 /Yc /DNDEBUG"  # /Ob0 a ete rajoute en cours de route a 47%
                 cmd += " /Qipo"                              # optimization multi file
 
             # for 3 & 4 optimization levels
@@ -999,7 +1003,7 @@ def CompileCxx(obj,src,opts):
                 cmd += " /Qopt-matmul"                        # needs /O2 or /O3
                 cmd += " /Qprec-div-"
                 cmd += " /Qsimd"
-                
+
                 cmd += " /QxHost"                            # compile for target host; Compiling for distribs should probably strictly enforce /arch:..
                 cmd += " /Quse-intel-optimized-headers"        # use intel optimized headers
                 cmd += " /Qparallel"                        # enable parallelization
@@ -1007,7 +1011,7 @@ def CompileCxx(obj,src,opts):
 
             ## PCH files coexistence: the /Qpchi option causes the Intel C++ Compiler to name its
             ## PCH files with a .pchi filename suffix and reduce build time.
-            ## The /Qpchi option is on by default but interferes with Microsoft libs; so use /Qpchi- to turn it off. 
+            ## The /Qpchi option is on by default but interferes with Microsoft libs; so use /Qpchi- to turn it off.
             ## I need to have a deeper look at this since the compile time is quite influenced by this setting !!!
             cmd += " /Qpchi-"                                 # keep it this way!
 
@@ -1025,7 +1029,7 @@ def CompileCxx(obj,src,opts):
             ## Use this option if you always define a class before you declare a pointer to a member of the class.
             ## The compiler will issue an error if it encounters a pointer declaration before the class is defined.
             ## Alternate: #pragma pointers_to_members
-      
+
             cmd += " /Fd" + os.path.splitext(obj)[0] + ".pdb"
             building = GetValueOption(opts, "BUILDING:")
             if (building): cmd += " /DBUILDING_" + building
@@ -1033,10 +1037,10 @@ def CompileCxx(obj,src,opts):
                 cmd += " /bigobj"
 
             # level of warnings and optimization reports
-            if GetVerbose(): 
+            if GetVerbose():
                 cmd += " /W3 " # or /W4 or /Wall
                 cmd += " /Qopt-report:2 /Qopt-report-phase:hlo /Qopt-report-phase:hpo"    # some optimization reports
-            else:            
+            else:
                 cmd += " /W1 "
             cmd += " /EHa /Zm300 /DWIN32_VC /DWIN32"
             if GetTargetArch() == 'x64':
@@ -1044,7 +1048,7 @@ def CompileCxx(obj,src,opts):
             cmd += " " + BracketNameWithQuotes(src)
 
             oscmd(cmd)
-            
+
     if (COMPILER=="GCC"):
         if (src.endswith(".c")): cmd = GetCC() +' -fPIC -c -o ' + obj
         else:                    cmd = GetCXX()+' -ftemplate-depth-50 -fPIC -c -o ' + obj
@@ -1117,7 +1121,7 @@ def CompileCxx(obj,src,opts):
 
         if PkgSkip("SSE2") == 0 and not arch.startswith("arm"):
             cmd += " -msse2"
-        
+
         if (optlevel==1): cmd += " -ggdb -D_DEBUG"
         if (optlevel==2): cmd += " -O1 -D_DEBUG"
         if (optlevel==3): cmd += " -O2"
@@ -1343,7 +1347,7 @@ def CompileLink(dll, obj, opts):
             if ("MFC" not in opts):
                 cmd += " /NOD:MFC90.LIB /NOD:MFC80.LIB /NOD:LIBCMT"
             cmd += " /NOD:LIBCI.LIB /DEBUG"
-            cmd += " /nod:libc /nod:libcmtd /nod:atlthunk /nod:atls"
+            cmd += " /nod:libc /nod:libcmtd /nod:atlthunk /nod:atls /nod:atlsd"
             if (GetOrigExt(dll) != ".exe"): cmd += " /DLL"
             optlevel = GetOptimizeOption(opts)
             if (optlevel==1): cmd += " /MAP /MAPINFO:EXPORTS /NOD:MSVCRT.LIB /NOD:MSVCPRT.LIB /NOD:MSVCIRT.LIB"
@@ -1394,7 +1398,7 @@ def CompileLink(dll, obj, opts):
             oscmd(cmd)
         else:
             cmd = "xilink"
-            if GetVerbose(): cmd += " /verbose:lib"            
+            if GetVerbose(): cmd += " /verbose:lib"
             if HasTargetArch():
                 cmd += " /MACHINE:" + GetTargetArch().upper()
             if ("MFC" not in opts):
@@ -2134,7 +2138,7 @@ def WriteConfigSettings():
 
     if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"):
         dtool_config["HAVE_WIN_TOUCHINPUT"] = '1'
-    
+
     if (GetOptimize() <= 3):
         dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
 
@@ -4475,7 +4479,7 @@ if (PkgSkip("DIRECT")==0):
     TargetAdd('packpanda.obj', opts=OPTS+['BUILDING:PACKPANDA'], input='ppython.cxx')
     TargetAdd('packpanda.exe', input='packpanda.obj')
     TargetAdd('packpanda.exe', opts=['PYTHON'])
-  
+
     DefSymbol("BUILDING:EGGCACHER", "IMPORT_MODULE", "direct.directscripts.eggcacher")
     TargetAdd('eggcacher.obj', opts=OPTS+['BUILDING:EGGCACHER'], input='ppython.cxx')
     TargetAdd('eggcacher.exe', input='eggcacher.obj')
@@ -4743,7 +4747,7 @@ if (RUNTIME and PkgSkip("NPAPI")==0):
 # DIRECTORY: direct/src/plugin_activex/
 #
 
-if (RUNTIME and GetTarget() == 'windows'):
+if (RUNTIME and GetTarget() == 'windows' and PkgSkip("MFC")==0):
   OPTS=['DIR:direct/src/plugin_activex', 'RUNTIME', 'ACTIVEX', 'MFC']
   DefSymbol('ACTIVEX', '_USRDLL', '')
   DefSymbol('ACTIVEX', '_WINDLL', '')
@@ -5810,7 +5814,7 @@ if (PkgSkip("PYTHON")==0 and not RUNTIME):
     TargetAdd('PandaModules.py', input='fx.pyd')
   if (PkgSkip("DIRECT")==0):
     TargetAdd('PandaModules.py', input='direct.pyd')
-  if (PkgSkip("VISION")==0):  
+  if (PkgSkip("VISION")==0):
     TargetAdd('PandaModules.py', input='vision.pyd')
   if (PkgSkip("SKEL")==0):
     TargetAdd('PandaModules.py', input='skel.pyd')
@@ -6047,11 +6051,25 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
     elif (os.path.isdir(file)):
         shutil.rmtree(file)
 
+    if GetTargetArch() == 'x64':
+        regview = '64'
+    else:
+        regview = '32'
+
     if (RUNTIME):
         # Invoke the make_installer script.
         AddToPathEnv("PATH", GetOutputDir() + "\\bin")
         AddToPathEnv("PATH", GetOutputDir() + "\\plugins")
-        oscmd(sys.executable + " -B direct\\src\\plugin_installer\\make_installer.py --version %s" % VERSION)
+
+        cmd = sys.executable + " -B -u direct\\src\\plugin_installer\\make_installer.py"
+        cmd += " --version %s --regview %s" % (VERSION, regview)
+
+        if GetTargetArch() == 'x64':
+            cmd += " --install \"$PROGRAMFILES64\\Panda3D\" "
+        else:
+            cmd += " --install \"$PROGRAMFILES32\\Panda3D\" "
+
+        oscmd(cmd)
         shutil.move("direct\\src\\plugin_installer\\p3d-setup.exe", file)
         return
 
@@ -6064,11 +6082,6 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
     psource = os.path.abspath(".")
     panda = os.path.abspath(GetOutputDir())
 
-    if GetTargetArch() == 'x64':
-        regview = '64'
-    else:
-        regview = '32'
-
     nsis_defs = {
         'COMPRESSOR'  : COMPRESSOR,
         'NAME'        : fullname,