Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a pong game in assembly, how do I get an input of multiple keystrokes at once?

I'm a beginner so this code probably isn't any good, I used int 16h for this but I don't know a lot about this int. I just found out you can't have multiple keystrokes at once; any help?
The problem with this code is that only one board can move at a time and I need both. How do I check for multiple inputs?

Here's the code for anyone who wants it:

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
    line1X dw 80
  line1Y dw 120
  line1start dw 5
  line1end dw 10
  line2X dw 80
  line2Y dw 120
  line2start dw 310
  line2end dw 315
CODESEG
    proc startVideo ;creates video mode
      mov al,13h
      mov ah,0h
      int 10h
      ret
  endp startVideo
  proc clearScrean ;turns the screen black
      mov ah, 0ch
      xor al,al
      mov dx,200 
BlankLine:
      mov cx,320
BlankColumn:
        int 10h
        Loop BlankColumn
      dec dx
        cmp dx,0
        jne BlankLine     
      ret
  endp clearScrean
  
    proc drawboard ;creates the board
      push bp
      mov bp,sp
      mov al,0fh
      mov ah,0ch
      beginning equ [bp+10]
      fn equ [bp+8]
      X equ [bp+6] ;boards start
      Y equ [bp+4] ;boards end
      mov dx,Y
drawrow:
      mov cx,fn
drawcolumn:
        int 10h
      dec cx
        cmp cx,beginning
        jne drawcolumn
      dec dx
      cmp dx,X 
      jne drawrow
      pop bp
      ret 8
  endp drawboard
  proc drawall
      push [line1start]
      push [line1end]
      push [line1X]
      push [line1Y]
      call drawboard
      push [line2start]
      push [line2end]
      push [line2X]
      push [line2Y]
      call drawboard
      ret
  endp drawall
  proc boardup
      push bp
      mov bp,sp
      mov bx,[bp+4]
      mov si,[bp+6]
      cmp [word ptr bx],0 ;checks if board didnt get to border 
      je fn1
        call clearScrean
      sub [word ptr bx],5 ;3 pixels added to board
      sub [word ptr si],5
      call drawall ;prints both boards
fn1:
      pop bp
      ret 4
  endp boardup
  proc boarddown
      push bp
      mov bp,sp
      mov bx,[bp+4]
      mov si,[bp+6]
      cmp [word ptr si],200 ;checks if board didnt get to border 
      je fn2
        call clearScrean
      add [word ptr bx],5 ;3 pixels added to board
      add [word ptr si],5
      call drawall ;prints both boards
fn2:
      pop bp
      ret 4
  endp boarddown
start:
  mov ax, @data
  mov ds, ax
    mov bh,0
  call startVideo
  call clearScrean
  call drawall
checkskey: ;checks if key is being pressed
  mov ah,1
  int 16h
  jz checkskey ;jumps if key isnt pressed
  mov ah,0 ;checks which key is pressed
  int 16h
  cmp ah,11h ;if key pressed is w jump to upboard
  je upboard1
  cmp ah,01fh ;if key pressed is s jump to downboard
  je downboard1
  cmp ah,050h
  je downboard2
  cmp ah,048h
  je upboard2
  jmp checkskey ;if key isnt pressed jump to check key
upboard1: ;board 1 goes up
    push offset line1Y
  push offset line1X
  call boardup
  jmp checkskey
downboard1: ;board 1 goes down
    push offset line1Y
  push offset line1X
  call boarddown
  jmp checkskey
downboard2:
    push offset line2Y
  push offset line2X
  call boarddown
  jmp checkskey
upboard2:
    push offset line2Y
  push offset line2X
  call boardup
  jmp checkskey
exit:
  mov ax, 4c00h
  int 21h
END start
like image 295
orraz1 Avatar asked Oct 27 '25 05:10

orraz1


1 Answers

the problem with this code is that only one board can move at a time and i need both

The sense of simultaneousness comes from being fast, real fast. Most everything in your computer works serially but we percieve many things as happening in parallel.

Your checkskey code is fine. One board uses the q and s keys, and the other board uses the up and down keys.
As soon as a key is available, the Keyboard BIOS function 00h will retrieve it immediately and your program will update the graphics accordingly. But if your graphical output routines take too long, then the players will start thinking that the keyboard is sluggish.

Looking at your graphics routines, I see that you use the Video BIOS function 0Ch to put pixels on the screen. This is slow and especially painful since you're playing on the easiest of graphics screen where you can just MOV a byte to draw a pixel.

In a program that needs fast graphics it can be very advantageous to have the ES segment register point at the video buffer permanently.

  mov  ax, 0A000h
  mov  es, ax
  cld             ; Because of the use of STOSB

This is all it takes to clear the screen:

ClearScreen:
  xor  di, di
  mov  cx, 64000
  mov  al, 0
  rep stosb
  ret

This is how you draw the horizontal line (160,100)-(200,100):

  mov  dl, 15    ; BrightWhite
  mov  cx, 51    ; 51 pixels from 160 to 200
  mov  bx, 160   ; X
  mov  ax, 100   ; Y
  call DrawLine

  ...

DrawLine:
  push dx
  mov  di, 320   ; BytesPerScanline
  mul  di
  add  ax, bx
  mov  di, ax    ; Address DI = (Y * BPS) + X
  pop  ax        ; Color AL
  rep stosb
  ret
like image 58
Sep Roland Avatar answered Oct 29 '25 03:10

Sep Roland