Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/boo

This commit is contained in:
Jack Andersen 2019-08-31 10:34:11 -10:00
commit c642bccf03
101 changed files with 2799 additions and 2369 deletions

View File

@ -5,140 +5,232 @@ cmake_policy(SET CMP0074 NEW)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing")
endif()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
if (NOT TARGET logvisor)
add_subdirectory(logvisor)
endif()
add_subdirectory(soxr/src)
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)
if (BOO_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()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
find_package(IPP)
if (IPP_FOUND)
list(APPEND _BOO_SYS_DEFINES -DINTEL_IPP=1)
list(APPEND _BOO_SYS_INCLUDES ${IPP_INCLUDE_DIRS})
list(APPEND _BOO_SYS_LIBS ${IPP_LIBRARIES})
target_compile_definitions(boo PUBLIC -DINTEL_IPP=1)
target_include_directories(boo PUBLIC ${IPP_INCLUDE_DIRS})
target_link_libraries(boo PUBLIC ${IPP_LIBRARIES})
message(STATUS "Building with IPP support")
else()
message(WARNING "IPP not found; skipping support")
endif ()
add_subdirectory(soxr/src)
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)
if(TARGET nx_compiler)
list(APPEND _BOO_SYS_DEFINES -DHECL_NOUVEAU_NX=1)
target_compile_definitions(boo PUBLIC -DHECL_NOUVEAU_NX=1)
endif()
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX)
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_compile_definitions(glew PUBLIC -DGLEW_NO_GLU=1)
endif()
if(NOT GEKKO AND NOT CAFE AND NOT WINDOWS_STORE AND NOT NX AND NOT APPLE)
list(APPEND PLAT_SRCS lib/graphicsdev/GL.cpp)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_GL=1)
list(APPEND _BOO_SYS_LIBS glew)
target_sources(boo PRIVATE lib/graphicsdev/GL.cpp)
target_compile_definitions(boo PUBLIC -DBOO_HAS_GL=1)
target_link_libraries(boo PUBLIC glew)
list(APPEND PLAT_HDRS
include/boo/graphicsdev/GLSLMacros.hpp
include/boo/graphicsdev/GL.hpp
include/boo/graphicsdev/Vulkan.hpp
include/boo/graphicsdev/VulkanDispatchTable.hpp)
target_sources(boo PRIVATE
include/boo/graphicsdev/GL.hpp
include/boo/graphicsdev/GLSLMacros.hpp
include/boo/graphicsdev/Vulkan.hpp
include/boo/graphicsdev/VulkanDispatchTable.hpp
)
endif()
if(WINDOWS_STORE)
list(APPEND PLAT_SRCS
lib/win/ApplicationUWP.cpp
lib/win/WindowUWP.cpp
lib/win/WinCommon.hpp
lib/win/UWPCommon.hpp
lib/inputdev/HIDListenerUWP.cpp
lib/inputdev/HIDDeviceUWP.cpp
lib/graphicsdev/D3D11.cpp
lib/graphicsdev/D3D12.cpp
lib/audiodev/WASAPI.cpp
lib/audiodev/AudioMatrixSSE.cpp)
target_sources(boo PRIVATE
lib/audiodev/AudioMatrixSSE.cpp
lib/audiodev/WASAPI.cpp
lib/inputdev/HIDDeviceUWP.cpp
lib/inputdev/HIDListenerUWP.cpp
lib/graphicsdev/D3D11.cpp
lib/graphicsdev/D3D12.cpp
lib/win/ApplicationUWP.cpp
lib/win/UWPCommon.hpp
lib/win/WinCommon.hpp
lib/win/WindowUWP.cpp
list(APPEND PLAT_HDRS
include/boo/UWPViewProvider.hpp
include/boo/graphicsdev/D3D.hpp)
include/boo/UWPViewProvider.hpp
include/boo/graphicsdev/D3D.hpp
)
list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE)
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi Imm32 Winmm Shlwapi Hid Xinput)
target_compile_definitions(boo PUBLIC
-DUNICODE
-D_UNICODE
)
target_link_libraries(boo PUBLIC
Hid
Imm32
opengl32
Setupapi
Shlwapi
Winmm
Winusb
Xinput
)
elseif(WIN32)
unset(VULKAN_SDK_DIRS 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")
message(STATUS "Enabling Vulkan support")
list(GET VULKAN_SDK_DIRS 0 VULKAN_SDK_DIR)
list(APPEND _EXTRA_INCLUDES ${VULKAN_SDK_DIR}/Include)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1 -DVK_USE_PLATFORM_WIN32_KHR=1)
list(APPEND _BOO_SYS_INCLUDES "${VULKAN_SDK_DIR}/Include")
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp
lib/graphicsdev/VulkanDispatchTable.cpp)
target_include_directories(boo PRIVATE "${VULKAN_SDK_DIR}/Include")
target_compile_definitions(boo PUBLIC
-DBOO_HAS_VULKAN=1
-DVK_USE_PLATFORM_WIN32_KHR=1
)
target_sources(boo PRIVATE
lib/graphicsdev/Vulkan.cpp
lib/graphicsdev/VulkanDispatchTable.cpp
)
endif()
find_file(TE_VIRTUAL_MIDI_H teVirtualMIDI.h PATHS
"$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)
message(STATUS "Enabling teVirtualMIDI")
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")
endif()
list(APPEND PLAT_SRCS
lib/win/ApplicationWin32.cpp
lib/win/WindowWin32.cpp
lib/win/WinCommon.hpp
lib/win/Win32Common.hpp
lib/inputdev/HIDListenerWinUSB.cpp
lib/inputdev/HIDDeviceWinUSB.cpp
lib/graphicsdev/D3D11.cpp
lib/audiodev/WASAPI.cpp
lib/audiodev/AudioMatrixSSE.cpp)
target_sources(boo PRIVATE
lib/audiodev/AudioMatrixSSE.cpp
lib/audiodev/WASAPI.cpp
lib/graphicsdev/D3D11.cpp
lib/inputdev/HIDListenerWinUSB.cpp
lib/inputdev/HIDDeviceWinUSB.cpp
lib/win/ApplicationWin32.cpp
lib/win/WindowWin32.cpp
lib/win/WinCommon.hpp
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)
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi Imm32 Winmm Shlwapi Hid Xinput)
target_compile_definitions(boo PUBLIC
-DUNICODE
-D_UNICODE
)
target_link_libraries(boo PUBLIC
Hid
Imm32
Setupapi
Shlwapi
Winmm
Winusb opengl32
Xinput
)
elseif(APPLE)
list(APPEND PLAT_SRCS
lib/mac/ApplicationCocoa.mm
lib/mac/WindowCocoa.mm
lib/mac/CocoaCommon.hpp
lib/inputdev/HIDListenerIOKit.cpp
lib/inputdev/HIDDeviceIOKit.cpp
lib/graphicsdev/Metal.mm
lib/audiodev/AQS.cpp
lib/audiodev/AudioMatrixSSE.cpp)
set_source_files_properties(lib/mac/ApplicationCocoa.mm
lib/mac/WindowCocoa.mm
lib/graphicsdev/Metal.mm
PROPERTIES COMPILE_FLAGS -fobjc-arc)
target_sources(boo PRIVATE
lib/audiodev/AQS.cpp
lib/audiodev/AudioMatrixSSE.cpp
lib/inputdev/HIDListenerIOKit.cpp
lib/inputdev/HIDDeviceIOKit.cpp
lib/mac/ApplicationCocoa.mm
lib/mac/WindowCocoa.mm
lib/mac/CocoaCommon.hpp
lib/graphicsdev/Metal.mm
list(APPEND PLAT_HDRS
lib/CFPointer.hpp
include/boo/graphicsdev/Metal.hpp
lib/inputdev/IOKitPointer.hpp)
lib/CFPointer.hpp
lib/inputdev/IOKitPointer.hpp
include/boo/graphicsdev/Metal.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(IOKIT_LIBRARY IOKit)
@ -146,7 +238,7 @@ elseif(APPLE)
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)
find_library(METAL_LIBRARY Metal)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_METAL=1)
target_compile_definitions(boo PUBLIC -DBOO_HAS_METAL=1)
else()
set(METAL_LIBRARY "")
endif()
@ -155,31 +247,39 @@ elseif(APPLE)
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
find_library(COREAUDIO_LIBRARY CoreAudio)
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)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_NX=1)
list(APPEND PLAT_SRCS
lib/nx/ApplicationNX.cpp
lib/nx/WindowNX.cpp
lib/audiodev/AudioMatrix.cpp
lib/inputdev/HIDListenerNX.cpp
lib/inputdev/HIDDeviceNX.cpp)
list(APPEND _BOO_SYS_LIBS nx_runtime)
target_compile_definitions(boo PUBLIC -DBOO_HAS_NX=1)
target_sources(boo PRIVATE
lib/nx/ApplicationNX.cpp
lib/nx/WindowNX.cpp
lib/audiodev/AudioMatrix.cpp
lib/inputdev/HIDListenerNX.cpp
lib/inputdev/HIDDeviceNX.cpp
)
target_link_libraries(boo PUBLIC nx_runtime)
else(NOT GEKKO)
list(APPEND PLAT_SRCS
lib/x11/XlibCommon.hpp
lib/x11/ApplicationUnix.cpp
lib/x11/ApplicationXlib.hpp
lib/x11/ApplicationWayland.hpp
lib/x11/WindowXlib.cpp
lib/x11/WindowWayland.cpp
lib/graphicsdev/GL.cpp
lib/graphicsdev/GLX.cpp
lib/audiodev/LinuxMidi.hpp)
target_sources(boo PRIVATE
lib/audiodev/LinuxMidi.hpp
lib/graphicsdev/GL.cpp
lib/graphicsdev/GLX.cpp
lib/x11/XlibCommon.hpp
lib/x11/ApplicationUnix.cpp
lib/x11/ApplicationWayland.hpp
lib/x11/ApplicationXlib.hpp
lib/x11/WindowWayland.cpp
lib/x11/WindowXlib.cpp
)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
@ -188,84 +288,120 @@ else(NOT GEKKO)
find_path(DBUS_INCLUDE_DIR
NAMES
dbus/dbus.h
dbus/dbus.h
HINTS
${dbus_pkg_INCLUDE_DIRS}
${dbus_pkg_INCLUDE_DIRS}
PATH_SUFFIXES
include/
include/dbus-1.0/
dbus-1.0/)
include/
include/dbus-1.0/
dbus-1.0/
)
find_path(DBUS_ARCH_INCLUDE_DIR
NAMES
dbus/dbus-arch-deps.h
dbus/dbus-arch-deps.h
HINTS
${dbus_pkg_INCLUDE_DIRS}
${dbus_pkg_INCLUDE_DIRS}
PATHS
# TODO use CMAKE_SYSTEM_PROCESSOR or similar?
/usr/lib/dbus-1.0/include
/usr/local/lib/dbus-1.0/include
/usr/lib/x86_64-linux-gnu/dbus-1.0/include/
# TODO use CMAKE_SYSTEM_PROCESSOR or similar?
/usr/lib/dbus-1.0/include
/usr/local/lib/dbus-1.0/include
/usr/lib/x86_64-linux-gnu/dbus-1.0/include/
PATH_SUFFIXES
dbus-1.0/include/)
dbus-1.0/include/
)
find_library(DBUS_LIBRARY
NAMES
dbus dbus-1
dbus
dbus-1
HINTS
${dbus_pkg_LIBRARY_DIRS}
${dbus_pkg_LIBRARY_DIRS}
PATH_SUFFIXES
lib
lib32
lib64)
lib
lib32
lib64
)
find_path(PULSEAUDIO_INCLUDE_DIR
NAMES pulse/pulseaudio.h)
NAMES pulse/pulseaudio.h
)
if(PULSEAUDIO_INCLUDE_DIR-NOTFOUND)
message(FATAL_ERROR "Unix build of boo requires pulseaudio")
endif()
list(APPEND PLAT_SRCS lib/audiodev/PulseAudio.cpp)
list(APPEND _BOO_SYS_LIBS pulse)
target_sources(boo PRIVATE lib/audiodev/PulseAudio.cpp)
target_link_libraries(boo PUBLIC pulse)
if(DBUS_INCLUDE_DIR-NOTFOUND)
message(FATAL_ERROR "Unix build of boo requires dbus")
endif()
list(APPEND _EXTRA_INCLUDES ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
list(APPEND _BOO_SYS_LIBS X11 Xi Xrandr GL asound ${DBUS_LIBRARY} pthread)
target_include_directories(boo PRIVATE
${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")
find_path(VULKAN_INCLUDE_DIR
NAMES vulkan/vulkan.h)
NAMES vulkan/vulkan.h
)
if(VULKAN_INCLUDE_DIR)
message(STATUS "Enabling Vulkan support")
list(APPEND PLAT_SRCS
lib/graphicsdev/Vulkan.cpp
lib/graphicsdev/VulkanDispatchTable.cpp)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1 -DVK_USE_PLATFORM_XCB_KHR=1)
target_sources(boo PRIVATE
lib/graphicsdev/Vulkan.cpp
lib/graphicsdev/VulkanDispatchTable.cpp
)
target_compile_definitions(boo
PUBLIC
-DBOO_HAS_VULKAN=1
-DVK_USE_PLATFORM_XCB_KHR=1
)
endif()
list(APPEND PLAT_SRCS
lib/inputdev/HIDListenerUdev.cpp
lib/inputdev/HIDDeviceUdev.cpp
lib/audiodev/AudioMatrixSSE.cpp)
list(APPEND _BOO_SYS_LIBS xcb X11-xcb dl udev)
target_sources(boo PRIVATE
lib/audiodev/AudioMatrixSSE.cpp
lib/inputdev/HIDDeviceUdev.cpp
lib/inputdev/HIDListenerUdev.cpp
)
target_link_libraries(boo
PUBLIC
dl
xcb
X11-xcb
udev
)
else()
list(APPEND PLAT_SRCS
lib/inputdev/HIDListenerBSD.cpp
lib/inputdev/HIDDeviceBSD.cpp
lib/audiodev/AudioMatrixSSE.cpp)
list(APPEND _BOO_SYS_LIBS execinfo)
target_sources(boo PRIVATE
lib/audiodev/AudioMatrixSSE.cpp
lib/inputdev/HIDDeviceBSD.cpp
lib/inputdev/HIDListenerBSD.cpp
)
target_link_libraries(boo
PUBLIC
execinfo
)
endif()
endif()
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
function(glslang_set_link_args TARGET)
endfunction(glslang_set_link_args)
@ -286,67 +422,29 @@ if(NOT NX)
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()
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)
add_sanitizers(boo)
endif()

View File

