Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

displaycard_directdraw.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: displaycard_directdraw.cpp,v 1.4 2001/03/24 22:30:37 plasmoid Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 #include "displaycard_directdraw.h"
00017 #include "API/Display/Display/mousecursor.h"
00018 #include "API/Display/Display/vidmode.h"
00019 #include "blit_dx.h"
00020 #include "API/Core/System/error.h"
00021 #include "../Generic/colormap.h"
00022 #include "../Generic/blitters.h"
00023 #include "API/Core/Math/rect.h"
00024 
00025 CL_DisplayCard_DirectDraw::CL_DisplayCard_DirectDraw(
00026         int card_no,
00027         LPGUID card_guid,
00028         std::string card_name)
00029 : CL_DisplayCard_Win32Compatible(card_no)
00030 {
00031         this->card_no = card_no;
00032         this->card_guid = card_guid;
00033         this->card_name = card_name;
00034 
00035         init_palette();
00036 
00037         back_buffer = NULL;
00038         front_buffer = NULL;
00039         directdraw = NULL;
00040         use_software_surfaces = false;
00041 
00042         enumerate_displaymodes();
00043 
00044         slot_resize = get_sig_resize().connect(CL_CreateSlot(this, &CL_DisplayCard_DirectDraw::on_resize));
00045 }
00046 
00047 CL_DisplayCard_DirectDraw::~CL_DisplayCard_DirectDraw()
00048 {
00049         deinit();
00050         destroy_displaymodes();
00051 }
00052 
00053 void CL_DisplayCard_DirectDraw::deinit()
00054 {
00055         if (directdraw == NULL) return;
00056         cl_assert(get_hwnd() != NULL);
00057 
00058         CL_MouseCursor::hide();
00059 
00060         directdraw->FlipToGDISurface();
00061 
00062         // If fullscreen, change back to the desktop.
00063         if (is_fullscreen())
00064         {
00065                 HRESULT err = directdraw->RestoreDisplayMode();
00066                 cl_assert(err == DD_OK);
00067         }
00068 
00069         // Shut down directdraw object.
00070         // We have to release all references to the ddraw object,
00071         // that's why we call release_all_surfaces().
00072 
00073         CL_Blit_DX::release_all_surfaces();
00074         delete back_buffer;
00075         delete front_buffer;
00076         back_buffer = NULL;
00077         front_buffer = NULL;
00078 
00079         cl_assert(directdraw->Release()==0);
00080         directdraw = NULL;
00081 
00082         destroy_window();
00083 }
00084 
00085 // CL_DisplayCard functions:
00086 // -------------------------
00087 
00088 void CL_DisplayCard_DirectDraw::set_palette(CL_Palette *palette)
00089 {
00090         // Change system palette to the specified palette.
00091 
00092         delete[] pal.palette;
00093 
00094         pal.num_colors = palette->num_colors;
00095         pal.palette = new unsigned char[pal.num_colors*3];
00096 
00097         memcpy(
00098                 pal.palette,
00099                 palette->palette,
00100                 pal.num_colors*3);
00101 }
00102 
00103 CL_Palette *CL_DisplayCard_DirectDraw::get_palette()
00104 {
00105         return &pal;
00106 }
00107 
00108 void CL_DisplayCard_DirectDraw::flip_display(bool sync)
00109 {
00110         // Surfaces are lost if the application is minimized, or if
00111         // some other ddraw application runs fullscreen.
00112         if (front_buffer->get_surface()->IsLost())
00113         {
00114                 if (front_buffer->get_surface()->Restore() == DD_OK)
00115                 {
00116                         CL_Blit_DX::reload_all_surfaces();
00117                 }
00118         }
00119         signal_preflip();
00120 
00121         if (can_flip)
00122         {
00123                 front_buffer->get_surface()->Flip(
00124                         NULL,
00125                         DDFLIP_WAIT);
00126         }
00127         else
00128         {
00129                 // Use surface Blt() because it can do some clipping for us,
00130                 // and because manual copy is only faster if backbuffer is in sysmem.
00131                 // (which isnn't nessesary the case here. it may just be a windows app)
00132 
00133                 DDBLTFX ddbltfx;
00134                 ddbltfx.dwSize = sizeof(ddbltfx);
00135 
00136                 DWORD flags = DDBLT_WAIT;
00137 
00138                 // I love you too Microsoft. The titlebar is part of the window!! LAMERS!
00139                 // That is why we start juggling with client rects and other stuff...
00140                 RECT client_rect;
00141                 GetClientRect(get_hwnd(), &client_rect);
00142 
00143                 RECT dest_rect;
00144                 GetWindowRect(get_hwnd(), &dest_rect);
00145 
00146                 POINT Pt;
00147                 Pt.x=0;
00148                 Pt.y=0;
00149                 ClientToScreen(get_hwnd(),&Pt);
00150 
00151                 dest_rect.top += Pt.y-dest_rect.top;
00152                 dest_rect.right = dest_rect.left + back_buffer->get_width()+(Pt.x-dest_rect.left);
00153                 dest_rect.left  += (Pt.x-dest_rect.left);
00154                 dest_rect.bottom = dest_rect.top + back_buffer->get_height();
00155 
00156                 front_buffer->get_surface()->Blt(
00157                         &dest_rect,
00158                         back_buffer->get_surface(),
00159                         NULL,
00160                         flags,
00161                         &ddbltfx);
00162         }
00163         signal_postflip();
00164 }
00165 
00166 void CL_DisplayCard_DirectDraw::put_display(const CL_Rect &rect)
00167 {
00168         // Use surface Blt() because it can do some clipping for us,
00169         // and because manual copy is only faster if backbuffer is in sysmem.
00170         // (which isnn't nessesary the case here. it may just be a windows app)
00171 
00172         DDBLTFX ddbltfx;
00173         ddbltfx.dwSize = sizeof(ddbltfx);
00174 
00175         DWORD flags = DDBLT_WAIT;
00176 
00177         // I love you too Microsoft. The titlebar is part of the window!! LAMERS!
00178         // That is why we start juggling with client rects and other stuff...
00179         RECT src_rect;
00180         if (can_flip)
00181         {
00182                 src_rect.left = rect.x1;
00183                 src_rect.top = rect.y1;
00184                 src_rect.right = rect.x2;
00185                 src_rect.bottom = rect.y2;
00186         }
00187         else
00188         {
00189                 GetWindowRect(get_hwnd(), &src_rect);
00190 
00191                 RECT client_rect;
00192                 GetClientRect(get_hwnd(), &client_rect);
00193 
00194                 POINT Pt;
00195                 Pt.x=0;
00196                 Pt.y=0;
00197                 ClientToScreen(get_hwnd(),&Pt);
00198 
00199                 src_rect.top += (Pt.y-src_rect.top);
00200                 src_rect.left  += (Pt.x-src_rect.left);
00201 
00202                 src_rect.right = src_rect.left + rect.x2;
00203                 src_rect.bottom = src_rect.top + rect.y2;
00204                 src_rect.left += rect.x1;
00205                 src_rect.top += rect.y1;
00206         }
00207 
00208         front_buffer->get_surface()->Blt(
00209                 NULL,
00210                 back_buffer->get_surface(),
00211                 &src_rect,
00212                 flags,
00213                 &ddbltfx);
00214 }
00215 
00216 void CL_DisplayCard_DirectDraw::sync_buffers()
00217 {
00218         // Use surface Blt() because it can do some clipping for us,
00219         // and because manual copy is only faster if backbuffer is in sysmem.
00220         // (which isnn't nessesary the case here. it may just be a windows app)
00221 
00222         DDBLTFX ddbltfx;
00223         ddbltfx.dwSize = sizeof(ddbltfx);
00224 
00225         DWORD flags = DDBLT_WAIT;
00226 
00227         // I love you too Microsoft. The titlebar is part of the window!! LAMERS!
00228         // That is why we start juggling with client rects and other stuff...
00229         RECT src_rect;
00230         if (can_flip)
00231         {
00232                 src_rect.left = 0;
00233                 src_rect.top = 0;
00234                 src_rect.right = front_buffer->get_width();
00235                 src_rect.bottom = front_buffer->get_height();
00236         }
00237         else
00238         {
00239                 GetWindowRect(get_hwnd(), &src_rect);
00240 
00241                 RECT client_rect;
00242                 GetClientRect(get_hwnd(), &client_rect);
00243 
00244                 POINT Pt;
00245                 Pt.x=0;
00246                 Pt.y=0;
00247                 ClientToScreen(get_hwnd(),&Pt);
00248 
00249                 src_rect.top += (Pt.y-src_rect.top);
00250                 src_rect.right = src_rect.left + back_buffer->get_width()+(Pt.x-src_rect.left);
00251                 src_rect.left  += (Pt.x-src_rect.left);
00252                 src_rect.bottom = src_rect.top + back_buffer->get_height();
00253         }
00254 
00255         back_buffer->get_surface()->Blt(
00256                 NULL,
00257                 front_buffer->get_surface(),
00258                 &src_rect,
00259                 flags,
00260                 &ddbltfx);
00261 }
00262 
00263 void CL_DisplayCard_DirectDraw::set_videomode(
00264         int width,
00265         int height,
00266         int bpp,
00267         bool fullscreen,
00268         bool allow_resize,
00269         bool video_memory)
00270 {
00271         HRESULT err;
00272 
00273         deinit();
00274 
00275         err = DirectDrawCreate(card_guid, &directdraw, NULL); 
00276         cl_assert(err == DD_OK);
00277 
00278         if (video_memory == false)
00279         {
00280                 use_software_surfaces = true;
00281         }
00282         create_window(width, height, bpp, fullscreen, allow_resize);
00283 
00284         // Connect directdraw object to window and setup flipping system:
00285 //      int flags = DDSCL_NORMAL | DDSCL_MULTITHREADED; //CL is now multithreaded
00286         int flags = DDSCL_NORMAL;
00287 
00288         if (fullscreen)
00289         {
00290                 flags = 
00291                         DDSCL_EXCLUSIVE |
00292                         DDSCL_FULLSCREEN |
00293                         DDSCL_ALLOWREBOOT|
00294                         DDSCL_ALLOWMODEX;
00295         }
00296 
00297         err = directdraw->SetCooperativeLevel(
00298                 get_hwnd(),
00299                 flags);
00300 
00301         cl_assert(err == DD_OK);
00302 
00303         // If fullscreen, do a mode switch:
00304         if (fullscreen)
00305         {
00306                 err = directdraw->SetDisplayMode(width, height, bpp);
00307                 cl_assert(err == DD_OK);
00308 
00309                 create_fullscreen_targets(video_memory);
00310         }
00311         else
00312         {
00313                 create_windowed_targets(video_memory);
00314         }
00315 
00316         // If there already was some surfaces attached to this
00317         // displaycard, recreate them using the new ddraw object:
00318         CL_Blit_DX::create_all_surfaces();
00319 
00320         // Setup generic displaycard internals:
00321         CL_DisplayCard_Generic::set_gfxmode(
00322                 width,
00323                 height,
00324                 bpp,
00325                 fullscreen,
00326                 allow_resize);
00327 }
00328 
00329 void CL_DisplayCard_DirectDraw::clear_display(
00330         float red,
00331         float green,
00332         float blue,
00333         float alpha)
00334 {
00335         fill_rect(
00336                 0,
00337                 0,
00338                 get_width(),
00339                 get_height(),
00340                 red,
00341                 green,
00342                 blue,
00343                 alpha);
00344 }
00345 
00346 /*
00347 void CL_DisplayCard_DirectDraw::draw_rect(
00348         int x1,
00349         int y1,
00350         int x2,
00351         int y2,
00352         float r,
00353         float g,
00354         float b,
00355         float a)
00356 {
00357 
00358 }
00359 */
00360 
00361 void CL_DisplayCard_DirectDraw::fill_rect(
00362         int x1,
00363         int y1,
00364         int x2,
00365         int y2,
00366         float r,
00367         float g,
00368         float b,
00369         float a)
00370 {
00371         // If the color is opaque, we use directdraw's hw accelerated fill function.
00372         // Otherwise we use the generic software implementation.
00373 
00374         if (a <= 0.01) return;
00375         if (a <= 0.99)
00376         {
00377                 CL_DisplayCard_Generic::fill_rect(x1, y1, x2, y2, r, g, b, a);
00378                 return;
00379         }
00380         
00381         // Translate coords into position:
00382         int trans_x = get_translate_offset_x();
00383         int trans_y = get_translate_offset_y();
00384         x1 += trans_x;
00385         x2 += trans_x;
00386         y1 += trans_y;
00387         y2 += trans_y;
00388 
00389         CL_ClipRect rect(x1, y1, x2, y2);
00390 
00391         CL_ClipRect cur_clip = get_clip_rect();
00392         if (cur_clip.test_all_clipped(rect)) 
00393         {
00394                 return;
00395         }
00396 
00397         CL_ClipRect crect = cur_clip.clip(rect);
00398         CL_ColorMap cmap(get_back_buffer());
00399         unsigned int fill_color = cmap.calc_color(r, g, b, a);
00400 
00401         DDBLTFX ddbltfx;
00402         ddbltfx.dwSize=sizeof(ddbltfx);
00403         ddbltfx.dwFillColor = fill_color;
00404 
00405         RECT dest;
00406         dest.left = crect.m_x1;
00407         dest.top = crect.m_y1;
00408         dest.right = crect.m_x2;
00409         dest.bottom = crect.m_y2;
00410 
00411         back_buffer->get_surface()->Blt(
00412                 &dest,
00413                 NULL,
00414                 NULL,
00415                 DDBLT_COLORFILL|DDBLT_WAIT,
00416                 &ddbltfx);      // clear screen
00417 }
00418 
00419 std::string CL_DisplayCard_DirectDraw::get_name()
00420 {
00421         return card_name;
00422 }
00423 
00424 const std::list<CL_VidMode*> &CL_DisplayCard_DirectDraw::get_videomodes()
00425 {
00426         return videomodes;
00427 }
00428 
00429 // CL_DisplayCard_Generic functions:
00430 // ---------------------------------
00431 
00432 CL_Blitters CL_DisplayCard_DirectDraw::create_hw_blitters(
00433         CL_SurfaceProvider *provider)
00434 {
00435         // Determine wether we can/want use a hw accelerated blitter:
00436 
00437         CL_Blitters ret;
00438 
00439         // Use software blitting if backbuffer in system memory
00440         if (use_software_surfaces) 
00441         {
00442                 return ret;
00443         }
00444 
00445         CL_Blit_DX *blitter = new CL_Blit_DX(this, provider);
00446         bool res = blitter->init_surface(&ret);
00447         if (!res)
00448         {
00449                 delete blitter;
00450         }
00451 
00452         return ret;
00453 }
00454 
00455 // Implementation, init/deinit functions:
00456 // --------------------------------------
00457 
00458 void CL_DisplayCard_DirectDraw::init_palette()
00459 {
00460         // Create a grayscaled palette.
00461 
00462         delete[] pal.palette;
00463 
00464         pal.num_colors = 256;
00465         pal.palette = new unsigned char[pal.num_colors*3];
00466 
00467         for (int i=0; i<pal.num_colors; i++)
00468         {
00469                 pal.palette[i*3 + 0] = i;
00470                 pal.palette[i*3 + 1] = i;
00471                 pal.palette[i*3 + 2] = i;
00472         }
00473 }
00474 
00475 void CL_DisplayCard_DirectDraw::enumerate_displaymodes()
00476 {
00477         HRESULT err;
00478         LPDIRECTDRAW directdraw;
00479 
00480         err = DirectDrawCreate(card_guid, &directdraw, NULL); 
00481         cl_assert(err == DD_OK);
00482 
00483         err = directdraw->EnumDisplayModes(
00484                 DDEDM_STANDARDVGAMODES,
00485                 NULL,
00486                 (void *) &videomodes,
00487                 enumerate_callback);
00488 
00489 // Remarked because NT 4 fails to enumerate display modes. We will just
00490 // have to live without that feature on that platform.
00491 //      cl_assert(err == DD_OK);
00492 
00493         directdraw->Release();
00494 }
00495 
00496 HRESULT CALLBACK CL_DisplayCard_DirectDraw::enumerate_callback(
00497         LPDDSURFACEDESC lpDDSurfaceDesc,
00498         LPVOID lpContext)
00499 {
00500         std::list<CL_VidMode*> *v_list=(std::list<CL_VidMode*> *) lpContext;
00501 
00502         DDSURFACEDESC surf_desc = *lpDDSurfaceDesc;
00503 
00504         bool modex = false;
00505         if ((surf_desc.ddsCaps.dwCaps & DDSCAPS_MODEX) == DDSCAPS_MODEX) modex = true;
00506 
00507         v_list->push_back(
00508                 new CL_VidMode(
00509                         surf_desc.dwWidth,
00510                         surf_desc.dwHeight,
00511                         surf_desc.ddpfPixelFormat.dwRGBBitCount,
00512                         modex));
00513 
00514         return DDENUMRET_OK;
00515 }
00516 
00517 void CL_DisplayCard_DirectDraw::destroy_displaymodes()
00518 {
00519         while (videomodes.empty() == false)
00520         {
00521                 delete *videomodes.begin();
00522                 videomodes.erase(videomodes.begin());
00523         }
00524 }
00525 
00526 void CL_DisplayCard_DirectDraw::create_fullscreen_targets(bool video_memory)
00527 {
00528         try // to create a surface flipping system with two surfaces.
00529         {
00530                 // setup the primary surface (the flipping system):
00531                 HRESULT err;
00532 
00533                 DDSURFACEDESC surf_desc;
00534                 memset(&surf_desc, 0, sizeof(surf_desc));
00535                 surf_desc.dwSize = sizeof(DDSURFACEDESC);
00536 
00537                 surf_desc.dwFlags =
00538                         DDSD_CAPS |
00539                         DDSD_BACKBUFFERCOUNT;
00540 
00541                 surf_desc.ddsCaps.dwCaps =
00542                         DDSCAPS_PRIMARYSURFACE |
00543                         DDSCAPS_FLIP |
00544                         DDSCAPS_COMPLEX;
00545 
00546                 if (video_memory) surf_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
00547                 else surf_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
00548 
00549                 // 3 buffers are more effecient, but at the price of memory.
00550                 // We should make it possible for the application to specify the
00551                 // buffer count.
00552                 surf_desc.dwBackBufferCount = 2;
00553 
00554                 LPDIRECTDRAWSURFACE primary_surface;
00555     directdraw->SetCooperativeLevel(hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT|DDSCL_ALLOWMODEX);
00556                 err = directdraw->CreateSurface(&surf_desc, &primary_surface, NULL);
00557                 if (err != DD_OK) throw CL_Error("Couldn't create flipping system.");
00558 
00559                 // Get the backbuffer surface from the primary/front:
00560                 DDSCAPS backbuffer_desc;
00561                 backbuffer_desc.dwCaps = DDSCAPS_BACKBUFFER;
00562 
00563                 LPDIRECTDRAWSURFACE backbuffer_surface;
00564                 err = primary_surface->GetAttachedSurface(
00565                         &backbuffer_desc,
00566                         &backbuffer_surface);
00567 
00568                 if (err != DD_OK)
00569                 {
00570                         primary_surface->Release();
00571                         throw CL_Error("Couldn't create flipping system.");
00572                 }
00573 
00574                 // Wrap the directx front and backbuffer surfaces into the CL_Target interface:
00575                 front_buffer = new CL_Target_DX(primary_surface);
00576                 back_buffer = new CL_Target_DX(backbuffer_surface);
00577 
00578                 can_flip = true;
00579         }
00580         catch (CL_Error err) // not enough memory, fallback to system memory backbuffer.
00581         {
00582                 create_windowed_targets(video_memory);
00583         }
00584 }
00585 
00586 void CL_DisplayCard_DirectDraw::create_windowed_targets(bool video_memory)
00587 {
00588         // setup the front buffer surface:
00589         HRESULT err;
00590 
00591         DDSURFACEDESC surf_desc;
00592         memset(&surf_desc, 0, sizeof(surf_desc));
00593         surf_desc.dwSize = sizeof(DDSURFACEDESC);
00594         surf_desc.dwFlags = DDSD_CAPS;
00595         surf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
00596 
00597         LPDIRECTDRAWSURFACE primary_surface;
00598         err = directdraw->CreateSurface(&surf_desc, &primary_surface, NULL);
00599         if (err != DD_OK) throw CL_Error("Couldn't create front buffer.");
00600 
00601         // Wrap front buffer into the CL_Target interface:
00602         RECT client_rect;
00603         GetClientRect(get_hwnd(), &client_rect);
00604 
00605         RECT dest_rect;
00606         GetWindowRect(get_hwnd(), &dest_rect);
00607 
00608         POINT Pt;
00609         Pt.x=0;
00610         Pt.y=0;
00611         ClientToScreen(get_hwnd(),&Pt);
00612 
00613         dest_rect.top += (Pt.y-dest_rect.top);
00614         dest_rect.left  += (Pt.x-dest_rect.left);
00615         front_buffer = new CL_FrontbufferTarget_DX(
00616                 primary_surface,
00617                 this/*,
00618                 dest_rect.right-dest_rect.left,
00619                 dest_rect.bottom-dest_rect.top*/);
00620 
00621         backbuffer_in_video_memory = video_memory;
00622         create_windowed_backbuffer(
00623                 dest_rect.right-dest_rect.left,
00624                 dest_rect.bottom-dest_rect.top);
00625 
00626         // Clip blits to the window borders:
00627         LPDIRECTDRAWCLIPPER clipper;
00628         err = directdraw->CreateClipper(0, &clipper, NULL);
00629         cl_assert(err == DD_OK);
00630         clipper->SetHWnd(0, get_hwnd());
00631 
00632         // attach clipper to front buffer:
00633         front_buffer->get_surface()->SetClipper(clipper);
00634         clipper->Release();
00635 
00636         can_flip = false;
00637 }
00638 
00639 void CL_DisplayCard_DirectDraw::create_windowed_backbuffer(int width, int height)
00640 {
00641         if (width == 0 || height == 0) return; // minimized.
00642 
00643         HRESULT err = 0;
00644 
00645         // clean up previous backbuffer:
00646         delete back_buffer;
00647         back_buffer = NULL;
00648 
00649         // create back buffer surface: (trying in framebuffer first)
00650 
00651         DDSURFACEDESC surf_desc;
00652         memset(&surf_desc, 0, sizeof(surf_desc));
00653         surf_desc.dwSize = sizeof(DDSURFACEDESC);
00654         surf_desc.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
00655         surf_desc.dwWidth = width;
00656         surf_desc.dwHeight = height;
00657         surf_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
00658         if (backbuffer_in_video_memory) surf_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
00659         else surf_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
00660 
00661         LPDIRECTDRAWSURFACE backbuffer_surface;
00662 
00663 //      directdraw->SetCooperativeLevel(hwnd,DDSCL_NORMAL| DDSCL_MULTITHREADED); //Make sure we set the co-op level
00664         directdraw->SetCooperativeLevel(hwnd,DDSCL_NORMAL); //Make sure we set the co-op level
00665         err = directdraw->CreateSurface(&surf_desc, &backbuffer_surface, NULL);
00666 
00667         if (err != DD_OK) // damn. Not enough memory in video, fallback to system memory.
00668         {
00669                 surf_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
00670 
00671                 err = directdraw->CreateSurface(&surf_desc, &backbuffer_surface, NULL);
00672                 cl_assert(err == DD_OK);
00673         }
00674 
00675         // Wrap back buffer into the CL_Target interface:
00676         back_buffer = new CL_Target_DX(backbuffer_surface);
00677 }
00678 
00679 // Implementation, nicer data retrieval:
00680 // ------------------------------------
00681 
00682 DDCAPS CL_DisplayCard_DirectDraw::get_hel_caps()
00683 {
00684         HRESULT err;
00685         DDCAPS hel_caps;
00686         hel_caps.dwSize = sizeof(DDCAPS);
00687  
00688         err = directdraw->GetCaps(NULL, &hel_caps);     
00689         cl_assert(err == DD_OK);
00690 
00691         return hel_caps;
00692 }
00693 
00694 DDCAPS CL_DisplayCard_DirectDraw::get_hal_caps()
00695 {
00696         HRESULT err;
00697         DDCAPS hal_caps;
00698         hal_caps.dwSize = sizeof(DDCAPS);
00699  
00700         err = directdraw->GetCaps(&hal_caps, NULL);
00701         cl_assert(err == DD_OK);
00702 
00703         return hal_caps;
00704 }
00705 
00706 CL_DisplayCard_DirectDraw::CL_FrontbufferTarget_DX::CL_FrontbufferTarget_DX(
00707         LPDIRECTDRAWSURFACE surf,
00708         CL_DisplayCard_DirectDraw *parent)
00709 : CL_Target_DX(surf), m_parent(parent)
00710 {
00711 }
00712 
00713 void *CL_DisplayCard_DirectDraw::CL_FrontbufferTarget_DX::get_data() const
00714 {
00715         RECT client_rect;
00716         GetClientRect(m_parent->get_hwnd(), &client_rect);
00717 
00718         RECT dest_rect;
00719         GetWindowRect(m_parent->get_hwnd(), &dest_rect);
00720 
00721         POINT Pt;
00722         Pt.x=0;
00723         Pt.y=0;
00724         ClientToScreen(m_parent->get_hwnd(),&Pt);
00725 
00726         dest_rect.top += (Pt.y-dest_rect.top);
00727         dest_rect.left  += (Pt.x-dest_rect.left);
00728         return (void *) &((unsigned char *) m_data)[dest_rect.left*(m_depth/8)+dest_rect.top*m_pitch];
00729 }
00730 
00731 void CL_DisplayCard_DirectDraw::on_resize(int x, int y)
00732 {
00733         if (is_fullscreen() == false)
00734         {
00735                 create_windowed_backbuffer(x, y);
00736         }
00737 }

Generated at Wed Apr 4 19:54:00 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001