Alle, die sich mit Krieg der Kerne (siehe auch [1]) beschäftigen, sollten einmal unser Programm »Cat Can« (Listing 2) ausprobieren. Denn trotz seines einfachen Prinzips ist es fast nicht zu besiegen. Cat Can stoppt gegnerische Programme, indem es deren Rechenzeit für sinnlose Aktionen verschwendet. Split-Befehle reduzieren die Rechenzeit der noch intakten gegnerischen Programme drastisch und legen sie im Idealfall völlig lahm. Sobald der Feind auf diese Weise gestoppt ist, zerstört Cat Can die letzten Gegner mit Datenbomben.
Beachten Sie beim Austesten, daß die Größe des Speicherrings durch acht teilbar sein muß. Wir verwendeten beispielsweise 2048 Speicherzellen. An dieser Stelle sei auch auf einen Fehler in dem Programm »Corewars« hingewiesen: Der letzte »JMN«-Befehl dient dazu, Cat Can sich nicht selbst umbringen zu lassen. Da jedoch Corewars die indirekte Adressierung mit pre-dekrement falsch bearbeitet, funktioniert diese Methode nicht. Denn sobald ein Überlauf stattfindet, setzt Corewars die Adresse nicht auf Null zurück, sondern erniedrigt sie weiter. Derselbe Fehler findet sich auch bei der »DJN«-Anweisung. Damit ist Cat Can unter »Corewars« nur bedingt lauffähig. Mit »Krieg der Kerne« funktioniert es dagegen problemlos.
(Alexander Kirchner/ba)
[1] »Duell im Computer«, ST-Magazin 1/90, Seite 58 f.
Die Menüleiste des GEM ist sehr komfortabel. Denn statt die Befehle mühselig einzutippen oder über schwer nachzuvollziehbare Tastaturkürzel aufzurufen, fahren Sie einfach mit der Maus in die Menüleiste und wählen den gewünschten Menüpunkt aus. Diese Art Menüs heißt Pull-Down-Menüs (zu deutsch etwa »Klappmenüs«). Eine weitere, noch komfortablere Art stellt das Pop-Up-Menü dar. Dieses erscheint auf Mausknopfdruck auf dem Bildschirm nahe beim Cursor. Der Vorteil liegt auf der Hand: Das lästige Anfahren des Menüs entfällt, da das Pop-Up-Menü beim Mauscursor erscheint. Leider unterstützt das AES keine Pop-Up-Menüs. Dazu bedarf es einer kleinen Routine, die Sie in Listing 1 Finden. Wir haben sie der besseren Verständlichkeit wegen in GFA-Basic 3.0 formuliert.
In den Programmzeilen 1 bis 9 demonstrieren wir den Aufruf der Pop-Up-Prozedur »menu«, die Sie ab Zeile 12 finden, »menu« benötigt vier Parameter: Einen Zeiger auf die Rückgabevariable (*num), in der »menu« am Ende die Nummer des ausgewählten Menüpunkts bzw. den Wert -1 (kein ausgewählter Menüpunkt) speichert. Als zweiten Parameter benötigt »menu« ein Stringarray, in dem die Menüpunkte bezeichnet sind (siehe Programmzeilen drei bis acht). Die letzten beiden Parameter geben die X- und Y-Koordinate der linken oberen Ecke des Pop-Up-Menüs an. Es liegt also an Ihnen, wo das Menü erscheint. Sinnvoll sind z. B. die X- und Y-Koordinate der Maus als Bezugspunkt. (Christoph Falk/ba)
.n4
DIM a$(100)
a$(1)="Menu"
a$(2)="Menu"
a$(3)="Menu"
a$(4)="Menu"
a$(5)=MMenu"
a$(6)="Menu"
menu(*num,*a$(),10,50)
'
'
PROCEDURE menu(nura,lp,x,y)
LOCAL lang,a,b,n,ly,lx.bild$
DIM menu$(100)
SWAP *lp,menu$()
n=1
REPEAT
INC n
UNTIL menu$(n)=""
DEC n
GRAPHMODE 1
b=-1
lang=0
ly=n*16
FOR i=1 TO n
IF LEN(menu$(i))>lang THEN
lang=LEN(menuS(i))
ENDIF
NEXT i
lx=(lang+2)*8
IF (x+lx)<635 AND (y+ly)<395 and x>5 AND y>5
fy=INT(ly/n)
DEFFILL 0,1,1
GET x-4.y-9,x+lx+3,y+ly+4,bild$
PBOX x-4,y-9,x+lx+3,y+ly+2
BOX x-4,y-5,x+lx+3,y+y+2
BOX x-1,y-2,x+lx,y+ly-1
PBOX x-4,y-9,x+lx+3,y-2
BOX x-4,y-9,x+lx+3,y-2
BOX x-2,y-6,x+lx+2,y-5
FOR s=1 TO n
TEXT x+6,y+s*16-4,menu$(s)
NEXT s
'
GRAPHMODE 3
DEFFILL 1,1,1
REPEAT
IF FN in(x,y+9,lx,ly-l4)=1
yk=MOUSEY
a=INT((yk-y)/fy)*fy
IF b<>a
IF b>=0 AND b<n*16
DEFFILL 0,1,1
PBOX x-3,b+y-1,x+lx+2,y+b+16
ENDIF
DEFFILL 1,1,1
PBOX x-3,a+y-1,x+lx+2,y+a+l6
b=a
ENDIF
ENDIF
UNTIL MOUSEK=1
IF FN in(x,y,lx,ly)=l
*num=a/l6+1
ELSE
*num=-1
ENDIF
'
PUT x-4,y-9,bild$
ELSE
*num=-1
ENDIF
SWAP *lp,menu$()
ERASE menu$()
DEFFN in{x,y,lx,ly)=ABS(MOUSEX>x AND MOUSEY>y AND MOUSEX<(x+lx) AND MOUSEY<(y+ly))
RETURN
'
' Pop-Up Menü
'
' Geschrieben von FALK CHRISTOPH
'
' 15.11.1989
'
Listing 1. Stellen auch Sie komfortable Pop-Up-Menüs unter GFA-Basic 3.0 dar
Turbo-C ist sicherlich eine der mächtigsten Programmiersprachen für den ST. Die Bibliotheken sind schnell und lassen im Funktionsumfang fast keine Wünsche mehr offen. Besonders die Spieleprogrammierer vermissen aber eine Routine zur unkomplizierten Joystickabfrage. Mittlerweile gibt es zwar eine Vielzahl von Vorschlägen zur Abfrage des Joysticks, aber entweder sind diese Routinen zu lang oder zu unhandlich. Um diesen Mißstand zu beseitigen, stellen wir eine kurze, universelle Joystickabfrage in Turbo-C und Assembler vor.
Der Kern, die Assembler-Routine (Listing 4), speichern Sie unter dem Namen JOYSTICK.S. Die Headerdatei (Listing 2) sollten Sie JOYSTICK.H benennen. Das C-Programm im Listing 3 demonstriert den Einsatz der Joystickroutinen. In Listing 4 finden Sie eine vorgefertigte Projektdatei, die ein ablauffertiges Programm erzeugt.
Beachten Sie, daß wir darin das Assembler-Programm mit ».S« aufgenommen haben. Damit geben wir Turbo-C an, JOYSTICK.S mit dem MAS.TTP zu assemblieren. Besitzer eines anderen Assemblers sollten die Assembler-Routine separat assemblieren und eine DRI-Objektdatei erzeugen. Um diese in die Projektdatei einzubinden, ersetzen Sie einfach das ».S« durch ».O«.
Die Joystick-Abfrage schalten Sie mit »j_on()« ein. Von nun an werden Sie von den beiden globalen Variablen »joyst1« und »joyst2« über den Status der Joysticks in Port 1 und 2 informiert. Jede Bewegung verändert den Wert der Variablen. Ein erneuter Aufruf von »j_on()« ist nicht nötig. Um die Joystick-Abfrage wieder abzuschalten, rufen Sie »j_off()« auf.
Die Werte, die die Variablen »joyst1« und »joyst2« annehmen können, finden Sie in der Textbox.
(Ulrich Eckartz/ba)
Diese Werte nehmen die beiden Variablen »joyst1« und »joyst2« an. Kombinationen sind möglich:
oben | ||||
5 | 1 | 9 | ||
links | 4 | 0 | 8 | rechts |
6 | 2 | 10 | ||
unten | ||||
Fire + 128 |
Bilder sagen oft mehr als tausend Worte. Und Programme, die sich der Bildersprache bedienen, sind doppelt so attraktiv. Doch dabei stellt sich vielen Programmierern ein Problem in den Weg: Wie erzeugt, lädt, verwaltet und zeigt man Bilder? In Listing 3 finden Sie drei Prozeduren für Omikron-Basic, die Ihnen diese Last abnehmen.
Die Prozedur »Bild_Speichern« (Programmzeile 49 ff.) erlaubt Ihnen, einen beliebigen Bildschirmausschnitt zu speichern. Dazu übergeben Sie fünf Parameter: den Bildnamen, die X- und die Y-Koordinate des linken oberen Ecks sowie die Breite und Höhe des Ausschnitts. Um den kompletten Bildschirm im monochromen Modus zu speichern, geben Sie beispielsweise die Parameter »"HIRES ",0,0,640,400« an. In diesem Beispiel sind die beiden Koordinaten x und y Null, die Breite des Ausschnitts beträgt 640 und die Höhe 400 Pixel.
Um ein Bild zu laden, rufen Sie die Prozedur »Bild_Laden« auf, die Sie ab Programmzeile 57 finden. Sie verlangt zwei Parameter: den Bildnamen und die Bildnummer. Die Bildnummer ist eine Art ID, mit dessen Hilfe Sie später erneut auf das Bild zurückgreifen können.
Ein geladenes Bild zeigen Sie mit der letzten Prozedur »Bild_Zeigen« an. Hierzu übergeben Sie die X- und Y-Koordinate der oberen linken Ecke, den Zeichenmodus (siehe Handbuch) und die Bildnummer. Er eignet sich besonders gut, da er aus einem Bildschirmausschnitt einen zusammenhängenden Block mit einem Header (Breite und Höhe) macht.
Die Prozeduren bedienen sich des »BITBLT«-Befehls, um Bildausschnitte für das Speichern vorzubereiten und darzustellen.
Mit den Befehlen »BSAVE« und »BLOAD« speichern und laden die Prozeduren den BITBLT-Block. Ein Anwendungsbeispiel der drei Prozeduren finden Sie in den Zeilen 0 bis 43.
(Peter Kraiczy/ba)
; CAT CAN
;
; Written by A. Kirchner with help from J. Tenzer
; and W. Rohmann
;
start MOV grab, @dest
MOV prog, <dest
SUB #7, dest
JMN start, dest
SUB #4, dest
kill MOV dest, <dest
JMN kill, dest
prog SPL 0
grab JMP -1
deat DAT -16
Listing 2. Ein fast unbesiegbares Kampfprogramm nach den Regeln von »Krieg der Kerne
0 PRINT CHR$(27)+"f"
1 CLIP 0,0,639,399
2 REPEAT
3 MODE = 1
4 CLS
5 FOR A= 1 TO 30
6 X= RND(640)
7 Y= RND(400)
8 Radius= RND(50)*20
9 Stil= RND(1)*2
10 Index= RND(22)
11 FILL STYLE= Stil, Index
12 PCIRCLE X,Y,Radius
13 NEXT A
14 TEXT 200,200,"Bitte Ausschnitt wählen..."
15 MODE= 3
16 MOUSEON
17 REPEAT
18 Maus_X= MOUSEX
19 Maus_Y= MOUSEY
20 UNTIL MOUSEBUT= 1
21 MOUSEOFF
22 REPEAT
23 Hoehe= ABS(Maus_Y-MOUSEY)
24 Breite= ABS(Maus_X-MOUSEX)
25 BOX Maus_X,Maus_Y,Breite.Hoehe
26 BOX Maus_X,Maus_Y,Breite,Hoehe
27 UNTIL MOUSE8UT= 0
28 MODE= 1
29 MOUSEON
30 FORM_ALERT(2,"[3][ Bitte Diskette elnlegen. | Ich speichere den Ausschnitt | Jetzt ab. ][ OK | ABBRUCH ]",Button)
31 MOUSEOFF
32 IF Button= 2 THEN
33 EXIT TO Ende
34 ENDIF
35 Bild_Speichern("Bild",Maus_X,Maus_Y,Breite,Hoehe)
36 CLS
37 PRINT @(11,3);"Ich lade Jetzt den abgespeicherten Ausschnitt auf die Position (0.0)"
38 WAIT 4
39 CLS
40 Bild_Laden("Bild",1)
41 Bild_Zeigen(0,0,3,1)
42 REPEAT UNTIL MOUSEBUT
43 UNTIL 0
44 '
45 -Ende
46 CLS
47 END
48 '
49 DEF PROC Bild_Speichern(File_Name$,X,Y,Breite,Hoehe)
50 LOCAL Adresse,Speicher
51 Speicher= (Breite*15)/16*Hoehe*2+6
52 Adresse= MEMORY(Speicher)
53 BITBLT X,Y,Breite,Hoehe TO Adresse
54 BSAVE File_Name$+".BLD",Adresse,Speicher
55 RETURN
56 '
57 DEF PROC Bild_Laden(File_Name$,Bild_Nummer)
58 LOCAL Bild_Laden_Flag
59 IF Bild_Laden_Flag= 0 THEN
60 DIM Adresse(10)
61 Bild_Laden_Flag= 1
62 ENDIF
63 File_Name$= File_Name$+".BLD"
64 GEMDOS(Dta_Buffer,$2f)
65 File_Name= LPEEK(SEGPTR+28)+LPEEK(VARPTR(File_Name$))
66 GEMDOS(.$4e,HIGH(File_Name),LOW(File_Name),$3f)
67 Datei_Laenge= LPEHC(DtaBuffer-26)
68 Adresse(Bild_Nummer)= MEMORY(Datei_Laenge)
69 BLOAD File_Name$,Adresse(Bild_Nummer)
70 RETURN
71 '
72 DEF PROC Bild_Zeigen(X,Y,Modus,Bild_Nummer)
73 Breite= WPEEK(Adresse(Bild_Nummer)+2)
74 Hoehe= WPEEK(Adresse(Bild_Nummer)+4)
75 BITBLT Adresse(Bild_Nummer) TO X,Y,Breite,Hoehe,Modus
76 RETURN
Listing 3. Drei Prozeduren und ein Anwendungsbeispiel zur komfortablen Blldschlrmverwaltung unter Omikron-Basic
xdef myjoy
xref joyst1,joyst2
text ; Für DEVPAC 2.0: section text
myjoy: movem.l a0-a1,-(a7)
addq.l #1,a0
move.b (a0)+,joyst1
move.b (a0),joyst2
movea.l (a7)+,a0-a1
rts
Listing 4. Der Kern der Joystickabfrage Ist Assembler. Nennen Sie diese Datei JOYSTICKS.
/* Variablendef. */
long oldjoy ;
char code = 0x14 ;
char mausan[] = { 0x15. 0x8 );
unsigned char joyst1, joyst2;
KBDVBASE *kvb;
/* Prototypen */
extern void myjoy(void);
void j_on(void);
void j_off(void);
/* Joystick an */
void j_on(void)
(
kvb = Kbdvbase() ;
oldjoy = (long)kvb->kb_joyvec: /* Alte Routine sichern */
kvb->kb_joyvec = myjoy; /* Neue setzen */
Ikbdws(0, &code);/* An Tastaturprozessor: Joysticks an */
}
/* Joystick aus */
void jo_ff(void)
{
Ikbdws(1, mausan); /* Joysticks aus und Maus an */
kvb->kb_joyvec = (void *)oldjoy; /* Alte Routine zurück */
}
Listing 5. Um In den Genuß unserer komfortablen Joystickabfrage zu kommen, binden Sie diese Headerdatei In Ihren C-Quelltext ein
#include <stdio.h>
#include <tos.h>
#include <joystick.h>
void main(void)
{
j_on(); /* Joystickroutine elnschalten */
while (!Bconstat(2)) /* ...bis Taste gedrückt wird */
printf("%d %d\n",joyst1, joyst2) ;
j_off(); /* Joystickroutine auaachalten */
}
Listing 6. Ein Anwendungsbelsplel für die Joystickabfrage In Turbo-C
; PRJ-Datei JOYSTICK.PRJ:
*; name of executable program is topmost window
= ; list of modules follows...
TCSTART.O ; startup code
JOYSTICK.S
* ; compile topmost window
TCFLTLIB.LIB
TCSTDLIB.LIB
TCEXTLIB.LIB
TCTOSLIB.LIB
Listing 7. Mit dieser Projektdatel erzeugen Sie ein ablauftertiges Programm aus den Listings 4 bis 6