/////// ESTRELLAS.CPP ///////
//
// Ejemplo pr谩ctico sobre programaci贸n gr谩fica ( b谩sico ), similar al salvapantallas de las estrellas de Windows, algo mas chulo ;).
// Puedes aprender:
// -- Trabajo con gr谩ficos en C++
// -- Trabajo con modo13h
// -- Estrucutras de datos.
// -- Proyeccion en 3d de puntos 2d.
// Fecha de 煤ltima revisi贸n: 13:40 10/07/2003
// Ejercicio realizado por Enrique Espejo 2003 Tarragona, este ejemplo es de LIBRE DISTRIBUCI脫N SIEMPRE QUE SEA
// CON FINES EDUCATIVOS, EN CASO CONTRARIO DEBER脕 PONERSE EN CONTRACTO CON EL AUTOR DEL DOCUMENTO, [email protected]
// PARA SOLICITAR PERMISO EN CASO DE QUERER PUBLICAR/MODIFICAR/EDITAR/DISTRIBUIR EL DOCUMENTO.
// HTTP://WWW.PROGRAMACI脫N.COM tiene todos los permisos descritos sobre este documento ;)
//
// Un saludo para todos los ceceadores de este peque帽o planeta.
#include <dide.h>
#define DISTANCIA_FOCAL 255 // DISTANCIA DESDE EL OJO HASTA EL CENTRO
#define MEDIOX 160 // CENTRO X DE LA PANTALLA EN PIXELS
#define MEDIOY 100 // CENTRO Y DE LA PANTALLA EN PIXELS
#define CANTIDAD 2000 // CANTIDAD DE ESTRELLAS
#define ESPERA 1 // MAYOR ESTELA MENOS VELOCIDAD
void inicia(void);
void muevelas(void);
void dibuja(void);
void proyecta(int *px, int *py, int x, int y, int z);
void escanea(void);
typedef unsigned char uchar;
typedef struct
{ int x,y;
} s2d;
typedef struct
{ int x,y,z;
uchar color;
int velocidad;
} s3d;
s3d estrellas3d[CANTIDAD];
s2d estrellas2d[CANTIDAD];
void inicia()
{ int i;
int x,y,z;
for(i=0;i<CANTIDAD;i++)
{ x = (rand()%320)-160;
y = (rand()%200)-100;
z = rand()%10000;
estrellas3d[i].x=x;
estrellas3d[i].y=y;
estrellas3d[i].z=z;
estrellas3d[i].velocidad = (rand()%20)+1;
estrellas3d[i].color = 31;
} }
void muevelas(void)
{ int i;
int temp;
while(!kbhit())
{ delay(ESPERA);
for(i=0;i<CANTIDAD;i++)
{ estrellas3d[i].z -= estrellas3d[i].velocidad;
if(estrellas3d[i].z<=0)
{ estrellas3d[i].z = 800;
estrellas3d[i].x = (rand()%320)-160;
estrellas3d[i].y= (rand()%200)-100;
} }
dibuja();
escanea();
} }
void dibuja(void)
{ int i,a;
for(i=0;i<CANTIDAD;i++)
{ proyecta(&estrellas2d[i].x,&estrellas2d[i].y,estrellas3d[i].x,estrellas3d[i].y,estrellas3d[i].z);
if(estrellas2d[i].x>=0 && estrellas2d[i].x<320 && estrellas2d[i].y >=0 && estrellas2d[i].y <200 )
pon_punto(estrellas2d[i].x,estrellas2d[i].y,estrellas3d[i].color);
} }
void proyecta(int *px, int *py, int x, int y, int z)
{ if(z!=0)
{ // proyeccion en el plano del punto en el espacio
*px=DISTANCIA_FOCAL * x / z;
*py=DISTANCIA_FOCAL * y / z;
// sumamos las coordenadas iniciales para que se centre en el monitor.
*px += MEDIOX;
*py += MEDIOY;
} }
void escanea(void)
{ int i ,a,t;
for(i=0;i<320;i++)
{ for(a=0;a<200;a++)
{ t=get_pixel(i,a);
if(t>=16 && t<= 32 )
{
if(t==16)
t=0;
else
t--;
pon_punto(i,a,t);
} } } }
void main()
{ randomize();
IniMode( 0x13 );
inicia();
muevelas();
}
/////// DIDE.H ///////
//|
//| Libreria DidE.h para trabajo con el modo 13h y el rat贸n, principalmente pensada para la programaci贸n de juegos.
//| Creada con fines educativos.
//| No pretendo darmelas de experto ni de profesor, si quieres preguntarme algo, hazlo pero no te garantizo la respuesta.
//| Libre distribuci贸n excepto bajo prop贸sitos comerciales. ( consultar con el autor: [email protected] )
//| No debe eliminarse esta cabecera. Hay un algoritmo oculto que eliminar谩 tu pc de la faz de la tierra si lo haces.
//| v 2.33 fecha de 煤ltima revisi贸n: 14/07/2003 --> a帽adidos nuevos comentarios y las funciones: linea y cambiarcolor
//| funciones pendientes: trabajo con archivos PCX
//|______________________________________________________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include <string.h>
/////////////////////////////////////////////////////////
// Declaraci贸n de Constantes
/////////////////////////////////////////////////////////
#define INT_MOUSE 0x33
#define SERV_ACTIVA_MOUSE 0x00
#define SERV_GET_MOUSE_STATUS 0x03
#define SERV_SET_MOUSE_XY 0x04
#define VVID 0xA0000000L
#define CANT 500
#define LX_MOUSE 640
#define LY_MOUSE 200
/////////////////////////////////////////////////////////
// Tipos de Datos.
/////////////////////////////////////////////////////////
// Declaraci贸n del tipo de datos Booleano.
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// Declaraci贸n de variables globales.
/////////////////////////////////////////////////////////
int xmouse=0; int y_mouse=0;
int _mouse_pulsado=0;
int _mouse_cargado=0;
int _cursor_cargado=0;
int activa_mouse(); // Inicializaci贸n del rat贸n
int get_x_mouse(); // Devuelve la coordenada x actual del rat贸n
int get_y_mouse(); // Devuelve la coordenada y actual del rat贸n
int pulsado_left(); // Devuelve true si esta pulsado el bot贸n izquierdo del rat贸n
int pulsado_right(); // Devuelve true si esta pulsado el bot贸n derecho del rat贸n
int mouse_movido(); // Devuelve true si el rat贸n ha cambiado de posici贸n
/////////////////////////////////////////////////////////
// Listado de Prototipos de las funciones implementadas.
/////////////////////////////////////////////////////////
char Sgn(int x);
void IniMode (char Mode); // Inicializa un modo de video determinado ( 0x13 video , 0x03 texto ...)
int get_pixel(int x, int y); // Devuelve el color del pixel situado en las coordenadas pasadas como parametros.
void pon_punto(int x,int y,unsigned char color); // Procedimiento que visualiza un punto en pantalla en modo 13h
void lineaH(int x1,int x2,int y,int color); // dibuja una linea horizontal en modo 13h
void lineaV(int y1,int y2,int x, int color); // dibuja una linea vertical en modo 13h
void recta(int x1, int y1, int x2, int y2,int color); // dibuja un rectangulo en modo 13 h
void cuadro13(int x1,int y1, int x2, int y2, int color); // dibuja un rectangulo relleno en modo 13h
void linea(int x1, int y1,int x2,int y2,char color); // dibuja una linea en modo 13h
void cambiarcolor( unsigned char color, unsigned char r, unsigned char v, unsigned char a ); // cambia un color determinado segun paleta RGB
///////////////// Definiciones /////////////////////////
char Sgn(int x)
{ char res;
if(x>0)
res=1;
if(x==0)
res=0;
if(x<0)
res=-1;
return(res);
}
void linea(int x1, int y1, int x2, int y2, char Color)
{
int i, s, d1x, d1y, d2x, d2y, u=x2-x1, v=y2 - y1, m, n;
d2x = Sgn(u); d1y= Sgn(v);
d2y = 0; d1x= Sgn(u);
m = abs(u); n = abs(v);
if(m>n==0)
{ d2x = 0 ;
d2y = Sgn(v);
m = abs(v);
n = abs(u);
}
s=m>>1;
for(i=0;i<=m;i++)
{ pon_punto(x1,y1,Color);
s+=n;
if(s<m==0)
{ s -= m;
x1 += d1x;
y1 += d1y;
}
else
{ x1 += d2x;
y1 += d2y;
} } }
void cambiarcolor( unsigned char color, unsigned char r, unsigned char v, unsigned char a )
{ outportb( 0x03c8, color );
outportb( 0x03c9, r );
outportb( 0x03c9, v );
outportb( 0x03c9, a );
}
int get_pixel(int x, int y)
{ char color;
int offset=320*y+x;
color=peekb(0xA000,offset);
return color;
}
void IniMode(char Mode)
{
asm xor ah, ah
asm mov al, Mode
asm int 10h
}
//Procedimiento que visualiza un punto en pantalla, esta implementado en asm para mejorara su velocidad y portabilidad.
void pon_punto(int x,int y,unsigned char color)
{ asm{
mov ax,0xA000
mov es,ax // {; Punto al segmento de la pantalla }
mov dx,[y]
mov bx, dx // {; bx = dx}
mov dh, dl // {; dx = dx * 256}
xor dl, dl
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1 // {; bx = bx * 64}
add dx, bx // {; dx = dx + bx (ie y*320)}
mov bx,[x] // {; get our x}
add bx, dx // {; finalise location}
mov di, bx // {; di = offset }
// {; es:di = where to go}
mov ah, [color]
mov es:[di],ah // {; mueve el valor de ah a la pantalla
// point es:[di] }
} //equivale a esto:
// pokeb(0xA000,y*320+x,Color); //Ponemos un byte en la memoria de v隆deo
}
// RECTANGLE CON LOS BORDER DE COLORES
void lineaH(int x1,int x2,int y,int color)
{ int i;
for(i=x1;i<=x2;i++)
pon_punto(i,y,color);
}
void lineaV(int y1,int y2,int x, int color)
{ int i;
for(i=y1;i<=y2;i++)
pon_punto(x,i,color);
}
void recta(int x1, int y1, int x2, int y2,int color)
{ lineaH(x1,x2,y1,color);
lineaH(x1,x2,y2,color);
lineaV(y1,y2,x1,color);
lineaV(y1,y2,x2,color);
}
void cuadro13(int x1,int y1, int x2, int y2, int color)
{ int i;
for(i=y1-1;i<y2;i++)
lineaH(x1,x2,i,color);
}
int activa_mouse()
{ union REGS r;
r.x.ax=SERV_ACTIVA_MOUSE;
int86(INT_MOUSE,&r,&r);
if (r.x.ax){
_mouse_cargado=1;
return 1;
}
return 0;
}
int get_x_mouse()
{ union REGS r;
r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.cx;
}
int get_y_mouse()
{ union REGS r;
r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.dx;
}
int pulsado_left()
{ union REGS r;
r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.bx&1;
}
int pulsado_right()
{ union REGS r;
r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.bx&2;
}
int mouse_movido()
{ if (!_cursor_cargado) return 0;
if (xmouse!=get_x_mouse() || y_mouse!=get_y_mouse())
return 1;
return 0;
}
Estrellas en modo13h
Ejemplo pr谩ctico de programaci贸n gr谩fica en C++ usando el modo 13h 256 colores, similar al salvapantallas de Windows de las estrellas, pero mas bonito.
Descargar adjuntos
COMPARTE ESTE TUTORIAL
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP