' eXtended-Hardcopy-Accessory
' ---------------------------
'
' ˝ HayoSoft 1990 (und Uwe Seimet 1988)
' Hayo Schmidt
' Grotiusweg 1
' 2000 Hamburg 55
'
' Anregungen von:
' Uwe Seimet, vgl. ST-Computer 4/90, S.94ff
'
$m300
' $I- Option kostet 1200 Bytes
$U- ! Option bringt nichts
$%3 ! "
$E- ! "
$P< ! "
$*& ! bringt scheinbar 92 Bytes
'
'
REM Als Accessory initialisieren
' ap_id&=APPL_INIT() ![direkt bergeben spart 4 Bytes]
IF {BASEPAGE+&H24}=0   ! wenn p_parent gleich null, ist es ein Accessory
  INLINE adr_buffer%,16
  IF MENU_REGISTER(APPL_INIT(),"  XHardcopy 1.2")=-1 ! registrieren
    ' PRINT "pXHardcopy nicht installiert - Menu_register() fehlgeschlagenq"
    END
  ENDIF
  DO
    ~EVNT_MESAG(adr_buffer%) ! warten bis Aufruf 40 AC_OPEN
    '
    IF WORD{adr_buffer%}=40
      ~WIND_UPDATE(3)
      xhard
      ~WIND_UPDATE(2)
    ENDIF
  LOOP
ELSE
  xhard
ENDIF
END
' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
'
PROCEDURE xhard
  '
  ' LOCAL mx&,my&,lw&,lh&,m_state&
  '
  REM Bildschirmparameter
  '   (mssen immer wieder neu geholt werden wegen AutoSwitchOverScan)
  xres&=WORD{L~A-12}                  ! Bildschirmauflsung
  yres&=WORD{L~A-4}
  v_lin_wr&=WORD{L~A+2}               ! Bytes pro Videozeile
  v_planes&=WORD{L~A}                 ! Anzahl Bildebenen
  pixperline&=v_lin_wr& DIV v_planes& ! Pixel pro Zeile
  '
  al&=FORM_ALERT(2,"[2][       *** XHardcopy ***| |      Bildschirm-Hardcopy|      Ausschnitt-Hardcopy|         ˝HayoSoft 1990][Bildschirm|Ausschnitt|Abbruch]")
  '
  IF al&=1
    blkhardcopy(0,0,xres&,yres&)         ! gesamter Bildschirm
  ELSE IF al&=2
    DEFMOUSE 3                           ! Ausschnitt
    ~EVNT_BUTTON(1,1,1,mx&,my&,d&,d&)       ! x,y-Koordinaten bestimmen
    ~GRAF_RUBBERBOX(mx&,my&,0,0,lw&,lh&)    ! Breite, Hhe bestimmen
    '
    ' statt GRAPHMODE 3
    REM vswr_mode()
    '   Set Writing Mode
    CONTRL(6)=V~H
    INTIN(0)=3
    VDISYS 32,1,0
    '
    REM vsf_interior(vsfi_hd&,style&)
    '   Set Fill Interior Style
    ' CONTRL(6)=V~H
    INTIN(0)=0
    VDISYS 23,1,0
    '
    FOR i&=3 DOWNTO 0
      ' statt BOX mx&,my&,mx&+lw&,my&+lh&   ! Ausschnitt nochmal anzeigen
      REM v_bar()
      ' CONTRL(6)=V~H
      PTSIN(0)=mx&
      PTSIN(1)=my&
      PTSIN(2)=mx&+lw&
      PTSIN(3)=my&+lh&
      VDISYS 11,0,2,1
      '
      PAUSE 5
    NEXT i&
    DEFMOUSE 0
    blkhardcopy(mx&,my&,lw&,lh&)
  ENDIF
