logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?

tilosag 20 Wrz 2009 21:42 7055 19
REKLAMA
  • #1 7039754
    tilosag
    Poziom 10  
    Posty: 14
    Witam wszystkich!

    Programuję w Turbo Pascalu i natknąłem się na z pozoru nierozwiązywany problem.

    Otóż chcę odczytać kod ascii znaku, który już istnieje (jest wypisany w trybie tekstowym na ekranie, ale został utworzony wcześniej, w nieznany sposób i nie jest przypisany do żadnej zmiennej) do zmiennej.


    Czy ktoś ma jakieś koncepcje? I czy jest to w ogóle możliwe?

    Pozdrawiam
    Tilosag


    PS
    Jest to część modułu części zadania domowego (pracy przejściowej) z informatyki. Zmiana platformy z TP 7 na inną nie wchodzi w grę.

    Korzystam z Free Pascala.
  • REKLAMA
  • #2 7039845
    SPAWN17
    Poziom 16  
    Posty: 151
    Pomógł: 13
    Ocena: 4
    A odczytanie wartości z bufora? adres 0B800:0000 o ile dobrze pamiętam
  • #3 7039866
    tilosag
    Poziom 10  
    Posty: 14
    Hm? Jak się to robi? :P

    Czy mógłby kolega przybliżyć?



    Pozdrawiam
    Tilosag
  • REKLAMA
  • Pomocny post
    #4 7039949
    SPAWN17
    Poziom 16  
    Posty: 151
    Pomógł: 13
    Ocena: 4
    Turbo Pascal i jego podstawowe sterowniki są w stanie obsłużyć 15 trybów. 5 tekstowych i 10 graficznych. Można je obsługiwać za pomocą funkcji bibliotecznych lub komórek pamięci. Adres pamięci tekstowej znajduje się w 0B800h:0000h, a graficznej w 0A000h:0000h. W komórkach znajdują się dane. A teraz odczyt: funkcja mem:
    var
    odczyt : byte;
    .
    .
    odczyt := mem[$0B800:$0000];
    


    Spowoduje to odczytanie kodu znaku, który znajduje się w (1, 1). Zapis jest podobny:
    
    memW[$0B800:$0000] := 86;
    


    Przesunięcie to offset - czyli druga część adresu. Znak (1, 2) = 0B800h:0001h. Ze względu na to że pamięć jest liniowa, znak (X, Y) definiowany jest w ten sposób:
    
    0B800h:Y*ilosc_kolumn+X
    

    Dawno się tym nie zajmowałem, wiec mam nadzieję że nic nie pokręciłem. Jak komu lepiej można to robić w asm. Chętnym podam przykłady.
  • #5 7040195
    tilosag
    Poziom 10  
    Posty: 14
    Wszystko fajnie opisane, dzięki!

    Jakby ktoś szukał czegoś więcej to na http://4programmers.net/Turbo_Pascal/Efektywne_programowanie_w_Turbo_Pascalu
    rodział: Bezpośredni dostęp do pamięci

    Z tym że pojawił mi się nowy problem.

    Kod:

    uses crt,dos;
    begin
    mem[$B800:1]:=byte('#');
    end.

    i wyskakuje error:

    First compilation of c:\fpc\2.2.4\bin\i386-win32\test.pas
    test.pas(3,7) Error: Identifier not found "mem"
    test.pas(3,13) Fatal: Syntax error, "]" expected but ":" found
    test.pas(0) Fatal: Compilation aborted



    Przecież wszystko jest w porządku? (Free Pascal)
  • #6 7040288
    SPAWN17
    Poziom 16  
    Posty: 151
    Pomógł: 13
    Ocena: 4
    Brak dolara i zera. Dolar wymusza tryb szesnastkowy, a zero jest potrzebne aby to byla liczba. W dziesietnym sie nie da adresować. Specyfika Pascala. Spróbuj mem[$0B800:$0001] := '#';
  • #7 7040298
    tilosag
    Poziom 10  
    Posty: 14
    Wcale że nie!

    pomimo: mem[$B800:$0]:=byte('#');

    Błąd jaki był - taki jest
  • #9 7040372
    tilosag
    Poziom 10  
    Posty: 14
    Tylko screen może to wyrazić lepiej:

    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?
  • REKLAMA
  • Pomocny post
    #10 7040374
    SPAWN17
    Poziom 16  
    Posty: 151
    Pomógł: 13
    Ocena: 4
    Już wiem dlaczego to nie działa. Otóż Free Pascal nie obsługuje struktur MEM, MEML, MEMW i PORT. Za to Turbo Pascal 7.0 Jak najbardziej. A zatem najprościej będzie zmienić Ci IDE. Możesz też poszukać biblioteki do FP o nazwie GO32.PPU. Wszystko to jest opisane tutaj: http://coleweb.dc.fi.udc.es/docencia/edi/freepascal/doc/user/node8.html
  • #11 7040611
    tilosag
    Poziom 10  
    Posty: 14
    Problem rozwiązała zmiana kompilatora na Turbo Pascal 7 (1szy wynik z Google)

    Pozdrawiam

    (Nigdzie nie mogłem znaleźć tej biblioteki go32.ppu)


    EDIT: I można adresować po dziesiętnych :P


    EDIT2: omg! ten kompilator TP7 działa o wiele gorzej niż FPC i przyposzczałem. Program który ładnie, płynnie chodził, teraz się tnie i mam pokaz slajdów :(

    EDIT3: pojawił mi się jakiś lolerror nie wiadomo skąd! Przedtem go nie było i w dodatku pojawia się na samym końcu (przy "end.");


    biblioteka.pas(253,1) Error: Undefined symbol: _mcount
    biblioteka.pas(253,1) Fatal: There were 1 errors compiling module, stopping
    biblioteka.pas(0) Fatal: Compilation aborted

    Załączę też plik z programem.


    Ktoś widzi jakieś wyjście? Przeinstalowywałem już kilka razy FPC do różnych lokalizacji i dalej to samo.


    Pozdrawiam
    Tilosag
    Załączniki:
    • biblioteka.pas.txt (4.28 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • #12 7043928
    SPAWN17
    Poziom 16  
    Posty: 151
    Pomógł: 13
    Ocena: 4
    Bez users_db,panel_u ciezko bedzie mi znaleść błąd. Moze istnieje w tych bibliotekach? Pierwsze slysze zeby takie dziwne rzeczy dzialy sie z TP7 :/ Nie wiem co moze byc tego przyczyna. Kozystalem z niego na 486 pod win95 i 98 oraz na nowszych z winXP. Nie bylo problemow. Trzeba tylko skonfigurowac kompilator jak ktos chce uzywac asemblera i skokow.
  • #13 7044647
    tilosag
    Poziom 10  
    Posty: 14
    Mnie również to zszokowało, gdy normalnie włączyłem FPC, zrobiłem małą poprawkę w kodzie i kompiluję... error jakiego w życiu nie widziałem który dotyczy "end."?! wtf?!

    Załączam wszystkie potrzebne moduły:

    test_bib.pas -> służy do ręcznego dodawania użytkowników do bazy (bo jescze nie zrobiłem panelu bibliotekarza :P )

    panel_u.pas -> jak sama nazwa wskazuje

    users_db.pas -> wszystkie możliwe operacje na bazie danych

    Przekopałem wszystkie 3 pliki i wszystkie się ładnie kompilują, nie wiedzieć czemu akurat główny plik z programem nie chce :/

    Pozdrawiam
    Tilosag
    Załączniki:
    • users_db.pas.txt (2.42 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • test_bib.pas.txt (690 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.
    • panel_u.pas.txt (2.08 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #14 7045008
    arnoldziq
    VIP Zasłużony dla elektroda
    Posty: 5376
    Pomógł: 789
    Ocena: 300
    Twój program kompiluje się całkowicie poprawnie.
    Według mnie napisany jest wadliwie; np. wszystkie te LABEL-e, brak obsługi błędów zakładania plików itd.
    Ale nie mniej, kompilacja przebiega poprawnie.
    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?

    Po kilku zmianach ja ta poniżej, można go nawet uruchomić.
    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?
  • #15 7045215
    tilosag
    Poziom 10  
    Posty: 14
    Wszystko jest ok, ale w Turbo Pascalu. Program jeszcze nie jest napisany nawet w połowie, więc dużo mu do celu jakim jest obsługa biblioteki.

    Tymczasem mi chodzi o kompilator Free Pascala, który kompiluje go jakoś inaczej i przez to bajery takie jak: po zalogowaniu się, pasek przesuwa się płynnie, działają normalnie. W TP wszystko się tnie!


    Btw: dlaczego Labele są z natury złe? skoro zostały stworzone to w jakimś konkretnym celu


    EDIT: na stronie FPC znalazłem chyba unit który mnie interesuje: http://www.stack.nl/~marcov/files/xtdfpc.zip

    tylko nie mam pojęcia jak go zainstalować :(
  • Pomocny post
    #16 7045353
    arnoldziq
    VIP Zasłużony dla elektroda
    Posty: 5376
    Pomógł: 789
    Ocena: 300
    tilosag napisał:
    Wszystko jest ok, ale w Turbo Pascalu. Program jeszcze nie jest napisany nawet w połowie, więc dużo mu do celu jakim jest obsługa biblioteki.


    Przykro mi ale z Free pascalem ci nie pomogę. Za dużo pieniędzy wydałem na TP, żeby z tego rezygnować. I będę bronił Borland/Turbo Pascal-a aż do śmierci :)

    tilosag napisał:
    Tymczasem mi chodzi o kompilator Free Pascala, który kompiluje go jakoś inaczej i przez to bajery takie jak: po zalogowaniu się, pasek przesuwa się płynnie, działają normalnie. W TP wszystko się tnie!


    Trochę się zagubiłem; to działa po TP czy nie ?
    Nie wiem o jaki pasek ci chodzi. Może o zawartość tych 2 plików 'introtxt.txt' i 'intro.txt' ? Po utworzeniu tych plików na moim ekranie pojawia się coś takiego :
    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?
    Dzieje się to natychmiast i nie bardzo wiem o jakich paskach mówisz.

    tilosag napisał:

    Btw: dlaczego Labele są z natury złe? skoro zostały stworzone to w jakimś konkretnym celu


    LABEL-e nie są złem wcielonym i masz rację : jeżeli są to można ich używać. Jednak... jeżeli kod się trochę skomplikuje - nie ma fizycznej możliwości prześledzić co w programie nie działa ... :( Po prostu zagubisz się. Znacznie bezpieczniej jest stosować procedury i pętle for..do lub while..do.
  • #17 7045432
    tilosag
    Poziom 10  
    Posty: 14
    Przepraszam że ich nie dołączyłem. :P Znajdują się tam obrazki w ascii.

    Tak powinno wszystko wyglądać:

    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?

    A pasek którego nie widziałeś, pojawia się po wpisaniu poprawnego loginu i hasła. (taki loading xD)

    [Turbo Pascal] Jak odczytać kod ASCII znaku z ekranu w trybie tekstowym?


    EDIT: i jescze jedna bardzo dziwna rzecz w TP. Mianowicie, jak zmieniam sobie kolory (textcolor) i chcę wrócić do defaultowego (nr 15) to jest on BIELSZY (zresztą jak widać na screenie załączonym, przy renderowaniu kolejnej ramki). Coś nie tak jest :P ja chce ten normalny bardziej szary kolor!

    EDIT2: Jak widzisz na obrazku moja ramka w Y ma 24 "pixele" wysokości, gdyż jak próbowałem narysować ramkę na poziomie 25 to pascal automatycznie przesuwał mi okno jeden "pixel" niżej. Da się coś z tym zrobić?



    btw jakby znalazł się ktoś kto wie jak zainstalować bibliotekę go32 która jest w pliku który już podałem, to proszę o kontakt.
    Załączniki:
    • introtxt.txt (63 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.
    • intro.txt (769 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #18 7045466
    arnoldziq
    VIP Zasłużony dla elektroda
    Posty: 5376
    Pomógł: 789
    Ocena: 300
    Po podmianie tych plików mam na ekranie dokładnie to samo co ty.
    I wygląda na to, że wszystko 'śmiga' pod TP 7.0.
    Ale wracając do oryginalnego pytania. Po co chcesz odczytywać znak znajdujący się na ekranie ? Co ma na celu odczytanie tego znaku / znaków ?

    Co do 'kolorów' :
    program kolorki;
    uses CRT;
    begin
    ClrScr;
    textcolor(15);
    writeln('def textcolor(15);');
    LowVideo;
    writeln('LowVideo textcolor(15);');
    HighVideo;
    writeln('HighVideo textcolor(15);');
    NormVideo;
    writeln('def textcolor(15);');
    
    textcolor(7);
    writeln('def textcolor(7);');
    LowVideo;
    writeln('LowVideo textcolor(7);');
    HighVideo;
    writeln('HighVideo textcolor(7);');
    NormVideo;
    writeln('def textcolor(7);');
    end.


    Co do ramki :

    program ramka;
    uses CRT;
    var
     x : word;
    begin
    clrscr;
    gotoxy(1,1); write('*');
    gotoxy(80,25); write('*');
    gotoxy(1,25); write('*');
    gotoxy(80,1); write('*');
    
    for x:=2 to 79 do
     begin
      gotoXY(x,1); write('-');
      gotoXY(x,25); write('-');
     end;
    for x:=2 to 24 do
     begin
      gotoXY(1,x); write('|');
      gotoXY(80,x); write('|');
     end;
    end.
  • #19 7045596
    tilosag
    Poziom 10  
    Posty: 14
    Co do ramki to mam: <shock> <- właśnie po to chciałem mieć możliwość odczytu i zapisu do pamięci graficznej O.o !

    mam to praktycznie to samo wpisane w procedurze "okno" a jak zmienię dim_y na 25 to przesuwa mi ...


    znalazłem errora:


    begin
    okno;
    readln;
    end.


    O rrany >.< to było takie proste.


    Dzięki wam wszystkim za wszystkie wasze rady!



    ale pozostaje jeszcze jeden problem!

    chcę czytać te znaki z ekranu po to, że w wypadku przecięcia się ramek, procedura okno zmienia kod ascii na odpowiedni (tak żeby się ładnie łączyły) i bardzo chciałbym zrobić to we FPC ze względu na jego lepszy sposób kompilowania kodu.



    EDIT:

    Coś tu nie działa. :/


    uses panel_u,crt;
    
    begin
    clrscr;
    ramka(1,1,80,25);
    delay(3000);
    end.



    unit panel_u;
    
    
    INTERFACE
    uses crt,users_db;
    const dim_x=80;dim_y=25;
    
    
    procedure panel_uzytkownika(login:string;haslo:string);
    
    procedure ramka(x1,y1,x2,y2:byte);
    
    IMPLEMENTATION
    
    procedure panel_uzytkownika(login:string;haslo:string);
    var uzytkownik:uzytkownicy;imie,nazwisko:string;id:longint;cnt,iksiazek:byte;label kontynuuj;
    begin
    ramka(1,1,80,25);
    
    assign(u,'users.db');
    reset(u);
    
    while not eof(u) do
    begin
    read(u,uzytkownik);
    if uzytkownik.login=login then
    begin
    seek(u,FilePos(u)-1);
    goto kontynuuj;
    end;
    
    end;
    kontynuuj:
    
    imie:=uzytkownik.imie;
    nazwisko:=uzytkownik.nazwisko;
    id:=uzytkownik.identyfikator;
    iksiazek:=uzytkownik.iksiazek;
    
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2),2);
    write(nazwisko,' ',imie);
    
    {RAMKA IMIE NAZW}
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1,2-1);
    write(chr(203));
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1,2);
    write(chr(186));
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1,2+1);
    write(chr(200));
    
    for cnt:=1 to (length(imie)+length(nazwisko))+1 do
    begin
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1+cnt,2+1);
    write(chr(205));
    end;
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1+(length(imie)+length(nazwisko))+1+1,2+1);
    write(chr(188));
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1+(length(imie)+length(nazwisko))+1+1,2);
    write(chr(186));
    
    GotoXY( (dim_x div 2)-( (length(imie)+length(nazwisko)) div 2)-1+(length(imie)+length(nazwisko))+1+1,2-1);
    write(chr(203));
    
    
    
    
    
    
    {RAMKA IMIE NAZW END}
    
    
    readln;
    
    
    
    
    end;
    
    procedure ramka(x1,y1,x2,y2:byte);
    var poz,pio:char;i:byte;
    begin
    
    
    poz:=Char(205);
    pio:=Char(186);
    
    for i:=x1+1 to x2-1 do
    begin
    GoToXY(i,y1);
    write(poz);
    GoToXY(i,y2);
    write(poz);
    end;
    
    for i:=y1+1 to y2-1 do
    begin
    GoToXY(x1,i);
    write(pio);
    GoToXY(x2,i);
    write(pio);
    end;
    
    GoToXY(x1,y1);
    write(Char(201));
    GoToXY(x2,y1);
    write(Char(187));
    GoToXY(x1,y2);
    write(Char(200));
    GoToXY(x2,y2);
    write(Char(188));
    end;
    
    end.
    
    
    
    


    Kod jest praktycznie identyczny, a TP przesuwa jeden pixel w dół! WTF?
  • Pomocny post
    #20 7047224
    arnoldziq
    VIP Zasłużony dla elektroda
    Posty: 5376
    Pomógł: 789
    Ocena: 300
    Podmień procedurę RAMKA na taką :
    procedure ramka(x1,y1,x2,y2:byte);
    var poz,pio:char;i:byte;
    begin
    poz:=Char(205);
    pio:=Char(186);
    
    for i:=x1+1 to x2-1 do
    begin
     GoToXY(i,y1); write(poz);
     GoToXY(i,y2); write(poz);
    end;
    
    for i:=y1+1 to y2-1 do
    begin
     GoToXY(x1,i); write(pio);
     GoToXY(x2,i); write(pio);
    end;
    
    GoToXY(x1,y1); write(Char(201));
    GoToXY(x2,y1);write(Char(187));
    GoToXY(x1,y2);write(Char(200));
    
    if (x2=80) and (y2=25) then Mem[$B800:3998] := 188
    else
    begin
     GoToXY(x2,y2); write(Char(188));
    end;
    end;

