Wie am besten in die Konsole Zeichen ausgeben?
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Wie am besten in die Konsole Zeichen ausgeben?
Hi
Wie gibt man am besten Zeichen in der Konsole aus?
Wenn man über den rechten Rand schreibt, wird die Ausgabe am Anfang der nächsten Zeile fortgeführt.
Der Quellcode von Free Vision ist mir zu hoch, ich habe nur was von MoveBuf mitbekommen.
Zuerst dachte ich daran, die Ausgabe der Zeichen abzubrechen wenn die Zeichenausgabe über den rechten Rand hinaus gehen würde, aber das würde viele Änderungen mit vielen Abfragen am Quellcode bedeuten.
Dann dachte ich daran, meine Unit die für die Textausgabe zu kopieren, und so so anzupassen das in einem Array die Zeichen ausgegeben werden, und erst im Abschluss den Inhalt des Arrays in die Konsole auszugeben.
Wie stellt man so was am besten an?
Gruß vom Nixsager.
Wie gibt man am besten Zeichen in der Konsole aus?
Wenn man über den rechten Rand schreibt, wird die Ausgabe am Anfang der nächsten Zeile fortgeführt.
Der Quellcode von Free Vision ist mir zu hoch, ich habe nur was von MoveBuf mitbekommen.
Zuerst dachte ich daran, die Ausgabe der Zeichen abzubrechen wenn die Zeichenausgabe über den rechten Rand hinaus gehen würde, aber das würde viele Änderungen mit vielen Abfragen am Quellcode bedeuten.
Dann dachte ich daran, meine Unit die für die Textausgabe zu kopieren, und so so anzupassen das in einem Array die Zeichen ausgegeben werden, und erst im Abschluss den Inhalt des Arrays in die Konsole auszugeben.
Wie stellt man so was am besten an?
Gruß vom Nixsager.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Wie am besten in die Konsole Zeichen ausgeben?
Über zu viele abfragen etc. würde ich mir keine Gedanken machen, dein Prozessor arbeitet im GHZ Bereich, das bedeutet das jeder Kern 1000000000+ Operationen pro Sekunde macht, eine Simple Abfrage sollte nicht mehr als 10 Operationen brauchen, da kannst du dir ausrechnen wie lange dein Prozessor wohl dafür brauchen würde 
Außerdem braucht eine Abfrage deutlich weniger Zeit als der WriteLn Call, da dieser dein Programm kurzzeitig Suspendiert, das Betriebsystem aufruft, welches sich um die Ausgabe kümmert, und dann dein Programm wieder lädt. Dieser Vorgang, Contextwechsel genannt, braucht so viel mehr zeit als ein paar kleine Abfragen, das diese in der gesamtzeit kaum ins Gewicht fallen, deine Anwendung würde damit nicht signifikant langsamer werden.
Die Idee mit dem Array wäre wohl die Performance beste, da du nur einen Contextwechsel brauchst, aber entsprechend brauchst du natürlich mehr Speicher. Was bei Ram zahlen im GB Bereich allerdings auch Irrelevant ist, tatsächlich gilt in den meisten Fällen die Faustregel, Zeit ist wichtiger als Speicher, denn Speicher ist billig, Zeit nicht. Wichtig dabei wäre nur ein Statisches Array zu nehmen, da dynamische Arrays wiederum den gesamten performance Bonus durch das einsparen der Kontextwechsel relativieren würden.
Und wie schon am Anfang erwähnt, bei Prozessoren im GHz Bereich und Speicher im GB Bereich ist weder der Speicher noch die Performance wirklich ein Kriterium für die meisten Anwendungen. Da kommt es eher auf die Asymptotische Laufzeit an, aber das ist wiederum eine ganz andere Geschichte.
Allerdings verstehe ich nicht so ganz was du tun möchtest und wo dein Problem liegt, Und kann daher keinen wirklichen Ratschlag geben

