diff --git a/.github/workflows/build-tests.yaml b/.github/workflows/build-tests.yaml new file mode 100644 index 000000000..6601e2c44 --- /dev/null +++ b/.github/workflows/build-tests.yaml @@ -0,0 +1,81 @@ + +run-name: ouzel build test +on: [push] +jobs: + linux: + name: ${{matrix.os}} + runs-on: ${{matrix.os}} + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-latest] + steps: + - name: Checkoout ouzel + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgl1-mesa-dev libgles2-mesa-dev libopenal-dev libasound2-dev libxi-dev libxcursor-dev libxrandr-dev libxss-dev libxxf86vm-dev + sudo apt-get install cmake ninja-build + + - name: Generate ninja files + run: cmake . -Bbuild -GNinja + + - name: Build + run: cd build && ninja + + mac: + name: ${{matrix.os}} + runs-on: ${{matrix.os}} + strategy: + matrix: + os: [macos-11, macos-latest] + + steps: + - name: Checkoout ouzel + uses: actions/checkout@v2 + + - name: Install ninja + run: brew install ninja + + - name: Generate ninja files + run: cmake . -Bbuild -GNinja + + - name: Build + run: cd build && ninja + + windows: + name: ${{matrix.os}}-${{matrix.compiler}} + runs-on: ${{matrix.os}} + strategy: + matrix: + os: [windows-2019, windows-latest] + compiler: [cl, clang] + include: + - os: windows-2019 + compiler: cl + generator: Visual Studio 16 2019 + toolchain: + - os: windows-latest + compiler: cl + generator: Visual Studio 17 2022 + toolchain: + - os: windows-2019 + compiler: clang + generator: Visual Studio 16 2019 + toolchain: -T ClangCL + - os: windows-latest + compiler: clang + generator: Visual Studio 17 2022 + toolchain: -T ClangCL + + steps: + - name: Checkoout ouzel + uses: actions/checkout@v2 + + - name: Build + run: cmake . -Bbuild -G "${{matrix.generator}}" ${{matrix.toolchain}} + + - name: Build + run: cd build && cmake --build . + diff --git a/.gitignore b/.gitignore index 49c40a0d9..a751897f8 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ test/test.xcodeproj/xcuserdata test/test samples/app/src/main/libs samples/app/src/main/obj +build/ +.cache/ +.DS_Store +compile_commands.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..c24ad76b9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.16) + +if (APPLE) + project(ouzel LANGUAGES C CXX OBJC OBJCXX) +else() + project(ouzel LANGUAGES C CXX) +endif() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_OBJCXX_STANDARD 17) + +set(CMAKE_C_FLAGS + "-Wall" +) + +set(CMAKE_CXX_FLAGS + "-Wall" +) + +set(CMAKE_OBJC_FLAGS + "-Wall" +) + +set(CMAKE_OBJCXX_FLAGS + "-Wall" +) + +if(NOT MSVC) + set(CMAKE_C_FLAGS + "-Wpedantic -Wextra -Wshadow -Wdouble-promotion -Woverloaded-virtual" + ) + set(CMAKE_CXX_FLAGS + "-Wpedantic -Wextra -Wshadow -Wdouble-promotion -Woverloaded-virtual -Wold-style-cast" + ) + set(CMAKE_OBJC_FLAGS + "-fno-objc-arc -Wpedantic -Wextra -Wshadow -Wdouble-promotion -Woverloaded-virtual" + ) + set(CMAKE_OBJCXX_FLAGS + "-fno-objc-arc -Wpedantic -Wextra -Wshadow -Wdouble-promotion -Woverloaded-virtual -Wold-style-cas" + ) +endif() + +if(MSVC) + set(CMAKE_CXX_FLAGS "/EHca") + set(CMAKE_OBJCXX_FLAGS "/EHca") +else() + set(CMAKE_CXX_FLAGS "-fexceptions") + set(CMAKE_OBJCXX_FLAGS "-fexceptions") +endif() + +set(EXTERNAL_LIB_INCLUDE_DIRS + ${CMAKE_CURRENT_LIST_DIR}/external/khronos + ${CMAKE_CURRENT_LIST_DIR}/external/smbPitchShift + ${CMAKE_CURRENT_LIST_DIR}/external/stb +) + +set(SHADER_DIRS + ${CMAKE_CURRENT_LIST_DIR}/shaders +) + +add_subdirectory(engine) +add_subdirectory(samples) +add_subdirectory(tools) +add_subdirectory(test) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt new file mode 100644 index 000000000..f1b9e826d --- /dev/null +++ b/engine/CMakeLists.txt @@ -0,0 +1,278 @@ +add_library(ouzel + assets/Bundle.cpp + assets/Cache.cpp + assets/ImageLoader.cpp + assets/MtlLoader.cpp + assets/ObjLoader.cpp + assets/WaveLoader.cpp + audio/mixer/Bus.cpp + audio/mixer/Mixer.cpp + audio/Audio.cpp + audio/AudioDevice.cpp + audio/Containers.cpp + audio/Cue.cpp + audio/Effect.cpp + audio/Effects.cpp + audio/Listener.cpp + audio/Mix.cpp + audio/Node.cpp + audio/Oscillator.cpp + audio/PcmClip.cpp + audio/SilenceSound.cpp + audio/Sound.cpp + audio/Submix.cpp + audio/Voice.cpp + audio/VorbisClip.cpp + core/Engine.cpp + core/System.cpp + core/NativeWindow.cpp + core/Window.cpp + events/EventDispatcher.cpp + graphics/opengl/OGLBlendState.cpp + graphics/opengl/OGLBuffer.cpp + graphics/opengl/OGLDepthStencilState.cpp + graphics/opengl/OGLRenderDevice.cpp + graphics/opengl/OGLRenderTarget.cpp + graphics/opengl/OGLShader.cpp + graphics/opengl/OGLTexture.cpp + graphics/BlendState.cpp + graphics/Buffer.cpp + graphics/DepthStencilState.cpp + graphics/Graphics.cpp + graphics/RenderDevice.cpp + graphics/RenderPass.cpp + graphics/RenderTarget.cpp + graphics/Shader.cpp + graphics/Texture.cpp + gui/BMFont.cpp + gui/TTFont.cpp + gui/Widgets.cpp + input/Cursor.cpp + input/Gamepad.cpp + input/GamepadDevice.cpp + input/InputDevice.cpp + input/InputManager.cpp + input/InputSystem.cpp + input/Keyboard.cpp + input/KeyboardDevice.cpp + input/Mouse.cpp + input/MouseDevice.cpp + input/Touchpad.cpp + input/TouchpadDevice.cpp + localization/Localization.cpp + network/Client.cpp + network/Network.cpp + network/Server.cpp + scene/Actor.cpp + scene/Animator.cpp + scene/Animators.cpp + scene/Camera.cpp + scene/Component.cpp + scene/Layer.cpp + scene/Light.cpp + scene/ParticleSystem.cpp + scene/Scene.cpp + scene/SceneManager.cpp + scene/ShapeRenderer.cpp + scene/SkinnedMeshRenderer.cpp + scene/SpriteRenderer.cpp + scene/StaticMeshRenderer.cpp + scene/TextRenderer.cpp + storage/FileSystem.cpp + utils/Log.cpp +) + +if(WIN32) + target_precompile_headers(ouzel PUBLIC stdafx.h) +else() + target_precompile_headers(ouzel PUBLIC Prefix.pch) +endif() +target_include_directories(ouzel PUBLIC + ${EXTERNAL_LIB_INCLUDE_DIRS} + ${SHADER_DIRS} + ${CMAKE_CURRENT_LIST_DIR} +) + +if(WIN32) + target_sources(ouzel + PRIVATE + audio/xaudio2/XA2AudioDevice.cpp + audio/xaudio2/XAudio27.cpp + audio/wasapi/WASAPIAudioDevice.cpp + core/windows/EngineWin.cpp + core/windows/NativeWindowWin.cpp + core/windows/SystemWin.cpp + graphics/direct3d11/D3D11BlendState.cpp + graphics/direct3d11/D3D11Buffer.cpp + graphics/direct3d11/D3D11DepthStencilState.cpp + graphics/direct3d11/D3D11RenderDevice.cpp + graphics/direct3d11/D3D11RenderTarget.cpp + graphics/direct3d11/D3D11Shader.cpp + graphics/direct3d11/D3D11Texture.cpp + graphics/opengl/windows/OGLRenderDeviceWin.cpp + input/windows/GamepadDeviceDI.cpp + input/windows/GamepadDeviceWin.cpp + input/windows/GamepadDeviceXI.cpp + input/windows/InputSystemWin.cpp + input/windows/KeyboardDeviceWin.cpp + input/windows/MouseDeviceWin.cpp + input/windows/CursorWin.cpp + ) + target_compile_definitions(ouzel PRIVATE -DWINVER=0x0601 -D_WIN32_WINNT=0x0602) + target_link_libraries(ouzel PRIVATE + kernel32 + user32 + gdi32 + winspool + shell32 + ole32 + oleaut32 + uuid + comdlg32 + advapi32 + winmm + imm32 + version + ws2_32 + dbghelp + d3d11 + d3dcompiler + dxgi + dxguid + Dinput8 + opengl32 + Xinput + Xinput9_1_0 + Xaudio2 + ) +elseif(UNIX AND NOT APPLE) # linux + target_sources(ouzel PRIVATE + audio/alsa/ALSAAudioDevice.cpp + audio/openal/OALAudioDevice.cpp + core/linux/EngineLinux.cpp + core/linux/NativeWindowLinux.cpp + core/linux/SystemLinux.cpp + graphics/opengl/linux/OGLRenderDeviceLinux.cpp + input/linux/EventDevice.cpp + input/linux/InputSystemLinux.cpp + input/linux/KeyboardDeviceLinux.cpp + input/linux/MouseDeviceLinux.cpp + input/linux/CursorLinux.cpp + ) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") + set(VC_DIR /opt/vc) + target_include_directories(ouzel PUBLIC + ${VC_DIR}/include + ${VC_DIR}/include/interface/vcos/pthreads + ${VC_DIR}/interface/vmcs_host/linux + ) + endif() +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") # macos + target_sources(ouzel PRIVATE + audio/coreaudio/CAAudioDevice.mm + audio/openal/OALAudioDevice.cpp + core/macos/EngineMacOS.mm + core/macos/NativeWindowMacOS.mm + core/macos/SystemMacOS.mm + core/macos/ViewMacOS.mm + graphics/metal/macos/MetalView.m + graphics/metal/macos/MetalRenderDeviceMacOS.mm + graphics/metal/MetalBlendState.mm + graphics/metal/MetalBuffer.mm + graphics/metal/MetalDepthStencilState.mm + graphics/metal/MetalRenderDevice.mm + graphics/metal/MetalRenderTarget.mm + graphics/metal/MetalShader.mm + graphics/metal/MetalTexture.mm + graphics/opengl/macos/OGLRenderDeviceMacOS.mm + graphics/opengl/macos/OpenGLView.m + input/macos/GamepadDeviceGC.mm + input/macos/GamepadDeviceIOKit.cpp + input/macos/GamepadDeviceMacOS.cpp + input/macos/InputSystemMacOS.mm + input/macos/MouseDeviceMacOS.mm + input/macos/CursorMacOS.mm + platform/cocoa/Window.mm + platform/foundation/RunLoop.mm + ) +elseif(IOS) + target_sources(ouzel PRIVATE + audio/coreaudio/CAAudioDevice.mm + audio/openal/OALAudioDevice.cpp + core/ios/EngineIOS.mm + core/ios/NativeWindowIOS.mm + core/ios/SystemIOS.mm + core/ios/ViewIOS.mm + graphics/metal/ios/MetalView.m + graphics/metal/ios/MetalRenderDeviceIOS.mm + graphics/metal/MetalBlendState.mm + graphics/metal/MetalBuffer.mm + graphics/metal/MetalDepthStencilState.mm + graphics/metal/MetalRenderDevice.mm + graphics/metal/MetalRenderTarget.mm + graphics/metal/MetalShader.mm + graphics/metal/MetalTexture.mm + graphics/opengl/ios/OGLRenderDeviceIOS.mm + graphics/opengl/ios/OpenGLView.m + input/ios/GamepadDeviceIOS.mm + input/ios/InputSystemIOS.mm + platform/foundation/RunLoop.mm + platform/quartzcore/DisplayLink.mm + ) + execute_process( + COMMAND xcrun --sdk iphoneos --show-sdk-path + OUTPUT_VARIABLE IOS_SYS_ROOT + ) + target_compile_options(ouzel + PRIVATE + -arch arm64 + -isysroot + ${IOS_SYS_ROOT} + -miphoneos-version-min=8.0) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "tvos") + target_sources(ouzel PRIVATE + audio/coreaudio/CAAudioDevice.mm + audio/openal/OALAudioDevice.cpp + core/tvos/EngineTVOS.mm + core/tvos/NativeWindowTVOS.mm + core/tvos/SystemTVOS.mm + core/tvos/ViewTVOS.mm + graphics/metal/tvos/MetalView.m + graphics/metal/tvos/MetalRenderDeviceTVOS.mm + graphics/metal/MetalBlendState.mm + graphics/metal/MetalBuffer.mm + graphics/metal/MetalDepthStencilState.mm + graphics/metal/MetalRenderDevice.mm + graphics/metal/MetalRenderTarget.mm + graphics/metal/MetalShader.mm + graphics/metal/MetalTexture.mm + graphics/opengl/tvos/OGLRenderDeviceTVOS.mm + graphics/opengl/tvos/OpenGLView.m + input/tvos/GamepadDeviceTVOS.mm + input/tvos/InputSystemTVOS.mm + platform/foundation/RunLoop.mm + platform/quartzcore/DisplayLink.mm + ) + execute_process( + COMMAND xcrun --sdk appletvos --show-sdk-path + OUTPUT_VARIABLE TVOS_SYS_ROOT + ) + target_compile_options(ouzel + PRIVATE + -arch arm64 + -isysroot + ${TVOS_SYS_ROOT} + -mtvos-version-min=9.0) +elseif(EMSCRIPTEN) + target_sources(ouzel PRIVATE + audio/openal/OALAudioDevice.cpp + core/emscripten/EngineEm.cpp + core/emscripten/NativeWindowEm.cpp + core/emscripten/SystemEm.cpp + graphics/opengl/emscripten/OGLRenderDeviceEm.cpp + input/emscripten/GamepadDeviceEm.cpp + input/emscripten/InputSystemEm.cpp + input/emscripten/MouseDeviceEm.cpp + ) + target_compile_options(ouzel PRIVATE -s DISABLE_EXCEPTION_CATCHING=0) +endif() diff --git a/engine/audio/wasapi/WASAPIAudioDevice.cpp b/engine/audio/wasapi/WASAPIAudioDevice.cpp index 4631e344d..d262c854e 100644 --- a/engine/audio/wasapi/WASAPIAudioDevice.cpp +++ b/engine/audio/wasapi/WASAPIAudioDevice.cpp @@ -127,17 +127,17 @@ namespace ouzel::audio::wasapi { LPVOID enumeratorPointer; if (const auto hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, &enumeratorPointer); FAILED(hr)) - throw std::system_error{hr, std::system_category(), "Failed to create device enumerator"}; + throw std::system_error{toErrorCode(hr), std::system_category(), "Failed to create device enumerator"}; enumerator = static_cast(enumeratorPointer); IMMDevice* devicePointer; if (const auto hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &devicePointer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get audio endpoint"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get audio endpoint"}; IPropertyStore* propertyStorePointer; if (const auto hr = devicePointer->OpenPropertyStore(STGM_READ, &propertyStorePointer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to open property store"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to open property store"}; Pointer propertyStore = propertyStorePointer; @@ -159,18 +159,18 @@ namespace ouzel::audio::wasapi notificationClient = new NotificationClient(); if (const auto hr = enumerator->RegisterEndpointNotificationCallback(notificationClient.get()); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get audio endpoint"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get audio endpoint"}; void* audioClientPointer; if (const auto hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, &audioClientPointer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to activate audio device"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to activate audio device"}; audioClient = static_cast(audioClientPointer); WAVEFORMATEX* audioClientWaveFormat; if (const auto hr = audioClient->GetMixFormat(&audioClientWaveFormat); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get audio mix format"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get audio mix format"}; WAVEFORMATEX waveFormat; waveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; @@ -228,7 +228,7 @@ namespace ouzel::audio::wasapi // init output device if (const auto hr = audioClient->GetBufferSize(&bufferFrameCount); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get audio buffer size"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get audio buffer size"}; bufferSize = bufferFrameCount * channels; void* renderClientPointer; @@ -242,7 +242,7 @@ namespace ouzel::audio::wasapi throw std::system_error{static_cast(GetLastError()), std::system_category(), "Failed to create event"}; if (const auto hr = audioClient->SetEventHandle(notifyEvent); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to set event handle"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to set event handle"}; } AudioDevice::~AudioDevice() @@ -260,7 +260,7 @@ namespace ouzel::audio::wasapi void AudioDevice::start() { if (const auto hr = audioClient->Start(); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to start audio"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to start audio"}; started = true; running = true; @@ -275,7 +275,7 @@ namespace ouzel::audio::wasapi if (started) { if (const auto hr = audioClient->Stop(); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to stop audio"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to stop audio"}; started = false; } @@ -295,21 +295,21 @@ namespace ouzel::audio::wasapi UINT32 bufferPadding; if (const auto hr = audioClient->GetCurrentPadding(&bufferPadding); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get buffer padding"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get buffer padding"}; const UINT32 frameCount = bufferFrameCount - bufferPadding; if (frameCount != 0) { BYTE* renderBuffer; if (const auto hr = renderClient->GetBuffer(frameCount, &renderBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get buffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get buffer"}; getData(frameCount, data); std::memcpy(renderBuffer, data.data(), data.size()); if (const auto hr = renderClient->ReleaseBuffer(frameCount, 0); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to release buffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to release buffer"}; } } } diff --git a/engine/audio/wasapi/WASAPIErrorCategory.hpp b/engine/audio/wasapi/WASAPIErrorCategory.hpp index c71f07161..68a3f038b 100644 --- a/engine/audio/wasapi/WASAPIErrorCategory.hpp +++ b/engine/audio/wasapi/WASAPIErrorCategory.hpp @@ -8,10 +8,56 @@ #if OUZEL_COMPILE_WASAPI #include +#include #include namespace ouzel::audio::wasapi { + enum ErrorCode { + ErrorClassNotReg, + ErrorClassNotAggregation, + ErrorPointer, + ErrorInvalidArg, + ErrorNotFound, + ErrorOutMemory, + ErrorNotInterface, + ErrorInitialized, + ErrorAlreadyInitialized, + ErrorWrongEndpointType, + ErrorDeviceInvalidated, + ErrorNotStopped, + ErrorBufferTooLarge, + ErrorOutOfOrder, + ErrorUnsupportedFormat, + ErrorInvalidSize, + ErrorDeviceInUse, + ErrorBufferOperationPending, + ErrorThreadNotRegistered, + ErrorExclusiveModeNotAllowed, + ErrorEndpointCreateFailed, + ErrorServiceNotRunning, + ErrorEventHandleNotExpected, + ErrorExclusiveModeOnly, + ErrorBufDurationPeriodNotEqual, + ErrorEventHandleNotSet, + ErrorIncorrectBufferSize, + ErrorBufferSizeError, + ErrorCpuUsageExceeded, + ErrorBufferError, + ErrorBufferSizeNotAligned, + ErrorDevicePeriod, + ErrorInvalidStreamFlag, + ErrorEndpointOffloadNotCapable, + ErrorOutOfOffloadResources, + ErrorOffloadModeOnly, + ErrorNonOffloadModeOnly, + ErrorResourcesInvalidated, + ErrorRawModeNotSupported, + ErrorBufferEmpty, + ErrorThreadAlreadyRegistered, + ErrorPositionStalled + }; + class ErrorCategory final: public std::error_category { public: @@ -24,53 +70,145 @@ namespace ouzel::audio::wasapi { switch (condition) { - case REGDB_E_CLASSNOTREG: return "REGDB_E_CLASSNOTREG"; - case CLASS_E_NOAGGREGATION: return "CLASS_E_NOAGGREGATION"; - case E_POINTER: return "E_POINTER"; - case E_INVALIDARG: return "E_INVALIDARG"; - case __HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /* E_NOTFOUND */: return "E_NOTFOUND"; - case E_OUTOFMEMORY: return "E_OUTOFMEMORY"; - case E_NOINTERFACE: return "E_NOINTERFACE"; - case AUDCLNT_E_NOT_INITIALIZED: return "AUDCLNT_E_NOT_INITIALIZED"; - case AUDCLNT_E_ALREADY_INITIALIZED: return "AUDCLNT_E_ALREADY_INITIALIZED"; - case AUDCLNT_E_WRONG_ENDPOINT_TYPE: return "AUDCLNT_E_WRONG_ENDPOINT_TYPE"; - case AUDCLNT_E_DEVICE_INVALIDATED: return "AUDCLNT_E_DEVICE_INVALIDATED"; - case AUDCLNT_E_NOT_STOPPED: return "AUDCLNT_E_NOT_STOPPED"; - case AUDCLNT_E_BUFFER_TOO_LARGE: return "AUDCLNT_E_BUFFER_TOO_LARGE"; - case AUDCLNT_E_OUT_OF_ORDER: return "AUDCLNT_E_OUT_OF_ORDER"; - case AUDCLNT_E_UNSUPPORTED_FORMAT: return "AUDCLNT_E_UNSUPPORTED_FORMAT"; - case AUDCLNT_E_INVALID_SIZE: return "AUDCLNT_E_INVALID_SIZE"; - case AUDCLNT_E_DEVICE_IN_USE: return "AUDCLNT_E_DEVICE_IN_USE"; - case AUDCLNT_E_BUFFER_OPERATION_PENDING: return "AUDCLNT_E_BUFFER_OPERATION_PENDING"; - case AUDCLNT_E_THREAD_NOT_REGISTERED: return "AUDCLNT_E_THREAD_NOT_REGISTERED"; - case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED: return "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED"; - case AUDCLNT_E_ENDPOINT_CREATE_FAILED: return "AUDCLNT_E_ENDPOINT_CREATE_FAILED"; - case AUDCLNT_E_SERVICE_NOT_RUNNING: return "AUDCLNT_E_SERVICE_NOT_RUNNING"; - case AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED: return "AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED"; - case AUDCLNT_E_EXCLUSIVE_MODE_ONLY: return "AUDCLNT_E_EXCLUSIVE_MODE_ONLY"; - case AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL: return "AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL"; - case AUDCLNT_E_EVENTHANDLE_NOT_SET: return "AUDCLNT_E_EVENTHANDLE_NOT_SET"; - case AUDCLNT_E_INCORRECT_BUFFER_SIZE: return "AUDCLNT_E_INCORRECT_BUFFER_SIZE"; - case AUDCLNT_E_BUFFER_SIZE_ERROR: return "AUDCLNT_E_BUFFER_SIZE_ERROR"; - case AUDCLNT_E_CPUUSAGE_EXCEEDED: return "AUDCLNT_E_CPUUSAGE_EXCEEDED"; - case AUDCLNT_E_BUFFER_ERROR: return "AUDCLNT_E_BUFFER_ERROR"; - case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED: return "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED"; - case AUDCLNT_E_INVALID_DEVICE_PERIOD: return "AUDCLNT_E_INVALID_DEVICE_PERIOD"; - case AUDCLNT_E_INVALID_STREAM_FLAG: return "AUDCLNT_E_INVALID_STREAM_FLAG"; - case AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE: return "AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE"; - case AUDCLNT_E_OUT_OF_OFFLOAD_RESOURCES: return "AUDCLNT_E_OUT_OF_OFFLOAD_RESOURCES"; - case AUDCLNT_E_OFFLOAD_MODE_ONLY: return "AUDCLNT_E_OFFLOAD_MODE_ONLY"; - case AUDCLNT_E_NONOFFLOAD_MODE_ONLY: return "AUDCLNT_E_NONOFFLOAD_MODE_ONLY"; - case AUDCLNT_E_RESOURCES_INVALIDATED: return "AUDCLNT_E_RESOURCES_INVALIDATED"; - case AUDCLNT_E_RAW_MODE_UNSUPPORTED: return "AUDCLNT_E_RAW_MODE_UNSUPPORTED"; - case AUDCLNT_S_BUFFER_EMPTY: return "AUDCLNT_S_BUFFER_EMPTY"; - case AUDCLNT_S_THREAD_ALREADY_REGISTERED: return "AUDCLNT_S_THREAD_ALREADY_REGISTERED"; - case AUDCLNT_S_POSITION_STALLED: return "AUDCLNT_S_POSITION_STALLED"; + case ErrorCode::ErrorClassNotReg: return "REGDB_E_CLASSNOTREG"; + case ErrorCode::ErrorClassNotAggregation: return "CLASS_E_NOAGGREGATION"; + case ErrorCode::ErrorPointer: return "E_POINTER"; + case ErrorCode::ErrorInvalidArg: return "E_INVALIDARG"; + case ErrorCode::ErrorNotFound /* E_NOTFOUND */: return "E_NOTFOUND"; + case ErrorCode::ErrorOutMemory: return "E_OUTOFMEMORY"; + case ErrorCode::ErrorNotInterface: return "E_NOINTERFACE"; + case ErrorCode::ErrorInitialized: return "AUDCLNT_E_NOT_INITIALIZED"; + case ErrorCode::ErrorAlreadyInitialized: return "AUDCLNT_E_ALREADY_INITIALIZED"; + case ErrorCode::ErrorWrongEndpointType: return "AUDCLNT_E_WRONG_ENDPOINT_TYPE"; + case ErrorCode::ErrorDeviceInvalidated: return "AUDCLNT_E_DEVICE_INVALIDATED"; + case ErrorCode::ErrorNotStopped: return "AUDCLNT_E_NOT_STOPPED"; + case ErrorCode::ErrorBufferTooLarge: return "AUDCLNT_E_BUFFER_TOO_LARGE"; + case ErrorCode::ErrorOutOfOrder: return "AUDCLNT_E_OUT_OF_ORDER"; + case ErrorCode::ErrorUnsupportedFormat: return "AUDCLNT_E_UNSUPPORTED_FORMAT"; + case ErrorCode::ErrorInvalidSize: return "AUDCLNT_E_INVALID_SIZE"; + case ErrorCode::ErrorDeviceInUse: return "AUDCLNT_E_DEVICE_IN_USE"; + case ErrorCode::ErrorBufferOperationPending: return "AUDCLNT_E_BUFFER_OPERATION_PENDING"; + case ErrorCode::ErrorThreadNotRegistered: return "AUDCLNT_E_THREAD_NOT_REGISTERED"; + case ErrorCode::ErrorExclusiveModeNotAllowed: return "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED"; + case ErrorCode::ErrorEndpointCreateFailed: return "AUDCLNT_E_ENDPOINT_CREATE_FAILED"; + case ErrorCode::ErrorServiceNotRunning: return "AUDCLNT_E_SERVICE_NOT_RUNNING"; + case ErrorCode::ErrorEventHandleNotExpected: return "AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED"; + case ErrorCode::ErrorExclusiveModeOnly: return "AUDCLNT_E_EXCLUSIVE_MODE_ONLY"; + case ErrorCode::ErrorBufDurationPeriodNotEqual: return "AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL"; + case ErrorCode::ErrorEventHandleNotSet: return "AUDCLNT_E_EVENTHANDLE_NOT_SET"; + case ErrorCode::ErrorIncorrectBufferSize: return "AUDCLNT_E_INCORRECT_BUFFER_SIZE"; + case ErrorCode::ErrorBufferSizeError: return "AUDCLNT_E_BUFFER_SIZE_ERROR"; + case ErrorCode::ErrorCpuUsageExceeded: return "AUDCLNT_E_CPUUSAGE_EXCEEDED"; + case ErrorCode::ErrorBufferError: return "AUDCLNT_E_BUFFER_ERROR"; + case ErrorCode::ErrorBufferSizeNotAligned: return "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED"; + case ErrorCode::ErrorDevicePeriod: return "AUDCLNT_E_INVALID_DEVICE_PERIOD"; + case ErrorCode::ErrorInvalidStreamFlag: return "AUDCLNT_E_INVALID_STREAM_FLAG"; + case ErrorCode::ErrorEndpointOffloadNotCapable: return "AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE"; + case ErrorCode::ErrorOutOfOffloadResources: return "AUDCLNT_E_OUT_OF_OFFLOAD_RESOURCES"; + case ErrorCode::ErrorOffloadModeOnly: return "AUDCLNT_E_OFFLOAD_MODE_ONLY"; + case ErrorCode::ErrorNonOffloadModeOnly: return "AUDCLNT_E_NONOFFLOAD_MODE_ONLY"; + case ErrorCode::ErrorResourcesInvalidated: return "AUDCLNT_E_RESOURCES_INVALIDATED"; + case ErrorCode::ErrorRawModeNotSupported: return "AUDCLNT_E_RAW_MODE_UNSUPPORTED"; + case ErrorCode::ErrorBufferEmpty: return "AUDCLNT_S_BUFFER_EMPTY"; + case ErrorCode::ErrorThreadAlreadyRegistered: return "AUDCLNT_S_THREAD_ALREADY_REGISTERED"; + case ErrorCode::ErrorPositionStalled: return "AUDCLNT_S_POSITION_STALLED"; default: return "Unknown error (" + std::to_string(condition) + ")"; } } }; + inline constexpr ErrorCode toErrorCode(int64_t hr) { + switch (hr) { + case REGDB_E_CLASSNOTREG: + return ErrorCode::ErrorClassNotReg; + case CLASS_E_NOAGGREGATION: + return ErrorCode::ErrorClassNotAggregation; + case E_POINTER: + return ErrorCode::ErrorPointer; + case E_INVALIDARG: + return ErrorCode::ErrorInvalidArg; + case __HRESULT_FROM_WIN32(ERROR_NOT_FOUND): + return ErrorCode::ErrorNotFound; + case E_OUTOFMEMORY: + return ErrorCode::ErrorOutMemory; + case E_NOINTERFACE: + return ErrorCode::ErrorNotInterface; + case AUDCLNT_E_NOT_INITIALIZED: + return ErrorCode::ErrorInitialized; + case AUDCLNT_E_ALREADY_INITIALIZED: + return ErrorCode::ErrorAlreadyInitialized; + case AUDCLNT_E_WRONG_ENDPOINT_TYPE: + return ErrorCode::ErrorWrongEndpointType; + case AUDCLNT_E_DEVICE_INVALIDATED: + return ErrorCode::ErrorDeviceInvalidated; + case AUDCLNT_E_NOT_STOPPED: + return ErrorCode::ErrorNotStopped; + case AUDCLNT_E_BUFFER_TOO_LARGE: + return ErrorCode::ErrorBufferTooLarge; + case AUDCLNT_E_OUT_OF_ORDER: + return ErrorCode::ErrorOutOfOrder; + case AUDCLNT_E_UNSUPPORTED_FORMAT: + return ErrorCode::ErrorUnsupportedFormat; + case AUDCLNT_E_INVALID_SIZE: + return ErrorCode::ErrorInvalidSize; + case AUDCLNT_E_DEVICE_IN_USE: + return ErrorCode::ErrorDeviceInUse; + case AUDCLNT_E_BUFFER_OPERATION_PENDING: + return ErrorCode::ErrorBufferOperationPending; + case AUDCLNT_E_THREAD_NOT_REGISTERED: + return ErrorCode::ErrorThreadNotRegistered; + case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED: + return ErrorCode::ErrorExclusiveModeNotAllowed; + case AUDCLNT_E_ENDPOINT_CREATE_FAILED: + return ErrorCode::ErrorEndpointCreateFailed; + case AUDCLNT_E_SERVICE_NOT_RUNNING: + return ErrorCode::ErrorServiceNotRunning; + case AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED: + return ErrorCode::ErrorEventHandleNotExpected; + case AUDCLNT_E_EXCLUSIVE_MODE_ONLY: + return ErrorCode::ErrorExclusiveModeOnly; + case AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL: + return ErrorCode::ErrorBufDurationPeriodNotEqual; + case AUDCLNT_E_EVENTHANDLE_NOT_SET: + return ErrorCode::ErrorEventHandleNotSet; + case AUDCLNT_E_INCORRECT_BUFFER_SIZE: + return ErrorCode::ErrorIncorrectBufferSize; + case AUDCLNT_E_BUFFER_SIZE_ERROR: + return ErrorCode::ErrorBufferSizeError; + case AUDCLNT_E_CPUUSAGE_EXCEEDED: + return ErrorCode::ErrorCpuUsageExceeded; + case AUDCLNT_E_BUFFER_ERROR: + return ErrorCode::ErrorBufferError; + case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED: + return ErrorCode::ErrorBufferSizeNotAligned; + case AUDCLNT_E_INVALID_DEVICE_PERIOD: + return ErrorCode::ErrorDevicePeriod; + case AUDCLNT_E_INVALID_STREAM_FLAG: + return ErrorCode::ErrorInvalidStreamFlag; + case AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE: + return ErrorCode::ErrorEndpointOffloadNotCapable; + case AUDCLNT_E_OUT_OF_OFFLOAD_RESOURCES: + return ErrorCode::ErrorOutOfOffloadResources; + case AUDCLNT_E_OFFLOAD_MODE_ONLY: + return ErrorCode::ErrorOffloadModeOnly; + case AUDCLNT_E_NONOFFLOAD_MODE_ONLY: + return ErrorCode::ErrorNonOffloadModeOnly; + case AUDCLNT_E_RESOURCES_INVALIDATED: + return ErrorCode::ErrorResourcesInvalidated; + case AUDCLNT_E_RAW_MODE_UNSUPPORTED: + return ErrorCode::ErrorRawModeNotSupported; + case AUDCLNT_S_BUFFER_EMPTY: + return ErrorCode::ErrorBufferEmpty; + case AUDCLNT_S_THREAD_ALREADY_REGISTERED: + return ErrorCode::ErrorThreadAlreadyRegistered; + case AUDCLNT_S_POSITION_STALLED: + return ErrorCode::ErrorPositionStalled; + + default: + return static_cast(hr); + } + } + inline const ErrorCategory errorCategory; } #endif diff --git a/engine/audio/xaudio2/XA2AudioDevice.cpp b/engine/audio/xaudio2/XA2AudioDevice.cpp index bd76caceb..29e626604 100644 --- a/engine/audio/xaudio2/XA2AudioDevice.cpp +++ b/engine/audio/xaudio2/XA2AudioDevice.cpp @@ -41,7 +41,7 @@ namespace ouzel::audio::xaudio2 throw std::system_error{static_cast(GetLastError()), std::system_category(), "Failed to get address of XAudio2Create"}; if (const auto hr = xAudio2CreateProc(&xAudio, 0, XAUDIO2_DEFAULT_PROCESSOR); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to initialize XAudio2"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to initialize XAudio2"}; if (settings.debugAudio) { @@ -74,7 +74,7 @@ namespace ouzel::audio::xaudio2 if (settings.debugAudio) flags |= XAUDIO2_DEBUG_ENGINE; if (const auto hr = XAudio27CreateProc(&xAudio, flags, XAUDIO2_DEFAULT_PROCESSOR); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to initialize XAudio2"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to initialize XAudio2"}; } WAVEFORMATEX waveFormat; @@ -89,18 +89,18 @@ namespace ouzel::audio::xaudio2 if (apiMajorVersion == 2 && apiMinorVersion == 7) { if (const auto hr = IXAudio2CreateMasteringVoice(xAudio, &masteringVoice); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create XAudio2 mastering voice"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create XAudio2 mastering voice"}; if (const auto hr = IXAudio2CreateSourceVoice(xAudio, &sourceVoice, &waveFormat, 0, XAUDIO2_DEFAULT_FREQ_RATIO, this); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create source voice"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create source voice"}; } else { if (const auto hr = xAudio->CreateMasteringVoice(&masteringVoice); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create XAudio2 mastering voice"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create XAudio2 mastering voice"}; if (const auto hr = xAudio->CreateSourceVoice(&sourceVoice, &waveFormat, 0, XAUDIO2_DEFAULT_FREQ_RATIO, this); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create source voice"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create source voice"}; } sampleFormat = SampleFormat::float32; @@ -134,19 +134,19 @@ namespace ouzel::audio::xaudio2 bufferData.pContext = nullptr; if (const auto hr = sourceVoice->SubmitSourceBuffer(&bufferData); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to upload sound data"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to upload sound data"}; getData(bufferSize / (channels * sizeof(float)), data[1]); bufferData.AudioBytes = static_cast(data[1].size()); bufferData.pAudioData = data[1].data(); if (const auto hr = sourceVoice->SubmitSourceBuffer(&bufferData); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to upload sound data"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to upload sound data"}; nextBuffer = 0; if (const auto hr = sourceVoice->Start(); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to start consuming sound data"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to start consuming sound data"}; } void AudioDevice::stop() @@ -190,7 +190,7 @@ namespace ouzel::audio::xaudio2 bufferData.pContext = nullptr; if (const auto hr = sourceVoice->SubmitSourceBuffer(&bufferData); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to upload sound data"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to upload sound data"}; nextBuffer = (nextBuffer == 0) ? 1 : 0; } diff --git a/engine/audio/xaudio2/XA2ErrorCategory.hpp b/engine/audio/xaudio2/XA2ErrorCategory.hpp index 789d0e725..0997323f0 100644 --- a/engine/audio/xaudio2/XA2ErrorCategory.hpp +++ b/engine/audio/xaudio2/XA2ErrorCategory.hpp @@ -8,10 +8,18 @@ #if OUZEL_COMPILE_XAUDIO2 #include +#include #include namespace ouzel::audio::xaudio2 { + enum ErrorCode { + ErrorInvalidCall, + ErrorXmaDeviceError, + ErrorXapoCreationFailed, + ErrorDeviceInvalidated + }; + class ErrorCategory final: public std::error_category { public: @@ -24,15 +32,34 @@ namespace ouzel::audio::xaudio2 { switch (condition) { - case XAUDIO2_E_INVALID_CALL: return "XAUDIO2_E_INVALID_CALL"; - case XAUDIO2_E_XMA_DECODER_ERROR: return "XAUDIO2_E_XMA_DECODER_ERROR"; - case XAUDIO2_E_XAPO_CREATION_FAILED: return "XAUDIO2_E_XAPO_CREATION_FAILED"; - case XAUDIO2_E_DEVICE_INVALIDATED: return "XAUDIO2_E_DEVICE_INVALIDATED"; + case ErrorCode::ErrorInvalidCall: return "XAUDIO2_E_INVALID_CALL"; + case ErrorCode::ErrorXmaDeviceError: return "XAUDIO2_E_XMA_DECODER_ERROR"; + case ErrorCode::ErrorXapoCreationFailed: return "XAUDIO2_E_XAPO_CREATION_FAILED"; + case ErrorCode::ErrorDeviceInvalidated: return "XAUDIO2_E_DEVICE_INVALIDATED"; default: return "Unknown error (" + std::to_string(condition) + ")"; } } }; + inline constexpr ErrorCode toErrorCode(int64_t hr) { + switch (hr) { + case XAUDIO2_E_INVALID_CALL: + return ErrorCode::ErrorInvalidCall; + + case XAUDIO2_E_XMA_DECODER_ERROR: + return ErrorCode::ErrorXmaDeviceError; + + case XAUDIO2_E_XAPO_CREATION_FAILED: + return ErrorCode::ErrorXapoCreationFailed; + + case XAUDIO2_E_DEVICE_INVALIDATED: + return ErrorCode::ErrorDeviceInvalidated; + + default: + return static_cast(hr); + } + } + inline const ErrorCategory errorCategory; } #endif diff --git a/engine/audio/xaudio2/XAudio27.cpp b/engine/audio/xaudio2/XAudio27.cpp index 0e8b7ade2..948a98b7b 100644 --- a/engine/audio/xaudio2/XAudio27.cpp +++ b/engine/audio/xaudio2/XAudio27.cpp @@ -21,15 +21,17 @@ HRESULT IXAudio2CreateMasteringVoice(IXAudio2* pXAudio2, UINT32 InputChannels, UINT32 InputSampleRate, UINT32 Flags, - UINT32 DeviceIndex, - const XAUDIO2_EFFECT_CHAIN* pEffectChain) + LPCWSTR szDeviceId, + const XAUDIO2_EFFECT_CHAIN* pEffectChain, + AUDIO_STREAM_CATEGORY StreamCategory) { return pXAudio2->CreateMasteringVoice(ppMasteringVoice, InputChannels, InputSampleRate, Flags, - DeviceIndex, - pEffectChain); + szDeviceId, + pEffectChain, + StreamCategory); } HRESULT IXAudio2CreateSourceVoice(IXAudio2* pXAudio2, diff --git a/engine/audio/xaudio2/XAudio27.hpp b/engine/audio/xaudio2/XAudio27.hpp index 81a00716c..cb0a05eed 100644 --- a/engine/audio/xaudio2/XAudio27.hpp +++ b/engine/audio/xaudio2/XAudio27.hpp @@ -16,8 +16,9 @@ HRESULT IXAudio2CreateMasteringVoice(IXAudio2* pXAudio2, UINT32 InputChannels = XAUDIO2_DEFAULT_CHANNELS, UINT32 InputSampleRate = XAUDIO2_DEFAULT_SAMPLERATE, UINT32 Flags = 0, - UINT32 DeviceIndex = 0, - const XAUDIO2_EFFECT_CHAIN* pEffectChain = nullptr); + LPCWSTR szDeviceId = nullptr, + const XAUDIO2_EFFECT_CHAIN* pEffectChain = nullptr, + AUDIO_STREAM_CATEGORY StreamCategory = AudioCategory_GameMedia); HRESULT IXAudio2CreateSourceVoice(IXAudio2* pXAudio2, IXAudio2SourceVoice** ppSourceVoice, const WAVEFORMATEX* pSourceFormat, diff --git a/engine/core/Platform.h b/engine/core/Platform.h index f4a737927..cae225027 100644 --- a/engine/core/Platform.h +++ b/engine/core/Platform.h @@ -60,6 +60,11 @@ # define OUZEL_SUPPORTS_OPENAL 1 # define OUZEL_SUPPORTS_ALSA 1 +// some compilers pre-defines macro 'linux', which clashes with some namespace and enum names +#if defined (linux) +#undef linux +#endif + # if defined(__x86_64__) || defined(__i386__) // x86 Linux # define OUZEL_SUPPORTS_X11 1 # elif defined(__arm64__) || defined(__aarch64__) || defined(__arm__) // ARM Linux diff --git a/engine/core/windows/NativeWindowWin.cpp b/engine/core/windows/NativeWindowWin.cpp index b55e11530..d5666b78d 100644 --- a/engine/core/windows/NativeWindowWin.cpp +++ b/engine/core/windows/NativeWindowWin.cpp @@ -513,7 +513,8 @@ namespace ouzel::core::windows if (MultiByteToWideChar(CP_UTF8, 0, title.c_str(), -1, titleBuffer.get(), buferSize) == 0) throw std::system_error{static_cast(GetLastError()), std::system_category(), "Failed to convert UTF-8 to wide char"}; - window = CreateWindowExW(WS_EX_APPWINDOW, MAKEINTATOM(windowClass), titleBuffer.get(), windowStyle, + window = CreateWindowExW(WS_EX_APPWINDOW, reinterpret_cast(MAKEINTATOM(windowClass)), + titleBuffer.get(), windowStyle, x, y, width, height, nullptr, nullptr, instance, nullptr); if (!window) @@ -549,7 +550,7 @@ namespace ouzel::core::windows DestroyWindow(window); if (windowClass) - UnregisterClassW(MAKEINTATOM(windowClass), GetModuleHandleW(nullptr)); + UnregisterClassW(reinterpret_cast(MAKEINTATOM(windowClass)), GetModuleHandleW(nullptr)); } void NativeWindow::executeCommand(const Command& command) diff --git a/engine/graphics/direct3d11/D3D11BlendState.cpp b/engine/graphics/direct3d11/D3D11BlendState.cpp index 4bcd2e727..25178f484 100644 --- a/engine/graphics/direct3d11/D3D11BlendState.cpp +++ b/engine/graphics/direct3d11/D3D11BlendState.cpp @@ -79,7 +79,7 @@ namespace ouzel::graphics::d3d11 ID3D11BlendState* newBlendState; if (const auto hr = renderDevice.getDevice()->CreateBlendState(&blendStateDesc, &newBlendState); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 blend state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 blend state"}; blendState = newBlendState; } diff --git a/engine/graphics/direct3d11/D3D11Buffer.cpp b/engine/graphics/direct3d11/D3D11Buffer.cpp index e0ed188c3..3782fe3ca 100644 --- a/engine/graphics/direct3d11/D3D11Buffer.cpp +++ b/engine/graphics/direct3d11/D3D11Buffer.cpp @@ -90,7 +90,7 @@ namespace ouzel::graphics::d3d11 ID3D11Buffer* newBuffer; if (const auto hr = renderDevice.getDevice()->CreateBuffer(&bufferDesc, &bufferResourceData, &newBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 buffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 buffer"}; buffer = newBuffer; } diff --git a/engine/graphics/direct3d11/D3D11DepthStencilState.cpp b/engine/graphics/direct3d11/D3D11DepthStencilState.cpp index 19e43fc04..f8ff7724b 100644 --- a/engine/graphics/direct3d11/D3D11DepthStencilState.cpp +++ b/engine/graphics/direct3d11/D3D11DepthStencilState.cpp @@ -80,7 +80,7 @@ namespace ouzel::graphics::d3d11 ID3D11DepthStencilState* newDepthStencilState; if (const auto hr = renderDevice.getDevice()->CreateDepthStencilState(&depthStencilStateDesc, &newDepthStencilState); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil state"}; depthStencilState = newDepthStencilState; } diff --git a/engine/graphics/direct3d11/D3D11ErrorCategory.hpp b/engine/graphics/direct3d11/D3D11ErrorCategory.hpp index 97bb409e6..110c9334b 100644 --- a/engine/graphics/direct3d11/D3D11ErrorCategory.hpp +++ b/engine/graphics/direct3d11/D3D11ErrorCategory.hpp @@ -8,6 +8,7 @@ #if OUZEL_COMPILE_DIRECT3D11 #include +#include #pragma push_macro("WIN32_LEAN_AND_MEAN") #pragma push_macro("NOMINMAX") #ifndef WIN32_LEAN_AND_MEAN @@ -22,6 +23,21 @@ namespace ouzel::graphics::d3d11 { + enum ErrorCode { + ErrorFileNotFound, + ErrorTooManyUniqueStateObjects, + ErrorTooManyUniqueViewObjects, + ErrorDeferredContextMapWithoutInitialDiscard, + ErrorInvalidCall, + ErrorWasStillDrawing, + ErrorNotCurrentlyAvailable, + ErrorDeviceRemoved, + ErrorFail, + ErrorInvalidArg, + ErrorOutOfMemory, + ErrorNotImpl + }; + class ErrorCategory final: public std::error_category { public: @@ -34,23 +50,55 @@ namespace ouzel::graphics::d3d11 { switch (condition) { - case D3D11_ERROR_FILE_NOT_FOUND: return "D3D11_ERROR_FILE_NOT_FOUND"; - case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS: return "D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS"; - case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS: return "D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS"; - case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD: return "D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD"; - case DXGI_ERROR_INVALID_CALL: return "DXGI_ERROR_INVALID_CALL"; - case DXGI_ERROR_WAS_STILL_DRAWING: return "DXGI_ERROR_WAS_STILL_DRAWING"; - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; - case DXGI_ERROR_DEVICE_REMOVED: return "DXGI_ERROR_DEVICE_REMOVED"; - case E_FAIL: return "E_FAIL"; - case E_INVALIDARG: return "E_INVALIDARG"; - case E_OUTOFMEMORY: return "E_OUTOFMEMORY"; - case E_NOTIMPL: return "E_NOTIMPL"; + case ErrorCode::ErrorFileNotFound: return "D3D11_ERROR_FILE_NOT_FOUND"; + case ErrorCode::ErrorTooManyUniqueStateObjects: return "D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS"; + case ErrorCode::ErrorTooManyUniqueViewObjects: return "D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS"; + case ErrorCode::ErrorDeferredContextMapWithoutInitialDiscard: return "D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD"; + case ErrorCode::ErrorInvalidCall: return "DXGI_ERROR_INVALID_CALL"; + case ErrorCode::ErrorWasStillDrawing: return "DXGI_ERROR_WAS_STILL_DRAWING"; + case ErrorCode::ErrorNotCurrentlyAvailable: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; + case ErrorCode::ErrorDeviceRemoved: return "DXGI_ERROR_DEVICE_REMOVED"; + case ErrorCode::ErrorFail: return "E_FAIL"; + case ErrorCode::ErrorInvalidArg: return "E_INVALIDARG"; + case ErrorCode::ErrorOutOfMemory: return "E_OUTOFMEMORY"; + case ErrorCode::ErrorNotImpl: return "E_NOTIMPL"; default: return "Unknown error (" + std::to_string(condition) + ")"; } } }; + inline constexpr ErrorCode toErrorCode(int64_t hr) { + switch (hr) { + case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS: + return ErrorCode::ErrorFileNotFound; + case D3D11_ERROR_FILE_NOT_FOUND: + return ErrorCode::ErrorTooManyUniqueStateObjects; + case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS: + return ErrorCode::ErrorTooManyUniqueViewObjects; + case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD: + return ErrorCode::ErrorDeferredContextMapWithoutInitialDiscard; + case DXGI_ERROR_INVALID_CALL: + return ErrorCode::ErrorInvalidCall; + case DXGI_ERROR_WAS_STILL_DRAWING: + return ErrorCode::ErrorWasStillDrawing; + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return ErrorCode::ErrorNotCurrentlyAvailable; + case DXGI_ERROR_DEVICE_REMOVED: + return ErrorCode::ErrorDeviceRemoved; + case E_FAIL: + return ErrorCode::ErrorFail; + case E_INVALIDARG: + return ErrorCode::ErrorInvalidArg; + case E_OUTOFMEMORY: + return ErrorCode::ErrorOutOfMemory; + case E_NOTIMPL: + return ErrorCode::ErrorNotImpl; + + default: + return static_cast(hr); + } + } + inline const ErrorCategory errorCategory; } #endif diff --git a/engine/graphics/direct3d11/D3D11RenderDevice.cpp b/engine/graphics/direct3d11/D3D11RenderDevice.cpp index 7dc2c4720..683796df5 100644 --- a/engine/graphics/direct3d11/D3D11RenderDevice.cpp +++ b/engine/graphics/direct3d11/D3D11RenderDevice.cpp @@ -97,7 +97,7 @@ namespace ouzel::graphics::d3d11 &newDevice, &featureLevel, &newContext); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create the Direct3D 11 device"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create the Direct3D 11 device"}; device = newDevice; context = newContext; @@ -113,19 +113,19 @@ namespace ouzel::graphics::d3d11 void* newAdapter; if (const auto hr = dxgiDevice->GetParent(IID_IDXGIAdapter, &newAdapter); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get the DXGI adapter"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get the DXGI adapter"}; adapter = static_cast(newAdapter); void* factoryPtr; if (const auto hr = adapter->GetParent(IID_IDXGIFactory, &factoryPtr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get the DXGI factory"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get the DXGI factory"}; Pointer factory = static_cast(factoryPtr); DXGI_ADAPTER_DESC adapterDesc; if (const auto hr = adapter->GetDesc(&adapterDesc); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get the DXGI adapter description"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get the DXGI adapter description"}; else { if (const auto byteCount = WideCharToMultiByte(CP_UTF8, 0, adapterDesc.Description, -1, nullptr, 0, nullptr, nullptr); byteCount != 0) @@ -146,7 +146,7 @@ namespace ouzel::graphics::d3d11 for (supportedSampleCount = sampleCount; supportedSampleCount > 1; --supportedSampleCount) { if (const auto hr = device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, supportedSampleCount, &qualityLevels); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to check Direct3D 11 multisample quality levels"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to check Direct3D 11 multisample quality levels"}; else if (qualityLevels) break; } @@ -179,7 +179,7 @@ namespace ouzel::graphics::d3d11 IDXGISwapChain* newSwapCahin; if (const auto hr = factory->CreateSwapChain(device.get(), &swapChainDesc, &newSwapCahin); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create the Direct3D 11 swap chain"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create the Direct3D 11 swap chain"}; swapChain = newSwapCahin; @@ -188,13 +188,13 @@ namespace ouzel::graphics::d3d11 // Backbuffer void* newBackBuffer; if (const auto hr = swapChain->GetBuffer(0, IID_ID3D11Texture2D, &newBackBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to retrieve Direct3D 11 backbuffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to retrieve Direct3D 11 backbuffer"}; backBuffer = static_cast(newBackBuffer); ID3D11RenderTargetView* newRenderTargetView; if (const auto hr = device->CreateRenderTargetView(backBuffer.get(), nullptr, &newRenderTargetView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 render target view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 render target view"}; renderTargetView = newRenderTargetView; @@ -223,7 +223,7 @@ namespace ouzel::graphics::d3d11 ID3D11RasterizerState* newRasterizerState; if (const auto hr = device->CreateRasterizerState(&rasterStateDesc, &newRasterizerState); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 rasterizer state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 rasterizer state"}; rasterizerStates[rasterStateIndex] = newRasterizerState; @@ -247,13 +247,13 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* newDepthStencilTexture; if (const auto hr = device->CreateTexture2D(&depthStencilDesc, nullptr, &newDepthStencilTexture); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil texture"}; depthStencilTexture = newDepthStencilTexture; ID3D11DepthStencilView* newDepthStencilView; if (const auto hr = device->CreateDepthStencilView(depthStencilTexture.get(), nullptr, &newDepthStencilView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil view"}; depthStencilView = newDepthStencilView; } @@ -276,7 +276,7 @@ namespace ouzel::graphics::d3d11 ID3D11DepthStencilState* newDefaultDepthStencilState; if (const auto hr = device->CreateDepthStencilState(&depthStencilStateDesc, &newDefaultDepthStencilState); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil state"}; defaultDepthStencilState = newDefaultDepthStencilState; } @@ -295,7 +295,7 @@ namespace ouzel::graphics::d3d11 { executeOnRenderThread([newFullscreen, this]() { if (const auto hr = swapChain->SetFullscreenState(newFullscreen ? TRUE : FALSE, nullptr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to set fullscreen state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to set fullscreen state"}; }); } @@ -833,7 +833,7 @@ namespace ouzel::graphics::d3d11 UINT numModes = 0U; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; if (const auto hr = output->GetDisplayModeList(format, 0, &numModes, nullptr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get display mode list"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get display mode list"}; if (numModes > 0U) { @@ -864,7 +864,7 @@ namespace ouzel::graphics::d3d11 { void* backBufferTexturePtr; if (const auto hr = backBuffer->QueryInterface(IID_ID3D11Texture2D, &backBufferTexturePtr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to get Direct3D 11 back buffer texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to get Direct3D 11 back buffer texture"}; Pointer backBufferTexture = static_cast(backBufferTexturePtr); @@ -886,7 +886,7 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* texturePtr; if (const auto hr = device->CreateTexture2D(&textureDesc, nullptr, &texturePtr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 texture"}; Pointer texture = texturePtr; @@ -907,7 +907,7 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* resolveTexturePtr; if (const auto hr = device->CreateTexture2D(&resolveTextureDesc, nullptr, &resolveTexturePtr); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 texture"}; Pointer resolveTexture = resolveTexturePtr; @@ -936,17 +936,17 @@ namespace ouzel::graphics::d3d11 depthStencilView = nullptr; if (const auto hr = swapChain->ResizeBuffers(0, newWidth, newHeight, DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to resize Direct3D 11 backbuffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to resize Direct3D 11 backbuffer"}; void* newBackBuffer; if (const auto hr = swapChain->GetBuffer(0, IID_ID3D11Texture2D, &newBackBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to retrieve Direct3D 11 backbuffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to retrieve Direct3D 11 backbuffer"}; backBuffer = static_cast(newBackBuffer); ID3D11RenderTargetView* newRenderTargetView; if (const auto hr = device->CreateRenderTargetView(backBuffer.get(), nullptr, &newRenderTargetView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 render target view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 render target view"}; renderTargetView = newRenderTargetView; @@ -970,13 +970,13 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* newDepthStencilTexture; if (const auto hr = device->CreateTexture2D(&depthStencilDesc, nullptr, &newDepthStencilTexture); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil texture"}; depthStencilTexture = newDepthStencilTexture; ID3D11DepthStencilView* newDepthStencilView; if (const auto hr = device->CreateDepthStencilView(depthStencilTexture.get(), nullptr, &newDepthStencilView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil view"}; depthStencilView = newDepthStencilView; } @@ -1041,7 +1041,7 @@ namespace ouzel::graphics::d3d11 ID3D11SamplerState* samplerState; if (const auto hr = device->CreateSamplerState(&samplerStateDesc, &samplerState); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 sampler state"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 sampler state"}; samplerStates[desc] = samplerState; diff --git a/engine/graphics/direct3d11/D3D11Shader.cpp b/engine/graphics/direct3d11/D3D11Shader.cpp index 1019be7d8..1a38e75c6 100644 --- a/engine/graphics/direct3d11/D3D11Shader.cpp +++ b/engine/graphics/direct3d11/D3D11Shader.cpp @@ -115,13 +115,13 @@ namespace ouzel::graphics::d3d11 { ID3D11PixelShader* newPixelShader; if (const auto hr = renderDevice.getDevice()->CreatePixelShader(fragmentShaderData.data(), fragmentShaderData.size(), nullptr, &newPixelShader); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create a Direct3D 11 pixel shader"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create a Direct3D 11 pixel shader"}; fragmentShader = newPixelShader; ID3D11VertexShader* newVertexShader; if (const auto hr = renderDevice.getDevice()->CreateVertexShader(vertexShaderData.data(), vertexShaderData.size(), nullptr, &newVertexShader); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create a Direct3D 11 vertex shader"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create a Direct3D 11 vertex shader"}; vertexShader = newVertexShader; @@ -157,7 +157,7 @@ namespace ouzel::graphics::d3d11 vertexShaderData.data(), vertexShaderData.size(), &newInputLayout); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 input layout for vertex shader"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 input layout for vertex shader"}; inputLayout = newInputLayout; @@ -186,7 +186,7 @@ namespace ouzel::graphics::d3d11 if (const auto hr = renderDevice.getDevice()->CreateBuffer(&fragmentShaderConstantBufferDesc, nullptr, &newFragmentShaderConstantBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 constant buffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 constant buffer"}; fragmentShaderConstantBuffer = newFragmentShaderConstantBuffer; @@ -215,7 +215,7 @@ namespace ouzel::graphics::d3d11 if (const auto hr = renderDevice.getDevice()->CreateBuffer(&vertexShaderConstantBufferDesc, nullptr, &newVertexShaderConstantBuffer); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 constant buffer"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 constant buffer"}; vertexShaderConstantBuffer = newVertexShaderConstantBuffer; } diff --git a/engine/graphics/direct3d11/D3D11Texture.cpp b/engine/graphics/direct3d11/D3D11Texture.cpp index f4202bb29..4ac5cdf50 100644 --- a/engine/graphics/direct3d11/D3D11Texture.cpp +++ b/engine/graphics/direct3d11/D3D11Texture.cpp @@ -174,7 +174,7 @@ namespace ouzel::graphics::d3d11 { ID3D11Texture2D* newTexture; if (const auto hr = renderDevice.getDevice()->CreateTexture2D(&textureDescriptor, nullptr, &newTexture); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 texture"}; texture = newTexture; } @@ -191,7 +191,7 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* newTexture; if (const auto hr = renderDevice.getDevice()->CreateTexture2D(&textureDescriptor, subresourceData.data(), &newTexture); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 texture"}; texture = newTexture; } @@ -220,7 +220,7 @@ namespace ouzel::graphics::d3d11 ID3D11Texture2D* newMsaaTexture; if (const auto hr = renderDevice.getDevice()->CreateTexture2D(&msaaTextureDescriptor, nullptr, &newMsaaTexture); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 texture"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 texture"}; msaaTexture = newMsaaTexture; @@ -235,7 +235,7 @@ namespace ouzel::graphics::d3d11 ID3D11DepthStencilView* newDepthStenciView; if (const auto hr = renderDevice.getDevice()->CreateDepthStencilView(msaaTexture.get(), &depthStencilViewDesc, &newDepthStenciView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil view"}; depthStencilView = newDepthStenciView; } @@ -249,7 +249,7 @@ namespace ouzel::graphics::d3d11 ID3D11RenderTargetView* newRenderTargetView; if (const auto hr = renderDevice.getDevice()->CreateRenderTargetView(msaaTexture.get(), &renderTargetViewDesc, &newRenderTargetView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 render target view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 render target view"}; renderTargetView = newRenderTargetView; } @@ -266,7 +266,7 @@ namespace ouzel::graphics::d3d11 ID3D11DepthStencilView* newDepthStenciView; if (const auto hr = renderDevice.getDevice()->CreateDepthStencilView(texture.get(), &depthStencilViewDesc, &newDepthStenciView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 depth stencil view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 depth stencil view"}; depthStencilView = newDepthStenciView; } @@ -279,7 +279,7 @@ namespace ouzel::graphics::d3d11 ID3D11RenderTargetView* newRenderTargetView; if (const auto hr = renderDevice.getDevice()->CreateRenderTargetView(texture.get(), &renderTargetViewDesc, &newRenderTargetView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 render target view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 render target view"}; renderTargetView = newRenderTargetView; } @@ -296,7 +296,7 @@ namespace ouzel::graphics::d3d11 ID3D11ShaderResourceView* newResourceView; if (const auto hr = renderDevice.getDevice()->CreateShaderResourceView(texture.get(), &resourceViewDesc, &newResourceView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 shader resource view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 shader resource view"}; resourceView = newResourceView; } @@ -311,7 +311,7 @@ namespace ouzel::graphics::d3d11 ID3D11ShaderResourceView* newResourceView; if (const auto hr = renderDevice.getDevice()->CreateShaderResourceView(texture.get(), &resourceViewDesc, &newResourceView); FAILED(hr)) - throw std::system_error{hr, errorCategory, "Failed to create Direct3D 11 shader resource view"}; + throw std::system_error{toErrorCode(hr), errorCategory, "Failed to create Direct3D 11 shader resource view"}; resourceView = newResourceView; } diff --git a/engine/graphics/opengl/windows/OGLRenderDeviceWin.cpp b/engine/graphics/opengl/windows/OGLRenderDeviceWin.cpp index 1baee014f..e5ee94312 100644 --- a/engine/graphics/opengl/windows/OGLRenderDeviceWin.cpp +++ b/engine/graphics/opengl/windows/OGLRenderDeviceWin.cpp @@ -50,7 +50,7 @@ namespace ouzel::graphics::opengl::windows if (!windowClass) throw std::system_error{static_cast(GetLastError()), std::system_category(), "Failed to register window class"}; - window = CreateWindowW(MAKEINTATOM(windowClass), L"TempWindow", 0, + window = CreateWindowW(reinterpret_cast(MAKEINTATOM(windowClass)), L"TempWindow", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instance, 0); @@ -122,7 +122,7 @@ namespace ouzel::graphics::opengl::windows } if (windowClass) - UnregisterClassW(MAKEINTATOM(windowClass), GetModuleHandleW(nullptr)); + UnregisterClassW(reinterpret_cast(MAKEINTATOM(windowClass)), GetModuleHandleW(nullptr)); } TempContext(const TempContext&) = delete; diff --git a/engine/input/linux/EventDevice.hpp b/engine/input/linux/EventDevice.hpp index ebfbcca9c..7d4dbad1e 100644 --- a/engine/input/linux/EventDevice.hpp +++ b/engine/input/linux/EventDevice.hpp @@ -10,6 +10,7 @@ #include #include #include "../Gamepad.hpp" +#include "../../core/Platform.h" namespace ouzel::input { diff --git a/engine/input/windows/DIErrorCategory.hpp b/engine/input/windows/DIErrorCategory.hpp index 8032aed0b..6f0e9661b 100644 --- a/engine/input/windows/DIErrorCategory.hpp +++ b/engine/input/windows/DIErrorCategory.hpp @@ -4,6 +4,7 @@ #define OUZEL_INPUT_DIERRORCATEGORY_HPP #include +#include #pragma push_macro("WIN32_LEAN_AND_MEAN") #pragma push_macro("NOMINMAX") @@ -20,6 +21,40 @@ namespace ouzel::input::windows { + enum ErrorCode { + ErrorAcquired, + ErrorAlreadyInitialized, + ErrorBadDriverVer, + ErrorBetaDirectInputVersion, + ErrorDeviceFull, + ErrorDeviceNotReg, + ErrorEffectPlaying, + ErrorGeneric, + ErrorHandleExists, + ErrorHasEffects, + ErrorInCompleteEffect, + ErrorInputLost, + ErrorInvalidParam, + ErrorMapFileFail, + ErrorMoreData, + ErrorNoAggregation, + ErrorNoInterface, + ErrorNotAcquired, + ErrorNotBuffered, + ErrorNotDownloaded, + ErrorNotExclusiveAcquired, + ErrorNotfound, + ErrorNotInitialized, + ErrorOldDirectInputvVersion, + ErrorOutOfMemory, + ErrorReportFull, + ErrorUnplugged, + ErrorUnsupported, + ErrorHandle, + ErrorPending, + ErrorPointer, + }; + class ErrorCategory final: public std::error_category { public: @@ -32,42 +67,112 @@ namespace ouzel::input::windows { switch (condition) { - case DIERR_ACQUIRED: return "DIERR_ACQUIRED"; - case DIERR_ALREADYINITIALIZED: return "DIERR_ALREADYINITIALIZED"; - case DIERR_BADDRIVERVER: return "DIERR_BADDRIVERVER"; - case DIERR_BETADIRECTINPUTVERSION: return "DIERR_BETADIRECTINPUTVERSION"; - case DIERR_DEVICEFULL: return "DIERR_DEVICEFULL"; - case DIERR_DEVICENOTREG: return "DIERR_DEVICENOTREG"; - case DIERR_EFFECTPLAYING: return "DIERR_EFFECTPLAYING"; - case DIERR_GENERIC: return "DIERR_GENERIC"; - case DIERR_HANDLEEXISTS: return "DIERR_HANDLEEXISTS"; - case DIERR_HASEFFECTS: return "DIERR_HASEFFECTS"; - case DIERR_INCOMPLETEEFFECT: return "DIERR_INCOMPLETEEFFECT"; - case DIERR_INPUTLOST: return "DIERR_INPUTLOST"; - case DIERR_INVALIDPARAM: return "DIERR_INVALIDPARAM"; - case DIERR_MAPFILEFAIL: return "DIERR_MAPFILEFAIL"; - case DIERR_MOREDATA: return "DIERR_MOREDATA"; - case DIERR_NOAGGREGATION: return "DIERR_NOAGGREGATION"; - case DIERR_NOINTERFACE: return "DIERR_NOINTERFACE"; - case DIERR_NOTACQUIRED: return "DIERR_NOTACQUIRED"; - case DIERR_NOTBUFFERED: return "DIERR_NOTBUFFERED"; - case DIERR_NOTDOWNLOADED: return "DIERR_NOTDOWNLOADED"; - case DIERR_NOTEXCLUSIVEACQUIRED: return "DIERR_NOTEXCLUSIVEACQUIRED"; - case DIERR_NOTFOUND: return "DIERR_NOTFOUND"; - case DIERR_NOTINITIALIZED: return "DIERR_NOTINITIALIZED"; - case DIERR_OLDDIRECTINPUTVERSION: return "DIERR_OLDDIRECTINPUTVERSION"; - case DIERR_OUTOFMEMORY: return "DIERR_OUTOFMEMORY"; - case DIERR_REPORTFULL: return "DIERR_REPORTFULL"; - case DIERR_UNPLUGGED: return "DIERR_UNPLUGGED"; - case DIERR_UNSUPPORTED: return "DIERR_UNSUPPORTED"; - case E_HANDLE: return "E_HANDLE"; - case E_PENDING: return "E_PENDING"; - case E_POINTER: return "E_POINTER"; + case ErrorCode::ErrorAcquired: return "DIERR_ACQUIRED"; + case ErrorCode::ErrorAlreadyInitialized: return "DIERR_ALREADYINITIALIZED"; + case ErrorCode::ErrorBadDriverVer: return "DIERR_BADDRIVERVER"; + case ErrorCode::ErrorBetaDirectInputVersion: return "DIERR_BETADIRECTINPUTVERSION"; + case ErrorCode::ErrorDeviceFull: return "DIERR_DEVICEFULL"; + case ErrorCode::ErrorDeviceNotReg: return "DIERR_DEVICENOTREG"; + case ErrorCode::ErrorEffectPlaying: return "DIERR_EFFECTPLAYING"; + case ErrorCode::ErrorGeneric: return "DIERR_GENERIC"; + case ErrorCode::ErrorHandleExists: return "DIERR_HANDLEEXISTS"; + case ErrorCode::ErrorHasEffects: return "DIERR_HASEFFECTS"; + case ErrorCode::ErrorInCompleteEffect: return "DIERR_INCOMPLETEEFFECT"; + case ErrorCode::ErrorInputLost: return "DIERR_INPUTLOST"; + case ErrorCode::ErrorInvalidParam: return "DIERR_INVALIDPARAM"; + case ErrorCode::ErrorMapFileFail: return "DIERR_MAPFILEFAIL"; + case ErrorCode::ErrorMoreData: return "DIERR_MOREDATA"; + case ErrorCode::ErrorNoAggregation: return "DIERR_NOAGGREGATION"; + case ErrorCode::ErrorNoInterface: return "DIERR_NOINTERFACE"; + case ErrorCode::ErrorNotAcquired: return "DIERR_NOTACQUIRED"; + case ErrorCode::ErrorNotBuffered: return "DIERR_NOTBUFFERED"; + case ErrorCode::ErrorNotDownloaded: return "DIERR_NOTDOWNLOADED"; + case ErrorCode::ErrorNotExclusiveAcquired: return "DIERR_NOTEXCLUSIVEACQUIRED"; + case ErrorCode::ErrorNotfound: return "DIERR_NOTFOUND"; + case ErrorCode::ErrorNotInitialized: return "DIERR_NOTINITIALIZED"; + case ErrorCode::ErrorOldDirectInputvVersion: return "DIERR_OLDDIRECTINPUTVERSION"; + case ErrorCode::ErrorOutOfMemory: return "DIERR_OUTOFMEMORY"; + case ErrorCode::ErrorReportFull: return "DIERR_REPORTFULL"; + case ErrorCode::ErrorUnplugged: return "DIERR_UNPLUGGED"; + case ErrorCode::ErrorUnsupported: return "DIERR_UNSUPPORTED"; + case ErrorCode::ErrorHandle: return "E_HANDLE"; + case ErrorCode::ErrorPending: return "E_PENDING"; + case ErrorCode::ErrorPointer: return "E_POINTER"; default: return "Unknown error (" + std::to_string(condition) + ")"; } } }; + inline constexpr ErrorCode toErrorCode(int64_t hr) { + switch (hr) { + case DIERR_ACQUIRED: + return ErrorCode::ErrorAcquired; + case DIERR_ALREADYINITIALIZED: + return ErrorCode::ErrorAlreadyInitialized; + case DIERR_BADDRIVERVER: + return ErrorCode::ErrorBadDriverVer; + case DIERR_BETADIRECTINPUTVERSION: + return ErrorCode::ErrorBetaDirectInputVersion; + case DIERR_DEVICEFULL: + return ErrorCode::ErrorDeviceFull; + case DIERR_DEVICENOTREG: + return ErrorCode::ErrorDeviceNotReg; + case DIERR_EFFECTPLAYING: + return ErrorCode::ErrorEffectPlaying; + case DIERR_GENERIC: + return ErrorCode::ErrorGeneric; + case DIERR_HANDLEEXISTS: + return ErrorCode::ErrorHandleExists; + case DIERR_HASEFFECTS: + return ErrorCode::ErrorHasEffects; + case DIERR_INCOMPLETEEFFECT: + return ErrorCode::ErrorInCompleteEffect; + case DIERR_INPUTLOST: + return ErrorCode::ErrorInputLost; + case DIERR_INVALIDPARAM: + return ErrorCode::ErrorInvalidParam; + case DIERR_MAPFILEFAIL: + return ErrorCode::ErrorMapFileFail; + case DIERR_MOREDATA: + return ErrorCode::ErrorMoreData; + case DIERR_NOAGGREGATION: + return ErrorCode::ErrorNoAggregation; + case DIERR_NOINTERFACE: + return ErrorCode::ErrorNoInterface; + case DIERR_NOTACQUIRED: + return ErrorCode::ErrorNotAcquired; + case DIERR_NOTBUFFERED: + return ErrorCode::ErrorNotBuffered; + case DIERR_NOTDOWNLOADED: + return ErrorCode::ErrorNotDownloaded; + case DIERR_NOTEXCLUSIVEACQUIRED: + return ErrorCode::ErrorNotExclusiveAcquired; + case DIERR_NOTFOUND: + return ErrorCode::ErrorNotfound; + case DIERR_NOTINITIALIZED: + return ErrorCode::ErrorNotInitialized; + case DIERR_OLDDIRECTINPUTVERSION: + return ErrorCode::ErrorOldDirectInputvVersion; + case DIERR_OUTOFMEMORY: + return ErrorCode::ErrorOutOfMemory; + case DIERR_REPORTFULL: + return ErrorCode::ErrorReportFull; + case DIERR_UNPLUGGED: + return ErrorCode::ErrorUnplugged; + case DIERR_UNSUPPORTED: + return ErrorCode::ErrorUnsupported; + case E_HANDLE: + return ErrorCode::ErrorHandle; + case E_PENDING: + return ErrorCode::ErrorPending; + case E_POINTER: + return ErrorCode::ErrorPointer; + + default: + return static_cast(hr); + } + } + inline const ErrorCategory errorCategory; } diff --git a/engine/input/windows/GamepadDeviceDI.cpp b/engine/input/windows/GamepadDeviceDI.cpp index 3214b018a..f5a968ee1 100644 --- a/engine/input/windows/GamepadDeviceDI.cpp +++ b/engine/input/windows/GamepadDeviceDI.cpp @@ -42,14 +42,14 @@ namespace ouzel::input::windows } if (const auto result = directInput->CreateDevice(instance->guidInstance, &device, nullptr); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to create DirectInput device"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to create DirectInput device"}; // Exclusive access is needed for force feedback if (const auto result = device->SetCooperativeLevel(window, DISCL_BACKGROUND | DISCL_EXCLUSIVE); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to set DirectInput device format"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to set DirectInput device format"}; if (const auto result = device->SetDataFormat(&c_dfDIJoystick); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to set DirectInput device format"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to set DirectInput device format"}; const auto& gamepadConfig = getGamepadConfig(vendorId, productId); @@ -105,7 +105,7 @@ namespace ouzel::input::windows propertyAxisRange.diph.dwHow = DIPH_BYOFFSET; if (const auto result = device->GetProperty(DIPROP_RANGE, &propertyAxisRange.diph); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to get DirectInput device axis range property"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to get DirectInput device axis range property"}; axis.min = propertyAxisRange.lMin; axis.max = propertyAxisRange.lMax; @@ -150,18 +150,18 @@ namespace ouzel::input::windows DIDEVCAPS capabilities; capabilities.dwSize = sizeof(capabilities); if (const auto result = device->GetCapabilities(&capabilities); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to get DirectInput device capabilities"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to get DirectInput device capabilities"}; if (capabilities.dwFlags & DIDC_FORCEFEEDBACK) { if (const auto result = device->Acquire(); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to acquire DirectInput device"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to acquire DirectInput device"}; if (const auto result = device->SendForceFeedbackCommand(DISFFC_RESET); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to set DirectInput device force feedback command"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to set DirectInput device force feedback command"}; if (const auto result = device->Unacquire(); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to unacquire DirectInput device"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to unacquire DirectInput device"}; DIPROPDWORD propertyAutoCenter; propertyAutoCenter.diph.dwSize = sizeof(propertyAutoCenter); @@ -183,7 +183,7 @@ namespace ouzel::input::windows const auto result = device->SetProperty(DIPROP_BUFFERSIZE, &propertyBufferSize.diph); if (FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to set DirectInput device buffer size property"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to set DirectInput device buffer size property"}; buffered = (result != DI_POLLEDDEVICE); } @@ -202,10 +202,10 @@ namespace ouzel::input::windows if (const auto result = device->Poll(); result == DIERR_NOTACQUIRED) { if (const auto acquireResult = device->Acquire(); FAILED(acquireResult)) - throw std::system_error{acquireResult, errorCategory, "Failed to acquire DirectInput device"}; + throw std::system_error{toErrorCode(acquireResult), errorCategory, "Failed to acquire DirectInput device"}; if (const auto pollResult = device->Poll(); FAILED(pollResult)) - throw std::system_error{pollResult, errorCategory, "Failed to poll DirectInput device"}; + throw std::system_error{toErrorCode(pollResult), errorCategory, "Failed to poll DirectInput device"}; } return buffered ? checkInputBuffered() : checkInputPolled(); @@ -221,13 +221,13 @@ namespace ouzel::input::windows if (result == DIERR_NOTACQUIRED) { if (const auto acquireResult = device->Acquire(); FAILED(acquireResult)) - throw std::system_error{acquireResult, errorCategory, "Failed to acquire DirectInput device"}; + throw std::system_error{toErrorCode(acquireResult), errorCategory, "Failed to acquire DirectInput device"}; result = device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), events, &eventCount, 0); } if (FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to get DirectInput device state"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to get DirectInput device state"}; for (DWORD e = 0; e < eventCount; ++e) { @@ -298,13 +298,13 @@ namespace ouzel::input::windows if (result == DIERR_NOTACQUIRED) { if (const auto acquireResult = device->Acquire(); FAILED(acquireResult)) - throw std::system_error{acquireResult, errorCategory, "Failed to acquire DirectInput device"}; + throw std::system_error{toErrorCode(acquireResult), errorCategory, "Failed to acquire DirectInput device"}; result = device->GetDeviceState(sizeof(newDIState), &newDIState); } if (FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to get DirectInput device state"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to get DirectInput device state"}; if (hatValue != newDIState.rgdwPOV[0]) { diff --git a/engine/input/windows/InputSystemWin.cpp b/engine/input/windows/InputSystemWin.cpp index 5b96482f5..23035d65f 100644 --- a/engine/input/windows/InputSystemWin.cpp +++ b/engine/input/windows/InputSystemWin.cpp @@ -8,6 +8,7 @@ #ifndef NOMINMAX # define NOMINMAX #endif +#include #include #include #include @@ -52,7 +53,7 @@ namespace ouzel::input::windows void* directInputPointer; if (const auto result = DirectInput8Create(instance, DIRECTINPUT_VERSION, IID_IDirectInput8W, &directInputPointer, nullptr); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to initialize DirectInput"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to initialize DirectInput"}; directInput = static_cast(directInputPointer); @@ -68,7 +69,7 @@ namespace ouzel::input::windows } if (const auto result = directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumDevicesCallback, this, DIEDFL_ATTACHEDONLY); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to enumerate devices"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to enumerate devices"}; } InputSystem::~InputSystem() @@ -221,7 +222,7 @@ namespace ouzel::input::windows } if (const auto result = directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumDevicesCallback, this, DIEDFL_ATTACHEDONLY); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to enumerate devices"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to enumerate devices"}; } } @@ -246,15 +247,15 @@ namespace ouzel::input::windows IWbemServices* wbemServices = nullptr; if (const auto result = wbemLocator->ConnectServer(namespaceStr.get(), nullptr, nullptr, 0L, 0L, nullptr, nullptr, &wbemServices); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to create a connection to the WMI namespace"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to create a connection to the WMI namespace"}; if (const auto result = CoSetProxyBlanket(wbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to set authentication information"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to set authentication information"}; IEnumWbemClassObject* enumDevices = nullptr; if (const auto result = wbemServices->CreateInstanceEnum(className.get(), 0, nullptr, &enumDevices); FAILED(result)) - throw std::system_error{result, errorCategory, "Failed to create the device enumerator"}; + throw std::system_error{toErrorCode(result), errorCategory, "Failed to create the device enumerator"}; // Get 20 at a time ULONG deviceCount = 0; diff --git a/engine/network/Socket.hpp b/engine/network/Socket.hpp index 9c2ecc1eb..f9e1dc598 100644 --- a/engine/network/Socket.hpp +++ b/engine/network/Socket.hpp @@ -41,7 +41,9 @@ namespace ouzel::network } #ifdef _WIN32 - constexpr auto closeSocket = closesocket; + inline int closeSocket(SOCKET s) { + return ::closesocket(s); + } #else constexpr auto closeSocket = ::close; #endif diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt new file mode 100644 index 000000000..a16c3d116 --- /dev/null +++ b/samples/CMakeLists.txt @@ -0,0 +1,167 @@ +add_executable(samples + AnimationsSample.cpp + GameSample.cpp + GUISample.cpp + InputSample.cpp + main.cpp + MainMenu.cpp + PerspectiveSample.cpp + SoundSample.cpp + SpritesSample.cpp + RTSample.cpp +) + +target_link_libraries(samples PRIVATE ouzel) + +set(SAMPLE_RESOURCES + 24-bit.wav + 8-bit.json + 8-bit.wav + ambient.wav + AmosisTechnik.ttf + arrow.png + assets.json + ball.png + cube.mtl + cube.obj + cube.png + cursor.png + fire.json + fire.png + flame.json + flame.png + floor.jpg + gui.zip + jump.wav + lv.mo + music.ogg + run.json + run.png + triangle.json + triangle.png + witch.png +) + +foreach(RESOURCE ${SAMPLE_RESOURCES}) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Resources/${RESOURCE} + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${CMAKE_CURRENT_LIST_DIR}/Resources/${RESOURCE} ${CMAKE_CURRENT_BINARY_DIR}/Resources/${RESOURCE} + DEPENDS ${CMAKE_CURRENT_LIST_DIR}/Resources/${RESOURCE} + ) + add_custom_target(ouzel-sample-copy-${RESOURCE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Resources/${RESOURCE} + ) + add_dependencies(samples ouzel-sample-copy-${RESOURCE}) +endforeach() + +if(WIN32) + target_link_libraries(samples PRIVATE + d3d11 + opengl32 + dxguid + xinput9_1_0 + shlwapi + version + dinput8 + user32 + gdi32 + shell32 + ole32 + oleaut32 + uuid + ws2_32 + ) + target_link_options(samples PRIVATE "-subsystem:WINDOWS") +elseif(UNIX AND NOT APPLE) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") # arm linux + target_link_directories(samples PRIVATE /opt/vc/lib) + target_link_libraries(samples PRIVATE + -lbrcmGLESv2 + -lbrcmEGL + -lbcm_host + ) + else() + target_link_libraries(samples PRIVATE + -lGL + -lEGL + -lX11 + -lXcursor + -lXss + -lXi + -lXxf86vm + -lXrandr + ) + endif() + target_link_libraries(samples PRIVATE + -lopenal + -lpthread + -lasound + -ldl + ) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + target_link_libraries(samples PRIVATE + "-framework AudioToolbox" + "-framework AudioUnit" + "-framework Cocoa" + "-framework CoreAudio" + "-framework CoreVideo" + "-framework GameController" + "-framework IOKit" + "-framework Metal" + "-framework OpenAL" + "-framework OpenGL" + "-framework QuartzCore" + ) +elseif(IOS) + target_link_libraries(samples PRIVATE + "-framework AudioToolbox" + "-framework AVFoundation" + "-framework Foundation" + "-framework GameController" + "-framework Metal" + "-framework OpenAL" + "-framework OpenGLES" + "-framework QuartzCore" + "-framework UIKit" + ) + execute_process( + COMMAND xcrun --sdk iphoneos --show-sdk-path + OUTPUT_VARIABLE IOS_SYS_ROOT + ) + target_compile_options(samples + PRIVATE + -arch arm64 + -isysroot + ${IOS_SYS_ROOT} + -miphoneos-version-min=8.0) +elseif(CMAKE_SYSTEM_NAME STREQUAL "tvos") + target_link_libraries(samples PRIVATE + "-framework AudioToolbox" + "-framework AVFoundation" + "-framework Foundation" + "-framework GameController" + "-framework Metal" + "-framework OpenAL" + "-framework OpenGLES" + "-framework QuartzCore" + "-framework UIKit" + ) + execute_process( + COMMAND xcrun --sdk appletvos --show-sdk-path + OUTPUT_VARIABLE TVOS_SYS_ROOT + ) + target_compile_options(ouzel + PRIVATE + -arch arm64 + -isysroot + ${TVOS_SYS_ROOT} + -mtvos-version-min=9.0) +elseif(EMSCRIPTEN) + target_link_options(samples PRIVATE + -lopenal + --embed-file settings.ini + --embed-file Resources + -s DISABLE_EXCEPTION_CATCHING=0 + -s TOTAL_MEMORY=134217728 + ) +endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..9a1f317e0 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(ouzel-test + main.cpp +) + +target_link_libraries(ouzel-test PRIVATE ouzel) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000..ed1aa6099 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,37 @@ +add_executable(ouzel-build + ouzel/main.cpp + ouzel/Asset.hpp + ouzel/Platform.hpp + ouzel/Project.hpp + ouzel/Target.hpp + ouzel/makefile/BuildSystem.hpp + ouzel/visualstudio/BuildSystem.hpp + ouzel/visualstudio/Solution.hpp + ouzel/visualstudio/VcxProject.hpp + ouzel/visualstudio/VcxProjectFilters.hpp + ouzel/xcode/BuildSystem.hpp + ouzel/xcode/PBXBuildFile.hpp + ouzel/xcode/PBXBuildPhase.hpp + ouzel/xcode/PBXContainerItemProxy.hpp + ouzel/xcode/PBXFileElement.hpp + ouzel/xcode/PBXFileReference.hpp + ouzel/xcode/PBXFileType.hpp + ouzel/xcode/PBXFrameworksBuildPhase.hpp + ouzel/xcode/PBXGroup.hpp + ouzel/xcode/PBXLegacyTarget.hpp + ouzel/xcode/PBXNativeTarget.hpp + ouzel/xcode/PBXObject.hpp + ouzel/xcode/PBXProject.hpp + ouzel/xcode/PBXReferenceProxy.hpp + ouzel/xcode/PBXResourcesBuildPhase.hpp + ouzel/xcode/PBXShellScriptBuildPhase.hpp + ouzel/xcode/PBXSourceTree.hpp + ouzel/xcode/PBXSourcesBuildPhase.hpp + ouzel/xcode/PBXTarget.hpp + ouzel/xcode/PBXTargetDependency.hpp + ouzel/xcode/XCBuildConfiguration.hpp + ouzel/xcode/XCConfigurationList.hpp + ouzel/xcode/XcodeProject.hpp +) + +target_link_libraries(ouzel-build PRIVATE ouzel) diff --git a/tools/ouzel/Platform.hpp b/tools/ouzel/Platform.hpp index 65bcbd353..a63e53183 100644 --- a/tools/ouzel/Platform.hpp +++ b/tools/ouzel/Platform.hpp @@ -6,6 +6,9 @@ #include #include +// some compilers pre-defines macro 'linux', which clashes with some namespace and enum names +#undef linux + namespace ouzel { enum class Platform