From 5ff007747f4708ac321f700827dda2fd26c15d9a Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Sun, 3 Jan 1999 17:00:19 +0000 Subject: [PATCH] - beginning of implementation of Direct3D2 (DX 5.0) and associated classes - some basic code for Direct3D and Direct3DExecuteBuffer (DX 3.0) - added stretching to Blt function --- configure | 217 +++-- configure.in | 2 + documentation/status/direct3D | 55 ++ documentation/status/directdraw | 2 +- graphics/Makefile.in | 7 + graphics/d3d_private.h | 110 +++ graphics/d3dcommon.c | 185 ++++ graphics/d3ddevices.c | 1499 +++++++++++++++++++++++++++++++ graphics/d3dexecutebuffer.c | 578 ++++++++++++ graphics/d3dlight.c | 260 ++++++ graphics/d3dmaterial.c | 251 ++++++ graphics/d3dtexture.c | 200 +++++ graphics/d3dviewport.c | 350 ++++++++ graphics/ddraw.c | 384 ++++++-- include/acconfig.h | 2 + include/config.h.in | 3 + include/d3d.h | 1071 +++++++++++++++++++++- include/wine_gl.h | 32 + multimedia/dsound.c | 42 +- 19 files changed, 5040 insertions(+), 210 deletions(-) create mode 100644 documentation/status/direct3D create mode 100644 graphics/d3d_private.h create mode 100644 graphics/d3dcommon.c create mode 100644 graphics/d3ddevices.c create mode 100644 graphics/d3dexecutebuffer.c create mode 100644 graphics/d3dlight.c create mode 100644 graphics/d3dmaterial.c create mode 100644 graphics/d3dtexture.c create mode 100644 graphics/d3dviewport.c create mode 100644 include/wine_gl.h diff --git a/configure b/configure index d01cfcf2a50..6f2682e2f3d 100755 --- a/configure +++ b/configure @@ -2451,6 +2451,49 @@ else echo "$ac_t""no" 1>&6 fi + echo $ac_n "checking for OSMesaCreateContext in -lMesaGL""... $ac_c" 1>&6 +echo "configure:2456: checking for OSMesaCreateContext in -lMesaGL" >&5 +ac_lib_var=`echo MesaGL'_'OSMesaCreateContext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lMesaGL $X_LIBS -lXext -lX11 -lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_MESAGL 1 +EOF + X_PRE_LIBS="$X_PRE_LIBS -lMesaGL" +else + echo "$ac_t""no" 1>&6 +fi + else XLIB="" X_CFLAGS="" @@ -2458,7 +2501,7 @@ else fi echo $ac_n "checking for waddch in -lncurses""... $ac_c" 1>&6 -echo "configure:2462: checking for waddch in -lncurses" >&5 +echo "configure:2505: checking for waddch in -lncurses" >&5 ac_lib_var=`echo ncurses'_'waddch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2466,7 +2509,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2508,7 +2551,7 @@ if test "$ac_cv_lib_ncurses_waddch" = "yes" then : else echo $ac_n "checking for waddch in -lcurses""... $ac_c" 1>&6 -echo "configure:2512: checking for waddch in -lcurses" >&5 +echo "configure:2555: checking for waddch in -lcurses" >&5 ac_lib_var=`echo curses'_'waddch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2516,7 +2559,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2557,12 +2600,12 @@ fi fi echo $ac_n "checking "for GNU style IPX support"""... $ac_c" 1>&6 -echo "configure:2561: checking "for GNU style IPX support"" >&5 +echo "configure:2604: checking "for GNU style IPX support"" >&5 if eval "test \"`echo '$''{'ac_cv_c_ipx_gnu'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2570,7 +2613,7 @@ int main() { ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX ; return 0; } EOF -if { (eval echo configure:2574: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_IPX_GNU 1 @@ -2592,12 +2635,12 @@ echo "$ac_t""$ac_cv_c_ipx_gnu" 1>&6 if test "$ac_cv_c_ipx_gnu" = "no" then echo $ac_n "checking "for linux style IPX support"""... $ac_c" 1>&6 -echo "configure:2596: checking "for linux style IPX support"" >&5 +echo "configure:2639: checking "for linux style IPX support"" >&5 if eval "test \"`echo '$''{'ac_cv_c_ipx_linux'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2606,7 +2649,7 @@ int main() { ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX ; return 0; } EOF -if { (eval echo configure:2610: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_IPX_LINUX 1 @@ -2630,17 +2673,17 @@ for ac_hdr in sys/soundcard.h machine/soundcard.h soundcard.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2634: checking for $ac_hdr" >&5 +echo "configure:2677: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2644: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -2668,12 +2711,12 @@ done echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6 -echo "configure:2672: checking "for Open Sound System"" >&5 +echo "configure:2715: checking "for Open Sound System"" >&5 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_opensoundsystem="yes" else @@ -2718,12 +2761,12 @@ fi echo $ac_n "checking "for union semun"""... $ac_c" 1>&6 -echo "configure:2722: checking "for union semun"" >&5 +echo "configure:2765: checking "for union semun"" >&5 if eval "test \"`echo '$''{'ac_cv_c_union_semun'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2731,7 +2774,7 @@ int main() { union semun foo ; return 0; } EOF -if { (eval echo configure:2735: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_union_semun="yes" else @@ -2759,7 +2802,7 @@ if test "x${GCC}" = "xyes" then CFLAGS="$CFLAGS -Wall" echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6 -echo "configure:2763: checking "for gcc strength-reduce bug"" >&5 +echo "configure:2806: checking "for gcc strength-reduce bug"" >&5 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2767,7 +2810,7 @@ else ac_cv_c_gcc_strength_bug="yes" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_gcc_strength_bug="no" else @@ -2801,7 +2844,7 @@ fi echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6 -echo "configure:2805: checking "whether external symbols need an underscore prefix"" >&5 +echo "configure:2848: checking "whether external symbols need an underscore prefix"" >&5 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2813,14 +2856,14 @@ _ac_test: .long 0 EOF cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_extern_prefix="yes" else @@ -2844,7 +2887,7 @@ fi echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6 -echo "configure:2848: checking "whether assembler accepts .string"" >&5 +echo "configure:2891: checking "whether assembler accepts .string"" >&5 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2854,14 +2897,14 @@ cat > conftest_asm.s < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_asm_string="yes" else @@ -2889,21 +2932,21 @@ LDSHARED="" if test "$LIB_TARGET" = "libwine.so.1.0" then echo $ac_n "checking "whether we can build a Linux dll"""... $ac_c" 1>&6 -echo "configure:2893: checking "whether we can build a Linux dll"" >&5 +echo "configure:2936: checking "whether we can build a Linux dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll_linux'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_dll_linux="yes" else @@ -2924,21 +2967,21 @@ echo "$ac_t""$ac_cv_c_dll_linux" 1>&6 LDSHARED="\$(CC) -shared -Wl,-soname,libwine.so" else echo $ac_n "checking "whether we can build a NetBSD dll"""... $ac_c" 1>&6 -echo "configure:2928: checking "whether we can build a NetBSD dll"" >&5 +echo "configure:2971: checking "whether we can build a NetBSD dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll_netbsd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -Bshareable -Bforcearchive" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_dll_netbsd="yes" else @@ -2969,7 +3012,7 @@ fi echo $ac_n "checking "for reentrant libc"""... $ac_c" 1>&6 -echo "configure:2973: checking "for reentrant libc"" >&5 +echo "configure:3016: checking "for reentrant libc"" >&5 if eval "test \"`echo '$''{'wine_cv_libc_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2977,14 +3020,14 @@ else wine_cv_libc_reentrant=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then wine_cv_libc_reentrant=yes else @@ -3009,7 +3052,7 @@ fi echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6 -echo "configure:3013: checking "for reentrant X libraries"" >&5 +echo "configure:3056: checking "for reentrant X libraries"" >&5 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3054,12 +3097,12 @@ fi for ac_func in clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3058: checking for $ac_func" >&5 +echo "configure:3101: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3110,17 +3153,17 @@ for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3114: checking for $ac_hdr" >&5 +echo "configure:3157: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3124: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3167: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -3147,12 +3190,12 @@ fi done echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:3151: checking whether stat file-mode macros are broken" >&5 +echo "configure:3194: checking whether stat file-mode macros are broken" >&5 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3203,12 +3246,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3207: checking for working const" >&5 +echo "configure:3250: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3278,12 +3321,12 @@ EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:3282: checking for ANSI C header files" >&5 +echo "configure:3325: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3291,7 +3334,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3338: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -3308,7 +3351,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3326,7 +3369,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3347,7 +3390,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -3358,7 +3401,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:3362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else @@ -3382,12 +3425,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3386: checking for size_t" >&5 +echo "configure:3429: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3415,7 +3458,7 @@ EOF fi echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:3419: checking size of long long" >&5 +echo "configure:3462: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3423,7 +3466,7 @@ else ac_cv_sizeof_long_long=0 else cat > conftest.$ac_ext < main() @@ -3434,7 +3477,7 @@ main() exit(0); } EOF -if { (eval echo configure:3438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -3457,7 +3500,7 @@ EOF if test $ac_cv_func_sendmsg = no; then echo $ac_n "checking for sendmsg in -lsocket""... $ac_c" 1>&6 -echo "configure:3461: checking for sendmsg in -lsocket" >&5 +echo "configure:3504: checking for sendmsg in -lsocket" >&5 ac_lib_var=`echo socket'_'sendmsg | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3465,7 +3508,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:3523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3509,12 +3552,12 @@ fi if test "$ac_cv_header_sys_vfs_h" = "yes" then echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3513: checking "whether sys/vfs.h defines statfs"" >&5 +echo "configure:3556: checking "whether sys/vfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3531,7 +3574,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_vfs_has_statfs=yes else @@ -3558,12 +3601,12 @@ fi if test "$ac_cv_header_sys_statfs_h" = "yes" then echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3562: checking "whether sys/statfs.h defines statfs"" >&5 +echo "configure:3605: checking "whether sys/statfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3578,7 +3621,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3582: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_statfs_has_statfs=yes else @@ -3605,12 +3648,12 @@ fi if test "$ac_cv_header_sys_mount_h" = "yes" then echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6 -echo "configure:3609: checking "whether sys/mount.h defines statfs"" >&5 +echo "configure:3652: checking "whether sys/mount.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3625,7 +3668,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_mount_has_statfs=yes else @@ -3651,7 +3694,7 @@ fi echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6 -echo "configure:3655: checking "for statfs.f_bfree"" >&5 +echo "configure:3698: checking "for statfs.f_bfree"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3660,7 +3703,7 @@ else wine_cv_statfs_bfree=no else cat > conftest.$ac_ext < @@ -3687,7 +3730,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3691: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3734: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bfree=yes else @@ -3711,7 +3754,7 @@ EOF fi echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6 -echo "configure:3715: checking "for statfs.f_bavail"" >&5 +echo "configure:3758: checking "for statfs.f_bavail"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3720,7 +3763,7 @@ else wine_cv_statfs_bavail=no else cat > conftest.$ac_ext < @@ -3747,7 +3790,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bavail=yes else @@ -3772,7 +3815,7 @@ fi echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6 -echo "configure:3776: checking "for working sigaltstack"" >&5 +echo "configure:3819: checking "for working sigaltstack"" >&5 if eval "test \"`echo '$''{'ac_cv_c_working_sigaltstack'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3781,7 +3824,7 @@ else else cat > conftest.$ac_ext < @@ -3819,7 +3862,7 @@ else } EOF -if { (eval echo configure:3823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_working_sigaltstack="yes" else @@ -3846,12 +3889,12 @@ fi echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6 -echo "configure:3850: checking "for msg_accrights in struct msghdr"" >&5 +echo "configure:3893: checking "for msg_accrights in struct msghdr"" >&5 if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3859,7 +3902,7 @@ int main() { struct msghdr hdr; hdr.msg_accrights=0 ; return 0; } EOF -if { (eval echo configure:3863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_msg_accrights="yes" else diff --git a/configure.in b/configure.in index 12c8036110b..194029b5143 100644 --- a/configure.in +++ b/configure.in @@ -106,6 +106,8 @@ then AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11) dnl Check for XFree86 VMODE extension AC_CHECK_LIB(Xxf86vm,XF86VidModeQueryExtension,AC_DEFINE(HAVE_LIBXXF86VM) X_PRE_LIBS="$X_PRE_LIBS -lXxf86vm",,$X_LIBS -lXext -lX11) + dnl Check for the presence of Mesa + AC_CHECK_LIB(MesaGL,OSMesaCreateContext,AC_DEFINE(HAVE_MESAGL) X_PRE_LIBS="$X_PRE_LIBS -lMesaGL",,$X_LIBS -lXext -lX11 -lm) else XLIB="" X_CFLAGS="" diff --git a/documentation/status/direct3D b/documentation/status/direct3D new file mode 100644 index 00000000000..b73d30da5ea --- /dev/null +++ b/documentation/status/direct3D @@ -0,0 +1,55 @@ +Introduction +------------ + +This file contains information about Wine's implementation of +Direct3D. + +The current version requires : + * Mesa (tested with version 3.1 beta) + * a display in 16bpp + +To minimize the impact on DirectDraw (i.e. to reuse most of the code +already done for DirectDraw), I decided not to start with an +implementation based on GLX, but on OSMesa. This way, all the OpenGL +rendering are done in a 'private' memory buffer, buffer that will +copied back to the DirectDraw Surface each time a 3D scene +finishes. It is not optimal for execution speed (on each frame, the +OpenGL buffer is converted from 32 to 16 bpp and copied onto the +screen) but is for development (I had almost nothing to change in +DirectDraw). Moreover, 99 % of the code in the Direct3D implementation +is 'device independant' (i.e. GLX / OSMesa / whatever), so that +changing to GLX will have only a minor impact on Direct3D's code. + +Code structure +-------------- + +TODO (well, once the code will be put in the dll/ddraw directory) + +Status +------ + +I tested this code with two programs (all using Direct3D 5.0) : + + * BOIDS.EXE that comes with the 5.2 DirectX SDK : works great. Only + thing missing is the texturing and transparency on the spinning + gobes. Lighting seems to be a bit different than the Real One. + + * Tomb Raider II : works quite well (without texturing). + +TODO +---- + * finish working on Execute Buffers (i.e. Direct3D 3.0) + * texture mapping / blending effects + * real GLX implementation (will need a complete rewrite of DirectDraw + also) to have 3DFx support + * restructuration of all the DDRAW.DLL (put that in the dll + directory, better separation of 'drivers, ...) + * start looking into DirectX 6.0 + * inquire on Mesa / XFree86 mailing lists about direct access to + display hardware (for games such as Tomb Raider II that displays + vertices that are already in screen coordinates) + * look into thread safeness... + +-- +Lionel Ulmer - ulmer@directprovider.net +Last updated : Sun Jan 03 1999 diff --git a/documentation/status/directdraw b/documentation/status/directdraw index a19ca49954c..ae69d70f444 100644 --- a/documentation/status/directdraw +++ b/documentation/status/directdraw @@ -1,5 +1,5 @@ This file contains information on the current implementation of the DirectDraw -API. +API. Information specific to Direct3D is in the direct3D file. The DirectDraw API is being used in a lot of current computergames. Its API layer is represented by the functions in the Win32 DLL ddraw.dll and the diff --git a/graphics/Makefile.in b/graphics/Makefile.in index 10b541852dd..eb7bacbf99c 100644 --- a/graphics/Makefile.in +++ b/graphics/Makefile.in @@ -8,6 +8,13 @@ MODULE = graphics C_SRCS = \ bitblt.c \ cache.c \ + d3dcommon.c \ + d3ddevices.c \ + d3dexecutebuffer.c \ + d3dlight.c \ + d3dmaterial.c \ + d3dtexture.c \ + d3dviewport.c \ ddraw.c \ dispdib.c \ driver.c \ diff --git a/graphics/d3d_private.h b/graphics/d3d_private.h new file mode 100644 index 00000000000..c5f81aef992 --- /dev/null +++ b/graphics/d3d_private.h @@ -0,0 +1,110 @@ +/* Direct3D private include file + (c) 1998 Lionel ULMER + + This files contains all the structure that are not exported + through d3d.h and all common macros. */ + +#ifndef _WINE_D3D_PRIVATE_H +#define _WINE_D3D_PRIVATE_H + +#ifdef HAVE_MESAGL + +#include "d3d.h" +#include "wine_gl.h" + +/* Matrix copy WITH transposition */ +#define conv_mat2(mat,gl_mat) \ +{ \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \ + (gl_mat)[ 0] = (mat)->_11; \ + (gl_mat)[ 1] = (mat)->_21; \ + (gl_mat)[ 2] = (mat)->_31; \ + (gl_mat)[ 3] = (mat)->_41; \ + (gl_mat)[ 4] = (mat)->_12; \ + (gl_mat)[ 5] = (mat)->_22; \ + (gl_mat)[ 6] = (mat)->_32; \ + (gl_mat)[ 7] = (mat)->_42; \ + (gl_mat)[ 8] = (mat)->_13; \ + (gl_mat)[ 9] = (mat)->_23; \ + (gl_mat)[10] = (mat)->_33; \ + (gl_mat)[11] = (mat)->_43; \ + (gl_mat)[12] = (mat)->_14; \ + (gl_mat)[13] = (mat)->_24; \ + (gl_mat)[14] = (mat)->_34; \ + (gl_mat)[15] = (mat)->_44; \ +}; + +/* Matrix copy WITHOUT transposition */ +#define conv_mat(mat,gl_mat) \ +{ \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \ + memcpy(gl_mat, (mat), 16 * sizeof(float)); \ +}; + +#define dump_mat(mat) \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \ + TRACE(ddraw, "%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); + +typedef struct OpenGL_IDirect3DDevice2 { + IDirect3DDevice2 common; + + /* These are the OpenGL-specific variables */ + OSMesaContext ctx; + unsigned char *buffer; + + float world_mat[16]; + float view_mat[16]; + float proj_mat[16]; +} OpenGL_IDirect3DDevice2; + +typedef struct OpenGL_IDirect3DDevice { + IDirect3DDevice common; + + /* These are the OpenGL-specific variables */ + OSMesaContext ctx; + unsigned char *buffer; + + D3DMATRIX *world_mat; + D3DMATRIX *view_mat; + D3DMATRIX *proj_mat; +} OpenGL_IDirect3DDevice; + +#define _dump_colorvalue(s,v) \ + TRACE(ddraw, " " s " : %f %f %f %f\n", \ + (v).r.r, (v).g.g, (v).b.b, (v).a.a); + +#endif /* HAVE_MESAGL */ + +/* Common functions defined in d3dcommon.c */ +void set_render_state(D3DRENDERSTATETYPE dwRenderStateType, + DWORD dwRenderState) ; + +/* All non-static functions 'exported' by various sub-objects */ +extern LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf) ; +extern LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf) ; + +extern LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d) ; +extern LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d) ; + +extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(LPDIRECT3DDEVICE d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc) ; + +extern LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d) ; +extern LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d) ; + +extern LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) ; +extern LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) ; + +extern int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device) ; +extern int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ; +extern int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ; +extern int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d) ; + +#endif /* _WINE_D3D_PRIVATE_H */ diff --git a/graphics/d3dcommon.c b/graphics/d3dcommon.c new file mode 100644 index 00000000000..8fa6c8b3f2c --- /dev/null +++ b/graphics/d3dcommon.c @@ -0,0 +1,185 @@ +/* Direct3D Common functions + (c) 1998 Lionel ULMER + + This file contains all common miscellaneous code that spans + different 'objects' */ + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "interfaces.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static void _dump_renderstate(D3DRENDERSTATETYPE type, + DWORD value) { + char *states[] = { + NULL, + "D3DRENDERSTATE_TEXTUREHANDLE", + "D3DRENDERSTATE_ANTIALIAS", + "D3DRENDERSTATE_TEXTUREADDRESS", + "D3DRENDERSTATE_TEXTUREPERSPECTIVE", + "D3DRENDERSTATE_WRAPU", + "D3DRENDERSTATE_WRAPV", + "D3DRENDERSTATE_ZENABLE", + "D3DRENDERSTATE_FILLMODE", + "D3DRENDERSTATE_SHADEMODE", + "D3DRENDERSTATE_LINEPATTERN", + "D3DRENDERSTATE_MONOENABLE", + "D3DRENDERSTATE_ROP2", + "D3DRENDERSTATE_PLANEMASK", + "D3DRENDERSTATE_ZWRITEENABLE", + "D3DRENDERSTATE_ALPHATESTENABLE", + "D3DRENDERSTATE_LASTPIXEL", + "D3DRENDERSTATE_TEXTUREMAG", + "D3DRENDERSTATE_TEXTUREMIN", + "D3DRENDERSTATE_SRCBLEND", + "D3DRENDERSTATE_DESTBLEND", + "D3DRENDERSTATE_TEXTUREMAPBLEND", + "D3DRENDERSTATE_CULLMODE", + "D3DRENDERSTATE_ZFUNC", + "D3DRENDERSTATE_ALPHAREF", + "D3DRENDERSTATE_ALPHAFUNC", + "D3DRENDERSTATE_DITHERENABLE", + "D3DRENDERSTATE_ALPHABLENDENABLE", + "D3DRENDERSTATE_FOGENABLE", + "D3DRENDERSTATE_SPECULARENABLE", + "D3DRENDERSTATE_ZVISIBLE", + "D3DRENDERSTATE_SUBPIXEL", + "D3DRENDERSTATE_SUBPIXELX", + "D3DRENDERSTATE_STIPPLEDALPHA", + "D3DRENDERSTATE_FOGCOLOR", + "D3DRENDERSTATE_FOGTABLEMODE", + "D3DRENDERSTATE_FOGTABLESTART", + "D3DRENDERSTATE_FOGTABLEEND", + "D3DRENDERSTATE_FOGTABLEDENSITY", + "D3DRENDERSTATE_STIPPLEENABLE", + "D3DRENDERSTATE_EDGEANTIALIAS", + "D3DRENDERSTATE_COLORKEYENABLE", + "D3DRENDERSTATE_BORDERCOLOR", + "D3DRENDERSTATE_TEXTUREADDRESSU", + "D3DRENDERSTATE_TEXTUREADDRESSV", + "D3DRENDERSTATE_MIPMAPLODBIAS", + "D3DRENDERSTATE_ZBIAS", + "D3DRENDERSTATE_RANGEFOGENABLE", + "D3DRENDERSTATE_ANISOTROPY", + "D3DRENDERSTATE_FLUSHBATCH", + "D3DRENDERSTATE_STIPPLEPATTERN00", + "D3DRENDERSTATE_STIPPLEPATTERN01", + "D3DRENDERSTATE_STIPPLEPATTERN02", + "D3DRENDERSTATE_STIPPLEPATTERN03", + "D3DRENDERSTATE_STIPPLEPATTERN04", + "D3DRENDERSTATE_STIPPLEPATTERN05", + "D3DRENDERSTATE_STIPPLEPATTERN06", + "D3DRENDERSTATE_STIPPLEPATTERN07", + "D3DRENDERSTATE_STIPPLEPATTERN08", + "D3DRENDERSTATE_STIPPLEPATTERN09", + "D3DRENDERSTATE_STIPPLEPATTERN10", + "D3DRENDERSTATE_STIPPLEPATTERN11", + "D3DRENDERSTATE_STIPPLEPATTERN12", + "D3DRENDERSTATE_STIPPLEPATTERN13", + "D3DRENDERSTATE_STIPPLEPATTERN14", + "D3DRENDERSTATE_STIPPLEPATTERN15", + "D3DRENDERSTATE_STIPPLEPATTERN16", + "D3DRENDERSTATE_STIPPLEPATTERN17", + "D3DRENDERSTATE_STIPPLEPATTERN18", + "D3DRENDERSTATE_STIPPLEPATTERN19", + "D3DRENDERSTATE_STIPPLEPATTERN20", + "D3DRENDERSTATE_STIPPLEPATTERN21", + "D3DRENDERSTATE_STIPPLEPATTERN22", + "D3DRENDERSTATE_STIPPLEPATTERN23", + "D3DRENDERSTATE_STIPPLEPATTERN24", + "D3DRENDERSTATE_STIPPLEPATTERN25", + "D3DRENDERSTATE_STIPPLEPATTERN26", + "D3DRENDERSTATE_STIPPLEPATTERN27", + "D3DRENDERSTATE_STIPPLEPATTERN28", + "D3DRENDERSTATE_STIPPLEPATTERN29", + "D3DRENDERSTATE_STIPPLEPATTERN30", + "D3DRENDERSTATE_STIPPLEPATTERN31" + }; + + DUMP(" %s = 0x%08lx\n", states[type], value); +} + + +void set_render_state(D3DRENDERSTATETYPE dwRenderStateType, + DWORD dwRenderState) +{ + + if (TRACE_ON(ddraw)) + _dump_renderstate(dwRenderStateType, dwRenderState); + + /* First, all the stipple patterns */ + if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && + (dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN31)) { + + } else { + /* All others state variables */ + switch (dwRenderStateType) { + case D3DRENDERSTATE_ZENABLE: /* 7 */ + if (dwRenderState) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + break; + + case D3DRENDERSTATE_ZWRITEENABLE: /* 14 */ + if (dwRenderState) + glDepthMask(GL_TRUE); + else + glDepthMask(GL_FALSE); + break; + + case D3DRENDERSTATE_ZFUNC: /* 23 */ + switch ((D3DCMPFUNC) dwRenderState) { + case D3DCMP_NEVER: + glDepthFunc(GL_NEVER); + break; + case D3DCMP_LESS: + glDepthFunc(GL_LESS); + break; + case D3DCMP_EQUAL: + glDepthFunc(GL_EQUAL); + break; + case D3DCMP_LESSEQUAL: + glDepthFunc(GL_LEQUAL); + break; + case D3DCMP_GREATER: + glDepthFunc(GL_GREATER); + break; + case D3DCMP_NOTEQUAL: + glDepthFunc(GL_NOTEQUAL); + break; + case D3DCMP_GREATEREQUAL: + glDepthFunc(GL_GEQUAL); + break; + case D3DCMP_ALWAYS: + glDepthFunc(GL_ALWAYS); + break; + + default: + ERR(ddraw, "Unexpected value\n"); + } + break; + + case D3DRENDERSTATE_DITHERENABLE: /* 26 */ + if (dwRenderState) + glEnable(GL_DITHER); + else + glDisable(GL_DITHER); + break; + + default: + FIXME(ddraw, "Unhandled Render State\n"); + break; + } + } +} + + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3ddevices.c b/graphics/d3ddevices.c new file mode 100644 index 00000000000..dcbdc0c7a4d --- /dev/null +++ b/graphics/d3ddevices.c @@ -0,0 +1,1499 @@ +/* Direct3D Device + (c) 1998 Lionel ULMER + + This files contains all the D3D devices that Wine supports. For the moment + only the 'OpenGL' target is supported. */ + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static GUID IID_D3DDEVICE2_OpenGL = { + 0x39a0da38, + 0x7e57, + 0x11d2, + { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c } +}; + +static GUID IID_D3DDEVICE_OpenGL = { + 0x31416d44, + 0x86ae, + 0x11d2, + { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa } +}; + + +static IDirect3DDevice2_VTable OpenGL_vtable; +static IDirect3DDevice_VTable OpenGL_vtable_dx3; + +/******************************************************************************* + * OpenGL static functions + */ +static void set_context(LPDIRECT3DDEVICE2 this) { + OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; + + OSMesaMakeCurrent(odev->ctx, odev->buffer, + GL_UNSIGNED_BYTE, + this->surface->s.surface_desc.dwWidth, + this->surface->s.surface_desc.dwHeight); +} + +static void set_context_dx3(LPDIRECT3DDEVICE this) { + OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; + + OSMesaMakeCurrent(odev->ctx, odev->buffer, + GL_UNSIGNED_BYTE, + this->surface->s.surface_desc.dwWidth, + this->surface->s.surface_desc.dwHeight); +} + +static void fill_opengl_primcaps(D3DPRIMCAPS *pc) +{ + pc->dwSize = sizeof(*pc); + pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW | + D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ; + pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE | + D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST; + pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */ + pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */ + pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */ + pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */ + pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */ + pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE | + D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY; + pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST | + D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST; + pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */ + pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP; + pc->dwStippleWidth = 32; + pc->dwStippleHeight = 32; +} + +static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2) +{ + GLint maxlight; + + d1->dwSize = sizeof(*d1); + d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH + | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS; + d1->dcmColorModel = D3DCOLOR_RGB; + d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY | + D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY | + D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY; + d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS); + d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; + d1->bClipping = TRUE; + d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS); + d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT; + d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; + glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; + fill_opengl_primcaps(&(d1->dpcLineCaps)); + fill_opengl_primcaps(&(d1->dpcTriCaps)); + d1->dwDeviceRenderBitDepth = DDBD_16; + d1->dwDeviceZBufferBitDepth = DDBD_16; + d1->dwMaxBufferSize = 0; + d1->dwMinTextureWidth = 1; + d1->dwMinTextureHeight = 1; + d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */ + d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */ + d1->dwMinStippleWidth = 1; + d1->dwMinStippleHeight = 1; + d1->dwMaxStippleWidth = 32; + d1->dwMaxStippleHeight = 32; + + d2->dwSize = sizeof(*d2); + d2->dwFlags = 0; +} + +int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) { + D3DDEVICEDESC d1,d2; + + TRACE(ddraw," Enumerating OpenGL D3D device.\n"); + + fill_opengl_caps(&d1, &d2); + + return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context); +} + +int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d) +{ + if (/* Default device */ + (rguid == NULL) || + /* HAL Device */ + (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) || + /* OpenGL Device */ + (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) { + OpenGL_IDirect3DDevice2 *odev; + + const float id_mat[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2)); + odev = (OpenGL_IDirect3DDevice2 *) (*device); + (*device)->ref = 1; + (*device)->lpvtbl = &OpenGL_vtable; + (*device)->d3d = d3d; + (*device)->surface = surface; + + (*device)->viewport_list = NULL; + (*device)->current_viewport = NULL; + + (*device)->set_context = set_context; + + TRACE(ddraw, "OpenGL device created \n"); + + /* Create the OpenGL context */ + odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); + odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); + + memcpy(odev->world_mat, id_mat, 16 * sizeof(float)); + memcpy(odev->view_mat , id_mat, 16 * sizeof(float)); + memcpy(odev->proj_mat , id_mat, 16 * sizeof(float)); + + /* Initialisation */ + (*device)->set_context(*device); + glClearColor(0.0, 0.0, 0.0, 0.0); + glColor3f(1.0, 1.0, 1.0); + + return 1; + } + + /* This is not the OpenGL UID */ + return 0; +} + +/******************************************************************************* + * Common IDirect3DDevice2 + */ + +static HRESULT WINAPI IDirect3DDevice2_QueryInterface(LPDIRECT3DDEVICE2 this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DDevice2_AddRef(LPDIRECT3DDEVICE2 this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DDevice2_Release(LPDIRECT3DDEVICE2 this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + + +/*** IDirect3DDevice2 methods ***/ +static HRESULT WINAPI IDirect3DDevice2_GetCaps(LPDIRECT3DDEVICE2 this, + LPD3DDEVICEDESC lpdescsoft, + LPD3DDEVICEDESC lpdeschard) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpdescsoft, lpdeschard); + + fill_opengl_caps(lpdescsoft, lpdeschard); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SwapTextureHandles(LPDIRECT3DDEVICE2 this, + LPDIRECT3DTEXTURE2 lptex1, + LPDIRECT3DTEXTURE2 lptex2) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lptex1, lptex2); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetStats(LPDIRECT3DDEVICE2 this, + LPD3DSTATS lpstats) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpstats); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_AddViewport(LPDIRECT3DDEVICE2 this, + LPDIRECT3DVIEWPORT2 lpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + /* Adds this viewport to the viewport list */ + lpvp->next = this->viewport_list; + this->viewport_list = lpvp; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_DeleteViewport(LPDIRECT3DDEVICE2 this, + LPDIRECT3DVIEWPORT2 lpvp) +{ + LPDIRECT3DVIEWPORT2 cur, prev; + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + /* Finds this viewport in the list */ + prev = NULL; + cur = this->viewport_list; + while ((cur != NULL) && (cur != lpvp)) { + prev = cur; + cur = cur->next; + } + if (cur == NULL) + return DDERR_INVALIDOBJECT; + + /* And remove it */ + if (prev == NULL) + this->viewport_list = cur->next; + else + prev->next = cur->next; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_NextViewport(LPDIRECT3DDEVICE2 this, + LPDIRECT3DVIEWPORT2 lpvp, + LPDIRECT3DVIEWPORT2* lplpvp, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags); + + switch (dwFlags) { + case D3DNEXT_NEXT: + *lplpvp = lpvp->next; + break; + + case D3DNEXT_HEAD: + *lplpvp = this->viewport_list; + break; + + case D3DNEXT_TAIL: + lpvp = this->viewport_list; + while (lpvp->next != NULL) + lpvp = lpvp->next; + + *lplpvp = lpvp; + break; + + default: + return DDERR_INVALIDPARAMS; + } + + return DD_OK; +} + +static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb, + LPVOID context) { + DDSURFACEDESC sdesc; + LPDDPIXELFORMAT pformat; + + /* Do the texture enumeration */ + sdesc.dwSize = sizeof(DDSURFACEDESC); + sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS; + sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + pformat = &(sdesc.ddpfPixelFormat); + pformat->dwSize = sizeof(DDPIXELFORMAT); + pformat->dwFourCC = 0; + + TRACE(ddraw, "Enumerating GL_RGBA (32)\n"); + pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + pformat->x.dwRGBBitCount = 32; + pformat->y.dwRBitMask = 0x00FF0000; + pformat->z.dwGBitMask = 0x0000FF00; + pformat->xx.dwBBitMask = 0x000000FF; + pformat->xy.dwRGBAlphaBitMask = 0xFF000000; + if (cb(&sdesc, context) == 0) + return DD_OK; + + TRACE(ddraw, "Enumerating GL_RGB (24)\n"); + pformat->dwFlags = DDPF_RGB; + pformat->x.dwRGBBitCount = 24; + pformat->y.dwRBitMask = 0x00FF0000; + pformat->z.dwGBitMask = 0x0000FF00; + pformat->xx.dwBBitMask = 0x000000FF; + pformat->xy.dwRGBAlphaBitMask = 0x00000000; + if (cb(&sdesc, context) == 0) + return DD_OK; + + TRACE(ddraw, "Enumerating GL_RGB (16)\n"); + pformat->dwFlags = DDPF_RGB; + pformat->x.dwRGBBitCount = 16; + pformat->y.dwRBitMask = 0x0000F800; + pformat->z.dwGBitMask = 0x000007E0; + pformat->xx.dwBBitMask = 0x0000001F; + pformat->xy.dwRGBAlphaBitMask = 0x00000000; + if (cb(&sdesc, context) == 0) + return DD_OK; + + TRACE(ddraw, "Enumerating Paletted (8)\n"); + pformat->dwFlags = DDPF_PALETTEINDEXED8; + pformat->x.dwRGBBitCount = 8; + pformat->y.dwRBitMask = 0x00000000; + pformat->z.dwGBitMask = 0x00000000; + pformat->xx.dwBBitMask = 0x00000000; + pformat->xy.dwRGBAlphaBitMask = 0x00000000; + if (cb(&sdesc, context) == 0) + return DD_OK; + + TRACE(ddraw, "End of enumeration\n"); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DDevice2_EnumTextureFormats(LPDIRECT3DDEVICE2 this, + LPD3DENUMTEXTUREFORMATSCALLBACK cb, + LPVOID context) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, cb, context); + + return enum_texture_format_OpenGL(cb, context); +} + + + +static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this) +{ + OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; + + FIXME(ddraw, "(%p)->(): stub\n", this); + + /* Here, we should get the DDraw surface and 'copy it' to the + OpenGL surface.... */ + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_EndScene(LPDIRECT3DDEVICE2 this) +{ + OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; + LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface; + DDSURFACEDESC sdesc; + int x,y; + unsigned char *src; + unsigned short *dest; + + FIXME(ddraw, "(%p)->(): stub\n", this); + + /* Here we copy back the OpenGL scene to the the DDraw surface */ + /* First, lock the surface */ + surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0); + + /* The copy the OpenGL buffer to this surface */ + + /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal. + I am currently working on a set of patches for Mesa to have OSMesa support + 16 bpp surfaces => we will able to render directly onto the surface, no + need to do a bpp conversion */ + dest = (unsigned short *) sdesc.y.lpSurface; + src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1)); + for (y = 0; y < sdesc.dwHeight; y++) { + unsigned char *lsrc = src; + + for (x = 0; x < sdesc.dwWidth ; x++) { + unsigned char r = *lsrc++; + unsigned char g = *lsrc++; + unsigned char b = *lsrc++; + lsrc++; /* Alpha */ + *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); + + dest++; + } + + src -= 4 * sdesc.dwWidth; + } + + /* Unlock the surface */ + surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetDirect3D(LPDIRECT3DDEVICE2 this, LPDIRECT3D2 *lpd3d2) +{ + TRACE(ddraw, "(%p)->(%p): stub\n", this, lpd3d2); + + *lpd3d2 = this->d3d; + + return DD_OK; +} + + + +/*** DrawPrimitive API ***/ +static HRESULT WINAPI IDirect3DDevice2_SetCurrentViewport(LPDIRECT3DDEVICE2 this, + LPDIRECT3DVIEWPORT2 lpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + /* Should check if the viewport was added or not */ + + /* Set this viewport as the current viewport */ + this->current_viewport = lpvp; + + /* Activate this viewport */ + lpvp->device.active_device2 = this; + lpvp->activate(lpvp); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetCurrentViewport(LPDIRECT3DDEVICE2 this, + LPDIRECT3DVIEWPORT2 *lplpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpvp); + + /* Returns the current viewport */ + *lplpvp = this->current_viewport; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SetRenderTarget(LPDIRECT3DDEVICE2 this, + LPDIRECTDRAWSURFACE lpdds, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", this, lpdds, dwFlags); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetRenderTarget(LPDIRECT3DDEVICE2 this, + LPDIRECTDRAWSURFACE *lplpdds) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpdds); + + /* Returns the current rendering target (the surface on wich we render) */ + *lplpdds = this->surface; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_Begin(LPDIRECT3DDEVICE2 this, + D3DPRIMITIVETYPE d3dp, + D3DVERTEXTYPE d3dv, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", this, d3dp, d3dv, dwFlags); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_BeginIndexed(LPDIRECT3DDEVICE2 this, + D3DPRIMITIVETYPE d3dp, + D3DVERTEXTYPE d3dv, + LPVOID lpvert, + DWORD numvert, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvert, numvert, dwFlags); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_Vertex(LPDIRECT3DDEVICE2 this, + LPVOID lpvert) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvert); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_Index(LPDIRECT3DDEVICE2 this, + WORD index) +{ + FIXME(ddraw, "(%p)->(%d): stub\n", this, index); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_End(LPDIRECT3DDEVICE2 this, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%08lx): stub\n", this, dwFlags); + + return DD_OK; +} + + + + +static HRESULT WINAPI IDirect3DDevice2_GetRenderState(LPDIRECT3DDEVICE2 this, + D3DRENDERSTATETYPE d3drs, + LPDWORD lprstate) +{ + FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3drs, lprstate); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SetRenderState(LPDIRECT3DDEVICE2 this, + D3DRENDERSTATETYPE dwRenderStateType, + DWORD dwRenderState) +{ + TRACE(ddraw, "(%p)->(%d,%ld)\n", this, dwRenderStateType, dwRenderState); + + /* Call the render state functions */ + set_render_state(dwRenderStateType, dwRenderState); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetLightState(LPDIRECT3DDEVICE2 this, + D3DLIGHTSTATETYPE d3dls, + LPDWORD lplstate) +{ + FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dls, lplstate); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SetLightState(LPDIRECT3DDEVICE2 this, + D3DLIGHTSTATETYPE dwLightStateType, + DWORD dwLightState) +{ + FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", this, dwLightStateType, dwLightState); + + switch (dwLightStateType) { + case D3DLIGHTSTATE_MATERIAL: { /* 1 */ + LPDIRECT3DMATERIAL2 mat = (LPDIRECT3DMATERIAL2) dwLightState; + + if (mat != NULL) { + mat->activate(mat); + } else { + TRACE(ddraw, "Zoups !!!\n"); + } + } break; + + case D3DLIGHTSTATE_AMBIENT: { /* 2 */ + float light[4]; + + light[0] = ((dwLightState >> 16) & 0xFF) / 255.0; + light[1] = ((dwLightState >> 8) & 0xFF) / 255.0; + light[2] = ((dwLightState >> 0) & 0xFF) / 255.0; + light[3] = 1.0; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light); + } break; + + case D3DLIGHTSTATE_COLORMODEL: /* 3 */ + break; + + case D3DLIGHTSTATE_FOGMODE: /* 4 */ + break; + + case D3DLIGHTSTATE_FOGSTART: /* 5 */ + break; + + case D3DLIGHTSTATE_FOGEND: /* 6 */ + break; + + case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ + break; + + default: + TRACE(ddraw, "Unexpected Light State Type\n"); + return DDERR_INVALIDPARAMS; + } + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SetTransform(LPDIRECT3DDEVICE2 this, + D3DTRANSFORMSTATETYPE d3dts, + LPD3DMATRIX lpmatrix) +{ + OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; + + FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix); + + /* Using a trial and failure approach, I found that the order of + Direct3D transformations that works best is : + + ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord + + As OpenGL uses only two matrices, I combined PROJECTION and VIEW into + OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW. + + If anyone has a good explanation of the three different matrices in + the SDK online documentation, feel free to point it to me. For example, + which matrices transform lights ? In OpenGL only the PROJECTION matrix + transform the lights, not the MODELVIEW. Using the matrix names, I + supposed that PROJECTION and VIEW (all 'camera' related names) do + transform lights, but WORLD do not. It may be wrong though... */ + + /* After reading through both OpenGL and Direct3D documentations, I + thought that D3D matrices were written in 'line major mode' transposed + from OpenGL's 'column major mode'. But I found out that a simple memcpy + works fine to transfer one matrix format to the other (it did not work + when transposing).... + + So : + 1) are the documentations wrong + 2) does the matrix work even if they are not read correctly + 3) is Mesa's implementation of OpenGL not compliant regarding Matrix + loading using glLoadMatrix ? + + Anyway, I always use 'conv_mat' to transfer the matrices from one format + to the other so that if I ever find out that I need to transpose them, I + will able to do it quickly, only by changing the macro conv_mat. */ + + switch (d3dts) { + case D3DTRANSFORMSTATE_WORLD: { + conv_mat(lpmatrix, odev->world_mat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((float *) &(odev->world_mat)); + } break; + + case D3DTRANSFORMSTATE_VIEW: { + conv_mat(lpmatrix, odev->view_mat); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float *) &(odev->proj_mat)); + glMultMatrixf((float *) &(odev->view_mat)); + } break; + + case D3DTRANSFORMSTATE_PROJECTION: { + conv_mat(lpmatrix, odev->proj_mat); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float *) &(odev->proj_mat)); + glMultMatrixf((float *) &(odev->view_mat)); + } break; + + default: + break; + } + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetTransform(LPDIRECT3DDEVICE2 this, + D3DTRANSFORMSTATETYPE d3dts, + LPD3DMATRIX lpmatrix) +{ + FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_MultiplyTransform(LPDIRECT3DDEVICE2 this, + D3DTRANSFORMSTATETYPE d3dts, + LPD3DMATRIX lpmatrix) +{ + FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_DrawPrimitive(LPDIRECT3DDEVICE2 this, + D3DPRIMITIVETYPE d3dp, + D3DVERTEXTYPE d3dv, + LPVOID lpvertex, + DWORD vertcount, + DWORD dwFlags) +{ + int vx_index; + + TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, dwFlags); + + /* Puts GL in the correct lighting mode */ + switch (d3dv) { + case D3DVT_VERTEX: + TRACE(ddraw, "Standard Vertex\n"); + glEnable(GL_LIGHTING); + break; + + case D3DVT_LVERTEX: + TRACE(ddraw, "Lighted Vertex\n"); + glDisable(GL_LIGHTING); + break; + + case D3DVT_TLVERTEX: { + GLdouble height, width; + + TRACE(ddraw, "Transformed - Lighted Vertex\n"); + /* First, disable lighting */ + glDisable(GL_LIGHTING); + + /* Then do not put any transformation matrixes */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if (this->current_viewport == NULL) { + ERR(ddraw, "No current viewport !\n"); + /* Using standard values */ + height = 640.0; + width = 480.0; + } else { + if (this->current_viewport->use_vp2) { + height = (GLdouble) this->current_viewport->viewport.vp2.dwHeight; + width = (GLdouble) this->current_viewport->viewport.vp2.dwWidth; + } else { + height = (GLdouble) this->current_viewport->viewport.vp1.dwHeight; + width = (GLdouble) this->current_viewport->viewport.vp1.dwWidth; + } + } + + glOrtho(0.0, width, height, 0.0, 1.5, -1.5); + } break; + + default: + TRACE(ddraw, "Unhandled vertex type\n"); + break; + } + + switch (d3dp) { + case D3DPT_POINTLIST: + TRACE(ddraw, "Start POINTS\n"); + glBegin(GL_POINTS); + break; + + case D3DPT_LINELIST: + TRACE(ddraw, "Start LINES\n"); + glBegin(GL_LINES); + break; + + case D3DPT_LINESTRIP: + TRACE(ddraw, "Start LINE_STRIP\n"); + glBegin(GL_LINE_STRIP); + break; + + case D3DPT_TRIANGLELIST: + TRACE(ddraw, "Start TRIANGLES\n"); + glBegin(GL_TRIANGLES); + break; + + case D3DPT_TRIANGLESTRIP: + TRACE(ddraw, "Start TRIANGLE_STRIP\n"); + glBegin(GL_TRIANGLE_STRIP); + break; + + case D3DPT_TRIANGLEFAN: + TRACE(ddraw, "Start TRIANGLE_FAN\n"); + glBegin(GL_TRIANGLE_FAN); + break; + + default: + TRACE(ddraw, "Unhandled primitive\n"); + break; + } + + /* Draw the primitives */ + for (vx_index = 0; vx_index < vertcount; vx_index++) { + switch (d3dv) { + case D3DVT_VERTEX: { + D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + vx_index; + + glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); + glVertex3f(vx->x.x, vx->y.y, vx->z.z); + TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); + } break; + + case D3DVT_LVERTEX: { + D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + vx_index; + DWORD col = vx->c.color; + + glColor3f(((col >> 16) & 0xFF) / 255.0, + ((col >> 8) & 0xFF) / 255.0, + ((col >> 0) & 0xFF) / 255.0); + glVertex3f(vx->x.x, vx->y.y, vx->z.z); + TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", + vx->x.x, vx->y.y, vx->z.z, + ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); + } break; + + case D3DVT_TLVERTEX: { + D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + vx_index; + DWORD col = vx->c.color; + + glColor3f(((col >> 16) & 0xFF) / 255.0, + ((col >> 8) & 0xFF) / 255.0, + ((col >> 0) & 0xFF) / 255.0); + + glVertex3f(vx->x.sx, vx->y.sy, vx->z.sz); + TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx)\n", + vx->x.sx, vx->y.sy, vx->z.sz, + ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); + } break; + + default: + TRACE(ddraw, "Unhandled vertex type\n"); + break; + } + } + + glEnd(); + TRACE(ddraw, "End\n"); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 this, + D3DPRIMITIVETYPE d3dp, + D3DVERTEXTYPE d3dv, + LPVOID lpvertex, + DWORD vertcount, + LPWORD lpindexes, + DWORD indexcount, + DWORD dwFlags) +{ + int vx_index; + + TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags); + + /* Puts GL in the correct lighting mode */ + switch (d3dv) { + case D3DVT_VERTEX: + glEnable(GL_LIGHTING); + break; + + case D3DVT_LVERTEX: + case D3DVT_TLVERTEX: + glDisable(GL_LIGHTING); + break; + + default: + break; + } + + switch (d3dp) { + case D3DPT_LINESTRIP: + TRACE(ddraw, "Start LINE_STRIP\n"); + glBegin(GL_LINE_STRIP); + break; + + case D3DPT_TRIANGLELIST: + TRACE(ddraw, "Start TRIANGLES\n"); + glBegin(GL_TRIANGLES); + break; + + default: + break; + } + + /* Draw the primitives */ + for (vx_index = 0; vx_index < indexcount; vx_index++) { + switch (d3dv) { + case D3DVT_VERTEX: { + D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + lpindexes[vx_index]; + + glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); + glVertex3f(vx->x.x, vx->y.y, vx->z.z); + TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); + } break; + + case D3DVT_LVERTEX: { + D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + lpindexes[vx_index]; + DWORD col = vx->c.color; + + glColor3f(((col >> 16) & 0xFF) / 255.0, + ((col >> 8) & 0xFF) / 255.0, + ((col >> 0) & 0xFF) / 255.0); + glVertex3f(vx->x.x, vx->y.y, vx->z.z); + TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", + vx->x.x, vx->y.y, vx->z.z, + ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); + } break; + + default: + break; + } + } + + glEnd(); + TRACE(ddraw, "End\n"); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_SetClipStatus(LPDIRECT3DDEVICE2 this, + LPD3DCLIPSTATUS lpcs) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs); + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice2_GetClipStatus(LPDIRECT3DDEVICE2 this, + LPD3DCLIPSTATUS lpcs) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs); + + return DD_OK; +} + + + +/******************************************************************************* + * OpenGL-specific IDirect3DDevice2 + */ + +/******************************************************************************* + * OpenGL-specific VTable + */ + +static IDirect3DDevice2_VTable OpenGL_vtable = { + IDirect3DDevice2_QueryInterface, + IDirect3DDevice2_AddRef, + IDirect3DDevice2_Release, + /*** IDirect3DDevice2 methods ***/ + IDirect3DDevice2_GetCaps, + IDirect3DDevice2_SwapTextureHandles, + IDirect3DDevice2_GetStats, + IDirect3DDevice2_AddViewport, + IDirect3DDevice2_DeleteViewport, + IDirect3DDevice2_NextViewport, + IDirect3DDevice2_EnumTextureFormats, + IDirect3DDevice2_BeginScene, + IDirect3DDevice2_EndScene, + IDirect3DDevice2_GetDirect3D, + + /*** DrawPrimitive API ***/ + IDirect3DDevice2_SetCurrentViewport, + IDirect3DDevice2_GetCurrentViewport, + + IDirect3DDevice2_SetRenderTarget, + IDirect3DDevice2_GetRenderTarget, + + IDirect3DDevice2_Begin, + IDirect3DDevice2_BeginIndexed, + IDirect3DDevice2_Vertex, + IDirect3DDevice2_Index, + IDirect3DDevice2_End, + + IDirect3DDevice2_GetRenderState, + IDirect3DDevice2_SetRenderState, + IDirect3DDevice2_GetLightState, + IDirect3DDevice2_SetLightState, + IDirect3DDevice2_SetTransform, + IDirect3DDevice2_GetTransform, + IDirect3DDevice2_MultiplyTransform, + + IDirect3DDevice2_DrawPrimitive, + IDirect3DDevice2_DrawIndexedPrimitive, + + IDirect3DDevice2_SetClipStatus, + IDirect3DDevice2_GetClipStatus, +}; + +/******************************************************************************* + * Direct3DDevice + */ +int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) { + D3DDEVICEDESC d1,d2; + + TRACE(ddraw," Enumerating OpenGL D3D device.\n"); + + fill_opengl_caps(&d1, &d2); + + return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context); +} + +float id_mat[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +}; + +int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device) +{ + if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) { + OpenGL_IDirect3DDevice *odev; + + *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice)); + odev = (OpenGL_IDirect3DDevice *) (*device); + (*device)->ref = 1; + (*device)->lpvtbl = &OpenGL_vtable_dx3; + (*device)->d3d = NULL; + (*device)->surface = surface; + + (*device)->viewport_list = NULL; + (*device)->current_viewport = NULL; + + (*device)->set_context = set_context_dx3; + + TRACE(ddraw, "OpenGL device created \n"); + + /* Create the OpenGL context */ + odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); + odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); + + odev->world_mat = (LPD3DMATRIX) &id_mat; + odev->view_mat = (LPD3DMATRIX) &id_mat; + odev->proj_mat = (LPD3DMATRIX) &id_mat; + + /* Initialisation */ + (*device)->set_context(*device); + glClearColor(0.0, 0.0, 0.0, 0.0); + glColor3f(1.0, 1.0, 1.0); + + return 1; + } + + /* This is not the OpenGL UID */ + return DD_OK; +} + + +/******************************************************************************* + * Direct3DDevice + */ +static HRESULT WINAPI IDirect3DDevice_QueryInterface(LPDIRECT3DDEVICE this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DDevice_AddRef(LPDIRECT3DDEVICE this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DDevice_Release(LPDIRECT3DDEVICE this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +static HRESULT WINAPI IDirect3DDevice_Initialize(LPDIRECT3DDEVICE this, + LPDIRECT3D lpd3d, + LPGUID lpGUID, + LPD3DDEVICEDESC lpd3ddvdesc) +{ + TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", this, lpd3d,lpGUID, lpd3ddvdesc); + + return DDERR_ALREADYINITIALIZED; +} + + +static HRESULT WINAPI IDirect3DDevice_GetCaps(LPDIRECT3DDEVICE this, + LPD3DDEVICEDESC lpD3DHWDevDesc, + LPD3DDEVICEDESC lpD3DSWDevDesc) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DHWDevDesc, lpD3DSWDevDesc); + + fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_SwapTextureHandles(LPDIRECT3DDEVICE this, + LPDIRECT3DTEXTURE lpD3DTex1, + LPDIRECT3DTEXTURE lpD3DTex2) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DTex1, lpD3DTex2); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DDevice_CreateExecuteBuffer(LPDIRECT3DDEVICE this, + LPD3DEXECUTEBUFFERDESC lpDesc, + LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, + IUnknown *pUnkOuter) +{ + TRACE(ddraw, "(%p)->(%p,%p,%p)\n", this, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter); + + *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(this, lpDesc); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_GetStats(LPDIRECT3DDEVICE this, + LPD3DSTATS lpD3DStats) +{ + TRACE(ddraw, "(%p)->(%p): stub\n", this, lpD3DStats); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_Execute(LPDIRECT3DDEVICE this, + LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, + LPDIRECT3DVIEWPORT lpDirect3DViewport, + DWORD dwFlags) +{ + TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags); + + /* Put this as the default context */ + + /* Execute... */ + lpDirect3DExecuteBuffer->execute(lpDirect3DExecuteBuffer, this, lpDirect3DViewport); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DDevice_AddViewport(LPDIRECT3DDEVICE this, + LPDIRECT3DVIEWPORT lpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + /* Adds this viewport to the viewport list */ + lpvp->next = this->viewport_list; + this->viewport_list = lpvp; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice_DeleteViewport(LPDIRECT3DDEVICE this, + LPDIRECT3DVIEWPORT lpvp) +{ + LPDIRECT3DVIEWPORT cur, prev; + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + /* Finds this viewport in the list */ + prev = NULL; + cur = this->viewport_list; + while ((cur != NULL) && (cur != lpvp)) { + prev = cur; + cur = cur->next; + } + if (cur == NULL) + return DDERR_INVALIDOBJECT; + + /* And remove it */ + if (prev == NULL) + this->viewport_list = cur->next; + else + prev->next = cur->next; + + return DD_OK; +} + + + +static HRESULT WINAPI IDirect3DDevice_NextViewport(LPDIRECT3DDEVICE this, + LPDIRECT3DVIEWPORT lpvp, + LPDIRECT3DVIEWPORT* lplpvp, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags); + + switch (dwFlags) { + case D3DNEXT_NEXT: + *lplpvp = lpvp->next; + break; + + case D3DNEXT_HEAD: + *lplpvp = this->viewport_list; + break; + + case D3DNEXT_TAIL: + lpvp = this->viewport_list; + while (lpvp->next != NULL) + lpvp = lpvp->next; + + *lplpvp = lpvp; + break; + + default: + return DDERR_INVALIDPARAMS; + } + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DDevice_Pick(LPDIRECT3DDEVICE this, + LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, + LPDIRECT3DVIEWPORT lpDirect3DViewport, + DWORD dwFlags, + LPD3DRECT lpRect) +{ + TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, + dwFlags, lpRect); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_GetPickRecords(LPDIRECT3DDEVICE this, + LPDWORD lpCount, + LPD3DPICKRECORD lpD3DPickRec) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpCount, lpD3DPickRec); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_EnumTextureFormats(LPDIRECT3DDEVICE this, + LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc, + LPVOID lpArg) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpd3dEnumTextureProc, lpArg); + + return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg); +} + + +static HRESULT WINAPI IDirect3DDevice_CreateMatrix(LPDIRECT3DDEVICE this, + LPD3DMATRIXHANDLE lpD3DMatHandle) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DMatHandle); + + *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX)); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_SetMatrix(LPDIRECT3DDEVICE this, + D3DMATRIXHANDLE d3dMatHandle, + const LPD3DMATRIX lpD3DMatrix) +{ + TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix); + + dump_mat(lpD3DMatrix); + *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix; + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_GetMatrix(LPDIRECT3DDEVICE this, + D3DMATRIXHANDLE D3DMatHandle, + LPD3DMATRIX lpD3DMatrix) +{ + TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, D3DMatHandle, lpD3DMatrix); + + *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_DeleteMatrix(LPDIRECT3DDEVICE this, + D3DMATRIXHANDLE d3dMatHandle) +{ + TRACE(ddraw, "(%p)->(%08lx)\n", this, d3dMatHandle); + + HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this) +{ + OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; + + FIXME(ddraw, "(%p)->(): stub\n", this); + + /* We get the pointer to the surface (should be done on flip) */ + /* odev->zb->pbuf = this->surface->s.surface_desc.y.lpSurface; */ + + return DD_OK; +} + + +/* This is for the moment copy-pasted from IDirect3DDevice2... + Will make a common function ... */ +static HRESULT WINAPI IDirect3DDevice_EndScene(LPDIRECT3DDEVICE this) +{ + OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; + LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface; + DDSURFACEDESC sdesc; + int x,y; + unsigned char *src; + unsigned short *dest; + + FIXME(ddraw, "(%p)->(): stub\n", this); + + /* Here we copy back the OpenGL scene to the the DDraw surface */ + /* First, lock the surface */ + surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0); + + /* The copy the OpenGL buffer to this surface */ + + /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal. + I am currently working on a set of patches for Mesa to have OSMesa support + 16 bpp surfaces => we will able to render directly onto the surface, no + need to do a bpp conversion */ + dest = (unsigned short *) sdesc.y.lpSurface; + src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1)); + for (y = 0; y < sdesc.dwHeight; y++) { + unsigned char *lsrc = src; + + for (x = 0; x < sdesc.dwWidth ; x++) { + unsigned char r = *lsrc++; + unsigned char g = *lsrc++; + unsigned char b = *lsrc++; + lsrc++; /* Alpha */ + *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); + + dest++; + } + + src -= 4 * sdesc.dwWidth; + } + + /* Unlock the surface */ + surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface); + + return DD_OK; +} + + +static HRESULT WINAPI IDirect3DDevice_GetDirect3D(LPDIRECT3DDEVICE this, + LPDIRECT3D *lpDirect3D) +{ + TRACE(ddraw, "(%p)->(%p): stub\n", this, lpDirect3D); + + return DD_OK; +} + + + +/******************************************************************************* + * Direct3DDevice VTable + */ +static IDirect3DDevice_VTable OpenGL_vtable_dx3 = { + IDirect3DDevice_QueryInterface, + IDirect3DDevice_AddRef, + IDirect3DDevice_Release, + IDirect3DDevice_Initialize, + IDirect3DDevice_GetCaps, + IDirect3DDevice_SwapTextureHandles, + IDirect3DDevice_CreateExecuteBuffer, + IDirect3DDevice_GetStats, + IDirect3DDevice_Execute, + IDirect3DDevice_AddViewport, + IDirect3DDevice_DeleteViewport, + IDirect3DDevice_NextViewport, + IDirect3DDevice_Pick, + IDirect3DDevice_GetPickRecords, + IDirect3DDevice_EnumTextureFormats, + IDirect3DDevice_CreateMatrix, + IDirect3DDevice_SetMatrix, + IDirect3DDevice_GetMatrix, + IDirect3DDevice_DeleteMatrix, + IDirect3DDevice_BeginScene, + IDirect3DDevice_EndScene, + IDirect3DDevice_GetDirect3D, +}; + +#else /* HAVE_MESAGL */ + +int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) { + return 0; +} + +int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d) +{ + return 0; +} + +int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) { + return 0; +} + +int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device) +{ + return 0; +} + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3dexecutebuffer.c b/graphics/d3dexecutebuffer.c new file mode 100644 index 00000000000..4fe4f041b28 --- /dev/null +++ b/graphics/d3dexecutebuffer.c @@ -0,0 +1,578 @@ +/* Direct3D ExecuteBuffer + (c) 1998 Lionel ULMER + + This files contains the implementation of Direct3DExecuteBuffer. */ + + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static IDirect3DExecuteBuffer_VTable executebuffer_vtable; + +/******************************************************************************* + * ExecuteBuffer static functions + */ +void _dump_d3dstatus(LPD3DSTATUS lpStatus) { + +} + +void _dump_executedata(LPD3DEXECUTEDATA lpData) { + DUMP("dwSize : %ld\n", lpData->dwSize); + DUMP("Vertex Offset : %ld Count : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount); + DUMP("Instruction Offset : %ld Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength); + DUMP("HVertex Offset : %ld\n", lpData->dwHVertexOffset); + _dump_d3dstatus(&(lpData->dsStatus)); +} + +#define DO_VERTEX(index) \ + glNormal3f(tvert[index].nx.nx, \ + tvert[index].ny.ny, \ + tvert[index].nz.nz); \ + glVertex3f(tvert[index].x.x, \ + tvert[index].y.y, \ + tvert[index].z.z); + + +static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff, + LPDIRECT3DDEVICE dev, + LPDIRECT3DVIEWPORT vp) { + DWORD bs = lpBuff->desc.dwBufferSize; + DWORD vs = lpBuff->data.dwVertexOffset; + DWORD vc = lpBuff->data.dwVertexCount; + DWORD is = lpBuff->data.dwInstructionOffset; + DWORD il = lpBuff->data.dwInstructionLength; + + unsigned char *instr = lpBuff->desc.lpData + is; + LPD3DVERTEX vert = (LPD3DVERTEX) (lpBuff->desc.lpData + vs); + LPD3DVERTEX tvert = lpBuff->vertex_data; + OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) dev; + + TRACE(ddraw, "ExecuteData : \n"); + _dump_executedata(&(lpBuff->data)); + + while (1) { + LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr; + BYTE size; + WORD count; + + count = current->wCount; + size = current->bSize; + instr += sizeof(D3DINSTRUCTION); + + switch (current->bOpcode) { + case D3DOP_POINT: { + TRACE(ddraw, "POINT-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_LINE: { + TRACE(ddraw, "LINE-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_TRIANGLE: { + int i; + TRACE(ddraw, "TRIANGLE (%d)\n", count); + + /* Use given matrixes */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); /* The model transformation was done during the + transformation phase */ + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float *) odev->proj_mat); + glMultMatrixf((float *) odev->view_mat); + + for (i = 0; i < count; i++) { + LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr; + + TRACE(ddraw, " v1: %d v2: %d v3: %d\n", + ci->v1.v1, ci->v2.v2, ci->v3.v3); + TRACE(ddraw, " Flags : "); + if (TRACE_ON(ddraw)) { + /* Wireframe */ + if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) + DUMP("EDGEENABLE1 "); + if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2) + DUMP("EDGEENABLE2 "); + if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) + DUMP("EDGEENABLE3 "); + + /* Strips / Fans */ + if (ci->wFlags == D3DTRIFLAG_EVEN) + DUMP("EVEN "); + if (ci->wFlags == D3DTRIFLAG_ODD) + DUMP("ODD "); + if (ci->wFlags == D3DTRIFLAG_START) + DUMP("START "); + if ((ci->wFlags > 0) && (ci->wFlags < 30)) + DUMP("STARTFLAT(%d) ", ci->wFlags); + DUMP("\n"); + } + + glBegin(GL_TRIANGLES); { + DO_VERTEX(ci->v1.v1); + DO_VERTEX(ci->v2.v2); + DO_VERTEX(ci->v3.v3); + } glEnd(); + + instr += size; + } + } break; + + case D3DOP_MATRIXLOAD: { + TRACE(ddraw, "MATRIXLOAD-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_MATRIXMULTIPLY: { + int i; + TRACE(ddraw, "MATRIXMULTIPLY (%d)\n", count); + + for (i = 0; i < count; i++) { + LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr; + LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix; + LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1; + LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2; + + TRACE(ddraw, " Dest : %08lx Src1 : %08lx Src2 : %08lx\n", + ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2); + + /* Do the multiplication.. + As I am VERY lazy, I let OpenGL do the multiplication for me */ + glMatrixMode(GL_PROJECTION); + /* Save the current matrix */ + glPushMatrix(); + /* Load Matrix one and do the multiplication */ + glLoadMatrixf((float *) ci->hSrcMatrix1); + glMultMatrixf((float *) ci->hSrcMatrix2); + glGetFloatv(GL_PROJECTION_MATRIX, (float *) ci->hDestMatrix); + /* Restore the current matrix */ + glPopMatrix(); + + instr += size; + } + } break; + + case D3DOP_STATETRANSFORM: { + int i; + TRACE(ddraw, "STATETRANSFORM (%d)\n", count); + + for (i = 0; i < count; i++) { + LPD3DSTATE ci = (LPD3DSTATE) instr; + + /* Handle the state transform */ + switch (ci->t.dtstTransformStateType) { + case D3DTRANSFORMSTATE_WORLD: { + TRACE(ddraw, " WORLD (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]); + odev->world_mat = (D3DMATRIX*) ci->v.dwArg[0]; + } break; + + case D3DTRANSFORMSTATE_VIEW: { + TRACE(ddraw, " VIEW (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]); + odev->view_mat = (D3DMATRIX*) ci->v.dwArg[0]; + } break; + + case D3DTRANSFORMSTATE_PROJECTION: { + TRACE(ddraw, " PROJECTION (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]); + odev->proj_mat = (D3DMATRIX*) ci->v.dwArg[0]; + } break; + + default: + ERR(ddraw, " Unhandled state transformation !! (%d)\n", (int) ci->t.dtstTransformStateType); + break; + + } + + instr += size; + } + } break; + + case D3DOP_STATELIGHT: { + int i; + TRACE(ddraw, "STATELIGHT (%d)\n", count); + + for (i = 0; i < count; i++) { + LPD3DSTATE ci = (LPD3DSTATE) instr; + + /* Handle the state transform */ + switch (ci->t.dlstLightStateType) { + case D3DLIGHTSTATE_MATERIAL: { + LPDIRECT3DMATERIAL mat = (LPDIRECT3DMATERIAL) ci->v.dwArg[0]; + TRACE(ddraw, " MATERIAL\n"); + + if (mat != NULL) { + mat->activate(mat); + } else { + TRACE(ddraw, " bad Material Handle\n"); + } + } break ; + + case D3DLIGHTSTATE_AMBIENT: { + float light[4]; + DWORD dwLightState = ci->v.dwArg[0]; + TRACE(ddraw, " AMBIENT\n"); + + light[0] = ((dwLightState >> 16) & 0xFF) / 255.0; + light[1] = ((dwLightState >> 8) & 0xFF) / 255.0; + light[2] = ((dwLightState >> 0) & 0xFF) / 255.0; + light[3] = 1.0; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light); + + TRACE(ddraw, " R:%02lx G:%02lx B:%02lx A:%02lx\n", + ((dwLightState >> 16) & 0xFF), + ((dwLightState >> 8) & 0xFF), + ((dwLightState >> 0) & 0xFF), + ((dwLightState >> 24) & 0xFF)); + } break ; + + case D3DLIGHTSTATE_COLORMODEL: { + TRACE(ddraw, " COLORMODEL\n"); + } break ; + + case D3DLIGHTSTATE_FOGMODE: { + TRACE(ddraw, " FOGMODE\n"); + } break ; + + case D3DLIGHTSTATE_FOGSTART: { + TRACE(ddraw, " FOGSTART\n"); + } break ; + + case D3DLIGHTSTATE_FOGEND: { + TRACE(ddraw, " FOGEND\n"); + } break ; + + case D3DLIGHTSTATE_FOGDENSITY: { + TRACE(ddraw, " FOGDENSITY\n"); + } break ; + + default: + ERR(ddraw, " Unhandled light state !! (%d)\n", (int) ci->t.dlstLightStateType); + break; + } + instr += size; + } + } break; + + case D3DOP_STATERENDER: { + int i; + TRACE(ddraw, "STATERENDER (%d)\n", count); + + for (i = 0; i < count; i++) { + LPD3DSTATE ci = (LPD3DSTATE) instr; + + /* Handle the state transform */ + set_render_state(ci->t.drstRenderStateType, ci->v.dwArg[0]); + + instr += size; + } + } break; + + case D3DOP_PROCESSVERTICES: { + int i; + TRACE(ddraw, "PROCESSVERTICES (%d)\n", count); + + for (i = 0; i < count; i++) { + LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr; + + TRACE(ddraw, " Start : %d Dest : %d Count : %ld\n", + ci->wStart, ci->wDest, ci->dwCount); + TRACE(ddraw, " Flags : "); + if (TRACE_ON(ddraw)) { + if (ci->dwFlags & D3DPROCESSVERTICES_COPY) + DUMP("COPY "); + if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) + DUMP("NOCOLOR "); + if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK) + DUMP("OPMASK "); + if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM) + DUMP("TRANSFORM "); + if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) + DUMP("TRANSFORMLIGHT "); + if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS) + DUMP("UPDATEEXTENTS "); + DUMP("\n"); + } + + /* This is where doing Direct3D on top on OpenGL is quite difficult. + This method transforms a set of vertices using the CURRENT state + (lighting, projection, ...) but does not rasterize them. + They will oinly be put on screen later (with the POINT / LINE and + TRIANGLE op-codes). The problem is that you can have a triangle + with each point having been transformed using another state... + + In this implementation, I will emulate only ONE thing : each + vertex can have its own "WORLD" transformation (this is used in the + TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the + execute buffer use the same state. + + If I find applications that change other states, I will try to do a + more 'fine-tuned' state emulation (but I may become quite tricky if + it changes a light position in the middle of a triangle). + + In this case, a 'direct' approach (i.e. without using OpenGL, but + writing our own 3D rasterizer) would be easier. */ + + /* The current method (with the hypothesis that only the WORLD matrix + will change between two points) is like this : + - I transform 'manually' all the vertices with the current WORLD + matrix and store them in the vertex buffer + - during the rasterization phase, the WORLD matrix will be set to + the Identity matrix */ + + /* Enough for the moment */ + if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) { + /* Enable lighting, so that when the rasterization will take place, + the correct LIGHTING state is active. */ + glEnable(GL_LIGHTING); + + /* */ + } + + instr += size; + } + } break; + + case D3DOP_TEXTURELOAD: { + TRACE(ddraw, "TEXTURELOAD-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_EXIT: { + TRACE(ddraw, "EXIT (%d)\n", count); + /* We did this instruction */ + instr += size; + /* Exit this loop */ + goto end_of_buffer; + } break; + + case D3DOP_BRANCHFORWARD: { + TRACE(ddraw, "BRANCHFORWARD-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_SPAN: { + TRACE(ddraw, "SPAN-s (%d)\n", count); + + instr += count * size; + } break; + + case D3DOP_SETSTATUS: { + TRACE(ddraw, "SETSTATUS-s (%d)\n", count); + + instr += count * size; + } break; + + default: + ERR(ddraw, "Unhandled OpCode !!!\n"); + /* Try to save ... */ + instr += count * size; + break; + } + } + + end_of_buffer: +} + +/******************************************************************************* + * ExecuteBuffer Creation functions + */ +LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(LPDIRECT3DDEVICE d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc) +{ + LPDIRECT3DEXECUTEBUFFER eb; + + eb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DExecuteBuffer)); + eb->ref = 1; + eb->lpvtbl = &executebuffer_vtable; + eb->d3ddev = d3ddev; + + /* Initializes memory */ + eb->desc = *lpDesc; + + /* No buffer given */ + if (!(eb->desc.dwFlags & D3DDEB_LPDATA)) + eb->desc.lpData = NULL; + + /* No buffer size given */ + if (!(lpDesc->dwFlags & D3DDEB_BUFSIZE)) + eb->desc.dwBufferSize = 0; + + /* Create buffer if asked */ + if ((eb->desc.lpData == NULL) && (eb->desc.dwBufferSize > 0)) { + eb->need_free = TRUE; + eb->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,eb->desc.dwBufferSize); + } else { + eb->need_free = FALSE; + } + + /* No vertices for the moment */ + eb->vertex_data = NULL; + + eb->desc.dwFlags |= D3DDEB_LPDATA; + + eb->execute = execute; + + return eb; +} + +/******************************************************************************* + * IDirect3DLight methods + */ + +static HRESULT WINAPI IDirect3DExecuteBuffer_QueryInterface(LPDIRECT3DEXECUTEBUFFER this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DExecuteBuffer_AddRef(LPDIRECT3DEXECUTEBUFFER this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DExecuteBuffer_Release(LPDIRECT3DEXECUTEBUFFER this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + if ((this->desc.lpData != NULL) && this->need_free) + HeapFree(GetProcessHeap(),0,this->desc.lpData); + + if (this->vertex_data != NULL) + HeapFree(GetProcessHeap(),0,this->vertex_data); + + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_Initialize(LPDIRECT3DEXECUTEBUFFER this, + LPDIRECT3DDEVICE lpDirect3DDevice, + LPD3DEXECUTEBUFFERDESC lpDesc) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpDirect3DDevice, lpDesc); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_Lock(LPDIRECT3DEXECUTEBUFFER this, + LPD3DEXECUTEBUFFERDESC lpDesc) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpDesc); + + /* Copies the buffer description */ + *lpDesc = this->desc; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_Unlock(LPDIRECT3DEXECUTEBUFFER this) +{ + TRACE(ddraw, "(%p)->()\n", this); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_SetExecuteData(LPDIRECT3DEXECUTEBUFFER this, + LPD3DEXECUTEDATA lpData) +{ + DWORD nbvert; + + TRACE(ddraw, "(%p)->(%p)\n", this, lpData); + + this->data = *lpData; + + /* Get the number of vertices in the execute buffer */ + nbvert = this->data.dwVertexCount; + + /* Prepares the transformed vertex buffer */ + if (this->vertex_data != NULL) + HeapFree(GetProcessHeap(), 0, this->vertex_data); + this->vertex_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,nbvert * sizeof(D3DVERTEX)); + + + if (TRACE_ON(ddraw)) { + _dump_executedata(lpData); + } + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_GetExecuteData(LPDIRECT3DEXECUTEBUFFER this, + LPD3DEXECUTEDATA lpData) +{ + TRACE(ddraw, "(%p)->(%p): stub\n", this, lpData); + + *lpData = this->data; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_Validate(LPDIRECT3DEXECUTEBUFFER this, + LPDWORD lpdwOffset, + LPD3DVALIDATECALLBACK lpFunc, + LPVOID lpUserArg, + DWORD dwReserved) +{ + TRACE(ddraw, "(%p)->(%p,%p,%p,%lu)\n", this, lpdwOffset, lpFunc, lpUserArg, dwReserved); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DExecuteBuffer_Optimize(LPDIRECT3DEXECUTEBUFFER this, + DWORD dwReserved) +{ + TRACE(ddraw, "(%p)->(%lu)\n", this, dwReserved); + + return DD_OK; +} + + +/******************************************************************************* + * IDirect3DLight VTable + */ +static IDirect3DExecuteBuffer_VTable executebuffer_vtable = { + /*** IUnknown methods ***/ + IDirect3DExecuteBuffer_QueryInterface, + IDirect3DExecuteBuffer_AddRef, + IDirect3DExecuteBuffer_Release, + /*** IDirect3DExecuteBuffer methods ***/ + IDirect3DExecuteBuffer_Initialize, + IDirect3DExecuteBuffer_Lock, + IDirect3DExecuteBuffer_Unlock, + IDirect3DExecuteBuffer_SetExecuteData, + IDirect3DExecuteBuffer_GetExecuteData, + IDirect3DExecuteBuffer_Validate, + IDirect3DExecuteBuffer_Optimize +}; + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3dlight.c b/graphics/d3dlight.c new file mode 100644 index 00000000000..7b191246185 --- /dev/null +++ b/graphics/d3dlight.c @@ -0,0 +1,260 @@ +/* Direct3D Light + (c) 1998 Lionel ULMER + + This files contains the implementation of Direct3DLight. */ + + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static IDirect3DLight_VTable light_vtable; + +enum { + D3D_1, + D3D_2 +}; + +/******************************************************************************* + * Light static functions + */ +static const float zero_value[] = { + 0.0, 0.0, 0.0, 0.0 +}; + +static void update(LPDIRECT3DLIGHT this) { + switch (this->light.dltType) { + case D3DLIGHT_POINT: /* 1 */ + TRACE(ddraw, "Activating POINT\n"); + break; + + case D3DLIGHT_SPOT: /* 2 */ + TRACE(ddraw, "Activating SPOT\n"); + break; + + case D3DLIGHT_DIRECTIONAL: { /* 3 */ + float direction[4]; + + TRACE(ddraw, "Activating DIRECTIONAL\n"); + TRACE(ddraw, " direction : %f %f %f\n", + this->light.dvDirection.x.x, + this->light.dvDirection.y.y, + this->light.dvDirection.z.z); + _dump_colorvalue(" color ", this->light.dcvColor); + + glLightfv(this->light_num, + GL_AMBIENT, + (float *) zero_value); + + glLightfv(this->light_num, + GL_DIFFUSE, + (float *) &(this->light.dcvColor)); + + direction[0] = -this->light.dvDirection.x.x; + direction[1] = -this->light.dvDirection.y.y; + direction[2] = -this->light.dvDirection.z.z; + direction[3] = 0.0; /* This is a directional light */ + glLightfv(this->light_num, + GL_POSITION, + (float *) direction); + } break; + + case D3DLIGHT_PARALLELPOINT: /* 4 */ + TRACE(ddraw, "Activating PARRALLEL-POINT\n"); + break; + + default: + TRACE(ddraw, "Not a know Light Type\n"); + break; + } +} + +static void activate(LPDIRECT3DLIGHT this) { + update(this); + + /* If was not active, activate it */ + if (this->is_active == 0) { + glEnable(this->light_num); + + this->is_active = 1; + } + + return ; +} + +/******************************************************************************* + * Light Creation functions + */ +LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d) +{ + LPDIRECT3DLIGHT mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLight)); + mat->ref = 1; + mat->lpvtbl = &light_vtable; + mat->d3d.d3d2 = d3d; + mat->type = D3D_2; + + mat->next = NULL; + mat->prev = NULL; + mat->activate = activate; + mat->is_active = 0; + + return mat; +} + +LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d) +{ + LPDIRECT3DLIGHT mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLight)); + mat->ref = 1; + mat->lpvtbl = &light_vtable; + + mat->d3d.d3d = d3d; + mat->type = D3D_1; + + mat->next = NULL; + mat->prev = NULL; + mat->activate = activate; + mat->is_active = 0; + + return mat; +} + +/******************************************************************************* + * IDirect3DLight methods + */ + +static HRESULT WINAPI IDirect3DLight_QueryInterface(LPDIRECT3DLIGHT this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DLight_AddRef(LPDIRECT3DLIGHT this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DLight_Release(LPDIRECT3DLIGHT this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +/*** IDirect3DLight methods ***/ +static void dump_light(LPD3DLIGHT light) +{ + fprintf(stderr, " dwSize : %ld\n", light->dwSize); +} + +static HRESULT WINAPI IDirect3DLight_GetLight(LPDIRECT3DLIGHT this, + LPD3DLIGHT lpLight) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpLight); + if (TRACE_ON(ddraw)) + dump_light(lpLight); + + /* Copies the light structure */ + switch (this->type) { + case D3D_1: + *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(this->light)); + break; + case D3D_2: + *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(this->light)); + break; + } + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DLight_SetLight(LPDIRECT3DLIGHT this, + LPD3DLIGHT lpLight) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpLight); + if (TRACE_ON(ddraw)) + dump_light(lpLight); + + /* Stores the light */ + switch (this->type) { + case D3D_1: + *((LPD3DLIGHT) &(this->light)) = *((LPD3DLIGHT)lpLight); + break; + case D3D_2: + *((LPD3DLIGHT2) &(this->light)) = *((LPD3DLIGHT2)lpLight); + break; + } + + if (this->is_active) + update(this); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DLight_Initialize(LPDIRECT3DLIGHT this, + LPDIRECT3D lpDirect3D) + +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpDirect3D); + + return DDERR_ALREADYINITIALIZED; +} + + +/******************************************************************************* + * IDirect3DLight VTable + */ +static IDirect3DLight_VTable light_vtable = { + /*** IUnknown methods ***/ + IDirect3DLight_QueryInterface, + IDirect3DLight_AddRef, + IDirect3DLight_Release, + /*** IDirect3DLight methods ***/ + IDirect3DLight_Initialize, + IDirect3DLight_SetLight, + IDirect3DLight_GetLight +}; + +#else /* HAVE_MESAGL */ + +/* These function should never be called if MesaGL is not present */ +LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3dmaterial.c b/graphics/d3dmaterial.c new file mode 100644 index 00000000000..de45b02dd5f --- /dev/null +++ b/graphics/d3dmaterial.c @@ -0,0 +1,251 @@ +/* Direct3D Material + (c) 1998 Lionel ULMER + + This files contains the implementation of Direct3DMaterial2. */ + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static IDirect3DMaterial2_VTable material2_vtable; +static IDirect3DMaterial_VTable material_vtable; + +/******************************************************************************* + * Matrial2 static functions + */ +static void activate(LPDIRECT3DMATERIAL2 this) { + TRACE(ddraw, "Activating material %p\n", this); + + /* First, set the rendering context */ + if (this->use_d3d2) + this->device.active_device2->set_context(this->device.active_device2); + else + this->device.active_device1->set_context(this->device.active_device1); + + /* Set the current Material */ + _dump_colorvalue("Diffuse", this->mat.a.diffuse); + glMaterialfv(GL_FRONT, + GL_DIFFUSE, + (float *) &(this->mat.a.diffuse)); + _dump_colorvalue("Ambient", this->mat.b.ambient); + glMaterialfv(GL_FRONT, + GL_AMBIENT, + (float *) &(this->mat.b.ambient)); + _dump_colorvalue("Specular", this->mat.c.specular); + glMaterialfv(GL_FRONT, + GL_SPECULAR, + (float *) &(this->mat.c.specular)); + _dump_colorvalue("Emissive", this->mat.d.emissive); + glMaterialfv(GL_FRONT, + GL_EMISSION, + (float *) &(this->mat.d.emissive)); + + TRACE(ddraw, "Size : %ld\n", this->mat.dwSize); + TRACE(ddraw, "Power : %f\n", this->mat.e.power); + + return ; +} + +/******************************************************************************* + * Matrial2 Creation functions + */ +LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d) +{ + LPDIRECT3DMATERIAL2 mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2)); + mat->ref = 1; + mat->lpvtbl = &material2_vtable; + + mat->use_d3d2 = 1; + mat->d3d.d3d2 = d3d; + + mat->activate = activate; + + return mat; +} + +LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d) +{ + LPDIRECT3DMATERIAL2 mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2)); + mat->ref = 1; + mat->lpvtbl = (LPDIRECT3DMATERIAL2_VTABLE) &material_vtable; + + mat->use_d3d2 = 0; + mat->d3d.d3d1 = d3d; + + mat->activate = activate; + + return (LPDIRECT3DMATERIAL) mat; +} + +/******************************************************************************* + * IDirect3DMaterial2 methods + */ + +static HRESULT WINAPI IDirect3DMaterial2_QueryInterface(LPDIRECT3DMATERIAL2 this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DMaterial2_AddRef(LPDIRECT3DMATERIAL2 this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DMaterial2_Release(LPDIRECT3DMATERIAL2 this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +/*** IDirect3DMaterial2 methods ***/ +static void dump_material(LPD3DMATERIAL mat) +{ + fprintf(stderr, " dwSize : %ld\n", mat->dwSize); +} + +static HRESULT WINAPI IDirect3DMaterial2_GetMaterial(LPDIRECT3DMATERIAL2 this, + LPD3DMATERIAL lpMat) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpMat); + if (TRACE_ON(ddraw)) + dump_material(lpMat); + + /* Copies the material structure */ + *lpMat = this->mat; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DMaterial2_SetMaterial(LPDIRECT3DMATERIAL2 this, + LPD3DMATERIAL lpMat) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpMat); + if (TRACE_ON(ddraw)) + dump_material(lpMat); + + /* Stores the material */ + this->mat = *lpMat; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DMaterial2_GetHandle(LPDIRECT3DMATERIAL2 this, + LPDIRECT3DDEVICE2 lpD3DDevice2, + LPD3DMATERIALHANDLE lpMatHandle) + +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice2, lpMatHandle); + + if (this->use_d3d2) + this->device.active_device2 = lpD3DDevice2; + else + this->device.active_device1 = (LPDIRECT3DDEVICE) lpD3DDevice2; + + *lpMatHandle = (DWORD) this; /* lpD3DDevice2->store_material(this); */ + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DMaterial_Reserve(LPDIRECT3DMATERIAL this) +{ + FIXME(ddraw, "(%p)->(): stub\n", this); + + return DDERR_INVALIDPARAMS; +} + +static HRESULT WINAPI IDirect3DMaterial_Unreserve(LPDIRECT3DMATERIAL this) +{ + FIXME(ddraw, "(%p)->(): stub\n", this); + + return DDERR_INVALIDPARAMS; +} + +static HRESULT WINAPI IDirect3DMaterial_Initialize(LPDIRECT3DMATERIAL this, + LPDIRECT3D lpDirect3D) + +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpDirect3D); + + return DDERR_ALREADYINITIALIZED; +} + + +/******************************************************************************* + * IDirect3DMaterial VTable + */ +static IDirect3DMaterial_VTable material_vtable = { + /*** IUnknown methods ***/ + IDirect3DMaterial2_QueryInterface, + IDirect3DMaterial2_AddRef, + IDirect3DMaterial2_Release, + /*** IDirect3DMaterial methods ***/ + IDirect3DMaterial_Initialize, + IDirect3DMaterial2_SetMaterial, + IDirect3DMaterial2_GetMaterial, + IDirect3DMaterial2_GetHandle, + IDirect3DMaterial_Reserve, + IDirect3DMaterial_Unreserve +}; + + +/******************************************************************************* + * IDirect3DMaterial2 VTable + */ +static IDirect3DMaterial2_VTable material2_vtable = { + /*** IUnknown methods ***/ + IDirect3DMaterial2_QueryInterface, + IDirect3DMaterial2_AddRef, + IDirect3DMaterial2_Release, + /*** IDirect3DMaterial methods ***/ + IDirect3DMaterial2_SetMaterial, + IDirect3DMaterial2_GetMaterial, + IDirect3DMaterial2_GetHandle +}; + +#else /* HAVE_MESAGL */ + +LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3dtexture.c b/graphics/d3dtexture.c new file mode 100644 index 00000000000..f79ba156599 --- /dev/null +++ b/graphics/d3dtexture.c @@ -0,0 +1,200 @@ +/* Direct3D Texture + (c) 1998 Lionel ULMER + + This files contains the implementation of interface Direct3DTexture2. */ + + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + +#ifdef HAVE_MESAGL + +static IDirect3DTexture2_VTable texture2_vtable; +static IDirect3DTexture_VTable texture_vtable; + +/******************************************************************************* + * Texture2 Creation functions + */ +LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf) +{ + LPDIRECT3DTEXTURE2 mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2)); + mat->ref = 1; + mat->lpvtbl = &texture2_vtable; + mat->surface = surf; + + return mat; +} + +/******************************************************************************* + * Texture Creation functions + */ +LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf) +{ + LPDIRECT3DTEXTURE mat; + + mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture)); + mat->ref = 1; + mat->lpvtbl = (IDirect3DTexture2_VTable*) &texture_vtable; + mat->surface = surf; + + return mat; +} + + +/******************************************************************************* + * IDirect3DTexture2 methods + */ + +static HRESULT WINAPI IDirect3DTexture2_QueryInterface(LPDIRECT3DTEXTURE2 this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DTexture2_AddRef(LPDIRECT3DTEXTURE2 this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DTexture2_Release(LPDIRECT3DTEXTURE2 this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +/*** IDirect3DTexture methods ***/ +static HRESULT WINAPI IDirect3DTexture_GetHandle(LPDIRECT3DTEXTURE this, + LPDIRECT3DDEVICE lpD3DDevice, + LPD3DTEXTUREHANDLE lpHandle) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice, lpHandle); + + *lpHandle = (DWORD) this->surface; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DTexture_Initialize(LPDIRECT3DTEXTURE this, + LPDIRECT3DDEVICE lpD3DDevice, + LPDIRECTDRAWSURFACE lpSurface) +{ + TRACE(ddraw, "(%p)->(%p,%p)\n", this, lpD3DDevice, lpSurface); + + return DDERR_ALREADYINITIALIZED; +} + +static HRESULT WINAPI IDirect3DTexture_Unload(LPDIRECT3DTEXTURE this) +{ + FIXME(ddraw, "(%p)->(): stub\n", this); + + return DD_OK; +} + +/*** IDirect3DTexture2 methods ***/ +static HRESULT WINAPI IDirect3DTexture2_GetHandle(LPDIRECT3DTEXTURE2 this, + LPDIRECT3DDEVICE2 lpD3DDevice2, + LPD3DTEXTUREHANDLE lpHandle) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice2, lpHandle); + + *lpHandle = (DWORD) this->surface; /* lpD3DDevice2->store_texture(this); */ + + return DD_OK; +} + +/* Common methods */ +static HRESULT WINAPI IDirect3DTexture2_PaletteChanged(LPDIRECT3DTEXTURE2 this, + DWORD dwStart, + DWORD dwCount) +{ + FIXME(ddraw, "(%p)->(%8ld,%8ld): stub\n", this, dwStart, dwCount); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DTexture2_Load(LPDIRECT3DTEXTURE2 this, + LPDIRECT3DTEXTURE2 lpD3DTexture2) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpD3DTexture2); + + /* Hack ? */ + FIXME(ddraw, "Sthis %p / Sload %p\n", this->surface, lpD3DTexture2->surface); + this->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + + return DD_OK; +} + + +/******************************************************************************* + * IDirect3DTexture2 VTable + */ +static IDirect3DTexture2_VTable texture2_vtable = { + /*** IUnknown methods ***/ + IDirect3DTexture2_QueryInterface, + IDirect3DTexture2_AddRef, + IDirect3DTexture2_Release, + /*** IDirect3DTexture methods ***/ + IDirect3DTexture2_GetHandle, + IDirect3DTexture2_PaletteChanged, + IDirect3DTexture2_Load +}; + +/******************************************************************************* + * IDirect3DTexture VTable + */ +static IDirect3DTexture_VTable texture_vtable = { + /*** IUnknown methods ***/ + IDirect3DTexture2_QueryInterface, + IDirect3DTexture2_AddRef, + IDirect3DTexture2_Release, + /*** IDirect3DTexture methods ***/ + IDirect3DTexture_Initialize, + IDirect3DTexture_GetHandle, + IDirect3DTexture2_PaletteChanged, + IDirect3DTexture2_Load, + IDirect3DTexture_Unload +}; + +#else /* HAVE_MESAGL */ + +/* These function should never be called if MesaGL is not present */ +LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +#endif /* HAVE_MESAGL */ diff --git a/graphics/d3dviewport.c b/graphics/d3dviewport.c new file mode 100644 index 00000000000..754d410f889 --- /dev/null +++ b/graphics/d3dviewport.c @@ -0,0 +1,350 @@ +/* Direct3D Viewport + (c) 1998 Lionel ULMER + + This files contains the implementation of Direct3DViewport2. */ + +#include "config.h" +#include "windows.h" +#include "wintypes.h" +#include "winerror.h" +#include "interfaces.h" +#include "heap.h" +#include "ddraw.h" +#include "d3d.h" +#include "debug.h" + +#include "d3d_private.h" + + +#ifdef HAVE_MESAGL + +static IDirect3DViewport2_VTable viewport2_vtable; + +/******************************************************************************* + * Viewport1/2 static functions + */ +static void activate(LPDIRECT3DVIEWPORT2 this) { + LPDIRECT3DLIGHT l; + + /* Activate all the lights associated with this context */ + l = this->lights; + + while (l != NULL) { + l->activate(l); + l = l->next; + } +} + +/******************************************************************************* + * Viewport1/2 Creation functions + */ +LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) +{ + LPDIRECT3DVIEWPORT2 vp; + + vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2)); + vp->ref = 1; + vp->lpvtbl = &viewport2_vtable; + vp->d3d.d3d2 = d3d; + vp->use_d3d2 = 1; + + vp->device.active_device2 = NULL; + vp->activate = activate; + + vp->lights = NULL; + + vp->nextlight = GL_LIGHT0; + + return vp; +} + +LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) +{ + LPDIRECT3DVIEWPORT2 vp; + + vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2)); + vp->ref = 1; + vp->lpvtbl = &viewport2_vtable; + vp->d3d.d3d1 = d3d; + vp->use_d3d2 = 0; + + vp->device.active_device1 = NULL; + vp->activate = activate; + + vp->lights = NULL; + + vp->nextlight = GL_LIGHT0; + + return (LPDIRECT3DVIEWPORT) vp; +} + +/******************************************************************************* + * IDirect3DViewport2 methods + */ + +static HRESULT WINAPI IDirect3DViewport2_QueryInterface(LPDIRECT3DVIEWPORT2 this, + REFIID riid, + LPVOID* ppvObj) +{ + char xrefiid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xrefiid); + FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj); + + return S_OK; +} + + + +static ULONG WINAPI IDirect3DViewport2_AddRef(LPDIRECT3DVIEWPORT2 this) +{ + TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + + + +static ULONG WINAPI IDirect3DViewport2_Release(LPDIRECT3DVIEWPORT2 this) +{ + FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); + + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + + return this->ref; +} + +/*** IDirect3DViewport methods ***/ +static HRESULT WINAPI IDirect3DViewport2_Initialize(LPDIRECT3DVIEWPORT2 this, + LPDIRECT3D d3d) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, d3d); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_GetViewport(LPDIRECT3DVIEWPORT2 this, + LPD3DVIEWPORT lpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + if (this->use_vp2 != 0) + return DDERR_INVALIDPARAMS; + + *lpvp = this->viewport.vp1; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_SetViewport(LPDIRECT3DVIEWPORT2 this, + LPD3DVIEWPORT lpvp) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp); + + this->use_vp2 = 0; + this->viewport.vp1 = *lpvp; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_TransformVertices(LPDIRECT3DVIEWPORT2 this, + DWORD dwVertexCount, + LPD3DTRANSFORMDATA lpData, + DWORD dwFlags, + LPDWORD lpOffScreen) +{ + FIXME(ddraw, "(%p)->(%8ld,%p,%08lx,%p): stub\n", + this, dwVertexCount, lpData, dwFlags, lpOffScreen); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_LightElements(LPDIRECT3DVIEWPORT2 this, + DWORD dwElementCount, + LPD3DLIGHTDATA lpData) +{ + FIXME(ddraw, "(%p)->(%8ld,%p): stub\n", this, dwElementCount, lpData); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_SetBackground(LPDIRECT3DVIEWPORT2 this, + D3DMATERIALHANDLE hMat) +{ + FIXME(ddraw, "(%p)->(%08x): stub\n", this, hMat); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_GetBackground(LPDIRECT3DVIEWPORT2 this, + LPD3DMATERIALHANDLE lphMat, + LPBOOL lpValid) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lphMat, lpValid); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 this, + LPDIRECTDRAWSURFACE lpDDSurface) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpDDSurface); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 this, + LPDIRECTDRAWSURFACE* lplpDDSurface, + LPBOOL lpValid) +{ + FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lplpDDSurface, lpValid); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_Clear(LPDIRECT3DVIEWPORT2 this, + DWORD dwCount, + LPD3DRECT lpRects, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%8ld,%p,%08lx): stub\n", this, dwCount, lpRects, dwFlags); + + /* For the moment, ignore the rectangles */ + if (this->device.active_device1 != NULL) { + /* Get the rendering context */ + if (this->use_d3d2) + this->device.active_device2->set_context(this->device.active_device2); + else + this->device.active_device1->set_context(this->device.active_device1); + + /* Clears the screen */ + glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_AddLight(LPDIRECT3DVIEWPORT2 this, + LPDIRECT3DLIGHT lpLight) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight); + + /* Add the light in the 'linked' chain */ + lpLight->next = this->lights; + this->lights = lpLight; + + /* If active, activate the light */ + if (this->device.active_device1 != NULL) { + /* Get the rendering context */ + if (this->use_d3d2) + this->device.active_device2->set_context(this->device.active_device2); + else + this->device.active_device1->set_context(this->device.active_device1); + + /* Activate the light */ + lpLight->light_num = this->nextlight++; + lpLight->activate(lpLight); + } + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_DeleteLight(LPDIRECT3DVIEWPORT2 this, + LPDIRECT3DLIGHT lpLight) +{ + FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_NextLight(LPDIRECT3DVIEWPORT2 this, + LPDIRECT3DLIGHT lpLight, + LPDIRECT3DLIGHT* lplpLight, + DWORD dwFlags) +{ + FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpLight, lplpLight, dwFlags); + + return DD_OK; +} + +/*** IDirect3DViewport2 methods ***/ +static HRESULT WINAPI IDirect3DViewport2_GetViewport2(LPDIRECT3DVIEWPORT2 this, + LPD3DVIEWPORT2 lpViewport2) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2); + + if (this->use_vp2 != 1) + return DDERR_INVALIDPARAMS; + + *lpViewport2 = this->viewport.vp2; + + return DD_OK; +} + +static HRESULT WINAPI IDirect3DViewport2_SetViewport2(LPDIRECT3DVIEWPORT2 this, + LPD3DVIEWPORT2 lpViewport2) +{ + TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2); + + TRACE(ddraw, "dwSize = %ld dwX = %ld dwY = %ld\n", + lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY); + TRACE(ddraw, "dwWidth = %ld dwHeight = %ld\n", + lpViewport2->dwWidth, lpViewport2->dwHeight); + TRACE(ddraw, "dvClipX = %f dvClipY = %f\n", + lpViewport2->dvClipX, lpViewport2->dvClipY); + TRACE(ddraw, "dvClipWidth = %f dvClipHeight = %f\n", + lpViewport2->dvClipWidth, lpViewport2->dvClipHeight); + TRACE(ddraw, "dvMinZ = %f dvMaxZ = %f\n", + lpViewport2->dvMinZ, lpViewport2->dvMaxZ); + + this->viewport.vp2 = *lpViewport2; + this->use_vp2 = 1; + + return DD_OK; +} + + +/******************************************************************************* + * IDirect3DViewport1/2 VTable + */ +static IDirect3DViewport2_VTable viewport2_vtable = { + /*** IUnknown methods ***/ + IDirect3DViewport2_QueryInterface, + IDirect3DViewport2_AddRef, + IDirect3DViewport2_Release, + /*** IDirect3DViewport methods ***/ + IDirect3DViewport2_Initialize, + IDirect3DViewport2_GetViewport, + IDirect3DViewport2_SetViewport, + IDirect3DViewport2_TransformVertices, + IDirect3DViewport2_LightElements, + IDirect3DViewport2_SetBackground, + IDirect3DViewport2_GetBackground, + IDirect3DViewport2_SetBackgroundDepth, + IDirect3DViewport2_GetBackgroundDepth, + IDirect3DViewport2_Clear, + IDirect3DViewport2_AddLight, + IDirect3DViewport2_DeleteLight, + IDirect3DViewport2_NextLight, + /*** IDirect3DViewport2 methods ***/ + IDirect3DViewport2_GetViewport2, + IDirect3DViewport2_SetViewport2 +}; + +#else /* HAVE_MESAGL */ + +LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) { + ERR(ddraw, "Should not be called...\n"); + return NULL; +} + +#endif /* HAVE_MESAGL */ diff --git a/graphics/ddraw.c b/graphics/ddraw.c index 474d2b050f1..e0a61b3ea29 100644 --- a/graphics/ddraw.c +++ b/graphics/ddraw.c @@ -1,6 +1,7 @@ /* DirectDraw using DGA or Xlib(XSHM) * * Copyright 1997,1998 Marcus Meissner + * Copyright 1998 Lionel Ulmer (most of Direct3D stuff) */ /* XF86DGA: * When DirectVideo mode is enabled you can no longer use 'normal' X @@ -59,6 +60,9 @@ #include "ts_xshm.h" #endif +/* This for all the enumeration and creation of D3D-related objects */ +#include "d3d_private.h" + /* define this if you want to play Diablo using XF86DGA. (bug workaround) */ #undef DIABLO_HACK @@ -121,10 +125,13 @@ DDRAW_DGA_Available() HRESULT WINAPI DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) { if (DDRAW_DGA_Available()) { + TRACE(ddraw, "Enumerating DGA interface\n"); ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data); } + TRACE(ddraw, "Enumerating Xlib interface\n"); ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data); - ddenumproc(NULL,"WINE","display",data); + TRACE(ddraw, "Enumerating Default interface\n"); + ddenumproc(NULL,"WINE (default)","display",data); return DD_OK; } @@ -324,9 +331,11 @@ static void _dump_DDCOLORKEY(DWORD flagmask) { } static void _dump_pixelformat(LPDDPIXELFORMAT pf) { + DUMP("Size : %ld\n", pf->dwSize); + if (pf->dwFlags) _dump_DDCOLORKEY(pf->dwFlags); DUMP("dwFourCC : %ld\n", pf->dwFourCC); - DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount); + DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount); DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n", pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask); } @@ -340,6 +349,7 @@ static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) { vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems); pf->dwFourCC = 0; + pf->dwSize = sizeof(DDPIXELFORMAT); if (ddraw->d.depth==8) { pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8; pf->x.dwRGBBitCount = 8; @@ -585,7 +595,7 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette( static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette( LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal ) { - TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal); + TRACE(ddraw,"(%p)->(%p)\n",this,pal); #ifdef HAVE_LIBXXF86DGA /* According to spec, we are only supposed to * AddRef if this is not the same palette. @@ -701,16 +711,49 @@ static HRESULT WINAPI IDirectDrawSurface3_Blt( ddesc.dwHeight * ddesc.lPitch); } else { int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8; - int height = xsrc.bottom - xsrc.top; + int srcheight = xsrc.bottom - xsrc.top; + int srcwidth = xsrc.right - xsrc.left; + int dstheight = xdst.bottom - xdst.top; + int dstwidth = xdst.right - xdst.left; int width = (xsrc.right - xsrc.left) * bpp; int h; - for (h = 0; h < height; h++) { + /* Sanity check for rectangle sizes */ + if ((srcheight != dstheight) || (srcwidth != dstwidth)) { + int x, y; + + /* I think we should do a Blit with 'stretching' here.... + Tomb Raider II uses this to display the background during the menu selection + when the screen resolution is != than 40x480 */ + TRACE(ddraw, "Blt with stretching\n"); + + /* This is a basic stretch implementation. It is painfully slow and quite ugly. */ + if (bpp == 1) { + /* In this case, we cannot do any anti-aliasing */ + for (y = xdst.top; y < xdst.bottom; y++) { + for (x = xdst.left; x < xdst.right; x++) { + double sx, sy; + unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface; + unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface; + + sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left; + sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top; + + dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)]; + } + } + } else { + FIXME(ddraw, "Not done yet for depth != 8\n"); + } + } else { + /* Same size => fast blit */ + for (h = 0; h < srcheight; h++) { memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp, sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp, width); } } + } if (dwFlags && FIXME_ON(ddraw)) { FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags); @@ -956,8 +999,41 @@ static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 th ) { *obj = this; this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IDirect3DSurfaceX interface (%p)\n", *obj); + return S_OK; } + else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID))) + { + /* Texture interface */ + *obj = d3dtexture2_create(this); + this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj); + + return S_OK; + } + else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID))) + { + /* Texture interface */ + *obj = d3dtexture_create(this); + this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj); + + return S_OK; + } + else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj)) + { + /* It is the OpenGL Direct3D Device */ + this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj); + + return S_OK; + } + FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid); return OLE_E_ENUM_NOMORE; } @@ -1159,6 +1235,9 @@ static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface( { FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD); + /* Not sure about that... */ + *lplpDD = (void *) this->s.ddraw; + return DD_OK; } @@ -1554,6 +1633,9 @@ static HRESULT WINAPI IDirect3D_QueryInterface( if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { *obj = this; this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { @@ -1565,6 +1647,9 @@ static HRESULT WINAPI IDirect3D_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3dvt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { @@ -1576,6 +1661,9 @@ static HRESULT WINAPI IDirect3D_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3d2vt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); + return S_OK; } FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid); @@ -1612,61 +1700,63 @@ static HRESULT WINAPI IDirect3D_Initialize( return DDERR_ALREADYINITIALIZED; } -static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) { - FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk); - return E_FAIL; -} +static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this, + LPD3DENUMDEVICESCALLBACK cb, + LPVOID context) { + FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context); -typedef LPVOID LPDIRECT3DDEVICE; + /* Call functions defined in d3ddevices.c */ + if (d3d_OpenGL_dx3(cb, context)) + return DD_OK; -static HRESULT WINAPI IDirect3D_CreateDevice(LPDIRECT3D this,LPCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE *d3dev) { - char xclsid[50]; - - WINE_StringFromCLSID(rclsid,xclsid); - FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev); - return E_FAIL; /* D3DERR_INVALID_DEVICE probably */ -} - -static HRESULT WINAPI IDirect3D_EnumDevices( - LPDIRECT3D this, - LPD3DENUMDEVICESCALLBACK a, - LPVOID b ) -{ - FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b); return DD_OK; } -static HRESULT WINAPI IDirect3D_CreateMaterial( - LPDIRECT3D this, - LPDIRECT3DMATERIAL* a, - IUnknown* b) +static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this, + LPDIRECT3DLIGHT *lplight, + IUnknown *lpunk) { - FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b); + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk); + + /* Call the creation function that is located in d3dlight.c */ + *lplight = d3dlight_create_dx3(this); + return DD_OK; } -static HRESULT WINAPI IDirect3D_CreateViewport( - LPDIRECT3D this, - LPDIRECT3DVIEWPORT* a, - IUnknown* b ) +static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this, + LPDIRECT3DMATERIAL *lpmaterial, + IUnknown *lpunk) { - FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b); + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk); + + /* Call the creation function that is located in d3dviewport.c */ + *lpmaterial = d3dmaterial_create(this); + return DD_OK; } -static HRESULT WINAPI IDirect3D_FindDevice( - LPDIRECT3D this, - LPD3DFINDDEVICESEARCH a, - LPD3DFINDDEVICERESULT b ) +static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this, + LPDIRECT3DVIEWPORT *lpviewport, + IUnknown *lpunk) { - FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b); + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk); + + /* Call the creation function that is located in d3dviewport.c */ + *lpviewport = d3dviewport_create(this); + return DD_OK; } +static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this, + LPD3DFINDDEVICESEARCH lpfinddevsrc, + LPD3DFINDDEVICERESULT lpfinddevrst) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst); + + return DD_OK; +} -/******************************************************************************* - * IDirect3D - */ static struct IDirect3D_VTable d3dvt = { IDirect3D_QueryInterface, IDirect3D_AddRef, @@ -1676,12 +1766,26 @@ static struct IDirect3D_VTable d3dvt = { IDirect3D_CreateLight, IDirect3D_CreateMaterial, IDirect3D_CreateViewport, - IDirect3D_FindDevice, + IDirect3D_FindDevice }; /******************************************************************************* * IDirect3D2 */ +static HRESULT WINAPI IDirect3D2_QueryInterface( + LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) { + /* For the moment, we use the same function as in IDirect3D */ + TRACE(ddraw, "Calling IDirect3D enumerating function.\n"); + + return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj); +} + +static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) { + TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); + + return ++(this->ref); +} + static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) { TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); @@ -1696,43 +1800,88 @@ static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) { static HRESULT WINAPI IDirect3D2_EnumDevices( LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context ) { - D3DDEVICEDESC d1,d2; - FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context); -#if 0 - d1.dwSize = sizeof(d1); - d1.dwFlags = 0; - d2.dwSize = sizeof(d2); - d2.dwFlags = 0; - cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context); -#endif + /* Call functions defined in d3ddevices.c */ + if (d3d_OpenGL(cb, context)) + return DD_OK; + return DD_OK; } -static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,REFCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE2 *d3dev) { - char xclsid[50]; +static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this, + LPDIRECT3DLIGHT *lplight, + IUnknown *lpunk) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk); - WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); - FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev); - return E_FAIL; /* D3DERR_INVALID_DEVICE probably */ + /* Call the creation function that is located in d3dlight.c */ + *lplight = d3dlight_create(this); + + return DD_OK; } -static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) { - FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk); - return E_FAIL; +static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this, + LPDIRECT3DMATERIAL2 *lpmaterial, + IUnknown *lpunk) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk); + + /* Call the creation function that is located in d3dviewport.c */ + *lpmaterial = d3dmaterial2_create(this); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this, + LPDIRECT3DVIEWPORT2 *lpviewport, + IUnknown *lpunk) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk); + + /* Call the creation function that is located in d3dviewport.c */ + *lpviewport = d3dviewport2_create(this); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this, + LPD3DFINDDEVICESEARCH lpfinddevsrc, + LPD3DFINDDEVICERESULT lpfinddevrst) +{ + TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst); + + return DD_OK; +} + +static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this, + REFCLSID rguid, + LPDIRECTDRAWSURFACE surface, + LPDIRECT3DDEVICE2 *device) +{ + char xbuf[50]; + + WINE_StringFromCLSID(rguid,xbuf); + FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device); + + if (is_OpenGL(rguid, surface, device, this)) { + this->lpvtbl->fnAddRef(this); + return DD_OK; +} + + return DDERR_INVALIDPARAMS; } static struct IDirect3D2_VTable d3d2vt = { - (void*)IDirect3D_QueryInterface, - (void*)IDirect3D_AddRef, + IDirect3D2_QueryInterface, + IDirect3D2_AddRef, IDirect3D2_Release, IDirect3D2_EnumDevices, - (void*)IDirect3D_EnumDevices, - (void*)IDirect3D_CreateLight, - (void*)IDirect3D_CreateMaterial, - (void*)IDirect3D_CreateViewport, - (void*)IDirect3D_FindDevice, + IDirect3D2_CreateLight, + IDirect3D2_CreateMaterial, + IDirect3D2_CreateViewport, + IDirect3D2_FindDevice, + IDirect3D2_CreateDevice }; /******************************************************************************* @@ -1751,6 +1900,13 @@ static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this, int bpp; /* The surface was already allocated when entering in this function */ + TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf); + + if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) { + /* This is a Z Buffer */ + bpp = lpddsd->x.dwZBufferBitDepth; + } else { + /* This is a standard image */ if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) { /* No pixel format => use DirectDraw's format */ _getpixelformat(this,&(lpddsd->ddpfPixelFormat)); @@ -1761,8 +1917,13 @@ static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this, _dump_pixelformat(&(lpddsd->ddpfPixelFormat)); } } + } + if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { + bpp = 1; + } else { bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8; + } /* Copy the surface description */ lpdsf->s.surface_desc = *lpddsd; @@ -1771,8 +1932,6 @@ static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this, lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp); lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp; - TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf); - return DD_OK; } @@ -2085,6 +2244,11 @@ static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel( TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw)); } this->d.mainWindow = hwnd; + + /* This will be overwritten in the case of Full Screen mode. + Windowed games could work with that :-) */ + this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(hwnd)->pDriverData)->window; + return DD_OK; } @@ -2276,20 +2440,45 @@ static HRESULT WINAPI DGA_IDirectDraw2_GetCaps( #endif /* defined(HAVE_LIBXXF86DGA) */ } +static void fill_caps(LPDDCAPS caps) { + /* This function tries to fill the capabilities of Wine's DDraw implementation. + Need to be fixed, though.. */ + if (caps == NULL) + return; + + caps->dwSize = sizeof(*caps); + caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | + DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS; + caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED | + DDCAPS2_WIDESURFACES; + caps->dwCKeyCaps = 0; + caps->dwFXCaps = 0; + caps->dwFXAlphaCaps = 0; + caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256; + caps->dwSVCaps = 0; + caps->dwZBufferBitDepths = DDBD_16; + /* I put here 8 Mo so that D3D applications will believe they have enough memory + to put textures in video memory. + BTW, is this only frame buffer memory or also texture memory (for Voodoo boards + for example) ? */ + caps->dwVidMemTotal = 8192 * 1024; + caps->dwVidMemFree = 8192 * 1024; + /* These are all the supported capabilities of the surfaces */ + caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP | + DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN | + DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | + DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER; +} + static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps( LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 ) { TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); - /* FIXME: Xlib */ - caps1->dwVidMemTotal = 2048*1024; - caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI); - caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ - if (caps2) { - caps2->dwVidMemTotal = 2048*1024; - caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI); - caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ - } - /* END FIXME: Xlib */ + + /* Put the same caps for the two capabilities */ + fill_caps(caps1); + fill_caps(caps2); + return DD_OK; } @@ -2325,7 +2514,6 @@ static HRESULT WINAPI common_IDirectDraw2_CreatePalette( /* Initialize the palette based on the passed palent struct */ FIXME(ddraw,"needs to handle palent (%p)\n",palent); } - return DD_OK; } @@ -2370,7 +2558,7 @@ static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { #ifdef RESTORE_SIGNALS SIGNAL_InitEmulator(); #endif - return 0; + return DD_OK; #else /* defined(HAVE_LIBXXF86DGA) */ return E_UNEXPECTED; #endif @@ -2442,18 +2630,27 @@ static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { *obj = this; this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt; this->lpvtbl->fnAddRef(this); *obj = this; + + TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt; this->lpvtbl->fnAddRef(this); *obj = this; + + TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { @@ -2465,6 +2662,9 @@ static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3dvt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { @@ -2476,6 +2676,9 @@ static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3d2vt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); + return S_OK; } WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); @@ -2492,18 +2695,27 @@ static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { *obj = this; this->lpvtbl->fnAddRef(this); + + TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt; this->lpvtbl->fnAddRef(this); *obj = this; + + TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt; this->lpvtbl->fnAddRef(this); *obj = this; + + TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { @@ -2515,6 +2727,9 @@ static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3dvt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); + return S_OK; } if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { @@ -2526,6 +2741,9 @@ static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3d2vt; *obj = d3d; + + TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); + return S_OK; } WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); @@ -2683,10 +2901,8 @@ static HRESULT WINAPI IDirectDraw2_GetFourCCCodes( static HRESULT WINAPI IDirectDraw2_EnumSurfaces( LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb -) -{ +) { FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb); - return DD_OK; } diff --git a/include/acconfig.h b/include/acconfig.h index f1cf8777362..35c7acf6951 100644 --- a/include/acconfig.h +++ b/include/acconfig.h @@ -72,3 +72,5 @@ /* Define if IPX includes are taken from Linux kernel */ #undef HAVE_IPX_LINUX +/* Define if Mesa is present on the system or not */ +#undef HAVE_MESAGL diff --git a/include/config.h.in b/include/config.h.in index 309b5f25ee3..75367e9bb6f 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -75,6 +75,9 @@ /* Define if IPX includes are taken from Linux kernel */ #undef HAVE_IPX_LINUX +/* Define if Mesa is present on the system or not */ +#undef HAVE_MESAGL + /* The number of bytes in a long long. */ #undef SIZEOF_LONG_LONG diff --git a/include/d3d.h b/include/d3d.h index 3cc18579cf0..d5729331d13 100644 --- a/include/d3d.h +++ b/include/d3d.h @@ -3,9 +3,13 @@ #include "ddraw.h" -typedef LPVOID LPDIRECT3DMATERIAL,LPDIRECT3DVIEWPORT; -typedef LPVOID LPDIRECT3DMATERIAL2,LPDIRECT3DVIEWPORT2; -typedef LPVOID LPDIRECT3DDEVICE2; +/* This is needed for GL_LIGHT */ +#ifdef HAVE_MESAGL +#include "wine_gl.h" +#endif + +typedef BOOL32 *LPBOOL; +typedef BOOL32 BOOL; DEFINE_GUID(IID_IDirect3D, 0x3BBA0080,0x2421,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 ); DEFINE_GUID(IID_IDirect3D2, 0x6aae1ec1,0x662a,0x11d0,0x88,0x9d,0x00,0xaa,0x00,0xbb,0xb7,0x6a); @@ -29,6 +33,169 @@ DEFINE_GUID(IID_IDirect3DViewport2, 0x93281500,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0 typedef struct IDirect3D IDirect3D ,*LPDIRECT3D ; typedef struct IDirect3D2 IDirect3D2,*LPDIRECT3D2; typedef struct IDirect3DLight IDirect3DLight,*LPDIRECT3DLIGHT; +typedef struct IDirect3DDevice IDirect3DDevice, *LPDIRECT3DDEVICE; +typedef struct IDirect3DDevice2 IDirect3DDevice2, *LPDIRECT3DDEVICE2; +typedef struct IDirect3DViewport2 IDirect3DViewport, IDirect3DViewport2, *LPDIRECT3DVIEWPORT2, *LPDIRECT3DVIEWPORT; +typedef struct IDirect3DMaterial2 IDirect3DMaterial, *LPDIRECT3DMATERIAL, IDirect3DMaterial2, *LPDIRECT3DMATERIAL2; +typedef struct IDirect3DTexture2 IDirect3DTexture, *LPDIRECT3DTEXTURE, IDirect3DTexture2, *LPDIRECT3DTEXTURE2; +typedef struct IDirect3DExecuteBuffer IDirect3DExecuteBuffer, *LPDIRECT3DEXECUTEBUFFER; + +/* ******************************************************************** + Enums + ******************************************************************** */ +#define D3DNEXT_NEXT 0x01l +#define D3DNEXT_HEAD 0x02l +#define D3DNEXT_TAIL 0x04l + +typedef enum { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_PARALLELPOINT = 4, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef enum { + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_LINESTRIP = 3, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_TRIANGLEFAN = 6, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +typedef enum { + D3DRENDERSTATE_TEXTUREHANDLE = 1, /* Texture handle */ + D3DRENDERSTATE_ANTIALIAS = 2, /* D3DANTIALIASMODE */ + D3DRENDERSTATE_TEXTUREADDRESS = 3, /* D3DTEXTUREADDRESS */ + D3DRENDERSTATE_TEXTUREPERSPECTIVE = 4, /* TRUE for perspective correction */ + D3DRENDERSTATE_WRAPU = 5, /* TRUE for wrapping in u */ + D3DRENDERSTATE_WRAPV = 6, /* TRUE for wrapping in v */ + D3DRENDERSTATE_ZENABLE = 7, /* TRUE to enable z test */ + D3DRENDERSTATE_FILLMODE = 8, /* D3DFILL_MODE */ + D3DRENDERSTATE_SHADEMODE = 9, /* D3DSHADEMODE */ + D3DRENDERSTATE_LINEPATTERN = 10, /* D3DLINEPATTERN */ + D3DRENDERSTATE_MONOENABLE = 11, /* TRUE to enable mono rasterization */ + D3DRENDERSTATE_ROP2 = 12, /* ROP2 */ + D3DRENDERSTATE_PLANEMASK = 13, /* DWORD physical plane mask */ + D3DRENDERSTATE_ZWRITEENABLE = 14, /* TRUE to enable z writes */ + D3DRENDERSTATE_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */ + D3DRENDERSTATE_LASTPIXEL = 16, /* TRUE for last-pixel on lines */ + D3DRENDERSTATE_TEXTUREMAG = 17, /* D3DTEXTUREFILTER */ + D3DRENDERSTATE_TEXTUREMIN = 18, /* D3DTEXTUREFILTER */ + D3DRENDERSTATE_SRCBLEND = 19, /* D3DBLEND */ + D3DRENDERSTATE_DESTBLEND = 20, /* D3DBLEND */ + D3DRENDERSTATE_TEXTUREMAPBLEND = 21, /* D3DTEXTUREBLEND */ + D3DRENDERSTATE_CULLMODE = 22, /* D3DCULL */ + D3DRENDERSTATE_ZFUNC = 23, /* D3DCMPFUNC */ + D3DRENDERSTATE_ALPHAREF = 24, /* D3DFIXED */ + D3DRENDERSTATE_ALPHAFUNC = 25, /* D3DCMPFUNC */ + D3DRENDERSTATE_DITHERENABLE = 26, /* TRUE to enable dithering */ + D3DRENDERSTATE_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */ + D3DRENDERSTATE_FOGENABLE = 28, /* TRUE to enable fog */ + D3DRENDERSTATE_SPECULARENABLE = 29, /* TRUE to enable specular */ + D3DRENDERSTATE_ZVISIBLE = 30, /* TRUE to enable z checking */ + D3DRENDERSTATE_SUBPIXEL = 31, /* TRUE to enable subpixel correction */ + D3DRENDERSTATE_SUBPIXELX = 32, /* TRUE to enable correction in X only */ + D3DRENDERSTATE_STIPPLEDALPHA = 33, /* TRUE to enable stippled alpha */ + D3DRENDERSTATE_FOGCOLOR = 34, /* D3DCOLOR */ + D3DRENDERSTATE_FOGTABLEMODE = 35, /* D3DFOGMODE */ + D3DRENDERSTATE_FOGTABLESTART = 36, /* Fog table start */ + D3DRENDERSTATE_FOGTABLEEND = 37, /* Fog table end */ + D3DRENDERSTATE_FOGTABLEDENSITY = 38, /* Fog table density */ + D3DRENDERSTATE_STIPPLEENABLE = 39, /* TRUE to enable stippling */ + D3DRENDERSTATE_EDGEANTIALIAS = 40, /* TRUE to enable edge antialiasing */ + D3DRENDERSTATE_COLORKEYENABLE = 41, /* TRUE to enable source colorkeyed textures */ + D3DRENDERSTATE_BORDERCOLOR = 43, /* Border color for texturing w/border */ + D3DRENDERSTATE_TEXTUREADDRESSU = 44, /* Texture addressing mode for U coordinate */ + D3DRENDERSTATE_TEXTUREADDRESSV = 45, /* Texture addressing mode for V coordinate */ + D3DRENDERSTATE_MIPMAPLODBIAS = 46, /* D3DVALUE Mipmap LOD bias */ + D3DRENDERSTATE_ZBIAS = 47, /* LONG Z bias */ + D3DRENDERSTATE_RANGEFOGENABLE = 48, /* Enables range-based fog */ + D3DRENDERSTATE_ANISOTROPY = 49, /* Max. anisotropy. 1 = no anisotropy */ + D3DRENDERSTATE_FLUSHBATCH = 50, /* Explicit flush for DP batching (DX5 Only) */ + D3DRENDERSTATE_STIPPLEPATTERN00 = 64, /* Stipple pattern 01... */ + D3DRENDERSTATE_STIPPLEPATTERN01 = 65, + D3DRENDERSTATE_STIPPLEPATTERN02 = 66, + D3DRENDERSTATE_STIPPLEPATTERN03 = 67, + D3DRENDERSTATE_STIPPLEPATTERN04 = 68, + D3DRENDERSTATE_STIPPLEPATTERN05 = 69, + D3DRENDERSTATE_STIPPLEPATTERN06 = 70, + D3DRENDERSTATE_STIPPLEPATTERN07 = 71, + D3DRENDERSTATE_STIPPLEPATTERN08 = 72, + D3DRENDERSTATE_STIPPLEPATTERN09 = 73, + D3DRENDERSTATE_STIPPLEPATTERN10 = 74, + D3DRENDERSTATE_STIPPLEPATTERN11 = 75, + D3DRENDERSTATE_STIPPLEPATTERN12 = 76, + D3DRENDERSTATE_STIPPLEPATTERN13 = 77, + D3DRENDERSTATE_STIPPLEPATTERN14 = 78, + D3DRENDERSTATE_STIPPLEPATTERN15 = 79, + D3DRENDERSTATE_STIPPLEPATTERN16 = 80, + D3DRENDERSTATE_STIPPLEPATTERN17 = 81, + D3DRENDERSTATE_STIPPLEPATTERN18 = 82, + D3DRENDERSTATE_STIPPLEPATTERN19 = 83, + D3DRENDERSTATE_STIPPLEPATTERN20 = 84, + D3DRENDERSTATE_STIPPLEPATTERN21 = 85, + D3DRENDERSTATE_STIPPLEPATTERN22 = 86, + D3DRENDERSTATE_STIPPLEPATTERN23 = 87, + D3DRENDERSTATE_STIPPLEPATTERN24 = 88, + D3DRENDERSTATE_STIPPLEPATTERN25 = 89, + D3DRENDERSTATE_STIPPLEPATTERN26 = 90, + D3DRENDERSTATE_STIPPLEPATTERN27 = 91, + D3DRENDERSTATE_STIPPLEPATTERN28 = 92, + D3DRENDERSTATE_STIPPLEPATTERN29 = 93, + D3DRENDERSTATE_STIPPLEPATTERN30 = 94, + D3DRENDERSTATE_STIPPLEPATTERN31 = 95, + D3DRENDERSTATE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DRENDERSTATETYPE; + +typedef enum { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, + D3DCMP_FORCE_DWORD = 0x7fffffff +} D3DCMPFUNC; + +typedef enum { + D3DLIGHTSTATE_MATERIAL = 1, + D3DLIGHTSTATE_AMBIENT = 2, + D3DLIGHTSTATE_COLORMODEL = 3, + D3DLIGHTSTATE_FOGMODE = 4, + D3DLIGHTSTATE_FOGSTART = 5, + D3DLIGHTSTATE_FOGEND = 6, + D3DLIGHTSTATE_FOGDENSITY = 7, + D3DLIGHTSTATE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTSTATETYPE; + +typedef enum { + D3DVT_VERTEX = 1, + D3DVT_LVERTEX = 2, + D3DVT_TLVERTEX = 3, + D3DVT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DVERTEXTYPE; + +typedef enum { + D3DTRANSFORMSTATE_WORLD = 1, + D3DTRANSFORMSTATE_VIEW = 2, + D3DTRANSFORMSTATE_PROJECTION = 3, + D3DTRANSFORMSTATE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +/* ******************************************************************** + Types and structures + ******************************************************************** */ +typedef DWORD D3DMATERIALHANDLE, *LPD3DMATERIALHANDLE; +typedef DWORD D3DTEXTUREHANDLE, *LPD3DTEXTUREHANDLE; +typedef DWORD D3DVIEWPORTHANDLE, *LPD3DVIEWPORTHANDLE; +typedef DWORD D3DMATRIXHANDLE, *LPD3DMATRIXHANDLE; + +typedef DWORD D3DCOLOR, *LPD3DCOLOR; typedef struct { DWORD dwSize; @@ -203,6 +370,7 @@ typedef struct { #define D3DDD_MAXVERTEXCOUNT 0x00000400 /* D3DDEVICEDESC.dwDevCaps */ +#define D3DDEVCAPS_FLOATTLVERTEX 0x00000001 #define D3DDEVCAPS_SORTINCREASINGZ 0x00000002 #define D3DDEVCAPS_SORTDECREASINGZ 0X00000004 #define D3DDEVCAPS_SORTEXACT 0x00000008 @@ -238,6 +406,8 @@ typedef struct _D3DDeviceDesc { } D3DDEVICEDESC,*LPD3DDEVICEDESC; typedef HRESULT (CALLBACK * LPD3DENUMDEVICESCALLBACK)(LPGUID lpGuid,LPSTR lpDeviceDescription,LPSTR lpDeviceName,LPD3DDEVICEDESC,LPD3DDEVICEDESC,LPVOID); +typedef HRESULT (CALLBACK* LPD3DVALIDATECALLBACK)(LPVOID lpUserArg, DWORD dwOffset); + /* dwflags for FindDevice */ #define D3DFDS_COLORMODEL 0x00000001 @@ -279,11 +449,61 @@ typedef float D3DVALUE,*LPD3DVALUE; #define D3DDivide(a, b) (float)((double) (a) / (double) (b)) #define D3DMultiply(a, b) ((a) * (b)) -#if 0 -/* This causes lots o' problems */ typedef struct { + DWORD dwFlags; /* Homogeneous clipping flags */ union { - D3DVALUE x; + D3DVALUE hx; + D3DVALUE dvHX; + } x; + union { + D3DVALUE hy; + D3DVALUE dvHY; + } y; + union { + D3DVALUE hz; + D3DVALUE dvHZ; + } z; +} D3DHVERTEX, *LPD3DHVERTEX; +/* + * Transformed/lit vertices + */ +typedef struct { + union { + D3DVALUE sx; /* Screen coordinates */ + D3DVALUE dvSX; + } x; + union { + D3DVALUE sy; + D3DVALUE dvSY; + } y; + union { + D3DVALUE sz; + D3DVALUE dvSZ; + } z; + union { + D3DVALUE rhw; /* Reciprocal of homogeneous w */ + D3DVALUE dvRHW; + } r; + union { + D3DCOLOR color; /* Vertex color */ + D3DCOLOR dcColor; + } c; + union { + D3DCOLOR specular; /* Specular component of vertex */ + D3DCOLOR dcSpecular; + } s; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + } u; + union { + D3DVALUE tv; + D3DVALUE dvTV; + } v; +} D3DTLVERTEX, *LPD3DTLVERTEX; +typedef struct { + union { + D3DVALUE x; /* Homogeneous coordinates */ D3DVALUE dvX; } x; union { @@ -294,23 +514,100 @@ typedef struct { D3DVALUE z; D3DVALUE dvZ; } z; - /* the c++ variant has operator overloads etc. too */ -} D3DVECTOR,*LPD3DVECTOR; -#endif + DWORD dwReserved; + union { + D3DCOLOR color; /* Vertex color */ + D3DCOLOR dcColor; + } c; + union { + D3DCOLOR specular; /* Specular component of vertex */ + D3DCOLOR dcSpecular; + } s; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + } u; + union { + D3DVALUE tv; + D3DVALUE dvTV; + } v; +} D3DLVERTEX, *LPD3DLVERTEX; +typedef struct { + union { + D3DVALUE x; /* Homogeneous coordinates */ + D3DVALUE dvX; + } x; + union { + D3DVALUE y; + D3DVALUE dvY; + } y; + union { + D3DVALUE z; + D3DVALUE dvZ; + } z; + union { + D3DVALUE nx; /* Normal */ + D3DVALUE dvNX; + } nx; + union { + D3DVALUE ny; + D3DVALUE dvNY; + } ny; + union { + D3DVALUE nz; + D3DVALUE dvNZ; + } nz; + union { + D3DVALUE tu; /* Texture coordinates */ + D3DVALUE dvTU; + } u; + union { + D3DVALUE tv; + D3DVALUE dvTV; + } v; +} D3DVERTEX, *LPD3DVERTEX; -typedef struct _D3DVECTOR { +typedef struct { + union { + LONG x1; + LONG lX1; + } x1; + union { + LONG y1; + LONG lY1; + } y1; + union { + LONG x2; + LONG lX2; + } x2; + union { + LONG y2; + LONG lY2; + } y2; +} D3DRECT, *LPD3DRECT; + +typedef struct { + union { D3DVALUE x; + D3DVALUE dvX; + } x; + union { D3DVALUE y; + D3DVALUE dvY; + } y; + union { D3DVALUE z; + D3DVALUE dvZ; + } z; + /* the c++ variant has operator overloads etc. too */ } D3DVECTOR,*LPD3DVECTOR; -typedef enum { - D3DLIGHT_POINT = 1, - D3DLIGHT_SPOT = 2, - D3DLIGHT_DIRECTIONAL = 3, - D3DLIGHT_PARALLELPOINT = 4, - D3DLIGHT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ -} D3DLIGHTTYPE; +typedef struct { + D3DVALUE _11, _12, _13, _14; + D3DVALUE _21, _22, _23, _24; + D3DVALUE _31, _32, _33, _34; + D3DVALUE _41, _42, _43, _44; +} D3DMATRIX, *LPD3DMATRIX; typedef struct _D3DCOLORVALUE { union { @@ -350,7 +647,370 @@ typedef struct { #define D3DLIGHT_ACTIVE 0x00000001 #define D3DLIGHT_NO_SPECULAR 0x00000002 +/* Textures */ +typedef HRESULT (CALLBACK* LPD3DENUMTEXTUREFORMATSCALLBACK)(LPDDSURFACEDESC lpDdsd, LPVOID lpContext); + +/* Statistics structure */ +typedef struct { + DWORD dwSize; + DWORD dwTrianglesDrawn; + DWORD dwLinesDrawn; + DWORD dwPointsDrawn; + DWORD dwSpansDrawn; + DWORD dwVerticesProcessed; +} D3DSTATS, *LPD3DSTATS; + +/* Clipping */ +typedef struct _D3DCLIPSTATUS { + DWORD dwFlags; /* Do we set 2d extents, 3D extents or status */ + DWORD dwStatus; /* Clip status */ + float minx, maxx; /* X extents */ + float miny, maxy; /* Y extents */ + float minz, maxz; /* Z extents */ +} D3DCLIPSTATUS, *LPD3DCLIPSTATUS; + +typedef struct { + DWORD dwSize; + union { + D3DCOLORVALUE diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE dcvDiffuse; + } a; + union { + D3DCOLORVALUE ambient; /* Ambient color RGB */ + D3DCOLORVALUE dcvAmbient; + } b; + union { + D3DCOLORVALUE specular; /* Specular 'shininess' */ + D3DCOLORVALUE dcvSpecular; + } c; + union { + D3DCOLORVALUE emissive; /* Emissive color RGB */ + D3DCOLORVALUE dcvEmissive; + } d; + union { + D3DVALUE power; /* Sharpness if specular highlight */ + D3DVALUE dvPower; + } e; + D3DTEXTUREHANDLE hTexture; /* Handle to texture map */ + DWORD dwRampSize; +} D3DMATERIAL, *LPD3DMATERIAL; + +typedef struct { + D3DVECTOR dvPosition; /* Lightable point in model space */ + D3DVECTOR dvNormal; /* Normalised unit vector */ +} D3DLIGHTINGELEMENT, *LPD3DLIGHTINGELEMENT; + +typedef struct { + DWORD dwSize; + DWORD dwX; + DWORD dwY; /* Top left */ + DWORD dwWidth; + DWORD dwHeight; /* Dimensions */ + D3DVALUE dvScaleX; /* Scale homogeneous to screen */ + D3DVALUE dvScaleY; /* Scale homogeneous to screen */ + D3DVALUE dvMaxX; /* Min/max homogeneous x coord */ + D3DVALUE dvMaxY; /* Min/max homogeneous y coord */ + D3DVALUE dvMinZ; + D3DVALUE dvMaxZ; /* Min/max homogeneous z coord */ +} D3DVIEWPORT, *LPD3DVIEWPORT; + +typedef struct { + DWORD dwSize; + DWORD dwX; + DWORD dwY; /* Viewport Top left */ + DWORD dwWidth; + DWORD dwHeight; /* Viewport Dimensions */ + D3DVALUE dvClipX; /* Top left of clip volume */ + D3DVALUE dvClipY; + D3DVALUE dvClipWidth; /* Clip Volume Dimensions */ + D3DVALUE dvClipHeight; + D3DVALUE dvMinZ; /* Min/max of clip Volume */ + D3DVALUE dvMaxZ; +} D3DVIEWPORT2, *LPD3DVIEWPORT2; + +#define D3DTRANSFORM_CLIPPED 0x00000001l +#define D3DTRANSFORM_UNCLIPPED 0x00000002l + +typedef struct { + DWORD dwSize; + LPVOID lpIn; /* Input vertices */ + DWORD dwInSize; /* Stride of input vertices */ + LPVOID lpOut; /* Output vertices */ + DWORD dwOutSize; /* Stride of output vertices */ + LPD3DHVERTEX lpHOut; /* Output homogeneous vertices */ + DWORD dwClip; /* Clipping hint */ + DWORD dwClipIntersection; + DWORD dwClipUnion; /* Union of all clip flags */ + D3DRECT drExtent; /* Extent of transformed vertices */ +} D3DTRANSFORMDATA, *LPD3DTRANSFORMDATA; + +/* flags bits */ +#define D3DLIGHT_ACTIVE 0x00000001 +#define D3DLIGHT_NO_SPECULAR 0x00000002 + +/* maximum valid light range */ +#define D3DLIGHT_RANGE_MAX ((float)sqrt(FLT_MAX)) + +typedef struct _D3DLIGHT2 { + DWORD dwSize; + D3DLIGHTTYPE dltType; /* Type of light source */ + D3DCOLORVALUE dcvColor; /* Color of light */ + D3DVECTOR dvPosition; /* Position in world space */ + D3DVECTOR dvDirection; /* Direction in world space */ + D3DVALUE dvRange; /* Cutoff range */ + D3DVALUE dvFalloff; /* Falloff */ + D3DVALUE dvAttenuation0; /* Constant attenuation */ + D3DVALUE dvAttenuation1; /* Linear attenuation */ + D3DVALUE dvAttenuation2; /* Quadratic attenuation */ + D3DVALUE dvTheta; /* Inner angle of spotlight cone */ + D3DVALUE dvPhi; /* Outer angle of spotlight cone */ + DWORD dwFlags; +} D3DLIGHT2, *LPD3DLIGHT2; + +typedef struct _D3DLIGHTDATA { + DWORD dwSize; + LPD3DLIGHTINGELEMENT lpIn; /* Input positions and normals */ + DWORD dwInSize; /* Stride of input elements */ + LPD3DTLVERTEX lpOut; /* Output colors */ + DWORD dwOutSize; /* Stride of output colors */ +} D3DLIGHTDATA, *LPD3DLIGHTDATA; + +typedef struct _D3DPICKRECORD { + BYTE bOpcode; + BYTE bPad; + DWORD dwOffset; + D3DVALUE dvZ; +} D3DPICKRECORD, *LPD3DPICKRECORD; + + +typedef struct _D3DExecuteBufferDesc { + DWORD dwSize; + DWORD dwFlags; + DWORD dwCaps; + DWORD dwBufferSize; + LPVOID lpData; +} D3DEXECUTEBUFFERDESC; +typedef D3DEXECUTEBUFFERDESC *LPD3DEXECUTEBUFFERDESC; + +#define D3DDEB_BUFSIZE 0x00000001l /* buffer size valid */ +#define D3DDEB_CAPS 0x00000002l /* caps valid */ +#define D3DDEB_LPDATA 0x00000004l /* lpData valid */ + +#define D3DDEBCAPS_SYSTEMMEMORY 0x00000001l /* buffer in system memory */ +#define D3DDEBCAPS_VIDEOMEMORY 0x00000002l /* buffer in device memory */ +#define D3DDEBCAPS_MEM (D3DDEBCAPS_SYSTEMMEMORY|D3DDEBCAPS_VIDEOMEMORY) + +/* + * Values for d3d status. + */ +#define D3DSTATUS_CLIPUNIONLEFT D3DCLIP_LEFT +#define D3DSTATUS_CLIPUNIONRIGHT D3DCLIP_RIGHT +#define D3DSTATUS_CLIPUNIONTOP D3DCLIP_TOP +#define D3DSTATUS_CLIPUNIONBOTTOM D3DCLIP_BOTTOM +#define D3DSTATUS_CLIPUNIONFRONT D3DCLIP_FRONT +#define D3DSTATUS_CLIPUNIONBACK D3DCLIP_BACK +#define D3DSTATUS_CLIPUNIONGEN0 D3DCLIP_GEN0 +#define D3DSTATUS_CLIPUNIONGEN1 D3DCLIP_GEN1 +#define D3DSTATUS_CLIPUNIONGEN2 D3DCLIP_GEN2 +#define D3DSTATUS_CLIPUNIONGEN3 D3DCLIP_GEN3 +#define D3DSTATUS_CLIPUNIONGEN4 D3DCLIP_GEN4 +#define D3DSTATUS_CLIPUNIONGEN5 D3DCLIP_GEN5 + +#define D3DSTATUS_CLIPINTERSECTIONLEFT 0x00001000L +#define D3DSTATUS_CLIPINTERSECTIONRIGHT 0x00002000L +#define D3DSTATUS_CLIPINTERSECTIONTOP 0x00004000L +#define D3DSTATUS_CLIPINTERSECTIONBOTTOM 0x00008000L +#define D3DSTATUS_CLIPINTERSECTIONFRONT 0x00010000L +#define D3DSTATUS_CLIPINTERSECTIONBACK 0x00020000L +#define D3DSTATUS_CLIPINTERSECTIONGEN0 0x00040000L +#define D3DSTATUS_CLIPINTERSECTIONGEN1 0x00080000L +#define D3DSTATUS_CLIPINTERSECTIONGEN2 0x00100000L +#define D3DSTATUS_CLIPINTERSECTIONGEN3 0x00200000L +#define D3DSTATUS_CLIPINTERSECTIONGEN4 0x00400000L +#define D3DSTATUS_CLIPINTERSECTIONGEN5 0x00800000L +#define D3DSTATUS_ZNOTVISIBLE 0x01000000L + +#define D3DSTATUS_CLIPUNIONALL ( \ + D3DSTATUS_CLIPUNIONLEFT | \ + D3DSTATUS_CLIPUNIONRIGHT | \ + D3DSTATUS_CLIPUNIONTOP | \ + D3DSTATUS_CLIPUNIONBOTTOM | \ + D3DSTATUS_CLIPUNIONFRONT | \ + D3DSTATUS_CLIPUNIONBACK | \ + D3DSTATUS_CLIPUNIONGEN0 | \ + D3DSTATUS_CLIPUNIONGEN1 | \ + D3DSTATUS_CLIPUNIONGEN2 | \ + D3DSTATUS_CLIPUNIONGEN3 | \ + D3DSTATUS_CLIPUNIONGEN4 | \ + D3DSTATUS_CLIPUNIONGEN5 \ + ) + +#define D3DSTATUS_CLIPINTERSECTIONALL ( \ + D3DSTATUS_CLIPINTERSECTIONLEFT | \ + D3DSTATUS_CLIPINTERSECTIONRIGHT | \ + D3DSTATUS_CLIPINTERSECTIONTOP | \ + D3DSTATUS_CLIPINTERSECTIONBOTTOM | \ + D3DSTATUS_CLIPINTERSECTIONFRONT | \ + D3DSTATUS_CLIPINTERSECTIONBACK | \ + D3DSTATUS_CLIPINTERSECTIONGEN0 | \ + D3DSTATUS_CLIPINTERSECTIONGEN1 | \ + D3DSTATUS_CLIPINTERSECTIONGEN2 | \ + D3DSTATUS_CLIPINTERSECTIONGEN3 | \ + D3DSTATUS_CLIPINTERSECTIONGEN4 | \ + D3DSTATUS_CLIPINTERSECTIONGEN5 \ + ) + +#define D3DSTATUS_DEFAULT ( \ + D3DSTATUS_CLIPINTERSECTIONALL | \ + D3DSTATUS_ZNOTVISIBLE) + + +typedef struct _D3DSTATUS { + DWORD dwFlags; + DWORD dwStatus; + D3DRECT drExtent; +} D3DSTATUS, *LPD3DSTATUS; + + +typedef struct _D3DEXECUTEDATA { + DWORD dwSize; + DWORD dwVertexOffset; + DWORD dwVertexCount; + DWORD dwInstructionOffset; + DWORD dwInstructionLength; + DWORD dwHVertexOffset; + D3DSTATUS dsStatus; +} D3DEXECUTEDATA, *LPD3DEXECUTEDATA; + +typedef enum _D3DOPCODE { + D3DOP_POINT = 1, + D3DOP_LINE = 2, + D3DOP_TRIANGLE = 3, + D3DOP_MATRIXLOAD = 4, + D3DOP_MATRIXMULTIPLY = 5, + D3DOP_STATETRANSFORM = 6, + D3DOP_STATELIGHT = 7, + D3DOP_STATERENDER = 8, + D3DOP_PROCESSVERTICES = 9, + D3DOP_TEXTURELOAD = 10, + D3DOP_EXIT = 11, + D3DOP_BRANCHFORWARD = 12, + D3DOP_SPAN = 13, + D3DOP_SETSTATUS = 14, + + D3DOP_FORCE_DWORD = 0x7fffffff, +} D3DOPCODE; + +typedef struct _D3DPOINT { + WORD wCount; + WORD wFirst; +} D3DPOINT, *LPD3DPOINT; + +typedef struct _D3DLINE { + union { + WORD v1; + WORD wV1; + } v1; + union { + WORD v2; + WORD wV2; + } v2; +} D3DLINE, *LPD3DLINE; + +#define D3DTRIFLAG_START 0x00000000L +#define D3DTRIFLAG_STARTFLAT(len) (len) /* 0 < len < 30 */ +#define D3DTRIFLAG_ODD 0x0000001eL +#define D3DTRIFLAG_EVEN 0x0000001fL + +#define D3DTRIFLAG_EDGEENABLE1 0x00000100L /* v0-v1 edge */ +#define D3DTRIFLAG_EDGEENABLE2 0x00000200L /* v1-v2 edge */ +#define D3DTRIFLAG_EDGEENABLE3 0x00000400L /* v2-v0 edge */ +#define D3DTRIFLAG_EDGEENABLETRIANGLE \ + (D3DTRIFLAG_EDGEENABLE1 | D3DTRIFLAG_EDGEENABLE2 | D3DTRIFLAG_EDGEENABLE3) + +typedef struct _D3DTRIANGLE { + union { + WORD v1; + WORD wV1; + } v1; + union { + WORD v2; + WORD wV2; + } v2; + union { + WORD v3; + WORD wV3; + } v3; + WORD wFlags; +} D3DTRIANGLE, *LPD3DTRIANGLE; + +typedef struct _D3DMATRIXLOAD { + D3DMATRIXHANDLE hDestMatrix; + D3DMATRIXHANDLE hSrcMatrix; +} D3DMATRIXLOAD, *LPD3DMATRIXLOAD; + +typedef struct _D3DMATRIXMULTIPLY { + D3DMATRIXHANDLE hDestMatrix; + D3DMATRIXHANDLE hSrcMatrix1; + D3DMATRIXHANDLE hSrcMatrix2; +} D3DMATRIXMULTIPLY, *LPD3DMATRIXMULTIPLY; + +typedef struct _D3DSTATE { + union { + D3DTRANSFORMSTATETYPE dtstTransformStateType; + D3DLIGHTSTATETYPE dlstLightStateType; + D3DRENDERSTATETYPE drstRenderStateType; + } t; + union { + DWORD dwArg[1]; + D3DVALUE dvArg[1]; + } v; +} D3DSTATE, *LPD3DSTATE; + +#define D3DPROCESSVERTICES_TRANSFORMLIGHT 0x00000000L +#define D3DPROCESSVERTICES_TRANSFORM 0x00000001L +#define D3DPROCESSVERTICES_COPY 0x00000002L +#define D3DPROCESSVERTICES_OPMASK 0x00000007L + +#define D3DPROCESSVERTICES_UPDATEEXTENTS 0x00000008L +#define D3DPROCESSVERTICES_NOCOLOR 0x00000010L + +typedef struct _D3DPROCESSVERTICES { + DWORD dwFlags; + WORD wStart; + WORD wDest; + DWORD dwCount; + DWORD dwReserved; +} D3DPROCESSVERTICES, *LPD3DPROCESSVERTICES; + +typedef struct _D3DTEXTURELOAD { + D3DTEXTUREHANDLE hDestTexture; + D3DTEXTUREHANDLE hSrcTexture; +} D3DTEXTURELOAD, *LPD3DTEXTURELOAD; + +typedef struct _D3DBRANCH { + DWORD dwMask; + DWORD dwValue; + BOOL bNegate; + DWORD dwOffset; +} D3DBRANCH, *LPD3DBRANCH; + +typedef struct _D3DSPAN { + WORD wCount; + WORD wFirst; +} D3DSPAN, *LPD3DSPAN; + +typedef struct _D3DINSTRUCTION { + BYTE bOpcode; + BYTE bSize; + WORD wCount; +} D3DINSTRUCTION, *LPD3DINSTRUCTION; + + +/* ******************************************************************** + Direct3D + ******************************************************************** */ #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn) #define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn) #define PURE @@ -379,6 +1039,9 @@ struct IDirect3D { }; #undef THIS +/* ******************************************************************** + Direct3D2 + ******************************************************************** */ #define THIS LPDIRECT3D2 this typedef struct IDirect3D2_VTable { /*** IUnknown methods ***/ @@ -401,6 +1064,9 @@ struct IDirect3D2 { }; #undef THIS +/* ******************************************************************** + Direct3DLight + ******************************************************************** */ #define THIS LPDIRECT3DLIGHT this typedef struct IDirect3DLight_VTable { /*** IUnknown methods ***/ @@ -416,10 +1082,381 @@ typedef struct IDirect3DLight_VTable { struct IDirect3DLight { LPDIRECT3DLIGHT_VTABLE lpvtbl; DWORD ref; + + union { + LPDIRECT3D d3d; + LPDIRECT3D2 d3d2; + } d3d; + int type; + + D3DLIGHT2 light; + + /* Chained list used for adding / removing from viewports */ + LPDIRECT3DLIGHT next, prev; + + /* Activation function */ + void (*activate)(THIS); + int is_active; + + /* Awful OpenGL code !!! */ +#ifdef HAVE_MESAGL + GLenum light_num; +#endif }; #undef THIS +/* ******************************************************************** + Direct3DMaterial + ******************************************************************** */ +#define THIS LPDIRECT3DMATERIAL this +typedef struct IDirect3DMaterial_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DMaterial2 methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE; + STDMETHOD(SetMaterial) (THIS_ LPD3DMATERIAL) PURE; + STDMETHOD(GetMaterial) (THIS_ LPD3DMATERIAL) PURE; + STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DMATERIALHANDLE) PURE; + STDMETHOD_(HRESULT, Reserve) (THIS) PURE; + STDMETHOD_(HRESULT, Unreserve) (THIS) PURE; +} IDirect3DMaterial_VTable,*LPDIRECT3DMATERIAL_VTABLE; + +#undef THIS + + +/* ******************************************************************** + Direct3DMaterial2 + ******************************************************************** */ +#define THIS LPDIRECT3DMATERIAL2 this +typedef struct IDirect3DMaterial2_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DMaterial2 methods ***/ + STDMETHOD(SetMaterial) (THIS_ LPD3DMATERIAL) PURE; + STDMETHOD(GetMaterial) (THIS_ LPD3DMATERIAL) PURE; + STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DMATERIALHANDLE) PURE; +} IDirect3DMaterial2_VTable,*LPDIRECT3DMATERIAL2_VTABLE; + +struct IDirect3DMaterial2 { + LPDIRECT3DMATERIAL2_VTABLE lpvtbl; + DWORD ref; + + union { + LPDIRECT3D d3d1; + LPDIRECT3D2 d3d2; + } d3d; + union { + LPDIRECT3DDEVICE active_device1; + LPDIRECT3DDEVICE2 active_device2; + } device; + int use_d3d2; + + D3DMATERIAL mat; + + void (*activate)(LPDIRECT3DMATERIAL2 this); +}; + +#undef THIS + +/* ******************************************************************** + Direct3DTexture + ******************************************************************** */ +#define THIS LPDIRECT3DTEXTURE this +typedef struct IDirect3DTexture_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DTexture methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3DDEVICE, LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE) PURE; + STDMETHOD(PaletteChanged) (THIS_ DWORD, DWORD) PURE; + STDMETHOD(Load) (THIS_ LPDIRECT3DTEXTURE) PURE; + STDMETHOD_(HRESULT, Unload) (THIS) PURE; +} IDirect3DTexture_VTable,*LPDIRECT3DTEXTURE_VTABLE; + +/* The structure is the same as for Direct3DTexture2 */ + +#undef THIS + +/* ******************************************************************** + Direct3DTexture2 + ******************************************************************** */ +#define THIS LPDIRECT3DTEXTURE2 this +typedef struct IDirect3DTexture2_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DTexture2 methods ***/ + STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DTEXTUREHANDLE) PURE; + STDMETHOD(PaletteChanged) (THIS_ DWORD, DWORD) PURE; + STDMETHOD(Load) (THIS_ LPDIRECT3DTEXTURE2) PURE; +} IDirect3DTexture2_VTable,*LPDIRECT3DTEXTURE2_VTABLE; + +struct IDirect3DTexture2 { + LPDIRECT3DTEXTURE2_VTABLE lpvtbl; + DWORD ref; + + LPDIRECTDRAWSURFACE3 surface; +}; + +#undef THIS + + +/* ******************************************************************** + Direct3DViewport + ******************************************************************** */ +#define THIS LPDIRECT3DVIEWPORT this +typedef struct IDirect3Viewport_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DViewport methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE; + STDMETHOD(GetViewport) (THIS_ LPD3DVIEWPORT) PURE; + STDMETHOD(SetViewport) (THIS_ LPD3DVIEWPORT) PURE; + STDMETHOD(TransformVertices) (THIS_ DWORD, LPD3DTRANSFORMDATA, DWORD, LPDWORD) PURE; + STDMETHOD(LightElements) (THIS_ DWORD, LPD3DLIGHTDATA) PURE; + STDMETHOD(SetBackground) (THIS_ D3DMATERIALHANDLE) PURE; + STDMETHOD(GetBackground) (THIS_ LPD3DMATERIALHANDLE, LPBOOL) PURE; + STDMETHOD(SetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(GetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE*, LPBOOL) PURE; + STDMETHOD(Clear) (THIS_ DWORD, LPD3DRECT, DWORD) PURE; + STDMETHOD(AddLight) (THIS_ LPDIRECT3DLIGHT) PURE; + STDMETHOD(DeleteLight) (THIS_ LPDIRECT3DLIGHT) PURE; + STDMETHOD(NextLight) (THIS_ LPDIRECT3DLIGHT, LPDIRECT3DLIGHT*, DWORD) PURE; +} IDirect3DViewport_VTable,*LPDIRECT3DVIEWPORT_VTABLE; + +#undef THIS + + +/* ******************************************************************** + Direct3DViewport2 + ******************************************************************** */ +#define THIS LPDIRECT3DVIEWPORT2 this +typedef struct IDirect3Viewport2_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DViewport methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE; + STDMETHOD(GetViewport) (THIS_ LPD3DVIEWPORT) PURE; + STDMETHOD(SetViewport) (THIS_ LPD3DVIEWPORT) PURE; + STDMETHOD(TransformVertices) (THIS_ DWORD, LPD3DTRANSFORMDATA, DWORD, LPDWORD) PURE; + STDMETHOD(LightElements) (THIS_ DWORD, LPD3DLIGHTDATA) PURE; + STDMETHOD(SetBackground) (THIS_ D3DMATERIALHANDLE) PURE; + STDMETHOD(GetBackground) (THIS_ LPD3DMATERIALHANDLE, LPBOOL) PURE; + STDMETHOD(SetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(GetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE*, LPBOOL) PURE; + STDMETHOD(Clear) (THIS_ DWORD, LPD3DRECT, DWORD) PURE; + STDMETHOD(AddLight) (THIS_ LPDIRECT3DLIGHT) PURE; + STDMETHOD(DeleteLight) (THIS_ LPDIRECT3DLIGHT) PURE; + STDMETHOD(NextLight) (THIS_ LPDIRECT3DLIGHT, LPDIRECT3DLIGHT*, DWORD) PURE; + /*** IDirect3DViewport2 methods ***/ + STDMETHOD(GetViewport2) (THIS_ LPD3DVIEWPORT2) PURE; + STDMETHOD(SetViewport2) (THIS_ LPD3DVIEWPORT2) PURE; +} IDirect3DViewport2_VTable,*LPDIRECT3DVIEWPORT2_VTABLE; + +struct IDirect3DViewport2 { + LPDIRECT3DVIEWPORT2_VTABLE lpvtbl; + DWORD ref; + + union { + LPDIRECT3D d3d1; + LPDIRECT3D2 d3d2; + } d3d; + /* If this viewport is active for one device, put the device here */ + union { + LPDIRECT3DDEVICE active_device1; + LPDIRECT3DDEVICE2 active_device2; + } device; + int use_d3d2; + + union { + D3DVIEWPORT vp1; + D3DVIEWPORT2 vp2; + } viewport; + int use_vp2; + + /* Activation function */ + void (*activate)(THIS); + + /* Field used to chain viewports together */ + LPDIRECT3DVIEWPORT2 next; + + /* Lights list */ + LPDIRECT3DLIGHT lights; + + /* OpenGL code */ +#ifdef HAVE_MESAGL + GLenum nextlight; +#endif +}; + +#undef THIS + +/* ******************************************************************** + Direct3DExecuteBuffer + ******************************************************************** */ +#define THIS LPDIRECT3DEXECUTEBUFFER this +typedef struct IDirect3DExecuteBuffer_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DExecuteBuffer methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3DDEVICE, LPD3DEXECUTEBUFFERDESC) PURE; + STDMETHOD(Lock) (THIS_ LPD3DEXECUTEBUFFERDESC) PURE; + STDMETHOD_(HRESULT, Unlock) (THIS) PURE; + STDMETHOD(SetExecuteData) (THIS_ LPD3DEXECUTEDATA) PURE; + STDMETHOD(GetExecuteData) (THIS_ LPD3DEXECUTEDATA) PURE; + STDMETHOD(Validate) (THIS_ LPDWORD, LPD3DVALIDATECALLBACK, LPVOID, DWORD) PURE; + STDMETHOD(Optimize) (THIS_ DWORD) PURE; +} *LPDIRECT3DEXECUTEBUFFER_VTABLE,IDirect3DExecuteBuffer_VTable; + +struct IDirect3DExecuteBuffer { + LPDIRECT3DEXECUTEBUFFER_VTABLE lpvtbl; + DWORD ref; + + LPDIRECT3DDEVICE d3ddev; + + D3DEXECUTEBUFFERDESC desc; + D3DEXECUTEDATA data; + + /* This buffer will store the transformed vertices */ + D3DVERTEX *vertex_data; + + /* This flags is set to TRUE if we allocated ourselves the + data buffer */ + BOOL need_free; + + void (*execute)(LPDIRECT3DEXECUTEBUFFER this, + LPDIRECT3DDEVICE dev, + LPDIRECT3DVIEWPORT vp); +}; + +#undef THIS + +/* ******************************************************************** + Direct3DDevice + ******************************************************************** */ +#define THIS LPDIRECT3DDEVICE this +typedef struct IDirect3DDevice_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DDevice methods ***/ + STDMETHOD(Initialize) (THIS_ LPDIRECT3D, LPGUID, LPD3DDEVICEDESC) PURE; + STDMETHOD(GetCaps) (THIS_ LPD3DDEVICEDESC, LPD3DDEVICEDESC) PURE; + STDMETHOD(SwapTextureHandles) (THIS_ LPDIRECT3DTEXTURE, LPDIRECT3DTEXTURE) PURE; + STDMETHOD(CreateExecuteBuffer) (THIS_ LPD3DEXECUTEBUFFERDESC, LPDIRECT3DEXECUTEBUFFER*, IUnknown*) PURE; + STDMETHOD(GetStats) (THIS_ LPD3DSTATS) PURE; + STDMETHOD(Execute) (THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD) PURE; + STDMETHOD(AddViewport) (THIS_ LPDIRECT3DVIEWPORT) PURE; + STDMETHOD(DeleteViewport) (THIS_ LPDIRECT3DVIEWPORT) PURE; + STDMETHOD(NextViewport) (THIS_ LPDIRECT3DVIEWPORT, LPDIRECT3DVIEWPORT*, DWORD) PURE; + STDMETHOD(Pick) (THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD, LPD3DRECT) PURE; + STDMETHOD(GetPickRecords)(THIS_ LPDWORD, LPD3DPICKRECORD) PURE; + STDMETHOD(EnumTextureFormats) (THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK, LPVOID) PURE; + STDMETHOD(CreateMatrix) (THIS_ LPD3DMATRIXHANDLE) PURE; + STDMETHOD(SetMatrix) (THIS_ D3DMATRIXHANDLE, const LPD3DMATRIX) PURE; + STDMETHOD(GetMatrix) (THIS_ D3DMATRIXHANDLE, LPD3DMATRIX) PURE; + STDMETHOD(DeleteMatrix) (THIS_ D3DMATRIXHANDLE) PURE; + STDMETHOD_(HRESULT, BeginScene) (THIS) PURE; + STDMETHOD_(HRESULT, EndScene) (THIS) PURE; + STDMETHOD(GetDirect3D) (THIS_ LPDIRECT3D*) PURE; +} *LPDIRECT3DDEVICE_VTABLE,IDirect3DDevice_VTable; + +struct IDirect3DDevice { + /* This are the fields common to all Direct3DDevice implementations */ + LPDIRECT3DDEVICE_VTABLE lpvtbl; + DWORD ref; + + LPDIRECT3D d3d; + LPDIRECTDRAWSURFACE surface; + + LPDIRECT3DVIEWPORT viewport_list; + LPDIRECT3DVIEWPORT current_viewport; + + void (*set_context)(THIS) ; +}; + +#undef THIS + +/* ******************************************************************** + Direct3DDevice2 + ******************************************************************** */ +#define THIS LPDIRECT3DDEVICE2 this +typedef struct IDirect3DDevice2_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + /*** IDirect3DDevice2 methods ***/ + STDMETHOD(GetCaps) (THIS_ LPD3DDEVICEDESC, LPD3DDEVICEDESC) PURE; + STDMETHOD(SwapTextureHandles) (THIS_ LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2) PURE; + STDMETHOD(GetStats) (THIS_ LPD3DSTATS) PURE; + STDMETHOD(AddViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE; + STDMETHOD(DeleteViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE; + STDMETHOD(NextViewport) (THIS_ LPDIRECT3DVIEWPORT2, LPDIRECT3DVIEWPORT2*, DWORD) PURE; + STDMETHOD(EnumTextureFormats) (THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK, LPVOID) PURE; + STDMETHOD_(HRESULT, BeginScene) (THIS) PURE; + STDMETHOD_(HRESULT, EndScene) (THIS) PURE; + STDMETHOD(GetDirect3D) (THIS_ LPDIRECT3D2*) PURE; + + /*** DrawPrimitive API ***/ + STDMETHOD(SetCurrentViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE; + STDMETHOD(GetCurrentViewport) (THIS_ LPDIRECT3DVIEWPORT2 *) PURE; + + STDMETHOD(SetRenderTarget) (THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE; + STDMETHOD(GetRenderTarget) (THIS_ LPDIRECTDRAWSURFACE *) PURE; + + STDMETHOD(Begin) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, DWORD) PURE; + STDMETHOD(BeginIndexed) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, DWORD) PURE; + STDMETHOD(Vertex) (THIS_ LPVOID) PURE; + STDMETHOD(Index) (THIS_ WORD) PURE; + STDMETHOD(End) (THIS_ DWORD) PURE; + + STDMETHOD(GetRenderState) (THIS_ D3DRENDERSTATETYPE, LPDWORD) PURE; + STDMETHOD(SetRenderState) (THIS_ D3DRENDERSTATETYPE, DWORD) PURE; + STDMETHOD(GetLightState) (THIS_ D3DLIGHTSTATETYPE, LPDWORD) PURE; + STDMETHOD(SetLightState) (THIS_ D3DLIGHTSTATETYPE, DWORD) PURE; + STDMETHOD(SetTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE; + STDMETHOD(GetTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE; + STDMETHOD(MultiplyTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE; + + STDMETHOD(DrawPrimitive) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, DWORD) PURE; + STDMETHOD(DrawIndexedPrimitive) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, LPWORD, DWORD, DWORD) PURE; + + STDMETHOD(SetClipStatus) (THIS_ LPD3DCLIPSTATUS) PURE; + STDMETHOD(GetClipStatus) (THIS_ LPD3DCLIPSTATUS) PURE; +} *LPDIRECT3DDEVICE2_VTABLE,IDirect3DDevice2_VTable; + +struct IDirect3DDevice2 { + /* This are the fields common to all Direct3DDevice2 implementations */ + LPDIRECT3DDEVICE2_VTABLE lpvtbl; + DWORD ref; + + LPDIRECT3D2 d3d; + LPDIRECTDRAWSURFACE surface; + + LPDIRECT3DVIEWPORT2 viewport_list; + LPDIRECT3DVIEWPORT2 current_viewport; + + void (*set_context)(THIS) ; +}; +#undef THIS + + #undef THIS_ #undef STDMETHOD #undef STDMETHOD_ diff --git a/include/wine_gl.h b/include/wine_gl.h new file mode 100644 index 00000000000..3fc7c9c9a09 --- /dev/null +++ b/include/wine_gl.h @@ -0,0 +1,32 @@ +/* Wrapper for OpenGL includes... + Copyright 1998 - Lionel Ulmer + + This wrapper is needed because Mesa uses also the CALLBACK / WINAPI + constants. */ + +#ifndef __WINE_GL_H +#define __WINE_GL_H + +#ifdef HAVE_MESAGL + +#undef APIENTRY +#undef CALLBACK +#undef WINAPI + +#include +/* These will need to have some #ifdef / #endif added to support + more than the X11 using OSMesa target */ +#include + +#undef APIENTRY +#undef CALLBACK +#undef WINAPI + +/* Redefines the constants */ +#define CALLBACK __stdcall +#define WINAPI __stdcall +#define APIENTRY WINAPI + +#endif /* HAVE_MESAGL */ + +#endif /* __WINE_GL_H */ diff --git a/multimedia/dsound.c b/multimedia/dsound.c index 1b5fb0f7701..e37a5727937 100644 --- a/multimedia/dsound.c +++ b/multimedia/dsound.c @@ -1211,17 +1211,17 @@ static HRESULT WINAPI IDirectSound_CreateSoundBuffer( ds3db->lpvtbl = &ds3dbvt; (*ppdsb)->ds3db = ds3db; ds3db->ds3db.dwSize = sizeof(DS3DBUFFER); - ds3db->ds3db.vPosition.x = 0.0; - ds3db->ds3db.vPosition.y = 0.0; - ds3db->ds3db.vPosition.z = 0.0; - ds3db->ds3db.vVelocity.x = 0.0; - ds3db->ds3db.vVelocity.y = 0.0; - ds3db->ds3db.vVelocity.z = 0.0; + ds3db->ds3db.vPosition.x.x = 0.0; + ds3db->ds3db.vPosition.y.y = 0.0; + ds3db->ds3db.vPosition.z.z = 0.0; + ds3db->ds3db.vVelocity.x.x = 0.0; + ds3db->ds3db.vVelocity.y.y = 0.0; + ds3db->ds3db.vVelocity.z.z = 0.0; ds3db->ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE; ds3db->ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE; - ds3db->ds3db.vConeOrientation.x = 0.0; - ds3db->ds3db.vConeOrientation.y = 0.0; - ds3db->ds3db.vConeOrientation.z = 0.0; + ds3db->ds3db.vConeOrientation.x.x = 0.0; + ds3db->ds3db.vConeOrientation.y.y = 0.0; + ds3db->ds3db.vConeOrientation.z.z = 0.0; ds3db->ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME; ds3db->ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE; ds3db->ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE; @@ -1355,18 +1355,18 @@ static HRESULT WINAPI IDirectSound_QueryInterface( this->listener->lpvtbl = &ds3dlvt; this->lpvtbl->fnAddRef(this); this->listener->ds3dl.dwSize = sizeof(DS3DLISTENER); - this->listener->ds3dl.vPosition.x = 0.0; - this->listener->ds3dl.vPosition.y = 0.0; - this->listener->ds3dl.vPosition.z = 0.0; - this->listener->ds3dl.vVelocity.x = 0.0; - this->listener->ds3dl.vVelocity.y = 0.0; - this->listener->ds3dl.vVelocity.z = 0.0; - this->listener->ds3dl.vOrientFront.x = 0.0; - this->listener->ds3dl.vOrientFront.y = 0.0; - this->listener->ds3dl.vOrientFront.z = 1.0; - this->listener->ds3dl.vOrientTop.x = 0.0; - this->listener->ds3dl.vOrientTop.y = 1.0; - this->listener->ds3dl.vOrientTop.z = 0.0; + this->listener->ds3dl.vPosition.x.x = 0.0; + this->listener->ds3dl.vPosition.y.y = 0.0; + this->listener->ds3dl.vPosition.z.z = 0.0; + this->listener->ds3dl.vVelocity.x.x = 0.0; + this->listener->ds3dl.vVelocity.y.y = 0.0; + this->listener->ds3dl.vVelocity.z.z = 0.0; + this->listener->ds3dl.vOrientFront.x.x = 0.0; + this->listener->ds3dl.vOrientFront.y.y = 0.0; + this->listener->ds3dl.vOrientFront.z.z = 1.0; + this->listener->ds3dl.vOrientTop.x.x = 0.0; + this->listener->ds3dl.vOrientTop.y.y = 1.0; + this->listener->ds3dl.vOrientTop.z.z = 0.0; this->listener->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR; this->listener->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR; this->listener->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;