00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "line.h"
00041
00042 #define LINE_T_MEMBERS \
00043 int dinc1, dinc2; \
00044 char xinc1, xinc2; \
00045 char yinc1, yinc2; \
00046 int numpixels; \
00047 int d
00048
00049 typedef struct {
00050 LINE_T_MEMBERS;
00051 } line_t;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #define LINE_T_FIRST dinc1
00069
00070 #define REVERSE_LINE_T_MEMBERS \
00071 int d; \
00072 int numpixels; \
00073 char yinc2, yinc1; \
00074 char xinc2, xinc1; \
00075 int dinc2, dinc1
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void compute_line(int x1, int y1, int x2, int y2, line_t *r) {
00092 int deltax, deltay;
00093
00094 deltax = (x2 - x1); if (deltax<0) deltax=-deltax;
00095 deltay = (y2 - y1); if (deltay<0) deltay=-deltay;
00096
00097 if (deltax >= deltay) {
00098 r->numpixels = deltax + 1;
00099 r->d = (2 * deltay) - deltax;
00100 r->dinc1 = deltay << 1;
00101 r->dinc2 = (deltay - deltax) << 1;
00102
00103 r->xinc1 = 1;
00104 r->xinc2 = 1;
00105
00106 r->yinc1 = 0;
00107 r->yinc2 = 1;
00108 } else {
00109 r->numpixels = deltay + 1;
00110 r->d = (2 * deltax) - deltay;
00111 r->dinc1 = deltax << 1;
00112 r->dinc2 = (deltax - deltay) << 1;
00113
00114 r->xinc1 = 0;
00115 r->xinc2 = 1;
00116
00117 r->yinc1 = 1;
00118 r->yinc2 = 1;
00119 }
00120
00121 if (x1 > x2) {
00122 r->xinc1 = -(r->xinc1);
00123 r->xinc2 = -(r->xinc2);
00124 }
00125 if (y1 > y2) {
00126 r->yinc1 = -(r->yinc1);
00127 r->yinc2 = -(r->yinc2);
00128 }
00129 }
00130
00131 void line(int x1, int y1, int x2, int y2)
00132 {
00133 REVERSE_LINE_T_MEMBERS;
00134
00135 int i;
00136 u_int addr, last;
00137 u_char bit, value;
00138
00139 compute_line(x1, y1, x2, y2, (line_t*)&LINE_T_FIRST);
00140
00141 addr = map_pixel(x1, y1);
00142 bit = map_subpixel(x1);
00143 value = vpeek(addr);
00144 last = addr;
00145
00146 for (i=0; i < numpixels; i++) {
00147 value |= bit;
00148
00149 if (d<0) {
00150 d += dinc1;
00151 if (xinc1) {
00152 if (xinc1 > 0) {
00153 bit >>= 1;
00154 if (!bit) {
00155 addr += 8;
00156 bit = 128;
00157 }
00158 } else {
00159 bit <<= 1;
00160 if (!bit) {
00161 addr -=8;
00162 bit = 1;
00163 }
00164 }
00165 }
00166 if (yinc1) {
00167 if (yinc1 > 0) {
00168 addr += 1;
00169 if (!(addr & 7))
00170 addr += 256 - 8;
00171 } else {
00172 addr -= 1;
00173 if ((addr & 7) == 7)
00174 addr -= 256 - 8;
00175 }
00176 }
00177 }
00178 else
00179 {
00180 d += dinc2;
00181 if (xinc2) {
00182 if (xinc2 > 0) {
00183 bit >>= 1;
00184 if (!bit) {
00185 addr += 8;
00186 bit = 128;
00187 }
00188 } else {
00189 bit <<= 1;
00190 if (!bit) {
00191 addr -=8;
00192 bit = 1;
00193 }
00194 }
00195 }
00196 if (yinc2) {
00197 if (yinc2 > 0) {
00198 addr += 1;
00199 if (!(addr & 7))
00200 addr += 256 - 8;
00201 } else {
00202 addr -= 1;
00203 if ((addr & 7) == 7)
00204 addr -= 256 - 8;
00205 }
00206 }
00207 }
00208 if (last != addr) {
00209 vpoke(last, value);
00210 value = vpeek(addr);
00211 last = addr;
00212 }
00213 }
00214 vpoke(addr, value);
00215 }
00216
00217 void line_slow(int x1, int y1, int x2, int y2)
00218 {
00219 REVERSE_LINE_T_MEMBERS;
00220
00221 int i, x, y;
00222 u_int addr, last;
00223 u_char value;
00224
00225 compute_line(x1, y1, x2, y2, (line_t*)&LINE_T_FIRST);
00226
00227 x = x1;
00228 y = y1;
00229 addr = map_pixel(x, y);
00230 last = addr;
00231 value = vpeek(addr);
00232
00233 for (i=0; i < numpixels; i++) {
00234 value |= map_subpixel(x);
00235 if (d<0) {
00236 d += dinc1;
00237 x += xinc1;
00238 y += yinc1;
00239 }
00240 else
00241 {
00242 d += dinc2;
00243 x += xinc2;
00244 y += yinc2;
00245 }
00246 addr = map_pixel(x, y);
00247 if (last != addr) {
00248 vpoke(last, value);
00249 value = vpeek(addr);
00250 last = addr;
00251 }
00252 }
00253 vpoke(addr, value);
00254 }
00255
00256 void surface_line(surface_t* s, int x1, int y1, int x2, int y2) {
00257 REVERSE_LINE_T_MEMBERS;
00258
00259 int i;
00260 u_int addr;
00261 u_char* data, bit;
00262
00263 compute_line(x1, y1, x2, y2, (line_t*)&LINE_T_FIRST);
00264
00265 data = s->data.ram;
00266 addr = map_pixel(x1, y1);
00267 bit = map_subpixel(x1);
00268
00269 i = numpixels;
00270 while (i--) {
00271 data[addr] |= bit;
00272
00273 if (d<0) {
00274 d += dinc1;
00275 if (xinc1) {
00276 if (xinc1 > 0) {
00277 bit >>= 1;
00278 if (!bit) {
00279 addr += 8;
00280 bit = 128;
00281 }
00282 } else {
00283 bit <<= 1;
00284 if (!bit) {
00285 addr -=8;
00286 bit = 1;
00287 }
00288 }
00289 }
00290 if (yinc1) {
00291 if (yinc1 > 0) {
00292 addr += 1;
00293 if (!(addr & 7))
00294 addr += 256 - 8;
00295 } else {
00296 addr -= 1;
00297 if ((addr & 7) == 7)
00298 addr -= 256 - 8;
00299 }
00300 }
00301 }
00302 else
00303 {
00304 d += dinc2;
00305 if (xinc2) {
00306 if (xinc2 > 0) {
00307 bit >>= 1;
00308 if (!bit) {
00309 addr += 8;
00310 bit = 128;
00311 }
00312 } else {
00313 bit <<= 1;
00314 if (!bit) {
00315 addr -=8;
00316 bit = 1;
00317 }
00318 }
00319 }
00320 if (yinc2) {
00321 if (yinc2 > 0) {
00322 addr += 1;
00323 if (!(addr & 7))
00324 addr += 256 - 8;
00325 } else {
00326 addr -= 1;
00327 if ((addr & 7) == 7)
00328 addr -= 256 - 8;
00329 }
00330 }
00331 }
00332 }
00333 }
00334
00335 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
00336 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
00337
00338 void calculate_side(int x1, int y1, int x2, int y2, int low[], int high[]) {
00339 int step;
00340 int lines;
00341 int ly, hy, ux;
00342 int *pl, *ph;
00343
00344 if (y2 < y1) {
00345 int t;
00346 t = x2; x2 = x1; x1 = t;
00347 t = y2; y2 = y1; y1 = t;
00348 }
00349 lines = y2 - y1;
00350
00351 pl = low + y1;
00352 ph = high + y1;
00353
00354 if (!lines) {
00355 ly = *pl; hy = *ph;
00356 if (x1 < x2) {
00357 low[y1] = MIN(ly, x1); high[y1] = MAX(hy, x2);
00358 } else {
00359 low[y1] = MIN(ly, x2); high[y1] = MAX(hy, x1);
00360 }
00361 return;
00362 }
00363
00364 step = i2f(x2 - x1);
00365 step /= lines;
00366 x1 = i2f(x1);
00367
00368 while (lines--) {
00369 ly = *pl; hy = *ph;
00370 ux = f2i(x1);
00371 *pl++ = MIN(ly, ux); *ph++ = MAX(hy, ux);
00372 x1 += step;
00373 }
00374 }
00375
00376 void surface_hline(surface_t* s, int x1, int y1, int x2, u_char value) {
00377 int bi, bf;
00378 u_char di, df, c;
00379 u_char *data;
00380
00381 if (x1 > x2)
00382 return;
00383
00384 data = s->data.ram + map_pixel(x1, y1);
00385
00386 bi = x1 >> 3;
00387 bf = x2 >> 3;
00388 di = x1 & 7;
00389 if (bi == bf) {
00390 c = ~(u_char)(255 >> (u_char)(x2 - x1 + 1)) >> di;
00391 *data = (c & value) | (*data & ~c);
00392 return;
00393 }
00394 df = x2 & 7;
00395 if (di > 0) {
00396 c = 255 >> di;
00397 *data = (c & value) | (*data & ~c);
00398 data += 8;
00399 ++bi;
00400 }
00401 if (df < 7) {
00402 --bf;
00403 }
00404 while (bi <= bf) {
00405 *data = value;
00406 data += 8;
00407 bi++;
00408 }
00409 if (df < 7) {
00410 c = ~(255 >> df);
00411 *data = (c & value) | (*data & ~c);
00412 }
00413 }
00414
00415 void hline(int x1, int y1, int x2, u_char value) {
00416 int bi, bf;
00417 u_char di, df, c;
00418 int data;
00419
00420 if (x1 > x2)
00421 return;
00422
00423 data = map_pixel(x1, y1);
00424
00425 bi = x1 >> 3;
00426 bf = x2 >> 3;
00427 di = x1 & 7;
00428 if (bi == bf) {
00429 c = ~(u_char)(255 >> (u_char)(x2 - x1 + 1)) >> di;
00430 vpoke(data, (c & value) | (vpeek(data) & ~c));
00431 return;
00432 }
00433 df = x2 & 7;
00434 if (di > 0) {
00435 c = 255 >> di;
00436 vpoke(data, (c & value) | (vpeek(data) & ~c));
00437 data += 8;
00438 ++bi;
00439 }
00440 if (df < 7) {
00441 --bf;
00442 }
00443 while (bi <= bf) {
00444 vpoke(data, value);
00445 data += 8;
00446 bi++;
00447 }
00448 if (df < 7) {
00449 c = ~(255 >> df);
00450 vpoke(data, (c & value) | (vpeek(data) & ~c));
00451 }
00452 }
00453
00454 #asm
00455 psect data
00456
00457 global _dithpat
00458 _dithpat:
00459 defb 00000000B
00460 defb 00000000B
00461
00462 defb 00000000B
00463 defb 10101010B
00464
00465 defb 01010101B
00466 defb 10101010B
00467
00468 defb 11111111B
00469 defb 10101010B
00470
00471 defb 11111111B
00472 defb 11111111B
00473 #endasm