Außerdem braucht eine Abfrage deutlich weniger Zeit als der WriteLn Call, da dieser dein Programm kurzzeitig Suspendiert, das Betriebsystem aufruft, welches sich um die Ausgabe kümmert, und dann dein Programm wieder lädt. Dieser Vorgang, Contextwechsel genannt, braucht so viel mehr zeit als ein paar kleine Abfragen, das diese in der gesamtzeit kaum ins Gewicht fallen, deine Anwendung würde damit nicht signifikant langsamer werden.
Die Idee mit dem Array wäre wohl die Performance beste, da du nur einen Contextwechsel brauchst, aber entsprechend brauchst du natürlich mehr Speicher. Was bei Ram zahlen im GB Bereich allerdings auch Irrelevant ist, tatsächlich gilt in den meisten Fällen die Faustregel, Zeit ist wichtiger als Speicher, denn Speicher ist billig, Zeit nicht. Wichtig dabei wäre nur ein Statisches Array zu nehmen, da dynamische Arrays wiederum den gesamten performance Bonus durch das einsparen der Kontextwechsel relativieren würden.
Und wie schon am Anfang erwähnt, bei Prozessoren im GHz Bereich und Speicher im GB Bereich ist weder der Speicher noch die Performance wirklich ein Kriterium für die meisten Anwendungen. Da kommt es eher auf die Asymptotische Laufzeit an, aber das ist wiederum eine ganz andere Geschichte.
Allerdings verstehe ich nicht so ganz was du tun möchtest und wo dein Problem liegt, Und kann daher keinen wirklichen Ratschlag geben
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Wie am besten in die Konsole Zeichen ausgeben?
Warf hat geschrieben:dein Prozessor arbeitet im GHZ Bereich
Zwar der Rechner auf dem ich arbeite, aber nicht der Rechner der als Mindestziel gedacht ist. Der Rechner hat so 4,7 MHz und 640 KB RAM.Warf hat geschrieben:Was bei Ram zahlen im GB Bereich allerdings auch Irrelevant ist.
Er dachte, das hätte ich gut erklärt?Warf hat geschrieben:Allerdings verstehe ich nicht so ganz was du tun möchtest und wo dein Problem liegt, Und kann daher keinen wirklichen Ratschlag geben

Ich bin ja gerade dabei eine MessageBox zu bauen. Und wenn die, breiter als die Zeile ist, oder soweit nach rechts positioniert ist das sie um den Zeilenrand geht, dann wird die Textausgabe am Anfang der nächsten Zeile fortgeführt.
Das glaube ich auch. Und so wird der Quellcode nicht komplexer, auch wenn er durch die Zusätzlich Unit größer wieder, da ich eine Unit für die direkte Textausgabe habe und ein für die Textausgabe in dem Array.Warf hat geschrieben:Die Idee mit dem Array wäre wohl die Performance beste
Das muss ich später wohl noch ein paar Fragen stellen. Hört sich an, als müsste ich mit Zeigern arbeiten. So muss ich im Grunde nicht die Daten kopieren, sondern gebe nur eine neue Adresse der Daten an. Aber das würde nur bei internen arbeiten Sinn machen. Für die Textausgabe müsste ich die Daten trotzdem kopieren. Oder manipuliere am Grafiksystem rum.Warf hat geschrieben:da du nur einen Contextwechsel brauchst
Zuletzt geändert von Nixsager am So 30. Okt 2016, 14:21, insgesamt 1-mal geändert.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Wie am besten in die Konsole Zeichen ausgeben?
Ich nehme mal an, es handel sich dabei um einen 8088, welcher im Real-Modus läuft.Zwar der Rechner auf dem ich arbeite, aber nicht der Rechner der als Mindestziel gedacht ist. Der Rechner hat so 4,7 MHz und 640 KB RAM.
Das heisst hier eigentlich nicht Konsole, sondern einfach Text-Modus.Wie gibt man am besten Zeichen in der Konsole aus?
Bei Konsole denken alle an das Text-Fenster Windows oder Linux.
Wen das so ist, würde ich direkt ins VRAM schreiben, etwas schnellere wirst du nicht finden.
Wie das geht könnte ich dir schon helfen.
Bis du nicht der Turbo-Pascal Programmierer ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Wie am besten in die Konsole Zeichen ausgeben?
Na ja, mein Ziel ist es, das mein Programm bzw. meine Units auch auf so einem System laufen können. Auch wenn keiner mein fertiges Programm jemals wirklich nutzen wird.Mathias hat geschrieben:Ich nehme mal an, es handel sich dabei um einen 8088, welcher im Real-Modus läuft.
Ich weiß.Mathias hat geschrieben:Das heisst hier eigentlich nicht Konsole, sondern einfach Text-Modus.
Bei Konsole denken alle an das Text-Fenster Windows oder Linux.

