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