(* ------------------------------------------------------------------------
  :Program.       PAMEHTAPatch
  :Contents.      Get PAMEHTA (AMOK #27) working with 2.0 and up
  :Author.        Kai Bolay [kai]
  :Address.       Snail-Mail:              E-Mail:
  :Address.       Hoffmannstraße 168       UUCP: kai@amokle.stgt.sub.org
  :Address.       D-7250 Leonberg 1        FIDO: 2:2407/106.3
  :History.       v1.0 [kai] 12-Jul-92 (derived from NTSC4NZTSC 1.9)
  :History.       v1.1 [kai] 17-Dec-92 (Patch OpenWindow() not OpenScreen() !!)
  :Copyright.     Freeware
  :Language.      Oberon
  :Translator.    AMIGA OBERON v3.0d
------------------------------------------------------------------------ *)
MODULE PAMEHTAPatch; (* $Debug- *)
(* $IF SmallData *) Not possible (* $END *)

(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)

IMPORT
  e: Exec, I: Intuition, g: Graphics, u: Utility, d: Dos, y: SYSTEM
  (* $IF DoIt *) ,dio: DebugIo (* $END *);

CONST
  OpenWindowOfs = -204;
  (* $IF DoIt *)
  Version = "$VER: PAMEHTAPatch v1.1 (17.12.92) by Kai Bolay (Debug)\r\n";
  (* $ELSE *)
  Version = "$VER: PAMEHTAPatch v1.1 (17.12.92) by Kai Bolay\r\n";
  (* $END *)
TYPE
  OpenWindowProc = PROCEDURE (newWindow{8}: I.NewWindowPtr): I.WindowPtr;
VAR
  OldOpenWindow: OpenWindowProc;

PROCEDURE NewOpenWindow* (newWindow{8}: I.NewWindowPtr): I.WindowPtr;
VAR
  Base: I.IntuitionBasePtr;
  type: SET;
  winPtr: I.WindowPtr;

(* $SaveRegs+ $ClearVars- Prepare to work in other tasks *)
BEGIN
  Base := y.REG (14);
  (* $IF DoIt *)
  dio.WriteString ("OpenWindow()\n");
  (* $END *)
  (* Do the magic *)
  type := newWindow.type;

  (* $IF DoIt *)
  dio.WriteString ("NewWindow: "); dio.WriteHex (y.VAL (LONGINT, newWindow), 8);
  dio.WriteLn;
  dio.WriteString ("Type: "); dio.WriteHex (y.VAL (INTEGER, newWindow.type), 4);
  (* $END *)

  IF (type * I.screenType # I.customScreen) AND
     (type * I.screenType # SET {I.wbenchScreen}) AND
     (type * I.screenType # SET {I.publicScreen}) THEN
    newWindow.type := type + I.customScreen;
  END;
  (* $IF DoIt *)
  dio.WriteString (" -> "); dio.WriteHex (y.VAL (INTEGER, newWindow.type), 4);
  dio.WriteLn;
  (* $END *)

  y.SETREG (14, Base);
  winPtr := OldOpenWindow (newWindow);
  (* $IF DoIt *)
  dio.WriteString ("Open!\n\n");
  (* $END *)
  newWindow.type := type;
  y.SETREG (14, Base);
  RETURN winPtr;
END NewOpenWindow;


BEGIN
  (* $IF DoIt *)
  dio.OpenIo;
  dio.WriteString ("Jappadappaduuu!\n");
  (* $END *)
  y.SETREG (0, d.Write (d.Output (), Version[6], y.SIZE (Version)-6));
  (* 2.04 should be :-) *)
  IF I.int.libNode.version < 37 THEN
    IF d.Output () # NIL THEN
      y.SETREG (0, d.Write (d.Output (), "Sorry, I need OS 2.04!\n", 23));
    END;
    HALT (20);
  END;

  (* Patch *)
  e.Forbid;
  OldOpenWindow := y.VAL (OpenWindowProc,
                          e.SetFunction (I.int, OpenWindowOfs,
                                         y.VAL (e.PROC, NewOpenWindow)));
  e.Permit;

  (* Wait for Break *)
  y.SETREG (0, e.Wait (LONGSET {d.ctrlC})); (* ... *)

  (* Unpatch *)
  e.Forbid;
  OldOpenWindow := y.VAL (OpenWindowProc,
                          e.SetFunction (I.int, OpenWindowOfs,
                                         y.VAL (e.PROC, OldOpenWindow)));
  e.Permit;
  IF (y.VAL (y.ADDRESS, OldOpenWindow) # y.VAL (y.ADDRESS, NewOpenWindow)) THEN
    IF I.DisplayAlert (I.recoveryAlert,
                       "\x00\x10\x10Someone else patched too. Safety cannot be guarateed, please reboot!\o\n\x00\x10\x1A     -> Reboot <-                           -> Hope and pray <-     \o\o",
                       40) THEN
      e.ColdReboot;
    END;
  END;
  (* $IF DoIt *)
  dio.CloseIo;
  (* $END *)
END PAMEHTAPatch.
