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.
				/////// 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;
}
Descargar adjuntos
COMPARTE ESTE TUTORIAL

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
TUTORIAL ANTERIOR

SIGUIENTE TUTORIAL