Search code examples
assemblyx86masmirvine32

Move char left or right in Assembly


I working on a simple game in assembly and for the moment I'm just trying to move the player icon (in this case it is a char X) left or right depending on whether the number 1 or 2 is hit on the keyboard. Currently I just have two if thens to move my X left or right by either decrementing or incrementing the X coordinate value. I'm using the Irvine 32 library for procs like Gotoxy to get the coordinate values. As of now my program displays the x in the right starting position but for some reason when I hit 1 or 2 the x moves up one space instead of left or right. I can't figure it out in the book I have and the things I find on the internet are not in my range of knowledge of assembly. As it stands I just want to move my char left or right. Later I will make the appropriate procs and such but for now it's a very weird problem. Any help would be appreciated. Below is my assembly code:

        TITLE Matrix Rain

; Description:Dodge falling numbers to reach the final level
; Authors: John , Killian
; Revision date:2/11/2015

INCLUDE Irvine32.inc
.data
player byte 'X'; Player Character
direction byte ?; Direction the player moves
startY byte 24; Starting Y position
startX byte 39; Starting X position

breakLoop byte 9 ; base case to break

right byte 2; moves player right
left byte 1; moves player left
.code

main PROC
    ;Player Starting Point
    mov dh , startY; column 24
    mov dl,startX ; row 39
    call Gotoxy; places cursor in the middle of the bottom part of the console window
    mov al, player; Copies player character to the AL register to be printed
    call WriteChar; Prints player to screen console
    call Crlf
    ;Player Starting point
    XOR al,al; Zeroes al out
    call ReadKey;Reads keyboard 
    mov eax, 3000
    call delay

    _if1: cmp al , left
         je THEN1
         jmp ENDIF1
         THEN1:

            inc startX
            mov dl, startX
            call Gotoxy
            call Clrscr

            mov al, player
            call WriteChar
            XOR al,al
    ENDIF1:

    _if2: cmp al , right
         je THEN2
         jmp ENDIF2
         THEN2:

            dec startX
            mov dl,startX
            call Gotoxy
            call Clrscr

            mov al, player
            call WriteChar
            XOR al,al
    ENDIF2:
        exit
        main ENDP

        END main

Solution

  • There are some issues with your code:

    1) Numbers are not characters

    right byte 2; moves player right
    left byte 1; moves player left
    

    right and left hold now the pure numbers 1 and 2. However, ReadKey returns in AL the ASCII code of the pressed key. You can look in a reference for the code for the keys 1 and 2 or you can write:

    right byte '2'; moves player right
    left byte '1'; moves player left
    

    2) Registers are not suitable to hold values permanently

    Although you initialize DH it will be changed when you reach the call Gotoxy. Insert a mov dh, startY just before calling Gotoxy:

    inc startX
    mov dl, startX
    mov dh, startY
    call Gotoxy
    

    Next issue:

    call ReadKey                ; Reads keyboard
    mov eax, 3000
    call delay
    

    ReadKey returns the ASCII code of the pressed key in AL, but mov eax, 3000 will destroy this result (AL is a part of EAX). RTFM and change the block to:

    LookForKey:
    mov  eax,50          ; sleep, to allow OS to time slice
    call Delay           ; (otherwise, some key presses are lost)
    call ReadKey         ; look for keyboard input
    jz   LookForKey      ; no key pressed yet
    

    3) Clrscr changes the current cursor position

    A call to Clrscr destroys the effect of Gotoxy. Remove the calls to that function after Gotoxy, better remove all calls in the development phase.


    I suggest to implement the loop right now:

    cmp al, '3'
    jne LookForKey
    
    exit
    

    This will exit the program when '3' is pressed and repeat the loop otherwise.