Amaurote izometr 3d na c64

Szukasz drobnej pomocy przy kodowaniu, albo chcesz przedstawić światu swoją gotową lub w trakcie realizacji produkcję? To właściwy dział.
Wiadomość
Autor
bimber
Posty: 814
Rejestracja: 16 wrz 2008, 10:16
Grupa: arise

#21 Post autor: bimber »

BagoZonde pisze:Gra zajmuje cały ekran więc masakra.
jesli ma to byc konwersja 1:1 z zx to niekoniecznie (rozdzielczosc spectrum = 256x192)

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#22 Post autor: BagoZonde »

Racja bimber, ale bazując na wersji na Atari (ZX nie sprawdzałem, ale to chyba kalka??), mamy 28x17 pól co daje 476 znaków. Wyciąłem jedno pole - taki szyb choć może to być jakaś bateria słoneczna, whatever. Prawdopodobnie nie zrobiłem pikselowego offseta w poziomie czy w pionie ale to wyjdzie w praniu. Mniejsza z tym. Jedno pole składać się może maksymalnie z 4x2 różnych znaków co daje 8. Z tego co widać, pozostaje tylko opcja zrobienia pól na zasadzie "sąsiadów". Czyli jeżeli po lewej ma być drugi szyb, to mamy w pierwszym rzędzie np: ABCD a jeżeli po lewej ma być droga to GHCD. CD jest wspólne dla obu bo jest to prawa część. Dochodzi do tego wiele kombinacji z budynkami, ale musi się to jakoś zmieścić w znakach.

Taka gra Fairlight - jak się jej przypatrzyłem - nie zawiera wielu różnorodnych elementów na jednej planszy - jest tam czysto. Amaurote jest bardzo bogaty.

No i do tego dochodzą zarezerwowane znaki wszystkich postaci.

Sztachnę sobie prosty silniczek na tej zasadzie.

BTW: Grałem trochę w wersję na C64 żeby odświeżyć pamięć, straszna nuda. Nie umywa się do wersji z Atari, zresztą wystarczy popatrzeć na AI owadów co wprowadza niezłą monotonię nie mówiąc o rozmiarach plansz, które jakoś wydają mi się o wiele większe ale nie jestem znawcą tematu ;).

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#23 Post autor: BagoZonde »

Ok, w załączniku przesyłam pierwszą wersję silnika izometrycznego: execute i źródło (w 64tass). Wymyśliłem działanie silnika bez żadnych pomocy i wgłębiania się w temat więc albo wyważałem otwarte drzwi albo napisałem głupi algorytm ale potraktowałem to jako wyzwanie więc ciiii;). Mimo wszystko działa w miarę szybko. Jest w stanie wyrysować planszę w czasie około 2 ramek więc spokojnie można sobie podzielić rysowanie planszy na dwie ramki po połowie co nie wpłynie na odtwarzanie muzyki, sterowania czy AI.

Od razu zaznaczam, że:

Jestem raczkującym programistą więc chętnie wysłucham wszelkich opinii na temat "niuansów" w tym kodzie choć jest to "kod wyrzygany" - zmieniany sto razy w ferworze pracy nad silnikiem, na tym etapie ma po prostu to działać ;). Nie optymalizowałem kodu, nie speedowałem żadnej z części ze względu na to, iż na tym etapie jedynie próbowałem wprowadzić swoją ideę. Wszelką optymalizację wykonam oczywiście na końcu :). Jest tam na przykład jedna brzydka pętla (2x wykonywana) z użyciem zmiennej LINE2 (której nazwę też w sumie muszę zmienić), tego momentu nie unrollowałem na razie.

Gwoli wyjaśnienia:

Bitmapę bitmap.png tworzę na Amidze i konwertuję do znaków ASCII swoim sprawdzonym programem ;). Podobnie z tablicami. Bitmapa czytana jest jako 16 kwadratów (każdy po 8 pikseli oczywiście) w poziomie.

Wymyśliłem sobie metodę "sąsiadów" zapisaną w nybble, lewy nybble to aktualne pole a następny nybble to pole sąsiadujące (Amaurote-neighbours.png). Tym sposobem tworzone są znaki dla wszystkich możliwości a potem dana wartość, np: 01 dla szukanego lewego sąsiada to znaki 22 i 23. Zakręcone trochę, ale przyspiesza znacznie wyświetlanie.
Wyświetlana jest linijka po linijce po dwa znaki. I co najważniejsze: dodanie następnych obiektów nie wpłynie na prędkość wyświetlania wcale.

