home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / gamesystem / source / gs_screen.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-11  |  31.1 KB  |  1,274 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    gsCScreen
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    12/03/00
  8. //
  9. // Base:    gsCVisual
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "gamesystem.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. gsLPDIRECTDRAWSURFACE    gsCScreen::m_primary_surface = 0;
  20. gsLPDIRECTDRAWSURFACE    gsCScreen::m_back_surface = 0;
  21. gsLPDIRECTDRAWCLIPPER    gsCScreen::m_clipper = 0;
  22. gsLPDIRECTDRAWPALETTE    gsCScreen::m_palette = 0;
  23. DDBLTFX gsCScreen::m_ddbltfx;
  24.  
  25. bool gsCScreen::m_isWindowed = true;
  26. gsCRect gsCScreen::m_window_rect;
  27. gsCRect gsCScreen::m_viewport_rect;
  28. gsCRect gsCScreen::m_screen_rect;
  29.  
  30. bool gsCScreen::m_display_mode_set = false;
  31.  
  32. int gsCScreen::m_bpp = 0;
  33.  
  34. //-------------------------------------------------------------
  35.  
  36. gsCScreen::gsCScreen()
  37. {
  38.     m_ddbltfx.dwSize = sizeof(DDBLTFX);
  39.     m_isLocked = false;
  40. }
  41.  
  42. //-------------------------------------------------------------
  43.  
  44. gsCScreen::~gsCScreen()
  45. {
  46. }
  47.  
  48. //-------------------------------------------------------------
  49.  
  50. bool gsCScreen::createWindowed(HWND window)
  51. {
  52.     m_isWindowed = true;
  53.  
  54.     HRESULT hr;
  55.  
  56.     hr = m_direct_draw->SetCooperativeLevel(window,DDSCL_NORMAL);
  57.     
  58.     if (hr != DD_OK) {
  59.         gsERROR("gsCScreen::createWindowed failed to set cooperative level");
  60.         destroy();
  61.         return false;
  62.         }
  63.  
  64.     updateRect(window);
  65.     
  66.     gsDDSURFACEDESC ddsd;
  67.  
  68.     ZeroMemory(&ddsd,sizeof(ddsd));
  69.     ddsd.dwSize = sizeof(ddsd);
  70.     ddsd.dwFlags = DDSD_CAPS;
  71.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  72.     
  73.     hr = m_direct_draw->CreateSurface(&ddsd,&m_primary_surface,NULL);
  74.     
  75.     if (hr != DD_OK) {
  76.         gsERROR("gsCScreen::createWindowed failed to create primary surface");
  77.         destroy();
  78.         return false;
  79.         }
  80.         
  81.     hr = m_direct_draw->CreateClipper(0,&m_clipper,NULL);
  82.     
  83.     if (hr != DD_OK) {
  84.         gsERROR("gsCScreen::createWindowed failed to create clipper");
  85.         destroy();
  86.         }
  87.     
  88.     hr = m_clipper->SetHWnd(0, window);
  89.     
  90.     if (hr != DD_OK) {
  91.         gsERROR("gsCScreen::createWindowed failed to set clipper window");
  92.         destroy();
  93.         return false;
  94.         }
  95.  
  96.     hr = m_primary_surface->SetClipper(m_clipper);
  97.     
  98.     if (hr != DD_OK) {
  99.         gsERROR("gsCScreen::createWindowed failed to set primary surface clipper");
  100.         destroy();
  101.         return false;
  102.         }
  103.  
  104.     ddsd.dwFlags        = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
  105.     ddsd.dwWidth        = m_screen_rect.getWidth();
  106.     ddsd.dwHeight       = m_screen_rect.getHeight();
  107.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  108.     
  109.     hr = m_direct_draw->CreateSurface(&ddsd,&m_back_surface,NULL);
  110.     
  111.     if (hr != DD_OK) {
  112.         gsERROR("gsCScreen::createWindowed failed to create back surface");
  113.         destroy();
  114.         return false;
  115.         }
  116.  
  117.     findBPP();
  118.  
  119.     if (m_bpp == 1) {
  120.         if (!createDefaultPalette()) {
  121.             gsERROR("gsCScreen::createWindowed failed to create palette");
  122.             destroy();
  123.             return false;
  124.             }
  125.         hr = m_primary_surface->SetPalette(m_palette);
  126.         if (hr != DD_OK) {
  127.             gsERROR("gsCScreen::createWindowed failed to set palette");
  128.             destroy();
  129.             return false;
  130.             }
  131.         }
  132.  
  133.     gsCColour::setupColourConversion(this);
  134.     
  135.     gsCApplication::m_screen = this;
  136.  
  137.     gsREPORT("gsCScreen created (windowed mode)");
  138.  
  139.     return true;
  140. }
  141.         
  142. //-------------------------------------------------------------
  143.  
  144. bool gsCScreen::createFullScreen(HWND window,const gsCPoint& size,gsDWORD bitdepth)
  145. {
  146.     m_isWindowed = false;
  147.  
  148.     HRESULT hr;
  149.  
  150.     hr = m_direct_draw->SetCooperativeLevel(window,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
  151.     
  152.     if (hr != DD_OK) {
  153.         gsERROR("gsCScreen::createFullscreen failed to set cooperative level");
  154.         destroy();
  155.         return false;
  156.         }
  157.     
  158.     hr = m_direct_draw->SetDisplayMode(size.getX(),size.getY(),bitdepth,0,0);
  159.     
  160.     if (hr != DD_OK) {
  161.         gsERROR("gsCScreen::createFullscreen failed to set display mode");
  162.         destroy();
  163.         return false;
  164.         }
  165.  
  166.     m_display_mode_set = true;
  167.  
  168.     m_viewport_rect.setTopLeft(gsCPoint(0,0));
  169.     m_viewport_rect.setBottomRight(gsCPoint(size));
  170.  
  171.     m_screen_rect = m_viewport_rect;
  172.  
  173.     gsDDSURFACEDESC ddsd;
  174.     
  175.     ZeroMemory(&ddsd,sizeof(ddsd));
  176.     ddsd.dwSize = sizeof(ddsd);
  177.     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  178.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  179.     ddsd.dwBackBufferCount = 1;
  180.  
  181.     hr = m_direct_draw->CreateSurface( &ddsd, &m_primary_surface, NULL);
  182.     
  183.     if (hr != DD_OK) {
  184.         gsERROR("gsCScreen::createFullscreen failed to create primary surface");
  185.         destroy();
  186.         return false;
  187.         }
  188.  
  189.     gsDDSCAPS ddscaps;
  190.  
  191.     ZeroMemory(&ddscaps,sizeof(ddscaps));
  192.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  193.     
  194.     hr = m_primary_surface->GetAttachedSurface(&ddscaps, &m_back_surface);
  195.     
  196.     if (hr != DD_OK) {
  197.         gsERROR("gsCScreen::createFullscreen failed to create back surface");
  198.         destroy();
  199.         return false;
  200.         }
  201.  
  202.     findBPP();
  203.  
  204.     if (m_bpp == 1) {
  205.         if (!createDefaultPalette()) {
  206.             gsERROR("gsCScreen::createFullScreen failed to create palette");
  207.             destroy();
  208.             return false;
  209.             }
  210.         hr = m_primary_surface->SetPalette(m_palette);
  211.         if (hr != DD_OK) {
  212.             gsERROR("gsCScreen::createFullScreen failed to set palette");
  213.             destroy();
  214.             return false;
  215.             }
  216.         }
  217.  
  218.     gsCColour::setupColourConversion(this);
  219.  
  220.     gsCApplication::m_screen = this;
  221.  
  222.     gsREPORT("gsCScreen created (fullscreen mode)");
  223.  
  224.     return true;
  225. }
  226.  
  227. //-------------------------------------------------------------
  228.  
  229. bool gsCScreen::createDefaultPalette()
  230. {
  231.     for (int i = 0; i < 256; i++) {
  232.         m_palette_colours[i].peRed = (BYTE) (((i >> 5) & 0x07) * 255 / 7);
  233.         m_palette_colours[i].peGreen = (BYTE) (((i >> 2) & 0x07) * 255 / 7);
  234.         m_palette_colours[i].peBlue = (BYTE) (((i >> 0) & 0x03) * 255 / 3);
  235.         m_palette_colours[i].peFlags = (BYTE) 0;
  236.         }
  237.  
  238.     return m_direct_draw->CreatePalette(DDPCAPS_8BIT,
  239.                                         m_palette_colours,
  240.                                         &m_palette,
  241.                                         NULL) == DD_OK;
  242. }
  243.  
  244. //-------------------------------------------------------------
  245.  
  246. bool gsCScreen::flip()
  247. {
  248.     HRESULT hr;
  249.  
  250. #ifndef _PROFILING
  251.     if (m_isWindowed) {
  252.         hr = m_direct_draw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL);
  253.  
  254.         if (hr != DD_OK)
  255.             gsREPORT("gsCScreen::flip wait for VB failed");
  256.         }
  257. #endif
  258.  
  259.     hr = DD_OK;
  260.  
  261.     do {
  262.         if (m_isWindowed) {
  263.             hr = m_primary_surface->Blt(LPRECT(m_screen_rect),
  264.                                         m_back_surface,
  265.                                         LPRECT(m_viewport_rect),
  266.                                         DDBLT_WAIT,
  267.                                         NULL);
  268.             if (hr != DD_OK) {
  269.                 gsREPORT("gsCScreen::flip couldn't blit back surface to primary");
  270.                 break;
  271.                 }
  272.             }
  273.         else {
  274.             hr = m_primary_surface->Flip(NULL,0L);
  275.  
  276.             if (hr != DD_OK) {
  277.                 gsREPORT("gsCScreen::flip couldn't flip surfaces");
  278.                 break;
  279.                 }
  280.             }
  281.  
  282.         if (hr == DDERR_SURFACELOST) {
  283.             hr = m_primary_surface->Restore();
  284.             if (hr != DD_OK) {
  285.                 gsREPORT("gsCScreen::flip couldn't restore primary surface");
  286.                 break;
  287.                 }
  288.             }
  289.         }
  290.     while (hr == DDERR_WASSTILLDRAWING);
  291.  
  292.     if (hr != DD_OK) {
  293.         gsREPORT("gsCScreen::flip failed");
  294.         return false;
  295.         }
  296.  
  297.     return true;
  298. }
  299.  
  300. //-------------------------------------------------------------
  301.  
  302. void gsCScreen::updateRect(HWND window)
  303. {
  304.     GetWindowRect(window,LPRECT(m_window_rect));
  305.     GetClientRect(window,LPRECT(m_viewport_rect));
  306.     GetClientRect(window,LPRECT(m_screen_rect));
  307.  
  308.     gsCPoint p;
  309.  
  310.     p = m_screen_rect.getTopLeft();
  311.     ClientToScreen(window,LPPOINT(p));
  312.     m_screen_rect.setTopLeft(p);
  313.  
  314.     p = m_screen_rect.getBottomRight();
  315.     ClientToScreen(window,LPPOINT(p));
  316.     m_screen_rect.setBottomRight(p);
  317. }
  318.  
  319. //-------------------------------------------------------------
  320.  
  321. void gsCScreen::clear(const gsCColour& colour)
  322. {
  323.     drawSolidRect(getRect(),colour);
  324. }
  325.  
  326. //-------------------------------------------------------------
  327.  
  328. bool gsCScreen::lock()
  329. {
  330.     if (!m_isLocked) {
  331.     
  332.         HRESULT hr;
  333.         
  334.         memset(&m_ddsd,0,sizeof(m_ddsd));
  335.         m_ddsd.dwSize = sizeof(m_ddsd);
  336.  
  337. #ifdef gsALLOW_SYSLOCK
  338.         hr = m_back_surface->Lock(NULL,&m_ddsd,DDLOCK_WAIT | DDLOCK_NOSYSLOCK,NULL);
  339. #else
  340.         hr = m_back_surface->Lock(NULL,&m_ddsd,DDLOCK_WAIT,NULL);
  341. #endif
  342.         
  343.         while (hr == DDERR_SURFACELOST) {
  344.             if (m_isWindowed)
  345.                 m_back_surface->Restore();
  346.             else
  347.                 m_primary_surface->Restore();
  348.  
  349.             memset(&m_ddsd,0,sizeof(m_ddsd));
  350.             m_ddsd.dwSize = sizeof(m_ddsd);
  351.         
  352. #ifdef gsALLOW_SYSLOCK
  353.             hr = m_back_surface->Lock(NULL,&m_ddsd,DDLOCK_WAIT | DDLOCK_NOSYSLOCK,NULL);
  354. #else
  355.             hr = m_back_surface->Lock(NULL,&m_ddsd,DDLOCK_WAIT,NULL);
  356. #endif
  357.             }
  358.         
  359.         if (hr != DD_OK) {
  360.             gsERROR("gsCScreen::lock failed");
  361.             return false;
  362.             }
  363.  
  364.         m_isLocked = true;
  365.         }
  366.  
  367.     return true;
  368. }
  369.  
  370. //-------------------------------------------------------------
  371.  
  372. void gsCScreen::unlock()
  373. {
  374.     if (m_isLocked) {
  375.         HRESULT hr;
  376.     
  377.         hr = m_back_surface->Unlock(NULL);
  378.  
  379.         while (hr == DDERR_SURFACELOST) {
  380.             if (m_isWindowed)
  381.                 m_back_surface->Restore();
  382.             else
  383.                 m_primary_surface->Restore();
  384.  
  385.             hr = m_back_surface->Unlock(NULL);
  386.             }
  387.  
  388.         if (hr != DD_OK)
  389.             gsERROR("gsCScreen::unlock failed");
  390.  
  391.         m_isLocked = false;
  392.         }
  393. }
  394.  
  395. //-------------------------------------------------------------
  396. // Internal function - must be inside lock/unlock
  397.  
  398. void gsCScreen::draw_pixel(const gsCPoint& position,const gsCColour& colour)
  399. {
  400.     if (position.getX() < 0 ||
  401.         position.getY() < 0 ||
  402.         position.getX() >= m_screen_rect.getWidth() ||
  403.         position.getY() >= m_screen_rect.getHeight())
  404.         return;
  405.  
  406.     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + position.getY() * m_ddsd.lPitch;
  407.  
  408.     gsUDWORD raw = colour.getRaw();
  409.  
  410.     switch (m_bpp) {
  411.         case 1:
  412.             dest += position.getX();
  413.             *dest = (gsUBYTE) raw;
  414.             break;
  415.         case 2:
  416.             dest += 2 * position.getX();
  417.             *((gsUWORD *) dest) = (gsUWORD) raw;
  418.             break;
  419.         case 3:
  420.             dest += 3 * position.getX();
  421.             *((gsUWORD *) dest) = (gsUWORD) raw;
  422.             *(dest + 2) = (gsUBYTE) (raw >> 16);
  423.             break;
  424.         case 4:
  425.             dest += 4 * position.getX();
  426.             *((gsUWORD *) dest) = (gsUWORD) raw;
  427.             *((gsUWORD *) (dest + 2)) = (gsUWORD) (raw >> 16);
  428.             break;
  429.         }
  430. }
  431.  
  432. //-------------------------------------------------------------
  433. // Internal function - must be inside lock/unlock
  434.  
  435. void gsCScreen::draw_pixels(int num_points,const gsCPoint *position,const gsCColour *colour,bool clip)
  436. {
  437.     if (clip) {
  438.         int sw = m_screen_rect.getWidth();
  439.         int sh = m_screen_rect.getHeight();
  440.     
  441.         switch (m_bpp) {
  442.             case 1:
  443.                 while (num_points-- > 0) {
  444.                     int x = position->getX();
  445.                     int y = position->getY();
  446.  
  447.                     if (x >= 0 && y >= 0 && x < sw && y < sh) {
  448.                         gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y * m_ddsd.lPitch + x;
  449.                         *dest = (gsUBYTE) colour->getRaw();
  450.                         }
  451.                     position++;
  452.                     colour++;
  453.                     }
  454.                 break;
  455.             case 2:
  456.                 while (num_points-- > 0) {
  457.                     int x = position->getX();
  458.                     int y = position->getY();
  459.  
  460.                     if (x >= 0 && y >= 0 && x < sw && y < sh) {
  461.                         gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y * m_ddsd.lPitch + 2 * x;
  462.                         *((gsUWORD *) dest) = (gsUWORD) colour->getRaw();
  463.                         }
  464.                     position++;
  465.                     colour++;
  466.                     }
  467.                 break;
  468.             case 3:
  469.                 while (num_points-- > 0) {
  470.                     int x = position->getX();
  471.                     int y = position->getY();
  472.  
  473.                     if (x >= 0 && y >= 0 && x < sw && y < sh) {
  474.                         gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y * m_ddsd.lPitch + 3 * x;
  475.                         *((gsUWORD *) dest) = (gsUWORD) colour->getRaw();
  476.                         *(dest + 2) = (gsUBYTE) (colour->getRaw() >> 16);
  477.                         }
  478.                     position++;
  479.                     colour++;
  480.                     }
  481.                 break;
  482.             case 4:
  483.                 while (num_points-- > 0) {
  484.                     int x = position->getX();
  485.                     int y = position->getY();
  486.  
  487.                     if (x >= 0 && y >= 0 && x < sw && y < sh) {
  488.                         gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y * m_ddsd.lPitch + 4 * x;
  489.                         *((gsUWORD *) dest) = (gsUWORD) colour->getRaw();
  490.                         *((gsUWORD *) (dest + 2)) = (gsUWORD) (colour->getRaw() >> 16);
  491.                         }
  492.                     position++;
  493.                     colour++;
  494.                     }
  495.                 break;
  496.             }
  497.         }
  498.     else {
  499.         switch (m_bpp) {
  500.             case 1:
  501.                 while (num_points-- > 0) {
  502.                     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + position->getY() * m_ddsd.lPitch + position->getX();
  503.                     *dest = (gsUBYTE) colour->getRaw();
  504.                     position++;
  505.                     colour++;
  506.                     }
  507.                 break;
  508.             case 2:
  509.                 while (num_points-- > 0) {
  510.                     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + position->getY() * m_ddsd.lPitch + 2 * position->getX();
  511.                     *((gsUWORD *) dest) = (gsUWORD) colour->getRaw();
  512.                     position++;
  513.                     colour++;
  514.                     }
  515.                 break;
  516.             case 3:
  517.                 while (num_points-- > 0) {
  518.                     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + position->getY() * m_ddsd.lPitch + 3 * position->getX();
  519.                     gsUDWORD raw = colour->getRaw();
  520.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  521.                     *(dest + 2) = (gsUBYTE) (raw >> 16);
  522.                     position++;
  523.                     colour++;
  524.                     }
  525.                 break;
  526.             case 4:
  527.                 while (num_points-- > 0) {
  528.                     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + position->getY() * m_ddsd.lPitch + 4 * position->getX();
  529.                     gsUDWORD raw = colour->getRaw();
  530.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  531.                     *((gsUWORD *) (dest + 2)) = (gsUWORD) (raw >> 16);
  532.                     position++;
  533.                     colour++;
  534.                     }
  535.                 break;
  536.             }
  537.         }
  538. }
  539.  
  540. //-------------------------------------------------------------
  541.  
  542. void gsCScreen::drawPoint(const gsCPoint& position,const gsCColour& colour)
  543. {
  544.     if (!m_back_surface) {
  545.         gsREPORT("gsCScreen::drawPoint called with no back surface");
  546.         return;
  547.         }
  548.  
  549.     if (lock()) {
  550.         draw_pixel(position,colour);
  551.         unlock();
  552.         }
  553. }
  554.  
  555. //-------------------------------------------------------------
  556.  
  557. void gsCScreen::draw_hline(int x1,int x2,int y,const gsCColour& colour)
  558. {
  559.     if (x1 > x2) {
  560.         int t = x1;
  561.         x1 = x2;
  562.         x2 = t;
  563.         }
  564.     
  565.     if (x1 >= m_screen_rect.getWidth() ||
  566.         x2 < 0 ||
  567.         y < 0 ||
  568.         y >= m_screen_rect.getHeight())
  569.         return;
  570.  
  571.     if (x1 < 0)
  572.         x1 = 0;
  573.     if (x2 >= m_screen_rect.getWidth())
  574.         x2 = m_screen_rect.getWidth() - 1;
  575.     
  576.     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y * m_ddsd.lPitch
  577.                                                  + x1 * m_bpp;
  578.  
  579.     gsUDWORD raw = colour.getRaw();
  580.  
  581.     int count = x2 + 1 - x1;
  582.  
  583.     switch (m_bpp) {
  584.         case 1:
  585.             {
  586.                 while (count >= 8) {
  587.                     *dest = (gsUBYTE) raw;
  588.                     *(dest + 1) = (gsUBYTE) raw;
  589.                     *(dest + 2) = (gsUBYTE) raw;
  590.                     *(dest + 3) = (gsUBYTE) raw;
  591.                     *(dest + 4) = (gsUBYTE) raw;
  592.                     *(dest + 5) = (gsUBYTE) raw;
  593.                     *(dest + 6) = (gsUBYTE) raw;
  594.                     *(dest + 7) = (gsUBYTE) raw;
  595.                     dest += 8;
  596.                     count -= 8;
  597.                     }
  598.                 while (count-- > 0) {
  599.                     *dest = (gsUBYTE) raw;
  600.                     dest++;
  601.                     }
  602.                 break;
  603.             }
  604.         case 2:
  605.             {
  606.                 while (count >= 8) {
  607.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  608.                     *((gsUWORD *) (dest + 2)) = (gsUWORD) raw;
  609.                     *((gsUWORD *) (dest + 4)) = (gsUWORD) raw;
  610.                     *((gsUWORD *) (dest + 6)) = (gsUWORD) raw;
  611.                     *((gsUWORD *) (dest + 8)) = (gsUWORD) raw;
  612.                     *((gsUWORD *) (dest + 10)) = (gsUWORD) raw;
  613.                     *((gsUWORD *) (dest + 12)) = (gsUWORD) raw;
  614.                     *((gsUWORD *) (dest + 14)) = (gsUWORD) raw;
  615.                     dest += 16;
  616.                     count -= 8;
  617.                     }
  618.                 while (count-- > 0) {
  619.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  620.                     dest += 2;
  621.                     }
  622.                 break;
  623.             }
  624.         case 3:
  625.             {
  626.                 while (count >= 8) {
  627.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  628.                     *(dest + 2) = (gsUBYTE) (raw >> 16);
  629.                     *((gsUWORD *) (dest + 3)) = (gsUWORD) raw;
  630.                     *(dest + 5) = (gsUBYTE) (raw >> 16);
  631.                     *((gsUWORD *) (dest + 6)) = (gsUWORD) raw;
  632.                     *(dest + 8) = (gsUBYTE) (raw >> 16);
  633.                     *((gsUWORD *) (dest + 9)) = (gsUWORD) raw;
  634.                     *(dest + 11) = (gsUBYTE) (raw >> 16);
  635.                     *((gsUWORD *) (dest + 12)) = (gsUWORD) raw;
  636.                     *(dest + 14) = (gsUBYTE) (raw >> 16);
  637.                     *((gsUWORD *) (dest + 15)) = (gsUWORD) raw;
  638.                     *(dest + 17) = (gsUBYTE) (raw >> 16);
  639.                     *((gsUWORD *) (dest + 18)) = (gsUWORD) raw;
  640.                     *(dest + 20) = (gsUBYTE) (raw >> 16);
  641.                     *((gsUWORD *) (dest + 21)) = (gsUWORD) raw;
  642.                     *(dest + 23) = (gsUBYTE) (raw >> 16);
  643.                     dest += 24;
  644.                     count -= 8;
  645.                     }
  646.                 while (count-- > 0) {
  647.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  648.                     *(dest + 2) = (gsUBYTE) (raw >> 16);
  649.                     dest += 3;
  650.                     }
  651.                 break;
  652.             }
  653.         case 4:
  654.             {
  655.                 while (count >= 8) {
  656.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  657.                     *((gsUWORD *) (dest + 2)) = (gsUWORD) (raw >> 16);
  658.                     *((gsUWORD *) (dest + 4)) = (gsUWORD) raw;
  659.                     *((gsUWORD *) (dest + 6)) = (gsUWORD) (raw >> 16);
  660.                     *((gsUWORD *) (dest + 8)) = (gsUWORD) raw;
  661.                     *((gsUWORD *) (dest + 10)) = (gsUWORD) (raw >> 16);
  662.                     *((gsUWORD *) (dest + 12)) = (gsUWORD) raw;
  663.                     *((gsUWORD *) (dest + 14)) = (gsUWORD) (raw >> 16);
  664.                     *((gsUWORD *) (dest + 16)) = (gsUWORD) raw;
  665.                     *((gsUWORD *) (dest + 18)) = (gsUWORD) (raw >> 16);
  666.                     *((gsUWORD *) (dest + 20)) = (gsUWORD) raw;
  667.                     *((gsUWORD *) (dest + 22)) = (gsUWORD) (raw >> 16);
  668.                     *((gsUWORD *) (dest + 24)) = (gsUWORD) raw;
  669.                     *((gsUWORD *) (dest + 26)) = (gsUWORD) (raw >> 16);
  670.                     *((gsUWORD *) (dest + 28)) = (gsUWORD) raw;
  671.                     *((gsUWORD *) (dest + 30)) = (gsUWORD) (raw >> 16);
  672.                     dest += 32;
  673.                     count -= 8;
  674.                     }
  675.                 while (count-- > 0) {
  676.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  677.                     *((gsUWORD *) (dest + 2)) = (gsUWORD) (raw >> 16);
  678.                     dest += 4;
  679.                     }
  680.             }
  681.             break;
  682.         }
  683. }
  684.  
  685. //-------------------------------------------------------------
  686.  
  687. void gsCScreen::draw_vline(int x,int y1,int y2,const gsCColour& colour)
  688. {
  689.     if (y1 > y2) {
  690.         int t = y1;
  691.         y1 = y2;
  692.         y2 = t;
  693.         }
  694.     
  695.     if (y1 >= m_screen_rect.getHeight() ||
  696.         y2 < 0 ||
  697.         x < 0 ||
  698.         x >= m_screen_rect.getWidth())
  699.         return;
  700.  
  701.     if (y1 < 0)
  702.         y1 = 0;
  703.     if (y2 >= m_screen_rect.getHeight())
  704.         y2 = m_screen_rect.getHeight() - 1;
  705.     
  706.     gsUBYTE *dest = (gsUBYTE *) m_ddsd.lpSurface + y1 * m_ddsd.lPitch
  707.                                                  + x * m_bpp;
  708.  
  709.     gsUDWORD raw = colour.getRaw();
  710.  
  711.     int count = y2 + 1 - y1;
  712.  
  713.     switch (m_bpp) {
  714.         case 1:
  715.             {
  716.                 while (count-- > 0) {
  717.                     *dest = (gsUBYTE) raw;
  718.                     dest += m_ddsd.lPitch;
  719.                     }
  720.                 break;
  721.             }
  722.         case 2:
  723.             {
  724.                 while (count-- > 0) {
  725.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  726.                     dest += m_ddsd.lPitch;
  727.                     }
  728.                 break;
  729.             }
  730.         case 3:
  731.             {
  732.                 while (count-- > 0) {
  733.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  734.                     *(dest + 2) = (gsUBYTE) (raw >> 16);
  735.                     dest += m_ddsd.lPitch;
  736.                     }
  737.                 break;
  738.             }
  739.         case 4:
  740.             {
  741.                 while (count-- > 0) {
  742.                     *((gsUWORD *) dest) = (gsUWORD) raw;
  743.                     *((gsUWORD *) (dest + 2)) = (gsUWORD) (raw >> 16);
  744.                     dest += m_ddsd.lPitch;
  745.                     }
  746.             }
  747.             break;
  748.         }
  749. }
  750.  
  751. //-------------------------------------------------------------
  752.  
  753. void gsCScreen::drawLine(const gsCPoint& from,const gsCPoint& to,const gsCColour& colour)
  754. {
  755.     if (from.getX() == to.getX()) {
  756.         if (lock()) {
  757.             draw_vline(from.getX(),from.getY(),to.getY(),colour);
  758.             unlock();
  759.             }
  760.         }
  761.     else if (from.getY() == to.getY()) {
  762.         if (lock()) {
  763.             draw_hline(from.getX(),to.getX(),from.getY(),colour);
  764.             unlock();
  765.             }
  766.         }
  767.     else
  768.         gsREPORT("gsCScreen::drawLine not yet fully implemented");
  769. }
  770.  
  771. //-------------------------------------------------------------
  772.  
  773. void gsCScreen::drawRect(const gsCRect& rect,const gsCColour& colour)
  774. {
  775.     if (!rect.isEmpty()) {
  776.         if (lock()) {
  777.             draw_hline(rect.getLeft(),rect.getRight(),rect.getTop(),colour);
  778.             draw_hline(rect.getLeft(),rect.getRight(),rect.getBottom(),colour);
  779.             draw_vline(rect.getLeft(),rect.getTop(),rect.getBottom(),colour);
  780.             draw_vline(rect.getRight(),rect.getTop(),rect.getBottom(),colour);
  781.             unlock();
  782.             }
  783.         }
  784. }    
  785.  
  786. //-------------------------------------------------------------
  787.     
  788. bool gsCScreen::drawSolidRect(const gsCRect& rect,const gsCColour& colour)
  789. {
  790.     if (!m_back_surface) {
  791.         gsREPORT("gsCScreen::drawSolidRect called with no back surface");
  792.         return false;
  793.         }
  794.  
  795.     m_ddbltfx.dwFillColor = colour.getRaw();
  796.  
  797.     gsCRect r = rect;
  798.  
  799.     getRect().clip(r);
  800.  
  801.     if (r.isEmpty())
  802.         return false;
  803.  
  804.     HRESULT hr;
  805.  
  806.     hr = m_back_surface->Blt(LPRECT(r),
  807.                              NULL,
  808.                              NULL,
  809.                              DDBLT_COLORFILL | DDBLT_WAIT,
  810.                              &m_ddbltfx);
  811.  
  812.     if (hr != DD_OK)
  813.         gsREPORT("gsCScreen::drawSolidRect blit failed");
  814.  
  815.     return true;
  816. }
  817.  
  818. //-------------------------------------------------------------
  819.  
  820. void gsCScreen::drawPoints(int num_points,const gsCPoint *points,const gsCColour *colours,bool clip)
  821. {
  822.     if (!m_back_surface) {
  823.         gsREPORT("gsCScreen::drawPoint called with no back surface");
  824.         return;
  825.         }
  826.  
  827.     if (lock()) {
  828.         draw_pixels(num_points,points,colours,clip);
  829.         unlock();
  830.         }
  831. }
  832.  
  833. //-------------------------------------------------------------
  834.  
  835. void gsCScreen::drawLines(int num_points,const gsCPoint *points,const gsCColour *colours)
  836. {
  837.     gsREPORT("gsCScreen::drawLines not yet implemented");
  838. }
  839.  
  840. //-------------------------------------------------------------
  841. // Blit image in solid colour
  842. //
  843. // Pixel which are non-MAGENTA are drawn in the fill colour
  844.  
  845. bool gsCScreen::bltSolid(const gsCRect& dest,gsDDSURFACEDESC& source_ddsd,const gsCRect& source,const gsCColour& fill_colour)
  846. {
  847.     if (lock()) {
  848.     
  849.         gsUBYTE *src = (gsUBYTE *) source_ddsd.lpSurface + source.getTop() * source_ddsd.lPitch
  850.                                                          + source.getLeft() * m_bpp;
  851.         
  852.         gsUBYTE *dst = (gsUBYTE *) m_ddsd.lpSurface + dest.getTop() * m_ddsd.lPitch
  853.                                                     + dest.getLeft() * m_bpp;
  854.  
  855.         gsUDWORD trans = gsCColour(gsMAGENTA).getRaw();
  856.         gsUDWORD fill = fill_colour.getRaw();
  857.  
  858.         int h = dest.getHeight();
  859.         int w = dest.getWidth();
  860.  
  861.         switch (m_bpp) {
  862.             case 1:
  863.                 {
  864.                     while (h-- > 0) {
  865.                         gsUBYTE *s = (gsUBYTE *) src;
  866.                         gsUBYTE *d = (gsUBYTE *) dst;
  867.                         int count = w;
  868.                         while (count >= 4) {
  869.                             if (*s != (gsUBYTE) trans)
  870.                                 *d = (gsUBYTE) fill;
  871.                             if (*(s + 1) != (gsUBYTE) trans)
  872.                                 *(d + 1) = (gsUBYTE) fill;
  873.                             if (*(s + 2) != (gsUBYTE) trans)
  874.                                 *(d + 2) = (gsUBYTE) fill;
  875.                             if (*(s + 3) != (gsUBYTE) trans)
  876.                                 *(d + 3) = (gsUBYTE) fill;
  877.                             s += 4;
  878.                             d += 4;
  879.                             count -= 4;
  880.                             }
  881.                         while (count-- > 0) {
  882.                             if (*s != (gsUBYTE) trans)
  883.                                 *d = (gsUBYTE) fill;
  884.                             s++;
  885.                             d++;
  886.                             }
  887.                         src += source_ddsd.lPitch;
  888.                         dst += m_ddsd.lPitch;
  889.                         }
  890.                 }
  891.                 break;
  892.             case 2:
  893.                 {
  894.                     while (h-- > 0) {
  895.                         gsUWORD *s = (gsUWORD *) src;
  896.                         gsUWORD *d = (gsUWORD *) dst;
  897.                         int count = w;
  898.                         while (count >= 4) {
  899.                             if (*s != (gsUWORD) trans)
  900.                                 *d = (gsUWORD) fill;
  901.                             if (*(s + 1) != (gsUWORD) trans)
  902.                                 *(d + 1) = (gsUWORD) fill;
  903.                             if (*(s + 2) != (gsUWORD) trans)
  904.                                 *(d + 2) = (gsUWORD) fill;
  905.                             if (*(s + 3) != (gsUWORD) trans)
  906.                                 *(d + 3) = (gsUWORD) fill;
  907.                             s += 4;
  908.                             d += 4;
  909.                             count -= 4;
  910.                             }
  911.                         while (count-- > 0) {
  912.                             if (*s != (gsUWORD) trans)
  913.                                 *d = (gsUWORD) fill;
  914.                             s++;
  915.                             d++;
  916.                             }
  917.                         src += source_ddsd.lPitch;
  918.                         dst += m_ddsd.lPitch;
  919.                         }
  920.                 }
  921.                 break;
  922.             case 3:
  923.                 {
  924.                     while (h-- > 0) {
  925.                         gsUBYTE *s = (gsUBYTE *) src;
  926.                         gsUBYTE *d = (gsUBYTE *) dst;
  927.                         int count = w;
  928.                         gsUBYTE trans_h = (gsUBYTE) (trans >> 16);
  929.                         gsUBYTE fill_h = (gsUBYTE) (fill >> 16);
  930.                         while (count >= 4) {
  931.                             if (*((gsUWORD *) s) != (gsUWORD) trans || *(s + 2) != trans_h) {
  932.                                 *((gsUWORD *) d) = (gsUWORD) fill;
  933.                                 *(d + 2) = fill_h;
  934.                                 }
  935.                             if (*((gsUWORD *) (s + 3)) != (gsUWORD) trans || *(s + 5) != trans_h) {
  936.                                 *((gsUWORD *) (d + 3)) = (gsUWORD) fill;
  937.                                 *(d + 6) = fill_h;
  938.                                 }
  939.                             if (*((gsUWORD *) (s + 6)) != (gsUWORD) trans || *(s + 8) != trans_h) {
  940.                                 *((gsUWORD *) (d + 6)) = (gsUWORD) fill;
  941.                                 *(d + 9) = fill_h;
  942.                                 }
  943.                             if (*((gsUWORD *) (s + 9)) != (gsUWORD) trans || *(s + 11) != trans_h) {
  944.                                 *((gsUWORD *) (d + 9)) = (gsUWORD) fill;
  945.                                 *(d + 11) = fill_h;
  946.                                 }
  947.                             s += 12;
  948.                             d += 12;
  949.                             count -= 3;
  950.                             }
  951.                         while (count-- > 0) {
  952.                             if (*((gsUWORD *) s) != (gsUWORD) trans || *(s + 2) != trans_h) {
  953.                                 *((gsUWORD *) d) = (gsUWORD) fill;
  954.                                 *(d + 2) = fill_h;
  955.                                 }
  956.                             s += 3;
  957.                             d += 3;
  958.                             }
  959.                         src += source_ddsd.lPitch;
  960.                         dst += m_ddsd.lPitch;
  961.                         }
  962.                 }
  963.                 break;
  964.             case 4:
  965.                 {
  966.                     while (h-- > 0) {
  967.                         gsUBYTE *s = (gsUBYTE *) src;
  968.                         gsUBYTE *d = (gsUBYTE *) dst;
  969.                         int count = w;
  970.                         gsUBYTE trans_h = (gsUBYTE) (trans >> 16);
  971.                         gsUBYTE fill_h = (gsUBYTE) (fill >> 16);
  972.                         while (count >= 4) {
  973.                             if (*((gsUWORD *) s) != (gsUWORD) trans || *(s + 2) != trans_h) {
  974.                                 *((gsUWORD *) d) = (gsUWORD) fill;
  975.                                 *(d + 2) = fill_h;
  976.                                 }
  977.                             if (*((gsUWORD *) (s + 4)) != (gsUWORD) trans || *(s + 6) != trans_h) {
  978.                                 *((gsUWORD *) (d + 4)) = (gsUWORD) fill;
  979.                                 *(d + 6) = fill_h;
  980.                                 }
  981.                             if (*((gsUWORD *) (s + 8)) != (gsUWORD) trans || *(s + 10) != trans_h) {
  982.                                 *((gsUWORD *) (d + 8)) = (gsUWORD) fill;
  983.                                 *(d + 10) = fill_h;
  984.                                 }
  985.                             if (*((gsUWORD *) (s + 12)) != (gsUWORD) trans || *(s + 14) != trans_h) {
  986.                                 *((gsUWORD *) (d + 12)) = (gsUWORD) fill;
  987.                                 *(d + 14) = fill_h;
  988.                                 }
  989.                             s += 16;
  990.                             d += 16;
  991.                             count -= 4;
  992.                             }
  993.                         while (count-- > 0) {
  994.                             if (*((gsUWORD *) s) != (gsUWORD) trans || *(s + 2) != trans_h) {
  995.                                 *((gsUWORD *) d) = (gsUWORD) fill;
  996.                                 *(d + 2) = fill_h;
  997.                                 }
  998.                             s += 4;
  999.                             d += 4;
  1000.                             }
  1001.                         src += source_ddsd.lPitch;
  1002.                         dst += m_ddsd.lPitch;
  1003.                         }
  1004.                 }
  1005.                 break;
  1006.             }
  1007.  
  1008.         unlock();
  1009.  
  1010.         return true;
  1011.         }
  1012.  
  1013.     return false;
  1014. }
  1015.  
  1016. //-------------------------------------------------------------
  1017. // Blit image with colour tint
  1018. //
  1019. // Pixels which are white are replaced by the tint colour
  1020. // Other pixels are drawn normally
  1021.  
  1022. bool gsCScreen::bltTinted(const gsCRect& dest,gsDDSURFACEDESC& source_ddsd,const gsCRect& source,const gsCColour& tint_colour)
  1023. {
  1024.     if (lock()) {
  1025.     
  1026.         gsUBYTE *src = (gsUBYTE *) source_ddsd.lpSurface + source.getTop() * source_ddsd.lPitch
  1027.                                                          + source.getLeft() * m_bpp;
  1028.         
  1029.         gsUBYTE *dst = (gsUBYTE *) m_ddsd.lpSurface + dest.getTop() * m_ddsd.lPitch
  1030.                                                     + dest.getLeft() * m_bpp;
  1031.  
  1032.         gsUDWORD base = gsCColour(gsWHITE).getRaw();
  1033.         gsUDWORD tint = tint_colour.getRaw();
  1034.  
  1035.         int h = dest.getHeight();
  1036.         int w = dest.getWidth();
  1037.  
  1038.         switch (m_bpp) {
  1039.             case 1:
  1040.                 {
  1041.                     while (h-- > 0) {
  1042.                         gsUBYTE *s = (gsUBYTE *) src;
  1043.                         gsUBYTE *d = (gsUBYTE *) dst;
  1044.                         int count = w;
  1045.                         while (count >= 4) {
  1046.                             if (*s == (gsUBYTE) base)
  1047.                                 *d = (gsUBYTE) tint;
  1048.                             else
  1049.                                 *d = *s;
  1050.                             if (*(s + 1) == (gsUBYTE) base)
  1051.                                 *(d + 1) = (gsUBYTE) tint;
  1052.                             else
  1053.                                 *(d + 1) = *(s + 1);
  1054.                             if (*(s + 2) == (gsUBYTE) base)
  1055.                                 *(d + 2) = (gsUBYTE) tint;
  1056.                             else
  1057.                                 *(d + 2) = *(s + 2);
  1058.                             if (*(s + 3) == (gsUBYTE) base)
  1059.                                 *(d + 3) = (gsUBYTE) tint;
  1060.                             else
  1061.                                 *(d + 3) = *(s + 3);
  1062.                             s += 4;
  1063.                             d += 4;
  1064.                             count -= 4;
  1065.                             }
  1066.                         while (count-- > 0) {
  1067.                             if (*s == (gsUBYTE) base)
  1068.                                 *d = (gsUBYTE) tint;
  1069.                             else
  1070.                                 *d = *s;
  1071.                             }
  1072.                         src += source_ddsd.lPitch;
  1073.                         dst += m_ddsd.lPitch;
  1074.                         }
  1075.                 }
  1076.                 break;
  1077.             case 2:
  1078.                 {
  1079.                     while (h-- > 0) {
  1080.                         gsUWORD *s = (gsUWORD *) src;
  1081.                         gsUWORD *d = (gsUWORD *) dst;
  1082.                         int count = w;
  1083.                         while (count >= 4) {
  1084.                             if (*s == (gsUWORD) base)
  1085.                                 *d = (gsUWORD) tint;
  1086.                             else
  1087.                                 *d = *s;
  1088.                             if (*(s + 1) == (gsUWORD) base)
  1089.                                 *(d + 1) = (gsUWORD) tint;
  1090.                             else
  1091.                                 *(d + 1) = *(s + 1);
  1092.                             if (*(s + 2) == (gsUWORD) base)
  1093.                                 *(d + 2) = (gsUWORD) tint;
  1094.                             else
  1095.                                 *(d + 3) = *(s + 3);
  1096.                             if (*(s + 3) == (gsUWORD) base)
  1097.                                 *(d + 3) = (gsUWORD) tint;
  1098.                             else
  1099.                                 *(d + 3) = *(s + 3);
  1100.                             s += 4;
  1101.                             d += 4;
  1102.                             count -= 4;
  1103.                             }
  1104.                         while (count-- > 0) {
  1105.                             if (*s != (gsUWORD) base)
  1106.                                 *d = (gsUWORD) tint;
  1107.                             else
  1108.                                 *d = *s;
  1109.                             s++;
  1110.                             d++;
  1111.                             }
  1112.                         src += source_ddsd.lPitch;
  1113.                         dst += m_ddsd.lPitch;
  1114.                         }
  1115.                 }
  1116.                 break;
  1117.             case 3:
  1118.                 {
  1119.                     while (h-- > 0) {
  1120.                         gsUBYTE *s = (gsUBYTE *) src;
  1121.                         gsUBYTE *d = (gsUBYTE *) dst;
  1122.                         int count = w;
  1123.                         gsUBYTE base_h = (gsUBYTE) (base >> 16);
  1124.                         gsUBYTE tint_h = (gsUBYTE) (tint >> 16);
  1125.                         while (count-- > 0) {
  1126.                             if (*((gsUWORD *) s) == (gsUWORD) base &&
  1127.                                 *(s + 2) == base_h) {
  1128.                                 *((gsUWORD *) d) = (gsUWORD) tint;
  1129.                                 *(d + 2) = tint_h;
  1130.                                 }
  1131.                             else {
  1132.                                 *((gsUWORD *) d) = *((gsUWORD *) s);
  1133.                                 *(d + 2) = *(s + 2);
  1134.                                 }
  1135.                             s += 3;
  1136.                             d += 3;
  1137.                             }
  1138.                         src += source_ddsd.lPitch;
  1139.                         dst += m_ddsd.lPitch;
  1140.                         }
  1141.                 }
  1142.                 break;
  1143.             case 4:
  1144.                 {
  1145.                     while (h-- > 0) {
  1146.                         gsUBYTE *s = (gsUBYTE *) src;
  1147.                         gsUBYTE *d = (gsUBYTE *) dst;
  1148.                         int count = w;
  1149.                         gsUBYTE base_h = (gsUBYTE) (base >> 16);
  1150.                         gsUBYTE tint_h = (gsUBYTE) (tint >> 16);
  1151.                         while (count-- > 0) {
  1152.                             if (*((gsUWORD *) s) == (gsUWORD) base &&
  1153.                                 *(s + 2) == base_h) {
  1154.                                 *((gsUWORD *) d) = (gsUWORD) tint;
  1155.                                 *(d + 2) = tint_h;
  1156.                                 }
  1157.                             else {
  1158.                                 *((gsUWORD *) d) = *((gsUWORD *) s);
  1159.                                 *(d + 2) = *(s + 2);
  1160.                                 }
  1161.                             s += 4;
  1162.                             d += 4;
  1163.                             }
  1164.                         src += source_ddsd.lPitch;
  1165.                         dst += m_ddsd.lPitch;
  1166.                         }
  1167.                 }
  1168.                 break;
  1169.             }
  1170.  
  1171.         unlock();
  1172.  
  1173.         return true;
  1174.         }
  1175.  
  1176.     return false;
  1177. }
  1178.  
  1179. //-------------------------------------------------------------
  1180.  
  1181. bool gsCScreen::destroy()
  1182. {
  1183.     if (m_display_mode_set) {
  1184.         m_direct_draw->RestoreDisplayMode();
  1185.         m_display_mode_set = false;
  1186.         }
  1187.  
  1188. //    gsCColour::setupColourConversion(0);
  1189.  
  1190.     gsCApplication::m_screen = 0;
  1191.  
  1192.     if (m_clipper) {
  1193.         m_clipper->Release();
  1194.         m_clipper = 0;
  1195.         }
  1196.  
  1197.     if (m_back_surface) {
  1198.         m_back_surface->Release();
  1199.         m_back_surface = 0;
  1200.         }
  1201.  
  1202.     if (m_primary_surface) {
  1203.         m_primary_surface->Release();
  1204.         m_primary_surface = 0;
  1205.         }
  1206.  
  1207.     if (m_palette) {
  1208.         m_palette->Release();
  1209.         m_palette = 0;
  1210.         }
  1211.  
  1212.     gsREPORT("gsCScreen destroyed");
  1213.  
  1214.     return true;
  1215. }
  1216.  
  1217. //-------------------------------------------------------------
  1218.  
  1219. void gsCScreen::findBPP()
  1220. {
  1221.     gsDDSURFACEDESC ddsd;
  1222.     HRESULT hr;
  1223.  
  1224.     ddsd.dwSize = sizeof(ddsd);
  1225.     while ((hr = m_primary_surface->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING);
  1226.  
  1227.     if (hr == DD_OK) {
  1228.         m_bpp = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
  1229.         m_primary_surface->Unlock(NULL);
  1230.         }
  1231. }
  1232.  
  1233. //-------------------------------------------------------------
  1234.  
  1235. int gsCScreen::getBytesPerPixel()
  1236. {
  1237.     return m_bpp;
  1238. }
  1239.  
  1240.  
  1241. //-------------------------------------------------------------
  1242.  
  1243. bool gsCScreen::loadPalette(const char *filename)
  1244. {
  1245.     if (m_bpp != 1)
  1246.         return false;
  1247.  
  1248.     gsCFile file;
  1249.  
  1250.     if (!file.open(filename))
  1251.         return false;
  1252.  
  1253.     int i;
  1254.  
  1255.     for (i = 0; i < 24; i++)
  1256.         file.getByte();
  1257.  
  1258.     for (i = 0; i < 256; i++) {
  1259.         m_palette_colours[i].peRed = (gsBYTE) file.getByte();
  1260.         m_palette_colours[i].peGreen = (gsBYTE) file.getByte();
  1261.         m_palette_colours[i].peBlue = (gsBYTE) file.getByte();
  1262.         m_palette_colours[i].peFlags = 0;
  1263.         file.getByte();
  1264.         }
  1265.  
  1266.     m_palette->SetEntries(0,0,256,m_palette_colours);
  1267.  
  1268.     file.close();
  1269.  
  1270.     return true;
  1271. }
  1272.  
  1273. //-------------------------------------------------------------
  1274.