Pokaż wyniki 1 do 5 z 5

Temat: Własne Crt - Turbo Pascal, Free Pascal itp.

  1. #1
    Zarejestrowany
    Aug 2007
    Skąd
    Gdzie nogi poniosą.
    Postów
    175

    Domyślnie Własne Crt - Turbo Pascal, Free Pascal itp.

    Witam!
    Gdyby kogoś interesowało jak w Pascalu wmiare sprawnie poradzić sobie ze sterowaniem wyświetlania tekstu w konsoli to zamieszczam poniższy kod.

    Tym się rózni od normalnego Crt, że aby wyswietlic tekst nalezy uzyc polecenia "PokazEkran".
    Pomaga to w zredukowaniu migania ekranu jeśli chcesz napisać np. grę dla konsoli (jakiegoś roguelika, czy takie tam).

    No i nie ma w nim ReadKey, Readln, ani Sound itp.

    Oczywiscia mozna, a nawet nalezy go rozbudowac i przerobić na Unita .

    Kod:
    {====================================
     ! m33Crt v.0001                    !
     !   (c) Michal "m33" Gawryluk, 2007!
     -----------------------------------
     !!!!!!!! licencja: GPL !!!!!!!!!
     ====================================
     *Co to jest:
       Pisanie biblioteki
       a'la Crt :)
      
     *Poco to pisze:
       Aby pozniej napisac
       to dla C++ :]
     ====================================
     ! start 31 X 2007 15:45            !
     ====================================
     31 X 2007 [ 15:45 - 16:45 ]
      16:34 NOWOSCI:
             *Procedury:
                - PokazEkran.[OK]
                - GoToXY.....[OK]
                - Napisz.....[OK]
                - CzyscEkran.[OK]
     ------------------------------------
     1 XI 2007 [ 11:09 - 11:11 ]
      11:10 ZMIANY:
             *Pocedura Napisz zmienia juz
              po modyfikacji bufora
              wartosc x na wspolrzedna
              konca wprowadzonego tekstu
     ------------------------------------
     3 XI 2007 [ 19:00 - 19:01 ]
      19:01 NOWOSCI:
             * Funkcje
                - GdzieX.....[OK]
                - GzieY......[OK]
     ====================================}
    VAR
       n,n2: integer; {zmienne do wykorzystania przy iteracji}
        x,y: integer; {pozycja kursora}
     bEkran: array[1..80,1..24] of char;{bufor ekranu tu przechowywujemy tekst  do wyswietlenia}
    {------------------------------------------------------------------------------}
    
    Procedure PokazEkran;{Wyswietla zmiany bufora bEkran}
    begin
    	for n:=1 to 24 do
    					for n2:= 1 to 80 do
    									  write(bEkran[n2,n]);
    end;
    {------------------------------------------------------------------------------}
    
    Procedure GoToXY(gx,gy:integer);
    begin
     x:=gx;
     y:=gy;
    end;
    {------------------------------------------------------------------------------}
    
    Procedure Napisz(napis:string);
    begin
    n2:=1;{jako numer litery w slowie}
    for n:=x to x+(length(napis)-1) do begin bEkran[n,y]:=napis[n2]; n2:=n2+1; end;
    {A teraz trzeba zmienic wsplrzedna x by wskazywala koniec tekstu}
    x:=x+(length(napis)-1); {Dlaczego -1? Bo ostatni znak ciagu to zawsze "null"(pusty)}
    end;
    {------------------------------------------------------------------------------}
    
    Procedure CzyscEkran;
    begin
     for n:=1 to 80 do 
    		for n2:=1 to 24 do
    				bEkran[n,n2]:=' ';
    end;
    {------------------------------------------------------------------------------}
    
    function GdzieX: integer;
    begin
       GdzieX:=X;
    end;
    {------------------------------------------------------------------------------}
    function GdzieY: integer;
    begin
       GdzieY:=Y;
    end;
    
    {------------------------------------------------------------------------------}
    
    {------------------------------------------------------------------------------}
    BEGIN
    	CzyscEkran;
    	GoToXY(1,1);
    	Napisz('FIRST Hello world!!!');
    	GoToXY(2,2);
    	Napisz('SECOND Hello world!!!');
    	GoToXY(3,3);
    	Napisz('THIRD Hello world!!!');
    	Napisz(' FOURTH Hello world!!!');
    
    	PokazEkran;
    END.
    Ostatnio edytowane przez m33 : 11-16-2007 - 09:02

  2. #2
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Czy w przypadku CzyscEkran nie lepiej zamiast zapisywac 24x80 czyli 1920 znakow nie prosciej wywolac clrscr (dla zastosowan lokalnych) albo wyswietlic 24x CR+LF (bardziej uniwersalnie)?

    Pomysl o tym ze ludzie nadal pracuja czasami przez zdalny terminal 9600bps i czyszczenie ekranu w ten sposob zajmie ponad 2 sekundy, gdy robiac to sprytnie za pomoca CR+LF trwalby to 0.025 sek?

    EDIT: poprwailem literufki
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  3. #3
    Zarejestrowany
    Aug 2007
    Skąd
    Gdzie nogi poniosą.
    Postów
    175

    Lightbulb

    Dziękuje za uwagi i korektę ortografii


    W ogóle można by całość oprzeć na znakach sterujących ASCII.

    Zmienię więc nazwę CzyscEkran na CzyscBufor i dodam CzyscEkran działający w oparciu o tą parę znaków końca wiersza. Czysc bufor zapełni bEkran znakami "\0".

    Dodam tez procedurę ( lub zmodyfikuję PokazEkran), która będzie badała zawartosc bEkran i wstawi znak konca wiersza jesli w danej linijce nie ma więcej zadnych innych znaków niż "\0". To chyba powinno przyśpieszyć wyświetlanie tekstu. Czy takie rozumowanie jest słuszne?
    Ostatnio edytowane przez m33 : 11-19-2007 - 07:50

  4. #4
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Sorry ale nie bardzo rozumiem sens wysylania \0 :-(
    Wyslanie CR+LF (bo mowa tu tylko do aplikacjach DOS-o pochodnych a nie Linux/Unix gdzie byloby samo LF) powoduje przewiniecie ekranu i tyle.

    Zaproponowalem CR+LF a nie \0 poniewaz zaleznie od terminala na jakim osoba pracuje moze sie okazac, ze odswiezysz tylko pierwsza kolumne a pozostale kolumny pozostana zapisane tekstem z poprzedniego ekranu.

    Zakladajac terminal 24x80 i wysylajac kazdy ekran dlugosci 24 linii mozna to zrobic tak, ze jesli np kmomunikat ma 5 linii, to piszemy 5 linii, drukujemy 19x CR+LF aby wedziec ze tekst jest na gorze ekranu (terminala) i kodami ASCII (jesli sie da - tzn terminal to ASCII a nie VT102 lub podobny) wracamy do miejsca gdzie czekamy na input (np T/n 19 linii wyzej). Zastanawiam sie co by bylo dalej gdyby terminal byl VT102...
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  5. #5
    Zarejestrowany
    Aug 2007
    Skąd
    Gdzie nogi poniosą.
    Postów
    175

    Domyślnie

    Cytat Napisał tqm Zobacz post
    Sorry ale nie bardzo rozumiem sens wysylania \0 :-(
    Wyslanie CR+LF (bo mowa tu tylko do aplikacjach DOS-o pochodnych a nie Linux/Unix gdzie byloby samo LF) powoduje przewiniecie ekranu i tyle.
    Od siebie dodam jeszcze że w MacOs koniec linii to samo CR.

    Cytat Napisał tqm Zobacz post
    Zaproponowalem CR+LF a nie \0 poniewaz zaleznie od terminala na jakim osoba pracuje moze sie okazac, ze odswiezysz tylko pierwsza kolumne a pozostale kolumny pozostana zapisane tekstem z poprzedniego ekranu.

    Zakladajac terminal 24x80 i wysylajac kazdy ekran dlugosci 24 linii mozna to zrobic tak, ze jesli np kmomunikat ma 5 linii, to piszemy 5 linii, drukujemy 19x CR+LF aby wedziec ze tekst jest na gorze ekranu (terminala) i kodami ASCII (jesli sie da - tzn terminal to ASCII a nie VT102 lub podobny) wracamy do miejsca gdzie czekamy na input (np T/n 19 linii wyzej). Zastanawiam sie co by bylo dalej gdyby terminal byl VT102...
    Widzę, że myśimy mniej więcej tak samo.

    A sens użycia null'a mam nadzieję rozjaśni zmodyfikowany kod źródłowy.
    Zmiany objaśniłem komentarzami. Działa to teraz tak jak sugerowałeś, z tym,że na razie nie ma powrotu do "miejsca gdzie czekamy na input".


    Użyłem tu Unixowego znaku końca linii.
    Kod:
    {====================================
     ! m33Crt v.0003                    !
     !   (c) Michal "m33" Gawryluk, 2007!
     ====================================
     *Co to jest:
       Pisanie biblioteki
       a'la Crt :)
      
     *Poco to pisze:
       Aby pozniej napisac
       to dla C++ :]
     ====================================
     ! start 31 X 2007 15:45            !
     ====================================
     31 X 2007 [ 15:45 - 16:45 ]
      16:34 NOWOSCI:
             *Procedury:
                - PokazEkran.[OK]
                - GoToXY.....[OK]
                - Napisz.....[OK]
                - CzyscEkran.[OK]
     ------------------------------------
     1 XI 2007 [ 11:09 - 11:11 ]
      11:10 ZMIANY:
             *Pocedura Napisz zmienia juz
              po modyfikacji bufora
              wartosc x na wspolrzedna
              konca wprowadzonego tekstu
     ------------------------------------
     3 XI 2007 [ 19:00 - 19:01 ]
      19:01 NOWOSCI:
             * Funkcje
                - GdzieX.....[OK]
                - GzieY......[OK]
     ------------------------------------
     19 XI 2007 [ 15:45 - 16:56]
     ====================================}
    VAR
       n,n2: integer; {zmienne do wykorzystania przy iteracji}
        x,y: integer; {pozycja kursora}
     bEkran: array[1..80,1..24] of char;{bufor ekranu}
    {------------------------------------------------------------------------------}
    
    Procedure PokazEkran;{Wyswietla zmiany bufora bEkran}
    begin
    n2:=1;
    	for n:=1 to 24 
    	do begin
    					while ((bEkran[n2,n]<>char(#10)) and (n2<=80))
    						do begin
    							if bEkran[n2,n]=char(#0) then write(' ') 
    							else write(bEkran[n2,n]);
    							n2:=n2+1;
    							{write('_',n2,'_');}
    						 end;
    							n2:=1;
    							write(char(#10));
    	end;
    		
    end;
    {------------------------------------------------------------------------------}
    
    Procedure GoToXY(gx,gy:integer);
    begin
     x:=gx;
     y:=gy;
    end;
    {------------------------------------------------------------------------------}
    
    Procedure Napisz(napis:string);
    begin
    n2:=1;{jako numer litery w slowie}
    for n:=x to x+(length(napis)-1) do begin bEkran[n,y]:=napis[n2]; n2:=n2+1; end;
    {A teraz trzeba zmienic wsplrzedna x by wskazywala koniec tekstu}
    x:=x+(length(napis)-1); {Dlaczego -1? Bo ostatni znak ciagu to zawsze "null"(pusty)}
    end;
    {------------------------------------------------------------------------------}
    
    Procedure CzyscEkran;{Wyswietlenie 24 rzay znaku nowej linii}
    begin
     x:=1;
     y:=1;
     for n:=1 to 24 do write(char(#10));
    {
     -----------------------------
     |SYSTEM | znak/znaki        |
     -----------------------------
     | UNIX  |  #10              |
     | DOS   |  #10 wraz z #13   |
     | MacOS |  #13              |
     -----------------------------
    }
    end;
    {------------------------------------------------------------------------------}		
    		
    Procedure CzyscBufor;
    begin
     x:=1;
     yL=1;
     for n:=1 to 80 do 
    		for n2:=1 to 24 do
    			bEkran[n,n2]:=char(#0);
    end;		
    {------------------------------------------------------------------------------}
    
    Procedure OtworzBufor;{Kasowanie znakow nowej linii}
    begin
    n2:=0;
    	for n:=1 to 24 
    		do for n2:=1 to 80 do begin if bEkran[n2,n]=char(#10) then bEkran[n2,n]:=char(#0);  end;
    end;
    {------------------------------------------------------------------------------}
    		
    Procedure ZapiszBufor;{Wstawianie znakow nowej linii}
    var
    	koniec: word;
    begin
    koniec:=0;
     for n2:=1 to 24 do 
     begin{-n2-}
      koniec:=0;
    		for n:=1 to 80 do begin
    							if bEkran[n,n2]<>char(#0) then koniec:=0;
    							if bEkran[n,n2]=char(#0) 
    								then if koniec=0 then koniec:=n;
    						   end;
    		if koniec>0 then bEkran[koniec,n2]:=char(#10);
     end;{-n2-}
    end;		
    		
    {------------------------------------------------------------------------------}
    
    function GdzieX: integer;
    begin
       GdzieX:=X;
    end;
    {------------------------------------------------------------------------------}
    function GdzieY: integer;
    begin
       GdzieY:=Y;
    end;
    
    {------------------------------------------------------------------------------}
    
    {------------------------------------------------------------------------------
      A TERAZ CZAS NA TEST:
     ------------------------------------------------------------------------------}
    BEGIN
    	CzyscEkran;
        CzyscBufor;
    	GoToXY(1,1);
    	Napisz('1-FIRST Hello world!!!');
    	GoToXY(2,2);
    	Napisz('2-SECOND Hello world!!!');
    	GoToXY(3,3);
    	Napisz('3-THIRD Hello world!!!');
    	Napisz(' 4-FOURTH Hello world!!!');
        ZapiszBufor;
    
        OtworzBufor;
        GoToXY(30,1);
    	Napisz('5-Goodbay!!!');
        ZapiszBufor;
    	
    	PokazEkran;
    END.
    Na tyle póki co wpadłem wczoraj.
    Dodałem dwie procedury:
    * OtworzBufor - usuwająca z bufora znaki końca linii
    :
    między nimi modyfikujemy zawartość bufora
    :
    * Zapisz bufor - wstawia do bufora znaki nowej linii
    :
    Teraz Wyświetlamy tekst.
    Ostatnio edytowane przez m33 : 11-22-2007 - 09:42 Powód: Zapomniałem o zmianie wartosci x i y na 1 po wyczuszceniu ekranu

Podobne wątki

  1. Free Pascal - poczatki...
    By lokid in forum Delphi/Pascal/Lisp
    Odpowiedzi: 7
    Autor: 02-16-2010, 08:38
  2. podrzucanie trojanów(itp.)
    By hubert in forum Newbie - dla początkujących!
    Odpowiedzi: 9
    Autor: 06-17-2007, 21:26
  3. turbo pascal kody zrodlowe
    By faD in forum Delphi/Pascal/Lisp
    Odpowiedzi: 11
    Autor: 05-30-2007, 19:47
  4. zadnia z informatyki --> pascal
    By slawek14 in forum Delphi/Pascal/Lisp
    Odpowiedzi: 6
    Autor: 04-13-2007, 18:13
  5. Pascal prostokąt
    By kosiarz in forum Delphi/Pascal/Lisp
    Odpowiedzi: 3
    Autor: 03-04-2007, 01:30

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj