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



  • 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.



  • fellowsgarden schrieb:

    Warum gotoxy nicht klappt ist unklar.

    Wieso unklar ?

    (Weil es einfach nicht reicht den Wert in eine globale Struktur zu schreiben ?!)

    Naja, schön das es mit Setcursor funktioniert.

    PS: Ich hätte setcursor eher wie folgt kodiert, aber das ist wohl Geschmackssache.

    void setcursor(int page, int x, int y)
    {
     __asm {
         mov  ah, 02h;   /* Cursorposition setzen */ 
         mov  bh, page;
         mov  dl, x;
         mov  dh, y;
         int  10h; 
       } 
    }
    


  • Ehrlich gesagt bin ich ziemlich überrascht über die starke Kritik. Früher habe ich immer ziemlich ausführlich geschrieben. Da wurde ich kritisiert dafür, dass es zu lang ist. Dann habe ich mir mit Mühe angewöhnt, möglichst prägnant zu schreiben. Jetzt heißt es, es sei ziemlich frech. Wie auch immer. Wie man es macht, Kritik kommt fast immer aus einer Richtung. Gebe aber zu, zuwenig auf die ersten Vorschläge (z.B. Biosfunktionen) eingegangen zu sein. Außerdem gingen meine Antworten immer nur an merano. Das war auch nicht gut.
    Es ist auch immer schwierig rein schriftlich etwas herüberzubringen und dabei die richtigen Emotionen auszulösen. Der Eine liest zwischen den Zeilen eine Kritik, der andere interpretiert es als Witz. Das ist halt ein Problem, wenn man sich nicht mehr wie früher gegenübersteht. Da helfen auch Smileys etc nicht immer.

    Ich versuche mich aber zu bessern und einige Fehler in Zukunft zu vermeiden. Zum Schluss - noch einmal deutlich - an alle Beteiligten. Ihr habt mir sehr geholfen!



  • Hallo,

    PS: Ich hätte setcursor eher wie folgt kodiert, aber das ist wohl Geschmackssache.

    Danke noch für den Nachtrag. Werde deine Version von setcursor verwenden. Bin mit den anderen Tipps ja auch gut gefahren.

    Viele Grüße


Anmelden zum Antworten