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

  1. /*===========================================================================*\
  2. |
  3. |  File:        cgscreen.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 <windowsx.h>
  32. #include "cgdebug.h"
  33. #include "cgbitbuf.h"
  34. #include "cgscreen.h"
  35.  
  36. // read a .pal file & convert to PALETTEENTRY array
  37. void
  38. ReadPalFile( char* pFile, LPPALETTEENTRY ppe, int count )
  39. {
  40.     int fh;
  41.     WORD i;
  42.     unsigned char   pRgb[4];
  43.  
  44.     fh = _lopen( pFile, OF_READ);
  45.     if( fh == -1 )
  46.     {
  47.         DB_LOG(DB_PROBLEM, "Can't open palette file.");
  48.         return;
  49.     }
  50.  
  51.     _llseek(fh, 24, SEEK_SET);  
  52.  
  53.     for( i=0; i < min(256, count); i++ )
  54.     {
  55.         if( sizeof (pRgb) != _lread (fh, pRgb, sizeof (pRgb)))
  56.         {
  57.             _lclose( fh );
  58.             return;
  59.         }
  60.         ppe[i].peRed = (BYTE)pRgb[0];
  61.         ppe[i].peGreen = (BYTE)pRgb[1];
  62.         ppe[i].peBlue = (BYTE)pRgb[2];
  63.     }
  64.  
  65.     ppe[0].peRed = (BYTE)0;
  66.     ppe[0].peGreen = (BYTE)0;
  67.     ppe[0].peBlue = (BYTE)0;
  68.  
  69.     if (count >= 256)
  70.     {
  71.         ppe[255].peRed = (BYTE)255;
  72.         ppe[255].peGreen = (BYTE)255;
  73.         ppe[255].peBlue = (BYTE)255;
  74.     }
  75.  
  76.     _lclose( fh );
  77. }
  78.  
  79. /*---------------------------------------------------------------------------*\
  80. |
  81. |       Class CGameScreen
  82. |
  83. |  DESCRIPTION:
  84. |       Encapsulates access to video display in Manhattan sample game
  85. |
  86. |
  87. \*---------------------------------------------------------------------------*/
  88. CGameScreen::CGameScreen(
  89.         HWND hwnd,          // this window determines "screen" size
  90.         int logWidth,
  91.         int logHeight,
  92.         int orgX,
  93.         int orgY
  94.         ) : mxCurrent( orgX ),
  95.             myCurrent( orgY ),
  96.             mhwnd( hwnd ),
  97.             mOutWidth( 0 ),
  98.             mOutHeight( 0 ),
  99.             mOldPalette( NULL )
  100. {
  101.     DB_CHECK( hwnd, "DEBUG: NULL hwnd in CGameScreen.");
  102.  
  103.     if (hwnd)
  104.     {
  105.         HDC hdc = GetDC( hwnd );
  106.  
  107.         // save previous palette
  108.                 mOldPalette = (HPALETTE)GetCurrentObject( hdc, OBJ_PAL );
  109.  
  110.         //now tell Windows to let us set our palette
  111. //      SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC );
  112.  
  113.         // determine size of output bitmap
  114.         if (GetClientRect( hwnd, &mScreenRect ))
  115.         {
  116.             mOutWidth = mScreenRect.right;
  117.             mOutHeight = mScreenRect.bottom;
  118.  
  119.             PatBlt(hdc, 0,0,mOutWidth,mOutHeight,BLACKNESS);
  120.         }
  121.         else
  122.         {
  123.             DB_LOG( DB_PROBLEM, "DEBUG: GetClientRect failed in CGameScreen" );
  124.         }
  125.  
  126.         ReleaseDC( hwnd, hdc );
  127.     }
  128. }   
  129.  
  130. CGameScreen::~CGameScreen()
  131. {
  132.     HDC hdc = GetDC( HWND_DESKTOP );
  133.  
  134.     PatBlt(hdc, 0,0,mOutWidth,mOutHeight,BLACKNESS);
  135.     if (mOldPalette)
  136.     {
  137.         SelectPalette( hdc, mOldPalette, FALSE );
  138.     }
  139.  
  140. //  SetSystemPaletteUse( hdc, SYSPAL_STATIC );
  141.     RealizePalette( hdc );
  142.  
  143.     ReleaseDC( HWND_DESKTOP, hdc );
  144. }   
  145.  
  146. void CGameScreen::SetPalette(HPALETTE hPal)
  147. {
  148.     HDC hdc = GetDC( HWND_DESKTOP );
  149.  
  150.     SelectPalette( hdc, hPal, FALSE );
  151.  
  152.     RealizePalette( hdc );
  153.  
  154.     ReleaseDC( HWND_DESKTOP, hdc );
  155. }
  156.  
  157. /*---------------------------------------------------------------------------*\
  158. |
  159. |       Class CGameDDrawScreen
  160. |
  161. |  DESCRIPTION:
  162. |       provide screen access via DirectDraw
  163. |
  164. |
  165. \*---------------------------------------------------------------------------*/
  166.  
  167. #define FRONT_BUFFER 0
  168. #define BACK_BUFFER 1
  169.  
  170. CGameDDrawScreen::CGameDDrawScreen(
  171.         HWND hwnd,          // this window determines "screen" size
  172.         int logWidth,
  173.         int logHeight,
  174.         int orgX,
  175.         int orgY
  176.         ) : CGameScreen( hwnd, logWidth, orgX, orgY ),
  177.             mBackSurface( 1 )
  178. {
  179.     // create the primary surfaces (front & back)
  180.     mpSurfaces[0] = new CGameDDrawScreenBuffer;
  181.     mpSurfaces[1] = new CGameDDrawScreenBuffer(mpSurfaces[0]);
  182. }
  183.  
  184. CGameDDrawScreen::~CGameDDrawScreen()
  185. {
  186.     delete mpSurfaces[1];
  187.     delete mpSurfaces[0];
  188. }   
  189.  
  190. void CGameDDrawScreen::Render(
  191.     int xDest,
  192.     int yDest,
  193.     int wDest,
  194.     int hDest,
  195.     CGameBitBuffer* pSrcBuffer,
  196.     int xSrc,
  197.     int ySrc,
  198.     DWORD rop
  199.     )
  200. {
  201.     pSrcBuffer->BltDDraw(
  202.         mpSurfaces[BACK_BUFFER],
  203.         xDest,
  204.         yDest,
  205.         wDest,
  206.         hDest,
  207.         xSrc,
  208.         ySrc,
  209.         rop
  210.         );
  211. }   
  212.  
  213. void CGameDDrawScreen::TransRender(
  214.     int xDest,
  215.     int yDest,
  216.     int wDest,
  217.     int hDest,
  218.     CGameBitBuffer* pSrcBuffer,
  219.     int xSrc,
  220.     int ySrc
  221.     )
  222. {
  223.     pSrcBuffer->TransBltDDraw(
  224.         (CGameDDrawBitBuffer*) mpSurfaces[BACK_BUFFER],
  225.         xDest,
  226.         yDest,
  227.         wDest,
  228.         hDest,
  229.         xSrc,
  230.         ySrc,
  231.         1
  232.         );
  233. }   
  234.  
  235. void CGameDDrawScreen::PageFlip()
  236. {
  237.     HRESULT result;
  238.  
  239.     int stopCount = DDRAW_RETRY;
  240.  
  241.     do
  242.     {
  243.         result = mpSurfaces[FRONT_BUFFER]->mpSurface->Flip(
  244.                     NULL, DDFLIP_WAIT );
  245.         if (result == DDERR_SURFACELOST )
  246.         {
  247.             mpSurfaces[FRONT_BUFFER]->mpSurface->Restore();
  248.             mpSurfaces[BACK_BUFFER]->mpSurface->Restore();          
  249.         }
  250.     }
  251.     while( (result != DD_OK) && (--stopCount > 0));
  252. }   
  253.  
  254. void
  255. CGameDDrawScreen::SetMode(
  256.     int width,
  257.     int height,
  258.     int bits
  259.     )
  260. {
  261.     mpSurfaces[FRONT_BUFFER]->SetMode(
  262.                         width,
  263.                         height,
  264.                         bits
  265.                         );
  266. }
  267.  
  268. void
  269. CGameDDrawScreen::ShowGDIPage()
  270. {
  271.     mpSurfaces[FRONT_BUFFER]->ShowGDIPage();
  272. }
  273.  
  274. void
  275. CGameDDrawScreen::RestoreMode()
  276. {
  277.     mpSurfaces[FRONT_BUFFER]->RestoreMode();
  278. }
  279.     
  280. void 
  281. CGameDDrawScreen::Refresh()
  282. {
  283.     mpSurfaces[FRONT_BUFFER]->mpSurface->Restore();
  284.     mpSurfaces[BACK_BUFFER]->mpSurface->Restore();  
  285. }
  286.  
  287.  
  288. void
  289. CGameDDrawScreen::ColorFill(
  290.     LPRECT pRect,
  291.     int palIndex
  292.     )
  293. {
  294.     HRESULT result;
  295.     DDBLTFX dbf;
  296.     RECT tempR = *pRect;
  297.  
  298.     // rects are off by one
  299.     tempR.right++;
  300.     tempR.bottom++;
  301.  
  302.     memset( &dbf, 0, sizeof( dbf ) );
  303.     dbf.dwSize = sizeof(dbf);
  304.     dbf.dwFillColor = palIndex;
  305.  
  306.     int stopCount = DDRAW_RETRY;
  307.  
  308.     do
  309.     {
  310.         result = mpSurfaces[BACK_BUFFER]->mpSurface->Blt( 
  311.             &tempR,     // dest rect
  312.             NULL,       // src surf
  313.             NULL,       // src rect
  314.             DDBLT_COLORFILL,// flags
  315.             &dbf );     // bltfx
  316.  
  317.         // surface may have been lost due to mode switch
  318.         if (result == DDERR_SURFACELOST)
  319.         {
  320.             mpSurfaces[FRONT_BUFFER]->mpSurface->Restore();
  321.             mpSurfaces[BACK_BUFFER]->mpSurface->Restore();
  322.             continue;
  323.         }
  324.     }
  325.     while( (result != DD_OK) && (--stopCount > 0));
  326. }
  327.  
  328. // read in a .pal file & set our palette to it
  329. void CGameDDrawScreen::SetPalette( char* pFile )
  330. {
  331.     LPPALETTEENTRY  ppe;
  332.  
  333.     ppe = new PALETTEENTRY[256];
  334.  
  335.     ReadPalFile( pFile, ppe, 256 );
  336.  
  337.     mpSurfaces[FRONT_BUFFER]->SetPalette( ppe );
  338.     delete[] ppe;
  339. }
  340.  
  341. int
  342. CGameDDrawScreen::GetVideoMemory()
  343. {
  344.     return mpSurfaces[FRONT_BUFFER]->GetVideoMemory();
  345. }
  346.  
  347. /*---------------------------------------------------------------------------*\
  348. |
  349. |       Class CGameDSScreen
  350. |
  351. |  DESCRIPTION:
  352. |       provide screen access via CreateDIBSection
  353. |
  354. |
  355. \*---------------------------------------------------------------------------*/
  356.  
  357. CGameDSScreen::CGameDSScreen(
  358.         HWND hwnd,  // this window determines "screen" size
  359.         int logWidth,
  360.         int logHeight,
  361.         int orgX,
  362.         int orgY
  363.         ) : CGameScreen( hwnd, logWidth, orgX, orgY )
  364. {
  365.     LOGPALETTE* pPal;
  366.     HPALETTE hOurPal = NULL;
  367.  
  368.     pPal = (LOGPALETTE*) GlobalAllocPtr( LPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY) );
  369.  
  370.     if (pPal)
  371.     {
  372.         pPal->palNumEntries = 256;
  373.         pPal->palVersion    = 0x300;
  374.  
  375.         ReadPalFile( "iklowns.pal", pPal->palPalEntry, 256 );
  376.  
  377.         hOurPal = CreatePalette( pPal );
  378.     }
  379.  
  380.     GlobalFreePtr( pPal );
  381.  
  382.     // create the primary surfaces (front & back)
  383.     mpScreenDIB = new CGameDIB( logWidth, logHeight, hOurPal );
  384.     mpBufferDIB = new CGameDIB( logWidth, logHeight, hOurPal );
  385.  
  386.     if (hwnd)
  387.     {
  388.         mhdcOut = GetDC( hwnd );
  389.  
  390.         mhdcBackBuffer = CreateCompatibleDC( mhdcOut );
  391.  
  392.         SelectPalette( mhdcOut, hOurPal, FALSE );
  393.         RealizePalette( mhdcOut );
  394.  
  395.         SelectPalette( mhdcBackBuffer, hOurPal, FALSE );
  396.         RealizePalette( mhdcBackBuffer );
  397.  
  398.                 HBITMAP hbmOld = (HBITMAP)SelectObject( mhdcBackBuffer, mpBufferDIB->GetHBitmap() );
  399.  
  400.         if (hbmOld)
  401.             DeleteObject( hbmOld );
  402.     }
  403.  
  404. }
  405.  
  406. CGameDSScreen::~CGameDSScreen()
  407. {
  408.     if (mhdcOut)
  409.     {
  410.         // restore the old palette
  411.         if (mOldPalette)
  412.             SelectPalette( mhdcOut, mOldPalette, FALSE );
  413.  
  414.         ReleaseDC( mhwnd, mhdcOut );
  415.     }
  416.  
  417.     // free up the backbuffer DC
  418.     if (mhdcBackBuffer)
  419.         DeleteDC( mhdcBackBuffer );
  420.  
  421.     delete mpBufferDIB;
  422.     delete mpScreenDIB;
  423. }   
  424.  
  425. void CGameDSScreen::Render(
  426.     int xDest,
  427.     int yDest,
  428.     int wDest,
  429.     int hDest,
  430.     CGameBitBuffer* pSrcBuffer,
  431.     int xSrc,
  432.     int ySrc,
  433.     DWORD rop
  434.     )
  435. {
  436.     int scanDest = mpBufferDIB->BytesPerScanline();
  437.     int scanSrc = ((CGameDSBitBuffer*)pSrcBuffer)->mpDIB->BytesPerScanline();
  438.  
  439.     CopyDIBBits(
  440.         mpBufferDIB->GetPixelAddress( xDest, yDest ),
  441.         ((CGameDSBitBuffer*)pSrcBuffer)->mpDIB->GetPixelAddress( xSrc, ySrc ),
  442.         wDest,  // width pixels
  443.         hDest,
  444.         (DWORD) -scanDest,
  445.         (DWORD) -scanSrc
  446.         );
  447. }   
  448.  
  449. void CGameDSScreen::TransRender(
  450.     int xDest,
  451.     int yDest,
  452.     int wDest,
  453.     int hDest,
  454.     CGameBitBuffer* pSrcBuffer,
  455.     int xSrc,
  456.     int ySrc
  457.     )
  458. {
  459.     int scanDest = mpBufferDIB->BytesPerScanline();
  460.     int scanSrc = ((CGameDSBitBuffer*)pSrcBuffer)->mpDIB->BytesPerScanline();
  461.  
  462.     TransCopyDIBBits(
  463.         mpBufferDIB->GetPixelAddress( xDest, yDest ),
  464.         ((CGameDSBitBuffer*)pSrcBuffer)->mpDIB->GetPixelAddress( xSrc, ySrc ),
  465.         wDest,  // width pixels
  466.         hDest,
  467.         (DWORD) -scanDest,
  468.         (DWORD) -scanSrc,
  469.         1
  470.         );
  471. }   
  472.  
  473. // we emulate page flipping by simply blitting from back to front
  474. void CGameDSScreen::PageFlip()
  475. {
  476.     BitBlt( mhdcOut, 0, 0, mOutWidth, mOutHeight, mhdcBackBuffer, 0, 0, SRCCOPY );
  477. }   
  478.  
  479. void
  480. CGameDSScreen::ColorFill(
  481.     LPRECT pRect,
  482.     int palIndex
  483.     )
  484. {
  485.     LPBYTE lpdest;
  486.     int bytes = pRect->right - pRect->left + 1;
  487.  
  488.     for (int line=pRect->top; line<=pRect->bottom; line++)
  489.     {
  490.         lpdest = mpBufferDIB->GetPixelAddress( pRect->left, line );
  491.         memset( lpdest, palIndex, bytes );
  492.     }
  493. }
  494.  
  495. void CGameDSScreen::SetPalette(HPALETTE hPal)
  496. {
  497.     CGameScreen::SetPalette( hPal );
  498.  
  499.     SelectPalette( mhdcBackBuffer, hPal, FALSE );
  500.     RealizePalette( mhdcBackBuffer );
  501. }
  502.  
  503. // read in a .pal file & set our palette to it
  504. void CGameDSScreen::SetPalette( char* pFile )
  505. {
  506. }
  507.