Annotation of pmsdk/samples/petzold/chap08/organ.c, revision 1.1.1.1

1.1       root        1: /*--------------------------------------
                      2:    ORGAN.C --  Play Organ from Keyboard
                      3:   --------------------------------------*/
                      4: 
                      5: #define INCL_DOS
                      6: #define INCL_WIN
                      7: #define INCL_GPI
                      8: #include <os2.h>
                      9: #include "organ.h"
                     10: 
                     11: MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
                     12: VOID    EXPENTRY Speaker (USHORT usFreq) ;
                     13: 
                     14: SHORT  xOffset, yOffset, cxCaps, cyChar ;
                     15: USHORT usLastScan ;
                     16: 
                     17: int main (void)
                     18:      {
                     19:      static CHAR  szClientClass [] = "Organ" ;
                     20:      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU |
                     21:                                  FCF_SIZEBORDER    | FCF_MINMAX  |
                     22:                                  FCF_SHELLPOSITION | FCF_TASKLIST ;
                     23:      HAB          hab ;
                     24:      HMQ          hmq ;
                     25:      HWND         hwndFrame, hwndClient ;
                     26:      QMSG         qmsg ;
                     27: 
                     28:      if (DosPortAccess (0, 0, 0x42, 0x61))   // Don't run if port access fails
                     29:           return 1 ;
                     30: 
                     31:      hab = WinInitialize (0) ;
                     32:      hmq = WinCreateMsgQueue (hab, 0) ;
                     33: 
                     34:      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
                     35: 
                     36:      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
                     37:                                      &flFrameFlags, szClientClass, NULL,
                     38:                                     0L, NULL, 0, &hwndClient) ;
                     39: 
                     40:      WinSendMsg (hwndFrame, WM_SETICON,
                     41:                  WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
                     42:                  NULL) ;
                     43: 
                     44:      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
                     45:           WinDispatchMsg (hab, &qmsg) ;
                     46: 
                     47:      WinDestroyWindow (hwndFrame) ;
                     48:      WinDestroyMsgQueue (hmq) ;
                     49:      WinTerminate (hab) ;
                     50:      DosPortAccess (0, 1, 0x42, 0x61) ;
                     51:      return 0 ;
                     52:      }
                     53: 
                     54: VOID DrawKey (HPS hps, USHORT usScanCode, BOOL fInvert)
                     55:      {
                     56:      RECTL rcl ;
                     57: 
                     58:      rcl.xLeft   = 3 * cxCaps * key[usScanCode].xPos / 2 + xOffset ;
                     59:      rcl.yBottom = 3 * cyChar * key[usScanCode].yPos / 2 + yOffset ;
                     60:      rcl.xRight  = rcl.xLeft   + 3 * cxCaps ;
                     61:      rcl.yTop    = rcl.yBottom + 3 * cyChar / 2 ;
                     62: 
                     63:      WinDrawText (hps, -1, key[usScanCode].szKey, &rcl,
                     64:                   CLR_NEUTRAL, CLR_BACKGROUND,
                     65:                   DT_CENTER | DT_VCENTER | DT_ERASERECT) ;
                     66:      if (fInvert)
                     67:           WinInvertRect (hps, &rcl) ;
                     68: 
                     69:      WinDrawBorder (hps, &rcl, 1, 1, CLR_NEUTRAL, CLR_BACKGROUND,
                     70:                     DB_STANDARD) ;
                     71:      }
                     72: 
                     73: VOID ProcessKey (HPS hps, USHORT usScanCode, USHORT fsFlags)
                     74:      {
                     75:      static USHORT ausOctFreq [] = { 262, 277, 294, 311, 330, 349,
                     76:                                      370, 392, 415, 440, 466, 494 } ;
                     77:      USHORT        usOct, usFreq ;
                     78: 
                     79:      if (usScanCode >= NUMSCANS)                       // No scan codes over 53
                     80:           return ;
                     81:      if ((usOct = key[usScanCode].sOctave) == -1)      // Non-music key
                     82:           return ;
                     83: 
                     84:      if (fsFlags & KC_KEYUP)                           // For key up
                     85:           {
                     86:           if (usLastScan == usScanCode)                // If that's the note
                     87:                {
                     88:                Speaker (0) ;                           // turn off speaker
                     89:                DrawKey (hps, usScanCode, FALSE) ;      // and redraw key
                     90:                usLastScan = 0 ;
                     91:                }
                     92:           return ;
                     93:           }
                     94:      if (fsFlags & KC_PREVDOWN)                        // Ignore typematics
                     95:           return ;
                     96: 
                     97:      usFreq = ausOctFreq [key[usScanCode].sNote] ;     // Get frequency
                     98: 
                     99:      if (fsFlags & KC_SHIFT)
                    100:           usOct += fsFlags & KC_ALT ? 2 : 1 ;          // Higher octave
                    101:      else if (fsFlags & KC_CTRL)
                    102:           usOct -= fsFlags & KC_ALT ? 2 : 1 ;          // Lower octave
                    103: 
                    104:      if (usOct > 4)                                    // Shift frequency
                    105:           usFreq <<= (usOct - 4) ;                     //   for octave
                    106:      else if (usOct < 4)
                    107:           usFreq >>= (4 - usOct) ;
                    108: 
                    109:      Speaker (usFreq) ;                                // Turn on speaker
                    110:      DrawKey (hps, usScanCode, TRUE) ;                 // Draw the inverted key
                    111: 
                    112:      if (usLastScan != 0)
                    113:           DrawKey (hps, usLastScan, FALSE) ;           // Redraw previous key
                    114:      usLastScan = usScanCode ;                         // Save scan code
                    115:      }
                    116: 
                    117: MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
                    118:      {
                    119:      FONTMETRICS fm ;
                    120:      HPS         hps ;
                    121:      SHORT       cxClient, cyClient ;
                    122:      USHORT      usScanCode ;
                    123: 
                    124:      switch (msg)
                    125:           {
                    126:           case WM_CREATE:
                    127:                hps = WinGetPS (hwnd) ;
                    128:                GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ;
                    129:                cxCaps = (SHORT) fm.lEmInc ;
                    130:                cyChar = (SHORT) fm.lMaxBaselineExt ;
                    131:                WinReleasePS (hps) ;
                    132:                return 0 ;
                    133: 
                    134:           case WM_SIZE:
                    135:                cxClient = SHORT1FROMMP (mp2) ;
                    136:                cyClient = SHORT2FROMMP (mp2) ;
                    137: 
                    138:                xOffset = (cxClient - 25 * 3 * cxCaps / 2) / 2 ;
                    139:                yOffset = (cyClient - 6 * cyChar) / 2 ;
                    140:                return 0 ;
                    141: 
                    142:           case WM_CHAR:
                    143:                if (!(CHARMSG(&msg)->fs & KC_SCANCODE))
                    144:                     break ;
                    145: 
                    146:                hps = WinGetPS (hwnd) ;
                    147:                ProcessKey (hps, CHARMSG(&msg)->scancode, CHARMSG(&msg)->fs) ;
                    148:                WinReleasePS (hps) ;
                    149:                return 0 ;
                    150: 
                    151:           case WM_PAINT:
                    152:                hps = WinBeginPaint (hwnd, NULL, NULL) ;
                    153:                GpiErase (hps) ;
                    154: 
                    155:                for (usScanCode = 0 ; usScanCode < NUMSCANS ; usScanCode++)
                    156:                     if (key[usScanCode].xPos != -1)
                    157:                          DrawKey (hps, usScanCode, usScanCode == usLastScan) ;
                    158: 
                    159:                WinEndPaint (hps) ;
                    160:                return 0 ;
                    161:           }
                    162:      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
                    163:      }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.