(*********************************************************************
 *                                                                   *
 *  :Program.    GameSupport.mod                                     *
 *  :Author.     Michael Frieß                                       *
 *  :Address.    Kernerstr. 22a                                      *
 *  :Address.    7000 Stuttgart 1                                    *
 *  :Phone.                                                          *
 *  :shortcut.   [MiF]                                               *
 *  :Version.    0.2                                                 *
 *  :Date.       03.04.88                                            *
 *  :Copyright.  PD                                                  *
 *  :Language.   Modula-II                                           *
 *  :Translator. M2Amiga                                             *
 *  :Contents.   Routinen zur Spieleprogrammierung                   *
 *                                                                   *
 *********************************************************************)

IMPLEMENTATION MODULE GameSupport;

FROM Hardware       IMPORT custom, ciaa;

FROM SYSTEM         IMPORT LONGSET, ADR, ADDRESS, BITSET, CAST,
                           INLINE;

FROM Exec           IMPORT OpenDevice, CloseDevice, MessagePtr,
                           MsgPortPtr, IOStdReq, IOStdReqPtr, quick,
                           DoIO, SendIO, WaitPort, GetMsg;

FROM ExecSupport    IMPORT CreatePort, DeletePort,
                           CreateStdIO, DeleteStdIO;

FROM GamePort       IMPORT gamePortName, setCType, Controller,
                           Keys, KeySet, GamePortTrigger,
                           setTrigger, readEvent;

FROM InputEvent     IMPORT InputEvent, lButton, upPrefix;

FROM Arts           IMPORT TermProcedure;


TYPE ByteSet = SET OF [0..7];

VAR
 (* von den Controller-Prozeduren benötigte Variablen *)
  gamemsgport     :    MsgPortPtr;
  gameiomsg       :    IOStdReqPtr;
  flags           :    LONGSET;
  msgptr          :    MessagePtr;
  gamedata        :    InputEvent;



PROCEDURE GetController (VAR r : Result; p : Port);
 (* Semantik siehe Definitionsmodul *)

BEGIN
  gameiomsg^.command := readEvent;
  gameiomsg^.data    := ADR(gamedata);
  gameiomsg^.length  := SIZE (InputEvent);
  gameiomsg^.flags   := quick;
  SendIO(gameiomsg);
  WaitPort(gamemsgport);
  msgptr := GetMsg(gamemsgport);
  IF gamedata.code = lButton THEN
    r.button := Pushed;
  ELSIF gamedata.code = lButton + upPrefix THEN
    r.button := Released;
  ELSE
    r.button := None;
  END;
  IF gamedata.y = -1 THEN
    r.y      := Back;
  ELSIF gamedata.y = 1 THEN
    r.y      := Forward;
  ELSE
    r.y      := None;
  END;
  IF gamedata.x = -1 THEN
    r.x      := Left;
  ELSIF gamedata.x = 1 THEN
    r.x      := Right;
  ELSE
    r.x      := None;
  END;
END GetController;





PROCEDURE QDJoystick (VAR r : Result; p : Port);
 (* Semantik siehe Definitionsmodul *)

VAR j : BITSET;
    b : ByteSet;

BEGIN
  CASE p OF
    0: j := CAST(BITSET,custom.joy0dat) |
    1: j := CAST(BITSET,custom.joy1dat)
  END;
  IF 1 IN j    THEN r.x := Right;
  ELSIF 9 IN j THEN r.x := Left;
  ELSE              r.x := None;
  END;
  IF (8 IN j) # (9 IN j)    THEN r.y := Back;
  ELSIF (0 IN j) # (1 IN j) THEN r.y := Forward;
  ELSE                           r.y := None;
  END;
  b := CAST(ByteSet,ciaa.ciapra);
  IF (6+p) IN b THEN
    r.button := None;
  ELSE
    r.button := Pushed;
  END;
END QDJoystick;




PROCEDURE SetControllerType (c : Controller; p : Port);
 (* Semantik siehe Definitionsmodul *)

BEGIN
  gameiomsg^.command := setCType;
  gameiomsg^.length  := 1;
  gameiomsg^.data    := ADR(c);
  SendIO (gameiomsg);
  WaitPort (gamemsgport);
  gameiomsg := GetMsg (gamemsgport);
END SetControllerType;



PROCEDURE SetControllerTrigger (t : GamePortTrigger; p : Port);
 (* Semantik siehe Definitionsmodul *)

BEGIN
  gameiomsg^.command := setTrigger;
  gameiomsg^.length  := SIZE (GamePortTrigger);
  gameiomsg^.data    := ADR(t);
  DoIO (gameiomsg);
END SetControllerTrigger;


PROCEDURE CloseController;
  (* Bei Beendigung des Programms müssen alle Resourcen wieder
     freigegeben werden, dies geschieht mit dieser Prozedur. Sie
     wird beim Initialiseren eines Controllers an TermProcedure
     vom Modul Arts übergeben.
   *)

BEGIN
  SetControllerType (noController,1);
  CloseDevice (gameiomsg);
  DeleteStdIO (gameiomsg);
  DeletePort (gamemsgport);
END CloseController;


PROCEDURE InitController (p : Port);
 (* Semantik siehe Definitionsmodul *)

 VAR  g : GamePortTrigger;

BEGIN
  gamemsgport := CreatePort (0,0);
  gameiomsg  := CreateStdIO (gamemsgport);
  OpenDevice  (ADR(gamePortName), 1, gameiomsg, LONGSET{0});
  SetControllerType (absJoystick,p);
  g.keys      := KeySet{downKeys, upKeys };
  g.timeout   := 1;
  g.xDelta    := 1;
  g.yDelta    := 1;
  SetControllerTrigger (g,p);
  (* Nicht vergessen, immer schön zurückgeben, was man sich
     geholt hat! *)
  TermProcedure (CloseController);
END InitController;

PROCEDURE InitRelative;
BEGIN
END InitRelative;



PROCEDURE Relativate (VAR x, y : INTEGER;
                      action   :INTEGER);

 VAR t: INTEGER;

BEGIN
 IF action # 0 THEN
   t := (x*12 - action*y*5) DIV 13;
   y := (x*5*action + y*12) DIV 13;
   x := t;
 END;
END Relativate;

END GameSupport.
