Autor Beitrag
Morpheusly
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 03.12.09 08:51 
Hallo liebe Community!

Ich arbeite nun schon seit mehreren Wochen an einem Projekt. Ich versuche ein Programm zu schreiben, welches in etwa wie (falls bekannt) ein Terminal für IBM Archtitekturen (z.B. AS/400) funktioniert.

Jeder der schonmal an einem solchen Terminal gesessen hat, weiß, dass es die funktion besitzt eine genaue Anzahl an Zeichen (80 Spalten, 24 Zeilen) exakt gestretched in verschiedenen Farben ect anzuzeigen.

Ich versuche hierzu das ganze mit Canvas: Da jeder Buchstabe von Farbe und Hintergrundfarbe anders definiert sein könnte vom Server, muss ich bisher leider jeden einzelnen Buchstaben einzeln Zeichnen lassen. Hierzu lasse ich zwei Schleifen (0 bis 79) und (0 bis 23) durchlaufen und zeichne den entsprechenden Buchstaben in eine TBitmap. Ist das Bild vollständig, lasse ich es aus dem TBitmap-Puffer mir auf eine Form zeichnen.

Somit kann ich auch auf die Form1.OnPaint Methode reagieren, indem ich das Bild nicht jedes mal neu erstelle, sondern aus dem Puffer neu zeichnen lasse.
Nun aber zu dem Problem: Die Dauer!
Wer mitgerechnet hat merkt, dass bei jeder Aktion, die irgendwie das Bild verändert, das Bild auch neu gezeichnet werden muss (z.B. Cursor wird bewegt, Taste gedrückt, o.Ä.)
Dies bedeutet, das Programm zeichnet alle 1920 Canvas-"Bildchen" neu in den Puffer und zeichnet diesen wiederum auf die Form.

Gibt es eine Möglichkeit das ganze schneller machen zu können?
Ich kann heute nachmittag nach der Arbeit auch gerne noch den zugehörigen Code posten, den habe ich aber im Moment leider nicht hier. Doch das ganze gibt mir natürlich keine Ruhe! :D
Habe natürlich auch schon die letzten 3 Tage gegoogelt und bin dabei auf Methoden mit DirectX gestoßen, was ich aber (rein logisch gesehen) vielleicht für ein reines "Green-Screen" Programm übertrieben halte, schließlich braucht IBM's Terminal auch kein DirectX (oder? :P)

Vielleicht hat ja jemand eine passende Idee.
Wie gesagt: Code folgt heute mittag hier =)

Vielen Dank!


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Do 03.12.2009 um 09:52
Manfred
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Do 03.12.09 22:17 
Hallo,
ich habe jetzt keinen Code zur Hand, aber wenn ich das richtig verstanden habe, geht es um eine Anwendung, die im Textmodus arbeitet.
Wenn dem so ist, warum verwendest Du dann nicht eine diktengleiche Schrift (Courier etc.)?
Alternativ dazu würde ich folgendes vorschlagen:
Die häufigsten Zeichen (alle Buchstaben groß+klein, Ziffern, Umlaute sowie die wichtigsten Satzzeichen) vorab in einem Speicherbereich vorbereiten. Das dürften etwa 70 oder 80 Zeichen sein.
Soll eines der Zeichen ausgegeben werden, wird nicht mehr pixelweise gezeichnet sondern der vorbereitete Speicher für das jeweilige Zeichen in die Bitmap kopiert.
Die pixelweise Zeichnung wird dann nur für Zeichen erforderlich, die eben nicht im vorbereiteten Speicher liegen.

_________________
Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
Morpheusly Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 03.12.09 22:28 
Hallo Manfred!
Danke für die Antwort. Habe nun auch eine Speicher-Idee entworfen.
Alle Buchstaben werden in ein TBitmap vorgepuffert mit einer exakten Größe von 6x8 Pixel (die normale 4zu3 Größe jeder monospace-Schrift).
Anschließend wird das Bild (wenn benötigt) einfach via PaintBox.Draw() neu gezeichnet. Klappt super schnell und ist leicht zu handeln.
Hier der Code aktuell:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
function WriteAll(): Boolean;
var C, R: Integer;
  TwoRect: TRect;
begin
ConLib := Form1.PaintBox1;
EMF := TMetafile.Create;
EMF.Width := 480;
EMF.Height := 192;
try
  EMFCanvas := TMetafileCanvas.Create(EMF, 0);
  EMFCanvas.Brush.Color := clblack;
  EMFCanvas.Font.Color := cllime;
  EMFCanvas.Font.Name := 'Terminal';
  EMFCanvas.Font.Height := 8;
  try
  for R := 0 to 23 do
  begin
  for C := 0 to 79 do
  EMFCanvas.TextOut(C*6, R*8, IntToStr(Trunc(C mod 10)));
  end;
  finally
    EMFCanvas.Free;
  end;
  TwoRect := Rect(Point(00), Point(ConLib.Width, ConLib.Height));
  GRP.Width := 480;
  GRP.Height := 192;
  GRP.Canvas.Draw(00, EMF);
  ConLib.Canvas.StretchDraw(TwoRect, GRP);
finally
EMF.Free;
end;
end;


Anmerkung: ConLib = TPaintBox auf der Form, EMF = Metafile zum Gesamtabbild aller 1920 Zeichen, EMFCanvas = Zu EMF gehörendes Canvas, das in EMF gespeichert wird, GRP = TBitmap (der Speicher des Komplettabbildes quasi).

Mit ConLib.Canvas.StretchDraw(TwoRect, GRP); lasse ich das Abbild GRP auf die Größe der PaintBox stretchen (TRect ist ein paar Zeilen drüber gesetzt!).

So sieht das ganze nun aus, wenn ich WriteAll(); aufrufe:

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Nun habe ich jedoch ein anderes Problem. Schaut euch die zwei For-Schleifen an. Einfache, gerade Zahlen.
Warum aber werden alle Buchstaben ab der 14 Zeile um 1 Pixel nach oben, und ab der 43 Spalte 1 Pixel nach links verschoben?
Sieht im Prinzip wie ein Rundungsfehler aus, aber worher resultiert dieser?
Ich dachte zuerst, dass kommt vom Stretchen, aber selbst wenn ich das GRP Bild ohne Stretchen einfach male, sind die Buchstaben verschoben... Verstehe ich nicht...
Einloggen, um Attachments anzusehen!
Manfred
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 90



BeitragVerfasst: Fr 04.12.09 09:41 
Warum arbeitest Du mit Trunc, wenn das Resultat ein Modulo-Ergebnis ist?

_________________
Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
Morpheusly Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Fr 04.12.09 14:48 
Huch, das ist noch drin geblieben.
Weil es vorher ein C div 10 war, mir das aber dann doch eingefallen ist, dass es mit mod einfacher wäre, im Prinzip aber egal, kommt beides Mal das selbe raus.

Bezüglich der Frage bin ich auch heute (nach einer ganzen Nacht Arbeit) nicht weiter...
Wenn ich exakt die gleichen Abmessungen verwende, entsteht beim Stretchen immer noch ein weißer, leerer Bereich.
Ich habe sogar versucht mal von 1:1 zu stretchen (also so, dass quasi gar kein Stretch vorliegt)... Selbes Ergebnis: Unten und Rechts entsteht ein "Hohlraum" im Bild...