home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / OTHER / KABOOM.ZIP / KABOOM.C < prev    next >
C/C++ Source or Header  |  1994-03-21  |  14KB  |  480 lines

  1. /* Display a transparent window */
  2. #define INCL_BASE
  3. #define INCL_PM
  4. #define INCL_GPIPRIMITIVES      /* GPI primitive functions      */
  5.  
  6. #include "kaboom.rh"       /* resource identifiers */
  7.  
  8. #include <os2.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include <ctype.h>
  14.  
  15. // Turn off parameter not used warning in Borland C++
  16. #pragma warn -par
  17. #pragma warn -rch
  18.  
  19. //--------------------------------------------------------------
  20. //  Global variables
  21. //--------------------------------------------------------------
  22.  
  23. CHAR   szAppName[MAXNAMEL] = "Kaboom"; // Buffer for client window class
  24. HMQ    hmq;                           // Handle to the process' message queue
  25. HAB    hab;                           // Handle to the anchor block
  26. QMSG   qmsg;                          // Queue message holder
  27. HBITMAP hbmcirc;                      // Global Bitmap for circuit board
  28. HBITMAP hbmhole;                      // Global Bitmap for hole
  29. HBITMAP hbmmush[MAX_MUSH+1],
  30.     hbmmushm[MAX_MUSH+1];         // Explosion Mushroom cloud sequence.
  31. int    clickcount=10;              // Click1 countdown to total destruction
  32.  
  33. //--------------------------------------------------------------
  34. //  Function Prototype declarations
  35. //--------------------------------------------------------------
  36.  
  37. MRESULT EXPENTRY _export MainWndProc(HWND, ULONG, MPARAM, MPARAM);
  38. void errorbox(HWND hwnd, PSZ psztext);
  39. void UtlCreateMemPS(HAB hab, HPS hps, ULONG cx, ULONG cy, PHPS hpsbm);
  40. void UtlDestroyMemPS(PHPS hpsbm);
  41. void blast(POINTL ground0, POINTL killsz, HPS hps, HWND hwnd);
  42.  
  43. // Start of main program source
  44.  
  45. INT main(VOID)
  46. {
  47.     ULONG    flCtlData;                        /* Frame control data */
  48.     HWND     hwndMain=0L;                // Handle to the main frame window
  49.     HWND     hwndClient;                 // Handle to the main client window
  50.  
  51.  
  52.     flCtlData = 0; /* no frame controls on window */
  53.  
  54.     hab = WinInitialize(0L);
  55.     hmq = WinCreateMsgQueue(hab, 0L);
  56.     WinRegisterClass(hab,
  57.             (PSZ)szAppName,      // Name of class being registered
  58.             (PFNWP)MainWndProc,  // Window Procedure function pointer
  59.             CS_SIZEREDRAW |      // Class style
  60.             CS_CLIPCHILDREN,     // Class style
  61.             0L);                 // Extra bytes to reserve
  62.  
  63.  
  64.     // Create a top-level frame window with a client window that
  65.     // belongs to the window class created in the previous step
  66.     // The window is "top level" due to indicating its parent is
  67.     // the PM desktop (HWND_DESKTOP).
  68.  
  69.    hwndMain = WinCreateStdWindow(HWND_DESKTOP,   // Parent is desktop window
  70.                           WS_VISIBLE |
  71.                           WS_MAXIMIZED,
  72.                           &flCtlData,            // Pointer to frame control style
  73.                           szAppName,             // Name of client class
  74.                           "KaBoom!!",            // Window Title
  75.                           WS_VISIBLE,            // Make Client Window Visible
  76.                           (HMODULE)0L,           // Resources are in executable
  77.                                      //   vs. dynamically loaded
  78.                           ID_RESOURCE,           // Resource/Window identifier
  79.                           (PHWND)&hwndClient);   // Returned Pointer to client window
  80.  
  81.  WinSetWindowPos(hwndMain, HWND_TOP, 0l, 0l, 0l, 0l, SWP_MAXIMIZE | SWP_ACTIVATE);
  82.  WinSetFocus(HWND_DESKTOP, hwndClient);
  83.  
  84.    // Required Get/Dispatch Message loop
  85.    while(WinGetMsg(hab,(PQMSG)&qmsg, 0L, 0L, 0L))
  86.        WinDispatchMsg(hab, (PQMSG)&qmsg);
  87.  
  88.    return(0);
  89.  
  90. }
  91.  
  92.  
  93. MRESULT EXPENTRY _export MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  94. {
  95. RECTL  rcl;            // Rectangle structure
  96. POINTL ground0;        // Ground Zero of the explosion
  97. POINTL killsz;         // Kill size (size of section of screen to trash)
  98. HPS    hps;               // Handle to a paint structure
  99. int    i;              // general loop counter
  100. USHORT fsflags, usch;  // misc work vars for WM_CHAR message
  101.  
  102.    switch(msg)
  103.    {
  104.  
  105.       case WM_CREATE:
  106.  
  107.         /* load all bitmaps when window is created */
  108.  
  109.         hps=WinGetPS(hwnd);
  110.         hbmcirc = GpiLoadBitmap(hps, NULLHANDLE, IDR_CIRCUIT, 0l, 0l);
  111.         hbmhole = GpiLoadBitmap(hps, NULLHANDLE, IDR_HOLE, 0l, 0l);
  112.         for (i=0; i <= MAX_MUSH; i++)
  113.             {
  114.             hbmmush[i] = GpiLoadBitmap(hps, NULLHANDLE, IDR_MUSH1+i, 0l, 0l);
  115.             hbmmushm[i] = GpiLoadBitmap(hps, NULLHANDLE, IDR_MUSHM1+i, 0l, 0l);
  116.             }
  117.         WinReleasePS(hps);
  118.         return (MRESULT) FALSE;
  119.         break;
  120.  
  121.  
  122.       case WM_PAINT:
  123.          /* nothing is actually painted - the window is transparent */
  124.          hps=WinBeginPaint(hwnd,(HPS)NULL,&rcl);
  125.          WinEndPaint(hps);
  126.          break;
  127.  
  128.       case WM_BUTTON1CLICK:
  129.  
  130.         /* make a small explosion with mouse at ground zero for
  131.            a double click of the first mouse button */
  132.  
  133.         /* if the countdown is zero - do button2 double click instead */
  134.  
  135.         if (clickcount-- == 0)
  136.             {
  137.             WinPostMsg(hwnd, WM_BUTTON2DBLCLK, mp1, mp2);
  138.             return (MRESULT) TRUE;
  139.             }
  140.  
  141.         hps=WinGetPS(hwnd);
  142.  
  143.         ground0.x = (LONG) SHORT1FROMMP(mp1); /* store mouse pointer */
  144.         ground0.y = (LONG) SHORT2FROMMP(mp1); /* loc as ground zero */
  145.  
  146.         killsz.x = 50;
  147.         killsz.y = 50;
  148.  
  149.         blast(ground0, killsz, hps, hwnd); /* blast a hole */
  150.  
  151.         WinReleasePS(hps);
  152.         return (MRESULT) TRUE;
  153.         break;
  154.  
  155.  
  156.       case WM_BUTTON2DBLCLK:
  157.  
  158.         /* Blast the entire screen for a double click of button 2 */
  159.         /* after toasting the whole screen, end the program */
  160.  
  161.         hps=WinGetPS(hwnd);
  162.         WinQueryWindowRect(hwnd,&rcl);
  163.  
  164.         killsz.x = rcl.xRight - rcl.xLeft;
  165.         killsz.y = rcl.yTop - rcl.yBottom;
  166.  
  167.         ground0.x = rcl.xLeft + killsz.x/2; /* Bottom Center */
  168.         ground0.y = rcl.yBottom;
  169.  
  170.         blast(ground0, killsz, hps, hwnd); /* blast a hole */
  171.  
  172.         WinReleasePS(hps);
  173.  
  174.         WinPostMsg(hwnd, WM_CLOSE, (MPARAM) NULL, (MPARAM) NULL);
  175.  
  176.         return (MRESULT) TRUE;
  177.         break;
  178.  
  179.  
  180.       case WM_CHAR:
  181.         /* Terminate the window when Ctrl-C Pressed */
  182.  
  183.         fsflags = SHORT1FROMMP(mp1);
  184.         usch    = SHORT1FROMMP(mp2);
  185.  
  186.         if ((toupper(usch) == 'C')  &&
  187.             (fsflags & KC_CTRL) )
  188.               {
  189.               WinPostMsg(hwnd, WM_CLOSE, (MPARAM) NULL, (MPARAM) NULL);
  190.               return (MRESULT) TRUE;
  191.               }
  192.         else
  193.               return (MRESULT) FALSE;
  194.  
  195.         break;
  196.  
  197.       case WM_CLOSE:
  198.         /* display an about box */
  199.  
  200.         WinMessageBox(HWND_DESKTOP, hwnd,
  201.          "KaBoom!\nby Vincent Greene\nTucson, AZ",
  202.          "About", 1, MB_OK |  MB_APPLMODAL | MB_INFORMATION);
  203.  
  204.         WinPostMsg(hwnd, WM_QUIT, (MPARAM) NULL, (MPARAM) NULL);
  205.  
  206.         return (MRESULT) FALSE;
  207.         break;
  208.  
  209.  
  210.       case WM_QUIT:
  211.         /* delete all bitmaps when window is closed */
  212.         GpiDeleteBitmap(hbmcirc);
  213.         GpiDeleteBitmap(hbmhole);
  214.         for (i=0; i <= MAX_MUSH; i++)
  215.             {
  216.             GpiDeleteBitmap(hbmmush[i]);
  217.             GpiDeleteBitmap(hbmmushm[i]);
  218.             }
  219.  
  220.         return (MRESULT) FALSE;
  221.         break;
  222.  
  223.       default:
  224.          return WinDefWindowProc(hwnd, msg, mp1, mp2);
  225.    }
  226.    return (MRESULT)0L;
  227. }
  228.  
  229.  
  230. /* BLAST
  231.  
  232.    Blasts a hole of a given size in the specified window complete with nuclear
  233.    explosion.
  234.  
  235. Parameters:
  236.     ground0 - Ground Zero Point (Center Bottom) of explosion area
  237.     killsz  - Kill Zone Size - size of explosion area
  238.     hps     - Presentation space handle for window to blast
  239.     hwnd    - window to blast hole in.
  240.  
  241. Globals required:
  242.     hbmhole, hab, hbmmush[], hbmmushm[]
  243.  
  244. DEFINES required:
  245.     MAX_MUSH - Highest element in mushroom bitmap handle arrays
  246. */
  247.  
  248. void blast(POINTL ground0, POINTL killsz, HPS hps, HWND hwnd)
  249.  
  250. {
  251. HPS    hpsbm;          // temporary memory bitmap
  252. RECTL  killz;          // Kill zone (section of screen to trash)
  253. RECTL  hole;           // rectangle describing size of hole bitmap
  254. RECTL  mush;           // rectangle describing size of mushroom bitmap
  255. POINTL aptl[4];
  256. int    i;
  257. clock_t start;
  258. BITMAPINFOHEADER2  pbmp2Data; /* Bit-map information header     */
  259.  
  260. /* get the size of the hole bitmap */
  261.  
  262.         pbmp2Data.cbFix = 16L;
  263.         GpiQueryBitmapInfoHeader(hbmhole, &pbmp2Data);
  264.  
  265.         hole.xLeft = 0;
  266.         hole.yBottom = 0;
  267.         hole.xRight = pbmp2Data.cx - 1;
  268.         hole.yTop = pbmp2Data.cy - 1;
  269.  
  270. /* calculate kill zone */
  271.  
  272.         killz.xLeft = ground0.x - killsz.x/2;
  273.         killz.yBottom = ground0.y;
  274.         killz.xRight = ground0.x + killsz.x/2;
  275.         killz.yTop = ground0.y + killsz.y;
  276.  
  277.  
  278.         UtlCreateMemPS(hab, hps, killsz.x+1, killsz.y+1, &hpsbm);
  279.  
  280. /* save the kill zone in memory to restore after the explosion */
  281.  
  282.         aptl[0].x = 0; /* lower left corner */
  283.         aptl[0].y = 0;
  284.         aptl[1] = killsz;
  285.         aptl[2].x = killz.xLeft;
  286.         aptl[2].y = killz.yBottom;
  287.         aptl[3].x = killz.xRight;
  288.         aptl[3].y = killz.yTop;
  289.         if (GPI_ERROR == GpiBitBlt(hpsbm, hps, 4l, aptl, ROP_SRCCOPY, BBO_IGNORE))
  290.             errorbox(hwnd, "hpsbm, hps GPIBitBlt");
  291.  
  292. /* get the size of the mushroom bitmaps */
  293.  
  294.         pbmp2Data.cbFix = 16L;
  295.         GpiQueryBitmapInfoHeader(hbmmush[0], &pbmp2Data);
  296.  
  297.         mush.xLeft = 0;
  298.         mush.yBottom = 0;
  299.         mush.xRight = pbmp2Data.cx - 1;
  300.         mush.yTop = pbmp2Data.cy - 1;
  301.  
  302. /* do the explosion */
  303.  
  304.         for (i=0; i <= MAX_MUSH; i++) /* repeat process for all bitmaps */
  305.             {
  306.             start = clock();
  307.             aptl[0].x = killz.xLeft;
  308.             aptl[0].y = killz.yBottom;
  309.             aptl[1].x = killz.xRight - 1;
  310.             aptl[1].y = killz.yTop - 1;
  311.             aptl[2].x = mush.xLeft;
  312.             aptl[2].y = mush.yBottom;
  313.             aptl[3].x = mush.xRight;
  314.             aptl[3].y = mush.yTop;
  315.             if (GPI_ERROR == GpiWCBitBlt(hps, hbmmushm[i], 4l, aptl, ROP_SRCAND, BBO_IGNORE))
  316.                 errorbox(hwnd, "hps, hbmmush GPIWCBitBlt");
  317.             if (GPI_ERROR == GpiWCBitBlt(hps, hbmmush[i], 4l, aptl, ROP_SRCPAINT, BBO_IGNORE))
  318.                 errorbox(hwnd, "hps, hbmmush GPIWCBitBlt");
  319.  
  320.             while (clock() < start+50); /* wait 50 clock ticks */
  321.  
  322.             /* restore the kill zone from memory */
  323.  
  324.             aptl[0].x = killz.xLeft;
  325.             aptl[0].y = killz.yBottom;
  326.             aptl[1].x = killz.xRight;
  327.             aptl[1].y = killz.yTop;
  328.             aptl[2].x = 0; /* lower left corner */
  329.             aptl[2].y = 0;
  330.             aptl[3] = killsz;
  331.             if (GPI_ERROR == GpiBitBlt(hps, hpsbm, 4l, aptl, ROP_SRCCOPY, BBO_IGNORE))
  332.                 errorbox(hwnd, "hps, hpsbm GPIBitBlt");
  333.             }
  334.  
  335.  
  336. /* copy the hole bitmap into memory */
  337.  
  338.         aptl[0].x = 0; /* lower left corner */
  339.         aptl[0].y = 0;
  340.         aptl[1] = killsz;
  341.         aptl[2].x = hole.xLeft;
  342.         aptl[2].y = hole.yBottom;
  343.         aptl[3].x = hole.xRight;
  344.         aptl[3].y = hole.yTop;
  345.         if (GPI_ERROR == GpiWCBitBlt(hpsbm, hbmhole, 4l, aptl, ROP_SRCCOPY, BBO_IGNORE))
  346.             errorbox(hwnd, "hpsbm, hbmcirc GPIWCBitBlt");
  347.  
  348. /* Create a hole on screen by copying from memory bitmap */
  349.  
  350.         aptl[0].x = killz.xLeft;
  351.         aptl[0].y = killz.yBottom;
  352.         aptl[1].x = killz.xRight;
  353.         aptl[1].y = killz.yTop;
  354.         aptl[2].x = 0; /* lower left corner */
  355.         aptl[2].y = 0;
  356.         aptl[3] = killsz;
  357.         if (GPI_ERROR == GpiBitBlt(hps, hpsbm, 4l, aptl, ROP_SRCAND, BBO_IGNORE))
  358.             errorbox(hwnd, "hps, hbmhole GPIWCBitBlt");
  359.  
  360. /* merge circuit section with hole bitmap in memory */
  361.         aptl[0].x = 0; /* lower left corner */
  362.         aptl[0].y = 0;
  363.         aptl[1] = killsz;
  364.         aptl[2].x = killz.xLeft;
  365.         aptl[2].y = killz.yBottom;
  366.         aptl[3].x = killz.xRight;
  367.         aptl[3].y = killz.yTop;
  368.         if (GPI_ERROR == GpiWCBitBlt(hpsbm, hbmcirc, 4l, aptl, ROP_SRCERASE, BBO_IGNORE))
  369.             errorbox(hwnd, "hpsbm, hbmcirc GPIWCBitBlt");
  370.  
  371. /* merge memory (circuit with hole in middle) with screen */
  372.  
  373.         aptl[0].x = killz.xLeft;
  374.         aptl[0].y = killz.yBottom;
  375.         aptl[1].x = killz.xRight;
  376.         aptl[1].y = killz.yTop;
  377.         aptl[2].x = 0; /* lower left corner */
  378.         aptl[2].y = 0;
  379.         aptl[3] = killsz;
  380.         if (GPI_ERROR == GpiBitBlt(hps, hpsbm, 4l, aptl, ROP_SRCPAINT, BBO_IGNORE))
  381.             errorbox(hwnd, "hps, hpsbm GPIBitBlt");
  382.         UtlDestroyMemPS(&hpsbm);
  383. }
  384.  
  385.  
  386.  
  387. /* UtlCreateMem -
  388.  
  389.   Creates a memory device context, presentation space, and temp bitmap of
  390.   size cx, cy.  This function sets hpsbm (the last parm) to the created
  391.   presentation space.  It requires the anchor block of the application,
  392.   the handle of the presentation space to model the mem space from, and
  393.   the size of the bitmap.
  394.  
  395. */
  396.  
  397. void UtlCreateMemPS(HAB hab, HPS hps, ULONG cx, ULONG cy, PHPS hpsbm)
  398.  
  399. {
  400. HDC    hdcmem;              /* Device-context handle                */
  401. HBITMAP hbmtemp;
  402. DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
  403.              NULL, NULL, NULL};
  404. SIZEL  sizl={0, 0};     /* use same page size as device        */
  405. BITMAPINFOHEADER2  pbmp2Data; /* Bit-map information header     */
  406. LONG devcaps;
  407.  
  408. /* Create memory space for temporary storage & bitmap manipulation */
  409.  
  410.         hdcmem = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, hps);
  411.         if (DEV_ERROR == hdcmem)
  412.             errorbox(HWND_DESKTOP, "DevOpenDC ");
  413.  
  414.         *hpsbm = GpiCreatePS(hab, hdcmem, &sizl, GPIA_ASSOC | PU_PELS);
  415.         if (GPI_ERROR == *hpsbm)
  416.             errorbox(HWND_DESKTOP, "GpiCreatePS ");
  417.  
  418. /* create a temporary memory bitmap of the specified size */
  419.  
  420.         pbmp2Data.cbFix = 16L;
  421.         pbmp2Data.cx = cx;
  422.         pbmp2Data.cy = cy;
  423.         DevQueryCaps(GpiQueryDevice(hps), CAPS_COLOR_PLANES, 1, &devcaps);
  424.         pbmp2Data.cPlanes = (SHORT) devcaps;
  425.         DevQueryCaps(GpiQueryDevice(hps), CAPS_COLOR_BITCOUNT, 1, &devcaps);
  426.         pbmp2Data.cBitCount = (SHORT) devcaps;
  427.         hbmtemp = GpiCreateBitmap(*hpsbm, &pbmp2Data, 0l, NULL,
  428.                         (PBITMAPINFO2) NULL);
  429.  
  430. /* associate the temporary bitmap with the memory presentation space */
  431.  
  432.         GpiSetBitmap(*hpsbm, hbmtemp);
  433. }
  434.  
  435.  
  436.  
  437. /* UtlDestroyMemPS
  438.  
  439.      This functions destroys a memory presentaton space, device context,
  440.      and bitmap previously created by the UtlCreateMemPS function.
  441.  
  442. */
  443.  
  444. void UtlDestroyMemPS(PHPS hpsbm)
  445.  
  446. {
  447. HDC    hdcmem;              /* Device-context handle                */
  448. HBITMAP hbmtemp;
  449.  
  450.     hbmtemp = GpiSetBitmap(*hpsbm, NULLHANDLE);
  451.     GpiDeleteBitmap(hbmtemp);
  452.  
  453. /* destroy the memory device and PS */
  454.     hdcmem = GpiQueryDevice(*hpsbm);
  455.     GpiDestroyPS(*hpsbm);
  456.     DevCloseDC(hdcmem);
  457. }
  458.  
  459.  
  460. /* errorbox
  461.  
  462.     a quick and easy function to display an error message box
  463.     required parameters are the handle to the window (HWND_DESKTOP is
  464.     ok here) and the text to display (only the first 80 characters
  465.     will be processed.)
  466.  
  467. */
  468.  
  469. void errorbox(HWND hwnd, PSZ psztext)
  470.  
  471. {
  472. ERRORID errid;
  473. char    szMsg[100];
  474.  
  475. errid = WinGetLastError(hab);
  476. sprintf(szMsg, "%.80s - 0x%.4lx", psztext, errid);
  477. WinMessageBox(hwnd, hwnd, szMsg, NULL, 1, MB_OK);
  478. }
  479.  
  480.