diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..3bb10018 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,137 @@ +name: CI + +on: [push, pull_request] + +jobs: + clang-format: + name: 'clang-format' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run clang-format + run: | + find CONFIG LEGO1 ISLE miniwin -iname '*.h' -o -iname '*.cpp' | xargs \ + pipx run "clang-format>=17,<18" \ + --style=file \ + -i + - name: Check diff + run: | + git diff --exit-code + + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + defaults: + run: + shell: ${{ matrix.shell || 'sh' }} + + strategy: + fail-fast: false + matrix: + include: + - { name: 'Linux', os: 'ubuntu-latest', dx5: false, build-type: 'Debug', linux: true, werror: true, clang-tify: true } + - { name: 'MSVC (x86)', os: 'windows-latest', dx5: true, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64_x86' } + - { name: 'MSVC (x64)', os: 'windows-latest', dx5: false, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64' } + - { name: 'MSVC (arm64)', os: 'windows-latest', dx5: false, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64_arm64' } + - { name: 'msys2 mingw32', os: 'windows-latest', dx5: false, build-type: 'Debug', mingw: true, werror: true, clang-tify: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' } + - { name: 'msys2 mingw64', os: 'windows-latest', dx5: false, build-type: 'Debug', mingw: true, werror: true, clang-tify: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' } + - { name: 'macOS', os: 'macos-latest', dx5: false, build-type: 'Debug', brew: true, werror: true, clang-tify: true } + steps: + - name: Setup vcvars + if: ${{ !!matrix.msvc }} + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.vc-arch }} + + - name: Set up MSYS2 + if: ${{ !!matrix.msystem }} + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: >- + ${{ matrix.msys-env }}-cc + ${{ matrix.msys-env }}-cmake + ${{ matrix.msys-env }}-ninja + ${{ matrix.msys-env }}-clang-tools-extra + + - name: Install Linux dependencies (apt-get) + if: ${{ matrix.linux }} + run: | + sudo apt-get update + sudo apt-get install -y \ + libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols + + - name: Install macOS dependencies (brew) + if: ${{ matrix.brew }} + run: | + brew update + brew install cmake ninja llvm + echo "LLVM_ROOT=$(brew --prefix llvm)/bin" >> $GITHUB_ENV + + - name: Setup ninja + if: ${{ matrix.msvc }} + uses: ashutoshvarma/setup-ninja@master + + - uses: actions/checkout@v4 + + - name: Configure (CMake) + run: | + cmake -S . -B build -GNinja \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ + -DISLE_USE_DX5=${{ !!matrix.dx5 }} \ + -DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \ + -DISLE_WERROR=${{ !!matrix.werror }} \ + -Werror=dev + + - name: Build (CMake) + run: cmake --build build --verbose -- -k0 + + - name: Package (CPack) + run: | + cd build + cpack . + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: '${{ matrix.name }} ${{ matrix.build-type }}' + path: build/dist/isle-* + + ncc: + name: 'C++' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v1 + with: + version: "16" + + - name: Install python libraries + run: | + pip install -r tools/requirements.txt + + - name: Run ncc + run: | + action_headers=$(find LEGO1/lego/legoomni/include/actions \ + -name '*.h' -print0 | xargs -0 echo) + + python3 tools/ncc/ncc.py \ + --clang-lib ${{ env.LLVM_PATH }}/lib/libclang.so \ + --recurse \ + --style tools/ncc/ncc.style \ + --skip tools/ncc/skip.yml \ + --definition WINAPI FAR BOOL CALLBACK HWND__=HWND SDLCALL \ + --include \ + util \ + LEGO1 \ + LEGO1/omni/include \ + LEGO1/lego/legoomni/include \ + LEGO1/lego/sources \ + --exclude \ + LEGO1/omni/include/flic.h \ + LEGO1/omni/src/video/flic.cpp \ + $action_headers \ + --path LEGO1/omni LEGO1/lego/legoomni diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index e5f2d4de..00000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Format - -on: [push, pull_request] - -jobs: - clang-format: - name: 'C++' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Run clang-format - run: | - find CONFIG LEGO1 ISLE miniwin -iname '*.h' -o -iname '*.cpp' | xargs \ - pipx run "clang-format>=17,<18" \ - --style=file \ - -i - git diff --exit-code diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 242ca537..00000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Linux - -on: [push, pull_request] - -jobs: - build-linux: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - build-type: [Release, Debug] - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols - - - name: Configure - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ - -DISLE_USE_DX5=OFF \ - -DENABLE_CLANG_TIDY=ON \ - -DISLE_WERROR=ON \ - -Werror=dev - - - name: Build - run: cmake --build build -- -k0 - - - name: Make Artifact Archive - run: | - cd build - zip "isle-portable-linux-${{ matrix.build-type }}.zip" \ - config isle liblego1.so - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: linux-artifacts-${{ matrix.build-type }} - path: build/isle-portable-linux-${{ matrix.build-type }}.zip diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml deleted file mode 100644 index f8f97029..00000000 --- a/.github/workflows/mac.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: macOS - -on: [push, pull_request] - -jobs: - build-macos: - runs-on: macos-latest - - strategy: - fail-fast: false - matrix: - build-type: [Release, Debug] - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - brew update - brew install cmake ninja llvm - echo "CLANG_TIDY=$(brew --prefix llvm)/bin/clang-tidy" >> $GITHUB_ENV - - - name: Configure - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ - -DISLE_USE_DX5=OFF \ - -DENABLE_CLANG_TIDY=ON \ - -DCLANG_TIDY_BIN=$CLANG_TIDY \ - -DISLE_WERROR=ON \ - -Werror=dev - - - name: Build - run: cmake --build build -- -k0 - - - name: Make Artifact Archive - run: | - cd build - zip "isle-portable-macos-${{ matrix.build-type }}.zip" \ - config isle liblego1.dylib - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: macos-artifacts-${{ matrix.build-type }} - path: build/isle-portable-macos-${{ matrix.build-type }}.zip diff --git a/.github/workflows/naming.yml b/.github/workflows/naming.yml deleted file mode 100644 index 20ffddff..00000000 --- a/.github/workflows/naming.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Naming - -on: [push, pull_request] - -jobs: - ncc: - name: 'C++' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install LLVM and Clang - uses: KyleMayes/install-llvm-action@v1 - with: - version: "16" - - - name: Install python libraries - run: | - pip install -r tools/requirements.txt - - - name: Run ncc - run: | - action_headers=$(find LEGO1/lego/legoomni/include/actions \ - -name '*.h' -print0 | xargs -0 echo) - - python3 tools/ncc/ncc.py \ - --clang-lib ${{ env.LLVM_PATH }}/lib/libclang.so \ - --recurse \ - --style tools/ncc/ncc.style \ - --skip tools/ncc/skip.yml \ - --definition WINAPI FAR BOOL CALLBACK HWND__=HWND SDLCALL \ - --include \ - util \ - LEGO1 \ - LEGO1/omni/include \ - LEGO1/lego/legoomni/include \ - LEGO1/lego/sources \ - --exclude \ - LEGO1/omni/include/flic.h \ - LEGO1/omni/src/video/flic.cpp \ - $action_headers \ - --path LEGO1/omni LEGO1/lego/legoomni diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 9d63a110..00000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,120 +0,0 @@ -name: Windows - -on: [push, pull_request] - -jobs: - build-current-toolchain: - name: 'Current ${{ matrix.toolchain.name }}' - runs-on: windows-latest - defaults: - run: - shell: ${{ matrix.toolchain.shell }} - strategy: - fail-fast: false - matrix: - toolchain: - - { name: 'MSVC (32-bit, Release)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_x86', dx5-libs: true, build-type: 'Release' } - - { name: 'MSVC (32-bit, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_x86', dx5-libs: true, build-type: 'Debug' } - - { name: 'MSVC (64-bit, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64', dx5-libs: false, build-type: 'Debug' } - - { name: 'MSVC (ARM64, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_arm64', dx5-libs: false, build-type: 'Debug' } - - { name: 'msys2 mingw32 (Debug)', shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686, clang-tidy: true, werror: true, dx5-libs: false, build-type: 'Debug' } - - { name: 'msys2 mingw64 (Debug)', shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64, clang-tidy: true, werror: true, dx5-libs: false, build-type: 'Debug' } - # - { name: 'msys2 clang32', shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686, clang-tidy: true, werror: true, dx5-libs: true, d3drm-from-wine: true } - - steps: - - name: Setup vcvars - if: matrix.toolchain.setup-msvc - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.toolchain.vc-arch }} - # Figure out how to build for 32-bit arch - # - name: Set up SDL - # id: sdl - # uses: libsdl-org/setup-sdl@main - # with: - # version: sdl3-head - - - name: Set up MSYS2 - if: ${{ !!matrix.toolchain.msystem }} - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.toolchain.msystem }} - install: >- - ${{ matrix.toolchain.msys-env }}-cc - ${{ matrix.toolchain.msys-env }}-cmake - ${{ matrix.toolchain.msys-env }}-ninja - ${{ matrix.toolchain.msys-env }}-clang-tools-extra - - - name: Setup cmake - if: matrix.toolchain.setup-cmake - uses: jwlawson/actions-setup-cmake@v1.13 - - - name: Setup ninja - if: matrix.toolchain.setup-ninja - uses: ashutoshvarma/setup-ninja@master - - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Build - # Add -DDOWNLOAD_DEPENDENCIES=OFF once setup-sdl works - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.toolchain.build-type }} \ - -DISLE_USE_DX5=${{ matrix.toolchain.dx5-libs }} \ - -DENABLE_CLANG_TIDY=${{ !!matrix.toolchain.clang-tidy }} \ - -DISLE_WERROR=${{ !!matrix.toolchain.werror }} \ - -Werror=dev - cmake --build build -- -k0 - - # Needs to be reworked when cross-platform building is achieved - - - name: Make Artifact Archive - shell: bash - run: | - cd build - 7z a "isle-portable (${{ matrix.toolchain.name }}).zip" \ - isle.exe lego1.dll sdl3.dll - - - name: Upload Build Artifacts (MSVC (32-bit)) - if: ${{ matrix.toolchain.name == 'MSVC (32-bit, Release)' || matrix.toolchain.name == 'MSVC (32-bit, Debug)' }} - uses: actions/upload-artifact@v4 - with: - name: msvc32-artifacts-${{ matrix.toolchain.name }} - path: | - build/isle-portable (${{ matrix.toolchain.name }}).zip - - merge-artifacts: - name: 'Merge artifacts' - runs-on: ubuntu-latest - needs: build-current-toolchain - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: msvc32-artifacts - pattern: msvc32-artifacts-* - - upload: - name: 'Upload artifacts' - needs: merge-artifacts - runs-on: ubuntu-latest - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'isledecomp/isle-portable' }} - steps: - - uses: actions/checkout@v4 - with: - repository: 'probonopd/uploadtool' - - - uses: actions/download-artifact@v4 - with: - name: msvc32-artifacts - path: build - - - name: Upload Continuous Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - UPLOAD_KEY: ${{ secrets.UPLOAD_KEY }} - run: | - ./upload.sh \ - build/*.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index 303e7619..3b523183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR) -project(isle CXX C) +project(isle LANGUAGES CXX C VERSION 0.1) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") @@ -69,7 +69,7 @@ endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN NAMES "clang-tidy") + find_program(CLANG_TIDY_BIN NAMES "clang-tidy" ENV "LLVM_ROOT" REQUIRED) set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_BIN}") set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}") endif() @@ -87,11 +87,14 @@ endif() #if (NOT WIN32) add_library(miniwin STATIC EXCLUDE_FROM_ALL miniwin/miniwin/src/miniwin.cpp + miniwin/miniwin/src/miniwin_ddclipper.cpp + miniwin/miniwin/src/miniwin_ddpalette.cpp + miniwin/miniwin/src/miniwin_ddsurface.cpp miniwin/miniwin/src/miniwin_ddraw.cpp - miniwin/miniwin/src/miniwin_d3d.cpp miniwin/miniwin/src/miniwin_d3drm.cpp ) target_include_directories(miniwin PUBLIC "$") +target_include_directories(miniwin PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/src/include") target_compile_definitions(miniwin PUBLIC "MINIWIN") target_link_libraries(miniwin PRIVATE SDL3::SDL3) @@ -570,3 +573,33 @@ if (EXISTS "${CLANGFORMAT_BIN}") endif() endif() endif() + +set(install_extra_targets) +if(DOWNLOAD_DEPENDENCIES) + get_property(sdl3_type TARGET SDL3::SDL3 PROPERTY TYPE) + if(sdl3_type STREQUAL "SHARED_LIBRARY") + list(APPEND install_extra_targets "SDL3-shared") + endif() +endif() + +if(MSVC) + set(CMAKE_INSTALL_BINDIR "." CACHE PATH "Binary install directory") + set(CMAKE_INSTALL_LIBDIR "." CACHE PATH "Binary install directory") +else() + include(GNUInstallDirs) +endif() + +set(ISLE_PACKAGE_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Platform name of the package") +install(TARGETS isle lego1 ${install_extra_targets} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(CPACK_PACKAGE_DIRECTORY "dist") +set(CPACK_PACKAGE_FILE_NAME "isle-${PROJECT_VERSION}-${ISLE_PACKAGE_NAME}-${CMAKE_SYSTEM_PROCESSOR}") +if(MSVC) + set(CPACK_GENERATOR ZIP) +else() + set(CPACK_GENERATOR TGZ) +endif() +include(CPack) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index ae034a2e..a16b6251 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -30,6 +30,8 @@ #include "roi/legoroi.h" #include "viewmanager/viewmanager.h" +#include + #define SDL_MAIN_USE_CALLBACKS #include #include @@ -289,7 +291,16 @@ SDL_AppResult SDL_AppIterate(void* appstate) return SDL_APP_SUCCESS; } - g_isle->Tick(); + if (!g_isle->Tick()) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "LEGO® Island Error", + "\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again." + "\nFailed to initialize; see logs for details", + NULL + ); + return SDL_APP_FAILURE; + } if (!g_closed) { if (g_reqEnableRMDevice) { @@ -304,7 +315,16 @@ SDL_AppResult SDL_AppIterate(void* appstate) } if (g_mousedown && g_mousemoved && g_isle) { - g_isle->Tick(); + if (!g_isle->Tick()) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "LEGO® Island Error", + "\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again." + "\nFailed to initialize; see logs for details", + NULL + ); + return SDL_APP_FAILURE; + } } if (g_mousemoved) { @@ -683,7 +703,7 @@ bool IsleApp::LoadConfig() } // FUNCTION: ISLE 0x402c20 -inline void IsleApp::Tick() +inline bool IsleApp::Tick() { // GLOBAL: ISLE 0x4101c0 static MxLong g_lastFrameTime = 0; @@ -693,17 +713,17 @@ inline void IsleApp::Tick() if (!m_windowActive) { SDL_Delay(1); - return; + return true; } if (!Lego()) { - return; + return true; } if (!TickleManager()) { - return; + return true; } if (!Timer()) { - return; + return true; } MxLong currentTime = Timer()->GetRealTime(); @@ -713,7 +733,7 @@ inline void IsleApp::Tick() if (m_frameDelta + g_lastFrameTime >= currentTime) { SDL_Delay(1); - return; + return true; } if (!Lego()->IsPaused()) { @@ -722,12 +742,12 @@ inline void IsleApp::Tick() g_lastFrameTime = currentTime; if (g_startupDelay == 0) { - return; + return true; } g_startupDelay--; if (g_startupDelay != 0) { - return; + return true; } LegoOmni::GetInstance()->CreateBackgroundAudio(); @@ -739,7 +759,8 @@ inline void IsleApp::Tick() if (!stream) { stream = Streamer()->Open("\\lego\\scripts\\nocd", MxStreamer::e_diskStream); if (!stream) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Streamer failed to load"); + return false; } ds.SetAtomId(stream->GetAtom()); @@ -748,7 +769,8 @@ inline void IsleApp::Tick() VideoManager()->EnableFullScreenMovie(TRUE, TRUE); if (Start(&ds) != SUCCESS) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Failed to start initial action"); + return false; } } else { @@ -756,10 +778,13 @@ inline void IsleApp::Tick() ds.SetUnknown24(-1); ds.SetObjectId(0); if (Start(&ds) != SUCCESS) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open ISLE.si: Failed to start initial action"); + return false; } m_gameStarted = TRUE; } + + return true; } // FUNCTION: ISLE 0x402e80 diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index 979ef16c..7fd3c84f 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -37,7 +37,7 @@ class IsleApp { MxResult SetupWindow(); bool LoadConfig(); - void Tick(); + bool Tick(); void SetupCursor(Cursor p_cursor); static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags); diff --git a/LEGO1/mxdirectx/mxdirectxinfo.cpp b/LEGO1/mxdirectx/mxdirectxinfo.cpp index d41e195a..f2d32e9c 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.cpp +++ b/LEGO1/mxdirectx/mxdirectxinfo.cpp @@ -42,7 +42,7 @@ MxDriver::MxDriver(LPGUID p_guid) // FUNCTION: CONFIG 0x00401180 // FUNCTION: LEGO1 0x1009ba80 // FUNCTION: BETA10 0x1011d8b6 -MxDriver::MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +MxDriver::MxDriver(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName) { m_guid = NULL; m_driverDesc = NULL; @@ -71,7 +71,7 @@ MxDriver::~MxDriver() // FUNCTION: CONFIG 0x00401330 // FUNCTION: LEGO1 0x1009bc30 // FUNCTION: BETA10 0x1011da89 -void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +void MxDriver::Init(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName) { if (m_driverDesc) { delete[] m_driverDesc; @@ -104,8 +104,8 @@ void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) // FUNCTION: BETA10 0x1011dbd0 Direct3DDeviceInfo::Direct3DDeviceInfo( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) @@ -136,8 +136,8 @@ Direct3DDeviceInfo::~Direct3DDeviceInfo() // FUNCTION: BETA10 0x1011dca6 void Direct3DDeviceInfo::Initialize( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) @@ -318,8 +318,8 @@ HRESULT MxDeviceEnumerate::EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd) // FUNCTION: BETA10 0x1011e32f HRESULT MxDeviceEnumerate::EnumDevicesCallback( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) diff --git a/LEGO1/mxdirectx/mxdirectxinfo.h b/LEGO1/mxdirectx/mxdirectxinfo.h index 15745abd..0dcb7d43 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.h +++ b/LEGO1/mxdirectx/mxdirectxinfo.h @@ -71,16 +71,16 @@ struct Direct3DDeviceInfo { ~Direct3DDeviceInfo(); Direct3DDeviceInfo( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); void Initialize( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); @@ -119,9 +119,9 @@ struct MxDriver { MxDriver() {} ~MxDriver(); MxDriver(LPGUID p_guid); - MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); + MxDriver(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName); - void Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); + void Init(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName); LPGUID m_guid; // 0x00 char* m_driverDesc; // 0x04 @@ -202,8 +202,8 @@ class MxDeviceEnumerate { HRESULT EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd); HRESULT EnumDevicesCallback( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 4f37f18a..878129d2 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -204,7 +204,7 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) ddsd.dwSize = sizeof(ddsd); ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers(); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX; if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDraw::CreateSurface failed"); diff --git a/miniwin/minimfc/include/minimfc.h b/miniwin/minimfc/include/minimfc.h index 02aa9a52..5df522a3 100644 --- a/miniwin/minimfc/include/minimfc.h +++ b/miniwin/minimfc/include/minimfc.h @@ -24,8 +24,6 @@ #define FAILED(hr) (((HRESULT) (hr)) < 0) #define InterlockedIncrement(x) __sync_add_and_fetch(x, 1) -#define INVALID_HANDLE ((HANDLE) -1) -#define INVALID_HANDLE_VALUE ((HANDLE) -1) #define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002) #define LOWORD(l) ((WORD) (((DWORD_PTR) (l)) & 0xffff)) #define MAKEINTRESOURCE(i) (reinterpret_cast((ULONG_PTR) ((WORD) (i)))) @@ -130,7 +128,7 @@ struct CMenu { struct CWinApp { CWinApp(); - virtual ~CWinApp() = default; + ~CWinApp() = default; virtual BOOL InitInstance() = 0; virtual int ExitInstance(); }; diff --git a/miniwin/miniwin/include/miniwin.h b/miniwin/miniwin/include/miniwin.h index dd095581..5350128f 100644 --- a/miniwin/miniwin/include/miniwin.h +++ b/miniwin/miniwin/include/miniwin.h @@ -16,7 +16,7 @@ #define CALLBACK #define FAR #define WINAPI -#define HWND_NOTOPMOST (HWND) - 2 +#define HWND_NOTOPMOST -2 #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) #define S_OK ((HRESULT) 0) #define E_NOINTERFACE (0x80004002) @@ -143,14 +143,11 @@ struct IUnknown { virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject); virtual ~IUnknown() = default; -private: +protected: int m_refCount; }; -inline BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) -{ - return TRUE; -} +BOOL SetWindowPos(HWND hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); inline HDC WINAPI GetDC(HWND hWnd) { diff --git a/miniwin/miniwin/include/miniwin_d3drm.h b/miniwin/miniwin/include/miniwin_d3drm.h index c42bab0b..d6fc97b6 100644 --- a/miniwin/miniwin/include/miniwin_d3drm.h +++ b/miniwin/miniwin/include/miniwin_d3drm.h @@ -8,6 +8,7 @@ #define D3DRM_OK DD_OK #define MAXSHORT ((short) 0x7fff) #define SUCCEEDED(hr) ((hr) >= D3DRM_OK) +#define D3DRMERR_NOTFOUND MAKE_DDHRESULT(785) // --- Typedefs --- typedef float D3DVAL; @@ -16,6 +17,9 @@ typedef unsigned long D3DRMGROUPINDEX; typedef DWORD D3DCOLOR, *LPD3DCOLOR; typedef float D3DVALUE, *LPD3DVALUE; +typedef struct IDirect3DRMObject* LPDIRECT3DRMOBJECT; +typedef void (*D3DRMOBJECTCALLBACK)(LPDIRECT3DRMOBJECT obj, LPVOID arg); + // --- Enums --- #define D3DRMCOMBINE_REPLACE D3DRMCOMBINETYPE::REPLACE enum class D3DRMCOMBINETYPE { @@ -140,35 +144,31 @@ struct D3DRMVERTEX { float tu, tv; }; -struct IDirect3DRMVisual : virtual public IUnknown {}; -typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL; - -struct IDirect3DRMObject : virtual public IUnknown { +struct IDirect3DRMObject : public IUnknown { virtual HRESULT Clone(void** ppObject) = 0; - virtual HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; - virtual HRESULT DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; + virtual HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0; + virtual HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0; virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; virtual LPVOID GetAppData() = 0; virtual HRESULT SetName(const char* name) = 0; virtual HRESULT GetName(DWORD* size, char* name) = 0; - virtual HRESULT GetClassName(DWORD* size, char* name) = 0; }; -struct IDirect3DRMTexture : virtual public IUnknown { - virtual HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; - virtual LPVOID GetAppData() = 0; - virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; - virtual HRESULT SetTexture(const IDirect3DRMTexture* texture) = 0; - virtual HRESULT Changed(BOOL arg1, BOOL arg2) = 0; + +struct IDirect3DRMVisual : public IDirect3DRMObject {}; +typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL; + +struct IDirect3DRMTexture : public IDirect3DRMVisual { + virtual HRESULT Changed(BOOL pixels, BOOL palette) = 0; }; typedef IDirect3DRMTexture* LPDIRECT3DRMTEXTURE; struct IDirect3DRMTexture2 : public IDirect3DRMTexture {}; typedef IDirect3DRMTexture2* LPDIRECT3DRMTEXTURE2; -struct IDirect3DRMMaterial : virtual public IUnknown {}; +struct IDirect3DRMMaterial : public IDirect3DRMObject {}; typedef IDirect3DRMMaterial *LPDIRECT3DRMMATERIAL, **LPLPDIRECT3DRMMATERIAL; -struct IDirect3DRMMesh : virtual public IUnknown { +struct IDirect3DRMMesh : public IDirect3DRMVisual { virtual HRESULT Clone(int flags, GUID iid, void** object) = 0; virtual HRESULT GetBox(D3DRMBOX* box) = 0; virtual HRESULT AddGroup( @@ -188,7 +188,7 @@ struct IDirect3DRMMesh : virtual public IUnknown { ) = 0; virtual HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) = 0; virtual HRESULT SetGroupColorRGB(int groupIndex, float r, float g, float b) = 0; - virtual HRESULT SetGroupTexture(int groupIndex, const IDirect3DRMTexture* texture) = 0; + virtual HRESULT SetGroupTexture(int groupIndex, IDirect3DRMTexture* texture) = 0; virtual HRESULT SetGroupMaterial(int groupIndex, IDirect3DRMMaterial* material) = 0; virtual HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) = 0; virtual HRESULT SetGroupQuality(int groupIndex, D3DRMRENDERQUALITY quality) = 0; @@ -200,24 +200,28 @@ struct IDirect3DRMMesh : virtual public IUnknown { virtual HRESULT GetVertices(int groupIndex, int startIndex, int count, D3DRMVERTEX* vertices) = 0; }; -struct IDirect3DRMLight : virtual public IUnknown { +struct IDirect3DRMLight : public IDirect3DRMObject { virtual HRESULT SetColorRGB(float r, float g, float b) = 0; }; -struct IDirect3DRMLightArray : virtual public IUnknown { +struct IDirect3DRMArray : public IUnknown { virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMLight** light) const = 0; }; -struct IDirect3DRMVisualArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMVisual** visual) const = 0; +struct IDirect3DRMLightArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMLight** out) = 0; + virtual HRESULT AddElement(IDirect3DRMLight* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMLight* element) = 0; +}; + +struct IDirect3DRMVisualArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMVisual** out) = 0; + virtual HRESULT AddElement(IDirect3DRMVisual* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMVisual* element) = 0; }; typedef struct IDirect3DRMFrameArray* LPDIRECT3DRMFRAMEARRAY; -struct IDirect3DRMFrame : virtual public IUnknown { - virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; - virtual LPVOID GetAppData() = 0; +struct IDirect3DRMFrame : public IDirect3DRMVisual { virtual HRESULT AddChild(IDirect3DRMFrame* child) = 0; virtual HRESULT DeleteChild(IDirect3DRMFrame* child) = 0; virtual HRESULT SetSceneBackgroundRGB(float r, float g, float b) = 0; @@ -232,7 +236,7 @@ struct IDirect3DRMFrame : virtual public IUnknown { virtual HRESULT AddVisual(IDirect3DRMFrame* visual) = 0; virtual HRESULT DeleteVisual(IDirect3DRMFrame* visual) = 0; virtual HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) = 0; - virtual HRESULT SetTexture(const IDirect3DRMTexture* texture) = 0; + virtual HRESULT SetTexture(IDirect3DRMTexture* texture) = 0; virtual HRESULT GetTexture(IDirect3DRMTexture** texture) = 0; virtual HRESULT SetColor(float r, float g, float b, float a) = 0; virtual HRESULT SetColor(D3DCOLOR) = 0; @@ -242,22 +246,22 @@ struct IDirect3DRMFrame : virtual public IUnknown { }; typedef IDirect3DRMFrame* LPDIRECT3DRMFRAME; +struct IDirect3DRMFrameArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMFrame** out) = 0; + virtual HRESULT AddElement(IDirect3DRMFrame* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMFrame* element) = 0; +}; + struct IDirect3DRMFrame2 : public IDirect3DRMFrame {}; typedef IDirect3DRMFrame2* LPDIRECT3DRMFRAME2; -struct IDirect3DRMFrameArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(DWORD index, IDirect3DRMFrame** frame) = 0; -}; - struct D3DRMPICKDESC { IDirect3DRMVisual* visual; IDirect3DRMFrame* frame; float dist; }; -struct IDirect3DRMPickedArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; +struct IDirect3DRMPickedArray : public IDirect3DRMArray { virtual HRESULT GetPick( DWORD index, IDirect3DRMVisual** visual, @@ -288,19 +292,20 @@ struct IDirect3DRMViewport : public IDirect3DRMObject { virtual HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) = 0; }; -struct IDirect3DRMWinDevice : virtual public IUnknown { +struct IDirect3DRMViewportArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMViewport** out) = 0; + virtual HRESULT AddElement(IDirect3DRMViewport* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMViewport* element) = 0; +}; + +struct IDirect3DRMWinDevice : virtual public IDirect3DRMObject { virtual HRESULT Activate() = 0; virtual HRESULT Paint() = 0; virtual void HandleActivate(WORD wParam) = 0; virtual void HandlePaint(void* p_dc) = 0; }; -struct IDirect3DRMViewportArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMViewport** viewport) = 0; -}; - -struct IDirect3DRMDevice2 : virtual public IUnknown { +struct IDirect3DRMDevice : virtual public IDirect3DRMObject { virtual unsigned long GetWidth() = 0; virtual unsigned long GetHeight() = 0; virtual HRESULT SetBufferCount(int count) = 0; @@ -316,9 +321,12 @@ struct IDirect3DRMDevice2 : virtual public IUnknown { virtual HRESULT SetRenderMode(D3DRMRENDERMODE mode) = 0; virtual D3DRMRENDERMODE GetRenderMode() = 0; virtual HRESULT Update() = 0; + virtual HRESULT AddViewport(IDirect3DRMViewport* viewport) = 0; virtual HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) = 0; }; +struct IDirect3DRMDevice2 : virtual public IDirect3DRMDevice {}; + struct IDirect3DRM : virtual public IUnknown { virtual HRESULT CreateDeviceFromD3D( const IDirect3D2* d3d, diff --git a/miniwin/miniwin/src/include/miniwin_ddclipper_p.h b/miniwin/miniwin/src/include/miniwin_ddclipper_p.h new file mode 100644 index 00000000..0c094824 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddclipper_p.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +class DirectDrawImpl; + +struct DirectDrawClipperImpl : public IDirectDrawClipper { + DirectDrawClipperImpl(DirectDrawImpl* lpDD); + ~DirectDrawClipperImpl() override; + + // IDirectDrawClipper interface + HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h new file mode 100644 index 00000000..04804431 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h @@ -0,0 +1,10 @@ +#pragma once + +#include "miniwin_ddraw.h" + +struct DirectDrawPaletteImpl : public IDirectDrawPalette { + DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable); + HRESULT GetCaps(LPDWORD lpdwCaps) override; + HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) override; + HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddraw_p.h b/miniwin/miniwin/src/include/miniwin_ddraw_p.h new file mode 100644 index 00000000..1dba2d71 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddraw_p.h @@ -0,0 +1,37 @@ +#pragma once + +#include "miniwin_d3d.h" +#include "miniwin_ddraw.h" + +extern struct SDL_Renderer* renderer; + +struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { + // IUnknown interface + HRESULT QueryInterface(const GUID& riid, void** ppvObject) override; + // IDirectDraw interface + HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) override; + HRESULT + CreatePalette( + DDPixelCaps dwFlags, + LPPALETTEENTRY lpColorTable, + LPDIRECTDRAWPALETTE* lplpDDPalette, + IUnknown* pUnkOuter + ) override; + HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) + override; + HRESULT EnumDisplayModes( + DWORD dwFlags, + LPDDSURFACEDESC lpDDSurfaceDesc, + LPVOID lpContext, + LPDDENUMMODESCALLBACK lpEnumModesCallback + ) override; + HRESULT FlipToGDISurface() override; + HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override; + HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override; + HRESULT RestoreDisplayMode() override; + HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) override; + HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override; + // IDirect3D2 interface + HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override; + HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h new file mode 100644 index 00000000..e20d42ac --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { + DirectDrawSurfaceImpl(); + DirectDrawSurfaceImpl(int width, int height); + ~DirectDrawSurfaceImpl() override; + + // IUnknown interface + HRESULT QueryInterface(const GUID& riid, void** ppvObject) override; + // IDirectDrawSurface interface + HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override; + HRESULT Blt( + LPRECT lpDestRect, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFlags dwFlags, + LPDDBLTFX lpDDBltFx + ) override; + HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans) + override; + HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override; + HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override; + HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override; + HRESULT GetDC(HDC* lphDC) override; + HRESULT GetOverlayPosition(LPLONG lplX, LPLONG lplY) override; + HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override; + HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override; + HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override; + HRESULT IsLost() override; + HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override; + HRESULT ReleaseDC(HDC hDC) override; + HRESULT Restore() override; + HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override; + HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override; + HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override; + HRESULT Unlock(LPVOID lpSurfaceData) override; + +private: + SDL_Texture* m_texture = nullptr; + IDirectDrawPalette* m_palette = nullptr; +}; diff --git a/miniwin/miniwin/src/include/miniwin_p.h b/miniwin/miniwin/src/include/miniwin_p.h new file mode 100644 index 00000000..c5fcc201 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_p.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#define LOG_CATEGORY_MINIWIN (SDL_LOG_CATEGORY_CUSTOM) + +#define MINIWIN_TRACE(FUNCTION, MSG, ...) \ + do { \ + SDL_LogTrace(LOG_CATEGORY_MINIWIN, FUNCTION); \ + } + +#define MINIWIN_ERROR(MSG) \ + do { \ + SDL_LogError(LOG_CATEGORY_MINIWIN, "%s:%s", __func__, MSG); \ + } while (0) + +static SDL_FRect ConvertRect(const RECT* r) +{ + SDL_FRect sdlRect; + sdlRect.x = r->left; + sdlRect.y = r->top; + sdlRect.w = r->right - r->left; + sdlRect.h = r->bottom - r->top; + return sdlRect; +} diff --git a/miniwin/miniwin/src/miniwin.cpp b/miniwin/miniwin/src/miniwin.cpp index 92da13ce..9e26a590 100644 --- a/miniwin/miniwin/src/miniwin.cpp +++ b/miniwin/miniwin/src/miniwin.cpp @@ -1,7 +1,6 @@ #include "miniwin.h" #include -#include #include ULONG IUnknown::AddRef() @@ -25,6 +24,27 @@ HRESULT IUnknown::QueryInterface(const GUID& riid, void** ppvObject) return E_NOINTERFACE; } +BOOL SetWindowPos(HWND hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + if (!hWnd) { + return FALSE; + } + + if (!(uFlags & SWP_NOACTIVATE)) { + SDL_RaiseWindow(hWnd); + } + + if (!(uFlags & SWP_NOSIZE)) { + SDL_SetWindowSize(hWnd, cx, cy); + } + + if (!(uFlags & SWP_NOMOVE)) { + SDL_SetWindowPosition(hWnd, X, Y); + } + + return TRUE; +} + VOID WINAPI Sleep(DWORD dwMilliseconds) { SDL_Delay(dwMilliseconds); diff --git a/miniwin/miniwin/src/miniwin_d3d.cpp b/miniwin/miniwin/src/miniwin_d3d.cpp deleted file mode 100644 index f91143af..00000000 --- a/miniwin/miniwin/src/miniwin_d3d.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "miniwin_d3d.h" diff --git a/miniwin/miniwin/src/miniwin_d3drm.cpp b/miniwin/miniwin/src/miniwin_d3drm.cpp index 7a7eb589..e613326d 100644 --- a/miniwin/miniwin/src/miniwin_d3drm.cpp +++ b/miniwin/miniwin/src/miniwin_d3drm.cpp @@ -1,9 +1,273 @@ #include "miniwin_d3drm.h" -#include -#include +#include "miniwin_ddsurface_p.h" -struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { +#include +#include +#include +#include + +template +class Direct3DRMArrayBase : public ArrayInterface { +public: + ~Direct3DRMArrayBase() override + { + for (auto* item : items) { + if (item) { + item->Release(); + } + } + } + DWORD GetSize() override { return static_cast(items.size()); } + HRESULT AddElement(InterfaceType* in) override + { + if (!in) { + return DDERR_INVALIDPARAMS; + } + in->AddRef(); + items.push_back(in); + return DD_OK; + } + HRESULT GetElement(DWORD index, InterfaceType** out) override + { + if (index >= items.size()) { + return DDERR_INVALIDPARAMS; + } + *out = static_cast(items[index]); + if (*out) { + (*out)->AddRef(); + } + return DD_OK; + } + HRESULT DeleteElement(InterfaceType* element) override + { + auto it = std::find(items.begin(), items.end(), element); + if (it == items.end()) { + return DDERR_INVALIDPARAMS; + } + + (*it)->Release(); + items.erase(it); + return DD_OK; + } + +protected: + std::vector items; +}; + +struct Direct3DRMFrameArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMLightArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMViewportArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMVisualArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct PickRecord { + IDirect3DRMVisual* visual; + IDirect3DRMFrameArray* frameArray; + D3DRMPICKDESC desc; +}; + +struct Direct3DRMPickedArrayImpl : public IDirect3DRMPickedArray { + ~Direct3DRMPickedArrayImpl() override + { + for (PickRecord& pick : picks) { + if (pick.visual) { + pick.visual->Release(); + } + if (pick.frameArray) { + pick.frameArray->Release(); + } + } + } + DWORD GetSize() override { return static_cast(picks.size()); } + HRESULT GetPick(DWORD index, IDirect3DRMVisual** visual, IDirect3DRMFrameArray** frameArray, D3DRMPICKDESC* desc) + override + { + if (index >= picks.size()) { + return DDERR_INVALIDPARAMS; + } + + const PickRecord& pick = picks[index]; + + *visual = pick.visual; + *frameArray = pick.frameArray; + *desc = pick.desc; + + if (*visual) { + (*visual)->AddRef(); + } + if (*frameArray) { + (*frameArray)->AddRef(); + } + + return DD_OK; + } + +private: + std::vector picks; +}; + +struct Direct3DRMWinDeviceImpl : public IDirect3DRMWinDevice { + HRESULT Activate() override { return DD_OK; } + HRESULT Paint() override { return DD_OK; } + void HandleActivate(WORD wParam) override {} + void HandlePaint(void* p_dc) override {} +}; + +template +struct Direct3DRMObjectBase : public T { + ULONG Release() override + { + if (IUnknown::m_refCount == 1) { + for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { + it->first(this, it->second); + } + } + return this->T::Release(); + } + HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override + { + m_callbacks.push_back(std::make_pair(callback, arg)); + return D3DRM_OK; + } + HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override + { + for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { + if (it->first == callback && it->second == arg) { + m_callbacks.erase(it); + return D3DRM_OK; + } + } + return D3DRMERR_NOTFOUND; + } + HRESULT SetAppData(LPD3DRM_APPDATA appData) override + { + m_appData = appData; + return D3DRM_OK; + } + LPVOID GetAppData() override { return m_appData; } + HRESULT SetName(const char* name) override + { + SDL_free(m_name); + m_name = NULL; + if (name) { + m_name = SDL_strdup(name); + } + return D3DRM_OK; + } + HRESULT GetName(DWORD* size, char* name) override + { + if (!size) { + return DDERR_INVALIDPARAMS; + } + const char* s = m_name ? m_name : ""; + size_t l = SDL_strlen(s); + if (name) { + SDL_strlcpy(name, s, *size); + } + else { + *size = l + 1; + } + return D3DRM_OK; + } + +private: + std::vector> m_callbacks; + LPD3DRM_APPDATA m_appData = NULL; + char* m_name = nullptr; +}; + +struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMMeshImpl); + return DD_OK; + } + HRESULT Clone(int flags, GUID iid, void** object) override + { + if (SDL_memcmp(&iid, &IID_IDirect3DRMMesh, sizeof(GUID)) == 0) { + *object = static_cast(new Direct3DRMMeshImpl); + return S_OK; + } + + return DDERR_GENERIC; + } + HRESULT GetBox(D3DRMBOX* box) override { return DD_OK; } + HRESULT AddGroup(int vertexCount, int faceCount, int vertexPerFace, void* faceBuffer, D3DRMGROUPINDEX* groupIndex) + override + { + return DD_OK; + } + HRESULT GetGroup( + int groupIndex, + unsigned int* vertexCount, + unsigned int* faceCount, + unsigned int* vertexPerFace, + DWORD* dataSize, + unsigned int* data + ) override + { + return DD_OK; + } + HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) override { return DD_OK; } + HRESULT SetGroupColorRGB(int groupIndex, float r, float g, float b) override { return DD_OK; } + HRESULT SetGroupMaterial(int groupIndex, IDirect3DRMMaterial* material) override { return DD_OK; } + HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) override { return DD_OK; } + HRESULT SetGroupQuality(int groupIndex, D3DRMRENDERQUALITY quality) override { return DD_OK; } + HRESULT SetVertices(int groupIndex, int offset, int count, D3DRMVERTEX* vertices) override { return DD_OK; } + HRESULT SetGroupTexture(int groupIndex, IDirect3DRMTexture* texture) override + { + m_groupTexture = texture; + return DD_OK; + } + HRESULT GetGroupTexture(int groupIndex, LPDIRECT3DRMTEXTURE* texture) override + { + if (!m_groupTexture) { + return DDERR_GENERIC; + } + *texture = m_groupTexture; + return DD_OK; + } + D3DRMMAPPING GetGroupMapping(int groupIndex) override { return D3DRMMAP_PERSPCORRECT; } + D3DRMRENDERQUALITY GetGroupQuality(int groupIndex) override { return D3DRMRENDER_GOURAUD; } + HRESULT GetGroupColor(D3DRMGROUPINDEX index) override { return DD_OK; } + HRESULT GetVertices(int groupIndex, int startIndex, int count, D3DRMVERTEX* vertices) override { return DD_OK; } + +private: + IDirect3DRMTexture* m_groupTexture; +}; + +struct Direct3DRMTextureImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMTextureImpl); + return DD_OK; + } + HRESULT Changed(BOOL pixels, BOOL palette) override { return DD_OK; } +}; + +struct Direct3DRMDevice2Impl : public Direct3DRMObjectBase { + Direct3DRMDevice2Impl() + { + m_viewports = new Direct3DRMViewportArrayImpl; + m_viewports->AddRef(); + } + ~Direct3DRMDevice2Impl() override { m_viewports->Release(); } + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMDevice2Impl); + return DD_OK; + } unsigned long GetWidth() override { return 640; } unsigned long GetHeight() override { return 480; } HRESULT SetBufferCount(int count) override { return DD_OK; } @@ -19,83 +283,82 @@ struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; } D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; } HRESULT Update() override { return DD_OK; } + HRESULT AddViewport(IDirect3DRMViewport* viewport) override { return m_viewports->AddElement(viewport); } HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *ppViewportArray = m_viewports; + return DD_OK; } + +private: + IDirect3DRMViewportArray* m_viewports; }; -struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { - HRESULT SetAppData(LPD3DRM_APPDATA appData) override +struct Direct3DRMFrameImpl : public Direct3DRMObjectBase { + Direct3DRMFrameImpl() { - m_data = appData; - return DD_OK; - } - LPVOID GetAppData() override { return m_data; } - HRESULT AddChild(IDirect3DRMFrame* child) override - { - child->AddRef(); - return DD_OK; - } - HRESULT DeleteChild(IDirect3DRMFrame* child) override - { - child->Release(); + m_children = new Direct3DRMFrameArrayImpl; + m_children->AddRef(); + m_lights = new Direct3DRMLightArrayImpl; + m_lights->AddRef(); + m_visuals = new Direct3DRMVisualArrayImpl; + m_visuals->AddRef(); + } + ~Direct3DRMFrameImpl() override + { + m_children->Release(); + m_lights->Release(); + m_visuals->Release(); + if (m_texture) { + m_texture->Release(); + } + } + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMFrameImpl); return DD_OK; } + HRESULT AddChild(IDirect3DRMFrame* child) override { return m_children->AddElement(child); } + HRESULT DeleteChild(IDirect3DRMFrame* child) override { return m_children->DeleteElement(child); } HRESULT SetSceneBackgroundRGB(float r, float g, float b) override { return DD_OK; } - HRESULT AddLight(IDirect3DRMLight* light) override - { - light->AddRef(); - return DD_OK; - } + HRESULT AddLight(IDirect3DRMLight* light) override { return m_lights->AddElement(light); } HRESULT GetLights(IDirect3DRMLightArray** lightArray) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *lightArray = m_lights; + m_lights->AddRef(); + return DD_OK; } HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; } HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; } - HRESULT AddVisual(IDirect3DRMVisual* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMVisual* visual) override - { - visual->Release(); - return DD_OK; - } - HRESULT AddVisual(IDirect3DRMMesh* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMMesh* visual) override - { - visual->Release(); - return DD_OK; - } - HRESULT AddVisual(IDirect3DRMFrame* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMFrame* visual) override - { - visual->Release(); - return DD_OK; - } + HRESULT AddVisual(IDirect3DRMVisual* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMVisual* visual) override { return m_visuals->DeleteElement(visual); } + HRESULT AddVisual(IDirect3DRMMesh* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMMesh* visual) override { return m_visuals->DeleteElement(visual); } + HRESULT AddVisual(IDirect3DRMFrame* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMFrame* visual) override { return m_visuals->DeleteElement(visual); } HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *visuals = m_visuals; + m_visuals->AddRef(); + return DD_OK; + } + HRESULT SetTexture(IDirect3DRMTexture* texture) override + { + if (m_texture) { + m_texture->Release(); + } + m_texture = texture; + m_texture->AddRef(); + return DD_OK; } - HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; } HRESULT GetTexture(IDirect3DRMTexture** texture) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + if (!m_texture) { + return DDERR_GENERIC; + } + *texture = m_texture; + m_texture->AddRef(); + return DD_OK; } HRESULT SetColor(float r, float g, float b, float a) override { return DD_OK; } HRESULT SetColor(D3DCOLOR) override { return DD_OK; } @@ -103,40 +366,36 @@ struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { HRESULT SetMaterialMode(D3DRMMATERIALMODE mode) override { return DD_OK; } HRESULT GetChildren(IDirect3DRMFrameArray** children) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *children = m_children; + m_children->AddRef(); + return DD_OK; } private: - LPD3DRM_APPDATA m_data; + IDirect3DRMFrameArray* m_children; + IDirect3DRMLightArray* m_lights; + IDirect3DRMVisualArray* m_visuals; + IDirect3DRMTexture* m_texture; }; -struct Direct3DRMViewportImpl : public IDirect3DRMViewport { - Direct3DRMViewportImpl() : m_data(nullptr) {} +struct Direct3DRMViewportImpl : public Direct3DRMObjectBase { HRESULT Clone(void** ppObject) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; - } - HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } - HRESULT DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } - HRESULT SetAppData(LPD3DRM_APPDATA appData) override - { - m_data = appData; + *ppObject = static_cast(new Direct3DRMViewportImpl); return DD_OK; } - LPVOID GetAppData() override { return m_data; } - HRESULT SetName(const char* name) override { return DD_OK; } - HRESULT GetName(DWORD* size, char* name) override { return DD_OK; } - HRESULT GetClassName(DWORD* size, char* name) override { return DD_OK; } HRESULT Render(IDirect3DRMFrame* group) override { return DD_OK; } HRESULT ForceUpdate(int x, int y, int w, int h) override { return DD_OK; } HRESULT Clear() override { return DD_OK; } - HRESULT SetCamera(IDirect3DRMFrame* camera) override { return DD_OK; } + HRESULT SetCamera(IDirect3DRMFrame* camera) override + { + m_camera = camera; + return DD_OK; + } HRESULT GetCamera(IDirect3DRMFrame** camera) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *camera = m_camera; + return DD_OK; } HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; } D3DRMPROJECTIONTYPE GetProjection() override { return D3DRMPROJECTIONTYPE::PERSPECTIVE; } @@ -153,14 +412,27 @@ struct Direct3DRMViewportImpl : public IDirect3DRMViewport { HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) override { return DD_OK; } private: - LPD3DRM_APPDATA m_data; + IDirect3DRMFrame* m_camera; }; -struct Direct3DRMLightImpl : public IDirect3DRMLight { +struct Direct3DRMLightImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMLightImpl); + return DD_OK; + } HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; } }; -struct Direct3DRMImpl : public IDirect3DRM2 { +struct Direct3DRMMaterialImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMMaterialImpl); + return DD_OK; + } +}; + +struct Direct3DRMImpl : virtual public IDirect3DRM2 { // IUnknown interface HRESULT QueryInterface(const GUID& riid, void** ppvObject) override { @@ -186,27 +458,27 @@ struct Direct3DRMImpl : public IDirect3DRM2 { IDirect3DRMDevice2** outDevice ) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *outDevice = static_cast(new Direct3DRMDevice2Impl); + return S_OK; } HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *outTexture = static_cast(new Direct3DRMTextureImpl); + return S_OK; } HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *outTexture = static_cast(new Direct3DRMTextureImpl); + return S_OK; } HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override { - assert(false && "unimplemented"); + *outMesh = static_cast(new Direct3DRMMeshImpl); return DDERR_GENERIC; } HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override { - *outMaterial = new IDirect3DRMMaterial; + *outMaterial = static_cast(new Direct3DRMMaterialImpl); return DD_OK; } HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override @@ -230,6 +502,7 @@ struct Direct3DRMImpl : public IDirect3DRM2 { ) override { *outViewport = static_cast(new Direct3DRMViewportImpl); + device->AddViewport(*outViewport); return DD_OK; } HRESULT SetDefaultTextureShades(unsigned int count) override { return DD_OK; } diff --git a/miniwin/miniwin/src/miniwin_ddclipper.cpp b/miniwin/miniwin/src/miniwin_ddclipper.cpp new file mode 100644 index 00000000..79dfa882 --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddclipper.cpp @@ -0,0 +1,15 @@ +#include "miniwin_ddclipper_p.h" +#include "miniwin_ddraw_p.h" + +DirectDrawClipperImpl::DirectDrawClipperImpl(DirectDrawImpl* lpDD) +{ +} + +DirectDrawClipperImpl::~DirectDrawClipperImpl() +{ +} + +HRESULT DirectDrawClipperImpl::SetHWnd(DWORD unnamedParam1, HWND hWnd) +{ + return DD_OK; +} diff --git a/miniwin/miniwin/src/miniwin_ddpalette.cpp b/miniwin/miniwin/src/miniwin_ddpalette.cpp new file mode 100644 index 00000000..0615f06c --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddpalette.cpp @@ -0,0 +1,21 @@ +#include "miniwin_ddpalette_p.h" +#include "miniwin_ddraw.h" + +DirectDrawPaletteImpl::DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable) +{ +} + +HRESULT DirectDrawPaletteImpl::GetCaps(LPDWORD lpdwCaps) +{ + return DD_OK; +} + +HRESULT DirectDrawPaletteImpl::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) +{ + return DD_OK; +} + +HRESULT DirectDrawPaletteImpl::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) +{ + return DD_OK; +} diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index 85036003..c6026930 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -1,6 +1,10 @@ -#include "miniwin_ddraw.h" #include "miniwin_d3d.h" +#include "miniwin_ddclipper_p.h" +#include "miniwin_ddpalette_p.h" +#include "miniwin_ddraw_p.h" +#include "miniwin_ddsurface_p.h" +#include "miniwin_p.h" #include #include @@ -10,360 +14,96 @@ SDL_Renderer* renderer; -static SDL_FRect ConvertRect(const RECT* r) +HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) { - SDL_FRect sdlRect; - sdlRect.x = r->left; - sdlRect.y = r->top; - sdlRect.w = r->right - r->left; - sdlRect.h = r->bottom - r->top; - return sdlRect; + if (SDL_memcmp(&riid, &IID_IDirectDraw2, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + SDL_LogError(LOG_CATEGORY_MINIWIN, "DirectDrawImpl does not implement guid"); + return E_NOINTERFACE; } -struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { - DirectDrawSurfaceImpl() {} - DirectDrawSurfaceImpl(int width, int height) - { - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); - } - } +// IDirectDraw interface +HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) +{ + *lplpDDClipper = static_cast(new DirectDrawClipperImpl(this)); - ~DirectDrawSurfaceImpl() override - { - if (texture) { - SDL_DestroyTexture(texture); - } - } - // IUnknown interface - HRESULT QueryInterface(const GUID& riid, void** ppvObject) override - { - if (SDL_memcmp(&riid, &IID_IDirectDrawSurface3, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); - return E_NOINTERFACE; - } - // IDirectDrawSurface interface - HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override { return DD_OK; } - HRESULT Blt( - LPRECT lpDestRect, - LPDIRECTDRAWSURFACE lpDDSrcSurface, - LPRECT lpSrcRect, - DDBltFlags dwFlags, - LPDDBLTFX lpDDBltFx - ) override - { - if (!renderer) { - return DDERR_GENERIC; - } - SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_FRect dstRect = ConvertRect(lpDestRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans) - override - { - if (!renderer) { - return DDERR_GENERIC; - } - SDL_FRect dstRect = { - (float) dwX, - (float) dwY, - (float) (lpSrcRect->right - lpSrcRect->left), - (float) (lpSrcRect->bottom - lpSrcRect->top) - }; - SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override - { - if (!renderer || !texture) { - return DDERR_GENERIC; - } - float width, height; - SDL_GetTextureSize(texture, &width, &height); - SDL_FRect rect{0, 0, width, height}; - SDL_RenderTexture(renderer, texture, &rect, &rect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override - { - if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) { - return DDERR_INVALIDPARAMS; - } - *lplpDDAttachedSurface = static_cast(this); - return DD_OK; - } - HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override { return DD_OK; } - HRESULT GetDC(HDC* lphDC) override { return DD_OK; } - HRESULT GetOverlayPosition(LPLONG lplX, LPLONG lplY) override { return DD_OK; } - HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override { return DDERR_GENERIC; } - HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override - { - memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); - lpDDPixelFormat->dwFlags = DDPF_RGB; - return DD_OK; - } - HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override - { - if (!texture) { - return DDERR_GENERIC; - } - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - return DD_OK; - } - HRESULT IsLost() override { return DD_OK; } - HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override - { - if (!lpDDSurfaceDesc) { - return DDERR_INVALIDPARAMS; - } - if (!texture) { - return DDERR_GENERIC; - } + return DD_OK; +} - int pitch = 0; - void* pixels = nullptr; - if (SDL_LockTexture(texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { - return DDERR_GENERIC; - } +HRESULT DirectDrawImpl::CreatePalette( + DDPixelCaps dwFlags, + LPPALETTEENTRY lpColorTable, + LPDIRECTDRAWPALETTE* lplpDDPalette, + IUnknown* pUnkOuter +) +{ + *lplpDDPalette = static_cast(new DirectDrawPaletteImpl(lpColorTable)); + return DD_OK; +} - lpDDSurfaceDesc->lpSurface = pixels; - lpDDSurfaceDesc->lPitch = pitch; - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - - return DD_OK; - } - HRESULT ReleaseDC(HDC hDC) override { return DD_OK; } - HRESULT Restore() override { return DD_OK; } - HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override { return DD_OK; } - HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override { return DD_OK; } - HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override { return DD_OK; } - HRESULT Unlock(LPVOID lpSurfaceData) override - { - if (texture) { - SDL_UnlockTexture(texture); +HRESULT DirectDrawImpl::CreateSurface( + LPDDSURFACEDESC lpDDSurfaceDesc, + LPDIRECTDRAWSURFACE* lplpDDSurface, + IUnknown* pUnkOuter +) +{ + if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) { + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) { + if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) { + return DDERR_INVALIDPARAMS; + } + SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth); + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl); return DD_OK; } - return DDERR_GENERIC; - } - -private: - SDL_Texture* texture = nullptr; -}; - -struct DirectDrawClipperImpl : public IDirectDrawClipper { - // IDirectDrawClipper interface - HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override { return DD_OK; } -}; - -struct DirectDrawPaletteImpl : public IDirectDrawPalette { - HRESULT GetCaps(LPDWORD lpdwCaps) override { return DD_OK; } - HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) override - { - return DD_OK; - } - HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) override - { - return DD_OK; - } -}; - -struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { - // IUnknown interface - HRESULT QueryInterface(const GUID& riid, void** ppvObject) override - { - if (SDL_memcmp(&riid, &IID_IDirectDraw2, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); - return E_NOINTERFACE; - } - // IDirecdtDraw interface - HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) override - { - *lplpDDClipper = static_cast(new DirectDrawClipperImpl); - - return DD_OK; - } - HRESULT CreatePalette( - DDPixelCaps dwFlags, - LPPALETTEENTRY lpColorTable, - LPDIRECTDRAWPALETTE* lplpDDPalette, - IUnknown* pUnkOuter - ) override - { - *lplpDDPalette = static_cast(new DirectDrawPaletteImpl); - return DD_OK; - } - HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) - override - { - if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) { - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) { - if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) { - return DDERR_INVALIDPARAMS; - } - SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth); - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl); - return DD_OK; - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { - if ((lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) == DDSD_BACKBUFFERCOUNT) { - SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount); - } - int width, height; - SDL_GetRenderOutputSize(renderer, &width, &height); - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); - return DD_OK; - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) { - SDL_Log("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces? - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) { - SDL_Log("DDSCAPS_SYSTEMMEMORY"); // Software rendering? - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) { - SDL_Log("DDSCAPS_TEXTURE"); // Texture for use in 3D - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) { - SDL_Log("DDSCAPS_3DDEVICE"); // back buffer - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) { - SDL_Log("DDSCAPS_VIDEOMEMORY"); // front / back buffer + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { + if ((lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) == DDSD_BACKBUFFERCOUNT) { + SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount); } + int width, height; + SDL_GetRenderOutputSize(renderer, &width, &height); + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + return DD_OK; } - - if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { - if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { - SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format - } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) { + SDL_Log("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces? } - - if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { - return DDERR_INVALIDPARAMS; + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) { + SDL_Log("DDSCAPS_SYSTEMMEMORY"); // Software rendering? + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) { + SDL_Log("DDSCAPS_TEXTURE"); // Texture for use in 3D + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) { + SDL_Log("DDSCAPS_3DDEVICE"); // back buffer + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) { + SDL_Log("DDSCAPS_VIDEOMEMORY"); // front / back buffer } - - int width = lpDDSurfaceDesc->dwWidth; - int height = lpDDSurfaceDesc->dwHeight; - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); - return DD_OK; } - HRESULT EnumDisplayModes( - DWORD dwFlags, - LPDDSURFACEDESC lpDDSurfaceDesc, - LPVOID lpContext, - LPDDENUMMODESCALLBACK lpEnumModesCallback - ) override; - HRESULT FlipToGDISurface() override { return DD_OK; } - HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override; - HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override - { - SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); - if (!displayID) { - return DDERR_GENERIC; + + if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { + if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { + SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format } - - const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID); - if (!mode) { - return DDERR_GENERIC; - } - - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(mode->format); - - lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; - lpDDSurfaceDesc->dwWidth = mode->w; - lpDDSurfaceDesc->dwHeight = mode->h; - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - - return DD_OK; } - HRESULT RestoreDisplayMode() override { return DD_OK; } - HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) override - { - if (hWnd) { - renderer = SDL_CreateRenderer(hWnd, NULL); - } - return DD_OK; - } - HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override { return DD_OK; } - // IDirect3D2 interface - HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override - { - *ppDirect3DDevice = new IDirect3DDevice2; - return DD_OK; - } - HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override; -}; -HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) -{ - if (!cb) { + if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { return DDERR_INVALIDPARAMS; } - int numDrivers = SDL_GetNumRenderDrivers(); - if (numDrivers <= 0) { - return DDERR_GENERIC; - } - - const char* deviceDesc = "SDL3-backed renderer"; - char* deviceDescDup = SDL_strdup(deviceDesc); - - for (int i = 0; i < numDrivers; ++i) { - const char* deviceName = SDL_GetRenderDriver(i); - if (!deviceName) { - return DDERR_GENERIC; - } - - GUID deviceGuid = {0x682656F3, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (uint8_t) i}}; - - D3DDEVICEDESC halDesc = {}; - halDesc.dcmColorModel = D3DCOLORMODEL::RGB; - halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; - halDesc.dwDeviceZBufferBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32; - halDesc.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16; - halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; - halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; - halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; - - char* deviceNameDup = SDL_strdup(deviceName); - cb(&deviceGuid, deviceNameDup, deviceDescDup, &halDesc, &halDesc, ctx); - SDL_free(deviceNameDup); - } - SDL_free(deviceDescDup); - - return S_OK; + int width = lpDDSurfaceDesc->dwWidth; + int height = lpDDSurfaceDesc->dwHeight; + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + return DD_OK; } HRESULT DirectDrawImpl::EnumDisplayModes( @@ -373,10 +113,6 @@ HRESULT DirectDrawImpl::EnumDisplayModes( LPDDENUMMODESCALLBACK lpEnumModesCallback ) { - if (!lpEnumModesCallback) { - return DDERR_INVALIDPARAMS; - } - SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); if (!displayID) { return DDERR_GENERIC; @@ -417,27 +153,132 @@ HRESULT DirectDrawImpl::EnumDisplayModes( return status; } +HRESULT DirectDrawImpl::FlipToGDISurface() +{ + return DD_OK; +} + HRESULT DirectDrawImpl::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) { if (lpDDDriverCaps) { - memset(lpDDDriverCaps, 0, sizeof(DDCAPS)); - lpDDDriverCaps->dwSize = sizeof(DDCAPS); - lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) { + lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + } } if (lpDDHELCaps) { - memset(lpDDHELCaps, 0, sizeof(DDCAPS)); - lpDDHELCaps->dwSize = sizeof(DDCAPS); - lpDDHELCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) { + lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + } } return S_OK; } +HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +{ + int numDrivers = SDL_GetNumRenderDrivers(); + if (numDrivers <= 0) { + return DDERR_GENERIC; + } + + const char* deviceDesc = "SDL3 SDL_Renderer"; + + for (int i = 0; i < numDrivers; ++i) { + const char* deviceName = SDL_GetRenderDriver(i); + if (!deviceName) { + return DDERR_GENERIC; + } + + GUID deviceGuid = {0x682656F3, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (uint8_t) i}}; + + D3DDEVICEDESC halDesc = {}; + halDesc.dcmColorModel = D3DCOLORMODEL::RGB; + halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; + halDesc.dwDeviceZBufferBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32; + halDesc.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16; + halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; + halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; + halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; + + char* deviceNameDup = SDL_strdup(deviceName); + char* deviceDescDup = SDL_strdup(deviceDesc); + cb(&deviceGuid, deviceNameDup, deviceDescDup, &halDesc, &halDesc, ctx); + SDL_free(deviceDescDup); + SDL_free(deviceNameDup); + } + + return S_OK; +} + +HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); + if (!displayID) { + return DDERR_GENERIC; + } + + const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID); + if (!mode) { + return DDERR_GENERIC; + } + + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(mode->format); + + lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + lpDDSurfaceDesc->dwWidth = mode->w; + lpDDSurfaceDesc->dwHeight = mode->h; + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + + return DD_OK; +} + +HRESULT DirectDrawImpl::RestoreDisplayMode() +{ + return DD_OK; +} + +HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) +{ + if (hWnd) { + bool fullscreen; + if ((dwFlags & DDSCL_NORMAL) == DDSCL_NORMAL) { + fullscreen = false; + } + else if ((dwFlags & DDSCL_FULLSCREEN) == DDSCL_FULLSCREEN) { + fullscreen = true; + } + else { + return DDERR_INVALIDPARAMS; + } + + if (!SDL_SetWindowFullscreen(hWnd, fullscreen)) { + return DDERR_GENERIC; + } + renderer = SDL_CreateRenderer(hWnd, NULL); + } + return DD_OK; +} + +HRESULT DirectDrawImpl::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) +{ + return DD_OK; +} +// IDirect3D2 interface +HRESULT DirectDrawImpl::CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) +{ + *ppDirect3DDevice = new IDirect3DDevice2; + return DD_OK; +} + HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter) { - if (!lplpDD) { - return DDERR_INVALIDPARAMS; + if (lpGuid) { + MINIWIN_ERROR("Specifying a DirectDraw driver is not implemented"); } *lplpDD = new DirectDrawImpl; @@ -451,8 +292,10 @@ HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context) for (int i = 0; i < numDrivers; ++i) { const char* driverName = SDL_GetVideoDriver(i); - - if (!cb(NULL, (LPSTR) driverName, NULL, context)) { + char* driverNameDup = SDL_strdup(driverName); + BOOL callback_result = cb(NULL, driverNameDup, NULL, context); + SDL_free(driverNameDup); + if (!callback_result) { return DDERR_GENERIC; } } diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp new file mode 100644 index 00000000..0ed41e9e --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -0,0 +1,217 @@ +#include "miniwin_ddraw_p.h" +#include "miniwin_ddsurface_p.h" +#include "miniwin_p.h" + +#include + +DirectDrawSurfaceImpl::DirectDrawSurfaceImpl() +{ +} + +DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height) +{ + m_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!m_texture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); + } +} + +DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl() +{ + if (m_texture) { + SDL_DestroyTexture(m_texture); + } +} + +// IUnknown interface +HRESULT DirectDrawSurfaceImpl::QueryInterface(const GUID& riid, void** ppvObject) +{ + if (SDL_memcmp(&riid, &IID_IDirectDrawSurface3, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); + return E_NOINTERFACE; +} + +// IDirectDrawSurface interface +HRESULT DirectDrawSurfaceImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) +{ + return DD_OK; +} +HRESULT DirectDrawSurfaceImpl::Blt( + LPRECT lpDestRect, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFlags dwFlags, + LPDDBLTFX lpDDBltFx +) +{ + if (!renderer) { + return DDERR_GENERIC; + } + SDL_FRect srcRect = ConvertRect(lpSrcRect); + SDL_FRect dstRect = ConvertRect(lpDestRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->m_texture, &srcRect, &dstRect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::BltFast( + DWORD dwX, + DWORD dwY, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFastFlags dwTrans +) +{ + if (!renderer) { + return DDERR_GENERIC; + } + SDL_FRect dstRect = { + (float) dwX, + (float) dwY, + (float) (lpSrcRect->right - lpSrcRect->left), + (float) (lpSrcRect->bottom - lpSrcRect->top) + }; + SDL_FRect srcRect = ConvertRect(lpSrcRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->m_texture, &srcRect, &dstRect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) +{ + if (!renderer || !m_texture) { + return DDERR_GENERIC; + } + float width, height; + SDL_GetTextureSize(m_texture, &width, &height); + SDL_FRect rect{0, 0, width, height}; + SDL_RenderTexture(renderer, m_texture, &rect, &rect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) +{ + if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) { + return DDERR_INVALIDPARAMS; + } + *lplpDDAttachedSurface = static_cast(this); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetCaps(LPDDSCAPS lpDDSCaps) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetDC(HDC* lphDC) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetOverlayPosition(LPLONG lplX, LPLONG lplY) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) +{ + if (!m_palette) { + return DDERR_GENERIC; + } + m_palette->AddRef(); + *lplpDDPalette = m_palette; + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) +{ + memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); + lpDDPixelFormat->dwFlags = DDPF_RGB; + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + if (!m_texture) { + return DDERR_GENERIC; + } + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(m_texture->format); + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::IsLost() +{ + return DD_OK; +} +HRESULT DirectDrawSurfaceImpl::Lock( + LPRECT lpDestRect, + LPDDSURFACEDESC lpDDSurfaceDesc, + DDLockFlags dwFlags, + HANDLE hEvent +) +{ + if (!m_texture) { + return DDERR_GENERIC; + } + + int pitch = 0; + void* pixels = nullptr; + if (SDL_LockTexture(m_texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { + return DDERR_GENERIC; + } + + lpDDSurfaceDesc->lpSurface = pixels; + lpDDSurfaceDesc->lPitch = pitch; + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(m_texture->format); + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::ReleaseDC(HDC hDC) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Restore() +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Unlock(LPVOID lpSurfaceData) +{ + if (!m_texture) { + return DDERR_GENERIC; + } + SDL_UnlockTexture(m_texture); + return DD_OK; +}