@ -1,8 +1,6 @@
#pragma once
#include <atomic>
#include <mutex>
#include "nxstl/mutex"
namespace boo {
@ -13,11 +11,10 @@ protected:
virtual ~IObj() = default;
public:
virtual std::unique_lock<std::recursive_mutex> destructorLock() = 0;
void increment() { m_refCount++; }
void decrement() {
if (m_refCount.fetch_sub(1) == 1) {
auto lk = destructorLock();
void increment() noexcept { m_refCount.fetch_add(1, std::memory_order_relaxed); }
void decrement() noexcept {
if (m_refCount.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
delete this;
}
}
@ -28,17 +25,17 @@ class ObjToken {
SubCls* m_obj = nullptr;
public:
ObjToken() = default;
ObjToken(SubCls* obj) : m_obj(obj) {
ObjToken() noexcept = default;
ObjToken(SubCls* obj) noexcept : m_obj(obj) {
if (m_obj)
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)
m_obj->increment();
}
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
ObjToken& operator=(SubCls* obj) {
ObjToken(ObjToken&& other) noexcept : m_obj(other.m_obj) { other.m_obj = nullptr; }
ObjToken& operator=(SubCls* obj) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = obj;
@ -46,7 +43,7 @@ public:
m_obj->increment();
return *this;
}
ObjToken& operator=(const ObjToken& other) {
ObjToken& operator=(const ObjToken& other) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = other.m_obj;
@ -54,26 +51,28 @@ public:
m_obj->increment();
return *this;
}
ObjToken& operator=(ObjToken&& other) {
ObjToken& operator=(ObjToken&& other) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = other.m_obj;
other.m_obj = nullptr;
return *this;
}
~ObjToken() {
~ObjToken() noexcept {
if (m_obj)
m_obj->decrement();
}
SubCls* get() const { return m_obj; }
SubCls* operator->() const { return m_obj; }
SubCls& operator*() const { return *m_obj; }
SubCls* get() const noexcept { return m_obj; }
SubCls* operator->() const noexcept { return m_obj; }
SubCls& operator*() const noexcept { return *m_obj; }
template <class T>
T* cast() const {
T* cast() const noexcept {
return static_cast<T*>(m_obj);
}
operator bool() const { return m_obj != nullptr; }
void reset() {
explicit operator bool() const noexcept { return m_obj != nullptr; }
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)
m_obj->decrement();
m_obj = nullptr;

View File

@ -1,8 +1,11 @@
#pragma once
#include <boo/boo.hpp>
#include <mutex>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <vector>
#include "boo/IWindow.hpp"
#include "nxstl/condition_variable"
namespace boo {
@ -15,11 +18,11 @@ struct DeferredWindowEvents : public IWindowCallback {
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
bool m_destroyed = false;
void destroyed() { m_destroyed = true; }
void destroyed() override { m_destroyed = true; }
bool m_hasResize = false;
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);
m_latestResize = rect;
m_hasResize = true;
@ -112,7 +115,7 @@ struct DeferredWindowEvents : public IWindowCallback {
};
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);
m_cmds.emplace_back(Command::Type::MouseDown);
m_cmds.back().m_coord = coord;
@ -120,7 +123,7 @@ struct DeferredWindowEvents : public IWindowCallback {
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);
m_cmds.emplace_back(Command::Type::MouseUp);
m_cmds.back().m_coord = coord;
@ -128,53 +131,53 @@ struct DeferredWindowEvents : public IWindowCallback {
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);
m_cmds.emplace_back(Command::Type::MouseMove);
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);
m_cmds.emplace_back(Command::Type::MouseEnter);
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);
m_cmds.emplace_back(Command::Type::MouseLeave);
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);
m_cmds.emplace_back(Command::Type::Scroll);
m_cmds.back().m_coord = coord;
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);
m_cmds.emplace_back(Command::Type::TouchDown);
m_cmds.back().m_tCoord = coord;
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);
m_cmds.emplace_back(Command::Type::TouchUp);
m_cmds.back().m_tCoord = coord;
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);
m_cmds.emplace_back(Command::Type::TouchMove);
m_cmds.back().m_tCoord = coord;
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);
m_cmds.emplace_back(Command::Type::CharKeyDown);
m_cmds.back().m_charcode = charCode;
@ -182,14 +185,14 @@ struct DeferredWindowEvents : public IWindowCallback {
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);
m_cmds.emplace_back(Command::Type::CharKeyUp);
m_cmds.back().m_charcode = charCode;
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);
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
m_cmds.back().m_special = key;
@ -197,27 +200,27 @@ struct DeferredWindowEvents : public IWindowCallback {
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);
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
m_cmds.back().m_special = key;
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);
m_cmds.emplace_back(Command::Type::ModKeyDown);
m_cmds.back().m_mods = mod;
m_cmds.back().m_isRepeat = isRepeat;
}
void modKeyUp(EModifierKey mod) {
void modKeyUp(EModifierKey mod) override {
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::ModKeyUp);
m_cmds.back().m_mods = mod;
}
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
ITextInputCallback* getTextInputCallback() override { return m_rec.getTextInputCallback(); }
void dispatchEvents() {
std::unique_lock<std::mutex> lk(m_mt);

View File

@ -1,11 +1,12 @@
#pragma once
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "IWindow.hpp"
#include "inputdev/DeviceFinder.hpp"
#include "boo/IWindow.hpp"
#include "boo/System.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
namespace boo {
class IApplication;

View File

@ -1,7 +1,7 @@
#pragma once
#include <memory>
#include <cstdint>
#include <memory>
namespace boo {
struct IGraphicsCommandQueue;
@ -14,7 +14,7 @@ class IGraphicsContext {
public:
enum class EGraphicsAPI {
None = 0,
Invalid = 0,
OpenGL3_3 = 1,
OpenGL4_2 = 2,
Vulkan = 3,
@ -26,7 +26,7 @@ public:
};
enum class EPixelFormat {
None = 0,
Invalid = 0,
RGBA8 = 1, /* Default */
RGBA16 = 2,
RGBA8_Z24 = 3,

View File

@ -1,10 +1,11 @@
#pragma once
#include "System.hpp"
#include <memory>
#include <algorithm>
#include <memory>
#include <cstring>
#include "boo/System.hpp"
#undef min
#undef max

View File

@ -37,12 +37,12 @@ static inline ComPtr<T>* ReferenceComPtr(ComPtr<T>& ptr) {
using T = std::underlying_type_t<type>; \
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>; \
a = type(static_cast<T>(a) | static_cast<T>(b)); \
return a; \
} \
inline type& operator&=(type& a, const type& b) { \
constexpr type& operator&=(type& a, type b) { \
using T = std::underlying_type_t<type>; \
a = type(static_cast<T>(a) & static_cast<T>(b)); \
return a; \

View File

@ -1,6 +1,6 @@
#pragma once
#include "IApplication.hpp"
#include "boo/IApplication.hpp"
namespace boo {

View File

@ -1,5 +1,6 @@
#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
@ -24,7 +25,7 @@ enum class AudioChannel {
struct ChannelMap {
unsigned m_channelCount = 0;
AudioChannel m_channels[8] = {};
std::array<AudioChannel, 8> m_channels{};
};
static inline unsigned ChannelCount(AudioChannelSet layout) {

View File

@ -1,12 +1,16 @@
#pragma once
#include "IAudioVoice.hpp"
#include "IAudioSubmix.hpp"
#include "IMIDIPort.hpp"
#include "boo/BooObject.hpp"
#include <cstddef>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "boo/BooObject.hpp"
#include "boo/audiodev/IAudioSubmix.hpp"
#include "boo/audiodev/IAudioVoice.hpp"
#include "boo/audiodev/IMIDIPort.hpp"
namespace boo {
struct IAudioVoiceEngine;

View File

@ -1,9 +1,10 @@
#pragma once
#include <string>
#include <functional>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <string>
#include <vector>
namespace boo {
struct IAudioVoiceEngine;
@ -35,7 +36,7 @@ protected:
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
public:
virtual ~IMIDIIn();
~IMIDIIn() override;
};
class IMIDIOut : public IMIDIPort {
@ -43,7 +44,7 @@ protected:
IMIDIOut(IAudioVoiceEngine* parent, bool virt) : IMIDIPort(parent, virt) {}
public:
virtual ~IMIDIOut();
~IMIDIOut() override;
virtual size_t send(const void* buf, size_t len) const = 0;
};
@ -53,7 +54,7 @@ protected:
: IMIDIPort(parent, virt), IMIDIReceiver(std::move(receiver)) {}
public:
virtual ~IMIDIInOut();
~IMIDIInOut() override;
virtual size_t send(const void* buf, size_t len) const = 0;
};

View File

@ -1,6 +1,6 @@
#pragma once
#include <cstdlib>
#include <cstddef>
#include <cstdint>
namespace boo {

View File

@ -1,17 +1,14 @@
#pragma once
#include "boo/audiodev/IMIDIReader.hpp"
#include "boo/audiodev/IMIDIPort.hpp"
#include <functional>
#include <cstdint>
#include <vector>
namespace boo {
class IMIDIReader;
class MIDIDecoder {
IMIDIReader& m_out;
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:
MIDIDecoder(IMIDIReader& out) : m_out(out) {}

View File

@ -1,7 +1,9 @@
#pragma once
#include <cstdint>
#include <iterator>
#include "boo/audiodev/IMIDIReader.hpp"
#include "boo/audiodev/IMIDIPort.hpp"
namespace boo {
@ -9,38 +11,45 @@ template <class Sender>
class MIDIEncoder : public IMIDIReader {
Sender& m_sender;
uint8_t m_status = 0;
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);
public:
MIDIEncoder(Sender& sender) : m_sender(sender) {}
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity);
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity);
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure);
void controlChange(uint8_t chan, uint8_t control, uint8_t value);
void programChange(uint8_t chan, uint8_t program);
void channelPressure(uint8_t chan, uint8_t pressure);
void pitchBend(uint8_t chan, int16_t pitch);
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity) override;
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity) override;
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure) override;
void controlChange(uint8_t chan, uint8_t control, uint8_t value) override;
void programChange(uint8_t chan, uint8_t program) override;
void channelPressure(uint8_t chan, uint8_t pressure) override;
void pitchBend(uint8_t chan, int16_t pitch) override;
void allSoundOff(uint8_t chan);
void resetAllControllers(uint8_t chan);
void localControl(uint8_t chan, bool on);
void allNotesOff(uint8_t chan);
void omniMode(uint8_t chan, bool on);
void polyMode(uint8_t chan, bool on);
void allSoundOff(uint8_t chan) override;
void resetAllControllers(uint8_t chan) override;
void localControl(uint8_t chan, bool on) override;
void allNotesOff(uint8_t chan) override;
void omniMode(uint8_t chan, bool on) override;
void polyMode(uint8_t chan, bool on) override;
void sysex(const void* data, size_t len);
void timeCodeQuarterFrame(uint8_t message, uint8_t value);
void songPositionPointer(uint16_t pointer);
void songSelect(uint8_t song);
void tuneRequest();
void sysex(const void* data, size_t len) override;
void timeCodeQuarterFrame(uint8_t message, uint8_t value) override;
void songPositionPointer(uint16_t pointer) override;
void songSelect(uint8_t song) override;
void tuneRequest() override;
void startSeq();
void continueSeq();
void stopSeq();
void startSeq() override;
void continueSeq() override;
void stopSeq() override;
void reset();
void reset() override;
};
} // namespace boo

View File

@ -1,5 +1,6 @@
#pragma once
#include "DeferredWindowEvents.hpp"
#include "IApplication.hpp"
#include "IWindow.hpp"
#include "inputdev/DeviceFinder.hpp"
@ -9,4 +10,3 @@
#include "inputdev/NintendoPowerA.hpp"
#include "graphicsdev/IGraphicsCommandQueue.hpp"
#include "graphicsdev/IGraphicsDataFactory.hpp"
#include "DeferredWindowEvents.hpp"

View File

@ -2,14 +2,14 @@
#if _WIN32
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/System.hpp"
#include <cstddef>
#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;
namespace boo {
@ -17,10 +17,10 @@ struct BaseGraphicsData;
class D3D11DataFactory : public IGraphicsDataFactory {
public:
virtual ~D3D11DataFactory() = default;
~D3D11DataFactory() override = default;
Platform platform() const { return Platform::D3D11; }
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
Platform platform() const override { return Platform::D3D11; }
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); }
class Context final : public IGraphicsDataFactory::Context {
friend class D3D11DataFactoryImpl;
@ -30,28 +30,30 @@ public:
~Context();
public:
Platform platform() const { return Platform::D3D11; }
const SystemChar* platformName() const { return _SYS_STR("D3D11"); }
Platform platform() const override { return Platform::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<IGraphicsBufferD> newDynamicBuffer(BufferUse use, 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) override;
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,
TextureFormat fmt, TextureClampMode clampMode, const void* data,
size_t sz);
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
size_t sz) override;
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,
size_t depthBindCount);
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips);
size_t depthBindCount) override;
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<IShaderStage> geometry, ObjToken<IShaderStage> control,
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& additionalInfo, bool asynchronous = true);
const AdditionalPipelineInfo& additionalInfo,
bool asynchronous = true) override;
ObjToken<IShaderDataBinding>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
@ -59,7 +61,7 @@ public:
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount,
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);

View File

@ -1,10 +1,11 @@
#pragma once
#if BOO_HAS_GL
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "boo/IGraphicsContext.hpp"
#include "GLSLMacros.hpp"
#include <cstdint>
#include "boo/BooObject.hpp"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
namespace boo {
struct BaseGraphicsData;
@ -25,35 +26,38 @@ public:
~Context();
public:
Platform platform() const { return Platform::OpenGL; }
const SystemChar* platformName() const { return _SYS_STR("OpenGL"); }
Platform platform() const override { return Platform::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<IGraphicsBufferD> newDynamicBuffer(BufferUse use, 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) override;
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,
TextureFormat fmt, TextureClampMode clampMode, const void* data,
size_t sz);
ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
size_t sz) override;
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 colorBindingCount, size_t depthBindingCount);
ObjToken<ITextureCubeR> newCubeRenderTexture(size_t width, size_t mips);
size_t colorBindingCount, size_t depthBindingCount) override;
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<IShaderStage> geometry, ObjToken<IShaderStage> control,
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& additionalInfo, bool asynchronous = true);
const AdditionalPipelineInfo& additionalInfo,
bool asynchronous = true) override;
ObjToken<IShaderDataBinding> newShaderDataBinding(
const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
const ObjToken<IGraphicsBuffer>& instVbo, const ObjToken<IGraphicsBuffer>& ibo, size_t ubufCount,
const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages, const size_t* ubufOffs,
const size_t* ubufSizes, size_t texCount, const ObjToken<ITexture>* texs, const int* texBindIdx,
const bool* depthBind, size_t baseVert = 0, size_t baseInst = 0);
ObjToken<IShaderDataBinding>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, const ObjToken<IGraphicsBuffer>& vbo,
const ObjToken<IGraphicsBuffer>& instVbo, const ObjToken<IGraphicsBuffer>& ibo,
size_t ubufCount, const ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, size_t texCount,
const ObjToken<ITexture>* texs, const int* texBindIdx, const bool* depthBind,
size_t baseVert = 0, size_t baseInst = 0) override;
};
};

View File

