kategoria: Asembler
[#1] [asm] gry w asemblerze ze źródłami
Wątek podobny do Amosowego link ale skupmy się tylko na grach ze źródłami w asemblerze. Mogą być też procedury pomocne w tworzeniu gier. Oczywiście produkcje w każdym stadium rozwoju byleby coś było naklepane.
[#2] Re: [asm] gry w asemblerze ze źródłami

@asman, post #1

W każdej grze są np. punkty życia, zapisane binarnie w jakiejś komórce pamięci. Gra musi je wyświetlić na ekranie w postaci zrozumiałej dla gracza. Najpierw więc trzeba taką wartość binarną zamienić na wartość dziesiętną. Do tego właśnie może posłużyć ta procedura, która konwertuje 32-bitową wartość binarną do postaci 10-cyfrowej liczby dziesiętnej ASCIIZ (zawierającej nieznaczące zera).

Podobna procedura znajduje się w każdym Kickstarcie i właśnie z niego ją wyciągnąłem.
Nie wklejałem tu kodu, bo byłby on nieczytelny.
[#3] Re: [asm] gry w asemblerze ze źródłami

@RomanWorkshop, post #2

Bardzo ciekawe procedury.

Jeśli chodzi o punkty w grze to musimy być świadomi dwóch rzecz. Pierwsze to pokazanie punktów a druga rzecz to operacje arytmetyczne na punktach i tu przeważnie mamy do czynienia tylko z dodawaniem i znowu przeważnie dodajemy stałą ilość punktów typu 10 punktów za ubicie przeciwnika a 100 za większego stwora. Co ciekawe wewnętrzna reprezentacja punktów wpływa na te dwa czynniki. W przypadku punktów w postaci binarnej łatwo jest dodawać, porównywać (highscore) a wyświetlenie wyniku już zabiera więcej czasu. W RollingThunder punkty są przechowywane jako ASCIIZ i wtedy dodawanie zabiera więcej czasu. I wydaje się to złym podejściem, bo przecież zawsze gdy zwiększamy punktację to musimy ten fakt odnotować na ekranie, na niekorzyść wtedy działa fakt zdobycia większej ilości punktów czyli wielokrotne wywołanie takiej procedury która zwiększa punkty w formacie ASCIIZ. Swego czasu zastanawiałem się nad tym problemem ale nie pamiętam bym znalazł jakieś ciekawe rozwiązanie, trzeba szukać.

Jedynej rzeczy jakiej mi brakuje, gdy rozprawiamy o szybkości danej procedury to asembler/narzędzię , które byłoby w stanie podać ilość cykli dla danej lini (dla procesora 68000).
[#4] Re: [asm] gry w asemblerze ze źródłami

@asman, post #3

Liczbę cykli, które są potrzebne na wykonanie danego kodu podają symulatory procesorów 68k, np. Easy68k na PC.
[#5] Re: [asm] gry w asemblerze ze źródłami

@RomanWorkshop, post #2

U mnie zawsze bardziej sprawdzało się trzymanie każdej cyfry w osobnym bajcie - zwłaszcza pod kątem ilości cykli potrzebnych do wyświetlania. Może na Amidze nie ma aż takiego znaczenia te parę cykli, ale na 8bitowcach owszem często ma. Bardziej mi się opłacało troszkę powalczyć z dodawaniem na takiej reprezentacji, niż z wyświetlaniem.
[#6] Re: [asm] gry w asemblerze ze źródłami

@xeen, post #5

A jeśli gra musiałaby odjąć punkty, np. za zabicie swoich jednostek? Wtedy odejmowanie na liczbach ASCII nie byłoby takie proste.

Jeśli chodzi o procedury na procesory 8-bit, to mam jeszcze prostszą procedurę konwersji 32-bitów na ASCIIZ dla procesora 6502. Wykonuje się ona bardzo szybko, niezależnie od konwertowanej wartości (prawie ze stałą szybkością). Mam zamiar ją przełożyć na asembler 68000. Przełożyłem ją na asembler AVR i na symulatorze wyszło, że wykonuje się w maks. 4186 cyklach przy konwersji wartości $FFFFFFFF.
[#7] Re: [asm] gry w asemblerze ze źródłami

@xeen, post #5

A cyfrę w tym bajcie trzymasz jako ASCII, normalnie (czyli od 0 do 9 ) czy jako offset do odpowiedniego fontu, przedstawiającego daną cyfrę ? Chociaż teraz sobie myślę że w przypadku 8 bitowców to raczej się trzyma zwyczajnie nr fontu dla cyfry. A ztym offsetem to by było lepiej na amidze bo wtedy jeśli font jest typu: 8x8x1 ( zwyczajowo 8 pikseli szeroki, 8 piskeli wysoki i jeden bitplan) to wtedy cyfra 0 ma offset 0, cyfra 1 ma offset 8, cyfra 2 ma offset 16 i tak dalej. Takie trzymanie offsetu upraszcza pokazywanie punktacji. Oczywiście zmianie ulegnie dodawanie punktów i po cichu zakładam że nie ma odejmowania punktów :D

@RomanWorkshop
Dzięki obadam tego Easy68k.
[#8] Re: [asm] gry w asemblerze ze źródłami

@RomanWorkshop, post #6

Witam,

A jeśli gra musiałaby odjąć punkty, np. za zabicie swoich jednostek? Wtedy odejmowanie na liczbach ASCII nie byłoby takie proste.

Ależ to nie jest znów takie trudne, sprawdza się znane ze szkoły pisemne dodawanie i odejmowanie wielocyfrowych liczb.

Weźmy odejmowanie:

Opis algorytmu:
1. dla każdej cyfry od najmniej znaczącej do najbardziej znaczącej:
2. odejmij odpowiednie cyfry.
3. jeśli wynik jest ujemny dodaj 10 do niego i odejmij 1 od bardziej znaczącej cyfry odjemnej.

Przykład:

Odejmujemy 49 od 100.
Biorąc cyfry jedności odejmujemy 0-9=-9. Wynik ujemny, więc dodajemy 10: -9+10=1. Wynik 1. Prócz tego zmniejszamy kolejną cyfrę o 1. Mamy tu 0, więc wychodzi -1.
Biorąc cyfry dziesiątek odejmujemy -1-4=-5. Wynik ujemny, więc dodajemy 10: -5+10=5. Wynik 5.
Prócz tego zmniejszamy kolejną cyfrę o 1. Mamy tu 1 więc wychodzi 0.
W ostatnim kroku (cyfry setek) odejmujemy 0 od 0 więc wychodzi 0.

Ostateczny wynik: 51. Sprawdzamy 51+49=100. W porządku.

Jak widać algorytm pisemnego odejmowania jest bardzo prosty. I doskonale sprawdzi się, gdy każda cyfra jest w jednym bajcie.

Pozdrawiam.
[#9] Re: [asm] gry w asemblerze ze źródłami

@asman, post #3

"Jedynej rzeczy jakiej mi brakuje, gdy rozprawiamy o szybkości danej procedury to asembler/narzędzię , które byłoby w stanie podać ilość cykli dla danej lini (dla procesora 68000)."

Trochę co innego, ale jak kiedyś miałem dużo czasu i wiele zapału, to optymalizowałem sobie różne algorytmy, albo pojedyńcze procedury - tak dla sportu (w asemblerze). Wykorzystując timer (nie pamiętam, czy bezpośrednio hardware, czy przez timer.device) puszczałem w pętli jakiś kawałek kodu np. 10000 razy, z timera odczytywałem zmierzony czas (rozdzielczość chyba rzędu mikrosekundy), co sobie można łatwo na cykle przeliczyć. Można wtedy zobaczyć, ile wyciąga cpu (z wyłączonym dma i przerwaniami), ile czasu zżera włączone dma, przerwania, itp. itd.
[#10] Re: [asm] gry w asemblerze ze źródłami

@asman, post #7

To zależy. Niekoniecznie potrzebujesz offsetu do znaku - jeżeli nie jesteś w trybie znakowym to masz offset (jakkolwiek - czy pośredni, czy nie to rozumiemy) do czego innego - np. początku graficznej reprezentacji cyfry. To zawsze jest kwestia indywidualna przy takim podejściu - czy to się sprawdza na AMI to w sumie nie wiem :)

Czy dodajesz czy odejmujesz - nie ma znaczenia.
[#11] Re: [asm] gry w asemblerze ze źródłami

@Hexmage960, post #8

Oczywiście da się to zrobić, ale czy taki algorytm dodawania/odejmowania liczb ASCII zajmie mniej czasu procesora od algorytmu, w którym dodaje/odejmuje się dane binarne, a następnie są one tylko konwertowane na ASCII? Moim zdaniem nie będzie ani krótszy, ani szybszy.
[#12] Re: [asm] gry w asemblerze ze źródłami

@RomanWorkshop, post #11

@RomanWorkshop
Aby być pewnym trzeba przysiąść i obadać :)

@xeen
Dzięki za odpowiedź, spodziewałem się takiej "To zależy" :)

@BigBang
Mnie tam ten sport (optymalizacja) się cały czas podoba i go uskuteczniam, fakt że masę czasu zabiera. Co do mierzenia za pomocą timera to można przez timer.device i to robiłem przy przygodzie z OS i Robbo. A i można z pominięciem tegoż device i tego nie robiłem. W każdym razie dzięki. Ja prawie zawsze uskuteczniam mierzenie za pomocą kolorów czyli ustawiam kolor czarny, czekam na ustaloną pozycję rastra, zmieniam kolor, odpalam procedurę do mierzenia, zmieniam na czarny. I siedze i się gapię na ekran :D
[#13] Re: [asm] gry w asemblerze ze źródłami

@asman, post #12

@asman
o tak, na ekranie fajnie można "widzieć" czas wykonania kodu! Ale jak na mojej plusce z 2MB CHIP szukałem liczb pierwszych, to wyłączenie DMA dawało zauważalny efekt, ale wtedy na ekranie nic nie widać. Chyba że się miało FAST.
Ech jak sobie przypominam, co jeszcze... na przykład procedura rysowania linii blitterem (pewnie znalazłbym gdzieś, do ilu cykli zszedłem), obroty geometryczne, gierka typu dwie kreski odbijające piłeczkę (czyli ping-pong w wersji najuboższej), no i fraktale całkowitoliczbowe!

A przy realizacji licznika można zauważyć, że nasza motorolka obsługuje coś takiego jak kod BCD - każdy półbajt to cyfra od 0 do 9. Co prawda jest ograniczona ilość działań (MC68000 ma chyba tylko dodawanie, odejmowanie i negację bcd), ale jeśli to wystarcza, to w bardzo prosto można przerobić taką liczbę BCD na ciąg bajtów z kodami ascii cyfr. Ale jak zajdzie potrzeba pomnożenia, czy podzielenia takiej liczby, to nie ma zmiłuj!
[#14] Re: [asm] gry w asemblerze ze źródłami

@BigBang, post #13

Hehe, faktycznie jak DMA wyłączone to nic nie widać :)

Co do BCD i innych sztuczek przydatnych w grach polecam bardzo ciekawy wątek na Atari-Forum w dziale dla Atari ST link. Oczywiście są rzeczy specyficzne dla Atari ST ale mi się przydały przy konwersji gier i w sumie dzięki temu się przekonałem że moje procedury są dalekie od doskonałości jeśli chodzi o prędkość działania. A im wcześniejsze źródła tym gorzej.

Odnalazłem najstarsze swoje źródła w asemblerze i nawet jest tam gra w stylu Tron, tylko nie wiedzieć czemu jest tylko jeden player, nie działa na AGA i przerwanie klawiatury jest skopane. Ogólnie jest to tragicznie napisane. Spojrzałem i punktację uskuteczniam jako ASCIIZ :D
A najlepsze jest że kodu jest 2860 bajtów + 768 bajtów relokacji i plik wynikowy jest 3804 bajtów - trzeba to zmienić. W sumie tak prosta gra nadaje się znakomicie na tutorial :D
[#15] Re: [asm] gry w asemblerze ze źródłami

@RomanWorkshop, post #6

Przełożyłem na asembler 68000 obiecany algorytm konwersji. Na procesorach 8-bitowych (6502, AVR) jest on jedynym, szybkim sposobem na zamianę 32-bitów na postać dziesiętną ASCII. Niestety na procesorze 68000 ani rozmiar algorytmu, ani jego szybkość nie są lepsze, niż w tradycyjnym sposobie konwersji. Poniżej porównanie:

Konwersja 8-bitów do systemu DEC-ASCIIZ:
ConBD: 34 bajty, 636-948 cykli
Con8D: 50 bajtów, 1264-1352 cykli

Konwersja 16-bitów do systemu DEC-ASCIIZ:
ConWD: 40 bajtów, 1026-1650 cykli
Con16D: 52 bajty, 3672-4046 cykli

Konwersja 32-bitów do systemu DEC-ASCIIZ:
ConLD: 79 bajtów, 910-2962 cykli
Con32D: 54 bajty, 14338-15900 cykli

Najmniejsza liczba cykli jest potrzebna przy konwersji danych o zerowej wartości ($00, $0000, $00000000),
a największa przy konwersji danych o maksymalnej wartości ($FF, $FFFF, $FFFFFFFF).
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem