/* Verschiedene Vektor-Grafikroutinen (Solid-Fill,Gouraud-Shading von Polygonen)
(c) DL 30.1.97-
Es mssen vom einbindenden Programm folgende Variablen gestellt werden:
BaseAddr - Dorthin sollen die Polygone gezeichnet werden
ACHTUNG: ab 6.4. ist BaseAddr ein Zeiger auf die Zielbitmap,
da nun die Allegro-Library statt LIBGRX verwendet wird
ScrWidth/ScrHeight
Prozeduren:
* SetLine_Interpol usw.: lineare Interpolationsmethoden
* DL_Line(x1,y1,x2,y2,farbe): Zeichnet eine Linie
* DL_LineGouraud(x1,y1,x2,y2,c1,c2): Schattiert eine Linie mit allen Farben zwischen c1 und c2
* DL_FillPoly(nPoint,int points[][2],farbe): Zeichnet ein einfrbig geflltes Polygon
* DL_FillPolyGouraud(nPoint,int points[][2],int colors[]): Zeichnet ein
Polygon mit Gouraud-Schattierung
Variablen:
char drawback; Wenn 1, dann wird das Polygon auch gezeichnet, wenn
es entgegen dem Uhrzeigersinn gespeichert ist (sinnvoll
fr verdeckte Flchen konvexer Krper in 3D-Transformationen
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <dos.h>
#ifdef test_dlline
#include <std.h>
#include <grx.h>
#include <math.h>
unsigned int RetracePort;
#define NoSprites
#include "_dlspr.c"
#define RedStart 32
#define LongTime(h,m,sec,sec100) (long)(sec100+sec*100+m*6000+h*360000)
#endif
#define xchg(x,y) x^=y^=x^=y
typedef struct { /* Struktur fr lineare Interpolation */
int a,dx; /* a = Zhler, dx = Nenner */
int IncrF,IncrIP;
int Dec_a; /* Um diesen Wert wird a bei jedem Durchlauf verringert */
int fcoord,ipcoord; /* fcoord ... Wird bei jedem Durchlauf fix um 1 erhht/verringert (-> Incr)
ipcoord .. Diese Koordinate wird linear interpoliert */
int flim;
int swp; /* Wenn 1, dann fcoord = y und ipcoord = x, ansonsten umgekehrt */
int swapcolors; /* Wenn 1, dann mssen beim Gouraud-Shading die beiden
Eckfarben umgedreht werden */
} TInterpol;
/* ---------- F u n k t i o n s p r o t o t y p e n --------------- */
inline void SetLine_Interpol(int x1,int y1,int x2,int y2,TInterpol *ipol);
inline int Do_Interpol(TInterpol *ipol);
inline int LineReady(TInterpol *ipol);
inline void SetColor_Interpol(int c1,int c2,int length,TInterpol *ipol);
void DL_Line(int x1,int y1,int x2,int y2,int farbe);
void DL_LineGouraud(int x1,int y1,int x2,int y2,int c1,int c2);
void DL_FillPoly(char nPoint,int points[][2],unsigned char color);
int DL_FillPolyGouraud(char nPoint,int points[][2],int colors[]);
void DL_Clear32(BITMAP *b);
/* -------------------------------------------------------------- */
unsigned char colortable[2000]; /* Fr die Funktion DL_HLineGouraud256 */
char drawback=1;
/* -------------------------------------------------------------- */
/* Die Prozedure SetLine_Interpol und Do_Interpol bilden im wesentlichen eine
Routine zum Linienzeichnen mittels linearer Interpolation, knnen aber z.B.
auch zum Fllen von Polygonen verwendet werden
(Hinweis: es wird immer von oben nach unten, d.h. vom Punkt mit der kleineren
y-Koordinate zum Punkt mit der gráeren y-Koordinate gerechnet */
inline void SetLine_Interpol(int x1,int y1,int x2,int y2,TInterpol *ipol) {
/* Setzt die Interpolationsvariablen fr eine Linie */
int dx,dy;
ipol->IncrF = ipol->IncrIP = 1;
ipol->swapcolors = 0;
if ((dx = x2-x1) < 0) dx = -dx;
if ((dy = y2-y1) < 0) dy = -dy;
if (dx > dy) { /* Steigung < 1? */
if (x1 > x2) {
xchg(x1,x2);
xchg(y1,y2);
ipol->swapcolors = 1;
}
if (y1 > y2) {
ipol->IncrF = -1;
ipol->Dec_a = (y1-y2) << 1;
ipol->fcoord = x2;
ipol->ipcoord = y2;
ipol->flim = x1;
ipol->swapcolors = !ipol->swapcolors;
}
else {
ipol->Dec_a = (y2-y1) << 1;
ipol->fcoord = x1;
ipol->ipcoord = y1;
ipol->flim = x2;
}
ipol->a = x2-x1;
ipol->swp = 0;
ipol->dx = ipol->a << 1;
}
else { /* Steigung > 1 */
if (y1 > y2) {
xchg(x1,x2);
xchg(y1,y2);
ipol->swapcolors = 1;
}
if (x1 > x2) {
ipol->IncrIP = -1;
ipol->Dec_a = (x1-x2) << 1;
ipol->fcoord = y1;
ipol->ipcoord = x1;
ipol->flim = y2;
} else {
ipol->Dec_a = (x2-x1) << 1;
ipol->fcoord = y1;
ipol->ipcoord = x1;
ipol->flim = y2;
}
ipol->a = y2-y1;
ipol->swp = 1;
ipol->dx = ipol->a << 1;
}
}
inline int Do_Interpol(TInterpol *ipol) /* Fhrt die Interpolation aus (1 Schritt),
Rckgabe 1, wenn ipcoord erhht wurde */
{
/* ipol-Offsets: a 0
dx 4
IncrF 8
IncrIP 12
Dec_a 16
fcoord 20
ipcoord 24
flim 28
swp 32
swapcolors 36 */
/* asm volatile (
"
movl %1,%%edi
movl $0,(%%edi)
movl %0,%%edi
movl 8(%%edi),%%eax
addl %%eax,20(%%edi)
movl 16(%%edi),%%eax
subl %%eax,(%%edi)
jns Do_InterpolEnde
movl 4(%%edi),%%eax
addl %%eax,(%%edi)
movl 12(%%edi),%%eax
addl %%eax,24(%%edi)
movl %1,%%edi
movl $1,(%%edi)
Do_InterpolEnde:
"
:
: "g" (ipol), "g" (&result)
: "edi","eax");*/
ipol->fcoord += ipol->IncrF;
if ((ipol->a -= ipol->Dec_a) > 0) return(0);
else
{
ipol->a += ipol->dx;
ipol->ipcoord += ipol->IncrIP;
return(1);
}
}
inline int LineReady(TInterpol *ipol)
{
if (ipol->IncrF > 0)
if (ipol->fcoord < ipol->flim) return(0);
else return(1);
else if (ipol->fcoord > ipol->flim) return(0);
else return(1);
}
inline void SetColor_Interpol(int c1,int c2,int length,TInterpol *ipol)
{
ipol->ipcoord = c1;
ipol->a = c1 << 10;
if (length != 0)
ipol->Dec_a = ((c2-c1) << 10)/length;
else ipol->Dec_a = 0;
}
#define Do_ColorInterpol(ipol) { \
ipol.a += ipol.Dec_a; \
ipol.ipcoord = ipol.a >> 10; \
}
/* ----------------------------------------------------------- */
/* Algorithmus siehe "Algorithmen zur Spieleprogrammierung", S. 187ff */
void DL_Line(int x1,int y1,int x2,int y2,int farbe) {
int x,y;
TInterpol ipol;
SetLine_Interpol(x1,y1,x2,y2,&ipol);
do {
if (ipol.swp)
putpixel(BaseAddr,ipol.ipcoord,ipol.fcoord,farbe);
else putpixel(BaseAddr,ipol.fcoord,ipol.ipcoord,farbe);
Do_Interpol(&ipol);
} while (!LineReady(&ipol));
}
/* Zeichnet eine Linie mittels Gouraudshading mit linearer Interpolation der
Farbe */
void DL_LineGouraud(int x1,int y1,int x2,int y2,int c1,int c2)
{
int x,y;
TInterpol ipol,ipol_color;
SetLine_Interpol(x1,y1,x2,y2,&ipol);
SetColor_Interpol(c1,c2,ipol.a,&ipol_color);
/* if (ipol.swapcolors) {
xchg(ipol_color.ipcoord,ipol_color.flim);
ipol_color.IncrIP = -ipol_color.IncrIP;
}*/
do {
if (ipol.swp)
putpixel(BaseAddr,ipol.ipcoord,ipol.fcoord,ipol_color.ipcoord);
else putpixel(BaseAddr,ipol.fcoord,ipol.ipcoord,ipol_color.ipcoord);
Do_Interpol(&ipol);
Do_ColorInterpol(ipol_color);
} while (!LineReady(&ipol));
}
#if 0
/* Diese Routine zeichnet NUR horizontale Gouraud-Linien NUR im 256-Farb-Modus */
void DL_HLineGouraud256(int x1,int x2,int y,char c1,char c2)
{
int x,w,ctablestart;
unsigned char *scrp;
int aktcolor,inccolor;
if ((y < 0) || (y >= ScrHeight) || (x2 < x1) ||
((x1 < 0) && (x2 < 0)) || ((x1 > ScrWidth) && (x2 > ScrWidth))) return;
w = x2-x1;
if (w == 1) {
scrp = (unsigned char *) BaseAddr+y*ScrWidth+x1;
*scrp = (c1+c2) >> 1;
return;
}
if (w < 2) return;
aktcolor = c1 << 10;
inccolor = ((c2-c1) << 10) / w;
/* for (x = 0; x < w; x++) {
colortable[x] = aktcolor >> 10;
aktcolor += inccolor;
}*/
/* Pixeltabelle aufbauen, die dann nur noch 1:1 in den Bildspeicher bertragen werden muá */
asm volatile (
"
movl %0,%%edi
movl %1,%%eax
movl %2,%%ebx
movl %3,%%ecx
ColorTableLoop:
movl %%eax,%%edx
shr $10,%%edx
movb %%dl,(%%edi)
inc %%edi
addl %%ebx,%%eax
dec %%ecx
jnz ColorTableLoop
"
:
: "g" (&colortable), "g" (aktcolor), "g" (inccolor), "g" (w)
: "edi","eax","ebx","ecx","edx");
if (x1 < 0) {
ctablestart = -x1;
scrp = (unsigned char *) BaseAddr+y*ScrWidth;
w += x1;
} else {
scrp = (unsigned char *) BaseAddr+y*ScrWidth+x1;
ctablestart = 0;
}
if (x2 >= ScrWidth)
w -= x2-ScrWidth;
asm volatile(
"
movl %0,%%edi
movl %1,%%esi
movl %2,%%ecx
cmp $4,%%ecx
jb IsShortLine
pushl %%ecx
shr $2,%%ecx
pushl %%ecx
rep
movsl
popl %%eax
popl %%ecx
shl $2,%%eax
subl %%eax,%%ecx
IsShortLine:
rep
movsb
"
:
: "g" (scrp), "g" (&colortable[ctablestart]), "g" (w)
: "esi","edi"
);
}
#endif
/* Diese Routine zeichnet NUR horizontale Gouraud-Linien NUR im 256-Farb-Modus */
void DL_HLineGouraud256(int x1,int x2,int y,char c1,char c2)
{
int x,w;
unsigned char *scrp;
int aktcolor,inccolor;
if ((y < 0) || (y >= ScrHeight) || (x2 <= x1) ||
((x1 <= 0) && (x2 <= 0)) || ((x1 >= ScrWidth) && (x2 >= ScrWidth))) return;
w = x2-x1;
if (w == 1) {
scrp = BaseAddr->line[y]+x1;
_farpokeb(BaseAddr->seg,scrp,((c1+c2) >> 1));
return;
}
// if (w < 2) return;
aktcolor = c1 << 10;
inccolor = ((c2-c1) << 10) / w;
if (x1 < 0) {
scrp = BaseAddr->line[y];
w += x1;
} else scrp = BaseAddr->line[y]+x1;
if (x2 >= ScrWidth)
w -= x2-ScrWidth+1;
if ((int) scrp & 1) {
_farpokeb(BaseAddr->seg,scrp,aktcolor >> 10);
aktcolor += inccolor;
scrp++;
if (--w == 1) {
_farpokeb(BaseAddr->seg,scrp,aktcolor >> 10);
return;
}
}
/* Es werden immer 2 Pixel auf einmal berechnet und dann als Word zur
Grafikkarte geschickt, bei HLineGouraud256_LP wird der letzte Punkt
gezeichnet, falls die Linienlnge keine gerade Zahl war
Da diese Routine auf direkt auf den Bildschirm zeichnen knnen
soll, muá das Segment explizit per Segment-Override angegeben
werden (Segment in FS)
*/
asm volatile(
"
push %%fs
mov %4,%%fs
movl %0,%%edi
movl %1,%%ecx
sub $1,%%ecx
js HLineGouraud256Ende
inc %%ecx
movl %2,%%ebx
push %%ecx
shr $1,%%ecx
movl %3,%%esi
push %%ecx
jz HLineGouraud256_LP
HLineGouraud256XLoop:
mov %%ebx,%%eax
add %%esi,%%ebx
shr $10,%%eax
mov %%ebx,%%edx
add %%esi,%%ebx
shr $10,%%edx
mov %%dl,%%ah
movw %%ax,%%fs:(%%edi)
add $2,%%edi
dec %%ecx
jnz HLineGouraud256XLoop
pop %%ecx
pop %%edx
shl $1,%%ecx
sub %%ecx,%%edx
jz HLineGouraud256Ende
HLineGouraud256_LP:
shr $10,%%ebx
mov %%bl,%%al
movb %%bl,%%fs:(%%edi)
HLineGouraud256Ende:
pop %%fs
"
:
: "g" (scrp), "g" (w), "g" (aktcolor), "g" (inccolor), "g" (BaseAddr->seg)
: "edi","esi","eax","ebx","ecx","edx"
);
}
/* -------------------------- DL_FillPolyGouraud ----------------------- */
/* Fllt ein Polygon mittels Gouraud-Shading. Die Farben der Eckpunkte sind im
Array colors gespeichert. */
int DL_FillPolyGouraud(char nPoint,int points[][2],int colors[]) {
int x,y;
int i,top_point,bottom_point,top_point2; /* Der hchste und der niedrigste Punkt des Polygons */
int point_left,point_right,opoint; /* Nummer des akt. rechten/linken Eckpunktes des Polygons */
int leftswap,rightswap;
int top_y,bottom_y;
TInterpol ipol_left,ipol_right; /* Interpolationsvariablen fr beide Seiten */
int aktcolor_left,inccolor_left,aktcolor_right,inccolor_right;
int left_x,right_x; /* x-Koordinate des interpolierten linken/rechten Punkts */
int leftpointx,leftpointy;
int rightpointx,rightpointy;
int rightpointcol,leftpointcol;
top_y = 0xFFFF; /* Vorsicht: "top" bedeutet NIEDRIGE y-Koordinate */
bottom_y = -0xFFFF;
for (i = 0; i < nPoint; i++) { /* Hchsten und niedrigsten Punkt des Polygons finden */
x = points[i][0];
y = points[i][1];
if (y <= top_y) {
if (y == top_y) top_point2 = i;
else {
top_y = y;
top_point = top_point2 = i;
}
}
if (y > bottom_y) {
bottom_y = y;
bottom_point = i;
}
}
if ((bottom_y-top_y < 1) || ((top_y <= 0) && (bottom_y <= 0)) ||
((top_y >= ScrHeight) && (bottom_y >= ScrHeight))) return(0);
if ((top_point != top_point2) && (top_point == 0) && (top_point2 == nPoint-1) &&
(points[top_point][0] < points[top_point2][0])) return(0);
/* if (top_y < 0) top_y = 0;
if (bottom_y >= ScrHeight) bottom_y = ScrHeight-1;*/
/* Annahme: Polygon ist im Uhrzeigersinn gespeichert */
point_left = top_point-1; if (point_left < 0) point_left = nPoint-1;
if (point_left == top_point2) point_left--;
point_right = top_point2+1; if (point_right > nPoint-1) point_right = 0;
if (point_right == top_point) point_right++;
if (points[top_point][0] > points[top_point2][0])
if ((top_point == 0) && (top_point2 == nPoint-1)) xchg(top_point,top_point2);
else
if (!drawback) return(0);
else xchg(top_point,top_point2);
leftpointx = points[point_left][0]; leftpointy = points[point_left][1];
rightpointx = points[point_right][0]; rightpointy = points[point_right][1];
SetLine_Interpol(points[top_point][0],points[top_point][1],
leftpointx,leftpointy,&ipol_left);
aktcolor_left = colors[top_point] << 10;
if (ipol_left.a) inccolor_left = ((colors[point_left]-colors[top_point]) << 10) / ipol_left.a;
else inccolor_left = 0;
SetLine_Interpol(points[top_point2][0],points[top_point2][1],
rightpointx,rightpointy,&ipol_right);
aktcolor_right = colors[top_point2] << 10;
if (ipol_right.a) inccolor_right = ((colors[point_right]-colors[top_point2]) << 10) / ipol_right.a;
else inccolor_right = 0;
leftswap = ipol_left.swp;
rightswap = ipol_right.swp;
/* --------- Die Hauptschleife ---------------- */
for (y = top_y; y <= bottom_y; y++) {
leftpointcol = aktcolor_left >> 10;
rightpointcol = aktcolor_right >> 10;
if (leftswap) {
left_x = ipol_left.ipcoord;
Do_Interpol(&ipol_left);
aktcolor_left += inccolor_left;
}
else {
left_x = ipol_left.fcoord;
if (ipol_left.Dec_a)
do { aktcolor_left += inccolor_left; } while (!Do_Interpol(&ipol_left));
/* ipol-Offsets: a 0
dx 4
IncrF 8
IncrIP 12
Dec_a 16
fcoord 20
ipcoord 24
flim 28
swp 32
swapcolors 36 */
// Assembler-Interpolation vorlufig ausgeklammert, da sie sich nicht
// mit den Compiler-Optimierungen vertrgt
/* if (ipol_left.Dec_a)
asm volatile (
"
movl %1,%%edi
push %%edi
movl (%%edi),%%ecx
movl %0,%%edi
movl %2,%%ebx
movl 8(%%edi),%%edx
movl 16(%%edi),%%eax
movl 20(%%edi),%%esi
push %%ebp
movl (%%edi),%%ebp
Do_LeftInterpol:
addl %%ebx,%%ecx
addl %%edx,%%esi
subl %%eax,%%ebp
jns Do_LeftInterpol
movl %%esi,20(%%edi)
movl 4(%%edi),%%eax
addl %%eax,%%ebp
movl 12(%%edi),%%eax
addl %%eax,24(%%edi)
movl %%ebp,(%%edi)
pop %%ebp
pop %%edi
movl %%ecx,(%%edi)
"
:
: "g" (&ipol_left), "g" (&aktcolor_left), "g" (inccolor_left)
: "edi","eax","ebx","ecx","edx","esi");*/
}
if (rightswap) {
right_x = ipol_right.ipcoord;
Do_Interpol(&ipol_right);
aktcolor_right += inccolor_right;
}
else {
right_x = ipol_right.fcoord;
if (ipol_right.Dec_a)
do { aktcolor_right += inccolor_right; } while (!Do_Interpol(&ipol_right));
// siehe left-interpol
/* if (ipol_right.Dec_a)
asm volatile (
"
movl %1,%%edi
push %%edi
movl (%%edi),%%ecx
movl %0,%%edi
movl %2,%%ebx
movl 8(%%edi),%%edx
movl 16(%%edi),%%eax
movl 20(%%edi),%%esi
push %%ebp
movl (%%edi),%%ebp
Do_RightInterpol:
addl %%ebx,%%ecx
addl %%edx,%%esi
subl %%eax,%%ebp
jns Do_RightInterpol
movl %%esi,20(%%edi)
movl 4(%%edi),%%eax
addl %%eax,%%ebp
movl 12(%%edi),%%eax
addl %%eax,24(%%edi)
movl %%ebp,(%%edi)
pop %%ebp
pop %%edi
movl %%ecx,(%%edi)
"
:
: "g" (&ipol_right), "g" (&aktcolor_right), "g" (inccolor_right)
: "edi","eax","ebx","ecx","edx","esi");*/
}
if (!drawback)
if (left_x > right_x) return(0);
else ;
else if (left_x > right_x) { xchg(left_x,right_x); xchg(leftpointcol,rightpointcol); }
DL_HLineGouraud256(left_x,right_x,y,leftpointcol,rightpointcol);
/* --- Eventuell neue Eckpunkte setzen ---- */
if (y == leftpointy) { /* Wenn eine linke Kante fertiggezeichnet ist, neuen Punkt berechnen */
opoint = point_left;
point_left--;
if (point_left < 0) point_left += nPoint;
else if (point_left > nPoint-1) point_left -= nPoint;
leftpointx = points[point_left][0]; leftpointy = points[point_left][1];
SetLine_Interpol(points[opoint][0],points[opoint][1],
leftpointx,leftpointy,&ipol_left);
leftswap = ipol_left.swp;
aktcolor_left = colors[opoint] << 10;
if (ipol_left.a) inccolor_left = ((colors[point_left]-colors[opoint]) << 10) / ipol_left.a;
else inccolor_left = 0;
}
if (y == rightpointy) { /* Fr die rechte Kante ebenso.... */
opoint = point_right;
point_right++;
if (point_right < 0) point_right += nPoint;
else if (point_right > nPoint-1) point_right -= nPoint;
rightpointx = points[point_right][0]; rightpointy = points[point_right][1];
SetLine_Interpol(points[opoint][0],points[opoint][1],
rightpointx,rightpointy,&ipol_right);
rightswap = ipol_right.swp;
aktcolor_right = colors[opoint] << 10;
if (ipol_right.a) inccolor_right = ((colors[point_right]-colors[opoint]) << 10) / ipol_right.a;
else inccolor_right = 0;
}
}
return(1);
}
#if 0
void DL_FillPoly(char nPoint,int points[][2],unsigned char color) {
short int x,y;
char i,top_point,bottom_point,top_point2; /* Der hchste und der niedrigste Punkt des Polygons */
char point_left,point_right,opoint; /* Nummer des akt. rechten/linken Eckpunktes des Polygons */
short int top_y,bottom_y;
TInterpol ipol_left,ipol_right; /* Interpolationsvariablen fr beide Seiten */
char richtung; /* 1 .. Polygon ist im Uhrzeigersinn gespeichert
-1 .. Polygon ist entgegen dem Uhrzeigersinn gespeichert
Durch Addition dieses Wertes kann man den jeweils rechten
Eckpunkt errechnen */
int left_x,right_x; /* x-Koordinate des interpolierten linken/rechten Punkts */
top_y = ScrHeight; /* Vorsicht: "hoch" bedeutet NIEDRIGE y-Koordinate */
bottom_y = 0;
for (i = 0; i < nPoint; i++) { /* Hchsten und niedrigsten Punkt des Polygons finden */
if (points[i][1] <= top_y) {
if (points[i][1] == top_y) top_point2 = i;
else {
top_y = points[i][1];
top_point = top_point2 = i;
}
}
if (points[i][1] > bottom_y) {
bottom_y = points[i][1];
bottom_point = i;
}
}
/* Annahme: Polygon ist im Uhrzeigersinn gespeichert */
point_left = top_point-1; if (point_left < 0) point_left += nPoint;
point_right = top_point+1; if (point_right > nPoint-1) point_right -= nPoint;
if (points[point_left][0] > points[point_right][0]) { /* Polygon ist andersrum gespeichert */
if (!drawback) return;
xchg(point_left,point_right);
xchg(top_point,top_point2);
richtung = -1;
} else richtung = 1;
SetLine_Interpol(points[top_point][0],points[top_point][1],
points[point_left][0],points[point_left][1],&ipol_left);
SetLine_Interpol(points[top_point2][0],points[top_point2][1],
points[point_right][0],points[point_right][1],&ipol_right);
for (y = top_y; y < bottom_y; y++) {
if (ipol_left.swp) left_x = ipol_left.ipcoord;
else left_x = ipol_left.fcoord;
if (ipol_right.swp) right_x = ipol_right.ipcoord;
else right_x = ipol_right.fcoord;
GrHLine(left_x,right_x,y,color);
if (ipol_left.swp) Do_Interpol(&ipol_left);
else while (!Do_Interpol(&ipol_left)) ;
if (ipol_right.swp) Do_Interpol(&ipol_right) ;
else while (!Do_Interpol(&ipol_right)) ;
if (LineReady(&ipol_left)) { /* Wenn eine linke Kante fertiggezeichnet ist, neuen Punkt berechnen */
opoint = point_left;
point_left -= richtung;
if (point_left < 0) point_left += nPoint;
else if (point_left > nPoint-1) point_left -= nPoint;
SetLine_Interpol(points[opoint][0],points[opoint][1],
points[point_left][0],points[point_left][1],&ipol_left);
}
if (LineReady(&ipol_right)) { /* Fr die rechte Kante ebenso.... */
opoint = point_right;
point_right += richtung;
if (point_right < 0) point_right += nPoint;
else if (point_right > nPoint-1) point_right -= nPoint;
SetLine_Interpol(points[opoint][0],points[opoint][1],
points[point_right][0],points[point_right][1],&ipol_right);
}
}
}
#endif
void DL_Clear32(BITMAP *b)
{
int y,x;
unsigned char *scrp;
for (y = 0; y < b->h; y++) {
scrp = b->line[y];
asm volatile (
"
push %%es
mov %2,%%edi
mov %1,%%es
mov %0,%%ecx
shr $2,%%ecx
xor %%eax,%%eax
rep
stosl
pop %%es
"
:
:"g" (b->w), "g" (b->seg), "g" (scrp)
:"eax","ecx","edi");
}
}
#ifdef __cplusplus
}
#endif
#ifdef test_dlline
void main() {
int x,y;
double angle;
int poly[10][2],poly_rot[10][2],i;
int pointcolors[10];
struct time timestart,timeend;
unsigned int tstart,tend;
unsigned char *offscreen;
RetracePort = _farpeekw(_go32_conventional_mem_selector(),0x40*16+0x63);
GrSetMode(GR_width_height_color_graphics,320,200,256);
DLSprInit();
offscreen = (unsigned char *)malloc(ScrWidth*ScrHeight);
for (i = 0; i < 64; i++) GrSetColor(i+RedStart,i*4,0,0);
/* poly[0][0] = 100-160; poly[0][1] = 50-100;
poly[1][0] = 220-160; poly[1][1] = 50-100;
poly[2][0] = 220-160; poly[2][1] = 150-100;
poly[3][0] = 100-160; poly[3][1] = 150-100;
poly[0][0] = -160; poly[0][1] = -150;
poly[1][0] = 320-160; poly[1][1] = -150;
poly[2][0] = 320-160; poly[2][1] = 250-100;
poly[3][0] = -160; poly[3][1] = 250-100;
*/
poly[0][0] = 50; poly[0][1] = -50;
poly[1][0] = 100; poly[1][1] = -50;
poly[2][0] = 100; poly[2][1] = 50;
poly[3][0] = 50; poly[3][1] = -10;
pointcolors[0] = RedStart+60;
pointcolors[1] = RedStart+10;
pointcolors[2] = RedStart+10;
pointcolors[3] = RedStart+62;
drawback = 1;
DL_FillPolyGouraud(4,poly,pointcolors);
getchar();
return;
angle = M_PI/4;
for (i = 0; i < 4; i++) {
poly_rot[i][0] = (int)160+(poly[i][0]*cos(angle)-poly[i][1]*sin(angle));
poly_rot[i][1] = (int)100+(poly[i][0]*sin(angle)+poly[i][1]*cos(angle));
}
gettime(×tart);
tstart = LongTime(timestart.ti_hour,timestart.ti_min,timestart.ti_sec,timestart.ti_hund);
drawback = 0;
for (x = 0; x < 500; x++) {
angle += 0.01;
for (i = 0; i < 4; i++) {
poly_rot[i][0] = (int)160+(poly[i][0]*cos(angle)-poly[i][1]*sin(angle));
poly_rot[i][1] = (int)100+(poly[i][0]*sin(angle)+poly[i][1]*cos(angle));
}
BaseAddr = (unsigned int)offscreen;
DL_ClearScreen(); /* Lscht den Zwischenpuffer */
DL_FillPolyGouraud(4,poly_rot,pointcolors);
BaseAddr = 0xD0000000;
DL_BlitScreen320(offscreen);
/* angle += 0.01;
x = (int)(100*sin(angle));
y = (int)(70*cos(angle));
DL_LineGouraud(160-x,100-y,160+x,100+y,63,32);
WaitRetrace();
DL_Line(160-x,100-y,160+x,100+y,0);*/
}
gettime(&timeend);
tend = LongTime(timeend.ti_hour,timeend.ti_min,timeend.ti_sec,timeend.ti_hund);
GrSetMode(GR_80_25_text,80,25);
printf("\n\nZeit pro Bild: %g/100 sec",((float)(tend-tstart)/500));
printf("\nfps: : %g",((float)100/((float)(tend-tstart)/500)));
getchar();
}
#endif