Ohad
Ohad

Reputation: 17

How to do In-game assembly timer?

I am working on my final project which is a game wrote in assembly language. Therefore, I have question about how to make a timer while the game running.

My game is a simple Maze that working with W S A D, I am already using that command to run the program until the buffer will get any char.

WaitForData:
mov ah, 1
int 16h
jz WaitForData
mov ah, 0 
int 16h

Now, all I need its just a timer working with the WATCH and not by Delay.

Upvotes: 0

Views: 3054

Answers (1)

The timer is made by reading time from system, then comparing seconds (for example) with previous seconds, if both have changed, one second has passed and you do something. Next example is a snake game I made (it's in spanish because I'm costarrican). The timer part starts in the comment ";OBTENER HORA DEL SISTEMA.". You may copy-paste next code in EMU8086 and run it.

.MODEL SMALL

.STACK 1024

.DATA

;             0    1    2    3    4   ...
;          |----|----|----|----|----|
;        X | 40 | 40 | 40 | 39 | 38 |
;        Y | 10 | 11 | 12 | 12 | 12 |
;DIRECCION |  A |  A |  D |  D |  D |
;          |----|----|----|----|----|
;
;          *      
;          *
;        ***

ARRAY_X           DB 100 DUP(0)              

ARRAY_Y           DB 100 DUP(0)               

ARRAY_DIRECCIONES DB 100 DUP(0)              

CUANTOS           DW 3

SEGUNDOS          DB ?

ASTERISCO         DB 219,'$'

BLANCO            DB ' $'

MINIMO            DW ?

MAXIMO            DW ?

SEMILLA           DW ?

RAND              DB ?

COLUMNA           DB ?

FILA              DB ?

ALIMENTO          DB 1,'$'

.CODE

;INICIALIZAR DS.

MOV AX,@DATA

MOV DS,AX

;INICIALIZAR SNAKE CON TRES ELEMENTOS.

;1.

MOV SI,OFFSET ARRAY_X + 0

MOV AL,40

MOV [SI],AL

MOV SI,OFFSET ARRAY_Y + 0

MOV AL,12

MOV [SI],AL

MOV SI,OFFSET ARRAY_DIRECCIONES + 0

MOV AL,'D'

MOV [SI],AL

;2.

MOV SI,OFFSET ARRAY_X + 1

MOV AL,39

MOV [SI],AL

MOV SI,OFFSET ARRAY_Y + 1

MOV AL,12

MOV [SI],AL

MOV SI,OFFSET ARRAY_DIRECCIONES + 1

MOV AL,'D'

MOV [SI],AL

;3.

MOV SI,OFFSET ARRAY_X + 2

MOV AL,38

MOV [SI],AL

MOV SI,OFFSET ARRAY_Y + 2

MOV AL,12

MOV [SI],AL

MOV SI,OFFSET ARRAY_DIRECCIONES + 2

MOV AL,'D'

MOV [SI],AL

;OBTENER HORA DEL SISTEMA.

MOV AH,2CH

INT 21H

MOV SEGUNDOS,DH

CALL COMIDA

LABEL_MOVIMIENTO:

;VERIFICAR Q.

MOV AH,0BH

INT 21H

CMP AL,0

JE HORA

MOV AH,0

INT 16H

CMP AL,'Q'

JNE NO_TERMINAR

JMP TERMINAR_PROGRAMA

NO_TERMINAR:

CMP AL,0

JNE HORA

CMP AH,72

JE LABEL_SUBIR

CMP AH,80

JE LABEL_BAJAR

CMP AH,75

JE LABEL_IZQUIERDA

CMP AH,77

JE LABEL_DERECHA

JMP HORA

LABEL_SUBIR:

MOV SI,OFFSET ARRAY_DIRECCIONES

MOV AL,'A'

MOV [SI],AL

JMP HORA

LABEL_BAJAR:

MOV SI,OFFSET ARRAY_DIRECCIONES

MOV AL,'B'

MOV [SI],AL

JMP HORA

LABEL_IZQUIERDA:

MOV SI,OFFSET ARRAY_DIRECCIONES

MOV AL,'I'

MOV [SI],AL

JMP HORA

LABEL_DERECHA:

MOV SI,OFFSET ARRAY_DIRECCIONES

MOV AL,'D'

MOV [SI],AL

;MOVIMIENTO.

