home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / gamesystem / source / gs_tiledimage.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-28  |  6.5 KB  |  313 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    gsCTiledImage
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    12/03/00
  8. //
  9. // Base:    gsCImage
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "gamesystem.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. gsCTiledImage::gsCTiledImage()
  20. {
  21.     m_num_tiles = 0;
  22.     m_tile_size = gsCPoint(0,0);
  23.     m_source_rects = 0;
  24. }
  25.  
  26. //-------------------------------------------------------------
  27.  
  28. gsCTiledImage::~gsCTiledImage()
  29. {
  30.     destroy();
  31. }
  32.  
  33. //-------------------------------------------------------------
  34.  
  35. void gsCTiledImage::destroy()
  36. {
  37.     if (m_source_rects) {
  38.         delete [] m_source_rects;
  39.         m_source_rects = 0;
  40.         }
  41.  
  42.     m_num_tiles = 0;
  43.  
  44.     gsCImage::destroy();
  45. }
  46.  
  47. //-------------------------------------------------------------
  48.  
  49. bool gsCTiledImage::load(const char *filename,bool rescale)
  50. {
  51.     if (!gsCImage::load(filename,rescale))
  52.         return false;
  53.  
  54.     return setTileSize(getSize());
  55. }
  56.  
  57. //-------------------------------------------------------------
  58.  
  59. bool gsCTiledImage::calculateSourceRects()
  60. {
  61.     if (m_source_rects) {
  62.         delete [] m_source_rects;
  63.         m_source_rects = 0;
  64.         }
  65.  
  66.     m_num_tiles = 0;
  67.  
  68.     if (m_tile_size.getX() == 0 ||
  69.         m_tile_size.getY() == 0)
  70.         return false;
  71.  
  72.     if (getSize().getX() == 0 ||
  73.         getSize().getY() == 0)
  74.         return false;
  75.  
  76.     int horiz = getSize().getX() / m_tile_size.getX();
  77.     int vert = getSize().getY() / m_tile_size.getY();
  78.  
  79.     m_num_tiles = horiz * vert;
  80.  
  81.     m_source_rects = new gsCRect[m_num_tiles];
  82.  
  83.     int i = 0;
  84.  
  85.     for (int y = 0; y + m_tile_size.getY() <= getSize().getY(); y += m_tile_size.getY()) {
  86.         for (int x = 0; x + m_tile_size.getX() <= getSize().getX(); x += m_tile_size.getX()) {
  87.             m_source_rects[i].setTopLeft(gsCPoint(x,y));
  88.             m_source_rects[i].setBottomRight(gsCPoint(x,y) + m_tile_size);
  89.             i++;
  90.             }
  91.         }
  92.  
  93.     return true;
  94. }
  95.  
  96. //-------------------------------------------------------------
  97.  
  98. bool gsCTiledImage::setTileSize(const gsCPoint& tile_size)
  99. {
  100.     m_tile_size = tile_size;
  101.  
  102.     return calculateSourceRects();
  103. }
  104.  
  105. //-------------------------------------------------------------
  106.  
  107. gsCPoint gsCTiledImage::getTileSize()
  108. {
  109.     return m_tile_size;
  110. }
  111.  
  112. //-------------------------------------------------------------
  113.  
  114. bool gsCTiledImage::draw(int tile,const gsCPoint& position)
  115. {
  116.     if (tile >= m_num_tiles)
  117.         return false;
  118.  
  119.     if (!m_direct_draw) {
  120.         gsREPORT("gsCTiledImage::draw called with no direct draw device");
  121.         return false;
  122.         }
  123.         
  124.     gsCScreen *screen = gsCApplication::getScreen();
  125.  
  126.     if (!screen) {
  127.         gsREPORT("gsCTiledImage::draw called with no active screen");
  128.         return false;
  129.         }
  130.  
  131.     gsCRect dest(position,position + m_tile_size);
  132.  
  133.     if (screen->getRect().contains(dest)) {
  134.         
  135.         HRESULT hr;
  136.  
  137.         hr = screen->getBackSurface()->Blt(LPRECT(dest),
  138.                                            m_surface,
  139.                                            m_source_rects[tile],
  140.                                            DDBLT_WAIT | m_colour_key,
  141.                                            NULL);
  142.  
  143.         if (hr != DD_OK) {
  144.             gsREPORT("gsCTiledImage::draw blit failed");
  145.             return false;
  146.             }
  147.         }
  148.     else {
  149.         if (!screen->getRect().overlaps(dest))
  150.             return false;
  151.  
  152.         gsCRect source = m_source_rects[tile];
  153.  
  154.         screen->getRect().clip(source,dest);
  155.         
  156.         HRESULT hr;
  157.  
  158.         hr = screen->getBackSurface()->Blt(LPRECT(dest),
  159.                                            m_surface,
  160.                                            LPRECT(source),
  161.                                            DDBLT_WAIT | m_colour_key,
  162.                                            NULL);
  163.  
  164.         if (hr != DD_OK) {
  165.             gsREPORT("gsCTiledImage::draw blit failed");
  166.             return false;
  167.             }
  168.         }
  169.  
  170.     return true;
  171. }
  172.  
  173. //-------------------------------------------------------------
  174.  
  175. bool gsCTiledImage::drawSolid(int tile,const gsCPoint& position,const gsCColour& fill_colour)
  176. {
  177.     if (tile >= m_num_tiles)
  178.         return false;
  179.  
  180.     if (!m_direct_draw) {
  181.         gsREPORT("gsCTiledImage::draw called with no direct draw device");
  182.         return false;
  183.         }
  184.         
  185.     gsCScreen *screen = gsCApplication::getScreen();
  186.  
  187.     if (!screen) {
  188.         gsREPORT("gsCTiledImage::draw called with no active screen");
  189.         return false;
  190.         }
  191.  
  192.     gsCRect dest(position,position + m_tile_size);
  193.  
  194.     if (screen->getRect().contains(dest)) {
  195.     
  196.         bool ok = false;
  197.  
  198.         if (lock()) {
  199.             ok = screen->bltSolid(dest,m_ddsd,m_source_rects[tile],fill_colour);
  200.             unlock();
  201.             }
  202.         if (!ok) {
  203.             gsREPORT("gsCTiledImage::drawSolid blit failed");
  204.             return false;
  205.             }
  206.         }
  207.     else {
  208.         if (!screen->getRect().overlaps(dest))
  209.             return false;
  210.  
  211.         gsCRect source = m_source_rects[tile];
  212.  
  213.         screen->getRect().clip(source,dest);
  214.  
  215.         bool ok = false;
  216.  
  217.         if (lock()) {
  218.             ok = screen->bltSolid(dest,m_ddsd,source,fill_colour);
  219.             unlock();
  220.             }
  221.         if (!ok) {
  222.             gsREPORT("gsCTiledImage::drawSolid blit failed");
  223.             return false;
  224.             }
  225.         }
  226.  
  227.     return true;
  228. }
  229.  
  230. //-------------------------------------------------------------
  231.  
  232. bool gsCTiledImage::drawTinted(int tile,const gsCPoint& position,const gsCColour& tint_colour)
  233. {
  234.     if (tile >= m_num_tiles)
  235.         return false;
  236.  
  237.     if (!m_direct_draw) {
  238.         gsREPORT("gsCTiledImage::draw called with no direct draw device");
  239.         return false;
  240.         }
  241.         
  242.     gsCScreen *screen = gsCApplication::getScreen();
  243.  
  244.     if (!screen) {
  245.         gsREPORT("gsCTiledImage::draw called with no active screen");
  246.         return false;
  247.         }
  248.  
  249.     gsCRect dest(position,position + m_tile_size);
  250.  
  251.     if (screen->getRect().contains(dest)) {
  252.  
  253.         bool ok = false;
  254.  
  255.         if (lock()) {
  256.             ok = screen->bltTinted(dest,m_ddsd,m_source_rects[tile],tint_colour);
  257.             unlock();
  258.             }
  259.         if (!ok) {
  260.             gsREPORT("gsCTiledImage::drawTinted blit failed");
  261.             return false;
  262.             }
  263.         }
  264.     else {
  265.         if (!screen->getRect().overlaps(dest))
  266.             return false;
  267.  
  268.         gsCRect source = m_source_rects[tile];
  269.  
  270.         screen->getRect().clip(source,dest);
  271.  
  272.         bool ok = false;
  273.  
  274.         if (lock()) {
  275.             ok = screen->bltTinted(dest,m_ddsd,source,tint_colour);
  276.             unlock();
  277.             }
  278.         if (!ok) {
  279.             gsREPORT("gsCTiledImage::drawTinted blit failed");
  280.             return false;
  281.             }
  282.         }
  283.  
  284.     return true;
  285. }
  286.  
  287. //-------------------------------------------------------------
  288.  
  289. bool gsCTiledImage::drawFast(int tile,const gsCPoint& position)
  290. {
  291.     gsCScreen *screen = gsCApplication::getScreen();
  292.  
  293.     HRESULT hr;
  294.  
  295.     gsCRect dest(position,position + m_tile_size);
  296.  
  297.     hr = screen->getBackSurface()->Blt(LPRECT(dest),
  298.                                        m_surface,
  299.                                        m_source_rects[tile],
  300.                                        DDBLT_WAIT | m_colour_key,
  301.                                        NULL);
  302.  
  303.     if (hr != DD_OK) {
  304.         gsREPORT("gsCTiledImage::drawFast blit failed");
  305.         return false;
  306.         }
  307.  
  308.     return true;
  309. }
  310.  
  311. //-------------------------------------------------------------
  312.  
  313.