First commit 01/01/1993

This commit is contained in:
José David Guillén 2021-09-08 21:41:03 +02:00
commit 63fd346c86
12 changed files with 1030 additions and 0 deletions

BIN
COMIX.FNT Normal file

Binary file not shown.

330
ESPIRAL.BAK Normal file
View File

@ -0,0 +1,330 @@
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <alloc.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
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<Flen1; j++ )
{
for ( j1=0; j1<16; j1++ )
FraseBit[j][j1] = FraseBit[j][j1] << 1;
for ( j1=0; j1<16; j1++ )
FraseBit[j][j1] = ( FraseBit[j][j1] & 0xFE ) | (0x01 & (FraseBit[j+1][j1] >> 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 */
}

330
ESPIRAL.C Normal file
View File

@ -0,0 +1,330 @@
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <alloc.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
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<Flen1; j++ )
{
for ( j1=0; j1<16; j1++ )
FraseBit[j][j1] = FraseBit[j][j1] << 1;
for ( j1=0; j1<16; j1++ )
FraseBit[j][j1] = ( FraseBit[j][j1] & 0xFE ) | (0x01 & (FraseBit[j+1][j1] >> 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 */
}

BIN
ESPIRAL.EXE Normal file

Binary file not shown.

BIN
ESPIRAL.OBJ Normal file

Binary file not shown.

BIN
FLAT.FNT Normal file

Binary file not shown.

BIN
HELVET.FNT Normal file

Binary file not shown.

BIN
MODERN.FNT Normal file

Binary file not shown.

9
README.md Normal file
View File

@ -0,0 +1,9 @@
#SPIRAL
*01/01/1993*
ToDo: wwtcf?
![screenshot](/SPIRAL.png "Screenshot")

361
S.C Normal file
View File

@ -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: tambin 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 <stdlib.h>
#include <time.h>
#include <math.h>
#include <conio.h>
#include <graphics.h>
/* 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 idntico 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 prdida 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 trminos 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 trigonomtricas 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
dividindolo por 10.0 se subdivide el  ngulo de giro en dcimas 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 tcnica
trigonomtrica 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 <stdlib.h>
#include <stddef.h> /*para definir NULL*/
#include <time.h>
#include <math.h>
#include <conio.h>
#include <graph.h>
/* 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 idntico 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 prdida 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 trminos 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 trigonomtricas 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
dividindolo por 10.0 se subdivide el  ngulo de giro en dcimas 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 tcnica
trigonomtrica 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*/


BIN
S.EXE Normal file

Binary file not shown.

BIN
SPIRAL.FNT Normal file

Binary file not shown.