Ahi va mi dithering que hice el siglo pasado...
Código:
#include "dither.h"
#define ABS(x) ((x>0)? ( x) : (-x) )
#define SGN(x) ((x<0)? (-1) : ( 1) )
#define SCREEN_ADR 0xa000
#define SCREEN_ADR_LIN ((SCREEN_ADR) << 4 )
void DitherUp(int xi, int xf, int y, unsigned ci, unsigned cf)
{
char *screen;
long dcolor;
short int icolor,error;
short unsigned color;
char c;
screen=(char *)SCREEN_ADR_LIN+xi+y*320;
c=ci>>8;
dcolor=((long)(cf-ci)<<8) / (xf-xi);
icolor=(dcolor>>16);
dcolor&=0xffff;
color=ci<<8;
error=0x8000;
while (xi<=xf) {
if ( (error+=(color>>1)) >0 ){
error+=0x8000;
*screen++=(c+1);
} else
*screen++=c;
c+=icolor;
if ((color+=dcolor) < dcolor)
c++;
xi++;
}
}
void DitherDown(int xi, int xf, int y, unsigned ci, unsigned cf)
{
char *screen;
long dcolor;
short int icolor,error;
short unsigned color;
char c;
screen=(char *)SCREEN_ADR_LIN+xf+y*320;
c=cf>>8;
dcolor=( (long) (ci-cf)<<8 ) / (xf-xi);
icolor=(dcolor>>16);
dcolor&=0xffff;
color=cf<<8;
error=0x8000;
while (xi<=xf) {
if ( (error+=(color>>1)) >0 ) {
error+=0x8000;
*screen--=(c+1);
} else
*screen--=c;
c+=icolor;
if ((color+=dcolor) < dcolor)
c++;
xi++;
}
}
void DitherSpan(short xi, short xf, short y, short unsigned ci, short unsigned cf)
{
if(xi<xf)
((ci<=cf)? DitherUp(xi,xf,y,ci,cf) : DitherDown(xi,xf,y,ci,cf) );
}
uff, cuantos comentarios, ya se sabe, si costo programarlo debe costar entenderlo...
Un par de cosas, como se ve esta hecho para el modo 0x13, pero no creo que tengas muchos problemas en cambiarlo, incluso en usar colores leyendolos de una tabla.
Hay dos rutinas una para hacer el dithering hacia arriba (con colores cada vez mayores o con un incide mayor), y otra hacia abajo. Se supone que estas dos versiones serian privadas, el usuario solo usaria DitherSpan.
En el codigo veras cosas un poco raras como los 0x8000, esto es porque la primera version la hice en ensamblador del 68000 y las rutinas usaban el bit de carry, como en C no puedes hacer saltos dependiedo de los bits de estado hay que hacer estas chapucillas.
Los parametros son los siguientes:- xi : coordenada x Inicial...
- xf : coordenada x final, siempre mayor que xi
- y : coordenada y de la linea horizontal con dithering
- ci : color inicial (16 bits), se supone que el byte alto es el indice del color o a una tabla, la parte baja serian la parte decimal del color
- cf: color final, igual que el inicial
Para hacer dithering en un cuadrado asegurate de que la parte decimal del color varia, o apareceran unas lineas verticales.
No tengo imagenes de como queda pero si has visto la intro del Interfase del Atari ST (el cubo con sombreado gouraud), es exactamente igual... la saque de ahi
Marcadores