00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Assert.h>
00023
00024 #include "GSpan.h"
00025 #include "GlideDrv.h"
00026 #include "GMain.h"
00027
00028 SPAN SpanLines[MAX_SPAN_LINES];
00029
00030 SPAN_MINMAX SMinMax[MAX_SPAN_LINES];
00031 SLIST ScanHash[MAX_SPANS];
00032
00033 BOOL PolyVisible = FALSE;
00034
00035 int32 NumWorldPixels = 0;
00036 int32 NumSpans = 0;
00037 int32 NumSpanPixels[MAX_SPAN_LINES];
00038 int32 PolysRendered = 0;
00039
00040 int32 CurrentSList = 0;
00041
00042 const int32 CEIL_FRACT = ( ( 1 << 16)-1);
00043 void DRIVERCC EdgeOutNoUV (int32 x1, int32 y1, int32 x2, int32 y2)
00044 {
00045 int32 Ctmp;
00046 int32 y;
00047 int32 x,m;
00048
00049 int32 Ydelta;
00050 int32 Dir;
00051 int32 Cx1, Cx2, Cy1, Cy2;
00052 SPAN *pSpans;
00053
00054 Cx1 = x1;
00055 Cx2 = x2;
00056 Cy1 = y1;
00057 Cy2 = y2;
00058
00059 if (Cy2 != Cy1)
00060 {
00061 Dir =0;
00062
00063 if (Cy2 < Cy1)
00064 {
00065 Dir =1;
00066
00067 Ctmp = Cx1;
00068 Cx1 = Cx2;
00069 Cx2 = Ctmp;
00070
00071 Ctmp = Cy1;
00072 Cy1 = Cy2;
00073 Cy2 = Ctmp;
00074
00075 }
00076
00077 Ydelta = (Cy2 - Cy1);
00078
00079 x = (Cx1 << 16) + CEIL_FRACT;
00080 m = (((Cx2 - Cx1))<<16) / Ydelta;
00081
00082 pSpans = &SpanLines[Cy1];
00083
00084 if (Dir == 0)
00085 {
00086 for (y = Cy1; y <= Cy2; y++)
00087 {
00088 pSpans->x1 = (x>>16);
00089 pSpans++;
00090 x += m;
00091 }
00092 }
00093 else
00094 {
00095 for (y = Cy1; y <= Cy2; y++)
00096 {
00097 pSpans->x2 = (x>>16);
00098 pSpans++;
00099 x += m;
00100 }
00101 }
00102 }
00103 }
00104
00105 void DRIVERCC AddSpanNoUV(int32 x1, int32 x2, int32 y)
00106 {
00107 int32 i, xx2;
00108 SLIST *LineStart = NULL;
00109 SLIST *Current;
00110
00111 assert(y >=0 && y < MAX_SPAN_LINES);
00112
00113
00114 if (NumSpanPixels[y] >= ClientWindow.Width)
00115 return;
00116
00117 if (x1 > x2)
00118 {
00119 i = x1;
00120 x1 = x2;
00121 x2 = i;
00122 }
00123
00124
00125
00126
00127 Current = SMinMax[y].First;
00128
00129
00130
00131 if (SMinMax[y].First == NULL)
00132 {
00133 SMinMax[y].First = NewSList();
00134 (SMinMax[y].First)->Last = NULL;
00135 (SMinMax[y].First)->Next = NULL;
00136 (SMinMax[y].First)->Min = x1;
00137 (SMinMax[y].First)->Max = x2;
00138 }
00139 else while (Current != NULL)
00140 {
00141 if (x1 >= Current->Min && x2 <= Current->Max)
00142 return;
00143
00144
00145 if (LineStart == NULL)
00146 {
00147 if (Current == SMinMax[y].First)
00148 if (x2 < Current->Min)
00149 {
00150 SLIST *NewMinMax = NewSList();
00151 NewMinMax->Next = Current;
00152 NewMinMax->Last = NULL;
00153 Current->Last = NewMinMax;
00154 SMinMax[y].First = NewMinMax;
00155 NewMinMax->Min = x1;
00156 NewMinMax->Max = x2;
00157 goto WasNull;
00158 }
00159
00160 if (Current->Next != NULL)
00161 if (x1 > Current->Max && x2 < (Current->Next)->Min)
00162 {
00163 SLIST *NewMinMax = NewSList();
00164 NewMinMax->Next = Current->Next;
00165 NewMinMax->Last = Current;
00166 (Current->Next)->Last = NewMinMax;
00167 Current->Next = NewMinMax;
00168 NewMinMax->Min = x1;
00169 NewMinMax->Max = x2;
00170 goto WasNull;
00171 }
00172
00173 if (Current->Next == NULL)
00174 if (x1 > Current->Max)
00175 {
00176 SLIST *NewMinMax = NewSList();
00177 Current->Next = NewMinMax;
00178 NewMinMax->Next = NULL;
00179 NewMinMax->Last = Current;
00180 NewMinMax->Min = x1;
00181 NewMinMax->Max = x2;
00182 goto WasNull;
00183 }
00184 }
00185
00186
00187 if (LineStart != NULL)
00188 if (x2 < Current->Min)
00189 goto WasNull;
00190
00191
00192
00193
00194
00195
00196 if (x1 < Current->Min && x2 > Current->Max)
00197 {
00198 xx2 = Current->Min-1;
00199 Current->Min = x1;
00200
00201 NumWorldPixels += xx2 - x1 + 1;
00202 NumSpanPixels[y] += xx2 - x1 + 1;
00203
00204 if (!PolyVisible)
00205 {
00206 PolysRendered++;
00207 PolyVisible = 1;
00208 }
00209
00210 x1 = Current->Max+1;
00211 Current->Max = x2;
00212 if (LineStart!=NULL)
00213 LineStart->Max = x2;
00214 else
00215 LineStart = Current;
00216 goto next;
00217 }
00218
00219 if (x1 <= Current->Max && x2 > Current->Max)
00220 {
00221 x1 = Current->Max+1;
00222 Current->Max = x2;
00223 LineStart = Current;
00224 goto next;
00225 }
00226 if (x1 < Current->Min && x2 >= Current->Min)
00227 {
00228 x2 = Current->Min-1;
00229 Current->Min = x1;
00230 if (LineStart!=NULL)
00231 LineStart->Max = Current->Max;
00232 goto WasNull;
00233 }
00234 next:;
00235 Current = Current->Next;
00236 }
00237 WasNull:;
00238
00239 if (!PolyVisible)
00240 {
00241 PolysRendered++;
00242 PolyVisible = 1;
00243 }
00244
00245 NumWorldPixels += x2 - x1 + 1;
00246 NumSpanPixels[y] += x2 - x1 + 1;
00247 }
00248
00249 void ResetSList(void)
00250 {
00251 CurrentSList = 0;
00252 NumSpans = 0;
00253 }
00254
00255 SLIST *NewSList(void)
00256 {
00257
00258 CurrentSList++;
00259 NumSpans++;
00260
00261 assert(CurrentSList < MAX_SPANS);
00262
00263 return &ScanHash[CurrentSList-1];
00264
00265 return NULL;
00266 }
00267
00268 void ResetSpans(int32 Rows)
00269 {
00270 int32 i;
00271
00272 for (i=0; i<Rows; i++)
00273 {
00274 SMinMax[i].First = NULL;
00275 NumSpanPixels[i] = 0;
00276 }
00277 ResetSList();
00278 }