home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / IKLOWNS / CGIMAGE.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  10KB  |  361 lines

  1. /*===========================================================================*\
  2. |
  3. |  File:        cgimage.cpp
  4. |
  5. |  Description: 
  6. |       
  7. |-----------------------------------------------------------------------------
  8. |
  9. |  Copyright (C) 1995-1996 Microsoft Corporation.  All Rights Reserved.
  10. |
  11. |  Written by Moss Bay Engineering, Inc. under contract to Microsoft Corporation
  12. |
  13. \*===========================================================================*/
  14.  
  15. /**************************************************************************
  16.  
  17.     (C) Copyright 1995-1996 Microsoft Corp.  All rights reserved.
  18.  
  19.     You have a royalty-free right to use, modify, reproduce and 
  20.     distribute the Sample Files (and/or any modified version) in 
  21.     any way you find useful, provided that you agree that 
  22.     Microsoft has no warranty obligations or liability for any 
  23.     Sample Application Files which are modified. 
  24.  
  25.     we do not recomend you base your game on IKlowns, start with one of
  26.     the other simpler sample apps in the GDK
  27.  
  28.  **************************************************************************/
  29.  
  30. #include <windows.h>
  31. #include "cgrsrce.h"
  32. #include "cgexcpt.h"
  33. #include "cgdebug.h"
  34. #include "cgglobl.h"
  35. #include "cgscreen.h"
  36. #include "cglevel.h"
  37. #include "cgupdate.h"
  38. #include "cgimage.h"
  39.  
  40. #define LIMIT(x, low, high) (max(low, min(x, high)))
  41.  
  42. /*---------------------------------------------------------------------------*\
  43. |
  44. |       Class CGameSkyImage
  45. |
  46. |  DESCRIPTION:
  47. |       
  48. |
  49. |
  50. \*---------------------------------------------------------------------------*/
  51.  
  52. // in our palette, entry 13 is a good sky blue
  53. #define SKY_COLOR ( 13 )
  54. // force to background
  55. #define SKY_Z ( 32760 )
  56.  
  57. CGameSkyImage::CGameSkyImage(
  58.     char* pFileName
  59.     ) : CGameImage( pFileName, SKY_Z )
  60. {
  61.     mCurZ = SKY_Z;  
  62. }
  63.  
  64. CGameSkyImage::~CGameSkyImage()
  65. {
  66. }
  67.  
  68. void
  69. CGameSkyImage::Update(
  70.     CGameLevel* pLevel,
  71.     CGameUpdateList* pUpdate
  72.     )
  73. {
  74. }
  75.  
  76. void
  77. CGameSkyImage::Render(
  78.     CGameLevel* pLevel,
  79.     CGameScreen* pScreen,
  80.     CGameUpdateList* pUpdate
  81.     )
  82. {
  83.     pScreen->ColorFill(
  84.             pUpdate->GetDirtyRect(),
  85.             SKY_COLOR
  86.             );
  87. }
  88.  
  89. /*---------------------------------------------------------------------------*\
  90. |
  91. |       Class CGameTiledImage
  92. |
  93. |  DESCRIPTION:
  94. |       
  95. |
  96. |
  97. \*---------------------------------------------------------------------------*/
  98.  
  99. static char tleExt[] = ".tle";
  100.  
  101. CGameTiledImage::CGameTiledImage(
  102.         char* pFileBase,        // file base name
  103.         int curz,
  104.         int curx,
  105.         int cury
  106.         ) : CGameImage( pFileBase, curz ),
  107.             mpDIBBuffer( NULL ),
  108.             mTileArray( NULL )
  109. {
  110.     HANDLE hFile;
  111.  
  112.     if (!pFileBase)
  113.         return;
  114.  
  115.     char* pFileName = new char[lstrlen(pFileBase) + lstrlen(tleExt) + 1];
  116.  
  117.     lstrcpy( pFileName, pFileBase );
  118.     lstrcat( pFileName, tleExt );
  119.  
  120.     // open the .tle file
  121.     hFile = CreateFile(
  122.         pFileName,
  123.         GENERIC_READ,
  124.         0,
  125.         NULL,
  126.         OPEN_EXISTING,
  127.         FILE_ATTRIBUTE_NORMAL,
  128.         NULL
  129.         );
  130.  
  131.     delete[] pFileName;
  132.  
  133.     if (hFile == INVALID_HANDLE_VALUE)
  134.     {
  135.         DB_LOG(DB_PROBLEM, "DEBUG: CreateFile failed in CGameTiledImage");
  136.         throw CGameException(
  137.                 IDS_INVALID_FILE
  138.                 );
  139.     }
  140.  
  141.     TileMapStamp stamp;
  142.  
  143.     DWORD bytesRead;
  144.  
  145.     // file begins with our stamp
  146.     ReadFile(
  147.         hFile,
  148.         &stamp,
  149.         sizeof( stamp ),
  150.         &bytesRead,
  151.         NULL
  152.         );
  153.  
  154.     // verify file is valid tile map
  155.     if ((stamp.signature != TILE_MAP_SIGNATURE) ||
  156.         (stamp.version != TILE_MAP_VERSION) ||
  157.         (stamp.tileSize != TILE_SIZE)
  158.         )
  159.     {
  160.         DB_LOG(DB_PROBLEM, "DEBUG: invalid file stamp in CGameTiledImage");
  161.         throw CGameException(
  162.                 IDS_INVALID_FILE
  163.                 );
  164.     }
  165.  
  166.     // allocate for dib filename (length includes terminator)
  167.     pFileName = new char[stamp.nameLength];
  168.  
  169.     // followed by the tile DIB filename
  170.     ReadFile(
  171.         hFile,
  172.         pFileName,
  173.         stamp.nameLength,
  174.         &bytesRead,
  175.         NULL
  176.         );
  177.  
  178.     // allocate our tile array
  179.     mNumCols = stamp.columns;
  180.     mTileArray = new WORD*[mNumCols];
  181.     mWidth = mNumCols * stamp.tileSize;
  182.     mHeight = stamp.rows * stamp.tileSize;
  183.  
  184.     mXpos = curx;
  185.     mYpos = cury;
  186.  
  187.     // read in the tile map
  188.     for (int col = 0; col < mNumCols; col++)
  189.     {
  190.         mTileArray[col] = new WORD[stamp.rows];
  191.         for (int row = 0; row < stamp.rows; row++)
  192.         {
  193.             ReadFile(
  194.                 hFile,
  195.                 &mTileArray[col][row],
  196.                 sizeof(WORD),
  197.                 &bytesRead,
  198.                 NULL
  199.                 );
  200.         }
  201.     }
  202.  
  203.     CloseHandle( hFile );
  204.  
  205.     // now create a bit buffer for our DIB
  206.     CGameDIB theDib( pFileName );
  207.  
  208.     delete[] pFileName;
  209.  
  210.     if (gUse_DDraw)
  211.     {
  212.         mpDIBBuffer = new CGameDDrawBitBuffer( &theDib );
  213.         if (!mpDIBBuffer->IsValid())
  214.         {
  215.             // we didn't get video memory, so delete that buffer
  216.             delete mpDIBBuffer;
  217.             // & create a system memory one
  218.             mpDIBBuffer = new CGameDSBitBuffer( &theDib );
  219.         }
  220.     }
  221.     else
  222.     {
  223.         mpDIBBuffer = new CGameDSBitBuffer(
  224.                     &theDib,
  225.                     theDib.GetWidth(),
  226.                     theDib.GetHeight(),
  227.                     theDib.GetPixelColor(0,0)
  228.                     );
  229.     }
  230.  
  231.     mCurZ = curz;
  232. }   
  233.  
  234. CGameTiledImage::~CGameTiledImage()
  235. {
  236.     if (mTileArray)
  237.     {
  238.         for (; mNumCols>0; mNumCols--)
  239.         {
  240.             delete[] mTileArray[mNumCols-1];
  241.         }
  242.         delete[] mTileArray;
  243.     }
  244.  
  245.     delete mpDIBBuffer;
  246. }
  247.  
  248. void 
  249. CGameTiledImage::Update(
  250.     CGameLevel* pLevel,
  251.     CGameUpdateList* pUpdate
  252.     )
  253. {
  254.     if (mpNext)
  255.         mpNext->Update(pLevel, pUpdate);
  256. }
  257.  
  258. void
  259. CGameTiledImage::Render(
  260.     CGameLevel* pLevel,
  261.     CGameScreen* pScreen,
  262.     CGameUpdateList* pUpdate
  263.     )
  264. {
  265.     if (mpNext)
  266.     {
  267.         // recurse down the list to get background filled in
  268.         mpNext->Render(pLevel, pScreen, pUpdate);
  269.     }
  270.  
  271.     LPRECT pDirty = pUpdate->GetDirtyRect();
  272.  
  273.     int width = pDirty->right - pDirty->left + 1;
  274.     int height = pDirty->bottom - pDirty->top + 1;
  275.  
  276.     RECT worldUpdate;
  277.  
  278.     worldUpdate.left = pLevel->Screen2WorldX( pDirty->left, mXParallax );
  279.     worldUpdate.top = pLevel->Screen2WorldY( pDirty->top, mYParallax );
  280.     worldUpdate.right = worldUpdate.left + width - 1;
  281.     worldUpdate.bottom = worldUpdate.top + height - 1;
  282.  
  283.     RECT image;
  284.  
  285.     image.left = mXpos;
  286.     image.top = mYpos;
  287.     image.right = mXpos + mWidth - 1;
  288.     image.bottom = mYpos + mHeight - 1;
  289.  
  290.     RECT realImage;
  291.  
  292.     if (IntersectRect( &realImage, &image, &worldUpdate ))
  293.     {
  294.         int offsetX = realImage.left>mXpos?(realImage.left-mXpos) % TILE_SIZE :0;
  295.         int tileWidth = TILE_SIZE - offsetX;
  296.  
  297.         for (
  298.             int worldPixelX = realImage.left;
  299.             worldPixelX <= realImage.right;
  300.             worldPixelX += tileWidth, tileWidth = TILE_SIZE
  301.             )
  302.         {
  303.             int colIndex = (worldPixelX - mXpos) / TILE_SIZE;
  304.             int screenX = pLevel->World2ScreenX( worldPixelX, mXParallax );
  305.  
  306.             int offsetY = realImage.top>mYpos? (realImage.top-mYpos) % TILE_SIZE:0;
  307.             int tileHeight = TILE_SIZE - offsetY;
  308.  
  309.             for (
  310.                 int worldPixelY = realImage.top;
  311.                 worldPixelY <= realImage.bottom;
  312.                 worldPixelY += tileHeight, tileHeight = TILE_SIZE
  313.                 )
  314.             {
  315.                 int rowIndex = (worldPixelY - mYpos) / TILE_SIZE;
  316.                 int screenY = pLevel->World2ScreenY( worldPixelY, mYParallax );
  317.  
  318.                 WORD tileNum = mTileArray[colIndex][rowIndex];
  319.  
  320.                 if (!IS_TRANSPARENT(tileNum))
  321.                 {
  322. //                  int srcX = (TILE_INDEX(tileNum) * TILE_SIZE) + offsetX;
  323.                     int srcX = TILE_SRC_X(tileNum) + offsetX;
  324. //                  int srcY = offsetY;
  325.                     int srcY = TILE_SRC_Y(tileNum) + offsetY;
  326.  
  327.                     if (HAS_TRANSPARENCY(tileNum))
  328.                     {
  329.                         pScreen->TransRender(
  330.                             screenX,
  331.                             screenY,
  332.                             min(tileWidth, realImage.right - worldPixelX + 1),
  333.                             min(tileHeight, realImage.bottom - worldPixelY + 1),
  334.                             mpDIBBuffer,
  335.                             srcX,
  336.                             srcY
  337.                             );
  338.                     }
  339.                     else
  340.                     {
  341.                         pScreen->Render(
  342.                             screenX,
  343.                             screenY,
  344.                             min(tileWidth, realImage.right - worldPixelX + 1),
  345.                             min(tileHeight, realImage.bottom - worldPixelY + 1),
  346.                             mpDIBBuffer,
  347.                             srcX,
  348.                             srcY,
  349.                             SRCCOPY
  350.                             );
  351.                     }
  352.                 }
  353.  
  354.                 offsetY = 0;
  355.             }
  356.  
  357.             offsetX = 0;
  358.         }
  359.     }
  360. }
  361.