]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/scaler.cpp
Initial revision
[taylor/freespace2.git] / src / graphics / scaler.cpp
1 /*
2  * $Logfile: /Freespace2/code/Graphics/Scaler.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Routines to scale a bitmap.
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:09  root
11  * Initial revision
12  *
13  * 
14  * 9     7/20/99 1:49p Dave
15  * Peter Drake build. Fixed some release build warnings.
16  * 
17  * 8     6/22/99 7:03p Dave
18  * New detail options screen.
19  * 
20  * 7     5/12/99 5:33p Johne
21  * Don't use gr8_scaler() in pofview.
22  * 
23  * 6     5/09/99 6:00p Dave
24  * Lots of cool new effects. E3 build tweaks.
25  * 
26  * 5     1/14/99 6:06p Dave
27  * 100% full squad logo support for single player and multiplayer.
28  * 
29  * 4     1/14/99 12:48a Dave
30  * Todo list bug fixes. Made a pass at putting briefing icons back into
31  * FRED. Sort of works :(
32  * 
33  * 3     11/30/98 1:07p Dave
34  * 16 bit conversion, first run.
35  * 
36  * 2     10/07/98 10:53a Dave
37  * Initial checkin.
38  * 
39  * 1     10/07/98 10:49a Dave
40  * 
41  * 40    4/02/98 2:01p Dave
42  * JAS: Increased constant for source of compiled code
43  * 
44  * 39    4/01/98 9:21p John
45  * Made NDEBUG, optimized build with no warnings or errors.
46  * 
47  * 38    4/01/98 7:15p John
48  * fixed bug with previous
49  * 
50  * 37    4/01/98 6:45p John
51  * Reduced memory by combining compled_code ptrs.
52  * 
53  * 36    3/22/98 3:28p John
54  * Added in stippled alpha for lower details.  Made medium detail use
55  * engine glow.
56  * 
57  * 35    3/10/98 4:18p John
58  * Cleaned up graphics lib.  Took out most unused gr functions.   Made D3D
59  * & Glide have popups and print screen.  Took out all >8bpp software
60  * support.  Made Fred zbuffer.  Made zbuffer allocate dynamically to
61  * support Fred.  Made zbuffering key off of functions rather than one
62  * global variable.
63  * 
64  * 34    2/05/98 9:21p John
65  * Some new Direct3D code.   Added code to monitor a ton of stuff in the
66  * game.
67  * 
68  * 33    1/27/98 10:18a John
69  * fixed warning for optimized build
70  * 
71  * 32    1/26/98 5:12p John
72  * Added in code for Pentium Pro specific optimizations. Speed up
73  * zbuffered correct tmapper about 35%.   Speed up non-zbuffered scalers
74  * by about 25%.
75  * 
76  * 31    1/19/98 6:15p John
77  * Fixed all my Optimized Build compiler warnings
78  * 
79  * 30    12/04/97 12:09p John
80  * Made glows use scaler instead of tmapper so they don't rotate.  Had to
81  * add a zbuffered scaler.
82  * 
83  * 29    12/02/97 4:00p John
84  * Added first rev of thruster glow, along with variable levels of
85  * translucency, which retquired some restructing of palman.
86  * 
87  * 28    11/30/97 4:33p John
88  * added 32-bpp aascaler
89  * 
90  * 27    11/30/97 3:57p John
91  * Made fixed 32-bpp translucency.  Made BmpMan always map translucent
92  * color into 255 even if you aren't supposed to remap and make it's
93  * palette black.
94  * 
95  * 26    11/30/97 12:18p John
96  * added more 24 & 32-bpp primitives
97  * 
98  * 25    11/29/97 2:06p John
99  * added mode 16-bpp support
100  * 
101  * 24    11/14/97 12:30p John
102  * Fixed some DirectX bugs.  Moved the 8-16 xlat tables into Graphics
103  * libs.  Made 16-bpp DirectX modes know what bitmap format they're in.
104  * 
105  * 23    10/19/97 12:55p John
106  * new code to lock / unlock surfaces for smooth directx integration.
107  * 
108  * 22    10/15/97 4:48p John
109  * added 16-bpp aascaler
110  * 
111  * 21    10/14/97 8:08a John
112  * added a bunch more 16 bit support
113  * 
114  * 20    10/09/97 5:23p John
115  * Added support for more 16-bpp functions
116  * 
117  * 19    8/04/97 4:47p John
118  * added gr_aascaler.
119  * 
120  * 18    7/28/97 11:31a John
121  * made compiled code save all registers that it changes.  When building
122  * optimized, my code was using EBX, and so was the compiler, so weird
123  * errors happened.  Pushing/popping ebx fixed this.
124  * 
125  * 17    7/16/97 5:29p John
126  * added palette table caching and made scaler and liner no light tmapper
127  * do alpha blending in 8 bpp mode.
128  * 
129  * 16    7/10/97 2:06p John
130  * added code to specify alphablending type for bitmaps.
131  * 
132  * 15    6/12/97 2:50a Lawrance
133  * bm_unlock() now passed bitmap number, not pointer
134  * 
135  * 14    5/29/97 3:10p John
136  * Took out debug menu.  
137  * Made software scaler draw larger bitmaps.
138  * Optimized Direct3D some.
139  * 
140  * 13    5/12/97 12:27p John
141  * Restructured Graphics Library to add support for multiple renderers.
142  * 
143  * 12    12/04/96 2:02p John
144  * Added fast compiled code to the scaler in 8,16,32 bpp modes.
145  * 
146  * 11    12/03/96 8:08p John
147  * Added compiled code to 8bpp scaler.  Made bitmaps that are trying to
148  * scale up too big to not draw.
149  * 
150  * 10    12/03/96 11:12a John
151  * added commented out "filtering" code to scaler.
152  * 
153  * 9     11/19/96 2:42p Allender
154  * fix up 32 bit scaler
155  * 
156  * 8     11/15/96 11:27a Allender
157  * 16bpp version of scaler
158  * 
159  * 7     11/07/96 6:19p John
160  * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
161  * mode.
162  * 
163  * 6     10/26/96 1:40p John
164  * Added some now primitives to the 2d library and
165  * cleaned up some old ones.
166  *
167  * $NoKeywords: $
168  */
169
170 #include <math.h>
171 #include <limits.h>
172 #include <stdio.h>
173 #ifndef PLAT_UNIX
174 #include <conio.h>
175 #endif
176 #include <stdlib.h>
177
178 #include "scaler.h"
179 #include "2d.h"
180 #include "grinternal.h"
181 #include "floating.h"
182 #include "bmpman.h"
183 #include "palman.h"
184 #include "tmapscanline.h"
185 #include "systemvars.h"
186 #include "key.h"
187 #include "colors.h"
188
189 #define MIN_SCALE_FACTOR 0.0001f
190
191 #define USE_COMPILED_CODE
192
193 #define TRANSPARENCY_COLOR_8            0xff
194 #define TRANSPARENCY_COLOR_16           0xffff
195 #define TRANSPARENCY_COLOR_32           0xffffffff
196
197 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
198
199 #define MAX_CODE_SIZE 32768             //65536 JAS: Determed to be 8208 on April1,98, 16K seems safe
200
201 ubyte compiled_code[MAX_CODE_SIZE];
202
203 static int Max_size = 0;
204
205 /*
206 void test_code()
207 {
208         _asm mov ax, [esi+0xabcdef12]
209         _asm cmp ax, 255
210         _asm je  0xabcdef12
211         _asm mov [edi+0xabcdef12], ax
212         _asm mov ax, [esi+0xabcdef12]
213 }
214 */
215
216
217
218 //----------------------------------------------------
219 // scaler_create_compiled_code8
220 //
221 // Creates code that looks like:
222 //
223 // @@: mov al, [esi+????]
224 //     cmp al, TRANSPARENCY_COLOR_8
225 //     je  @f   ; jump to next @@ label
226 //     mov [edi+???], al    ; If the source pixel is scaled up
227 //     mov [edi+???], al    ; there might be a lot of these lines
228 //     ...
229 // @@: mov al, [esi+????]
230 //
231
232 ubyte *scaler_create_compiled_code8( int w, fix u, fix du )
233 {
234         int last_u, x;
235         ubyte * cc;
236         uint * last_jmp_pos;
237
238         cc = compiled_code;
239
240         //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
241
242 //      *cc++ = 0xCC;   // Int3
243 //      *cc++ = 0xc3;   // RET
244
245         last_u = -1;
246
247         last_jmp_pos=NULL;
248
249         for (x=0; x<w; x++ )                    {
250                 if ( last_u != f2i(u) ) {
251                         if ( last_jmp_pos )     {
252                                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
253                         }
254                         *cc++ = 0x8a;   *cc++ = 0x86; // mov al, [esi+imm]
255                         *(uint *)cc = f2i(u); cc += 4;
256                         last_u = f2i(u);
257
258                         *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8;     // cmp al, 255
259                         *cc++ = 0x0f; *cc++ = 0x84;   // je rel32
260                         last_jmp_pos = (uint *)cc;
261                         cc += 4;                
262                 }
263                 
264         
265                 *cc++ = 0x88;   *cc++ = 0x87; // mov [edi+imm], al
266                 *(uint *)cc = x; cc += 4;
267
268                 u += du;
269         }
270         if ( last_jmp_pos )     {
271                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
272         }
273         *cc++ = 0xc3;   // RET
274
275         if ( cc >= &compiled_code[MAX_CODE_SIZE] )
276                 Int3();         // GET JOHN NOW!
277
278 #ifdef FIND_MAX_SIZE
279         int size = cc - compiled_code;
280         if ( size > Max_size )  {
281                 Max_size = size;
282                 mprintf(( "Max size = %d\n", size ));
283         }
284 #endif
285
286         return compiled_code;
287 }
288
289 ubyte *scaler_create_compiled_code8_stippled( int w, fix u, fix du )
290 {
291         int last_u, x;
292         ubyte * cc;
293         uint * last_jmp_pos;
294
295         cc = compiled_code;
296
297         //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
298
299 //      *cc++ = 0xCC;   // Int3
300 //      *cc++ = 0xc3;   // RET
301
302         last_u = -1;
303
304         last_jmp_pos=NULL;
305
306         for (x=0; x<w-1; x+=2 )                 {
307                 if ( last_u != f2i(u) ) {
308                         if ( last_jmp_pos )     {
309                                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
310                         }
311                         *cc++ = 0x8a;   *cc++ = 0x86; // mov al, [esi+imm]
312                         *(uint *)cc = f2i(u); cc += 4;
313                         last_u = f2i(u);
314
315                         *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8;     // cmp al, 255
316                         *cc++ = 0x0f; *cc++ = 0x84;   // je rel32
317                         last_jmp_pos = (uint *)cc;
318                         cc += 4;                
319                 }
320                 
321         
322                 *cc++ = 0x88;   *cc++ = 0x87; // mov [edi+imm], al
323                 *(uint *)cc = x; cc += 4;
324
325                 u += du*2;
326         }
327         if ( last_jmp_pos )     {
328                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
329         }
330         *cc++ = 0xc3;   // RET
331
332         if ( cc >= &compiled_code[MAX_CODE_SIZE] )
333                 Int3();         // GET JOHN NOW!
334
335 #ifdef FIND_MAX_SIZE
336         int size = cc - compiled_code;
337         if ( size > Max_size )  {
338                 Max_size = size;
339                 mprintf(( "Max size = %d\n", size ));
340         }
341 #endif
342
343         return compiled_code;
344 }
345
346 void test_code1()
347 {
348 #ifdef PLAT_UNIX
349         STUB_FUNCTION;
350 #else
351         _asm mov ebx, -1
352         _asm xor eax, eax
353         _asm xor ebx, ebx
354         _asm mov        bl, BYTE PTR [edi-1412567278]
355         _asm add ebx, eax
356         _asm mov ebx, [ecx+ebx] ; blend it
357         _asm cmp ebp, [edx]
358         _asm add edx, 4
359         _asm jl [0xABCDEF12]
360         
361 //     xor eax, eax                     ; avoid ppro partial register stall
362 //     mov ah, [esi+????]   ; get the foreground pixel
363 //     ; the following lines might be repeated
364 //     xor ebx, ebx                     ; avoid ppro partial register stall
365 //     mov bl, [edi+????]   ; get the background pixel
366 //     mov ebx, [ecx+ebx]       ; blend it
367 //     mov [edi+????], bl   ; write it
368 #endif
369 }
370
371 /*
372   00130 b8 00 00 00 00  mov     eax, 0
373   00135 8a a6 12 ef cd ab               mov     ah, BYTE PTR [esi-1412567278]
374   0013b 8a 87 12 ef cd ab               mov     al, BYTE PTR [edi-1412567278]
375   00141 8a 1c 01                    mov bl, BYTE PTR [ecx+eax]
376   00141 8b 1c 01                                        mov     ebx, DWORD PTR [ecx+eax]
377   00144 88 9f 12 ef cd ab               mov     BYTE PTR [edi-1412567278], bl
378
379
380   00130 33 c0           xor     eax, eax
381   00132 33 db           xor     ebx, ebx
382   00134 8a 9f 12 ef cd  ab              mov     bl, BYTE PTR [edi-1412567278]
383   0013a 03 d8           add     ebx, eax
384   0013c 8b 1c 19        mov     ebx, DWORD PTR [ecx+ebx]
385
386   0013f 3b 2a           cmp     ebp, DWORD PTR [edx]
387   00141 83 c2 04        add     edx, 4
388
389
390 */
391
392 //----------------------------------------------------
393 // scaler_create_compiled_code8_alpha
394 //
395 // Creates code that looks like:
396
397 //=============== Pentium ======================
398 // mov eax, 0
399 //     mov ah, [esi+????]   ; get the foreground pixel
400 //     ; the following lines might be repeated
401 //     mov al, [edi+????]   ; get the background pixel
402 //     mov bl, [ecx+eax]        ; blend it
403 //     mov [edi+????], bl   ; write it
404 //     ...
405
406 //============= Pentium Pro code =============
407 //     xor eax, eax                     ; avoid ppro partial register stall
408 //     mov ah, [esi+????]   ; get the foreground pixel
409 //     ; the following lines might be repeated
410 //     xor ebx, ebx                     ; avoid ppro partial register stall
411 //     mov bl, [edi+????]   ; get the background pixel
412 //     mov ebx, [ecx+ebx]       ; blend it
413 //     mov [edi+????], bl   ; write it
414
415
416 ubyte *scaler_create_compiled_code8_alpha( int w, fix u, fix du )
417 {
418         int last_u, x;
419         ubyte * cc;
420
421         cc = compiled_code;
422
423         //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
424
425         //*cc++ = 0xCC; // Int3
426         //*cc++ = 0xc3; // RET
427
428         last_u = -1;
429
430         if ( Gr_cpu     > 5 )   {
431                 // Pentium Pro optimized code.
432
433                 for (x=0; x<w; x++ )                    {
434                         if ( last_u != f2i(u) ) {
435                                 *cc++ = 0x33;   *cc++ = 0xc0; // xor eax, eax
436                                 *cc++ = 0x8a;   *cc++ = 0xa6; // mov ah, [esi+imm]
437                                 //*cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
438                                 *(uint *)cc = f2i(u); cc += 4;
439                                 last_u = f2i(u);
440                         }
441                         
442                         *cc++ = 0x33;   *cc++ = 0xdb;           // xor ebx, ebx
443                         
444                         *cc++ = 0x8a;   *cc++ = 0x9f; 
445                         *(uint *)cc = x; cc += 4;               // mov bl, [edi+imm]
446
447                         *cc++ = 0x03;   *cc++ = 0xd8;           // add ebx, eax
448
449                         *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19;       // mov  ebx, BYTE PTR [ecx+ebx]
450
451                         *cc++ = 0x88;   *cc++ = 0x9f; 
452                         *(uint *)cc = x; cc += 4;               // mov [edi+imm], bl
453
454                         u += du;
455                 }
456         } else {
457                 // Pentium optimized code.
458
459                 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4;         // mov eax, 0
460
461                 for (x=0; x<w; x++ )                    {
462                         if ( last_u != f2i(u) ) {
463                                 *cc++ = 0x8a;   *cc++ = 0xa6; // mov ah, [esi+imm]
464                                 *(uint *)cc = f2i(u); cc += 4;
465                                 last_u = f2i(u);
466                         }
467                         
468                         *cc++ = 0x8a;   *cc++ = 0x87; 
469                         *(uint *)cc = x; cc += 4;               // mov al, [edi+imm]
470
471                         *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01;       // mov  bl, BYTE PTR [ecx+eax]
472
473                         *cc++ = 0x88;   *cc++ = 0x9f; 
474                         *(uint *)cc = x; cc += 4;               // mov [edi+imm], bl
475
476                         u += du;
477                 }
478         }
479
480         *cc++ = 0xc3;   // RET
481
482         if ( cc >= &compiled_code[MAX_CODE_SIZE] )
483                 Int3();         // GET JOHN NOW!
484
485 #ifdef FIND_MAX_SIZE
486         int size = cc - compiled_code;
487         if ( size > Max_size )  {
488                 Max_size = size;
489                 mprintf(( "Max size = %d\n", size ));
490         }
491 #endif
492
493         return compiled_code;
494 }
495
496 /*
497                                 for (x=0; x<w; x++ )                    {
498                                         if ( fx_w > *zbuf )     {
499                                                 uint c = sbits[ tmp_u >> 16 ]<<8;
500                                                 *dbits = *((ubyte *)(lookup + (*dbits | c)));
501                                         }
502                                         dbits++;
503                                         zbuf++;
504                                         tmp_u += du;
505                                 }
506 */
507
508 //----------------------------------------------------
509 // scaler_create_compiled_code8_alpha_zbuffered
510 //
511 // Creates code that looks like:
512 // mov eax, 0
513 //     mov ah, [esi+????]   ; get the foreground pixel
514 //     ; the following lines might be repeated
515 //     cmp      fx_w, [edx+?????]
516 //     jle  @f
517 //     mov al, [edi+????]   ; get the background pixel
518 //     mov bl, [ecx+eax]        ; blend it
519 //     mov [edi+????], bl   ; write it
520 //  @@:
521 //     ...
522
523
524
525
526 //void test_code1()
527 //{
528 //      _asm cmp 0xFFFFFFFF, [edx+0xabcdef12]
529 //      _asm cmp ebp, [edx+0xabcdef12]
530 //      _asm jle        0xabcdef12
531 //}
532 //; 302  :      _asm cmp ebp, [edx+0xabcdef12]
533 //  00244       3b aa 12 ef cd ab               cmp     ebp, DWORD PTR [edx-1412567278]
534 //; 303  :      _asm jle        0xabcdef12
535 //  0024a       0f 8e 12 ef cd ab               jle     -1412567278             ; abcdef12H
536
537 ubyte *scaler_create_compiled_code8_alpha_zbuffered( int w, fix u, fix du )
538 {
539         int last_u, x;
540         ubyte * cc;
541         uint *last_jmp_pos=NULL;
542
543         cc = compiled_code;
544
545         //     xor eax, eax                     ; avoid ppro partial register stall
546 //     mov ah, [esi+????]   ; get the foreground pixel
547 //     ; the following lines might be repeated
548 //     xor ebx, ebx                     ; avoid ppro partial register stall
549 //     mov bl, [edi+????]   ; get the background pixel
550 //     mov ebx, [ecx+ebx]       ; blend it
551 //     mov [edi+????], bl   ; write it
552
553         //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
554
555         //*cc++ = 0xCC; // Int3
556         //*cc++ = 0xc3; // RET
557         last_u = -1;
558
559         if ( Gr_cpu     > 5 )   {
560                 // Pentium Pro optimized code.
561
562                 for (x=0; x<w; x++ )                    {
563                         if ( last_u != f2i(u) ) {
564                                 *cc++ = 0x33;   *cc++ = 0xc0; // xor eax, eax
565                                 *cc++ = 0x8a;   *cc++ = 0xa6; // mov ah, [esi+imm]
566                                 *(uint *)cc = f2i(u); cc += 4;
567                                 last_u = f2i(u);
568                         }
569
570                         *cc++ = 0x3b;  *cc++ = 0xaa;    
571                         *(uint *)cc = x*4; cc += 4;             // cmp ebp, [edx+imm]
572
573 //                      *cc++ = 0x3b;  *cc++ = 0x2a;                                            // cmp ebp, [edx]
574 //                      *cc++ = 0x83;  *cc++ = 0xc2;  *cc++ = 0x4;      // add edx, 4
575
576                         *cc++ = 0x0f;  *cc++ = 0x8e;            // jle (8e) imm
577                         last_jmp_pos = (uint *)cc;
578                         *(uint *)cc = 0; cc += 4;
579                 
580                         *cc++ = 0x33;   *cc++ = 0xdb;           // xor ebx, ebx
581                         
582                         *cc++ = 0x8a;   *cc++ = 0x9f; 
583                         *(uint *)cc = x; cc += 4;               // mov bl, [edi+imm]
584
585                         *cc++ = 0x03;   *cc++ = 0xd8;           // add ebx, eax
586
587                         *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19;       // mov  ebx, BYTE PTR [ecx+ebx]
588
589                         *cc++ = 0x88;   *cc++ = 0x9f; 
590                         *(uint *)cc = x; cc += 4;               // mov [edi+imm], bl
591
592                         if ( last_jmp_pos )     {
593                                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
594                                 last_jmp_pos  = NULL;
595                         }
596
597                         u += du;
598                 }
599
600
601         } else {
602                 // Pentium optimized code.
603
604                 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4;         // mov eax, 0
605
606                 for (x=0; x<w; x++ )                    {
607                         if ( last_u != f2i(u) ) {
608                                 *cc++ = 0x8a;   *cc++ = 0xa6; // mov ah, [esi+imm]
609                                 *(uint *)cc = f2i(u); cc += 4;
610                                 last_u = f2i(u);
611                         }
612
613                         *cc++ = 0x3b;  *cc++ = 0xaa;    
614                         *(uint *)cc = x*4; cc += 4;             // cmp ebp, [edx+imm]
615
616                         *cc++ = 0x0f;  *cc++ = 0x8e;            // jle imm
617                         last_jmp_pos = (uint *)cc;
618                         *(uint *)cc = 0; cc += 4;               
619                         
620                         *cc++ = 0x8a;   *cc++ = 0x87; 
621                         *(uint *)cc = x; cc += 4;               // mov al, [edi+imm]
622
623                         *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01;       // mov  bl, BYTE PTR [ecx+eax]
624
625                         *cc++ = 0x88;   *cc++ = 0x9f; 
626                         *(uint *)cc = x; cc += 4;               // mov [edi+imm], bl
627
628                         if ( last_jmp_pos )     {
629                                 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
630                                 last_jmp_pos = NULL;
631                         }
632
633                         u += du;
634                 }
635         }
636         *cc++ = 0xc3;   // RET
637
638         if ( cc >= &compiled_code[MAX_CODE_SIZE] )
639                 Int3();         // GET JOHN NOW!
640
641 #ifdef FIND_MAX_SIZE
642         int size = cc - compiled_code;
643         if ( size > Max_size )  {
644                 Max_size = size;
645                 mprintf(( "Max sizeZ = %d\n", size ));
646         }
647 #endif
648
649         return compiled_code;
650 }
651
652
653
654 int Gr_scaler_zbuffering = 0;
655 uint Gr_global_z;
656
657 MONITOR( ScalerNumCalls );      
658
659
660 //----------------------------------------------------
661 // Scales current bitmap, between va and vb
662 void gr8_scaler(vertex *va, vertex *vb )
663 {
664 #if 1
665         if(Pofview_running){
666                 return;
667         }
668
669         float x0, y0, x1, y1;
670         float u0, v0, u1, v1;
671         float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
672         float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
673         float xmin, xmax, ymin, ymax;
674         int dx0, dy0, dx1, dy1;
675
676         MONITOR_INC( ScalerNumCalls, 1 );       
677
678         //============= CLIP IT =====================
679
680         x0 = va->sx; y0 = va->sy;
681         x1 = vb->sx; y1 = vb->sy;
682
683         xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
684         xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
685
686         u0 = va->u; v0 = va->v;
687         u1 = vb->u; v1 = vb->v;
688
689         // Check for obviously offscreen bitmaps...
690         if ( (y1<=y0) || (x1<=x0) ) return;
691         if ( (x1<xmin ) || (x0>xmax) ) return;
692         if ( (y1<ymin ) || (y0>ymax) ) return;
693
694         clipped_u0 = u0; clipped_v0 = v0;
695         clipped_u1 = u1; clipped_v1 = v1;
696
697         clipped_x0 = x0; clipped_y0 = y0;
698         clipped_x1 = x1; clipped_y1 = y1;
699
700         // Clip the left, moving u0 right as necessary
701         if ( x0 < xmin )        {
702                 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
703                 clipped_x0 = xmin;
704         }
705
706         // Clip the right, moving u1 left as necessary
707         if ( x1 > xmax )        {
708                 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
709                 clipped_x1 = xmax;
710         }
711
712         // Clip the top, moving v0 down as necessary
713         if ( y0 < ymin )        {
714                 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
715                 clipped_y0 = ymin;
716         }
717
718         // Clip the bottom, moving v1 up as necessary
719         if ( y1 > ymax )        {
720                 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
721                 clipped_y1 = ymax;
722         }
723         
724         dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
725         dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
726
727         if (dx1<=dx0) return;
728         if (dy1<=dy0) return;
729
730         //============= DRAW IT =====================
731         int u, v, du, dv;
732         int y, w;
733         ubyte * sbits, * dbits;
734         bitmap * bp;
735         ubyte * spixels;
736         float tmpu, tmpv;
737
738         tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
739         if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
740                 return;         // scaled up way too far!
741         }
742         tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
743         if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
744                 return;         // scaled up way too far!
745         }
746
747         int is_stippled = 0;
748
749         /*
750         if ( !Detail.alpha_effects )    {
751                 is_stippled = 1;
752                 Gr_scaler_zbuffering = 0;
753         }
754         */
755         
756         if ( is_stippled )      {
757                 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
758         } else {
759                 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
760         }
761
762
763         du = fl2f(tmpu*(bp->w-1));
764         dv = fl2f(tmpv*(bp->h-1));
765
766         v = fl2f(clipped_v0*(bp->h-1));
767         u = fl2f(clipped_u0*(bp->w-1)); 
768         w = dx1 - dx0 + 1;
769         if ( w < 2 ) {
770                 bm_unlock(gr_screen.current_bitmap);
771                 return;
772         }
773
774         uint fx_w = 0;
775         if ( Gr_scaler_zbuffering && gr_zbuffering )    {
776                 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
777                 Gr_global_z = fx_w;
778         }
779
780 #ifdef USE_COMPILED_CODE
781         ubyte *cc=NULL;
782
783         if ( Gr_scaler_zbuffering && gr_zbuffering )    {
784                 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER )        {
785                         cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );  
786                 }
787         } else {
788                 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER )        {
789                         if ( is_stippled )      {
790                                 cc = scaler_create_compiled_code8_stippled( w, u, du );
791                         } else {
792                                 cc = scaler_create_compiled_code8_alpha( w, u, du );    
793                         }
794                 } else  {
795                         cc = scaler_create_compiled_code8( w, u, du );
796                 }
797         }
798         
799 #endif
800
801         spixels = (ubyte *)bp->data;
802
803         gr_lock();
804         Tmap.pScreenBits = (uint)gr_screen.offscreen_buffer_base;
805
806         uint *zbuf;
807
808         for (y=dy0; y<=dy1; v += dv, y++ )                      {
809                 if ( is_stippled && (y&1) )     {
810                         sbits = &spixels[bp->rowsize*(v>>16)+f2i(du)];
811                         dbits = GR_SCREEN_PTR(ubyte,dx0+1,y);
812                 } else {
813                         sbits = &spixels[bp->rowsize*(v>>16)];
814                         dbits = GR_SCREEN_PTR(ubyte,dx0,y);
815                 }
816                 uint lookup = 0;
817
818                 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER )        {
819                         lookup = (uint)palette_get_blend_table(gr_screen.current_alpha);
820                 }
821
822                 if ( Gr_scaler_zbuffering && gr_zbuffering )    {
823                         zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
824                 }
825         
826 #ifdef USE_COMPILED_CODE
827                 // Call the compiled code to draw one scanline
828                 if ( Gr_scaler_zbuffering &&  gr_zbuffering && (gr_screen.current_alphablend_mode != GR_ALPHABLEND_FILTER))     {                       
829                         Int3();
830
831                         /*
832                         int x, tmp_u;
833                         tmp_u = u;
834
835                         for (x=0; x<w; x++ )                    {
836                                 if ( fx_w > *zbuf )     {
837                                         ubyte c = sbits[ tmp_u >> 16 ];
838                                         if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
839                                 }
840                                 zbuf++;
841                                 dbits++;
842                                 tmp_u += du;
843                         }
844                         */
845                 } else {
846 /*                      {
847                                 int x, tmp_u;
848                                 tmp_u = u;
849
850         
851                                 for (x=0; x<w; x++ )                    {
852                                         if ( fx_w > *zbuf )     {
853                                                 uint c = sbits[ tmp_u >> 16 ]<<8;
854                                                 *dbits = *((ubyte *)(lookup + (*dbits | c)));
855                                         }
856                                         dbits++;
857                                         zbuf++;
858                                         tmp_u += du;
859                                 }
860                         } 
861 */
862 #ifdef PLAT_UNIX
863                         STUB_FUNCTION;
864 #else
865                         _asm push esi
866                         _asm push edi
867                         _asm push edx
868                         _asm push ecx
869                         _asm push ebx
870                         _asm push eax
871                         _asm mov ecx, lookup
872                         _asm mov esi, sbits
873                         _asm mov edi, dbits
874                         _asm mov eax, cc
875                         _asm mov edx, zbuf
876                         _asm push ebp
877                         _asm mov ebp, Gr_global_z
878                         _asm call eax
879                         _asm pop ebp
880                         _asm pop eax
881                         _asm pop ebx
882                         _asm pop ecx
883                         _asm pop edx
884                         _asm pop edi
885                         _asm pop esi
886 #endif
887                 }
888 #else   
889                 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER )        {
890                         if ( Gr_scaler_zbuffering && gr_zbuffering )    {
891                                 int x, tmp_u;
892                                 tmp_u = u;
893
894                                 for (x=0; x<w; x++ )                    {
895                                         if ( fx_w > *zbuf )     {
896                                                 uint c = sbits[ tmp_u >> 16 ]<<8;
897                                                 *dbits = *((ubyte *)(lookup + (*dbits | c)));
898                                         }
899                                         dbits++;
900                                         zbuf++;
901                                         tmp_u += du;
902                                 }
903                         } else {
904                                 int x, tmp_u;
905                                 tmp_u = u;
906                                 for (x=0; x<w; x++ )                    {
907                                         uint c = sbits[ tmp_u >> 16 ]<<8;
908                                         *dbits++ = palette_blend[*dbits|c];
909                                         tmp_u += du;
910                                 }
911                         }
912                 } else {
913                         if ( Gr_scaler_zbuffering && gr_zbuffering )    {
914                                 int x, tmp_u;
915                                 tmp_u = u;
916                         
917                                 for (x=0; x<w; x++ )                    {
918                                         if ( fx_w > *zbuf )     {
919                                                 ubyte c = sbits[ tmp_u >> 16 ];
920                                                 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
921                                         }
922                                         zbuf++;
923                                         dbits++;
924                                         tmp_u += du;
925                                 }
926                         } else {
927                                 int x, tmp_u;
928                                 tmp_u = u;
929                                 for (x=0; x<w; x++ )                    {
930                                         ubyte c = sbits[ tmp_u >> 16 ];
931                                         if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
932                                         dbits++;
933                                         tmp_u += du;
934                                 }
935                         }
936                 }
937 #endif
938         }
939
940         gr_unlock();
941         bm_unlock(gr_screen.current_bitmap);
942 #endif
943 }
944
945 int aiee = 0;
946 alphacolor_old old_alphac;
947 //----------------------------------------------------
948 // Scales current bitmap, between va and vb
949 void gr8_aascaler(vertex *va, vertex *vb )
950 {
951         float x0, y0, x1, y1;
952         float u0, v0, u1, v1;
953         float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
954         float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
955         float xmin, xmax, ymin, ymax;
956         int dx0, dy0, dx1, dy1;
957
958         //if ( !Current_alphacolor )    return;
959
960         MONITOR_INC( ScalerNumCalls, 1 );       
961
962         Assert(Fred_running);
963         if(!aiee){
964                 old_alphac.used = 1;
965                 old_alphac.r = 93;
966                 old_alphac.g = 93;
967                 old_alphac.b = 128;
968                 old_alphac.alpha = 255;
969                 //ac->type = type;
970                 //ac->clr=clr;
971                 //93, 93, 128, 255
972                 calc_alphacolor_old(&old_alphac);
973                 aiee = 1;
974         }
975
976         //============= CLIP IT =====================
977
978         x0 = va->sx; y0 = va->sy;
979         x1 = vb->sx; y1 = vb->sy;
980
981         xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
982         xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
983
984         u0 = va->u; v0 = va->v;
985         u1 = vb->u; v1 = vb->v;
986
987         // Check for obviously offscreen bitmaps...
988         if ( (y1<=y0) || (x1<=x0) ) return;
989         if ( (x1<xmin ) || (x0>xmax) ) return;
990         if ( (y1<ymin ) || (y0>ymax) ) return;
991
992         clipped_u0 = u0; clipped_v0 = v0;
993         clipped_u1 = u1; clipped_v1 = v1;
994
995         clipped_x0 = x0; clipped_y0 = y0;
996         clipped_x1 = x1; clipped_y1 = y1;
997
998         // Clip the left, moving u0 right as necessary
999         if ( x0 < xmin )        {
1000                 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1001                 clipped_x0 = xmin;
1002         }
1003
1004         // Clip the right, moving u1 left as necessary
1005         if ( x1 > xmax )        {
1006                 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1007                 clipped_x1 = xmax;
1008         }
1009
1010         // Clip the top, moving v0 down as necessary
1011         if ( y0 < ymin )        {
1012                 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1013                 clipped_y0 = ymin;
1014         }
1015
1016         // Clip the bottom, moving v1 up as necessary
1017         if ( y1 > ymax )        {
1018                 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1019                 clipped_y1 = ymax;
1020         }
1021         
1022         dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1023         dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1024
1025         if (dx1<=dx0) return;
1026         if (dy1<=dy0) return;
1027
1028         //============= DRAW IT =====================
1029         int u, v, du, dv;
1030         int y, w;
1031         ubyte * sbits, * dbits;
1032         bitmap * bp;
1033         ubyte * spixels;
1034         float tmpu, tmpv;
1035
1036         tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
1037         if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
1038                 return;         // scaled up way too far!
1039         }
1040         tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
1041         if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
1042                 return;         // scaled up way too far!
1043         }
1044
1045         bp = bm_lock( gr_screen.current_bitmap, 8, BMP_AABITMAP );
1046
1047         du = fl2f(tmpu*(bp->w-1));
1048         dv = fl2f(tmpv*(bp->h-1));
1049
1050         v = fl2f(clipped_v0*(bp->h-1));
1051         u = fl2f(clipped_u0*(bp->w-1)); 
1052         w = dx1 - dx0 + 1;
1053
1054 #ifdef USE_COMPILED_CODE
1055         ubyte *cc;
1056
1057         if ( Gr_scaler_zbuffering && gr_zbuffering )    {
1058                 //cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
1059         } else {
1060                 cc = scaler_create_compiled_code8_alpha( w, u, du );
1061         }
1062
1063 #endif
1064
1065         spixels = (ubyte *)bp->data;
1066
1067         gr_lock();
1068
1069         uint fx_w = 0;
1070         if ( Gr_scaler_zbuffering  && gr_zbuffering )   {
1071                 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
1072         }       
1073
1074         for (y=dy0; y<=dy1; y++ )                       {
1075                 sbits = &spixels[bp->rowsize*(v>>16)];
1076                 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
1077                 // uint lookup = (uint)&Current_alphacolor->table.lookup[0][0];
1078                 uint lookup = (uint)&old_alphac.table.lookup[0][0];
1079                 
1080 #ifdef USE_COMPILED_CODE
1081                 // Call the compiled code to draw one scanline
1082                 if ( Gr_scaler_zbuffering  && gr_zbuffering )   {
1083                         int x, tmp_u;
1084                         tmp_u = u;
1085
1086                         uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1087         
1088                         for (x=0; x<w; x++ )                    {
1089                                 if ( fx_w > *zbuf )     {
1090                                         // uint c = sbits[ tmp_u >> 16 ];
1091                                         // *dbits = Current_alphacolor->table.lookup[c][*dbits];
1092                                         *dbits = (ubyte)0x00;
1093                                 }
1094                                 zbuf++;
1095                                 dbits++;
1096                                 tmp_u += du;
1097                         }
1098                 } else {
1099 #ifdef PLAT_UNIX
1100                         STUB_FUNCTION;
1101 #else
1102                         _asm push esi
1103                         _asm push edi
1104                         _asm push ecx
1105                         _asm push ebx
1106                         _asm push eax
1107                         _asm mov ecx, lookup
1108                         _asm mov esi, sbits
1109                         _asm mov edi, dbits
1110                         _asm mov eax, cc
1111                         _asm call eax
1112                         _asm pop eax
1113                         _asm pop ebx
1114                         _asm pop ecx
1115                         _asm pop edi
1116                         _asm pop esi
1117 #endif
1118                 }
1119 #else   
1120                 if ( Gr_scaler_zbuffering && gr_zbuffering )    {
1121                         int x, tmp_u;
1122                         tmp_u = u;
1123
1124                         uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1125         
1126                         for (x=0; x<w; x++ )                    {
1127                                 if ( fx_w > *zbuf )     {
1128                                         uint c = sbits[ tmp_u >> 16 ];
1129                                         *dbits = Current_alphacolor->table.lookup[c][*dbits];
1130                                 }
1131                                 zbuf++;
1132                                 dbits++;
1133                                 tmp_u += du;
1134                         }
1135                 } else {
1136                         int x, tmp_u;
1137                         tmp_u = u;
1138                         for (x=0; x<w; x++ )                    {
1139                                 uint c = sbits[ tmp_u >> 16 ];
1140                                 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1141                                 dbits++;
1142                                 tmp_u += du;
1143                         }
1144                 }
1145 #endif
1146                 v += dv;
1147         }
1148
1149         gr_unlock();
1150
1151         bm_unlock(gr_screen.current_bitmap);
1152 }
1153