Search code examples
assemblyx86-16

I'm trying to make a game like flappy bird in x86 assembly in DOSBOX. I am stuck on a few issues


I am unable to figure out why my bird doesn't go down when i release my space bar key and why the last location isn't clearing. I also want the display (except my bird) to scroll sideways, so it gives the effect of bird going through the pillars.

[org 0x0100]
jmp start

value: dw 16
value2: dw 2896
pillar_color: db 0x26
space: db 0x20
bird_row: dw 1760
sky_color: db 0x13
bird_color: db 0x18
bird_char: db 'L'
c: dw 3


delay:
    push cx
    mov cx, 0x09
delay_loop1:
    push cx
    mov cx, 0xFFFF
delay_loop2:
    loop delay_loop2
    pop cx
    loop delay_loop1
    pop cx
    ret

my_isr:
    push ax

    in al, 0x60
    TEST al, al
    JZ released

    cmp al, 0x39
    JNE released

pressed:
    call move_up
    call delay ; Add a delay here if needed
    jmp sub_end

released:
    ; Check if the released key is the space key (ASCII code 32)
    mov ah, 0
    int 16h
    cmp al, 32
    jne sub_end

    ; Space key is released, move down
    call move_down

sub_end:
    mov al, 0x20
    out 0x20, al

    pop ax
    iret


print:
    push es
    push ax
    push cx
    push di

    mov ax, 0xb800
    mov es, ax
    xor di, di
    mov ax, 0x1320
    mov cx, 1520

    cld
    rep stosw

    mov di, 3200
    mov ax, 0x6820
    mov cx, 2000

    cld
    rep stosw

    mov dx, 9
    mov di, 0

    ; First Pillar
    mov dx, 9
    mov di, 0

    First_pillar:
        mov di, [value]
        mov cx, 8

    p1:
        mov ah, [pillar_color]
        mov al, [space]

        cld
        stosw

        add di, 158
        dec cx

        cmp cx, 0
        jnz p1

        mov ax, [value]
        add ax, 16
        mov [value], ax
        dec dx

        cmp dx, 0
        jnz First_pillar

    ; Second Pillar
    mov dx, 9
    mov di, 0

    Second_pillar:
        mov di, [value2]
        mov cx, 6

    p2:
        mov ah, [pillar_color]
        mov al, [space]

        cld
        stosw

        sub di, 162
        dec cx

        cmp cx, 0
        jnz p2

        mov ax, [value2]
        add ax, 16
        mov [value2], ax
        dec dx

        cmp dx, 0
        jnz Second_pillar

    pop di
    pop cx
    pop ax
    pop es
    ret

draw_bird:
    call clear_bird ; Clear previous position
    mov ax, 0xb800
    mov es, ax
    mov di, word [bird_row]

    ; Set the color attribute for the bird
    mov ah, [bird_color]

    ; Combine the character and color attribute
    shl ah, 8
    mov al, [bird_char]

    ; Store the character and color attribute in the video memory
    mov [es:di], ax

    ret

clear_bird:
    mov ax, 0xb800
    mov es, ax
    mov di, word [bird_row]

    ; Set the color attribute for the sky
    mov ah, [sky_color]

    ; Combine the character (space) and color attribute
    shl ah, 8
    mov ax, 0x20 ; Use a constant value for the space character

    ; Store the character and color attribute in the video memory using stosw
    stosw

    ret




move_up:
    call delay
    call clear_bird ; Clear previous position
    sub word [bird_row], 160
    call draw_bird ; Draw the bird in the new position
    ret

move_down:
    call delay
    call clear_bird ; Clear previous position
    add word [bird_row], 160 ; Move down by 2 bytes (1 word)
    call draw_bird ; Draw the bird in the new position
    ret


start:
    call print
    call draw_bird

key_check_loop:
    ; Check if the pressed key is the space key (ASCII code 32)
    mov ah, 0
    int 16h
    cmp al, 32
    je space_pressed

    ; Check for key release
    mov ah, 1
    int 16h
    cmp al, 32
    jne not_space_pressed

    ; Space key is released, move down
    call move_down
    jmp key_check_loop

not_space_pressed:
    jmp key_check_loop

space_pressed:
    ; Space key is pressed
    call move_up
    jmp key_check_loop


space_released:
    ; Space key is released
    call move_down
    jmp key_check_loop

end:
    mov ax, 0x4c00
    int 0x21

Solution

  • I am unable to figure out why my bird doesn't go down when i release my space bar key and why the last location isn't clearing.

    You seem to be mixing a couple of methods for working with the keyboard.

    • In key_check_loop you are using the traditional approach via the int 16h interface. Function 00h waits until a key is available. There's no direct evidence for a key to be released, but if the next invokation of the same function produces a different key, then there's a good chance that the key of interest (spacebar) has been released.

      ; Press spacebar to move up once
      ; Press any other key to move down once
      key_check_loop:
        mov  ah, 00h
        int  16h
        cmp  al, 32
        je   space_pressed
        call move_down
        jmp  key_check_loop
      space_pressed:
        call move_up
        jmp  key_check_loop
      
    • You don't show us how or even if you set it up, but the my_isr int 09h handler can indeed provide the key-release information that you want. What you should not do is drawing the bird from within this handler, nor should you be delaying here. And invoking int 16h from this handler can't work because the BIOS keystroke buffer doesn't receive new keystrokes while this handler is active.

      Study the example in Interrupt 09 handling in assembly x86 for how to find out about presses and releases using a new int 09h handler.
      More detailed info is in this other answer.


    mov di, 3200
    mov ax, 0x6820
    mov cx, 2000
    cld
    rep stosw
    

    The 80 x 25 text video mode uses a buffer of 4000 bytes in total. Starting from offset address 3200 there remain 800 bytes. It makes sense to store 400 words, but not the 2000 that you did.

    mov ah, [bird_color]
    ; Combine the character and color attribute
    shl ah, 8
    mov al, [bird_char]
    

    The shl ah, 8 destroys the color for the bird! Your intent is to combine AL and AH, so just write:

    mov ah, [bird_color]
    mov al, [bird_char]
    

    Now AX has the combined info. A similar error happens for the color of the sky.


    I also want the display (except my bird) to scroll sideways, so it gives the effect of bird going through the pillars.

    Keep this for later. It merits a different question once you get the other stuff right!