Nie wiem czy dobrą drogą podążam, bo jeżeli pojawi się więcej rodzajów pól i dla każdego narysować będę musiał wszystkie możliwości to może tych znaków zabraknąć. Ale wydaje mi się, że dzięki temu bardzo szybko się to wyświetla, więc jeżeli Amaurote będzie niemożliwe do konwersji w ten sposób, zawsze pozostanie mi silnik dlatego nie liczyłem czy starczy znaków - jak starczy to ok. Innej metody nie jestem w stanie wymyślić.
Obiekty "wystające" ponad ziemię to kolejny etap, wszystko właśnie chciałem wyrysować bez modyfikacji charsetów na gotowym zestawie, więc zastanawiam się jak to rozwiązać dla tak różnorodnej ilości pól. Myślę, że wszystkie muchy, naszego "pająka" mogą być tylko sprite'ami z nakładaną maską zasłaniających elementów.

Więc to na tyle, rozgryzłem izometrię w ten sposób - jeżeli ktoś znalazłby jakieś udogodnienie bądź też zaproponował inne rozwiązanie - byłoby super. Wyzwanie jest spore :).

Co do obsługi można klawiszami kursora przesuwać się po polach na ograniczonym obszarze.

Mam tylko problem w wyświetlaniu pozycji x i y w postaci decymalnej.
W include/print_screen.asm próbowałem z:

Kod: Zaznacz cały

lda #0
ldx map_x
jmp $bdcd
ale zawiesza mi przerwania chyba. Po rozwinięciu tego co kryje się pod $BDCD okazało się, że "przeszkadza" JMP $AB1E. Nie drążyłem tematu bo dowiedziałem się o tym prostym przekształcaniu hex2dec godzinę temu i nie chciałem zwlekać z tym kodem więc HEEEELP!!

To chyba wszystko na razie, temat otwarty chyba, zobaczymy. Mam nadzieję, że nie dałem plamy z tym moim kodowaniem :P.

Nie wiem do końca jak nałożyć na to sprite'y skoro czarny jest przeźroczystym (nie odseparuje sprite'a od planszy na czarnym tyle) no i jeszcze dochodzą te "ramki" z boków, może najlepiej z czegoś po prostu zrezygnować. Ktoś umiałby zamieścić w kodzie player z muzyką z gry?

BTW. Wersja Amaurote na ZX Spectrum jest nieco bogatsza niż ta na Atari więc warto się na niej skupić :).

No i wszystkiego najlepszego Commodore 64! Rok w rok obchodzimy te same urodziny ;).

Edit: poprawiłem te wyświetlanie koordynat w pliku i jeszcze raz wrzuciłem załącznik, żeby nie robić następnej wersji archiwum.
Załączniki
AMAUROTE.rar
(16.28 KiB) Pobrany 772 razy
Ostatnio zmieniony 05 sty 2012, 22:42 przez BagoZonde, łącznie zmieniany 3 razy.

k.

#24 Post autor: k. »

jmp bcd???????
Kurwa czemu jmp gdzie to ma wrócić?

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#25 Post autor: BagoZonde »

Haha, rzeczywiście. Podłapałem na lemonie64, że jest jmp i pomyślałem: no może coś tam na stack odkłada ;) i w programie testowym zadziałało dobrze, ale teraz już wiem, że dlatego, że robiłem jsr do funkcji "PRINT_SHIT" i powrót następował przez rts, ale nie ten z funkcji "PRINT_SHIT" tylko ten z bdcd :).

Dzięki kisiel, uznaj to za moją chwilową niepoczytalność, się spieszyłem :).

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#26 Post autor: BagoZonde »

@Skull
Nie nie, kisiel wylał poprawną diagnozę. Testowałem to na czymś takim dla przykładu:

Kod: Zaznacz cały

MAIN_PRG
jsr PRINT_SHIT
jmp MAIN_PRG

PRINT_SHIT
jmp $bdcd

rts ;do tego rts-a w ogóle nie dochodziło


Lamerstwo pierwsza klasa ale działało w tamtym przypadku, w przypadku kodu do Amaurote już nie :). W sumie dzięki jmp $bdcd nie trzeba wpisywać potem rts po powrocie - wszystko zależy od tego skąd i jak skaczemy :).

Mniejsza zresztą o te wyświetlanie koordynat.

Awatar użytkownika
Nitro
Posty: 1551
Rejestracja: 03 wrz 2008, 20:23
Grupa: Black Sun

#27 Post autor: Nitro »

O tej godzinie pozwolę sobie tylko pogratulować :)

Awatar użytkownika
skull
Posty: 760
Rejestracja: 15 wrz 2008, 08:18
Grupa: samar

#28 Post autor: skull »

