Programming game in assembly language I need help programming a game in assembly
ID: 3772595 • Letter: P
Question
Programming game in assembly language
I need help programming a game in assembly language. I have most of the program ready to go, just need help with where to start on the code.
B - is a block, your character can not go through them
G - is gold, your character can pick them up for points
* - is the wall, your character can not go through the walls.
Your program should, at a minimum, do the following:
Stop your character from going out of bounds - don’t let them go past an asterisks (*)
Stop the character from going through a block (B)
When the character goes over a G, give them points
Display the player's score and keep it updated
Add an exit to the map - place an E that terminates the program when they go over it
%include "asm_io.inc"
%include "io.inc"
; initialized data is put in the .data segment
segment .data
clear db 27,"[2J",27,"[1;1H",0
cc db 27,"c",0
scanFormat db "%c",0
file db "input.txt",0
mode db "r",0
formatA db "%c",0
x dd 3
y dd 3
prevX dd 0
prevY dd 0
rows dd 8
cols dd 27
; uninitialized data is put in the .bss segment
segment .bss
text resb 2000
; code is put in the .text segment
segment .text
global asm_main
extern fscanf
extern fopen
extern fclose
extern scanf
extern getchar
extern putchar
asm_main:
enter 0,0 ; setup routine
pusha
;***************CODE STARTS HERE*******
mov eax, clear ;two lines to clear
call print_string ;clear the screen
mov eax, cc
call load ;load the file into text
call update ;update the file with the location
mov eax, text
call print_string
mov ecx, 20
top:
call movement
call update
mov eax, clear ;two lines to clear
call print_string ;clear the screen
mov eax, text
call print_string
loop top
;***************CODE ENDS HERE*********
popa
mov eax, 0 ; return back to C
leave
ret
;*********************************
;* Function to load var text with*
;* input from input.txt *
;*********************************
load:
push eax
push esi
sub esp, 20h
;get the file pointer
mov dword [esp+4], mode; the mode for the file which is "r"
mov dword [esp], file; the name of the file. Hard coded here (input.txt)
call fopen ; call fopen to open the file
;read stuff
mov [esp], eax; mov the file pointer to param 1
mov eax, esp ;use stack to store a pointer where char goes
add eax, 1Ch ;address is 1C up from the bottom of the stack
mov [esp+8], eax;pointer is param 3
mov dword [esp+4], scanFormat; fromat is param 2
mov edx, 0
mov [prevX], edx
mov [prevY], edx
scan: call fscanf; call scanf
cmp eax, 0 ; eax will be less than 1 when EOF
jl done; eof means quit
mov eax, [esp+1Ch]; mov the result (on the stack) to eax
cmp al, 'M'
jz Mario
mov edx, [prevX]; increment prevX
inc edx
mov [prevX], edx
cmp al, 10
jz NewLine
jmp save
NewLine:
mov dword [prevX], 0
mov edx, [prevY]
inc edx
mov [prevY], edx
jmp save
Mario:
mov edx, [prevX]
mov [x], edx
mov edx, [prevY]
mov [y], edx
jmp save
save:
mov [text + esi], al; store in the array
inc esi; add one to esi (index in the array)
cmp esi, 2000; dont go tooo far into the array
jz done; quit if went too far
jmp scan ;loop back
done:
call fclose; close the file pointer
mov byte [text+esi],0 ;set the last char to null
add esp, 20h; unallocate stack space
pop esi ;restore registers
pop eax
ret
;*********************************
;* Function to update the screen *
;* *
;*********************************
update:
push eax
push ebx
;update the new loc
mov eax, [x]
mov ebx, [y]
mov edx, 0
imul ebx, [cols]
add eax, ebx
mov byte [text + eax], 'M'
;update the old loc
mov eax, [prevX]
mov ebx, [prevY]
mov edx, 0
imul ebx, [cols]
add eax, ebx
mov byte [text + eax], ' '
pop ebx
pop eax
ret
;*********************************
;* Function to get mouse movement*
;* *
;*********************************
movement:
pushad
mov ebx, [x]
mov [prevX], ebx;save old value of x in prevX
mov ebx, [y]
mov [prevY], ebx; save old value of y in prevY
call canonical_off
call echo_off
mov eax, formatA
push eax
;http://stackoverflow.com/questions/15306463/getchar-returns-the-same-value-27-for-up-and-down-arrow-keys
call getchar
call getchar
call getchar
call canonical_on
call echo_on
cmp eax, 43h; right
jz right
cmp eax, 44h; left
jz left
cmp eax, 42h; right
jz up
cmp eax, 41h; left
jz down
jmp over
right:
mov eax, [x]
inc eax
mov [x], eax
jmp mDone
left:
mov eax, [x]
dec eax
mov [x], eax
jmp mDone
up:
mov eax, [y]
add eax, 1
mov [y], eax
jmp mDone
down:
mov eax, [y]
sub eax, 1
mov [y], eax
jmp mDone
mDone:
over:pop eax
popad
ret
segment .data
termios: times 36 db 0
stdin: equ 0
ICANON: equ 1<<1
ECHO: equ 1<<3
segment .text
global canonical_off, echo_off,echo_on, canonical_on, write_stdin_termios, read_stdin_termios
;*********************************
;* Function turn off canonical *
;* *
;*********************************
canonical_off:
call read_stdin_termios
; clear canonical bit in local mode flags
push eax
mov eax, ICANON
not eax
and [termios+12], eax
pop eax
call write_stdin_termios
ret
;*********************************
;* Function turn off echo *
;* *
;*********************************
echo_off:
call read_stdin_termios
; clear echo bit in local mode flags
push eax
mov eax, ECHO
not eax
and [termios+12], eax
pop eax
call write_stdin_termios
ret
;*********************************
;* Function turn canonical on *
;* *
;*********************************
canonical_on:
call read_stdin_termios
; set canonical bit in local mode flags
or dword [termios+12], ICANON
call write_stdin_termios
ret
;*********************************
;* Function turn echo on *
;* *
;*********************************
echo_on:
call read_stdin_termios
; set echo bit in local mode flags
or dword [termios+12], ECHO
call write_stdin_termios
ret
;*********************************
;* Function read termios *
;* *
;*********************************
read_stdin_termios:
push eax
push ebx
push ecx
push edx
mov eax, 36h
mov ebx, stdin
mov ecx, 5401h
mov edx, termios
int 80h
pop edx
pop ecx
pop ebx
pop eax
ret
;*********************************
;* Function write a termios *
;* *
;*********************************
write_stdin_termios:
push eax
push ebx
push ecx
push edx
mov eax, 36h
mov ebx, stdin
mov ecx, 5402h
mov edx, termios
int 80h
pop edx
pop ecx
pop ebx
pop eax
ret
Explanation / Answer
%include "asm_io.inc"
%include "io.inc"
; initialized data is put in the .data segment
segment .data
clear db 27,"[2J",27,"[1;1H",0
cc db 27,"c",0
scanFormat db "%c",0
file db "input.txt",0
mode db "r",0
formatA db "%c",0
x dd 3
y dd 3
prevX dd 0
prevY dd 0
holdprevX dd 0
holdprevY dd 0
rows dd 15
cols dd 51
scorestring db "Your score is: ", 0
score dd 20
mario dd "m", 0
; uninitialized data is put in the .bss segment
segment .bss
text resb 2000
;score resb 1
; code is put in the .text segment
segment .text
global asm_main
extern fscanf
extern fopen
extern fclose
extern scanf
extern getchar
extern putchar
asm_main:
enter 0,0 ; setup routine
pusha
;***************CODE STARTS HERE*******
mov eax, clear ;two lines to clear
call print_string ;clear the screen
mov eax, cc
call load ;load the file into text
call update ;update the file with the location
mov eax, scorestring
call print_string
mov eax, [score]
call print_int
call print_nl
mov eax, text
call print_string
mov ecx, 200
top:
mov eax, 1 ;update score
sub [score], eax
call movement
call update
mov eax, clear ;two lines to clear
call print_string ;clear the screen
mov eax, scorestring ;print score and text string
call print_string
mov eax, [score]
call print_int
call print_nl
mov eax, text
call print_string
mov ebx, [x] ;check to see if we need to exit
mov ecx, [y]
inc ecx
imul ecx, [cols]
add ecx, ebx
mov eax, [text+ecx]
cmp al, 'E'
jz exit
loop top
exit:
;***************CODE ENDS HERE*********
popa
mov eax, 0 ; return back to C
leave
ret
;*********************************
;* Function to load var text with*
;* input from input.txt *
;*********************************
load:
push eax
push esi
sub esp, 20h
;get the file pointer
mov dword [esp+4], mode; the mode for the file which is "r"
mov dword [esp], file; the name of the file. Hard coded here (input.txt)
call fopen ; call fopen to open the file
;read stuff
mov [esp], eax; mov the file pointer to param 1
mov eax, esp ;use stack to store a pointer where char goes
add eax, 1Ch ;address is 1C up from the bottom of the stack
mov [esp+8], eax;pointer is param 3
mov dword [esp+4], scanFormat; fromat is param 2
mov edx, 0
mov [prevX], edx
mov [prevY], edx
scan:
call fscanf; call scanf
cmp eax, 0 ; eax will be less than 1 when EOF
jl done; eof means quit
mov eax, [esp+1Ch]; mov the result (on the stack) to eax
cmp al, 'm'
jz Mario
mov edx, [prevX]; increment prevX
inc edx
mov [prevX], edx
cmp al, 10
jz NewLine
jmp save
NewLine:
mov dword [prevX], 0
mov edx, [prevY]
inc edx
mov [prevY], edx
jmp save
Mario:
mov edx, [prevX]
mov [x], edx
mov edx, [prevY]
mov [y], edx
jmp save
save:
mov [text + esi], al; store in the array
inc esi; add one to esi (index in the array)
cmp esi, 2000; dont go tooo far into the array
jz done; quit if went too far
jmp scan ;loop back
done:
call fclose; close the file pointer
mov byte [text+esi],0 ;set the last char to null
add esp, 20h; unallocate stack space
pop esi ;restore registers
pop eax
ret
;*********************************
;* Function to update the screen *
;* *
;*********************************
update:
push eax
push ebx
;update the new loc
mov eax, [x]
mov ebx, [y]
imul ebx, [cols]
add eax, ebx
mov ebx, [mario]
cmp bl, 'm'
jz littlem
jmp bigm
littlem:
mov byte [text + eax], 'm'
jmp done2
bigm:
mov byte [text+eax], 'M'
done2:
;update the old loc
mov eax, [prevX]
mov ebx, [prevY]
mov edx, 0
imul ebx, [cols]
add eax, ebx
mov byte [text + eax], ' '
pop ebx
pop eax
ret
;*********************************
;* Function to get mouse movement*
;* *
;*********************************
movement:
pushad
mov ebx, [prevX] ;need to store prevX and prevY for when we call checkMove
mov [holdprevX], ebx ;and we are not able to move
mov ebx, [prevY]
mov [holdprevY], ebx
mov ebx, [x]
mov [prevX], ebx;save old value of x in prevX
mov ebx, [y]
mov [prevY], ebx; save old value of y in prevY
call canonical_off
call echo_off
mov eax, formatA
push eax
;http://stackoverflow.com/questions/15306463/getchar-returns-
;the-same-value-27-for-up-and-down-arrow-keys
call getchar
call getchar
call getchar
call canonical_on
call echo_on
push eax ;push the arrowkey to use in checkMove
cmp eax, 43h; right
jz right
cmp eax, 44h; left
jz left
cmp eax, 42h; down
jz down
cmp eax, 41h; up
jz up
;jmp mDone
right:
call checkMove
cmp edi, 0
jz undo
call fall ;
mov eax, [x]
inc eax
mov [x], eax
jmp mDone
left:
call checkMove
cmp edi, 0
jz undo
call fall
mov eax, [x]
dec eax
mov [x], eax
jmp mDone
down:
call checkMove
cmp edi, 0
jz undo
call fall
jmp mDone
up:
mov ebx, [x]
mov ecx, [y]
inc ecx
imul ecx, [cols]
add ebx, ecx
mov ebx, [text+ebx]
cmp bl, ' '
jz undo
call checkMove
cmp edi, 0
jz undo
jmp mDone
undo: ;if we cant mov then we need to reset prevX and prevY
mov eax, [holdprevX]
mov [prevX], eax
mov eax, [holdprevY]
mov [prevY], eax
mDone:
add esp, 4
pop eax
popad
ret
;*********************************
;* Function to check if there is *
;* a block in the way *
;*********************************
checkMove:
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
mov ebx, [x] ;mov x and y into registers here so we don't have to do it each time
mov ecx, [y] ;in the different if statements
mov eax, [ebp+8] ;parameter holding which input was givin in the movement function
cmp eax, 43h; right
jz checkright
cmp eax, 44h; left
jz checkleft
cmp eax, 42h; down
jz checkdown
cmp eax, 41h; up
jz checkup
;jmp checkDone
checkright:
imul ecx, [cols]
add ebx, ecx
add ebx, 1
mov eax, [text+ebx]
;mov ecx, [x]
;mov edx, [y]
;mov esi, [cols]
;dump_regs 1
push ebx
push eax
call gold
cmp al, 'B'
jz noright
cmp al, '*'
jz noright
cmp al, 'E'
jz noright
cmp al, '?'
jz noright
jmp yesright
noright:
mov edi, 0
jmp checkDone
yesright:
mov edi, 1
jmp checkDone
checkleft:
imul ecx, [cols]
add ebx, ecx
sub ebx, 1
mov eax, [text+ebx]
;mov ecx, [x]
;mov edx, [y]
;mov esi, [cols]
;dump_regs 1
push ebx
push eax
call gold
cmp al, 'B'
jz noleft
cmp al, '*'
jz noleft
cmp al, 'E'
jz noleft
cmp al, '?'
jz noleft
jmp yesleft
noleft:
mov edi, 0
jmp checkDone
yesleft:
mov edi, 1
jmp checkDone
checkdown:
inc ecx
imul ecx, [cols]
add ebx, ecx
mov eax, [text+ebx]
cmp al, 'B'
jz nodown
cmp al, '*'
jz nodown
cmp al, 'E'
jz nodown
cmp al, '?'
jz nodown
jmp yesdown
nodown:
mov edi, 0
jmp checkDone
yesdown:
mov edi, 1
jmp checkDone
checkup:
mov edx, [y] ;need two registers with y for when we need to update y because
dec edx ;it gets overwritten in ecx when we multiply (used in statements below
dec ecx
imul ecx, [cols] ; <----- gets overwritten so we need it in edx as well
add ebx, ecx
mov eax, [text+ebx]
push ebx
push eax ;use the character & location we are checking as a parameter for gold function
call gold ;check to see if the space is a G using the parameters
cmp al, 'B'
jz firstblocked
cmp al, '*'
jz firstblocked
cmp al, '?'
jz firstblocked
mov ecx, [y]
mov edx, [y]
mov ebx, [x]
sub ecx, 2
sub edx, 2
imul ecx, [cols]
add ebx, ecx
mov eax, [text+ebx]
push ebx
push eax
call gold
call flower
cmp al, 'B'
jz blocked
cmp al, '*'
jz blocked
cmp al, '?'
jz blocked
mov ecx, [y]
mov edx, [y]
mov ebx, [x]
sub ecx, 3
sub edx, 3
imul ecx, [cols]
add ebx, ecx
mov eax, [text+ebx]
push ebx
push eax
call gold
cmp al, 'B'
jz blocked
cmp al, '*'
jz blocked
cmp al, '?'
jz blocked
jmp notblocked
firstblocked:
inc edx
mov [y], edx
mov edi, 0
jmp checkDone
blocked:
inc edx
mov [y], edx
mov edi, 1
jmp checkDone
notblocked:
mov [y], edx
mov edi, 1
jmp checkDone
jmp checkDone
checkDone:
pop edx
pop ecx
pop ebx
pop eax
mov esp, ebp
pop ebp
ret
;*********************************
;* Function to calculate where *
;* you will fall to *
;*********************************
fall:
push ebp
mov ebp, esp
push eax
push ebx
push ecx
mov eax, [x]
mov ebx, [ebp+8]
cmp ebx, 43h; right
jz fallRight
cmp ebx, 44h; left
jz fallLeft
cmp ebx, 42h; down
jz fallDone
fallRight:
add eax, 1
jmp fallDone
fallLeft:
sub eax, 1
fallDone:
mov ebx, [y]
imul ebx, [cols]
add ebx, eax
mov ecx, [y]
while:
cmp bl, '*'
jz endwhile
cmp bl, 'B'
jz endwhile
cmp bl, 'E'
jz endwhile
cmp bl, '?'
jz endwhile
inc ecx
mov ebx, ecx
imul ebx, [cols]
add ebx, eax
push ebx
mov ebx, [text+ebx]
push ebx
call gold
jmp while
endwhile:
dec ecx
mov [y], ecx
pop ecx
pop ebx
pop eax
mov esp, ebp
pop ebp
ret
;*********************************
;* Function to add 100 points *
;* when you hit a G. Also makes *
;* Mario a capital M if it finds *
;* a F. *
;*********************************
gold:
push ebp
mov ebp, esp
push eax
push ebx
mov eax, [ebp+8]
mov ebx, [ebp+12]
cmp al, 'G'
jz add100
cmp al, 'F'
jz yesflower
jmp nogold
add100:
mov eax, 100
add [score], eax
mov byte [text+ebx], ' '
jmp nogold
yesflower:
mov eax, 50
add [score], eax
mov byte [mario], 'M'
nogold:
pop ebx
pop eax
mov esp, ebp
pop ebp
ret
;*********************************
;* Function to add a flower to *
;* the map *
;*********************************
flower:
push ebp
mov ebp, esp
push eax
mov eax, [ebp+8]
cmp al, '?'
jz yes?
jmp no?
yes?:
mov eax, [ebp+12]
sub eax, 51 ;sub 51 because thats how many characters in a row and we need one row up
mov byte [text+eax], 'F' no?:
pop eax
mov esp, ebp
pop ebp
ret
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.