mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Merge branch 'release/1.10.x'
This commit is contained in:
commit
0ac36185a9
@ -22,10 +22,12 @@ class DirectOptionMenu(DirectButton):
|
|||||||
# List of items to display on the popup menu
|
# List of items to display on the popup menu
|
||||||
('items', [], self.setItems),
|
('items', [], self.setItems),
|
||||||
# Initial item to display on menu button
|
# Initial item to display on menu button
|
||||||
# Can be an interger index or the same string as the button
|
# Can be an integer index or the same string as the button
|
||||||
('initialitem', None, DGG.INITOPT),
|
('initialitem', None, DGG.INITOPT),
|
||||||
# Amount of padding to place around popup button indicator
|
# Amount of padding to place around popup button indicator
|
||||||
('popupMarkerBorder', (.1, .1), None),
|
('popupMarkerBorder', (.1, .1), None),
|
||||||
|
# The initial position of the popup marker
|
||||||
|
('popupMarker_pos', (0, 0, 0), None),
|
||||||
# Background color to use to highlight popup menu items
|
# Background color to use to highlight popup menu items
|
||||||
('highlightColor', (.5, .5, .5, 1), None),
|
('highlightColor', (.5, .5, .5, 1), None),
|
||||||
# Extra scale to use on highlight popup menu items
|
# Extra scale to use on highlight popup menu items
|
||||||
@ -42,6 +44,8 @@ class DirectOptionMenu(DirectButton):
|
|||||||
DirectButton.__init__(self, parent)
|
DirectButton.__init__(self, parent)
|
||||||
# Record any user specified frame size
|
# Record any user specified frame size
|
||||||
self.initFrameSize = self['frameSize']
|
self.initFrameSize = self['frameSize']
|
||||||
|
# Record any user specified popup marker position
|
||||||
|
self.initPopupMarkerPos = self['popupMarker_pos']
|
||||||
# Create a small rectangular marker to distinguish this button
|
# Create a small rectangular marker to distinguish this button
|
||||||
# as a popup menu button
|
# as a popup menu button
|
||||||
self.popupMarker = self.createcomponent(
|
self.popupMarker = self.createcomponent(
|
||||||
@ -168,8 +172,13 @@ class DirectOptionMenu(DirectButton):
|
|||||||
else:
|
else:
|
||||||
# Or base it upon largest item
|
# Or base it upon largest item
|
||||||
bounds = [self.minX, self.maxX, self.minZ, self.maxZ]
|
bounds = [self.minX, self.maxX, self.minZ, self.maxZ]
|
||||||
pm.setPos(bounds[1] + pmw/2.0, 0,
|
if self.initPopupMarkerPos:
|
||||||
bounds[2] + (bounds[3] - bounds[2])/2.0)
|
# Use specified position
|
||||||
|
pmPos = list(self.initPopupMarkerPos)
|
||||||
|
else:
|
||||||
|
# Or base the position on the frame size.
|
||||||
|
pmPos = [bounds[1] + pmw/2.0, 0, bounds[2] + (bounds[3] - bounds[2])/2.0]
|
||||||
|
pm.setPos(pmPos[0], pmPos[1], pmPos[2])
|
||||||
# Adjust popup menu button to fit all items (or use user specified
|
# Adjust popup menu button to fit all items (or use user specified
|
||||||
# frame size
|
# frame size
|
||||||
bounds[1] += pmw
|
bounds[1] += pmw
|
||||||
@ -184,6 +193,12 @@ class DirectOptionMenu(DirectButton):
|
|||||||
Adjust popup position if default position puts it outside of
|
Adjust popup position if default position puts it outside of
|
||||||
visible screen region
|
visible screen region
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Needed attributes (such as minZ) won't be set unless the user has specified
|
||||||
|
# items to display. Let's assert that we've given items to work with.
|
||||||
|
items = self['items']
|
||||||
|
assert items and len(items) > 0, 'Cannot show an empty popup menu! You must add items!'
|
||||||
|
|
||||||
# Show the menu
|
# Show the menu
|
||||||
self.popupMenu.show()
|
self.popupMenu.show()
|
||||||
# Make sure its at the right scale
|
# Make sure its at the right scale
|
||||||
|
@ -53,6 +53,8 @@ class SfxPlayer:
|
|||||||
d = node.getDistance(listenerNode)
|
d = node.getDistance(listenerNode)
|
||||||
else:
|
else:
|
||||||
d = node.getDistance(base.cam)
|
d = node.getDistance(base.cam)
|
||||||
|
if not cutoff:
|
||||||
|
cutoff = self.cutoffDistance
|
||||||
if d == None or d > cutoff:
|
if d == None or d > cutoff:
|
||||||
volume = 0
|
volume = 0
|
||||||
else:
|
else:
|
||||||
@ -70,9 +72,6 @@ class SfxPlayer:
|
|||||||
self, sfx, looping = 0, interrupt = 1, volume = None,
|
self, sfx, looping = 0, interrupt = 1, volume = None,
|
||||||
time = 0.0, node=None, listenerNode = None, cutoff = None):
|
time = 0.0, node=None, listenerNode = None, cutoff = None):
|
||||||
if sfx:
|
if sfx:
|
||||||
if not cutoff:
|
|
||||||
cutoff = self.cutoffDistance
|
|
||||||
|
|
||||||
self.setFinalVolume(sfx, node, volume, listenerNode, cutoff)
|
self.setFinalVolume(sfx, node, volume, listenerNode, cutoff)
|
||||||
|
|
||||||
# don't start over if it's already playing, unless
|
# don't start over if it's already playing, unless
|
||||||
|
@ -9,13 +9,16 @@ __all__ = ['AnimPanel', 'ActorControl']
|
|||||||
# Import Tkinter, Pmw, and the floater code from this directory tree.
|
# Import Tkinter, Pmw, and the floater code from this directory tree.
|
||||||
from direct.tkwidgets.AppShell import *
|
from direct.tkwidgets.AppShell import *
|
||||||
from direct.showbase.TkGlobal import *
|
from direct.showbase.TkGlobal import *
|
||||||
import Pmw, sys
|
import Pmw, sys, os
|
||||||
from direct.task import Task
|
from direct.task import Task
|
||||||
|
from panda3d.core import Filename, getModelPath
|
||||||
|
|
||||||
if sys.version_info >= (3, 0):
|
if sys.version_info >= (3, 0):
|
||||||
from tkinter.simpledialog import askfloat
|
from tkinter.simpledialog import askfloat
|
||||||
|
from tkinter.filedialog import askopenfilename
|
||||||
else:
|
else:
|
||||||
from tkSimpleDialog import askfloat
|
from tkSimpleDialog import askfloat
|
||||||
|
from tkFileDialog import askopenfilename
|
||||||
|
|
||||||
|
|
||||||
FRAMES = 0
|
FRAMES = 0
|
||||||
@ -273,7 +276,7 @@ class AnimPanel(AppShell):
|
|||||||
title = 'Load Animation',
|
title = 'Load Animation',
|
||||||
parent = self.component('hull')
|
parent = self.component('hull')
|
||||||
)
|
)
|
||||||
if (animFilename == ''):
|
if not animFilename:
|
||||||
# no file selected, canceled
|
# no file selected, canceled
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -369,8 +372,9 @@ class AnimPanel(AppShell):
|
|||||||
def destroy(self):
|
def destroy(self):
|
||||||
# First clean up
|
# First clean up
|
||||||
taskMgr.remove(self.id + '_UpdateTask')
|
taskMgr.remove(self.id + '_UpdateTask')
|
||||||
self.destroyCallBack()
|
if self.destroyCallBack is not None:
|
||||||
self.destroyCallBack = None
|
self.destroyCallBack()
|
||||||
|
self.destroyCallBack = None
|
||||||
AppShell.destroy(self)
|
AppShell.destroy(self)
|
||||||
|
|
||||||
class ActorControl(Pmw.MegaWidget):
|
class ActorControl(Pmw.MegaWidget):
|
||||||
|
@ -656,25 +656,35 @@ def rgbPanel(nodePath, callback = None, style = 'mini'):
|
|||||||
pButton.pack(expand = 1, fill = BOTH)
|
pButton.pack(expand = 1, fill = BOTH)
|
||||||
|
|
||||||
# Update menu
|
# Update menu
|
||||||
menu = vgp.component('menubar').component('Valuator Group-menu')
|
menubar = vgp.component('menubar')
|
||||||
|
menubar.deletemenuitems('Valuator Group', 1, 1)
|
||||||
|
|
||||||
# Some helper functions
|
# Some helper functions
|
||||||
# Clear color
|
# Clear color
|
||||||
menu.insert_command(index = 1, label = 'Clear Color',
|
menubar.addmenuitem(
|
||||||
command = lambda: nodePath.clearColor())
|
'Valuator Group', 'command',
|
||||||
|
label='Clear Color', command=lambda: nodePath.clearColor())
|
||||||
# Set Clear Transparency
|
# Set Clear Transparency
|
||||||
menu.insert_command(index = 2, label = 'Set Transparency',
|
menubar.addmenuitem(
|
||||||
command = lambda: nodePath.setTransparency(1))
|
'Valuator Group', 'command',
|
||||||
menu.insert_command(
|
label='Set Transparency', command=lambda: nodePath.setTransparency(1))
|
||||||
index = 3, label = 'Clear Transparency',
|
menubar.addmenuitem(
|
||||||
command = lambda: nodePath.clearTransparency())
|
'Valuator Group', 'command',
|
||||||
|
label='Clear Transparency', command=lambda: nodePath.clearTransparency())
|
||||||
|
|
||||||
|
|
||||||
# System color picker
|
# System color picker
|
||||||
menu.insert_command(index = 4, label = 'Popup Color Picker',
|
menubar.addmenuitem(
|
||||||
command = popupColorPicker)
|
'Valuator Group', 'command',
|
||||||
|
label='Popup Color Picker', command=popupColorPicker)
|
||||||
|
|
||||||
menu.insert_command(index = 5, label = 'Print to log',
|
menubar.addmenuitem(
|
||||||
command = printToLog)
|
'Valuator Group', 'command',
|
||||||
|
label='Print to log', command=printToLog)
|
||||||
|
|
||||||
|
menubar.addmenuitem(
|
||||||
|
'Valuator Group', 'command', 'Dismiss Valuator Group panel',
|
||||||
|
label='Dismiss', command=vgp.destroy)
|
||||||
|
|
||||||
def setNodePathColor(color):
|
def setNodePathColor(color):
|
||||||
nodePath.setColor(color[0]/255.0, color[1]/255.0,
|
nodePath.setColor(color[0]/255.0, color[1]/255.0,
|
||||||
@ -724,18 +734,23 @@ def lightRGBPanel(light, style = 'mini'):
|
|||||||
# Update menu button
|
# Update menu button
|
||||||
vgp.component('menubar').component('Valuator Group-button')['text'] = (
|
vgp.component('menubar').component('Valuator Group-button')['text'] = (
|
||||||
'Light Control Panel')
|
'Light Control Panel')
|
||||||
|
|
||||||
# Add a print button which will also serve as a color tile
|
# Add a print button which will also serve as a color tile
|
||||||
pButton = Button(vgp.interior(), text = 'Print to Log',
|
pButton = Button(vgp.interior(), text = 'Print to Log',
|
||||||
bg = getTkColorString(initColor),
|
bg = getTkColorString(initColor),
|
||||||
command = printToLog)
|
command = printToLog)
|
||||||
pButton.pack(expand = 1, fill = BOTH)
|
pButton.pack(expand = 1, fill = BOTH)
|
||||||
|
|
||||||
# Update menu
|
# Update menu
|
||||||
menu = vgp.component('menubar').component('Valuator Group-menu')
|
menubar = vgp.component('menubar')
|
||||||
# System color picker
|
# System color picker
|
||||||
menu.insert_command(index = 4, label = 'Popup Color Picker',
|
menubar.addmenuitem(
|
||||||
command = popupColorPicker)
|
'Valuator Group', 'command',
|
||||||
menu.insert_command(index = 5, label = 'Print to log',
|
label='Popup Color Picker', command=popupColorPicker)
|
||||||
command = printToLog)
|
menubar.addmenuitem(
|
||||||
|
'Valuator Group', 'command',
|
||||||
|
label='Print to log', command=printToLog)
|
||||||
|
|
||||||
def setLightColor(color):
|
def setLightColor(color):
|
||||||
light.setColor(Vec4(color[0]/255.0, color[1]/255.0,
|
light.setColor(Vec4(color[0]/255.0, color[1]/255.0,
|
||||||
color[2]/255.0, color[3]/255.0))
|
color[2]/255.0, color[3]/255.0))
|
||||||
|
@ -4952,13 +4952,14 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||||||
expected_params += "NoneType";
|
expected_params += "NoneType";
|
||||||
|
|
||||||
} else if (TypeManager::is_char(type)) {
|
} else if (TypeManager::is_char(type)) {
|
||||||
indent(out, indent_level) << "char " << param_name << default_expr << ";\n";
|
indent(out, indent_level) << "char *" << param_name << "_str;\n";
|
||||||
|
indent(out, indent_level) << "Py_ssize_t " << param_name << "_len;\n";
|
||||||
|
|
||||||
format_specifiers += "c";
|
format_specifiers += "s#";
|
||||||
parameter_list += ", &" + param_name;
|
parameter_list += ", &" + param_name + "_str, &" + param_name + "_len";
|
||||||
|
extra_param_check << " && " << param_name << "_len == 1";
|
||||||
|
|
||||||
// extra_param_check << " && isascii(" << param_name << ")";
|
pexpr_string = param_name + "_str[0]";
|
||||||
pexpr_string = "(char) " + param_name;
|
|
||||||
expected_params += "char";
|
expected_params += "char";
|
||||||
only_pyobjects = false;
|
only_pyobjects = false;
|
||||||
|
|
||||||
|
@ -17,31 +17,34 @@ from optparse import OptionParser
|
|||||||
def test_wheel(wheel, verbose=False):
|
def test_wheel(wheel, verbose=False):
|
||||||
envdir = tempfile.mkdtemp(prefix="venv-")
|
envdir = tempfile.mkdtemp(prefix="venv-")
|
||||||
print("Setting up virtual environment in {0}".format(envdir))
|
print("Setting up virtual environment in {0}".format(envdir))
|
||||||
|
sys.stdout.flush()
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
subprocess.call([sys.executable, "-m", "venv", "--clear", envdir])
|
|
||||||
else:
|
|
||||||
subprocess.call([sys.executable, "-m", "virtualenv", "--clear", envdir])
|
|
||||||
|
|
||||||
# Make sure pip is up-to-date first.
|
# Make sure pip is up-to-date first.
|
||||||
if subprocess.call([sys.executable, "-m", "pip", "install", "-U", "pip"]) != 0:
|
subprocess.call([sys.executable, "-B", "-m", "pip", "install", "-U", "pip"])
|
||||||
shutil.rmtree(envdir)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Install pytest into the environment, as well as our wheel.
|
# Create a virtualenv.
|
||||||
if sys.platform == "win32":
|
if sys.version_info >= (3, 0):
|
||||||
pip = os.path.join(envdir, "Scripts", "pip.exe")
|
subprocess.call([sys.executable, "-B", "-m", "venv", "--clear", envdir])
|
||||||
else:
|
else:
|
||||||
pip = os.path.join(envdir, "bin", "pip")
|
subprocess.call([sys.executable, "-B", "-m", "virtualenv", "--clear", envdir])
|
||||||
if subprocess.call([pip, "install", "pytest", wheel]) != 0:
|
|
||||||
shutil.rmtree(envdir)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Run the test suite.
|
# Determine the path to the Python interpreter.
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
python = os.path.join(envdir, "Scripts", "python.exe")
|
python = os.path.join(envdir, "Scripts", "python.exe")
|
||||||
else:
|
else:
|
||||||
python = os.path.join(envdir, "bin", "python")
|
python = os.path.join(envdir, "bin", "python")
|
||||||
|
|
||||||
|
# Upgrade pip inside the environment too.
|
||||||
|
if subprocess.call([python, "-m", "pip", "install", "-U", "pip"]) != 0:
|
||||||
|
shutil.rmtree(envdir)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Install pytest into the environment, as well as our wheel.
|
||||||
|
if subprocess.call([python, "-m", "pip", "install", "pytest", wheel]) != 0:
|
||||||
|
shutil.rmtree(envdir)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Run the test suite.
|
||||||
test_cmd = [python, "-m", "pytest", "tests"]
|
test_cmd = [python, "-m", "pytest", "tests"]
|
||||||
if verbose:
|
if verbose:
|
||||||
test_cmd.append("--verbose")
|
test_cmd.append("--verbose")
|
||||||
|
@ -51,6 +51,8 @@ PUBLISHED:
|
|||||||
INLINE bool get_respect_prev_transform() const;
|
INLINE bool get_respect_prev_transform() const;
|
||||||
MAKE_PROPERTY(respect_prev_transform, get_respect_prev_transform,
|
MAKE_PROPERTY(respect_prev_transform, get_respect_prev_transform,
|
||||||
set_respect_prev_transform);
|
set_respect_prev_transform);
|
||||||
|
MAKE_PROPERTY(respect_prev_transform, get_respect_prev_transform,
|
||||||
|
set_respect_prev_transform);
|
||||||
|
|
||||||
void add_collider(const NodePath &collider, CollisionHandler *handler);
|
void add_collider(const NodePath &collider, CollisionHandler *handler);
|
||||||
bool remove_collider(const NodePath &collider);
|
bool remove_collider(const NodePath &collider);
|
||||||
|
@ -62,6 +62,9 @@ enum QuirkBits {
|
|||||||
// We only connect it if it is reporting any events, because when Steam is
|
// We only connect it if it is reporting any events, because when Steam is
|
||||||
// running, the Steam controller is muted in favour of a dummy Xbox device.
|
// running, the Steam controller is muted in favour of a dummy Xbox device.
|
||||||
QB_steam_controller = 32,
|
QB_steam_controller = 32,
|
||||||
|
|
||||||
|
// Axes on the right stick are swapped, using x for y and vice versa.
|
||||||
|
QB_right_axes_swapped = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct DeviceMapping {
|
static const struct DeviceMapping {
|
||||||
@ -81,7 +84,7 @@ static const struct DeviceMapping {
|
|||||||
// Steam Controller (wireless)
|
// Steam Controller (wireless)
|
||||||
{0x28de, 0x1142, InputDevice::DeviceClass::unknown, QB_steam_controller},
|
{0x28de, 0x1142, InputDevice::DeviceClass::unknown, QB_steam_controller},
|
||||||
// Jess Tech Colour Rumble Pad
|
// Jess Tech Colour Rumble Pad
|
||||||
{0x0f30, 0x0111, InputDevice::DeviceClass::gamepad, 0},
|
{0x0f30, 0x0111, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_right_axes_swapped},
|
||||||
// SPEED Link SL-6535-SBK-01
|
// SPEED Link SL-6535-SBK-01
|
||||||
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, 0},
|
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, 0},
|
||||||
// 8bitdo N30 Pro Controller
|
// 8bitdo N30 Pro Controller
|
||||||
@ -488,7 +491,11 @@ init_device() {
|
|||||||
break;
|
break;
|
||||||
case ABS_Z:
|
case ABS_Z:
|
||||||
if (quirks & QB_rstick_from_z) {
|
if (quirks & QB_rstick_from_z) {
|
||||||
axis = InputDevice::Axis::right_x;
|
if (quirks & QB_right_axes_swapped) {
|
||||||
|
axis = InputDevice::Axis::right_y;
|
||||||
|
} else {
|
||||||
|
axis = InputDevice::Axis::right_x;
|
||||||
|
}
|
||||||
} else if (_device_class == DeviceClass::gamepad) {
|
} else if (_device_class == DeviceClass::gamepad) {
|
||||||
axis = InputDevice::Axis::left_trigger;
|
axis = InputDevice::Axis::left_trigger;
|
||||||
have_analog_triggers = true;
|
have_analog_triggers = true;
|
||||||
@ -514,7 +521,11 @@ init_device() {
|
|||||||
break;
|
break;
|
||||||
case ABS_RZ:
|
case ABS_RZ:
|
||||||
if (quirks & QB_rstick_from_z) {
|
if (quirks & QB_rstick_from_z) {
|
||||||
axis = InputDevice::Axis::right_y;
|
if (quirks & QB_right_axes_swapped) {
|
||||||
|
axis = InputDevice::Axis::right_x;
|
||||||
|
} else {
|
||||||
|
axis = InputDevice::Axis::right_y;
|
||||||
|
}
|
||||||
} else if (_device_class == DeviceClass::gamepad) {
|
} else if (_device_class == DeviceClass::gamepad) {
|
||||||
axis = InputDevice::Axis::right_trigger;
|
axis = InputDevice::Axis::right_trigger;
|
||||||
have_analog_triggers = true;
|
have_analog_triggers = true;
|
||||||
|
@ -32,6 +32,12 @@ enum QuirkBits : int {
|
|||||||
|
|
||||||
// Throttle is reversed.
|
// Throttle is reversed.
|
||||||
QB_reversed_throttle = 4,
|
QB_reversed_throttle = 4,
|
||||||
|
|
||||||
|
// Right stick uses Z and Rz inputs.
|
||||||
|
QB_rstick_from_z = 8,
|
||||||
|
|
||||||
|
// Axes on the right stick are swapped, using x for y and vice versa.
|
||||||
|
QB_right_axes_swapped = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Some nonstandard gamepads have different button mappings.
|
// Some nonstandard gamepads have different button mappings.
|
||||||
@ -42,12 +48,17 @@ static const struct DeviceMapping {
|
|||||||
int quirks;
|
int quirks;
|
||||||
const char *buttons[16];
|
const char *buttons[16];
|
||||||
} mapping_presets[] = {
|
} mapping_presets[] = {
|
||||||
// SNES-style USB gamepad
|
// SNES-style USB gamepad, or cheap unbranded USB gamepad with no sticks
|
||||||
|
// ABXY are mapped based on their position, not based on their label.
|
||||||
{0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers,
|
{0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers,
|
||||||
{"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", "none", "none", "back", "start"}
|
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start"}
|
||||||
},
|
},
|
||||||
// SPEED Link SL-6535-SBK-01
|
// Unbranded generic cheap USB gamepad
|
||||||
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers,
|
{0x0810, 0x0001, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers | QB_right_axes_swapped,
|
||||||
|
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"}
|
||||||
|
},
|
||||||
|
// Trust GXT 24 / SPEED Link SL-6535-SBK-01
|
||||||
|
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers,
|
||||||
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"}
|
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"}
|
||||||
},
|
},
|
||||||
// T.Flight Hotas X
|
// T.Flight Hotas X
|
||||||
@ -56,7 +67,7 @@ static const struct DeviceMapping {
|
|||||||
},
|
},
|
||||||
// NVIDIA Shield Controller
|
// NVIDIA Shield Controller
|
||||||
{0x0955, 0x7214, InputDevice::DeviceClass::gamepad, 0,
|
{0x0955, 0x7214, InputDevice::DeviceClass::gamepad, 0,
|
||||||
{"face_a", "face_b", "n", "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", "e", "f", "g", "start", "h", "lstick", "rstick", "i"}
|
{"face_a", "face_b", 0, "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", 0, 0, 0, "start", 0, "lstick", "rstick", 0}
|
||||||
},
|
},
|
||||||
{0},
|
{0},
|
||||||
};
|
};
|
||||||
@ -422,7 +433,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
break;
|
break;
|
||||||
case HID_USAGE_GENERIC_Z:
|
case HID_USAGE_GENERIC_Z:
|
||||||
if (_device_class == DeviceClass::gamepad) {
|
if (_device_class == DeviceClass::gamepad) {
|
||||||
if ((quirks & QB_no_analog_triggers) == 0) {
|
if (quirks & QB_rstick_from_z) {
|
||||||
|
if (quirks & QB_right_axes_swapped) {
|
||||||
|
axis = InputDevice::Axis::right_y;
|
||||||
|
swap(cap.LogicalMin, cap.LogicalMax);
|
||||||
|
} else {
|
||||||
|
axis = InputDevice::Axis::right_x;
|
||||||
|
}
|
||||||
|
} else if ((quirks & QB_no_analog_triggers) == 0) {
|
||||||
axis = Axis::left_trigger;
|
axis = Axis::left_trigger;
|
||||||
}
|
}
|
||||||
} else if (_device_class == DeviceClass::flight_stick) {
|
} else if (_device_class == DeviceClass::flight_stick) {
|
||||||
@ -455,7 +473,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
break;
|
break;
|
||||||
case HID_USAGE_GENERIC_RZ:
|
case HID_USAGE_GENERIC_RZ:
|
||||||
if (_device_class == DeviceClass::gamepad) {
|
if (_device_class == DeviceClass::gamepad) {
|
||||||
if ((quirks & QB_no_analog_triggers) == 0) {
|
if (quirks & QB_rstick_from_z) {
|
||||||
|
if (quirks & QB_right_axes_swapped) {
|
||||||
|
axis = InputDevice::Axis::right_x;
|
||||||
|
} else {
|
||||||
|
axis = InputDevice::Axis::right_y;
|
||||||
|
swap(cap.LogicalMin, cap.LogicalMax);
|
||||||
|
}
|
||||||
|
} else if ((quirks & QB_no_analog_triggers) == 0) {
|
||||||
axis = Axis::right_trigger;
|
axis = Axis::right_trigger;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -481,6 +506,16 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this axis already exists, don't double-map it, but take the first
|
||||||
|
// one. This is important for the Trust GXT 24 / SL-6535-SBK-01 which
|
||||||
|
// have a weird extra Z axis with DataIndex 2 that should be ignored.
|
||||||
|
for (size_t i = 0; i < _axes.size(); ++i) {
|
||||||
|
if (_axes[i].axis == axis) {
|
||||||
|
axis = Axis::none;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int axis_index;
|
int axis_index;
|
||||||
if (!is_signed) {
|
if (!is_signed) {
|
||||||
// All axes on the weird XInput-style mappings go from -1 to 1
|
// All axes on the weird XInput-style mappings go from -1 to 1
|
||||||
|
@ -484,13 +484,9 @@ get_col(int col) const {
|
|||||||
*/
|
*/
|
||||||
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
|
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
|
||||||
get_row3(int row) const {
|
get_row3(int row) const {
|
||||||
#ifdef HAVE_EIGEN
|
|
||||||
return FLOATNAME(LVecBase3)(_m.block<1, 3>(row, 0));
|
|
||||||
#else
|
|
||||||
return FLOATNAME(LVecBase3)((*this)(row, 0),
|
return FLOATNAME(LVecBase3)((*this)(row, 0),
|
||||||
(*this)(row, 1),
|
(*this)(row, 1),
|
||||||
(*this)(row, 2));
|
(*this)(row, 2));
|
||||||
#endif // HAVE_EIGEN
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -514,13 +510,9 @@ get_row3(FLOATNAME(LVecBase3) &result_vec,int row) const {
|
|||||||
*/
|
*/
|
||||||
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
|
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
|
||||||
get_col3(int col) const {
|
get_col3(int col) const {
|
||||||
#ifdef HAVE_EIGEN
|
|
||||||
return FLOATNAME(LVecBase3)(_m.block<1, 3>(0, col));
|
|
||||||
#else
|
|
||||||
return FLOATNAME(LVecBase3)((*this)(0, col),
|
return FLOATNAME(LVecBase3)((*this)(0, col),
|
||||||
(*this)(1, col),
|
(*this)(1, col),
|
||||||
(*this)(2, col));
|
(*this)(2, col));
|
||||||
#endif // HAVE_EIGEN
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +104,7 @@ seek(double t) {
|
|||||||
if (result == OV_ENOSEEK && t == 0.0) {
|
if (result == OV_ENOSEEK && t == 0.0) {
|
||||||
std::istream *stream = (std::istream *)_ov.datasource;
|
std::istream *stream = (std::istream *)_ov.datasource;
|
||||||
|
|
||||||
if (stream->rdbuf()->pubseekpos(0, std::ios::in) == 0) {
|
if (stream->rdbuf()->pubseekpos(0, std::ios::in) == (std::streampos)0) {
|
||||||
// Back up the callbacks, then destroy the stream, making sure to first
|
// Back up the callbacks, then destroy the stream, making sure to first
|
||||||
// unset the datasource so that it won't close the file.
|
// unset the datasource so that it won't close the file.
|
||||||
ov_callbacks callbacks = _ov.callbacks;
|
ov_callbacks callbacks = _ov.callbacks;
|
||||||
|
@ -315,7 +315,7 @@ seek(double t) {
|
|||||||
} else if (pos < current) {
|
} else if (pos < current) {
|
||||||
// Can we seek to the beginning? Some streams, such as ZStream, let us
|
// Can we seek to the beginning? Some streams, such as ZStream, let us
|
||||||
// rewind the stream.
|
// rewind the stream.
|
||||||
if (buf->pubseekpos(0, std::ios::in) == 0) {
|
if (buf->pubseekpos(0, std::ios::in) == (std::streampos)0) {
|
||||||
if (pos > _data_start && movies_cat.is_info()) {
|
if (pos > _data_start && movies_cat.is_info()) {
|
||||||
Filename fn = get_source()->get_filename();
|
Filename fn = get_source()->get_filename();
|
||||||
movies_cat.info()
|
movies_cat.info()
|
||||||
|
@ -87,3 +87,39 @@ def test_mat4_invert_correct(type):
|
|||||||
|
|
||||||
assert (mat * inv).is_identity()
|
assert (mat * inv).is_identity()
|
||||||
assert (inv * mat).is_identity()
|
assert (inv * mat).is_identity()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||||
|
def test_mat4_rows(type):
|
||||||
|
mat = type((1, 2, 3, 4,
|
||||||
|
5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12,
|
||||||
|
13, 14, 15, 16))
|
||||||
|
|
||||||
|
assert mat.rows[0] == (1, 2, 3, 4)
|
||||||
|
assert mat.rows[1] == (5, 6, 7, 8)
|
||||||
|
assert mat.rows[2] == (9, 10, 11, 12)
|
||||||
|
assert mat.rows[3] == (13, 14, 15, 16)
|
||||||
|
|
||||||
|
assert mat.get_row3(0) == (1, 2, 3)
|
||||||
|
assert mat.get_row3(1) == (5, 6, 7)
|
||||||
|
assert mat.get_row3(2) == (9, 10, 11)
|
||||||
|
assert mat.get_row3(3) == (13, 14, 15)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f))
|
||||||
|
def test_mat4_cols(type):
|
||||||
|
mat = type((1, 5, 9, 13,
|
||||||
|
2, 6, 10, 14,
|
||||||
|
3, 7, 11, 15,
|
||||||
|
4, 8, 12, 16))
|
||||||
|
|
||||||
|
assert mat.cols[0] == (1, 2, 3, 4)
|
||||||
|
assert mat.cols[1] == (5, 6, 7, 8)
|
||||||
|
assert mat.cols[2] == (9, 10, 11, 12)
|
||||||
|
assert mat.cols[3] == (13, 14, 15, 16)
|
||||||
|
|
||||||
|
assert mat.get_col3(0) == (1, 2, 3)
|
||||||
|
assert mat.get_col3(1) == (5, 6, 7)
|
||||||
|
assert mat.get_col3(2) == (9, 10, 11)
|
||||||
|
assert mat.get_col3(3) == (13, 14, 15)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user