e no nie do końca,
bo wciąłeś tylko wycinek z podprocedury - w pierwszej chwili mogłoby sie wydawac ze skaczesz tam z głównej częsci programu - stąd ten zawiech, a tak wcale nie było.
ten jmp powodował tylko za wczesny powrót z jedenej z procedur - zwis wcale nie nastepował w romie - jakby sugerowały te twoje 3 linijki kodu.
Bo pecet to zwykły banan...

Awatar użytkownika
nes
Posty: 509
Rejestracja: 21 maja 2010, 22:03
Grupa: Impact

#29 Post autor: nes »

Oglądnąłem. Czekam na chociaż jedną nie-płaską figurę :P
"A ile zrobisz pompek ?" (c) 2o11 eLban
http://apt.hopto.org/nes/impact/

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#30 Post autor: BagoZonde »

@nes
Tak :). Samo zrobienie przestrzennych obiektów jest łatwe bazując na tym silniku - w rzeczywistości nadal są to "płaskie" obrazki. Problem tylko w tym, czy starczy znaków, gdyż wchodzą tutaj różne kombinacje każdego pola z każdym. Redefinicja na przykład 64 znaków (dla dwóch rzędów po 32 znaki) co 16 rasterlinii odpada. Naiwnie próbowałem to rozwiązać w ten sposób - wyświetliłem na ekranie te znaki, ustawiłem kilka przerwań IRQ ale w tak krótkim czasie procesor zdąży skopiować pod $E800+ zaledwie max 10 znaków (użyłem unrolled: lda chars1; sta $e800; lda chars1+1; sta $e800+1 itd.).

Nie macie pojęcia jak to jest rozwiązane w Fairlight, The Great Escape czy Nosferatu? Patrzyłem pobieżnie w kod Nightshade, ale nie wiele tam znalazłem (ekran jest pod $C000 z tego co mi się wydaje).

Awatar użytkownika
nes
Posty: 509
Rejestracja: 21 maja 2010, 22:03
Grupa: Impact

#31 Post autor: nes »

Wszystkie efekty na C64 są teoretycznie "do zrobienia", dopóki się ich nie spróbuje zrobić ;) Wtedy się okazuje, że plan działania nie wystarcza.
"A ile zrobisz pompek ?" (c) 2o11 eLban
http://apt.hopto.org/nes/impact/

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#32 Post autor: BagoZonde »

Tja, prowokujesz do działania ;).

Niedawno jak 3 dni temu bawiłem się w przełączanie character setów. Bardzo teoretycznie wydaje mi się, że można to rozwiązać właśnie w ten sposób jednak potrzebowałbym porady kolegów.

Pomyślałem, żeby wykorzystać wspaniałą właściwość rejestru $d018. 4 górne bity kontrolują SCREEN MEMORY (16 dostępnych ekranów) a 4 dolne bity kontrolują CHARACTER SET (8 dostępnych dla banku 3).

Innymi słowy w trakcie przesuwania się planszy re-definiowane by były np: dwa rzędy znaków w 8 kompletach CHARACTER SET. Dzięki IRQ można by przełączać CHARACTER SET co dwa rzędy. Na wyświetlanych polach można po kolei umieścić znaki ekranowe, które zmieniane by były podczas przesunięcia planszy.

Dlaczego dwa rzędy znaków? Zauważcie, że w Amaurote jest 16 pól w pionie! Podzielmy to na ilość dostępnych setów. Wyjdzie po 2 rzędy. Każdy rząd ma w poziomie 28 pól więc zdefiniować można 56 znaków dla każdego CHARACTER SET-u. Można też zrobić po 4 rzędy na CHARACTER SET - wtedy re-definiowane będzie 56*2=112 znaków a zmieniane będą tylko 4 sety, mniejsza z tym. Reszta znaków pozostaje na ruchomą animację i te ramko-plastry miodu dookoła.

SCREEN MEMORY można by wykorzystać jako double buffering: raz re-definiowane są znaki na jednym screenie, a raz na drugim - dzięki czemu przy wyświetlaniu nowego układu planszy następuje natychmiastowe przejście ze "starych" znaków na "nowe" - przez co nie będzie oczywiście widoczne to, że te znaki modyfikujemy "w locie". Sprawa jasna.

Obecnie silniczek, który napisałem pobiera numer pola z mapy i wyświetla relatywnie dla niego odpowiednie znaki ekranowe. To jest metoda na sztywkę, a gdyby zrobić właśnie dynamiczne zmieniane znaków?

Będą więc dwa pytania, pierwsze prowadzi do drugiego. Kto zna odpowiedź, niech napisze lub zamilknie na wieki:

