Merge branch 'master' into filesystem-map

This commit is contained in:
Christian Semmler 2025-05-16 18:17:21 -07:00
commit aed95aed19
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
27 changed files with 1243 additions and 800 deletions

137
.github/workflows/ci.yml vendored Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR) 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") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
@ -69,7 +69,7 @@ endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (ENABLE_CLANG_TIDY) 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_C_CLANG_TIDY "${CLANG_TIDY_BIN}")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}") set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}")
endif() endif()
@ -87,11 +87,14 @@ endif()
#if (NOT WIN32) #if (NOT WIN32)
add_library(miniwin STATIC EXCLUDE_FROM_ALL add_library(miniwin STATIC EXCLUDE_FROM_ALL
miniwin/miniwin/src/miniwin.cpp 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_ddraw.cpp
miniwin/miniwin/src/miniwin_d3d.cpp
miniwin/miniwin/src/miniwin_d3drm.cpp miniwin/miniwin/src/miniwin_d3drm.cpp
) )
target_include_directories(miniwin PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/include>") target_include_directories(miniwin PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/include>")
target_include_directories(miniwin PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/src/include")
target_compile_definitions(miniwin PUBLIC "MINIWIN") target_compile_definitions(miniwin PUBLIC "MINIWIN")
target_link_libraries(miniwin PRIVATE SDL3::SDL3) target_link_libraries(miniwin PRIVATE SDL3::SDL3)
@ -570,3 +573,33 @@ if (EXISTS "${CLANGFORMAT_BIN}")
endif() endif()
endif() 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)

View File

