home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / fastgpi.zip / fastgpi.c < prev    next >
C/C++ Source or Header  |  1994-09-01  |  9KB  |  335 lines

  1. /* $Id: inten5pm.c 1.6 93/09/19 05:14:07 Unknown Exp Locker: Unknown $ */
  2. /* Copyright (c) 1994 Donald Graft, All Rights Reserved */
  3.  
  4. #define INCL_DOS
  5. #define INCL_WIN
  6. #define INCL_GPI
  7.  
  8. #include <os2.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include "a-float.h"
  13. /* ENDINCL */
  14.  
  15. #define NUM_MASSES_X    320u
  16. #define NUM_MASSES_Y    240u
  17.  
  18. HAB hab;
  19. HAB habt;
  20. HWND hwndFrame, hwndClient;
  21. HDC hdc, hdcMemory;
  22. HPS hps, hpsMemory;
  23. HMTX hmtxLock;
  24. TID tidModel;
  25. BOOL ModelSuspended = FALSE;
  26. HBITMAP hbm;
  27. BITMAPINFOHEADER2 bmih;
  28. BITMAPINFOHEADER2 bmp2data;
  29. PBITMAPINFO2 pbmi;
  30. BYTE RGBmap[32];
  31. BYTE Bitmap[NUM_MASSES_X*NUM_MASSES_Y];
  32. POINTL aptl[3] =
  33.   { 0u, 0u, NUM_MASSES_X, NUM_MASSES_Y, 0u, 0u };
  34.  
  35. MRESULT EXPENTRY window_func(HWND, ULONG, MPARAM, MPARAM);
  36. void Model(ULONG);
  37. void PrepareGraphics(BYTE *);
  38. void DisplayPlane(float **current);
  39. float ***Storage();
  40.   
  41. void
  42. main(void)
  43. {
  44.   HMQ hmq;
  45.   QMSG qmsg;
  46.   ULONG flFlags;
  47.   unsigned char class[]="MyClass";
  48.  
  49.   flFlags = FCF_TITLEBAR |
  50.             FCF_MINBUTTON |
  51.             FCF_TASKLIST |
  52.             FCF_SYSMENU;
  53.  
  54.   if ((hab = WinInitialize(0)) == 0)
  55.   {
  56.     printf("Error doing WinInitialize()\n");
  57.     exit(1);
  58.   }
  59.   if ((hmq = WinCreateMsgQueue(hab, 0)) == (HMQ) NULL)
  60.   {
  61.     printf("Error doing WinCreateMsgQueue()\n");
  62.     exit(1);
  63.   }
  64.   if (!WinRegisterClass(hab, (PSZ) class, (PFNWP) window_func,
  65.                         CS_SIZEREDRAW, 0))
  66.   {
  67.     printf("Error doing WinRegisterClass()\n");
  68.     exit(1);
  69.   }
  70.   if ((hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flFlags,
  71.                                   (PSZ) class, (PSZ) "5-Point Wave Equation",
  72.                                   WS_VISIBLE, 0, 0, &hwndClient)) == 0)
  73.   {
  74.     printf("Error doing WinCreateStdWindow()\n");
  75.     exit(1);
  76.   }
  77.   WinSetWindowPos(hwndFrame, 0L,
  78.                   (SHORT) (60),
  79.                   (SHORT) (WinQuerySysValue(HWND_DESKTOP,
  80.                             SV_CYSCREEN) - (NUM_MASSES_Y+60)),
  81.                   (SHORT) NUM_MASSES_X,
  82.           (SHORT) NUM_MASSES_Y + WinQuerySysValue(HWND_DESKTOP,
  83.             SV_CYTITLEBAR) - 2, SWP_SIZE | SWP_MOVE);
  84.   while (WinGetMsg(hab, &qmsg, (HWND) NULL, 0, 0))
  85.   {
  86.     WinDispatchMsg(hab, &qmsg);
  87.   }
  88.   WinDestroyWindow(hwndFrame);
  89.   WinDestroyMsgQueue(hmq);
  90.   WinTerminate(hab);
  91. }
  92.  
  93. MRESULT EXPENTRY
  94. window_func(HWND handle, ULONG mess, MPARAM parm1, MPARAM parm2)
  95. {
  96.   LONG palette[33];
  97.   int i;
  98.   LONG j;
  99.   SIZEL sizl;
  100.  
  101.   switch(mess)
  102.   {
  103.     case WM_CREATE:
  104.       /* Create presentation space for screen. */
  105.       hdc = WinOpenWindowDC(handle);
  106.       sizl.cx = 0;
  107.       sizl.cy = 0;
  108.       hps = GpiCreatePS(hab, hdc, &sizl,
  109.         PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
  110.  
  111.       /* Create presentation space for memory image of screen. */
  112.       hdcMemory = DevOpenDC(hab, OD_MEMORY, (PSZ) "*", 0L, 0L, 0L);
  113.       sizl.cx = 0;
  114.       sizl.cy = 0;
  115.       hpsMemory = GpiCreatePS(hab, hdcMemory, &sizl,
  116.         PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
  117.  
  118.       /* Create bitmap for memory image of screen. */
  119.       memset(&bmih, 0, sizeof(bmih));
  120.       bmih.cbFix = sizeof(bmih);
  121.       bmih.cx = NUM_MASSES_X;
  122.       bmih.cy = NUM_MASSES_Y;
  123.       bmih.cPlanes = 1;
  124.       bmih.cBitCount = 8;
  125.       hbm = GpiCreateBitmap(hpsMemory, &bmih, 0L, NULL, NULL);
  126.       GpiSetBitmap(hpsMemory, hbm);
  127.  
  128.       /* Set up gray-scale palette for screen image. */
  129.       for (i = 0; i < 32; i++)
  130.       {
  131.         j = i << 3;
  132.         palette[i] = (j << 16) | (j << 8) | j;
  133.       }
  134.       palette[32] = 0x00ffffffL;
  135.       GpiCreateLogColorTable(hpsMemory, (ULONG) LCOL_PURECOLOR,
  136.         (LONG) LCOLF_CONSECRGB, (LONG) 0L, (LONG) 33L, (PLONG) palette);
  137.       GpiSetBackMix(hpsMemory, BM_OVERPAINT);
  138.  
  139.       /* Create a semaphore to control access to the memory image
  140.          presentation space. Only one thread can perform Gpi operations
  141.          on it at a time. */
  142.       DosCreateMutexSem("\\sem32\\Lock", &hmtxLock, 0, FALSE);
  143.  
  144.       /* Create a thread to run the system model. */
  145.       DosCreateThread(&tidModel, Model, 0UL, 0UL, 4096);
  146.  
  147.       /* Take the input focus. */
  148.       WinFocusChange(HWND_DESKTOP, handle, 0L);
  149.       break;
  150.  
  151.     case WM_ERASEBACKGROUND:
  152.     case WM_PAINT:
  153.       /* Copy the memory image of the screen out to the real screen. */
  154.       DosRequestMutexSem(hmtxLock, SEM_INDEFINITE_WAIT);
  155.       WinBeginPaint(handle, hps, NULL);
  156.       GpiBitBlt(hps, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_AND);
  157.       WinEndPaint(hps);
  158.       DosReleaseMutexSem(hmtxLock);
  159.       break;
  160.  
  161.     case WM_CHAR:
  162.       if (SHORT1FROMMP(parm1) & KC_KEYUP)
  163.         break;
  164.       if (SHORT2FROMMP(parm2) == VK_PAUSE)
  165.       {
  166.         if (ModelSuspended == TRUE)
  167.         {
  168.           ModelSuspended = FALSE;
  169.         }
  170.         else
  171.         {
  172.           ModelSuspended = TRUE;
  173.         }
  174.       }
  175.       break;
  176.     default:
  177.       return WinDefWindowProc(handle, mess, parm1, parm2);
  178.   }
  179.   return (MRESULT) FALSE;
  180. }
  181.  
  182. void
  183. Model(ULONG dummy)
  184. {
  185.   /* Pointers to node storage. */
  186.   float ***node, **current, **excitatory, **inhibitory, **tmp;
  187.  
  188.   /* Epoch counter. */
  189.   unsigned long count;
  190.  
  191.   /* Temporary variables and flags. */
  192.   int x, y;
  193.   float harm;
  194.  
  195.   /* Work out mapping from bitmap color table to our logical palette. */
  196.   PrepareGraphics(RGBmap);
  197.  
  198.   /* Allocate node storage from the heap. */
  199.   node = Storage();
  200.  
  201.   /* Start at time 0. */
  202.   count = 0L;
  203.   current = node[0];
  204.   excitatory = node[1];
  205.   inhibitory = node[2];
  206.  
  207.   /* Main simulation loop. */
  208.   while(1)
  209.   {
  210.     while (ModelSuspended == TRUE)
  211.       DosSleep(100);
  212.  
  213.     for (x = 1; x < NUM_MASSES_X-1; x++)
  214.     {
  215.       for (y = 1; y < NUM_MASSES_Y-1; y++)
  216.       {
  217.         /* Difference equation for the 5-point wave equation. */
  218.         current[x][y] = 0.5*(excitatory[x+1][y] +
  219.                     excitatory[x-1][y] +
  220.                     excitatory[x][y+1] +
  221.                     excitatory[x][y-1]) -
  222.                     inhibitory[x][y];
  223.       }
  224.     }
  225.  
  226.     /* Apply harmonic inputs. */
  227.     harm = 30*sin(0.6*count);
  228.     current[130][120] += harm;
  229.     current[190][120] += harm;
  230.  
  231.     /* Display results. */
  232.     DisplayPlane(current);
  233.     
  234.     /* Advance epoch. */
  235.     count++;
  236.     tmp = inhibitory;
  237.     inhibitory = excitatory;
  238.     excitatory = current;
  239.     current = tmp;
  240.   }
  241. }
  242.  
  243. void
  244. PrepareGraphics(BYTE *RGBmap)
  245. {
  246.   POINTL coords;
  247.   int x, y;
  248.  
  249.   /* Give thread access to Gpi. */
  250.   habt = WinInitialize(0);
  251.  
  252.   /* Determine mapping from logical color value to bitmap color table
  253.      index.  Anybody know a more direct way??? */
  254.   DosRequestMutexSem(hmtxLock, SEM_INDEFINITE_WAIT);
  255.   for (x = 0, y = 0; x < 33; x++)
  256.   {
  257.       GpiSetColor(hpsMemory, (LONG) x);
  258.       coords.x = x;
  259.       coords.y = y;
  260.       GpiSetPel(hpsMemory, &coords);
  261.   }
  262.   bmp2data.cbFix = 16L;
  263.   GpiQueryBitmapInfoHeader(hbm, &bmp2data);
  264.   DosAllocMem((PPVOID)&pbmi, sizeof(BITMAPINFO2) +
  265.         (sizeof(RGB2) * (1 << bmp2data.cPlanes) *
  266.                 (1 << bmp2data.cBitCount)),
  267.                 PAG_COMMIT | PAG_READ | PAG_WRITE);
  268.   pbmi->cbFix = bmp2data.cbFix;
  269.   pbmi->cx = bmp2data.cx;
  270.   pbmi->cy = bmp2data.cy;
  271.   pbmi->cPlanes = bmp2data.cPlanes;
  272.   pbmi->cBitCount = bmp2data.cBitCount;
  273.   pbmi->ulCompression = bmp2data.ulCompression;
  274.   pbmi->cbImage = bmp2data.cbImage;
  275.   pbmi->cxResolution = bmp2data.cxResolution;
  276.   pbmi->cyResolution = bmp2data.cyResolution;
  277.   pbmi->cclrUsed = bmp2data.cclrUsed;
  278.   pbmi->cclrImportant = bmp2data.cclrImportant;
  279.   pbmi->usUnits = bmp2data.usUnits;
  280.   pbmi->usReserved = bmp2data.usReserved;
  281.   pbmi->usRecording = bmp2data.usRecording;
  282.   pbmi->usRendering = bmp2data.usRendering;
  283.   pbmi->cSize1 = bmp2data.cSize1;
  284.   pbmi->cSize2 = bmp2data.cSize2;
  285.   pbmi->ulColorEncoding = bmp2data.ulColorEncoding;
  286.   pbmi->ulIdentifier = bmp2data.ulIdentifier;
  287.   GpiQueryBitmapBits(hpsMemory, 0L, NUM_MASSES_Y-2, &Bitmap[0], pbmi);
  288.   DosReleaseMutexSem(hmtxLock);
  289.   for (x = 0; x < 33; x++)
  290.   {
  291.     RGBmap[x] = Bitmap[x];
  292.   }
  293. }
  294.  
  295. void
  296. DisplayPlane(float **current)
  297. {
  298.   int x, y;
  299.   int disp_val;
  300.  
  301.   for (y = 0; y < NUM_MASSES_Y; y++)
  302.   {
  303.     for (x = 0; x < NUM_MASSES_X; x++)
  304.     {
  305.       disp_val = ((int) current[x][y] + 16);
  306.       if (disp_val > 32) disp_val = 32;
  307.       else if (disp_val < 0) disp_val = 0;
  308.       Bitmap[y*NUM_MASSES_X+x] = RGBmap[disp_val];
  309.     }
  310.   }
  311.   DosRequestMutexSem(hmtxLock, SEM_INDEFINITE_WAIT);
  312.  
  313.   /* This is the key to the speed. Instead of doing a GPI call to set the
  314.      color and a GPI call to set the pixel for EACH pixel, we get by
  315.      with only two GPI calls. */
  316.   GpiSetBitmapBits(hpsMemory, 0L, (LONG) (NUM_MASSES_Y-2), &Bitmap[0], pbmi);
  317.   GpiBitBlt(hps, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_AND);
  318.  
  319.   DosReleaseMutexSem(hmtxLock);
  320. }
  321.  
  322. float ***
  323. Storage()
  324. {
  325.     float ***node;
  326.  
  327.     /* Allocate node storage from the heap. */
  328.     if (!(node = New3DOffloat(0, 2, 0, NUM_MASSES_X-1, 0, NUM_MASSES_Y-1)))
  329.     {
  330.         printf("Can't allocate required memory from heap.\n");
  331.         exit(1);
  332.     }
  333.     return(node);
  334. }
  335.