diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 9dfdfbd200..b70effdf87 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -8,7 +8,6 @@ from __future__ import print_function import collections import os -import pip import plistlib import sys import subprocess @@ -393,6 +392,8 @@ class build_apps(setuptools.Command): directory containing the Python runtime libraries, which will be added to sys.path.""" + import pip + self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO) whldir = os.path.join(self.build_base, '__whl_cache__') @@ -639,6 +640,28 @@ class build_apps(setuptools.Command): freezer_modules = set() freezer_modpaths = set() ext_suffixes = set() + + def get_search_path_for(source_path): + search_path = [os.path.dirname(source_path)] + if use_wheels: + search_path.append(os.path.join(p3dwhlfn, 'deploy_libs')) + + # If the .whl containing this file has a .libs directory, add + # it to the path. This is an auditwheel/numpy convention. + if '.whl' + os.sep in source_path: + whl, wf = source_path.split('.whl' + os.path.sep) + whl += '.whl' + rootdir = wf.split(os.path.sep, 1)[0] + search_path.append(os.path.join(whl, rootdir, '.libs')) + + # Also look for more specific per-package cases, defined in + # PACKAGE_LIB_DIRS at the top of this file. + whl_name = os.path.basename(whl).split('-', 1)[0] + extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, []) + for extra_dir in extra_dirs: + search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep))) + return search_path + def create_runtime(appname, mainscript, use_console): freezer = FreezeTool.Freezer(platform=platform, path=path) freezer.addModule('__main__', filename=mainscript) @@ -781,26 +804,8 @@ class build_apps(setuptools.Command): continue # If this is a dynamic library, search for dependencies. - search_path = [os.path.dirname(source_path)] - if use_wheels: - search_path.append(os.path.join(p3dwhlfn, 'deploy_libs')) - - # If the .whl containing this file has a .libs directory, add - # it to the path. This is an auditwheel/numpy convention. - if '.whl' + os.sep in source_path: - whl, wf = source_path.split('.whl' + os.path.sep) - whl += '.whl' - rootdir = wf.split(os.path.sep, 1)[0] - search_path.append(os.path.join(whl, rootdir, '.libs')) - - # Also look for more specific per-package cases, defined in - # PACKAGE_LIB_DIRS at the top of this file. - whl_name = os.path.basename(whl).split('-', 1)[0] - extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, []) - for extra_dir in extra_dirs: - search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep))) - target_path = os.path.join(builddir, basename) + search_path = get_search_path_for(source_path) self.copy_with_dependencies(source_path, target_path, search_path) # Copy over the tcl directory. @@ -846,12 +851,15 @@ class build_apps(setuptools.Command): relpath = wf[len(source_dir) + 1:] source_path = os.path.join(whl, wf) target_path = os.path.join(target_dir, relpath) - self.copy(source_path, target_path) if 'PKG_DATA_MAKE_EXECUTABLE' in flags: + search_path = get_search_path_for(source_path) + self.copy_with_dependencies(source_path, target_path, search_path) mode = os.stat(target_path).st_mode mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH os.chmod(target_path, mode) + else: + self.copy(source_path, target_path) # Copy Game Files self.announce('Copying game files for platform: {}'.format(platform), distutils.log.INFO) diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py index ddcd35d05d..c5823a9efc 100644 --- a/direct/src/gui/DirectSlider.py +++ b/direct/src/gui/DirectSlider.py @@ -10,6 +10,7 @@ from panda3d.core import * from . import DirectGuiGlobals as DGG from .DirectFrame import * from .DirectButton import * +from math import isnan """ import DirectSlider @@ -89,12 +90,15 @@ class DirectSlider(DirectFrame): def __setValue(self): # This is the internal function that is called when # self['value'] is directly assigned. - self.guiItem.setValue(self['value']) + value = self['value'] + assert not isnan(value) + self.guiItem.setValue(value) def setValue(self, value): # This is the public function that is meant to be called by a # user that doesn't like to use (or doesn't understand) the # preferred interface of self['value']. + assert not isnan(value) self['value'] = value def getValue(self): diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index a89062a341..f706d7e495 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -11,8 +11,11 @@ This is a recommended bugfix release, especially for macOS users. * Fix NaN assertions when particles get very large positions (#822) * Add support for Autodesk Maya 2020 * Fix maya2egg erroring when running from a pip installation (#709) +* Support DualShock 4 (2nd gen) controller on Windows * Support .pz and .gz compressed models in deployment system * Support implicit namespace packages in deployment system (#778) +* Fix issues when using CEF Python on macOS with deployment system +* Fix deployment system issues reading .pyc files in some Python versions * Fix error with distutils package when deploying in a "virtualenv" env (#747) * Fix "NameError: name 'mdef' is not defined" error when deploying (#721) * Deployment system now strips weird -psn_* argument passed to macOS GUI apps diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 60cbf13239..7d19c6bb9e 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -1128,13 +1128,14 @@ find_display_mode(int width, int height) { int refresh_rate; mode = CGDisplayCopyDisplayMode(_display); -#if __MAC_OS_X_VERSION_MAX_ALLOWED < 1080 // First check if the current mode is adequate. - if (CGDisplayModeGetWidth(mode) == width && + // This test not done for macOS 10.15 and above as the mode resolution is + // not enough to identify a mode. + if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 && + CGDisplayModeGetWidth(mode) == width && CGDisplayModeGetHeight(mode) == height) { return mode; } -#endif current_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode); refresh_rate = CGDisplayModeGetRefreshRate(mode); diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 3651f14fb8..9411ad508b 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -70,16 +70,16 @@ static const struct DeviceMapping { {"face_a", "face_b", 0, "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", 0, 0, 0, "start", 0, "lstick", "rstick", 0} }, // Dualshock (PS4) - {0x054c, 0x05c4, InputDevice::DeviceClass::gamepad, 0, - {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick", "guide", 0} + {0x054c, 0x05c4, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, // Dualshock 2nd Gen (PS4 Slim) - {0x054c, 0x09cc, InputDevice::DeviceClass::gamepad, 0, - {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick", "guide", 0} + {0x054c, 0x09cc, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, // Dualshock 2nd Gen (PS4 wireless adapter) - {0x054c, 0x0ba0, InputDevice::DeviceClass::gamepad, 0, - {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick", "guide", 0} + {0x054c, 0x0ba0, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, + {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, {0}, }; @@ -475,18 +475,31 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { break; case HID_USAGE_GENERIC_RX: if (_device_class == DeviceClass::gamepad) { - axis = Axis::right_x; + if (quirks & QB_rstick_from_z) { + if ((quirks & QB_no_analog_triggers) == 0) { + axis = Axis::left_trigger; + } + } else { + axis = Axis::right_x; + } } else { axis = Axis::pitch; } break; case HID_USAGE_GENERIC_RY: if (_device_class == DeviceClass::gamepad) { - axis = Axis::right_y; + if (quirks & QB_rstick_from_z) { + if ((quirks & QB_no_analog_triggers) == 0) { + axis = Axis::right_trigger; + } + } else { + axis = Axis::right_y; + swap(cap.LogicalMin, cap.LogicalMax); + } } else { axis = Axis::roll; + swap(cap.LogicalMin, cap.LogicalMax); } - swap(cap.LogicalMin, cap.LogicalMax); break; case HID_USAGE_GENERIC_RZ: if (_device_class == DeviceClass::gamepad) {