2 * $Logfile: /Freespace2/code/Graphics/Scaler.cpp $
7 * Routines to scale a bitmap.
10 * Revision 1.2 2002/06/05 08:05:29 relnev
11 * stub/warning removal.
13 * reworked the sound code.
15 * Revision 1.1.1.1 2002/05/03 03:28:09 root
19 * 9 7/20/99 1:49p Dave
20 * Peter Drake build. Fixed some release build warnings.
22 * 8 6/22/99 7:03p Dave
23 * New detail options screen.
25 * 7 5/12/99 5:33p Johne
26 * Don't use gr8_scaler() in pofview.
28 * 6 5/09/99 6:00p Dave
29 * Lots of cool new effects. E3 build tweaks.
31 * 5 1/14/99 6:06p Dave
32 * 100% full squad logo support for single player and multiplayer.
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 :(
38 * 3 11/30/98 1:07p Dave
39 * 16 bit conversion, first run.
41 * 2 10/07/98 10:53a Dave
44 * 1 10/07/98 10:49a Dave
46 * 40 4/02/98 2:01p Dave
47 * JAS: Increased constant for source of compiled code
49 * 39 4/01/98 9:21p John
50 * Made NDEBUG, optimized build with no warnings or errors.
52 * 38 4/01/98 7:15p John
53 * fixed bug with previous
55 * 37 4/01/98 6:45p John
56 * Reduced memory by combining compled_code ptrs.
58 * 36 3/22/98 3:28p John
59 * Added in stippled alpha for lower details. Made medium detail use
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
69 * 34 2/05/98 9:21p John
70 * Some new Direct3D code. Added code to monitor a ton of stuff in the
73 * 33 1/27/98 10:18a John
74 * fixed warning for optimized build
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
81 * 31 1/19/98 6:15p John
82 * Fixed all my Optimized Build compiler warnings
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.
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.
92 * 28 11/30/97 4:33p John
93 * added 32-bpp aascaler
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
100 * 26 11/30/97 12:18p John
101 * added more 24 & 32-bpp primitives
103 * 25 11/29/97 2:06p John
104 * added mode 16-bpp support
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.
110 * 23 10/19/97 12:55p John
111 * new code to lock / unlock surfaces for smooth directx integration.
113 * 22 10/15/97 4:48p John
114 * added 16-bpp aascaler
116 * 21 10/14/97 8:08a John
117 * added a bunch more 16 bit support
119 * 20 10/09/97 5:23p John
120 * Added support for more 16-bpp functions
122 * 19 8/04/97 4:47p John
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.
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.
134 * 16 7/10/97 2:06p John
135 * added code to specify alphablending type for bitmaps.
137 * 15 6/12/97 2:50a Lawrance
138 * bm_unlock() now passed bitmap number, not pointer
140 * 14 5/29/97 3:10p John
141 * Took out debug menu.
142 * Made software scaler draw larger bitmaps.
143 * Optimized Direct3D some.
145 * 13 5/12/97 12:27p John
146 * Restructured Graphics Library to add support for multiple renderers.
148 * 12 12/04/96 2:02p John
149 * Added fast compiled code to the scaler in 8,16,32 bpp modes.
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.
155 * 10 12/03/96 11:12a John
156 * added commented out "filtering" code to scaler.
158 * 9 11/19/96 2:42p Allender
159 * fix up 32 bit scaler
161 * 8 11/15/96 11:27a Allender
162 * 16bpp version of scaler
164 * 7 11/07/96 6:19p John
165 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
168 * 6 10/26/96 1:40p John
169 * Added some now primitives to the 2d library and
170 * cleaned up some old ones.
185 #include "grinternal.h"
186 #include "floating.h"
189 #include "tmapscanline.h"
190 #include "systemvars.h"
194 #define MIN_SCALE_FACTOR 0.0001f
196 #define USE_COMPILED_CODE
198 #define TRANSPARENCY_COLOR_8 0xff
199 #define TRANSPARENCY_COLOR_16 0xffff
200 #define TRANSPARENCY_COLOR_32 0xffffffff
202 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
204 #define MAX_CODE_SIZE 32768 //65536 JAS: Determed to be 8208 on April1,98, 16K seems safe
206 ubyte compiled_code[MAX_CODE_SIZE];
209 static int Max_size = 0;
215 _asm mov ax, [esi+0xabcdef12]
218 _asm mov [edi+0xabcdef12], ax
219 _asm mov ax, [esi+0xabcdef12]
225 //----------------------------------------------------
226 // scaler_create_compiled_code8
228 // Creates code that looks like:
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
236 // @@: mov al, [esi+????]
239 ubyte *scaler_create_compiled_code8( int w, fix u, fix du )
247 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
249 // *cc++ = 0xCC; // Int3
250 // *cc++ = 0xc3; // RET
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;
261 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
262 *(uint *)cc = f2i(u); cc += 4;
265 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
266 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
267 last_jmp_pos = (uint *)cc;
272 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
273 *(uint *)cc = x; cc += 4;
277 if ( last_jmp_pos ) {
278 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
282 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
283 Int3(); // GET JOHN NOW!
286 int size = cc - compiled_code;
287 if ( size > Max_size ) {
289 mprintf(( "Max size = %d\n", size ));
293 return compiled_code;
296 ubyte *scaler_create_compiled_code8_stippled( int w, fix u, fix du )
304 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
306 // *cc++ = 0xCC; // Int3
307 // *cc++ = 0xc3; // RET
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;
318 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
319 *(uint *)cc = f2i(u); cc += 4;
322 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
323 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
324 last_jmp_pos = (uint *)cc;
329 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
330 *(uint *)cc = x; cc += 4;
334 if ( last_jmp_pos ) {
335 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
339 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
340 Int3(); // GET JOHN NOW!
343 int size = cc - compiled_code;
344 if ( size > Max_size ) {
346 mprintf(( "Max size = %d\n", size ));
350 return compiled_code;
361 _asm mov bl, BYTE PTR [edi-1412567278]
363 _asm mov ebx, [ecx+ebx] ; blend it
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
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
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]
393 0013f 3b 2a cmp ebp, DWORD PTR [edx]
394 00141 83 c2 04 add edx, 4
399 //----------------------------------------------------
400 // scaler_create_compiled_code8_alpha
402 // Creates code that looks like:
404 //=============== Pentium ======================
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
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
423 ubyte *scaler_create_compiled_code8_alpha( int w, fix u, fix du )
430 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
432 //*cc++ = 0xCC; // Int3
433 //*cc++ = 0xc3; // RET
438 // Pentium Pro optimized code.
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;
449 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
451 *cc++ = 0x8a; *cc++ = 0x9f;
452 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
454 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
456 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
458 *cc++ = 0x88; *cc++ = 0x9f;
459 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
464 // Pentium optimized code.
466 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
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;
475 *cc++ = 0x8a; *cc++ = 0x87;
476 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
478 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
480 *cc++ = 0x88; *cc++ = 0x9f;
481 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
489 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
490 Int3(); // GET JOHN NOW!
493 int size = cc - compiled_code;
494 if ( size > Max_size ) {
496 mprintf(( "Max size = %d\n", size ));
500 return compiled_code;
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)));
515 //----------------------------------------------------
516 // scaler_create_compiled_code8_alpha_zbuffered
518 // Creates code that looks like:
520 // mov ah, [esi+????] ; get the foreground pixel
521 // ; the following lines might be repeated
522 // cmp fx_w, [edx+?????]
524 // mov al, [edi+????] ; get the background pixel
525 // mov bl, [ecx+eax] ; blend it
526 // mov [edi+????], bl ; write it
535 // _asm cmp 0xFFFFFFFF, [edx+0xabcdef12]
536 // _asm cmp ebp, [edx+0xabcdef12]
537 // _asm jle 0xabcdef12
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
544 ubyte *scaler_create_compiled_code8_alpha_zbuffered( int w, fix u, fix du )
548 uint *last_jmp_pos=NULL;
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
560 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
562 //*cc++ = 0xCC; // Int3
563 //*cc++ = 0xc3; // RET
567 // Pentium Pro optimized code.
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;
577 *cc++ = 0x3b; *cc++ = 0xaa;
578 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
580 // *cc++ = 0x3b; *cc++ = 0x2a; // cmp ebp, [edx]
581 // *cc++ = 0x83; *cc++ = 0xc2; *cc++ = 0x4; // add edx, 4
583 *cc++ = 0x0f; *cc++ = 0x8e; // jle (8e) imm
584 last_jmp_pos = (uint *)cc;
585 *(uint *)cc = 0; cc += 4;
587 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
589 *cc++ = 0x8a; *cc++ = 0x9f;
590 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
592 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
594 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
596 *cc++ = 0x88; *cc++ = 0x9f;
597 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
599 if ( last_jmp_pos ) {
600 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
609 // Pentium optimized code.
611 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
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;
620 *cc++ = 0x3b; *cc++ = 0xaa;
621 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
623 *cc++ = 0x0f; *cc++ = 0x8e; // jle imm
624 last_jmp_pos = (uint *)cc;
625 *(uint *)cc = 0; cc += 4;
627 *cc++ = 0x8a; *cc++ = 0x87;
628 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
630 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
632 *cc++ = 0x88; *cc++ = 0x9f;
633 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
635 if ( last_jmp_pos ) {
636 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
645 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
646 Int3(); // GET JOHN NOW!
649 int size = cc - compiled_code;
650 if ( size > Max_size ) {
652 mprintf(( "Max sizeZ = %d\n", size ));
656 return compiled_code;
661 int Gr_scaler_zbuffering = 0;
664 MONITOR( ScalerNumCalls );
667 //----------------------------------------------------
668 // Scales current bitmap, between va and vb
669 void gr8_scaler(vertex *va, vertex *vb )
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;
683 MONITOR_INC( ScalerNumCalls, 1 );
685 //============= CLIP IT =====================
687 x0 = va->sx; y0 = va->sy;
688 x1 = vb->sx; y1 = vb->sy;
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);
693 u0 = va->u; v0 = va->v;
694 u1 = vb->u; v1 = vb->v;
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;
701 clipped_u0 = u0; clipped_v0 = v0;
702 clipped_u1 = u1; clipped_v1 = v1;
704 clipped_x0 = x0; clipped_y0 = y0;
705 clipped_x1 = x1; clipped_y1 = y1;
707 // Clip the left, moving u0 right as necessary
709 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
713 // Clip the right, moving u1 left as necessary
715 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
719 // Clip the top, moving v0 down as necessary
721 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
725 // Clip the bottom, moving v1 up as necessary
727 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
731 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
732 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
734 if (dx1<=dx0) return;
735 if (dy1<=dy0) return;
737 //============= DRAW IT =====================
740 ubyte * sbits, * dbits;
745 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
746 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
747 return; // scaled up way too far!
749 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
750 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
751 return; // scaled up way too far!
757 if ( !Detail.alpha_effects ) {
759 Gr_scaler_zbuffering = 0;
764 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
766 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
770 du = fl2f(tmpu*(bp->w-1));
771 dv = fl2f(tmpv*(bp->h-1));
773 v = fl2f(clipped_v0*(bp->h-1));
774 u = fl2f(clipped_u0*(bp->w-1));
777 bm_unlock(gr_screen.current_bitmap);
782 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
783 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
787 #ifdef USE_COMPILED_CODE
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 );
795 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
797 cc = scaler_create_compiled_code8_stippled( w, u, du );
799 cc = scaler_create_compiled_code8_alpha( w, u, du );
802 cc = scaler_create_compiled_code8( w, u, du );
808 spixels = (ubyte *)bp->data;
811 Tmap.pScreenBits = (uint)gr_screen.offscreen_buffer_base;
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);
820 sbits = &spixels[bp->rowsize*(v>>16)];
821 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
825 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
826 lookup = (uint)palette_get_blend_table(gr_screen.current_alpha);
829 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
830 zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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)) {
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;
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)));
884 _asm mov ebp, Gr_global_z
896 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
897 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
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)));
913 for (x=0; x<w; x++ ) {
914 uint c = sbits[ tmp_u >> 16 ]<<8;
915 *dbits++ = palette_blend[*dbits|c];
920 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
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;
936 for (x=0; x<w; x++ ) {
937 ubyte c = sbits[ tmp_u >> 16 ];
938 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
948 bm_unlock(gr_screen.current_bitmap);
953 alphacolor_old old_alphac;
954 //----------------------------------------------------
955 // Scales current bitmap, between va and vb
956 void gr8_aascaler(vertex *va, vertex *vb )
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;
965 //if ( !Current_alphacolor ) return;
967 MONITOR_INC( ScalerNumCalls, 1 );
969 Assert(Fred_running);
975 old_alphac.alpha = 255;
979 calc_alphacolor_old(&old_alphac);
983 //============= CLIP IT =====================
985 x0 = va->sx; y0 = va->sy;
986 x1 = vb->sx; y1 = vb->sy;
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);
991 u0 = va->u; v0 = va->v;
992 u1 = vb->u; v1 = vb->v;
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;
999 clipped_u0 = u0; clipped_v0 = v0;
1000 clipped_u1 = u1; clipped_v1 = v1;
1002 clipped_x0 = x0; clipped_y0 = y0;
1003 clipped_x1 = x1; clipped_y1 = y1;
1005 // Clip the left, moving u0 right as necessary
1007 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1011 // Clip the right, moving u1 left as necessary
1013 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1017 // Clip the top, moving v0 down as necessary
1019 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1023 // Clip the bottom, moving v1 up as necessary
1025 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1029 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1030 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1032 if (dx1<=dx0) return;
1033 if (dy1<=dy0) return;
1035 //============= DRAW IT =====================
1038 ubyte * sbits, * dbits;
1043 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
1044 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
1045 return; // scaled up way too far!
1047 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
1048 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
1049 return; // scaled up way too far!
1052 bp = bm_lock( gr_screen.current_bitmap, 8, BMP_AABITMAP );
1054 du = fl2f(tmpu*(bp->w-1));
1055 dv = fl2f(tmpv*(bp->h-1));
1057 v = fl2f(clipped_v0*(bp->h-1));
1058 u = fl2f(clipped_u0*(bp->w-1));
1061 #ifdef USE_COMPILED_CODE
1064 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1065 //cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
1067 cc = scaler_create_compiled_code8_alpha( w, u, du );
1072 spixels = (ubyte *)bp->data;
1077 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1078 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
1081 for (y=dy0; y<=dy1; y++ ) {
1082 sbits = &spixels[bp->rowsize*(v>>16)];
1083 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
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];
1089 // Call the compiled code to draw one scanline
1090 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1094 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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;
1115 _asm mov ecx, lookup
1128 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1132 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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];
1146 for (x=0; x<w; x++ ) {
1147 uint c = sbits[ tmp_u >> 16 ];
1148 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1159 bm_unlock(gr_screen.current_bitmap);