Schiebe-Puzzle ByPixx
ByPixx
ByPixx

Genau wie ByPuzz ist ByPixx ein 4×4-Schiebe-Puzzle. Hier sind es jedoch nicht Zahlen, sondern Bilder (im PETSCII-Format), die nach einem automatischen Mischen (in drei Schwierigkeitsstufen) in die ursprüngliche Anordnung zurückgebracht werden müssen. Dazu werden die 15 Teile, auf denen sich das Bild befindet, über eine sechzehnte, leere Stelle solange verschoben, bis das Bild fertig ist. Die Anzahl der Züge, die man dafür braucht, wird mitgezählt und unter dem Titelkasten angezeigt (hier in Bild 2: 0, da das Spiel noch nicht begonnen wurde).

gemischtBild 1: Vor dem MischenByPixx zeigt nach dem Start die Namen von maximal 22 auf der Disk gespeicherter Puzzle-Bilder an, aus denen man auswählen kann oder aus denen vom Programm eins per Zufall zum Spielen bestimmt wird.

Die Bilder stammen alle von der britischen Webseite Retro Gallery (die sich natürlich hauptsächlich aus der CSDb speist). Wie sie von mir bearbeitet wurden, damit sie zu ByPixx passen, folgt weiter unten. Ich danke hiermit allen mit Bildern in ByPixx vertretenen Künstlern für ihre hervorragenden Werke und zugleich den Urhebern der nötigen Tools für ihre ebenfalls unschätzbare Arbeit. Auch dazu weiter unten mehr. Zurück zu ByPixx:

Die Spielsteine verschiebt man wie in ByPuzz mit der Tastatur, mit dem Joystick oder mit einer 1351-kompatiblen Maus. Bei Mausbedienung muss man den Stein, der sich bewegen soll, anklicken. Bei Tastatur- und Joystick-Bedienung bewegt man die dem Leerfeld benachbarten Steine in Richtung des Leerfeldes.

Zur bequemeren Handhabung gibt es eine Reihe von Tastatur-Shortcuts, die immer verwendet werden können:

MischenBild 2: Nach dem MischenIm Konfigurationsbildschirm gleich nach dem Start des Programms kann man als Bedienungstasten andere Tasten als die Cursor-Tasten auswählen (z.B. "WASD" für Linkshänder oder "OKL:" für rechtshändige Spieler auf dem Original-C64, wodurch man sich den Einsatz der Shift-Taste erspart). Was eingestellt ist, erkennt man an der grünen Hervorhebung.

Auch in der direkt nach dem Konfigurieren erscheinenden Vorschau des Ziel-Puzzles funktionieren die Tasten "X" und "R". Man vermeidet damit den evtl. ungewollten langen Mischvorgang, wenn man ein Bild zufällig hat auswählen lassen und es einem gerade nicht gefällt.

Das "Mischen" dauert - je nach eingestelltem Spielgrad - ziemlich lange. Es endet mit einem Prüflauf, in dem getestet wird, welche Spielsteine bereits an ihrer richtigen Position liegen (diese Steine blinken kurz grün und werden in einem Kasten oben rechts mitgezählt, im Bild 2 befinden sich 3 der 15 Steine bereits an der richtigen Position).

Alle anderen Funktionen kann man in der Anleitung zu ByPuzz nachlesen.

Download ByPixx (zwei D64 in einer ZIP-Datei)

<nach oben>


Wie kommt man nun an diese beeindruckend schönen PETSCII-Bilder heran? Und wie kriegt man sie in eine Form, mit der ByPixx etwas anfangen kann?

Die Webseiten, auf denen man fündig wird, habe ich ja schon genannt. Hier noch einmal die Links: Retro Gallery und CSDb. Die Bilder liegen dort entweder als Screenshot oder als ausführbare Datei vor. Für die Konvertierung in ein ByPixx-Bild brauchen wir ein PETSCII-Bild im PNG-, JPG- oder GIF-Format.

Die von mir verwendeten Tools sind geradezu ideal für ByPixx: XnView (um die Bilder, wenn nötig, auf die richtige Größe von 320×200 Pixeln zu beschneiden), Marq's PETSCII Editor (verwandelt Grafik in PETSCII-Zeichen und legt sie in einem eigenen Text-Format ab) und Georg Rottensteiners C64Studio (das dieses Format kennt und daraus Basic-DATA-Zeilen generieren kann). Zum Schluss kommt ein TSB-Tool von mir zum Einsatz (befindet sich auf der Release-Disk von ByPixx).

