ST-Ecke: Heute schon gewrapt? Die Maus kommt von allen Seiten

Zugegeben, die Maus hat es uns angetan. Aber ein solch liebes Tierchen, das unseren ATARI von einigen anderen Rechnern unterscheidet, sollte man auch nicht unbeachtet lassen, oder? Trotzdem werden wir nicht einfach eine normale Mausroutine veröffentlichen, sondern wir haben uns etwas Besonderes ausgedacht. Was halten Sie von einer Maus, die bei Verlassen des Bildschirmrandes einfach an der gegenüberliegenden Seite wieder zum Vorschein kommt und nicht einfach am Rand stehenbleibt? Dieser ‘Spielerei’ konnten wir uns nicht entziehen, also haben wir versucht, sie zu verwirklichen.

AES und VDI sind auch dabei

Immer öfter werden Tips und Tricks veröffentlicht, wie man die Maus an eine bestimmte Position setzt. So können Sie dies zum Beispiel über die weniger bekannte Routine vsm_locator() des VDI erreichen. In Listing 1 finden Sie ein kleines Beispiel, welches wir schon einmal in den Leserbriefen der ST-Computer 11/88 veröffentlichten. Auch AES läßt ein Setzen der Maus indirekt über die Routine appl_tplay() zu, was wir auch schon in einer der letzten ST-Ecken demonstriert haben. Aber wie es nun einmal im Leben so ist, sind diese beiden Routinen nicht des Rätsels Lösung. Wollen wir den Effekt des Randsprungs unserer Maus nur in unserem eigenen Programm verwenden, so können wir natürlich diese Routinen benutzen, da wir hier die volle Kontrolle über die Maus besitzen. Soll die Maus aber immer über den Rand hinausspringen, so muß die Routine im Interrupt verankert werden. Es hat sich wahrscheinlich herumgesprochen, daß GEM-Routinen leider nicht wiedereintrittsfähig (auf neudeutsch re-entrant) sind. Dies bedeutet, daß sie gleichzeitig nur von einem Prozeß benutzt werden dürfen. Aber wer sagt uns denn, daß zum Zeitpunkt des Interrupts nicht gerade irgendein Programm schon in dieser Routine steckt? Schlimmer noch: es könnte sein, daß der momentane Interrupt von einem weiteren unterbrochen wird, der auch diese Routine benutzen möchte. Das heißt, es muß nach einer anderen Möglichkeit gesucht werden.

Päckchen für Päckchen

Eine Überlegung bezüglich der Maussteuerung bringt uns auf den Gedanken, nach der Herkunft der Mausbewegung zu fragen. Wird die (beim ATARI graue) Maus bewegt, so bemerkt dies der Tastaturprozessor, in dem er die Flanken der mausintemen Lichtschrankenpegel auswertet. Alle Meldungen des Tastaturprozessors führen zu einem Interrupt und führen über den Vektor ikbdsys, der in einer Vektortabelle zu finden ist, deren Adresse man von der XBIOS-Routine Kbdvbase() zurückgeliefert bekommt - ikbdsys ist der neunte Vektor dieser Tabelle. Hat man den Tastaturprozessor in den entsprechenden Mausmodus geschaltet. was beim Starten des ST getan wurde, so schickt er. sofern die Maus bewegt (oder eine Maustaste betätigt) wird, fleißig relative Mauskoordinaten.

Da der Prozessor nicht nur Informationen über die Maus meldet, gibt es eine Möglichkeit, diese Pakete zu unterscheiden. Ein Paket des Tastaturprozessors trägt einen ein Byte großen Header (Kopf), an dem die folgenden Daten erkennbar sind. In unserem Fall liegt der Wert des Headers zwischen $f8 bis $fb. Die Variation des Headers ist darin begründet, daß sich in ihm zusätzlich eine Information über den Zustand der Maustasten befindet. Das Bit 0 zeigt an, ob die linke und das Bit 1, ob die rechte Maustaste gedrückt worden ist. Darauf folgen, in dieser Reihenfolge, jeweils ein Byte für die relative Bewegung der Maus in X- und in Y-Richtung. Da für die Bewegung nur ein Byte reserviert wurde, kann sich die relative Bewegung auch nur im Bereich von -128 bis 127 befinden. Sollten größere Bewegungen verursacht worden sein, schickt der Tastaturprozessor mehrere Pakete hintereinander ab.

Unterbrechung

