Forum: PC-Programmierung C gesammte Konsole auslesen


von Llemaban (Gast)


Lesenswert?

Hallo Zusammen

Ich suche verzweifelt einen Weg, um in C den gesamten angezeigten Text 
auf der Konsole auszulesen, um diesen zwischenzuspeichern.

Hintergrund:
Ich bin dabei einige Spiele zu programmieren, welche auf der Konsole 
laufen. Beim drücken von ESC soll das Spiel unterbrochen werden und sich 
in der Mitte des "Spielfeldes" ein "Unterbruch-Fenster" über den Rest 
aufbauen:
1
Beispiel Snake-Feld:     Beispiel bei Unterbrechung:
2
+--------------------+   +--------------------+
3
|                    |   |                    |
4
| ooooooooo          |   | ooooooooo          |
5
|         o          |   |   +============+   |
6
|         o          |   |   |            |   |
7
|         o          |   |   | Unterbruch |   |
8
|         oooo>   $  |   |   |            |$  |
9
|                    |   |   |            |   |
10
|                    |   |   +============+   |
11
|                    |   |                    |
12
|                    |   |                    |
13
+--------------------+   +--------------------+

Sobald ich das "Unterbruch-Fenster" wieder schliesse, sollte das 
vorherige "Spielfeld" wieder eingeblendet (bzw aufgebaut) werden.
Aufbau des "Unterbruch-Fenster" ist kein Problem, aber leider weiss ich 
nicht, wie ich direkt aus der Konsole auslesen kann, um dessen Inhalt 
zuvor zwischenzuspeichern.

lg Llemaban

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Merke dir doch besser, was vorher dort stand.

von Nase (Gast)


Lesenswert?

Llemaban schrieb:
> wie ich direkt aus der Konsole auslesen kann, um dessen Inhalt
> zuvor zwischenzuspeichern.

Garnicht.

Historische Erklärung: "Konsole" war früher ein Nadeldrucker. Wie 
wolltest du da irgendetwas auslesen?

Zeitgemäße Erklärung: Google mal nach "ncurses", damit wirst du 
sicherlich weiterkommen.

von Max M. (jens2001)


Lesenswert?

Llemaban schrieb:
> einige Spiele zu programmieren, welche auf der Konsole
> laufen

Llemaban schrieb:
> aus der Konsole auslesen

Wiso willst du da was "auslesen"?
Du musst doch selbst am besten wissen was du da hinein geschrieben hast!

von Mag (Gast)


Lesenswert?

.. so falsch ist der Gedanke garnicht. Zu Zeiten von DOS lagen die Daten 
ab Adresse 0x800, und eine Kopie mit memcpy war ein effektiver Weg.
Unter Linux wird das praktisch nichts mehr, da die Konsole anders 
abstrahiert ist (als Drucker bzw. Stream).

von Dr. Sommer (Gast)


Lesenswert?

Wenn du das snake-Feld einmal gezeichnet hast, wirst du es doch noch 
einmal, nach dem Schließen des Fensters, schaffen...

von Llemaban (Gast)


Lesenswert?

Danke für alle Antworten.

Nase schrieb:
> Google mal nach "ncurses"

Danke, die kannte ich bisher noch nicht. Sieht auch ziemlich mächtig 
aus...

Mag schrieb:
> Zu Zeiten von DOS lagen die Daten
> ab Adresse 0x800, und eine Kopie mit memcpy war ein effektiver Weg.

Genau an sowas hatte ich gedacht, nur habe ich keine Ahnung, an welcher 
Adresse das Zeugs jetzt drin liegt (Win10).

Meine Idee war eben NICHT alles doppelt zu speichern. Ich sehe jedoch 
langsam ein, dass dies der einfachste Weg sein wird.
Das Snake-Beispiel soll es nur veranschaulichen. Dahinter steckt eine 
ganze Reihe an verschiedenen Spielen, welche ich immer durch Aufruf der 
gleichen Unterbruch-Funktion unterbrechen möchte.
In dem Fall übergebe ich der Funktion einen Pointer zum 
Zwischenspeicher...

von Dr. Sommer (Gast)


Lesenswert?

Llemaban schrieb:
> Das Snake-Beispiel soll es nur veranschaulichen. Dahinter steckt eine
> ganze Reihe an verschiedenen Spielen, welche ich immer durch Aufruf der
> gleichen Unterbruch-Funktion unterbrechen möchte.
> In dem Fall übergebe ich der Funktion einen Pointer zum
> Zwischenspeicher...

Ja speichert denn das Spiel nicht den eigenen Zustand? Snake muss doch 
wissen wo die Schlange ist, Pong muss wissen wo der Ball ist... Wozu da 
noch einen zusätzlichen Zwischenspeicher bauen?

von Bernd K. (prof7bit)


