[Back to JOYSTICK SWAG index]  [Back to Main SWAG index]  [Original]

==============================================================================
 BBS: ®® The Information and Technology Exchan
  To: MATT CRILL                   Date: 01-05Ä92 (23:03)
From: DANIEL CHURCHMAN           Number: 4144   [101] PASCAL
Subj: JOYSTICK 1                 Status: Public
------------------------------------------------------------------------------
Program Joy;  { Read Joystick positions and button states }

Uses DOS, Crt;

Const
  Buttons          : Byte = 0;
  Joystick         : Byte = 1;

  JoyIntr          : Byte = $15;
  JoyFunc          : Byte = $84;

  CStart           : Byte = 0; { To hold cursor start line }
  CEnd             : Byte = 0; { To hold cursor end line }

  kX               : Real = 6.25; { constant for horizontal conversion }
  kY               : Real = 20.0; { constant for vertical conversion }

  LastKey          : Char = ' ';

Var
  { Variables for Joystick 1 }
  Joy1Vert         : Word; { Vertical Position }
  Joy1Hori         : Word; { Horizontal Position }
  Joy1But1         : Boolean; { Button 1 }
  Joy1But2         : Boolean; { Button 2 }

  { Variables for Joystick 2 }
  Joy2Vert         : Word; { Vertical Position }
  Joy2Hori         : Word; { Horizontal Position }
  Joy2But1         : Boolean; { Button 1 }
  Joy2But2         : Boolean; { Button 2 }

  Error            : Boolean; { We'll set this if the joystick isn't found }

  Regs             : Registers;
  NewX, NewY       : Byte;
  OldX, OldY       : Byte;
  MinX, MinY,
  MaxX, MaxY       : Word;

{ Checkjoy and CheckBut are really the only two procedures of real }
{ interest to you; the rest is just support code to do something   }
{ with the samples.                                                }


Procedure CheckJoy;
    begin   { Prepare and make Int 15h, subfunction 84h call }
      With Regs do
      begin
        AH := JoyFunc;
        DX := Joystick;  { Subfunction 1 = joystick }
        Intr(JoyIntr, Regs);
        Joy1Hori := AX;
        Joy1Vert := BX;
        Joy2Hori := CX;
        Joy2Vert := DX;
        Error := ((Flags AND FCarry) <> 0)
      end;
    end;

Procedure CheckBut;
    Const
      MaskJ1B1     = $10;
      MaskJ1B2     = $20;
      MaskJ2B1     = $40;
      MaskJ2B2     = $80;
    begin   { Prepare and make Int 15h, subfunction 84h call }
      With Regs do
      begin
        AH := JoyFunc;
        DX := Buttons;  { Subfunction 0 = buttons }
        Intr(JoyIntr, Regs);
        Joy1But1 := (AL AND MaskJ1B1) <> MaskJ1B1;
        Joy1But2 := (AL AND MaskJ1B2) <> MaskJ1B2;
        Joy2But1 := (AL AND MaskJ2B1) <> MaskJ2B1;
        Joy2But2 := (AL AND MaskJ2B2) <> MaskJ2B2;
        Error := ((Flags AND FCarry) <> 0)
      end;
    end;

Procedure Calibrate;
    Var
      n            : Byte;
    begin
      { Calibrate joystick 1 }
      CheckJoy;
      If Error then
      begin
        Write('No Joystick(s) found - terminating program');
        Halt(1)
      end;

      If (Joy1Vert + Joy1Hori) = 0 then
        Writeln('Joystick 1 Absent')
      else
        Writeln('Joystick 1 Present');
      If (Joy2Vert + Joy2Hori) = 0 then
        Writeln('Joystick 2 Absent')
      else
        Writeln('Joystick 2 Present');