Wie oben schon angedeutet, löst der Tastaturprozessor ein Interrupt aus, der über den Vektor ikbdsys führt, wobei diese Routine aufgrund der unterschiedlichen Header wieder in entsprechende Vektoren der Maus-, Joystick- und Uhrzeit-Verarbeitung verzweigt. Auch diese vier Vektoren sind in der schon angesprochenen Vektortabelle zufinden. Der für uns interessante Mausvektor mousevec ist der fünfte in der Reihe. Wie schon von der Quick-Mouse bekannt, steht die Adresse, an der das nun als Mauspaket identifizierte Tastaturprozessorpaket zu finden ist, im Register A0.

#define WORD int

WORD work_in[], work_out[], vdi_handle;
WORD gl_wchar,gl_hchar,gl_wbox,gl_hbox;

main()
{
    WORD i; 
    appl_init();
    for(i=0;i<10;work_in[i++]=1); 
        work_in[10]=2; 
    vdi_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox); 
    v_opnvwk(work_in,&vdi_handle,work_out);
            /* Maus in Samplemode schalten */ 
    vsin_mode(vdi_handle, 1, 2);
    v_hide_c(vdi_handle);
    Cconws("\33ENach Tastendruck wird die Maus auf Position0,0,gesetzt\n\r"); 
    v_show_c(vdi_handle); 
    getkey();
            /* Setze Maus */ 
    vsm_locator(vdi_handle, 0, 0, &dummy, &dummy, &dummy); 
    v_hide_c(vdi_handle);
    Cconws("\rEnde (Taste)\n\r"); 
    v_show_c(vdi_handle); 
    getkey(); 
    appl_exit();
}

Listing 1: MOUSESET.C

Das Prinzip der WRAP-Mouse

Prinzipiell ist das Verfahren recht einfach: Wir zählen intern die Mauskoordinaten mit, und falls die Maus am Rand (beispielsweise 640) angekommen ist, setzen wir sie auf die Koordinaten des Randes gegenüber (also 0). Dabei werden drei Probleme aufgeworfen: Erstens schickt der Tastaturprozessor relative Koordinaten, zweitens müssen wir uns am Anfang die aktuellen Koordinaten der Maus ‘besorgen’, und drittens müssen wir die Maus neu setzen.

Problem 1: Das Mitzählen

Dieses Problem ist an sich sehr einfach: Haben wir erst einmal die Anfangskoordinaten, so addieren wir brav die relativen Mauskoordinaten auf unsere Absolutkoordinaten. Die Sache hat aber einen Haken. Angenommen, wir melden uns später an als eine eventuell vorher schon geladene Quickmouse, so ist diese Quickmouse hinter uns geschaltet, und wir bekommen die von ihr veränderten (also verdoppelten) Koordinaten nicht mit. Eine Lösung gibt es direkt nicht. Deshalb ist in der WRAP-Mouse auch eine QUICK-Mouse integriert, was praktisch keinen Aufwand bedeutete. Dadurch brauchen Sie keine Quickmouse mehr zu laden. Zu der Quick-Mouse wird später noch eine Kleinigkeit erzählt.

Problem 2: Die Anfangskoordinaten

Auch dieses Problem läßt sich relativ einfach lösen. In der letzten Ausgabe der ST-Ecke brauchten wir die Anfangskoordinaten für die Echtzeitlupe, was wir durch den Aufruf der AES-Routine graf_mkstate() verwirklichten. Theoretisch wäre auch ein Aufruf der VDI-Funktion vq_mouse() möglich, aber dies würde eine Initialisierung des GEM voraussetzen, was hier einmal bewußt vermieden werden soll- es geht auch anders. Nebenbei, ein Aufruf einer GEM-Funktion ist an dieser Stelle übrigens ohne weiteres möglich, da er nur am Anfang (in der Initialisierung) vorgenommen wird und dadurch nicht in einem Interrupt vorkommt.

