home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* PULS.PAS *)
- (* Pulsmessung über Joystickport *)
- (* Turbo Pascal ab 5.0 *)
- (* (c) 1990 Andreas Bartels & TOOLBOX *)
- (* ------------------------------------------------------ *)
-
- {$A+,B-,D-,E-,F-,I-,L-,N-,O-,R-,S-,V-} { Tempo ist Trumpf! }
-
- PROGRAM Puls_Messung_am_Gameport;
- { Pulsmessung am Finger oder Ohrläppchen... }
-
- USES Crt, Graph, Dos;
-
- FUNCTION Game_1_X : WORD; { Gameport abfragen }
- VAR
- w : BYTE;
- Zaehler, Wert : WORD;
- BEGIN
- w := 0;
- REPEAT
- Wert := Port[$201];
- Inc(w);
- UNTIL ((Wert AND 3) = 0) OR (w > 100);
- Port[$201] := Wert;
- Zaehler := 0;
- REPEAT
- Wert := Port[$201];
- Inc(Zaehler);
- UNTIL Wert AND 1 = 0;
- Game_1_X := Zaehler;
- END;
-
- FUNCTION Zeit : REAL;
- { fragt die Zeit ab und wandelt sie in eine Realzahl }
- VAR
- Hour, Min, Second, Sec100 : WORD;
- BEGIN
- GetTime(Hour, Min, Second, Sec100);
- Zeit := 3600 * Hour + 60 * Min + Second + Sec100 / 100;
- END;
-
- PROCEDURE Puls; { Hauptprozedur Pulsmessung }
- VAR
- R, RAlt : WORD;
- WayDown, PartDown, y : LONGINT;
- Gd, Gm, x, delx, MaxY, PulsX : INTEGER;
- yOffset, Min, Max, BeepCounter : WORD;
- yFaktor, At, Nt : REAL;
- ch : CHAR;
- CONST
- StrahlColor : WORD = LightGreen;
- RahmenColor : WORD = White;
- Step : BYTE = 2;
- BeepDelay = 10; { rechnerabhängig }
- BeepGuard = 120; { dito! }
-
- PROCEDURE ClearScope; { Anzeige löschen }
- BEGIN
- ClearViewPort;
- x := 0;
- delx := 2;
- WayDown := 0;
- PartDown := 0;
- RAlt := 0;
- BeepCounter := 0;
- SetTextStyle(DefaultFont, HorizDir, 1);
- SetTextJustify(LeftText, BottomText);
- OutTextXY(0, GetMaxY, 'toolbox-PULSATOR');
- MoveTo(0, Round((Game_1_X - yOffset)*yFaktor));
- END;
-
- PROCEDURE Abgleich; { Abgleichen der Meßwerte }
- VAR
- Count, Wert, Overhead : WORD;
- CONST
- MaxCount = 100; { Anzahl Messungen }
- BEGIN
- NoSound;
- SetTextStyle(DefaultFont, HorizDir, 2);
- SetTextJustify(CenterText, CenterText);
- SetColor(RahmenColor);
- OutTextXY(GetMaxX DIV 2, MaxY DIV 2,
- 'Abgleich - bitte warten...');
- Min := $FFFF; { Startwert Minimum auf hoch, }
- Max := 0; { Startwert Maximum auf tief setzen }
- FOR Count := 0 TO MaxCount DO BEGIN
- Wert := Game_1_X;
- IF Wert < Min THEN Min := Wert;
- IF Wert > Max THEN Max := Wert;
- END;
- Overhead := 3 * (Max - Min) DIV 5;
- { "Reserve" bei der Skalierung; ggf. anpassen }
- IF Min > Overhead THEN Dec(Min, Overhead)
- ELSE Min := 0;
- IF Max < $FFFF THEN Inc(Max, Overhead)
- ELSE Max := $FFFF;
- IF Max = Min THEN { Division durch 0 vermeiden }
- Max := Min + 2;
- yFaktor := MaxY / (Max - Min); { Skalierungsfaktor }
- yOffset := Min; { Verschiebung }
- ClearScope; { Schirm löschen }
- END;
-
- PROCEDURE ShowPuls; { Puls berechnen und anzeigen }
- VAR
- PulsStr : STRING[3];
- xAlt, yAlt : INTEGER;
- FPuls : WORD;
- BEGIN
- xAlt := GetX; { Position Grafikcursor sichern }
- yAlt := GetY;
- SetFillStyle(SolidFill, 0);
- Bar(PulsX, MaxY, GetMaxX, GetMaxY); { Feld löschen }
- Nt := Zeit;
- IF Nt <> At THEN BEGIN
- FPuls := Round(60 / (Nt - At));
- IF FPuls < 300 THEN
- At := Nt;
- END;
- Str(FPuls:3, PulsStr);
- SetColor(RahmenColor);
- SetTextStyle(DefaultFont, HorizDir, 1);
- SetTextJustify(LeftText, BottomText);
- OutTextXY(PulsX, GetMaxY, PulsStr);
- MoveTo(xAlt, yAlt); { Grafikcursor restaurieren }
- END;
-
- BEGIN { Hauptprogramm GamePuls }
- At := Zeit;
- Nt := Zeit;
- DetectGraph(Gd, Gm);
- InitGraph(Gd, Gm, '');
- IF Gd IN [CGA, MCGA, HercMono, EGAMono] THEN BEGIN
- StrahlColor := 1;
- RahmenColor := 1;
- END;
- SetTextStyle(DefaultFont, HorizDir, 1);
- SetTextJustify(LeftText, BottomText);
- PulsX := GetMaxX - 8 * TextWidth('X');
- MaxY := GetMaxY - 3 * TextHeight('X') DIV 2;
- Abgleich;
- REPEAT
- IF KeyPressed THEN BEGIN
- Ch := ReadKey;
- IF Ch = #0 THEN
- Ch := ReadKey;
- CASE Ch OF
- #32: Abgleich;
- #27: BEGIN
- NoSound;
- RestoreCrtMode;
- Halt(0);
- END;
- END;
- END;
- Inc(BeepCounter);
- IF BeepCounter > BeepGuard THEN Abgleich;
- Inc(x, Step);
- IF x > GetMaxX THEN x := 0;
- Inc(delx, Step);
- IF delx > GetMaxX THEN delx := 0;
- SetColor(0);
- SetLineStyle(SolidLn, 0, ThickWidth);
- Line(delx, 1 , delx, Pred(MaxY));
- RAlt := R;
- R := Game_1_X;
- IF RAlt < R THEN BEGIN { fallende Linie }
- PartDown := Abs(LONGINT(RAlt) - LONGINT(R));
- { wichtig: Typecasting! }
- Inc(WayDown, PartDown)
- END ELSE BEGIN { steigende Linie }
- IF Abs(RAlt - R) > PartDown THEN BEGIN
- WayDown := 0;
- PartDown := 0;
- END;
- END;
- { Bedingung für Piepsen eventuell anpassen! }
- IF (WayDown > (Max-Min) DIV 4) AND
- (BeepCounter > BeepDelay) THEN BEGIN
- BeepCounter := 0;
- Sound(100);
- ShowPuls;
- END ELSE
- NoSound;
- SetLineStyle(SolidLn, 0, NormWidth);
- SetColor(StrahlColor);
- y := Round((R - yOffset) * yFaktor);
- IF (y > MaxY) OR (y < 0) THEN
- Abgleich { Linie verläßt Schirm }
- ELSE
- IF x > 0 THEN
- LineTo(x, INTEGER(y)) { Linie ziehen }
- ELSE
- MoveTo(0, INTEGER(y)); { linker Rand }
- UNTIL FALSE;
- END;
-
- BEGIN
- Puls;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von PULS.PAS *)
-