ubuntuusers.de

"frame buffer" eines Terminals verändern

Status: Gelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

IHaveNoIdea

Anmeldungsdatum:
28. Juli 2014

Beiträge: 57

Hallo, ich bin ein Anfänger in C und möchte einen Pong-Klon schreiben, der in einem Terminal läuft. Ich habe das Kapitel in der glbc-Dokumentation über das Terminal-Interface gelesen. Ich kann das Terminal in non-canonical Mode bringen,um einzelne Tastendrücke lesen zu können.

Aber die Ausgabe macht mir Probleme: Selbst im non-canonical Mode würde ich doch Text nur an den bereits ausgegebenen Text anhängen können. Programme wie z.B. vi, emacs, nano und nethack können aber anscheinend direkt einzelne Zeichen ("Pixel") auf dem Terminal verändern ohne das gesamte Bild neu auf auszugeben. Wie kann man das machen?

Mooi

Anmeldungsdatum:
15. August 2014

Beiträge: 187

Mit Escape-Sequenzen kannst Du den Cursor beliebig positionieren.

IHaveNoIdea

(Themenstarter)

Anmeldungsdatum:
28. Juli 2014

Beiträge: 57

Danke.

Laut Google hat jedes Terminal ( und jeder Terminalemulator ) eigene Escape-Sequenzen. Also brauche ich eine Bibliothek, wie z.B. ncurses, um das hinzukriegen. In C braucht man anscheinend für ALLES eine Bibliothek.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17618

Wohnort: Berlin

Aus einem alten Fundus bei mir, mit C++ - Code, nicht C, aber der Code selbst taugt eh nix, dürfte aber die Verwendung zeigen:

  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
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*

siehe auch Professional C edition, S. 25
Escape / 0x1b + Eckige Klammer

4DOS Help Topic:  ANSI Commands


This section is a quick-reference to commonly-used ANSI commands.  This
information is generally applicable to the MS-DOS ANSI.SYS driver, and  to
other ANSI drivers such as ANSI.COM, NANSI.SYS, etc.  See the documentation
for the driver you use for more details.