Die aktuellen Koordinaten bekommt man über Adressen, die inzwischen von ATARI als unveränderlich bekannt- und damit freigegeben wurden. Sicherlich werden Sie wissen, daß der ATARI interne GRAFIK-Routinen auf unterster Ebene, die sogenannten LINE_A-Routinen, zur Verfügung stellt. Um diese Routinen anzusprechen, führt man den LINEA-Init-Befehl durch, der einen Zeiger auf eine Anzahl von Variablen zurückliefert. Diese Variablen sind seit Anbeginn des ST bekannt. Weniger bekannt und damals auch nicht offiziell freigegeben waren Variablen, die VOR dieser Adresse lagen. Diese Variablen mit negativem Offset zur Startadresse beinhalten auch die aktuellen Koordinaten der Maus. Der negative Offset der X-Koordinate liegt bei -$ 158, die der Y-Koordinate bei -$ 156 bezogen auf die von LINE_A-Init zurückgelieferte Adresse. Auf die Gesamtheit der negativen Line-A-Variablen werde ich in einer der späteren ST-Ecken einmal gesondert eingehen, da Sie sonst hier den Rahmen sprengen würden (Wer nicht warten möchte, sei auf das Dokument ‘S.A.L.A.D.‘ von ATARI oder auf das PROFIBUCH von SYBEX verwiesen).

Nachdem wir uns die Anfangskoordinaten geholt haben, zählen wir intern selbst weiter.

Problem 3: Das Setzen der Maus

Dies ist sicherlich das Schwierigste aller Probleme, da wir, wie schon erwähnt, nicht aus dem Interrupt heraus auf die GEM-Routinen zugreifen dürfen. Deshalb emulieren wir einfach den Tastaturprozessor und schicken der offiziellen Mausroutine, die dann die Maus verwaltet, Pakete, wie sie sie auch vom Tastaturprozessor bekommen würde! Ist die Maus beispielsweise am unteren Rand angekommen, so schicken wir Pakete, die einer relativen Verschiebung der Maus (in hochauflösender Grafik) um 400 Punkte entsprechen. Das einzige Problem ist dabei, daß in einem Paket eine maximale Verschiebung der Maus um -128 oder +127 Punkte angegeben werden kann. Das bedeutet, daß wir für die Neupositionierung der Maus mehrere Pakete zu schicken haben, übrigens macht das der Tastaturprozessor bei sehr schnellen Mausbewegungen auch. In unserem Programm haben wir die Tastaturpakete schon für jede Richtung vorgefertigt. In der Routine loop werden die Pakete auf den Stack gelegt, dann die Original-Maus-Routine angesprochen, was aufgrund der Notwendigkeit mehrfacher Mauspakete auch mehrfach durch lloop geschieht. Zum Schluß bleiben dann noch ein paar Pixel übrig, da die Teilung von 640 oder 400 durch 127 nicht ohne Rest aufgeht, die am Ende der Mausroutine noch verwertet werden. Das Konzept könnte man auch dahingehend erweitern, daß man eine Routine schreibt, die bei Übergabe der neuen (beliebigen) Koordinaten automatisch die benötigten relativen Koordinaten errechnet und diese an die Mausroutine schickt.

Der Kampf mit der Auflösung

Eine etwas unangenehme Sache sollte auch noch erwähnt werden: Der ST arbeitet (als Erschwernis für jeden Programmierer) leider nicht immer in der gleichen Auflösung, so daß sich die Maximalkoordinaten (welche unsere Rand- und damit Sprungkoordinaten darstellen) auflösungsbedingt verändern. Dazu fragen wir bei der Initialisierung die Auflösung über XBIOS-Getrez() ab und setzen uns dann die Maximalkoordinaten. Die Auflösung merken wir uns aber, denn die können wir ganz besonders gut für die Quick-Mouse benutzen.

Veränderliche Quick-Mouse

Interessanterweise ist die Quick-Mouse zum fast unentbehrlichen Hilfsmittel auf dem ST geworden, eine Tatsache, die wir in diesem Ausmaß nicht geahnt hatten. Es stellte sich aber schnell heraus, daß die Quickmouse in Farbe einfach zu schnell, beziehungsweise ungleich schnell war. Dies liegt daran, daß zum Beispiel die mittlere Auflösung im Vergleich zur hohen Auflösung nur in einer Richtung halbiert wird. Da die Maus aber bei der halbierten Auflösung schon zu schnell war, sollte sie demzufolge nur in der nichthalbierten Achse zum Zuge kommen, was bei der niedrigen Auflösung zu einem völligen Ausgeschaltetsein führt. Eine solche Quick-Mouse ist jetzt in dieser WRAP-Mouse auch integriert. Bewegt man die Maus langsam von einem Punkt zum andern, werden Mauspakete mit kleinen Differenzen geschickt. Bewegt man die Maus schnell, so werden größere Differenzen verpackt. Dies könnte man (als Erweiterung) so ausnutzen, daß die Quick-Mouse erst ab bestimmten Differenzen wirksam wird. Benutzt man mehrere Schwellen, so hat man eine dynamische Maus, die mit einer kleinen aber schnellen Mausbewegung große Entfernungen zurücklegen kann, aber bei langsamen Bewegungen immer noch pixelgenau zu positionieren ist. Übrigens, die meisten Zeichenprogramme haben eigene Mausroutinen, so daß Sie keine Angst haben müssen, jetzt nur noch jeden zweiten Pixel zeichnen zu können. Abgesehen davon können Sie unsere neue WRAP/Quick-Mouse auch...