BeispielBild 3: Beispiel PETSCIIZeigen wir das Vorgehen an einem Beispiel: "prey - Morgan Yu I" von Chris2Balls. Auf CSDb liegt es als ausführbares Programm vor, das wir in VICE einfach starten können.

1. Schritt: Die Farben von VICE stellen wir zuerst auf die Pepto-Palette um, da das Konvertierprogramm von Marq von dieser Palette ausgeht (sonst entstehen Farbfehler). Wird das Bild angezeigt, machen wir einen Screenshot (mit der "Druck"-Taste) und schneiden das PETSCII-Bild aus dem Screenshot heraus (Bild 3). Wenn es nicht die Maße 320×200 hat, passen wir das an (in XnView: Bild - Größe ändern). Abgespeichert wird es im GIF-Format.

2. Schritt: Nun kommt das nächste Tool ins Spiel, Marqs "PETSCII Editor". Ist dieses Programm gestartet, könnte man damit jetzt eigene PETSCII-Bilder malen, es bietet dafür alle nötigen Werkzeuge und stellt die in PETSCII vorhandenen Zeichen sehr übersichtlich, in Funktionsgruppen zusammengefasst, dar (Bild 4). Unser Ziel ist jedoch, eine bereits fertige PETSCII-Vorlage, die allerdings nicht in PETSCII-Form vorliegt, zurückzuverwandeln in PETSCII. Dazu dient der Button Ref (für "Reference").

Unter einer Referenz versteht der Editor so etwas wie einen Lighttable aus der Zeichentrick-Technik: Um eine neue Trickphase zu zeichnen, nimmt man das vorige Bild als Unterlage, lässt Licht hindurchscheinen und kann auf einem darauf liegenden neuen Blatt die nächste Trickphase passgenau eintragen. So auch hier: Nach Ref sieht man das geladene Bild halb durchscheinend im Bearbeitungsbereich des Editors und könnte jetzt versuchen, von Hand das Ganze aus PETSCII-Zeichen nachzuempfinden.

PETSCII EditorBild 4: Der PETSCII-EditorDas wäre sehr mühsam und das Tool wäre nur halb so brauchbar, wenn es nicht eine Funktion aufwiese, die die ganze Handarbeit automatisieren würde. Und genau diese Funktion gibt es auch. Wir stellen mit der rechten Maustaste in der Palettenleiste rechts oben die Hintergrundfarbe ein (hier: schwarz, erkennbar am roten Dreieck links oben im Farbkasten) und drücken dann einfach auf einem leeren Blatt (wo nur das Referenzbild zu sehen ist) die Taste Shift-T und schon ist das Grafikbild umgewandelt in ein PETSCII-Bild (Bild 4). Sollte das Ergebnis nicht den Erwartungen entsprechen, ist wahrscheinlich eine falsche Hintergrundfarbe daran schuld. Wir wiederholen in dem Fall den ganzen Vorgang: zuerst Clear und dann weiter wie eben beschrieben, bis wir ein akzeptables Bild vor uns sehen.

Dieses Bild speichern wir nun in Marqs Editor-Format ab (Save as). Es entsteht eine reine Textdatei mit dem Dateisuffix ".c". Um genau zu sein, handelt es sich um eine Datei, die direkt in ein C-Programm eingebunden werden könnte, sie enthält die entsprechenden Anweisungen, die Border- und Hintergrundfarbe, die Codes der 1000 PETSCII-Zeichen in Dezimalform und die Codes der 1000 Farben, ebenfalls dezimal. Zum Schluss steht in der Datei, auf welchen C64-Zeichensatz sie sich bezieht (meist C64 Upper).

3. Schritt: Im Tool C64Studio können wir in der Abteilung Char Screen Editor (im Menü Window) den Text Screen Editor aufrufen. Dort aktivieren wir den Reiter Import, lassen die Voreinstellung "from binary file" bestehen (auch wenn es sich um eine Textdatei handelt) und klicken den Button Import an. Im aufklappenden Dateirequester navigieren wir zum Verzeichnis, in dem die .C-Dateien zu finden sind. Alle unterstützten Dateien ("Charpad Project (*.ctm)" und "Marq'PETSCII Editor File (.c)") erscheinen in der Liste, auch der Name unserer eben in Schritt 2 abgespeicherten PETSCII-Datei. Wir öffnen sie und weil sich im C64Studio scheinbar nichts getan hat, wechseln wir den Dateireiter auf Screen. Voilá! Da ist das Bild!

