Hallo Besucher, der Thread wurde 3,5k mal aufgerufen und enthält 19 Antworten

letzter Beitrag von Bytebreaker am

Char Rotation in Loco Basic - auch in CBM machbar?

  • Hallo,


    evtl. sogar thematisch passend zur aktuellen ASM Rotations-Compo ein kleines Experiment in Amstrad CPC Basic.


    @ Tale-X:


    Mir ist Dein genialer kleiner CharROM Sprite Reader nur zu klar im Gedächtnis, das war auch die Inspiration für die vorliegende kleine Spielerei. Siehst Du einen Weg, ein gescanntes Char Sprite zu rotieren, und zwar nicht 90 Grad als fixe Bitkopier-Schleife, sondern um ein frei definierbares Bogenmaß. Kann auch C128 Basic sein.


    Der Schlüssel beim CPC ist der "Test" Befehl. Der gibt mir die Farbe eines beliebigen Pixels, dessen Koordinaten ich angebe. Das ist sozusagen der im CPC Basic eingebaute Reader.


    Es wäre schön wenn wir die Compo Idee in Basic umsetzen könnten und evtl. erweitern, indem wir Bogenmaß-Rotation ermöglichen.


    Natürlich sind auch Jeek, RKSoft, Hexworx und alle anderen eingeladen hier mitzudenken und beizutragen.


    Edit: Ich habe keinen txt Quellcode, ich habe direkt in WinCPC gearbeitet. mode 2 (return) load"charrot.bas" (return) und dann list (return) zum Einsehen des Quellcodes. Er ist deutsch kommentiert.


    http://www.cpcwiki.eu/forum/de…asic/msg139588/#msg139588

  • Im CPCWiki schreibst Du:

    Zitat von Bytebreaker

    I was thinking hard if such effects can be ported to C128, Plus/4 or C64. As far as I am aware, even the advanced Commodore 3.5 and 7.0 BASIC versions do not have an equivalent to the "test" command, which was the key to realize this little project without using machine language.

    Doch, das geht. Der Befehl LOCATE X,Y und die Funktion RDOT(2) sind deine Freunde. :)


    Und mit MINIGRAFIK auf dem VC-20 gibt's das kombiniert in einer Funktion, @(X,Y). Damit lassen sich z.B. Bildausschnitte mit zwei geschachtelten FOR-Schleifen und einem Plot-Kommando, etwa wie so:

    Code
    1. FOR DY=0 TO M
    2. FOR DX=0 TO N
    3. @@(X1+DX,Y1+DY),X2+DX,Y2+DY
    4. NEXT DX
    5. NEXT DY

    verschieben (das erste Argument des @-Befehls ist die Malfarbe). :D

  • Gibt kein RDOT in Loco.

    Übersetzung des Beitrags von Bytebreaker in CPCWiki:


    "Ich habe mir überlegt ob solche Effekte auch zum C128, Plus/4 or C64 portiert werden können. So weit es mir bekannt ist, haben selbst die fortgeschrittenen BASIC 3.5 und 7.0 keine Entsprechung zum TEST-Kommando (von Locomotive-BASIC, Anm. d. Übersetzers), welches der Schlüssel dazu war, dieses Projekt ohne den Einsatz von Maschinensprache zu realisieren."


    Jetzt alles klar? Hoffentlich.

  • Bin gerade faul :D Ich würde sonst was mit Matrizen versuchen ;)

  • @ Mike


    Aaahh, sehr schön und gut zu wissen!
    Mir dämmert nun auch, dass im C128 Handbuch ein Beispiel ist, wie ein Bitmap-Bereich abgescannt und in ein Sprite überführt wird. Täte mich nicht wundern wenn Rdot da mit im Spiel ist.


    @ RKSoft, Tale-X


    Ja, es wäre halt wieder so eine Art "Demo Effekt", der mit CBM Bordmitteln ab Basic 3.5 ja nun tatsächlich machbar ist.


    Als nächstes mache ich mich ans vertikale und horizontale Flipping der eingelesenen Pixel-Matrix. Evtl. find ich auch noch Zeit, bei der Rotations-ASM Compo mitzumachen.

  • Also eine Rotation um 180 Grad bekäme ich hin, keine Frage. Aber 90 Grad oder gar 45 Grad, da hörts dann wahrscheinlich auf. Obwohl, 90 Grad noch gingen, wie es mit 45 aussähe, keine Ahnung. Versuchen könnte ich dies ja mal. Gibt es eine spezielle Wunschvorlage, wie was ablaufen soll?


    Ansonsten würde ich einfach beim Programmstart ne Frage einbauen, welches Zeichen und um wieviel Grad es gedreht werden soll. Programm würde dann aus dem CHAR-ROM die Werte direkt umrechnen. Dies müßte dann nicht nur am C264er gehen, sondern auch (angepasste Adressen vorrausgesetzt) auch am C64er.

  • @RKSoft


    Schau Dir das mal an:


    Sprite drehen


    Was jetzt im Grunde nur noch fehlt ist, ab Basic v3.5 mit dem rdot Befehl einen fest definierten Bitmap Bereich zu scannen, in ein Sprite zu überführen und dieses zu drehen und das alles in ein User Interface zu packen mit Eingabemöglichkeit (Input, get, was einem lieber ist) für den Nutzer was er gern hätte an Rotation.


    Schau mal ins C128 Handbuch, da wird mit Draw und Plot eine Autobahn und ein Auto gezeichnet. Das Auto wird abgescannt und als Sprite überführt und dann bewegen sich 2 Sprites im Wettrennen über die Autobahn. Ich kann Dir JPEG-Screenshots davon machen wenn Du das Handbuch nicht hast.


    Auf die Art hätte man sogar ein Tool. Am PC oder am Plus/4 oder C128 eine HiRes-Grafik zeichnen und positionieren und die Höhe und Länge an Pixeln kennen und den Rotationsmittelpunkt berechnen.


    Mit diesen Parametern kann man jeden rechteckigen oder quadratischen Ausschnitt einer Bitmap drehen. Die Größenbegrenzung sollte das maximale Sprite-Maß sein.


    Das wäre dann ein Tool für eigene Spiele in denen sich drehende Gegner o.ä. vorkommen.


    PS:


    Hier


    cpcwiki.eu/forum/demos/char-ro…asic/msg139588/#msg139588


    habe ich mittlerweile eine erweitrte Version "charflip.bas" dazu getan, mit der man auch vertikal und horizontal "flippen" kann. Das merkt man bei allen Buchstaben die nicht symmetrisch sind. Ein P flippen ist anders als es zu rotieren. Bei einen M oder A sieht man keinen Unterschied.


    PS:


    Wenn Du Fragen zum Thema Geometrie hast, antworte ich gerne. Das Schlimmste war eigentlich zu erkennen, dass ich Arkussinus und Arkuscosinus als Umkehrfunktionen zu Sinus und Cosinus brauche, sorich, die Möglichkeit, einen Sinus und einen Cosinus in ein Bogenmaß rückzuwandeln und die Symmetrie über die Quadranten zu berücksichtigen.

  • Zitat von Bytebreaker

    Das Schlimmste war eigentlich zu erkennen, dass ich Arkussinus und Arkuscosinus als Umkehrfunktionen zu Sinus und Cosinus brauche [...]

    Schau dir nochmal an, wie ich beim Tribar die Rotation (in Zeile 29) gemacht habe:


    Plot-Routine für Basic V2


    Da braucht's keinen Arcuscosinus oder -sinus, Sinus und Cosinus werden direkt in Zeile 24 aus dem Rotationswinkel (von Gradmaß in Bogenmaß umgerechnet in Zeile 15) berechnet.


    Zitat

    Mir dämmert nun auch, dass im C128 Handbuch ein Beispiel ist, wie ein Bitmap-Bereich abgescannt und in ein Sprite überführt wird. Täte mich nicht wundern wenn Rdot da mit im Spiel ist.

    Für's Ablegen und wieder herausholen eines Bitmap-Bereichs in/aus einer Zeichenkette haben BASIC 3.5 und 7.0 die beiden Befehle SSHAPE und GSHAPE, das braucht man also nicht "von Hand" pixelweise zu machen. Geschwindigkeitswunder sind die beiden Befehle dennoch nicht, man kann einem Bereich von etwa Spritegröße bereits zusehen, wie er gemütlich gezeichnet wird.


    Auf dem C128 kann man darüberhinaus mit dem Befehl SPRSAV eine Zeichenkette (auch von den SHAPE-Befehlen) von *exakt* Sprite-Größe zwischen Zeichenkette und Sprite hin- und herwandeln. Auf dem C16 geht das nicht, der hat keine Sprites und hat darum auch SPRSAV nicht im BASIC.

  • Ich habe mir das Programm selbst noch nicht näher angesehen, hab´s aber mal durch WinCPC gescheucht. Recht nett, aber ARG langsam ;-) Ich vermute jetzt mal in´s Blaue hinein, aber Sinus-/Cosinus-Tabellen scheinen da noch nicht bedacht worden zu sein?


    P.S.: besonders groß werden solche Tabellen auch nicht werden, da die Auflösung und die Menge überhaupt möglicher Winkel von Pixel zu Pixel doch ziemlich begrenzt ist. Ich hab die Winkel leider nicht mehr parat (laaaange her, Informatikunterricht in der Schule), aber die im Voraus auszurechnen und in eine Tabelle umzusetzen dürfte kein großer Aufwand sein.

  • @whose


    Na dann programmier es doch schneller in Basic wenn Du kannst. ;-)
    Doch, natürlich sind da Sin/Cos Tabellen dabei.


    Zuallererst wird eine allgemeine Matrix aufgebaut, in der für jedes Pixel eines Zeichens vom Mittelpunkt her ein Radius und ein Bogenmaß ermittelt wird. Diese Tabelle hätte ich auch in ein SEQ-File auslagern und bei Programmstart einlesen können oder als DATAs im Quellcode anlegen. Das würde nochmal 50% mehr Speed geben, da geb ich Dir Recht.


    Dann werden die Pixelfarbinformationen für eine Zeichenkoordinate ausgelesen und in der gleichen Matrix mit gespeichert im Array grid(225,2). 15*15 Pixel, 0=Farbe,1=Winkel,2=Radius.


    Dann werden die Bogenmaßwerte um den Drehwinkel addiert/subtrahiert und Routine 4000 im Quellcode plottet das Ganze.


    @Mike


    Danke für den Hinweis. Du sprichst davon, dass bei Dir Winkel schon da sind und in Sin/Cos transformiert werden. Ich bilde zuerst Sin, Cos und Radien um jeden Punkt per "Bogenmaßansprache" plotten zu können. Dazu bestimme ich mit dem umgeformten Satz des Pythagoras zuerst die Länge (=Radius) vom Rotationsmittelpunkt zum aktuellen Pixel. Und mit der Umformung länge x = cos(winkel)*radis zu cos(winkel) = länge x/radius bzw. sin(winkel) = länge y/radius. Dann habe ich Sin, Cos und Radien zu jedem Pixel für der 15*15 Matrix erstmal einzeln vorliegen.


    Ich muss aber, um rotieren zu können, den Winkel zu der sin/cos/radius Kombination jedes Pixels wissen. Bei einem Sinus von 0,876 und einem Cosinus von 0,636 weiß ich ja nicht, welches Bogenmaß das ist. Dazu nutze ich die Umkehrfunktion Arcussinus/Arcuscosinus, der mir aus Sin/Cos-Werten Bogenmaße macht. Diese Bogenmaße landen dann im Array grid und funktionieren nur in Kombination mit den passenden Radien zum plotten. Denn erst dann kann ich sagen Bogenmaß X plus Offset Y=Zielpunkt der Rotation.


    Ich habe evtl. einen umständlichen Ansatz gewählt. Ich versuche ja immer, aus eigener Kraft etwas selber auszudenken und im ersten Step möglichst wenig abzugucken. Da kommen dann natürlich auch komische Konstrukte raus.


    Ich werde zu Hause Abends Tribar analysieren und mir anschauen, auf was für unnötige Dinge Du verzichtest um schneller zu sein.


    PS: Mike das Bild im Anhang ist für Dich. Der linke obere Punkt in der Zeichnng wo vom Koordinatenursprung der Strich hinführt kann als erstes Zeichen einer Char-Matrix interpretiert werden. Das mute ich normalen Menschen eigentlich nicht zu, aber Du hast Dich damals auch nicht gescheut, handgeschriebende Matritzenmultiplikationen als Scan von mir zu korrigieren. :-)

  • Zitat von Bytebreaker

    Mike das Bild im Anhang ist für Dich. Der linke obere Punkt in der Zeichnng wo vom Koordinatenursprung der Strich hinführt kann als erstes Zeichen einer Char-Matrix interpretiert werden. Das mute ich normalen Menschen eigentlich nicht zu, aber Du hast Dich damals auch nicht gescheut, handgeschriebende Matritzenmultiplikationen als Scan von mir zu korrigieren.

    Das paßt schon alles, es funktioniert ja. Und richtig: wenn Du aus Koordinaten den Argumentwinkel zurückrechnen willst, kommst Du auch nicht um Fallunterscheidungen für die Quadranten herum (es gibt eine ATAN2-Funktion, die das schon automatisch macht, allerdings nicht in V2 BASIC).


    Im Prinzip rechnest Du einmal von kartesischen Koordinaten nach Polarkoordinaten, wobei Du in letzteren ganz einfach drehen kannst, indem Du auf den Winkel addierst oder subtrahiert. Und dann wieder zurück nach kartesischen Koordinaten.


    Dazu dann noch mal ein anderes Posting: Rotierender 3D Würfel - Neujahrsgeschenk für Oobdoo und alle Interessierten


    Da leite ich die Rotationsmatrix in 2D ab. Wichtig sind an dieser Stelle die Sätze: "Ein scharfer Blick zeigt uns, daß da mit r * cos(phi) und r * sin(phi) die Koordinaten x und y drin stecken! Also setzen wir die ursprünglichen Formeln einfach wieder ein [...] Dadurch sparen wir uns auch in dieser Stelle die doch recht aufwendige Quadratwurzel und den Arcustangens (also, das Hin- und Herrechnen zwischen kartesischen und Polarkoordinaten)."

  • Wenn es interessiert,


    im CPC Wiki Thread kann man jetzt auch eigene Chars designen (Vorder/Hintergrundfarbe, Rotation, horiz./vertl. Spiegelung), auf Diskette speichern und in den Data-Bereich eines Anzeigeprogramms einbauen. 20 Zeichen passen auf den Bildschirm in gegebener Skalierung und Auflösung.