Adventure-Programmiertechnik
Es ist soweit. Im nun folgenden Abschnitt erfahren Sie endlich, wie man sie programmiert: Super-Adventures, wie es sie bis jetzt noch nicht gibt. Sie erhalten alle notwendigen Grundlagen, um professionelle Adventures zu erstellen.
In meinem ersten Adventure-Kurs habe ich bereits ausführlich beschrieben, wie man eine Adventure-Idee aufgreift, diese ausarbeitet, Pläne anfertigt etc. Wir wollen uns deshalb hier gar nicht mehr erst lange mit solchen Grundlagen aufhalten, sondern gleich zur Sache kommen. Auf den nächsten Seiten programmieren wir gemeinsam die ersten Fortsetzungsszenen von Gordon Saga II. An dieser Stelle muß ich auch gleich noch einmal ein paar Worte zur Gordon Saga I verlieren. Ich möchte mich bei allen begeisterten Adventurern bedanken, die im Spiel mit mühevoller Kleinstarbeit meine Telefonnummer herausgefunden und mich dann angerufen haben. Ich erhielt zahlreiche Anrufe aus allen Teilen Deutschlands, Österreichs und der Schweiz. Bedanken möchte ich mich vor allem deshalb, weil ich bisher keinen einzigen bösen Anruf erhielt. Einige teilten mir sogar mit, daß das Spiel Fehler enthält und deshalb nicht lösbar sei. Es stimmt, es sind einige Fehler enthalten, aber ich kann versichern, daß diese Fehler in keinster Weise zur Unlösbarkeit beziehungsweise zum Absturz des Spiels führen: es sind lediglich kleine Logikfehler, wie sie bei der Programmierung eines komplexen Adventures unvermeidbar sind. An dieser Stelle sei auch die »Incredible Four« gegrüßt, die Gordon Saga I geknackt und beim Titelbild das HAPPY-SOFTWARE-Emblem durch UNHAPPY SOFTWARE ersetzt haben (PS: Wenn ich euch erwische, dreh ich euch den Hals um!). »Wo bleibt Gordon Saga, Teil II« haben mich viele gefragt. Die Programmierung von Teil II habe ich kurz vor Abschluß abgebrochen. Dies hat seinen guten Grund: Teil II ist einfach um Längen besser als Teil I in puncto Text, Grafik und Parser. Wenn jemand, der Gordon Saga I kennt, von Gordon Saga II hört, so vergleicht er unwillkürlich den zweiten mit dem ersten Teil – und dies wäre nicht gerade die beste Werbung.
Als kleinen Vorgeschmack möchte ich gemeinsam mit Ihnen nun die ersten Szenen von Gordon Saga II programmieren. Dazu ist notwendig, daß Sie wissen, wie Gordon Saga I ausgeht. Am Spielende treibt der Spieler mit einem Floß auf einem stillen unterirdischen See in einem geheimnisvollen Gebirge. Plötzlich entsteht im See ein riesiger Strudel, der den Spieler samt Floß in die Tiefe reißt – die Pforte zu einer geheimnisvollen Welt hat sich aufgetan ...
Und dies sind die ersten Szenen von Gordon Saga II: Der Spieler wacht in einer Glaskuppel am Grunde des Sees wieder auf. Von der Glaskuppel aus führt ein Tunnel in die Dunkelheit. Durch diesen Tunnel gelangt man in eine Kristallgrotte ...
Den Lageplan für diesen Teil des Spieles zeigt Bild 1.

Wir haben 4 Räume: Glaskuppel, Tunnel, Kristallgrotte und Felsplateau. Außerdem ist bei jedem Raum aufgezählt, welche Objekte sich in ihm befinden. Von Raum 3 gelangt man nicht so ohne weiteres zu Raum 4, was durch die gestrichelte Linie angedeutet ist – man braucht irgendwie das Schwert.
Wie fängt man jetzt an zu programmieren?
Nun, man muß sich erst einmal überlegen, wie man die einzelnen Programmteile – also Basic-Programm, Zeichensatzlader, Grafikbilder, relative Dateien etc. auf einer Disk unterbringt. Am besten, man entscheidet sich, eine Diskette beidseitig zu verwenden.
Auf Seite 1 bringt man das Grundprogramm, den deutschen Zeichensatz, eventuell Maschinenprogramme und Grafikbilder unter.
Das heißt, außer den Grafikbildern kommt auf Seite 1 alles, was einmal in den Rechner geladen wird und dann dort bleibt. Auf Seite 2 kommt die relative Datei, auf der alle Texte, Kommentare und Raumbeschreibungen gespeichert sind. Außerdem wird auf Seite 2 die relative Wortschatzdatei untergebracht. In der Entwicklungsphase eines Adventures eignet sich Parser 4.0 zweifellos am besten – man kann leicht neue Wörter einfügen etc. Erst ganz am Ende, wenn alle Spielszenen fertig programmiert sind – das Adventure also fertig ist -, sollte man endgültig auf Parser 5.0 umrüsten.
Nehmen Sie sich jetzt bitte eine gute Diskette her, die für beidseitiges Bespielen geeignet ist, und formatieren Sie beide Seiten. Dann nehmen Sie die Disk-Utility her und ändern die IDs der Disketten so, daß der ID der ersten Seite »1side«, der der zweiten Seite »2side« lautet. Dies ist notwendig, damit später innerhalb des Programmes festgestellt werden kann, ob die richtige Disk-Seite eingelegt ist. Jetzt brauchen wir den Relativ-Datei-Editor. Mit ihm eröffnen wir auf der 2. Diskseite eine relative Datei mit folgenden Angaben:
Satzlänge 41
Anzahl Sätze 3000
Filename »TEXTE«
Jetzt müssen Sie auf die zweite Diskseite noch die relative Wortschatzdatei überspielen. Dies geht nicht so ohne weiteres, da es nur sehr wenige Kopierprogramme gibt, die relative Files einzeln kopieren können. Sie können jedoch mit dem Editor eine neue Wortschatzdatei anlegen und dann mittels VERSETZEN-Befehl (siehe auch Anleitung zum Editor) die alte Wortschatzdatei in die neu angelegte übertragen. Eine andere Möglichkeit besteht darin, einfach die ganze Diskettenseite, auf der sich die Wortschatzdatei befindet, mit einem Diskettenkopierprogramm auf die zweite Seite unserer jetzigen Arbeitsdiskette zu kopieren und dann mittels Scratch und Validate den Rest zu löschen. Diskseite 2 muß jetzt so aussehen:
0 "gordon saga ii "2side
492 "texte" rel
32 "wortschatz" rel
140 blocks free.
Jetzt können wir mit der Arbeit beginnen.
Der erste Schritt besteht darin, den Wortschatz und die Wörter zu erweitern, die für die aktuelle Spielszene, die sich in der Regel aus einigen Räumen zusammensetzt, benötigt werden. Man sollte nie zu viele Räume auf einmal behandeln.
Wortschatz erweitern
Denken Sie sich immer eine kleine Szene aus, programmieren Sie diese und arbeiten Sie erst dann weiter, wenn diese Szene einwandfrei läuft. Durch dieses Szene-für-Szene-Programmieren hält sich die Fehlersuche in engen Grenzen, und man kann sicher sein, daß das Adventure bei der Fertigstellung nur wenige Logikfehler enthält – da jede Szene für sich ausgiebig getestet wurde. Wie erweitert man den Wortschatz? Ganz einfach. Für unsere jetzige Szene müssen wir den Wortschatz um folgende Objekte ergänzen:
Glaskuppel 1
Sand 2
Tunnel 3
Kristallgrotte 4
Quader 5
Statue 6
Schwert 7
Zettel 8
Amulett 9
Grube 10
Oeffnung 11
Felsplateau 12
Kristalle 13
Der Wortschatz wird ganz einfach erweitert, indem Sie mit dem relativen Datei-Editor die neuen Wörter ans Ende des bisherigen Wortschatzes anhängen (ab Satz Nr. 198) und dann die gesamte Datei neu sortieren. Hängen Sie bitte folgende Sätze an:
198 glaskuppel 3001
199 sand 3002
200 tunnel 3003
201 kristallgrotte 3004
202 quader 3005
203 statue 3006
204 schwert 3007
205 zettel 3008
206 amulett 3009
207 grube 3010
208 oeffnung 3011
209 felsplateau 3012
210 kristalle 3013
Jetzt muß der Wortschatz neu sortiert werden. Beachten Sie bitte, daß mit der Sortierroutine des relativen Datei-Editors nur Dateien sortiert werden können, die nicht mehr als 300 Sätze haben. Übersteigt die Anzahl der Worte im Wortschatz diese Zahl, so müssen Sie zum Sortieren des Wortschatzes den Super-Sorter hernehmen, bei dem kein Limit besteht.
Nachdem der Wortschatz erweitert ist, können wir uns dem Text des Adventures zuwenden. Textadventures zeichnen sich besonders durch lange, beschreibende Texte aus. Nicht umsonst arbeiten viele Softwarehäuser bei der Erstellung ihrer Adventures mit Schriftstellern zusammen. Alleine Adventures schreiben ist langweilig. Auch sind Programmierer meistens keine guten Texter. Vielleicht tun Sie sich hier am besten mit einem Freund zusammen, der gerne schreibt. Zu zweit ein Spiel aushecken macht schließlich auch viel mehr Spaß.
Anschließend finden Sie den Text zu den ersten Szenen von Gordon Saga II. Bitte schreiben Sie ihn in die entsprechenden Sätze der Texte-Datei:
1 Als Sie aus Ihrer Bewußlosigkeit 2 erwachen, finden Sie sich auf einem 3 weichen weißen Sandboden liegend 4 wieder. 5 Augenblicklich erinnern Sie sich an die 6 letzten Ereignisse vor Ihrer 7 Bewußtlosigkeit .. In Ihren Gedanken 8 setzt sich das Abbild der riesigen 9 Seeschlange zusammen, die Sie mit Hilfe 10 einer goldenen Armbrust erlegt hatten. 11 Ihre folgende Erinnerung gilt dem 12 plötzlich aufgekommenen Strudel, durch 13 den Ihr Floß samt Ihnen in die Tiefe 14 gerissen worden war. 15 Obwohl es Ihnen noch immer unbegreiflich 16 ist, wie Sie all dies überleben konnten, 17 machen Sie sich daran, Ihre jetzige 18 Umgebung näher zu untersuchen ..... 19 20 GORDON SAGA II. Die Rückkehr des Helden 21 Ein Abenteuerspiel von Michael Nickles. 22 Parsersystem 4.0 - Copyright 1985 23 Auszug für Kurs im 64er-Sonderheft. * 24 Glaskuppel 25 Sie befinden sich innerhalb einer 26 Glaskuppel am Grunde eines Sees. 27 Außerhalb der Kuppel ist das Wasser so 28 dunkel, daß man nichts erkennen kann. 29 Der weiße Sand am Boden strahlt ein 30 schwaches Licht aus, das die Kuppel 31 erhellt. Ein kleiner Tunnel führt von 32 hier aus hinaus in die endlose 33 Dunkelheit. * 34 Tunnel 35 Sie befinden sich in einem zwei Meter 36 hohen und etwa drei Meter breiten 37 Tunnel. Die Wände sind aus einem Glas 38 angefertigt, das etwas trüber als das 39 Glas, aus dem die Kuppel besteht, ist. 40 Der Tunnel verläuft in nördliche 41 Richtung. Weit entfernt in nördlicher 42 Richtung sehen Sie ein helles Licht. * 43 Kristallgrotte. 44 Dies ist eine riesige Grotte, deren Wände 45 mit Kristallen, die in allen Farben des 46 Lichtspektrums glitzern, besetzt sind. 47 Der Boden besteht aus glatten, strahlend 48 weißen Marmorplatten. Trotz zahlreicher 49 Unebenheiten ähnelt diese Grotte dem 50 Inneren einer Halbkugel mit einem Radius 51 von ca. 100 Metern. Der einzige Ausgang 52 von hier ist ein in südlicher Richtung 53 verlaufender Tunnel. * 54 Felsplateau 55 Dieses Felsplateau außerhalb der Grotte 56 bietet Ihnen eine fantastische Aussicht. 57 Sie blicken über ein weites Land hinweg. 58 das in Dunkelheit gehüllt ist. Am Himmel 59 sehen Sie eine schwarze Scheibe, deren 60 Ränder orangerot leuchten - es scheint, 61 als sei die Dunkelheit durch eine 62 andauernde Sonnenfinsternis bedingt. 63 Etwa 300 Meter unterhalb des Plateaus 64 befindet sich ein Wald mit einer Ihnen 65 unbekannten Flora. 66 All diese eindrucksvollen Anblicke 67 verstärken in Ihnen das Gefühl, daß Sie 68 sich in einer fremden Welt befinden. 69 In der östlichen Gebirgswand ist ein 70 Zugang zu einer Grotte. * 71 Sie graben in dem leuchtenden Sand. * 72 Es ist sinnlos, noch tiefer zu graben. * 73 Nachdem Sie ein etwa 50 cm tiefes Loch 74 in den Sand gegraben haben, finden Sie 75 einen Zettel und ein Amulett. * 76 Im Sandboden ist eine ca. 50 cm tiefe 77 Grube ausgehoben - es scheint so, als ob 78 hier vor kurzem jemand gegraben hat! * 79 Auf dem Zettel steht etwas geschrieben! * 80 "Supermike grüßt Captain Future, 81 Section 8, Pink, Brutallica, Gommel, 82 GCS (ich weiß, daß ihr genau 35 km 83 Luftlinie von mir entfernt wohnt - 84 Paßt bloß auf!!!), und natürlich alle 85 Freunde, RAMBO und alle Girls, die mich 86 besonders gut kennen!!" * 87 Das Amulett ist aus massivem Gold 88 angefertigt, mit schwarzen Edelsteinen 89 besetzt und hängt an einer goldenen 90 Halskette. * 91 Die Grube ist völlig leer. * 92 Die Glaskuppel ist so groß, daß sich 93 etwa 10 ausgewachsene Männer darin 94 aufhalten können. * 95 Der Sand ist sehr grobkörnig und 96 leuchtet seltsamerweise. * 97 Die Kristalle glitzern in allen Farben 98 des Lichtspektrums. * 99 Die Kristalle sind fest in die Wände 100 eingelassen und lassen sich auch mit 101 größten Anstrengungen nicht entfernen. * 102 Auf dem Marmorboden, exakt im Zentrum 103 des Raumes, steht ein goldener Quader, 104 von dem eine ca. 3 Meter hohe Statue 105 emporragt. * 106 Nur wenige Meter von der Statue entfernt 107 steckt ein goldenes Schwert zu etwa 108 einem Drittel seiner Gesamtlänge im 109 Marmorboden. * 110 Das Schwert ist fest im Marmorboden 111 verankert und läßt sich um keinen 112 Millimeter herausziehen. * 113 Die Statue gibt die groben Umrisse eines 114 jungen Kriegers wieder. Er hat lange 115 Haare, ist von athletischer Körperstatur 116 und trägt eine Rüstung. Sie fühlen sich 117 von der Statue in einer seltsamen Art 118 und Weise angezogen. * 119 Als Sie die Statue mit Ihrer rechten 120 Hand berühren, durchfährt augenblicklich 121 eine Lähmung Ihren ganzen Körper und Sie 122 sind nicht mehr in der Lage, Ihren Arm 123 zurückzuziehen. Unmittelbar vor Ihren 124 Augen beginnt die Statue plötzlich ihr 125 Äußeres zu verändern..... 126 Die Lähmung läßt schließlich nach und 127 Sie stürzen benommen zu Boden. 128 Nachdem Sie den Schock überwunden haben, 129 stellen Sie fest, daß nicht nur die 130 Statue ihr Äußeres verändert hat - 131 während die Statue Ihre Form angenommen 132 hat, haben Sie den Körper des jungen 133 Kriegers erhalten, den die Statue noch 134 vor kurzem verkörpert hat. * 135 Die Statue gibt jetzt die Umrisse und 136 Gesichtszüge eines Ihnen wohlvertrauten 137 Menschenkörpers wieder - ein Körper, der 138 noch vor kurzem der ihrige war! * 139 Mit der unglaublichen Kraft, die in 140 Ihrem neuen Körper zu stecken scheint, 141 ziehen Sie das Schwert ohne jegliche 142 Anstrengung aus dem Marmorboden. 143 Kaum, daß Sie es in Ihren Händen halten, 144 beginnt der gesamte Raum um Sie herum 145 leicht zu beben und das Schwert strahlt 146 in gleißendem Licht. 147 Aus dem Nichts ertönt plötzlich eine 148 Ihnen altbekannte Stimme. "In Dir 149 erfüllt sich die alte Prophezeiung! 150 Geh, GORDON, die Macht ist mit Dir!" 151 Als die letzten Worte des Uralten 152 gerade verklingen, tut sich in der 153 westlichen Wand der Grotte eine Öffnung 154 auf und gibt den Ausgang zu einem 155 Felsplateau frei. 156 Sie stehen verwundert da und fragen sich 157 immer wieder, warum gerade Sie der 158 Auserwählte sind und zu welchem Zweck 159 der Uralte Sie in diese fremde Welt 160 geholt hat..... * 161 In der westlichen Wand der Grotte ist 162 eine Öffnung, die den Ausgang zu einem 163 Felsplateau ermöglicht. * 164 die Glaskuppel 165 der Sand 166 der Tunnel 167 die Kristallgrotte 168 der Quader 169 die Statue 170 das Schwert 171 der Zettel 172 das Amulett 173 die Grube 174 die Öffnung 175 das Felsplateau 176 die Kristalle
Sie haben sicherlich bereits bemerkt, wie Adventuretexte in einer relativen Datei untergebracht werden: Jede Raumbeschreibung oder jeder Kommentar wird mit einem Sternchen abgeschlossen. Nur die Objektnamen selbst stehen allein in einer Zeile, den Geschlechtsartikel vorangestellt.
Damit ist auch der Text für die ersten Szenen auf Disk vorhanden. Jetzt benötigen wir ein Programmiergerüst, um das herum wir unser Adventure aufbauen. Dieses Gerüst finden Sie in Listing 1.
Dieses Gerüst soll Ihnen als Grundprogramm für jedes Adventure dienen. In ihm sind nahezu alle Routinen enthalten, die für die Programmierung beziehungsweise Entwicklung eines Textadventures notwendig sind.
Dokumentation
| 3-4 | Laden und Aktivieren des deutschen Zeichensatzes (muß sich ebenfalls auf der ersten Diskseite befinden!). |
| 5 | Floppykanal öffnen. |
| 6 | Disk Seite 2 einlegen! |
| 15 | Ab 60000 stehen alle Tabellen wie der Wortschatz-Index. |
| 20 | Anhand des Feldes WI(1)-WI(100) merkt sich das Programm, in welchem Raum der Spieler bereits war. Genau wie bei INFOCOM erhält der Spieler von Räumen, in denen er bereits war, nur noch eine kurze Beschreibung. |
| 30 | Zähler für Punktzahl und Anzahl der Befehlseingaben werden auf Null gesetzt. |
| 40 | Der Titelvorspann des Spiels wird von der relativen Datei aufgerufen (SA ist dann meistens 1, da der Vorspann meistens beim ersten Satz der Texte-Datei beginnt). |
| 50 | Raumbeschreibung des ersten Zimmers ausgeben. |
| 50000-52180 | Hier steht Parser 4.0. Allerdings sind einige kleine Sachen hinzugefügt. Kommt im Befehlssatz das Wort »Alles« vor, so wird der Variablen SP der Wert 1 zugeordnet. Kommt »Ausser« vor, so erhält die Variable SQ den Wert 1. Dies ist nötig, damit wir auch Sätze wie zum Beispiel »NIMM ALLES AUSSER DEM SCHWERT« abhandeln können. |
| 53000-53040 | Unterprogramm zum Einblenden einer Statuszeile in der obersten Bildschirmzeile. Wie bei Infocom stehen in dieser Zeile der Name des Raumes, in dem man sich gerade befindet, sowie Punktzahl und Anzahl der Versuche. Dieses Unterprogramm wird innerhalb der erweiterten INPUT-Routine von Parser 4.0 aufgerufen (Zeile 50011). |
| 53200-53230 | Dieses Unterprogramm haben wir bereits im Kapitel Dateiverwaltung kennengelernt. Es dient dazu, festzustellen, ob die richtige Diskseite (Wert von Variable SI) eingelegt ist. Ist Disk Seite 2 eingelegt, so öffnet das Unterprogramm außerdem automatisch die relative Datei »Texte«. Soll Disk Seite 1 eingelegt werden, so sagen Sie einfache SIDE=1:GOSUB53200. Der Rücksprung aus dem Unterprogramm erfolgt erst dann, wenn die gewünschte Seite eingelegt ist. |
| 53400-53440 | Das altbekannte Unterprogramm zum Positionieren des Zeigers auf eine relative Datei. |
| 53500-53520 | Dito, zum Einlesen eines Satzes (I$) aus einer relativen Datei. |
| 53600-53695 | Ein Text aus der relativen Texte-Datei wird eingelesen. Beginnend ab Satz SA bis zu dem nächsten Satz, der mit einem Sternchen endet. Wenn Sie also einen Text von der relativen Datei einlesen und auf dem Bildschirm ausgeben wollen, so ist ein SA = (1. Satz des Textes): GOSUB 53600 notwendig. |
| 53700-53710 | Auf dem Bildschirm erscheint das Wort WEITER. Bei Tastendruck verschwindet es wieder, und das Unterprogramm wird mittels RETURN beendet. Dieses Unterprogramm wird zum Beispiel dann verwendet, wenn ein Text am Stück auf dem Bildschirm ausgegeben wird, der mehr als 25 Sätze enthält. Nach dem 24. Satz erscheint WEITER, damit dem Spieler genug Zeit zum Lesen bleibt und der Text nicht wegscrollt. |
| 53800-53810 | Dasselbe wie 53600-53695 nur, daß von der eigentlichen Textausgabe diesmal eine Leerzeile eingefügt wird. |
| 53900-53945 | Der altbekannte Textformer, der den String X$ per word-wrapping auf dem Bildschirm ausgibt. |
| 53950-53970 | Die Gegenstände beziehungsweise transportablen Objekte sind in der Texte-Datei mit voranstehendem Geschlechtsartikel – der, die oder das – gekennzeichnet. Am Ende der Raumbeschreibungen soll jedoch für zum Beispiel Schwert der Kommentar »Hier liegt ein Schwert« kommen. (Natürlich wieder analog zu Infocoms THERE IS A SWORD LYING HERE.) Die Artikelwandlung ist ganz einfach: Aus der beziehungsweise das wird EIN: Aus die wird EINE. |
| 54000-54095 | Unterprogramm zum Einlesen eines Raumtextes. Das Einlesen eines Raumtextes ist nicht ganz so einfach wie das Einlesen eines gewöhnlichen Textes, da sich ein Raumtext aus mehreren Einzelteilen zusammensetzt: — Zuerst wird der Haupt-Raumtext ausgegeben. Das ist der Text, der sich nie ändert. — Dann werden Textteile ausgegeben, die sich ändern können. Ein Beispiel: Eine Tür, die bei der Beschreibung sowohl als offen als auch als geschlossen beschrieben werden kann. — Im Raum befindliche Gegenstände. Dies sind in der Regel Objekte, die transportiert werden können. In der Raumbeschreibung erscheinen diese Objekte dann als »Hier liegt ein...« etc. |
| 63000-63440 | Hier steht eine Mini-Version des Relativen-Dateien-Editors. Er wird mittels GOSUB 63000 gestartet. Beim Schreiben eines Textadventures fallen einem stets neue Kommentare ein, die man der Texte-Datei zufügen muß. Es wäre viel zu umständlich, wegen jedem neuen Kommentar die aktuelle Arbeit zu speichern, dann den Relative-Datei-Editor laden etc. Daher steht am Ende des Gerüstes eine Mini-Version, mit der nur gelesen und geschrieben werden kann. Am Ende der Programmierung kann dieser Editor entfernt werden. |
Die Dokumentation ist an dieser Stelle noch nicht komplett. Sie müssen erst noch einige andere Dinge wissen.
Spielablauf der ersten Szene
So läuft die erste Spielszene ab: Der Spieler erwacht in der Glaskuppel. Er muß jetzt im Sand graben, um einen Zettel und ein Amulett zu finden. Anschließend gelangt er durch den Tunnel in eine Kristallgrotte, in der eine Statue steht. Im Marmorboden steckt ein Schwert, das sich nicht herausziehen läßt. Der Spieler muß jetzt die Statue berühren, um sich in die Figur zu verwandeln, die die Statue darstellt. Er nimmt so den Körper eines jungen Kriegers an. Jetzt kann er mühelos das Schwert aus dem Boden ziehen. Dieses Herausziehen des Schwertes wirkt gleichzeitig wie ein Schlüssel: In der westlichen Wand tut sich eine Öffnung auf, die zu einem Felsplateau hinausführt. Dort beginnt die nächste Szene.
Wir wollen jetzt gemeinsam das Gerüst um diese Szene ergänzen. Sie erfahren dabei gleichzeitig die Dokumentation zu den übrigen Gerüstteilen. Zunächst müssen ab Zeile 60000 die Tabellen fertiggestellt werden, die im Rahmen von Gordon Saga II benötigt werden: die Wortschatz-Index-Tabelle, die Landkarte und die Objekt-Logik-Tabelle. Bitte ergänzen Sie das bisherige Gerüst-Programm um die Zeilen aus Listing 2.
Anlegen der Tabellen
Auf den Wortschatz-Index brauche ich nicht lange einzugehen. Es ist der Index des modifizierten Wortschatzes – erstellt mit dem Index-Maker-Programm und anschließend in Data-Zeilen abgelegt. Anders bei der Objekttabelle. Die Objekttabelle ist das wichtigste am ganzen Programm. Zu jedem der Objekte sind mehrere Daten gespeichert. Diese Daten sind in den Feldern OB(), OX(), OA(), OU() und OS() untergebracht. Was geben diese einzelnen Felder an? Betrachten wir sie am besten einmal im einzelnen:
In der Variablen OZ ist die Anzahl der Objekte gespeichert.
| OB(1)-OB(Z): | OB(X) gibt an, in welchem Raum sich Objekt X befindet. Der Wert OB(X) ist immer dann größer Null, wenn sich das Objekt X in einem Raum befindet. Ist OB(X) = 0, so heißt dies, daß das Objekt X nicht bzw. nicht mehr vorhanden ist. Ist OB(X) kleiner als Null, so befindet sich das Objekt irgendwo anders als in einem Zimmer. Zum Beispiel im Besitz des Spielers -OB(X)=-1. Soll das Objekt in einem Schrank liegen, so kann man ihm eine für den Schrank spezifische negative Zahl zuordnen und so weiter. |
| OX(1)-OX(OZ): | OX(X) gibt an, ab welchem Satz der relativen Datei der Beschreibungs-Text zu Objekt X steht. Ist OX(X)=0, so heißt dies, daß das Objekt X bei der Raumbeschreibung nicht anhand eines Textes erläutert wird. |
| OA(1)-OA(OZ): | OA(OZ) gibt an, um welche Art von Objekt es sich bei Objekt X handelt. Es gibt folgende Werte: 1. Das Objekt ist ein Raum (zum Beispiel Tunnel). 2. Das Objekt befindet sich im Raum und kann nicht transportiert werden (zum Beispiel Öffnung in der Wand). 3. Das Objekt kann transportiert werden vom Spieler (zum Beispiel Schwert). |
| OU(1)-OU(OZ): | OU(OZ) zeigt auf den ersten Satz des Kommentars in der Texte-Datei, der ausgegeben wird, wenn das Objekt untersucht wird. Wird ein Objekt untersucht, dessen OU(X)-Wert gleich 0 ist, so erfolgt der Kommentar »DAS OBJEKT X HAT KEINE BESONDEREN MERKMALE.« |
| OS(1)-OS(OZ): | OS(X) gibt an, in welchem Satz der Texte-Datei der Objektname von Objekt X gespeichert ist (Beispiel: die Glaskuppel = 164). |
Die Objekttabelle steht nur bei der Entwicklung des Programmes in DATA-Zeilen. Sie wird später entweder als SEQ-File geladen oder als PRG-File geladen und irgendwo im RAM mit entsprechender Verwaltung untergebracht. Durch geschicktes Manipulieren der Objekttabelle ist es leicht, dem Adventure Intelligenz zu verleihen: Das Programm lacht den Spieler aus, wenn er auf die unsinnige Idee kommt, einen Raum wie den Tunnel nehmen zu wollen. Will der Spieler eine lebende Person nehmen (OA-Wert könnte zum Beispiel mit 4 definiert werden), so kann sich der Analyseteil des Adventures mit »ICH GLAUBE KAUM, DASS SICH DIE PERSON X SO OHNE WEITERES NEHMEN LÄSST« etc.
Nehmen wir einmal an, der Spieler will Objekt X nehmen – also BES=»NIMM OBJEKT X«.
Das Programm kann nun verschiedenes überprüfen und so feststellen, ob der Spieler Objekt X überhaupt nehmen kann.
Erweist sich OB(X) als -1, so meldet sich das Adventure mit »SIE HABEN OBJEKT X BEREITS«.
IST OB(X) ungleich ZN (der aktuelle Raum), so erfolgt der Kommentar »OBJEKT X IST HIER NICHT ZU SEHEN«. Außerdem läßt das Programm nur zu, Objekte zu nehmen, deren OA-Wert = 3 ist (also transportables Objekt beziehungsweise Gegenstand).
Mit den 5 Objekttabellen kann also jedes Objekt exakt analysiert werden. Ein Beispiel: Die Statue hat folgende Werte:
OB(6)=3: Das heißt, die Statue steht im Raum 3.
OX(6)=0: Das heißt, die Statue wird in der Raumbeschreibung nicht mehr besonders erwähnt. Sie kommt schließlich bereits in der Beschreibung des Quaders, auf dem sie steht, vor.
OA(6)=2: Das heißt, die Statue ist ein feststehendes Objekt und kann daher auch nicht transportiert werden.
OU(6)=113: Ab Satz 113 steht der Kommentar für die Untersuchung der Statue.
OS(6)=164: In diesem Satz der Texte-Datei steht der Objektname der Statue – die Statue.
Ganz klar wird Ihnen die Objekttabelle allerdings erst dann werden, wenn Sie sich mit der Abhandlung der Objekte im Programm selbst vertraut gemacht haben.
Zunächst möchte ich Ihnen jedoch noch einmal ganz genau zeigen, wie sich eine Raumbeschreibung zusammensetzt. Bild 2 zeigt die Raumbeschreibung der Kristallgrotte, nachdem man dort noch zwei transportable Gegenstände verloren hat.