C64StudioBild 5: Das C64StudioJetzt folgt der für ByPixx entscheidende Vorgang. In ByPixx brauchen wir vom PETSCII-Bild einen 20×20 Zeichen großen Ausschnitt. Den erzeugen wir mit dem Button Selection (links neben dem T-Button). Wir spannen damit einen grünen Rahmen auf, dessen Größe unterhalb des Bildfensters angezeigt wird (hier: Selection 10,0 20*20, s. Bild 5). Korrigieren ist einfach: der vorherige Rahmen bleibt solange sichtbar, bis man den neuen aufgezogen hat. C64Studio übernimmt die Hintergrundfarbe aus der .C-Datei, wir müssen sie also nicht von Hand einstellen (die häufigste Farbe ist aber schwarz, die auch in unserem Beispiel vorlag).

Diesen Ausschnitt exportieren wir jetzt als Basic-Datei. Dazu aktivieren wir den Reiter Export, stellen dort die Export Area auf "Selection", die Export Method auf "as BASIC Data statements", die Start Line auf 6000, die Einstellung der Zeilenlänge mit Wrap at auf 64 und haken die Option "Export with Hex notation" an. Daraufhin erscheinen im großen Fenster rechts sehr kompakt die Basic-Zeilen, in jeder stehen die Codes für 20 Zeichen/Farben.

Diese Datei kopieren wir über die Zwischenablage (einen anderen Weg habe ich nicht gefunden) in eine Basic-Datei, die wir ebenfalls im C64Studio anlegen können: Menü File - New - BASIC File - Namen eingeben. Damit ist die für ByPixx vorbereitete PETSCII-Datei gesichert.

4. Schritt: Es wird langsam Zeit, dass TSB ins Spiel kommt, damit ByPixx endlich mit den vorbereiteten Puzzles gefüttert werden kann. Sie müssen dazu im TSB-Screen-Format vorliegen, das mit dem Befehl SCRSV generiert wird. Das entsprechende TSB-Tool dafür liegt auf der ByPixx-Diskette unter dem Namen "makebypixx.tsb" vor. In dieses Programm müssen wir die im C64Studio erzeugten Basic-Daten einbauen.

Dazu laden wir "makebypixx.tsb" (unter TSB) und löschen zuerst die Daten des zuletzt abgespeicherten Durchgangs mit D! 6000-. Dann schauen wir in der Zeile 1030 nach, ob die Farbeinstellungen in Ordnung sind: LIST 1030. Es erscheint so etwas wie dies:

1030 bg= 0:pn=15:sf=16

Wobei BG die Farbe des Hintergrunds enthält (hier: 0, also schwarz), mit PN ist die Vordergrundfarbe gemeint (das ist die Schreibfarbe, in der ByPixx alle Bildschirmausgaben macht, hier: 15, also hellgrau) und - ganz wichtig! - in SF steht die Nummer des Leerfeldes im Puzzle (1 bis 16, in Bild 6: 16, das ist rechts unten), das ja bisher noch nirgends definiert wurde. Diese Werte muss man von Hand in Zeile 1030 eintragen. Der Name des Puzzles auf Disk ist fest vorgegeben (in Zeile 1020) und lautet "screen".

Für die Arbeit mit VICE kopiert man sich im C64Studio die Data-Zeilen des Bildes in die Zwischenablage und injiziert diese Zeilen in VICE mit Alt-Einfg ins makepixx-Programm hinein (darauf achten, dass im C64Studio die Groß-Kleinschrift eingeschaltet ist). Für einen echten C64 (oder Emulatoren, bei denen Code-Injektion nicht funktioniert) führt man im C64Studio die Data-Zeilen als Programm aus (mit F7, Build) und überträgt das Ergebnis dann auf eine Disk, von der es letztendlich per MERGE "datazeilen" ins makebypixx.tsb eingebaut wird.

