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

  1. /*===========================================================================*\
  2. |
  3. |  File:        splash.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 "splashrc.h"
  33.  
  34. char szAppName[] = "ISplash";   // The name of this application
  35. char acModuleName[256];
  36.  
  37. HINSTANCE       ghInst;
  38. HWND            ghMainWnd;
  39. LPBITMAPINFOHEADER  lpBitmap;
  40. LPBYTE          mpBits;
  41. HPALETTE        hPal;
  42. HPALETTE        hPalOld;
  43. LOGPALETTE      *pPal;
  44. int         nPasses = 0;
  45. int         fadeDirection = 1;
  46. LPSTR           pSoundBuffer = NULL;
  47.  
  48. /* Macro to determine to round off the given value to the closest byte */
  49. #define WIDTHBYTES(i)   ((i+31)/32*4)
  50.  
  51. #define PALVERSION  0x300
  52. #define MAXPALETTE  256      /* max. # supported palette entries */
  53.  
  54. #define NUMFADESTEPS    64
  55. #define HOLD_TIME   500
  56. #define INTERVAL_TIME   30
  57.  
  58. /****************************************************************************
  59.  *                                      *
  60.  *  FUNCTION   : DibNumColors(VOID FAR * pv)                    *
  61.  *                                      *
  62.  *  PURPOSE    : Determines the number of colors in the DIB by looking at   *
  63.  *       the BitCount filed in the info block.              *
  64.  *                                      *
  65.  *  RETURNS    : The number of colors in the DIB.               *
  66.  *                                      *
  67.  ****************************************************************************/
  68. WORD DibNumColors (VOID FAR * pv)
  69. {
  70.     INT             bits;
  71.     LPBITMAPINFOHEADER  lpbi;
  72.     LPBITMAPCOREHEADER  lpbc;
  73.  
  74.     lpbi = ((LPBITMAPINFOHEADER)pv);
  75.     lpbc = ((LPBITMAPCOREHEADER)pv);
  76.  
  77.     /*  With the BITMAPINFO format headers, the size of the palette
  78.      *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  79.      *  is dependent on the bits per pixel ( = 2 raised to the power of
  80.      *  bits/pixel).
  81.      */
  82.     if (lpbi->biSize != sizeof(BITMAPCOREHEADER))
  83.     {
  84.         if (lpbi->biClrUsed != 0)
  85.             return (WORD)lpbi->biClrUsed;
  86.         bits = lpbi->biBitCount;
  87.     }
  88.     else
  89.         bits = lpbc->bcBitCount;
  90.  
  91.     switch (bits)
  92.     {
  93.         case 1:
  94.             return 2;
  95.         case 4:
  96.             return 16;
  97.         case 8:
  98.             return 256;
  99.         default:
  100.             /* A 24 bitcount DIB has no color table */
  101.             return 0;
  102.     }
  103. }
  104.  
  105. /****************************************************************************
  106.  *                                      *
  107.  *  FUNCTION   :  PaletteSize(VOID FAR * pv)                    *
  108.  *                                      *
  109.  *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
  110.  *        is of the BITMAPCOREHEADER type, the number of colors is  *
  111.  *        multiplied by 3 to give the palette size, otherwise the   *
  112.  *        number of colors is multiplied by 4.                              *
  113.  *                                      *
  114.  *  RETURNS    :  Palette size in number of bytes.              *
  115.  *                                      *
  116.  ****************************************************************************/
  117. WORD PaletteSize (VOID FAR * pv)
  118. {
  119.     LPBITMAPINFOHEADER  lpbi;
  120.     WORD            NumColors;
  121.  
  122.     lpbi = (LPBITMAPINFOHEADER)pv;
  123.     NumColors = DibNumColors(lpbi);
  124.  
  125.     if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  126.         return (WORD)(NumColors * sizeof(RGBTRIPLE));
  127.     else
  128.         return (WORD)(NumColors * sizeof(RGBQUAD));
  129. }
  130.  
  131. void FadePalette(
  132.     LOGPALETTE      *pPal,
  133.     LPBITMAPINFOHEADER  lpbi,
  134.     int         fadestep
  135. )
  136. {
  137.     RGBQUAD FAR *pRgb;
  138.  
  139.     if (lpbi == NULL)
  140.         return;
  141.  
  142.     if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  143.         return;
  144.  
  145.     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  146.     for (int i = 1; i <= pPal->palNumEntries; i++)
  147.     {
  148.         pPal->palPalEntry[i-1].peRed   = (pRgb[i].rgbRed * fadestep) / NUMFADESTEPS;
  149.         pPal->palPalEntry[i-1].peGreen = (pRgb[i].rgbGreen * fadestep) / NUMFADESTEPS;
  150.         pPal->palPalEntry[i-1].peBlue  = (pRgb[i].rgbBlue * fadestep) / NUMFADESTEPS;
  151.         pPal->palPalEntry[i-1].peFlags = PC_NOCOLLAPSE;
  152.     }
  153. }
  154.  
  155. /****************************************************************************
  156.  *                                      *
  157.  *  FUNCTION   : CreateBIPalette(LPBITMAPINFOHEADER lpbi)           *
  158.  *                                      *
  159.  *  PURPOSE    : Given a Pointer to a BITMAPINFO struct will create a       *
  160.  *       a GDI palette object from the color table.         *
  161.  *                                      *
  162.  *  RETURNS    :                                            *
  163.  *                                      *
  164.  ****************************************************************************/
  165. LOGPALETTE  *CreateBIPalette (
  166.      LPBITMAPINFOHEADER lpbi,
  167.      int            fadestep
  168. )
  169. {
  170.  
  171.      LOGPALETTE *pPal;
  172.      HPALETTE   hpal = NULL;
  173.      WORD       nNumColors;
  174.      BYTE       red;
  175.      BYTE       green;
  176.      BYTE       blue;
  177.      WORD       i;
  178.      RGBQUAD    FAR *pRgb;
  179.  
  180.     if (lpbi == NULL)
  181.         return NULL;
  182.  
  183.     if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  184.         return NULL;
  185.  
  186.     /* Get a pointer to the color table and the number of colors in it */
  187.     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  188.     nNumColors = DibNumColors(lpbi);
  189.  
  190.     if (nNumColors)
  191.     {
  192.         /* Allocate for the logical palette structure */
  193.         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  194.         if (!pPal)
  195.             return NULL;
  196.  
  197.         pPal->palNumEntries = nNumColors - 2;
  198.         pPal->palVersion    = PALVERSION;
  199.  
  200.         /* Fill in the palette entries from the DIB color table and
  201.         * create a logical color palette.
  202.         */
  203.  
  204.         for (i = 1; i < (nNumColors-1); i++)
  205.         {
  206.             pPal->palPalEntry[i-1].peRed   = (pRgb[i].rgbRed * fadestep) / NUMFADESTEPS;
  207.             pPal->palPalEntry[i-1].peGreen = (pRgb[i].rgbGreen * fadestep) / NUMFADESTEPS;
  208.             pPal->palPalEntry[i-1].peBlue  = (pRgb[i].rgbBlue * fadestep) / NUMFADESTEPS;
  209.             pPal->palPalEntry[i-1].peFlags = PC_NOCOLLAPSE;
  210.         }
  211.     }
  212.     else if (lpbi->biBitCount == 24)
  213.     {
  214.         /* A 24 bitcount DIB has no color table entries so, set the number of
  215.         * to the maximum value (256).
  216.         */
  217.         nNumColors = MAXPALETTE;
  218.         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  219.         if (!pPal)
  220.             return NULL;
  221.  
  222.         pPal->palNumEntries = nNumColors;
  223.         pPal->palVersion    = PALVERSION;
  224.  
  225.         red = green = blue = 0;
  226.  
  227.         /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
  228.         * entries.
  229.         */
  230.         for (i = 0; i < pPal->palNumEntries; i++)
  231.         {
  232.             pPal->palPalEntry[i].peRed   = red;
  233.             pPal->palPalEntry[i].peGreen = green;
  234.             pPal->palPalEntry[i].peBlue  = blue;
  235.             pPal->palPalEntry[i].peFlags = (BYTE)0;
  236.  
  237.             if (!(red += 32))
  238.                 if (!(green += 32))
  239.                     blue += 64;
  240.         }
  241.     }
  242.     return pPal;
  243. }
  244.  
  245. /****************************************************************************
  246.  
  247.         FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  248.  
  249.         PURPOSE:  Processes messages
  250.  
  251.         MESSAGES:
  252.  
  253.         WM_COMMAND    - application menu (About dialog box)
  254.         WM_DESTROY    - destroy window
  255.  
  256.         COMMENTS:
  257.  
  258.         To process the IDM_ABOUT message, call MakeProcInstance() to get the
  259.         current instance address of the About() function.  Then call Dialog
  260.         box which will create the box according to the information in your
  261.         generic.rc file and turn control over to the About() function.  When
  262.         it returns, free the intance address.
  263.  
  264. ****************************************************************************/
  265.  
  266. LRESULT CALLBACK WndProc(
  267.     HWND hWnd,         // window handle
  268.     UINT message,      // type of message
  269.     WPARAM uParam,     // additional information
  270.     LPARAM lParam)     // additional information
  271. {
  272.         switch (message) {
  273.  
  274.     case WM_CREATE:
  275.     {
  276.         ShowCursor(FALSE);
  277.         SetTimer(hWnd, 1, HOLD_TIME, NULL);
  278.         break;
  279.     }
  280.  
  281.     case WM_PAINT:
  282.     {
  283.         PAINTSTRUCT PS;
  284.         HDC         hDC;
  285.         HPALETTE    hPalTmp;
  286.  
  287.         hDC = BeginPaint( hWnd, &PS );
  288.  
  289.         hPalTmp = SelectPalette(hDC, hPal, FALSE);
  290.         if (hPalOld == NULL)
  291.             hPalOld = hPalTmp;
  292.         RealizePalette(hDC);
  293.  
  294.         StretchDIBits(
  295.                 hDC,
  296.                 0,
  297.                 0,
  298. #if 0
  299.                 lpBitmap->biWidth,      // stretch to fit
  300.                 lpBitmap->biHeight,     // stretch to fit
  301. #endif
  302.                 GetSystemMetrics(SM_CXSCREEN),
  303.                 GetSystemMetrics(SM_CYSCREEN),
  304.                 0,
  305.                 0,
  306.                 lpBitmap->biWidth,      // stretch to fit
  307.                 lpBitmap->biHeight,     // stretch to fit
  308.                 mpBits,
  309.                 (CONST BITMAPINFO *)lpBitmap,
  310.                 DIB_RGB_COLORS,
  311.                 SRCCOPY
  312.                 );
  313.  
  314.         EndPaint( hWnd, &PS );
  315.     }
  316.     break;
  317.  
  318.     case WM_TIMER:
  319.     {
  320.         KillTimer(hWnd, 1);
  321.         HDC hDC = GetDC(hWnd);
  322.  
  323.         DWORD lastTime = timeGetTime();
  324.  
  325.         if (pSoundBuffer != NULL)
  326.             sndPlaySound(pSoundBuffer, SND_MEMORY | SND_ASYNC);
  327.  
  328.         do {
  329. #if 1
  330.             pPal = CreateBIPalette(lpBitmap, nPasses);
  331.             hPal = CreatePalette(pPal);
  332. #else
  333.             FadePalette(pPal, lpBitmap, nPasses);
  334.             AnimatePalette(hPal, 1, pPal->palNumEntries, pPal->palPalEntry);
  335. #endif
  336.             DeleteObject(SelectPalette(hDC, hPal, FALSE));
  337.             RealizePalette(hDC);
  338.  
  339.             nPasses += fadeDirection;
  340.             if (nPasses == NUMFADESTEPS)
  341.             {
  342.                 fadeDirection = -1;
  343.             } 
  344.  
  345.             while (timeGetTime() - lastTime < INTERVAL_TIME)
  346.             {
  347.                 //Sleep(0);
  348.             }
  349.             lastTime = timeGetTime();
  350.  
  351.         } while(nPasses > 0);
  352.  
  353.         ReleaseDC(hWnd, hDC);
  354.         WinExec(acModuleName, SW_SHOW);
  355.     }
  356.  
  357.         case WM_DESTROY:  // message: window being destroyed
  358.     {
  359. #if 1
  360.         HDC hDC = GetDC(hWnd);
  361.         PatBlt(hDC, 0,0, 640, 480,BLACKNESS);
  362.         SelectPalette(hDC, hPalOld, FALSE);
  363.         RealizePalette(hDC);
  364.         ReleaseDC(hWnd, hDC);
  365. #endif
  366.  
  367.         sndPlaySound(NULL, SND_SYNC);
  368.         ShowCursor(TRUE);
  369.         KillTimer(hWnd, 1);
  370.         PostQuitMessage(0);
  371.         break;
  372.     }
  373.  
  374.         default:          // Passes it on if unproccessed
  375.         return (DefWindowProc(hWnd, message, uParam, lParam));
  376.         }
  377.         return (0);
  378. }
  379.  
  380. #if 0
  381. void dbgprintf(char *fmt,...)
  382. {
  383.     static HANDLE dbg = NULL;
  384.     char    out [ 256 ];
  385.     DWORD  len;
  386.     va_list vlist;
  387.  
  388.     if (dbg == NULL)
  389.     {
  390.         AllocConsole();
  391.         dbg =  GetStdHandle(STD_OUTPUT_HANDLE);
  392.         if (dbg == NULL)
  393.             return;         
  394.     }
  395.     
  396.     va_start(vlist, fmt);
  397.     wvsprintf(out, fmt, vlist);
  398.     WriteConsole(dbg, out, strlen(out), &len, NULL);
  399. }
  400. #endif
  401. /****************************************************************************
  402.  
  403.         FUNCTION:  InitInstance(HINSTANCE, int)
  404.  
  405.         PURPOSE:  Saves instance handle and creates main window
  406.  
  407.         COMMENTS:
  408.  
  409.                 This function is called at initialization time for every instance of
  410.                 this application.  This function performs initialization tasks that
  411.                 cannot be shared by multiple instances.
  412.  
  413.                 In this case, we save the instance handle in a static variable and
  414.                 create and display the main program window.
  415.  
  416. ****************************************************************************/
  417.  
  418. BOOL InitInstance(
  419.         HINSTANCE   hInstance,
  420.         int     nCmdShow)
  421. {
  422.     WNDCLASS  wc;
  423.  
  424.  
  425.     // Fill in window class structure with parameters that describe the
  426.     // main window.
  427.  
  428.     wc.style         = CS_OWNDC;                        // Class style(s).
  429.     wc.lpfnWndProc   = (WNDPROC)WndProc;       // Window Procedure
  430.     wc.cbClsExtra    = 0;                      // No per-class extra data.
  431.     wc.cbWndExtra    = 0;                      // No per-window extra data.
  432.     wc.hInstance     = hInstance;              // Owner of this class
  433.     wc.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_APP)); // Icon name from .RC
  434.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);// Cursor
  435.     wc.hbrBackground = NULL;                    // Default color
  436.     wc.lpszMenuName  = NULL;
  437.     wc.lpszClassName = szAppName;              // Name to register as
  438.  
  439.     // Register the window class
  440.     if (!RegisterClass(&wc))
  441.         return(FALSE);
  442.  
  443.     // Create a main window for this application instance.
  444.  
  445.     ghMainWnd = CreateWindow(
  446.             szAppName,           // See RegisterClass() call.
  447.             NULL,               // Text for window title bar.
  448.             WS_POPUP,                   // Window style.
  449.             0,
  450.             0,
  451.             GetSystemMetrics(SM_CXSCREEN),
  452.             GetSystemMetrics(SM_CYSCREEN),
  453.             NULL,                // Overlapped windows have no parent.
  454.             NULL,                // Use the window class menu.
  455.             hInstance,           // This instance owns this window.
  456.             NULL                 // We don't use any data in our WM_CREATE
  457.             );
  458.  
  459.     // If window could not be created, return "failure"
  460.     if (!ghMainWnd)
  461.         return(FALSE);
  462.  
  463.     // Make the window visible; update its client area; and return "success"
  464.     ShowWindow(ghMainWnd, nCmdShow); // Show the window
  465.     UpdateWindow(ghMainWnd);         // Sends WM_PAINT message
  466.  
  467.     return (TRUE);              // We succeeded...
  468. }
  469.  
  470. /****************************************************************************
  471.  
  472.         FUNCTION:  ShutDownApp()
  473.  
  474.         PURPOSE:  un-initialize the app as needed
  475.  
  476.         COMMENTS:
  477.  
  478. ****************************************************************************/
  479. void ShutDownApp()
  480. {
  481. }
  482.  
  483. /****************************************************************************
  484.  
  485.         FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
  486.  
  487.         PURPOSE: calls initialization function, processes message loop
  488.  
  489.         COMMENTS:
  490.  
  491.                 Windows recognizes this function by name as the initial entry point
  492.                 for the program.  This function calls the application initialization
  493.                 routine, if no other instance of the program is running, and always
  494.                 calls the instance initialization routine.  It then executes a message
  495.                 retrieval and dispatch loop that is the top-level control structure
  496.                 for the remainder of execution.  The loop is terminated when a WM_QUIT
  497.                 message is received, at which time this function exits the application
  498.                 instance by returning the value passed by PostQuitMessage().
  499.  
  500.                 If this function must abort before entering the message loop, it
  501.                 returns the conventional value NULL.
  502.  
  503. ****************************************************************************/
  504.  
  505. int CALLBACK WinMain(
  506.         HINSTANCE hInstance,
  507.         HINSTANCE hPrevInstance,
  508.         LPSTR lpCmdLine,
  509.         int nCmdShow)
  510. {
  511.     MSG msg;
  512.     int result = NULL;
  513.     int nNameLength;
  514.  
  515.     // only allow 1 instance
  516.     if (hPrevInstance)
  517.       return NULL;
  518.  
  519.     ghInst = hInstance;
  520.  
  521.     nNameLength = GetModuleFileName(ghInst, acModuleName, sizeof(acModuleName));
  522.     lstrcpy(&acModuleName[nNameLength-3], "OVL"); 
  523.  
  524.  
  525.     HGLOBAL hgrBitmap = LoadResource( ghInst, FindResource(ghInst, MAKEINTRESOURCE(IDB_SPLASH), RT_BITMAP));
  526.  
  527.     lpBitmap = (LPBITMAPINFOHEADER)LockResource( hgrBitmap );
  528.  
  529.     mpBits = (LPBYTE)lpBitmap + (WORD)lpBitmap->biSize + PaletteSize(lpBitmap);
  530.     pPal = CreateBIPalette(lpBitmap, NUMFADESTEPS);
  531.     hPal = CreatePalette(pPal);
  532.     fadeDirection = -1;
  533.     nPasses = NUMFADESTEPS;
  534.  
  535.  
  536.     HGLOBAL hgrSound = LoadResource( ghInst, FindResource(ghInst, MAKEINTRESOURCE(IDS_SPLASH), "WAVE"));
  537.     pSoundBuffer = (LPSTR)LockResource( hgrSound );
  538.  
  539.  
  540.     if (InitInstance(hInstance, nCmdShow))
  541.     {
  542.         /* Acquire and dispatch messages until a WM_QUIT message is
  543.         received.
  544.         */
  545.         while (GetMessage(&msg, // message structure
  546.           NULL,   // handle of window receiving the message
  547.           0,      // lowest message to examine
  548.           0))     // highest message to examine
  549.         {
  550.                 TranslateMessage(&msg);// Translates virtual key codes
  551.                 DispatchMessage(&msg); // Dispatches message to window
  552.         }
  553.  
  554.         ShutDownApp();  // call de-init code
  555.         result = msg.wParam;
  556.     }
  557.  
  558.     return (result);
  559. }
  560.