@ -1,9 +1,12 @@
#pragma once
#include "IGraphicsDataFactory.hpp"
#include "boo/IWindow.hpp"
#include <functional>
#include <array>
#include <cstddef>
#include <functional>
#include "boo/BooObject.hpp"
#include "boo/IWindow.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
namespace boo {

View File

@ -1,12 +1,13 @@
#pragma once
#include <memory>
#include <functional>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <vector>
#include "boo/System.hpp"
#include "boo/ThreadLocalPtr.hpp"
#include "boo/BooObject.hpp"
#include "boo/System.hpp"
#ifdef __SWITCH__
#include <ctype.h>
@ -118,7 +119,7 @@ ENABLE_BITWISE_ENUM(VertexSemantic)
/** Used to create IVertexFormat */
struct VertexElementDescriptor {
VertexSemantic semantic;
VertexSemantic semantic{};
int semanticIdx = 0;
VertexElementDescriptor() = default;
VertexElementDescriptor(VertexSemantic s, int idx = 0) : semantic(s), semanticIdx(idx) {}
@ -250,7 +251,8 @@ struct IGraphicsDataFactory {
const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& additionalInfo,
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(

View File

@ -2,9 +2,11 @@
#ifdef __APPLE__
#if BOO_HAS_METAL
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "boo/BooObject.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/System.hpp"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
namespace boo {
struct BaseGraphicsData;

View File

@ -1,9 +1,12 @@
#pragma once
#if BOO_HAS_NX
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "nx_compiler.hpp"
#include <unordered_map>
#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>

View File

@ -1,15 +1,16 @@
#pragma once
#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 <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"
/* Forward-declare handle type for Vulkan Memory Allocator */

View File

@ -1,11 +1,12 @@
#pragma once
#include <cstdint>
#include <cstdlib>
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <memory>
#include <vector>
#include <mutex>
#include <vector>
#include "nxstl/mutex"
#include "boo/System.hpp"
@ -54,18 +55,18 @@ public:
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
inline unsigned getVendorId();
inline unsigned getProductId();
inline std::string_view getVendorName();
inline std::string_view getProductName();
inline unsigned getVendorId() const;
inline unsigned getProductId() const;
inline std::string_view getVendorName() const;
inline std::string_view getProductName() const;
/* High-Level API */
#if _WIN32
#if !WINDOWS_STORE
const PHIDP_PREPARSED_DATA getReportDescriptor();
PHIDP_PREPARSED_DATA getReportDescriptor() const;
#endif
#else
std::vector<uint8_t> getReportDescriptor();
std::vector<uint8_t> getReportDescriptor() const;
#endif
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,

View File

@ -1,13 +1,13 @@
#pragma once
#include <unordered_set>
#include <typeindex>
#include <memory>
#include <mutex>
#include "DeviceToken.hpp"
#include "IHIDListener.hpp"
#include "DeviceSignature.hpp"
#include <cstring>
#include <cstdio>
#include <string>
#include <unordered_set>
#include "boo/inputdev/DeviceSignature.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/IHIDListener.hpp"
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
@ -41,34 +41,11 @@ private:
/* Friend methods for platform-listener to find/insert/remove
* tokens with type-filtering */
bool _hasToken(const std::string& path) {
auto preCheck = m_tokens.find(path);
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 _hasToken(const std::string& path) const {
return m_tokens.find(path) != m_tokens.end();
}
bool _insertToken(std::unique_ptr<DeviceToken>&& token);
void _removeToken(const std::string& path);
public:
class CDeviceTokensHandle {
@ -77,31 +54,17 @@ public:
public:
CDeviceTokensHandle(DeviceFinder& finder) : m_finder(finder) { m_finder.m_tokensLock.lock(); }
~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 */
DeviceFinder(std::unordered_set<uint64_t> types) {
if (skDevFinder) {
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;
}
DeviceFinder(std::unordered_set<uint64_t> types);
virtual ~DeviceFinder();
/* Get interested device-type mask */
const DeviceSignature::TDeviceSignatureSet& getTypes() const { return m_types; }
@ -110,29 +73,11 @@ public:
CDeviceTokensHandle getTokens() { return CDeviceTokensHandle(*this); }
/* Automatic device scanning */
bool startScanning() {
if (!m_listener)
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;
}
bool startScanning();
bool stopScanning();
/* Manual device scanning */
bool scanNow() {
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->scanNow();
return false;
}
bool scanNow();
virtual void deviceConnected(DeviceToken&) {}
virtual void deviceDisconnected(DeviceToken&, DeviceBase*) {}

View File

@ -1,10 +1,11 @@
#pragma once
#include <vector>
#include <cstdint>
#include <functional>
#include <typeindex>
#include <memory>
#include <string>
#include <typeindex>
#include <vector>
namespace boo {
@ -16,14 +17,16 @@ class DeviceBase;
#define dev_typeid(type) std::hash<std::string>()(#type)
struct DeviceSignature {
typedef std::vector<const DeviceSignature*> TDeviceSignatureSet;
typedef std::function<std::shared_ptr<DeviceBase>(DeviceToken*)> TFactoryLambda;
const char* m_name;
uint64_t m_typeHash;
unsigned m_vid, m_pid;
using TDeviceSignatureSet = std::vector<const DeviceSignature*>;
using TFactoryLambda = std::function<std::shared_ptr<DeviceBase>(DeviceToken*)>;
const char* m_name = nullptr;
uint64_t m_typeHash = 0;
unsigned m_vid = 0;
unsigned m_pid = 0;
TFactoryLambda m_factory;
DeviceType m_type;
DeviceSignature() : m_name(NULL), m_typeHash(dev_typeid(DeviceSignature)) {} /* Sentinel constructor */
DeviceType m_type{};
DeviceSignature() : m_typeHash(dev_typeid(DeviceSignature)) {} /* Sentinel constructor */
DeviceSignature(const char* name, uint64_t typeHash, unsigned vid, unsigned pid, TFactoryLambda&& factory,
DeviceType type = DeviceType::None)
: m_name(name), m_typeHash(typeHash), m_vid(vid), m_pid(pid), m_factory(factory), m_type(type) {}

View File

@ -1,8 +1,10 @@
#pragma once
#include <memory>
#include <string>
#include "DeviceBase.hpp"
#include "DeviceSignature.hpp"
#include "boo/inputdev/DeviceBase.hpp"
#include "boo/inputdev/DeviceSignature.hpp"
namespace boo {
@ -28,14 +30,7 @@ class DeviceToken {
public:
DeviceToken(const DeviceToken&) = delete;
DeviceToken(const DeviceToken&& other)
: 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(DeviceToken&& other) noexcept = default;
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) {
if (vname)
@ -44,6 +39,12 @@ public:
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; }
unsigned getVendorId() const { return m_vendorId; }
unsigned getProductId() const { return m_productId; }
@ -56,9 +57,6 @@ public:
m_connectedDev = DeviceSignature::DeviceNew(*this);
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

View File

@ -1,8 +1,9 @@
#pragma once
#include <cstdint>
#include "DeviceBase.hpp"
#include "../System.hpp"
#include "boo/System.hpp"
#include "boo/inputdev/DeviceBase.hpp"
namespace boo {
@ -67,14 +68,14 @@ class DolphinSmashAdapter final : public TDeviceBase<IDolphinSmashAdapterCallbac
uint8_t m_rumbleRequest = 0;
bool m_hardStop[4] = {false};
uint8_t m_rumbleState = 0xf; /* Force initial send of stop-rumble command */
void deviceDisconnected();
void initialCycle();
void transferCycle();
void finalCycle();
void deviceDisconnected() override;
void initialCycle() override;
void transferCycle() override;
void finalCycle() override;
public:
DolphinSmashAdapter(DeviceToken* token);
~DolphinSmashAdapter();
~DolphinSmashAdapter() override;
void setCallback(IDolphinSmashAdapterCallback* cb) {
TDeviceBase<IDolphinSmashAdapterCallback>::setCallback(cb);

View File

@ -1,8 +1,9 @@
#pragma once
#include <cstdint>
#include <type_traits>
#include "DeviceBase.hpp"
#include "boo/System.hpp"
#include "boo/inputdev/DeviceBase.hpp"
namespace boo {
@ -112,15 +113,15 @@ class DualshockPad final : public TDeviceBase<IDualshockPadCallback> {
uint8_t m_rumbleIntensity[2];
EDualshockLED m_led;
DualshockOutReport m_report;
void deviceDisconnected();
void initialCycle();
void transferCycle();
void finalCycle();
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
void deviceDisconnected() override;
void initialCycle() override;
void transferCycle() override;
void finalCycle() override;
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override;
public:
DualshockPad(DeviceToken* token);
~DualshockPad();
~DualshockPad() override;
void startRumble(EDualshockMotor motor, uint8_t duration = 254, uint8_t intensity = 255) {
m_rumbleRequest |= motor;
@ -136,7 +137,7 @@ public:
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) {
if (on)

View File

@ -1,9 +1,9 @@
#pragma once
#include "DeviceBase.hpp"
#include "HIDParser.hpp"
#include <map>
#include <mutex>
#include <functional>
#include "boo/inputdev/DeviceBase.hpp"
#include "boo/inputdev/HIDParser.hpp"
namespace boo {
@ -18,11 +18,11 @@ class GenericPad final : public TDeviceBase<IGenericPadCallback> {
public:
GenericPad(DeviceToken* token);
~GenericPad();
~GenericPad() override;
void deviceDisconnected();
void initialCycle();
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
void deviceDisconnected() override;
void initialCycle() override;
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;
};

View File

@ -1,10 +1,14 @@
#pragma once
#include "boo/System.hpp"
#include <vector>
#include <stack>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <stack>
#include <utility>
#include <vector>
#include "boo/System.hpp"
#if _WIN32
#include <hidsdi.h>

View File

@ -1,15 +1,18 @@
#pragma once
#include <unordered_map>
#include <memory>
#include <mutex>
#include "DeviceToken.hpp"
#include <unordered_map>
#include <utility>
#include "boo/inputdev/DeviceToken.hpp"
namespace boo {
typedef std::unordered_map<std::string, std::unique_ptr<DeviceToken>> TDeviceTokens;
typedef std::pair<TDeviceTokens::iterator, bool> TInsertedDeviceToken;
class DeviceFinder;
using TDeviceTokens = std::unordered_map<std::string, std::unique_ptr<DeviceToken>>;
using TInsertedDeviceToken = std::pair<TDeviceTokens::iterator, bool>;
class IHIDListener {
public:
virtual ~IHIDListener() = default;

View File

@ -23,8 +23,8 @@ struct NintendoPowerAState {
uint8_t leftY;
uint8_t rightX;
uint8_t rightY;
bool operator==(const NintendoPowerAState& other);
bool operator!=(const NintendoPowerAState& other);
bool operator==(const NintendoPowerAState& other) const;
bool operator!=(const NintendoPowerAState& other) const;
};
class NintendoPowerA;
@ -35,14 +35,14 @@ struct INintendoPowerACallback {
class NintendoPowerA final : public TDeviceBase<INintendoPowerACallback> {
NintendoPowerAState m_last;
void deviceDisconnected();
void initialCycle();
void transferCycle();
void finalCycle();
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
void deviceDisconnected() override;
void initialCycle() override;
void transferCycle() override;
void finalCycle() override;
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override;
public:
NintendoPowerA(DeviceToken*);
~NintendoPowerA();
~NintendoPowerA() override;
};
} // namespace boo

View File

@ -1,8 +1,10 @@
#pragma once
#include "DeviceBase.hpp"
#include "DeviceSignature.hpp"
#include <cstdint>
#include "boo/System.hpp"
#include "boo/inputdev/DeviceBase.hpp"
#include "boo/inputdev/DeviceSignature.hpp"
namespace boo {
@ -36,7 +38,7 @@ class XInputPad final : public TDeviceBase<IXInputPadCallback> {
public:
XInputPad(DeviceToken* token) : TDeviceBase<IXInputPadCallback>(dev_typeid(XInputPad), token) {}
void deviceDisconnected() {
void deviceDisconnected() override {
std::lock_guard<std::mutex> lk(m_callbackLock);
if (m_callback)
m_callback->controllerDisconnected();

View File

@ -1,8 +1,10 @@
#pragma once
#include "boo/BooObject.hpp"
#include <cstddef>
#include <iterator>
#include "boo/BooObject.hpp"
namespace boo {
/** Linked-list iterator shareable by ListNode types. */

View File

@ -1,14 +1,13 @@
#include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include "boo/IApplication.hpp"
#include "../CFPointer.hpp"
#include "lib/CFPointer.hpp"
#include <AudioToolbox/AudioToolbox.h>
#include <CoreMIDI/CoreMIDI.h>
#include <CoreAudio/HostTime.h>
#include <mutex>
#include <condition_variable>
#include <logvisor/logvisor.hpp>
namespace boo {
static logvisor::Module Log("boo::AQS");
@ -74,15 +73,15 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
argSize = sizeof(devId);
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, sizeof(devName), &devName, &argSize,
&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));
argSize = sizeof(devId);
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &argSize, &devId) == noErr) {
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &argSize, &devId) == noErr) {
argSize = sizeof(CFStringRef);
AudioObjectPropertyAddress deviceAddress;
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
AudioObjectGetPropertyData(devId, &deviceAddress, 0, NULL, &argSize, &m_devName);
AudioObjectGetPropertyData(devId, &deviceAddress, 0, nullptr, &argSize, &m_devName);
} else {
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
return {AudioChannelSet::Unknown, 48000.0};
@ -90,21 +89,21 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
}
propertyAddress.mSelector = kAudioDevicePropertyStreams;
if (AudioObjectGetPropertyDataSize(devId, &propertyAddress, 0, NULL, &argSize) == noErr) {
if (AudioObjectGetPropertyDataSize(devId, &propertyAddress, 0, nullptr, &argSize) == noErr) {
numStreams = argSize / sizeof(AudioStreamID);
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;
for (int stm = 0; stm < numStreams; stm++) {
UInt32 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) {
propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat;
AudioStreamBasicDescription 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) {
case 2:
return {AudioChannelSet::Stereo, asbd.mSampleRate};
@ -130,9 +129,9 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
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));
_rebuildAudioQueue();
return true;
@ -155,29 +154,29 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
propertyAddress.mSelector = kAudioHardwarePropertyDevices;
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize) == noErr) {
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &propertySize) == noErr) {
numDevices = propertySize / sizeof(AudioDeviceID);
ret.reserve(numDevices);
deviceIDs.resize(numDevices);
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize,
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &propertySize,
&deviceIDs[0]) == noErr) {
char deviceName[64];
for (int idx = 0; idx < numDevices; idx++) {
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);
streamIDs.resize(numStreams);
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, &streamIDs[0]) ==
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, &streamIDs[0]) ==
noErr) {
propertyAddress.mSelector = kAudioStreamPropertyDirection;
bool foundOutput = false;
for (int stm = 0; stm < numStreams; stm++) {
UInt32 streamDir;
propertySize = sizeof(streamDir);
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, NULL, &propertySize, &streamDir) ==
if (AudioObjectGetPropertyData(streamIDs[stm], &propertyAddress, 0, nullptr, &propertySize, &streamDir) ==
noErr) {
if (streamDir == 0) {
foundOutput = true;
@ -192,13 +191,13 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
propertySize = sizeof(deviceName);
propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, deviceName) ==
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, deviceName) ==
noErr) {
CFPointer<CFStringRef> uidString;
propertySize = sizeof(CFStringRef);
propertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, NULL, &propertySize, &uidString) ==
if (AudioObjectGetPropertyData(deviceIDs[idx], &propertyAddress, 0, nullptr, &propertySize, &uidString) ==
noErr) {
ret.emplace_back(CFStringGetCStringPtr(uidString.get(), kCFStringEncodingUTF8), deviceName);
}
@ -336,14 +335,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
MIDIIn(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
: IMIDIIn(parent, virt, std::move(receiver)) {}
~MIDIIn() {
~MIDIIn() override {
if (m_midi)
MIDIEndpointDispose(m_midi);
if (m_midiPort)
MIDIPortDispose(m_midiPort);
}
std::string description() const {
std::string description() const override {
CFPointer<CFStringRef> namestr;
const char* nameCstr;
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
@ -362,14 +361,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
MIDIOut(AQSAudioVoiceEngine* parent, bool virt) : IMIDIOut(parent, virt) {}
~MIDIOut() {
~MIDIOut() override {
if (m_midi)
MIDIEndpointDispose(m_midi);
if (m_midiPort)
MIDIPortDispose(m_midiPort);
}
std::string description() const {
std::string description() const override {
CFPointer<CFStringRef> namestr;
const char* nameCstr;
if (MIDIObjectGetStringProperty(m_midi, kMIDIPropertyName, &namestr))
@ -381,7 +380,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return nameCstr;
}
size_t send(const void* buf, size_t len) const {
size_t send(const void* buf, size_t len) const override {
union {
MIDIPacketList head;
Byte storage[512];
@ -408,7 +407,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
MIDIInOut(AQSAudioVoiceEngine* parent, bool virt, ReceiveFunctor&& receiver)
: IMIDIInOut(parent, virt, std::move(receiver)) {}
~MIDIInOut() {
~MIDIInOut() override {
if (m_midiIn)
MIDIEndpointDispose(m_midiIn);
if (m_midiPortIn)
@ -419,7 +418,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
MIDIPortDispose(m_midiPortOut);
}
std::string description() const {
std::string description() const override {
CFPointer<CFStringRef> namestr;
const char* nameCstr;
if (MIDIObjectGetStringProperty(m_midiIn, kMIDIPropertyName, &namestr))
@ -431,7 +430,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return nameCstr;
}
size_t send(const void* buf, size_t len) const {
size_t send(const void* buf, size_t len) const override {
union {
MIDIPacketList head;
Byte storage[512];
@ -452,7 +451,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
unsigned m_midiInCounter = 0;
unsigned m_midiOutCounter = 0;
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
if (!m_midiClient)
return {};
@ -477,7 +476,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
if (!m_midiClient)
return {};
@ -500,7 +499,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) {
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override {
if (!m_midiClient)
return {};
@ -537,7 +536,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
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)
return {};
@ -561,7 +560,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
if (!m_midiClient)
return {};
@ -584,7 +583,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
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)
return {};
@ -623,7 +622,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
bool useMIDILock() const { return true; }
bool useMIDILock() const override { return true; }
static void SampleRateChanged(AQSAudioVoiceEngine* engine, AudioQueueRef inAQ, AudioQueuePropertyID inID) {
engine->m_needsRebuild = true;
@ -759,7 +758,7 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
chMapOut.m_channels[4] = AudioChannel::FrontCenter;
break;
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_channels[0] = AudioChannel::FrontLeft;
chMapOut.m_channels[1] = AudioChannel::FrontRight;
@ -800,11 +799,11 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
const AudioObjectPropertyAddress* inAddresses, AQSAudioVoiceEngine* engine) {
AudioObjectID 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);
AudioObjectPropertyAddress deviceAddress;
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;
return noErr;
@ -820,12 +819,12 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
AudioObjectID defaultDeviceId;
UInt32 argSize = sizeof(defaultDeviceId);
propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &argSize, &defaultDeviceId) ==
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &argSize, &defaultDeviceId) ==
noErr) {
argSize = sizeof(CFStringRef);
AudioObjectPropertyAddress deviceAddress;
deviceAddress.mSelector = kAudioDevicePropertyDeviceUID;
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, NULL, &argSize, &m_devName);
AudioObjectGetPropertyData(defaultDeviceId, &deviceAddress, 0, nullptr, &argSize, &m_devName);
} else {
Log.report(logvisor::Fatal, fmt("unable determine default audio device"));
return;
@ -841,14 +840,14 @@ struct AQSAudioVoiceEngine : BaseAudioVoiceEngine {
MIDIClientCreate(CFSTR("Boo MIDI"), nullptr, nullptr, &m_midiClient);
}
~AQSAudioVoiceEngine() {
~AQSAudioVoiceEngine() override {
m_cbRunning = false;
AudioQueueDispose(m_queue, true);
if (m_midiClient)
MIDIClientDispose(m_midiClient);
}
void pumpAndMixVoices() {
void pumpAndMixVoices() override {
while (CFRunLoopRunInMode(m_runLoopMode.get(), 0, true) == kCFRunLoopRunHandledSource) {}
if (m_needsRebuild) {
_rebuildAudioQueue();

View File

@ -1,5 +1,5 @@
#include "AudioMatrix.hpp"
#include "AudioVoiceEngine.hpp"
#include "lib/audiodev/AudioMatrix.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <cstring>
namespace boo {

View File

@ -1,10 +1,11 @@
#pragma once
#include "boo/audiodev/IAudioVoice.hpp"
#include <vector>
#include <cstdint>
#include <limits.h>
#include <cfloat>
#include <climits>
#include <cstddef>
#include <cstdint>
#include "boo/audiodev/IAudioVoice.hpp"
#if __SSE__
#include <immintrin.h>

View File

@ -1,18 +1,17 @@
#include "AudioMatrix.hpp"
#include "AudioVoiceEngine.hpp"
#include <cstring>
#include "lib/audiodev/AudioMatrix.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <immintrin.h>
namespace boo {
typedef union {
union TVectorUnion {
float v[4];
#if __SSE__
__m128 q;
__m64 d[2];
#endif
} TVectorUnion;
};
static constexpr TVectorUnion Min32Vec = {{INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN}};
static constexpr TVectorUnion Max32Vec = {{INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX}};

View File

@ -1,7 +1,7 @@
#include "AudioSubmix.hpp"
#include "AudioVoiceEngine.hpp"
#include "AudioVoice.hpp"
#include <cstring>
#include "lib/audiodev/AudioSubmix.hpp"
#include "lib/audiodev/AudioVoice.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <algorithm>
#undef min
@ -21,9 +21,6 @@ AudioSubmix*& AudioSubmix::_getHeadPtr(BaseAudioVoiceEngine* head) { return head
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head) {
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(); }

View File

@ -1,11 +1,15 @@
#pragma once
#include "boo/audiodev/IAudioSubmix.hpp"
#include <list>
#include <vector>
#include <array>
#include <cstddef>
#include <cstdint>
#include <list>
#include <mutex>
#include <unordered_map>
#include "Common.hpp"
#include <vector>
#include "boo/audiodev/IAudioSubmix.hpp"
#include "lib/audiodev/Common.hpp"
#if __SSE__
#include <immintrin.h>
@ -80,16 +84,15 @@ class AudioSubmix : public ListNode<AudioSubmix, BaseAudioVoiceEngine*, IAudioSu
public:
static AudioSubmix*& _getHeadPtr(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();
~AudioSubmix() override;
void resetSendLevels();
void setSendLevel(IAudioSubmix* submix, float level, bool slew);
void resetSendLevels() override;
void setSendLevel(IAudioSubmix* submix, float level, bool slew) override;
const AudioVoiceEngineMixInfo& mixInfo() const;
double getSampleRate() const;
SubmixFormat getSampleFormat() const;
double getSampleRate() const override;
SubmixFormat getSampleFormat() const override;
};
template <>

View File

@ -18,9 +18,6 @@ AudioVoice*& AudioVoice::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head) {
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) {
if (m_dynamicRate) {

View File

@ -1,12 +1,14 @@
#pragma once
#include <soxr.h>
#include <list>
#include <mutex>
#include <unordered_map>
#include "boo/audiodev/IAudioVoice.hpp"
#include "AudioMatrix.hpp"
#include "Common.hpp"
#include "AudioVoiceEngine.hpp"
#include "lib/audiodev/AudioMatrix.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include "lib/audiodev/Common.hpp"
#include <soxr.h>
struct AudioUnitVoiceEngine;
struct VSTVoiceEngine;
@ -64,13 +66,12 @@ protected:
public:
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
std::unique_lock<std::recursive_mutex> destructorLock();
~AudioVoice();
void resetSampleRate(double sampleRate);
void setPitchRatio(double ratio, bool slew);
void start();
void stop();
~AudioVoice() override;
void resetSampleRate(double sampleRate) override;
void setPitchRatio(double ratio, bool slew) override;
void start() override;
void stop() override;
double getSampleRateIn() const { return m_sampleRateIn; }
double getSampleRateOut() const { return m_sampleRateOut; }
};
@ -91,7 +92,7 @@ inline size_t AudioVoice::pumpAndMix<float>(size_t frames) {
class AudioVoiceMono : public AudioVoice {
std::unordered_map<IAudioSubmix*, AudioMatrixMono> m_sendMatrices;
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);
@ -99,21 +100,21 @@ class AudioVoiceMono : public AudioVoice {
template <typename T>
size_t _pumpAndMix(size_t frames);
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
public:
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
void resetChannelLevels();
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
void resetChannelLevels() override;
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
};
class AudioVoiceStereo : public AudioVoice {
std::unordered_map<IAudioSubmix*, AudioMatrixStereo> m_sendMatrices;
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);
@ -121,15 +122,15 @@ class AudioVoiceStereo : public AudioVoice {
template <typename T>
size_t _pumpAndMix(size_t frames);
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
public:
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
void resetChannelLevels();
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
void resetChannelLevels() override;
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
};
} // namespace boo

View File

@ -1,5 +1,7 @@
#include "AudioVoiceEngine.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <cassert>
#include <cstring>
namespace boo {

View File

@ -1,12 +1,18 @@
#pragma once
#include "boo/audiodev/IAudioVoiceEngine.hpp"
#include "LtRtProcessing.hpp"
#include "Common.hpp"
#include "AudioVoice.hpp"
#include "AudioSubmix.hpp"
#include <functional>
#include <cstddef>
#include <cstdint>
#include <list>
#include <memory>
#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 {
@ -57,22 +63,24 @@ protected:
public:
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
~BaseAudioVoiceEngine();
ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate, IAudioVoiceCallback* cb, bool dynamicPitch = false);
~BaseAudioVoiceEngine() override;
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);
bool enableLtRt(bool enable);
void setVolume(float vol) override;
bool enableLtRt(bool enable) override;
const AudioVoiceEngineMixInfo& mixInfo() const;
const AudioVoiceEngineMixInfo& clientMixInfo() const;
AudioChannelSet getAvailableSet() { return clientMixInfo().m_channels; }
void pumpAndMixVoices() {}
size_t get5MsFrames() const { return m_5msFrames; }
AudioChannelSet getAvailableSet() override { return clientMixInfo().m_channels; }
void pumpAndMixVoices() override {}
size_t get5MsFrames() const override { return m_5msFrames; }
};
template <>

View File

@ -1,8 +1,8 @@
#pragma once
#include <soxr.h>
#include "../Common.hpp"
#include "boo/audiodev/IAudioVoice.hpp"
#include "lib/Common.hpp"
namespace boo {

View File

@ -1,11 +1,13 @@
#pragma once
#include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include <csignal>
#include <thread>
#include <unordered_map>
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <alsa/asoundlib.h>
#include <signal.h>
#include <logvisor/logvisor.hpp>
namespace boo {
extern logvisor::Module ALSALog;
@ -25,12 +27,12 @@ struct LinuxMidi : BaseAudioVoiceEngine {
}
}
~LinuxMidi() {
~LinuxMidi() override {
for (auto& p : m_openHandles)
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;
int status;
int card = -1; /* use -1 to prime the pump of iterating through card list */
@ -83,7 +85,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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); }
@ -126,7 +128,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
, m_midi(midi)
, m_midiThread(std::bind(MIDIReceiveProc, m_midi, m_receiver)) {}
~MIDIIn() {
~MIDIIn() override {
if (m_parent)
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
pthread_cancel(m_midiThread.native_handle());
@ -135,7 +137,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
snd_rawmidi_close(m_midi);
}
std::string description() const {
std::string description() const override {
snd_rawmidi_info_t* info;
snd_rawmidi_info_alloca(&info);
snd_rawmidi_info(m_midi, info);
@ -148,13 +150,13 @@ struct LinuxMidi : BaseAudioVoiceEngine {
snd_rawmidi_t* m_midi;
MIDIOut(LinuxMidi* parent, snd_rawmidi_t* midi, bool virt) : IMIDIOut(parent, virt), m_midi(midi) {}
~MIDIOut() {
~MIDIOut() override {
if (m_parent)
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
snd_rawmidi_close(m_midi);
}
std::string description() const {
std::string description() const override {
snd_rawmidi_info_t* info;
snd_rawmidi_info_alloca(&info);
snd_rawmidi_info(m_midi, info);
@ -162,7 +164,9 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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 {
@ -176,7 +180,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
, m_midiOut(midiOut)
, m_midiThread(std::bind(MIDIReceiveProc, m_midiIn, m_receiver)) {}
~MIDIInOut() {
~MIDIInOut() override {
if (m_parent)
static_cast<LinuxMidi*>(m_parent)->_removeOpenHandle(this);
pthread_cancel(m_midiThread.native_handle());
@ -186,7 +190,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
snd_rawmidi_close(m_midiOut);
}
std::string description() const {
std::string description() const override {
snd_rawmidi_info_t* info;
snd_rawmidi_info_alloca(&info);
snd_rawmidi_info(m_midiIn, info);
@ -194,12 +198,12 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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)));
}
};
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) {
std::unique_ptr<IMIDIIn> newVirtualMIDIIn(ReceiveFunctor&& receiver) override {
int status;
snd_rawmidi_t* midi;
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));
}
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
int status;
snd_rawmidi_t* midi;
status = snd_rawmidi_open(nullptr, &midi, "virtual", 0);
@ -217,7 +221,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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;
snd_rawmidi_t* midiIn;
snd_rawmidi_t* midiOut;
@ -227,7 +231,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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;
int status = snd_rawmidi_open(&midi, nullptr, name, 0);
if (status)
@ -237,7 +241,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
return ret;
}
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
snd_rawmidi_t* midi;
int status = snd_rawmidi_open(nullptr, &midi, name, 0);
if (status)
@ -247,7 +251,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
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* midiOut;
int status = snd_rawmidi_open(&midiIn, &midiOut, name, 0);
@ -258,7 +262,7 @@ struct LinuxMidi : BaseAudioVoiceEngine {
return ret;
}
bool useMIDILock() const { return true; }
bool useMIDILock() const override { return true; }
};
} // namespace boo

View File

@ -1,16 +1,17 @@
#include "LtRtProcessing.hpp"
#include <cmath>
#include "lib/audiodev/LtRtProcessing.hpp"
#include <algorithm>
#include <cmath>
#undef min
#undef max
namespace boo {
namespace {
template <typename T>
inline T ClampFull(float in) {
if (std::is_floating_point<T>()) {
return std::min<T>(std::max<T>(in, -1.f), 1.f);
constexpr T ClampFull(float in) {
if constexpr (std::is_floating_point_v<T>) {
return std::clamp(in, -1.f, 1.f);
} else {
constexpr T MAX = std::numeric_limits<T>::max();
constexpr T MIN = std::numeric_limits<T>::min();
@ -23,6 +24,7 @@ inline T ClampFull(float in) {
return in;
}
}
} // Anonymous namespace
#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[4] = AudioChannel::RearRight;
int samples = m_windowFrames * (5 * 2 + 2 * 2);
const int samples = m_windowFrames * (5 * 2 + 2 * 2);
switch (mixInfo.m_sampleFormat) {
case SOXR_INT16_I:
m_16Buffer.reset(new int16_t[samples]);
memset(m_16Buffer.get(), 0, sizeof(int16_t) * samples);
m_16Buffer = std::make_unique<int16_t[]>(samples);
break;
case SOXR_INT32_I:
m_32Buffer.reset(new int32_t[samples]);
memset(m_32Buffer.get(), 0, sizeof(int32_t) * samples);
m_32Buffer = std::make_unique<int32_t[]>(samples);
break;
case SOXR_FLOAT32_I:
m_fltBuffer.reset(new float[samples]);
memset(m_fltBuffer.get(), 0, sizeof(float) * samples);
m_fltBuffer = std::make_unique<float[]>(samples);
break;
default:
break;
@ -259,12 +258,12 @@ LtRtProcessing::LtRtProcessing(int _5msFrames, const AudioVoiceEngineMixInfo& mi
template <typename T>
void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
#if 0
for (int i=0 ; i<frameCount ; ++i)
{
output[i * 2] = input[i * 5 + 3];
output[i * 2 + 1] = input[i * 5 + 4];
}
return;
for (int i = 0; i < frameCount; ++i)
{
output[i * 2] = input[i * 5 + 3];
output[i * 2 + 1] = input[i * 5 + 4];
}
return;
#endif
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 samples = (tail - m_bufferTail) * 5;
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;
frameCount -= tail - m_bufferTail;
int head = std::min(m_windowFrames * 2, m_bufferHead + outFramesRem);
samples = (head - m_bufferHead) * 2;
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;
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) {
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]);
// 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 {
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) {
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]);
// 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;
for (; i < m_windowFrames; ++i, ++delayI) {
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]);
// 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
@ -328,14 +327,14 @@ void LtRtProcessing::Process(const T* input, T* output, int frameCount) {
if (frameCount) {
samples = frameCount * 5;
memmove(inBuf, input, samples * sizeof(T));
// printf("input %d to %d\n", frameCount, 0);
// fmt::print("input {} to {}\n", frameCount, 0);
m_bufferTail = frameCount;
}
if (outFramesRem) {
samples = outFramesRem * 2;
memmove(output, outBuf, samples * sizeof(T));
// printf("output %d from %d\n", outFramesRem, 0);
// fmt::print("output {} from {}\n", outFramesRem, 0);
m_bufferHead = outFramesRem;
}
}

View File

@ -1,9 +1,11 @@
#pragma once
#include <cstdint>
#include <memory>
#include "boo/System.hpp"
#include "boo/audiodev/IAudioVoice.hpp"
#include "Common.hpp"
#include <memory>
#include "lib/audiodev/Common.hpp"
#if INTEL_IPP
#include "ipp.h"

View File

@ -1,4 +1,5 @@
#include "MIDICommon.hpp"
#include "lib/audiodev/MIDICommon.hpp"
#include "boo/audiodev/IMIDIPort.hpp"
namespace boo {

View File

@ -1,39 +1,46 @@
#include "boo/audiodev/MIDIDecoder.hpp"
#include "MIDICommon.hpp"
#include <memory>
#include <algorithm>
#include <optional>
#include "boo/audiodev/IMIDIReader.hpp"
#include "lib/audiodev/MIDICommon.hpp"
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))); }
bool MIDIDecoder::_readContinuedValue(std::vector<uint8_t>::const_iterator& it,
std::vector<uint8_t>::const_iterator end, uint32_t& valOut) {
std::optional<uint32_t> readContinuedValue(std::vector<uint8_t>::const_iterator& it,
std::vector<uint8_t>::const_iterator end) {
uint8_t a = *it++;
valOut = a & 0x7f;
uint32_t valOut = a & 0x7f;
if (a & 0x80) {
if (it == end)
return false;
if ((a & 0x80) != 0) {
if (it == end) {
return std::nullopt;
}
valOut <<= 7;
a = *it++;
valOut |= a & 0x7f;
if (a & 0x80) {
if (it == end)
return false;
if ((a & 0x80) != 0) {
if (it == end) {
return std::nullopt;
}
valOut <<= 7;
a = *it++;
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 end) {
std::vector<uint8_t>::const_iterator it = begin;
auto it = begin;
while (it != end) {
uint8_t a = *it++;
uint8_t b;
@ -48,9 +55,8 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
return begin;
a = *it++;
uint32_t length;
_readContinuedValue(it, end, length);
it += length;
const auto length = readContinuedValue(it, end);
it += *length;
} else {
uint8_t chan = m_status & 0xf;
switch (Status(m_status & 0xf0)) {
@ -121,10 +127,11 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
case Status::SysEx: {
switch (Status(m_status & 0xff)) {
case Status::SysEx: {
uint32_t len;
if (!_readContinuedValue(it, end, len) || end - it < len)
const auto len = readContinuedValue(it, end);
if (!len || end - it < *len) {
return begin;
m_out.sysex(&*it, len);
}
m_out.sysex(&*it, *len);
break;
}
case Status::TimecodeQuarterFrame: {

View File

@ -1,7 +1,17 @@
#include "boo/audiodev/MIDIEncoder.hpp"
#include "MIDICommon.hpp"
#include <array>
#include "boo/audiodev/IMIDIPort.hpp"
#include "lib/audiodev/MIDICommon.hpp"
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>
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>
void MIDIEncoder<Sender>::_sendContinuedValue(uint32_t val) {
uint8_t send[3] = {};
std::array<uint8_t, 3> send{};
uint8_t* ptr = nullptr;
if (val >= 0x4000) {
ptr = &send[0];
@ -26,154 +36,164 @@ void MIDIEncoder<Sender>::_sendContinuedValue(uint32_t val) {
}
if (val >= 0x80) {
if (!ptr)
if (ptr == nullptr) {
ptr = &send[1];
}
send[1] = 0x80 | ((val / 0x80) & 0x7f);
}
if (!ptr)
if (ptr == nullptr) {
ptr = &send[2];
}
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>
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)};
_sendMessage(cmd, 3);
const auto cmd =
MakeCommand(uint8_t(int(Status::NoteOff) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 3);
const auto cmd =
MakeCommand(uint8_t(int(Status::NoteOn) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(velocity & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 3);
const auto cmd =
MakeCommand(uint8_t(int(Status::NotePressure) | (chan & 0xf)), uint8_t(key & 0x7f), uint8_t(pressure & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 3);
const auto cmd =
MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(control & 0x7f), uint8_t(value & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 2);
const auto cmd = MakeCommand(uint8_t(int(Status::ProgramChange) | (chan & 0xf)), uint8_t(program & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 2);
const auto cmd = MakeCommand(uint8_t(int(Status::ChannelPressure) | (chan & 0xf)), uint8_t(pressure & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
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),
uint8_t((pitch / 128) & 0x7f)};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::PitchBend) | (chan & 0xf)), uint8_t((pitch % 128) & 0x7f),
uint8_t((pitch / 128) & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::allSoundOff(uint8_t chan) {
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 120, 0};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{120}, uint8_t{0});
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::resetAllControllers(uint8_t chan) {
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 121, 0};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{121}, uint8_t{0});
_sendMessage(cmd);
}
template <class Sender>
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)};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{122}, uint8_t(on ? 127 : 0));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::allNotesOff(uint8_t chan) {
uint8_t cmd[3] = {uint8_t(int(Status::ControlChange) | (chan & 0xf)), 123, 0};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t{123}, uint8_t{0});
_sendMessage(cmd);
}
template <class Sender>
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};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 125 : 124), uint8_t{0});
_sendMessage(cmd);
}
template <class Sender>
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};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::ControlChange) | (chan & 0xf)), uint8_t(on ? 127 : 126), uint8_t{0});
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::sysex(const void* data, size_t len) {
uint8_t cmd = uint8_t(Status::SysEx);
_sendMessage(&cmd, 1);
constexpr auto sysexCmd = MakeCommand(uint8_t(Status::SysEx));
_sendMessage(sysexCmd);
_sendContinuedValue(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>
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))};
_sendMessage(cmd, 2);
const auto cmd =
MakeCommand(uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t((message & 0x7 << 4) | (value & 0xf)));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::songPositionPointer(uint16_t pointer) {
uint8_t cmd[3] = {uint8_t(int(Status::SongPositionPointer)), uint8_t((pointer % 128) & 0x7f),
uint8_t((pointer / 128) & 0x7f)};
_sendMessage(cmd, 3);
const auto cmd = MakeCommand(uint8_t(int(Status::SongPositionPointer)), uint8_t((pointer % 128) & 0x7f),
uint8_t((pointer / 128) & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::songSelect(uint8_t song) {
uint8_t cmd[2] = {uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t(song & 0x7f)};
_sendMessage(cmd, 2);
const auto cmd = MakeCommand(uint8_t(int(Status::TimecodeQuarterFrame)), uint8_t(song & 0x7f));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::tuneRequest() {
uint8_t cmd = uint8_t(Status::TuneRequest);
_sendMessage(&cmd, 1);
constexpr auto cmd = MakeCommand(uint8_t(Status::TuneRequest));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::startSeq() {
uint8_t cmd = uint8_t(Status::Start);
_sendMessage(&cmd, 1);
constexpr auto cmd = MakeCommand(uint8_t(Status::Start));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::continueSeq() {
uint8_t cmd = uint8_t(Status::Continue);
_sendMessage(&cmd, 1);
constexpr auto cmd = MakeCommand(uint8_t(Status::Continue));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::stopSeq() {
uint8_t cmd = uint8_t(Status::Stop);
_sendMessage(&cmd, 1);
constexpr auto cmd = MakeCommand(uint8_t(Status::Stop));
_sendMessage(cmd);
}
template <class Sender>
void MIDIEncoder<Sender>::reset() {
uint8_t cmd = uint8_t(Status::Reset);
_sendMessage(&cmd, 1);
constexpr auto cmd = MakeCommand(uint8_t(Status::Reset));
_sendMessage(cmd);
}
template class MIDIEncoder<IMIDIOut>;

View File

@ -1,8 +1,9 @@
#include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include "boo/boo.hpp"
#include "LinuxMidi.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include "boo/boo.hpp"
#include "lib/audiodev/LinuxMidi.hpp"
#include <logvisor/logvisor.hpp>
#include <pulse/pulseaudio.h>
#include <unistd.h>
@ -154,7 +155,7 @@ struct PulseAudioVoiceEngine : LinuxMidi {
m_mainloop = nullptr;
}
~PulseAudioVoiceEngine() {
~PulseAudioVoiceEngine() override {
if (m_stream) {
pa_stream_disconnect(m_stream);
pa_stream_unref(m_stream);
@ -270,7 +271,7 @@ struct PulseAudioVoiceEngine : LinuxMidi {
if (i)
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);
_paIterate(op);
pa_operation_unref(op);
@ -279,14 +280,14 @@ struct PulseAudioVoiceEngine : LinuxMidi {
return ret;
}
std::string getCurrentAudioOutput() const { return m_sinkName; }
std::string getCurrentAudioOutput() const override { return m_sinkName; }
bool m_sinkOk = false;
static void _checkAudioSinkReply(pa_context* c, const pa_sink_info* i, int eol, PulseAudioVoiceEngine* userdata) {
if (i)
userdata->m_sinkOk = true;
}
bool setCurrentAudioOutput(const char* name) {
bool setCurrentAudioOutput(const char* name) override {
m_sinkOk = false;
pa_operation* op;
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) {
/* Dummy pump mode - use failsafe defaults for 1/60sec of samples */
m_mixInfo.m_sampleRate = 32000.0;

View File

@ -1,23 +1,25 @@
#include "../win/Win32Common.hpp"
#include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include "lib/win/Win32Common.hpp"
#include <iterator>
#include "boo/IApplication.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <Mmdeviceapi.h>
#include <Audioclient.h>
#include <mmsystem.h>
#include <Functiondiscoverykeys_devpkey.h>
#include <iterator>
#include <logvisor/logvisor.hpp>
#ifdef TE_VIRTUAL_MIDI
#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 flags);
typedef void(CALLBACK* pfnvirtualMIDIClosePort)(LPVM_MIDI_PORT midiPort);
typedef BOOL(CALLBACK* pfnvirtualMIDISendData)(LPVM_MIDI_PORT midiPort, LPBYTE midiDataBytes, DWORD length);
typedef LPCWSTR(CALLBACK* pfnvirtualMIDIGetDriverVersion)(PWORD major, PWORD minor, PWORD release, PWORD build);
using pfnvirtualMIDIClosePort = void(CALLBACK*)(LPVM_MIDI_PORT midiPort);
using pfnvirtualMIDISendData = BOOL(CALLBACK*)(LPVM_MIDI_PORT midiPort, LPBYTE midiDataBytes, DWORD length);
using pfnvirtualMIDIGetDriverVersion = LPCWSTR(CALLBACK*)(PWORD major, PWORD minor, PWORD release, PWORD build);
static pfnvirtualMIDICreatePortEx2 virtualMIDICreatePortEx2PROC = nullptr;
static pfnvirtualMIDIClosePort virtualMIDIClosePortPROC = nullptr;
static pfnvirtualMIDISendData virtualMIDISendDataPROC = nullptr;
@ -38,9 +40,9 @@ namespace boo {
static logvisor::Module Log("boo::WASAPI");
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) { \
if ((punk) != nullptr) { \
(punk)->Release(); \
(punk) = NULL; \
(punk) = nullptr; \
}
struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
@ -70,11 +72,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
// IUnknown methods -- AddRef, Release, and QueryInterface
ULONG STDMETHODCALLTYPE AddRef() {
ULONG STDMETHODCALLTYPE AddRef() override {
return InterlockedIncrement(&_cRef);
}
ULONG STDMETHODCALLTYPE Release() {
ULONG STDMETHODCALLTYPE Release() override {
ULONG ulRef = InterlockedDecrement(&_cRef);
if (0 == ulRef) {
delete this;
@ -82,7 +84,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return ulRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface) {
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface) override {
if (IID_IUnknown == riid) {
AddRef();
*ppvInterface = (IUnknown*)this;
@ -90,7 +92,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
AddRef();
*ppvInterface = (IMMNotificationClient*)this;
} else {
*ppvInterface = NULL;
*ppvInterface = nullptr;
return E_NOINTERFACE;
}
return S_OK;
@ -98,18 +100,20 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
// 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;
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;
#endif
@ -117,7 +121,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#if !WINDOWS_STORE
if (!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();
return;
}
@ -200,7 +204,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
chMapOut.m_channels[7] = AudioChannel::SideRight;
break;
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_channels[0] = AudioChannel::FrontLeft;
chMapOut.m_channels[1] = AudioChannel::FrontRight;
@ -301,7 +305,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
AddRef();
*ppvInterface = (IActivateAudioInterfaceCompletionHandler*)this;
} else {
*ppvInterface = NULL;
*ppvInterface = nullptr;
return E_NOINTERFACE;
}
return S_OK;
@ -386,7 +390,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
_resetSampleRate();
}
void pumpAndMixVoices() {
void pumpAndMixVoices() override {
#if WINDOWS_STORE
if (!m_ready)
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;
if (FAILED(m_enumerator->GetDevice(MBSTWCS(name).c_str(), &newDevice))) {
Log.report(logvisor::Error, fmt("unable to obtain audio device {}"), name);
@ -477,7 +481,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
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;
ComPtr<IMMDeviceCollection> collection;
@ -507,7 +511,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
}
#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;
UINT numInDevices = midiInGetNumDevs();
@ -547,7 +551,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
bool supportsVirtualMIDIIn() const {
bool supportsVirtualMIDIIn() const override {
#ifdef TE_VIRTUAL_MIDI
WORD major, minor, release, build;
return virtualMIDIGetDriverVersionPROC &&
@ -588,9 +592,9 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
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 {
@ -598,11 +602,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
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;
}
};
@ -613,11 +617,11 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
VMIDIInOut(WASAPIAudioVoiceEngine* parent, ReceiveFunctor&& 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;
}
};
@ -628,9 +632,9 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
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;
midiInGetID(m_midi, &id);
MIDIINCAPS caps;
@ -661,16 +665,16 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_hdr.dwBufferLength = 512;
m_hdr.dwFlags = MHDR_ISSTRM;
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);
midiOutUnprepareHeader(m_midi, &m_hdr, sizeof(m_hdr));
midiOutClose(m_midi);
}
std::string description() const {
std::string description() const override {
UINT id = 0;
midiOutGetID(m_midi, &id);
MIDIOUTCAPS caps;
@ -684,7 +688,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#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)));
const_cast<MIDIOut*>(this)->m_hdr.dwBytesRecorded = len;
midiStreamOut(m_strm, LPMIDIHDR(&m_hdr), sizeof(m_hdr));
@ -710,17 +714,17 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_hdr.dwBufferLength = 512;
m_hdr.dwFlags = MHDR_ISSTRM;
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);
midiStreamClose(m_strm);
midiOutUnprepareHeader(m_midiOut, &m_hdr, sizeof(m_hdr));
midiOutClose(m_midiOut);
}
std::string description() const {
std::string description() const override {
UINT id = 0;
midiOutGetID(m_midiOut, &id);
MIDIOUTCAPS caps;
@ -734,7 +738,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#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)));
const_cast<MIDIHDR&>(m_hdr).dwBytesRecorded = len;
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
if (!virtualMIDICreatePortEx2PROC)
return {};
@ -764,7 +768,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#endif
}
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() {
std::unique_ptr<IMIDIOut> newVirtualMIDIOut() override {
#ifdef TE_VIRTUAL_MIDI
if (!virtualMIDICreatePortEx2PROC)
return {};
@ -785,7 +789,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#endif
}
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) {
std::unique_ptr<IMIDIInOut> newVirtualMIDIInOut(ReceiveFunctor&& receiver) override {
#ifdef TE_VIRTUAL_MIDI
if (!virtualMIDICreatePortEx2PROC)
return {};
@ -807,7 +811,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
#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))
return {};
long id = strtol(name + 2, nullptr, 10);
@ -824,7 +828,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return ret;
}
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) {
std::unique_ptr<IMIDIOut> newRealMIDIOut(const char* name) override {
if (strncmp(name, "out", 3))
return {};
long id = strtol(name + 3, nullptr, 10);
@ -833,14 +837,14 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
if (!ret)
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 {};
static_cast<MIDIOut&>(*ret).prepare();
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* out = strstr(name, "out");
@ -859,28 +863,28 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return {};
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 {};
static_cast<MIDIInOut&>(*ret).prepare();
return ret;
}
bool useMIDILock() const { return true; }
bool useMIDILock() const override { return true; }
#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; }
#endif

View File

@ -1,6 +1,9 @@
#include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include "lib/audiodev/AudioVoiceEngine.hpp"
#include <cstdio>
#include "boo/audiodev/IAudioVoiceEngine.hpp"
#include <logvisor/logvisor.hpp>
namespace boo {
@ -11,15 +14,17 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
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;
@ -27,26 +32,26 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
MIDIIn(WAVOutVoiceEngine* parent, bool virt, ReceiveFunctor&& 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));
m_midiReceiver = &ret->m_receiver;
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;
size_t m_bytesWritten = 0;
@ -207,7 +212,7 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
fclose(m_fp);
}
~WAVOutVoiceEngine() { finishWav(); }
~WAVOutVoiceEngine() override { finishWav(); }
void _buildAudioRenderClient() {
m_5msFrames = m_mixInfo.m_sampleRate * 5 / 1000;
@ -221,7 +226,7 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
_resetSampleRate();
}
void pumpAndMixVoices() {
void pumpAndMixVoices() override {
size_t frameSz = 4 * m_mixInfo.m_channelMap.m_channelCount;
_pumpAndMixVoices(m_5msFrames, m_interleavedBuf.data());
fwrite(m_interleavedBuf.data(), 1, m_5msFrames * frameSz, m_fp);

View File

@ -3,17 +3,18 @@
/* Private header for managing shader data
* binding lifetimes through rendering cycle */
#include <array>
#include <atomic>
#include <vector>
#include <mutex>
#include <cassert>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "../Common.hpp"
#include "lib/Common.hpp"
namespace boo {
@ -63,9 +64,6 @@ struct BaseGraphicsData : ListNode<BaseGraphicsData, GraphicsDataFactoryHead*> {
auto* head = getHead<T>();
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)
: ListNode<BaseGraphicsData, GraphicsDataFactoryHead*>(&head) __BooTraceInitializer {}
@ -131,9 +129,6 @@ struct BaseGraphicsPool : ListNode<BaseGraphicsPool, GraphicsDataFactoryHead*> {
auto* head = getHead<T>();
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)
: 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};
}
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)
: ListNode<GraphicsDataNode<NodeCls, DataCls>, ObjToken<DataCls>, NodeCls>(data) {}
@ -249,7 +240,7 @@ public:
m_backcv.wait(lk, [this]() { return m_outstandingTasks == 0 || !m_running; });
}
bool isReady() {
bool isReady() const {
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

View File

@ -1,5 +1,5 @@
#include "boo/graphicsdev/glxew.h"
#include "logvisor/logvisor.hpp"
#include <logvisor/logvisor.hpp>
namespace boo {
static logvisor::Module Log("boo::GLX");

View File

@ -1,16 +1,17 @@
#include "../mac/CocoaCommon.hpp"
#include "lib/mac/CocoaCommon.hpp"
#if BOO_HAS_METAL
#include "logvisor/logvisor.hpp"
#include "boo/IApplication.hpp"
#include "boo/graphicsdev/Metal.hpp"
#include "boo/IGraphicsContext.hpp"
#include "Common.hpp"
#include <vector>
#include "boo/graphicsdev/Metal.hpp"
#include "lib/graphicsdev/Common.hpp"
#include <unordered_map>
#include <unordered_set>
#include "xxhash/xxhash.h"
#include <vector>
#include <logvisor/logvisor.hpp>
#if !__has_feature(objc_arc)
#error ARC Required
@ -848,11 +849,13 @@ class MetalShaderStage : public GraphicsDataNode<IShaderStage> {
shaderLib = [ctx->m_dev newLibraryWithSource:@((const char*) (data + 1))
options:compOpts
error:&err];
if (!shaderLib)
if (!shaderLib) {
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;
switch (stage) {
@ -969,9 +972,10 @@ protected:
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
NSError* err = nullptr;
m_state = [ctx->m_dev newRenderPipelineStateWithDescriptor:desc error:&err];
if (err)
Log.report(logvisor::Fatal, fmt("error making shader pipeline: %s"),
if (err) {
Log.report(logvisor::Fatal, fmt("error making shader pipeline: {}"),
[[err localizedDescription] UTF8String]);
}
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
switch (info.depthTest) {
@ -1043,9 +1047,10 @@ class MetalTessellationShaderPipeline : public MetalShaderPipeline {
NSError* err = nullptr;
m_computeState = [ctx->m_dev newComputePipelineStateWithDescriptor:compDesc options:MTLPipelineOptionNone
reflection:nil error:&err];
if (err)
Log.report(logvisor::Fatal, fmt("error making compute pipeline: %s"),
if (err) {
Log.report(logvisor::Fatal, fmt("error making compute pipeline: {}"),
[[err localizedDescription] UTF8String]);
}
}
void draw(MetalCommandQueue& q, size_t start, size_t count);
@ -1147,9 +1152,10 @@ struct MetalShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
m_ubufOffs.reserve(ubufCount);
for (size_t i = 0; i < ubufCount; ++i) {
#ifndef NDEBUG
if (ubufOffs[i] % 256)
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding"),
int(i));
if (ubufOffs[i] % 256) {
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset {} provided to newShaderDataBinding"),
i);
}
#endif
m_ubufOffs.push_back(ubufOffs[i]);
}
@ -1157,8 +1163,9 @@ struct MetalShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
m_ubufs.reserve(ubufCount);
for (size_t i = 0; i < ubufCount; ++i) {
#ifndef NDEBUG
if (!ubufs[i])
Log.report(logvisor::Fatal, fmt("null uniform-buffer %d provided to newShaderDataBinding"), int(i));
if (!ubufs[i]) {
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), i);
}
#endif
m_ubufs.push_back(ubufs[i]);
}
@ -2005,7 +2012,6 @@ void MetalDataFactoryImpl::SetupGammaResources() {
ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()};
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {},
0, nullptr, nullptr, 2, texs, nullptr, nullptr);
return true;
} BooTrace);
}

View File

@ -1,15 +1,18 @@
#include "boo/graphicsdev/Vulkan.hpp"
#include "boo/IGraphicsContext.hpp"
#include <vector>
#include <array>
#include <cmath>
#include <vector>
#include <glslang/Public/ShaderLang.h>
#include <StandAlone/ResourceLimits.h>
#include <SPIRV/GlslangToSpv.h>
#include <SPIRV/disassemble.h>
#include "boo/IGraphicsContext.hpp"
#include "boo/graphicsdev/GLSLMacros.hpp"
#include "Common.hpp"
#include "xxhash/xxhash.h"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "lib/graphicsdev/Common.hpp"
#define AMD_PAL_HACK 1
@ -17,7 +20,7 @@
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#include "vk_mem_alloc.h"
#include "logvisor/logvisor.hpp"
#include <logvisor/logvisor.hpp>
#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) {
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = NULL;
imageMemoryBarrier.pNext = nullptr;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = 0;
imageMemoryBarrier.oldLayout = old_image_layout;
@ -261,7 +264,7 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image, VkImageAspectFlag
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) {
@ -1060,9 +1063,6 @@ struct VulkanDescriptorPool : ListNode<VulkanDescriptorPool, VulkanDataFactoryIm
~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) {
return std::unique_lock<std::recursive_mutex>{factory->m_dataMutex};
}
@ -2668,9 +2668,10 @@ struct VulkanShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
m_ubufOffs.reserve(ubufCount);
for (size_t i = 0; i < ubufCount; ++i) {
#ifndef NDEBUG
if (ubufOffs[i] % 256)
if (ubufOffs[i] % 256) {
Log.report(logvisor::Fatal, fmt("non-256-byte-aligned uniform-offset {} provided to newShaderDataBinding"),
int(i));
i);
}
#endif
std::array<VkDescriptorBufferInfo, 2> fillArr;
fillArr.fill({VK_NULL_HANDLE, ubufOffs[i], (ubufSizes[i] + 255) & ~255});
@ -2680,8 +2681,9 @@ struct VulkanShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
m_ubufs.reserve(ubufCount);
for (size_t i = 0; i < ubufCount; ++i) {
#ifndef NDEBUG
if (!ubufs[i])
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), int(i));
if (!ubufs[i]) {
Log.report(logvisor::Fatal, fmt("null uniform-buffer {} provided to newShaderDataBinding"), i);
}
#endif
m_ubufs.push_back(ubufs[i]);
}

View File

@ -1,9 +1,13 @@
#include "logvisor/logvisor.hpp"
#include "boo/graphicsdev/NX.hpp"
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include "boo/IGraphicsContext.hpp"
#include "boo/graphicsdev/GLSLMacros.hpp"
#include "../Common.hpp"
#include "xxhash/xxhash.h"
#include "lib/graphicsdev/Common.hpp"
#include "main/shaderobj.h"
#include "st_program.h"
@ -19,6 +23,9 @@ extern "C" {
#include "gallium/winsys/nouveau/switch/nouveau_switch_public.h"
}
#include <logvisor/logvisor.hpp>
#include <xxhash/xxhash.h>
#include <switch.h>
namespace boo {
@ -1801,7 +1808,7 @@ bool NXContext::initialize() {
gfxInitDefault();
gfxSetMode(GfxMode_TiledDouble);
consoleInit(NULL);
consoleInit(nullptr);
printf("Activated console\n\n");
m_screen = nouveau_switch_screen_create();
if (!m_screen) {

View File

@ -1,7 +1,6 @@
#include "boo/inputdev/DeviceBase.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "IHIDDevice.hpp"
#include <cstdarg>
#include "lib/inputdev/IHIDDevice.hpp"
namespace boo {
@ -37,25 +36,25 @@ size_t DeviceBase::receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
return false;
}
unsigned DeviceBase::getVendorId() {
unsigned DeviceBase::getVendorId() const {
if (m_token)
return m_token->getVendorId();
return -1;
}
unsigned DeviceBase::getProductId() {
unsigned DeviceBase::getProductId() const {
if (m_token)
return m_token->getProductId();
return -1;
}
std::string_view DeviceBase::getVendorName() {
std::string_view DeviceBase::getVendorName() const {
if (m_token)
return m_token->getVendorName();
return {};
}
std::string_view DeviceBase::getProductName() {
std::string_view DeviceBase::getProductName() const {
if (m_token)
return m_token->getProductName();
return {};
@ -63,14 +62,14 @@ std::string_view DeviceBase::getProductName() {
#if _WIN32
#if !WINDOWS_STORE
const PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() {
PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() const {
if (m_hidDev)
return m_hidDev->_getReportDescriptor();
return {};
}
#endif
#else
std::vector<uint8_t> DeviceBase::getReportDescriptor() {
std::vector<uint8_t> DeviceBase::getReportDescriptor() const {
if (m_hidDev)
return m_hidDev->_getReportDescriptor();
return {};

View File

@ -1,5 +1,8 @@
#include "boo/inputdev/DeviceFinder.hpp"
#include <cstdio>
#include <cstdlib>
#if _WIN32
#include <Dbt.h>
#include <hidclass.h>
@ -10,6 +13,79 @@ namespace boo {
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
/* Windows-specific WM_DEVICECHANGED handler */
LRESULT DeviceFinder::winDevChangedHandler(WPARAM wParam, LPARAM lParam) {

View File

@ -1,7 +1,7 @@
#include "boo/inputdev/DeviceSignature.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/GenericPad.hpp"
#include "IHIDDevice.hpp"
#include "lib/inputdev/IHIDDevice.hpp"
namespace boo {

View File

@ -1,5 +1,6 @@
#include "boo/inputdev/DolphinSmashAdapter.hpp"
#include "boo/inputdev/DeviceSignature.hpp"
#include <cstdio>
#include <cstring>
@ -54,7 +55,7 @@ void DolphinSmashAdapter::transferCycle() {
if (recvSz != 37 || payload[0] != 0x21)
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);
if (!m_callback)

View File

@ -1,10 +1,11 @@
#include "boo/inputdev/DualshockPad.hpp"
#include "boo/inputdev/DeviceSignature.hpp"
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <cstring>
#include <iostream>
#ifdef _MSC_VER
inline uint16_t bswap16(uint16_t val) { return _byteswap_ushort(val); }
@ -42,16 +43,20 @@ void DualshockPad::deviceDisconnected() {
void DualshockPad::initialCycle() {
#if 0
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4))
{
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++)
m_btAddress[5 - i] = btAddr[i + 2]; // Copy into buffer reversed, so it is LSB first
// Tells controller to start sending changes on in pipe
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00};
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4)) {
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++) {
// Copy into buffer reversed, so it is LSB first
m_btAddress[5 - i] = btAddr[i + 2];
}
#endif
}

View File

@ -8,13 +8,12 @@ class HIDListenerBSD final : public IHIDListener {
public:
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 stopScanning() { return false; }
bool scanNow() { return false; }
bool scanNow() override { return false; }
};
IHIDListener* IHIDListenerNew(DeviceFinder& finder) { return new HIDListenerBSD(finder); }

View File

@ -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/IOHIDDevicePlugin.h>
#include <IOKit/usb/IOUSBLib.h>
#include "IOKitPointer.hpp"
#include <thread>
namespace boo {
@ -23,7 +26,7 @@ class HIDDeviceIOKit : public IHIDDevice {
std::condition_variable m_initCond;
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) {
IOReturn res = m_usbIntf->WritePipe(m_usbIntf.storage(), m_usbIntfOutPipe, (void*)data, length);
return res == kIOReturnSuccess;
@ -31,7 +34,7 @@ class HIDDeviceIOKit : public IHIDDevice {
return false;
}
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
if (m_usbIntf) {
UInt32 readSize = length;
IOReturn res = m_usbIntf->ReadPipe(m_usbIntf.storage(), m_usbIntfInPipe, data, &readSize);
@ -42,7 +45,7 @@ class HIDDeviceIOKit : public IHIDDevice {
return 0;
}
std::vector<uint8_t> _getReportDescriptor() {
std::vector<uint8_t> _getReportDescriptor() override {
if (m_hidIntf) {
if (CFTypeRef desc = IOHIDDeviceGetProperty(m_hidIntf.get(), CFSTR(kIOHIDReportDescriptorKey))) {
CFIndex len = CFDataGetLength(CFDataRef(desc));
@ -54,7 +57,7 @@ class HIDDeviceIOKit : public IHIDDevice {
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
* USB driver appears to work correctly */
if (m_hidIntf && !m_isBt) {
@ -64,7 +67,7 @@ class HIDDeviceIOKit : public IHIDDevice {
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) {
CFIndex readSize = length;
IOReturn res = IOHIDDeviceGetReport(m_hidIntf.get(), IOHIDReportType(tp), message, data, &readSize);
@ -273,13 +276,13 @@ class HIDDeviceIOKit : public IHIDDevice {
device->m_hidIntf.reset();
}
void _deviceDisconnected() { m_runningTransferLoop = false; }
void _deviceDisconnected() override { m_runningTransferLoop = false; }
public:
HIDDeviceIOKit(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
void _startThread() {
void _startThread() override {
std::unique_lock<std::mutex> lk(m_initMutex);
DeviceType dType = m_token.getDeviceType();
if (dType == DeviceType::USB)
@ -295,7 +298,7 @@ public:
m_initCond.wait(lk);
}
~HIDDeviceIOKit() {
~HIDDeviceIOKit() override {
m_runningTransferLoop = false;
if (m_thread.joinable())
m_thread.detach();

View File

@ -1,4 +1,4 @@
#include "IHIDDevice.hpp"
#include "lib/inputdev/IHIDDevice.hpp"
namespace boo {
@ -11,13 +11,13 @@ public:
HIDDeviceNX(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
void _deviceDisconnected() {}
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
std::vector<uint8_t> _getReportDescriptor() { return {}; }
bool _sendHIDReport(const 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) { return 0; }
void _startThread() {}
void _deviceDisconnected() override {}
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override { return 0; }
std::vector<uint8_t> _getReportDescriptor() override { return {}; }
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) override { return 0; }
void _startThread() override {}
};
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {

View File

@ -1,5 +1,7 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "IHIDDevice.hpp"
#include "lib/inputdev/IHIDDevice.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/DeviceBase.hpp"
@ -9,12 +11,12 @@ class HIDDeviceUWP : public IHIDDevice {
public:
HIDDeviceUWP(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {}
void _deviceDisconnected() {}
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
bool _sendHIDReport(const 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) { return false; }
void _startThread() {}
void _deviceDisconnected() override {}
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
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) override { return false; }
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
void _startThread() override {}
};
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {

View File

@ -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/DeviceBase.hpp"
#include <thread>
#include <mutex>
#include <condition_variable>
#include "boo/inputdev/HIDParser.hpp"
#include <cstdio>
#include <fcntl.h>
#include <libudev.h>
#include <stropts.h>
#include <linux/usb/ch9.h>
#include <linux/usbdevice_fs.h>
#include <linux/input.h>
#include <linux/hidraw.h>
#include <fcntl.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <cstring>
#include "boo/inputdev/HIDParser.hpp"
namespace boo {
@ -40,7 +42,7 @@ class HIDDeviceUdev final : public IHIDDevice {
std::condition_variable m_initCond;
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) {
usbdevfs_bulktransfer xfer = {m_usbIntfOutPipe | USB_DIR_OUT, (unsigned)length, 30, (void*)data};
int ret = ioctl(m_devFd, USBDEVFS_BULK, &xfer);
@ -51,7 +53,7 @@ class HIDDeviceUdev final : public IHIDDevice {
return false;
}
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
if (m_devFd) {
usbdevfs_bulktransfer xfer = {m_usbIntfInPipe | USB_DIR_IN, (unsigned)length, 30, data};
return ioctl(m_devFd, USBDEVFS_BULK, &xfer);
@ -102,7 +104,7 @@ class HIDDeviceUdev final : public IHIDDevice {
}
/* 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);
/* Return control to main thread */
@ -209,9 +211,9 @@ class HIDDeviceUdev final : public IHIDDevice {
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 */
int reportDescSize;
if (ioctl(m_devFd, HIDIOCGRDESCSIZE, &reportDescSize) == -1)
@ -227,7 +229,7 @@ class HIDDeviceUdev final : public IHIDDevice {
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 (tp == HIDReportType::Feature) {
int ret = ioctl(m_devFd, HIDIOCSFEATURE(length), data);
@ -244,7 +246,7 @@ class HIDDeviceUdev final : public IHIDDevice {
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 (tp == HIDReportType::Feature) {
data[0] = message;
@ -261,7 +263,7 @@ public:
HIDDeviceUdev(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
void _startThread() {
void _startThread() override {
std::unique_lock<std::mutex> lk(m_initMutex);
DeviceType dType = m_token.getDeviceType();
if (dType == DeviceType::USB)
@ -277,7 +279,7 @@ public:
m_initCond.wait(lk);
}
~HIDDeviceUdev() {
~HIDDeviceUdev() override {
m_runningTransferLoop = false;
if (m_thread.joinable())
m_thread.detach();

View File

@ -1,13 +1,15 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "IHIDDevice.hpp"
#include "lib/inputdev/IHIDDevice.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/DeviceBase.hpp"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <condition_variable>
#include <cstdio>
#include <cstring>
#include <mutex>
#include <thread>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
@ -27,8 +29,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
DeviceToken& m_token;
std::shared_ptr<DeviceBase> m_devImp;
HANDLE m_devHandle = 0;
HANDLE m_hidHandle = 0;
HANDLE m_devHandle = nullptr;
HANDLE m_hidHandle = nullptr;
WINUSB_INTERFACE_HANDLE m_usbHandle = nullptr;
unsigned m_usbIntfInPipe = 0;
unsigned m_usbIntfOutPipe = 0;
@ -39,21 +41,22 @@ class HIDDeviceWinUSB final : public IHIDDevice {
std::condition_variable m_initCond;
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) {
ULONG lengthTransferred = 0;
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, NULL) ||
lengthTransferred != length)
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, nullptr) ||
lengthTransferred != length) {
return false;
}
return true;
}
return false;
}
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
if (m_usbHandle) {
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 lengthTransferred;
}
@ -66,8 +69,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
/* POSIX.. who needs it?? -MS */
device->m_devHandle =
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 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, nullptr);
if (INVALID_HANDLE_VALUE == device->m_devHandle) {
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
device->m_token.getProductName(), device->m_devPath, GetLastError());
@ -150,8 +153,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
/* POSIX.. who needs it?? -MS */
device->m_overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
device->m_hidHandle =
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 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, nullptr);
if (INVALID_HANDLE_VALUE == device->m_hidHandle) {
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
device->m_token.getProductName(), device->m_devPath, GetLastError());
@ -199,14 +202,14 @@ class HIDDeviceWinUSB final : public IHIDDevice {
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_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));
if (m_sendBuf.size() < maxOut)
m_sendBuf.resize(maxOut);
@ -250,7 +253,7 @@ class HIDDeviceWinUSB final : public IHIDDevice {
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));
if (m_recvBuf.size() < maxIn)
m_recvBuf.resize(maxIn);
@ -273,7 +276,7 @@ public:
HIDDeviceWinUSB(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
void _startThread() {
void _startThread() override {
std::unique_lock<std::mutex> lk(m_initMutex);
DeviceType dType = m_token.getDeviceType();
if (dType == DeviceType::USB)
@ -287,7 +290,7 @@ public:
m_initCond.wait(lk);
}
~HIDDeviceWinUSB() {
~HIDDeviceWinUSB() override {
m_runningTransferLoop = false;
if (m_thread.joinable())
m_thread.detach();

View File

@ -16,8 +16,7 @@ class HIDDeviceBSD final : public IHIDDevice {
public:
HIDDeviceBSD(DeviceToken& token, DeviceBase& devImp) : m_token(token), m_devImp(devImp) {}
~HIDDeviceBSD() {}
~HIDDeviceBSD() override = default;
};
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {

View File

@ -108,7 +108,7 @@ class HIDListenerIOKit : public IHIDListener {
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)
continue;
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));
// 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)
continue;
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;
}
~HIDListenerIOKit() {
~HIDListenerIOKit() override {
// CFRunLoopRemoveSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
IONotificationPortDestroy(m_llPort);
}
/* Automatic device scanning */
bool startScanning() {
bool startScanning() override {
m_scanningEnabled = true;
return true;
}
bool stopScanning() {
bool stopScanning() override {
m_scanningEnabled = false;
return true;
}
/* Manual device scanning */
bool scanNow() {
bool scanNow() override {
IOObjectPointer<io_iterator_t> iter;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(m_usbClass), &iter) == kIOReturnSuccess) {
devicesConnectedUSBLL(this, iter.get());

View File

@ -8,9 +8,9 @@ class HIDListenerNX : public IHIDListener {
public:
HIDListenerNX(DeviceFinder& finder) : m_finder(finder) {}
bool startScanning() { return false; }
bool stopScanning() { return false; }
bool scanNow() { return false; }
bool startScanning() override { return false; }
bool stopScanning() override { return false; }
bool scanNow() override { return false; }
};
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerNX>(finder); }

View File

@ -1,4 +1,5 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "boo/inputdev/IHIDListener.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
@ -9,11 +10,11 @@ public:
HIDListenerUWP(DeviceFinder& finder) {}
/* Automatic device scanning */
bool startScanning() { return false; }
bool stopScanning() { return false; }
bool startScanning() override { return false; }
bool stopScanning() override { return false; }
/* 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); }

View File

@ -118,14 +118,14 @@ class HIDListenerUdev final : public IHIDListener {
}
#if 0
udev_list_entry* att = nullptr;
udev_list_entry_foreach(att, attrs)
{
const char* name = udev_list_entry_get_name(att);
const char* val = udev_list_entry_get_value(att);
fprintf(stderr, "%s %s\n", name, val);
}
fprintf(stderr, "\n\n");
udev_list_entry* att = nullptr;
udev_list_entry_foreach(att, attrs)
{
const char* name = udev_list_entry_get_name(att);
const char* val = udev_list_entry_get_value(att);
fmt::print(stderr, fmt("{} {}\n"), name, val);
}
std::fputs("\n\n", stderr);
#endif
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);
}
~HIDListenerUdev() {
~HIDListenerUdev() override {
pthread_cancel(m_udevThread.native_handle());
if (m_udevThread.joinable())
m_udevThread.join();
@ -195,17 +195,17 @@ public:
}
/* Automatic device scanning */
bool startScanning() {
bool startScanning() override {
m_scanningEnabled = true;
return true;
}
bool stopScanning() {
bool stopScanning() override {
m_scanningEnabled = false;
return true;
}
/* Manual device scanning */
bool scanNow() {
bool scanNow() override {
udev_enumerate* uenum = udev_enumerate_new(GetUdev());
udev_enumerate_add_match_subsystem(uenum, "usb");
udev_enumerate_add_match_subsystem(uenum, "bluetooth");

View File

@ -1,10 +1,13 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "boo/inputdev/IHIDListener.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include "boo/inputdev/XInputPad.hpp"
#include <cstring>
#include <thread>
#include "boo/inputdev/DeviceFinder.hpp"
#include "boo/inputdev/XInputPad.hpp"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#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];
/* 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)
return;
for (i = 0;; ++i) {
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, TypeGUID, i, &DeviceInterfaceData))
if (!SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, TypeGUID, i, &DeviceInterfaceData))
break;
DeviceInterfaceDetailData.wtf.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetailA(hDevInfo, &DeviceInterfaceData, &DeviceInterfaceDetailData.wtf,
sizeof(DeviceInterfaceDetailData), NULL, &DeviceInfoData))
sizeof(DeviceInterfaceDetailData), nullptr, &DeviceInfoData))
continue;
r = CM_Get_Device_IDA(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
@ -73,7 +76,7 @@ class HIDListenerWinUSB final : public IHIDListener {
szVid[0] = '\0';
szPid[0] = '\0';
szMi[0] = '\0';
while (pszToken != NULL) {
while (pszToken != nullptr) {
for (j = 0; j < 3; ++j) {
if (strncmp(pszToken, arPrefix[j], 4) == 0) {
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])
continue;
unsigned vid = strtol(szVid + 4, NULL, 16);
unsigned pid = strtol(szPid + 4, NULL, 16);
unsigned vid = strtol(szVid + 4, nullptr, 16);
unsigned pid = strtol(szPid + 4, nullptr, 16);
CHAR productW[1024] = {0};
// CHAR product[1024] = {0};
@ -121,8 +124,8 @@ class HIDListenerWinUSB final : public IHIDListener {
if (type == DeviceType::HID) {
HANDLE devHnd = CreateFileA(DeviceInterfaceDetailData.wtf.DevicePath, GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
if (INVALID_HANDLE_VALUE == devHnd)
continue;
PHIDP_PREPARSED_DATA preparsedData;
@ -227,29 +230,29 @@ public:
}
}
~HIDListenerWinUSB() {
~HIDListenerWinUSB() override {
m_xinputRunning = false;
if (m_xinputThread.joinable())
m_xinputThread.join();
}
/* Automatic device scanning */
bool startScanning() {
bool startScanning() override {
m_scanningEnabled = true;
return true;
}
bool stopScanning() {
bool stopScanning() override {
m_scanningEnabled = false;
return true;
}
/* Manual device scanning */
bool scanNow() {
bool scanNow() override {
_pollDevices(nullptr);
return true;
}
bool _extDevConnect(const char* path) {
bool _extDevConnect(const char* path) override {
char upperPath[1024];
strcpy_s(upperPath, 1024, path);
CharUpperA(upperPath);
@ -258,7 +261,7 @@ public:
return true;
}
bool _extDevDisconnect(const char* path) {
bool _extDevDisconnect(const char* path) override {
char upperPath[1024];
strcpy_s(upperPath, 1024, path);
CharUpperA(upperPath);

View File

@ -1,6 +1,8 @@
#include "boo/inputdev/HIDParser.hpp"
#include <map>
#include <algorithm>
#include <array>
#include <map>
#undef min
#undef max
@ -11,251 +13,257 @@ namespace boo {
* http://www.usb.org/developers/hidpage/HID1_11.pdf
*/
static const char* UsagePageNames[] = {"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
"Ordinal", "Telephony", "Consumer", "Digitizer"};
constexpr std::array<const char*, 14> UsagePageNames{
"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
"Ordinal", "Telephony", "Consumer", "Digitizer",
};
static const char* GenericDesktopUsages[] = {"Undefined",
"Pointer",
"Mouse",
"Reserved",
"Joystick",
"Game Pad",
"Keyboard",
"Keypad",
"Multi-axis Controller",
"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,
"X",
"Y",
"Z",
"Rx",
"Ry",
"Rz",
"Slider",
"Dial",
"Wheel",
"Hat Switch",
"Counted Buffer",
"Byte Count",
"Motion Wakeup",
"Start",
"Select",
"Reserved",
"Vx",
"Vy",
"Vz",
"Vbrx",
"Vbry",
"Vbrz",
"Vno",
"Feature Notification",
"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,
"System Control",
"System Power Down",
"System Sleep",
"System Wake Up",
"System Context Menu",
"System Main Menu",
"System App Menu",
"System Menu Help",
"System Menu Exit",
"System Menu Select",
"System Menu Right",
"System Menu Left",
"System Menu Up",
"System Menu Down",
"System Cold Restart",
"System Warm Restart",
"D-pad Up",
"D-pad Down",
"D-pad Right",
"D-pad Left",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
"System Dock",
"System Undock",
"System Setup",
"System Break",
"System Debugger Break",
"Application Break",
"Application Debugger Break",
"System Speaker Mute",
"System Hibernate",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
"System Display Invert",
"System Display Internal",
"System Display External",
"System Display Both",
"System Display Dual",
"System Display Toggle Int/Ext"};
constexpr std::array<const char*, 182> GenericDesktopUsages{
"Undefined",
"Pointer",
"Mouse",
"Reserved",
"Joystick",
"Game Pad",
"Keyboard",
"Keypad",
"Multi-axis Controller",
"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,
"X",
"Y",
"Z",
"Rx",
"Ry",
"Rz",
"Slider",
"Dial",
"Wheel",
"Hat Switch",
"Counted Buffer",
"Byte Count",
"Motion Wakeup",
"Start",
"Select",
"Reserved",
"Vx",
"Vy",
"Vz",
"Vbrx",
"Vbry",
"Vbrz",
"Vno",
"Feature Notification",
"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,
"System Control",
"System Power Down",
"System Sleep",
"System Wake Up",
"System Context Menu",
"System Main Menu",
"System App Menu",
"System Menu Help",
"System Menu Exit",
"System Menu Select",
"System Menu Right",
"System Menu Left",
"System Menu Up",
"System Menu Down",
"System Cold Restart",
"System Warm Restart",
"D-pad Up",
"D-pad Down",
"D-pad Right",
"D-pad Left",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
"System Dock",
"System Undock",
"System Setup",
"System Break",
"System Debugger Break",
"Application Break",
"Application Debugger Break",
"System Speaker Mute",
"System Hibernate",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
"System Display Invert",
"System Display Internal",
"System Display External",
"System Display Both",
"System Display Dual",
"System Display Toggle Int/Ext",
};
static const char* GameUsages[] = {"Undefined",
"3D Game Controller",
"Pinball Device",
"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,
"Point of View",
"Turn Right/Left",
"Pitch Forward/Backward",
"Roll Right/Left",
"Move Right/Left",
"Move Forward/Backward",
"Move Up/Down",
"Lean Right/Left",
"Lean Forward/Backward",
"Height of POV",
"Flipper",
"Secondary Flipper",
"Bump",
"New Game",
"Shoot Ball",
"Player",
"Gun Bolt",
"Gun Clip",
"Gun Selector",
"Gun Single Shot",
"Gun Burst",
"Gun Automatic",
"Gun Safety",
"Gemepad Fire/Jump",
nullptr,
"Gamepad Trigger"};
constexpr std::array<const char*, 58> GameUsages{
"Undefined",
"3D Game Controller",
"Pinball Device",
"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,
"Point of View",
"Turn Right/Left",
"Pitch Forward/Backward",
"Roll Right/Left",
"Move Right/Left",
"Move Forward/Backward",
"Move Up/Down",
"Lean Right/Left",
"Lean Forward/Backward",
"Height of POV",
"Flipper",
"Secondary Flipper",
"Bump",
"New Game",
"Shoot Ball",
"Player",
"Gun Bolt",
"Gun Clip",
"Gun Selector",
"Gun Single Shot",
"Gun Burst",
"Gun Automatic",
"Gun Safety",
"Gemepad Fire/Jump",
nullptr,
"Gamepad Trigger",
};
enum class HIDCollectionType : uint8_t {
Physical,
@ -380,21 +388,31 @@ HIDMainItem::HIDMainItem(uint32_t flags, HIDUsagePage usagePage, HIDUsage usage,
, m_reportSize(reportSize) {}
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 UsagePageNames[int(m_usagePage)];
}
return UsagePageNames[index];
}
const char* HIDMainItem::GetUsageName() const {
const auto index = size_t(m_usage);
switch (m_usagePage) {
case HIDUsagePage::GenericDesktop:
if (int(m_usage) >= std::extent<decltype(GenericDesktopUsages)>::value)
if (index >= GenericDesktopUsages.size()) {
return nullptr;
return GenericDesktopUsages[int(m_usage)];
}
return GenericDesktopUsages[index];
case HIDUsagePage::Game:
if (int(m_usage) >= std::extent<decltype(GameUsages)>::value)
if (index >= GameUsages.size()) {
return nullptr;
return GameUsages[int(m_usage)];
}
return GameUsages[index];
default:
return nullptr;
}
@ -443,17 +461,17 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
USHORT length = caps.NumberInputButtonCaps;
std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS());
HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData);
for (const HIDP_BUTTON_CAPS& caps : bCaps) {
if (caps.IsRange) {
int usage = caps.Range.UsageMin;
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
inputItems.insert(std::make_pair(
i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage), std::make_pair(0, 1), 1)));
for (const HIDP_BUTTON_CAPS& buttonCaps : bCaps) {
if (buttonCaps.IsRange) {
int usage = buttonCaps.Range.UsageMin;
for (int i = buttonCaps.Range.DataIndexMin; i <= buttonCaps.Range.DataIndexMax; ++i, ++usage) {
inputItems.emplace(i, HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage), HIDUsage(usage),
std::make_pair(0, 1), 1));
}
} else {
inputItems.insert(std::make_pair(caps.NotRange.DataIndex,
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage),
HIDUsage(caps.NotRange.Usage), std::make_pair(0, 1), 1)));
inputItems.emplace(buttonCaps.NotRange.DataIndex,
HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage),
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;
std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS());
HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData);
for (const HIDP_VALUE_CAPS& caps : vCaps) {
if (caps.IsRange) {
int usage = caps.Range.UsageMin;
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
inputItems.insert(
std::make_pair(i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage),
std::make_pair(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
for (const HIDP_VALUE_CAPS& valueCaps : vCaps) {
if (valueCaps.IsRange) {
int usage = valueCaps.Range.UsageMin;
for (int i = valueCaps.Range.DataIndexMin; i <= valueCaps.Range.DataIndexMax; ++i, ++usage) {
inputItems.emplace(i, HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage), HIDUsage(usage),
std::make_pair(valueCaps.LogicalMin, valueCaps.LogicalMax),
valueCaps.BitSize));
}
} else {
inputItems.insert(
std::make_pair(caps.NotRange.DataIndex,
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(caps.NotRange.Usage),
HIDRange(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
inputItems.emplace(valueCaps.NotRange.DataIndex,
HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage),
HIDUsage(valueCaps.NotRange.Usage),
HIDRange(valueCaps.LogicalMin, valueCaps.LogicalMax), valueCaps.BitSize));
}
}
}
@ -804,9 +822,9 @@ void HIDParser::ScanValues(const std::function<bool(const HIDMainItem& item, int
continue;
int32_t value = 0;
if (it != end) {
const HIDP_DATA& data = *it;
if (data.DataIndex == idx) {
value = data.RawValue;
const HIDP_DATA& hidData = *it;
if (hidData.DataIndex == idx) {
value = hidData.RawValue;
++it;
}
}

View File

@ -1,9 +1,10 @@
#pragma once
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/DeviceBase.hpp"
#include <memory>
#include "boo/inputdev/DeviceBase.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#if _WIN32
#include <hidsdi.h>
#endif

View File

@ -1,6 +1,6 @@
#pragma once
#include "../CFPointer.hpp"
#include "lib/CFPointer.hpp"
#include <IOKit/IOTypes.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>

View File

@ -1,6 +1,9 @@
#include "boo/inputdev/NintendoPowerA.hpp"
#include <cstring>
#include "boo/inputdev/DeviceSignature.hpp"
#include <memory.h>
namespace boo {
NintendoPowerA::NintendoPowerA(DeviceToken* 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) {}
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) {
return !memcmp(this, &other, sizeof(NintendoPowerAState));
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) const {
return memcmp(this, &other, sizeof(NintendoPowerAState)) == 0;
}
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) {
return memcmp(this, &other, sizeof(NintendoPowerAState));
}
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) const { return !operator==(other); }
} // namespace boo

View File

@ -1,12 +1,13 @@
#include <AppKit/AppKit.h>
#include <thread>
#include "boo/IApplication.hpp"
#include "boo/graphicsdev/Metal.hpp"
#include "CocoaCommon.hpp"
#include "../Common.hpp"
#include "lib/Common.hpp"
#include "lib/mac/CocoaCommon.hpp"
#include "logvisor/logvisor.hpp"
#include <logvisor/logvisor.hpp>
#if !__has_feature(objc_arc)
#error ARC Required
@ -110,7 +111,7 @@ public:
Log.report(logvisor::Info, fmt("using Metal renderer"));
}
EPlatformType getPlatformType() const {
EPlatformType getPlatformType() const override {
return EPlatformType::Cocoa;
}
@ -118,7 +119,7 @@ public:
int m_clientReturn = 0;
bool m_terminateNow = false;
int run() {
int run() override {
/* Spawn client thread */
m_clientThread = std::thread([&]() {
std::string thrName = std::string(getFriendlyName()) + " Client Thread";
@ -161,23 +162,23 @@ public:
[NSApp terminate:nil];
}
SystemStringView getUniqueName() const {
SystemStringView getUniqueName() const override {
return m_uniqueName;
}
SystemStringView getFriendlyName() const {
SystemStringView getFriendlyName() const override {
return m_friendlyName;
}
SystemStringView getProcessName() const {
SystemStringView getProcessName() const override {
return m_pname;
}
const std::vector<SystemString>& getArgs() const {
const std::vector<SystemString>& 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 {
auto newWindow = _WindowCocoaNew(title, &m_metalCtx);
m_windows[newWindow->getPlatformHandle()] = newWindow;
return newWindow;

View File

@ -9,8 +9,9 @@
#include <Metal/Metal.h>
#include <QuartzCore/CAMetalLayer.h>
#include <unordered_map>
#include <mutex>
#include <unordered_map>
namespace boo {
class IWindow;

View File

@ -1,12 +1,19 @@
#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 <CoreVideo/CVDisplayLink.h>
#include "boo/IApplication.hpp"
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/audiodev/IAudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp"
#include <logvisor/logvisor.hpp>
#if !__has_feature(objc_arc)
#error ARC Required
@ -93,7 +100,7 @@ static const NSOpenGLPixelFormatAttribute PF_RGBAF32_Z24_ATTRS[] =
static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
{
NULL,
nullptr,
PF_RGBA8_ATTRS,
PF_RGBA16_ATTRS,
PF_RGBA8_Z24_ATTRS,
@ -139,7 +146,7 @@ protected:
}
public:
~GraphicsContextCocoa() {
~GraphicsContextCocoa() override {
if (m_dispLink) {
CVDisplayLinkStop(m_dispLink);
CVDisplayLinkRelease(m_dispLink);
@ -223,36 +230,36 @@ public:
m_dataFactory = _NewGLDataFactory(this, glCtx);
}
~GraphicsContextCocoaGL()
~GraphicsContextCocoaGL() override
{
m_commandQueue->stopRenderer();
fmt::print(fmt("CONTEXT DESTROYED\n"));
}
void _setCallback(IWindowCallback* cb)
void _setCallback(IWindowCallback* cb) override
{
std::lock_guard<std::recursive_mutex> lk(m_callbackMutex);
m_callback = cb;
}
EGraphicsAPI getAPI() const
EGraphicsAPI getAPI() const override
{
return m_api;
}
EPixelFormat getPixelFormat() const
EPixelFormat getPixelFormat() const override
{
return m_pf;
}
void setPixelFormat(EPixelFormat pf)
void setPixelFormat(EPixelFormat pf) override
{
if (pf > EPixelFormat::RGBAF32_Z24)
return;
m_pf = pf;
}
bool initializeContext(void*)
bool initializeContext(void*) override
{
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
if (!m_nsContext)
@ -266,26 +273,26 @@ public:
return true;
}
void makeCurrent()
void makeCurrent() override
{
[[m_nsContext openGLContext] makeCurrentContext];
}
void postInit()
void postInit() override
{
}
IGraphicsCommandQueue* getCommandQueue()
IGraphicsCommandQueue* getCommandQueue() override
{
return m_commandQueue.get();
}
IGraphicsDataFactory* getDataFactory()
IGraphicsDataFactory* getDataFactory() override
{
return m_dataFactory.get();
}
IGraphicsDataFactory* getMainContextDataFactory()
IGraphicsDataFactory* getMainContextDataFactory() override
{
if (!m_mainCtx)
{
@ -298,7 +305,7 @@ public:
return m_dataFactory.get();
}
IGraphicsDataFactory* getLoadContextDataFactory()
IGraphicsDataFactory* getLoadContextDataFactory() override
{
if (!m_loadCtx)
{
@ -311,12 +318,12 @@ public:
return m_dataFactory.get();
}
void present()
void present() override
{
[[m_nsContext openGLContext] flushBuffer];
}
BooCocoaResponder* responder() const
BooCocoaResponder* responder() const override
{
if (!m_nsContext)
return nullptr;
@ -330,15 +337,15 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api,
GLContext* glCtx)
{
if (api != IGraphicsContext::EGraphicsAPI::OpenGL3_3 && api != IGraphicsContext::EGraphicsAPI::OpenGL4_2)
return NULL;
return nullptr;
/* Create temporary context to query GL version */
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_RGBA8_ATTRS];
if (!nspf)
return NULL;
return nullptr;
NSOpenGLContext* nsctx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:nil];
if (!nsctx)
return NULL;
return nullptr;
[nsctx makeCurrentContext];
const char* glVersion = (char*)glGetString(GL_VERSION);
unsigned major = 0;
@ -352,13 +359,13 @@ IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api,
Log.report(logvisor::Fatal, fmt("glewInit failed"));
[NSOpenGLContext clearCurrentContext];
if (!glVersion)
return NULL;
return nullptr;
if (major > 4 || (major == 4 && minor >= 2))
api = IGraphicsContext::EGraphicsAPI::OpenGL4_2;
else if (major == 3 && minor >= 3)
if (api == IGraphicsContext::EGraphicsAPI::OpenGL4_2)
return NULL;
return nullptr;
return new GraphicsContextCocoaGL(api, parentWindow, lastGLCtx, glCtx);
}
@ -384,31 +391,31 @@ public:
m_dataFactory = _NewMetalDataFactory(this, metalCtx);
}
~GraphicsContextCocoaMetal() {
~GraphicsContextCocoaMetal() override {
m_commandQueue->stopRenderer();
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);
m_callback = cb;
}
EGraphicsAPI getAPI() const {
EGraphicsAPI getAPI() const override {
return m_api;
}
EPixelFormat getPixelFormat() const {
EPixelFormat getPixelFormat() const override {
return m_pf;
}
void setPixelFormat(EPixelFormat pf) {
void setPixelFormat(EPixelFormat pf) override {
if (pf > EPixelFormat::RGBAF32_Z24)
return;
m_pf = pf;
}
bool initializeContext(void*) {
bool initializeContext(void*) override {
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
if (!m_nsContext)
@ -423,32 +430,32 @@ public:
return true;
}
void makeCurrent() {
void makeCurrent() override {
}
void postInit() {
void postInit() override {
}
IGraphicsCommandQueue* getCommandQueue() {
IGraphicsCommandQueue* getCommandQueue() override {
return m_commandQueue.get();
}
IGraphicsDataFactory* getDataFactory() {
IGraphicsDataFactory* getDataFactory() override {
return m_dataFactory.get();
}
IGraphicsDataFactory* getMainContextDataFactory() {
IGraphicsDataFactory* getMainContextDataFactory() override {
return m_dataFactory.get();
}
IGraphicsDataFactory* getLoadContextDataFactory() {
IGraphicsDataFactory* getLoadContextDataFactory() override {
return m_dataFactory.get();
}
void present() {
void present() override {
}
BooCocoaResponder* responder() const {
BooCocoaResponder* responder() const override {
if (!m_nsContext)
return nullptr;
return m_nsContext->resp;
@ -1252,47 +1259,47 @@ public:
m_nsWindow = nullptr;
}
~WindowCocoa() {
~WindowCocoa() override {
APP->_deletedWindow(this);
}
void setCallback(IWindowCallback* cb) {
void setCallback(IWindowCallback* cb) override {
m_gfxCtx->_setCallback(cb);
}
void closeWindow() {
void closeWindow() override {
dispatch_sync(dispatch_get_main_queue(),
^{
[m_nsWindow close];
});
}
void showWindow() {
void showWindow() override {
dispatch_sync(dispatch_get_main_queue(),
^{
[m_nsWindow makeKeyAndOrderFront:nil];
});
}
void hideWindow() {
void hideWindow() override {
dispatch_sync(dispatch_get_main_queue(),
^{
[m_nsWindow orderOut:nil];
});
}
std::string getTitle() {
std::string getTitle() override {
return [[m_nsWindow title] UTF8String];
}
void setTitle(std::string_view title) {
void setTitle(std::string_view title) override {
dispatch_sync(dispatch_get_main_queue(),
^{
[m_nsWindow setTitle:[NSString stringWithUTF8String:title.data()]];
});
}
void setCursor(EMouseCursor cursor) {
void setCursor(EMouseCursor cursor) override {
if (cursor == m_cursor)
return;
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 */
return 60.0;
}
void setWindowFrameDefault() {
void setWindowFrameDefault() override {
dispatch_sync(dispatch_get_main_queue(),
^{
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];
NSRect wFrame = [view convertRectToBacking:view.frame];
xOut = wFrame.origin.x;
@ -1347,7 +1354,7 @@ public:
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];
NSRect wFrame = [view convertRectToBacking:view.frame];
xOut = wFrame.origin.x;
@ -1356,7 +1363,7 @@ public:
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(),
^{
[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(),
^{
[m_nsWindow setContentSize:NSMakeSize(w, h)];
@ -1372,15 +1379,15 @@ public:
});
}
float getVirtualPixelFactor() const {
float getVirtualPixelFactor() const override {
return [m_nsWindow backingScaleFactor];
}
bool isFullscreen() const {
bool isFullscreen() const override {
return ([m_nsWindow styleMask] & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
void setFullscreen(bool fs) {
void setFullscreen(bool fs) override {
if ((fs && !isFullscreen()) || (!fs && isFullscreen()))
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();
if (resp) {
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];
[pb clearContents];
NSData* d = [NSData dataWithBytes:data length:sz];
@ -1409,7 +1416,7 @@ public:
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];
NSData* d = [pb dataForType:ClipboardTypes[int(type)]];
if (!d)
@ -1420,11 +1427,11 @@ public:
return ret;
}
ETouchType getTouchType() const {
ETouchType getTouchType() const override {
return ETouchType::Trackpad;
}
void setStyle(EWindowStyle style) {
void setStyle(EWindowStyle style) override {
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
m_nsWindow.titleVisibility = NSWindowTitleVisible;
@ -1443,7 +1450,7 @@ public:
m_nsWindow.styleMask &= ~NSWindowStyleMaskResizable;
}
EWindowStyle getStyle() const {
EWindowStyle getStyle() const override {
EWindowStyle retval = EWindowStyle::None;
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
retval |= m_nsWindow.titleVisibility == NSWindowTitleVisible ? EWindowStyle::Titlebar : EWindowStyle::None;
@ -1455,34 +1462,34 @@ public:
return retval;
}
void setTouchBarProvider(void* provider) {
void setTouchBarProvider(void* provider) override {
dispatch_sync(dispatch_get_main_queue(),
^{
[m_nsWindow setTouchBarProvider:(__bridge_transfer id) provider];
});
}
int waitForRetrace() {
int waitForRetrace() override {
return static_cast<GraphicsContextCocoa*>(m_gfxCtx)->waitForRetrace();
}
uintptr_t getPlatformHandle() const {
uintptr_t getPlatformHandle() const override {
return (uintptr_t) m_nsWindow;
}
IGraphicsCommandQueue* getCommandQueue() {
IGraphicsCommandQueue* getCommandQueue() override {
return m_gfxCtx->getCommandQueue();
}
IGraphicsDataFactory* getDataFactory() {
IGraphicsDataFactory* getDataFactory() override {
return m_gfxCtx->getDataFactory();
}
IGraphicsDataFactory* getMainContextDataFactory() {
IGraphicsDataFactory* getMainContextDataFactory() override {
return m_gfxCtx->getMainContextDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory() {
IGraphicsDataFactory* getLoadContextDataFactory() override {
return m_gfxCtx->getLoadContextDataFactory();
}

View File

@ -1,9 +1,13 @@
#include "boo/IApplication.hpp"
#include "logvisor/logvisor.hpp"
#include "nxstl/thread"
#include "nxstl/condition_variable"
#include "nxstl/mutex"
#include "boo/IApplication.hpp"
#include "boo/graphicsdev/NX.hpp"
#include <limits.h>
#include <climits>
#include <logvisor/logvisor.hpp>
#include <switch.h>
@ -21,7 +25,7 @@ class ApplicationNX : public IApplication {
NXContext m_nxCtx;
void _deletedWindow(IWindow* window) {}
void _deletedWindow(IWindow* window) override {}
public:
ApplicationNX(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
@ -29,9 +33,9 @@ public:
uint32_t anisotropy, bool deepColor, bool singleInstance)
: 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 */
int clientReturn = INT_MIN;
std::mutex initmt;
@ -63,16 +67,16 @@ public:
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> newWindow(std::string_view title) {
std::shared_ptr<IWindow> newWindow(std::string_view title) override {
if (m_window)
Log.report(logvisor::Fatal, fmt("Only 1 window allowed on NX"));
m_window = _WindowNXNew(title, &m_nxCtx);

View File

@ -1,8 +1,9 @@
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "logvisor/logvisor.hpp"
#include "boo/graphicsdev/NX.hpp"
#include <logvisor/logvisor.hpp>
#include <switch.h>
namespace boo {
@ -21,18 +22,18 @@ public:
m_commandQueue = _NewNXCommandQueue(nxCtx, this);
}
EGraphicsAPI getAPI() const { return EGraphicsAPI::NX; }
EPixelFormat getPixelFormat() const { return EPixelFormat::RGBA8; }
void setPixelFormat(EPixelFormat pf) {}
bool initializeContext(void* handle) { return m_nxCtx->initialize(); }
void makeCurrent() {}
void postInit() {}
void present() {}
EGraphicsAPI getAPI() const override { return EGraphicsAPI::NX; }
EPixelFormat getPixelFormat() const override { return EPixelFormat::RGBA8; }
void setPixelFormat(EPixelFormat pf) override {}
bool initializeContext(void* handle) override { return m_nxCtx->initialize(); }
void makeCurrent() override {}
void postInit() override {}
void present() override {}
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue.get(); }
IGraphicsDataFactory* getDataFactory() { return m_dataFactory.get(); }
IGraphicsDataFactory* getMainContextDataFactory() { return m_dataFactory.get(); }
IGraphicsDataFactory* getLoadContextDataFactory() { return m_dataFactory.get(); }
IGraphicsCommandQueue* getCommandQueue() override { return m_commandQueue.get(); }
IGraphicsDataFactory* getDataFactory() override { return m_dataFactory.get(); }
IGraphicsDataFactory* getMainContextDataFactory() override { return m_dataFactory.get(); }
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_dataFactory.get(); }
};
class WindowNX : public IWindow {
@ -45,20 +46,20 @@ public:
m_gfxCtx->initializeContext(nullptr);
}
void setCallback(IWindowCallback* cb) { m_callback = cb; }
void setCallback(IWindowCallback* cb) override { m_callback = cb; }
void closeWindow() {}
void showWindow() {}
void hideWindow() {}
void closeWindow() override {}
void showWindow() override {}
void hideWindow() override {}
SystemString getTitle() { return m_title; }
void setTitle(SystemStringView title) { m_title = title; }
SystemString getTitle() override { return m_title; }
void setTitle(SystemStringView title) override { m_title = title; }
void setCursor(EMouseCursor cursor) {}
void setWaitCursor(bool wait) {}
void setCursor(EMouseCursor cursor) override {}
void setWaitCursor(bool wait) override {}
void setWindowFrameDefault() {}
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
void setWindowFrameDefault() override {}
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const override {
u32 width, height;
gfxGetFramebufferResolution(&width, &height);
xOut = 0;
@ -66,7 +67,7 @@ public:
wOut = width;
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;
gfxGetFramebufferResolution(&width, &height);
xOut = 0;
@ -74,37 +75,37 @@ public:
wOut = width;
hOut = height;
}
void setWindowFrame(float x, float y, float w, float h) {}
void setWindowFrame(int x, int y, int w, int h) {}
float getVirtualPixelFactor() const { return 1.f; }
void setWindowFrame(float x, float y, float w, float h) override {}
void setWindowFrame(int x, int y, int w, int h) override {}
float getVirtualPixelFactor() const override { return 1.f; }
bool isFullscreen() const { return true; }
void setFullscreen(bool fs) {}
bool isFullscreen() const override { return true; }
void setFullscreen(bool fs) override {}
void claimKeyboardFocus(const int coord[2]) {}
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { return false; }
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) { return {}; }
void claimKeyboardFocus(const int coord[2]) override {}
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) override { return {}; }
void waitForRetrace() {}
void waitForRetrace() override {}
uintptr_t getPlatformHandle() const { return 0; }
bool _incomingEvent(void* event) {
uintptr_t getPlatformHandle() const override { return 0; }
bool _incomingEvent(void* event) override {
(void)event;
return false;
}
void _cleanup() {}
void _cleanup() override {}
ETouchType getTouchType() const { return ETouchType::Display; }
ETouchType getTouchType() const override { return ETouchType::Display; }
void setStyle(EWindowStyle style) {}
EWindowStyle getStyle() const { return EWindowStyle::None; }
void setStyle(EWindowStyle style) override {}
EWindowStyle getStyle() const override { return EWindowStyle::None; }
void setTouchBarProvider(void*) {}
void setTouchBarProvider(void*) override {}
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
IGraphicsDataFactory* getMainContextDataFactory() override { return m_gfxCtx->getMainContextDataFactory(); }
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
};
std::shared_ptr<IWindow> _WindowNXNew(std::string_view title, NXContext* nxCtx) {

View File

@ -1,4 +1,4 @@
#include "UWPCommon.hpp"
#include "lib/win/UWPCommon.hpp"
using namespace Windows::Foundation;
using namespace Windows::UI::Core;
@ -12,12 +12,15 @@ using namespace Platform;
#define D3D11_CREATE_DEVICE_FLAGS 0
#endif
#include "boo/System.hpp"
#include <cstdlib>
#include "boo/IApplication.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include "boo/graphicsdev/D3D.hpp"
#include "logvisor/logvisor.hpp"
#include "boo/System.hpp"
#include "boo/UWPViewProvider.hpp"
#include "boo/graphicsdev/D3D.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include <logvisor/logvisor.hpp>
#if _WIN32_WINNT_WIN10
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
@ -49,7 +52,7 @@ class ApplicationUWP final : public IApplication {
Boo3DAppContextUWP m_3dCtx;
void _deletedWindow(IWindow* window) {}
void _deletedWindow(IWindow* window) override {}
public:
ApplicationUWP(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
@ -60,7 +63,7 @@ public:
, m_pname(pname)
, m_args(args)
, 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;
bool no12 = true;
@ -180,10 +183,10 @@ public:
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;
int run() {
int run() override {
/* Spawn client thread */
int clientReturn = 0;
m_clientThread = std::thread([&]() {
@ -203,15 +206,15 @@ public:
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) {
m_issuedWindow = true;
return m_window;
@ -222,7 +225,7 @@ public:
void _setWindow(CoreWindow ^ window) { m_window = _WindowUWPNew(m_friendlyName, m_3dCtx); }
};
IApplication* APP = NULL;
IApplication* APP = nullptr;
ref class AppView sealed : public IFrameworkView {
ApplicationUWP m_app;

View File

@ -1,4 +1,5 @@
#include "Win32Common.hpp"
#include "lib/win/Win32Common.hpp"
#include <shellapi.h>
#include <initguid.h>
#include <Usbiodef.h>
@ -15,11 +16,16 @@ PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor = nullptr;
#define D3D11_CREATE_DEVICE_FLAGS 0
#endif
#include "boo/System.hpp"
#include <condition_variable>
#include <cstdlib>
#include <mutex>
#include "boo/IApplication.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include "boo/System.hpp"
#include "boo/graphicsdev/D3D.hpp"
#include "logvisor/logvisor.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include <logvisor/logvisor.hpp>
#if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp"
@ -86,7 +92,7 @@ class ApplicationWin32 final : public IApplication {
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
#endif
void _deletedWindow(IWindow* window) { m_allWindows.erase(HWND(window->getPlatformHandle())); }
void _deletedWindow(IWindow* window) override { m_allWindows.erase(HWND(window->getPlatformHandle())); }
public:
ApplicationWin32(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
@ -110,8 +116,8 @@ public:
if (!dxgilib)
Log.report(logvisor::Fatal, fmt("unable to load dxgi.dll"));
typedef HRESULT(WINAPI * CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void** ppFactory);
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
using CreateDXGIFactory1PROC = HRESULT(WINAPI*)(REFIID riid, _COM_Outptr_ void** ppFactory);
auto MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
if (!MyCreateDXGIFactory1)
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"));
}
EPlatformType getPlatformType() const { return EPlatformType::Win32; }
EPlatformType getPlatformType() const override { return EPlatformType::Win32; }
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
/* Lookup boo window instance */
@ -340,7 +346,7 @@ public:
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(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.bottom - monitor_info.rcMonitor.top,
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_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_fs = false;
@ -358,7 +364,7 @@ public:
g_nwcv.notify_one();
}
int run() {
int run() override {
g_mainThreadId = GetCurrentThreadId();
/* Spawn client thread */
@ -372,8 +378,8 @@ public:
});
/* Pump messages */
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0)) {
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0)) {
if (!msg.hwnd) {
/* PostThreadMessage events */
switch (msg.message) {
@ -424,22 +430,22 @@ public:
return clientReturn;
}
~ApplicationWin32() {
~ApplicationWin32() override {
for (auto& p : m_allWindows)
if (auto w = p.second.lock())
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> newWindow(SystemStringView title) {
std::shared_ptr<IWindow> newWindow(SystemStringView title) override {
if (GetCurrentThreadId() != g_mainThreadId) {
std::unique_lock<std::mutex> lk(g_nwmt);
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,
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args,
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);
/* 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.hCursor = WIN32_CURSORS.m_arrow;
RegisterClassW(&wndClass);

View File

@ -1,6 +1,6 @@
#pragma once
#include "WinCommon.hpp"
#include "lib/win/WinCommon.hpp"
struct Boo3DAppContextUWP : Boo3DAppContext {
bool isFullscreen(const boo::IWindow* window) {

View File

@ -14,19 +14,22 @@
#endif
#include "boo/graphicsdev/GL.hpp"
#include <condition_variable>
#include <mutex>
extern DWORD g_mainThreadId;
extern std::mutex g_nwmt;
extern std::condition_variable g_nwcv;
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
#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;
#endif
struct OGLContext {
ComPtr<IDXGIFactory1> m_dxFactory;
HGLRC m_lastContext = 0;
HGLRC m_lastContext = nullptr;
struct Window {
HWND m_hwnd;
HDC m_deviceContext;

View File

@ -1,6 +1,10 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
#include <unordered_map>
#include "boo/IWindow.hpp"
namespace boo {
@ -25,8 +29,8 @@ class IWindow;
#include <d3d9.h>
typedef int (WINAPI *pD3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName);
typedef int (WINAPI *pD3DPERF_EndEvent)();
using pD3DPERF_BeginEvent = int (WINAPI*)(D3DCOLOR col, LPCWSTR wszName);
using pD3DPERF_EndEvent = int (WINAPI*)();
struct D3D12Context {
ComPtr<IDXGIFactory2> m_dxFactory;

View File

@ -1,11 +1,12 @@
#include "UWPCommon.hpp"
#include "boo/IApplication.hpp"
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "logvisor/logvisor.hpp"
#include "lib/win/UWPCommon.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/graphicsdev/D3D.hpp"
#include <logvisor/logvisor.hpp>
using namespace Windows::UI;
using namespace Windows::UI::Core;
@ -117,7 +118,7 @@ public:
}
}
~GraphicsContextUWPD3D() {
~GraphicsContextUWPD3D() override {
#if _WIN32_WINNT_WIN10
if (m_3dCtx.m_ctx12.m_dev)
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
@ -126,33 +127,33 @@ public:
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)
return;
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,
@ -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 {
/* TODO: Actually get refresh rate */
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;
yOut = m_bounds.Y * m_dispInfoDpiFactor;
wOut = m_bounds.Width * 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;
yOut = m_bounds.Y * m_dispInfoDpiFactor;
wOut = m_bounds.Width * 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)
ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();
else
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)
engine->pumpAndMixVoices();
m_gfxCtx->m_output->WaitForVBlank();
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) {
ESpecialKey specialKey;
@ -469,23 +472,23 @@ public:
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;
return retval;
}
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
/* 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 */
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
};
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) {

View File

@ -1,15 +1,16 @@
#include "Win32Common.hpp"
#include <Windowsx.h>
#include "boo/IApplication.hpp"
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "logvisor/logvisor.hpp"
#include "lib/win/Win32Common.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/GL.hpp"
#include "boo/graphicsdev/glew.h"
#include "boo/graphicsdev/wglew.h"
#include "boo/audiodev/IAudioVoiceEngine.hpp"
#if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp"
@ -19,6 +20,8 @@
#include <dxgi1_5.h>
#endif
#include <logvisor/logvisor.hpp>
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_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
@ -88,35 +91,35 @@ public:
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)
return;
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 {
@ -198,7 +201,7 @@ public:
Log.report(logvisor::Fatal, fmt("glewInit failed"));
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglMakeCurrent(w.m_deviceContext, 0);
wglMakeCurrent(w.m_deviceContext, nullptr);
wglDeleteContext(tmpCtx);
if (b3dCtx.m_ctxOgl.m_glCtx.m_deepColor) {
@ -249,23 +252,23 @@ public:
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)
return;
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];
// if (!wglMakeCurrent(w.m_deviceContext, w.m_mainContext))
// 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"));
}
void postInit() {
void postInit() override {
// OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
// wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
@ -293,18 +296,18 @@ public:
wglSwapIntervalEXT(1);
}
void present() {
void present() override {
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
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 */
HGLRC m_mainCtx = 0;
IGraphicsDataFactory* getMainContextDataFactory() {
HGLRC m_mainCtx = nullptr;
IGraphicsDataFactory* getMainContextDataFactory() override {
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
if (!m_mainCtx) {
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 */
HGLRC m_loadCtx = 0;
IGraphicsDataFactory* getLoadContextDataFactory() {
HGLRC m_loadCtx = nullptr;
IGraphicsDataFactory* getLoadContextDataFactory() override {
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
if (!m_loadCtx) {
m_loadCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
@ -347,8 +350,11 @@ struct GraphicsContextWin32Vulkan : GraphicsContextWin32 {
bool m_vsyncRunning;
static void ThrowIfFailed(VkResult res) {
if (res != VK_SUCCESS)
Log.report(logvisor::Fatal, fmt("%d\n"), res);
if (res == VK_SUCCESS) {
return;
}
Log.report(logvisor::Fatal, fmt("{}\n"), res);
}
public:
@ -400,7 +406,7 @@ public:
m_ctx->m_windows.erase(m_parentWindow);
}
~GraphicsContextWin32Vulkan() { destroy(); }
~GraphicsContextWin32Vulkan() override { destroy(); }
VulkanContext::Window* m_windowCtx = nullptr;
@ -409,19 +415,19 @@ public:
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)
return;
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>()))
.first->second.get();
m_windowCtx->m_hwnd = m_hwnd;
@ -509,19 +515,19 @@ public:
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
@ -852,7 +858,7 @@ public:
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
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));
m_imc = ImmGetContext(m_hwnd);
@ -874,37 +880,37 @@ public:
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
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];
int c = GetWindowTextW(m_hwnd, title, 256);
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); }
void setCursor(EMouseCursor cursor) {
void setCursor(EMouseCursor cursor) override {
if (cursor == m_cursor && !m_cursorWait)
return;
m_cursor = cursor;
_setCursor(GetWin32Cursor(cursor));
}
void setWaitCursor(bool wait) {
void setWaitCursor(bool wait) override {
if (wait && !m_cursorWait) {
_setCursor(WIN32_CURSORS.m_wait);
m_cursorWait = true;
@ -914,12 +920,12 @@ public:
}
}
double getWindowRefreshRate() const {
double getWindowRefreshRate() const override {
/* TODO: Actually get refresh rate */
return 60.0;
}
void setWindowFrameDefault() {
void setWindowFrameDefault() override {
MONITORINFO monInfo = {};
monInfo.cbSize = sizeof(MONITORINFO);
HMONITOR mon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY);
@ -929,7 +935,7 @@ public:
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;
GetClientRect(m_hwnd, &rct);
POINT pt;
@ -942,7 +948,7 @@ public:
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;
GetClientRect(m_hwnd, &rct);
POINT pt;
@ -955,15 +961,15 @@ public:
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};
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
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 (MyGetScaleFactorForMonitor) {
DEVICE_SCALE_FACTOR Factor;
@ -977,9 +983,9 @@ public:
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) {
if (GetCurrentThreadId() != g_mainThreadId) {
@ -1005,7 +1011,7 @@ public:
ImmSetCompositionWindow(m_imc, &m_cForm);
}
void claimKeyboardFocus(const int coord[2]) {
void claimKeyboardFocus(const int coord[2]) override {
if (!coord) {
//_immSetOpenStatus(false);
return;
@ -1014,7 +1020,7 @@ public:
//_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) {
case EClipboardType::String: {
HGLOBAL gStr = MakeANSICRLF(reinterpret_cast<const char*>(data), sz);
@ -1038,7 +1044,7 @@ public:
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) {
case EClipboardType::String: {
OpenClipboard(m_hwnd);
@ -1068,9 +1074,12 @@ public:
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) {
if (m_callback) {
@ -1105,7 +1114,7 @@ public:
}
bool mouseTracking = false;
bool _incomingEvent(void* ev) {
bool _incomingEvent(void* ev) override {
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
switch (e.uMsg) {
case WM_CLOSE:
@ -1288,9 +1297,9 @@ public:
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);
if ((style & EWindowStyle::Titlebar) != EWindowStyle::None)
@ -1311,7 +1320,7 @@ public:
SetWindowLong(m_hwnd, GWL_STYLE, sty);
}
EWindowStyle getStyle() const {
EWindowStyle getStyle() const override {
LONG sty = GetWindowLong(m_hwnd, GWL_STYLE);
EWindowStyle retval = EWindowStyle::None;
if ((sty & WS_CAPTION) != 0)
@ -1323,14 +1332,14 @@ public:
return retval;
}
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
IGraphicsCommandQueue* getCommandQueue() override { return m_gfxCtx->getCommandQueue(); }
IGraphicsDataFactory* getDataFactory() override { return m_gfxCtx->getDataFactory(); }
/* 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 */
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
};
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx) {

View File

@ -4,12 +4,15 @@
#define APPLICATION_UNIX_CPP
#include <dbus/dbus.h>
#include <cstdint>
#include <unistd.h>
#include "logvisor/logvisor.hpp"
#include <cstdlib>
#include "boo/IApplication.hpp"
#include <dbus/dbus.h>
#include <logvisor/logvisor.hpp>
#include <unistd.h>
namespace boo {
static logvisor::Module Log("boo::ApplicationUnix");
IApplication* APP = nullptr;
@ -99,8 +102,8 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst) {
fmt::print(stderr, fmt("DBus Connection Error ({})\n"), err.message);
dbus_error_free(&err);
}
if (NULL == conn)
return NULL;
if (conn == nullptr)
return nullptr;
/* 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(),
@ -109,7 +112,7 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst) {
fmt::print(stderr, fmt("DBus Name Error ({})\n"), err.message);
dbus_error_free(&err);
dbus_connection_close(conn);
return NULL;
return nullptr;
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret)
isFirst = false;

View File

@ -19,7 +19,7 @@ class ApplicationWayland final : public IApplication {
const std::vector<std::string> m_args;
bool m_singleInstance;
void _deletedWindow(IWindow* window) { (void)window; }
void _deletedWindow(IWindow* window) override { (void)window; }
public:
ApplicationWayland(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
@ -35,19 +35,19 @@ public:
(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

View File

@ -4,7 +4,7 @@
#include "boo/IApplication.hpp"
#include "boo/graphicsdev/GL.hpp"
#include "../Common.hpp"
#include "lib/Common.hpp"
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
@ -12,16 +12,17 @@
#include <X11/extensions/XInput2.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <locale>
#include <dbus/dbus.h>
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 <thread>
#include <mutex>
#include <condition_variable>
#include "XlibCommon.hpp"
#include <X11/cursorfont.h>
@ -196,7 +197,7 @@ class ApplicationXlib final : public IApplication {
}
#endif
void _deletedWindow(IWindow* window) { m_windows.erase((Window)window->getPlatformHandle()); }
void _deletedWindow(IWindow* window) override { m_windows.erase((Window)window->getPlatformHandle()); }
public:
ApplicationXlib(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
@ -368,7 +369,7 @@ public:
XFlush(m_xDisp);
}
~ApplicationXlib() {
~ApplicationXlib() override {
for (auto& p : m_windows)
if (auto w = p.second.lock())
w->_cleanup();
@ -385,7 +386,7 @@ public:
XCloseDisplay(m_xDisp);
}
EPlatformType getPlatformType() const { return EPlatformType::Xlib; }
EPlatformType getPlatformType() const override { return EPlatformType::Xlib; }
/* Empty handler for SIGINT */
static void _sigint(int) {}
@ -414,7 +415,7 @@ public:
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int run() {
int run() override {
if (!m_xDisp)
return 1;
@ -459,7 +460,7 @@ public:
FD_ZERO(&fds);
FD_SET(m_x11Fd, &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 */
if (errno == EINTR)
break;
@ -512,15 +513,15 @@ public:
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);
#if BOO_HAS_VULKAN
std::shared_ptr<IWindow> newWindow = _WindowXlibNew(title, m_xDisp, m_xcbConn, m_xDefaultScreen, m_xIM, m_bestStyle,

View File

@ -1,4 +1,5 @@
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/audiodev/IAudioVoiceEngine.hpp"
@ -19,35 +20,35 @@ public:
GraphicsContextWayland(EGraphicsAPI api, IWindow* 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)
return;
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 {
@ -55,65 +56,65 @@ struct WindowWayland : IWindow {
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); }

View File

@ -1,26 +1,28 @@
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/IApplication.hpp"
#include "boo/graphicsdev/GL.hpp"
#include "boo/IGraphicsContext.hpp"
#include "boo/audiodev/IAudioVoiceEngine.hpp"
#include "boo/graphicsdev/GL.hpp"
#include "boo/graphicsdev/glew.h"
#include "../Common.hpp"
#include "lib/Common.hpp"
#if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp"
#include <X11/Xlib-xcb.h>
#endif
#include <limits.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unordered_set>
#include <unistd.h>
#include <GL/glx.h>
@ -32,9 +34,9 @@
#include <X11/extensions/XInput2.h>
#include <X11/Xatom.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 FS_ATOM "_NET_WM_STATE_FULLSCREEN"
@ -59,7 +61,7 @@
#undef False
#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 bool s_glxError;
static int ctxErrorHandler(Display* dpy, XErrorEvent* ev) {
@ -227,7 +229,7 @@ struct XlibAtoms {
m_imagePng = XInternAtom(disp, "image/png", false);
}
};
static XlibAtoms* S_ATOMS = NULL;
static XlibAtoms* S_ATOMS = nullptr;
static Atom GetClipboardTypeAtom(EClipboardType t) {
switch (t) {
@ -356,7 +358,7 @@ public:
visualIdOut = m_visualid;
}
void destroy() {
void destroy() override {
if (m_glxCtx) {
glXDestroyContext(m_xDisp, m_glxCtx);
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)
return;
m_pf = pf;
}
bool initializeContext(void*) {
bool initializeContext(void*) override {
if (!glXCreateContextAttribsARB) {
glXCreateContextAttribsARB =
(glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
@ -424,25 +426,25 @@ public:
return true;
}
void makeCurrent() {
void makeCurrent() override {
XLockDisplay(m_xDisp);
if (!glXMakeContextCurrent(m_xDisp, m_glxWindow, m_glxWindow, m_glxCtx))
Log.report(logvisor::Fatal, fmt("unable to make GLX context current"));
XUnlockDisplay(m_xDisp);
}
void postInit() {
void postInit() override {
GLXExtensionCheck();
XLockDisplay(m_xDisp);
GLXEnableVSync(m_xDisp, m_glxWindow);
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);
if (!m_mainCtx) {
s_glxError = false;
@ -458,7 +460,7 @@ public:
return getDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory() {
IGraphicsDataFactory* getLoadContextDataFactory() override {
XLockDisplay(m_xDisp);
if (!m_loadCtx) {
s_glxError = false;
@ -474,7 +476,7 @@ public:
return getDataFactory();
}
void present() { glXSwapBuffers(m_xDisp, m_glxWindow); }
void present() override { glXSwapBuffers(m_xDisp, m_glxWindow); }
};
#if BOO_HAS_VULKAN
@ -510,7 +512,7 @@ public:
visualIdOut = screen->root_visual->visualid;
}
void destroy() {
void destroy() override {
VulkanContext::Window& m_windowCtx = *m_ctx->m_windows[m_parentWindow];
m_windowCtx.m_swapChains[0].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;
void resized(const SWindowRect& rect) {
void resized(const SWindowRect& rect) override {
if (m_windowCtx)
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)
return;
m_pf = pf;
}
bool initializeContext(void* getVkProc) {
bool initializeContext(void* getVkProc) override {
if (m_ctx->m_instance == VK_NULL_HANDLE)
m_ctx->initVulkan(APP->getUniqueName(), PFN_vkGetInstanceProcAddr(getVkProc));
@ -637,19 +639,19 @@ public:
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
@ -732,6 +734,7 @@ public:
m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, display,
defaultScreen, lastCtx, m_visualId, glCtx));
m_openGL = true;
Log.report(logvisor::Warning, fmt("OPENGL HAS BEEN DEPRECATED, IT IS HIGHLY RECOMMENDED TO BUILD AND USE VULKAN INSTEAD"));
}
XVisualInfo visTemplate;
@ -848,38 +851,38 @@ public:
}
}
~WindowXlib() {
~WindowXlib() override {
_cleanup();
if (APP)
APP->_deletedWindow(this);
}
void setCallback(IWindowCallback* cb) {
void setCallback(IWindowCallback* cb) override {
XLockDisplay(m_xDisp);
m_callback = cb;
XUnlockDisplay(m_xDisp);
}
void closeWindow() {
void closeWindow() override {
// TODO: Free window resources and prevent further access
XLockDisplay(m_xDisp);
XUnmapWindow(m_xDisp, m_windowId);
XUnlockDisplay(m_xDisp);
}
void showWindow() {
void showWindow() override {
XLockDisplay(m_xDisp);
XMapWindow(m_xDisp, m_windowId);
XUnlockDisplay(m_xDisp);
}
void hideWindow() {
void hideWindow() override {
XLockDisplay(m_xDisp);
XUnmapWindow(m_xDisp, m_windowId);
XUnlockDisplay(m_xDisp);
}
std::string getTitle() {
std::string getTitle() override {
unsigned long nitems;
Atom actualType;
int actualFormat;
@ -897,7 +900,7 @@ public:
return std::string();
}
void setTitle(std::string_view title) {
void setTitle(std::string_view title) override {
XLockDisplay(m_xDisp);
/* Set the title of the window */
@ -914,7 +917,7 @@ public:
XUnlockDisplay(m_xDisp);
}
void setCursor(EMouseCursor cursor) {
void setCursor(EMouseCursor cursor) override {
if (cursor == m_cursor && !m_cursorWait)
return;
m_cursor = cursor;
@ -923,7 +926,7 @@ public:
XUnlockDisplay(m_xDisp);
}
void setWaitCursor(bool wait) {
void setWaitCursor(bool wait) override {
if (wait && !m_cursorWait) {
XLockDisplay(m_xDisp);
XDefineCursor(m_xDisp, m_windowId, X_CURSORS.m_wait);
@ -942,7 +945,7 @@ public:
return 60.0;
}
double getWindowRefreshRate() const {
double getWindowRefreshRate() const override {
BOO_MSAN_NO_INTERCEPT
double ret = 60.0;
int nmonitors;
@ -969,7 +972,7 @@ public:
return ret;
}
void setWindowFrameDefault() {
void setWindowFrameDefault() override {
BOO_MSAN_NO_INTERCEPT
int x, y, w, h, nmonitors;
Screen* screen = DefaultScreenOfDisplay(m_xDisp);
@ -986,7 +989,7 @@ public:
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
XWindowAttributes attrs = {};
XLockDisplay(m_xDisp);
@ -998,7 +1001,7 @@ public:
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
XWindowAttributes attrs = {};
XLockDisplay(m_xDisp);
@ -1010,7 +1013,7 @@ public:
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
XWindowChanges values = {(int)x, (int)y, (int)w, (int)h};
XLockDisplay(m_xDisp);
@ -1018,7 +1021,7 @@ public:
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
XWindowChanges values = {x, y, w, h};
XLockDisplay(m_xDisp);
@ -1026,9 +1029,9 @@ public:
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;
unsigned long nitems;
Atom actualType;
@ -1054,7 +1057,7 @@ public:
return false;
}
void setStyle(EWindowStyle style) {
void setStyle(EWindowStyle style) override {
struct {
unsigned long flags;
unsigned long functions;
@ -1086,9 +1089,9 @@ public:
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)
return;
@ -1121,7 +1124,7 @@ public:
}
} m_clipData;
void claimKeyboardFocus(const int coord[2]) {
void claimKeyboardFocus(const int coord[2]) override {
if (m_xIC) {
XLockDisplay(m_xDisp);
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);
if (!xType)
return false;
@ -1155,7 +1158,7 @@ public:
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);
if (!xType)
return {};
@ -1273,7 +1276,7 @@ public:
return lhs.tv_nsec - rhs.tv_nsec;
}
int waitForRetrace() {
int waitForRetrace() override {
BOO_MSAN_NO_INTERCEPT
struct timespec 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) {
int nDevices;
@ -1414,7 +1417,7 @@ public:
}
#endif
bool _incomingEvent(void* e) {
bool _incomingEvent(void* e) override {
XEvent* event = (XEvent*)e;
switch (event->type) {
case SelectionRequest: {
@ -1708,7 +1711,7 @@ public:
return false;
}
void _cleanup() {
void _cleanup() override {
if (m_gfxCtx) {
XLockDisplay(m_xDisp);
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() {
XWindowAttributes attr;

@ -1 +1 @@
Subproject commit dcd0ffcaece7f9ea3785d0ffca30a82cd60c573c
Subproject commit f623ace3b4620c56722a1460ff2d9db61621f659

Some files were not shown because too many files have changed in this diff Show More