makebypixxBild 6: Das fertige Puzzle in makebypixxIst alles soweit vorbereitet, startet man makebypixx.tsb mit RUN. Der Bildschirm wird aufgebaut und man erhält den endgültigen Eindruck des Puzzles, jetzt auch mit Leerstelle. Gefällt einem etwas nicht (Farben ungünstig, Leerstelle verkehrt o.ä.), drückt man irgendeine Taste, um ins Basic zurückzukehren und die Änderungen vorzunehmen.

War jedoch alles in Ordnung und man möchte dieses Puzzle abspeichern, drückt man auf die Taste "s" (für "Speichern") und legt damit das Puzzle "byp.screen" an. Sollen noch mehr Puzzles folgen, benennt man byp.screen schnell um: DISK "r:byp.neuer name=byp.screen" und wiederholt den gesamten hier beschriebenen Vorgang für das nächste Puzzle.

Beachten: ByPixx kann nicht mehr als 22 Puzzles verwalten. Sind mehr auf Disk, zeigt es nur die letzten 22 davon an. Möchte man mit mehr Puzzles spielen, muss man sich entweder eine weitere Diskette anlegen oder aber auf einer Diskette mit vielen Puzzles alle diejenigen im Namen unkenntlich machen (z.B. aus dem Präfix "byp." die Zeichenfolge "byp!" machen), die man gerade nicht spielen will.

Viel Spaß mit ByPixx!

<nach oben>


Auch hier wieder ein paar Worte zur Programmierung, vor allem zu ein paar Tricks, ohne die ByPixx nicht funktionieren würde.

Da ist vor allem der Varpntr-SYS für die Einbindung von relokatiblen Maschinensprache-Add-Ons (womit in ByPixx das Backup des aktuellen Spielstands bei der Anzeige der Vorschau auf das fertige Puzzle ermöglicht wird). Außerdem verwendet das Programm die Kurzverzögerung mit dem Jiffy-Zähler und zum Dritten eine Tastatur-Entprellung, falls man ByPixx auf einem Emulator laufen lässt und die Bedienung beschleunigen möchte, ohne immer wieder Mehrfachzüge auszulösen.

Die Maschinensprache-Routine in ByPixx patcht den TSB-Befehl MOVE, mit dem man Teile der Anzeige auf dem Bildschirm an andere Stellen auf dem Bildschirm versetzen kann. Der Patch sorgt nun dafür, dass der zu verschiebende Teil nicht wieder im Bildschirm, sondern an einer ganz anderen, freien Stelle im C64-Speicher landet (in ByPixx im Bereich $6000) und von dort auch wieder zurückgeholt werden kann: er macht ein Backup des angegebenen Bildschirmbereichs. Er greift an der Stelle der MOVE-Routine ein, an der die Verschiebung durchgeführt werden soll. Hier die beiden Routinen:

; SYS m1: Backup Screen

m1      lda $21                ; adjust hibyte of destination
        and #$0f
patch1: ora #$f0               ; here: argument $f0 gets patched in program (to $60)
        sta $21
        jmp $a00e              ; transport (to $6xxx, pre TSBneo: $ae02)

; SYS m2: Restore Screen

m2      sei                    ; open RAM under kernal
        lda #$35               ; (note: this behavior only necessary when routine was not patched!)
        sta $01
        lda $24                ; adjust highbyte of source
        and #$0f
patch2: ora #$f0               ; again: argument $f0 gets patched in program (to $60)
        sta $24
        jsr $a00e              ; and transport from there to screen/color ram (pre TSBneo: $ae02)
        lda #$36               ; back to Basic RAM
        sta $01                ; (see note above)
        ldx #$00               ; .x=0: just make sure that equal flag is on
        cli
        rts

Manipuliert wird der Aufruf der TSB-Routine moveit ($a00e, früher: $ae02) an Adresse $9f22/3 (früher: $ad16/7). Die Zieladresse des Transports wird dabei von Basic aus auf den Speicher bei $6000 (statt $f000) gerichtet, weil im Spiel der Bereich jenseits von $e000 bereits vom geänderten Zeichensatz gebraucht wird. So wird die Manipulation in der Prozedur init vorbereitet. Die Maschinenroutine wird nach dem Varpntr-Trick in einen Basic-String übertragen, per POKE, damit kein Stringmüll entsteht (Z.1025 und Z.1040):

