Odbijająca się piłka

0

Witam,
Mam narysowaną piłkę w asemblerze i chcę aby się odbijała.
Ustawiam w zmiennej wartość w którym kierunku ma się poruszać, i w pętli sprawdzam wartość zmiennej i chcę wykonać skok do danej procedury. Wygląda to mniej więcej tak:

 
	; 1 kieruek w lewo
        mov al,1
	mov [direction],al
	                                 
moveball:	
        ; tak nie wykonuje skoku                          
	mov bx,[direction]
	cmp bx,1
	je inLeft
	
        ; tak działa
	;call inLeft
	
	loop moveball

I przy sprawdzaniu wartości zmiennej powinno wykonać skok do funkcji ale go nie wykonuje co jest nie tak?

0

Zgaduje że twoje porównanie jest błędne. Domyślam sie nawet dlaczego. Najpierw do [direction] wrzucasz zawartość al więc zgaduje że direction to jest db czyli 1 bajt. A potem wczytujesz z [direction] do bx czyli czytasz 2 bajty! Więc jak to wreszcie jest? Albo w jednym albo w drugim miejscu jest błąd.

Na przyszłość: emu8086 do debugowania...

0

Ale nawet jak dam tak:

 moveball:	                          
	mov bl,1
	cmp bl,1
	je inRight
	
	loop moveball

To mi nie działa a tu chyba porównanie jest dobre?

0

Nie wierzę. Ale nie ważne. Odpal to pod emu8086 i zobacz jak się ustawiają flagi po tym cmp i potem zobacz czy faktycznie ci nie skacze.

0

Jak dam skok do innej procedury to mi skacze, a do tej procedury inRight mi nie skacze

0

To pokaż więcej kodu. Co to jest ten inRight? Zwykła etykieta w kodzie? Jak daleko jest (bo skoki mają ograniczoną odległość...)?

0
moveball:	                          
	mov al,1
	cmp al,1
	;je inLeft
	
	call inRight
	loop moveball
		
inLeft:	
	mov ax,[centerX]
	sub ax,10
	mov [centerX],ax
		
	mov ah, 0
	mov al, 13h
	int 10h
	
	call draw_ball
	ret

inRight:
	mov ax,[centerX]
	add ax,10
	mov [centerX],ax
		
	mov ah, 0
	mov al, 13h
	int 10h
	
	call draw_ball
	ret	
	
draw_ball:	
okrag:	
	push cx		; zachowanie licznika pętli w CX 
	;zmiana kąta
	fld qword [angle]
	fadd qword [angleDelta]
	fst qword [angle]
	
	; obliczenie współrzędnych odpowiedniego punktu
	fsincos
	fimul word [radius]
	fiadd word [centerX]
	fistp word [pointX]
	
	fimul word [radius]
	fiadd word [centerY]
	fistp word [pointY]	
	
	; wyświetlenie punktu	
	mov ah, 0Ch
	mov al, 2	; kolor
	mov bh, 0	; strona wideo
	mov cx, [pointX]
	mov dx, [pointY]
	int 10h
	
	pop cx
	loop okrag
	ret
 
0

Tragedia! Jak robisz skoki za pomocą jmp to NIE wolno ci robić ret na końcu bo psujesz sobie stos. Jak chcesz robić ret to wołaj ZAWSZE przez call.
ret zdejmuje ze stosu adres powrotny ale jeśli skakałeś a nie robileś call na na stosie wcale tego adresu nie ma więc zdejmujesz losową wartość i potem tam skaczesz. To ci w ogóle działa?

0

jak w moveball dam

 call inRight 

to działa

0

No to teraz doczytaj sobie czym się różni call of skoków i czemu NIE WOLNO tego tak mieszać jak to własnie próbowałeś zrobić.

0

to jak mam to zrobić?
Albo jak mam sprawdzić warunek i wykonać skok przez call?

1

Za pomocą etykietek oczywiście ;] Musisz zmontować takiego asemblerowego ifa

cmp cośtam,cośtam
jne brak_calla
call cośtam
brak_calla:
0

Dobra działa, a jak zrobić opóźnienie a raczej w tym wypadku przyśpieszenie bo w tej chwili zmieniam pozycje o 10 pixeli ale piłka porusza się dość wolno i nie płynnie czym to jest spowodowane bo przecież pętle powinny się wykonywać bardzo szybko?

0

A pod co to piszesz? Bo dużo szybciej byłoby zapalać punkty pisząc po pamięci a nie wołając przerwania.

edit: Jak sobie włączysz tryb graficzny

	mov	al,13h  ;320x200 punktow 256 kolorow
	mov	ah,0
	int	10h

To mozesz malować tak:

zapal_punkt:
	mov	ax,0a000h  ; pamięć obrazu
	mov	es,ax
	mov	ax,word ptr [y]
	mov	bx,320
	mul	bx	;dx:ax = ax * bx
	add	ax,word ptr [x]   ;ax = 320*y +x
	mov	bx,ax
	mov	al,byte ptr [kolor]
	mov	byte ptr es:[bx],al

i namalujesz punkt w (x,y) o kolorze kolor.

0

Pisze pod emulator Dosa

0

No to pod dosboxem spokojnie możesz sobie malować pisząc po pamięci.

0

Dałem ten kod co napisałeś i wywala takie błedy w tych linijkach co jest "ptr":

 comma colon decorator or end of line expected after operand
0

Nie napisałeś jaki to asembler... Wyrzuć te word ptr / byte ptr i tyle (tylko te słowa kluczowe! nie całe linijki)

0

No wywaliłem ale w ostatniej linii dalej jest błąd

 mov es:[bx],al 

invalid combination of opcode and operands

0

To napiszesz łaskawie JAKI to asembler? Czy liczysz na to ze napisze ci kod pod wszystkie możliwe? Jeśli to NASM to zamiast byte ptr daj byte

0

Tak to NASM, dałem tak

  mov    byte es:[bx],al 

i dalej ten sam błąd

0

A jak dasz

 mov    byte [es:bx],al 

?

0

Tak działa.

A da się bardziej przyśpieszyć bo dalej troch za wolno się porusza piłka?
Bo teraz w pętli wykonuje ten kod i zapalam po jednym pixelu.

0

Ja bym w takim razie sprawdził co w tym kodzie się tak długo wykonuje pod jakimś debugerem / profilerem. Przypuszczam że to nie rysowanie jest problemem tylko jakieś inne operacje które wykonujesz.

0

Wydaje mi się ze rysowanie okręgu, czyli wyliczanie współrzędnych punktów na podstawie środka okręgu czyli jakieś 150 punktów. A jak modę to sprawdzić w turbo debugerze?

0

Pogooglaj za jakimś profilerem. Ja zgaduje że to wyliczanie współrzednych każdego punktu od początku może stanowić problem. Nie da się prościej - tak wektorowo? Liczysz współrzędne raz a potem przesuwasz sobie każdy piksel o 1 w lewo / prawo zamiast obliczać wszystko znowu od zera. Nie da rady tak?

Trochę tak jak @cepa zrobił tutaj: http://lukasz.cepowski.com/projects/snake chociaż on sobie to juz całkiem ułatwił bo "namalował" sobie cały segment i potem tylko wrzuca go na ekran.

1 użytkowników online, w tym zalogowanych: 0, gości: 1