org 0x7c00
jmp _main
; _data:
playerPosition dw 0
; %1 == coluna (x)
; %2 == linha (y)
%macro drawRacket 2
mov ah, 0ch ; print pixels mode
mov dx, %2
for1:
mov bx, 32 ;racket height
add bx, %2
cmp dx, bx ; racket end (row)
je .fim1
mov cx, %1 ; racket beggining (column)
jmp .for2
jmp for1
.fim1:
jmp mainLoop
; loop to draw each line
.for2:
mov bx, 8 ;racket width
add bx, %1
cmp cx, bx ;
je .fim2
mov al, 0x0f
mov ah, 0ch
int 10h
inc cx
jmp .for2
.fim2:
inc dx
jmp for1
%endmacro
_main:
;
xor ax, ax
mov ds, ax
mov cx, ax
mov dx, ax
call setVideoMode
;racket initial position
mov word[playerPosition], 10
mainLoop:
mov ah, 01h
int 16h
cmp al, 115
je moveDown
jmp mainLoop
jmp $
;
setVideoMode:
mov ah, 0 ;
mov al, 13h ;
int 10h
ret
moveDown:
drawRacket 10, word[playerPosition]
mov ax, word[playerPosition]
inc ax
mov word[playerPosition], ax
jmp mainLoop
times 510-($-$$) db 0
dw 0xaa55
That's the assembly code. I am trying to make a "Pong game", and I am at the very beggining. I was trying to draw the 1st player's racket, but it is not working. When I press "s" (mainLoop function) on the keyboard, it actually works and jumps to the macro drawRacket and draws it. But, if I press "s" again nothing works.. I already tried to change a lot of things on the mainLoop function but nothing works, what makes me think that I have some problems with the macro drawRacket. I would appreciate any hints or answers.
CodePudding user response:
But, if I press "s" again nothing works..
Regardless of the keyboard issue about using function 01h instead of function 00h, your macro does get its second invokation and draws the racket a second time, but it does so exactly where the first racket was drawn. You don't see anything moved, that way! (For the sensation of true movement you would have to remove the first racket (partially) before drawing the second racket (partially)).
The reason is that the macro's execution stops with a jmp mainLoop
. This bypasses your code that increments the playerPosition variable. The quick solution is to place the .fim1 label near the bottom of the macro.
%macro drawRacket 2
mov ah, 0Ch
mov dx, %2
...
.fim2:
inc dx
jmp .for1
.fim1: ; New position!
%endmacro
Now the macro code will fall through in the code that increments Y. This happens because of how macro's work. In your program the line drawRacket 10, word[playerPosition]
gets replaced by all the code you have between the tags %macro drawRacket 2
and %endmacro
. This process is called macro expansion.
The expanded version looks like this:
moveDown:
mov ah, 0Ch ; \
mov dx, [playerPosition] ; \
; \
... ; \
; The expanded macro code
drawRacket.fim2: ; /
inc dx ; /
jmp drawRacket.for1 ; /
drawRacket.fim1: ; /
mov ax, [playerPosition]
inc ax
mov [playerPosition], ax
jmp mainLoop
The keyboard function 01h checks to see if a key is available and reports about the fact. You receive a preview of the key in AX
, and the key is not removed from the keybuffer. Next time your code uses this keyboard function 01h, you still get the preview of that same key, even if you pushed another key on the keyboard.
Your program just needs to wait for a key and act upon it. Use the keyboard function 00h that does exactly that.
mov ah, 00h ; BIOS.GetKeyboardKey
int 16h ; -> AL is ASCII, AH is scancode