| I | Dies ist die Statuszeile. Sie ist ständig zu sehen und gibt an, in welchem Raum man sich gerade befindet, die bisher erzielte Punktzahl und die Anzahl der Spielzüge, die man bisher gemacht hat. |
| II | In diesem Bereich steht die Hauptraumbeschreibung – also die Beschreibung, die sich während des gesamten Verlaufs des Spieles nicht ändert. |
| III | Hier sind alle Objekte aufgeführt, die sich zwar verändern können, jedoch (zumindest im Moment) nicht vom Spieler transportiert werden können. Der OA-Wert dieser Objekte beziehungsweise Beschreibungen ist 2. Der OA-Wert von Gegenständen (=transportable Objekte) ist in der Regel 0. Hier gibt es jedoch eine Ausnahme: Es ist möglich, ein solches Objekt bei seinem ersten Auftreten ausführlicher zu beschreiben als mit HIER LIEGT EIN ... Wird das Objekt jedoch genommen, so wird innerhalb der NIMM-Routine sein OA-Wert für immer auf Null gesetzt. Wird es wieder verloren, so taucht es in der Raumbeschreibung anschließend mit der Beschreibung HIER LIEGT EIN ... auf. |
| IV | Ganz am Ende der Raumbeschreibung werden die Objekte aufgeführt, die dort vom Spieler verloren worden sind beziehungsweise bei denen es sich um Gegenstände handelt, deren OA-Wert von vorneherein 0 ist. |
Das Unterprogramm zur Erzeugung der Raumbeschreibung steht im Programm ab Zeile 54000. Vergleichen Sie doch mal die obige Theorie mit diesem Programmteil – dann gewinnen Sie am schnellsten den Durchblick!
Die nächste Tabelle, die definiert wird, ist die Landkarte, die als Feld MAP(N,10) angelegt ist, wobei N für die Anzahl der Räume steht. In dieser Tabelle ist eingetragen, welche Verbindungen zwischen den einzelnen Räumen existieren. Dabei werden allerdings nur die stets bestehenden Verbindungen eingetragen, die nicht erst geschaffen werden müssen (zum Beispiel durch das Öffnen einer Tür mit einem Schlüssel). Die Richtungen stehen so: N,S,W,O,NW, NO,SW,SO, rauf, runter – also MAP(N,1) für wohin es nach Norden geht und MAP(N,10) für Süden. Eine nicht existente Verbindung hat den Wert 0.
Beispiel: Ist MAP(3,3)=4, so heißt dies, daß man von Raum 3 nach Westen gehen kann, um zu Raum 4 zu gelangen.
Analyseteil
Wie schon beim ersten Adventure-Kurs unterscheiden wir auch diesmal zwei Arten von Action: allgemeine und raumspezifische Action.
Allgemeine Action sind Handlungen, die man in jedem Raum, jederzeit ausführen kann – zum Beispiel Objekte untersuchen, Sachen nehmen, verlieren, Inventur etc.
Raumspezifische Action hingegen sind Handlungen, die man nur in bestimmten Räumen ausführen kann. »Berühre Statue« hat nur in dem Raum einen Effekt, in dem die Statue steht.
Im Programm steht die allgemeine Action in den Zeilen 300-800, die raumspezifische Action ab Zeile 2000.
Beim Gerüst sind in den Zeilen 300 - 700 bisher nur die Routinen untergebracht, die bei jedem Adventure unentbehrlich sind: GEH-Routine, NIMM-Routine, INVENTUR-Routine, VERLIER-Routine, UNTERSUCHE-Routine.
Ich verzichte an dieser Stelle bewußt auf eine genaue Dokumentation dieser Programmteile: Die Routinen sind sauber programmiert, und es sollte Ihnen keine Schwierigkeiten bereiten, sie selbst zu analysieren, wenn Sie bisher aufmerksam mitgearbeitet haben!
Wenn Sie das bisherige Programm um die folgenden wenigen Zeilen ergänzen, haben Sie die erste Szene von Gordon Saga Teil II komplett im Computer, da diese Zeilen die noch fehlende raumspezifische Action darstellen.
| 800-900 | Hier ist bei der allgemeinen Action noch eine kleine Routine eingefügt, mit der man den Brief lesen kann, der in Gordon Saga Teil 2 gefunden wird. Diese Routine habe ich erst jetzt beigefügt, da sie zwar zur allgemeinen Action zählt (man kann einen Brief überall lesen – nicht raumabhängige Action), aber nicht für jedes Adventure benötigt wird. |
| 2100-2130 | Hier steht die raumspezifische Action zur Glaskuppel. |
| 2110 | Hier wird festgestellt, ob der Spieler im Sand graben will: ist Verb = 15 (graben) und Objekt = 2 (Sand)? Gräbt der Spieler zum ersten Mal, so wird der Variablen SB der Wert 71 gesetzt (Zeiger auf Satz: Sie graben in dem Sand.). In Zeile 110 wird der Wert der Variablen SB abgefragt. Ist SB ungleich Null, so wird in der Texte-Datei der Kommentar ausgelesen, der ab Satz SB bis zum nächsten Sternchen steht. SB wird sodann auf 0 gesetzt. Mittels SB werden also Kommentare aus der Texte-Datei abgerufen. |
| 2117 | Zweites Graben. Der Spieler findet ein Amulett und einen Zettel. Diesen beiden Objekten wird jetzt der OB-Wert der Zimmernummer ZN zugeordnet, da diese beiden Objekte gefunden sind und von nun an im Spiel enthalten sind. Außerdem wird der OB-Wert der Grube auf ZN gesetzt. Dadurch wird die Grube das nächste Mal in der Raumbeschreibung erwähnt, wenn der Spieler Raum 1 untersucht: Es scheint so, als ob hier jemand vor kurzem gegraben hat.....Durch solche Action werden die Raumbeschreibungen variabel – das Adventure gewinnt an »Leben«. |
| 2119 | Versucht der Spieler ein drittes Mal zu graben, so erfolgt der Kommentar, daß weiteres Graben sinnlos ist. |
| 2120 | Wenn Verb=geh und Objekt=Tunnel, dann ist dies gleichbedeutend mit der Befehlseingabe »Norden«, da man von der Glaskuppel nach Norden gehen muß, um in den Tunnel zu gelangen. Also einfach die RI-Variable auf Norden setzen – RI=1 – und Sprung zur GEH-Routine (GOTO 300). |
| 2200 | Im Tunnel kommt keine raumspezifische Action vor. |
| 2300-2320 | Raumspezifische Action der Kristallgrotte. |
| 2305 | Wenn Verb=berühre und Objekt=Statue then Kommentar ab Zeile 119: Die Statue hat jetzt die Form des Spielers angenommen. Beim Untersuchen derselben muß also ein anderer Kommentar als bisher erscheinen. Also OU(6)=135. |
Sie sehen schon: Mit Hilfe der einzelnen Objekt- und Wortschatz-Tabellen läßt sich die raumspezifische Action nahezu in Klartext übersetzen.
Damit wäre ich mit meinen Erklärungen auch schon am Ende. Die restlichen Action-Szenen können Sie leicht selbst deuten. Adventure-Programmierung ist ein sehr kompliziertes Gebiet. Ich bin mir sicher, daß einige von Ihnen bereits jetzt Ideen haben, wo sich hier und da noch so manches verbessern läßt.
Vielleicht haben Sie auch schon die Idee zu Parser 6.0 – dem NON-PLUS-ULTRA-Parser im Kopf.
Ich hoffe, Ihnen mit diesem Kapitel neue Anregungen im Bereich der Adventure-Programmierung gegeben zu haben. Wenn Sie noch irgendwelche Fragen oder Probleme mit Adventure-Programmierung haben, dann wenden Sie sich doch mal an die 64'er, vielleicht geben Ihre Nachfragen Anlaß zu einem kleinen Folgekurs.
Ich will allerdings noch nicht zum Schlußwort kommen, denn es steht noch ein wichtiges Kapitel aus:
Der Adventure-Cracker
Das Programm im Listing 4 macht's möglich: Adventures im Schlaf gelöst. Naja, ganz im Schlaf geht's nicht, aber Sie müssen sich lediglich im Sessel zurücklehnen und am Bildschirm mitverfolgen, wie der gesamte Text des Adventures ausgegeben wird.
Im Prinzip ist der Adventure-Cracker nichts weiter als ein ultra-primitiver Disk-Monitor, mit dem sich die einzelnen Bytes einer Diskette lesen lassen. Sie müssen einfach die Diskette, auf der sich das Adventure befindet, ins Laufwerk legen und dann mittels Angabe von Track und Sector nach Text suchen.
Der Adventure-Cracker filtert automatisch alle Zeichen heraus, die keinen Text darstellen (Grafikzeichen etc.). Es ist nur eine Frage der Zeit, bis man so den gesamten Text eines Adventures herausfindet.
Der Cracker knackt alle Basic-Adventures, Adventures, die mit relativen Dateien arbeiten (also unsere), und auch professionelle Spiele. Den INFOCOMs kann man mit dem Adventure-Cracker allerdings in keinster Weise zu Leibe rücken: Ihr Text ist auf eine äußerst komplizierte Weise verschlüsselt und bringt auch harte Dechiffrierer zur Verzweiflung ...
Es ist also ratsam, Adventure-Texte nicht einfach unverschlüsselt in relativen Dateien abzulegen. Parallel zum Codieren bietet sich allerdings noch etwas anderes an:
Text-Raffung
Es gibt verschiedene Methoden, Text zu kürzen, um so letztendlich noch mehr Text auf einer Disk-Seite unterzubringen. Es bietet sich zum Beispiel an, einzelne Kürzel zu definieren. Schließlich haben wir 255 verschiedene Zeichen zur Verfügung, von denen zur reinen Textdarstellung nur ca. 70 benötigt werden (Groß-Klein-Buchstaben und diverse Satzzeichen). Man könnte nun doch eigentlich eine Tabelle anlegen, in der häufige Buchstabenkombinationen (er, die, ch, das, ng, en, .....) durch Grafikzeichen codiert werden.
Sie können insgesamt zirka 180 solche Kürzel definieren und dann ein Programm schreiben, das Ihre relativen Dateien automatisch kürzt und die Buchstaben anhand einer weiteren Tabelle – einem Code-Schlüssel – chiffriert.
Es gibt unglaublich viele Verschlüsselungs- und Text-Raffungsmethoden, die sich relativ einfach programmieren lassen. Denken Sie mal nach!
Bonbon zum Schluß
Zu Beginn dieses Kurses habe ich Ihnen versprochen, daß das freie RAM bis zum letzten Byte mit interessanten Routinen belegt wird. Das haben wir auch geschafft. Bis auf einen kleinen Bereich: von 1024 bis 2023 der alte Bildschirmspeicher.
Dort bringen wir jetzt noch eine Maschinenroutine unter, die in Listing 5 abgedruckt ist.
Diese Routine können Sie erst dann laden, wenn der deutsche Zeichensatz aktiviert und der Bildschirm an eine andere Stelle als 1024-2023 gelegt worden ist. Zum Laden können Sie nicht den LOAD-Befehl, sondern nur Listing 6 verwenden.
Die Routine beherbergt zwei sehr wichtige Funktionen, die bei jeder Adventure-Programmierung benötigt werden:
- Erweiterte INPUT-Routine
Mittels SYS 1160,BE$ rufen Sie die erweiterte INPUT-Routine auf. Nach Rücksprung steht der eingegebene Satz in BE$ – natürlich kann anstelle von BE$ auch jeder andere beliebige String gesetzt werden. - Raumbeschreibung einlesen
Mittels SYS 1024,SA rufen Sie eine Maschinenroutine auf, die den Satzbereich einer relativen Datei von Satz SA ab bis zum nächsten Sternchen ausgibt – und das sehr, sehr schnell!
Die relative Datei muß von Basic aus per OPEN 8,8,8,»Filename« geöffnet werden, ebenso der Floppykanal mittels OPEN 15,8,15.
Nochmals sei darauf hingewiesen, daß die Routinen nur lauffähig sind, wenn der deutsche Zeichensatz verwendet wird, und daß sie nur mit den Zeilen aus Listing 6 geladen werden können.
Mit dieser Routine möchte ich mich von Ihnen verabschieden. Ich hoffe, daß Sie einige wertvolle Tips zur Programmierung von Abenteuerspielen erhalten haben. Viel Spaß beim Programmieren!
(M. Nickles/bs)0 rem ***************************
1 rem gordon saga ii - 1985 by sm
2 rem ***************************
3 ifi=0theni=1:load"d.z.satz",8,1
4 poke648,204:poke53272,56:poke56576,0:print"{clr}":rem d.t.satz aktivieren
5 open15,8,15:print"{clr}{yel}";chr$(14);
6 side=2:gosub53200:print"{clr}";
15 gosub60000: rem tabellen einlesen
20 dimwi(100): rem zimmer-merker
30 sc=0:mo=0 : rem score/versuch
40 sa=1:gosub53600 : rem titeltext
50 zn=1:gosub54000 : rem beschreib. 1.raum
100 rem start ------------------------------------------------------------------
101 :
110 ifsb<>0thensa=sb:sb=0:gosub53600:rem kommentar ausgeben
120 gosub50000 :rem befehlseingabe
130 :
300 rem geh-routine -----------------
310 ifri=0then400
320 i=map(zn,ri)
330 ifi=0thenprint"Diese Richtung ist nicht m{CBM-O}glich!":goto400
340 zn=i:gosub54000
400 rem schau/untersuche ------------
410 ifve<>11then500
415 ifo1=0thengosub54000:goto500
420 sa=os(o1):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1)
425 ifob(o1)=-1then430
430 ifob(o1)<>znthenx$=ob$+" ist hier nicht zu sehen!":gosub53900:goto500
440 ifou(o1)=0thenx$=ob$+" hat keine besonderen Merkmale.":gosub53900
450 ifou(o1)thensa=ou(o1):gosub53800
500 rem nimm ------------------------
505 ifve<>12then600
506 ifsp=1then550:rem nimm alles
507 sa=os(o1):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1)
510 ifo1=0thenprint"Ihr Satz enth{CBM-A}lt kein Objekt !":goto600
514 :ifob(o1)=-1thenprint"Das haben Sie bereits !":goto600
515 :ifob(o1)<>znthenx$=ob$+" ist hier nicht zu sehen!":gosub53900:goto600
516 ifoa(o1)=0then600
520 :ifoa(o1)=1thenprint"Bizarr!":goto600
525 :ifoa(o1)=2thenx$=ob$+" ist viel zu schwer zum tragen!":gosub53900:goto600
530 :ifoa(o1)=3thenprint"Genommen.":ob(o1)=-1:goto600
550 :
554 print:fori=1tooz
555 :ifob(i)<>znthen580
556 sa=os(i):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1)
560 :i$=ob$+": "
565 ifsq=1andi=o1then580:rem ausser
570 :ifoa(i)=1thenprinti$;"Bizarr !"
575 :ifoa(i)=2thenprinti$;"Zu schwer zum tragen !"
577 :ifoa(i)=3thenprinti$;"Genommen.":ob(i)=-1
580 nexti
600 rem inventur -----------------
601 ifve<>13then700
605 print"{down}Sie haben: {up}"
610 ic=0:fori=1tooz
611 sa=os(i):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1):i$=ob$
612 :ifleft$(i$,3)="Der"thenj$=right$(i$,len(i$)-3):i$="Den"+j$
615 :ifob(i)=-1thenprint"{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}";i$:ic=1
620 nexti:ific=0thenprint"{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}Bock auf Bier !"
700 rem verliere -----------------
701 ifve<>14then800
702 ifsp=1then750: rem verlier alles
703 ifo1=0thenprint"Ihr Satz enth{CBM-A}lt kein Objekt!":goto800
705 ifob(o1)<>-1thenprint"{down}Sie haben das nicht !":goto800
715 ob(o1)=zn:print"Ok.":goto800
750 ic=0:fori=1tooz
755 :ifsq=1andi=o1then780:rem ausser
760 sa=os(i):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1):i$=ob$+": "
770 :ifob(i)=-1thenob(i)=zn:printi$;"Ok.":ic=1
780 nexti:ific=0andsq=1thenprint"Wie soll das gehen ?"
782 ific=0andsq=0thenprint"Sie haben doch garnichts !"
800 :
2000 rem raumspezifische action ------------------------------------------------
50000 rem *****************************
50001 rem * *
50002 rem * wort-parser 4.0 *
50003 rem * *
50004 rem * <c> 1986 bei *
50005 rem * *
50006 rem * michael nickles *
50007 rem * *
50008 rem *****************************
50010 rem befehlssatzeingabe ---------------------------------------------------
50011 zw=0:print:gosub53000:mo=mo+1:rem titelline ausgeben
50012 ifud>0then50500:rem und
50015 sl=77: rem befehlssatzlaenge
50020 be$="":poke198,0:print"{yel}>{CBM-@}";
50030 getx$:ifpeek(203)=1then50120
50040 ifx$=""then50030
50050 iflen(be$)=0andasc(x$)=20then50030
50060 i=asc(x$):ifi<32ori>133andi<159thenifi<>20then50030
50070 iflen(be$)=slandi<>20then50030
50080 be$=be$+x$
50090 printchr$(20);x$;"{CBM-@}";
50100 ifi=20thenbe$=left$(be$,len(be$)-2):goto50030
50110 goto50030
50120 print"{left} "
50400 rem satzzeichen suchen ---------------------------------------------------
50401 :
50415 sn=0
50420 ifright$(be$,1)=" "thenbe$=left$(be$,len(be$)-1):goto50420
50430 i$=right$(be$,1)
50440 ifi$="."ori$="!"thensn=0:be$=left$(be$,len(be$)-1):goto50420
50450 ifi$="?"thensn=1:be$=left$(be$,len(be$)-1):goto50420
50500 rem be$-zeiger setzen ----------------------------------------------------
50501 :
50502 ifud=0thenve=0:ri=0:o1=0:o2=0:sp=0:sq=0
50504 ifud>0thenri=0:goto50530
50505 ifleft$(be$,1)=" "thenbe$=right$(be$,len(be$)-1):goto50505
50510 be$=be$+" "
50520 za=1 :rem zeiger a setzen
50530 zb=za+1
50540 ifmid$(be$,zb,1)=""thenud=0:close1:open1,8,3,"texte":return
50550 ifmid$(be$,zb,1)<>" "thenzb=zb+1:goto50550
50590 su$=mid$(be$,za,zb-za)
50600 rem su$ vorbehandlung ----------------------------------------------------
50601 :
50610 ifsu$="und"thenud=1:goto50630
50620 ifsu$=","thenud=2:goto50630
50625 goto50670
50630 za=zb+1
50640 ifmid$(be$,za,1)=""thenprint"Und was ?":goto50530
50650 ifmid$(be$,za,1)=" "thenza=za+1:goto50650
50660 close1:open1,8,3,"texte":return
50670 ifsu$="ihn"orsu$="sie"orsu$="es"theno1=om:goto51300
50680 ifsu$="alles"thensp=1:goto51300
50690 ifsu$="ausser"thensq=1:goto51300
51000 rem binaere suchroutine --------------------------------------------------
51001 :
51002 close1:open1,8,3,"wortschatz"
51007 rem anfang und ende des suchbereiches ermitteln
51008 i=asc(left$(su$,1))
51009 ifi-65<0ori-65>25thengosub51500:goto50000
51010 an=in(i-65):rem anfang des suchbereiches
51012 iz=64
51013 ifin(i-iz)=0theniz=iz-1:goto51013
51015 en=in(i-iz)-1:rem ende des suchbereiches
51016 ifan=0thengosub51500:ud=0:goto50000
51020 sz=197:n=int(log(en-an+1)/log(2))+1 :rem maximal-formel
51030 sa=an-1+(2^n)/2:rem mitte der ges.dat
51040 gosub52100:rem a$ lesen
51050 n=n-1 :rem 1.abfrage
51060 :
51070 rem su$ mit a$ vergleichen ------
51080 : iflen(su$)<3then51110
51090 : ifwa=1 and su$=left$(a$,len(su$)) thenve=wc:goto51300
51100 : ifwa<>3orsu$<>right$(a$,len(su$))then51110
51102 : ifud=1orud=2thenud=3:o1=0:o2=0
51104 : ifo1=0theno1=wc:om=o1:goto51300
51105 : ifo2=0theno2=wc:om=o1:goto51300
51110 : ifwa=2 and su$=a$ thenri=wc:goto51300
51115 : ifwa=5 and su$=a$ thenad=wc:goto51300
51120 : ifwa=1 and su$=a$ thenve=wc:goto51300
51125 : ifwa=4 and su$=a$ then51300
51130 : ifsu$<a$thensa=sa-(2^(n-1)):gosub52100:goto51160
51140 : ifsa+(2^(n-1))>sa+en-anandn>-1thenn=n-1:goto51140:rem ''ueberlauf''
51150 : sa=sa+(2^(n-1)):gosub52100:rem ''halbieren''
51160 :
51170 :n=n-1 :rem naechst. halbieren
51180 :ifn<0thengosub51500:ud=0:goto50000
51190 rem print"sa=";sa;" n=";n :rem unnoetig !!
51200 :goto51060:rem naechst. such-vers.
51300 rem naechstes wort
51310 za=zb+1
51320 ifmid$(be$,za,1)=""then50530
51330 ifmid$(be$,za,1)=" "thenza=za+1:goto51330
51350 goto50530
51500 rem ich kenne su$ nicht --------------------------------------------------
51501 :
51510 i=int(3*rnd(1))+1
51520 onigoto51530,51540,51550
51530 x$=""+"Ich kenne das Wort '"+su$+"' nicht.":goto52000
51540 x$=""+"Das Wort '"+su$+"' ist mir nicht bekannt.":goto52000
51550 x$=""+"Deutsch ist leider nur meine zweite Sprache. Ich kenne das "
51555 x$=x$+"Wort '"+su$+"' nicht.":goto52000
52000 rem formatierte textausgabe ----------------------------------------------
52010 ifx$=""then52090
52020 iflen(x$)<40thenprintx$:goto52090
52030 iflen(x$)=40thenprintx$;:goto52090
52040 i$=left$(x$,41):ic=0:fori=1tolen(i$):ifmid$(i$,i,1)=" "thenic=i
52050 nexti:ific=0thenprintx$:goto52090
52060 i$=left$(i$,ic-1):iflen(i$)=40thenprinti$;
52070 iflen(i$)<40thenprinti$
52080 x$=right$(x$,len(x$)-ic):goto52010
52090 return
52100 rem satz-teilbereich lesen -----------------------------------------------
52101 :
52110 hb%=sa/256:lb%=sa-hb%*256
52112 print#15,"p";chr$(3);chr$(lb%);chr$(hb%);chr$(1)
52114 input#15,a:ifa=50thenprint"satznummer zu hoch"
52120 ifa=50thenreturn
52130 input#1,a$
52140 wa=val(mid$(a$,22,1))
52150 wc=val(mid$(a$,23,3))
52160 a$=left$(a$,21)
52170 ifright$(a$,1)="{rght}"thena$=left$(a$,len(a$)-1):goto52170
52180 return
53000 rem up - titelline -------------------------------------------------------
53001 :
53010 i1$=" ":t$=""
53020 t$=t$+chr$(18)+r$:i$=str$(sc)+"/"+right$(str$(mo),len(str$(mo))-1)
53030 t$=t$+right$(i1$,41-len(t$)-len(i$))+i$+chr$(146):print"{home}";t$;
53040 print"{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}";:return
53200 rem up - disk einlegen ---------------------------------------------------
53201 :
53205 ific=21thengosub53700:rem weiter
53210 print"{rvon}Bitte Disk-Seite";side;"{left} einlegen !{rvof}";:poke198,0:wait198,1
53220 print"{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left} ";
53221 print"{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}{left}";
53222 open2,8,2,"#":print#15,"u1 2 0 18 0":print#15,"b-p";2;162:get#2,i$
53224 close2:ifside<>val(i$)then53200
53225 ifside=2thenopen1,8,3,"texte"
53230 return
53400 rem zeiger postionieren --------------------------------------------------
53401 :
53420 hb%=sa/256:lb%=sa-hb%*256:print#15,"p";chr$(3);chr$(lb%);chr$(hb%);chr$(1)
53430 input#15,ia:ifia=50thenprint"satznummer zu hoch"
53440 return
53500 rem satz einlesen --------------------------------------------------------
53501 :
53510 ifa=50then53520
53512 input#1,i$
53515 zw=zw+1:ifzw>23thengosub53700:zw=0
53520 return
53600 rem text-einlesen --------------------------------------------------------
53601 :
53610 ifside<>2thenside=2:gosub53200
53620 gosub53400:rem positonieren
53630 gosub53500:rem i$ einlesen
53640 ifright$(i$,1)<>"*"then53660
53650 :ifi$<>"*"thenprintleft$(i$,len(i$)-1)
53652 :sa=0:return
53660 iflen(i$)<40thenprinti$
53670 iflen(i$)>=40thenprinti$;
53680 sa=sa+1
53695 goto53630
53700 rem weiter ---------------------------------------------------------------
53701 :
53705 print"[weiter]";:poke198,0:wait198,1:print"{left}{left}{left}{left}{left}{left}{left}{left} {left}{left}{left}{left}{up}
53710 return
53800 rem kommentar lesen ------------------------------------------------------
53801 :
53805 zw=1
53810 print:gosub53600:return
53900 rem textformer ------------------
53901 :
53902 ifx$<>""thenprint
53905 ifx$=""then53945
53910 iflen(x$)<40thenprintx$:goto53945
53915 iflen(x$)=40thenprintx$;:goto53945
53920 i$=left$(x$,41):ic=0:fori=1tolen(i$):ifmid$(i$,i,1)=" "thenic=i
53925 nexti:ific=0thenprintx$:goto53945
53930 i$=left$(i$,ic-1):iflen(i$)=40thenprinti$;
53935 iflen(i$)<40thenprinti$
53940 x$=right$(x$,len(x$)-ic):goto53905
53945 return
53950 rem artikel-wandler -------------
53951 :
53952 ii$=left$(ob$,3)
53955 ifii$<>"Der"andii$<>"Das"then53965
53960 x$="":x$="Hier liegt ein"+right$(ob$,len(ob$)-3)+"."
53965 ifii$<>"Die"then53970
53966 x$="":x$="Hier liegt eine"+right$(ob$(i),len(ob$)-3)+"."
53970 goto53905
54000 rem raumtext-einlesen ----------------------------------------------------
54001 :
54020 print:fori=1tooz :rem ob.tab.
54030 :ifob(i)<>znthen54080
54035 :ifox(i)<1then54080 :rem namelos
54040 :sa=ox(i):gosub53400 :rem posit.
54050 :ifoa(i)=1thengosub53500:r$=i$ :rem read i$, titelline
54060 :ifwi(zn)=1andve<>11andoa(i)=1thenprintr$:sa=0:goto54080
54070 :gosub53600 :rem lesen
54080 nexti
54081 fori=1tooz
54083 ifob(i)<>znoroa(i)<>3orox(i)<>0then54088
54084 sa=os(i):gosub53400:gosub53500:ob$="D"+right$(i$,len(i$)-1)
54085 x$="Hier liegt "+ob$+".":zw=zw+1:gosub53950
54088 nexti
54095 wi(zn)=1:print:return
60000 rem tabellen einlesen ----------------------------------------------------
60001 :
63000 rem *****************************
63005 rem * mini-texteditor v.iii.4 *
63010 rem * <c> 1985 *
63015 rem * von michael nickles *
63020 rem *****************************
63025 rem anfangsmenue -----------------
63030 poke198,0:input"{down}{down}dateiname *{left}{left}{left}";d$:poke198,0
63035 input"satzlaenge 40{left}{left}{left}{left}";sl:ifsl<1orsl>254thenprint"geht nicht !":goto30
63040 open 15,8,15
63045 print#15,"i0":open 1,8,3,d$:print
63050 rem zwischenmenue ----------------
63055 print"{rvon}s / l / ende {rvof}";
63060 geti$:ifi$=""then63060
63065 ifi$="e"thenprint"{clr}";:goto63265
63070 ifi$<>"s"andi$<>"l"then63060
63075 input"satznr";sa:if sa<0 or sa>63000 then63070
63080 ifi$="l"thenprint"{clr}";:goto63095
63085 ifi$="s"thenprint"{clr}";:mo=1:goto63150
63090 goto 63050
63095 rem lesen ------------------------
63100 :print"{clr}{rvon}";sa;"{left}-";str$(sa+20);" {rvof}"
63105 ia=sa
63110 for sa=ia to ia+20
63115 : gosub63195:gosub63220
63120 : ifa=50thensa=ia+21:goto63135
63125 : iflen(a$)<40thenprinta$
63130 : iflen(a$)>=40thenprinta$;
63135 next:print
63140 ifa=50thenprint"satznummer zu hoch!"
63145 goto 63050
63150 rem schreiben --------------------
63155 print"eingabesatz //=keine eingabe"
63160 gosub63195:rem positionieren
63165 ifa=50thenprint"satznummer zu hoch!":goto63050:rem fehlerkanalabfr.
63170 gosub63330:a$=be$ :rem input-rout.
63175 ifa$="//"thenmo=0:goto63050:rem ende
63180 gosub63240:rem a$ schreiben
63185 sa=sa+1 :rem naechster satz
63190 goto63160:rem next (loop)
63195 rem positionieren ****************
63200 hb%=sa/256:lb%=sa-hb%*256
63205 print#15,"p";chr$(3);chr$(lb%);chr$(hb%);chr$(1)
63210 input#15,a
63215 return
63220 rem satz einlesen ****************
63225 ifa=50thenreturn
63230 input#1,a$
63235 return
63240 rem satz schreiben ***************
63245 ifa=50thenreturn
63250 ifa$=""thena$=":":rem zur sicherheit !!!
63255 print#1,a$
63260 return
63265 rem beenden **********************
63270 close 1
63275 close 15
63280 print "++ ende ++"
63285 end
63290 rem korrektur-routine ------------
63295 fori=0tolen(be$):printchr$(20);:nexti:be$=""
63300 sa=sa+sc : rem textzeiger
63305 ifsa<0thensa=0 : rem sperre
63310 gosub 63195: rem positionieren
63315 ifa=50thensa=sa-sc:goto63310
63320 input#1,a$
63325 return
63330 rem texteingabe ------------------
63335 ifar=1thenar=0:a$="{rvon}satznummer zu hoch!{rvof}":goto63345
63340 gosub63195:gosub63220
63345 print"{home} ";:print"{home}{rvon}satz";sa;"{rvof}"
63350 print" {up}";a$
63355 print"{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}";
63360 print"{down}"
63365 be$="":poke198,0:poke211,0:poke214,22:sys58732:print"{yel}{CBM-@}";
63370 getx$:ifpeek(203)=1then63430
63375 if peek(203)=7andpeek(653)=0 then sc=1 : gosub 63290: goto 63330
63380 if peek(203)=7andpeek(653)=1 then sc=-1 : gosub 63290: goto 63330
63385 ifx$=""then63370
63390 iflen(be$)=0andasc(x$)=20then63370
63395 i=asc(x$):ifi<32ori>133andi<159thenifi<>20then63370
63400 iflen(be$)=slandi<>20then63370
63405 ifx$=" "thenx$="{rght}"
63410 be$=be$+x$
63415 printchr$(20);x$;"{CBM-@}";
63420 ifi=20thenbe$=left$(be$,len(be$)-2):goto63370
63425 goto63370
63430 print"{left} ":gosub63195
63435 ifbe$=""thenbe$=":"
63440 print"{home}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}":return
0 REM *************************** 1 REM GORDON SAGA II - 1985 BY SM 2 REM *************************** 3 IF I=0 THENI=1:LOAD "D.Z.SATZ",8,1 4 POKE 648,204:POKE 53272,56:POKE 56576,0:PRINT"{CLR}":REM D.T.SATZ AKTIVIEREN 5 OPEN 15,8,15:PRINT"{CLR,YELLOW}";CHR$ (14); 6 SIDE=2:GOSUB 53200:PRINT"{CLR}"; 15 GOSUB 60000: REM TABELLEN EINLESEN 20 DIM WI(100): REM ZIMMER-MERKER 30 SC=0:MO=0 : REM SCORE/VERSUCH 40 SA=1:GOSUB 53600 : REM TITELTEXT 50 ZN=1:GOSUB 54000 : REM BESCHREIB. 1.RAUM 100 REM START ------------------------------------------------------------------ 101 : 110 IF SB<>0 THENSA=SB:SB=0:GOSUB 53600:REM KOMMENTAR AUSGEBEN 120 GOSUB 50000 :REM BEFEHLSEINGABE 130 : 300 REM GEH-ROUTINE ----------------- 310 IF RI=0 THEN400 320 I=MAP(ZN,RI) 330 IF I=0 THENPRINT"DIESE RICHTUNG IST NICHT MOGLICH!":GOTO 400 340 ZN=I:GOSUB 54000 400 REM SCHAU/UNTERSUCHE ------------ 410 IF VE<>11 THEN500 415 IF O1=0 THENGOSUB 54000:GOTO 500 420 SA=OS(O1):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1) 425 IF OB(O1)=-1 THEN430 430 IF OB(O1)<>ZN THENX$=OB$+" IST HIER NICHT ZU SEHEN!":GOSUB 53900:GOTO 500 440 IF OU(O1)=0 THENX$=OB$+" HAT KEINE BESONDEREN MERKMALE.":GOSUB 53900 450 IF OU(O1) THENSA=OU(O1):GOSUB 53800 500 REM NIMM ------------------------ 505 IF VE<>12 THEN600 506 IF SP=1 THEN550:REM NIMM ALLES 507 SA=OS(O1):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1) 510 IF O1=0 THENPRINT"IHR SATZ ENTHALT KEIN OBJEKT !":GOTO 600 514 :IF OB(O1)=-1 THENPRINT"DAS HABEN SIE BEREITS !":GOTO 600 515 :IF OB(O1)<>ZN THENX$=OB$+" IST HIER NICHT ZU SEHEN!":GOSUB 53900:GOTO 600 516 IF OA(O1)=0 THEN600 520 :IF OA(O1)=1 THENPRINT"BIZARR!":GOTO 600 525 :IF OA(O1)=2 THENX$=OB$+" IST VIEL ZU SCHWER ZUM TRAGEN!":GOSUB 53900:GOTO 600 530 :IF OA(O1)=3 THENPRINT"GENOMMEN.":OB(O1)=-1:GOTO 600 550 : 554 PRINT:FOR I=1 TOOZ 555 :IF OB(I)<>ZN THEN580 556 SA=OS(I):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1) 560 :I$=OB$+": " 565 IF SQ=1AND I=O1 THEN580:REM AUSSER 570 :IF OA(I)=1 THENPRINTI$;"BIZARR !" 575 :IF OA(I)=2 THENPRINTI$;"ZU SCHWER ZUM TRAGEN !" 577 :IF OA(I)=3 THENPRINTI$;"GENOMMEN.":OB(I)=-1 580 NEXT I 600 REM INVENTUR ----------------- 601 IF VE<>13 THEN700 605 PRINT"{DOWN}SIE HABEN:{SPACE,UP}" 610 IC=0:FOR I=1 TOOZ 611 SA=OS(I):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1):I$=OB$ 612 :IF LEFT$ (I$,3)="DER" THENJ$=RIGHT$ (I$,LEN (I$)-3):I$="DEN"+J$ 615 :IF OB(I)=-1 THENPRINT"{11RIGHT}";I$:IC=1 620 NEXT I:IF IC=0 THENPRINT"{11RIGHT}BOCK AUF BIER !" 700 REM VERLIERE ----------------- 701 IF VE<>14 THEN800 702 IF SP=1 THEN750: REM VERLIER ALLES 703 IF O1=0 THENPRINT"IHR SATZ ENTHALT KEIN OBJEKT!":GOTO 800 705 IF OB(O1)<>-1 THENPRINT"{DOWN}SIE HABEN DAS NICHT !":GOTO 800 715 OB(O1)=ZN:PRINT"OK.":GOTO 800 750 IC=0:FOR I=1 TOOZ 755 :IF SQ=1AND I=O1 THEN780:REM AUSSER 760 SA=OS(I):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1):I$=OB$+": " 770 :IF OB(I)=-1 THENOB(I)=ZN:PRINTI$;"OK.":IC=1 780 NEXT I:IF IC=0AND SQ=1 THENPRINT"WIE SOLL DAS GEHEN ?" 782 IF IC=0AND SQ=0 THENPRINT"SIE HABEN DOCH GARNICHTS !" 800 : 2000 REM RAUMSPEZIFISCHE ACTION ------------------------------------------------ 50000 REM ***************************** 50001 REM * * 50002 REM * WORT-PARSER 4.0 * 50003 REM * * 50004 REM * <C> 1986 BEI * 50005 REM * * 50006 REM * MICHAEL NICKLES * 50007 REM * * 50008 REM ***************************** 50010 REM BEFEHLSSATZEINGABE --------------------------------------------------- 50011 ZW=0:PRINT:GOSUB 53000:MO=MO+1:REM TITELLINE AUSGEBEN 50012 IF UD>0 THEN50500:REM UND 50015 SL=77: REM BEFEHLSSATZLAENGE 50020 BE$="":POKE 198,0:PRINT"{YELLOW}>@"; 50030 GET X$:IF PEEK (203)=1 THEN50120 50040 IF X$="" THEN50030 50050 IF LEN (BE$)=0AND ASC (X$)=20 THEN50030 50060 I=ASC (X$):IF I<32OR I>133AND I<159 THENIF I<>20 THEN50030 50070 IF LEN (BE$)=SLAND I<>20 THEN50030 50080 BE$=BE$+X$ 50090 PRINTCHR$ (20);X$;"@"; 50100 IF I=20 THENBE$=LEFT$ (BE$,LEN (BE$)-2):GOTO 50030 50110 GOTO 50030 50120 PRINT"{LEFT,SPACE}" 50400 REM SATZZEICHEN SUCHEN --------------------------------------------------- 50401 : 50415 SN=0 50420 IF RIGHT$ (BE$,1)=" " THENBE$=LEFT$ (BE$,LEN (BE$)-1):GOTO 50420 50430 I$=RIGHT$ (BE$,1) 50440 IF I$="."OR I$="!" THENSN=0:BE$=LEFT$ (BE$,LEN (BE$)-1):GOTO 50420 50450 IF I$="?" THENSN=1:BE$=LEFT$ (BE$,LEN (BE$)-1):GOTO 50420 50500 REM BE$-ZEIGER SETZEN ---------------------------------------------------- 50501 : 50502 IF UD=0 THENVE=0:RI=0:O1=0:O2=0:SP=0:SQ=0 50504 IF UD>0 THENRI=0:GOTO 50530 50505 IF LEFT$ (BE$,1)=" " THENBE$=RIGHT$ (BE$,LEN (BE$)-1):GOTO 50505 50510 BE$=BE$+" " 50520 ZA=1 :REM ZEIGER A SETZEN 50530 ZB=ZA+1 50540 IF MID$ (BE$,ZB,1)="" THENUD=0:CLOSE 1:OPEN 1,8,3,"TEXTE":RETURN 50550 IF MID$ (BE$,ZB,1)<>" " THENZB=ZB+1:GOTO 50550 50590 SU$=MID$ (BE$,ZA,ZB-ZA) 50600 REM SU$ VORBEHANDLUNG ---------------------------------------------------- 50601 : 50610 IF SU$="UND" THENUD=1:GOTO 50630 50620 IF SU$="," THENUD=2:GOTO 50630 50625 GOTO 50670 50630 ZA=ZB+1 50640 IF MID$ (BE$,ZA,1)="" THENPRINT"UND WAS ?":GOTO 50530 50650 IF MID$ (BE$,ZA,1)=" " THENZA=ZA+1:GOTO 50650 50660 CLOSE 1:OPEN 1,8,3,"TEXTE":RETURN 50670 IF SU$="IHN"OR SU$="SIE"OR SU$="ES" THENO1=OM:GOTO 51300 50680 IF SU$="ALLES" THENSP=1:GOTO 51300 50690 IF SU$="AUSSER" THENSQ=1:GOTO 51300 51000 REM BINAERE SUCHROUTINE -------------------------------------------------- 51001 : 51002 CLOSE 1:OPEN 1,8,3,"WORTSCHATZ" 51007 REM ANFANG UND ENDE DES SUCHBEREICHES ERMITTELN 51008 I=ASC (LEFT$ (SU$,1)) 51009 IF I-65<0OR I-65>25 THENGOSUB 51500:GOTO 50000 51010 AN=IN(I-65):REM ANFANG DES SUCHBEREICHES 51012 IZ=64 51013 IF IN(I-IZ)=0 THENIZ=IZ-1:GOTO 51013 51015 EN=IN(I-IZ)-1:REM ENDE DES SUCHBEREICHES 51016 IF AN=0 THENGOSUB 51500:UD=0:GOTO 50000 51020 SZ=197:N=INT (LOG (EN-AN+1)/LOG (2))+1 :REM MAXIMAL-FORMEL 51030 SA=AN-1+(2^N)/2:REM MITTE DER GES.DAT 51040 GOSUB 52100:REM A$ LESEN 51050 N=N-1 :REM 1.ABFRAGE 51060 : 51070 REM SU$ MIT A$ VERGLEICHEN ------ 51080 : IF LEN (SU$)<3 THEN51110 51090 : IF WA=1 AND SU$=LEFT$ (A$,LEN (SU$)) THENVE=WC:GOTO 51300 51100 : IF WA<>3OR SU$<>RIGHT$ (A$,LEN (SU$)) THEN51110 51102 : IF UD=1OR UD=2 THENUD=3:O1=0:O2=0 51104 : IF O1=0 THENO1=WC:OM=O1:GOTO 51300 51105 : IF O2=0 THENO2=WC:OM=O1:GOTO 51300 51110 : IF WA=2 AND SU$=A$ THENRI=WC:GOTO 51300 51115 : IF WA=5 AND SU$=A$ THENAD=WC:GOTO 51300 51120 : IF WA=1 AND SU$=A$ THENVE=WC:GOTO 51300 51125 : IF WA=4 AND SU$=A$ THEN51300 51130 : IF SU$<A$ THENSA=SA-(2^(N-1)):GOSUB 52100:GOTO 51160 51140 : IF SA+(2^(N-1))>SA+EN-ANAND N>-1 THENN=N-1:GOTO 51140:REM ''UEBERLAUF'' 51150 : SA=SA+(2^(N-1)):GOSUB 52100:REM ''HALBIEREN'' 51160 : 51170 :N=N-1 :REM NAECHST. HALBIEREN 51180 :IF N<0 THENGOSUB 51500:UD=0:GOTO 50000 51190 REM PRINT"SA=";SA;" N=";N :REM UNNOETIG !! 51200 :GOTO 51060:REM NAECHST. SUCH-VERS. 51300 REM NAECHSTES WORT 51310 ZA=ZB+1 51320 IF MID$ (BE$,ZA,1)="" THEN50530 51330 IF MID$ (BE$,ZA,1)=" " THENZA=ZA+1:GOTO 51330 51350 GOTO 50530 51500 REM ICH KENNE SU$ NICHT -------------------------------------------------- 51501 : 51510 I=INT (3*RND (1))+1 51520 ON IGOTO 51530,51540,51550 51530 X$=""+"ICH KENNE DAS WORT '"+SU$+"' NICHT.":GOTO 52000 51540 X$=""+"DAS WORT '"+SU$+"' IST MIR NICHT BEKANNT.":GOTO 52000 51550 X$=""+"DEUTSCH IST LEIDER NUR MEINE ZWEITE SPRACHE. ICH KENNE DAS " 51555 X$=X$+"WORT '"+SU$+"' NICHT.":GOTO 52000 52000 REM FORMATIERTE TEXTAUSGABE ---------------------------------------------- 52010 IF X$="" THEN52090 52020 IF LEN (X$)<40 THENPRINTX$:GOTO 52090 52030 IF LEN (X$)=40 THENPRINTX$;:GOTO 52090 52040 I$=LEFT$ (X$,41):IC=0:FOR I=1 TOLEN (I$):IF MID$ (I$,I,1)=" " THENIC=I 52050 NEXT I:IF IC=0 THENPRINTX$:GOTO 52090 52060 I$=LEFT$ (I$,IC-1):IF LEN (I$)=40 THENPRINTI$; 52070 IF LEN (I$)<40 THENPRINTI$ 52080 X$=RIGHT$ (X$,LEN (X$)-IC):GOTO 52010 52090 RETURN 52100 REM SATZ-TEILBEREICH LESEN ----------------------------------------------- 52101 : 52110 HB%=SA/256:LB%=SA-HB%*256 52112 PRINT#15,"P";CHR$ (3);CHR$ (LB%);CHR$ (HB%);CHR$ (1) 52114 INPUT#15,A:IF A=50 THENPRINT"SATZNUMMER ZU HOCH" 52120 IF A=50 THENRETURN 52130 INPUT#1,A$ 52140 WA=VAL (MID$ (A$,22,1)) 52150 WC=VAL (MID$ (A$,23,3)) 52160 A$=LEFT$ (A$,21) 52170 IF RIGHT$ (A$,1)="{RIGHT}" THENA$=LEFT$ (A$,LEN (A$)-1):GOTO 52170 52180 RETURN 53000 REM UP - TITELLINE ------------------------------------------------------- 53001 : 53010 I1$="{37SPACE}":T$="" 53020 T$=T$+CHR$ (18)+R$:I$=STR$ (SC)+"/"+RIGHT$ (STR$ (MO),LEN (STR$ (MO))-1) 53030 T$=T$+RIGHT$ (I1$,41-LEN (T$)-LEN (I$))+I$+CHR$ (146):PRINT"{HOME}";T$; 53040 PRINT"{22DOWN}";:RETURN 53200 REM UP - DISK EINLEGEN --------------------------------------------------- 53201 : 53205 IF IC=21 THENGOSUB 53700:REM WEITER 53210 PRINT"{RVSON}BITTE DISK-SEITE";SIDE;"{LEFT,SPACE}EINLEGEN !{RVOFF}";:POKE 198,0:WAIT 198,1 53220 PRINT"{29LEFT,29SPACE}"; 53221 PRINT"{29LEFT}"; 53222 OPEN 2,8,2,"#":PRINT#15,"U1 2 0 18 0":PRINT#15,"B-P";2;162:GET #2,I$ 53224 CLOSE 2:IF SIDE<>VAL (I$) THEN53200 53225 IF SIDE=2 THENOPEN 1,8,3,"TEXTE" 53230 RETURN 53400 REM ZEIGER POSTIONIEREN -------------------------------------------------- 53401 : 53420 HB%=SA/256:LB%=SA-HB%*256:PRINT#15,"P";CHR$ (3);CHR$ (LB%);CHR$ (HB%);CHR$ (1) 53430 INPUT#15,IA:IF IA=50 THENPRINT"SATZNUMMER ZU HOCH" 53440 RETURN 53500 REM SATZ EINLESEN -------------------------------------------------------- 53501 : 53510 IF A=50 THEN53520 53512 INPUT#1,I$ 53515 ZW=ZW+1:IF ZW>23 THENGOSUB 53700:ZW=0 53520 RETURN 53600 REM TEXT-EINLESEN -------------------------------------------------------- 53601 : 53610 IF SIDE<>2 THENSIDE=2:GOSUB 53200 53620 GOSUB 53400:REM POSITONIEREN 53630 GOSUB 53500:REM I$ EINLESEN 53640 IF RIGHT$ (I$,1)<>"*" THEN53660 53650 :IF I$<>"*" THENPRINTLEFT$ (I$,LEN (I$)-1) 53652 :SA=0:RETURN 53660 IF LEN (I$)<40 THENPRINTI$ 53670 IF LEN (I$)>=40 THENPRINTI$; 53680 SA=SA+1 53695 GOTO 53630 53700 REM WEITER --------------------------------------------------------------- 53701 : 53705 PRINT"[WEITER]";:POKE 198,0:WAIT 198,1:PRINT"{8LEFT,8SPACE,4LEFT,UP} 53710 RETURN 53800 REM KOMMENTAR LESEN ------------------------------------------------------ 53801 : 53805 ZW=1 53810 PRINT:GOSUB 53600:RETURN 53900 REM TEXTFORMER ------------------ 53901 : 53902 IF X$<>"" THENPRINT 53905 IF X$="" THEN53945 53910 IF LEN (X$)<40 THENPRINTX$:GOTO 53945 53915 IF LEN (X$)=40 THENPRINTX$;:GOTO 53945 53920 I$=LEFT$ (X$,41):IC=0:FOR I=1 TOLEN (I$):IF MID$ (I$,I,1)=" " THENIC=I 53925 NEXT I:IF IC=0 THENPRINTX$:GOTO 53945 53930 I$=LEFT$ (I$,IC-1):IF LEN (I$)=40 THENPRINTI$; 53935 IF LEN (I$)<40 THENPRINTI$ 53940 X$=RIGHT$ (X$,LEN (X$)-IC):GOTO 53905 53945 RETURN 53950 REM ARTIKEL-WANDLER ------------- 53951 : 53952 II$=LEFT$ (OB$,3) 53955 IF II$<>"DER"AND II$<>"DAS" THEN53965 53960 X$="":X$="HIER LIEGT EIN"+RIGHT$ (OB$,LEN (OB$)-3)+"." 53965 IF II$<>"DIE" THEN53970 53966 X$="":X$="HIER LIEGT EINE"+RIGHT$ (OB$(I),LEN (OB$)-3)+"." 53970 GOTO 53905 54000 REM RAUMTEXT-EINLESEN ---------------------------------------------------- 54001 : 54020 PRINT:FOR I=1 TOOZ :REM OB.TAB. 54030 :IF OB(I)<>ZN THEN54080 54035 :IF OX(I)<1 THEN54080 :REM NAMELOS 54040 :SA=OX(I):GOSUB 53400 :REM POSIT. 54050 :IF OA(I)=1 THENGOSUB 53500:R$=I$ :REM READ I$, TITELLINE 54060 :IF WI(ZN)=1AND VE<>11AND OA(I)=1 THENPRINTR$:SA=0:GOTO 54080 54070 :GOSUB 53600 :REM LESEN 54080 NEXT I 54081 FOR I=1 TOOZ 54083 IF OB(I)<>ZNOR OA(I)<>3OR OX(I)<>0 THEN54088 54084 SA=OS(I):GOSUB 53400:GOSUB 53500:OB$="D"+RIGHT$ (I$,LEN (I$)-1) 54085 X$="HIER LIEGT "+OB$+".":ZW=ZW+1:GOSUB 53950 54088 NEXT I 54095 WI(ZN)=1:PRINT:RETURN 60000 REM TABELLEN EINLESEN ---------------------------------------------------- 60001 : 63000 REM ***************************** 63005 REM * MINI-TEXTEDITOR V.III.4 * 63010 REM * <C> 1985 * 63015 REM * VON MICHAEL NICKLES * 63020 REM ***************************** 63025 REM ANFANGSMENUE ----------------- 63030 POKE 198,0:INPUT"{2DOWN}DATEINAME{2SPACE}*{3LEFT}";D$:POKE 198,0 63035 INPUT"SATZLAENGE{2SPACE}40{4LEFT}";SL:IF SL<1OR SL>254 THENPRINT"GEHT NICHT !":GOTO 30 63040 OPEN 15,8,15 63045 PRINT#15,"I0":OPEN 1,8,3,D$:PRINT 63050 REM ZWISCHENMENUE ---------------- 63055 PRINT"{RVSON}S / L / ENDE{SPACE,27SPACE,RVOFF}"; 63060 GET I$:IF I$="" THEN63060 63065 IF I$="E" THENPRINT"{CLR}";:GOTO 63265 63070 IF I$<>"S"AND I$<>"L" THEN63060 63075 INPUT"SATZNR";SA:IF SA<0 OR SA>63000 THEN63070 63080 IF I$="L" THENPRINT"{CLR}";:GOTO 63095 63085 IF I$="S" THENPRINT"{CLR}";:MO=1:GOTO 63150 63090 GOTO 63050 63095 REM LESEN ------------------------ 63100 :PRINT"{CLR,RVSON}";SA;"{LEFT}-";STR$ (SA+20);"{SPACE,RVOFF}" 63105 IA=SA 63110 FOR SA=IA TO IA+20 63115 : GOSUB 63195:GOSUB 63220 63120 : IF A=50 THENSA=IA+21:GOTO 63135 63125 : IF LEN (A$)<40 THENPRINTA$ 63130 : IF LEN (A$)>=40 THENPRINTA$; 63135 NEXT :PRINT 63140 IF A=50 THENPRINT"SATZNUMMER ZU HOCH!" 63145 GOTO 63050 63150 REM SCHREIBEN -------------------- 63155 PRINT"EINGABESATZ{2SPACE}//=KEINE EINGABE" 63160 GOSUB 63195:REM POSITIONIEREN 63165 IF A=50 THENPRINT"SATZNUMMER ZU HOCH!":GOTO 63050:REM FEHLERKANALABFR. 63170 GOSUB 63330:A$=BE$ :REM INPUT-ROUT. 63175 IF A$="//" THENMO=0:GOTO 63050:REM ENDE 63180 GOSUB 63240:REM A$ SCHREIBEN 63185 SA=SA+1 :REM NAECHSTER SATZ 63190 GOTO 63160:REM NEXT (LOOP) 63195 REM POSITIONIEREN **************** 63200 HB%=SA/256:LB%=SA-HB%*256 63205 PRINT#15,"P";CHR$ (3);CHR$ (LB%);CHR$ (HB%);CHR$ (1) 63210 INPUT#15,A 63215 RETURN 63220 REM SATZ EINLESEN **************** 63225 IF A=50 THENRETURN 63230 INPUT#1,A$ 63235 RETURN 63240 REM SATZ SCHREIBEN *************** 63245 IF A=50 THENRETURN 63250 IF A$="" THENA$=":":REM ZUR SICHERHEIT !!! 63255 PRINT#1,A$ 63260 RETURN 63265 REM BEENDEN ********************** 63270 CLOSE 1 63275 CLOSE 15 63280 PRINT "++ ENDE ++" 63285 END 63290 REM KORREKTUR-ROUTINE ------------ 63295 FOR I=0 TOLEN (BE$):PRINTCHR$ (20);:NEXT I:BE$="" 63300 SA=SA+SC : REM TEXTZEIGER 63305 IF SA<0 THENSA=0 : REM SPERRE 63310 GOSUB 63195: REM POSITIONIEREN 63315 IF A=50 THENSA=SA-SC:GOTO 63310 63320 INPUT#1,A$ 63325 RETURN 63330 REM TEXTEINGABE ------------------ 63335 IF AR=1 THENAR=0:A$="{RVSON}SATZNUMMER ZU HOCH!{RVOFF}":GOTO 63345 63340 GOSUB 63195:GOSUB 63220 63345 PRINT"{HOME,40SPACE}";:PRINT"{HOME,RVSON}SATZ";SA;"{RVOFF}" 63350 PRINT"{40SPACE,UP}";A$ 63355 PRINT"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"; 63360 PRINT"{DOWN}" 63365 BE$="":POKE 198,0:POKE 211,0:POKE 214,22:SYS 58732:PRINT"{YELLOW}@"; 63370 GET X$:IF PEEK (203)=1 THEN63430 63375 IF PEEK (203)=7AND PEEK (653)=0 THEN SC=1 : GOSUB 63290: GOTO 63330 63380 IF PEEK (203)=7AND PEEK (653)=1 THEN SC=-1 : GOSUB 63290: GOTO 63330 63385 IF X$="" THEN63370 63390 IF LEN (BE$)=0AND ASC (X$)=20 THEN63370 63395 I=ASC (X$):IF I<32OR I>133AND I<159 THENIF I<>20 THEN63370 63400 IF LEN (BE$)=SLAND I<>20 THEN63370 63405 IF X$=" " THENX$="{RIGHT}" 63410 BE$=BE$+X$ 63415 PRINTCHR$ (20);X$;"@"; 63420 IF I=20 THENBE$=LEFT$ (BE$,LEN (BE$)-2):GOTO 63370 63425 GOTO 63370 63430 PRINT"{LEFT,SPACE}":GOSUB 63195 63435 IF BE$="" THENBE$=":" 63440 PRINT"{HOME,24DOWN}":RETURN
60000 rem tabellen einlesen ---------------------------------------------------- 60001 : 60100 rem wortschatz-index ----------- 60110 dimin(26) 60120 fori=0to26:read in(i):nexti 60130 data 1,4,0,29,32,48,53,64,72,0,74,82,0,88,96,100,107,109,124,160,167 60140 data 170,190,0,0,201 60150 data 211 : rem buchstabe nach z ! 60200 rem objekt-tabelle ------------- 60210 oz=13:rem anzahl der objekte 60220 dim ob(oz),ox(oz),oa(oz),ou(oz),os(oz) 60230 fori=1tooz 60240 : readob(i),ox(i),oa(i),ou(i),os(i) 60250 nexti 60260 data 1,24 ,1,24 ,164:rem glaskuppel 60262 data 1,0 ,2,95 ,165:rem sand 60264 data 2,34 ,1,34 ,166:rem tunnel 60266 data 3,43 ,1,43 ,167:rem kr.grotte 60268 data 3,102,2,0 ,168:rem quader 60270 data 3,0 ,2,113,169:rem statue 60272 data 3,106,0,0 ,170:rem schwert 60274 data 0,0 ,3,79 ,171:rem zettel 60276 data 0,0 ,3,87 ,172:rem amulett 60278 data 0,76 ,2,91 ,173:rem grube 60279 data 0,161,2,0 ,174:rem oeffnung 60280 data 4,54 ,1,54 ,175:rem felsplat. 60282 data 3,0 ,2,97 ,176:rem kristalle 60500 rem landkarte ------------------ 60501 : 60510 dim map(4,10) 60520 fori=1to4 60530 : fori1=1to10 60540 : read map(i,i1) 60550 : nexti1 60560 nexti 60570 data 2,0,0,0,0,0,0,0,0,0 60572 data 3,1,0,0,0,0,0,0,0,0 60574 data 0,2,0,0,0,0,0,0,0,0 60576 data 0,0,0,3,0,0,0,0,0,0 60600 return
60000 REM TABELLEN EINLESEN ---------------------------------------------------- 60001 : 60100 REM WORTSCHATZ-INDEX ----------- 60110 DIM IN(26) 60120 FOR I=0 TO26:READ IN(I):NEXT I 60130 DATA 1,4,0,29,32,48,53,64,72,0,74,82,0,88,96,100,107,109,124,160,167 60140 DATA 170,190,0,0,201 60150 DATA 211 : REM BUCHSTABE NACH Z ! 60200 REM OBJEKT-TABELLE ------------- 60210 OZ=13:REM ANZAHL DER OBJEKTE 60220 DIM OB(OZ),OX(OZ),OA(OZ),OU(OZ),OS(OZ) 60230 FOR I=1 TOOZ 60240 : READ OB(I),OX(I),OA(I),OU(I),OS(I) 60250 NEXT I 60260 DATA 1,24 ,1,24 ,164:REM GLASKUPPEL 60262 DATA 1,0 ,2,95 ,165:REM SAND 60264 DATA 2,34 ,1,34 ,166:REM TUNNEL 60266 DATA 3,43 ,1,43 ,167:REM KR.GROTTE 60268 DATA 3,102,2,0 ,168:REM QUADER 60270 DATA 3,0 ,2,113,169:REM STATUE 60272 DATA 3,106,0,0 ,170:REM SCHWERT 60274 DATA 0,0 ,3,79 ,171:REM ZETTEL 60276 DATA 0,0 ,3,87 ,172:REM AMULETT 60278 DATA 0,76 ,2,91 ,173:REM GRUBE 60279 DATA 0,161,2,0 ,174:REM OEFFNUNG 60280 DATA 4,54 ,1,54 ,175:REM FELSPLAT. 60282 DATA 3,0 ,2,97 ,176:REM KRISTALLE 60500 REM LANDKARTE ------------------ 60501 : 60510 DIM MAP(4,10) 60520 FOR I=1 TO4 60530 : FOR I1=1 TO10 60540 : READ MAP(I,I1) 60550 : NEXT I1 60560 NEXT I 60570 DATA 2,0,0,0,0,0,0,0,0,0 60572 DATA 3,1,0,0,0,0,0,0,0,0 60574 DATA 0,2,0,0,0,0,0,0,0,0 60576 DATA 0,0,0,3,0,0,0,0,0,0 60600 RETURN
800 rem lesen -------------------- 805 ifve<>16then900 810 ifo1=8andob(8)=-1thensb=80 900 : 2000 rem raumspezifische action ------------------------------------------------ 2010 on zn goto 2100,2200,2300,2400 2100 rem glaskuppel 2110 ifve<>15oro1<>2then2120 2115 ifpa(0)<3thensb=71:pa(0)=pa(0)+1 2117 ifpa(0)=2thensb=73:ob(8)=zn:ob(9)=zn:ob(10)=1 2119 ifpa(0)=3thensb=72 2120 ifve=1ando1=3thenri=1:goto300 2130 goto100 2200 rem tunnel 2210 goto100 2300 rem kristallgrotte 2305 ifve=17ando1=6andou(6)=113thensb=119:ou(6)=135:goto2307 2306 ifve=17ando1=6andou(6)=135thenprint"Es passiert nichts." 2307 ifve<>12oro1<>7then2310 2308 ifou(6)=113thensb=110 2309 ifou(6)=135thensb=139:oa(7)=3:ob(7)=-1:ob(11)=3:map(3,3)=4:ox(7)=0 2310 ifve=1ando1=3thenri=3:goto300 2320 goto100 2400 rem felsplateau 2410 goto100
800 REM LESEN -------------------- 805 IF VE<>16 THEN900 810 IF O1=8AND OB(8)=-1 THENSB=80 900 : 2000 REM RAUMSPEZIFISCHE ACTION ------------------------------------------------ 2010 ON ZN GOTO 2100,2200,2300,2400 2100 REM GLASKUPPEL 2110 IF VE<>15OR O1<>2 THEN2120 2115 IF PA(0)<3 THENSB=71:PA(0)=PA(0)+1 2117 IF PA(0)=2 THENSB=73:OB(8)=ZN:OB(9)=ZN:OB(10)=1 2119 IF PA(0)=3 THENSB=72 2120 IF VE=1AND O1=3 THENRI=1:GOTO 300 2130 GOTO 100 2200 REM TUNNEL 2210 GOTO 100 2300 REM KRISTALLGROTTE 2305 IF VE=17AND O1=6AND OU(6)=113 THENSB=119:OU(6)=135:GOTO 2307 2306 IF VE=17AND O1=6AND OU(6)=135 THENPRINT"ES PASSIERT NICHTS." 2307 IF VE<>12OR O1<>7 THEN2310 2308 IF OU(6)=113 THENSB=110 2309 IF OU(6)=135 THENSB=139:OA(7)=3:OB(7)=-1:OB(11)=3:MAP(3,3)=4:OX(7)=0 2310 IF VE=1AND O1=3 THENRI=3:GOTO 300 2320 GOTO 100 2400 REM FELSPLATEAU 2410 GOTO 100
0 rem *******************************
1 rem * *
2 rem * adventure-cracker *
3 rem * version 1.0 *
4 rem * von mright$chael nickles *
5 rem * *
6 rem *******************************
10 print"{clr}{rvon}adventure-cracker version 1.0 {rvof}";
20 print"{down}bitte disk mit spiel einlegen {rvon}return{rvof}"
25 poke198,0:wait198,1
30 open1,8,15:open2,8,2,"#"
50 rem hauptmenue
51 print"{rvon}einzel / alles"
52 getx$:ifx$=""then52
55 ifx$="e"then200
57 ifx$="a"then100
58 goto52
100 rem alle daten von disk lesen
105 input"ab welchem track ";an
110 for t=an to 35: rem tracks
112 rem as=anzahl der sektoren
113 if t<18 then as=21
114 if t>17andt<25 then as=19
115 if t>24andt<31 then as=18
116 if t>30 then as=17
118 for s=1 to as: rem sectors
120 gosub1000:rem daten in buffer lesen
130 gosub2000:rem daten ausdrucken
140 next s
150 next t
200 rem einzelne daten lesen
201 print
205 input"track ";t
206 input"sektor ";s
210 ift<1ort>35then200
211 ifs<1then200
212 ift<18ands>21then200
213 ift>17andt<25ands>19then200
214 ift>24andt<31ands>18then200
215 ift>30ands>17then200
220 gosub1000
230 gosub2000
250 goto200
1000 :
1001 rem daten in buffer lesen
1002 :
1005 print#1,"u1 2 0 ";t;s
1010 return
2000 :
2001 rem buffer auslesen
2002 :m$=""
2010 fori=0to255
2020 : get#2,a$
2021 ifa$=""then2030
2022 m=asc(a$) : rem checken
2023 ifm>64andm<91thenprinta$;
2024 ifm>96andm<123thenprinta$;
2030 ifm=46orm=58orm=59orm=63orm=32orm=160orval(a$)>0thenprinta$;
2040 nexti
2050 return
0 REM ******************************* 1 REM * * 2 REM * ADVENTURE-CRACKER * 3 REM * VERSION 1.0 * 4 REM * VON MRIGHT$CHAEL NICKLES * 5 REM * * 6 REM ******************************* 10 PRINT"{CLR,RVSON}ADVENTURE-CRACKER VERSION 1.0{11SPACE,RVOFF}"; 20 PRINT"{DOWN}BITTE DISK MIT SPIEL EINLEGEN{SPACE,RVSON}RETURN{RVOFF}" 25 POKE 198,0:WAIT 198,1 30 OPEN 1,8,15:OPEN 2,8,2,"#" 50 REM HAUPTMENUE 51 PRINT"{RVSON}EINZEL / ALLES" 52 GET X$:IF X$="" THEN52 55 IF X$="E" THEN200 57 IF X$="A" THEN100 58 GOTO 52 100 REM ALLE DATEN VON DISK LESEN 105 INPUT"AB WELCHEM TRACK ";AN 110 FOR T=AN TO 35: REM TRACKS 112 REM AS=ANZAHL DER SEKTOREN 113 IF T<18 THEN AS=21 114 IF T>17AND T<25 THEN AS=19 115 IF T>24AND T<31 THEN AS=18 116 IF T>30 THEN AS=17 118 FOR S=1 TO AS: REM SECTORS 120 GOSUB 1000:REM DATEN IN BUFFER LESEN 130 GOSUB 2000:REM DATEN AUSDRUCKEN 140 NEXT S 150 NEXT T 200 REM EINZELNE DATEN LESEN 201 PRINT 205 INPUT"TRACK ";T 206 INPUT"SEKTOR ";S 210 IF T<1OR T>35 THEN200 211 IF S<1 THEN200 212 IF T<18AND S>21 THEN200 213 IF T>17AND T<25AND S>19 THEN200 214 IF T>24AND T<31AND S>18 THEN200 215 IF T>30AND S>17 THEN200 220 GOSUB 1000 230 GOSUB 2000 250 GOTO 200 1000 : 1001 REM DATEN IN BUFFER LESEN 1002 : 1005 PRINT#1,"U1 2 0 ";T;S 1010 RETURN 2000 : 2001 REM BUFFER AUSLESEN 2002 :M$="" 2010 FOR I=0 TO255 2020 : GET #2,A$ 2021 IF A$="" THEN2030 2022 M=ASC (A$) : REM CHECKEN 2023 IF M>64AND M<91 THENPRINTA$; 2024 IF M>96AND M<123 THENPRINTA$; 2030 IF M=46OR M=58OR M=59OR M=63OR M=32OR M=160OR VAL (A$)>0 THENPRINTA$; 2040 NEXT I 2050 RETURN
PROGRAMM : MS 1400 16B0 ----------------------------------- 1400 : A2 0F 20 C9 FF 20 FD AE C1 1408 : 20 8A AD 20 F7 B7 A9 50 61 1410 : 20 D2 FF A9 08 20 D2 FF 9B 1418 : A5 14 20 D2 FF A5 15 20 EB 1420 : D2 FF A9 01 20 D2 FF 20 55 1428 : CC FF A2 08 20 C6 FF A2 1B 1430 : 00 20 CF FF 9D FA 04 C9 89 1438 : 0D F0 03 E8 D0 F3 E0 28 1C 1440 : D0 05 A9 00 9D FA 04 E8 91 1448 : A9 00 9D FA 04 20 CC FF 2C 1450 : A2 FF E8 BD FA 04 D0 FA ED 1458 : CA BD FA 04 C9 0D F0 F8 FB 1460 : C9 2A F0 2F A2 00 BD FA 77 1468 : 04 F0 06 20 D2 FF E8 D0 DC 1470 : F5 A5 14 18 69 01 85 14 1D 1478 : A5 15 69 00 85 15 EE F9 B3 1480 : 04 AD F9 04 C9 16 D0 03 F0 1488 : 20 B9 04 A2 0F 20 C9 FF F3 1490 : 4C 0E 04 A9 0D 9D FA 04 CB 1498 : E8 A9 00 9D FA 04 A2 00 63 14A0 : BD FA 04 F0 06 20 D2 FF A6 14A8 : E8 D0 F5 EE F9 04 AD F9 BE 14B0 : 04 C9 16 D0 03 20 B9 04 59 14B8 : 60 A9 00 8D F9 04 A2 00 E9 14C0 : BD E5 04 F0 06 20 D2 FF 3C 14C8 : E8 D0 F5 A9 00 85 C6 A5 5D 14D0 : C6 F0 FC A2 00 BD F0 04 5B 14D8 : F0 06 20 D2 FF E8 D0 F5 A4 14E0 : A9 00 85 C6 60 12 5B 57 76 14E8 : 45 49 54 45 52 5D 92 00 EA 14F0 : 14 14 14 14 14 14 14 14 F0 14F8 : 00 00 00 00 00 00 00 00 F9 1500 : 00 00 00 00 00 00 00 00 01 1508 : 00 00 00 00 00 00 00 00 09 1510 : 00 00 00 00 00 00 00 00 11 1518 : 00 00 00 00 00 00 00 00 19 1520 : 00 00 00 00 00 00 00 00 21 1528 : A9 40 8D 04 D4 A9 0F 8D C7 1530 : 18 D4 A2 1E A0 86 8E 00 97 1538 : D4 8C 01 D4 A2 00 A0 A0 1B 1540 : 8E 05 D4 8C 06 D4 A9 00 C5 1548 : 8D F9 04 A9 3E 20 D2 FF 38 1550 : A9 A4 20 D2 FF A9 00 8D 16 1558 : AF 06 A9 00 85 C6 A5 C6 27 1560 : F0 FC AD 77 02 A2 00 DD 1A 1568 : 5D 06 F0 08 E8 E0 52 D0 86 1570 : F6 4C 77 05 4C B5 05 C9 25 1578 : 0D D0 15 AD AF 06 F0 2F 36 1580 : A9 9D 20 D2 FF A9 20 20 68 1588 : D2 FF 20 F8 05 4C 08 06 60 1590 : C9 14 D0 1B AD AF 06 F0 4D 1598 : 16 A9 14 20 D2 FF 20 D2 DF 15A0 : FF A9 A4 20 D2 FF 20 F8 41 15A8 : 05 CE AF 06 4C 5A 05 20 AD 15B0 : 36 06 4C 5A 05 AC AF 06 C8 15B8 : C0 4D F0 36 AE AF 06 9D DD 15C0 : B0 06 A9 9D 20 D2 FF BD A5 15C8 : B0 06 20 D2 FF A9 A4 20 FE 15D0 : D2 FF EE AF 06 BD B0 06 70 15D8 : C9 22 D0 10 20 D2 FF A9 D4 15E0 : 14 20 D2 FF 20 D2 FF A9 A5 15E8 : A4 20 D2 FF 20 F8 05 4C C7 15F0 : 5A 05 20 36 06 4C 5A 05 D2 15F8 : A9 41 8D 04 D4 A2 00 E8 5A 1600 : D0 FD A9 80 8D 04 D4 60 56 1608 : A9 00 85 C6 20 FD AE AD F3 1610 : AF 06 20 7D B4 A0 00 B9 3E 1618 : B0 06 91 62 C8 CC AF 06 3A 1620 : D0 F5 20 8B B0 85 FB 84 94 1628 : FC A2 02 A0 02 B5 61 91 80 1630 : FB CA 88 10 F8 60 A2 0A E6 1638 : 8E 00 D4 8E 01 D4 A9 21 6D 1640 : 8D 04 D4 A2 B0 A0 00 C8 FA 1648 : D0 FD E8 D0 F8 A9 80 8D 65 1650 : 04 D4 A6 1E A4 86 8E 00 E4 1658 : D4 8C 01 D4 60 41 42 43 ED 1660 : 44 45 46 47 48 49 4A 4B 50 1668 : 4C 4D 4E 4F 50 51 52 53 58 1670 : 54 55 56 57 58 59 5A 30 09 1678 : 31 32 33 34 35 36 37 38 68 1680 : 39 2C 2E 20 21 23 24 25 65 1688 : 26 27 28 29 2B 2D 3A 3B ED 1690 : 2F 3F 40 2A 22 C1 C2 C3 77 1698 : C4 C5 C6 C7 C8 C9 CA CB 87 16A0 : CC CD CE CF D0 D1 D2 D3 8F 16A8 : D4 D5 D6 D7 D8 D9 DA 00 DF
10 open 1,8,0,"ms":get#1,a$:get#1,a$ 20 fori=1024to1718:get#1,a$:a$=a$+chr$(0):pokei,asc(a$):nexti:close1
10 OPEN 1,8,0,"MS":GET #1,A$:GET #1,A$ 20 FOR I=1024 TO1718:GET #1,A$:A$=A$+CHR$ (0):POKE I,ASC (A$):NEXT I:CLOSE 1