@ -30,6 +30,8 @@
#include "roi/legoroi.h" #include "roi/legoroi.h"
#include "viewmanager/viewmanager.h" #include "viewmanager/viewmanager.h"
#include <SDL3/SDL_init.h>
#define SDL_MAIN_USE_CALLBACKS #define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_main.h> #include <SDL3/SDL_main.h>
@ -289,7 +291,16 @@ SDL_AppResult SDL_AppIterate(void* appstate)
return SDL_APP_SUCCESS; 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_closed) {
if (g_reqEnableRMDevice) { if (g_reqEnableRMDevice) {
@ -304,7 +315,16 @@ SDL_AppResult SDL_AppIterate(void* appstate)
} }
if (g_mousedown && g_mousemoved && g_isle) { 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) { if (g_mousemoved) {
@ -683,7 +703,7 @@ bool IsleApp::LoadConfig()
} }
// FUNCTION: ISLE 0x402c20 // FUNCTION: ISLE 0x402c20
inline void IsleApp::Tick() inline bool IsleApp::Tick()
{ {
// GLOBAL: ISLE 0x4101c0 // GLOBAL: ISLE 0x4101c0
static MxLong g_lastFrameTime = 0; static MxLong g_lastFrameTime = 0;
@ -693,17 +713,17 @@ inline void IsleApp::Tick()
if (!m_windowActive) { if (!m_windowActive) {
SDL_Delay(1); SDL_Delay(1);
return; return true;
} }
if (!Lego()) { if (!Lego()) {
return; return true;
} }
if (!TickleManager()) { if (!TickleManager()) {
return; return true;
} }
if (!Timer()) { if (!Timer()) {
return; return true;
} }
MxLong currentTime = Timer()->GetRealTime(); MxLong currentTime = Timer()->GetRealTime();
@ -713,7 +733,7 @@ inline void IsleApp::Tick()
if (m_frameDelta + g_lastFrameTime >= currentTime) { if (m_frameDelta + g_lastFrameTime >= currentTime) {
SDL_Delay(1); SDL_Delay(1);
return; return true;
} }
if (!Lego()->IsPaused()) { if (!Lego()->IsPaused()) {
@ -722,12 +742,12 @@ inline void IsleApp::Tick()
g_lastFrameTime = currentTime; g_lastFrameTime = currentTime;
if (g_startupDelay == 0) { if (g_startupDelay == 0) {
return; return true;
} }
g_startupDelay--; g_startupDelay--;
if (g_startupDelay != 0) { if (g_startupDelay != 0) {
return; return true;
} }
LegoOmni::GetInstance()->CreateBackgroundAudio(); LegoOmni::GetInstance()->CreateBackgroundAudio();
@ -739,7 +759,8 @@ inline void IsleApp::Tick()
if (!stream) { if (!stream) {
stream = Streamer()->Open("\\lego\\scripts\\nocd", MxStreamer::e_diskStream); stream = Streamer()->Open("\\lego\\scripts\\nocd", MxStreamer::e_diskStream);
if (!stream) { if (!stream) {
return; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Streamer failed to load");
return false;
} }
ds.SetAtomId(stream->GetAtom()); ds.SetAtomId(stream->GetAtom());
@ -748,7 +769,8 @@ inline void IsleApp::Tick()
VideoManager()->EnableFullScreenMovie(TRUE, TRUE); VideoManager()->EnableFullScreenMovie(TRUE, TRUE);
if (Start(&ds) != SUCCESS) { if (Start(&ds) != SUCCESS) {
return; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Failed to start initial action");
return false;
} }
} }
else { else {
@ -756,10 +778,13 @@ inline void IsleApp::Tick()
ds.SetUnknown24(-1); ds.SetUnknown24(-1);
ds.SetObjectId(0); ds.SetObjectId(0);
if (Start(&ds) != SUCCESS) { 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; m_gameStarted = TRUE;
} }
return true;
} }
// FUNCTION: ISLE 0x402e80 // FUNCTION: ISLE 0x402e80

View File

@ -37,7 +37,7 @@ class IsleApp {
MxResult SetupWindow(); MxResult SetupWindow();
bool LoadConfig(); bool LoadConfig();
void Tick(); bool Tick();
void SetupCursor(Cursor p_cursor); void SetupCursor(Cursor p_cursor);
static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags); static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags);

View File

@ -42,7 +42,7 @@ MxDriver::MxDriver(LPGUID p_guid)
// FUNCTION: CONFIG 0x00401180 // FUNCTION: CONFIG 0x00401180
// FUNCTION: LEGO1 0x1009ba80 // FUNCTION: LEGO1 0x1009ba80
// FUNCTION: BETA10 0x1011d8b6 // 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_guid = NULL;
m_driverDesc = NULL; m_driverDesc = NULL;
@ -71,7 +71,7 @@ MxDriver::~MxDriver()
// FUNCTION: CONFIG 0x00401330 // FUNCTION: CONFIG 0x00401330
// FUNCTION: LEGO1 0x1009bc30 // FUNCTION: LEGO1 0x1009bc30
// FUNCTION: BETA10 0x1011da89 // 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) { if (m_driverDesc) {
delete[] m_driverDesc; delete[] m_driverDesc;
@ -104,8 +104,8 @@ void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName)
// FUNCTION: BETA10 0x1011dbd0 // FUNCTION: BETA10 0x1011dbd0
Direct3DDeviceInfo::Direct3DDeviceInfo( Direct3DDeviceInfo::Direct3DDeviceInfo(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
) )
@ -136,8 +136,8 @@ Direct3DDeviceInfo::~Direct3DDeviceInfo()
// FUNCTION: BETA10 0x1011dca6 // FUNCTION: BETA10 0x1011dca6
void Direct3DDeviceInfo::Initialize( void Direct3DDeviceInfo::Initialize(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
) )
@ -318,8 +318,8 @@ HRESULT MxDeviceEnumerate::EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd)
// FUNCTION: BETA10 0x1011e32f // FUNCTION: BETA10 0x1011e32f
HRESULT MxDeviceEnumerate::EnumDevicesCallback( HRESULT MxDeviceEnumerate::EnumDevicesCallback(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
) )

View File

@ -71,16 +71,16 @@ struct Direct3DDeviceInfo {
~Direct3DDeviceInfo(); ~Direct3DDeviceInfo();
Direct3DDeviceInfo( Direct3DDeviceInfo(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
); );
void Initialize( void Initialize(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
); );
@ -119,9 +119,9 @@ struct MxDriver {
MxDriver() {} MxDriver() {}
~MxDriver(); ~MxDriver();
MxDriver(LPGUID p_guid); 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 LPGUID m_guid; // 0x00
char* m_driverDesc; // 0x04 char* m_driverDesc; // 0x04
@ -202,8 +202,8 @@ class MxDeviceEnumerate {
HRESULT EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd); HRESULT EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd);
HRESULT EnumDevicesCallback( HRESULT EnumDevicesCallback(
LPGUID p_guid, LPGUID p_guid,
LPSTR p_deviceDesc, LPCSTR p_deviceDesc,
LPSTR p_deviceName, LPCSTR p_deviceName,
LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HWDesc,
LPD3DDEVICEDESC p_HELDesc LPD3DDEVICEDESC p_HELDesc
); );

View File

@ -204,7 +204,7 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers(); ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers();
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 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)) { if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDraw::CreateSurface failed"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDraw::CreateSurface failed");

View File

