00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Windows.h>
00023 #include <Assert.h>
00024
00025 #include "D3DDrv.h"
00026 #include "GSpan.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)
00085 {
00086 for (y = Cy1; y <= Cy2; y++, pSpans++)
00087 {
00088 pSpans->x1 = (x>>16);
00089 x += m;
00090 }
00091 }
00092 else
00093 {
00094 for (y = Cy1; y <= Cy2; y++, pSpans++)
00095 {
00096 pSpans->x2 = (x>>16);
00097 x += m;
00098 }
00099 }
00100 }
00101 }
00102
00103 void DRIVERCC AddSpanNoUV(int32 x1, int32 x2, int32 y)
00104 {
00105 int32 i, xx2;
00106 SLIST *LineStart;
00107 SLIST *Current;
00108 SPAN_MINMAX *pSList;
00109
00110 assert(y >=0 && y < MAX_SPAN_LINES);
00111
00112 if (NumSpanPixels[y] >= ClientWindow.Width)
00113 return;
00114
00115 if (x1 > x2)
00116 {
00117 i = x1;
00118 x1 = x2;
00119 x2 = i;
00120 }
00121
00122
00123
00124
00125 Current = SMinMax[y].First;
00126
00127 LineStart = NULL;
00128
00129 pSList = &SMinMax[y];
00130
00131
00132
00133 if (!pSList->First)
00134 {
00135 pSList->First = NewSList();
00136 pSList->First->Last = NULL;
00137 pSList->First->Next = NULL;
00138 pSList->First->Min = x1;
00139 pSList->First->Max = x2;
00140 }
00141 else while (Current != NULL)
00142 {
00143 if (x1 >= Current->Min && x2 <= Current->Max)
00144 return;
00145
00146
00147 if (LineStart == NULL)
00148 {
00149 if (Current == pSList->First)
00150 if (x2 < Current->Min)
00151 {
00152 SLIST *NewMinMax = NewSList();
00153 NewMinMax->Next = Current;
00154 NewMinMax->Last = NULL;
00155 Current->Last = NewMinMax;
00156 pSList->First = NewMinMax;
00157 NewMinMax->Min = x1;
00158 NewMinMax->Max = x2;
00159 goto WasNull;
00160 }
00161
00162 if (Current->Next != NULL)
00163 if (x1 > Current->Max && x2 < (Current->Next)->Min)
00164 {
00165 SLIST *NewMinMax = NewSList();
00166 NewMinMax->Next = Current->Next;
00167 NewMinMax->Last = Current;
00168 Current->Next->Last = NewMinMax;
00169 Current->Next = NewMinMax;
00170 NewMinMax->Min = x1;
00171 NewMinMax->Max = x2;
00172 goto WasNull;
00173 }
00174
00175 if (Current->Next == NULL)
00176 if (x1 > Current->Max)
00177 {
00178 SLIST *NewMinMax = NewSList();
00179 Current->Next = NewMinMax;
00180 NewMinMax->Next = NULL;
00181 NewMinMax->Last = Current;
00182 NewMinMax->Min = x1;
00183 NewMinMax->Max = x2;
00184 goto WasNull;
00185 }
00186 }
00187
00188
00189 if (LineStart != NULL)
00190 if (x2 < Current->Min)
00191 goto WasNull;
00192
00193
00194
00195
00196
00197
00198 if (x1 < Current->Min && x2 > Current->Max)
00199 {
00200 xx2 = Current->Min-1;
00201 Current->Min = x1;
00202
00203 NumWorldPixels += xx2 - x1 + 1;
00204 NumSpanPixels[y] += xx2 - x1 + 1;
00205
00206 if (!PolyVisible)
00207 {
00208 PolysRendered++;
00209 PolyVisible = 1;
00210 }
00211
00212 x1 = Current->Max+1;
00213 Current->Max = x2;
00214 if (LineStart!=NULL)
00215 LineStart->Max = x2;
00216 else
00217 LineStart = Current;
00218 goto next;
00219 }
00220
00221 if (x1 <= Current->Max && x2 > Current->Max)
00222 {
00223 x1 = Current->Max+1;
00224 Current->Max = x2;
00225 LineStart = Current;
00226 goto next;
00227 }
00228 if (x1 < Current->Min && x2 >= Current->Min)
00229 {
00230 x2 = Current->Min-1;
00231 Current->Min = x1;
00232 if (LineStart!=NULL)
00233 LineStart->Max = Current->Max;
00234 goto WasNull;
00235 }
00236 next:;
00237 Current = Current->Next;
00238 }
00239 WasNull:;
00240
00241 if (!PolyVisible)
00242 {
00243 PolysRendered++;
00244 PolyVisible = 1;
00245 }
00246
00247 NumWorldPixels += x2 - x1 + 1;
00248 NumSpanPixels[y] += x2 - x1 + 1;
00249 }
00250
00251 void ResetSList(void)
00252 {
00253 CurrentSList = 0;
00254 NumSpans = 0;
00255 }
00256
00257 SLIST *NewSList(void)
00258 {
00259
00260 CurrentSList++;
00261 NumSpans++;
00262
00263 assert(CurrentSList < MAX_SPANS);
00264
00265 return &ScanHash[CurrentSList-1];
00266
00267 return NULL;
00268 }
00269
00270 void ResetSpans(int32 Rows)
00271 {
00272 int32 i;
00273
00274 for (i=0; i<Rows; i++)
00275 {
00276 SMinMax[i].First = NULL;
00277 NumSpanPixels[i] = 0;
00278 }
00279 ResetSList();
00280 NumWorldPixels = 0;
00281 }