Hallo Besucher, der Thread wurde 2,8k mal aufgerufen und enthält 24 Antworten

letzter Beitrag von Mac Bacon am

Komplette Text-/Grafikblöcke "in einem Rutsch" bis zum rechten Rand ausgeben?

  • HeyHo! Blöde Frage sicherlich, aber ich brech mir hier grad die Finger und komme partout nicht drauf ...
    Ich möchte gerne einen vorgefertigten Textblock, oder eben PETSCII bis an den rechten Bildrand ohne Umbruch ausgeben.
    Semikolon hilft aber eben nur für die erste Zeile; die nächste rutscht dann an den linken Rand.
    TAB scheint nach Semikolon auch nicht mehr zu helfen. SPC geht, aber eben nur für diese eine Position.


    Ich hab' mir jetzt mit div. Pokes zur Cursor-Positionierung beholfen, aber dann zeichne ich ja immer nur eine Zeile,
    positioniere neu und zeichne die nächste. Außerdem braucht das viele GOSUBs - geht zwar rel. fix, belastet aber auch den
    Speicher recht ordentlich, oder?


    Geht das nicht irgendwie eleganter? Ich finde leider nicht wirklich das, was ich brauche.


    Vielleicht kann mir hier Jemand helfen. Würde mich sehr freuen!


    LG!
    Phu


    PS: Basic v2

  • Hi
    Ich habe mal für einen ein Basicprogramm geschrieben, da habe ich so eine Print At Routine eingesetzt
    Hier mal der Assemblercode


    und im Basic eingebunden sieht es dann so aus:



    Code
    1. 10 IF F=0 THEN F=1:LOAD"R1",8,1
    2. 20 ?"clr Home":CLR:REM LOESCHE DEN SPEICHER VON BASIC-VARIABELN
    3. 30 AT=49152
    4. 40 SYS AT,22,10:PRINT "HIER STEHT DEIN TEXT"

    Es ist zwar so ähnlich wie bei dir, aber vielleicht hilft es dir.


    Gruß Drachen

  • Hey Drachen!
    Danke für Deine Antwort. Ja, ich glaub' das ist meiner Variante sehr ähnlich, nur dass ich eben NULL Ahnung von Assembler hab.
    Aber das ist ja super kommentiert- da kann ich mir das ganz gut zusammenreimen.


    Im Grunde schreib ich ja auch erst eine Zeile, setze den Cursor neu, schreib die nächste...


    Aber mal so für mich zum Verständnis (auch wenn jetzt hier gleich Steine fliegen, aber wer nicht fragt bleibt halt dumm):
    - r1.prg ist ja die Routine zum Positionieren und SYS ruft sie auf, richtig?
    - AT ist die Adresse der Routine im Speicher?


    Welchen Editor kannst Du empfehlen, damit ich den Assembler-code mal testen kann?
    Ich hab wirklich keinen plan, wie ich das auf'n Disk-Image bekomme
    :facepalm:


    Aber ich Dank Dir vielmals für die Mühe!

  • Hi phat-phu


    Das Assemblerprogramm habe ich mit C64 Studio geschrieben. Entwickelt von Endurion der hier im Forum immer zu finden ist wenn am Probleme mit seinen Programm hat. Er hilf immer sehr schnell.
    Hier die Seite zum downloaden :http://www.georg-rottensteiner.de/de/index.html


    Und hier eine Seite wie man damit um geht. https://www.retro-programming.…notigte-tools/c64-studio/


    So jetzt zu deinen Fragen.
    Richtig das Maschinen Programm heißt R1.prg und wird nach $c000 (hex-Zahl) geladen. In einer Dezimalzahl umgewandelt heißt die hex-Zahl dann 49152.
    Damit kann man dann das Maschinenprogramm mit Sys 49152,y,x aufrufen.
    So ich hoffe es hilft dir.


    Gruß Drachen

  • Ohne den auszugebenden Text (umständlich) zu manipulieren wird das nicht gehen:

    • das vorletzte Zeichen aus dem auszugebenden String löschen
    • an den string hinten chr$(157)chr$(148)"X" anhängen, wobei du statt "X" das im obigen Schritt gelöscht Zeichen einsetzt


    Das Resultat würde dann ungefähr so aussehen:


    Code
    1. 10 Print "[Zeichen 1-38 und Zeichen 40]"chr$(157)chr$(148)"[Zeichen 39]"

    Die beiden chr$-Angaben stehen für CURSOR LEFT und INSERT, das heißt der Cursor wird auf Position 39 zurück bewegt (wo derzeit Zeichen 40 steht), durch INSERT wird Zeichen 40 auf Position 40 verschoben ohne dass ein Zeilenumbruch entsteht, dann wird Zeichen 39 an Position 39 geschrieben.

  • Ich versteh das Problem nicht. Kann mal jemand das visualisieren als Screenshot mit Soll / Ist?


    Dass man einen String gern positionieren möchte kann ich verstehen (es fehlt ein Locate-Befehl, wie ihn andere Basic-Dialekte haben).


    Aber was ist mit Textblöcken verschieben zum rechten Rand ohne Umbruch gemeint? Was ist der Anwendungsfall? Wie sieht das denn konkret am Bildschirm aus?

  • Ich hab' mir jetzt mit div. Pokes zur Cursor-Positionierung beholfen, aber dann zeichne ich ja immer nur eine Zeile,
    positioniere neu und zeichne die nächste.

    Also wenn ich das richtig verstehe und das ganze ungefähr so aussieht

    Dann wirst du IMMER für jede Zeile neu positionieren müssen, das ist ja schließlich auch im Bildschirmspeicher kein zusammenhängender Block ....


    Allerdings ließe sich das in Assembler immerhin einigermaßen flott umsetzen :)


    (edit: brainfuck-bug im Board? Kriege ich das sinnlose highlighting irgendwie aus?)

  • Das heißt, man hat irgendeinen beliebigen Zeichensalat und will, dass der blockweise positionierbar ist wenn der Bildschirmrand überschritten wird?


    OOOOOhallo d
    OOOOOas ist e
    OOOOOin test.



    Ich weiß nicht wie im Forum das oben genannte aussehen wird, wahrscheinlich nicht streng untereinander, aber die Os sollen Leerzeichen sein und ganz rechts denken wir uns den Bildschirmrand.


    Wenn das o.g. die Anforderung ist, dann ist das nicht so einfach. Wenn man aber ein Array gleich großer Strings hätte, müsste man nur ausrechnen ab wann man den rechten Bildschirmrand berührt und das String Array dann String für String mit den richtigen Offsets drucken. Das wäre nicht so schwer.

  • @Drachen:Klar hilft mir das! Vielen Dank!!! Ich hab' nur grad 'n Mac ohne Windows-Partition, daher auch (noch) kein c64 Studio- steht ganz oben.
    Korodny: Die Lösung find' ich gut- ich probier das später aus, aber ich glaube das macht schon den Trick.
    zrs1: Genau so soll's sein... bei meiner jetzigen "Lösung" positioniere ich halt immer wieder neu.


  • Oben mal das Beispiel, wie's aussehen sollte. Der Kasten geht bis zum Bildschirmrand ohne den Zeilenumbruch zu machen.
    Und anbei die bisherige, umständliche Lösung mit "neu positionieren". Gefällt mir nicht wirklich. :/


    Habt 1000Dank für die Hilfe! Ich weiß es zu schätzen! =D

  • Code
    1. 10 Print "[Zeichen 1-38 und Zeichen 40]"chr$(157)chr$(148)"[Zeichen 39]"

    Die beiden chr$-Angaben stehen für CURSOR LEFT und INSERT, das heißt der Cursor wird auf Position 39 zurück bewegt (wo derzeit Zeichen 40 steht), durch INSERT wird Zeichen 40 auf Position 40 verschoben ohne dass ein Zeilenumbruch entsteht, dann wird Zeichen 39 an Position 39 geschrieben.

    ... zumal ich mit dieser Variante ja auch in die letzte Bildschirmzeile schreiben könnte ohne dass alles "scrollt"; versteh ich zumindest so. Naja- ich probier's aus. Danke!

  • Hier mal ne weitere Maschinencode-Lösung ;)

    Der Maschinencode liegt im Datasettenpuffer, der Text wird unterm BASIC ROM "versteckt" :)


    edit: Das Ding beherrscht keine Steuerzeichen, der String wird direkt in Screencode konvertiert und abgelegt, das Plotten kopiert dann nur noch. Heißt auch dass so keine Reversen Zeichen gehen.

  • Diese 2 Jackpot Blöcke sind doch fest platziert. Ich hätte einfach Strings definiert und diese mit der richtigen Anzahl Return und spc Codes ausgegeben und das Ganze in ein Unterprogramm gepackt.


    Vielleicht irre ich mich ich bin außer Haus und kann das Prg nicht testen aber einen Locate Ersatz braucht man hierfür imho nicht.


    Wobei es interessant wäre das für kleinere Strings zu haben: drucke diesen String an koordinate x,y. Ich setz mich mal hin und schreib was in Basic.

  • hm ein maschinen program mit sys x,y,string waere wohl nich schlecht... kann man auch super in basic schreiben.
    wobei mir jetzt zrs1 loesung total gefaellt, er/sie muesste es nur um die steuercodes erweitern ;)
    evtl waere e auch super zu sagen wo ein textblock anfaengt um mehrere texte unter basic rom zu schreiben.
    so nach dem motto


    da der text unterm basicrom versteckt wird bleibt auch noch speicher uebrig wenn ich das richtig verstehe.


    etwas besseres wuerde ich wohl garnich hinbekomm :rauchen:

  • Hier ein Locate String in Basic. Da ist keine Plausibilitätsprüfung drin (Sind Zeile, Spalte zu groß, passt der String noch ohne Umbruch bis an den rechten Rand). Man kann es aber in ein Unterprogramm wandeln und dann bei Bedarf anspringen.


    Code
    1. 10 print chr$(147)
    2. 20 input "string";tx$
    3. 30 input "zeile,spalte";y,x
    4. 40 print chr$(19)
    5. 50 print chr$(147)
    6. 60 for i=1 to y-2:print:next i
    7. 70 for i=1 to x-1:print " ";:next i
    8. 80 print tx$;
    9. 90 end
  • Hier ein Locate String in Basic

    Das war nicht wirklich phat-phus Problem: Er wollte einen 40 Zeichen lang String ausgeben, ohne dass ein Zeilenumbruch entsteht.


    LOCATE - also den Cursor an X/Y positionieren - simuliert man in BASIC am Besten durch Nutzung der entsprechenden Betriebssystem-Routine:


    Code
    1. POKE 781,[Zeile]:POKE 782,[Spalte]:POKE 783,0:SYS 65520: PRINT"[Irgendein Text]"
  • @Korodny


    Danke für die Pokes!



    Zitat von Korodny

    Er wollte einen 40 Zeichen lang String ausgeben, ohne dass ein Zeilenumbruch entsteht.


    Jetzt hab ich es begriffen. Der String wird über 40 Zeichen ausgegeben und Basic produziert danach ein Return zuviel wenn man nicht 517 umständliche Maßnahmen dagegen unternimmt. Lange Leitung gehabt. :schande:

  • wobei mir jetzt zrs1 loesung total gefaellt, er/sie muesste es nur um die steuercodes erweitern
    evtl waere e auch super zu sagen wo ein textblock anfaengt um mehrere texte unter basic rom zu schreiben.

    Jo, das macht es aber um einiges komplexer, da müsste ich erstmal schauen, ob ich irgendwie das ROM verwenden kann, denn das ganze parsen von Steuercodes will man eigentlich nicht nochmal machen -- und das Format im Speicher müsste auch anders werden, mit expliziten Datenstrukturen, weil im Screencode keine ungenutzten Zeichen sind, die man als Marker für "Zeilenende" und "Blockende" nutzen könnte :)


    Achja, SYS825 ist ausgeschlossen, jeder JMP befehl braucht 3 bytes :)


    Vielleicht überlege ich mir da ja was nettes, ist aber unwahrscheinlich, dass der Code dann noch in den Datasettenpuffer passt.

  • Der String wird über 40 Zeichen ausgegeben und Basic produziert danach ein Return zuviel wenn man nicht 517 umständliche Maßnahmen dagegen unternimmt.

    Ausnahmsweise liegt das nicht am Basic, sondern am Bildschirm-"Treiber" des Kernals. Schön(tm) wäre es, wenn das Einfügen einer Leerzeile bei Erreichen des rechten Rands nur im Direktmodus passieren würde (denn eigentlich braucht man das nur beim Editieren eines Basicprogramms). Für den Quote-Modus gilt das gleiche, der ist zur Programmlaufzeit auch eher hinderlich.
    Statt einer speziellen Ausgaberoutine, die man per SYS aufruft, würde ich daher eher für einen Nachlade-Patch plädieren, der sich auf dem FFD2-Vektor installiert und den Bildschirm anders ansteuert.

  • Ein Hintergedanke war, dass der Anwendungsfall hier ja so ne art "plotten von Fenstern" ist, und man das etwas optimieren kann, wenn die Daten vor dem ausgeben schon in Screencode vorliegen :) Klar, das oben gepostete ist nur mal quick&dirty runtergehackt und keine tolle Lösung...