Home > database >  Assembly Pong - deleting the ball in a more efficient way
Assembly Pong - deleting the ball in a more efficient way

Time:02-17

I am making a Pong game in assembly and for the ball mechanic I am drawing a blank ball in the place where the last ball location was but when I added it to my game loop the ball started flashing and it looks buggy, Here is the code I use for the ball, any way to make the deleting process better so it won’t flash (including different methods from the one I am using)?

IDEAL
MODEL small
jumps
STACK 100h
p186
DATASEG
;-------------------------
temp_x dw 0
temp_y dw 0
color dw 4
lengthOfDrawings dw 9
pic_off dw 0
x_ball dw 150
y_ball dw 50
h_ball dw 9
w_ball dw 9
ballSpeed dw 03AFFh
y_direction_ball dw 'd'
x_direction_ball dw 'r'
temp_var dw 0
ball db 00h, 00h, 08h, 08h, 08h, 08h, 08h, 00h, 00h
     db 00h, 08h, 08h, 07h, 07h, 07h, 08h, 08h, 00h
     db 08h, 08h, 07h, 07h, 07h, 07h, 07h, 08h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 08h, 07h, 07h, 07h, 07h, 07h, 08h, 08h
     db 00h, 08h, 08h, 07h, 07h, 07h, 08h, 08h, 00h
     db 00h, 00h, 08h, 08h, 08h, 08h, 08h, 00h, 00h
     
;----------------------
CODESEG

proc draw_pixel
    pusha
    xor bh, bh
    mov cx, [temp_x]
    mov dx, [temp_y]
    mov ax, [color]
    mov ah, 0ch
    int 10h
    popa
    ret
endp draw_pixel

proc draw_line_ball
    pusha
    mov cx, [lengthOfDrawings]
    mov ax, [x_ball]
    mov [temp_x], ax
drawpr:
    call draw_pixel
    inc [temp_x]
    loop drawpr
    popa
    ret
endp draw_line_ball

proc draw_ball
    pusha
    mov cx, [x_ball]
    mov dx,[y_ball]
    mov ax, 0ch
    int 10H ; AL = COLOR
    cmp al, 4
    je endDrawBall
    cmp al, 9
    je endDrawBall
    ; DI  שמירה כתובת התחלתית של מערך דמות 
    mov di,[pic_off]
    mov dx, [y_ball]
    
print_line:
    mov cx, [x_ball] ; x pos
    mov si, [w_ball] ; ball width

print_columns: 
    mov al, [di] copy color to AL
    inc di  ; next item in array
    
    ; painting a pixel
    ;  cx = x coordinate , dx = y coordinate, al- color
    mov bh,0
    mov ah,0ch
    int 10h 
    
    inc cx ; inc x
    dec si ; decrease col counter
    cmp si, 0
    jne print_columns
    
    inc dx ;inc Y
    dec [h_ball] ; decreasing row counter
    cmp [h_ball], 0
    jne print_line
endDrawBall:
    popa
    ret
endp draw_ball

proc draw_blank_ball
    pusha
    mov cx, 9
    mov ax, [y_ball]
    mov [temp_y], ax
    mov [color], 0
rectanl:
    call draw_line_ball
    inc [temp_y]
    loop rectanl
    mov [color], 4
    popa
    ret
endp draw_blank_ball

proc delay
    pusha
    mov cx, 00h ;Higher part of the number
    mov dx, [ballSpeed] ;Lower part of the number
    mov al, 0
    mov ah, 86h
    int 15h
    popa
    ret
endp delay

start:

mov ax, @data
mov ds, ax

;---------------------------
    ;Changing to graphic mode
    mov ax, 13h
    int 10h
    
gameLoop:
    add [x_ball], 2h
    inc [y_ball]
    mov [pic_off], offset ball
    mov [h_ball], 9
    mov [w_ball], 9
    call draw_ball
    call delay
    call draw_blank_ball
    jmp gameLoop

    
endGame:
    ;Returns to text mode
    mov ax, 2h
    int 10h
;---------------------------


exit:
mov ax, 4c00h
int 21h
END start

CodePudding user response:

pusha is going to be a pretty expensive operation. Only pushing/popping the registers you modify might be a savings.

That said, how about something like this? It gets rid of the call to draw_pixel (thus a pusha/popa), plus the constant repopulating of the registers.

proc draw_line_ball
    pusha
    mov si, [lengthOfDrawings]

    xor bh, bh
    mov cx, [x_ball]
    mov dx, [temp_y]
    mov ax, [color]
    mov ah, 0ch

drawpr:

    int 10h

    inc cx
    dec si
    jnz drawpr

    popa
    ret
endp draw_line_ball

(Obviously) I have not tried this, but there may be some useful ideas there.

  • Related