HORA:

MOV AH,2CH

INT 21H

CMP DH,SEGUNDOS

JE LABEL_MOVIMIENTO

MOV SEGUNDOS,DH

;EXAMINAR DIRECCION.

MOV BP,0 ;CONTADOR DEL FOR.

FOR:

;TERMINAR FOR.

CMP BP,CUANTOS

JB SIGUE ;JUMP IF BELOW.

JMP LABEL_MOVIMIENTO

SIGUE:

MOV SI,OFFSET ARRAY_DIRECCIONES

ADD SI,BP

MOV AL,[SI]

CMP AL,'D'

JE  MOVIMIENTO_DERECHA

CMP AL,'A'

JE  MOVIMIENTO_ARRIBA

CMP AL,'B'

JE  MOVIMIENTO_ABAJO

CMP AL,'I'

JE  MOVIMIENTO_IZQUIERDA

MOVIMIENTO_DERECHA:   

CALL BORRAR

;AVANZA.

MOV SI,OFFSET ARRAY_X

ADD SI,BP

MOV AL,[SI]

CMP AL,79

JB DERECHA_BIEN

JMP TERMINAR_PROGRAMA

DERECHA_BIEN:

INC AL

MOV [SI],AL

CALL DESPLEGAR

JMP FOR

MOVIMIENTO_ARRIBA:   

CALL BORRAR

;AVANZA.

MOV SI,OFFSET ARRAY_Y

ADD SI,BP

MOV AL,[SI]

CMP AL,0

JA ARRIBA_BIEN

JMP TERMINAR_PROGRAMA

ARRIBA_BIEN:

DEC AL

MOV [SI],AL

CALL DESPLEGAR

JMP FOR

MOVIMIENTO_ABAJO:   

CALL BORRAR

;AVANZA.

MOV SI,OFFSET ARRAY_Y

ADD SI,BP

MOV AL,[SI]

CMP AL,24

JB ABAJO_BIEN

JMP TERMINAR_PROGRAMA

ABAJO_BIEN:

INC AL

MOV [SI],AL

CALL DESPLEGAR

JMP FOR

MOVIMIENTO_IZQUIERDA:   

CALL BORRAR

;AVANZA.

MOV SI,OFFSET ARRAY_X

ADD SI,BP

MOV AL,[SI]

CMP AL,0

JA IZQUIERDA_BIEN

JMP TERMINAR_PROGRAMA

IZQUIERDA_BIEN:

DEC AL

MOV [SI],AL

CALL DESPLEGAR

JMP FOR

TERMINAR_PROGRAMA:

MOV AX,4C00H

INT 21H       



DESPLEGAR PROC

;GOTOXY.

MOV SI,OFFSET ARRAY_X

ADD SI,BP

MOV DL,[SI]

MOV SI,OFFSET ARRAY_Y

ADD SI,BP

MOV DH,[SI]

MOV AH,2

MOV BH,0

INT 10H

;DISPLAY.

MOV AH,9

MOV DX,OFFSET ASTERISCO

INT 21H

;VERIFICAR SI HA COMIDO.

MOV SI,OFFSET ARRAY_X

ADD SI,BP

MOV AL,[SI]

MOV SI,OFFSET ARRAY_Y

ADD SI,BP

MOV AH,[SI]

CMP AL,COLUMNA

JNE CAMBIO

CMP AH,FILA

JNE CAMBIO

CALL COMIDA

;OBTENER DATOS DEL ULTIMO ELEMENTO.

MOV SI,OFFSET ARRAY_X

ADD SI,CUANTOS

DEC SI

MOV AL,[SI]

MOV SI,OFFSET ARRAY_Y

ADD SI,CUANTOS

DEC SI

MOV AH,[SI]

MOV SI,OFFSET ARRAY_DIRECCIONES

ADD SI,CUANTOS

DEC SI

MOV BL,[SI]

;NUEVO ULTIMO ELEMENTO.

CMP BL,'A'

JE POQUITO_ABAJO

CMP BL,'B'

JE POQUITO_ARRIBA

CMP BL,'D'

JE POQUITO_IZQUIERDA

POQUITO_DERECHA:

INC AL

JMP GUARDAR_DATOS

POQUITO_IZQUIERDA:

DEC AL

JMP GUARDAR_DATOS

POQUITO_ARRIBA:

DEC AH

JMP GUARDAR_DATOS

POQUITO_ABAJO:

INC AH

GUARDAR_DATOS:

MOV SI,OFFSET ARRAY_X

ADD SI,CUANTOS

MOV [SI],AL

MOV SI,OFFSET ARRAY_Y

ADD SI,CUANTOS

MOV [SI],AH

MOV SI,OFFSET ARRAY_DIRECCIONES

ADD SI,CUANTOS

MOV [SI],BL

INC CUANTOS

CAMBIO:

MOV SI,OFFSET ARRAY_DIRECCIONES

ADD SI,BP

MOV BL,[SI]

MOV BL,'A'

CMP [SI],BL 

JE VERTICAL

MOV BL,'B'

CMP [SI],BL

JE VERTICAL

HORIZONTAL:

MOV DI,OFFSET ARRAY_Y

ADD DI,BP

MOV AL,[DI]

INC DI

CMP [DI],AL

JNE FIN

MOV AL,[SI]

INC SI

MOV [SI],AL                   

JMP FIN

VERTICAL:

MOV DI,OFFSET ARRAY_X

ADD DI,BP

MOV AL,[DI]

INC DI

CMP [DI],AL

JNE FIN

MOV AL,[SI]

INC SI

MOV [SI],AL                   

FIN:

INC BP 

RET

ENDP



BORRAR PROC

;GOTOXY.

MOV SI,OFFSET ARRAY_X

ADD SI,BP

MOV DL,[SI]

MOV SI,OFFSET ARRAY_Y

ADD SI,BP

MOV DH,[SI]

MOV AH,2

MOV BH,0

INT 10H

;DISPLAY.

MOV AH,9

MOV DX,OFFSET BLANCO

INT 21H

RET

ENDP


COMIDA PROC

;COLUMNA ALEATORIA.

MOV MINIMO,0

MOV MAXIMO,79

CALL ALEATORIO

MOV AL,RAND

MOV COLUMNA,AL

;FILA ALEATORIA.

MOV MINIMO,0

MOV MAXIMO,24

CALL ALEATORIO

MOV AL,RAND

MOV FILA,AL

;GOTOXY.

MOV DL,COLUMNA

MOV DH,FILA

MOV AH,2

MOV BH,0

INT 10H

;DISPLAY.

MOV AH,9

MOV DX,OFFSET ALIMENTO

INT 21H

RET

ENDP


ALEATORIO PROC

REPETICION:    

MOV  AH,0

INT  1AH

ADD  SEMILLA,DX

MOV  AX,SEMILLA

MOV  BX,2053

MOV  DX,0

MUL  BX

MOV  BX,13849

CLC       

ADD  AX,BX

ADC  DX,0

MOV  BX,65535

DIV  BX

MOV  AX,DX

MOV  SEMILLA,DX

MOV  AH,0

SHR  AL,1

CMP  AX,MINIMO

JB   REPETICION

CMP  AX,MAXIMO

JA   REPETICION

MOV  AH,0

CMP  AL,RAND

JE   REPETICION

MOV  AH,0

MOV  RAND,AL

RET

ENDP    

END

I was told that the previous code was too big, so I'm posting a small timer. All it does is display a text every second. The algorithm is simple : get system time, detect if one second has passed, then display the text :

.stack 100h
.data

text     db 'text$'
seconds  db 99

.code          
;INITILIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax   

while:   
;GET SYSTEM TIME.
  mov  ah, 2ch
  int  21h ;RETURN SECONDS IN DH.
;CHECK IF ONE SECOND HAS PASSED. 
  cmp  dh, seconds
  je   no_change
;IF NO JUMP, ONE SECOND HAS PASSED. VERY IMPORTANT : PRESERVE SECONDS TO
;USE THEM TO COMPARE WITH NEXT SECONDS. THIS IS HOW WE KNOW ONE SECOND
;HAS PASSED.
  mov  seconds, dh
;DISPLAY TEXT EVERY SECOND.
  mov  ah, 9
  mov  dx, offset text
  int  21h
no_change:  
  jmp  while 

;FINISH THE PROGRAM PROPERLY.
  mov  ax, 4c00h
  int  21h           

With a timer like this it's possible to control the ghosts with the timer, while the pacman is controlled by the keyboard (for example).

Upvotes: 1

Related Questions