1) Ile czasu zajmie re-definicja całej planszy? Plansza ma rozmiar 28 x 16 = 448 znaków - każdy składa się z 8 bajtów więc musimy zmienić wartości 3584 bajtów (!!). Teraz więc pytanie jak najszybciej je odczytać i wyświetlić, żeby przejścia te były w miarę płynne. Trzeba tu uwzględnić zmianę adresów do danego CHARACTER SET-u (zmienianego osiem lub cztery razy).

2) Czy dałoby się utworzyć mapę złożoną już z definicji znaków? Będzie to w sumie ta sama mapa co dotychczas tylko 8 razy większa (każdy wygląd znaku składa się z 8 bajtów). Odczytywane wartości byłyby od razu tymi bajtami składającymi się na znak: i w ten sposób za pomocą okna z danej pozycji byłyby od razu kopiowane do odpowiednich CHARACTER SET-ów.

Jeżeli na pytanie 1) i 2) znajdzie się rozwiązanie, ten silnik mogę spróbować napisać, jest prostszy niż dotychczasowo utworzony gdyż kopiowałby tylko dane wyglądu znaków ekranowych, które przełączane by były przez zmianę CHARACTER SET-ów z racji tego, iż jeden set ma tych znaków 256 a chcemy wyświetlić planszę, która ma ich 448 a dochodzą do tego znaki naszego pająka, pocisków, much, plastrów miodu (ramek).

Ciężko jest to napisać, łatwiej narysować a jeszcze prościej o tym pogadać na żywca, ale mam nadzieję, że jest to na tyle banalna metoda, że złapaliście o co mi chodzi. Tylko czy ja dobrze łapię, że to może się w miarę szybko wyrysować ;) - nie potrafię sobie jeszcze odpowiedzieć na to pytanie, brak doświadczenia mi na to nie pozwala ale będę próbował jakby co.

Awatar użytkownika
skull
Posty: 760
Rejestracja: 15 wrz 2008, 08:18
Grupa: samar

#33 Post autor: skull »

Chyba jednak nie ogaraniam tego co piszesz. Czy Ty nadal walczysz ze scrollowaniem planszy, czy z czymś innym?

Te gry które wymieniłeś, działają tylko na operacjach na bitmapie (nie wiem czy wogóle używają sprites i scrolla), bo kod był żywcem dostosowywany z zx spectrum, tam nie ma sprites.

Mimo wszystko przy konwersji tej gry - również bym postawił na zabawę na bitmapie, tyle że wzbogaconą warstwą ze sprites, a przesuwem na hsp/vsp. Okno gry nie jest duże.
Oczywiście, problem do rozwiązania to ten: priorytet wyświetlania punktów, - bo tak właśnie tworzymy grafikę trójwymiaru, postać bohatera i przeciwników - raz przed przeszkodą raz za, a dochodzi jeszcze nakładanie się przeciwników z bohaterem, pociski, czyli bedą potrzebne tablice maskujące, uwzględniające cechy sprites.

Ale może lepiej w trybie tekstowym.
Bo pecet to zwykły banan...

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#34 Post autor: BagoZonde »

Myślę o trybie tekstowym tylko. I tak jak w Amaurote nie myślę o żadnym scrollu - tylko o rysowaniu ekranu podczas przesunięcia (po przejściu pająka do krawędzi zostaje przesunięty ekran tak, że pająk znajduje się znowu na środku). Jeżeli scroll byłby możliwy to super, ale myślę, że C64 nie wyrobi aby to było płynne.

I chodzi mi o to, żeby w trakcie tego przesunięcia w locie kopiować bajty prosto z bitmapy (o taką mapę mi chodziło) do odpowiednich znaków ekranowych, np: idąc od 0 dojdziemy dla dwóch rzędów do 55 znaku - mamy więc 56 znaków dla każdego character setu a potem przełączamy na następny character set i znów definiowane jest kolejne 0-55 znaków ekranowych. A dlatego przełączane character sety za pomocą IRQ bo w jednym character secie nie zmieścimy całej planszy, której rozmiar to 28 x 16 = 448 znaków. W tym kontekście te okno jest duże ;).

Oczywiście do tego musi jeszcze istnieć mapa (taka jak obecnie w moim kodzie) służąca do detekcji czy na dane pole można wejść, czy można "te pole zniszczyć" pociskiem, etc.

Awatar użytkownika
skull
Posty: 760
Rejestracja: 15 wrz 2008, 08:18
Grupa: samar

#35 Post autor: skull »

czyli jak rozumiem - teraz Twoim problemem jest buforowanie ekranu?
Bo pecet to zwykły banan...

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#36 Post autor: BagoZonde »