Ich habe es einfach mal Konsole genannt, weil das Prinzip ist das Selbe, und das ist hier ein Free Pascal-Forum, und da arbeiten wohl eher welche für die Konsole als für Dos und den Textmodus.
Das ist relativ einfach mit Mem, MemL und MemW.Mathias hat geschrieben:Wen das so ist, würde ich direkt ins VRAM schreiben, etwas schnellere wirst du nicht finden.
Wie das geht könnte ich dir schon helfen.
Aber dann müsste vorher überprüfen wo der Video-RAM liegt.
Ich nutze dafür in meiner Unit den Interrupt 10h.
Und da taucht auch wieder das Problem mit dem Zeichnen über den Rand auf.
Ich verweise mal auf meine Signatur.Mathias hat geschrieben:Bis du nicht der Turbo-Pascal Programmierer ?

Ich arbeite mit Turbo Pascal, aber als Programmieren würde ich das nicht bezeichnen. Mich könnte man eher als Scriptkiddie bezeichnen.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Wie am besten in die Konsole Zeichen ausgeben?
Dann mache es doch so, zwei if-Abfragen pro String-Ausgabe.Und da taucht auch wieder das Problem mit dem Zeichnen über den Rand auf.
Code: Alles auswählen
program Project1;
uses
Crt;
const
satz = 'Ich bin ein sehr langer Satz';
var
i: integer;
procedure OutTextXY(x, y: integer; s: ShortString);
var
l: integer;
begin
if x > 80 then begin
Exit;
end;
GotoXY(x, y);
l := 80 - WhereX + 1;
if l < byte(s[0]) then begin
s[0] := char(l);
end;
Write(s);
end;
begin
for i := 1 to 10 do begin
OutTextXY(i + 60, i * 2, satz);
end;
repeat
until KeyPressed;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Wie am besten in die Konsole Zeichen ausgeben?
TP schreibt mit Write/WriteLn standardmäßig direkt in den VRAM! Um das zu verhindern, muss die variable "DirectVideo", die sich in der Unit CRT befindet, auf False gesetzt werden.Mathias hat geschrieben:Wen das so ist, würde ich direkt ins VRAM schreiben, etwas schnellere wirst du nicht finden.
Wie das geht könnte ich dir schon helfen.
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Wie am besten in die Konsole Zeichen ausgeben?
Dies war aber trotzdem niemals so schnell, wie man direkt ins VRAM schrieb. Writeln hat noch recht Overhead.TP schreibt mit Write/WriteLn standardmäßig direkt in den VRAM! Um das zu verhindern, muss die variable "DirectVideo", die sich in der Unit CRT befindet, auf False gesetzt werden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Wie am besten in die Konsole Zeichen ausgeben?
Ihr vergisst, das 'Write' Steuerzeichen interpretiert. Und wenn man ein Zeichen nutzen will, das auch ein Steuerzeichen ist, dann hat man ein Problem.
Denkt an das ♪-Zeichen. Mit Write springt man dann zur nächsten Zeile da da Zeichen den Zeilenvorschub ausführt, aber wenn man es in den Video-RAM schreibt, erhält man einen Notenschlüssel.
Denkt an das ♪-Zeichen. Mit Write springt man dann zur nächsten Zeile da da Zeichen den Zeilenvorschub ausführt, aber wenn man es in den Video-RAM schreibt, erhält man einen Notenschlüssel.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Wie am besten in die Konsole Zeichen ausgeben?
Das Problem kannte ich auch, entweder VRAM oder eine int 10 Funktion nehmen,Ihr vergisst, das 'Write' Steuerzeichen interpretiert. Und wenn man ein Zeichen nutzen will, das auch ein Steuerzeichen ist, dann hat man ein Problem.
So nebenbei hatte Write noch eine Problem, versuche mal ein Zeichen ganze rechts unten zu schreiben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Wie am besten in die Konsole Zeichen ausgeben?
Wenn du meinen ersten Post nochmals liest, merkt du, da ich da das Problem habe. Nur das das Problem eine andere Ursache hat.Mathias hat geschrieben:So nebenbei hatte Write noch eine Problem, versuche mal ein Zeichen ganze rechts unten zu schreiben.
Am einfachsten, scheint es mit einem Array zu sein, und wenn man sich die 8088 Flex-Demo anschaut, ist das auch nicht so schlimm.
Nur das Problem ist, das das Programm immer einem Speicher von der Größe des Arrays braucht. Und wenn dann man noch andere Daten hat, kommt es schnell zu einem Stapelspeicherüberlauf.
Aber so ist es einfacher. anstatt bei Label, Button und sonstige Objekte eine Abfrage einzubauen um zu überprüfen ob das Zeichen über die Zeilenbreiten gehen würde.
So nebenbei, ich hätte nicht gedacht, das ich bei TP so schnell an Grenzen stoßen würde.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Wie am besten in die Konsole Zeichen ausgeben?
Ich habe so in der Schnelle einen Speed-Test gemacht, die Differenz ist ziemlich genau das 4-fache.
Als Kompiler cabe ich den Cross8086 verwendet.
Mit Assembler könnte man vielleicht noch mehr rausholen.
Als Kompiler cabe ich den Cross8086 verwendet.
Mit Assembler könnte man vielleicht noch mehr rausholen.
Code: Alles auswählen
program Project1;
uses
SysUtils, Crt;
procedure OUTTextXYVRAM(x,y:integer; s:shortstring);
var
i, ofs:integer;
begin
ofs := x * 2 + y * 160;
for i:=0 to Byte(s[0]) -1 do begin
// Mem[$B800:ofs + i * 2]:=Byte(s[i + 1]);
// Mem[$B800:ofs + i * 2 + 1]:=$56;
MemW[$B800:ofs + i * 2]:=Byte(s[i + 1]) + $56 shl 8;
end;
end;
procedure OUTTextXYCrt(x,y:integer; s:shortstring);
var
i:integer;
begin
GotoXY(x, y);
TextAttr := $65;
Write(s);
end;
var
z1, z2, t:TDateTime;
i :integer;
begin
t := now;
for i := 0 to 1000 do begin
OutTextXYCrt(10, 15, 'Hello World !');
end;
z2 := now - t;
t := now;
for i := 0 to 1000 do begin
OutTextXYVRAM(10, 15, 'Hello World !');
end;
z1 := now - t;
GotoXY(1,1);
TextAttr := 15;
Writeln('VRAM: ', z1, ' Crt: ', z2);
Readln;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Wie am besten in die Konsole Zeichen ausgeben?
Das stimmt, WriteLn gibt ja nicht einfach nur Text aus, sondern muss den ggf. erst noch zusammen bauen (Variable u.s.w). Für die normale Textausgabe reicht das alle mal.Mathias hat geschrieben:Dies war aber trotzdem niemals so schnell, wie man direkt ins VRAM schrieb. Writeln hat noch recht Overhead.TP schreibt mit Write/WriteLn standardmäßig direkt in den VRAM! Um das zu verhindern, muss die variable "DirectVideo", die sich in der Unit CRT befindet, auf False gesetzt werden.
Das habe, zu mindest ich, nicht vergessen. Diese tatsache könnte man aber zur Ausgabe nutzen in dem man den Text schon mit Steuerzeichen versieht (CR/LF u.s.w). TP hat so schöne sachen wie "WINDOW", ist die Box gezeichnet, legt man den Ausgabebereich auf das innere der Box fest und braucht sich nicht mehr um das Positionieren des Textes zu kümmern (Fenster zurücksetzen nicht vergessen).Nixsager hat geschrieben:Ihr vergisst, das 'Write' Steuerzeichen interpretiert. Und wenn man ein Zeichen nutzen will, das auch ein Steuerzeichen ist, dann hat man ein Problem.
Denkt an das ♪-Zeichen. Mit Write springt man dann zur nächsten Zeile da da Zeichen den Zeilenvorschub ausführt, aber wenn man es in den Video-RAM schreibt, erhält man einen Notenschlüssel.
Ich gehe mal nicht davon aus das er seine MessageBox da unten hin bauen will.Mathias hat geschrieben:Das Problem kannte ich auch, entweder VRAM oder eine int 10 Funktion nehmen,Ihr vergisst, das 'Write' Steuerzeichen interpretiert. Und wenn man ein Zeichen nutzen will, das auch ein Steuerzeichen ist, dann hat man ein Problem.
So nebenbei hatte Write noch eine Problem, versuche mal ein Zeichen ganze rechts unten zu schreiben.
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Wie am besten in die Konsole Zeichen ausgeben?
Wieso nicht? Wenn die MessageBox so groß wird wie Auflösung Textmodus.Jole hat geschrieben:Ich gehe mal nicht davon aus das er seine MessageBox da unten hin bauen will.
Es geht auch darum um Fenster zu zeichnen. Ihr sieht es ja daran wenn ihr im TUI von FP ein Fenster verschiebt.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
Re: Wie am besten in die Konsole Zeichen ausgeben?
Du vergisst aber das FP nicht mehr direkt in den VRAM schreibt, DirectVideo existiert, soweit ich weiß, nur noch aus Kompatibilitätsgründen. Der gleiche Test mit TP ergibt erst dann eine zeit Differenz wenn DirectVideo auf False gesetzt wird.Mathias hat geschrieben:Ich habe so in der Schnelle einen Speed-Test gemacht, die Differenz ist ziemlich genau das 4-fache.
Als Kompiler cabe ich den Cross8086 verwendet.
Mit Assembler könnte man vielleicht noch mehr rausholen.
[/code]
Er will doch nur wissen wie er Text in seine MessageBox schreiben kann, ohne das bei einem Zeilenumbruch der Text am linken Fensterrand fortgesetzt wird, sondern links in seiner MessageBox. Dafür bietet sich die Prozedur WINDOW an.Nixsager hat geschrieben:Wieso nicht? Wenn die MessageBox so groß wird wie Auflösung Textmodus.Jole hat geschrieben:Ich gehe mal nicht davon aus das er seine MessageBox da unten hin bauen will.
Es geht auch darum um Fenster zu zeichnen. Ihr sieht es ja daran wenn ihr im TUI von FP ein Fenster verschiebt.
Ich persönlich kämme nie wieder auf die Idee Fenster, MsgBoxen u.ä. mit Write/WriteLn oder eigenen VRAM Prozeduren zu zeichnen. Warum nicht das nutzen was bereits vorhanden ist? Im TP Verzeichnis EXAMPLES\DOCDEMOS befindet sich der gesamte Quellcode für das Turbo Vision 2.0 Tutorial. Das Tutorial dazu kann man sich hier als PDF (Englisch) runter laden.