commit 63fd346c866853e480b7adb929db120dd1c8b75b Author: jdg Date: Wed Sep 8 21:41:03 2021 +0200 First commit 01/01/1993 diff --git a/COMIX.FNT b/COMIX.FNT new file mode 100644 index 0000000..95b19cd Binary files /dev/null and b/COMIX.FNT differ diff --git a/ESPIRAL.BAK b/ESPIRAL.BAK new file mode 100644 index 0000000..5899332 --- /dev/null +++ b/ESPIRAL.BAK @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +char far *VidRam = MK_FP( 0xA000, 0); + +typedef struct + { + int x, y; + char ndigitos; + char AX, AY; + unsigned char C1, C2, C3; + } p_graphics; + +char Reverse = 0; + +void Letras_en_espiral( char *Frase, p_graphics *FA ); +void writepixel( int x, int y, char color ); +void asigna_modo_video(char modo); /* asigna el modo de v¡deo indicado */ +void LeeFuentes(char *file); + +char *ptr_char; +double grad, pi; + double ia=3; /*incremento  ngulo*/ + double ir=0.3; /*incremento radio*/ + int key; + +void main( int argc, char *argv[] ) +{ + clock_t tiempo; + char up_down = 1; + + char Texto[255]; + /* .. */ + p_graphics Text1 = { 0, 84, 48, 1, 1, 0, 15, 15 }; + + pi = 4.0*atan(1.0); + grad = pi/180.0; + +if( argc != 2 ) + strcpy( Texto, "<-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL -->" ); +else + strcpy( Texto, argv[2] ); + +if( argc != 3 ) LeeFuentes("comix.fnt"); else LeeFuentes(argv[1]); + + + /* Load Mod, and begin to play... */ + + + /* While Sound up, J&D down and up until BOOM!! */ + + + /* When 2nd BOOM!! will sound, J&D was join and change VidMode */ + + asigna_modo_video(0x13); + /* Swap to graphic mode and show TextSpiral while background is flicking */ +/* + tiempo = clock() / CLK_TCK; + while( ( (clock()/CLK_TCK) - tiempo) <= 15 && !kbhit()) + Letras_en_espiral( Texto, &Text1 ); +*/ + ia += 30; + + while( 1 ) + { + delay(50); + + if ( kbhit() ) + { + + if( (key=getch()) == 27 ) break; + else + { +/* memset( VidRam, 0, 64000);*/ + Text1.C1 = 255; + Letras_en_espiral( Texto, &Text1 ); +Text1.C1 = 0; + switch( key ) + { + case 'r': + case 'R': + Reverse = !Reverse; + break; + case 'a': + case 'A': + ia += 0.5; + break; + case 's': + case 'S': + ia -=0.5; + break; + case 'z': + case 'Z': + ir +=0.5; + break; + case 'x': + case 'X': + ir -=0.5; + break; + } + } + } + Text1.C1 = 255; + Letras_en_espiral( Texto, &Text1 ); + Text1.C1 = 0; + /* ia 3 __ -3.5 */ + if ( up_down==1 ) ia -= 0.1; + else ia += 0.1; + if ( ia <= -3.5 ) up_down = 0; + if ( ia >= 3 ) up_down = 1; + + + /* Letras_en_espiral( "abcdefghijklmn¤opqrstuvwxyz ABCDEFGHIJKLMN¥OPQRSTU... 0123456789", &Text1 );*/ + Letras_en_espiral( Texto, &Text1 ); + } + + asigna_modo_video(0x3); + printf("La fuente utilizada fue: %s\n", argv[2]); + getch(); + free(ptr_char); + +} + + + + +void Letras_en_espiral( char *Frase, p_graphics *FA ) +{ +static char vez_ptr = 0; + +static char FraseBit[110][16]; +static char Frase1[100]; +static unsigned int Flen; +static char Flen1; +static char RLen; + +char cont; +int i; +char j, j1; + + char c_elec; + char bit_s; + char *Frase_seg; + + char FrBit_tmp[16]; + unsigned seg, off; +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + double r; /*radio*/ +/* double ia; */ /*incremento  ngulo*/ +/* double ir;*/ /*incremento radio*/ + double s,c; /*seno y coseno actuales <2>*/ + double ca; /*coseno anterior*/ + double isin,icos; /*incremento seno y coseno*/ + int x,y; +/* + ia = 3; + ir = 0.3; +*/ + isin = sin(ia*grad); + icos = cos(ia*grad); + r = 0.0; /*parte del centro*/ + s = sin(0.0); /*con  ngulo 0 grados*/ + c = cos(0.0); +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + + Frase_seg = Frase1; + +if ( !vez_ptr ) + { + vez_ptr = 1; + /* Now, we going to get 8x8 Font dir. */ +/* + asm mov AH, 0x11 + asm mov AL, 0x30 + asm mov BH, 0x03 + asm int 0x10 + asm mov seg, ES + asm mov off, BP +*/ + } + +if ( strcmp( Frase1, Frase ) != 0 ) + { + strncpy( Frase1, Frase, 99 ); + Frase1[99] = '\0'; + j = i = strlen( Frase ); + Flen = i * 8; + cont = 0; + + if ( i < FA -> ndigitos ) + i += FA -> ndigitos - i; + else + i += 5; + + Flen1 = i; + +/* // Almacenamos en la Frase a Bit's la FRASE A BIT'S */ + while( cont <= i ) + { +/* // Descomponemos cada caracter en un patron de BIT's */ + if ( (cont - j) > 0 ) + { + FraseBit[cont][0] = 0x00; FraseBit[cont][1] = 0x00; + FraseBit[cont][2] = 0x00; FraseBit[cont][3] = 0x00; + FraseBit[cont][4] = 0x00; FraseBit[cont][5] = 0x00; + FraseBit[cont][6] = 0x00; FraseBit[cont][7] = 0x00; + } else { + for( j1=0; j1<16; j1++) + FraseBit[cont][j1]= ptr_char[ ( *Frase_seg ) * 16 + j1 ]; + } + cont++; + Frase_seg++; + } + } else { +/* + // Rotamos la frase + // Almacenamos el 1er bit que vamos a perder... +*/ + for ( j1=0; j1<16; j1++ ) + FrBit_tmp[j1] = 0x01 & ( FraseBit[0][j1] >> 7 ); + + for ( j=0; j> 7 ) ); + } + for ( j1=0; j1<16; j1++ ) + FraseBit[Flen1-1][j1] = ( FraseBit[Flen1-1][j1] & 0xFE ) | FrBit_tmp[j1]; + } + +/*// ndigitos --> m x. = 40*/ + for ( i=0; i < FA->ndigitos; i ++ ) + { + for ( j=0, j1=0; j1<8; j+=2*FA->AX, j1++ ) + { +/* + // Analizamos el patron de BIT's y lo imprimimos + // FraseBit[cont][0] + // ^ ^----- N£mero de byte del digito ( 8x8 ) + // |_________ N£mero de digito alfa-numerico +*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + if( r < 250 ) + { + ca = c; + + c = c*icos-s*isin; + s = s*icos+ca*isin; + x = 160+(int)(floor(r*c*1.2+0.5)); + y = 100+(int)(floor(r*s+0.5)); + + r += ir; + } + +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + for ( bit_s = 0; bit_s < 16; bit_s++ ) + { + if ( FraseBit[i][bit_s] & ( (char)0x01 << (7-j1) ) ) c_elec = FA->C2; else c_elec = FA->C1; +/* writepixel( ( FA->x + j + i*8*2*FA->AX ), ( FA->y + 2*bit_s*FA->AY ), c_elec );*/ + + if( !Reverse ) + { + if ( c_elec == FA->C2 ) c_elec = r; + } else { + if ( c_elec == FA->C1 ) c_elec = r; + else + c_elec = FA->C1; + } + if ( FA->C1==255 ) c_elec=0; + /* writepixel( x,y+bit_s*2, c_elec ); */writepixel( x, y+bit_s*2, c_elec ); + } + } + } + +} + + +void writepixel( int x, int y, char color ) + { + if ( x>=0 && x<320 && y>=0 && y<200 ) + *(VidRam + (x + y*320) ) = color; + } + +void asigna_modo_video(char modo) /* asigna el modo de v¡deo indicado */ +{ /* en la variable "modo" */ + union REGS ent, sal; + + ent.h.al = modo; + ent.h.ah = 0; + int86(16, &ent, &sal); /* funci¢n para asignar el modo de video */ +} + +void LeeFuentes(char *file) +{ +FILE *fich; + /* Reservamos 4 Kb. para cargar la fuente en memoria */ + + if((ptr_char=(char *)malloc(4096))==NULL) { + printf("­­ No hay suficiente memoria !!\n"); + exit (1); + } + + /* Abrimos el fichero de la fuente */ + + if ((fich=fopen(file,"rb"))==NULL) { + printf("\a\nArchivo %s no encontrado.\n",file); + free(ptr_char); + exit(1); + } + + fseek(fich, SEEK_SET, 0); /* Nos colocamos al principio del fichero */ + fread(ptr_char,1,4096,fich); /* Cargamos en memoria 4096 bytes del fichero */ + fclose(fich); /* Cerramos el fichero */ +} + + + diff --git a/ESPIRAL.C b/ESPIRAL.C new file mode 100644 index 0000000..586be8f --- /dev/null +++ b/ESPIRAL.C @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +char far *VidRam = MK_FP( 0xA000, 0); + +typedef struct + { + int x, y; + char ndigitos; + char AX, AY; + unsigned char C1, C2, C3; + } p_graphics; + +char Reverse = 0; + +void Letras_en_espiral( char *Frase, p_graphics *FA ); +void writepixel( int x, int y, char color ); +void asigna_modo_video(char modo); /* asigna el modo de v¡deo indicado */ +void LeeFuentes(char *file); + +char *ptr_char; +double grad, pi; + double ia=3; /*incremento  ngulo*/ + double ir=0.3; /*incremento radio*/ + int key; + +void main( int argc, char *argv[] ) +{ + clock_t tiempo; + char up_down = 1; + + char Texto[255]; + /* .. */ + p_graphics Text1 = { 0, 84, 48, 1, 1, 0, 15, 15 }; + + pi = 4.0*atan(1.0); + grad = pi/180.0; + +if( argc != 2 ) + strcpy( Texto, "<-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL --><-- ESPIRAL -->" ); +else + strcpy( Texto, argv[2] ); + +if( argc != 3 ) LeeFuentes("comix.fnt"); else LeeFuentes(argv[2]); + + + /* Load Mod, and begin to play... */ + + + /* While Sound up, J&D down and up until BOOM!! */ + + + /* When 2nd BOOM!! will sound, J&D was join and change VidMode */ + + asigna_modo_video(0x13); + /* Swap to graphic mode and show TextSpiral while background is flicking */ +/* + tiempo = clock() / CLK_TCK; + while( ( (clock()/CLK_TCK) - tiempo) <= 15 && !kbhit()) + Letras_en_espiral( Texto, &Text1 ); +*/ + ia += 30; + + while( 1 ) + { + delay(50); + + if ( kbhit() ) + { + + if( (key=getch()) == 27 ) break; + else + { +/* memset( VidRam, 0, 64000);*/ + Text1.C1 = 255; + Letras_en_espiral( Texto, &Text1 ); +Text1.C1 = 0; + switch( key ) + { + case 'r': + case 'R': + Reverse = !Reverse; + break; + case 'a': + case 'A': + ia += 0.5; + break; + case 's': + case 'S': + ia -=0.5; + break; + case 'z': + case 'Z': + ir +=0.5; + break; + case 'x': + case 'X': + ir -=0.5; + break; + } + } + } + Text1.C1 = 255; + Letras_en_espiral( Texto, &Text1 ); + Text1.C1 = 0; + /* ia 3 __ -3.5 */ + if ( up_down==1 ) ia -= 0.1; + else ia += 0.1; + if ( ia <= -3.5 ) up_down = 0; + if ( ia >= 3 ) up_down = 1; + + + /* Letras_en_espiral( "abcdefghijklmn¤opqrstuvwxyz ABCDEFGHIJKLMN¥OPQRSTU... 0123456789", &Text1 );*/ + Letras_en_espiral( Texto, &Text1 ); + } + + asigna_modo_video(0x3); + printf("La fuente utilizada fue: %s\n", argv[2]); + getch(); + free(ptr_char); + +} + + + + +void Letras_en_espiral( char *Frase, p_graphics *FA ) +{ +static char vez_ptr = 0; + +static char FraseBit[110][16]; +static char Frase1[100]; +static unsigned int Flen; +static char Flen1; +static char RLen; + +char cont; +int i; +char j, j1; + + char c_elec; + char bit_s; + char *Frase_seg; + + char FrBit_tmp[16]; + unsigned seg, off; +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + double r; /*radio*/ +/* double ia; */ /*incremento  ngulo*/ +/* double ir;*/ /*incremento radio*/ + double s,c; /*seno y coseno actuales <2>*/ + double ca; /*coseno anterior*/ + double isin,icos; /*incremento seno y coseno*/ + int x,y; +/* + ia = 3; + ir = 0.3; +*/ + isin = sin(ia*grad); + icos = cos(ia*grad); + r = 0.0; /*parte del centro*/ + s = sin(0.0); /*con  ngulo 0 grados*/ + c = cos(0.0); +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + + Frase_seg = Frase1; + +if ( !vez_ptr ) + { + vez_ptr = 1; + /* Now, we going to get 8x8 Font dir. */ +/* + asm mov AH, 0x11 + asm mov AL, 0x30 + asm mov BH, 0x03 + asm int 0x10 + asm mov seg, ES + asm mov off, BP +*/ + } + +if ( strcmp( Frase1, Frase ) != 0 ) + { + strncpy( Frase1, Frase, 99 ); + Frase1[99] = '\0'; + j = i = strlen( Frase ); + Flen = i * 8; + cont = 0; + + if ( i < FA -> ndigitos ) + i += FA -> ndigitos - i; + else + i += 5; + + Flen1 = i; + +/* // Almacenamos en la Frase a Bit's la FRASE A BIT'S */ + while( cont <= i ) + { +/* // Descomponemos cada caracter en un patron de BIT's */ + if ( (cont - j) > 0 ) + { + FraseBit[cont][0] = 0x00; FraseBit[cont][1] = 0x00; + FraseBit[cont][2] = 0x00; FraseBit[cont][3] = 0x00; + FraseBit[cont][4] = 0x00; FraseBit[cont][5] = 0x00; + FraseBit[cont][6] = 0x00; FraseBit[cont][7] = 0x00; + } else { + for( j1=0; j1<16; j1++) + FraseBit[cont][j1]= ptr_char[ ( *Frase_seg ) * 16 + j1 ]; + } + cont++; + Frase_seg++; + } + } else { +/* + // Rotamos la frase + // Almacenamos el 1er bit que vamos a perder... +*/ + for ( j1=0; j1<16; j1++ ) + FrBit_tmp[j1] = 0x01 & ( FraseBit[0][j1] >> 7 ); + + for ( j=0; j> 7 ) ); + } + for ( j1=0; j1<16; j1++ ) + FraseBit[Flen1-1][j1] = ( FraseBit[Flen1-1][j1] & 0xFE ) | FrBit_tmp[j1]; + } + +/*// ndigitos --> m x. = 40*/ + for ( i=0; i < FA->ndigitos; i ++ ) + { + for ( j=0, j1=0; j1<8; j+=2*FA->AX, j1++ ) + { +/* + // Analizamos el patron de BIT's y lo imprimimos + // FraseBit[cont][0] + // ^ ^----- N£mero de byte del digito ( 8x8 ) + // |_________ N£mero de digito alfa-numerico +*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + if( r < 250 ) + { + ca = c; + + c = c*icos-s*isin; + s = s*icos+ca*isin; + x = 160+(int)(floor(r*c*1.2+0.5)); + y = 100+(int)(floor(r*s+0.5)); + + r += ir; + } + +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ +/*ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ*/ + for ( bit_s = 0; bit_s < 16; bit_s++ ) + { + if ( FraseBit[i][bit_s] & ( (char)0x01 << (7-j1) ) ) c_elec = FA->C2; else c_elec = FA->C1; +/* writepixel( ( FA->x + j + i*8*2*FA->AX ), ( FA->y + 2*bit_s*FA->AY ), c_elec );*/ + + if( !Reverse ) + { + if ( c_elec == FA->C2 ) c_elec = r; + } else { + if ( c_elec == FA->C1 ) c_elec = r; + else + c_elec = FA->C1; + } + if ( FA->C1==255 ) c_elec=0; + /* writepixel( x,y+bit_s*2, c_elec ); */writepixel( x, y+bit_s*2, c_elec ); + } + } + } + +} + + +void writepixel( int x, int y, char color ) + { + if ( x>=0 && x<320 && y>=0 && y<200 ) + *(VidRam + (x + y*320) ) = color; + } + +void asigna_modo_video(char modo) /* asigna el modo de v¡deo indicado */ +{ /* en la variable "modo" */ + union REGS ent, sal; + + ent.h.al = modo; + ent.h.ah = 0; + int86(16, &ent, &sal); /* funci¢n para asignar el modo de video */ +} + +void LeeFuentes(char *file) +{ +FILE *fich; + /* Reservamos 4 Kb. para cargar la fuente en memoria */ + + if((ptr_char=(char *)malloc(4096))==NULL) { + printf("­­ No hay suficiente memoria !!\n"); + exit (1); + } + + /* Abrimos el fichero de la fuente */ + + if ((fich=fopen(file,"rb"))==NULL) { + printf("\a\nArchivo %s no encontrado.\n",file); + free(ptr_char); + exit(1); + } + + fseek(fich, SEEK_SET, 0); /* Nos colocamos al principio del fichero */ + fread(ptr_char,1,4096,fich); /* Cargamos en memoria 4096 bytes del fichero */ + fclose(fich); /* Cerramos el fichero */ +} + + + diff --git a/ESPIRAL.EXE b/ESPIRAL.EXE new file mode 100644 index 0000000..98cd50e Binary files /dev/null and b/ESPIRAL.EXE differ diff --git a/ESPIRAL.OBJ b/ESPIRAL.OBJ new file mode 100644 index 0000000..edfd13c Binary files /dev/null and b/ESPIRAL.OBJ differ diff --git a/FLAT.FNT b/FLAT.FNT new file mode 100644 index 0000000..3c011ae Binary files /dev/null and b/FLAT.FNT differ diff --git a/HELVET.FNT b/HELVET.FNT new file mode 100644 index 0000000..c48c33c Binary files /dev/null and b/HELVET.FNT differ diff --git a/MODERN.FNT b/MODERN.FNT new file mode 100644 index 0000000..3f35e89 Binary files /dev/null and b/MODERN.FNT differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..f778269 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +#SPIRAL + + +*01/01/1993* + +ToDo: wwtcf? + + +![screenshot](/SPIRAL.png "Screenshot") diff --git a/S.C b/S.C new file mode 100644 index 0000000..d67e8a1 --- /dev/null +++ b/S.C @@ -0,0 +1,361 @@ +/* + Este programa forma parte del Curso de C + Copyright (C) 1991 Grupo Editorial Jackson + Todos los derechos reservados +*/ + + +/* ESPIRAL: dibuja espirales poligonales aleatorias */ + + +/* NOTA: tambi‚n este fichero, como REBOTE.C, contiene dos programas + distintos, el primero escrito con las funciones gr ficas de Turbo C + 2.0 y el segundo con las de Quick C 2.0. La opci¢n es autom tica + con una instrucci¢n #ifdef. + + Este sistema comienza a resultar demasiado inc¢modo: en la lecci¢n + E5 se explica c¢mo crear una 'librer¡a' de funciones gr ficas + port til, parecida a la librer¡a Jconio, empleada para las funciones + de consola. +*/ + + +/*========================= Versi¢n para Turbo C 2.0 ======================*/ + +#ifdef __TURBOC__ + + +#include +#include +#include +#include +#include + + +/* constantes y variables globales */ + +#define PAUSA 3 /*3 segundos de pausa entre espirales*/ + +int maxcol; /*l¡mite de colores*/ +int centroX; /*coordenadas del centro de la pantalla*/ +int centroY; +double cuadra; /*factor de cuadratura*/ +double pi; /*n£mero pi*/ +double grad; /*constante de conversi¢n grados/radianes*/ + + +/* prototipos de funciones: */ + +void Espiral(void); + + +/******************************************************************** + * main + ********************************************************************/ + +main() +{ + int driver = DETECT; /*elige autom ticamente*/ + int modo; + int dimx,dimy; /*dimensiones pantalla (n£mero pixels)*/ + time_t t; + + initgraph(&driver,&modo,NULL); /*inicia gr ficos <1>*/ + if (driver < 0) { /*comprueba si ok*/ + cputs("\r\n- No se pueden utilizar los" + " gr ficos de este ordenador."); /*sale si no puede*/ + exit(1); + } + + maxcol = getmaxcolor(); /*color m s alto*/ + dimx = getmaxx()+1; /*y l¡mites pantalla*/ + dimy = getmaxy()+1; + centroX = dimx/2; /*calcula centro <2>*/ + centroY = dimy/2; + cuadra = (dimx/(double)dimy)/(4.0/3.0); /*cuadratura <3>*/ + pi = 4.0*atan(1.0); /*n£mero pi <4>*/ + grad = pi/180.0; /*constante convers. <5>*/ + + srand((unsigned int)time(NULL)); /*inicia random*/ + while (kbhit()) getch(); /*vac¡a buffer*/ + + while (! kbhit()) { /*sale con una tecla*/ + Espiral(); /*dibuja una espiral*/ + t = time(NULL)+PAUSA; /*espera o tecla <6>*/ + while (! kbhit() && time(NULL) < t) + ; + } + if (kbhit()) getch(); /*vac¡a posibles teclas*/ + + closegraph(); /*vuelve al modo texto*/ +} + +/* Notas sobre main: + <1> El paso al modo gr fico es id‚ntico al de REBOTE. + <2> Dado que el n£mero de pixels es par, no existe un centro exacto. + <3> El factor de cuadratura se utilizar  para corregir la dimensi¢n + horizontal de forma que la figura aparezca con las mismas proporciones + tanto en vertical como en horizontal, independientemente de la forma + de los pixels en un determinado ordenador. Las operaciones con + (double) son necesarias para evitar que dimx/dimy sea una divisi¢n + entera con p‚rdida del resto. + <4> Aprovechando el hecho de que 45ø es ã/4 y que la tangente de 45ø es + 1.0, se puede obtener el valor de pi sin tener que escribirlo. + <5> Es m s c¢modo disponer de una constante para convertir entre grados + sexagesimales (una vuelta = 360ø) y radianes (una vuelta = 2ã). + <6> El tiempo de espera establecido (PAUSA segundos) se interrumpe si el + usuario pulsa una tecla para terminar el programa. Si se desea una + mayor precisi¢n, se deber¡a utilizar clock en lugar de time. +*/ + + +/******************************************************************** + * Espiral: dibuja una espiral poligonal aleatoria. + ********************************************************************/ + +void Espiral(void) /*<1>*/ +{ + double r; /*radio*/ + double ia; /*incremento  ngulo*/ + double ir; /*incremento radio*/ + double rlim; /*l¡mite radio*/ + double s,c; /*seno y coseno actuales <2>*/ + double ca; /*coseno anterior*/ + double isin,icos; /*incremento seno y coseno*/ + int x,y; + + rlim = centroY*2.5; /*fija l¡mite*/ + ia = (double)((rand()%3600)/10.0); /*extrae incrementos <3>*/ + ir = 1.0+(double)((rand()%200)/100.0); + isin = sin(ia*grad); + icos = cos(ia*grad); + r = 0.0; /*parte del centro*/ + s = sin(0.0); /*con  ngulo 0 grados*/ + c = cos(0.0); + + setcolor(1+rand()%maxcol); /*y color, no negro <4>*/ + cleardevice(); /*borra pantalla*/ + moveto(centroX,centroY); /*va al centro*/ + while (r < rlim) { + ca = c; /*copia coseno*/ + c = c*icos-s*isin; /*nuevo coseno <5>*/ + s = s*icos+ca*isin; /*nuevo seno*/ + x = centroX+(int)(floor(r*c*cuadra+0.5)); /*nuevas coordenadas <6>*/ + y = centroY+(int)(floor(r*s+0.5)); + lineto(x,y); /*traza l¡nea*/ + r += ir; /*incrementa radio*/ + } +} + +/* Notas sobre Espiral: + <1> Una espiral poligonal se obtiene girando a velocidad constante + alrededor del centro y aumentando progresivamente el radio. A + intervalos regulares (en t‚rminos de  ngulo) se fija un punto y + se une con un segmento rectil¡neo al punto anterior. + <2> La funci¢n Espiral usa un truco para no tener que llamar a dos + funciones trigonom‚tricas relativamente lentas (seno y coseno) en + cada vuelta. Es posible calcular una sola vez, al principio, las dos + variables isin y icos, y utilizarlas con simples multiplicaciones + para calcular la posici¢n sucesiva a lo largo de una circunferencia. + <3> La rotaci¢n se obtiene aumentando en cada vuelta el  ngulo actual un + determinado valor (en realidad utilizamos el truco descrito en la nota + 2). Ejecutando rand()%3600 se obtiene un valor entre 0 y 3599, y + dividi‚ndolo por 10.0 se subdivide el  ngulo de giro en d‚cimas de + grado: el valor de ia resulta entonces comprendido entre 0.0 y 359.9 + grados. El valor de ir (incremento radio) estar  comprendido, sin + embargo, entre 1.0 y 2.99. + <4> Extrae un color entre los disponibles, excluido el cero. En el caso + de un monitor monocromo, extrae siempre el blanco. + <5> Este es el atajo utilizado para evitar el c lculo en cada vuelta del + seno y el coseno del  ngulo actual. No profundizamos en la t‚cnica + trigonom‚trica empleada. + <6> La coordenada horizontal se multiplica por cuadra (el factor de + cuadratura) para asegurar unas proporciones 'cuadradas'. Utilizamos + el sistema habitual para aproximar un double al entero m s cercano: + a¤adir 0.5 y aproximar con floor al entero inferior. La utilizaci¢n + de (int) no es estrictamente necesaria, pero muestra sin ninguna + duda que se ejecuta un truncamiento de la parte decimal pasando de + un double a un int (la parte decimal ya era cero, de todas formas, + por el efecto de floor). +*/ + + + +/*========================= Versi¢n para Quick C 2.0 ======================*/ + +#else + + +#include +#include /*para definir NULL*/ +#include +#include +#include +#include + + +/* constantes y variables globales */ + +#define PAUSA 3 /*3 segundos de pausa entre espirales*/ + +int maxcol; /*l¡mite de colores*/ +int centroX; /*coordenadas del centro de la pantalla*/ +int centroY; +double cuadra; /*factor de cuadratura*/ +double pi; /*n£mero pi*/ +double grad; /*constante de conversi¢n grados/radianes*/ + + +/* prototipos de funciones: */ + +void Espiral(void); + + +/******************************************************************** + * main + ********************************************************************/ + +main() +{ + int modos[] = { /*lista de los modos en orden de preferencia*/ + _VRES16COLOR, /*VGA 640 x 480*/ + _ERESCOLOR, /*EGA color 640 x 350*/ + _ERESNOCOLOR, /*EGA monocroma 640 x 350*/ + _ORESCOLOR, /*Olivetti 640 x 400*/ + _HERCMONO, /*Hercules 720 x 348*/ + _HRESBW, /*CGA 640 x 400*/ + _DEFAULTMODE /*indica fin de lista*/ + }; + struct videoconfig v; /*datos del modo de v¡deo actual*/ + int dimx,dimy; /*dimensiones de la pantalla (n£mero pixels)*/ + time_t t; + int i; + + i = 0; /*inicia gr ficos <1>*/ + while (modos[i] != _DEFAULTMODE + && _setvideomode(modos[i]) == 0) { + i++; + } + + if (modos[i] == _DEFAULTMODE) { /*comprueba si ok*/ + cputs("\r\n- No se pueden utilizar los" + " gr ficos de este ordenador."); /*sale si no puede*/ + exit(1); + } + + _getvideoconfig(&v); /*lee datos modo v¡deo:*/ + maxcol = v.numcolors; /*color m ximo*/ + dimx = v.numxpixels; /*l¡mites pantalla*/ + dimy = v.numypixels; + centroX = dimx/2; /*calcula centro <2>*/ + centroY = dimy/2; + cuadra = (dimx/(double)dimy)/(4.0/3.0); /*cuadratura <3>*/ + pi = 4.0*atan(1.0); /*n£mero pi <4>*/ + grad = pi/180.0; /*constante convers. <5>*/ + + srand((unsigned int)time(NULL)); /*inicia random*/ + while (kbhit()) getch(); /*vac¡a buffer*/ + + while (! kbhit()) { /*sale con una tecla*/ + Espiral(); /*dibuja una espiral*/ + t = time(NULL)+PAUSA; /*espera o tecla <6>*/ + while (! kbhit() && time(NULL) < t) + ; + } + if (kbhit()) getch(); /*vac¡a posibles teclas*/ + + _setvideomode(_DEFAULTMODE); /*vuelve al modo texto*/ +} + +/* Notas sobre main: + <1> El paso al modo gr fico es id‚ntico al de REBOTE. + <2> Dado que el n£mero de pixels es par, no existe un centro exacto. + <3> El factor de cuadratura se utilizar  para corregir la dimensi¢n + horizontal de forma que la figura aparezca con las mismas proporciones + tanto en vertical como en horizontal, independientemente de la forma + de los pixels en un determinado ordenador. Las operaciones con + (double) son necesarias para evitar que dimx/dimy sea una divisi¢n + entera con p‚rdida del resto. + <4> Aprovechando el hecho de que 45ø es ã/4 y que la tangente de 45ø es + 1.0, se puede obtener el valor de pi sin tener que escribirlo. + <5> Es m s c¢modo disponer de una constante para convertir entre grados + sexagesimales (una vuelta = 360ø) y radianes (una vuelta = 2ã). + <6> El tiempo de espera establecido (PAUSA segundos) se interrumpe si el + usuario pulsa una tecla para terminar el programa. Si se desea una + mayor precisi¢n, se deber¡a utilizar clock en lugar de time. +*/ + + +/******************************************************************** + * Espiral: dibuja una espiral poligonal aleatoria. + ********************************************************************/ + +void Espiral(void) /*<1>*/ +{ + double r; /*radio*/ + double ia; /*incremento  ngulo*/ + double ir; /*incremento radio*/ + double rlim; /*l¡mite radio*/ + double s,c; /*seno y coseno actuales <2>*/ + double ca; /*coseno anterior*/ + double isin,icos; /*incremento seno y coseno*/ + int x,y; + + rlim = centroY*2.5; /*fija l¡mite*/ + ia = (double)((rand()%3600)/10.0); /*extrae incrementos <3>*/ + ir = 1.0+(double)((rand()%200)/100.0); + isin = sin(ia*grad); + icos = cos(ia*grad); + r = 0.0; /*parte del centro*/ + s = sin(0.0); /*con  ngulo 0 grados*/ + c = cos(0.0); + + _setcolor(1+rand()%maxcol); /*y color, no negro <4>*/ + _clearscreen(_GCLEARSCREEN); /*borra pantalla*/ + _moveto(centroX,centroY); /*va al centro*/ + while (r < rlim) { + ca = c; /*copia coseno*/ + c = c*icos-s*isin; /*nuevo coseno <5>*/ + s = s*icos+ca*isin; /*nuevo seno*/ + x = centroX+(int)(floor(r*c*cuadra+0.5)); /*nuevas coordenadas <6>*/ + y = centroY+(int)(floor(r*s+0.5)); + lineto(x,y); /*traza l¡nea*/ + r += ir; /*incrementa radio*/ + } +} + +/* Notas sobre Espiral: + <1> Una espiral poligonal se obtiene girando a velocidad constante + alrededor del centro y aumentando progresivamente el radio. A + intervalos regulares (en t‚rminos de  ngulo) se fija un punto y + se une con un segmento rectil¡neo al punto anterior. + <2> La funci¢n Espiral usa un truco para no tener que llamar a dos + funciones trigonom‚tricas relativamente lentas (seno y coseno) en + cada vuelta. Es posible calcular una sola vez, al principio, las dos + variables isin y icos, y utilizarlas con simples multiplicaciones + para calcular la posici¢n sucesiva a lo largo de una circunferencia. + <3> La rotaci¢n se obtiene aumentando en cada vuelta el  ngulo actual un + determinado valor (utilizamos el truco descrito en la nota 2). + Ejecutando rand()%3600 se obtiene un valor entre 0 y 3599, y + dividi‚ndolo por 10.0 se subdivide el  ngulo de giro en d‚cimas de + grado: el valor de ia resulta entonces comprendido entre 0.0 y 359.9 + grados. El valor de ir (incremento radio) estar  comprendido, sin + embargo, entre 1.0 y 2.99. + <4> Extrae un color entre los disponibles, excluido el cero. En el caso + de un monitor monocromo, extrae siempre el blanco. + <5> Este es el atajo utilizado para evitar calcular en cada vuelta el + seno y el coseno del  ngulo actual. No profundizamos en la t‚cnica + trigonom‚trica empleada. + <6> La coordenada horizontal se multiplica por cuadra (el factor de + cuadratura) para asegurar unas proporciones 'cuadradas'. Utilizamos + el sistema habitual para aproximar un double al entero m s cercano: + a¤adir 0.5 y aproximar con floor al entero inferior. La utilizaci¢n + de (int) no es estrictamente necesaria, pero muestra sin ninguna + duda que se ejecuta un truncamiento de la parte decimal pasando de + un double a un int (la parte decimal ya era cero, de todas formas, + por el efecto de floor). +*/ + + +#endif /*fin opci¢n Turbo C/Quick C*/ + \ No newline at end of file diff --git a/S.EXE b/S.EXE new file mode 100644 index 0000000..13f8771 Binary files /dev/null and b/S.EXE differ diff --git a/SPIRAL.FNT b/SPIRAL.FNT new file mode 100644 index 0000000..f0b651e Binary files /dev/null and b/SPIRAL.FNT differ