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