2017-05-22 13 views
1

Ich benutze Dosbox mit Tasm.Ich weiß nicht, warum das Score-System nicht funktioniert

Dies ist der Hauptteil des in Assembler geschriebenen Codes.

IDEAL 
MODEL small 
STACK 100h 
P186 

include 'GL1.asm' 

DATASEG 

ballX DW 160 
ballY DW 100 
ballColor DB 4 
BALL_SIZE EQU 20 
ballDeltaX DW ? 
ballDeltaY DW ? 
scorr db 0 

randChangeCounter DW ? 

CODESEG 

start: 
mov ax, @data 
mov ds, ax 
mov ax, 13h 
int 10h 
mov al,[ballColor] 
call glBall 
mov CX,60 
mov [ballDeltaX],-2 
mov [ballDeltaY],-1 
mov cx,300 
call SetCursor 
Gameloop: 
mov BH ,00h 
call TickDelay 

call mouse 

call Score 

cmp [scorr] , 20 
je exit 
call randChange 


call changeOnborder 
call renderBall 

call mouse 
call Score 
cmp [scorr] , 20 
je exit 


jmp Gameloop 
exit: 

mov ah, 0 
mov al, 2 
int 10h 

mov ax, 4c00h 
int 21h 

proc renderBall 
PUSHA 

xor al,al ; balck 
call glBall 

mov cx,[ballDeltaX] 
add [ballX],cx 
mov cx,[ballDeltaY] 
add [ballY],cx 

mov al,[ballColor] 
call glBall 
POPA  
ret 
endp renderBall 

proc waitKey 
PUSHA 
mov ah,00h 
int 16h 
POPA 
ret 
endp waitKey  

proc glBall 
PUSHA 
mov cx,[ballX] 
mov dx,[ballY] 
mov ah,BALL_SIZE 
mov bl,BALL_SIZE 

call glBox 
POPA 
ret 
endp glBall 

proc glBox 
PUSHA 
@@ONE_LINE : 
call glVLine 
inc dx 
dec bl 
jnz @@ONE_LINE 
POPA 
ret 
endp 

proc glVLine 
PUSHA 
mov bl,ah 
mov bh,0 
mov ah,0ch 
@@ONE_PIXEL : 
int 10h 
inc cx 
dec bl 
jnz @@ONE_PIXEL 
POPA 
ret 
endp 

proc randChange 
push ax 
inc [randChangeCounter] 
cmp [randChangeCounter],20 
jne @@skip 
    mov [randChangeCounter],0 

    mov ax,13 ; +-6 
    call rand_max 
    sub ax,6 
    mov [ballDeltaX],ax 

    mov ax,13 ; +-4 
    call rand_max 
    sub ax,6 
    mov [ballDeltaY],ax 

    mov ax,6 
    call rand_max 
    add ax,2 
    mov [ballColor],al 

@@skip: 
pop ax 
ret 
endp randChange 
proc SetCursor 

mov ax, 0h 
int 33h 
mov ax, 1h 
int 33h 
mov ax, 3h 
int 33h 
ret 
endp SetCursor 
proc mouse 
mov ax, 3h 
int 33h 
ret 
endp mouse 
proc Score 

mov ax,3h 
int 33h 
cmp bl,1 
je Check_X1_Cords 
ret 
Check_X1_Cords: 
cmp cx, [ballX] 
jg Check_X2_Cords 
ret 
Check_X2_Cords: 
cmp cx,[ballX+20] 
jl Check_Y1_Cords 
ret 
Check_Y1_Cords: 
cmp dx, [ballY] 
jg ScoreLabel 
ret 
Check_Y2_Cords: 
cmp dx, [ballY+20] 
jl ScoreLabel 
ret 
ScoreLabel: 
inc [scorr] 
ret 
endp Score 

proc changeOnborder 
push ax 

mov ax,[ballX] 
add ax,[ballDeltaX] 
cmp ax,320-BALL_SIZE 
jg X_FIX 
cmp ax,0 
jge X_OK 
X_FIX: 
mov [ballColor],1 
neg [ballDeltaX] 
X_OK: 

mov ax,[ballY] 
add ax,[ballDeltaY] 
cmp ax,200- BALL_SIZE 
jg Y_FIX 
cmp ax,0 
jge Y_OK 
Y_FIX: 
mov [ballColor],1 
neg [ballDeltaY] 
Y_OK: 

pop ax 
ret 
endp changeOnborder 

END start 

und das ist GL1.asm

RANDPRIME equ 401 

segment biosdata at 40h 
org 6ch 
timer  dw ? ; clock ticks 
ends 

DATASEG 
lastrand dw 0 


FastCounter DW 0 ; 
SlowCounter DW 0 ; 

CODESEG 

; 
; timeticks - get time ticks from bios data segment. 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - current ticks 
; 

proc timeticks 
push es 

mov ax, biosdata 
mov es, ax 
assume es:biosdata 
mov ax, [timer] 
assume es:nothing 
pop es 
ret 
endp 

; 
; random - pseudo generate random number 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - random number. 
; 
codeseg 
proc random 
push dx 
push bx 
mov bx, [lastrand] 
mov ax, bx 
mov dx, RANDPRIME 
mul dx 
mov dx, ax 
call timeticks 
xor ax, dx 
xchg dh, dl 
xor ax, dx 
xchg bh, bl 
xor ax, bx 
mov [lastrand], ax 
pop bx 
pop dx 
ret 
endp 

