atarionline.pl MAD-Pascal - Początki - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1:
       
      CommentAuthorbocianu
    • CommentTime3 Dec 2019
     
    no niestety, innego wyjścia raczej nie ma.
    No chyba że Tebe coś wie, czego my nie wiemy ;)
    • 2: CommentAuthortebe
    • CommentTime3 Dec 2019
     
    świetnie sobie radzicie :)
    • 3: CommentAuthorkski
    • CommentTime3 Dec 2019
     
    ok nie ma problemu
    • 4:
       
      CommentAuthorgalu
    • CommentTime3 Dec 2019 zmieniony
     
    Skończyła mi się pamięć i dopiero zacząłem "optymalizować" program (przypomnę - przeniesiony z Javy). Na początek widzę, że każdorazowe odpytanie tablicy 2D [0..5][0..9] to aż 19 bajtów, więc w konstrukcji w rodzaju if (costam[y][x]=A) or (costam[y][x]=B) or (costam[y][x]=C) strata pamięci i czasu procesora była oczywista.
    A czy samo odczytanie wartości z tablicy i przypisanie nowej - jak na tym przykładzie - można załatwić w jakiś lepszy sposób?
    if (blockTimer[y][x] = BT_NULL) then blockTimer[y][x] := BT_TRIGGER;
    • 5: CommentAuthortebe
    • CommentTime3 Dec 2019
     
    sprawdziłeś kompilując z najnowszą wersją ?

    ->link<-
    • 6:
       
      CommentAuthorgalu
    • CommentTime3 Dec 2019
     
    Wynikowy XEX o 1,5KB mniejszy (plik 33KB, CODE: $2000..$6A96). Czy jest możliwe, że kod szybciej się wykonuje?
    Dzięki!
    • 7: CommentAuthortebe
    • CommentTime3 Dec 2019
     
    krótszy kod szybciej się wykonuje
    • 8:
       
      CommentAuthorgalu
    • CommentTime4 Dec 2019
     
    Przy okazji (nie wiem czy to jest zamierzone):

    const INDX_0 = 40;
    Test(10);


    procedure Test(offset : byte);
    begin
    CRT_Goto(INDX_0 + 123 + 20 + offset);
    end;


    34884 bytes written to the object file

    procedure Test(offset : byte);
    begin
    CRT_Goto(INDX_0 + 143 + offset);
    end;


    34874 bytes written to the object file

    procedure Test(offset : byte);
    begin
    CRT_Goto(183 + offset);
    end;


    34864 bytes written to the object file
    • 9: CommentAuthortebe
    • CommentTime4 Dec 2019
     
    nie wiem skąd jest CRT_GOTO. W bibliotece BLIBS jest moduł B_CRT, tam jest procedura CRT_GOTOXY(a,b)

    może umieść kompletny fragment programu
    • 10: CommentAuthorkski
    • CommentTime5 Dec 2019 zmieniony
     
    Czy zrobienie loadera wyświetlającego obrazek z Atari Graphics Studio i następnie ładującego właściwą grę (Mad Pascal) może być na tyle proste żeby początkujący programista atari nie wiedzący o jeszcze NIC o temacie zrobił to w 1-2 wieczory?
    Może ktoś dysponuje jakimś przykładem lub jest w stanie pomóc? Chodzi o Alberta.
    • 11: CommentAuthortebe
    • CommentTime5 Dec 2019
     
    nowe wersje Graph2Font zapisują plik *.PAS z obrazkiem (MODE = DLI), tryb znakowy jest możliwy podczas transmisji pod warunkiem że wszystko zmieści się w jednym zestawie znaków

    AGS (Atari Graphics Studio) może być prostsze bo to tylko tryby bitmapowe, chyba że ma jeszcze mrugać interlace

    przykłady wczytania obrazka i jego wyświetlenia dla MIC, PIC są w przykładach MP
    • 12: CommentAuthorMADRAFi
    • CommentTime5 Dec 2019
     
    Jestem ciekaw odpowiedzi na temat loaderea :)
    Mialem ten sam problem :)
    • 13: CommentAuthorkski
    • CommentTime5 Dec 2019
     
    Ok, popatrzę na przykłady, pytanie jak zrobić z tego loadera który wyświetla obrazek, czeka na naciśnięcie klawisza i dopiero ładuje grę. Sam albert to plik 38 kb i tam już obrazka nie wcisnę. Albo inaczej, ładuje go do pamięci pod os'a, skąd mogę wyświetlić przed pierwszym rozpoczęciem gry.
    W swoim czasie oczywiście sam nad tym posiedzę, ale pytam na szybko może coś ktoś robił i udało by się przed SV.

    Madrafi rozwiązałeś problem xBiosem? Jakieś sugestie które mogłyby mi pomóc?
    • 14: CommentAuthortebe
    • CommentTime5 Dec 2019
     
    czegoś takiego jak "splash screen" w MP nie ma, tworzysz blok wykonywalny, zmieniasz mu RUN na INI i łączysz ze swoim głównym programem

    kolejne bloki które będą ładowane do pamięci muszą omijać obszar pamięci która jest wykorzystywana do wyświetlenia obrazka, dlatego oszczędniej wypadają tryby znakowe, równie dobrze może to być ATASCII art

    G2F ma opcję zamiany bitmapy na kody znaków ATASCII
    • 15: CommentAuthorkski
    • CommentTime5 Dec 2019
     
    nie ma pamięci na dołączenie go do mojego programu... Chodzi więc o to żeby go załadować, pokazać, a potem olać - może zniknąć podczas ładowania głównego programu, lub żeby załadować pod os'a (też zniknie po pierwszym uruchomieniu gry).
    • 16:
       
      CommentAuthorgalu
    • CommentTime5 Dec 2019 zmieniony
     
    @tebe: Faktycznie - procedura (niepotrzebna) dopisana przeze mnie - przyjmuje inta zamiast pary bajtów (czy choćby smallinta).

    procedure CRT_Goto(offset : integer);
    begin
    CRT_cursor := CRT_vram + offset;
    end;
    • 17: CommentAuthortebe
    • CommentTime5 Dec 2019
     
    const INDX_0 = 40;

    var CRT_cursor, CRT_vram: word;

    procedure CRT_Goto(offset : integer);
    begin
    CRT_cursor := CRT_vram + offset;
    end;

    procedure Test(offset : byte);
    begin
    CRT_Goto(INDX_0 + 123 + 20 + offset);
    end;

    begin

    Test(10);

    end.


    261 bajtów

    gdy asemblujesz mads-em, istotny jest parametr -x, który usuwa procedury do których nie nastąpiło odwołanie
    • 18: CommentAuthorkski
    • CommentTime5 Dec 2019 zmieniony
     
    No i okazało się proste to o co prosiłem, poniżej z xbiosem, ale za chwilę sprawdzę "normalnego" dosa. Najpierw uruchamia się intro, po naciśnięciu klawisza wraca do loadera i ładuje grę. Loader i intro nie używają tej samej pamięci. W momencie jak ładowana gra zacznie pisac po pamięci obraziu będą śmieci dlatego umieściłem ją (pamięć obrazu) najdalej.

    program albert;
    uses xbios;
    var
    path1: TString = 'INTRO XEX';
    path2: TString = 'MAIN XEX';

    begin
    xBiosOpenFile(path1);
    if xBiosIOresult <> 0 then Writeln('IOerror: ', xBiosIOerror)
    else xBiosLoadBinaryFile;

    xBiosOpenFile(path2);
    if xBiosIOresult <> 0 then Writeln('IOerror: ', xBiosIOerror)
    else xBiosLoadBinaryFile;
    end.
    • 19: CommentAuthorkski
    • CommentTime6 Dec 2019 zmieniony
     
    Mały update, dzięki pomocy Yolka i Integratorowi Larka, zamiana RUN na INIT i połączenie dwóch xex'ów (o czym pisał wyżej Tebe, tylko potrzeba najpierw troszkę wiedzy żeby zrozumieć) okazała się najlepszym rozwiązaniem do wyświetlenia obrazka przed załadowaniem gry - powstaje xex łatwiejszy w obsłudze niż atr w przypadku historii z dosami/xbiosami. A Ci którzy będą jutro na SV zobaczą efekt.
    • 20: CommentAuthorMADRAFi
    • CommentTime7 Dec 2019
     
    To co pisalem.
    Ale fajnie by bylo jakbys zrobil opis i tutaj wkleil. Przyda sie tez innym :)
    • 21: CommentAuthorxxl
    • CommentTime7 Dec 2019
     
    zapisujesz w g2f obrazek przez export xex format. zmieniasz ostatni blok z RUN na INI. kodlejasz do swojego kodu na POCZATKU i tyle.
    • 22: CommentAuthorMADRAFi
    • CommentTime7 Dec 2019
     
    Kluczowe jest to jak w gotowym juz pliku XEX zmienic ten blok :)
    • 23: CommentAuthortebe
    • CommentTime7 Dec 2019
     
    Graph2Font, przechodzimy do zakładki Special -> Options -> ASM file, zaznaczamy INI zamiast RUN

    innym sposobem jest użycie Super Packera, można blok RUN zmienić na INI, można usuwać, łączyć, dodawać bloki
    • 24: CommentAuthorMADRAFi
    • CommentTime7 Dec 2019
     
    no i git!
    • 25: CommentAuthorkski
    • CommentTime7 Dec 2019
     
    no i trzeba było tak od razu
    • 26: CommentAuthornosty
    • CommentTime31 Dec 2019 zmieniony
     
    Zachęcony na SV przez Bociana zrobiłem podejście do MadPascala. Zbudowałem środowisko, zacząłem analizować i odpalać przykłady, wszystko bangla pięknie.
    Ale po 1 dniu mam już kilka pierwszych wątpliwości i pytań, (wynikających pewnie z tego, że do pacala podchodzę po doświadczeniach z assemblerem):

    1. Mapa pamięci.
    Nie widzę w przykładach jak decydować gdzie w pamięci ma się znaleźć skompilowany kod. A jeśli nie mam na to wpływu, to nie wiem skąd kompilator wie, które miejsca zarezerwowałem? Albo których obszarów nie powinienem używać na dane czy pamięć ekranu?
    W przykładach są deklaracje takie jak:
    PMGBASE = $C000;
    CHARSET_GAME_ADDRESS = PMGBASE + $400;
    ale to przecież tylko deklaracje stałych.
    Króko mówiąc: jaki jest tu odpowiednik "org" lub jak sobie radzić bez niego, by kod nie wlazł mi na dane?

    2. W przykładach nie znalazłem nic, co by wymuszało synchronizację głównej pętli gry z VBI. Nie wyobrażam sobie jak żyć i animować bez tego? :)
    Tzn wiem oczywiście jak to uzyskać. Nie rozumiem czemu twórcy przykładów o to nie dbają?

    3. Do umieszczania zmiennych w konkretnych miejscach służy zdaje się deklaracja ABSOLUTE. Ale nie widzę by w przykładach ktoś dbał o to by umieszczać zmienne na stronie zerowej. Dlaczego?

    4. Nie rozumiem chyba idei tabeli z jednym elementem:
    levelData: array [0..0] of byte;
    Szczególnie, że wg dokumentacji dostęp do niej jest realizowany w najgorszy możliwy sposób: lda (bp),y
    Dokumentacja pisze, ze jest możliwość relokacji takiej tabeli. Ale po co?
    Z przykładów widzę, że mimo, że jest to tabela jednoelementowa, to następują próby odczytów z indexów innych niż 0, co powinno spowodować błąd.

    Bardzo dziękuję za pomoc!
    • 27:
       
      CommentAuthorbocianu
    • CommentTime31 Dec 2019
     
    @nosty:

    1:
    Jako tako odpowiednika samego org nie ma. Możemy definiować indywidualnie położenie zmiennych korzystając z "absolute", ale dla kodu (procedur i funkcji) to nie zadziała - tu jesteśmy zdani na kompilator.
    Domyślnie kod kompilowany jest od $2000 i zaraz za nim pakowane są dane. Ile miejsca zajmują widzimy w konsoli podczas kompilacji. Ale można to zmienić przełącznikami kompilatora:
    -code:$address  adres uruchomienia programu
    -data:$address adres pamięci dla zmiennych, tablic
    -stack:$address adres pamięci dla stosu programowego (64 bajty)
    -zpage:$address adres na stronie zerowej dla zmiennych (24 bajty)


    2:
    Wystarczy w głównej pętli dać rozkaz "Pause" i wszystko co damy bezpośrednio za nim powinno sie wykonywać poza okresem rysowania obrazu (oczywiscie o ile nie przesadzimy z długością). To najprostszy sposób.

    3:
    Mi się zdarzało umieszczać zmienne na stronie zerowej korzystając z absolute i to działa. Może słabo szukałeś :D

    4:
    tabela typu [0..0] to tak naprawdę wskaźnik na tablice o dowolnym rozmiarze. Możemy ten wskaźnik dowolnie relokować, przykładowo na dane binarne dołączone w zewnętrznym pliku, żeby wygodniej i bardziej kulturalnie się do nich dobrać.

    Czyli przykładowo dołączamy sobie plik binarny pod adres $6000, deklarujemy tablicę:
    var dane: array [0..0] of byte;

    potem ustawiamy jej lokalizację:
    dane := pointer($6000);

    i wtedy pobieramy kulturalnie dane korzystając z:
    wartosc_danej := dane[index_danej];

    Możemy tez adres tej tabeli przypisać na stałe przez "absolute" przy deklaracji, jeśli nie zamierzamy go już zmieniać.

    Korzystam z tego często - wygodne.
    • 28: CommentAuthortebe
    • CommentTime31 Dec 2019
     
    ad.1
    domyślny adres ładowania programu to $2000, można to zmienić poprzez parametr -code:hexaddress

    wszystkie informacje dotyczące mapy pamięci pojawiają się na wyjściu

    CODE to nasz program, DATA to zmienne, tablice itd.

    214 lines compiled, 1.01 sec, 5738 tokens, 613 idents, 180 blocks, 7 types
    1 warning(s) issued
    25 note(s) issued
    ZPFREE: $0000..$007F / $00D8..$00FF
    RUNLIB: $20CF..$20D3
    SYSTEM: $20F2..$20F5
    CRT: $20F6..$2109
    CODE: $2000..$215B
    DATA: $215C..$2220


    ad.2
    procedura PAUSE czeka ramkę

    ad.3
    ZPFREE: $0000..$007F / $00D8..$00FF

    obszar $0080..$00D7 MP rezerwuje na swoje potrzeby

    ad.4
    tablica reprezentowana jest przez wskaźnik

    dostęp do tablic które nie przekraczają 256 bajtów jest najszybszy, bo nie jest realizowana przez wskaźnik, wskaźnik jest ignorowany, to taki tryb "absolutny"

    są sytuacje kiedy potrzebujemy zmienić, ustalić nowy adres tablicy, albo nie chcemy podawać rozmiaru takiej tablicy
    podanie rozmiaru tablicy spowoduje zarezerwowanie pamięci
    • 29: CommentAuthornosty
    • CommentTime31 Dec 2019
     
    Bardzo Wam dziękuję za błyskawiczne odpowiedzi.
    Rozjaśniło mi się znacznie. Dwie wątpliwości:

    Jeszcze a propos strony zerowej:
    "obszar $0080..$00D7 MP rezerwuje na swoje potrzeby"

    a Bocianu opisał (jak widzę, zgodnie z dokumentacją):
    -zpage:$address adres na stronie zerowej dla zmiennych (24 bajty)

    Tymczasem od $80 do $D7 to znacznie więcej niż 24 bajty.

    Czy ilość zajętej przez MP strony zerowej jest zmienna zależnie od programu, czy też dokumentacja dotyczyła wcześniejszej wersji i jest nieaktualna?

    I a propos Pause, żeby mieć pewność:
    Po komendzie Pause program staje aż do najbliższego VBI, czyli zakończenia rysowania ekranu, tak?
    Tak rozumiem wyjaśnienie Bocianu.

    W dokumentacji jest:
    procedure Pause;
    procedure Pause(n: word);
    Zatrzymuje działanie programu na N * 1.50 sek

    Rozumiem literówkę (powinno być zapewne 1/50 sek.), ale to też nie jest zgodne z opisem Bocianiu, bo tu już jednoznacznie jest podany czas pauzy jako wielokrotność 1/50 sek.
    • 30: CommentAuthortebe
    • CommentTime31 Dec 2019 zmieniony
     
    -stack:address  Software stack hex address (size = 64 bytes)
    -zpage:address Variables on the zero page hex address (size = 24 bytes)


    w sumie 88 bajty na stronie zerowej

    PAUSE (unit SYSTEM)
    procedure Pause; assembler; overload;
    (*
    @description:
    Delay program execution (1/50 second).
    *)
    asm
    { lda:cmp:req :rtclok+2
    };
    end;
    • 31:
       
      CommentAuthorbocianu
    • CommentTime31 Dec 2019 zmieniony
     
    Opis procedury pause nie jest do końca poprawny :D
    Tak naprawdę to pause czeka na zmianę zawartości rtclok+2
    procedure Pause; assembler; overload;
    (*
    @description:
    Delay program execution (1/50 second).
    *)
    asm
    { lda:cmp:req :rtclok+2
    };
    end;


    I trzeba pamiętać, że nie będzie działała jak wyłączymy OS. No chyba ze sami będziemy sobie inkrementować rtclok co ramkę :)
    • 32: CommentAuthornosty
    • CommentTime31 Dec 2019
     
    Pięknie.
    W takim razie próbuję przenieść do MP prostą grę, którą zacząłem pisać w asm.
    Szczęśliwego Nowego! :)