Search code examples
assemblydosx86-16tasm

How do I make two codes to run at the same time? (DOS Assembly)


I made 2 squares (I am using assembly DOS) and I am trying to make one square to move and the other square will jump when the user presses SPACE. The problem is that the user can only press SPACE after the other square stops moving. Can you help me please?

CODE:

IDEAL
MODEL small
STACK 100h
DATASEG

X dw ?
Y dw ?
SquareSize dw ?

PlayerSquareX dw 20
PlayerSquareY dw 193

BlockX dw 305
BlockY dw 193

color db 1  ; default color is blue

FloorY dw 194
FloorX dw 0




CODESEG



    proc HalfSecondDelay
    push cx ;Backup
    push dx
    push ax
    
    MOV CX, 1H
    MOV DX, 3H
    MOV AH, 86H
    INT 15H
    
    pop ax ;Backup
    pop dx
    pop cx
    ret
    endp HalfSecondDelay

    
    proc WaitForSpace
    EnterSpace:  ;Wait until user presses Space
    mov ah,0
    int 16h
    cmp al,32
    ;jne EnterSpace
    jne ReturnToMain
    call PlayerJump
    ReturnToMain:
    ret
    endp WaitForSpace
    
    proc ClearKeyboardBuffer
    push ax
    ClearKeyboardBuffer_loop:
    mov ah,01h
    int 16h                     ; is there a key pressed
    jz ClearKeyboardBuffer_ret  ; if not, return
    mov ah,00h
    int 16h                     ; "handle" the key
    jmp ClearKeyboardBuffer_loop

    ClearKeyboardBuffer_ret:
    pop ax
    ret
endp ClearKeyboardBuffer


    proc PlayerJump ;Makes The Square Jump
    push cx
    
    
    mov cx, 10
    MoveUp:
    Call HalfSecondDelay
    
    call RemovePlayerSquare
    sub [PlayerSquareY],4 ; Move Up
    call PaintPlayerSquare
    loop MoveUp
    
    mov cx, 10
    MoveDown:
    Call HalfSecondDelay
    call RemovePlayerSquare
    add [PlayerSquareY], 4 ; Move Down
    Call PaintPlayerSquare
    loop MoveDown

    pop cx
    ret
    endp PlayerJump


proc PaintFloorLine
    push bp
    mov bp,sp
    push cx


    
    mov cx, 320
LoopPaintFloorLine:
    call PaintPixel
    
    inc [X]
    loop loopPaintFloorLine
    

    pop cx
    pop bp
    ret
endp PaintFloorLine

proc PaintFloor ;Paints The Floor
    push bp
    mov bp,sp
    push cx
    
    mov [x], 0
    mov [y], 194
    mov [color], 0Ah
    
    mov cx, 7
    
loopPaintFloor:     
    call PaintFloorLine
    inc [Y]
    mov [x], 0
    loop loopPaintFloor
    
    
    pop cx
    pop bp
    ret
endp PaintFloor
    

proc PaintPixel
    push bp
    mov bp,sp

    push ax
    push bx
    push cx
    push dx 
    

    mov cx,[X]
    mov dx,[Y]
    mov al,[color]
    mov ah,0ch
    int 10h
    
    pop dx
    pop cx
    pop bx
    pop ax
    pop bp
    ret
endp PaintPixel

proc PaintLine
    push bp
    mov bp,sp
    push cx
    
    mov cx, [SquareSize]
    
loopPaintLine:  
    call PaintPixel
    inc [X]
    loop loopPaintLine
    
    mov cx, [SquareSize] ; Return The X
    sub [X], cx
    
    pop cx
    pop bp
    ret
endp PaintLine

    
proc PaintSquare ;Paints A Sqaure
    push bp
    mov bp,sp
    push cx
    
    mov cx, [SquareSize]
    
loopPrinSquare:     
    call PaintLine
    dec [Y]
    loop loopPrinSquare
    
    mov cx, [SquareSize] ; Return The Y
    add [Y], cx
    
    pop cx
    pop bp
    ret
endp PaintSquare

proc PaintPlayerSquare ; Paints The Player Square
    push bp
    mov bp,sp
    
    mov ax, [PlayerSquareX]
    mov [x], ax
    
    mov ax, [PlayerSquareY]
    mov [Y], ax
    
    mov [SquareSize], 25
    mov  [color], 1 ; blue color
    call PaintSquare ;  
    
    pop bp
    ret 
endp PaintPlayerSquare

proc RemovePlayerSquare ;Removes The Player Square
    push bp
    mov bp,sp
    
    push ax
    push bx
    push cx
    push dx 
    
    mov ax, [PlayerSquareX]
    mov [x], ax
    
    mov ax, [PlayerSquareY]
    mov [Y], ax
    
    mov [SquareSize], 25
    mov  [color], 0 ; black color
    call PaintSquare ;  
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    pop bp
    ret 
endp RemovePlayerSquare


proc PaintBlockSquare ; Paints The Block Square
    push bp
    mov bp,sp
    
    
    mov ax, [BlockX]
    mov [x], ax
    
    mov ax, [BlockY]
    mov [Y], ax
    
    mov [SquareSize], 15
    mov  [color], 4 ; red color
    call PaintSquare ;  
    
    pop bp
    ret 
endp PaintBlockSquare

proc RemoveBlockSquare ;Removes The block Square
    push bp
    mov bp,sp
    
    push ax
    push bx
    push cx
    push dx 
    
    
    mov ax, [BlockX]
    mov [x], ax
    
    mov ax, [BlockY]
    mov [Y], ax
    
    mov [SquareSize], 15
    mov  [color], 0 ; black color
    call PaintSquare ;  
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    pop bp
    ret 
endp RemoveBlockSquare

proc MoveBlockLeft ;Makes The Square Jump
    push cx
    
    
    mov cx, 77
    loopMoveBlockLeft:
    Call HalfSecondDelay
    
    call RemoveBlockSquare
    sub [BlockX], 4 ; Move Up
    call PaintBlockSquare
    loop loopMoveBlockLeft
    


    pop cx
    ret
endp MoveBlockLeft



proc GraphicsScreen
    mov al, 13h
    mov ah, 0
    int 10h
    ret
endp GraphicsScreen

proc ResetBlockLocation
    mov [BlockX], 305
    mov [BlockY], 193
    ret
endp ResetBlockLocation

    
start:
    mov ax, @data
    mov ds, ax
    
    Call GraphicsScreen
    Call PaintFloor
    Call PaintPlayerSquare
    
    
    call PaintBlockSquare
    call MoveBlockLeft
    call RemoveBlockSquare
    call ResetBlockLocation
    call ClearKeyboardBuffer
    call WaitForSpace
    

    

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

Solution

  • One way to go is to implement a game loop, or a similar concept - event loop.

    The idea is to split your animation in a series of frames, and update only 1 frame at a time. Let's say you want to do 30 FPS, and the speed of your movement is 90px per second. It means that you need to move the object about 3px in 1 frame, and then pause for 0.033 seconds (33 ms).

    After each frame you check for input and process actions.

    The way it runs is that you start the first animation, remember your animation state, update to the next frame, then check for input, update to the next frame, then check for input again, maybe start a second animation (now you handle 2 animation states at a time), update both to the next frame, check for input again etc.