Uno de mis primeros proyectos en QBASIC fue tratar de adaptar mis programa de dibujo de gw-basic Pinta, Pintarel y Zoomdraw.
Como Qbasic no permitía usar MERGE, tuve que idear mi propio formato de archivo. Pero eso me permitió más flexibilidad que el programa equivalente de GW-BASIC.
Puede descargar el grupo de programas, incluido el fichero de ejemplo ABCD.LIB, desde este fichero: qb-pinta
Programa para crear imágenes vectoriales. El intérprete está en “Ejecuta”, de forma que importando esa parte se podrían reutilizar las imágenes en otros programas qbasic.
DECLARE SUB Grabar () DECLARE SUB Cargar () DECLARE SUB Poncursor (Px!, Py!, colo!) DECLARE SUB Ejecuta (Trad$) DECLARE SUB RePintar () DECLARE SUB sparklepause () DECLARE SUB leeteclas () DECLARE FUNCTION MAX! (a!, B!) DECLARE SUB Centrar (y!, a$) DECLARE SUB Ayuda (a$) COLOR 7, 1: CLS CLS columnas = 80 COLOR 15, 1 Centrar 8, "Pintor Electr¢nico" COLOR 7, 1 Centrar 10, "(Programa de dibujo por comandos)" Ayuda "Pulse una tecla" 'DO 'LOOP UNTIL INKEY$ > "" sparklepause col = 1 INC = 1 RX = 1 RY = 1 X = 0 y = 0 DIM SHARED MATRIZ$(1000) 'DIM SHARED PUNDO(100) PMatriz = 0 SCREEN 12 CLS LOCATE 28, 1 PRINT "1 Linea 2 Cuadro 3 CuadroR 4 Circulo 5 Arco 8 INC 9 DEC" x1! = 0 x2! = 8 y1! = 0 Y2! = 8 bpp% = 1 planos% = 4 tama% = 4 + INT(((PMAP(x2!, 0) - PMAP(x1!, 0) + 1) * (bpp%) + 7) / 8) * planos% * (PMAP(Y2!, 1) - PMAP(y1!, 1) + 1) LINE (0, 3)-(3, 3) LINE (0, 5)-(3, 5) LINE (8, 3)-(5, 3) LINE (8, 5)-(5, 5) LINE (3, 0)-(3, 3) LINE (5, 0)-(5, 3) LINE (3, 8)-(3, 5) LINE (5, 8)-(5, 5) DIM SHARED curs%(tama%) GET (0, 0)-(8, 8), curs% CLS DO leeteclas LOOP END ERRORMAN: SELECT CASE ERR CASE 53 PRINT "No se encontr¢ ning£n archivo" RESUME NEXT CASE 71, 75, 76 SELECT CASE ERR CASE 71: PRINT "El disco no est listo." CASE 75: PRINT "Error de acceso en ruta/archivo." CASE 76: PRINT "Ruta de acceso no v lida." END SELECT PRINT "Introduzca un disquete en la unidad y pulse <INTRO> o" INPUT "escriba el nombre de la nueva v¡a de acceso"; VIA$ IF VIA$ > "" THEN CHDIR VIA$ END SELECT SUB Ayuda (a$) COLOR 1', 7 LOCATE 25, 1 PRINT SPACE$(80); Centrar 25, a$ COLOR 7', 1 END SUB SUB Cargar SHARED MATRIZ$(), PMatriz ON ERROR GOTO ERRORMAN FILES "*.PIN" ON ERROR GOTO 0 INPUT "Cargar: ¨NOMBRE?"; a$ IF INSTR(a$, ".") < 1 THEN a$ = a$ + ".PIN" OPEN a$ FOR BINARY AS #1 CABE$ = INPUT$(11, #1) IF CABE$ <> "JMYPINTOR00" THEN EXIT SUB GET 1, , PMatriz FOR f = 0 TO PMatriz GET 1, , L 'L = LEN(Matriz$(F)) MATRIZ$(f) = INPUT$(L, #1) NEXT CLOSE #1 CLS RePintar END SUB SUB Centrar (y, a$) SHARED columnas LOCATE y, (columnas - LEN(a$)) / 2 PRINT a$; END SUB SUB Ejecuta (Trad$) SHARED XP, YP, RX, RY, col SELECT CASE MID$(Trad$, 1, 2) CASE CHR$(0) + CHR$(1) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) X = CVI(MID$(Trad$, 7, 2)) y = CVI(MID$(Trad$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col CASE CHR$(0) + CHR$(2) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) X = CVI(MID$(Trad$, 7, 2)) y = CVI(MID$(Trad$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col, B CASE CHR$(0) + CHR$(3) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) X = CVI(MID$(Trad$, 7, 2)) y = CVI(MID$(Trad$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col, BF CASE CHR$(0) + CHR$(4) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) RADIO = CVI(MID$(Trad$, 7, 2)) CIRCLE (ANTX * RX + XP, ANTY * RY + XP), MAX(RX, RY) * RADIO, col, , , RY / RX CASE CHR$(0) + CHR$(5) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) RADIO = CVI(MID$(Trad$, 7, 2)) ANG = CVS(MID$(Trad$, 9, 4)) ANG2 = CVS(MID$(Trad$, 13, 4)) CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, col, ANG, ANG2, RY / RX CASE CHR$(0) + CHR$(6) ANTX = CVI(MID$(Trad$, 3, 2)) ANTY = CVI(MID$(Trad$, 5, 2)) PAINT (ANTX, ANTY), col, col CASE CHR$(0) + CHR$(7) col = ASC(MID$(Trad$, 3, 1)) END SELECT END SUB SUB Grabar SHARED MATRIZ$(), PMatriz ON ERROR GOTO ERRORMAN FILES "*.PIN" ON ERROR GOTO 0 INPUT "¨NOMBRE?"; a$ IF INSTR(a$, ".") < 1 THEN a$ = a$ + ".PIN" OPEN a$ FOR BINARY AS #1 a$ = "JMYPINTOR00" PUT 1, , a$ PUT 1, , PMatriz FOR f = 0 TO PMatriz L = LEN(MATRIZ$(f)) PUT 1, , L PUT #1, , MATRIZ$(f) NEXT CLOSE #1 CLS RePintar END SUB SUB leeteclas SHARED y, X, INC, RX, RY, col, XP, YP SHARED ANTX, ANTY, RADIO, ANG, ANG2, Pintado SHARED Modo, CambioModo, PMatriz, in$ IF in$ = "" THEN in$ = INKEY$ 'PUT (X, Y), curs% Poncursor X, y, 0 'RePintar SELECT CASE in$ CASE " " CLS : RePintar CASE CHR$(27) Pintado = 0 CASE CHR$(8) 'BS IF PMatriz > 0 THEN PMatriz = PMatriz - 1: CLS : RePintar CASE CHR$(127) 'CTRL-BS IF MATRIZ$(PMatriz + 1) > "" THEN PMatriz = PMatriz + 1: CLS : RePintar CASE CHR$(0) + CHR$(59): Modo = 0: Pintado = 0 CASE CHR$(0) + CHR$(60): Modo = 1: Pintado = 0 CASE CHR$(0) + CHR$(61): Modo = 2: Pintado = 0 CASE CHR$(0) + CHR$(62): Modo = 3: Pintado = 0 CASE CHR$(0) + CHR$(63): Modo = 5: Pintado = 0 CASE CHR$(0) + CHR$(64): Modo = 7: Pintado = 0 CASE CHR$(0) + CHR$(65): Modo = 8: Pintado = 0 CASE CHR$(0) + CHR$(66): INC = INC * 2 CASE CHR$(0) + CHR$(67): INC = INC / 2 CASE "G", "g": Grabar CASE "C", "c": Cargar CASE CHR$(0) + "H" y = y - INC * RY CASE CHR$(0) + "P" y = y + INC * RY CASE CHR$(0) + "K" X = X - INC * RX CASE CHR$(0) + "M" X = X + INC * RX CASE CHR$(13) SELECT CASE Modo CASE 0, 1, 2'Dibujando l¡nea o cuadro IF Pintado > 0 THEN SELECT CASE Modo CASE 0 'Dibujando l¡nea LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col Trad$ = CHR$(0) + CHR$(1) + MKI$(ANTX) + MKI$(ANTY) + MKI$(X) + MKI$(y) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 CASE 1 'Cuadro LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col, B Trad$ = CHR$(0) + CHR$(2) + MKI$(ANTX) + MKI$(ANTY) + MKI$(X) + MKI$(y) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 CASE 2 'Dibujando cuadro relleno LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, y * RY + YP), col, BF Trad$ = CHR$(0) + CHR$(3) + MKI$(ANTX) + MKI$(ANTY) + MKI$(X) + MKI$(y) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 END SELECT Pintado = 0 ELSE ANTX = X ANTY = y Pintado = 1 END IF CASE 3 'Dibujando c¡rculo IF Pintado = 0 THEN Ayuda "Seleccione el radio" ANTX = X ANTY = y Pintado = 1 ELSE 'Pit goras: H^2=C1^2+c2^2 lado1 = ABS(ANTX - X) LADO2 = ABS(ANTY - y) RADIO = SQR(lado1 ^ 2 + LADO2 ^ 2) PLAY "L64 CD" CIRCLE (ANTX * RX + XP, ANTY * RY + XP), MAX(RX, RY) * RADIO, col, , , RY / RX Trad$ = CHR$(0) + CHR$(4) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 Pintado = 0 Ayuda " " END IF CASE 5 SELECT CASE Pintado CASE 0 Ayuda "Seleccione radio y ngulo inicial" ANTX = X ANTY = y Pintado = 1 CASE 1 'Pit goras: H^2=C1^2+c2^2 lado1 = -(ANTX - X) LADO2 = -(ANTY - y) RADIO = SQR(lado1 ^ 2 + LADO2 ^ 2) 'Selecci¢n de ngulo: IF lado1 = 0 THEN ANG = ATN(9.999999E+09) ELSE ANG = ATN(ABS(LADO2 / lado1)) END IF SELECT CASE ((SGN(lado1) + 1) * 2 + SGN(LADO2) + 1) CASE 0 'X:+ Y:- ANG = 4 * ATN(1#) - ANG CASE 1 '180 grados ANG = 4 * ATN(1#) CASE 2 'X:- Y:- o bien ang=90 grados IF SGN(lado1) = -1 THEN ANG = 4 * ATN(1#) + ANG END IF CASE 6 'X:+ Y:- ANG = 8 * ATN(1#) - ANG CASE 4 IF LADO2 > 0 THEN ANG = 6 * ATN(1#) END SELECT Pintado = 2 CASE 2 'Pit goras: H^2=C1^2+c2^2 lado1 = -(ANTX - X) LADO2 = -(ANTY - y) 'Radio = SQR(Lado1 ^ 2 + lado2 ^ 2) 'Selecci¢n de ngulo: IF lado1 = 0 THEN ANG2 = ATN(9.999999E+09) ELSE ANG2 = ATN(ABS(LADO2 / lado1)) END IF SELECT CASE ((SGN(lado1) + 1) * 2 + SGN(LADO2) + 1) CASE 0 'X:+ Y:- ANG2 = 4 * ATN(1#) - ANG2 CASE 1 '180 grados ANG2 = 4 * ATN(1#) CASE 2 'X:- Y:- o bien ang2=90 grados IF SGN(lado1) = -1 THEN ANG2 = 4 * ATN(1#) + ANG2 END IF CASE 6 'X:+ Y:- ANG2 = 8 * ATN(1#) - ANG2 CASE 4 IF LADO2 > 0 THEN ANG2 = 6 * ATN(1#) END SELECT 'BEEP CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, col, ANG, ANG2, RY / RX Trad$ = CHR$(0) + CHR$(5) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) + MKS$(ANG) + MKS$(ANG2) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 Pintado = 0 END SELECT CASE 7 PAINT (X * RX + XP, y * RY + XP), col, col Trad$ = CHR$(0) + CHR$(6) + MKI$(X) + MKI$(y) + MKI$(col) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 CASE 8 CLS FOR f = 0 TO 15 LINE (f * 16 * 2, 0)-(f * 2 * 16 + 16, 16), f, BF LINE (f * 16 * 2, 0)-(f * 2 * 16 + 16, 16), 15, B, &HF0F0 NEXT FOR f = 0 TO 15: LOCATE 3, f * 4 + 1: PRINT RIGHT$(STR$(f), 2); : NEXT LOCATE 4, 1: PRINT "-1: Volver" INPUT "¨Color?"; CL IF CL <> -1 THEN col = CL Trad$ = CHR$(0) + CHR$(7) + CHR$(col) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 END IF RePintar END SELECT RePintar CASE CHR$(10) IF Modo = 5 AND Pintado = 2 THEN 'Pit goras: H^2=C1^2+c2^2 lado1 = -(ANTX - X) LADO2 = -(ANTY - y) 'Radio = SQR(Lado1 ^ 2 + lado2 ^ 2) 'Selecci¢n de ngulo: IF lado1 = 0 THEN ANG2 = ATN(9.999999E+09) ELSE ANG2 = ATN(ABS(LADO2 / lado1)) END IF SELECT CASE ((SGN(lado1) + 1) * 2 + SGN(LADO2) + 1) CASE 0 'X:+ Y:- ANG2 = 4 * ATN(1#) - ANG2 CASE 1 '180 grados ANG2 = 4 * ATN(1#) CASE 2 'X:- Y:- o bien ang2=90 grados IF SGN(lado1) = -1 THEN ANG2 = 4 * ATN(1#) + ANG2 END IF CASE 6 'X:+ Y:- ANG2 = 8 * ATN(1#) - ANG2 CASE 4 IF LADO2 > 0 THEN ANG2 = 6 * ATN(1#) END SELECT CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, col, ANG2, ANG, RY / RX Trad$ = CHR$(0) + CHR$(5) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) + MKS$(ANG2) + MKS$(ANG) MATRIZ$(PMatriz) = Trad$: PMatriz = PMatriz + 1 Pintado = 0 RePintar END IF END SELECT IF X < 0 THEN X = 0 LOCATE 26, 1 PRINT USING "X:#### Y:#### RX:#### RY:#### INC:####"; X; y; RX; RY; INC LOCATE 27, 1 in$ = "" 'PUT (X, Y), curs%, PSET Poncursor X, y, col SELECT CASE Modo CASE 0 PRINT "Trazar l¡nea"; SPACE$(20) CASE 1 PRINT "Dibujar cuadro"; SPACE$(20) CASE 2 PRINT "Dibujar cuadro relleno"; SPACE$(20) CASE 3 PRINT "Dibujar circulo"; SPACE$(20) CASE 5 PRINT "Dibujar arco"; SPACE$(20) IF Pintado = 1 THEN PRINT "Seleccione ngulo y radio" lado1 = ABS(ANTX - X) LADO2 = ABS(ANTY - y) 'Rad se utiliza para evitar problemas con el radio 'definitivo Rad = SQR(lado1 ^ 2 + LADO2 ^ 2) CIRCLE (ANTX, ANTY), Rad in$ = "": IF in$ = "" THEN DO: in$ = INKEY$: LOOP UNTIL in$ > "" CIRCLE (ANTX, ANTY), Rad, 0 LOCATE 27, 15: PRINT Rad ELSEIF Pintado = 2 THEN PRINT "Seleccione ngulo final. Ctrl-ret para seleccionar ngulo no pintado." lado1 = (-ANTX + X) LADO2 = (-ANTY + y) 'Selecci¢n de ngulo: IF lado1 = 0 THEN ANG2 = ATN(9.999999E+09) ELSE ANG2 = ATN(ABS(LADO2 / lado1)) END IF LOCATE 25, 1 PRINT ((SGN(lado1) + 1) * 2 + SGN(LADO2) + 1); SELECT CASE ((SGN(lado1) + 1) * 2 + SGN(LADO2) + 1) CASE 0 'X:+ Y:- ANG2 = 4 * ATN(1#) - ANG2 CASE 1 '180 grados ANG2 = 4 * ATN(1#) CASE 2 'X:- Y:- o bien ang2=90 grados IF SGN(lado1) = -1 THEN ANG2 = 4 * ATN(1#) + ANG2 END IF CASE 6 'X:+ Y:- ANG2 = 8 * ATN(1#) - ANG2 CASE 4 IF LADO2 > 0 THEN ANG2 = 6 * ATN(1#) END SELECT CIRCLE (ANTX * RX + XP, ANTY * RY + XP), MAX(RX, RY) * RADIO, col, ANG, ANG2, RY / RX in$ = "": IF in$ = "" THEN DO: in$ = INKEY$: LOOP UNTIL in$ > "" CIRCLE (ANTX * RX + XP, ANTY * RY + XP), MAX(RX, RY) * RADIO, 0, ANG, ANG2, RY / RX LOCATE 27, 15: PRINT RADIO END IF CASE 7: PRINT "Rellenando. Elija centro" END SELECT IF in$ = "" THEN DO: in$ = INKEY$: LOOP UNTIL in$ > "" END SUB FUNCTION MAX (a, B) MAX = a IF B > a THEN MAX = B END FUNCTION SUB Poncursor (Px, Py, colo) LINE (Px, Py + 1)-(Px, Py + 7), colo LINE (Px, Py - 1)-(Px, Py - 7), colo LINE (Px + 1, Py)-(Px + 7, Py), colo LINE (Px - 1, Py)-(Px - 7, Py), colo END SUB SUB RePintar SHARED PMatriz, col 'CLS col = 1 FOR f = 0 TO PMatriz - 1 Trad$ = MATRIZ$(f) Ejecuta (Trad$) NEXT END SUB SUB sparklepause 'SparklePause: ' Creates flashing border for intro screen COLOR 15, 1 a1$ = "Ü " a$ = "" FOR a = 1 TO 40: a$ = a$ + a1$: NEXT WHILE INKEY$ <> "": WEND 'Clear keyboard buffer WHILE INKEY$ = "" FOR a = 1 TO 5 LOCATE 1, 1 'print horizontal sparkles PRINT MID$(a$, a, 80); LOCATE 22, 1 PRINT MID$(a$, 6 - a, 80); FOR B = 2 TO 21 'Print Vertical sparkles c = (a + B) MOD 5 IF c = 1 THEN LOCATE B, 80 PRINT "Ü"; LOCATE 23 - B, 1 PRINT "Ü"; ELSE LOCATE B, 80 PRINT " "; LOCATE 23 - B, 1 PRINT " "; END IF NEXT B NEXT a WEND END SUB
Convierte un archivo .PIN en un archivo .LIB (“biblioteca”), que puede ser interpretado después como una tipografía. El uso es un poco críptico. Se pide un archivo .PIN y hay que señalar (con las teclas del cursor, porque por aquel entonces yo no sabía usar el ratón con QBASIC) qué zona corresponde a cada “letra”.
En su estado actual, el programa está configurado para actuar “automáticamente”, sin intervención del usuario. Para que pregunte al usuario (en vez de tomar el ancho y el alto predeterminados), hay que cambiar este código:
'Esta L¡nea para modo manual: 'LEETECLAS 'Estas L¡nea para modo autom tico: XINI = 0 'Inicio de X YINI = -8 'Inicio de Y XFIN = 640 YFIN = 480 XANCHO = 16 'Ancho de X YANCHO = 48 'Ancho de Y XAVANCE = 24 YAVANCE = 48
Por este otro:
'Esta L¡nea para modo manual: LEETECLAS 'Estas L¡nea para modo autom tico: ' XINI = 0 'Inicio de X ' YINI = -8 'Inicio de Y ' XFIN = 640 ' YFIN = 480 ' XANCHO = 16 'Ancho de X ' YANCHO = 48 'Ancho de Y ' XAVANCE = 24 ' YAVANCE = 48
DECLARE SUB LEETECLAS () DECLARE SUB ALMACENA (ANTX!, ANTY!, XAC!, YAC!, A$) DECLARE SUB GRABAR (A$) DECLARE FUNCTION INCLUIDO! (A!, INICIO!, FIN!) DECLARE SUB Cargar (A$) DECLARE SUB Ejecuta (TRAD$) DECLARE SUB RePintar () DECLARE FUNCTION MAX! (A!, B!) DIM SHARED PMATRIZ DIM SHARED MATRIZ$(200) DIM SHARED MAT2$(200) 'Matriz ordenada por grupos. DIM SHARED PMAT2%(100) 'N£mero de instrucciones de cada grupo. DIM SHARED INIMAT2%(100) 'Posicion de inicio del grupo en MAT2$. DIM SHARED NMAT2$(100) 'Nombre del grupo. DIM SHARED PNOMB% 'Grupo actual. SCREEN 12 RX = 1: RY = 1 Col = 7 ON ERROR GOTO ERRORMAN FILES "*.PIN" ON ERROR GOTO 0 INPUT "Escriba el nombre del archivo a cargar"; A$ Cargar A$ CLS RePintar 'Esta L¡nea para modo manual: 'LEETECLAS 'Estas L¡nea para modo autom tico: XINI = 0 'Inicio de X YINI = -8 'Inicio de Y XFIN = 640 YFIN = 480 XANCHO = 16 'Ancho de X YANCHO = 48 'Ancho de Y XAVANCE = 24 YAVANCE = 48 XAC = XINI YAC = YINI DO LINE (XAC, YAC)-(XAC + XANCHO, YAC + YANCHO), , B LOCATE 21, 1 VALIDO = 0 DO UNTIL VALIDO INPUT "¨Incluir en archivo?"; A$ VALIDO = -1 SELECT CASE UCASE$(MID$(A$, 1, 1)) CASE "S" INPUT "¨Nombre?"; N$ LINE (XAC, YAC)-(XAC + XANCHO, YAC + YANCHO), 0, B ALMACENA XAC, YAC, XAC + XANCHO, YAC + YANCHO, N$ CASE "N" LINE (XAC, YAC)-(XAC + XANCHO, YAC + YANCHO), 0, B CASE ELSE: VALIDO = 0 END SELECT LOOP XAC = XAC + XAVANCE IF XAC > XFIN THEN YAC = YAC + YAVANCE: XAC = XINI IF YAC > YFIN THEN EXIT DO 'RePintar LOOP ON ERROR GOTO ERRORMAN FILES "*.LIB" ON ERROR GOTO 0 INPUT "Introduzca el nombre del archivo .LIB"; A$ GRABAR A$ RePintar END ERRORMAN: SELECT CASE ERR CASE 53 RESUME NEXT END SELECT RESUME SUB ALMACENA (X1, Y1, X2, Y2, A$) SHARED XP, YP, RX, RY, Col NMAT2$(PNOMB%) = A$ IF X1 > X2 THEN MAXX = X1: MINX = X2 ELSE MINX = X1: MAXX = X2 IF Y1 > Y2 THEN MAXY = Y1: MINY = Y2 ELSE MINY = Y1: MAXY = Y2 FOR F = 0 TO PMATRIZ - 1 TRAD$ = MATRIZ$(F) SELECT CASE MID$(TRAD$, 1, 2) CASE CHR$(0) + CHR$(1), CHR$(0) + CHR$(2), CHR$(0) + CHR$(3) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) a1 = INCLUIDO(ANTX, MINX, MAXX) a2 = INCLUIDO(ANTY, MINY, MAXY) a3 = INCLUIDO(Y, MINY, MAXY) a4 = INCLUIDO(Y, MINY, MAXY) IF a1 AND a2 AND a3 AND a4 THEN SELECT CASE MID$(TRAD$, 2, 1) CASE CHR$(1): LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), 15 CASE CHR$(2): LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), 15, B CASE CHR$(3): LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), 15, BF END SELECT 'PLAY "l16 n8 n13 n17 n20 n20 n20 n17 n17 n17 n13 n17 n13 l8 n8" ANTX = ANTX - MINX X = X - MINX ANTY = ANTY - MINY Y = Y - MINY TRAD$ = CHR$(0) + MID$(TRAD$, 2, 1) + MKI$(ANTX) + MKI$(ANTY) + MKI$(X) + MKI$(Y) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 END IF CASE CHR$(0) + CHR$(4) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) a1 = ANTX - RADIO >= MINX a2 = ANTY - RADIO >= MINY a1 = ANTX + RADIO >= MAXX a2 = ANTY + RADIO >= MAXY IF a1 AND a2 AND a3 AND a4 THEN CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, 15, , , RY / RX ANTX = ANTX - MINX ANTY = ANTY - MINY TRAD$ = CHR$(0) + CHR$(4) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 END IF CASE CHR$(0) + CHR$(5) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) ANG = CVS(MID$(TRAD$, 9, 4)) ANG2 = CVS(MID$(TRAD$, 13, 4)) a1 = ANTX - RADIO >= MINX a2 = ANTY - RADIO >= MINY a3 = ANTX + RADIO <= MAXX a4 = ANTY + RADIO <= MAXY IF a1 AND a2 AND a3 AND a4 THEN CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, 15, ANG, ANG2, RY / RX 'PLAY "MBo3L8ED+ED+Eo2Bo3DCL2o2A" ANTX = ANTX - MINX ANTY = ANTY - MINY TRAD$ = CHR$(0) + CHR$(5) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) + MKS$(ANG) + MKS$(ANG2) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 ELSEIF INCLUIDO(ANTX, MINX, MAXX) AND INCLUIDO(ANTY, MINY, MAXY) THEN DO LOCATE 24, 1: PRINT "¨Se sale de la zona seleccionada el arco parpadeante?" LOCATE 25, 1: PRINT "Pulse '1' en ese caso, o '0' en caso contrario" CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, 15, ANG, ANG2, RY / RX SLEEP 1 CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, 0, ANG, ANG2, RY / RX IN$ = INKEY$ IF IN$ = "1" THEN EXIT DO IF IN$ = "0" THEN ANTX = ANTX - MINX ANTY = ANTY - MINY TRAD$ = CHR$(0) + CHR$(5) + MKI$(ANTX) + MKI$(ANTY) + MKI$(RADIO) + MKS$(ANG) + MKS$(ANG2) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 EXIT DO END IF LOOP END IF CASE CHR$(0) + CHR$(6) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) PAINT (ANTX, ANTY), Col, Col IF INCLUIDO(ANTX, MINX, MAXX) AND INCLUIDO(ANTY, MINY, MAXY) THEN ANTX = ANTX - MINX ANTY = ANTY - MINY TRAD$ = CHR$(0) + CHR$(6) + MKI$(ANTX) + MKI$(ANTY) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 END IF CASE CHR$(0) + CHR$(7) 'Col = ASC(MID$(TRAD$, 3, 1)) TRAD$ = CHR$(0) + CHR$(7) MAT2$(INIMAT2%(PNOMB%) + PMAT2%(PNOMB%)) = TRAD$ PMAT2%(PNOMB%) = PMAT2%(PNOMB%) + 1 END SELECT NEXT INIMAT2%(PNOMB% + 1) = INIMAT2%(PNOMB%) + PMAT2%(PNOMB%) PNOMB% = PNOMB% + 1 END SUB SUB Cargar (A$) SHARED MATRIZ$(), PMATRIZ IF INSTR(A$, ".") < 1 THEN A$ = A$ + ".PIN" OPEN A$ FOR BINARY AS #1 CABE$ = INPUT$(11, #1) IF CABE$ <> "JMYPINTOR00" THEN EXIT SUB GET 1, , PMATRIZ FOR F = 0 TO PMATRIZ GET 1, , L MATRIZ$(F) = INPUT$(L, #1) NEXT CLOSE #1 RePintar END SUB SUB Ejecuta (TRAD$) SHARED XP, YP, RX, RY, Col SELECT CASE MID$(TRAD$, 1, 2) CASE CHR$(0) + CHR$(1) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), Col CASE CHR$(0) + CHR$(2) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), Col, B CASE CHR$(0) + CHR$(3) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + XP)-(X * RX + XP, Y * RY + YP), Col, BF CASE CHR$(0) + CHR$(4) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) CIRCLE (ANTX * RX + XP, ANTY * RY + XP), MAX(RX, RY) * RADIO, Col, , , RY / RX CASE CHR$(0) + CHR$(5) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) ANG = CVS(MID$(TRAD$, 9, 4)) ANG2 = CVS(MID$(TRAD$, 13, 4)) CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, Col, ANG, ANG2, RY / RX CASE CHR$(0) + CHR$(6) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) PAINT (ANTX, ANTY), Col, Col CASE CHR$(0) + CHR$(7) Col = ASC(MID$(TRAD$, 3, 1)) END SELECT END SUB SUB GRABAR (A$) IF INSTR(A$, ".") < 1 THEN A$ = A$ + ".LIB" OPEN A$ FOR BINARY AS #1 W$ = "JMYPINLIB00" PUT #1, , W$ PUT #1, , PNOMB% FOR F = 0 TO PNOMB% LONNOMB% = LEN(NMAT2$(F)) PUT #1, , LONNOMB% PUT #1, , NMAT2$(F) PUT #1, , INIMAT2%(F) PUT #1, , PMAT2%(F) NEXT FOR F = 0 TO PNOMB% FOR CMD = 0 TO PMAT2%(F) Longit% = LEN(MAT2$(INIMAT2%(F) + CMD)) PUT #1, , Longit% PUT #1, , MAT2$(INIMAT2%(F) + CMD) NEXT FIN$ = "##" 'Verificacion de final. PUT #1, , FIN$ NEXT END SUB FUNCTION INCLUIDO (A, INICIO, FIN) IF A >= INICIO AND A <= FIN THEN INCLUIDO = -1: EXIT FUNCTION IF A > FIN THEN INCLUIDO = 0: EXIT FUNCTION IF A < INICIO THEN INCLUIDO = 0: EXIT FUNCTION INCLUIDO = -1 END FUNCTION SUB LEETECLAS SHARED ANTESTADO, ESTADO, ANTX, ANTY, XAC, YAC IF PASO = 0 THEN PASO = 1 DO DO: IN$ = INKEY$: LOOP UNTIL IN$ > "" IF ANTESTADO = ESTADO THEN IF ANTESTADO = 0 THEN LINE (XAC - 8, YAC)-(XAC + 8, YAC), 0 LINE (XAC, YAC - 8)-(XAC, YAC + 8), 0 ELSE LINE (XAC, YAC)-(ANTX, ANTY), 0, B END IF END IF ANTESTADO = ESTADO SELECT CASE IN$ CASE "+" PASO = PASO + 1 CASE "-" PASO = PASO - 1 CASE CHR$(0) + "H" YAC = YAC - PASO CASE CHR$(0) + "P" YAC = YAC + PASO CASE CHR$(0) + "K" XAC = XAC - PASO CASE CHR$(0) + "M" XAC = XAC + PASO CASE CHR$(27) ESTADO = 0 CASE " " RePintar CASE "G", "g" ON ERROR GOTO ERRORMAN FILES "*.LIB" ON ERROR GOTO 0 INPUT "Introduzca el nombre del archivo .LIB"; A$ GRABAR A$ RePintar CASE CHR$(13) SELECT CASE ESTADO CASE 0 ANTX = XAC ANTY = YAC ESTADO = 1 CASE 1 INPUT "NOMBRE?"; A$ ALMACENA ANTX, ANTY, XAC, YAC, A$ ESTADO = 0 END SELECT RePintar END SELECT IF ESTADO = 0 THEN LINE (XAC - 8, YAC)-(XAC + 8, YAC) LINE (XAC, YAC - 8)-(XAC, YAC + 8) ELSE LINE (XAC, YAC)-(ANTX, ANTY), , B, &HF0F0 END IF LOCATE 25, 1: PRINT USING "X:#### Y:#### PASO:####"; X; Y; PASO LOOP END SUB FUNCTION MAX (A, B) IF A > B THEN MAX = A ELSE MAX = B END FUNCTION SUB RePintar CLS FOR F = 0 TO PMATRIZ - 1 Ejecuta (MATRIZ$(F)) NEXT END SUB
Este programa interpreta un como “tipografía” un archivo .LIB creado por PIN2LIB, y permite escribir un cartel. Se puede indicar un multiplicador de ancho y de alto, y una columna y fila inicial.
Téngase en cuenta que la línea y columna inicial están expresadas en píxeles, no en letras.
Para poderlo probar, necesitaría un archivo .LIB, por ejemplo ABCD.LIB, incluido en este archivo: qb-pinta
DECLARE SUB escribe (w$) DECLARE SUB CARGAR (A$) DECLARE SUB EJECUTA (TRAD$) DECLARE FUNCTION MAX! (A!, B!) DIM SHARED MAT2$(200) 'Matriz ordenada por grupos. DIM SHARED PMAT2%(100) 'N£mero de instrucciones de cada grupo. DIM SHARED inimat2%(100) 'Posicion de inicio del grupo en MAT2$. DIM SHARED NMAT2$(100) 'Nombre del grupo. DIM SHARED PNOMB% 'Grupo actual. SCREEN 12 RX = 2: RY = 1 DespX1 = 32: DespX = DespX1 DespY1 = 64: DespY = DespY1 Col = 7 ON ERROR GOTO ERRORMAN FILES "*.LIB" ON ERROR GOTO 0 INPUT "Escriba el nombre del archivo a cargar"; A$ CARGAR A$ CLS DO LOCATE 28, 1: INPUT "Introduzca una frase"; w$ LOCATE 28, 1: PRINT SPACE$(80); LOCATE 28, 1: INPUT "¨Tama¤o de x?"; RX LOCATE 28, 1: PRINT SPACE$(80); LOCATE 28, 1: INPUT "¨Tama¤o de y?"; RY LOCATE 28, 1: PRINT SPACE$(80); LOCATE 28, 1: INPUT "¨Espaciado de x?"; XD2 DespX = DespX1 * XD2 LOCATE 28, 1: PRINT SPACE$(80) LOCATE 28, 1: INPUT "¨Espaciado de y?"; YD2 DespY = DespY1 * YD2 LOCATE 28, 1: PRINT SPACE$(80) LOCATE 28, 1: INPUT "¨Columna inicial?"; XP LOCATE 28, 1: PRINT SPACE$(80) LOCATE 28, 1: INPUT "¨Fila inicial?"; YP escribe (w$) LOCATE 28, 1: PRINT SPACE$(80) LOCATE 28, 1: INPUT "¨Borrar?"; Y$ IF UCASE$(MID$(Y$, 1, 1)) = "Y" OR MID$(Y$, 1, 1) = "S" THEN CLS LOOP END ERRORMAN: SELECT CASE ERR CASE 53 RESUME NEXT END SELECT RESUME SUB CARGAR (A$) IF INSTR(A$, ".") < 1 THEN A$ = A$ + ".LIB" OPEN A$ FOR BINARY AS #1 w$ = INPUT$(11, 1) IF w$ <> "JMYPINLIB00" THEN PRINT "No es un archivo v lido de la versi¢n 0" GET #1, , PNOMB% FOR F = 0 TO PNOMB% LONNOMB% = LEN(NMAT2$(F)) GET #1, , LONNOMB% NMAT2$(F) = INPUT$(LONNOMB%, 1) GET #1, , inimat2%(F) GET #1, , PMAT2%(F) NEXT FOR F = 0 TO PNOMB% FOR CMD = 0 TO PMAT2%(F) GET #1, , Longitud% MAT2$(inimat2%(F) + CMD) = INPUT$(Longitud%, 1) NEXT FIN$ = INPUT$(2, 1) IF FIN$ <> "##" THEN PRINT "Longitud de registro err¢nea" 'Verificacion de final. PRINT FIN$ END IF NEXT END SUB SUB EJECUTA (TRAD$) SHARED XP, YP, RX, RY, Col SELECT CASE MID$(TRAD$, 1, 2) CASE CHR$(0) + CHR$(1) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + YP)-(X * RX + XP, Y * RY + YP), Col CASE CHR$(0) + CHR$(2) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + YP)-(X * RX + XP, Y * RY + YP), Col, B CASE CHR$(0) + CHR$(3) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) X = CVI(MID$(TRAD$, 7, 2)) Y = CVI(MID$(TRAD$, 9, 2)) LINE (ANTX * RX + XP, ANTY * RY + YP)-(X * RX + XP, Y * RY + YP), Col, BF CASE CHR$(0) + CHR$(4) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, Col, , , RY / RX CASE CHR$(0) + CHR$(5) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) RADIO = CVI(MID$(TRAD$, 7, 2)) ANG = CVS(MID$(TRAD$, 9, 4)) ANG2 = CVS(MID$(TRAD$, 13, 4)) CIRCLE (ANTX * RX + XP, ANTY * RY + YP), MAX(RX, RY) * RADIO, Col, ANG, ANG2, RY / RX CASE CHR$(0) + CHR$(6) ANTX = CVI(MID$(TRAD$, 3, 2)) ANTY = CVI(MID$(TRAD$, 5, 2)) PAINT (ANTX, ANTY), Col, Col CASE CHR$(0) + CHR$(7) Col = ASC(MID$(TRAD$, 3, 1)) END SELECT END SUB SUB escribe (w$) SHARED XP, YP, DespX, DespY FOR F = 1 TO LEN(w$) L$ = MID$(w$, F, 1) IF L$ = CHR$(0) THEN I = INSTR(F + 1, L$, CHR$(0)) IF I = 0 THEN I = LEN(w$) L$ = MID$(w$, F + 1, INSTR(F + 1, L$, CHR$(0)) - F) F = I END IF FOR G = 0 TO 100 IF NMAT2$(G) = L$ THEN FOR H = inimat2%(G) TO inimat2%(G) + PMAT2%(G) - 1 EJECUTA MAT2$(H) NEXT XP = XP + DespX IF XP > 640 THEN XP = 0: YP = YP + DespY EXIT FOR END IF NEXT NEXT END SUB FUNCTION MAX (A, B) IF A > B THEN MAX = A ELSE MAX = B END FUNCTION