Ein- und Ausschalten

Interrupt-Routinen wie die unserer Maus müssen resident im Speicher gehalten werden, das ist bekannt. Eine sehr einfache Realisierung ist, das gesamte Programm als Accessory zu definieren, da diese nie enden (jedenfalls solange, bis der Rechner auf einen Reset geht). Die einfache Anwählbarkeit der Accessories über die Menüleiste gibt dies uns eine zusätzliche Möglichkeit, Einstellungen zu realisieren. Unsere WRAP-Mouse haben wir als Accessory angemeldet. Sie bringt bei Anwählen eine Alert-Box auf den Bildschirm, die uns ein Selektieren von Einstellungen ermöglicht - leider ist die Anzahl der Knöpfe in einer solchen Box auf drei beschränkt. Hier kann man einstellen, ob die WRAP- oder QUICK-Mouse eingeschaltet werden sollen. Dies wird in zwei Bytes vermerkt, auf die unsere Mausroutine zugreift. Sind diese Bytes gesetzt (ungleich Null), gilt die entsprechende Option als eingeschaltet. Dieses Byte-Flag könnte bei der Quick-Mouse als Schwelle einer einfachen Dynamik genutzt werden, welche wiederum über eine Box eingebbar ist...wie immer sind der Phantasie keine Grenzen gesetzt.

SH

/***********************************************/
/*                                             */
/*                WRAP-MOUSE                   */
/*           ( mit Quick-Mouse )               */
/*                                             */
/*  Programmierung: Stefan Höhn                */
/*  Idee:           Alex Beller & Stefan Höhn  */
/*    Compiler:         Megamax C              */
/*                                             */
/***********************************************/

#include <gemdefs.h>    /* GEM-Definitionen */ 
#include <osbind.h>     /* Definitionen des OS */

#define ACC             /* Als ACC compilieren */

#define LA_INIT 0xA000  /* Line-A-Initialisierung */ 
#define GETREZ  4       /* Xbios: Get-Resolution */
#define SUPEREXEC 0x26  /* Supervisor-Eintritt */ 
#define XBIOS 14        /* TRAP-Nummer des XBIOS */

static mouse_status();  /* F.Zugriff auf Flags */

extern gl_apid;         /* Applikations-ID */

/***********************************************/
/* Diese Routine initialisiert nur den         */
/* Mausvektor und bleibt resident...           */
/***********************************************/

main()
{
    int *zeiger; /* Zeiger auf Flags */
    int msgbuff[8]; /* Ereignis-Puffer */
    int ret; /* Button-Nummer */


    appl_init(); /* Wichtig für AES-Routinen */

    menu_register(gl_apid," Crazy-Mouse");
                        /* anmelden */

    wrap_mouse(0); /* Maus einbinden */

    zeiger = (int*) mouse_status; /* Zeigertyp wandeln */

    #ifdef ACC
        while(1) /* Endlos währt am längsten...*/
        {
            evnt_mesag(msgbuff); /* Ereignis erwarten */ 
            if (msgbuff[0]==AC_OPEN)
            {
                ret=form_alert(1,"[3][QUICK- & WRAP-MOUSE (c) S. Höhn][Beides aus|Quick ein| Wrap ein]");
                if (ret==1)
                    *zeiger=0;          /* Beides löschen */
                else if (ret==2)
                    *zeiger|=0xff00;    /* Quickmouse an */ 
                else
                    *zeiger|=0xff;      /* Wrapmouse an */
            }
        }
    #endif

    #ifndef ACC             /* zum Ausprobieren */
        gemdos(7);          /* Tastendruck */
        wrap_mouse(1);      /* Maus ausklinken */
    #endif

}

