DrawMisc.cpp (153833B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* 17 ** 18 ** 19 ** Misc asm functions from ww lib 20 ** ST - 12/19/2018 1:20PM 21 ** 22 ** 23 ** 24 ** 25 ** 26 ** 27 ** 28 ** 29 ** 30 ** 31 ** 32 */ 33 34 #include "gbuffer.h" 35 #include "MISC.H" 36 37 IconCacheClass::IconCacheClass (void) 38 { 39 IsCached =FALSE; 40 SurfaceLost =FALSE; 41 DrawFrequency =0; 42 CacheSurface =NULL; 43 IconSource =NULL; 44 } 45 46 IconCacheClass::~IconCacheClass (void) 47 { 48 } 49 50 IconCacheClass CachedIcons[MAX_CACHED_ICONS]; 51 52 extern "C"{ 53 IconSetType IconSetList[MAX_ICON_SETS]; 54 short IconCacheLookup[MAX_LOOKUP_ENTRIES]; 55 } 56 57 int CachedIconsDrawn=0; //Counter of number of cache hits 58 int UnCachedIconsDrawn=0; //Counter of number of cache misses 59 BOOL CacheMemoryExhausted; //Flag set if we have run out of video RAM 60 61 62 void Invalidate_Cached_Icons (void) {} 63 void Restore_Cached_Icons (void) {} 64 void Register_Icon_Set (void *icon_data , BOOL pre_cache) {}; 65 66 // 67 // Prototypes for assembly language procedures in STMPCACH.ASM 68 // 69 extern "C" void __cdecl Clear_Icon_Pointers (void) {}; 70 extern "C" void __cdecl Cache_Copy_Icon (void const *icon_ptr ,void * , int) {}; 71 extern "C" int __cdecl Is_Icon_Cached (void const *icon_data , int icon) {return -1;}; 72 extern "C" int __cdecl Get_Icon_Index (void *icon_ptr) {return 0;}; 73 extern "C" int __cdecl Get_Free_Index (void) {return 0;}; 74 extern "C" BOOL __cdecl Cache_New_Icon (int icon_index, void *icon_ptr) {return -1;}; 75 extern "C" int __cdecl Get_Free_Cache_Slot(void) {return -1;} 76 77 void IconCacheClass::Draw_It (LPDIRECTDRAWSURFACE dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height) {} 78 79 80 81 extern int CachedIconsDrawn; 82 extern int UnCachedIconsDrawn; 83 84 85 extern "C" void __cdecl Set_Font_Palette_Range(void const *palette, INT start_idx, INT end_idx) 86 { 87 } 88 89 90 /* 91 ;*************************************************************************** 92 ;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport * 93 ;* * 94 ;* INPUT: WORD sx_pixel - the starting x pixel position * 95 ;* WORD sy_pixel - the starting y pixel position * 96 ;* WORD dx_pixel - the destination x pixel position * 97 ;* WORD dy_pixel - the destination y pixel position * 98 ;* WORD color - the color of the line to draw * 99 ;* * 100 ;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel * 101 ;* with the graphic viewport it has been assigned to. * 102 ;* * 103 ;* HISTORY: * 104 ;* 06/16/1994 PWG : Created. * 105 ;* 08/30/1994 IML : Fixed clipping bug. * 106 ;*=========================================================================* 107 PROC Buffer_Draw_Line C NEAR 108 USES eax,ebx,ecx,edx,esi,edi 109 */ 110 111 void __cdecl Buffer_Draw_Line(void *this_object, int sx, int sy, int dx, int dy, unsigned char color) 112 { 113 unsigned int clip_min_x; 114 unsigned int clip_max_x; 115 unsigned int clip_min_y; 116 unsigned int clip_max_y; 117 unsigned int clip_var; 118 unsigned int accum; 119 unsigned int bpr; 120 121 static int _one_time_init = 0; 122 123 //clip_tbl DD nada,a_up,a_dwn,nada 124 // DD a_lft,a_lft,a_dwn,nada 125 // DD a_rgt,a_up,a_rgt,nada 126 // DD nada,nada,nada,nada 127 128 static void *_clip_table [4*4] = {0}; 129 130 unsigned int int_color = color; 131 unsigned int x1_pixel = (unsigned int) sx; 132 unsigned int y1_pixel = (unsigned int) sy; 133 unsigned int x2_pixel = (unsigned int) dx; 134 unsigned int y2_pixel = (unsigned int) dy; 135 136 __asm { 137 mov eax,_one_time_init 138 and eax,eax 139 jnz init_done 140 141 call do_init 142 143 init_done: 144 145 //;*================================================================== 146 //;* Take care of find the clip minimum and maximums 147 //;*================================================================== 148 mov ebx,[this_object] 149 xor eax,eax 150 mov [clip_min_x],eax 151 mov [clip_min_y],eax 152 mov eax,[ebx]GraphicViewPortClass.Width 153 mov [clip_max_x],eax 154 add eax,[ebx]GraphicViewPortClass.XAdd 155 add eax,[ebx]GraphicViewPortClass.Pitch 156 mov [bpr],eax 157 mov eax,[ebx]GraphicViewPortClass.Height 158 mov [clip_max_y],eax 159 160 //;*================================================================== 161 //;* Adjust max pixels as they are tested inclusively. 162 //;*================================================================== 163 dec [clip_max_x] 164 dec [clip_max_y] 165 166 //;*================================================================== 167 //;* Set the registers with the data for drawing the line 168 //;*================================================================== 169 mov eax,[x1_pixel] //; eax = start x pixel position 170 mov ebx,[y1_pixel] //; ebx = start y pixel position 171 mov ecx,[x2_pixel] //; ecx = dest x pixel position 172 mov edx,[y2_pixel] //; edx = dest y pixel position 173 174 //;*================================================================== 175 //;* This is the section that "pushes" the line into bounds. 176 //;* I have marked the section with PORTABLE start and end to signify 177 //;* how much of this routine is 100% portable between graphics modes. 178 //;* It was just as easy to have variables as it would be for constants 179 //;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used 180 //;* to clip the line (default is the screen) 181 //;* PORTABLE start 182 //;*================================================================== 183 184 cmp eax,[clip_min_x] 185 jl short clip_it 186 cmp eax,[clip_max_x] 187 jg short clip_it 188 cmp ebx,[clip_min_y] 189 jl short clip_it 190 cmp ebx,[clip_max_y] 191 jg short clip_it 192 cmp ecx,[clip_min_x] 193 jl short clip_it 194 cmp ecx,[clip_max_x] 195 jg short clip_it 196 cmp edx,[clip_min_y] 197 jl short clip_it 198 cmp edx,[clip_max_y] 199 jle short on_screen 200 201 //;*================================================================== 202 //;* Takes care off clipping the line. 203 //;*================================================================== 204 clip_it: 205 call set_bits 206 xchg eax,ecx 207 xchg ebx,edx 208 mov edi,esi 209 call set_bits 210 mov [clip_var],edi 211 or [clip_var],esi 212 jz short on_screen 213 test edi,esi 214 jne short off_screen 215 shl esi,2 216 //call [clip_tbl+esi] 217 call [_clip_table+esi] 218 jc clip_it 219 xchg eax,ecx 220 xchg ebx,edx 221 shl edi,2 222 //call [clip_tbl+edi] 223 call [_clip_table+edi] 224 jmp clip_it 225 226 on_screen: 227 jmp draw_it 228 229 off_screen: 230 jmp and_out 231 232 //;*================================================================== 233 //;* Jump table for clipping conditions 234 //;*================================================================== 235 //clip_tbl DD nada,a_up,a_dwn,nada 236 // DD a_lft,a_lft,a_dwn,nada 237 // DD a_rgt,a_up,a_rgt,nada 238 // DD nada,nada,nada,nada 239 240 nada: 241 clc 242 ret 243 244 a_up: 245 mov esi,[clip_min_y] 246 call clip_vert 247 stc 248 ret 249 250 a_dwn: 251 mov esi,[clip_max_y] 252 neg esi 253 neg ebx 254 neg edx 255 call clip_vert 256 neg ebx 257 neg edx 258 stc 259 ret 260 261 //;*================================================================== 262 //;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)] 263 //;*================================================================== 264 clip_vert: 265 push edx 266 push eax 267 mov [clip_var],edx //; clip_var = yb 268 sub [clip_var],ebx //; clip_var = (yb-ya) 269 neg eax //; eax=-xa 270 add eax,ecx //; (ebx-xa) 271 mov edx,esi //; edx=miny 272 sub edx,ebx //; edx=(miny-ya) 273 imul edx 274 idiv [clip_var] 275 pop edx 276 add eax,edx 277 pop edx 278 mov ebx,esi 279 ret 280 281 a_lft: 282 mov esi,[clip_min_x] 283 call clip_horiz 284 stc 285 ret 286 287 a_rgt: 288 mov esi,[clip_max_x] 289 neg eax 290 neg ecx 291 neg esi 292 call clip_horiz 293 neg eax 294 neg ecx 295 stc 296 ret 297 298 //;*================================================================== 299 //;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)] 300 //;*================================================================== 301 clip_horiz: 302 push edx 303 mov [clip_var],ecx //; clip_var = xb 304 sub [clip_var],eax //; clip_var = (xb-xa) 305 sub edx,ebx //; edx = (yb-ya) 306 neg eax //; eax = -xa 307 add eax,esi //; eax = (minx-xa) 308 imul edx //; eax = (minx-xa)(yb-ya) 309 idiv [clip_var] //; eax = (minx-xa)(yb-ya)/(xb-xa) 310 add ebx,eax //; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)] 311 pop edx 312 mov eax,esi 313 ret 314 315 //;*================================================================== 316 //;* Sets the condition bits 317 //;*================================================================== 318 set_bits: 319 xor esi,esi 320 cmp ebx,[clip_min_y] //; if y >= top its not up 321 jge short a_not_up 322 or esi,1 323 324 a_not_up: 325 cmp ebx,[clip_max_y] //; if y <= bottom its not down 326 jle short a_not_down 327 or esi,2 328 329 a_not_down: 330 cmp eax,[clip_min_x] //; if x >= left its not left 331 jge short a_not_left 332 or esi,4 333 334 a_not_left: 335 cmp eax,[clip_max_x] //; if x <= right its not right 336 jle short a_not_right 337 or esi,8 338 339 a_not_right: 340 ret 341 342 //;*================================================================== 343 //;* Draw the line to the screen. 344 //;* PORTABLE end 345 //;*================================================================== 346 draw_it: 347 sub edx,ebx //; see if line is being draw down 348 jnz short not_hline //; if not then its not a hline 349 jmp short hline //; do special case h line 350 351 not_hline: 352 jg short down //; if so there is no need to rev it 353 neg edx //; negate for actual pixel length 354 xchg eax,ecx //; swap x's to rev line draw 355 sub ebx,edx //; get old edx 356 357 down: 358 push edx 359 push eax 360 mov eax,[bpr] 361 mul ebx 362 mov ebx,eax 363 mov eax,[this_object] 364 add ebx,[eax]GraphicViewPortClass.Offset 365 pop eax 366 pop edx 367 368 mov esi,1 //; assume a right mover 369 sub ecx,eax //; see if line is right 370 jnz short not_vline //; see if its a vertical line 371 jmp vline 372 373 not_vline: 374 jg short right //; if so, the difference = length 375 376 //left: 377 neg ecx //; else negate for actual pixel length 378 neg esi //; negate counter to move left 379 380 right: 381 cmp ecx,edx //; is it a horiz or vert line 382 jge short horiz //; if ecx > edx then |x|>|y| or horiz 383 384 //vert: 385 xchg ecx,edx //; make ecx greater and edx lesser 386 mov edi,ecx //; set greater 387 mov [accum],ecx //; set accumulator to 1/2 greater 388 shr [accum],1 389 390 //;*================================================================== 391 //;* at this point ... 392 //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; 393 //;* esi=adder; accum=accumulator 394 //;* in a vertical loop the adder is conditional and the inc constant 395 //;*================================================================== 396 //vert_loop: 397 add ebx,eax 398 mov eax,[int_color] 399 400 v_midloop: 401 mov [ebx],al 402 dec ecx 403 jl and_out 404 add ebx,[bpr] 405 sub [accum],edx //; sub the lesser 406 jge v_midloop //; any line could be new 407 add [accum],edi //; add greater for new accum 408 add ebx,esi //; next pixel over 409 jmp v_midloop 410 411 horiz: 412 mov edi,ecx //; set greater 413 mov [accum],ecx //; set accumulator to 1/2 greater 414 shr [accum],1 415 416 //;*================================================================== 417 //;* at this point ... 418 //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; 419 //;* esi=adder; accum=accumulator 420 //;* in a vertical loop the adder is conditional and the inc constant 421 //;*================================================================== 422 //horiz_loop: 423 add ebx,eax 424 mov eax,[int_color] 425 426 h_midloop: 427 mov [ebx],al 428 dec ecx //; dec counter 429 jl and_out //; end of line 430 add ebx,esi 431 sub [accum],edx //; sub the lesser 432 jge h_midloop 433 add [accum],edi //; add greater for new accum 434 add ebx,[bpr] //; goto next line 435 jmp h_midloop 436 437 //;*================================================================== 438 //;* Special case routine for horizontal line draws 439 //;*================================================================== 440 hline: 441 cmp eax,ecx //; make eax < ecx 442 jl short hl_ac 443 xchg eax,ecx 444 445 hl_ac: 446 sub ecx,eax //; get len 447 inc ecx 448 449 push edx 450 push eax 451 mov eax,[bpr] 452 mul ebx 453 mov ebx,eax 454 mov eax,[this_object] 455 add ebx,[eax]GraphicViewPortClass.Offset 456 pop eax 457 pop edx 458 add ebx,eax 459 mov edi,ebx 460 cmp ecx,15 461 jg big_line 462 mov al,[color] 463 rep stosb //; write as many words as possible 464 jmp short and_out //; get outt 465 466 467 big_line: 468 mov al,[color] 469 mov ah,al 470 mov ebx,eax 471 shl eax,16 472 mov ax,bx 473 test edi,3 474 jz aligned 475 mov [edi],al 476 inc edi 477 dec ecx 478 test edi,3 479 jz aligned 480 mov [edi],al 481 inc edi 482 dec ecx 483 test edi,3 484 jz aligned 485 mov [edi],al 486 inc edi 487 dec ecx 488 489 aligned: 490 mov ebx,ecx 491 shr ecx,2 492 rep stosd 493 mov ecx,ebx 494 and ecx,3 495 rep stosb 496 jmp and_out 497 498 499 //;*================================================================== 500 //;* a special case routine for vertical line draws 501 //;*================================================================== 502 vline: 503 mov ecx,edx //; get length of line to draw 504 inc ecx 505 add ebx,eax 506 mov eax,[int_color] 507 508 vl_loop: 509 mov [ebx],al //; store bit 510 add ebx,[bpr] 511 dec ecx 512 jnz vl_loop 513 jmp and_out 514 515 516 do_init: 517 mov edi, offset _clip_table 518 519 lea esi, nada 520 mov [edi], esi 521 mov [edi+12], esi 522 lea esi, a_up 523 mov [edi+4], esi 524 lea esi, a_dwn 525 mov [edi+8], esi 526 527 add edi, 16 528 529 lea esi, a_lft 530 mov [edi], esi 531 mov [edi+4], esi 532 lea esi, a_dwn 533 mov [edi+8], esi 534 lea esi, nada 535 mov [edi+12], esi 536 537 add edi, 16 538 539 lea esi, a_rgt 540 mov [edi], esi 541 mov [edi+8], esi 542 lea esi, a_up 543 mov [edi+4], esi 544 lea esi, nada 545 mov [edi+12], esi 546 547 add edi, 16 548 549 lea esi, nada 550 mov [edi], esi 551 mov [edi+4], esi 552 mov [edi+8], esi 553 mov [edi+12], esi 554 555 mov [_one_time_init], 1 556 ret 557 558 and_out: 559 } 560 } 561 562 563 564 565 566 /* 567 ;*************************************************************************** 568 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 569 ;*************************************************************************** 570 ;* * 571 ;* Project Name : Westwood 32 bit Library * 572 ;* * 573 ;* File Name : DRAWLINE.ASM * 574 ;* * 575 ;* Programmer : Phil W. Gorrow * 576 ;* * 577 ;* Start Date : June 16, 1994 * 578 ;* * 579 ;* Last Update : August 30, 1994 [IML] * 580 ;* * 581 ;*-------------------------------------------------------------------------* 582 ;* Functions: * 583 ;* VVC::Scale -- Scales a virtual viewport to another virtual viewport * 584 ;* Normal_Draw -- jump loc for drawing scaled line of normal pixel * 585 ;* __DRAW_LINE -- Assembly routine to draw a line * 586 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 587 588 IDEAL 589 P386 590 MODEL USE32 FLAT 591 592 INCLUDE ".\drawbuff.inc" 593 INCLUDE ".\gbuffer.inc" 594 595 596 CODESEG 597 */ 598 599 600 /* 601 ;*************************************************************************** 602 ;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport * 603 ;* * 604 ;* INPUT: WORD sx_pixel - the starting x pixel position * 605 ;* WORD sy_pixel - the starting y pixel position * 606 ;* WORD dx_pixel - the destination x pixel position * 607 ;* WORD dy_pixel - the destination y pixel position * 608 ;* WORD color - the color of the line to draw * 609 ;* * 610 ;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel * 611 ;* with the graphic viewport it has been assigned to. * 612 ;* * 613 ;* HISTORY: * 614 ;* 06/16/1994 PWG : Created. * 615 ;* 08/30/1994 IML : Fixed clipping bug. * 616 ;*=========================================================================* 617 PROC Buffer_Draw_Line C NEAR 618 USES eax,ebx,ecx,edx,esi,edi 619 620 ;*================================================================== 621 ;* Define the arguements that the function takes. 622 ;*================================================================== 623 ARG this_object:DWORD ; associated graphic view port 624 ARG x1_pixel:DWORD ; the start x pixel position 625 ARG y1_pixel:DWORD ; the start y pixel position 626 ARG x2_pixel:DWORD ; the dest x pixel position 627 ARG y2_pixel:DWORD ; the dest y pixel position 628 ARG color:DWORD ; the color we are drawing 629 630 ;*================================================================== 631 ;* Define the local variables that we will use on the stack 632 ;*================================================================== 633 LOCAL clip_min_x:DWORD 634 LOCAL clip_max_x:DWORD 635 LOCAL clip_min_y:DWORD 636 LOCAL clip_max_y:DWORD 637 LOCAL clip_var:DWORD 638 LOCAL accum:DWORD 639 LOCAL bpr:DWORD 640 641 ;*================================================================== 642 ;* Take care of find the clip minimum and maximums 643 ;*================================================================== 644 mov ebx,[this_object] 645 xor eax,eax 646 mov [clip_min_x],eax 647 mov [clip_min_y],eax 648 mov eax,[(GraphicViewPort ebx).GVPWidth] 649 mov [clip_max_x],eax 650 add eax,[(GraphicViewPort ebx).GVPXAdd] 651 add eax,[(GraphicViewPort ebx).GVPPitch] 652 mov [bpr],eax 653 mov eax,[(GraphicViewPort ebx).GVPHeight] 654 mov [clip_max_y],eax 655 656 ;*================================================================== 657 ;* Adjust max pixels as they are tested inclusively. 658 ;*================================================================== 659 dec [clip_max_x] 660 dec [clip_max_y] 661 662 ;*================================================================== 663 ;* Set the registers with the data for drawing the line 664 ;*================================================================== 665 mov eax,[x1_pixel] ; eax = start x pixel position 666 mov ebx,[y1_pixel] ; ebx = start y pixel position 667 mov ecx,[x2_pixel] ; ecx = dest x pixel position 668 mov edx,[y2_pixel] ; edx = dest y pixel position 669 670 ;*================================================================== 671 ;* This is the section that "pushes" the line into bounds. 672 ;* I have marked the section with PORTABLE start and end to signify 673 ;* how much of this routine is 100% portable between graphics modes. 674 ;* It was just as easy to have variables as it would be for constants 675 ;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used 676 ;* to clip the line (default is the screen) 677 ;* PORTABLE start 678 ;*================================================================== 679 680 cmp eax,[clip_min_x] 681 jl short ??clip_it 682 cmp eax,[clip_max_x] 683 jg short ??clip_it 684 cmp ebx,[clip_min_y] 685 jl short ??clip_it 686 cmp ebx,[clip_max_y] 687 jg short ??clip_it 688 cmp ecx,[clip_min_x] 689 jl short ??clip_it 690 cmp ecx,[clip_max_x] 691 jg short ??clip_it 692 cmp edx,[clip_min_y] 693 jl short ??clip_it 694 cmp edx,[clip_max_y] 695 jle short ??on_screen 696 697 ;*================================================================== 698 ;* Takes care off clipping the line. 699 ;*================================================================== 700 ??clip_it: 701 call NEAR PTR ??set_bits 702 xchg eax,ecx 703 xchg ebx,edx 704 mov edi,esi 705 call NEAR PTR ??set_bits 706 mov [clip_var],edi 707 or [clip_var],esi 708 jz short ??on_screen 709 test edi,esi 710 jne short ??off_screen 711 shl esi,2 712 call [DWORD PTR cs:??clip_tbl+esi] 713 jc ??clip_it 714 xchg eax,ecx 715 xchg ebx,edx 716 shl edi,2 717 call [DWORD PTR cs:??clip_tbl+edi] 718 jmp ??clip_it 719 720 ??on_screen: 721 jmp ??draw_it 722 723 ??off_screen: 724 jmp ??out 725 726 ;*================================================================== 727 ;* Jump table for clipping conditions 728 ;*================================================================== 729 ??clip_tbl DD ??nada,??a_up,??a_dwn,??nada 730 DD ??a_lft,??a_lft,??a_dwn,??nada 731 DD ??a_rgt,??a_up,??a_rgt,??nada 732 DD ??nada,??nada,??nada,??nada 733 734 ??nada: 735 clc 736 retn 737 738 ??a_up: 739 mov esi,[clip_min_y] 740 call NEAR PTR ??clip_vert 741 stc 742 retn 743 744 ??a_dwn: 745 mov esi,[clip_max_y] 746 neg esi 747 neg ebx 748 neg edx 749 call NEAR PTR ??clip_vert 750 neg ebx 751 neg edx 752 stc 753 retn 754 755 ;*================================================================== 756 ;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)] 757 ;*================================================================== 758 ??clip_vert: 759 push edx 760 push eax 761 mov [clip_var],edx ; clip_var = yb 762 sub [clip_var],ebx ; clip_var = (yb-ya) 763 neg eax ; eax=-xa 764 add eax,ecx ; (ebx-xa) 765 mov edx,esi ; edx=miny 766 sub edx,ebx ; edx=(miny-ya) 767 imul edx 768 idiv [clip_var] 769 pop edx 770 add eax,edx 771 pop edx 772 mov ebx,esi 773 retn 774 775 ??a_lft: 776 mov esi,[clip_min_x] 777 call NEAR PTR ??clip_horiz 778 stc 779 retn 780 781 ??a_rgt: 782 mov esi,[clip_max_x] 783 neg eax 784 neg ecx 785 neg esi 786 call NEAR PTR ??clip_horiz 787 neg eax 788 neg ecx 789 stc 790 retn 791 792 ;*================================================================== 793 ;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)] 794 ;*================================================================== 795 ??clip_horiz: 796 push edx 797 mov [clip_var],ecx ; clip_var = xb 798 sub [clip_var],eax ; clip_var = (xb-xa) 799 sub edx,ebx ; edx = (yb-ya) 800 neg eax ; eax = -xa 801 add eax,esi ; eax = (minx-xa) 802 imul edx ; eax = (minx-xa)(yb-ya) 803 idiv [clip_var] ; eax = (minx-xa)(yb-ya)/(xb-xa) 804 add ebx,eax ; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)] 805 pop edx 806 mov eax,esi 807 retn 808 809 ;*================================================================== 810 ;* Sets the condition bits 811 ;*================================================================== 812 ??set_bits: 813 xor esi,esi 814 cmp ebx,[clip_min_y] ; if y >= top its not up 815 jge short ??a_not_up 816 or esi,1 817 818 ??a_not_up: 819 cmp ebx,[clip_max_y] ; if y <= bottom its not down 820 jle short ??a_not_down 821 or esi,2 822 823 ??a_not_down: 824 cmp eax,[clip_min_x] ; if x >= left its not left 825 jge short ??a_not_left 826 or esi,4 827 828 ??a_not_left: 829 cmp eax,[clip_max_x] ; if x <= right its not right 830 jle short ??a_not_right 831 or esi,8 832 833 ??a_not_right: 834 retn 835 836 ;*================================================================== 837 ;* Draw the line to the screen. 838 ;* PORTABLE end 839 ;*================================================================== 840 ??draw_it: 841 sub edx,ebx ; see if line is being draw down 842 jnz short ??not_hline ; if not then its not a hline 843 jmp short ??hline ; do special case h line 844 845 ??not_hline: 846 jg short ??down ; if so there is no need to rev it 847 neg edx ; negate for actual pixel length 848 xchg eax,ecx ; swap x's to rev line draw 849 sub ebx,edx ; get old edx 850 851 ??down: 852 push edx 853 push eax 854 mov eax,[bpr] 855 mul ebx 856 mov ebx,eax 857 mov eax,[this_object] 858 add ebx,[(GraphicViewPort eax).GVPOffset] 859 pop eax 860 pop edx 861 862 mov esi,1 ; assume a right mover 863 sub ecx,eax ; see if line is right 864 jnz short ??not_vline ; see if its a vertical line 865 jmp ??vline 866 867 ??not_vline: 868 jg short ??right ; if so, the difference = length 869 870 ??left: 871 neg ecx ; else negate for actual pixel length 872 neg esi ; negate counter to move left 873 874 ??right: 875 cmp ecx,edx ; is it a horiz or vert line 876 jge short ??horiz ; if ecx > edx then |x|>|y| or horiz 877 878 ??vert: 879 xchg ecx,edx ; make ecx greater and edx lesser 880 mov edi,ecx ; set greater 881 mov [accum],ecx ; set accumulator to 1/2 greater 882 shr [accum],1 883 884 ;*================================================================== 885 ;* at this point ... 886 ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; 887 ;* esi=adder; accum=accumulator 888 ;* in a vertical loop the adder is conditional and the inc constant 889 ;*================================================================== 890 ??vert_loop: 891 add ebx,eax 892 mov eax,[color] 893 894 ??v_midloop: 895 mov [ebx],al 896 dec ecx 897 jl ??out 898 add ebx,[bpr] 899 sub [accum],edx ; sub the lesser 900 jge ??v_midloop ; any line could be new 901 add [accum],edi ; add greater for new accum 902 add ebx,esi ; next pixel over 903 jmp ??v_midloop 904 905 ??horiz: 906 mov edi,ecx ; set greater 907 mov [accum],ecx ; set accumulator to 1/2 greater 908 shr [accum],1 909 910 ;*================================================================== 911 ;* at this point ... 912 ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater; 913 ;* esi=adder; accum=accumulator 914 ;* in a vertical loop the adder is conditional and the inc constant 915 ;*================================================================== 916 ??horiz_loop: 917 add ebx,eax 918 mov eax,[color] 919 920 ??h_midloop: 921 mov [ebx],al 922 dec ecx ; dec counter 923 jl ??out ; end of line 924 add ebx,esi 925 sub [accum],edx ; sub the lesser 926 jge ??h_midloop 927 add [accum],edi ; add greater for new accum 928 add ebx,[bpr] ; goto next line 929 jmp ??h_midloop 930 931 ;*================================================================== 932 ;* Special case routine for horizontal line draws 933 ;*================================================================== 934 ??hline: 935 cmp eax,ecx ; make eax < ecx 936 jl short ??hl_ac 937 xchg eax,ecx 938 939 ??hl_ac: 940 sub ecx,eax ; get len 941 inc ecx 942 943 push edx 944 push eax 945 mov eax,[bpr] 946 mul ebx 947 mov ebx,eax 948 mov eax,[this_object] 949 add ebx,[(GraphicViewPort eax).GVPOffset] 950 pop eax 951 pop edx 952 add ebx,eax 953 mov edi,ebx 954 cmp ecx,15 955 jg ??big_line 956 mov al,[byte color] 957 rep stosb ; write as many words as possible 958 jmp short ??out ; get outt 959 960 961 ??big_line: 962 mov al,[byte color] 963 mov ah,al 964 mov ebx,eax 965 shl eax,16 966 mov ax,bx 967 test edi,3 968 jz ??aligned 969 mov [edi],al 970 inc edi 971 dec ecx 972 test edi,3 973 jz ??aligned 974 mov [edi],al 975 inc edi 976 dec ecx 977 test edi,3 978 jz ??aligned 979 mov [edi],al 980 inc edi 981 dec ecx 982 983 ??aligned: 984 mov ebx,ecx 985 shr ecx,2 986 rep stosd 987 mov ecx,ebx 988 and ecx,3 989 rep stosb 990 jmp ??out 991 992 993 ;*================================================================== 994 ;* a special case routine for vertical line draws 995 ;*================================================================== 996 ??vline: 997 mov ecx,edx ; get length of line to draw 998 inc ecx 999 add ebx,eax 1000 mov eax,[color] 1001 1002 ??vl_loop: 1003 mov [ebx],al ; store bit 1004 add ebx,[bpr] 1005 dec ecx 1006 jnz ??vl_loop 1007 1008 ??out: 1009 ret 1010 ENDP Buffer_Draw_Line 1011 1012 1013 */ 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 /* 1030 1031 ;*************************************************************************** 1032 ;* GVPC::FILL_RECT -- Fills a rectangular region of a graphic view port * 1033 ;* * 1034 ;* INPUT: WORD the left hand x pixel position of region * 1035 ;* WORD the upper x pixel position of region * 1036 ;* WORD the right hand x pixel position of region * 1037 ;* WORD the lower x pixel position of region * 1038 ;* UBYTE the color (optional) to clear the view port to * 1039 ;* * 1040 ;* OUTPUT: none * 1041 ;* * 1042 ;* NOTE: This function is optimized to handle viewport with no XAdd * 1043 ;* value. It also handles DWORD aligning the destination * 1044 ;* when speed can be gained by doing it. * 1045 ;* HISTORY: * 1046 ;* 06/07/1994 PWG : Created. * 1047 ;*=========================================================================* 1048 */ 1049 1050 /* 1051 ;****************************************************************************** 1052 ; Much testing was done to determine that only when there are 14 or more bytes 1053 ; being copied does it speed the time it takes to do copies in this algorithm. 1054 ; For this reason and because 1 and 2 byte copies crash, is the special case 1055 ; used. SKB 4/21/94. Tested on 486 66mhz. Copied by PWG 6/7/04. 1056 */ 1057 #define OPTIMAL_BYTE_COPY 14 1058 1059 1060 void __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color) 1061 { 1062 /* 1063 ;*=================================================================== 1064 ;* define the arguements that our function takes. 1065 ;*=================================================================== 1066 ARG this_object:DWORD ; this is a member function 1067 ARG x1_pixel:WORD 1068 ARG y1_pixel:WORD 1069 ARG x2_pixel:WORD 1070 ARG y2_pixel:WORD 1071 ARG color:BYTE ; what color should we clear to 1072 */ 1073 1074 void *this_object = thisptr; 1075 int x1_pixel = sx; 1076 int y1_pixel = sy; 1077 int x2_pixel = dx; 1078 int y2_pixel = dy; 1079 1080 /* 1081 ;*=================================================================== 1082 ; Define some locals so that we can handle things quickly 1083 ;*=================================================================== 1084 LOCAL VPwidth:DWORD ; the width of the viewport 1085 LOCAL VPheight:DWORD ; the height of the viewport 1086 LOCAL VPxadd:DWORD ; the additional x offset of viewport 1087 LOCAL VPbpr:DWORD ; the number of bytes per row of viewport 1088 */ 1089 1090 int VPwidth; 1091 int VPheight; 1092 int VPxadd; 1093 int VPbpr; 1094 1095 int local_ebp; // Can't use ebp 1096 1097 __asm { 1098 1099 ;*=================================================================== 1100 ;* save off the viewport characteristics on the stack 1101 ;*=================================================================== 1102 mov ebx,[this_object] ; get a pointer to viewport 1103 mov eax,[ebx]GraphicViewPortClass.Width ; get width from viewport 1104 mov ecx,[ebx]GraphicViewPortClass.Height ; get height from viewport 1105 mov edx,[ebx]GraphicViewPortClass.XAdd ; get xadd from viewport 1106 add edx,[ebx]GraphicViewPortClass.Pitch ; extra pitch of direct draw surface 1107 mov [VPwidth],eax ; store the width of locally 1108 mov [VPheight],ecx 1109 mov [VPxadd],edx 1110 add eax,edx 1111 mov [VPbpr],eax 1112 1113 ;*=================================================================== 1114 ;* move the important parameters into local registers 1115 ;*=================================================================== 1116 mov eax,[x1_pixel] 1117 mov ebx,[y1_pixel] 1118 mov ecx,[x2_pixel] 1119 mov edx,[y2_pixel] 1120 1121 ;*=================================================================== 1122 ;* Convert the x2 and y2 pixel to a width and height 1123 ;*=================================================================== 1124 cmp eax,ecx 1125 jl no_swap_x 1126 xchg eax,ecx 1127 1128 no_swap_x: 1129 sub ecx,eax 1130 cmp ebx,edx 1131 jl no_swap_y 1132 xchg ebx,edx 1133 no_swap_y: 1134 sub edx,ebx 1135 inc ecx 1136 inc edx 1137 1138 ;*=================================================================== 1139 ;* Bounds check source X. 1140 ;*=================================================================== 1141 cmp eax, [VPwidth] ; compare with the max 1142 jge done ; starts off screen, then later 1143 jb short sx_done ; if it's not negative, it's ok 1144 1145 ;------ Clip source X to left edge of screen. 1146 add ecx, eax ; Reduce width (add in negative src X). 1147 xor eax, eax ; Clip to left of screen. 1148 sx_done: 1149 1150 ;*=================================================================== 1151 ;* Bounds check source Y. 1152 ;*=================================================================== 1153 cmp ebx, [VPheight] ; compare with the max 1154 jge done ; starts off screen, then later 1155 jb short sy_done ; if it's not negative, it's ok 1156 1157 ;------ Clip source Y to top edge of screen. 1158 add edx, ebx ; Reduce height (add in negative src Y). 1159 xor ebx, ebx ; Clip to top of screen. 1160 1161 sy_done: 1162 ;*=================================================================== 1163 ;* Bounds check width versus width of source and dest view ports 1164 ;*=================================================================== 1165 push ebx ; save off ebx for later use 1166 mov ebx,[VPwidth] ; get the source width 1167 sub ebx, eax ; Maximum allowed pixel width (given coordinates). 1168 sub ebx, ecx ; Pixel width undershoot. 1169 jns short width_ok ; if not signed no adjustment necessary 1170 add ecx, ebx ; Reduce width to screen limits. 1171 1172 width_ok: 1173 pop ebx ; restore ebx to old value 1174 1175 ;*=================================================================== 1176 ;* Bounds check height versus height of source view port 1177 ;*=================================================================== 1178 push eax ; save of eax for later use 1179 mov eax, [VPheight] ; get the source height 1180 sub eax, ebx ; Maximum allowed pixel height (given coordinates). 1181 sub eax, edx ; Pixel height undershoot. 1182 jns short height_ok ; if not signed no adjustment necessary 1183 add edx, eax ; Reduce height to screen limits. 1184 height_ok: 1185 pop eax ; restore eax to old value 1186 1187 ;*=================================================================== 1188 ;* Perform the last minute checks on the width and height 1189 ;*=================================================================== 1190 or ecx,ecx 1191 jz done 1192 1193 or edx,edx 1194 jz done 1195 1196 cmp ecx,[VPwidth] 1197 ja done 1198 cmp edx,[VPheight] 1199 ja done 1200 1201 ;*=================================================================== 1202 ;* Get the offset into the virtual viewport. 1203 ;*=================================================================== 1204 xchg edi,eax ; save off the contents of eax 1205 xchg esi,edx ; and edx for size test 1206 mov eax,ebx ; move the y pixel into eax 1207 mul [VPbpr] ; multiply by bytes per row 1208 add edi,eax ; add the result into the x position 1209 mov ebx,[this_object] 1210 add edi,[ebx]GraphicViewPortClass.Offset 1211 1212 mov edx,esi ; restore edx back to real value 1213 mov eax,ecx ; store total width in ecx 1214 sub eax,[VPwidth] ; modify xadd value to include clipped 1215 sub [VPxadd],eax ; width bytes (subtract a negative number) 1216 1217 ;*=================================================================== 1218 ; Convert the color byte to a DWORD for fast storing 1219 ;*=================================================================== 1220 mov al,[color] ; get color to clear to 1221 mov ah,al ; extend across WORD 1222 mov ebx,eax ; extend across DWORD in 1223 shl eax,16 ; several steps 1224 mov ax,bx 1225 1226 ;*=================================================================== 1227 ; If there is no row offset then adjust the width to be the size of 1228 ; the entire viewport and adjust the height to be 1 1229 ;*=================================================================== 1230 mov esi,[VPxadd] 1231 or esi,esi ; set the flags for esi 1232 jnz row_by_row_aligned ; and act on them 1233 1234 xchg eax,ecx ; switch bit pattern and width 1235 mul edx ; multiply by edx to get size 1236 xchg eax,ecx ; switch size and bit pattern 1237 mov edx,1 ; only 1 line off view port size to do 1238 1239 ;*=================================================================== 1240 ; Find out if we should bother to align the row. 1241 ;*=================================================================== 1242 row_by_row_aligned: 1243 mov [local_ebp],ecx ; width saved in ebp 1244 cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them? 1245 jl row_by_row ; if not then skip 1246 1247 ;*=================================================================== 1248 ; Figure out the alignment offset if there is any 1249 ;*=================================================================== 1250 mov ebx,edi ; get output position 1251 and ebx,3 ; is there a remainder? 1252 jz aligned_loop ; if not we are aligned 1253 xor ebx,3 ; find number of align bytes 1254 inc ebx ; this number is off by one 1255 sub [local_ebp],ebx ; subtract from width 1256 1257 ;*=================================================================== 1258 ; Now that we have the alignment offset copy each row 1259 ;*=================================================================== 1260 aligned_loop: 1261 mov ecx,ebx ; get number of bytes to align 1262 rep stosb ; and move them over 1263 mov ecx,[local_ebp] ; get number of aligned bytes 1264 shr ecx,2 ; convert to DWORDS 1265 rep stosd ; and move them over 1266 mov ecx,[local_ebp] ; get number of aligned bytes 1267 and ecx,3 ; find the remainder 1268 rep stosb ; and move it over 1269 add edi,esi ; fix the line offset 1270 dec edx ; decrement the height 1271 jnz aligned_loop ; if more to do than do it 1272 jmp done ; we are all done 1273 1274 ;*=================================================================== 1275 ; If not enough bytes to bother aligning copy each line across a byte 1276 ; at a time. 1277 ;*=================================================================== 1278 row_by_row: 1279 mov ecx,[local_ebp] ; get total width in bytes 1280 rep stosb ; store the width 1281 add edi,esi ; handle the xadd 1282 dec edx ; decrement the height 1283 jnz row_by_row ; if any left then next line 1284 done: 1285 } 1286 } 1287 1288 1289 1290 1291 /* 1292 ;*************************************************************************** 1293 ;* VVPC::CLEAR -- Clears a virtual viewport instance * 1294 ;* * 1295 ;* INPUT: UBYTE the color (optional) to clear the view port to * 1296 ;* * 1297 ;* OUTPUT: none * 1298 ;* * 1299 ;* NOTE: This function is optimized to handle viewport with no XAdd * 1300 ;* value. It also handles DWORD aligning the destination * 1301 ;* when speed can be gained by doing it. * 1302 ;* HISTORY: * 1303 ;* 06/07/1994 PWG : Created. * 1304 ;* 08/23/1994 SKB : Clear the direction flag to always go forward. * 1305 ;*=========================================================================* 1306 */ 1307 void __cdecl Buffer_Clear(void *this_object, unsigned char color) 1308 { 1309 unsigned int local_color = color; 1310 1311 __asm { 1312 1313 cld ; always go forward 1314 1315 mov ebx,[this_object] ; get a pointer to viewport 1316 mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset 1317 mov edx,[ebx]GraphicViewPortClass.Height ; get height from viewport 1318 mov esi,[ebx]GraphicViewPortClass.Width ; get width from viewport 1319 //push [dword (GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface 1320 push [ebx]GraphicViewPortClass.Pitch 1321 1322 mov ebx,[ebx]GraphicViewPortClass.XAdd ; esi = add for each line 1323 add ebx,[esp] ; Yes, I know its nasty but 1324 add esp,4 ; it works! 1325 1326 ;*=================================================================== 1327 ; Convert the color byte to a DWORD for fast storing 1328 ;*=================================================================== 1329 mov al,[color] ; get color to clear to 1330 mov ah,al ; extend across WORD 1331 mov ecx,eax ; extend across DWORD in 1332 shl eax,16 ; several steps 1333 mov ax,cx 1334 1335 ;*=================================================================== 1336 ; Find out if we should bother to align the row. 1337 ;*=================================================================== 1338 1339 cmp esi , OPTIMAL_BYTE_COPY ; is it worth aligning them? 1340 jl byte_by_byte ; if not then skip 1341 1342 ;*=================================================================== 1343 ; Figure out the alignment offset if there is any 1344 ;*=================================================================== 1345 push ebx 1346 1347 dword_aligned_loop: 1348 mov ecx , edi 1349 mov ebx , esi 1350 neg ecx 1351 and ecx , 3 1352 sub ebx , ecx 1353 rep stosb 1354 mov ecx , ebx 1355 shr ecx , 2 1356 rep stosd 1357 mov ecx , ebx 1358 and ecx , 3 1359 rep stosb 1360 add edi , [ esp ] 1361 dec edx ; decrement the height 1362 jnz dword_aligned_loop ; if more to do than do it 1363 pop eax 1364 jmp done 1365 //ret 1366 1367 ;*=================================================================== 1368 ; If not enough bytes to bother aligning copy each line across a byte 1369 ; at a time. 1370 ;*=================================================================== 1371 byte_by_byte: 1372 mov ecx,esi ; get total width in bytes 1373 rep stosb ; store the width 1374 add edi,ebx ; handle the xadd 1375 dec edx ; decrement the height 1376 jnz byte_by_byte ; if any left then next line 1377 done: 1378 } 1379 } 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 BOOL __cdecl Linear_Blit_To_Linear( void *this_object, void * dest, int x_pixel, int y_pixel, int dest_x0, int dest_y0, int pixel_width, int pixel_height, BOOL trans) 1395 { 1396 /* 1397 ;*=================================================================== 1398 ;* define the arguements that our function takes. 1399 ;*=================================================================== 1400 ARG this_object :DWORD ; this is a member function 1401 ARG dest :DWORD ; what are we blitting to 1402 ARG x_pixel :DWORD ; x pixel position in source 1403 ARG y_pixel :DWORD ; y pixel position in source 1404 ARG dest_x0 :dword 1405 ARG dest_y0 :dword 1406 ARG pixel_width :DWORD ; width of rectangle to blit 1407 ARG pixel_height:DWORD ; height of rectangle to blit 1408 ARG trans :DWORD ; do we deal with transparents? 1409 1410 ;*=================================================================== 1411 ; Define some locals so that we can handle things quickly 1412 ;*=================================================================== 1413 LOCAL x1_pixel :dword 1414 LOCAL y1_pixel :dword 1415 LOCAL dest_x1 : dword 1416 LOCAL dest_y1 : dword 1417 LOCAL scr_ajust_width:DWORD 1418 LOCAL dest_ajust_width:DWORD 1419 LOCAL source_area : dword 1420 LOCAL dest_area : dword 1421 */ 1422 1423 int x1_pixel; 1424 int y1_pixel; 1425 int dest_x1; 1426 int dest_y1; 1427 int scr_adjust_width; 1428 int dest_adjust_width; 1429 int source_area; 1430 int dest_area; 1431 1432 __asm { 1433 1434 ;This Clipping algorithm is a derivation of the very well known 1435 ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency 1436 ;it is probably the most commontly implemented algorithm both in software 1437 ;and hardware for clipping lines, rectangles, and convex polygons against 1438 ;a rectagular clipping window. For reference see 1439 ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes 1440 ; pages 113 to 177". 1441 ; Briefly consist in computing the Sutherland code for both end point of 1442 ; the rectangle to find out if the rectangle is: 1443 ; - trivially accepted (no further clipping test, display rectangle) 1444 ; - trivially rejected (return with no action) 1445 ; - retangle must be iteratively clipped again edges of the clipping window 1446 ; and the remaining retangle is display. 1447 1448 ; Clip Source Rectangle against source Window boundaries. 1449 mov esi,[this_object] ; get ptr to src 1450 xor ecx,ecx ; Set sutherland code to zero 1451 xor edx,edx ; Set sutherland code to zero 1452 1453 ; compute the difference in the X axis and get the bit signs into ecx , edx 1454 mov edi,[esi]GraphicViewPortClass.Width ; get width into register 1455 mov ebx,[x_pixel] ; Get first end point x_pixel into register 1456 mov eax,[x_pixel] ; Get second end point x_pixel into register 1457 add ebx,[pixel_width] ; second point x1_pixel = x + width 1458 shld ecx, eax,1 ; the sign bit of x_pixel is sutherland code0 bit4 1459 mov [x1_pixel],ebx ; save second for future use 1460 inc edi ; move the right edge by one unit 1461 shld edx,ebx,1 ; the sign bit of x1_pixel is sutherland code0 bit4 1462 sub eax,edi ; compute the difference x0_pixel - width 1463 sub ebx,edi ; compute the difference x1_pixel - width 1464 shld ecx,eax,1 ; the sign bit of the difference is sutherland code0 bit3 1465 shld edx,ebx,1 ; the sign bit of the difference is sutherland code0 bit3 1466 1467 ; the following code is just a repeticion of the above code 1468 ; in the Y axis. 1469 mov edi,[esi]GraphicViewPortClass.Height ; get height into register 1470 mov ebx,[y_pixel] 1471 mov eax,[y_pixel] 1472 add ebx,[pixel_height] 1473 shld ecx,eax,1 1474 mov [y1_pixel ],ebx 1475 inc edi 1476 shld edx,ebx,1 1477 sub eax,edi 1478 sub ebx,edi 1479 shld ecx,eax,1 1480 shld edx,ebx,1 1481 1482 ; Here we have the to Sutherland code into cl and dl 1483 xor cl,5 ; bit 2 and 0 are complented, reverse then 1484 xor dl,5 ; bit 2 and 0 are complented, reverse then 1485 mov al,cl ; save code1 in case we have to clip iteratively 1486 test dl,cl ; if any bit in code0 and its counter bit 1487 jnz real_out ; in code1 is set then the rectangle in outside 1488 or al,dl ; if all bit of code0 the counter bit in 1489 jz clip_against_dest ; in code1 is set to zero, then all 1490 ; end points of the rectangle are 1491 ; inside the clipping window 1492 1493 ; if we are here the polygon have to be clip iteratively 1494 test cl,1000b ; if bit 4 in code0 is set then 1495 jz scr_left_ok ; x_pixel is smaller than zero 1496 mov [x_pixel],0 ; set x_pixel to cero. 1497 1498 scr_left_ok: 1499 test cl,0010b ; if bit 2 in code0 is set then 1500 jz scr_bottom_ok ; y_pixel is smaller than zero 1501 mov [ y_pixel ],0 ; set y_pixel to cero. 1502 1503 scr_bottom_ok: 1504 test dl,0100b ; if bit 3 in code1 is set then 1505 jz scr_right_ok ; x1_pixel is greater than the width 1506 mov eax,[esi]GraphicViewPortClass.Width ; get width into register 1507 mov [ x1_pixel ],eax ; set x1_pixel to width. 1508 scr_right_ok: 1509 test dl,0001b ; if bit 0 in code1 is set then 1510 jz clip_against_dest ; y1_pixel is greater than the width 1511 mov eax,[esi]GraphicViewPortClass.Height ; get height into register 1512 mov [ y1_pixel ],eax ; set y1_pixel to height. 1513 1514 ; Clip Source Rectangle against destination Window boundaries. 1515 clip_against_dest: 1516 1517 ; build the destination rectangle before clipping 1518 ; dest_x1 = dest_x0 + ( x1_pixel - x_pixel ) 1519 ; dest_y1 = dest_y0 + ( y1_pixel - y_pixel ) 1520 mov eax,[dest_x0] ; get dest_x0 into eax 1521 mov ebx,[dest_y0] ; get dest_y0 into ebx 1522 sub eax,[x_pixel] ; subtract x_pixel from eax 1523 sub ebx,[y_pixel] ; subtract y_pixel from ebx 1524 add eax,[x1_pixel] ; add x1_pixel to eax 1525 add ebx,[y1_pixel] ; add y1_pixel to ebx 1526 mov [dest_x1],eax ; save eax into dest_x1 1527 mov [dest_y1],ebx ; save eax into dest_y1 1528 1529 1530 ; The followin code is a repeticion of the Sutherland clipping 1531 ; descrived above. 1532 mov esi,[dest] ; get ptr to src 1533 xor ecx,ecx 1534 xor edx,edx 1535 mov edi,[esi]GraphicViewPortClass.Width ; get width into register 1536 mov eax,[dest_x0] 1537 mov ebx,[dest_x1] 1538 shld ecx,eax,1 1539 inc edi 1540 shld edx,ebx,1 1541 sub eax,edi 1542 sub ebx,edi 1543 shld ecx,eax,1 1544 shld edx,ebx,1 1545 1546 mov edi,[esi]GraphicViewPortClass.Height ; get height into register 1547 mov eax,[dest_y0] 1548 mov ebx,[dest_y1] 1549 shld ecx,eax,1 1550 inc edi 1551 shld edx,ebx,1 1552 sub eax,edi 1553 sub ebx,edi 1554 shld ecx,eax,1 1555 shld edx,ebx,1 1556 1557 xor cl,5 1558 xor dl,5 1559 mov al,cl 1560 test dl,cl 1561 jnz real_out 1562 or al,dl 1563 jz do_blit 1564 1565 test cl,1000b 1566 jz dest_left_ok 1567 mov eax,[ dest_x0 ] 1568 mov [ dest_x0 ],0 1569 sub [ x_pixel ],eax 1570 1571 dest_left_ok: 1572 test cl,0010b 1573 jz dest_bottom_ok 1574 mov eax,[ dest_y0 ] 1575 mov [ dest_y0 ],0 1576 sub [ y_pixel ],eax 1577 1578 1579 dest_bottom_ok: 1580 test dl,0100b 1581 jz dest_right_ok 1582 mov ebx,[esi]GraphicViewPortClass.Width ; get width into register 1583 mov eax,[ dest_x1 ] 1584 mov [ dest_x1 ],ebx 1585 sub eax,ebx 1586 sub [ x1_pixel ],eax 1587 1588 dest_right_ok: 1589 test dl,0001b 1590 jz do_blit 1591 mov ebx,[esi]GraphicViewPortClass.Height ; get width into register 1592 mov eax,[ dest_y1 ] 1593 mov [ dest_y1 ],ebx 1594 sub eax,ebx 1595 sub [ y1_pixel ],eax 1596 1597 1598 ; Here is where we do the actual blit 1599 do_blit: 1600 cld 1601 mov ebx,[this_object] 1602 mov esi,[ebx]GraphicViewPortClass.Offset 1603 mov eax,[ebx]GraphicViewPortClass.XAdd 1604 add eax,[ebx]GraphicViewPortClass.Width 1605 add eax,[ebx]GraphicViewPortClass.Pitch 1606 mov ecx,eax 1607 mul [y_pixel] 1608 add esi,[x_pixel] 1609 mov [source_area],ecx 1610 add esi,eax 1611 1612 add ecx,[x_pixel ] 1613 sub ecx,[x1_pixel ] 1614 mov [scr_adjust_width ],ecx 1615 1616 mov ebx,[dest] 1617 mov edi,[ebx]GraphicViewPortClass.Offset 1618 mov eax,[ebx]GraphicViewPortClass.XAdd 1619 add eax,[ebx]GraphicViewPortClass.Width 1620 add eax,[ebx]GraphicViewPortClass.Pitch 1621 mov ecx,eax 1622 mul [ dest_y0 ] 1623 add edi,[ dest_x0 ] 1624 mov [ dest_area ],ecx 1625 add edi,eax 1626 1627 mov eax,[ dest_x1 ] 1628 sub eax,[ dest_x0 ] 1629 jle real_out 1630 sub ecx,eax 1631 mov [ dest_adjust_width ],ecx 1632 1633 mov edx,[ dest_y1 ] 1634 sub edx,[ dest_y0 ] 1635 jle real_out 1636 1637 cmp esi,edi 1638 jz real_out 1639 jl backupward_blit 1640 1641 ; ******************************************************************** 1642 ; Forward bitblit 1643 1644 test [ trans ],1 1645 jnz forward_Blit_trans 1646 1647 1648 ; the inner loop is so efficient that 1649 ; the optimal consept no longer apply because 1650 ; the optimal byte have to by a number greather than 9 bytes 1651 cmp eax,10 1652 jl forward_loop_bytes 1653 1654 forward_loop_dword: 1655 mov ecx,edi 1656 mov ebx,eax 1657 neg ecx 1658 and ecx,3 1659 sub ebx,ecx 1660 rep movsb 1661 mov ecx,ebx 1662 shr ecx,2 1663 rep movsd 1664 mov ecx,ebx 1665 and ecx,3 1666 rep movsb 1667 add esi,[ scr_adjust_width ] 1668 add edi,[ dest_adjust_width ] 1669 dec edx 1670 jnz forward_loop_dword 1671 jmp real_out //ret 1672 1673 forward_loop_bytes: 1674 mov ecx,eax 1675 rep movsb 1676 add esi,[ scr_adjust_width ] 1677 add edi,[ dest_adjust_width ] 1678 dec edx 1679 jnz forward_loop_bytes 1680 jmp real_out 1681 1682 forward_Blit_trans: 1683 mov ecx,eax 1684 and ecx,01fh 1685 lea ecx,[ ecx + ecx * 4 ] 1686 neg ecx 1687 shr eax,5 1688 lea ecx,[ transp_reference + ecx * 2 ] 1689 mov [ y1_pixel ],ecx 1690 1691 forward_loop_trans: 1692 mov ecx,eax 1693 jmp [ y1_pixel ] 1694 forward_trans_line: 1695 //REPT 32 1696 //local transp_pixel 1697 //No REPT in msvc inline assembly. 1698 // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM 1699 push ecx 1700 mov ecx, 32 1701 1702 rept_loop: 1703 mov bl,[ esi ] 1704 test bl,bl 1705 jz transp_pixel 1706 mov [ edi ],bl 1707 transp_pixel: 1708 inc esi 1709 inc edi 1710 1711 dec ecx //ST - 12/19/2018 5:44PM 1712 jnz rept_loop //ST - 12/19/2018 5:44PM 1713 1714 pop ecx //ST - 12/19/2018 5:44PM 1715 1716 //ENDM 1717 transp_reference: 1718 dec ecx 1719 jge forward_trans_line 1720 add esi,[ scr_adjust_width ] 1721 add edi,[ dest_adjust_width ] 1722 dec edx 1723 jnz forward_loop_trans 1724 jmp real_out //ret 1725 1726 1727 ; ************************************************************************ 1728 ; backward bitblit 1729 1730 backupward_blit: 1731 1732 mov ebx,[ source_area ] 1733 dec edx 1734 add esi,eax 1735 imul ebx,edx 1736 std 1737 lea esi,[ esi + ebx - 1 ] 1738 1739 mov ebx,[ dest_area ] 1740 add edi,eax 1741 imul ebx,edx 1742 lea edi,[ edi + ebx - 1] 1743 1744 test [ trans ],1 1745 jnz backward_Blit_trans 1746 1747 cmp eax,15 1748 jl backward_loop_bytes 1749 1750 backward_loop_dword: 1751 push edi 1752 push esi 1753 lea ecx,[edi+1] 1754 mov ebx,eax 1755 and ecx,3 ; Get non aligned bytes. 1756 sub ebx,ecx ; remove that from the total size to be copied later. 1757 rep movsb ; do the copy. 1758 sub esi,3 1759 mov ecx,ebx ; Get number of bytes left. 1760 sub edi,3 1761 shr ecx,2 ; Do 4 bytes at a time. 1762 rep movsd ; do the dword copy. 1763 mov ecx,ebx 1764 add esi,3 1765 add edi,3 1766 and ecx,03h 1767 rep movsb ; finnish the remaining bytes. 1768 pop esi 1769 pop edi 1770 sub esi,[ source_area ] 1771 sub edi,[ dest_area ] 1772 dec edx 1773 jge backward_loop_dword 1774 cld 1775 jmp real_out //ret 1776 1777 backward_loop_bytes: 1778 push edi 1779 mov ecx,eax ; remove that from the total size to be copied later. 1780 push esi 1781 rep movsb ; do the copy. 1782 pop esi 1783 pop edi 1784 sub esi,[ source_area ] 1785 sub edi,[ dest_area ] 1786 dec edx 1787 jge backward_loop_bytes 1788 cld 1789 jmp real_out //ret 1790 1791 backward_Blit_trans: 1792 mov ecx,eax 1793 and ecx,01fh 1794 lea ecx,[ ecx + ecx * 4 ] 1795 neg ecx 1796 shr eax,5 1797 lea ecx,[ back_transp_reference + ecx * 2 ] 1798 mov [ y1_pixel ],ecx 1799 1800 backward_loop_trans: 1801 mov ecx,eax 1802 push edi 1803 push esi 1804 jmp [ y1_pixel ] 1805 backward_trans_line: 1806 //REPT 32 1807 //local transp_pixel2 1808 //No REPT in msvc inline assembly. 1809 // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM 1810 push ecx 1811 mov ecx, 32 1812 rept_loop2: 1813 mov bl,[ esi ] 1814 test bl,bl 1815 jz transp_pixel2 1816 mov [ edi ],bl 1817 transp_pixel2: 1818 dec esi 1819 dec edi 1820 1821 dec ecx //ST - 12/19/2018 5:44PM 1822 jnz rept_loop2 //ST - 12/19/2018 5:44PM 1823 1824 pop ecx //ST - 12/19/2018 5:44PM 1825 1826 //ENDM 1827 1828 back_transp_reference: 1829 dec ecx 1830 jge backward_trans_line 1831 pop esi 1832 pop edi 1833 sub esi,[ source_area ] 1834 sub edi,[ dest_area ] 1835 dec edx 1836 jge backward_loop_trans 1837 cld 1838 //ret 1839 1840 real_out: 1841 } 1842 } 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 /* 1856 ;*************************************************************************** 1857 ;* VVC::SCALE -- Scales a virtual viewport to another virtual viewport * 1858 ;* * 1859 ;* INPUT: * 1860 ;* * 1861 ;* OUTPUT: * 1862 ;* * 1863 ;* WARNINGS: * 1864 ;* * 1865 ;* HISTORY: * 1866 ;* 06/16/1994 PWG : Created. * 1867 ;*=========================================================================* 1868 PROC Linear_Scale_To_Linear C NEAR 1869 USES eax,ebx,ecx,edx,esi,edi 1870 */ 1871 1872 // Ran out of registers so had to use ebp. ST - 12/19/2018 6:22PM 1873 #pragma warning (push) 1874 #pragma warning (disable : 4731) 1875 1876 BOOL __cdecl Linear_Scale_To_Linear(void *this_object, void *dest, int src_x, int src_y, int dst_x, int dst_y, int src_width, int src_height, int dst_width, int dst_height, BOOL trans, char *remap) 1877 { 1878 /* 1879 1880 ;*=================================================================== 1881 ;* Define the arguements that our function takes. 1882 ;*=================================================================== 1883 ARG this_object:DWORD ; pointer to source view port 1884 ARG dest:DWORD ; pointer to destination view port 1885 ARG src_x:DWORD ; source x offset into view port 1886 ARG src_y:DWORD ; source y offset into view port 1887 ARG dst_x:DWORD ; dest x offset into view port 1888 ARG dst_y:DWORD ; dest y offset into view port 1889 ARG src_width:DWORD ; width of source rectangle 1890 ARG src_height:DWORD ; height of source rectangle 1891 ARG dst_width:DWORD ; width of dest rectangle 1892 ARG dst_height:DWORD ; width of dest height 1893 ARG trans:DWORD ; is this transparent? 1894 ARG remap:DWORD ; pointer to table to remap source 1895 1896 ;*=================================================================== 1897 ;* Define local variables to hold the viewport characteristics 1898 ;*=================================================================== 1899 local src_x0 : dword 1900 local src_y0 : dword 1901 local src_x1 : dword 1902 local src_y1 : dword 1903 1904 local dst_x0 : dword 1905 local dst_y0 : dword 1906 local dst_x1 : dword 1907 local dst_y1 : dword 1908 1909 local src_win_width : dword 1910 local dst_win_width : dword 1911 local dy_intr : dword 1912 local dy_frac : dword 1913 local dy_acc : dword 1914 local dx_frac : dword 1915 1916 local counter_x : dword 1917 local counter_y : dword 1918 local remap_counter :dword 1919 local entry : dword 1920 */ 1921 1922 int src_x0; 1923 int src_y0; 1924 int src_x1; 1925 int src_y1; 1926 1927 int dst_x0; 1928 int dst_y0; 1929 int dst_x1; 1930 int dst_y1; 1931 1932 int src_win_width; 1933 int dst_win_width; 1934 int dy_intr; 1935 int dy_frac; 1936 int dy_acc; 1937 int dx_frac; 1938 1939 int counter_x; 1940 int counter_y; 1941 int remap_counter; 1942 int entry; 1943 1944 1945 __asm { 1946 1947 ;*=================================================================== 1948 ;* Check for scale error when to or from size 0,0 1949 ;*=================================================================== 1950 cmp [dst_width],0 1951 je all_done 1952 cmp [dst_height],0 1953 je all_done 1954 cmp [src_width],0 1955 je all_done 1956 cmp [src_height],0 1957 je all_done 1958 1959 mov eax , [ src_x ] 1960 mov ebx , [ src_y ] 1961 mov [ src_x0 ] , eax 1962 mov [ src_y0 ] , ebx 1963 add eax , [ src_width ] 1964 add ebx , [ src_height ] 1965 mov [ src_x1 ] , eax 1966 mov [ src_y1 ] , ebx 1967 1968 mov eax , [ dst_x ] 1969 mov ebx , [ dst_y ] 1970 mov [ dst_x0 ] , eax 1971 mov [ dst_y0 ] , ebx 1972 add eax , [ dst_width ] 1973 add ebx , [ dst_height ] 1974 mov [ dst_x1 ] , eax 1975 mov [ dst_y1 ] , ebx 1976 1977 ; Clip Source Rectangle against source Window boundaries. 1978 mov esi , [ this_object ] ; get ptr to src 1979 xor ecx , ecx 1980 xor edx , edx 1981 mov edi , [esi]GraphicViewPortClass.Width ; get width into register 1982 mov eax , [ src_x0 ] 1983 mov ebx , [ src_x1 ] 1984 shld ecx , eax , 1 1985 inc edi 1986 shld edx , ebx , 1 1987 sub eax , edi 1988 sub ebx , edi 1989 shld ecx , eax , 1 1990 shld edx , ebx , 1 1991 1992 mov edi,[esi]GraphicViewPortClass.Height ; get height into register 1993 mov eax , [ src_y0 ] 1994 mov ebx , [ src_y1 ] 1995 shld ecx , eax , 1 1996 inc edi 1997 shld edx , ebx , 1 1998 sub eax , edi 1999 sub ebx , edi 2000 shld ecx , eax , 1 2001 shld edx , ebx , 1 2002 2003 xor cl , 5 2004 xor dl , 5 2005 mov al , cl 2006 test dl , cl 2007 jnz all_done 2008 or al , dl 2009 jz clip_against_dest 2010 mov bl , dl 2011 test cl , 1000b 2012 jz src_left_ok 2013 xor eax , eax 2014 mov [ src_x0 ] , eax 2015 sub eax , [ src_x ] 2016 imul [ dst_width ] 2017 idiv [ src_width ] 2018 add eax , [ dst_x ] 2019 mov [ dst_x0 ] , eax 2020 2021 src_left_ok: 2022 test cl , 0010b 2023 jz src_bottom_ok 2024 xor eax , eax 2025 mov [ src_y0 ] , eax 2026 sub eax , [ src_y ] 2027 imul [ dst_height ] 2028 idiv [ src_height ] 2029 add eax , [ dst_y ] 2030 mov [ dst_y0 ] , eax 2031 2032 src_bottom_ok: 2033 test bl , 0100b 2034 jz src_right_ok 2035 mov eax , [esi]GraphicViewPortClass.Width ; get width into register 2036 mov [ src_x1 ] , eax 2037 sub eax , [ src_x ] 2038 imul [ dst_width ] 2039 idiv [ src_width ] 2040 add eax , [ dst_x ] 2041 mov [ dst_x1 ] , eax 2042 2043 src_right_ok: 2044 test bl , 0001b 2045 jz clip_against_dest 2046 mov eax , [esi]GraphicViewPortClass.Height ; get width into register 2047 mov [ src_y1 ] , eax 2048 sub eax , [ src_y ] 2049 imul [ dst_height ] 2050 idiv [ src_height ] 2051 add eax , [ dst_y ] 2052 mov [ dst_y1 ] , eax 2053 2054 ; Clip destination Rectangle against source Window boundaries. 2055 clip_against_dest: 2056 mov esi , [ dest ] ; get ptr to src 2057 xor ecx , ecx 2058 xor edx , edx 2059 mov edi , [esi]GraphicViewPortClass.Width ; get width into register 2060 mov eax , [ dst_x0 ] 2061 mov ebx , [ dst_x1 ] 2062 shld ecx , eax , 1 2063 inc edi 2064 shld edx , ebx , 1 2065 sub eax , edi 2066 sub ebx , edi 2067 shld ecx , eax , 1 2068 shld edx , ebx , 1 2069 2070 mov edi,[esi]GraphicViewPortClass.Height ; get height into register 2071 mov eax , [ dst_y0 ] 2072 mov ebx , [ dst_y1 ] 2073 shld ecx , eax , 1 2074 inc edi 2075 shld edx , ebx , 1 2076 sub eax , edi 2077 sub ebx , edi 2078 shld ecx , eax , 1 2079 shld edx , ebx , 1 2080 2081 xor cl , 5 2082 xor dl , 5 2083 mov al , cl 2084 test dl , cl 2085 jnz all_done 2086 or al , dl 2087 jz do_scaling 2088 mov bl , dl 2089 test cl , 1000b 2090 jz dst_left_ok 2091 xor eax , eax 2092 mov [ dst_x0 ] , eax 2093 sub eax , [ dst_x ] 2094 imul [ src_width ] 2095 idiv [ dst_width ] 2096 add eax , [ src_x ] 2097 mov [ src_x0 ] , eax 2098 2099 dst_left_ok: 2100 test cl , 0010b 2101 jz dst_bottom_ok 2102 xor eax , eax 2103 mov [ dst_y0 ] , eax 2104 sub eax , [ dst_y ] 2105 imul [ src_height ] 2106 idiv [ dst_height ] 2107 add eax , [ src_y ] 2108 mov [ src_y0 ] , eax 2109 2110 dst_bottom_ok: 2111 test bl , 0100b 2112 jz dst_right_ok 2113 mov eax , [esi]GraphicViewPortClass.Width ; get width into register 2114 mov [ dst_x1 ] , eax 2115 sub eax , [ dst_x ] 2116 imul [ src_width ] 2117 idiv [ dst_width ] 2118 add eax , [ src_x ] 2119 mov [ src_x1 ] , eax 2120 2121 dst_right_ok: 2122 test bl , 0001b 2123 jz do_scaling 2124 2125 mov eax , [esi]GraphicViewPortClass.Height ; get width into register 2126 mov [ dst_y1 ] , eax 2127 sub eax , [ dst_y ] 2128 imul [ src_height ] 2129 idiv [ dst_height ] 2130 add eax , [ src_y ] 2131 mov [ src_y1 ] , eax 2132 2133 do_scaling: 2134 2135 cld 2136 mov ebx , [ this_object ] 2137 mov esi , [ebx]GraphicViewPortClass. Offset 2138 mov eax , [ebx]GraphicViewPortClass. XAdd 2139 add eax , [ebx]GraphicViewPortClass. Width 2140 add eax , [ebx]GraphicViewPortClass. Pitch 2141 mov [ src_win_width ] , eax 2142 mul [ src_y0 ] 2143 add esi , [ src_x0 ] 2144 add esi , eax 2145 2146 mov ebx , [ dest ] 2147 mov edi , [ebx]GraphicViewPortClass. Offset 2148 mov eax , [ebx]GraphicViewPortClass. XAdd 2149 add eax , [ebx]GraphicViewPortClass. Width 2150 add eax , [ebx]GraphicViewPortClass. Pitch 2151 mov [ dst_win_width ] , eax 2152 mul [ dst_y0 ] 2153 add edi , [ dst_x0 ] 2154 add edi , eax 2155 2156 mov eax , [ src_height ] 2157 xor edx , edx 2158 mov ebx , [ dst_height ] 2159 idiv [ dst_height ] 2160 imul eax , [ src_win_width ] 2161 neg ebx 2162 mov [ dy_intr ] , eax 2163 mov [ dy_frac ] , edx 2164 mov [ dy_acc ] , ebx 2165 2166 mov eax , [ src_width ] 2167 xor edx , edx 2168 shl eax , 16 2169 idiv [ dst_width ] 2170 xor edx , edx 2171 shld edx , eax , 16 2172 shl eax , 16 2173 2174 mov ecx , [ dst_y1 ] 2175 mov ebx , [ dst_x1 ] 2176 sub ecx , [ dst_y0 ] 2177 jle all_done 2178 sub ebx , [ dst_x0 ] 2179 jle all_done 2180 2181 mov [ counter_y ] , ecx 2182 2183 cmp [ trans ] , 0 2184 jnz transparency 2185 2186 cmp [ remap ] , 0 2187 jnz normal_remap 2188 2189 ; ************************************************************************* 2190 ; normal scale 2191 mov ecx , ebx 2192 and ecx , 01fh 2193 lea ecx , [ ecx + ecx * 2 ] 2194 shr ebx , 5 2195 neg ecx 2196 mov [ counter_x ] , ebx 2197 lea ecx , [ ref_point + ecx + ecx * 2 ] 2198 mov [ entry ] , ecx 2199 2200 outter_loop: 2201 push esi 2202 push edi 2203 xor ecx , ecx 2204 mov ebx , [ counter_x ] 2205 jmp [ entry ] 2206 inner_loop: 2207 // REPT not supported for inline asm. ST - 12/19/2018 6:11PM 2208 //REPT 32 2209 push ebx //ST - 12/19/2018 6:11PM 2210 mov ebx,32 //ST - 12/19/2018 6:11PM 2211 rept_loop: 2212 mov cl , [ esi ] 2213 add ecx , eax 2214 adc esi , edx 2215 mov [ edi ] , cl 2216 inc edi 2217 2218 dec ebx //ST - 12/19/2018 6:11PM 2219 jnz rept_loop //ST - 12/19/2018 6:11PM 2220 pop ebx //ST - 12/19/2018 6:11PM 2221 //ENDM 2222 ref_point: 2223 dec ebx 2224 jge inner_loop 2225 2226 pop edi 2227 pop esi 2228 add edi , [ dst_win_width ] 2229 add esi , [ dy_intr ] 2230 2231 mov ebx , [ dy_acc ] 2232 add ebx , [ dy_frac ] 2233 jle skip_line 2234 add esi , [ src_win_width ] 2235 sub ebx , [ dst_height ] 2236 skip_line: 2237 dec [ counter_y ] 2238 mov [ dy_acc ] , ebx 2239 jnz outter_loop 2240 jmp all_done //ret 2241 2242 2243 ; ************************************************************************* 2244 ; normal scale with remap 2245 2246 normal_remap: 2247 mov ecx , ebx 2248 mov [ dx_frac ], eax 2249 and ecx , 01fh 2250 mov eax , [ remap ] 2251 shr ebx , 5 2252 imul ecx , - 13 2253 mov [ counter_x ] , ebx 2254 lea ecx , [ remapref_point + ecx ] 2255 mov [ entry ] , ecx 2256 2257 remapoutter_loop: 2258 mov ebx , [ counter_x ] 2259 push esi 2260 mov [ remap_counter ] , ebx 2261 push edi 2262 xor ecx , ecx 2263 xor ebx , ebx 2264 jmp [ entry ] 2265 remapinner_loop: 2266 // REPT not supported for inline asm. ST - 12/19/2018 6:11PM 2267 //REPT 32 2268 mov bl , [ esi ] 2269 add ecx , [ dx_frac ] 2270 adc esi , edx 2271 mov cl , [ eax + ebx ] 2272 mov [ edi ] , cl 2273 inc edi 2274 mov bl , [ esi ] 2275 add ecx , [ dx_frac ] 2276 adc esi , edx 2277 mov cl , [ eax + ebx ] 2278 mov [ edi ] , cl 2279 inc edi 2280 mov bl , [ esi ] 2281 add ecx , [ dx_frac ] 2282 adc esi , edx 2283 mov cl , [ eax + ebx ] 2284 mov [ edi ] , cl 2285 inc edi 2286 mov bl , [ esi ] 2287 add ecx , [ dx_frac ] 2288 adc esi , edx 2289 mov cl , [ eax + ebx ] 2290 mov [ edi ] , cl 2291 inc edi 2292 mov bl , [ esi ] 2293 add ecx , [ dx_frac ] 2294 adc esi , edx 2295 mov cl , [ eax + ebx ] 2296 mov [ edi ] , cl 2297 inc edi 2298 mov bl , [ esi ] 2299 add ecx , [ dx_frac ] 2300 adc esi , edx 2301 mov cl , [ eax + ebx ] 2302 mov [ edi ] , cl 2303 inc edi 2304 mov bl , [ esi ] 2305 add ecx , [ dx_frac ] 2306 adc esi , edx 2307 mov cl , [ eax + ebx ] 2308 mov [ edi ] , cl 2309 inc edi 2310 mov bl , [ esi ] 2311 add ecx , [ dx_frac ] 2312 adc esi , edx 2313 mov cl , [ eax + ebx ] 2314 mov [ edi ] , cl 2315 inc edi 2316 mov bl , [ esi ] 2317 add ecx , [ dx_frac ] 2318 adc esi , edx 2319 mov cl , [ eax + ebx ] 2320 mov [ edi ] , cl 2321 inc edi 2322 mov bl , [ esi ] 2323 add ecx , [ dx_frac ] 2324 adc esi , edx 2325 mov cl , [ eax + ebx ] 2326 mov [ edi ] , cl 2327 inc edi 2328 mov bl , [ esi ] 2329 add ecx , [ dx_frac ] 2330 adc esi , edx 2331 mov cl , [ eax + ebx ] 2332 mov [ edi ] , cl 2333 inc edi 2334 mov bl , [ esi ] 2335 add ecx , [ dx_frac ] 2336 adc esi , edx 2337 mov cl , [ eax + ebx ] 2338 mov [ edi ] , cl 2339 inc edi 2340 mov bl , [ esi ] 2341 add ecx , [ dx_frac ] 2342 adc esi , edx 2343 mov cl , [ eax + ebx ] 2344 mov [ edi ] , cl 2345 inc edi 2346 mov bl , [ esi ] 2347 add ecx , [ dx_frac ] 2348 adc esi , edx 2349 mov cl , [ eax + ebx ] 2350 mov [ edi ] , cl 2351 inc edi 2352 mov bl , [ esi ] 2353 add ecx , [ dx_frac ] 2354 adc esi , edx 2355 mov cl , [ eax + ebx ] 2356 mov [ edi ] , cl 2357 inc edi 2358 mov bl , [ esi ] 2359 add ecx , [ dx_frac ] 2360 adc esi , edx 2361 mov cl , [ eax + ebx ] 2362 mov [ edi ] , cl 2363 inc edi 2364 mov bl , [ esi ] 2365 add ecx , [ dx_frac ] 2366 adc esi , edx 2367 mov cl , [ eax + ebx ] 2368 mov [ edi ] , cl 2369 inc edi 2370 mov bl , [ esi ] 2371 add ecx , [ dx_frac ] 2372 adc esi , edx 2373 mov cl , [ eax + ebx ] 2374 mov [ edi ] , cl 2375 inc edi 2376 mov bl , [ esi ] 2377 add ecx , [ dx_frac ] 2378 adc esi , edx 2379 mov cl , [ eax + ebx ] 2380 mov [ edi ] , cl 2381 inc edi 2382 mov bl , [ esi ] 2383 add ecx , [ dx_frac ] 2384 adc esi , edx 2385 mov cl , [ eax + ebx ] 2386 mov [ edi ] , cl 2387 inc edi 2388 mov bl , [ esi ] 2389 add ecx , [ dx_frac ] 2390 adc esi , edx 2391 mov cl , [ eax + ebx ] 2392 mov [ edi ] , cl 2393 inc edi 2394 mov bl , [ esi ] 2395 add ecx , [ dx_frac ] 2396 adc esi , edx 2397 mov cl , [ eax + ebx ] 2398 mov [ edi ] , cl 2399 inc edi 2400 mov bl , [ esi ] 2401 add ecx , [ dx_frac ] 2402 adc esi , edx 2403 mov cl , [ eax + ebx ] 2404 mov [ edi ] , cl 2405 inc edi 2406 mov bl , [ esi ] 2407 add ecx , [ dx_frac ] 2408 adc esi , edx 2409 mov cl , [ eax + ebx ] 2410 mov [ edi ] , cl 2411 inc edi 2412 mov bl , [ esi ] 2413 add ecx , [ dx_frac ] 2414 adc esi , edx 2415 mov cl , [ eax + ebx ] 2416 mov [ edi ] , cl 2417 inc edi 2418 mov bl , [ esi ] 2419 add ecx , [ dx_frac ] 2420 adc esi , edx 2421 mov cl , [ eax + ebx ] 2422 mov [ edi ] , cl 2423 inc edi 2424 mov bl , [ esi ] 2425 add ecx , [ dx_frac ] 2426 adc esi , edx 2427 mov cl , [ eax + ebx ] 2428 mov [ edi ] , cl 2429 inc edi 2430 mov bl , [ esi ] 2431 add ecx , [ dx_frac ] 2432 adc esi , edx 2433 mov cl , [ eax + ebx ] 2434 mov [ edi ] , cl 2435 inc edi 2436 mov bl , [ esi ] 2437 add ecx , [ dx_frac ] 2438 adc esi , edx 2439 mov cl , [ eax + ebx ] 2440 mov [ edi ] , cl 2441 inc edi 2442 mov bl , [ esi ] 2443 add ecx , [ dx_frac ] 2444 adc esi , edx 2445 mov cl , [ eax + ebx ] 2446 mov [ edi ] , cl 2447 inc edi 2448 mov bl , [ esi ] 2449 add ecx , [ dx_frac ] 2450 adc esi , edx 2451 mov cl , [ eax + ebx ] 2452 mov [ edi ] , cl 2453 inc edi 2454 mov bl , [ esi ] 2455 add ecx , [ dx_frac ] 2456 adc esi , edx 2457 mov cl , [ eax + ebx ] 2458 mov [ edi ] , cl 2459 inc edi 2460 2461 //ENDM 2462 remapref_point: 2463 dec [ remap_counter ] 2464 jge remapinner_loop 2465 2466 pop edi 2467 pop esi 2468 add edi , [ dst_win_width ] 2469 add esi , [ dy_intr ] 2470 2471 mov ebx , [ dy_acc ] 2472 add ebx , [ dy_frac ] 2473 jle remapskip_line 2474 add esi , [ src_win_width ] 2475 sub ebx , [ dst_height ] 2476 remapskip_line: 2477 dec [ counter_y ] 2478 mov [ dy_acc ] , ebx 2479 jnz remapoutter_loop 2480 jmp all_done //ret 2481 2482 2483 ;**************************************************************************** 2484 ; scale with trnsparency 2485 2486 transparency: 2487 cmp [ remap ] , 0 2488 jnz trans_remap 2489 2490 ; ************************************************************************* 2491 ; normal scale with transparency 2492 mov ecx , ebx 2493 and ecx , 01fh 2494 imul ecx , -13 2495 shr ebx , 5 2496 mov [ counter_x ] , ebx 2497 lea ecx , [ trans_ref_point + ecx ] 2498 mov [ entry ] , ecx 2499 2500 trans_outter_loop: 2501 xor ecx , ecx 2502 push esi 2503 push edi 2504 mov ebx , [ counter_x ] 2505 jmp [ entry ] 2506 trans_inner_loop: 2507 2508 // REPT not supported for inline asm. ST - 12/19/2018 6:11PM 2509 //REPT 32 2510 push ebx //ST - 12/19/2018 6:11PM 2511 mov ebx,32 //ST - 12/19/2018 6:11PM 2512 rept_loop2: 2513 2514 mov cl , [ esi ] 2515 test cl , cl 2516 jz trans_pixel 2517 mov [ edi ] , cl 2518 trans_pixel: 2519 add ecx , eax 2520 adc esi , edx 2521 inc edi 2522 2523 dec ebx //ST - 12/19/2018 6:11PM 2524 jnz rept_loop2 //ST - 12/19/2018 6:11PM 2525 pop ebx //ST - 12/19/2018 6:11PM 2526 2527 //ENDM 2528 trans_ref_point: 2529 dec ebx 2530 jge trans_inner_loop 2531 2532 pop edi 2533 pop esi 2534 add edi , [ dst_win_width ] 2535 add esi , [ dy_intr ] 2536 2537 mov ebx , [ dy_acc ] 2538 add ebx , [ dy_frac ] 2539 jle trans_skip_line 2540 add esi , [ src_win_width ] 2541 sub ebx , [ dst_height ] 2542 trans_skip_line: 2543 dec [ counter_y ] 2544 mov [ dy_acc ] , ebx 2545 jnz trans_outter_loop 2546 jmp all_done //ret 2547 2548 2549 ; ************************************************************************* 2550 ; normal scale with remap 2551 2552 trans_remap: 2553 mov ecx , ebx 2554 mov [ dx_frac ], eax 2555 and ecx , 01fh 2556 mov eax , [ remap ] 2557 shr ebx , 5 2558 imul ecx , - 17 2559 mov [ counter_x ] , ebx 2560 lea ecx , [ trans_remapref_point + ecx ] 2561 mov [ entry ] , ecx 2562 2563 trans_remapoutter_loop: 2564 mov ebx , [ counter_x ] 2565 push esi 2566 mov [ remap_counter ] , ebx 2567 push edi 2568 xor ecx , ecx 2569 xor ebx , ebx 2570 jmp [ entry ] 2571 2572 2573 trans_remapinner_loop: 2574 // REPT not supported for inline asm. ST - 12/19/2018 6:11PM 2575 //REPT 32 2576 // Run out of registers so use ebp 2577 push ebp //ST - 12/19/2018 6:11PM 2578 mov ebp,32 //ST - 12/19/2018 6:11PM 2579 rept_loop3: 2580 mov bl , [ esi ] 2581 test bl , bl 2582 jz trans_pixel2 2583 mov cl , [ eax + ebx ] 2584 mov [ edi ] , cl 2585 trans_pixel2: 2586 add ecx , [ dx_frac ] 2587 adc esi , edx 2588 inc edi 2589 2590 dec ebp //ST - 12/19/2018 6:11PM 2591 jnz rept_loop3 //ST - 12/19/2018 6:11PM 2592 pop ebp //ST - 12/19/2018 6:11PM 2593 2594 //ENDM 2595 2596 trans_remapref_point: 2597 dec [ remap_counter ] 2598 jge trans_remapinner_loop 2599 2600 pop edi 2601 pop esi 2602 add edi , [ dst_win_width ] 2603 add esi , [ dy_intr ] 2604 2605 mov ebx , [ dy_acc ] 2606 add ebx , [ dy_frac ] 2607 jle trans_remapskip_line 2608 add esi , [ src_win_width ] 2609 sub ebx , [ dst_height ] 2610 trans_remapskip_line: 2611 dec [ counter_y ] 2612 mov [ dy_acc ] , ebx 2613 jnz trans_remapoutter_loop 2614 //ret 2615 2616 2617 all_done: 2618 } 2619 } 2620 2621 2622 #pragma warning (pop) 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 unsigned int LastIconset = 0; 2644 unsigned int StampPtr = 0; // DD 0 ; Pointer to icon data. 2645 2646 unsigned int IsTrans = 0; // DD 0 ; Pointer to transparent icon flag table. 2647 2648 unsigned int MapPtr = 0; // DD 0 ; Pointer to icon map. 2649 unsigned int IconWidth = 0; // DD 0 ; Width of icon in pixels. 2650 unsigned int IconHeight = 0; // DD 0 ; Height of icon in pixels. 2651 unsigned int IconSize = 0; // DD 0 ; Number of bytes for each icon data. 2652 unsigned int IconCount = 0; // DD 0 ; Number of icons in the set. 2653 2654 2655 2656 #if (0) 2657 LastIconset DD 0 ; Pointer to last iconset initialized. 2658 StampPtr DD 0 ; Pointer to icon data. 2659 2660 IsTrans DD 0 ; Pointer to transparent icon flag table. 2661 2662 MapPtr DD 0 ; Pointer to icon map. 2663 IconWidth DD 0 ; Width of icon in pixels. 2664 IconHeight DD 0 ; Height of icon in pixels. 2665 IconSize DD 0 ; Number of bytes for each icon data. 2666 IconCount DD 0 ; Number of icons in the set. 2667 2668 2669 GLOBAL C Buffer_Draw_Stamp:near 2670 GLOBAL C Buffer_Draw_Stamp_Clip:near 2671 2672 ; 256 color icon system. 2673 #endif 2674 2675 2676 /* 2677 ;*********************************************************** 2678 ; INIT_STAMPS 2679 ; 2680 ; VOID cdecl Init_Stamps(VOID *icondata); 2681 ; 2682 ; This routine initializes the stamp data. 2683 ; Bounds Checking: NONE 2684 ; 2685 ;* 2686 */ 2687 extern "C" void __cdecl Init_Stamps(unsigned int icondata) 2688 { 2689 2690 __asm { 2691 pushad // ST - 12/20/2018 10:30AM 2692 2693 ; Verify legality of parameter. 2694 cmp [icondata],0 2695 je short fini 2696 2697 ; Don't initialize if already initialized to this set (speed reasons). 2698 mov edi,[icondata] 2699 cmp [LastIconset],edi 2700 je short fini 2701 mov [LastIconset],edi 2702 2703 ; Record number of icons in set. 2704 movzx eax,[edi]IControl_Type.Count 2705 mov [IconCount],eax 2706 2707 ; Record width of icon. 2708 movzx eax,[edi]IControl_Type.Width 2709 mov [IconWidth],eax 2710 2711 ; Record height of icon. 2712 movzx ebx,[edi]IControl_Type.Height 2713 mov [IconHeight],ebx 2714 2715 ; Record size of icon (in bytes). 2716 mul ebx 2717 mov [IconSize],eax 2718 2719 ; Record hard pointer to icon map data. 2720 mov eax,[edi]IControl_Type.Map 2721 add eax,edi 2722 mov [MapPtr],eax 2723 2724 //nomap: 2725 ; Record hard pointer to icon data. 2726 mov eax,edi 2727 add eax,[edi]IControl_Type.Icons 2728 mov [StampPtr],eax 2729 2730 ; Record the transparent table. 2731 mov eax,edi 2732 add eax,[edi]IControl_Type.TransFlag 2733 mov [IsTrans],eax 2734 2735 fini: 2736 popad // ST - 12/20/2018 10:30AM 2737 2738 } 2739 } 2740 2741 2742 /* 2743 ;*********************************************************** 2744 2745 ;*********************************************************** 2746 ; DRAW_STAMP 2747 ; 2748 ; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap); 2749 ; 2750 ; This routine renders the icon at the given coordinate. 2751 ; 2752 ; The remap table is a 256 byte simple pixel translation table to use when 2753 ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to 2754 ; remap valid colors to be invisible (for special effect reasons). 2755 ; This routine is fastest when no remap table is passed in. 2756 ;* 2757 */ 2758 2759 void __cdecl Buffer_Draw_Stamp(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap) 2760 { 2761 unsigned int modulo = 0; 2762 unsigned int iwidth = 0; 2763 unsigned char doremap = 0; 2764 2765 2766 /* 2767 PROC Buffer_Draw_Stamp C near 2768 2769 ARG this_object:DWORD ; this is a member function 2770 ARG icondata:DWORD ; Pointer to icondata. 2771 ARG icon:DWORD ; Icon number to draw. 2772 ARG x_pixel:DWORD ; X coordinate of icon. 2773 ARG y_pixel:DWORD ; Y coordinate of icon. 2774 ARG remap:DWORD ; Remap table. 2775 2776 LOCAL modulo:DWORD ; Modulo to get to next row. 2777 LOCAL iwidth:DWORD ; Icon width (here for speedy access). 2778 LOCAL doremap:BYTE ; Should remapping occur? 2779 */ 2780 2781 __asm { 2782 2783 pushad 2784 cmp [icondata],0 2785 je proc_out 2786 2787 ; Initialize the stamp data if necessary. 2788 mov eax,[icondata] 2789 cmp [LastIconset],eax 2790 je short noreset 2791 push eax 2792 call Init_Stamps 2793 pop eax // Clean up stack. ST - 12/20/2018 10:42AM 2794 noreset: 2795 2796 ; Determine if the icon number requested is actually in the set. 2797 ; Perform the logical icon to actual icon number remap if necessary. 2798 mov ebx,[icon] 2799 cmp [MapPtr],0 2800 je short notmap 2801 mov edi,[MapPtr] 2802 mov bl,[edi+ebx] 2803 notmap: 2804 cmp ebx,[IconCount] 2805 jae proc_out 2806 mov [icon],ebx ; Updated icon number. 2807 2808 ; If the remap table pointer passed in is NULL, then flag this condition 2809 ; so that the faster (non-remapping) icon draw loop will be used. 2810 cmp [remap],0 2811 setne [doremap] 2812 2813 ; Get pointer to position to render icon. EDI = ptr to destination page. 2814 mov ebx,[this_object] 2815 mov edi,[ebx]GraphicViewPortClass.Offset 2816 mov eax,[ebx]GraphicViewPortClass.Width 2817 add eax,[ebx]GraphicViewPortClass.XAdd 2818 add eax,[ebx]GraphicViewPortClass.Pitch 2819 push eax ; save viewport full width for lower 2820 mul [y_pixel] 2821 add edi,eax 2822 add edi,[x_pixel] 2823 2824 ; Determine row modulo for advancing to next line. 2825 pop eax ; retrieve viewport width 2826 sub eax,[IconWidth] 2827 mov [modulo],eax 2828 2829 ; Setup some working variables. 2830 mov ecx,[IconHeight] ; Row counter. 2831 mov eax,[IconWidth] 2832 mov [iwidth],eax ; Stack copy of byte width for easy BP access. 2833 2834 ; Fetch pointer to start of icon's data. ESI = ptr to icon data. 2835 mov eax,[icon] 2836 mul [IconSize] 2837 mov esi,[StampPtr] 2838 add esi,eax 2839 2840 ; Determine whether simple icon draw is sufficient or whether the 2841 ; extra remapping icon draw is needed. 2842 cmp [BYTE PTR doremap],0 2843 je short istranscheck 2844 2845 ;************************************************************ 2846 ; Complex icon draw -- extended remap. 2847 ; EBX = Palette pointer (ready for XLAT instruction). 2848 ; EDI = Pointer to icon destination in page. 2849 ; ESI = Pointer to icon data. 2850 ; ECX = Number of pixel rows. 2851 ;;; mov edx,[remap] 2852 mov ebx,[remap] 2853 xor eax,eax 2854 xrowloop: 2855 push ecx 2856 mov ecx,[iwidth] 2857 2858 xcolumnloop: 2859 lodsb 2860 ;;; mov ebx,edx 2861 ;;; add ebx,eax 2862 ;;; mov al,[ebx] ; New real color to draw. 2863 xlatb 2864 or al,al 2865 jz short xskip1 ; Transparency skip check. 2866 mov [edi],al 2867 xskip1: 2868 inc edi 2869 loop xcolumnloop 2870 2871 pop ecx 2872 add edi,[modulo] 2873 loop xrowloop 2874 jmp short proc_out 2875 2876 2877 ;************************************************************ 2878 ; Check to see if transparent or generic draw is necessary. 2879 istranscheck: 2880 mov ebx,[IsTrans] 2881 add ebx,[icon] 2882 cmp [BYTE PTR ebx],0 2883 jne short rowloop 2884 2885 ;************************************************************ 2886 ; Fast non-transparent icon draw routine. 2887 ; ES:DI = Pointer to icon destination in page. 2888 ; DS:SI = Pointer to icon data. 2889 ; CX = Number of pixel rows. 2890 mov ebx,ecx 2891 shr ebx,2 2892 mov edx,[modulo] 2893 mov eax,[iwidth] 2894 shr eax,2 2895 loop1: 2896 mov ecx,eax 2897 rep movsd 2898 add edi,edx 2899 2900 mov ecx,eax 2901 rep movsd 2902 add edi,edx 2903 2904 mov ecx,eax 2905 rep movsd 2906 add edi,edx 2907 2908 mov ecx,eax 2909 rep movsd 2910 add edi,edx 2911 2912 dec ebx 2913 jnz loop1 2914 jmp short proc_out 2915 2916 ;************************************************************ 2917 ; Transparent icon draw routine -- no extended remap. 2918 ; ES:DI = Pointer to icon destination in page. 2919 ; DS:SI = Pointer to icon data. 2920 ; CX = Number of pixel rows. 2921 rowloop: 2922 push ecx 2923 mov ecx,[iwidth] 2924 2925 columnloop: 2926 lodsb 2927 or al,al 2928 jz short skip1 ; Transparency check. 2929 mov [edi],al 2930 skip1: 2931 inc edi 2932 loop columnloop 2933 2934 pop ecx 2935 add edi,[modulo] 2936 loop rowloop 2937 2938 ; Cleanup and exit icon drawing routine. 2939 proc_out: 2940 popad 2941 //ret 2942 } 2943 } 2944 2945 2946 2947 2948 /* 2949 ;*********************************************************** 2950 ; DRAW_STAMP_CLIP 2951 ; 2952 ; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y); 2953 ; 2954 ; This routine renders the icon at the given coordinate. 2955 ; 2956 ; The remap table is a 256 byte simple pixel translation table to use when 2957 ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to 2958 ; remap valid colors to be invisible (for special effect reasons). 2959 ; This routine is fastest when no remap table is passed in. 2960 ;* 2961 */ 2962 void __cdecl Buffer_Draw_Stamp_Clip(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int min_x, int min_y, int max_x, int max_y) 2963 { 2964 2965 2966 unsigned int modulo = 0; 2967 unsigned int iwidth = 0; 2968 unsigned int skip = 0; 2969 unsigned char doremap = 0; 2970 2971 2972 /* 2973 ARG this_object:DWORD ; this is a member function 2974 ARG icondata:DWORD ; Pointer to icondata. 2975 ARG icon:DWORD ; Icon number to draw. 2976 ARG x_pixel:DWORD ; X coordinate of icon. 2977 ARG y_pixel:DWORD ; Y coordinate of icon. 2978 ARG remap:DWORD ; Remap table. 2979 ARG min_x:DWORD ; Clipping rectangle boundary 2980 ARG min_y:DWORD ; Clipping rectangle boundary 2981 ARG max_x:DWORD ; Clipping rectangle boundary 2982 ARG max_y:DWORD ; Clipping rectangle boundary 2983 2984 LOCAL modulo:DWORD ; Modulo to get to next row. 2985 LOCAL iwidth:DWORD ; Icon width (here for speedy access). 2986 LOCAL skip:DWORD ; amount to skip per row of icon data 2987 LOCAL doremap:BYTE ; Should remapping occur? 2988 */ 2989 __asm { 2990 pushad 2991 cmp [icondata],0 2992 je proc_out 2993 2994 ; Initialize the stamp data if necessary. 2995 mov eax,[icondata] 2996 cmp [LastIconset],eax 2997 je short noreset2 2998 push eax 2999 call Init_Stamps 3000 pop eax // Clean up stack. ST - 12/20/2018 10:42AM 3001 noreset2: 3002 3003 ; Determine if the icon number requested is actually in the set. 3004 ; Perform the logical icon to actual icon number remap if necessary. 3005 mov ebx,[icon] 3006 cmp [MapPtr],0 3007 je short notmap2 3008 mov edi,[MapPtr] 3009 mov bl,[edi+ebx] 3010 notmap2: 3011 cmp ebx,[IconCount] 3012 jae proc_out 3013 mov [icon],ebx ; Updated icon number. 3014 3015 ; Setup some working variables. 3016 mov ecx,[IconHeight] ; Row counter. 3017 mov eax,[IconWidth] 3018 mov [iwidth],eax ; Stack copy of byte width for easy BP access. 3019 3020 ; Fetch pointer to start of icon's data. ESI = ptr to icon data. 3021 mov eax,[icon] 3022 mul [IconSize] 3023 mov esi,[StampPtr] 3024 add esi,eax 3025 3026 ; Update the clipping window coordinates to be valid maxes instead of width & height 3027 ; , and change the coordinates to be window-relative 3028 mov ebx,[min_x] 3029 add [max_x],ebx 3030 add [x_pixel],ebx ; make it window-relative 3031 mov ebx,[min_y] 3032 add [max_y],ebx 3033 add [y_pixel],ebx ; make it window-relative 3034 3035 ; See if the icon is within the clipping window 3036 ; First, verify that the icon position is less than the maximums 3037 mov ebx,[x_pixel] 3038 cmp ebx,[max_x] 3039 jge proc_out 3040 mov ebx,[y_pixel] 3041 cmp ebx,[max_y] 3042 jge proc_out 3043 ; Now verify that the icon position is >= the minimums 3044 add ebx,[IconHeight] 3045 cmp ebx,[min_y] 3046 jle proc_out 3047 mov ebx,[x_pixel] 3048 add ebx,[IconWidth] 3049 cmp ebx,[min_x] 3050 jle proc_out 3051 3052 ; Now, clip the x, y, width, and height variables to be within the 3053 ; clipping rectangle 3054 mov ebx,[x_pixel] 3055 cmp ebx,[min_x] 3056 jge nominxclip 3057 ; x < minx, so must clip 3058 mov ebx,[min_x] 3059 sub ebx,[x_pixel] 3060 add esi,ebx ; source ptr += (minx - x) 3061 sub [iwidth],ebx ; icon width -= (minx - x) 3062 mov ebx,[min_x] 3063 mov [x_pixel],ebx 3064 3065 nominxclip: 3066 mov eax,[IconWidth] 3067 sub eax,[iwidth] 3068 mov [skip],eax 3069 3070 ; Check for x+width > max_x 3071 mov eax,[x_pixel] 3072 add eax,[iwidth] 3073 cmp eax,[max_x] 3074 jle nomaxxclip 3075 ; x+width is greater than max_x, so must clip width down 3076 mov eax,[iwidth] ; eax = old width 3077 mov ebx,[max_x] 3078 sub ebx,[x_pixel] 3079 mov [iwidth],ebx ; iwidth = max_x - xpixel 3080 sub eax,ebx 3081 add [skip],eax ; skip += (old width - iwidth) 3082 nomaxxclip: 3083 ; check if y < miny 3084 mov eax,[min_y] 3085 cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed 3086 jle nominyclip 3087 sub eax,[y_pixel] 3088 sub ecx,eax ; height -= (miny - y) 3089 mul [IconWidth] 3090 add esi,eax ; icon source ptr += (width * (miny - y)) 3091 mov eax,[min_y] 3092 mov [y_pixel],eax ; y = miny 3093 nominyclip: 3094 ; check if (y+height) > max y 3095 mov eax,[y_pixel] 3096 add eax,ecx 3097 cmp eax,[max_y] ; if (y + height <= max_y), no clip needed 3098 jle nomaxyclip 3099 mov ecx,[max_y] ; height = max_y - y_pixel 3100 sub ecx,[y_pixel] 3101 nomaxyclip: 3102 3103 ; If the remap table pointer passed in is NULL, then flag this condition 3104 ; so that the faster (non-remapping) icon draw loop will be used. 3105 cmp [remap],0 3106 setne [doremap] 3107 3108 ; Get pointer to position to render icon. EDI = ptr to destination page. 3109 mov ebx,[this_object] 3110 mov edi,[ebx]GraphicViewPortClass.Offset 3111 mov eax,[ebx]GraphicViewPortClass.Width 3112 add eax,[ebx]GraphicViewPortClass.XAdd 3113 add eax,[ebx]GraphicViewPortClass.Pitch 3114 push eax ; save viewport full width for lower 3115 mul [y_pixel] 3116 add edi,eax 3117 add edi,[x_pixel] 3118 3119 ; Determine row modulo for advancing to next line. 3120 pop eax ; retrieve viewport width 3121 sub eax,[iwidth] 3122 mov [modulo],eax 3123 3124 ; Determine whether simple icon draw is sufficient or whether the 3125 ; extra remapping icon draw is needed. 3126 cmp [BYTE PTR doremap],0 3127 je short istranscheck2 3128 3129 ;************************************************************ 3130 ; Complex icon draw -- extended remap. 3131 ; EBX = Palette pointer (ready for XLAT instruction). 3132 ; EDI = Pointer to icon destination in page. 3133 ; ESI = Pointer to icon data. 3134 ; ECX = Number of pixel rows. 3135 mov ebx,[remap] 3136 xor eax,eax 3137 xrowloopc: 3138 push ecx 3139 mov ecx,[iwidth] 3140 3141 xcolumnloopc: 3142 lodsb 3143 xlatb 3144 or al,al 3145 jz short xskip1c ; Transparency skip check. 3146 mov [edi],al 3147 xskip1c: 3148 inc edi 3149 loop xcolumnloopc 3150 3151 pop ecx 3152 add edi,[modulo] 3153 add esi,[skip] 3154 loop xrowloopc 3155 jmp short proc_out 3156 3157 3158 ;************************************************************ 3159 ; Check to see if transparent or generic draw is necessary. 3160 istranscheck2: 3161 mov ebx,[IsTrans] 3162 add ebx,[icon] 3163 cmp [BYTE PTR ebx],0 3164 jne short rowloopc 3165 3166 ;************************************************************ 3167 ; Fast non-transparent icon draw routine. 3168 ; ES:DI = Pointer to icon destination in page. 3169 ; DS:SI = Pointer to icon data. 3170 ; CX = Number of pixel rows. 3171 mov ebx,ecx 3172 mov edx,[modulo] 3173 mov eax,[iwidth] 3174 3175 ; 3176 ; Optimise copy by dword aligning the destination 3177 ; 3178 loop1c: 3179 push eax 3180 //rept 3 // No rept in inline asm. ST - 12/20/2018 10:43AM 3181 test edi,3 3182 jz aligned 3183 movsb 3184 dec eax 3185 jz finishedit 3186 3187 test edi,3 3188 jz aligned 3189 movsb 3190 dec eax 3191 jz finishedit 3192 3193 test edi,3 3194 jz aligned 3195 movsb 3196 dec eax 3197 jz finishedit 3198 3199 //endm 3200 aligned: 3201 mov ecx,eax 3202 shr ecx,2 3203 rep movsd 3204 mov ecx,eax 3205 and ecx,3 3206 rep movsb 3207 3208 finishedit: 3209 add edi,edx 3210 add esi,[skip] 3211 pop eax 3212 3213 dec ebx 3214 jnz loop1c 3215 jmp short proc_out 3216 3217 ;************************************************************ 3218 ; Transparent icon draw routine -- no extended remap. 3219 ; ES:DI = Pointer to icon destination in page. 3220 ; DS:SI = Pointer to icon data. 3221 ; CX = Number of pixel rows. 3222 rowloopc: 3223 push ecx 3224 mov ecx,[iwidth] 3225 3226 columnloopc: 3227 lodsb 3228 or al,al 3229 jz short skip1c ; Transparency check. 3230 mov [edi],al 3231 skip1c: 3232 inc edi 3233 loop columnloopc 3234 3235 pop ecx 3236 add edi,[modulo] 3237 add esi,[skip] 3238 loop rowloopc 3239 3240 ; Cleanup and exit icon drawing routine. 3241 proc_out: 3242 popad 3243 //ret 3244 } 3245 } 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); 3262 VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color); 3263 VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap); 3264 VOID __cdecl Buffer_Fill_Quad(void * thisptr, VOID *span_buff, int x0, int y0, int x1, int y1, 3265 int x2, int y2, int x3, int y3, int color); 3266 void __cdecl Buffer_Draw_Stamp(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap); 3267 void __cdecl Buffer_Draw_Stamp_Clip(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int ,int,int,int); 3268 void * __cdecl Get_Font_Palette_Ptr ( void ); 3269 3270 3271 /* 3272 ;*************************************************************************** 3273 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 3274 ;*************************************************************************** 3275 ;* * 3276 ;* Project Name : Westwood 32 bit Library * 3277 ;* * 3278 ;* File Name : REMAP.ASM * 3279 ;* * 3280 ;* Programmer : Phil W. Gorrow * 3281 ;* * 3282 ;* Start Date : July 1, 1994 * 3283 ;* * 3284 ;* Last Update : July 1, 1994 [PWG] * 3285 ;* * 3286 ;*-------------------------------------------------------------------------* 3287 ;* Functions: * 3288 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 3289 */ 3290 3291 3292 VOID __cdecl Buffer_Remap(void * this_object, int sx, int sy, int width, int height, void *remap) 3293 { 3294 /* 3295 PROC Buffer_Remap C NEAR 3296 USES eax,ebx,ecx,edx,esi,edi 3297 3298 ;*=================================================================== 3299 ;* Define the arguements that our function takes. 3300 ;*=================================================================== 3301 ARG this_object:DWORD 3302 ARG x0_pixel:DWORD 3303 ARG y0_pixel:DWORD 3304 ARG region_width:DWORD 3305 ARG region_height:DWORD 3306 ARG remap :DWORD 3307 3308 ;*=================================================================== 3309 ; Define some locals so that we can handle things quickly 3310 ;*=================================================================== 3311 local x1_pixel : DWORD 3312 local y1_pixel : DWORD 3313 local win_width : dword 3314 local counter_x : dword 3315 */ 3316 3317 unsigned int x0_pixel = (unsigned int) sx; 3318 unsigned int y0_pixel = (unsigned int) sy; 3319 unsigned int region_width = (unsigned int) width; 3320 unsigned int region_height = (unsigned int) height; 3321 3322 unsigned int x1_pixel = 0; 3323 unsigned int y1_pixel = 0; 3324 unsigned int win_width = 0; 3325 unsigned int counter_x = 0; 3326 3327 __asm { 3328 3329 cmp [ remap ] , 0 3330 jz real_out 3331 3332 ; Clip Source Rectangle against source Window boundaries. 3333 mov esi , [ this_object ] ; get ptr to src 3334 xor ecx , ecx 3335 xor edx , edx 3336 mov edi , [esi]GraphicViewPortClass.Width ; get width into register 3337 mov ebx , [ x0_pixel ] 3338 mov eax , [ x0_pixel ] 3339 add ebx , [ region_width ] 3340 shld ecx , eax , 1 3341 mov [ x1_pixel ] , ebx 3342 inc edi 3343 shld edx , ebx , 1 3344 sub eax , edi 3345 sub ebx , edi 3346 shld ecx , eax , 1 3347 shld edx , ebx , 1 3348 3349 mov edi,[esi]GraphicViewPortClass.Height ; get height into register 3350 mov ebx , [ y0_pixel ] 3351 mov eax , [ y0_pixel ] 3352 add ebx , [ region_height ] 3353 shld ecx , eax , 1 3354 mov [ y1_pixel ] , ebx 3355 inc edi 3356 shld edx , ebx , 1 3357 sub eax , edi 3358 sub ebx , edi 3359 shld ecx , eax , 1 3360 shld edx , ebx , 1 3361 3362 xor cl , 5 3363 xor dl , 5 3364 mov al , cl 3365 test dl , cl 3366 jnz real_out 3367 or al , dl 3368 jz do_remap 3369 3370 test cl , 1000b 3371 jz scr_left_ok 3372 mov [ x0_pixel ] , 0 3373 3374 scr_left_ok: 3375 test cl , 0010b 3376 jz scr_bottom_ok 3377 mov [ y0_pixel ] , 0 3378 3379 scr_bottom_ok: 3380 test dl , 0100b 3381 jz scr_right_ok 3382 mov eax , [esi]GraphicViewPortClass.Width ; get width into register 3383 mov [ x1_pixel ] , eax 3384 scr_right_ok: 3385 test dl , 0001b 3386 jz do_remap 3387 mov eax , [esi]GraphicViewPortClass.Height ; get width into register 3388 mov [ y1_pixel ] , eax 3389 3390 3391 do_remap: 3392 cld 3393 mov edi , [esi]GraphicViewPortClass.Offset 3394 mov eax , [esi]GraphicViewPortClass.XAdd 3395 mov ebx , [ x1_pixel ] 3396 add eax , [esi]GraphicViewPortClass.Width 3397 add eax , [esi]GraphicViewPortClass.Pitch 3398 mov esi , eax 3399 mul [ y0_pixel ] 3400 add edi , [ x0_pixel ] 3401 sub ebx , [ x0_pixel ] 3402 jle real_out 3403 add edi , eax 3404 sub esi , ebx 3405 3406 mov ecx , [ y1_pixel ] 3407 sub ecx , [ y0_pixel ] 3408 jle real_out 3409 mov eax , [ remap ] 3410 mov [ counter_x ] , ebx 3411 xor edx , edx 3412 3413 outer_loop: 3414 mov ebx , [ counter_x ] 3415 inner_loop: 3416 mov dl , [ edi ] 3417 mov dl , [ eax + edx ] 3418 mov [ edi ] , dl 3419 inc edi 3420 dec ebx 3421 jnz inner_loop 3422 add edi , esi 3423 dec ecx 3424 jnz outer_loop 3425 3426 3427 3428 3429 real_out: 3430 // ret 3431 } 3432 } 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 /* 3449 ; ************************************************************************** 3450 ; ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S * 3451 ; ************************************************************************** 3452 ; * * 3453 ; * Project Name : WSA Support routines * 3454 ; * * 3455 ; * File Name : XORDELTA.ASM * 3456 ; * * 3457 ; * Programmer : Scott K. Bowen * 3458 ; * * 3459 ; * Last Update :May 23, 1994 [SKB] * 3460 ; * * 3461 ; *------------------------------------------------------------------------* 3462 ; * Functions: * 3463 ;* Apply_XOR_Delta -- Apply XOR delta data to a buffer. * 3464 ;* Apply_XOR_Delta_To_Page_Or_Viewport -- Calls the copy or the XOR funti* 3465 ;* Copy_Delta_buffer -- Copies XOR Delta Data to a section of a page. * 3466 ;* XOR_Delta_Buffer -- Xor's the data in a XOR Delta format to a page. * 3467 ; * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* 3468 3469 IDEAL 3470 P386 3471 MODEL USE32 FLAT 3472 */ 3473 3474 3475 /* 3476 LOCALS ?? 3477 3478 ; These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If 3479 ; These change, make sure and change their values in wsa.cpp. 3480 DO_XOR equ 0 3481 DO_COPY equ 1 3482 TO_VIEWPORT equ 0 3483 TO_PAGE equ 2 3484 3485 ; 3486 ; Routines defined in this module 3487 ; 3488 ; 3489 ; UWORD Apply_XOR_Delta(UWORD page_seg, BYTE *delta_ptr); 3490 ; PUBLIC Apply_XOR_Delta_To_Page_Or_Viewport(UWORD page_seg, BYTE *delta_ptr, WORD width, WORD copy) 3491 ; 3492 ; PROC C XOR_Delta_Buffer 3493 ; PROC C Copy_Delta_Buffer 3494 ; 3495 3496 GLOBAL C Apply_XOR_Delta:NEAR 3497 GLOBAL C Apply_XOR_Delta_To_Page_Or_Viewport:NEAR 3498 */ 3499 3500 #define DO_XOR 0 3501 #define DO_COPY 1 3502 #define TO_VIEWPORT 0 3503 #define TO_PAGE 2 3504 3505 void __cdecl XOR_Delta_Buffer(int nextrow); 3506 void __cdecl Copy_Delta_Buffer(int nextrow); 3507 3508 3509 /* 3510 ;*************************************************************************** 3511 ;* APPLY_XOR_DELTA -- Apply XOR delta data to a linear buffer. * 3512 ;* AN example of this in C is at the botton of the file commented out. * 3513 ;* * 3514 ;* INPUT: BYTE *target - destination buffer. * 3515 ;* BYTE *delta - xor data to be delta uncompress. * 3516 ;* * 3517 ;* OUTPUT: * 3518 ;* * 3519 ;* WARNINGS: * 3520 ;* * 3521 ;* HISTORY: * 3522 ;* 05/23/1994 SKB : Created. * 3523 ;*=========================================================================* 3524 */ 3525 unsigned int __cdecl Apply_XOR_Delta(char *target, char *delta) 3526 { 3527 /* 3528 PROC Apply_XOR_Delta C near 3529 USES ebx,ecx,edx,edi,esi 3530 ARG target:DWORD ; pointers. 3531 ARG delta:DWORD ; pointers. 3532 */ 3533 3534 __asm { 3535 3536 ; Optimized for 486/pentium by rearanging instructions. 3537 mov edi,[target] ; get our pointers into offset registers. 3538 mov esi,[delta] 3539 3540 cld ; make sure we go forward 3541 xor ecx,ecx ; use cx for loop 3542 3543 top_loop: 3544 xor eax,eax ; clear out eax. 3545 mov al,[esi] ; get delta source byte 3546 inc esi 3547 3548 test al,al ; check for a SHORTDUMP ; check al incase of sign value. 3549 je short_run 3550 js check_others 3551 3552 ; 3553 ; SHORTDUMP 3554 ; 3555 mov ecx,eax ; stick count in cx 3556 3557 dump_loop: 3558 mov al,[esi] ;get delta XOR byte 3559 xor [edi],al ; xor that byte on the dest 3560 inc esi 3561 inc edi 3562 dec ecx 3563 jnz dump_loop 3564 jmp top_loop 3565 3566 ; 3567 ; SHORTRUN 3568 ; 3569 3570 short_run: 3571 mov cl,[esi] ; get count 3572 inc esi ; inc delta source 3573 3574 do_run: 3575 mov al,[esi] ; get XOR byte 3576 inc esi 3577 3578 run_loop: 3579 xor [edi],al ; xor that byte. 3580 3581 inc edi ; go to next dest pixel 3582 dec ecx ; one less to go. 3583 jnz run_loop 3584 jmp top_loop 3585 3586 ; 3587 ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP 3588 ; 3589 3590 check_others: 3591 sub eax,080h ; opcode -= 0x80 3592 jnz do_skip ; if zero then get next word, otherwise use remainder. 3593 3594 mov ax,[esi] 3595 lea esi,[esi+2] ; get word code in ax 3596 test ax,ax ; set flags. (not 32bit register so neg flag works) 3597 jle not_long_skip 3598 3599 ; 3600 ; SHORTSKIP AND LONGSKIP 3601 ; 3602 do_skip: 3603 add edi,eax ; do the skip. 3604 jmp top_loop 3605 3606 3607 not_long_skip: 3608 jz stop ; long count of zero means stop 3609 sub eax,08000h ; opcode -= 0x8000 3610 test eax,04000h ; is it a LONGRUN (code & 0x4000)? 3611 je long_dump 3612 3613 ; 3614 ; LONGRUN 3615 ; 3616 sub eax,04000h ; opcode -= 0x4000 3617 mov ecx,eax ; use cx as loop count 3618 jmp do_run ; jump to run code. 3619 3620 3621 ; 3622 ; LONGDUMP 3623 ; 3624 3625 long_dump: 3626 mov ecx,eax ; use cx as loop count 3627 jmp dump_loop ; go to the dump loop. 3628 3629 stop: 3630 } 3631 } 3632 3633 3634 /* 3635 ;---------------------------------------------------------------------------- 3636 3637 ;*************************************************************************** 3638 ;* APPLY_XOR_DELTA_To_Page_Or_Viewport -- Calls the copy or the XOR funtion. * 3639 ;* * 3640 ;* * 3641 ;* This funtion is call to either xor or copy XOR_Delta data onto a * 3642 ;* page instead of a buffer. The routine will set up the registers * 3643 ;* need for the actual routines that will perform the copy or xor. * 3644 ;* * 3645 ;* The registers are setup as follows : * 3646 ;* es:edi - destination segment:offset onto page. * 3647 ;* ds:esi - source buffer segment:offset of delta data. * 3648 ;* dx,cx,ax - are all zeroed out before entry. * 3649 ;* * 3650 ;* INPUT: * 3651 ;* * 3652 ;* OUTPUT: * 3653 ;* * 3654 ;* WARNINGS: * 3655 ;* * 3656 ;* HISTORY: * 3657 ;* 03/09/1992 SB : Created. * 3658 ;*=========================================================================* 3659 */ 3660 3661 void __cdecl Apply_XOR_Delta_To_Page_Or_Viewport(void *target, void *delta, int width, int nextrow, int copy) 3662 { 3663 /* 3664 USES ebx,ecx,edx,edi,esi 3665 ARG target:DWORD ; pointer to the destination buffer. 3666 ARG delta:DWORD ; pointer to the delta buffer. 3667 ARG width:DWORD ; width of animation. 3668 ARG nextrow:DWORD ; Page/Buffer width - anim width. 3669 ARG copy:DWORD ; should it be copied or xor'd? 3670 */ 3671 3672 __asm { 3673 3674 mov edi,[target] ; Get the target pointer. 3675 mov esi,[delta] ; Get the destination pointer. 3676 3677 xor eax,eax ; clear eax, later put them into ecx and edx. 3678 3679 cld ; make sure we go forward 3680 3681 mov ebx,[nextrow] ; get the amount to add to get to next row from end. push it later... 3682 3683 mov ecx,eax ; use cx for loop 3684 mov edx,eax ; use dx to count the relative column. 3685 3686 push ebx ; push nextrow onto the stack for Copy/XOR_Delta_Buffer. 3687 mov ebx,[width] ; bx will hold the max column for speed compares 3688 3689 ; At this point, all the registers have been set up. Now call the correct function 3690 ; to either copy or xor the data. 3691 3692 cmp [copy],DO_XOR ; Do we want to copy or XOR 3693 je xorfunct ; Jump to XOR if not copy 3694 call Copy_Delta_Buffer ; Call the function to copy the delta buffer. 3695 jmp didcopy ; jump past XOR 3696 xorfunct: 3697 call XOR_Delta_Buffer ; Call funtion to XOR the deltat buffer. 3698 didcopy: 3699 pop ebx ; remove the push done to pass a value. 3700 } 3701 } 3702 3703 3704 /* 3705 ;---------------------------------------------------------------------------- 3706 3707 3708 ;*************************************************************************** 3709 ;* XOR_DELTA_BUFFER -- Xor's the data in a XOR Delta format to a page. * 3710 ;* This will only work right if the page has the previous data on it. * 3711 ;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * 3712 ;* The registers must be setup as follows : * 3713 ;* * 3714 ;* INPUT: * 3715 ;* es:edi - destination segment:offset onto page. * 3716 ;* ds:esi - source buffer segment:offset of delta data. * 3717 ;* edx,ecx,eax - are all zeroed out before entry. * 3718 ;* * 3719 ;* OUTPUT: * 3720 ;* * 3721 ;* WARNINGS: * 3722 ;* * 3723 ;* HISTORY: * 3724 ;* 03/09/1992 SB : Created. * 3725 ;*=========================================================================* 3726 */ 3727 void __cdecl XOR_Delta_Buffer(int nextrow) 3728 { 3729 /* 3730 ARG nextrow:DWORD 3731 */ 3732 3733 __asm { 3734 3735 top_loop: 3736 xor eax,eax ; clear out eax. 3737 mov al,[esi] ; get delta source byte 3738 inc esi 3739 3740 test al,al ; check for a SHORTDUMP ; check al incase of sign value. 3741 je short_run 3742 js check_others 3743 3744 ; 3745 ; SHORTDUMP 3746 ; 3747 mov ecx,eax ; stick count in cx 3748 3749 dump_loop: 3750 mov al,[esi] ; get delta XOR byte 3751 xor [edi],al ; xor that byte on the dest 3752 inc esi 3753 inc edx ; increment our count on current column 3754 inc edi 3755 cmp edx,ebx ; are we at the final column 3756 jne end_col1 ; if not the jmp over the code 3757 3758 sub edi,edx ; get our column back to the beginning. 3759 xor edx,edx ; zero out our column counter 3760 add edi,[nextrow] ; jump to start of next row 3761 end_col1: 3762 3763 dec ecx 3764 jnz dump_loop 3765 jmp top_loop 3766 3767 ; 3768 ; SHORTRUN 3769 ; 3770 3771 short_run: 3772 mov cl,[esi] ; get count 3773 inc esi ; inc delta source 3774 3775 do_run: 3776 mov al,[esi] ; get XOR byte 3777 inc esi 3778 3779 run_loop: 3780 xor [edi],al ; xor that byte. 3781 3782 inc edx ; increment our count on current column 3783 inc edi ; go to next dest pixel 3784 cmp edx,ebx ; are we at the final column 3785 jne end_col2 ; if not the jmp over the code 3786 3787 sub edi,ebx ; get our column back to the beginning. 3788 xor edx,edx ; zero out our column counter 3789 add edi,[nextrow] ; jump to start of next row 3790 end_col2: 3791 3792 3793 dec ecx 3794 jnz run_loop 3795 jmp top_loop 3796 3797 ; 3798 ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP 3799 ; 3800 3801 check_others: 3802 sub eax,080h ; opcode -= 0x80 3803 jnz do_skip ; if zero then get next word, otherwise use remainder. 3804 3805 mov ax,[esi] ; get word code in ax 3806 lea esi,[esi+2] 3807 test ax,ax ; set flags. (not 32bit register so neg flag works) 3808 jle not_long_skip 3809 3810 ; 3811 ; SHORTSKIP AND LONGSKIP 3812 ; 3813 do_skip: 3814 sub edi,edx ; go back to beginning or row. 3815 add edx,eax ; incriment our count on current row 3816 recheck3: 3817 cmp edx,ebx ; are we past the end of the row 3818 jb end_col3 ; if not the jmp over the code 3819 3820 sub edx,ebx ; Subtract width from the col counter 3821 add edi,[nextrow] ; jump to start of next row 3822 jmp recheck3 ; jump up to see if we are at the right row 3823 end_col3: 3824 add edi,edx ; get to correct position in row. 3825 jmp top_loop 3826 3827 3828 not_long_skip: 3829 jz stop ; long count of zero means stop 3830 sub eax,08000h ; opcode -= 0x8000 3831 test eax,04000h ; is it a LONGRUN (code & 0x4000)? 3832 je long_dump 3833 3834 ; 3835 ; LONGRUN 3836 ; 3837 sub eax,04000h ; opcode -= 0x4000 3838 mov ecx,eax ; use cx as loop count 3839 jmp do_run ; jump to run code. 3840 3841 3842 ; 3843 ; LONGDUMP 3844 ; 3845 3846 long_dump: 3847 mov ecx,eax ; use cx as loop count 3848 jmp dump_loop ; go to the dump loop. 3849 3850 stop: 3851 3852 } 3853 } 3854 3855 3856 /* 3857 ;---------------------------------------------------------------------------- 3858 3859 3860 ;*************************************************************************** 3861 ;* COPY_DELTA_BUFFER -- Copies XOR Delta Data to a section of a page. * 3862 ;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. * 3863 ;* The registers must be setup as follows : * 3864 ;* * 3865 ;* INPUT: * 3866 ;* es:edi - destination segment:offset onto page. * 3867 ;* ds:esi - source buffer segment:offset of delta data. * 3868 ;* dx,cx,ax - are all zeroed out before entry. * 3869 ;* * 3870 ;* OUTPUT: * 3871 ;* * 3872 ;* WARNINGS: * 3873 ;* * 3874 ;* HISTORY: * 3875 ;* 03/09/1992 SB : Created. * 3876 ;*=========================================================================* 3877 */ 3878 void __cdecl Copy_Delta_Buffer(int nextrow) 3879 { 3880 /* 3881 ARG nextrow:DWORD 3882 */ 3883 3884 __asm { 3885 3886 top_loop: 3887 xor eax,eax ; clear out eax. 3888 mov al,[esi] ; get delta source byte 3889 inc esi 3890 3891 test al,al ; check for a SHORTDUMP ; check al incase of sign value. 3892 je short_run 3893 js check_others 3894 3895 ; 3896 ; SHORTDUMP 3897 ; 3898 mov ecx,eax ; stick count in cx 3899 3900 dump_loop: 3901 mov al,[esi] ; get delta XOR byte 3902 3903 mov [edi],al ; store that byte on the dest 3904 3905 inc edx ; increment our count on current column 3906 inc esi 3907 inc edi 3908 cmp edx,ebx ; are we at the final column 3909 jne end_col1 ; if not the jmp over the code 3910 3911 sub edi,edx ; get our column back to the beginning. 3912 xor edx,edx ; zero out our column counter 3913 add edi,[nextrow] ; jump to start of next row 3914 end_col1: 3915 3916 dec ecx 3917 jnz dump_loop 3918 jmp top_loop 3919 3920 ; 3921 ; SHORTRUN 3922 ; 3923 3924 short_run: 3925 mov cl,[esi] ; get count 3926 inc esi ; inc delta source 3927 3928 do_run: 3929 mov al,[esi] ; get XOR byte 3930 inc esi 3931 3932 run_loop: 3933 mov [edi],al ; store the byte (instead of XOR against current color) 3934 3935 inc edx ; increment our count on current column 3936 inc edi ; go to next dest pixel 3937 cmp edx,ebx ; are we at the final column 3938 jne end_col2 ; if not the jmp over the code 3939 3940 sub edi,ebx ; get our column back to the beginning. 3941 xor edx,edx ; zero out our column counter 3942 add edi,[nextrow] ; jump to start of next row 3943 end_col2: 3944 3945 3946 dec ecx 3947 jnz run_loop 3948 jmp top_loop 3949 3950 ; 3951 ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP 3952 ; 3953 3954 check_others: 3955 sub eax,080h ; opcode -= 0x80 3956 jnz do_skip ; if zero then get next word, otherwise use remainder. 3957 3958 mov ax,[esi] ; get word code in ax 3959 lea esi,[esi+2] 3960 test ax,ax ; set flags. (not 32bit register so neg flag works) 3961 jle not_long_skip 3962 3963 ; 3964 ; SHORTSKIP AND LONGSKIP 3965 ; 3966 do_skip: 3967 sub edi,edx ; go back to beginning or row. 3968 add edx,eax ; incriment our count on current row 3969 recheck3: 3970 cmp edx,ebx ; are we past the end of the row 3971 jb end_col3 ; if not the jmp over the code 3972 3973 sub edx,ebx ; Subtract width from the col counter 3974 add edi,[nextrow] ; jump to start of next row 3975 jmp recheck3 ; jump up to see if we are at the right row 3976 end_col3: 3977 add edi,edx ; get to correct position in row. 3978 jmp top_loop 3979 3980 3981 not_long_skip: 3982 jz stop ; long count of zero means stop 3983 sub eax,08000h ; opcode -= 0x8000 3984 test eax,04000h ; is it a LONGRUN (code & 0x4000)? 3985 je long_dump 3986 3987 ; 3988 ; LONGRUN 3989 ; 3990 sub eax,04000h ; opcode -= 0x4000 3991 mov ecx,eax ; use cx as loop count 3992 jmp do_run ; jump to run code. 3993 3994 3995 ; 3996 ; LONGDUMP 3997 ; 3998 3999 long_dump: 4000 mov ecx,eax ; use cx as loop count 4001 jmp dump_loop ; go to the dump loop. 4002 4003 stop: 4004 4005 } 4006 } 4007 /* 4008 ;---------------------------------------------------------------------------- 4009 */ 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 /* 4033 ;*************************************************************************** 4034 ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** 4035 ;*************************************************************************** 4036 ;* * 4037 ;* Project Name : Westwood Library * 4038 ;* * 4039 ;* File Name : FADING.ASM * 4040 ;* * 4041 ;* Programmer : Joe L. Bostic * 4042 ;* * 4043 ;* Start Date : August 20, 1993 * 4044 ;* * 4045 ;* Last Update : August 20, 1993 [JLB] * 4046 ;* * 4047 ;*-------------------------------------------------------------------------* 4048 ;* Functions: * 4049 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 4050 4051 IDEAL 4052 P386 4053 MODEL USE32 FLAT 4054 4055 GLOBAL C Build_Fading_Table :NEAR 4056 4057 CODESEG 4058 4059 ;*********************************************************** 4060 ; BUILD_FADING_TABLE 4061 ; 4062 ; void *Build_Fading_Table(void *palette, void *dest, long int color, long int frac); 4063 ; 4064 ; This routine will create the fading effect table used to coerce colors 4065 ; from toward a common value. This table is used when Fading_Effect is 4066 ; active. 4067 ; 4068 ; Bounds Checking: None 4069 ;* 4070 */ 4071 void * __cdecl Build_Fading_Table(void const *palette, void const *dest, long int color, long int frac) 4072 { 4073 /* 4074 PROC Build_Fading_Table C near 4075 USES ebx, ecx, edi, esi 4076 ARG palette:DWORD 4077 ARG dest:DWORD 4078 ARG color:DWORD 4079 ARG frac:DWORD 4080 4081 LOCAL matchvalue:DWORD ; Last recorded match value. 4082 LOCAL targetred:BYTE ; Target gun red. 4083 LOCAL targetgreen:BYTE ; Target gun green. 4084 LOCAL targetblue:BYTE ; Target gun blue. 4085 LOCAL idealred:BYTE 4086 LOCAL idealgreen:BYTE 4087 LOCAL idealblue:BYTE 4088 LOCAL matchcolor:BYTE ; Tentative match color. 4089 */ 4090 4091 int matchvalue = 0; //:DWORD ; Last recorded match value. 4092 unsigned char targetred = 0; //BYTE ; Target gun red. 4093 unsigned char targetgreen = 0; //BYTE ; Target gun green. 4094 unsigned char targetblue = 0; //BYTE ; Target gun blue. 4095 unsigned char idealred = 0; //BYTE 4096 unsigned char idealgreen = 0; //BYTE 4097 unsigned char idealblue = 0; //BYTE 4098 unsigned char matchcolor = 0; //:BYTE ; Tentative match color. 4099 4100 __asm { 4101 cld 4102 4103 ; If the source palette is NULL, then just return with current fading table pointer. 4104 cmp [palette],0 4105 je fini 4106 cmp [dest],0 4107 je fini 4108 4109 ; Fractions above 255 become 255. 4110 mov eax,[frac] 4111 cmp eax,0100h 4112 jb short ok 4113 mov [frac],0FFh 4114 ok: 4115 4116 ; Record the target gun values. 4117 mov esi,[palette] 4118 mov ebx,[color] 4119 add esi,ebx 4120 add esi,ebx 4121 add esi,ebx 4122 lodsb 4123 mov [targetred],al 4124 lodsb 4125 mov [targetgreen],al 4126 lodsb 4127 mov [targetblue],al 4128 4129 ; Main loop. 4130 xor ebx,ebx ; Remap table index. 4131 4132 ; Transparent black never gets remapped. 4133 mov edi,[dest] 4134 mov [edi],bl 4135 inc edi 4136 4137 ; EBX = source palette logical number (1..255). 4138 ; EDI = running pointer into dest remap table. 4139 mainloop: 4140 inc ebx 4141 mov esi,[palette] 4142 add esi,ebx 4143 add esi,ebx 4144 add esi,ebx 4145 4146 mov edx,[frac] 4147 shr edx,1 4148 ; new = orig - ((orig-target) * fraction); 4149 4150 lodsb ; orig 4151 mov dh,al ; preserve it for later. 4152 sub al,[targetred] ; al = (orig-target) 4153 imul dl ; ax = (orig-target)*fraction 4154 shl ax,1 4155 sub dh,ah ; dh = orig - ((orig-target) * fraction) 4156 mov [idealred],dh ; preserve ideal color gun value. 4157 4158 lodsb ; orig 4159 mov dh,al ; preserve it for later. 4160 sub al,[targetgreen] ; al = (orig-target) 4161 imul dl ; ax = (orig-target)*fraction 4162 shl ax,1 4163 sub dh,ah ; dh = orig - ((orig-target) * fraction) 4164 mov [idealgreen],dh ; preserve ideal color gun value. 4165 4166 lodsb ; orig 4167 mov dh,al ; preserve it for later. 4168 sub al,[targetblue] ; al = (orig-target) 4169 imul dl ; ax = (orig-target)*fraction 4170 shl ax,1 4171 sub dh,ah ; dh = orig - ((orig-target) * fraction) 4172 mov [idealblue],dh ; preserve ideal color gun value. 4173 4174 ; Sweep through the entire existing palette to find the closest 4175 ; matching color. Never matches with color 0. 4176 4177 mov eax,[color] 4178 mov [matchcolor],al ; Default color (self). 4179 mov [matchvalue],-1 ; Ridiculous match value init. 4180 mov ecx,255 4181 4182 mov esi,[palette] ; Pointer to original palette. 4183 add esi,3 4184 4185 ; BH = color index. 4186 mov bh,1 4187 innerloop: 4188 4189 ; Recursion through the fading table won't work if a color is allowed 4190 ; to remap to itself. Prevent this from occuring. 4191 add esi,3 4192 cmp bh,bl 4193 je short notclose 4194 sub esi,3 4195 4196 xor edx,edx ; Comparison value starts null. 4197 mov eax,edx 4198 ; Build the comparison value based on the sum of the differences of the color 4199 ; guns squared. 4200 lodsb 4201 sub al,[idealred] 4202 mov ah,al 4203 imul ah 4204 add edx,eax 4205 4206 lodsb 4207 sub al,[idealgreen] 4208 mov ah,al 4209 imul ah 4210 add edx,eax 4211 4212 lodsb 4213 sub al,[idealblue] 4214 mov ah,al 4215 imul ah 4216 add edx,eax 4217 jz short perfect ; If perfect match found then quit early. 4218 4219 cmp edx,[matchvalue] 4220 ja short notclose 4221 mov [matchvalue],edx ; Record new possible color. 4222 mov [matchcolor],bh 4223 notclose: 4224 inc bh ; Checking color index. 4225 loop innerloop 4226 mov bh,[matchcolor] 4227 perfect: 4228 mov [matchcolor],bh 4229 xor bh,bh ; Make BX valid main index again. 4230 4231 ; When the loop exits, we have found the closest match. 4232 mov al,[matchcolor] 4233 stosb 4234 cmp ebx,255 4235 jne mainloop 4236 4237 fini: 4238 mov eax,[dest] 4239 // ret 4240 4241 4242 } 4243 } 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 /* 4269 ;*************************************************************************** 4270 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 4271 ;*************************************************************************** 4272 ;* * 4273 ;* Project Name : Westwood Library * 4274 ;* * 4275 ;* File Name : PAL.ASM * 4276 ;* * 4277 ;* Programmer : Joe L. Bostic * 4278 ;* * 4279 ;* Start Date : May 30, 1992 * 4280 ;* * 4281 ;* Last Update : April 27, 1994 [BR] * 4282 ;* * 4283 ;*-------------------------------------------------------------------------* 4284 ;* Functions: * 4285 ;* Set_Palette_Range -- Sets changed values in the palette. * 4286 ;* Bump_Color -- adjusts specified color in specified palette * 4287 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 4288 ;********************** Model & Processor Directives ************************ 4289 IDEAL 4290 P386 4291 MODEL USE32 FLAT 4292 4293 4294 ;include "keyboard.inc" 4295 FALSE = 0 4296 TRUE = 1 4297 4298 ;****************************** Declarations ******************************** 4299 GLOBAL C Set_Palette_Range:NEAR 4300 GLOBAL C Bump_Color:NEAR 4301 GLOBAL C CurrentPalette:BYTE:768 4302 GLOBAL C PaletteTable:byte:1024 4303 4304 4305 ;********************************** Data ************************************ 4306 LOCALS ?? 4307 4308 DATASEG 4309 4310 CurrentPalette DB 768 DUP(255) ; copy of current values of DAC regs 4311 PaletteTable DB 1024 DUP(0) 4312 4313 IFNDEF LIB_EXTERNS_RESOLVED 4314 VertBlank DW 0 ; !!!! this should go away 4315 ENDIF 4316 4317 4318 ;********************************** Code ************************************ 4319 CODESEG 4320 */ 4321 4322 extern "C" unsigned char CurrentPalette[768] = {255}; // DB 768 DUP(255) ; copy of current values of DAC regs 4323 extern "C" unsigned char PaletteTable[1024] = {0}; // DB 1024 DUP(0) 4324 4325 4326 /* 4327 ;*************************************************************************** 4328 ;* SET_PALETTE_RANGE -- Sets a palette range to the new pal * 4329 ;* * 4330 ;* INPUT: * 4331 ;* * 4332 ;* OUTPUT: * 4333 ;* * 4334 ;* PROTO: * 4335 ;* * 4336 ;* WARNINGS: This routine is optimized for changing a small number of * 4337 ;* colors in the palette. 4338 ;* * 4339 ;* HISTORY: * 4340 ;* 03/07/1995 PWG : Created. * 4341 ;*=========================================================================* 4342 */ 4343 void __cdecl Set_Palette_Range(void *palette) 4344 { 4345 memcpy(CurrentPalette, palette, 768); 4346 Set_DD_Palette(palette); 4347 4348 /* 4349 PROC Set_Palette_Range C NEAR 4350 ARG palette:DWORD 4351 4352 GLOBAL Set_DD_Palette_:near 4353 GLOBAL Wait_Vert_Blank_:near 4354 4355 pushad 4356 mov esi,[palette] 4357 mov ecx,768/4 4358 mov edi,offset CurrentPalette 4359 cld 4360 rep movsd 4361 ;call Wait_Vert_Blank_ 4362 mov eax,[palette] 4363 push eax 4364 call Set_DD_Palette_ 4365 pop eax 4366 popad 4367 ret 4368 */ 4369 } 4370 4371 4372 /* 4373 ;*************************************************************************** 4374 ;* Bump_Color -- adjusts specified color in specified palette * 4375 ;* * 4376 ;* INPUT: * 4377 ;* VOID *palette - palette to modify * 4378 ;* WORD changable - color # to change * 4379 ;* WORD target - color to bend toward * 4380 ;* * 4381 ;* OUTPUT: * 4382 ;* * 4383 ;* WARNINGS: * 4384 ;* * 4385 ;* HISTORY: * 4386 ;* 04/27/1994 BR : Converted to 32-bit. * 4387 ;*=========================================================================* 4388 ; BOOL cdecl Bump_Color(VOID *palette, WORD changable, WORD target); 4389 */ 4390 BOOL __cdecl Bump_Color(void *pal, int color, int desired) 4391 { 4392 /* 4393 PROC Bump_Color C NEAR 4394 USES ebx,ecx,edi,esi 4395 ARG pal:DWORD, color:WORD, desired:WORD 4396 LOCAL changed:WORD ; Has palette changed? 4397 */ 4398 4399 short short_color = (short) color; 4400 short short_desired = (short) desired; 4401 bool changed = false; 4402 4403 __asm { 4404 mov edi,[pal] ; Original palette pointer. 4405 mov esi,edi 4406 mov eax,0 4407 mov ax,[short_color] 4408 add edi,eax 4409 add edi,eax 4410 add edi,eax ; Offset to changable color. 4411 mov ax,[short_desired] 4412 add esi,eax 4413 add esi,eax 4414 add esi,eax ; Offset to target color. 4415 4416 mov [changed],FALSE ; Presume no change. 4417 mov ecx,3 ; Three color guns. 4418 4419 ; Check the color gun. 4420 colorloop: 4421 mov al,[BYTE PTR esi] 4422 sub al,[BYTE PTR edi] ; Carry flag is set if subtraction needed. 4423 jz short gotit 4424 mov [changed],TRUE 4425 inc [BYTE PTR edi] ; Presume addition. 4426 jnc short gotit ; oops, subtraction needed so dec twice. 4427 dec [BYTE PTR edi] 4428 dec [BYTE PTR edi] 4429 gotit: 4430 inc edi 4431 inc esi 4432 loop colorloop 4433 4434 movzx eax,[changed] 4435 } 4436 } 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 /* 4453 ;*************************************************************************** 4454 ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** 4455 ;*************************************************************************** 4456 ;* * 4457 ;* Project Name : GraphicViewPortClass * 4458 ;* * 4459 ;* File Name : PUTPIXEL.ASM * 4460 ;* * 4461 ;* Programmer : Phil Gorrow * 4462 ;* * 4463 ;* Start Date : June 7, 1994 * 4464 ;* * 4465 ;* Last Update : June 8, 1994 [PWG] * 4466 ;* * 4467 ;*-------------------------------------------------------------------------* 4468 ;* Functions: * 4469 ;* VVPC::Put_Pixel -- Puts a pixel on a virtual viewport * 4470 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 4471 4472 IDEAL 4473 P386 4474 MODEL USE32 FLAT 4475 4476 INCLUDE ".\drawbuff.inc" 4477 INCLUDE ".\gbuffer.inc" 4478 4479 4480 CODESEG 4481 */ 4482 4483 /* 4484 ;*************************************************************************** 4485 ;* VVPC::PUT_PIXEL -- Puts a pixel on a virtual viewport * 4486 ;* * 4487 ;* INPUT: WORD the x position for the pixel relative to the upper * 4488 ;* left corner of the viewport * 4489 ;* WORD the y pos for the pixel relative to the upper left * 4490 ;* corner of the viewport * 4491 ;* UBYTE the color of the pixel to write * 4492 ;* * 4493 ;* OUTPUT: none * 4494 ;* * 4495 ;* WARNING: If pixel is to be placed outside of the viewport then * 4496 ;* this routine will abort. * 4497 ;* * 4498 ;* HISTORY: * 4499 ;* 06/08/1994 PWG : Created. * 4500 ;*=========================================================================* 4501 PROC Buffer_Put_Pixel C near 4502 USES eax,ebx,ecx,edx,edi 4503 */ 4504 4505 void __cdecl Buffer_Put_Pixel(void * this_object, int x_pixel, int y_pixel, unsigned char color) 4506 { 4507 4508 /* 4509 ARG this_object:DWORD ; this is a member function 4510 ARG x_pixel:DWORD ; x position of pixel to set 4511 ARG y_pixel:DWORD ; y position of pixel to set 4512 ARG color:BYTE ; what color should we clear to 4513 */ 4514 4515 __asm { 4516 4517 4518 ;*=================================================================== 4519 ; Get the viewport information and put bytes per row in ecx 4520 ;*=================================================================== 4521 mov ebx,[this_object] ; get a pointer to viewport 4522 xor eax,eax 4523 mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset 4524 mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport 4525 mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport 4526 4527 ;*=================================================================== 4528 ; Verify that the X pixel offset if legal 4529 ;*=================================================================== 4530 mov eax,[x_pixel] ; find the x position 4531 cmp eax,edx ; is it out of bounds 4532 jae short done ; if so then get out 4533 add edi,eax ; otherwise add in offset 4534 4535 ;*=================================================================== 4536 ; Verify that the Y pixel offset if legal 4537 ;*=================================================================== 4538 mov eax,[y_pixel] ; get the y position 4539 cmp eax,ecx ; is it out of bounds 4540 jae done ; if so then get out 4541 add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row 4542 add edx,[ebx]GraphicViewPortClass.Pitch ; add in direct draw pitch 4543 mul edx ; offset = bytes per row * y 4544 add edi,eax ; add it into the offset 4545 4546 ;*=================================================================== 4547 ; Write the pixel to the screen 4548 ;*=================================================================== 4549 mov al,[color] ; read in color value 4550 mov [edi],al ; write it to the screen 4551 done: 4552 } 4553 } 4554 4555 4556 4557 4558 4559 4560 4561 4562 /* 4563 ;*************************************************************************** 4564 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 4565 ;*************************************************************************** 4566 ;* * 4567 ;* Project Name : Support Library * 4568 ;* * 4569 ;* File Name : cliprect.asm * 4570 ;* * 4571 ;* Programmer : Julio R Jerez * 4572 ;* * 4573 ;* Start Date : Mar, 2 1995 * 4574 ;* * 4575 ;* * 4576 ;*-------------------------------------------------------------------------* 4577 ;* Functions: * 4578 ;* int Clip_Rect ( int * x , int * y , int * dw , int * dh , * 4579 ;* int width , int height ) ; * 4580 ;* int Confine_Rect ( int * x , int * y , int * dw , int * dh , * 4581 ;* int width , int height ) ; * 4582 ;* * 4583 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 4584 4585 4586 IDEAL 4587 P386 4588 MODEL USE32 FLAT 4589 4590 GLOBAL C Clip_Rect :NEAR 4591 GLOBAL C Confine_Rect :NEAR 4592 4593 CODESEG 4594 4595 ;*************************************************************************** 4596 ;* Clip_Rect -- clip a given rectangle against a given window * 4597 ;* * 4598 ;* INPUT: &x , &y , &w , &h -> Pointer to rectangle being clipped * 4599 ;* width , height -> dimension of clipping window * 4600 ;* * 4601 ;* OUTPUT: a) Zero if the rectangle is totally contained by the * 4602 ;* clipping window. * 4603 ;* b) A negative value if the rectangle is totally outside the * 4604 ;* the clipping window * 4605 ;* c) A positive value if the rectangle was clipped against the * 4606 ;* clipping window, also the values pointed by x, y, w, h will * 4607 ;* be modified to new clipped values * 4608 ;* * 4609 ;* 05/03/1995 JRJ : added comment * 4610 ;*=========================================================================* 4611 ; int Clip_Rect (int* x, int* y, int* dw, int* dh, int width, int height); * 4612 */ 4613 4614 extern "C" int __cdecl Clip_Rect ( int * x , int * y , int * w , int * h , int width , int height ) 4615 { 4616 4617 /* 4618 PROC Clip_Rect C near 4619 uses ebx,ecx,edx,esi,edi 4620 arg x:dword 4621 arg y:dword 4622 arg w:dword 4623 arg h:dword 4624 arg width:dword 4625 arg height:dword 4626 */ 4627 4628 __asm { 4629 4630 ;This Clipping algorithm is a derivation of the very well known 4631 ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency 4632 ;it is probably the most commontly implemented algorithm both in software 4633 ;and hardware for clipping lines, rectangles, and convex polygons against 4634 ;a rectagular clipping window. For reference see 4635 ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes 4636 ; pages 113 to 177". 4637 ; Briefly consist in computing the Sutherland code for both end point of 4638 ; the rectangle to find out if the rectangle is: 4639 ; - trivially accepted (no further clipping test, return the oroginal data) 4640 ; - trivially rejected (return with no action, return error code) 4641 ; - retangle must be iteratively clipped again edges of the clipping window 4642 ; and return the clipped rectangle 4643 4644 ; get all four pointer into regisnters 4645 mov esi,[x] ; esi = pointer to x 4646 mov edi,[y] ; edi = pointer to x 4647 mov eax,[w] ; eax = pointer to dw 4648 mov ebx,[h] ; ebx = pointer to dh 4649 4650 ; load the actual data into reg 4651 mov esi,[esi] ; esi = x0 4652 mov edi,[edi] ; edi = y0 4653 mov eax,[eax] ; eax = dw 4654 mov ebx,[ebx] ; ebx = dh 4655 4656 ; create a wire frame of the type [x0,y0] , [x1,y1] 4657 add eax,esi ; eax = x1 = x0 + dw 4658 add ebx,edi ; ebx = y1 = y0 + dh 4659 4660 ; we start we suthenland code0 and code1 set to zero 4661 xor ecx,ecx ; cl = sutherland boolean code0 4662 xor edx,edx ; dl = sutherland boolean code0 4663 4664 ; now we start computing the to suthenland boolean code for x0 , x1 4665 shld ecx,esi,1 ; bit3 of code0 = sign bit of (x0 - 0) 4666 shld edx,eax,1 ; bit3 of code1 = sign bit of (x1 - 0) 4667 sub esi,[width] ; get the difference (x0 - (width + 1)) 4668 sub eax,[width] ; get the difference (x1 - (width + 1)) 4669 dec esi 4670 dec eax 4671 shld ecx,esi,1 ; bit2 of code0 = sign bit of (x0 - (width + 1)) 4672 shld edx,eax,1 ; bit2 of code1 = sign bit of (x0 - (width + 1)) 4673 4674 ; now we start computing the to suthenland boolean code for y0 , y1 4675 shld ecx,edi,1 ; bit1 of code0 = sign bit of (y0 - 0) 4676 shld edx,ebx,1 ; bit1 of code1 = sign bit of (y0 - 0) 4677 sub edi,[height] ; get the difference (y0 - (height + 1)) 4678 sub ebx,[height] ; get the difference (y1 - (height + 1)) 4679 dec edi 4680 dec ebx 4681 shld ecx,edi,1 ; bit0 of code0 = sign bit of (y0 - (height + 1)) 4682 shld edx,ebx,1 ; bit0 of code1 = sign bit of (y1 - (height + 1)) 4683 4684 ; Bit 2 and 0 of cl and bl are complemented 4685 xor cl,5 ; reverse bit2 and bit0 in code0 4686 xor dl,5 ; reverse bit2 and bit0 in code1 4687 4688 ; now perform the rejection test 4689 mov eax,-1 ; set return code to false 4690 mov bl,cl ; save code0 for future use 4691 test dl,cl ; if any two pair of bit in code0 and code1 is set 4692 jnz clip_out ; then rectangle is outside the window 4693 4694 ; now perform the aceptance test 4695 xor eax,eax ; set return code to true 4696 or bl,dl ; if all pair of bits in code0 and code1 are reset 4697 jz clip_out ; then rectangle is insize the window. ' 4698 4699 ; we need to clip the rectangle iteratively 4700 mov eax,-1 ; set return code to false 4701 test cl,1000b ; if bit3 of code0 is set then the rectangle 4702 jz left_ok ; spill out the left edge of the window 4703 mov edi,[x] ; edi = a pointer to x0 4704 mov ebx,[w] ; ebx = a pointer to dw 4705 mov esi,[edi] ; esi = x0 4706 mov [dword ptr edi],0 ; set x0 to 0 "this the left edge value" 4707 add [ebx],esi ; adjust dw by x0, since x0 must be negative 4708 4709 left_ok: 4710 test cl,0010b ; if bit1 of code0 is set then the rectangle 4711 jz bottom_ok ; spill out the bottom edge of the window 4712 mov edi,[y] ; edi = a pointer to y0 4713 mov ebx,[h] ; ebx = a pointer to dh 4714 mov esi,[edi] ; esi = y0 4715 mov [dword ptr edi],0 ; set y0 to 0 "this the bottom edge value" 4716 add [ebx],esi ; adjust dh by y0, since y0 must be negative 4717 4718 bottom_ok: 4719 test dl,0100b ; if bit2 of code1 is set then the rectangle 4720 jz right_ok ; spill out the right edge of the window 4721 mov edi,[w] ; edi = a pointer to dw 4722 mov esi,[x] ; esi = a pointer to x 4723 mov ebx,[width] ; ebx = the width of the window 4724 sub ebx,[esi] ; the new dw is the difference (width-x0) 4725 mov [edi],ebx ; adjust dw to (width - x0) 4726 jle clip_out ; if (width-x0) = 0 then the clipped retangle 4727 ; has no width we are done 4728 right_ok: 4729 test dl,0001b ; if bit0 of code1 is set then the rectangle 4730 jz clip_ok ; spill out the top edge of the window 4731 mov edi,[h] ; edi = a pointer to dh 4732 mov esi,[y] ; esi = a pointer to y0 4733 mov ebx,[height] ; ebx = the height of the window 4734 sub ebx,[esi] ; the new dh is the difference (height-y0) 4735 mov [edi],ebx ; adjust dh to (height-y0) 4736 jle clip_out ; if (width-x0) = 0 then the clipped retangle 4737 ; has no width we are done 4738 clip_ok: 4739 mov eax,1 ; signal the calling program that the rectangle was modify 4740 clip_out: 4741 //ret 4742 } 4743 4744 //ENDP Clip_Rect 4745 } 4746 4747 /* 4748 ;*************************************************************************** 4749 ;* Confine_Rect -- clip a given rectangle against a given window * 4750 ;* * 4751 ;* INPUT: &x,&y,w,h -> Pointer to rectangle being clipped * 4752 ;* width,height -> dimension of clipping window * 4753 ;* * 4754 ;* OUTPUT: a) Zero if the rectangle is totally contained by the * 4755 ;* clipping window. * 4756 ;* c) A positive value if the rectangle was shifted in position * 4757 ;* to fix inside the clipping window, also the values pointed * 4758 ;* by x, y, will adjusted to a new values * 4759 ;* * 4760 ;* NOTE: this function make not attempt to verify if the rectangle is * 4761 ;* bigger than the clipping window and at the same time wrap around* 4762 ;* it. If that is the case the result is meaningless * 4763 ;*=========================================================================* 4764 ; int Confine_Rect (int* x, int* y, int dw, int dh, int width, int height); * 4765 */ 4766 4767 extern "C" int __cdecl Confine_Rect ( int * x , int * y , int w , int h , int width , int height ) 4768 { 4769 4770 /* 4771 PROC Confine_Rect C near 4772 uses ebx, esi,edi 4773 arg x:dword 4774 arg y:dword 4775 arg w:dword 4776 arg h:dword 4777 arg width :dword 4778 arg height:dword 4779 */ 4780 __asm { 4781 4782 xor eax,eax 4783 mov ebx,[x] 4784 mov edi,[w] 4785 4786 mov esi,[ebx] 4787 add edi,[ebx] 4788 4789 sub edi,[width] 4790 neg esi 4791 dec edi 4792 4793 test esi,edi 4794 jl x_axix_ok 4795 mov eax,1 4796 4797 test esi,esi 4798 jl shift_right 4799 mov [dword ptr ebx],0 4800 jmp x_axix_ok 4801 shift_right: 4802 inc edi 4803 sub [ebx],edi 4804 x_axix_ok: 4805 mov ebx,[y] 4806 mov edi,[h] 4807 4808 mov esi,[ebx] 4809 add edi,[ebx] 4810 4811 sub edi,[height] 4812 neg esi 4813 dec edi 4814 4815 test esi,edi 4816 jl confi_out 4817 mov eax,1 4818 4819 test esi,esi 4820 jl shift_top 4821 mov [dword ptr ebx],0 4822 4823 //ret 4824 jmp confi_out 4825 shift_top: 4826 inc edi 4827 sub [ebx],edi 4828 confi_out: 4829 //ret 4830 4831 //ENDP Confine_Rect 4832 } 4833 } 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 /* 4844 ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp#139 $ 4845 ;*************************************************************************** 4846 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 4847 ;*************************************************************************** 4848 ;* * 4849 ;* Project Name : Library routine * 4850 ;* * 4851 ;* File Name : UNCOMP.ASM * 4852 ;* * 4853 ;* Programmer : Christopher Yates * 4854 ;* * 4855 ;* Last Update : 20 August, 1990 [CY] * 4856 ;* * 4857 ;*-------------------------------------------------------------------------* 4858 ;* Functions: * 4859 ;* * 4860 ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); * 4861 ;* * 4862 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 4863 4864 IDEAL 4865 P386 4866 MODEL USE32 FLAT 4867 4868 GLOBAL C LCW_Uncompress :NEAR 4869 4870 CODESEG 4871 4872 ; ---------------------------------------------------------------- 4873 ; 4874 ; Here are prototypes for the routines defined within this module: 4875 ; 4876 ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); 4877 ; 4878 ; ---------------------------------------------------------------- 4879 */ 4880 4881 extern "C" unsigned long __cdecl LCW_Uncompress(void *source, void *dest, unsigned long length_) 4882 { 4883 //PROC LCW_Uncompress C near 4884 // 4885 // USES ebx,ecx,edx,edi,esi 4886 // 4887 // ARG source:DWORD 4888 // ARG dest:DWORD 4889 // ARG length:DWORD 4890 //;LOCALS 4891 // LOCAL a1stdest:DWORD 4892 // LOCAL maxlen:DWORD 4893 // LOCAL lastbyte:DWORD 4894 // LOCAL lastcom:DWORD 4895 // LOCAL lastcom1:DWORD 4896 4897 unsigned long a1stdest; 4898 unsigned long maxlen; 4899 unsigned long lastbyte; 4900 //unsigned long lastcom; 4901 //unsigned long lastcom1; 4902 4903 __asm { 4904 4905 4906 mov edi,[dest] 4907 mov esi,[source] 4908 mov edx,[length_] 4909 4910 ; 4911 ; 4912 ; uncompress data to the following codes in the format b = byte, w = word 4913 ; n = byte code pulled from compressed data 4914 ; Bit field of n command description 4915 ; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3 4916 ; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes 4917 ; n=11xxxxxx,w1 med run run x+3 bytes from offset w1 4918 ; n=11111111,w1,w2 long copy copy w1 bytes from offset w2 4919 ; n=11111110,w1,b1 long run run byte b1 for w1 bytes 4920 ; n=10000000 end end of data reached 4921 ; 4922 4923 mov [a1stdest],edi 4924 add edx,edi 4925 mov [lastbyte],edx 4926 cld ; make sure all lod and sto are forward 4927 mov ebx,esi ; save the source offset 4928 4929 loop_label: 4930 mov eax,[lastbyte] 4931 sub eax,edi ; get the remaining byte to uncomp 4932 jz short out_label ; were done 4933 4934 mov [maxlen],eax ; save for string commands 4935 mov esi,ebx ; mov in the source index 4936 4937 xor eax,eax 4938 mov al,[esi] 4939 inc esi 4940 test al,al ; see if its a short run 4941 js short notshort 4942 4943 mov ecx,eax ;put count nibble in cl 4944 4945 mov ah,al ; put rel offset high nibble in ah 4946 and ah,0Fh ; only 4 bits count 4947 4948 shr cl,4 ; get run -3 4949 add ecx,3 ; get actual run length 4950 4951 cmp ecx,[maxlen] ; is it too big to fit? 4952 jbe short rsok ; if not, its ok 4953 4954 mov ecx,[maxlen] ; if so, max it out so it dosen't overrun 4955 4956 rsok: 4957 mov al,[esi] ; get rel offset low byte 4958 lea ebx,[esi+1] ; save the source offset 4959 mov esi,edi ; get the current dest 4960 sub esi,eax ; get relative offset 4961 4962 rep movsb 4963 4964 jmp loop_label 4965 4966 notshort: 4967 test al,40h ; is it a length? 4968 jne short notlength ; if not it could be med or long run 4969 4970 cmp al,80h ; is it the end? 4971 je short out_label ; if so its over 4972 4973 mov cl,al ; put the byte in count register 4974 and ecx,3Fh ; and off the extra bits 4975 4976 cmp ecx,[maxlen] ; is it too big to fit? 4977 jbe short lenok ; if not, its ok 4978 4979 mov ecx,[maxlen] ; if so, max it out so it dosen't overrun 4980 4981 lenok: 4982 rep movsb 4983 4984 mov ebx,esi ; save the source offset 4985 jmp loop_label 4986 4987 out_label: 4988 mov eax,edi 4989 sub eax,[a1stdest] 4990 jmp label_exit 4991 4992 notlength: 4993 mov cl,al ; get the entire code 4994 and ecx,3Fh ; and off all but the size -3 4995 add ecx,3 ; add 3 for byte count 4996 4997 cmp al,0FEh 4998 jne short notrunlength 4999 5000 xor ecx,ecx 5001 mov cx,[esi] 5002 5003 xor eax,eax 5004 mov al,[esi+2] 5005 lea ebx,[esi+3] ;save the source offset 5006 5007 cmp ecx,[maxlen] ; is it too big to fit? 5008 jbe short runlenok ; if not, its ok 5009 5010 mov ecx,[maxlen] ; if so, max it out so it dosen't overrun 5011 5012 runlenok: 5013 test ecx,0ffe0h 5014 jnz dont_use_stosb 5015 rep stosb 5016 jmp loop_label 5017 5018 5019 dont_use_stosb: 5020 mov ah,al 5021 mov edx,eax 5022 shl eax,16 5023 or eax,edx 5024 5025 test edi,3 5026 jz aligned 5027 5028 mov [edi],eax 5029 mov edx,edi 5030 and edi,0fffffffch 5031 lea edi,[edi+4] 5032 and edx,3 5033 dec dl 5034 xor dl,3 5035 sub ecx,edx 5036 5037 aligned: 5038 mov edx,ecx 5039 shr ecx,2 5040 rep stosd 5041 5042 and edx,3 5043 jz loop_label 5044 mov ecx,edx 5045 rep stosb 5046 jmp loop_label 5047 5048 5049 5050 5051 5052 5053 notrunlength: 5054 cmp al,0FFh ; is it a long run? 5055 jne short notlong ; if not use the code as the size 5056 5057 xor ecx,ecx 5058 xor eax,eax 5059 mov cx,[esi] ; if so, get the size 5060 lea esi,[esi+2] 5061 5062 notlong: 5063 mov ax,[esi] ;get the real index 5064 add eax,[a1stdest] ;add in the 1st index 5065 lea ebx,[esi+2] ;save the source offset 5066 cmp ecx,[maxlen] ;compare for overrun 5067 mov esi,eax ;use eax as new source 5068 jbe short runok ; if not, its ok 5069 5070 mov ecx,[maxlen] ; if so, max it out so it dosen't overrun 5071 5072 runok: 5073 test ecx,0ffe0h 5074 jnz dont_use_movsb 5075 rep movsb 5076 jmp loop_label 5077 5078 5079 5080 5081 dont_use_movsb: 5082 lea edx,[edi+0fffffffch] 5083 cmp esi,edx 5084 ja use_movsb 5085 5086 test edi,3 5087 jz aligned2 5088 5089 mov eax,[esi] 5090 mov [edi],eax 5091 mov edx,edi 5092 and edi,0fffffffch 5093 lea edi,[edi+4] 5094 and edx,3 5095 dec dl 5096 xor dl,3 5097 sub ecx,edx 5098 add esi,edx 5099 5100 aligned2: 5101 mov edx,ecx 5102 shr ecx,2 5103 and edx,3 5104 rep movsd 5105 mov ecx,edx 5106 use_movsb: 5107 rep movsb 5108 jmp loop_label 5109 5110 5111 5112 5113 label_exit: 5114 mov eax,edi 5115 mov ebx,[dest] 5116 sub eax,ebx 5117 5118 //ret 5119 5120 } 5121 } 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 /* 5137 ;*************************************************************************** 5138 ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 5139 ;*************************************************************************** 5140 ;* * 5141 ;* Project Name : Westwood 32 bit Library * 5142 ;* * 5143 ;* File Name : TOPAGE.ASM * 5144 ;* * 5145 ;* Programmer : Phil W. Gorrow * 5146 ;* * 5147 ;* Start Date : June 8, 1994 * 5148 ;* * 5149 ;* Last Update : June 15, 1994 [PWG] * 5150 ;* * 5151 ;*-------------------------------------------------------------------------* 5152 ;* Functions: * 5153 ;* Buffer_To_Page -- Copies a linear buffer to a virtual viewport * 5154 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 5155 5156 IDEAL 5157 P386 5158 MODEL USE32 FLAT 5159 5160 TRANSP equ 0 5161 5162 5163 INCLUDE ".\drawbuff.inc" 5164 INCLUDE ".\gbuffer.inc" 5165 5166 CODESEG 5167 5168 ;*************************************************************************** 5169 ;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport * 5170 ;* * 5171 ;* INPUT: WORD x_pixel - x pixel on viewport to copy from * 5172 ;* WORD y_pixel - y pixel on viewport to copy from * 5173 ;* WORD pixel_width - the width of copy region * 5174 ;* WORD pixel_height - the height of copy region * 5175 ;* BYTE * src - buffer to copy from * 5176 ;* VVPC * dest - virtual viewport to copy to * 5177 ;* * 5178 ;* OUTPUT: none * 5179 ;* * 5180 ;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed * 5181 ;* the boundaries. In the event that no adjustment is * 5182 ;* possible this routine will abort. If the size of the * 5183 ;* region to copy exceeds the size passed in for the buffer * 5184 ;* the routine will automatically abort. * 5185 ;* * 5186 ;* HISTORY: * 5187 ;* 06/15/1994 PWG : Created. * 5188 ;*=========================================================================* 5189 */ 5190 5191 extern "C" long __cdecl Buffer_To_Page(int x_pixel, int y_pixel, int pixel_width, int pixel_height, void *src, void *dest) 5192 { 5193 5194 /* 5195 PROC Buffer_To_Page C near 5196 USES eax,ebx,ecx,edx,esi,edi 5197 5198 ;*=================================================================== 5199 ;* define the arguements that our function takes. 5200 ;*=================================================================== 5201 ARG x_pixel :DWORD ; x pixel position in source 5202 ARG y_pixel :DWORD ; y pixel position in source 5203 ARG pixel_width :DWORD ; width of rectangle to blit 5204 ARG pixel_height:DWORD ; height of rectangle to blit 5205 ARG src :DWORD ; this is a member function 5206 ARG dest :DWORD ; what are we blitting to 5207 5208 ; ARG trans :DWORD ; do we deal with transparents? 5209 5210 ;*=================================================================== 5211 ; Define some locals so that we can handle things quickly 5212 ;*=================================================================== 5213 LOCAL x1_pixel :dword 5214 LOCAL y1_pixel :dword 5215 local scr_x : dword 5216 local scr_y : dword 5217 LOCAL dest_ajust_width:DWORD 5218 LOCAL scr_ajust_width:DWORD 5219 LOCAL dest_area : dword 5220 */ 5221 5222 unsigned long x1_pixel; 5223 unsigned long y1_pixel; 5224 unsigned long scr_x; 5225 unsigned long scr_y; 5226 unsigned long dest_ajust_width; 5227 unsigned long scr_ajust_width; 5228 //unsigned long dest_area; 5229 5230 __asm { 5231 5232 cmp [ src ] , 0 5233 jz real_out 5234 5235 5236 ; Clip dest Rectangle against source Window boundaries. 5237 5238 mov [ scr_x ] , 0 5239 mov [ scr_y ] , 0 5240 mov esi , [ dest ] ; get ptr to dest 5241 xor ecx , ecx 5242 xor edx , edx 5243 mov edi , [esi]GraphicViewPortClass.Width ; get width into register 5244 mov ebx , [ x_pixel ] 5245 mov eax , [ x_pixel ] 5246 add ebx , [ pixel_width ] 5247 shld ecx , eax , 1 5248 mov [ x1_pixel ] , ebx 5249 inc edi 5250 shld edx , ebx , 1 5251 sub eax , edi 5252 sub ebx , edi 5253 shld ecx , eax , 1 5254 shld edx , ebx , 1 5255 5256 mov edi, [esi]GraphicViewPortClass.Height ; get height into register 5257 mov ebx , [ y_pixel ] 5258 mov eax , [ y_pixel ] 5259 add ebx , [ pixel_height ] 5260 shld ecx , eax , 1 5261 mov [ y1_pixel ] , ebx 5262 inc edi 5263 shld edx , ebx , 1 5264 sub eax , edi 5265 sub ebx , edi 5266 shld ecx , eax , 1 5267 shld edx , ebx , 1 5268 5269 xor cl , 5 5270 xor dl , 5 5271 mov al , cl 5272 test dl , cl 5273 jnz real_out 5274 or al , dl 5275 jz do_blit 5276 5277 test cl , 1000b 5278 jz dest_left_ok 5279 mov eax , [ x_pixel ] 5280 neg eax 5281 mov [ x_pixel ] , 0 5282 mov [ scr_x ] , eax 5283 5284 dest_left_ok: 5285 test cl , 0010b 5286 jz dest_bottom_ok 5287 mov eax , [ y_pixel ] 5288 neg eax 5289 mov [ y_pixel ] , 0 5290 mov [ scr_y ] , eax 5291 5292 dest_bottom_ok: 5293 test dl , 0100b 5294 jz dest_right_ok 5295 mov eax , [esi]GraphicViewPortClass.Width ; get width into register 5296 mov [ x1_pixel ] , eax 5297 dest_right_ok: 5298 test dl , 0001b 5299 jz do_blit 5300 mov eax , [esi]GraphicViewPortClass.Height ; get width into register 5301 mov [ y1_pixel ] , eax 5302 5303 do_blit: 5304 5305 cld 5306 5307 mov eax , [esi]GraphicViewPortClass.XAdd 5308 add eax , [esi]GraphicViewPortClass.Width 5309 add eax , [esi]GraphicViewPortClass.Pitch 5310 mov edi , [esi]GraphicViewPortClass.Offset 5311 5312 mov ecx , eax 5313 mul [ y_pixel ] 5314 add edi , [ x_pixel ] 5315 add edi , eax 5316 5317 add ecx , [ x_pixel ] 5318 sub ecx , [ x1_pixel ] 5319 mov [ dest_ajust_width ] , ecx 5320 5321 5322 mov esi , [ src ] 5323 mov eax , [ pixel_width ] 5324 sub eax , [ x1_pixel ] 5325 add eax , [ x_pixel ] 5326 mov [ scr_ajust_width ] , eax 5327 5328 mov eax , [ scr_y ] 5329 mul [ pixel_width ] 5330 add eax , [ scr_x ] 5331 add esi , eax 5332 5333 mov edx , [ y1_pixel ] 5334 mov eax , [ x1_pixel ] 5335 5336 sub edx , [ y_pixel ] 5337 jle real_out 5338 sub eax , [ x_pixel ] 5339 jle real_out 5340 5341 5342 ; ******************************************************************** 5343 ; Forward bitblit only 5344 5345 //IF TRANSP 5346 // test [ trans ] , 1 5347 // jnz forward_Blit_trans 5348 //ENDIF 5349 5350 5351 ; the inner loop is so efficient that 5352 ; the optimal consept no longer apply because 5353 ; the optimal byte have to by a number greather than 9 bytes 5354 cmp eax , 10 5355 jl forward_loop_bytes 5356 5357 forward_loop_dword: 5358 mov ecx , edi 5359 mov ebx , eax 5360 neg ecx 5361 and ecx , 3 5362 sub ebx , ecx 5363 rep movsb 5364 mov ecx , ebx 5365 shr ecx , 2 5366 rep movsd 5367 mov ecx , ebx 5368 and ecx , 3 5369 rep movsb 5370 add esi , [ scr_ajust_width ] 5371 add edi , [ dest_ajust_width ] 5372 dec edx 5373 jnz forward_loop_dword 5374 jmp real_out //ret 5375 5376 forward_loop_bytes: 5377 mov ecx , eax 5378 rep movsb 5379 add esi , [ scr_ajust_width ] 5380 add edi , [ dest_ajust_width ] 5381 dec edx ; decrement the height 5382 jnz forward_loop_bytes 5383 // ret 5384 5385 //IF TRANSP 5386 // 5387 // 5388 //forward_Blit_trans: 5389 // 5390 // 5391 // mov ecx , eax 5392 // and ecx , 01fh 5393 // lea ecx , [ ecx + ecx * 4 ] 5394 // neg ecx 5395 // shr eax , 5 5396 // lea ecx , [ transp_reference + ecx * 2 ] 5397 // mov [ y1_pixel ] , ecx 5398 // 5399 // 5400 //forward_loop_trans: 5401 // mov ecx , eax 5402 // jmp [ y1_pixel ] 5403 //forward_trans_line: 5404 // REPT 32 5405 // local transp_pixel 5406 // mov bl , [ esi ] 5407 // inc esi 5408 // test bl , bl 5409 // jz transp_pixel 5410 // mov [ edi ] , bl 5411 // transp_pixel: 5412 // inc edi 5413 // ENDM 5414 // transp_reference: 5415 // dec ecx 5416 // jge forward_trans_line 5417 // add esi , [ scr_ajust_width ] 5418 // add edi , [ dest_ajust_width ] 5419 // dec edx 5420 // jnz forward_loop_trans 5421 // ret 5422 //ENDIF 5423 5424 real_out: 5425 //ret 5426 } 5427 } 5428 5429 //ENDP Buffer_To_Page 5430 //END 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 /* 5441 5442 ;*************************************************************************** 5443 ;* VVPC::GET_PIXEL -- Gets a pixel from the current view port * 5444 ;* * 5445 ;* INPUT: WORD the x pixel on the screen. * 5446 ;* WORD the y pixel on the screen. * 5447 ;* * 5448 ;* OUTPUT: UBYTE the pixel at the specified location * 5449 ;* * 5450 ;* WARNING: If pixel is to be placed outside of the viewport then * 5451 ;* this routine will abort. * 5452 ;* * 5453 ;* HISTORY: * 5454 ;* 06/07/1994 PWG : Created. * 5455 ;*=========================================================================* 5456 PROC Buffer_Get_Pixel C near 5457 USES ebx,ecx,edx,edi 5458 5459 ARG this_object:DWORD ; this is a member function 5460 ARG x_pixel:DWORD ; x position of pixel to set 5461 ARG y_pixel:DWORD ; y position of pixel to set 5462 */ 5463 5464 extern "C" int __cdecl Buffer_Get_Pixel(void * this_object, int x_pixel, int y_pixel) 5465 { 5466 __asm { 5467 5468 ;*=================================================================== 5469 ; Get the viewport information and put bytes per row in ecx 5470 ;*=================================================================== 5471 mov ebx,[this_object] ; get a pointer to viewport 5472 xor eax,eax 5473 mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset 5474 mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport 5475 mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport 5476 5477 ;*=================================================================== 5478 ; Verify that the X pixel offset if legal 5479 ;*=================================================================== 5480 mov eax,[x_pixel] ; find the x position 5481 cmp eax,edx ; is it out of bounds 5482 jae short exit_label ; if so then get out 5483 add edi,eax ; otherwise add in offset 5484 5485 ;*=================================================================== 5486 ; Verify that the Y pixel offset if legal 5487 ;*=================================================================== 5488 mov eax,[y_pixel] ; get the y position 5489 cmp eax,ecx ; is it out of bounds 5490 jae exit_label ; if so then get out 5491 add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row 5492 add edx,[ebx]GraphicViewPortClass.Pitch ; otherwise find bytes per row 5493 mul edx ; offset = bytes per row * y 5494 add edi,eax ; add it into the offset 5495 5496 ;*=================================================================== 5497 ; Write the pixel to the screen 5498 ;*=================================================================== 5499 xor eax,eax ; clear the word 5500 mov al,[edi] ; read in the pixel 5501 exit_label: 5502 //ret 5503 //ENDP Buffer_Get_Pixel 5504 5505 } 5506 } 5507 5508