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
BeispielSnake-Feld:BeispielbeiUnterbrechung:
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
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.
Llemaban schrieb:> einige Spiele zu programmieren, welche auf der Konsole> laufenLlemaban schrieb:> aus der Konsole auslesen
Wiso willst du da was "auslesen"?
Du musst doch selbst am besten wissen was du da hinein geschrieben hast!
.. 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).
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...
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?
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.
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!
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. :)
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.
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.
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
enumGameState{
2
GS_Menu,
3
GS_Action,
4
GS_GameOver,
5
GS_Pause,
6
GS_Exit
7
};
8
9
10
structGame{
11
GameStatestate;
12
//Andere Spieldate
13
}game;
14
15
16
voidirgendneMainFunktion{
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.