Podsumowanie tematu

✨ Dyskusja dotyczy problemu odczytania kodu ASCII znaku wyświetlonego w trybie tekstowym na ekranie w Turbo Pascalu, przy użyciu Free Pascala. Wskazano, że w trybie tekstowym dane znaków i ich atrybutów są przechowywane w pamięci wideo pod adresem segmentu 0B800h. Odczyt i zapis znaków można realizować poprzez bezpośredni dostęp do pamięci, np. za pomocą wskaźnika mem[$0B800:$offset]. Jednak Free Pascal nie obsługuje struktur MEM, MEML, MEMW, co powoduje błędy kompilacji przy próbach użycia takiego dostępu. Rozwiązaniem jest użycie Turbo Pascal 7, który wspiera te struktury, lub poszukiwanie odpowiednich bibliotek (np. GO32.PPU) dla Free Pascala, choć ich instalacja i działanie są problematyczne. W dyskusji pojawiły się także problemy z kompatybilnością i wydajnością między Free Pascalem a Turbo Pascalem, zwłaszcza w kontekście płynności działania programu i obsługi graficznej. Zaproponowano przykładową procedurę rysowania ramek w trybie tekstowym, wykorzystującą znaki ASCII i funkcje CRT. Omówiono także kwestie związane z kolorami tekstu i ich intensywnością w Turbo Pascalu. Podsumowując, bezpośredni odczyt kodu ASCII znaku z ekranu w Free Pascalu jest utrudniony ze względu na brak wsparcia dla struktur pamięci wideo, a najlepszym rozwiązaniem jest użycie Turbo Pascal 7 lub specjalnych bibliotek.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA