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