Lesenswert?

Llemaban schrieb:
> Meine Idee war eben NICHT alles doppelt zu speichern.

Nimm doch einfach ncurses wie jeder andere es auch tun würde statt Dir 
da umständlich einen abzuwürgen und das perfekt funktionierende Rad 
unvollständig und fehlerbehaftet neu zu erfinden.

Oder wenn Du zufällig mit Lazarus/FPC unterwegs bist dann nimm Free 
Vision, das ist das gleiche in grün und objektorientiert und läuft 
ebenfalls überall. Oder Turbo Vision wenn Du mit Borland Tools 
arbeitest.

von Llemaban (Gast)


Lesenswert?

Bernd K. schrieb:
> Nimm doch einfach ncurses wie jeder andere es auch tun würde

Die schaue ich mir schon an :)

Dr. Sommer schrieb:
> Ja speichert denn das Spiel nicht den eigenen Zustand?

Gewiss doch, aber ich wollte es gerne über die Unterbruch-Funktion 
realisieren und nicht jedes mal auf die eigentlichen Funktionen des 
Spieles zurückgreifen.

Danke an die Antworten!

von Heiko L. (zer0)


Lesenswert?

Llemaban schrieb:
> Genau an sowas hatte ich gedacht, nur habe ich keine Ahnung, an welcher
> Adresse das Zeugs jetzt drin liegt (Win10).

Da musst du wohl die API welzen
https://docs.microsoft.com/en-us/windows/console/console-functions

ist ein bisschen frickelig, aber mit ein bisschen Übung bekommt man auch 
einen Backbuffer-Readback für full-scene Lichtbrechungseffekte in einer 
ASCII-art 3d engine hin. :)

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Llemaban schrieb:
> (Win10)

Ah, na immerhin wissen wir jetzt mal, dass es um Windows geht.

Llemaban schrieb:
> Dr. Sommer schrieb:
>> Ja speichert denn das Spiel nicht den eigenen Zustand?
>
> Gewiss doch, aber ich wollte es gerne über die Unterbruch-Funktion
> realisieren und nicht jedes mal auf die eigentlichen Funktionen des
> Spieles zurückgreifen.

Verstehe ich nicht. Wie soll das Spiel denn so ganz allgemein 
weiterlaufen, ohne auf dessen Funktionen "zurückzugreifen"? Und wenn es 
weiterläuft, muss es doch sowieso neu zeichnen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Man findet den Linux-Console-Inhalt in /dev/vcs bzw. /dev/vcs1, 
/dev/vcs2 usw.

cat /dev/vcs1

zeigt den Inhalt von /dev/tty1, also der 1. Linux-Console an, allerdings 
ohne die Zeilenumbrüche. Bei einer Textauflösung von 80x25 Zeichen sind 
dies exakt 2000 Zeichen:

# wc -c /dev/vcs1
2000

Das geht natürlich nur mit der entsprechenden Berechtigung, also in der 
Regel root. Außer man ändert die Berechtigung von /dev/vcsX.

Aber ich schließe mich den Vorrednern an: Entweder merkt man sich den 
ausgegebenen Bildschirminhalt selbst oder man benutzt einfach ncurses.

: Bearbeitet durch Moderator
von Vlad T. (vlad_tepesch)


Lesenswert?

Llemaban schrieb:
> Gewiss doch, aber ich wollte es gerne über die Unterbruch-Funktion
> realisieren und nicht jedes mal auf die eigentlichen Funktionen des
> Spieles zurückgreifen.
>

Ich glaub da ist was am design faul.
Klassischerweise sieht ein Spiel doch so aus:
1
enum GameState{
2
  GS_Menu,
3
  GS_Action,
4
  GS_GameOver,
5
  GS_Pause,
6
  GS_Exit
7
};
8
9
10
struct Game{
11
  GameState state;
12
  //Andere Spieldate
13
}game;
14
15
16
void irgendneMainFunktion{
17
  while(game.state != GS_Exit){
18
    leseInput;
19
    updateZustand;
20
    erzeugeAusgabe;
21
  }
22
}
Je nach Art des oder programmtechnischen Design des Spiels, hat auch 
jeder Zustand diese Funktionen, oder jede dieser Funktionen hat eine 
Unterscheidung, in welchem Zustand das Spiel gerade ist (Menü, 
Hauptspiel, Inventar, ..., Pause)

Im Falle von "Pause" macht "updateZustand" eben gar nix, und 
"erzeugeAusgabe" ruft nur die Pause-Bildschirm-Zeichnen Funktion auf 
(die braucht dann von dem Spiel auch überhaupt nix wissen). Erst wenn in 
"leseInput" entschieden wird, dass der Benutzer den Zustand 
zurückwechselt, erzeugt "erzeugeAusgabe" wieder den Spielbildschrim.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.