2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Graphics/Scaler.cpp $
15 * Routines to scale a bitmap.
18 * Revision 1.4 2002/07/13 06:46:48 theoddone33
21 * Revision 1.3 2002/06/09 04:41:18 relnev
22 * added copyright header
24 * Revision 1.2 2002/06/05 08:05:29 relnev
25 * stub/warning removal.
27 * reworked the sound code.
29 * Revision 1.1.1.1 2002/05/03 03:28:09 root
33 * 9 7/20/99 1:49p Dave
34 * Peter Drake build. Fixed some release build warnings.
36 * 8 6/22/99 7:03p Dave
37 * New detail options screen.
39 * 7 5/12/99 5:33p Johne
40 * Don't use gr8_scaler() in pofview.
42 * 6 5/09/99 6:00p Dave
43 * Lots of cool new effects. E3 build tweaks.
45 * 5 1/14/99 6:06p Dave
46 * 100% full squad logo support for single player and multiplayer.
48 * 4 1/14/99 12:48a Dave
49 * Todo list bug fixes. Made a pass at putting briefing icons back into
50 * FRED. Sort of works :(
52 * 3 11/30/98 1:07p Dave
53 * 16 bit conversion, first run.
55 * 2 10/07/98 10:53a Dave
58 * 1 10/07/98 10:49a Dave
60 * 40 4/02/98 2:01p Dave
61 * JAS: Increased constant for source of compiled code
63 * 39 4/01/98 9:21p John
64 * Made NDEBUG, optimized build with no warnings or errors.
66 * 38 4/01/98 7:15p John
67 * fixed bug with previous
69 * 37 4/01/98 6:45p John
70 * Reduced memory by combining compled_code ptrs.
72 * 36 3/22/98 3:28p John
73 * Added in stippled alpha for lower details. Made medium detail use
76 * 35 3/10/98 4:18p John
77 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
78 * & Glide have popups and print screen. Took out all >8bpp software
79 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
80 * support Fred. Made zbuffering key off of functions rather than one
83 * 34 2/05/98 9:21p John
84 * Some new Direct3D code. Added code to monitor a ton of stuff in the
87 * 33 1/27/98 10:18a John
88 * fixed warning for optimized build
90 * 32 1/26/98 5:12p John
91 * Added in code for Pentium Pro specific optimizations. Speed up
92 * zbuffered correct tmapper about 35%. Speed up non-zbuffered scalers
95 * 31 1/19/98 6:15p John
96 * Fixed all my Optimized Build compiler warnings
98 * 30 12/04/97 12:09p John
99 * Made glows use scaler instead of tmapper so they don't rotate. Had to
100 * add a zbuffered scaler.
102 * 29 12/02/97 4:00p John
103 * Added first rev of thruster glow, along with variable levels of
104 * translucency, which retquired some restructing of palman.
106 * 28 11/30/97 4:33p John
107 * added 32-bpp aascaler
109 * 27 11/30/97 3:57p John
110 * Made fixed 32-bpp translucency. Made BmpMan always map translucent
111 * color into 255 even if you aren't supposed to remap and make it's
114 * 26 11/30/97 12:18p John
115 * added more 24 & 32-bpp primitives
117 * 25 11/29/97 2:06p John
118 * added mode 16-bpp support
120 * 24 11/14/97 12:30p John
121 * Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
122 * libs. Made 16-bpp DirectX modes know what bitmap format they're in.
124 * 23 10/19/97 12:55p John
125 * new code to lock / unlock surfaces for smooth directx integration.
127 * 22 10/15/97 4:48p John
128 * added 16-bpp aascaler
130 * 21 10/14/97 8:08a John
131 * added a bunch more 16 bit support
133 * 20 10/09/97 5:23p John
134 * Added support for more 16-bpp functions
136 * 19 8/04/97 4:47p John
139 * 18 7/28/97 11:31a John
140 * made compiled code save all registers that it changes. When building
141 * optimized, my code was using EBX, and so was the compiler, so weird
142 * errors happened. Pushing/popping ebx fixed this.
144 * 17 7/16/97 5:29p John
145 * added palette table caching and made scaler and liner no light tmapper
146 * do alpha blending in 8 bpp mode.
148 * 16 7/10/97 2:06p John
149 * added code to specify alphablending type for bitmaps.
151 * 15 6/12/97 2:50a Lawrance
152 * bm_unlock() now passed bitmap number, not pointer
154 * 14 5/29/97 3:10p John
155 * Took out debug menu.
156 * Made software scaler draw larger bitmaps.
157 * Optimized Direct3D some.
159 * 13 5/12/97 12:27p John
160 * Restructured Graphics Library to add support for multiple renderers.
162 * 12 12/04/96 2:02p John
163 * Added fast compiled code to the scaler in 8,16,32 bpp modes.
165 * 11 12/03/96 8:08p John
166 * Added compiled code to 8bpp scaler. Made bitmaps that are trying to
167 * scale up too big to not draw.
169 * 10 12/03/96 11:12a John
170 * added commented out "filtering" code to scaler.
172 * 9 11/19/96 2:42p Allender
173 * fix up 32 bit scaler
175 * 8 11/15/96 11:27a Allender
176 * 16bpp version of scaler
178 * 7 11/07/96 6:19p John
179 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
182 * 6 10/26/96 1:40p John
183 * Added some now primitives to the 2d library and
184 * cleaned up some old ones.
199 #include "grinternal.h"
200 #include "floating.h"
203 #include "tmapscanline.h"
204 #include "systemvars.h"
208 #define MIN_SCALE_FACTOR 0.0001f
210 #define USE_COMPILED_CODE
212 #define TRANSPARENCY_COLOR_8 0xff
213 #define TRANSPARENCY_COLOR_16 0xffff
214 #define TRANSPARENCY_COLOR_32 0xffffffff
216 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
218 #define MAX_CODE_SIZE 32768 //65536 JAS: Determed to be 8208 on April1,98, 16K seems safe
220 ubyte compiled_code[MAX_CODE_SIZE];
223 static int Max_size = 0;
229 _asm mov ax, [esi+0xabcdef12]
232 _asm mov [edi+0xabcdef12], ax
233 _asm mov ax, [esi+0xabcdef12]
239 //----------------------------------------------------
240 // scaler_create_compiled_code8
242 // Creates code that looks like:
244 // @@: mov al, [esi+????]
245 // cmp al, TRANSPARENCY_COLOR_8
246 // je @f ; jump to next @@ label
247 // mov [edi+???], al ; If the source pixel is scaled up
248 // mov [edi+???], al ; there might be a lot of these lines
250 // @@: mov al, [esi+????]
253 ubyte *scaler_create_compiled_code8( int w, fix u, fix du )
261 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
263 // *cc++ = 0xCC; // Int3
264 // *cc++ = 0xc3; // RET
270 for (x=0; x<w; x++ ) {
271 if ( last_u != f2i(u) ) {
272 if ( last_jmp_pos ) {
273 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
275 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
276 *(uint *)cc = f2i(u); cc += 4;
279 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
280 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
281 last_jmp_pos = (uint *)cc;
286 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
287 *(uint *)cc = x; cc += 4;
291 if ( last_jmp_pos ) {
292 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
296 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
297 Int3(); // GET JOHN NOW!
300 int size = cc - compiled_code;
301 if ( size > Max_size ) {
303 mprintf(( "Max size = %d\n", size ));
307 return compiled_code;
310 ubyte *scaler_create_compiled_code8_stippled( int w, fix u, fix du )
318 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
320 // *cc++ = 0xCC; // Int3
321 // *cc++ = 0xc3; // RET
327 for (x=0; x<w-1; x+=2 ) {
328 if ( last_u != f2i(u) ) {
329 if ( last_jmp_pos ) {
330 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
332 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
333 *(uint *)cc = f2i(u); cc += 4;
336 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
337 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
338 last_jmp_pos = (uint *)cc;
343 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
344 *(uint *)cc = x; cc += 4;
348 if ( last_jmp_pos ) {
349 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
353 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
354 Int3(); // GET JOHN NOW!
357 int size = cc - compiled_code;
358 if ( size > Max_size ) {
360 mprintf(( "Max size = %d\n", size ));
364 return compiled_code;
375 _asm mov bl, BYTE PTR [edi-1412567278]
377 _asm mov ebx, [ecx+ebx] ; blend it
382 // xor eax, eax ; avoid ppro partial register stall
383 // mov ah, [esi+????] ; get the foreground pixel
384 // ; the following lines might be repeated
385 // xor ebx, ebx ; avoid ppro partial register stall
386 // mov bl, [edi+????] ; get the background pixel
387 // mov ebx, [ecx+ebx] ; blend it
388 // mov [edi+????], bl ; write it
393 00130 b8 00 00 00 00 mov eax, 0
394 00135 8a a6 12 ef cd ab mov ah, BYTE PTR [esi-1412567278]
395 0013b 8a 87 12 ef cd ab mov al, BYTE PTR [edi-1412567278]
396 00141 8a 1c 01 mov bl, BYTE PTR [ecx+eax]
397 00141 8b 1c 01 mov ebx, DWORD PTR [ecx+eax]
398 00144 88 9f 12 ef cd ab mov BYTE PTR [edi-1412567278], bl
401 00130 33 c0 xor eax, eax
402 00132 33 db xor ebx, ebx
403 00134 8a 9f 12 ef cd ab mov bl, BYTE PTR [edi-1412567278]
404 0013a 03 d8 add ebx, eax
405 0013c 8b 1c 19 mov ebx, DWORD PTR [ecx+ebx]
407 0013f 3b 2a cmp ebp, DWORD PTR [edx]
408 00141 83 c2 04 add edx, 4
413 //----------------------------------------------------
414 // scaler_create_compiled_code8_alpha
416 // Creates code that looks like:
418 //=============== Pentium ======================
420 // mov ah, [esi+????] ; get the foreground pixel
421 // ; the following lines might be repeated
422 // mov al, [edi+????] ; get the background pixel
423 // mov bl, [ecx+eax] ; blend it
424 // mov [edi+????], bl ; write it
427 //============= Pentium Pro code =============
428 // xor eax, eax ; avoid ppro partial register stall
429 // mov ah, [esi+????] ; get the foreground pixel
430 // ; the following lines might be repeated
431 // xor ebx, ebx ; avoid ppro partial register stall
432 // mov bl, [edi+????] ; get the background pixel
433 // mov ebx, [ecx+ebx] ; blend it
434 // mov [edi+????], bl ; write it
437 ubyte *scaler_create_compiled_code8_alpha( int w, fix u, fix du )
444 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
446 //*cc++ = 0xCC; // Int3
447 //*cc++ = 0xc3; // RET
452 // Pentium Pro optimized code.
454 for (x=0; x<w; x++ ) {
455 if ( last_u != f2i(u) ) {
456 *cc++ = 0x33; *cc++ = 0xc0; // xor eax, eax
457 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
458 //*cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
459 *(uint *)cc = f2i(u); cc += 4;
463 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
465 *cc++ = 0x8a; *cc++ = 0x9f;
466 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
468 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
470 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
472 *cc++ = 0x88; *cc++ = 0x9f;
473 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
478 // Pentium optimized code.
480 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
482 for (x=0; x<w; x++ ) {
483 if ( last_u != f2i(u) ) {
484 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
485 *(uint *)cc = f2i(u); cc += 4;
489 *cc++ = 0x8a; *cc++ = 0x87;
490 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
492 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
494 *cc++ = 0x88; *cc++ = 0x9f;
495 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
503 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
504 Int3(); // GET JOHN NOW!
507 int size = cc - compiled_code;
508 if ( size > Max_size ) {
510 mprintf(( "Max size = %d\n", size ));
514 return compiled_code;
518 for (x=0; x<w; x++ ) {
519 if ( fx_w > *zbuf ) {
520 uint c = sbits[ tmp_u >> 16 ]<<8;
521 *dbits = *((ubyte *)(lookup + (*dbits | c)));
529 //----------------------------------------------------
530 // scaler_create_compiled_code8_alpha_zbuffered
532 // Creates code that looks like:
534 // mov ah, [esi+????] ; get the foreground pixel
535 // ; the following lines might be repeated
536 // cmp fx_w, [edx+?????]
538 // mov al, [edi+????] ; get the background pixel
539 // mov bl, [ecx+eax] ; blend it
540 // mov [edi+????], bl ; write it
549 // _asm cmp 0xFFFFFFFF, [edx+0xabcdef12]
550 // _asm cmp ebp, [edx+0xabcdef12]
551 // _asm jle 0xabcdef12
553 //; 302 : _asm cmp ebp, [edx+0xabcdef12]
554 // 00244 3b aa 12 ef cd ab cmp ebp, DWORD PTR [edx-1412567278]
555 //; 303 : _asm jle 0xabcdef12
556 // 0024a 0f 8e 12 ef cd ab jle -1412567278 ; abcdef12H
558 ubyte *scaler_create_compiled_code8_alpha_zbuffered( int w, fix u, fix du )
562 uint *last_jmp_pos=NULL;
566 // xor eax, eax ; avoid ppro partial register stall
567 // mov ah, [esi+????] ; get the foreground pixel
568 // ; the following lines might be repeated
569 // xor ebx, ebx ; avoid ppro partial register stall
570 // mov bl, [edi+????] ; get the background pixel
571 // mov ebx, [ecx+ebx] ; blend it
572 // mov [edi+????], bl ; write it
574 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
576 //*cc++ = 0xCC; // Int3
577 //*cc++ = 0xc3; // RET
581 // Pentium Pro optimized code.
583 for (x=0; x<w; x++ ) {
584 if ( last_u != f2i(u) ) {
585 *cc++ = 0x33; *cc++ = 0xc0; // xor eax, eax
586 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
587 *(uint *)cc = f2i(u); cc += 4;
591 *cc++ = 0x3b; *cc++ = 0xaa;
592 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
594 // *cc++ = 0x3b; *cc++ = 0x2a; // cmp ebp, [edx]
595 // *cc++ = 0x83; *cc++ = 0xc2; *cc++ = 0x4; // add edx, 4
597 *cc++ = 0x0f; *cc++ = 0x8e; // jle (8e) imm
598 last_jmp_pos = (uint *)cc;
599 *(uint *)cc = 0; cc += 4;
601 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
603 *cc++ = 0x8a; *cc++ = 0x9f;
604 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
606 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
608 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
610 *cc++ = 0x88; *cc++ = 0x9f;
611 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
613 if ( last_jmp_pos ) {
614 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
623 // Pentium optimized code.
625 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
627 for (x=0; x<w; x++ ) {
628 if ( last_u != f2i(u) ) {
629 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
630 *(uint *)cc = f2i(u); cc += 4;
634 *cc++ = 0x3b; *cc++ = 0xaa;
635 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
637 *cc++ = 0x0f; *cc++ = 0x8e; // jle imm
638 last_jmp_pos = (uint *)cc;
639 *(uint *)cc = 0; cc += 4;
641 *cc++ = 0x8a; *cc++ = 0x87;
642 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
644 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
646 *cc++ = 0x88; *cc++ = 0x9f;
647 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
649 if ( last_jmp_pos ) {
650 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
659 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
660 Int3(); // GET JOHN NOW!
663 int size = cc - compiled_code;
664 if ( size > Max_size ) {
666 mprintf(( "Max sizeZ = %d\n", size ));
670 return compiled_code;
675 int Gr_scaler_zbuffering = 0;
678 MONITOR( ScalerNumCalls );
681 //----------------------------------------------------
682 // Scales current bitmap, between va and vb
683 void gr8_scaler(vertex *va, vertex *vb )
690 float x0, y0, x1, y1;
691 float u0, v0, u1, v1;
692 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
693 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
694 float xmin, xmax, ymin, ymax;
695 int dx0, dy0, dx1, dy1;
697 MONITOR_INC( ScalerNumCalls, 1 );
699 //============= CLIP IT =====================
701 x0 = va->sx; y0 = va->sy;
702 x1 = vb->sx; y1 = vb->sy;
704 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
705 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
707 u0 = va->u; v0 = va->v;
708 u1 = vb->u; v1 = vb->v;
710 // Check for obviously offscreen bitmaps...
711 if ( (y1<=y0) || (x1<=x0) ) return;
712 if ( (x1<xmin ) || (x0>xmax) ) return;
713 if ( (y1<ymin ) || (y0>ymax) ) return;
715 clipped_u0 = u0; clipped_v0 = v0;
716 clipped_u1 = u1; clipped_v1 = v1;
718 clipped_x0 = x0; clipped_y0 = y0;
719 clipped_x1 = x1; clipped_y1 = y1;
721 // Clip the left, moving u0 right as necessary
723 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
727 // Clip the right, moving u1 left as necessary
729 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
733 // Clip the top, moving v0 down as necessary
735 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
739 // Clip the bottom, moving v1 up as necessary
741 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
745 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
746 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
748 if (dx1<=dx0) return;
749 if (dy1<=dy0) return;
751 //============= DRAW IT =====================
754 ubyte * sbits, * dbits;
759 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
760 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
761 return; // scaled up way too far!
763 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
764 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
765 return; // scaled up way too far!
771 if ( !Detail.alpha_effects ) {
773 Gr_scaler_zbuffering = 0;
778 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
780 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
784 du = fl2f(tmpu*(bp->w-1));
785 dv = fl2f(tmpv*(bp->h-1));
787 v = fl2f(clipped_v0*(bp->h-1));
788 u = fl2f(clipped_u0*(bp->w-1));
791 bm_unlock(gr_screen.current_bitmap);
796 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
797 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
801 #ifdef USE_COMPILED_CODE
804 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
805 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
806 cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
809 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
811 cc = scaler_create_compiled_code8_stippled( w, u, du );
813 cc = scaler_create_compiled_code8_alpha( w, u, du );
816 cc = scaler_create_compiled_code8( w, u, du );
822 spixels = (ubyte *)bp->data;
825 Tmap.pScreenBits = (uint)gr_screen.offscreen_buffer_base;
829 for (y=dy0; y<=dy1; v += dv, y++ ) {
830 if ( is_stippled && (y&1) ) {
831 sbits = &spixels[bp->rowsize*(v>>16)+f2i(du)];
832 dbits = GR_SCREEN_PTR(ubyte,dx0+1,y);
834 sbits = &spixels[bp->rowsize*(v>>16)];
835 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
839 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
840 lookup = (uint)palette_get_blend_table(gr_screen.current_alpha);
843 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
844 zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
847 #ifdef USE_COMPILED_CODE
848 // Call the compiled code to draw one scanline
849 if ( Gr_scaler_zbuffering && gr_zbuffering && (gr_screen.current_alphablend_mode != GR_ALPHABLEND_FILTER)) {
856 for (x=0; x<w; x++ ) {
857 if ( fx_w > *zbuf ) {
858 ubyte c = sbits[ tmp_u >> 16 ];
859 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
872 for (x=0; x<w; x++ ) {
873 if ( fx_w > *zbuf ) {
874 uint c = sbits[ tmp_u >> 16 ]<<8;
875 *dbits = *((ubyte *)(lookup + (*dbits | c)));
898 _asm mov ebp, Gr_global_z
910 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
911 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
915 for (x=0; x<w; x++ ) {
916 if ( fx_w > *zbuf ) {
917 uint c = sbits[ tmp_u >> 16 ]<<8;
918 *dbits = *((ubyte *)(lookup + (*dbits | c)));
927 for (x=0; x<w; x++ ) {
928 uint c = sbits[ tmp_u >> 16 ]<<8;
929 *dbits++ = palette_blend[*dbits|c];
934 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
938 for (x=0; x<w; x++ ) {
939 if ( fx_w > *zbuf ) {
940 ubyte c = sbits[ tmp_u >> 16 ];
941 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
950 for (x=0; x<w; x++ ) {
951 ubyte c = sbits[ tmp_u >> 16 ];
952 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
962 bm_unlock(gr_screen.current_bitmap);
967 alphacolor_old old_alphac;
968 //----------------------------------------------------
969 // Scales current bitmap, between va and vb
970 void gr8_aascaler(vertex *va, vertex *vb )
972 float x0, y0, x1, y1;
973 float u0, v0, u1, v1;
974 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
975 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
976 float xmin, xmax, ymin, ymax;
977 int dx0, dy0, dx1, dy1;
979 //if ( !Current_alphacolor ) return;
981 MONITOR_INC( ScalerNumCalls, 1 );
983 SDL_assert(Fred_running);
989 old_alphac.alpha = 255;
993 calc_alphacolor_old(&old_alphac);
997 //============= CLIP IT =====================
999 x0 = va->sx; y0 = va->sy;
1000 x1 = vb->sx; y1 = vb->sy;
1002 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
1003 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
1005 u0 = va->u; v0 = va->v;
1006 u1 = vb->u; v1 = vb->v;
1008 // Check for obviously offscreen bitmaps...
1009 if ( (y1<=y0) || (x1<=x0) ) return;
1010 if ( (x1<xmin ) || (x0>xmax) ) return;
1011 if ( (y1<ymin ) || (y0>ymax) ) return;
1013 clipped_u0 = u0; clipped_v0 = v0;
1014 clipped_u1 = u1; clipped_v1 = v1;
1016 clipped_x0 = x0; clipped_y0 = y0;
1017 clipped_x1 = x1; clipped_y1 = y1;
1019 // Clip the left, moving u0 right as necessary
1021 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1025 // Clip the right, moving u1 left as necessary
1027 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1031 // Clip the top, moving v0 down as necessary
1033 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1037 // Clip the bottom, moving v1 up as necessary
1039 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1043 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1044 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1046 if (dx1<=dx0) return;
1047 if (dy1<=dy0) return;
1049 //============= DRAW IT =====================
1052 ubyte * sbits, * dbits;
1057 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
1058 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
1059 return; // scaled up way too far!
1061 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
1062 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
1063 return; // scaled up way too far!
1066 bp = bm_lock( gr_screen.current_bitmap, 8, BMP_AABITMAP );
1068 du = fl2f(tmpu*(bp->w-1));
1069 dv = fl2f(tmpv*(bp->h-1));
1071 v = fl2f(clipped_v0*(bp->h-1));
1072 u = fl2f(clipped_u0*(bp->w-1));
1075 #ifdef USE_COMPILED_CODE
1078 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1079 //cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
1081 cc = scaler_create_compiled_code8_alpha( w, u, du );
1086 spixels = (ubyte *)bp->data;
1091 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1092 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
1095 for (y=dy0; y<=dy1; y++ ) {
1096 sbits = &spixels[bp->rowsize*(v>>16)];
1097 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
1099 #ifdef USE_COMPILED_CODE
1100 // uint lookup = (uint)&Current_alphacolor->table.lookup[0][0];
1101 //uint lookup = (uint)&old_alphac.table.lookup[0][0]; // Unused - DDOI
1103 // Call the compiled code to draw one scanline
1104 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1108 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1110 for (x=0; x<w; x++ ) {
1111 if ( fx_w > *zbuf ) {
1112 // uint c = sbits[ tmp_u >> 16 ];
1113 // *dbits = Current_alphacolor->table.lookup[c][*dbits];
1114 *dbits = (ubyte)0x00;
1129 _asm mov ecx, lookup
1142 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1146 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1148 for (x=0; x<w; x++ ) {
1149 if ( fx_w > *zbuf ) {
1150 uint c = sbits[ tmp_u >> 16 ];
1151 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1160 for (x=0; x<w; x++ ) {
1161 uint c = sbits[ tmp_u >> 16 ];
1162 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1173 bm_unlock(gr_screen.current_bitmap);