Search code examples
assemblyinterruptx86-16

Cant get color of pixel where i clicked at assembly 8086


im trying to get my program to give me the color of the pixel i clicked on.

From what i understood i use the ah=0dh and int 10h to get the color of the current pixel based on the CX and DX values which represent what X and Y. I divided the CX by 2 to get the accurate position. Yet each time i get the value its always wrong.

Can anybody please help me? thanks

proc playerTurn
       mov ax, 0h ;Reset mouse
       int 33h
       
       mov ax, 1h ;Display mouse to user
       int 33h
       
click:
       mov ax, 3h ;Result to be displayed in BX, is LSB=1 Left click, if left to LSB=1 Rightclick
       int 33h    ;If both = 0, no click at all
                  ;CX holds column coordinate, 0-629, must divide by 2 because graphic is 320
                  ;DX holds row coordinate 0-199
      
      cmp bx, 0
      je click
      
      shr cx, 1 ; divide cx by 2
      mov bh, 0 ; page number = 0
      
          
      mov ah, 0Dh ; get color from current CX DX and store value in AL
      int 10h 
      
      cmp randomNum, 49
      je checkBlue
      cmp randomNum, 50
      je checkGreen
      cmp randomNum, 51
      je checkRed
      cmp randomNum, 52
      je checkYellow
      jmp wrong
      
      
checkBlue:
  cmp al, 69h
  jne wrong
  call pressBlue
  jmp endTurn
checkGreen:
  cmp al, 79h
  jne wrong
  call pressGreen
  jmp endTurn
checkRed:
  cmp al, 70h
  jne wrong
  call pressRed
  jmp endTurn
checkYellow:
  cmp al, 74h
  jne wrong
  call pressYellow
  jmp endTurn

wrong:
          mov dx, offset wrongColor
          mov ah, 09h
          int 21h
endTurn:
      ret


playerTurn endp

Solution

  • While waiting for the user to either left- or right click, you should not just compare BX to zero! The bits that do not correspond to a mouse button (left=1, right=2, middle=4) are 'undefined'. This means that a mouse handler can store additional info (or even garbage) in those bits if it wanted so. The way to check for a left- or right click is:

    test bx, 3
    jz   click    ; Neither left, nor right click
    

    Your understanding about the BIOS.ReadGraphicsPixel function 0Dh is correct. From the included tail comments, I deduce that you are working on the 320x200 256-color graphics screen. Halving the value that was returned in the CX register therefore is good. AL will contain a color value in the range [0,255].

    It is possible that none of your color tests run because of that special block that you can't pass if a certain randomNum is not in the very limited range [49,52]. Only you know what purpose it serves. My guess is that your program does not pass at that point.

    The color tests are using these unusual values {69h=Blue, 79h=Green, 70h=Red, 74h=Yellow} that represent pastelcolors. Are you sure those same color codes were used to draw the screen; the 'usual' values being {01h=Blue, 02h=Green, 04h=Red, 0Eh=Yellow}?

    You should try next code and find out if my guess about the randomNum block was right:

    proc playerTurn
    
        mov  ax, 0000h  ; ResetMouse
        int  33h        ; -> AX BX
        mov  ax, 0001h  ; ShowMouse
        int  33h
    click:
        mov  ax, 0003h  ; GetMousePosition
        int  33h        ; -> BX CX DX     
        test bx, 3
        jz   click      ; Neither left, nor right click
    
        shr  cx, 1
        mov  bh, 0      ; page number = 0
        mov  ah, 0Dh
        int  10h        ; -> AL
          
        mov  di, OFFSET pressBlue
        cmp  al, 69h
        je   OK
        mov  di, OFFSET pressGreen
        cmp  al, 79h
        je   OK
        mov  di, OFFSET pressRed
        cmp  al, 70h
        je   OK
        mov  di, OFFSET pressYellow
        cmp  al, 74h
        je   OK
    NOK:mov  dx, OFFSET wrongColor
        mov  ah, 09h
        int  21h
        ret
    OK: jmp  di         ; `call di` `ret`
    
    playerTurn endp