/***********************************************/
/*                                             */
/* Routine zum Einbinden der WRAP/QUICK-Mouse  */ 
/* arg: =0 Einhängen der neuen Routine         */
/* arg: =1 Wiedereinbinden des alten Vektors   */
/*      (wichtig für nicht-residente Programme */
/*                                             */
/***********************************************/
wrap_mouse(arg) 
char arg;
{
    asm{
    movem.l A0-A1/D0-D2,-(A7)

    dc.w LA_INIT            /* Linea_init */
    lea mouse_x,A1          /* Adresse Maus-X/Y */
    move.l -0x25a(A0),(A1)  /* Koord. speichern */

    move #34,-(A7)          /* Funktion Kbdvbase() */
    trap #XBIOS             /* Xbios-Aufruf */
    addq.l #2,A7            /* Stack korrigieren */
    lea kbdv_addr,A1        /* Adr. für Vektortab.*/
    move.l D0,(A1)          /* Adr.der Vektortab.*/

    lea mouse_on,A0         /* Adresse: Einbinde-Routine */ 
    tst.b arg(A6)           /* Arg = 0? */
    beq do_mouse            /* Ja */

    lea  mouse_off,A0        /* Adresse: Ausblend-Routine */

do_mouse:
    pea     (A0)                /* Adresse auf Stack */
    move.w  #SUPEREXEC,-(A7)    /* Supervisor */
    trap    #XBIOS              /* Xbios-Einsprung */
    addq.l  #6,A7               /* Stack korrigieren */
    jmp     ende                /* Bis dann... */

mouse_on:
    move.w  #640,D1             /* xmax */
    move.w  #400,D2             /* ymax */

    move.w  #GETREZ,-(A7)       /* Fkt.nummer a.Stack */
    trap    #XBIOS              /* Xbios aufrufen */
    addq.l  #2,A7               /* Stack korrigieren */

    lea     res,A0              /* Auflösung */
    move.w  D0,(A0)             /* merken */

    cmpi.w  #1,D0               /* Auflösung vergl. */
    beq     mid_res             /* 1=Mid-Res */
    bpi     high_res            /* 2=High-Res: Werte schon da */

low_res:                        /* Ans. 0=Low-Res */
    move.w  #320,D1             /* xmax */
mid_res:
    move.w  #200, D2            /* ymax */
high_res:
    lea     x_max,A0            /* Adresse von xmax */
    move.w  D1,(A0)+            /* Xmax speichern */
    move.w  D2,(A0)             /* Ymax speichern */

    movea.l kbdv_addr,A0        /* Adr.Keyboard-Tab.  */
    lea     mouse_vec,A1
    move.l  16(A0),(A1)         /* Alt.Vektor sichern */ 
    lea     new_mouse,A1
    move.l  A1,16(A0)           /* Neuen Vektor setzen */
    rts

mouse_off:
    movea.l kbdv_addr,A0        /* Adr. Keyboard-Tab. */ 
    lea     mouse_vec,A1        /* Adresse d.Vektors */ 
    move.l  (A1),16(A0)         /* Alt. Vektor setzen */
    rts

new_mouse:
    movem.l D0-D4/A1-A4,-(A7)   /* alle Register retten */

    move.b  (A0),D0             /* Code aus Paket holen */
    cmpi.b  #0xf8,D0            /* Mauscode: >=f8 <=fc */
    bmi     end_mouse           /* <f8, kein Mauspaket */

    cmpi.b  #0xfc,D0
    bpi     end_mouse           /* >fc, kein Mauspaket */

    lea     mouse_x,A1          /* Adresse der Mauskoordinaten */

    move.b  1(A0),D0            /* X */ 
    move.b  2(A0),D1            /* Y */

    ext.w   D0 
    ext.w   D1

    lea     xmax,A3
    move.w  (A3)+,D3            /* xmax */ 
    move.w  (A3),D4             /* ymax */

    lea     mouse_status,A3     /* Adresse der Flags */ 
    tst.b   (A3)                /* Quickmouse an ? */
    beq     no_double           /* Nein */
    move.w  res,D2              /* Auflösung holen */
    cmpi.w  #1,D2               /* vergleichen */
    beq     double_mid          /* mittlere Auflösung */
    bmi     no_double           /* low-kein Verdoppeln */

double_high:                    /* Beide Verdoppelen */
    add.w   D1,D1               /* relatives Y-Verdoppeln */ 
double_mid:
    add.w   D0,D0               /* relatives X-Verdoppeln */

    move.b  D0,1(A0)            /* X speichern */
    move.b  D1,2(A0)            /* Y speichern */

no_double:
    add.w   (A1),D0             /* Absolutes_X += Relatives_X */ 
    bpi     MS_1                /* X>=0, weiter */
    moveq   #0,D0

    tst.b   1(A3)               /* Wrap an ? */
    beq     MS_1                /* Nein */

    move.w  D3,D0               /* X<0 -> X=xmax */
    move.w  #4,D2               /* 5 mal 127 = 635 */
    lea     mouse_dx1,A4        /* Mauspaketadresse */
    jsr     loop                /* Schicke Mauskoord. */
    bra     MS_2                /* nächste Abfrage: Y */

MS_1:
    cmp.w   D3,D0               /* X > xmax  ? */
    bmi.s   MS_2                /* X < xmax  */
    move.w  D3,D0               /* Setzen auf xmax */
    tst.b   1(A3)               /* Wrap an ? */
    beq     MS_2                /* Nein */
    move.w  #1,D0               /* X >= xmax -> x=1 */

    move.w  #4,D2               /* 4 mal -127 */
    lea     mouse_dx2,A4        /* Mauspakete */
    jsr     loop                /* Schicke Mauskoordinaten */

MS_2:
    add.w   2(A1),D1            /* Absolutes_Y += Relatives_Y */ 
    bpl     MS_3                /* <0: nächste Abfrage: Y */
    moveq   #0,D1
    tst.b   1(A3)               /* Wrap an ? */
    beq     MS_3                /* Nein */
    move.w  D4,D1               /* Y=ymax */
    move.w  #3,D2               /* 3 mal 127 */
    lea     mouse_dy1,A4        /* Mauspakete */
    jsr     loop                /* Schicke Mauskoordinaten */ 
    bra     next_mouse          /* -> Ende */
MS_3:
    cmp.w   D4,D1               /* Y >ymax ? */
    bmi.s   next_mouse          /* -> Ende */
    move.w  D4,D1
    tst.b   1(A3)               /* Wrap an ? */
    beq     next_mouse          /* Nein */
    move.w  #1,D1               /* Y=1 */
    move.w  #3,D2               /* 3 mal -127 */
    lea     mouse_dy2,A4        /* Mauspakete */
    jsr     loop                /* Schicke Mauskoordinaten */

next_mouse:
    move.w  D0,(A1)             /* Speichere X */
    move.w  D1,2(A1)            /* Speichere Y */

end_mouse:
    movem.l (A7)+,D0-D4/A1-A4   /* Register rückschreiben */ 
    move.l  mouse_vec,-(A7)     /* z.alten Vektor */
    rts                         /* Ciao  */

loop:
    move.l  mouse_vec,A2        /* Mausroutine */
lloop:
    move.l  A4, A0              /* Mauspaketadresse */
    movem.l A0-A3/D0-D2,-(A7)   /* Register speichern */ 
    jsr     (A2)                /* Mausroutine */
    movem.l (A7)+,A0-A3/D0-D2   /* Register wieder holen */
    dbf     D2,lloop            /* Schleife */
    lea     4(A0), A0           /* Zum Schluß den Rest*/
end_loop: 
    rts

mouse_vec:      dc.l 0          /* alter Mausvektor */
kbdv_addr:      dc.1 0          /* Vektor-Tabelle */
mouse x:        dc.w 0          /* absolute Mauskoordinate: X*/ 
mouse_y:        dc.w 0          /* absolute Mauskoordinate: Y*/

mouse_status:   dc.w 0xffff     /* Flag: Maus quick/wrap */
                /* anfangs beides eingeschaltet */ 
res:            dc.w 0          /* Auflösung */

x_max:          dc.w 640        /* Auflösungsabhängiger MAX-Wert */
y_max:          dc.w 400        /* Auflösungsabhängiger MAX-Wert */

mouse_dx1:      dc.w 0xf87f,0   /* dx=127 */
                dc.w 0xf803,0   /* dx=3 */
mouse_dx2:      dc.w 0xf881,0   /* dx=-127 */
                dc.w 0xf8fd,0   /* dx=-3 */
mouse_dy1:      dc.w 0xf800,0x7f00 /* dy=127 */
                dc.w 0xf800,0x1100 /* dy=17 */
mouse_dy2:      dc.w 0xf800,0x8100 /* dy=-127 */
                dc.w 0xf800,0xef00 /* dy=-17 */

ende:
    movem.l     (A7)+,A0-A1/D0-D2
    }
}
exit()      /* wirft echten Exit raus, */
{           /* was 'ne Menge Bytes spart */
}

Listing 2: MOUSE. C



Aus: ST-Computer 02 / 1989, Seite 97

Links

Copyright-Bestimmungen: siehe Über diese Seite