mirror of https://github.com/AxioDL/boo.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/boo
This commit is contained in:
commit
c642bccf03
494
CMakeLists.txt
494
CMakeLists.txt
|
@ -5,140 +5,232 @@ cmake_policy(SET CMP0074 NEW)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
if (NOT MSVC)
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET logvisor)
|
if (NOT TARGET logvisor)
|
||||||
add_subdirectory(logvisor)
|
add_subdirectory(logvisor)
|
||||||
endif()
|
endif()
|
||||||
|
add_subdirectory(soxr/src)
|
||||||
add_subdirectory(xxhash)
|
add_subdirectory(xxhash)
|
||||||
|
|
||||||
|
add_library(boo
|
||||||
|
lib/audiodev/Common.hpp
|
||||||
|
lib/audiodev/AudioMatrix.hpp
|
||||||
|
lib/audiodev/AudioSubmix.cpp
|
||||||
|
lib/audiodev/AudioSubmix.hpp
|
||||||
|
lib/audiodev/AudioVoice.cpp
|
||||||
|
lib/audiodev/AudioVoice.hpp
|
||||||
|
lib/audiodev/AudioVoiceEngine.cpp
|
||||||
|
lib/audiodev/AudioVoiceEngine.hpp
|
||||||
|
lib/audiodev/LtRtProcessing.cpp
|
||||||
|
lib/audiodev/LtRtProcessing.hpp
|
||||||
|
lib/audiodev/MIDICommon.cpp
|
||||||
|
lib/audiodev/MIDICommon.hpp
|
||||||
|
lib/audiodev/MIDIDecoder.cpp
|
||||||
|
lib/audiodev/MIDIEncoder.cpp
|
||||||
|
lib/audiodev/WAVOut.cpp
|
||||||
|
lib/Common.hpp
|
||||||
|
lib/graphicsdev/Common.cpp
|
||||||
|
lib/graphicsdev/Common.hpp
|
||||||
|
lib/inputdev/DeviceBase.cpp include/boo/inputdev/DeviceBase.hpp
|
||||||
|
lib/inputdev/CafeProPad.cpp include/boo/inputdev/CafeProPad.hpp
|
||||||
|
lib/inputdev/RevolutionPad.cpp include/boo/inputdev/RevolutionPad.hpp
|
||||||
|
lib/inputdev/DolphinSmashAdapter.cpp include/boo/inputdev/DolphinSmashAdapter.hpp
|
||||||
|
lib/inputdev/NintendoPowerA.cpp include/boo/inputdev/NintendoPowerA.hpp
|
||||||
|
lib/inputdev/DualshockPad.cpp include/boo/inputdev/DualshockPad.hpp
|
||||||
|
lib/inputdev/GenericPad.cpp include/boo/inputdev/GenericPad.hpp
|
||||||
|
lib/inputdev/DeviceSignature.cpp include/boo/inputdev/DeviceSignature.hpp
|
||||||
|
lib/inputdev/DeviceFinder.cpp include/boo/inputdev/DeviceFinder.hpp
|
||||||
|
lib/inputdev/HIDParser.cpp include/boo/inputdev/HIDParser.hpp
|
||||||
|
lib/inputdev/IHIDDevice.hpp
|
||||||
|
include/boo/IGraphicsContext.hpp
|
||||||
|
include/boo/audiodev/IAudioSubmix.hpp
|
||||||
|
include/boo/audiodev/IAudioVoice.hpp
|
||||||
|
include/boo/audiodev/IAudioVoiceEngine.hpp
|
||||||
|
include/boo/audiodev/IMIDIPort.hpp
|
||||||
|
include/boo/audiodev/IMIDIReader.hpp
|
||||||
|
include/boo/audiodev/MIDIDecoder.hpp
|
||||||
|
include/boo/audiodev/MIDIEncoder.hpp
|
||||||
|
include/boo/graphicsdev/IGraphicsDataFactory.hpp
|
||||||
|
include/boo/graphicsdev/IGraphicsCommandQueue.hpp
|
||||||
|
include/boo/inputdev/IHIDListener.hpp
|
||||||
|
include/boo/inputdev/XInputPad.hpp
|
||||||
|
include/boo/boo.hpp
|
||||||
|
include/boo/BooObject.hpp
|
||||||
|
include/boo/DeferredWindowEvents.hpp
|
||||||
|
include/boo/IApplication.hpp
|
||||||
|
include/boo/IWindow.hpp
|
||||||
|
include/boo/System.hpp
|
||||||
|
include/boo/ThreadLocalPtr.hpp
|
||||||
|
InputDeviceClasses.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if (NOT MSVC)
|
||||||
|
target_compile_options(boo PRIVATE -Wno-narrowing)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(BOO_GRAPHICS_DEBUG_GROUPS "Enable Debug Groups for labeling graphics passes within backend API." OFF)
|
option(BOO_GRAPHICS_DEBUG_GROUPS "Enable Debug Groups for labeling graphics passes within backend API." OFF)
|
||||||
if (BOO_GRAPHICS_DEBUG_GROUPS)
|
if (BOO_GRAPHICS_DEBUG_GROUPS)
|
||||||
message(STATUS "Enabling graphics debug groups")
|
message(STATUS "Enabling graphics debug groups")
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_GRAPHICS_DEBUG_GROUPS=1)
|
target_compile_definitions(boo PUBLIC -DBOO_GRAPHICS_DEBUG_GROUPS=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
||||||
find_package(IPP)
|
find_package(IPP)
|
||||||
if (IPP_FOUND)
|
if (IPP_FOUND)
|
||||||
list(APPEND _BOO_SYS_DEFINES -DINTEL_IPP=1)
|
target_compile_definitions(boo PUBLIC -DINTEL_IPP=1)
|
||||||
list(APPEND _BOO_SYS_INCLUDES ${IPP_INCLUDE_DIRS})
|
target_include_directories(boo PUBLIC ${IPP_INCLUDE_DIRS})
|
||||||
list(APPEND _BOO_SYS_LIBS ${IPP_LIBRARIES})
|
target_link_libraries(boo PUBLIC ${IPP_LIBRARIES})
|
||||||
message(STATUS "Building with IPP support")
|
message(STATUS "Building with IPP support")
|
||||||
else()
|
else()
|
||||||
message(WARNING "IPP not found; skipping support")
|
message(WARNING "IPP not found; skipping support")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_subdirectory(soxr/src)
|
|
||||||
|
|
||||||
set(_EXTRA_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
|
set(_EXTRA_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_include_directories(boo PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(lib/graphicsdev/nx)
|
add_subdirectory(lib/graphicsdev/nx)
|
||||||
if(TARGET nx_compiler)
|
if(TARGET nx_compiler)
|
||||||
list(APPEND _BOO_SYS_DEFINES -DHECL_NOUVEAU_NX=1)
|
target_compile_definitions(boo PUBLIC -DHECL_NOUVEAU_NX=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX)
|
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX)
|
||||||
add_library(glew lib/graphicsdev/glew.c)
|
add_library(glew lib/graphicsdev/glew.c)
|
||||||
|
# For some reason, clang takes forever if glew.c is not built with -Os
|
||||||
|
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||||
|
set_source_files_properties(lib/graphicsdev/glew.c PROPERTIES COMPILE_FLAGS -Os)
|
||||||
|
endif()
|
||||||
target_include_directories(glew PUBLIC include/boo/graphicsdev)
|
target_include_directories(glew PUBLIC include/boo/graphicsdev)
|
||||||
target_compile_definitions(glew PUBLIC -DGLEW_NO_GLU=1)
|
target_compile_definitions(glew PUBLIC -DGLEW_NO_GLU=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX AND NOT APPLE)
|
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX AND NOT APPLE)
|
||||||
list(APPEND PLAT_SRCS lib/graphicsdev/GL.cpp)
|
target_sources(boo PRIVATE lib/graphicsdev/GL.cpp)
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_GL=1)
|
target_compile_definitions(boo PUBLIC -DBOO_HAS_GL=1)
|
||||||
list(APPEND _BOO_SYS_LIBS glew)
|
target_link_libraries(boo PUBLIC glew)
|
||||||
|
|
||||||
list(APPEND PLAT_HDRS
|
target_sources(boo PRIVATE
|
||||||
include/boo/graphicsdev/GLSLMacros.hpp
|
include/boo/graphicsdev/GL.hpp
|
||||||
include/boo/graphicsdev/GL.hpp
|
include/boo/graphicsdev/GLSLMacros.hpp
|
||||||
include/boo/graphicsdev/Vulkan.hpp
|
include/boo/graphicsdev/Vulkan.hpp
|
||||||
include/boo/graphicsdev/VulkanDispatchTable.hpp)
|
include/boo/graphicsdev/VulkanDispatchTable.hpp
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WINDOWS_STORE)
|
if(WINDOWS_STORE)
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/win/ApplicationUWP.cpp
|
lib/audiodev/AudioMatrixSSE.cpp
|
||||||
lib/win/WindowUWP.cpp
|
lib/audiodev/WASAPI.cpp
|
||||||
lib/win/WinCommon.hpp
|
lib/inputdev/HIDDeviceUWP.cpp
|
||||||
lib/win/UWPCommon.hpp
|
lib/inputdev/HIDListenerUWP.cpp
|
||||||
lib/inputdev/HIDListenerUWP.cpp
|
lib/graphicsdev/D3D11.cpp
|
||||||
lib/inputdev/HIDDeviceUWP.cpp
|
lib/graphicsdev/D3D12.cpp
|
||||||
lib/graphicsdev/D3D11.cpp
|
lib/win/ApplicationUWP.cpp
|
||||||
lib/graphicsdev/D3D12.cpp
|
lib/win/UWPCommon.hpp
|
||||||
lib/audiodev/WASAPI.cpp
|
lib/win/WinCommon.hpp
|
||||||
lib/audiodev/AudioMatrixSSE.cpp)
|
lib/win/WindowUWP.cpp
|
||||||
|
|
||||||
list(APPEND PLAT_HDRS
|
include/boo/UWPViewProvider.hpp
|
||||||
include/boo/UWPViewProvider.hpp
|
include/boo/graphicsdev/D3D.hpp
|
||||||
include/boo/graphicsdev/D3D.hpp)
|
)
|
||||||
|
|
||||||
list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE)
|
target_compile_definitions(boo PUBLIC
|
||||||
|
-DUNICODE
|
||||||
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi Imm32 Winmm Shlwapi Hid Xinput)
|
-D_UNICODE
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(boo PUBLIC
|
||||||
|
Hid
|
||||||
|
Imm32
|
||||||
|
opengl32
|
||||||
|
Setupapi
|
||||||
|
Shlwapi
|
||||||
|
Winmm
|
||||||
|
Winusb
|
||||||
|
Xinput
|
||||||
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
unset(VULKAN_SDK_DIRS CACHE)
|
unset(VULKAN_SDK_DIRS CACHE)
|
||||||
get_filename_component(VULKAN_SDK_DIRS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\LunarG\\VulkanSDK;VK_SDK_PATHs]" ABSOLUTE CACHE)
|
get_filename_component(VULKAN_SDK_DIRS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\LunarG\\VulkanSDK;VK_SDK_PATHs]" ABSOLUTE CACHE)
|
||||||
if (NOT ${VULKAN_SDK_DIRS} STREQUAL "/registry")
|
if (NOT ${VULKAN_SDK_DIRS} STREQUAL "/registry")
|
||||||
message(STATUS "Enabling Vulkan support")
|
message(STATUS "Enabling Vulkan support")
|
||||||
list(GET VULKAN_SDK_DIRS 0 VULKAN_SDK_DIR)
|
list(GET VULKAN_SDK_DIRS 0 VULKAN_SDK_DIR)
|
||||||
list(APPEND _EXTRA_INCLUDES ${VULKAN_SDK_DIR}/Include)
|
target_include_directories(boo PRIVATE "${VULKAN_SDK_DIR}/Include")
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1 -DVK_USE_PLATFORM_WIN32_KHR=1)
|
target_compile_definitions(boo PUBLIC
|
||||||
list(APPEND _BOO_SYS_INCLUDES "${VULKAN_SDK_DIR}/Include")
|
-DBOO_HAS_VULKAN=1
|
||||||
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp
|
-DVK_USE_PLATFORM_WIN32_KHR=1
|
||||||
lib/graphicsdev/VulkanDispatchTable.cpp)
|
)
|
||||||
|
target_sources(boo PRIVATE
|
||||||
|
lib/graphicsdev/Vulkan.cpp
|
||||||
|
lib/graphicsdev/VulkanDispatchTable.cpp
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_file(TE_VIRTUAL_MIDI_H teVirtualMIDI.h PATHS
|
find_file(TE_VIRTUAL_MIDI_H teVirtualMIDI.h PATHS
|
||||||
"$ENV{PROGRAMFILES\(X86\)}/Tobias Erichsen/teVirtualMIDISDK/C-Binding")
|
"$ENV{PROGRAMFILES\(X86\)}/Tobias Erichsen/teVirtualMIDISDK/C-Binding")
|
||||||
|
find_file(TE_VIRTUAL_MIDI_H teVirtualMIDI.h
|
||||||
|
PATHS
|
||||||
|
"$ENV{PROGRAMFILES\(X86\)}/Tobias Erichsen/teVirtualMIDISDK/C-Binding"
|
||||||
|
)
|
||||||
if (NO AND TE_VIRTUAL_MIDI_H)
|
if (NO AND TE_VIRTUAL_MIDI_H)
|
||||||
message(STATUS "Enabling teVirtualMIDI")
|
message(STATUS "Enabling teVirtualMIDI")
|
||||||
get_filename_component(TE_VIRTUAL_MIDI_DIR ${TE_VIRTUAL_MIDI_H} DIRECTORY)
|
get_filename_component(TE_VIRTUAL_MIDI_DIR ${TE_VIRTUAL_MIDI_H} DIRECTORY)
|
||||||
list(APPEND _EXTRA_INCLUDES ${TE_VIRTUAL_MIDI_DIR})
|
target_include_directories(boo PRIVATE ${TE_VIRTUAL_MIDI_DIR})
|
||||||
add_definitions("-DTE_VIRTUAL_MIDI=1")
|
add_definitions("-DTE_VIRTUAL_MIDI=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/win/ApplicationWin32.cpp
|
lib/audiodev/AudioMatrixSSE.cpp
|
||||||
lib/win/WindowWin32.cpp
|
lib/audiodev/WASAPI.cpp
|
||||||
lib/win/WinCommon.hpp
|
lib/graphicsdev/D3D11.cpp
|
||||||
lib/win/Win32Common.hpp
|
lib/inputdev/HIDListenerWinUSB.cpp
|
||||||
lib/inputdev/HIDListenerWinUSB.cpp
|
lib/inputdev/HIDDeviceWinUSB.cpp
|
||||||
lib/inputdev/HIDDeviceWinUSB.cpp
|
lib/win/ApplicationWin32.cpp
|
||||||
lib/graphicsdev/D3D11.cpp
|
lib/win/WindowWin32.cpp
|
||||||
lib/audiodev/WASAPI.cpp
|
lib/win/WinCommon.hpp
|
||||||
lib/audiodev/AudioMatrixSSE.cpp)
|
lib/win/Win32Common.hpp
|
||||||
|
|
||||||
list(APPEND PLAT_HDRS
|
include/boo/graphicsdev/D3D.hpp
|
||||||
include/boo/graphicsdev/D3D.hpp)
|
)
|
||||||
|
|
||||||
list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE)
|
target_compile_definitions(boo PUBLIC
|
||||||
|
-DUNICODE
|
||||||
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi Imm32 Winmm Shlwapi Hid Xinput)
|
-D_UNICODE
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(boo PUBLIC
|
||||||
|
Hid
|
||||||
|
Imm32
|
||||||
|
Setupapi
|
||||||
|
Shlwapi
|
||||||
|
Winmm
|
||||||
|
Winusb opengl32
|
||||||
|
Xinput
|
||||||
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/mac/ApplicationCocoa.mm
|
lib/audiodev/AQS.cpp
|
||||||
lib/mac/WindowCocoa.mm
|
lib/audiodev/AudioMatrixSSE.cpp
|
||||||
lib/mac/CocoaCommon.hpp
|
lib/inputdev/HIDListenerIOKit.cpp
|
||||||
lib/inputdev/HIDListenerIOKit.cpp
|
lib/inputdev/HIDDeviceIOKit.cpp
|
||||||
lib/inputdev/HIDDeviceIOKit.cpp
|
lib/mac/ApplicationCocoa.mm
|
||||||
lib/graphicsdev/Metal.mm
|
lib/mac/WindowCocoa.mm
|
||||||
lib/audiodev/AQS.cpp
|
lib/mac/CocoaCommon.hpp
|
||||||
lib/audiodev/AudioMatrixSSE.cpp)
|
lib/graphicsdev/Metal.mm
|
||||||
set_source_files_properties(lib/mac/ApplicationCocoa.mm
|
|
||||||
lib/mac/WindowCocoa.mm
|
|
||||||
lib/graphicsdev/Metal.mm
|
|
||||||
PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
|
||||||
|
|
||||||
list(APPEND PLAT_HDRS
|
lib/CFPointer.hpp
|
||||||
lib/CFPointer.hpp
|
lib/inputdev/IOKitPointer.hpp
|
||||||
include/boo/graphicsdev/Metal.hpp
|
include/boo/graphicsdev/Metal.hpp
|
||||||
lib/inputdev/IOKitPointer.hpp)
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(
|
||||||
|
lib/mac/ApplicationCocoa.mm
|
||||||
|
lib/mac/WindowCocoa.mm
|
||||||
|
lib/graphicsdev/Metal.mm
|
||||||
|
PROPERTIES COMPILE_FLAGS -fobjc-arc
|
||||||
|
)
|
||||||
|
|
||||||
find_library(APPKIT_LIBRARY AppKit)
|
find_library(APPKIT_LIBRARY AppKit)
|
||||||
find_library(IOKIT_LIBRARY IOKit)
|
find_library(IOKIT_LIBRARY IOKit)
|
||||||
|
@ -146,7 +238,7 @@ elseif(APPLE)
|
||||||
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.11)
|
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.11)
|
||||||
set(BOO_HAS_METAL ON CACHE BOOL "Metal is available in this OS X version" FORCE)
|
set(BOO_HAS_METAL ON CACHE BOOL "Metal is available in this OS X version" FORCE)
|
||||||
find_library(METAL_LIBRARY Metal)
|
find_library(METAL_LIBRARY Metal)
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_METAL=1)
|
target_compile_definitions(boo PUBLIC -DBOO_HAS_METAL=1)
|
||||||
else()
|
else()
|
||||||
set(METAL_LIBRARY "")
|
set(METAL_LIBRARY "")
|
||||||
endif()
|
endif()
|
||||||
|
@ -155,31 +247,39 @@ elseif(APPLE)
|
||||||
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
|
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
|
||||||
find_library(COREAUDIO_LIBRARY CoreAudio)
|
find_library(COREAUDIO_LIBRARY CoreAudio)
|
||||||
find_library(COREMIDI_LIBRARY CoreMIDI)
|
find_library(COREMIDI_LIBRARY CoreMIDI)
|
||||||
list(APPEND _BOO_SYS_LIBS ${APPKIT_LIBRARY} ${IOKIT_LIBRARY} ${METAL_LIBRARY}
|
|
||||||
${QUARTZCORE_LIBRARY} ${COREVIDEO_LIBRARY} ${AUDIOTOOLBOX_LIBRARY}
|
|
||||||
${COREAUDIO_LIBRARY} ${COREMIDI_LIBRARY})
|
|
||||||
|
|
||||||
|
target_link_libraries(boo PUBLIC
|
||||||
|
${APPKIT_LIBRARY}
|
||||||
|
${AUDIOTOOLBOX_LIBRARY}
|
||||||
|
${COREAUDIO_LIBRARY}
|
||||||
|
${COREMIDI_LIBRARY}
|
||||||
|
${COREVIDEO_LIBRARY}
|
||||||
|
${IOKIT_LIBRARY}
|
||||||
|
${METAL_LIBRARY}
|
||||||
|
${QUARTZCORE_LIBRARY}
|
||||||
|
)
|
||||||
elseif(NX)
|
elseif(NX)
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_NX=1)
|
target_compile_definitions(boo PUBLIC -DBOO_HAS_NX=1)
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/nx/ApplicationNX.cpp
|
lib/nx/ApplicationNX.cpp
|
||||||
lib/nx/WindowNX.cpp
|
lib/nx/WindowNX.cpp
|
||||||
lib/audiodev/AudioMatrix.cpp
|
lib/audiodev/AudioMatrix.cpp
|
||||||
lib/inputdev/HIDListenerNX.cpp
|
lib/inputdev/HIDListenerNX.cpp
|
||||||
lib/inputdev/HIDDeviceNX.cpp)
|
lib/inputdev/HIDDeviceNX.cpp
|
||||||
list(APPEND _BOO_SYS_LIBS nx_runtime)
|
)
|
||||||
|
target_link_libraries(boo PUBLIC nx_runtime)
|
||||||
else(NOT GEKKO)
|
else(NOT GEKKO)
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/x11/XlibCommon.hpp
|
lib/audiodev/LinuxMidi.hpp
|
||||||
lib/x11/ApplicationUnix.cpp
|
lib/graphicsdev/GL.cpp
|
||||||
lib/x11/ApplicationXlib.hpp
|
lib/graphicsdev/GLX.cpp
|
||||||
lib/x11/ApplicationWayland.hpp
|
lib/x11/XlibCommon.hpp
|
||||||
lib/x11/WindowXlib.cpp
|
lib/x11/ApplicationUnix.cpp
|
||||||
lib/x11/WindowWayland.cpp
|
lib/x11/ApplicationWayland.hpp
|
||||||
lib/graphicsdev/GL.cpp
|
lib/x11/ApplicationXlib.hpp
|
||||||
lib/graphicsdev/GLX.cpp
|
lib/x11/WindowWayland.cpp
|
||||||
lib/audiodev/LinuxMidi.hpp)
|
lib/x11/WindowXlib.cpp
|
||||||
|
)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
if(PKG_CONFIG_FOUND)
|
if(PKG_CONFIG_FOUND)
|
||||||
|
@ -188,84 +288,120 @@ else(NOT GEKKO)
|
||||||
|
|
||||||
find_path(DBUS_INCLUDE_DIR
|
find_path(DBUS_INCLUDE_DIR
|
||||||
NAMES
|
NAMES
|
||||||
dbus/dbus.h
|
dbus/dbus.h
|
||||||
|
|
||||||
HINTS
|
HINTS
|
||||||
${dbus_pkg_INCLUDE_DIRS}
|
${dbus_pkg_INCLUDE_DIRS}
|
||||||
|
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
include/
|
include/
|
||||||
include/dbus-1.0/
|
include/dbus-1.0/
|
||||||
dbus-1.0/)
|
dbus-1.0/
|
||||||
|
)
|
||||||
|
|
||||||
find_path(DBUS_ARCH_INCLUDE_DIR
|
find_path(DBUS_ARCH_INCLUDE_DIR
|
||||||
NAMES
|
NAMES
|
||||||
dbus/dbus-arch-deps.h
|
dbus/dbus-arch-deps.h
|
||||||
|
|
||||||
HINTS
|
HINTS
|
||||||
${dbus_pkg_INCLUDE_DIRS}
|
${dbus_pkg_INCLUDE_DIRS}
|
||||||
|
|
||||||
PATHS
|
PATHS
|
||||||
# TODO use CMAKE_SYSTEM_PROCESSOR or similar?
|
# TODO use CMAKE_SYSTEM_PROCESSOR or similar?
|
||||||
/usr/lib/dbus-1.0/include
|
/usr/lib/dbus-1.0/include
|
||||||
/usr/local/lib/dbus-1.0/include
|
/usr/local/lib/dbus-1.0/include
|
||||||
/usr/lib/x86_64-linux-gnu/dbus-1.0/include/
|
/usr/lib/x86_64-linux-gnu/dbus-1.0/include/
|
||||||
|
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
dbus-1.0/include/)
|
dbus-1.0/include/
|
||||||
|
)
|
||||||
|
|
||||||
find_library(DBUS_LIBRARY
|
find_library(DBUS_LIBRARY
|
||||||
NAMES
|
NAMES
|
||||||
dbus dbus-1
|
dbus
|
||||||
|
dbus-1
|
||||||
|
|
||||||
HINTS
|
HINTS
|
||||||
${dbus_pkg_LIBRARY_DIRS}
|
${dbus_pkg_LIBRARY_DIRS}
|
||||||
|
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
lib
|
lib
|
||||||
lib32
|
lib32
|
||||||
lib64)
|
lib64
|
||||||
|
)
|
||||||
|
|
||||||
find_path(PULSEAUDIO_INCLUDE_DIR
|
find_path(PULSEAUDIO_INCLUDE_DIR
|
||||||
NAMES pulse/pulseaudio.h)
|
NAMES pulse/pulseaudio.h
|
||||||
|
)
|
||||||
if(PULSEAUDIO_INCLUDE_DIR-NOTFOUND)
|
if(PULSEAUDIO_INCLUDE_DIR-NOTFOUND)
|
||||||
message(FATAL_ERROR "Unix build of boo requires pulseaudio")
|
message(FATAL_ERROR "Unix build of boo requires pulseaudio")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND PLAT_SRCS lib/audiodev/PulseAudio.cpp)
|
target_sources(boo PRIVATE lib/audiodev/PulseAudio.cpp)
|
||||||
list(APPEND _BOO_SYS_LIBS pulse)
|
target_link_libraries(boo PUBLIC pulse)
|
||||||
|
|
||||||
if(DBUS_INCLUDE_DIR-NOTFOUND)
|
if(DBUS_INCLUDE_DIR-NOTFOUND)
|
||||||
message(FATAL_ERROR "Unix build of boo requires dbus")
|
message(FATAL_ERROR "Unix build of boo requires dbus")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND _EXTRA_INCLUDES ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
target_include_directories(boo PRIVATE
|
||||||
list(APPEND _BOO_SYS_LIBS X11 Xi Xrandr GL asound ${DBUS_LIBRARY} pthread)
|
${DBUS_ARCH_INCLUDE_DIR}
|
||||||
|
${DBUS_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(boo
|
||||||
|
PUBLIC
|
||||||
|
asound
|
||||||
|
${DBUS_LIBRARY}
|
||||||
|
GL
|
||||||
|
pthread
|
||||||
|
X11
|
||||||
|
Xi
|
||||||
|
Xrandr
|
||||||
|
)
|
||||||
|
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
find_path(VULKAN_INCLUDE_DIR
|
find_path(VULKAN_INCLUDE_DIR
|
||||||
NAMES vulkan/vulkan.h)
|
NAMES vulkan/vulkan.h
|
||||||
|
)
|
||||||
if(VULKAN_INCLUDE_DIR)
|
if(VULKAN_INCLUDE_DIR)
|
||||||
message(STATUS "Enabling Vulkan support")
|
message(STATUS "Enabling Vulkan support")
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/graphicsdev/Vulkan.cpp
|
lib/graphicsdev/Vulkan.cpp
|
||||||
lib/graphicsdev/VulkanDispatchTable.cpp)
|
lib/graphicsdev/VulkanDispatchTable.cpp
|
||||||
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1 -DVK_USE_PLATFORM_XCB_KHR=1)
|
)
|
||||||
|
target_compile_definitions(boo
|
||||||
|
PUBLIC
|
||||||
|
-DBOO_HAS_VULKAN=1
|
||||||
|
-DVK_USE_PLATFORM_XCB_KHR=1
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/inputdev/HIDListenerUdev.cpp
|
lib/audiodev/AudioMatrixSSE.cpp
|
||||||
lib/inputdev/HIDDeviceUdev.cpp
|
lib/inputdev/HIDDeviceUdev.cpp
|
||||||
lib/audiodev/AudioMatrixSSE.cpp)
|
lib/inputdev/HIDListenerUdev.cpp
|
||||||
list(APPEND _BOO_SYS_LIBS xcb X11-xcb dl udev)
|
)
|
||||||
|
target_link_libraries(boo
|
||||||
|
PUBLIC
|
||||||
|
dl
|
||||||
|
xcb
|
||||||
|
X11-xcb
|
||||||
|
udev
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
list(APPEND PLAT_SRCS
|
target_sources(boo PRIVATE
|
||||||
lib/inputdev/HIDListenerBSD.cpp
|
lib/audiodev/AudioMatrixSSE.cpp
|
||||||
lib/inputdev/HIDDeviceBSD.cpp
|
lib/inputdev/HIDDeviceBSD.cpp
|
||||||
lib/audiodev/AudioMatrixSSE.cpp)
|
lib/inputdev/HIDListenerBSD.cpp
|
||||||
list(APPEND _BOO_SYS_LIBS execinfo)
|
)
|
||||||
|
target_link_libraries(boo
|
||||||
|
PUBLIC
|
||||||
|
execinfo
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT NX)
|
if(NOT NX)
|
||||||
# For some reason, clang takes forever if glew.c is not built with -Os
|
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
|
||||||
set_source_files_properties(lib/graphicsdev/glew.c PROPERTIES COMPILE_FLAGS -Os)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Empty link args for boo's use
|
# Empty link args for boo's use
|
||||||
function(glslang_set_link_args TARGET)
|
function(glslang_set_link_args TARGET)
|
||||||
endfunction(glslang_set_link_args)
|
endfunction(glslang_set_link_args)
|
||||||
|
@ -286,67 +422,29 @@ if(NOT NX)
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/glslang
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/glslang
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND _BOO_SYS_LIBS glslang soxr xxhash OSDependent OGLCompiler SPIRV glslang-default-resource-limits)
|
target_link_libraries(boo
|
||||||
|
PUBLIC
|
||||||
|
glslang
|
||||||
|
glslang-default-resource-limits
|
||||||
|
OGLCompiler
|
||||||
|
OSDependent
|
||||||
|
soxr
|
||||||
|
SPIRV
|
||||||
|
xxhash
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND _EXTRA_INCLUDES glslang soxr/src)
|
target_link_libraries(boo PUBLIC logvisor)
|
||||||
|
target_include_directories(boo
|
||||||
|
PUBLIC
|
||||||
|
include
|
||||||
|
|
||||||
|
PRIVATE
|
||||||
|
glslang
|
||||||
|
soxr/src
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
add_library(boo
|
|
||||||
lib/inputdev/DeviceBase.cpp include/boo/inputdev/DeviceBase.hpp
|
|
||||||
lib/inputdev/CafeProPad.cpp include/boo/inputdev/CafeProPad.hpp
|
|
||||||
lib/inputdev/RevolutionPad.cpp include/boo/inputdev/RevolutionPad.hpp
|
|
||||||
lib/inputdev/DolphinSmashAdapter.cpp include/boo/inputdev/DolphinSmashAdapter.hpp
|
|
||||||
lib/inputdev/NintendoPowerA.cpp include/boo/inputdev/NintendoPowerA.hpp
|
|
||||||
lib/inputdev/DualshockPad.cpp include/boo/inputdev/DualshockPad.hpp
|
|
||||||
include/boo/inputdev/XInputPad.hpp
|
|
||||||
lib/inputdev/GenericPad.cpp include/boo/inputdev/GenericPad.hpp
|
|
||||||
lib/inputdev/DeviceSignature.cpp include/boo/inputdev/DeviceSignature.hpp
|
|
||||||
lib/inputdev/DeviceFinder.cpp include/boo/inputdev/DeviceFinder.hpp
|
|
||||||
lib/inputdev/HIDParser.cpp include/boo/inputdev/HIDParser.hpp
|
|
||||||
lib/inputdev/IHIDDevice.hpp
|
|
||||||
lib/audiodev/Common.hpp
|
|
||||||
lib/audiodev/WAVOut.cpp
|
|
||||||
lib/audiodev/AudioMatrix.hpp
|
|
||||||
lib/audiodev/AudioVoiceEngine.hpp
|
|
||||||
lib/audiodev/AudioVoiceEngine.cpp
|
|
||||||
lib/audiodev/AudioVoice.hpp
|
|
||||||
lib/audiodev/AudioVoice.cpp
|
|
||||||
lib/audiodev/AudioSubmix.hpp
|
|
||||||
lib/audiodev/AudioSubmix.cpp
|
|
||||||
lib/audiodev/LtRtProcessing.hpp
|
|
||||||
lib/audiodev/LtRtProcessing.cpp
|
|
||||||
lib/audiodev/MIDIEncoder.cpp
|
|
||||||
lib/audiodev/MIDIDecoder.cpp
|
|
||||||
lib/audiodev/MIDICommon.hpp
|
|
||||||
lib/audiodev/MIDICommon.cpp
|
|
||||||
lib/Common.hpp
|
|
||||||
include/boo/inputdev/IHIDListener.hpp
|
|
||||||
include/boo/IGraphicsContext.hpp
|
|
||||||
include/boo/graphicsdev/IGraphicsDataFactory.hpp
|
|
||||||
include/boo/graphicsdev/IGraphicsCommandQueue.hpp
|
|
||||||
lib/graphicsdev/Common.hpp
|
|
||||||
lib/graphicsdev/Common.cpp
|
|
||||||
include/boo/audiodev/IAudioSubmix.hpp
|
|
||||||
include/boo/audiodev/IAudioVoice.hpp
|
|
||||||
include/boo/audiodev/IMIDIPort.hpp
|
|
||||||
include/boo/audiodev/IMIDIReader.hpp
|
|
||||||
include/boo/audiodev/MIDIEncoder.hpp
|
|
||||||
include/boo/audiodev/MIDIDecoder.hpp
|
|
||||||
include/boo/audiodev/IAudioVoiceEngine.hpp
|
|
||||||
include/boo/IWindow.hpp
|
|
||||||
include/boo/IApplication.hpp
|
|
||||||
include/boo/ThreadLocalPtr.hpp
|
|
||||||
include/boo/DeferredWindowEvents.hpp
|
|
||||||
include/boo/System.hpp
|
|
||||||
include/boo/BooObject.hpp
|
|
||||||
include/boo/boo.hpp
|
|
||||||
InputDeviceClasses.cpp
|
|
||||||
${PLAT_SRCS}
|
|
||||||
${PLAT_HDRS})
|
|
||||||
target_link_libraries(boo PUBLIC ${_BOO_SYS_LIBS} logvisor)
|
|
||||||
target_compile_definitions(boo PUBLIC ${_BOO_SYS_DEFINES})
|
|
||||||
target_include_directories(boo PUBLIC include ${_BOO_SYS_INCLUDES}
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${_EXTRA_INCLUDES})
|
|
||||||
if(COMMAND add_sanitizers)
|
if(COMMAND add_sanitizers)
|
||||||
add_sanitizers(boo)
|
add_sanitizers(boo)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
|
||||||
#include "nxstl/mutex"
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -13,11 +11,10 @@ protected:
|
||||||
virtual ~IObj() = default;
|
virtual ~IObj() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual std::unique_lock<std::recursive_mutex> destructorLock() = 0;
|
void increment() noexcept { m_refCount.fetch_add(1, std::memory_order_relaxed); }
|
||||||
void increment() { m_refCount++; }
|
void decrement() noexcept {
|
||||||
void decrement() {
|
if (m_refCount.fetch_sub(1, std::memory_order_release) == 1) {
|
||||||
if (m_refCount.fetch_sub(1) == 1) {
|
std::atomic_thread_fence(std::memory_order_acquire);
|
||||||
auto lk = destructorLock();
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,17 +25,17 @@ class ObjToken {
|
||||||
SubCls* m_obj = nullptr;
|
SubCls* m_obj = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjToken() = default;
|
ObjToken() noexcept = default;
|
||||||
ObjToken(SubCls* obj) : m_obj(obj) {
|
ObjToken(SubCls* obj) noexcept : m_obj(obj) {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->increment();
|
m_obj->increment();
|
||||||
}
|
}
|
||||||
ObjToken(const ObjToken& other) : m_obj(other.m_obj) {
|
ObjToken(const ObjToken& other) noexcept : m_obj(other.m_obj) {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->increment();
|
m_obj->increment();
|
||||||
}
|
}
|
||||||
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
ObjToken(ObjToken&& other) noexcept : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
||||||
ObjToken& operator=(SubCls* obj) {
|
ObjToken& operator=(SubCls* obj) noexcept {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->decrement();
|
m_obj->decrement();
|
||||||
m_obj = obj;
|
m_obj = obj;
|
||||||
|
@ -46,7 +43,7 @@ public:
|
||||||
m_obj->increment();
|
m_obj->increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ObjToken& operator=(const ObjToken& other) {
|
ObjToken& operator=(const ObjToken& other) noexcept {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->decrement();
|
m_obj->decrement();
|
||||||
m_obj = other.m_obj;
|
m_obj = other.m_obj;
|
||||||
|
@ -54,26 +51,28 @@ public:
|
||||||
m_obj->increment();
|
m_obj->increment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ObjToken& operator=(ObjToken&& other) {
|
ObjToken& operator=(ObjToken&& other) noexcept {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->decrement();
|
m_obj->decrement();
|
||||||
m_obj = other.m_obj;
|
m_obj = other.m_obj;
|
||||||
other.m_obj = nullptr;
|
other.m_obj = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
~ObjToken() {
|
~ObjToken() noexcept {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->decrement();
|
m_obj->decrement();
|
||||||
}
|
}
|
||||||
SubCls* get() const { return m_obj; }
|
SubCls* get() const noexcept { return m_obj; }
|
||||||
SubCls* operator->() const { return m_obj; }
|
SubCls* operator->() const noexcept { return m_obj; }
|
||||||
SubCls& operator*() const { return *m_obj; }
|
SubCls& operator*() const noexcept { return *m_obj; }
|
||||||
template <class T>
|
template <class T>
|
||||||
T* cast() const {
|
T* cast() const noexcept {
|
||||||
return static_cast<T*>(m_obj);
|
return static_cast<T*>(m_obj);
|
||||||
}
|
}
|
||||||
operator bool() const { return m_obj != nullptr; }
|
explicit operator bool() const noexcept { return m_obj != nullptr; }
|
||||||
void reset() {
|
constexpr bool operator==(const ObjToken& other) const noexcept { return m_obj == other.m_obj; }
|
||||||
|
constexpr bool operator!=(const ObjToken& other) const noexcept { return !(*this == other); }
|
||||||
|
void reset() noexcept {
|
||||||
if (m_obj)
|
if (m_obj)
|
||||||
m_obj->decrement();
|
m_obj->decrement();
|
||||||
m_obj = nullptr;
|
m_obj = nullptr;
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boo/boo.hpp>
|
#include <chrono>
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
#include "nxstl/condition_variable"
|
#include "nxstl/condition_variable"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
@ -15,11 +18,11 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
|
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
|
||||||
|
|
||||||
bool m_destroyed = false;
|
bool m_destroyed = false;
|
||||||
void destroyed() { m_destroyed = true; }
|
void destroyed() override { m_destroyed = true; }
|
||||||
|
|
||||||
bool m_hasResize = false;
|
bool m_hasResize = false;
|
||||||
SWindowRect m_latestResize;
|
SWindowRect m_latestResize;
|
||||||
void resized(const SWindowRect& rect, bool sync) {
|
void resized(const SWindowRect& rect, bool sync) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_latestResize = rect;
|
m_latestResize = rect;
|
||||||
m_hasResize = true;
|
m_hasResize = true;
|
||||||
|
@ -112,7 +115,7 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
};
|
};
|
||||||
std::vector<Command> m_cmds;
|
std::vector<Command> m_cmds;
|
||||||
|
|
||||||
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
|
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::MouseDown);
|
m_cmds.emplace_back(Command::Type::MouseDown);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
|
@ -120,7 +123,7 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
m_cmds.back().m_mods = mods;
|
m_cmds.back().m_mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) {
|
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::MouseUp);
|
m_cmds.emplace_back(Command::Type::MouseUp);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
|
@ -128,53 +131,53 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
m_cmds.back().m_mods = mods;
|
m_cmds.back().m_mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseMove(const SWindowCoord& coord) {
|
void mouseMove(const SWindowCoord& coord) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::MouseMove);
|
m_cmds.emplace_back(Command::Type::MouseMove);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseEnter(const SWindowCoord& coord) {
|
void mouseEnter(const SWindowCoord& coord) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::MouseEnter);
|
m_cmds.emplace_back(Command::Type::MouseEnter);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseLeave(const SWindowCoord& coord) {
|
void mouseLeave(const SWindowCoord& coord) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::MouseLeave);
|
m_cmds.emplace_back(Command::Type::MouseLeave);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll) {
|
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::Scroll);
|
m_cmds.emplace_back(Command::Type::Scroll);
|
||||||
m_cmds.back().m_coord = coord;
|
m_cmds.back().m_coord = coord;
|
||||||
m_cmds.back().m_scroll = scroll;
|
m_cmds.back().m_scroll = scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void touchDown(const STouchCoord& coord, uintptr_t tid) {
|
void touchDown(const STouchCoord& coord, uintptr_t tid) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::TouchDown);
|
m_cmds.emplace_back(Command::Type::TouchDown);
|
||||||
m_cmds.back().m_tCoord = coord;
|
m_cmds.back().m_tCoord = coord;
|
||||||
m_cmds.back().m_tid = tid;
|
m_cmds.back().m_tid = tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void touchUp(const STouchCoord& coord, uintptr_t tid) {
|
void touchUp(const STouchCoord& coord, uintptr_t tid) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::TouchUp);
|
m_cmds.emplace_back(Command::Type::TouchUp);
|
||||||
m_cmds.back().m_tCoord = coord;
|
m_cmds.back().m_tCoord = coord;
|
||||||
m_cmds.back().m_tid = tid;
|
m_cmds.back().m_tid = tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void touchMove(const STouchCoord& coord, uintptr_t tid) {
|
void touchMove(const STouchCoord& coord, uintptr_t tid) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::TouchMove);
|
m_cmds.emplace_back(Command::Type::TouchMove);
|
||||||
m_cmds.back().m_tCoord = coord;
|
m_cmds.back().m_tCoord = coord;
|
||||||
m_cmds.back().m_tid = tid;
|
m_cmds.back().m_tid = tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat) {
|
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::CharKeyDown);
|
m_cmds.emplace_back(Command::Type::CharKeyDown);
|
||||||
m_cmds.back().m_charcode = charCode;
|
m_cmds.back().m_charcode = charCode;
|
||||||
|
@ -182,14 +185,14 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
m_cmds.back().m_isRepeat = isRepeat;
|
m_cmds.back().m_isRepeat = isRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void charKeyUp(unsigned long charCode, EModifierKey mods) {
|
void charKeyUp(unsigned long charCode, EModifierKey mods) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::CharKeyUp);
|
m_cmds.emplace_back(Command::Type::CharKeyUp);
|
||||||
m_cmds.back().m_charcode = charCode;
|
m_cmds.back().m_charcode = charCode;
|
||||||
m_cmds.back().m_mods = mods;
|
m_cmds.back().m_mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat) {
|
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
|
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
|
||||||
m_cmds.back().m_special = key;
|
m_cmds.back().m_special = key;
|
||||||
|
@ -197,27 +200,27 @@ struct DeferredWindowEvents : public IWindowCallback {
|
||||||
m_cmds.back().m_isRepeat = isRepeat;
|
m_cmds.back().m_isRepeat = isRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void specialKeyUp(ESpecialKey key, EModifierKey mods) {
|
void specialKeyUp(ESpecialKey key, EModifierKey mods) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
|
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
|
||||||
m_cmds.back().m_special = key;
|
m_cmds.back().m_special = key;
|
||||||
m_cmds.back().m_mods = mods;
|
m_cmds.back().m_mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modKeyDown(EModifierKey mod, bool isRepeat) {
|
void modKeyDown(EModifierKey mod, bool isRepeat) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::ModKeyDown);
|
m_cmds.emplace_back(Command::Type::ModKeyDown);
|
||||||
m_cmds.back().m_mods = mod;
|
m_cmds.back().m_mods = mod;
|
||||||
m_cmds.back().m_isRepeat = isRepeat;
|
m_cmds.back().m_isRepeat = isRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modKeyUp(EModifierKey mod) {
|
void modKeyUp(EModifierKey mod) override {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_cmds.emplace_back(Command::Type::ModKeyUp);
|
m_cmds.emplace_back(Command::Type::ModKeyUp);
|
||||||
m_cmds.back().m_mods = mod;
|
m_cmds.back().m_mods = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
|
ITextInputCallback* getTextInputCallback() override { return m_rec.getTextInputCallback(); }
|
||||||
|
|
||||||
void dispatchEvents() {
|
void dispatchEvents() {
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
#include "inputdev/DeviceFinder.hpp"
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
class IApplication;
|
class IApplication;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
struct IGraphicsCommandQueue;
|
struct IGraphicsCommandQueue;
|
||||||
|
@ -14,7 +14,7 @@ class IGraphicsContext {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class EGraphicsAPI {
|
enum class EGraphicsAPI {
|
||||||
None = 0,
|
Invalid = 0,
|
||||||
OpenGL3_3 = 1,
|
OpenGL3_3 = 1,
|
||||||
OpenGL4_2 = 2,
|
OpenGL4_2 = 2,
|
||||||
Vulkan = 3,
|
Vulkan = 3,
|
||||||
|
@ -26,7 +26,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EPixelFormat {
|
enum class EPixelFormat {
|
||||||
None = 0,
|
Invalid = 0,
|
||||||
RGBA8 = 1, /* Default */
|
RGBA8 = 1, /* Default */
|
||||||
RGBA16 = 2,
|
RGBA16 = 2,
|
||||||
RGBA8_Z24 = 3,
|
RGBA8_Z24 = 3,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "System.hpp"
|
|
||||||
#include <memory>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,12 @@ static inline ComPtr<T>* ReferenceComPtr(ComPtr<T>& ptr) {
|
||||||
using T = std::underlying_type_t<type>; \
|
using T = std::underlying_type_t<type>; \
|
||||||
return type(static_cast<T>(a) & static_cast<T>(b)); \
|
return type(static_cast<T>(a) & static_cast<T>(b)); \
|
||||||
} \
|
} \
|
||||||
inline type& operator|=(type& a, const type& b) { \
|
constexpr type& operator|=(type& a, type b) { \
|
||||||
using T = std::underlying_type_t<type>; \
|
using T = std::underlying_type_t<type>; \
|
||||||
a = type(static_cast<T>(a) | static_cast<T>(b)); \
|
a = type(static_cast<T>(a) | static_cast<T>(b)); \
|
||||||
return a; \
|
return a; \
|
||||||
} \
|
} \
|
||||||
inline type& operator&=(type& a, const type& b) { \
|
constexpr type& operator&=(type& a, type b) { \
|
||||||
using T = std::underlying_type_t<type>; \
|
using T = std::underlying_type_t<type>; \
|
||||||
a = type(static_cast<T>(a) & static_cast<T>(b)); \
|
a = type(static_cast<T>(a) & static_cast<T>(b)); \
|
||||||
return a; \
|
return a; \
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -24,7 +25,7 @@ enum class AudioChannel {
|
||||||
|
|
||||||
struct ChannelMap {
|
struct ChannelMap {
|
||||||
unsigned m_channelCount = 0;
|
unsigned m_channelCount = 0;
|
||||||
AudioChannel m_channels[8] = {};
|
std::array<AudioChannel, 8> m_channels{};
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned ChannelCount(AudioChannelSet layout) {
|
static inline unsigned ChannelCount(AudioChannelSet layout) {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IAudioVoice.hpp"
|
#include <cstddef>
|
||||||
#include "IAudioSubmix.hpp"
|
|
||||||
#include "IMIDIPort.hpp"
|
|
||||||
#include "boo/BooObject.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/audiodev/IAudioSubmix.hpp"
|
||||||
|
#include "boo/audiodev/IAudioVoice.hpp"
|
||||||
|
#include "boo/audiodev/IMIDIPort.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
struct IAudioVoiceEngine;
|
struct IAudioVoiceEngine;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <cstddef>
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
struct IAudioVoiceEngine;
|
struct IAudioVoiceEngine;
|
||||||
|
@ -35,7 +36,7 @@ protected:
|
||||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~IMIDIIn();
|
~IMIDIIn() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IMIDIOut : public IMIDIPort {
|
class IMIDIOut : public IMIDIPort {
|
||||||
|
@ -43,7 +44,7 @@ protected:
|
||||||
IMIDIOut(IAudioVoiceEngine* parent, bool virt) : IMIDIPort(parent, virt) {}
|
IMIDIOut(IAudioVoiceEngine* parent, bool virt) : IMIDIPort(parent, virt) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~IMIDIOut();
|
~IMIDIOut() override;
|
||||||
virtual size_t send(const void* buf, size_t len) const = 0;
|
virtual size_t send(const void* buf, size_t len) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ protected:
|
||||||
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~IMIDIInOut();
|
~IMIDIInOut() override;
|
||||||
virtual size_t send(const void* buf, size_t len) const = 0;
|
virtual size_t send(const void* buf, size_t len) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/audiodev/IMIDIReader.hpp"
|
#include <cstdint>
|
||||||
#include "boo/audiodev/IMIDIPort.hpp"
|
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
class IMIDIReader;
|
||||||
|
|
||||||
class MIDIDecoder {
|
class MIDIDecoder {
|
||||||
IMIDIReader& m_out;
|
IMIDIReader& m_out;
|
||||||
uint8_t m_status = 0;
|
uint8_t m_status = 0;
|
||||||
bool _readContinuedValue(std::vector<uint8_t>::const_iterator& it, std::vector<uint8_t>::const_iterator end,
|
|
||||||
uint32_t& valOut);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MIDIDecoder(IMIDIReader& out) : m_out(out) {}
|
MIDIDecoder(IMIDIReader& out) : m_out(out) {}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
#include "boo/audiodev/IMIDIReader.hpp"
|
#include "boo/audiodev/IMIDIReader.hpp"
|
||||||
#include "boo/audiodev/IMIDIPort.hpp"
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -9,38 +11,45 @@ template <class Sender>
|
||||||
class MIDIEncoder : public IMIDIReader {
|
class MIDIEncoder : public IMIDIReader {
|
||||||
Sender& m_sender;
|
Sender& m_sender;
|
||||||
uint8_t m_status = 0;
|
uint8_t m_status = 0;
|
||||||
|
|
||||||
void _sendMessage(const uint8_t* data, size_t len);
|
void _sendMessage(const uint8_t* data, size_t len);
|
||||||
|
|
||||||
|
template <typename ContiguousContainer>
|
||||||
|
void _sendMessage(const ContiguousContainer& container) {
|
||||||
|
_sendMessage(std::data(container), std::size(container));
|
||||||
|
}
|
||||||
|
|
||||||
void _sendContinuedValue(uint32_t val);
|
void _sendContinuedValue(uint32_t val);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MIDIEncoder(Sender& sender) : m_sender(sender) {}
|
MIDIEncoder(Sender& sender) : m_sender(sender) {}
|
||||||
|
|
||||||
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity);
|
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity) override;
|
||||||
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity);
|
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity) override;
|
||||||
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure);
|
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure) override;
|
||||||
void controlChange(uint8_t chan, uint8_t control, uint8_t value);
|
void controlChange(uint8_t chan, uint8_t control, uint8_t value) override;
|
||||||
void programChange(uint8_t chan, uint8_t program);
|
void programChange(uint8_t chan, uint8_t program) override;
|
||||||
void channelPressure(uint8_t chan, uint8_t pressure);
|
void channelPressure(uint8_t chan, uint8_t pressure) override;
|
||||||
void pitchBend(uint8_t chan, int16_t pitch);
|
void pitchBend(uint8_t chan, int16_t pitch) override;
|
||||||
|
|
||||||
void allSoundOff(uint8_t chan);
|
void allSoundOff(uint8_t chan) override;
|
||||||
void resetAllControllers(uint8_t chan);
|
void resetAllControllers(uint8_t chan) override;
|
||||||
void localControl(uint8_t chan, bool on);
|
void localControl(uint8_t chan, bool on) override;
|
||||||
void allNotesOff(uint8_t chan);
|
void allNotesOff(uint8_t chan) override;
|
||||||
void omniMode(uint8_t chan, bool on);
|
void omniMode(uint8_t chan, bool on) override;
|
||||||
void polyMode(uint8_t chan, bool on);
|
void polyMode(uint8_t chan, bool on) override;
|
||||||
|
|
||||||
void sysex(const void* data, size_t len);
|
void sysex(const void* data, size_t len) override;
|
||||||
void timeCodeQuarterFrame(uint8_t message, uint8_t value);
|
void timeCodeQuarterFrame(uint8_t message, uint8_t value) override;
|
||||||
void songPositionPointer(uint16_t pointer);
|
void songPositionPointer(uint16_t pointer) override;
|
||||||
void songSelect(uint8_t song);
|
void songSelect(uint8_t song) override;
|
||||||
void tuneRequest();
|
void tuneRequest() override;
|
||||||
|
|
||||||
void startSeq();
|
void startSeq() override;
|
||||||
void continueSeq();
|
void continueSeq() override;
|
||||||
void stopSeq();
|
void stopSeq() override;
|
||||||
|
|
||||||
void reset();
|
void reset() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "DeferredWindowEvents.hpp"
|
||||||
#include "IApplication.hpp"
|
#include "IApplication.hpp"
|
||||||
#include "IWindow.hpp"
|
#include "IWindow.hpp"
|
||||||
#include "inputdev/DeviceFinder.hpp"
|
#include "inputdev/DeviceFinder.hpp"
|
||||||
|
@ -9,4 +10,3 @@
|
||||||
#include "inputdev/NintendoPowerA.hpp"
|
#include "inputdev/NintendoPowerA.hpp"
|
||||||
#include "graphicsdev/IGraphicsCommandQueue.hpp"
|
#include "graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
#include "graphicsdev/IGraphicsDataFactory.hpp"
|
#include "graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
#include "DeferredWindowEvents.hpp"
|
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
#include <cstddef>
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "boo/System.hpp"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
typedef HRESULT(WINAPI* pD3DCreateBlob)(SIZE_T Size, ID3DBlob** ppBlob);
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
|
using pD3DCreateBlob = HRESULT(WINAPI*)(SIZE_T Size, ID3DBlob** ppBlob);
|
||||||
extern pD3DCreateBlob D3DCreateBlobPROC;
|
extern pD3DCreateBlob D3DCreateBlobPROC;
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
@ -17,10 +17,10 @@ struct BaseGraphicsData;
|
||||||
|
|
||||||
class D3D11DataFactory : public IGraphicsDataFactory {
|
class D3D11DataFactory : public IGraphicsDataFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~D3D11DataFactory() = default;
|
~D3D11DataFactory() override = default;
|
||||||
|
|
||||||
Platform platform() const { return Platform::D3D11; }
|
Platform platform() const override { return Platform::D3D11; }
|
||||||
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
|
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); }
|
||||||
|
|
||||||
class Context final : public IGraphicsDataFactory::Context {
|
class Context final : public IGraphicsDataFactory::Context {
|
||||||
friend class D3D11DataFactoryImpl;
|
friend class D3D11DataFactoryImpl;
|
||||||
|
@ -30,28 +30,30 @@ public:
|
||||||
~Context();
|
~Context();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Platform platform() const { return Platform::D3D11; }
|
Platform platform() const override { return Platform::D3D11; }
|
||||||
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
|
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); }
|
||||||
|
|
||||||
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override;
|
||||||
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override;
|
||||||
|
|
||||||
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
TextureClampMode clampMode, const void* data, size_t sz);
|
TextureClampMode clampMode, const void* data, size_t sz) override;
|
||||||
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
||||||
size_t sz);
|
size_t sz) override;
|
||||||
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt,
|
||||||
|
TextureClampMode clampMode) override;
|
||||||
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode, size_t colorBindCount,
|
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode, size_t colorBindCount,
|
||||||
size_t depthBindCount);
|
size_t depthBindCount) override;
|
||||||
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips);
|
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips) override;
|
||||||
|
|
||||||
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage) override;
|
||||||
|
|
||||||
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||||
const AdditionalPipelineInfo& additionalInfo, bool asynchronous = true);
|
const AdditionalPipelineInfo& additionalInfo,
|
||||||
|
bool asynchronous = true) override;
|
||||||
|
|
||||||
ObjToken<IShaderDataBinding>
|
ObjToken<IShaderDataBinding>
|
||||||
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
|
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
|
||||||
|
@ -59,7 +61,7 @@ public:
|
||||||
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount,
|
const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount,
|
||||||
const ObjToken<ITexture>* texs, const int* bindIdxs, const bool* bindDepth,
|
const ObjToken<ITexture>* texs, const int* bindIdxs, const bool* bindDepth,
|
||||||
size_t baseVert = 0, size_t baseInst = 0);
|
size_t baseVert = 0, size_t baseInst = 0) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<uint8_t> CompileHLSL(const char* source, PipelineStage stage);
|
static std::vector<uint8_t> CompileHLSL(const char* source, PipelineStage stage);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#if BOO_HAS_GL
|
#if BOO_HAS_GL
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
#include <cstdint>
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/BooObject.hpp"
|
||||||
#include "GLSLMacros.hpp"
|
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
struct BaseGraphicsData;
|
struct BaseGraphicsData;
|
||||||
|
@ -25,35 +26,38 @@ public:
|
||||||
~Context();
|
~Context();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Platform platform() const { return Platform::OpenGL; }
|
Platform platform() const override { return Platform::OpenGL; }
|
||||||
const SystemChar* platformName() const { return _SYS_STR("OpenGL"); }
|
const SystemChar* platformName() const override { return _SYS_STR("OpenGL"); }
|
||||||
|
|
||||||
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override;
|
||||||
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override;
|
||||||
|
|
||||||
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
TextureClampMode clampMode, const void* data, size_t sz);
|
TextureClampMode clampMode, const void* data, size_t sz) override;
|
||||||
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
TextureFormat fmt, TextureClampMode clampMode, const void* data,
|
||||||
size_t sz);
|
size_t sz) override;
|
||||||
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt,
|
||||||
|
TextureClampMode clampMode) override;
|
||||||
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||||
size_t colorBindingCount, size_t depthBindingCount);
|
size_t colorBindingCount, size_t depthBindingCount) override;
|
||||||
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips);
|
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips) override;
|
||||||
|
|
||||||
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
|
ObjToken<IShaderStage> newShaderStage(const uint8_t* data, size_t size, PipelineStage stage) override;
|
||||||
|
|
||||||
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
ObjToken<IShaderPipeline> newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
|
||||||
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
|
||||||
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
|
||||||
const AdditionalPipelineInfo& additionalInfo, bool asynchronous = true);
|
const AdditionalPipelineInfo& additionalInfo,
|
||||||
|
bool asynchronous = true) override;
|
||||||
|
|
||||||
ObjToken<IShaderDataBinding> newShaderDataBinding(
|
ObjToken<IShaderDataBinding>
|
||||||
const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
|
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
|
||||||
const ObjToken<IGraphicsBuffer>& instVbo, const ObjToken<IGraphicsBuffer>& ibo, size_t ubufCount,
|
const ObjToken<IGraphicsBuffer>& instVbo, const ObjToken<IGraphicsBuffer>& ibo,
|
||||||
const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages, const size_t* ubufOffs,
|
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufSizes, size_t texCount, const ObjToken<ITexture>* texs, const int* texBindIdx,
|
const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount,
|
||||||
const bool* depthBind, size_t baseVert = 0, size_t baseInst = 0);
|
const ObjToken<ITexture>* texs, const int* texBindIdx, const bool* depthBind,
|
||||||
|
size_t baseVert = 0, size_t baseInst = 0) override;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
|
||||||
#include "boo/IWindow.hpp"
|
|
||||||
#include <functional>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <cstddef>
|
||||||
#include <functional>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <initializer_list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "boo/System.hpp"
|
|
||||||
#include "boo/ThreadLocalPtr.hpp"
|
|
||||||
#include "boo/BooObject.hpp"
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -118,7 +119,7 @@ ENABLE_BITWISE_ENUM(VertexSemantic)
|
||||||
|
|
||||||
/** Used to create IVertexFormat */
|
/** Used to create IVertexFormat */
|
||||||
struct VertexElementDescriptor {
|
struct VertexElementDescriptor {
|
||||||
VertexSemantic semantic;
|
VertexSemantic semantic{};
|
||||||
int semanticIdx = 0;
|
int semanticIdx = 0;
|
||||||
VertexElementDescriptor() = default;
|
VertexElementDescriptor() = default;
|
||||||
VertexElementDescriptor(VertexSemantic s, int idx = 0) : semantic(s), semanticIdx(idx) {}
|
VertexElementDescriptor(VertexSemantic s, int idx = 0) : semantic(s), semanticIdx(idx) {}
|
||||||
|
@ -250,7 +251,8 @@ struct IGraphicsDataFactory {
|
||||||
const VertexFormatInfo& vtxFmt,
|
const VertexFormatInfo& vtxFmt,
|
||||||
const AdditionalPipelineInfo& additionalInfo,
|
const AdditionalPipelineInfo& additionalInfo,
|
||||||
bool asynchronous = true) {
|
bool asynchronous = true) {
|
||||||
return newShaderPipeline(vertex, fragment, {}, {}, {}, vtxFmt, additionalInfo, asynchronous);
|
return newShaderPipeline(std::move(vertex), std::move(fragment), {}, {}, {}, vtxFmt, additionalInfo,
|
||||||
|
asynchronous);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ObjToken<IShaderDataBinding> newShaderDataBinding(
|
virtual ObjToken<IShaderDataBinding> newShaderDataBinding(
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#if BOO_HAS_METAL
|
#if BOO_HAS_METAL
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
#include "boo/BooObject.hpp"
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
struct BaseGraphicsData;
|
struct BaseGraphicsData;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#if BOO_HAS_NX
|
#if BOO_HAS_NX
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
#include <unordered_map>
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
|
||||||
#include "nx_compiler.hpp"
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
#include "boo/graphicsdev/nx_compiler.hpp"
|
||||||
|
|
||||||
#include <switch/nvidia/fence.h>
|
#include <switch/nvidia/fence.h>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
|
|
||||||
#include "IGraphicsDataFactory.hpp"
|
|
||||||
#include "IGraphicsCommandQueue.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "GLSLMacros.hpp"
|
|
||||||
#include <vector>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
#include "boo/graphicsdev/VulkanDispatchTable.hpp"
|
#include "boo/graphicsdev/VulkanDispatchTable.hpp"
|
||||||
|
|
||||||
/* Forward-declare handle type for Vulkan Memory Allocator */
|
/* Forward-declare handle type for Vulkan Memory Allocator */
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "nxstl/mutex"
|
#include "nxstl/mutex"
|
||||||
#include "boo/System.hpp"
|
#include "boo/System.hpp"
|
||||||
|
|
||||||
|
@ -54,18 +55,18 @@ public:
|
||||||
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
|
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
|
||||||
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
|
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
|
||||||
|
|
||||||
inline unsigned getVendorId();
|
inline unsigned getVendorId() const;
|
||||||
inline unsigned getProductId();
|
inline unsigned getProductId() const;
|
||||||
inline std::string_view getVendorName();
|
inline std::string_view getVendorName() const;
|
||||||
inline std::string_view getProductName();
|
inline std::string_view getProductName() const;
|
||||||
|
|
||||||
/* High-Level API */
|
/* High-Level API */
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
const PHIDP_PREPARSED_DATA getReportDescriptor();
|
PHIDP_PREPARSED_DATA getReportDescriptor() const;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
std::vector<uint8_t> getReportDescriptor();
|
std::vector<uint8_t> getReportDescriptor() const;
|
||||||
#endif
|
#endif
|
||||||
bool sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message = 0);
|
bool sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message = 0);
|
||||||
size_t receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp,
|
size_t receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <memory>
|
||||||
#include <typeindex>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "DeviceToken.hpp"
|
#include <string>
|
||||||
#include "IHIDListener.hpp"
|
#include <unordered_set>
|
||||||
#include "DeviceSignature.hpp"
|
|
||||||
#include <cstring>
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
#include <cstdio>
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
|
#include "boo/inputdev/IHIDListener.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
@ -41,34 +41,11 @@ private:
|
||||||
|
|
||||||
/* Friend methods for platform-listener to find/insert/remove
|
/* Friend methods for platform-listener to find/insert/remove
|
||||||
* tokens with type-filtering */
|
* tokens with type-filtering */
|
||||||
bool _hasToken(const std::string& path) {
|
bool _hasToken(const std::string& path) const {
|
||||||
auto preCheck = m_tokens.find(path);
|
return m_tokens.find(path) != m_tokens.end();
|
||||||
if (preCheck != m_tokens.end())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool _insertToken(std::unique_ptr<DeviceToken>&& token) {
|
|
||||||
if (DeviceSignature::DeviceMatchToken(*token, m_types)) {
|
|
||||||
m_tokensLock.lock();
|
|
||||||
TInsertedDeviceToken inseredTok = m_tokens.insert(std::make_pair(token->getDevicePath(), std::move(token)));
|
|
||||||
m_tokensLock.unlock();
|
|
||||||
deviceConnected(*inseredTok.first->second);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void _removeToken(const std::string& path) {
|
|
||||||
auto preCheck = m_tokens.find(path);
|
|
||||||
if (preCheck != m_tokens.end()) {
|
|
||||||
DeviceToken& tok = *preCheck->second;
|
|
||||||
std::shared_ptr<DeviceBase> dev = tok.m_connectedDev;
|
|
||||||
tok._deviceClose();
|
|
||||||
deviceDisconnected(tok, dev.get());
|
|
||||||
m_tokensLock.lock();
|
|
||||||
m_tokens.erase(preCheck);
|
|
||||||
m_tokensLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
bool _insertToken(std::unique_ptr<DeviceToken>&& token);
|
||||||
|
void _removeToken(const std::string& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class CDeviceTokensHandle {
|
class CDeviceTokensHandle {
|
||||||
|
@ -77,31 +54,17 @@ public:
|
||||||
public:
|
public:
|
||||||
CDeviceTokensHandle(DeviceFinder& finder) : m_finder(finder) { m_finder.m_tokensLock.lock(); }
|
CDeviceTokensHandle(DeviceFinder& finder) : m_finder(finder) { m_finder.m_tokensLock.lock(); }
|
||||||
~CDeviceTokensHandle() { m_finder.m_tokensLock.unlock(); }
|
~CDeviceTokensHandle() { m_finder.m_tokensLock.unlock(); }
|
||||||
TDeviceTokens::iterator begin() { return m_finder.m_tokens.begin(); }
|
|
||||||
TDeviceTokens::iterator end() { return m_finder.m_tokens.end(); }
|
TDeviceTokens::iterator begin() noexcept { return m_finder.m_tokens.begin(); }
|
||||||
|
TDeviceTokens::iterator end() noexcept { return m_finder.m_tokens.end(); }
|
||||||
|
|
||||||
|
TDeviceTokens::const_iterator begin() const noexcept { return m_finder.m_tokens.begin(); }
|
||||||
|
TDeviceTokens::const_iterator end() const noexcept { return m_finder.m_tokens.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Application must specify its interested device-types */
|
/* Application must specify its interested device-types */
|
||||||
DeviceFinder(std::unordered_set<uint64_t> types) {
|
DeviceFinder(std::unordered_set<uint64_t> types);
|
||||||
if (skDevFinder) {
|
virtual ~DeviceFinder();
|
||||||
fmt::print(stderr, fmt("only one instance of CDeviceFinder may be constructed"));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
skDevFinder = this;
|
|
||||||
for (const uint64_t& typeHash : types) {
|
|
||||||
const DeviceSignature* sigIter = BOO_DEVICE_SIGS;
|
|
||||||
while (sigIter->m_name) {
|
|
||||||
if (sigIter->m_typeHash == typeHash)
|
|
||||||
m_types.push_back(sigIter);
|
|
||||||
++sigIter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual ~DeviceFinder() {
|
|
||||||
if (m_listener)
|
|
||||||
m_listener->stopScanning();
|
|
||||||
skDevFinder = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get interested device-type mask */
|
/* Get interested device-type mask */
|
||||||
const DeviceSignature::TDeviceSignatureSet& getTypes() const { return m_types; }
|
const DeviceSignature::TDeviceSignatureSet& getTypes() const { return m_types; }
|
||||||
|
@ -110,29 +73,11 @@ public:
|
||||||
CDeviceTokensHandle getTokens() { return CDeviceTokensHandle(*this); }
|
CDeviceTokensHandle getTokens() { return CDeviceTokensHandle(*this); }
|
||||||
|
|
||||||
/* Automatic device scanning */
|
/* Automatic device scanning */
|
||||||
bool startScanning() {
|
bool startScanning();
|
||||||
if (!m_listener)
|
bool stopScanning();
|
||||||
m_listener = IHIDListenerNew(*this);
|
|
||||||
if (m_listener)
|
|
||||||
return m_listener->startScanning();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool stopScanning() {
|
|
||||||
if (!m_listener)
|
|
||||||
m_listener = IHIDListenerNew(*this);
|
|
||||||
if (m_listener)
|
|
||||||
return m_listener->stopScanning();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Manual device scanning */
|
/* Manual device scanning */
|
||||||
bool scanNow() {
|
bool scanNow();
|
||||||
if (!m_listener)
|
|
||||||
m_listener = IHIDListenerNew(*this);
|
|
||||||
if (m_listener)
|
|
||||||
return m_listener->scanNow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void deviceConnected(DeviceToken&) {}
|
virtual void deviceConnected(DeviceToken&) {}
|
||||||
virtual void deviceDisconnected(DeviceToken&, DeviceBase*) {}
|
virtual void deviceDisconnected(DeviceToken&, DeviceBase*) {}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <typeindex>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -16,14 +17,16 @@ class DeviceBase;
|
||||||
#define dev_typeid(type) std::hash<std::string>()(#type)
|
#define dev_typeid(type) std::hash<std::string>()(#type)
|
||||||
|
|
||||||
struct DeviceSignature {
|
struct DeviceSignature {
|
||||||
typedef std::vector<const DeviceSignature*> TDeviceSignatureSet;
|
using TDeviceSignatureSet = std::vector<const DeviceSignature*>;
|
||||||
typedef std::function<std::shared_ptr<DeviceBase>(DeviceToken*)> TFactoryLambda;
|
using TFactoryLambda = std::function<std::shared_ptr<DeviceBase>(DeviceToken*)>;
|
||||||
const char* m_name;
|
|
||||||
uint64_t m_typeHash;
|
const char* m_name = nullptr;
|
||||||
unsigned m_vid, m_pid;
|
uint64_t m_typeHash = 0;
|
||||||
|
unsigned m_vid = 0;
|
||||||
|
unsigned m_pid = 0;
|
||||||
TFactoryLambda m_factory;
|
TFactoryLambda m_factory;
|
||||||
DeviceType m_type;
|
DeviceType m_type{};
|
||||||
DeviceSignature() : m_name(NULL), m_typeHash(dev_typeid(DeviceSignature)) {} /* Sentinel constructor */
|
DeviceSignature() : m_typeHash(dev_typeid(DeviceSignature)) {} /* Sentinel constructor */
|
||||||
DeviceSignature(const char* name, uint64_t typeHash, unsigned vid, unsigned pid, TFactoryLambda&& factory,
|
DeviceSignature(const char* name, uint64_t typeHash, unsigned vid, unsigned pid, TFactoryLambda&& factory,
|
||||||
DeviceType type = DeviceType::None)
|
DeviceType type = DeviceType::None)
|
||||||
: m_name(name), m_typeHash(typeHash), m_vid(vid), m_pid(pid), m_factory(factory), m_type(type) {}
|
: m_name(name), m_typeHash(typeHash), m_vid(vid), m_pid(pid), m_factory(factory), m_type(type) {}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "DeviceBase.hpp"
|
|
||||||
#include "DeviceSignature.hpp"
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -28,14 +30,7 @@ class DeviceToken {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceToken(const DeviceToken&) = delete;
|
DeviceToken(const DeviceToken&) = delete;
|
||||||
DeviceToken(const DeviceToken&& other)
|
DeviceToken(DeviceToken&& other) noexcept = default;
|
||||||
: m_devType(other.m_devType)
|
|
||||||
, m_vendorId(other.m_vendorId)
|
|
||||||
, m_productId(other.m_productId)
|
|
||||||
, m_vendorName(other.m_vendorName)
|
|
||||||
, m_productName(other.m_productName)
|
|
||||||
, m_devPath(other.m_devPath)
|
|
||||||
, m_connectedDev(other.m_connectedDev) {}
|
|
||||||
DeviceToken(DeviceType devType, unsigned vid, unsigned pid, const char* vname, const char* pname, const char* path)
|
DeviceToken(DeviceType devType, unsigned vid, unsigned pid, const char* vname, const char* pname, const char* path)
|
||||||
: m_devType(devType), m_vendorId(vid), m_productId(pid), m_devPath(path), m_connectedDev(NULL) {
|
: m_devType(devType), m_vendorId(vid), m_productId(pid), m_devPath(path), m_connectedDev(NULL) {
|
||||||
if (vname)
|
if (vname)
|
||||||
|
@ -44,6 +39,12 @@ public:
|
||||||
m_productName = pname;
|
m_productName = pname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceToken& operator=(const DeviceToken&) = delete;
|
||||||
|
DeviceToken& operator=(DeviceToken&&) noexcept = default;
|
||||||
|
|
||||||
|
bool operator==(const DeviceToken& rhs) const { return m_devPath == rhs.m_devPath; }
|
||||||
|
bool operator<(const DeviceToken& rhs) const { return m_devPath < rhs.m_devPath; }
|
||||||
|
|
||||||
DeviceType getDeviceType() const { return m_devType; }
|
DeviceType getDeviceType() const { return m_devType; }
|
||||||
unsigned getVendorId() const { return m_vendorId; }
|
unsigned getVendorId() const { return m_vendorId; }
|
||||||
unsigned getProductId() const { return m_productId; }
|
unsigned getProductId() const { return m_productId; }
|
||||||
|
@ -56,9 +57,6 @@ public:
|
||||||
m_connectedDev = DeviceSignature::DeviceNew(*this);
|
m_connectedDev = DeviceSignature::DeviceNew(*this);
|
||||||
return m_connectedDev;
|
return m_connectedDev;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const DeviceToken& rhs) const { return m_devPath == rhs.m_devPath; }
|
|
||||||
bool operator<(const DeviceToken& rhs) const { return m_devPath < rhs.m_devPath; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "DeviceBase.hpp"
|
|
||||||
#include "../System.hpp"
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -67,14 +68,14 @@ class DolphinSmashAdapter final : public TDeviceBase<IDolphinSmashAdapterCallbac
|
||||||
uint8_t m_rumbleRequest = 0;
|
uint8_t m_rumbleRequest = 0;
|
||||||
bool m_hardStop[4] = {false};
|
bool m_hardStop[4] = {false};
|
||||||
uint8_t m_rumbleState = 0xf; /* Force initial send of stop-rumble command */
|
uint8_t m_rumbleState = 0xf; /* Force initial send of stop-rumble command */
|
||||||
void deviceDisconnected();
|
void deviceDisconnected() override;
|
||||||
void initialCycle();
|
void initialCycle() override;
|
||||||
void transferCycle();
|
void transferCycle() override;
|
||||||
void finalCycle();
|
void finalCycle() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DolphinSmashAdapter(DeviceToken* token);
|
DolphinSmashAdapter(DeviceToken* token);
|
||||||
~DolphinSmashAdapter();
|
~DolphinSmashAdapter() override;
|
||||||
|
|
||||||
void setCallback(IDolphinSmashAdapterCallback* cb) {
|
void setCallback(IDolphinSmashAdapterCallback* cb) {
|
||||||
TDeviceBase<IDolphinSmashAdapterCallback>::setCallback(cb);
|
TDeviceBase<IDolphinSmashAdapterCallback>::setCallback(cb);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <type_traits>
|
|
||||||
#include "DeviceBase.hpp"
|
|
||||||
#include "boo/System.hpp"
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -112,15 +113,15 @@ class DualshockPad final : public TDeviceBase<IDualshockPadCallback> {
|
||||||
uint8_t m_rumbleIntensity[2];
|
uint8_t m_rumbleIntensity[2];
|
||||||
EDualshockLED m_led;
|
EDualshockLED m_led;
|
||||||
DualshockOutReport m_report;
|
DualshockOutReport m_report;
|
||||||
void deviceDisconnected();
|
void deviceDisconnected() override;
|
||||||
void initialCycle();
|
void initialCycle() override;
|
||||||
void transferCycle();
|
void transferCycle() override;
|
||||||
void finalCycle();
|
void finalCycle() override;
|
||||||
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
|
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DualshockPad(DeviceToken* token);
|
DualshockPad(DeviceToken* token);
|
||||||
~DualshockPad();
|
~DualshockPad() override;
|
||||||
|
|
||||||
void startRumble(EDualshockMotor motor, uint8_t duration = 254, uint8_t intensity = 255) {
|
void startRumble(EDualshockMotor motor, uint8_t duration = 254, uint8_t intensity = 255) {
|
||||||
m_rumbleRequest |= motor;
|
m_rumbleRequest |= motor;
|
||||||
|
@ -136,7 +137,7 @@ public:
|
||||||
|
|
||||||
void stopRumble(int motor) { m_rumbleRequest &= ~EDualshockMotor(motor); }
|
void stopRumble(int motor) { m_rumbleRequest &= ~EDualshockMotor(motor); }
|
||||||
|
|
||||||
EDualshockLED getLED() { return m_led; }
|
EDualshockLED getLED() const { return m_led; }
|
||||||
|
|
||||||
void setLED(EDualshockLED led, bool on = true) {
|
void setLED(EDualshockLED led, bool on = true) {
|
||||||
if (on)
|
if (on)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DeviceBase.hpp"
|
#include <functional>
|
||||||
#include "HIDParser.hpp"
|
|
||||||
#include <map>
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
#include <mutex>
|
#include "boo/inputdev/HIDParser.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ class GenericPad final : public TDeviceBase<IGenericPadCallback> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericPad(DeviceToken* token);
|
GenericPad(DeviceToken* token);
|
||||||
~GenericPad();
|
~GenericPad() override;
|
||||||
|
|
||||||
void deviceDisconnected();
|
void deviceDisconnected() override;
|
||||||
void initialCycle();
|
void initialCycle() override;
|
||||||
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
|
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override;
|
||||||
|
|
||||||
void enumerateValues(const std::function<bool(const HIDMainItem& item)>& valueCB) const;
|
void enumerateValues(const std::function<bool(const HIDMainItem& item)>& valueCB) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/System.hpp"
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <cstdint>
|
||||||
#include <stack>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stack>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/System.hpp"
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <hidsdi.h>
|
#include <hidsdi.h>
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "DeviceToken.hpp"
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, std::unique_ptr<DeviceToken>> TDeviceTokens;
|
|
||||||
typedef std::pair<TDeviceTokens::iterator, bool> TInsertedDeviceToken;
|
|
||||||
class DeviceFinder;
|
class DeviceFinder;
|
||||||
|
|
||||||
|
using TDeviceTokens = std::unordered_map<std::string, std::unique_ptr<DeviceToken>>;
|
||||||
|
using TInsertedDeviceToken = std::pair<TDeviceTokens::iterator, bool>;
|
||||||
|
|
||||||
class IHIDListener {
|
class IHIDListener {
|
||||||
public:
|
public:
|
||||||
virtual ~IHIDListener() = default;
|
virtual ~IHIDListener() = default;
|
||||||
|
|
|
@ -23,8 +23,8 @@ struct NintendoPowerAState {
|
||||||
uint8_t leftY;
|
uint8_t leftY;
|
||||||
uint8_t rightX;
|
uint8_t rightX;
|
||||||
uint8_t rightY;
|
uint8_t rightY;
|
||||||
bool operator==(const NintendoPowerAState& other);
|
bool operator==(const NintendoPowerAState& other) const;
|
||||||
bool operator!=(const NintendoPowerAState& other);
|
bool operator!=(const NintendoPowerAState& other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NintendoPowerA;
|
class NintendoPowerA;
|
||||||
|
@ -35,14 +35,14 @@ struct INintendoPowerACallback {
|
||||||
|
|
||||||
class NintendoPowerA final : public TDeviceBase<INintendoPowerACallback> {
|
class NintendoPowerA final : public TDeviceBase<INintendoPowerACallback> {
|
||||||
NintendoPowerAState m_last;
|
NintendoPowerAState m_last;
|
||||||
void deviceDisconnected();
|
void deviceDisconnected() override;
|
||||||
void initialCycle();
|
void initialCycle() override;
|
||||||
void transferCycle();
|
void transferCycle() override;
|
||||||
void finalCycle();
|
void finalCycle() override;
|
||||||
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
|
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NintendoPowerA(DeviceToken*);
|
NintendoPowerA(DeviceToken*);
|
||||||
~NintendoPowerA();
|
~NintendoPowerA() override;
|
||||||
};
|
};
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DeviceBase.hpp"
|
#include <cstdint>
|
||||||
#include "DeviceSignature.hpp"
|
|
||||||
#include "boo/System.hpp"
|
#include "boo/System.hpp"
|
||||||
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ class XInputPad final : public TDeviceBase<IXInputPadCallback> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XInputPad(DeviceToken* token) : TDeviceBase<IXInputPadCallback>(dev_typeid(XInputPad), token) {}
|
XInputPad(DeviceToken* token) : TDeviceBase<IXInputPadCallback>(dev_typeid(XInputPad), token) {}
|
||||||
void deviceDisconnected() {
|
void deviceDisconnected() override {
|
||||||
std::lock_guard<std::mutex> lk(m_callbackLock);
|
std::lock_guard<std::mutex> lk(m_callbackLock);
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
m_callback->controllerDisconnected();
|
m_callback->controllerDisconnected();
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/BooObject.hpp"
|
#include <cstddef>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
/** Linked-list iterator shareable by ListNode types. */
|
/** Linked-list iterator shareable by ListNode types. */
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "../CFPointer.hpp"
|
#include "lib/CFPointer.hpp"
|
||||||
|
|
||||||
#include <AudioToolbox/AudioToolbox.h>
|
#include <AudioToolbox/AudioToolbox.h>
|
||||||
#include <CoreMIDI/CoreMIDI.h>
|
#include <CoreMIDI/CoreMIDI.h>
|
||||||
#include <CoreAudio/HostTime.h>
|
#include <CoreAudio/HostTime.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <logvisor/logvisor.hpp>
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
static logvisor::Module Log("boo::AQS");
|
static logvisor::Module Log("boo::AQS");
|
||||||
|
@ -74,15 +73,15 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
argSize = sizeof(devId);
|
argSize = sizeof(devId);
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, sizeof(devName), &devName, &argSize,
|
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, sizeof(devName), &devName, &argSize,
|
||||||
&devId) != noErr) {
|
&devId) != noErr) {
|
||||||
Log.report(logvisor::Error, fmt("unable to resolve audio device UID %s, using default"),
|
Log.report(logvisor::Error, fmt("unable to resolve audio device UID {}, using default"),
|
||||||
CFStringGetCStringPtr(devName, kCFStringEncodingUTF8));
|
CFStringGetCStringPtr(devName, kCFStringEncodingUTF8));
|
||||||
argSize = sizeof(devId);
|
argSize = sizeof(devId);
|
||||||
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
|
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &argSize, &devId) == noErr) {
|
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &argSize, &devId) == noErr) {
|
||||||
argSize = sizeof(CFStringRef);
|
argSize = sizeof(CFStringRef);
|
||||||
AudioObjectPropertyAddress deviceAddress;
|
AudioObjectPropertyAddress deviceAddress;
|
||||||
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
||||||
AudioObjectGetPropertyData(devId, &deviceAddress, 0, NULL, &argSize, &m_devName);
|
AudioObjectGetPropertyData(devId, &deviceAddress, 0, nullptr, &argSize, &m_devName);
|
||||||
} else {
|
} else {
|
||||||
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
|
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
|
||||||
return {AudioChannelSet::Unknown, 48000.0};
|
return {AudioChannelSet::Unknown, 48000.0};
|
||||||
|
@ -90,21 +89,21 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyAddress.mSelector = kAudioDevicePropertyStreams;
|
propertyAddress.mSelector = kAudioDevicePropertyStreams;
|
||||||
if (AudioObjectGetPropertyDataSize(devId, &propertyAddress, 0, NULL, &argSize) == noErr) {
|
if (AudioObjectGetPropertyDataSize(devId, &propertyAddress, 0, nullptr, &argSize) == noErr) {
|
||||||
numStreams = argSize / sizeof(AudioStreamID);
|
numStreams = argSize / sizeof(AudioStreamID);
|
||||||
streamIDs.resize(numStreams);
|
streamIDs.resize(numStreams);
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(devId, &propertyAddress, 0, NULL, &argSize, &streamIDs[0]) == noErr) {
|
if (AudioObjectGetPropertyData(devId, &propertyAddress, 0, nullptr, &argSize, &streamIDs[0]) == noErr) {
|
||||||
propertyAddress.mSelector = kAudioStreamPropertyDirection;
|
propertyAddress.mSelector = kAudioStreamPropertyDirection;
|
||||||
for (int stm = 0; stm < numStreams; stm++) {
|
for (int stm = 0; stm < numStreams; stm++) {
|
||||||
UInt32 streamDir;
|
UInt32 streamDir;
|
||||||
argSize = sizeof(streamDir);
|
argSize = sizeof(streamDir);
|
||||||
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, NULL, &argSize, &streamDir) == noErr) {
|
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, nullptr, &argSize, &streamDir) == noErr) {
|
||||||
if (streamDir == 0) {
|
if (streamDir == 0) {
|
||||||
propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat;
|
propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat;
|
||||||
AudioStreamBasicDescription asbd;
|
AudioStreamBasicDescription asbd;
|
||||||
argSize = sizeof(asbd);
|
argSize = sizeof(asbd);
|
||||||
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, NULL, &argSize, &asbd) == noErr) {
|
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, nullptr, &argSize, &asbd) == noErr) {
|
||||||
switch (asbd.mChannelsPerFrame) {
|
switch (asbd.mChannelsPerFrame) {
|
||||||
case 2:
|
case 2:
|
||||||
return {AudioChannelSet::Stereo, asbd.mSampleRate};
|
return {AudioChannelSet::Stereo, asbd.mSampleRate};
|
||||||
|
@ -130,9 +129,9 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return {AudioChannelSet::Unknown, 48000.0};
|
return {AudioChannelSet::Unknown, 48000.0};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCurrentAudioOutput() const { return CFStringGetCStringPtr(m_devName.get(), kCFStringEncodingUTF8); }
|
std::string getCurrentAudioOutput() const override { return CFStringGetCStringPtr(m_devName.get(), kCFStringEncodingUTF8); }
|
||||||
|
|
||||||
bool setCurrentAudioOutput(const char* name) {
|
bool setCurrentAudioOutput(const char* name) override {
|
||||||
m_devName = CFPointer<CFStringRef>::adopt(CFStringCreateWithCString(nullptr, name, kCFStringEncodingUTF8));
|
m_devName = CFPointer<CFStringRef>::adopt(CFStringCreateWithCString(nullptr, name, kCFStringEncodingUTF8));
|
||||||
_rebuildAudioQueue();
|
_rebuildAudioQueue();
|
||||||
return true;
|
return true;
|
||||||
|
@ -155,29 +154,29 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
propertyAddress.mSelector = kAudioHardwarePropertyDevices;
|
propertyAddress.mSelector = kAudioHardwarePropertyDevices;
|
||||||
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
|
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
|
||||||
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
||||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize) == noErr) {
|
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &propertySize) == noErr) {
|
||||||
numDevices = propertySize / sizeof(AudioDeviceID);
|
numDevices = propertySize / sizeof(AudioDeviceID);
|
||||||
ret.reserve(numDevices);
|
ret.reserve(numDevices);
|
||||||
deviceIDs.resize(numDevices);
|
deviceIDs.resize(numDevices);
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize,
|
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &propertySize,
|
||||||
&deviceIDs[0]) == noErr) {
|
&deviceIDs[0]) == noErr) {
|
||||||
char deviceName[64];
|
char deviceName[64];
|
||||||
|
|
||||||
for (int idx = 0; idx < numDevices; idx++) {
|
for (int idx = 0; idx < numDevices; idx++) {
|
||||||
propertyAddress.mSelector = kAudioDevicePropertyStreams;
|
propertyAddress.mSelector = kAudioDevicePropertyStreams;
|
||||||
if (AudioObjectGetPropertyDataSize(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize) == noErr) {
|
if (AudioObjectGetPropertyDataSize(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize) == noErr) {
|
||||||
numStreams = propertySize / sizeof(AudioStreamID);
|
numStreams = propertySize / sizeof(AudioStreamID);
|
||||||
streamIDs.resize(numStreams);
|
streamIDs.resize(numStreams);
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, &streamIDs[0]) ==
|
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, &streamIDs[0]) ==
|
||||||
noErr) {
|
noErr) {
|
||||||
propertyAddress.mSelector = kAudioStreamPropertyDirection;
|
propertyAddress.mSelector = kAudioStreamPropertyDirection;
|
||||||
bool foundOutput = false;
|
bool foundOutput = false;
|
||||||
for (int stm = 0; stm < numStreams; stm++) {
|
for (int stm = 0; stm < numStreams; stm++) {
|
||||||
UInt32 streamDir;
|
UInt32 streamDir;
|
||||||
propertySize = sizeof(streamDir);
|
propertySize = sizeof(streamDir);
|
||||||
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, NULL, &propertySize, &streamDir) ==
|
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, nullptr, &propertySize, &streamDir) ==
|
||||||
noErr) {
|
noErr) {
|
||||||
if (streamDir == 0) {
|
if (streamDir == 0) {
|
||||||
foundOutput = true;
|
foundOutput = true;
|
||||||
|
@ -192,13 +191,13 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
propertySize = sizeof(deviceName);
|
propertySize = sizeof(deviceName);
|
||||||
propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
|
propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
|
||||||
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, deviceName) ==
|
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, deviceName) ==
|
||||||
noErr) {
|
noErr) {
|
||||||
CFPointer<CFStringRef> uidString;
|
CFPointer<CFStringRef> uidString;
|
||||||
|
|
||||||
propertySize = sizeof(CFStringRef);
|
propertySize = sizeof(CFStringRef);
|
||||||
propertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
propertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
||||||
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, &uidString) ==
|
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, &uidString) ==
|
||||||
noErr) {
|
noErr) {
|
||||||
ret.emplace_back(CFStringGetCStringPtr(uidString.get(), kCFStringEncodingUTF8), deviceName);
|
ret.emplace_back(CFStringGetCStringPtr(uidString.get(), kCFStringEncodingUTF8), deviceName);
|
||||||
}
|
}
|
||||||
|
@ -336,14 +335,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
MIDIIn(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
MIDIIn(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||||
: IMIDIIn(parent, virt, std::move(receiver)) {}
|
: IMIDIIn(parent, virt, std::move(receiver)) {}
|
||||||
|
|
||||||
~MIDIIn() {
|
~MIDIIn() override {
|
||||||
if (m_midi)
|
if (m_midi)
|
||||||
MIDIEndpointDispose(m_midi);
|
MIDIEndpointDispose(m_midi);
|
||||||
if (m_midiPort)
|
if (m_midiPort)
|
||||||
MIDIPortDispose(m_midiPort);
|
MIDIPortDispose(m_midiPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
CFPointer<CFStringRef> namestr;
|
CFPointer<CFStringRef> namestr;
|
||||||
const char* nameCstr;
|
const char* nameCstr;
|
||||||
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
|
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
|
||||||
|
@ -362,14 +361,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
MIDIOut(AQSAudioVoiceEngine* parent, bool virt) : IMIDIOut(parent, virt) {}
|
MIDIOut(AQSAudioVoiceEngine* parent, bool virt) : IMIDIOut(parent, virt) {}
|
||||||
|
|
||||||
~MIDIOut() {
|
~MIDIOut() override {
|
||||||
if (m_midi)
|
if (m_midi)
|
||||||
MIDIEndpointDispose(m_midi);
|
MIDIEndpointDispose(m_midi);
|
||||||
if (m_midiPort)
|
if (m_midiPort)
|
||||||
MIDIPortDispose(m_midiPort);
|
MIDIPortDispose(m_midiPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
CFPointer<CFStringRef> namestr;
|
CFPointer<CFStringRef> namestr;
|
||||||
const char* nameCstr;
|
const char* nameCstr;
|
||||||
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
|
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
|
||||||
|
@ -381,7 +380,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return nameCstr;
|
return nameCstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
union {
|
union {
|
||||||
MIDIPacketList head;
|
MIDIPacketList head;
|
||||||
Byte storage[512];
|
Byte storage[512];
|
||||||
|
@ -408,7 +407,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
MIDIInOut(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
MIDIInOut(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||||
: IMIDIInOut(parent, virt, std::move(receiver)) {}
|
: IMIDIInOut(parent, virt, std::move(receiver)) {}
|
||||||
|
|
||||||
~MIDIInOut() {
|
~MIDIInOut() override {
|
||||||
if (m_midiIn)
|
if (m_midiIn)
|
||||||
MIDIEndpointDispose(m_midiIn);
|
MIDIEndpointDispose(m_midiIn);
|
||||||
if (m_midiPortIn)
|
if (m_midiPortIn)
|
||||||
|
@ -419,7 +418,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
MIDIPortDispose(m_midiPortOut);
|
MIDIPortDispose(m_midiPortOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
CFPointer<CFStringRef> namestr;
|
CFPointer<CFStringRef> namestr;
|
||||||
const char* nameCstr;
|
const char* nameCstr;
|
||||||
if (MIDIObjectGetStringProperty(m_midiIn, kMIDIPropertyName, &namestr))
|
if (MIDIObjectGetStringProperty(m_midiIn, kMIDIPropertyName, &namestr))
|
||||||
|
@ -431,7 +430,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return nameCstr;
|
return nameCstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
union {
|
union {
|
||||||
MIDIPacketList head;
|
MIDIPacketList head;
|
||||||
Byte storage[512];
|
Byte storage[512];
|
||||||
|
@ -452,7 +451,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
unsigned m_midiInCounter = 0;
|
unsigned m_midiInCounter = 0;
|
||||||
unsigned m_midiOutCounter = 0;
|
unsigned m_midiOutCounter = 0;
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -477,7 +476,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
|
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -500,7 +499,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -537,7 +536,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -561,7 +560,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
|
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -584,7 +583,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
if (!m_midiClient)
|
if (!m_midiClient)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -623,7 +622,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useMIDILock() const { return true; }
|
bool useMIDILock() const override { return true; }
|
||||||
|
|
||||||
static void SampleRateChanged(AQSAudioVoiceEngine* engine, AudioQueueRef inAQ, AudioQueuePropertyID inID) {
|
static void SampleRateChanged(AQSAudioVoiceEngine* engine, AudioQueueRef inAQ, AudioQueuePropertyID inID) {
|
||||||
engine->m_needsRebuild = true;
|
engine->m_needsRebuild = true;
|
||||||
|
@ -759,7 +758,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
chMapOut.m_channels[4] = AudioChannel::FrontCenter;
|
chMapOut.m_channels[4] = AudioChannel::FrontCenter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Warning, fmt("unknown channel layout %u; using stereo"), layout.mChannelLayoutTag);
|
Log.report(logvisor::Warning, fmt("unknown channel layout {}; using stereo"), layout.mChannelLayoutTag);
|
||||||
chMapOut.m_channelCount = 2;
|
chMapOut.m_channelCount = 2;
|
||||||
chMapOut.m_channels[0] = AudioChannel::FrontLeft;
|
chMapOut.m_channels[0] = AudioChannel::FrontLeft;
|
||||||
chMapOut.m_channels[1] = AudioChannel::FrontRight;
|
chMapOut.m_channels[1] = AudioChannel::FrontRight;
|
||||||
|
@ -800,11 +799,11 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
const AudioObjectPropertyAddress* inAddresses, AQSAudioVoiceEngine* engine) {
|
const AudioObjectPropertyAddress* inAddresses, AQSAudioVoiceEngine* engine) {
|
||||||
AudioObjectID defaultDeviceId;
|
AudioObjectID defaultDeviceId;
|
||||||
UInt32 argSize = sizeof(defaultDeviceId);
|
UInt32 argSize = sizeof(defaultDeviceId);
|
||||||
if (AudioObjectGetPropertyData(inObjectID, inAddresses, 0, NULL, &argSize, &defaultDeviceId) == noErr) {
|
if (AudioObjectGetPropertyData(inObjectID, inAddresses, 0, nullptr, &argSize, &defaultDeviceId) == noErr) {
|
||||||
argSize = sizeof(CFStringRef);
|
argSize = sizeof(CFStringRef);
|
||||||
AudioObjectPropertyAddress deviceAddress;
|
AudioObjectPropertyAddress deviceAddress;
|
||||||
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
||||||
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, NULL, &argSize, &engine->m_devName);
|
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, nullptr, &argSize, &engine->m_devName);
|
||||||
}
|
}
|
||||||
engine->m_needsRebuild = true;
|
engine->m_needsRebuild = true;
|
||||||
return noErr;
|
return noErr;
|
||||||
|
@ -820,12 +819,12 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
AudioObjectID defaultDeviceId;
|
AudioObjectID defaultDeviceId;
|
||||||
UInt32 argSize = sizeof(defaultDeviceId);
|
UInt32 argSize = sizeof(defaultDeviceId);
|
||||||
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
|
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &argSize, &defaultDeviceId) ==
|
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &argSize, &defaultDeviceId) ==
|
||||||
noErr) {
|
noErr) {
|
||||||
argSize = sizeof(CFStringRef);
|
argSize = sizeof(CFStringRef);
|
||||||
AudioObjectPropertyAddress deviceAddress;
|
AudioObjectPropertyAddress deviceAddress;
|
||||||
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
|
||||||
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, NULL, &argSize, &m_devName);
|
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, nullptr, &argSize, &m_devName);
|
||||||
} else {
|
} else {
|
||||||
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
|
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
|
||||||
return;
|
return;
|
||||||
|
@ -841,14 +840,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
MIDIClientCreate(CFSTR("Boo MIDI"), nullptr, nullptr, &m_midiClient);
|
MIDIClientCreate(CFSTR("Boo MIDI"), nullptr, nullptr, &m_midiClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AQSAudioVoiceEngine() {
|
~AQSAudioVoiceEngine() override {
|
||||||
m_cbRunning = false;
|
m_cbRunning = false;
|
||||||
AudioQueueDispose(m_queue, true);
|
AudioQueueDispose(m_queue, true);
|
||||||
if (m_midiClient)
|
if (m_midiClient)
|
||||||
MIDIClientDispose(m_midiClient);
|
MIDIClientDispose(m_midiClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pumpAndMixVoices() {
|
void pumpAndMixVoices() override {
|
||||||
while (CFRunLoopRunInMode(m_runLoopMode.get(), 0, true) == kCFRunLoopRunHandledSource) {}
|
while (CFRunLoopRunInMode(m_runLoopMode.get(), 0, true) == kCFRunLoopRunHandledSource) {}
|
||||||
if (m_needsRebuild) {
|
if (m_needsRebuild) {
|
||||||
_rebuildAudioQueue();
|
_rebuildAudioQueue();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "AudioMatrix.hpp"
|
#include "lib/audiodev/AudioMatrix.hpp"
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/audiodev/IAudioVoice.hpp"
|
|
||||||
#include <vector>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "boo/audiodev/IAudioVoice.hpp"
|
||||||
|
|
||||||
#if __SSE__
|
#if __SSE__
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
#include "AudioMatrix.hpp"
|
#include "lib/audiodev/AudioMatrix.hpp"
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
typedef union {
|
union TVectorUnion {
|
||||||
float v[4];
|
float v[4];
|
||||||
#if __SSE__
|
#if __SSE__
|
||||||
__m128 q;
|
__m128 q;
|
||||||
__m64 d[2];
|
__m64 d[2];
|
||||||
#endif
|
#endif
|
||||||
} TVectorUnion;
|
};
|
||||||
|
|
||||||
static constexpr TVectorUnion Min32Vec = {{INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN}};
|
static constexpr TVectorUnion Min32Vec = {{INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN}};
|
||||||
static constexpr TVectorUnion Max32Vec = {{INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX}};
|
static constexpr TVectorUnion Max32Vec = {{INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX}};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "AudioSubmix.hpp"
|
#include "lib/audiodev/AudioSubmix.hpp"
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoice.hpp"
|
||||||
#include "AudioVoice.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
|
@ -21,9 +21,6 @@ AudioSubmix*& AudioSubmix::_getHeadPtr(BaseAudioVoiceEngine* head) { return head
|
||||||
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head) {
|
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head) {
|
||||||
return std::unique_lock<std::recursive_mutex>{head->m_dataMutex};
|
return std::unique_lock<std::recursive_mutex>{head->m_dataMutex};
|
||||||
}
|
}
|
||||||
std::unique_lock<std::recursive_mutex> AudioSubmix::destructorLock() {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioSubmix::_isDirectDependencyOf(AudioSubmix* send) { return m_sendGains.find(send) != m_sendGains.cend(); }
|
bool AudioSubmix::_isDirectDependencyOf(AudioSubmix* send) { return m_sendGains.find(send) != m_sendGains.cend(); }
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/audiodev/IAudioSubmix.hpp"
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Common.hpp"
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/audiodev/IAudioSubmix.hpp"
|
||||||
|
#include "lib/audiodev/Common.hpp"
|
||||||
|
|
||||||
#if __SSE__
|
#if __SSE__
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
@ -80,16 +84,15 @@ class AudioSubmix : public ListNode<AudioSubmix, BaseAudioVoiceEngine*, IAudioSu
|
||||||
public:
|
public:
|
||||||
static AudioSubmix*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
static AudioSubmix*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
||||||
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock();
|
|
||||||
|
|
||||||
AudioSubmix(BaseAudioVoiceEngine& root, IAudioSubmixCallback* cb, int busId, bool mainOut);
|
AudioSubmix(BaseAudioVoiceEngine& root, IAudioSubmixCallback* cb, int busId, bool mainOut);
|
||||||
~AudioSubmix();
|
~AudioSubmix() override;
|
||||||
|
|
||||||
void resetSendLevels();
|
void resetSendLevels() override;
|
||||||
void setSendLevel(IAudioSubmix* submix, float level, bool slew);
|
void setSendLevel(IAudioSubmix* submix, float level, bool slew) override;
|
||||||
const AudioVoiceEngineMixInfo& mixInfo() const;
|
const AudioVoiceEngineMixInfo& mixInfo() const;
|
||||||
double getSampleRate() const;
|
double getSampleRate() const override;
|
||||||
SubmixFormat getSampleFormat() const;
|
SubmixFormat getSampleFormat() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -18,9 +18,6 @@ AudioVoice*& AudioVoice::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->
|
||||||
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head) {
|
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head) {
|
||||||
return std::unique_lock<std::recursive_mutex>{head->m_dataMutex};
|
return std::unique_lock<std::recursive_mutex>{head->m_dataMutex};
|
||||||
}
|
}
|
||||||
std::unique_lock<std::recursive_mutex> AudioVoice::destructorLock() {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVoice::_setPitchRatio(double ratio, bool slew) {
|
void AudioVoice::_setPitchRatio(double ratio, bool slew) {
|
||||||
if (m_dynamicRate) {
|
if (m_dynamicRate) {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <soxr.h>
|
#include <mutex>
|
||||||
#include <list>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "boo/audiodev/IAudioVoice.hpp"
|
#include "boo/audiodev/IAudioVoice.hpp"
|
||||||
#include "AudioMatrix.hpp"
|
#include "lib/audiodev/AudioMatrix.hpp"
|
||||||
#include "Common.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/Common.hpp"
|
||||||
|
|
||||||
|
#include <soxr.h>
|
||||||
|
|
||||||
struct AudioUnitVoiceEngine;
|
struct AudioUnitVoiceEngine;
|
||||||
struct VSTVoiceEngine;
|
struct VSTVoiceEngine;
|
||||||
|
@ -64,13 +66,12 @@ protected:
|
||||||
public:
|
public:
|
||||||
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
||||||
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock();
|
|
||||||
|
|
||||||
~AudioVoice();
|
~AudioVoice() override;
|
||||||
void resetSampleRate(double sampleRate);
|
void resetSampleRate(double sampleRate) override;
|
||||||
void setPitchRatio(double ratio, bool slew);
|
void setPitchRatio(double ratio, bool slew) override;
|
||||||
void start();
|
void start() override;
|
||||||
void stop();
|
void stop() override;
|
||||||
double getSampleRateIn() const { return m_sampleRateIn; }
|
double getSampleRateIn() const { return m_sampleRateIn; }
|
||||||
double getSampleRateOut() const { return m_sampleRateOut; }
|
double getSampleRateOut() const { return m_sampleRateOut; }
|
||||||
};
|
};
|
||||||
|
@ -91,7 +92,7 @@ inline size_t AudioVoice::pumpAndMix<float>(size_t frames) {
|
||||||
class AudioVoiceMono : public AudioVoice {
|
class AudioVoiceMono : public AudioVoice {
|
||||||
std::unordered_map<IAudioSubmix*, AudioMatrixMono> m_sendMatrices;
|
std::unordered_map<IAudioSubmix*, AudioMatrixMono> m_sendMatrices;
|
||||||
bool m_silentOut = false;
|
bool m_silentOut = false;
|
||||||
void _resetSampleRate(double sampleRate);
|
void _resetSampleRate(double sampleRate) override;
|
||||||
|
|
||||||
static size_t SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t requestedLen);
|
static size_t SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t requestedLen);
|
||||||
|
|
||||||
|
@ -99,21 +100,21 @@ class AudioVoiceMono : public AudioVoice {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t _pumpAndMix(size_t frames);
|
size_t _pumpAndMix(size_t frames);
|
||||||
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
|
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
|
||||||
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
|
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
|
||||||
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
|
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
||||||
void resetChannelLevels();
|
void resetChannelLevels() override;
|
||||||
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
|
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
|
||||||
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
|
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioVoiceStereo : public AudioVoice {
|
class AudioVoiceStereo : public AudioVoice {
|
||||||
std::unordered_map<IAudioSubmix*, AudioMatrixStereo> m_sendMatrices;
|
std::unordered_map<IAudioSubmix*, AudioMatrixStereo> m_sendMatrices;
|
||||||
bool m_silentOut = false;
|
bool m_silentOut = false;
|
||||||
void _resetSampleRate(double sampleRate);
|
void _resetSampleRate(double sampleRate) override;
|
||||||
|
|
||||||
static size_t SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t requestedLen);
|
static size_t SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t requestedLen);
|
||||||
|
|
||||||
|
@ -121,15 +122,15 @@ class AudioVoiceStereo : public AudioVoice {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t _pumpAndMix(size_t frames);
|
size_t _pumpAndMix(size_t frames);
|
||||||
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
|
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
|
||||||
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
|
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
|
||||||
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
|
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
||||||
void resetChannelLevels();
|
void resetChannelLevels() override;
|
||||||
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
|
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
|
||||||
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
|
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include <cstddef>
|
||||||
#include "LtRtProcessing.hpp"
|
#include <cstdint>
|
||||||
#include "Common.hpp"
|
#include <list>
|
||||||
#include "AudioVoice.hpp"
|
#include <memory>
|
||||||
#include "AudioSubmix.hpp"
|
|
||||||
#include <functional>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
#include "lib/audiodev/AudioSubmix.hpp"
|
||||||
|
#include "lib/audiodev/AudioVoice.hpp"
|
||||||
|
#include "lib/audiodev/Common.hpp"
|
||||||
|
#include "lib/audiodev/LtRtProcessing.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -57,22 +63,24 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
|
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
|
||||||
~BaseAudioVoiceEngine();
|
~BaseAudioVoiceEngine() override;
|
||||||
ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate, IAudioVoiceCallback* cb, bool dynamicPitch = false);
|
ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate, IAudioVoiceCallback* cb,
|
||||||
|
bool dynamicPitch = false) override;
|
||||||
|
|
||||||
ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate, IAudioVoiceCallback* cb, bool dynamicPitch = false);
|
ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate, IAudioVoiceCallback* cb,
|
||||||
|
bool dynamicPitch = false) override;
|
||||||
|
|
||||||
ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId);
|
ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId) override;
|
||||||
|
|
||||||
void setCallbackInterface(IAudioVoiceEngineCallback* cb);
|
void setCallbackInterface(IAudioVoiceEngineCallback* cb) override;
|
||||||
|
|
||||||
void setVolume(float vol);
|
void setVolume(float vol) override;
|
||||||
bool enableLtRt(bool enable);
|
bool enableLtRt(bool enable) override;
|
||||||
const AudioVoiceEngineMixInfo& mixInfo() const;
|
const AudioVoiceEngineMixInfo& mixInfo() const;
|
||||||
const AudioVoiceEngineMixInfo& clientMixInfo() const;
|
const AudioVoiceEngineMixInfo& clientMixInfo() const;
|
||||||
AudioChannelSet getAvailableSet() { return clientMixInfo().m_channels; }
|
AudioChannelSet getAvailableSet() override { return clientMixInfo().m_channels; }
|
||||||
void pumpAndMixVoices() {}
|
void pumpAndMixVoices() override {}
|
||||||
size_t get5MsFrames() const { return m_5msFrames; }
|
size_t get5MsFrames() const override { return m_5msFrames; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <soxr.h>
|
#include <soxr.h>
|
||||||
#include "../Common.hpp"
|
|
||||||
#include "boo/audiodev/IAudioVoice.hpp"
|
#include "boo/audiodev/IAudioVoice.hpp"
|
||||||
|
#include "lib/Common.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include <csignal>
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
|
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <signal.h>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
extern logvisor::Module ALSALog;
|
extern logvisor::Module ALSALog;
|
||||||
|
@ -25,12 +27,12 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~LinuxMidi() {
|
~LinuxMidi() override {
|
||||||
for (auto& p : m_openHandles)
|
for (auto& p : m_openHandles)
|
||||||
p.second->_disown();
|
p.second->_disown();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const {
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const override {
|
||||||
std::vector<std::pair<std::string, std::string>> ret;
|
std::vector<std::pair<std::string, std::string>> ret;
|
||||||
int status;
|
int status;
|
||||||
int card = -1; /* use -1 to prime the pump of iterating through card list */
|
int card = -1; /* use -1 to prime the pump of iterating through card list */
|
||||||
|
@ -83,7 +85,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsVirtualMIDIIn() const { return true; }
|
bool supportsVirtualMIDIIn() const override { return true; }
|
||||||
|
|
||||||
static void MIDIFreeProc(void* midiStatus) { snd_rawmidi_status_free((snd_rawmidi_status_t*)midiStatus); }
|
static void MIDIFreeProc(void* midiStatus) { snd_rawmidi_status_free((snd_rawmidi_status_t*)midiStatus); }
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
, m_midi(midi)
|
, m_midi(midi)
|
||||||
, m_midiThread(std::bind(MIDIReceiveProc, m_midi, m_receiver)) {}
|
, m_midiThread(std::bind(MIDIReceiveProc, m_midi, m_receiver)) {}
|
||||||
|
|
||||||
~MIDIIn() {
|
~MIDIIn() override {
|
||||||
if (m_parent)
|
if (m_parent)
|
||||||
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
||||||
pthread_cancel(m_midiThread.native_handle());
|
pthread_cancel(m_midiThread.native_handle());
|
||||||
|
@ -135,7 +137,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
snd_rawmidi_close(m_midi);
|
snd_rawmidi_close(m_midi);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
snd_rawmidi_info_t* info;
|
snd_rawmidi_info_t* info;
|
||||||
snd_rawmidi_info_alloca(&info);
|
snd_rawmidi_info_alloca(&info);
|
||||||
snd_rawmidi_info(m_midi, info);
|
snd_rawmidi_info(m_midi, info);
|
||||||
|
@ -148,13 +150,13 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
snd_rawmidi_t* m_midi;
|
snd_rawmidi_t* m_midi;
|
||||||
MIDIOut(LinuxMidi* parent, snd_rawmidi_t* midi, bool virt) : IMIDIOut(parent, virt), m_midi(midi) {}
|
MIDIOut(LinuxMidi* parent, snd_rawmidi_t* midi, bool virt) : IMIDIOut(parent, virt), m_midi(midi) {}
|
||||||
|
|
||||||
~MIDIOut() {
|
~MIDIOut() override {
|
||||||
if (m_parent)
|
if (m_parent)
|
||||||
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
||||||
snd_rawmidi_close(m_midi);
|
snd_rawmidi_close(m_midi);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
snd_rawmidi_info_t* info;
|
snd_rawmidi_info_t* info;
|
||||||
snd_rawmidi_info_alloca(&info);
|
snd_rawmidi_info_alloca(&info);
|
||||||
snd_rawmidi_info(m_midi, info);
|
snd_rawmidi_info(m_midi, info);
|
||||||
|
@ -162,7 +164,9 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const { return size_t(std::max(0l, snd_rawmidi_write(m_midi, buf, len))); }
|
size_t send(const void* buf, size_t len) const override {
|
||||||
|
return size_t(std::max(0l, snd_rawmidi_write(m_midi, buf, len)));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MIDIInOut : public IMIDIInOut {
|
struct MIDIInOut : public IMIDIInOut {
|
||||||
|
@ -176,7 +180,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
, m_midiOut(midiOut)
|
, m_midiOut(midiOut)
|
||||||
, m_midiThread(std::bind(MIDIReceiveProc, m_midiIn, m_receiver)) {}
|
, m_midiThread(std::bind(MIDIReceiveProc, m_midiIn, m_receiver)) {}
|
||||||
|
|
||||||
~MIDIInOut() {
|
~MIDIInOut() override {
|
||||||
if (m_parent)
|
if (m_parent)
|
||||||
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
|
||||||
pthread_cancel(m_midiThread.native_handle());
|
pthread_cancel(m_midiThread.native_handle());
|
||||||
|
@ -186,7 +190,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
snd_rawmidi_close(m_midiOut);
|
snd_rawmidi_close(m_midiOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
snd_rawmidi_info_t* info;
|
snd_rawmidi_info_t* info;
|
||||||
snd_rawmidi_info_alloca(&info);
|
snd_rawmidi_info_alloca(&info);
|
||||||
snd_rawmidi_info(m_midiIn, info);
|
snd_rawmidi_info(m_midiIn, info);
|
||||||
|
@ -194,12 +198,12 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
return size_t(std::max(0l, snd_rawmidi_write(m_midiOut, buf, len)));
|
return size_t(std::max(0l, snd_rawmidi_write(m_midiOut, buf, len)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
|
||||||
int status;
|
int status;
|
||||||
snd_rawmidi_t* midi;
|
snd_rawmidi_t* midi;
|
||||||
status = snd_rawmidi_open(&midi, nullptr, "virtual", 0);
|
status = snd_rawmidi_open(&midi, nullptr, "virtual", 0);
|
||||||
|
@ -208,7 +212,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return std::make_unique<MIDIIn>(nullptr, midi, true, std::move(receiver));
|
return std::make_unique<MIDIIn>(nullptr, midi, true, std::move(receiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
|
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
|
||||||
int status;
|
int status;
|
||||||
snd_rawmidi_t* midi;
|
snd_rawmidi_t* midi;
|
||||||
status = snd_rawmidi_open(nullptr, &midi, "virtual", 0);
|
status = snd_rawmidi_open(nullptr, &midi, "virtual", 0);
|
||||||
|
@ -217,7 +221,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return std::make_unique<MIDIOut>(nullptr, midi, true);
|
return std::make_unique<MIDIOut>(nullptr, midi, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override {
|
||||||
int status;
|
int status;
|
||||||
snd_rawmidi_t* midiIn;
|
snd_rawmidi_t* midiIn;
|
||||||
snd_rawmidi_t* midiOut;
|
snd_rawmidi_t* midiOut;
|
||||||
|
@ -227,7 +231,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return std::make_unique<MIDIInOut>(nullptr, midiIn, midiOut, true, std::move(receiver));
|
return std::make_unique<MIDIInOut>(nullptr, midiIn, midiOut, true, std::move(receiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
snd_rawmidi_t* midi;
|
snd_rawmidi_t* midi;
|
||||||
int status = snd_rawmidi_open(&midi, nullptr, name, 0);
|
int status = snd_rawmidi_open(&midi, nullptr, name, 0);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -237,7 +241,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
|
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
|
||||||
snd_rawmidi_t* midi;
|
snd_rawmidi_t* midi;
|
||||||
int status = snd_rawmidi_open(nullptr, &midi, name, 0);
|
int status = snd_rawmidi_open(nullptr, &midi, name, 0);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -247,7 +251,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
snd_rawmidi_t* midiIn;
|
snd_rawmidi_t* midiIn;
|
||||||
snd_rawmidi_t* midiOut;
|
snd_rawmidi_t* midiOut;
|
||||||
int status = snd_rawmidi_open(&midiIn, &midiOut, name, 0);
|
int status = snd_rawmidi_open(&midiIn, &midiOut, name, 0);
|
||||||
|
@ -258,7 +262,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useMIDILock() const { return true; }
|
bool useMIDILock() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
#include "LtRtProcessing.hpp"
|
#include "lib/audiodev/LtRtProcessing.hpp"
|
||||||
#include <cmath>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
namespace {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T ClampFull(float in) {
|
constexpr T ClampFull(float in) {
|
||||||
if (std::is_floating_point<T>()) {
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
return std::min<T>(std::max<T>(in, -1.f), 1.f);
|
return std::clamp(in, -1.f, 1.f);
|
||||||
} else {
|
} else {
|
||||||
constexpr T MAX = std::numeric_limits<T>::max();
|
constexpr T MAX = std::numeric_limits<T>::max();
|
||||||
constexpr T MIN = std::numeric_limits<T>::min();
|
constexpr T MIN = std::numeric_limits<T>::min();
|
||||||
|
@ -23,6 +24,7 @@ inline T ClampFull(float in) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
#if INTEL_IPP
|
#if INTEL_IPP
|
||||||
|
|
||||||
|
@ -237,19 +239,16 @@ LtRtProcessing::LtRtProcessing(int _5msFrames, const AudioVoiceEngineMixInfo& mi
|
||||||
m_inMixInfo.m_channelMap.m_channels[3] = AudioChannel::RearLeft;
|
m_inMixInfo.m_channelMap.m_channels[3] = AudioChannel::RearLeft;
|
||||||
m_inMixInfo.m_channelMap.m_channels[4] = AudioChannel::RearRight;
|
m_inMixInfo.m_channelMap.m_channels[4] = AudioChannel::RearRight;
|
||||||
|
|
||||||
int samples = m_windowFrames * (5 * 2 + 2 * 2);
|
const int samples = m_windowFrames * (5 * 2 + 2 * 2);
|
||||||
switch (mixInfo.m_sampleFormat) {
|
switch (mixInfo.m_sampleFormat) {
|
||||||
case SOXR_INT16_I:
|
case SOXR_INT16_I:
|
||||||
m_16Buffer.reset(new int16_t[samples]);
|
m_16Buffer = std::make_unique<int16_t[]>(samples);
|
||||||
memset(m_16Buffer.get(), 0, sizeof(int16_t) * samples);
|
|
||||||
break;
|
break;
|
||||||
case SOXR_INT32_I:
|
case SOXR_INT32_I:
|
||||||
m_32Buffer.reset(new int32_t[samples]);
|
m_32Buffer = std::make_unique<int32_t[]>(samples);
|
||||||
memset(m_32Buffer.get(), 0, sizeof(int32_t) * samples);
|
|
||||||
break;
|
break;
|
||||||
case SOXR_FLOAT32_I:
|
case SOXR_FLOAT32_I:
|
||||||
m_fltBuffer.reset(new float[samples]);
|
m_fltBuffer = std::make_unique<float[]>(samples);
|
||||||
memset(m_fltBuffer.get(), 0, sizeof(float) * samples);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -259,12 +258,12 @@ LtRtProcessing::LtRtProcessing(int _5msFrames, const AudioVoiceEngineMixInfo& mi
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
||||||
#if 0
|
#if 0
|
||||||
for (int i=0 ; i<frameCount ; ++i)
|
for (int i = 0; i < frameCount; ++i)
|
||||||
{
|
{
|
||||||
output[i * 2] = input[i * 5 + 3];
|
output[i * 2] = input[i * 5 + 3];
|
||||||
output[i * 2 + 1] = input[i * 5 + 4];
|
output[i * 2 + 1] = input[i * 5 + 4];
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int outFramesRem = frameCount;
|
int outFramesRem = frameCount;
|
||||||
|
@ -273,14 +272,14 @@ void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
||||||
int tail = std::min(m_windowFrames * 2, m_bufferTail + frameCount);
|
int tail = std::min(m_windowFrames * 2, m_bufferTail + frameCount);
|
||||||
int samples = (tail - m_bufferTail) * 5;
|
int samples = (tail - m_bufferTail) * 5;
|
||||||
memmove(&inBuf[m_bufferTail * 5], input, samples * sizeof(T));
|
memmove(&inBuf[m_bufferTail * 5], input, samples * sizeof(T));
|
||||||
// printf("input %d to %d\n", tail - m_bufferTail, m_bufferTail);
|
// fmt::print("input {} to {}\n", tail - m_bufferTail, m_bufferTail);
|
||||||
input += samples;
|
input += samples;
|
||||||
frameCount -= tail - m_bufferTail;
|
frameCount -= tail - m_bufferTail;
|
||||||
|
|
||||||
int head = std::min(m_windowFrames * 2, m_bufferHead + outFramesRem);
|
int head = std::min(m_windowFrames * 2, m_bufferHead + outFramesRem);
|
||||||
samples = (head - m_bufferHead) * 2;
|
samples = (head - m_bufferHead) * 2;
|
||||||
memmove(output, outBuf + m_bufferHead * 2, samples * sizeof(T));
|
memmove(output, outBuf + m_bufferHead * 2, samples * sizeof(T));
|
||||||
// printf("output %d from %d\n", head - m_bufferHead, m_bufferHead);
|
// fmt::print("output {} from {}\n", head - m_bufferHead, m_bufferHead);
|
||||||
output += samples;
|
output += samples;
|
||||||
outFramesRem -= head - m_bufferHead;
|
outFramesRem -= head - m_bufferHead;
|
||||||
|
|
||||||
|
@ -300,7 +299,7 @@ void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
||||||
for (int i = 0; i < m_windowFrames; ++i, ++delayI) {
|
for (int i = 0; i < m_windowFrames; ++i, ++delayI) {
|
||||||
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
// printf("in %d out %d\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
// fmt::print("in {} out {}\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int delayI = m_windowFrames * 2 - m_halfFrames;
|
int delayI = m_windowFrames * 2 - m_halfFrames;
|
||||||
|
@ -308,13 +307,13 @@ void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
||||||
for (i = 0; i < m_halfFrames; ++i, ++delayI) {
|
for (i = 0; i < m_halfFrames; ++i, ++delayI) {
|
||||||
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
// printf("in %d out %d\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
// fmt::print("in {} out {}\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
||||||
}
|
}
|
||||||
delayI = 0;
|
delayI = 0;
|
||||||
for (; i < m_windowFrames; ++i, ++delayI) {
|
for (; i < m_windowFrames; ++i, ++delayI) {
|
||||||
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2] = ClampFull<T>(in[delayI * 5] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
out[i * 2 + 1] = ClampFull<T>(in[delayI * 5 + 1] + 0.7071068f * in[delayI * 5 + 2]);
|
||||||
// printf("in %d out %d\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
// fmt::print("in {} out {}\n", bufIdx * m_5msFrames + delayI, bufIdx * m_5msFrames + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if INTEL_IPP
|
#if INTEL_IPP
|
||||||
|
@ -328,14 +327,14 @@ void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
|
||||||
if (frameCount) {
|
if (frameCount) {
|
||||||
samples = frameCount * 5;
|
samples = frameCount * 5;
|
||||||
memmove(inBuf, input, samples * sizeof(T));
|
memmove(inBuf, input, samples * sizeof(T));
|
||||||
// printf("input %d to %d\n", frameCount, 0);
|
// fmt::print("input {} to {}\n", frameCount, 0);
|
||||||
m_bufferTail = frameCount;
|
m_bufferTail = frameCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outFramesRem) {
|
if (outFramesRem) {
|
||||||
samples = outFramesRem * 2;
|
samples = outFramesRem * 2;
|
||||||
memmove(output, outBuf, samples * sizeof(T));
|
memmove(output, outBuf, samples * sizeof(T));
|
||||||
// printf("output %d from %d\n", outFramesRem, 0);
|
// fmt::print("output {} from {}\n", outFramesRem, 0);
|
||||||
m_bufferHead = outFramesRem;
|
m_bufferHead = outFramesRem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "boo/System.hpp"
|
#include "boo/System.hpp"
|
||||||
#include "boo/audiodev/IAudioVoice.hpp"
|
#include "boo/audiodev/IAudioVoice.hpp"
|
||||||
#include "Common.hpp"
|
#include "lib/audiodev/Common.hpp"
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#if INTEL_IPP
|
#if INTEL_IPP
|
||||||
#include "ipp.h"
|
#include "ipp.h"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "MIDICommon.hpp"
|
#include "lib/audiodev/MIDICommon.hpp"
|
||||||
|
|
||||||
#include "boo/audiodev/IMIDIPort.hpp"
|
#include "boo/audiodev/IMIDIPort.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
|
@ -1,39 +1,46 @@
|
||||||
#include "boo/audiodev/MIDIDecoder.hpp"
|
#include "boo/audiodev/MIDIDecoder.hpp"
|
||||||
#include "MIDICommon.hpp"
|
|
||||||
#include <memory>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "boo/audiodev/IMIDIReader.hpp"
|
||||||
|
#include "lib/audiodev/MIDICommon.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
namespace {
|
||||||
|
constexpr uint8_t clamp7(uint8_t val) { return std::clamp(val, uint8_t{0}, uint8_t{127}); }
|
||||||
|
|
||||||
constexpr uint8_t clamp7(uint8_t val) { return std::max(0, std::min(127, int(val))); }
|
std::optional<uint32_t> readContinuedValue(std::vector<uint8_t>::const_iterator& it,
|
||||||
|
std::vector<uint8_t>::const_iterator end) {
|
||||||
bool MIDIDecoder::_readContinuedValue(std::vector<uint8_t>::const_iterator& it,
|
|
||||||
std::vector<uint8_t>::const_iterator end, uint32_t& valOut) {
|
|
||||||
uint8_t a = *it++;
|
uint8_t a = *it++;
|
||||||
valOut = a & 0x7f;
|
uint32_t valOut = a & 0x7f;
|
||||||
|
|
||||||
if (a & 0x80) {
|
if ((a & 0x80) != 0) {
|
||||||
if (it == end)
|
if (it == end) {
|
||||||
return false;
|
return std::nullopt;
|
||||||
|
}
|
||||||
valOut <<= 7;
|
valOut <<= 7;
|
||||||
a = *it++;
|
a = *it++;
|
||||||
valOut |= a & 0x7f;
|
valOut |= a & 0x7f;
|
||||||
|
|
||||||
if (a & 0x80) {
|
if ((a & 0x80) != 0) {
|
||||||
if (it == end)
|
if (it == end) {
|
||||||
return false;
|
return std::nullopt;
|
||||||
|
}
|
||||||
valOut <<= 7;
|
valOut <<= 7;
|
||||||
a = *it++;
|
a = *it++;
|
||||||
valOut |= a & 0x7f;
|
valOut |= a & 0x7f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return valOut;
|
||||||
}
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8_t>::const_iterator begin,
|
std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8_t>::const_iterator begin,
|
||||||
std::vector<uint8_t>::const_iterator end) {
|
std::vector<uint8_t>::const_iterator end) {
|
||||||
std::vector<uint8_t>::const_iterator it = begin;
|
auto it = begin;
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
uint8_t a = *it++;
|
uint8_t a = *it++;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
|
@ -48,9 +55,8 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
|
||||||
return begin;
|
return begin;
|
||||||
a = *it++;
|
a = *it++;
|
||||||
|
|
||||||
uint32_t length;
|
const auto length = readContinuedValue(it, end);
|
||||||
_readContinuedValue(it, end, length);
|
it += *length;
|
||||||
it += length;
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t chan = m_status & 0xf;
|
uint8_t chan = m_status & 0xf;
|
||||||
switch (Status(m_status & 0xf0)) {
|
switch (Status(m_status & 0xf0)) {
|
||||||
|
@ -121,10 +127,11 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
|
||||||
case Status::SysEx: {
|
case Status::SysEx: {
|
||||||
switch (Status(m_status & 0xff)) {
|
switch (Status(m_status & 0xff)) {
|
||||||
case Status::SysEx: {
|
case Status::SysEx: {
|
||||||
uint32_t len;
|
const auto len = readContinuedValue(it, end);
|
||||||
if (!_readContinuedValue(it, end, len) || end - it < len)
|
if (!len || end - it < *len) {
|
||||||
return begin;
|
return begin;
|
||||||
m_out.sysex(&*it, len);
|
}
|
||||||
|
m_out.sysex(&*it, *len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Status::TimecodeQuarterFrame: {
|
case Status::TimecodeQuarterFrame: {
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
#include "boo/audiodev/MIDIEncoder.hpp"
|
#include "boo/audiodev/MIDIEncoder.hpp"
|
||||||
#include "MIDICommon.hpp"
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "boo/audiodev/IMIDIPort.hpp"
|
||||||
|
#include "lib/audiodev/MIDICommon.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
namespace {
|
||||||
|
template <typename... Args>
|
||||||
|
constexpr auto MakeCommand(Args&&... args) -> std::array<uint8_t, sizeof...(Args)> {
|
||||||
|
return {std::forward<Args>(args)...};
|
||||||
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::_sendMessage(const uint8_t* data, size_t len) {
|
void MIDIEncoder<Sender>::_sendMessage(const uint8_t* data, size_t len) {
|
||||||
|
@ -16,7 +26,7 @@ void MIDIEncoder<Sender>::_sendMessage(const uint8_t* data, size_t len) {
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::_sendContinuedValue(uint32_t val) {
|
void MIDIEncoder<Sender>::_sendContinuedValue(uint32_t val) {
|
||||||
uint8_t send[3] = {};
|
std::array<uint8_t, 3> send{};
|
||||||
uint8_t* ptr = nullptr;
|
uint8_t* ptr = nullptr;
|
||||||
if (val >= 0x4000) {
|
if (val >= 0x4000) {
|
||||||
ptr = &send[0];
|
ptr = &send[0];
|
||||||
|
@ -26,154 +36,164 @@ void MIDIEncoder<Sender>::_sendContinuedValue(uint32_t val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val >= 0x80) {
|
if (val >= 0x80) {
|
||||||
if (!ptr)
|
if (ptr == nullptr) {
|
||||||
ptr = &send[1];
|
ptr = &send[1];
|
||||||
|
}
|
||||||
send[1] = 0x80 | ((val / 0x80) & 0x7f);
|
send[1] = 0x80 | ((val / 0x80) & 0x7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ptr)
|
if (ptr == nullptr) {
|
||||||
ptr = &send[2];
|
ptr = &send[2];
|
||||||
|
}
|
||||||
send[2] = val & 0x7f;
|
send[2] = val & 0x7f;
|
||||||
|
|
||||||
m_sender.send(ptr, 3 - (ptr - send));
|
const size_t sendLength = send.size() - (ptr - send.data());
|
||||||
|
m_sender.send(ptr, sendLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::noteOff(uint8_t chan, uint8_t key, uint8_t velocity) {
|
void MIDIEncoder<Sender>::noteOff(uint8_t chan, uint8_t key, uint8_t velocity) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::NoteOff) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f)};
|
const auto cmd =
|
||||||
_sendMessage(cmd, 3);
|
MakeCommand(uint8_t(int(Status::NoteOff) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f));
|
||||||
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::noteOn(uint8_t chan, uint8_t key, uint8_t velocity) {
|
void MIDIEncoder<Sender>::noteOn(uint8_t chan, uint8_t key, uint8_t velocity) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::NoteOn) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f)};
|
const auto cmd =
|
||||||
_sendMessage(cmd, 3);
|
MakeCommand(uint8_t(int(Status::NoteOn) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f));
|
||||||
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::notePressure(uint8_t chan, uint8_t key, uint8_t pressure) {
|
void MIDIEncoder<Sender>::notePressure(uint8_t chan, uint8_t key, uint8_t pressure) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::NotePressure) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(pressure & 0x7f)};
|
const auto cmd =
|
||||||
_sendMessage(cmd, 3);
|
MakeCommand(uint8_t(int(Status::NotePressure) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(pressure & 0x7f));
|
||||||
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::controlChange(uint8_t chan, uint8_t control, uint8_t value) {
|
void MIDIEncoder<Sender>::controlChange(uint8_t chan, uint8_t control, uint8_t value) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(control & 0x7f), uint8_t(value & 0x7f)};
|
const auto cmd =
|
||||||
_sendMessage(cmd, 3);
|
MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(control & 0x7f), uint8_t(value & 0x7f));
|
||||||
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::programChange(uint8_t chan, uint8_t program) {
|
void MIDIEncoder<Sender>::programChange(uint8_t chan, uint8_t program) {
|
||||||
uint8_t cmd[2] = {uint8_t(int(Status::ProgramChange) | (chan & 0xf)), uint8_t(program & 0x7f)};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ProgramChange) | (chan & 0xf)), uint8_t(program & 0x7f));
|
||||||
_sendMessage(cmd, 2);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::channelPressure(uint8_t chan, uint8_t pressure) {
|
void MIDIEncoder<Sender>::channelPressure(uint8_t chan, uint8_t pressure) {
|
||||||
uint8_t cmd[2] = {uint8_t(int(Status::ChannelPressure) | (chan & 0xf)), uint8_t(pressure & 0x7f)};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ChannelPressure) | (chan & 0xf)), uint8_t(pressure & 0x7f));
|
||||||
_sendMessage(cmd, 2);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::pitchBend(uint8_t chan, int16_t pitch) {
|
void MIDIEncoder<Sender>::pitchBend(uint8_t chan, int16_t pitch) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::PitchBend) | (chan & 0xf)), uint8_t((pitch % 128) & 0x7f),
|
const auto cmd = MakeCommand(uint8_t(int(Status::PitchBend) | (chan & 0xf)), uint8_t((pitch % 128) & 0x7f),
|
||||||
uint8_t((pitch / 128) & 0x7f)};
|
uint8_t((pitch / 128) & 0x7f));
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::allSoundOff(uint8_t chan) {
|
void MIDIEncoder<Sender>::allSoundOff(uint8_t chan) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 120, 0};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{120}, uint8_t{0});
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::resetAllControllers(uint8_t chan) {
|
void MIDIEncoder<Sender>::resetAllControllers(uint8_t chan) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 121, 0};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{121}, uint8_t{0});
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::localControl(uint8_t chan, bool on) {
|
void MIDIEncoder<Sender>::localControl(uint8_t chan, bool on) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 122, uint8_t(on ? 127 : 0)};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{122}, uint8_t(on ? 127 : 0));
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::allNotesOff(uint8_t chan) {
|
void MIDIEncoder<Sender>::allNotesOff(uint8_t chan) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 123, 0};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{123}, uint8_t{0});
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::omniMode(uint8_t chan, bool on) {
|
void MIDIEncoder<Sender>::omniMode(uint8_t chan, bool on) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 125 : 124), 0};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 125 : 124), uint8_t{0});
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::polyMode(uint8_t chan, bool on) {
|
void MIDIEncoder<Sender>::polyMode(uint8_t chan, bool on) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 127 : 126), 0};
|
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 127 : 126), uint8_t{0});
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::sysex(const void* data, size_t len) {
|
void MIDIEncoder<Sender>::sysex(const void* data, size_t len) {
|
||||||
uint8_t cmd = uint8_t(Status::SysEx);
|
constexpr auto sysexCmd = MakeCommand(uint8_t(Status::SysEx));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(sysexCmd);
|
||||||
|
|
||||||
_sendContinuedValue(len);
|
_sendContinuedValue(len);
|
||||||
m_sender.send(data, len);
|
m_sender.send(data, len);
|
||||||
cmd = uint8_t(Status::SysExTerm);
|
|
||||||
_sendMessage(&cmd, 1);
|
constexpr auto sysexTermCmd = MakeCommand(uint8_t(Status::SysExTerm));
|
||||||
|
_sendMessage(sysexTermCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::timeCodeQuarterFrame(uint8_t message, uint8_t value) {
|
void MIDIEncoder<Sender>::timeCodeQuarterFrame(uint8_t message, uint8_t value) {
|
||||||
uint8_t cmd[2] = {uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t((message & 0x7 << 4) | (value & 0xf))};
|
const auto cmd =
|
||||||
_sendMessage(cmd, 2);
|
MakeCommand(uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t((message & 0x7 << 4) | (value & 0xf)));
|
||||||
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::songPositionPointer(uint16_t pointer) {
|
void MIDIEncoder<Sender>::songPositionPointer(uint16_t pointer) {
|
||||||
uint8_t cmd[3] = {uint8_t(int(Status::SongPositionPointer)), uint8_t((pointer % 128) & 0x7f),
|
const auto cmd = MakeCommand(uint8_t(int(Status::SongPositionPointer)), uint8_t((pointer % 128) & 0x7f),
|
||||||
uint8_t((pointer / 128) & 0x7f)};
|
uint8_t((pointer / 128) & 0x7f));
|
||||||
_sendMessage(cmd, 3);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::songSelect(uint8_t song) {
|
void MIDIEncoder<Sender>::songSelect(uint8_t song) {
|
||||||
uint8_t cmd[2] = {uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t(song & 0x7f)};
|
const auto cmd = MakeCommand(uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t(song & 0x7f));
|
||||||
_sendMessage(cmd, 2);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::tuneRequest() {
|
void MIDIEncoder<Sender>::tuneRequest() {
|
||||||
uint8_t cmd = uint8_t(Status::TuneRequest);
|
constexpr auto cmd = MakeCommand(uint8_t(Status::TuneRequest));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::startSeq() {
|
void MIDIEncoder<Sender>::startSeq() {
|
||||||
uint8_t cmd = uint8_t(Status::Start);
|
constexpr auto cmd = MakeCommand(uint8_t(Status::Start));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::continueSeq() {
|
void MIDIEncoder<Sender>::continueSeq() {
|
||||||
uint8_t cmd = uint8_t(Status::Continue);
|
constexpr auto cmd = MakeCommand(uint8_t(Status::Continue));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::stopSeq() {
|
void MIDIEncoder<Sender>::stopSeq() {
|
||||||
uint8_t cmd = uint8_t(Status::Stop);
|
constexpr auto cmd = MakeCommand(uint8_t(Status::Stop));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Sender>
|
template <class Sender>
|
||||||
void MIDIEncoder<Sender>::reset() {
|
void MIDIEncoder<Sender>::reset() {
|
||||||
uint8_t cmd = uint8_t(Status::Reset);
|
constexpr auto cmd = MakeCommand(uint8_t(Status::Reset));
|
||||||
_sendMessage(&cmd, 1);
|
_sendMessage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template class MIDIEncoder<IMIDIOut>;
|
template class MIDIEncoder<IMIDIOut>;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/boo.hpp"
|
|
||||||
#include "LinuxMidi.hpp"
|
|
||||||
|
|
||||||
|
#include "boo/boo.hpp"
|
||||||
|
#include "lib/audiodev/LinuxMidi.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ struct PulseAudioVoiceEngine : LinuxMidi {
|
||||||
m_mainloop = nullptr;
|
m_mainloop = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
~PulseAudioVoiceEngine() {
|
~PulseAudioVoiceEngine() override {
|
||||||
if (m_stream) {
|
if (m_stream) {
|
||||||
pa_stream_disconnect(m_stream);
|
pa_stream_disconnect(m_stream);
|
||||||
pa_stream_unref(m_stream);
|
pa_stream_unref(m_stream);
|
||||||
|
@ -270,7 +271,7 @@ struct PulseAudioVoiceEngine : LinuxMidi {
|
||||||
if (i)
|
if (i)
|
||||||
userdata->m_sinks.push_back(std::make_pair(i->name, i->description));
|
userdata->m_sinks.push_back(std::make_pair(i->name, i->description));
|
||||||
}
|
}
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const {
|
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const override {
|
||||||
pa_operation* op = pa_context_get_sink_info_list(m_ctx, pa_sink_info_cb_t(_getSinkInfoListReply), (void*)this);
|
pa_operation* op = pa_context_get_sink_info_list(m_ctx, pa_sink_info_cb_t(_getSinkInfoListReply), (void*)this);
|
||||||
_paIterate(op);
|
_paIterate(op);
|
||||||
pa_operation_unref(op);
|
pa_operation_unref(op);
|
||||||
|
@ -279,14 +280,14 @@ struct PulseAudioVoiceEngine : LinuxMidi {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCurrentAudioOutput() const { return m_sinkName; }
|
std::string getCurrentAudioOutput() const override { return m_sinkName; }
|
||||||
|
|
||||||
bool m_sinkOk = false;
|
bool m_sinkOk = false;
|
||||||
static void _checkAudioSinkReply(pa_context* c, const pa_sink_info* i, int eol, PulseAudioVoiceEngine* userdata) {
|
static void _checkAudioSinkReply(pa_context* c, const pa_sink_info* i, int eol, PulseAudioVoiceEngine* userdata) {
|
||||||
if (i)
|
if (i)
|
||||||
userdata->m_sinkOk = true;
|
userdata->m_sinkOk = true;
|
||||||
}
|
}
|
||||||
bool setCurrentAudioOutput(const char* name) {
|
bool setCurrentAudioOutput(const char* name) override {
|
||||||
m_sinkOk = false;
|
m_sinkOk = false;
|
||||||
pa_operation* op;
|
pa_operation* op;
|
||||||
op = pa_context_get_sink_info_by_name(m_ctx, name, pa_sink_info_cb_t(_checkAudioSinkReply), this);
|
op = pa_context_get_sink_info_by_name(m_ctx, name, pa_sink_info_cb_t(_checkAudioSinkReply), this);
|
||||||
|
@ -308,7 +309,7 @@ struct PulseAudioVoiceEngine : LinuxMidi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pumpAndMixVoices() {
|
void pumpAndMixVoices() override {
|
||||||
if (!m_stream) {
|
if (!m_stream) {
|
||||||
/* Dummy pump mode - use failsafe defaults for 1/60sec of samples */
|
/* Dummy pump mode - use failsafe defaults for 1/60sec of samples */
|
||||||
m_mixInfo.m_sampleRate = 32000.0;
|
m_mixInfo.m_sampleRate = 32000.0;
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
#include "../win/Win32Common.hpp"
|
#include "lib/win/Win32Common.hpp"
|
||||||
#include "AudioVoiceEngine.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
#include <iterator>
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
|
|
||||||
#include <Mmdeviceapi.h>
|
#include <Mmdeviceapi.h>
|
||||||
#include <Audioclient.h>
|
#include <Audioclient.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
#include <Functiondiscoverykeys_devpkey.h>
|
#include <Functiondiscoverykeys_devpkey.h>
|
||||||
|
|
||||||
#include <iterator>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#ifdef TE_VIRTUAL_MIDI
|
#ifdef TE_VIRTUAL_MIDI
|
||||||
#include <teVirtualMIDI.h>
|
#include <teVirtualMIDI.h>
|
||||||
typedef LPVM_MIDI_PORT(CALLBACK* pfnvirtualMIDICreatePortEx2)(LPCWSTR portName, LPVM_MIDI_DATA_CB callback,
|
using pfnvirtualMIDICreatePortEx2 = LPVM_MIDI_PORT(CALLBACK*)(LPCWSTR portName, LPVM_MIDI_DATA_CB callback,
|
||||||
DWORD_PTR dwCallbackInstance, DWORD maxSysexLength,
|
DWORD_PTR dwCallbackInstance, DWORD maxSysexLength,
|
||||||
DWORD flags);
|
DWORD flags);
|
||||||
typedef void(CALLBACK* pfnvirtualMIDIClosePort)(LPVM_MIDI_PORT midiPort);
|
using pfnvirtualMIDIClosePort = void(CALLBACK*)(LPVM_MIDI_PORT midiPort);
|
||||||
typedef BOOL(CALLBACK* pfnvirtualMIDISendData)(LPVM_MIDI_PORT midiPort, LPBYTE midiDataBytes, DWORD length);
|
using pfnvirtualMIDISendData = BOOL(CALLBACK*)(LPVM_MIDI_PORT midiPort, LPBYTE midiDataBytes, DWORD length);
|
||||||
typedef LPCWSTR(CALLBACK* pfnvirtualMIDIGetDriverVersion)(PWORD major, PWORD minor, PWORD release, PWORD build);
|
using pfnvirtualMIDIGetDriverVersion = LPCWSTR(CALLBACK*)(PWORD major, PWORD minor, PWORD release, PWORD build);
|
||||||
static pfnvirtualMIDICreatePortEx2 virtualMIDICreatePortEx2PROC = nullptr;
|
static pfnvirtualMIDICreatePortEx2 virtualMIDICreatePortEx2PROC = nullptr;
|
||||||
static pfnvirtualMIDIClosePort virtualMIDIClosePortPROC = nullptr;
|
static pfnvirtualMIDIClosePort virtualMIDIClosePortPROC = nullptr;
|
||||||
static pfnvirtualMIDISendData virtualMIDISendDataPROC = nullptr;
|
static pfnvirtualMIDISendData virtualMIDISendDataPROC = nullptr;
|
||||||
|
@ -38,9 +40,9 @@ namespace boo {
|
||||||
static logvisor::Module Log("boo::WASAPI");
|
static logvisor::Module Log("boo::WASAPI");
|
||||||
|
|
||||||
#define SAFE_RELEASE(punk) \
|
#define SAFE_RELEASE(punk) \
|
||||||
if ((punk) != NULL) { \
|
if ((punk) != nullptr) { \
|
||||||
(punk)->Release(); \
|
(punk)->Release(); \
|
||||||
(punk) = NULL; \
|
(punk) = nullptr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
@ -70,11 +72,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
// IUnknown methods -- AddRef, Release, and QueryInterface
|
// IUnknown methods -- AddRef, Release, and QueryInterface
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef() {
|
ULONG STDMETHODCALLTYPE AddRef() override {
|
||||||
return InterlockedIncrement(&_cRef);
|
return InterlockedIncrement(&_cRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE Release() {
|
ULONG STDMETHODCALLTYPE Release() override {
|
||||||
ULONG ulRef = InterlockedDecrement(&_cRef);
|
ULONG ulRef = InterlockedDecrement(&_cRef);
|
||||||
if (0 == ulRef) {
|
if (0 == ulRef) {
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -82,7 +84,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ulRef;
|
return ulRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface) {
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface) override {
|
||||||
if (IID_IUnknown == riid) {
|
if (IID_IUnknown == riid) {
|
||||||
AddRef();
|
AddRef();
|
||||||
*ppvInterface = (IUnknown*)this;
|
*ppvInterface = (IUnknown*)this;
|
||||||
|
@ -90,7 +92,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
AddRef();
|
AddRef();
|
||||||
*ppvInterface = (IMMNotificationClient*)this;
|
*ppvInterface = (IMMNotificationClient*)this;
|
||||||
} else {
|
} else {
|
||||||
*ppvInterface = NULL;
|
*ppvInterface = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -98,18 +100,20 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
// Callback methods for device-event notifications.
|
// Callback methods for device-event notifications.
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) {
|
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) override {
|
||||||
m_parent.m_rebuild = true;
|
m_parent.m_rebuild = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) { return S_OK; }
|
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) override { return S_OK; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) { return S_OK; }
|
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) override { return S_OK; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { return S_OK; }
|
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) override { return S_OK; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { return S_OK; }
|
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) override {
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
} m_notificationClient;
|
} m_notificationClient;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -117,7 +121,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
if (!m_device) {
|
if (!m_device) {
|
||||||
if (FAILED(m_enumerator->GetDevice(MBSTWCS(m_sinkName.c_str()).c_str(), &m_device))) {
|
if (FAILED(m_enumerator->GetDevice(MBSTWCS(m_sinkName.c_str()).c_str(), &m_device))) {
|
||||||
Log.report(logvisor::Error, fmt("unable to obtain audio device %s"), m_sinkName);
|
Log.report(logvisor::Error, fmt("unable to obtain audio device {}"), m_sinkName);
|
||||||
m_device.Reset();
|
m_device.Reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +204,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
chMapOut.m_channels[7] = AudioChannel::SideRight;
|
chMapOut.m_channels[7] = AudioChannel::SideRight;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Warning, fmt("unknown channel layout %u; using stereo"), pwfx->Format.nChannels);
|
Log.report(logvisor::Warning, fmt("unknown channel layout {}; using stereo"), pwfx->Format.nChannels);
|
||||||
chMapOut.m_channelCount = 2;
|
chMapOut.m_channelCount = 2;
|
||||||
chMapOut.m_channels[0] = AudioChannel::FrontLeft;
|
chMapOut.m_channels[0] = AudioChannel::FrontLeft;
|
||||||
chMapOut.m_channels[1] = AudioChannel::FrontRight;
|
chMapOut.m_channels[1] = AudioChannel::FrontRight;
|
||||||
|
@ -301,7 +305,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
AddRef();
|
AddRef();
|
||||||
*ppvInterface = (IActivateAudioInterfaceCompletionHandler*)this;
|
*ppvInterface = (IActivateAudioInterfaceCompletionHandler*)this;
|
||||||
} else {
|
} else {
|
||||||
*ppvInterface = NULL;
|
*ppvInterface = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -386,7 +390,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
_resetSampleRate();
|
_resetSampleRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pumpAndMixVoices() {
|
void pumpAndMixVoices() override {
|
||||||
#if WINDOWS_STORE
|
#if WINDOWS_STORE
|
||||||
if (!m_ready)
|
if (!m_ready)
|
||||||
return;
|
return;
|
||||||
|
@ -463,9 +467,9 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCurrentAudioOutput() const { return m_sinkName; }
|
std::string getCurrentAudioOutput() const override { return m_sinkName; }
|
||||||
|
|
||||||
bool setCurrentAudioOutput(const char* name) {
|
bool setCurrentAudioOutput(const char* name) override {
|
||||||
ComPtr<IMMDevice> newDevice;
|
ComPtr<IMMDevice> newDevice;
|
||||||
if (FAILED(m_enumerator->GetDevice(MBSTWCS(name).c_str(), &newDevice))) {
|
if (FAILED(m_enumerator->GetDevice(MBSTWCS(name).c_str(), &newDevice))) {
|
||||||
Log.report(logvisor::Error, fmt("unable to obtain audio device {}"), name);
|
Log.report(logvisor::Error, fmt("unable to obtain audio device {}"), name);
|
||||||
|
@ -477,7 +481,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const {
|
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const override {
|
||||||
std::vector<std::pair<std::string, std::string>> ret;
|
std::vector<std::pair<std::string, std::string>> ret;
|
||||||
|
|
||||||
ComPtr<IMMDeviceCollection> collection;
|
ComPtr<IMMDeviceCollection> collection;
|
||||||
|
@ -507,7 +511,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const {
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const override {
|
||||||
std::vector<std::pair<std::string, std::string>> ret;
|
std::vector<std::pair<std::string, std::string>> ret;
|
||||||
|
|
||||||
UINT numInDevices = midiInGetNumDevs();
|
UINT numInDevices = midiInGetNumDevs();
|
||||||
|
@ -547,7 +551,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsVirtualMIDIIn() const {
|
bool supportsVirtualMIDIIn() const override {
|
||||||
#ifdef TE_VIRTUAL_MIDI
|
#ifdef TE_VIRTUAL_MIDI
|
||||||
WORD major, minor, release, build;
|
WORD major, minor, release, build;
|
||||||
return virtualMIDIGetDriverVersionPROC &&
|
return virtualMIDIGetDriverVersionPROC &&
|
||||||
|
@ -588,9 +592,9 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
VMIDIIn(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver) : IMIDIIn(parent, true, std::move(receiver)) {}
|
VMIDIIn(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver) : IMIDIIn(parent, true, std::move(receiver)) {}
|
||||||
|
|
||||||
~VMIDIIn() { virtualMIDIClosePortPROC(m_midi); }
|
~VMIDIIn() override { virtualMIDIClosePortPROC(m_midi); }
|
||||||
|
|
||||||
std::string description() const { return "Virtual MIDI-In"; }
|
std::string description() const override { return "Virtual MIDI-In"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VMIDIOut : public IMIDIOut {
|
struct VMIDIOut : public IMIDIOut {
|
||||||
|
@ -598,11 +602,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
VMIDIOut(WASAPIAudioVoiceEngine* parent) : IMIDIOut(parent, true) {}
|
VMIDIOut(WASAPIAudioVoiceEngine* parent) : IMIDIOut(parent, true) {}
|
||||||
|
|
||||||
~VMIDIOut() { virtualMIDIClosePortPROC(m_midi); }
|
~VMIDIOut() override { virtualMIDIClosePortPROC(m_midi); }
|
||||||
|
|
||||||
std::string description() const { return "Virtual MIDI-Out"; }
|
std::string description() const override { return "Virtual MIDI-Out"; }
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
return virtualMIDISendDataPROC(m_midi, (LPBYTE)buf, len) ? len : 0;
|
return virtualMIDISendDataPROC(m_midi, (LPBYTE)buf, len) ? len : 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -613,11 +617,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
VMIDIInOut(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver)
|
VMIDIInOut(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver)
|
||||||
: IMIDIInOut(parent, true, std::move(receiver)) {}
|
: IMIDIInOut(parent, true, std::move(receiver)) {}
|
||||||
|
|
||||||
~VMIDIInOut() { virtualMIDIClosePortPROC(m_midi); }
|
~VMIDIInOut() override { virtualMIDIClosePortPROC(m_midi); }
|
||||||
|
|
||||||
std::string description() const { return "Virtual MIDI-In/Out"; }
|
std::string description() const override { return "Virtual MIDI-In/Out"; }
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
return virtualMIDISendDataPROC(m_midi, (LPBYTE)buf, len) ? len : 0;
|
return virtualMIDISendDataPROC(m_midi, (LPBYTE)buf, len) ? len : 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -628,9 +632,9 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
MIDIIn(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver) : IMIDIIn(parent, false, std::move(receiver)) {}
|
MIDIIn(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& receiver) : IMIDIIn(parent, false, std::move(receiver)) {}
|
||||||
|
|
||||||
~MIDIIn() { midiInClose(m_midi); }
|
~MIDIIn() override { midiInClose(m_midi); }
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
UINT id = 0;
|
UINT id = 0;
|
||||||
midiInGetID(m_midi, &id);
|
midiInGetID(m_midi, &id);
|
||||||
MIDIINCAPS caps;
|
MIDIINCAPS caps;
|
||||||
|
@ -661,16 +665,16 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
m_hdr.dwBufferLength = 512;
|
m_hdr.dwBufferLength = 512;
|
||||||
m_hdr.dwFlags = MHDR_ISSTRM;
|
m_hdr.dwFlags = MHDR_ISSTRM;
|
||||||
midiOutPrepareHeader(m_midi, &m_hdr, sizeof(m_hdr));
|
midiOutPrepareHeader(m_midi, &m_hdr, sizeof(m_hdr));
|
||||||
midiStreamOpen(&m_strm, &id, 1, NULL, NULL, CALLBACK_NULL);
|
midiStreamOpen(&m_strm, &id, 1, 0, 0, CALLBACK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
~MIDIOut() {
|
~MIDIOut() override {
|
||||||
midiStreamClose(m_strm);
|
midiStreamClose(m_strm);
|
||||||
midiOutUnprepareHeader(m_midi, &m_hdr, sizeof(m_hdr));
|
midiOutUnprepareHeader(m_midi, &m_hdr, sizeof(m_hdr));
|
||||||
midiOutClose(m_midi);
|
midiOutClose(m_midi);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
UINT id = 0;
|
UINT id = 0;
|
||||||
midiOutGetID(m_midi, &id);
|
midiOutGetID(m_midi, &id);
|
||||||
MIDIOUTCAPS caps;
|
MIDIOUTCAPS caps;
|
||||||
|
@ -684,7 +688,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
memcpy(const_cast<MIDIOut*>(this)->m_buf, buf, std::min(len, size_t(512)));
|
memcpy(const_cast<MIDIOut*>(this)->m_buf, buf, std::min(len, size_t(512)));
|
||||||
const_cast<MIDIOut*>(this)->m_hdr.dwBytesRecorded = len;
|
const_cast<MIDIOut*>(this)->m_hdr.dwBytesRecorded = len;
|
||||||
midiStreamOut(m_strm, LPMIDIHDR(&m_hdr), sizeof(m_hdr));
|
midiStreamOut(m_strm, LPMIDIHDR(&m_hdr), sizeof(m_hdr));
|
||||||
|
@ -710,17 +714,17 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
m_hdr.dwBufferLength = 512;
|
m_hdr.dwBufferLength = 512;
|
||||||
m_hdr.dwFlags = MHDR_ISSTRM;
|
m_hdr.dwFlags = MHDR_ISSTRM;
|
||||||
midiOutPrepareHeader(m_midiOut, &m_hdr, sizeof(m_hdr));
|
midiOutPrepareHeader(m_midiOut, &m_hdr, sizeof(m_hdr));
|
||||||
midiStreamOpen(&m_strm, &id, 1, NULL, NULL, CALLBACK_NULL);
|
midiStreamOpen(&m_strm, &id, 1, 0, 0, CALLBACK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
~MIDIInOut() {
|
~MIDIInOut() override {
|
||||||
midiInClose(m_midiIn);
|
midiInClose(m_midiIn);
|
||||||
midiStreamClose(m_strm);
|
midiStreamClose(m_strm);
|
||||||
midiOutUnprepareHeader(m_midiOut, &m_hdr, sizeof(m_hdr));
|
midiOutUnprepareHeader(m_midiOut, &m_hdr, sizeof(m_hdr));
|
||||||
midiOutClose(m_midiOut);
|
midiOutClose(m_midiOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string description() const {
|
std::string description() const override {
|
||||||
UINT id = 0;
|
UINT id = 0;
|
||||||
midiOutGetID(m_midiOut, &id);
|
midiOutGetID(m_midiOut, &id);
|
||||||
MIDIOUTCAPS caps;
|
MIDIOUTCAPS caps;
|
||||||
|
@ -734,7 +738,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(const void* buf, size_t len) const {
|
size_t send(const void* buf, size_t len) const override {
|
||||||
memcpy(const_cast<uint8_t*>(m_buf), buf, std::min(len, size_t(512)));
|
memcpy(const_cast<uint8_t*>(m_buf), buf, std::min(len, size_t(512)));
|
||||||
const_cast<MIDIHDR&>(m_hdr).dwBytesRecorded = len;
|
const_cast<MIDIHDR&>(m_hdr).dwBytesRecorded = len;
|
||||||
midiStreamOut(m_strm, LPMIDIHDR(&m_hdr), sizeof(m_hdr));
|
midiStreamOut(m_strm, LPMIDIHDR(&m_hdr), sizeof(m_hdr));
|
||||||
|
@ -742,7 +746,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
|
||||||
#ifdef TE_VIRTUAL_MIDI
|
#ifdef TE_VIRTUAL_MIDI
|
||||||
if (!virtualMIDICreatePortEx2PROC)
|
if (!virtualMIDICreatePortEx2PROC)
|
||||||
return {};
|
return {};
|
||||||
|
@ -764,7 +768,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
|
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
|
||||||
#ifdef TE_VIRTUAL_MIDI
|
#ifdef TE_VIRTUAL_MIDI
|
||||||
if (!virtualMIDICreatePortEx2PROC)
|
if (!virtualMIDICreatePortEx2PROC)
|
||||||
return {};
|
return {};
|
||||||
|
@ -785,7 +789,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override {
|
||||||
#ifdef TE_VIRTUAL_MIDI
|
#ifdef TE_VIRTUAL_MIDI
|
||||||
if (!virtualMIDICreatePortEx2PROC)
|
if (!virtualMIDICreatePortEx2PROC)
|
||||||
return {};
|
return {};
|
||||||
|
@ -807,7 +811,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
if (strncmp(name, "in", 2))
|
if (strncmp(name, "in", 2))
|
||||||
return {};
|
return {};
|
||||||
long id = strtol(name + 2, nullptr, 10);
|
long id = strtol(name + 2, nullptr, 10);
|
||||||
|
@ -824,7 +828,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
|
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
|
||||||
if (strncmp(name, "out", 3))
|
if (strncmp(name, "out", 3))
|
||||||
return {};
|
return {};
|
||||||
long id = strtol(name + 3, nullptr, 10);
|
long id = strtol(name + 3, nullptr, 10);
|
||||||
|
@ -833,14 +837,14 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (FAILED(midiOutOpen(&static_cast<MIDIOut&>(*ret).m_midi, id, NULL, NULL, CALLBACK_NULL)))
|
if (FAILED(midiOutOpen(&static_cast<MIDIOut&>(*ret).m_midi, id, 0, 0, CALLBACK_NULL)))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
static_cast<MIDIOut&>(*ret).prepare();
|
static_cast<MIDIOut&>(*ret).prepare();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) override {
|
||||||
const char* in = strstr(name, "in");
|
const char* in = strstr(name, "in");
|
||||||
const char* out = strstr(name, "out");
|
const char* out = strstr(name, "out");
|
||||||
|
|
||||||
|
@ -859,28 +863,28 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
|
||||||
return {};
|
return {};
|
||||||
midiInStart(static_cast<MIDIInOut&>(*ret).m_midiIn);
|
midiInStart(static_cast<MIDIInOut&>(*ret).m_midiIn);
|
||||||
|
|
||||||
if (FAILED(midiOutOpen(&static_cast<MIDIInOut&>(*ret).m_midiOut, outId, NULL, NULL, CALLBACK_NULL)))
|
if (FAILED(midiOutOpen(&static_cast<MIDIInOut&>(*ret).m_midiOut, outId, 0, 0, CALLBACK_NULL)))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
static_cast<MIDIInOut&>(*ret).prepare();
|
static_cast<MIDIInOut&>(*ret).prepare();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useMIDILock() const { return true; }
|
bool useMIDILock() const override { return true; }
|
||||||
#else
|
#else
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices() const { return {}; }
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices() const override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() { return {}; }
|
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) { return {}; }
|
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
bool useMIDILock() const { return false; }
|
bool useMIDILock() const { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "AudioVoiceEngine.hpp"
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -11,15 +14,17 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
|
||||||
|
|
||||||
AudioChannelSet _getAvailableSet() { return AudioChannelSet::Stereo; }
|
AudioChannelSet _getAvailableSet() { return AudioChannelSet::Stereo; }
|
||||||
|
|
||||||
std::string getCurrentAudioOutput() const { return "wavout"; }
|
std::string getCurrentAudioOutput() const override { return "wavout"; }
|
||||||
|
|
||||||
bool setCurrentAudioOutput(const char* name) { return false; }
|
bool setCurrentAudioOutput(const char* name) override { return false; }
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const { return {{"wavout", "WAVOut"}}; }
|
std::vector<std::pair<std::string, std::string>> enumerateAudioOutputs() const override {
|
||||||
|
return {{"wavout", "WAVOut"}};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const { return {}; }
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIInputs() const override { return {}; }
|
||||||
|
|
||||||
bool supportsVirtualMIDIIn() const { return false; }
|
bool supportsVirtualMIDIIn() const override { return false; }
|
||||||
|
|
||||||
ReceiveFunctor* m_midiReceiver = nullptr;
|
ReceiveFunctor* m_midiReceiver = nullptr;
|
||||||
|
|
||||||
|
@ -27,26 +32,26 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
|
||||||
MIDIIn(WAVOutVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
MIDIIn(WAVOutVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
|
||||||
: IMIDIIn(parent, virt, std::move(receiver)) {}
|
: IMIDIIn(parent, virt, std::move(receiver)) {}
|
||||||
|
|
||||||
std::string description() const { return "WAVOut MIDI"; }
|
std::string description() const override { return "WAVOut MIDI"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
|
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
|
||||||
std::unique_ptr<IMIDIIn> ret = std::make_unique<MIDIIn>(nullptr, true, std::move(receiver));
|
std::unique_ptr<IMIDIIn> ret = std::make_unique<MIDIIn>(nullptr, true, std::move(receiver));
|
||||||
m_midiReceiver = &ret->m_receiver;
|
m_midiReceiver = &ret->m_receiver;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() { return {}; }
|
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIIn> newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) { return {}; }
|
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override { return {}; }
|
||||||
|
|
||||||
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) { return {}; }
|
std::unique_ptr<IMIDIInOut> newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) override { return {}; }
|
||||||
|
|
||||||
bool useMIDILock() const { return false; }
|
bool useMIDILock() const override { return false; }
|
||||||
|
|
||||||
FILE* m_fp = nullptr;
|
FILE* m_fp = nullptr;
|
||||||
size_t m_bytesWritten = 0;
|
size_t m_bytesWritten = 0;
|
||||||
|
@ -207,7 +212,7 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
|
||||||
fclose(m_fp);
|
fclose(m_fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
~WAVOutVoiceEngine() { finishWav(); }
|
~WAVOutVoiceEngine() override { finishWav(); }
|
||||||
|
|
||||||
void _buildAudioRenderClient() {
|
void _buildAudioRenderClient() {
|
||||||
m_5msFrames = m_mixInfo.m_sampleRate * 5 / 1000;
|
m_5msFrames = m_mixInfo.m_sampleRate * 5 / 1000;
|
||||||
|
@ -221,7 +226,7 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
|
||||||
_resetSampleRate();
|
_resetSampleRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pumpAndMixVoices() {
|
void pumpAndMixVoices() override {
|
||||||
size_t frameSz = 4 * m_mixInfo.m_channelMap.m_channelCount;
|
size_t frameSz = 4 * m_mixInfo.m_channelMap.m_channelCount;
|
||||||
_pumpAndMixVoices(m_5msFrames, m_interleavedBuf.data());
|
_pumpAndMixVoices(m_5msFrames, m_interleavedBuf.data());
|
||||||
fwrite(m_interleavedBuf.data(), 1, m_5msFrames * frameSz, m_fp);
|
fwrite(m_interleavedBuf.data(), 1, m_5msFrames * frameSz, m_fp);
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
/* Private header for managing shader data
|
/* Private header for managing shader data
|
||||||
* binding lifetimes through rendering cycle */
|
* binding lifetimes through rendering cycle */
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <vector>
|
|
||||||
#include <mutex>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
#include "../Common.hpp"
|
#include "lib/Common.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -63,9 +64,6 @@ struct BaseGraphicsData : ListNode<BaseGraphicsData, GraphicsDataFactoryHead*> {
|
||||||
auto* head = getHead<T>();
|
auto* head = getHead<T>();
|
||||||
return head ? head->countForward() : 0;
|
return head ? head->countForward() : 0;
|
||||||
}
|
}
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock() override {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit BaseGraphicsData(GraphicsDataFactoryHead& head __BooTraceArgs)
|
explicit BaseGraphicsData(GraphicsDataFactoryHead& head __BooTraceArgs)
|
||||||
: ListNode<BaseGraphicsData, GraphicsDataFactoryHead*>(&head) __BooTraceInitializer {}
|
: ListNode<BaseGraphicsData, GraphicsDataFactoryHead*>(&head) __BooTraceInitializer {}
|
||||||
|
@ -131,9 +129,6 @@ struct BaseGraphicsPool : ListNode<BaseGraphicsPool, GraphicsDataFactoryHead*> {
|
||||||
auto* head = getHead<T>();
|
auto* head = getHead<T>();
|
||||||
return head ? head->countForward() : 0;
|
return head ? head->countForward() : 0;
|
||||||
}
|
}
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock() override {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit BaseGraphicsPool(GraphicsDataFactoryHead& head __BooTraceArgs)
|
explicit BaseGraphicsPool(GraphicsDataFactoryHead& head __BooTraceArgs)
|
||||||
: ListNode<BaseGraphicsPool, GraphicsDataFactoryHead*>(&head) __BooTraceInitializer {}
|
: ListNode<BaseGraphicsPool, GraphicsDataFactoryHead*>(&head) __BooTraceInitializer {}
|
||||||
|
@ -158,10 +153,6 @@ struct GraphicsDataNode : ListNode<GraphicsDataNode<NodeCls, DataCls>, ObjToken<
|
||||||
return std::unique_lock<std::recursive_mutex>{head->m_head->m_dataMutex};
|
return std::unique_lock<std::recursive_mutex>{head->m_head->m_dataMutex};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock() override {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{base::m_head->m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit GraphicsDataNode(const ObjToken<DataCls>& data)
|
explicit GraphicsDataNode(const ObjToken<DataCls>& data)
|
||||||
: ListNode<GraphicsDataNode<NodeCls, DataCls>, ObjToken<DataCls>, NodeCls>(data) {}
|
: ListNode<GraphicsDataNode<NodeCls, DataCls>, ObjToken<DataCls>, NodeCls>(data) {}
|
||||||
|
|
||||||
|
@ -249,7 +240,7 @@ public:
|
||||||
m_backcv.wait(lk, [this]() { return m_outstandingTasks == 0 || !m_running; });
|
m_backcv.wait(lk, [this]() { return m_outstandingTasks == 0 || !m_running; });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isReady() {
|
bool isReady() const {
|
||||||
return m_outstandingTasks == 0 || !m_running;
|
return m_outstandingTasks == 0 || !m_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
#include "boo/graphicsdev/glxew.h"
|
#include "boo/graphicsdev/glxew.h"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
static logvisor::Module Log("boo::GLX");
|
static logvisor::Module Log("boo::GLX");
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
#include "../mac/CocoaCommon.hpp"
|
#include "lib/mac/CocoaCommon.hpp"
|
||||||
|
|
||||||
#if BOO_HAS_METAL
|
#if BOO_HAS_METAL
|
||||||
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/Metal.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "Common.hpp"
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
#include <vector>
|
#include "lib/graphicsdev/Common.hpp"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include "xxhash/xxhash.h"
|
#include <vector>
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
#error ARC Required
|
#error ARC Required
|
||||||
|
@ -848,11 +849,13 @@ class MetalShaderStage : public GraphicsDataNode<IShaderStage> {
|
||||||
shaderLib = [ctx->m_dev newLibraryWithSource:@((const char*) (data + 1))
|
shaderLib = [ctx->m_dev newLibraryWithSource:@((const char*) (data + 1))
|
||||||
options:compOpts
|
options:compOpts
|
||||||
error:&err];
|
error:&err];
|
||||||
if (!shaderLib)
|
if (!shaderLib) {
|
||||||
fmt::print(fmt("{}\n"), data + 1);
|
fmt::print(fmt("{}\n"), data + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!shaderLib) {
|
||||||
|
Log.report(logvisor::Fatal, fmt("error creating library: {}"), [[err localizedDescription] UTF8String]);
|
||||||
}
|
}
|
||||||
if (!shaderLib)
|
|
||||||
Log.report(logvisor::Fatal, fmt("error creating library: %s"), [[err localizedDescription] UTF8String]);
|
|
||||||
|
|
||||||
NSString* funcName;
|
NSString* funcName;
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
|
@ -969,9 +972,10 @@ protected:
|
||||||
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
|
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
|
||||||
NSError* err = nullptr;
|
NSError* err = nullptr;
|
||||||
m_state = [ctx->m_dev newRenderPipelineStateWithDescriptor:desc error:&err];
|
m_state = [ctx->m_dev newRenderPipelineStateWithDescriptor:desc error:&err];
|
||||||
if (err)
|
if (err) {
|
||||||
Log.report(logvisor::Fatal, fmt("error making shader pipeline: %s"),
|
Log.report(logvisor::Fatal, fmt("error making shader pipeline: {}"),
|
||||||
[[err localizedDescription] UTF8String]);
|
[[err localizedDescription] UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
||||||
switch (info.depthTest) {
|
switch (info.depthTest) {
|
||||||
|
@ -1043,9 +1047,10 @@ class MetalTessellationShaderPipeline : public MetalShaderPipeline {
|
||||||
NSError* err = nullptr;
|
NSError* err = nullptr;
|
||||||
m_computeState = [ctx->m_dev newComputePipelineStateWithDescriptor:compDesc options:MTLPipelineOptionNone
|
m_computeState = [ctx->m_dev newComputePipelineStateWithDescriptor:compDesc options:MTLPipelineOptionNone
|
||||||
reflection:nil error:&err];
|
reflection:nil error:&err];
|
||||||
if (err)
|
if (err) {
|
||||||
Log.report(logvisor::Fatal, fmt("error making compute pipeline: %s"),
|
Log.report(logvisor::Fatal, fmt("error making compute pipeline: {}"),
|
||||||
[[err localizedDescription] UTF8String]);
|
[[err localizedDescription] UTF8String]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(MetalCommandQueue& q, size_t start, size_t count);
|
void draw(MetalCommandQueue& q, size_t start, size_t count);
|
||||||
|
@ -1147,9 +1152,10 @@ struct MetalShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
|
||||||
m_ubufOffs.reserve(ubufCount);
|
m_ubufOffs.reserve(ubufCount);
|
||||||
for (size_t i = 0; i < ubufCount; ++i) {
|
for (size_t i = 0; i < ubufCount; ++i) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (ubufOffs[i] % 256)
|
if (ubufOffs[i] % 256) {
|
||||||
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding"),
|
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset {} provided to newShaderDataBinding"),
|
||||||
int(i));
|
i);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
m_ubufOffs.push_back(ubufOffs[i]);
|
m_ubufOffs.push_back(ubufOffs[i]);
|
||||||
}
|
}
|
||||||
|
@ -1157,8 +1163,9 @@ struct MetalShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
|
||||||
m_ubufs.reserve(ubufCount);
|
m_ubufs.reserve(ubufCount);
|
||||||
for (size_t i = 0; i < ubufCount; ++i) {
|
for (size_t i = 0; i < ubufCount; ++i) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (!ubufs[i])
|
if (!ubufs[i]) {
|
||||||
Log.report(logvisor::Fatal, fmt("null uniform-buffer %d provided to newShaderDataBinding"), int(i));
|
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), i);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
m_ubufs.push_back(ubufs[i]);
|
m_ubufs.push_back(ubufs[i]);
|
||||||
}
|
}
|
||||||
|
@ -2005,7 +2012,6 @@ void MetalDataFactoryImpl::SetupGammaResources() {
|
||||||
ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()};
|
ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()};
|
||||||
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {},
|
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {},
|
||||||
0, nullptr, nullptr, 2, texs, nullptr, nullptr);
|
0, nullptr, nullptr, 2, texs, nullptr, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} BooTrace);
|
} BooTrace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#include <StandAlone/ResourceLimits.h>
|
#include <StandAlone/ResourceLimits.h>
|
||||||
#include <SPIRV/GlslangToSpv.h>
|
#include <SPIRV/GlslangToSpv.h>
|
||||||
#include <SPIRV/disassemble.h>
|
#include <SPIRV/disassemble.h>
|
||||||
|
|
||||||
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "boo/graphicsdev/GLSLMacros.hpp"
|
#include "boo/graphicsdev/GLSLMacros.hpp"
|
||||||
#include "Common.hpp"
|
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||||
#include "xxhash/xxhash.h"
|
#include "lib/graphicsdev/Common.hpp"
|
||||||
|
|
||||||
#define AMD_PAL_HACK 1
|
#define AMD_PAL_HACK 1
|
||||||
|
|
||||||
|
@ -17,7 +20,7 @@
|
||||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
#include "vk_mem_alloc.h"
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
#include "logvisor/logvisor.hpp"
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#define BOO_VK_MAX_DESCRIPTOR_SETS 65536
|
#define BOO_VK_MAX_DESCRIPTOR_SETS 65536
|
||||||
|
|
||||||
|
@ -188,7 +191,7 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image, VkImageAspectFlag
|
||||||
uint32_t layerCount, uint32_t baseMipLevel = 0) {
|
uint32_t layerCount, uint32_t baseMipLevel = 0) {
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||||
imageMemoryBarrier.pNext = NULL;
|
imageMemoryBarrier.pNext = nullptr;
|
||||||
imageMemoryBarrier.srcAccessMask = 0;
|
imageMemoryBarrier.srcAccessMask = 0;
|
||||||
imageMemoryBarrier.dstAccessMask = 0;
|
imageMemoryBarrier.dstAccessMask = 0;
|
||||||
imageMemoryBarrier.oldLayout = old_image_layout;
|
imageMemoryBarrier.oldLayout = old_image_layout;
|
||||||
|
@ -261,7 +264,7 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image, VkImageAspectFlag
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::CmdPipelineBarrier(cmd, src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
|
vk::CmdPipelineBarrier(cmd, src_stages, dest_stages, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult InitGlobalExtensionProperties(VulkanContext::LayerProperties& layerProps) {
|
static VkResult InitGlobalExtensionProperties(VulkanContext::LayerProperties& layerProps) {
|
||||||
|
@ -1060,9 +1063,6 @@ struct VulkanDescriptorPool : ListNode<VulkanDescriptorPool, VulkanDataFactoryIm
|
||||||
|
|
||||||
~VulkanDescriptorPool() { vk::DestroyDescriptorPool(m_head->m_ctx->m_dev, m_descPool, nullptr); }
|
~VulkanDescriptorPool() { vk::DestroyDescriptorPool(m_head->m_ctx->m_dev, m_descPool, nullptr); }
|
||||||
|
|
||||||
std::unique_lock<std::recursive_mutex> destructorLock() override {
|
|
||||||
return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex};
|
|
||||||
}
|
|
||||||
static std::unique_lock<std::recursive_mutex> _getHeadLock(VulkanDataFactoryImpl* factory) {
|
static std::unique_lock<std::recursive_mutex> _getHeadLock(VulkanDataFactoryImpl* factory) {
|
||||||
return std::unique_lock<std::recursive_mutex>{factory->m_dataMutex};
|
return std::unique_lock<std::recursive_mutex>{factory->m_dataMutex};
|
||||||
}
|
}
|
||||||
|
@ -2668,9 +2668,10 @@ struct VulkanShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
|
||||||
m_ubufOffs.reserve(ubufCount);
|
m_ubufOffs.reserve(ubufCount);
|
||||||
for (size_t i = 0; i < ubufCount; ++i) {
|
for (size_t i = 0; i < ubufCount; ++i) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (ubufOffs[i] % 256)
|
if (ubufOffs[i] % 256) {
|
||||||
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset {} provided to newShaderDataBinding"),
|
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset {} provided to newShaderDataBinding"),
|
||||||
int(i));
|
i);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
std::array<VkDescriptorBufferInfo, 2> fillArr;
|
std::array<VkDescriptorBufferInfo, 2> fillArr;
|
||||||
fillArr.fill({VK_NULL_HANDLE, ubufOffs[i], (ubufSizes[i] + 255) & ~255});
|
fillArr.fill({VK_NULL_HANDLE, ubufOffs[i], (ubufSizes[i] + 255) & ~255});
|
||||||
|
@ -2680,8 +2681,9 @@ struct VulkanShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
|
||||||
m_ubufs.reserve(ubufCount);
|
m_ubufs.reserve(ubufCount);
|
||||||
for (size_t i = 0; i < ubufCount; ++i) {
|
for (size_t i = 0; i < ubufCount; ++i) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (!ubufs[i])
|
if (!ubufs[i]) {
|
||||||
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), int(i));
|
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), i);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
m_ubufs.push_back(ubufs[i]);
|
m_ubufs.push_back(ubufs[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/graphicsdev/NX.hpp"
|
#include "boo/graphicsdev/NX.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "boo/graphicsdev/GLSLMacros.hpp"
|
#include "boo/graphicsdev/GLSLMacros.hpp"
|
||||||
#include "../Common.hpp"
|
#include "lib/graphicsdev/Common.hpp"
|
||||||
#include "xxhash/xxhash.h"
|
|
||||||
|
|
||||||
#include "main/shaderobj.h"
|
#include "main/shaderobj.h"
|
||||||
#include "st_program.h"
|
#include "st_program.h"
|
||||||
|
@ -19,6 +23,9 @@ extern "C" {
|
||||||
#include "gallium/winsys/nouveau/switch/nouveau_switch_public.h"
|
#include "gallium/winsys/nouveau/switch/nouveau_switch_public.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
#include <xxhash/xxhash.h>
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
@ -1801,7 +1808,7 @@ bool NXContext::initialize() {
|
||||||
|
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
gfxSetMode(GfxMode_TiledDouble);
|
gfxSetMode(GfxMode_TiledDouble);
|
||||||
consoleInit(NULL);
|
consoleInit(nullptr);
|
||||||
printf("Activated console\n\n");
|
printf("Activated console\n\n");
|
||||||
m_screen = nouveau_switch_screen_create();
|
m_screen = nouveau_switch_screen_create();
|
||||||
if (!m_screen) {
|
if (!m_screen) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "boo/inputdev/DeviceBase.hpp"
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
#include <cstdarg>
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -37,25 +36,25 @@ size_t DeviceBase::receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DeviceBase::getVendorId() {
|
unsigned DeviceBase::getVendorId() const {
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->getVendorId();
|
return m_token->getVendorId();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DeviceBase::getProductId() {
|
unsigned DeviceBase::getProductId() const {
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->getProductId();
|
return m_token->getProductId();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view DeviceBase::getVendorName() {
|
std::string_view DeviceBase::getVendorName() const {
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->getVendorName();
|
return m_token->getVendorName();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view DeviceBase::getProductName() {
|
std::string_view DeviceBase::getProductName() const {
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->getProductName();
|
return m_token->getProductName();
|
||||||
return {};
|
return {};
|
||||||
|
@ -63,14 +62,14 @@ std::string_view DeviceBase::getProductName() {
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
const PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() {
|
PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() const {
|
||||||
if (m_hidDev)
|
if (m_hidDev)
|
||||||
return m_hidDev->_getReportDescriptor();
|
return m_hidDev->_getReportDescriptor();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
std::vector<uint8_t> DeviceBase::getReportDescriptor() {
|
std::vector<uint8_t> DeviceBase::getReportDescriptor() const {
|
||||||
if (m_hidDev)
|
if (m_hidDev)
|
||||||
return m_hidDev->_getReportDescriptor();
|
return m_hidDev->_getReportDescriptor();
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <Dbt.h>
|
#include <Dbt.h>
|
||||||
#include <hidclass.h>
|
#include <hidclass.h>
|
||||||
|
@ -10,6 +13,79 @@ namespace boo {
|
||||||
|
|
||||||
DeviceFinder* DeviceFinder::skDevFinder = nullptr;
|
DeviceFinder* DeviceFinder::skDevFinder = nullptr;
|
||||||
|
|
||||||
|
DeviceFinder::DeviceFinder(std::unordered_set<uint64_t> types) {
|
||||||
|
if (skDevFinder) {
|
||||||
|
fmt::print(stderr, fmt("only one instance of CDeviceFinder may be constructed"));
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
skDevFinder = this;
|
||||||
|
for (const uint64_t& typeHash : types) {
|
||||||
|
const DeviceSignature* sigIter = BOO_DEVICE_SIGS;
|
||||||
|
while (sigIter->m_name) {
|
||||||
|
if (sigIter->m_typeHash == typeHash)
|
||||||
|
m_types.push_back(sigIter);
|
||||||
|
++sigIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceFinder::~DeviceFinder() {
|
||||||
|
if (m_listener)
|
||||||
|
m_listener->stopScanning();
|
||||||
|
skDevFinder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceFinder::_insertToken(std::unique_ptr<DeviceToken>&& token) {
|
||||||
|
if (!DeviceSignature::DeviceMatchToken(*token, m_types)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tokensLock.lock();
|
||||||
|
const TInsertedDeviceToken insertedTok = m_tokens.emplace(token->getDevicePath(), std::move(token));
|
||||||
|
m_tokensLock.unlock();
|
||||||
|
deviceConnected(*insertedTok.first->second);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceFinder::_removeToken(const std::string& path) {
|
||||||
|
const auto preCheck = m_tokens.find(path);
|
||||||
|
if (preCheck == m_tokens.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceToken& tok = *preCheck->second;
|
||||||
|
std::shared_ptr<DeviceBase> dev = tok.m_connectedDev;
|
||||||
|
tok._deviceClose();
|
||||||
|
deviceDisconnected(tok, dev.get());
|
||||||
|
m_tokensLock.lock();
|
||||||
|
m_tokens.erase(preCheck);
|
||||||
|
m_tokensLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceFinder::startScanning() {
|
||||||
|
if (!m_listener)
|
||||||
|
m_listener = IHIDListenerNew(*this);
|
||||||
|
if (m_listener)
|
||||||
|
return m_listener->startScanning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceFinder::stopScanning() {
|
||||||
|
if (!m_listener)
|
||||||
|
m_listener = IHIDListenerNew(*this);
|
||||||
|
if (m_listener)
|
||||||
|
return m_listener->stopScanning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceFinder::scanNow() {
|
||||||
|
if (!m_listener)
|
||||||
|
m_listener = IHIDListenerNew(*this);
|
||||||
|
if (m_listener)
|
||||||
|
return m_listener->scanNow();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#if _WIN32 && !WINDOWS_STORE
|
#if _WIN32 && !WINDOWS_STORE
|
||||||
/* Windows-specific WM_DEVICECHANGED handler */
|
/* Windows-specific WM_DEVICECHANGED handler */
|
||||||
LRESULT DeviceFinder::winDevChangedHandler(WPARAM wParam, LPARAM lParam) {
|
LRESULT DeviceFinder::winDevChangedHandler(WPARAM wParam, LPARAM lParam) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "boo/inputdev/DeviceSignature.hpp"
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
#include "boo/inputdev/GenericPad.hpp"
|
#include "boo/inputdev/GenericPad.hpp"
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "boo/inputdev/DolphinSmashAdapter.hpp"
|
#include "boo/inputdev/DolphinSmashAdapter.hpp"
|
||||||
#include "boo/inputdev/DeviceSignature.hpp"
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ void DolphinSmashAdapter::transferCycle() {
|
||||||
if (recvSz != 37 || payload[0] != 0x21)
|
if (recvSz != 37 || payload[0] != 0x21)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
|
// fmt::print("RECEIVED DATA {} {:02X}\n", recvSz, payload[0]);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(m_callbackLock);
|
std::lock_guard<std::mutex> lk(m_callbackLock);
|
||||||
if (!m_callback)
|
if (!m_callback)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "boo/inputdev/DualshockPad.hpp"
|
#include "boo/inputdev/DualshockPad.hpp"
|
||||||
#include "boo/inputdev/DeviceSignature.hpp"
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
|
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <memory.h>
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
inline uint16_t bswap16(uint16_t val) { return _byteswap_ushort(val); }
|
inline uint16_t bswap16(uint16_t val) { return _byteswap_ushort(val); }
|
||||||
|
@ -42,16 +43,20 @@ void DualshockPad::deviceDisconnected() {
|
||||||
|
|
||||||
void DualshockPad::initialCycle() {
|
void DualshockPad::initialCycle() {
|
||||||
#if 0
|
#if 0
|
||||||
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe
|
// Tells controller to start sending changes on in pipe
|
||||||
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4))
|
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00};
|
||||||
{
|
|
||||||
deviceError("Unable to send complete packet! Request size %x\n", sizeof(setupCommand));
|
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4)) {
|
||||||
return;
|
deviceError("Unable to send complete packet! Request size {:x}\n", sizeof(setupCommand));
|
||||||
}
|
return;
|
||||||
uint8_t btAddr[8];
|
}
|
||||||
receiveHIDReport(btAddr, sizeof(btAddr), HIDReportType::Feature, 0xF5);
|
|
||||||
for (int i = 0; i < 6; i++)
|
uint8_t btAddr[8];
|
||||||
m_btAddress[5 - i] = btAddr[i + 2]; // Copy into buffer reversed, so it is LSB first
|
receiveHIDReport(btAddr, sizeof(btAddr), HIDReportType::Feature, 0xF5);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
// Copy into buffer reversed, so it is LSB first
|
||||||
|
m_btAddress[5 - i] = btAddr[i + 2];
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,12 @@ class HIDListenerBSD final : public IHIDListener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HIDListenerBSD(DeviceFinder& finder) : m_finder(finder) {}
|
HIDListenerBSD(DeviceFinder& finder) : m_finder(finder) {}
|
||||||
|
~HIDListenerBSD() override = default;
|
||||||
|
|
||||||
~HIDListenerBSD() {}
|
bool startScanning() override { return false; }
|
||||||
|
bool stopScanning() override { return false; }
|
||||||
|
|
||||||
bool startScanning() { return false; }
|
bool scanNow() override { return false; }
|
||||||
bool stopScanning() { return false; }
|
|
||||||
|
|
||||||
bool scanNow() { return false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IHIDListener* IHIDListenerNew(DeviceFinder& finder) { return new HIDListenerBSD(finder); }
|
IHIDListener* IHIDListenerNew(DeviceFinder& finder) { return new HIDListenerBSD(finder); }
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "lib/inputdev/IOKitPointer.hpp"
|
||||||
|
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
#include <IOKit/hid/IOHIDDevicePlugin.h>
|
#include <IOKit/hid/IOHIDDevicePlugin.h>
|
||||||
#include <IOKit/usb/IOUSBLib.h>
|
#include <IOKit/usb/IOUSBLib.h>
|
||||||
#include "IOKitPointer.hpp"
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||||
if (m_usbIntf) {
|
if (m_usbIntf) {
|
||||||
IOReturn res = m_usbIntf->WritePipe(m_usbIntf.storage(), m_usbIntfOutPipe, (void*)data, length);
|
IOReturn res = m_usbIntf->WritePipe(m_usbIntf.storage(), m_usbIntfOutPipe, (void*)data, length);
|
||||||
return res == kIOReturnSuccess;
|
return res == kIOReturnSuccess;
|
||||||
|
@ -31,7 +34,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||||
if (m_usbIntf) {
|
if (m_usbIntf) {
|
||||||
UInt32 readSize = length;
|
UInt32 readSize = length;
|
||||||
IOReturn res = m_usbIntf->ReadPipe(m_usbIntf.storage(), m_usbIntfInPipe, data, &readSize);
|
IOReturn res = m_usbIntf->ReadPipe(m_usbIntf.storage(), m_usbIntfInPipe, data, &readSize);
|
||||||
|
@ -42,7 +45,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> _getReportDescriptor() {
|
std::vector<uint8_t> _getReportDescriptor() override {
|
||||||
if (m_hidIntf) {
|
if (m_hidIntf) {
|
||||||
if (CFTypeRef desc = IOHIDDeviceGetProperty(m_hidIntf.get(), CFSTR(kIOHIDReportDescriptorKey))) {
|
if (CFTypeRef desc = IOHIDDeviceGetProperty(m_hidIntf.get(), CFSTR(kIOHIDReportDescriptorKey))) {
|
||||||
CFIndex len = CFDataGetLength(CFDataRef(desc));
|
CFIndex len = CFDataGetLength(CFDataRef(desc));
|
||||||
|
@ -54,7 +57,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
/* HACK: A bug in IOBluetoothGamepadHIDDriver prevents raw output report transmission
|
/* HACK: A bug in IOBluetoothGamepadHIDDriver prevents raw output report transmission
|
||||||
* USB driver appears to work correctly */
|
* USB driver appears to work correctly */
|
||||||
if (m_hidIntf && !m_isBt) {
|
if (m_hidIntf && !m_isBt) {
|
||||||
|
@ -64,7 +67,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
if (m_hidIntf) {
|
if (m_hidIntf) {
|
||||||
CFIndex readSize = length;
|
CFIndex readSize = length;
|
||||||
IOReturn res = IOHIDDeviceGetReport(m_hidIntf.get(), IOHIDReportType(tp), message, data, &readSize);
|
IOReturn res = IOHIDDeviceGetReport(m_hidIntf.get(), IOHIDReportType(tp), message, data, &readSize);
|
||||||
|
@ -273,13 +276,13 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||||
device->m_hidIntf.reset();
|
device->m_hidIntf.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HIDDeviceIOKit(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
HIDDeviceIOKit(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||||
|
|
||||||
void _startThread() {
|
void _startThread() override {
|
||||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||||
DeviceType dType = m_token.getDeviceType();
|
DeviceType dType = m_token.getDeviceType();
|
||||||
if (dType == DeviceType::USB)
|
if (dType == DeviceType::USB)
|
||||||
|
@ -295,7 +298,7 @@ public:
|
||||||
m_initCond.wait(lk);
|
m_initCond.wait(lk);
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDDeviceIOKit() {
|
~HIDDeviceIOKit() override {
|
||||||
m_runningTransferLoop = false;
|
m_runningTransferLoop = false;
|
||||||
if (m_thread.joinable())
|
if (m_thread.joinable())
|
||||||
m_thread.detach();
|
m_thread.detach();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ public:
|
||||||
HIDDeviceNX(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
HIDDeviceNX(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||||
|
|
||||||
void _deviceDisconnected() {}
|
void _deviceDisconnected() override {}
|
||||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override { return 0; }
|
||||||
std::vector<uint8_t> _getReportDescriptor() { return {}; }
|
std::vector<uint8_t> _getReportDescriptor() override { return {}; }
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return 0; }
|
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return 0; }
|
||||||
void _startThread() {}
|
void _startThread() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||||
#include "IHIDDevice.hpp"
|
|
||||||
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
#include "boo/inputdev/DeviceBase.hpp"
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
|
||||||
|
@ -9,12 +11,12 @@ class HIDDeviceUWP : public IHIDDevice {
|
||||||
public:
|
public:
|
||||||
HIDDeviceUWP(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {}
|
HIDDeviceUWP(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {}
|
||||||
|
|
||||||
void _deviceDisconnected() {}
|
void _deviceDisconnected() override {}
|
||||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override { return 0; }
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||||
void _startThread() {}
|
void _startThread() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
#include "boo/inputdev/DeviceBase.hpp"
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
#include <thread>
|
#include "boo/inputdev/HIDParser.hpp"
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <fcntl.h>
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
#include <stropts.h>
|
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usbdevice_fs.h>
|
#include <linux/usbdevice_fs.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/hidraw.h>
|
#include <linux/hidraw.h>
|
||||||
#include <fcntl.h>
|
#include <stropts.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cstring>
|
|
||||||
#include "boo/inputdev/HIDParser.hpp"
|
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||||
if (m_devFd) {
|
if (m_devFd) {
|
||||||
usbdevfs_bulktransfer xfer = {m_usbIntfOutPipe | USB_DIR_OUT, (unsigned)length, 30, (void*)data};
|
usbdevfs_bulktransfer xfer = {m_usbIntfOutPipe | USB_DIR_OUT, (unsigned)length, 30, (void*)data};
|
||||||
int ret = ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
int ret = ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
||||||
|
@ -51,7 +53,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||||
if (m_devFd) {
|
if (m_devFd) {
|
||||||
usbdevfs_bulktransfer xfer = {m_usbIntfInPipe | USB_DIR_IN, (unsigned)length, 30, data};
|
usbdevfs_bulktransfer xfer = {m_usbIntfInPipe | USB_DIR_IN, (unsigned)length, 30, data};
|
||||||
return ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
return ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
||||||
|
@ -102,7 +104,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request that kernel disconnects existing driver */
|
/* Request that kernel disconnects existing driver */
|
||||||
usbdevfs_ioctl disconnectReq = {0, USBDEVFS_DISCONNECT, NULL};
|
usbdevfs_ioctl disconnectReq = {0, USBDEVFS_DISCONNECT, nullptr};
|
||||||
ioctl(fd, USBDEVFS_IOCTL, &disconnectReq);
|
ioctl(fd, USBDEVFS_IOCTL, &disconnectReq);
|
||||||
|
|
||||||
/* Return control to main thread */
|
/* Return control to main thread */
|
||||||
|
@ -209,9 +211,9 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
udev_device_unref(udevDev);
|
udev_device_unref(udevDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||||
|
|
||||||
std::vector<uint8_t> _getReportDescriptor() {
|
std::vector<uint8_t> _getReportDescriptor() override {
|
||||||
/* Report descriptor size */
|
/* Report descriptor size */
|
||||||
int reportDescSize;
|
int reportDescSize;
|
||||||
if (ioctl(m_devFd, HIDIOCGRDESCSIZE, &reportDescSize) == -1)
|
if (ioctl(m_devFd, HIDIOCGRDESCSIZE, &reportDescSize) == -1)
|
||||||
|
@ -227,7 +229,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
if (m_devFd) {
|
if (m_devFd) {
|
||||||
if (tp == HIDReportType::Feature) {
|
if (tp == HIDReportType::Feature) {
|
||||||
int ret = ioctl(m_devFd, HIDIOCSFEATURE(length), data);
|
int ret = ioctl(m_devFd, HIDIOCSFEATURE(length), data);
|
||||||
|
@ -244,7 +246,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
if (m_devFd) {
|
if (m_devFd) {
|
||||||
if (tp == HIDReportType::Feature) {
|
if (tp == HIDReportType::Feature) {
|
||||||
data[0] = message;
|
data[0] = message;
|
||||||
|
@ -261,7 +263,7 @@ public:
|
||||||
HIDDeviceUdev(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
HIDDeviceUdev(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||||
|
|
||||||
void _startThread() {
|
void _startThread() override {
|
||||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||||
DeviceType dType = m_token.getDeviceType();
|
DeviceType dType = m_token.getDeviceType();
|
||||||
if (dType == DeviceType::USB)
|
if (dType == DeviceType::USB)
|
||||||
|
@ -277,7 +279,7 @@ public:
|
||||||
m_initCond.wait(lk);
|
m_initCond.wait(lk);
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDDeviceUdev() {
|
~HIDDeviceUdev() override {
|
||||||
m_runningTransferLoop = false;
|
m_runningTransferLoop = false;
|
||||||
if (m_thread.joinable())
|
if (m_thread.joinable())
|
||||||
m_thread.detach();
|
m_thread.detach();
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||||
#include "IHIDDevice.hpp"
|
#include "lib/inputdev/IHIDDevice.hpp"
|
||||||
|
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
#include "boo/inputdev/DeviceBase.hpp"
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN 1
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
@ -27,8 +29,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
DeviceToken& m_token;
|
DeviceToken& m_token;
|
||||||
std::shared_ptr<DeviceBase> m_devImp;
|
std::shared_ptr<DeviceBase> m_devImp;
|
||||||
|
|
||||||
HANDLE m_devHandle = 0;
|
HANDLE m_devHandle = nullptr;
|
||||||
HANDLE m_hidHandle = 0;
|
HANDLE m_hidHandle = nullptr;
|
||||||
WINUSB_INTERFACE_HANDLE m_usbHandle = nullptr;
|
WINUSB_INTERFACE_HANDLE m_usbHandle = nullptr;
|
||||||
unsigned m_usbIntfInPipe = 0;
|
unsigned m_usbIntfInPipe = 0;
|
||||||
unsigned m_usbIntfOutPipe = 0;
|
unsigned m_usbIntfOutPipe = 0;
|
||||||
|
@ -39,21 +41,22 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||||
if (m_usbHandle) {
|
if (m_usbHandle) {
|
||||||
ULONG lengthTransferred = 0;
|
ULONG lengthTransferred = 0;
|
||||||
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, NULL) ||
|
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, nullptr) ||
|
||||||
lengthTransferred != length)
|
lengthTransferred != length) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||||
if (m_usbHandle) {
|
if (m_usbHandle) {
|
||||||
ULONG lengthTransferred = 0;
|
ULONG lengthTransferred = 0;
|
||||||
if (!WinUsb_ReadPipe(m_usbHandle, m_usbIntfInPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, NULL))
|
if (!WinUsb_ReadPipe(m_usbHandle, m_usbIntfInPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, nullptr))
|
||||||
return 0;
|
return 0;
|
||||||
return lengthTransferred;
|
return lengthTransferred;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +69,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
|
|
||||||
/* POSIX.. who needs it?? -MS */
|
/* POSIX.. who needs it?? -MS */
|
||||||
device->m_devHandle =
|
device->m_devHandle =
|
||||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
|
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr,
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||||
if (INVALID_HANDLE_VALUE == device->m_devHandle) {
|
if (INVALID_HANDLE_VALUE == device->m_devHandle) {
|
||||||
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
||||||
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
||||||
|
@ -150,8 +153,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
/* POSIX.. who needs it?? -MS */
|
/* POSIX.. who needs it?? -MS */
|
||||||
device->m_overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
device->m_overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||||
device->m_hidHandle =
|
device->m_hidHandle =
|
||||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
|
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr,
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||||
if (INVALID_HANDLE_VALUE == device->m_hidHandle) {
|
if (INVALID_HANDLE_VALUE == device->m_hidHandle) {
|
||||||
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
||||||
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
||||||
|
@ -199,14 +202,14 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
device->m_hidHandle = nullptr;
|
device->m_hidHandle = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||||
|
|
||||||
std::vector<uint8_t> m_sendBuf;
|
std::vector<uint8_t> m_sendBuf;
|
||||||
std::vector<uint8_t> m_recvBuf;
|
std::vector<uint8_t> m_recvBuf;
|
||||||
|
|
||||||
const PHIDP_PREPARSED_DATA _getReportDescriptor() { return m_preparsedData; }
|
const PHIDP_PREPARSED_DATA _getReportDescriptor() override { return m_preparsedData; }
|
||||||
|
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
size_t maxOut = std::max(m_minFeatureSz, std::max(m_minOutputSz, length));
|
size_t maxOut = std::max(m_minFeatureSz, std::max(m_minOutputSz, length));
|
||||||
if (m_sendBuf.size() < maxOut)
|
if (m_sendBuf.size() < maxOut)
|
||||||
m_sendBuf.resize(maxOut);
|
m_sendBuf.resize(maxOut);
|
||||||
|
@ -250,7 +253,7 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||||
size_t maxIn = std::max(m_minFeatureSz, std::max(m_minInputSz, length));
|
size_t maxIn = std::max(m_minFeatureSz, std::max(m_minInputSz, length));
|
||||||
if (m_recvBuf.size() < maxIn)
|
if (m_recvBuf.size() < maxIn)
|
||||||
m_recvBuf.resize(maxIn);
|
m_recvBuf.resize(maxIn);
|
||||||
|
@ -273,7 +276,7 @@ public:
|
||||||
HIDDeviceWinUSB(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
HIDDeviceWinUSB(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||||
|
|
||||||
void _startThread() {
|
void _startThread() override {
|
||||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||||
DeviceType dType = m_token.getDeviceType();
|
DeviceType dType = m_token.getDeviceType();
|
||||||
if (dType == DeviceType::USB)
|
if (dType == DeviceType::USB)
|
||||||
|
@ -287,7 +290,7 @@ public:
|
||||||
m_initCond.wait(lk);
|
m_initCond.wait(lk);
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDDeviceWinUSB() {
|
~HIDDeviceWinUSB() override {
|
||||||
m_runningTransferLoop = false;
|
m_runningTransferLoop = false;
|
||||||
if (m_thread.joinable())
|
if (m_thread.joinable())
|
||||||
m_thread.detach();
|
m_thread.detach();
|
||||||
|
|
|
@ -16,8 +16,7 @@ class HIDDeviceBSD final : public IHIDDevice {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HIDDeviceBSD(DeviceToken& token, DeviceBase& devImp) : m_token(token), m_devImp(devImp) {}
|
HIDDeviceBSD(DeviceToken& token, DeviceBase& devImp) : m_token(token), m_devImp(devImp) {}
|
||||||
|
~HIDDeviceBSD() override = default;
|
||||||
~HIDDeviceBSD() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||||
|
|
|
@ -108,7 +108,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||||
|
|
||||||
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::USB, vid, pid, vstr, pstr, devPath));
|
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::USB, vid, pid, vstr, pstr, devPath));
|
||||||
|
|
||||||
// printf("ADDED %08X %s\n", obj.get(), devPath);
|
// fmt::print(fmt("ADDED {:08X} {}\n"), obj.get(), devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||||
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
||||||
continue;
|
continue;
|
||||||
listener->m_finder._removeToken(devPath);
|
listener->m_finder._removeToken(devPath);
|
||||||
// printf("REMOVED %08X %s\n", obj.get(), devPath);
|
// fmt::print(fmt("REMOVED {:08X} {}\n"), obj.get(), devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||||
|
|
||||||
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::HID, vidv, pidv, vstr, pstr, devPath));
|
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::HID, vidv, pidv, vstr, pstr, devPath));
|
||||||
|
|
||||||
// printf("ADDED %08X %s\n", obj, devPath);
|
// fmt::print(fmt("ADDED {:08X} {}\n"), obj, devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||||
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
||||||
continue;
|
continue;
|
||||||
listener->m_finder._removeToken(devPath);
|
listener->m_finder._removeToken(devPath);
|
||||||
// printf("REMOVED %08X %s\n", obj, devPath);
|
// fmt::print(fmt("REMOVED {:08X} {}\n"), obj, devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,23 +263,23 @@ public:
|
||||||
m_scanningEnabled = false;
|
m_scanningEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDListenerIOKit() {
|
~HIDListenerIOKit() override {
|
||||||
// CFRunLoopRemoveSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
|
// CFRunLoopRemoveSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
|
||||||
IONotificationPortDestroy(m_llPort);
|
IONotificationPortDestroy(m_llPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Automatic device scanning */
|
/* Automatic device scanning */
|
||||||
bool startScanning() {
|
bool startScanning() override {
|
||||||
m_scanningEnabled = true;
|
m_scanningEnabled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool stopScanning() {
|
bool stopScanning() override {
|
||||||
m_scanningEnabled = false;
|
m_scanningEnabled = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manual device scanning */
|
/* Manual device scanning */
|
||||||
bool scanNow() {
|
bool scanNow() override {
|
||||||
IOObjectPointer<io_iterator_t> iter;
|
IOObjectPointer<io_iterator_t> iter;
|
||||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(m_usbClass), &iter) == kIOReturnSuccess) {
|
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(m_usbClass), &iter) == kIOReturnSuccess) {
|
||||||
devicesConnectedUSBLL(this, iter.get());
|
devicesConnectedUSBLL(this, iter.get());
|
||||||
|
|
|
@ -8,9 +8,9 @@ class HIDListenerNX : public IHIDListener {
|
||||||
public:
|
public:
|
||||||
HIDListenerNX(DeviceFinder& finder) : m_finder(finder) {}
|
HIDListenerNX(DeviceFinder& finder) : m_finder(finder) {}
|
||||||
|
|
||||||
bool startScanning() { return false; }
|
bool startScanning() override { return false; }
|
||||||
bool stopScanning() { return false; }
|
bool stopScanning() override { return false; }
|
||||||
bool scanNow() { return false; }
|
bool scanNow() override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerNX>(finder); }
|
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerNX>(finder); }
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||||
|
|
||||||
#include "boo/inputdev/IHIDListener.hpp"
|
#include "boo/inputdev/IHIDListener.hpp"
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
|
||||||
|
@ -9,11 +10,11 @@ public:
|
||||||
HIDListenerUWP(DeviceFinder& finder) {}
|
HIDListenerUWP(DeviceFinder& finder) {}
|
||||||
|
|
||||||
/* Automatic device scanning */
|
/* Automatic device scanning */
|
||||||
bool startScanning() { return false; }
|
bool startScanning() override { return false; }
|
||||||
bool stopScanning() { return false; }
|
bool stopScanning() override { return false; }
|
||||||
|
|
||||||
/* Manual device scanning */
|
/* Manual device scanning */
|
||||||
bool scanNow() { return false; }
|
bool scanNow() override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerUWP>(finder); }
|
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerUWP>(finder); }
|
||||||
|
|
|
@ -118,14 +118,14 @@ class HIDListenerUdev final : public IHIDListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
udev_list_entry* att = nullptr;
|
udev_list_entry* att = nullptr;
|
||||||
udev_list_entry_foreach(att, attrs)
|
udev_list_entry_foreach(att, attrs)
|
||||||
{
|
{
|
||||||
const char* name = udev_list_entry_get_name(att);
|
const char* name = udev_list_entry_get_name(att);
|
||||||
const char* val = udev_list_entry_get_value(att);
|
const char* val = udev_list_entry_get_value(att);
|
||||||
fprintf(stderr, "%s %s\n", name, val);
|
fmt::print(stderr, fmt("{} {}\n"), name, val);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n\n");
|
std::fputs("\n\n", stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_finder._insertToken(std::make_unique<DeviceToken>(type, vid, pid, manuf, product, devPath));
|
m_finder._insertToken(std::make_unique<DeviceToken>(type, vid, pid, manuf, product, devPath));
|
||||||
|
@ -187,7 +187,7 @@ public:
|
||||||
m_udevThread = std::thread(std::bind(&HIDListenerUdev::_udevProc, this), this);
|
m_udevThread = std::thread(std::bind(&HIDListenerUdev::_udevProc, this), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDListenerUdev() {
|
~HIDListenerUdev() override {
|
||||||
pthread_cancel(m_udevThread.native_handle());
|
pthread_cancel(m_udevThread.native_handle());
|
||||||
if (m_udevThread.joinable())
|
if (m_udevThread.joinable())
|
||||||
m_udevThread.join();
|
m_udevThread.join();
|
||||||
|
@ -195,17 +195,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Automatic device scanning */
|
/* Automatic device scanning */
|
||||||
bool startScanning() {
|
bool startScanning() override {
|
||||||
m_scanningEnabled = true;
|
m_scanningEnabled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool stopScanning() {
|
bool stopScanning() override {
|
||||||
m_scanningEnabled = false;
|
m_scanningEnabled = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manual device scanning */
|
/* Manual device scanning */
|
||||||
bool scanNow() {
|
bool scanNow() override {
|
||||||
udev_enumerate* uenum = udev_enumerate_new(GetUdev());
|
udev_enumerate* uenum = udev_enumerate_new(GetUdev());
|
||||||
udev_enumerate_add_match_subsystem(uenum, "usb");
|
udev_enumerate_add_match_subsystem(uenum, "usb");
|
||||||
udev_enumerate_add_match_subsystem(uenum, "bluetooth");
|
udev_enumerate_add_match_subsystem(uenum, "bluetooth");
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||||
|
|
||||||
#include "boo/inputdev/IHIDListener.hpp"
|
#include "boo/inputdev/IHIDListener.hpp"
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
|
||||||
#include "boo/inputdev/XInputPad.hpp"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
#include "boo/inputdev/XInputPad.hpp"
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN 1
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,17 +54,17 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||||
CHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
|
CHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
|
||||||
|
|
||||||
/* List all connected HID devices */
|
/* List all connected HID devices */
|
||||||
hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
hDevInfo = SetupDiGetClassDevs(nullptr, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
||||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0;; ++i) {
|
for (i = 0;; ++i) {
|
||||||
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, TypeGUID, i, &DeviceInterfaceData))
|
if (!SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, TypeGUID, i, &DeviceInterfaceData))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DeviceInterfaceDetailData.wtf.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
DeviceInterfaceDetailData.wtf.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||||
if (!SetupDiGetDeviceInterfaceDetailA(hDevInfo, &DeviceInterfaceData, &DeviceInterfaceDetailData.wtf,
|
if (!SetupDiGetDeviceInterfaceDetailA(hDevInfo, &DeviceInterfaceData, &DeviceInterfaceDetailData.wtf,
|
||||||
sizeof(DeviceInterfaceDetailData), NULL, &DeviceInfoData))
|
sizeof(DeviceInterfaceDetailData), nullptr, &DeviceInfoData))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = CM_Get_Device_IDA(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
|
r = CM_Get_Device_IDA(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
|
||||||
|
@ -73,7 +76,7 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||||
szVid[0] = '\0';
|
szVid[0] = '\0';
|
||||||
szPid[0] = '\0';
|
szPid[0] = '\0';
|
||||||
szMi[0] = '\0';
|
szMi[0] = '\0';
|
||||||
while (pszToken != NULL) {
|
while (pszToken != nullptr) {
|
||||||
for (j = 0; j < 3; ++j) {
|
for (j = 0; j < 3; ++j) {
|
||||||
if (strncmp(pszToken, arPrefix[j], 4) == 0) {
|
if (strncmp(pszToken, arPrefix[j], 4) == 0) {
|
||||||
switch (j) {
|
switch (j) {
|
||||||
|
@ -91,14 +94,14 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pszToken = strtok_s(NULL, "\\#&", &pszNextToken);
|
pszToken = strtok_s(nullptr, "\\#&", &pszNextToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!szVid[0] || !szPid[0])
|
if (!szVid[0] || !szPid[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned vid = strtol(szVid + 4, NULL, 16);
|
unsigned vid = strtol(szVid + 4, nullptr, 16);
|
||||||
unsigned pid = strtol(szPid + 4, NULL, 16);
|
unsigned pid = strtol(szPid + 4, nullptr, 16);
|
||||||
|
|
||||||
CHAR productW[1024] = {0};
|
CHAR productW[1024] = {0};
|
||||||
// CHAR product[1024] = {0};
|
// CHAR product[1024] = {0};
|
||||||
|
@ -121,8 +124,8 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||||
|
|
||||||
if (type == DeviceType::HID) {
|
if (type == DeviceType::HID) {
|
||||||
HANDLE devHnd = CreateFileA(DeviceInterfaceDetailData.wtf.DevicePath, GENERIC_WRITE | GENERIC_READ,
|
HANDLE devHnd = CreateFileA(DeviceInterfaceDetailData.wtf.DevicePath, GENERIC_WRITE | GENERIC_READ,
|
||||||
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||||
if (INVALID_HANDLE_VALUE == devHnd)
|
if (INVALID_HANDLE_VALUE == devHnd)
|
||||||
continue;
|
continue;
|
||||||
PHIDP_PREPARSED_DATA preparsedData;
|
PHIDP_PREPARSED_DATA preparsedData;
|
||||||
|
@ -227,29 +230,29 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~HIDListenerWinUSB() {
|
~HIDListenerWinUSB() override {
|
||||||
m_xinputRunning = false;
|
m_xinputRunning = false;
|
||||||
if (m_xinputThread.joinable())
|
if (m_xinputThread.joinable())
|
||||||
m_xinputThread.join();
|
m_xinputThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Automatic device scanning */
|
/* Automatic device scanning */
|
||||||
bool startScanning() {
|
bool startScanning() override {
|
||||||
m_scanningEnabled = true;
|
m_scanningEnabled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool stopScanning() {
|
bool stopScanning() override {
|
||||||
m_scanningEnabled = false;
|
m_scanningEnabled = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manual device scanning */
|
/* Manual device scanning */
|
||||||
bool scanNow() {
|
bool scanNow() override {
|
||||||
_pollDevices(nullptr);
|
_pollDevices(nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _extDevConnect(const char* path) {
|
bool _extDevConnect(const char* path) override {
|
||||||
char upperPath[1024];
|
char upperPath[1024];
|
||||||
strcpy_s(upperPath, 1024, path);
|
strcpy_s(upperPath, 1024, path);
|
||||||
CharUpperA(upperPath);
|
CharUpperA(upperPath);
|
||||||
|
@ -258,7 +261,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _extDevDisconnect(const char* path) {
|
bool _extDevDisconnect(const char* path) override {
|
||||||
char upperPath[1024];
|
char upperPath[1024];
|
||||||
strcpy_s(upperPath, 1024, path);
|
strcpy_s(upperPath, 1024, path);
|
||||||
CharUpperA(upperPath);
|
CharUpperA(upperPath);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "boo/inputdev/HIDParser.hpp"
|
#include "boo/inputdev/HIDParser.hpp"
|
||||||
#include <map>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
@ -11,251 +13,257 @@ namespace boo {
|
||||||
* http://www.usb.org/developers/hidpage/HID1_11.pdf
|
* http://www.usb.org/developers/hidpage/HID1_11.pdf
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char* UsagePageNames[] = {"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
|
constexpr std::array<const char*, 14> UsagePageNames{
|
||||||
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
|
"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
|
||||||
"Ordinal", "Telephony", "Consumer", "Digitizer"};
|
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
|
||||||
|
"Ordinal", "Telephony", "Consumer", "Digitizer",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* GenericDesktopUsages[] = {"Undefined",
|
constexpr std::array<const char*, 182> GenericDesktopUsages{
|
||||||
"Pointer",
|
"Undefined",
|
||||||
"Mouse",
|
"Pointer",
|
||||||
"Reserved",
|
"Mouse",
|
||||||
"Joystick",
|
"Reserved",
|
||||||
"Game Pad",
|
"Joystick",
|
||||||
"Keyboard",
|
"Game Pad",
|
||||||
"Keypad",
|
"Keyboard",
|
||||||
"Multi-axis Controller",
|
"Keypad",
|
||||||
"Tablet PC System Controls",
|
"Multi-axis Controller",
|
||||||
nullptr,
|
"Tablet PC System Controls",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
"X",
|
nullptr,
|
||||||
"Y",
|
"X",
|
||||||
"Z",
|
"Y",
|
||||||
"Rx",
|
"Z",
|
||||||
"Ry",
|
"Rx",
|
||||||
"Rz",
|
"Ry",
|
||||||
"Slider",
|
"Rz",
|
||||||
"Dial",
|
"Slider",
|
||||||
"Wheel",
|
"Dial",
|
||||||
"Hat Switch",
|
"Wheel",
|
||||||
"Counted Buffer",
|
"Hat Switch",
|
||||||
"Byte Count",
|
"Counted Buffer",
|
||||||
"Motion Wakeup",
|
"Byte Count",
|
||||||
"Start",
|
"Motion Wakeup",
|
||||||
"Select",
|
"Start",
|
||||||
"Reserved",
|
"Select",
|
||||||
"Vx",
|
"Reserved",
|
||||||
"Vy",
|
"Vx",
|
||||||
"Vz",
|
"Vy",
|
||||||
"Vbrx",
|
"Vz",
|
||||||
"Vbry",
|
"Vbrx",
|
||||||
"Vbrz",
|
"Vbry",
|
||||||
"Vno",
|
"Vbrz",
|
||||||
"Feature Notification",
|
"Vno",
|
||||||
"Resolution Multiplier",
|
"Feature Notification",
|
||||||
nullptr,
|
"Resolution Multiplier",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
"System Control",
|
nullptr,
|
||||||
"System Power Down",
|
"System Control",
|
||||||
"System Sleep",
|
"System Power Down",
|
||||||
"System Wake Up",
|
"System Sleep",
|
||||||
"System Context Menu",
|
"System Wake Up",
|
||||||
"System Main Menu",
|
"System Context Menu",
|
||||||
"System App Menu",
|
"System Main Menu",
|
||||||
"System Menu Help",
|
"System App Menu",
|
||||||
"System Menu Exit",
|
"System Menu Help",
|
||||||
"System Menu Select",
|
"System Menu Exit",
|
||||||
"System Menu Right",
|
"System Menu Select",
|
||||||
"System Menu Left",
|
"System Menu Right",
|
||||||
"System Menu Up",
|
"System Menu Left",
|
||||||
"System Menu Down",
|
"System Menu Up",
|
||||||
"System Cold Restart",
|
"System Menu Down",
|
||||||
"System Warm Restart",
|
"System Cold Restart",
|
||||||
"D-pad Up",
|
"System Warm Restart",
|
||||||
"D-pad Down",
|
"D-pad Up",
|
||||||
"D-pad Right",
|
"D-pad Down",
|
||||||
"D-pad Left",
|
"D-pad Right",
|
||||||
nullptr,
|
"D-pad Left",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
"System Dock",
|
nullptr,
|
||||||
"System Undock",
|
"System Dock",
|
||||||
"System Setup",
|
"System Undock",
|
||||||
"System Break",
|
"System Setup",
|
||||||
"System Debugger Break",
|
"System Break",
|
||||||
"Application Break",
|
"System Debugger Break",
|
||||||
"Application Debugger Break",
|
"Application Break",
|
||||||
"System Speaker Mute",
|
"Application Debugger Break",
|
||||||
"System Hibernate",
|
"System Speaker Mute",
|
||||||
nullptr,
|
"System Hibernate",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
"System Display Invert",
|
nullptr,
|
||||||
"System Display Internal",
|
"System Display Invert",
|
||||||
"System Display External",
|
"System Display Internal",
|
||||||
"System Display Both",
|
"System Display External",
|
||||||
"System Display Dual",
|
"System Display Both",
|
||||||
"System Display Toggle Int/Ext"};
|
"System Display Dual",
|
||||||
|
"System Display Toggle Int/Ext",
|
||||||
|
};
|
||||||
|
|
||||||
static const char* GameUsages[] = {"Undefined",
|
constexpr std::array<const char*, 58> GameUsages{
|
||||||
"3D Game Controller",
|
"Undefined",
|
||||||
"Pinball Device",
|
"3D Game Controller",
|
||||||
"Gun Device",
|
"Pinball Device",
|
||||||
nullptr,
|
"Gun Device",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
"Point of View",
|
nullptr,
|
||||||
"Turn Right/Left",
|
"Point of View",
|
||||||
"Pitch Forward/Backward",
|
"Turn Right/Left",
|
||||||
"Roll Right/Left",
|
"Pitch Forward/Backward",
|
||||||
"Move Right/Left",
|
"Roll Right/Left",
|
||||||
"Move Forward/Backward",
|
"Move Right/Left",
|
||||||
"Move Up/Down",
|
"Move Forward/Backward",
|
||||||
"Lean Right/Left",
|
"Move Up/Down",
|
||||||
"Lean Forward/Backward",
|
"Lean Right/Left",
|
||||||
"Height of POV",
|
"Lean Forward/Backward",
|
||||||
"Flipper",
|
"Height of POV",
|
||||||
"Secondary Flipper",
|
"Flipper",
|
||||||
"Bump",
|
"Secondary Flipper",
|
||||||
"New Game",
|
"Bump",
|
||||||
"Shoot Ball",
|
"New Game",
|
||||||
"Player",
|
"Shoot Ball",
|
||||||
"Gun Bolt",
|
"Player",
|
||||||
"Gun Clip",
|
"Gun Bolt",
|
||||||
"Gun Selector",
|
"Gun Clip",
|
||||||
"Gun Single Shot",
|
"Gun Selector",
|
||||||
"Gun Burst",
|
"Gun Single Shot",
|
||||||
"Gun Automatic",
|
"Gun Burst",
|
||||||
"Gun Safety",
|
"Gun Automatic",
|
||||||
"Gemepad Fire/Jump",
|
"Gun Safety",
|
||||||
nullptr,
|
"Gemepad Fire/Jump",
|
||||||
"Gamepad Trigger"};
|
nullptr,
|
||||||
|
"Gamepad Trigger",
|
||||||
|
};
|
||||||
|
|
||||||
enum class HIDCollectionType : uint8_t {
|
enum class HIDCollectionType : uint8_t {
|
||||||
Physical,
|
Physical,
|
||||||
|
@ -380,21 +388,31 @@ HIDMainItem::HIDMainItem(uint32_t flags, HIDUsagePage usagePage, HIDUsage usage,
|
||||||
, m_reportSize(reportSize) {}
|
, m_reportSize(reportSize) {}
|
||||||
|
|
||||||
const char* HIDMainItem::GetUsagePageName() const {
|
const char* HIDMainItem::GetUsagePageName() const {
|
||||||
if (int(m_usagePage) >= std::extent<decltype(UsagePageNames)>::value)
|
const auto index = size_t(m_usagePage);
|
||||||
|
|
||||||
|
if (index >= UsagePageNames.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return UsagePageNames[int(m_usagePage)];
|
}
|
||||||
|
|
||||||
|
return UsagePageNames[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* HIDMainItem::GetUsageName() const {
|
const char* HIDMainItem::GetUsageName() const {
|
||||||
|
const auto index = size_t(m_usage);
|
||||||
|
|
||||||
switch (m_usagePage) {
|
switch (m_usagePage) {
|
||||||
case HIDUsagePage::GenericDesktop:
|
case HIDUsagePage::GenericDesktop:
|
||||||
if (int(m_usage) >= std::extent<decltype(GenericDesktopUsages)>::value)
|
if (index >= GenericDesktopUsages.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return GenericDesktopUsages[int(m_usage)];
|
}
|
||||||
|
return GenericDesktopUsages[index];
|
||||||
|
|
||||||
case HIDUsagePage::Game:
|
case HIDUsagePage::Game:
|
||||||
if (int(m_usage) >= std::extent<decltype(GameUsages)>::value)
|
if (index >= GameUsages.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return GameUsages[int(m_usage)];
|
}
|
||||||
|
return GameUsages[index];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -443,17 +461,17 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
|
||||||
USHORT length = caps.NumberInputButtonCaps;
|
USHORT length = caps.NumberInputButtonCaps;
|
||||||
std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS());
|
std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS());
|
||||||
HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData);
|
HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData);
|
||||||
for (const HIDP_BUTTON_CAPS& caps : bCaps) {
|
for (const HIDP_BUTTON_CAPS& buttonCaps : bCaps) {
|
||||||
if (caps.IsRange) {
|
if (buttonCaps.IsRange) {
|
||||||
int usage = caps.Range.UsageMin;
|
int usage = buttonCaps.Range.UsageMin;
|
||||||
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
|
for (int i = buttonCaps.Range.DataIndexMin; i <= buttonCaps.Range.DataIndexMax; ++i, ++usage) {
|
||||||
inputItems.insert(std::make_pair(
|
inputItems.emplace(i, HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage), HIDUsage(usage),
|
||||||
i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage), std::make_pair(0, 1), 1)));
|
std::make_pair(0, 1), 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inputItems.insert(std::make_pair(caps.NotRange.DataIndex,
|
inputItems.emplace(buttonCaps.NotRange.DataIndex,
|
||||||
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage),
|
HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage),
|
||||||
HIDUsage(caps.NotRange.Usage), std::make_pair(0, 1), 1)));
|
HIDUsage(buttonCaps.NotRange.Usage), std::make_pair(0, 1), 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,19 +481,19 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
|
||||||
USHORT length = caps.NumberInputValueCaps;
|
USHORT length = caps.NumberInputValueCaps;
|
||||||
std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS());
|
std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS());
|
||||||
HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData);
|
HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData);
|
||||||
for (const HIDP_VALUE_CAPS& caps : vCaps) {
|
for (const HIDP_VALUE_CAPS& valueCaps : vCaps) {
|
||||||
if (caps.IsRange) {
|
if (valueCaps.IsRange) {
|
||||||
int usage = caps.Range.UsageMin;
|
int usage = valueCaps.Range.UsageMin;
|
||||||
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
|
for (int i = valueCaps.Range.DataIndexMin; i <= valueCaps.Range.DataIndexMax; ++i, ++usage) {
|
||||||
inputItems.insert(
|
inputItems.emplace(i, HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage), HIDUsage(usage),
|
||||||
std::make_pair(i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage),
|
std::make_pair(valueCaps.LogicalMin, valueCaps.LogicalMax),
|
||||||
std::make_pair(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
|
valueCaps.BitSize));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inputItems.insert(
|
inputItems.emplace(valueCaps.NotRange.DataIndex,
|
||||||
std::make_pair(caps.NotRange.DataIndex,
|
HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage),
|
||||||
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(caps.NotRange.Usage),
|
HIDUsage(valueCaps.NotRange.Usage),
|
||||||
HIDRange(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
|
HIDRange(valueCaps.LogicalMin, valueCaps.LogicalMax), valueCaps.BitSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,9 +822,9 @@ void HIDParser::ScanValues(const std::function<bool(const HIDMainItem& item, int
|
||||||
continue;
|
continue;
|
||||||
int32_t value = 0;
|
int32_t value = 0;
|
||||||
if (it != end) {
|
if (it != end) {
|
||||||
const HIDP_DATA& data = *it;
|
const HIDP_DATA& hidData = *it;
|
||||||
if (data.DataIndex == idx) {
|
if (hidData.DataIndex == idx) {
|
||||||
value = data.RawValue;
|
value = hidData.RawValue;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boo/inputdev/DeviceToken.hpp"
|
|
||||||
#include "boo/inputdev/DeviceBase.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "boo/inputdev/DeviceBase.hpp"
|
||||||
|
#include "boo/inputdev/DeviceToken.hpp"
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <hidsdi.h>
|
#include <hidsdi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../CFPointer.hpp"
|
#include "lib/CFPointer.hpp"
|
||||||
#include <IOKit/IOTypes.h>
|
#include <IOKit/IOTypes.h>
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
#include <IOKit/IOCFPlugIn.h>
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "boo/inputdev/NintendoPowerA.hpp"
|
#include "boo/inputdev/NintendoPowerA.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "boo/inputdev/DeviceSignature.hpp"
|
#include "boo/inputdev/DeviceSignature.hpp"
|
||||||
#include <memory.h>
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
NintendoPowerA::NintendoPowerA(DeviceToken* token)
|
NintendoPowerA::NintendoPowerA(DeviceToken* token)
|
||||||
: TDeviceBase<INintendoPowerACallback>(dev_typeid(NintendoPowerA), token) {}
|
: TDeviceBase<INintendoPowerACallback>(dev_typeid(NintendoPowerA), token) {}
|
||||||
|
@ -33,12 +36,10 @@ void NintendoPowerA::finalCycle() {}
|
||||||
|
|
||||||
void NintendoPowerA::receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {}
|
void NintendoPowerA::receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {}
|
||||||
|
|
||||||
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) {
|
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) const {
|
||||||
return !memcmp(this, &other, sizeof(NintendoPowerAState));
|
return memcmp(this, &other, sizeof(NintendoPowerAState)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) {
|
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) const { return !operator==(other); }
|
||||||
return memcmp(this, &other, sizeof(NintendoPowerAState));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#include <AppKit/AppKit.h>
|
#include <AppKit/AppKit.h>
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/Metal.hpp"
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
#include "CocoaCommon.hpp"
|
#include "lib/Common.hpp"
|
||||||
#include "../Common.hpp"
|
#include "lib/mac/CocoaCommon.hpp"
|
||||||
|
|
||||||
#include "logvisor/logvisor.hpp"
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
#error ARC Required
|
#error ARC Required
|
||||||
|
@ -110,7 +111,7 @@ public:
|
||||||
Log.report(logvisor::Info, fmt("using Metal renderer"));
|
Log.report(logvisor::Info, fmt("using Metal renderer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const {
|
EPlatformType getPlatformType() const override {
|
||||||
return EPlatformType::Cocoa;
|
return EPlatformType::Cocoa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ public:
|
||||||
int m_clientReturn = 0;
|
int m_clientReturn = 0;
|
||||||
bool m_terminateNow = false;
|
bool m_terminateNow = false;
|
||||||
|
|
||||||
int run() {
|
int run() override {
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
m_clientThread = std::thread([&]() {
|
m_clientThread = std::thread([&]() {
|
||||||
std::string thrName = std::string(getFriendlyName()) + " Client Thread";
|
std::string thrName = std::string(getFriendlyName()) + " Client Thread";
|
||||||
|
@ -161,23 +162,23 @@ public:
|
||||||
[NSApp terminate:nil];
|
[NSApp terminate:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemStringView getUniqueName() const {
|
SystemStringView getUniqueName() const override {
|
||||||
return m_uniqueName;
|
return m_uniqueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemStringView getFriendlyName() const {
|
SystemStringView getFriendlyName() const override {
|
||||||
return m_friendlyName;
|
return m_friendlyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemStringView getProcessName() const {
|
SystemStringView getProcessName() const override {
|
||||||
return m_pname;
|
return m_pname;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SystemString>& getArgs() const {
|
const std::vector<SystemString>& getArgs() const override {
|
||||||
return m_args;
|
return m_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IWindow> newWindow(std::string_view title) {
|
std::shared_ptr<IWindow> newWindow(std::string_view title) override {
|
||||||
auto newWindow = _WindowCocoaNew(title, &m_metalCtx);
|
auto newWindow = _WindowCocoaNew(title, &m_metalCtx);
|
||||||
m_windows[newWindow->getPlatformHandle()] = newWindow;
|
m_windows[newWindow->getPlatformHandle()] = newWindow;
|
||||||
return newWindow;
|
return newWindow;
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
|
|
||||||
#include <Metal/Metal.h>
|
#include <Metal/Metal.h>
|
||||||
#include <QuartzCore/CAMetalLayer.h>
|
#include <QuartzCore/CAMetalLayer.h>
|
||||||
#include <unordered_map>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
class IWindow;
|
class IWindow;
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
#include "boo/graphicsdev/Metal.hpp"
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
#include "CocoaCommon.hpp"
|
|
||||||
|
#include "boo/IApplication.hpp"
|
||||||
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
#include "lib/mac/CocoaCommon.hpp"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#import <CoreVideo/CVDisplayLink.h>
|
#import <CoreVideo/CVDisplayLink.h>
|
||||||
#include "boo/IApplication.hpp"
|
|
||||||
#include "boo/IWindow.hpp"
|
#include <logvisor/logvisor.hpp>
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
#error ARC Required
|
#error ARC Required
|
||||||
|
@ -93,7 +100,7 @@ static const NSOpenGLPixelFormatAttribute PF_RGBAF32_Z24_ATTRS[] =
|
||||||
|
|
||||||
static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
|
static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
|
||||||
{
|
{
|
||||||
NULL,
|
nullptr,
|
||||||
PF_RGBA8_ATTRS,
|
PF_RGBA8_ATTRS,
|
||||||
PF_RGBA16_ATTRS,
|
PF_RGBA16_ATTRS,
|
||||||
PF_RGBA8_Z24_ATTRS,
|
PF_RGBA8_Z24_ATTRS,
|
||||||
|
@ -139,7 +146,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~GraphicsContextCocoa() {
|
~GraphicsContextCocoa() override {
|
||||||
if (m_dispLink) {
|
if (m_dispLink) {
|
||||||
CVDisplayLinkStop(m_dispLink);
|
CVDisplayLinkStop(m_dispLink);
|
||||||
CVDisplayLinkRelease(m_dispLink);
|
CVDisplayLinkRelease(m_dispLink);
|
||||||
|
@ -223,36 +230,36 @@ public:
|
||||||
m_dataFactory = _NewGLDataFactory(this, glCtx);
|
m_dataFactory = _NewGLDataFactory(this, glCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextCocoaGL()
|
~GraphicsContextCocoaGL() override
|
||||||
{
|
{
|
||||||
m_commandQueue->stopRenderer();
|
m_commandQueue->stopRenderer();
|
||||||
fmt::print(fmt("CONTEXT DESTROYED\n"));
|
fmt::print(fmt("CONTEXT DESTROYED\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb)
|
void _setCallback(IWindowCallback* cb) override
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lk(m_callbackMutex);
|
std::lock_guard<std::recursive_mutex> lk(m_callbackMutex);
|
||||||
m_callback = cb;
|
m_callback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const
|
EGraphicsAPI getAPI() const override
|
||||||
{
|
{
|
||||||
return m_api;
|
return m_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const
|
EPixelFormat getPixelFormat() const override
|
||||||
{
|
{
|
||||||
return m_pf;
|
return m_pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf)
|
void setPixelFormat(EPixelFormat pf) override
|
||||||
{
|
{
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*)
|
bool initializeContext(void*) override
|
||||||
{
|
{
|
||||||
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
|
@ -266,26 +273,26 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent() override
|
||||||
{
|
{
|
||||||
[[m_nsContext openGLContext] makeCurrentContext];
|
[[m_nsContext openGLContext] makeCurrentContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit()
|
void postInit() override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue()
|
IGraphicsCommandQueue* getCommandQueue() override
|
||||||
{
|
{
|
||||||
return m_commandQueue.get();
|
return m_commandQueue.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory()
|
IGraphicsDataFactory* getDataFactory() override
|
||||||
{
|
{
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory()
|
IGraphicsDataFactory* getMainContextDataFactory() override
|
||||||
{
|
{
|
||||||
if (!m_mainCtx)
|
if (!m_mainCtx)
|
||||||
{
|
{
|
||||||
|
@ -298,7 +305,7 @@ public:
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
IGraphicsDataFactory* getLoadContextDataFactory() override
|
||||||
{
|
{
|
||||||
if (!m_loadCtx)
|
if (!m_loadCtx)
|
||||||
{
|
{
|
||||||
|
@ -311,12 +318,12 @@ public:
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void present()
|
void present() override
|
||||||
{
|
{
|
||||||
[[m_nsContext openGLContext] flushBuffer];
|
[[m_nsContext openGLContext] flushBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
BooCocoaResponder* responder() const
|
BooCocoaResponder* responder() const override
|
||||||
{
|
{
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -330,15 +337,15 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
GLContext* glCtx)
|
GLContext* glCtx)
|
||||||
{
|
{
|
||||||
if (api != IGraphicsContext::EGraphicsAPI::OpenGL3_3 && api != IGraphicsContext::EGraphicsAPI::OpenGL4_2)
|
if (api != IGraphicsContext::EGraphicsAPI::OpenGL3_3 && api != IGraphicsContext::EGraphicsAPI::OpenGL4_2)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
/* Create temporary context to query GL version */
|
/* Create temporary context to query GL version */
|
||||||
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_RGBA8_ATTRS];
|
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_RGBA8_ATTRS];
|
||||||
if (!nspf)
|
if (!nspf)
|
||||||
return NULL;
|
return nullptr;
|
||||||
NSOpenGLContext* nsctx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:nil];
|
NSOpenGLContext* nsctx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:nil];
|
||||||
if (!nsctx)
|
if (!nsctx)
|
||||||
return NULL;
|
return nullptr;
|
||||||
[nsctx makeCurrentContext];
|
[nsctx makeCurrentContext];
|
||||||
const char* glVersion = (char*)glGetString(GL_VERSION);
|
const char* glVersion = (char*)glGetString(GL_VERSION);
|
||||||
unsigned major = 0;
|
unsigned major = 0;
|
||||||
|
@ -352,13 +359,13 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
Log.report(logvisor::Fatal, fmt("glewInit failed"));
|
Log.report(logvisor::Fatal, fmt("glewInit failed"));
|
||||||
[NSOpenGLContext clearCurrentContext];
|
[NSOpenGLContext clearCurrentContext];
|
||||||
if (!glVersion)
|
if (!glVersion)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
if (major > 4 || (major == 4 && minor >= 2))
|
if (major > 4 || (major == 4 && minor >= 2))
|
||||||
api = IGraphicsContext::EGraphicsAPI::OpenGL4_2;
|
api = IGraphicsContext::EGraphicsAPI::OpenGL4_2;
|
||||||
else if (major == 3 && minor >= 3)
|
else if (major == 3 && minor >= 3)
|
||||||
if (api == IGraphicsContext::EGraphicsAPI::OpenGL4_2)
|
if (api == IGraphicsContext::EGraphicsAPI::OpenGL4_2)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
return new GraphicsContextCocoaGL(api, parentWindow, lastGLCtx, glCtx);
|
return new GraphicsContextCocoaGL(api, parentWindow, lastGLCtx, glCtx);
|
||||||
}
|
}
|
||||||
|
@ -384,31 +391,31 @@ public:
|
||||||
m_dataFactory = _NewMetalDataFactory(this, metalCtx);
|
m_dataFactory = _NewMetalDataFactory(this, metalCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextCocoaMetal() {
|
~GraphicsContextCocoaMetal() override {
|
||||||
m_commandQueue->stopRenderer();
|
m_commandQueue->stopRenderer();
|
||||||
m_metalCtx->m_windows.erase(m_parentWindow);
|
m_metalCtx->m_windows.erase(m_parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) {
|
void _setCallback(IWindowCallback* cb) override {
|
||||||
std::lock_guard<std::recursive_mutex> lk(m_callbackMutex);
|
std::lock_guard<std::recursive_mutex> lk(m_callbackMutex);
|
||||||
m_callback = cb;
|
m_callback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const {
|
EGraphicsAPI getAPI() const override {
|
||||||
return m_api;
|
return m_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const {
|
EPixelFormat getPixelFormat() const override {
|
||||||
return m_pf;
|
return m_pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) {
|
bool initializeContext(void*) override {
|
||||||
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
||||||
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
|
@ -423,32 +430,32 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {
|
void makeCurrent() override {
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit() {
|
void postInit() override {
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() {
|
IGraphicsCommandQueue* getCommandQueue() override {
|
||||||
return m_commandQueue.get();
|
return m_commandQueue.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() {
|
IGraphicsDataFactory* getDataFactory() override {
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() {
|
IGraphicsDataFactory* getMainContextDataFactory() override {
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() {
|
IGraphicsDataFactory* getLoadContextDataFactory() override {
|
||||||
return m_dataFactory.get();
|
return m_dataFactory.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void present() {
|
void present() override {
|
||||||
}
|
}
|
||||||
|
|
||||||
BooCocoaResponder* responder() const {
|
BooCocoaResponder* responder() const override {
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return m_nsContext->resp;
|
return m_nsContext->resp;
|
||||||
|
@ -1252,47 +1259,47 @@ public:
|
||||||
m_nsWindow = nullptr;
|
m_nsWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowCocoa() {
|
~WindowCocoa() override {
|
||||||
APP->_deletedWindow(this);
|
APP->_deletedWindow(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) {
|
void setCallback(IWindowCallback* cb) override {
|
||||||
m_gfxCtx->_setCallback(cb);
|
m_gfxCtx->_setCallback(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeWindow() {
|
void closeWindow() override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow close];
|
[m_nsWindow close];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void showWindow() {
|
void showWindow() override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow makeKeyAndOrderFront:nil];
|
[m_nsWindow makeKeyAndOrderFront:nil];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideWindow() {
|
void hideWindow() override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow orderOut:nil];
|
[m_nsWindow orderOut:nil];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getTitle() {
|
std::string getTitle() override {
|
||||||
return [[m_nsWindow title] UTF8String];
|
return [[m_nsWindow title] UTF8String];
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTitle(std::string_view title) {
|
void setTitle(std::string_view title) override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow setTitle:[NSString stringWithUTF8String:title.data()]];
|
[m_nsWindow setTitle:[NSString stringWithUTF8String:title.data()]];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {
|
void setCursor(EMouseCursor cursor) override {
|
||||||
if (cursor == m_cursor)
|
if (cursor == m_cursor)
|
||||||
return;
|
return;
|
||||||
m_cursor = cursor;
|
m_cursor = cursor;
|
||||||
|
@ -1320,14 +1327,14 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWaitCursor(bool wait) {}
|
void setWaitCursor(bool wait) override {}
|
||||||
|
|
||||||
double getWindowRefreshRate() const {
|
double getWindowRefreshRate() const override {
|
||||||
/* TODO: Actually get refresh rate */
|
/* TODO: Actually get refresh rate */
|
||||||
return 60.0;
|
return 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrameDefault() {
|
void setWindowFrameDefault() override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
NSScreen* mainScreen = [NSScreen mainScreen];
|
NSScreen* mainScreen = [NSScreen mainScreen];
|
||||||
|
@ -1338,7 +1345,7 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
|
||||||
NSView* view = [m_nsWindow contentView];
|
NSView* view = [m_nsWindow contentView];
|
||||||
NSRect wFrame = [view convertRectToBacking:view.frame];
|
NSRect wFrame = [view convertRectToBacking:view.frame];
|
||||||
xOut = wFrame.origin.x;
|
xOut = wFrame.origin.x;
|
||||||
|
@ -1347,7 +1354,7 @@ public:
|
||||||
hOut = wFrame.size.height;
|
hOut = wFrame.size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {
|
||||||
NSView* view = [m_nsWindow contentView];
|
NSView* view = [m_nsWindow contentView];
|
||||||
NSRect wFrame = [view convertRectToBacking:view.frame];
|
NSRect wFrame = [view convertRectToBacking:view.frame];
|
||||||
xOut = wFrame.origin.x;
|
xOut = wFrame.origin.x;
|
||||||
|
@ -1356,7 +1363,7 @@ public:
|
||||||
hOut = wFrame.size.height;
|
hOut = wFrame.size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(float x, float y, float w, float h) {
|
void setWindowFrame(float x, float y, float w, float h) override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow setContentSize:NSMakeSize(w, h)];
|
[m_nsWindow setContentSize:NSMakeSize(w, h)];
|
||||||
|
@ -1364,7 +1371,7 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(int x, int y, int w, int h) {
|
void setWindowFrame(int x, int y, int w, int h) override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow setContentSize:NSMakeSize(w, h)];
|
[m_nsWindow setContentSize:NSMakeSize(w, h)];
|
||||||
|
@ -1372,15 +1379,15 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
float getVirtualPixelFactor() const {
|
float getVirtualPixelFactor() const override {
|
||||||
return [m_nsWindow backingScaleFactor];
|
return [m_nsWindow backingScaleFactor];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFullscreen() const {
|
bool isFullscreen() const override {
|
||||||
return ([m_nsWindow styleMask] & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
|
return ([m_nsWindow styleMask] & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFullscreen(bool fs) {
|
void setFullscreen(bool fs) override {
|
||||||
if ((fs && !isFullscreen()) || (!fs && isFullscreen()))
|
if ((fs && !isFullscreen()) || (!fs && isFullscreen()))
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
|
@ -1388,7 +1395,7 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {
|
void claimKeyboardFocus(const int coord[2]) override {
|
||||||
BooCocoaResponder* resp = m_gfxCtx->responder();
|
BooCocoaResponder* resp = m_gfxCtx->responder();
|
||||||
if (resp) {
|
if (resp) {
|
||||||
dispatch_async(dispatch_get_main_queue(),
|
dispatch_async(dispatch_get_main_queue(),
|
||||||
|
@ -1401,7 +1408,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) {
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override {
|
||||||
NSPasteboard* pb = [NSPasteboard generalPasteboard];
|
NSPasteboard* pb = [NSPasteboard generalPasteboard];
|
||||||
[pb clearContents];
|
[pb clearContents];
|
||||||
NSData* d = [NSData dataWithBytes:data length:sz];
|
NSData* d = [NSData dataWithBytes:data length:sz];
|
||||||
|
@ -1409,7 +1416,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) {
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override {
|
||||||
NSPasteboard* pb = [NSPasteboard generalPasteboard];
|
NSPasteboard* pb = [NSPasteboard generalPasteboard];
|
||||||
NSData* d = [pb dataForType:ClipboardTypes[int(type)]];
|
NSData* d = [pb dataForType:ClipboardTypes[int(type)]];
|
||||||
if (!d)
|
if (!d)
|
||||||
|
@ -1420,11 +1427,11 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETouchType getTouchType() const {
|
ETouchType getTouchType() const override {
|
||||||
return ETouchType::Trackpad;
|
return ETouchType::Trackpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStyle(EWindowStyle style) {
|
void setStyle(EWindowStyle style) override {
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||||
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
|
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
|
||||||
m_nsWindow.titleVisibility = NSWindowTitleVisible;
|
m_nsWindow.titleVisibility = NSWindowTitleVisible;
|
||||||
|
@ -1443,7 +1450,7 @@ public:
|
||||||
m_nsWindow.styleMask &= ~NSWindowStyleMaskResizable;
|
m_nsWindow.styleMask &= ~NSWindowStyleMaskResizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
EWindowStyle getStyle() const {
|
EWindowStyle getStyle() const override {
|
||||||
EWindowStyle retval = EWindowStyle::None;
|
EWindowStyle retval = EWindowStyle::None;
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||||
retval |= m_nsWindow.titleVisibility == NSWindowTitleVisible ? EWindowStyle::Titlebar : EWindowStyle::None;
|
retval |= m_nsWindow.titleVisibility == NSWindowTitleVisible ? EWindowStyle::Titlebar : EWindowStyle::None;
|
||||||
|
@ -1455,34 +1462,34 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTouchBarProvider(void* provider) {
|
void setTouchBarProvider(void* provider) override {
|
||||||
dispatch_sync(dispatch_get_main_queue(),
|
dispatch_sync(dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[m_nsWindow setTouchBarProvider:(__bridge_transfer id) provider];
|
[m_nsWindow setTouchBarProvider:(__bridge_transfer id) provider];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitForRetrace() {
|
int waitForRetrace() override {
|
||||||
return static_cast<GraphicsContextCocoa*>(m_gfxCtx)->waitForRetrace();
|
return static_cast<GraphicsContextCocoa*>(m_gfxCtx)->waitForRetrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const {
|
uintptr_t getPlatformHandle() const override {
|
||||||
return (uintptr_t) m_nsWindow;
|
return (uintptr_t) m_nsWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() {
|
IGraphicsCommandQueue* getCommandQueue() override {
|
||||||
return m_gfxCtx->getCommandQueue();
|
return m_gfxCtx->getCommandQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() {
|
IGraphicsDataFactory* getDataFactory() override {
|
||||||
return m_gfxCtx->getDataFactory();
|
return m_gfxCtx->getDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() {
|
IGraphicsDataFactory* getMainContextDataFactory() override {
|
||||||
return m_gfxCtx->getMainContextDataFactory();
|
return m_gfxCtx->getMainContextDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() {
|
IGraphicsDataFactory* getLoadContextDataFactory() override {
|
||||||
return m_gfxCtx->getLoadContextDataFactory();
|
return m_gfxCtx->getLoadContextDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
#include "boo/IApplication.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "nxstl/thread"
|
#include "nxstl/thread"
|
||||||
#include "nxstl/condition_variable"
|
#include "nxstl/condition_variable"
|
||||||
|
#include "nxstl/mutex"
|
||||||
|
|
||||||
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/NX.hpp"
|
#include "boo/graphicsdev/NX.hpp"
|
||||||
#include <limits.h>
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
|
@ -21,7 +25,7 @@ class ApplicationNX : public IApplication {
|
||||||
|
|
||||||
NXContext m_nxCtx;
|
NXContext m_nxCtx;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window) {}
|
void _deletedWindow(IWindow* window) override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplicationNX(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
ApplicationNX(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
||||||
|
@ -29,9 +33,9 @@ public:
|
||||||
uint32_t anisotropy, bool deepColor, bool singleInstance)
|
uint32_t anisotropy, bool deepColor, bool singleInstance)
|
||||||
: m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) {}
|
: m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) {}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const { return EPlatformType::NX; }
|
EPlatformType getPlatformType() const override { return EPlatformType::NX; }
|
||||||
|
|
||||||
int run() {
|
int run() override {
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
int clientReturn = INT_MIN;
|
int clientReturn = INT_MIN;
|
||||||
std::mutex initmt;
|
std::mutex initmt;
|
||||||
|
@ -63,16 +67,16 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view getUniqueName() const { return m_uniqueName; }
|
std::string_view getUniqueName() const override { return m_uniqueName; }
|
||||||
|
|
||||||
std::string_view getFriendlyName() const { return m_friendlyName; }
|
std::string_view getFriendlyName() const override { return m_friendlyName; }
|
||||||
|
|
||||||
std::string_view getProcessName() const { return m_pname; }
|
std::string_view getProcessName() const override { return m_pname; }
|
||||||
|
|
||||||
const std::vector<std::string>& getArgs() const { return m_args; }
|
const std::vector<std::string>& getArgs() const override { return m_args; }
|
||||||
|
|
||||||
std::shared_ptr<IWindow> m_window;
|
std::shared_ptr<IWindow> m_window;
|
||||||
std::shared_ptr<IWindow> newWindow(std::string_view title) {
|
std::shared_ptr<IWindow> newWindow(std::string_view title) override {
|
||||||
if (m_window)
|
if (m_window)
|
||||||
Log.report(logvisor::Fatal, fmt("Only 1 window allowed on NX"));
|
Log.report(logvisor::Fatal, fmt("Only 1 window allowed on NX"));
|
||||||
m_window = _WindowNXNew(title, &m_nxCtx);
|
m_window = _WindowNXNew(title, &m_nxCtx);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/graphicsdev/NX.hpp"
|
#include "boo/graphicsdev/NX.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
@ -21,18 +22,18 @@ public:
|
||||||
m_commandQueue = _NewNXCommandQueue(nxCtx, this);
|
m_commandQueue = _NewNXCommandQueue(nxCtx, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return EGraphicsAPI::NX; }
|
EGraphicsAPI getAPI() const override { return EGraphicsAPI::NX; }
|
||||||
EPixelFormat getPixelFormat() const { return EPixelFormat::RGBA8; }
|
EPixelFormat getPixelFormat() const override { return EPixelFormat::RGBA8; }
|
||||||
void setPixelFormat(EPixelFormat pf) {}
|
void setPixelFormat(EPixelFormat pf) override {}
|
||||||
bool initializeContext(void* handle) { return m_nxCtx->initialize(); }
|
bool initializeContext(void* handle) override { return m_nxCtx->initialize(); }
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
void present() {}
|
void present() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_dataFactory.get(); }
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_dataFactory.get(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WindowNX : public IWindow {
|
class WindowNX : public IWindow {
|
||||||
|
@ -45,20 +46,20 @@ public:
|
||||||
m_gfxCtx->initializeContext(nullptr);
|
m_gfxCtx->initializeContext(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
void closeWindow() {}
|
void closeWindow() override {}
|
||||||
void showWindow() {}
|
void showWindow() override {}
|
||||||
void hideWindow() {}
|
void hideWindow() override {}
|
||||||
|
|
||||||
SystemString getTitle() { return m_title; }
|
SystemString getTitle() override { return m_title; }
|
||||||
void setTitle(SystemStringView title) { m_title = title; }
|
void setTitle(SystemStringView title) override { m_title = title; }
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {}
|
void setCursor(EMouseCursor cursor) override {}
|
||||||
void setWaitCursor(bool wait) {}
|
void setWaitCursor(bool wait) override {}
|
||||||
|
|
||||||
void setWindowFrameDefault() {}
|
void setWindowFrameDefault() override {}
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
|
||||||
u32 width, height;
|
u32 width, height;
|
||||||
gfxGetFramebufferResolution(&width, &height);
|
gfxGetFramebufferResolution(&width, &height);
|
||||||
xOut = 0;
|
xOut = 0;
|
||||||
|
@ -66,7 +67,7 @@ public:
|
||||||
wOut = width;
|
wOut = width;
|
||||||
hOut = height;
|
hOut = height;
|
||||||
}
|
}
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {
|
||||||
u32 width, height;
|
u32 width, height;
|
||||||
gfxGetFramebufferResolution(&width, &height);
|
gfxGetFramebufferResolution(&width, &height);
|
||||||
xOut = 0;
|
xOut = 0;
|
||||||
|
@ -74,37 +75,37 @@ public:
|
||||||
wOut = width;
|
wOut = width;
|
||||||
hOut = height;
|
hOut = height;
|
||||||
}
|
}
|
||||||
void setWindowFrame(float x, float y, float w, float h) {}
|
void setWindowFrame(float x, float y, float w, float h) override {}
|
||||||
void setWindowFrame(int x, int y, int w, int h) {}
|
void setWindowFrame(int x, int y, int w, int h) override {}
|
||||||
float getVirtualPixelFactor() const { return 1.f; }
|
float getVirtualPixelFactor() const override { return 1.f; }
|
||||||
|
|
||||||
bool isFullscreen() const { return true; }
|
bool isFullscreen() const override { return true; }
|
||||||
void setFullscreen(bool fs) {}
|
void setFullscreen(bool fs) override {}
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {}
|
void claimKeyboardFocus(const int coord[2]) override {}
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { return false; }
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override { return false; }
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) { return {}; }
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override { return {}; }
|
||||||
|
|
||||||
void waitForRetrace() {}
|
void waitForRetrace() override {}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const { return 0; }
|
uintptr_t getPlatformHandle() const override { return 0; }
|
||||||
bool _incomingEvent(void* event) {
|
bool _incomingEvent(void* event) override {
|
||||||
(void)event;
|
(void)event;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void _cleanup() {}
|
void _cleanup() override {}
|
||||||
|
|
||||||
ETouchType getTouchType() const { return ETouchType::Display; }
|
ETouchType getTouchType() const override { return ETouchType::Display; }
|
||||||
|
|
||||||
void setStyle(EWindowStyle style) {}
|
void setStyle(EWindowStyle style) override {}
|
||||||
EWindowStyle getStyle() const { return EWindowStyle::None; }
|
EWindowStyle getStyle() const override { return EWindowStyle::None; }
|
||||||
|
|
||||||
void setTouchBarProvider(void*) {}
|
void setTouchBarProvider(void*) override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx->getMainContextDataFactory(); }
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IWindow> _WindowNXNew(std::string_view title, NXContext* nxCtx) {
|
std::shared_ptr<IWindow> _WindowNXNew(std::string_view title, NXContext* nxCtx) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "UWPCommon.hpp"
|
#include "lib/win/UWPCommon.hpp"
|
||||||
|
|
||||||
using namespace Windows::Foundation;
|
using namespace Windows::Foundation;
|
||||||
using namespace Windows::UI::Core;
|
using namespace Windows::UI::Core;
|
||||||
|
@ -12,12 +12,15 @@ using namespace Platform;
|
||||||
#define D3D11_CREATE_DEVICE_FLAGS 0
|
#define D3D11_CREATE_DEVICE_FLAGS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boo/System.hpp"
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
#include "boo/System.hpp"
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/UWPViewProvider.hpp"
|
#include "boo/UWPViewProvider.hpp"
|
||||||
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
||||||
|
@ -49,7 +52,7 @@ class ApplicationUWP final : public IApplication {
|
||||||
|
|
||||||
Boo3DAppContextUWP m_3dCtx;
|
Boo3DAppContextUWP m_3dCtx;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window) {}
|
void _deletedWindow(IWindow* window) override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplicationUWP(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
ApplicationUWP(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||||
|
@ -60,7 +63,7 @@ public:
|
||||||
, m_pname(pname)
|
, m_pname(pname)
|
||||||
, m_args(args)
|
, m_args(args)
|
||||||
, m_singleInstance(singleInstance) {
|
, m_singleInstance(singleInstance) {
|
||||||
typedef HRESULT(WINAPI * CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
using CreateDXGIFactory1PROC = HRESULT (WINAPI *)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
||||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1;
|
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1;
|
||||||
|
|
||||||
bool no12 = true;
|
bool no12 = true;
|
||||||
|
@ -180,10 +183,10 @@ public:
|
||||||
Log.report(logvisor::Fatal, fmt("system doesn't support D3D11 or D3D12"));
|
Log.report(logvisor::Fatal, fmt("system doesn't support D3D11 or D3D12"));
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const { return EPlatformType::UWP; }
|
EPlatformType getPlatformType() const override { return EPlatformType::UWP; }
|
||||||
|
|
||||||
std::thread m_clientThread;
|
std::thread m_clientThread;
|
||||||
int run() {
|
int run() override {
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
int clientReturn = 0;
|
int clientReturn = 0;
|
||||||
m_clientThread = std::thread([&]() {
|
m_clientThread = std::thread([&]() {
|
||||||
|
@ -203,15 +206,15 @@ public:
|
||||||
m_clientThread.join();
|
m_clientThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemStringView getUniqueName() const { return m_uniqueName; }
|
SystemStringView getUniqueName() const override { return m_uniqueName; }
|
||||||
|
|
||||||
SystemStringView getFriendlyName() const { return m_friendlyName; }
|
SystemStringView getFriendlyName() const override { return m_friendlyName; }
|
||||||
|
|
||||||
SystemStringView getProcessName() const { return m_pname; }
|
SystemStringView getProcessName() const override { return m_pname; }
|
||||||
|
|
||||||
const std::vector<SystemString>& getArgs() const { return m_args; }
|
const std::vector<SystemString>& getArgs() const override { return m_args; }
|
||||||
|
|
||||||
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount) {
|
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount) override {
|
||||||
if (!m_issuedWindow) {
|
if (!m_issuedWindow) {
|
||||||
m_issuedWindow = true;
|
m_issuedWindow = true;
|
||||||
return m_window;
|
return m_window;
|
||||||
|
@ -222,7 +225,7 @@ public:
|
||||||
void _setWindow(CoreWindow ^ window) { m_window = _WindowUWPNew(m_friendlyName, m_3dCtx); }
|
void _setWindow(CoreWindow ^ window) { m_window = _WindowUWPNew(m_friendlyName, m_3dCtx); }
|
||||||
};
|
};
|
||||||
|
|
||||||
IApplication* APP = NULL;
|
IApplication* APP = nullptr;
|
||||||
ref class AppView sealed : public IFrameworkView {
|
ref class AppView sealed : public IFrameworkView {
|
||||||
ApplicationUWP m_app;
|
ApplicationUWP m_app;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "Win32Common.hpp"
|
#include "lib/win/Win32Common.hpp"
|
||||||
|
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include <Usbiodef.h>
|
#include <Usbiodef.h>
|
||||||
|
@ -15,11 +16,16 @@ PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor = nullptr;
|
||||||
#define D3D11_CREATE_DEVICE_FLAGS 0
|
#define D3D11_CREATE_DEVICE_FLAGS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boo/System.hpp"
|
#include <condition_variable>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
#include "boo/System.hpp"
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
|
@ -86,7 +92,7 @@ class ApplicationWin32 final : public IApplication {
|
||||||
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
|
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window) { m_allWindows.erase(HWND(window->getPlatformHandle())); }
|
void _deletedWindow(IWindow* window) override { m_allWindows.erase(HWND(window->getPlatformHandle())); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplicationWin32(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
ApplicationWin32(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||||
|
@ -110,8 +116,8 @@ public:
|
||||||
if (!dxgilib)
|
if (!dxgilib)
|
||||||
Log.report(logvisor::Fatal, fmt("unable to load dxgi.dll"));
|
Log.report(logvisor::Fatal, fmt("unable to load dxgi.dll"));
|
||||||
|
|
||||||
typedef HRESULT(WINAPI * CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
using CreateDXGIFactory1PROC = HRESULT(WINAPI*)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
||||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
|
auto MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
|
||||||
if (!MyCreateDXGIFactory1)
|
if (!MyCreateDXGIFactory1)
|
||||||
Log.report(logvisor::Fatal, fmt("unable to find CreateDXGIFactory1 in DXGI.dll\n"));
|
Log.report(logvisor::Fatal, fmt("unable to find CreateDXGIFactory1 in DXGI.dll\n"));
|
||||||
|
|
||||||
|
@ -272,7 +278,7 @@ public:
|
||||||
Log.report(logvisor::Fatal, fmt("system doesn't support Vulkan, D3D11, or OpenGL"));
|
Log.report(logvisor::Fatal, fmt("system doesn't support Vulkan, D3D11, or OpenGL"));
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const { return EPlatformType::Win32; }
|
EPlatformType getPlatformType() const override { return EPlatformType::Win32; }
|
||||||
|
|
||||||
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||||
/* Lookup boo window instance */
|
/* Lookup boo window instance */
|
||||||
|
@ -340,7 +346,7 @@ public:
|
||||||
MONITORINFO monitor_info;
|
MONITORINFO monitor_info;
|
||||||
monitor_info.cbSize = sizeof(monitor_info);
|
monitor_info.cbSize = sizeof(monitor_info);
|
||||||
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST), &monitor_info);
|
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST), &monitor_info);
|
||||||
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
|
SetWindowPos(win.m_hwnd, nullptr, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
|
||||||
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
||||||
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
||||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||||
|
@ -350,7 +356,7 @@ public:
|
||||||
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
|
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
|
||||||
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
|
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
|
||||||
|
|
||||||
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top, win.m_fsRect.right - win.m_fsRect.left,
|
SetWindowPos(win.m_hwnd, nullptr, win.m_fsRect.left, win.m_fsRect.top, win.m_fsRect.right - win.m_fsRect.left,
|
||||||
win.m_fsRect.bottom - win.m_fsRect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
win.m_fsRect.bottom - win.m_fsRect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||||
|
|
||||||
win.m_fs = false;
|
win.m_fs = false;
|
||||||
|
@ -358,7 +364,7 @@ public:
|
||||||
g_nwcv.notify_one();
|
g_nwcv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
int run() {
|
int run() override {
|
||||||
g_mainThreadId = GetCurrentThreadId();
|
g_mainThreadId = GetCurrentThreadId();
|
||||||
|
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
|
@ -372,8 +378,8 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Pump messages */
|
/* Pump messages */
|
||||||
MSG msg = {0};
|
MSG msg = {};
|
||||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
while (GetMessage(&msg, nullptr, 0, 0)) {
|
||||||
if (!msg.hwnd) {
|
if (!msg.hwnd) {
|
||||||
/* PostThreadMessage events */
|
/* PostThreadMessage events */
|
||||||
switch (msg.message) {
|
switch (msg.message) {
|
||||||
|
@ -424,22 +430,22 @@ public:
|
||||||
return clientReturn;
|
return clientReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ApplicationWin32() {
|
~ApplicationWin32() override {
|
||||||
for (auto& p : m_allWindows)
|
for (auto& p : m_allWindows)
|
||||||
if (auto w = p.second.lock())
|
if (auto w = p.second.lock())
|
||||||
w->_cleanup();
|
w->_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemStringView getUniqueName() const { return m_uniqueName; }
|
SystemStringView getUniqueName() const override { return m_uniqueName; }
|
||||||
|
|
||||||
SystemStringView getFriendlyName() const { return m_friendlyName; }
|
SystemStringView getFriendlyName() const override { return m_friendlyName; }
|
||||||
|
|
||||||
SystemStringView getProcessName() const { return m_pname; }
|
SystemStringView getProcessName() const override { return m_pname; }
|
||||||
|
|
||||||
const std::vector<SystemString>& getArgs() const { return m_args; }
|
const std::vector<SystemString>& getArgs() const override { return m_args; }
|
||||||
|
|
||||||
std::shared_ptr<IWindow> m_mwret;
|
std::shared_ptr<IWindow> m_mwret;
|
||||||
std::shared_ptr<IWindow> newWindow(SystemStringView title) {
|
std::shared_ptr<IWindow> newWindow(SystemStringView title) override {
|
||||||
if (GetCurrentThreadId() != g_mainThreadId) {
|
if (GetCurrentThreadId() != g_mainThreadId) {
|
||||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||||
if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0))
|
if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0))
|
||||||
|
@ -457,7 +463,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
IApplication* APP = NULL;
|
IApplication* APP = nullptr;
|
||||||
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName,
|
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName,
|
||||||
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args,
|
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args,
|
||||||
std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor,
|
std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor,
|
||||||
|
@ -484,7 +490,7 @@ int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& c
|
||||||
WIN32_CURSORS.m_wait = LoadCursor(nullptr, IDC_WAIT);
|
WIN32_CURSORS.m_wait = LoadCursor(nullptr, IDC_WAIT);
|
||||||
|
|
||||||
/* One class for *all* boo windows */
|
/* One class for *all* boo windows */
|
||||||
WNDCLASS wndClass = {0, WindowProc, 0, 0, GetModuleHandle(nullptr), 0, 0, 0, 0, L"BooWindow"};
|
WNDCLASS wndClass = {0, WindowProc, 0, 0, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"BooWindow"};
|
||||||
wndClass.hIcon = LoadIconW(wndClass.hInstance, MAKEINTRESOURCEW(101));
|
wndClass.hIcon = LoadIconW(wndClass.hInstance, MAKEINTRESOURCEW(101));
|
||||||
wndClass.hCursor = WIN32_CURSORS.m_arrow;
|
wndClass.hCursor = WIN32_CURSORS.m_arrow;
|
||||||
RegisterClassW(&wndClass);
|
RegisterClassW(&wndClass);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WinCommon.hpp"
|
#include "lib/win/WinCommon.hpp"
|
||||||
|
|
||||||
struct Boo3DAppContextUWP : Boo3DAppContext {
|
struct Boo3DAppContextUWP : Boo3DAppContext {
|
||||||
bool isFullscreen(const boo::IWindow* window) {
|
bool isFullscreen(const boo::IWindow* window) {
|
||||||
|
|
|
@ -14,19 +14,22 @@
|
||||||
#endif
|
#endif
|
||||||
#include "boo/graphicsdev/GL.hpp"
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
extern DWORD g_mainThreadId;
|
extern DWORD g_mainThreadId;
|
||||||
extern std::mutex g_nwmt;
|
extern std::mutex g_nwmt;
|
||||||
extern std::condition_variable g_nwcv;
|
extern std::condition_variable g_nwcv;
|
||||||
|
|
||||||
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
|
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
|
||||||
#include <ShellScalingApi.h>
|
#include <ShellScalingApi.h>
|
||||||
typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(_In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR*);
|
using PFN_GetScaleFactorForMonitor = HRESULT(WINAPI*)(_In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR*);
|
||||||
extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor;
|
extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct OGLContext {
|
struct OGLContext {
|
||||||
ComPtr<IDXGIFactory1> m_dxFactory;
|
ComPtr<IDXGIFactory1> m_dxFactory;
|
||||||
HGLRC m_lastContext = 0;
|
HGLRC m_lastContext = nullptr;
|
||||||
struct Window {
|
struct Window {
|
||||||
HWND m_hwnd;
|
HWND m_hwnd;
|
||||||
HDC m_deviceContext;
|
HDC m_deviceContext;
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
|
@ -25,8 +29,8 @@ class IWindow;
|
||||||
|
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
|
||||||
typedef int (WINAPI *pD3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName);
|
using pD3DPERF_BeginEvent = int (WINAPI*)(D3DCOLOR col, LPCWSTR wszName);
|
||||||
typedef int (WINAPI *pD3DPERF_EndEvent)();
|
using pD3DPERF_EndEvent = int (WINAPI*)();
|
||||||
|
|
||||||
struct D3D12Context {
|
struct D3D12Context {
|
||||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#include "UWPCommon.hpp"
|
#include "lib/win/UWPCommon.hpp"
|
||||||
#include "boo/IApplication.hpp"
|
|
||||||
#include "boo/IWindow.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
|
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
using namespace Windows::UI;
|
using namespace Windows::UI;
|
||||||
using namespace Windows::UI::Core;
|
using namespace Windows::UI::Core;
|
||||||
|
@ -117,7 +118,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextUWPD3D() {
|
~GraphicsContextUWPD3D() override {
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
if (m_3dCtx.m_ctx12.m_dev)
|
if (m_3dCtx.m_ctx12.m_dev)
|
||||||
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
||||||
|
@ -126,33 +127,33 @@ public:
|
||||||
m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) { return true; }
|
bool initializeContext(void*) override { return true; }
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
|
|
||||||
void present() {}
|
void present() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue; }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory; }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_dataFactory; }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_dataFactory; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_dataFactory; }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_dataFactory; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t translateKeysym(CoreWindow ^ window, VirtualKey sym, ESpecialKey& specialSym,
|
static uint32_t translateKeysym(CoreWindow ^ window, VirtualKey sym, ESpecialKey& specialSym,
|
||||||
|
@ -304,76 +305,78 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowUWP() {}
|
~WindowUWP() override = default;
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
void closeWindow() { m_coreWindow->Close(); }
|
void closeWindow() override { m_coreWindow->Close(); }
|
||||||
|
|
||||||
void showWindow() {}
|
void showWindow() override {}
|
||||||
|
|
||||||
void hideWindow() {}
|
void hideWindow() override {}
|
||||||
|
|
||||||
SystemString getTitle() { return SystemString(m_appView->Title->Data()); }
|
SystemString getTitle() override { return SystemString(m_appView->Title->Data()); }
|
||||||
|
|
||||||
void setTitle(SystemStringView title) { m_appView->Title = ref new Platform::String(title.data()); }
|
void setTitle(SystemStringView title) override { m_appView->Title = ref new Platform::String(title.data()); }
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {}
|
void setCursor(EMouseCursor cursor) override {}
|
||||||
|
|
||||||
void setWaitCursor(bool wait) {}
|
void setWaitCursor(bool wait) override {}
|
||||||
|
|
||||||
double getWindowRefreshRate() const {
|
double getWindowRefreshRate() const {
|
||||||
/* TODO: Actually get refresh rate */
|
/* TODO: Actually get refresh rate */
|
||||||
return 60.0;
|
return 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrameDefault() {}
|
void setWindowFrameDefault() override {}
|
||||||
|
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
|
||||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {
|
||||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(float x, float y, float w, float h) {}
|
void setWindowFrame(float x, float y, float w, float h) override {}
|
||||||
|
|
||||||
void setWindowFrame(int x, int y, int w, int h) {}
|
void setWindowFrame(int x, int y, int w, int h) override {}
|
||||||
|
|
||||||
float getVirtualPixelFactor() const { return m_dispInfoDpiFactor; }
|
float getVirtualPixelFactor() const override { return m_dispInfoDpiFactor; }
|
||||||
|
|
||||||
bool isFullscreen() const { return ApplicationView::GetForCurrentView()->IsFullScreenMode; }
|
bool isFullscreen() const override { return ApplicationView::GetForCurrentView()->IsFullScreenMode; }
|
||||||
|
|
||||||
void setFullscreen(bool fs) {
|
void setFullscreen(bool fs) override {
|
||||||
if (fs)
|
if (fs)
|
||||||
ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();
|
ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();
|
||||||
else
|
else
|
||||||
ApplicationView::GetForCurrentView()->ExitFullScreenMode();
|
ApplicationView::GetForCurrentView()->ExitFullScreenMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {}
|
void claimKeyboardFocus(const int coord[2]) override {}
|
||||||
|
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { return false; }
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override { return false; }
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) { return std::unique_ptr<uint8_t[]>(); }
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override {
|
||||||
|
return std::unique_ptr<uint8_t[]>();
|
||||||
|
}
|
||||||
|
|
||||||
int waitForRetrace(IAudioVoiceEngine* engine) {
|
int waitForRetrace(IAudioVoiceEngine* engine) override {
|
||||||
if (engine)
|
if (engine)
|
||||||
engine->pumpAndMixVoices();
|
engine->pumpAndMixVoices();
|
||||||
m_gfxCtx->m_output->WaitForVBlank();
|
m_gfxCtx->m_output->WaitForVBlank();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const { return 0; }
|
uintptr_t getPlatformHandle() const override { return 0; }
|
||||||
|
|
||||||
bool _incomingEvent(void* ev) { return false; }
|
bool _incomingEvent(void* ev) override { return false; }
|
||||||
|
|
||||||
void OnKeyDown(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) {
|
void OnKeyDown(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) {
|
||||||
ESpecialKey specialKey;
|
ESpecialKey specialKey;
|
||||||
|
@ -469,23 +472,23 @@ public:
|
||||||
m_callback->resized(rect, false);
|
m_callback->resized(rect, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ETouchType getTouchType() const { return ETouchType::None; }
|
ETouchType getTouchType() const override { return ETouchType::None; }
|
||||||
|
|
||||||
void setStyle(EWindowStyle style) {}
|
void setStyle(EWindowStyle style) override {}
|
||||||
|
|
||||||
EWindowStyle getStyle() const {
|
EWindowStyle getStyle() const override {
|
||||||
EWindowStyle retval = EWindowStyle::None;
|
EWindowStyle retval = EWindowStyle::None;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from main client thread */
|
/* Creates a new context on current thread!! Call from main client thread */
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx->getMainContextDataFactory(); }
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from client loading thread */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) {
|
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#include "Win32Common.hpp"
|
#include "lib/win/Win32Common.hpp"
|
||||||
#include <Windowsx.h>
|
|
||||||
#include "boo/IApplication.hpp"
|
|
||||||
#include "boo/IWindow.hpp"
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
|
|
||||||
|
#include <Windowsx.h>
|
||||||
|
|
||||||
|
#include "boo/IApplication.hpp"
|
||||||
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
|
|
||||||
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
#include "boo/graphicsdev/GL.hpp"
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
#include "boo/graphicsdev/glew.h"
|
#include "boo/graphicsdev/glew.h"
|
||||||
#include "boo/graphicsdev/wglew.h"
|
#include "boo/graphicsdev/wglew.h"
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
|
@ -19,6 +20,8 @@
|
||||||
#include <dxgi1_5.h>
|
#include <dxgi1_5.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
static const int ContextAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
static const int ContextAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
// WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
// WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||||
|
@ -88,35 +91,35 @@ public:
|
||||||
Log.report(logvisor::Fatal, fmt("unable to get DXGI output"));
|
Log.report(logvisor::Fatal, fmt("unable to get DXGI output"));
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextWin32D3D() { m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow); }
|
~GraphicsContextWin32D3D() override { m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow); }
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) { return true; }
|
bool initializeContext(void*) override { return true; }
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
|
|
||||||
void present() {}
|
void present() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_dataFactory.get(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GraphicsContextWin32GL : GraphicsContextWin32 {
|
struct GraphicsContextWin32GL : GraphicsContextWin32 {
|
||||||
|
@ -198,7 +201,7 @@ public:
|
||||||
Log.report(logvisor::Fatal, fmt("glewInit failed"));
|
Log.report(logvisor::Fatal, fmt("glewInit failed"));
|
||||||
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||||
wglMakeCurrent(w.m_deviceContext, 0);
|
wglMakeCurrent(w.m_deviceContext, nullptr);
|
||||||
wglDeleteContext(tmpCtx);
|
wglDeleteContext(tmpCtx);
|
||||||
|
|
||||||
if (b3dCtx.m_ctxOgl.m_glCtx.m_deepColor) {
|
if (b3dCtx.m_ctxOgl.m_glCtx.m_deepColor) {
|
||||||
|
@ -249,23 +252,23 @@ public:
|
||||||
m_commandQueue->startRenderer();
|
m_commandQueue->startRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextWin32GL() { m_3dCtx.m_ctxOgl.m_windows.erase(m_parentWindow); }
|
~GraphicsContextWin32GL() override { m_3dCtx.m_ctxOgl.m_windows.erase(m_parentWindow); }
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) { return true; }
|
bool initializeContext(void*) override { return true; }
|
||||||
|
|
||||||
void makeCurrent() {
|
void makeCurrent() override {
|
||||||
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
// if (!wglMakeCurrent(w.m_deviceContext, w.m_mainContext))
|
// if (!wglMakeCurrent(w.m_deviceContext, w.m_mainContext))
|
||||||
// Log.report(logvisor::Fatal, fmt("unable to make WGL context current"));
|
// Log.report(logvisor::Fatal, fmt("unable to make WGL context current"));
|
||||||
|
@ -277,7 +280,7 @@ public:
|
||||||
Log.report(logvisor::Fatal, fmt("unable to make WGL context current"));
|
Log.report(logvisor::Fatal, fmt("unable to make WGL context current"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit() {
|
void postInit() override {
|
||||||
// OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
// OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
|
|
||||||
// wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
// wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||||
|
@ -293,18 +296,18 @@ public:
|
||||||
wglSwapIntervalEXT(1);
|
wglSwapIntervalEXT(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void present() {
|
void present() override {
|
||||||
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
SwapBuffers(w.m_deviceContext);
|
SwapBuffers(w.m_deviceContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from client loading thread */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
HGLRC m_mainCtx = 0;
|
HGLRC m_mainCtx = nullptr;
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() {
|
IGraphicsDataFactory* getMainContextDataFactory() override {
|
||||||
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
if (!m_mainCtx) {
|
if (!m_mainCtx) {
|
||||||
m_mainCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
m_mainCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
||||||
|
@ -317,8 +320,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from client loading thread */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
HGLRC m_loadCtx = 0;
|
HGLRC m_loadCtx = nullptr;
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() {
|
IGraphicsDataFactory* getLoadContextDataFactory() override {
|
||||||
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
if (!m_loadCtx) {
|
if (!m_loadCtx) {
|
||||||
m_loadCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
m_loadCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
||||||
|
@ -347,8 +350,11 @@ struct GraphicsContextWin32Vulkan : GraphicsContextWin32 {
|
||||||
bool m_vsyncRunning;
|
bool m_vsyncRunning;
|
||||||
|
|
||||||
static void ThrowIfFailed(VkResult res) {
|
static void ThrowIfFailed(VkResult res) {
|
||||||
if (res != VK_SUCCESS)
|
if (res == VK_SUCCESS) {
|
||||||
Log.report(logvisor::Fatal, fmt("%d\n"), res);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.report(logvisor::Fatal, fmt("{}\n"), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -400,7 +406,7 @@ public:
|
||||||
m_ctx->m_windows.erase(m_parentWindow);
|
m_ctx->m_windows.erase(m_parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextWin32Vulkan() { destroy(); }
|
~GraphicsContextWin32Vulkan() override { destroy(); }
|
||||||
|
|
||||||
VulkanContext::Window* m_windowCtx = nullptr;
|
VulkanContext::Window* m_windowCtx = nullptr;
|
||||||
|
|
||||||
|
@ -409,19 +415,19 @@ public:
|
||||||
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace, rect);
|
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) {
|
bool initializeContext(void*) override {
|
||||||
m_windowCtx = m_ctx->m_windows.emplace(std::make_pair(m_parentWindow, std::make_unique<VulkanContext::Window>()))
|
m_windowCtx = m_ctx->m_windows.emplace(std::make_pair(m_parentWindow, std::make_unique<VulkanContext::Window>()))
|
||||||
.first->second.get();
|
.first->second.get();
|
||||||
m_windowCtx->m_hwnd = m_hwnd;
|
m_windowCtx->m_hwnd = m_hwnd;
|
||||||
|
@ -509,19 +515,19 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return getDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return getDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return getDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return getDataFactory(); }
|
||||||
|
|
||||||
void present() {}
|
void present() override {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -852,7 +858,7 @@ public:
|
||||||
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
|
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
|
||||||
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW, r.left, r.top, r.right - r.left,
|
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW, r.left, r.top, r.right - r.left,
|
||||||
r.bottom - r.top, NULL, NULL, NULL, NULL);
|
r.bottom - r.top, nullptr, nullptr, nullptr, nullptr);
|
||||||
HINSTANCE wndInstance = HINSTANCE(GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE));
|
HINSTANCE wndInstance = HINSTANCE(GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE));
|
||||||
m_imc = ImmGetContext(m_hwnd);
|
m_imc = ImmGetContext(m_hwnd);
|
||||||
|
|
||||||
|
@ -874,37 +880,37 @@ public:
|
||||||
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
|
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cleanup() { m_gfxCtx.reset(); }
|
void _cleanup() override { m_gfxCtx.reset(); }
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
void closeWindow() {
|
void closeWindow() override {
|
||||||
// TODO: Perform thread-coalesced deallocation
|
// TODO: Perform thread-coalesced deallocation
|
||||||
ShowWindow(m_hwnd, SW_HIDE);
|
ShowWindow(m_hwnd, SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showWindow() { ShowWindow(m_hwnd, SW_SHOW); }
|
void showWindow() override { ShowWindow(m_hwnd, SW_SHOW); }
|
||||||
|
|
||||||
void hideWindow() { ShowWindow(m_hwnd, SW_HIDE); }
|
void hideWindow() override { ShowWindow(m_hwnd, SW_HIDE); }
|
||||||
|
|
||||||
SystemString getTitle() {
|
SystemString getTitle() override {
|
||||||
wchar_t title[256];
|
wchar_t title[256];
|
||||||
int c = GetWindowTextW(m_hwnd, title, 256);
|
int c = GetWindowTextW(m_hwnd, title, 256);
|
||||||
return SystemString(title, c);
|
return SystemString(title, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTitle(SystemStringView title) { SetWindowTextW(m_hwnd, title.data()); }
|
void setTitle(SystemStringView title) override { SetWindowTextW(m_hwnd, title.data()); }
|
||||||
|
|
||||||
static void _setCursor(HCURSOR cur) { PostThreadMessageW(g_mainThreadId, WM_USER + 2, WPARAM(cur), 0); }
|
static void _setCursor(HCURSOR cur) { PostThreadMessageW(g_mainThreadId, WM_USER + 2, WPARAM(cur), 0); }
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {
|
void setCursor(EMouseCursor cursor) override {
|
||||||
if (cursor == m_cursor && !m_cursorWait)
|
if (cursor == m_cursor && !m_cursorWait)
|
||||||
return;
|
return;
|
||||||
m_cursor = cursor;
|
m_cursor = cursor;
|
||||||
_setCursor(GetWin32Cursor(cursor));
|
_setCursor(GetWin32Cursor(cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWaitCursor(bool wait) {
|
void setWaitCursor(bool wait) override {
|
||||||
if (wait && !m_cursorWait) {
|
if (wait && !m_cursorWait) {
|
||||||
_setCursor(WIN32_CURSORS.m_wait);
|
_setCursor(WIN32_CURSORS.m_wait);
|
||||||
m_cursorWait = true;
|
m_cursorWait = true;
|
||||||
|
@ -914,12 +920,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double getWindowRefreshRate() const {
|
double getWindowRefreshRate() const override {
|
||||||
/* TODO: Actually get refresh rate */
|
/* TODO: Actually get refresh rate */
|
||||||
return 60.0;
|
return 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrameDefault() {
|
void setWindowFrameDefault() override {
|
||||||
MONITORINFO monInfo = {};
|
MONITORINFO monInfo = {};
|
||||||
monInfo.cbSize = sizeof(MONITORINFO);
|
monInfo.cbSize = sizeof(MONITORINFO);
|
||||||
HMONITOR mon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY);
|
HMONITOR mon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
@ -929,7 +935,7 @@ public:
|
||||||
setWindowFrame(x, y, w, h);
|
setWindowFrame(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
|
||||||
RECT rct;
|
RECT rct;
|
||||||
GetClientRect(m_hwnd, &rct);
|
GetClientRect(m_hwnd, &rct);
|
||||||
POINT pt;
|
POINT pt;
|
||||||
|
@ -942,7 +948,7 @@ public:
|
||||||
hOut = rct.bottom;
|
hOut = rct.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {
|
||||||
RECT rct;
|
RECT rct;
|
||||||
GetClientRect(m_hwnd, &rct);
|
GetClientRect(m_hwnd, &rct);
|
||||||
POINT pt;
|
POINT pt;
|
||||||
|
@ -955,15 +961,15 @@ public:
|
||||||
hOut = rct.bottom;
|
hOut = rct.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(float x, float y, float w, float h) { setWindowFrame(int(x), int(y), int(w), int(h)); }
|
void setWindowFrame(float x, float y, float w, float h) override { setWindowFrame(int(x), int(y), int(w), int(h)); }
|
||||||
|
|
||||||
void setWindowFrame(int x, int y, int w, int h) {
|
void setWindowFrame(int x, int y, int w, int h) override {
|
||||||
RECT r = {x, y, x + w, y + h};
|
RECT r = {x, y, x + w, y + h};
|
||||||
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
|
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
MoveWindow(m_hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, true);
|
MoveWindow(m_hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getVirtualPixelFactor() const {
|
float getVirtualPixelFactor() const override {
|
||||||
#if _WIN32_WINNT_WINBLUE
|
#if _WIN32_WINNT_WINBLUE
|
||||||
if (MyGetScaleFactorForMonitor) {
|
if (MyGetScaleFactorForMonitor) {
|
||||||
DEVICE_SCALE_FACTOR Factor;
|
DEVICE_SCALE_FACTOR Factor;
|
||||||
|
@ -977,9 +983,9 @@ public:
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFullscreen() const { return m_gfxCtx->m_3dCtx.isFullscreen(this); }
|
bool isFullscreen() const override { return m_gfxCtx->m_3dCtx.isFullscreen(this); }
|
||||||
|
|
||||||
void setFullscreen(bool fs) { m_gfxCtx->m_3dCtx.setFullscreen(this, fs); }
|
void setFullscreen(bool fs) override { m_gfxCtx->m_3dCtx.setFullscreen(this, fs); }
|
||||||
|
|
||||||
void _immSetOpenStatus(bool open) {
|
void _immSetOpenStatus(bool open) {
|
||||||
if (GetCurrentThreadId() != g_mainThreadId) {
|
if (GetCurrentThreadId() != g_mainThreadId) {
|
||||||
|
@ -1005,7 +1011,7 @@ public:
|
||||||
ImmSetCompositionWindow(m_imc, &m_cForm);
|
ImmSetCompositionWindow(m_imc, &m_cForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {
|
void claimKeyboardFocus(const int coord[2]) override {
|
||||||
if (!coord) {
|
if (!coord) {
|
||||||
//_immSetOpenStatus(false);
|
//_immSetOpenStatus(false);
|
||||||
return;
|
return;
|
||||||
|
@ -1014,7 +1020,7 @@ public:
|
||||||
//_immSetOpenStatus(true);
|
//_immSetOpenStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) {
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case EClipboardType::String: {
|
case EClipboardType::String: {
|
||||||
HGLOBAL gStr = MakeANSICRLF(reinterpret_cast<const char*>(data), sz);
|
HGLOBAL gStr = MakeANSICRLF(reinterpret_cast<const char*>(data), sz);
|
||||||
|
@ -1038,7 +1044,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) {
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case EClipboardType::String: {
|
case EClipboardType::String: {
|
||||||
OpenClipboard(m_hwnd);
|
OpenClipboard(m_hwnd);
|
||||||
|
@ -1068,9 +1074,12 @@ public:
|
||||||
return std::unique_ptr<uint8_t[]>();
|
return std::unique_ptr<uint8_t[]>();
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitForRetrace() { m_gfxCtx->m_output->WaitForVBlank(); return 1; }
|
int waitForRetrace() override {
|
||||||
|
m_gfxCtx->m_output->WaitForVBlank();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const { return uintptr_t(m_hwnd); }
|
uintptr_t getPlatformHandle() const override { return uintptr_t(m_hwnd); }
|
||||||
|
|
||||||
void buttonDown(HWNDEvent& e, EMouseButton button) {
|
void buttonDown(HWNDEvent& e, EMouseButton button) {
|
||||||
if (m_callback) {
|
if (m_callback) {
|
||||||
|
@ -1105,7 +1114,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mouseTracking = false;
|
bool mouseTracking = false;
|
||||||
bool _incomingEvent(void* ev) {
|
bool _incomingEvent(void* ev) override {
|
||||||
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
|
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
|
||||||
switch (e.uMsg) {
|
switch (e.uMsg) {
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
@ -1288,9 +1297,9 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETouchType getTouchType() const { return ETouchType::None; }
|
ETouchType getTouchType() const override { return ETouchType::None; }
|
||||||
|
|
||||||
void setStyle(EWindowStyle style) {
|
void setStyle(EWindowStyle style) override {
|
||||||
LONG sty = GetWindowLong(m_hwnd, GWL_STYLE);
|
LONG sty = GetWindowLong(m_hwnd, GWL_STYLE);
|
||||||
|
|
||||||
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
|
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
|
||||||
|
@ -1311,7 +1320,7 @@ public:
|
||||||
SetWindowLong(m_hwnd, GWL_STYLE, sty);
|
SetWindowLong(m_hwnd, GWL_STYLE, sty);
|
||||||
}
|
}
|
||||||
|
|
||||||
EWindowStyle getStyle() const {
|
EWindowStyle getStyle() const override {
|
||||||
LONG sty = GetWindowLong(m_hwnd, GWL_STYLE);
|
LONG sty = GetWindowLong(m_hwnd, GWL_STYLE);
|
||||||
EWindowStyle retval = EWindowStyle::None;
|
EWindowStyle retval = EWindowStyle::None;
|
||||||
if ((sty & WS_CAPTION) != 0)
|
if ((sty & WS_CAPTION) != 0)
|
||||||
|
@ -1323,14 +1332,14 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from main client thread */
|
/* Creates a new context on current thread!! Call from main client thread */
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx->getMainContextDataFactory(); }
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from client loading thread */
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx) {
|
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx) {
|
||||||
|
|
|
@ -4,12 +4,15 @@
|
||||||
|
|
||||||
#define APPLICATION_UNIX_CPP
|
#define APPLICATION_UNIX_CPP
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unistd.h>
|
#include <cstdlib>
|
||||||
#include "logvisor/logvisor.hpp"
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
|
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace boo {
|
namespace boo {
|
||||||
static logvisor::Module Log("boo::ApplicationUnix");
|
static logvisor::Module Log("boo::ApplicationUnix");
|
||||||
IApplication* APP = nullptr;
|
IApplication* APP = nullptr;
|
||||||
|
@ -99,8 +102,8 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst) {
|
||||||
fmt::print(stderr, fmt("DBus Connection Error ({})\n"), err.message);
|
fmt::print(stderr, fmt("DBus Connection Error ({})\n"), err.message);
|
||||||
dbus_error_free(&err);
|
dbus_error_free(&err);
|
||||||
}
|
}
|
||||||
if (NULL == conn)
|
if (conn == nullptr)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
/* request our name on the bus and check for errors */
|
/* request our name on the bus and check for errors */
|
||||||
int ret = dbus_bus_request_name(conn, fmt::format(fmt("boo.{}.unique"), appName).c_str(),
|
int ret = dbus_bus_request_name(conn, fmt::format(fmt("boo.{}.unique"), appName).c_str(),
|
||||||
|
@ -109,7 +112,7 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst) {
|
||||||
fmt::print(stderr, fmt("DBus Name Error ({})\n"), err.message);
|
fmt::print(stderr, fmt("DBus Name Error ({})\n"), err.message);
|
||||||
dbus_error_free(&err);
|
dbus_error_free(&err);
|
||||||
dbus_connection_close(conn);
|
dbus_connection_close(conn);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret)
|
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret)
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
|
|
|
@ -19,7 +19,7 @@ class ApplicationWayland final : public IApplication {
|
||||||
const std::vector<std::string> m_args;
|
const std::vector<std::string> m_args;
|
||||||
bool m_singleInstance;
|
bool m_singleInstance;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window) { (void)window; }
|
void _deletedWindow(IWindow* window) override { (void)window; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplicationWayland(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
ApplicationWayland(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
||||||
|
@ -35,19 +35,19 @@ public:
|
||||||
(void)m_singleInstance;
|
(void)m_singleInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const { return EPlatformType::Wayland; }
|
EPlatformType getPlatformType() const override { return EPlatformType::Wayland; }
|
||||||
|
|
||||||
int run() { return 0; }
|
int run() override { return 0; }
|
||||||
|
|
||||||
std::string_view getUniqueName() const { return m_uniqueName; }
|
std::string_view getUniqueName() const override { return m_uniqueName; }
|
||||||
|
|
||||||
std::string_view getFriendlyName() const { return m_friendlyName; }
|
std::string_view getFriendlyName() const override { return m_friendlyName; }
|
||||||
|
|
||||||
std::string_view getProcessName() const { return m_pname; }
|
std::string_view getProcessName() const override { return m_pname; }
|
||||||
|
|
||||||
const std::vector<std::string>& getArgs() const { return m_args; }
|
const std::vector<std::string>& getArgs() const override { return m_args; }
|
||||||
|
|
||||||
std::shared_ptr<IWindow> newWindow(std::string_view title) { return _WindowWaylandNew(title); }
|
std::shared_ptr<IWindow> newWindow(std::string_view title) override { return _WindowWaylandNew(title); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boo
|
} // namespace boo
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/GL.hpp"
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
#include "../Common.hpp"
|
#include "lib/Common.hpp"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
@ -12,16 +12,17 @@
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#include <GL/glxext.h>
|
#include <GL/glxext.h>
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
|
DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
|
||||||
|
|
||||||
#include <signal.h>
|
#include <clocale>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <csignal>
|
||||||
|
#include <locale>
|
||||||
|
#include <mutex>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#include "XlibCommon.hpp"
|
#include "XlibCommon.hpp"
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
@ -196,7 +197,7 @@ class ApplicationXlib final : public IApplication {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window) { m_windows.erase((Window)window->getPlatformHandle()); }
|
void _deletedWindow(IWindow* window) override { m_windows.erase((Window)window->getPlatformHandle()); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplicationXlib(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
ApplicationXlib(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
|
||||||
|
@ -368,7 +369,7 @@ public:
|
||||||
XFlush(m_xDisp);
|
XFlush(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ApplicationXlib() {
|
~ApplicationXlib() override {
|
||||||
for (auto& p : m_windows)
|
for (auto& p : m_windows)
|
||||||
if (auto w = p.second.lock())
|
if (auto w = p.second.lock())
|
||||||
w->_cleanup();
|
w->_cleanup();
|
||||||
|
@ -385,7 +386,7 @@ public:
|
||||||
XCloseDisplay(m_xDisp);
|
XCloseDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const { return EPlatformType::Xlib; }
|
EPlatformType getPlatformType() const override { return EPlatformType::Xlib; }
|
||||||
|
|
||||||
/* Empty handler for SIGINT */
|
/* Empty handler for SIGINT */
|
||||||
static void _sigint(int) {}
|
static void _sigint(int) {}
|
||||||
|
@ -414,7 +415,7 @@ public:
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run() {
|
int run() override {
|
||||||
if (!m_xDisp)
|
if (!m_xDisp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -459,7 +460,7 @@ public:
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(m_x11Fd, &fds);
|
FD_SET(m_x11Fd, &fds);
|
||||||
FD_SET(m_dbusFd, &fds);
|
FD_SET(m_dbusFd, &fds);
|
||||||
if (pselect(m_maxFd + 1, &fds, NULL, NULL, NULL, &origmask) < 0) {
|
if (pselect(m_maxFd + 1, &fds, nullptr, nullptr, nullptr, &origmask) < 0) {
|
||||||
/* SIGINT/SIGUSR2 handled here */
|
/* SIGINT/SIGUSR2 handled here */
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
break;
|
break;
|
||||||
|
@ -512,15 +513,15 @@ public:
|
||||||
return clientReturn;
|
return clientReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view getUniqueName() const { return m_uniqueName; }
|
std::string_view getUniqueName() const override { return m_uniqueName; }
|
||||||
|
|
||||||
std::string_view getFriendlyName() const { return m_friendlyName; }
|
std::string_view getFriendlyName() const override { return m_friendlyName; }
|
||||||
|
|
||||||
std::string_view getProcessName() const { return m_pname; }
|
std::string_view getProcessName() const override { return m_pname; }
|
||||||
|
|
||||||
const std::vector<std::string>& getArgs() const { return m_args; }
|
const std::vector<std::string>& getArgs() const override { return m_args; }
|
||||||
|
|
||||||
std::shared_ptr<IWindow> newWindow(std::string_view title) {
|
std::shared_ptr<IWindow> newWindow(std::string_view title) override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
std::shared_ptr<IWindow> newWindow = _WindowXlibNew(title, m_xDisp, m_xcbConn, m_xDefaultScreen, m_xIM, m_bestStyle,
|
std::shared_ptr<IWindow> newWindow = _WindowXlibNew(title, m_xDisp, m_xcbConn, m_xDefaultScreen, m_xIM, m_bestStyle,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
|
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
|
||||||
|
@ -19,35 +20,35 @@ public:
|
||||||
GraphicsContextWayland(EGraphicsAPI api, IWindow* parentWindow)
|
GraphicsContextWayland(EGraphicsAPI api, IWindow* parentWindow)
|
||||||
: m_api(api), m_pf(EPixelFormat::RGBA8), m_parentWindow(parentWindow) {}
|
: m_api(api), m_pf(EPixelFormat::RGBA8), m_parentWindow(parentWindow) {}
|
||||||
|
|
||||||
~GraphicsContextWayland() {}
|
~GraphicsContextWayland() override = default;
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) { return false; }
|
bool initializeContext(void*) override { return false; }
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return nullptr; }
|
IGraphicsCommandQueue* getCommandQueue() override { return nullptr; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return nullptr; }
|
IGraphicsDataFactory* getDataFactory() override { return nullptr; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return nullptr; }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return nullptr; }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return nullptr; }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return nullptr; }
|
||||||
|
|
||||||
void present() {}
|
void present() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WindowWayland : IWindow {
|
struct WindowWayland : IWindow {
|
||||||
|
@ -55,65 +56,65 @@ struct WindowWayland : IWindow {
|
||||||
|
|
||||||
WindowWayland(std::string_view title) : m_gfxCtx(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this) {}
|
WindowWayland(std::string_view title) : m_gfxCtx(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this) {}
|
||||||
|
|
||||||
~WindowWayland() {}
|
~WindowWayland() override = default;
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) {}
|
void setCallback(IWindowCallback* cb) override {}
|
||||||
|
|
||||||
void closeWindow() {}
|
void closeWindow() override {}
|
||||||
|
|
||||||
void showWindow() {}
|
void showWindow() override {}
|
||||||
|
|
||||||
void hideWindow() {}
|
void hideWindow() override {}
|
||||||
|
|
||||||
std::string getTitle() { return ""; }
|
std::string getTitle() override { return ""; }
|
||||||
|
|
||||||
void setTitle(std::string_view title) {}
|
void setTitle(std::string_view title) override {}
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {}
|
void setCursor(EMouseCursor cursor) override {}
|
||||||
|
|
||||||
void setWaitCursor(bool wait) {}
|
void setWaitCursor(bool wait) override {}
|
||||||
|
|
||||||
double getWindowRefreshRate() const { return 60.0; }
|
double getWindowRefreshRate() const override { return 60.0; }
|
||||||
|
|
||||||
void setWindowFrameDefault() {}
|
void setWindowFrameDefault() override {}
|
||||||
|
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {}
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {}
|
||||||
|
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {}
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {}
|
||||||
|
|
||||||
void setWindowFrame(float x, float y, float w, float h) {}
|
void setWindowFrame(float x, float y, float w, float h) override {}
|
||||||
|
|
||||||
void setWindowFrame(int x, int y, int w, int h) {}
|
void setWindowFrame(int x, int y, int w, int h) override {}
|
||||||
|
|
||||||
float getVirtualPixelFactor() const { return 0; }
|
float getVirtualPixelFactor() const override { return 0; }
|
||||||
|
|
||||||
void setStyle(EWindowStyle /*style*/) {}
|
void setStyle(EWindowStyle /*style*/) override {}
|
||||||
|
|
||||||
EWindowStyle getStyle() const { return EWindowStyle::None; }
|
EWindowStyle getStyle() const override { return EWindowStyle::None; }
|
||||||
|
|
||||||
bool isFullscreen() const { return false; }
|
bool isFullscreen() const override { return false; }
|
||||||
|
|
||||||
void setFullscreen(bool fs) {}
|
void setFullscreen(bool fs) override {}
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {}
|
void claimKeyboardFocus(const int coord[2]) override {}
|
||||||
|
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { return false; }
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override { return false; }
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) { return std::unique_ptr<uint8_t[]>(); }
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override { return std::unique_ptr<uint8_t[]>(); }
|
||||||
|
|
||||||
int waitForRetrace() { return 1; }
|
int waitForRetrace() override { return 1; }
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const { return 0; }
|
uintptr_t getPlatformHandle() const override { return 0; }
|
||||||
|
|
||||||
ETouchType getTouchType() const { return ETouchType::None; }
|
ETouchType getTouchType() const override { return ETouchType::None; }
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx.getCommandQueue(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx.getCommandQueue(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx.getDataFactory(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx.getDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx.getMainContextDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx.getMainContextDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx.getLoadContextDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx.getLoadContextDataFactory(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<IWindow> _WindowWaylandNew(std::string_view title) { return std::make_shared<WindowWayland>(title); }
|
std::shared_ptr<IWindow> _WindowWaylandNew(std::string_view title) { return std::make_shared<WindowWayland>(title); }
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
#include "boo/graphicsdev/GL.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
#include "boo/graphicsdev/glew.h"
|
#include "boo/graphicsdev/glew.h"
|
||||||
#include "../Common.hpp"
|
#include "lib/Common.hpp"
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
#include "boo/graphicsdev/Vulkan.hpp"
|
#include "boo/graphicsdev/Vulkan.hpp"
|
||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <limits.h>
|
#include <climits>
|
||||||
#include <unistd.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <unordered_set>
|
||||||
#include <condition_variable>
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
|
@ -32,9 +34,9 @@
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include "logvisor/logvisor.hpp"
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
#include "XlibCommon.hpp"
|
#include "lib/x11/XlibCommon.hpp"
|
||||||
|
|
||||||
#define REF_DPMM 3.78138
|
#define REF_DPMM 3.78138
|
||||||
#define FS_ATOM "_NET_WM_STATE_FULLSCREEN"
|
#define FS_ATOM "_NET_WM_STATE_FULLSCREEN"
|
||||||
|
@ -59,7 +61,7 @@
|
||||||
#undef False
|
#undef False
|
||||||
#undef True
|
#undef True
|
||||||
|
|
||||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
using glXCreateContextAttribsARBProc = GLXContext (*)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||||
static glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
static glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
||||||
static bool s_glxError;
|
static bool s_glxError;
|
||||||
static int ctxErrorHandler(Display* dpy, XErrorEvent* ev) {
|
static int ctxErrorHandler(Display* dpy, XErrorEvent* ev) {
|
||||||
|
@ -227,7 +229,7 @@ struct XlibAtoms {
|
||||||
m_imagePng = XInternAtom(disp, "image/png", false);
|
m_imagePng = XInternAtom(disp, "image/png", false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static XlibAtoms* S_ATOMS = NULL;
|
static XlibAtoms* S_ATOMS = nullptr;
|
||||||
|
|
||||||
static Atom GetClipboardTypeAtom(EClipboardType t) {
|
static Atom GetClipboardTypeAtom(EClipboardType t) {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
|
@ -356,7 +358,7 @@ public:
|
||||||
visualIdOut = m_visualid;
|
visualIdOut = m_visualid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() override {
|
||||||
if (m_glxCtx) {
|
if (m_glxCtx) {
|
||||||
glXDestroyContext(m_xDisp, m_glxCtx);
|
glXDestroyContext(m_xDisp, m_glxCtx);
|
||||||
m_glxCtx = nullptr;
|
m_glxCtx = nullptr;
|
||||||
|
@ -371,23 +373,23 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextXlibGLX() { destroy(); }
|
~GraphicsContextXlibGLX() override { destroy(); }
|
||||||
|
|
||||||
void resized(const SWindowRect& rect) {}
|
void resized(const SWindowRect& rect) override {}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void*) {
|
bool initializeContext(void*) override {
|
||||||
if (!glXCreateContextAttribsARB) {
|
if (!glXCreateContextAttribsARB) {
|
||||||
glXCreateContextAttribsARB =
|
glXCreateContextAttribsARB =
|
||||||
(glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
|
(glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
|
||||||
|
@ -424,25 +426,25 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {
|
void makeCurrent() override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_glxCtx))
|
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_glxCtx))
|
||||||
Log.report(logvisor::Fatal, fmt("unable to make GLX context current"));
|
Log.report(logvisor::Fatal, fmt("unable to make GLX context current"));
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit() {
|
void postInit() override {
|
||||||
GLXExtensionCheck();
|
GLXExtensionCheck();
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
GLXEnableVSync(m_xDisp, m_glxWindow);
|
GLXEnableVSync(m_xDisp, m_glxWindow);
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() {
|
IGraphicsDataFactory* getMainContextDataFactory() override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
if (!m_mainCtx) {
|
if (!m_mainCtx) {
|
||||||
s_glxError = false;
|
s_glxError = false;
|
||||||
|
@ -458,7 +460,7 @@ public:
|
||||||
return getDataFactory();
|
return getDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() {
|
IGraphicsDataFactory* getLoadContextDataFactory() override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
if (!m_loadCtx) {
|
if (!m_loadCtx) {
|
||||||
s_glxError = false;
|
s_glxError = false;
|
||||||
|
@ -474,7 +476,7 @@ public:
|
||||||
return getDataFactory();
|
return getDataFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
void present() { glXSwapBuffers(m_xDisp, m_glxWindow); }
|
void present() override { glXSwapBuffers(m_xDisp, m_glxWindow); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
|
@ -510,7 +512,7 @@ public:
|
||||||
visualIdOut = screen->root_visual->visualid;
|
visualIdOut = screen->root_visual->visualid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() override {
|
||||||
VulkanContext::Window& m_windowCtx = *m_ctx->m_windows[m_parentWindow];
|
VulkanContext::Window& m_windowCtx = *m_ctx->m_windows[m_parentWindow];
|
||||||
m_windowCtx.m_swapChains[0].destroy(m_ctx->m_dev);
|
m_windowCtx.m_swapChains[0].destroy(m_ctx->m_dev);
|
||||||
m_windowCtx.m_swapChains[1].destroy(m_ctx->m_dev);
|
m_windowCtx.m_swapChains[1].destroy(m_ctx->m_dev);
|
||||||
|
@ -520,28 +522,28 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextXlibVulkan() { destroy(); }
|
~GraphicsContextXlibVulkan() override { destroy(); }
|
||||||
|
|
||||||
VulkanContext::Window* m_windowCtx = nullptr;
|
VulkanContext::Window* m_windowCtx = nullptr;
|
||||||
|
|
||||||
void resized(const SWindowRect& rect) {
|
void resized(const SWindowRect& rect) override {
|
||||||
if (m_windowCtx)
|
if (m_windowCtx)
|
||||||
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace, rect);
|
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
void _setCallback(IWindowCallback* cb) override { m_callback = cb; }
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const { return m_api; }
|
EGraphicsAPI getAPI() const override { return m_api; }
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
EPixelFormat getPixelFormat() const override { return m_pf; }
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf) {
|
void setPixelFormat(EPixelFormat pf) override {
|
||||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||||
return;
|
return;
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeContext(void* getVkProc) {
|
bool initializeContext(void* getVkProc) override {
|
||||||
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
||||||
m_ctx->initVulkan(APP->getUniqueName(), PFN_vkGetInstanceProcAddr(getVkProc));
|
m_ctx->initVulkan(APP->getUniqueName(), PFN_vkGetInstanceProcAddr(getVkProc));
|
||||||
|
|
||||||
|
@ -637,19 +639,19 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() override {}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() override {}
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return getDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return getDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return getDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return getDataFactory(); }
|
||||||
|
|
||||||
void present() {}
|
void present() override {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -732,6 +734,7 @@ public:
|
||||||
m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, display,
|
m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, display,
|
||||||
defaultScreen, lastCtx, m_visualId, glCtx));
|
defaultScreen, lastCtx, m_visualId, glCtx));
|
||||||
m_openGL = true;
|
m_openGL = true;
|
||||||
|
Log.report(logvisor::Warning, fmt("OPENGL HAS BEEN DEPRECATED, IT IS HIGHLY RECOMMENDED TO BUILD AND USE VULKAN INSTEAD"));
|
||||||
}
|
}
|
||||||
|
|
||||||
XVisualInfo visTemplate;
|
XVisualInfo visTemplate;
|
||||||
|
@ -848,38 +851,38 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowXlib() {
|
~WindowXlib() override {
|
||||||
_cleanup();
|
_cleanup();
|
||||||
if (APP)
|
if (APP)
|
||||||
APP->_deletedWindow(this);
|
APP->_deletedWindow(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCallback(IWindowCallback* cb) {
|
void setCallback(IWindowCallback* cb) override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
m_callback = cb;
|
m_callback = cb;
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeWindow() {
|
void closeWindow() override {
|
||||||
// TODO: Free window resources and prevent further access
|
// TODO: Free window resources and prevent further access
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
XUnmapWindow(m_xDisp, m_windowId);
|
XUnmapWindow(m_xDisp, m_windowId);
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showWindow() {
|
void showWindow() override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
XMapWindow(m_xDisp, m_windowId);
|
XMapWindow(m_xDisp, m_windowId);
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideWindow() {
|
void hideWindow() override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
XUnmapWindow(m_xDisp, m_windowId);
|
XUnmapWindow(m_xDisp, m_windowId);
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getTitle() {
|
std::string getTitle() override {
|
||||||
unsigned long nitems;
|
unsigned long nitems;
|
||||||
Atom actualType;
|
Atom actualType;
|
||||||
int actualFormat;
|
int actualFormat;
|
||||||
|
@ -897,7 +900,7 @@ public:
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTitle(std::string_view title) {
|
void setTitle(std::string_view title) override {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
|
||||||
/* Set the title of the window */
|
/* Set the title of the window */
|
||||||
|
@ -914,7 +917,7 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCursor(EMouseCursor cursor) {
|
void setCursor(EMouseCursor cursor) override {
|
||||||
if (cursor == m_cursor && !m_cursorWait)
|
if (cursor == m_cursor && !m_cursorWait)
|
||||||
return;
|
return;
|
||||||
m_cursor = cursor;
|
m_cursor = cursor;
|
||||||
|
@ -923,7 +926,7 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWaitCursor(bool wait) {
|
void setWaitCursor(bool wait) override {
|
||||||
if (wait && !m_cursorWait) {
|
if (wait && !m_cursorWait) {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
XDefineCursor(m_xDisp, m_windowId, X_CURSORS.m_wait);
|
XDefineCursor(m_xDisp, m_windowId, X_CURSORS.m_wait);
|
||||||
|
@ -942,7 +945,7 @@ public:
|
||||||
return 60.0;
|
return 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getWindowRefreshRate() const {
|
double getWindowRefreshRate() const override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
double ret = 60.0;
|
double ret = 60.0;
|
||||||
int nmonitors;
|
int nmonitors;
|
||||||
|
@ -969,7 +972,7 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrameDefault() {
|
void setWindowFrameDefault() override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
int x, y, w, h, nmonitors;
|
int x, y, w, h, nmonitors;
|
||||||
Screen* screen = DefaultScreenOfDisplay(m_xDisp);
|
Screen* screen = DefaultScreenOfDisplay(m_xDisp);
|
||||||
|
@ -986,7 +989,7 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
XWindowAttributes attrs = {};
|
XWindowAttributes attrs = {};
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
@ -998,7 +1001,7 @@ public:
|
||||||
hOut = attrs.height;
|
hOut = attrs.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
XWindowAttributes attrs = {};
|
XWindowAttributes attrs = {};
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
@ -1010,7 +1013,7 @@ public:
|
||||||
hOut = attrs.height;
|
hOut = attrs.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(float x, float y, float w, float h) {
|
void setWindowFrame(float x, float y, float w, float h) override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
XWindowChanges values = {(int)x, (int)y, (int)w, (int)h};
|
XWindowChanges values = {(int)x, (int)y, (int)w, (int)h};
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
@ -1018,7 +1021,7 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowFrame(int x, int y, int w, int h) {
|
void setWindowFrame(int x, int y, int w, int h) override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
XWindowChanges values = {x, y, w, h};
|
XWindowChanges values = {x, y, w, h};
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
@ -1026,9 +1029,9 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getVirtualPixelFactor() const { return m_pixelFactor; }
|
float getVirtualPixelFactor() const override { return m_pixelFactor; }
|
||||||
|
|
||||||
bool isFullscreen() const {
|
bool isFullscreen() const override {
|
||||||
return m_inFs;
|
return m_inFs;
|
||||||
unsigned long nitems;
|
unsigned long nitems;
|
||||||
Atom actualType;
|
Atom actualType;
|
||||||
|
@ -1054,7 +1057,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStyle(EWindowStyle style) {
|
void setStyle(EWindowStyle style) override {
|
||||||
struct {
|
struct {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long functions;
|
unsigned long functions;
|
||||||
|
@ -1086,9 +1089,9 @@ public:
|
||||||
m_styleFlags = style;
|
m_styleFlags = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
EWindowStyle getStyle() const { return m_styleFlags; }
|
EWindowStyle getStyle() const override { return m_styleFlags; }
|
||||||
|
|
||||||
void setFullscreen(bool fs) {
|
void setFullscreen(bool fs) override {
|
||||||
if (fs == m_inFs)
|
if (fs == m_inFs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1121,7 +1124,7 @@ public:
|
||||||
}
|
}
|
||||||
} m_clipData;
|
} m_clipData;
|
||||||
|
|
||||||
void claimKeyboardFocus(const int coord[2]) {
|
void claimKeyboardFocus(const int coord[2]) override {
|
||||||
if (m_xIC) {
|
if (m_xIC) {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
if (!coord) {
|
if (!coord) {
|
||||||
|
@ -1139,7 +1142,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) {
|
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) override {
|
||||||
Atom xType = GetClipboardTypeAtom(type);
|
Atom xType = GetClipboardTypeAtom(type);
|
||||||
if (!xType)
|
if (!xType)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1155,7 +1158,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) {
|
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) override {
|
||||||
Atom xType = GetClipboardTypeAtom(type);
|
Atom xType = GetClipboardTypeAtom(type);
|
||||||
if (!xType)
|
if (!xType)
|
||||||
return {};
|
return {};
|
||||||
|
@ -1273,7 +1276,7 @@ public:
|
||||||
return lhs.tv_nsec - rhs.tv_nsec;
|
return lhs.tv_nsec - rhs.tv_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitForRetrace() {
|
int waitForRetrace() override {
|
||||||
BOO_MSAN_NO_INTERCEPT
|
BOO_MSAN_NO_INTERCEPT
|
||||||
struct timespec tp = {};
|
struct timespec tp = {};
|
||||||
clock_gettime(CLOCK_REALTIME, &tp);
|
clock_gettime(CLOCK_REALTIME, &tp);
|
||||||
|
@ -1306,7 +1309,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const { return (uintptr_t)m_windowId; }
|
uintptr_t getPlatformHandle() const override { return (uintptr_t)m_windowId; }
|
||||||
|
|
||||||
void _pointingDeviceChanged(int deviceId) {
|
void _pointingDeviceChanged(int deviceId) {
|
||||||
int nDevices;
|
int nDevices;
|
||||||
|
@ -1414,7 +1417,7 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool _incomingEvent(void* e) {
|
bool _incomingEvent(void* e) override {
|
||||||
XEvent* event = (XEvent*)e;
|
XEvent* event = (XEvent*)e;
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SelectionRequest: {
|
case SelectionRequest: {
|
||||||
|
@ -1708,7 +1711,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cleanup() {
|
void _cleanup() override {
|
||||||
if (m_gfxCtx) {
|
if (m_gfxCtx) {
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
m_gfxCtx->destroy();
|
m_gfxCtx->destroy();
|
||||||
|
@ -1720,15 +1723,15 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ETouchType getTouchType() const { return m_touchType; }
|
ETouchType getTouchType() const override { return m_touchType; }
|
||||||
|
|
||||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
|
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
|
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
|
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx->getMainContextDataFactory(); }
|
||||||
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
|
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
|
||||||
|
|
||||||
bool _isWindowMapped() {
|
bool _isWindowMapped() {
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
|
|
2
logvisor
2
logvisor
|
@ -1 +1 @@
|
||||||
Subproject commit dcd0ffcaece7f9ea3785d0ffca30a82cd60c573c
|
Subproject commit f623ace3b4620c56722a1460ff2d9db61621f659
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue