Fixed audio playing
[kvidha.git] / dblbuf.c
1 #include "executor.h"\r
2 #include "kvidha.h"\r
3 #include "sb.h"\r
4 #include "newdb.h"\r
5 \r
6 static unsigned char MMXBuffer[8];\r
7 \r
8 void DBFillScreen(unsigned long c)\r
9 {\r
10     int i;\r
11     unsigned long *p;\r
12     \r
13     p = (unsigned long *)DblBuffer;\r
14     for(i = 0; i < 64000; i++)\r
15         *(p++) = c;\r
16 }\r
17 \r
18 void DBSetClip(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)\r
19 {\r
20     clip_x1 = x1;\r
21     clip_x2 = x2;\r
22     clip_y1 = y1;\r
23     clip_y2 = y2;\r
24 }\r
25 \r
26 unsigned long DBPoint(unsigned short x, unsigned short y)\r
27 {\r
28     return(*(unsigned long *)&DblBuffer[((unsigned long)y << 10) + ((unsigned long)y << 8) + ((unsigned long)x << 2)]);\r
29 }\r
30 \r
31 /*void DBPSet(unsigned short x, unsigned short y, unsigned long c)\r
32 {\r
33     *(unsigned long *)&DblBuffer[((unsigned long)y << 10) + ((unsigned long)y << 8) + ((unsigned long)x << 2)] = c;\r
34 }*/\r
35 \r
36 void DBPSetC(unsigned short x, unsigned short y, unsigned long c)\r
37 {\r
38     if ((x >= clip_x1) && (x <= clip_x2) && (y >= clip_y1) && (y <= clip_y2))\r
39         *(unsigned long *)&DblBuffer[((unsigned long)y << 10) + ((unsigned long)y << 8) + ((unsigned long)x << 2)] = c;\r
40 }\r
41 \r
42 void DBPSetCTrans(unsigned short x, unsigned short y, unsigned long c, unsigned char Method)\r
43 {\r
44     if ((x >= clip_x1) && (x <= clip_x2) && (y >= clip_y1) && (y <= clip_y2))\r
45         TransOps[Method]((unsigned long *)&DblBuffer[((unsigned long)y << 10) + ((unsigned long)y << 8) + ((unsigned long)x << 2)], c);\r
46 }\r
47 \r
48 void DBFRect(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned long c)\r
49 {\r
50     unsigned short y, x;\r
51 \r
52     for(y = y1; y <= y2; y++)\r
53     {\r
54         for(x = x1; x <= x2; x++)\r
55         {\r
56             DBPSetC(x, y, c);\r
57         }\r
58     }\r
59 }\r
60 \r
61 void DBFRectTrans(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned long c, unsigned char Method)\r
62 {\r
63     unsigned short y, x;\r
64 \r
65     for(y = y1; y <= y2; y++)\r
66     {\r
67         for(x = x1; x <= x2; x++)\r
68         {\r
69             DBPSetCTrans(x, y, c, Method);\r
70         }\r
71     }\r
72 }\r
73 \r
74 void DBFCircle(signed short x, signed short y, unsigned short r, unsigned long Color, unsigned char Filled, float Aspect)\r
75 {\r
76     signed short y1, y2, x1, x2;\r
77     signed short cy, cx;\r
78     unsigned long r2;\r
79 \r
80     if(y - r < clip_y1)\r
81     {\r
82         y1 = clip_y1;\r
83         cy = clip_y1 - y;\r
84     } else {\r
85         y1 = y - r;\r
86         cy = -r;\r
87     }\r
88     if(y + r > clip_y2)\r
89         y2 = clip_y2 - y;\r
90     else\r
91         y2 = r;\r
92     for(r2 = (unsigned long)r * (unsigned long)r; cy <= y2; cy++)\r
93     {\r
94         x1 = x - (x2 = (sqrt(r2 - ((unsigned long)cy * (unsigned long)cy)) * Aspect));\r
95         x2 += x;\r
96         if(Filled == 1)\r
97         {\r
98             if(x1 < clip_x1)\r
99                 x1 = clip_x1;\r
100             if(x2 > clip_x2)\r
101                 x2 = clip_x2;\r
102             for(cx = x1; cx <= x2; cx++)\r
103                 DBPSetC(cx, y1, Color);\r
104         } else {\r
105             DBPSetC(x1, y1, Color);\r
106             DBPSetC(x2, y1, Color);\r
107         }\r
108         y1++;\r
109     }\r
110 }\r
111 \r
112 void DBFCircleTrans(signed short x, signed short y, unsigned short r, unsigned long Color, unsigned char Filled, float Aspect, unsigned char Method)\r
113 {\r
114     signed short y1, y2, x1, x2;\r
115     signed short cy, cx;\r
116     unsigned long r2;\r
117 \r
118     if(y - r < clip_y1)\r
119     {\r
120         y1 = clip_y1;\r
121         cy = clip_y1 - y;\r
122     } else {\r
123         y1 = y - r;\r
124         cy = -r;\r
125     }\r
126     if(y + r > clip_y2)\r
127         y2 = clip_y2 - y;\r
128     else\r
129         y2 = r;\r
130     for(r2 = (unsigned long)r * (unsigned long)r; cy <= y2; cy++)\r
131     {\r
132         x1 = x - (x2 = (sqrt(r2 - ((unsigned long)cy * (unsigned long)cy)) * Aspect));\r
133         x2 += x;\r
134         if(Filled == 1)\r
135         {\r
136             if(x1 < clip_x1)\r
137                 x1 = clip_x1;\r
138             if(x2 > clip_x2)\r
139                 x2 = clip_x2;\r
140             for(cx = x1; cx <= x2; cx++)\r
141                 DBPSetCTrans(cx, y1, Color, Method);\r
142         } else {\r
143             DBPSetCTrans(x1, y1, Color, Method);\r
144             DBPSetCTrans(x2, y1, Color, Method);\r
145         }\r
146         y1++;\r
147     }\r
148 }\r
149 \r
150 void DBFCircleFadedTrans(signed short x, signed short y, unsigned short r, unsigned long Color, float Aspect, unsigned char Method)\r
151 {\r
152     signed short y1, y2, x1, x2;\r
153     signed short cy, cx;\r
154     unsigned long r2;\r
155     struct ColorType MainColor, MidColor, CurColor;\r
156     unsigned short RE, GE, BE;\r
157     signed char Inc;\r
158 \r
159     if(y - r < clip_y1)\r
160     {\r
161         y1 = clip_y1;\r
162         cy = clip_y1 - y;\r
163     } else {\r
164         y1 = y - r;\r
165         cy = -r;\r
166     }\r
167     if(y + r > clip_y2)\r
168         y2 = clip_y2 - y;\r
169     else\r
170         y2 = r;\r
171     MainColor = *(struct ColorType *)&Color;\r
172     for(r2 = (unsigned long)r * (unsigned long)r; cy <= y2; cy++)\r
173     {\r
174         if(cy < 0)\r
175         {\r
176             MidColor.R = (unsigned char)(((unsigned long)MainColor.R * (unsigned long)(r + cy)) / (unsigned long)r);\r
177             MidColor.G = (unsigned char)(((unsigned long)MainColor.G * (unsigned long)(r + cy)) / (unsigned long)r);\r
178             MidColor.B = (unsigned char)(((unsigned long)MainColor.B * (unsigned long)(r + cy)) / (unsigned long)r);\r
179         } else {\r
180             MidColor.R = (unsigned char)(((unsigned long)MainColor.R * (unsigned long)(r - cy)) / (unsigned long)r);\r
181             MidColor.G = (unsigned char)(((unsigned long)MainColor.G * (unsigned long)(r - cy)) / (unsigned long)r);\r
182             MidColor.B = (unsigned char)(((unsigned long)MainColor.B * (unsigned long)(r - cy)) / (unsigned long)r);\r
183         }\r
184         *(unsigned long *)&CurColor = 0;\r
185         RE = GE = BE = 0;\r
186         x1 = x - (x2 = (sqrt(r2 - ((unsigned long)cy * (unsigned long)cy)) * Aspect));\r
187         x2 += x;\r
188         Inc = 1;\r
189         if(x1 < clip_x1)\r
190         {\r
191             CurColor.R = (unsigned char)(((unsigned long)(clip_x1 - x1) * (unsigned long)MidColor.R) / (unsigned long)r);\r
192             CurColor.G = (unsigned char)(((unsigned long)(clip_x1 - x1) * (unsigned long)MidColor.G) / (unsigned long)r);\r
193             CurColor.B = (unsigned char)(((unsigned long)(clip_x1 - x1) * (unsigned long)MidColor.B) / (unsigned long)r);\r
194             x1 = clip_x1;\r
195             if(x1 > x)\r
196                 Inc = -1;\r
197         }\r
198         if(x2 > clip_x2)\r
199             x2 = clip_x2;\r
200         for(cx = x1; cx <= x2; cx++)\r
201         {\r
202             if(cx == x)\r
203             {\r
204                 Inc = -1;\r
205                 RE = GE = BE = 0;\r
206             }\r
207             DBPSetCTrans(cx, y1, *(unsigned long *)&CurColor, Method);\r
208             RE += (unsigned short)MidColor.R;\r
209             GE += (unsigned short)MidColor.G;\r
210             BE += (unsigned short)MidColor.B;\r
211             while(RE > r)\r
212             {\r
213                 RE -= r;\r
214                 CurColor.R += Inc;\r
215             }\r
216             while(GE > r)\r
217             {\r
218                 GE -= r;\r
219                 CurColor.G += Inc;\r
220             }\r
221             while(BE > r)\r
222             {\r
223                 BE -= r;\r
224                 CurColor.B += Inc;\r
225             }\r
226         }\r
227         y1++;\r
228     }\r
229 }\r
230 \r
231 void DBFPoly(signed short x1, signed short y1, signed short x2, signed short y2, signed short x3, signed short y3, unsigned long Color)\r
232 {\r
233     signed short x[3], y[3], Temp, m1, m2;\r
234     signed short i, o, StartX, StopX;\r
235     signed long k1, k2, cx1, cx2;\r
236 \r
237     x[0] = x1; y[0] = y1;\r
238     x[1] = x2; y[1] = y2;\r
239     x[2] = x3; y[2] = y3;\r
240     for(i = 0; i < 2; i++)\r
241     {\r
242         for(o = i + 1; o < 3; o++)\r
243         {\r
244             if(y[o] < y[i])\r
245             {\r
246                 Temp = y[o];\r
247                 y[o] = y[i];\r
248                 y[i] = Temp;\r
249                 Temp = x[o];\r
250                 x[o] = x[i];\r
251                 x[i] = Temp;\r
252             }\r
253         }\r
254     }\r
255     cx1 = cx2 = x[0] << 16;\r
256     if(y[0] == y[1])\r
257     {\r
258         cx1 = x[1] << 16;\r
259     } else {\r
260         k1 = ((signed long)(x[1] - x[0]) << 16) / (signed long)(y[1] - y[0]);\r
261         k2 = ((signed long)(x[2] - x[0]) << 16) / (signed long)(y[2] - y[0]);\r
262         for(i = y[0]; i <= y[1]; i++)\r
263         {\r
264             if((i >= clip_y1) && (i <= clip_y2))\r
265             {\r
266                 if(cx1 > cx2)\r
267                 {\r
268                     StartX = cx2 >> 16;\r
269                     StopX = cx1 >> 16;\r
270                 } else {\r
271                     StartX = cx1 >> 16;\r
272                     StopX = cx2 >> 16;\r
273                 }\r
274                 if(StartX < clip_x1)\r
275                     StartX = clip_x1;\r
276                 if(StopX > clip_x2)\r
277                     StopX = clip_x2;\r
278                 if((StartX <= clip_x2) && (StopX >= clip_x1))\r
279                 {\r
280                     for(o = StartX; o <= StopX; o++)\r
281                         DBPSetC(o, i, Color);\r
282                 }\r
283             }\r
284             /*asm("\r
285             cld\r
286             rep stosl\r
287             "\r
288             :\r
289             : "a" (Color), "c" ((abs(x1 - x2) >> 16) + 1), "D" ((unsigned long)DblBuffer + ((unsigned long)i << 10) + ((unsigned long)i << 8) + (((x1 < x2)?x1:x2) >> 14))\r
290             );*/\r
291             cx1 += k1;\r
292             cx2 += k2;\r
293         }\r
294     }\r
295     if(y[1] == y[2])\r
296         return;\r
297     k1 = ((signed long)(x[2] - x[1]) << 16) / (signed long)(y[2] - y[1]);\r
298     k2 = ((signed long)(x[2] - x[0]) << 16) / (signed long)(y[2] - y[0]);\r
299     for(i = y[1] + 1; i <= y[2]; i++)\r
300     {\r
301         if((i >= clip_y1) && (i <= clip_y2))\r
302         {\r
303             if(cx1 > cx2)\r
304             {\r
305                 StartX = cx2 >> 16;\r
306                 StopX = cx1 >> 16;\r
307             } else {\r
308                 StartX = cx1 >> 16;\r
309                 StopX = cx2 >> 16;\r
310             }\r
311             if(StartX < clip_x1)\r
312                 StartX = clip_x1;\r
313             if(StopX > clip_x2)\r
314                 StopX = clip_x2;\r
315             if((StartX <= clip_x2) && (StopX >= clip_x1))\r
316             {\r
317                 for(o = StartX; o <= StopX; o++)\r
318                     DBPSetC(o, i, Color);\r
319             }\r
320         }\r
321         /*asm("\r
322         cld\r
323         rep stosl\r
324         "\r
325         :\r
326         : "a" (Color), "c" ((abs(x1 - x2) >> 16) + 1), "D" ((unsigned long)DblBuffer + ((unsigned long)i << 10) + ((unsigned long)i << 8) + (((x1 < x2)?x1:x2) >> 14))\r
327         );*/\r
328         cx1 += k1;\r
329         cx2 += k2;\r
330     }\r
331 }\r
332 \r
333 void DBFPolyTrans(signed short x1, signed short y1, signed short x2, signed short y2, signed short x3, signed short y3, unsigned long Color, unsigned char Method)\r
334 {\r
335     signed short x[3], y[3], Temp, m1, m2;\r
336     signed short i, o, StartX, StopX;\r
337     signed long k1, k2, cx1, cx2;\r
338 \r
339     x[0] = x1; y[0] = y1;\r
340     x[1] = x2; y[1] = y2;\r
341     x[2] = x3; y[2] = y3;\r
342     for(i = 0; i < 2; i++)\r
343     {\r
344         for(o = i + 1; o < 3; o++)\r
345         {\r
346             if(y[o] < y[i])\r
347             {\r
348                 Temp = y[o];\r
349                 y[o] = y[i];\r
350                 y[i] = Temp;\r
351                 Temp = x[o];\r
352                 x[o] = x[i];\r
353                 x[i] = Temp;\r
354             }\r
355         }\r
356     }\r
357     cx1 = cx2 = x[0] << 16;\r
358     if(y[0] == y[1])\r
359     {\r
360         cx1 = x[1] << 16;\r
361     } else {\r
362         k1 = ((signed long)(x[1] - x[0]) << 16) / (signed long)(y[1] - y[0]);\r
363         k2 = ((signed long)(x[2] - x[0]) << 16) / (signed long)(y[2] - y[0]);\r
364         for(i = y[0]; i <= y[1]; i++)\r
365         {\r
366             if((i >= clip_y1) && (i <= clip_y2))\r
367             {\r
368                 if(cx1 > cx2)\r
369                 {\r
370                     StartX = cx2 >> 16;\r
371                     StopX = cx1 >> 16;\r
372                 } else {\r
373                     StartX = cx1 >> 16;\r
374                     StopX = cx2 >> 16;\r
375                 }\r
376                 if(StartX < clip_x1)\r
377                     StartX = clip_x1;\r
378                 if(StopX > clip_x2)\r
379                     StopX = clip_x2;\r
380                 if((StartX <= clip_x2) && (StopX >= clip_x1))\r
381                 {\r
382                     for(o = StartX; o <= StopX; o++)\r
383                         DBPSetCTrans(o, i, Color, Method);\r
384                 }\r
385             }\r
386             cx1 += k1;\r
387             cx2 += k2;\r
388         }\r
389         cx1 -= k1;\r
390         cx2 -= k2;\r
391     }\r
392     if(y[1] == y[2])\r
393         return;\r
394     k1 = ((signed long)(x[2] - x[1]) << 16) / (signed long)(y[2] - y[1]);\r
395     k2 = ((signed long)(x[2] - x[0]) << 16) / (signed long)(y[2] - y[0]);\r
396     for(i = y[1] + 1; i <= y[2]; i++)\r
397     {\r
398         if((i >= clip_y1) && (i <= clip_y2))\r
399         {\r
400             if(cx1 > cx2)\r
401             {\r
402                 StartX = cx2 >> 16;\r
403                 StopX = cx1 >> 16;\r
404             } else {\r
405                 StartX = cx1 >> 16;\r
406                 StopX = cx2 >> 16;\r
407             }\r
408             if(StartX < clip_x1)\r
409                 StartX = clip_x1;\r
410             if(StopX > clip_x2)\r
411                 StopX = clip_x2;\r
412             if((StartX <= clip_x2) && (StopX >= clip_x1))\r
413             {\r
414                 for(o = StartX; o <= StopX; o++)\r
415                     DBPSetCTrans(o, i, Color, Method);\r
416             }\r
417         }\r
418         cx1 += k1;\r
419         cx2 += k2;\r
420     }\r
421 }\r
422 \r
423 void DBLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned long c1, unsigned long c2)\r
424 {\r
425     signed short dx, dy, x, y;\r
426     signed short xi, yi, d;\r
427     unsigned short i;\r
428     unsigned char c;\r
429 \r
430     dx = x2 - x1;\r
431     dy = y2 - y1;\r
432     if(dx >= 0)\r
433     {\r
434         xi = 1;\r
435     } else {\r
436         xi = -1;\r
437         dx = -dx;\r
438     }\r
439     if(dy >= 0)\r
440     {\r
441         yi = 1;\r
442     } else {\r
443         yi = -1;\r
444         dy = -dy;\r
445     }\r
446     d = 0;\r
447     x = x1;\r
448     y = y1;\r
449     c = 0;\r
450     if(dx > dy)\r
451     {\r
452         for(i = 0; i <= dx; i++)\r
453         {\r
454             DBPSetC((unsigned short)x, (unsigned short)y, ((c ^= 1) == 0)?c2:c1);\r
455             d += dy;\r
456             if(d > dx)\r
457             {\r
458                 d -= dx;\r
459                 y += yi;\r
460             }\r
461             x += xi;\r
462         }\r
463     } else {\r
464         for(i = 0; i <= dy; i++)\r
465         {\r
466             DBPSetC((unsigned short)x, (unsigned short)y, ((c ^= 1) == 0)?c2:c1);\r
467             d += dx;\r
468             if(d > 0)\r
469             {\r
470                 d -= dy;\r
471                 x += xi;\r
472             }\r
473             y += yi;\r
474         }\r
475     }\r
476 }\r
477 \r
478 void DBLineTrans(signed short x1, signed short y1, signed short x2, signed short y2, unsigned long c1, unsigned long c2, unsigned char Method)\r
479 {\r
480     signed short dx, dy, x, y;\r
481     signed short xi, yi, d;\r
482     unsigned short i;\r
483     unsigned char c;\r
484 \r
485     dx = x2 - x1;\r
486     dy = y2 - y1;\r
487     if(dx >= 0)\r
488     {\r
489         xi = 1;\r
490     } else {\r
491         xi = -1;\r
492         dx = -dx;\r
493     }\r
494     if(dy >= 0)\r
495     {\r
496         yi = 1;\r
497     } else {\r
498         yi = -1;\r
499         dy = -dy;\r
500     }\r
501     d = 0;\r
502     x = x1;\r
503     y = y1;\r
504     c = 0;\r
505     if(dx > dy)\r
506     {\r
507         for(i = 0; i <= dx; i++)\r
508         {\r
509             DBPSetCTrans((unsigned short)x, (unsigned short)y, ((c ^= 1) == 0)?c2:c1, Method);\r
510             d += dy;\r
511             if(d > dx)\r
512             {\r
513                 d -= dx;\r
514                 y += yi;\r
515             }\r
516             x += xi;\r
517         }\r
518     } else {\r
519         for(i = 0; i <= dy; i++)\r
520         {\r
521             DBPSetCTrans((unsigned short)x, (unsigned short)y, ((c ^= 1) == 0)?c2:c1, Method);\r
522             d += dx;\r
523             if(d > 0)\r
524             {\r
525                 d -= dy;\r
526                 x += xi;\r
527             }\r
528             y += yi;\r
529         }\r
530     }\r
531 }\r
532 \r
533 void DBCopyBuffer(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc)\r
534 {\r
535     unsigned char *WorkOffset;\r
536     unsigned long offset;\r
537     unsigned long OffsetAdd;\r
538     unsigned short cx, cy;\r
539     unsigned long data;\r
540 \r
541     offset = 0;\r
542     WorkOffset = DblBuffer + ((signed long)y << 10) + ((signed long)y << 8) + ((signed long)x << 2);\r
543     OffsetAdd = 1280 - (w << 2);\r
544     for(cy = 0; cy < h; cy++)\r
545     {\r
546         for(cx = 0; cx < w; cx++)\r
547         {\r
548             data = *(unsigned long *)Buffer;\r
549             if(data != bgc)\r
550                 *(unsigned long *)WorkOffset = data;\r
551             Buffer += 4;\r
552             WorkOffset += 4;\r
553         }\r
554         WorkOffset += OffsetAdd;\r
555     }\r
556 /*\r
557     DBCopyBufferAsm(x, y, Buffer, w, h, bgc);\r
558 */\r
559 }\r
560 \r
561 void DBCopyBufferClip(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc)\r
562 {\r
563     unsigned char *WorkOffset;\r
564     unsigned long OffsetAdd1, OffsetAdd2;\r
565     signed short cx, cy, sx, sy, cw, ch;\r
566     unsigned long data;\r
567 \r
568     if((x > clip_x2) || ((x + w) < clip_x1) || (y > clip_y2) || ((y + h) < clip_y1))\r
569         return;\r
570     if((x >= clip_x1) && ((x + w) <= clip_x2) && (y >= clip_y1) && ((y + h) <= clip_y2))\r
571     {\r
572         DBCopyBuffer(x, y, Buffer, w, h, bgc);\r
573         return;\r
574     }\r
575     sx = (x < clip_x1)?(clip_x1 - x):0;\r
576     sy = (y < clip_y1)?(clip_y1 - y):0;\r
577     cw = (x + (signed short)w - 1 > clip_x2)?(clip_x2 - x + 1):(signed short)w;\r
578     ch = (y + (signed short)h - 1 > clip_y2)?(clip_y2 - y + 1):(signed short)h;\r
579     Buffer += (sx + (sy * w)) << 2;\r
580     OffsetAdd1 = (sx + w - cw) << 2;\r
581     OffsetAdd2 = 1280 - ((cw - sx) << 2);\r
582     WorkOffset = DblBuffer + ((signed long)(y + sy) << 10) + ((signed long)(y + sy) << 8) + ((signed long)(x + sx) << 2);\r
583     for(cy = 0; cy < ch - sy; cy++)\r
584     {\r
585         for(cx = 0; cx < cw - sx; cx++)\r
586         {\r
587             data = *(unsigned long *)Buffer;\r
588             if(data != bgc)\r
589                 *(unsigned long *)WorkOffset = data;\r
590             Buffer += 4;\r
591             WorkOffset += 4;\r
592         }\r
593         Buffer += OffsetAdd1;\r
594         WorkOffset += OffsetAdd2;\r
595     }\r
596 }\r
597 \r
598 void DBSpriteLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned char *Buffer, unsigned short w, unsigned short h)\r
599 {\r
600     signed short dx, dy, x, y;\r
601     signed short xi, yi, d;\r
602     unsigned short i;\r
603     unsigned char c;\r
604 \r
605     dx = x2 - x1;\r
606     dy = y2 - y1;\r
607     if(dx >= 0)\r
608     {\r
609         xi = 1;\r
610     } else {\r
611         xi = -1;\r
612         dx = -dx;\r
613     }\r
614     if(dy >= 0)\r
615     {\r
616         yi = 1;\r
617     } else {\r
618         yi = -1;\r
619         dy = -dy;\r
620     }\r
621     d = 0;\r
622     x = x1;\r
623     y = y1;\r
624     c = 0;\r
625     if(dx > dy)\r
626     {\r
627         for(i = 0; i <= dx; i++)\r
628         {\r
629             DBCopyBufferClip((unsigned short)x, (unsigned short)y, Buffer, w, h, 0);\r
630             d += dy;\r
631             if(d > dx)\r
632             {\r
633                 d -= dx;\r
634                 y += yi;\r
635             }\r
636             x += xi;\r
637         }\r
638     } else {\r
639         for(i = 0; i <= dy; i++)\r
640         {\r
641             DBCopyBufferClip((unsigned short)x, (unsigned short)y, Buffer, w, h, 0);\r
642             d += dx;\r
643             if(d > 0)\r
644             {\r
645                 d -= dy;\r
646                 x += xi;\r
647             }\r
648             y += yi;\r
649         }\r
650     }\r
651 }\r
652 \r
653 void DBCopyBufferRotated(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc, signed short rx, signed short ry, unsigned short a)\r
654 {\r
655     signed short cx, cy, sx, sy, xd, yd;\r
656     unsigned long Data, OffsetMax;\r
657     signed long w1, h1;\r
658     signed long x0, y0, xn, yn;\r
659     signed long c, s;\r
660 \r
661     c = (signed long)(Cosine[a] * 0x10000);\r
662     s = (signed long)(Sine[a] * 0x10000);\r
663     if(a < 90)\r
664     {\r
665         w1 = (s * h) + (c * w);\r
666         h1 = (c * h) + (s * w);\r
667         x0 = (signed long)((Sine[a] * Sine[a] * (float)w) * 0x10000);\r
668         y0 = (signed long)(-(Sine[a] * Cosine[a] * (float)w) * 0x10000);\r
669         xd = 0;\r
670         yd = (signed short)((s * (signed long)w) >> 16);\r
671     } else if(a < 180)\r
672     {\r
673         w1 = (s * h) - (c * w);\r
674         h1 = (s * w) - (c * h);\r
675         x0 = (signed long)((w - ((Sine[a] * Cosine[a]) * (float)h)) * 0x10000);\r
676         y0 = (signed long)((Cosine[a] * Cosine[a] * (float)h) * 0x10000);\r
677         xd = (signed short)((-c * (signed long)w) >> 16);\r
678         yd = (signed short)(h1 >> 16);\r
679     } else if(a < 270)\r
680     {\r
681         w1 = -(s * h) - (c * w);\r
682         h1 = -(s * w) - (c * h);\r
683         x0 = (signed long)((Cosine[a] * Cosine[a] * (float)w) * 0x10000);\r
684         y0 = (signed long)((h + (Sine[a] * Cosine[a] * (float)w)) * 0x10000);\r
685         xd = (signed short)(w1 >> 16);\r
686         yd = (signed short)((-c * (signed long)h) >> 16);\r
687     } else {\r
688         w1 = (c * w) - (s * h);\r
689         h1 = (c * h) - (s * w);\r
690         x0 = (signed long)((Sine[a] * Cosine[a] * (float)h) * 0x10000);\r
691         y0 = (signed long)((Sine[a] * Sine[a] * (float)h) * 0x10000);\r
692         xd = (signed short)((-s * (signed long)h) >> 16);\r
693         yd = 0;\r
694     }\r
695     if((w1 & 0xFFFF) != 0)\r
696         w1 = (w1 & 0xFFFF0000) + 0x10000;\r
697     if((h1 & 0xFFFF) != 0)\r
698         h1 = (h1 & 0xFFFF0000) + 0x10000;\r
699     w1 >>= 16;\r
700     h1 >>= 16;\r
701     xd += (signed short)(((c * (signed long)rx) + (s * (signed long)ry)) >> 16);\r
702     yd += (signed short)(((c * (signed long)ry) - (s * (signed long)ry)) >> 16);\r
703     sy = y - yd;\r
704     for(cy = 0; cy < h1; cy++)\r
705     {\r
706         xn = x0;\r
707         yn = y0;\r
708         sx = x - xd;\r
709         for(cx = 0; cx < w1; cx++)\r
710         {\r
711             if((xn >= 0) && (yn >= 0) && (xn < (w << 16)) && (yn < (h << 16)))\r
712             {\r
713                 Data = ((unsigned long *)Buffer)[((xn & 0xFFFF0000) + ((yn & 0xFFFF0000) * w)) >> 16];\r
714                 if(Data != bgc)\r
715                     DBPSetC(sx, sy, Data);\r
716                 if((sx == x) && (sy == y))\r
717                     ((unsigned long *)Buffer)[((xn & 0xFFFF0000) + ((yn & 0xFFFF0000) * w)) >> 16] = MakeColor(255, 0, 0);\r
718             }\r
719             sx++;\r
720             xn += c;\r
721             yn += s;\r
722         }\r
723         x0 -= s;\r
724         y0 += c;\r
725         sy++;\r
726     }\r
727 }\r
728 \r
729 void ColorAdd(unsigned long *Bg, unsigned long Amount)\r
730 {\r
731     Color *c1;\r
732     Color c2;\r
733     unsigned short R, G, B;\r
734 \r
735     c1 = (Color *)Bg;\r
736     c2 = *(Color *)&Amount;\r
737     R = (unsigned short)c1->R + (unsigned short)c2.R;\r
738     G = (unsigned short)c1->G + (unsigned short)c2.G;\r
739     B = (unsigned short)c1->B + (unsigned short)c2.B;\r
740     if(R > 255)\r
741         R = 255;\r
742     if(G > 255)\r
743         G = 255;\r
744     if(B > 255)\r
745         B = 255;\r
746     c1->R = (unsigned char)R;\r
747     c1->G = (unsigned char)G;\r
748     c1->B = (unsigned char)B;\r
749 }\r
750 \r
751 void ColorSub(unsigned long *Bg, unsigned long Amount)\r
752 {\r
753     Color *c1;\r
754     Color c2;\r
755     signed short R, G, B;\r
756 \r
757     c1 = (Color *)Bg;\r
758     c2 = *(Color *)&Amount;\r
759     R = (unsigned short)c1->R - (unsigned short)c2.R;\r
760     G = (unsigned short)c1->G - (unsigned short)c2.G;\r
761     B = (unsigned short)c1->B - (unsigned short)c2.B;\r
762     if(R < 0)\r
763         R = 0;\r
764     if(G < 0)\r
765         G = 0;\r
766     if(B < 0)\r
767         B = 0;\r
768     c1->R = (unsigned char)R;\r
769     c1->G = (unsigned char)G;\r
770     c1->B = (unsigned char)B;\r
771 }\r
772 \r
773 /*void ColorAdd(unsigned long *Bg, unsigned long Amount)\r
774 {\r
775     asm("\r
776     movd %%eax, %%mm0\r
777     movd (%%esi), %%mm1\r
778     paddusb %%mm1, %%mm0\r
779     movd %%mm0, 0(%%esi)\r
780     "\r
781     :\r
782     : "a" (Amount), "S" (Bg)\r
783     );\r
784     asm("\r
785     addb %%al, 0(%%esi)\r
786     jnc ColorAddNoBlueOF\r
787     movb $0xFF, 0(%%esi)\r
788 ColorAddNoBlueOF:\r
789     addb %%ah, 1(%%esi)\r
790     jnc ColorAddNoGreenOF\r
791     movb $0xFF, 1(%%esi)\r
792 ColorAddNoGreenOF:\r
793     shrl $0x10, %%eax\r
794     addb %%al, 2(%%esi)\r
795     jnc ColorAddNoRedOF\r
796     movb $0xFF, 2(%%esi)\r
797 ColorAddNoRedOF:\r
798     "\r
799     :\r
800     : "a" (Amount), "S" (Bg)\r
801     );\r
802 }*/\r
803 \r
804 /*void ColorSub(unsigned long *Bg, unsigned long Amount)\r
805 {\r
806     asm("\r
807     subb %%al, 0(%%esi)\r
808     jnc ColorSubNoBlueOF\r
809     movb $0x00, 0(%%esi)\r
810 ColorSubNoBlueOF:\r
811     subb %%ah, 1(%%esi)\r
812     jnc ColorSubNoGreenOF\r
813     movb $0x00, 1(%%esi)\r
814 ColorSubNoGreenOF:\r
815     shrl $0x10, %%eax\r
816     subb %%al, 2(%%esi)\r
817     jnc ColorSubNoRedOF\r
818     movb $0x00, 2(%%esi)\r
819 ColorSubNoRedOF:\r
820     "\r
821     :\r
822     : "a" (Amount), "S" (Bg)\r
823     );\r
824 }*/\r
825 \r
826 void ColorAvr(unsigned long *Bg, unsigned long Amount)\r
827 {\r
828 /*\r
829     asm("\r
830     addb %%al, 0(%%esi)\r
831     .byte 0xD0\r
832     .byte 0x1E\r
833     addb %%ah, 1(%%esi)\r
834     .byte 0xD0\r
835     .byte 0x5E\r
836     .byte 1\r
837     shrl $0x10, %%eax\r
838     addb %%al, 2(%%esi)\r
839     .byte 0xD0\r
840     .byte 0x5E\r
841     .byte 2\r
842     "\r
843     :\r
844     : "a" (Amount), "S" (Bg)\r
845     );\r
846 */\r
847     ((Color *)(Bg))->R = (unsigned char)(((unsigned short)((Color *)(Bg))->R + (unsigned short)(*(Color *)(&Amount)).R) >> 1);\r
848     ((Color *)(Bg))->G = (unsigned char)(((unsigned short)((Color *)(Bg))->G + (unsigned short)(*(Color *)(&Amount)).G) >> 1);\r
849     ((Color *)(Bg))->B = (unsigned char)(((unsigned short)((Color *)(Bg))->B + (unsigned short)(*(Color *)(&Amount)).B) >> 1);\r
850 }\r
851 \r
852 void ColorSpc(unsigned long *Bg, unsigned long Amount)\r
853 {\r
854     Color *c1;\r
855     Color c2;\r
856     unsigned short R, G, B;\r
857 \r
858     c1 = (Color *)Bg;\r
859     c2 = *(Color *)&Amount;\r
860     R = ((3 * (unsigned short)c1->R) + (3 * (unsigned short)c2.R)) >> 2;\r
861     G = ((3 * (unsigned short)c1->G) + (3 * (unsigned short)c2.G)) >> 2;\r
862     B = ((3 * (unsigned short)c1->B) + (3 * (unsigned short)c2.B)) >> 2;\r
863     if(R > 255)\r
864         R = 255;\r
865     if(G > 255)\r
866         G = 255;\r
867     if(B > 255)\r
868         B = 255;\r
869     c1->R = (unsigned char)R;\r
870     c1->G = (unsigned char)G;\r
871     c1->B = (unsigned char)B;\r
872 }\r
873 \r
874 void ColorFul(unsigned long *Bg, unsigned long Amount)\r
875 {\r
876     Color *c1, c2;\r
877 \r
878     *(unsigned long *)&c2 = Amount;\r
879     c1 = (Color *)Bg;\r
880     if(c2.R > c1->R)\r
881         c1->R = c2.R;\r
882     if(c2.G > c1->G)\r
883         c1->G = c2.G;\r
884     if(c2.B > c1->B)\r
885         c1->B = c2.B;\r
886 }\r
887 \r
888 void DBCopyMapBufferClip(signed short x, signed short y, unsigned char *Buffer, unsigned char *BgBuffer, unsigned short w, unsigned short h)\r
889 {\r
890     unsigned char *WorkOffset;\r
891     unsigned long OffsetAdd1, OffsetAdd2;\r
892     signed short cx, cy, sx, sy, cw, ch;\r
893     unsigned long data;\r
894 \r
895     if((x > clip_x2) || ((x + w) < clip_x1) || (y > clip_y2) || ((y + h) < clip_y1))\r
896         return;\r
897     sx = (x < clip_x1)?(clip_x1 - x):0;\r
898     sy = (y < clip_y1)?(clip_y1 - y):0;\r
899     cw = (x + (signed short)w - 1 > clip_x2)?(clip_x2 - x + 1):(signed short)w;\r
900     ch = (y + (signed short)h - 1 > clip_y2)?(clip_y2 - y + 1):(signed short)h;\r
901     Buffer += (sx + (sy * w)) << 2;\r
902     BgBuffer += sx + (sy * w);\r
903     OffsetAdd1 = (sx + w - cw) << 2;\r
904     OffsetAdd2 = 1280 - ((cw - sx) << 2);\r
905     WorkOffset = DblBuffer + ((signed long)(y + sy) << 10) + ((signed long)(y + sy) << 8) + ((signed long)(x + sx) << 2);\r
906     for(cy = 0; cy < ch - sy; cy++)\r
907     {\r
908         for(cx = 0; cx < cw - sx; cx++)\r
909         {\r
910             data = *(unsigned long *)Buffer;\r
911             if(data != 0)\r
912             {\r
913                 if(((*BgBuffer) & 0x70) == 0x20)\r
914                     ColorAdd((unsigned long *)WorkOffset, data);\r
915                 else\r
916                     *(unsigned long *)WorkOffset = data;\r
917             }\r
918             Buffer += 4;\r
919             BgBuffer++;\r
920             WorkOffset += 4;\r
921         }\r
922         Buffer += OffsetAdd1;\r
923         BgBuffer += OffsetAdd1 >> 2;\r
924         WorkOffset += OffsetAdd2;\r
925     }\r
926 }\r
927 \r
928 void DBCopyBufferTrans(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc, unsigned char Method)\r
929 {\r
930     unsigned char *WorkOffset;\r
931     unsigned long OffsetAdd;\r
932     unsigned short cx, cy;\r
933     unsigned long data;\r
934 \r
935     WorkOffset = DblBuffer + ((signed long)y << 10) + ((signed long)y << 8) + ((signed long)x << 2);\r
936     OffsetAdd = 1280 - (w << 2);\r
937     for(cy = 0; cy < h; cy++)\r
938     {\r
939         for(cx = 0; cx < w; cx++)\r
940         {\r
941             data = *(unsigned long *)Buffer;\r
942             if(data != bgc)\r
943                 TransOps[Method]((unsigned long *)WorkOffset, data);\r
944             Buffer += 4;\r
945             WorkOffset += 4;\r
946         }\r
947         WorkOffset += OffsetAdd;\r
948     }\r
949 }\r
950 \r
951 void DBCopyBufferClipTrans(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned short bgc, unsigned char Method)\r
952 {\r
953     unsigned char *WorkOffset;\r
954     unsigned long OffsetAdd1, OffsetAdd2;\r
955     signed short cx, cy, sx, sy, cw, ch;\r
956     unsigned long data;\r
957 \r
958     if((x > clip_x2) || ((x + w) < clip_x1) || (y > clip_y2) || ((y + h) < clip_y1))\r
959         return;\r
960     if((x >= clip_x1) && ((x + w) <= clip_x2) && (y >= clip_y1) && ((y + h) <= clip_y2))\r
961     {\r
962         DBCopyBufferTrans(x, y, Buffer, w, h, bgc, Method);\r
963         return;\r
964     }\r
965     sx = (x < clip_x1)?(clip_x1 - x):0;\r
966     sy = (y < clip_y1)?(clip_y1 - y):0;\r
967     cw = (x + (signed short)w - 1 > clip_x2)?(clip_x2 - x + 1):(signed short)w;\r
968     ch = (y + (signed short)h - 1 > clip_y2)?(clip_y2 - y + 1):(signed short)h;\r
969     Buffer += (sx + (sy * w)) << 2;\r
970     OffsetAdd1 = (sx + w - cw) << 2;\r
971     OffsetAdd2 = 1280 - ((cw - sx) << 2);\r
972     WorkOffset = DblBuffer + ((signed long)(y + sy) << 10) + ((signed long)(y + sy) << 8) + ((signed long)(x + sx) << 2);\r
973     for(cy = 0; cy < ch - sy; cy++)\r
974     {\r
975         for(cx = 0; cx < cw - sx; cx++)\r
976         {\r
977             data = *(unsigned long *)Buffer;\r
978             if(data != bgc)\r
979                 TransOps[Method]((unsigned long *)WorkOffset, data);\r
980             Buffer += 4;\r
981             WorkOffset += 4;\r
982         }\r
983         Buffer += OffsetAdd1;\r
984         WorkOffset += OffsetAdd2;\r
985     }\r
986 }\r
987 \r
988 void DBSpriteLineTrans(signed short x1, signed short y1, signed short x2, signed short y2, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned char Method)\r
989 {\r
990     signed short dx, dy, x, y;\r
991     signed short xi, yi, d;\r
992     unsigned short i;\r
993     unsigned char c;\r
994 \r
995     dx = x2 - x1;\r
996     dy = y2 - y1;\r
997     if(dx >= 0)\r
998     {\r
999         xi = 1;\r
1000     } else {\r
1001         xi = -1;\r
1002         dx = -dx;\r
1003     }\r
1004     if(dy >= 0)\r
1005     {\r
1006         yi = 1;\r
1007     } else {\r
1008         yi = -1;\r
1009         dy = -dy;\r
1010     }\r
1011     d = 0;\r
1012     x = x1;\r
1013     y = y1;\r
1014     c = 0;\r
1015     if(dx > dy)\r
1016     {\r
1017         for(i = 0; i <= dx; i++)\r
1018         {\r
1019             DBCopyBufferClipTrans((unsigned short)x, (unsigned short)y, Buffer, w, h, 0, Method);\r
1020             d += dy;\r
1021             if(d > dx)\r
1022             {\r
1023                 d -= dx;\r
1024                 y += yi;\r
1025             }\r
1026             x += xi;\r
1027         }\r
1028     } else {\r
1029         for(i = 0; i <= dy; i++)\r
1030         {\r
1031             DBCopyBufferClipTrans((unsigned short)x, (unsigned short)y, Buffer, w, h, 0, Method);\r
1032             d += dx;\r
1033             if(d > 0)\r
1034             {\r
1035                 d -= dy;\r
1036                 x += xi;\r
1037             }\r
1038             y += yi;\r
1039         }\r
1040     }\r
1041 }\r
1042 \r
1043 void DBCopyBufferTransRotated(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc, unsigned char Method, signed short rx, signed short ry, unsigned short a)\r
1044 {\r
1045     unsigned short cx, cy, sx, sy;\r
1046     unsigned long Data, OffsetMax;\r
1047     signed long w1, h1;\r
1048     signed long x0, y0, xn, yn;\r
1049     signed long c, s;\r
1050 \r
1051     c = (signed long)(Cosine[a] * 0x10000);\r
1052     s = (signed long)(Sine[a] * 0x10000);\r
1053     w1 = (s * h) + (c * w);\r
1054     h1 = (c * h) + (s * w);\r
1055     x0 = (signed long)((Sine[a] * Sine[a] * (float)w) * 0x10000);\r
1056     y0 = (signed long)(-(Sine[a] * Cosine[a] * (float)w) * 0x10000);\r
1057     if((w1 & 0xFFFF) != 0)\r
1058         w1 = (w1 & 0xFFFF0000) + 0x10000;\r
1059     if((h1 & 0xFFFF) != 0)\r
1060         h1 = (h1 & 0xFFFF0000) + 0x10000;\r
1061     w1 >>= 16;\r
1062     h1 >>= 16;\r
1063     sx = x;\r
1064     sy = y;\r
1065     for(cy = 0; cy < h1; cy++)\r
1066     {\r
1067         xn = x0;\r
1068         yn = y0;\r
1069         for(cx = 0; cx < w1; cx++)\r
1070         {\r
1071             if((xn >= 0) && (yn >= 0) && (xn < (w << 16)) && (yn < (h << 16)))\r
1072             {\r
1073                 Data = ((unsigned long *)Buffer)[((xn & 0xFFFF0000) + ((yn & 0xFFFF0000) * w)) >> 16];\r
1074                 if(Data != bgc)\r
1075                     DBPSetCTrans(sx, sy, Data, Method);\r
1076             }\r
1077             sx++;\r
1078             xn += c;\r
1079             yn += s;\r
1080         }\r
1081         x0 -= s;\r
1082         y0 += c;\r
1083         sy++;\r
1084         sx = x;\r
1085     }\r
1086 }\r
1087 \r
1088 #undef MOTION_BLUR\r
1089 \r
1090 void DisplayDB(void)\r
1091 {\r
1092     SDL_Flip(VBuffer);\r
1093 }\r
1094 \r
1095 #if 0\r
1096 void DisplayDB(void)\r
1097 {\r
1098     unsigned long i;\r
1099 \r
1100 #ifdef DEBUG\r
1101     return;\r
1102 #endif\r
1103 #ifndef MOTION_BLUR\r
1104     if(BPP == 0x20)\r
1105     {\r
1106         /*for(i = 0; i < 256000; i += 4)\r
1107         {\r
1108             *(unsigned long *)&VBuffer[i] = SmoothColor(*(unsigned long *)&DblBuffer[i], *(unsigned long *)&DblBuffer[i - 1280], *(unsigned long *)&DblBuffer[i + 1280], *(unsigned long *)&DblBuffer[i - 4], *(unsigned long *)&DblBuffer[i + 4]);\r
1109         }*/\r
1110         /*for(i = 0; i < 64000; i++)\r
1111             ((unsigned long *)VBuffer)[i] = ((unsigned long *)DblBuffer)[i];*/\r
1112         DisplayDBAsm();\r
1113         /*for(i = 0; i < 256000; i++)\r
1114             _farpokeb(VideoLDT, i, DblBuffer[i]);*/\r
1115     } else {\r
1116         for(i = 0; i < 64000; i++)\r
1117         {\r
1118             VBuffer[i * 3] = (DblBuffer)[i * 4];\r
1119             VBuffer[(i * 3) + 1] = (DblBuffer)[(i * 4) + 1];\r
1120             VBuffer[(i * 3) + 2] = (DblBuffer)[(i * 4) + 2];\r
1121         }\r
1122     }\r
1123 #else\r
1124     asm("\r
1125     mov $0, %%eax\r
1126     movd %%eax, %%mm2\r
1127     "\r
1128     :\r
1129     :\r
1130     : "%eax"\r
1131     );\r
1132     for(i = 0; i < 256000; i += 4)\r
1133     {\r
1134         asm("\r
1135         movd (%%eax), %%mm0\r
1136         movd (%%esi), %%mm1\r
1137         punpcklbw %%mm2, %%mm0\r
1138         punpcklbw %%mm2, %%mm1\r
1139         paddw %%mm1, %%mm0\r
1140         psrlw $1, %%mm0\r
1141         packuswb %%mm0, %%mm0\r
1142         movd %%mm0, (%%esi)\r
1143         "\r
1144         :\r
1145         : "a" (DblBuffer + i), "S" (VBuffer + i)\r
1146         );\r
1147     }\r
1148     asm("emms");\r
1149 #endif\r
1150 }\r
1151 #endif\r