@ -24,8 +24,6 @@
#define FAILED(hr) (((HRESULT) (hr)) < 0) #define FAILED(hr) (((HRESULT) (hr)) < 0)
#define InterlockedIncrement(x) __sync_add_and_fetch(x, 1) #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 HKEY_LOCAL_MACHINE ((HKEY) 0x80000002)
#define LOWORD(l) ((WORD) (((DWORD_PTR) (l)) & 0xffff)) #define LOWORD(l) ((WORD) (((DWORD_PTR) (l)) & 0xffff))
#define MAKEINTRESOURCE(i) (reinterpret_cast<LPCTSTR>((ULONG_PTR) ((WORD) (i)))) #define MAKEINTRESOURCE(i) (reinterpret_cast<LPCTSTR>((ULONG_PTR) ((WORD) (i))))
@ -130,7 +128,7 @@ struct CMenu {
struct CWinApp { struct CWinApp {
CWinApp(); CWinApp();
virtual ~CWinApp() = default; ~CWinApp() = default;
virtual BOOL InitInstance() = 0; virtual BOOL InitInstance() = 0;
virtual int ExitInstance(); virtual int ExitInstance();
}; };

View File

@ -16,7 +16,7 @@
#define CALLBACK #define CALLBACK
#define FAR #define FAR
#define WINAPI #define WINAPI
#define HWND_NOTOPMOST (HWND) - 2 #define HWND_NOTOPMOST -2
#define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
#define S_OK ((HRESULT) 0) #define S_OK ((HRESULT) 0)
#define E_NOINTERFACE (0x80004002) #define E_NOINTERFACE (0x80004002)
@ -143,14 +143,11 @@ struct IUnknown {
virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject); virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject);
virtual ~IUnknown() = default; virtual ~IUnknown() = default;
private: protected:
int m_refCount; int m_refCount;
}; };
inline BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) BOOL SetWindowPos(HWND hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
{
return TRUE;
}
inline HDC WINAPI GetDC(HWND hWnd) inline HDC WINAPI GetDC(HWND hWnd)
{ {

View File

@ -8,6 +8,7 @@
#define D3DRM_OK DD_OK #define D3DRM_OK DD_OK
#define MAXSHORT ((short) 0x7fff) #define MAXSHORT ((short) 0x7fff)
#define SUCCEEDED(hr) ((hr) >= D3DRM_OK) #define SUCCEEDED(hr) ((hr) >= D3DRM_OK)
#define D3DRMERR_NOTFOUND MAKE_DDHRESULT(785)
// --- Typedefs --- // --- Typedefs ---
typedef float D3DVAL; typedef float D3DVAL;
@ -16,6 +17,9 @@ typedef unsigned long D3DRMGROUPINDEX;
typedef DWORD D3DCOLOR, *LPD3DCOLOR; typedef DWORD D3DCOLOR, *LPD3DCOLOR;
typedef float D3DVALUE, *LPD3DVALUE; typedef float D3DVALUE, *LPD3DVALUE;
typedef struct IDirect3DRMObject* LPDIRECT3DRMOBJECT;
typedef void (*D3DRMOBJECTCALLBACK)(LPDIRECT3DRMOBJECT obj, LPVOID arg);
// --- Enums --- // --- Enums ---
#define D3DRMCOMBINE_REPLACE D3DRMCOMBINETYPE::REPLACE #define D3DRMCOMBINE_REPLACE D3DRMCOMBINETYPE::REPLACE
enum class D3DRMCOMBINETYPE { enum class D3DRMCOMBINETYPE {
@ -140,35 +144,31 @@ struct D3DRMVERTEX {
float tu, tv; float tu, tv;
}; };
struct IDirect3DRMVisual : virtual public IUnknown {}; struct IDirect3DRMObject : public IUnknown {
typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL;
struct IDirect3DRMObject : virtual public IUnknown {
virtual HRESULT Clone(void** ppObject) = 0; virtual HRESULT Clone(void** ppObject) = 0;
virtual HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; virtual HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0;
virtual HRESULT DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; virtual HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0;
virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0;
virtual LPVOID GetAppData() = 0; virtual LPVOID GetAppData() = 0;
virtual HRESULT SetName(const char* name) = 0; virtual HRESULT SetName(const char* name) = 0;
virtual HRESULT GetName(DWORD* size, 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; struct IDirect3DRMVisual : public IDirect3DRMObject {};
virtual LPVOID GetAppData() = 0; typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL;
virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0;
virtual HRESULT SetTexture(const IDirect3DRMTexture* texture) = 0; struct IDirect3DRMTexture : public IDirect3DRMVisual {
virtual HRESULT Changed(BOOL arg1, BOOL arg2) = 0; virtual HRESULT Changed(BOOL pixels, BOOL palette) = 0;
}; };
typedef IDirect3DRMTexture* LPDIRECT3DRMTEXTURE; typedef IDirect3DRMTexture* LPDIRECT3DRMTEXTURE;
struct IDirect3DRMTexture2 : public IDirect3DRMTexture {}; struct IDirect3DRMTexture2 : public IDirect3DRMTexture {};
typedef IDirect3DRMTexture2* LPDIRECT3DRMTEXTURE2; typedef IDirect3DRMTexture2* LPDIRECT3DRMTEXTURE2;
struct IDirect3DRMMaterial : virtual public IUnknown {}; struct IDirect3DRMMaterial : public IDirect3DRMObject {};
typedef IDirect3DRMMaterial *LPDIRECT3DRMMATERIAL, **LPLPDIRECT3DRMMATERIAL; 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 Clone(int flags, GUID iid, void** object) = 0;
virtual HRESULT GetBox(D3DRMBOX* box) = 0; virtual HRESULT GetBox(D3DRMBOX* box) = 0;
virtual HRESULT AddGroup( virtual HRESULT AddGroup(
@ -188,7 +188,7 @@ struct IDirect3DRMMesh : virtual public IUnknown {
) = 0; ) = 0;
virtual HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) = 0; virtual HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) = 0;
virtual HRESULT SetGroupColorRGB(int groupIndex, float r, float g, float b) = 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 SetGroupMaterial(int groupIndex, IDirect3DRMMaterial* material) = 0;
virtual HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) = 0; virtual HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) = 0;
virtual HRESULT SetGroupQuality(int groupIndex, D3DRMRENDERQUALITY quality) = 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; 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; virtual HRESULT SetColorRGB(float r, float g, float b) = 0;
}; };
struct IDirect3DRMLightArray : virtual public IUnknown { struct IDirect3DRMArray : public IUnknown {
virtual DWORD GetSize() = 0; virtual DWORD GetSize() = 0;
virtual HRESULT GetElement(int index, IDirect3DRMLight** light) const = 0;
}; };
struct IDirect3DRMVisualArray : virtual public IUnknown { struct IDirect3DRMLightArray : public IDirect3DRMArray {
virtual DWORD GetSize() = 0; virtual HRESULT GetElement(DWORD index, IDirect3DRMLight** out) = 0;
virtual HRESULT GetElement(int index, IDirect3DRMVisual** visual) const = 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; typedef struct IDirect3DRMFrameArray* LPDIRECT3DRMFRAMEARRAY;
struct IDirect3DRMFrame : virtual public IUnknown { struct IDirect3DRMFrame : public IDirect3DRMVisual {
virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0;
virtual LPVOID GetAppData() = 0;
virtual HRESULT AddChild(IDirect3DRMFrame* child) = 0; virtual HRESULT AddChild(IDirect3DRMFrame* child) = 0;
virtual HRESULT DeleteChild(IDirect3DRMFrame* child) = 0; virtual HRESULT DeleteChild(IDirect3DRMFrame* child) = 0;
virtual HRESULT SetSceneBackgroundRGB(float r, float g, float b) = 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 AddVisual(IDirect3DRMFrame* visual) = 0;
virtual HRESULT DeleteVisual(IDirect3DRMFrame* visual) = 0; virtual HRESULT DeleteVisual(IDirect3DRMFrame* visual) = 0;
virtual HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) = 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 GetTexture(IDirect3DRMTexture** texture) = 0;
virtual HRESULT SetColor(float r, float g, float b, float a) = 0; virtual HRESULT SetColor(float r, float g, float b, float a) = 0;
virtual HRESULT SetColor(D3DCOLOR) = 0; virtual HRESULT SetColor(D3DCOLOR) = 0;
@ -242,22 +246,22 @@ struct IDirect3DRMFrame : virtual public IUnknown {
}; };
typedef IDirect3DRMFrame* LPDIRECT3DRMFRAME; 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 {}; struct IDirect3DRMFrame2 : public IDirect3DRMFrame {};
typedef IDirect3DRMFrame2* LPDIRECT3DRMFRAME2; typedef IDirect3DRMFrame2* LPDIRECT3DRMFRAME2;
struct IDirect3DRMFrameArray : virtual public IUnknown {
virtual DWORD GetSize() = 0;
virtual HRESULT GetElement(DWORD index, IDirect3DRMFrame** frame) = 0;
};
struct D3DRMPICKDESC { struct D3DRMPICKDESC {
IDirect3DRMVisual* visual; IDirect3DRMVisual* visual;
IDirect3DRMFrame* frame; IDirect3DRMFrame* frame;
float dist; float dist;
}; };
struct IDirect3DRMPickedArray : virtual public IUnknown { struct IDirect3DRMPickedArray : public IDirect3DRMArray {
virtual DWORD GetSize() = 0;
virtual HRESULT GetPick( virtual HRESULT GetPick(
DWORD index, DWORD index,
IDirect3DRMVisual** visual, IDirect3DRMVisual** visual,
@ -288,19 +292,20 @@ struct IDirect3DRMViewport : public IDirect3DRMObject {
virtual HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) = 0; 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 Activate() = 0;
virtual HRESULT Paint() = 0; virtual HRESULT Paint() = 0;
virtual void HandleActivate(WORD wParam) = 0; virtual void HandleActivate(WORD wParam) = 0;
virtual void HandlePaint(void* p_dc) = 0; virtual void HandlePaint(void* p_dc) = 0;
}; };
struct IDirect3DRMViewportArray : virtual public IUnknown { struct IDirect3DRMDevice : virtual public IDirect3DRMObject {
virtual DWORD GetSize() = 0;
virtual HRESULT GetElement(int index, IDirect3DRMViewport** viewport) = 0;
};
struct IDirect3DRMDevice2 : virtual public IUnknown {
virtual unsigned long GetWidth() = 0; virtual unsigned long GetWidth() = 0;
virtual unsigned long GetHeight() = 0; virtual unsigned long GetHeight() = 0;
virtual HRESULT SetBufferCount(int count) = 0; virtual HRESULT SetBufferCount(int count) = 0;
@ -316,9 +321,12 @@ struct IDirect3DRMDevice2 : virtual public IUnknown {
virtual HRESULT SetRenderMode(D3DRMRENDERMODE mode) = 0; virtual HRESULT SetRenderMode(D3DRMRENDERMODE mode) = 0;
virtual D3DRMRENDERMODE GetRenderMode() = 0; virtual D3DRMRENDERMODE GetRenderMode() = 0;
virtual HRESULT Update() = 0; virtual HRESULT Update() = 0;
virtual HRESULT AddViewport(IDirect3DRMViewport* viewport) = 0;
virtual HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) = 0; virtual HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) = 0;
}; };
struct IDirect3DRMDevice2 : virtual public IDirect3DRMDevice {};
struct IDirect3DRM : virtual public IUnknown { struct IDirect3DRM : virtual public IUnknown {
virtual HRESULT CreateDeviceFromD3D( virtual HRESULT CreateDeviceFromD3D(
const IDirect3D2* d3d, const IDirect3D2* d3d,

View File

@ -0,0 +1,14 @@
#pragma once
#include <SDL3/SDL.h>
#include <miniwin_ddraw.h>
class DirectDrawImpl;
struct DirectDrawClipperImpl : public IDirectDrawClipper {
DirectDrawClipperImpl(DirectDrawImpl* lpDD);
~DirectDrawClipperImpl() override;
// IDirectDrawClipper interface
HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override;
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -0,0 +1,44 @@
#pragma once
#include <SDL3/SDL.h>
#include <miniwin_ddraw.h>
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;
};

View File

@ -0,0 +1,25 @@
#pragma once
#include <SDL3/SDL.h>
#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;
}

View File

@ -1,7 +1,6 @@
#include "miniwin.h" #include "miniwin.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <utility>
#include <vector> #include <vector>
ULONG IUnknown::AddRef() ULONG IUnknown::AddRef()
@ -25,6 +24,27 @@ HRESULT IUnknown::QueryInterface(const GUID& riid, void** ppvObject)
return E_NOINTERFACE; 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) VOID WINAPI Sleep(DWORD dwMilliseconds)
{ {
SDL_Delay(dwMilliseconds); SDL_Delay(dwMilliseconds);

View File

@ -1 +0,0 @@
#include "miniwin_d3d.h"

View File

@ -1,9 +1,273 @@
#include "miniwin_d3drm.h" #include "miniwin_d3drm.h"
#include <SDL3/SDL.h> #include "miniwin_ddsurface_p.h"
#include <assert.h>
struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { #include <SDL3/SDL.h>
#include <algorithm>
#include <assert.h>
#include <vector>
template <typename InterfaceType, typename ArrayInterface>
class Direct3DRMArrayBase : public ArrayInterface {
public:
~Direct3DRMArrayBase() override
{
for (auto* item : items) {
if (item) {
item->Release();
}
}
}
DWORD GetSize() override { return static_cast<DWORD>(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<InterfaceType*>(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<InterfaceType*> items;
};
struct Direct3DRMFrameArrayImpl : public Direct3DRMArrayBase<IDirect3DRMFrame, IDirect3DRMFrameArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMLightArrayImpl : public Direct3DRMArrayBase<IDirect3DRMLight, IDirect3DRMLightArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMViewportArrayImpl : public Direct3DRMArrayBase<IDirect3DRMViewport, IDirect3DRMViewportArray> {
using Direct3DRMArrayBase::Direct3DRMArrayBase;
};
struct Direct3DRMVisualArrayImpl : public Direct3DRMArrayBase<IDirect3DRMVisual, IDirect3DRMVisualArray> {
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<DWORD>(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<PickRecord> 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 <typename T>
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<std::pair<D3DRMOBJECTCALLBACK, void*>> m_callbacks;
LPD3DRM_APPDATA m_appData = NULL;
char* m_name = nullptr;
};
struct Direct3DRMMeshImpl : public Direct3DRMObjectBase<IDirect3DRMMesh> {
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(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<IDirect3DRMMesh*>(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<IDirect3DRMTexture2> {
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(new Direct3DRMTextureImpl);
return DD_OK;
}
HRESULT Changed(BOOL pixels, BOOL palette) override { return DD_OK; }
};
struct Direct3DRMDevice2Impl : public Direct3DRMObjectBase<IDirect3DRMDevice2> {
Direct3DRMDevice2Impl()
{
m_viewports = new Direct3DRMViewportArrayImpl;
m_viewports->AddRef();
}
~Direct3DRMDevice2Impl() override { m_viewports->Release(); }
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(new Direct3DRMDevice2Impl);
return DD_OK;
}
unsigned long GetWidth() override { return 640; } unsigned long GetWidth() override { return 640; }
unsigned long GetHeight() override { return 480; } unsigned long GetHeight() override { return 480; }
HRESULT SetBufferCount(int count) override { return DD_OK; } HRESULT SetBufferCount(int count) override { return DD_OK; }
@ -19,83 +283,82 @@ struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 {
HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; } HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; }
D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; } D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; }
HRESULT Update() override { return DD_OK; } HRESULT Update() override { return DD_OK; }
HRESULT AddViewport(IDirect3DRMViewport* viewport) override { return m_viewports->AddElement(viewport); }
HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override
{ {
assert(false && "unimplemented"); *ppViewportArray = m_viewports;
return DDERR_GENERIC; return DD_OK;
} }
private:
IDirect3DRMViewportArray* m_viewports;
}; };
struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { struct Direct3DRMFrameImpl : public Direct3DRMObjectBase<IDirect3DRMFrame2> {
HRESULT SetAppData(LPD3DRM_APPDATA appData) override Direct3DRMFrameImpl()
{ {
m_data = appData; m_children = new Direct3DRMFrameArrayImpl;
return DD_OK; m_children->AddRef();
} m_lights = new Direct3DRMLightArrayImpl;
LPVOID GetAppData() override { return m_data; } m_lights->AddRef();
HRESULT AddChild(IDirect3DRMFrame* child) override m_visuals = new Direct3DRMVisualArrayImpl;
{ m_visuals->AddRef();
child->AddRef(); }
return DD_OK; ~Direct3DRMFrameImpl() override
} {
HRESULT DeleteChild(IDirect3DRMFrame* child) override m_children->Release();
{ m_lights->Release();
child->Release(); m_visuals->Release();
if (m_texture) {
m_texture->Release();
}
}
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(new Direct3DRMFrameImpl);
return DD_OK; 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 SetSceneBackgroundRGB(float r, float g, float b) override { return DD_OK; }
HRESULT AddLight(IDirect3DRMLight* light) override HRESULT AddLight(IDirect3DRMLight* light) override { return m_lights->AddElement(light); }
{
light->AddRef();
return DD_OK;
}
HRESULT GetLights(IDirect3DRMLightArray** lightArray) override HRESULT GetLights(IDirect3DRMLightArray** lightArray) override
{ {
assert(false && "unimplemented"); *lightArray = m_lights;
return DDERR_GENERIC; m_lights->AddRef();
return DD_OK;
} }
HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; } HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; }
HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; } HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; }
HRESULT AddVisual(IDirect3DRMVisual* visual) override HRESULT AddVisual(IDirect3DRMVisual* visual) override { return m_visuals->AddElement(visual); }
{ HRESULT DeleteVisual(IDirect3DRMVisual* visual) override { return m_visuals->DeleteElement(visual); }
visual->AddRef(); HRESULT AddVisual(IDirect3DRMMesh* visual) override { return m_visuals->AddElement(visual); }
return DD_OK; HRESULT DeleteVisual(IDirect3DRMMesh* visual) override { return m_visuals->DeleteElement(visual); }
} HRESULT AddVisual(IDirect3DRMFrame* visual) override { return m_visuals->AddElement(visual); }
HRESULT DeleteVisual(IDirect3DRMVisual* visual) override HRESULT DeleteVisual(IDirect3DRMFrame* visual) override { return m_visuals->DeleteElement(visual); }
{
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 GetVisuals(IDirect3DRMVisualArray** visuals) override HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override
{ {
assert(false && "unimplemented"); *visuals = m_visuals;
return DDERR_GENERIC; 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 HRESULT GetTexture(IDirect3DRMTexture** texture) override
{ {
assert(false && "unimplemented"); if (!m_texture) {
return DDERR_GENERIC; 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(float r, float g, float b, float a) override { return DD_OK; }
HRESULT SetColor(D3DCOLOR) 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 SetMaterialMode(D3DRMMATERIALMODE mode) override { return DD_OK; }
HRESULT GetChildren(IDirect3DRMFrameArray** children) override HRESULT GetChildren(IDirect3DRMFrameArray** children) override
{ {
assert(false && "unimplemented"); *children = m_children;
return DDERR_GENERIC; m_children->AddRef();
return DD_OK;
} }
private: private:
LPD3DRM_APPDATA m_data; IDirect3DRMFrameArray* m_children;
IDirect3DRMLightArray* m_lights;
IDirect3DRMVisualArray* m_visuals;
IDirect3DRMTexture* m_texture;
}; };
struct Direct3DRMViewportImpl : public IDirect3DRMViewport { struct Direct3DRMViewportImpl : public Direct3DRMObjectBase<IDirect3DRMViewport> {
Direct3DRMViewportImpl() : m_data(nullptr) {}
HRESULT Clone(void** ppObject) override HRESULT Clone(void** ppObject) override
{ {
assert(false && "unimplemented"); *ppObject = static_cast<void*>(new Direct3DRMViewportImpl);
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;
return DD_OK; 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 Render(IDirect3DRMFrame* group) override { return DD_OK; }
HRESULT ForceUpdate(int x, int y, int w, int h) 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 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 HRESULT GetCamera(IDirect3DRMFrame** camera) override
{ {
assert(false && "unimplemented"); *camera = m_camera;
return DDERR_GENERIC; return DD_OK;
} }
HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; } HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; }
D3DRMPROJECTIONTYPE GetProjection() override { return D3DRMPROJECTIONTYPE::PERSPECTIVE; } 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; } HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) override { return DD_OK; }
private: private:
LPD3DRM_APPDATA m_data; IDirect3DRMFrame* m_camera;
}; };
struct Direct3DRMLightImpl : public IDirect3DRMLight { struct Direct3DRMLightImpl : public Direct3DRMObjectBase<IDirect3DRMLight> {
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(new Direct3DRMLightImpl);
return DD_OK;
}
HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; } HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; }
}; };
struct Direct3DRMImpl : public IDirect3DRM2 { struct Direct3DRMMaterialImpl : public Direct3DRMObjectBase<IDirect3DRMMaterial> {
HRESULT Clone(void** ppObject) override
{
*ppObject = static_cast<void*>(new Direct3DRMMaterialImpl);
return DD_OK;
}
};
struct Direct3DRMImpl : virtual public IDirect3DRM2 {
// IUnknown interface // IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override HRESULT QueryInterface(const GUID& riid, void** ppvObject) override
{ {
@ -186,27 +458,27 @@ struct Direct3DRMImpl : public IDirect3DRM2 {
IDirect3DRMDevice2** outDevice IDirect3DRMDevice2** outDevice
) override ) override
{ {
assert(false && "unimplemented"); *outDevice = static_cast<IDirect3DRMDevice2*>(new Direct3DRMDevice2Impl);
return DDERR_GENERIC; return S_OK;
} }
HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override
{ {
assert(false && "unimplemented"); *outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl);
return DDERR_GENERIC; return S_OK;
} }
HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override
{ {
assert(false && "unimplemented"); *outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl);
return DDERR_GENERIC; return S_OK;
} }
HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override
{ {
assert(false && "unimplemented"); *outMesh = static_cast<IDirect3DRMMesh*>(new Direct3DRMMeshImpl);
return DDERR_GENERIC; return DDERR_GENERIC;
} }
HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override
{ {
*outMaterial = new IDirect3DRMMaterial; *outMaterial = static_cast<IDirect3DRMMaterial*>(new Direct3DRMMaterialImpl);
return DD_OK; return DD_OK;
} }
HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override
@ -230,6 +502,7 @@ struct Direct3DRMImpl : public IDirect3DRM2 {
) override ) override
{ {
*outViewport = static_cast<IDirect3DRMViewport*>(new Direct3DRMViewportImpl); *outViewport = static_cast<IDirect3DRMViewport*>(new Direct3DRMViewportImpl);
device->AddViewport(*outViewport);
return DD_OK; return DD_OK;
} }
HRESULT SetDefaultTextureShades(unsigned int count) override { return DD_OK; } HRESULT SetDefaultTextureShades(unsigned int count) override { return DD_OK; }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,6 +1,10 @@
#include "miniwin_ddraw.h"
#include "miniwin_d3d.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 <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <assert.h> #include <assert.h>
@ -10,360 +14,96 @@
SDL_Renderer* renderer; SDL_Renderer* renderer;
static SDL_FRect ConvertRect(const RECT* r) HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
{ {
SDL_FRect sdlRect; if (SDL_memcmp(&riid, &IID_IDirectDraw2, sizeof(GUID)) == 0) {
sdlRect.x = r->left; this->IUnknown::AddRef();
sdlRect.y = r->top; *ppvObject = static_cast<IDirectDraw2*>(this);
sdlRect.w = r->right - r->left; return S_OK;
sdlRect.h = r->bottom - r->top; }
return sdlRect; if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) {
this->IUnknown::AddRef();
*ppvObject = static_cast<IDirect3D2*>(this);
return S_OK;
}
SDL_LogError(LOG_CATEGORY_MINIWIN, "DirectDrawImpl does not implement guid");
return E_NOINTERFACE;
} }
struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { // IDirectDraw interface
DirectDrawSurfaceImpl() {} HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter)
DirectDrawSurfaceImpl(int width, int height) {
{ *lplpDDClipper = static_cast<IDirectDrawClipper*>(new DirectDrawClipperImpl(this));
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());
}
}
~DirectDrawSurfaceImpl() override return DD_OK;
{ }
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<IDirectDrawSurface3*>(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<DirectDrawSurfaceImpl*>(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<DirectDrawSurfaceImpl*>(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<IDirectDrawSurface*>(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;
}
int pitch = 0; HRESULT DirectDrawImpl::CreatePalette(
void* pixels = nullptr; DDPixelCaps dwFlags,
if (SDL_LockTexture(texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { LPPALETTEENTRY lpColorTable,
return DDERR_GENERIC; LPDIRECTDRAWPALETTE* lplpDDPalette,
} IUnknown* pUnkOuter
)
{
*lplpDDPalette = static_cast<LPDIRECTDRAWPALETTE>(new DirectDrawPaletteImpl(lpColorTable));
return DD_OK;
}
lpDDSurfaceDesc->lpSurface = pixels; HRESULT DirectDrawImpl::CreateSurface(
lpDDSurfaceDesc->lPitch = pitch; LPDDSURFACEDESC lpDDSurfaceDesc,
const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); LPDIRECTDRAWSURFACE* lplpDDSurface,
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; IUnknown* pUnkOuter
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; )
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; {
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) {
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) {
if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) {
return DD_OK; return DDERR_INVALIDPARAMS;
} }
HRESULT ReleaseDC(HDC hDC) override { return DD_OK; } SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth);
HRESULT Restore() override { return DD_OK; } *lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl);
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);
return DD_OK; return DD_OK;
} }
return DDERR_GENERIC; if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) {
} if ((lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) == DDSD_BACKBUFFERCOUNT) {
SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount);
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<IDirectDraw2*>(this);
return S_OK;
}
if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) {
this->IUnknown::AddRef();
*ppvObject = static_cast<IDirect3D2*>(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<IDirectDrawClipper*>(new DirectDrawClipperImpl);
return DD_OK;
}
HRESULT CreatePalette(
DDPixelCaps dwFlags,
LPPALETTEENTRY lpColorTable,
LPDIRECTDRAWPALETTE* lplpDDPalette,
IUnknown* pUnkOuter
) override
{
*lplpDDPalette = static_cast<LPDIRECTDRAWPALETTE>(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<IDirectDrawSurface*>(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<IDirectDrawSurface*>(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
} }
int width, height;
SDL_GetRenderOutputSize(renderer, &width, &height);
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height));
return DD_OK;
} }
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) {
if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { SDL_Log("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces?
if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) {
SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format
}
} }
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) {
if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { SDL_Log("DDSCAPS_SYSTEMMEMORY"); // Software rendering?
return DDERR_INVALIDPARAMS; }
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<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height));
return DD_OK;
} }
HRESULT EnumDisplayModes(
DWORD dwFlags, if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) {
LPDDSURFACEDESC lpDDSurfaceDesc, if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) {
LPVOID lpContext, SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format
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;
} }
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 ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) {
{
if (!cb) {
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
} }
int numDrivers = SDL_GetNumRenderDrivers(); int width = lpDDSurfaceDesc->dwWidth;
if (numDrivers <= 0) { int height = lpDDSurfaceDesc->dwHeight;
return DDERR_GENERIC; *lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height));
} return DD_OK;
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;
} }
HRESULT DirectDrawImpl::EnumDisplayModes( HRESULT DirectDrawImpl::EnumDisplayModes(
@ -373,10 +113,6 @@ HRESULT DirectDrawImpl::EnumDisplayModes(
LPDDENUMMODESCALLBACK lpEnumModesCallback LPDDENUMMODESCALLBACK lpEnumModesCallback
) )
{ {
if (!lpEnumModesCallback) {
return DDERR_INVALIDPARAMS;
}
SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); SDL_DisplayID displayID = SDL_GetPrimaryDisplay();
if (!displayID) { if (!displayID) {
return DDERR_GENERIC; return DDERR_GENERIC;
@ -417,27 +153,132 @@ HRESULT DirectDrawImpl::EnumDisplayModes(
return status; return status;
} }
HRESULT DirectDrawImpl::FlipToGDISurface()
{
return DD_OK;
}
HRESULT DirectDrawImpl::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) HRESULT DirectDrawImpl::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps)
{ {
if (lpDDDriverCaps) { if (lpDDDriverCaps) {
memset(lpDDDriverCaps, 0, sizeof(DDCAPS)); if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) {
lpDDDriverCaps->dwSize = sizeof(DDCAPS); lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting
lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting }
} }
if (lpDDHELCaps) { if (lpDDHELCaps) {
memset(lpDDHELCaps, 0, sizeof(DDCAPS)); if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) {
lpDDHELCaps->dwSize = sizeof(DDCAPS); lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting
lpDDHELCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting }
} }
return S_OK; 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) HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter)
{ {
if (!lplpDD) { if (lpGuid) {
return DDERR_INVALIDPARAMS; MINIWIN_ERROR("Specifying a DirectDraw driver is not implemented");
} }
*lplpDD = new DirectDrawImpl; *lplpDD = new DirectDrawImpl;
@ -451,8 +292,10 @@ HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context)
for (int i = 0; i < numDrivers; ++i) { for (int i = 0; i < numDrivers; ++i) {
const char* driverName = SDL_GetVideoDriver(i); const char* driverName = SDL_GetVideoDriver(i);
char* driverNameDup = SDL_strdup(driverName);
if (!cb(NULL, (LPSTR) driverName, NULL, context)) { BOOL callback_result = cb(NULL, driverNameDup, NULL, context);
SDL_free(driverNameDup);
if (!callback_result) {
return DDERR_GENERIC; return DDERR_GENERIC;
} }
} }

View File

@ -0,0 +1,217 @@
#include "miniwin_ddraw_p.h"
#include "miniwin_ddsurface_p.h"
#include "miniwin_p.h"
#include <assert.h>
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<IDirectDrawSurface3*>(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<DirectDrawSurfaceImpl*>(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<DirectDrawSurfaceImpl*>(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<IDirectDrawSurface*>(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;
}