Skull, ten problem nazywa się brakiem doświadczenia ;). Nie chcę wyważać otwartych drzwi więc mam tylko pytanie czy to może być w miarę szybkie? Jeżeli tak, napiszę do tego spokojnie kod, który potem ktoś doświadczony i tak pewnie będzie mógł przyspieszyć ;). Pomysł wydaje mi się dobry więc po prostu czy jest sens się tym babrać? Napiszę sobie do tego jakiś edytor, żeby mi bitmapę szybko generowało.

Awatar użytkownika
skull
Posty: 760
Rejestracja: 15 wrz 2008, 08:18
Grupa: samar

#37 Post autor: skull »

tzn. jeżeli przesuw ekranu ma być o taki "krok" jak jest w orginale, to może rzeczywiście lepiej przepisywać na char-y odpowiedni fragment z całej mapy levelu (czasu na pewno starczy).
Ale będzie to tylko rozwiązanie dla chodzenia po lokacji. Teraz trzeba będzie pomyśleć o przeszkodach/elementach wystających planszy. Tu z pomocą przychodzą sprites - ale nie do końca, bo priorytet wyświetlania sprite jest bardzo prymitywny, albo zasłania tło, albo tło zasłania sprite, no i w przypadku gdy ma tylko częściowo zasłonić robi się problem.
Żeby porządnie emulować ten "wymiar" potrzebna będzie zabawa w analizę punktów do wyświetlenia - tu jest kilka wariantów i nie wiadomo który w rezulatacie będzie korzystniejszy.
Żeby tego było mało, dochodzą pociski i rozwalanie przeszkód.
Operowanie na charach, wygląda w tym przypadku beznadziejnie.
Bo pecet to zwykły banan...

Awatar użytkownika
nes
Posty: 509
Rejestracja: 21 maja 2010, 22:03
Grupa: Impact

#38 Post autor: nes »

BagoZonde pisze:Skull, ten problem nazywa się brakiem doświadczenia ;)
W sumie, to z tym problemem spotykają się wszyscy piszący coś koderzy, którzy nie robią "wycinanek" ;)
"A ile zrobisz pompek ?" (c) 2o11 eLban
http://apt.hopto.org/nes/impact/

Awatar użytkownika
BagoZonde
Posty: 57
Rejestracja: 15 gru 2011, 09:33
Grupa: Commocore
Kontakt:

#39 Post autor: BagoZonde »

No nic, spróbuję więc to napisać na zasadzie kopiowania z gotowej bitmapy i podmiany odpowiednich CHARACTER SET-ów, żeby wyświetlić na ekranie taką ilość znaków. Pomysłów nigdy mi nie brakuje ;).

Co do maskowania, nie będę robił żadnej kolejności rysowania, tj. najpierw podłoga - potem pająk a potem zasłaniający go trochę budynek.

Tak jak pisałem wcześniej: budynki mimo tego, że są w rzeczywistości trójwymiarowe - zostaną potraktowane jako płaski element planszy a maskowane będą wszystkie obiekty "żywe". Do tego potrzebna więc będzie druga bitmapa-maska, która zasłaniać będzie tylko wtedy, gdy pozycja x i y będzie za danym polem.

Dużo paprania będzie i sporo miejsca to będzie zajmowało, ale czego się nie robi dla prędkości działania.

brush
Posty: 261
Rejestracja: 20 kwie 2009, 10:32
Grupa: Elysium

#40 Post autor: brush »

Hej,

Może się nie znam ale proponuje:

1. Nie morduj się z charsetami użyj bitmapę. Jeden to za mało, będziesz miał zabawy więcej i przepisywać dużo.
2. Jeśli chcesz mieć pajączka na środku ekranu i scrollować bitmapę za pomocą hsp/vsp (już ktoś proponował). Jak to wygląda w praktyce zobacz tutaj: http://csdb.dk/release/?id=55080 Jak to skodowac to chyba już też są jakieś tutoriale.
3. Jeśli nie chcesz scrollować tylko przerysowywać ekran w momencie dojścia do krawędzi to też bym się nie przejmował bo wiesz z pewnym wyprzedzeniem do ktorej krawędzi zmierza pajączek. Więc możesz ja wyrysować kilka ramek wcześniej i po prostu przełączyć tylko ekran jak już pajączek dojdzie. W najgorszym wypadku jak ktoś zmieni zdanie tuż przy krawędzie ekranu i zacznie zawracać to ci się "zmarnuje" to co narysowałeś, ale to żadna strata chyba.

Nie wiem dlaczego Atarowcy myślą, że się na c64 nie da :)

ODPOWIEDZ