(*      { Get centre joystick values for X and Y }
      Write('Hold joystick in centre position and press a button');
      Repeat
        CheckBut
      Until (Joy1But1 OR Joy1But2);
      CentreX := 0;
      CentreY := 0;
      For n := 1 to 10 do
      begin
        CheckJoy;
        CentreX := CentreX + Joy1Hori;
        CentreY := CentreY + Joy1Vert;
      end;
      CentreX := CentreX DIV 10;
      CentreY := CentreY DIV 10;
      While (Joy1But1 OR Joy1But2) do  { Wait till button released }
      begin
        CheckBut
      end;
      Writeln('  -  ',CentreX,':',CentreY);
*)

      { Get minimum joystick values for X and Y }
      Write('Hold joystick in upper-left position and press a button');
      Repeat
        CheckBut
      Until (Joy1But1 OR Joy1But2);
      MinX := 0;
      MinY := 0;
      For n := 1 to 10 do  { Sample over time for accuracy }
      begin
        CheckJoy;
        { Bias the reading slightly to ensure }
        { we can always reach coord 1,1 }
        MinX := MinX + Word(Round(Joy1Hori * 1.1));
        MinY := MinY + Word(Round(Joy1Vert * 1.1))
      end;
      MinX := MinX DIV 10;
      MinY := MinY DIV 10;
      While (Joy1But1 OR Joy1But2) do  { Wait till button released }
      begin
        CheckBut
      end;
      Writeln('  -  ',MinX,':',MinY);

      { Get maximum joystick values for X and Y }
      Write('Hold joystick in bottom-right position and press a button');
      Repeat
        CheckBut
      Until (Joy1But1 OR Joy1But2);
      MaxX := 0;
      MaxY := 0;
      For n := 1 to 10 do   { Sample over time for accuracy }
      begin
        CheckJoy;
        { Bias the reading slightly to ensure }
        { we can always reach coord 80,25 }
        MaxX := MaxX + Word(Round(Joy1Hori * 0.95));
        MaxY := MaxY + Word(Round(Joy1Vert * 0.95))
      end;
      MaxX := MaxX DIV 10;
      MaxY := MaxY DIV 10;
      While (Joy1But1 OR Joy1But2) do  { Wait till button released }
      begin
        CheckBut
      end;
      Writeln('  -  ',MaxX,':',MaxY);

      { Important to note that the following calculations of kX and   }
      { kY is done linearly.  This is not really correct, as you'll   }
      { see by the fact that when centred, your screen coords are     }
      { NOT 40,13.  The reason is that the resistors in joysticks     }
      { work on a logarithmic scale.  My knowledge of logs is too     }
      { rusty to build this in properly, so I've skipped it.  What    }
      { you should do is derive the log that correctly passes through }
      { minimum, maximum AND centre.  This way, the joystick, centred }
      { will correctly position your screen coord dead centre, and    }
      { you can still reach the extremes as well.                     }

      kX := (MaxX - MinX) / 80;
      kY := (MaxY - MinY) / 25;
      Writeln('kX = ', kX:0:2,'     kY = ',kY:0:2);

    end;

[Continued]


--- Msged/sq
 * Origin: C&O Systems, Brisbane, AUSTRALIA (3:640/777)
==============================================================================
 BBS: ®® The Information and Technology Exchan
  To: MATT CRILL                   Date: 01-05Ä92 (23:04)
From: DANIEL CHURCHMAN           Number: 4145   [101] PASCAL
Subj: JOYSTICK 2                 Status: Public
------------------------------------------------------------------------------
Procedure SetCoord;
    begin
      If Joy1Hori < MinX then NewX := 1 else
        NewX := Byte(Round((Joy1Hori - MinX) / kX));
      If Joy1Vert < MinY then NewY := 1 else
        NewY := Byte(Round((Joy1Vert - MinY) / kY));

      If NewX = 0 then NewX := 1;
      If NewX > 80 then NewX := 80;
      If NewY = 0 then NewY := 1;
      If NewY > 25 then NewY := 25;

    end;

Procedure MoveIndicator;
    begin

      { If the position has changed, clean up old indicator }
      If NOT ((OldX = NewX) AND (OldY = NewY)) then
      begin

        { Turn off indicator at old position }
        With Regs do
        begin
          { First, move cursor to old position }
          AH := 2;   { Set cursor position                }
          BH := 0;   { Assume page 0                      }
          DH := OldY - 1; { This value must be zero-based }
          DL := OldX - 1; { This one too                  }
          Intr($10,Regs);

          { Now change the attribute }
          AH := 8;   { Read what character is there now                  }
          BH := 0;   { I'm assuming page 0                               }
          Intr($10,Regs);  {AH now holds the attribute, AL the character }
          AH := 9;   { Write Character and Attribute, AL is ok, so...    }
          BL := 31;  { ...only change the attribute                      }
          BH := 0;   { Again, assume page 0                              }
          CX := 1;   { Number of characters to write                     }
          Intr($10,Regs)
        end
      end;
      { Always refresh the current position }

      With Regs do
      begin
        { Next, move cursor to new position }
        AH := 2;   { Set cursor position                }
        BH := 0;   { Assume page 0                      }
        DH := NewY - 1; { This value must be zero-based }
        DL := NewX - 1; { This one too                  }
        Intr($10,Regs);

        { Then, turn on indicator at NEW position }
        AH := 8;   { Read what character is there now                  }
        BH := 0;   { I'm assuming page 0                               }
        Intr($10,Regs);  {AH now holds the attribute, AL the character }
        AH := 9;   { Write Character and Attribute, AL is ok, so...    }
        BL := 112; { ...change the attribute to black on grey          }
        BH := 0;   { Again, assume page 0                              }
        CX := 1;   { Number of characters to write                     }
        Intr($10,Regs)

      end;

    end;

Procedure InitScreen;
    begin
      GotoXY(26,10);
      Write('Joystick 1        Joystick 2');
      GotoXY(20,12);
      Write('X :');
      GotoXY(20,13);
      Write('Y :');
      GotoXY(14,14);
      Write('Buttons :');
      GotoXY(16,16);
      Write('Error =');
      GotoXY(20,23);
      Write('Press "C" to reCalibrate your joystick');

      With Regs do
      begin      { First, save present cursor configuration }

        AH := 3; { Read cursor pos and config }
        BH := 0; { Assuming we are using page 0 }
        Intr($10,Regs);
        CStart := CH; { Starting line of cursor }
        CEnd   := CL; { Ending line of cursor }
        { DH holds cursor row }
        { DL holds cursor column }

        { Now turn the cursor off - we hope! }

        AH := 1;  { Set cursor type }
        CH := $20; { Should cause the cursor to disappear }
        Intr($10,Regs);

      end
    end;

Procedure GetKey;
    begin
      If KeyPressed then
      begin
        LastKey := ReadKey;  { Read the key in the buffer       }
        If LastKey = #0 then { The key is an extended character }
          LastKey := ReadKey { Read the extended value          }
      end else
        LastKey := #0
    end;

[Continued]

--- Msged/sq
 * Origin: C&O Systems, Brisbane, AUSTRALIA (3:640/777)
==============================================================================
 BBS: ®® The Information and Technology Exchan
  To: MATT CRILL                   Date: 01-05Ä92 (23:05)
From: DANIEL CHURCHMAN           Number: 4146   [101] PASCAL
Subj: JOYSTICK 3                 Status: Public
------------------------------------------------------------------------------
begin
  TextAttr := 31;  { White on Blue - my favourite :-) }
  ClrScr;

  Calibrate;
  SetCoord;

  InitScreen;

  Repeat
    GetKey;  { Simply load the variable LastKey with }
             { a keystroke if one is available       }
    CheckJoy;
    CheckBut;
    OldX := NewX;
    OldY := NewY;
    SetCoord;
    GotoXY(24,12);
    Write(Joy1Hori:10);
    GotoXY(24,13);
    Write(Joy1Vert:10);
    GotoXY(31,14);
    Write((Joy1But1):5,':',(Joy1But2):5);

    GotoXY(44,12);
    Write(Joy2Hori:10);
    GotoXY(44,13);
    Write(Joy2Vert:10);
    GotoXY(51,14);
    Write(Byte(Joy2But1),':',Byte(Joy2But2));

    GotoXY(37,15);
    Write(NewX:2,':',NewY:2);

    GotoXY(24,16);
    Write(Error:5);

    Writeln;
    MoveIndicator;

    If UpCase(LastKey) = 'C' then
    begin
      ClrScr;
      Calibrate;
      InitScreen
    end;

  Until LastKey = #27;

  With Regs do
  begin      { Restore original cursor configuration }

    AH := 1;  { Set cursor type }
    CH := CStart; { Original cursor start line }
    CL := CEnd;   { Original cursor end line }
    Intr($10,Regs);
    GotoXY(1,24)
  end;

end.



[End of code]
--- Msged/sq
 * Origin: C&O Systems, Brisbane, AUSTRALIA (3:640/777)

[Back to JOYSTICK SWAG index]  [Back to Main SWAG index]  [Original]