#include #include #include #include // Escribe un caracter en (x,y) -> Color|Fondo en VText 0x7900 #define WriteChar50( x, y, caracter, Col, Fon, VText ) VText[80*y + x] = (((unsigned)caracter)&0x00FF) | (((unsigned)( (Fon<<4)+Col )<<8)&0xFF00); /* ( (Fon<<4)+Col ) ( ( (int)( (char)Fon << 4) + Col )<< 8 ) 7 6 5 4 º 3 2 1 0 ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ×ÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ B ³ b ³ b ³ b º f ³ f ³ f ³ f ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄ×ÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ º In this 8-bit newattr parameter, þ ffff = 4-bit foreground color (0 to 15) þ bbb = 3-bit background color (0 to 7) þ B = blink-enable bit */ // Proyecto para mostrar cosas en modo texto: 80x50 // Preparamos un buffer virtual a pantalla: 80x50*2 bytes/punto = 8000 bytes int *textoVirtual; int XSinMov[256], YSinMov[256]; int TSin[360+90]; void RellenaTablas(void) { float angle; angle = 0; while( angle < 256 ) { XSinMov[angle] = YSinMov[angle] = (int)( sin( (2*M_PI*angle*1.4)/360 ) * 360) / (2*M_PI); YSinMov[angle] = 0; angle+=1; }; angle = 0; while( angle < (360+90) ) { TSin[angle] = (int)(sin( (2*M_PI*angle)/360 ) * 360 / (2*M_PI) ); angle+=1; }; } char PRIMARIO8 = YELLOW; char SECUNDARIO1 = RED; void Put( int x, int y, unsigned char c) { if ( x < 0 || x >= 80 ) return; if ( y < 0 || y >= 50 ) return; WriteChar50( x, y, '±', (c==0 ? 0 : PRIMARIO8), SECUNDARIO1, textoVirtual ); }; //#define RADIO 255 // Radio de partida #define RADIO 255 #define SALTOS_ANCHOS 7 //#define SALTOS_PROFUNDOS 8 // Grado de torcion #define SALTOS_PROFUNDOS 8 //#define SALTOS_ANCHOS 7 // Saltos de radio #define BLOQUEO_RADIO 1 #define INCREMENTAL 1 //#define PROFUNDIDAD_TUNEL 35 #define PROFUNDIDAD_TUNEL 35 #define FACTOR_SERPIENTE 0.015F //#define TODO_BLANCO //#define TODO_GRIS int PERFECCION_CIRCULO = 8; // Circulo con impresi¢n de giro ( MEJORA POR JD ) void Circulo( int x, int y, int radio, int giro, int Color ) { int angle; for ( angle = 0; angle < 360; angle+=PERFECCION_CIRCULO ) Put( x + (radio*FACTOR_SERPIENTE*TSin[ (giro + angle)%360 + 90 ]), y + (radio*FACTOR_SERPIENTE*TSin[ (giro+angle)%360 ]), angle >= 0 && angle <= 50 ? (Color-PROFUNDIDAD_TUNEL) : Color ); }; // Circulo con impresi¢n de giro ( MEJORA POR JD ) void CirculoB( int x, int y, int radio, int giro ) { int angle; for ( angle = 0; angle < 360; angle+=PERFECCION_CIRCULO ) Put( x + (radio*FACTOR_SERPIENTE*TSin[ (giro + angle)%360 + 90 ]), y + (radio*FACTOR_SERPIENTE*TSin[ (giro+angle)%360 ]), 0 ); }; void TunelEstrellas(void) { int depth, Color; static unsigned char ZMov = 0; static int GiroAngular = 0; unsigned char Movimiento = ZMov; static Subidon = 255; static Velocidad = 0; // Controles de giro por JD: // SUAVE ZMov // DURO Movimiento int OGiroAngular = GiroAngular; GiroAngular = ( GiroAngular++ ) % 360; ZMov ++; Movimiento = ZMov; Color = 255-PROFUNDIDAD_TUNEL; // Color = 255; Velocidad++; if ( Velocidad == 5 ) { Velocidad = 0; // Subidon --; if ( Subidon < 255-PROFUNDIDAD_TUNEL ) Subidon = 255; Subidon = (Subidon++)%PROFUNDIDAD_TUNEL; } int Retorcido = 0; for ( depth=0; depth=0; depth-=SALTOS_ANCHOS*INCREMENTAL, Movimiento+=SALTOS_PROFUNDOS, Color-- ) { Retorcido+=15; /* OGiroAngular = GiroAngular; GiroAngular = ( GiroAngular++ ) % 360; */ // Borra el anterior CirculoB( XSinMov[(unsigned char)(Movimiento-1)] + 40, YSinMov[(unsigned char)(Movimiento-1)] + 25, RADIO - depth*BLOQUEO_RADIO, OGiroAngular + 0*Movimiento + Retorcido ); Subidon = (Subidon++)%PROFUNDIDAD_TUNEL; // Dibuja el nuevo circulo // Circulo( XSinMov[Movimiento] + 160, YSinMov[Movimiento] + 100, RADIO - depth*BLOQUEO_RADIO, GiroAngular + 0*Movimiento, (Subidon >= Color && Subidon <= Color + 2 ) ? 1: Color ); Circulo( XSinMov[Movimiento] + 40, YSinMov[Movimiento] + 25, RADIO - depth*BLOQUEO_RADIO, GiroAngular + 0*Movimiento + Retorcido, Subidon%6 == 0 || Subidon%6 == 1 ? 1+Subidon : Color); } delay(10); } // Escribe un caracter en (x,y) -> Color|Fondo en VText 0x7900 #define WriteChar50( x, y, caracter, Col, Fon, VText ) VText[80*y + x] = (((unsigned)caracter)&0x00FF) | (((unsigned)( (Fon<<4)+Col )<<8)&0xFF00); class TextoAnimado { private: int *pPlanoVirtual; int *sPlanoVirtual; int *tPlanoVirtual; public: TextoAnimado(void); ~TextoAnimado(void){ delete [] pPlanoVirtual; delete [] sPlanoVirtual; delete [] tPlanoVirtual; }; void locateText( int x, int y, unsigned char *texto, char color, char fondo ); void VuelcaPantallas(void); void BorraTodo(void) { memset( MK_FP( 0xB800, 0 ), 0, 8000 ); memset( tPlanoVirtual, 0, 8000 ); memset( pPlanoVirtual, 0, 8000 ); memset( sPlanoVirtual, 0, 8000 ); }; int *pPlano(void){ return pPlanoVirtual; }; int *sPlano(void){ return sPlanoVirtual; }; }; void TextoAnimado::locateText( int x, int y, unsigned char *texto, char color, char fondo ) { while( *texto != '\0' ) WriteChar50( x++, y, *(texto++), color, fondo, pPlanoVirtual ) } TextoAnimado::TextoAnimado(void) { if ( ( pPlanoVirtual = new int [4000] ) == NULL ) { pPlanoVirtual = sPlanoVirtual = tPlanoVirtual = (int *)MK_FP( 0xB800, 0 ); } else if ( ( sPlanoVirtual = new int [4000] ) == NULL ) { sPlanoVirtual = tPlanoVirtual = (int *)MK_FP( 0xB800, 0 ); } else if ( ( tPlanoVirtual = new int [4000] ) == NULL ) tPlanoVirtual = (int *)MK_FP( 0xB800, 0 ); } void TextoAnimado::VuelcaPantallas(void) { int count = 3999;//4000; int * dest, * scr; // Volcamos el segundo plano, ENTERO memcpy( tPlanoVirtual, sPlanoVirtual, 8000 ); // Volcamos el primer plano, pero cuidado caracter ú == transparente dest = tPlanoVirtual; scr = pPlanoVirtual; while( count-- ) { if ( *scr && ((*scr)&0x00FF) != 'ú' ) { *(dest++) = *(scr++); } else { scr++; dest++; } }; memcpy( MK_FP( 0xB800, 0 ), tPlanoVirtual, 8000 ); } void main(void) { TextoAnimado prueba1; textmode( C4350 ); RellenaTablas(); _setcursortype( _NOCURSOR ); prueba1.BorraTodo(); prueba1.locateText( 10, 10, "Esto es una prueba de mis librerias", WHITE, BLACK ); prueba1.locateText( 10, 15, "Los espacio pueden aparecer. ¨Lo ves?", WHITE, BLACK ); prueba1.locateText( 10, 17, "Oúnoúaparecer,úcomoúmasúteúguste,úoúconvenga!!!.", WHITE, BLACK ); textoVirtual = prueba1.sPlano(); while ( !kbhit() ) { TunelEstrellas(); prueba1.VuelcaPantallas(); } textmode( C80 ); }