Ersatz für Borland C++ gettext und puttext unter MS C/C++ 7.00 - Dos



  • Hallo,

    habe in diesem Forum einen Thread gefunden, der sich mit dem Ersatz von Borland C++ Befehlen für andere 16 Bit Compilern beschäftigt. Er war sehr hilfreich und ich konnte einige wichtige Befehle wie gotoxy() oder textcolor() unter MS C/C++ 7.00 ersetzten. Leider fehlen 2 wichtige Funktionen in diesem Beitrag. Das sind gettext() und puttext().

    Eigentlich stellt MC C/C++ 7.00 ähnliche Funktionen (z.B. _gettextwindow und _settextwindow) zur Verfügung. Diese erzwingen aber immer einen Fullscreen beim Programmstart, was mir natürlich nicht gefällt.

    Kurz gesagt. Kann mir jemand mit gettext() und puttext() weiter helfen? Ein lauffähiger assembler code würde völlig reichen.

    Erst einmal vielen Dank.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Geht es Dir weiterhin um 16bit Software?

    Ansonsten siehe Consolen FAQ:
    http://www.c-plusplus.net/forum/f20



  • Hallo,

    ich denke es geht nicht um Winapi. Es ist ein reiner Fall der 16 Bit C / C++ Programmierung unter Dos im Textmode. Dabei sollen Befehle von Borland C++ unter MS C / C++ 7.00 nachgebaut werden.

    Es handelt sich in erster Linie um die Befehle gettext() und puttext(). Diese sind verwandt mit gotoxy(), textbackground() textecolor() etc.

    Ich hoffe es ist nun klarer.

    Viele Grüße



  • Ist lange her.

    Unter 16bit-DOS konnte man den Speicher der Grafikkarte im Textmodus direkt ansprechen. 64k Adresssegment A oder B - genaues müsste ich selbst suchen.
    Wenn ich mich recht erinnere, sollte da auch schreiben und lesen funktionieren.

    Alternativ könnte der "Videointerrupt" dir da auch weiter helfen.
    Stichwort: Ralf Brown's Interrupt List.

    Ob das auch noch mit DOS-Emulatoren funktioniert?

    In der Hilfe deines alten MSC 7.0 findest du nichts? Eventuell in den Beispielen?

    MfG f.-th.



  • In den Beispielen des MC C 7.00 finden sich einige Befehle wie z.B. _outtext, _settextposition etc.

    Wenn man diese Befehle verwendet schaltet das Dos-Programm zu Beginn immer in den Fullscreen. Daher versuche ich alternative Funktionen zu finden, bei denen das nicht passiert. In diesem Forum wurden schon einige vorgestellt, die funktionieren, ohne in den Vollbildmodus zu schalten.

    Jetzt fehlt nur noch die Möglichkeit den Bildschirm zu speichern (Gettext) und ihn wieder herzustellen (puttext).

    Vielen Dank für die Mühe bis hierher!



  • Nun der Link über den nützlichen Thread (auch in diesem Forum). Das hat schon viel gebracht und die Dosprogramme laufen nun - wie gewünscht - im Fenster statt im Vollbild.

    Lieder fehlen in dieser Aufstellung - wie schon erwähnt - noch die Befehle gettext() und puttext().

    http://www.c-plusplus.net/forum/285926-full

    Siehe den code "coltool.h" und "coltool.c".



  • Also richtiges 16-Bit DOS hat man hier im Forum vor einiger Zeit "beerdigt". Das Forum ist read-only.

    An die benötigten Funktionen kann ich mich momentan nicht mehr genau erinnern.

    Wie sehen denn die Funktionen genau aus und was machen sie? Habe kein Buch über Turbo-C finden können.

    Beim googeln habe ich sowas gefunden

    http://www.thradams.com/codeblog/console.htm

    Wenn ich mir die Beiträge aus http://www.c-plusplus.net/forum/285926-full
    ansehe würde ich aber eher auf Int 10h (BIOS-VIDEO-Interrupt) tippen.
    -Funktion 08h: ASCII-Code an der aktuellen Cursorposition auslesen
    -Funktion 0Eh: Schreiben eines Zeichens an aktueller Cursorposition



  • Vielen Dank für die Antwort. Schade, dass Dos aus diesem Forum verbannt wurde.

    Leider handelt es sich bei deinem Link um eine Lösung für die Portierung von den Turbo C++ Befehlen nach Windows Console (32 bit). Das hilft leider nicht. Trotzdem danke!!!

    Wäre toll, wenn jemand noch eine Lösung findet. Mir fehlen tatsächlich nur noch die zwei Befehle (s.o.).

    Viele Grüße



  • fellowsgarden schrieb:

    Wäre toll, wenn jemand noch eine Lösung findet. Mir fehlen tatsächlich nur noch die zwei Befehle (s.o.).

    Es wäre natürlich hilfreich wenn Du Postings vollständig lesen würdest.

    Die benötigten BIOS-Funktionen hatte ich bereits gepostet und die Frage

    Wie sehen denn die Funktionen genau aus und was machen sie?

    ist leider unbeantwortet. Mit einiger Sicherheit sind die Funktionen trivial.



  • Entschuldige! Mit Biosfunktionen kenne ich mich leider nicht aus. Kannst du mir da mehr Informationen zukommen lassen?

    Wie sehen denn die Funktionen genau aus und was machen sie?

    Die beiden Funktionen sind wirklich einfach. Eigentlich "siehe oben" aber gerne noch genauer:

    Es handelt sich um gettext und puttext. Mit gettext kann man den aktuellen Bildschirm einer Dosanwendung (im Textmode) in einen Buffer kopieren. Mit puttext kann man den Buffer dann wieder später wieder auf dem Bildschirm ausgeben. Das macht Sinn, wenn man Teile des Bildschirms überschreibt und dann den alten Zustand später - ohne viel code - zurückholen will.

    Bei puttext und gettext kann man außerdem die Koordinaten mit übergeben, wenn nur ein Teil des Bildschirms gesichert und später zurückholt werden soll.

    Danke bis hier her!



  • fellowsgarden schrieb:

    Entschuldige! Mit Biosfunktionen kenne ich mich leider nicht aus. Kannst du mir da mehr Informationen zukommen lassen?

    Wie sehen denn die Funktionen genau aus und was machen sie?

    Die beiden Funktionen sind wirklich einfach. Eigentlich "siehe oben" aber gerne noch genauer:

    Es handelt sich um gettext und puttext. Mit gettext kann man den aktuellen Bildschirm einer Dosanwendung (im Textmode) in einen Buffer kopieren. Mit puttext kann man den Buffer dann wieder später wieder auf dem Bildschirm ausgeben. Das macht Sinn, wenn man Teile des Bildschirms überschreibt und dann den alten Zustand später - ohne viel code - zurückholen will.

    Bei puttext und gettext kann man außerdem die Koordinaten mit übergeben, wenn nur ein Teil des Bildschirms gesichert und später zurückholt werden soll.

    Die Funktion puttext in console.htm zu der ich den Link geschickt hatte macht doch genau das was du beschreibst ?!?

    Offensichtlich geht es auch mit putch().
    Mit den BIOS-Funktionen wäre es vermutlich aber schneller ...

    Leider hilft siehe oben nicht, da dort der Prototyp nicht steht!

    Hier der Code aus console.htm zum mitlesen:

    int puttext(int left, int top, int right, int bottom, const char*source)
        {
            if(source == 0)
                return 0;
            const char * pszText = (const char *) source;
            int count = 0;
            for(int k = top; (k <= bottom) && (*pszText); k++) {
                for(int i = left; (i < right) && (*pszText); i++) {
                    gotoxy(i, k);
                    putch(*pszText);
                    count++;
                    pszText++;
                }
            }
            return count;
        }
    

    Das ist einfachstes ANSI-C (wenn man gotoxy schon hat wovon ich ausgehe).
    Das Feature Cursor an die alte Stelle setzen habe ich gelöscht.

    Vermutlich macht gettext einfach das Gegenteil, oder etwa nicht ?

    einige vorgestellt, die funktionieren, ohne in den Vollbildmodus zu schalten.

    Zeig doch mal GENAU die Funktionen die für Dich OK sind, wenn es so nicht passt !

    Wegen BIOS-Funktionen hat f.-th. Dir die Referenz bereits genannt. Probier erstmal selbst aus bevor Du fragst! Bei Problemen gibts dann Hilfe.



  • Der "echte" Text-Mode unter DOS verwendet soweit ich weiss die selben Adressen wie die "einfachen" Grafik-Modes (z.B. 320x200x8).
    Also Segment A000 ab Offset 0.

    Da drinnen stehen dann der Reihe nach die einzelnen Zeichen.
    Wobei immer zwei Byte pro Zeichen verwendet werden, eins für das Zeichen selbst (gerade Adressen) und eins für die "Attribute" (Farbe etc., ungerade Adressen).

    Wenn du die Breite des verwendeten Text-Modes kennst, und weisst ob nur die Zeichen oder Zeichen+Attribute kopiert werden sollen, dann sollte die Implementierung der gettext / settext Funktionen relativ einfach sein:
    nen Far-Pointer auf A000:0000 machen, und dann mit den entsprechenden Offsets (vermutlich y * Breite + x ) die Zeichen rauskopieren/reinkopieren.

    Und bei "emulierten" Text-Modes, die in wirklichkeit Grafik-Modes sind, funktioniert das so natürlich nicht mehr.



  • @merano
    Ich behaupte mal dass das a) ziemlich langsam sein wird und b) beim Schreiben der rechten unteren Ecke buggen wird 😉
    Und, achja, c) dass die Original Funktionen die Cursorposition vermutlich nicht ändern.



  • hustbaer schrieb:

    @merano - Ich behaupte mal dass das a) ziemlich langsam sein wird

    Hab nichts anderes behauptet, es war nichts gefordert - reicht möglicherweise.

    hustbaer schrieb:

    b) beim Schreiben der rechten unteren Ecke buggen wird 😉

    Das Scrollen des Screens sollte man vermeiden, klar.

    hustbaer schrieb:

    c) dass die Original Funktionen die Cursorposition vermutlich nicht ändern.

    GotoXY sollte genau das aber tun - was sonst ?

    Dein Ansatz den Screen direkt auszulesen funktioniert, wenn man genau weiss
    welche Grafikkarte man hat und in welchem Modus sie sich befindet. Ich würde es
    nur in Erwägung ziehen wenn BIOS auch noch zu langsam sein sollte.

    -----

    Hier noch die Funktion zum Lesen eines Zeichens an der Cursorposition:

    AH = 08h VIDEO - READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION

    http://www.ctyme.com/intr/rb-0098.htm

    void readscreen(in x, int y, char *pbyte, char *pcol)
    {
      char  cbyte, ccol;
    
      gotoxy(x, y);     /* Cursor an Position X,Y */
    
      asm { 
        mov  ah, 08h;   /* Zeichen an Cursorposition lesen */ 
        mov  bh, 0;
        int  10h; 
        mov  ccol, ah;
        mov  cbyte, al;
      }
    
      *pbyte = cbyte;
      *pcol  = ccol;
    
      return;
    }
    

    *Da ich weder Lust noch Zeit habe mich mit 16Bit Kram zu beschäftigen hab ich
    es nicht aktuell ausprobiert, sollte aber so ähnlich aussehen.



  • @merano

    merano schrieb:

    hustbaer schrieb:

    @merano - Ich behaupte mal dass das a) ziemlich langsam sein wird

    Hab nichts anderes behauptet, es war nichts gefordert - reicht möglicherweise.

    Ja, reicht möglicherweise. Die Original-Funktionen sind allerdings genau dazu da nicht so langsam zu sein. Wobei die Rechner seit damals natürlich um einiges schneller geworden sind - mag also sein dass es wirklich reicht. Andrerseits kommt heutzutage viel Virtualisierungs- bzw. Emulations-Overhead dazu. Könnte also sein dass es doch nicht reicht 🙂

    merano schrieb:

    hustbaer schrieb:

    c) dass die Original Funktionen die Cursorposition vermutlich nicht ändern.

    GotoXY sollte genau das aber tun - was sonst ?

    Ich beziehe mich hier auf die gettext()/settext() Funktionen, nicht auf GotoXY().

    merano schrieb:

    Dein Ansatz den Screen direkt auszulesen funktioniert, wenn man genau weiss
    welche Grafikkarte man hat und in welchem Modus sie sich befindet. Ich würde es
    nur in Erwägung ziehen wenn BIOS auch noch zu langsam sein sollte.

    Och, die Grafikkarte sollte hübsch egal sein, die Standard-Modi sind bei allen gleich. In welchem Modus sie sich befindet muss man natürlich wissen, das ist klar.
    Wobei... mMn. müsste aber alles bis auf die Breite egal sein.
    Die originalen Funktionen von Borland machen vermutlich auch nix anderes.



  • Ja toll! So eine rege Beteiligung bei diesem Olttimer-Thema.

    Habe die code-Beispiele von merano (Ansi und assembler) zusammengebracht.

    Klappt leider noch nicht. Ist wahrscheinlich nur eine Kleinigkeit. Hier der code:

    int gettext(int left, int top, int right, int bottom, void*destin)
    {
       int count = 0;
       int k;
       int i;
       char pcol[2]; // noch unklar da bisher ohne Farben
    
       char * pszText = (char *) destin;
    
       if (destin == 0) return 0;
    
       for (k = top; (k <= bottom) && (*pszText); k++)
          {
           for (i = left; (i <= right) && (*pszText); i++)
    	  {
    	   readscreen(i, k, *pszText, pcol);
    	   count++;
    	   pszText++;
    	  }
          }
       *pszText = 0;
       return count;
    }
    
    int puttext(int left, int top, int right, int bottom, const char*source)
    {
       int count = 0;
       int k;
       int i;
    
       const char * pszText = (const char *) source;
       if (source == 0) return 0;
    
       for (k = top; (k <= bottom) && (*pszText); k++)
          {
           for (i = left; (i < right) && (*pszText); i++)
    	  {
    	   gotoxy(i, k);
    	   putch(*pszText);
    	   count++;
    	   pszText++;
    	  }
          }
       return count;
    }
    
    void readscreen(int x, int y, char *pbyte, char *pcol)
    {
       char  cbyte, ccol; 
    
       gotoxy(x, y);     /* Cursor an Position X,Y */ 
    
       __asm {
         mov  ah, 08h;   /* Zeichen an Cursorposition lesen */ 
         mov  bh, 0; 
         int  10h; 
         mov  ccol, ah; 
         mov  cbyte, al; 
       } 
    
       *pbyte = cbyte; 
       *pcol  = ccol; 
    
       return; 
    }
    

    Hat jemand eine Idee?



  • fellowsgarden schrieb:

    Klappt leider noch nicht. Hat jemand eine Idee?

    Normalerweise erntet man für solche Fragen einen blöden Kommentar; z.B. das das keine sinnvolle
    Fehlerbeschreibung ist und das man eigentlich erwartet, das die Fehlerstelle oder Fehlermeldungen
    des Compilers angegeben werden sollen.

    Naja, in diesem Fall wird der Compiler sagen:

    error C2664: 'readscreen': Konvertierung des Parameters 3 von 'char' in 'char *' nicht möglich

    Und natürlich müsste es eher so aussehen:

    int gettext(int left, int top, int right, int bottom, void*destin) 
    { 
       int count = 0; 
       int k; 
       int i; 
       char pcol; // noch unklar da bisher ohne Farben 
    
       char * pszText = (char *) destin; 
    
       if (destin == 0) return 0; 
    
       for(k=top; k <= bottom; k++) 
          { 
           for(i=left; i <= right; i++) 
          { 
           readscreen(i, k, pszText, &pcol); 
           count++; 
           pszText++; 
          } 
          } 
       *pszText = 0; 
       return count; 
    }
    


  • Hallo merano,

    ja ja, du hast ja Recht. Bist ziemlich streng aber in der Tat bin ich sonst immer nur Forum-Leser. Bis heute gab es immer einen Thread der irgendwie geholfen hat. Versuche mich als Schreiberling zu bessern.

    Musste ein paar kleine Änderungen vornehmen und nun klappt es.

    Die Änderungen siehe Auskommentierungen. Außerdem musste gotoxy durch setcursor ersetzt werden (siehe weiter unten).

    Hier der geänderte Code:

    int gettext(int left, int top, int right, int bottom, void*destin)
    {
       int count = 0;
       int k;
       int i;
       char pcol;
    
       char * pszText = (char *) destin;
    
       if (destin == 0) return 0;
    
       for (k = top; (k <= bottom)/* && (*pszText)*/; k++)
          {
           for (i = left; (i </*=*/ right)/* && (*pszText)*/; i++)
    	  {
    	   readscreen(i, k, pszText, &pcol);
    	   count++;
    	   pszText++;
    	  }
          }
       *pszText = 0;
       return count;
    }
    
    int puttext(int left, int top, int right, int bottom, const char*source)
    {
       int count = 0;
       int k;
       int i;
    
       const char * pszText = (const char *) source;
       if (source == 0) return 0;
    
       for (k = top; (k <= bottom) && (*pszText); k++)
          {
           for (i = left; (i < right) && (*pszText); i++)
    	  {
    //	   gotoxy(i, k);
    	   setcursor(0, i, k);
    	   putch(*pszText);
    	   count++;
    	   pszText++;
    	  }
          }
       return count;
    }
    
    void readscreen(int x, int y, char *pbyte, char *pcol)
    {
       char  cbyte, ccol; 
    
       //gotoxy(x, y);     /* Cursor an Position X,Y */
       setcursor(0, x, y);
    
       __asm {
         mov  ah, 08h;   /* Zeichen an Cursorposition lesen */ 
         mov  bh, 0; 
         int  10h; 
         mov  ccol, ah; 
         mov  cbyte, al; 
       } 
    
       *pbyte = cbyte; 
       *pcol  = ccol; 
    
       return; 
    }
    

    Warum gotoxy nicht klappt ist unklar. Hier aber der Thread aus dem gotoxy und setcursor abgeleitet sind:

    http://www.c-plusplus.net/forum/285926-full

    Klasse, dass es nun funktioniert. Jetzt wäre natürlich auch noch alles mit Farben großartig. Werde es erst einmal selber versuchen. Ansonsten Hilfe ist immer erwünscht.

    Vielen Dank bis hier her.



  • fellowsgarden schrieb:

    Hallo merano,

    ja ja, du hast ja Recht. Bist ziemlich streng

    Eher ziemlich freundlich hätte ich gesagt.

    Ich hätte dir ganz anders geantwortet.
    Die Formulierung, die Art & Weise wie du uns deine Frage hinwirfst, sind ja schon ziemlich frech.


Anmelden zum Antworten