;======================================================== ;Realistic Internet Simulator for Grzybsoniada 2012 competition ; ;2012-04-20 - 2012-05-03 ; ;Atari 8-bit ver. code: nosty ;compiled with XASM 3.0.2 ;-------------------------------------------------------- ;Original game: http://www2.b3ta.com/realistic-internet-simulator/ ;Author: Rob Manuel for B3ta.com ;-------------------------------------------------------- ; ;======================================================== ;obszar ekranu w jednostkach pozycji graczy/pociskow (0-255). ;x: 48 do 207 ;y: 32 do 223 ;kod kolor ;$0x szary ;$lx złoty ;$2x pomarańczowy ;$3x czerwony ;$4x różowy ;$5x purpurowy ;$6x fioletowy ;$7x niebieski zimny ;$8x niebieski ;$9x błękitny ;$Ax turkusowy ;$Bx niebiesko-zielony ;$Cx zielony ;$Dx żółto-zielony ;$Ex pomarańczowp-zielony ;$Fx żółty ;LICZNIK equ $14 ;RTC zwiekszany co 1/50s sysvbv equ $e45f ;systemowa proc VBLI jsetvblv equ $e45c ;ustawienie wektora VBLI NMIEN equ $D40E ;wlaczenie przerwan VDSLST equ $200 WSYNC equ $D40A VCOUNT equ $D40B PAL equ $D014 ;1 - PAL/SECAM, $0F - NTSC CONSOL equ $D01F ;status OPTION, SELECT, START (bity: 2,1,0) (0 - naciśnięty) HSCROL equ $D404 ;bity 0-3 okreslaja przesuniecie linii ekranu RANDOM equ $D20A TRIG0S equ $0284 ;rejestr cien fire joya 0 - bit 0 = 0 oznacza wcisniety fire CHBASE equ $D409 ;adres zestawu znakow (starszy bajt) ma cien CHABS - $02F4 (756) CHBAS equ $2F4 DMACTL equ $22F GRACTL equ $D01D GPRIOR equ $026F ;cien PRIOR'a PRIOR equ $D01B PMBASE equ $D407 ;pozycje X graczy HPOSP0 equ $D000 ;Standardowe pole gry zajmuje pozycje 41 do 207 HPOSP1 equ $D001 HPOSP2 equ $D002 HPOSP3 equ $D003 ;pozycje X pociskow HPOSM0 equ $D004 HPOSM1 equ $D005 HPOSM2 equ $D006 HPOSM3 equ $D007 ;kolory graczy COLPM0S equ $02C0 ;cien przepisywany w VBL COLPM0 equ $D012 COLPM1S equ $02C1 COLPM1 equ $D013 COLPM2S equ $02C2 COLPM2 equ $D014 COLPM3S equ $02C3 COLPM3 equ $D015 ;rozdzielczosc duszkow SIZEP0 equ $D008 SIZEP1 equ $D009 SIZEP2 equ $D00A SIZEP3 equ $D00B ;rodzielczosc pociskow SIZEM equ $D00C ;kolizje duszka z tlem KOLP0PF equ $D004 KOLP1PF equ $D005 KOLP2PF equ $D006 KOLP3PF equ $D007 HITCLR equ $D01E ;Zapis dowolnej wartości pod ten adres kasuje stany rejestrów kolizji. COLOR0 equ $02C4 COLOR1 equ $02C5 COLOR2 equ $02C6 COLOR3 equ $02C7 ;kolor piatego gracza z polaczonych pociskow COLOR4 equ $02C8 ;cien COLBAK COLPF0 equ $D016 COLPF1 equ $D017 COLPF2 equ $D018 COLPF3 equ $D019 ;kolor piatego gracza z polaczonych pociskow COLBAK equ $D01A ;cieniem jest COLOR4 STICK0 equ $0278 ;cien - stan joya 0 ATRACT equ $004d ;licznik wygaszacza ekranu - trzeba wstawiac 0 co jakis czas (kilkadziesiat sek.) dliadr equ $230 obr equ $58 ;-------------STALE---------------- player_bitmap_0 equ pmg_memory_1+4*256 ;poczatek obszaru graczy ;kolory KOL_kursora equ $9C KOL_tla equ $0 KOL_znakow equ $0E KOL_ramki equ $0 KOL_tla_tytul equ $30 KOL_tla_blue equ $82 KOL_licznika equ $36 max_okien equ 12 ;maxymalna liczba okien, ktora konczy gre STEREOMODE equ 0 ;0 => compile RMTplayer for mono 4 tracks ;-------------ZMIENNE--------------- org $80 _arr equ $80 _arr2 equ $82 _arr3 equ $84 uni2 equ $85 uni3 equ $86 uni4 equ $87 stan_joya equ $88 fire equ $89 stan_joya_poprzedni equ $8A stan_joya_zatrzask equ $8B licznik equ $8C kursor_X equ $8D ;lewy gorny rog strzalki (player 0) kursor_Y equ $8E level equ $8F ;okresla tylko poziom trudnosci gry licznik_old equ $90 licznik_joya equ $91 ;jak dlugo (ile ramek) stan joya sie nie zmienil - do akceleracji kursor_Xt equ $92 ;0..39 - kolumna tekstowa nad ktora jest kursor, $FF - poza ekranem, UWAGA! odswiezany tylko po fire ;kursor_Xt i kursor_Yt musza byc po kolei i kursor_Xt najpierw! (razem tworza aderes) kursor_Yt equ $93 ;0..23+#>pamiec_ekranu - wiersz tekstowy nad ktorym jest kursor ale przesuniety o pozycje pamieci ekranu, ;$FF - poza ekranem, UWAGA! odswiezany tylko po fire ;kursor_Yt i kursor_Xt tworza wiec jednoczesnie adres znaku pod kursorem znak_pod_kursorem equ $94 ;jaki znak ekranowy jest pod kursorem, UWAGA! odswiezany tylko po fire punkty equ $95 ;ilosc zamknietych okien ile_otwartych equ $96 ;ilosc otwartych okien oknaXt_tab equ $97 ;12 komorek - LSB adresu okna (albo pozycja X lewego gornego rogu), dane musza isc bez przerw bo $FF oznacza ze juz dalej nie ma okien oknaYt_tab equ $A3 ;12 komorek - MSB adresu okna (albo pozycja Y+#>pamiec_ekranu lewego gornego rogu ) oknaNr_tab equ $AF ;12 komorek - nr okna*2: 0,2,4,6,8,10,12,14, UWAGA! oknaXt_tab, oknaYt_tab, oknaNr_tab musza zajmowac obszar po sobie fire_poprzedni equ $BB ;poprzednia wartosc fire kursor_Xt_b equ $BC ;poprzednia wartosc kursora przy wcisnietym fire - do przesuwania okna za belke kursor_Yt_b equ $BD kliknieto_belke equ $BE ;$FF nie, inna wartosc - nr okna w ktorego belke kliknieto (0..11) wymazaneX_b equ $BF ;na potrzeby przesuwu okna wymazaneY_b equ $C0 ;na potrzeby przesuwu okna sfx_effect equ $C1 ;efekt do odegrania czy_w_grze equ $C2 ;0 - ekran tyt./bluescreen, 1 - rozgrywka punktyBCD equ $C3 opoznienie equ $C4 ;opoznienie 1s po zakonczeniu gry, zeby natychmiast nie wystartowac nowej ;!! od 203 ($CB) do 222 ($DE) zajete przez RMT player ;================================ run start org $2000 ekran_tytulowy ins "popupstitle.mapa" org $2400 ekran_blue ins "popupsblue.mapa" org $2800 fonty ins 'popups.fnt' org $2800 ;ten sam adres co fontow! pmg_memory_1 ;pierwszy 1kB wolny jesli nie uzywamy pociskow i mozna go dzielic z fontami org $3000 ;wolne 1kB wymagane przez RMT playera (koniecznie przed samym platerem) org $3400 icl "popups_rmtplayr.a65" ;include RMT player routine org $4000 muzyka opt h- ins "popups_sfx.rmt" ;689B zaokraglam do 3 stron opt h+ org $4300 pamiec_ekranu ;24 strony = 6kB na okna + 1 strona na linie statusu - kazda linia ma osobny adres od poczatku strony pamiec_ekranu2 equ pamiec_ekranu+50 ;wykorzystujemy ten sam obszat pamieci co pamiec_ekranu, ;ale z przesunieciem o 50 znakow (40+rezerwa), drugi eran jest jaky obok pierwszego org $6300 ;ale po liniach okien zostawiamy jeszcze 7 stron rezerwy na okna wystajace za krawedz ;display list dl dta $70,$70,$70 dta $42,a(pamiec_ekranu) dta $42,a(pamiec_ekranu+$100) dta $42,a(pamiec_ekranu+$200) dta $42,a(pamiec_ekranu+$300) dta $42,a(pamiec_ekranu+$400) dta $42,a(pamiec_ekranu+$500) dta $42,a(pamiec_ekranu+$600) dta $42,a(pamiec_ekranu+$700) dta $42,a(pamiec_ekranu+$800) dta $42,a(pamiec_ekranu+$900) dta $42,a(pamiec_ekranu+$A00) dta $42,a(pamiec_ekranu+$B00) dta $42,a(pamiec_ekranu+$C00) dta $42,a(pamiec_ekranu+$D00) dta $42,a(pamiec_ekranu+$E00) dta $42,a(pamiec_ekranu+$F00) dta $42,a(pamiec_ekranu+$1000) dta $42,a(pamiec_ekranu+$1100) dta $42,a(pamiec_ekranu+$1200) dta $42,a(pamiec_ekranu+$1300) dta $42,a(pamiec_ekranu+$1400) dta $42,a(pamiec_ekranu+$1500) dta $42,a(pamiec_ekranu+$1600) dta $42,a(pamiec_ekranu+$1700) dta $42,a(pamiec_ekranu+$1F00) ;linia statusu dta $41,a(dl) ;display list 2 dl2 dta $70,$70,$70 dta $42,a(pamiec_ekranu2) dta $42,a(pamiec_ekranu2+$100) dta $42,a(pamiec_ekranu2+$200) dta $42,a(pamiec_ekranu2+$300) dta $42,a(pamiec_ekranu2+$400) dta $42,a(pamiec_ekranu2+$500) dta $42,a(pamiec_ekranu2+$600) dta $42,a(pamiec_ekranu2+$700) dta $42,a(pamiec_ekranu2+$800) dta $42,a(pamiec_ekranu2+$900) dta $42,a(pamiec_ekranu2+$A00) dta $42,a(pamiec_ekranu2+$B00) dta $42,a(pamiec_ekranu2+$C00) dta $42,a(pamiec_ekranu2+$D00) dta $42,a(pamiec_ekranu2+$E00) dta $42,a(pamiec_ekranu2+$F00) dta $42,a(pamiec_ekranu2+$1000) dta $42,a(pamiec_ekranu2+$1100) dta $42,a(pamiec_ekranu2+$1200) dta $42,a(pamiec_ekranu2+$1300) dta $42,a(pamiec_ekranu2+$1400) dta $42,a(pamiec_ekranu2+$1500) dta $42,a(pamiec_ekranu2+$1600) dta $42,a(pamiec_ekranu2+$1700) dta $42,a(pamiec_ekranu+$1F00) ;linia statusu dta $41,a(dl2) dl_title dta $70,$70,$70 dta $42 dl_title_e dta a(ekran_tytulowy) :23 dta $02 dta $41,a(dl_title) ;--------------------------------------- ;--------------------------------------- start jsr inicjalizacja_gry st_1 lda licznik ;synchronizacja z VBI cmp licznik_old beq st_1 sta licznik_old ;---muzyka jsr RASTERMUSICTRACKER+3 ;gramy melodie glowna lda #0 sta ATRACT ;zeby nie wlaczyl sie wygaszacz ;--jesli wcisnieto ESC to wyjscie do DOS'a lda 764 cmp #$1C bne st_2 ;wyjscie do dosa lda #$ff ; ustawiamy na $FF ostatnio wcisniety klawisz sta 764 mva #$00 GRACTL ;zatrzymanie wyswietlania PMG ;wylaczenie muzyki jsr RASTERMUSICTRACKER+9 ;all sounds off ;wylaczenie przerwan lda #0 sta NMIEN ;przywrocenie czcionek systemowych lda #$E0 sta CHBAS jmp ($000a) ;wyjscie do DOS st_2 lda opoznienie beq st_3 dec opoznienie jmp st_1 st_3 ;--czekamy na nacisniecie fire zeby zaczac gre lda fire and #1 bne st_1 ;---fire wcisniety--- lda #1 sta czy_w_grze jsr inicjalizajca_rozgrywki ;-------------------------------------------------- ;-------------------------------------------------- ;tu sie zaczyna glowna petla w czasie gry g2 lda licznik ;synchronizacja z VBI cmp licznik_old beq g2 sta licznik_old ;---muzyka jsr RASTERMUSICTRACKER+3 ;gramy melodie glowna lda #0 sta ATRACT ;zeby nie wlaczyl sie wygaszacz jsr obsluga_joya jsr rysuj_kursor jsr obsluga_fire jsr generuj_okna jsr rysuj_okna jsr rysuj_status ;---sprawdzenie czy nie otwarto juz 12 okien lda ile_otwartych cmp #12 bcc g_koniec ;---koniec gry lda #0 sta czy_w_grze jsr czysc_kursor jsr czysc_punkty_srodek jsr punkty_na_blue lda #KOL_tla_blue sta COLOR2 mwa #ekran_blue obr ;---ustawienia pamieci obrazu mwa #ekran_blue dl_title_e mwa #dl_title dliadr ;ustawienie DL jsr RASTERMUSICTRACKER+9 ;all sounds off lda #240 sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) lda #7 ;efekt sta sfx_effect lda #$FF sta fire ;zeby od razu nie wystartowac znowu lda #50 sta opoznienie ;to 1s opoznienia w starcie gry lda #$ff ; ustawiamy na $FF ostatnio wcisniety klawisz sta 764 jmp st_1 g_koniec jmp g2 ;------------------------------------------------ ;tu jest sprawdzane czy wcisniety fire i jesli tak ;to robiona jest cala logika gry zwiazana z akcja gracza! obsluga_fire lda kliknieto_belke cmp #$FF beq of_17 lda wymazaneX_b sta ro_gdzie+1 ;LSB gdzie rysowac lda wymazaneY_b sta ro_gdzie+2 ;MSB gdzie rysowac ldy #64 jsr rysuj_okno of_17 lda fire and #1 beq of_p jmp of_kk of_p ;---fire wcisniety--- ; ;--obliczam zmienne pod kursorem lda kursor_X sec sbc #48 :2 lsr @ ;/4 cmp #40 ;sprawdzamy czy kursor nie jest poza polem gry bcc of_2 lda #$FF ;znacznik ze kursor poza polem gry sta kursor_Xt jmp of_k ;jesli kursor poza polem gry to nic nie robimy of_2 sta kursor_Xt lda kursor_Y sec sbc #32 :3 lsr @ ;/8 clc adc #>pamiec_ekranu ;przesuniecie cmp #>pamiec_ekranu+24 ;sprawdzamy czy kursor nie jest poza polem gry bcc of_3 lda #$FF ;znacznik ze kursor poza polem gry sta kursor_Yt jmp of_k ;jesli kursor poza polem gry to nic nie robimy of_3 sta kursor_Yt ;w kursor_Yt i kursor_Xt mamy adres znaku pod kursorem i wiemy ze jest w polu gry ldy #0 lda (kursor_Xt),y sta znak_pod_kursorem ;---teraz obsluga logiki--- lda fire_poprzedni and #1 bne of_15 jmp of_4 of_15 ;---fire zostal dopiero wcisniety lda #$FF ;jak dopiero wcisniety to mozna wyczyscic te zmienna sta kliknieto_belke lda znak_pod_kursorem cmp #$43 ;znak zamykania okna bne of_5 ;---zamykamy okno--- ;najpierw szukamy ktore, od najnowszych w glab - zamkniemy pierwsze ldy #11 of_7 lda oknaYt_tab,y cmp kursor_Yt ;czy linia sie zgadza? bne of_6 lda oknaXt_tab,y ;teraz sprawdzamy kolumne clc adc #9 cmp kursor_Xt bne of_6 ;mamy okno do zamkniecia! pozycja jest w Y jsr zamknij_okno inc punkty sed ;tryb BCD clc lda punktyBCD adc #1 sta punktyBCD cld ;wyjscie z trybu BCD ;wyswietlamy punkty jsr punkty_na_srodek ;sfx lda #240 ;initial value sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) lda #1 ;efekt sta sfx_effect jmp of_k of_6 dey bpl of_7 jmp of_k ;to sie praktycznie nie powinno zdarzyc of_5 cmp #$42 ;znak gornej belki beq of_8 cmp #$41 ;znak lewego gornego rogu - oba dzialaja tak samo beq of_8 jmp of_9 of_8 ;---kliknieto w belke - wyciagamy okno na pierwszy plan ;najpierw szukamy ktore, od najnowszych w glab ldy #11 of_10 lda oknaYt_tab,y cmp kursor_Yt ;czy linia sie zgadza? bne of_11 lda kursor_Xt ;teraz sprawdzamy kolumne ;czy kursor > lewej krawedzi cmp oknaXt_tab,y bcc of_11 sec ;w A mamy kursor_Xt sbc oknaXt_tab,y cmp #9 ;roznica ma byc mniejsza niz 9 bcs of_11 ;mamy okno do wyciagniecia pozycja jest w Y jsr wyciagnij_okno ;teraz zapamietujemy pozycje kursora, zeby moc przesunac okno jesli ;gracz przytrzyma kursor na belce i przesunie kursorem lda kursor_Xt sta kursor_Xt_b lda kursor_Yt sta kursor_Yt_b ldy ile_otwartych dey ;bo to okno jest wyciagniete na wierzch sty kliknieto_belke ;przyda sie do przesuniecia okna lda oknaXt_tab,y sta wymazaneX_b lda oknaYt_tab,y sta wymazaneY_b jmp of_k of_11 dey bpl of_10 jmp of_k ;to sie praktycznie nie powinno zdarzyc of_9 cmp #$40 ;jesli kliknieto w font od $40 do $51 to wychodz bcc of_9a cmp #$52 bcs of_9a jmp of_k of_9a ;w przeciwnym wypadku wiemy ze ;---kliknieto w okno - generujemy 3 nowe okna ;niewazne w ktore okno kliknieto lda #240 ;initial value sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) lda #5 ;efekt sta sfx_effect lda ile_otwartych cmp #11 beq of_12 cmp #10 beq of_13 cmp #12 beq of_k jsr generuj_nowe_okno of_13 jsr generuj_nowe_okno of_12 jsr generuj_nowe_okno of_4 ;--fire jest wcisniety i byl wcisniety wczesniej--- ;sprawdzamy czy byla trzymana belka lda kliknieto_belke cmp #$FF beq of_14 ;belka trzymana, obliczamy nowa pozycje tay ;tu mamy nr okna ;sprawdzenie czy kursor sie ruszyl ; lda kursor_Xt ; cmp kursor_Xt_b ; bne of_16 ; lda kursor_Yt ; cmp kursor_Yt_b ; bne of_16 ; jmp of_14 ;of_16 lda oknaXt_tab,y ;sta ro_gdzie+1 ;LSB gdzie rysowac sta wymazaneX_b ;zapamietujemy gdzie wymazac w nastepnej ramce clc adc kursor_Xt ;dodajemy nowa pozycje kursora sec sbc kursor_Xt_b ;odejmujemy stara pozycje kursora ;sprawdzamy czy nie przekraczamy granic cmp #200 ;czy nie jestesmy ponizej zera bcc of_18 lda #0 of_18 cmp #38 ;to chyba nie potrzebne ale zostawiam na wszelki wypadek bcc of_19 lda #38 of_19 sta oknaXt_tab,y lda oknaYt_tab,y ;sta ro_gdzie+2 ;MSB gdzie rysowac sta wymazaneY_b clc adc kursor_Yt sec sbc kursor_Yt_b sta oknaYt_tab,y ;ldy #64 ;ktora definicja okna *2 (czyli 0,2,4...16) ;jsr rysuj_okno ;dziwne!!! bez tego nie powinno dzialac poprawnie, a dziala ;) ;gdyby przesuwanie mialo byc kontynuowane zapamietujemy pozycje kursora lda kursor_Xt sta kursor_Xt_b lda kursor_Yt sta kursor_Yt_b jmp of_k of_14 of_kk lda #$FF sta kliknieto_belke of_k rts ;----------------------------------------------- ;po zakonczeniu gry wstawia ilosc punktow ;na blue screen punkty_na_blue lda punktyBCD and #%00001111 clc adc #16 sta ekran_blue+18*40+21 lda punktyBCD and #%11110000 :4 lsr @ clc adc #16 sta ekran_blue+18*40+20 rts ;----------------------------------------------- ;wyswietla punktyBCD na duszkach na ekranie punkty_na_srodek ;mlodsza cyfra lda #7 sta uni2 lda #32 ;#32+12*8-16 sta cB2p_2+1 lda punktyBCD and #%00001111 jsr cyfraBCD2pmg ;starsza cyfra lda #6 sta uni2 lda #32 ;#32+12*8-16 sta cB2p_2+1 lda punktyBCD and #%11110000 :4 lsr @ jsr cyfraBCD2pmg rts ;--------------------------------------------------- ;wyswietla cyfre w A (0 - 9 i 240),240 oznacza spacje ;na duszku wskazanym przez uni2: 3 - pociski, 4 - P0, 5 - P1, 6 - P2, 7 - P3 ;i pozycji pionowej wskazanej przez cB2p_2+1 cyfraBCD2pmg :3 asl @ ;cyfra *8 clc adc #16*8 sta cB2p_4+1 lda #>fonty sta cB2p_4+2 ;ustalanie adresu docelowego lda #pmg_memory_1 adc uni2 sta cB2p_3+2 ;-- ldx #31 cB2p_1 txa lsr @ lsr @ tay cB2p_4 lda $FFFF,y ;automodyfikowany cB2p_3 sta pmg_memory_1,x dex bpl cB2p_1 rts ;-------------------------- ;czysci punkty na duszkach na ekranie (wstawia spacje) czysc_punkty_srodek ;mlodsza cyfra lda #7 sta uni2 lda #32 ;#32+12*8-16 sta cB2p_2+1 lda #240 jsr cyfraBCD2pmg ;starsza cyfra lda #6 sta uni2 lda #32 ;#32+12*8-16 sta cB2p_2+1 lda #240 jsr cyfraBCD2pmg rts ;----------------------------------------------- ;wyciaga na pierwszy plan okno o nr Y (0..11) wyciagnij_okno lda oknaXt_tab,y pha lda oknaYt_tab,y pha lda oknaNr_tab,y pha ;przesuwamy wartosci w tabelach w dol wo_3 lda oknaXt_tab+1,y sta oknaXt_tab,y lda oknaYt_tab+1,y sta oknaYt_tab,y lda oknaNr_tab+1,y sta oknaNr_tab,y iny cpy ile_otwartych bne wo_3 dey pla sta oknaNr_tab,y pla sta oknaYt_tab,y pla sta oknaXt_tab,y wo_k rts ;----------------------------------------------- ;zamyka okno o nr Y (0..11) zamknij_okno lda oknaXt_tab,y sta rono_gdzie+1 ;LSB gdzie rysowac lda oknaYt_tab,y sta rono_gdzie+2 ;MSB gdzie rysowac sty zo_2+1 ;zeby odtworzyc ldy #64 ;ktora definicja okna *2 (czyli 0,2,4...16) jsr rysuj_okno_na_obu zo_2 ldy #0 ;automodyfikowane ;usuwamy dane okna z tablic i przesuwamy wartosci w dol jesli trzeba zo_3 lda oknaXt_tab+1,y sta oknaXt_tab,y lda oknaYt_tab+1,y sta oknaYt_tab,y lda oknaNr_tab+1,y sta oknaNr_tab,y iny cpy #12 bne zo_3 dey lda #$FF ;wstawiamy $FF na ostatnia pozycje (11) sta oknaXt_tab,y sta oknaYt_tab,y sta oknaNr_tab,y dec ile_otwartych zo_k rts ;------------------------------------------------ ;procedura w odpowiednich odstepach czasu dodaje nowe okna ;i jesli jest ich za duzo to konczy gre ;robimy 4 rozne predkosci dodawania okien generuj_okna lda ile_otwartych cmp #max_okien beq go_k ;jak otwartych 12 to koniec gdy - nie generujemy nowych lda punkty cmp #16 bcs go_2 lda licznik and #%01111111 ;!!! do testow, potem ma tej linii nie byc jmp go_4 go_2 cmp #24 bcs go_3 lda licznik and #%01111111 jmp go_4 go_3 cmp #34 bcs go_5 lda licznik and #%00111111 jmp go_4 go_5 lda licznik and #%00011111 go_4 bne go_k ;co n-ta ramke dodajemy nowe okno lda #128 ;o polowe ciszej niz inne dzwieki sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) lda #2 ;efekt sta sfx_effect jsr generuj_nowe_okno go_k rts ;------------------------------ -------- ;tworzy nowe okno w losowym miejscu ;nie kontroluje ile juz jest okien otwartych! generuj_nowe_okno inc ile_otwartych ldy #38 lda punkty cmp #7 bcs gno_2 ldy #30 ;pierwsze kilka okien nie bedzie wystawac poza krawedz gno_2 jsr losuj63 ;losujemy liczbe z zakresu 0..38 - pozycje pozioma okna ldy ile_otwartych sta oknaXt_tab-1,y ldy #21 jsr losuj31 ;losujemy liczbe z zakresu 0..21 - pozycje pionowa okna clc adc #>pamiec_ekranu ;ustalamy faktyczny MSB adresu ldy ile_otwartych sta oknaYt_tab-1,y ;losujemy nr okna 0..18 ldy #18 jsr losuj31 asl @ ;*2 ldy ile_otwartych sta oknaNr_tab-1,y rts ;narzedziowka - losuje liczbe z zakresu 0..Y ale nie wieksza niz 31 losuj31 iny sty los31_2+1 ;gorna granica losowania los31_3 lda RANDOM and #%00011111 los31_2 cmp #0 ;automodyfiowany bcs los31_3 ;dopoki wylowana liczba przekracza granice to probuj dalej rts ;narzedziowka - losuje liczbe z zakresu 0..Y ale nie wieksza niz 63 losuj63 iny sty los63_2+1 ;gorna granica losowania los63_3 lda RANDOM and #%00111111 los63_2 cmp #0 ;automodyfiowany bcs los63_3 ;dopoki wylowana liczba przekracza granice to probuj dalej rts ;------------------------------------------------- ;rysuje okna na ekranie w odpowiedniej kolejnosci ;uzywa uni2 rysuj_okna lda ile_otwartych beq rok_k ;jak 0 otwartych to nic nie rysujemy ldy #0 rok_3 ;rysujemy okno lda oknaXt_tab,y sta ro_gdzie+1 ;LSB gdzie rysowac lda oknaYt_tab,y sta ro_gdzie+2 ;MSB gdzie rysowac sty rok_2+1 ;zeby odtworzyc lda oknaNr_tab,y tay ;ktora definicja okna *2 (czyli 0,2,4...16) jsr rysuj_okno rok_2 ldy #0 ;automodyfikowany iny cpy ile_otwartych ;w taki sposob bo y petli sie od 0 bne rok_3 rok_k rts ;------------------------------------------------- ;rysuje pasek postepu na linii statusu ;kazde otwarte okno to 3 znaki ;uzywa uni2 rysuj_status ldy ile_otwartych lda mnozenie_x3_tab,y ;mamy ilosc otwartych okien *3 tay :3 iny ;4..39 zaleznie ile jest otwartych okien sty uni2 lda #$0 ldy #40 rst_2 sta pamiec_ekranu+$1F00,y dey cpy uni2 bne rst_3 lda #$80 rst_3 cpy #3 bne rst_2 rts ;------------------------------------------------ ;przesuwa kursor zaleznie od ruchu joyem ;obsluguje akceleracje ;uzywa A, uni2 obsluga_joya lda stan_joya cmp #$0F beq oj_k ;jak joy puszczony to nic nie robimy jsr czysc_kursor ;a jak wychylony to najpierw czyscimy stare polozenie kursora ; lda stan_joya cmp stan_joya_poprzedni beq oj_2 lda #0 sta licznik_joya oj_2 inc licznik_joya lda licznik_joya :3 lsr @ ;/8 sta uni2 inc uni2 ;teraz sprawdzamy kierunek lda stan_joya and #%00000001 bne oj_3 ;w gore lda kursor_Y sec sbc uni2 cmp #32 bcs oj_3a lda #32 oj_3a sta kursor_Y oj_3 lda stan_joya and #%00000010 bne oj_4 ;w dol lda kursor_Y clc adc uni2 cmp #223 bcc oj_4a lda #223 oj_4a sta kursor_Y oj_4 lda stan_joya and #%00000100 bne oj_5 ;w lewo lda kursor_X sec sbc uni2 cmp #48 bcs oj_5a lda #48 oj_5a sta kursor_X sta HPOSP0 oj_5 lda stan_joya and #%00001000 bne oj_6 ;w prawo lda kursor_X clc adc uni2 cmp #207 bcc oj_6a lda #207 oj_6a sta kursor_X sta HPOSP0 oj_6 oj_k rts ;------------------------------------------------ ;rysuje na ekranie okno o numerze*2 w y ;adres juz jest wpisany do automodyfikowanej ro_gdzie+1 ;ta procedura moze zostac pozniej przebudowana! ;mozna usmiescic kolejne linie okien na kolejnych stronach co uprosci dodawanie #12 ; ;kiedy okno mialo 12 znakow szerokosci wykonywala sie w okolo 1600 taktow, ;uzywa X, Y rysuj_okno ;ustawienie automodyfikowalnego adresu na wlasciwa definicje okna lda okna_adr_tab,y sta ro_2+1 lda okna_adr_tab+1,y sta ro_2+2 ; ;rysujemy na ekranie zaleznym od licznika lda licznik and #%00000001 bne ro_4 lda ro_gdzie+1 clc adc #50 ;ustawienie na pamiec_ekranu2 sta ro_gdzie+1 ro_4 ; ldx #8 ro_3 ldy #9 ro_2 lda $FFFF,y ;automodyfikowany - skad ro_gdzie sta $FFFF,y ;automodyfikowany - dokad dey bpl ro_2 ;zwiekszamy adres wynikowy o strone a wiec zmieniamy linie na kolejna inc ro_gdzie+2 ;zwiekszamy adres skad czytamy lda ro_2+1 clc adc #10 sta ro_2+1 ;def. okna nie przekracza strony wiec starszy bajt adresu sobie darujemy dex bne ro_3 rts ;------------------------------------------------ ;rysuje na ekranie okno o numerze*2 w y na obu okranach ;adres juz jest wpisany do automodyfikowanej rono_gdzie+1 ;ta procedura jest wolna, ale dla 12 okien w PAL sie wyrabia ;moznaby usmiescic kolejne linie okien na kolejnych stronach co uprosci dodawanie #12 ; ;uzywa X, Y rysuj_okno_na_obu ;ustawienie automodyfikowalnego adresu na wlasciwa definicje okna lda okna_adr_tab,y sta rono_2+1 lda okna_adr_tab+1,y sta rono_2+2 ; ;automodyfikacja rono_gdzie2 lda rono_gdzie+1 clc adc #50 ;ustawienie na pamiec_ekranu2 sta rono_gdzie2+1 lda rono_gdzie+2 sta rono_gdzie2+2 ; ldx #8 rono_3 ldy #9 rono_2 lda $FFFF,y ;automodyfikowany - skad rono_gdzie sta $FFFF,y ;automodyfikowany - dokad rono_gdzie2 sta $FFFF,y ;automodyfikowany - dokad dey bpl rono_2 ;zwiekszamy adres wynikowy o strone a wiec zmieniamy linie na kolejna inc rono_gdzie+2 inc rono_gdzie2+2 ;zwiekszamy adres skad czytamy lda rono_2+1 clc adc #10 sta rono_2+1 ;def. okna nie przekracza strony wiec starszy bajt adresu sobie darujemy dex bne rono_3 rts ;----------------------------------- ;rysuje kursor w miejscu kursor_Y rysuj_kursor ;ustawienie automodyfikowanego adresu gdzie rysowac mva #>player_bitmap_0 rk_3+2 mva kursor_Y rk_3+1 ldy #12 rk_2 lda kursor_0,y rk_3 sta $FFFF,y ;automodyfikowany dey bpl rk_2 rts ;----------------------------------- ;rysuje kursor w miejscu kursor_Y ;!wersja na kursor na 2 duszkach ;rysuj_kursor ; ;ustawienie automodyfikowanego adresu gdzie rysowac ; mva #>player_bitmap_0 rk_3+2 ; mva #>[player_bitmap_0+$100] rk_4+2 ; mva kursor_Y rk_3+1 ; sta rk_4+1 ; ldy #12 ;rk_2 ; lda kursor_0,y ;rk_3 ; sta $FFFF,y ;automodyfikowany ; lda kursor_1,y ;rk_4 ; sta $FFFF,y ;automodyfikowany ; dey ; bpl rk_2 ; rts ;----------------------------------- ;rysuje kursor w miejscu kursor_Y ale wypelnia zerami czysc_kursor ;ustawienie automodyfikowanego adresu gdzie rysowac mva #>player_bitmap_0 ck_3+2 mva kursor_Y ck_3+1 ldy #12 ck_2 lda #0 ck_3 sta $FFFF,y ;automodyfikowany dey bpl ck_2 rts ;----------------------------------- ;rysuje kursor w miejscu kursor_Y ale wypelnia zerami ;!wersja na kursor na 2 duszkach ;czysc_kursor ; ;ustawienie automodyfikowanego adresu gdzie rysowac ; mva #>player_bitmap_0 ck_3+2 ; mva #>[player_bitmap_0+$100] ck_4+2 ; mva kursor_Y ck_3+1 ; sta ck_4+1 ; ldy #12 ;ck_2 ; lda #0 ;ck_3 ; sta $FFFF,y ;automodyfikowany ;ck_4 ; sta $FFFF,y ;automodyfikowany ; dey ; bpl ck_2 ; rts ;--------------------------------- ;trzeba odpalic raz na poczatku uruchomienia programu inicjalizacja_gry ;---wyzerowanie zmiennych na stronie 0 ldy #$80 lda #0 ig_4 sta $0,y iny bne ig_4 jsr czysc_PMG ;ustawienia kolorow lda #KOL_tla_tytul sta COLOR2 lda #KOL_znakow sta COLOR1 lda #KOL_ramki sta COLOR4 ;------inicjalizacja PMG------- jsr inicjalizacja_PMG ;-----przelaczenie zestawu znakow lda #>fonty sta CHBAS ;-----muzyka--------- lda #$F0 ;initial value sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) lda #$FF ;initial value sta sfx_effect ldx #muzyka ;hi byte of RMT module to Y reg lda #2 ;starting song line 0-255 to A reg jsr RASTERMUSICTRACKER ;Init ;VBI jsr ustaw_i_wlacz_przerwania ;----zmienne----- lda #0 sta level ;zaczynamy od levelu 0 lda #$FF ;bo po inicjalizacja_gry jest sprawdzany fire sta fire ;a VBLI jeszcze nie zdazy go obsluzyc mwa #ekran_tytulowy obr ;---ustawienia pamieci obrazu mwa #dl_title dliadr ;ustawienie DL rts ;------------------------------------ ;przed kazda nowa gra inicjalizajca_rozgrywki jsr czysc_ekran ;wypelnia ekran kaszka lda #0 sta licznik_joya sta ile_otwartych ;ilsoc otwartych okien sta punkty sta punktyBCD lda #$FF sta kliknieto_belke jsr czysc_dane_otwartych lda #32+95 sta kursor_Y lda #48+80 sta kursor_X sta HPOSP0 ;zerowanie licznika na ekranie jsr punkty_na_srodek ;---przelaczenie ekranow, kolorow itp lda #KOL_tla sta COLOR2 mwa #pamiec_ekranu obr ;---ustawienia pamieci obrazu mwa #dl dliadr ;ustawienie DL ;wylaczenie muzyki jsr RASTERMUSICTRACKER+9 ;all sounds off ldx #muzyka ;hi byte of RMT module to Y reg lda #0 ;0 - nic nie gra jsr RASTERMUSICTRACKER ;Init ;napisanie "MEM:" w lini statusu ldy #3 ir_5 lda mem_text,y sta pamiec_ekranu+$1F00,y dey bpl ir_5 ;--- rts ;---------------------- ;wypelnia $FF dane otwartych okien czysc_dane_otwartych ldy #35 lda #$FF cdo_2 sta oknaXt_tab,y dey bpl cdo_2 rts ;----------------------------- ustaw_i_wlacz_przerwania ;ustawienie przerwania VBI ldy #vbli lda #$06 jsr jsetvblv lda #64 ;wlaczenie tylko VBL sta NMIEN rts ;------------------------------------- ;czysci $40 pamiec_ekranu i pamiec_ekranu2 ale tylko 24 linie po 40 bajtow ;nie musimy czyscic tego co poza ekranem ;linia statusu nie musi byc czyszczona, bo procedura rysujaca pasek czysci ja sama ;uzywa a, y, x czysc_ekran mwa #pamiec_ekranu+$1700 ce_2+1 ;ustawienie automodyfikowanego mwa #pamiec_ekranu2+$1700 ce_4+1 ldx #24 lda #$40 ce_3 ldy #39 ce_2 sta $FFFF,y ;automodyfikowany ce_4 sta $FFFF,y ;automodyfikowany dey bpl ce_2 dec ce_2+2 ;zeby przejsc do kolejnej, wczesniejszej linii odejmujemy tylko strone dec ce_4+2 dex bne ce_3 ;i tak 24 linie rts ;------------------------------------- ;czysci $0 obszar PMG 4x256B - tylko graczy! ;uzywa a, y, x czysc_PMG ldy #0 lda #0 cPMG_1 sta pmg_memory_1+$400,y sta pmg_memory_1+$500,y sta pmg_memory_1+$600,y sta pmg_memory_1+$700,y dey bne cPMG_1 rts ;----inicjalizacja PMG---- inicjalizacja_PMG lda #>pmg_memory_1 sta PMBASE ;DMACTL = playfield + dl + players + missiles + hires_sprites lda #62 sta DMACTL ;GRACTL = tylko players lda #2 sta GRACTL ;GPRIOR lda #%00000001 ;priorytet 1 sta GPRIOR ;pojedyncza szerokosc graczy 0,1, podwojna 2,3 (licznik) lda #0 sta SIZEP0 sta SIZEP1 lda #1 sta SIZEP2 sta SIZEP3 ;---ustawienie pozycji duszkow lda #48+12*4 sta HPOSP0 sta kursor_X lda #48 ;#48+160/2-16 ;pierwsza cyfra licznika sta HPOSP2 lda #48+16 ;#48+160/2 ;druga cyfra licznika sta HPOSP3 ;kolory duszkow lda #KOL_kursora sta COLPM0S lda #KOL_licznika sta COLPM2S sta COLPM3S ;---koniec inicjalizacji PMG rts ;----------------------------------------- ;przerwanie VBLI - synchro pionowej - dziala zawsze vbli php pha tya pha txa pha ;-- inc licznik ;---obsluga joya i fire--- ;zapamietanie poprzedniego stanu lda stan_joya sta stan_joya_poprzedni lda STICK0 sta stan_joya ;---obsluga SFX'ow--- lda sfx_effect bmi vb_4 asl @ ; * 2 tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126) ldx #3 ;X = 3 channel (0..3 or 0..7 for stereo module) lda #12 ;A = 12 note (0..60) jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!) lda #$ff sta sfx_effect ;reinit value vb_4 ;---muzyka ;jsr RASTERMUSICTRACKER+3 ;gramy melodie glowna ;---obsluga zatrzaskow eor stan_joya_poprzedni and stan_joya_poprzedni eor #%11111111 sta stan_joya_zatrzask ;na danym bicie bedzie 0 TYLKO po zmianie stanu bitu ;fire lda fire sta fire_poprzedni lda TRIG0S sta fire ;---przelaczanie ekranow jesli jestesmy w rozgrywce lda czy_w_grze bne vb_2b jmp vb_2a vb_2b lda licznik and #%00000001 bne vb_2 mwa #pamiec_ekranu obr ;---ustawienia pamieci obrazu mwa #dl dliadr ;ustawienie DL jmp vb_3 vb_2 mwa #pamiec_ekranu2 obr ;---ustawienia pamieci obrazu mwa #dl2 dliadr ;ustawienie DL vb_3 ;----animacja reklam---- lda licznik and #%00010000 ;/*32 ramek bne vb_5 mwa #okno12a okna_adr_smolensk mwa #okno13a okna_adr_cycki jmp vb_6 vb_5 mwa #okno12 okna_adr_smolensk mwa #okno13 okna_adr_cycki vb_6 ;vbxe mwa #okno14 okna_adr_vbxe lda RANDOM and #%00001111 ;szansa 1/16 bne vb_7 mwa #okno14a okna_adr_vbxe vb_7 ;line runner lda licznik and #%00001000 ;/*16 ramek bne vb_8 mwa #okno18a okna_adr_line jmp vb_9 vb_8 mwa #okno18 okna_adr_line vb_9 vb_2a ;-- pla tax pla tay pla plp jmp sysvbv ;=================================================== ;DANE ;=================================================== ;----------------------------------- ;tabela adresow definicji okien do wylosowania okna_adr_tab dta a(okno0) dta a(okno1) dta a(okno2) dta a(okno3) dta a(okno4) dta a(okno5) dta a(okno6) dta a(okno7) dta a(okno8) dta a(okno9) dta a(okno10) dta a(okno11) okna_adr_smolensk dta a(okno12) okna_adr_cycki dta a(okno13) okna_adr_vbxe dta a(okno14) dta a(okno15) dta a(okno16) dta a(okno17) okna_adr_line dta a(okno18) dta a(okno_tlo) ;do zamazywania tla pod oknem dta a(okno_tlo) ;a tyle bo nie chce mi sie zmieniac kodu ;) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) dta a(okno_tlo) kursor_z ;13B do zamazania poprzedniej pozycji kursora :13 dta 0 kursor_0 ;13B dta $80,$C0,$E0,$F0,$F8,$F0,$E0,$E0,$B0,$90,$18,$08,$08 ;kursor_1 ;13B ; dta $C0,$E0,$F0,$F8,$FC,$F8,$F0,$F0,$B8,$98,$1C,$0C,$0C mnozenie_x3_tab dta 0,3,6,9,12,15,18,21,24,27,30,33,36 ;do mnozenia 0..12 x3 mem_text dta d"MEM:" ;definicje okien nie moga przekraczac granicy stron ;to upraszcza rysowanie w obecnej formie procedury ;wstawiamy definicje w nieuzywane obszary pamieci ekranu ;(dwa ekrany zajmuja tylko po 100 bajtow na poczatku kazdej strony) ;wiec wcisniemy jeszcze po 1 definicji do kazdej linii org pamiec_ekranu+100 okno0 ins "popupsTDC.mapa" org pamiec_ekranu+$100+100 okno1 ins "popupsPIN.mapa" org pamiec_ekranu+$200+100 okno2 ins "popupsGONZO.mapa" org pamiec_ekranu+$300+100 okno3 ins "popupsSIKOR.mapa" org pamiec_ekranu+$400+100 okno4 ins "popupsNOSTY.mapa" org pamiec_ekranu+$500+100 okno5 ins "popupsXXL.mapa" org pamiec_ekranu+$600+100 okno6 ins "popupsVASCO.mapa" org pamiec_ekranu+$700+100 okno7 ins "popupsZENON.mapa" org pamiec_ekranu+$800+100 okno8 ins "popupsYERZU.mapa" org pamiec_ekranu+$900+100 okno9 ins "popupsAS.mapa" org pamiec_ekranu+$A00+100 okno10 ins "popupsPAPIEZ.mapa" org pamiec_ekranu+$B00+100 okno11 ins "popupsGRZYBSONIADA.mapa" org pamiec_ekranu+$C00+100 okno12 ins "popupsSMOLENSK.mapa" org pamiec_ekranu+$D00+100 okno13 ins "popupsCYCKI.mapa" org pamiec_ekranu+$E00+100 okno14 ins "popupsVBXE.mapa" org pamiec_ekranu+$F00+100 okno15 ins "popupsIK.mapa" org pamiec_ekranu+$1000+100 okno16 ins "popupsPOWER.mapa" org pamiec_ekranu+$1100+100 okno17 ins "popupsEND.mapa" org pamiec_ekranu+$1200+100 okno18 ins "popupsLINE.mapa" org pamiec_ekranu+$1300+100 okno12a ins "popupsSMOLENSK2.mapa" org pamiec_ekranu+$1400+100 okno13a ins "popupsCYCKI2.mapa" org pamiec_ekranu+$1500+100 okno14a ins "popupsVBXE2.mapa" org pamiec_ekranu+$1600+100 okno18a ins "popupsLINE2.mapa" org pamiec_ekranu+$1700+100 okno_tlo ;do zamazywania tla pod oknem dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40 dta $40,$40,$40,$40,$40,$40,$40,$40,$40,$40