proc rand_max 
push dx 
push bx 
mov bx,ax ; store max 
call random ; -> ax 
xor dx,dx 
div bx 
mov ax,dx ; the reminder [0..max] 

pop bx 
pop dx 
ret 
endp rand_max 
;===================== Delay ===================== 
Proc delay 

push ax 
push cx 
push dx 
push es 

mov dx,0 
mov cx , 55 
div cx 

mov cx, ax 
cmp cx,0 
je Finish 
DelayLoop: 

call timeticks 
mov dx,ax 
Tick: 
call timeticks 
cmp dx,ax 
je Tick 

loop DelayLoop 
Finish: 

pop es 
pop dx 
pop cx 
pop ax 
ret 
endp Delay 

proc TickDelay 
pusha 

mov cx, 4 
each_sync: 
    call wait_for_vsync 
loop each_sync 

popa 
ret 
endp TickDelay 

proc wait_for_vsync 
pusha 

mov dx, 03dah 
@@previous_not_ended: 
in al, dx 
test al, 08h 
jnz @@previous_not_ended 

@@next_not_started: 
in al, dx 
test al, 08h 
jz @@next_not_started 

@@exit: 
popa 
ret 
endp 

Ich weiß nicht, was zu tun ist glaube ich das Problem in GL1 ist, aber ich bin nicht sicher.

Jede Hilfe nach dem Problem oder die Art des Codes wäre wirklich appreaciated.

Vielen Dank im Voraus.

+0

Was erwarten Sie Ihren Code zu tun? Was macht der Code stattdessen? Bitte geben Sie diese Informationen an. – fuz

Antwort

0

Schwierig zu sagen, was "nicht funktioniert" bedeutet, und was Ihr Code tun sollte, aber ich werde versuchen zu erraten, dass der folgende Teil nicht tut, was beabsichtigt war (vielleicht haben Sie nichts kommentiert) .

... 
    ; cx = 0..639 mouse.x position 
Check_X1_Cords: 
    cmp cx, [ballX] 
    jg Check_X2_Cords 
    ret 
Check_X2_Cords: 
    cmp cx,[ballX+20] 
    jl Check_Y1_Cords 
    ret 
    ... 

Die Sache ist die, dass ballX Symbolspeicheradresse DW (zwei Byte) reserviert Platz vorhanden ist. Zum Beispiel Adresse 0x1234. Und der Speicher an der Adresse 0x1234 enthält beispielsweise zwei Bytes: 0x88 0x01 (0x0188 = 392). Und lassen Sie uns sagen Maus an x-Position ist 550.

Dann wird der erste cmp wird 0x1234 (0x0188 = 392) mit dem Wert bei der Adresse cx (550) vergleichen, und tun das jg Sprung zu Check_X2_Cords.

Die zweiten cmp wird cx (550) bei der Adresse mit dem Wert vergleichen 0x1234+20 = 0x1248, das, was Wert ist im Speicher vorhanden, aber sehr wahrscheinlich nicht etwas Nützliches (wahrscheinlich Null, da es über Ihre andere Variablen sieht man im Datensegment).

Sie wahrscheinlich wollte, dass die zweite Prüfung schreiben, wie:

... 
Check_X2_Cords: 
    add cx,20 
    cmp cx,[ballX] 
    jl Check_Y1_Cords 
    ... 

Die cmp cx,[ballX+20] nicht 20 im Speicher auf den Wert hinzufügen, aber es wird 20-ballX hinzufügen, die symbolische Markierung (Adresse im Speicher), nicht Wert/Variable.

Während einige Montierer (MASM) Unterstützung Syntax wie mov ax,ballX, die es macht wie ballX aussehen ist Variable (wie in Hochsprache), ist es IMO nur verwirrend Irrtum, wie die wahre Natur dieses Befehls mov ax,[offset_of_some_address] ist und die Adresse ballX ist Adresse, nicht Wert.

Es kann andere Fehler geben, ich habe keine vollständige Code-Überprüfung, nur auf den ersten verdächtige Sache, die ich gesehen habe (in etwa 10 Sekunden).


Noch ein schneller Fang, in random Sie einige Zeitdaten verwenden, um mit jeder Zufallszahl generiert? Tu das nicht, das ist auch ein Fehler. Verwenden Sie die Zeit-Ticks nur, um einen anfänglichen "Seed" -Wert zu berechnen, danach arbeitet der Zufallsgenerator. Das Mischen von Zeitdaten in jeden Anruf wird es tatsächlich nicht zufällig machen.Dein RANDPRIME ist zu klein, aber google einfach für einige sehr einfach und schnell (und nicht gut genug für Sicherheitszwecke, aber für das Spiel wird es sehr gut tun) RNGR-Algorithmen, die klassische ist sicherlich fast überall beschrieben.

1

Nur eine schnelle Durchsuchen ergab folgende:

Ihre Timeticks Verfahren das BIOS-Timer überhaupt nicht lesen!
Sie haben alles für das ES Segmentregister eingerichtet, aber die Anweisung hängt ausschließlich vom DS Segmentregister ab.

Dies zerstört sowohl Ihre rand_max und Verzögerung Verfahren.
Kein Wunder dann, dass es nicht funktioniert!

anders gesagt, die folgenden wird eine Endlosschleife (weil Timeticks höchstwahrscheinlich immer den gleichen Wert zurückgibt!):

call timeticks 
    mov dx, ax 
Tick: 
    call timeticks 
    cmp dx, ax 
    je Tick 
Verwandte Themen