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.3 2002/06/09 04:41:18 relnev
19 * added copyright header
21 * Revision 1.2 2002/06/05 08:05:29 relnev
22 * stub/warning removal.
24 * reworked the sound code.
26 * Revision 1.1.1.1 2002/05/03 03:28:09 root
30 * 9 7/20/99 1:49p Dave
31 * Peter Drake build. Fixed some release build warnings.
33 * 8 6/22/99 7:03p Dave
34 * New detail options screen.
36 * 7 5/12/99 5:33p Johne
37 * Don't use gr8_scaler() in pofview.
39 * 6 5/09/99 6:00p Dave
40 * Lots of cool new effects. E3 build tweaks.
42 * 5 1/14/99 6:06p Dave
43 * 100% full squad logo support for single player and multiplayer.
45 * 4 1/14/99 12:48a Dave
46 * Todo list bug fixes. Made a pass at putting briefing icons back into
47 * FRED. Sort of works :(
49 * 3 11/30/98 1:07p Dave
50 * 16 bit conversion, first run.
52 * 2 10/07/98 10:53a Dave
55 * 1 10/07/98 10:49a Dave
57 * 40 4/02/98 2:01p Dave
58 * JAS: Increased constant for source of compiled code
60 * 39 4/01/98 9:21p John
61 * Made NDEBUG, optimized build with no warnings or errors.
63 * 38 4/01/98 7:15p John
64 * fixed bug with previous
66 * 37 4/01/98 6:45p John
67 * Reduced memory by combining compled_code ptrs.
69 * 36 3/22/98 3:28p John
70 * Added in stippled alpha for lower details. Made medium detail use
73 * 35 3/10/98 4:18p John
74 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
75 * & Glide have popups and print screen. Took out all >8bpp software
76 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
77 * support Fred. Made zbuffering key off of functions rather than one
80 * 34 2/05/98 9:21p John
81 * Some new Direct3D code. Added code to monitor a ton of stuff in the
84 * 33 1/27/98 10:18a John
85 * fixed warning for optimized build
87 * 32 1/26/98 5:12p John
88 * Added in code for Pentium Pro specific optimizations. Speed up
89 * zbuffered correct tmapper about 35%. Speed up non-zbuffered scalers
92 * 31 1/19/98 6:15p John
93 * Fixed all my Optimized Build compiler warnings
95 * 30 12/04/97 12:09p John
96 * Made glows use scaler instead of tmapper so they don't rotate. Had to
97 * add a zbuffered scaler.
99 * 29 12/02/97 4:00p John
100 * Added first rev of thruster glow, along with variable levels of
101 * translucency, which retquired some restructing of palman.
103 * 28 11/30/97 4:33p John
104 * added 32-bpp aascaler
106 * 27 11/30/97 3:57p John
107 * Made fixed 32-bpp translucency. Made BmpMan always map translucent
108 * color into 255 even if you aren't supposed to remap and make it's
111 * 26 11/30/97 12:18p John
112 * added more 24 & 32-bpp primitives
114 * 25 11/29/97 2:06p John
115 * added mode 16-bpp support
117 * 24 11/14/97 12:30p John
118 * Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
119 * libs. Made 16-bpp DirectX modes know what bitmap format they're in.
121 * 23 10/19/97 12:55p John
122 * new code to lock / unlock surfaces for smooth directx integration.
124 * 22 10/15/97 4:48p John
125 * added 16-bpp aascaler
127 * 21 10/14/97 8:08a John
128 * added a bunch more 16 bit support
130 * 20 10/09/97 5:23p John
131 * Added support for more 16-bpp functions
133 * 19 8/04/97 4:47p John
136 * 18 7/28/97 11:31a John
137 * made compiled code save all registers that it changes. When building
138 * optimized, my code was using EBX, and so was the compiler, so weird
139 * errors happened. Pushing/popping ebx fixed this.
141 * 17 7/16/97 5:29p John
142 * added palette table caching and made scaler and liner no light tmapper
143 * do alpha blending in 8 bpp mode.
145 * 16 7/10/97 2:06p John
146 * added code to specify alphablending type for bitmaps.
148 * 15 6/12/97 2:50a Lawrance
149 * bm_unlock() now passed bitmap number, not pointer
151 * 14 5/29/97 3:10p John
152 * Took out debug menu.
153 * Made software scaler draw larger bitmaps.
154 * Optimized Direct3D some.
156 * 13 5/12/97 12:27p John
157 * Restructured Graphics Library to add support for multiple renderers.
159 * 12 12/04/96 2:02p John
160 * Added fast compiled code to the scaler in 8,16,32 bpp modes.
162 * 11 12/03/96 8:08p John
163 * Added compiled code to 8bpp scaler. Made bitmaps that are trying to
164 * scale up too big to not draw.
166 * 10 12/03/96 11:12a John
167 * added commented out "filtering" code to scaler.
169 * 9 11/19/96 2:42p Allender
170 * fix up 32 bit scaler
172 * 8 11/15/96 11:27a Allender
173 * 16bpp version of scaler
175 * 7 11/07/96 6:19p John
176 * Added a bunch of 16bpp primitives so the game sort of runs in 16bpp
179 * 6 10/26/96 1:40p John
180 * Added some now primitives to the 2d library and
181 * cleaned up some old ones.
196 #include "grinternal.h"
197 #include "floating.h"
200 #include "tmapscanline.h"
201 #include "systemvars.h"
205 #define MIN_SCALE_FACTOR 0.0001f
207 #define USE_COMPILED_CODE
209 #define TRANSPARENCY_COLOR_8 0xff
210 #define TRANSPARENCY_COLOR_16 0xffff
211 #define TRANSPARENCY_COLOR_32 0xffffffff
213 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
215 #define MAX_CODE_SIZE 32768 //65536 JAS: Determed to be 8208 on April1,98, 16K seems safe
217 ubyte compiled_code[MAX_CODE_SIZE];
220 static int Max_size = 0;
226 _asm mov ax, [esi+0xabcdef12]
229 _asm mov [edi+0xabcdef12], ax
230 _asm mov ax, [esi+0xabcdef12]
236 //----------------------------------------------------
237 // scaler_create_compiled_code8
239 // Creates code that looks like:
241 // @@: mov al, [esi+????]
242 // cmp al, TRANSPARENCY_COLOR_8
243 // je @f ; jump to next @@ label
244 // mov [edi+???], al ; If the source pixel is scaled up
245 // mov [edi+???], al ; there might be a lot of these lines
247 // @@: mov al, [esi+????]
250 ubyte *scaler_create_compiled_code8( int w, fix u, fix du )
258 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
260 // *cc++ = 0xCC; // Int3
261 // *cc++ = 0xc3; // RET
267 for (x=0; x<w; x++ ) {
268 if ( last_u != f2i(u) ) {
269 if ( last_jmp_pos ) {
270 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
272 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
273 *(uint *)cc = f2i(u); cc += 4;
276 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
277 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
278 last_jmp_pos = (uint *)cc;
283 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
284 *(uint *)cc = x; cc += 4;
288 if ( last_jmp_pos ) {
289 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
293 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
294 Int3(); // GET JOHN NOW!
297 int size = cc - compiled_code;
298 if ( size > Max_size ) {
300 mprintf(( "Max size = %d\n", size ));
304 return compiled_code;
307 ubyte *scaler_create_compiled_code8_stippled( int w, fix u, fix du )
315 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
317 // *cc++ = 0xCC; // Int3
318 // *cc++ = 0xc3; // RET
324 for (x=0; x<w-1; x+=2 ) {
325 if ( last_u != f2i(u) ) {
326 if ( last_jmp_pos ) {
327 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
329 *cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
330 *(uint *)cc = f2i(u); cc += 4;
333 *cc++ = 0x3c; *cc++ = TRANSPARENCY_COLOR_8; // cmp al, 255
334 *cc++ = 0x0f; *cc++ = 0x84; // je rel32
335 last_jmp_pos = (uint *)cc;
340 *cc++ = 0x88; *cc++ = 0x87; // mov [edi+imm], al
341 *(uint *)cc = x; cc += 4;
345 if ( last_jmp_pos ) {
346 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
350 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
351 Int3(); // GET JOHN NOW!
354 int size = cc - compiled_code;
355 if ( size > Max_size ) {
357 mprintf(( "Max size = %d\n", size ));
361 return compiled_code;
372 _asm mov bl, BYTE PTR [edi-1412567278]
374 _asm mov ebx, [ecx+ebx] ; blend it
379 // xor eax, eax ; avoid ppro partial register stall
380 // mov ah, [esi+????] ; get the foreground pixel
381 // ; the following lines might be repeated
382 // xor ebx, ebx ; avoid ppro partial register stall
383 // mov bl, [edi+????] ; get the background pixel
384 // mov ebx, [ecx+ebx] ; blend it
385 // mov [edi+????], bl ; write it
390 00130 b8 00 00 00 00 mov eax, 0
391 00135 8a a6 12 ef cd ab mov ah, BYTE PTR [esi-1412567278]
392 0013b 8a 87 12 ef cd ab mov al, BYTE PTR [edi-1412567278]
393 00141 8a 1c 01 mov bl, BYTE PTR [ecx+eax]
394 00141 8b 1c 01 mov ebx, DWORD PTR [ecx+eax]
395 00144 88 9f 12 ef cd ab mov BYTE PTR [edi-1412567278], bl
398 00130 33 c0 xor eax, eax
399 00132 33 db xor ebx, ebx
400 00134 8a 9f 12 ef cd ab mov bl, BYTE PTR [edi-1412567278]
401 0013a 03 d8 add ebx, eax
402 0013c 8b 1c 19 mov ebx, DWORD PTR [ecx+ebx]
404 0013f 3b 2a cmp ebp, DWORD PTR [edx]
405 00141 83 c2 04 add edx, 4
410 //----------------------------------------------------
411 // scaler_create_compiled_code8_alpha
413 // Creates code that looks like:
415 //=============== Pentium ======================
417 // mov ah, [esi+????] ; get the foreground pixel
418 // ; the following lines might be repeated
419 // mov al, [edi+????] ; get the background pixel
420 // mov bl, [ecx+eax] ; blend it
421 // mov [edi+????], bl ; write it
424 //============= Pentium Pro code =============
425 // xor eax, eax ; avoid ppro partial register stall
426 // mov ah, [esi+????] ; get the foreground pixel
427 // ; the following lines might be repeated
428 // xor ebx, ebx ; avoid ppro partial register stall
429 // mov bl, [edi+????] ; get the background pixel
430 // mov ebx, [ecx+ebx] ; blend it
431 // mov [edi+????], bl ; write it
434 ubyte *scaler_create_compiled_code8_alpha( int w, fix u, fix du )
441 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
443 //*cc++ = 0xCC; // Int3
444 //*cc++ = 0xc3; // RET
449 // Pentium Pro optimized code.
451 for (x=0; x<w; x++ ) {
452 if ( last_u != f2i(u) ) {
453 *cc++ = 0x33; *cc++ = 0xc0; // xor eax, eax
454 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
455 //*cc++ = 0x8a; *cc++ = 0x86; // mov al, [esi+imm]
456 *(uint *)cc = f2i(u); cc += 4;
460 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
462 *cc++ = 0x8a; *cc++ = 0x9f;
463 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
465 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
467 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
469 *cc++ = 0x88; *cc++ = 0x9f;
470 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
475 // Pentium optimized code.
477 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
479 for (x=0; x<w; x++ ) {
480 if ( last_u != f2i(u) ) {
481 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
482 *(uint *)cc = f2i(u); cc += 4;
486 *cc++ = 0x8a; *cc++ = 0x87;
487 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
489 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
491 *cc++ = 0x88; *cc++ = 0x9f;
492 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
500 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
501 Int3(); // GET JOHN NOW!
504 int size = cc - compiled_code;
505 if ( size > Max_size ) {
507 mprintf(( "Max size = %d\n", size ));
511 return compiled_code;
515 for (x=0; x<w; x++ ) {
516 if ( fx_w > *zbuf ) {
517 uint c = sbits[ tmp_u >> 16 ]<<8;
518 *dbits = *((ubyte *)(lookup + (*dbits | c)));
526 //----------------------------------------------------
527 // scaler_create_compiled_code8_alpha_zbuffered
529 // Creates code that looks like:
531 // mov ah, [esi+????] ; get the foreground pixel
532 // ; the following lines might be repeated
533 // cmp fx_w, [edx+?????]
535 // mov al, [edi+????] ; get the background pixel
536 // mov bl, [ecx+eax] ; blend it
537 // mov [edi+????], bl ; write it
546 // _asm cmp 0xFFFFFFFF, [edx+0xabcdef12]
547 // _asm cmp ebp, [edx+0xabcdef12]
548 // _asm jle 0xabcdef12
550 //; 302 : _asm cmp ebp, [edx+0xabcdef12]
551 // 00244 3b aa 12 ef cd ab cmp ebp, DWORD PTR [edx-1412567278]
552 //; 303 : _asm jle 0xabcdef12
553 // 0024a 0f 8e 12 ef cd ab jle -1412567278 ; abcdef12H
555 ubyte *scaler_create_compiled_code8_alpha_zbuffered( int w, fix u, fix du )
559 uint *last_jmp_pos=NULL;
563 // xor eax, eax ; avoid ppro partial register stall
564 // mov ah, [esi+????] ; get the foreground pixel
565 // ; the following lines might be repeated
566 // xor ebx, ebx ; avoid ppro partial register stall
567 // mov bl, [edi+????] ; get the background pixel
568 // mov ebx, [ecx+ebx] ; blend it
569 // mov [edi+????], bl ; write it
571 //if ( abs(du) < F1_0 / 4 ) *cc++ = 0xCC;
573 //*cc++ = 0xCC; // Int3
574 //*cc++ = 0xc3; // RET
578 // Pentium Pro optimized code.
580 for (x=0; x<w; x++ ) {
581 if ( last_u != f2i(u) ) {
582 *cc++ = 0x33; *cc++ = 0xc0; // xor eax, eax
583 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
584 *(uint *)cc = f2i(u); cc += 4;
588 *cc++ = 0x3b; *cc++ = 0xaa;
589 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
591 // *cc++ = 0x3b; *cc++ = 0x2a; // cmp ebp, [edx]
592 // *cc++ = 0x83; *cc++ = 0xc2; *cc++ = 0x4; // add edx, 4
594 *cc++ = 0x0f; *cc++ = 0x8e; // jle (8e) imm
595 last_jmp_pos = (uint *)cc;
596 *(uint *)cc = 0; cc += 4;
598 *cc++ = 0x33; *cc++ = 0xdb; // xor ebx, ebx
600 *cc++ = 0x8a; *cc++ = 0x9f;
601 *(uint *)cc = x; cc += 4; // mov bl, [edi+imm]
603 *cc++ = 0x03; *cc++ = 0xd8; // add ebx, eax
605 *cc++ = 0x8b; *cc++ = 0x1c; *cc++ = 0x19; // mov ebx, BYTE PTR [ecx+ebx]
607 *cc++ = 0x88; *cc++ = 0x9f;
608 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
610 if ( last_jmp_pos ) {
611 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
620 // Pentium optimized code.
622 *cc++ = 0xb8; *(uint *)cc = 0; cc += 4; // mov eax, 0
624 for (x=0; x<w; x++ ) {
625 if ( last_u != f2i(u) ) {
626 *cc++ = 0x8a; *cc++ = 0xa6; // mov ah, [esi+imm]
627 *(uint *)cc = f2i(u); cc += 4;
631 *cc++ = 0x3b; *cc++ = 0xaa;
632 *(uint *)cc = x*4; cc += 4; // cmp ebp, [edx+imm]
634 *cc++ = 0x0f; *cc++ = 0x8e; // jle imm
635 last_jmp_pos = (uint *)cc;
636 *(uint *)cc = 0; cc += 4;
638 *cc++ = 0x8a; *cc++ = 0x87;
639 *(uint *)cc = x; cc += 4; // mov al, [edi+imm]
641 *cc++ = 0x8a; *cc++ = 0x1c; *cc++ = 0x01; // mov bl, BYTE PTR [ecx+eax]
643 *cc++ = 0x88; *cc++ = 0x9f;
644 *(uint *)cc = x; cc += 4; // mov [edi+imm], bl
646 if ( last_jmp_pos ) {
647 *last_jmp_pos = (uint)cc - (uint)last_jmp_pos - 4;
656 if ( cc >= &compiled_code[MAX_CODE_SIZE] )
657 Int3(); // GET JOHN NOW!
660 int size = cc - compiled_code;
661 if ( size > Max_size ) {
663 mprintf(( "Max sizeZ = %d\n", size ));
667 return compiled_code;
672 int Gr_scaler_zbuffering = 0;
675 MONITOR( ScalerNumCalls );
678 //----------------------------------------------------
679 // Scales current bitmap, between va and vb
680 void gr8_scaler(vertex *va, vertex *vb )
687 float x0, y0, x1, y1;
688 float u0, v0, u1, v1;
689 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
690 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
691 float xmin, xmax, ymin, ymax;
692 int dx0, dy0, dx1, dy1;
694 MONITOR_INC( ScalerNumCalls, 1 );
696 //============= CLIP IT =====================
698 x0 = va->sx; y0 = va->sy;
699 x1 = vb->sx; y1 = vb->sy;
701 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
702 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
704 u0 = va->u; v0 = va->v;
705 u1 = vb->u; v1 = vb->v;
707 // Check for obviously offscreen bitmaps...
708 if ( (y1<=y0) || (x1<=x0) ) return;
709 if ( (x1<xmin ) || (x0>xmax) ) return;
710 if ( (y1<ymin ) || (y0>ymax) ) return;
712 clipped_u0 = u0; clipped_v0 = v0;
713 clipped_u1 = u1; clipped_v1 = v1;
715 clipped_x0 = x0; clipped_y0 = y0;
716 clipped_x1 = x1; clipped_y1 = y1;
718 // Clip the left, moving u0 right as necessary
720 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
724 // Clip the right, moving u1 left as necessary
726 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
730 // Clip the top, moving v0 down as necessary
732 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
736 // Clip the bottom, moving v1 up as necessary
738 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
742 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
743 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
745 if (dx1<=dx0) return;
746 if (dy1<=dy0) return;
748 //============= DRAW IT =====================
751 ubyte * sbits, * dbits;
756 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
757 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
758 return; // scaled up way too far!
760 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
761 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
762 return; // scaled up way too far!
768 if ( !Detail.alpha_effects ) {
770 Gr_scaler_zbuffering = 0;
775 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
777 bp = bm_lock( gr_screen.current_bitmap, 8, 0 );
781 du = fl2f(tmpu*(bp->w-1));
782 dv = fl2f(tmpv*(bp->h-1));
784 v = fl2f(clipped_v0*(bp->h-1));
785 u = fl2f(clipped_u0*(bp->w-1));
788 bm_unlock(gr_screen.current_bitmap);
793 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
794 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
798 #ifdef USE_COMPILED_CODE
801 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
802 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
803 cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
806 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
808 cc = scaler_create_compiled_code8_stippled( w, u, du );
810 cc = scaler_create_compiled_code8_alpha( w, u, du );
813 cc = scaler_create_compiled_code8( w, u, du );
819 spixels = (ubyte *)bp->data;
822 Tmap.pScreenBits = (uint)gr_screen.offscreen_buffer_base;
826 for (y=dy0; y<=dy1; v += dv, y++ ) {
827 if ( is_stippled && (y&1) ) {
828 sbits = &spixels[bp->rowsize*(v>>16)+f2i(du)];
829 dbits = GR_SCREEN_PTR(ubyte,dx0+1,y);
831 sbits = &spixels[bp->rowsize*(v>>16)];
832 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
836 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
837 lookup = (uint)palette_get_blend_table(gr_screen.current_alpha);
840 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
841 zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
844 #ifdef USE_COMPILED_CODE
845 // Call the compiled code to draw one scanline
846 if ( Gr_scaler_zbuffering && gr_zbuffering && (gr_screen.current_alphablend_mode != GR_ALPHABLEND_FILTER)) {
853 for (x=0; x<w; x++ ) {
854 if ( fx_w > *zbuf ) {
855 ubyte c = sbits[ tmp_u >> 16 ];
856 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
869 for (x=0; x<w; x++ ) {
870 if ( fx_w > *zbuf ) {
871 uint c = sbits[ tmp_u >> 16 ]<<8;
872 *dbits = *((ubyte *)(lookup + (*dbits | c)));
895 _asm mov ebp, Gr_global_z
907 if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) {
908 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
912 for (x=0; x<w; x++ ) {
913 if ( fx_w > *zbuf ) {
914 uint c = sbits[ tmp_u >> 16 ]<<8;
915 *dbits = *((ubyte *)(lookup + (*dbits | c)));
924 for (x=0; x<w; x++ ) {
925 uint c = sbits[ tmp_u >> 16 ]<<8;
926 *dbits++ = palette_blend[*dbits|c];
931 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
935 for (x=0; x<w; x++ ) {
936 if ( fx_w > *zbuf ) {
937 ubyte c = sbits[ tmp_u >> 16 ];
938 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
947 for (x=0; x<w; x++ ) {
948 ubyte c = sbits[ tmp_u >> 16 ];
949 if ( c != TRANSPARENCY_COLOR_8 ) *dbits = c;
959 bm_unlock(gr_screen.current_bitmap);
964 alphacolor_old old_alphac;
965 //----------------------------------------------------
966 // Scales current bitmap, between va and vb
967 void gr8_aascaler(vertex *va, vertex *vb )
969 float x0, y0, x1, y1;
970 float u0, v0, u1, v1;
971 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
972 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
973 float xmin, xmax, ymin, ymax;
974 int dx0, dy0, dx1, dy1;
976 //if ( !Current_alphacolor ) return;
978 MONITOR_INC( ScalerNumCalls, 1 );
980 Assert(Fred_running);
986 old_alphac.alpha = 255;
990 calc_alphacolor_old(&old_alphac);
994 //============= CLIP IT =====================
996 x0 = va->sx; y0 = va->sy;
997 x1 = vb->sx; y1 = vb->sy;
999 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
1000 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
1002 u0 = va->u; v0 = va->v;
1003 u1 = vb->u; v1 = vb->v;
1005 // Check for obviously offscreen bitmaps...
1006 if ( (y1<=y0) || (x1<=x0) ) return;
1007 if ( (x1<xmin ) || (x0>xmax) ) return;
1008 if ( (y1<ymin ) || (y0>ymax) ) return;
1010 clipped_u0 = u0; clipped_v0 = v0;
1011 clipped_u1 = u1; clipped_v1 = v1;
1013 clipped_x0 = x0; clipped_y0 = y0;
1014 clipped_x1 = x1; clipped_y1 = y1;
1016 // Clip the left, moving u0 right as necessary
1018 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
1022 // Clip the right, moving u1 left as necessary
1024 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
1028 // Clip the top, moving v0 down as necessary
1030 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
1034 // Clip the bottom, moving v1 up as necessary
1036 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
1040 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
1041 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
1043 if (dx1<=dx0) return;
1044 if (dy1<=dy0) return;
1046 //============= DRAW IT =====================
1049 ubyte * sbits, * dbits;
1054 tmpu = (clipped_u1-clipped_u0) / (dx1-dx0);
1055 if ( fl_abs(tmpu) < MIN_SCALE_FACTOR ) {
1056 return; // scaled up way too far!
1058 tmpv = (clipped_v1-clipped_v0) / (dy1-dy0);
1059 if ( fl_abs(tmpv) < MIN_SCALE_FACTOR ) {
1060 return; // scaled up way too far!
1063 bp = bm_lock( gr_screen.current_bitmap, 8, BMP_AABITMAP );
1065 du = fl2f(tmpu*(bp->w-1));
1066 dv = fl2f(tmpv*(bp->h-1));
1068 v = fl2f(clipped_v0*(bp->h-1));
1069 u = fl2f(clipped_u0*(bp->w-1));
1072 #ifdef USE_COMPILED_CODE
1075 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1076 //cc = scaler_create_compiled_code8_alpha_zbuffered( w, u, du );
1078 cc = scaler_create_compiled_code8_alpha( w, u, du );
1083 spixels = (ubyte *)bp->data;
1088 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1089 fx_w = (uint)fl2i(va->sw * GR_Z_RANGE)+gr_zoffset;
1092 for (y=dy0; y<=dy1; y++ ) {
1093 sbits = &spixels[bp->rowsize*(v>>16)];
1094 dbits = GR_SCREEN_PTR(ubyte,dx0,y);
1096 #ifdef USE_COMPILED_CODE
1097 // uint lookup = (uint)&Current_alphacolor->table.lookup[0][0];
1098 uint lookup = (uint)&old_alphac.table.lookup[0][0];
1100 // Call the compiled code to draw one scanline
1101 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1105 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1107 for (x=0; x<w; x++ ) {
1108 if ( fx_w > *zbuf ) {
1109 // uint c = sbits[ tmp_u >> 16 ];
1110 // *dbits = Current_alphacolor->table.lookup[c][*dbits];
1111 *dbits = (ubyte)0x00;
1126 _asm mov ecx, lookup
1139 if ( Gr_scaler_zbuffering && gr_zbuffering ) {
1143 uint *zbuf = (uint *)&gr_zbuffer[(uint)dbits-(uint)Tmap.pScreenBits];
1145 for (x=0; x<w; x++ ) {
1146 if ( fx_w > *zbuf ) {
1147 uint c = sbits[ tmp_u >> 16 ];
1148 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1157 for (x=0; x<w; x++ ) {
1158 uint c = sbits[ tmp_u >> 16 ];
1159 *dbits = Current_alphacolor->table.lookup[c][*dbits];
1170 bm_unlock(gr_screen.current_bitmap);