(De mi [http://jgmoyay.apagada.com/jgmware.arj] )
Troncol es el juego de las “motos de luz” (juego parecido al de la serpiente pero con el objetivo declarado de eliminar al otro rival, sin la excusa de ir comiendo manzanitas), en ensamblador (bueno, realmente en cutressembler).
;CONVENCIONES EXTERNAS A CSEMBL: ;&DXXX representa el valor decimal de XXX. ;&"X" representa el valor de cadena/ASCII de X. ;&HXXX (=XXX) representa el valor hexadecimal de XXX. ; CSEMBL puede tener problemas con las etiquetas y los comentarios que ;vayan detr s de un TAB. MS-EDIT convierte cierta cantidad de espacios en ;TAB. ;07/10/91 -------> Fecha del programa base, TRONCOL.BAS, basado en un ; programa BASIC anterior. ;06/06/94 20:55 -> Hecho hasta l¡nea 30. No incluida subrutina l¡nea 7000 ; (NUEVPANT). ;07/12/94 -> A¤adido NuevPant. Cambiadas a WO referencias a PuntoX ; y PuntoY que lo consideraban BY (pero ya en la versi¢n ; antigua los valores se especificaban con "DW"). ;08/12/94 -> Contin£o a¤adiendo la rutina de direcci¢n (l¡neas ; 5000 en adelante). ; ACABADO (EXCEPTO TRADUCCIàN &D/&"") a las 21:42 ; ACABADA TRADUCCIàN "&..." a las 22:42, tras cenar. ;09/12/94 -> Correcci¢n de errores. ;Versi¢n 2. Nueva pantalla de info-teclado creada antes del 15-12-93. ; La versi¢n comienza a reprogramarse a las 23:57 horas del 16-12-93. ;**************LISTADO DE TRONCOL.BAS*************** ;5 RANDOMIZE VAL(MID$(TIME$,7)) ;6 NIVEL=1:PANTALLA=1 ;10 SCREEN 1:COLOR 0,1:KEY OFF:CLS ;20 X=30:X2=300:Y=100:Y2=100:IN$="P" ;30 LINE (0,0)-(319,199),,B:IF PANTALLA>1 THEN GOSUB 7000 ;40 INTENTOS=1 :X3=X2:Y3=Y2:X4=X:Y4=Y:AN$=INKEY$:IF AN$<>"" THEN IN$=AN$ ;50 IF IN$="q" OR IN$="Q" THEN Y=Y-1 ;60 IF IN$="a" OR IN$="A" THEN Y=Y+1 ;70 IF IN$="p" OR IN$="P" THEN X=X+1 ;80 IF IN$="o" OR IN$="O" THEN X=X-1 ;85 SOUND 100,.01 ;90 ON NIVEL GOSUB 5000, 5500, 6000 ;100 IF DIR=1 AND ((POINT (X2+1,Y2)<1 AND X2<329) OR INTENTOS>20) THEN X2=X2+1 ;110 IF DIR=2 AND ((POINT (X2-1,Y2)<1 AND X2>1) OR INTENTOS>20) THEN X2=X2-1 ;120 IF DIR=3 AND ((POINT (X2,Y2-1)<1 AND Y2>1) OR INTENTOS>20) THEN Y2=Y2-1 ;130 IF DIR=4 AND ((POINT (X2,Y2+1)<1 AND Y2<199) OR INTENTOS>20) THEN Y2=Y2+1 ;140 IF X3=X2 AND Y3=Y2 AND INTENTOS<=20 THEN INTENTOS=INTENTOS+1:GOTO 90 ;150 IF X2>319 OR X2<0 OR Y2>199 OR Y2<0 THEN GOTO 1000:REM el se estrell¢ ;160 IF X>319 OR X<0 OR Y>199 OR Y<0 THEN GOTO 2000:REM tu te estrellaste ;170 IF POINT (X2,Y2)>0 THEN GOTO 1000:REM ‚l se estrell¢ ;180 IF POINT (X,Y)>0 THEN GOTO 2000:REM tu te estrellaste ;190 PSET (X,Y),1:PSET (X2,Y2),2 ;195 IF X=X2 AND Y=Y2 THEN PRINT "Choque mutuo: los dos perd‚is":GOTO 2020 ;200 GOTO 40 ;1000 REM ‚l muere ;1010 LOCATE 22,1:PRINT "GANASTE: ‚l se ha estrellado" ;1020 PLAY "C40a40d40b40e40g40f40" ;1030 LOCATE 23,1:PRINT " PULSA UNA TECLA " ;1040 IF INKEY$="" THEN GOTO 1040 ;1045 NIVEL=NIVEL+1:IF NIVEL>3 THEN NIVEL=1:PANTALLA=PANTALLA+1 ;1046 IF PANTALLA<5 THEN GOTO 10 ;1050 RUN"logotrCO" ;2000 REM tu mueres ;2010 LOCATE 22,1:PRINT "Perdiste: te has estrellado" ;2020 PLAY "gd6c" ;2030 LOCATE 23,1:PRINT " PULSA UNA TECLA " ;2040 IF INKEY$="" THEN GOTO 2040 ;2050 RUN "logotrCO" ;5000 REM direcci¢n ;5010 IF X>X2 AND INTENTOS=1 THEN DIR=1:RETURN ;5020 IF X<X2 AND INTENTOS=1 THEN DIR=2:RETURN ;5030 IF Y<Y2 AND INTENTOS<3 THEN DIR=3 ;5040 IF Y>Y2 AND INTENTOS<3 THEN DIR=4 ;5050 IF INTENTOS<3 THEN RETURN ;5060 IF POINT (X2-1,Y2)<1 AND INTENTOS<4 THEN DIR=2 ;5070 IF POINT (X2+1,Y2)<1 AND INTENTOS<4 THEN DIR=1 ;5080 IF POINT (X2,Y2+1)<1 AND INTENTOS<5 THEN DIR=4 ;5090 IF POINT (X2,Y2-1)<1 AND INTENTOS<5 THEN DIR=3 ;5100 IF INTENTOS<5 THEN RETURN ;5110 DIR=INT(RND*4)+1:RETURN ;5500 REM direcci¢n nivel 2 ;5510 IF X>X2 AND INTENTOS=1 THEN DIR=2:RETURN ;5520 IF X<X2 AND INTENTOS=1 THEN DIR=1:RETURN ;5530 IF Y<Y2 AND INTENTOS<3 THEN DIR=4 ;5540 IF Y>Y2 AND INTENTOS<3 THEN DIR=3 ;5550 IF INTENTOS<3 THEN RETURN ;5560 IF POINT (X2-1,Y2)<1 AND INTENTOS<4 THEN DIR=2 ;5570 IF POINT (X2+1,Y2)<1 AND INTENTOS<4 THEN DIR=1 ;5580 IF POINT (X2,Y2+1)<1 AND INTENTOS<5 THEN DIR=4 ;5590 IF POINT (X2,Y2-1)<1 AND INTENTOS<5 THEN DIR=3 ;5600 IF INTENTOS<5 THEN RETURN ;5610 DIR=INT(RND*4)+1:RETURN ;6000 REM direcci¢n nivel 3 ;6010 IF IN$="4" AND INTENTOS=1 THEN DIR=2:RETURN ;6020 IF IN$="6" AND INTENTOS=1 THEN DIR=1:RETURN ;6030 IF IN$="2" AND INTENTOS<3 THEN DIR=4 ;6040 IF IN$="8" AND INTENTOS<3 THEN DIR=3 ;6050 IF INTENTOS<3 THEN RETURN ;6060 IF POINT (X2-1,Y2)<1 AND INTENTOS<4 THEN DIR=2 ;6070 IF POINT (X2+1,Y2)<1 AND INTENTOS<4 THEN DIR=1 ;6080 IF POINT (X2,Y2+1)<1 AND INTENTOS<5 THEN DIR=4 ;6090 IF POINT (X2,Y2-1)<1 AND INTENTOS<5 THEN DIR=3 ;6100 IF INTENTOS<5 THEN RETURN ;6110 DIR=INT(RND*4)+1:RETURN ;7000 REM pantallas ;7010 IF PANTALLA=2 THEN LINE(160-10,100-10)-(160+10,100+10),2,BF ;7020 IF PANTALLA=3 THEN CIRCLE (160,100),30,1:CIRCLE (160,100),29,1 ;7030 IF PANTALLA=4 THEN LINE(5,5)-(315,195),2,B:PAINT(1,1),2 ;7040 RETURN ;************INTENTO DE TRADUCCIàN A ASSEMBLER************** JMP %MENU1% ;En MENU1 hay una secci¢n de ayuda. :INICIO ;Cambiado el sistema de nivel y pantalla para que el valor m s ;peque¤o sea cero. MOV BY [%NIVEL%],0 MOV BY [%PANTALLA%],0 ;L10 reinicia sin cambiar el nivel actual (=nuevo nivel). :L10 ;SCREEN 1:COLOR 0,1:KEY OFF:CLS => MOV AX,0 INT 10 Call %ModoPant% Call %CLS% ;20 X=30:X2=300:Y=100:Y2=100:IN$="P" => ;1eh=30 MOV wo [%X%],1E ;12ch=300 MOV wo [%X2%],12C ;64h=100 MOV wo [%Y%],64 MOV wo [%Y2%],64 ;ASC("P")=50h MOV by [%IN$%],50 ;30 LINE (0,0)-(319,199),,B:IF PANTALLA>1 THEN GOSUB 7000 => PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV WO [%C%],3 XOR CX,CX XOR DX,DX :BUCLEL30_1 MOV [%PUNTOX%],CX MOV wo [%PUNTOY%],0 CALL %PUNTO% ;C7h=199 MOV wo [%PUNTOY%],C7 CALL %PUNTO% INC CX ;13Fh=319 CMP CX,13f JNZ %BUCLEL30_1% :BUCLEL30_2 MOV [%PUNTOY%],DX MOV wo [%PUNTOX%],0 CALL %PUNTO% MOV wo [%PUNTOX%],13f CALL %PUNTO% INC DX CMP DX,13f JNZ %BUCLEL30_2% POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP by [%PANTALLA%],1 JL %FINL30% CALL %NUEVPANT% :FINL30 :L40 ;40 INTENTOS=1 :X3=X2:Y3=Y2:X4=X:Y4=Y:AN$=INKEY$:IF AN$<>"" THEN IN$=AN$ MOV by [%INTENTOS%],1 MOV AX,[%X2%] MOV [%X3%],AX MOV AX,[%Y2%] MOV [%Y3%],AX MOV AX,[%X%] MOV [%X4%],AX MOV AX,[%Y%] MOV [%Y4%],AX ;Leer Teclas ;IIN$ es una nueva variable de la versi¢n 2. Mov al,[%IN$%] Mov [%IIN$%],al MOV AH,1 INT 16 ;;Este OR se ha a¤adido el 9/12/94: ;El OR no es necesario. ;OR AX,AX JE %FinLeerTeclas% :Teclapulsada XOR AX,AX INT 16 MOV [%IIN$%],AL :FinLeerTeclas ;50 IF IN$="q" OR IN$="Q" THEN Y=Y-1 ;60 IF IN$="a" OR IN$="A" THEN Y=Y+1 ;70 IF IN$="p" OR IN$="P" THEN X=X+1 ;80 IF IN$="o" OR IN$="O" THEN X=X-1 MOV AL,[%IIN$%] MOV AH,[%IN$%] ;ASC("Q")=51h CMP AL,51 JZ %QPULS% ;71h="q" CMP AL,71 JZ %QPULS% ;ASC("A")=41h CMP AL,41 JZ %APULS% ;61h="a" CMP AL,61 JZ %APULS% ;ASC("O")=4Fh CMP AL,4F JZ %OPULS% ;6fh="a" CMP AL,6f JZ %OPULS% ;ASC("P")=50h CMP AL,50 JZ %PPULS% CMP AL,70 JZ %PPULS% ;70h="p" CMP AL,1b JNZ %LTEC_NO_ESC% JMP %FINPARTIDA% :LTEC_NO_ESC JMP %TecNoV% :QPULS ;IN$ CMP AH,41 JZ %TECNOV% CMP AH,61 JZ %TECNOV% DEC wo [%Y%] JMP %FINLTEC1% :APULS CMP AH,51 JZ %TECNOV% CMP AH,71 JZ %TECNOV% INC wo [%Y%] JMP %FINLTEC1% :OPULS CMP AH,50 JZ %TECNOV% CMP AH,70 JZ %TECNOV% DEC wo [%X%] JMP %FINLTEC1% :PPULS CMP AH,4f JZ %TECNOV% CMP AH,6f JZ %TECNOV% INC wo [%X%] JMP %FINLTEC1% :TECNOV ;Tecla no v lida. Sustituir por AH (=IN$) MOV [%IIN$%],AH JMP %FinLeerTeclas% :FINLTEC1 Mov al, [%IIN$%] MOV [%IN$%], al ;85 SOUND 100,.01 ;lo sustituyo por un sonido de corta duraci¢n. CALL %BEEP% ;DEBUG-ONLY *************************************** ;JMP %L190% :L90 ;90 ON NIVEL GOSUB 5000, 5500, 6000 CMP BY [%Nivel%],0 JNZ %LIN90_2% CALL %Mover_N1% :LIN90_2 CMP BY [%Nivel%],1 JNZ %LIN90_3% CALL %Mover_N2% :LIN90_3 CMP BY [%Nivel%],2 JNZ %LIN90_4% CALL %Mover_N3% :LIN90_4 :FINL90 :L100 ;100 IF DIR=1 AND ((POINT (X2+1,Y2)<1 AND X2<329) OR INTENTOS>20) THEN X2=X2+1 CMP BY [%DIR%],1 JZ %L100_1% JMP %L110% :L100_1 ;AND (...OR intentos>20) ;14h=20 CMP BY [%INTENTOS%],14 JNG %L100_2% JMP %CONSECL100% :L100_2 ;AND ((... AND X2<329 ) OR ...) ;149h=329 CMP WO [%X2%],149 JL %L100_3% JMP %L110% :L100_3 ;AND ((POINT (X2+1,Y2)<1 AND ...) OR ...) PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X2%] MOV BX,[%Y2%] INC AX MOV [%PUNTOX%],AX MOV [%PUNTOY%],BX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,1 JL %CONSECL100% JMP %L110% :CONSECL100 INC WO [%X2%] :L110 ;110 IF DIR=2 AND ((POINT (X2-1,Y2)<1 AND X2>1) OR INTENTOS>20) THEN X2=X2-1 CMP BY [%DIR%],2 JZ %L110_1% JMP %L120% :L110_1 ;AND (...OR intentos>20) CMP BY [%INTENTOS%],14 JNG %L110_2% JMP %CONSECL110% :L110_2 ;AND ((... AND X2>1 ) OR ...) CMP WO [%X2%],1 JG %L110_3% JMP %L120% :L110_3 ;AND ((POINT (X2-1,Y2)<1 AND ...) OR ...) PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X2%] MOV BX,[%Y2%] DEC AX MOV [%PUNTOX%],AX MOV [%PUNTOY%],BX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,1 JL %CONSECL110% JMP %L120% :CONSECL110 DEC WO [%X2%] :L120 ;120 IF DIR=3 AND ((POINT (X2,Y2-1)<1 AND Y2>1) OR INTENTOS>20) THEN Y2=Y2-1 CMP BY [%DIR%],3 JZ %L120_1% JMP %L130% :L120_1 ;AND (...OR intentos>20) CMP BY [%INTENTOS%],14 JNG %L120_2% JMP %CONSECL120% :L120_2 ;AND ((... AND Y2>1 ) OR ...) CMP WO [%Y2%],1 JG %L120_3% JMP %L130% :L120_3 ;AND ((POINT (X2,Y2-1)<1 AND ...) OR ...) PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X2%] MOV BX,[%Y2%] DEC BX MOV [%PUNTOX%],AX MOV [%PUNTOY%],BX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,1 JL %CONSECL120% JMP %L130% :CONSECL120 DEC WO [%Y2%] :L130 ;130 IF DIR=4 AND ((POINT (X2,Y2+1)<1 AND Y2<199) OR INTENTOS>20) THEN Y2=Y2+1 CMP BY [%DIR%],4 JZ %L130_1% JMP %L140% :L130_1 ;AND (...OR intentos>20) CMP BY [%INTENTOS%],14 JNG %L130_2% JMP %CONSECL130% :L130_2 ;AND ((... AND Y2<199 ) OR ...) CMP WO [%Y2%],C7 JG %L130_3% JMP %L140% :L130_3 ;AND ((POINT (X2,Y2+1)<1 AND ...) OR ...) PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X2%] MOV BX,[%Y2%] INC BX MOV [%PUNTOX%],AX MOV [%PUNTOY%],BX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,1 JL %CONSECL130% JMP %L140% :CONSECL130 INC WO [%Y2%] :L140 ;140 IF X3=X2 AND Y3=Y2 AND INTENTOS<=20 THEN INTENTOS=INTENTOS+1:GOTO 90 MOV AX,[%X3%] CMP AX,[%X2%] JNZ %L150% MOV AX,[%Y3%] CMP AX,[%Y2%] JNZ %L150% CMP BY [%INTENTOS%],14 JG %L150% INC BY [%INTENTOS%] JMP %L90% :L150 ;150 IF X2>319 OR X2<0 OR Y2>199 OR Y2<0 THEN GOTO 1000:REM el se estrell¢ MOV AX,[%X2%] CMP AX,13f JNG %L150_2% JMP %L1000% :L150_2 CMP AX,0 JNL %L150_3% JMP %L1000% :L150_3 MOV AX,[%Y2%] CMP AX,C7 JNG %L150_4% JMP %L1000% :L150_4 CMP AX,0 JNL %L160% JMP %L1000% :L160 ;160 IF X>319 OR X<0 OR Y>199 OR Y<0 THEN GOTO 2000:REM tu te estrellaste MOV AX,[%X%] CMP AX,13f JNG %L160_2% JMP %L2000% :L160_2 CMP AX,0 JNL %L160_3% JMP %L2000% :L160_3 MOV AX,[%Y%] CMP AX,C7 JNG %L160_4% JMP %L2000% :L160_4 CMP AX,0 JNL %L170% JMP %L2000% :L170 ;170 IF POINT (X2,Y2)>0 THEN GOTO 1000:REM ‚l se estrell¢ PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X2%] MOV [%PUNTOX%],AX MOV AX,[%Y2%] MOV [%PUNTOY%],AX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,0 JLE %L180% JMP %L1000% :L180 ;180 IF POINT (X,Y)>0 THEN GOTO 2000:REM tu te estrellaste PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV AX,[%X%] MOV [%PUNTOX%],AX MOV AX,[%Y%] MOV [%PUNTOY%],AX CALL %POINT% MOV AX,[%C%] POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] CMP AX,0 JLE %L190% JMP %L2000% :L190 ;190 PSET (X,Y),1:PSET (X2,Y2),2 PUSH [%C%] PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV WO [%C%],1 MOV AX,[%X%] MOV [%PUNTOX%],AX MOV AX,[%Y%] MOV [%PUNTOY%],AX CALL %PUNTO% MOV WO [%C%],2 MOV AX,[%X2%] MOV [%PUNTOX%],AX MOV AX,[%Y2%] MOV [%PUNTOY%],AX CALL %PUNTO% POP [%PUNTOY%] POP [%PUNTOX%] POP [%C%] :L195 ;195 IF X=X2 AND Y=Y2 THEN PRINT "Choque mutuo: los dos perd‚is":GOTO 2020 MOV AX,[%X%] CMP AX,[%X2%] JNZ %L200% MOV AX,[%Y%] CMP AX,[%Y2%] JNZ %L200% ;UTILIZO EL "PRINT STRING" DEL DOS MOV DX,%$CHOQUEMUTUO% CALL %DOSPRINTSTRING% JMP %L2020% :L200 ;200 GOTO 40 JMP %L40% :L1000 ;1000 REM ‚l muere ;1010 LOCATE 22,1:PRINT "GANASTE: ‚l se ha estrellado" ;Esto traduce el "locate". XOR BX,BX MOV AH,2 ;22 decimal es 16+6, 16 hexadecimal. MOV DX,1601 INT 10 MOV DX,%$GANASTE% CALL %DOSPRINTSTRING% ; Esto no lo traduzco porque no s‚ c¢mo tocar notas concretas ;con el altavoz ni c¢mo usar la Sound Blaster: ; 1020 PLAY "C40a40d40b40e40g40f40" ;1030 LOCATE 23,1:PRINT " PULSA UNA TECLA " XOR BX,BX MOV AH,2 MOV DX,1701 INT 10 MOV DX,%$PULSATECLA% CALL %DOSPRINTSTRING% ;1040 IF INKEY$="" THEN GOTO 1040 XOR AX,AX INT 16 ;1045 NIVEL=NIVEL+1:IF NIVEL>3 THEN NIVEL=1:PANTALLA=PANTALLA+1 INC BY [%NIVEL%] CMP BY [%NIVEL%],2 JNG %L1046% MOV BY [%NIVEL%],0 INC BY [%PANTALLA%] :L1046 ;1046 IF PANTALLA<5 THEN GOTO 10 CMP BY [%PANTALLA%],5 JNL %L1050% JMP %L10% :L1050 ;1050 RUN"logotrCO" ;Comoquiera que ni conservo el c¢digo fuente de LOGOTRCO ni lo traduje a ;CSEMBLER ni, en caso de traducirlo, sabr¡a c¢mo ejecutarlo, suprimo el logo ;y reinicio el programa. ;Quiz m s adelante haga un logo para este programa. JMP %INICIO% :L2000 ;2000 REM tu mueres ;2010 LOCATE 22,1:PRINT "Perdiste: te has estrellado" XOR BX,BX MOV AH,2 ;22 decimal es 16+6, 16 hexadecimal. MOV DX,1601 INT 10 MOV DX,%$PERDISTE% CALL %DOSPRINTSTRING% ; La etiqueta de esta l¡nea es necesaria porque se llama desde ;la rutina de choque mutuo. :L2020 ;2020 PLAY "gd6c" ; Esto no lo traduzco porque no s‚ c¢mo tocar notas concretas ;con el altavoz ni c¢mo usar la Sound Blaster: ;2030 LOCATE 23,1:PRINT " PULSA UNA TECLA " XOR BX,BX MOV AH,2 MOV DX,1701 INT 10 MOV DX,%$PULSATECLA% CALL %DOSPRINTSTRING% ;2040 IF INKEY$="" THEN GOTO 1040 XOR AX,AX INT 16 ;2050 RUN"logotrCO" ;Como ya hemos visto, lo sustituyo por ;JMP %INICIO% ;Pero ahora voy a permitir al jugador decidir si quiere seguir. JMP %FINPARTIDA% ;COMPILADO HASTA AQUÖ******************************************************* :NUEVPANT ;Pantallas para pantalla>2 (en vers. basic), pantalla>1 (esta versi¢n). ;Nota: en esta rutina pueden cambiar los valores de CX y DX. Se espera ;que no se llame mientras estos registros est n en uso. ;7010 IF PANTALLA=2 THEN LINE(160-10,100-10)-(160+10,100+10),2,BF CMP BY [%PANTALLA%],1 JNZ %FINL7010% PUSH [%PUNTOX%] PUSH [%PUNTOY%] PUSH [%C%] MOV by [%C%],2 ;96h=150 MOV CX,96 ;La etiqueta estaba debajo del MOV DX,5a :BUC7010_1 ;5ah=90 MOV DX,5a MOV [%PUNTOX%],CX :BUC7010_2 MOV [%PUNTOY%],DX ;Aqu¡ pon¡a CALL [%PUNTO%]. Cambio del 12/12/94 CALL %PUNTO% INC DX ;6eh=110 CMP DX, 6e JNZ %BUC7010_2% INC CX ;aah=170 CMP CX, aa JNZ %BUC7010_1% POP [%C%] POP [%PUNTOY%] POP [%PUNTOX%] :FINL7010 ;7020 IF PANTALLA=3 THEN CIRCLE (160,100),30,1:CIRCLE (160,100),29,1 CMP BY [%PANTALLA%],2 JNZ %FINL7020% PUSH [%PUNTOX%] PUSH [%PUNTOY%] PUSH [%RADIO%] PUSH [%C%] ;A0h=160 MOV WO [%PUNTOX%],A0 ;64h=100 MOV WO [%PUNTOY%],64 MOV WO [%RADIO%],1E MOV WO [%C%],1 ;La siguiente l¡nea la he puesto el 12/12/94. No estaba. CALL %Redondel% POP [%C%] POP [%RADIO%] POP [%PUNTOY%] POP [%PUNTOX%] :FINL7020 ;7030 IF PANTALLA=4 THEN LINE(5,5)-(315,195),2,B:PAINT(1,1),2 CMP BY [%PANTALLA%],3 JNZ %FINL7030% PUSH [%CUAX1%] PUSH [%CUAX2%] PUSH [%CUAY1%] PUSH [%CUAY2%] PUSH [%C%] MOV wo [%CUAX1%],0 MOV wo [%CUAY1%],0 MOV wo [%CUAX2%],13F MOV wo [%CUAY2%],C7 Mov wo [%C%],2 XOR CX,CX :BUCL7030 CALL %CUADROH% ;Lo que sigue se podr¡a poner de otra manera para ahorrar algo de ;memoria. Lo pongo as¡ para mayor compatibilidad. DEC wo [%CUAX1%] DEC wo [%CUAY1%] DEC wo [%CUAX2%] DEC wo [%CUAY2%] INC Cl CMP Cl,5 JLE %Bucl7030% POP [%C%] POP [%CUAY2%] POP [%CUAY1%] POP [%CUAX2%] POP [%CUAX1%] :FINL7030 ;7040 RETURN RET ;5000 REM direcci¢n :Mover_N1 ;No se respetan AX, BX ni DX. ;5010 IF X>X2 AND INTENTOS=1 THEN DIR=1:RETURN MOV AX,[%X%] CMP AX,[%X2%] JNG %L5020% MOV AL,[%INTENTOS%] CMP AL,1 JNZ %L5020% MOV by [%DIR%],1 RET :L5020 ;5020 IF X<X2 AND INTENTOS=1 THEN DIR=2:RETURN MOV AX,[%X%] CMP AX,[%X2%] JNL %L5030% MOV AL,[%INTENTOS%] CMP AL,1 JNZ %L5030% MOV by [%DIR%],2 RET :L5030 ;5030 IF Y<Y2 AND INTENTOS<3 THEN DIR=3 MOV AX,[%Y%] CMP AX,[%Y2%] JNL %L5040% MOV AL,[%INTENTOS%] CMP AL,3 JNL %L5040% MOV by [%DIR%],3 RET :L5040 ;5040 IF Y>Y2 AND INTENTOS<3 THEN DIR=4 MOV AX,[%Y%] CMP AX,[%Y2%] JNG %L5050% MOV AL,[%INTENTOS%] CMP AL,3 JNL %L5050% MOV by [%DIR%],4 RET :L5050 ;5050 IF INTENTOS<3 THEN RETURN CMP By [%Intentos%],3 JNL %L5060% RET ;Lo que sigue se repite en otras l¡neas, o sea que le dar‚ car cter aut¢nomo ;de subrutina. :L5060 PUSH [%PUNTOX%] PUSH [%PUNTOY%] PUSH [%C%] :L5060_2 ;5060 IF POINT (X2-1,Y2)<1 AND INTENTOS<4 THEN DIR=2 CMP by [%INTENTOS%],4 JNL %L5080% MOV AX,[%X2%] MOV BX,[%Y2%] DEC AX MOV [%PuntoX%],AX MOV [%PuntoY%],BX CALL %POINT% CMP wo [%C%],1 JNL %L5070% MOV by [%DIR%],2 :L5070 ;5070 IF POINT (X2+1,Y2)<1 AND INTENTOS<4 THEN DIR=1 ;Restauro AX INC AX ;Sumo uno a AX INC AX MOV [%PuntoX%],AX MOV [%PuntoY%],BX CALL %POINT% CMP wo [%C%],1 JNL %L5080% MOV by [%DIR%],1 :L5080 ;5080 IF POINT (X2,Y2+1)<1 AND INTENTOS<5 THEN DIR=4 CMP by [%INTENTOS%],5 JNL %L5110% MOV AX,[%X2%] MOV BX,[%Y2%] INC BX MOV [%PuntoX%],AX MOV [%PuntoY%],BX CALL %POINT% CMP wo [%C%],1 JNL %L5090% MOV by [%DIR%],4 :L5090 ;5090 IF POINT (X2,Y2-1)<1 AND INTENTOS<5 THEN DIR=3 ;Restauro BX DEC BX ;Resto uno a BX DEC BX MOV [%PuntoX%],AX MOV [%PuntoY%],BX CALL %POINT% CMP wo [%C%],1 JNL %L5100% MOV by [%DIR%],3 :L5100 ;5100 IF INTENTOS<5 THEN RETURN JMP %FINL5110% :L5110 ;5110 DIR=INT(RND*4)+1:RETURN ;Voy a trampear RNDINT, porque no s‚ c¢mo generar n£meros aleatorios, ;ni siquiera con el coprocesador. ;Seg£n lo que tarde el programa en ejecutarse, podr¡a ser aleatorio el ;valor del temporizador del DOS. ;El byte menos significativo de este temporizador est en [40:&D108] ;&D100=&H64 -> est en [40:6C] ;Aqu¡ pon¡a "PUSH DX" PUSH DS MOV DX,40 MOV DS,DX MOV AL,[6c] AND AL,4 INC AL MOV [%DIR%],AL ;Aqu¡ pon¡a "POP DX" POP DS :FINL5110 POP [%C%] POP [%PUNTOY%] POP [%PUNTOX%] RET :Mover_N2 ;5500 REM direcci¢n nivel 2 ;No se respetan AX, BX ni DX. ;5510 IF X>X2 AND INTENTOS=1 THEN DIR=2:RETURN MOV AX,[%X%] CMP AX,[%X2%] JNG %L5520% MOV AL,[%INTENTOS%] CMP AL,1 JNZ %L5520% MOV by [%DIR%],2 RET :L5520 ;5520 IF X<X2 AND INTENTOS=1 THEN DIR=1:RETURN MOV AX,[%X%] CMP AX,[%X2%] JNL %L5530% MOV AL,[%INTENTOS%] CMP AL,1 JNZ %L5530% MOV by [%DIR%],1 RET :L5530 ;5530 IF Y<Y2 AND INTENTOS<3 THEN DIR=4 MOV AX,[%Y%] CMP AX,[%Y2%] JNL %L5540% MOV AL,[%INTENTOS%] CMP AL,3 JNL %L5540% MOV by [%DIR%],4 RET :L5540 ;5540 IF Y>Y2 AND INTENTOS<3 THEN DIR=3 MOV AX,[%Y%] CMP AX,[%Y2%] JNG %L5550% MOV AL,[%INTENTOS%] CMP AL,3 JNL %L5550% MOV by [%DIR%],3 RET :L5550 ;5550 IF INTENTOS<3 THEN RETURN CMP By [%Intentos%],3 JL %FINL5550% JMP %L5060% :FINL5550 RET :Mover_N3 ;6000 REM direcci¢n nivel 3 CMP by [%INTENTOS%],1 JZ %L6010% JMP %L6030% :L6010 ;6010 IF IN$="4" AND INTENTOS=1 THEN DIR=2:RETURN ;34h="4" CMP by [%IN$%],34 JNZ %L6020% MOV by [%DIR%],2 :L6020 ;6020 IF IN$="6" AND INTENTOS=1 THEN DIR=1:RETURN ;36h="6" CMP by [%IN$%],36 ;He cambiado la siguiente l¡nea (pon¡a "JNZ %L6020%). Madrugada del 12/12/94: JNZ %L6030% MOV by [%DIR%],1 :L6030 CMP BY [%INTENTOS%],3 JNL %L6060% ;6030 IF IN$="2" AND INTENTOS<3 THEN DIR=4 ;32h=2 CMP by [%IN$%],32 JNZ %L6040% MOV by [%DIR%],4 :L6040 ;6040 IF IN$="8" AND INTENTOS<3 THEN DIR=3 ;38h=8 CMP by [%IN$%],38 JNZ %L6050% MOV by [%DIR%],3 :L6050 RET :L6060 JMP %L5060% :NIVEL DB 00 :PANTALLA DB 00 :MODOP DB 0 :MAXX DW 0 :MAXY DW 0 :X DW 0 :X2 DW 0 :X3 DW 0 :X4 DW 0 :Y DW 0 :Y2 DW 0 :Y3 DW 0 :Y4 DW 0 :DIR DB 0 :INTENTOS DB 0 :IN$ DB 0 :AN$ DB 0 :IIN$ DB 0 :ModoPant ;Pone la pantalla en el modo 1 del basic (5hex). PUSH AX PUSH BX PUSH CX PUSH DX MOV AX,5 INT 10 MOV AH,F INT 10 CMP AL,5 JNZ %FINModoPant% ;Aqu¡ pon¡a "mov by [%modop%],1. Esto daba un valor simb¢lico pero no ;reconocible por CLS. MOV by [%MODOP%],5 MOV wo [%MAXX%],13f MOV wo [%MAXY%],C7 :FINModoPant POP DX POP CX POP BX POP AX RET :Redondel PUSH [%F%] PUSH [%G%] PUSH AX PUSH BX PUSH SI PUSH DI MOV wo [%F%],0 :RDFORF MOV wo [%G%],0 :RDFORG MOV AX,[%F%] MUL wo [%F%] MOV BX,AX MOV AX,[%G%] MUL wo [%G%] ADD BX,AX MOV AX,[%Radio%] MUL wo [%Radio%] CMP BX,AX JL %CCIRCUL2% JMP %FINRDFORG% :CCIRCUL2 PUSH [%F%] PUSH [%G%] CALL %CIRCUL2% NEG wo [%F%] CALL %CIRCUL2% NEG wo [%G%] CALL %CIRCUL2% NEG wo [%F%] CALL %CIRCUL2% POP [%G%] POP [%F%] JMP %RDNEXTG% :RDNEXTG INC wo [%G%] MOV SI,%G% MOV DI,%Radio% CMPSW JG %FINRDFORG% JMP %RDFORG% :FINRDFORG INC wo [%F%] MOV SI,%F% MOV DI,%Radio% CMPSW JG %FINRDFORF% JMP %RDFORF% :FINRDFORF POP DI POP SI POP BX POP AX POP [%G%] POP [%F%] RET ;Rutina complementaria de Redondel. :CIRCUL2 MOV AX, [%PuntoX%] ADD AX, [%F%] MOV BX, [%PuntoY%] ADD BX, [%G%] PUSH [%PuntoX%] PUSH [%PuntoY%] MOV [%PuntoX%],AX MOV [%PuntoY%],BX CALL %PUNTO% POP [%PuntoY%] POP [%PuntoX%] RET :PUNTO PUSH AX PUSH BX PUSH CX PUSH DX MOV CX,[%PuntoX%] CMP CX,0 JL %FinPunto% CMP CX,wo [%Maxx%] JG %FinPunto% MOV DX,[%PuntoY%] CMP DX,0 JL %FinPunto% CMP DX,wo [%Maxy%] JG %FinPunto% MOV AX,[%C%] MOV AH,0c XOR BX,BX INT 10 :FinPunto POP DX POP CX POP BX POP AX RET :G DW 0 :F DW 0 :PuntoX DW 0 :PuntoY DW 0 :Radio DW 0 :C DW 0 :BEEP PUSH AX PUSH BX PUSH CX MOV AL,B6 OUT 43,AL MOV AL,33 OUT 42,AL MOV AL,DL OUT 42,AL IN AL,61 MOV AH,AL OR AL,03 OUT 61,AL MOV BX,0000 :BUCBEEP INC BX ;Cambio del 11/12/94: Aqu¡ pon¡a: ;CMP BX,00FF ;Pero eso hace que el juego sea demasiado r pido. Mejor: ;CMP BX,2FF ;Cambio del 12/12/94:Quiz podamos poner varios niveles: CMP BX,[%Retardo%] JNZ %BUCBEEP% MOV AL,B6 OUT 43,AL MOV AL,AH OUT 61,AL POP CX POP BX POP AX RET :POINT ;En cierto modo, inversa de punto. ;Averigua el color de un punto situado en la pantalla. ;Esta subrutina devolver el color del punto en la variable C. PUSH AX PUSH BX PUSH CX PUSH DX ;Da el valor 1FF a la salida. Esto dar una salida ;err¢nea si el punto no est en pantalla. MOV wo [%C%],1FF MOV CX,[%PuntoX%] CMP CX,0 JL %FinPoint% CMP CX,wo [%Maxx%] JG %FinPoint% MOV DX,[%PuntoY%] CMP DX,0 JL %FinPoint% CMP DX,wo [%Maxy%] JG %FinPoint% MOV AH,0D XOR BX,BX INT 10 ;A¤adido el 11/12/94 XOR AH,AH MOV [%C%],AX :FinPoint POP DX POP CX POP BX POP AX RET :CUADROH ;Crea un cuadro hueco. Coordenadas: CuaX1,CuaY1,CuaX2,CuaY2 ;A¤adido el 07/12/94 PUSH CX PUSH DX PUSH [%PUNTOX%] PUSH [%PUNTOY%] MOV CX,[%CuaX1%] MOV DX,[%CuaY1%] :BUCLECH_1 MOV [%PUNTOX%],CX PUSH [%CuaY1%] POP [%PuntoY%] CALL %PUNTO% PUSH [%CuaY2%] POP [%PuntoY%] CALL %Punto% INC CX CMP CX,wo [%Cuax2%] JNZ %BUCLECH_1% :BUCLECH_2 MOV CX,[%CuaX1%] MOV DX,[%CuaY1%] :BUCLECH_3 MOV [%PUNTOY%],DX PUSH [%CuaX1%] POP [%PuntoX%] CALL %PUNTO% PUSH [%CuaX2%] POP [%PuntoX%] CALL %Punto% INC DX CMP DX,wo [%Cuay2%] JNZ %BUCLECH_3% POP [%PUNTOY%] POP [%PUNTOX%] POP DX POP CX RET :CuaX1 DW 0 :CuaY1 DW 0 :CuaX2 DW 0 :CuaY2 DW 0 :DOSPRINTSTRING PUSH AX MOV AH,9 INT 21 POP AX RET :FINPARTIDA ;Pone la pantalla en modo texto. XOR AX,AX INT 10 :FINPAR_2 ;Permite al jugador expresar libremente su opini¢n y decir que, POR SUPUESTO, ;quiere seguir jugando a este maravilloso juego. MOV DX,%$OTRASN% CALL %DOSPRINTSTRING% XOR AX,AX INT 16 PUSH AX MOV AH,E INT 10 MOV DX,%$0a0d% ;El siguiente call fue a¤adido el 9/12/94. Sin ‚l la l¡nea anterior no ;tiene sentido. CALL %DOSPRINTSTRING% POP AX MOV BX,%FIN_OPCIONES% MOV CX,BX ADD CX,[%FIN_N_OPCIONES%] :FIN_BUCLE CMP AL,[BX] JZ %FIN_ENCONTR% INC BX CMP BX,CX JL %FIN_BUCLE% ;Si el jugador da una respuesta no admitida, se vuelve a mostrar ;el mensaje. JMP %FINPAR_2% :FIN_ENCONTR ;Cambia BX de la direcci¢n de opciones a la de significado. SUB BX,%Fin_Opciones% ADD BX,%FIN_Significado% MOV AL,[BX] CMP AL,0 ;Nota: los acentos en esta l¡nea pueden dar problemas si las letras ;acentuadas no est n en la misma caja (baja o alta) en etiqueta y llamada. JNZ %FIN_quiz S¡% ;Voy a hacer que el jugador tenga un men£ antes de salir. JMP %MENU1% JMP %SALIDADOS% :FIN_quiz S¡ CMP AL,1 JNZ %FIN_ERROR% ;En la versi¢n de prueba aqu¡ pon¡a JMP %INICIO%. Pero ahora ;hay un men£ que el jugador puede querer utilizar. ;Bueno, mejor que salga el men£ si el jugador no quiere seguir. ;JMP %MENU1% JMP %INICIO% :FIN_ERROR MOV DX,%$ERRFINENC% CALL %DOSPRINTSTRING% MOV DX,%$ABEND% CALL %DOSPRINTSTRING% INT 20 :SALIDADOS MOV AX,3 INT 10 MOV DX, %$ABOUT% CALL %DOSPRINTSTRING% MOV DX, %$FREEWARE% CALL %DOSPRINTSTRING% INT 20 :CLS ;A¤adido en la b£squeda de errores. PUSH AX MOV AX,0 INT 10 XOR AX,AX MOV AL,[%MODOP%] INT 10 POP AX RET :FIN_N_Opciones ;Es palabra para sumarlo facilmente a BX. DW 6 :FIN_Opciones ;Nota: lo que sigue ser estropeado por CSEMBL. Ed¡tese con DEBUG para ;restaurar la diferencia may£sculas-min£sculas. DB "SsYyNn" :FIN_Significado ;Uno: seguir; Cero: dejarlo. DB 1 1 1 1 0 0 ;A¤adido el 12/12/94 para la versi¢n 1.0 :MENU1 MOV AX,3 INT 10 MOV DX, %$M_OPC% CALL %DOSPRINTSTRING% XOR AX,AX INT 16 ;Aqu¡ pon¡a CMP AL,27 CMP AL,1B JNZ %Menu1NoESC% JMP %SalidaDOS% :Menu1NoEsc CMP AL,31 JL %Menu1% CMP AL,35 JG %Menu1% AND AX,F ;Aqu¡ pon¡a "SHR..." SHL AL,1 MOV BX,AX ;A¤adido un -2 porque el valor m¡nimo es 1 (*2=2). ADD BX,%M_OPC_SELCASE% -2 JMP [BX] :Ateclas MOV AX,3 INT 10 XOR BX,BX MOV AH,2 MOV DX,B00 INT 10 MOV DX,%$A_Teclas% CALL %DOSPRINTSTRING% XOR BX,BX MOV AH,2 MOV DX,1701 INT 10 MOV DX,%$PULSATECLA% CALL %DOSPRINTSTRING% xor AX,AX INT 16 JMP %MENU1% :AAbout MOV AX,3 INT 10 XOR BX,BX MOV AH,2 MOV DX,122 INT 10 MOV DX,%$About% CALL %DOSPRINTSTRING% XOR BX,BX MOV AH,2 MOV DX,924 INT 10 MOV DX,%$EngAbout% CALL %DOSPRINTSTRING% XOR BX,BX MOV AH,2 MOV DX,1120 INT 10 MOV DX,%$FreeWare% CALL %DOSPRINTSTRING% XOR BX,BX MOV AH,2 MOV DX,1701 INT 10 MOV DX,%$PULSATECLA% CALL %DOSPRINTSTRING% xor AX,AX INT 16 JMP %MENU1% :ACambiaN MOV AX,3 INT 10 XOR BX,BX MOV AH,2 MOV DX,800 INT 10 MOV DX,%$M_Nivel% CALL %DOSPRINTSTRING% MOV AX,[%Retardo%] ;Pon¡a: MOV AL,C. Cambiado para dar un d¡gito (30h-39h ASCII). MOV AL,3C SUB AL,AH MOV AH,E INT 10 XOR BX,BX MOV AH,2 MOV DX,C00 INT 10 MOV DX,%$M_CH_Nivel% CALL %DOSPRINTSTRING% :ACambiaN_B XOR AX,AX INT 16 CMP AL,30 JL %ACambiaN_B% CMP AL,39 JG %ACambiaN_B% AND AL,F MOV AH,C SUB AH,AL OR AL,FF MOV [%Retardo%],AX XOR BX,BX MOV AH,2 MOV DX,1701 INT 10 MOV DX,%$PULSATECLA% CALL %DOSPRINTSTRING% xor AX,AX INT 16 JMP %MENU1% :Ajugar JMP %INICIO% :$CHOQUEMUTUO DB "Choque mutuo: Los dos perd‚is." 0a 0d 24 :$GANASTE DB "GANASTE: ‚l se ha estrellado" 0a 0d 24 :$PULSATECLA DB " PULSA UNA TECLA " 0a 0d 24 :$PERDISTE DB "Perdiste: te has estrellado" 0a 0d 24 :$OTRASN DB "¨Otra partida? (S/N) ------------->" 0a 0d DB "Do you want to play again? (Y/N) ->" 24 :$ERRFINENC DB "Error: M¢dulo FINPARTIDA, FIN_SIGNIFICADO err¢neo." 0a 0d 24 :$ABEND DB "Final de ejecuci¢n anormal / abnormal end of execution." 0a 0d 24 :$M_OPC ;A¤adido el 12/12/94 para la versi¢n definitiva. DB "1 - Ayuda: Teclas." 0a 0d DB " Help: Keyboard." 0a 0d DB "2 - Acerca de..." 0a 0d DB " About..." 0a 0d DB "3 - Cambiar nivel." 0a 0d DB " Change level." 0a 0d DB "4 - Jugar." 0a 0d DB " Play." 0a 0d DB "5 - Terminar." 0a 0d DB " Exit." 0a 0d 24 ;Lo siguiente ha de remitir a etiquetas que existan. :M_OPC_SELCASE DW %ATeclas%,%AAbout%,%AcambiaN%,%Ajugar%,%SalidaDos% ;:$A_teclas ;DB "Q ARRIBA / UP O P" 0a 0a 0d ;DB "A ABAJO / DOWN IZQUIERDA / LEFT DERECHA / RIGHT" 0a 0d 24 :$M_Nivel DB "El nivel actual es:" 0a 0d DB "Current level is: " 24 :Retardo DW 5FF :$M_CH_Nivel DB "Escriba el nuevo nivel (0-9):" 0a 0d DB "Type in new level number (0-9): " 24 ;Notas ;A¤adido el 07/12/94 :$ABOUT DB "Acerca de..." 0a 0d DB "Programado en Assembler / CSEMBL" 0a 0d DB "Basado en la pel¡cula ®TRON¯, producida (creo) por Disney, y en un" 0a 0d DB "antiguo juego de ordenador para Sinclair Zx-Spectrum." 0a 0d DB "En este programa se incluye una rutina para trazar c¡rculos basada en" DB 0a 0d DB "el c lculo de la ra¡z cuadrada aproximada y la aplicaci¢n de Pit goras" DB 0a 0d 24 :$FREEWARE DB "THIS IS FREEWARE" 0a 0d 24 :$0a0d DB 0a 0d 24 :$ENGABOUT DB "About..." 0a 0d DB "Programmed in Assembler with CSEMBL.BAS" 0a 0d DB "Based in a film called 'TRON', produced (but I'm not sure) by Disney," a d DB "and also in an old ZX-SPECTRUM game." 0a 0d DB "This program includes circle drawing procedures based in aproximate" db " calculus" 0a 0d DB "of square root and application of hý=c1ý+c2ý (radiusý=siný(a)+cosý(a))." DB 0a 0d 24 ;Pantalla de teclas para tron v. 2: :$A_Teclas DB "ÜÛÛÛÛÜ ÜÛÛÛÛÜ ÛÛÛÛÛÜ" a d DB "ÛÛ ÛÛ Arriba ÛÛ ÛÛ ÛÛ ÛÛ" a d DB "ÛÛ ÜÛÛ Up ÛÛ ÛÛ ÛÛÛÛÛß" a d DB "ßÛÛÛßÛÛ ßÛÛÛÛß ÛÛ" a d DB " Izquierda Derecha" a d DB " Left Right" a d DB a d DB "ÜÛÛÛÛÜ ÜÜÜÜÜ" a d db "ÛÛ ÛÛ Abajo ÛÛ ÜÜÜ ÜÜÜ Abortar partida." a d db "ÛÛÛÛÛÛ Down ÛÛßß ßÜÜ Û Abort game." a d db "ÛÛ ÛÛ ÛÛÜÜÜÜÜÜÜß ßÜÜÜ" a d 24