RETURN
' --------------------------------
'
PROCEDURE blkhardcopy(x&,y&,w&,h&)
  ' Block-Hardcopy:
  ' Fhrt automatisch Hardcopy eines bestimmten Bildausschnittes durch.
  ' Luft auch unter Hyperscreen/OverScan.
  ' ˝HayoSoft 1990
  '
  ' LOCAL setprt%,pmask%,prttype&
  '
  setprt%=XBIOS(33,-1)       ! SETPRT
  ' RESTORE prttypes
  '   FOR i&=0 TO setprt% AND 7
  '   READ prttype&
  ' NEXT i&
  '
  '                        ! Wesentlich krzer folgende Form der Tabelle
  INLINE prttypes%,8
  {prttypes%}=&H201FF      ! Tabelle in FLOAT-Variable (15 B krzer als String)
  {prttypes%+4}=&H3FFFFFF
  prttype&=BYTE{prttypes%+(setprt% AND 7)}
  '
  ' RESTORE pmask
  ' pmask$=""
  ' FOR i&=0 TO 17
  '   READ pm|
  '   pmask$=pmask$+CHR$(pm|)
  ' NEXT i&
  '
  ' wesentlich krzer ist
  INLINE pmask%,18
  {pmask%}=&HF0F0D06
  {pmask%+4}=&H9060806
  {pmask%+8}=&H8020800
  {pmask%+12}=&H8000800       ! durch die 2 nderungen habe ich ber 1800
  ' WORD{pmask%+16}=0           ! Bytes eingespart.
  '
  xdiv8&=x& DIV 8
  a%=XBIOS(3)+xdiv8&*v_planes&              ! Die Zerlegung der Parameter
  ADD a%,MUL(y&,v_lin_wr&)
  SUB x&,MUL(xdiv8&,8)                      ! auf Variablen
  c&=MUL(pixperline&,8)-w&                  ! bringt nochmal 740 Bytes
  d&=-BTST(setprt%,2)
  e&=-BTST(setprt%,4)
  prtblk(a%,x&,w&,h&,c&,0,XBIOS(4),d&,&HFF8240,prttype&,e&,pmask%)
  '
  ' prtblk(XBIOS(3)+x& DIV 8+y&*v_lin_wr&/v_planes&,x& MOD 8,w&,h&,v_lin_wr&*8-w&,0,XBIOS(4),-1*(BTST(setprt%,2)),&HFF8240,prttype&,-1*(BTST(setprt%,4)),pmask%)
  '     logbase   x,y in Bytes umrechnen   x-Rest  Breite
  '                                                 Hhe
  ' prttypes:               ! Druckertypen entsprechend OS-Tabelle
  ' DATA 0,2,1,-1,3,-1,-1,-1
  '
  ' pmask:                  ! Graustufenmaske
  ' DATA $0F,$0F,$0D,$06,$09,$06,$08,$06
  ' DATA $08,$02,$08,$00,$08,$00,$08,$00
  ' DATA $00,$00
  '
  ' Parameterbeschreibung:
  ' ----------------------
  ' blkprt%        logbase
  '                + x-Koordinate in Bytes
  '                + y-Koordinate mal Bytes pro Videozeile.
  ' offset&        ist der nicht durch 8 teilbare Rest der x-Koordinate.
  ' width&,height& ist wohl klar.
  ' left&          v_lin_wr, die Anzahl Bytes pro Videozeile wird ermittelt
  '                durch v_planes (bit je Pixel) geteilt und
  '                mit 8 multipliziert (dieses umstndliche Verfahren
  '                ist notwendig um Overscan-kompatibel zu sein). left& ist
  '                die Videozeilenbreite in Pixeln abzglich width&.
  ' right&         wird auf 0 gesetzt (dieser 2. Parameter ist scheinbar
  '                ziemlich berflssig?).
  '                left&+width&+right& mu = Videozeilenbreite in Pixel sein.
  ' scrres&        GETREZ-Rckgabewert (0,1 oder 2), entspricht sshiftmd.
  ' dstres&        wird ber Bit 2 von SETPRT ermittelt.
  ' colpal%        ber das Farbpalettenregister 0 ($FF8240).
  ' type&          das Verfahren der XBIOS-Hardcopy-Routine wird nachempfunden.
  ' port&          Bit 4 aus SETPRT.
  ' masks%         0 wrde grundstzlich auch reichen, jedoch enthlt das XBIOS
  '                einen Fehler und gibt den rechten Rand nicht immer voll-
  '                stndig aus. Deshalb verwendet man eine eigene Kopie der
  '                masks-Tabelle (vgl. ST-Computer 4/90, S. 94ff).
  '
RETURN
' -----------------
'
PROCEDURE prtblk(blkprt%,offset&,width&,height&,left&,right&,scrres&,dstres&,colpal%,type&,port&,masks%)
  ' Aufruf der entsprechenden XBIOS-Routine prtblk()
  ' vgl. ST-Computer 4/90, S.95
  REM Normale Hardcopy wre z.B.:
  REM prtblk(LPEEK(&H44E),0,640,400,0,0,PEEK(&H44C),1,&HFF8240,3,0,0)
  '
  ' LOCAL par% ! entfllt zum Speicherplatz sparen
  INLINE par%,30
  LONG{par%}=blkprt%        ! Startadresse = _v_bas_ad + x,y-Offset
  WORD{par%+4}=offset&      ! 0 bis 7 Pixel links ausblenden
  WORD{par%+6}=width&       ! Breite
  WORD{par%+8}=height&      ! Hhe
  WORD{par%+10}=left&       ! ???? linker Rand in Pixeln (geht nicht)
  WORD{par%+12}=right&      ! ???? rechter Rand in Pixeln (dito)
  '                         ! [width+left+right = Bildschirmbreite in Pixeln]
  WORD{par%+14}=scrres&     ! _sshiftmod
  WORD{par%+16}=dstres&     ! Druckerauflsung in Punkten
  LONG{par%+18}=colpal%     ! Farbpalette (aus Videoregister)
  WORD{par%+22}=type&       ! Druckertyp (z.B. Epson SW Matrix=3)
  WORD{par%+24}=port&       ! 0=parallel  1=seriell
  LONG{par%+26}=masks%      ! Graustufenmaske
  '
  SDPOKE &H4EE,1            ! _dmpflg setzen
  ~XBIOS(36,L:par%)         ! PRTBLK
  ' Der Rckgabewert ist meistens -65536, also $FFFF0000,
  ' Lt das auf einen unkorrekten Abbruch der Funktion schlieen?
  ' Ein Rckgabewert von -1 bedeutet fehlerhafte Parameter.
  ' Ein Rckgabewert von 0 wird erzeugt, wenn der Ausschnitt als Breite
  ' UND Hhe 0 hat. Nur Hhe=0 gibt -65536, nur Breite=0 gibt -1.
  SDPOKE &H4EE,-1           ! scrdmp-flag rcksetzen
  '
RETURN
'
