2 * $Logfile: /Freespace2/code/Graphics/Scaler.cpp $
7 * Routines to scale a bitmap.
10 * Revision 1.1 2002/05/03 03:28:09 root
14 * 9 7/20/99 1:49p Dave
15 * Peter Drake build. Fixed some release build warnings.
17 * 8 6/22/99 7:03p Dave
18 * New detail options screen.
20 * 7 5/12/99 5:33p Johne
21 * Don't use gr8_scaler() in pofview.
23 * 6 5/09/99 6:00p Dave
24 * Lots of cool new effects. E3 build tweaks.
26 * 5 1/14/99 6:06p Dave
27 * 100% full squad logo support for single player and multiplayer.
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 :(
33 * 3 11/30/98 1:07p Dave
34 * 16 bit conversion, first run.
36 * 2 10/07/98 10:53a Dave
39 * 1 10/07/98 10:49a Dave
41 * 40 4/02/98 2:01p Dave
42 * JAS: Increased constant for source of compiled code
44 * 39 4/01/98 9:21p John
45 * Made NDEBUG, optimized build with no warnings or errors.
47 * 38 4/01/98 7:15p John
48 * fixed bug with previous
50 * 37 4/01/98 6:45p John
51 * Reduced memory by combining compled_code ptrs.
53 * 36 3/22/98 3:28p John
54 * Added in stippled alpha for lower details. Made medium detail use
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
64 * 34 2/05/98 9:21p John
65 * Some new Direct3D code. Added code to monitor a ton of stuff in the
68 * 33 1/27/98 10:18a John
69 * fixed warning for optimized build
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
76 * 31 1/19/98 6:15p John
77 * Fixed all my Optimized Build compiler warnings
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.
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.
87 * 28 11/30/97 4:33p John
88 * added 32-bpp aascaler
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
95 * 26 11/30/97 12:18p John
96 * added more 24 & 32-bpp primitives
98 * 25 11/29/97 2:06p John
99 * added mode 16-bpp support
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.
105 * 23 10/19/97 12:55p John
106 * new code to lock / unlock surfaces for smooth directx integration.
108 * 22 10/15/97 4:48p John
109 * added 16-bpp aascaler
111 * 21 10/14/97 8:08a John
112 * added a bunch more 16 bit support
114 * 20 10/09/97 5:23p John
115 * Added support for more 16-bpp functions
117 * 19 8/04/97 4:47p John
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.
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.
129 * 16 7/10/97 2:06p John
130 * added code to specify alphablending type for bitmaps.
132 * 15 6/12/97 2:50a Lawrance
133 * bm_unlock() now passed bitmap number, not pointer
135 * 14 5/29/97 3:10p John
136 * Took out debug menu.
137 * Made software scaler draw larger bitmaps.
138 * Optimized Direct3D some.
140 * 13 5/12/97 12:27p John
141 * Restructured Graphics Library to add support for multiple renderers.
143 * 12 12/04/96 2:02p John
144 * Added fast compiled code to the scaler in 8,16,32 bpp modes.
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.
150 * 10 12/03/96 11:12a John
151 * added commented out "filtering" code to scaler.
153 * 9 11/19/96 2:42p Allender
154 * fix up 32 bit scaler
156 * 8 11/15/96 11:27a Allender
157 * 16bpp version of scaler
159 * 7 11/07/96 6:19p John
160 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
163 * 6 10/26/96 1:40p John
164 * Added some now primitives to the 2d library and
165 * cleaned up some old ones.
180 #include "grinternal.h"
181 #include "floating.h"
184 #include "tmapscanline.h"
185 #include "systemvars.h"
189 #define MIN_SCALE_FACTOR 0.0001f
191 #define USE_COMPILED_CODE
193 #define TRANSPARENCY_COLOR_8 0xff
194 #define TRANSPARENCY_COLOR_16 0xffff
195 #define TRANSPARENCY_COLOR_32 0xffffffff
197 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
199 #define MAX_CODE_SIZE 32768 //65536 JAS: Determed to be 8208 on April1,98, 16K seems safe
201 ubyte compiled_code[MAX_CODE_SIZE];
203 static int Max_size = 0;
208 _asm mov ax, [esi+0xabcdef12]
211 _asm mov [edi+0xabcdef12], ax
212 _asm mov ax, [esi+0xabcdef12]
218 //----------------------------------------------------
219 // scaler_create_compiled_code8
221 // Creates code that looks like:
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
229 // @@: mov al, [esi+????]
232 ubyte *scaler_create_compiled_code8( int w, fix u, fix du )
240 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
242 // *cc++ = 0xCC; // Int3
243 // *cc++ = 0xc3; // RET
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;
254 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
255 *(uint *)cc = f2i(u); cc += 4;
258 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
259 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
260 last_jmp_pos = (uint *)cc;
265 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
266 *(uint *)cc = x; cc += 4;
270 if ( last_jmp_pos ) {
271 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
275 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
276 Int3(); // GET JOHN NOW!
279 int size = cc - compiled_code;
280 if ( size > Max_size ) {
282 mprintf(( "Max size = %d\n", size ));
286 return compiled_code;
289 ubyte *scaler_create_compiled_code8_stippled( int w, fix u, fix du )
297 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
299 // *cc++ = 0xCC; // Int3
300 // *cc++ = 0xc3; // RET
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;
311 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
312 *(uint *)cc = f2i(u); cc += 4;
315 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
316 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
317 last_jmp_pos = (uint *)cc;
322 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
323 *(uint *)cc = x; cc += 4;
327 if ( last_jmp_pos ) {
328 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
332 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
333 Int3(); // GET JOHN NOW!
336 int size = cc - compiled_code;
337 if ( size > Max_size ) {
339 mprintf(( "Max size = %d\n", size ));
343 return compiled_code;
354 _asm mov bl, BYTE PTR [edi-1412567278]
356 _asm mov ebx, [ecx+ebx] ; blend it
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
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
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]
386 0013f 3b 2a cmp ebp, DWORD PTR [edx]
387 00141 83 c2 04 add edx, 4
392 //----------------------------------------------------
393 // scaler_create_compiled_code8_alpha
395 // Creates code that looks like:
397 //=============== Pentium ======================
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
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
416 ubyte *scaler_create_compiled_code8_alpha( int w, fix u, fix du )
423 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
425 //*cc++ = 0xCC; // Int3
426 //*cc++ = 0xc3; // RET
431 // Pentium Pro optimized code.
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;
442 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
444 *cc++ = 0x8a; *cc++ = 0x9f;
445 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
447 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
449 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
451 *cc++ = 0x88; *cc++ = 0x9f;
452 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
457 // Pentium optimized code.
459 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
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;
468 *cc++ = 0x8a; *cc++ = 0x87;
469 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
471 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
473 *cc++ = 0x88; *cc++ = 0x9f;
474 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
482 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
483 Int3(); // GET JOHN NOW!
486 int size = cc - compiled_code;
487 if ( size > Max_size ) {
489 mprintf(( "Max size = %d\n", size ));
493 return compiled_code;
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)));
508 //----------------------------------------------------
509 // scaler_create_compiled_code8_alpha_zbuffered
511 // Creates code that looks like:
513 // mov ah, [esi+????] ; get the foreground pixel
514 // ; the following lines might be repeated
515 // cmp fx_w, [edx+?????]
517 // mov al, [edi+????] ; get the background pixel
518 // mov bl, [ecx+eax] ; blend it
519 // mov [edi+????], bl ; write it
528 // _asm cmp 0xFFFFFFFF, [edx+0xabcdef12]
529 // _asm cmp ebp, [edx+0xabcdef12]
530 // _asm jle 0xabcdef12
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
537 ubyte *scaler_create_compiled_code8_alpha_zbuffered( int w, fix u, fix du )
541 uint *last_jmp_pos=NULL;
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
553 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
555 //*cc++ = 0xCC; // Int3
556 //*cc++ = 0xc3; // RET
560 // Pentium Pro optimized code.
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;
570 *cc++ = 0x3b; *cc++ = 0xaa;
571 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
573 // *cc++ = 0x3b; *cc++ = 0x2a; // cmp ebp, [edx]
574 // *cc++ = 0x83; *cc++ = 0xc2; *cc++ = 0x4; // add edx, 4
576 *cc++ = 0x0f; *cc++ = 0x8e; // jle (8e) imm
577 last_jmp_pos = (uint *)cc;
578 *(uint *)cc = 0; cc += 4;
580 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
582 *cc++ = 0x8a; *cc++ = 0x9f;
583 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
585 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
587 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
589 *cc++ = 0x88; *cc++ = 0x9f;
590 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
592 if ( last_jmp_pos ) {
593 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
602 // Pentium optimized code.
604 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
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;
613 *cc++ = 0x3b; *cc++ = 0xaa;
614 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
616 *cc++ = 0x0f; *cc++ = 0x8e; // jle imm
617 last_jmp_pos = (uint *)cc;
618 *(uint *)cc = 0; cc += 4;
620 *cc++ = 0x8a; *cc++ = 0x87;
621 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
623 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
625 *cc++ = 0x88; *cc++ = 0x9f;
626 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
628 if ( last_jmp_pos ) {
629 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
638 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
639 Int3(); // GET JOHN NOW!
642 int size = cc - compiled_code;
643 if ( size > Max_size ) {
645 mprintf(( "Max sizeZ = %d\n", size ));
649 return compiled_code;
654 int Gr_scaler_zbuffering = 0;
657 MONITOR( ScalerNumCalls );
660 //----------------------------------------------------
661 // Scales current bitmap, between va and vb
662 void gr8_scaler(vertex *va, vertex *vb )
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;
676 MONITOR_INC( ScalerNumCalls, 1 );
678 //============= CLIP IT =====================
680 x0 = va->sx; y0 = va->sy;
681 x1 = vb->sx; y1 = vb->sy;
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);
686 u0 = va->u; v0 = va->v;
687 u1 = vb->u; v1 = vb->v;
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;
694 clipped_u0 = u0; clipped_v0 = v0;
695 clipped_u1 = u1; clipped_v1 = v1;
697 clipped_x0 = x0; clipped_y0 = y0;
698 clipped_x1 = x1; clipped_y1 = y1;
700 // Clip the left, moving u0 right as necessary
702 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
706 // Clip the right, moving u1 left as necessary
708 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
712 // Clip the top, moving v0 down as necessary
714 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
718 // Clip the bottom, moving v1 up as necessary
720 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
724 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
725 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
727 if (dx1<=dx0) return;
728 if (dy1<=dy0) return;
730 //============= DRAW IT =====================
733 ubyte * sbits, * dbits;
738 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
739 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
740 return; // scaled up way too far!
742 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
743 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
744 return; // scaled up way too far!
750 if ( !Detail.alpha_effects ) {
752 Gr_scaler_zbuffering = 0;
757 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
759 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
763 du = fl2f(tmpu*(bp->w-1));
764 dv = fl2f(tmpv*(bp->h-1));
766 v = fl2f(clipped_v0*(bp->h-1));
767 u = fl2f(clipped_u0*(bp->w-1));
770 bm_unlock(gr_screen.current_bitmap);
775 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
776 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
780 #ifdef USE_COMPILED_CODE
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 );
788 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
790 cc = scaler_create_compiled_code8_stippled( w, u, du );
792 cc = scaler_create_compiled_code8_alpha( w, u, du );
795 cc = scaler_create_compiled_code8( w, u, du );
801 spixels = (ubyte *)bp->data;
804 Tmap.pScreenBits = (uint)gr_screen.offscreen_buffer_base;
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);
813 sbits = &spixels[bp->rowsize*(v>>16)];
814 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
818 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
819 lookup = (uint)palette_get_blend_table(gr_screen.current_alpha);
822 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
823 zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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)) {
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;
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)));
877 _asm mov ebp, Gr_global_z
889 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
890 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
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)));
906 for (x=0; x<w; x++ ) {
907 uint c = sbits[ tmp_u >> 16 ]<<8;
908 *dbits++ = palette_blend[*dbits|c];
913 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
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;
929 for (x=0; x<w; x++ ) {
930 ubyte c = sbits[ tmp_u >> 16 ];
931 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
941 bm_unlock(gr_screen.current_bitmap);
946 alphacolor_old old_alphac;
947 //----------------------------------------------------
948 // Scales current bitmap, between va and vb
949 void gr8_aascaler(vertex *va, vertex *vb )
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;
958 //if ( !Current_alphacolor ) return;
960 MONITOR_INC( ScalerNumCalls, 1 );
962 Assert(Fred_running);
968 old_alphac.alpha = 255;
972 calc_alphacolor_old(&old_alphac);
976 //============= CLIP IT =====================
978 x0 = va->sx; y0 = va->sy;
979 x1 = vb->sx; y1 = vb->sy;
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);
984 u0 = va->u; v0 = va->v;
985 u1 = vb->u; v1 = vb->v;
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;
992 clipped_u0 = u0; clipped_v0 = v0;
993 clipped_u1 = u1; clipped_v1 = v1;
995 clipped_x0 = x0; clipped_y0 = y0;
996 clipped_x1 = x1; clipped_y1 = y1;
998 // Clip the left, moving u0 right as necessary
1000 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1004 // Clip the right, moving u1 left as necessary
1006 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1010 // Clip the top, moving v0 down as necessary
1012 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1016 // Clip the bottom, moving v1 up as necessary
1018 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1022 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1023 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1025 if (dx1<=dx0) return;
1026 if (dy1<=dy0) return;
1028 //============= DRAW IT =====================
1031 ubyte * sbits, * dbits;
1036 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
1037 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
1038 return; // scaled up way too far!
1040 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
1041 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
1042 return; // scaled up way too far!
1045 bp = bm_lock( gr_screen.current_bitmap, 8, BMP_AABITMAP );
1047 du = fl2f(tmpu*(bp->w-1));
1048 dv = fl2f(tmpv*(bp->h-1));
1050 v = fl2f(clipped_v0*(bp->h-1));
1051 u = fl2f(clipped_u0*(bp->w-1));
1054 #ifdef USE_COMPILED_CODE
1057 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1058 //cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
1060 cc = scaler_create_compiled_code8_alpha( w, u, du );
1065 spixels = (ubyte *)bp->data;
1070 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1071 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
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];
1080 #ifdef USE_COMPILED_CODE
1081 // Call the compiled code to draw one scanline
1082 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1086 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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;
1107 _asm mov ecx, lookup
1120 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1124 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
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];
1138 for (x=0; x<w; x++ ) {
1139 uint c = sbits[ tmp_u >> 16 ];
1140 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1151 bm_unlock(gr_screen.current_bitmap);