diff --git a/configure.in b/configure.in index bb29302..353b911 100644 --- a/configure.in +++ b/configure.in @@ -99,6 +99,15 @@ AC_CHECK_HEADER(Evas_Engine_Software_DDraw.h, [ #include ] ) +have_d3d="no" +AC_CHECK_HEADER(Evas_Engine_Direct3D.h, + [ AC_DEFINE(HAVE_DIRECT3D, 1, [Evas Direct3D Engine Support]) + have_d3d="yes" + d3d_libs="-ld3d9 -ld3dx9d" ], + [ dummy=no ], + [ #include ] +) + if test "x$have_xlib" = "xyes" -o "x$have_xlib_16" = "xyes" -o "x$have_xlib_render" = "xyes" -o "x$have_xlib_opengl" = "xyes" ; then AC_PATH_XTRA x_dir=${x_dir:-/usr/X11R6} @@ -109,6 +118,7 @@ fi AC_SUBST(x_cflags) AC_SUBST(x_libs) AC_SUBST(ddraw_libs) +AC_SUBST(d3d_libs) AC_SUBST(glew_libs) ####################################### @@ -157,6 +167,7 @@ echo " X Render Xlib...........: ${have_xlib_render}" echo " Open GL Glew............: ${have_glew_opengl}" echo " Open GL Xlib............: ${have_xlib_opengl}" echo " Software DirectDraw.....: ${have_ddraw}" +echo " Direct3D................: ${have_d3d}" echo " Software SDL............: ${have_sdl}" echo echo " Installation:" diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index e1ac1ce..cc8a4c3 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -17,6 +17,7 @@ engine_gl_x11.c engine_gl_x11.h \ engine_xrender_x11.c engine_xrender_x11.h \ engine_software_16_x11.c engine_software_16_x11.h \ engine_software_ddraw.c engine_software_ddraw.h \ +engine_direct3d.cpp engine_direct3d.h \ engine_software_sdl.c engine_software_sdl.h \ ui.c ui.h \ about.c about.h \ @@ -60,4 +61,4 @@ image_blend_occlude2_very_many.c \ image_blend_occlude3_very_many.c \ poly_blend.c -expedite_LDFLAGS = @EVAS_LIBS@ @sdl_libs@ @x_libs@ @ddraw_libs@ @glew_libs@ -lm +expedite_LDFLAGS = @EVAS_LIBS@ @sdl_libs@ @x_libs@ @ddraw_libs@ @d3d_libs@ @glew_libs@ -lm diff --git a/src/bin/engine_direct3d.cpp b/src/bin/engine_direct3d.cpp new file mode 100644 index 0000000..1d219e3 --- /dev/null +++ b/src/bin/engine_direct3d.cpp @@ -0,0 +1,392 @@ +#include "main.h" + + +#ifndef HAVE_DIRECT3D + + +extern "C" { + +int +engine_direct3d_args(int argc, char **argv) +{ + fprintf(stderr, "ERROR: No Direct3D Engine built\n"); + return 0; +} + +void +engine_direct3d_loop(void) +{ +} + +} + +#else +# include +# include + + +static HWND window; + + +extern "C" { + +static int +_direct3d_init (HWND window, + int width, + int height, + LPDIRECT3D9 *object, + LPDIRECT3DDEVICE9 *device, + LPD3DXSPRITE *sprite, + LPDIRECT3DTEXTURE9 *texture, + int *depth) +{ + D3DPRESENT_PARAMETERS pp; + D3DDISPLAYMODE dm; + D3DSURFACE_DESC sd; + D3DCAPS9 caps; + DWORD flag; + + *object = Direct3DCreate9 (D3D_SDK_VERSION); + if (!*object) + goto no_object; + + if (FAILED ((*object)->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, &dm))) + goto no_device; + + if (FAILED ((*object)->GetDeviceCaps (D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + &caps))) + goto no_device; + + flag = (caps.VertexProcessingCaps != 0) + ? D3DCREATE_HARDWARE_VERTEXPROCESSING + : D3DCREATE_SOFTWARE_VERTEXPROCESSING; + + ZeroMemory(&pp, sizeof(pp)); + pp.BackBufferWidth = width; + pp.BackBufferHeight = height; + pp.BackBufferFormat = dm.Format; + pp.BackBufferCount = 1; + pp.MultiSampleType = D3DMULTISAMPLE_NONE; + pp.MultiSampleQuality = 0; + pp.SwapEffect = D3DSWAPEFFECT_FLIP; + pp.hDeviceWindow = window; + pp.Windowed = TRUE; + pp.EnableAutoDepthStencil = FALSE; + pp.FullScreen_RefreshRateInHz = 0; + pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + if (FAILED((*object)->CreateDevice (D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + window, + flag, + &pp, + device))) + goto no_device; + + if (FAILED (D3DXCreateSprite (*device, sprite))) + goto no_sprite; + + if (FAILED ((*device)->CreateTexture (width, height, 1, + D3DUSAGE_DYNAMIC, + dm.Format, + D3DPOOL_DEFAULT, + texture, NULL))) + goto no_texture; + + if (FAILED ((*texture)->GetLevelDesc (0, &sd))) + goto no_level_desc; + + switch (sd.Format) { + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + *depth = 32; + break; + case D3DFMT_R5G6B5: + *depth = 16; + break; + default: + goto no_level_desc; + } + + return 1; + + no_level_desc: + (*texture)->Release (); + no_texture: + (*sprite)->Release (); + no_sprite: + (*device)->Release (); + no_device: + (*object)->Release (); + no_object: + return 0; +} + +static LRESULT CALLBACK +MainWndProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + return 0; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + case WM_CLOSE: + PostQuitMessage(0); + return 0; + case WM_PAINT: { + PAINTSTRUCT ps; + HDC hdc; + + hdc = BeginPaint (window, &ps); + EndPaint(window, &ps); + evas_damage_rectangle_add(evas, + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top); + return 0; + } + case WM_SIZING: + { + PRECT rect = (PRECT)lParam; + + evas_output_size_set(evas, + rect->right - rect->left, + rect->bottom - rect->top); + return 0; + } + case WM_RBUTTONDOWN: + evas_event_feed_mouse_move(evas, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, NULL); + evas_event_feed_mouse_down(evas, 3, EVAS_BUTTON_NONE, 0, NULL); + return 0; + case WM_LBUTTONDOWN: + evas_event_feed_mouse_move(evas, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, NULL); + evas_event_feed_mouse_down(evas, 1, EVAS_BUTTON_NONE, 0, NULL); + return 0; + case WM_LBUTTONUP: + evas_event_feed_mouse_move(evas, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, NULL); + evas_event_feed_mouse_up(evas, 1, EVAS_BUTTON_NONE, 0, NULL); + return 0; + case WM_RBUTTONUP: + evas_event_feed_mouse_move(evas, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, NULL); + evas_event_feed_mouse_up(evas, 3, EVAS_BUTTON_NONE, 0, NULL); + return 0; + case WM_MOUSEMOVE: + if (!evas_pointer_inside_get(evas)) evas_event_feed_mouse_in(evas, 0, NULL); + evas_event_feed_mouse_move(evas, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, NULL); + return 0; + case WM_MOUSELEAVE: + evas_event_feed_mouse_out(evas, 0, NULL); + return 0; + /* FIXME : can't find an event when the mouse is entering */ + case WM_KEYDOWN: + case WM_SYSKEYDOWN: { + int key; + + key = LOWORD(wParam); + + if ((key == VK_SHIFT) || + (key == VK_LSHIFT) || + (key == VK_RSHIFT)) + evas_key_modifier_on(evas, "Shift"); + if ((key == VK_CONTROL) || + (key == VK_LCONTROL) || + (key == VK_RCONTROL)) + evas_key_modifier_on(evas, "Control"); + if ((key == VK_MENU) || + (key == VK_LMENU) || + (key == VK_RMENU)) + evas_key_modifier_on(evas, "Alt"); + if ((key == VK_LWIN) || + (key == VK_RWIN)) + evas_key_modifier_on(evas, "Super"); + + if (key == VK_CAPITAL) + { + if (evas_key_lock_is_set(evas_key_lock_get(evas), "Caps_Lock")) + evas_key_lock_off(evas, "Caps_Lock"); + else + evas_key_lock_on(evas, "Caps_Lock"); + } + if (key == VK_NUMLOCK) + { + if (evas_key_lock_is_set(evas_key_lock_get(evas), "Num_Lock")) + evas_key_lock_off(evas, "Num_Lock"); + else + evas_key_lock_on(evas, "Num_Lock"); + } + if (key == VK_SCROLL) + { + if (evas_key_lock_is_set(evas_key_lock_get(evas), "Scroll_Lock")) + evas_key_lock_off(evas, "Scroll_Lock"); + else + evas_key_lock_on(evas, "Scroll_Lock"); + } + if (key == VK_ESCAPE) + evas_event_feed_key_down(evas, "Escape", "Escape", NULL, NULL, 0, NULL); + if (key == VK_RETURN) + evas_event_feed_key_down(evas, "Return", "Return", NULL, NULL, 0, NULL); + if (key == VK_LEFT) + evas_event_feed_key_down(evas, "Left", "Left", NULL, NULL, 0, NULL); + if (key == VK_RIGHT) + evas_event_feed_key_down(evas, "Right", "Right", NULL, NULL, 0, NULL); + if (key == 81) + evas_event_feed_key_down(evas, "Q", "Q", NULL, NULL, 0, NULL); + if (key == 113) + evas_event_feed_key_down(evas, "q", "q", NULL, NULL, 0, NULL); + return 0; + } + case WM_KEYUP: + case WM_SYSKEYUP: { + int key; + + key = LOWORD(wParam); + + if ((key == VK_SHIFT) || + (key == VK_LSHIFT) || + (key == VK_RSHIFT)) + evas_key_modifier_off(evas, "Shift"); + if ((key == VK_CONTROL) || + (key == VK_LCONTROL) || + (key == VK_RCONTROL)) + evas_key_modifier_off(evas, "Control"); + if ((key == VK_MENU) || + (key == VK_LMENU) || + (key == VK_RMENU)) + evas_key_modifier_off(evas, "Alt"); + if ((key == VK_LWIN) || + (key == VK_RWIN)) + evas_key_modifier_off(evas, "Super"); + if (key == VK_ESCAPE) + evas_event_feed_key_up(evas, "Escape", "Escape", NULL, NULL, 0, NULL); + if (key == VK_RETURN) + evas_event_feed_key_up(evas, "Return", "Return", NULL, NULL, 0, NULL); + if (key == VK_LEFT) + evas_event_feed_key_up(evas, "Left", "Left", NULL, NULL, 0, NULL); + if (key == VK_RIGHT) + evas_event_feed_key_up(evas, "Right", "Right", NULL, NULL, 0, NULL); + if (key == 81) + evas_event_feed_key_up(evas, "Q", "Q", NULL, NULL, 0, NULL); + if (key == 113) + evas_event_feed_key_up(evas, "q", "q", NULL, NULL, 0, NULL); + return 0; + } + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } +} + +int +engine_direct3d_args(int argc, char **argv) +{ + WNDCLASS wc; + RECT rect; + HINSTANCE hinstance; + MSG msg; + LPDIRECT3D9 object; + LPDIRECT3DDEVICE9 device; + LPD3DXSPRITE sprite; + LPDIRECT3DTEXTURE9 texture; + Evas_Engine_Info_Direct3D *einfo; + int depth; + int i; + int ok = 0; + + for (i = 1; i < argc; i++) + { + if ((!strcmp(argv[i], "-e")) && (i < (argc - 1))) + { + i++; + if (!strcmp(argv[i], "direct3d")) ok = 1; + } + } + if (!ok) return 0; + + hinstance = GetModuleHandle(0); + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hinstance; + wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = "Evas_Direct3D_Test"; + + if(!RegisterClass(&wc)) return EXIT_FAILURE; + + rect.left = 0; + rect.top = 0; + rect.right = win_w; + rect.bottom = win_h; + AdjustWindowRect (&rect, WS_OVERLAPPEDWINDOW | WS_SIZEBOX, FALSE); + + window = CreateWindowEx(0, + "Evas_Direct3D_Test", + "Evas_Direct3D_Test", + WS_OVERLAPPEDWINDOW | WS_SIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, + rect.right - rect.left, rect.bottom - rect.top, + NULL, NULL, hinstance, NULL); + if (!window) return EXIT_FAILURE; + + if (!_direct3d_init(window, win_w, win_h, + &object, + &device, + &sprite, + &texture, + &depth)) + return 0; + + evas_output_method_set(evas, evas_render_method_lookup("direct3d")); + einfo = (Evas_Engine_Info_Direct3D *)evas_engine_info_get(evas); + if (!einfo) + { + printf("Evas does not support the Direct3D Engine\n"); + return 0; + } + + einfo->info.window = window; + einfo->info.object = object; + einfo->info.device = device; + einfo->info.sprite = sprite; + einfo->info.texture = texture; + einfo->info.depth = depth; + einfo->info.rotation = 0; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + + /* the second parameter is ignored, as it's the first call of ShowWindow */ + ShowWindow(window, SW_SHOWDEFAULT); + UpdateWindow(window); + + return 1; +} + +void +engine_direct3d_loop(void) +{ + MSG msg; + int res; + + again: + if (!PeekMessage (&msg, window, 0, 0, PM_NOREMOVE)) + return; + + res = GetMessage (&msg, NULL, 0, 0); + TranslateMessage (&msg); + DispatchMessage (&msg); + + goto again; +} + + +} + +#endif /* HAVE_DIRECT3D */ diff --git a/src/bin/engine_direct3d.h b/src/bin/engine_direct3d.h new file mode 100644 index 0000000..86bec74 --- /dev/null +++ b/src/bin/engine_direct3d.h @@ -0,0 +1,19 @@ +#ifndef __ENGINE_DIRECT3D_H__ +#define __ENGINE_DIRECT3D_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + +int engine_direct3d_args(int argc, char **argv); +void engine_direct3d_loop(void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* __ENGINE_DIRECT3D_H__ */ diff --git a/src/bin/main.c b/src/bin/main.c index 513b41a..1e6e53a 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -1058,6 +1058,7 @@ rnd(void) return (int)(((unsigned int)r1 << 16) | ((unsigned int)r2)); } +#ifndef _WIN32 double get_time(void) { @@ -1066,6 +1067,13 @@ get_time(void) gettimeofday(&timev, NULL); return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); } +#else +double +get_time(void) +{ + return (double)GetTickCount()/1000.0; +} +#endif int engine_abort(void) @@ -1104,6 +1112,8 @@ _engine_args(int argc, char **argv) loop_func = engine_software_ddraw_loop; if (engine_software_sdl_args(argc, argv)) loop_func = engine_software_sdl_loop; + if (engine_direct3d_args(argc, argv)) + loop_func = engine_direct3d_loop; if (!loop_func) { fprintf(stderr, @@ -1113,7 +1123,7 @@ _engine_args(int argc, char **argv) " -e ENGINE\n" "\n" "Where ENGINE can be one of:\n" - " x11 xr gl-glew gl x11-16 ddraw sdl\n" + " x11 xr gl-glew gl x11-16 ddraw direct3d sdl\n" ); exit(-1); } diff --git a/src/bin/main.h b/src/bin/main.h index d35ffff..55de5f5 100644 --- a/src/bin/main.h +++ b/src/bin/main.h @@ -8,6 +8,10 @@ #include #include +#ifdef _WIN32 +# include +#endif + #include #include "config.h" #include "engine_software_x11.h" @@ -17,6 +21,7 @@ #include "engine_software_16_x11.h" #include "engine_software_ddraw.h" #include "engine_software_sdl.h" +#include "engine_direct3d.h" #include "ui.h" #include "about.h"