1015 m1$=dup(" ",11): sys $8b65 m1$      :rem pre neo: $8096
1020 x=256*peek(782)+peek(780):wl=peek(x+1):wh=peek(x+2):m1=d!peek(x+1)
1025 reset 1400:for i=0 to 10:read x$:poke m1+i,nrm(x$):next
1030 m2$=dup(" ",24): sys $8b65 m2$      :rem pre neo: $8096
1035 x=256*peek(782)+peek(780):gl=peek(x+1):gh=peek(x+2):m2=d!peek(x+1)
1040 reset 1410:for i=0 to 23:read x$:poke m2+i,nrm(x$):next

1400 data a5,21,29,0f,09,f0,85,21
1405 data 4c,0e,a0                       :rem pre neo: 02,ae instead of 0e,a0
1410 data 78,a9,35,85,01,a5,24,29
1420 data 0f,09,f0,85,24,20,0e,a0        :rem pre neo: 02,ae instead of 0e,a0
1430 data a9,36,85,01,a2,00,58,60

Und so wird der Patch durchgeführt (hier in der Prozedur hilfe ab Zeile 2500 im Programm). Zuerst das Backup. Patchen auf $6000-Bereich, manipulieren des moveit-Aufrufs (an $9f22/3 - früher: $ad16/7 - gemäß M1 aus Z.1020) und MOVE mit Transport an scheinbar die gleiche Zielposition wie die Quelle (aber jetzt im Bereich $6000, PY/PX):

2505 poke m1+5,$60:d!poke $9f22,m1: move py,px,w*4,w*4,py,px     : rem pre neo: $ad16

Und dann die Restore-Routine. Auch hier der Patch auf $6000 und die Umlenkung des moveit-Aufrufs, diesmal auf die Restore-Routine (per M2 aus Z.1035) und MOVE an scheinbar gleiche Positionen. Wichtig am Schluss: die Umlenkung muss zurückgenommen werden, da der MOVE-Befehl in seiner Normalform auch sonst in ByPixx eine große Rolle spielt (Z.2588, Wiederherstellen der ursprünglichen moveit-Adresse $ae02):

2587 poke m2+10,$60:d!poke $9f22,m2: move py,px,w*4,w*4,py,px     : rem pre neo: $ad16
2588 d!poke $9f22,$a00e                                           : rem pre neo: $ad16 and $ae02

Wenn man kleinere Pufferbereiche ansteuern will (hier in ByPixx wird sehr großzügig verfahren), muss die Patch-Routine geändert werden, da dann sicher auch die Low-Bytes der Zieladressen betroffen wären.

 

Nun zur Entprell-Routine (beigetragen von Forum64-User Christian Nennewitz, @Omega). Immer wenn ein Rechner sehr schnell arbeitet, kann es dazu kommen, dass Tastendrücke so schnell abgefragt werden, dass der Benutzer zu langsam ist für einzelne Tastendrücke. Folge: ein Buchstabe/eine Aktion wird mehrfach ausgeführt, was natürlich niemand möchte. Folgende einfache Routine wartet bei jedem Tastendruck darauf, dass die Taste wieder losgelassen wird, löscht dann den Tastaturpuffer und macht erst dann im Programm weiter.

Ab Zeile 3500 wird in ByPixx ein Tastendruck ausgewertet und das Ergebnis der Variablen C zugewiesen. Erste Entprellmaßnahme: der Zwischenspeicher für Tastendrücke ($c5ec) wird gelöscht. Und dann die Hauptmaßnahme: der Aufruf der Prozedur entprell. In Speicherstelle 197 meldet der C64, welche Taste gerade gedrückt wird. Der Wert 64 ist der Code für <keine Taste>. Die Routine entprell macht also erst weiter, wenn die zuletzt gedrückte Taste losgelassen wird (Z.4310). Damit Tastendrücke auch wirklich alle verworfen werden, wird über Speicherstelle 198 mit dem Wert 0 festgelegt, dass der Tastaturpuffer leer zu sein hat.

3500 proc auswertung
3505 c=peek($c5ec):poke $c5ec,0: entprell
3510 if tt=0 then do
3515 if c=29 then t=3
[...]
4300 proc entprell
4310 repeat:until peek(197)=64:poke 198,0
4320 end proc

So viel zur Programmierung von ByPixx (weitere Einzelheiten bei ByPuzz)!

<nach oben>