An ANSI.SYS command string consists of three parts:

	  ESC[         The ASCII character ESC, followed by a left bracket.
						These two characters must be present in all ANSI
						strings.

	  parameters   Optional parameters for the command.  If there are
						multiple parameters they are separated by semicolons.

	  cmd          A single-letter command.  The case of the letter is
						meaningful.

For example, to position the cursor to row 7, column 12 the ANSI command is:

			 ESC[7;12H

To transmit ANSI commands to the screen with 4DOS, you should use the ECHO
command.  The ESC character can be generated by inserting it into the string
directly (if you are putting the string in a batch file and your editor will
insert such a character), or by using 4DOS's internal "escape" character
(ctrl-X, appearing as ) followed by a lower- case "e".  For example, the
sequence shown above could be transmitted from a batch file with either of
these commands (the first uses an ESC character directly; the second uses
e):

	  echo [7;12H
	  echo e[7;12H

You can also include ANSI commands in your prompt, using $e to transmit the
ESC character.  You can NOT use PROMPT to transmit ANSI commands to the
screen from a batch file (see PROMPT). 

Commands

     Command        Description 
     ------------------  -------------------------------------------------- 
	  ESC[rowsA           Cursor up
	  ESC[rowsB           Cursor down
	  ESC[colsC           Cursor right
	  ESC[colsD           Cursor left
	  ESC[row;colH        Set cursor position (top left is row 1, column 1)
	  ESC[2J              Clear screen
	  ESC[K               Clear from cursor to end of line
	  ESC[row;colf        Set cursor position, same as "H" command
	  ESC[=modeh          Set display mode; see table of mode values below
	  ESC[=model          Set display mode; see table of mode values below
	  ESC[attr;attr;..m   Set display attributes; see table of attribute
								 values below
	  ESC[key;string;..p  Substitute "string" for the specified key; see


                         key substitutions section below. 
     ESC[s               Save cursor position (may not be nested) 
	  ESC[u               Restore cursor position after a save

Display Attributes 

     Attribute Description 
     --------- --------------------------------------------------- 
	  0         All attributes off (normal white on black)
     1         High intensity (bold) 
     2         Normal intensity 
     4         Underline (usually effective only on monochrome displays) 
	  5         Blinking
     7         Reverse Video 
	  8         Invisible
	  30-37     Set the foreground color:
						  30=Black   31=Red       32=Green   33=Yellow
						  34=Blue    35=Magenta   36=Cyan    37=White
	  40-47     Set the background color:
						  40=Black   41=Red       42=Green   43=Yellow
						  44=Blue    45=Magenta   46=Cyan    47=White

Settings are cumulative, so (for example) to set bright red foreground set
all attributes off, then set red, then bold:  echo _[0;31;1m.

Siehe ansi.h: Dort z.B.:
	const char* VDG_SCHWARZ = "[30m"
	const char* VDG_ROT  	= "[31m"

	const char* HTG_SCHWARZ = "[30m"
*/

#include "iostream.h"
// #include "strstrea.h"
// #include "stdlib.h"

int main(void)
{
	cout << "[2J" << "[ANSI] - Test\n";
	// char cInt[3];
	for (int i = 0; i <= 7; ++i)
	{
		cout << "\n";
		for (int j = 0; j <= 7; ++j)
		{
			char* esc = "[3 ;4 m " ;
			// itoa (i, cInt, 10);
			esc[3] = i + '0';
			//itoa (i+1, cInt, 10);
			// esc[4] = 'm';
			// esc[5] = cInt[0];
			esc[6] = j + '0';
			cout << esc << 30 + i << " " << 40 + j << "   ";
		}
	}
	cout << "\n[36m" << "[41m" << "36 41 ";
	return 0;
}

Womöögich muss man den Beitrag zitieren, um im Editmode an die unverfälschten, nichtdarstellbaren Zeichen zu kommen.

Eine Bibliothek braucht man nicht zwingend.

IHaveNoIdea

(Themenstarter)

Anmeldungsdatum:
28. Juli 2014

Beiträge: 57

Das funktioniert! Ich habe bis jetzt [H und [2J auf dem Gnome-Terminal, xterm und den Terminals in Linux ausprobiert. Im gcc kann man Escape-Sequenzen mit \e escapen, man muss also nicht wirklich den Escape-Charakter eintippen (das wäre bei meinem Vim im Terminal auch ziemlich dämlich ☺ )

mit [X;YH kann man in dem Terminalfenster hin und her springen und der Cursor schreibt einfach über den Buffer drüber. Ich habe gedacht, dass in einem Terminal mehr "Magie" drinsteckt.

Es wundert mich aber , dass das so ganz ohne Double Buffering funktioniert ohne, dass man irgendwelche "halben Bilder" sieht.

Danke für den Text. Wenn selbst MS DOS hier mit Linux kompatibel ist scheinen die Escape-Sequenzen doch relativ einheitlich zu sein.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

Du willst aber eigentlich eher (n)curses für so etwas verwenden, damit es auch für verschiedene Terminals funktioniert. Für genau diesen Anwendungsfall ist diese Bibliothek doch gemacht.

IHaveNoIdea

(Themenstarter)

Anmeldungsdatum:
28. Juli 2014

Beiträge: 57

rklm schrieb:

Du willst aber eigentlich eher (n)curses für so etwas verwenden, damit es auch für verschiedene Terminals funktioniert. Für genau diesen Anwendungsfall ist diese Bibliothek doch gemacht.

Da hast du recht. Aber mich hat auch interessiert, wie das intern umgesetzt wird und ncurses ist da mehr so etwas, wie ein komplettes GUI-Toolkit für die Kommandozeile.

Es gibt aber Bibliotheken dazwischen, wie z.B. Termcap, die nur die Escape-Sequenzen abstrahieren. Nicht jedes Programm, das auf das Terminal zugreift braucht gleich ein soviel (screen verwendet z.B. direkt Termcap)

Aber in einem richtigen TUI-Programm würde ich natürlich (n)curses verwenden. Der Geschwindigkeitsvoteil, den ich ohne gewinnen könnte ist wirklich zu vernachlässigen. (ein hastig selbst zusammengeschriebenes Programm wäre wahrscheinlich sogar noch langsamer.)

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17618

Wohnort: Berlin

IHaveNoIdea schrieb:

Danke für den Text. Wenn selbst MS DOS hier mit Linux kompatibel ist scheinen die Escape-Sequenzen doch relativ einheitlich zu sein.

Ich glaube 2 Farben sind irgendwo/wie vertauscht und es soll Dinge geben wie Blinken, Unterstrichen, Fett, Unsichtbar und Espresso die bei mir auch nicht alle funktioniert haben.

Als ich das damals benutzt habe gab es zwar schon ncurses aber ich habe keine Anleitung gefunden wie es zu verwenden wäre. Und es sollte ohne viel Bohei auf DOS laufen, für das es auch eine ncurses-lib hätte geben sollen, aber die hätte ich erst suchen müssen. Außerdem kam ich ja den umgekehrten Weg. 😉

Antworten |